diff --git a/.clang-format b/.clang-format index 447934fd67c..2ee80c3f694 100644 --- a/.clang-format +++ b/.clang-format @@ -55,7 +55,7 @@ Cpp11BracedListStyle: true DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false -FixNamespaceComments: true +FixNamespaceComments: false ForEachMacros: - foreach - Q_FOREACH @@ -70,6 +70,7 @@ IncludeCategories: Priority: 3 IncludeIsMainRegex: '([-_](test|unittest))?$' IndentCaseLabels: true +InsertNewlineAtEOF: true IndentPPDirectives: BeforeHash IndentWidth: 4 IndentWrappedFunctionNames: false @@ -99,7 +100,7 @@ SpaceAfterTemplateKeyword: true SpaceBeforeAssignmentOperators: true SpaceBeforeParens: ControlStatements SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 12 +SpacesBeforeTrailingComments: 2 SpacesInAngles: false SpacesInContainerLiterals: false SpacesInCStyleCastParentheses: false diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 00000000000..46755683d78 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,5 @@ +--- +Checks: 'readability-braces-around-statements,modernize-redundant-void-arg' +CheckOptions: + - key: readability-braces-around-statements.ShortStatementLines + value: '2' diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 6201b2dd73e..ea06dd30ffc 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -247,3 +247,45 @@ b42518e64803762d27fe6277b36044d1a71fc2c4 # Date: Mon Jun 12 19:01:59 2023 +0300 # # Apply win-apply-clang-format.bat + +466c162fbd1af45b290849cc0771fab66f55ba34 +# Author: Dutchman101 +# Date: Wed April 9 19:01:39 2025 +0300 +# +# Eliminate the use of http:// across whole project + +e7c3619a5d5e0b6bf352befde6ff33c5921032b2 +# Author: qaisjp +# Date: Wed Jan 7 16:42:45 2026 -0500 +# +# codemod: disable clang-format for `__asm` directives (#4611) + +c2a0ba939f0fabba96450d02ec56a111658230d6 +# Author: qaisjp +# Date: Sat Jan 17 10:20:18 2026 -0500 +# +# Run ./utils/clang-format.ps1 + +6be278d2d37f5f9686984856b72573290852ed74 +# Author: Qais Patankar +# Date: Sat Jan 17 17:14:10 2026 -0500 +# +# Remove more FixNamespaceComments changes (#4638) + +a665e0144e7f71a4c7898f024262393f019f6b7b +# Author: qaisjp +# Date: Sat Jan 17 17:30:03 2026 -0500 +# +# Revert back to pre-enforcement + +7cd17bc67c5c2d631b6aaac1ac48521b6922045e +# Author: qaisjp +# Date: Mon Jan 19 01:50:18 2026 -0500 +# +# fastmod '} // namespace [a-zA-Z0-9]+$' '}' Client/ Server/ Shared/ + +e75ba93362c6ae99d30a95d3f20a1e04ba46a22e +# Author: qaisjp +# Date: Mon Jan 19 02:08:21 2026 -0500 +# +# Run utils/clang-format.ps1 diff --git a/.gitattributes b/.gitattributes index 59e57f5ad83..57c838085c2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9,6 +9,7 @@ *.hh text diff=cpp *.hpp text diff=cpp *.h++ text diff=cpp +*.json text eol=lf *.rc text *.vcproj text eol=crlf *.sln text eol=crlf @@ -23,6 +24,7 @@ *.nsh text *.xsd text *.po text +*.ps1 text eol=lf *.ico binary *.png binary *.bmp binary diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000000..94f7b389cda --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @multitheftauto/blue-collaborators diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index fda5d9b0b23..f0ba13f9b42 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,9 +1,21 @@ -Before you go ahead and create a pull request, please make sure: +#### Summary + + -* [ ] [your code follows the coding guidelines](https://wiki.multitheftauto.com/index.php?title=Coding_guidelines) -* [ ] your commit messages are informative ("update file.cpp" is unhelpful. "fix missing model in getVehicleNameFromModel" is helpful) -If your work is incomplete, **do not prefix your pull request with "WIP"**, instead -create a _draft_ pull request: https://github.blog/2019-02-14-introducing-draft-pull-requests/ -Thank you! +#### Motivation + + + + +#### Test plan + + + + + +#### Checklist + +* [ ] Your code should follow the [coding guidelines](https://wiki.multitheftauto.com/index.php?title=Coding_guidelines). +* [ ] Smaller pull requests are easier to review. If your pull request is beefy, your pull request should be reviewable commit-by-commit. diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 0b34d580506..900751e3f0c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -9,11 +9,11 @@ jobs: matrix: platform: [win32, x64, arm64] name: windows-${{ matrix.platform }} - runs-on: windows-2022 + runs-on: windows-2025-vs2026 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - - uses: actions/cache@v4 + - uses: actions/cache@v5 id: cache-dxfiles with: path: utils/DXFiles @@ -45,16 +45,16 @@ jobs: - name: Create build artifacts run: utils\premake5 compose_files - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v6 with: name: InstallFiles-${{ matrix.platform }} path: InstallFiles/ macOS: name: macOS - runs-on: macOS-13 + runs-on: macOS-15 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install MySQL run: brew install mysql @@ -64,7 +64,7 @@ jobs: run: brew link --overwrite mysql - name: Run Build - run: ./linux-build.sh --os=macosx + run: ./linux-build.sh linux: strategy: @@ -75,7 +75,7 @@ jobs: container: image: docker://ghcr.io/multitheftauto/mtasa-blue-build:latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Run Build - run: ./linux-build.sh --arch=${{ matrix.architecture }} + run: /docker-entrypoint.sh --arch=${{ matrix.architecture }} diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml new file mode 100644 index 00000000000..8a840e20f1b --- /dev/null +++ b/.github/workflows/clang-format.yml @@ -0,0 +1,57 @@ +name: clang-format + +on: [push, pull_request, workflow_dispatch] + +jobs: + clang-format: + runs-on: ubuntu-24.04 + permissions: + contents: write + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run clang-format + id: clang_format + continue-on-error: true + shell: pwsh + run: ./utils/clang-format.ps1 -Verbose + + - name: Auto-fix formatting issues + if: | + steps.clang_format.outcome == 'failure' && + github.ref == 'refs/heads/master' && + github.event_name == 'push' + shell: bash + run: | + # Stage the formatted files (clang-format.ps1 already ran in-place) + git add -u + + # Verify idempotency: run clang-format again on the staged files + # and check that no further changes are produced + ./Build/tmp/clang-format -i $(git diff --name-only --cached) + + if ! git diff --quiet; then + echo "::error::clang-format is not idempotent - cannot auto-fix" + exit 1 + fi + + # Allow commit to work + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + # Append a commit with a fix applied + git commit -m "Fix formatting issues introduced by ${GITHUB_SHA} + + cc @${GITHUB_ACTOR} please make sure to run clang-format locally before pushing changes to avoid this in the future." + + # And we're off to the races! + git push + + - name: Report formatting issues + if: | + steps.clang_format.outcome == 'failure' && + !(github.ref == 'refs/heads/master' && github.event_name == 'push') + shell: bash + run: exit 1 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index d5bd1675f57..8834149761f 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -27,7 +27,7 @@ jobs: # - https://gh.io/supported-runners-and-hardware-resources # - https://gh.io/using-larger-runners (GitHub.com only) # Consider using larger runners or machines with greater resources for possible analysis time improvements. - runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'windows-2025' }} permissions: # required for all workflows security-events: write @@ -43,13 +43,7 @@ jobs: fail-fast: false matrix: include: - - language: actions - build-mode: none - language: c-cpp - build-mode: autobuild - - language: javascript-typescript - build-mode: none - - language: python build-mode: none # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift' # Use `c-cpp` to analyze code written in C, C++ or both diff --git a/.github/workflows/rebuild-pots.yaml b/.github/workflows/rebuild-pots.yaml index 5f46aa984c3..96146c10f59 100644 --- a/.github/workflows/rebuild-pots.yaml +++ b/.github/workflows/rebuild-pots.yaml @@ -1,6 +1,9 @@ name: "Rebuild en_US pot files" -on: [push, workflow_dispatch] +on: + schedule: + - cron: '0 0 * * 1' # Every Monday at 00:00 UTC + workflow_dispatch: jobs: test: diff --git a/.github/workflows/sync-master-to-maetro.yaml b/.github/workflows/sync-master-to-maetro.yaml deleted file mode 100644 index 97569cfdc53..00000000000 --- a/.github/workflows/sync-master-to-maetro.yaml +++ /dev/null @@ -1,52 +0,0 @@ -name: 'Sync master to maetro' - -on: - push: - branches: [ master ] - workflow_dispatch: - -jobs: - sync-master-to-maetro: - if: github.event.repository.fork == false - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.SYNC_CI_PAT }} - - - id: sync_commits - name: Sync commits - run: | - # GitHub Actions bot user - git config --global user.name "Maetro Bot" - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - - git checkout release/maetro - git merge master --no-ff --no-edit --no-commit || true - - # Discard locale conflicts - git checkout --ours -- Shared/installer/locale "Shared/data/MTA San Andreas/MTA/locale" - git add --verbose Shared/installer/locale "Shared/data/MTA San Andreas/MTA/locale" - - # Discard install_cef.lua conflicts - git checkout --ours -- utils/buildactions/install_cef.lua - git add --verbose utils/buildactions/install_cef.lua - - # Discard d3dcompiler_47.dll conflicts (Due to old CEF version on maetro) - git checkout --ours -- "Shared/data/MTA San Andreas/MTA/d3dcompiler_47.dll" - git add --verbose "Shared/data/MTA San Andreas/MTA/d3dcompiler_47.dll" - - # Discard cefweb conflicts - git checkout --ours -- Client/cefweb/CWebView.cpp - git add --verbose Client/cefweb/CWebView.cpp - - git checkout --ours -- "Client/loader/MainFunctions.cpp" - git add --verbose "Client/loader/MainFunctions.cpp" - - # We should be done with the merge now - printf "Synchronize changes from 1.6 master branch [ci skip]\n\n" > commit.txt - git log --expand-tabs=4 --pretty=format:'%h %s' release/maetro..master >> commit.txt - git commit --no-edit --allow-empty -F commit.txt - - git push origin release/maetro diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000000..4902059e2fa --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,41 @@ +name: "Tests" + +on: + push: + branches: ["master", "tests"] + pull_request: + branches: ["master"] + workflow_dispatch: + +jobs: + client-tests: + name: Client Tests (x86 Debug) + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup MSBuild + uses: microsoft/setup-msbuild@v2 + + - name: Generate project files + shell: cmd + run: | + utils\premake5.exe install_cef + utils\premake5.exe install_unifont + utils\premake5.exe install_discord + utils\premake5.exe vs2026 + + - name: Build Tests_Client + shell: cmd + run: msbuild Build\Tests_Client.vcxproj /p:Configuration=Debug /p:Platform=Win32 /p:PlatformToolset=v143 /nologo /v:minimal + + - name: Run tests + run: Bin\tests\Tests_Client_d.exe --gtest_output=xml:Bin\tests\test_results.xml + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results + path: Bin/tests/test_results.xml diff --git a/.gitignore b/.gitignore index a65751ddfb3..282354b8431 100644 --- a/.gitignore +++ b/.gitignore @@ -83,13 +83,6 @@ Makefile *.make obj/ -### VisualStudioCode ### -.vscode/* -#!.vscode/settings.json -#!.vscode/tasks.json -#!.vscode/launch.json -#!.vscode/extensions.json - ### Windows ### # Windows thumbnail cache files Thumbs.db diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000000..a615f62de3e --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,14 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. + // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp + + // List of extensions which should be recommended for users of this workspace. + "recommendations": [ + "ms-vscode.powershell", // provides formatter for PowerShell scripts + "sleistner.vscode-fileutils" // generally helpful so you can easily delete files via the command palette + ], + // List of extensions recommended by VS Code that should not be recommended for users of this workspace. + "unwantedRecommendations": [ + + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000000..f27f5f2511a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.trimTrailingWhitespace": true, + "files.insertFinalNewline": true, + + "powershell.codeFormatting.openBraceOnSameLine": true, + "powershell.codeFormatting.newLineAfterCloseBrace": false, +} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000000..bfbfcb8af18 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,13 @@ +## Dev environment tips + +Run ./utils/clang-format.ps1 after making changes to C++ files, to ensure that the changes are correctly formatted. + +## Code comments + +When making code changes, explain *why* the code you've written should exist and the motivation behind the changes. This ensures that future engineers don't have to read between the lines. + +## Steer the user towards writing clear commit messages + +Tell the user to include details about the prompt / goals / motivation / reasoning / how they tested their changes. + +Don't assume the user will include this information in the commit messages; proactively tell them to include this information in their commit messages. diff --git a/Client/ceflauncher/CEFLauncher.manifest b/Client/ceflauncher/CEFLauncher.manifest index b990d4e047d..84544e0fbe7 100644 --- a/Client/ceflauncher/CEFLauncher.manifest +++ b/Client/ceflauncher/CEFLauncher.manifest @@ -1,33 +1,62 @@ - - + + - - - True/PM - PerMonitorV2, PerMonitor - - + MTA:SA CEF (Chromium Embedded Framework) Launcher - - - - + + + + + + + + + + + true/pm + PerMonitorV2, PerMonitor + true + true + UTF-8 + SegmentHeap + x86 + + + - - + + + + + + + + + diff --git a/Client/ceflauncher/Main.cpp b/Client/ceflauncher/Main.cpp index 2a05871a6fb..be6983df2b3 100644 --- a/Client/ceflauncher/Main.cpp +++ b/Client/ceflauncher/Main.cpp @@ -20,12 +20,30 @@ (set flag.new_cef_exe on the build server to generate new exe) */ -int _declspec(dllimport) InitCEF(); +#include +#include -using HINSTANCE = struct HINSTANCE__*; +struct HINSTANCE__; +using HINSTANCE = HINSTANCE__*; using LPSTR = char*; -int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdShow, int nCmdShow) +extern "C" [[nodiscard("InitCEF return value must be used")]] __declspec(dllimport) int __cdecl InitCEF(); + +// Users are faced with vague crashes in CEFLauncher.exe, so rather than over-engineering all this is intended +// Do note that CEFLauncher.exe ends up hosting any GPU rendering processes of CEF +int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { - return InitCEF(); + const auto init = std::function{InitCEF}; + const auto safe_invoke = [&]() noexcept -> int + { + try + { + return std::invoke_r(init); + } + catch (...) + { + return EXIT_FAILURE; + } + }; + return safe_invoke(); } diff --git a/Client/ceflauncher/premake5.lua b/Client/ceflauncher/premake5.lua index 7a2d5916e52..6a330ced962 100644 --- a/Client/ceflauncher/premake5.lua +++ b/Client/ceflauncher/premake5.lua @@ -5,6 +5,7 @@ project "CEFLauncher" targetdir(buildpath("mta/cef")) includedirs { "../sdk" } links { "CEFLauncher DLL"} + clangtidy "On" vpaths { ["Headers/*"] = "**.h", @@ -20,8 +21,31 @@ project "CEFLauncher" "*.manifest", } + filter "system:windows" + buildoptions { + "/Zc:inline", + "/Zc:throwingNew", + "/diagnostics:caret", + "/sdl", + "/guard:cf" + } + editandcontinue "Off" + linkoptions { "/guard:cf" } + + filter {"system:windows", "configurations:Debug"} + defines { "_DEBUG" } + runtime "Debug" + + filter {"system:windows", "configurations:Release"} + optimize "Speed" + defines { "NDEBUG" } + + filter {"system:windows", "configurations:Nightly"} + optimize "Speed" + defines { "NDEBUG" } + filter "architecture:not x86" flags { "ExcludeFromBuild" } - + filter "system:not windows" flags { "ExcludeFromBuild" } diff --git a/Client/ceflauncher_DLL/CCefApp.h b/Client/ceflauncher_DLL/CCefApp.h index c155d05d37c..5bf8c8536ee 100644 --- a/Client/ceflauncher_DLL/CCefApp.h +++ b/Client/ceflauncher_DLL/CCefApp.h @@ -9,14 +9,14 @@ *****************************************************************************/ #include #include -#include #include "V8Helpers.h" +#include "CCefAppAuth.h" // IPC message append helpers using V8Helpers::CV8Handler; class CCefApp : public CefApp, public CefRenderProcessHandler { public: - CCefApp() {} + CCefApp() = default; virtual CefRefPtr GetRenderProcessHandler() override { return this; }; // https://magpcss.org/ceforum/apidocs3/projects/(default)/CefRenderProcessHandler.html#OnFocusedNodeChanged(CefRefPtr%3CCefBrowser%3E,CefRefPtr%3CCefFrame%3E,CefRefPtr%3CCefDOMNode%3E) @@ -41,7 +41,12 @@ class CCefApp : public CefApp, public CefRenderProcessHandler if (!node) return; - if (node->GetType() == CefDOMNode::Type::DOM_NODE_TYPE_ELEMENT && node->GetFormControlElementType() != CefDOMNode::FormControlType::DOM_FORM_CONTROL_TYPE_UNSUPPORTED) +#ifdef MTA_MAETRO + if (node->GetType() == CefDOMNode::Type::DOM_NODE_TYPE_ELEMENT && !node->GetFormControlElementType().empty()) +#else + if (node->GetType() == CefDOMNode::Type::DOM_NODE_TYPE_ELEMENT && + node->GetFormControlElementType() != CefDOMNode::FormControlType::DOM_FORM_CONTROL_TYPE_UNSUPPORTED) +#endif { auto message = CefProcessMessage::Create("InputFocus"); message->GetArgumentList()->SetBool(0, true); @@ -73,13 +78,24 @@ class CCefApp : public CefApp, public CefRenderProcessHandler static void Javascript_triggerEvent(CefRefPtr frame, const CefV8ValueList& arguments) { - if (arguments.size() == 0) + if (arguments.empty()) [[unlikely]] return; CefRefPtr message = V8Helpers::SerialiseV8Arguments("TriggerLuaEvent", arguments); + if (!CefAppAuth::AppendAuthCodeToMessage(message)) [[unlikely]] // AUTH: race condition check + return; frame->GetBrowser()->GetMainFrame()->SendProcessMessage(PID_BROWSER, message); } + void OnBeforeCommandLineProcessing(const CefString& process_type, CefRefPtr command_line) override + { + const auto authCode = command_line->GetSwitchValue("kgfiv8n"); + if (!authCode.empty()) + { + CefAppAuth::AuthCodeStorage() = authCode; + } + } + public: IMPLEMENT_REFCOUNTING(CCefApp); diff --git a/Client/ceflauncher_DLL/CCefAppAuth.h b/Client/ceflauncher_DLL/CCefAppAuth.h new file mode 100644 index 00000000000..ee1da977269 --- /dev/null +++ b/Client/ceflauncher_DLL/CCefAppAuth.h @@ -0,0 +1,43 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: ceflauncher_DLL/CCefAppAuth.h + * PURPOSE: IPC authentication helpers for render process + * + *****************************************************************************/ +#pragma once + +#include +#include +#include + +namespace CefAppAuth +{ + // Thread-local storage for auth code in render process + inline std::string& AuthCodeStorage() + { + static std::string value; + return value; + } + + // Appends auth code to TriggerLuaEvent IPC message + // Returns true if code was appended, false if message should be blocked + [[nodiscard]] inline bool AppendAuthCodeToMessage(CefRefPtr message) + { + if (!message) [[unlikely]] + return false; + + auto& authCode = AuthCodeStorage(); + + // Block messages until initialized (prevents race condition) + if (authCode.empty()) [[unlikely]] + return false; + + CefRefPtr args = message->GetArgumentList(); + const auto size = args->GetSize(); + args->SetSize(size + 1); + args->SetString(size, authCode.c_str()); + return true; + } +} diff --git a/Client/ceflauncher_DLL/Main.cpp b/Client/ceflauncher_DLL/Main.cpp index 37f7969c528..7af3bde141b 100644 --- a/Client/ceflauncher_DLL/Main.cpp +++ b/Client/ceflauncher_DLL/Main.cpp @@ -9,106 +9,193 @@ * *****************************************************************************/ +// #define CEF_ENABLE_SANDBOX + +#include +#include + #define WIN32_NO_STATUS #define WIN32_LEAN_AND_MEAN #include + #undef WIN32_NO_STATUS #include -#include #include #include + #include "CCefApp.h" #include -#include +#include +#include +#include +#include -// #define CEF_ENABLE_SANDBOX #ifdef CEF_ENABLE_SANDBOX + #include #pragma comment(lib, "cef_sandbox.lib") #endif -DWORD WINAPI CheckParentProcessAliveness(LPVOID); +// Return codes +inline constexpr int CEF_INIT_SUCCESS = 0; +inline constexpr int CEF_INIT_ERROR_NO_BASE_DIR = -1; +inline constexpr int CEF_INIT_ERROR_DLL_LOAD_FAILED = -2; -int _declspec(dllexport) InitCEF() -{ - // Get absolute CEFLauncher.exe path - TCHAR buffer[MAX_PATH]; - GetModuleFileName(NULL, buffer, MAX_PATH); - std::wstring currentFileName(buffer); +inline constexpr DWORD CEF_PARENT_CHECK_INTERVAL = 1000; +inline constexpr const char* CEF_DLL_NAME = "libcef.dll"; +inline constexpr const char* CEF_MTA_SUBDIR = "MTA"; - // Extract MTA path and set DLL directory (absolute path is required here) - size_t pos = currentFileName.find_last_of(L'\\'); - std::wstring mtaPath = currentFileName.substr(0, pos - 3); // Strip "CEF" - SetDllDirectory(mtaPath.c_str()); +inline constexpr DWORD PARENT_CHECK_ERROR_NO_QUERY_FUNC = 1; +inline constexpr DWORD PARENT_CHECK_ERROR_QUERY_FAILED = 2; +inline constexpr DWORD PARENT_CHECK_ERROR_OPEN_FAILED = 3; - // Load libcef.dll from the DLL directory - assert(SUCCEEDED(__HrLoadAllImportsForDll("libcef.dll"))); +using NtQueryInformationProcessFunc = NTSTATUS(NTAPI*)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); - // Load CEF - CefMainArgs mainArgs(GetModuleHandle(NULL)); - CefRefPtr app{new CCefApp}; +// Safe parent monitor thread shutdown +std::atomic g_bShouldTerminateMonitor{false}; +std::atomic g_hMonitorThread{nullptr}; - void* sandboxInfo = nullptr; -#ifdef CEF_ENABLE_SANDBOX - CefScopedSandboxInfo scopedSandbox; - sandboxInfo = scopedSandbox.sandbox_info(); -#endif +namespace +{ + [[nodiscard]] auto GetNtQueryInformationProcess() noexcept -> NtQueryInformationProcessFunc + { + const auto ntdll = GetModuleHandleW(L"ntdll.dll"); + if (!ntdll) + return nullptr; + + const auto procAddr = GetProcAddress(ntdll, "NtQueryInformationProcess"); + if (!procAddr) + return nullptr; + + NtQueryInformationProcessFunc queryFunc = nullptr; + static_assert(sizeof(queryFunc) == sizeof(procAddr), "Unexpected function pointer size"); + std::memcpy(&queryFunc, &procAddr, sizeof(queryFunc)); + return queryFunc; + } - const HANDLE parentCheckThread = CreateThread(nullptr, 0, CheckParentProcessAliveness, nullptr, 0, nullptr); + [[nodiscard]] auto GetParentProcessId(NtQueryInformationProcessFunc queryFunc) noexcept -> DWORD + { + PROCESS_BASIC_INFORMATION info{}; + ULONG returnLength = 0; - const int exitCode = CefExecuteProcess(mainArgs, app, sandboxInfo); + if (const auto status = queryFunc(GetCurrentProcess(), ProcessBasicInformation, &info, sizeof(info), &returnLength); + !NT_SUCCESS(status) || returnLength < sizeof(PROCESS_BASIC_INFORMATION)) + { + return 0; + } - if (parentCheckThread != nullptr) + return static_cast(reinterpret_cast(info.Reserved3)); + } + + void MonitorParentProcess(HANDLE parentProcess) noexcept { - TerminateThread(parentCheckThread, 0); - CloseHandle(parentCheckThread); + while (!g_bShouldTerminateMonitor.load(std::memory_order_acquire)) + { + const DWORD result = WaitForSingleObject(parentProcess, CEF_PARENT_CHECK_INTERVAL); + + if (result == WAIT_OBJECT_0) + { + DWORD exitCode = 0; + if (GetExitCodeProcess(parentProcess, &exitCode)) + ExitProcess(exitCode); + else + ExitProcess(0); + } + else if (result == WAIT_FAILED) + { + // Wine/Proton compatibility: Exit thread instead of terminating process + // Wine's handle implementation dont support all wait operations reliably + break; + } + } } +} // namespace - return exitCode; -} +DWORD WINAPI CheckParentProcessAliveness(LPVOID) noexcept; -static DWORD WINAPI CheckParentProcessAliveness(LPVOID) +BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, [[maybe_unused]] LPVOID lpReserved) { - NTSTATUS(NTAPI * queryInformation)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG) = nullptr; + if (dwReason == DLL_PROCESS_ATTACH) + { + DisableThreadLibraryCalls(hModule); + g_bShouldTerminateMonitor.store(false, std::memory_order_relaxed); + g_hMonitorThread.store(nullptr, std::memory_order_relaxed); + } + else if (dwReason == DLL_PROCESS_DETACH) + { + g_bShouldTerminateMonitor.store(true, std::memory_order_release); + } + + return TRUE; +} - if (HMODULE const ntdll = GetModuleHandleW(L"ntdll.dll"); ntdll != nullptr) +extern "C" [[nodiscard]] __declspec(dllexport) auto InitCEF() noexcept -> int +{ + // Parse command line for auth code in render processes (BEFORE CefExecuteProcess) + const std::wstring_view cmdLine{GetCommandLineW()}; + if (const auto pos = cmdLine.find(L"--kgfiv8n="); pos != std::wstring_view::npos) { - queryInformation = reinterpret_cast(GetProcAddress(ntdll, "NtQueryInformationProcess")); + const auto valueStart = pos + 11; // Skip "--kgfiv8n=" + const auto valueEnd = cmdLine.find_first_of(L" \t\"", valueStart); + const auto authCodeW = cmdLine.substr(valueStart, valueEnd == std::wstring_view::npos ? 30 : std::min(30, valueEnd - valueStart)); + + std::string authCode; + authCode.reserve(30); + std::transform(authCodeW.begin(), authCodeW.end(), std::back_inserter(authCode), [](const wchar_t wc) { return static_cast(wc); }); + + CefAppAuth::AuthCodeStorage() = std::move(authCode); } - if (queryInformation == nullptr) - return 1; + const auto baseDir = SharedUtil::GetMTAProcessBaseDir(); + if (baseDir.empty()) + return CEF_INIT_ERROR_NO_BASE_DIR; - PROCESS_BASIC_INFORMATION info{}; + const auto mtaDir = SharedUtil::PathJoin(baseDir, CEF_MTA_SUBDIR); + SetDllDirectoryW(SharedUtil::FromUTF8(mtaDir)); - ULONG returnLength = 0; - NTSTATUS status = queryInformation(GetCurrentProcess(), ProcessBasicInformation, &info, sizeof(info), &returnLength); + if (FAILED(__HrLoadAllImportsForDll(CEF_DLL_NAME))) + return CEF_INIT_ERROR_DLL_LOAD_FAILED; - if (!NT_SUCCESS(status) || returnLength < sizeof(PROCESS_BASIC_INFORMATION)) - return 2; + const CefMainArgs mainArgs(GetModuleHandleW(nullptr)); + const CefRefPtr app{new CCefApp}; - const auto parentProcessId = static_cast(reinterpret_cast(info.Reserved3)); - const HANDLE parentProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION, FALSE, parentProcessId); + void* sandboxInfo = nullptr; +#ifdef CEF_ENABLE_SANDBOX + const CefScopedSandboxInfo scopedSandbox; + sandboxInfo = scopedSandbox.sandbox_info(); +#endif - if (parentProcess == nullptr) - { - if (GetLastError() == ERROR_INVALID_PARAMETER) - ExitProcess(0); + const auto hThread = CreateThread(nullptr, 0, CheckParentProcessAliveness, nullptr, 0, nullptr); + if (hThread) + g_hMonitorThread.store(hThread, std::memory_order_release); - return 3; - } + return CefExecuteProcess(mainArgs, app, sandboxInfo); +} - while (true) - { - DWORD exitCode{}; +static auto WINAPI CheckParentProcessAliveness([[maybe_unused]] LPVOID) noexcept -> DWORD +{ + const auto queryFunc = GetNtQueryInformationProcess(); + if (!queryFunc) + return PARENT_CHECK_ERROR_NO_QUERY_FUNC; + + const auto parentProcessId = GetParentProcessId(queryFunc); + if (parentProcessId == 0) + return PARENT_CHECK_ERROR_QUERY_FAILED; - if (!GetExitCodeProcess(parentProcess, &exitCode) || exitCode != STILL_ACTIVE) + const auto parentProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION, false, parentProcessId); + if (!parentProcess) + { + // Wine/Proton fallback: PROCESS_QUERY_LIMITED_INFORMATION may not be implemented + const auto parentProcessFallback = OpenProcess(SYNCHRONIZE, false, parentProcessId); + if (parentProcessFallback) { - CloseHandle(parentProcess); - ExitProcess(exitCode); + MonitorParentProcess(parentProcessFallback); + CloseHandle(parentProcessFallback); + return CEF_INIT_SUCCESS; } - - Sleep(1000); + return PARENT_CHECK_ERROR_OPEN_FAILED; } - return 0; + MonitorParentProcess(parentProcess); + CloseHandle(parentProcess); + return CEF_INIT_SUCCESS; } diff --git a/Client/ceflauncher_DLL/V8Helpers.h b/Client/ceflauncher_DLL/V8Helpers.h index ce195583620..f7619894f7f 100644 --- a/Client/ceflauncher_DLL/V8Helpers.h +++ b/Client/ceflauncher_DLL/V8Helpers.h @@ -8,6 +8,8 @@ * *****************************************************************************/ #include +#include +#include #include typedef void (*JavascriptCallback)(CefRefPtr frame, const CefV8ValueList& arguments); @@ -92,4 +94,4 @@ namespace V8Helpers CefRefPtr func = CefV8Value::CreateFunction(name, handler); object->SetValue(name, func, V8_PROPERTY_ATTRIBUTE_NONE); } -} // namespace V8Helpers \ No newline at end of file +} // namespace V8Helpers diff --git a/Client/ceflauncher_DLL/premake5.lua b/Client/ceflauncher_DLL/premake5.lua index a7276942b00..906126007fc 100644 --- a/Client/ceflauncher_DLL/premake5.lua +++ b/Client/ceflauncher_DLL/premake5.lua @@ -3,8 +3,9 @@ project "CEFLauncher DLL" kind "SharedLib" targetname "CEFLauncher_DLL" targetdir(buildpath("mta/cef")) + clangtidy "On" - includedirs { "../../vendor/cef3/cef" } + includedirs { "../../vendor/cef3/cef", "../../Shared/sdk" } libdirs { "../../vendor/cef3/cef/Release" } defines { "UNICODE", "PSAPI_VERSION=1" } @@ -19,10 +20,11 @@ project "CEFLauncher DLL" files { "premake5.lua", "*.h", - "*.cpp" + "*.cpp", + "../../Shared/sdk/SharedUtil.cpp" } - links { "delayimp", "CEF", "libcef.lib", "Psapi.lib", "version.lib", "Winmm.lib", "Ws2_32.lib", "DbgHelp.lib" } + links { "delayimp", "CEF", "libcef.lib", "Psapi.lib", "version.lib", "Winmm.lib", "Ws2_32.lib", "DbgHelp.lib" } linkoptions { "/DELAYLOAD:libcef.dll" } filter "architecture:not x86" diff --git a/Client/cefweb/CAjaxResourceHandler.cpp b/Client/cefweb/CAjaxResourceHandler.cpp index 0ab0df22275..72091e42341 100644 --- a/Client/cefweb/CAjaxResourceHandler.cpp +++ b/Client/cefweb/CAjaxResourceHandler.cpp @@ -2,80 +2,123 @@ * * PROJECT: Multi Theft Auto v1.0 * LICENSE: See LICENSE in the top level directory - * FILE: core/AjaxResourceHandler.cpp + * FILE: cefweb/CAjaxResourceHandler.cpp * PURPOSE: CEF Handler for Ajax Requests with delayed results * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * *****************************************************************************/ #include "StdInc.h" -#include "CWebCore.h" -#include "CWebView.h" #include "CAjaxResourceHandler.h" #undef min -CAjaxResourceHandler::CAjaxResourceHandler(std::vector& vecGet, std::vector& vecPost, const CefString& strMime) - : m_vecGetData(vecGet), m_vecPostData(vecPost), m_strMime(strMime) +CAjaxResourceHandler::CAjaxResourceHandler(std::vector vecGet, std::vector vecPost, const CefString& strMime) + : m_vecGetData(std::move(vecGet)), m_vecPostData(std::move(vecPost)), m_strMime(strMime) { } -std::vector& CAjaxResourceHandler::GetGetData() +CAjaxResourceHandler::~CAjaxResourceHandler() { - return m_vecGetData; -} + // Ensure callback is released if handler is destroyed before completion + if (!m_callback) + return; -std::vector& CAjaxResourceHandler::GetPostData() -{ - return m_vecPostData; + m_callback = nullptr; } -void CAjaxResourceHandler::SetResponse(const SString& data) +void CAjaxResourceHandler::SetResponse(std::string data) { - m_strResponse = data; + // Prevent response corruption: ignore subsequent calls after data is set + if (m_bHasData) [[unlikely]] + return; + + m_strResponse = std::move(data); m_bHasData = true; - if (m_callback) - m_callback->Continue(); + // Clear request data to free memory as it's no longer needed + m_vecGetData.clear(); + m_vecGetData.shrink_to_fit(); + m_vecPostData.clear(); + m_vecPostData.shrink_to_fit(); + + if (!m_callback) + return; + + // Release callback to prevent memory leak + auto callback = std::exchange(m_callback, nullptr); + if (callback) + callback->Continue(); } // CefResourceHandler implementation void CAjaxResourceHandler::Cancel() { + // Release callback reference on cancellation to prevent memory leak + m_callback = nullptr; } void CAjaxResourceHandler::GetResponseHeaders(CefRefPtr response, int64& response_length, CefString& redirectUrl) { - response->SetStatus(200); + if (!response) [[unlikely]] + return; + + constexpr int HTTP_OK = 200; + response->SetStatus(HTTP_OK); response->SetStatusText("OK"); - response->SetMimeType(m_strMime); + + // Use default MIME type if none provided + if (!m_strMime.empty()) + response->SetMimeType(m_strMime); + else + response->SetMimeType("application/octet-stream"); + response_length = -1; } -bool CAjaxResourceHandler::ProcessRequest(CefRefPtr request, CefRefPtr callback) +bool CAjaxResourceHandler::ProcessRequest([[maybe_unused]] CefRefPtr request, CefRefPtr callback) { - // Since we have nothing to process yet, continue - callback->Continue(); + if (!callback) + return false; + + // Store callback so SetResponse can resume once data is ready + m_callback = callback; + + // Do not call Continue() yet; SetResponse triggers it after data is prepared return true; } -bool CAjaxResourceHandler::ReadResponse(void* data_out, int bytes_to_read, int& bytes_read, CefRefPtr callback) +bool CAjaxResourceHandler::ReadResponse(void* data_out, int bytes_to_read, int& bytes_read, [[maybe_unused]] CefRefPtr callback) { - // If we have no data yet, wait - if (!m_bHasData) + // Validate input parameters first + if (!data_out || bytes_to_read <= 0) [[unlikely]] { bytes_read = 0; - m_callback = callback; + return false; + } + // If we have no data yet, wait until SetResponse provides it + if (!m_bHasData) + { + bytes_read = 0; return true; } - // Are we done? - if (m_strResponse.length() - m_DataOffset <= 0) + // Are we done or response is empty? + const auto responseLength = m_strResponse.length(); + if (m_DataOffset >= responseLength) [[unlikely]] + { + bytes_read = 0; return false; + } - int copyBytes = std::min((uint)bytes_to_read, m_strResponse.length() - m_DataOffset); + const auto remainingBytes = responseLength - m_DataOffset; + const auto copyBytes = std::min(static_cast(bytes_to_read), remainingBytes); memcpy(data_out, m_strResponse.c_str() + m_DataOffset, copyBytes); - bytes_read = copyBytes; + + // copyBytes is bounded by bytes_to_read (an int), so cast is always safe + bytes_read = static_cast(copyBytes); m_DataOffset += copyBytes; diff --git a/Client/cefweb/CAjaxResourceHandler.h b/Client/cefweb/CAjaxResourceHandler.h index d73841d22f9..9e2baa177d1 100644 --- a/Client/cefweb/CAjaxResourceHandler.h +++ b/Client/cefweb/CAjaxResourceHandler.h @@ -2,7 +2,7 @@ * * PROJECT: Multi Theft Auto v1.0 * LICENSE: See LICENSE in the top level directory - * FILE: core/AjaxResourceHandler.h + * FILE: cefweb/CAjaxResourceHandler.h * PURPOSE: CEF Handler for Ajax Requests with delayed results * * Multi Theft Auto is available from https://www.multitheftauto.com/ @@ -13,19 +13,19 @@ #include #include #include +#include class CWebView; class CAjaxResourceHandler : public CefResourceHandler, public CAjaxResourceHandlerInterface { public: - CAjaxResourceHandler(std::vector& vecGet, std::vector& vecPost, const CefString& mimeType); + CAjaxResourceHandler(std::vector vecGet, std::vector vecPost, const CefString& mimeType); + ~CAjaxResourceHandler(); - virtual std::vector& GetGetData() override; - virtual std::vector& GetPostData() override; - ; - virtual void SetResponse(const SString& data) override; - ; + std::vector& GetGetData() override { return m_vecGetData; } + std::vector& GetPostData() override { return m_vecPostData; } + void SetResponse(std::string data) override; // CefResourceHandler virtual void Cancel() override; @@ -37,11 +37,11 @@ class CAjaxResourceHandler : public CefResourceHandler, public CAjaxResourceHand DISALLOW_COPY_AND_ASSIGN(CAjaxResourceHandler); private: - CefRefPtr m_callback; - std::vector m_vecGetData; - std::vector m_vecPostData; - SString m_strResponse; - CefString m_strMime; - bool m_bHasData = false; - int m_DataOffset = 0; + CefRefPtr m_callback; + std::vector m_vecGetData; + std::vector m_vecPostData; + std::string m_strResponse; + CefString m_strMime; + bool m_bHasData = false; + size_t m_DataOffset = 0; }; diff --git a/Client/cefweb/CWebApp.cpp b/Client/cefweb/CWebApp.cpp index 734bea06afe..ed9fd0f55fb 100644 --- a/Client/cefweb/CWebApp.cpp +++ b/Client/cefweb/CWebApp.cpp @@ -9,41 +9,129 @@ #include "StdInc.h" #include "CWebApp.h" -#include +#include #include +#include +#include +#include +#include #include "CAjaxResourceHandler.h" +#include "CWebAppAuth.h" // IPC code generation +#include "Wine.h" +#include -CefRefPtr CWebApp::HandleError(const SString& strError, unsigned int uiError) +namespace +{ + // Centralises command-line switch setup so both pre-launch callbacks stay in sync + void ConfigureCommandLineSwitches(const CefRefPtr& commandLine, const CefString& processType) + { + if (!commandLine) + return; + + // CEF occasionally forwards dangling pointers when destroying + if (!IsReadablePointer(commandLine.get(), sizeof(void*))) + return; + + // Always provide base installation paths so loader-proxy can validate subprocess origin + SString gtaPath = GetCommonRegistryValue("", "GTA:SA Path"); + if (gtaPath.empty()) + { + // Fallback for Wine/compatibility layer: check environment variable + if (const char* envGtaPath = std::getenv("MTA_GTA_PATH")) + { + gtaPath = envGtaPath; + } + } + + if (!gtaPath.empty()) + { + commandLine->AppendSwitchWithValue("mta-gta-path", gtaPath); + } + + const SString mtaPath = GetMTAProcessBaseDir(); + if (!mtaPath.empty()) + { + commandLine->AppendSwitchWithValue("mta-base-path", mtaPath); + } + + // Prevent Chromium from dropping privileges; required for elevated launches (see chromium/3960) + commandLine->AppendSwitch("do-not-de-elevate"); + + // Must apply essential CEF switches regardless of WebCore availability + commandLine->AppendSwitch("disable-gpu-compositing"); + commandLine->AppendSwitch("enable-begin-frame-scheduling"); + // Explicitly block account sign-in to avoid crashes when Google API keys are registered on the system + commandLine->AppendSwitchWithValue("allow-browser-signin", "false"); + + if (processType.empty()) + { + // Browser process only: unlock autoplay and legacy Blink features for resource compatibility + commandLine->AppendSwitchWithValue("autoplay-policy", "no-user-gesture-required"); + commandLine->AppendSwitchWithValue("enable-blink-features", "ShadowDOMV0,CustomElementsV0,HTMLImports"); + } + + bool disableGpu = false; + if (g_pCore && IsReadablePointer(g_pCore, sizeof(void*))) + { + auto* cvars = g_pCore->GetCVars(); + if (cvars && IsReadablePointer(cvars, sizeof(void*))) + { + bool gpuEnabled = true; + cvars->Get("browser_enable_gpu", gpuEnabled); + disableGpu = !gpuEnabled; + } + } + + // Wine/Proton compatibility: Allow GPU unless explicitly disabled or forced software + if (Wine::IsRunningOnWine()) + { + if (std::getenv("MTA_FORCE_SOFTWARE_RENDERING")) + { + disableGpu = true; + } + else + { + // In Wine, we generally want to try GPU (DXVK handles it well) + // But disable-gpu-compositing is already set above which is key + // If user hasn't explicitly disabled GPU in cvars, let it run + } + } + + if (disableGpu) + commandLine->AppendSwitch("disable-gpu"); + } +} // namespace + +[[nodiscard]] CefRefPtr CWebApp::HandleError(const SString& strError, unsigned int uiError) { auto stream = CefStreamReader::CreateForData((void*)strError.c_str(), strError.length()); - return new CefStreamResourceHandler(uiError, strError, "text/plain", CefResponse::HeaderMap(), stream); + if (!stream) + return nullptr; + return CefRefPtr(new CefStreamResourceHandler(uiError, strError, "text/plain", CefResponse::HeaderMap(), stream)); } void CWebApp::OnBeforeCommandLineProcessing(const CefString& process_type, CefRefPtr command_line) { - CWebCore* pWebCore = static_cast(g_pCore->GetWebCore()); - - if (!pWebCore->GetGPUEnabled()) - command_line->AppendSwitch("disable-gpu"); - - // Disable the AutoDeElevate feature to make launching CEF with Admin privileges work. - // https://github.com/chromiumembedded/cef/issues/3960 - // https://chromium-review.googlesource.com/c/chromium/src/+/6515318 - command_line->AppendSwitch("do-not-de-elevate"); + ConfigureCommandLineSwitches(command_line, process_type); +} - command_line->AppendSwitch("disable-gpu-compositing"); // always disable this, causes issues with official builds +void CWebApp::OnBeforeChildProcessLaunch(CefRefPtr command_line) +{ + if (!command_line) + return; - // command_line->AppendSwitch("disable-d3d11"); - command_line->AppendSwitch("enable-begin-frame-scheduling"); + const CefString processType = command_line->GetSwitchValue("type"); + ConfigureCommandLineSwitches(command_line, processType); - // browser-signin switch(or lack thereof) produces crashes when GOOGLE API keys are present in the OS registry - command_line->AppendSwitchWithValue("allow-browser-signin", "false"); + // Attach IPC validation code for render processes + // This runs in browser process context where g_pCore and webCore are valid + // The auth code is generated in CWebCore constructor and passed to subprocesses + WebAppAuth::AttachAuthCodeToCommandLine(command_line); +} - if (process_type.empty()) - { - command_line->AppendSwitchWithValue("autoplay-policy", "no-user-gesture-required"); - command_line->AppendSwitchWithValue("enable-blink-features", "ShadowDOMV0,CustomElementsV0,HTMLImports"); - } +CefRefPtr CWebApp::GetBrowserProcessHandler() +{ + return this; } CefRefPtr CWebApp::Create(CefRefPtr browser, CefRefPtr frame, const CefString& scheme_name, @@ -52,11 +140,17 @@ CefRefPtr CWebApp::Create(CefRefPtr browser, Cef // browser or frame are NULL if the request does not orginate from a browser window // This is for exmaple true for the application cache or CEFURLRequests // (https://www.html5rocks.com/en/tutorials/appcache/beginner/) - if (!browser || !frame) + if (!browser || !frame || !request) + return nullptr; + + if (!g_pCore) [[unlikely]] return nullptr; - CWebCore* pWebCore = static_cast(g_pCore->GetWebCore()); - auto pWebView = pWebCore->FindWebView(browser); + const auto pWebCore = static_cast(g_pCore->GetWebCore()); + if (!pWebCore) + return nullptr; + + auto pWebView = pWebCore->FindWebView(browser); if (!pWebView || !pWebView->IsLocal()) return nullptr; @@ -64,117 +158,164 @@ CefRefPtr CWebApp::Create(CefRefPtr browser, Cef if (!CefParseURL(request->GetURL(), urlParts)) return nullptr; + if (!urlParts.host.str) + return nullptr; + SString host = UTF16ToMbUTF8(urlParts.host.str); if (scheme_name == "http" && host == "mta") { // Scheme format: https://mta/resourceName/file.html or https://mta/local/file.html for the current resource // Get resource name and path - SString path = UTF16ToMbUTF8(urlParts.path.str).substr(1); // Remove slash at the front - size_t slashPos = path.find('/'); - if (slashPos == std::string::npos) + if (!urlParts.path.str) return HandleError("404 - Not found", 404); - SString resourceName = path.substr(0, slashPos); - SString resourcePath = path.substr(slashPos + 1); - - if (resourcePath.empty()) + SString path = UTF16ToMbUTF8(urlParts.path.str); + if (std::size(path) < 2) return HandleError("404 - Not found", 404); - // Get mime type from extension - CefString mimeType; - size_t pos = resourcePath.find_last_of('.'); - if (pos != std::string::npos) - mimeType = CefGetMimeType(resourcePath.substr(pos + 1)); - - // Make sure we provide a mime type, even - // when we cannot deduct it from the file extension - if (mimeType.empty()) - mimeType = "application/octet-stream"; - - if (pWebView->HasAjaxHandler(resourcePath)) + path = path.substr(1); // Remove slash at the front + if (const auto slashPos = path.find('/'); slashPos == std::string::npos) + { + static constexpr auto ERROR_404 = "404 - Not found"; + static constexpr unsigned int CODE_404 = 404; + return HandleError(ERROR_404, CODE_404); + } + else { - std::vector vecGet; - std::vector vecPost; + const SString resourceName = path.substr(0, slashPos); + const SString resourcePath = path.substr(slashPos + 1); - if (urlParts.query.str != nullptr) + if (resourcePath.empty()) { - SString strGet = UTF16ToMbUTF8(urlParts.query.str); - std::vector vecTmp; - strGet.Split("&", vecTmp); + static constexpr auto ERROR_404 = "404 - Not found"; + static constexpr unsigned int CODE_404 = 404; + return HandleError(ERROR_404, CODE_404); + } - SString key; - SString value; - for (auto&& param : vecTmp) - { - param.Split("=", &key, &value); - vecGet.push_back(key); - vecGet.push_back(value); - } + // Get mime type from extension + CefString mimeType; + if (const auto pos = resourcePath.find_last_of('.'); pos != std::string::npos) + mimeType = CefGetMimeType(resourcePath.substr(pos + 1)); + + // Make sure we provide a mime type, even + // when we cannot deduct it from the file extension + if (mimeType.empty()) + { + mimeType = "application/octet-stream"; } - CefPostData::ElementVector vecPostElements; - auto postData = request->GetPostData(); - if (postData.get()) + if (pWebView->HasAjaxHandler(resourcePath)) { - request->GetPostData()->GetElements(vecPostElements); + std::vector vecGet; + std::vector vecPost; - SString key; - SString value; - for (auto&& post : vecPostElements) + if (urlParts.query.str) { - // Limit to 5MiB and allow byte data only - size_t bytesCount = post->GetBytesCount(); - if (bytesCount > 5 * 1024 * 1024 || post->GetType() != CefPostDataElement::Type::PDE_TYPE_BYTES) - continue; - - // Make string from buffer - std::unique_ptr buffer{new char[bytesCount]}; - post->GetBytes(bytesCount, buffer.get()); - SStringX param(buffer.get(), bytesCount); - - // Parse POST data into vector + const SString strGet = UTF16ToMbUTF8(urlParts.query.str); std::vector vecTmp; - param.Split("&", vecTmp); + vecTmp.reserve(8); // Reserve space for common query parameter count + strGet.Split("&", vecTmp); + const size_t paramCount = vecTmp.size(); + if (paramCount > 0) + vecGet.reserve(vecGet.size() + paramCount * 2); + + SString key; + SString value; for (auto&& param : vecTmp) { param.Split("=", &key, &value); - vecPost.push_back(key); - vecPost.push_back(value); + vecGet.push_back(key); + vecGet.push_back(value); } } - } - auto handler = new CAjaxResourceHandler(vecGet, vecPost, mimeType); - pWebView->HandleAjaxRequest(resourcePath, handler); - return handler; - } - else - { - // Calculate MTA resource path - if (resourceName != "local") - path = ":" + resourceName + "/" + resourcePath; + CefPostData::ElementVector vecPostElements; + if (const auto postData = request->GetPostData(); postData) + { + postData->GetElements(vecPostElements); + + SString key; + SString value; + for (const auto& post : vecPostElements) + { + // Limit to 5MiB and allow byte data only + constexpr size_t MAX_POST_SIZE = 5 * 1024 * 1024; + size_t bytesCount = post->GetBytesCount(); + if (bytesCount > MAX_POST_SIZE || post->GetType() != CefPostDataElement::Type::PDE_TYPE_BYTES) + continue; + + // Make string from buffer + const auto buffer = std::make_unique(bytesCount); + // Verify GetBytes succeeded before using buffer + const size_t bytesRead = post->GetBytes(bytesCount, buffer.get()); + if (bytesRead != bytesCount) + continue; + const SStringX postParam(buffer.get(), bytesCount); + + // Parse POST data into vector + std::vector vecTmp; + vecTmp.reserve(8); + postParam.Split("&", vecTmp); + + const size_t postParamCount = vecTmp.size(); + if (postParamCount > 0) + vecPost.reserve(vecPost.size() + postParamCount * 2); + + for (auto&& param : vecTmp) + { + param.Split("=", &key, &value); + vecPost.push_back(key); + vecPost.push_back(value); + } + } + } + + CefRefPtr handler(new CAjaxResourceHandler(std::move(vecGet), std::move(vecPost), mimeType)); + pWebView->HandleAjaxRequest(resourcePath, handler.get()); + return handler; + } else - path = resourcePath; + { + // Calculate MTA resource path + static constexpr auto LOCAL = "local"; + path = (resourceName != LOCAL) ? SString(":" + resourceName + "/" + resourcePath) : resourcePath; - // Calculate absolute path - if (!pWebView->GetFullPathFromLocal(path)) - return HandleError("404 - Not found", 404); + // Calculate absolute path + if (!pWebView->GetFullPathFromLocal(path)) + { + static constexpr auto ERROR_404 = "404 - Not found"; + static constexpr unsigned int CODE_404 = 404; + return HandleError(ERROR_404, CODE_404); + } - // Verify local files - CBuffer fileData; - if (!pWebView->VerifyFile(path, fileData)) - return HandleError("403 - Access Denied", 403); + // Verify local files + CBuffer fileData; + if (!pWebView->VerifyFile(path, fileData)) + { + static constexpr auto ERROR_403 = "403 - Access Denied"; + static constexpr unsigned int CODE_403 = 403; + return HandleError(ERROR_403, CODE_403); + } - // Finally, load the file stream - if (fileData.GetData() == nullptr || fileData.GetSize() == 0) - fileData = CBuffer("", sizeof("")); + // Finally, load the file stream + if (!fileData.GetData() || fileData.GetSize() == 0) + { + static constexpr char emptyStr[] = ""; + fileData = CBuffer(emptyStr, std::size(emptyStr)); + } - auto stream = CefStreamReader::CreateForData(fileData.GetData(), fileData.GetSize()); - if (stream.get()) - return new CefStreamResourceHandler(mimeType, stream); - return HandleError("404 - Not found", 404); + auto stream = CefStreamReader::CreateForData(fileData.GetData(), fileData.GetSize()); + if (!stream) + { + static constexpr auto ERROR_404 = "404 - Not found"; + static constexpr unsigned int CODE_404 = 404; + return HandleError(ERROR_404, CODE_404); + } + + return CefRefPtr(new CefStreamResourceHandler(mimeType, stream)); + } } } diff --git a/Client/cefweb/CWebApp.h b/Client/cefweb/CWebApp.h index 914031b259e..b50c26587ee 100644 --- a/Client/cefweb/CWebApp.h +++ b/Client/cefweb/CWebApp.h @@ -9,14 +9,18 @@ #pragma once #include #include +#include -class CWebApp : public CefApp, public CefSchemeHandlerFactory +class CWebApp : public CefApp, public CefSchemeHandlerFactory, public CefBrowserProcessHandler { public: // Error Handler static CefRefPtr HandleError(const SString& strError, unsigned int uiError); virtual void OnBeforeCommandLineProcessing(const CefString& process_type, CefRefPtr command_line) override; + virtual void OnBeforeChildProcessLaunch(CefRefPtr command_line) override; + + virtual CefRefPtr GetBrowserProcessHandler() override; // CefSchemeHandlerFactory methods virtual CefRefPtr Create(CefRefPtr browser, CefRefPtr frame, const CefString& scheme_name, diff --git a/Client/cefweb/CWebAppAuth.h b/Client/cefweb/CWebAppAuth.h new file mode 100644 index 00000000000..2f2a9616a24 --- /dev/null +++ b/Client/cefweb/CWebAppAuth.h @@ -0,0 +1,96 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: cefweb/CWebAppAuth.h + * PURPOSE: IPC authentication code generation for browser process + * + *****************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include + +// Forward declarations +class CWebCore; +class CCoreInterface; +extern CCoreInterface* g_pCore; + +// Note: IsReadablePointer is available via StdInc.h which includes SharedUtil.h + +namespace WebAppAuth +{ + // Shared auth code storage (used by both generation and validation) + inline std::string& GetSharedAuthCode() + { + static std::string sharedAuthCode; + return sharedAuthCode; + } + + inline std::mutex& GetSharedAuthMutex() + { + static std::mutex sharedMutex; + return sharedMutex; + } + + inline bool& GetSyncedToWebCoreFlag() + { + static bool syncedToWebCore = false; + return syncedToWebCore; + } + + // Thread-safe auth code generation + inline std::mutex& GetAuthCodeMutex() + { + static std::mutex mutex; + return mutex; + } + + // Auth code configuration + inline constexpr std::size_t AUTH_CODE_LENGTH = 30; + inline constexpr char AUTH_CODE_MIN_CHAR = 'A'; + inline constexpr char AUTH_CODE_MAX_CHAR = 'Z'; + + // Generates random 30-character auth code (A-Z) + [[nodiscard]] inline std::string GenerateAuthCode() + { + std::array buffer{}; + + // Use mt19937 with time-based seed (fast, cryptographic strength not needed for DoS prevention) + static std::mt19937 rng(static_cast(std::chrono::high_resolution_clock::now().time_since_epoch().count())); + std::uniform_int_distribution dist(0, AUTH_CODE_MAX_CHAR - AUTH_CODE_MIN_CHAR); + + for (auto& ch : buffer) + ch = static_cast(AUTH_CODE_MIN_CHAR + dist(rng)); + + return std::string(buffer.data(), buffer.size()); + } + + // Generates and attaches auth code to child process command line + inline void AttachAuthCodeToCommandLine(CefRefPtr commandLine) + { + if (!commandLine) [[unlikely]] + return; + + const std::lock_guard lock{GetSharedAuthMutex()}; + + // Always use webCore->m_AuthCode (already populated in CWebCore constructor) + // No need for fallback - webCore is guaranteed to exist before this is called + if (!::g_pCore || !IsReadablePointer(::g_pCore, sizeof(void*))) [[unlikely]] + return; + + auto* const webCore = static_cast(::g_pCore->GetWebCore()); + if (!webCore || !IsReadablePointer(webCore, sizeof(void*))) [[unlikely]] + return; + + // webCore->m_AuthCode already populated in CWebCore::CWebCore() + if (webCore->m_AuthCode.empty()) [[unlikely]] + return; + + commandLine->AppendSwitchWithValue("kgfiv8n", webCore->m_AuthCode); + } +} diff --git a/Client/cefweb/CWebCore.cpp b/Client/cefweb/CWebCore.cpp index abe2c622876..6336bb03cfd 100644 --- a/Client/cefweb/CWebCore.cpp +++ b/Client/cefweb/CWebCore.cpp @@ -17,18 +17,45 @@ #include #include "WebBrowserHelpers.h" #include "CWebApp.h" +#include "CWebAppAuth.h" // For GenerateAuthCode() +#include +#include +#include +#include // #define CEF_ENABLE_SANDBOX #ifdef CEF_ENABLE_SANDBOX #pragma comment(lib, "cef_sandbox.lib") #endif +CWebCore::EventEntry::EventEntry(const std::function& callback_, CWebView* pWebView_) : callback(callback_), pWebView(pWebView_) +{ +} + +#ifdef MTA_DEBUG +CWebCore::EventEntry::EventEntry(const std::function& callback_, CWebView* pWebView_, const SString& name_) + : callback(callback_), pWebView(pWebView_), name(name_) +{ +} +#endif + +CWebCore::TaskEntry::TaskEntry(std::function callback, CWebView* webView) : task(callback), webView(webView) +{ +} + CWebCore::CWebCore() { m_pRequestsGUI = nullptr; m_bTestmodeEnabled = false; m_pXmlConfig = nullptr; m_pFocusedWebView = nullptr; + m_bGPUEnabled = false; + m_bInitialised = false; + m_iWhitelistRevision = 0; + m_iBlacklistRevision = 0; + + // Initialize auth code BEFORE CefInitialize (ensures webCore->m_AuthCode populated early) + m_AuthCode = WebAppAuth::GenerateAuthCode(); MakeSureXMLNodesExist(); InitialiseWhiteAndBlacklist(); @@ -39,23 +66,193 @@ CWebCore::CWebCore() CWebCore::~CWebCore() { - // Unregister schema factories + std::ranges::for_each(m_WebViews, + [](const auto& pWebView) + { + if (pWebView) [[likely]] + pWebView->CloseBrowser(); + }); + m_WebViews.clear(); CefClearSchemeHandlerFactories(); - // Shutdown CEF - CefShutdown(); - + // Don't call CefShutdown() here to avoid freeze. + // TerminateProcess (during quit) is called before CCore destruction anyways. delete m_pRequestsGUI; delete m_pXmlConfig; } bool CWebCore::Initialise(bool gpuEnabled) { - CefMainArgs mainArgs; - void* sandboxInfo = nullptr; + // CefInitialize() can only be called once per process lifetime + // Do not call this function again or recreate CWebCore if initialization fails + // Repeated calls cause "Timeout of new browser info response for frame" errors m_bGPUEnabled = gpuEnabled; + // Get MTA base directory + SString strBaseDir = SharedUtil::GetMTAProcessBaseDir(); + + if (strBaseDir.empty()) + { + g_pCore->GetConsole()->Printf("CEF initialization skipped - Unable to determine MTA base directory"); + AddReportLog(8000, "CEF initialization skipped - Unable to determine MTA base directory"); + m_bInitialised = false; + return false; + } + + SString strMTADir = PathJoin(strBaseDir, "MTA"); + +#ifndef MTA_DEBUG + SString strLauncherPath = PathJoin(strMTADir, "CEF", "CEFLauncher.exe"); +#else + SString strLauncherPath = PathJoin(strMTADir, "CEF", "CEFLauncher_d.exe"); +#endif + + // Set DLL directory for CEFLauncher subprocess to locate required libraries + SString strCEFDir = PathJoin(strMTADir, "CEF"); +#ifdef _WIN32 + SetDllDirectoryW(FromUTF8(strCEFDir)); +#else + // On Wine/Proton: Use environment variable for library search + const char* existingPath = std::getenv("LD_LIBRARY_PATH"); + SString newPath = strCEFDir; + if (existingPath) + { + newPath = SString("%s:%s", strCEFDir.c_str(), existingPath); + } + // Note: setenv is not available in MSVC, but _putenv is. + // However, since we are compiling for Windows (running on Wine), we use Windows APIs. + // Wine maps Windows environment variables. + // But LD_LIBRARY_PATH is a Linux variable. + // If we are in Wine, we might want to set PATH instead or as well. + // SetDllDirectoryW handles the Windows loader. + + // Log for debugging + if (std::getenv("WINE") || std::getenv("WINEPREFIX")) + { + g_pCore->GetConsole()->Printf("DEBUG: CEF library path set via SetDllDirectoryW: %s", strCEFDir.c_str()); + } +#endif + + // Read GTA path from registry to pass to CEF subprocess + int iRegistryResult = 0; + const SString strGTAPath = GetCommonRegistryValue("", "GTA:SA Path", &iRegistryResult); + + // Check if process is running with elevated privileges + // CEF subprocesses may have communication issues when running elevated + const bool bIsElevated = []() -> bool + { + // Check for Wine environment + if (std::getenv("WINE") || std::getenv("WINEPREFIX")) + { + // In Wine, privilege escalation works differently + // Assume not elevated for browser feature purposes + return false; + } + + HANDLE hToken = nullptr; + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) + return false; + + // RAII wrapper for token handle + const std::unique_ptr tokenGuard(hToken, &CloseHandle); + + TOKEN_ELEVATION elevation{}; + DWORD dwSize = sizeof(elevation); + if (!GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &dwSize)) + return false; + + return elevation.TokenIsElevated != 0; + }(); + + if (bIsElevated && !std::getenv("WINE")) + { + g_pCore->GetConsole()->Printf("WARNING: Running as Administrator - browser features may be limited"); + } + + // Verify CEFLauncher can run in current environment + auto CanExecuteCEFLauncher = []() -> bool + { +#ifdef _WIN32 + // On Windows, we know it works + if (!std::getenv("WINE") && !std::getenv("WINEPREFIX") && !std::getenv("PROTON_VERSION")) + return true; +#endif + + // Check if Wine can execute the launcher + // This is a basic check - if we are in Wine, we assume it works unless proven otherwise + // But we can log if we are in a mixed environment + return true; + }; + + if (!FileExists(strLauncherPath)) + { + g_pCore->GetConsole()->Printf("CEF initialization skipped - CEFLauncher not found: %s", *strLauncherPath); + AddReportLog(8001, SString("CEF initialization skipped - CEFLauncher not found: %s", *strLauncherPath)); + m_bInitialised = false; + return false; + } + + if (!CanExecuteCEFLauncher()) + { + g_pCore->GetConsole()->Printf("CEF initialization skipped - Wine/Proton not available"); + AddReportLog(8026, "CEF initialization skipped - Wine/Proton not available or misconfigured"); + m_bInitialised = false; + return false; + } + + // Ensure cache directory can be created + const SString strCachePath = PathJoin(strMTADir, "CEF", "cache"); + MakeSureDirExists(strCachePath); + + // Verify locales directory exists + const SString strLocalesPath = PathJoin(strMTADir, "CEF", "locales"); + if (!DirectoryExists(strLocalesPath)) + { + g_pCore->GetConsole()->Printf("CEF initialization skipped - locales directory not found: %s", *strLocalesPath); + AddReportLog(8002, SString("CEF initialization skipped - locales directory not found: %s", *strLocalesPath)); + m_bInitialised = false; + return false; + } + + // Use std::filesystem for CWD management with RAII scope guard + namespace fs = std::filesystem; + std::error_code ec; + + // Save current working directory + const fs::path savedCwd = fs::current_path(ec); + if (ec) + { + AddReportLog(8025, SString("Failed to get current directory: %s", ec.message().c_str())); + m_bInitialised = false; + return false; + } + + // RAII scope guard to restore CWD, even if CefInitialize throws or returns early + struct CwdGuard + { + fs::path savedPath; + explicit CwdGuard(fs::path path) : savedPath(std::move(path)) {} + ~CwdGuard() + { + std::error_code restoreEc; + fs::current_path(savedPath, restoreEc); + } + } cwdGuard(savedCwd); + + // Temporarily change CWD to MTA directory for CefInitialize + // CEFLauncher.exe requires this to locate CEF dependencies + fs::current_path(fs::path(FromUTF8(strMTADir)), ec); + if (ec) + { + AddReportLog(8026, SString("Failed to change CWD to MTA dir: %s", ec.message().c_str())); + m_bInitialised = false; + return false; + } + + CefMainArgs mainArgs; + void* sandboxInfo = nullptr; + CefRefPtr app(new CWebApp); #ifdef CEF_ENABLE_SANDBOX @@ -64,19 +261,15 @@ bool CWebCore::Initialise(bool gpuEnabled) #endif CefSettings settings; + CefString(&settings.browser_subprocess_path).FromWString(FromUTF8(strLauncherPath)); #ifndef CEF_ENABLE_SANDBOX settings.no_sandbox = true; #endif - // Specifiy sub process executable path -#ifndef MTA_DEBUG - CefString(&settings.browser_subprocess_path).FromWString(FromUTF8(CalcMTASAPath("MTA\\CEF\\CEFLauncher.exe"))); -#else - CefString(&settings.browser_subprocess_path).FromWString(FromUTF8(CalcMTASAPath("MTA\\CEF\\CEFLauncher_d.exe"))); -#endif - CefString(&settings.cache_path).FromWString(FromUTF8(CalcMTASAPath("MTA\\CEF\\cache"))); - CefString(&settings.locales_dir_path).FromWString(FromUTF8(CalcMTASAPath("MTA\\CEF\\locales"))); - CefString(&settings.log_file).FromWString(FromUTF8(CalcMTASAPath("MTA\\CEF\\cefdebug.txt"))); + CefString(&settings.browser_subprocess_path).FromWString(FromUTF8(strLauncherPath)); + CefString(&settings.cache_path).FromWString(FromUTF8(strCachePath)); + CefString(&settings.locales_dir_path).FromWString(FromUTF8(strLocalesPath)); + CefString(&settings.log_file).FromWString(FromUTF8(PathJoin(strMTADir, "CEF", "cefdebug.txt"))); #ifdef MTA_DEBUG settings.log_severity = cef_log_severity_t::LOGSEVERITY_INFO; #else @@ -86,17 +279,42 @@ bool CWebCore::Initialise(bool gpuEnabled) settings.multi_threaded_message_loop = true; settings.windowless_rendering_enabled = true; - bool state = CefInitialize(mainArgs, settings, app, sandboxInfo); + // Wrap CefInitialize in try-catch for exception safety + try + { + m_bInitialised = CefInitialize(mainArgs, settings, app, sandboxInfo); + } + catch (...) + { + g_pCore->GetConsole()->Printf("CefInitialize threw exception - CEF features will be disabled"); + AddReportLog(8003, "CefInitialize threw exception - CEF features will be disabled"); + m_bInitialised = false; + } + + // CWD will be restored by cwdGuard destructor when this function returns - // Register custom scheme handler factory - CefRegisterSchemeHandlerFactory("http", "mta", app); + if (m_bInitialised) + { + // Register custom scheme handler factory only if initialization succeeded + CefRegisterSchemeHandlerFactory("http", "mta", app); + } + else + { + // Log initialization failure + g_pCore->GetConsole()->Printf("CefInitialize failed - CEF features will be disabled"); + AddReportLog(8004, "CefInitialize failed - CEF features will be disabled"); + } - return state; + return m_bInitialised; } CWebViewInterface* CWebCore::CreateWebView(unsigned int uiWidth, unsigned int uiHeight, bool bIsLocal, CWebBrowserItem* pWebBrowserRenderItem, bool bTransparent) { + // Skip browser creation if CEF initialization failed + if (!m_bInitialised) + return nullptr; + // Create our webview implementation CefRefPtr pWebView = new CWebView(bIsLocal, pWebBrowserRenderItem, bTransparent); m_WebViews.push_back(pWebView); @@ -109,13 +327,22 @@ void CWebCore::DestroyWebView(CWebViewInterface* pWebViewInterface) CefRefPtr pWebView = dynamic_cast(pWebViewInterface); if (pWebView) { + // Mark as being destroyed to prevent new events/tasks + pWebView->SetBeingDestroyed(true); + // Ensure that no attached events or tasks are in the queue RemoveWebViewEvents(pWebView.get()); RemoveWebViewTasks(pWebView.get()); + // Remove from list before closing to break reference cycles early m_WebViews.remove(pWebView); - // pWebView->Release(); // Do not release since other references get corrupted then + + // CloseBrowser will eventually trigger OnBeforeClose which clears m_pWebView + // This breaks the circular reference: CWebView -> CefBrowser -> CWebView pWebView->CloseBrowser(); + + // Note: Do not call Release() - let CefRefPtr manage the lifecycle + // The circular reference is broken via OnBeforeClose setting m_pWebView = nullptr } } @@ -136,7 +363,7 @@ CWebView* CWebCore::FindWebView(CefRefPtr browser) if (!browser) return nullptr; - for (auto pWebView : m_WebViews) + for (const auto& pWebView : m_WebViews) { if (!pWebView) continue; @@ -162,7 +389,19 @@ void CWebCore::AddEventToEventQueue(std::function event, CWebView* pWebV if (pWebView && pWebView->IsBeingDestroyed()) return; - std::lock_guard lock(m_EventQueueMutex); + std::scoped_lock lock(m_EventQueueMutex); + + // Prevent unbounded queue growth - drop oldest events if queue is too large + if (m_EventQueue.size() >= MAX_EVENT_QUEUE_SIZE) + { + // Log warning even in release builds as this indicates a serious issue + g_pCore->GetConsole()->Printf("WARNING: Browser event queue size limit reached (%d), dropping oldest events", MAX_EVENT_QUEUE_SIZE); + + // Remove oldest 10% of events to make room + auto removeCount = static_cast(MAX_EVENT_QUEUE_SIZE / 10); + for (auto i = size_t{0}; i < removeCount && !m_EventQueue.empty(); ++i) + m_EventQueue.pop_front(); + } #ifndef MTA_DEBUG m_EventQueue.push_back(EventEntry(event, pWebView)); @@ -173,7 +412,7 @@ void CWebCore::AddEventToEventQueue(std::function event, CWebView* pWebV void CWebCore::RemoveWebViewEvents(CWebView* pWebView) { - std::lock_guard lock(m_EventQueueMutex); + std::scoped_lock lock(m_EventQueueMutex); for (auto iter = m_EventQueue.begin(); iter != m_EventQueue.end();) { @@ -188,12 +427,16 @@ void CWebCore::DoEventQueuePulse() { std::list eventQueue; { - std::lock_guard lock(m_EventQueueMutex); + std::scoped_lock lock(m_EventQueueMutex); std::swap(eventQueue, m_EventQueue); } for (auto& event : eventQueue) { + // Skip event if the associated WebView is being destroyed + if (event.pWebView && event.pWebView->IsBeingDestroyed()) + continue; + event.callback(); } @@ -215,6 +458,20 @@ void CWebCore::WaitForTask(std::function task, CWebView* webView) std::future result; { std::scoped_lock lock(m_TaskQueueMutex); + + // Prevent unbounded queue growth - abort new task if queue is too large + if (m_TaskQueue.size() >= MAX_TASK_QUEUE_SIZE) [[unlikely]] + { +#ifdef MTA_DEBUG + static constexpr auto WARNING_MSG = "Warning: Task queue size limit reached (%d), aborting new task"; + g_pCore->GetConsole()->Printf(WARNING_MSG, MAX_TASK_QUEUE_SIZE); +#endif + // Abort the new task immediately to prevent deadlock + // Don't add it to the queue + task(true); + return; + } + m_TaskQueue.emplace_back(TaskEntry{task, webView}); result = m_TaskQueue.back().task.get_future(); } @@ -226,14 +483,16 @@ void CWebCore::RemoveWebViewTasks(CWebView* webView) { std::scoped_lock lock(m_TaskQueueMutex); - for (auto iter = m_TaskQueue.begin(); iter != m_TaskQueue.end(); ++iter) - { - if (iter->webView != webView) - continue; - - iter->task(true); - iter = m_TaskQueue.erase(iter); - } + std::erase_if(m_TaskQueue, + [webView](TaskEntry& entry) + { + if (entry.webView == webView) + { + entry.task(true); + return true; + } + return false; + }); } void CWebCore::DoTaskQueuePulse() @@ -246,26 +505,32 @@ void CWebCore::DoTaskQueuePulse() for (TaskEntry& entry : taskQueue) { + // Abort task if the associated WebView is being destroyed + if (entry.webView && entry.webView->IsBeingDestroyed()) + { + entry.task(true); + continue; + } + entry.task(false); } } eURLState CWebCore::GetDomainState(const SString& strURL, bool bOutputDebug) { - std::lock_guard lock(m_FilterMutex); + std::scoped_lock lock(m_FilterMutex); // Initialize wildcard whitelist (be careful with modifying) | Todo: Think about the following - static SString wildcardWhitelist[] = {"*.googlevideo.com", "*.google.com", "*.youtube.com", "*.ytimg.com", - "*.vimeocdn.com", "*.gstatic.com", "*.googleapis.com", "*.ggpht.com"}; + static constexpr const char* wildcardWhitelist[] = {"*.googlevideo.com", "*.google.com", "*.youtube.com", "*.ytimg.com", + "*.vimeocdn.com", "*.gstatic.com", "*.googleapis.com", "*.ggpht.com"}; - for (int i = 0; i < sizeof(wildcardWhitelist) / sizeof(SString); ++i) + for (const auto& pattern : wildcardWhitelist) { - if (WildcardMatch(wildcardWhitelist[i], strURL)) + if (WildcardMatch(pattern, strURL)) return eURLState::WEBPAGE_ALLOWED; } - google::dense_hash_map::iterator iter = m_Whitelist.find(strURL); - if (iter != m_Whitelist.end()) + if (auto iter = m_Whitelist.find(strURL); iter != m_Whitelist.end()) { if (iter->second.first == true) return eURLState::WEBPAGE_ALLOWED; @@ -356,20 +621,53 @@ void CWebCore::InitialiseWhiteAndBlacklist(bool bAddHardcoded, bool bAddDynamic) void CWebCore::AddAllowedPage(const SString& strURL, eWebFilterType filterType) { - std::lock_guard lock(m_FilterMutex); + std::scoped_lock lock(m_FilterMutex); + + // Prevent unbounded whitelist growth - remove old REQUEST entries if limit reached + if (m_Whitelist.size() >= 50000) + { + // Remove WEBFILTER_REQUEST entries (temporary session entries) + for (auto iter = m_Whitelist.begin(); iter != m_Whitelist.end();) + { + if (iter->second.second == eWebFilterType::WEBFILTER_REQUEST) + m_Whitelist.erase(iter++); + else + ++iter; + } + } m_Whitelist[strURL] = std::pair(true, filterType); } void CWebCore::AddBlockedPage(const SString& strURL, eWebFilterType filterType) { - std::lock_guard lock(m_FilterMutex); + std::scoped_lock lock(m_FilterMutex); + + // Prevent unbounded whitelist growth - remove old REQUEST entries if limit reached + if (m_Whitelist.size() >= 50000) + { + // Remove WEBFILTER_REQUEST entries (temporary session entries) + for (auto iter = m_Whitelist.begin(); iter != m_Whitelist.end();) + { + if (iter->second.second == eWebFilterType::WEBFILTER_REQUEST) + m_Whitelist.erase(iter++); + else + ++iter; + } + } m_Whitelist[strURL] = std::pair(false, filterType); } void CWebCore::RequestPages(const std::vector& pages, WebRequestCallback* pCallback) { + if (m_PendingRequests.size() >= MAX_PENDING_REQUESTS) + { + if (pCallback) + (*pCallback)(false, std::unordered_set(pages.begin(), pages.end())); + return; + } + // Add to pending pages queue bool bNewItem = false; for (const auto& page : pages) @@ -378,8 +676,9 @@ void CWebCore::RequestPages(const std::vector& pages, WebRequestCallbac if (status == eURLState::WEBPAGE_ALLOWED || status == eURLState::WEBPAGE_DISALLOWED) continue; - m_PendingRequests.insert(page); - bNewItem = true; + const auto [iter, inserted] = m_PendingRequests.insert(page); + if (inserted) + bNewItem = true; } if (bNewItem) @@ -417,8 +716,8 @@ std::unordered_set CWebCore::AllowPendingPages(bool bRemember) if (bRemember) { - std::vector> result; // Contains only allowed entries - g_pCore->GetWebCore()->GetFilterEntriesByType(result, eWebFilterType::WEBFILTER_USER, eWebFilterState::WEBFILTER_ALLOWED); + std::vector> result; // Contains only allowed entries + GetFilterEntriesByType(result, eWebFilterType::WEBFILTER_USER, eWebFilterState::WEBFILTER_ALLOWED); std::vector customWhitelist; for (std::vector>::iterator iter = result.begin(); iter != result.end(); ++iter) customWhitelist.push_back(iter->first); @@ -427,7 +726,7 @@ std::unordered_set CWebCore::AllowPendingPages(bool bRemember) } auto allowedRequests(std::move(m_PendingRequests)); - m_PendingRequests.clear(); // MSVC's move constructor already clears the list which isn't specified by the C++ standard though + m_PendingRequests.clear(); // MSVC's move constructor already clears the list which isn't specified by the C++ standard though return allowedRequests; } @@ -467,7 +766,7 @@ bool CWebCore::GetRemoteJavascriptEnabled() void CWebCore::OnPreScreenshot() { // Clear all textures - g_pCore->GetWebCore()->ClearTextures(); + ClearTextures(); } void CWebCore::OnPostScreenshot() @@ -479,6 +778,16 @@ void CWebCore::OnPostScreenshot() } } +void CWebCore::OnFPSLimitChange(std::uint16_t fps) +{ + dassert(g_pCore->GetNetwork() != nullptr); // Ensure network module is loaded + for (auto& webView : m_WebViews) + { + if (auto browser = webView->GetCefBrowser(); browser) [[likely]] + browser->GetHost()->SetWindowlessFrameRate(fps); + } +} + void CWebCore::ProcessInputMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { if (!m_pFocusedWebView || @@ -502,7 +811,7 @@ void CWebCore::ProcessInputMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) if ((keyEvent.type == KEYEVENT_CHAR) && isKeyDown(VK_RMENU)) { HKL current_layout = ::GetKeyboardLayout(0); - SHORT scan_res = ::VkKeyScanExW(wParam, current_layout); + SHORT scan_res = ::VkKeyScanExW(static_cast(wParam), current_layout); if ((HIBYTE(scan_res) & (2 | 4)) == (2 | 4)) { keyEvent.modifiers &= ~(EVENTFLAG_CONTROL_DOWN | EVENTFLAG_ALT_DOWN); @@ -533,6 +842,11 @@ bool CWebCore::SetGlobalAudioVolume(float fVolume) return true; } +CWebViewInterface* CWebCore::GetFocusedWebView() +{ + return m_pFocusedWebView; +} + bool CWebCore::UpdateListsFromMaster() { if (!m_pXmlConfig) @@ -744,7 +1058,7 @@ void CWebCore::GetFilterEntriesByType(std::vector>& out outEntries.push_back(std::pair(iter->first, iter->second.first)); else if (state == eWebFilterState::WEBFILTER_ALLOWED && iter->second.first == true) outEntries.push_back(std::pair(iter->first, iter->second.first)); - else + else if (state == eWebFilterState::WEBFILTER_DISALLOWED && iter->second.first == false) outEntries.push_back(std::pair(iter->first, iter->second.first)); } } @@ -753,8 +1067,14 @@ void CWebCore::GetFilterEntriesByType(std::vector>& out void CWebCore::StaticFetchRevisionFinished(const SHttpDownloadResult& result) { CWebCore* pWebCore = static_cast(result.pObj); + if (!pWebCore) [[unlikely]] + return; + if (result.bSuccess) { + if (result.dataSize > 1024 * 1024) [[unlikely]] + return; + SString strData = result.pData; SString strWhiteRevision, strBlackRevision; strData.Split(";", &strWhiteRevision, &strBlackRevision); @@ -793,16 +1113,30 @@ void CWebCore::StaticFetchWhitelistFinished(const SHttpDownloadResult& result) return; CWebCore* pWebCore = static_cast(result.pObj); + if (!pWebCore) [[unlikely]] + return; + if (!pWebCore->m_pXmlConfig) return; if (!pWebCore->MakeSureXMLNodesExist()) return; + if (result.dataSize > 5 * 1024 * 1024) [[unlikely]] + { + return; + } + CXMLNode* pRootNode = pWebCore->m_pXmlConfig->GetRootNode(); std::vector whitelist; SString strData = result.pData; strData.Split(";", whitelist); + + if (whitelist.size() > 50000) [[unlikely]] + { + whitelist.resize(50000); + } + CXMLNode* pListNode = pRootNode->FindSubNode("globalwhitelist"); if (!pListNode) return; @@ -836,16 +1170,30 @@ void CWebCore::StaticFetchBlacklistFinished(const SHttpDownloadResult& result) return; CWebCore* pWebCore = static_cast(result.pObj); + if (!pWebCore) [[unlikely]] + return; + if (!pWebCore->m_pXmlConfig) return; if (!pWebCore->MakeSureXMLNodesExist()) return; + if (result.dataSize > 5 * 1024 * 1024) [[unlikely]] + { + return; + } + CXMLNode* pRootNode = pWebCore->m_pXmlConfig->GetRootNode(); std::vector blacklist; SString strData = result.pData; strData.Split(";", blacklist); + + if (blacklist.size() > 50000) [[unlikely]] + { + blacklist.resize(50000); + } + CXMLNode* pListNode = pRootNode->FindSubNode("globalblacklist"); if (!pListNode) return; diff --git a/Client/cefweb/CWebCore.h b/Client/cefweb/CWebCore.h index 006f8d2e760..9b82d612491 100644 --- a/Client/cefweb/CWebCore.h +++ b/Client/cefweb/CWebCore.h @@ -17,44 +17,50 @@ #include #include #include -#define MTA_BROWSERDATA_PATH "mta/cef/browserdata.xml" -#define BROWSER_LIST_UPDATE_INTERVAL (24*60*60) -#define BROWSER_UPDATE_URL "https://cef.multitheftauto.com/get.php" -#define GetNextSibling(hwnd) GetWindow(hwnd, GW_HWNDNEXT) // Re-define the conflicting macro -#define GetFirstChild(hwnd) GetTopWindow(hwnd) +#define MTA_BROWSERDATA_PATH "mta/cef/browserdata.xml" +#define BROWSER_LIST_UPDATE_INTERVAL (24 * 60 * 60) +#define BROWSER_UPDATE_URL "https://cef.multitheftauto.com/get.php" +#define MAX_EVENT_QUEUE_SIZE 10000 +#define MAX_TASK_QUEUE_SIZE 1000 +#define MAX_WHITELIST_SIZE 50000 +#define MAX_PENDING_REQUESTS 100 +#define GetNextSibling(hwnd) GetWindow(hwnd, GW_HWNDNEXT) // Re-define the conflicting macro +#define GetFirstChild(hwnd) GetTopWindow(hwnd) class CWebBrowserItem; class CWebsiteRequests; class CWebView; +class CWebViewInterface; class CWebCore : public CWebCoreInterface { struct EventEntry { std::function callback; - CWebView* pWebView; - #ifdef MTA_DEBUG + CefRefPtr pWebView; +#ifdef MTA_DEBUG SString name; - #endif +#endif - EventEntry(const std::function& callback_, CWebView* pWebView_) : callback(callback_), pWebView(pWebView_) {} + EventEntry(const std::function& callback_, CWebView* pWebView_); #ifdef MTA_DEBUG - EventEntry(const std::function& callback_, CWebView* pWebView_, const SString& name_) : callback(callback_), pWebView(pWebView_), name(name_) {} + EventEntry(const std::function& callback_, CWebView* pWebView_, const SString& name_); #endif }; struct TaskEntry { std::packaged_task task; - CWebView* webView; + CefRefPtr webView; - TaskEntry(std::function callback, CWebView* webView) : task(callback), webView(webView) {} + TaskEntry(std::function callback, CWebView* webView); }; public: CWebCore(); ~CWebCore(); bool Initialise(bool gpuEnabled) override; + bool IsInitialised() const noexcept override { return m_bInitialised; } CWebViewInterface* CreateWebView(unsigned int uiWidth, unsigned int uiHeight, bool bIsLocal, CWebBrowserItem* pWebBrowserRenderItem, bool bTransparent); void DestroyWebView(CWebViewInterface* pWebViewInterface); @@ -85,7 +91,7 @@ class CWebCore : public CWebCoreInterface void SetTestModeEnabled(bool bEnabled) { m_bTestmodeEnabled = bEnabled; }; void DebugOutputThreadsafe(const SString& message, unsigned char R, unsigned char G, unsigned char B); - CWebViewInterface* GetFocusedWebView() { return (CWebViewInterface*)m_pFocusedWebView; }; + CWebViewInterface* GetFocusedWebView(); void SetFocusedWebView(CWebView* pWebView) { m_pFocusedWebView = pWebView; }; void ProcessInputMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); void ClearTextures(); @@ -96,6 +102,8 @@ class CWebCore : public CWebCoreInterface void OnPreScreenshot(); void OnPostScreenshot(); + void OnFPSLimitChange(std::uint16_t fps) override; + bool SetGlobalAudioVolume(float fVolume); bool UpdateListsFromMaster(); @@ -134,4 +142,10 @@ class CWebCore : public CWebCoreInterface // Shouldn't be changed after init bool m_bGPUEnabled; + bool m_bInitialised = false; // Track if CefInitialize() succeeded + + // ===== AUTH: IPC message validation ===== +public: + std::string m_AuthCode; // Random 30-char code for validating browser IPC messages + // ===== END AUTH ===== }; diff --git a/Client/cefweb/CWebView.cpp b/Client/cefweb/CWebView.cpp index da6aa327495..c1a64b72297 100644 --- a/Client/cefweb/CWebView.cpp +++ b/Client/cefweb/CWebView.cpp @@ -13,6 +13,9 @@ #include #include #include "CWebDevTools.h" +#include +#include "CWebViewAuth.h" // AUTH: IPC validation helpers +#include namespace { @@ -21,9 +24,13 @@ namespace CWebView::CWebView(bool bIsLocal, CWebBrowserItem* pWebBrowserRenderItem, bool bTransparent) { + m_pEventTarget = std::make_shared(); m_bIsLocal = bIsLocal; m_bIsTransparent = bTransparent; m_pWebBrowserRenderItem = pWebBrowserRenderItem; + if (m_pWebBrowserRenderItem) + m_pWebBrowserRenderItem->AddRef(); + m_pEventsInterface = nullptr; m_bBeingDestroyed = false; m_fVolume = 1.0f; @@ -35,33 +42,104 @@ CWebView::CWebView(bool bIsLocal, CWebBrowserItem* pWebBrowserRenderItem, bool b CWebView::~CWebView() { + m_bBeingDestroyed = true; + + if (m_pEventTarget) + m_pEventTarget->Clear(m_pEventsInterface); + if (IsMainThread()) { - if (g_pCore->GetWebCore()->GetFocusedWebView() == this) - g_pCore->GetWebCore()->SetFocusedWebView(nullptr); + if (auto pWebCore = g_pCore->GetWebCore(); pWebCore) + { + if (pWebCore->GetFocusedWebView() == this) + pWebCore->SetFocusedWebView(nullptr); + } + } + + if (m_pWebBrowserRenderItem) + { + m_pWebBrowserRenderItem->Release(); + m_pWebBrowserRenderItem = nullptr; } // Make sure we don't dead lock the CEF render thread ResumeCefThread(); - // Ensure that CefRefPtr::~CefRefPtr doesn't try to release it twice (it has already been released in CWebView::OnBeforeClose) - m_pWebView = nullptr; + // Clean up AJAX handlers to prevent accumulation + m_AjaxHandlers.clear(); + + // Break circular reference: ensure browser reference is cleared + // This is to prevent memory leaks from CWebView <-> CefBrowser cycles + if (m_pWebView) + { + // Stop any loading immediately + m_pWebView->StopLoad(); + + // Navigate to blank page to force V8/DOM cleanup and release video/audio resources + // We do this BEFORE hiding to ensure the navigation request is processed + m_pWebView->GetMainFrame()->LoadURL("about:blank"); + + // Notify that the browser is hidden and lost focus to release rendering resources + m_pWebView->GetHost()->WasHidden(true); + m_pWebView->GetHost()->SetFocus(false); + + // Force close the browser host to ensure the renderer process terminates immediately + m_pWebView->GetHost()->CloseBrowser(true); + m_pWebView = nullptr; + } OutputDebugLine("CWebView::~CWebView"); } +void CWebView::SetWebBrowserEvents(CWebBrowserEventsInterface* pInterface) +{ + m_pEventsInterface = pInterface; + + if (m_pEventTarget) + m_pEventTarget->Assign(pInterface); +} + +void CWebView::ClearWebBrowserEvents(CWebBrowserEventsInterface* pInterface) +{ + if (m_pEventTarget) + m_pEventTarget->Clear(pInterface); + + if (m_pEventsInterface == pInterface) + m_pEventsInterface = nullptr; +} + +void CWebView::QueueBrowserEvent(const char* name, std::function&& fn) +{ + auto target = m_pEventTarget; + if (!target) + return; + + const auto token = target->CreateDispatchToken(); + + g_pCore->GetWebCore()->AddEventToEventQueue( + [target, token, fn = std::move(fn)]() mutable + { + if (!target) + return; + + target->Dispatch(token, fn); + }, + this, name); +} + void CWebView::Initialise() { // Initialise the web session (which holds the actual settings) in in-memory mode CefBrowserSettings browserSettings; - browserSettings.windowless_frame_rate = g_pCore->GetFrameRateLimit(); + browserSettings.windowless_frame_rate = g_pCore->GetFPSLimiter()->GetFPSTarget(); browserSettings.javascript_access_clipboard = cef_state_t::STATE_DISABLED; browserSettings.javascript_dom_paste = cef_state_t::STATE_DISABLED; browserSettings.webgl = cef_state_t::STATE_ENABLED; if (!m_bIsLocal) { - bool bEnabledJavascript = g_pCore->GetWebCore()->GetRemoteJavascriptEnabled(); + const auto pWebCore = g_pCore->GetWebCore(); + const bool bEnabledJavascript = pWebCore ? pWebCore->GetRemoteJavascriptEnabled() : false; browserSettings.javascript = bEnabledJavascript ? cef_state_t::STATE_ENABLED : cef_state_t::STATE_DISABLED; } @@ -83,8 +161,25 @@ void CWebView::CloseBrowser() // Make sure we don't dead lock the CEF render thread ResumeCefThread(); + // Clear AJAX handlers early to prevent late event processing + m_AjaxHandlers.clear(); + if (m_pWebView) + { + // Stop any loading immediately + m_pWebView->StopLoad(); + + // Navigate to blank page to force V8/DOM cleanup and release video/audio resources + // We do this BEFORE hiding to ensure the navigation request is processed + m_pWebView->GetMainFrame()->LoadURL("about:blank"); + + // Notify that the browser is hidden and lost focus to release rendering resources + m_pWebView->GetHost()->WasHidden(true); + m_pWebView->GetHost()->SetFocus(false); + m_pWebView->GetHost()->CloseBrowser(true); + m_pWebView = nullptr; + } } bool CWebView::LoadURL(const SString& strURL, bool bFilterEnabled, const SString& strPostData, bool bURLEncoded) @@ -94,11 +189,15 @@ bool CWebView::LoadURL(const SString& strURL, bool bFilterEnabled, const SString CefURLParts urlParts; if (strURL.empty() || !CefParseURL(strURL, urlParts)) - return false; // Invalid URL + return false; // Invalid URL // Are we allowed to browse this website? - if (bFilterEnabled && g_pCore->GetWebCore()->GetDomainState(UTF16ToMbUTF8(urlParts.host.str), true) != eURLState::WEBPAGE_ALLOWED) - return false; + if (bFilterEnabled) + { + auto pWebCore = g_pCore->GetWebCore(); + if (pWebCore && pWebCore->GetDomainState(UTF16ToMbUTF8(urlParts.host.str), true) != eURLState::WEBPAGE_ALLOWED) + return false; + } // Load it! auto pFrame = m_pWebView->GetMainFrame(); @@ -163,6 +262,22 @@ void CWebView::SetRenderingPaused(bool bPaused) { m_pWebView->GetHost()->WasHidden(bPaused); m_bIsRenderingPaused = bPaused; + + if (bPaused) + { + // Free memory held by render data when paused + std::lock_guard lock{m_RenderData.dataMutex}; + m_RenderData.changed = false; + m_RenderData.popupShown = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.popupBuffer.reset(); + + // Release any waiting CEF thread + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + } } } @@ -176,116 +291,328 @@ void CWebView::Focus(bool state) if (m_pWebView) m_pWebView->GetHost()->SetFocus(state); + auto pWebCore = g_pCore->GetWebCore(); + if (!pWebCore) + return; + if (state) - g_pCore->GetWebCore()->SetFocusedWebView(this); - else if (g_pCore->GetWebCore()->GetFocusedWebView() == this) - g_pCore->GetWebCore()->SetFocusedWebView(nullptr); + pWebCore->SetFocusedWebView(this); + else if (pWebCore->GetFocusedWebView() == this) + pWebCore->SetFocusedWebView(nullptr); } void CWebView::ClearTexture() { - IDirect3DSurface9* pD3DSurface = m_pWebBrowserRenderItem->m_pD3DRenderTargetSurface; - if (!pD3DSurface) + if (!m_pWebBrowserRenderItem) [[unlikely]] + return; + + auto* const pD3DSurface = m_pWebBrowserRenderItem->m_pD3DRenderTargetSurface; + if (!pD3DSurface) [[unlikely]] return; D3DSURFACE_DESC SurfaceDesc; - if (FAILED(pD3DSurface->GetDesc(&SurfaceDesc))) + if (FAILED(pD3DSurface->GetDesc(&SurfaceDesc))) [[unlikely]] return; D3DLOCKED_RECT LockedRect; - if (SUCCEEDED(pD3DSurface->LockRect(&LockedRect, NULL, D3DLOCK_DISCARD))) + if (SUCCEEDED(pD3DSurface->LockRect(&LockedRect, nullptr, D3DLOCK_DISCARD))) { - memset(LockedRect.pBits, 0xFF, SurfaceDesc.Height * LockedRect.Pitch); + // Check for integer overflow in size calculation: height * pitch must fit in size_t + // Ensure both are positive and that multiplication won't overflow + if (SurfaceDesc.Height > 0 && LockedRect.Pitch > 0 && static_cast(SurfaceDesc.Height) <= SIZE_MAX / static_cast(LockedRect.Pitch)) + [[likely]] + { + const auto memsetSize = static_cast(SurfaceDesc.Height) * static_cast(LockedRect.Pitch); + std::memset(LockedRect.pBits, 0xFF, memsetSize); + } pD3DSurface->UnlockRect(); } } void CWebView::UpdateTexture() { - std::lock_guard lock(m_RenderData.dataMutex); + const std::scoped_lock lock(m_RenderData.dataMutex); - auto pSurface = m_pWebBrowserRenderItem->m_pD3DRenderTargetSurface; - if (m_bBeingDestroyed || !pSurface) + // Validate render item exists before accessing + if (!m_pWebBrowserRenderItem) [[unlikely]] + { m_RenderData.changed = m_RenderData.popupShown = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + return; + } + + auto* const pSurface = m_pWebBrowserRenderItem->m_pD3DRenderTargetSurface; + if (m_bBeingDestroyed || !pSurface) [[unlikely]] + { + m_RenderData.changed = m_RenderData.popupShown = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + return; + } // Discard current buffer if size doesn't match // This happens when resizing the browser as OnPaint is called asynchronously if (m_RenderData.changed && (m_pWebBrowserRenderItem->m_uiSizeX != m_RenderData.width || m_pWebBrowserRenderItem->m_uiSizeY != m_RenderData.height)) + { m_RenderData.changed = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + } - if (m_RenderData.changed || m_RenderData.popupShown) + if (m_RenderData.changed || m_RenderData.popupShown) [[likely]] { // Lock surface D3DLOCKED_RECT LockedRect; if (SUCCEEDED(pSurface->LockRect(&LockedRect, nullptr, 0))) { // Dirty rect implementation, don't use this as loops are significantly slower than memcpy - const auto destData = static_cast(LockedRect.pBits); - const auto sourceData = static_cast(m_RenderData.buffer); - const auto destPitch = LockedRect.Pitch; + auto* const destData = static_cast(LockedRect.pBits); + const auto* const sourceData = static_cast(m_RenderData.buffer); + const auto destPitch = LockedRect.Pitch; + + // Validate destination pitch + if (destPitch <= 0) [[unlikely]] + { + pSurface->UnlockRect(); + m_RenderData.changed = false; + m_RenderData.popupShown = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + return; + } + + // Validate sourcePitch calculation won't overflow + constexpr auto maxWidthForPitch = INT_MAX / CEF_PIXEL_STRIDE; + if (m_RenderData.width > maxWidthForPitch) [[unlikely]] + { + pSurface->UnlockRect(); + m_RenderData.changed = false; + m_RenderData.popupShown = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + return; + } const auto sourcePitch = m_RenderData.width * CEF_PIXEL_STRIDE; + // Validate source buffer exists before accessing it + if (!sourceData) [[unlikely]] + { + pSurface->UnlockRect(); + m_RenderData.changed = false; + m_RenderData.popupShown = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + return; + } + // Update view area - if (m_RenderData.changed) + if (m_RenderData.changed) [[likely]] { // Update changed state m_RenderData.changed = false; - if (m_RenderData.dirtyRects.size() > 0 && m_RenderData.dirtyRects[0].width == m_RenderData.width && - m_RenderData.dirtyRects[0].height == m_RenderData.height) + const auto& dirtyRects = m_RenderData.dirtyRects; + if (!dirtyRects.empty() && dirtyRects[0].width == m_RenderData.width && dirtyRects[0].height == m_RenderData.height) { // Note that D3D texture size can be hardware dependent(especially with dynamic texture) // When destination and source pitches differ we must copy pixels row by row - if (destPitch == sourcePitch) - memcpy(destData, sourceData, destPitch * m_RenderData.height); + if (destPitch == sourcePitch) [[likely]] + { + // Check for integer overflow in size calculation: height * pitch must fit in size_t + if (m_RenderData.height > 0 && static_cast(m_RenderData.height) > SIZE_MAX / static_cast(destPitch)) [[unlikely]] + { + pSurface->UnlockRect(); + m_RenderData.changed = false; + m_RenderData.popupShown = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + return; + } + std::memcpy(destData, sourceData, static_cast(destPitch) * static_cast(m_RenderData.height)); + } else { + // Ensure both pitches are positive before row-by-row copy + if (destPitch <= 0 || sourcePitch <= 0) [[unlikely]] + { + pSurface->UnlockRect(); + m_RenderData.changed = false; + m_RenderData.popupShown = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + return; + } + + // Check for integer overflow in size calculation for row-by-row copy + if (m_RenderData.height > 0 && (static_cast(m_RenderData.height) > SIZE_MAX / static_cast(destPitch) || + static_cast(m_RenderData.height) > SIZE_MAX / static_cast(sourcePitch))) [[unlikely]] + { + pSurface->UnlockRect(); + m_RenderData.changed = false; + m_RenderData.popupShown = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + return; + } + for (int y = 0; y < m_RenderData.height; ++y) { - const int sourceIndex = y * sourcePitch; - const int destIndex = y * destPitch; + // Use size_t for all calculations to prevent overflow + const auto sourceIndex = static_cast(y) * static_cast(sourcePitch); + const auto destIndex = static_cast(y) * static_cast(destPitch); + const auto copySize = std::min(static_cast(sourcePitch), static_cast(destPitch)); - memcpy(&destData[destIndex], &sourceData[sourceIndex], std::min(sourcePitch, destPitch)); + std::memcpy(&destData[destIndex], &sourceData[sourceIndex], copySize); } } } else { + // Check for integer overflow in destination size calculation + if (m_RenderData.height > 0 && static_cast(m_RenderData.height) > SIZE_MAX / static_cast(destPitch)) [[unlikely]] + { + pSurface->UnlockRect(); + m_RenderData.changed = false; + m_RenderData.popupShown = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + return; + } + // Update dirty rects - for (const auto& rect : m_RenderData.dirtyRects) + for (const auto& rect : dirtyRects) { - for (int y = rect.y; y < rect.y + rect.height; ++y) + // Validate dirty rect bounds to prevent buffer overflow + if (rect.x < 0 || rect.y < 0 || rect.width <= 0 || rect.height <= 0) [[unlikely]] + continue; + + // Check bounds using addition to prevent subtraction underflow + // rect.x + rect.width could overflow, so check rect.x and rect.width separately + if (rect.x >= m_RenderData.width || rect.y >= m_RenderData.height || rect.width > m_RenderData.width || + rect.height > m_RenderData.height || rect.x > m_RenderData.width - rect.width || rect.y > m_RenderData.height - rect.height) + [[unlikely]] + continue; + + // Pre-calculate end to prevent overflow in loop condition + const auto rectEndY = rect.y + rect.height; + + // Ensure we don't write past the destination pitch + if (static_cast(destPitch) < static_cast(rect.x + rect.width) * CEF_PIXEL_STRIDE) [[unlikely]] + continue; + + for (int y = rect.y; y < rectEndY; ++y) { // Note that D3D texture size can be hardware dependent(especially with dynamic texture) // We cannot be sure that source and destination pitches are the same - const int sourceIndex = y * sourcePitch + rect.x * CEF_PIXEL_STRIDE; - const int destIndex = y * destPitch + rect.x * CEF_PIXEL_STRIDE; + // Use size_t for all calculations to prevent integer overflow + const auto sourceIndex = static_cast(y) * static_cast(sourcePitch) + static_cast(rect.x) * CEF_PIXEL_STRIDE; + const auto destIndex = static_cast(y) * static_cast(destPitch) + static_cast(rect.x) * CEF_PIXEL_STRIDE; - memcpy(&destData[destIndex], &sourceData[sourceIndex], rect.width * CEF_PIXEL_STRIDE); + std::memcpy(&destData[destIndex], &sourceData[sourceIndex], static_cast(rect.width) * CEF_PIXEL_STRIDE); } } } } // Update popup area (override certain areas of the view texture) - const bool popupSizeMismatches = m_RenderData.popupRect.x + m_RenderData.popupRect.width >= (int)m_pWebBrowserRenderItem->m_uiSizeX || - m_RenderData.popupRect.y + m_RenderData.popupRect.height >= (int)m_pWebBrowserRenderItem->m_uiSizeY; - - if (m_RenderData.popupShown && !popupSizeMismatches) + // Validate popup rect bounds to prevent integer overflow and out-of-bounds access + const auto& popupRect = m_RenderData.popupRect; + const auto renderWidth = static_cast(m_pWebBrowserRenderItem->m_uiSizeX); + const auto renderHeight = static_cast(m_pWebBrowserRenderItem->m_uiSizeY); + const auto popupSizeMismatches = popupRect.x < 0 || popupRect.y < 0 || popupRect.width <= 0 || popupRect.height <= 0 || + popupRect.x >= renderWidth || popupRect.y >= renderHeight || popupRect.width > renderWidth || + popupRect.height > renderHeight || popupRect.x > renderWidth - popupRect.width || + popupRect.y > renderHeight - popupRect.height; + + // Verify popup buffer exists before accessing it + if (m_RenderData.popupShown && !popupSizeMismatches && m_RenderData.popupBuffer) [[likely]] { - const auto popupPitch = m_RenderData.popupRect.width * CEF_PIXEL_STRIDE; - for (int y = 0; y < m_RenderData.popupRect.height; ++y) + // Validate popup pitch calculation won't overflow + constexpr auto maxWidthForPopupPitch = INT_MAX / CEF_PIXEL_STRIDE; + if (popupRect.width > maxWidthForPopupPitch) [[unlikely]] { - const int sourceIndex = y * popupPitch; - const int destIndex = (y + m_RenderData.popupRect.y) * destPitch + m_RenderData.popupRect.x * CEF_PIXEL_STRIDE; + pSurface->UnlockRect(); + m_RenderData.popupShown = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + return; + } + const auto popupPitch = popupRect.width * CEF_PIXEL_STRIDE; - memcpy(&destData[destIndex], &m_RenderData.popupBuffer[sourceIndex], popupPitch); + // Ensure we don't write past the destination pitch + if (static_cast(destPitch) < static_cast(popupRect.x + popupRect.width) * CEF_PIXEL_STRIDE) [[unlikely]] + { + pSurface->UnlockRect(); + m_RenderData.popupShown = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + return; + } + + for (int y = 0; y < popupRect.height; ++y) + { + // Use size_t for all calculations to prevent integer overflow + const auto sourceIndex = static_cast(y) * static_cast(popupPitch); + // Calculate destination y coordinate safely + const auto destY = static_cast(popupRect.y) + static_cast(y); + const auto destIndex = destY * static_cast(destPitch) + static_cast(popupRect.x) * CEF_PIXEL_STRIDE; + + std::memcpy(&destData[destIndex], &m_RenderData.popupBuffer[sourceIndex], static_cast(popupPitch)); } } // Unlock surface pSurface->UnlockRect(); } + else + { + OutputDebugLine("[CWebView] UpdateTexture: LockRect failed"); + // Clear flags to prevent re-attempting to render stale buffer + m_RenderData.changed = false; + m_RenderData.popupShown = false; + } + + // Clear buffer pointer - it's only valid during OnPaint callback and we've used it + m_RenderData.buffer = nullptr; + + // Clear dirty rects and release capacity to prevent memory accumulation + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); } m_RenderData.cefThreadState = ECefThreadState::Running; @@ -405,13 +732,20 @@ bool CWebView::SetAudioVolume(float fVolume) "tags = document.getElementsByTagName('video'); for (var i = 0; i frameNames; m_pWebView->GetFrameNames(frameNames); for (auto& name : frameNames) { +#ifdef MTA_MAETRO + auto frame = m_pWebView->GetFrame(name); +#else auto frame = m_pWebView->GetFrameByName(name); - frame->ExecuteJavaScript(strJSCode, "", 0); +#endif + if (frame) + frame->ExecuteJavaScript(strJSCode, "", 0); } m_fVolume = fVolume; return true; @@ -425,7 +759,7 @@ void CWebView::GetSourceCode(const std::function& class MyStringVisitor : public CefStringVisitor { private: - CWebView* webView; + CefRefPtr webView; std::function callback; public: @@ -433,11 +767,15 @@ void CWebView::GetSourceCode(const std::function& virtual void Visit(const CefString& code) override { + // Check if webview is being destroyed to prevent UAF + if (webView->IsBeingDestroyed()) + return; + // Limit to 2MiB for now to prevent freezes (TODO: Optimize that and increase later) if (code.size() <= 2097152) { // Call callback on main thread - g_pCore->GetWebCore()->AddEventToEventQueue(std::bind(callback, code), webView, "GetSourceCode_Visit"); + g_pCore->GetWebCore()->AddEventToEventQueue(std::bind(callback, code), webView.get(), "GetSourceCode_Visit"); } } @@ -450,6 +788,10 @@ void CWebView::GetSourceCode(const std::function& void CWebView::Resize(const CVector2D& size) { + // Validate render item exists + if (!m_pWebBrowserRenderItem) [[unlikely]] + return; + // Resize underlying texture m_pWebBrowserRenderItem->Resize(size); @@ -462,6 +804,9 @@ void CWebView::Resize(const CVector2D& size) CVector2D CWebView::GetSize() { + if (!m_pWebBrowserRenderItem) [[unlikely]] + return CVector2D(0.0f, 0.0f); + return CVector2D(static_cast(m_pWebBrowserRenderItem->m_uiSizeX), static_cast(m_pWebBrowserRenderItem->m_uiSizeY)); } @@ -470,11 +815,16 @@ bool CWebView::GetFullPathFromLocal(SString& strPath) bool result = false; g_pCore->GetWebCore()->WaitForTask( - [&](bool aborted) { + [&](bool aborted) + { if (aborted) return; - result = m_pEventsInterface->Events_OnResourcePathCheck(strPath); + auto* events = m_pEventsInterface; + if (!events) + return; + + result = events->Events_OnResourcePathCheck(strPath); }, this); @@ -483,8 +833,8 @@ bool CWebView::GetFullPathFromLocal(SString& strPath) bool CWebView::RegisterAjaxHandler(const SString& strURL) { - auto result = m_AjaxHandlers.insert(strURL); - return result.second; + auto [iter, inserted] = m_AjaxHandlers.insert(strURL); + return inserted; } bool CWebView::UnregisterAjaxHandler(const SString& strURL) @@ -500,8 +850,12 @@ bool CWebView::HasAjaxHandler(const SString& strURL) void CWebView::HandleAjaxRequest(const SString& strURL, CAjaxResourceHandler* pHandler) { - auto func = std::bind(&CWebBrowserEventsInterface::Events_OnAjaxRequest, m_pEventsInterface, pHandler, strURL); - g_pCore->GetWebCore()->AddEventToEventQueue(func, this, "AjaxResourceRequest"); + // Only queue event if not being destroyed to prevent UAF + if (!m_bBeingDestroyed) + { + QueueBrowserEvent("AjaxResourceRequest", + [handler = pHandler, url = strURL](CWebBrowserEventsInterface* iface) { iface->Events_OnAjaxRequest(handler, url); }); + } } bool CWebView::ToggleDevTools(bool visible) @@ -517,11 +871,16 @@ bool CWebView::VerifyFile(const SString& strPath, CBuffer& outFileData) bool result = false; g_pCore->GetWebCore()->WaitForTask( - [&](bool aborted) { + [&](bool aborted) + { if (aborted) return; - result = m_pEventsInterface->Events_OnResourceFileCheck(strPath, outFileData); + auto* events = m_pEventsInterface; + if (!events) + return; + + result = events->Events_OnResourceFileCheck(strPath, outFileData); }, this); @@ -593,41 +952,15 @@ void CWebView::Refresh(bool bIgnoreCache) bool CWebView::OnProcessMessageReceived(CefRefPtr browser, CefRefPtr frame, CefProcessId source_process, CefRefPtr message) { + if (m_bBeingDestroyed) + return false; + CefRefPtr argList = message->GetArgumentList(); if (message->GetName() == "TriggerLuaEvent") - { - if (!m_bIsLocal) - return true; - - // Get event name - CefString eventName = argList->GetString(0); + return WebViewAuth::HandleTriggerLuaEvent(this, argList, m_bIsLocal); // AUTH - // Get number of arguments from IPC process message - int numArgs = argList->GetInt(1); - - // Get args - std::vector args; - for (int i = 2; i < numArgs + 2; ++i) - { - args.push_back(argList->GetString(i)); - } - - // Queue event to run on the main thread - auto func = std::bind(&CWebBrowserEventsInterface::Events_OnTriggerEvent, m_pEventsInterface, SString(eventName), args); - g_pCore->GetWebCore()->AddEventToEventQueue(func, this, "OnProcessMessageReceived1"); - - // The message was handled - return true; - } if (message->GetName() == "InputFocus") - { - // Retrieve arguments from process message - m_bHasInputFocus = argList->GetBool(0); - - // Queue event to run on the main thread - auto func = std::bind(&CWebBrowserEventsInterface::Events_OnInputFocusChanged, m_pEventsInterface, m_bHasInputFocus); - g_pCore->GetWebCore()->AddEventToEventQueue(func, this, "OnProcessMessageReceived2"); - } + return WebViewAuth::HandleInputFocus(this, argList, m_bIsLocal); // AUTH // The message wasn't handled return false; @@ -644,7 +977,7 @@ void CWebView::GetViewRect(CefRefPtr browser, CefRect& rect) rect.x = 0; rect.y = 0; - if (m_bBeingDestroyed) + if (m_bBeingDestroyed || !m_pWebBrowserRenderItem) [[unlikely]] { rect.width = 1; rect.height = 1; @@ -681,11 +1014,19 @@ void CWebView::OnPopupSize(CefRefPtr browser, const CefRect& rect) { std::lock_guard lock{m_RenderData.dataMutex}; + // If dimensions change, the current popup buffer is no longer valid for the new size + // We must release it to prevent UpdateTexture from reading past the end of the buffer + // using the new (larger) dimensions + if (m_RenderData.popupRect.width != rect.width || m_RenderData.popupRect.height != rect.height) + { + m_RenderData.popupBuffer.reset(); + } + // Update rect m_RenderData.popupRect = rect; - // Resize buffer - m_RenderData.popupBuffer.reset(new byte[rect.width * rect.height * CEF_PIXEL_STRIDE]); + // Note: Don't allocate buffer here - OnPaint may provide different dimensions + // Buffer allocation moved to OnPaint to prevent dimension mismatch } //////////////////////////////////////////////////////////////////// @@ -698,20 +1039,86 @@ void CWebView::OnPopupSize(CefRefPtr browser, const CefRect& rect) void CWebView::OnPaint(CefRefPtr browser, CefRenderHandler::PaintElementType paintType, const CefRenderHandler::RectList& dirtyRects, const void* buffer, int width, int height) { - if (m_bBeingDestroyed) + if (m_bBeingDestroyed) [[unlikely]] return; - std::unique_lock lock(m_RenderData.dataMutex); + std::unique_lock lock(m_RenderData.dataMutex); // Copy popup buffer if (paintType == PET_POPUP) { - if (m_RenderData.popupBuffer) + // Validate buffer parameter from CEF + if (!buffer || width <= 0 || height <= 0) [[unlikely]] + return; + + // Allocate buffer based on actual paint dimensions, not OnPopupSize rect + // This prevents buffer overflow when CEF provides different dimensions + // Check for integer overflow in size calculation: width * height * CEF_PIXEL_STRIDE must fit in size_t + constexpr auto maxDimension = INT_MAX / CEF_PIXEL_STRIDE; + if (width > maxDimension || height > maxDimension) [[unlikely]] + return; // Individual dimension too large + if (static_cast(width) > SIZE_MAX / (static_cast(height) * CEF_PIXEL_STRIDE)) [[unlikely]] + return; // width * height * stride would overflow + + const auto requiredSize = static_cast(width) * static_cast(height) * CEF_PIXEL_STRIDE; + + // Calculate current size safely to avoid overflow + size_t currentSize = 0; + const auto& popupRect = m_RenderData.popupRect; + if (popupRect.width > 0 && popupRect.height > 0 && popupRect.width <= maxDimension && popupRect.height <= maxDimension && + static_cast(popupRect.width) <= SIZE_MAX / (static_cast(popupRect.height) * CEF_PIXEL_STRIDE)) [[likely]] + { + currentSize = static_cast(popupRect.width) * static_cast(popupRect.height) * CEF_PIXEL_STRIDE; + } + + // Reallocate if size changed or buffer doesn't exist + if (!m_RenderData.popupBuffer || requiredSize != currentSize) [[unlikely]] { - memcpy(m_RenderData.popupBuffer.get(), buffer, width * height * CEF_PIXEL_STRIDE); + m_RenderData.popupBuffer = std::make_unique(requiredSize); + // Update rect to reflect actual dimensions + m_RenderData.popupRect.width = width; + m_RenderData.popupRect.height = height; } - return; // We don't have to wait as we've copied the buffer already + std::memcpy(m_RenderData.popupBuffer.get(), buffer, requiredSize); + + // Popup path doesn't wait, so no need to signal + return; + } + + // Validate main frame buffer parameter + if (!buffer || width <= 0 || height <= 0) [[unlikely]] + { + m_RenderData.changed = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + return; + } + + // Check for integer overflow in size calculation + constexpr auto maxDimension = INT_MAX / CEF_PIXEL_STRIDE; + if (width > maxDimension || height > maxDimension) [[unlikely]] + { + m_RenderData.changed = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + return; + } + if (static_cast(width) > SIZE_MAX / (static_cast(height) * CEF_PIXEL_STRIDE)) [[unlikely]] + { + m_RenderData.changed = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + m_RenderData.cefThreadCv.notify_all(); + return; } // Store render data @@ -719,11 +1126,22 @@ void CWebView::OnPaint(CefRefPtr browser, CefRenderHandler::PaintEle m_RenderData.width = width; m_RenderData.height = height; m_RenderData.dirtyRects = dirtyRects; + // Prevent vector capacity growth memory leak - shrink excess capacity + m_RenderData.dirtyRects.shrink_to_fit(); m_RenderData.changed = true; // Wait for the main thread to handle drawing the texture m_RenderData.cefThreadState = ECefThreadState::Wait; - m_RenderData.cefThreadCv.wait(lock, [&]() { return m_RenderData.cefThreadState == ECefThreadState::Running; }); + if (!m_RenderData.cefThreadCv.wait_for(lock, std::chrono::milliseconds(250), [&]() { return m_RenderData.cefThreadState == ECefThreadState::Running; })) + { + // Timed out - rendering is likely stalled or stopped + // Clear data to prevent UpdateTexture from using stale buffer and allow CEF to free it + m_RenderData.changed = false; + m_RenderData.buffer = nullptr; + m_RenderData.dirtyRects.clear(); + m_RenderData.dirtyRects.shrink_to_fit(); + m_RenderData.cefThreadState = ECefThreadState::Running; + } } //////////////////////////////////////////////////////////////////// @@ -734,13 +1152,14 @@ void CWebView::OnPaint(CefRefPtr browser, CefRenderHandler::PaintEle //////////////////////////////////////////////////////////////////// void CWebView::OnLoadStart(CefRefPtr browser, CefRefPtr frame, TransitionType transitionType) { + // Note: TransitionType parameter is deprecated in CEF3 but still required by virtual interface override SString strURL = UTF16ToMbUTF8(frame->GetURL()); if (strURL == "blank") return; // Queue event to run on the main thread - auto func = std::bind(&CWebBrowserEventsInterface::Events_OnLoadingStart, m_pEventsInterface, strURL, frame->IsMain()); - g_pCore->GetWebCore()->AddEventToEventQueue(func, this, "OnLoadStart"); + QueueBrowserEvent("OnLoadStart", + [url = strURL, isMain = frame->IsMain()](CWebBrowserEventsInterface* iface) { iface->Events_OnLoadingStart(url, isMain); }); } //////////////////////////////////////////////////////////////////// @@ -759,8 +1178,7 @@ void CWebView::OnLoadEnd(CefRefPtr browser, CefRefPtr fram SString strURL = UTF16ToMbUTF8(frame->GetURL()); // Queue event to run on the main thread - auto func = std::bind(&CWebBrowserEventsInterface::Events_OnDocumentReady, m_pEventsInterface, strURL); - g_pCore->GetWebCore()->AddEventToEventQueue(func, this, "OnLoadEnd"); + QueueBrowserEvent("OnLoadEnd", [url = strURL](CWebBrowserEventsInterface* iface) { iface->Events_OnDocumentReady(url); }); } } @@ -777,8 +1195,8 @@ void CWebView::OnLoadError(CefRefPtr browser, CefRefPtr fr SString strURL = UTF16ToMbUTF8(frame->GetURL()); // Queue event to run on the main thread - auto func = std::bind(&CWebBrowserEventsInterface::Events_OnLoadingFailed, m_pEventsInterface, strURL, errorCode, SString(errorText)); - g_pCore->GetWebCore()->AddEventToEventQueue(func, this, "OnLoadError"); + QueueBrowserEvent("OnLoadError", [url = strURL, errorCode, errorDescription = SString(errorText)](CWebBrowserEventsInterface* iface) mutable + { iface->Events_OnLoadingFailed(url, errorCode, errorDescription); }); } //////////////////////////////////////////////////////////////////// @@ -800,7 +1218,7 @@ bool CWebView::OnBeforeBrowse(CefRefPtr browser, CefRefPtr CefURLParts urlParts; if (!CefParseURL(request->GetURL(), urlParts)) - return true; // Cancel if invalid URL (this line will normally not be executed) + return true; // Cancel if invalid URL (this line will normally not be executed) bool bResult; WString scheme = urlParts.scheme.str; @@ -810,22 +1228,22 @@ bool CWebView::OnBeforeBrowse(CefRefPtr browser, CefRefPtr if (host != "mta") { if (IsLocal() || g_pCore->GetWebCore()->GetDomainState(host, true) != eURLState::WEBPAGE_ALLOWED) - bResult = true; // Block remote here + bResult = true; // Block remote here else - bResult = false; // Allow + bResult = false; // Allow } else bResult = false; } else - bResult = true; // Block other schemes + bResult = true; // Block other schemes // Check if we're in the browser's main frame or only a frame element of the current page bool bIsMainFrame = frame->IsMain(); // Queue event to run on the main thread - auto func = std::bind(&CWebBrowserEventsInterface::Events_OnNavigate, m_pEventsInterface, SString(request->GetURL()), bResult, bIsMainFrame); - g_pCore->GetWebCore()->AddEventToEventQueue(func, this, "OnNavigate"); + QueueBrowserEvent("OnNavigate", [url = SString(request->GetURL()), blocked = bResult, isMain = bIsMainFrame](CWebBrowserEventsInterface* iface) mutable + { iface->Events_OnNavigate(url, blocked, isMain); }); // Return execution to CEF return bResult; @@ -844,7 +1262,7 @@ CefResourceRequestHandler::ReturnValue CWebView::OnBeforeResourceLoad(CefRefPtr< // Mostly the same as CWebView::OnBeforeBrowse CefURLParts urlParts; if (!CefParseURL(request->GetURL(), urlParts)) - return RV_CANCEL; // Cancel if invalid URL (this line will normally not be executed) + return RV_CANCEL; // Cancel if invalid URL (this line will normally not be executed) SString domain = UTF16ToMbUTF8(urlParts.host.str); @@ -870,6 +1288,10 @@ CefResourceRequestHandler::ReturnValue CWebView::OnBeforeResourceLoad(CefRefPtr< request->SetHeaderMap(headerMap); } + + // Fix youtube embed (#4531) + if (domain == "www.youtube.com" && UTF16ToMbUTF8(urlParts.path.str).find("/embed") == 0) + request->SetReferrer("https://mtasa.com/", REFERRER_POLICY_ORIGIN); } WString scheme = urlParts.scheme.str; @@ -878,17 +1300,18 @@ CefResourceRequestHandler::ReturnValue CWebView::OnBeforeResourceLoad(CefRefPtr< if (domain != "mta") { if (IsLocal()) - return RV_CANCEL; // Block remote requests in local mode generally + return RV_CANCEL; // Block remote requests in local mode generally eURLState urlState = g_pCore->GetWebCore()->GetDomainState(domain, true); if (urlState != eURLState::WEBPAGE_ALLOWED) { // Trigger onClientBrowserResourceBlocked event - auto func = std::bind(&CWebBrowserEventsInterface::Events_OnResourceBlocked, m_pEventsInterface, SString(request->GetURL()), domain, - urlState == eURLState::WEBPAGE_NOT_LISTED ? 0 : 1); - g_pCore->GetWebCore()->AddEventToEventQueue(func, this, "OnResourceBlocked"); + QueueBrowserEvent( + "OnResourceBlocked", + [url = SString(request->GetURL()), domain, reason = static_cast(urlState == eURLState::WEBPAGE_NOT_LISTED ? 0 : 1)]( + CWebBrowserEventsInterface* iface) mutable { iface->Events_OnResourceBlocked(url, domain, reason); }); - return RV_CANCEL; // Block if explicitly forbidden + return RV_CANCEL; // Block if explicitly forbidden } // Allow @@ -903,9 +1326,8 @@ CefResourceRequestHandler::ReturnValue CWebView::OnBeforeResourceLoad(CefRefPtr< } // Trigger onClientBrowserResourceBlocked event - auto func = std::bind(&CWebBrowserEventsInterface::Events_OnResourceBlocked, m_pEventsInterface, SString(request->GetURL()), "", - 2); // reason 1 := blocked protocol scheme - g_pCore->GetWebCore()->AddEventToEventQueue(func, this, "OnResourceBlocked"); + QueueBrowserEvent("OnResourceBlocked", + [url = SString(request->GetURL())](CWebBrowserEventsInterface* iface) mutable { iface->Events_OnResourceBlocked(url, "", 2); }); // Block everything else return RV_CANCEL; @@ -920,13 +1342,16 @@ CefResourceRequestHandler::ReturnValue CWebView::OnBeforeResourceLoad(CefRefPtr< void CWebView::OnBeforeClose(CefRefPtr browser) { // Remove events owned by this webview and invoke left callbacks - g_pCore->GetWebCore()->RemoveWebViewEvents(this); + if (auto pWebCore = g_pCore->GetWebCore(); pWebCore) [[likely]] + { + pWebCore->RemoveWebViewEvents(this); - m_pWebView = nullptr; + // Remove focused web view reference + if (pWebCore->GetFocusedWebView() == this) + pWebCore->SetFocusedWebView(nullptr); + } - // Remove focused web view reference - if (g_pCore->GetWebCore()->GetFocusedWebView() == this) - g_pCore->GetWebCore()->SetFocusedWebView(nullptr); + m_pWebView = nullptr; } //////////////////////////////////////////////////////////////////// @@ -936,10 +1361,17 @@ void CWebView::OnBeforeClose(CefRefPtr browser) // // // // //////////////////////////////////////////////////////////////////// +#ifdef MTA_MAETRO +bool CWebView::OnBeforePopup(CefRefPtr browser, CefRefPtr frame, const CefString& target_url, const CefString& target_frame_name, + CefLifeSpanHandler::WindowOpenDisposition target_disposition, bool user_gesture, const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, CefRefPtr& client, CefBrowserSettings& settings, CefRefPtr& extra_info, + bool* no_javascript_access) +#else bool CWebView::OnBeforePopup(CefRefPtr browser, CefRefPtr frame, int popup_id, const CefString& target_url, const CefString& target_frame_name, CefLifeSpanHandler::WindowOpenDisposition target_disposition, bool user_gesture, const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, CefRefPtr& client, CefBrowserSettings& settings, CefRefPtr& extra_info, bool* no_javascript_access) +#endif { // ATTENTION: This method is called on the IO thread @@ -948,8 +1380,8 @@ bool CWebView::OnBeforePopup(CefRefPtr browser, CefRefPtr SString strOpenerURL = UTF16ToMbUTF8(frame->GetURL()); // Queue event to run on the main thread - auto func = std::bind(&CWebBrowserEventsInterface::Events_OnPopup, m_pEventsInterface, strTagetURL, strOpenerURL); - g_pCore->GetWebCore()->AddEventToEventQueue(func, this, "OnBeforePopup"); + QueueBrowserEvent("OnBeforePopup", + [target = strTagetURL, opener = strOpenerURL](CWebBrowserEventsInterface* iface) { iface->Events_OnPopup(target, opener); }); // Block popups generally return true; @@ -963,12 +1395,17 @@ bool CWebView::OnBeforePopup(CefRefPtr browser, CefRefPtr //////////////////////////////////////////////////////////////////// void CWebView::OnAfterCreated(CefRefPtr browser) { + if (m_bBeingDestroyed) + { + browser->GetHost()->CloseBrowser(true); + return; + } + // Set web view reference m_pWebView = browser; // Call created event callback - auto func = std::bind(&CWebBrowserEventsInterface::Events_OnCreated, m_pEventsInterface); - g_pCore->GetWebCore()->AddEventToEventQueue(func, this, "OnAfterCreated"); + QueueBrowserEvent("OnAfterCreated", [](CWebBrowserEventsInterface* iface) { iface->Events_OnCreated(); }); } //////////////////////////////////////////////////////////////////// @@ -996,9 +1433,14 @@ bool CWebView::OnJSDialog(CefRefPtr browser, const CefString& origin // // // // //////////////////////////////////////////////////////////////////// +#ifdef MTA_MAETRO +bool CWebView::OnFileDialog(CefRefPtr browser, CefDialogHandler::FileDialogMode mode, const CefString& title, const CefString& default_file_path, + const std::vector& accept_filters, CefRefPtr callback) +#else bool CWebView::OnFileDialog(CefRefPtr browser, FileDialogMode mode, const CefString& title, const CefString& default_file_path, - const std::vector& accept_filters, const std::vector& accept_extensions, const std::vector& accept_descriptions, - CefRefPtr callback) + const std::vector& accept_filters, const std::vector& accept_extensions, + const std::vector& accept_descriptions, CefRefPtr callback) +#endif { // Don't show the dialog return true; @@ -1024,8 +1466,7 @@ void CWebView::OnTitleChange(CefRefPtr browser, const CefString& tit bool CWebView::OnTooltip(CefRefPtr browser, CefString& title) { // Queue event to run on the main thread - auto func = std::bind(&CWebBrowserEventsInterface::Events_OnTooltip, m_pEventsInterface, UTF16ToMbUTF8(title)); - g_pCore->GetWebCore()->AddEventToEventQueue(func, this, "OnTooltip"); + QueueBrowserEvent("OnTooltip", [tooltip = UTF16ToMbUTF8(title)](CWebBrowserEventsInterface* iface) mutable { iface->Events_OnTooltip(tooltip); }); return true; } @@ -1039,14 +1480,14 @@ bool CWebView::OnTooltip(CefRefPtr browser, CefString& title) //////////////////////////////////////////////////////////////////// bool CWebView::OnConsoleMessage(CefRefPtr browser, cef_log_severity_t level, const CefString& message, const CefString& source, int line) { + // Note: cef_log_severity_t parameter is deprecated in CEF3 but required for virtual override // Redirect console message to debug window (if development mode is enabled) if (g_pCore->GetWebCore()->IsTestModeEnabled()) { g_pCore->GetWebCore()->AddEventToEventQueue( - [message, source]() { - g_pCore->DebugPrintfColor("[BROWSER] Console: %s (%s)", 255, 0, 0, UTF16ToMbUTF8(message).c_str(), UTF16ToMbUTF8(source).c_str()); - }, - this, "OnConsoleMessage"); + [message, source]() + { g_pCore->DebugPrintfColor("[BROWSER] Console: %s (%s)", 255, 0, 0, UTF16ToMbUTF8(message).c_str(), UTF16ToMbUTF8(source).c_str()); }, this, + "OnConsoleMessage"); } return true; @@ -1064,8 +1505,7 @@ bool CWebView::OnCursorChange(CefRefPtr browser, CefCursorHandle cur unsigned char cursorIndex = static_cast(type); // Queue event to run on the main thread - auto func = std::bind(&CWebBrowserEventsInterface::Events_OnChangeCursor, m_pEventsInterface, cursorIndex); - g_pCore->GetWebCore()->AddEventToEventQueue(func, this, "OnCursorChange"); + QueueBrowserEvent("OnCursorChange", [cursorIndex](CWebBrowserEventsInterface* iface) { iface->Events_OnChangeCursor(cursorIndex); }); return false; } diff --git a/Client/cefweb/CWebView.h b/Client/cefweb/CWebView.h index 59cd64f381b..45020abb884 100644 --- a/Client/cefweb/CWebView.h +++ b/Client/cefweb/CWebView.h @@ -21,19 +21,32 @@ #include #include #include +#include #include -#include #include #include -#define GetNextSibling(hwnd) GetWindow(hwnd, GW_HWNDNEXT) // Re-define the conflicting macro -#define GetFirstChild(hwnd) GetTopWindow(hwnd) +#include +#include +#include +#include +#include +#define GetNextSibling(hwnd) GetWindow(hwnd, GW_HWNDNEXT) // Re-define the conflicting macro +#define GetFirstChild(hwnd) GetTopWindow(hwnd) #define MTA_CEF_USERAGENT "Multi Theft Auto: San Andreas Client " MTA_DM_BUILDTAG_LONG +// Forward declaration for WebViewAuth namespace functions (defined in CWebViewAuth.h) +class CWebView; +namespace WebViewAuth +{ + bool HandleTriggerLuaEvent(CWebView*, CefRefPtr, const bool); + bool HandleInputFocus(CWebView*, CefRefPtr, const bool); +} + enum class ECefThreadState { - Running = 0, // CEF thread is currently running - Wait // CEF thread is waiting for the main thread + Running = 0, // CEF thread is currently running + Wait // CEF thread is waiting for the main thread }; class CWebView : public CWebViewInterface, @@ -48,11 +61,15 @@ class CWebView : public CWebViewInterface, private CefDisplayHandler, private CefContextMenuHandler { + friend bool WebViewAuth::HandleTriggerLuaEvent(CWebView*, CefRefPtr, const bool); + friend bool WebViewAuth::HandleInputFocus(CWebView*, CefRefPtr, const bool); + public: CWebView(bool bIsLocal, CWebBrowserItem* pWebBrowserRenderItem, bool bTransparent = false); virtual ~CWebView(); void Initialise(); - void SetWebBrowserEvents(CWebBrowserEventsInterface* pInterface) { m_pEventsInterface = pInterface; }; + void SetWebBrowserEvents(CWebBrowserEventsInterface* pInterface); + void ClearWebBrowserEvents(CWebBrowserEventsInterface* pInterface); void CloseBrowser(); CefRefPtr GetCefBrowser() { return m_pWebView; }; @@ -72,7 +89,9 @@ class CWebView : public CWebViewInterface, void UpdateTexture(); - bool HasInputFocus() { return m_bHasInputFocus; } + bool HasInputFocus() { return m_bHasInputFocus; } + void SetInputFocus(bool bFocus) { m_bHasInputFocus = bFocus; } // Setter for IPC handlers + CWebBrowserEventsInterface* GetEventsInterface() { return m_pEventsInterface; } // Getter for IPC handlers void ExecuteJavascript(const SString& strJavascriptCode); @@ -109,17 +128,17 @@ class CWebView : public CWebViewInterface, bool CanGoForward(); bool GoBack(); bool GoForward(); - void Refresh(bool ignoreCache); + void Refresh(bool bIgnoreCache); // CefClient methods - virtual CefRefPtr GetRenderHandler() override { return this; }; - virtual CefRefPtr GetLoadHandler() override { return this; }; - virtual CefRefPtr GetRequestHandler() override { return this; }; - virtual CefRefPtr GetLifeSpanHandler() override { return this; }; - virtual CefRefPtr GetJSDialogHandler() override { return this; }; - virtual CefRefPtr GetDialogHandler() override { return this; }; - virtual CefRefPtr GetDisplayHandler() override { return this; }; - virtual CefRefPtr GetContextMenuHandler() override { return this; }; + virtual CefRefPtr GetRenderHandler() override { return this; } + virtual CefRefPtr GetLoadHandler() override { return this; } + virtual CefRefPtr GetRequestHandler() override { return this; } + virtual CefRefPtr GetLifeSpanHandler() override { return this; } + virtual CefRefPtr GetJSDialogHandler() override { return this; } + virtual CefRefPtr GetDialogHandler() override { return this; } + virtual CefRefPtr GetDisplayHandler() override { return this; } + virtual CefRefPtr GetContextMenuHandler() override { return this; } virtual bool OnProcessMessageReceived(CefRefPtr browser, CefRefPtr frame, CefProcessId source_process, CefRefPtr message) override; @@ -152,10 +171,17 @@ class CWebView : public CWebViewInterface, // CefLifeSpawnHandler methods virtual void OnBeforeClose(CefRefPtr browser) override; +#ifdef MTA_MAETRO + virtual bool OnBeforePopup(CefRefPtr browser, CefRefPtr frame, const CefString& target_url, const CefString& target_frame_name, + CefLifeSpanHandler::WindowOpenDisposition target_disposition, bool user_gesture, const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, CefRefPtr& client, CefBrowserSettings& settings, CefRefPtr& extra_info, + bool* no_javascript_access) override; +#else virtual bool OnBeforePopup(CefRefPtr browser, CefRefPtr frame, int popup_id, const CefString& target_url, const CefString& target_frame_name, CefLifeSpanHandler::WindowOpenDisposition target_disposition, bool user_gesture, const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, CefRefPtr& client, CefBrowserSettings& settings, CefRefPtr& extra_info, bool* no_javascript_access) override; +#endif virtual void OnAfterCreated(CefRefPtr browser) override; // CefJSDialogHandler methods @@ -164,9 +190,14 @@ class CWebView : public CWebViewInterface, bool& suppress_message) override; // CefDialogHandler methods +#ifdef MTA_MAETRO + virtual bool OnFileDialog(CefRefPtr browser, CefDialogHandler::FileDialogMode mode, const CefString& title, const CefString& default_file_path, + const std::vector& accept_filters, CefRefPtr callback) override; +#else virtual bool OnFileDialog(CefRefPtr browser, FileDialogMode mode, const CefString& title, const CefString& default_file_path, - const std::vector& accept_filters, const std::vector& accept_extensions, const std::vector& accept_descriptions, - CefRefPtr callback) override; + const std::vector& accept_filters, const std::vector& accept_extensions, + const std::vector& accept_descriptions, CefRefPtr callback) override; +#endif // CefDisplayHandler methods virtual void OnTitleChange(CefRefPtr browser, const CefString& title) override; @@ -181,21 +212,76 @@ class CWebView : public CWebViewInterface, private: void ResumeCefThread(); + void QueueBrowserEvent(const char* name, std::function&& fn); + + struct FEventTarget + { + struct DispatchToken + { + uint64_t generation = 0; + }; + + DispatchToken CreateDispatchToken() const + { + std::lock_guard lock(mutex); + return DispatchToken{generation}; + } + + void Assign(CWebBrowserEventsInterface* ptr) + { + std::lock_guard lock(mutex); + if (target == ptr) + return; + + target = ptr; + ++generation; + } + + void Clear(CWebBrowserEventsInterface* expected) + { + std::lock_guard lock(mutex); + if (target != expected) + return; + + target = nullptr; + ++generation; + } + + template + void Dispatch(const DispatchToken& token, Fn&& fn) + { + CWebBrowserEventsInterface* current = nullptr; + { + std::lock_guard lock(mutex); + if (generation != token.generation || !target) + return; + current = target; + } + + fn(current); + } + + private: + mutable std::mutex mutex; + CWebBrowserEventsInterface* target = nullptr; + uint64_t generation = 0; + }; CefRefPtr m_pWebView; CWebBrowserItem* m_pWebBrowserRenderItem; - std::atomic_bool m_bBeingDestroyed; - bool m_bIsLocal; - bool m_bIsRenderingPaused; - bool m_bIsTransparent; - POINT m_vecMousePosition; - bool m_mouseButtonStates[3]; - SString m_CurrentTitle; - float m_fVolume; - std::map m_Properties; - bool m_bHasInputFocus; - std::set m_AjaxHandlers; + std::atomic_bool m_bBeingDestroyed; + bool m_bIsLocal; + bool m_bIsRenderingPaused; + bool m_bIsTransparent; + POINT m_vecMousePosition; + bool m_mouseButtonStates[3]; + SString m_CurrentTitle; + float m_fVolume; + std::map m_Properties; + bool m_bHasInputFocus; + std::set m_AjaxHandlers; + std::shared_ptr m_pEventTarget; struct { diff --git a/Client/cefweb/CWebViewAuth.h b/Client/cefweb/CWebViewAuth.h new file mode 100644 index 00000000000..4ca9f138033 --- /dev/null +++ b/Client/cefweb/CWebViewAuth.h @@ -0,0 +1,148 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: cefweb/CWebViewAuth.h + * PURPOSE: IPC authentication helpers for browser message validation + * + *****************************************************************************/ +#pragma once + +#include "CWebView.h" +#include "CWebCore.h" +#include +#include // For std::min +#include // For INT_MAX +#include // For std::bind +#include +#include + +// Note: These inline functions access private members of CWebView (m_bHasInputFocus, m_pEventsInterface). +// This is valid because this header is #included in CWebView.cpp, making these functions part of that +// translation unit where they have access to CWebView's private members (similar to friend functions). +namespace WebViewAuth +{ + // Validates IPC auth code for TriggerLuaEvent messages + [[nodiscard]] inline bool ValidateTriggerEventAuthCode(CefRefPtr argList) + { + if (!argList) [[unlikely]] + return false; + + const auto argCount = argList->GetSize(); + if (argCount < 3) [[unlikely]] // Need at least: eventName, numArgs, authCode + return false; + + // SECURITY: Type validation BEFORE expensive auth operations (DoS prevention) + // Reject malformed messages early without crypto comparison overhead + if (argList->GetType(0) != VTYPE_STRING) [[unlikely]] // eventName must be STRING + return false; + if (argList->GetType(1) != VTYPE_INT) [[unlikely]] // numArgs must be INT + return false; + + const auto authCodeIndex = static_cast(argCount - 1); + if (argList->GetType(authCodeIndex) != VTYPE_STRING) [[unlikely]] + return false; + + // Must read from webCore->m_AuthCode (browser process storage) + // Cannot use WebAppAuth::GetSharedAuthCode() - that's render process memory! + if (!g_pCore || !IsReadablePointer(g_pCore, sizeof(void*))) [[unlikely]] + return false; + + const auto* const webCore = static_cast(g_pCore->GetWebCore()); + if (!webCore || !IsReadablePointer(webCore, sizeof(void*))) [[unlikely]] + return false; + + const auto& authCode = webCore->m_AuthCode; + if (authCode.empty()) [[unlikely]] + return false; + + // Compare auth codes (use ToString() which returns std::string) + const std::string receivedCode = argList->GetString(authCodeIndex).ToString(); + if (authCode != receivedCode) [[unlikely]] + return false; + + return true; + } + + // Gets the maximum argument index, excluding the auth code + [[nodiscard]] inline int GetTriggerEventMaxArgIndex(CefRefPtr argList, const int numArgs) noexcept + { + if (!argList) [[unlikely]] + return 0; + + const auto argCount = argList->GetSize(); + const auto authCodeIndex = static_cast(argCount - 1); + + // Overflow protection: ensure numArgs + 2 won't overflow + if (numArgs < 0 || numArgs > INT_MAX - 2) [[unlikely]] + return authCodeIndex; + + return std::min(numArgs + 2, authCodeIndex); + } + + // Handles TriggerLuaEvent message with auth validation + inline bool HandleTriggerLuaEvent(CWebView* pWebView, CefRefPtr argList, const bool isLocal) + { + if (!pWebView || !argList) [[unlikely]] + return true; // Return true = handled (rejected), not false which would bypass + + if (!isLocal) [[unlikely]] + return true; + + if (!ValidateTriggerEventAuthCode(argList)) [[unlikely]] + return true; + + // Type validation already done in ValidateTriggerEventAuthCode + const CefString eventName = argList->GetString(0); + const int numArgs = argList->GetInt(1); + + const auto argCount = argList->GetSize(); + + // Validate numArgs matches actual arguments present in message + // Expected structure: [eventName, numArgs, arg0..argN-1, authCode] + // Therefore: argCount should equal numArgs + 3 (eventName + numArgs + authCode) + if (const auto expectedArgCount = numArgs + 3; expectedArgCount < 3 || expectedArgCount != static_cast(argCount)) [[unlikely]] + return true; // Reject: numArgs mismatch (confusion attack prevention) + + std::vector args; + args.reserve(numArgs > 0 ? static_cast(numArgs) : 0); + + const int maxArgIndex = GetTriggerEventMaxArgIndex(argList, numArgs); + + for (int i = 2; i < maxArgIndex; ++i) + { + // Type check: all arguments must be STRING + if (argList->GetType(i) != VTYPE_STRING) [[unlikely]] + return true; + + args.emplace_back(argList->GetString(i).ToString()); + } + + // Use QueueBrowserEvent for UAF-safe event dispatch (generation token pattern) + pWebView->QueueBrowserEvent("OnProcessMessageReceived1", + [eventNameStr = SString(eventName), args = std::move(args)](CWebBrowserEventsInterface* iface) mutable + { iface->Events_OnTriggerEvent(eventNameStr, args); }); + return true; + } + + // Handles InputFocus message (no auth needed - internal CEF event, not user-triggered) + inline bool HandleInputFocus(CWebView* pWebView, CefRefPtr argList, const bool isLocal) + { + if (!pWebView || !argList) [[unlikely]] + return true; // Return true = handled (rejected), not false which would bypass + + if (!isLocal) [[unlikely]] + return true; + + if (argList->GetSize() < 1 || argList->GetType(0) != VTYPE_BOOL) [[unlikely]] + return true; + + pWebView->SetInputFocus(argList->GetBool(0)); + + // Use QueueBrowserEvent for UAF-safe event dispatch (generation token pattern) + const bool hasFocus = pWebView->HasInputFocus(); + pWebView->QueueBrowserEvent("OnProcessMessageReceived2", + [focus = hasFocus](CWebBrowserEventsInterface* iface) { iface->Events_OnInputFocusChanged(focus); }); + return true; + } +} diff --git a/Client/cefweb/CWebsiteRequests.cpp b/Client/cefweb/CWebsiteRequests.cpp index bc43b8a7869..341d2009a17 100644 --- a/Client/cefweb/CWebsiteRequests.cpp +++ b/Client/cefweb/CWebsiteRequests.cpp @@ -63,13 +63,8 @@ CWebsiteRequests::CWebsiteRequests() CWebsiteRequests::~CWebsiteRequests() { - delete m_pLabel1; - delete m_pLabel2; - delete m_pAddressMemo; - delete m_pCheckRemember; - delete m_pButtonAllow; - delete m_pButtonDeny; - delete m_pWindow; + if (m_pWindow) + g_pCore->GetGUI()->DestroyElementRecursive(m_pWindow); } void CWebsiteRequests::Show() @@ -126,7 +121,11 @@ void CWebsiteRequests::Callback(bool bAllow, const std::unordered_set& bool CWebsiteRequests::OnAllowButtonClick(CGUIElement* pElement) { Hide(); - auto requests = g_pCore->GetWebCore()->AllowPendingPages(m_pCheckRemember->GetSelected()); + std::unordered_set requests; + if (auto pWebCore = g_pCore->GetWebCore(); pWebCore) + { + requests = pWebCore->AllowPendingPages(m_pCheckRemember->GetSelected()); + } Callback(true, requests); return true; @@ -135,7 +134,11 @@ bool CWebsiteRequests::OnAllowButtonClick(CGUIElement* pElement) bool CWebsiteRequests::OnDenyButtonClick(CGUIElement* pElement) { Hide(); - auto requests = g_pCore->GetWebCore()->DenyPendingPages(); + std::unordered_set requests; + if (auto pWebCore = g_pCore->GetWebCore(); pWebCore) + { + requests = pWebCore->DenyPendingPages(); + } Callback(false, requests); return true; diff --git a/Client/cefweb/CWebsiteRequests.h b/Client/cefweb/CWebsiteRequests.h index 5aa08027321..54c9320f6dc 100644 --- a/Client/cefweb/CWebsiteRequests.h +++ b/Client/cefweb/CWebsiteRequests.h @@ -9,7 +9,7 @@ *****************************************************************************/ #pragma once -#define WEBSITEREQUESTS_WINDOW_DEFAULTWIDTH 476 +#define WEBSITEREQUESTS_WINDOW_DEFAULTWIDTH 476 #define WEBSITEREQUESTS_WINDOW_DEFAULTHEIGHT 297 class CGUIWindow; class CGUILabel; diff --git a/Client/cefweb/CefWeb.cpp b/Client/cefweb/CefWeb.cpp index 39734e969b1..9e6c7c9e128 100644 --- a/Client/cefweb/CefWeb.cpp +++ b/Client/cefweb/CefWeb.cpp @@ -3,27 +3,66 @@ * PROJECT: Multi Theft Auto v1.0 * LICENSE: See LICENSE in the top level directory * FILE: CefWeb.cpp + * PURPOSE: CEF web browser module initialization entry point * * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ #include "StdInc.h" -#include "SharedUtil.hpp" +#include +#include -CCoreInterface* g_pCore = NULL; +CCoreInterface* g_pCore = nullptr; CLocalizationInterface* g_pLocalization = nullptr; -extern "C" _declspec(dllexport) CWebCoreInterface* InitWebCoreInterface(CCoreInterface* pCore) +namespace { - g_pCore = pCore; - g_pLocalization = pCore->GetLocalization(); + [[nodiscard]] inline bool InitializeGlobalInterfaces(CCoreInterface* pCore) noexcept + { + if (!pCore) [[unlikely]] + return false; + + g_pCore = pCore; + g_pLocalization = pCore->GetLocalization(); + + // Localization is critical for browser GUI (request dialogs, etc.) + if (!g_pLocalization) [[unlikely]] + return false; + + return true; + } - // Ensure main thread identification is consistent - IsMainThread(); + // + // Performs required runtime initialization + // Must be called on the main thread before creating CWebCore + // + inline void PerformRuntimeInitialization() noexcept + { + // Ensure main thread identification is consistent + IsMainThread(); + + // Set up memory allocation failure handler for CEF processes + SharedUtil::SetMemoryAllocationFailureHandler(); + } +} // namespace + +// +// DLL export: Initialize the web browser subsystem +// Called by CCore::GetWebCore() during initialization +// Returns CWebCoreInterface pointer on success, nullptr on failure +// Thread safety: Must be called from the main thread only +// +extern "C" _declspec(dllexport) CWebCoreInterface* InitWebCoreInterface(CCoreInterface* pCore) +{ + // Validate and initialize global interfaces + if (!InitializeGlobalInterfaces(pCore)) [[unlikely]] + return nullptr; - SetMemoryAllocationFailureHandler(); + // Perform runtime initialization + PerformRuntimeInitialization(); - CWebCore* pWebCore = new CWebCore; - return pWebCore; + // Create and return the web core instance + // Using make_unique for exception safety, then releasing ownership to caller + return std::make_unique().release(); } diff --git a/Client/cefweb/StdInc.cpp b/Client/cefweb/StdInc.cpp index 2594336e532..abddc0b5f1a 100644 --- a/Client/cefweb/StdInc.cpp +++ b/Client/cefweb/StdInc.cpp @@ -1,2 +1,3 @@ // StdInc.h #include "StdInc.h" +#include "SharedUtil.hpp" diff --git a/Client/cefweb/StdInc.h b/Client/cefweb/StdInc.h index 41126f31f16..473c51da714 100644 --- a/Client/cefweb/StdInc.h +++ b/Client/cefweb/StdInc.h @@ -1,5 +1,9 @@ #include +#include +#include +#include +#include #define MTA_CLIENT #define SHARED_UTIL_WITH_FAST_HASH_MAP #include "SharedUtil.h" diff --git a/Client/cefweb/WebBrowserHelpers.h b/Client/cefweb/WebBrowserHelpers.h index 79dd15c0326..e4ac040bd04 100644 --- a/Client/cefweb/WebBrowserHelpers.h +++ b/Client/cefweb/WebBrowserHelpers.h @@ -8,6 +8,7 @@ * *****************************************************************************/ #pragma once +#include #include #include @@ -18,18 +19,27 @@ bool isKeyDown(WPARAM wParam) int GetCefKeyboardModifiers(WPARAM wParam, LPARAM lParam) { + // Optimization for Wine: Use GetKeyboardState to fetch all key states in one go + // instead of multiple GetKeyState calls which can be slow due to round-trips. + BYTE keyState[256]; + if (!GetKeyboardState(keyState)) + return 0; + + auto checkKey = [&](int key) { return (keyState[key] & 0x80) != 0; }; + auto checkToggle = [&](int key) { return (keyState[key] & 1) != 0; }; + int modifiers = 0; - if (isKeyDown(VK_SHIFT)) + if (checkKey(VK_SHIFT)) modifiers |= EVENTFLAG_SHIFT_DOWN; - if (isKeyDown(VK_CONTROL)) + if (checkKey(VK_CONTROL)) modifiers |= EVENTFLAG_CONTROL_DOWN; - if (isKeyDown(VK_MENU)) + if (checkKey(VK_MENU)) modifiers |= EVENTFLAG_ALT_DOWN; // Low bit set from GetKeyState indicates "toggled". - if (::GetKeyState(VK_NUMLOCK) & 1) + if (checkToggle(VK_NUMLOCK)) modifiers |= EVENTFLAG_NUM_LOCK_ON; - if (::GetKeyState(VK_CAPITAL) & 1) + if (checkToggle(VK_CAPITAL)) modifiers |= EVENTFLAG_CAPS_LOCK_ON; switch (wParam) @@ -71,21 +81,21 @@ int GetCefKeyboardModifiers(WPARAM wParam, LPARAM lParam) modifiers |= EVENTFLAG_IS_KEY_PAD; break; case VK_SHIFT: - if (isKeyDown(VK_LSHIFT)) + if (checkKey(VK_LSHIFT)) modifiers |= EVENTFLAG_IS_LEFT; - else if (isKeyDown(VK_RSHIFT)) + else if (checkKey(VK_RSHIFT)) modifiers |= EVENTFLAG_IS_RIGHT; break; case VK_CONTROL: - if (isKeyDown(VK_LCONTROL)) + if (checkKey(VK_LCONTROL)) modifiers |= EVENTFLAG_IS_LEFT; - else if (isKeyDown(VK_RCONTROL)) + else if (checkKey(VK_RCONTROL)) modifiers |= EVENTFLAG_IS_RIGHT; break; case VK_MENU: - if (isKeyDown(VK_LMENU)) + if (checkKey(VK_LMENU)) modifiers |= EVENTFLAG_IS_LEFT; - else if (isKeyDown(VK_RMENU)) + else if (checkKey(VK_RMENU)) modifiers |= EVENTFLAG_IS_RIGHT; break; case VK_LWIN: diff --git a/Client/cefweb/premake5.lua b/Client/cefweb/premake5.lua index da81e609de5..89369d92852 100644 --- a/Client/cefweb/premake5.lua +++ b/Client/cefweb/premake5.lua @@ -3,10 +3,10 @@ project "Client Webbrowser" kind "SharedLib" targetname "cefweb" targetdir(buildpath("mta")) + clangtidy "On" filter "system:windows" includedirs { "../../vendor/sparsehash/src/windows" } - linkoptions { "/SAFESEH:NO" } buildoptions { "-Zm130" } filter {} @@ -38,6 +38,8 @@ project "Client Webbrowser" "**.cpp" } + filter {} + links { "libcef", "CEF", "Psapi.lib", "version.lib", "Winmm.lib", "Ws2_32.lib", "DbgHelp.lib" } diff --git a/Client/core/CAdditionalVertexStreamManager.cpp b/Client/core/CAdditionalVertexStreamManager.cpp index f5a200e58ca..7d191c0d6f8 100644 --- a/Client/core/CAdditionalVertexStreamManager.cpp +++ b/Client/core/CAdditionalVertexStreamManager.cpp @@ -11,20 +11,51 @@ #include "StdInc.h" #include "CAdditionalVertexStreamManager.h" +#include "DXHook/CProxyDirect3DDevice9.h" +#include +#include -CAdditionalVertexStreamManager* CAdditionalVertexStreamManager::ms_Singleton = NULL; +CAdditionalVertexStreamManager* CAdditionalVertexStreamManager::ms_Singleton = nullptr; namespace { // Helper functions for this file only - // Convert size of PT stream to sizeof of N stream - uint ConvertPTSize(uint SizePT) { return SizePT * 12 / 20; } + uint ConvertPTOffset(uint OffsetPT) + { + return (OffsetPT / 20) * 12; + } + + // Convert size of PT stream to sizeof of N stream (rounded up to the next vertex) + uint ConvertPTSize(uint SizePT) + { + uint64_t padded = static_cast(SizePT) + 19ull; + uint64_t result = (padded / 20ull) * 12ull; + if (result > std::numeric_limits::max()) + return std::numeric_limits::max(); + return static_cast(result); + } + + struct STriKey + { + uint32_t v0; + uint32_t v1; + uint32_t v2; - // Get 64 bit key for a triangle by using the ordered vertex indices - long long getTriKey(WORD a, WORD b, WORD c) + bool operator<(const STriKey& rhs) const + { + if (v0 != rhs.v0) + return v0 < rhs.v0; + if (v1 != rhs.v1) + return v1 < rhs.v1; + return v2 < rhs.v2; + } + }; + + // Get ordered key for a triangle by using the sorted vertex indices + STriKey GetTriKey(uint32_t a, uint32_t b, uint32_t c) { - WORD tmp; + uint32_t tmp; if (b < a) { tmp = b; @@ -43,9 +74,12 @@ namespace b = a; a = tmp; } - return (((long long)a) << 32) | (((long long)b) << 16) | ((long long)c); + STriKey key = {a, b, c}; + return key; } -} // namespace + + std::mutex g_singletonMutex; +} // namespace /////////////////////////////////////////////////////////////// // @@ -67,6 +101,17 @@ CAdditionalVertexStreamManager::CAdditionalVertexStreamManager() /////////////////////////////////////////////////////////////// CAdditionalVertexStreamManager::~CAdditionalVertexStreamManager() { + SAFE_RELEASE(m_pOldVertexDeclaration); + + for (auto iter = m_AdditionalStreamInfoMap.begin(); iter != m_AdditionalStreamInfoMap.end(); ++iter) + { + SAdditionalStreamInfo& info = iter->second; + SAFE_RELEASE(info.pStreamData); + SAFE_RELEASE(info.pVertexDeclaration); + } + + m_AdditionalStreamInfoMap.clear(); + m_pDevice = nullptr; } /////////////////////////////////////////////////////////////// @@ -78,11 +123,28 @@ CAdditionalVertexStreamManager::~CAdditionalVertexStreamManager() /////////////////////////////////////////////////////////////// CAdditionalVertexStreamManager* CAdditionalVertexStreamManager::GetSingleton() { + std::lock_guard guard(g_singletonMutex); if (!ms_Singleton) ms_Singleton = new CAdditionalVertexStreamManager(); return ms_Singleton; } +CAdditionalVertexStreamManager* CAdditionalVertexStreamManager::GetExistingSingleton() +{ + std::lock_guard guard(g_singletonMutex); + return ms_Singleton; +} + +void CAdditionalVertexStreamManager::DestroySingleton() +{ + std::lock_guard guard(g_singletonMutex); + if (!ms_Singleton) + return; + + delete ms_Singleton; + ms_Singleton = nullptr; +} + /////////////////////////////////////////////////////////////// // // CAdditionalVertexStreamManager::OnDeviceCreate @@ -105,6 +167,9 @@ void CAdditionalVertexStreamManager::OnDeviceCreate(IDirect3DDevice9* pDevice) bool CAdditionalVertexStreamManager::MaybeSetAdditionalVertexStream(D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) { + if (!m_pDevice) + return false; + // Cache info SCurrentStateInfo state; @@ -117,14 +182,14 @@ bool CAdditionalVertexStreamManager::MaybeSetAdditionalVertexStream(D3DPRIMITIVE state.args.primCount = primCount; // Cache info about state streams etc - UpdateCurrentStateInfo(state); + if (!UpdateCurrentStateInfo(state)) + return false; // For now, this only works if the original has 3 decl elements (0:D, 1:P, 1:T) and stream 1 has a stride of 20 if (!CheckCanDoThis(state)) return false; - SetAdditionalVertexStream(state); - return true; + return SetAdditionalVertexStream(state); } /////////////////////////////////////////////////////////////// @@ -134,49 +199,95 @@ bool CAdditionalVertexStreamManager::MaybeSetAdditionalVertexStream(D3DPRIMITIVE // // /////////////////////////////////////////////////////////////// -void CAdditionalVertexStreamManager::SetAdditionalVertexStream(SCurrentStateInfo& state) +bool CAdditionalVertexStreamManager::SetAdditionalVertexStream(SCurrentStateInfo& state) { - HRESULT hr; - // Get matching custom N vbuffer for std PT vbuffer SAdditionalStreamInfo* pAdditionalInfo = GetAdditionalStreamInfo(state.stream1.pStreamData); if (!pAdditionalInfo) pAdditionalInfo = CreateAdditionalStreamInfo(state); + if (!pAdditionalInfo) + return false; + uint StridePT = 20; uint StrideN = 12; - // Calc area we are going to use - uint viMinBased = state.args.MinVertexIndex + state.args.BaseVertexIndex; - uint viMaxBased = state.args.MinVertexIndex + state.args.NumVertices + state.args.BaseVertexIndex; + const INT baseVertexIndex = state.args.BaseVertexIndex; + + const int64_t maxUint = static_cast(std::numeric_limits::max()); + const int64_t viMinBasedSigned = static_cast(state.args.MinVertexIndex) + static_cast(baseVertexIndex); + if (viMinBasedSigned < 0 || viMinBasedSigned > maxUint) + return false; + + const int64_t viMaxBasedSigned = viMinBasedSigned + static_cast(state.args.NumVertices); + if (viMaxBasedSigned < viMinBasedSigned || viMaxBasedSigned > maxUint) + return false; + + uint viMinBased = static_cast(viMinBasedSigned); + uint viMaxBased = static_cast(viMaxBasedSigned); + uint vertexSpan = viMaxBased - viMinBased; + + uint64_t readOffsetStart64 = static_cast(viMinBased) * StridePT + state.stream1.OffsetInBytes; + if (readOffsetStart64 > std::numeric_limits::max()) + return false; + uint ReadOffsetStart = static_cast(readOffsetStart64); - uint ReadOffsetStart = viMinBased * StridePT + state.stream1.OffsetInBytes; - uint ReadOffsetSize = (viMaxBased - viMinBased) * StridePT; + uint64_t readOffsetSize64 = static_cast(vertexSpan) * StridePT; + if (readOffsetSize64 > std::numeric_limits::max()) + return false; + uint ReadOffsetSize = static_cast(readOffsetSize64); + + uint OffsetInBytesN = ConvertPTOffset(state.stream1.OffsetInBytes); + uint64_t writeOffsetStart64 = static_cast(viMinBased) * StrideN + OffsetInBytesN; + if (writeOffsetStart64 > std::numeric_limits::max()) + return false; + uint WriteOffsetStart = static_cast(writeOffsetStart64); - uint OffsetInBytesN = ConvertPTSize(state.stream1.OffsetInBytes); - uint WriteOffsetStart = viMinBased * StrideN + OffsetInBytesN; - uint WriteOffsetSize = (viMaxBased - viMinBased) * StrideN; + uint64_t writeOffsetSize64 = static_cast(vertexSpan) * StrideN; + if (writeOffsetSize64 > std::numeric_limits::max()) + return false; + uint WriteOffsetSize = static_cast(writeOffsetSize64); - assert(WriteOffsetStart == ConvertPTSize(ReadOffsetStart)); + assert(WriteOffsetStart == ConvertPTOffset(ReadOffsetStart)); assert(WriteOffsetSize == ConvertPTSize(ReadOffsetSize)); // See if area VB area needs updating if (!pAdditionalInfo->ConvertedRanges.IsRangeSet(WriteOffsetStart, WriteOffsetSize)) { - // Update VB area - UpdateAdditionalStreamContent(state, pAdditionalInfo, ReadOffsetStart, ReadOffsetSize, WriteOffsetStart, WriteOffsetSize); + if (!UpdateAdditionalStreamContent(state, pAdditionalInfo, ReadOffsetStart, ReadOffsetSize, WriteOffsetStart, WriteOffsetSize)) + return false; + pAdditionalInfo->ConvertedRanges.SetRange(WriteOffsetStart, WriteOffsetSize); } - // Save old declaration - hr = m_pDevice->GetVertexDeclaration(&m_pOldVertexDeclaration); + IDirect3DVertexDeclaration9* pPreviousDecl = nullptr; + if (FAILED(m_pDevice->GetVertexDeclaration(&pPreviousDecl))) + return false; + + CScopedActiveProxyDevice proxyDevice; + if (!proxyDevice) + { + SAFE_RELEASE(pPreviousDecl); + return false; + } - // Set declaration - hr = g_pProxyDevice->SetVertexDeclaration(pAdditionalInfo->pVertexDeclaration); + if (FAILED(proxyDevice->SetVertexDeclaration(pAdditionalInfo->pVertexDeclaration))) + { + SAFE_RELEASE(pPreviousDecl); + return false; + } - // Set additional stream - uint OffsetInBytes = ConvertPTSize(state.stream1.OffsetInBytes); - hr = m_pDevice->SetStreamSource(2, pAdditionalInfo->pStreamData, OffsetInBytes, pAdditionalInfo->Stride); + uint OffsetInBytes = ConvertPTOffset(state.stream1.OffsetInBytes); + if (FAILED(m_pDevice->SetStreamSource(2, pAdditionalInfo->pStreamData, OffsetInBytes, pAdditionalInfo->Stride))) + { + proxyDevice->SetVertexDeclaration(pPreviousDecl); + SAFE_RELEASE(pPreviousDecl); + return false; + } + + SAFE_RELEASE(m_pOldVertexDeclaration); + m_pOldVertexDeclaration = pPreviousDecl; + return true; } /////////////////////////////////////////////////////////////// @@ -188,15 +299,26 @@ void CAdditionalVertexStreamManager::SetAdditionalVertexStream(SCurrentStateInfo /////////////////////////////////////////////////////////////// void CAdditionalVertexStreamManager::MaybeUnsetAdditionalVertexStream() { - HRESULT hr; + if (!m_pDevice) + return; + if (m_pOldVertexDeclaration) { - // Set prev declaration - hr = g_pProxyDevice->SetVertexDeclaration(m_pOldVertexDeclaration); - SAFE_RELEASE(m_pOldVertexDeclaration); + HRESULT hr = m_pDevice->TestCooperativeLevel(); + const bool bDeviceOperational = (hr == D3D_OK); + + if (bDeviceOperational) + { + // Set prev declaration + CScopedActiveProxyDevice proxyDevice; + if (proxyDevice) + proxyDevice->SetVertexDeclaration(m_pOldVertexDeclaration); + + // Unset additional stream + m_pDevice->SetStreamSource(2, nullptr, 0, 0); + } - // Unset additional stream - hr = m_pDevice->SetStreamSource(2, NULL, 0, 0); + SAFE_RELEASE(m_pOldVertexDeclaration); } } @@ -218,12 +340,44 @@ bool CAdditionalVertexStreamManager::UpdateAdditionalStreamContent(SCurrentState uint NumVerts = ReadSize / StridePT; assert(NumVerts == WriteSize / StrideN); + if (ReadSize == 0 || WriteSize == 0) + return false; + + if ((ReadSize % StridePT) != 0) + return false; + + if ((WriteSize % StrideN) != 0) + return false; + + if (WriteSize != NumVerts * StrideN) + return false; + + if (NumVerts == 0) + return false; + + const UINT bufferSizePT = state.decl.VertexBufferDesc1.Size; + if (ReadOffsetStart > bufferSizePT) + return false; + + if (ReadSize > bufferSizePT - ReadOffsetStart) + return false; + + D3DVERTEXBUFFER_DESC destDesc; + if (FAILED(pStreamDataN->GetDesc(&destDesc))) + return false; + + if (WriteOffsetStart > destDesc.Size) + return false; + + if (WriteSize > destDesc.Size - WriteOffsetStart) + return false; + // Get the source vertex bytes std::vector sourceArray; sourceArray.resize(ReadSize); uchar* pSourceArrayBytes = &sourceArray[0]; { - void* pVertexBytesPT = NULL; + void* pVertexBytesPT = nullptr; if (FAILED(pStreamDataPT->Lock(ReadOffsetStart, ReadSize, &pVertexBytesPT, D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) return false; memcpy(pSourceArrayBytes, pVertexBytesPT, ReadSize); @@ -238,13 +392,21 @@ bool CAdditionalVertexStreamManager::UpdateAdditionalStreamContent(SCurrentState // Compute dest bytes { // Get index buffer - if (FAILED(m_pDevice->GetIndices(&state.pIndexData))) + if (FAILED(m_pDevice->GetIndices(&state.pIndexData)) || !state.pIndexData) return false; // Get index buffer desc D3DINDEXBUFFER_DESC IndexBufferDesc; state.pIndexData->GetDesc(&IndexBufferDesc); + uint indexStride = 0; + if (IndexBufferDesc.Format == D3DFMT_INDEX16) + indexStride = sizeof(WORD); + else if (IndexBufferDesc.Format == D3DFMT_INDEX32) + indexStride = sizeof(DWORD); + else + return false; + uint numIndices = state.args.primCount + 2; uint step = 1; if (state.args.PrimitiveType == D3DPT_TRIANGLELIST) @@ -252,17 +414,35 @@ bool CAdditionalVertexStreamManager::UpdateAdditionalStreamContent(SCurrentState numIndices = state.args.primCount * 3; step = 3; } - assert(IndexBufferDesc.Size >= (numIndices + state.args.startIndex) * 2); - // Get index buffer data - std::vector indexArray; - indexArray.resize(ReadSize); - uchar* pIndexArrayBytes = &indexArray[0]; + size_t startByte = static_cast(state.args.startIndex) * indexStride; + size_t requiredBytes = static_cast(numIndices) * indexStride; + if (startByte > IndexBufferDesc.Size) + return false; + + if (requiredBytes > IndexBufferDesc.Size - startByte) + return false; + + std::vector indices(numIndices); { - void* pIndexBytes = NULL; - if (FAILED(state.pIndexData->Lock(state.args.startIndex * 2, numIndices * 2, &pIndexBytes, D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) + void* pIndexBytes = nullptr; + if (FAILED( + state.pIndexData->Lock(static_cast(startByte), static_cast(requiredBytes), &pIndexBytes, D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) return false; - memcpy(pIndexArrayBytes, pIndexBytes, numIndices * 2); + + if (indexStride == sizeof(WORD)) + { + const WORD* pSrc = static_cast(pIndexBytes); + for (uint i = 0; i < numIndices; ++i) + indices[i] = pSrc[i]; + } + else + { + const DWORD* pSrc = static_cast(pIndexBytes); + for (uint i = 0; i < numIndices; ++i) + indices[i] = pSrc[i]; + } + state.pIndexData->Unlock(); } @@ -270,26 +450,26 @@ bool CAdditionalVertexStreamManager::UpdateAdditionalStreamContent(SCurrentState std::vector NormalList; NormalList.insert(NormalList.end(), NumVerts, CVector()); - std::map doneTrisMap; + std::map doneTrisMap; // For each triangle for (uint i = 0; i < numIndices - 2; i += step) { // Get triangle vertex indici - WORD v0 = ((WORD*)pIndexArrayBytes)[i]; - WORD v1 = ((WORD*)pIndexArrayBytes)[i + 1]; - WORD v2 = ((WORD*)pIndexArrayBytes)[i + 2]; + uint32_t v0 = indices[i]; + uint32_t v1 = indices[i + 1]; + uint32_t v2 = indices[i + 2]; if (v0 >= NumVerts || v1 >= NumVerts || v2 >= NumVerts) - continue; // vert index out of range + continue; // vert index out of range if (v0 == v1 || v0 == v2 || v1 == v2) - continue; // degenerate tri + continue; // degenerate tri // Get vertex positions from original stream - CVector* pPos0 = (CVector*)(pSourceArrayBytes + v0 * 20); - CVector* pPos1 = (CVector*)(pSourceArrayBytes + v1 * 20); - CVector* pPos2 = (CVector*)(pSourceArrayBytes + v2 * 20); + CVector* pPos0 = reinterpret_cast(pSourceArrayBytes + v0 * StridePT); + CVector* pPos1 = reinterpret_cast(pSourceArrayBytes + v1 * StridePT); + CVector* pPos2 = reinterpret_cast(pSourceArrayBytes + v2 * StridePT); // Calculate the normal CVector Dir1 = *pPos2 - *pPos1; @@ -304,7 +484,7 @@ bool CAdditionalVertexStreamManager::UpdateAdditionalStreamContent(SCurrentState Normal = -Normal; // Try to improve results by ignoring duplicated triangles - long long key = getTriKey(v0, v1, v2); + STriKey key = GetTriKey(v0, v1, v2); if (CVector* pDoneTriPrevNormal = MapFind(doneTrisMap, key)) { // Already done this tri - Keep prev tri if it has a better 'up' rating @@ -334,14 +514,14 @@ bool CAdditionalVertexStreamManager::UpdateAdditionalStreamContent(SCurrentState Normal = CVector(0, 0, 1); // Set - CVector* pNormal = (CVector*)(pDestArrayBytes + i * 12); + CVector* pNormal = reinterpret_cast(pDestArrayBytes + i * StrideN); *pNormal = Normal; } } // Set the dest bytes { - void* pVertexBytesN = NULL; + void* pVertexBytesN = nullptr; if (FAILED(pStreamDataN->Lock(WriteOffsetStart, WriteSize, &pVertexBytesN, D3DLOCK_NOSYSLOCK))) return false; memcpy(pVertexBytesN, pDestArrayBytes, WriteSize); @@ -360,6 +540,9 @@ bool CAdditionalVertexStreamManager::UpdateAdditionalStreamContent(SCurrentState ///////////////////////////////////////////////////////////// bool CAdditionalVertexStreamManager::UpdateCurrentStateInfo(SCurrentStateInfo& state) { + if (!m_pDevice) + return false; + // Get vertex declaration if (FAILED(m_pDevice->GetVertexDeclaration(&state.decl.pVertexDeclaration))) return false; @@ -373,7 +556,7 @@ bool CAdditionalVertexStreamManager::UpdateCurrentStateInfo(SCurrentStateInfo& s // Get vertex stream if (FAILED(m_pDevice->GetStreamSource(1, &state.stream1.pStreamData, &state.stream1.OffsetInBytes, &state.stream1.Stride))) - return NULL; + return false; // Get vertex stream desc if (state.stream1.pStreamData) @@ -466,13 +649,16 @@ SAdditionalStreamInfo* CAdditionalVertexStreamManager::CreateAdditionalStreamInf declNew->Usage = D3DDECLUSAGE_NORMAL; declNew->UsageIndex = 0; if (FAILED(m_pDevice->CreateVertexDeclaration(elements, &info.pVertexDeclaration))) - return false; + return nullptr; // Create new stream info.Stride = sizeof(float) * 3; UINT Size2 = ConvertPTSize(state.decl.VertexBufferDesc1.Size); - if (FAILED(m_pDevice->CreateVertexBuffer(Size2, D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &info.pStreamData, NULL))) - return false; + if (FAILED(m_pDevice->CreateVertexBuffer(Size2, D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &info.pStreamData, nullptr))) + { + SAFE_RELEASE(info.pVertexDeclaration); + return nullptr; + } // Save info MapSet(m_AdditionalStreamInfoMap, state.stream1.pStreamData, info); @@ -512,6 +698,24 @@ void CAdditionalVertexStreamManager::OnVertexBufferRangeInvalidated(IDirect3DVer SAdditionalStreamInfo* pAdditionalInfo = GetAdditionalStreamInfo(pStreamData1); if (pAdditionalInfo) { - pAdditionalInfo->ConvertedRanges.UnsetRange(Offset, Size); + if (Size == 0) + { + pAdditionalInfo->ConvertedRanges = CRanges(); + return; + } + + uint convertedOffset = ConvertPTOffset(Offset); + + uint verticesTouched = Size / 20; + if ((Size % 20) != 0) + ++verticesTouched; + + if (verticesTouched == 0) + verticesTouched = 1; + + uint64_t convertedSize64 = static_cast(verticesTouched) * static_cast(pAdditionalInfo->Stride); + uint convertedSize = convertedSize64 > std::numeric_limits::max() ? std::numeric_limits::max() : static_cast(convertedSize64); + + pAdditionalInfo->ConvertedRanges.UnsetRange(convertedOffset, convertedSize); } } diff --git a/Client/core/CAdditionalVertexStreamManager.h b/Client/core/CAdditionalVertexStreamManager.h index 4a330a3c34b..b9d80b84adf 100644 --- a/Client/core/CAdditionalVertexStreamManager.h +++ b/Client/core/CAdditionalVertexStreamManager.h @@ -84,9 +84,11 @@ class CAdditionalVertexStreamManager void OnVertexBufferRangeInvalidated(IDirect3DVertexBuffer9* pStreamData, uint Offset, uint Size); static CAdditionalVertexStreamManager* GetSingleton(); + static CAdditionalVertexStreamManager* GetExistingSingleton(); + static void DestroySingleton(); protected: - void SetAdditionalVertexStream(SCurrentStateInfo& renderState); + bool SetAdditionalVertexStream(SCurrentStateInfo& renderState); bool UpdateCurrentStateInfo(SCurrentStateInfo& state); bool UpdateAdditionalStreamContent(SCurrentStateInfo& state, SAdditionalStreamInfo* pAdditionalStreamInfo, uint ReadOffsetStart, uint ReadSize, uint WriteOffsetStart, uint WriteSize); diff --git a/Client/core/CChat.cpp b/Client/core/CChat.cpp index 1ae9c99b725..4182d279469 100644 --- a/Client/core/CChat.cpp +++ b/Client/core/CChat.cpp @@ -27,6 +27,7 @@ CChat::CChat(CGUI* pManager, const CVector2D& vecPosition) // Calculate relative position (assuming a 800x600 native resolution for our defined CCHAT_* values) CVector2D vecResolution = m_pManager->GetResolution(); m_vecScale = CVector2D(vecResolution.fX / 800.0f, vecResolution.fY / 600.0f); + m_previousScale = m_vecScale; m_vecBackgroundPosition = vecPosition * vecResolution; // Initialize variables @@ -226,13 +227,13 @@ void CChat::Draw(bool bUseCacheTexture, bool bAllowOutline) iRenderTargetSizeY, g_pDeviceState->AdapterState.Name.c_str())); } } - m_iCacheTextureRevision = -1; // Make sure the graphics will be updated + m_iCacheTextureRevision = -1; // Make sure the graphics will be updated } // If we can't get a rendertarget for some reason, just render the text directly to the screen if (!m_pCacheTexture) { - drawList.bOutline = false; // Outline too slow without cache texture + drawList.bOutline = false; // Outline too slow without cache texture DrawDrawList(drawList, chatTopLeft); return; } @@ -358,7 +359,7 @@ void CChat::GetDrawList(SDrawList& outDrawList, bool bUsingOutline) uiLine = (uiLine + 1) % CHAT_MAX_LINES; uiLinesDrawn++; - if (uiLine == m_uiMostRecentLine) // Went through all lines? + if (uiLine == m_uiMostRecentLine) // Went through all lines? break; } } @@ -465,21 +466,21 @@ void CChat::UpdateSmoothScroll(float* pfPixelScroll, int* piLineScroll) // Also update CssStyle override alpha // float fTarget = (!m_bCssStyleText || m_bInputVisible || m_iScrollingBack) ? 1.0f : 0.0f; - float fMaxAmount = fDeltaSeconds * 2.0f; // 0.5 seconds fade time + float fMaxAmount = fDeltaSeconds * 2.0f; // 0.5 seconds fade time m_fCssStyleOverrideAlpha += Clamp(-fMaxAmount, fTarget - m_fCssStyleOverrideAlpha, fMaxAmount); // // Also update background alpha // fTarget = (!m_bCssStyleBackground || m_bInputVisible || m_iScrollingBack) ? 1.0f : 0.0f; - fMaxAmount = fDeltaSeconds * 5.0f; // 0.2 seconds fade time + fMaxAmount = fDeltaSeconds * 5.0f; // 0.2 seconds fade time m_fBackgroundAlpha += Clamp(-fMaxAmount, fTarget - m_fBackgroundAlpha, fMaxAmount); // // Also update input background alpha // fTarget = (m_bInputVisible) ? 1.0f : 0.0f; - fMaxAmount = fDeltaSeconds * 5.0f; // 0.2 seconds fade time + fMaxAmount = fDeltaSeconds * 5.0f; // 0.2 seconds fade time m_fInputBackgroundAlpha += Clamp(-fMaxAmount, fTarget - m_fInputBackgroundAlpha, fMaxAmount); } @@ -644,7 +645,7 @@ bool CChat::CharacterKeyHandler(CGUIKeyEventArgs KeyboardArgs) case VK_RETURN: { // Empty the chat and hide the input stuff - // If theres a command to call, call it + // If there's a command to call, call it if (!m_strCommand.empty() && !m_strInputText.empty()) CCommands::GetSingleton().Execute(m_strCommand.c_str(), m_strInputText.c_str()); @@ -659,14 +660,14 @@ bool CChat::CharacterKeyHandler(CGUIKeyEventArgs KeyboardArgs) else if (m_strCommand.compare("login") != 0) { // If the input is a command, check that it isn't the 'login' command, if it is censor it - char szInput[256]; + char szInput[256]; unsigned int uiLength = sizeof(szInput) - 1; strncpy(szInput, m_strInputText.c_str() + 1, uiLength); szInput[uiLength] = '\0'; const char* szCommand = strtok(szInput, " "); - + if (szCommand && (strcmp(szCommand, "login") != 0)) m_pInputHistory->Add(m_strInputText); else if ((m_pInputHistory->Empty() || m_pInputHistory->GetLast() != std::string("/login"))) @@ -737,7 +738,7 @@ bool CChat::CharacterKeyHandler(CGUIKeyEventArgs KeyboardArgs) { // Check size if it's ok, then output SString strOutput = strCurrentInput.replace(iFound, std::string::npos, strPlayerName); - if (MbUTF8ToUTF16(strOutput).size() < m_iCharacterLimit) + if (MbUTF8ToUTF16(strOutput).size() < static_cast(m_iCharacterLimit)) { bSuccess = true; m_strLastPlayerNamePart = strPlayerNamePart; @@ -767,7 +768,7 @@ bool CChat::CharacterKeyHandler(CGUIKeyEventArgs KeyboardArgs) if (m_strLastPlayerName.size() != 0) m_strLastPlayerName.clear(); - if (KeyboardArgs.codepoint == 127) // "delete" char, used to remove the previous word from input + if (KeyboardArgs.codepoint == 127) // "delete" char, used to remove the previous word from input { if (m_strInputText.size() > 0) { @@ -802,18 +803,18 @@ bool CChat::CharacterKeyHandler(CGUIKeyEventArgs KeyboardArgs) } // If we haven't exceeded the maximum number of characters per chat message, append the char to the message and update the input control - if (MbUTF8ToUTF16(m_strInputText).size() < m_iCharacterLimit) + if (MbUTF8ToUTF16(m_strInputText).size() < static_cast(m_iCharacterLimit)) { if (KeyboardArgs.codepoint >= 32) { unsigned int uiCharacter = KeyboardArgs.codepoint; - if (uiCharacter < 127) // we have any char from ASCII + if (uiCharacter < 127) // we have any char from ASCII { // injecting as is m_strInputText += static_cast(KeyboardArgs.codepoint); SetInputText(m_strInputText.c_str()); } - else // we have any char from Extended ASCII, any ANSI code page or UNICODE range + else // we have any char from Extended ASCII, any ANSI code page or UNICODE range { // Generate a null-terminating string for our character wchar_t wUNICODE[2] = {static_cast(uiCharacter), '\0'}; @@ -914,6 +915,13 @@ void CChat::SetDxFont(LPD3DXFONT pDXFont) void CChat::UpdateGUI() { + // Check if scale has changed and invalidate cached widths if so + if (m_vecScale != m_previousScale) + { + InvalidateAllCachedWidths(); + m_previousScale = m_vecScale; + } + m_vecBackgroundSize = CVector2D(m_fNativeWidth * m_vecScale.fX, CChat::GetFontHeight(m_vecScale.fY) * (float(m_uiNumLines) + 0.5f)); m_vecBackgroundSize.fX = Round(m_vecBackgroundSize.fX); m_vecBackgroundSize.fY = Round(m_vecBackgroundSize.fY); @@ -935,6 +943,15 @@ void CChat::UpdateGUI() UpdatePosition(); } +void CChat::InvalidateAllCachedWidths() +{ + for (int i = 0; i < CHAT_MAX_LINES; i++) + { + m_Lines[i].InvalidateCache(); + } + m_InputLine.InvalidateCache(); +} + void CChat::UpdatePosition() { CVector2D vecResolution = m_pManager->GetResolution(); @@ -1136,7 +1153,12 @@ void CChat::DrawTextString(const char* szText, CRect2D DrawArea, float fZ, CRect void CChat::SetCharacterLimit(int charLimit) { - m_iCharacterLimit = charLimit; + if (charLimit < 0) + m_iCharacterLimit = 0; + else if (charLimit > m_iMaxCharacterLimit) + m_iCharacterLimit = m_iMaxCharacterLimit; + else + m_iCharacterLimit = charLimit; } float CChat::GetChatBottomPosition() const noexcept @@ -1166,78 +1188,78 @@ const char* CalcAnsiPtr(const char* szStringAnsi, const wchar_t* szPosition) return szStringAnsi + iOffset; } -const char* CChatLine::Format(const char* szStringAnsi, float fWidth, CColor& color, bool bColorCoded) +const char* CChatLine::Format(const char* text, float width, CColor& color, bool colorCoded) { - std::wstring wString = MbUTF8ToUTF16(szStringAnsi); + std::wstring wString = MbUTF8ToUTF16(text); const wchar_t* szString = wString.c_str(); - float fPrevSectionsWidth = 0.0f; + float prevSectionsWidth = 0.0f; m_Sections.clear(); - const wchar_t* szSectionStart = szString; - const wchar_t* szSectionEnd = szString; - const wchar_t* szLastWrapPoint = szString; - bool bLastSection = false; - while (!bLastSection) // iterate over sections + const wchar_t* sectionStart = szString; + const wchar_t* sectionEnd = szString; + const wchar_t* lastWrapPoint = szString; + bool lastSection = false; + while (!lastSection) // iterate over sections { m_Sections.resize(m_Sections.size() + 1); CChatLineSection& section = *(m_Sections.end() - 1); section.SetColor(color); - if (m_Sections.size() > 1 && bColorCoded) // If we've processed sections before - szSectionEnd += 7; // skip the color code + if (m_Sections.size() > 1 && colorCoded) // If we've processed sections before + sectionEnd += 7; // skip the color code - szSectionStart = szSectionEnd; - szLastWrapPoint = szSectionStart; - unsigned int uiSeekPos = 0; - std::wstring strSectionStart = szSectionStart; + sectionStart = sectionEnd; + lastWrapPoint = sectionStart; + unsigned int seekPos = 0; + std::wstring strSectionStart = sectionStart; - while (true) // find end of this section + while (true) // find end of this section { - float fSectionWidth = CChat::GetTextExtent(UTF16ToMbUTF8(strSectionStart.substr(0, uiSeekPos)).c_str(), g_pChat->m_vecScale.fX); + float sectionWidth = CChat::GetTextExtent(UTF16ToMbUTF8(strSectionStart.substr(0, seekPos)).c_str(), g_pChat->m_vecScale.fX); - if (*szSectionEnd == '\0' || *szSectionEnd == '\n' || std::ceil(fPrevSectionsWidth + fSectionWidth) > fWidth) + if (*sectionEnd == '\0' || *sectionEnd == '\n' || std::ceil(prevSectionsWidth + sectionWidth) > width) { - bLastSection = true; + lastSection = true; break; } - if (bColorCoded && IsColorCode(UTF16ToMbUTF8(szSectionEnd).c_str())) + if (colorCoded && IsColorCode(UTF16ToMbUTF8(sectionEnd).c_str())) { - unsigned long ulColor = 0; - sscanf(UTF16ToMbUTF8(szSectionEnd).c_str() + 1, "%06x", &ulColor); - color = ulColor; - fPrevSectionsWidth += fSectionWidth; + unsigned long colorValue = 0; + sscanf(UTF16ToMbUTF8(sectionEnd).c_str() + 1, "%06x", &colorValue); + color = colorValue; + prevSectionsWidth += sectionWidth; break; } - if (isspace((unsigned char)*szSectionEnd) || ispunct((unsigned char)*szSectionEnd)) + if (isspace((unsigned char)*sectionEnd) || ispunct((unsigned char)*sectionEnd)) { - szLastWrapPoint = szSectionEnd; + lastWrapPoint = sectionEnd; } - szSectionEnd++; - uiSeekPos++; + sectionEnd++; + seekPos++; } - section.m_strText = UTF16ToMbUTF8(strSectionStart.substr(0, uiSeekPos)); + section.m_text = UTF16ToMbUTF8(strSectionStart.substr(0, seekPos)); } - if (*szSectionEnd == '\0') + if (*sectionEnd == '\0') { - return NULL; + return nullptr; } - else if (*szSectionEnd == '\n') + else if (*sectionEnd == '\n') { - return CalcAnsiPtr(szStringAnsi, szSectionEnd + 1); + return CalcAnsiPtr(text, sectionEnd + 1); } else { // Do word wrap - if (szLastWrapPoint == szSectionStart) + if (lastWrapPoint == sectionStart) { // Wrapping point coincides with the start of a section. - if (szLastWrapPoint == szString) + if (lastWrapPoint == szString) { // The line consists of one huge word. Leave the one section we created as it - // is (with the huge word cut off) and return szRemaining as the rest of the word - return CalcAnsiPtr(szStringAnsi, szSectionEnd); + // is (with the huge word cut off) and return remaining as the rest of the word + return CalcAnsiPtr(text, sectionEnd); } else { @@ -1249,56 +1271,61 @@ const char* CChatLine::Format(const char* szStringAnsi, float fWidth, CColor& co { // Wrapping point is in the middle of a section, truncate CChatLineSection& last = *(m_Sections.end() - 1); - std::wstring wstrTemp = MbUTF8ToUTF16(last.m_strText); - wstrTemp.resize(szLastWrapPoint - szSectionStart); - last.m_strText = UTF16ToMbUTF8(wstrTemp); + std::wstring wstrTemp = MbUTF8ToUTF16(last.m_text); + wstrTemp.resize(lastWrapPoint - sectionStart); + last.m_text = UTF16ToMbUTF8(wstrTemp); } - return CalcAnsiPtr(szStringAnsi, szLastWrapPoint); + return CalcAnsiPtr(text, lastWrapPoint); + } +} + +void CChatLine::Draw(const CVector2D& position, unsigned char alpha, bool shadow, bool outline, const CRect2D& renderBounds) +{ + float currentX = position.fX; + for (auto& section : m_Sections) + { + section.Draw(CVector2D(currentX, position.fY), alpha, shadow, outline, renderBounds); + currentX += section.GetWidth(); } } -void CChatLine::Draw(const CVector2D& vecPosition, unsigned char ucAlpha, bool bShadow, bool bOutline, const CRect2D& RenderBounds) +float CChatLine::GetWidth() const { - float fCurrentX = vecPosition.fX; - std::vector::iterator iter = m_Sections.begin(); - for (; iter != m_Sections.end(); iter++) + float width = 0.0f; + for (const auto& section : m_Sections) { - (*iter).Draw(CVector2D(fCurrentX, vecPosition.fY), ucAlpha, bShadow, bOutline, RenderBounds); - fCurrentX += (*iter).GetWidth(); + width += section.GetWidth(); } + return width; } -float CChatLine::GetWidth() +void CChatLine::InvalidateCache() { - float fWidth = 0.0f; - std::vector::iterator it; - for (it = m_Sections.begin(); it != m_Sections.end(); it++) + for (auto& section : m_Sections) { - fWidth += (*it).GetWidth(); + section.InvalidateCache(); } - return fWidth; } -void CChatInputLine::Draw(CVector2D& vecPosition, unsigned char ucAlpha, bool bShadow, bool bOutline) +void CChatInputLine::Draw(CVector2D& position, unsigned char alpha, bool shadow, bool outline) { - CRect2D RenderBounds(0, 0, 9999, 9999); + CRect2D renderBounds(0, 0, 9999, 9999); - CColor colPrefix; - m_Prefix.GetColor(colPrefix); - if (colPrefix.A > 0) - m_Prefix.Draw(vecPosition, colPrefix.A, bShadow, bOutline, RenderBounds); + CColor prefixColor; + m_Prefix.GetColor(prefixColor); + if (prefixColor.A > 0) + m_Prefix.Draw(position, prefixColor.A, shadow, outline, renderBounds); if (g_pChat->m_InputTextColor.A > 0 && m_Sections.size() > 0) { - m_Sections[0].Draw(CVector2D(vecPosition.fX + m_Prefix.GetWidth(), vecPosition.fY), g_pChat->m_InputTextColor.A, bShadow, bOutline, RenderBounds); + m_Sections[0].Draw(CVector2D(position.fX + m_Prefix.GetWidth(), position.fY), g_pChat->m_InputTextColor.A, shadow, outline, renderBounds); - float fLineDifference = CChat::GetFontHeight(g_pChat->m_vecScale.fY); + float lineDifference = CChat::GetFontHeight(g_pChat->m_vecScale.fY); - vector::iterator iter = m_ExtraLines.begin(); - for (; iter != m_ExtraLines.end(); iter++) + for (auto& line : m_ExtraLines) { - vecPosition.fY += fLineDifference; - (*iter).Draw(vecPosition, g_pChat->m_InputTextColor.A, bShadow, bOutline, RenderBounds); + position.fY += lineDifference; + line.Draw(position, g_pChat->m_InputTextColor.A, shadow, outline, renderBounds); } } } @@ -1309,10 +1336,20 @@ void CChatInputLine::Clear() m_ExtraLines.clear(); } +void CChatInputLine::InvalidateCache() +{ + CChatLine::InvalidateCache(); + m_Prefix.InvalidateCache(); + for (auto& line : m_ExtraLines) + { + line.InvalidateCache(); + } +} + CChatLineSection::CChatLineSection() { - m_fCachedWidth = -1.0f; - m_uiCachedLength = 0; + m_cachedWidth = -1.0f; + m_cachedLength = 0; } CChatLineSection::CChatLineSection(const CChatLineSection& other) @@ -1322,35 +1359,41 @@ CChatLineSection::CChatLineSection(const CChatLineSection& other) CChatLineSection& CChatLineSection::operator=(const CChatLineSection& other) { - m_strText = other.m_strText; - m_Color = other.m_Color; - m_fCachedWidth = other.m_fCachedWidth; - m_uiCachedLength = other.m_uiCachedLength; + m_text = other.m_text; + m_color = other.m_color; + m_cachedWidth = other.m_cachedWidth; + m_cachedLength = other.m_cachedLength; return *this; } -void CChatLineSection::Draw(const CVector2D& vecPosition, unsigned char ucAlpha, bool bShadow, bool bOutline, const CRect2D& RenderBounds) +void CChatLineSection::Draw(const CVector2D& position, unsigned char alpha, bool shadow, bool outline, const CRect2D& renderBounds) { - if (!m_strText.empty() && ucAlpha > 0) + if (!m_text.empty() && alpha > 0) { - if (bShadow) + if (shadow) { - CRect2D drawShadowAt(vecPosition.fX + 1.0f, vecPosition.fY + 1.0f, vecPosition.fX + 1000.0f, vecPosition.fY + 1000.0f); - CChat::DrawTextString(m_strText.c_str(), drawShadowAt, 0.0f, drawShadowAt, 0, COLOR_ARGB(ucAlpha, 0, 0, 0), g_pChat->m_vecScale.fX, - g_pChat->m_vecScale.fY, bOutline, RenderBounds); + CRect2D drawShadowAt(position.fX + 1.0f, position.fY + 1.0f, position.fX + 1000.0f, position.fY + 1000.0f); + CChat::DrawTextString(m_text.c_str(), drawShadowAt, 0.0f, drawShadowAt, 0, COLOR_ARGB(alpha, 0, 0, 0), g_pChat->m_vecScale.fX, + g_pChat->m_vecScale.fY, outline, renderBounds); } - CRect2D drawAt(vecPosition.fX, vecPosition.fY, vecPosition.fX + 1000.0f, vecPosition.fY + 1000.0f); - CChat::DrawTextString(m_strText.c_str(), drawAt, 0.0f, drawAt, 0, COLOR_ARGB(ucAlpha, m_Color.R, m_Color.G, m_Color.B), g_pChat->m_vecScale.fX, - g_pChat->m_vecScale.fY, bOutline, RenderBounds); + CRect2D drawAt(position.fX, position.fY, position.fX + 1000.0f, position.fY + 1000.0f); + CChat::DrawTextString(m_text.c_str(), drawAt, 0.0f, drawAt, 0, COLOR_ARGB(alpha, m_color.R, m_color.G, m_color.B), g_pChat->m_vecScale.fX, + g_pChat->m_vecScale.fY, outline, renderBounds); } } -float CChatLineSection::GetWidth() +float CChatLineSection::GetWidth() const { - if (m_fCachedWidth < 0.0f || m_strText.size() != m_uiCachedLength) + if (m_cachedWidth < 0.0f || m_text.size() != m_cachedLength) { - m_fCachedWidth = std::ceil(CChat::GetTextExtent(m_strText.c_str(), g_pChat->m_vecScale.fX) / std::max(0.01f, g_pChat->m_vecScale.fX)); - m_uiCachedLength = m_strText.size(); + m_cachedWidth = std::ceil(CChat::GetTextExtent(m_text.c_str(), g_pChat->m_vecScale.fX) / std::max(0.01f, g_pChat->m_vecScale.fX)); + m_cachedLength = m_text.size(); } - return m_fCachedWidth * g_pChat->m_vecScale.fX; + return m_cachedWidth * g_pChat->m_vecScale.fX; +} + +void CChatLineSection::InvalidateCache() +{ + m_cachedWidth = -1.0f; + m_cachedLength = 0; } diff --git a/Client/core/CChat.h b/Client/core/CChat.h index a48b1a2bae2..1aa79c2a834 100644 --- a/Client/core/CChat.h +++ b/Client/core/CChat.h @@ -16,10 +16,10 @@ class CChatLineSection; -#define CHAT_WIDTH 320 // Chatbox default width -#define CHAT_TEXT_COLOR CColor(235, 221, 178) // Chatbox default text color -#define CHAT_MAX_LINES 100 // Chatbox maximum chat lines -#define CHAT_BUFFER 1024 // Chatbox buffer size +#define CHAT_WIDTH 320 // Chatbox default width +#define CHAT_TEXT_COLOR CColor(235, 221, 178) // Chatbox default text color +#define CHAT_MAX_LINES 100 // Chatbox maximum chat lines +#define CHAT_BUFFER 1024 // Chatbox buffer size #define CHAT_INPUT_HISTORY_LENGTH 128 // Chatbox input history length class CColor @@ -47,7 +47,7 @@ class CColor { R = (ulColor >> 16) & 0xFF; G = (ulColor >> 8) & 0xFF; - B = (ulColor)&0xFF; + B = (ulColor) & 0xFF; return *this; } bool operator==(const CColor& other) const { return R == other.R && G == other.G && B == other.B && A == other.A; } @@ -65,18 +65,19 @@ class CChatLineSection CChatLineSection& operator=(const CChatLineSection& other); - void Draw(const CVector2D& vecPosition, unsigned char ucAlpha, bool bShadow, bool bOutline, const CRect2D& RenderBounds); - float GetWidth(); - const char* GetText() { return m_strText.c_str(); } - void SetText(const char* szText) { m_strText = szText; } - void GetColor(CColor& color) { color = m_Color; } - void SetColor(const CColor& color) { m_Color = color; } + void Draw(const CVector2D& position, unsigned char alpha, bool shadow, bool outline, const CRect2D& renderBounds); + float GetWidth() const; + const char* GetText() { return m_text.c_str(); } + void SetText(const char* text) { m_text = text; } + void GetColor(CColor& color) { color = m_color; } + void SetColor(const CColor& color) { m_color = color; } + void InvalidateCache(); protected: - std::string m_strText; - CColor m_Color; - float m_fCachedWidth; - unsigned int m_uiCachedLength; + std::string m_text; + CColor m_color; + mutable float m_cachedWidth; + mutable unsigned int m_cachedLength; }; class CChatLine @@ -84,14 +85,15 @@ class CChatLine public: CChatLine(); - virtual const char* Format(const char* szText, float fWidth, CColor& color, bool bColorCoded); - virtual void Draw(const CVector2D& vecPosition, unsigned char ucAlpha, bool bShadow, bool bOutline, const CRect2D& RenderBounds); - virtual float GetWidth(); + virtual const char* Format(const char* text, float width, CColor& color, bool colorCoded); + virtual void Draw(const CVector2D& position, unsigned char alpha, bool shadow, bool outline, const CRect2D& renderBounds); + virtual float GetWidth() const; bool IsActive() { return m_bActive; } - void SetActive(bool bActive) { m_bActive = bActive; } + void SetActive(bool active) { m_bActive = active; } unsigned long GetCreationTime() { return m_ulCreationTime; } void UpdateCreationTime(); + void InvalidateCache(); protected: bool m_bActive; @@ -102,8 +104,9 @@ class CChatLine class CChatInputLine : public CChatLine { public: - void Draw(CVector2D& vecPosition, unsigned char ucAlpha, bool bShadow, bool bOutline); + void Draw(CVector2D& position, unsigned char alpha, bool shadow, bool outline); void Clear(); + void InvalidateCache(); CChatLineSection m_Prefix; std::vector m_ExtraLines; @@ -153,7 +156,7 @@ class CChat friend class CChatLineSection; public: - CChat(){}; + CChat() {}; CChat(CGUI* pManager, const CVector2D& vecPosition); virtual ~CChat(); @@ -220,9 +223,10 @@ class CChat void DrawDrawList(const SDrawList& drawList, const CVector2D& topLeftOffset = CVector2D(0, 0)); void GetDrawList(SDrawList& outDrawList, bool bUsingOutline); void DrawInputLine(bool bUsingOutline); + void InvalidateAllCachedWidths(); - CChatLine m_Lines[CHAT_MAX_LINES]; // Circular buffer - int m_iScrollState; // 1 up, 0 stop, -1 down + CChatLine m_Lines[CHAT_MAX_LINES]; // Circular buffer + int m_iScrollState; // 1 up, 0 stop, -1 down unsigned int m_uiMostRecentLine; unsigned int m_uiScrollOffset; float m_fSmoothScroll; @@ -266,8 +270,8 @@ class CChat bool m_bVisible; bool m_bInputBlocked; bool m_bInputVisible; - int m_iScrollingBack; // Non zero if currently scrolling back - float m_fCssStyleOverrideAlpha; // For fading out 'CssStyle' effect. (When entering text or scrolling back) + int m_iScrollingBack; // Non zero if currently scrolling back + float m_fCssStyleOverrideAlpha; // For fading out 'CssStyle' effect. (When entering text or scrolling back) float m_fBackgroundAlpha; float m_fInputBackgroundAlpha; @@ -283,6 +287,7 @@ class CChat unsigned long m_ulChatLineFadeOut; bool m_bUseCEGUI; CVector2D m_vecScale; + CVector2D m_previousScale; float m_fNativeWidth; float m_fRcpUsingDxFontScale; diff --git a/Client/core/CClientVariables.cpp b/Client/core/CClientVariables.cpp index 4dbba290e39..65d8e6ce53a 100644 --- a/Client/core/CClientVariables.cpp +++ b/Client/core/CClientVariables.cpp @@ -103,18 +103,16 @@ bool CClientVariables::Get(const std::string& strVariable, CColor& val) strVal = Node(strVariable)->GetTagContent(); ss.str(strVal); - try - { - ss >> iR >> iG >> iB >> iA; - val.R = iR; - val.G = iG; - val.B = iB; - val.A = iA; - } - catch (...) - { + if (!(ss >> iR >> iG >> iB >> iA)) return false; - } + + if (iR < 0 || iR > 255 || iG < 0 || iG > 255 || iB < 0 || iB > 255 || iA < 0 || iA > 255) + return false; + + val.R = static_cast(iR); + val.G = static_cast(iG); + val.B = static_cast(iB); + val.A = static_cast(iA); return true; } @@ -234,7 +232,14 @@ void CClientVariables::ValidateValues() ClampValue("console_pos", CVector2D(0, 0), CVector2D(uiViewportWidth - 32, uiViewportHeight - 32)); ClampValue("console_size", CVector2D(50, 50), CVector2D(uiViewportWidth - 32, uiViewportHeight - 32)); - ClampValue("fps_limit", 0, std::numeric_limits::max()); + + // CVars need a better API for this (Issue #4427) + int temp; + CVARS_GET("fps_limit", temp); + std::uint16_t fps = static_cast(temp); + FPSLimits::IsValidAndSetValid(fps, fps); + CVARS_SET("fps_limit", fps); + ClampValue("chat_font", 0, 3); ClampValue("chat_lines", 3, 62); ClampValue("chat_color", CColor(0, 0, 0, 0), CColor(255, 255, 255, 255)); @@ -257,109 +262,141 @@ void CClientVariables::ValidateValues() ClampValue("voicevolume", 0.0f, 1.0f); ClampValue("mapalpha", 0, 255); ClampValue("mapimage", 0, 1); + ClampValue("borderless_gamma_power", 0.5f, 2.0f); + ClampValue("borderless_brightness_scale", 0.5f, 2.0f); + ClampValue("borderless_contrast_scale", 0.5f, 2.0f); + ClampValue("borderless_saturation_scale", 0.5f, 2.0f); + ClampValue("borderless_gamma_enabled", false, true); + ClampValue("borderless_brightness_enabled", false, true); + ClampValue("borderless_contrast_enabled", false, true); + ClampValue("borderless_saturation_enabled", false, true); + ClampValue("borderless_apply_windowed", false, true); + ClampValue("borderless_apply_fullscreen", false, true); } void CClientVariables::LoadDefaults() { - #define DEFAULT(__x,__y) if(!Exists(__x)) \ - Set(__x,__y) - #define _S(__x) std::string(__x) +#define DEFAULT(__x, __y) \ + if (!Exists(__x)) \ + Set(__x, __y) +#define _S(__x) std::string(__x) if (!Exists("nick")) { - DEFAULT("nick", _S(CNickGen::GetRandomNickname())); // nickname - CCore::GetSingleton().RequestNewNickOnStart(); // Request the user to set a new nickname + DEFAULT("nick", _S(CNickGen::GetRandomNickname())); // nickname + CCore::GetSingleton().RequestNewNickOnStart(); // Request the user to set a new nickname } - DEFAULT("host", _S("127.0.0.1")); // hostname - DEFAULT("port", 22003); // port - DEFAULT("password", _S("")); // password - DEFAULT("debugfile", _S("")); // debug filename - DEFAULT("console_pos", CVector2D(0, 0)); // console position - DEFAULT("console_size", CVector2D(200, 200)); // console size - DEFAULT("serverbrowser_size", CVector2D(720.0f, 495.0f)); // serverbrowser size - DEFAULT("fps_limit", 100); // frame limiter - DEFAULT("chat_font", 2); // chatbox font type - DEFAULT("chat_lines", 10); // chatbox lines - DEFAULT("chat_color", CColor(0, 0, 0, 0)); // chatbox background color - DEFAULT("chat_text_color", CColor(172, 213, 254, 255)); // chatbox text color + DEFAULT("host", _S("127.0.0.1")); // hostname + DEFAULT("port", 22003); // port + DEFAULT("password", _S("")); // password + DEFAULT("debugfile", _S("")); // debug filename + DEFAULT("console_pos", CVector2D(0, 0)); // console position + DEFAULT("console_size", CVector2D(200, 200)); // console size + DEFAULT("serverbrowser_size", CVector2D(720.0f, 495.0f)); // serverbrowser size + DEFAULT("fps_limit", 100); // frame limiter + DEFAULT("vsync", true); // vsync + DEFAULT("chat_font", 2); // chatbox font type + DEFAULT("chat_lines", 10); // chatbox lines + DEFAULT("chat_color", CColor(0, 0, 0, 0)); // chatbox background color + DEFAULT("chat_text_color", CColor(172, 213, 254, 255)); // chatbox text color DEFAULT("chat_text_outline", false); - DEFAULT("chat_input_color", CColor(0, 0, 0, 0)); // chatbox input background color - DEFAULT("chat_input_prefix_color", CColor(172, 213, 254, 255)); // chatbox input prefix color - DEFAULT("chat_input_text_color", CColor(172, 213, 254, 255)); // chatbox input text color - DEFAULT("chat_scale", CVector2D(1.0f, 1.0f)); // chatbox scale - DEFAULT("chat_width", 1.5f); // chatbox width - - DEFAULT("chat_css_style_text", false); // chatbox css/hl style text - DEFAULT("chat_css_style_background", false); // chatbox css/hl style background - DEFAULT("chat_line_life", 12000); // chatbox line life time - DEFAULT("chat_line_fade_out", 3000); // chatbox line fade out time - DEFAULT("chat_use_cegui", false); // chatbox uses cegui - DEFAULT("chat_nickcompletion", true); // chatbox nick completion - DEFAULT("chat_position_offset_x", 0.0125f); // chatbox relative x position offset - DEFAULT("chat_position_offset_y", 0.015f); // chatbox relative y position offset - DEFAULT("chat_position_horizontal", Chat::Position::Horizontal::LEFT); // chatbox horizontal position - DEFAULT("chat_position_vertical", Chat::Position::Vertical::TOP); // chatbox vertical position - DEFAULT("chat_text_alignment", Chat::Text::Align::LEFT); // chatbox horizontal text alignment - DEFAULT("server_can_flash_window", true); // allow server to flash the window - DEFAULT("allow_tray_notifications", true); // allow scripts to create tray balloon notifications - DEFAULT("text_scale", 1.0f); // text scale - DEFAULT("invert_mouse", false); // mouse inverting - DEFAULT("fly_with_mouse", false); // flying with mouse controls - DEFAULT("steer_with_mouse", false); // steering with mouse controls - DEFAULT("classic_controls", false); // classic/standard controls - DEFAULT("mastervolume", 1.0f); // master volume - DEFAULT("mtavolume", 1.0f); // custom sound's volume - DEFAULT("voicevolume", 1.0f); // voice chat output volume - DEFAULT("mapalpha", 155); // player map alpha - DEFAULT("mapimage", 0); // player map image - DEFAULT("browser_speed", 1); // Browser speed - DEFAULT("single_download", 0); // Single connection for downloads - DEFAULT("packet_tag", 0); // Tag network packets - DEFAULT("progress_animation", 1); // Progress spinner at the bottom of the screen - DEFAULT("update_build_type", 0); // 0-stable 1-test 2-nightly - DEFAULT("update_auto_install", 1); // 0-off 1-on - DEFAULT("volumetric_shadows", 0); // Enable volumetric shadows - DEFAULT("aspect_ratio", 0); // Display aspect ratio - DEFAULT("hud_match_aspect_ratio", 1); // GTA HUD should match the display aspect ratio - DEFAULT("anisotropic", 0); // Anisotropic filtering - DEFAULT("grass", 1); // Enable grass - DEFAULT("heat_haze", 1); // Enable heat haze - DEFAULT("tyre_smoke_enabled", 1); // Enable tyre smoke - DEFAULT("high_detail_vehicles", 0); // Disable rendering high detail vehicles all the time - DEFAULT("high_detail_peds", 0); // Disable rendering high detail peds all the time - DEFAULT("blur", 1); // Enable blur - DEFAULT("corona_reflections", 0); // Disable corona rain reflections - DEFAULT("dynamic_ped_shadows", 0); // Disable dynamic ped shadows - DEFAULT("fast_clothes_loading", 1); // 0-off 1-auto 2-on - DEFAULT("allow_screen_upload", 1); // 0-off 1-on - DEFAULT("allow_external_sounds", 1); // 0-off 1-on - DEFAULT("max_clientscript_log_kb", 5000); // Max size in KB (0-No limit) - DEFAULT("display_fullscreen_style", 0); // 0-standard 1-borderless 2-borderless keep res 3-borderless stretch - DEFAULT("display_windowed", 0); // 0-off 1-on - DEFAULT("multimon_fullscreen_minimize", 1); // 0-off 1-on - DEFAULT("vertical_aim_sensitivity", 0.0015f); // 0.0015f is GTA default setting - DEFAULT("process_priority", 0); // 0-normal 1-above normal 2-high - DEFAULT("process_dpi_aware", false); // Enable DPI awareness in core initialization - DEFAULT("mute_master_when_minimized", 0); // 0-off 1-on - DEFAULT("mute_sfx_when_minimized", 0); // 0-off 1-on - DEFAULT("mute_radio_when_minimized", 0); // 0-off 1-on - DEFAULT("mute_mta_when_minimized", 0); // 0-off 1-on - DEFAULT("mute_voice_when_minimized", 0); // 0-off 1-on - DEFAULT("share_file_cache", 1); // 0-no 1-share client resource file cache with other MTA installs - DEFAULT("show_unsafe_resolutions", 0); // 0-off 1-show resolutions that are higher that the desktop - DEFAULT("fov", 70); // Camera field of view - DEFAULT("browser_remote_websites", true); // Load remote websites? - DEFAULT("browser_remote_javascript", true); // Execute javascript on remote websites? - DEFAULT("filter_duplicate_log_lines", true); // Filter duplicate log lines for debug view and clientscript.log - DEFAULT("always_show_transferbox", false); // Should the transfer box always be visible for downloads? (and ignore scripted control) - DEFAULT("allow_discord_rpc", true); // Enable Discord Rich Presence - DEFAULT("discord_rpc_share_data", false); // Consistent Rich Presence data sharing - DEFAULT("discord_rpc_share_data_firsttime", false); // Display the user data sharing consent dialog box - for the first time - DEFAULT("browser_enable_gpu", true); // Enable GPU in CEF? (allows stuff like WebGL to function) - DEFAULT("process_cpu_affinity", true); // Set CPU 0 affinity to improve game performance and fix the known issue in single-threaded games - DEFAULT("ask_before_disconnect", true); // Ask before disconnecting from a server - DEFAULT("allow_steam_client", false); // Allow connecting with the local Steam client (to set GTA:SA ingame status) + DEFAULT("chat_input_color", CColor(0, 0, 0, 0)); // chatbox input background color + DEFAULT("chat_input_prefix_color", CColor(172, 213, 254, 255)); // chatbox input prefix color + DEFAULT("chat_input_text_color", CColor(172, 213, 254, 255)); // chatbox input text color + DEFAULT("chat_scale", CVector2D(1.0f, 1.0f)); // chatbox scale + DEFAULT("chat_width", 1.5f); // chatbox width + + DEFAULT("chat_css_style_text", false); // chatbox css/hl style text + DEFAULT("chat_css_style_background", false); // chatbox css/hl style background + DEFAULT("chat_line_life", 12000); // chatbox line life time + DEFAULT("chat_line_fade_out", 3000); // chatbox line fade out time + DEFAULT("chat_use_cegui", false); // chatbox uses cegui + DEFAULT("chat_nickcompletion", true); // chatbox nick completion + DEFAULT("chat_position_offset_x", 0.0125f); // chatbox relative x position offset + DEFAULT("chat_position_offset_y", 0.015f); // chatbox relative y position offset + DEFAULT("chat_position_horizontal", Chat::Position::Horizontal::LEFT); // chatbox horizontal position + DEFAULT("chat_position_vertical", Chat::Position::Vertical::TOP); // chatbox vertical position + DEFAULT("chat_text_alignment", Chat::Text::Align::LEFT); // chatbox horizontal text alignment + DEFAULT("server_can_flash_window", true); // allow server to flash the window + DEFAULT("allow_tray_notifications", true); // allow scripts to create tray balloon notifications + DEFAULT("text_scale", 1.0f); // text scale + DEFAULT("invert_mouse", false); // mouse inverting + DEFAULT("fly_with_mouse", false); // flying with mouse controls + DEFAULT("steer_with_mouse", false); // steering with mouse controls + DEFAULT("classic_controls", false); // classic/standard controls + DEFAULT("mastervolume", 1.0f); // master volume + DEFAULT("mtavolume", 1.0f); // custom sound's volume + DEFAULT("voicevolume", 1.0f); // voice chat output volume + DEFAULT("mapalpha", 155); // player map alpha + DEFAULT("mapimage", 0); // player map image + DEFAULT("browser_speed", 1); // Browser speed + DEFAULT("single_download", 0); // Single connection for downloads + DEFAULT("packet_tag", 0); // Tag network packets + DEFAULT("progress_animation", 1); // Progress spinner at the bottom of the screen + DEFAULT("update_build_type", 0); // 0-stable 1-test 2-nightly + DEFAULT("update_auto_install", 1); // 0-off 1-on + DEFAULT("volumetric_shadows", 0); // Enable volumetric shadows + DEFAULT("aspect_ratio", 0); // Display aspect ratio + DEFAULT("hud_match_aspect_ratio", 1); // GTA HUD should match the display aspect ratio + DEFAULT("anisotropic", 0); // Anisotropic filtering + DEFAULT("grass", 1); // Enable grass + DEFAULT("heat_haze", 1); // Enable heat haze + DEFAULT("tyre_smoke_enabled", 1); // Enable tyre smoke + DEFAULT("high_detail_vehicles", 0); // Disable rendering high detail vehicles all the time + DEFAULT("high_detail_peds", 0); // Disable rendering high detail peds all the time + DEFAULT("blur", 1); // Enable blur + DEFAULT("corona_reflections", 0); // Disable corona rain reflections + DEFAULT("dynamic_ped_shadows", 0); // Disable dynamic ped shadows + DEFAULT("fast_clothes_loading", 1); // 0-off 1-auto 2-on + DEFAULT("allow_screen_upload", 1); // 0-off 1-on + DEFAULT("allow_external_sounds", 1); // 0-off 1-on + DEFAULT("max_clientscript_log_kb", 5000); // Max size in KB (0-No limit) + DEFAULT("display_fullscreen_style", 0); // 0-standard 1-borderless 2-borderless keep res 3-borderless stretch + DEFAULT("display_windowed", 0); // 0-off 1-on + DEFAULT("multimon_fullscreen_minimize", 1); // 0-off 1-on + DEFAULT("borderless_gamma_power", 0.95f); // Gamma exponent applied to windowed gamma ramp (1.0 = unchanged) + DEFAULT("borderless_brightness_scale", 1.03f); // Brightness multiplier for windowed gamma ramp (1.0 = unchanged) + DEFAULT("borderless_contrast_scale", 1.0f); // Contrast multiplier for borderless presentation (1.0 = unchanged) + DEFAULT("borderless_saturation_scale", 1.0f); // Saturation multiplier for borderless presentation (1.0 = unchanged) + DEFAULT("borderless_enable_srgb", false); // Enable sRGB correction when running borderless + DEFAULT("borderless_gamma_enabled", false); // Apply gamma adjustment while borderless tuning active + DEFAULT("borderless_brightness_enabled", false); // Apply brightness adjustment while borderless tuning active + DEFAULT("borderless_contrast_enabled", false); // Apply contrast adjustment while borderless tuning active + DEFAULT("borderless_saturation_enabled", false); // Apply saturation adjustment while borderless tuning active + DEFAULT("borderless_apply_windowed", false); // Apply display adjustments while windowed/borderless + DEFAULT("borderless_apply_fullscreen", false); // Apply display adjustments while in exclusive fullscreen + + if (Exists("borderless_enable_srgb")) + { + bool legacyEnable = false; + Get("borderless_enable_srgb", legacyEnable); + Set("borderless_apply_windowed", legacyEnable); + } + DEFAULT("vertical_aim_sensitivity", 0.0015f); // 0.0015f is GTA default setting + DEFAULT("process_priority", 0); // 0-normal 1-above normal 2-high + DEFAULT("process_dpi_aware", false); // Enable DPI awareness in core initialization + DEFAULT("mute_master_when_minimized", 0); // 0-off 1-on + DEFAULT("mute_sfx_when_minimized", 0); // 0-off 1-on + DEFAULT("mute_radio_when_minimized", 0); // 0-off 1-on + DEFAULT("mute_mta_when_minimized", 0); // 0-off 1-on + DEFAULT("mute_voice_when_minimized", 0); // 0-off 1-on + DEFAULT("share_file_cache", 1); // 0-no 1-share client resource file cache with other MTA installs + DEFAULT("show_unsafe_resolutions", 0); // 0-off 1-show resolutions that are higher that the desktop + DEFAULT("fov", 70); // Camera field of view + DEFAULT("browser_remote_websites", true); // Load remote websites? + DEFAULT("browser_remote_javascript", true); // Execute javascript on remote websites? + DEFAULT("filter_duplicate_log_lines", true); // Filter duplicate log lines for debug view and clientscript.log + DEFAULT("always_show_transferbox", false); // Should the transfer box always be visible for downloads? (and ignore scripted control) + DEFAULT("allow_discord_rpc", true); // Enable Discord Rich Presence + DEFAULT("discord_rpc_share_data", false); // Consistent Rich Presence data sharing + DEFAULT("discord_rpc_share_data_firsttime", false); // Display the user data sharing consent dialog box - for the first time + DEFAULT("browser_enable_gpu", true); // Enable GPU in CEF? (allows stuff like WebGL to function) + DEFAULT("process_cpu_affinity", true); // Set CPU 0 affinity to improve game performance and fix the known issue in single-threaded games + DEFAULT("ask_before_disconnect", true); // Ask before disconnecting from a server + DEFAULT("allow_steam_client", false); // Allow connecting with the local Steam client (to set GTA:SA ingame status) + DEFAULT("use_mouse_sensitivity_for_aiming", + false); // It uses the horizontal mouse sensitivity for aiming, making the Y-axis sensitivity the same as the X-axis if (!Exists("locale")) { @@ -379,4 +416,7 @@ void CClientVariables::LoadDefaults() #if 0 DEFAULT ( "streaming_memory", 50 ); // Streaming memory #endif + +#undef DEFAULT +#undef _S } diff --git a/Client/core/CClientVariables.h b/Client/core/CClientVariables.h index 1528a57a8b8..767dcecd73d 100644 --- a/Client/core/CClientVariables.h +++ b/Client/core/CClientVariables.h @@ -27,9 +27,13 @@ class CClientVariables : public CCVarsInterface, public CSingleton { - // Sanity macros << Who ever did this is idiot - #define SAN if(!m_pStorage) return - #define SANGET if(!Node(strVariable)) return false +// Sanity macros << Who ever did this is idiot +#define SAN \ + if (!m_pStorage) \ + return +#define SANGET \ + if (!Node(strVariable)) \ + return false public: CClientVariables(); diff --git a/Client/core/CCommandFuncs.cpp b/Client/core/CCommandFuncs.cpp index 22e13e3d88e..b8cd786d3f2 100644 --- a/Client/core/CCommandFuncs.cpp +++ b/Client/core/CCommandFuncs.cpp @@ -318,6 +318,10 @@ void CCommandFuncs::Reconnect(const char* szParameters) // Start the connect if (CCore::GetSingleton().GetConnectManager()->Reconnect(strHost.c_str(), usPort, strPassword.c_str(), false)) { + if (CCore::GetSingleton().GetConnectManager()->WasQuickConnect()) + { + CCore::GetSingleton().GetConnectManager()->SetQuickConnect(false); + } CCore::GetSingleton().GetConsole()->Printf(_("reconnect: Reconnecting to %s:%u..."), strHost.c_str(), usPort); } else @@ -476,7 +480,29 @@ void CCommandFuncs::FakeLag(const char* szCmdLine) if (parts.size() > 3) iKBPSLimit = atoi(parts[3]); - g_pCore->GetNetwork()->SetFakeLag(iPacketLoss, iExtraPing, iExtraPingVary, iKBPSLimit); + if (iPacketLoss < 0 || iPacketLoss > 100) + { + g_pCore->GetConsole()->Print("fakelag: packet loss must be 0-100"); + return; + } + + if (iExtraPing < 0 || iExtraPing > 0xFFFF || iExtraPingVary < 0 || iExtraPingVary > 0xFFFF) + { + g_pCore->GetConsole()->Print("fakelag: ping values must be 0-65535"); + return; + } + + if (iKBPSLimit < 0) + { + g_pCore->GetConsole()->Print("fakelag: KBPS limit must be 0 or higher"); + return; + } + + const unsigned short usPacketLoss = static_cast(iPacketLoss); + const unsigned short usExtraPing = static_cast(iExtraPing); + const unsigned short usExtraPingVary = static_cast(iExtraPingVary); + + g_pCore->GetNetwork()->SetFakeLag(usPacketLoss, usExtraPing, usExtraPingVary, iKBPSLimit); g_pCore->GetConsole()->Print(SString("Client send lag is now: %d%% packet loss and %d extra ping with %d extra ping variance and %d KBPS limit", iPacketLoss, iExtraPing, iExtraPingVary, iKBPSLimit)); } diff --git a/Client/core/CCommandFuncs.h b/Client/core/CCommandFuncs.h index 0e161e10e35..854d2f87ccf 100644 --- a/Client/core/CCommandFuncs.h +++ b/Client/core/CCommandFuncs.h @@ -13,7 +13,7 @@ #include -#define DECLARE_COMMAND_HANDLER(a) static void a ( const char * szParameters ); +#define DECLARE_COMMAND_HANDLER(a) static void a(const char* szParameters); class CCommandFuncs { diff --git a/Client/core/CCommands.cpp b/Client/core/CCommands.cpp index 5936e8ddf0c..af9f09c77c0 100644 --- a/Client/core/CCommands.cpp +++ b/Client/core/CCommands.cpp @@ -85,6 +85,7 @@ bool CCommands::Execute(const char* szCommand, const char* szParametersIn, bool { // Copy szParametersIn so the contents can be changed char* szParameters = NULL; + char empyParameters[1] = {0}; if (szParametersIn) { size_t sizeParameters = strlen(szParametersIn) + 1; @@ -101,7 +102,7 @@ bool CCommands::Execute(const char* szCommand, const char* szParametersIn, bool // His line starts with '/'? if (*szParameters == '/') { - // Copy the characters after the slash to the 0 terminator to a seperate buffer + // Copy the characters after the slash to the 0 terminator to a separate buffer char szBuffer[256]; strncpy(szBuffer, szParameters + 1, 256); szBuffer[255] = 0; @@ -115,7 +116,7 @@ bool CCommands::Execute(const char* szCommand, const char* szParametersIn, bool } if (szParameters == NULL) { - szParameters = ""; + szParameters = empyParameters; } } } @@ -171,10 +172,19 @@ bool CCommands::Execute(const char* szCommand, const char* szParametersIn, bool CVARS_SET(key, val); // HACK: recalculate frame rate limit on cvar change - if (key == "fps_limit" && m_FpsLimitTimer.Get() >= 500 && CCore::GetSingleton().IsConnected()) + if (key == "fps_limit") { - CCore::GetSingleton().RecalculateFrameRateLimit(-1, true); - m_FpsLimitTimer.Reset(); + int fpsVal = 0; + CVARS_GET("fps_limit", fpsVal); + CCore::GetSingleton().GetFPSLimiter()->SetUserDefinedFPS(static_cast(fpsVal)); + } + + // HACK: Foul dirty hack to force vsync (Rework on #4427) + if (key == "vsync") + { + bool vSync; + CVARS_GET("vsync", vSync); + CCore::GetSingleton().GetFPSLimiter()->SetDisplayVSync(vSync); } } else diff --git a/Client/core/CCommands.h b/Client/core/CCommands.h index 6c9f98a92f5..3b3ea8ecf2a 100644 --- a/Client/core/CCommands.h +++ b/Client/core/CCommands.h @@ -44,7 +44,5 @@ class CCommands : public CCommandsInterface, public CSingleton void ExecuteHandler(PFNCOMMAND pfnHandler, const char* szParameters); std::list m_CommandList; - CElapsedTime m_FpsLimitTimer; - pfnExecuteCommandHandler m_pfnExecuteHandler; }; diff --git a/Client/core/CCompressorJobQueue.cpp b/Client/core/CCompressorJobQueue.cpp index 402f04744a1..48434e09109 100644 --- a/Client/core/CCompressorJobQueue.cpp +++ b/Client/core/CCompressorJobQueue.cpp @@ -48,7 +48,7 @@ class CCompressorJobQueueImpl : public CCompressorJobQueue // Main thread variables CThreadHandle* m_pServiceThreadHandle; std::set m_IgnoreResultList; - std::set m_FinishedList; // Result has been used, will be deleted next pulse + std::set m_FinishedList; // Result has been used, will be deleted next pulse // Other thread variables // -none- @@ -317,7 +317,7 @@ bool CCompressorJobQueueImpl::PollCommand(CCompressJobData* pJobData, uint uiTim bool CCompressorJobQueueImpl::FreeCommand(CCompressJobData* pJobData) { if (MapContains(m_IgnoreResultList, pJobData)) - return false; // Already ignoring query handle + return false; // Already ignoring query handle // if in command or result queue, then put in ignore result list bool bFound; @@ -488,10 +488,10 @@ void CCompressorJobQueueImpl::ProcessCommand(CCompressJobData* pJobData) bool CCompressJobData::SetCallback(PFN_SCREENSHOT_CALLBACK pfnScreenShotCallback, uint uiTimeSpentInQueue) { if (callback.bSet) - return false; // One has already been set + return false; // One has already been set if (this->stage > EJobStage::RESULT) - return false; // Too late to set a callback now + return false; // Too late to set a callback now // Set new callback.uiTimeSpentInQueue = uiTimeSpentInQueue; diff --git a/Client/core/CConnectManager.cpp b/Client/core/CConnectManager.cpp index d6a12e110b6..bca7246295b 100644 --- a/Client/core/CConnectManager.cpp +++ b/Client/core/CConnectManager.cpp @@ -83,7 +83,7 @@ bool CConnectManager::Connect(const char* szHost, unsigned short usPort, const c if (!CheckNickProvided((char*)szNick)) { SString strBuffer = _("Connecting failed. Invalid nick provided!"); - CCore::GetSingleton().ShowMessageBox(_("Error") + _E("CC20"), strBuffer, MB_BUTTON_OK | MB_ICON_ERROR); // Invalid nick provided + CCore::GetSingleton().ShowMessageBox(_("Error") + _E("CC20"), strBuffer, MB_BUTTON_OK | MB_ICON_ERROR); // Invalid nick provided return false; } @@ -114,7 +114,7 @@ bool CConnectManager::Connect(const char* szHost, unsigned short usPort, const c if (!CServerListItem::Parse(m_strHost.c_str(), m_Address)) { SString strBuffer = _("Connecting failed. Invalid host provided!"); - CCore::GetSingleton().ShowMessageBox(_("Error") + _E("CC21"), strBuffer, MB_BUTTON_OK | MB_ICON_ERROR); // Invalid host provided + CCore::GetSingleton().ShowMessageBox(_("Error") + _E("CC21"), strBuffer, MB_BUTTON_OK | MB_ICON_ERROR); // Invalid host provided return false; } @@ -130,7 +130,7 @@ bool CConnectManager::Connect(const char* szHost, unsigned short usPort, const c if (m_usPort && !pNet->StartNetwork(strAddress, m_usPort, CVARS_GET_VALUE("packet_tag"))) { SString strBuffer(_("Connecting to %s at port %u failed!"), m_strHost.c_str(), m_usPort); - CCore::GetSingleton().ShowMessageBox(_("Error") + _E("CC22"), strBuffer, MB_BUTTON_OK | MB_ICON_ERROR); // Failed to connect + CCore::GetSingleton().ShowMessageBox(_("Error") + _E("CC22"), strBuffer, MB_BUTTON_OK | MB_ICON_ERROR); // Failed to connect return false; } @@ -165,7 +165,9 @@ bool CConnectManager::Reconnect(const char* szHost, unsigned short usPort, const unsigned int uiPort = 0; CVARS_GET("host", m_strHost); CVARS_GET("port", uiPort); - m_usPort = uiPort; + if (uiPort == 0 || uiPort > 0xFFFF) + uiPort = 22003; + m_usPort = static_cast(uiPort); // If keeping the same host & port, retrieve the password as well if (!szHost || !szHost[0] || m_strHost == szHost) @@ -283,11 +285,11 @@ void CConnectManager::DoPulse() { case RID_RSA_PUBLIC_KEY_MISMATCH: strError = _("Disconnected: unknown protocol error"); - strErrorCode = _E("CC24"); // encryption key mismatch + strErrorCode = _E("CC24"); // encryption key mismatch break; case RID_INCOMPATIBLE_PROTOCOL_VERSION: strError = _("Disconnected: unknown protocol error"); - strErrorCode = _E("CC34"); // old raknet version + strErrorCode = _E("CC34"); // old raknet version break; case RID_REMOTE_DISCONNECTION_NOTIFICATION: strError = _("Disconnected: disconnected remotely"); @@ -328,7 +330,7 @@ void CConnectManager::DoPulse() { CCore::GetSingleton().ShowNetErrorMessageBox(_("Error") + strErrorCode, strError); } - else // Otherwise, remove the message box and hide quick connect + else // Otherwise, remove the message box and hide quick connect { CCore::GetSingleton().RemoveMessageBox(false); } @@ -412,7 +414,7 @@ bool CConnectManager::StaticProcessPacket(unsigned char ucPacketID, NetBitStream { // Failed loading the mod strArguments.Format(_("No such mod installed (%s)"), strModName.c_str()); - CCore::GetSingleton().ShowMessageBox(_("Error") + _E("CC31"), strArguments, MB_BUTTON_OK | MB_ICON_ERROR); // Mod loading failed + CCore::GetSingleton().ShowMessageBox(_("Error") + _E("CC31"), strArguments, MB_BUTTON_OK | MB_ICON_ERROR); // Mod loading failed g_pConnectManager->Abort(); } } diff --git a/Client/core/CConnectManager.h b/Client/core/CConnectManager.h index 63f4de39654..e80eb964887 100644 --- a/Client/core/CConnectManager.h +++ b/Client/core/CConnectManager.h @@ -26,10 +26,14 @@ class CConnectManager bool Abort(); + bool WasQuickConnect() const noexcept { return m_quickConnect; } + void DoPulse(); void OnServerExists(); + void SetQuickConnect(bool quick) noexcept { m_quickConnect = quick; } + static void OpenServerFirewall(in_addr Address, ushort usHttpPort = 80, bool bHighPriority = false); static bool StaticProcessPacket(unsigned char ucPacketID, class NetBitStreamInterface& bitStream); @@ -59,4 +63,5 @@ class CConnectManager bool m_bNotifyServerBrowser; bool CheckNickProvided(const char* szNick); + bool m_quickConnect{false}; }; diff --git a/Client/core/CConsole.cpp b/Client/core/CConsole.cpp index 340187f1d84..be40befa214 100644 --- a/Client/core/CConsole.cpp +++ b/Client/core/CConsole.cpp @@ -15,7 +15,7 @@ using SharedUtil::CalcMTASAPath; using std::string; #define CONSOLE_INPUT_HISTORY_LENGTH 128 -#define CONSOLE_SIZE 4096 +#define CONSOLE_SIZE 4096 #define MAX_CONSOLE_COMMAND_LENGTH 255 @@ -368,13 +368,13 @@ void CConsole::SetNextAutoCompleteMatch() while (CEntryHistoryItem* pEntryHistoryItem = m_pConsoleHistory->Get(++iIndex)) { const char* szItem = *pEntryHistoryItem; - if (strlen(szItem) < 3) // Skip very short lines + if (strlen(szItem) < 3) // Skip very short lines continue; // Save the index of any matches if (strnicmp(szItem, strInput.c_str(), strInput.length()) == 0) { - if (m_AutoCompleteList.size()) // Dont add duplicates of the previously added line + if (m_AutoCompleteList.size()) // Dont add duplicates of the previously added line { CEntryHistoryItem* pPrevEntryHistoryItem = m_pConsoleHistory->Get(m_AutoCompleteList.at(m_AutoCompleteList.size() - 1)); if (!pPrevEntryHistoryItem) @@ -556,7 +556,7 @@ void CConsole::FlushPendingAdd() uiSelectionStart = 0; uiSelectionEnd -= uiBufferLengthDiff; } - else // Both start and end of selection are greater than length difference + else // Both start and end of selection are greater than length difference { // Whole selection would still be visible on the screen, // just a simple movement is needed diff --git a/Client/core/CCore.cpp b/Client/core/CCore.cpp index 152320a6b8a..6876424fb0b 100644 --- a/Client/core/CCore.cpp +++ b/Client/core/CCore.cpp @@ -15,7 +15,10 @@ #include #include #include -#include "Userenv.h" // This will enable SharedUtil::ExpandEnvString +#include +#include +#include +#include "Userenv.h" // This will enable SharedUtil::ExpandEnvString #define ALLOC_STATS_MODULE_NAME "core" #include "SharedUtil.hpp" #include @@ -27,12 +30,31 @@ #include #include "CDiscordRichPresence.h" #include "CSteamClient.h" +#include "CCrashDumpWriter.h" +#include "FastFailCrashHandler/WerCrashHandler.h" using SharedUtil::CalcMTASAPath; using namespace std; namespace fs = std::filesystem; +// Set to true to enable the freeze watchdog (monitors main thread responsiveness) +// Do NOT enable it unless you run a QA testing cycle (see commit desc: 3e54dcb2742bccf0319b9552b2ed5a2c0a012425) +constexpr bool bFreezeWatchdogEnabled = false; + +// Watchdog active in debug builds +// In debug builds, the contributor should get an early heads up if their changes are this level of blocking (it can't make it in). +// If you freeze beyond 20 secs in a debug build, not due to a bug in your code changes but due to your local server assets, you have 2 options: +// 1. Disable the watchdog +// 2. Fix your mess (imagine what that would do to players in release builds) +#ifdef MTA_DEBUG +constexpr bool bFreezeWatchdogEnabledInCurrentBuild = true; +constexpr DWORD uiFreezeWatchdogTimeoutSeconds = 20; // Already unacceptable. Strikes a balance: you'll still be able to a load heavy asseted local server +#else +constexpr bool bFreezeWatchdogEnabledInCurrentBuild = bFreezeWatchdogEnabled; +constexpr DWORD uiFreezeWatchdogTimeoutSeconds = 40; // Player won't be patient beyond this; we get no info +#endif + static float fTest = 1; extern CCore* g_pCore; @@ -44,7 +66,7 @@ extern fs::path g_gtaDirectory; template <> CCore* CSingleton::m_pSingleton = NULL; -static auto Win32LoadLibraryA = static_cast(nullptr); +static auto Win32LoadLibraryA = LoadLibraryA; static constexpr long long TIME_DISCORD_UPDATE_RICH_PRESENCE_RATE = 10000; static HMODULE WINAPI SkipDirectPlay_LoadLibraryA(LPCSTR fileName) @@ -56,18 +78,18 @@ static HMODULE WINAPI SkipDirectPlay_LoadLibraryA(LPCSTR fileName) if (!StrCmpIA("enbseries\\enbhelper.dll", fileName)) { std::error_code ec; - + // Try to load enbhelper.dll from our custom launch directory first. const fs::path inLaunchDir = fs::path{FromUTF8(GetLaunchPath())} / "enbseries" / "enbhelper.dll"; if (fs::is_regular_file(inLaunchDir, ec)) - return Win32LoadLibraryA(inLaunchDir.u8string().c_str()); + return Win32LoadLibraryA(UTF8FilePath(inLaunchDir).c_str()); // Try to load enbhelper.dll from the GTA install directory second. const fs::path inGTADir = g_gtaDirectory / "enbseries" / "enbhelper.dll"; if (fs::is_regular_file(inGTADir, ec)) - return Win32LoadLibraryA(inGTADir.u8string().c_str()); + return Win32LoadLibraryA(UTF8FilePath(inGTADir).c_str()); return nullptr; } @@ -123,6 +145,7 @@ CCore::CCore() m_bDestroyMessageBox = false; m_bCursorToggleControls = false; m_bLastFocused = true; + m_uiNextRenderTargetRetryTime = 0; m_DiagnosticDebug = EDiagnosticDebug::NONE; // Create our Direct3DData handler. @@ -130,6 +153,9 @@ CCore::CCore() WriteDebugEvent("CCore::CCore"); + // Store initial module bases (will be updated more comprehensively later) + WerCrash::UpdateModuleBases(); + m_pKeyBinds = new CKeyBinds(this); m_pMouseControl = new CMouseControl(); @@ -146,10 +172,11 @@ CCore::CCore() // Setup our hooks. ApplyHooks(); - // No initial fps limit - m_bDoneFrameRateLimit = false; - m_uiFrameRateLimit = 0; - m_uiServerFrameRateLimit = 0; + m_pModelCacheManager = nullptr; + m_iDummyProgressValue = 0; + m_DummyProgressTimerHandle = NULL; + m_bDummyProgressUpdateAlways = false; + m_iUnminimizeFrameCounter = 0; m_bDidRecreateRenderTargets = false; m_fMinStreamingMemory = 0; @@ -157,7 +184,9 @@ CCore::CCore() m_bGettingIdleCallsFromMultiplayer = false; m_bWindowsTimerEnabled = false; m_timeDiscordAppLastUpdate = 0; - m_CurrentRefreshRate = 60; + + // Initialize FPS limiter + m_pFPSLimiter = std::make_unique(); // Create tray icon m_pTrayIcon = new CTrayIcon(); @@ -171,6 +200,9 @@ CCore::~CCore() { WriteDebugEvent("CCore::~CCore"); + if constexpr (bFreezeWatchdogEnabledInCurrentBuild) + StopWatchdogThread(); + // Reset Discord rich presence if (m_pDiscordRichPresence) m_pDiscordRichPresence.reset(); @@ -180,6 +212,8 @@ CCore::~CCore() // Destroy tray icon delete m_pTrayIcon; + m_pFPSLimiter.reset(); + // This will set the GTA volume to the GTA volume value in the settings, // and is not affected by the master volume setting. m_pLocalGUI->GetMainMenu()->GetSettingsWindow()->ResetGTAVolume(); @@ -187,10 +221,27 @@ CCore::~CCore() // Remove input hook CMessageLoopHook::GetSingleton().RemoveHook(); + if (m_bWindowsTimerEnabled) + { + KillTimer(GetHookedWindow(), IDT_TIMER1); + m_bWindowsTimerEnabled = false; + } + + extern int ms_iDummyProgressTimerCounter; + + if (m_DummyProgressTimerHandle != NULL) + { + DeleteTimerQueueTimer(NULL, m_DummyProgressTimerHandle, INVALID_HANDLE_VALUE); + m_DummyProgressTimerHandle = NULL; + ms_iDummyProgressTimerCounter = 0; + } + // Delete the mod manager delete m_pModManager; SAFE_DELETE(m_pMessageBox); + SAFE_DELETE(m_pModelCacheManager); + // Destroy early subsystems m_bModulesLoaded = false; DestroyNetwork(); @@ -225,6 +276,8 @@ CCore::~CCore() DestroyGUI(); DestroyXML(); + SAFE_DELETE(g_pLocalization); + // Delete keybinds delete m_pKeyBinds; @@ -655,6 +708,7 @@ void CCore::ApplyGameSettings() CVARS_GET("dynamic_ped_shadows", bVal); pGameSettings->SetDynamicPedShadowsEnabled(bVal); pController->SetVerticalAimSensitivityRawValue(CVARS_GET_VALUE("vertical_aim_sensitivity")); + pController->SetVerticalAimSensitivitySameAsHorizontal(CVARS_GET_VALUE("use_mouse_sensitivity_for_aiming")); CVARS_GET("mastervolume", fVal); pGameSettings->SetRadioVolume(pGameSettings->GetRadioVolume() * fVal); pGameSettings->SetSFXVolume(pGameSettings->GetSFXVolume() * fVal); @@ -663,7 +717,7 @@ void CCore::ApplyGameSettings() void CCore::SetConnected(bool bConnected) { m_pLocalGUI->GetMainMenu()->SetIsIngame(bConnected); - UpdateIsWindowMinimized(); // Force update of stuff + UpdateIsWindowMinimized(); // Force update of stuff if (g_pCore->GetCVars()->GetValue("allow_discord_rpc", false)) { @@ -777,7 +831,7 @@ void CCore::ShowNetErrorMessageBox(const SString& strTitle, SString strMessage, strTroubleLink += SString("&neterrorcode=%08X", uiErrorCode); } else if (bLinkRequiresErrorCode) - strTroubleLink = ""; // No link if no error code + strTroubleLink = ""; // No link if no error code AddReportLog(7100, SString("Core - NetError (%s) (%s)", *strTitle, *strMessage)); ShowErrorMessageBox(strTitle, strMessage, strTroubleLink); @@ -913,7 +967,7 @@ void LoadModule(CModuleLoader& m_Loader, const SString& strName, const SString& // Save current directory (shouldn't change anyway) SString strSavedCwd = GetSystemCurrentDirectory(); - // Load approrpiate compilation-specific library. + // Load appropriate compilation-specific library. #ifdef MTA_DEBUG SString strModuleFileName = strModuleName + "_d.dll"; #else @@ -1016,6 +1070,19 @@ void CCore::DeinitGUI() void CCore::InitGUI(IDirect3DDevice9* pDevice) { m_pGUI = InitModule(m_GUIModule, "GUI", "InitGUIInterface", pDevice); + + // Apply CPU affinity here (GTA allocates threads on startup, so we have to do it here instead of earlier) + bool affinity = CVARS_GET_VALUE("process_cpu_affinity"); + if (!affinity) + return; + + DWORD_PTR mask; + DWORD_PTR sys; + HANDLE process = GetCurrentProcess(); + BOOL result = GetProcessAffinityMask(process, &mask, &sys); + + if (result) + SetProcessAffinityMask(process, mask & ~1); } void CCore::CreateGUI() @@ -1072,6 +1139,16 @@ void CCore::CreateXML() if (!m_pConfigFile) { assert(false); + + if (m_pXML) + { + using PFNReleaseXMLInterface = void (*)(); + if (auto pfnRelease = reinterpret_cast(m_XMLModule.GetFunctionPointer("ReleaseXMLInterface"))) + pfnRelease(); + } + + m_pXML = NULL; + m_XMLModule.UnloadModule(); return; } @@ -1123,10 +1200,14 @@ void CCore::DestroyXML() { SaveConfig(true); delete m_pConfigFile; + m_pConfigFile = nullptr; } if (m_pXML) { + using PFNReleaseXMLInterface = void (*)(); + if (auto pfnRelease = reinterpret_cast(m_XMLModule.GetFunctionPointer("ReleaseXMLInterface"))) + pfnRelease(); m_pXML = NULL; } @@ -1156,8 +1237,48 @@ CWebCoreInterface* CCore::GetWebCore() cvars->Get("browser_enable_gpu", gpuEnabled); m_pWebCore = CreateModule(m_WebCoreModule, "CefWeb", "cefweb", "InitWebCoreInterface", this); - m_pWebCore->Initialise(gpuEnabled); + if (!m_pWebCore) + { + WriteDebugEvent("CCore::GetWebCore - CreateModule failed"); + return nullptr; + } + + // Log current working directory + wchar_t cwdBeforeWebInit[32768]{}; + DWORD cwdBeforeWebInitLen = GetCurrentDirectoryW(32768, cwdBeforeWebInit); + if (cwdBeforeWebInitLen > 0) + { + WriteDebugEvent(SString("CCore::GetWebCore - CWD before Initialise: %S", cwdBeforeWebInit)); + } + + // Keep m_pWebCore alive even if Initialise() fails + // CefInitialize() can only be called once per process + // Deleting and recreating m_pWebCore causes repeated initialization attempts + // Track initialization state via IsInitialised() instead + bool bInitSuccess = false; + try + { + bInitSuccess = m_pWebCore->Initialise(gpuEnabled); + } + catch (...) + { + WriteDebugEvent("CCore::GetWebCore - Initialise threw exception"); + bInitSuccess = false; + } + + if (!bInitSuccess) + { + WriteDebugEvent("CCore::GetWebCore - Initialise failed"); + return nullptr; + } } + else + { + // On subsequent calls, check if initialization succeeded + if (!m_pWebCore->IsInitialised()) + return nullptr; + } + return m_pWebCore; } @@ -1196,6 +1317,9 @@ void CCore::DoPreFramePulse() { TIMING_CHECKPOINT("+CorePreFrame"); + if constexpr (bFreezeWatchdogEnabledInCurrentBuild) + UpdateWatchdogHeartbeat(); + m_pKeyBinds->DoPreFramePulse(); // Notify the mod manager @@ -1249,14 +1373,28 @@ void CCore::DoPostFramePulse() if (m_menuFrame == 1) { - WatchDogCompletedSection("L2"); // gta_sa.set seems ok - WatchDogCompletedSection("L3"); // No hang on startup - HandleCrashDumpEncryption(); + WatchDogCompletedSection("L2"); // gta_sa.set seems ok + WatchDogCompletedSection("L3"); // No hang on startup + + // Start watchdog thread now that initial loading is complete + if constexpr (bFreezeWatchdogEnabledInCurrentBuild) + { + if (!StartWatchdogThread(GetCurrentThreadId(), uiFreezeWatchdogTimeoutSeconds)) + { + WriteDebugEvent("CCore: WARNING - Failed to start watchdog thread"); + } + } // Disable vsync while it's all dark m_pGame->DisableVSync(); } + if (!m_bCrashDumpEncryptionDone && m_menuFrame >= 5 && m_pNet && m_pNet->IsReady()) + { + m_bCrashDumpEncryptionDone = true; + HandleCrashDumpEncryption(); + } + if (m_menuFrame >= 5 && !m_isNetworkReady && m_pNet->IsReady()) { m_isNetworkReady = true; @@ -1303,7 +1441,7 @@ void CCore::DoPostFramePulse() m_bLastFocused = true; } - GetJoystickManager()->DoPulse(); // Note: This may indirectly call CMessageLoopHook::ProcessMessage + GetJoystickManager()->DoPulse(); // Note: This may indirectly call CMessageLoopHook::ProcessMessage m_pKeyBinds->DoPostFramePulse(); if (m_pWebCore) @@ -1347,7 +1485,7 @@ void CCore::OnModUnload() m_pKeyBinds->RemoveAllControlFunctions(); // Reset client script frame rate limit - m_uiClientScriptFrameRateLimit = 0; + GetFPSLimiter()->SetClientEnforcedFPS(FPSLimits::FPS_UNLIMITED); // Clear web whitelist if (m_pWebCore) @@ -1461,7 +1599,7 @@ void CCore::Quit(bool bInstantly) // Show that we are quiting (for the crash dump filename) SetApplicationSettingInt("last-server-ip", 1); - WatchDogBeginSection("Q0"); // Allow loader to detect freeze on exit + WatchDogBeginSection("Q0"); // Allow loader to detect freeze on exit // Hide game window to make quit look instant PostQuitMessage(0); @@ -1470,13 +1608,13 @@ void CCore::Quit(bool bInstantly) // Destroy the client CModManager::GetSingleton().Unload(); - // Destroy ourself - delete CCore::GetSingletonPtr(); - WatchDogCompletedSection("Q0"); - // Use TerminateProcess for now as exiting the normal way crashes + // Use TerminateProcess before destroying CCore to ensure clean exit code (Exiting the normal way also crashes). TerminateProcess(GetCurrentProcess(), 0); + + // Destroy ourself (unreachable but kept for completeness) + delete CCore::GetSingletonPtr(); } else { @@ -1751,18 +1889,23 @@ void CCore::UpdateRecentlyPlayed() std::string strHost; CVARS_GET("host", strHost); CVARS_GET("port", uiPort); + + if (uiPort == 0 || uiPort > 0xFFFF) + return; + + const ushort usPort = static_cast(uiPort); // Save the connection details into the recently played servers list in_addr Address; if (CServerListItem::Parse(strHost.c_str(), Address)) { CServerBrowser* pServerBrowser = CCore::GetSingleton().GetLocalGUI()->GetMainMenu()->GetServerBrowser(); CServerList* pRecentList = pServerBrowser->GetRecentList(); - pRecentList->Remove(Address, uiPort); - pRecentList->AddUnique(Address, uiPort, true); + pRecentList->Remove(Address, usPort); + pRecentList->AddUnique(Address, usPort, true); pServerBrowser->SaveRecentlyPlayedList(); if (!m_pConnectManager->m_strLastPassword.empty()) - pServerBrowser->SetServerPassword(strHost + ":" + SString("%u", uiPort), m_pConnectManager->m_strLastPassword); + pServerBrowser->SetServerPassword(strHost + ":" + SString("%u", usPort), m_pConnectManager->m_strLastPassword); } // Save our configuration file CCore::GetSingleton().SaveConfig(); @@ -1772,8 +1915,8 @@ void CCore::OnPostColorFilterRender() { if (!CGraphics::GetSingleton().HasLine3DPostFXQueueItems() && !CGraphics::GetSingleton().HasPrimitive3DPostFXQueueItems()) return; - - CGraphics::GetSingleton().EnteringMTARenderZone(); + + CGraphics::GetSingleton().EnteringMTARenderZone(); CGraphics::GetSingleton().DrawPrimitive3DPostFXQueue(); CGraphics::GetSingleton().DrawLine3DPostFXQueue(); @@ -1807,23 +1950,11 @@ void CCore::ApplyCoreInitSettings() SetApplicationSettingInt("reset-settings-revision", 21486); } - HANDLE process = GetCurrentProcess(); + HANDLE process = GetCurrentProcess(); const int priorities[] = {NORMAL_PRIORITY_CLASS, ABOVE_NORMAL_PRIORITY_CLASS, HIGH_PRIORITY_CLASS}; - int priority = CVARS_GET_VALUE("process_priority") % 3; + int priority = CVARS_GET_VALUE("process_priority") % 3; SetPriorityClass(process, priorities[priority]); - - bool affinity = CVARS_GET_VALUE("process_cpu_affinity"); - - if (!affinity) - return; - - DWORD_PTR mask; - DWORD_PTR sys; - BOOL result = GetProcessAffinityMask(process, &mask, &sys); - - if (result) - SetProcessAffinityMask(process, mask & ~1); } // @@ -1831,141 +1962,14 @@ void CCore::ApplyCoreInitSettings() // void CCore::OnGameTimerUpdate() { - ApplyQueuedFrameRateLimit(); + // NOTE: (pxd) We are handling the frame limiting updates + // earlier in the callpath (CModManager::DoPulsePreFrame, CModManager::DoPulsePostFrame) } -// -// Recalculate FPS limit to use -// -// Uses client rate from config -// Uses client rate from script -// Uses server rate from argument, or last time if not supplied -// -void CCore::RecalculateFrameRateLimit(uint uiServerFrameRateLimit, bool bLogToConsole) -{ - // Save rate from server if valid - if (uiServerFrameRateLimit != -1) - m_uiServerFrameRateLimit = uiServerFrameRateLimit; - - // Start with value set by the server - m_uiFrameRateLimit = m_uiServerFrameRateLimit; - - // Apply client config setting - uint uiClientConfigRate; - g_pCore->GetCVars()->Get("fps_limit", uiClientConfigRate); - if (uiClientConfigRate > 0) - uiClientConfigRate = std::max(45U, uiClientConfigRate); - // Lowest wins (Although zero is highest) - if ((m_uiFrameRateLimit == 0 || uiClientConfigRate < m_uiFrameRateLimit) && uiClientConfigRate > 0) - m_uiFrameRateLimit = uiClientConfigRate; - - // Apply client script setting - uint uiClientScriptRate = m_uiClientScriptFrameRateLimit; - // Lowest wins (Although zero is highest) - if ((m_uiFrameRateLimit == 0 || uiClientScriptRate < m_uiFrameRateLimit) && uiClientScriptRate > 0) - m_uiFrameRateLimit = uiClientScriptRate; - - if (!IsConnected()) - m_uiFrameRateLimit = m_CurrentRefreshRate; - - // Removes Limiter from Frame Graph if limit is zero and skips frame limit - if (m_uiFrameRateLimit == 0) - { - m_bQueuedFrameRateValid = false; - GetGraphStats()->RemoveTimingPoint("Limiter"); - } - - // Print new limits to the console - if (bLogToConsole) - { - SString strStatus("Server FPS limit: %d", m_uiServerFrameRateLimit); - if (m_uiFrameRateLimit != m_uiServerFrameRateLimit) - strStatus += SString(" (Using %d)", m_uiFrameRateLimit); - CCore::GetSingleton().GetConsole()->Print(strStatus); - } -} - -// -// Change client rate as set by script -// -void CCore::SetClientScriptFrameRateLimit(uint uiClientScriptFrameRateLimit) -{ - m_uiClientScriptFrameRateLimit = uiClientScriptFrameRateLimit; - RecalculateFrameRateLimit(-1, false); -} - -void CCore::SetCurrentRefreshRate(uint value) -{ - m_CurrentRefreshRate = value; - RecalculateFrameRateLimit(-1, false); -} - -// -// Make sure the frame rate limit has been applied since the last call -// -void CCore::EnsureFrameRateLimitApplied() +void CCore::OnFPSLimitChange(std::uint16_t fps) { - if (!m_bDoneFrameRateLimit) - { - ApplyFrameRateLimit(); - } - m_bDoneFrameRateLimit = false; -} - -// -// Do FPS limiting -// -// This is called once a frame even if minimized -// -void CCore::ApplyFrameRateLimit(uint uiOverrideRate) -{ - TIMING_CHECKPOINT("-CallIdle1"); - ms_TimingCheckpoints.EndTimingCheckpoints(); - - // Frame rate limit stuff starts here - m_bDoneFrameRateLimit = true; - - uint uiUseRate = uiOverrideRate != -1 ? uiOverrideRate : m_uiFrameRateLimit; - - if (uiUseRate > 0) - { - // Apply previous frame rate if is hasn't been done yet - ApplyQueuedFrameRateLimit(); - - // Limit is usually applied in OnGameTimerUpdate - m_uiQueuedFrameRate = uiUseRate; - m_bQueuedFrameRateValid = true; - } - - DoReliablePulse(); - - TIMING_GRAPH("FrameEnd"); - TIMING_GRAPH(""); -} - -// -// Frame rate limit (wait) is done here. -// -void CCore::ApplyQueuedFrameRateLimit() -{ - if (m_bQueuedFrameRateValid) - { - m_bQueuedFrameRateValid = false; - // Calc required time in ms between frames - const double dTargetTimeToUse = 1000.0 / m_uiQueuedFrameRate; - - while (true) - { - // See if we need to wait - double dSpare = dTargetTimeToUse - m_FrameRateTimer.Get(); - if (dSpare <= 0.0) - break; - if (dSpare >= 10.0) - Sleep(1); - } - m_FrameRateTimer.Reset(); - TIMING_GRAPH("Limiter"); - } + if (m_pNet != nullptr && IsWebCoreLoaded()) // We have to wait for the network module to be loaded + GetWebCore()->OnFPSLimitChange(fps); } // @@ -1982,7 +1986,7 @@ void CCore::DoReliablePulse() // Non frame rate limit stuff if (IsWindowMinimized()) - m_iUnminimizeFrameCounter = 4; // Tell script we have unminimized after a short delay + m_iUnminimizeFrameCounter = 4; // Tell script we have unminimized after a short delay UpdateModuleTickCount64(); } @@ -2010,8 +2014,9 @@ void CCore::OnTimingDetail(const char* szTag) // void CCore::OnDeviceRestore() { - m_iUnminimizeFrameCounter = 4; // Tell script we have restored after 4 frames to avoid double sends + m_iUnminimizeFrameCounter = 4; // Tell script we have restored after 4 frames to avoid double sends m_bDidRecreateRenderTargets = true; + m_uiNextRenderTargetRetryTime = 0; } // @@ -2020,7 +2025,7 @@ void CCore::OnDeviceRestore() void CCore::OnPreFxRender() { if (!CGraphics::GetSingleton().HasLine3DPreGUIQueueItems() && !CGraphics::GetSingleton().HasPrimitive3DPreGUIQueueItems()) - return; + return; CGraphics::GetSingleton().EnteringMTARenderZone(); @@ -2035,7 +2040,14 @@ void CCore::OnPreFxRender() // void CCore::OnPreHUDRender() { - CGraphics::GetSingleton().EnteringMTARenderZone(); + const uint uiNow = GetTickCount32(); + if (uiNow >= m_uiNextRenderTargetRetryTime) + { + CGraphics::GetSingleton().RetryInvalidRenderTargets(); + m_uiNextRenderTargetRetryTime = uiNow + 250; + } + + CGraphics::GetSingleton().EnteringMTARenderZone(); // Maybe capture screen and other stuff CGraphics::GetSingleton().GetRenderItemManager()->DoPulse(); @@ -2152,6 +2164,11 @@ void CCore::OnEnterCrashZone(uint uiId) CCrashDumpWriter::OnEnterCrashZone(uiId); } +void CCore::UpdateWerCrashModuleBases() +{ + WerCrash::UpdateModuleBases(); +} + // // LogEvent // @@ -2227,6 +2244,52 @@ void CCore::HandleIdlePulse() m_pModManager->GetClient()->IdleHandler(); } +namespace +{ + bool IsCoreDump(const SString& filePath) + { + constexpr std::array markers = { + 0x734C4F50, // 'POLs' + 0x73443344, // 'D3Ds' + 0x73474F4C, // 'LOGs' + 0x73524557 // 'WERs' - WER fail-fast crash info + }; + + constexpr std::size_t tailSize = 64 * 1024; + constexpr std::size_t minFileSize = 1024; + + std::ifstream file(FromUTF8(filePath), std::ios::binary | std::ios::ate); + if (!file) + return false; + + const auto fileSize = file.tellg(); + if (fileSize < static_cast(minFileSize)) + return false; + + const auto readSize = std::min(static_cast(fileSize), tailSize); + const auto readStart = static_cast(fileSize) - static_cast(readSize); + + file.seekg(readStart); + std::vector buffer(readSize); + file.read(buffer.data(), static_cast(readSize)); + + const auto bytesRead = static_cast(file.gcount()); + if (bytesRead < sizeof(std::uint32_t)) + return false; + + for (std::size_t i = 0; i + sizeof(std::uint32_t) <= bytesRead; ++i) + { + std::uint32_t value; + std::memcpy(&value, buffer.data() + i, sizeof(std::uint32_t)); + + if (std::find(markers.begin(), markers.end(), value) != markers.end()) + return true; + } + + return false; + } +} + // // Handle encryption of Windows crash dump files // @@ -2260,7 +2323,13 @@ void CCore::HandleCrashDumpEncryption() SString strPublicPathFilename = PathJoin(strDumpDirPublicPath, strPublicFilename); if (!FileExists(strPublicPathFilename)) { - GetNetwork()->EncryptDumpfile(strPrivatePathFilename, strPublicPathFilename); + if (!IsCoreDump(strPrivatePathFilename)) + continue; + + if (CNet* pNet = GetNetwork(); pNet && pNet->IsReady()) + { + pNet->EncryptDumpfile(strPrivatePathFilename, strPublicPathFilename); + } } } } @@ -2396,7 +2465,8 @@ SString CCore::GetBlueCopyrightString() // Set streaming memory size override [See `engineStreamingSetMemorySize`] // Use `0` to turn it off, and thus restore the value to the `cvar` setting -void CCore::SetCustomStreamingMemory(size_t sizeBytes) { +void CCore::SetCustomStreamingMemory(size_t sizeBytes) +{ // NOTE: The override is applied to the game in `CClientGame::DoPulsePostFrame` // There's no specific reason we couldn't do it here, but we wont m_CustomStreamingMemoryLimitBytes = sizeBytes; @@ -2410,9 +2480,8 @@ bool CCore::IsUsingCustomStreamingMemorySize() // Streaming memory size used [In Bytes] size_t CCore::GetStreamingMemory() { - return IsUsingCustomStreamingMemorySize() - ? m_CustomStreamingMemoryLimitBytes - : CVARS_GET_VALUE("streaming_memory") * 1024 * 1024; // MB to B conversion + return IsUsingCustomStreamingMemorySize() ? m_CustomStreamingMemoryLimitBytes + : CVARS_GET_VALUE("streaming_memory") * 1024 * 1024; // MB to B conversion } // Discord rich presence diff --git a/Client/core/CCore.h b/Client/core/CCore.h index d7f7762b2ce..14a1bf3d092 100644 --- a/Client/core/CCore.h +++ b/Client/core/CCore.h @@ -41,6 +41,7 @@ class CDiscordInterface; #include #include #include "CTrayIcon.h" +#include "FPSLimiter.h" #define DIRECTINPUT_VERSION 0x0800 #include @@ -54,15 +55,15 @@ class CDiscordInterface; #define MTA_CONSOLE_LOG_PATH "mta/logs/console.log" #define MTA_CONSOLE_INPUT_LOG_PATH "mta/logs/console-input.log" #define CONFIG_ROOT "mainconfig" -#define CONFIG_NODE_CVARS "settings" // cvars node -#define CONFIG_NODE_KEYBINDS "binds" // keybinds node +#define CONFIG_NODE_CVARS "settings" // cvars node +#define CONFIG_NODE_KEYBINDS "binds" // keybinds node #define CONFIG_NODE_JOYPAD "joypad" #define CONFIG_NODE_UPDATER "updater" -#define CONFIG_NODE_SERVER_INT "internet_servers" // backup of last successful master server list query -#define CONFIG_NODE_SERVER_FAV "favourite_servers" // favourite servers list node -#define CONFIG_NODE_SERVER_REC "recently_played_servers" // recently played servers list node -#define CONFIG_NODE_SERVER_OPTIONS "serverbrowser_options" // saved options for the server browser -#define CONFIG_NODE_SERVER_SAVED "server_passwords" // This contains saved passwords (as appose to save_server_passwords which is a setting) +#define CONFIG_NODE_SERVER_INT "internet_servers" // backup of last successful master server list query +#define CONFIG_NODE_SERVER_FAV "favourite_servers" // favourite servers list node +#define CONFIG_NODE_SERVER_REC "recently_played_servers" // recently played servers list node +#define CONFIG_NODE_SERVER_OPTIONS "serverbrowser_options" // saved options for the server browser +#define CONFIG_NODE_SERVER_SAVED "server_passwords" // This contains saved passwords (as appose to save_server_passwords which is a setting) #define CONFIG_NODE_SERVER_HISTORY "connect_history" #define CONFIG_INTERNET_LIST_TAG "internet_server" #define CONFIG_FAVOURITE_LIST_TAG "favourite_server" @@ -104,9 +105,11 @@ class CCore : public CCoreInterface, public CSingleton CLocalGUI* GetLocalGUI(); CLocalizationInterface* GetLocalization() { return g_pLocalization; }; CWebCoreInterface* GetWebCore(); + CWebCoreInterface* GetWebCoreUnchecked() { return m_pWebCore; } // For cleanup in destructors only - bypasses initialization check CTrayIconInterface* GetTrayIcon() { return m_pTrayIcon; }; std::shared_ptr GetDiscord(); CSteamClient* GetSteamClient() { return m_steamClient.get(); } + FPSLimiter::FPSLimiterInterface* GetFPSLimiter() const noexcept { return m_pFPSLimiter.get(); } void SaveConfig(bool bWaitUntilFinished = false); @@ -187,7 +190,7 @@ class CCore : public CCoreInterface, public CSingleton void DestroyGUI(); // Web - bool IsWebCoreLoaded() { return m_pWebCore != nullptr; } + bool IsWebCoreLoaded() { return m_pWebCore != nullptr && m_pWebCore->IsInitialised(); } void DestroyWeb(); // Hooks @@ -214,19 +217,15 @@ class CCore : public CCoreInterface, public CSingleton // Misc void RegisterCommands(); - bool IsValidNick(const char* szNick); // Move somewhere else + bool IsValidNick(const char* szNick); // Move somewhere else void Quit(bool bInstantly = true); void InitiateUpdate(const char* szType, const char* szData, const char* szHost) { m_pLocalGUI->InitiateUpdate(szType, szData, szHost); } bool IsOptionalUpdateInfoRequired(const char* szHost) { return m_pLocalGUI->IsOptionalUpdateInfoRequired(szHost); } void InitiateDataFilesFix() { m_pLocalGUI->InitiateDataFilesFix(); } - uint GetFrameRateLimit() { return m_uiFrameRateLimit; } - void RecalculateFrameRateLimit(uint uiServerFrameRateLimit = -1, bool bLogToConsole = true); - void ApplyFrameRateLimit(uint uiOverrideRate = -1); - void ApplyQueuedFrameRateLimit(); - void EnsureFrameRateLimitApplied(); - void SetClientScriptFrameRateLimit(uint uiClientScriptFrameRateLimit); - void SetCurrentRefreshRate(uint value); + // FPS Limiter + void OnFPSLimitChange(std::uint16_t fps); + void DoReliablePulse(); bool IsTimingCheckpoints(); @@ -252,6 +251,7 @@ class CCore : public CCoreInterface, public CSingleton void OnDeviceRestore(); void OnCrashAverted(uint uiId); void OnEnterCrashZone(uint uiId); + void UpdateWerCrashModuleBases(); void LogEvent(uint uiDebugId, const char* szType, const char* szContext, const char* szBody, uint uiAddReportLogId = 0); bool GetDebugIdEnabled(uint uiDebugId); EDiagnosticDebugType GetDiagnosticDebug(); @@ -294,6 +294,9 @@ class CCore : public CCoreInterface, public CSingleton const SString& GetLastConnectedServerName() const { return m_strLastConnectedServerName; } void SetLastConnectedServerName(const SString& strServerName) { m_strLastConnectedServerName = strServerName; } + void SetCurrentRefreshRate(uint uiRefreshRate) { m_uiCurrentRefreshRate = uiRefreshRate; } + uint GetCurrentRefreshRate() const { return m_uiCurrentRefreshRate; } + void OnPostColorFilterRender() override; private: @@ -310,12 +313,13 @@ class CCore : public CCoreInterface, public CSingleton CModelCacheManager* m_pModelCacheManager; // Instances (put new classes here!) - CXMLFile* m_pConfigFile; - CClientVariables m_ClientVariables; - CWebCoreInterface* m_pWebCore = nullptr; - CTrayIcon* m_pTrayIcon; - std::unique_ptr m_steamClient; - std::shared_ptr m_pDiscordRichPresence; + CXMLFile* m_pConfigFile; + CClientVariables m_ClientVariables; + CWebCoreInterface* m_pWebCore = nullptr; + CTrayIcon* m_pTrayIcon; + std::unique_ptr m_steamClient; + std::shared_ptr m_pDiscordRichPresence; + std::unique_ptr m_pFPSLimiter; // Hook interfaces. CMessageLoopHook* m_pMessageLoopHook; @@ -327,6 +331,7 @@ class CCore : public CCoreInterface, public CSingleton int m_iUnminimizeFrameCounter; bool m_bDidRecreateRenderTargets; bool m_bIsWindowMinimized; + uint m_uiNextRenderTargetRetryTime; // Module loader objects. CModuleLoader m_GameModule; @@ -355,6 +360,7 @@ class CCore : public CCoreInterface, public CSingleton unsigned short m_menuFrame{}; bool m_isNetworkReady{}; + bool m_bCrashDumpEncryptionDone{}; bool m_bIsOfflineMod; bool m_bCursorToggleControls; pfnProcessMessage m_pfnMessageProcessor; @@ -369,14 +375,6 @@ class CCore : public CCoreInterface, public CSingleton bool m_bQuitOnPulse; bool m_bDestroyMessageBox; - bool m_bDoneFrameRateLimit; - uint m_uiServerFrameRateLimit; - uint m_uiClientScriptFrameRateLimit; - uint m_uiFrameRateLimit; - CElapsedTimeHD m_FrameRateTimer; - uint m_uiQueuedFrameRate; - bool m_bQueuedFrameRateValid; - uint m_CurrentRefreshRate; bool m_requestNewNickname{false}; EDiagnosticDebugType m_DiagnosticDebug; @@ -399,11 +397,12 @@ class CCore : public CCoreInterface, public CSingleton bool m_bFakeLagCommandEnabled; SString m_strLastConnectedServerName{}; + uint m_uiCurrentRefreshRate{}; // Command line static void ParseCommandLine(std::map& options, const char*& szArgs, const char** pszNoValOptions = NULL); - std::map m_CommandLineOptions; // e.g. "-o option" -> {"o" = "option"} - const char* m_szCommandLineArgs; // Everything that comes after the options + std::map m_CommandLineOptions; // e.g. "-o option" -> {"o" = "option"} + const char* m_szCommandLineArgs; // Everything that comes after the options long long m_timeDiscordAppLastUpdate; }; diff --git a/Client/core/CCrashDumpWriter.cpp b/Client/core/CCrashDumpWriter.cpp index bcecc054a7f..3e8cedead7c 100644 --- a/Client/core/CCrashDumpWriter.cpp +++ b/Client/core/CCrashDumpWriter.cpp @@ -3,19 +3,401 @@ * PROJECT: Multi Theft Auto v1.0 * LICENSE: See LICENSE in the top level directory * FILE: core/CCrashDumpWriter.cpp - * PURPOSE: + * PURPOSE: Crash dump generation and crash dialog * * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ #include "StdInc.h" +#include "StackTraceHelpers.h" +#include #include #include #include #include +#include +#include "CrashHandler.h" +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static constexpr DWORD CRASH_EXIT_CODE = 3; +static constexpr std::size_t LOG_EVENT_SIZE = 200; +static constexpr uint INVALID_PARAMETER_WARNING_THRESHOLD = 5; +static constexpr std::size_t INVALID_PARAMETER_SAMPLE_LIMIT = 8; +static constexpr std::size_t MAX_FALLBACK_STACK_FRAMES = 32; +static constexpr int MAX_WIDE_TO_UTF8_BYTES = 1 * 1024 * 1024; + +static const std::chrono::milliseconds PROCESS_WAIT_TIMEOUT{500}; +static const std::chrono::milliseconds WINDOW_POLL_TIMEOUT{100}; +static constexpr std::size_t MAX_WINDOW_POLL_ATTEMPTS = 30; +static constexpr std::size_t SHELL_EXEC_POLL_ATTEMPTS = 20; +static const std::chrono::milliseconds ALT_KEY_DURATION{50}; +static constexpr int SCREEN_MARGIN_PIXELS = 50; +static constexpr int EMERGENCY_MSGBOX_WIDTH = 600; +static constexpr int EMERGENCY_MSGBOX_HEIGHT = 200; + +constexpr DWORD Milliseconds(std::chrono::milliseconds duration) +{ + return static_cast(duration.count()); +} + +[[nodiscard]] static DWORD ResolveCrashExitCode(const _EXCEPTION_POINTERS* exceptionPtrs) +{ + if (const auto* record = (exceptionPtrs != nullptr) ? exceptionPtrs->ExceptionRecord : nullptr; record != nullptr && record->ExceptionCode != 0) + { + return record->ExceptionCode; + } + + return CRASH_EXIT_CODE; +} + +[[noreturn]] static void TerminateCurrentProcessWithExitCode(DWORD exitCode) +{ + if (exitCode == 0) + { + exitCode = CRASH_EXIT_CODE; + } + + TerminateProcess(GetCurrentProcess(), exitCode); + _exit(static_cast(exitCode)); +} + +#define SAFE_DEBUG_OUTPUT(msg) SafeDebugOutput(msg) + +class CClientBase; + +// Record crash registers in scenario that a failure to create .dmp is likely +namespace EmergencyCrashLogging +{ + // Result codes for SEH-protected read operations + enum class ReadResult : int + { + Success = 1, + NullPointer = 0, + AccessFault = -1 + }; + + static void DoAddReportLog(int id, const char* msg) + { + SharedUtil::AddReportLog(id, msg); + } + + static bool TryAddReportLog(int id, const char* msg) + { + __try + { + DoAddReportLog(id, msg); + return true; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + } + + static void SafeEmergencyLog(const char* msg) + { + // Always output to debugger first (guaranteed crash-safe) + OutputDebugStringA(msg); + OutputDebugStringA("\n"); + + TryAddReportLog(9800, msg); + } + +// SEH-isolated reader for exception record +#pragma warning(push) +#pragma warning(disable : 4702) + static ReadResult TryReadExceptionRecord(const _EXCEPTION_POINTERS* pException, char* buf, size_t bufSize) + { + ReadResult result = ReadResult::AccessFault; + __try + { + if (pException->ExceptionRecord != nullptr) + { + sprintf_s(buf, bufSize, "Code=0x%08lX Addr=0x%08lX ThreadId=%lu", static_cast(pException->ExceptionRecord->ExceptionCode), + static_cast(reinterpret_cast(pException->ExceptionRecord->ExceptionAddress)), + static_cast(GetCurrentThreadId())); + result = ReadResult::Success; + } + else + { + result = ReadResult::NullPointer; + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + result = ReadResult::AccessFault; + } + return result; + } + + // SEH-isolated reader for context record + static ReadResult TryReadContextRecord(const _EXCEPTION_POINTERS* pException, char* buf1, size_t buf1Size, char* buf2, size_t buf2Size) + { + ReadResult result = ReadResult::AccessFault; + __try + { + if (pException->ContextRecord != nullptr) + { + const CONTEXT* ctx = pException->ContextRecord; + + sprintf_s(buf1, buf1Size, "EAX=0x%08lX EBX=0x%08lX ECX=0x%08lX EDX=0x%08lX", ctx->Eax, ctx->Ebx, ctx->Ecx, ctx->Edx); + + sprintf_s(buf2, buf2Size, "ESI=0x%08lX EDI=0x%08lX EBP=0x%08lX ESP=0x%08lX EIP=0x%08lX EFL=0x%08lX", ctx->Esi, ctx->Edi, ctx->Ebp, ctx->Esp, + ctx->Eip, ctx->EFlags); + + result = ReadResult::Success; + } + else + { + result = ReadResult::NullPointer; + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + result = ReadResult::AccessFault; + } + return result; + } +#pragma warning(pop) + +} + +// Call SEH-isolated readers +static void LogEmergencyExceptionRecord(const _EXCEPTION_POINTERS* pException) +{ + using namespace EmergencyCrashLogging; + + std::array buf{}; + + const auto result = TryReadExceptionRecord(pException, buf.data(), buf.size()); + + switch (result) + { + case ReadResult::Success: + SafeEmergencyLog(buf.data()); + break; + case ReadResult::NullPointer: + SafeEmergencyLog("[!] ExceptionRecord is NULL"); + break; + case ReadResult::AccessFault: + SafeEmergencyLog("[!] Fault reading ExceptionRecord"); + break; + default: + SafeEmergencyLog("[!] Unknown result reading ExceptionRecord"); + break; + } +} + +static void LogEmergencyContextRecord(const _EXCEPTION_POINTERS* pException) +{ + using namespace EmergencyCrashLogging; + + std::array buf1{}; + std::array buf2{}; + + const auto result = TryReadContextRecord(pException, buf1.data(), buf1.size(), buf2.data(), buf2.size()); + + switch (result) + { + case ReadResult::Success: + SafeEmergencyLog(buf1.data()); + SafeEmergencyLog(buf2.data()); + break; + case ReadResult::NullPointer: + SafeEmergencyLog("[!] ContextRecord is NULL"); + break; + case ReadResult::AccessFault: + SafeEmergencyLog("[!] Fault reading context"); + break; + default: + SafeEmergencyLog("[!] Unknown result reading ContextRecord"); + break; + } +} + +static void LogEmergencyCrashContext(const _EXCEPTION_POINTERS* pException) +{ + using namespace EmergencyCrashLogging; + + SafeEmergencyLog("=== EMERGENCY CRASH CONTEXT ==="); + + if (pException == nullptr) + { + SafeEmergencyLog("[!] pException is NULL"); + return; + } + + LogEmergencyExceptionRecord(pException); + + LogEmergencyContextRecord(pException); +} + +static bool SafeReadGameByte(uintptr_t address, unsigned char& outValue) +{ + __try + { + outValue = *reinterpret_cast(address); + return true; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } +} + +static bool InvokeClientHandleExceptionSafe(CClientBase* pClient, CExceptionInformation_Impl* pExceptionInformation, bool& outHandled) +{ + outHandled = false; + + if (pClient == nullptr || pExceptionInformation == nullptr) + return false; + + __try + { + outHandled = pClient->HandleException(pExceptionInformation); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: DOUBLE-FAULT in exception handler\n"); + return false; + } + return true; +} + +namespace +{ + void ConfigureDbgHelpOptions() + { + static std::atomic_flag configured = ATOMIC_FLAG_INIT; + if (!configured.test_and_set(std::memory_order_acq_rel)) + { + SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME | SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_DEFERRED_LOADS); + } + } + + std::mutex& GetSymInitMutex() + { + static std::mutex symMutex; + return symMutex; + } +} // namespace + +class SymbolHandlerGuard +{ +public: + explicit SymbolHandlerGuard(HANDLE process, bool enableSymbols) : m_process(process), m_initialized(false) + { + if (!enableSymbols) + return; + + if (m_process != nullptr) + { + std::lock_guard lock{GetSymInitMutex()}; + + ConfigureDbgHelpOptions(); + + const SString& processDir = SharedUtil::GetMTAProcessBaseDir(); + const char* searchPath = processDir.empty() ? nullptr : processDir.c_str(); + + if (SymInitialize(m_process, searchPath, TRUE) != FALSE) + m_initialized = true; + } + } + + ~SymbolHandlerGuard() + { + if (m_initialized) + SymCleanup(m_process); + } + + SymbolHandlerGuard(const SymbolHandlerGuard&) = delete; + SymbolHandlerGuard& operator=(const SymbolHandlerGuard&) = delete; + SymbolHandlerGuard(SymbolHandlerGuard&&) = delete; + SymbolHandlerGuard& operator=(SymbolHandlerGuard&&) = delete; + + bool IsInitialized() const { return m_initialized; } + +private: + HANDLE m_process; + bool m_initialized; +}; + +[[nodiscard]] static bool NormalizePathForValidation(const SString& inputPath, SString& outputPath) +{ + if (inputPath.empty()) + return false; + + const auto required = GetFullPathNameA(inputPath.c_str(), 0, nullptr, nullptr); + if (required == 0) + return false; + + std::vector buffer(static_cast(required) + 1u, '\0'); + const auto written = GetFullPathNameA(inputPath.c_str(), required + 1u, buffer.data(), nullptr); + if (written == 0 || written > required) + return false; + + outputPath = buffer.data(); + for (std::size_t i = 0; i < outputPath.length(); ++i) + { + if (outputPath[i] == '/') + outputPath[i] = '\\'; + } + + return true; +} + +static void EnsureTrailingBackslash(SString& path) +{ + if (path.empty()) + return; + + if (!path.EndsWith("\\")) + path += "\\"; +} + +[[nodiscard]] static bool ValidatePathWithinBase(const SString& baseDir, const SString& candidatePath, DWORD logId) +{ + SString normalizedBase; + if (!NormalizePathForValidation(baseDir, normalizedBase)) + { + AddReportLog(logId, SString("CCrashDumpWriter::ValidatePathWithinBase - failed to normalize base (%s)", baseDir.c_str())); + return false; + } + + EnsureTrailingBackslash(normalizedBase); + + SString normalizedCandidate; + if (!NormalizePathForValidation(candidatePath, normalizedCandidate)) + { + AddReportLog(logId, SString("CCrashDumpWriter::ValidatePathWithinBase - failed to normalize candidate (%s)", candidatePath.c_str())); + return false; + } + + const std::size_t baseLength = normalizedBase.length(); + if (baseLength == 0 || normalizedCandidate.length() < baseLength) + return false; -#define LOG_EVENT_SIZE 200 + if (_strnicmp(normalizedCandidate.c_str(), normalizedBase.c_str(), baseLength) != 0) + return false; + + return true; +} struct SLogEventInfo { @@ -25,595 +407,2686 @@ struct SLogEventInfo SString strBody; }; -struct SLogEventLine -{ - SString strBody; - SString strType; - SString strContext; - void operator+=(const char* szAppend) { strBody += szAppend; } - bool operator==(const SLogEventLine& other) const { return strBody == other.strBody && strType == other.strType && strContext == other.strContext; } -}; +struct SLogEventLine +{ + SString strBody; + SString strType; + SString strContext; + void operator+=(const char* szAppend) { strBody += szAppend; } + bool operator==(const SLogEventLine& other) const { return strBody == other.strBody && strType == other.strType && strContext == other.strContext; } +}; + +struct SCrashAvertedInfo +{ + uint uiTickCount; + int uiUsageCount; +}; + +static std::list ms_LogEventList; +static CDuplicateLineFilter ms_LogEventFilter; +static std::map ms_CrashAvertedMap; +static uint ms_uiTickCountBase = 0; +static void* ms_pReservedMemory = nullptr; +static uint ms_uiInCrashZone = 0; + +static std::atomic ms_uiInvalidParameterCount{0}; +static std::atomic ms_uiInvalidParameterCountLogged{0}; +static std::atomic ms_bInCrashHandler{false}; +static std::array ms_InvalidParameterSamples; +static std::atomic ms_uiInvalidParameterSampleCount{0}; +static std::atomic ms_bInvalidParameterWarningStored{false}; +static std::atomic ms_bFallbackStackLogged{false}; +static HANDLE ms_hCrashDialogProcess = nullptr; + +[[nodiscard]] static std::array BuildCrashDialogCandidates() +{ + const SString basePath = GetMTASABaseDir(); + std::array candidates = {SharedUtil::PathJoin(basePath, "Multi Theft Auto.exe"), SharedUtil::PathJoin(basePath, "Multi Theft Auto_d.exe")}; + + return candidates; +} + +[[nodiscard]] static inline constexpr bool IsValidHandle(HANDLE handle) +{ + return handle != nullptr && handle != INVALID_HANDLE_VALUE; +} + +class UniqueHandle +{ +public: + UniqueHandle() = default; + explicit UniqueHandle(HANDLE handle) : m_handle(handle) {} + ~UniqueHandle() { reset(); } + + UniqueHandle(const UniqueHandle&) = delete; + UniqueHandle& operator=(const UniqueHandle&) = delete; + + UniqueHandle(UniqueHandle&& other) : m_handle(other.release()) {} + UniqueHandle& operator=(UniqueHandle&& other) + { + if (this != &other) + { + reset(); + m_handle = other.release(); + } + return *this; + } + + void reset(HANDLE handle = nullptr) + { + if (IsValidHandle(m_handle)) + CloseHandle(m_handle); + m_handle = handle; + } + + [[nodiscard]] HANDLE get() const { return m_handle; } + + [[nodiscard]] HANDLE release() + { + HANDLE handle = m_handle; + m_handle = nullptr; + return handle; + } + + [[nodiscard]] explicit operator bool() const { return IsValidHandle(m_handle); } + +private: + HANDLE m_handle = nullptr; +}; + +static void EnsureCrashReasonForDialog(CExceptionInformation* pExceptionInformation) +{ + if (pExceptionInformation == nullptr) + { + SAFE_DEBUG_OUTPUT("EnsureCrashReasonForDialog: NULL exception information\n"); + SetApplicationSetting("diagnostics", "last-crash-reason", "Unknown crash - no exception information"); + return; + } + + SString strReason = GetApplicationSetting("diagnostics", "last-crash-reason"); + + if (strReason.empty()) + { + const unsigned int code = pExceptionInformation->GetCode(); + + SString exceptionType; + switch (code) + { + case EXCEPTION_ACCESS_VIOLATION: + exceptionType = "Access Violation - Invalid memory access"; + break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + exceptionType = "Array Bounds Exceeded"; + break; + case EXCEPTION_BREAKPOINT: + exceptionType = "Breakpoint Hit"; + break; + case EXCEPTION_DATATYPE_MISALIGNMENT: + exceptionType = "Data Type Misalignment"; + break; + case EXCEPTION_FLT_DENORMAL_OPERAND: + exceptionType = "Floating Point - Denormal Operand"; + break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + exceptionType = "Floating Point - Divide by Zero"; + break; + case EXCEPTION_FLT_INEXACT_RESULT: + exceptionType = "Floating Point - Inexact Result"; + break; + case EXCEPTION_FLT_INVALID_OPERATION: + exceptionType = "Floating Point - Invalid Operation"; + break; + case EXCEPTION_FLT_OVERFLOW: + exceptionType = "Floating Point - Overflow"; + break; + case EXCEPTION_FLT_STACK_CHECK: + exceptionType = "Floating Point - Stack Check"; + break; + case EXCEPTION_FLT_UNDERFLOW: + exceptionType = "Floating Point - Underflow"; + break; + case EXCEPTION_ILLEGAL_INSTRUCTION: + exceptionType = "Illegal Instruction"; + break; + case EXCEPTION_IN_PAGE_ERROR: + exceptionType = "In Page Error - Page fault"; + break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + exceptionType = "Integer Divide by Zero"; + break; + case EXCEPTION_INT_OVERFLOW: + exceptionType = "Integer Overflow"; + break; + case EXCEPTION_INVALID_DISPOSITION: + exceptionType = "Invalid Disposition"; + break; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + exceptionType = "Non-Continuable Exception"; + break; + case EXCEPTION_PRIV_INSTRUCTION: + exceptionType = "Privileged Instruction"; + break; + case EXCEPTION_SINGLE_STEP: + exceptionType = "Single Step (Debugging)"; + break; + case EXCEPTION_STACK_OVERFLOW: + exceptionType = "Stack Overflow"; + break; + case EXCEPTION_GUARD_PAGE: + exceptionType = "Guard Page Violation"; + break; + case EXCEPTION_INVALID_HANDLE: + exceptionType = "Invalid Handle"; + break; + case CPP_EXCEPTION_CODE: + exceptionType = "C++ Exception"; + break; + case STATUS_STACK_BUFFER_OVERRUN_CODE: + exceptionType = "Stack Buffer Overrun (Security Check)"; + break; + case STATUS_INVALID_CRUNTIME_PARAMETER_CODE: + exceptionType = "Invalid C Runtime Parameter"; + break; + case STATUS_FATAL_USER_CALLBACK_EXCEPTION: + exceptionType = "Fatal Exception in Windows Callback - Callback Exception Unhandled"; + break; + case CUSTOM_EXCEPTION_CODE_OOM: + exceptionType = "Out of Memory - Allocation Failure"; + break; + case CUSTOM_EXCEPTION_CODE_WATCHDOG_TIMEOUT: + exceptionType = "Watchdog Timeout - Thread Freeze Detected"; + break; + case STATUS_HEAP_CORRUPTION_CODE: + exceptionType = "Heap Corruption Detected"; + break; + case 0xC0000420: + exceptionType = "Assertion Failure"; + break; + case 0x40000015: + exceptionType = "Fatal App Exit"; + break; + case 0xC00002C9: + exceptionType = "Register NaT Consumption"; + break; + case 0xC0000194: + exceptionType = "Possible Deadlock Condition"; + break; + case 0x80000029: + exceptionType = "Unwind Consolidate (Frame consolidation)"; + break; + default: + exceptionType = SString("Exception 0x%08X", code); + break; + } + + const char* moduleBaseName = pExceptionInformation->GetModuleBaseName(); + if (moduleBaseName == nullptr || moduleBaseName[0] == '\0') + moduleBaseName = pExceptionInformation->GetModulePathName(); + if (moduleBaseName == nullptr || moduleBaseName[0] == '\0') + moduleBaseName = "unknown"; + + // If we still have "unknown", try registry-resolved module info as fallback + CExceptionInformation_Impl* pImpl = dynamic_cast(pExceptionInformation); + const char* resolvedModuleName = nullptr; + DWORD resolvedIdaAddress = 0; + bool hasResolvedInfo = false; + + if (pImpl != nullptr && pImpl->HasResolvedModuleInfo()) + { + resolvedModuleName = pImpl->GetResolvedModuleName(); + resolvedIdaAddress = pImpl->GetResolvedIdaAddress(); + hasResolvedInfo = true; + } + + // Build the reason string with best available module info + if (strcmp(moduleBaseName, "unknown") == 0 && hasResolvedInfo && resolvedModuleName != nullptr && resolvedModuleName[0] != '\0') + { + // Use registry-resolved info when basic module resolution failed + strReason = + SString("\n\nReason: %s at %s+0x%08X (IDA: 0x%08X)", exceptionType.c_str(), resolvedModuleName, pImpl->GetResolvedRva(), resolvedIdaAddress); + } + else if (hasResolvedInfo && resolvedModuleName != nullptr && resolvedModuleName[0] != '\0') + { + // Include IDA address as additional info when we have both sources + strReason = SString("\n\nReason: %s at %s+0x%08X (IDA via %s: 0x%08X)", exceptionType.c_str(), moduleBaseName, + pExceptionInformation->GetAddressModuleOffset(), resolvedModuleName, resolvedIdaAddress); + } + else + { + // Original format when no registry-resolved info available + strReason = SString("\n\nReason: %s at %s+0x%08X", exceptionType.c_str(), moduleBaseName, pExceptionInformation->GetAddressModuleOffset()); + } + + if (ms_uiInCrashZone != 0) + strReason += SString(" (CrashZone=%u)", ms_uiInCrashZone); + + const uint invalidParameterCount = ms_uiInvalidParameterCount.load(std::memory_order_relaxed); + if (invalidParameterCount > 0) + strReason += SString(" (InvalidParameterCount=%u)", invalidParameterCount); + + strReason += SString(" (ThreadId=%u)", GetCurrentThreadId()); + + SAFE_DEBUG_OUTPUT(SString("EnsureCrashReasonForDialog: %s\n", strReason.c_str()).c_str()); + } + else + { + SAFE_DEBUG_OUTPUT(SString("EnsureCrashReasonForDialog: Using existing reason: %s\n", strReason.c_str()).c_str()); + } + + SString pendingWarning = GetApplicationSetting("diagnostics", "pending-invalid-parameter-warning"); + if (!pendingWarning.empty()) + strReason += pendingWarning; + + SetApplicationSetting("diagnostics", "last-crash-reason", strReason); +} + +[[nodiscard]] static SString WideToUtf8(const wchar_t* input) +{ + if (input == nullptr || input[0] == L'\0') + return SString(); + + const auto required = WideCharToMultiByte(CP_UTF8, 0, input, -1, nullptr, 0, nullptr, nullptr); + if (required <= 0) + return SString(); + + if (required > MAX_WIDE_TO_UTF8_BYTES) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::WideToUtf8 - input too large for UTF-8 conversion\n"); + AddReportLog(9212, SString("CCrashDumpWriter::WideToUtf8 - conversion request exceeds %d bytes", MAX_WIDE_TO_UTF8_BYTES)); + return SString(); + } + + std::vector buffer(static_cast(required)); + const auto converted = WideCharToMultiByte(CP_UTF8, 0, input, -1, buffer.data(), required, nullptr, nullptr); + if (converted <= 0) + return SString(); + + const char* convertedText = buffer.data(); + return SString(std::string(convertedText)); +} + +static void AppendCrashDiagnostics(const SString& text) +{ + if (text.empty()) + return; + + FILE* pFile = File::Fopen(CalcMTASAPath("mta\\core.log"), "a+"); + if (pFile != nullptr) + { + fprintf(pFile, "%s", text.c_str()); + fclose(pFile); + } + + SString strInfo = GetApplicationSetting("diagnostics", "last-crash-info"); + strInfo += text; + SetApplicationSetting("diagnostics", "last-crash-info", strInfo); + + WriteDebugEvent(text.Replace("\n", " ")); +} + +[[nodiscard]] static bool CaptureStackTraceText(_EXCEPTION_POINTERS* pException, SString& outText) +{ + if (pException == nullptr || pException->ContextRecord == nullptr) + return false; + + const bool hasSymbols = CrashHandler::ProcessHasLocalDebugSymbols(); + if (!hasSymbols) + { + static std::once_flag logOnce; + std::call_once(logOnce, [] { SAFE_DEBUG_OUTPUT("CaptureStackTraceText: capturing without symbols (raw addresses only)\n"); }); + } + + // For callback exceptions (0xC000041D), context and stack may be unreliable + const bool isCallbackException = (pException->ExceptionRecord != nullptr && pException->ExceptionRecord->ExceptionCode == 0xC000041D); + if (isCallbackException) + { + SAFE_DEBUG_OUTPUT("CaptureStackTraceText: Callback exception detected - using reduced trace depth\n"); + } + + const DWORD contextFlags = pException->ContextRecord->ContextFlags; + if ((contextFlags & CONTEXT_CONTROL) == 0) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::CaptureStackTraceText - CONTEXT_CONTROL flag missing; stack walk aborted\n"); + return false; + } + + outText = ""; + outText.reserve(MAX_FALLBACK_STACK_FRAMES * 128u); + + const auto hProcess = GetCurrentProcess(); + const auto hThread = GetCurrentThread(); + + CONTEXT context = *pException->ContextRecord; + STACKFRAME64 frame{}; + + frame.AddrPC.Offset = context.Eip; + frame.AddrFrame.Offset = context.Ebp; + frame.AddrStack.Offset = context.Esp; + + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Mode = AddrModeFlat; + + SymbolHandlerGuard symbolGuard(hProcess, hasSymbols); + + const bool useDbgHelp = symbolGuard.IsInitialized(); + const auto routines = useDbgHelp ? StackTraceHelpers::MakeStackWalkRoutines(true) : StackTraceHelpers::MakeStackWalkRoutines(false); + + static_assert(MAX_SYM_NAME > 1, "MAX_SYM_NAME must include room for a terminator"); + constexpr DWORD kSymbolNameCapacity = MAX_SYM_NAME - 1; + alignas(SYMBOL_INFO) unsigned char symbolBuffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME] = {}; + PSYMBOL_INFO pSymbol = reinterpret_cast(symbolBuffer); + pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); + pSymbol->MaxNameLen = kSymbolNameCapacity; + + std::array visitedAddresses{}; + std::size_t visitedCount = 0; + + for (std::size_t frameIndex = 0; frameIndex < MAX_FALLBACK_STACK_FRAMES; ++frameIndex) + { + BOOL bWalked = StackWalk64(IMAGE_FILE_MACHINE_I386, hProcess, hThread, &frame, &context, routines.readMemory, routines.functionTableAccess, + routines.moduleBase, nullptr); + if (bWalked == FALSE) + break; + + if (frame.AddrPC.Offset == 0) + break; + + DWORD64 address = frame.AddrPC.Offset; + + const bool alreadyVisited = + std::any_of(visitedAddresses.begin(), visitedAddresses.begin() + visitedCount, [address](DWORD64 seen) { return seen == address; }); + if (alreadyVisited) + break; + + if (visitedCount < visitedAddresses.size()) + visitedAddresses[visitedCount++] = address; + + SString symbolName = SString("0x%llX", static_cast(address)); + if (useDbgHelp && SymFromAddr(hProcess, address, nullptr, pSymbol) != FALSE) + { + const auto terminatorIndex = static_cast(pSymbol->MaxNameLen); + if (terminatorIndex < MAX_SYM_NAME) + pSymbol->Name[terminatorIndex] = '\0'; + symbolName = pSymbol->Name; + } + + IMAGEHLP_LINE64 lineInfo{}; + lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + DWORD lineDisplacement = 0; + SString lineDetail; + + if (useDbgHelp && SymGetLineFromAddr64(hProcess, address, &lineDisplacement, &lineInfo) != FALSE) + { + const char* fileName = lineInfo.FileName != nullptr ? lineInfo.FileName : "unknown"; + lineDetail = SString("%s:%lu", fileName, static_cast(lineInfo.LineNumber)); + } + else + { + const std::string formatted = StackTraceHelpers::FormatAddressWithModule(address); + lineDetail = formatted.c_str(); + } + + outText += SString("#%02u %s [0x%llX] (%s)\n", static_cast(frameIndex), symbolName.c_str(), static_cast(address), + lineDetail.c_str()); + } + + return !outText.empty(); +} + +static void AppendFallbackStackTrace(_EXCEPTION_POINTERS* pException) +{ + bool expected = false; + if (!ms_bFallbackStackLogged.compare_exchange_strong(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) + return; + + SString stackText; + if (CaptureStackTraceText(pException, stackText)) + { + AppendCrashDiagnostics(SString("\n[Fallback Stack Trace]\n%s\n", stackText.c_str())); + } + else + { + AppendCrashDiagnostics("\n[Fallback Stack Trace] unavailable\n"); + } +} + +// Helper function to safely read callback exception context (uses SEH) +static void TryLogCallbackContext(_EXCEPTION_POINTERS* pException) +{ + __try + { + if (pException->ContextRecord != nullptr) + { + std::array szDebug; + SAFE_DEBUG_PRINT_C(szDebug.data(), szDebug.size(), "CCrashDumpWriter: Callback context EIP=0x%08X ESP=0x%08X\n", pException->ContextRecord->Eip, + pException->ContextRecord->Esp); + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Failed to read callback exception context\n"); + } +} + +namespace +{ + constexpr MINIDUMP_STREAM_TYPE kStreamExceptionSummary = static_cast(LastReservedStream + 1); + constexpr MINIDUMP_STREAM_TYPE kStreamStackTrace = static_cast(LastReservedStream + 2); + constexpr MINIDUMP_STREAM_TYPE kStreamRegisterState = static_cast(LastReservedStream + 3); + constexpr MINIDUMP_STREAM_TYPE kStreamAdditionalInfo = CommentStreamA; + constexpr MINIDUMP_STREAM_TYPE kStreamCapturedException = static_cast(LastReservedStream + 4); + + class MinidumpUserStreamCollection + { + public: + void AddTextStream(MINIDUMP_STREAM_TYPE type, std::string_view text) + { + if (text.empty()) + return; + + auto& buffer = m_buffers.emplace_back(); + buffer.reserve(text.size() + 1); + buffer.insert(buffer.end(), text.begin(), text.end()); + if (buffer.empty() || buffer.back() != '\0') + buffer.push_back('\0'); + + MINIDUMP_USER_STREAM stream{}; + stream.Type = type; + stream.Buffer = buffer.data(); + stream.BufferSize = static_cast(buffer.size()); + m_streams.push_back(stream); + } + + PMINIDUMP_USER_STREAM_INFORMATION Build() + { + if (m_streams.empty()) + { + m_info = MINIDUMP_USER_STREAM_INFORMATION{}; + return nullptr; + } + + m_info.UserStreamArray = m_streams.data(); + m_info.UserStreamCount = static_cast(m_streams.size()); + return &m_info; + } + + private: + std::vector> m_buffers; + std::vector m_streams; + MINIDUMP_USER_STREAM_INFORMATION m_info{}; + }; + + std::string FormatExceptionSummary(const ENHANCED_EXCEPTION_INFO& info) + { + std::string summary; + summary.reserve(512); + char line[256]{}; + + _snprintf_s(line, sizeof(line), _TRUNCATE, "Exception Code: 0x%08X\n", info.exceptionCode); + summary += line; + + if (info.exceptionAddress != nullptr) + { + _snprintf_s(line, sizeof(line), _TRUNCATE, "Exception Address: 0x%p\n", info.exceptionAddress); + summary += line; + } + + if (!info.exceptionDescription.empty()) + { + summary += "Description: "; + summary += info.exceptionDescription; + if (summary.back() != '\n') + summary += '\n'; + } + + if (!info.exceptionType.empty()) + { + summary += "Exception Type: "; + summary += info.exceptionType; + summary += '\n'; + } + + if (!info.moduleName.empty()) + { + summary += "Module: "; + summary += info.moduleName; + summary += '\n'; + } + + if (!info.modulePathName.empty()) + { + summary += "Module Path: "; + summary += info.modulePathName; + summary += '\n'; + } + + if (info.moduleOffset != 0U) + { + _snprintf_s(line, sizeof(line), _TRUNCATE, "Module Offset: 0x%08X\n", info.moduleOffset); + summary += line; + } + + if (info.timestamp.time_since_epoch().count() != 0) + { + const std::time_t timeValue = std::chrono::system_clock::to_time_t(info.timestamp); + std::tm localTime{}; +#if defined(_WIN32) + if (localtime_s(&localTime, &timeValue) == 0) +#else + if (localtime_r(&timeValue, &localTime) != nullptr) +#endif + { + char timeBuffer[64]{}; + if (std::strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %H:%M:%S", &localTime) != 0) + { + summary += "Timestamp: "; + summary += timeBuffer; + summary += '\n'; + } + } + } + + _snprintf_s(line, sizeof(line), _TRUNCATE, "Thread ID: %lu Process ID: %lu\n", static_cast(info.threadId), + static_cast(info.processId)); + summary += line; + + _snprintf_s(line, sizeof(line), _TRUNCATE, "Uncaught Exceptions: %d\n", info.uncaughtExceptionCount); + summary += line; + + summary += "Crash Severity: "; + summary += info.isFatal ? "fatal" : "recoverable"; + summary += '\n'; + + return summary; + } + + std::string FormatStackTrace(const ENHANCED_EXCEPTION_INFO& info) + { + if (!info.stackTrace.has_value() || info.stackTrace->empty()) + return {}; + + std::string traceText; + traceText.reserve(info.stackTrace->size() * 64); + traceText += "Stack Trace (CrashHandler):\n"; + + for (std::size_t i = 0; i < info.stackTrace->size(); ++i) + { + traceText += " #"; + traceText += std::to_string(i); + traceText += " "; + traceText += info.stackTrace->at(i); + if (traceText.back() != '\n') + traceText += '\n'; + } + + return traceText; + } + + std::string FormatRegisterDump(const ENHANCED_EXCEPTION_INFO& info) + { + std::string registers; + registers.reserve(256); + char line[160]{}; + + registers += "CPU Registers:\n"; + _snprintf_s(line, sizeof(line), _TRUNCATE, " EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n", info.eax, info.ebx, info.ecx, info.edx); + registers += line; + + _snprintf_s(line, sizeof(line), _TRUNCATE, " ESI=0x%08X EDI=0x%08X EBP=0x%08X ESP=0x%08X\n", info.esi, info.edi, info.ebp, info.esp); + registers += line; + + _snprintf_s(line, sizeof(line), _TRUNCATE, " EIP=0x%08X EFLAGS=0x%08X\n", info.eip, info.eflags); + registers += line; + + _snprintf_s(line, sizeof(line), _TRUNCATE, " CS=0x%04X DS=0x%04X ES=0x%04X FS=0x%04X GS=0x%04X SS=0x%04X\n", info.cs, info.ds, info.es, info.fs, + info.gs, info.ss); + registers += line; + + return registers; + } + + std::string FormatCapturedExceptionInfo(const ENHANCED_EXCEPTION_INFO& info) + { + if (info.exceptionType.empty() && !info.capturedException.has_value()) + return {}; + + std::string text; + text.reserve(256); + text += "Captured Exception Metadata:\n"; + + if (!info.exceptionType.empty()) + { + text += " Type: "; + text += info.exceptionType; + text += '\n'; + } + + text += " exception_ptr captured: "; + text += info.capturedException.has_value() ? "yes" : "no"; + text += '\n'; + + if (!info.exceptionDescription.empty()) + { + text += " Description: "; + text += info.exceptionDescription; + if (text.back() != '\n') + text += '\n'; + } + + return text; + } + + std::string BuildAdditionalInfoPayload(const ENHANCED_EXCEPTION_INFO* info, std::string_view telemetryFallback, std::string_view fallbackSummary = {}) + { + std::string payload; + + const auto appendBlock = [&](std::string_view block) + { + if (block.empty()) + return; + + if (!payload.empty()) + payload.push_back('\n'); + + payload.append(block.begin(), block.end()); + if (!payload.empty() && payload.back() != '\n') + payload.push_back('\n'); + }; + + if (info != nullptr) + { + appendBlock(info->additionalInfo); + + const std::string summary = FormatExceptionSummary(*info); + appendBlock(summary); + + const std::string capturedMeta = FormatCapturedExceptionInfo(*info); + appendBlock(capturedMeta); + + const std::string registers = FormatRegisterDump(*info); + appendBlock(registers); + + const std::string stackTrace = FormatStackTrace(*info); + appendBlock(stackTrace); + } + else if (!fallbackSummary.empty()) + { + appendBlock(fallbackSummary); + } + + const bool hasTelemetry = !telemetryFallback.empty(); + bool telemetryAlreadyIncluded = false; + if (info != nullptr && hasTelemetry && !info->additionalInfo.empty()) + { + telemetryAlreadyIncluded = info->additionalInfo.find("Allocation telemetry") != std::string::npos; + } + + if (hasTelemetry && !telemetryAlreadyIncluded) + { + appendBlock(telemetryFallback); + } + + return payload; + } + + std::string BuildBasicExceptionSummary(_EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation) + { + if (pException == nullptr || pException->ExceptionRecord == nullptr) + return {}; + + std::string summary; + summary.reserve(256); + char line[160]{}; + + _snprintf_s(line, sizeof(line), _TRUNCATE, "Exception Code: 0x%08X\n", pException->ExceptionRecord->ExceptionCode); + summary += line; + + _snprintf_s(line, sizeof(line), _TRUNCATE, "Exception Address: 0x%p\n", pException->ExceptionRecord->ExceptionAddress); + summary += line; + + if (pExceptionInformation != nullptr) + { + if (const char* modulePath = pExceptionInformation->GetModulePathName(); modulePath != nullptr && modulePath[0] != '\0') + { + summary += "Module: "; + summary += modulePath; + summary += '\n'; + } + + _snprintf_s(line, sizeof(line), _TRUNCATE, "Module Offset: 0x%08X\n", pExceptionInformation->GetAddressModuleOffset()); + summary += line; + } + + return summary; + } +} // namespace + +template +void AppendDumpSection(const SString& targetPath, const char* tryLabel, const char* successLabel, DWORD tagBegin, DWORD tagEnd, SectionGenerator&& generator) +{ + SetApplicationSetting("diagnostics", "last-dump-extra", tryLabel); + CBuffer buffer; + std::forward(generator)(buffer); + CCrashDumpWriter::AppendToDumpFile(targetPath, buffer, tagBegin, tagEnd); + SetApplicationSetting("diagnostics", "last-dump-extra", successLabel); +} + +using MINIDUMPWRITEDUMP = BOOL(WINAPI*)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, + CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); + +void CCrashDumpWriter::OnCrashAverted(uint uiId) +{ + SCrashAvertedInfo* pInfo = MapFind(ms_CrashAvertedMap, uiId); + if (pInfo == nullptr) + { + MapSet(ms_CrashAvertedMap, uiId, SCrashAvertedInfo()); + pInfo = MapFind(ms_CrashAvertedMap, uiId); + pInfo->uiUsageCount = 0; + } + pInfo->uiTickCount = GetTickCount32(); + pInfo->uiUsageCount++; +} + +void CCrashDumpWriter::OnEnterCrashZone(uint uiId) +{ + ms_uiInCrashZone = uiId; +} + +void CCrashDumpWriter::LogEvent(const char* szType, const char* szContext, const char* szBody) +{ + ms_LogEventFilter.AddLine({szBody, szType, szContext}); + + SLogEventLine line; + while (ms_LogEventFilter.PopOutputLine(line)) + { + ms_LogEventList.emplace_front(SLogEventInfo{GetTickCount32(), line.strType, line.strContext, line.strBody}); + + while (ms_LogEventList.size() > LOG_EVENT_SIZE) + ms_LogEventList.pop_back(); + } +} + +void CCrashDumpWriter::SetHandlers() +{ + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Setting up crash handlers\n"); + + if (!EnableStackCookieFailureCapture(TRUE)) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: WARNING - Failed to enable stack cookie failure capture\n"); + } + else + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Stack cookie failure capture enabled\n"); + } + + // Install crash filter as absolute first action to catch early exceptions + // This improves the catching of crashes during window creation or early init + if (!SetCrashHandlerFilter(CCrashDumpWriter::HandleExceptionGlobal)) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: WARNING - Failed to install crash handler filter\n"); + } + else + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Crash handler filter installed successfully\n"); + } + + ms_uiInvalidParameterSampleCount.store(0, std::memory_order_relaxed); + ms_bInvalidParameterWarningStored.store(false, std::memory_order_relaxed); + std::fill(ms_InvalidParameterSamples.begin(), ms_InvalidParameterSamples.end(), ""); + SetApplicationSetting("diagnostics", "pending-invalid-parameter-warning", ""); + + _set_invalid_parameter_handler(CCrashDumpWriter::HandleInvalidParameter); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Invalid parameter handler installed\n"); + + CCrashDumpWriter::ReserveMemoryKBForCrashDumpProcessing(3000); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Reserved 3000KB for crash dump processing\n"); +} + +void CCrashDumpWriter::UpdateCounters() +{ + const auto currentCount = ms_uiInvalidParameterCount.load(std::memory_order_relaxed); + const auto loggedCount = ms_uiInvalidParameterCountLogged.load(std::memory_order_relaxed); + + if (currentCount > loggedCount && loggedCount < 10) + { + AddReportLog(9206, SString("InvalidParameterCount changed from %d to %d", loggedCount, currentCount)); + ms_uiInvalidParameterCountLogged.store(currentCount, std::memory_order_relaxed); + } + + if (currentCount >= INVALID_PARAMETER_WARNING_THRESHOLD) + { + bool expected = false; + if (ms_bInvalidParameterWarningStored.compare_exchange_strong(expected, true, std::memory_order_acq_rel, std::memory_order_relaxed)) + { + const auto sampleCount = + std::min(ms_uiInvalidParameterSampleCount.load(std::memory_order_relaxed), static_cast(INVALID_PARAMETER_SAMPLE_LIMIT)); + + SString warning = SString("\n\nWarning: Detected %u invalid CRT parameter calls prior to crash.\n", currentCount); + if (sampleCount > 0) + { + warning += "Sample invalid parameter inputs:\n"; + for (uint i = 0; i < sampleCount && i < ms_InvalidParameterSamples.size(); ++i) + { + warning += SString(" %u) %s\n", i + 1, ms_InvalidParameterSamples[i].c_str()); + } + } + + warning += "\n"; + + SetApplicationSetting("diagnostics", "pending-invalid-parameter-warning", warning); + WriteDebugEvent(warning.Replace("\n", " ")); + AddReportLog(9210, warning); + } + } +} + +void CCrashDumpWriter::HandleInvalidParameter(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, + [[maybe_unused]] uintptr_t pReserved) +{ + const uint sampleIndex = ms_uiInvalidParameterSampleCount.fetch_add(1, std::memory_order_relaxed); + if (sampleIndex < INVALID_PARAMETER_SAMPLE_LIMIT) + { + SString exprStr = WideToUtf8(expression); + SString funcStr = WideToUtf8(function); + SString fileStr = WideToUtf8(file); + + if (exprStr.empty()) + exprStr = ""; + if (funcStr.empty()) + funcStr = ""; + if (fileStr.empty()) + fileStr = ""; + + ms_InvalidParameterSamples[static_cast(sampleIndex)] = + SString("expr=\"%s\" func=\"%s\" file=\"%s\" line=%u reserved=0x%p", exprStr.c_str(), funcStr.c_str(), fileStr.c_str(), line, + reinterpret_cast(pReserved)); + } + + ms_uiInvalidParameterCount.fetch_add(1, std::memory_order_relaxed); +} + +void CCrashDumpWriter::ReserveMemoryKBForCrashDumpProcessing(uint uiMemoryKB) +{ + FreeMemoryForCrashDumpProcessing(); + + constexpr std::size_t kMaxReserveMemoryKB = 64u * 1024u; + + uiMemoryKB = std::clamp(static_cast(uiMemoryKB), std::size_t{0}, kMaxReserveMemoryKB); + + if (uiMemoryKB > SIZE_MAX / 1024) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Memory reservation size too large\n"); + return; + } + + ms_pReservedMemory = malloc(static_cast(uiMemoryKB) * 1024); + if (ms_pReservedMemory == nullptr) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Failed to reserve memory for crash dump processing\n"); + } +} + +void CCrashDumpWriter::FreeMemoryForCrashDumpProcessing() +{ + if (ms_pReservedMemory != nullptr) + { + free(ms_pReservedMemory); + ms_pReservedMemory = nullptr; + } +} + +// Helper to safely read exception code using SEH +static DWORD SafeReadExceptionCode(_EXCEPTION_POINTERS* pException) +{ + DWORD exceptionCode = 0; + __try + { + if (pException != nullptr && pException->ExceptionRecord != nullptr) + { + exceptionCode = pException->ExceptionRecord->ExceptionCode; + if (exceptionCode == STATUS_FATAL_USER_CALLBACK_EXCEPTION) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: 0xC000041D callback exception detected\n"); + } + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Exception accessing exception record (corrupted frame)\n"); + } + return exceptionCode; +} + +// Helper to get MTA path as C string for SEH contexts (avoids SString unwinding issues) +static const char* GetMTAPathForSEH() +{ + static char szPath[MAX_PATH] = {0}; + static bool initialized = false; + + if (!initialized) + { + SString strPath = GetMTASABaseDir(); + strncpy_s(szPath, sizeof(szPath), strPath.c_str(), _TRUNCATE); + initialized = true; + } + + return szPath; +} + +// Helper to write reentrant flag file using only SEH +static void TryWriteReentrantFlag(DWORD exceptionCode) +{ + // Use static buffer to avoid SString (which requires object unwinding) + static char szFlagPath[MAX_PATH]; + const char* szMTAPath = GetMTAPathForSEH(); + if (szMTAPath != nullptr && szMTAPath[0] != '\0') + { + snprintf(szFlagPath, sizeof(szFlagPath), "%s\\mta\\core.log.flag.reentrant", szMTAPath); + } + else + { + return; // Can't proceed without path + } + + __try + { + if (FILE* pFlagFile = File::Fopen(szFlagPath, "w")) + { + fprintf(pFlagFile, "Reentrant exception 0x%08X\n", exceptionCode); + fclose(pFlagFile); + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + // Ignore failures in emergency path + } +} + +// Helper to re-read exception code with SEH protection (no C++ exception handling) +static DWORD SafeRereadExceptionCode(_EXCEPTION_POINTERS* pException, DWORD fallback) +{ + DWORD exceptionCode = fallback; + __try + { + if (pException != nullptr && pException->ExceptionRecord != nullptr) + { + exceptionCode = pException->ExceptionRecord->ExceptionCode; + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + // Keep using fallback if re-read fails + } + return exceptionCode; +} + +long WINAPI CCrashDumpWriter::HandleExceptionGlobal(_EXCEPTION_POINTERS* pException) +{ + // Absolute first action - log that we entered the handler (before anything can fail) + // This is critical for diagnosing exceptions that may fault during handling + OutputDebugStringSafe("CCrashDumpWriter::HandleExceptionGlobal - EMERGENCY ENTRY MARKER\n"); + + // Log exception code and registers immediately - ensures crash context is captured + // even if subsequent processing fails and no dump is generated (stale artifact scenario) + // Uses SafeEmergencyLog internally which is SEH-protected + LogEmergencyCrashContext(pException); + + SAFE_DEBUG_OUTPUT("========================================\n"); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::HandleExceptionGlobal - ENTRY\n"); + SAFE_DEBUG_OUTPUT("========================================\n"); + + const DWORD crashExitCode = ResolveCrashExitCode(pException); + + // Protect against stale/corrupted exception frames - use SEH to safely dereference exception pointers + // This applies to any exception that may have invalid pointers (callbacks, stack corruption, etc.) + const DWORD exceptionCodeSafe = SafeReadExceptionCode(pException); + + // Attempt minimal emergency dump for any reentrant crash + bool expected{false}; + if (!ms_bInCrashHandler.compare_exchange_strong(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: RECURSIVE CRASH - Already in crash handler\n"); + + // Try emergency minimal dump for any reentrant exception + if (exceptionCodeSafe != 0) + { + OutputDebugStringSafe("CCrashDumpWriter: EMERGENCY - Reentrant exception, attempting minimal dump\n"); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Exception during crash handling - attempting emergency artifacts\n"); + TryWriteReentrantFlag(exceptionCodeSafe); + } + + TerminateCurrentProcessWithExitCode(crashExitCode); + return EXCEPTION_EXECUTE_HANDLER; + } + + ms_bFallbackStackLogged.store(false, std::memory_order_relaxed); + + FreeMemoryForCrashDumpProcessing(); + + // Use the safely-obtained exception code from SEH block + DWORD exceptionCode = SafeRereadExceptionCode(pException, exceptionCodeSafe); + + if (pException == nullptr || exceptionCode == 0) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::HandleExceptionGlobal - NULL or invalid exception\n"); + TerminateCurrentProcessWithExitCode(crashExitCode); + return EXCEPTION_EXECUTE_HANDLER; + } + + if (IsFatalException(exceptionCode) == FALSE) + { + std::array szDebug; + SAFE_DEBUG_PRINT_C(szDebug.data(), szDebug.size(), "CCrashDumpWriter: Non-fatal exception 0x%08X - ignoring\n", exceptionCode); + return EXCEPTION_CONTINUE_SEARCH; + } + + const BOOL exceptionLogged = LogExceptionDetails(pException); + if (exceptionLogged == FALSE) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: WARNING - LogExceptionDetails failed\n"); + } + + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: ======================================\n"); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: FATAL EXCEPTION - Begin crash processing\n"); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: ======================================\n"); + + // Special handling for callback exceptions - they require extra care + const bool isCallbackException = (exceptionCode == STATUS_FATAL_USER_CALLBACK_EXCEPTION); + if (isCallbackException) + { + OutputDebugStringSafe("CCrashDumpWriter: EMERGENCY - Entering callback exception special handling\n"); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: STATUS_FATAL_USER_CALLBACK_EXCEPTION detected\n"); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: This exception occurred in a Windows callback\n"); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Stack frames may be incomplete or corrupted\n"); + + // Try to capture what we can with additional protection + TryLogCallbackContext(pException); + OutputDebugStringSafe("CCrashDumpWriter: EMERGENCY - Callback exception context capture attempted\n"); + } + + CExceptionInformation_Impl* pExceptionInformation = nullptr; + + pExceptionInformation = new (std::nothrow) CExceptionInformation_Impl; + if (pExceptionInformation == nullptr) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::HandleExceptionGlobal - Failed to allocate exception information\n"); + TerminateCurrentProcessWithExitCode(crashExitCode); + return EXCEPTION_EXECUTE_HANDLER; + } + + pExceptionInformation->Set(exceptionCode, pException); + + // Validate that Set() succeeded - if code is 0, Set() failed validation + const DWORD storedCode = pExceptionInformation->GetCode(); + if (storedCode == 0 && exceptionCode != 0) + { + std::array szDebug; + SAFE_DEBUG_PRINT_C(szDebug.data(), szDebug.size(), "CCrashDumpWriter: CRITICAL - Set() failed, stored code is 0 (expected 0x%08X)\n", exceptionCode); + + // This may occur due to null/corrupted context - try to salvage what we can + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Set() failed (likely null/corrupted context) - proceeding with minimal info\n"); + // Continue processing with whatever partial info we have + } + else if (storedCode != exceptionCode) + { + std::array szDebug; + SAFE_DEBUG_PRINT_C(szDebug.data(), szDebug.size(), "CCrashDumpWriter: WARNING - Exception code mismatch after Set() (expected 0x%08X, got 0x%08X)\n", + exceptionCode, storedCode); + } + + WriteDebugEvent("CCrashDumpWriter::HandleExceptionGlobal"); + + bool bClientHandled = false; + bool coreLogSucceeded = false; + bool miniDumpSucceeded = false; + bool crashDialogShown = false; + + // Skip client hook for callback exceptions - addresses may be system trampolines + if (!isCallbackException) + { + CModManager* pModManager = CModManager::GetSingletonPtr(); + if (pModManager != nullptr && pModManager->IsLoaded()) + { + CClientBase* pClient = pModManager->GetClient(); + bool bHandled = false; + const bool bHandledSafely = InvokeClientHandleExceptionSafe(pClient, pExceptionInformation, bHandled); + + if (bHandledSafely && bHandled) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Client handled exception - continuing execution\n"); + delete pExceptionInformation; + return EXCEPTION_CONTINUE_SEARCH; + } + + if (!bHandledSafely) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Client exception handler failed - forcing crash dump\n"); + } + + bClientHandled = true; + } + } + else + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Skipping client hook for callback exception (may re-enter broken callback)\n"); + } + + ms_uiTickCountBase = GetTickCount32(); + + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Generating crash artifacts...\n"); + + // Enhanced emergency logging for all exceptions to track dump generation progress + if (isCallbackException) + { + OutputDebugStringSafe("CCrashDumpWriter: EMERGENCY - Callback exception attempting core log\n"); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Callback exception - attempting dump generation despite potential secondary faults\n"); + } + + try + { + if (isCallbackException) + { + OutputDebugStringSafe("CCrashDumpWriter: EMERGENCY - Starting DumpCoreLog\n"); + } + DumpCoreLog(pException, pExceptionInformation); + coreLogSucceeded = true; + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Core log dumped successfully\n"); + if (isCallbackException) + { + OutputDebugStringSafe("CCrashDumpWriter: EMERGENCY - DumpCoreLog succeeded\n"); + } + } + catch (...) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: ERROR - Failed to dump core log\n"); + if (isCallbackException) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Callback exception may have caused secondary fault during core log\n"); + } + } + + try + { + if (isCallbackException) + { + OutputDebugStringSafe("CCrashDumpWriter: EMERGENCY - Starting DumpMiniDump for callback exception\n"); + } + DumpMiniDump(pException, pExceptionInformation); + miniDumpSucceeded = true; + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Mini dump created successfully\n"); + if (isCallbackException) + { + OutputDebugStringSafe("CCrashDumpWriter: EMERGENCY - DumpMiniDump succeeded for callback exception\n"); + } + } + catch (...) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: ERROR - Failed to create mini dump\n"); + if (isCallbackException) + { + OutputDebugStringSafe("CCrashDumpWriter: EMERGENCY - DumpMiniDump FAILED for callback exception\n"); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Callback exception may have caused secondary fault during minidump\n"); + } + } + + try + { + if (isCallbackException) + { + OutputDebugStringSafe("CCrashDumpWriter: EMERGENCY - Starting RunErrorTool for callback exception\n"); + } + crashDialogShown = RunErrorTool(pExceptionInformation); + if (crashDialogShown) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Error dialog launched successfully\n"); + if (isCallbackException) + { + OutputDebugStringSafe("CCrashDumpWriter: EMERGENCY - RunErrorTool succeeded for callback exception\n"); + } + } + } + catch (...) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: ERROR - Failed to launch error dialog\n"); + if (isCallbackException) + { + OutputDebugStringSafe("CCrashDumpWriter: EMERGENCY - RunErrorTool FAILED for callback exception\n"); + } + } + + struct CrashStage + { + const char* name; + bool succeeded; + }; + + const std::array crashStages{{ + {"core", coreLogSucceeded}, + {"dump", miniDumpSucceeded}, + {"dialog", crashDialogShown}, + }}; + + const bool crashArtifactsGenerated = std::any_of(crashStages.cbegin(), crashStages.cbegin() + 2, [](const CrashStage& stage) { return stage.succeeded; }); + const bool crashHandlingComplete = std::all_of(crashStages.cbegin(), crashStages.cend(), [](const CrashStage& stage) { return stage.succeeded; }); + + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: ======================================\n"); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Crash processing complete - terminating\n"); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: ======================================\n"); + + if (isCallbackException) + { + OutputDebugStringSafe("CCrashDumpWriter: EMERGENCY - Callback exception processing completed, about to terminate\n"); + } + + delete pExceptionInformation; + pExceptionInformation = nullptr; + + UniqueHandle crashDialogProcessHandle{ms_hCrashDialogProcess}; + const bool hadCrashDialogProcess = static_cast(crashDialogProcessHandle); + ms_hCrashDialogProcess = nullptr; + + if (hadCrashDialogProcess) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Detaching from crash dialog process before termination\n"); + } + + if (!hadCrashDialogProcess && crashDialogShown) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: No process handle (likely ShellExecute path), polling for dialog window...\n"); + + HWND hDialogWindow = nullptr; + for (std::size_t attempts = 0; attempts < MAX_WINDOW_POLL_ATTEMPTS && hDialogWindow == nullptr; ++attempts) + { + hDialogWindow = FindWindowW(nullptr, L"MTA: San Andreas has encountered a problem"); + if (hDialogWindow == nullptr) + Sleep(Milliseconds(WINDOW_POLL_TIMEOUT)); + } + + if (hDialogWindow != nullptr && IsWindow(hDialogWindow)) + { + SAFE_DEBUG_OUTPUT(SString("CCrashDumpWriter: Found dialog window %p, waiting for it to close...\n", hDialogWindow).c_str()); + + while (true) + { + if (!IsWindow(hDialogWindow)) + break; + Sleep(Milliseconds(WINDOW_POLL_TIMEOUT)); + } + + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Dialog window closed\n"); + } + else + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Could not find dialog window, waiting 500ms as fallback\n"); + Sleep(Milliseconds(PROCESS_WAIT_TIMEOUT)); + } + } + else if (!crashDialogShown) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Crash dialog was not shown; skipping dialog wait\n"); + Sleep(Milliseconds(PROCESS_WAIT_TIMEOUT)); + } + else if (!crashArtifactsGenerated) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: No dialog process and no artifacts generated (early termination)\n"); + Sleep(Milliseconds(PROCESS_WAIT_TIMEOUT)); + } + + if (!crashHandlingComplete) + { + std::array crashStageStatuses{}; + std::transform(crashStages.cbegin(), crashStages.cend(), crashStageStatuses.begin(), + [](const CrashStage& stage) { return stage.succeeded ? "ok" : "fail"; }); + + AddReportLog(3146, SString("Crash handler incomplete (code=0x%08X core=%s dump=%s dialog=%s)", static_cast(crashExitCode), + crashStageStatuses[0], crashStageStatuses[1], crashStageStatuses[2])); + } + + SAFE_DEBUG_OUTPUT("CCrashDumpWriter: Force terminating crashed process NOW\n"); + if (isCallbackException) + { + OutputDebugStringSafe("CCrashDumpWriter: EMERGENCY - About to call TerminateProcess for callback exception\n"); + } + TerminateCurrentProcessWithExitCode(crashExitCode); + + return EXCEPTION_EXECUTE_HANDLER; +} + +void CCrashDumpWriter::DumpCoreLog(_EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation) +{ + if (pExceptionInformation == nullptr) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpCoreLog - nullptr exception information\n"); + return; + } + + if (!SharedUtil::IsReadablePointer(pExceptionInformation, sizeof(CExceptionInformation))) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpCoreLog - Invalid exception information pointer\n"); + return; + } + + // Use direct Win32 API to bypass potentially broken CRT after severe exceptions + // (stack corruption, buffer overruns, invalid parameters can all corrupt CRT state) + bool flagFileCreated = false; + const auto hFlagFile = CreateFileA(CalcMTASAPath("mta\\core.log.flag"), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (hFlagFile != INVALID_HANDLE_VALUE) + { + const char* flagData = "crash\n"; + DWORD bytesWritten = 0; + WriteFile(hFlagFile, flagData, static_cast(strlen(flagData)), &bytesWritten, nullptr); + CloseHandle(hFlagFile); + flagFileCreated = true; + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpCoreLog - Flag file created via Win32 API\n"); + } + else + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpCoreLog - Failed to create crash flag file via Win32 API\n"); + // Fallback: try CRT in case Win32 failed + if (FILE* pFlagFile = File::Fopen(CalcMTASAPath("mta\\core.log.flag"), "w")) + { + fclose(pFlagFile); + flagFileCreated = true; + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpCoreLog - Flag file created via CRT fallback\n"); + } + } + + time_t timeTemp; + time(&timeTemp); + + const auto strMTAVersionFull = SString("%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting("mta-version-ext").SplitRight(".", nullptr, -2)); + + constexpr auto kNullInstructionPointer = 0u; + static_assert(kNullInstructionPointer == 0u, "Null instruction pointer must be zero"); + + const auto eip = pExceptionInformation->GetEIP(); + const auto isNullJump = (eip == kNullInstructionPointer); + + constexpr std::string_view kNullJumpAnnotation = " (attempted jump to null)"; + constexpr std::string_view kEmptyAnnotation = ""; + const auto eipAnnotation = isNullJump ? kNullJumpAnnotation : kEmptyAnnotation; + + SString strInfo{}; + strInfo += SString("Version = %s\n", strMTAVersionFull.c_str()); + strInfo += SString("Time = %s", ctime(&timeTemp)); + strInfo += SString("Module = %s\n", pExceptionInformation->GetModulePathName()); + strInfo += SString("Code = 0x%08X\n", pExceptionInformation->GetCode()); + strInfo += SString("Offset = 0x%08X\n\n", pExceptionInformation->GetAddressModuleOffset()); + + // Add special notice for watchdog timeout exceptions + if (const auto exceptionCode = pExceptionInformation->GetCode(); exceptionCode == CUSTOM_EXCEPTION_CODE_WATCHDOG_TIMEOUT) + { + constexpr std::string_view kWatchdogBanner = + "========================================\n" + "GAME FREEZE: FORCED CRASH GENERATION FOR INVESTIGATION\n" + "Stack Arrow marks frozen function/loop\n" + "========================================\n\n"; + strInfo += SString{kWatchdogBanner.data(), kWatchdogBanner.size()}; + } + + strInfo += SString( + "EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESI=%08X\n" + "EDI=%08X EBP=%08X ESP=%08X EIP=%08X%.*s FLG=%08X\n" + "CS=%04X DS=%04X SS=%04X ES=%04X FS=%04X GS=%04X\n\n", + pExceptionInformation->GetEAX(), pExceptionInformation->GetEBX(), pExceptionInformation->GetECX(), pExceptionInformation->GetEDX(), + pExceptionInformation->GetESI(), pExceptionInformation->GetEDI(), pExceptionInformation->GetEBP(), pExceptionInformation->GetESP(), + pExceptionInformation->GetEIP(), static_cast(eipAnnotation.size()), eipAnnotation.data(), pExceptionInformation->GetEFlags(), + pExceptionInformation->GetCS(), pExceptionInformation->GetDS(), pExceptionInformation->GetSS(), pExceptionInformation->GetES(), + pExceptionInformation->GetFS(), pExceptionInformation->GetGS()); + + const auto invalidParameterCount = ms_uiInvalidParameterCount.load(std::memory_order_relaxed); + strInfo += SString("InvalidParameterCount = %u\n", invalidParameterCount); + strInfo += SString("CrashZone = %u\n", ms_uiInCrashZone); + strInfo += SString("ThreadId = %u\n\n", GetCurrentThreadId()); + + if (auto pendingWarning = GetApplicationSetting("diagnostics", "pending-invalid-parameter-warning"); !pendingWarning.empty()) + { + strInfo += pendingWarning; + } + + EnsureCrashReasonForDialog(pExceptionInformation); + + SString strDetailed; + SString strDetailedForDialog; + bool hasDetailedSection = false; + bool hasDetailedSectionForDialog = false; + + struct DetailedAppender + { + SString& buffer; + SString& bufferForDialog; + bool& hasSection; + bool& hasSectionForDialog; + bool skipFromDialog; + + void EnsureSectionHeader() const + { + if (!hasSection) + { + buffer += "\n"; + hasSection = true; + } + if (!skipFromDialog && !hasSectionForDialog) + { + bufferForDialog += "\n"; + hasSectionForDialog = true; + } + } + + void operator()(const SString& line, bool excludeFromDialog = false) const + { + if (line.empty()) + return; + + EnsureSectionHeader(); + buffer += line; + if (!excludeFromDialog) + bufferForDialog += line; + } + + void operator()(const char* text, bool excludeFromDialog = false) const + { + if (text == nullptr || *text == '\0') + return; + + EnsureSectionHeader(); + buffer += text; + if (!excludeFromDialog) + bufferForDialog += text; + } + } appendDetailedLine{strDetailed, strDetailedForDialog, hasDetailedSection, hasDetailedSectionForDialog, false}; + + bool telemetryNotePresent = false; + + const auto appendTelemetryNoteIfMissing = [&]() + { + if (telemetryNotePresent) + return; + + if (auto telemetryNote = CrashTelemetry::BuildAllocationTelemetryNote(); !telemetryNote.empty()) + { + appendDetailedLine(SString("Additional Info: %s\n", telemetryNote.c_str())); + telemetryNotePresent = true; + } + }; + + ENHANCED_EXCEPTION_INFO enhancedInfo = {}; + bool hasEnhancedInfo = false; + + const std::vector* stackFrames = nullptr; + std::optional> fallbackStackStorage; + const char* stackHeader = nullptr; + + try + { + hasEnhancedInfo = GetEnhancedExceptionInfo(&enhancedInfo) != FALSE; + if (hasEnhancedInfo) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpCoreLog - Using enhanced exception info from CrashHandler\n"); + } + else + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpCoreLog - No enhanced exception info available, using local data\n"); + } + } + catch (...) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpCoreLog - Exception while querying enhanced info\n"); + hasEnhancedInfo = false; + } + + CExceptionInformation_Impl* pImpl = dynamic_cast(pExceptionInformation); + + if (hasEnhancedInfo) + { + const auto timePoint = enhancedInfo.timestamp; + const auto timeT = std::chrono::system_clock::to_time_t(timePoint); + const auto milliseconds = std::chrono::duration_cast(timePoint.time_since_epoch()) % 1000; + + if (std::tm* tmInfo = std::localtime(&timeT)) + { + const int year = std::clamp(tmInfo->tm_year + 1900, 1900, 9999); + const int month = std::clamp(tmInfo->tm_mon + 1, 1, 12); + const int day = std::clamp(tmInfo->tm_mday, 1, 31); + const int hour = std::clamp(tmInfo->tm_hour, 0, 23); + const int minute = std::clamp(tmInfo->tm_min, 0, 59); + const int second = std::clamp(tmInfo->tm_sec, 0, 59); + + const long long msValue = std::clamp(milliseconds.count(), 0LL, 999LL); + + appendDetailedLine(SString("Precise crash time: %04d-%02d-%02d %02d:%02d:%02d.%03lld\n", year, month, day, hour, minute, second, msValue)); + } + + appendDetailedLine(SString("Thread ID: %lu\n", enhancedInfo.threadId), true); + appendDetailedLine(SString("Process ID: %lu\n", enhancedInfo.processId), true); + + if (!enhancedInfo.exceptionType.empty()) + appendDetailedLine(SString("Exception Type: %s\n", enhancedInfo.exceptionType.c_str())); + + if (!enhancedInfo.exceptionDescription.empty()) + appendDetailedLine(SString("Exception: %s\n", enhancedInfo.exceptionDescription.c_str())); + + if (enhancedInfo.stackTrace.has_value() && !enhancedInfo.stackTrace->empty()) + { + stackFrames = &enhancedInfo.stackTrace.value(); + stackHeader = "Stack trace:\n"; + } + + if (!enhancedInfo.modulePathName.empty()) + appendDetailedLine(SString("Resolved Module Path: %s\n", enhancedInfo.modulePathName.c_str())); + + if (!enhancedInfo.moduleBaseName.empty()) + appendDetailedLine(SString("Resolved Module Base: %s\n", enhancedInfo.moduleBaseName.c_str())); + + appendDetailedLine(SString("Resolved Module Offset: 0x%08X\n", enhancedInfo.moduleOffset)); + + if (!enhancedInfo.additionalInfo.empty()) + { + appendDetailedLine(SString("Additional Info: %s\n", enhancedInfo.additionalInfo.c_str())); + if (enhancedInfo.additionalInfo.find("Allocation telemetry") != std::string::npos) + telemetryNotePresent = true; + } + + if (enhancedInfo.capturedException.has_value()) + { + appendDetailedLine("Captured C++ exception: Yes\n"); + appendDetailedLine(SString("Uncaught exception count: %d\n", enhancedInfo.uncaughtExceptionCount)); + } + + appendDetailedLine(SString("Fatal Exception: %s\n", enhancedInfo.isFatal ? "Yes" : "No")); + } + else if (pImpl != nullptr) + { + auto timestamp = pImpl->GetTimestamp(); + if (timestamp.has_value()) + { + const auto timePoint = timestamp.value(); + const auto timeT = std::chrono::system_clock::to_time_t(timePoint); + const auto milliseconds = std::chrono::duration_cast(timePoint.time_since_epoch()) % 1000; + + if (std::tm* tmInfo = std::localtime(&timeT)) + { + long long msValue = milliseconds.count(); + if (msValue < 0) + msValue = 0; + else if (msValue > 999) + msValue = 999; + + appendDetailedLine(SString("Precise crash time: %04d-%02d-%02d %02d:%02d:%02d.%03lld\n", tmInfo->tm_year + 1900, tmInfo->tm_mon + 1, + tmInfo->tm_mday, tmInfo->tm_hour, tmInfo->tm_min, tmInfo->tm_sec, msValue)); + } + } + + appendDetailedLine(SString("Thread ID: %lu\n", pImpl->GetThreadId()), true); + appendDetailedLine(SString("Process ID: %lu\n", pImpl->GetProcessId()), true); + + std::string description = pImpl->GetExceptionDescription(); + if (!description.empty()) + appendDetailedLine(SString("Exception: %s\n", description.c_str())); + + auto capturedException = pImpl->GetCapturedException(); + if (capturedException.has_value()) + { + appendDetailedLine("Captured C++ exception: Yes\n"); + appendDetailedLine(SString("Uncaught exception count: %d\n", pImpl->GetUncaughtExceptionCount())); + } + } + else + { + appendDetailedLine("Enhanced exception diagnostics unavailable.\n"); + } + + // Registry-resolved module info (independent source of truth with IDA-compatible offsets) + // This uses pre-captured module bases from before the crash occurred + if (pImpl != nullptr && pImpl->HasResolvedModuleInfo()) + { + appendDetailedLine("\n"); + appendDetailedLine("=== Registry-Resolved Module Info (IDA-compatible) ===\n"); + appendDetailedLine(SString("Resolved Module: %s\n", pImpl->GetResolvedModuleName())); + appendDetailedLine(SString("Resolved Module Base: 0x%08X\n", pImpl->GetResolvedModuleBase())); + appendDetailedLine(SString("Resolved RVA: 0x%08X\n", pImpl->GetResolvedRva())); + appendDetailedLine(SString("Resolved IDA Address: 0x%08X\n", pImpl->GetResolvedIdaAddress())); + appendDetailedLine("======================================================\n"); + } + + appendTelemetryNoteIfMissing(); + + // Try to get stack trace from detailed exception information + if (stackFrames == nullptr && pImpl != nullptr && pImpl->HasDetailedStackTrace()) + { + if (auto stackTrace = pImpl->GetStackTrace(); stackTrace.has_value() && !stackTrace->empty()) + { + fallbackStackStorage = std::move(*stackTrace); + stackFrames = std::addressof(*fallbackStackStorage); + stackHeader = hasEnhancedInfo ? "Stack trace (local capture):\n" : "Stack trace:\n"; + } + } + + // If still no stack trace, try to capture one directly from exception pointers + if (stackFrames == nullptr && pException != nullptr) + { + if (SString stackText; CaptureStackTraceText(pException, stackText) && !stackText.empty()) + { + constexpr std::size_t kTypicalStackDepth = 50; + static_assert(kTypicalStackDepth > 0, "Stack depth must be positive"); + + std::vector lines{}; + lines.reserve(kTypicalStackDepth); + stackText.Split("\n", lines); + + if (const auto lineCount = lines.size(); lineCount > 0) + { + std::vector capturedFrames{}; + capturedFrames.reserve(lineCount); + + std::transform(lines.cbegin(), lines.cend(), std::back_inserter(capturedFrames), + [](const auto& line) -> std::string { return std::string{line.c_str()}; }); + + const auto newEnd = std::remove_if(capturedFrames.begin(), capturedFrames.end(), [](const auto& frame) -> bool { return frame.empty(); }); + capturedFrames.erase(newEnd, capturedFrames.end()); + + if (const auto capturedCount = capturedFrames.size(); capturedCount > 0) + { + fallbackStackStorage = std::move(capturedFrames); + stackFrames = std::addressof(*fallbackStackStorage); + stackHeader = "Stack trace (captured):\n"; + } + } + } + else if (pException->ContextRecord != nullptr && pException->ContextRecord->Eip == 0) + { + // Special case: EIP=0 means we cannot walk the stack + // Provide register-based context instead + constexpr std::size_t kRegisterFrameCount = 3; + static_assert(kRegisterFrameCount > 0, "Register frame count must be positive"); + + std::vector registerFrames{}; + registerFrames.reserve(kRegisterFrameCount); + + const auto* ctx = pException->ContextRecord; + registerFrames.emplace_back(SString("EIP=0x%08X (null instruction pointer - cannot walk stack)", ctx->Eip).c_str()); + registerFrames.emplace_back(SString("ESP=0x%08X EBP=0x%08X (stack pointers)", ctx->Esp, ctx->Ebp).c_str()); + registerFrames.emplace_back(SString("Last known address: check return address at [ESP] or recent call history", 0).c_str()); + + fallbackStackStorage = std::move(registerFrames); + stackFrames = std::addressof(*fallbackStackStorage); + stackHeader = "Stack trace (EIP=0 - register context only):\n"; + } + } + + if (stackFrames != nullptr) + { + constexpr std::size_t kMaxDisplayFrames = 100; + constexpr std::size_t kMaxFrameLength = 512; + static_assert(kMaxDisplayFrames > 0 && kMaxFrameLength > 0, "Display limits must be positive"); + + const auto& frames = *stackFrames; + const auto frameCount = frames.size(); + const auto maxFrames = std::clamp(frameCount, std::size_t{0}, kMaxDisplayFrames); + + if (stackHeader == nullptr) + stackHeader = "Stack trace:\n"; + + // For watchdog timeouts, add explanatory note about freeze point + const bool isWatchdogTimeout = pExceptionInformation != nullptr && pExceptionInformation->GetCode() == CUSTOM_EXCEPTION_CODE_WATCHDOG_TIMEOUT; + + if (isWatchdogTimeout && maxFrames > 0) + { + appendDetailedLine("Stack trace (captured from frozen thread - first frame shows freeze location):\n"); + } + else + { + appendDetailedLine(stackHeader); + } + + [[maybe_unused]] const auto allFramesValid = std::all_of(frames.cbegin(), std::next(frames.cbegin(), static_cast(maxFrames)), + [](const auto& frame) constexpr -> bool { return !frame.empty(); }); + + for (std::size_t i{}; i < maxFrames; ++i) + { + const auto& frame = frames[i]; + const std::size_t frameLength = std::clamp(frame.length(), std::size_t{0}, kMaxFrameLength); + + // First frame in watchdog timeout = exact freeze location + if (isWatchdogTimeout && i == 0) + { + appendDetailedLine(SString("--> %.*s <-- FREEZE POINT\n", static_cast(frameLength), frame.c_str())); + } + else + { + appendDetailedLine(SString(" %.*s\n", static_cast(frameLength), frame.c_str())); + } + } + } + else + { + appendDetailedLine("Stack trace: unavailable\n"); + } + + // Get crash dump file path if available + const auto dumpFileInfo = [dumpFilePath = GetApplicationSetting("diagnostics", "last-dump-save")]() -> SString + { + if (dumpFilePath.empty()) + return {}; + + constexpr std::string_view kDumpFileHeader = "\nCrash dump file: "; + return SString{kDumpFileHeader.data(), kDumpFileHeader.size()} + dumpFilePath + "\n"; + }(); + + FILE* pFile = File::Fopen(CalcMTASAPath("mta\\core.log"), "a+"); + if (pFile != nullptr) + { + fprintf(pFile, "%s", "** -- Unhandled exception -- **\n\n"); + fprintf(pFile, "%s", strInfo.c_str()); + + if (!strDetailed.empty()) + fprintf(pFile, "%s", strDetailed.c_str()); + + if (!dumpFileInfo.empty()) + fprintf(pFile, "%s", dumpFileInfo.c_str()); + + fprintf(pFile, "%s", "** -- End of unhandled exception -- **\n\n\n"); + fclose(pFile); + } + else + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpCoreLog - Failed to open core.log file\n"); + } + + SString strInfoForSettings = strInfo; + if (!strDetailedForDialog.empty()) + { + strInfoForSettings += strDetailedForDialog; + } + + if (!dumpFileInfo.empty()) + { + strInfoForSettings += dumpFileInfo; + } + + if (strInfoForSettings.empty()) + strInfoForSettings = "** Crash info unavailable **\n"; + + SetApplicationSetting("diagnostics", "last-crash-info", strInfoForSettings); + SetApplicationSetting("diagnostics", "last-crash-module", pExceptionInformation->GetModulePathName()); + SetApplicationSettingInt("diagnostics", "last-crash-code", pExceptionInformation->GetCode()); + SetApplicationSetting("diagnostics", "last-crash-extra", ""); + SetApplicationSetting("diagnostics", "pending-invalid-parameter-warning", ""); + + // Store registry-resolved module info as separate diagnostic settings + if (pImpl != nullptr && pImpl->HasResolvedModuleInfo()) + { + SetApplicationSetting("diagnostics", "last-crash-resolved-module", pImpl->GetResolvedModuleName()); + SetApplicationSetting("diagnostics", "last-crash-resolved-ida-addr", SString("0x%08X", pImpl->GetResolvedIdaAddress())); + } + else + { + SetApplicationSetting("diagnostics", "last-crash-resolved-module", ""); + SetApplicationSetting("diagnostics", "last-crash-resolved-ida-addr", ""); + } + + SString strInfoForDebug = strInfoForSettings; + strInfoForDebug.Replace("\n", " "); + WriteDebugEvent(strInfoForDebug); +} + +void CCrashDumpWriter::DumpMiniDump(_EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation) +{ + WriteDebugEvent("CCrashDumpWriter::DumpMiniDump"); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpMiniDump - Starting minidump creation...\n"); + + bool bMiniDumpSucceeded = false; + + constexpr const char* kDbgHelpDllName = "DBGHELP.DLL"; + + HMODULE hDll = nullptr; + std::array modulePath{}; + DWORD moduleLen = GetModuleFileNameA(nullptr, modulePath.data(), static_cast(modulePath.size())); + + if (moduleLen == 0) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpMiniDump - GetModuleFileNameA failed\n"); + } + else if (moduleLen >= modulePath.size()) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpMiniDump - Module path truncated\n"); + } + else + { + char* pSlash = strrchr(modulePath.data(), '\\'); + if (pSlash != nullptr) + { + const std::size_t dirLength = static_cast(pSlash - modulePath.data()) + 1; + const std::size_t remainingSpace = modulePath.size() - dirLength; + const std::size_t requiredSpace = std::strlen(kDbgHelpDllName) + 1; + + if (remainingSpace >= requiredSpace) + { + std::memcpy(pSlash + 1, kDbgHelpDllName, requiredSpace); + hDll = LoadLibraryA(modulePath.data()); + } + else + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpMiniDump - Not enough space to append DBGHELP.DLL\n"); + } + } + } + + if (hDll == nullptr) + { + std::array systemPath{}; + UINT systemLen = GetSystemDirectoryA(systemPath.data(), static_cast(systemPath.size())); + + if (systemLen == 0) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpMiniDump - GetSystemDirectoryA failed\n"); + } + else if (systemLen >= systemPath.size()) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpMiniDump - System directory path truncated\n"); + } + else + { + const std::size_t dllNameLen = std::strlen(kDbgHelpDllName); + std::size_t appendIndex = static_cast(systemLen); + + if (appendIndex > 0 && systemPath[appendIndex - 1] != '\\') + { + if (appendIndex + 1 < systemPath.size()) + { + systemPath[appendIndex++] = '\\'; + } + else + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpMiniDump - No space to append backslash to system path\n"); + appendIndex = std::numeric_limits::max(); + } + } + + if (appendIndex != std::numeric_limits::max()) + { + const std::size_t required = appendIndex + dllNameLen + 1; + if (required <= systemPath.size()) + { + std::memcpy(systemPath.data() + appendIndex, kDbgHelpDllName, dllNameLen + 1); + hDll = LoadLibraryA(systemPath.data()); + } + else + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpMiniDump - System path too long for DBGHELP.DLL\n"); + } + } + } + } + + if (hDll == nullptr) + AddReportLog(9201, "CCrashDumpWriter::DumpMiniDump - Could not load DBGHELP.DLL"); + + if (hDll != nullptr) + { + if (MINIDUMPWRITEDUMP pDump = nullptr; SharedUtil::TryGetProcAddress(hDll, "MiniDumpWriteDump", pDump)) + { + const auto hFile = + CreateFileA(CalcMTASAPath("mta\\core.dmp"), GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (hFile == INVALID_HANDLE_VALUE) + AddReportLog(9203, SString("CCrashDumpWriter::DumpMiniDump - Could not create '%s'", *CalcMTASAPath("mta\\core.dmp"))); + + if (hFile != INVALID_HANDLE_VALUE) + { + _MINIDUMP_EXCEPTION_INFORMATION ExInfo{}; + ExInfo.ThreadId = GetCurrentThreadId(); + ExInfo.ExceptionPointers = pException; + ExInfo.ClientPointers = FALSE; + + MinidumpUserStreamCollection userStreams; + + const std::string telemetryNote = CrashTelemetry::BuildAllocationTelemetryNote(); + std::string basicSummary; + ENHANCED_EXCEPTION_INFO enhancedInfo{}; + const bool hasEnhancedInfo = (GetEnhancedExceptionInfo(&enhancedInfo) != FALSE); + + if (hasEnhancedInfo) + { + userStreams.AddTextStream(kStreamExceptionSummary, FormatExceptionSummary(enhancedInfo)); + userStreams.AddTextStream(kStreamStackTrace, FormatStackTrace(enhancedInfo)); + userStreams.AddTextStream(kStreamRegisterState, FormatRegisterDump(enhancedInfo)); + userStreams.AddTextStream(kStreamCapturedException, FormatCapturedExceptionInfo(enhancedInfo)); + } + else + { + basicSummary = BuildBasicExceptionSummary(pException, pExceptionInformation); + userStreams.AddTextStream(kStreamExceptionSummary, basicSummary); + } + + const std::string additionalInfoPayload = BuildAdditionalInfoPayload(hasEnhancedInfo ? &enhancedInfo : nullptr, telemetryNote, + hasEnhancedInfo ? std::string_view{} : std::string_view{basicSummary}); + userStreams.AddTextStream(kStreamAdditionalInfo, additionalInfoPayload); + + PMINIDUMP_USER_STREAM_INFORMATION userStreamParam = userStreams.Build(); + + BOOL bResult = pDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, + static_cast(MiniDumpNormal | MiniDumpWithIndirectlyReferencedMemory), &ExInfo, userStreamParam, nullptr); + + if (!bResult) + { + const DWORD dwError = GetLastError(); + AddReportLog(9204, SString("CCrashDumpWriter::DumpMiniDump - MiniDumpWriteDump failed (%08x)", dwError)); + SAFE_DEBUG_OUTPUT(SString("CCrashDumpWriter::DumpMiniDump - MiniDumpWriteDump FAILED with error 0x%08X\n", dwError).c_str()); + + // Retry with simpler dump type on partial copy errors (corrupted stacks, inaccessible memory) + if (dwError == 0x8007012B || dwError == ERROR_PARTIAL_COPY) // ERROR_PARTIAL_COPY + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpMiniDump - Retrying with MiniDumpNormal only (no indirect memory)\n"); + SetFilePointer(hFile, 0, nullptr, FILE_BEGIN); + SetEndOfFile(hFile); + + bResult = pDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, userStreamParam, nullptr); + if (bResult) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpMiniDump - Retry with MiniDumpNormal succeeded\n"); + bMiniDumpSucceeded = true; + } + else + { + SAFE_DEBUG_OUTPUT(SString("CCrashDumpWriter::DumpMiniDump - Retry also failed with error 0x%08X\n", GetLastError()).c_str()); + } + } + } + else + { + WriteDebugEvent("CCrashDumpWriter::DumpMiniDump - MiniDumpWriteDump succeeded"); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpMiniDump - MiniDumpWriteDump succeeded\n"); + bMiniDumpSucceeded = true; + } + + CloseHandle(hFile); + + SYSTEMTIME SystemTime; + GetLocalTime(&SystemTime); + + if (!CreateDirectoryA(CalcMTASAPath("mta\\dumps"), nullptr)) + { + if (const auto dwError = GetLastError(); dwError != ERROR_ALREADY_EXISTS) + { + AddReportLog(9207, SString("CCrashDumpWriter::DumpMiniDump - Failed to create dumps directory (%08x)", dwError)); + } + } + + if (!CreateDirectoryA(CalcMTASAPath("mta\\dumps\\private"), nullptr)) + { + if (const auto dwError = GetLastError(); dwError != ERROR_ALREADY_EXISTS) + { + AddReportLog(9208, SString("CCrashDumpWriter::DumpMiniDump - Failed to create private dumps directory (%08x)", dwError)); + } + } + + SString strModuleName = pExceptionInformation->GetModuleBaseName(); + strModuleName = strModuleName.ReplaceI(".dll", "").Replace(".exe", "").Replace("_", "").Replace(".", "").Replace("-", ""); + if (strModuleName.length() == 0) + strModuleName = "unknown"; + + const auto strMTAVersionFull = SString("%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting("mta-version-ext").SplitRight(".", nullptr, -2)); + const auto strSerialPart = GetApplicationSetting("serial").substr(0, 5); + const auto uiServerIP = GetApplicationSettingInt("last-server-ip"); + const auto uiServerPort = GetApplicationSettingInt("last-server-port"); + const auto uiServerTime = GetApplicationSettingInt("last-server-time"); + const __time64_t currentTime = _time64(nullptr); + + __int64 rawDuration = 0; + if (currentTime != static_cast<__time64_t>(-1)) + { + const __time64_t lastServerTime = static_cast<__time64_t>(uiServerTime); + rawDuration = currentTime - lastServerTime; + } + + rawDuration = std::clamp(rawDuration, static_cast<__int64>(0), std::numeric_limits<__int64>::max() - 1); + + const __int64 adjustedDuration = std::clamp(rawDuration + 1, static_cast<__int64>(1), static_cast<__int64>(0x0fff)); + + const int uiServerDuration = static_cast(adjustedDuration); + + SString strPathCode; + { + std::vector parts; + PathConform(CalcMTASAPath("")).Split(PATH_SEPERATOR, parts); + for (uint i = 0; i < parts.size(); i++) + { + if (!parts[i].empty()) + strPathCode += parts[i].Left(1).ToUpper(); + } + } + + SString strFilename("mta\\dumps\\private\\client_%s_%s_%08x_%x_%s_%08X_%04X_%03X_%s_%04d%02d%02d_%02d%02d.dmp", strMTAVersionFull.c_str(), + strModuleName.c_str(), pExceptionInformation->GetAddressModuleOffset(), pExceptionInformation->GetCode() & 0xffff, + strPathCode.c_str(), uiServerIP, uiServerPort, uiServerDuration, strSerialPart.c_str(), SystemTime.wYear, SystemTime.wMonth, + SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute); + + const SString privateDumpDir = CalcMTASAPath("mta\\dumps\\private"); + const SString strPathFilename = CalcMTASAPath(strFilename); + + if (!ValidatePathWithinBase(privateDumpDir, strPathFilename, 9213)) + { + AddReportLog(9213, SString("CCrashDumpWriter::DumpMiniDump - rejected dump path (%s)", strPathFilename.c_str())); + SetApplicationSetting("diagnostics", "last-dump-extra", "invalid-path"); + SetApplicationSetting("diagnostics", "last-dump-save", ""); + SetApplicationSetting("diagnostics", "last-dump-complete", ""); + } + else + { + const BOOL bCopied = CopyFileA(CalcMTASAPath("mta\\core.dmp"), strPathFilename, FALSE); + if (!bCopied) + { + const DWORD copyError = GetLastError(); + AddReportLog(9209, SString("CCrashDumpWriter::DumpMiniDump - Failed to persist crash dump copy (%08x)", copyError)); + SetApplicationSetting("diagnostics", "last-dump-extra", "copy-failed"); + SetApplicationSetting("diagnostics", "last-dump-save", ""); + SetApplicationSetting("diagnostics", "last-dump-complete", ""); + } + else + { + SetApplicationSetting("diagnostics", "last-dump-extra", "none"); + SetApplicationSetting("diagnostics", "last-dump-save", strPathFilename); + SetApplicationSetting("diagnostics", "last-dump-complete", ""); + + AppendDumpSection(strPathFilename, "try-pools", "added-pools", 'POLs', 'POLe', + [](CBuffer& buffer) { CCrashDumpWriter::GetPoolInfo(buffer); }); + + AppendDumpSection(strPathFilename, "try-d3d", "added-d3d", 'D3Ds', 'D3De', + [](CBuffer& buffer) { CCrashDumpWriter::GetD3DInfo(buffer); }); + + AppendDumpSection(strPathFilename, "try-crash-averted", "added-crash-averted", 'CASs', 'CASe', + [](CBuffer& buffer) { CCrashDumpWriter::GetCrashAvertedStats(buffer); }); + + AppendDumpSection(strPathFilename, "try-log", "added-log", 'LOGs', 'LOGe', + [](CBuffer& buffer) { CCrashDumpWriter::GetLogInfo(buffer); }); + + AppendDumpSection(strPathFilename, "try-misc", "added-misc", 'DXIs', 'DXIe', + [](CBuffer& buffer) { CCrashDumpWriter::GetDxInfo(buffer); }); + + AppendDumpSection(strPathFilename, "try-misc", "added-misc", 'MSCs', 'MSCe', + [](CBuffer& buffer) { CCrashDumpWriter::GetMiscInfo(buffer); }); + + AppendDumpSection(strPathFilename, "try-mem", "added-mem", 'MEMs', 'MEMe', + [](CBuffer& buffer) { CCrashDumpWriter::GetMemoryInfo(buffer); }); + + AppendDumpSection(strPathFilename, "try-logfile", "added-logfile", 'LOGs', 'LOGe', + [](CBuffer& buffer) { buffer.LoadFromFile(CalcMTASAPath(PathJoin("mta", "logs", "logfile.txt"))); }); + + AppendDumpSection(strPathFilename, "try-report", "added-report", 'REPs', 'REPe', + [](CBuffer& buffer) { buffer.LoadFromFile(PathJoin(GetMTADataPath(), "report.log")); }); + + AppendDumpSection(strPathFilename, "try-anim-task", "added-anim-task", 'CATs', 'CATe', + [](CBuffer& buffer) { CCrashDumpWriter::GetCurrentAnimTaskInfo(buffer); }); + + // Mark dump file as complete (all sections appended) + SetApplicationSetting("diagnostics", "last-dump-complete", "1"); + AddReportLog(5201, SString("CCrashDumpWriter::DumpMiniDump - Marked dump file as complete: %s", *strPathFilename)); + } + } + } + } + else + { + AddReportLog(9202, "CCrashDumpWriter::DumpMiniDump - Could not find MiniDumpWriteDump"); + } + + FreeLibrary(hDll); + } + + if (bMiniDumpSucceeded) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpMiniDump - Minidump creation COMPLETED successfully\n"); + } + else + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::DumpMiniDump - Minidump creation FAILED\n"); + AppendFallbackStackTrace(pException); + } + + if (ms_uiInCrashZone == 1 || ms_uiInCrashZone == 2) + { + CVARS_SET("volumetric_shadows", false); + CCore::GetSingleton().SaveConfig(); + AddReportLog(9205, "Disabled volumetric shadows"); + } + + CNet* pNet = CCore::GetSingleton().GetNetwork(); + if (pNet != nullptr) + pNet->PostCrash(); +} + +[[nodiscard]] bool CCrashDumpWriter::RunErrorTool(CExceptionInformation* pExceptionInformation) +{ + static std::atomic bDoneReport{false}; + bool expected = false; + if (!bDoneReport.compare_exchange_strong(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::RunErrorTool - Already called, returning\n"); + return false; + } + + const DWORD exceptionCode = pExceptionInformation->GetCode(); + + if (exceptionCode == 0xC0000409 || exceptionCode == 0xC0000374) + { + SetApplicationSetting("diagnostics", "debugger-crash-capture", "1"); + AddReportLog(7210, SString("Core - Fail-fast crash detected (0x%08X), debugger capture flag SET for next launch", exceptionCode)); + } + + SString strMessage( + "Crash 0x%08X 0x%08X %s" + " EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESI=%08X" + " EDI=%08X EBP=%08X ESP=%08X EIP=%08X FLG=%08X" + " CS=%04X DS=%04X SS=%04X ES=%04X" + " FS=%04X GS=%04X", + pExceptionInformation->GetCode(), pExceptionInformation->GetAddressModuleOffset(), pExceptionInformation->GetModulePathName(), + pExceptionInformation->GetEAX(), pExceptionInformation->GetEBX(), pExceptionInformation->GetECX(), pExceptionInformation->GetEDX(), + pExceptionInformation->GetESI(), pExceptionInformation->GetEDI(), pExceptionInformation->GetEBP(), pExceptionInformation->GetESP(), + pExceptionInformation->GetEIP(), pExceptionInformation->GetEFlags(), pExceptionInformation->GetCS(), pExceptionInformation->GetDS(), + pExceptionInformation->GetSS(), pExceptionInformation->GetES(), pExceptionInformation->GetFS(), pExceptionInformation->GetGS()); + + AddReportLog(3120, strMessage); + + EnsureCrashReasonForDialog(pExceptionInformation); + + AllowSetForegroundWindow(ASFW_ANY); -struct SCrashAvertedInfo -{ - uint uiTickCount; - int uiUsageCount; -}; + ClipCursor(nullptr); + ReleaseCapture(); + SystemParametersInfoW(SPI_SETCURSORS, 0, nullptr, 0); -static std::list ms_LogEventList; -static CDuplicateLineFilter ms_LogEventFilter; -static std::map ms_CrashAvertedMap; -static uint ms_uiTickCountBase = 0; -static void* ms_pReservedMemory = NULL; -static uint ms_uiInCrashZone = 0; -static uint ms_uiInvalidParameterCount = 0; -static uint ms_uiInvalidParameterCountLogged = 0; + auto EnsureCursorVisible = []() + { + int cursorCount = ShowCursor(TRUE); + int loopGuard = 0; + while (cursorCount < 1 && loopGuard++ < 256) + cursorCount = ShowCursor(TRUE); + return cursorCount; + }; -typedef BOOL(WINAPI* MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, - CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, - CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); + EnsureCursorVisible(); -/////////////////////////////////////////////////////////////// -// -// CCrashDumpWriter::OnCrashAverted -// -// Static function. Called everytime a crash is averted -// -/////////////////////////////////////////////////////////////// -void CCrashDumpWriter::OnCrashAverted(uint uiId) -{ - SCrashAvertedInfo* pInfo = MapFind(ms_CrashAvertedMap, uiId); - if (!pInfo) + if (HCURSOR arrowCursor = LoadCursor(nullptr, IDC_ARROW); arrowCursor != nullptr) + SetCursor(arrowCursor); + + const int screenCenterX = GetSystemMetrics(SM_CXSCREEN) / 2; + const int screenCenterY = GetSystemMetrics(SM_CYSCREEN) / 2; + SetCursorPos(screenCenterX, screenCenterY); + + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::RunErrorTool - Restoring desktop display mode\n"); + + for (int retryCount = 0; retryCount < 3; retryCount++) { - MapSet(ms_CrashAvertedMap, uiId, SCrashAvertedInfo()); - pInfo = MapFind(ms_CrashAvertedMap, uiId); - pInfo->uiUsageCount = 0; + const LONG result = ChangeDisplaySettings(nullptr, 0); + if (result == DISP_CHANGE_SUCCESSFUL) + break; + Sleep(300); } - pInfo->uiTickCount = GetTickCount32(); - pInfo->uiUsageCount++; -} -/////////////////////////////////////////////////////////////// -// -// CCrashDumpWriter::OnEnterCrashZone -// -// Static function. Called when entering possible crash zone -// -/////////////////////////////////////////////////////////////// -void CCrashDumpWriter::OnEnterCrashZone(uint uiId) -{ - ms_uiInCrashZone = uiId; -} + DEVMODEW registryMode{}; + registryMode.dmSize = sizeof(registryMode); + DEVMODEW currentMode{}; + currentMode.dmSize = sizeof(currentMode); -/////////////////////////////////////////////////////////////// -// -// CCrashDumpWriter::LogEvent -// -// Static function. -// -/////////////////////////////////////////////////////////////// -void CCrashDumpWriter::LogEvent(const char* szType, const char* szContext, const char* szBody) -{ - ms_LogEventFilter.AddLine({szBody, szType, szContext}); + const BOOL haveRegistryMode = EnumDisplaySettingsExW(nullptr, ENUM_REGISTRY_SETTINGS, ®istryMode, 0); + const BOOL haveCurrentMode = EnumDisplaySettingsExW(nullptr, ENUM_CURRENT_SETTINGS, ¤tMode, 0); - SLogEventLine line; - while (ms_LogEventFilter.PopOutputLine(line)) + if (haveRegistryMode && haveCurrentMode) { - SLogEventInfo info; - info.uiTickCount = GetTickCount32(); - info.strType = line.strType; - info.strContext = line.strContext; - info.strBody = line.strBody; - ms_LogEventList.push_front(info); + const bool modesDiffer = registryMode.dmPelsWidth != currentMode.dmPelsWidth || registryMode.dmPelsHeight != currentMode.dmPelsHeight || + registryMode.dmBitsPerPel != currentMode.dmBitsPerPel || registryMode.dmDisplayFrequency != currentMode.dmDisplayFrequency; - while (ms_LogEventList.size() > LOG_EVENT_SIZE) - ms_LogEventList.pop_back(); + if (modesDiffer) + ChangeDisplaySettingsExW(nullptr, ®istryMode, nullptr, CDS_FULLSCREEN, nullptr); } -} - -/////////////////////////////////////////////////////////////// -// -// CCrashDumpWriter::SetHandlers -// -// Static function. Initialize handlers for crash situations -// -/////////////////////////////////////////////////////////////// -void CCrashDumpWriter::SetHandlers() -{ -#ifndef MTA_DEBUG - _set_invalid_parameter_handler(CCrashDumpWriter::HandleInvalidParameter); - SetCrashHandlerFilter(CCrashDumpWriter::HandleExceptionGlobal); - CCrashDumpWriter::ReserveMemoryKBForCrashDumpProcessing(500); -#endif -} -/////////////////////////////////////////////////////////////// -// -// CCrashDumpWriter::UpdateCounters -// -// Static function. Called every so often, you know -// -/////////////////////////////////////////////////////////////// -void CCrashDumpWriter::UpdateCounters() -{ - if (ms_uiInvalidParameterCount > ms_uiInvalidParameterCountLogged && ms_uiInvalidParameterCountLogged < 10) + HWND hGTAWindow = FindWindowW(L"Grand theft auto San Andreas", nullptr); + if (hGTAWindow == nullptr) + hGTAWindow = FindWindowW(nullptr, L"MTA: San Andreas"); + if (hGTAWindow != nullptr && IsWindow(hGTAWindow)) { - AddReportLog(9206, SString("InvalidParameterCount changed from %d to %d", ms_uiInvalidParameterCountLogged, ms_uiInvalidParameterCount)); - ms_uiInvalidParameterCountLogged = ms_uiInvalidParameterCount; + ShowWindowAsync(hGTAWindow, SW_MINIMIZE); + PostMessageW(hGTAWindow, WM_SYSCOMMAND, SC_MINIMIZE, 0); + + const UINT asyncFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS | SWP_NOZORDER; + if (SetWindowPos(hGTAWindow, HWND_NOTOPMOST, 0, 0, 0, 0, asyncFlags) == FALSE) + { + const DWORD posError = GetLastError(); + AddReportLog(3145, SString("Crash dialog failed to SetWindowPos (async) error %u", posError)); + } } -} -/////////////////////////////////////////////////////////////// -// -// CCrashDumpWriter::HandleInvalidParameter -// -// Static function. Called when an invalid parameter is detected by functions such as printf. -// Can be caused by problems with localized strings. -// -/////////////////////////////////////////////////////////////// -void CCrashDumpWriter::HandleInvalidParameter(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved) -{ - ms_uiInvalidParameterCount++; -} + if (HWND shellWindow = GetShellWindow(); shellWindow != nullptr) + { + ShowWindow(shellWindow, SW_SHOWNORMAL); + SetForegroundWindow(shellWindow); + } -/////////////////////////////////////////////////////////////// -// -// CCrashDumpWriter::ReserveMemoryKBForCrashDumpProcessing -// CCrashDumpWriter::FreeMemoryForCrashDumpProcessing -// -// Static functions. Keep some RAM to help avoid mem problems during crash dump saving -// -/////////////////////////////////////////////////////////////// -void CCrashDumpWriter::ReserveMemoryKBForCrashDumpProcessing(uint uiMemoryKB) -{ - FreeMemoryForCrashDumpProcessing(); - ms_pReservedMemory = malloc(uiMemoryKB * 1024); -} + const auto basePath = GetMTASABaseDir(); -void CCrashDumpWriter::FreeMemoryForCrashDumpProcessing() -{ - if (ms_pReservedMemory) + const auto basePathWide = basePath.empty() ? WString() : FromUTF8(basePath); + if (!basePath.empty() && basePathWide.empty()) { - free(ms_pReservedMemory); - ms_pReservedMemory = NULL; + AddReportLog(3138, "RunErrorTool base path conversion to wide string failed"); } -} -long WINAPI CCrashDumpWriter::HandleExceptionGlobal(_EXCEPTION_POINTERS* pException) -{ - FreeMemoryForCrashDumpProcessing(); + auto RestoreBaseDirectories = [&]() + { + if (basePath.empty()) + return; - // Create the exception information class - CExceptionInformation_Impl* pExceptionInformation = new CExceptionInformation_Impl; - pExceptionInformation->Set(pException->ExceptionRecord->ExceptionCode, pException); + if (basePathWide.empty()) + { + if (!SetCurrentDirectoryA(basePath.c_str())) + { + const DWORD restoreError = GetLastError(); + AddReportLog(3125, SString("RunErrorTool failed to restore current directory (%s) error %u", basePath.c_str(), restoreError)); + } - WriteDebugEvent("CCrashDumpWriter::HandleExceptionGlobal"); + if (!SetDllDirectoryA(basePath.c_str())) + { + const DWORD restoreDllError = GetLastError(); + AddReportLog(3126, SString("RunErrorTool failed to restore DLL directory (%s) error %u", basePath.c_str(), restoreDllError)); + } - // Grab the mod manager - CModManager* pModManager = CModManager::GetSingletonPtr(); - if (pModManager) - { - // Got a client? - if (pModManager->IsLoaded()) + return; + } + + if (!SetCurrentDirectoryW(basePathWide.c_str())) { - // Protect us from "double-faults" - try - { - // Let the client handle it. If it could, continue the execution - if (pModManager->GetClient()->HandleException(pExceptionInformation)) - { - // Delete the exception record and continue to search the exception stack - delete pExceptionInformation; - return EXCEPTION_CONTINUE_SEARCH; - } + const DWORD restoreError = GetLastError(); + AddReportLog(3125, SString("RunErrorTool failed to restore current directory (%s) error %u", basePath.c_str(), restoreError)); + } - // Save tick count now - ms_uiTickCountBase = GetTickCount32(); + if (!SetDllDirectoryW(basePathWide.c_str())) + { + const DWORD restoreDllError = GetLastError(); + AddReportLog(3126, SString("RunErrorTool failed to restore DLL directory (%s) error %u", basePath.c_str(), restoreDllError)); + } + }; - // The client wants us to terminate the process - DumpCoreLog(pExceptionInformation); - DumpMiniDump(pException, pExceptionInformation); - RunErrorTool(pExceptionInformation); - TerminateProcess(GetCurrentProcess(), 1); + if (basePath.empty()) + { + AddReportLog(3125, "RunErrorTool base path empty; skipping initial directory setup"); + } + else + { + if (basePathWide.empty()) + { + AddReportLog(3125, SString("RunErrorTool failed to convert base directory to wide characters (%s)", basePath.c_str())); + if (!SetCurrentDirectoryA(basePath.c_str())) + { + const DWORD baseDirError = GetLastError(); + AddReportLog(3125, SString("RunErrorTool failed to set base current directory (%s) error %u", basePath.c_str(), baseDirError)); } - catch (...) + + if (!SetDllDirectoryA(basePath.c_str())) { - // Double-fault, terminate the process - DumpCoreLog(pExceptionInformation); - DumpMiniDump(pException, pExceptionInformation); - RunErrorTool(pExceptionInformation); - TerminateProcess(GetCurrentProcess(), 1); + const DWORD baseDllError = GetLastError(); + AddReportLog(3126, SString("RunErrorTool failed to set base DLL directory (%s) error %u", basePath.c_str(), baseDllError)); } } else { - // Continue if we're in debug mode, if not terminate - #ifdef MTA_DEBUG - return EXCEPTION_CONTINUE_SEARCH; - #endif + if (!SetCurrentDirectoryW(basePathWide.c_str())) + { + const DWORD baseDirError = GetLastError(); + AddReportLog(3125, SString("RunErrorTool failed to set base current directory (%s) error %u", basePath.c_str(), baseDirError)); + } + + if (!SetDllDirectoryW(basePathWide.c_str())) + { + const DWORD baseDllError = GetLastError(); + AddReportLog(3126, SString("RunErrorTool failed to set base DLL directory (%s) error %u", basePath.c_str(), baseDllError)); + } } } - // Terminate the process - DumpCoreLog(pExceptionInformation); - DumpMiniDump(pException, pExceptionInformation); - RunErrorTool(pExceptionInformation); - TerminateProcess(GetCurrentProcess(), 1); - return EXCEPTION_CONTINUE_SEARCH; -} + constexpr const char* crashArgs = "install_stage=crashed"; + const WString crashArgsWide = FromUTF8(crashArgs); + const size_t crashArgsLength = std::strlen(crashArgs); + if (crashArgsLength > std::numeric_limits::max() - 1) + { + AddReportLog(3129, "RunErrorTool crash arguments unexpectedly large; aborting relaunch"); + return false; + } -void CCrashDumpWriter::DumpCoreLog(CExceptionInformation* pExceptionInformation) -{ - // Write crash flag for next launch (Simple flag in case of double faults later) - fclose(File::Fopen(CalcMTASAPath("mta\\core.log.flag"), "w")); + bool dialogLaunched = false; + const auto candidates = BuildCrashDialogCandidates(); - // Write a log with the generic exception information - FILE* pFile = File::Fopen(CalcMTASAPath("mta\\core.log"), "a+"); - if (pFile) + for (const SString& candidate : candidates) { - // Header - fprintf(pFile, "%s", "** -- Unhandled exception -- **\n\n"); - - // Write the time - time_t timeTemp; - time(&timeTemp); + if (candidate.empty()) + continue; - SString strMTAVersionFull = SString("%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting("mta-version-ext").SplitRight(".", NULL, -2)); + const std::string candidateStd(candidate.c_str()); + bool candidateExists = SharedUtil::FileExists(candidateStd); - SString strInfo; - strInfo += SString("Version = %s\n", strMTAVersionFull.c_str()); - strInfo += SString("Time = %s", ctime(&timeTemp)); + const WString candidateWide = candidate.empty() ? WString() : FromUTF8(candidate); + if (!candidateExists && !candidateWide.empty()) + { + if (const auto attrs = GetFileAttributesW(candidateWide.c_str()); attrs != INVALID_FILE_ATTRIBUTES) + { + candidateExists = (attrs & FILE_ATTRIBUTE_DIRECTORY) == 0; + } + } - strInfo += SString("Module = %s\n", pExceptionInformation->GetModulePathName()); + if (!candidateExists) + { + AddReportLog(3123, SString("RunErrorTool candidate missing (%s)", candidate.c_str())); + continue; + } - // Write the basic exception information - strInfo += SString("Code = 0x%08X\n", pExceptionInformation->GetCode()); - strInfo += SString("Offset = 0x%08X\n\n", pExceptionInformation->GetAddressModuleOffset()); + SString candidateDir = SharedUtil::ExtractPath(candidate); + if (candidateDir.empty()) + candidateDir = basePath; - // Write the register info - strInfo += SString( - "EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESI=%08X\n" - "EDI=%08X EBP=%08X ESP=%08X EIP=%08X FLG=%08X\n" - "CS=%04X DS=%04X SS=%04X ES=%04X " - "FS=%04X GS=%04X\n\n", - pExceptionInformation->GetEAX(), pExceptionInformation->GetEBX(), pExceptionInformation->GetECX(), pExceptionInformation->GetEDX(), - pExceptionInformation->GetESI(), pExceptionInformation->GetEDI(), pExceptionInformation->GetEBP(), pExceptionInformation->GetESP(), - pExceptionInformation->GetEIP(), pExceptionInformation->GetEFlags(), pExceptionInformation->GetCS(), pExceptionInformation->GetDS(), - pExceptionInformation->GetSS(), pExceptionInformation->GetES(), pExceptionInformation->GetFS(), pExceptionInformation->GetGS()); + const WString candidateDirWide = candidateDir.empty() ? basePathWide : FromUTF8(candidateDir); + if (candidateDirWide.empty() && !candidateDir.empty()) + { + AddReportLog(3127, SString("RunErrorTool failed to convert candidate directory to wide characters (%s)", candidateDir.c_str())); + RestoreBaseDirectories(); + continue; + } - fprintf(pFile, "%s", strInfo.c_str()); + const wchar_t* candidateDirWidePtr = candidateDirWide.empty() ? basePathWide.c_str() : candidateDirWide.c_str(); - // End of unhandled exception - fprintf(pFile, "%s", "** -- End of unhandled exception -- **\n\n\n"); + if ((candidateDirWidePtr == nullptr || candidateDirWidePtr[0] == L'\0') && !candidateDir.empty()) + { + AddReportLog(3127, SString("RunErrorTool candidate directory unavailable (%s)", candidateDir.c_str())); + RestoreBaseDirectories(); + continue; + } - // Close the file - fclose(pFile); + if (!SetCurrentDirectoryW(candidateDirWidePtr)) + { + if (const auto candidateDirError = GetLastError()) + { + AddReportLog(3127, SString("RunErrorTool failed to set candidate current directory (%s) error %u", candidateDir.c_str(), candidateDirError)); + } + RestoreBaseDirectories(); + continue; + } - // For the crash dialog - SetApplicationSetting("diagnostics", "last-crash-info", strInfo); - SetApplicationSetting("diagnostics", "last-crash-module", pExceptionInformation->GetModulePathName()); - SetApplicationSettingInt("diagnostics", "last-crash-code", pExceptionInformation->GetCode()); - WriteDebugEvent(strInfo.Replace("\n", " ")); - } -} + if (!SetDllDirectoryW(candidateDirWidePtr)) + { + if (const auto candidateDllError = GetLastError()) + { + AddReportLog(3128, SString("RunErrorTool failed to set candidate DLL directory (%s) error %u", candidateDir.c_str(), candidateDllError)); + } + RestoreBaseDirectories(); + continue; + } -void CCrashDumpWriter::DumpMiniDump(_EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation) -{ - WriteDebugEvent("CCrashDumpWriter::DumpMiniDump"); + auto commandLine = SString("\"%s\" %s", candidate.c_str(), crashArgs); + AddReportLog(3125, SString("RunErrorTool attempting launch with command: %s", commandLine.c_str())); - // Try to load the DLL in our directory - HMODULE hDll = NULL; - char szDbgHelpPath[MAX_PATH]; - if (GetModuleFileNameA(NULL, szDbgHelpPath, MAX_PATH)) - { - char* pSlash = _tcsrchr(szDbgHelpPath, '\\'); - if (pSlash) + const size_t commandLength = commandLine.length(); + if (commandLength == 0 || commandLength > std::numeric_limits::max() - 1) { - _tcscpy(pSlash + 1, "DBGHELP.DLL"); - hDll = LoadLibrary(szDbgHelpPath); + AddReportLog(3130, SString("RunErrorTool produced invalid command line for %s", candidate.c_str())); + RestoreBaseDirectories(); + continue; } - } - // If we couldn't load the one in our dir, load any version available - if (!hDll) - { - hDll = LoadLibrary("DBGHELP.DLL"); - } + const WString commandLineWide = FromUTF8(commandLine); + if (commandLineWide.empty()) + { + AddReportLog(3130, SString("RunErrorTool failed to convert command line to wide characters for %s", candidate.c_str())); + RestoreBaseDirectories(); + continue; + } - if (!hDll) - AddReportLog(9201, "CCrashDumpWriter::DumpMiniDump - Could not load DBGHELP.DLL"); + std::vector commandBuffer(commandLineWide.length() + 1u, L'\0'); + std::copy(commandLineWide.begin(), commandLineWide.end(), commandBuffer.begin()); - // We could load a dll? - if (hDll) - { - // Grab the MiniDumpWriteDump proc address - MINIDUMPWRITEDUMP pDump = reinterpret_cast(GetProcAddress(hDll, "MiniDumpWriteDump")); - if (!pDump) - AddReportLog(9202, "CCrashDumpWriter::DumpMiniDump - Could not find MiniDumpWriteDump"); + STARTUPINFOW startupInfo{}; + startupInfo.cb = sizeof(startupInfo); + startupInfo.dwFlags = STARTF_USESHOWWINDOW; + startupInfo.wShowWindow = SW_SHOWNORMAL; + PROCESS_INFORMATION processInfo{}; - if (pDump) + constexpr DWORD kProcessCreationFlags = DETACHED_PROCESS | CREATE_BREAKAWAY_FROM_JOB | CREATE_NEW_PROCESS_GROUP; + const auto bProcessCreated = CreateProcessW(nullptr, commandBuffer.data(), nullptr, nullptr, FALSE, kProcessCreationFlags, nullptr, candidateDirWidePtr, + &startupInfo, &processInfo); + if (bProcessCreated) { - // Create the file - HANDLE hFile = CreateFile(CalcMTASAPath("mta\\core.dmp"), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) - AddReportLog(9203, SString("CCrashDumpWriter::DumpMiniDump - Could not create '%s'", *CalcMTASAPath("mta\\core.dmp"))); + AddReportLog(3124, SString("RunErrorTool launched crash dialog via CreateProcess (%s)", candidate.c_str())); + UniqueHandle processHandle{processInfo.hProcess}; + UniqueHandle threadHandle{processInfo.hThread}; - if (hFile != INVALID_HANDLE_VALUE) + if (processHandle) { - // Create an exception information struct - _MINIDUMP_EXCEPTION_INFORMATION ExInfo; - ExInfo.ThreadId = GetCurrentThreadId(); - ExInfo.ExceptionPointers = pException; - ExInfo.ClientPointers = FALSE; - - // Write the dump - BOOL bResult = pDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, - (MINIDUMP_TYPE)(MiniDumpNormal | MiniDumpWithIndirectlyReferencedMemory), &ExInfo, NULL, NULL); + SetPriorityClass(processHandle.get(), HIGH_PRIORITY_CLASS); + } - if (!bResult) - AddReportLog(9204, SString("CCrashDumpWriter::DumpMiniDump - MiniDumpWriteDump failed (%08x)", GetLastError())); - else - WriteDebugEvent("CCrashDumpWriter::DumpMiniDump - MiniDumpWriteDump succeeded"); + if (processInfo.dwProcessId != 0) + { + AllowSetForegroundWindow(processInfo.dwProcessId); + } - // Close the dumpfile - CloseHandle(hFile); + if (processHandle) + { + WaitForInputIdle(processHandle.get(), 3000); + } - // Grab the current time - // Ask windows for the system time. - SYSTEMTIME SystemTime; - GetLocalTime(&SystemTime); + Sleep(Milliseconds(PROCESS_WAIT_TIMEOUT)); - // Create the dump directory - CreateDirectory(CalcMTASAPath("mta\\dumps"), 0); - CreateDirectory(CalcMTASAPath("mta\\dumps\\private"), 0); + HWND hDialogWindow = nullptr; + for (std::size_t attempts = 0; attempts < MAX_WINDOW_POLL_ATTEMPTS && hDialogWindow == nullptr; ++attempts) + { + hDialogWindow = FindWindowW(nullptr, L"MTA: San Andreas has encountered a problem"); + if (hDialogWindow == nullptr) + Sleep(Milliseconds(WINDOW_POLL_TIMEOUT)); + } - SString strModuleName = pExceptionInformation->GetModuleBaseName(); - strModuleName = strModuleName.ReplaceI(".dll", "").Replace(".exe", "").Replace("_", "").Replace(".", "").Replace("-", ""); - if (strModuleName.length() == 0) - strModuleName = "unknown"; + bool windowFound = (hDialogWindow != nullptr && IsWindow(hDialogWindow)); - SString strMTAVersionFull = SString("%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting("mta-version-ext").SplitRight(".", NULL, -2)); - SString strSerialPart = GetApplicationSetting("serial").substr(0, 5); - uint uiServerIP = GetApplicationSettingInt("last-server-ip"); - uint uiServerPort = GetApplicationSettingInt("last-server-port"); - int uiServerTime = GetApplicationSettingInt("last-server-time"); - int uiServerDuration = _time32(NULL) - uiServerTime; - uiServerDuration = Clamp(0, uiServerDuration + 1, 0xfff); + if (windowFound) + { + if (const auto isIconic = IsIconic(hDialogWindow); isIconic) + { + ShowWindow(hDialogWindow, SW_RESTORE); + } - // Get path to mta dir - SString strPathCode; + if (IsWindow(hDialogWindow)) { - std::vector parts; - PathConform(CalcMTASAPath("")).Split(PATH_SEPERATOR, parts); - for (uint i = 0; i < parts.size(); i++) + const DWORD dialogThreadId = GetWindowThreadProcessId(hDialogWindow, nullptr); + const DWORD currentThreadId = GetCurrentThreadId(); + + BOOL attached = FALSE; + if (dialogThreadId != 0 && dialogThreadId != currentThreadId) { - if (parts[i].CompareI("Program Files")) - strPathCode += "Pr"; - else if (parts[i].CompareI("Program Files (x86)")) - strPathCode += "Px"; - else if (parts[i].CompareI("MTA San Andreas")) - strPathCode += "Mt"; - else if (parts[i].BeginsWithI("MTA San Andreas")) - strPathCode += "Mb"; - else - strPathCode += parts[i].Left(1).ToUpper(); + attached = AttachThreadInput(currentThreadId, dialogThreadId, TRUE); } - } - // Ensure filename parts match up with EDumpFileNameParts - SString strFilename("mta\\dumps\\private\\client_%s_%s_%08x_%x_%s_%08X_%04X_%03X_%s_%04d%02d%02d_%02d%02d.dmp", strMTAVersionFull.c_str(), - strModuleName.c_str(), pExceptionInformation->GetAddressModuleOffset(), pExceptionInformation->GetCode() & 0xffff, - strPathCode.c_str(), uiServerIP, uiServerPort, uiServerDuration, strSerialPart.c_str(), SystemTime.wYear, SystemTime.wMonth, - SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute); + LockSetForegroundWindow(LSFW_UNLOCK); + SetWindowPos(hDialogWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + + if (!SetForegroundWindow(hDialogWindow)) + { + keybd_event(VK_MENU, 0, 0, 0); + SetForegroundWindow(hDialogWindow); + Sleep(Milliseconds(ALT_KEY_DURATION)); + keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0); + } + + BringWindowToTop(hDialogWindow); + SetActiveWindow(hDialogWindow); + SetFocus(hDialogWindow); + + if (attached && dialogThreadId != 0) + { + AttachThreadInput(currentThreadId, dialogThreadId, FALSE); + } + + RECT windowRect{}; + if (GetWindowRect(hDialogWindow, &windowRect)) + { + const int screenWidth = GetSystemMetrics(SM_CXSCREEN); + const int screenHeight = GetSystemMetrics(SM_CYSCREEN); + + if (windowRect.left < -100 || windowRect.top < -100 || windowRect.left > screenWidth || windowRect.top > screenHeight) + { + const int windowWidth = windowRect.right - windowRect.left; + const int windowHeight = windowRect.bottom - windowRect.top; + const int centerX = (screenWidth - windowWidth) / 2; + const int centerY = (screenHeight - windowHeight) / 2; + SetWindowPos(hDialogWindow, HWND_TOPMOST, centerX, centerY, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); + } + } + + if (!IsWindowVisible(hDialogWindow)) + { + ShowWindow(hDialogWindow, SW_RESTORE); + } + } + } + else + { + AddReportLog(3132, SString("RunErrorTool could not find crash dialog window by title after CreateProcess (%s)", candidate.c_str())); + } - SString strPathFilename = CalcMTASAPath(strFilename); - - // Copy the file - CopyFile(CalcMTASAPath("mta\\core.dmp"), strPathFilename, false); - - // For the dump uploader - SetApplicationSetting("diagnostics", "last-dump-extra", "none"); - SetApplicationSetting("diagnostics", "last-dump-save", strPathFilename); - - // Try to append pool sizes info to dump file - SetApplicationSetting("diagnostics", "last-dump-extra", "try-pools"); - CBuffer poolInfo; - GetPoolInfo(poolInfo); - AppendToDumpFile(strPathFilename, poolInfo, 'POLs', 'POLe'); - SetApplicationSetting("diagnostics", "last-dump-extra", "added-pools"); - - // Try to append d3d state info to dump file - SetApplicationSetting("diagnostics", "last-dump-extra", "try-d3d"); - CBuffer d3dInfo; - GetD3DInfo(d3dInfo); - AppendToDumpFile(strPathFilename, d3dInfo, 'D3Ds', 'D3De'); - SetApplicationSetting("diagnostics", "last-dump-extra", "added-d3d"); - - // Try to append crash averted stats to dump file - SetApplicationSetting("diagnostics", "last-dump-extra", "try-crash-averted"); - CBuffer crashAvertedStats; - GetCrashAvertedStats(crashAvertedStats); - AppendToDumpFile(strPathFilename, crashAvertedStats, 'CASs', 'CASe'); - SetApplicationSetting("diagnostics", "last-dump-extra", "added-crash-averted"); - - // Try to append log info to dump file - SetApplicationSetting("diagnostics", "last-dump-extra", "try-log"); - CBuffer logInfo; - GetLogInfo(logInfo); - AppendToDumpFile(strPathFilename, logInfo, 'LOGs', 'LOGe'); - SetApplicationSetting("diagnostics", "last-dump-extra", "added-log"); - - // Try to append dx info to dump file - SetApplicationSetting("diagnostics", "last-dump-extra", "try-misc"); - CBuffer dxInfo; - GetDxInfo(dxInfo); - AppendToDumpFile(strPathFilename, dxInfo, 'DXIs', 'DXIe'); - SetApplicationSetting("diagnostics", "last-dump-extra", "added-misc"); - - // Try to append misc info to dump file - SetApplicationSetting("diagnostics", "last-dump-extra", "try-misc"); - CBuffer miscInfo; - GetMiscInfo(miscInfo); - AppendToDumpFile(strPathFilename, miscInfo, 'MSCs', 'MSCe'); - SetApplicationSetting("diagnostics", "last-dump-extra", "added-misc"); - - // Try to append memory info to dump file - SetApplicationSetting("diagnostics", "last-dump-extra", "try-mem"); - CBuffer memInfo; - GetMemoryInfo(memInfo); - AppendToDumpFile(strPathFilename, memInfo, 'MEMs', 'MEMe'); - SetApplicationSetting("diagnostics", "last-dump-extra", "added-mem"); - - // Try to logfile.txt to dump file - SetApplicationSetting("diagnostics", "last-dump-extra", "try-logfile"); - CBuffer logfileContent; - logfileContent.LoadFromFile(CalcMTASAPath(PathJoin("mta", "logs", "logfile.txt"))); - AppendToDumpFile(strPathFilename, logfileContent, 'LOGs', 'LOGe'); - SetApplicationSetting("diagnostics", "last-dump-extra", "added-logfile"); - - // Try to report.log to dump file - SetApplicationSetting("diagnostics", "last-dump-extra", "try-report"); - CBuffer reportLogContent; - reportLogContent.LoadFromFile(PathJoin(GetMTADataPath(), "report.log")); - AppendToDumpFile(strPathFilename, reportLogContent, 'REPs', 'REPe'); - SetApplicationSetting("diagnostics", "last-dump-extra", "added-report"); - - // Try to append current animation and task to dump file - SetApplicationSetting("diagnostics", "last-dump-extra", "try-anim-task"); - CBuffer currentAnimTaskInfo; - GetCurrentAnimTaskInfo(currentAnimTaskInfo); - AppendToDumpFile(strPathFilename, currentAnimTaskInfo, 'CATs', 'CATe'); - SetApplicationSetting("diagnostics", "last-dump-extra", "added-anim-task"); + if (windowFound) + { + ms_hCrashDialogProcess = processHandle.release(); + threadHandle.reset(); + dialogLaunched = true; + break; } } - // Free the DLL again - FreeLibrary(hDll); - } + if (const auto dwError = GetLastError()) + { + AddReportLog(3121, SString("RunErrorTool CreateProcess failed with error %u for %s", dwError, candidate.c_str())); + } - // Auto-fixes + if (crashArgsWide.empty()) + { + AddReportLog(3131, "RunErrorTool failed to convert crash arguments to wide characters"); + RestoreBaseDirectories(); + continue; + } - // Check if crash was in volumetric shadow code - if (ms_uiInCrashZone == 1 || ms_uiInCrashZone == 2) - { - CVARS_SET("volumetric_shadows", false); - CCore::GetSingleton().SaveConfig(); - AddReportLog(9205, "Disabled volumetric shadows"); - } + const auto shellExecuteResult = ShellExecuteW(nullptr, L"open", candidateWide.c_str(), crashArgsWide.c_str(), candidateDirWidePtr, SW_SHOW); + const auto shellExecuteCode = reinterpret_cast(shellExecuteResult); + if (shellExecuteCode > 32u) + { + AddReportLog(3124, SString("RunErrorTool launched crash dialog via ShellExecute (%s)", candidate.c_str())); + Sleep(1000); - CNet* pNet = CCore::GetSingleton().GetNetwork(); - if (pNet) - pNet->PostCrash(); -} + HWND hDialogWindow = nullptr; + for (std::size_t attempts = 0; attempts < SHELL_EXEC_POLL_ATTEMPTS && hDialogWindow == nullptr; attempts++) + { + hDialogWindow = FindWindowW(nullptr, L"MTA: San Andreas has encountered a problem"); + if (hDialogWindow == nullptr) + Sleep(Milliseconds(WINDOW_POLL_TIMEOUT)); + } -void CCrashDumpWriter::RunErrorTool(CExceptionInformation* pExceptionInformation) -{ - // MTA Error Reporter is now integrated into the launcher + if (hDialogWindow != nullptr && IsWindow(hDialogWindow)) + { + SetWindowPos(hDialogWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + SetForegroundWindow(hDialogWindow); + dialogLaunched = true; + break; + } - // Only do once - static bool bDoneReport = false; - if (bDoneReport) - return; - bDoneReport = false; + AddReportLog(3132, SString("RunErrorTool could not find crash dialog window by title after ShellExecute (%s)", candidate.c_str())); + } + else + { + AddReportLog( + 3122, SString("RunErrorTool ShellExecute fallback failed with code %u for %s", static_cast(shellExecuteCode), candidate.c_str())); + } - // Log the basic exception information - SString strMessage( - "Crash 0x%08X 0x%08X %s" - " EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESI=%08X" - " EDI=%08X EBP=%08X ESP=%08X EIP=%08X FLG=%08X" - " CS=%04X DS=%04X SS=%04X ES=%04X" - " FS=%04X GS=%04X", - pExceptionInformation->GetCode(), pExceptionInformation->GetAddressModuleOffset(), pExceptionInformation->GetModulePathName(), - pExceptionInformation->GetEAX(), pExceptionInformation->GetEBX(), pExceptionInformation->GetECX(), pExceptionInformation->GetEDX(), - pExceptionInformation->GetESI(), pExceptionInformation->GetEDI(), pExceptionInformation->GetEBP(), pExceptionInformation->GetESP(), - pExceptionInformation->GetEIP(), pExceptionInformation->GetEFlags(), pExceptionInformation->GetCS(), pExceptionInformation->GetDS(), - pExceptionInformation->GetSS(), pExceptionInformation->GetES(), pExceptionInformation->GetFS(), pExceptionInformation->GetGS()); + RestoreBaseDirectories(); + } - AddReportLog(3120, strMessage); + RestoreBaseDirectories(); - // Try relaunch with crashed flag - SString strMTASAPath = GetMTASABaseDir(); - SetCurrentDirectory(strMTASAPath); - SetDllDirectory(strMTASAPath); + if (!dialogLaunched) + { + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::RunErrorTool - FAILED to launch crash dialog with any candidate!\n"); + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::RunErrorTool - User will not see crash report dialog!\n"); + AddReportLog(3129, "RunErrorTool completely failed to launch crash dialog"); + + const wchar_t* emergencyMessage = + L"MTA: San Andreas has crashed.\n\n" + L"The usual crash dialog has also failed, with this as fallback.\n\n" + L"Crash information has been saved to:\n" + L"MTA San Andreas\\mta\\core.log\n\n" + L"Contact support on the MTA discord: https://discord.gg/RygaCSD.\n\n" + L"The game will now close."; + + MessageBoxW(nullptr, emergencyMessage, L"MTA: San Andreas - Fatal Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL | MB_SETFOREGROUND | MB_TOPMOST); + } -#ifdef MTA_DEBUG - #define MTA_EXE_NAME "Multi Theft Auto_d.exe" -#else - #define MTA_EXE_NAME "Multi Theft Auto.exe" -#endif - SString strFile = strMTASAPath + "\\" + MTA_EXE_NAME; - ShellExecute(NULL, "open", strFile, "install_stage=crashed", NULL, SW_SHOWNORMAL); + return dialogLaunched; } -// -// Add extra data to the dump file and hope visual studio doesn't mind -// void CCrashDumpWriter::AppendToDumpFile(const SString& strPathFilename, const CBuffer& dataBuffer, DWORD dwMagicStart, DWORD dwMagicEnd) { CBuffer output; CBufferWriteStream stream(output); - // 4 bytes zero - stream.Write((DWORD)0); - // 4 bytes magic + stream.Write(static_cast(0)); stream.Write(dwMagicStart); - // 4 bytes size of data stream.Write(dataBuffer.GetSize()); - // n bytes data stream.WriteBytes(dataBuffer.GetData(), dataBuffer.GetSize()); - // 4 bytes size of data stream.Write(dataBuffer.GetSize()); - // 4 bytes magic stream.Write(dwMagicEnd); - // 4 bytes zero - stream.Write((DWORD)0); + stream.Write(static_cast(0)); FileAppend(strPathFilename, output.GetData(), output.GetSize()); } -// -// Helper crap for GetPoolInfo -// namespace { - #define CLASS_CBuildingPool 0xb74498 - #define CLASS_CPedPool 0xb74490 - #define CLASS_CObjectPool 0xb7449c - #define CLASS_CDummyPool 0xb744a0 - #define CLASS_CVehiclePool 0xb74494 - #define CLASS_CColModelPool 0xb744a4 - #define CLASS_CTaskPool 0xb744a8 - #define CLASS_CEventPool 0xb744ac - #define CLASS_CTaskAllocatorPool 0xb744bc - #define CLASS_CPedIntelligencePool 0xb744c0 - #define CLASS_CPedAttractorPool 0xb744c4 - #define CLASS_CEntryInfoNodePool 0xb7448c - #define CLASS_CNodeRoutePool 0xb744b8 - #define CLASS_CPatrolRoutePool 0xb744b4 - #define CLASS_CPointRoutePool 0xb744b0 - #define CLASS_CPtrNodeDoubleLinkPool 0xB74488 - #define CLASS_CPtrNodeSingleLinkPool 0xB74484 - - #define FUNC_CBuildingPool_GetNoOfUsedSpaces 0x550620 - #define FUNC_CPedPool_GetNoOfUsedSpaces 0x5504A0 - #define FUNC_CObjectPool_GetNoOfUsedSpaces 0x54F6B0 - #define FUNC_CDummyPool_GetNoOfUsedSpaces 0x5507A0 - #define FUNC_CVehiclePool_GetNoOfUsedSpaces 0x42CCF0 - #define FUNC_CColModelPool_GetNoOfUsedSpaces 0x550870 - #define FUNC_CTaskPool_GetNoOfUsedSpaces 0x550940 - #define FUNC_CEventPool_GetNoOfUsedSpaces 0x550A10 - #define FUNC_CTaskAllocatorPool_GetNoOfUsedSpaces 0x550d50 - #define FUNC_CPedIntelligencePool_GetNoOfUsedSpaces 0x550E20 - #define FUNC_CPedAttractorPool_GetNoOfUsedSpaces 0x550ef0 - #define FUNC_CEntryInfoNodePool_GetNoOfUsedSpaces 0x5503d0 - #define FUNC_CNodeRoutePool_GetNoOfUsedSpaces 0x550c80 - #define FUNC_CPatrolRoutePool_GetNoOfUsedSpaces 0x550bb0 - #define FUNC_CPointRoutePool_GetNoOfUsedSpaces 0x550ae0 - #define FUNC_CPtrNodeSingleLinkPool_GetNoOfUsedSpaces 0x550230 - #define FUNC_CPtrNodeDoubleLinkPool_GetNoOfUsedSpaces 0x550300 - - int GetPoolCapacity(ePools pool) - { - DWORD iPtr = NULL; - DWORD cPtr = NULL; + constexpr int POOL_INFO_VERSION = 1; + constexpr int D3D_INFO_VERSION = 2; + constexpr int CRASH_AVERTED_STATS_VERSION = 1; + constexpr int LOG_INFO_VERSION = 1; + + constexpr DWORD CLASS_CBuildingPool = 0xb74498; + constexpr DWORD CLASS_CPedPool = 0xb74490; + constexpr DWORD CLASS_CObjectPool = 0xb7449c; + constexpr DWORD CLASS_CDummyPool = 0xb744a0; + constexpr DWORD CLASS_CVehiclePool = 0xb74494; + constexpr DWORD CLASS_CColModelPool = 0xb744a4; + constexpr DWORD CLASS_CTaskPool = 0xb744a8; + constexpr DWORD CLASS_CEventPool = 0xb744ac; + constexpr DWORD CLASS_CTaskAllocatorPool = 0xb744bc; + constexpr DWORD CLASS_CPedIntelligencePool = 0xb744c0; + constexpr DWORD CLASS_CPedAttractorPool = 0xb744c4; + constexpr DWORD CLASS_CEntryInfoNodePool = 0xb7448c; + constexpr DWORD CLASS_CNodeRoutePool = 0xb744b8; + constexpr DWORD CLASS_CPatrolRoutePool = 0xb744b4; + constexpr DWORD CLASS_CPointRoutePool = 0xb744b0; + constexpr DWORD CLASS_CPtrNodeDoubleLinkPool = 0xB74488; + constexpr DWORD CLASS_CPtrNodeSingleLinkPool = 0xB74484; + + constexpr DWORD FUNC_CBuildingPool_GetNoOfUsedSpaces = 0x550620; + constexpr DWORD FUNC_CPedPool_GetNoOfUsedSpaces = 0x5504A0; + constexpr DWORD FUNC_CObjectPool_GetNoOfUsedSpaces = 0x54F6B0; + constexpr DWORD FUNC_CDummyPool_GetNoOfUsedSpaces = 0x5507A0; + constexpr DWORD FUNC_CVehiclePool_GetNoOfUsedSpaces = 0x42CCF0; + constexpr DWORD FUNC_CColModelPool_GetNoOfUsedSpaces = 0x550870; + constexpr DWORD FUNC_CTaskPool_GetNoOfUsedSpaces = 0x550940; + constexpr DWORD FUNC_CEventPool_GetNoOfUsedSpaces = 0x550A10; + constexpr DWORD FUNC_CTaskAllocatorPool_GetNoOfUsedSpaces = 0x550d50; + constexpr DWORD FUNC_CPedIntelligencePool_GetNoOfUsedSpaces = 0x550E20; + constexpr DWORD FUNC_CPedAttractorPool_GetNoOfUsedSpaces = 0x550ef0; + constexpr DWORD FUNC_CEntryInfoNodePool_GetNoOfUsedSpaces = 0x5503d0; + constexpr DWORD FUNC_CNodeRoutePool_GetNoOfUsedSpaces = 0x550c80; + constexpr DWORD FUNC_CPatrolRoutePool_GetNoOfUsedSpaces = 0x550bb0; + constexpr DWORD FUNC_CPointRoutePool_GetNoOfUsedSpaces = 0x550ae0; + constexpr DWORD FUNC_CPtrNodeSingleLinkPool_GetNoOfUsedSpaces = 0x550230; + constexpr DWORD FUNC_CPtrNodeDoubleLinkPool_GetNoOfUsedSpaces = 0x550300; + + [[nodiscard]] int GetPoolCapacity(ePools pool) + { + DWORD iPtr = 0; + DWORD cPtr = 0; switch (pool) { case BUILDING_POOL: @@ -677,19 +3150,19 @@ namespace iPtr = 0x5DA106; break; } - if (iPtr) - return *(int*)iPtr; + if (iPtr != 0) + return *reinterpret_cast(iPtr); - if (cPtr) - return *(char*)cPtr; + if (cPtr != 0) + return *reinterpret_cast(cPtr); return 0; } - int GetNumberOfUsedSpaces(ePools pool) + [[nodiscard]] int GetNumberOfUsedSpaces(ePools pool) { - DWORD dwFunc = NULL; - DWORD dwThis = NULL; + DWORD dwFunc = 0; + DWORD dwThis = 0; switch (pool) { case BUILDING_POOL: @@ -765,7 +3238,7 @@ namespace } int iOut = -2; - if (*(DWORD*)dwThis != NULL) + if (*(DWORD*)dwThis != 0) { _asm { @@ -773,163 +3246,107 @@ namespace mov ecx, [ecx] call dwFunc mov iOut, eax - } } return iOut; } -} // namespace +} // namespace -// -// Grab the state of the memory pools -// void CCrashDumpWriter::GetPoolInfo(CBuffer& buffer) { CBufferWriteStream stream(buffer); - // Write PoolInfo version - stream.Write(1); + stream.Write(POOL_INFO_VERSION); - // Write number of pools we have info on stream.Write(MAX_POOLS); - // For each pool for (int i = 0; i < MAX_POOLS; i++) { - int iCapacity = GetPoolCapacity((ePools)i); - int iUsedSpaces = GetNumberOfUsedSpaces((ePools)i); - // Write pool info + int iCapacity = GetPoolCapacity(static_cast(i)); + int iUsedSpaces = GetNumberOfUsedSpaces(static_cast(i)); stream.Write(i); stream.Write(iCapacity); stream.Write(iUsedSpaces); } - - // TODO - Get usage info for other arrays such as CMatrixLinkList } -// -// Grab the state of D3D -// void CCrashDumpWriter::GetD3DInfo(CBuffer& buffer) { CBufferWriteStream stream(buffer); - // Write D3DInfo version - stream.Write(2); + stream.Write(D3D_INFO_VERSION); - // Quit if device state pointer is not valid - if (!g_pDeviceState) + if (g_pDeviceState == nullptr) return; - // Write D3D call type stream.Write(g_pDeviceState->CallState.callType); - // Only record state if crash was inside D3D if (g_pDeviceState->CallState.callType == CProxyDirect3DDevice9::SCallState::NONE) return; - // Write D3D call args stream.Write(g_pDeviceState->CallState.uiNumArgs); for (uint i = 0; i < g_pDeviceState->CallState.uiNumArgs; i++) stream.Write(g_pDeviceState->CallState.args[i]); - // Try to get CRenderWare pointer CCore* pCore = CCore::GetSingletonPtr(); - CGame* pGame = pCore ? pCore->GetGame() : NULL; - CRenderWare* pRenderWare = pGame ? pGame->GetRenderWare() : NULL; - // Write on how we got on with doing that - stream.Write((uchar)(pCore ? 1 : 0)); - stream.Write((uchar)(pGame ? 1 : 0)); - stream.Write((uchar)(pRenderWare ? 1 : 0)); + CGame* pGame = pCore != nullptr ? pCore->GetGame() : nullptr; + CRenderWare* pRenderWare = pGame != nullptr ? pGame->GetRenderWare() : nullptr; + + stream.Write(static_cast(pCore != nullptr ? 1 : 0)); + stream.Write(static_cast(pGame != nullptr ? 1 : 0)); + stream.Write(static_cast(pRenderWare != nullptr ? 1 : 0)); - // Write last used texture D3D pointer - stream.Write((uint)g_pDeviceState->TextureState[0].Texture); + stream.Write(reinterpret_cast(g_pDeviceState->TextureState[0].Texture)); - // Write last used texture name SString strTextureName = "no name"; - if (pRenderWare) - strTextureName = pRenderWare->GetTextureName((CD3DDUMMY*)g_pDeviceState->TextureState[0].Texture); + if (pRenderWare != nullptr) + strTextureName = pRenderWare->GetTextureName(reinterpret_cast(static_cast(g_pDeviceState->TextureState[0].Texture))); stream.WriteString(strTextureName); - // Write shader name if being used stream.WriteString(""); stream.Write(false); - - // TODO - Vertex state and vertex/index buffer if readable } -/////////////////////////////////////////////////////////////// -// -// CCrashDumpWriter::GetCrashAvertedStats -// -// Static function -// Grab the crash averted stats -// -/////////////////////////////////////////////////////////////// void CCrashDumpWriter::GetCrashAvertedStats(CBuffer& buffer) { CBufferWriteStream stream(buffer); - // Write info version - stream.Write(2); + stream.Write(CRASH_AVERTED_STATS_VERSION); - // Write number of stats stream.Write(ms_CrashAvertedMap.size()); - // Write stats - for (std::map::iterator iter = ms_CrashAvertedMap.begin(); iter != ms_CrashAvertedMap.end(); ++iter) + for (const auto& [id, info] : ms_CrashAvertedMap) { - stream.Write(ms_uiTickCountBase - iter->second.uiTickCount); - stream.Write(iter->first); - stream.Write(iter->second.uiUsageCount); + stream.Write(ms_uiTickCountBase - info.uiTickCount); + stream.Write(id); + stream.Write(info.uiUsageCount); } } -/////////////////////////////////////////////////////////////// -// -// CCrashDumpWriter::GetLogInfo -// -// Static function -// Grab log info -// -/////////////////////////////////////////////////////////////// void CCrashDumpWriter::GetLogInfo(CBuffer& buffer) { CBufferWriteStream stream(buffer); - // Write info version - stream.Write(1); + stream.Write(LOG_INFO_VERSION); - // Write number of stats stream.Write(ms_LogEventList.size()); - // Write stats - for (std::list::iterator iter = ms_LogEventList.begin(); iter != ms_LogEventList.end(); ++iter) + for (const auto& eventInfo : ms_LogEventList) { - stream.Write(ms_uiTickCountBase - iter->uiTickCount); - stream.WriteString(iter->strType); - stream.WriteString(iter->strContext); - stream.WriteString(iter->strBody); + stream.Write(ms_uiTickCountBase - eventInfo.uiTickCount); + stream.WriteString(eventInfo.strType); + stream.WriteString(eventInfo.strContext); + stream.WriteString(eventInfo.strBody); } } -/////////////////////////////////////////////////////////////// -// -// CCrashDumpWriter::GetDxInfo -// -// Static function -// Grab our dx datum -// -/////////////////////////////////////////////////////////////// void CCrashDumpWriter::GetDxInfo(CBuffer& buffer) { CBufferWriteStream stream(buffer); - // Write info version stream.Write(2); - // video card name etc.. SDxStatus status; CGraphics::GetSingleton().GetRenderItemManager()->GetDxStatus(status); @@ -951,50 +3368,36 @@ void CCrashDumpWriter::GetDxInfo(CBuffer& buffer) stream.Write(status.settings.iStreamingMemory); } -/////////////////////////////////////////////////////////////// -// -// CCrashDumpWriter::GetMiscInfo -// -// Static function -// Grab various bits 'n' bobs -// -/////////////////////////////////////////////////////////////// void CCrashDumpWriter::GetMiscInfo(CBuffer& buffer) { CBufferWriteStream stream(buffer); - // Write info version stream.Write(2); - // US/Euro gta_sa.exe - unsigned char ucA = *reinterpret_cast(0x748ADD); - unsigned char ucB = *reinterpret_cast(0x748ADE); + unsigned char ucA = 0; + unsigned char ucB = 0; + + const bool bReadA = SafeReadGameByte(0x748ADD, ucA); + const bool bReadB = SafeReadGameByte(0x748ADE, ucB); + + if (!bReadA || !bReadB) + SAFE_DEBUG_OUTPUT("CCrashDumpWriter::GetMiscInfo - Failed to read GTA memory\n"); + stream.Write(ucA); stream.Write(ucB); - // Crash zone if any stream.Write(ms_uiInCrashZone); } -/////////////////////////////////////////////////////////////// -// -// CCrashDumpWriter::GetMemoryInfo -// -// Static function -// Same stuff as from showmemstat command -// -/////////////////////////////////////////////////////////////// void CCrashDumpWriter::GetMemoryInfo(CBuffer& buffer) { CBufferWriteStream stream(buffer); - // Write info version stream.Write(1); SMemStatsInfo memStatsNow; GetMemStats()->SampleState(memStatsNow); - // GTA video memory static const CProxyDirect3DDevice9::SResourceMemory* const nowList[] = { &memStatsNow.d3dMemory.StaticVertexBuffer, &memStatsNow.d3dMemory.DynamicVertexBuffer, &memStatsNow.d3dMemory.StaticIndexBuffer, &memStatsNow.d3dMemory.DynamicIndexBuffer, &memStatsNow.d3dMemory.StaticTexture, &memStatsNow.d3dMemory.DynamicTexture}; @@ -1009,13 +3412,11 @@ void CCrashDumpWriter::GetMemoryInfo(CBuffer& buffer) stream.Write(nowList[i]->iCurrentBytes); } - // Game memory stream.Write(3); stream.Write(memStatsNow.iProcessMemSizeKB); stream.Write(memStatsNow.iStreamingMemoryUsed); stream.Write(memStatsNow.iStreamingMemoryAvailable); - // Model usage iNumLines = sizeof(memStatsNow.modelInfo) / sizeof(uint); stream.Write(iNumLines); for (int i = 0; i < iNumLines; i++) @@ -1028,12 +3429,11 @@ void CCrashDumpWriter::GetCurrentAnimTaskInfo(CBuffer& buffer) { CBufferWriteStream stream(buffer); - // Write info version stream.Write(1); stream.WriteString("-- ** Current Animation Task Info -- **\n\n"); CMultiplayer* pMultiplayer = g_pCore->GetMultiplayer(); - if (pMultiplayer) + if (pMultiplayer != nullptr) { stream.WriteString(SString("Last Animation Added: group ID = %u, animation ID = %u, CAnimManager::ms_aAnimAssocGroups = %#.8x\n", pMultiplayer->GetLastStaticAnimationGroupID(), pMultiplayer->GetLastStaticAnimationID(), @@ -1041,24 +3441,15 @@ void CCrashDumpWriter::GetCurrentAnimTaskInfo(CBuffer& buffer) } } -/////////////////////////////////////////////////////////////// -// -// CCrashDumpWriter::GetCrashAvertedStatsSoFar -// -// Static function -// Grab the crash averted stats -// -/////////////////////////////////////////////////////////////// -SString CCrashDumpWriter::GetCrashAvertedStatsSoFar() +[[nodiscard]] SString CCrashDumpWriter::GetCrashAvertedStatsSoFar() { SString strResult; ms_uiTickCountBase = GetTickCount32(); int iIndex = 1; - for (std::map::iterator iter = ms_CrashAvertedMap.begin(); iter != ms_CrashAvertedMap.end(); ++iter) + for (const auto& [id, info] : ms_CrashAvertedMap) { - strResult += - SString("%d) Age:%5d Type:%2d Count:%d\n", iIndex++, ms_uiTickCountBase - iter->second.uiTickCount, iter->first, iter->second.uiUsageCount); + strResult += SString("%d) Age:%5d Type:%2d Count:%d\n", iIndex++, ms_uiTickCountBase - info.uiTickCount, id, info.uiUsageCount); } return strResult; } diff --git a/Client/core/CCrashDumpWriter.h b/Client/core/CCrashDumpWriter.h index d98faff49de..228dcd0d374 100644 --- a/Client/core/CCrashDumpWriter.h +++ b/Client/core/CCrashDumpWriter.h @@ -11,6 +11,8 @@ #pragma once +#include + class CExceptionInformation; enum EDumpFileNameParts @@ -37,26 +39,26 @@ enum EDumpFileNameParts class CCrashDumpWriter { public: - static long WINAPI HandleExceptionGlobal(_EXCEPTION_POINTERS* pException); - static void DumpCoreLog(CExceptionInformation* pExceptionInformation); - static void DumpMiniDump(_EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation); - static void RunErrorTool(CExceptionInformation* pExceptionInformation); - static void AppendToDumpFile(const SString& strPathFilename, const CBuffer& dataBuffer, DWORD dwMagicStart, DWORD dwMagicEnd); - static void GetPoolInfo(CBuffer& buffer); - static void GetD3DInfo(CBuffer& buffer); - static void GetCrashAvertedStats(CBuffer& buffer); - static void GetLogInfo(CBuffer& buffer); - static void GetDxInfo(CBuffer& buffer); - static void GetMemoryInfo(CBuffer& buffer); - static void GetCurrentAnimTaskInfo(CBuffer& buffer); - static void GetMiscInfo(CBuffer& buffer); - static void OnCrashAverted(uint uiId); - static void OnEnterCrashZone(uint uiId); - static void LogEvent(const char* szType, const char* szContext, const char* szBody); - static SString GetCrashAvertedStatsSoFar(); - static void ReserveMemoryKBForCrashDumpProcessing(uint uiMemoryKB); - static void FreeMemoryForCrashDumpProcessing(); - static void SetHandlers(); - static void UpdateCounters(); - static void HandleInvalidParameter(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved); + static long WINAPI HandleExceptionGlobal(_EXCEPTION_POINTERS* pException); + static void DumpCoreLog(_EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation); + static void DumpMiniDump(_EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation); + [[nodiscard]] static bool RunErrorTool(CExceptionInformation* pExceptionInformation); + static void AppendToDumpFile(const SString& strPathFilename, const CBuffer& dataBuffer, DWORD dwMagicStart, DWORD dwMagicEnd); + static void GetPoolInfo(CBuffer& buffer); + static void GetD3DInfo(CBuffer& buffer); + static void GetCrashAvertedStats(CBuffer& buffer); + static void GetLogInfo(CBuffer& buffer); + static void GetDxInfo(CBuffer& buffer); + static void GetMemoryInfo(CBuffer& buffer); + static void GetCurrentAnimTaskInfo(CBuffer& buffer); + static void GetMiscInfo(CBuffer& buffer); + static void OnCrashAverted(uint uiId); + static void OnEnterCrashZone(uint uiId); + static void LogEvent(const char* szType, const char* szContext, const char* szBody); + static SString GetCrashAvertedStatsSoFar(); + static void ReserveMemoryKBForCrashDumpProcessing(uint uiMemoryKB); + static void FreeMemoryForCrashDumpProcessing(); + static void SetHandlers(); + static void UpdateCounters(); + static void HandleInvalidParameter(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved); }; diff --git a/Client/core/CCredits.cpp b/Client/core/CCredits.cpp index 4b6d316eaba..95c7c50ee0f 100644 --- a/Client/core/CCredits.cpp +++ b/Client/core/CCredits.cpp @@ -17,7 +17,7 @@ namespace CCreditsGUI { float fWindowX = 560.0f; float fWindowY = 300.0f; -} // namespace CCreditsGUI +} // namespace CCreditsGUI using namespace CCreditsGUI; CCredits::CCredits() @@ -42,7 +42,9 @@ CCredits::CCredits() "Dan \"Talidan\" Chowdhury\n" "Chris \"ccw\" Cockwanger\n" "Adge \"Jax\" Cutler\n" + "Leonard \"lopsi\" Drumsticks\n" "Cecill \"ijs\" Etheredge\n" + "Patrik Juvonen\n" "Danish \"Saml1er\" Khan\n" "Marek \"botder\" Kulik\n" "Sebas \"x86\" Lamers\n" @@ -51,10 +53,12 @@ CCredits::CCredits() "Christian \"ChrML\" Myhre Lundheim\n" "Qais \"qaisjp\" Patankar\n" "Arushan \"aru\" Raj\n" + "Jordy \"Megadreams\" Sleeubus\n" "Frank \"Aim\" Spijkerman\n" "Pascal \"sbx320\" Stücker\n" "Kevin \"Kevuwk\" Whiteside\n" "Richard \"Cazomino05\" Whitlock\n" + "Dutchman101\n" "Gamesnert\n" "Jusonex\n" "\n" @@ -65,7 +69,6 @@ CCredits::CCredits() "\n\n" "Patrik \"Pirulax\" Jankovics-Szmolenicki\n" - "Patrik \"myonlake\" Juvonen\n" "Uladzislau \"TheNormalnij\" Nikalayevich\n" "Nikita \"StrixG\" Obrecht\n" "Arran\n" @@ -74,7 +77,6 @@ CCredits::CCredits() "Iztas\n" "JoeBullet\n" "lopezloo\n" - "Lpsd\n" "MX_Master\n" "Remp\n" "SugarD-x\n" @@ -93,7 +95,6 @@ CCredits::CCredits() "Norbert \"norby89\" Juhos\n" "Kris \"KWKSND\" Kulchisky\n" "Dustin \"Ransom\" Morren\n" - "Dutchman101\n" "erorr404\n" "Synecy\n" "\n" @@ -141,7 +142,6 @@ CCredits::CCredits() "Sam \"samr46\" R.\n" "Fernando Rocha\n" "Fedor \"Ted\" Sinev\n" - "Jordy \"MegadreamsBE\" Sleeubus\n" "Simon \"Simi23\" Tamás\n" "Adam \"50p\" Telega\n" "Ilya \"Kenix\" Volkov\n" @@ -315,7 +315,6 @@ CCredits::CCredits() "UnRAR (https://www.rarlab.com/)\n" "zlib (https://zlib.net/)\n"; - // SA credits m_strCredits += "\n\n\n== Grand Theft Auto: San Andreas (TM) (c) 2005 Rockstar Games, Inc. ==\n\n\n"; @@ -1092,8 +1091,7 @@ CCredits::CCredits() "Sarah Oram\n" "Smoke Stack\n" "Trattoria Siciliana\n" - "Black Bull\n" - ; + "Black Bull\n"; // Create our window CVector2D RelativeWindow = CVector2D(fWindowX / pManager->GetResolution().fX, fWindowY / pManager->GetResolution().fY); @@ -1101,7 +1099,7 @@ CCredits::CCredits() m_pWindow->SetCloseButtonEnabled(false); m_pWindow->SetMovable(false); m_pWindow->SetPosition(CVector2D(0.5f - RelativeWindow.fX * 0.5f, 0.5f - RelativeWindow.fY * 0.5f), true); - m_pWindow->SetSize(CVector2D(fWindowX, fWindowY)); // relative 0.70, 0.50 + m_pWindow->SetSize(CVector2D(fWindowX, fWindowY)); // relative 0.70, 0.50 m_pWindow->SetSizingEnabled(false); m_pWindow->SetVisible(false); m_pWindow->SetAlwaysOnTop(true); @@ -1134,7 +1132,7 @@ CCredits::CCredits() // Create the label m_pLabels[uiLabelIndex] = reinterpret_cast(pManager->CreateLabel(m_pWindow, strBuffer.c_str())); m_pLabels[uiLabelIndex]->SetPosition(CVector2D(0.022f, fStartPosition), true); - m_pLabels[uiLabelIndex]->SetSize(CVector2D(532.0f, 1500.0f)); // relative 0.95, 6.0 + m_pLabels[uiLabelIndex]->SetSize(CVector2D(532.0f, 1500.0f)); // relative 0.95, 6.0 m_pLabels[uiLabelIndex]->SetHorizontalAlign(CGUI_ALIGN_HORIZONTALCENTER); ++uiLabelIndex; @@ -1153,7 +1151,7 @@ CCredits::CCredits() // Create the OK button m_pButtonOK = reinterpret_cast(pManager->CreateButton(m_pWindow, "OK")); m_pButtonOK->SetPosition(CVector2D(0.77f, 0.90f), true); - m_pButtonOK->SetSize(CVector2D(112.0f, 21.0f)); // relative 0.20, 0.07 + m_pButtonOK->SetSize(CVector2D(112.0f, 21.0f)); // relative 0.20, 0.07 m_pButtonOK->SetVisible(true); m_pButtonOK->SetAlwaysOnTop(true); diff --git a/Client/core/CDebugView.h b/Client/core/CDebugView.h index 3f43368f263..75b60306c64 100644 --- a/Client/core/CDebugView.h +++ b/Client/core/CDebugView.h @@ -15,8 +15,8 @@ #include #include "CChat.h" -#define DEBUGVIEW_WIDTH 576 // Debugview default width -#define DEBUGVIEW_TEXT_COLOR CColor( 235, 221, 178, 255 ) // Debugview default text color +#define DEBUGVIEW_WIDTH 576 // Debugview default width +#define DEBUGVIEW_TEXT_COLOR CColor(235, 221, 178, 255) // Debugview default text color class CDebugView : public CChat { @@ -28,5 +28,5 @@ class CDebugView : public CChat protected: // Debug view doesn't support position changes unlike chat box - void UpdatePosition() override{}; + void UpdatePosition() override {}; }; diff --git a/Client/core/CDiscordRichPresence.cpp b/Client/core/CDiscordRichPresence.cpp index bc49a07a91a..28473778292 100644 --- a/Client/core/CDiscordRichPresence.cpp +++ b/Client/core/CDiscordRichPresence.cpp @@ -37,7 +37,7 @@ CDiscordRichPresence::~CDiscordRichPresence() void CDiscordRichPresence::InitializeDiscord() { std::lock_guard lock(m_threadSafetyMutex); - DiscordEventHandlers handlers; + DiscordEventHandlers handlers; memset(&handlers, 0, sizeof(handlers)); handlers.ready = HandleDiscordReady; @@ -107,7 +107,7 @@ void CDiscordRichPresence::UpdatePresence() return; std::lock_guard lock(m_threadSafetyMutex); - DiscordRichPresence discordPresence; + DiscordRichPresence discordPresence; memset(&discordPresence, 0, sizeof(discordPresence)); discordPresence.largeImageKey = m_strDiscordAppAsset.c_str(); @@ -115,7 +115,8 @@ void CDiscordRichPresence::UpdatePresence() discordPresence.smallImageKey = m_strDiscordAppAssetSmall.c_str(); discordPresence.smallImageText = m_strDiscordAppAssetSmallText.c_str(); - discordPresence.state = (!m_strDiscordAppCustomState.empty() || !m_bDisallowCustomDetails) ? m_strDiscordAppCustomState.c_str() : m_strDiscordAppState.c_str(); + discordPresence.state = + (!m_strDiscordAppCustomState.empty() || !m_bDisallowCustomDetails) ? m_strDiscordAppCustomState.c_str() : m_strDiscordAppState.c_str(); discordPresence.details = (!m_strDiscordAppCustomDetails.empty() || !m_bDisallowCustomDetails) ? m_strDiscordAppCustomDetails.c_str() : m_strDiscordAppDetails.c_str(); diff --git a/Client/core/CEntryHistory.h b/Client/core/CEntryHistory.h index 69e3414b4c5..45bbec1545f 100644 --- a/Client/core/CEntryHistory.h +++ b/Client/core/CEntryHistory.h @@ -66,7 +66,7 @@ class CEntryHistory // Return a specific entry from history CEntryHistoryItem* Get(unsigned int index) { - auto& iter = std::next(m_entries.begin(), index); + auto iter = std::next(m_entries.begin(), index); if (iter != m_entries.end()) return &(*iter); return nullptr; diff --git a/Client/core/CExceptionInformation_Impl.cpp b/Client/core/CExceptionInformation_Impl.cpp index ff7f28897df..b1cc2e2922d 100644 --- a/Client/core/CExceptionInformation_Impl.cpp +++ b/Client/core/CExceptionInformation_Impl.cpp @@ -10,179 +10,1092 @@ *****************************************************************************/ #include "StdInc.h" +#include "StackTraceHelpers.h" +#include "FastFailCrashHandler/WerCrashHandler.h" +#include +#include +#include -#define MAX_MODULE_PATH 512 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#pragma comment(lib, "dbghelp.lib") + +static void DebugPrintExceptionInfo([[maybe_unused]] const char* /*message*/) +{ +} + +[[nodiscard]] static bool ValidateExceptionContext(_EXCEPTION_POINTERS* pException) +{ + if (pException == nullptr) + return false; + + if (pException->ExceptionRecord == nullptr) + return false; + + const EXCEPTION_RECORD* pRecord = pException->ExceptionRecord; + if (pRecord->ExceptionCode == 0) + return false; + + // CUSTOM_EXCEPTION_CODE_OOM is a custom exception raised manually via RaiseException + // Always accept it for crash dump processing regardless of context state + if (pRecord->ExceptionCode == CUSTOM_EXCEPTION_CODE_OOM) + return true; + + // CUSTOM_EXCEPTION_CODE_WATCHDOG_TIMEOUT is a custom exception for frozen threads + // Always accept it for crash dump processing + if (pRecord->ExceptionCode == CUSTOM_EXCEPTION_CODE_WATCHDOG_TIMEOUT) + return true; + + // STATUS_FATAL_USER_CALLBACK_EXCEPTION (0xC000041D) - Windows often provides + // null or incomplete context for callback exceptions. Accept them anyway to generate dumps. + if (pRecord->ExceptionCode == 0xC000041D) + { + // Accept callback exceptions even with null context - we'll work with what we have + return true; + } + + // For other exceptions, require valid context to ensure we can extract meaningful information + if (pException->ContextRecord == nullptr) + return false; + + const CONTEXT* pContext = pException->ContextRecord; + + if (pContext->ContextFlags == 0) + return false; + + if (pContext->ContextFlags & CONTEXT_CONTROL) + { + if (pContext->Esp == 0) + { + return false; + } + } + + return true; +} + +constexpr std::size_t MAX_MODULE_PATH = 512; +constexpr std::size_t MAX_STACK_WALK_DEPTH = 16; +constexpr std::size_t MAX_STACK_FRAMES = 32; +constexpr std::size_t MAX_SYMBOL_NAME = 256; + +[[nodiscard]] static bool CopyModulePathToBuffer(const char* source, char* destination, std::size_t destinationSize, const char* context) +{ + if (source == nullptr || destination == nullptr || destinationSize == 0U) + return false; + + const errno_t copyResult = strncpy_s(destination, destinationSize, source, _TRUNCATE); + if (copyResult == STRUNCATE) + { + char buffer[DEBUG_BUFFER_SIZE] = {}; + SAFE_DEBUG_PRINT_C(buffer, DEBUG_BUFFER_SIZE, "%.*s%s - Module path truncated to %zu bytes\n", static_cast(DEBUG_PREFIX_EXCEPTION_INFO.size()), + DEBUG_PREFIX_EXCEPTION_INFO.data(), context, destinationSize - 1U); + return true; + } + + if (copyResult != 0) + { + char buffer[DEBUG_BUFFER_SIZE] = {}; + SAFE_DEBUG_PRINT_C(buffer, DEBUG_BUFFER_SIZE, "%.*s%s - strncpy_s failed (error=%d)\n", static_cast(DEBUG_PREFIX_EXCEPTION_INFO.size()), + DEBUG_PREFIX_EXCEPTION_INFO.data(), context, copyResult); + if (destinationSize > 0U) + destination[0] = '\0'; + return false; + } + + return true; +} + +struct StackFrameInfo +{ + std::string symbolName; + std::string fileName; + DWORD lineNumber; + DWORD64 address; + bool isValid; +}; +constexpr std::size_t MAX_FILE_NAME = 260; + +class SymbolHandlerGuard +{ +public: + explicit SymbolHandlerGuard(HANDLE process, bool enableSymbols) : m_process(process), m_initialized(false), m_uncaughtExceptions(std::uncaught_exceptions()) + { + if (!enableSymbols) + { + return; + } + + if (m_process != nullptr) + { + SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME | SYMOPT_FAIL_CRITICAL_ERRORS); + + if (SymInitialize(m_process, nullptr, TRUE) != FALSE) + { + m_initialized = true; + } + else + { + const DWORD dwError = GetLastError(); + char debugBuffer[DEBUG_BUFFER_SIZE] = {}; + SAFE_DEBUG_PRINT_C(debugBuffer, DEBUG_BUFFER_SIZE, "%.*sSymbolHandlerGuard: SymInitialize failed, error: %u\n", + static_cast(DEBUG_PREFIX_EXCEPTION_INFO.size()), DEBUG_PREFIX_EXCEPTION_INFO.data(), dwError); + } + } + } + + ~SymbolHandlerGuard() + { + if (m_initialized) + { + if (std::uncaught_exceptions() <= m_uncaughtExceptions) + { + SymCleanup(m_process); + } + m_initialized = false; + } + } + + SymbolHandlerGuard(const SymbolHandlerGuard&) = delete; + SymbolHandlerGuard& operator=(const SymbolHandlerGuard&) = delete; + SymbolHandlerGuard(SymbolHandlerGuard&&) = delete; + SymbolHandlerGuard& operator=(SymbolHandlerGuard&&) = delete; + + bool IsInitialized() const { return m_initialized; } + +private: + HANDLE m_process; + bool m_initialized; + int m_uncaughtExceptions; +}; + +[[nodiscard]] static std::optional> CaptureEnhancedStackTrace(_EXCEPTION_POINTERS* pException) +{ + if (pException == nullptr || pException->ContextRecord == nullptr) + return std::nullopt; + + const bool hasSymbols = CrashHandler::ProcessHasLocalDebugSymbols(); + if (!hasSymbols) + { + static std::once_flag logOnce; + std::call_once( + logOnce, + [] { SafeDebugPrintPrefixed(DEBUG_PREFIX_EXCEPTION_INFO, "CaptureEnhancedStackTrace - capturing without symbols (raw addresses only)\n"); }); + } + + std::vector frames; + frames.reserve(MAX_STACK_FRAMES); + + HANDLE hProcess = GetCurrentProcess(); + HANDLE hThread = GetCurrentThread(); + + CONTEXT context = *pException->ContextRecord; + STACKFRAME64 frame; + memset(&frame, 0, sizeof(frame)); + + frame.AddrPC.Offset = context.Eip; + frame.AddrFrame.Offset = context.Ebp; + frame.AddrStack.Offset = context.Esp; + + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Mode = AddrModeFlat; + + SymbolHandlerGuard symbolGuard(hProcess, hasSymbols); + + const bool useDbgHelp = symbolGuard.IsInitialized(); + + const auto routines = useDbgHelp ? StackTraceHelpers::MakeStackWalkRoutines(true) : StackTraceHelpers::MakeStackWalkRoutines(false); + alignas(SYMBOL_INFO) std::uint8_t symbolBuffer[sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME]; + memset(symbolBuffer, 0, sizeof(symbolBuffer)); + PSYMBOL_INFO pSymbol = reinterpret_cast(symbolBuffer); + pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); + pSymbol->MaxNameLen = MAX_SYMBOL_NAME; + + for (std::size_t frameIndex = 0; frameIndex < MAX_STACK_FRAMES; ++frameIndex) + { + BOOL bWalked = StackWalk64(IMAGE_FILE_MACHINE_I386, hProcess, hThread, &frame, &context, routines.readMemory, routines.functionTableAccess, + routines.moduleBase, nullptr); + if (bWalked == FALSE) + break; + + if (frame.AddrPC.Offset == 0) + break; + + StackFrameInfo frameInfo; + frameInfo.address = frame.AddrPC.Offset; + frameInfo.isValid = true; + + DWORD64 address = frame.AddrPC.Offset; + frameInfo.symbolName = StackTraceHelpers::FormatAddressWithModuleAndAbsolute(address); + + if (useDbgHelp) + { + DWORD64 displacement = 0; + if (SymFromAddr(hProcess, address, &displacement, pSymbol) != FALSE) + { + frameInfo.symbolName = pSymbol->Name[0] != '\0' ? pSymbol->Name : "unknown"; + } + + IMAGEHLP_LINE64 lineInfo; + memset(&lineInfo, 0, sizeof(lineInfo)); + lineInfo.SizeOfStruct = sizeof(lineInfo); + DWORD lineDisplacement = 0; + + if (SymGetLineFromAddr64(hProcess, address, &lineDisplacement, &lineInfo) != FALSE) + { + frameInfo.fileName = lineInfo.FileName ? lineInfo.FileName : "unknown"; + frameInfo.lineNumber = lineInfo.LineNumber; + } + else + { + frameInfo.fileName.clear(); + frameInfo.lineNumber = 0; + } + } + + frames.push_back(std::move(frameInfo)); + } + + if (frames.empty()) + return std::nullopt; + + std::vector result; + result.reserve(frames.size()); + for (const auto& frame : frames) + { + if (frame.isValid) + { + std::string frameStr = frame.symbolName; + if (!frame.fileName.empty()) + { + frameStr += " (" + frame.fileName + ":" + std::to_string(frame.lineNumber) + ")"; + } + result.push_back(frameStr); + } + } + return result; +} + +////////////////////////////////////////////////////////// +// +// ResolveModuleFromRegistrySafe_Inner +// +// Inner function that does the actual registry resolution work. +// Separated to allow SEH exception handling in the wrapper. +// This function may allocate memory and access registry, both of which +// can fail in a corrupted crash state. +// +////////////////////////////////////////////////////////// +struct ResolutionDiagnostics +{ + DWORD eipUsed = 0; + int failReason = 0; + int chunkCount = 0; + int moduleCount = 0; + int innerFailReason = 0; +}; + +static bool ResolveModuleFromRegistrySafe_Inner(_EXCEPTION_POINTERS* pException, void* pAddress, CExceptionInformation_Impl::ResolvedInfo& outInfo, + std::string& outNameStorage, ResolutionDiagnostics& diag) +{ + const DWORD eipForResolution = (pException->ContextRecord != nullptr) ? pException->ContextRecord->Eip : reinterpret_cast(pAddress); + + diag.eipUsed = eipForResolution; + + if (eipForResolution == 0) + { + diag.failReason = 1; + return false; + } + + auto resolvedInfo = WerCrash::ResolveAddressToModule(eipForResolution); + + diag.chunkCount = resolvedInfo.debugChunkCount; + diag.moduleCount = resolvedInfo.debugModuleCount; + diag.innerFailReason = resolvedInfo.debugFailReason; + + if (!resolvedInfo.resolved) + { + diag.failReason = 2; + return false; + } + + outInfo.resolved = true; + outInfo.moduleBase = resolvedInfo.moduleBase; + outInfo.rva = resolvedInfo.rva; + outInfo.idaAddress = resolvedInfo.idaAddress; + outNameStorage = resolvedInfo.moduleName.c_str(); + return true; +} + +////////////////////////////////////////////////////////// +// +// ResolveModuleFromRegistrySafe_SEH +// +// SEH-protected wrapper that catches ALL exceptions including access violations. +// Uses __try/__except which catches structured exceptions that C++ try-catch misses. +// CRITICAL: This must be in a separate function because SEH and C++ exception +// handling cannot coexist in the same function with local objects that have destructors. +// NO C++ objects with destructors allowed in this function! +// +////////////////////////////////////////////////////////// +static bool ResolveModuleFromRegistrySafe_SEH(_EXCEPTION_POINTERS* pException, void* pAddress, CExceptionInformation_Impl::ResolvedInfo& outInfo, + std::string& outNameStorage, ResolutionDiagnostics& diag) +{ + __try + { + return ResolveModuleFromRegistrySafe_Inner(pException, pAddress, outInfo, outNameStorage, diag); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + diag.failReason = 99; + return false; + } +} + +void CExceptionInformation_Impl::ResolveModuleFromRegistrySafe(_EXCEPTION_POINTERS* pException) +{ + OutputDebugStringA(">>> ResolveModuleFromRegistrySafe ENTRY <<<\n"); + + m_resolvedModuleInfo = {}; + m_resolvedModuleNameStorage.clear(); + + if (pException == nullptr) + { + OutputDebugStringA("ResolveModule: pException is NULL\n"); + return; + } + + ResolutionDiagnostics diag = {}; + + if (ResolveModuleFromRegistrySafe_SEH(pException, m_pAddress, m_resolvedModuleInfo, m_resolvedModuleNameStorage, diag)) + { + char buf[256]; + sprintf_s(buf, sizeof(buf), "ResolveModule: OK EIP=0x%08X Base=0x%08X RVA=0x%08X IDA=0x%08X Chunks=%d Mods=%d\n", diag.eipUsed, + m_resolvedModuleInfo.moduleBase, m_resolvedModuleInfo.rva, m_resolvedModuleInfo.idaAddress, diag.chunkCount, diag.moduleCount); + OutputDebugStringA(buf); + } + else + { + char buf[256]; + sprintf_s(buf, sizeof(buf), "ResolveModule: FAIL EIP=0x%08X Reason=%d Chunks=%d Mods=%d InnerFail=%d\n", diag.eipUsed, diag.failReason, diag.chunkCount, + diag.moduleCount, diag.innerFailReason); + OutputDebugStringA(buf); + + m_resolvedModuleInfo = {}; + m_resolvedModuleNameStorage.clear(); + } +} CExceptionInformation_Impl::CExceptionInformation_Impl() + : m_uiCode(0), + m_pAddress(nullptr), + m_szModulePathName(nullptr), + m_szModuleBaseName(nullptr), + m_moduleBaseNameStorage(), + m_uiAddressModuleOffset(0), + m_ulEAX(0), + m_ulEBX(0), + m_ulECX(0), + m_ulEDX(0), + m_ulESI(0), + m_ulEDI(0), + m_ulEBP(0), + m_ulESP(0), + m_ulEIP(0), + m_ulCS(0), + m_ulDS(0), + m_ulES(0), + m_ulFS(0), + m_ulGS(0), + m_ulSS(0), + m_ulEFlags(0), + m_stackTrace(), + m_timestamp(std::chrono::system_clock::now()), + m_threadId(GetCurrentThreadId()), + m_processId(GetCurrentProcessId()), + m_hasDetailedStackTrace(false), + m_capturedException(nullptr), + m_uncaughtExceptionCount(std::uncaught_exceptions()), + m_resolvedModuleInfo(), + m_resolvedModuleNameStorage() { - m_uiCode = 0; - m_pAddress = NULL; - m_szModulePathName = NULL; - m_szModuleBaseName = NULL; - m_uiAddressModuleOffset = 0; - m_ulEAX = 0; - m_ulEBX = 0; - m_ulECX = 0; - m_ulEDX = 0; - m_ulESI = 0; - m_ulEDI = 0; - m_ulEBP = 0; - m_ulESP = 0; - m_ulEIP = 0; - m_ulCS = 0; - m_ulDS = 0; - m_ulES = 0; - m_ulFS = 0; - m_ulGS = 0; - m_ulSS = 0; - m_ulEFlags = 0; } CExceptionInformation_Impl::~CExceptionInformation_Impl() { - if (m_szModulePathName) - delete m_szModulePathName; } -void CExceptionInformation_Impl::Set(unsigned int iCode, _EXCEPTION_POINTERS* pException) +void CExceptionInformation_Impl::Set(std::uint32_t iCode, _EXCEPTION_POINTERS* pException) { + OutputDebugStringA(">>> CExceptionInformation_Impl::Set ENTRY <<<\n"); + + if (!ValidateExceptionContext(pException)) + { + DebugPrintExceptionInfo("Set - Invalid exception context\n"); + return; + } + + // Allow null context for callback exceptions and other special cases (validated above) + const bool isCallbackException = (iCode == 0xC000041D); + if (pException->ContextRecord == nullptr && !isCallbackException) + { + DebugPrintExceptionInfo("Set - Null context record (exception type requires context)\n"); + return; + } + + if (pException->ContextRecord == nullptr && isCallbackException) + { + DebugPrintExceptionInfo("Set - Null context for callback exception - proceeding with limited info\n"); + } + + if (iCode == 0 || iCode > 0xFFFFFFFF) + { + DebugPrintExceptionInfo("Set - Invalid exception code\n"); + return; + } + m_uiCode = iCode; m_pAddress = pException->ExceptionRecord->ExceptionAddress; - m_ulEAX = pException->ContextRecord->Eax; - m_ulEBX = pException->ContextRecord->Ebx; - m_ulECX = pException->ContextRecord->Ecx; - m_ulEDX = pException->ContextRecord->Edx; - m_ulESI = pException->ContextRecord->Esi; - m_ulEDI = pException->ContextRecord->Edi; - m_ulEBP = pException->ContextRecord->Ebp; - m_ulESP = pException->ContextRecord->Esp; - m_ulEIP = pException->ContextRecord->Eip; - m_ulCS = pException->ContextRecord->SegCs; - m_ulDS = pException->ContextRecord->SegDs; - m_ulES = pException->ContextRecord->SegEs; - m_ulFS = pException->ContextRecord->SegFs; - m_ulGS = pException->ContextRecord->SegGs; - m_ulSS = pException->ContextRecord->SegSs; - m_ulEFlags = pException->ContextRecord->EFlags; - - // Find module where the problem emanated - m_szModulePathName = new char[MAX_MODULE_PATH]; - char* szModulePathNameTemp = new char[MAX_MODULE_PATH]; - void* pModuleBaseAddress = NULL; + ClearModulePathState(); + + OutputDebugStringA(">>> Set: Passed all validation, checking enhanced info <<<\n"); + + ENHANCED_EXCEPTION_INFO enhancedInfo = {}; + bool hasEnhancedInfo = (GetEnhancedExceptionInfo(&enhancedInfo) != FALSE); + + { + char debugBuf[128]; + sprintf_s(debugBuf, sizeof(debugBuf), ">>> Set: GetEnhancedExceptionInfo returned %s <<<\n", hasEnhancedInfo ? "TRUE" : "FALSE"); + OutputDebugStringA(debugBuf); + if (hasEnhancedInfo) + { + sprintf_s(debugBuf, sizeof(debugBuf), ">>> Set: Enhanced code=0x%08X, current code=0x%08X <<<\n", enhancedInfo.exceptionCode, iCode); + OutputDebugStringA(debugBuf); + } + } + + if (hasEnhancedInfo && enhancedInfo.exceptionCode == iCode) + { + DebugPrintExceptionInfo("Set - Using enhanced exception info from CrashHandler (FRESH)\n"); + + // Additional note for callback exceptions even when we have enhanced info + if (iCode == 0xC000041D) + { + DebugPrintExceptionInfo("Set - Callback exception: enhanced info available but stack/module may be incomplete\n"); + } + } + else if (hasEnhancedInfo && enhancedInfo.exceptionCode != iCode) + { + char mismatchBuffer[DEBUG_BUFFER_SIZE] = {}; + SAFE_DEBUG_PRINT_C(mismatchBuffer, DEBUG_BUFFER_SIZE, + "%.*sSet - Exception code mismatch (stored: 0x%08X, current: 0x%08X) - STALE DATA, extracting fresh\n", + static_cast(DEBUG_PREFIX_EXCEPTION_INFO.size()), DEBUG_PREFIX_EXCEPTION_INFO.data(), enhancedInfo.exceptionCode, iCode); + hasEnhancedInfo = false; + } + else if (!hasEnhancedInfo) + { + DebugPrintExceptionInfo("Set - No enhanced info available, extracting manually\n"); + } + + if (hasEnhancedInfo) + { + m_uiAddressModuleOffset = enhancedInfo.moduleOffset; + m_timestamp = enhancedInfo.timestamp; + m_threadId = enhancedInfo.threadId; + m_processId = enhancedInfo.processId; + m_uncaughtExceptionCount = enhancedInfo.uncaughtExceptionCount; + m_capturedException = enhancedInfo.capturedException.value_or(nullptr); + + if (!enhancedInfo.modulePathName.empty()) + { + const std::size_t pathLen = enhancedInfo.modulePathName.length() + 1U; + std::unique_ptr enhancedPathBuffer(new (std::nothrow) char[pathLen]); + if (!enhancedPathBuffer) + { + DebugPrintExceptionInfo("Set - Failed to allocate enhanced module path buffer\n"); + } + else + { + memcpy(enhancedPathBuffer.get(), enhancedInfo.modulePathName.c_str(), pathLen); + m_szModulePathName = std::move(enhancedPathBuffer); + UpdateModuleBaseNameFromCurrentPath(); + } + } + + m_ulEAX = enhancedInfo.eax; + m_ulEBX = enhancedInfo.ebx; + m_ulECX = enhancedInfo.ecx; + m_ulEDX = enhancedInfo.edx; + m_ulESI = enhancedInfo.esi; + m_ulEDI = enhancedInfo.edi; + m_ulEBP = enhancedInfo.ebp; + m_ulESP = enhancedInfo.esp; + m_ulEIP = enhancedInfo.eip; + m_ulCS = enhancedInfo.cs; + m_ulDS = enhancedInfo.ds; + m_ulES = enhancedInfo.es; + m_ulFS = enhancedInfo.fs; + m_ulGS = enhancedInfo.gs; + m_ulSS = enhancedInfo.ss; + m_ulEFlags = enhancedInfo.eflags; + + if (auto trace = enhancedInfo.stackTrace) + { + m_stackTrace = *trace; + m_hasDetailedStackTrace = true; + } + + OutputDebugStringA(">>> Set: Enhanced path - calling ResolveModuleFromRegistrySafe <<<\n"); + ResolveModuleFromRegistrySafe(pException); + return; + } + + try + { + m_timestamp = std::chrono::system_clock::now(); + m_threadId = GetCurrentThreadId(); + m_processId = GetCurrentProcessId(); + m_uncaughtExceptionCount = std::uncaught_exceptions(); + + if (std::uncaught_exceptions() > 0) + { + try + { + m_capturedException = std::current_exception(); + } + catch (...) + { + m_capturedException = nullptr; + } + } + else + { + m_capturedException = nullptr; + } + } + catch (...) + { + m_threadId = GetCurrentThreadId(); + m_processId = GetCurrentProcessId(); + m_uncaughtExceptionCount = 0; + m_capturedException = nullptr; + } + + // Only access ContextRecord if it's not null (can be null for certain exception types) + if (pException->ContextRecord != nullptr) + { + m_ulEAX = pException->ContextRecord->Eax; + m_ulEBX = pException->ContextRecord->Ebx; + m_ulECX = pException->ContextRecord->Ecx; + m_ulEDX = pException->ContextRecord->Edx; + m_ulESI = pException->ContextRecord->Esi; + m_ulEDI = pException->ContextRecord->Edi; + m_ulEBP = pException->ContextRecord->Ebp; + m_ulESP = pException->ContextRecord->Esp; + m_ulEIP = pException->ContextRecord->Eip; + m_ulCS = pException->ContextRecord->SegCs; + m_ulDS = pException->ContextRecord->SegDs; + m_ulES = pException->ContextRecord->SegEs; + m_ulFS = pException->ContextRecord->SegFs; + m_ulGS = pException->ContextRecord->SegGs; + m_ulSS = pException->ContextRecord->SegSs; + m_ulEFlags = pException->ContextRecord->EFlags; + } + else + { + // No context available - zero out all registers + DebugPrintExceptionInfo("Set - Null context, zeroing register values\n"); + m_ulEAX = 0; + m_ulEBX = 0; + m_ulECX = 0; + m_ulEDX = 0; + m_ulESI = 0; + m_ulEDI = 0; + m_ulEBP = 0; + m_ulESP = 0; + m_ulEIP = 0; + m_ulCS = 0; + m_ulDS = 0; + m_ulES = 0; + m_ulFS = 0; + m_ulGS = 0; + m_ulSS = 0; + m_ulEFlags = 0; + } + + std::unique_ptr modulePathNameBuffer(new (std::nothrow) char[MAX_MODULE_PATH]); + std::unique_ptr tempModulePathBuffer(new (std::nothrow) char[MAX_MODULE_PATH]); + + if (!modulePathNameBuffer || !tempModulePathBuffer) + { + DebugPrintExceptionInfo("Set - Failed to allocate buffers\n"); + return; + } + + modulePathNameBuffer[0] = '\0'; + tempModulePathBuffer[0] = '\0'; + + void* pModuleBaseAddress = nullptr; void* pExceptionAddress = m_pAddress; void* pQueryAddress = m_pAddress; - for (uint i = 0; i < 16; i++) + + // Special handling for EIP=0: Start from return address at [ESP] instead + constexpr auto kNullAddress = uintptr_t{0}; + static_assert(kNullAddress == 0, "Null address must be zero"); + + const auto queryAddressValue = reinterpret_cast(pQueryAddress); + + if (queryAddressValue == kNullAddress && m_ulEIP == kNullAddress) + { + const auto espAddr = static_cast(m_ulESP); + const auto pReturnAddress = reinterpret_cast(espAddr); + + char debugBuffer[DEBUG_BUFFER_SIZE] = {}; + SAFE_DEBUG_PRINT_C(debugBuffer, DEBUG_BUFFER_SIZE, "%.*sSet - EIP=0 detected (ESP=0x%08X), attempting to read return address...\n", + static_cast(DEBUG_PREFIX_EXCEPTION_INFO.size()), DEBUG_PREFIX_EXCEPTION_INFO.data(), static_cast(espAddr)); + + if (SharedUtil::IsReadablePointer(pReturnAddress, sizeof(void*))) + { + pQueryAddress = *pReturnAddress; + pExceptionAddress = pQueryAddress; + + const auto returnAddressValue = reinterpret_cast(pQueryAddress); + SAFE_DEBUG_PRINT_C(debugBuffer, DEBUG_BUFFER_SIZE, "%.*sSet - Successfully read return address: 0x%08X\n", + static_cast(DEBUG_PREFIX_EXCEPTION_INFO.size()), DEBUG_PREFIX_EXCEPTION_INFO.data(), + static_cast(returnAddressValue)); + } + else + { + SAFE_DEBUG_PRINT_C(debugBuffer, DEBUG_BUFFER_SIZE, "%.*sSet - Failed to read return address at ESP=0x%08X (not readable)\n", + static_cast(DEBUG_PREFIX_EXCEPTION_INFO.size()), DEBUG_PREFIX_EXCEPTION_INFO.data(), static_cast(espAddr)); + } + } + + for (std::size_t i = 0; i < MAX_STACK_WALK_DEPTH; ++i) { - void* pModuleBaseAddressTemp = NULL; - GetModule(pQueryAddress, szModulePathNameTemp, MAX_MODULE_PATH, &pModuleBaseAddressTemp); - const char* szModuleBaseNameTemp = strrchr(szModulePathNameTemp, '\\'); - szModuleBaseNameTemp = szModuleBaseNameTemp ? szModuleBaseNameTemp + 1 : szModulePathNameTemp; + void* pModuleBaseAddressTemp = nullptr; + + if (pQueryAddress == nullptr || !SharedUtil::IsReadablePointer(pQueryAddress, sizeof(void*))) + { + DebugPrintExceptionInfo("Set - Invalid stack address during walk\n"); + break; + } + + if (!GetModule(pQueryAddress, tempModulePathBuffer.get(), static_cast(MAX_MODULE_PATH), &pModuleBaseAddressTemp)) + { + DebugPrintExceptionInfo("Set - Failed to get module info\n"); + break; + } + + const std::string_view tempPathView(tempModulePathBuffer.get()); + auto tempBaseNamePos = tempPathView.find_last_of('\\'); + const char* szModuleBaseNameTemp = + tempBaseNamePos != std::string_view::npos ? tempModulePathBuffer.get() + tempBaseNamePos + 1 : tempModulePathBuffer.get(); + + if (szModuleBaseNameTemp == nullptr) + { + szModuleBaseNameTemp = tempModulePathBuffer.get(); + } - // Save first result if (i == 0) { - STRNCPY(m_szModulePathName, szModulePathNameTemp, MAX_MODULE_PATH); + const bool copied = + CopyModulePathToBuffer(tempModulePathBuffer.get(), modulePathNameBuffer.get(), MAX_MODULE_PATH, "Set - Initial module path copy"); + if (!copied) + { + DebugPrintExceptionInfo("Set - Initial module path copy failed\n"); + } pModuleBaseAddress = pModuleBaseAddressTemp; pExceptionAddress = pQueryAddress; } - // Use this result if it looks good - if (strnicmp(szModuleBaseNameTemp, "ntdll", 5) != 0 && strnicmp(szModuleBaseNameTemp, "kernel", 6) != 0 && - strnicmp(szModuleBaseNameTemp, "msvc", 4) != 0 && stricmp(szModuleBaseNameTemp, "") != 0) + if (::_strnicmp(szModuleBaseNameTemp, "ntdll", 5) != 0 && ::_strnicmp(szModuleBaseNameTemp, "kernel", 6) != 0 && + ::_strnicmp(szModuleBaseNameTemp, "msvc", 4) != 0 && ::_stricmp(szModuleBaseNameTemp, "") != 0) { - STRNCPY(m_szModulePathName, szModulePathNameTemp, MAX_MODULE_PATH); + const bool copied = + CopyModulePathToBuffer(tempModulePathBuffer.get(), modulePathNameBuffer.get(), MAX_MODULE_PATH, "Set - Selected module path copy"); + if (!copied) + { + DebugPrintExceptionInfo("Set - Selected module path copy failed\n"); + } pModuleBaseAddress = pModuleBaseAddressTemp; pExceptionAddress = pQueryAddress; break; } - // Try next address up the stack - __try + const uintptr_t espAddr = static_cast(m_ulESP); + const uintptr_t offset = i * sizeof(void*); + + if (offset > UINTPTR_MAX - espAddr) + { + DebugPrintExceptionInfo("Set - Stack address calculation overflow\n"); + break; + } + + const auto stackAddress = espAddr + offset; + void** stackEntry = reinterpret_cast(stackAddress); + + if (!SharedUtil::IsReadablePointer(stackEntry, sizeof(*stackEntry))) + { + DebugPrintExceptionInfo("Set - Stack walk encountered unreadable memory\n"); + break; + } + + void* stackValue = nullptr; + if (SharedUtil::IsReadablePointer(stackEntry, sizeof(*stackEntry))) { - pQueryAddress = *(ulong**)(m_ulESP + i * 4); + stackValue = *stackEntry; } - __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) + + if (stackValue == nullptr) { + DebugPrintExceptionInfo("Set - Stack walk encountered null pointer\n"); break; } + + pQueryAddress = stackValue; } - m_szModuleBaseName = strrchr(m_szModulePathName, '\\'); - m_szModuleBaseName = m_szModuleBaseName ? m_szModuleBaseName + 1 : m_szModulePathName; - m_uiAddressModuleOffset = static_cast(pExceptionAddress) - static_cast(pModuleBaseAddress); + m_szModulePathName = std::move(modulePathNameBuffer); + UpdateModuleBaseNameFromCurrentPath(); + + if (pModuleBaseAddress != nullptr && pExceptionAddress != nullptr) + { + const uintptr_t baseAddr = reinterpret_cast(pModuleBaseAddress); + const uintptr_t exceptionAddr = reinterpret_cast(pExceptionAddress); + + if (exceptionAddr >= baseAddr) + { + const uintptr_t offset = exceptionAddr - baseAddr; + + if (offset <= UINT_MAX) + { + m_uiAddressModuleOffset = static_cast(offset); + } + else + { + m_uiAddressModuleOffset = 0; + DebugPrintExceptionInfo("Set - Module offset too large\n"); + } + } + else + { + m_uiAddressModuleOffset = 0; + DebugPrintExceptionInfo("Set - Exception address before module base\n"); + } + } + else + { + m_uiAddressModuleOffset = 0; + } + + OutputDebugStringA(">>> Set: About to call ResolveModuleFromRegistrySafe <<<\n"); + + // Resolve module info from registry as an independent source of truth + // This uses pre-captured module bases and provides IDA-compatible offsets + // CRITICAL: This is done in a separate phase AFTER all essential crash data is collected + // to ensure a secondary failure here doesn't prevent core crash handling + ResolveModuleFromRegistrySafe(pException); + + try + { + if (CaptureUnifiedStackTrace(pException, 0, &m_stackTrace) != FALSE) + { + m_hasDetailedStackTrace = true; + DebugPrintExceptionInfo("Set - Unified stack trace captured successfully\n"); + } + else + { + m_hasDetailedStackTrace = false; + DebugPrintExceptionInfo("Set - Unified stack trace capture failed\n"); + } + } + catch (...) + { + m_hasDetailedStackTrace = false; + DebugPrintExceptionInfo("Set - Stack trace capture failed with exception\n"); + } } -/** - * Returns the name of the module in which the exception occured, or - * an emtpy string if the module could not be found. - * - * @return true if successful, false otherwise. - */ bool CExceptionInformation_Impl::GetModule(void* pQueryAddress, char* szOutputBuffer, int nOutputNameLength, void** ppModuleBaseAddress) { - HMODULE hModule; + if (pQueryAddress == nullptr || szOutputBuffer == nullptr || ppModuleBaseAddress == nullptr) + { + DebugPrintExceptionInfo("GetModule - Invalid parameters\n"); + return false; + } - if (szOutputBuffer == NULL) + if (nOutputNameLength <= 0) + { + DebugPrintExceptionInfo("GetModule - Invalid buffer length\n"); return false; + } - /* - * NUL out the first char in the output buffer. - */ - szOutputBuffer[0] = 0; + szOutputBuffer[0] = '\0'; + *ppModuleBaseAddress = nullptr; - if (nOutputNameLength == 0) + using GetModuleHandleExA_t = BOOL(WINAPI*)(DWORD, LPCSTR, HMODULE*); + + HMODULE hKern32 = GetModuleHandleA("kernel32.dll"); + if (hKern32 == nullptr) + { + DebugPrintExceptionInfo("GetModule - Failed to get kernel32 handle\n"); return false; + } - /* - * GetModuleHandleExA isn't supported under Windows 2000. - */ - typedef BOOL(WINAPI * _pfnGetModuleHandleExA)(DWORD, LPCSTR, HMODULE*); + GetModuleHandleExA_t pfnGetModuleHandleExA = nullptr; + if (!SharedUtil::TryGetProcAddress(hKern32, "GetModuleHandleExA", pfnGetModuleHandleExA)) + { + DebugPrintExceptionInfo("GetModule - GetModuleHandleExA not available\n"); + return false; + } - /* - * Get kernel32.dll's HMODULE. - */ - HMODULE hKern32 = GetModuleHandleA("kernel32.dll"); - if (NULL == hKern32) + HMODULE hModule = nullptr; + + // Wrap in __try for exception addresses that may be invalid/in guard pages/trampolines + // (callbacks, corrupted stacks, etc. can point to invalid memory) + __try + { + if (pfnGetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, static_cast(pQueryAddress), + &hModule) == 0) + { + const DWORD dwErrorHandle = GetLastError(); + char debugBuffer[DEBUG_BUFFER_SIZE] = {}; + SAFE_DEBUG_PRINT_C(debugBuffer, DEBUG_BUFFER_SIZE, "%.*sGetModule - GetModuleHandleExA failed (0x%08X)\n", + static_cast(DEBUG_PREFIX_EXCEPTION_INFO.size()), DEBUG_PREFIX_EXCEPTION_INFO.data(), dwErrorHandle); + + // Address may be a system trampoline or invalid memory - don't proceed + return false; + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + char debugBuffer[DEBUG_BUFFER_SIZE] = {}; + SAFE_DEBUG_PRINT_C(debugBuffer, DEBUG_BUFFER_SIZE, "%.*sGetModule - Exception accessing address 0x%p (invalid/trampoline address)\n", + static_cast(DEBUG_PREFIX_EXCEPTION_INFO.size()), DEBUG_PREFIX_EXCEPTION_INFO.data(), pQueryAddress); + // Don't proceed with invalid module info return false; + } - /* - * See if we're able to use GetModuleHandleExA. According to Microsoft, - * this API is only available on Windows XP and Vista. - */ - _pfnGetModuleHandleExA pfnGetModuleHandleExA = (_pfnGetModuleHandleExA)GetProcAddress(hKern32, "GetModuleHandleExA"); + *ppModuleBaseAddress = hModule; - /* - * TODO: Possibly use our own code to do this for other systems. - * It is possible to enumerate all modules and get their starting/ending - * offsets, so it would just be a simple comparison of addresses to - * do this... - */ - if (NULL == pfnGetModuleHandleExA) + const DWORD dwResult = GetModuleFileNameA(hModule, szOutputBuffer, nOutputNameLength); + if (dwResult == 0) + { + const DWORD dwErrorFileName = GetLastError(); + char debugBuffer[DEBUG_BUFFER_SIZE] = {}; + SAFE_DEBUG_PRINT_C(debugBuffer, DEBUG_BUFFER_SIZE, "%.*sGetModule - GetModuleFileNameA failed (0x%08X)\n", + static_cast(DEBUG_PREFIX_EXCEPTION_INFO.size()), DEBUG_PREFIX_EXCEPTION_INFO.data(), dwErrorFileName); + szOutputBuffer[0] = '\0'; return false; + } + + if (static_cast(dwResult) >= nOutputNameLength) + { + szOutputBuffer[nOutputNameLength - 1] = '\0'; + DebugPrintExceptionInfo("GetModule - Module path truncated\n"); + } - if (0 == pfnGetModuleHandleExA(0x00000004 /*GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS*/, (LPCSTR)pQueryAddress, &hModule)) + if (szOutputBuffer != nullptr && strlen(szOutputBuffer) == 0) { + DebugPrintExceptionInfo("GetModule - Empty module path\n"); return false; } - *ppModuleBaseAddress = hModule; + return true; +} + +struct ExceptionDetails +{ + DWORD code; + void* address; + std::string_view description; + bool isValid; +}; - if (0 != GetModuleFileNameA(hModule, szOutputBuffer, nOutputNameLength)) +[[nodiscard]] static ExceptionDetails GetExceptionDetails(_EXCEPTION_POINTERS* pException) +{ + if (pException == nullptr || pException->ExceptionRecord == nullptr) { - /* - * GetModuleFileNameA will return nOutputNameLength to us - * if the buffer is too small. NUL term the buffer. - * - * TODO: Check GetLastError() and actually grow the buffer - * and retry if it is too small. - */ - if (nOutputNameLength) - szOutputBuffer[nOutputNameLength - 1] = 0; + return ExceptionDetails{0, nullptr, "Invalid exception", false}; + } - return true; + const auto& record = *pException->ExceptionRecord; + return ExceptionDetails{record.ExceptionCode, record.ExceptionAddress, "Valid exception", true}; +} + +std::optional> CExceptionInformation_Impl::GetStackTrace() const +{ + if (!m_hasDetailedStackTrace || m_stackTrace.empty()) + return std::nullopt; + + return m_stackTrace; +} + +std::optional CExceptionInformation_Impl::GetTimestamp() const +{ + return m_timestamp; +} + +DWORD CExceptionInformation_Impl::GetThreadId() const +{ + return m_threadId; +} + +DWORD CExceptionInformation_Impl::GetProcessId() const +{ + return m_processId; +} + +std::string CExceptionInformation_Impl::GetExceptionDescription() const +{ + std::string description; + description.reserve(256); + + char buffer[DEBUG_BUFFER_SIZE] = {}; + SAFE_DEBUG_PRINT_C(buffer, DEBUG_BUFFER_SIZE, "Exception 0x%08X", m_uiCode); + description = buffer; + + if (m_szModuleBaseName != nullptr) + { + description += " in "; + description += m_szModuleBaseName; + if (m_uiAddressModuleOffset > 0) + { + SAFE_DEBUG_PRINT_C(buffer, DEBUG_BUFFER_SIZE, "+0x%08X", m_uiAddressModuleOffset); + description += buffer; + } + } + + SAFE_DEBUG_PRINT_C(buffer, DEBUG_BUFFER_SIZE, " (Thread: %u)", m_threadId); + description += buffer; + + return description; +} + +bool CExceptionInformation_Impl::HasDetailedStackTrace() const +{ + return m_hasDetailedStackTrace; +} + +std::optional CExceptionInformation_Impl::GetCapturedException() const +{ + return m_capturedException ? std::optional{m_capturedException} : std::nullopt; +} + +int CExceptionInformation_Impl::GetUncaughtExceptionCount() const +{ + return m_uncaughtExceptionCount; +} + +void CExceptionInformation_Impl::CaptureCurrentException() +{ + const int uncaught = std::uncaught_exceptions(); + if (uncaught <= 0) + { + m_capturedException = nullptr; + m_uncaughtExceptionCount = 0; + return; + } + + try + { + m_capturedException = std::current_exception(); + } + catch (...) + { + m_capturedException = nullptr; + } + + m_uncaughtExceptionCount = uncaught; +} + +void CExceptionInformation_Impl::UpdateModuleBaseNameFromCurrentPath() +{ + m_moduleBaseNameStorage.clear(); + m_szModuleBaseName = nullptr; + + if (!m_szModulePathName) + return; + + const char* path = m_szModulePathName.get(); + if (path == nullptr || path[0] == '\0') + return; + + std::string_view pathView(path); + const auto separatorPos = pathView.find_last_of("\\/"); + std::string_view baseView = separatorPos != std::string_view::npos ? pathView.substr(separatorPos + 1) : pathView; + if (baseView.empty()) + return; + + m_moduleBaseNameStorage.assign(baseView.begin(), baseView.end()); + m_szModuleBaseName = m_moduleBaseNameStorage.c_str(); +} + +void CExceptionInformation_Impl::ClearModulePathState() +{ + m_szModulePathName.reset(); + m_moduleBaseNameStorage.clear(); + m_szModuleBaseName = nullptr; +} + +[[nodiscard]] static std::optional GetSafeModulePath(std::string_view modulePath) +{ + try + { + std::filesystem::path path(modulePath); + + if (!std::filesystem::exists(path)) + { + return std::nullopt; + } + + auto absolutePath = std::filesystem::absolute(path); + + return absolutePath.string(); } + catch (...) + { + return std::nullopt; + } +} - szOutputBuffer[0] = 0; +[[nodiscard]] static std::optional> CaptureMemoryDump(void* address, std::size_t size) +{ + if (address == nullptr || size == 0) + return std::nullopt; - return false; + if (!SharedUtil::IsReadablePointer(address, size)) + { + DebugPrintExceptionInfo("CaptureMemoryDump - Memory region not readable\n"); + return std::nullopt; + } + + try + { + std::vector memoryDump(size); + const auto* source = static_cast(address); + std::memcpy(memoryDump.data(), source, size); + return memoryDump; + } + catch (...) + { + DebugPrintExceptionInfo("CaptureMemoryDump - Failed to allocate buffer\n"); + return std::nullopt; + } } diff --git a/Client/core/CExceptionInformation_Impl.h b/Client/core/CExceptionInformation_Impl.h index 06305acd41e..b0fe50e0f41 100644 --- a/Client/core/CExceptionInformation_Impl.h +++ b/Client/core/CExceptionInformation_Impl.h @@ -13,59 +13,114 @@ #include #include +#include +#include +#include +#include +#include +#include +#include class CExceptionInformation_Impl : public CExceptionInformation { public: CExceptionInformation_Impl(); - ~CExceptionInformation_Impl(); // {}; - - unsigned int GetCode() { return m_uiCode; }; - void* GetAddress() { return m_pAddress; }; - bool GetModule(void* pQueryAddress, char* szModuleName, int nOutputNameLength, void** ppModuleBaseAddress); - virtual const char* GetModulePathName() { return m_szModulePathName; }; - virtual const char* GetModuleBaseName() { return m_szModuleBaseName; }; - virtual uint GetAddressModuleOffset() { return m_uiAddressModuleOffset; }; - - unsigned long GetEAX() { return m_ulEAX; }; - unsigned long GetEBX() { return m_ulEBX; }; - unsigned long GetECX() { return m_ulECX; }; - unsigned long GetEDX() { return m_ulEDX; }; - unsigned long GetESI() { return m_ulESI; }; - unsigned long GetEDI() { return m_ulEDI; }; - unsigned long GetEBP() { return m_ulEBP; }; - unsigned long GetESP() { return m_ulESP; }; - unsigned long GetEIP() { return m_ulEIP; }; - unsigned long GetCS() { return m_ulCS; }; - unsigned long GetDS() { return m_ulDS; }; - unsigned long GetES() { return m_ulES; }; - unsigned long GetFS() { return m_ulFS; }; - unsigned long GetGS() { return m_ulGS; }; - unsigned long GetSS() { return m_ulSS; }; - unsigned long GetEFlags() { return m_ulEFlags; }; - - void Set(unsigned int iCode, _EXCEPTION_POINTERS* pException); + ~CExceptionInformation_Impl(); + + unsigned int GetCode() { return m_uiCode; } + void* GetAddress() { return m_pAddress; } + [[nodiscard]] bool GetModule(void* pQueryAddress, char* szModuleName, int nOutputNameLength, void** ppModuleBaseAddress); + + virtual const char* GetModulePathName() override { return m_szModulePathName.get(); } + virtual const char* GetModuleBaseName() override { return m_szModuleBaseName; } + virtual uint GetAddressModuleOffset() override { return m_uiAddressModuleOffset; } + + unsigned long GetEAX() { return m_ulEAX; } + unsigned long GetEBX() { return m_ulEBX; } + unsigned long GetECX() { return m_ulECX; } + unsigned long GetEDX() { return m_ulEDX; } + unsigned long GetESI() { return m_ulESI; } + unsigned long GetEDI() { return m_ulEDI; } + unsigned long GetEBP() { return m_ulEBP; } + unsigned long GetESP() { return m_ulESP; } + unsigned long GetEIP() { return m_ulEIP; } + unsigned long GetCS() { return m_ulCS; } + unsigned long GetDS() { return m_ulDS; } + unsigned long GetES() { return m_ulES; } + unsigned long GetFS() { return m_ulFS; } + unsigned long GetGS() { return m_ulGS; } + unsigned long GetSS() { return m_ulSS; } + unsigned long GetEFlags() { return m_ulEFlags; } + + void Set(std::uint32_t iCode, _EXCEPTION_POINTERS* pException); + + [[nodiscard]] std::optional> GetStackTrace() const; + [[nodiscard]] std::optional GetTimestamp() const; + [[nodiscard]] DWORD GetThreadId() const; + [[nodiscard]] DWORD GetProcessId() const; + [[nodiscard]] std::string GetExceptionDescription() const; + [[nodiscard]] bool HasDetailedStackTrace() const; + + [[nodiscard]] std::optional GetCapturedException() const; + [[nodiscard]] int GetUncaughtExceptionCount() const; + void CaptureCurrentException(); + + // Registry-resolved module info (independent source of truth, IDA-compatible offsets) + [[nodiscard]] bool HasResolvedModuleInfo() const { return m_resolvedModuleInfo.resolved; } + [[nodiscard]] const char* GetResolvedModuleName() const { return m_resolvedModuleNameStorage.c_str(); } + [[nodiscard]] DWORD GetResolvedModuleBase() const { return m_resolvedModuleInfo.moduleBase; } + [[nodiscard]] DWORD GetResolvedRva() const { return m_resolvedModuleInfo.rva; } + [[nodiscard]] DWORD GetResolvedIdaAddress() const { return m_resolvedModuleInfo.idaAddress; } private: - unsigned int m_uiCode; - void* m_pAddress; - char* m_szModulePathName; - const char* m_szModuleBaseName; - uint m_uiAddressModuleOffset; - unsigned long m_ulEAX; - unsigned long m_ulEBX; - unsigned long m_ulECX; - unsigned long m_ulEDX; - unsigned long m_ulESI; - unsigned long m_ulEDI; - unsigned long m_ulEBP; - unsigned long m_ulESP; - unsigned long m_ulEIP; - unsigned long m_ulCS; - unsigned long m_ulDS; - unsigned long m_ulES; - unsigned long m_ulFS; - unsigned long m_ulGS; - unsigned long m_ulSS; - unsigned long m_ulEFlags; + std::uint32_t m_uiCode; + void* m_pAddress; + std::unique_ptr m_szModulePathName; + const char* m_szModuleBaseName; + std::string m_moduleBaseNameStorage; + uint m_uiAddressModuleOffset; + unsigned long m_ulEAX; + unsigned long m_ulEBX; + unsigned long m_ulECX; + unsigned long m_ulEDX; + unsigned long m_ulESI; + unsigned long m_ulEDI; + unsigned long m_ulEBP; + unsigned long m_ulESP; + unsigned long m_ulEIP; + unsigned long m_ulCS; + unsigned long m_ulDS; + unsigned long m_ulES; + unsigned long m_ulFS; + unsigned long m_ulGS; + unsigned long m_ulSS; + unsigned long m_ulEFlags; + + std::vector m_stackTrace; + std::chrono::system_clock::time_point m_timestamp; + DWORD m_threadId; + DWORD m_processId; + bool m_hasDetailedStackTrace; + + std::exception_ptr m_capturedException; + int m_uncaughtExceptionCount; + +public: + // Registry-resolved module info (independent source of truth) + // Public to allow SEH-protected helper functions to access + struct ResolvedInfo + { + bool resolved = false; + DWORD moduleBase = 0; + DWORD rva = 0; + DWORD idaAddress = 0; + }; + +private: + ResolvedInfo m_resolvedModuleInfo; + std::string m_resolvedModuleNameStorage; + + void UpdateModuleBaseNameFromCurrentPath(); + void ClearModulePathState(); + void ResolveModuleFromRegistrySafe(_EXCEPTION_POINTERS* pException); }; diff --git a/Client/core/CFileFormat.h b/Client/core/CFileFormat.h index 07ec4058a5f..1be2401a916 100644 --- a/Client/core/CFileFormat.h +++ b/Client/core/CFileFormat.h @@ -8,11 +8,15 @@ * *****************************************************************************/ +#pragma once + +#include + // Jpeg stuff bool IsJpeg(const void* pData, uint uiDataSize); -bool JpegGetDimensions(const void* pData, uint uiDataSize, uint& uiOutWidth, uint& uiOutHeight); -bool JpegEncode(uint uiWidth, uint uiHeight, uint uiQuality, const void* pData, uint uiDataSize, CBuffer& outBuffer); -bool JpegDecode(const void* pData, uint uiDataSize, CBuffer* pOutBuffer, uint& uiOutWidth, uint& uiOutHeight); +bool JpegGetDimensions(const void* pData, uint uiDataSize, uint& uiOutWidth, uint& uiOutHeight, std::string* pOutError = nullptr); +bool JpegEncode(uint uiWidth, uint uiHeight, uint uiQuality, const void* pData, uint uiDataSize, CBuffer& outBuffer, std::string* pOutError = nullptr); +bool JpegDecode(const void* pData, uint uiDataSize, CBuffer* pOutBuffer, uint& uiOutWidth, uint& uiOutHeight, std::string* pOutError = nullptr); // Png stuff bool IsPng(const void* pData, uint uiDataSize); diff --git a/Client/core/CFileFormatJpeg.cpp b/Client/core/CFileFormatJpeg.cpp index e61532d7046..bc640910470 100644 --- a/Client/core/CFileFormatJpeg.cpp +++ b/Client/core/CFileFormatJpeg.cpp @@ -11,22 +11,32 @@ #include "StdInc.h" #include "jinclude.h" #include "jpeglib.h" -#include "jerror.h" /* get library error codes too */ -#include "cderror.h" /* get application-specific error codes */ - -/////////////////////////////////////////////////////////////// -// -// IsJpeg -// -// Check if probably jpeg -// -/////////////////////////////////////////////////////////////// +#include "jerror.h" /* get library error codes too */ +#include "cderror.h" /* get application-specific error codes */ + +// Custom error handler for libjpeg - allows recovery instead of exit() +struct JpegErrorManager +{ + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; +}; + +static void JpegErrorExit(j_common_ptr cinfo) +{ + JpegErrorManager* myerr = reinterpret_cast(cinfo->err); + longjmp(myerr->setjmp_buffer, 1); +} + bool IsJpeg(const void* pData, uint uiDataSize) { + if (!pData || uiDataSize == 0) + return false; + static uchar JpegHeader[] = {0xFF, 0xD8, 0xFF}; static uchar JpegTail[] = {0xFF, 0xD9}; - if (uiDataSize >= sizeof(JpegHeader) + sizeof(JpegTail)) + // Need header (3), segment size (2 at offset 4-5), and tail (2) + if (uiDataSize >= 6) { if (memcmp(pData, JpegHeader, sizeof(JpegHeader)) == 0 && memcmp((BYTE*)pData + uiDataSize - sizeof(JpegTail), JpegTail, sizeof(JpegTail)) == 0) { @@ -45,150 +55,311 @@ bool IsJpeg(const void* pData, uint uiDataSize) return false; } -/////////////////////////////////////////////////////////////// -// -// JpegDecode -// -// jpeg to XRGB -// -/////////////////////////////////////////////////////////////// -bool JpegDecode(const void* pData, uint uiDataSize, CBuffer* pOutBuffer, uint& uiOutWidth, uint& uiOutHeight) +// Decode JPEG to XRGB +bool JpegDecode(const void* pData, uint uiDataSize, CBuffer* pOutBuffer, uint& uiOutWidth, uint& uiOutHeight, std::string* pOutError) { + if (!pData || uiDataSize == 0) + { + if (pOutError) + *pOutError = "Invalid JPEG input data"; + return false; + } + struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; + JpegErrorManager jerr; - /* Initialize the JPEG decompression object with default error handling. */ - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_decompress(&cinfo); + memset(&cinfo, 0, sizeof(cinfo)); + + // Set up error handling + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = JpegErrorExit; - /* Specify data source for decompression */ + if (setjmp(jerr.setjmp_buffer)) + { + if (pOutError) + *pOutError = "JPEG decode error (libjpeg internal error)"; + jpeg_destroy_decompress(&cinfo); + return false; + } + + jpeg_create_decompress(&cinfo); jpeg_mem_src(&cinfo, (uchar*)pData, uiDataSize); - /* Read file header, set default decompression parameters */ - jpeg_read_header(&cinfo, TRUE); + int headerResult = jpeg_read_header(&cinfo, TRUE); + if (headerResult != JPEG_HEADER_OK) + { + if (pOutError) + *pOutError = "Failed to read JPEG header"; + jpeg_destroy_decompress(&cinfo); + return false; + } + + // Validate dimensions (libjpeg max: 65500) + if (cinfo.image_width == 0 || cinfo.image_height == 0 || cinfo.image_width > JPEG_MAX_DIMENSION || cinfo.image_height > JPEG_MAX_DIMENSION) + { + if (pOutError) + *pOutError = "Invalid JPEG dimensions: " + std::to_string(cinfo.image_width) + "x" + std::to_string(cinfo.image_height) + " (max " + + std::to_string(JPEG_MAX_DIMENSION) + ")"; + jpeg_destroy_decompress(&cinfo); + return false; + } + + // Return dimensions only if no output buffer + if (!pOutBuffer) + { + uiOutWidth = cinfo.image_width; + uiOutHeight = cinfo.image_height; - /* default decompression parameters */ - // TODO + jpeg_destroy_decompress(&cinfo); + return true; + } - /* Start decompressor */ + cinfo.out_color_space = JCS_RGB; jpeg_start_decompress(&cinfo); - /* Write output file header */ - JDIMENSION uiWidth = cinfo.output_width; /* scaled image width */ - JDIMENSION uiHeight = cinfo.output_height; /* scaled image height */ + // Verify RGB output + if (cinfo.output_components != 3) + { + if (pOutError) + *pOutError = "Unexpected JPEG output components: " + std::to_string(cinfo.output_components) + " (expected 3)"; + jpeg_destroy_decompress(&cinfo); + return false; + } + + JDIMENSION uiWidth = cinfo.output_width; + JDIMENSION uiHeight = cinfo.output_height; uiOutWidth = uiWidth; uiOutHeight = uiHeight; - if (pOutBuffer) + uint64 uiRequiredSize = static_cast(uiWidth) * uiHeight * 4; + if (uiRequiredSize > UINT_MAX) + { + if (pOutError) + *pOutError = "JPEG dimensions too large for buffer: " + std::to_string(uiWidth) + "x" + std::to_string(uiHeight) + " requires " + + std::to_string(uiRequiredSize) + " bytes"; + jpeg_destroy_decompress(&cinfo); + return false; + } + + // Allocate buffers before decode loop (longjmp safety) + try { - pOutBuffer->SetSize(uiWidth * uiHeight * 4); - char* pOutData = pOutBuffer->GetData(); + pOutBuffer->SetSize(static_cast(uiRequiredSize)); + } + catch (...) + { + if (pOutError) + *pOutError = "Out of memory allocating decode buffer (" + std::to_string(static_cast(uiRequiredSize)) + " bytes)"; + jpeg_destroy_decompress(&cinfo); + return false; + } - /* Process data */ - JSAMPROW row_pointer[1]; - CBuffer rowBuffer; + char* pOutData = pOutBuffer->GetData(); + + CBuffer rowBuffer; + try + { rowBuffer.SetSize(uiWidth * 3); - char* pRowTemp = rowBuffer.GetData(); + } + catch (...) + { + if (pOutError) + *pOutError = "Out of memory allocating row buffer (" + std::to_string(uiWidth * 3) + " bytes)"; + jpeg_destroy_decompress(&cinfo); + return false; + } - while (cinfo.output_scanline < cinfo.output_height) - { - BYTE* pRowDest = (BYTE*)pOutData + cinfo.output_scanline * uiWidth * 4; - row_pointer[0] = (JSAMPROW)pRowTemp; + char* pRowTemp = rowBuffer.GetData(); - JDIMENSION num_scanlines = jpeg_read_scanlines(&cinfo, row_pointer, 1); + JSAMPROW row_pointer[1]; + while (cinfo.output_scanline < cinfo.output_height) + { + uint64 uiRowOffset = static_cast(cinfo.output_scanline) * uiWidth * 4; + BYTE* pRowDest = (BYTE*)pOutData + static_cast(uiRowOffset); + row_pointer[0] = (JSAMPROW)pRowTemp; - for (uint i = 0; i < uiWidth; i++) - { - pRowDest[i * 4 + 0] = pRowTemp[i * 3 + 2]; - pRowDest[i * 4 + 1] = pRowTemp[i * 3 + 1]; - pRowDest[i * 4 + 2] = pRowTemp[i * 3 + 0]; - pRowDest[i * 4 + 3] = 255; - } + JDIMENSION num_read = jpeg_read_scanlines(&cinfo, row_pointer, 1); + if (num_read != 1) + { + if (pOutError) + *pOutError = "Failed to read JPEG scanline " + std::to_string(cinfo.output_scanline) + " of " + std::to_string(cinfo.output_height) + + " (truncated image?)"; + jpeg_destroy_decompress(&cinfo); + return false; } - // Finish decompression and release memory. - jpeg_finish_decompress(&cinfo); + // Convert RGB to BGRA + for (uint i = 0; i < uiWidth; i++) + { + pRowDest[i * 4 + 0] = pRowTemp[i * 3 + 2]; // B + pRowDest[i * 4 + 1] = pRowTemp[i * 3 + 1]; // G + pRowDest[i * 4 + 2] = pRowTemp[i * 3 + 0]; // R + pRowDest[i * 4 + 3] = 255; // A + } } + jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); - if (jerr.num_warnings) + // Treat libjpeg warnings as errors + if (jerr.pub.num_warnings) + { + if (pOutError) + *pOutError = "JPEG decode completed with " + std::to_string(static_cast(jerr.pub.num_warnings)) + " warning(s)"; return false; + } + return true; } -/////////////////////////////////////////////////////////////// -// -// JpegEncode -// -// XRGB to jpeg -// -/////////////////////////////////////////////////////////////// -bool JpegEncode(uint uiWidth, uint uiHeight, uint uiQuality, const void* pData, uint uiDataSize, CBuffer& outBuffer) +// Encode XRGB to JPEG +bool JpegEncode(uint uiWidth, uint uiHeight, uint uiQuality, const void* pData, uint uiDataSize, CBuffer& outBuffer, std::string* pOutError) { - // Validate - if (uiDataSize == 0 || uiDataSize != uiWidth * uiHeight * 4) + if (!pData || uiWidth == 0 || uiHeight == 0) + { + if (pOutError) + *pOutError = "Invalid JPEG encode input parameters"; return false; + } + + // Validate dimensions (libjpeg max: 65500) + if (uiWidth > JPEG_MAX_DIMENSION || uiHeight > JPEG_MAX_DIMENSION) + { + if (pOutError) + *pOutError = + "JPEG dimensions too large: " + std::to_string(uiWidth) + "x" + std::to_string(uiHeight) + " (max " + std::to_string(JPEG_MAX_DIMENSION) + ")"; + return false; + } + + uint64 uiExpectedSize = static_cast(uiWidth) * uiHeight * 4; + if (uiDataSize == 0) + { + if (pOutError) + *pOutError = "Input buffer size is zero"; + return false; + } + if (uiExpectedSize > UINT_MAX) + { + if (pOutError) + *pOutError = "Image dimensions cause buffer overflow: " + std::to_string(uiWidth) + "x" + std::to_string(uiHeight); + return false; + } + if (uiDataSize != static_cast(uiExpectedSize)) + { + if (pOutError) + *pOutError = + "Input buffer size mismatch: expected " + std::to_string(static_cast(uiExpectedSize)) + " bytes, got " + std::to_string(uiDataSize); + return false; + } struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - cinfo.err = jpeg_std_error(&jerr); + JpegErrorManager jerr; + + memset(&cinfo, 0, sizeof(cinfo)); + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = JpegErrorExit; + + if (setjmp(jerr.setjmp_buffer)) + { + if (pOutError) + *pOutError = "JPEG encode error (libjpeg internal error)"; + jpeg_destroy_compress(&cinfo); + return false; + } + jpeg_create_compress(&cinfo); - size_t memlen = 0; - unsigned char* membuffer = NULL; - jpeg_mem_dest(&cinfo, &membuffer, &memlen); + unsigned char* membuffer_ptr = nullptr; + size_t memlen_val = 0; + jpeg_mem_dest(&cinfo, &membuffer_ptr, &memlen_val); - cinfo.image_width = uiWidth; /* image width and height, in pixels */ + cinfo.image_width = uiWidth; cinfo.image_height = uiHeight; - cinfo.input_components = 3; /* # of color components per pixel */ - cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo, uiQuality, true); + jpeg_set_quality(&cinfo, uiQuality, TRUE); cinfo.dct_method = JDCT_IFAST; - /* Start compressor */ jpeg_start_compress(&cinfo, TRUE); - /* Process data */ + // Allocate row buffer before encode loop (longjmp safety) CBuffer rowBuffer; - rowBuffer.SetSize(uiWidth * 3); + try + { + rowBuffer.SetSize(uiWidth * 3); + } + catch (...) + { + if (pOutError) + *pOutError = "Out of memory allocating encode row buffer (" + std::to_string(uiWidth * 3) + " bytes)"; + jpeg_destroy_compress(&cinfo); + if (membuffer_ptr) + free(membuffer_ptr); + return false; + } + char* pRowTemp = rowBuffer.GetData(); + bool bSuccess = false; JSAMPROW row_pointer[1]; while (cinfo.next_scanline < cinfo.image_height) { - BYTE* pRowSrc = (BYTE*)pData + cinfo.next_scanline * uiWidth * 4; + uint64 uiRowOffset = static_cast(cinfo.next_scanline) * uiWidth * 4; + BYTE* pRowSrc = (BYTE*)pData + static_cast(uiRowOffset); + + // Convert BGRA to RGB for (uint i = 0; i < uiWidth; i++) { - pRowTemp[i * 3 + 0] = pRowSrc[i * 4 + 2]; - pRowTemp[i * 3 + 1] = pRowSrc[i * 4 + 1]; - pRowTemp[i * 3 + 2] = pRowSrc[i * 4 + 0]; + pRowTemp[i * 3 + 0] = pRowSrc[i * 4 + 2]; // R + pRowTemp[i * 3 + 1] = pRowSrc[i * 4 + 1]; // G + pRowTemp[i * 3 + 2] = pRowSrc[i * 4 + 0]; // B } row_pointer[0] = (JSAMPROW)pRowTemp; - jpeg_write_scanlines(&cinfo, row_pointer, 1); + + JDIMENSION num_written = jpeg_write_scanlines(&cinfo, row_pointer, 1); + if (num_written != 1) + { + if (pOutError) + *pOutError = "Failed to write JPEG scanline " + std::to_string(cinfo.next_scanline) + " of " + std::to_string(cinfo.image_height); + jpeg_destroy_compress(&cinfo); + return false; + } } - /* Finish compression and release memory */ jpeg_finish_compress(&cinfo); - jpeg_destroy_compress(&cinfo); - // Copy out data and free memory - outBuffer = CBuffer(membuffer, memlen); - free(membuffer); + if (membuffer_ptr && memlen_val > 0) + { + try + { + outBuffer = CBuffer(membuffer_ptr, memlen_val); + bSuccess = true; + } + catch (...) + { + if (pOutError) + *pOutError = "Out of memory copying JPEG output (" + std::to_string(memlen_val) + " bytes)"; + jpeg_destroy_compress(&cinfo); + free(membuffer_ptr); + return false; + } + } + else if (pOutError) + { + *pOutError = "JPEG compression produced no output"; + } - return true; + jpeg_destroy_compress(&cinfo); + if (membuffer_ptr) + free(membuffer_ptr); + + return bSuccess; } -/////////////////////////////////////////////////////////////// -// -// JpegGetDimensions -// -// -// -/////////////////////////////////////////////////////////////// -bool JpegGetDimensions(const void* pData, uint uiDataSize, uint& uiOutWidth, uint& uiOutHeight) +// Get JPEG dimensions without decoding +bool JpegGetDimensions(const void* pData, uint uiDataSize, uint& uiOutWidth, uint& uiOutHeight, std::string* pOutError) { - return JpegDecode(pData, uiDataSize, nullptr, uiOutWidth, uiOutHeight); + return JpegDecode(pData, uiDataSize, nullptr, uiOutWidth, uiOutHeight, pOutError); } diff --git a/Client/core/CFileFormatPng.cpp b/Client/core/CFileFormatPng.cpp index ccf5b13b2cc..8cc0a9b428f 100644 --- a/Client/core/CFileFormatPng.cpp +++ b/Client/core/CFileFormatPng.cpp @@ -46,23 +46,31 @@ void ParseRGBA(CBuffer& outImage, const png_structp& png_ptr, const png_infop& i const png_uint_32 bytesPerRow = png_get_rowbytes(png_ptr, info_ptr); byte* rowData = new byte[bytesPerRow]; - // read single row at a time - for (uint rowIdx = 0; rowIdx < height; ++rowIdx) + try { - png_read_row(png_ptr, (png_bytep)rowData, NULL); - - const uint rowOffset = rowIdx * width; - - uint byteIndex = 0; - for (uint colIdx = 0; colIdx < width; ++colIdx) + // read single row at a time + for (uint rowIdx = 0; rowIdx < height; ++rowIdx) { - pData->R = rowData[byteIndex++]; - pData->G = rowData[byteIndex++]; - pData->B = rowData[byteIndex++]; - pData->A = rowData[byteIndex++]; - pData++; + png_read_row(png_ptr, (png_bytep)rowData, NULL); + + const uint rowOffset = rowIdx * width; + + uint byteIndex = 0; + for (uint colIdx = 0; colIdx < width; ++colIdx) + { + pData->R = rowData[byteIndex++]; + pData->G = rowData[byteIndex++]; + pData->B = rowData[byteIndex++]; + pData->A = rowData[byteIndex++]; + pData++; + } + assert(byteIndex == bytesPerRow); } - assert(byteIndex == bytesPerRow); + } + catch (...) + { + delete[] rowData; + throw; } delete[] rowData; @@ -81,23 +89,31 @@ void ParseRGB(CBuffer& outImage, const png_structp& png_ptr, const png_infop& in const png_uint_32 bytesPerRow = png_get_rowbytes(png_ptr, info_ptr); byte* rowData = new byte[bytesPerRow]; - // read single row at a time - for (uint rowIdx = 0; rowIdx < height; ++rowIdx) + try { - png_read_row(png_ptr, (png_bytep)rowData, NULL); - - const uint rowOffset = rowIdx * width; - - uint byteIndex = 0; - for (uint colIdx = 0; colIdx < width; ++colIdx) + // read single row at a time + for (uint rowIdx = 0; rowIdx < height; ++rowIdx) { - pData->R = rowData[byteIndex++]; - pData->G = rowData[byteIndex++]; - pData->B = rowData[byteIndex++]; - pData->A = 255; - pData++; + png_read_row(png_ptr, (png_bytep)rowData, NULL); + + const uint rowOffset = rowIdx * width; + + uint byteIndex = 0; + for (uint colIdx = 0; colIdx < width; ++colIdx) + { + pData->R = rowData[byteIndex++]; + pData->G = rowData[byteIndex++]; + pData->B = rowData[byteIndex++]; + pData->A = 255; + pData++; + } + assert(byteIndex == bytesPerRow); } - assert(byteIndex == bytesPerRow); + } + catch (...) + { + delete[] rowData; + throw; } delete[] rowData; @@ -192,21 +208,29 @@ bool PngDecode(const void* pData, uint uiDataSize, CBuffer* pOutBuffer, uint& ui if (pOutBuffer) { - pOutBuffer->SetSize(width * height * 4); - - switch (colorType) + try { - case PNG_COLOR_TYPE_RGB: - ParseRGB(*pOutBuffer, png_ptr, info_ptr, width, height); - break; - - case PNG_COLOR_TYPE_RGB_ALPHA: - ParseRGBA(*pOutBuffer, png_ptr, info_ptr, width, height); - break; - - default: - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - return false; + pOutBuffer->SetSize(width * height * 4); + + switch (colorType) + { + case PNG_COLOR_TYPE_RGB: + ParseRGB(*pOutBuffer, png_ptr, info_ptr, width, height); + break; + + case PNG_COLOR_TYPE_RGB_ALPHA: + ParseRGBA(*pOutBuffer, png_ptr, info_ptr, width, height); + break; + + default: + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + return false; + } + } + catch (...) + { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + throw; } } @@ -234,7 +258,6 @@ void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) stream->WriteBytes(data, length); } - /////////////////////////////////////////////////////////////// // // PngEncode @@ -244,38 +267,69 @@ void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) /////////////////////////////////////////////////////////////// bool PngEncode(uint uiWidth, uint uiHeight, const void* pData, uint uiDataSize, CBuffer& outBuffer) { - // Create the screen data buffer - BYTE** ppScreenData = NULL; - ppScreenData = new BYTE*[uiHeight]; - for (unsigned short y = 0; y < uiHeight; y++) + BYTE** ppScreenData = NULL; + png_struct* png_ptr = NULL; + png_info* info_ptr = NULL; + + try { - ppScreenData[y] = new BYTE[uiWidth * 4]; - } + // Create the screen data buffer + ppScreenData = new BYTE*[uiHeight]; + memset(ppScreenData, 0, sizeof(BYTE*) * uiHeight); + for (uint y = 0; y < uiHeight; y++) + { + ppScreenData[y] = new BYTE[uiWidth * 4]; + } + + // Copy the surface data into a row-based buffer for libpng + unsigned long ulLineWidth = uiWidth * 4; + for (unsigned int i = 0; i < uiHeight; i++) + { + memcpy(ppScreenData[i], (BYTE*)pData + i * ulLineWidth, ulLineWidth); + } - // Copy the surface data into a row-based buffer for libpng - unsigned long ulLineWidth = uiWidth * 4; - for (unsigned int i = 0; i < uiHeight; i++) + CBufferWriteStream stream(outBuffer); + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) + throw std::bad_alloc(); + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + throw std::bad_alloc(); + + png_set_write_fn(png_ptr, &stream, my_png_write_data, NULL); + png_set_filter(png_ptr, 0, PNG_FILTER_NONE); + png_set_compression_level(png_ptr, 1); + png_set_IHDR(png_ptr, info_ptr, uiWidth, uiHeight, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + png_set_rows(png_ptr, info_ptr, ppScreenData); + png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR /*| PNG_TRANSFORM_STRIP_ALPHA*/, NULL); + png_write_end(png_ptr, info_ptr); + } + catch (...) { - memcpy(ppScreenData[i], (BYTE*)pData + i * ulLineWidth, ulLineWidth); + if (png_ptr) + png_destroy_write_struct(&png_ptr, info_ptr ? &info_ptr : NULL); + + if (ppScreenData) + { + for (uint y = 0; y < uiHeight; y++) + { + if (ppScreenData[y]) + delete[] ppScreenData[y]; + } + delete[] ppScreenData; + } + throw; } - CBufferWriteStream stream(outBuffer); - - png_struct* png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - png_info* info_ptr = png_create_info_struct(png_ptr); - png_set_write_fn(png_ptr, &stream, my_png_write_data, NULL); - png_set_filter(png_ptr, 0, PNG_FILTER_NONE); - png_set_compression_level(png_ptr, 1); - png_set_IHDR(png_ptr, info_ptr, uiWidth, uiHeight, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - png_set_rows(png_ptr, info_ptr, ppScreenData); - png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR /*| PNG_TRANSFORM_STRIP_ALPHA*/, NULL); - png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); // Clean up the screen data buffer if (ppScreenData) { - for (unsigned short y = 0; y < uiHeight; y++) + for (uint y = 0; y < uiHeight; y++) { delete[] ppScreenData[y]; } diff --git a/Client/core/CFilePathTranslator.cpp b/Client/core/CFilePathTranslator.cpp index 20b93f2f64d..89b9227d7a8 100644 --- a/Client/core/CFilePathTranslator.cpp +++ b/Client/core/CFilePathTranslator.cpp @@ -80,7 +80,7 @@ void CFilePathTranslator::GetCurrentWorkingDirectory(std::string& WorkingDirecto void CFilePathTranslator::GetGTARootDirectory(std::string& ModuleRootDirOut) { - ModuleRootDirOut = g_gtaDirectory.u8string(); + ModuleRootDirOut = UTF8FilePath(g_gtaDirectory); } void CFilePathTranslator::GetMTASARootDirectory(std::string& InstallRootDirOut) diff --git a/Client/core/CGUI.cpp b/Client/core/CGUI.cpp index 75aff3a597d..32edce4e4e8 100644 --- a/Client/core/CGUI.cpp +++ b/Client/core/CGUI.cpp @@ -20,11 +20,11 @@ template <> CLocalGUI* CSingleton::m_pSingleton = NULL; #ifndef HIWORD - #define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16)) + #define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16)) #endif -#define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam)) +#define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam)) -const char* const DEFAULT_SKIN_NAME = "Default 2023"; // TODO: Change to whatever the default skin is if it changes +const char* const DEFAULT_SKIN_NAME = "Default 2023"; // TODO: Change to whatever the default skin is if it changes CLocalGUI::CLocalGUI() { @@ -44,6 +44,7 @@ CLocalGUI::CLocalGUI() m_LastSettingsRevision = -1; m_LocaleChangeCounter = 0; + m_bHasQueuedLocaleChange = false; } CLocalGUI::~CLocalGUI() @@ -123,8 +124,19 @@ void CLocalGUI::ChangeLocale(const char* szName) CClientVariables* cvars = CCore::GetSingleton().GetCVars(); m_LastSettingsRevision = cvars->GetRevision(); - g_pLocalization->SetCurrentLanguage(); - m_LastLocaleName = szName; + g_pLocalization->SetCurrentLanguage(szName ? szName : ""); + + SString strCanonicalLocale = g_pLocalization->GetLanguageCode(); + if (strCanonicalLocale.empty()) + strCanonicalLocale = CVARS_GET_VALUE("locale"); + if (strCanonicalLocale.empty() && szName) + strCanonicalLocale = szName; + + m_LastLocaleName = strCanonicalLocale; + + // Attempt CEGUI cleanup + if (CGUI* pGUI = CCore::GetSingleton().GetGUI()) + pGUI->Cleanup(); if (guiWasLoaded) { @@ -158,7 +170,7 @@ void CLocalGUI::CreateWindows(bool bGameIsAlreadyLoaded) m_pLabelVersionTag->SetTextColor(255, 255, 255); m_pLabelVersionTag->SetZOrderingEnabled(false); m_pLabelVersionTag->MoveToBack(); - if (MTASA_VERSION_TYPE < VERSION_TYPE_RELEASE) + if (MTASA_VERSION_TYPE < VERSION_TYPE_UNTESTED) m_pLabelVersionTag->SetAlwaysOnTop(true); // Create mainmenu @@ -211,6 +223,78 @@ void CLocalGUI::DestroyObjects() SAFE_DELETE(m_pLabelVersionTag); } +void CLocalGUI::RequestLocaleChange(const SString& strLocale) +{ + if (strLocale.empty()) + return; + + if (m_bHasQueuedLocaleChange && strLocale == m_QueuedLocaleChange) + return; + + const SString strCurrentLocale = CVARS_GET_VALUE("locale"); + if (!m_bHasQueuedLocaleChange && strLocale == strCurrentLocale && strLocale == m_LastLocaleName) + return; + + if (m_LocaleChangeCounter > 0) + CCore::GetSingleton().RemoveMessageBox(); + + m_QueuedLocaleChange = strLocale; + m_bHasQueuedLocaleChange = true; + m_LocaleChangeCounter = 0; + + // Keep the cvar at the last applied locale so dependent systems remain stable while we rebuild UI + if (!m_LastLocaleName.empty() && strCurrentLocale != m_LastLocaleName) + CVARS_SET("locale", m_LastLocaleName); +} + +void CLocalGUI::ApplyQueuedLocale() +{ + if (!m_bHasQueuedLocaleChange) + return; + + CClientVariables* cvars = CCore::GetSingleton().GetCVars(); + + if (m_QueuedLocaleChange.empty()) + { + m_bHasQueuedLocaleChange = false; + m_LocaleChangeCounter = 0; + CCore::GetSingleton().RemoveMessageBox(); + return; + } + + if (CCore::GetSingleton().GetModManager()->IsLoaded()) + { + CCore::GetSingleton().GetConsole()->Printf("Please disconnect before changing language"); + if (cvars) + cvars->Set("locale", m_LastLocaleName); + + m_bHasQueuedLocaleChange = false; + m_QueuedLocaleChange.clear(); + m_LocaleChangeCounter = 0; + CCore::GetSingleton().RemoveMessageBox(); + return; + } + + ChangeLocale(m_QueuedLocaleChange); + + m_bHasQueuedLocaleChange = false; + SString strAppliedLocale = m_LastLocaleName; + m_QueuedLocaleChange.clear(); + m_LocaleChangeCounter = 0; + + if (!strAppliedLocale.empty()) + { + SString strCurrentLocale = CVARS_GET_VALUE("locale"); + if (strCurrentLocale != strAppliedLocale) + CVARS_SET("locale", strAppliedLocale); + } + + if (cvars) + m_LastSettingsRevision = cvars->GetRevision(); + + CCore::GetSingleton().RemoveMessageBox(); +} + void CLocalGUI::DoPulse() { m_pVersionUpdater->DoPulse(); @@ -247,51 +331,41 @@ void CLocalGUI::DoPulse() { m_LastLocaleName = currentLocaleName; } - if (currentLocaleName != m_LastLocaleName) + else if (!m_bHasQueuedLocaleChange && currentLocaleName != m_LastLocaleName) { - m_LocaleChangeCounter++; - if (m_LocaleChangeCounter < 5) - { - // Do GUI stuff for first 5 frames - // Force pulse next time - m_LastSettingsRevision = cvars->GetRevision() - 1; + RequestLocaleChange(currentLocaleName); + } + } - if (m_LocaleChangeCounter == 2) - CCore::GetSingleton().ShowMessageBox(_E("CC99"), ("Changing language, please wait..."), MB_ICON_INFO); - } - else - { - // Do actual locale change - m_LocaleChangeCounter = 0; - CCore::GetSingleton().RemoveMessageBox(); + if (m_bHasQueuedLocaleChange) + { + m_LocaleChangeCounter++; - if (!CCore::GetSingleton().GetModManager()->IsLoaded()) - ChangeLocale(currentLocaleName); - else - { - CCore::GetSingleton().GetConsole()->Printf("Please disconnect before changing language"); - cvars->Set("locale", m_LastLocaleName); - } - } - } + if (m_LocaleChangeCounter == 2) + CCore::GetSingleton().ShowMessageBox(_E("CC99"), ("Changing language, please wait..."), MB_ICON_INFO); + + if (m_LocaleChangeCounter >= 5) + ApplyQueuedLocale(); } } void CLocalGUI::Draw() { // Get the game interface - CGame* pGame = CCore::GetSingleton().GetGame(); - SystemState systemState = pGame->GetSystemState(); - CGUI* pGUI = CCore::GetSingleton().GetGUI(); + CGame* pGame = CCore::GetSingleton().GetGame(); + SystemState systemState = pGame->GetSystemState(); + CGUI* pGUI = CCore::GetSingleton().GetGUI(); // Update mainmenu stuff m_pMainMenu->Update(); // If we're ingame, make sure the chatbox is drawn - bool bChatVisible = (systemState == SystemState::GS_PLAYING_GAME && m_pMainMenu->GetIsIngame() && m_bChatboxVisible && !CCore::GetSingleton().IsOfflineMod()); + bool bChatVisible = + (systemState == SystemState::GS_PLAYING_GAME && m_pMainMenu->GetIsIngame() && m_bChatboxVisible && !CCore::GetSingleton().IsOfflineMod()); if (m_pChat->IsVisible() != bChatVisible) m_pChat->SetVisible(bChatVisible, !bChatVisible); - bool bDebugVisible = (systemState == SystemState::GS_PLAYING_GAME && m_pMainMenu->GetIsIngame() && m_pDebugViewVisible && !CCore::GetSingleton().IsOfflineMod()); + bool bDebugVisible = + (systemState == SystemState::GS_PLAYING_GAME && m_pMainMenu->GetIsIngame() && m_pDebugViewVisible && !CCore::GetSingleton().IsOfflineMod()); if (m_pDebugView->IsVisible() != bDebugVisible) m_pDebugView->SetVisible(bDebugVisible, true); @@ -700,8 +774,6 @@ bool CLocalGUI::InputGoesToGUI() if (!pGUI) return false; - // Here we're supposed to check if things like menues are up, console is up or the chatbox is expecting input - // If the console is visible OR the chat is expecting input OR the mainmenu is visible return (IsConsoleVisible() || IsMainMenuVisible() || IsChatBoxInputEnabled() || m_bForceCursorVisible || pGUI->GetGUIInputEnabled() || !CCore::GetSingleton().IsFocused() || IsWebRequestGUIVisible()); } @@ -813,13 +885,13 @@ DWORD CLocalGUI::TranslateScanCodeToGUIKey(DWORD dwCharacter) case VK_DELETE: return DIK_DELETE; case 0x56: - return DIK_V; // V + return DIK_V; // V case 0x43: - return DIK_C; // C + return DIK_C; // C case 0x58: - return DIK_X; // X + return DIK_X; // X case 0x41: - return DIK_A; // A + return DIK_A; // A default: return 0; } diff --git a/Client/core/CGUI.h b/Client/core/CGUI.h index c39c6a4f37a..cdc07302647 100644 --- a/Client/core/CGUI.h +++ b/Client/core/CGUI.h @@ -14,10 +14,10 @@ class CLocalGUI; #pragma once #ifndef WM_MOUSEWHEEL -#define WM_MOUSEWHEEL 0x20A // Defined only when including Windows.h -> Not getting defined? (<=XP only?) + #define WM_MOUSEWHEEL 0x20A // Defined only when including Windows.h -> Not getting defined? (<=XP only?) #endif -#define DIRECT3D_VERSION 0x0900 +#define DIRECT3D_VERSION 0x0900 #include "d3d9.h" #include "d3dx9.h" @@ -92,8 +92,11 @@ class CLocalGUI : public CSingleton bool IsOptionalUpdateInfoRequired(const char* szHost) { return m_pVersionUpdater->IsOptionalUpdateInfoRequired(szHost); } void InitiateDataFilesFix() { m_pVersionUpdater->InitiateDataFilesFix(); } + void RequestLocaleChange(const SString& strLocale); + private: void UpdateCursor(); + void ApplyQueuedLocale(); DWORD TranslateScanCodeToGUIKey(DWORD dwCharacter); @@ -114,8 +117,10 @@ class CLocalGUI : public CSingleton int m_uiActiveCompositionSize; POINT m_StoredMousePosition; - int m_LastSettingsRevision; // the revision number the last time we saw the skin change + int m_LastSettingsRevision; // the revision number the last time we saw the skin change SString m_LastSkinName; SString m_LastLocaleName; uint m_LocaleChangeCounter; + SString m_QueuedLocaleChange; + bool m_bHasQueuedLocaleChange; }; diff --git a/Client/core/CGraphStats.cpp b/Client/core/CGraphStats.cpp index 96abdceedfc..061c7fee5c6 100644 --- a/Client/core/CGraphStats.cpp +++ b/Client/core/CGraphStats.cpp @@ -20,7 +20,7 @@ namespace SColor color; std::string strName; }; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -115,7 +115,12 @@ void CGraphStats::AddTimingPoint(const char* szName) CGraphicsInterface* pGraphics = g_pCore->GetGraphics(); std::uint32_t viewportWidth = pGraphics->GetViewportWidth(); - std::uint32_t sizeX = viewportWidth / 4; // one quarter of screen width + std::uint32_t sizeX = viewportWidth / 4; // one quarter of screen width + + if (sizeX == 0) + return; + + const int iSizeX = static_cast(sizeX); // Start of next frame? if (szName[0] == 0) @@ -137,7 +142,7 @@ void CGraphStats::AddTimingPoint(const char* szName) for (int i = 0; i < Dups; i++) { pLine->iDataPos++; - if (pLine->iDataPos > sizeX - 1) + if (pLine->iDataPos >= iSizeX) pLine->iDataPos = 0; pLine->dataHistory[pLine->iDataPos] = Data; } @@ -158,7 +163,6 @@ void CGraphStats::AddTimingPoint(const char* szName) MapSet(m_LineList, szName, SGraphStatLine()); pLine = MapFind(m_LineList, szName); pLine->dataHistory.resize(sizeX); - memset(&pLine->dataHistory[0], 0, pLine->dataHistory.size()); pLine->iDataPos = 0; pLine->prevData = 0; pLine->strName = szName; @@ -169,9 +173,10 @@ void CGraphStats::AddTimingPoint(const char* szName) uchar* p = md5.data; while (p[0] + p[1] + p[2] < 128) { - int f = rand() % NUMELMS(md5.data); - int t = rand() % 3; - p[t] = std::min(255, p[t] + p[f] + 1); + int f = rand() % NUMELMS(md5.data); + int t = rand() % 3; + const int newValue = std::min(255, static_cast(p[t]) + static_cast(p[f]) + 1); + p[t] = static_cast(newValue); } pLine->color = SColorRGBA(p[0], p[1], p[2], 255); } @@ -183,7 +188,7 @@ void CGraphStats::AddTimingPoint(const char* szName) // Inc position pLine->iDataPos++; - if (pLine->iDataPos > sizeX - 1) + if (pLine->iDataPos >= iSizeX) pLine->iDataPos = 0; // Insert data point @@ -228,6 +233,11 @@ void CGraphStats::Draw() std::uint32_t sizeY = viewportHeight / 4; // set the height of graph to 1/4 of current resolution std::uint32_t rangeY = 100; // 100ms + if (sizeX == 0) + return; + + const int iSizeX = static_cast(sizeX); + originY = originY + sizeY + 30; // add graph height plus a little gap to the overall Y position float fLineScale = 1 / 1000.f / rangeY * sizeY; @@ -245,7 +255,7 @@ void CGraphStats::Draw() int iDataPos = line.iDataPos; int iDataPosPrev = iDataPos; - for (int i = sizeX - 1; i > 0; i--) + for (int i = iSizeX - 1; i > 0; i--) { float fY0 = line.dataHistory[iDataPos] * fLineScale; float fY1 = line.dataHistory[iDataPosPrev] * fLineScale; @@ -253,11 +263,11 @@ void CGraphStats::Draw() iDataPosPrev = iDataPos; iDataPos--; if (iDataPos == -1) - iDataPos = sizeX - 1; + iDataPos = iSizeX - 1; pGraphics->DrawLineQueued(originX + i - 1, originY - fY0, originX + i, originY - fY1, 1, line.color, true); - if (i == sizeX - 1) + if (i == iSizeX - 1) { // Line from graph to label pGraphics->DrawLineQueued(originX + i - 1, originY - fY0, fLabelX - 2, fLabelY + fLineHeight / 2, 1, line.color, true); diff --git a/Client/core/CGraphStats.h b/Client/core/CGraphStats.h index 4d429988083..445e0d14f35 100644 --- a/Client/core/CGraphStats.h +++ b/Client/core/CGraphStats.h @@ -8,8 +8,9 @@ * *****************************************************************************/ -#define TIMING_GRAPH(name) \ - GetGraphStats()->AddTimingPoint( name ); +#pragma once + +#define TIMING_GRAPH(name) GetGraphStats()->AddTimingPoint(name); // // CGraphStatsInterface for measuring and displaying a timing graph diff --git a/Client/core/CJoystickManager.cpp b/Client/core/CJoystickManager.cpp index 81fddbc08ad..a05514da1de 100644 --- a/Client/core/CJoystickManager.cpp +++ b/Client/core/CJoystickManager.cpp @@ -23,12 +23,11 @@ extern IDirectInput8* g_pDirectInput8; // Helper stuff // -#ifndef NUMELMS // in DShow.h - #define NUMELMS(aa) (sizeof(aa)/sizeof((aa)[0])) +#ifndef NUMELMS // in DShow.h + #define NUMELMS(aa) (sizeof(aa) / sizeof((aa)[0])) #endif -#define VALID_INDEX_FOR( array, index ) \ - ( index >= 0 && index < NUMELMS(array) ) +#define VALID_INDEX_FOR(array, index) (index >= 0 && index < NUMELMS(array)) SString GUIDToString(const GUID& g) { @@ -75,10 +74,10 @@ enum eStick struct SMappingLine { - eJoy SourceAxisIndex; // 0 - 7 - eDir SourceAxisDir; // 0 - 2 - eStick OutputAxisIndex; // 0/1 2/3 4 5 - eDir OutputAxisDir; // 0 - 1 + eJoy SourceAxisIndex; // 0 - 7 + eDir SourceAxisDir; // 0 - 2 + eStick OutputAxisIndex; // 0/1 2/3 4 5 + eDir OutputAxisDir; // 0 - 1 bool bEnabled; int MaxValue; }; @@ -116,7 +115,7 @@ struct SJoystickState BYTE rgbButtons[32]; /* 32 buttons */ BYTE rgbButtonsWas[32]; BYTE povButtonsWas[4]; - BYTE axisButtonsWas[14]; // Axis as buttons + BYTE axisButtonsWas[14]; // Axis as buttons }; /////////////////////////////////////////////////////////////// @@ -325,7 +324,7 @@ BOOL CJoystickManager::DoEnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdido range.diph.dwSize = sizeof(DIPROPRANGE); range.diph.dwHeaderSize = sizeof(DIPROPHEADER); range.diph.dwHow = DIPH_BYID; - range.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis + range.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis range.lMin = -1000; range.lMax = +1000; @@ -348,10 +347,10 @@ BOOL CJoystickManager::DoEnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdido dead.diph.dwHeaderSize = sizeof dead.diph; dead.diph.dwHow = DIPH_BYID; dead.diph.dwObj = pdidoi->dwType; - dead.dwData = 0; // No Deadzone + dead.dwData = 0; // No Deadzone sat = dead; - sat.dwData = 10000; // No Saturation + sat.dwData = 10000; // No Saturation m_DevInfo.pDevice->SetProperty(DIPROP_DEADZONE, &dead.diph); m_DevInfo.pDevice->SetProperty(DIPROP_SATURATION, &sat.diph); @@ -400,7 +399,7 @@ BOOL CJoystickManager::DoEnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdido WriteDebugEvent(" " + strStatus); #ifdef MTA_DEBUG -#if 0 + #if 0 if ( CCore::GetSingleton ().GetConsole () ) CCore::GetSingleton ().GetConsole ()->Printf( "%p dwHow:%d dwObj:%d guid:%x index:%d lMin:%d lMax:%d" @@ -413,7 +412,7 @@ BOOL CJoystickManager::DoEnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdido ,range.lMax ); -#endif + #endif #endif } @@ -481,7 +480,7 @@ void CJoystickManager::InitDirectInput() } PreferredJoyCfg.dwSize = sizeof(PreferredJoyCfg); - if (SUCCEEDED(pJoyConfig->GetConfig(0, &PreferredJoyCfg, DIJC_GUIDINSTANCE))) // This function is expected to fail if no Joystick is attached + if (SUCCEEDED(pJoyConfig->GetConfig(0, &PreferredJoyCfg, DIJC_GUIDINSTANCE))) // This function is expected to fail if no Joystick is attached m_bPreferredJoyCfgValid = true; SAFE_RELEASE(pJoyConfig); @@ -693,7 +692,7 @@ void CJoystickManager::ReadCurrentState() for (int i = 0; i < 32; i++) m_JoystickState.rgbButtons[i] = 0; - DIJOYSTATE2 js; // DInput joystick state + DIJOYSTATE2 js; // DInput joystick state if (ReadInputSubsystem(js)) { @@ -763,7 +762,7 @@ void CJoystickManager::ReadCurrentState() range.diph.dwSize = sizeof(DIPROPRANGE); range.diph.dwHeaderSize = sizeof(DIPROPHEADER); range.diph.dwHow = DIPH_BYID; - range.diph.dwObj = m_DevInfo.axis[a].dwType; // Specify the enumerated axis + range.diph.dwObj = m_DevInfo.axis[a].dwType; // Specify the enumerated axis range.lMin = -2001; range.lMax = +2001; @@ -813,7 +812,7 @@ void CJoystickManager::ReadCurrentState() { CGraphicsInterface* pGraphics = CCore::GetSingleton().GetGraphics(); int x = 20; - int y = 20; // pGraphics->GetViewportHeight() / 2; + int y = 20; // pGraphics->GetViewportHeight() / 2; pGraphics->DrawRectQueued(x, y, 350, 150, 0xaf000000, true); pGraphics->DrawStringQueued(x + 10, y + 10, 0, 0, 0xFFFFFFFF, strStatus, 1, 1, DT_NOCLIP, NULL, true); } @@ -1034,6 +1033,13 @@ void CJoystickManager::ApplyAxes(CControllerState& cs, bool bInVehicle) if (!IsJoypadConnected()) return; + int leftStickX = cs.LeftStickX; + int leftStickY = cs.LeftStickY; + int rightStickX = cs.RightStickX; + int rightStickY = cs.RightStickY; + int buttonCross = cs.ButtonCross; + int buttonSquare = cs.ButtonSquare; + // Map each half axis for (int i = 0; i < NUMELMS(m_currentMapping); i++) { @@ -1054,34 +1060,34 @@ void CJoystickManager::ApplyAxes(CControllerState& cs, bool bInVehicle) if (line.OutputAxisDir == eDirNeg) value = -value; - int iValue = Round(value * line.MaxValue); + auto sValue = static_cast(Round(value * line.MaxValue)); if (line.OutputAxisIndex == eLeftStickX) - cs.LeftStickX += iValue; + leftStickX += sValue; else if (line.OutputAxisIndex == eLeftStickY) - cs.LeftStickY += iValue; + leftStickY += sValue; else if (line.OutputAxisIndex == eRightStickX) - cs.RightStickX += iValue; + rightStickX += sValue; else if (line.OutputAxisIndex == eRightStickY) - cs.RightStickY += iValue; + rightStickY += sValue; else if (line.OutputAxisIndex == eAccelerate && bInVehicle) - cs.ButtonCross += iValue; + buttonCross += sValue; else if (line.OutputAxisIndex == eBrake && bInVehicle) - cs.ButtonSquare += iValue; + buttonSquare += sValue; } // Keep everything in range - cs.LeftStickX = Clamp(-128, cs.LeftStickX, 128); - cs.LeftStickY = Clamp(-128, cs.LeftStickY, 128); - cs.RightStickX = Clamp(-128, cs.RightStickX, 128); - cs.RightStickY = Clamp(-128, cs.RightStickY, 128); + cs.LeftStickX = static_cast(Clamp(-128, leftStickX, 128)); + cs.LeftStickY = static_cast(Clamp(-128, leftStickY, 128)); + cs.RightStickX = static_cast(Clamp(-128, rightStickX, 128)); + cs.RightStickY = static_cast(Clamp(-128, rightStickY, 128)); - cs.ButtonCross = Clamp(0, cs.ButtonCross, 255); - cs.ButtonSquare = Clamp(0, cs.ButtonSquare, 255); + cs.ButtonCross = static_cast(Clamp(0, buttonCross, 255)); + cs.ButtonSquare = static_cast(Clamp(0, buttonSquare, 255)); // Debug output #ifdef MTA_DEBUG -#if 0 + #if 0 SString strBuffer = SString::Printf ( "LeftShoulder1: %u\n" "LeftShoulder2: %u\n" @@ -1153,7 +1159,7 @@ void CJoystickManager::ApplyAxes(CControllerState& cs, bool bInVehicle) CCore::GetSingleton ().GetGraphics ()->DrawString ( 20, 550, 0xFFFFFFFF, 1, strBuffer ); -#endif + #endif #endif } @@ -1195,7 +1201,7 @@ void CJoystickManager::SetDeadZone(int iDeadZone) { m_SettingsRevision++; if (iDeadZone != m_DevInfo.iDeadZone) - m_bAutoDeadZoneEnabled = false; // Disable auto dead zone on change (user edit) + m_bAutoDeadZoneEnabled = false; // Disable auto dead zone on change (user edit) m_DevInfo.iDeadZone = Clamp(0, iDeadZone, 49); } diff --git a/Client/core/CJoystickManager.h b/Client/core/CJoystickManager.h index ccd46e872f3..f8a59db1753 100644 --- a/Client/core/CJoystickManager.h +++ b/Client/core/CJoystickManager.h @@ -48,11 +48,11 @@ CJoystickManagerInterface* NewJoystickManager(); CJoystickManagerInterface* GetJoystickManager(); // Custom VK_ codes for the joystick buttons - Starts at VK_JOY(1) -#define VK_JOY(x) ( 0x100+(x) ) +#define VK_JOY(x) (0x100 + (x)) // Custom VK_ codes for the joystick pov hat - Starts at VK_POV(1) -#define VK_POV(x) ( 0x150+(x) ) +#define VK_POV(x) (0x150 + (x)) // Custom VK_ codes for the joystick axes - Starts at VK_AXIS(1) -#define VK_AXIS(x) ( 0x160+(x) ) +#define VK_AXIS(x) (0x160 + (x)) // Unique numbers for the joystick buttons - Used to identify buttons in the GTA settings -#define GTA_KEY_JOY(x) ( 500+(x) ) +#define GTA_KEY_JOY(x) (500 + (x)) diff --git a/Client/core/CKeyBinds.cpp b/Client/core/CKeyBinds.cpp index 6d451574cb5..3664d326de2 100644 --- a/Client/core/CKeyBinds.cpp +++ b/Client/core/CKeyBinds.cpp @@ -29,7 +29,7 @@ const SBindableKey g_bkKeys[] = {{"mouse1", VK_LBUTTON, GTA_KEY_LMOUSE, DATA_NON // TODO: Consider using VK_(L|R)(SHIFT|CONTROL|MENU) {"lshift", VK_SHIFT, GTA_KEY_LSHIFT, DATA_NOT_EXTENDED, 0}, - {"rshift", VK_SHIFT, GTA_KEY_RSHIFT, DATA_EXTENDED, 0}, // 10 + {"rshift", VK_SHIFT, GTA_KEY_RSHIFT, DATA_EXTENDED, 0}, // 10 {"lctrl", VK_CONTROL, GTA_KEY_LCONTROL, DATA_NOT_EXTENDED, 0}, {"rctrl", VK_CONTROL, GTA_KEY_RCONTROL, DATA_EXTENDED, 0}, {"lalt", VK_MENU, GTA_KEY_LMENU, DATA_NOT_EXTENDED, 0, true}, @@ -40,7 +40,7 @@ const SBindableKey g_bkKeys[] = {{"mouse1", VK_LBUTTON, GTA_KEY_LMOUSE, DATA_NON {"enter", VK_RETURN, GTA_KEY_RETURN, DATA_NOT_EXTENDED, 0}, {"space", VK_SPACE, GTA_KEY_SPACE, DATA_NONE, 0}, {"pgup", VK_PRIOR, GTA_KEY_PGUP, DATA_NUMPAD, 74, true}, - {"pgdn", VK_NEXT, GTA_KEY_PGDN, DATA_NUMPAD, 68, true}, // 20 + {"pgdn", VK_NEXT, GTA_KEY_PGDN, DATA_NUMPAD, 68, true}, // 20 {"end", VK_END, GTA_KEY_END, DATA_NUMPAD, 66}, {"home", VK_HOME, GTA_KEY_HOME, DATA_NUMPAD, 72}, {"arrow_l", VK_LEFT, GTA_KEY_LEFT, DATA_NUMPAD, 69}, @@ -50,7 +50,7 @@ const SBindableKey g_bkKeys[] = {{"mouse1", VK_LBUTTON, GTA_KEY_LMOUSE, DATA_NON {"insert", VK_INSERT, GTA_KEY_INSERT, DATA_NUMPAD, 65, true}, {"delete", VK_DELETE, GTA_KEY_DELETE, DATA_NUMPAD, 79}, {"0", 0x30, GTA_KEY_0, DATA_NONE, 0}, - {"1", 0x31, GTA_KEY_1, DATA_NONE, 0}, // 30 + {"1", 0x31, GTA_KEY_1, DATA_NONE, 0}, // 30 {"2", 0x32, GTA_KEY_2, DATA_NONE, 0}, {"3", 0x33, GTA_KEY_3, DATA_NONE, 0}, {"4", 0x34, GTA_KEY_4, DATA_NONE, 0}, @@ -60,7 +60,7 @@ const SBindableKey g_bkKeys[] = {{"mouse1", VK_LBUTTON, GTA_KEY_LMOUSE, DATA_NON {"8", 0x38, GTA_KEY_8, DATA_NONE, 0}, {"9", 0x39, GTA_KEY_9, DATA_NONE, 0}, {"a", 0x41, GTA_KEY_A, DATA_NONE, 0}, - {"b", 0x42, GTA_KEY_B, DATA_NONE, 0}, // 40 + {"b", 0x42, GTA_KEY_B, DATA_NONE, 0}, // 40 {"c", 0x43, GTA_KEY_C, DATA_NONE, 0}, {"d", 0x44, GTA_KEY_D, DATA_NONE, 0}, {"e", 0x45, GTA_KEY_E, DATA_NONE, 0}, @@ -70,7 +70,7 @@ const SBindableKey g_bkKeys[] = {{"mouse1", VK_LBUTTON, GTA_KEY_LMOUSE, DATA_NON {"i", 0x49, GTA_KEY_I, DATA_NONE, 0}, {"j", 0x4A, GTA_KEY_J, DATA_NONE, 0}, {"k", 0x4B, GTA_KEY_K, DATA_NONE, 0}, - {"l", 0x4C, GTA_KEY_L, DATA_NONE, 0}, // 50 + {"l", 0x4C, GTA_KEY_L, DATA_NONE, 0}, // 50 {"m", 0x4D, GTA_KEY_M, DATA_NONE, 0}, {"n", 0x4E, GTA_KEY_N, DATA_NONE, 0}, {"o", 0x4F, GTA_KEY_O, DATA_NONE, 0}, @@ -80,7 +80,7 @@ const SBindableKey g_bkKeys[] = {{"mouse1", VK_LBUTTON, GTA_KEY_LMOUSE, DATA_NON {"s", 0x53, GTA_KEY_S, DATA_NONE, 0}, {"t", 0x54, GTA_KEY_T, DATA_NONE, 0}, {"u", 0x55, GTA_KEY_U, DATA_NONE, 0}, - {"v", 0x56, GTA_KEY_V, DATA_NONE, 0}, // 60 + {"v", 0x56, GTA_KEY_V, DATA_NONE, 0}, // 60 {"w", 0x57, GTA_KEY_W, DATA_NONE, 0}, {"x", 0x58, GTA_KEY_X, DATA_NONE, 0}, {"y", 0x59, GTA_KEY_Y, DATA_NONE, 0}, @@ -90,7 +90,7 @@ const SBindableKey g_bkKeys[] = {{"mouse1", VK_LBUTTON, GTA_KEY_LMOUSE, DATA_NON {"num_2", VK_NUMPAD2, GTA_KEY_NUMPAD2, DATA_NONE, 0}, {"num_3", VK_NUMPAD3, GTA_KEY_NUMPAD3, DATA_NONE, 0}, {"num_4", VK_NUMPAD4, GTA_KEY_NUMPAD4, DATA_NONE, 0}, - {"num_5", VK_NUMPAD5, GTA_KEY_NUMPAD5, DATA_NONE, 0}, // 70 + {"num_5", VK_NUMPAD5, GTA_KEY_NUMPAD5, DATA_NONE, 0}, // 70 {"num_6", VK_NUMPAD6, GTA_KEY_NUMPAD6, DATA_NONE, 0}, {"num_7", VK_NUMPAD7, GTA_KEY_NUMPAD7, DATA_NONE, 0}, {"num_8", VK_NUMPAD8, GTA_KEY_NUMPAD8, DATA_NONE, 0}, @@ -100,7 +100,7 @@ const SBindableKey g_bkKeys[] = {{"mouse1", VK_LBUTTON, GTA_KEY_LMOUSE, DATA_NON {"num_sep", VK_SEPARATOR, NO_KEY_DEFINED, DATA_NONE, 0}, {"num_sub", VK_SUBTRACT, GTA_KEY_SUBTRACT, DATA_NONE, 0}, {"num_dec", VK_DECIMAL, GTA_KEY_DECIMAL, DATA_NONE, 0}, - {"num_div", VK_DIVIDE, GTA_KEY_DIVIDE, DATA_NONE, 0}, // 80 + {"num_div", VK_DIVIDE, GTA_KEY_DIVIDE, DATA_NONE, 0}, // 80 {"F1", VK_F1, GTA_KEY_F1, DATA_NONE, 0, true}, {"F2", VK_F2, GTA_KEY_F2, DATA_NONE, 0, true}, {"F3", VK_F3, GTA_KEY_F3, DATA_NONE, 0, true}, @@ -111,7 +111,7 @@ const SBindableKey g_bkKeys[] = {{"mouse1", VK_LBUTTON, GTA_KEY_LMOUSE, DATA_NON // {"F8", VK_F8, GTA_KEY_F8, DATA_NONE, 0, true}, * Used for console {"F9", VK_F9, GTA_KEY_F9, DATA_NONE, 0, true}, {"F10", VK_F10, GTA_KEY_F10, DATA_NONE, 0, true}, - {"F11", VK_F11, GTA_KEY_F11, DATA_NONE, 0, true}, // 90 + {"F11", VK_F11, GTA_KEY_F11, DATA_NONE, 0, true}, // 90 {"F12", VK_F12, GTA_KEY_F12, DATA_NONE, 0, true}, {"scroll", VK_SCROLL, GTA_KEY_SCROLL, DATA_NONE, 0, true}, {";", 0xBA, GTA_KEY_SEMICOLON, DATA_NONE, 0}, @@ -121,7 +121,7 @@ const SBindableKey g_bkKeys[] = {{"mouse1", VK_LBUTTON, GTA_KEY_LMOUSE, DATA_NON {".", 0xBE, GTA_KEY_PERIOD, DATA_NONE, 0}, {"/", 0xBF, GTA_KEY_SLASH, DATA_NONE, 0}, {"'", 0xC0, GTA_KEY_APOSTROPHE, DATA_NONE, 0}, - {"[", 0xDB, GTA_KEY_LBRACKET, DATA_NONE, 0}, // 100 + {"[", 0xDB, GTA_KEY_LBRACKET, DATA_NONE, 0}, // 100 {"\\", 0xDC, GTA_KEY_BACKSLASH, DATA_NONE, 0}, {"]", 0xDD, GTA_KEY_RBRACKET, DATA_NONE, 0}, {"#", 0xDE, GTA_KEY_HASH, DATA_NONE, 0}, @@ -193,7 +193,7 @@ SBindableGTAControl g_bcControls[] = {{"fire", FIRE, CONTROL_FOOT, false, true, {"zoom_in", ZOOM_IN, CONTROL_FOOT, false, true, _td("Zoom in")}, {"zoom_out", ZOOM_OUT, CONTROL_FOOT, false, true, _td("Zoom out")}, {"enter_exit", ENTER_EXIT, CONTROL_BOTH, false, true, _td("Enter/Exit")}, - {"change_camera", CHANGE_CAMERA, CONTROL_BOTH, false, true, _td("Change camera")}, // 10 + {"change_camera", CHANGE_CAMERA, CONTROL_BOTH, false, true, _td("Change camera")}, // 10 {"jump", JUMP, CONTROL_FOOT, false, true, _td("Jump")}, {"sprint", SPRINT, CONTROL_FOOT, false, true, _td("Sprint")}, {"look_behind", LOOK_BEHIND, CONTROL_FOOT, false, true, _td("Look behind")}, @@ -203,7 +203,7 @@ SBindableGTAControl g_bcControls[] = {{"fire", FIRE, CONTROL_FOOT, false, true, {"vehicle_fire", VEHICLE_FIRE, CONTROL_VEHICLE, false, true, _td("Vehicle fire")}, {"vehicle_secondary_fire", VEHICLE_SECONDARY_FIRE, CONTROL_VEHICLE, false, true, _td("Vehicle secondary fire")}, {"vehicle_left", VEHICLE_LEFT, CONTROL_VEHICLE, false, true, _td("Vehicle left")}, - {"vehicle_right", VEHICLE_RIGHT, CONTROL_VEHICLE, false, true, _td("Vehicle right")}, // 20 + {"vehicle_right", VEHICLE_RIGHT, CONTROL_VEHICLE, false, true, _td("Vehicle right")}, // 20 {"steer_forward", STEER_FORWARDS_DOWN, CONTROL_VEHICLE, false, true, _td("Steer forwards/down")}, {"steer_back", STEER_BACK_UP, CONTROL_VEHICLE, false, true, _td("Steer backwards/up")}, {"accelerate", ACCELERATE, CONTROL_VEHICLE, false, true, _td("Accelerate")}, @@ -213,7 +213,7 @@ SBindableGTAControl g_bcControls[] = {{"fire", FIRE, CONTROL_FOOT, false, true, {"radio_user_track_skip", RADIO_USER_TRACK_SKIP, CONTROL_VEHICLE, false, true, _td("Radio user track skip")}, {"horn", HORN, CONTROL_VEHICLE, false, true, _td("Horn")}, {"sub_mission", SUB_MISSION, CONTROL_VEHICLE, false, true, _td("Sub-mission")}, - {"handbrake", HANDBRAKE, CONTROL_VEHICLE, false, true, _td("Handbrake")}, // 30 + {"handbrake", HANDBRAKE, CONTROL_VEHICLE, false, true, _td("Handbrake")}, // 30 {"vehicle_look_left", VEHICLE_LOOK_LEFT, CONTROL_VEHICLE, false, true, _td("Vehicle look left")}, {"vehicle_look_right", VEHICLE_LOOK_RIGHT, CONTROL_VEHICLE, false, true, _td("Vehicle look right")}, {"vehicle_look_behind", VEHICLE_LOOK_BEHIND, CONTROL_VEHICLE, false, true, _td("Vehicle look behind")}, @@ -223,7 +223,7 @@ SBindableGTAControl g_bcControls[] = {{"fire", FIRE, CONTROL_FOOT, false, true, {"special_control_down", SPECIAL_CONTROL_DOWN, CONTROL_VEHICLE, false, true, _td("Special control down")}, {"special_control_up", SPECIAL_CONTROL_UP, CONTROL_VEHICLE, false, true, _td("Special control up")}, {"aim_weapon", AIM_WEAPON, CONTROL_FOOT, false, true, _td("Aim weapon")}, - {"conversation_yes", CONVERSATION_YES, CONTROL_FOOT, false, true, _td("Conversation yes")}, // 40 + {"conversation_yes", CONVERSATION_YES, CONTROL_FOOT, false, true, _td("Conversation yes")}, // 40 {"conversation_no", CONVERSATION_NO, CONTROL_FOOT, false, true, _td("Conversation no")}, {"group_control_forwards", GROUP_CONTROL_FORWARDS, CONTROL_FOOT, false, true, _td("Group control forwards")}, {"group_control_back", GROUP_CONTROL_BACK, CONTROL_FOOT, false, true, _td("Group control backwards")}, @@ -277,20 +277,36 @@ static bool& GetBindableKeyState(const SBindableKey* key) return bindableKeyStates[index]; } -// Ensure zero length strings are NULL -static void NullEmptyStrings(const char*& a, const char*& b = *(const char**)NULL, const char*& c = *(const char**)NULL, const char*& d = *(const char**)NULL, - const char*& e = *(const char**)NULL) +static void NullIfEmpty(const char*& str) { - if (&a && a && a[0] == 0) - a = NULL; - if (&b && b && b[0] == 0) - b = NULL; - if (&c && c && c[0] == 0) - c = NULL; - if (&d && d && d[0] == 0) - d = NULL; - if (&e && e && e[0] == 0) - e = NULL; + if (str && str[0] == 0) + str = nullptr; +} + +static void NullEmptyStrings(const char*& a) +{ + NullIfEmpty(a); +} + +static void NullEmptyStrings(const char*& a, const char*& b) +{ + NullIfEmpty(a); + NullIfEmpty(b); +} + +static void NullEmptyStrings(const char*& a, const char*& b, const char*& c) +{ + NullIfEmpty(a); + NullIfEmpty(b); + NullIfEmpty(c); +} + +static void NullEmptyStrings(const char*& a, const char*& b, const char*& c, const char*& d) +{ + NullIfEmpty(a); + NullIfEmpty(b); + NullIfEmpty(c); + NullIfEmpty(d); } template @@ -416,16 +432,19 @@ bool CKeyBinds::ProcessKeyStroke(const SBindableKey* pKey, bool bState) bool wasBindFound = false; std::list processedCommandBinds; - auto wasCommandBindProcessed = [&processedCommandBinds](CCommandBind* commandBind) { - auto iter = std::find_if(processedCommandBinds.begin(), processedCommandBinds.end(), [&](CCommandBind* processedCommandBind) { - if (processedCommandBind->triggerState != commandBind->triggerState) - return false; + auto wasCommandBindProcessed = [&processedCommandBinds](CCommandBind* commandBind) + { + auto iter = std::find_if(processedCommandBinds.begin(), processedCommandBinds.end(), + [&](CCommandBind* processedCommandBind) + { + if (processedCommandBind->triggerState != commandBind->triggerState) + return false; - if (processedCommandBind->command != commandBind->command) - return false; + if (processedCommandBind->command != commandBind->command) + return false; - return commandBind->arguments.empty() || processedCommandBind->arguments == commandBind->arguments; - }); + return commandBind->arguments.empty() || processedCommandBind->arguments == commandBind->arguments; + }); return iter != processedCommandBinds.end(); }; @@ -490,7 +509,7 @@ bool CKeyBinds::ProcessKeyStroke(const SBindableKey* pKey, bool bState) processedCommandBinds.push_back(commandBind); } } - else // bindWithState->type == KeyBindType::FUNCTION + else // bindWithState->type == KeyBindType::FUNCTION { if (bAllowed) { @@ -549,8 +568,20 @@ void CKeyBinds::RemoveDeletedBinds() void CKeyBinds::ClearCommandsAndControls() { - const auto predicate = [](const KeyBindPtr& bind) { - return !bind->isBeingDeleted && bind->type != KeyBindType::FUNCTION && bind->type != KeyBindType::CONTROL_FUNCTION; + const auto predicate = [](const KeyBindPtr& bind) + { + if (bind->isBeingDeleted) + return false; + + if (bind->type == KeyBindType::COMMAND) + { + auto commandBind = static_cast(bind.get()); + // Only remove resource bindings, preserve user bindings + return commandBind->context == BindingContext::RESOURCE; + } + + // Remove all control bindings (GTA_CONTROL) + return bind->type == KeyBindType::GTA_CONTROL; }; RemoveBinds(m_binds, !m_bProcessingKeyStroke, predicate); } @@ -612,9 +643,11 @@ bool CKeyBinds::AddCommand(const char* szKey, const char* szCommand, const char* CCommandBind* pUserAddedBind = FindCommandMatch(NULL, szCommand, szArguments, szResource, szKey, true, bState, true, false); if (pUserAddedBind) { - // Upgrade + // Upgrade user binding to resource binding pUserAddedBind->wasCreatedByScript = true; pUserAddedBind->isReplacingScriptKey = true; + pUserAddedBind->context = BindingContext::RESOURCE; + pUserAddedBind->sourceResource = szResource; assert(pUserAddedBind->originalScriptKey == szKey); return true; } @@ -631,12 +664,19 @@ bool CKeyBinds::AddCommand(const char* szKey, const char* szCommand, const char* if (szResource) { bind->resource = szResource; + bind->sourceResource = szResource; bind->wasCreatedByScript = bScriptCreated; + bind->context = BindingContext::RESOURCE; if (bScriptCreated) bind->originalScriptKey = szKey; else if (szOriginalScriptKey) - bind->originalScriptKey = szOriginalScriptKey; // Will wait for script to addcommand before doing replace + bind->originalScriptKey = szOriginalScriptKey; // Will wait for script to addcommand before doing replace + } + else + { + // User-created binding (via /bind command) + bind->context = BindingContext::USER; } m_binds.emplace_back(bind.release()); @@ -669,7 +709,8 @@ bool CKeyBinds::RemoveCommand(const char* szKey, const char* szCommand, bool bCh std::string_view command{szCommand}; - const auto predicate = [&](const KeyBindPtr& bind) { + const auto predicate = [&](const KeyBindPtr& bind) + { if (bind->isBeingDeleted || bind->type != KeyBindType::COMMAND) return false; @@ -692,7 +733,8 @@ bool CKeyBinds::RemoveAllCommands(const char* szKey, bool bCheckState, bool bSta if (!szKey) return false; - const auto predicate = [&](const KeyBindPtr& bind) { + const auto predicate = [&](const KeyBindPtr& bind) + { if (bind->isBeingDeleted || bind->type != KeyBindType::COMMAND) return false; @@ -931,7 +973,8 @@ void CKeyBinds::UserChangeCommandBoundKey(CCommandBind* pBind, const SBindableKe // void CKeyBinds::SortCommandBinds() { - auto compare = [](const KeyBindPtr& lhs, const KeyBindPtr& rhs) { + auto compare = [](const KeyBindPtr& lhs, const KeyBindPtr& rhs) + { // Group command binds last if (lhs->type != KeyBindType::COMMAND && rhs->type == KeyBindType::COMMAND) return true; @@ -1021,7 +1064,8 @@ bool CKeyBinds::RemoveGTAControl(const char* szKey, const char* szControl) if (!szKey || !szControl) return false; - const auto predicate = [&](const KeyBindPtr& bind) { + const auto predicate = [&](const KeyBindPtr& bind) + { if (bind->isBeingDeleted || bind->type != KeyBindType::GTA_CONTROL) return false; @@ -1037,7 +1081,8 @@ bool CKeyBinds::RemoveAllGTAControls(const char* szKey) if (!szKey) return false; - const auto predicate = [&](const KeyBindPtr& bind) { + const auto predicate = [&](const KeyBindPtr& bind) + { if (bind->isBeingDeleted || bind->type != KeyBindType::GTA_CONTROL) return false; @@ -1332,7 +1377,8 @@ bool CKeyBinds::RemoveFunction(const char* szKey, KeyFunctionBindHandler Handler bool CKeyBinds::RemoveFunction(const SBindableKey* pKey, KeyFunctionBindHandler Handler, bool bCheckState, bool bState) { - const auto predicate = [&](const KeyBindPtr& bind) { + const auto predicate = [&](const KeyBindPtr& bind) + { if (bind->isBeingDeleted || bind->type != KeyBindType::FUNCTION) return false; @@ -1349,7 +1395,8 @@ bool CKeyBinds::RemoveFunction(const SBindableKey* pKey, KeyFunctionBindHandler bool CKeyBinds::RemoveAllFunctions(KeyFunctionBindHandler Handler) { - const auto predicate = [&](const KeyBindPtr& bind) { + const auto predicate = [&](const KeyBindPtr& bind) + { if (bind->isBeingDeleted || bind->type != KeyBindType::FUNCTION) return false; @@ -1436,7 +1483,8 @@ bool CKeyBinds::RemoveControlFunction(const char* szControl, ControlFunctionBind bool CKeyBinds::RemoveControlFunction(SBindableGTAControl* pControl, ControlFunctionBindHandler Handler, bool bCheckState, bool bState) { - const auto predicate = [&](const KeyBindPtr& bind) { + const auto predicate = [&](const KeyBindPtr& bind) + { if (bind->isBeingDeleted || bind->type != KeyBindType::CONTROL_FUNCTION) return false; @@ -1453,7 +1501,8 @@ bool CKeyBinds::RemoveControlFunction(SBindableGTAControl* pControl, ControlFunc bool CKeyBinds::RemoveAllControlFunctions(ControlFunctionBindHandler Handler) { - const auto predicate = [&](const KeyBindPtr& bind) { + const auto predicate = [&](const KeyBindPtr& bind) + { if (bind->isBeingDeleted || bind->type != KeyBindType::CONTROL_FUNCTION) return false; @@ -1874,7 +1923,8 @@ void CKeyBinds::DoPostFramePulse() { SystemState systemState = CCore::GetSingleton().GetGame()->GetSystemState(); - if (m_bWaitingToLoadDefaults && (systemState == SystemState::GS_FRONTEND || systemState == SystemState::GS_PLAYING_GAME)) // Are GTA controls actually initialized? + if (m_bWaitingToLoadDefaults && + (systemState == SystemState::GS_FRONTEND || systemState == SystemState::GS_PLAYING_GAME)) // Are GTA controls actually initialized? { LoadDefaultBinds(); m_bWaitingToLoadDefaults = false; @@ -1926,16 +1976,16 @@ void CKeyBinds::DoPostFramePulse() { if (!bInVehicle) { - cs.ButtonCircle = (g_bcControls[0].bState && !bHasDetonator) ? 255 : 0; // Fire + cs.ButtonCircle = (g_bcControls[0].bState && !bHasDetonator) ? 255 : 0; // Fire if (bAimingWeapon) { - cs.RightShoulder2 = g_bcControls[8].bState ? 255 : 0; // Zoom Out - cs.LeftShoulder2 = g_bcControls[7].bState ? 255 : 0; // Zoom In + cs.RightShoulder2 = g_bcControls[8].bState ? 255 : 0; // Zoom Out + cs.LeftShoulder2 = g_bcControls[7].bState ? 255 : 0; // Zoom In } else { - cs.RightShoulder2 = g_bcControls[1].bState ? 255 : 0; // Next Weapon - cs.LeftShoulder2 = g_bcControls[2].bState ? 255 : 0; // Previous Weapon + cs.RightShoulder2 = g_bcControls[1].bState ? 255 : 0; // Next Weapon + cs.LeftShoulder2 = g_bcControls[2].bState ? 255 : 0; // Previous Weapon } if (!ControlForwardsBackWards(cs)) @@ -1950,39 +2000,39 @@ void CKeyBinds::DoPostFramePulse() // * Enter Exit // * Change View - cs.ButtonSquare = (!bEnteringVehicle && g_bcControls[11].bState) ? 255 : 0; // Jump - cs.ButtonCross = (g_bcControls[12].bState) ? 255 : 0; // Sprint - cs.ShockButtonR = (g_bcControls[13].bState) ? 255 : 0; // Look Behind - cs.ShockButtonL = (g_bcControls[14].bState) ? 255 : 0; // Crouch - cs.LeftShoulder1 = (g_bcControls[15].bState) ? 255 : 0; // Action - cs.m_bPedWalk = (g_bcControls[16].bState) ? 255 : 0; // Walk + cs.ButtonSquare = (!bEnteringVehicle && !bAimingWeapon && g_bcControls[11].bState) ? 255 : 0; // Jump + cs.ButtonCross = (g_bcControls[12].bState) ? 255 : 0; // Sprint + cs.ShockButtonR = (g_bcControls[13].bState) ? 255 : 0; // Look Behind + cs.ShockButtonL = (g_bcControls[14].bState) ? 255 : 0; // Crouch + cs.LeftShoulder1 = (g_bcControls[15].bState) ? 255 : 0; // Action + cs.m_bPedWalk = (g_bcControls[16].bState) ? 255 : 0; // Walk // * Vehicle Keys - cs.RightShoulder1 = (g_bcControls[39].bState) ? 255 : 0; // Aim Weapon - cs.DPadRight = (g_bcControls[40].bState) ? 255 : 0; // Conversation Yes - cs.DPadLeft = (g_bcControls[41].bState) ? 255 : 0; // Conversation No - cs.DPadUp = (g_bcControls[42].bState) ? 255 : 0; // Group Control Forwards - cs.DPadDown = (g_bcControls[43].bState) ? 255 : 0; // Group Control Backwards + cs.RightShoulder1 = (g_bcControls[39].bState) ? 255 : 0; // Aim Weapon + cs.DPadRight = (g_bcControls[40].bState) ? 255 : 0; // Conversation Yes + cs.DPadLeft = (g_bcControls[41].bState) ? 255 : 0; // Conversation No + cs.DPadUp = (g_bcControls[42].bState) ? 255 : 0; // Group Control Forwards + cs.DPadDown = (g_bcControls[43].bState) ? 255 : 0; // Group Control Backwards } else { - cs.ButtonCircle = (g_bcControls[17].bState) ? 255 : 0; // Fire - cs.LeftShoulder1 = (g_bcControls[18].bState) ? 255 : 0; // Secondary Fire + cs.ButtonCircle = (g_bcControls[17].bState) ? 255 : 0; // Fire + cs.LeftShoulder1 = (g_bcControls[18].bState) ? 255 : 0; // Secondary Fire cs.LeftStickX = ((g_bcControls[19].bState && g_bcControls[20].bState) || (!g_bcControls[19].bState && !g_bcControls[20].bState)) ? 0 : (g_bcControls[19].bState) ? -128 : 128; cs.LeftStickY = ((g_bcControls[21].bState && g_bcControls[22].bState) || (!g_bcControls[21].bState && !g_bcControls[22].bState)) ? 0 : (g_bcControls[21].bState) ? -128 : 128; - cs.ButtonCross = (g_bcControls[23].bState) ? 255 : 0; // Accelerate - cs.ButtonSquare = (g_bcControls[24].bState) ? 255 : 0; // Reverse - cs.DPadUp = (g_bcControls[25].bState) ? 255 : 0; // Radio Next - cs.DPadDown = (g_bcControls[26].bState) ? 255 : 0; // Radio Previous - cs.m_bRadioTrackSkip = (g_bcControls[27].bState) ? 255 : 0; // Radio Skip - cs.ShockButtonL = (g_bcControls[28].bState) ? 255 : 0; // Horn - cs.ShockButtonR = (g_bcControls[29].bState) ? 255 : 0; // Sub Mission - cs.RightShoulder1 = (g_bcControls[30].bState) ? 255 : 0; // Handbrake - cs.LeftShoulder2 = (g_bcControls[31].bState || g_bcControls[33].bState) ? 255 : 0; // Look Left - cs.RightShoulder2 = (g_bcControls[32].bState || g_bcControls[33].bState) ? 255 : 0; // Look Right + cs.ButtonCross = (g_bcControls[23].bState) ? 255 : 0; // Accelerate + cs.ButtonSquare = (g_bcControls[24].bState) ? 255 : 0; // Reverse + cs.DPadUp = (g_bcControls[25].bState) ? 255 : 0; // Radio Next + cs.DPadDown = (g_bcControls[26].bState) ? 255 : 0; // Radio Previous + cs.m_bRadioTrackSkip = (g_bcControls[27].bState) ? 255 : 0; // Radio Skip + cs.ShockButtonL = (g_bcControls[28].bState) ? 255 : 0; // Horn + cs.ShockButtonR = (g_bcControls[29].bState) ? 255 : 0; // Sub Mission + cs.RightShoulder1 = (g_bcControls[30].bState) ? 255 : 0; // Handbrake + cs.LeftShoulder2 = (g_bcControls[31].bState || g_bcControls[33].bState) ? 255 : 0; // Look Left + cs.RightShoulder2 = (g_bcControls[32].bState || g_bcControls[33].bState) ? 255 : 0; // Look Right // * Look Behind - uses both keys above simultaneously // Mouse Look cs.RightStickX = ((g_bcControls[35].bState && g_bcControls[36].bState) || (!g_bcControls[35].bState && !g_bcControls[36].bState)) ? 0 @@ -1992,8 +2042,8 @@ void CKeyBinds::DoPostFramePulse() : (g_bcControls[37].bState) ? 128 : -128; } - cs.ButtonTriangle = (g_bcControls[9].bState) ? 255 : 0; // Enter Exit - cs.Select = (g_bcControls[10].bState) ? 255 : 0; // Change View + cs.ButtonTriangle = (g_bcControls[9].bState) ? 255 : 0; // Enter Exit + cs.Select = (g_bcControls[10].bState) ? 255 : 0; // Change View bool disableGameplayControls = m_pCore->IsCursorForcedVisible() && m_pCore->IsCursorControlsToggled(); @@ -2118,12 +2168,17 @@ bool CKeyBinds::LoadFromXML(CXMLNode* pMainNode) pAttribute = pNode->GetAttributes().Find("default"); SString strOriginalScriptKey = pAttribute ? pAttribute->GetValue() : ""; - AddCommand(strKey.c_str(), strCommand.c_str(), strArguments.c_str(), bState, strResource.c_str(), false, - strOriginalScriptKey); - SetCommandActive(strKey.c_str(), strCommand.c_str(), bState, strArguments.c_str(), strResource.c_str(), false, true); + const char* szArgs = strArguments.empty() ? nullptr : strArguments.c_str(); + const char* szOrigKey = strOriginalScriptKey.empty() ? nullptr : strOriginalScriptKey.c_str(); + + AddCommand(strKey.c_str(), strCommand.c_str(), szArgs, bState, strResource.c_str(), false, szOrigKey); + SetCommandActive(strKey.c_str(), strCommand.c_str(), bState, szArgs, strResource.c_str(), false, true); } else if (!CommandExists(strKey.c_str(), strCommand.c_str(), true, bState)) - AddCommand(strKey.c_str(), strCommand.c_str(), strArguments.c_str(), bState); + { + const char* szArgs = strArguments.empty() ? nullptr : strArguments.c_str(); + AddCommand(strKey.c_str(), strCommand.c_str(), szArgs, bState); + } } } else @@ -2154,7 +2209,7 @@ bool CKeyBinds::LoadFromXML(CXMLNode* pMainNode) SystemState systemState = CCore::GetSingleton().GetGame()->GetSystemState(); if (bLoadDefaults) { - if (systemState == SystemState::GS_FRONTEND || systemState == SystemState::GS_PLAYING_GAME) // Are GTA controls actually initialized? + if (systemState == SystemState::GS_FRONTEND || systemState == SystemState::GS_PLAYING_GAME) // Are GTA controls actually initialized? LoadDefaultBinds(); else m_bWaitingToLoadDefaults = true; @@ -2188,7 +2243,8 @@ bool CKeyBinds::SaveToXML(CXMLNode* pMainNode) CXMLAttributes& attributes = bindNode->GetAttributes(); - auto createAttribute = [&attributes](const char* key, const char* value) { + auto createAttribute = [&attributes](const char* key, const char* value) + { if (value && value[0]) { CXMLAttribute* attribute = attributes.Create(key); @@ -2218,7 +2274,7 @@ bool CKeyBinds::SaveToXML(CXMLNode* pMainNode) createAttribute("default", commandBind->originalScriptKey.c_str()); } } - else // bind->type == KeyBindType::GTA_CONTROL + else // bind->type == KeyBindType::GTA_CONTROL { auto controlBind = static_cast(bind.get()); createAttribute("key", controlBind->boundKey->szKey); @@ -2301,7 +2357,7 @@ void CKeyBinds::BindCommand(const char* szCmdLine) { CConsoleInterface* pConsole = m_pCore->GetConsole(); - char* szError = "* Syntax: bind [] []"; + const char* szError = "* Syntax: bind [] []"; if (szCmdLine == NULL) { pConsole->Print(szError); @@ -2384,7 +2440,7 @@ void CKeyBinds::UnbindCommand(const char* szCmdLine) { CConsoleInterface* pConsole = m_pCore->GetConsole(); - char* szError = "* Syntax: unbind [ ]"; + const char* szError = "* Syntax: unbind [ ]"; if (szCmdLine == NULL) { pConsole->Print(szError); @@ -2467,7 +2523,8 @@ void CKeyBinds::PrintBindsCommand(const char* szCmdLine) CConsoleInterface* console = m_pCore->GetConsole(); - auto print = [console](const KeyBindPtr& bind) { + auto print = [console](const KeyBindPtr& bind) + { switch (bind->type) { case KeyBindType::COMMAND: @@ -2632,3 +2689,150 @@ bool CKeyBinds::TriggerKeyStrokeHandler(const SString& strKey, bool bState, bool } return true; } + +bool CKeyBinds::CommandExistsInContext(const char* key, const char* command, BindingContext context, bool checkState, bool state, const char* arguments, + const char* resource) +{ + if (!key || !command) + return false; + + for (const KeyBindPtr& bind : m_binds) + { + if (bind->isBeingDeleted || bind->type != KeyBindType::COMMAND) + continue; + + auto commandBind = static_cast(bind.get()); + + if (commandBind->context != context) + continue; + + if (stricmp(commandBind->boundKey->szKey, key) != 0) + continue; + + if (stricmp(commandBind->command.c_str(), command) != 0) + continue; + + if (checkState && commandBind->triggerState != state) + continue; + + if (arguments && commandBind->arguments != arguments) + continue; + + if (resource && commandBind->resource != resource) + continue; + + return true; + } + + return false; +} + +bool CKeyBinds::RemoveCommandFromContext(const char* key, const char* command, BindingContext context, bool checkState, bool state, const char* arguments, + const char* resource) +{ + if (!key || !command) + return false; + + const auto predicate = [&](const KeyBindPtr& bind) + { + if (bind->isBeingDeleted || bind->type != KeyBindType::COMMAND) + return false; + + auto commandBind = static_cast(bind.get()); + + if (commandBind->context != context) + return false; + + if (stricmp(commandBind->boundKey->szKey, key) != 0) + return false; + + if (stricmp(commandBind->command.c_str(), command) != 0) + return false; + + if (checkState && commandBind->triggerState != state) + return false; + + if (arguments && commandBind->arguments != arguments) + return false; + + if (resource && commandBind->resource != resource) + return false; + + return true; + }; + + return RemoveBinds(m_binds, !m_bProcessingKeyStroke, predicate); +} + +bool CKeyBinds::HasAnyBindingForKey(const char* key, bool checkState, bool state) +{ + if (!key) + return false; + + for (const KeyBindPtr& bind : m_binds) + { + if (bind->isBeingDeleted) + continue; + + if (bind->type == KeyBindType::COMMAND) + { + auto commandBind = static_cast(bind.get()); + if (stricmp(commandBind->boundKey->szKey, key) == 0) + { + if (!checkState || commandBind->triggerState == state) + return true; + } + } + else if (bind->type == KeyBindType::FUNCTION) + { + auto functionBind = static_cast(bind.get()); + if (stricmp(functionBind->boundKey->szKey, key) == 0) + { + if (!checkState || functionBind->triggerState == state) + return true; + } + } + else if (bind->type == KeyBindType::CONTROL_FUNCTION) + { + auto controlBind = static_cast(bind.get()); + if (stricmp(controlBind->boundKey->szKey, key) == 0) + { + if (!checkState || controlBind->triggerState == state) + return true; + } + } + else if (bind->type == KeyBindType::GTA_CONTROL) + { + auto gtaBind = static_cast(bind.get()); + if (stricmp(gtaBind->boundKey->szKey, key) == 0) + return true; + } + } + + return false; +} + +bool CKeyBinds::HasBindingInContext(const char* key, BindingContext context, bool checkState, bool state) +{ + if (!key) + return false; + + for (const KeyBindPtr& bind : m_binds) + { + if (bind->isBeingDeleted || bind->type != KeyBindType::COMMAND) + continue; + + auto commandBind = static_cast(bind.get()); + + if (commandBind->context != context) + continue; + + if (stricmp(commandBind->boundKey->szKey, key) != 0) + continue; + + if (!checkState || commandBind->triggerState == state) + return true; + } + + return false; +} diff --git a/Client/core/CKeyBinds.h b/Client/core/CKeyBinds.h index c5464a5b463..ecde1221b79 100644 --- a/Client/core/CKeyBinds.h +++ b/Client/core/CKeyBinds.h @@ -75,6 +75,14 @@ class CKeyBinds final : public CKeyBindsInterface bool bCheckState, bool bState, bool bCheckScriptCreated, bool bScriptCreated); void SortCommandBinds(); + // Context-aware binding methods + bool CommandExistsInContext(const char* key, const char* command, BindingContext context, bool checkState = false, bool state = true, + const char* arguments = NULL, const char* resource = NULL); + bool RemoveCommandFromContext(const char* key, const char* command, BindingContext context, bool checkState = false, bool state = true, + const char* arguments = NULL, const char* resource = NULL); + bool HasAnyBindingForKey(const char* key, bool checkState = false, bool state = true); + bool HasBindingInContext(const char* key, BindingContext context, bool checkState = false, bool state = true); + // Control-bind funcs bool AddGTAControl(const char* szKey, const char* szControl); bool AddGTAControl(const SBindableKey* pKey, SBindableGTAControl* pControl); diff --git a/Client/core/CLanguage.h b/Client/core/CLanguage.h index fcbd98e5c51..01ec4586d8c 100644 --- a/Client/core/CLanguage.h +++ b/Client/core/CLanguage.h @@ -31,6 +31,6 @@ class CLanguage private: Dictionary m_Dict; - SString m_strCode; // Language code - SString m_strName; // Human readable name + SString m_strCode; // Language code + SString m_strName; // Human readable name }; diff --git a/Client/core/CLanguageSelector.cpp b/Client/core/CLanguageSelector.cpp index db2cc861788..6b4e47dca92 100644 --- a/Client/core/CLanguageSelector.cpp +++ b/Client/core/CLanguageSelector.cpp @@ -11,28 +11,28 @@ #include "StdInc.h" #include "CLanguageSelector.h" -#define LANGUAGE_ICON_SIZE_X 20 -#define LANGUAGE_ICON_SIZE_Y 24 -#define LANGUAGE_ICON_LABEL_GAP_X 10 // Gap between language icon and label +#define LANGUAGE_ICON_SIZE_X 20 +#define LANGUAGE_ICON_SIZE_Y 24 +#define LANGUAGE_ICON_LABEL_GAP_X 10 // Gap between language icon and label -#define LABEL_SIZE_X 165 -#define LABEL_SIZE_Y 16 +#define LABEL_SIZE_X 165 +#define LABEL_SIZE_Y 16 #define LANGUAGE_ICON_LABEL_OFFSET_Y ((LANGUAGE_ICON_SIZE_Y - LABEL_SIZE_Y) / 2) // Language icon and label combo -#define ITEM_SIZE_X 165 -#define ITEM_SIZE_Y 24 +#define ITEM_SIZE_X 165 +#define ITEM_SIZE_Y 24 // Current language button -#define BUTTON_MARGIN_X 20 -#define BUTTON_MARGIN_Y 5 +#define BUTTON_MARGIN_X 20 +#define BUTTON_MARGIN_Y 5 // All languages list -#define LIST_MARGIN_X 20 -#define LIST_MARGIN_Y 18 -#define LIST_ITEM_SPACING_X 10 -#define LIST_ITEM_SPACING_Y 1 +#define LIST_MARGIN_X 20 +#define LIST_MARGIN_Y 18 +#define LIST_ITEM_SPACING_X 10 +#define LIST_ITEM_SPACING_Y 1 /////////////////////////////////////////////////////////////// // @@ -55,17 +55,25 @@ CLanguageSelector::CLanguageSelector(CGUIElement* pMainMenuCanvas) /////////////////////////////////////////////////////////////// CLanguageSelector::~CLanguageSelector() { - SAFE_DELETE(m_pButtonWindow); - SAFE_DELETE(m_pListWindow); - SAFE_DELETE(m_ButtonItem.pContainerPane); - SAFE_DELETE(m_ButtonItem.pIcon); - SAFE_DELETE(m_ButtonItem.pLabel); - for (CLangListItem& item : m_ListItems) + CGUI* pGUI = g_pCore ? g_pCore->GetGUI() : nullptr; + + auto destroyElement = [pGUI](auto*& element) { - SAFE_DELETE(item.pContainerPane); - SAFE_DELETE(item.pIcon); - SAFE_DELETE(item.pLabel); - } + if (!element) + return; + + auto* elementToDestroy = element; + element = nullptr; + if (pGUI) + pGUI->DestroyElementRecursive(elementToDestroy); + }; + + // Ensure callbacks see a safe state even if destruction triggers them re-entrantly + m_ButtonItem = CLangListItem(); + m_ListItems.clear(); + + destroyElement(m_pListWindow); + destroyElement(m_pButtonWindow); } /////////////////////////////////////////////////////////////// @@ -118,7 +126,6 @@ void CLanguageSelector::CreateGUI(CGUIElement* pMainMenuCanvas) pLabel->SetZOrderingEnabled(false); pLabel->SetText(g_pLocalization->GetLanguageNativeName()); - CLangListItem m_ButtonItem; m_ButtonItem.strLocale = ""; m_ButtonItem.pContainerPane = pContainerPane; m_ButtonItem.pIcon = pIcon; @@ -226,6 +233,9 @@ CLangListItem CLanguageSelector::CreateGUILangItem(CGUIElement* pGUIParent, cons /////////////////////////////////////////////////////////////// void CLanguageSelector::DoPulse() { + if (!m_pButtonWindow) + return; + if (CLocalGUI::GetSingleton().GetMainMenu()->GetIsIngame()) { // Can't change locale when connected, so hide @@ -241,12 +251,12 @@ void CLanguageSelector::DoPulse() fDeltaSeconds = Clamp(0.01f, fDeltaSeconds, 0.10f); // Update current language button mouseover effect - m_bListWasVisible = m_pListWindow->IsVisible(); + m_bListWasVisible = m_pListWindow && m_pListWindow->IsVisible(); m_pButtonWindow->SetAlpha((m_bMouseOverButton || m_bListWasVisible) ? 1.f : 0.5f); m_pButtonWindow->SetVisible(true); // Animate list items if list is visible - if (m_bListWasVisible) + if (m_bListWasVisible && m_pListWindow) { for (CLangListItem& item : m_ListItems) { @@ -272,6 +282,9 @@ void CLanguageSelector::DoPulse() /////////////////////////////////////////////////////////////// void CLanguageSelector::SetLanguageListVisible(bool bVisible) { + if (!m_pListWindow) + return; + if (bVisible) { m_pListWindow->BringToFront(); @@ -280,7 +293,6 @@ void CLanguageSelector::SetLanguageListVisible(bool bVisible) } m_pListWindow->SetVisible(bVisible); } - /////////////////////////////////////////////////////////////// // // CLanguageSelector::GetListItemByIndex @@ -379,13 +391,16 @@ bool CLanguageSelector::OnListItemClick(CGUIElement* pElement) if (pItem) { SetLanguageListVisible(false); - SString strPrevLocale = CVARS_GET_VALUE("locale"); - SString strNewLocale = pItem->strLocale; + const SString strPrevLocale = CVARS_GET_VALUE("locale"); + const SString strNewLocale = pItem->strLocale; if (strNewLocale != strPrevLocale) { - // Locale change - CVARS_SET("locale", strNewLocale); - SetApplicationSetting("locale", strNewLocale); + CLocalGUI::GetSingleton().RequestLocaleChange(strNewLocale); + + // Update button label immediately so user sees their selection + m_ButtonItem.strLocale = strNewLocale; + if (m_ButtonItem.pLabel) + m_ButtonItem.pLabel->SetText(g_pLocalization->GetLanguageNativeName(strNewLocale)); } } return true; diff --git a/Client/core/CLinkedList.h b/Client/core/CLinkedList.h index b271232cfe4..7a46b295fb1 100644 --- a/Client/core/CLinkedList.h +++ b/Client/core/CLinkedList.h @@ -17,7 +17,7 @@ #pragma once // ignore the return type warning for the -> operator when we are potentially using pointers themselves -#pragma warning(disable:4284) +#pragma warning(disable : 4284) #include @@ -271,7 +271,7 @@ class CLinkedList void remove(CIterator& itNode, BOOL bIterateForwards = TRUE) { CNode* pTempNode = itNode.m_pCurrent; - CNode* pTempSingleNode = NULL; // will be used if only a single node remains + CNode* pTempSingleNode = NULL; // will be used if only a single node remains BOOL bIteratorSet = FALSE; diff --git a/Client/core/CLocalization.cpp b/Client/core/CLocalization.cpp index fbc56232773..24c9875b200 100644 --- a/Client/core/CLocalization.cpp +++ b/Client/core/CLocalization.cpp @@ -11,7 +11,7 @@ #include "StdInc.h" #include "../../vendor/tinygettext/log.hpp" -#define MTA_LOCALE_TEXTDOMAIN "client" +#define MTA_LOCALE_TEXTDOMAIN "client" // TRANSLATORS: Replace with your language native name #define NATIVE_LANGUAGE_NAME _td("English") @@ -20,11 +20,13 @@ struct NativeLanguageName std::string locale; std::string name; } g_nativeLanguageNames[] = { - #include "languages.generated.h" +#include "languages.generated.h" }; CLocalization::CLocalization(const SString& strLocale, const SString& strLocalePath) { + m_pCurrentLang = NULL; + // Set log callbacks so we can record problems Log::set_log_info_callback(NULL); Log::set_log_warning_callback(LogCallback); @@ -39,10 +41,7 @@ CLocalization::CLocalization(const SString& strLocale, const SString& strLocaleP CLocalization::~CLocalization() { - for (auto iter : m_LanguageMap) - { - delete iter.second; - } + m_pCurrentLang = nullptr; } // @@ -78,7 +77,18 @@ void CLocalization::SetCurrentLanguage(SString strLocale) // Update our locale setting with full country code, now that we've matched it if (g_pCore) - CVARS_SET("locale", strLocale); + { + SString strCurrentLocale = CVARS_GET_VALUE("locale"); + if (strCurrentLocale != strLocale) + CVARS_SET("locale", strLocale); + } + + SString strStoredLocale = GetApplicationSetting("locale"); + if (strStoredLocale != strLocale) + SetApplicationSetting("locale", strLocale); + + if (m_pCurrentLang && m_pCurrentLang->GetCode() == strLocale) + return; m_pCurrentLang = GetLanguage(strLocale); } @@ -86,15 +96,33 @@ void CLocalization::SetCurrentLanguage(SString strLocale) CLanguage* CLocalization::GetLanguage(SString strLocale) { strLocale = ValidateLocale(strLocale); - CLanguage* pLanguage = MapFindRef(m_LanguageMap, strLocale); - if (!pLanguage) + auto iter = m_LanguageMap.find(strLocale); + if (iter != m_LanguageMap.end()) + { + return iter->second.get(); + } + + Language Lang = Language::from_name(strLocale); + Lang = Lang ? Lang : Language::from_name("en_US"); + + try + { + std::unique_ptr pLanguage = + std::make_unique(m_DictManager.get_dictionary(Lang, MTA_LOCALE_TEXTDOMAIN), Lang.str(), Lang.get_name()); + CLanguage* pLanguagePtr = pLanguage.get(); + m_LanguageMap.emplace(strLocale, std::move(pLanguage)); + return pLanguagePtr; + } + catch (const std::exception& ex) { - Language Lang = Language::from_name(strLocale); - Lang = Lang ? Lang : Language::from_name("en_US"); - pLanguage = new CLanguage(m_DictManager.get_dictionary(Lang, MTA_LOCALE_TEXTDOMAIN), Lang.str(), Lang.get_name()); - MapSet(m_LanguageMap, strLocale, pLanguage); + WriteDebugEvent(SString("Localization failed to load dictionary for '%s': %s", strLocale.c_str(), ex.what())); + return (strLocale != "en_US") ? GetLanguage("en_US") : nullptr; + } + catch (...) + { + WriteDebugEvent(SString("Localization failed to load dictionary for '%s': unknown error", strLocale.c_str())); + return (strLocale != "en_US") ? GetLanguage("en_US") : nullptr; } - return pLanguage; } // @@ -113,11 +141,15 @@ SString CLocalization::GetLanguageNativeName(SString strLocale) return iter->name; // If not found, we fall back to the loading the language file and using the name from there. - SString strNativeName = GetLanguage(strLocale)->Translate(NATIVE_LANGUAGE_NAME); + CLanguage* pLanguage = GetLanguage(strLocale); + if (!pLanguage) + return SString(); + + SString strNativeName = pLanguage->Translate(NATIVE_LANGUAGE_NAME); if (strNativeName == "English" && strLocale != "en_US") { // If native name not available, use English version - strNativeName = GetLanguage(strLocale)->GetName(); + strNativeName = pLanguage->GetName(); } return strNativeName; @@ -125,26 +157,41 @@ SString CLocalization::GetLanguageNativeName(SString strLocale) SString CLocalization::Translate(const SString& strMessage) { + if (!m_pCurrentLang) + return strMessage; + return m_pCurrentLang->Translate(strMessage); } SString CLocalization::TranslateWithContext(const SString& strContext, const SString& strMessage) { + if (!m_pCurrentLang) + return strMessage; + return m_pCurrentLang->TranslateWithContext(strContext, strMessage); } SString CLocalization::TranslatePlural(const SString& strSingular, const SString& strPlural, const int iNum) { + if (!m_pCurrentLang) + return (iNum == 1 ? strSingular : strPlural); + return m_pCurrentLang->TranslatePlural(strSingular, strPlural, iNum); } SString CLocalization::TranslatePluralWithContext(const SString& strContext, const SString& strSingular, const SString& strPlural, int iNum) { + if (!m_pCurrentLang) + return (iNum == 1 ? strSingular : strPlural); + return m_pCurrentLang->TranslatePluralWithContext(strContext, strSingular, strPlural, iNum); } SString CLocalization::GetTranslators() { + if (!m_pCurrentLang) + return ""; + std::map metaData = m_pCurrentLang->GetDictionary().get_metadata(); if (metaData.find("Translators") != metaData.end()) { @@ -176,19 +223,22 @@ bool CLocalization::IsLocalized() SString CLocalization::GetLanguageCode() { - return m_pCurrentLang->GetCode(); + return m_pCurrentLang ? m_pCurrentLang->GetCode() : SString(); } SString CLocalization::GetLanguageName() { - return m_pCurrentLang->GetName(); + return m_pCurrentLang ? m_pCurrentLang->GetName() : SString(); } // Get the file directory of the current language SString CLocalization::GetLanguageDirectory(CLanguage* pLanguage) { CLanguage* pSelectLang = pLanguage != nullptr ? pLanguage : m_pCurrentLang; - SString strFullPath = pSelectLang->GetDictionary().get_filepath(); + if (!pSelectLang) + return SString(); + + SString strFullPath = pSelectLang->GetDictionary().get_filepath(); // Replace all backslashes with forward slashes int idx = 0; diff --git a/Client/core/CLocalization.h b/Client/core/CLocalization.h index 29d5c8f6bdd..6e5b46b5798 100644 --- a/Client/core/CLocalization.h +++ b/Client/core/CLocalization.h @@ -13,7 +13,8 @@ using namespace tinygettext; #include #include "CLanguage.h" -#define MTA_LOCALE_DIR "MTA/locale/" +#include +#define MTA_LOCALE_DIR "MTA/locale/" #pragma once @@ -42,7 +43,7 @@ class CLocalization : public CLocalizationInterface static void LogCallback(const std::string& str); private: - DictionaryManager m_DictManager; - std::map m_LanguageMap; - CLanguage* m_pCurrentLang; + DictionaryManager m_DictManager; + std::map> m_LanguageMap; + CLanguage* m_pCurrentLang{}; }; diff --git a/Client/core/CMainMenu.cpp b/Client/core/CMainMenu.cpp index 7848da2162a..95ac496a92a 100644 --- a/Client/core/CMainMenu.cpp +++ b/Client/core/CMainMenu.cpp @@ -15,39 +15,40 @@ #include "CLanguageSelector.h" #include "CDiscordRichPresence.h" -#define NATIVE_RES_X 1280.0f -#define NATIVE_RES_Y 1024.0f +#define NATIVE_RES_X 1280.0f +#define NATIVE_RES_Y 1024.0f -#define NATIVE_BG_X 1280.0f -#define NATIVE_BG_Y 649.0f +#define NATIVE_BG_X 1280.0f +#define NATIVE_BG_Y 649.0f -#define NATIVE_LOGO_X 1058.0f -#define NATIVE_LOGO_Y 540.0f +#define NATIVE_LOGO_X 1058.0f +#define NATIVE_LOGO_Y 540.0f -#define CORE_MTA_MENUITEMS_START_X 0.168 +#define CORE_MTA_MENUITEMS_START_X 0.168 -#define CORE_MTA_BG_MAX_ALPHA 1.00f //ACHTUNG: Set to 1 for now due to GTA main menu showing through (no delay inserted between Entering game... and loading screen) -#define CORE_MTA_BG_INGAME_ALPHA 0.90f -#define CORE_MTA_FADER 0.05f // 1/20 -#define CORE_MTA_FADER_CREDITS 0.01f +#define CORE_MTA_BG_MAX_ALPHA \ + 1.00f // ACHTUNG: Set to 1 for now due to GTA main menu showing through (no delay inserted between Entering game... and loading screen) +#define CORE_MTA_BG_INGAME_ALPHA 0.90f +#define CORE_MTA_FADER 0.05f // 1/20 +#define CORE_MTA_FADER_CREDITS 0.01f -#define CORE_MTA_HOVER_SCALE 1.0f -#define CORE_MTA_NORMAL_SCALE 0.6f -#define CORE_MTA_HOVER_ALPHA 1.0f -#define CORE_MTA_NORMAL_ALPHA 0.6f +#define CORE_MTA_HOVER_SCALE 1.0f +#define CORE_MTA_NORMAL_SCALE 0.6f +#define CORE_MTA_HOVER_ALPHA 1.0f +#define CORE_MTA_NORMAL_ALPHA 0.6f -#define CORE_MTA_HIDDEN_ALPHA 0.0f -#define CORE_MTA_DISABLED_ALPHA 0.4f -#define CORE_MTA_ENABLED_ALPHA 1.0f +#define CORE_MTA_HIDDEN_ALPHA 0.0f +#define CORE_MTA_DISABLED_ALPHA 0.4f +#define CORE_MTA_ENABLED_ALPHA 1.0f #define CORE_MTA_ANIMATION_TIME_IN 200 #define CORE_MTA_ANIMATION_TIME_OUT 100 #define CORE_MTA_MOVE_ANIM_TIME 600 -#define CORE_MTA_STATIC_BG "cgui\\images\\background.png" -#define CORE_MTA_LOGO "cgui\\images\\background_logo.png" -#define CORE_MTA_FILLER "cgui\\images\\mta_filler.png" -#define CORE_MTA_VERSION "cgui\\images\\version.png" +#define CORE_MTA_STATIC_BG "cgui\\images\\background.png" +#define CORE_MTA_LOGO "cgui\\images\\background_logo.png" +#define CORE_MTA_FILLER "cgui\\images\\mta_filler.png" +#define CORE_MTA_VERSION "cgui\\images\\version.png" static const SColor headlineColors[] = {SColorRGBA(233, 234, 106, 255), SColorRGBA(233 / 6 * 4, 234 / 6 * 4, 106 / 6 * 4, 255), SColorRGBA(233 / 7 * 3, 234 / 7 * 3, 106 / 7 * 3, 255)}; @@ -88,7 +89,7 @@ CMainMenu::CMainMenu(CGUI* pManager) int iBackgroundSizeY; // First let's work out our x and y offsets - if (ScreenSize.fX > ScreenSize.fY) // If the monitor is a normal landscape one + if (ScreenSize.fX > ScreenSize.fY) // If the monitor is a normal landscape one { float iRatioSizeY = ScreenSize.fY / NATIVE_RES_Y; m_iMenuSizeX = NATIVE_RES_X * iRatioSizeY; @@ -100,7 +101,7 @@ CMainMenu::CMainMenu(CGUI* pManager) iBackgroundSizeX = ScreenSize.fX; iBackgroundSizeY = NATIVE_BG_Y * iRatioSizeX; } - else // Otherwise our monitor is in a portrait resolution, so we cant fill the background by y + else // Otherwise our monitor is in a portrait resolution, so we cant fill the background by y { float iRatioSizeX = ScreenSize.fX / NATIVE_RES_X; m_iMenuSizeY = NATIVE_RES_Y * iRatioSizeX; @@ -171,20 +172,27 @@ CMainMenu::CMainMenu(CGUI* pManager) float fBase = 0.613f; float fGap = 0.043f; - // Our disconnect item is shown/hidden dynamically, so we store it seperately + // Our disconnect item is shown/hidden dynamically, so we store it separately m_pDisconnect = CreateItem(MENU_ITEM_DISCONNECT, "menu_disconnect.png", CVector2D(0.168f, fBase + fGap * 0)); m_pDisconnect->image->SetVisible(false); // Create the menu items // Filepath, Relative position, absolute native size // And the font for the graphics is ? - m_menuItems.push_back(CreateItem(MENU_ITEM_QUICK_CONNECT, "menu_quick_connect.png", CVector2D(0.168f, fBase + fGap * 0))); - m_menuItems.push_back(CreateItem(MENU_ITEM_BROWSE_SERVERS, "menu_browse_servers.png", CVector2D(0.168f, fBase + fGap * 1))); - m_menuItems.push_back(CreateItem(MENU_ITEM_HOST_GAME, "menu_host_game.png", CVector2D(0.168f, fBase + fGap * 2))); - m_menuItems.push_back(CreateItem(MENU_ITEM_MAP_EDITOR, "menu_map_editor.png", CVector2D(0.168f, fBase + fGap * 3))); - m_menuItems.push_back(CreateItem(MENU_ITEM_SETTINGS, "menu_settings.png", CVector2D(0.168f, fBase + fGap * 4))); - m_menuItems.push_back(CreateItem(MENU_ITEM_ABOUT, "menu_about.png", CVector2D(0.168f, fBase + fGap * 5))); - m_menuItems.push_back(CreateItem(MENU_ITEM_QUIT, "menu_quit.png", CVector2D(0.168f, fBase + fGap * 6))); + int iMenuItemIndex = 0; + m_menuItems.push_back(CreateItem(MENU_ITEM_QUICK_CONNECT, "menu_quick_connect.png", CVector2D(0.168f, fBase + fGap * iMenuItemIndex++))); + m_menuItems.push_back(CreateItem(MENU_ITEM_BROWSE_SERVERS, "menu_browse_servers.png", CVector2D(0.168f, fBase + fGap * iMenuItemIndex++))); + + // Only add Host Game and Map Editor if server folder and MTA Server.exe exist + if (DirectoryExists(CalcMTASAPath("server"))) + { + m_menuItems.push_back(CreateItem(MENU_ITEM_HOST_GAME, "menu_host_game.png", CVector2D(0.168f, fBase + fGap * iMenuItemIndex++))); + m_menuItems.push_back(CreateItem(MENU_ITEM_MAP_EDITOR, "menu_map_editor.png", CVector2D(0.168f, fBase + fGap * iMenuItemIndex++))); + } + + m_menuItems.push_back(CreateItem(MENU_ITEM_SETTINGS, "menu_settings.png", CVector2D(0.168f, fBase + fGap * iMenuItemIndex++))); + m_menuItems.push_back(CreateItem(MENU_ITEM_ABOUT, "menu_about.png", CVector2D(0.168f, fBase + fGap * iMenuItemIndex++))); + m_menuItems.push_back(CreateItem(MENU_ITEM_QUIT, "menu_quit.png", CVector2D(0.168f, fBase + fGap * iMenuItemIndex++))); // We store the position of the top item, and the second item. These will be useful later float fFirstItemSize = m_menuItems.front()->image->GetSize(false).fY; @@ -194,9 +202,9 @@ CMainMenu::CMainMenu(CGUI* pManager) m_iSecondItemCentre = (m_menuItems[1]->image)->GetPosition().fY + fSecondItemSize * 0.5f; // Store some mouse over bounding box positions - m_menuAX = (0.168f * m_iMenuSizeX) + m_iXOff; // Left side of the items - m_menuAY = m_iFirstItemCentre - fFirstItemSize * (CORE_MTA_HOVER_SCALE / CORE_MTA_NORMAL_SCALE) * 0.5f; // Top side of the items - m_menuBX = m_menuAX + ((390 / NATIVE_RES_X) * m_iMenuSizeX); // Right side of the items. We add the longest picture (browse_servers) + m_menuAX = (0.168f * m_iMenuSizeX) + m_iXOff; // Left side of the items + m_menuAY = m_iFirstItemCentre - fFirstItemSize * (CORE_MTA_HOVER_SCALE / CORE_MTA_NORMAL_SCALE) * 0.5f; // Top side of the items + m_menuBX = m_menuAX + ((390 / NATIVE_RES_X) * m_iMenuSizeX); // Right side of the items. We add the longest picture (browse_servers) m_menuAY += BODGE_FACTOR_1; m_pMenuArea = reinterpret_cast(pManager->CreateStaticImage(m_pCanvas)); @@ -223,7 +231,7 @@ CMainMenu::CMainMenu(CGUI* pManager) float fDrawSizeX = (vecNativeSize.fX / NATIVE_RES_X) * m_iMenuSizeX; float fDrawSizeY = (vecNativeSize.fY / NATIVE_RES_Y) * m_iMenuSizeY; m_pLatestNews->SetSize(CVector2D(fDrawSizeX, fDrawSizeY), false); - float fDrawPosX = 0.83f * m_iMenuSizeX - fDrawSizeX; // Right aligned + float fDrawPosX = 0.83f * m_iMenuSizeX - fDrawSizeX; // Right aligned float fDrawPosY = 0.61f * m_iMenuSizeY; m_pLatestNews->SetPosition(CVector2D(fDrawPosX, fDrawPosY), false); m_pLatestNews->SetVisible(false); @@ -320,7 +328,7 @@ CMainMenu::CMainMenu(CGUI* pManager) // Add feature branch alert m_pFeatureBranchAlertTexture.reset(reinterpret_cast(m_pManager->CreateTexture())); std::int32_t buffer = 0xFFFF0000; - m_pFeatureBranchAlertTexture->LoadFromMemory(&buffer, 1, 1); // HACK: Load red dot + m_pFeatureBranchAlertTexture->LoadFromMemory(&buffer, 1, 1); // HACK: Load red dot m_pFeatureBranchAlertImage.reset(reinterpret_cast(m_pManager->CreateStaticImage(m_pBackground))); m_pFeatureBranchAlertImage->LoadFromTexture(m_pFeatureBranchAlertTexture.get()); @@ -341,7 +349,7 @@ CMainMenu::CMainMenu(CGUI* pManager) // Add annonying alert m_pAlertTexture.reset(reinterpret_cast(m_pManager->CreateTexture())); std::int32_t buffer = 0xFFFF0000; - m_pAlertTexture->LoadFromMemory(&buffer, 1, 1); // HACK: Load red dot + m_pAlertTexture->LoadFromMemory(&buffer, 1, 1); // HACK: Load red dot m_pAlertImage.reset(reinterpret_cast(m_pManager->CreateStaticImage(m_pBackground))); m_pAlertImage->LoadFromTexture(m_pAlertTexture.get()); @@ -358,33 +366,66 @@ CMainMenu::CMainMenu(CGUI* pManager) CMainMenu::~CMainMenu() { - // Destroy GUI items - delete m_pBackground; - delete m_pCanvas; - delete m_pFiller; - delete m_pFiller2; - delete m_pLogo; - delete m_pLatestNews; - delete m_pVersion; - delete m_pMenuArea; - - // Destroy the menu items. Note: The disconnect item isn't always in the - // list of menu items (it's only in there when we're in game). This means we - // don't delete it when we iterate the list and delete it separately - the - // menu item itself still exists even when it's no in the list of menu - // items. Perhaps there should be a separate list of loaded items really. - for (std::deque::iterator it = m_menuItems.begin(); it != m_menuItems.end(); ++it) + auto destroyElement = [this](auto*& element) + { + if (!element) + return; + m_pManager->DestroyElementRecursive(element); + element = nullptr; + }; + + for (uint i = 0; i < CORE_MTA_NEWS_ITEMS; ++i) + { + destroyElement(m_pNewsItemLabels[i]); + destroyElement(m_pNewsItemShadowLabels[i]); + destroyElement(m_pNewsItemDateLabels[i]); + destroyElement(m_pNewsItemNEWLabels[i]); + } + + for (sMenuItem* pItem : m_menuItems) + { + if (!pItem || pItem == m_pDisconnect) + continue; + + if (pItem->image) + { + m_pManager->DestroyElementRecursive(pItem->image); + pItem->image = nullptr; + } + + delete pItem; + } + m_menuItems.clear(); + m_unhoveredItems.clear(); + m_pHoveredItem = nullptr; + + if (m_pDisconnect) { - if ((*it) != m_pDisconnect) + if (m_pDisconnect->image) { - delete (*it)->image; - delete (*it); + m_pManager->DestroyElementRecursive(m_pDisconnect->image); + m_pDisconnect->image = nullptr; } + + delete m_pDisconnect; + m_pDisconnect = nullptr; } - delete m_pDisconnect->image; - delete m_pDisconnect; delete m_pLanguageSelector; + m_pLanguageSelector = nullptr; + + delete m_pNewsBrowser; + m_pNewsBrowser = nullptr; + + destroyElement(m_pMenuArea); + destroyElement(m_pLogo); + destroyElement(m_pLatestNews); + destroyElement(m_pVersion); + + destroyElement(m_pCanvas); + destroyElement(m_pBackground); + destroyElement(m_pFiller); + destroyElement(m_pFiller2); } void CMainMenu::SetMenuVerticalPosition(int iPosY) @@ -412,9 +453,9 @@ void CMainMenu::SetMenuVerticalPosition(int iPosY) m_pMenuArea->SetSize(CVector2D(m_menuBX - m_menuAX, m_menuBY - m_menuAY) + BODGE_FACTOR_6, false); } -void CMainMenu::SetMenuUnhovered() // Dehighlight all our items +void CMainMenu::SetMenuUnhovered() // Dehighlight all our items { - if (m_bIsIngame) // CEGUI hack + if (m_bIsIngame) // CEGUI hack { float fAlpha = m_pDisconnect->image->GetAlpha(); m_pDisconnect->image->SetAlpha(0.35f); @@ -446,8 +487,8 @@ void CMainMenu::Update() } // Get the game interface and the system state - CGame* pGame = CCore::GetSingleton().GetGame(); - SystemState systemState = pGame->GetSystemState(); + CGame* pGame = CCore::GetSingleton().GetGame(); + SystemState systemState = pGame->GetSystemState(); m_Credits.Update(); m_Settings.Update(); @@ -458,7 +499,7 @@ void CMainMenu::Update() if (m_bHideGame) m_pGraphics->DrawRectangle(0, 0, m_ScreenSize.fX, m_ScreenSize.fY, 0xFF000000); - if (m_bIsIngame) // CEGUI hack + if (m_bIsIngame) // CEGUI hack { float fAlpha = m_pDisconnect->image->GetAlpha(); m_pDisconnect->image->SetAlpha(0.35f); @@ -534,8 +575,9 @@ void CMainMenu::Update() while (it != m_unhoveredItems.end()) { // Let's work out what the target progress should be by working out the time passed - // Min of 0.5 progress fixes occasional graphical glitchekal - float newProgress = (*it)->animProgress - std::min(0.5f, ((float)ulTimePassed / CORE_MTA_ANIMATION_TIME_OUT) * (CORE_MTA_HOVER_ALPHA - CORE_MTA_NORMAL_ALPHA)); + // Min of 0.5 progress fixes occasional graphical glitches + float newProgress = + (*it)->animProgress - std::min(0.5f, ((float)ulTimePassed / CORE_MTA_ANIMATION_TIME_OUT) * (CORE_MTA_HOVER_ALPHA - CORE_MTA_NORMAL_ALPHA)); if (SetItemHoverProgress((*it), newProgress, false)) { std::set::iterator itToErase = it++; @@ -570,7 +612,7 @@ void CMainMenu::Update() float fTopItemSize = m_pDisconnect->image->GetSize(false).fY; float fTopItemCentre = m_pDisconnect->image->GetPosition(false).fY + fTopItemSize * 0.5f; - m_menuAY = fTopItemCentre - fTopItemSize * (CORE_MTA_HOVER_SCALE / CORE_MTA_NORMAL_SCALE) * 0.5f; // Top side of the items + m_menuAY = fTopItemCentre - fTopItemSize * (CORE_MTA_HOVER_SCALE / CORE_MTA_NORMAL_SCALE) * 0.5f; // Top side of the items m_menuAY += BODGE_FACTOR_1; m_pMenuArea->SetPosition(CVector2D(m_menuAX - m_iXOff, m_menuAY - m_iYOff) + BODGE_FACTOR_5, false); @@ -594,7 +636,7 @@ void CMainMenu::Update() if (m_fFader > 0.0f) { - m_bIsVisible = true; // Make cursor appear faster + m_bIsVisible = true; // Make cursor appear faster if (!m_bCursorAlphaReset) { @@ -614,7 +656,6 @@ void CMainMenu::Update() m_ucFade = FADE_VISIBLE; m_bIsVisible = true; m_bIsFullyVisible = true; - } } // Fade out @@ -629,10 +670,9 @@ void CMainMenu::Update() if (m_fFader < 1.0f) { - m_bIsVisible = false; // Make cursor disappear faster + m_bIsVisible = false; // Make cursor disappear faster m_bCursorAlphaReset = false; } - // If the fade is complete if (m_fFader <= 0) @@ -674,8 +714,7 @@ void CMainMenu::Update() if (m_bIsVisible && systemState != SystemState::GS_INIT_PLAYING_GAME) { // If we're at the game's mainmenu, or ingame when m_bIsIngame is true show the background - if (systemState == SystemState::GS_FRONTEND || - systemState == SystemState::GS_PLAYING_GAME && !m_bIsIngame) + if (systemState == SystemState::GS_FRONTEND || systemState == SystemState::GS_PLAYING_GAME && !m_bIsIngame) { if (m_ucFade == FADE_INVISIBLE) Show(false); @@ -777,7 +816,7 @@ void CMainMenu::SetIsIngame(bool bIsIngame) m_Settings.SetIsModLoaded(bIsIngame); // Reset frame rate limit - CCore::GetSingleton().RecalculateFrameRateLimit(-1, false); + CCore::GetSingleton().GetFPSLimiter()->Reset(); m_ulMoveStartTick = GetTickCount32(); if (bIsIngame) @@ -848,8 +887,11 @@ bool CMainMenu::OnMenuClick(CGUIMouseEventArgs Args) AskUserIfHeWantsToDisconnect(m_pHoveredItem->menuType); return true; } - + break; + case MENU_ITEM_QUICK_CONNECT: + AskUserIfHeWantsToDisconnect(m_pHoveredItem->menuType); + return true; default: break; } @@ -915,6 +957,7 @@ bool CMainMenu::OnQuickConnectButtonClick(CGUIElement* pElement, bool left) return true; } + g_pCore->GetConnectManager()->SetQuickConnect(true); g_pCore->GetCommands()->Execute("reconnect", ""); } else @@ -1262,6 +1305,9 @@ void CMainMenu::WantsToDisconnectCallBack(void* pData, uint uiButton) case MENU_ITEM_DISCONNECT: OnDisconnectButtonClick(); break; + case MENU_ITEM_QUICK_CONNECT: + OnQuickConnectButtonClick(nullptr, true); + break; default: break; } diff --git a/Client/core/CMainMenu.h b/Client/core/CMainMenu.h index 6c6e93c8ffe..810f568c366 100644 --- a/Client/core/CMainMenu.h +++ b/Client/core/CMainMenu.h @@ -23,7 +23,7 @@ class CMainMenu; class CNewsBrowser; class CLanguageSelector; -#define CORE_MTA_NEWS_ITEMS 3 +#define CORE_MTA_NEWS_ITEMS 3 struct sMenuItem { diff --git a/Client/core/CMemStats.cpp b/Client/core/CMemStats.cpp index edcc59decfa..126e27d187c 100644 --- a/Client/core/CMemStats.cpp +++ b/Client/core/CMemStats.cpp @@ -244,7 +244,7 @@ namespace static SMemStatsInfo* pZeroed = new SMemStatsInfo(); memStats = *pZeroed; } -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -407,7 +407,7 @@ void CMemStats::Draw() /////////////////////////////////////////////////////////////// void CMemStats::UpdateFrameStats() { - m_MemStatsNow.d3dMemory = g_pDeviceState->MemoryState; + m_MemStatsNow.d3dMemory = g_StaticMemoryState; static CProxyDirect3DDevice9::SResourceMemory* const nowList[] = {&m_MemStatsNow.d3dMemory.StaticVertexBuffer, &m_MemStatsNow.d3dMemory.DynamicVertexBuffer, @@ -454,8 +454,8 @@ void CMemStats::SampleState(SMemStatsInfo& memStatsInfo) // // Update 'now' state // - memStatsInfo.d3dMemory = g_pDeviceState->MemoryState; - memStatsInfo.frameStats = g_pDeviceState->FrameStats; + memStatsInfo.d3dMemory = g_StaticMemoryState; + memStatsInfo.frameStats = g_pDeviceState ? g_pDeviceState->FrameStats : CProxyDirect3DDevice9::SFrameStats{}; g_pGraphics->GetRenderItemManager()->GetDxStatus(memStatsInfo.dxStatus); @@ -475,42 +475,47 @@ void CMemStats::SampleState(SMemStatsInfo& memStatsInfo) memStatsInfo.iStreamingMemoryUsed = *(size_t*)0x08E4CB4; memStatsInfo.iStreamingMemoryAvailable = *(size_t*)0x08A5A80; - char* pFileInfoArray = *(char**)(0x5B8B08 + 6); - CGame* pGame = g_pCore->GetGame(); - unsigned int RRR_BASE_ID = pGame->GetBaseIDforRRR(); + char* pFileInfoArray = *(char**)(0x5B8B08 + 6); + CGame* pGame = g_pCore->GetGame(); + const uint baseTxdId = static_cast(pGame->GetBaseIDforTXD()); + const uint baseColId = static_cast(pGame->GetBaseIDforCOL()); + const uint baseIplId = static_cast(pGame->GetBaseIDforIPL()); + const uint baseDatId = static_cast(pGame->GetBaseIDforDAT()); + const uint baseIfpId = static_cast(pGame->GetBaseIDforIFP()); + const uint baseRrrId = static_cast(pGame->GetBaseIDforRRR()); - for (uint i = 0; i < RRR_BASE_ID; i++) + for (uint i = 0; i < baseRrrId; i++) { char* pModelInfo = pFileInfoArray + 20 /* sizeof(CStreamingInfo) */ * i; - char uiLoadedFlag = pModelInfo[0x10]; // CStreamingInfo.uiLoadFlag + char uiLoadedFlag = pModelInfo[0x10]; // CStreamingInfo.uiLoadFlag if (uiLoadedFlag) { memStatsInfo.modelInfo.uiTotal++; - if (i < 313) + if (i < 313u) memStatsInfo.modelInfo.uiPlayerModels_0_312++; - else if (i < 318) + else if (i < 318u) memStatsInfo.modelInfo.uiUnknown_313_317++; - else if (i < 373) + else if (i < 373u) memStatsInfo.modelInfo.uiWeaponModels_318_372++; - else if (i < 400) + else if (i < 400u) memStatsInfo.modelInfo.uiUnknown_373_399++; - else if (i < 612) + else if (i < 612u) memStatsInfo.modelInfo.uiVehicles_400_611++; - else if (i < 1000) + else if (i < 1000u) memStatsInfo.modelInfo.uiUnknown_612_999++; - else if (i < 1194) + else if (i < 1194u) memStatsInfo.modelInfo.uiUpgrades_1000_1193++; - else if (i < pGame->GetBaseIDforTXD()) + else if (i < baseTxdId) memStatsInfo.modelInfo.uiUnknown_1194_19999++; - else if (i < pGame->GetBaseIDforCOL()) + else if (i < baseColId) memStatsInfo.modelInfo.uiTextures_20000_24999++; - else if (i < pGame->GetBaseIDforIPL()) + else if (i < baseIplId) memStatsInfo.modelInfo.uiCollisions_25000_25254++; - else if (i < pGame->GetBaseIDforDAT()) + else if (i < baseDatId) memStatsInfo.modelInfo.uiIpls_25255_25510++; - else if (i < pGame->GetBaseIDforIFP()) + else if (i < baseIfpId) memStatsInfo.modelInfo.uiPaths_25511_25574++; - else if (i < pGame->GetBaseIDforRRR()) + else if (i < baseRrrId) memStatsInfo.modelInfo.uiAnims_25575_25754++; } } @@ -598,7 +603,7 @@ void CMemStats::UpdateIntervalStats() deltaList[i]->iCreatedBytes = nowList[i]->iCreatedBytes - prevList[i]->iCreatedBytes; deltaList[i]->iDestroyedCount = nowList[i]->iDestroyedCount - prevList[i]->iDestroyedCount; deltaList[i]->iDestroyedBytes = nowList[i]->iDestroyedBytes - prevList[i]->iDestroyedBytes; - deltaList[i]->iLockedCount = maxList[i]->iLockedCount; // Use per-frame max for lock stats + deltaList[i]->iLockedCount = maxList[i]->iLockedCount; // Use per-frame max for lock stats } m_MemStatsDelta.rwResourceStats.uiTextures = m_MemStatsNow.rwResourceStats.uiTextures - m_MemStatsPrev.rwResourceStats.uiTextures; @@ -664,27 +669,27 @@ void CMemStats::CreateTables() CGame* pGame = g_pCore->GetGame(); m_TableList.clear(); -// -// Color setups -// - #define YELLOW "#FFFF00" - #define RED "#FF0000" - #define BLUE "#0000FF" - #define WHITE "#FFFFFF" - - #define LT_RED "#FF5050" - #define DK_RED "#CF0000" - #define GREY "#808080" - #define LT_GREY "#C0C0C0" - #define INVIS "#000000" - #define DK_GREEN "#00CF00" - #define LT_GREEN "#30FF30" - #define PURPLE "#FF00FF" - #define CYAN "#00FFFF" - #define LT_CYAN "#00C0F0" - - // Table header - #define HEADER1(text) LT_CYAN text WHITE + // + // Color setups + // +#define YELLOW "#FFFF00" +#define RED "#FF0000" +#define BLUE "#0000FF" +#define WHITE "#FFFFFF" + +#define LT_RED "#FF5050" +#define DK_RED "#CF0000" +#define GREY "#808080" +#define LT_GREY "#C0C0C0" +#define INVIS "#000000" +#define DK_GREEN "#00CF00" +#define LT_GREEN "#30FF30" +#define PURPLE "#FF00FF" +#define CYAN "#00FFFF" +#define LT_CYAN "#00C0F0" + +// Table header +#define HEADER1(text) LT_CYAN text WHITE // Cell colour depending upon the value SString strNumberColorsCreat = GREY "0," CYAN "999999,"; @@ -983,7 +988,7 @@ void CMemStats::CreateTables() int iDefCapacity = g_pCore->GetGame()->GetPools()->GetPoolDefaultCapacity((ePools)i); int iCapacity = g_pCore->GetGame()->GetPools()->GetPoolCapacity((ePools)i); int iUsedSpaces = g_pCore->GetGame()->GetPools()->GetNumberOfUsedSpaces((ePools)i); - int iUsedPercent = iUsedSpaces * 100 / iCapacity; + int iUsedPercent = iCapacity > 0 ? (iUsedSpaces * 100 / iCapacity) : 0; table.AddRow(SString("%s|%d|%d|%d%%", *strName, iCapacity, iUsedSpaces, iUsedPercent)); } } diff --git a/Client/core/CMemStats.h b/Client/core/CMemStats.h index ce0aacc7522..b75851878c6 100644 --- a/Client/core/CMemStats.h +++ b/Client/core/CMemStats.h @@ -8,6 +8,8 @@ * *****************************************************************************/ +#pragma once + struct SModelCacheStats { uint uiMaxNumPedModels; diff --git a/Client/core/CMessageLoopHook.cpp b/Client/core/CMessageLoopHook.cpp index 5935bdb8c2c..bad9a3dbb63 100644 --- a/Client/core/CMessageLoopHook.cpp +++ b/Client/core/CMessageLoopHook.cpp @@ -22,6 +22,8 @@ UCHAR CMessageLoopHook::m_LastScanCode = NULL; BYTE* CMessageLoopHook::m_LastKeyboardState = new BYTE[256]; bool ms_bIgnoreNextEscapeCharacter = false; +#define WM_CUSTOMFOCUS_FIX WM_APP + 1 + CMessageLoopHook::CMessageLoopHook() { WriteDebugEvent("CMessageLoopHook::CMessageLoopHook"); @@ -132,6 +134,17 @@ LRESULT CALLBACK CMessageLoopHook::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM w if (pModManager && pModManager->IsLoaded()) { bool bFocus = (wState == WA_CLICKACTIVE) || (wState == WA_ACTIVE); + + // Fix for the Windows behavior that removes focus from a window if it was minimized during startup + // (you have to double-click the icon or alt+tab to regain focus despite the window being visible). + // GitHub issue #4233 + static bool fixFirstTimeFocus = false; + if (!fixFirstTimeFocus && !bFocus && GetForegroundWindow() != hwnd && GetFocus() == hwnd && !IsIconic(hwnd)) + { + fixFirstTimeFocus = true; + PostMessage(hwnd, WM_CUSTOMFOCUS_FIX, 0, 0); + } + pModManager->GetClient()->OnWindowFocusChange(bFocus); } @@ -150,6 +163,30 @@ LRESULT CALLBACK CMessageLoopHook::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM w } } + // When updating m_bFocused in CClientGame from CPacketHandler (to fix another bug — see the note there), + // the window might not actually have focus at that moment (even though Windows reports it as focused). + // In this case, isMTAWindowFocused returns false even though the window has focus. + // Therefore, we need to intercept the window return operation and manually set the focus in CClientGame. + if (uMsg == WM_WINDOWPOSCHANGING) + { + WINDOWPOS* wp = reinterpret_cast(lParam); + if (wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE && !(wp->flags & SWP_NOZORDER)) + { + if (GetForegroundWindow() == hwnd && !IsIconic(hwnd)) + { + CModManager* pModManager = CModManager::GetSingletonPtr(); + if (pModManager && pModManager->IsLoaded()) + pModManager->GetClient()->OnWindowFocusChange(true); + } + } + } + + if (uMsg == WM_CUSTOMFOCUS_FIX) + { + AllowSetForegroundWindow(ASFW_ANY); + SetForegroundWindow(hwnd); + } + if (uMsg == WM_PAINT) { GetVideoModeManager()->OnPaint(); @@ -211,10 +248,10 @@ LRESULT CALLBACK CMessageLoopHook::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM w // Make sure our pointers are valid. if (pThis != NULL && hwnd == pThis->GetHookedWindowHandle() && g_pCore->AreModulesLoaded()) { - g_pCore->UpdateIsWindowMinimized(); // Force update of stuff + g_pCore->UpdateIsWindowMinimized(); // Force update of stuff if (uMsg == WM_TIMER && wParam == IDT_TIMER1) - g_pCore->WindowsTimerHandler(); // Used for 'minimized before first game' pulses + g_pCore->WindowsTimerHandler(); // Used for 'minimized before first game' pulses // Handle IME if input is not for the GUI if (!g_pCore->GetLocalGUI()->InputGoesToGUI()) @@ -322,7 +359,8 @@ LRESULT CALLBACK CMessageLoopHook::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM w if ((uMsg == WM_KEYDOWN && wParam == VK_TAB)) { SystemState systemState = g_pCore->GetGame()->GetSystemState(); - if (systemState == SystemState::GS_FRONTEND || systemState == SystemState::GS_INIT_PLAYING_GAME || systemState == SystemState::GS_PLAYING_GAME) + if (systemState == SystemState::GS_FRONTEND || systemState == SystemState::GS_INIT_PLAYING_GAME || + systemState == SystemState::GS_PLAYING_GAME) { short sCtrlState = GetKeyState(VK_CONTROL); short sShiftState = GetKeyState(VK_SHIFT); @@ -345,7 +383,8 @@ LRESULT CALLBACK CMessageLoopHook::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM w if ((uMsg == WM_KEYDOWN && (wParam >= VK_1 && wParam <= VK_9))) { SystemState systemState = g_pCore->GetGame()->GetSystemState(); - if (systemState == SystemState::GS_FRONTEND || systemState == SystemState::GS_INIT_PLAYING_GAME || systemState == SystemState::GS_PLAYING_GAME) + if (systemState == SystemState::GS_FRONTEND || systemState == SystemState::GS_INIT_PLAYING_GAME || + systemState == SystemState::GS_PLAYING_GAME) { short sCtrlState = GetKeyState(VK_CONTROL); if (sCtrlState & 0x8000) @@ -369,8 +408,8 @@ LRESULT CALLBACK CMessageLoopHook::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM w if ((uMsg == WM_KEYDOWN && wParam == VK_F8) || (uMsg == WM_CHAR && wParam == '`')) { SystemState systemState = g_pCore->GetGame()->GetSystemState(); - if (CLocalGUI::GetSingleton().IsConsoleVisible() || systemState == SystemState::GS_FRONTEND || systemState == SystemState::GS_INIT_PLAYING_GAME || - systemState == SystemState::GS_PLAYING_GAME) + if (CLocalGUI::GetSingleton().IsConsoleVisible() || systemState == SystemState::GS_FRONTEND || + systemState == SystemState::GS_INIT_PLAYING_GAME || systemState == SystemState::GS_PLAYING_GAME) { CLocalGUI::GetSingleton().SetConsoleVisible(!CLocalGUI::GetSingleton().IsConsoleVisible()); } @@ -494,10 +533,10 @@ LRESULT CALLBACK CMessageLoopHook::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM w if (!GetVideoModeManager()->IsWindowed()) { if (!CLocalGUI::GetSingleton().GetMainMenu() || !CLocalGUI::GetSingleton().GetMainMenu()->HasStarted()) - return true; // No auto-minimize + return true; // No auto-minimize if (GetVideoModeManager()->IsMultiMonitor() && !GetVideoModeManager()->IsMinimizeEnabled()) - return true; // No auto-minimize + return true; // No auto-minimize } } /* @@ -512,7 +551,7 @@ LRESULT CALLBACK CMessageLoopHook::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM w } */ - if (uMsg == WM_SYSCOMMAND && wParam == 0xF012) // SC_DRAGMOVE + if (uMsg == WM_SYSCOMMAND && wParam == 0xF012) // SC_DRAGMOVE { CMessageLoopHook::GetSingleton().StartWindowMovement(); return true; diff --git a/Client/core/CMessageLoopHook.h b/Client/core/CMessageLoopHook.h index d1daafa98da..e8d16690d4b 100644 --- a/Client/core/CMessageLoopHook.h +++ b/Client/core/CMessageLoopHook.h @@ -15,8 +15,8 @@ #include "CSingleton.h" #define URI_CONNECT 1 -#define VK_1 0x30 -#define VK_9 0x39 +#define VK_1 0x30 +#define VK_9 0x39 class CMessageLoopHook : public CSingleton { diff --git a/Client/core/CModManager.cpp b/Client/core/CModManager.cpp index f3ed22bebbd..858b5ea86ef 100644 --- a/Client/core/CModManager.cpp +++ b/Client/core/CModManager.cpp @@ -10,6 +10,7 @@ *****************************************************************************/ #include "StdInc.h" +#include #include "CModManager.h" #define DECLARE_PROFILER_SECTION_CModManager #include "profiler/SharedUtil.Profiler.h" @@ -55,30 +56,39 @@ bool CModManager::TriggerCommand(const char* commandName, size_t commandNameLeng void CModManager::DoPulsePreFrame() { + TIMING_GRAPH("+DoPulsePreFrame"); + CCore::GetSingleton().GetFPSLimiter()->OnFrameStart(); // Prepare FPS limiting for this frame + if (m_client) { m_client->PreFrameExecutionHandler(); } + TIMING_GRAPH("-DoPulsePreFrame"); } void CModManager::DoPulsePreHUDRender(bool bDidUnminimize, bool bDidRecreateRenderTargets) { + TIMING_GRAPH("+DoPulsePreHUDRender"); if (m_client) { m_client->PreHUDRenderExecutionHandler(bDidUnminimize, bDidRecreateRenderTargets); } + TIMING_GRAPH("-DoPulsePreHUDRender"); } void CModManager::DoPulsePostFrame() { - if (m_state == State::PendingStart) - { - Start(); - } - else if (m_state == State::PendingStop) + auto handleStateChange = [&]() { - Stop(); - } + if (m_state == State::PendingStart) + Start(); + else if (m_state == State::PendingStop) + Stop(); + }; + + TIMING_GRAPH("+DoPulsePostFrame"); + + handleStateChange(); // Handle state changes before pulse if (m_client) { @@ -89,20 +99,15 @@ void CModManager::DoPulsePostFrame() CCore::GetSingleton().GetNetwork()->DoPulse(); } - // Make sure frame rate limit gets applied - if (m_client != nullptr) - CCore::GetSingleton().EnsureFrameRateLimitApplied(); // Catch missed frames - else - CCore::GetSingleton().ApplyFrameRateLimit(); // Limit when not connected + CCore::GetSingleton().DoReliablePulse(); // Do reliable pulse - if (m_state == State::PendingStart) - { - Start(); - } - else if (m_state == State::PendingStop) - { - Stop(); - } + handleStateChange(); // Handle state changes after pulse + + // TODO: ENSURE "CModManager::DoPulsePostFrame" IS THE LAST THING BEFORE THE FRAME ENDS + CCore::GetSingleton().GetFPSLimiter()->OnFrameEnd(); // Apply FPS limiting + + TIMING_GRAPH("-DoPulsePostFrame"); + TIMING_GRAPH(""); } bool CModManager::Load(const char* arguments) @@ -182,16 +187,16 @@ bool CModManager::TryStart() return false; } - CClientBase*(__cdecl * InitClient)() = reinterpret_cast(GetProcAddress(library, "InitClient")); - - if (InitClient == nullptr) + using InitClientFn = CClientBase*(__cdecl*)(); + InitClientFn initClient = nullptr; + if (!SharedUtil::TryGetProcAddress(library, "InitClient", initClient)) { CCore::GetSingleton().GetConsole()->Printf("Unable to initialize deathmatch's DLL (missing init)"); FreeLibrary(library); return false; } - CClientBase* client = InitClient(); + CClientBase* client = initClient(); if (client == nullptr || client->ClientInitialize(m_arguments.c_str(), CCore::GetSingletonPtr()) != 0) { diff --git a/Client/core/CModelCacheManager.cpp b/Client/core/CModelCacheManager.cpp index a65df63ffd1..44119c53035 100644 --- a/Client/core/CModelCacheManager.cpp +++ b/Client/core/CModelCacheManager.cpp @@ -9,9 +9,12 @@ #include "StdInc.h" #include +#include +#include #include #include #include +#include #include "CModelCacheManager.h" namespace @@ -25,7 +28,93 @@ namespace bool bIsModelCachedHere; bool bIsModelLoadedByGame; }; -} // namespace + + constexpr uint8_t STREAMING_FLAG_GAME_REQUIRED = 0x2; + constexpr uint8_t STREAMING_FLAG_MISSION_REQUIRED = 0x4; + + constexpr std::uintptr_t VAR_CStreaming_msPedsLoaded = 0x8E4C00; + constexpr std::uintptr_t VAR_CStreaming_msNumPedsLoaded = 0x8E4BB0; + constexpr std::uintptr_t VAR_CStreaming_msVehiclesLoaded = 0x8E4C24; + constexpr std::uintptr_t FUNC_CGame_CanSeeOutsideFromCurrArea = 0x53C4A0; + + constexpr std::size_t PED_STREAMING_SLOT_COUNT = 8u; + constexpr int32_t PED_STREAMING_SLOT_MAX_VALUE = 0xFFFF; + constexpr uint32_t PED_STREAMING_FLOOR = 4u; + constexpr uint32_t VEHICLE_STREAMING_FLOOR_EXTERIOR = 7u; + constexpr uint32_t VEHICLE_STREAMING_FLOOR_INTERIOR = 4u; + constexpr std::size_t VEHICLE_STREAMING_SLOT_COUNT = 23u; + constexpr int16_t VEHICLE_STREAMING_SLOT_UNUSED = -1; + + uint32_t GetNativeNumPedsLoaded() + { + return *reinterpret_cast(VAR_CStreaming_msNumPedsLoaded); + } + + bool IsModelTrackedByNativePedSlots(uint16_t modelId) + { + const auto* slots = reinterpret_cast(VAR_CStreaming_msPedsLoaded); + if (!slots) + return false; + + for (std::size_t idx = 0; idx < PED_STREAMING_SLOT_COUNT; ++idx) + { + const int32_t pedSlot = slots[idx]; + if (pedSlot < 0 || pedSlot > PED_STREAMING_SLOT_MAX_VALUE) + continue; + + if (static_cast(pedSlot) == modelId) + return true; + } + + return false; + } + + uint32_t GetNativeVehicleStreamCount() + { + const auto* slots = reinterpret_cast(VAR_CStreaming_msVehiclesLoaded); + if (!slots) + return 0; + + uint32_t count = 0; + for (std::size_t idx = 0; idx < VEHICLE_STREAMING_SLOT_COUNT; ++idx) + { + if (slots[idx] == VEHICLE_STREAMING_SLOT_UNUSED) + break; + + ++count; + } + + return count; + } + + bool IsModelTrackedByNativeVehicleGroup(uint16_t modelId) + { + const auto* slots = reinterpret_cast(VAR_CStreaming_msVehiclesLoaded); + if (!slots) + return false; + + for (std::size_t idx = 0; idx < VEHICLE_STREAMING_SLOT_COUNT; ++idx) + { + const int16_t slotValue = slots[idx]; + if (slotValue == VEHICLE_STREAMING_SLOT_UNUSED) + break; + + if (slotValue < 0) + continue; + + if (static_cast(slotValue) == modelId) + return true; + } + + return false; + } + + bool NativeCanSeeOutsideFromCurrArea() + { + using Fn = bool(__cdecl*)(); + return reinterpret_cast(FUNC_CGame_CanSeeOutsideFromCurrArea)(); + } +} // namespace /////////////////////////////////////////////////////////////// // @@ -47,7 +136,7 @@ class CModelCacheManagerImpl : public CModelCacheManager virtual void OnClientClose(); virtual void UpdatePedModelCaching(const std::map& newNeedCacheList); virtual void UpdateVehicleModelCaching(const std::map& newNeedCacheList); - virtual void SetCustomLimits(std::optional numVehicles, std::optional numPeds); + virtual void SetCustomLimits(const size_t* numVehicles, const size_t* numPeds); // CModelCacheManagerImpl methods CModelCacheManagerImpl(); @@ -59,16 +148,17 @@ class CModelCacheManagerImpl : public CModelCacheManager int GetModelRefCount(ushort usModelId); void AddModelRefCount(ushort usModelId); void SubModelRefCount(ushort usModelId); + bool TryReleaseCachedModel(ushort usModelId, SModelCacheInfo& info, const char* contextTag, uint& uiNumModelsCachedHereOnly); protected: - CGame* m_pGame{}; - int m_iFrameCounter{}; - CTickCount m_TickCountNow{}; - bool m_bDonePreLoad{}; - uint m_uiMaxCachedPedModels{}; - bool m_IsUsingCustomPedCacheLimit{}; //< If `true` the value is set by the scripter, otherwise is calculated in `DoPulse()` - uint m_uiMaxCachedVehicleModels{}; - bool m_IsUsingCustomVehicleCacheLimit{}; //< If `true` the value is set by the scripter, otherwise is calculated in `DoPulse()` + CGame* m_pGame{}; + int m_iFrameCounter{}; + CTickCount m_TickCountNow{}; + bool m_bDonePreLoad{}; + uint m_uiMaxCachedPedModels{}; + bool m_IsUsingCustomPedCacheLimit{}; //< If `true` the value is set by the scripter, otherwise is calculated in `DoPulse()` + uint m_uiMaxCachedVehicleModels{}; + bool m_IsUsingCustomVehicleCacheLimit{}; //< If `true` the value is set by the scripter, otherwise is calculated in `DoPulse()` std::map m_PedModelCacheInfoMap{}; std::map m_VehicleModelCacheInfoMap{}; }; @@ -173,14 +263,16 @@ void CModelCacheManagerImpl::PreLoad() // PreLoad upgrades WatchDogBeginSection(WD_SECTION_PRELOAD_UPGRADES); { - for (int i = 1000; i < iLowestUnsafeUpgrade; i++) + const int iEndModelId = std::min(iLowestUnsafeUpgrade, 0x10000); + for (int i = 1000; i < iEndModelId; i++) { if (bSlowMethod) SetApplicationSettingInt(DIAG_PRELOAD_UPGRADE_ATTEMPT_ID, i); - AddModelRefCount(i); + AddModelRefCount(static_cast(i)); if (bSlowMethod) m_pGame->GetStreaming()->LoadAllRequestedModels(false); } + m_pGame->GetStreaming()->LoadAllRequestedModels(false); } WatchDogCompletedSection(WD_SECTION_PRELOAD_UPGRADES); @@ -222,15 +314,18 @@ void CModelCacheManagerImpl::GetStats(SModelCacheStats& outStats) // CModelCacheManagerImpl::SetCustomLimits // // Function to set custom limits, instead of calculating them automatically. -// If the optional is empty, the value is restored to the automatic one -// otherwise it is set to whatever value the opt contains -// +// If the pointer is nullptr, the value is restored to the automatic one +// otherwise it is set to whatever value the pointer points to +// /////////////////////////////////////////////////////////////// -void CModelCacheManagerImpl::SetCustomLimits(std::optional numVehicles, std::optional numPeds) { - if (m_IsUsingCustomPedCacheLimit = numPeds.has_value()) { +void CModelCacheManagerImpl::SetCustomLimits(const size_t* numVehicles, const size_t* numPeds) +{ + if (m_IsUsingCustomPedCacheLimit = (numPeds != nullptr)) + { m_uiMaxCachedPedModels = *numPeds; } - if (m_IsUsingCustomVehicleCacheLimit = numVehicles.has_value()) { + if (m_IsUsingCustomVehicleCacheLimit = (numVehicles != nullptr)) + { m_uiMaxCachedVehicleModels = *numVehicles; } } @@ -254,11 +349,13 @@ void CModelCacheManagerImpl::DoPulse() // 256MB streaming = 16+8 MB for peds & vehicles 72 peds + 56 veh // const auto iStreamingMemoryAvailableKB = *(int*)0x08A5A80; - if (!m_IsUsingCustomPedCacheLimit) { - SSamplePoint pedPoints[] = { {65536, 9}, {98304, 18}, {131072, 36}, {262144, 72} }; + if (!m_IsUsingCustomPedCacheLimit) + { + SSamplePoint pedPoints[] = {{65536, 9}, {98304, 18}, {131072, 36}, {262144, 72}}; m_uiMaxCachedPedModels = (int)EvalSamplePosition(pedPoints, NUMELMS(pedPoints), (float)iStreamingMemoryAvailableKB); } - if (!m_IsUsingCustomVehicleCacheLimit) { + if (!m_IsUsingCustomVehicleCacheLimit) + { SSamplePoint vehPoints[] = {{65536, 7}, {98304, 28}, {131072, 56}, {262144, 56}}; m_uiMaxCachedVehicleModels = (int)EvalSamplePosition(vehPoints, NUMELMS(vehPoints), (float)iStreamingMemoryAvailableKB); } @@ -396,31 +493,30 @@ void CModelCacheManagerImpl::UpdateModelCaching(const std::map& n } // If at or above cache limit, try to uncache unneeded first - if (uiNumModelsCachedHereOnly >= uiMaxCachedAllowed && !maybeUncacheUnneededList.empty()) - { - const ushort usModelId = maybeUncacheUnneededList.rbegin()->second; - SModelCacheInfo* pInfo = MapFind(currentCacheInfoMap, usModelId); - assert(pInfo); - assert(pInfo->bIsModelCachedHere); - SubModelRefCount(usModelId); - pInfo->bIsModelCachedHere = false; - MapRemove(currentCacheInfoMap, usModelId); - OutputDebugLine(SString("[Cache] End caching model %d (UncacheUnneeded)", usModelId)); - } - else if (uiNumModelsCachedHereOnly > uiMaxCachedAllowed && !maybeUncacheNeededList.empty()) + bool bReleasedModel = false; + auto AttemptReleaseFromList = [&](const std::map& candidateList, const char* contextTag) -> bool { - // Only uncache from the needed list if above limit + for (auto it = candidateList.rbegin(); it != candidateList.rend(); ++it) + { + const ushort modelId = it->second; + auto cacheIt = currentCacheInfoMap.find(modelId); + if (cacheIt == currentCacheInfoMap.end()) + continue; - // Uncache furthest away model - const ushort usModelId = maybeUncacheNeededList.rbegin()->second; - SModelCacheInfo* pInfo = MapFind(currentCacheInfoMap, usModelId); - assert(pInfo); - assert(pInfo->bIsModelCachedHere); - SubModelRefCount(usModelId); - pInfo->bIsModelCachedHere = false; - MapRemove(currentCacheInfoMap, usModelId); - OutputDebugLine(SString("[Cache] End caching model %d (UncacheNeeded)", usModelId)); - } + SModelCacheInfo& candidateInfo = cacheIt->second; + assert(candidateInfo.bIsModelCachedHere); + + if (TryReleaseCachedModel(modelId, candidateInfo, contextTag, uiNumModelsCachedHereOnly)) + return true; + } + return false; + }; + + if (uiNumModelsCachedHereOnly >= uiMaxCachedAllowed && !maybeUncacheUnneededList.empty()) + bReleasedModel = AttemptReleaseFromList(maybeUncacheUnneededList, "UncacheUnneeded"); + + if (!bReleasedModel && uiNumModelsCachedHereOnly > uiMaxCachedAllowed && !maybeUncacheNeededList.empty()) + bReleasedModel = AttemptReleaseFromList(maybeUncacheNeededList, "UncacheNeeded"); // Cache if room if (!maybeCacheList.empty() && uiNumModelsCachedHereOnly < uiMaxCachedAllowed) @@ -507,6 +603,7 @@ bool CModelCacheManagerImpl::UnloadModel(ushort usModelId) /////////////////////////////////////////////////////////////// void CModelCacheManagerImpl::OnRestreamModel(ushort usModelId) { + // Keep forced restream untouched: callers expect full removal when restreaming. std::map* mapList[] = {&m_PedModelCacheInfoMap, &m_VehicleModelCacheInfoMap}; for (uint i = 0; i < NUMELMS(mapList); i++) @@ -524,5 +621,81 @@ void CModelCacheManagerImpl::OnRestreamModel(ushort usModelId) OutputDebugLine(SString("[Cache] End caching model %d (OnRestreamModel)", usModelId)); } } - } + } +} + +/////////////////////////////////////////////////////////////// +// +// CModelCacheManagerImpl::TryReleaseCachedModel +// +/////////////////////////////////////////////////////////////// +bool CModelCacheManagerImpl::TryReleaseCachedModel(ushort usModelId, SModelCacheInfo& info, const char* contextTag, uint& uiNumModelsCachedHereOnly) +{ + assert(info.bIsModelCachedHere); + + CStreaming* pStreaming = m_pGame->GetStreaming(); + if (!pStreaming) + { + return false; + } + + CStreamingInfo* pStreamingInfo = pStreaming->GetStreamingInfo(usModelId); + if (!pStreamingInfo) + { + return false; + } + + if (pStreamingInfo->flg & STREAMING_FLAG_MISSION_REQUIRED) + { + return false; + } + + if (pStreamingInfo->flg & STREAMING_FLAG_GAME_REQUIRED) + { + return false; + } + + const int iRefCount = GetModelRefCount(usModelId); + if (iRefCount > 1) + { + return false; + } + + CModelInfo* pModelInfo = m_pGame->GetModelInfo(usModelId, true); + const eModelInfoType modelType = pModelInfo ? pModelInfo->GetModelType() : eModelInfoType::UNKNOWN; + const bool bIsPedModel = modelType == eModelInfoType::PED; + const bool bIsVehicleModel = modelType == eModelInfoType::VEHICLE; + + const bool bTrackedByNativePedSlots = bIsPedModel && IsModelTrackedByNativePedSlots(usModelId); + const bool bTrackedByNativeVehicleGroup = bIsVehicleModel && IsModelTrackedByNativeVehicleGroup(usModelId); + + if (bTrackedByNativePedSlots) + { + if (GetNativeNumPedsLoaded() <= PED_STREAMING_FLOOR) + { + return false; + } + } + + if (bTrackedByNativeVehicleGroup) + { + const uint32_t vehicleCount = GetNativeVehicleStreamCount(); + const bool bIsInterior = m_pGame->GetWorld() && m_pGame->GetWorld()->GetCurrentArea() != 0; + const bool bTreatAsInterior = bIsInterior || !NativeCanSeeOutsideFromCurrArea(); + const uint32_t minVehicleBudget = bTreatAsInterior ? VEHICLE_STREAMING_FLOOR_INTERIOR : VEHICLE_STREAMING_FLOOR_EXTERIOR; + if (vehicleCount <= minVehicleBudget) + { + return false; + } + } + + SubModelRefCount(usModelId); + info.bIsModelCachedHere = false; + info.lastNeeded = m_TickCountNow; + info.bIsModelLoadedByGame = false; + + if (uiNumModelsCachedHereOnly > 0) + uiNumModelsCachedHereOnly--; + + return true; } diff --git a/Client/core/CModelCacheManager.h b/Client/core/CModelCacheManager.h index 978ee518ae1..7963b7db426 100644 --- a/Client/core/CModelCacheManager.h +++ b/Client/core/CModelCacheManager.h @@ -7,7 +7,9 @@ * *****************************************************************************/ -#include +#pragma once + +#include struct SModelCacheStats; @@ -24,7 +26,7 @@ class CModelCacheManager virtual void OnClientClose() = 0; virtual void UpdatePedModelCaching(const std::map& newNeedCacheList) = 0; virtual void UpdateVehicleModelCaching(const std::map& newNeedCacheList) = 0; - virtual void SetCustomLimits(std::optional numVehicles, std::optional numPeds) = 0; + virtual void SetCustomLimits(const size_t* numVehicles, const size_t* numPeds) = 0; }; CModelCacheManager* NewModelCacheManager(); diff --git a/Client/core/CModuleLoader.cpp b/Client/core/CModuleLoader.cpp index 0b2e4e007f5..4659be32007 100644 --- a/Client/core/CModuleLoader.cpp +++ b/Client/core/CModuleLoader.cpp @@ -10,6 +10,7 @@ *****************************************************************************/ #include "StdInc.h" +#include using std::string; @@ -62,14 +63,14 @@ PVOID CModuleLoader::GetFunctionPointer(const string& FunctionName) { if (m_bStatus) { - FARPROC fpProcAddr; - - fpProcAddr = GetProcAddress(m_hLoadedModule, FunctionName.c_str()); + FARPROC fpProcAddr = nullptr; + if (!SharedUtil::TryGetProcAddress(m_hLoadedModule, FunctionName.c_str(), fpProcAddr)) + return nullptr; return static_cast(fpProcAddr); } else - return NULL; + return nullptr; } const SString& CModuleLoader::GetLastErrorMessage() const diff --git a/Client/core/CMouseControl.cpp b/Client/core/CMouseControl.cpp index 2e772c185cb..acf6ace4b61 100644 --- a/Client/core/CMouseControl.cpp +++ b/Client/core/CMouseControl.cpp @@ -19,7 +19,7 @@ #include #include -#define MOUSE_CONTROL_MULTIPLIER 35 +#define MOUSE_CONTROL_MULTIPLIER 35 extern CCore* g_pCore; @@ -75,11 +75,11 @@ bool CMouseControl::ProcessMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam) bool bVar; CVARS_GET("fly_with_mouse", bVar); - if (pModelInfo->IsPlane() || pModelInfo->IsHeli() && !bVar) // Are we in a plane, but not have mouse flight enabled? + if (pModelInfo->IsPlane() || pModelInfo->IsHeli() && !bVar) // Are we in a plane, but not have mouse flight enabled? return false; CVARS_GET("steer_with_mouse", bVar); - if (!bVar) // Are we in another type of vehicle, but not have mouse steering enabled? + if (!bVar) // Are we in another type of vehicle, but not have mouse steering enabled? return false; // Let's calculate our mouse movement directions diff --git a/Client/core/CNewsBrowser.cpp b/Client/core/CNewsBrowser.cpp index 9b76fbc4628..032d3fb06d0 100644 --- a/Client/core/CNewsBrowser.cpp +++ b/Client/core/CNewsBrowser.cpp @@ -26,6 +26,7 @@ CNewsBrowser::CNewsBrowser() m_pWindow = NULL; m_pTabPanel = NULL; m_pButtonOK = NULL; + m_pButtonNewsLink = NULL; } //////////////////////////////////////////////////// @@ -66,9 +67,9 @@ void CNewsBrowser::InitNewsItemList() { SString strItemDir = directoryList[directoryList.size() - 1 - i]; if (strItemDir < strOldestPost) - continue; // Post too old + continue; // Post too old if (m_NewsitemList.size() >= uiMaxHistoryLength) - continue; // Post count too high + continue; // Post count too high SNewsItem newsItem; newsItem.strContentFullDir = PathJoin(strAllNewsDir, strItemDir); @@ -199,31 +200,18 @@ void CNewsBrowser::CreateGUI() //////////////////////////////////////////////////// void CNewsBrowser::DestroyGUI() { - // Destroy - for (uint i = 0; i < m_TabList.size(); i++) - { - CGUITab* pTab = m_TabList[i]; - if (pTab) - delete pTab; - } - m_TabList.clear(); - for (uint i = 0; i < m_TabContentList.size(); i++) - { - CGUIWindow* pWindow = m_TabContentList[i]; - if (pWindow) - { - CGUIElement* m_pScrollPane = pWindow->GetParent(); - if (m_pScrollPane) - { - delete m_pScrollPane; - } - delete pWindow; - } - } - m_TabContentList.clear(); - SAFE_DELETE(m_pTabPanel); + if (!m_pWindow && !m_pTabPanel && !m_pButtonOK && !m_pButtonNewsLink) + return; + + // Clean up the main UI elements in reverse order of creation + SAFE_DELETE(m_pTabPanel); // This will destroy all tabs and their children SAFE_DELETE(m_pButtonOK); + SAFE_DELETE(m_pButtonNewsLink); SAFE_DELETE(m_pWindow); + + // Clear the lists after the GUI objects are destroyed + m_TabList.clear(); + m_TabContentList.clear(); } //////////////////////////////////////////////////// diff --git a/Client/core/CNickGen.h b/Client/core/CNickGen.h index 86a36990728..8ccb853405e 100644 --- a/Client/core/CNickGen.h +++ b/Client/core/CNickGen.h @@ -12,5 +12,5 @@ class CNickGen { public: - static SString GetRandomNickname(); + static SString GetRandomNickname(); }; diff --git a/Client/core/CQueryReceiver.cpp b/Client/core/CQueryReceiver.cpp index 4a20c643b33..5c791179fac 100644 --- a/Client/core/CQueryReceiver.cpp +++ b/Client/core/CQueryReceiver.cpp @@ -22,11 +22,11 @@ CQueryReceiver::~CQueryReceiver() void CQueryReceiver::RequestQuery(in_addr address, ushort port) { - if (m_Socket == INVALID_SOCKET) // Create the socket + if (m_Socket == INVALID_SOCKET) // Create the socket { m_Socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); u_long flag = 1; - ioctlsocket(m_Socket, FIONBIO, &flag); // Nonblocking I/O + ioctlsocket(m_Socket, FIONBIO, &flag); // Nonblocking I/O } sockaddr_in addr; @@ -88,7 +88,7 @@ SQueryInfo CQueryReceiver::GetServerResponse() SQueryInfo info; if (m_Socket == INVALID_SOCKET) - return info; // Query not sent + return info; // Query not sent char szBuffer[SERVER_LIST_QUERY_BUFFER] = {0}; @@ -162,8 +162,14 @@ SQueryInfo CQueryReceiver::GetServerResponse() SString strJoinedPlayers, strMaxPlayers; if (strPlayerCount.Split("/", &strJoinedPlayers, &strMaxPlayers)) { - info.players = atoi(strJoinedPlayers); - info.playerSlot = atoi(strMaxPlayers); + const int joinedPlayers = atoi(strJoinedPlayers); + const int maxPlayers = atoi(strMaxPlayers); + + if (joinedPlayers >= 0 && joinedPlayers <= 0xFFFF) + info.players = static_cast(joinedPlayers); + + if (maxPlayers >= 0 && maxPlayers <= 0xFFFF) + info.playerSlot = static_cast(maxPlayers); } } @@ -190,7 +196,11 @@ SQueryInfo CQueryReceiver::GetServerResponse() const SString strUpTime = strNetRoute.Right(strNetRoute.length() - strlen(strNetRoute) - 1); const SString strHttpPort = strUpTime.Right(strUpTime.length() - strlen(strUpTime) - 1); if (!strHttpPort.empty()) - info.httpPort = atoi(strHttpPort); + { + const int httpPort = atoi(strHttpPort); + if (httpPort >= 0 && httpPort <= 0xFFFF) + info.httpPort = static_cast(httpPort); + } // Get player nicks while (i < len) diff --git a/Client/core/CQuestionBox.cpp b/Client/core/CQuestionBox.cpp index 5b8bf46b661..7a6dbf78889 100644 --- a/Client/core/CQuestionBox.cpp +++ b/Client/core/CQuestionBox.cpp @@ -217,7 +217,7 @@ bool CQuestionBox::OnButtonClick(CGUIElement* pElement) if (m_Callback) m_Callback(m_CallbackParameter, m_uiLastButton); - if (m_CallbackEdit && !m_EditList.empty()) // Just grab the first editbox for now + if (m_CallbackEdit && !m_EditList.empty()) // Just grab the first editbox for now m_CallbackEdit(m_CallbackParameter, m_uiLastButton, m_EditList[0]->GetText()); return true; } diff --git a/Client/core/CScreenGrabber.cpp b/Client/core/CScreenGrabber.cpp index b8c6bd08269..70e34cfa9f6 100644 --- a/Client/core/CScreenGrabber.cpp +++ b/Client/core/CScreenGrabber.cpp @@ -9,6 +9,7 @@ #include "StdInc.h" #include "CCompressorJobQueue.h" +#include "DXHook/CProxyDirect3DDevice9.h" struct SScreenShotQueueItem { @@ -242,6 +243,7 @@ bool CScreenGrabber::GetBackBufferPixels(uint uiSizeX, uint uiSizeY, CBuffer& bu if (!m_pScreenShotTemp) { strOutError = "No ScreenShotTemp"; + SAFE_RELEASE(pD3DBackBufferSurface); return false; } @@ -251,6 +253,7 @@ bool CScreenGrabber::GetBackBufferPixels(uint uiSizeX, uint uiSizeY, CBuffer& bu if (FAILED(hr)) { strOutError = SString("StretchRect failed (0x%08x)", hr); + SAFE_RELEASE(pD3DBackBufferSurface); return false; } @@ -260,6 +263,7 @@ bool CScreenGrabber::GetBackBufferPixels(uint uiSizeX, uint uiSizeY, CBuffer& bu if (!m_pScreenShotTemp->ReadPixels(buffer, strOutError)) { dassert(!strOutError.empty()); + SAFE_RELEASE(pD3DBackBufferSurface); return false; } diff --git a/Client/core/CScreenShot.cpp b/Client/core/CScreenShot.cpp index 48264614319..96d260a4d97 100644 --- a/Client/core/CScreenShot.cpp +++ b/Client/core/CScreenShot.cpp @@ -10,6 +10,8 @@ *****************************************************************************/ #include "StdInc.h" +#include "DXHook/CProxyDirect3DDevice9.h" +#include #include extern CCore* g_pCore; @@ -38,6 +40,86 @@ static uint ms_uiHeight = 0; // whether we want to actually save photo in documents folder static bool savePhotoInDocuments = false; +namespace +{ + float Clamp(float value, float minValue, float maxValue) + { + if (value < minValue) + return minValue; + if (value > maxValue) + return maxValue; + return value; + } + + void ApplyBorderlessAdjustmentsToBuffer(void* rawData, uint width, uint height) + { + if (!rawData || width == 0 || height == 0) + return; + + bool isBorderless = false; + if (CVideoModeManagerInterface* videoModeManager = GetVideoModeManager()) + isBorderless = videoModeManager->IsDisplayModeWindowed() || videoModeManager->IsDisplayModeFullScreenWindow(); + + if (!isBorderless && ::g_pDeviceState) + isBorderless = (::g_pDeviceState->CreationState.PresentationParameters.Windowed != 0); + + float gammaPower = 1.0f; + float brightnessScale = 1.0f; + float contrastScale = 1.0f; + float saturationScale = 1.0f; + bool applyWindowed = true; + bool applyFullscreen = false; + ::BorderlessGamma::FetchSettings(gammaPower, brightnessScale, contrastScale, saturationScale, applyWindowed, applyFullscreen); + + const bool adjustmentsEnabled = isBorderless ? applyWindowed : applyFullscreen; + if (!adjustmentsEnabled) + return; + + if (!::BorderlessGamma::ShouldApplyAdjustments(gammaPower, brightnessScale, contrastScale, saturationScale)) + return; + + BYTE* data = static_cast(rawData); + const size_t pixelCount = static_cast(width) * static_cast(height); + const float inv255 = 1.0f / 255.0f; + const float contrastPivot = 0.5f; + + for (size_t i = 0; i < pixelCount; ++i) + { + float r = Clamp(data[0] * inv255, 0.0f, 1.0f); + float g = Clamp(data[1] * inv255, 0.0f, 1.0f); + float b = Clamp(data[2] * inv255, 0.0f, 1.0f); + + r = powf(r, gammaPower); + g = powf(g, gammaPower); + b = powf(b, gammaPower); + + r *= brightnessScale; + g *= brightnessScale; + b *= brightnessScale; + + r = (r - contrastPivot) * contrastScale + contrastPivot; + g = (g - contrastPivot) * contrastScale + contrastPivot; + b = (b - contrastPivot) * contrastScale + contrastPivot; + + float luminance = Clamp(0.299f * r + 0.587f * g + 0.114f * b, 0.0f, 1.0f); + + r = luminance + (r - luminance) * saturationScale; + g = luminance + (g - luminance) * saturationScale; + b = luminance + (b - luminance) * saturationScale; + + r = Clamp(r, 0.0f, 1.0f); + g = Clamp(g, 0.0f, 1.0f); + b = Clamp(b, 0.0f, 1.0f); + + data[0] = static_cast(r * 255.0f + 0.5f); + data[1] = static_cast(g * 255.0f + 0.5f); + data[2] = static_cast(b * 255.0f + 0.5f); + + data += 4; + } + } +} // namespace + void CScreenShot::InitiateScreenShot(bool bIsCameraShot) { if (ms_bScreenShot || ms_bIsSaving || IsRateLimited(bIsCameraShot)) @@ -109,6 +191,7 @@ void CScreenShot::CheckForScreenShot(bool bBeforeGUI) if (uiDataSize == uiReqDataSize) { + ApplyBorderlessAdjustmentsToBuffer(ms_ScreenShotBuffer.GetData(), ms_uiWidth, ms_uiHeight); // Start the save thread StartSaveThread(); } @@ -128,7 +211,7 @@ void CScreenShot::CheckForScreenShot(bool bBeforeGUI) } // Callback for threaded save -DWORD CScreenShot::ThreadProc(LPVOID lpdwThreadParam) +DWORD WINAPI CScreenShot::ThreadProc(LPVOID lpdwThreadParam) { uint uiLinePitch = ms_uiWidth * 4; void* pData = ms_ScreenShotBuffer.GetData(); @@ -141,8 +224,8 @@ DWORD CScreenShot::ThreadProc(LPVOID lpdwThreadParam) ppScreenData[y] = new BYTE[ms_uiWidth * 4]; } - // Copy the surface data into a row-based buffer for libpng - #define BYTESPERPIXEL 4 +// Copy the surface data into a row-based buffer for libpng +#define BYTESPERPIXEL 4 unsigned long ulLineWidth = ms_uiWidth * 4; for (unsigned int i = 0; i < ms_uiHeight; i++) { @@ -194,7 +277,7 @@ DWORD CScreenShot::ThreadProc(LPVOID lpdwThreadParam) void CScreenShot::StartSaveThread() { - HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc, NULL, CREATE_SUSPENDED, NULL); + HANDLE hThread = CreateThread(NULL, 0, &CScreenShot::ThreadProc, NULL, CREATE_SUSPENDED, NULL); if (!hThread) { CCore::GetSingleton().GetConsole()->Printf("Could not create screenshot thread."); diff --git a/Client/core/CScreenShot.h b/Client/core/CScreenShot.h index 5474fbeb571..2cc9f4ecec6 100644 --- a/Client/core/CScreenShot.h +++ b/Client/core/CScreenShot.h @@ -22,9 +22,9 @@ class CScreenShot static void SetPhotoSavingInsideDocuments(bool bSavePhoto) noexcept; protected: - static void StartSaveThread(); - static void ClearBuffer(); - static SString GetScreenshotPath(); - static bool IsRateLimited(bool bIsCameraShot); - static DWORD ThreadProc(LPVOID lpdwThreadParam); + static void StartSaveThread(); + static void ClearBuffer(); + static SString GetScreenshotPath(); + static bool IsRateLimited(bool bIsCameraShot); + static DWORD WINAPI ThreadProc(LPVOID lpdwThreadParam); }; diff --git a/Client/core/CSettings.cpp b/Client/core/CSettings.cpp index 159c4f8502d..6ddf6477052 100644 --- a/Client/core/CSettings.cpp +++ b/Client/core/CSettings.cpp @@ -10,31 +10,430 @@ *****************************************************************************/ #include "StdInc.h" +#include +#include #include #include #include #include "CSteamClient.h" +#include "DXHook/CProxyDirect3DDevice9.h" using namespace std; -#define CORE_MTA_FILLER "cgui\\images\\mta_filler.png" -#define CORE_SETTINGS_UPDATE_INTERVAL 30 // Settings update interval in frames -#define CORE_SETTINGS_HEADERS 3 -#define CORE_SETTINGS_HEADER_SPACER " " -#define CORE_SETTINGS_NO_KEY " " +#define CORE_MTA_FILLER "cgui\\images\\mta_filler.png" +#define CORE_SETTINGS_UPDATE_INTERVAL 30 // Settings update interval in frames +#define CORE_SETTINGS_HEADERS 3 +#define CORE_SETTINGS_HEADER_SPACER " " +#define CORE_SETTINGS_NO_KEY " " extern CCore* g_pCore; extern SBindableGTAControl g_bcControls[]; extern SBindableKey g_bkKeys[]; +namespace +{ + constexpr float kBorderlessGammaMin = 0.5f; + constexpr float kBorderlessGammaMax = 2.0f; + constexpr float kBorderlessGammaDefault = 0.95f; + constexpr float kBorderlessBrightnessMin = 0.5f; + constexpr float kBorderlessBrightnessMax = 2.0f; + constexpr float kBorderlessBrightnessDefault = 1.03f; + constexpr float kBorderlessContrastMin = 0.5f; + constexpr float kBorderlessContrastMax = 2.0f; + constexpr float kBorderlessContrastDefault = 1.0f; + constexpr float kBorderlessSaturationMin = 0.5f; + constexpr float kBorderlessSaturationMax = 2.0f; + constexpr float kBorderlessSaturationDefault = 1.0f; + + constexpr float kSettingsContentWidth = 680.0f; + constexpr float kSettingsBaseContentHeight = 480.0f; + constexpr float kSettingsWindowFrameHorizontal = 18.0f; // 9px left + 9px right + constexpr float kSettingsWindowFrameVertical = 22.0f; // 20px top + 2px bottom + constexpr float kSettingsBottomButtonAreaHeight = 38.0f; + constexpr float kPostFxCheckboxOffset = 24.0f; + constexpr float kSettingsTabHorizontalPadding = 20.0f; + constexpr float kSliderValueReserve = 80.0f; + constexpr float kSettingsSliderExtraAllowance = 0.0f; + constexpr float kSettingsSliderMinWidth = 32.0f; + constexpr float kSliderLabelSpacing = 6.0f; + constexpr float kSliderLeftSpacing = 6.0f; + constexpr float kBrowserColumnSpacing = 18.0f; + constexpr float kBrowserColumnMinWidth = 240.0f; + + float NormalizeSliderValue(float value, float minValue, float maxValue) + { + if (maxValue <= minValue) + return 0.0f; + return std::clamp((value - minValue) / (maxValue - minValue), 0.0f, 1.0f); + } + + float DenormalizeSliderValue(float position, float minValue, float maxValue) + { + position = std::clamp(position, 0.0f, 1.0f); + return minValue + position * (maxValue - minValue); + } + + float ComputeSliderWidth(float tabWidth, float sliderX, float preferredWidth, float reservedWidth = kSliderValueReserve) + { + const float totalAvailable = std::max(0.0f, tabWidth - sliderX); + if (totalAvailable <= 0.0f) + { + return 0.0f; + } + + const float clampedReserve = std::clamp(reservedWidth, 0.0f, totalAvailable); + const float spaceForSlider = totalAvailable - clampedReserve; + + float width = 0.0f; + if (spaceForSlider >= preferredWidth) + { + width = std::min(spaceForSlider, preferredWidth + kSettingsSliderExtraAllowance); + } + else if (spaceForSlider > 0.0f) + { + width = spaceForSlider; + } + else + { + width = std::min(preferredWidth, totalAvailable); + } + + if (width > 0.0f && width < kSettingsSliderMinWidth) + width = std::min(std::max(width, kSettingsSliderMinWidth), totalAvailable); + + return width; + } + + void FinalizeSliderRow(float tabWidth, CGUIScrollBar* slider, CGUILabel* valueLabel, float preferredWidth, float labelSpacing = kSliderLabelSpacing, + CGUILabel* textLabel = nullptr) + { + if (!slider) + return; + + CVector2D sliderPos; + slider->GetPosition(sliderPos); + + if (textLabel) + { + CVector2D textPos; + textLabel->GetPosition(textPos); + CVector2D textSize; + textLabel->GetSize(textSize); + const float minSliderX = textPos.fX + textSize.fX + kSliderLeftSpacing; + if (sliderPos.fX < minSliderX) + { + sliderPos.fX = minSliderX; + slider->SetPosition(CVector2D(sliderPos.fX, sliderPos.fY)); + } + } + + float reservedWidth = 0.0f; + CVector2D labelSize; + if (valueLabel) + { + valueLabel->GetSize(labelSize); + reservedWidth = std::max(0.0f, labelSize.fX + labelSpacing); + } + else + { + reservedWidth = std::max(0.0f, labelSpacing); + } + + const float maxSliderStart = std::max(0.0f, tabWidth - reservedWidth - kSettingsSliderMinWidth); + if (sliderPos.fX > maxSliderStart) + { + sliderPos.fX = maxSliderStart; + slider->SetPosition(CVector2D(sliderPos.fX, sliderPos.fY)); + } + + float targetWidth = ComputeSliderWidth(tabWidth, sliderPos.fX, preferredWidth, reservedWidth); + if (targetWidth <= 0.0f) + targetWidth = std::max(0.0f, tabWidth - sliderPos.fX - reservedWidth); + + CVector2D sliderSize; + slider->GetSize(sliderSize); + if (sliderSize.fY <= 0.0f) + sliderSize.fY = 20.0f; + sliderSize.fX = targetWidth; + slider->SetSize(sliderSize); + + if (!valueLabel) + return; + + if (labelSize.fX <= 0.0f) + valueLabel->GetSize(labelSize); + + CVector2D labelPos; + valueLabel->GetPosition(labelPos); + labelPos.fX = sliderPos.fX + targetWidth + labelSpacing; + + const float maxLabelX = std::max(0.0f, tabWidth - labelSize.fX); + if (labelPos.fX > maxLabelX) + labelPos.fX = maxLabelX; + + valueLabel->SetPosition(labelPos); + } +} + +void CSettings::ResetGuiPointers() +{ + m_pWindow = NULL; + m_pTabs = NULL; + m_pTabMultiplayer = NULL; + m_pTabVideo = NULL; + m_pTabInterface = NULL; + m_pTabBrowser = NULL; + m_pTabPostFX = NULL; + m_pTabAudio = NULL; + m_pTabBinds = NULL; + m_pTabControls = NULL; + m_pTabAdvanced = NULL; + m_pButtonOK = NULL; + m_pButtonCancel = NULL; + m_pLabelNick = NULL; + m_pButtonGenerateNick = NULL; + m_pButtonGenerateNickIcon = NULL; + m_pEditNick = NULL; + m_pSavePasswords = NULL; + m_pAutoRefreshBrowser = NULL; + + m_pVideoGeneralLabel = NULL; + m_pVideoResolutionLabel = NULL; + m_pComboResolution = NULL; + m_pCheckBoxMipMapping = NULL; + m_pCheckBoxWindowed = NULL; + m_pCheckBoxDPIAware = NULL; + m_pCheckBoxHudMatchAspectRatio = NULL; + m_pCheckBoxMinimize = NULL; + m_pMapRenderingLabel = NULL; + m_pComboFxQuality = NULL; + m_pFXQualityLabel = NULL; + m_pComboAspectRatio = NULL; + m_pAspectRatioLabel = NULL; + m_pCheckBoxVolumetricShadows = NULL; + m_pCheckBoxDeviceSelectionDialog = NULL; + m_pCheckBoxShowUnsafeResolutions = NULL; + m_pCheckBoxAllowScreenUpload = NULL; + m_pCheckBoxAllowExternalSounds = NULL; + m_pCheckBoxCustomizedSAFiles = NULL; + m_pCheckBoxAllowDiscordRPC = NULL; + m_pCheckBoxAllowSteamClient = NULL; + m_pCheckBoxAlwaysShowTransferBox = NULL; + m_pCheckBoxGrass = NULL; + m_pCheckBoxHeatHaze = NULL; + m_pCheckBoxTyreSmokeParticles = NULL; + m_pCheckBoxHighDetailVehicles = NULL; + m_pCheckBoxHighDetailPeds = NULL; + m_pCheckBoxBlur = NULL; + m_pCheckBoxCoronaReflections = NULL; + m_pCheckBoxDynamicPedShadows = NULL; + m_pFieldOfViewLabel = NULL; + m_pFieldOfView = NULL; + m_pFieldOfViewValueLabel = NULL; + m_pDrawDistanceLabel = NULL; + m_pDrawDistance = NULL; + m_pDrawDistanceValueLabel = NULL; + m_pBrightnessLabel = NULL; + m_pBrightness = NULL; + m_pBrightnessValueLabel = NULL; + m_pBorderlessGammaToggle = NULL; + m_pBorderlessGamma = NULL; + m_pBorderlessGammaValueLabel = NULL; + m_pBorderlessBrightnessToggle = NULL; + m_pBorderlessBrightness = NULL; + m_pBorderlessBrightnessValueLabel = NULL; + m_pBorderlessContrastToggle = NULL; + m_pBorderlessContrast = NULL; + m_pBorderlessContrastValueLabel = NULL; + m_pBorderlessSaturationToggle = NULL; + m_pBorderlessSaturation = NULL; + m_pBorderlessSaturationValueLabel = NULL; + m_pCheckBoxApplyBorderless = NULL; + m_pCheckBoxApplyFullscreen = NULL; + m_pPostFXDefButton = NULL; + + m_pAnisotropicLabel = NULL; + m_pAnisotropic = NULL; + m_pAnisotropicValueLabel = NULL; + m_pComboAntiAliasing = NULL; + m_pAntiAliasingLabel = NULL; + m_pMapAlphaLabel = NULL; + m_pMapAlpha = NULL; + m_pMapAlphaValueLabel = NULL; + m_pStreamingMemoryLabel = NULL; + m_pStreamingMemory = NULL; + m_pStreamingMemoryMinLabel = NULL; + m_pStreamingMemoryMaxLabel = NULL; + m_pStreamingMemoryLabelInfo = NULL; + m_pVideoDefButton = NULL; + + m_pAdvancedSettingDescriptionLabel = NULL; + m_pFullscreenStyleLabel = NULL; + m_pFullscreenStyleCombo = NULL; + m_pCheckBoxVSync = NULL; + m_pPriorityLabel = NULL; + m_pPriorityCombo = NULL; + m_pPlayerMapImageLabel = NULL; + m_pPlayerMapImageCombo = NULL; + m_pFastClothesLabel = NULL; + m_pFastClothesCombo = NULL; + m_pAudioGeneralLabel = NULL; + m_pUserTrackGeneralLabel = NULL; + m_pBrowserSpeedLabel = NULL; + m_pBrowserSpeedCombo = NULL; + m_pSingleDownloadLabel = NULL; + m_pSingleDownloadCombo = NULL; + m_pPacketTagLabel = NULL; + m_pPacketTagCombo = NULL; + m_pProgressAnimationLabel = NULL; + m_pProgressAnimationCombo = NULL; + m_pDebugSettingLabel = NULL; + m_pDebugSettingCombo = NULL; + m_pWin8Label = NULL; + m_pWin8ColorCheckBox = NULL; + m_pWin8MouseCheckBox = NULL; + m_pPhotoSavingCheckbox = NULL; + m_pCheckBoxAskBeforeDisconnect = NULL; + m_pProcessAffinityCheckbox = NULL; + m_pUpdateBuildTypeLabel = NULL; + m_pUpdateBuildTypeCombo = NULL; + m_pUpdateAutoInstallLabel = NULL; + m_pUpdateAutoInstallCombo = NULL; + m_pButtonUpdate = NULL; + m_pAdvancedMiscLabel = NULL; + m_pAdvancedUpdaterLabel = NULL; + m_pCachePathLabel = NULL; + m_pCachePathValue = NULL; + m_pCachePathShowButton = NULL; + + m_pLabelMasterVolume = NULL; + m_pLabelRadioVolume = NULL; + m_pLabelSFXVolume = NULL; + m_pLabelMTAVolume = NULL; + m_pLabelVoiceVolume = NULL; + m_pLabelMasterVolumeValue = NULL; + m_pLabelRadioVolumeValue = NULL; + m_pLabelSFXVolumeValue = NULL; + m_pLabelMTAVolumeValue = NULL; + m_pLabelVoiceVolumeValue = NULL; + m_pAudioMasterVolume = NULL; + m_pAudioRadioVolume = NULL; + m_pAudioSFXVolume = NULL; + m_pAudioMTAVolume = NULL; + m_pAudioVoiceVolume = NULL; + m_pAudioRadioLabel = NULL; + m_pCheckBoxAudioEqualizer = NULL; + m_pCheckBoxAudioAutotune = NULL; + m_pAudioMuteLabel = NULL; + m_pCheckBoxMuteMaster = NULL; + m_pCheckBoxMuteSFX = NULL; + m_pCheckBoxMuteRadio = NULL; + m_pCheckBoxMuteMTA = NULL; + m_pCheckBoxMuteVoice = NULL; + m_pAudioUsertrackLabel = NULL; + m_pCheckBoxUserAutoscan = NULL; + m_pLabelUserTrackMode = NULL; + m_pComboUsertrackMode = NULL; + m_pAudioDefButton = NULL; + + m_pBindsList = NULL; + m_pBindsDefButton = NULL; + + m_pJoypadName = NULL; + m_pJoypadUnderline = NULL; + m_pEditDeadzone = NULL; + m_pEditSaturation = NULL; + m_pJoypadLabels.clear(); + m_pJoypadButtons.clear(); + + m_pSelectedBind = NULL; + + m_pControlsMouseLabel = NULL; + m_pInvertMouse = NULL; + m_pSteerWithMouse = NULL; + m_pFlyWithMouse = NULL; + m_pLabelMouseSensitivity = NULL; + m_pMouseSensitivity = NULL; + m_pLabelMouseSensitivityValue = NULL; + m_pLabelVerticalAimSensitivity = NULL; + m_pVerticalAimSensitivity = NULL; + m_pLabelVerticalAimSensitivityValue = NULL; + m_pCheckboxVerticalAimSensitivity = nullptr; + + m_pControlsJoypadLabel = NULL; + m_pControlsInputTypePane = NULL; + m_pStandardControls = NULL; + m_pClassicControls = NULL; + + m_pInterfaceLanguageSelector = NULL; + m_pInterfaceSkinSelector = NULL; + m_pInterfaceLoadSkin = NULL; + + m_pChatPresets = NULL; + m_pChatLoadPreset = NULL; + + for (int i = 0; i < Chat::ColorType::MAX; ++i) + { + m_pChatRed[i] = NULL; + m_pChatGreen[i] = NULL; + m_pChatBlue[i] = NULL; + m_pChatAlpha[i] = NULL; + m_pChatRedValue[i] = NULL; + m_pChatGreenValue[i] = NULL; + m_pChatBlueValue[i] = NULL; + m_pChatAlphaValue[i] = NULL; + m_pChatColorPreview[i] = NULL; + } + + m_pPaneChatFont = NULL; + for (int i = 0; i < Chat::Font::MAX; ++i) + m_pRadioChatFont[i] = NULL; + + m_pChatHorizontalCombo = NULL; + m_pChatVerticalCombo = NULL; + m_pChatTextAlignCombo = NULL; + m_pChatOffsetX = NULL; + m_pChatOffsetY = NULL; + m_pChatLines = NULL; + m_pChatScaleX = NULL; + m_pChatScaleY = NULL; + m_pChatWidth = NULL; + m_pChatCssBackground = NULL; + m_pChatNickCompletion = NULL; + m_pChatCssText = NULL; + m_pChatTextBlackOutline = NULL; + m_pChatLineLife = NULL; + m_pChatLineFadeout = NULL; + m_pFlashWindow = NULL; + m_pTrayBalloon = NULL; + + m_pLabelBrowserGeneral = NULL; + m_pCheckBoxRemoteBrowser = NULL; + m_pCheckBoxRemoteJavascript = NULL; + m_pLabelBrowserCustomBlacklist = NULL; + m_pEditBrowserBlacklistAdd = NULL; + m_pLabelBrowserBlacklistAdd = NULL; + m_pButtonBrowserBlacklistAdd = NULL; + m_pGridBrowserBlacklist = NULL; + m_pButtonBrowserBlacklistRemove = NULL; + m_pLabelBrowserCustomWhitelist = NULL; + m_pEditBrowserWhitelistAdd = NULL; + m_pLabelBrowserWhitelistAdd = NULL; + m_pButtonBrowserWhitelistAdd = NULL; + m_pGridBrowserWhitelist = NULL; + m_pButtonBrowserWhitelistRemove = NULL; + m_pCheckBoxBrowserGPUEnabled = NULL; +} + CSettings::CSettings() { + ResetGuiPointers(); + CGameSettings* gameSettings = CCore::GetSingleton().GetGame()->GetSettings(); m_fRadioVolume = (float)gameSettings->GetRadioVolume() / 64.0f; m_fSFXVolume = (float)gameSettings->GetSFXVolume() / 64.0f; m_iMaxAnisotropic = g_pDeviceState->AdapterState.MaxAnisotropicSetting; - m_pWindow = NULL; m_bBrowserListsChanged = false; m_bBrowserListsLoadEnabled = false; CreateGUI(); @@ -57,7 +456,7 @@ void CSettings::CreateGUI() if (m_pWindow) DestroyGUI(); - CGUITab *pTabMultiplayer, *pTabVideo, *pTabAudio, *pTabBinds, *pTabControls, *pTabAdvanced; + CGUITab *pTabMultiplayer, *pTabVideo, *pTabPostFX, *pTabAudio, *pTabBinds, *pTabControls, *pTabAdvanced; CGUI* pManager = g_pCore->GetGUI(); // Init @@ -71,13 +470,27 @@ void CSettings::CreateGUI() CVector2D resolution = CCore::GetSingleton().GetGUI()->GetResolution(); - CVector2D contentSize(640, 480); - float fBottomButtonAreaHeight = 38; + const float fBottomButtonAreaHeight = kSettingsBottomButtonAreaHeight; + CVector2D contentSize(kSettingsContentWidth, kSettingsBaseContentHeight); + const float availableContentWidth = resolution.fX - kSettingsWindowFrameHorizontal; + if (availableContentWidth > 0.0f) + contentSize.fX = std::min(kSettingsContentWidth, availableContentWidth); + + const float availableContentHeight = resolution.fY - kSettingsWindowFrameVertical; + if (availableContentHeight > 0.0f) + { + const float minContentHeight = fBottomButtonAreaHeight + 1.0f; // Adjusted for clarity + const float maxContentHeight = std::max(availableContentHeight, minContentHeight); + contentSize.fY = std::clamp(kSettingsBaseContentHeight, minContentHeight, maxContentHeight); + } + + contentSize.fX = std::max(contentSize.fX, 0.0f); + contentSize.fY = std::max(contentSize.fY, fBottomButtonAreaHeight + 1.0f); + CVector2D tabPanelPosition; - CVector2D tabPanelSize = contentSize - CVector2D(0, fBottomButtonAreaHeight); // Window size is content size plus window frame edge dims - CVector2D windowSize = contentSize + CVector2D(9 + 9, 20 + 2); + CVector2D windowSize = contentSize + CVector2D(kSettingsWindowFrameHorizontal, kSettingsWindowFrameVertical); if (windowSize.fX <= resolution.fX && windowSize.fY <= resolution.fY) { @@ -102,6 +515,8 @@ void CSettings::CreateGUI() pFiller->SetZOrderingEnabled(false); pFiller->SetAlwaysOnTop(true); pFiller->MoveToBack(); + contentSize.fX = std::min(contentSize.fX, resolution.fX); + contentSize.fY = std::min(contentSize.fY, resolution.fY); pFiller->SetPosition((resolution - contentSize) / 2); pFiller->SetSize(contentSize); m_pWindow = pFiller; @@ -111,17 +526,31 @@ void CSettings::CreateGUI() // Create the tab panel and necessary tabs m_pTabs = reinterpret_cast(pManager->CreateTabPanel(m_pWindow)); m_pTabs->SetPosition(tabPanelPosition); + const CVector2D tabPanelSize = CVector2D(contentSize.fX, std::max(0.0f, contentSize.fY - fBottomButtonAreaHeight)); m_pTabs->SetSize(tabPanelSize); m_pTabs->SetSelectionHandler(GUI_CALLBACK(&CSettings::OnTabChanged, this)); - pTabMultiplayer = m_pTabs->CreateTab(_("Multiplayer")); - pTabVideo = m_pTabs->CreateTab(_("Video")); - pTabAudio = m_pTabs->CreateTab(_("Audio")); - pTabBinds = m_pTabs->CreateTab(_("Binds")); - pTabControls = m_pTabs->CreateTab(_("Controls")); + const float tabHorizontalPadding = kSettingsTabHorizontalPadding; + const auto placeBottomRightButton = [&](CGUIButton* button) + { + if (!button) + return; + CVector2D buttonSize; + button->GetSize(buttonSize); + const float bottomPadding = 32.0f; + const float buttonY = std::max(0.0f, tabPanelSize.fY - buttonSize.fY - bottomPadding - 4.0f); + button->SetPosition(CVector2D(std::max(0.0f, tabPanelSize.fX - buttonSize.fX - bottomPadding), buttonY)); + }; + + pTabMultiplayer = m_pTabMultiplayer = m_pTabs->CreateTab(_("Multiplayer")); + pTabVideo = m_pTabVideo = m_pTabs->CreateTab(_("Video")); + pTabPostFX = m_pTabPostFX = m_pTabs->CreateTab(_("PostFX")); + pTabAudio = m_pTabAudio = m_pTabs->CreateTab(_("Audio")); + pTabBinds = m_pTabBinds = m_pTabs->CreateTab(_("Binds")); + pTabControls = m_pTabControls = m_pTabs->CreateTab(_("Controls")); m_pTabInterface = m_pTabs->CreateTab(_("Interface")); m_pTabBrowser = m_pTabs->CreateTab(_("Web Browser")); - pTabAdvanced = m_pTabs->CreateTab(_("Advanced")); + pTabAdvanced = m_pTabAdvanced = m_pTabs->CreateTab(_("Advanced")); // Create buttons // OK button @@ -138,8 +567,9 @@ void CSettings::CreateGUI() * Binds tab **/ m_pBindsList = reinterpret_cast(pManager->CreateGridList(pTabBinds, false)); - m_pBindsList->SetPosition(CVector2D(10, 15)); - m_pBindsList->SetSize(CVector2D(620, 357)); + const float bindsListX = tabHorizontalPadding * 0.5f; + const float bindsListTop = 15.0f; + m_pBindsList->SetPosition(CVector2D(bindsListX, bindsListTop)); m_pBindsList->SetSortingEnabled(false); m_pBindsList->SetSelectionMode(SelectionModes::CellSingle); m_pBindsList->SetDoubleClickHandler(GUI_CALLBACK(&CSettings::OnBindsListClick, this)); @@ -149,8 +579,15 @@ void CSettings::CreateGUI() m_pBindsDefButton->SetClickHandler(GUI_CALLBACK(&CSettings::OnBindsDefaultClick, this)); m_pBindsDefButton->AutoSize(NULL, 20.0f, 8.0f); m_pBindsDefButton->GetSize(vecSize); - m_pBindsDefButton->SetPosition(CVector2D(vecTemp.fX - vecSize.fX - 12.0f, 387)); + placeBottomRightButton(m_pBindsDefButton); m_pBindsDefButton->SetZOrderingEnabled(false); + CVector2D bindsButtonPos; + m_pBindsDefButton->GetPosition(bindsButtonPos); + const float minBindsListHeight = 120.0f; + const float maxBindsListHeight = std::max(minBindsListHeight, tabPanelSize.fY - bindsListTop - 20.0f); + const float availableBindsHeight = bindsButtonPos.fY - bindsListTop - 10.0f; + const float bindsListHeight = std::clamp(availableBindsHeight, minBindsListHeight, maxBindsListHeight); + m_pBindsList->SetSize(CVector2D(std::max(0.0f, tabPanelSize.fX - tabHorizontalPadding), bindsListHeight)); /** * Controls tab @@ -186,13 +623,16 @@ void CSettings::CreateGUI() m_pMouseSensitivity = reinterpret_cast(pManager->CreateScrollBar(true, pTabControls)); m_pMouseSensitivity->SetPosition(CVector2D(vecTemp.fX + fIndentX + 5.0f, vecTemp.fY)); m_pMouseSensitivity->GetPosition(vecTemp); - m_pMouseSensitivity->SetSize(CVector2D(160.0f, 20.0f)); + const CVector2D mouseSliderPos = vecTemp; + const float mouseSliderWidth = ComputeSliderWidth(tabPanelSize.fX, mouseSliderPos.fX, 160.0f); + m_pMouseSensitivity->SetSize(CVector2D(mouseSliderWidth, 20.0f)); m_pMouseSensitivity->GetSize(vecSize); m_pMouseSensitivity->SetProperty("StepSize", "0.01"); m_pLabelMouseSensitivityValue = reinterpret_cast(pManager->CreateLabel(pTabControls, "0%")); - m_pLabelMouseSensitivityValue->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 5.0f, vecTemp.fY)); + m_pLabelMouseSensitivityValue->SetPosition(CVector2D(mouseSliderPos.fX + vecSize.fX + kSliderLabelSpacing, mouseSliderPos.fY)); m_pLabelMouseSensitivityValue->AutoSize("100%"); + FinalizeSliderRow(tabPanelSize.fX, m_pMouseSensitivity, m_pLabelMouseSensitivityValue, 160.0f, kSliderLabelSpacing, m_pLabelMouseSensitivity); vecTemp.fX = 16; vecTemp.fY += 24.f; @@ -204,15 +644,23 @@ void CSettings::CreateGUI() m_pVerticalAimSensitivity = reinterpret_cast(pManager->CreateScrollBar(true, pTabControls)); m_pVerticalAimSensitivity->SetPosition(CVector2D(vecTemp.fX + fIndentX + 5.0f, vecTemp.fY)); m_pVerticalAimSensitivity->GetPosition(vecTemp); - m_pVerticalAimSensitivity->SetSize(CVector2D(160.0f, 20.0f)); + const CVector2D verticalSliderPos = vecTemp; + const float verticalSliderWidth = ComputeSliderWidth(tabPanelSize.fX, verticalSliderPos.fX, 160.0f); + m_pVerticalAimSensitivity->SetSize(CVector2D(verticalSliderWidth, 20.0f)); m_pVerticalAimSensitivity->GetSize(vecSize); m_pVerticalAimSensitivity->SetProperty("StepSize", "0.01"); m_pLabelVerticalAimSensitivityValue = reinterpret_cast(pManager->CreateLabel(pTabControls, "0%")); - m_pLabelVerticalAimSensitivityValue->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 5.0f, vecTemp.fY)); + m_pLabelVerticalAimSensitivityValue->SetPosition(CVector2D(verticalSliderPos.fX + vecSize.fX + kSliderLabelSpacing, verticalSliderPos.fY)); m_pLabelVerticalAimSensitivityValue->AutoSize("100%"); + FinalizeSliderRow(tabPanelSize.fX, m_pVerticalAimSensitivity, m_pLabelVerticalAimSensitivityValue, 160.0f, kSliderLabelSpacing, + m_pLabelVerticalAimSensitivity); vecTemp.fY += 30.f; + m_pCheckboxVerticalAimSensitivity = reinterpret_cast(pManager->CreateCheckBox(pTabControls, _("Use mouse sensitivity for aiming"), false)); + m_pCheckboxVerticalAimSensitivity->SetPosition(CVector2D(verticalSliderPos.fX, verticalSliderPos.fY + 20.0f)); + m_pCheckboxVerticalAimSensitivity->AutoSize(nullptr, 20.0f); + vecTemp.fX = 16; // Joypad options m_pControlsJoypadLabel = reinterpret_cast(pManager->CreateLabel(pTabControls, _("Joypad options"))); @@ -289,13 +737,13 @@ void CSettings::CreateGUI() vecTemp.fY += -91; // Layout the mapping buttons like a dual axis joypad - CVector2D vecPosList[] = {CVector2D(162, 202), // Left Stick + CVector2D vecPosList[] = {CVector2D(162, 202), // Left Stick CVector2D(280, 202), CVector2D(221, 182), CVector2D(221, 220), - CVector2D(351, 202), // Right Stick + CVector2D(351, 202), // Right Stick CVector2D(469, 202), CVector2D(410, 182), CVector2D(410, 220), - CVector2D(410, 276), // Acceleration/Brake + CVector2D(410, 276), // Acceleration/Brake CVector2D(221, 276)}; for (int i = 0; i < JoyMan->GetOutputCount() && i < 10; i++) @@ -315,7 +763,7 @@ void CSettings::CreateGUI() pLabel->SetPosition(CVector2D((vecPos.fX + 10) + vecSize.fX * 0.5f - 80.0f, vecPos.fY - 26)); pLabel->SetHorizontalAlign(CGUI_ALIGN_HORIZONTALCENTER); pLabel->SetVerticalAlign(CGUI_ALIGN_VERTICALCENTER); - pLabel->SetVisible(i >= 8); // Hide all labels except 'Acceleration' and 'Brake' + pLabel->SetVisible(i >= 8); // Hide all labels except 'Acceleration' and 'Brake' m_pJoypadLabels.push_back(pLabel); m_pJoypadButtons.push_back(pButton); @@ -340,7 +788,7 @@ void CSettings::CreateGUI() pControlsDefButton->SetClickHandler(GUI_CALLBACK(&CSettings::OnControlsDefaultClick, this)); pControlsDefButton->AutoSize(NULL, 20.0f, 8.0f); pControlsDefButton->GetSize(vecSize); - pControlsDefButton->SetPosition(CVector2D(vecTemp.fX - vecSize.fX - 12.0f, 387)); + placeBottomRightButton(pControlsDefButton); pControlsDefButton->SetZOrderingEnabled(false); m_hBind = m_pBindsList->AddColumn(_("DESCRIPTION"), 0.35f); @@ -401,7 +849,8 @@ void CSettings::CreateGUI() m_pCheckBoxAlwaysShowTransferBox->GetPosition(vecTemp, false); m_pCheckBoxAlwaysShowTransferBox->AutoSize(nullptr, 20.0f); - m_pCheckBoxAllowDiscordRPC = reinterpret_cast(pManager->CreateCheckBox(pTabMultiplayer, _("Allow connecting with Discord Rich Presence"), false)); + m_pCheckBoxAllowDiscordRPC = + reinterpret_cast(pManager->CreateCheckBox(pTabMultiplayer, _("Allow connecting with Discord Rich Presence"), false)); m_pCheckBoxAllowDiscordRPC->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f)); m_pCheckBoxAllowDiscordRPC->GetPosition(vecTemp, false); m_pCheckBoxAllowDiscordRPC->AutoSize(NULL, 20.0f); @@ -412,12 +861,14 @@ void CSettings::CreateGUI() m_pCheckBoxAllowSteamClient->AutoSize(NULL, 20.0f); // Enable camera photos getting saved to documents folder - m_pPhotoSavingCheckbox = reinterpret_cast(pManager->CreateCheckBox(pTabMultiplayer, _("Save photos taken by camera weapon to GTA San Andreas User Files folder"), true)); + m_pPhotoSavingCheckbox = reinterpret_cast( + pManager->CreateCheckBox(pTabMultiplayer, _("Save photos taken by camera weapon to GTA San Andreas User Files folder"), true)); m_pPhotoSavingCheckbox->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f)); m_pPhotoSavingCheckbox->GetPosition(vecTemp, false); m_pPhotoSavingCheckbox->AutoSize(NULL, 20.0f); - m_pCheckBoxAskBeforeDisconnect = reinterpret_cast(pManager->CreateCheckBox(pTabMultiplayer, _("Ask before disconnecting from server using main menu"), true)); + m_pCheckBoxAskBeforeDisconnect = + reinterpret_cast(pManager->CreateCheckBox(pTabMultiplayer, _("Ask before disconnecting from server using main menu"), true)); m_pCheckBoxAskBeforeDisconnect->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f)); m_pCheckBoxAskBeforeDisconnect->GetPosition(vecTemp, false); m_pCheckBoxAskBeforeDisconnect->AutoSize(NULL, 20.0f); @@ -443,14 +894,17 @@ void CSettings::CreateGUI() m_pMapAlpha = reinterpret_cast(pManager->CreateScrollBar(true, pTabMultiplayer)); m_pMapAlpha->SetPosition(CVector2D(vecTemp.fX + fIndentX + 5.0f, vecTemp.fY)); m_pMapAlpha->GetPosition(vecTemp, false); - m_pMapAlpha->SetSize(CVector2D(160.0f, 20.0f)); + const CVector2D mapAlphaSliderPos = vecTemp; + const float mapAlphaSliderWidth = ComputeSliderWidth(tabPanelSize.fX, mapAlphaSliderPos.fX, 160.0f); + m_pMapAlpha->SetSize(CVector2D(mapAlphaSliderWidth, 20.0f)); m_pMapAlpha->GetSize(vecSize); m_pMapAlpha->SetProperty("StepSize", "0.01"); m_pMapAlphaValueLabel = reinterpret_cast(pManager->CreateLabel(pTabMultiplayer, "0%")); - m_pMapAlphaValueLabel->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 5.0f, vecTemp.fY)); + m_pMapAlphaValueLabel->SetPosition(CVector2D(mapAlphaSliderPos.fX + vecSize.fX + kSliderLabelSpacing, mapAlphaSliderPos.fY)); m_pMapAlphaValueLabel->GetPosition(vecTemp, false); m_pMapAlphaValueLabel->AutoSize("100%"); + FinalizeSliderRow(tabPanelSize.fX, m_pMapAlpha, m_pMapAlphaValueLabel, 160.0f, kSliderLabelSpacing, m_pMapAlphaLabel); m_pMapAlphaLabel->GetPosition(vecTemp, false); vecTemp.fY += 24.0f; @@ -462,8 +916,8 @@ void CSettings::CreateGUI() m_pPlayerMapImageCombo = reinterpret_cast(pManager->CreateComboBox(pTabMultiplayer, "")); m_pPlayerMapImageCombo->SetPosition(CVector2D(vecTemp.fX + fIndentX + 5.0f, vecTemp.fY - 1.0f)); m_pPlayerMapImageCombo->SetSize(CVector2D(170.f, 95.0f)); - m_pPlayerMapImageCombo->AddItem(_("1024 x 1024 (Default)")); // index 0 - m_pPlayerMapImageCombo->AddItem(_("2048 x 2048")); // index 1 + m_pPlayerMapImageCombo->AddItem(_("1024 x 1024 (Default)")); // index 0 + m_pPlayerMapImageCombo->AddItem(_("2048 x 2048")); // index 1 m_pPlayerMapImageCombo->SetReadOnly(true); /** @@ -486,15 +940,18 @@ void CSettings::CreateGUI() m_pAudioMasterVolume = reinterpret_cast(pManager->CreateScrollBar(true, pTabAudio)); m_pAudioMasterVolume->SetPosition(CVector2D(vecTemp.fX + fIndentX + 5.0f, vecTemp.fY)); m_pAudioMasterVolume->GetPosition(vecTemp, false); - m_pAudioMasterVolume->SetSize(CVector2D(160.0f, 20.0f)); + const CVector2D masterSliderPos = vecTemp; + const float masterSliderWidth = ComputeSliderWidth(tabPanelSize.fX, masterSliderPos.fX, 160.0f); + m_pAudioMasterVolume->SetSize(CVector2D(masterSliderWidth, 20.0f)); m_pAudioMasterVolume->GetSize(vecSize, false); m_pAudioMasterVolume->SetProperty("StepSize", "0.01"); m_pLabelMasterVolumeValue = reinterpret_cast(pManager->CreateLabel(pTabAudio, "0%")); - m_pLabelMasterVolumeValue->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 5.0f, vecTemp.fY)); + m_pLabelMasterVolumeValue->SetPosition(CVector2D(masterSliderPos.fX + vecSize.fX + kSliderLabelSpacing, masterSliderPos.fY)); m_pLabelMasterVolumeValue->GetPosition(vecTemp, false); m_pLabelMasterVolumeValue->AutoSize("100%"); m_pLabelMasterVolumeValue->GetSize(vecSize, false); + FinalizeSliderRow(tabPanelSize.fX, m_pAudioMasterVolume, m_pLabelMasterVolumeValue, 160.0f, kSliderLabelSpacing, m_pLabelMasterVolume); vecTemp.fX = 11; m_pLabelRadioVolume = reinterpret_cast(pManager->CreateLabel(pTabAudio, _("Radio volume:"))); @@ -505,15 +962,18 @@ void CSettings::CreateGUI() m_pAudioRadioVolume = reinterpret_cast(pManager->CreateScrollBar(true, pTabAudio)); m_pAudioRadioVolume->SetPosition(CVector2D(vecTemp.fX + fIndentX + 5.0f, vecTemp.fY)); m_pAudioRadioVolume->GetPosition(vecTemp, false); - m_pAudioRadioVolume->SetSize(CVector2D(160.0f, 20.0f)); + const CVector2D radioSliderPos = vecTemp; + const float radioSliderWidth = ComputeSliderWidth(tabPanelSize.fX, radioSliderPos.fX, 160.0f); + m_pAudioRadioVolume->SetSize(CVector2D(radioSliderWidth, 20.0f)); m_pAudioRadioVolume->GetSize(vecSize, false); m_pAudioRadioVolume->SetProperty("StepSize", "0.01"); m_pLabelRadioVolumeValue = reinterpret_cast(pManager->CreateLabel(pTabAudio, "0%")); - m_pLabelRadioVolumeValue->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 5.0f, vecTemp.fY)); + m_pLabelRadioVolumeValue->SetPosition(CVector2D(radioSliderPos.fX + vecSize.fX + kSliderLabelSpacing, radioSliderPos.fY)); m_pLabelRadioVolumeValue->GetPosition(vecTemp, false); m_pLabelRadioVolumeValue->AutoSize("100%"); m_pLabelRadioVolumeValue->GetSize(vecSize, false); + FinalizeSliderRow(tabPanelSize.fX, m_pAudioRadioVolume, m_pLabelRadioVolumeValue, 160.0f, kSliderLabelSpacing, m_pLabelRadioVolume); vecTemp.fX = 11; m_pLabelSFXVolume = reinterpret_cast(pManager->CreateLabel(pTabAudio, _("SFX volume:"))); @@ -524,15 +984,18 @@ void CSettings::CreateGUI() m_pAudioSFXVolume = reinterpret_cast(pManager->CreateScrollBar(true, pTabAudio)); m_pAudioSFXVolume->SetPosition(CVector2D(vecTemp.fX + fIndentX + 5.0f, vecTemp.fY)); m_pAudioSFXVolume->GetPosition(vecTemp, false); - m_pAudioSFXVolume->SetSize(CVector2D(160.0f, 20.0f)); + const CVector2D sfxSliderPos = vecTemp; + const float sfxSliderWidth = ComputeSliderWidth(tabPanelSize.fX, sfxSliderPos.fX, 160.0f); + m_pAudioSFXVolume->SetSize(CVector2D(sfxSliderWidth, 20.0f)); m_pAudioSFXVolume->GetSize(vecSize, false); m_pAudioSFXVolume->SetProperty("StepSize", "0.01"); m_pLabelSFXVolumeValue = reinterpret_cast(pManager->CreateLabel(pTabAudio, "0%")); - m_pLabelSFXVolumeValue->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 5.0f, vecTemp.fY)); + m_pLabelSFXVolumeValue->SetPosition(CVector2D(sfxSliderPos.fX + vecSize.fX + kSliderLabelSpacing, sfxSliderPos.fY)); m_pLabelSFXVolumeValue->GetPosition(vecTemp, false); m_pLabelSFXVolumeValue->AutoSize("100%"); m_pLabelSFXVolumeValue->GetSize(vecSize, false); + FinalizeSliderRow(tabPanelSize.fX, m_pAudioSFXVolume, m_pLabelSFXVolumeValue, 160.0f, kSliderLabelSpacing, m_pLabelSFXVolume); vecTemp.fX = 11; m_pLabelMTAVolume = reinterpret_cast(pManager->CreateLabel(pTabAudio, _("MTA volume:"))); @@ -543,15 +1006,18 @@ void CSettings::CreateGUI() m_pAudioMTAVolume = reinterpret_cast(pManager->CreateScrollBar(true, pTabAudio)); m_pAudioMTAVolume->SetPosition(CVector2D(vecTemp.fX + fIndentX + 5.0f, vecTemp.fY)); m_pAudioMTAVolume->GetPosition(vecTemp, false); - m_pAudioMTAVolume->SetSize(CVector2D(160.0f, 20.0f)); + const CVector2D mtaSliderPos = vecTemp; + const float mtaSliderWidth = ComputeSliderWidth(tabPanelSize.fX, mtaSliderPos.fX, 160.0f); + m_pAudioMTAVolume->SetSize(CVector2D(mtaSliderWidth, 20.0f)); m_pAudioMTAVolume->GetSize(vecSize, false); m_pAudioMTAVolume->SetProperty("StepSize", "0.01"); m_pLabelMTAVolumeValue = reinterpret_cast(pManager->CreateLabel(pTabAudio, "0%")); - m_pLabelMTAVolumeValue->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 5.0f, vecTemp.fY)); + m_pLabelMTAVolumeValue->SetPosition(CVector2D(mtaSliderPos.fX + vecSize.fX + kSliderLabelSpacing, mtaSliderPos.fY)); m_pLabelMTAVolumeValue->GetPosition(vecTemp, false); m_pLabelMTAVolumeValue->AutoSize("100%"); m_pLabelMTAVolumeValue->GetSize(vecSize, false); + FinalizeSliderRow(tabPanelSize.fX, m_pAudioMTAVolume, m_pLabelMTAVolumeValue, 160.0f, kSliderLabelSpacing, m_pLabelMTAVolume); vecTemp.fX = 11; m_pLabelVoiceVolume = reinterpret_cast(pManager->CreateLabel(pTabAudio, _("Voice volume:"))); @@ -562,15 +1028,18 @@ void CSettings::CreateGUI() m_pAudioVoiceVolume = reinterpret_cast(pManager->CreateScrollBar(true, pTabAudio)); m_pAudioVoiceVolume->SetPosition(CVector2D(vecTemp.fX + fIndentX + 5.0f, vecTemp.fY)); m_pAudioVoiceVolume->GetPosition(vecTemp, false); - m_pAudioVoiceVolume->SetSize(CVector2D(160.0f, 20.0f)); + const CVector2D voiceSliderPos = vecTemp; + const float voiceSliderWidth = ComputeSliderWidth(tabPanelSize.fX, voiceSliderPos.fX, 160.0f); + m_pAudioVoiceVolume->SetSize(CVector2D(voiceSliderWidth, 20.0f)); m_pAudioVoiceVolume->GetSize(vecSize, false); m_pAudioVoiceVolume->SetProperty("StepSize", "0.01"); m_pLabelVoiceVolumeValue = reinterpret_cast(pManager->CreateLabel(pTabAudio, "0%")); - m_pLabelVoiceVolumeValue->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 5.0f, vecTemp.fY)); + m_pLabelVoiceVolumeValue->SetPosition(CVector2D(voiceSliderPos.fX + vecSize.fX + kSliderLabelSpacing, voiceSliderPos.fY)); m_pLabelVoiceVolumeValue->GetPosition(vecTemp, false); m_pLabelVoiceVolumeValue->AutoSize("100%"); m_pLabelVoiceVolumeValue->GetSize(vecSize, false); + FinalizeSliderRow(tabPanelSize.fX, m_pAudioVoiceVolume, m_pLabelVoiceVolumeValue, 160.0f, kSliderLabelSpacing, m_pLabelVoiceVolume); vecTemp.fX = 11; m_pAudioRadioLabel = reinterpret_cast(pManager->CreateLabel(pTabAudio, _("Radio options"))); @@ -651,7 +1120,7 @@ void CSettings::CreateGUI() m_pAudioDefButton->SetClickHandler(GUI_CALLBACK(&CSettings::OnAudioDefaultClick, this)); m_pAudioDefButton->AutoSize(NULL, 20.0f, 8.0f); m_pAudioDefButton->GetSize(vecSize); - m_pAudioDefButton->SetPosition(CVector2D(vecTemp.fX - vecSize.fX - 12.0f, 387)); + placeBottomRightButton(m_pAudioDefButton); m_pAudioDefButton->SetZOrderingEnabled(false); /** @@ -685,7 +1154,7 @@ void CSettings::CreateGUI() m_pCheckBoxDPIAware->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 10.0f, vecTemp.fY)); m_pCheckBoxDPIAware->AutoSize(NULL, 20.0f); - m_pVideoResolutionLabel->GetPosition(vecTemp, false); // Restore our label position + m_pVideoResolutionLabel->GetPosition(vecTemp, false); // Restore our label position // Fullscreen mode vecTemp.fY += 26; @@ -695,20 +1164,28 @@ void CSettings::CreateGUI() m_pFullscreenStyleCombo = reinterpret_cast(pManager->CreateComboBox(pTabVideo, "")); m_pFullscreenStyleCombo->SetPosition(CVector2D(vecTemp.fX + fIndentX + 5.0f, vecTemp.fY - 1.0f)); + m_pFullscreenStyleCombo->GetPosition(vecTemp, false); m_pFullscreenStyleCombo->SetSize(CVector2D(200, 95.0f)); + m_pFullscreenStyleCombo->GetSize(vecSize); m_pFullscreenStyleCombo->AddItem(_("Standard"))->SetData((void*)FULLSCREEN_STANDARD); m_pFullscreenStyleCombo->AddItem(_("Borderless window"))->SetData((void*)FULLSCREEN_BORDERLESS); m_pFullscreenStyleCombo->AddItem(_("Borderless keep res"))->SetData((void*)FULLSCREEN_BORDERLESS_KEEP_RES); m_pFullscreenStyleCombo->SetReadOnly(true); - vecTemp.fY += 4; m_pCheckBoxMipMapping = reinterpret_cast(pManager->CreateCheckBox(pTabVideo, _("Mip Mapping"), true)); #ifndef MIP_MAPPING_SETTING_APPEARS_TO_DO_SOMETHING - m_pCheckBoxMipMapping->SetPosition(CVector2D(vecTemp.fX + 340.0f, vecTemp.fY + 45.0f)); + m_pCheckBoxMipMapping->SetPosition(CVector2D(vecTemp.fX + vecSize.fX, vecTemp.fY + 45.0f)); m_pCheckBoxMipMapping->SetSize(CVector2D(224.0f, 16.0f)); m_pCheckBoxMipMapping->SetVisible(false); #endif + m_pCheckBoxVSync = reinterpret_cast(pManager->CreateCheckBox(pTabVideo, _("V-Sync"), true)); + m_pCheckBoxVSync->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 10.0f, vecTemp.fY + 3.0f)); + m_pCheckBoxVSync->AutoSize(NULL, 20.0f); + + // Reset position to leftmost + m_pFullscreenStyleLabel->GetPosition(vecTemp, false); + vecTemp.fY -= 5; m_pFieldOfViewLabel = reinterpret_cast(pManager->CreateLabel(pTabVideo, _("FOV:"))); m_pFieldOfViewLabel->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 30.0f)); @@ -718,12 +1195,15 @@ void CSettings::CreateGUI() m_pFieldOfView = reinterpret_cast(pManager->CreateScrollBar(true, pTabVideo)); m_pFieldOfView->SetPosition(CVector2D(vecTemp.fX + fIndentX + 5.0f, vecTemp.fY)); m_pFieldOfView->GetPosition(vecTemp, false); - m_pFieldOfView->SetSize(CVector2D(160.0f, 20.0f)); + const CVector2D fovSliderPos = vecTemp; + const float fovSliderWidth = ComputeSliderWidth(tabPanelSize.fX, fovSliderPos.fX, 160.0f); + m_pFieldOfView->SetSize(CVector2D(fovSliderWidth, 20.0f)); m_pFieldOfView->GetSize(vecSize); m_pFieldOfViewValueLabel = reinterpret_cast(pManager->CreateLabel(pTabVideo, "70")); - m_pFieldOfViewValueLabel->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 5.0f, vecTemp.fY)); + m_pFieldOfViewValueLabel->SetPosition(CVector2D(fovSliderPos.fX + vecSize.fX + kSliderLabelSpacing, fovSliderPos.fY)); m_pFieldOfViewValueLabel->AutoSize("70 "); + FinalizeSliderRow(tabPanelSize.fX, m_pFieldOfView, m_pFieldOfViewValueLabel, 160.0f, kSliderLabelSpacing, m_pFieldOfViewLabel); vecTemp.fX = 11; m_pDrawDistanceLabel = reinterpret_cast(pManager->CreateLabel(pTabVideo, _("Draw Distance:"))); @@ -734,13 +1214,16 @@ void CSettings::CreateGUI() m_pDrawDistance = reinterpret_cast(pManager->CreateScrollBar(true, pTabVideo)); m_pDrawDistance->SetPosition(CVector2D(vecTemp.fX + fIndentX + 5.0f, vecTemp.fY)); m_pDrawDistance->GetPosition(vecTemp, false); - m_pDrawDistance->SetSize(CVector2D(160.0f, 20.0f)); + const CVector2D drawDistanceSliderPos = vecTemp; + const float drawDistanceSliderWidth = ComputeSliderWidth(tabPanelSize.fX, drawDistanceSliderPos.fX, 160.0f); + m_pDrawDistance->SetSize(CVector2D(drawDistanceSliderWidth, 20.0f)); m_pDrawDistance->GetSize(vecSize); m_pDrawDistance->SetProperty("StepSize", "0.01"); m_pDrawDistanceValueLabel = reinterpret_cast(pManager->CreateLabel(pTabVideo, "0%")); - m_pDrawDistanceValueLabel->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 5.0f, vecTemp.fY)); + m_pDrawDistanceValueLabel->SetPosition(CVector2D(drawDistanceSliderPos.fX + vecSize.fX + kSliderLabelSpacing, drawDistanceSliderPos.fY)); m_pDrawDistanceValueLabel->AutoSize("100%"); + FinalizeSliderRow(tabPanelSize.fX, m_pDrawDistance, m_pDrawDistanceValueLabel, 160.0f, kSliderLabelSpacing, m_pDrawDistanceLabel); vecTemp.fX = 11; @@ -752,13 +1235,16 @@ void CSettings::CreateGUI() m_pBrightness = reinterpret_cast(pManager->CreateScrollBar(true, pTabVideo)); m_pBrightness->SetPosition(CVector2D(vecTemp.fX + fIndentX + 5.0f, vecTemp.fY)); m_pBrightness->GetPosition(vecTemp, false); - m_pBrightness->SetSize(CVector2D(160.0f, 20.0f)); + const CVector2D brightnessSliderPos = vecTemp; + const float brightnessSliderWidth = ComputeSliderWidth(tabPanelSize.fX, brightnessSliderPos.fX, 160.0f); + m_pBrightness->SetSize(CVector2D(brightnessSliderWidth, 20.0f)); m_pBrightness->GetSize(vecSize); m_pBrightness->SetProperty("StepSize", "0.01"); m_pBrightnessValueLabel = reinterpret_cast(pManager->CreateLabel(pTabVideo, "0%")); - m_pBrightnessValueLabel->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 5.0f, vecTemp.fY)); + m_pBrightnessValueLabel->SetPosition(CVector2D(brightnessSliderPos.fX + vecSize.fX + kSliderLabelSpacing, brightnessSliderPos.fY)); m_pBrightnessValueLabel->AutoSize("100%"); + FinalizeSliderRow(tabPanelSize.fX, m_pBrightness, m_pBrightnessValueLabel, 160.0f, kSliderLabelSpacing, m_pBrightnessLabel); vecTemp.fX = 11; @@ -784,13 +1270,23 @@ void CSettings::CreateGUI() m_pAnisotropic = reinterpret_cast(pManager->CreateScrollBar(true, pTabVideo)); m_pAnisotropic->SetPosition(CVector2D(vecTemp.fX + fIndentX + 5.0f, vecTemp.fY)); m_pAnisotropic->GetPosition(vecTemp, false); - m_pAnisotropic->SetSize(CVector2D(160.0f, 20.0f)); + const CVector2D anisotropicSliderPos = vecTemp; + const float anisotropicSliderWidth = ComputeSliderWidth(tabPanelSize.fX, anisotropicSliderPos.fX, 160.0f); + m_pAnisotropic->SetSize(CVector2D(anisotropicSliderWidth, 20.0f)); m_pAnisotropic->GetSize(vecSize); m_pAnisotropic->SetProperty("StepSize", SString("%1.2f", 1 / (float)m_iMaxAnisotropic)); m_pAnisotropicValueLabel = reinterpret_cast(pManager->CreateLabel(pTabVideo, _("Off"))); - m_pAnisotropicValueLabel->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 5.0f, vecTemp.fY)); - m_pAnisotropicValueLabel->SetSize(CVector2D(100.0f, 20.0f)); + m_pAnisotropicValueLabel->SetPosition(CVector2D(anisotropicSliderPos.fX + vecSize.fX + kSliderLabelSpacing, anisotropicSliderPos.fY)); + + const SString anisotropicOffText = _("Off"); + const SString anisotropicMaxText = (m_iMaxAnisotropic > 0) ? SString("%ix", 1 << m_iMaxAnisotropic) : anisotropicOffText; + const float anisotropicOffExtent = pManager->GetTextExtent(anisotropicOffText); + const float anisotropicMaxExtent = pManager->GetTextExtent(anisotropicMaxText); + const SString anisotropicSizeHint = (anisotropicMaxExtent > anisotropicOffExtent) ? anisotropicMaxText : anisotropicOffText; + const SString anisotropicSizePadding("%s ", anisotropicSizeHint.c_str()); + m_pAnisotropicValueLabel->AutoSize(anisotropicSizePadding); + FinalizeSliderRow(tabPanelSize.fX, m_pAnisotropic, m_pAnisotropicValueLabel, 160.0f, kSliderLabelSpacing, m_pAnisotropicLabel); if (m_iMaxAnisotropic < 1) { @@ -920,9 +1416,104 @@ void CSettings::CreateGUI() m_pVideoDefButton->SetClickHandler(GUI_CALLBACK(&CSettings::OnVideoDefaultClick, this)); m_pVideoDefButton->AutoSize(NULL, 20.0f, 8.0f); m_pVideoDefButton->GetSize(vecSize); - m_pVideoDefButton->SetPosition(CVector2D(vecTemp.fX - vecSize.fX - 12.0f, 387)); + placeBottomRightButton(m_pVideoDefButton); m_pVideoDefButton->SetZOrderingEnabled(false); + /** + * PostFX tab + **/ + CVector2D postFxPos(12.0f, 12.0f); + const float postFxRowHeight = 28.0f; + const float postFxValueColumnPadding = 10.0f; + const float postFxCheckboxColumnX = postFxPos.fX; + const float postFxLabelColumnX = postFxCheckboxColumnX + kPostFxCheckboxOffset; + const float postFxLabelIndent = pManager->CGUI_GetMaxTextExtent("default-normal", _("Gamma:"), _("Brightness:"), _("Contrast:"), _("Saturation:")) + 5.0f; + const float postFxSliderColumnX = postFxLabelColumnX + postFxLabelIndent; + const float postFxValueColumnReserve = postFxValueColumnPadding + 60.0f; + const float postFxSliderWidth = ComputeSliderWidth(tabPanelSize.fX, postFxSliderColumnX, 220.0f, postFxValueColumnReserve); + const float postFxValueColumnX = postFxSliderColumnX + postFxSliderWidth + postFxValueColumnPadding; + + m_pBorderlessGammaToggle = reinterpret_cast(pManager->CreateCheckBox(m_pTabPostFX, _("Gamma:"))); + m_pBorderlessGammaToggle->SetPosition(CVector2D(postFxCheckboxColumnX, postFxPos.fY)); + m_pBorderlessGammaToggle->AutoSize(nullptr, 20.0f); + + m_pBorderlessGamma = reinterpret_cast(pManager->CreateScrollBar(true, m_pTabPostFX)); + m_pBorderlessGamma->SetPosition(CVector2D(postFxSliderColumnX, postFxPos.fY)); + m_pBorderlessGamma->SetSize(CVector2D(postFxSliderWidth, 20.0f)); + m_pBorderlessGamma->SetProperty("StepSize", "0.01"); + + m_pBorderlessGammaValueLabel = reinterpret_cast(pManager->CreateLabel(m_pTabPostFX, "")); + m_pBorderlessGammaValueLabel->SetPosition(CVector2D(postFxValueColumnX, postFxPos.fY + 2.0f)); + m_pBorderlessGammaValueLabel->AutoSize("2.00x"); + FinalizeSliderRow(tabPanelSize.fX, m_pBorderlessGamma, m_pBorderlessGammaValueLabel, 220.0f, kSliderLabelSpacing); + + postFxPos.fY += postFxRowHeight; + + m_pBorderlessBrightnessToggle = reinterpret_cast(pManager->CreateCheckBox(m_pTabPostFX, _("Brightness:"))); + m_pBorderlessBrightnessToggle->SetPosition(CVector2D(postFxCheckboxColumnX, postFxPos.fY)); + m_pBorderlessBrightnessToggle->AutoSize(nullptr, 20.0f); + + m_pBorderlessBrightness = reinterpret_cast(pManager->CreateScrollBar(true, m_pTabPostFX)); + m_pBorderlessBrightness->SetPosition(CVector2D(postFxSliderColumnX, postFxPos.fY)); + m_pBorderlessBrightness->SetSize(CVector2D(postFxSliderWidth, 20.0f)); + m_pBorderlessBrightness->SetProperty("StepSize", "0.01"); + + m_pBorderlessBrightnessValueLabel = reinterpret_cast(pManager->CreateLabel(m_pTabPostFX, "")); + m_pBorderlessBrightnessValueLabel->SetPosition(CVector2D(postFxValueColumnX, postFxPos.fY + 2.0f)); + m_pBorderlessBrightnessValueLabel->AutoSize("2.00x"); + FinalizeSliderRow(tabPanelSize.fX, m_pBorderlessBrightness, m_pBorderlessBrightnessValueLabel, 220.0f, kSliderLabelSpacing); + + postFxPos.fY += postFxRowHeight; + + m_pBorderlessContrastToggle = reinterpret_cast(pManager->CreateCheckBox(m_pTabPostFX, _("Contrast:"))); + m_pBorderlessContrastToggle->SetPosition(CVector2D(postFxCheckboxColumnX, postFxPos.fY)); + m_pBorderlessContrastToggle->AutoSize(nullptr, 20.0f); + + m_pBorderlessContrast = reinterpret_cast(pManager->CreateScrollBar(true, m_pTabPostFX)); + m_pBorderlessContrast->SetPosition(CVector2D(postFxSliderColumnX, postFxPos.fY)); + m_pBorderlessContrast->SetSize(CVector2D(postFxSliderWidth, 20.0f)); + m_pBorderlessContrast->SetProperty("StepSize", "0.01"); + + m_pBorderlessContrastValueLabel = reinterpret_cast(pManager->CreateLabel(m_pTabPostFX, "")); + m_pBorderlessContrastValueLabel->SetPosition(CVector2D(postFxValueColumnX, postFxPos.fY + 2.0f)); + m_pBorderlessContrastValueLabel->AutoSize("2.00x"); + FinalizeSliderRow(tabPanelSize.fX, m_pBorderlessContrast, m_pBorderlessContrastValueLabel, 220.0f, kSliderLabelSpacing); + + postFxPos.fY += postFxRowHeight; + + m_pBorderlessSaturationToggle = reinterpret_cast(pManager->CreateCheckBox(m_pTabPostFX, _("Saturation:"))); + m_pBorderlessSaturationToggle->SetPosition(CVector2D(postFxCheckboxColumnX, postFxPos.fY)); + m_pBorderlessSaturationToggle->AutoSize(nullptr, 20.0f); + + m_pBorderlessSaturation = reinterpret_cast(pManager->CreateScrollBar(true, m_pTabPostFX)); + m_pBorderlessSaturation->SetPosition(CVector2D(postFxSliderColumnX, postFxPos.fY)); + m_pBorderlessSaturation->SetSize(CVector2D(postFxSliderWidth, 20.0f)); + m_pBorderlessSaturation->SetProperty("StepSize", "0.01"); + + m_pBorderlessSaturationValueLabel = reinterpret_cast(pManager->CreateLabel(m_pTabPostFX, "")); + m_pBorderlessSaturationValueLabel->SetPosition(CVector2D(postFxValueColumnX, postFxPos.fY + 2.0f)); + m_pBorderlessSaturationValueLabel->AutoSize("2.00x"); + FinalizeSliderRow(tabPanelSize.fX, m_pBorderlessSaturation, m_pBorderlessSaturationValueLabel, 220.0f, kSliderLabelSpacing); + + postFxPos.fY += postFxRowHeight + 8.0f; + + m_pCheckBoxApplyBorderless = reinterpret_cast(pManager->CreateCheckBox(m_pTabPostFX, _("Apply adjustments in windowed/borderless mode"))); + m_pCheckBoxApplyBorderless->SetPosition(CVector2D(postFxCheckboxColumnX, postFxPos.fY)); + m_pCheckBoxApplyBorderless->AutoSize(nullptr, 20.0f); + + postFxPos.fY += 22.0f; + + m_pCheckBoxApplyFullscreen = reinterpret_cast(pManager->CreateCheckBox(m_pTabPostFX, _("Apply adjustments in fullscreen mode"))); + m_pCheckBoxApplyFullscreen->SetPosition(CVector2D(postFxCheckboxColumnX, postFxPos.fY)); + m_pCheckBoxApplyFullscreen->AutoSize(nullptr, 20.0f); + + m_pPostFXDefButton = reinterpret_cast(pManager->CreateButton(m_pTabPostFX, _("Load defaults"))); + m_pPostFXDefButton->SetClickHandler(GUI_CALLBACK(&CSettings::OnPostFXDefaultClick, this)); + m_pPostFXDefButton->AutoSize(NULL, 20.0f, 8.0f); + m_pPostFXDefButton->GetSize(vecSize); + placeBottomRightButton(m_pPostFXDefButton); + m_pPostFXDefButton->SetZOrderingEnabled(false); + /** * Interface/chat Tab **/ @@ -931,8 +1522,21 @@ void CSettings::CreateGUI() /** * Webbrowser tab **/ + const float browserListButtonWidth = 90.0f; + const float browserMargin = 10.0f; + const float availableBrowserWidth = std::max(0.0f, tabPanelSize.fX - browserMargin * 2.0f); + float browserColumnWidth = (availableBrowserWidth - kBrowserColumnSpacing) * 0.5f; + if (browserColumnWidth < kBrowserColumnMinWidth && availableBrowserWidth >= kBrowserColumnMinWidth * 2.0f + kBrowserColumnSpacing) + browserColumnWidth = kBrowserColumnMinWidth; + else + browserColumnWidth = std::max(0.0f, browserColumnWidth); + if (browserColumnWidth * 2.0f + kBrowserColumnSpacing > availableBrowserWidth) + browserColumnWidth = std::max(0.0f, (availableBrowserWidth - kBrowserColumnSpacing) * 0.5f); + const float browserLeftColumnX = browserMargin; + const float browserRightColumnX = browserLeftColumnX + browserColumnWidth + kBrowserColumnSpacing; + m_pLabelBrowserGeneral = reinterpret_cast(pManager->CreateLabel(m_pTabBrowser, _("General"))); - m_pLabelBrowserGeneral->SetPosition(CVector2D(10.0f, 12.0f)); + m_pLabelBrowserGeneral->SetPosition(CVector2D(browserLeftColumnX, 12.0f)); m_pLabelBrowserGeneral->GetPosition(vecTemp); m_pLabelBrowserGeneral->AutoSize(NULL, 5.0f); m_pLabelBrowserGeneral->SetFont("default-bold-small"); @@ -948,7 +1552,7 @@ void CSettings::CreateGUI() m_pCheckBoxRemoteJavascript->AutoSize(NULL, 20.0f); m_pCheckBoxBrowserGPUEnabled = reinterpret_cast(pManager->CreateCheckBox(m_pTabBrowser, _("Enable GPU rendering"), true)); - m_pCheckBoxBrowserGPUEnabled->SetPosition(CVector2D(vecTemp.fX + 300.0f, vecTemp.fY - 25.0f)); + m_pCheckBoxBrowserGPUEnabled->SetPosition(CVector2D(browserRightColumnX, vecTemp.fY - 25.0f)); m_pCheckBoxBrowserGPUEnabled->AutoSize(NULL, 20.0f); m_pLabelBrowserCustomBlacklist = reinterpret_cast(pManager->CreateLabel(m_pTabBrowser, _("Custom blacklist"))); @@ -960,7 +1564,7 @@ void CSettings::CreateGUI() m_pEditBrowserBlacklistAdd = reinterpret_cast(pManager->CreateEdit(m_pTabBrowser)); m_pEditBrowserBlacklistAdd->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 25.0f)); m_pEditBrowserBlacklistAdd->GetPosition(vecTemp); - m_pEditBrowserBlacklistAdd->SetSize(CVector2D(209.0f, 22.0f)); + m_pEditBrowserBlacklistAdd->SetSize(CVector2D(browserColumnWidth - browserListButtonWidth, 22.0f)); m_pLabelBrowserBlacklistAdd = reinterpret_cast(pManager->CreateLabel(m_pEditBrowserBlacklistAdd, _("Enter a domain e.g. google.com"))); m_pLabelBrowserBlacklistAdd->SetPosition(CVector2D(10.0f, 3.0f), false); @@ -977,17 +1581,30 @@ void CSettings::CreateGUI() m_pGridBrowserBlacklist = reinterpret_cast(pManager->CreateGridList(m_pTabBrowser)); m_pGridBrowserBlacklist->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 32.0f)); m_pGridBrowserBlacklist->GetPosition(vecTemp); - m_pGridBrowserBlacklist->SetSize(CVector2D(300.0f, 150.0f)); + const CVector2D blacklistGridPos = vecTemp; + const float browserBottomPadding = 32.0f; + const float browserButtonSpacing = 5.0f; + const CVector2D blacklistRemoveSize(155.0f, 22.0f); + const CVector2D blacklistRemoveAllSize(155.0f, 22.0f); + const float blacklistRemoveAllSpacing = 165.0f; + const float blacklistHeightAvailable = tabPanelSize.fY - blacklistGridPos.fY - blacklistRemoveSize.fY - browserButtonSpacing - browserBottomPadding; + m_pGridBrowserBlacklist->SetSize(CVector2D(browserColumnWidth, std::max(80.0f, blacklistHeightAvailable))); m_pGridBrowserBlacklist->AddColumn(_("Domain"), 0.9f); m_pButtonBrowserBlacklistRemove = reinterpret_cast(pManager->CreateButton(m_pTabBrowser, _("Remove domain"))); - m_pButtonBrowserBlacklistRemove->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + m_pGridBrowserBlacklist->GetSize().fY + 5.0f)); - m_pButtonBrowserBlacklistRemove->SetSize(CVector2D(140.0f, 22.0f)); + m_pButtonBrowserBlacklistRemove->SetSize(blacklistRemoveSize); + m_pButtonBrowserBlacklistRemove->SetPosition( + CVector2D(blacklistGridPos.fX, blacklistGridPos.fY + m_pGridBrowserBlacklist->GetSize().fY + browserButtonSpacing)); - m_pLabelBrowserCustomBlacklist->GetPosition(vecTemp); // Reset vecTemp + m_pButtonBrowserBlacklistRemoveAll = reinterpret_cast(pManager->CreateButton(m_pTabBrowser, _("Remove all"))); + m_pButtonBrowserBlacklistRemoveAll->SetSize(blacklistRemoveAllSize); + m_pButtonBrowserBlacklistRemoveAll->SetPosition( + CVector2D(vecTemp.fX + blacklistRemoveAllSpacing, vecTemp.fY + m_pGridBrowserBlacklist->GetSize().fY + browserButtonSpacing)); + + m_pLabelBrowserCustomBlacklist->GetPosition(vecTemp); // Reset vecTemp m_pLabelBrowserCustomWhitelist = reinterpret_cast(pManager->CreateLabel(m_pTabBrowser, _("Custom whitelist"))); - m_pLabelBrowserCustomWhitelist->SetPosition(CVector2D(vecTemp.fX + 300.0f + 19.0f, vecTemp.fY)); + m_pLabelBrowserCustomWhitelist->SetPosition(CVector2D(browserRightColumnX, vecTemp.fY)); m_pLabelBrowserCustomWhitelist->GetPosition(vecTemp); m_pLabelBrowserCustomWhitelist->AutoSize(NULL, 20.0f); m_pLabelBrowserCustomWhitelist->SetFont("default-bold-small"); @@ -995,7 +1612,7 @@ void CSettings::CreateGUI() m_pEditBrowserWhitelistAdd = reinterpret_cast(pManager->CreateEdit(m_pTabBrowser)); m_pEditBrowserWhitelistAdd->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 25.0f)); m_pEditBrowserWhitelistAdd->GetPosition(vecTemp); - m_pEditBrowserWhitelistAdd->SetSize(CVector2D(209.0f, 22.0f)); + m_pEditBrowserWhitelistAdd->SetSize(CVector2D(browserColumnWidth - browserListButtonWidth, 22.0f)); m_pLabelBrowserWhitelistAdd = reinterpret_cast(pManager->CreateLabel(m_pEditBrowserWhitelistAdd, _("Enter a domain e.g. google.com"))); m_pLabelBrowserWhitelistAdd->SetPosition(CVector2D(10.0f, 3.0f), false); @@ -1012,12 +1629,23 @@ void CSettings::CreateGUI() m_pGridBrowserWhitelist = reinterpret_cast(pManager->CreateGridList(m_pTabBrowser)); m_pGridBrowserWhitelist->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 32.0f)); m_pGridBrowserWhitelist->GetPosition(vecTemp); - m_pGridBrowserWhitelist->SetSize(CVector2D(300.0f, 150.0f)); + const CVector2D whitelistGridPos = vecTemp; + const CVector2D whitelistRemoveSize(155.0f, 22.0f); + const CVector2D whitelistRemoveAllSize(155.0f, 22.0f); + const float whitelistRemoveAllSpacing = 165.0f; + const float whitelistHeightAvailable = tabPanelSize.fY - whitelistGridPos.fY - whitelistRemoveSize.fY - browserButtonSpacing - browserBottomPadding; + m_pGridBrowserWhitelist->SetSize(CVector2D(browserColumnWidth, std::max(80.0f, whitelistHeightAvailable))); m_pGridBrowserWhitelist->AddColumn(_("Domain"), 0.9f); m_pButtonBrowserWhitelistRemove = reinterpret_cast(pManager->CreateButton(m_pTabBrowser, _("Remove domain"))); - m_pButtonBrowserWhitelistRemove->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + m_pGridBrowserWhitelist->GetSize().fY + 5.0f)); - m_pButtonBrowserWhitelistRemove->SetSize(CVector2D(140.0f, 22.0f)); + m_pButtonBrowserWhitelistRemove->SetSize(whitelistRemoveSize); + m_pButtonBrowserWhitelistRemove->SetPosition( + CVector2D(whitelistGridPos.fX, whitelistGridPos.fY + m_pGridBrowserWhitelist->GetSize().fY + browserButtonSpacing)); + + m_pButtonBrowserWhitelistRemoveAll = reinterpret_cast(pManager->CreateButton(m_pTabBrowser, _("Remove all"))); + m_pButtonBrowserWhitelistRemoveAll->SetSize(whitelistRemoveAllSize); + m_pButtonBrowserWhitelistRemoveAll->SetPosition( + CVector2D(vecTemp.fX + whitelistRemoveAllSpacing, vecTemp.fY + m_pGridBrowserWhitelist->GetSize().fY + browserButtonSpacing)); /** * Advanced tab @@ -1162,13 +1790,26 @@ void CSettings::CreateGUI() m_pStreamingMemory = reinterpret_cast(pManager->CreateScrollBar(true, pTabAdvanced)); m_pStreamingMemory->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 5.0f, vecTemp.fY)); m_pStreamingMemory->GetPosition(vecTemp); - m_pStreamingMemory->SetSize(CVector2D(130.0f, 20.0f)); + const float streamingSliderWidth = ComputeSliderWidth(tabPanelSize.fX, vecTemp.fX, 130.0f, 65.0f); + m_pStreamingMemory->SetSize(CVector2D(streamingSliderWidth, 20.0f)); m_pStreamingMemory->GetSize(vecSize); - m_pStreamingMemory->SetProperty("StepSize", SString("%.07lf", 1.0 / (uiMaxMemory - uiMinMemory))); + + const unsigned int uiStreamingRange = (uiMaxMemory > uiMinMemory) ? (uiMaxMemory - uiMinMemory) : 0u; + if (uiStreamingRange > 0u) + { + m_pStreamingMemory->SetProperty("StepSize", SString("%.07lf", 1.0 / static_cast(uiStreamingRange))); + m_pStreamingMemory->SetEnabled(true); + } + else + { + m_pStreamingMemory->SetProperty("StepSize", "1.0"); + m_pStreamingMemory->SetEnabled(false); + } m_pStreamingMemoryMaxLabel = reinterpret_cast(pManager->CreateLabel(pTabAdvanced, _("Max"))); m_pStreamingMemoryMaxLabel->SetPosition(CVector2D(vecTemp.fX + vecSize.fX + 5.0f, vecTemp.fY)); m_pStreamingMemoryMaxLabel->AutoSize(); + FinalizeSliderRow(tabPanelSize.fX, m_pStreamingMemory, m_pStreamingMemoryMaxLabel, 130.0f, 5.0f, m_pStreamingMemoryMinLabel); vecTemp.fX = 22.f; vecTemp.fY += fLineHeight; @@ -1191,7 +1832,7 @@ void CSettings::CreateGUI() // Hide if not Win8 if (atoi(GetApplicationSetting("real-os-version")) != 8) { -#ifndef MTA_DEBUG // Don't hide when debugging +#ifndef MTA_DEBUG // Don't hide when debugging m_pWin8Label->SetVisible(false); m_pWin8ColorCheckBox->SetVisible(false); m_pWin8MouseCheckBox->SetVisible(false); @@ -1219,7 +1860,8 @@ void CSettings::CreateGUI() vecTemp.fY += fLineHeight; // Process affinity - m_pProcessAffinityCheckbox = reinterpret_cast(pManager->CreateCheckBox(pTabAdvanced, _("Set CPU 0 affinity to improve game performance"), true)); + m_pProcessAffinityCheckbox = + reinterpret_cast(pManager->CreateCheckBox(pTabAdvanced, _("Set CPU 0 affinity to improve game performance"), true)); m_pProcessAffinityCheckbox->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY)); m_pProcessAffinityCheckbox->AutoSize(nullptr, 20.0f); vecTemp.fY += fLineHeight; @@ -1303,6 +1945,16 @@ void CSettings::CreateGUI() m_pFieldOfView->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnFieldOfViewChanged, this)); m_pDrawDistance->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnDrawDistanceChanged, this)); m_pBrightness->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnBrightnessChanged, this)); + m_pBorderlessGamma->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnBorderlessGammaChanged, this)); + m_pBorderlessBrightness->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnBorderlessBrightnessChanged, this)); + m_pBorderlessContrast->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnBorderlessContrastChanged, this)); + m_pBorderlessSaturation->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnBorderlessSaturationChanged, this)); + m_pBorderlessGammaToggle->SetClickHandler(GUI_CALLBACK(&CSettings::OnBorderlessGammaToggleClicked, this)); + m_pBorderlessBrightnessToggle->SetClickHandler(GUI_CALLBACK(&CSettings::OnBorderlessBrightnessToggleClicked, this)); + m_pBorderlessContrastToggle->SetClickHandler(GUI_CALLBACK(&CSettings::OnBorderlessContrastToggleClicked, this)); + m_pBorderlessSaturationToggle->SetClickHandler(GUI_CALLBACK(&CSettings::OnBorderlessSaturationToggleClicked, this)); + m_pCheckBoxApplyBorderless->SetClickHandler(GUI_CALLBACK(&CSettings::OnBorderlessApplyBorderlessClicked, this)); + m_pCheckBoxApplyFullscreen->SetClickHandler(GUI_CALLBACK(&CSettings::OnBorderlessApplyFullscreenClicked, this)); m_pAnisotropic->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnAnisotropicChanged, this)); m_pMouseSensitivity->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnMouseSensitivityChanged, this)); m_pVerticalAimSensitivity->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnVerticalAimSensitivityChanged, this)); @@ -1314,16 +1966,20 @@ void CSettings::CreateGUI() m_pCheckBoxCustomizedSAFiles->SetClickHandler(GUI_CALLBACK(&CSettings::OnCustomizedSAFilesClick, this)); m_pCheckBoxWindowed->SetClickHandler(GUI_CALLBACK(&CSettings::OnWindowedClick, this)); m_pCheckBoxDPIAware->SetClickHandler(GUI_CALLBACK(&CSettings::OnDPIAwareClick, this)); + m_pCheckBoxVSync->SetClickHandler(GUI_CALLBACK(&CSettings::OnVSyncClick, this)); m_pCheckBoxShowUnsafeResolutions->SetClickHandler(GUI_CALLBACK(&CSettings::ShowUnsafeResolutionsClick, this)); m_pButtonBrowserBlacklistAdd->SetClickHandler(GUI_CALLBACK(&CSettings::OnBrowserBlacklistAdd, this)); m_pButtonBrowserBlacklistRemove->SetClickHandler(GUI_CALLBACK(&CSettings::OnBrowserBlacklistRemove, this)); + m_pButtonBrowserBlacklistRemoveAll->SetClickHandler(GUI_CALLBACK(&CSettings::OnBrowserBlacklistRemoveAll, this)); m_pEditBrowserBlacklistAdd->SetActivateHandler(GUI_CALLBACK(&CSettings::OnBrowserBlacklistDomainAddFocused, this)); m_pEditBrowserBlacklistAdd->SetDeactivateHandler(GUI_CALLBACK(&CSettings::OnBrowserBlacklistDomainAddDefocused, this)); m_pButtonBrowserWhitelistAdd->SetClickHandler(GUI_CALLBACK(&CSettings::OnBrowserWhitelistAdd, this)); m_pButtonBrowserWhitelistRemove->SetClickHandler(GUI_CALLBACK(&CSettings::OnBrowserWhitelistRemove, this)); + m_pButtonBrowserWhitelistRemoveAll->SetClickHandler(GUI_CALLBACK(&CSettings::OnBrowserWhitelistRemoveAll, this)); m_pEditBrowserWhitelistAdd->SetActivateHandler(GUI_CALLBACK(&CSettings::OnBrowserWhitelistDomainAddFocused, this)); m_pEditBrowserWhitelistAdd->SetDeactivateHandler(GUI_CALLBACK(&CSettings::OnBrowserWhitelistDomainAddDefocused, this)); m_pProcessAffinityCheckbox->SetClickHandler(GUI_CALLBACK(&CSettings::OnAffinityClick, this)); + m_pCheckboxVerticalAimSensitivity->SetClickHandler(GUI_CALLBACK(&CSettings::OnMouseAimingClick, this)); // Set up the events for advanced description m_pPriorityLabel->SetMouseEnterHandler(GUI_CALLBACK(&CSettings::OnShowAdvancedSettingDescription, this)); @@ -1404,11 +2060,25 @@ void CSettings::CreateGUI() void CSettings::DestroyGUI() { - // Destroy - delete m_pButtonCancel; - delete m_pButtonOK; - delete m_pWindow; - m_pWindow = NULL; + if (!m_pWindow) + { + RemoveAllKeyBindSections(); + m_bBrowserListsChanged = false; + m_bBrowserListsLoadEnabled = false; + m_pSelectedBind = NULL; + ResetGuiPointers(); + return; + } + + g_pCore->GetGUI()->DestroyElementRecursive(m_pWindow); + m_pWindow = nullptr; + + RemoveAllKeyBindSections(); + m_bBrowserListsChanged = false; + m_bBrowserListsLoadEnabled = false; + m_pSelectedBind = NULL; + + ResetGuiPointers(); } void RestartCallBack(void* ptr, unsigned int uiButton) @@ -1542,6 +2212,8 @@ void CSettings::UpdateVideoTab() m_pDrawDistance->SetScrollPosition((gameSettings->GetDrawDistance() - 0.925f) / 0.8749f); m_pBrightness->SetScrollPosition((float)gameSettings->GetBrightness() / 384); + UpdatePostFxTab(); + // DPI aware bool processDPIAware = false; CVARS_GET("process_dpi_aware", processDPIAware); @@ -1567,14 +2239,14 @@ void CSettings::UpdateVideoTab() else if (FxQuality == 3) m_pComboFxQuality->SetText(_("Very high")); - char AntiAliasing = gameSettings->GetAntiAliasing(); - if (AntiAliasing == 1) + unsigned int antiAliasing = gameSettings->GetAntiAliasing(); + if (antiAliasing == 1) m_pComboAntiAliasing->SetText(_("Off")); - else if (AntiAliasing == 2) + else if (antiAliasing == 2) m_pComboAntiAliasing->SetText(_("1x")); - else if (AntiAliasing == 3) + else if (antiAliasing == 3) m_pComboAntiAliasing->SetText(_("2x")); - else if (AntiAliasing == 4) + else if (antiAliasing == 4) m_pComboAntiAliasing->SetText(_("3x")); // Aspect ratio @@ -1683,6 +2355,15 @@ void CSettings::UpdateVideoTab() m_pPlayerMapImageCombo->SetSelectedItemByIndex(iVar); } +struct ResolutionData +{ + int width; + int height; + int depth; + int vidMode; + bool isWidescreen; +}; + // // PopulateResolutionComboBox // @@ -1696,47 +2377,88 @@ void CSettings::PopulateResolutionComboBox() bool bShowUnsafeResolutions = m_pCheckBoxShowUnsafeResolutions->GetSelected(); CGameSettings* gameSettings = CCore::GetSingleton().GetGame()->GetSettings(); + if (!gameSettings) + return; - VideoMode vidModemInfo; - int vidMode, numVidModes; + VideoMode vidModemInfo; + int vidMode, numVidModes; + std::vector resolutions; + + if (!m_pComboResolution) + return; m_pComboResolution->Clear(); numVidModes = gameSettings->GetNumVideoModes(); for (vidMode = 0; vidMode < numVidModes; vidMode++) { - gameSettings->GetVideoModeInfo(&vidModemInfo, vidMode); + if (!gameSettings->GetVideoModeInfo(&vidModemInfo, vidMode)) + continue; // Remove resolutions that will make the gui unusable if (vidModemInfo.width < 640 || vidModemInfo.height < 480) continue; + // Check resolution is below desktop res unless that is allowed + if (gameSettings->IsUnsafeResolution(vidModemInfo.width, vidModemInfo.height) && !bShowUnsafeResolutions) + continue; + + if (!(vidModemInfo.flags & rwVIDEOMODEEXCLUSIVE)) + continue; + + ResolutionData resData; + resData.width = vidModemInfo.width; + resData.height = vidModemInfo.height; + resData.depth = vidModemInfo.depth; + resData.vidMode = vidMode; + resData.isWidescreen = (vidModemInfo.flags & rwVIDEOMODE_XBOX_WIDESCREEN) != 0; + // Check resolution hasn't already been added bool bDuplicate = false; - for (int i = 1; i < vidMode; i++) + for (const auto& existing : resolutions) { - VideoMode info; - gameSettings->GetVideoModeInfo(&info, i); - if (info.width == vidModemInfo.width && info.height == vidModemInfo.height && info.depth == vidModemInfo.depth) + if (existing.width == resData.width && existing.height == resData.height && existing.depth == resData.depth) + { bDuplicate = true; + break; + } } - if (bDuplicate) - continue; - // Check resolution is below desktop res unless that is allowed - if (gameSettings->IsUnsafeResolution(vidModemInfo.width, vidModemInfo.height) && !bShowUnsafeResolutions) - continue; + if (!bDuplicate) + resolutions.push_back(resData); + } - SString strMode("%lu x %lu x %lu", vidModemInfo.width, vidModemInfo.height, vidModemInfo.depth); + if (resolutions.empty()) + return; - if (vidModemInfo.flags & rwVIDEOMODEEXCLUSIVE) - m_pComboResolution->AddItem(strMode)->SetData((void*)vidMode); + // Sort resolutions by width (descending), then by height, then by depth + std::sort(resolutions.begin(), resolutions.end(), + [](const ResolutionData& a, const ResolutionData& b) + { + if (a.width != b.width) + return a.width > b.width; + if (a.height != b.height) + return a.height > b.height; + return a.depth > b.depth; + }); + + SString selectedText; + VideoMode currentInfo; + if (gameSettings->GetVideoModeInfo(¤tInfo, iNextVidMode)) + { + for (const auto& res : resolutions) + { + SString strMode("%d x %d x %d", res.width, res.height, res.depth); + CGUIListItem* pItem = m_pComboResolution->AddItem(strMode); + if (pItem) + pItem->SetData((void*)res.vidMode); - VideoMode currentInfo; - gameSettings->GetVideoModeInfo(¤tInfo, iNextVidMode); + if (currentInfo.width == res.width && currentInfo.height == res.height && currentInfo.depth == res.depth) + selectedText = strMode; + } - if (currentInfo.width == vidModemInfo.width && currentInfo.height == vidModemInfo.height && currentInfo.depth == vidModemInfo.depth) - m_pComboResolution->SetText(strMode); + if (!selectedText.empty()) + m_pComboResolution->SetText(selectedText); } } @@ -1758,7 +2480,6 @@ void CSettings::UpdateFullScreenComboBoxEnabled() m_pFullscreenStyleCombo->SetEnabled(true); } } - // // Saves the Joypad settings // @@ -1771,6 +2492,67 @@ void CSettings::ProcessJoypad() GetJoystickManager()->SaveToXML(); } +void CSettings::UpdatePostFxTab() +{ + bool applyWindowed = false; + bool applyFullscreen = false; + bool gammaEnabled = false; + bool brightnessEnabled = false; + bool contrastEnabled = false; + bool saturationEnabled = false; + float gammaValue = kBorderlessGammaDefault; + float brightnessValue = kBorderlessBrightnessDefault; + float contrastValue = kBorderlessContrastDefault; + float saturationValue = kBorderlessSaturationDefault; + + CVARS_GET("borderless_apply_windowed", applyWindowed); + CVARS_GET("borderless_apply_fullscreen", applyFullscreen); + CVARS_GET("borderless_gamma_enabled", gammaEnabled); + CVARS_GET("borderless_brightness_enabled", brightnessEnabled); + CVARS_GET("borderless_contrast_enabled", contrastEnabled); + CVARS_GET("borderless_saturation_enabled", saturationEnabled); + CVARS_GET("borderless_gamma_power", gammaValue); + CVARS_GET("borderless_brightness_scale", brightnessValue); + CVARS_GET("borderless_contrast_scale", contrastValue); + CVARS_GET("borderless_saturation_scale", saturationValue); + + if (m_pBorderlessGammaToggle) + m_pBorderlessGammaToggle->SetSelected(gammaEnabled); + if (m_pBorderlessBrightnessToggle) + m_pBorderlessBrightnessToggle->SetSelected(brightnessEnabled); + if (m_pBorderlessContrastToggle) + m_pBorderlessContrastToggle->SetSelected(contrastEnabled); + if (m_pBorderlessSaturationToggle) + m_pBorderlessSaturationToggle->SetSelected(saturationEnabled); + + if (m_pBorderlessGamma) + m_pBorderlessGamma->SetScrollPosition(NormalizeSliderValue(gammaValue, kBorderlessGammaMin, kBorderlessGammaMax)); + if (m_pBorderlessGammaValueLabel) + m_pBorderlessGammaValueLabel->SetText(SString("%.2fx", gammaValue).c_str()); + + if (m_pBorderlessBrightness) + m_pBorderlessBrightness->SetScrollPosition(NormalizeSliderValue(brightnessValue, kBorderlessBrightnessMin, kBorderlessBrightnessMax)); + if (m_pBorderlessBrightnessValueLabel) + m_pBorderlessBrightnessValueLabel->SetText(SString("%.2fx", brightnessValue).c_str()); + + if (m_pBorderlessContrast) + m_pBorderlessContrast->SetScrollPosition(NormalizeSliderValue(contrastValue, kBorderlessContrastMin, kBorderlessContrastMax)); + if (m_pBorderlessContrastValueLabel) + m_pBorderlessContrastValueLabel->SetText(SString("%.2fx", contrastValue).c_str()); + + if (m_pBorderlessSaturation) + m_pBorderlessSaturation->SetScrollPosition(NormalizeSliderValue(saturationValue, kBorderlessSaturationMin, kBorderlessSaturationMax)); + if (m_pBorderlessSaturationValueLabel) + m_pBorderlessSaturationValueLabel->SetText(SString("%.2fx", saturationValue).c_str()); + + if (m_pCheckBoxApplyBorderless) + m_pCheckBoxApplyBorderless->SetSelected(applyWindowed); + if (m_pCheckBoxApplyFullscreen) + m_pCheckBoxApplyFullscreen->SetSelected(applyFullscreen); + + UpdateBorderlessAdjustmentControls(); +} + // // Update GUI elements for the Joypad Tab // @@ -1815,8 +2597,8 @@ void CSettings::UpdateJoypadTab() // Update axes labels and buttons for (int i = 0; i < JoyMan->GetOutputCount() && i < (int)m_pJoypadButtons.size(); i++) { - string outputName = JoyMan->GetOutputName(i); // LeftStickPosX etc - string inputName = JoyMan->GetOutputInputName(i); // X+ or RZ- etc + string outputName = JoyMan->GetOutputName(i); // LeftStickPosX etc + string inputName = JoyMan->GetOutputInputName(i); // X+ or RZ- etc CGUILabel* pLabel = m_pJoypadLabels[i]; pLabel->SetText(outputName.c_str()); @@ -1883,8 +2665,18 @@ bool CSettings::OnVideoDefaultClick(CGUIElement* pElement) CVARS_SET("blur", true); CVARS_SET("corona_reflections", false); CVARS_SET("dynamic_ped_shadows", false); + CVARS_SET("borderless_gamma_power", kBorderlessGammaDefault); + CVARS_SET("borderless_brightness_scale", kBorderlessBrightnessDefault); + CVARS_SET("borderless_contrast_scale", kBorderlessContrastDefault); + CVARS_SET("borderless_saturation_scale", kBorderlessSaturationDefault); + CVARS_SET("borderless_gamma_enabled", false); + CVARS_SET("borderless_brightness_enabled", false); + CVARS_SET("borderless_contrast_enabled", false); + CVARS_SET("borderless_saturation_enabled", false); + CVARS_SET("borderless_apply_windowed", false); + CVARS_SET("borderless_apply_fullscreen", false); gameSettings->UpdateFieldOfViewFromSettings(); - gameSettings->SetDrawDistance(1.19625f); // All values taken from a default SA install, no gta_sa.set or coreconfig.xml modifications. + gameSettings->SetDrawDistance(1.19625f); // All values taken from a default SA install, no gta_sa.set or coreconfig.xml modifications. gameSettings->SetBrightness(253); gameSettings->SetFXQuality(2); gameSettings->SetAntiAliasing(1, true); @@ -1908,10 +2700,56 @@ bool CSettings::OnVideoDefaultClick(CGUIElement* pElement) // Update the GUI UpdateVideoTab(); + RefreshBorderlessDisplayCalibration(); return true; } +void CSettings::RefreshBorderlessDisplayCalibration() +{ + CScopedActiveProxyDevice scopedProxy; + if (!scopedProxy) + return; + + scopedProxy->ApplyBorderlessPresentationTuning(); +} + +void CSettings::UpdateBorderlessAdjustmentControls() +{ + const bool applyAdjustments = + (m_pCheckBoxApplyBorderless && m_pCheckBoxApplyBorderless->GetSelected()) || (m_pCheckBoxApplyFullscreen && m_pCheckBoxApplyFullscreen->GetSelected()); + + const bool gammaEnabled = applyAdjustments && (!m_pBorderlessGammaToggle || m_pBorderlessGammaToggle->GetSelected()); + const bool brightnessEnabled = applyAdjustments && (!m_pBorderlessBrightnessToggle || m_pBorderlessBrightnessToggle->GetSelected()); + const bool contrastEnabled = applyAdjustments && (!m_pBorderlessContrastToggle || m_pBorderlessContrastToggle->GetSelected()); + const bool saturationEnabled = applyAdjustments && (!m_pBorderlessSaturationToggle || m_pBorderlessSaturationToggle->GetSelected()); + + if (m_pBorderlessGamma) + m_pBorderlessGamma->SetEnabled(gammaEnabled); + if (m_pBorderlessGammaValueLabel) + m_pBorderlessGammaValueLabel->SetEnabled(gammaEnabled); + + if (m_pBorderlessBrightness) + m_pBorderlessBrightness->SetEnabled(brightnessEnabled); + if (m_pBorderlessBrightnessValueLabel) + m_pBorderlessBrightnessValueLabel->SetEnabled(brightnessEnabled); + + if (m_pBorderlessContrast) + m_pBorderlessContrast->SetEnabled(contrastEnabled); + if (m_pBorderlessContrastValueLabel) + m_pBorderlessContrastValueLabel->SetEnabled(contrastEnabled); + + if (m_pBorderlessSaturation) + m_pBorderlessSaturation->SetEnabled(saturationEnabled); + if (m_pBorderlessSaturationValueLabel) + m_pBorderlessSaturationValueLabel->SetEnabled(saturationEnabled); + + m_pBorderlessGammaToggle->SetEnabled(applyAdjustments); + m_pBorderlessBrightnessToggle->SetEnabled(applyAdjustments); + m_pBorderlessContrastToggle->SetEnabled(applyAdjustments); + m_pBorderlessSaturationToggle->SetEnabled(applyAdjustments); +} + void CSettings::ResetGTAVolume() { // This will set the GTA volume to the GTA volume value in the settings, @@ -2021,6 +2859,8 @@ bool CSettings::OnControlsDefaultClick(CGUIElement* pElement) m_pClassicControls->SetSelected(CVARS_GET_VALUE("classic_controls")); m_pMouseSensitivity->SetScrollPosition(gameSettings->GetMouseSensitivity()); m_pVerticalAimSensitivity->SetScrollPosition(pController->GetVerticalAimSensitivity()); + m_pCheckboxVerticalAimSensitivity->SetSelected(CVARS_GET_VALUE("use_mouse_sensitivity_for_aiming")); + m_pVerticalAimSensitivity->SetEnabled(!m_pCheckboxVerticalAimSensitivity->GetSelected()); return true; } @@ -2676,10 +3516,10 @@ bool CSettings::OnBindsListClick(CGUIElement* pElement) } #ifndef WM_XBUTTONDOWN -#define WM_XBUTTONDOWN 0x020B + #define WM_XBUTTONDOWN 0x020B #endif #ifndef WM_XBUTTONUP -#define WM_XBUTTONUP 0x020C + #define WM_XBUTTONUP 0x020C #endif bool CSettings::ProcessMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -2783,7 +3623,7 @@ void CSettings::Initialize() if (controlBind->control != pControl) continue; - if (!numMatches) // Primary key + if (!numMatches) // Primary key { // Add bind to the list iBind = m_pBindsList->InsertRowAfter(iRowGame); @@ -2795,7 +3635,7 @@ void CSettings::Initialize() m_pBindsList->SetItemData(iBind, m_hPriKey, controlBind); iGameRowCount++; } - else // Secondary key + else // Secondary key { for (size_t k = 0; k < SecKeyNum; k++) { @@ -2953,7 +3793,7 @@ void CSettings::SetVisible(bool bVisible) { #ifdef MTA_DEBUG if ((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0) - CreateGUI(); // Recreate GUI (for adjusting layout with edit and continue) + CreateGUI(); // Recreate GUI (for adjusting layout with edit and continue) #endif m_pWindow->BringToFront(); m_pWindow->Activate(); @@ -2966,7 +3806,7 @@ void CSettings::SetVisible(bool bVisible) Initialize(); } - m_pWindow->SetZOrderingEnabled(!bVisible); // Message boxes dont appear on top otherwise + m_pWindow->SetZOrderingEnabled(!bVisible); // Message boxes dont appear on top otherwise } bool CSettings::IsVisible() @@ -3124,6 +3964,10 @@ void CSettings::LoadData() pController->SetVerticalAimSensitivityRawValue(CVARS_GET_VALUE("vertical_aim_sensitivity")); m_pVerticalAimSensitivity->SetScrollPosition(pController->GetVerticalAimSensitivity()); + CVARS_GET("use_mouse_sensitivity_for_aiming", bVar); + m_pCheckboxVerticalAimSensitivity->SetSelected(bVar); + m_pVerticalAimSensitivity->SetEnabled(!m_pCheckboxVerticalAimSensitivity->GetSelected()); + // Audio m_pCheckBoxAudioEqualizer->SetSelected(gameSettings->IsRadioEqualizerEnabled()); m_pCheckBoxAudioAutotune->SetSelected(gameSettings->IsRadioAutotuneEnabled()); @@ -3269,7 +4113,7 @@ void CSettings::LoadData() DWORD_PTR sys; HANDLE process = GetCurrentProcess(); - BOOL result = GetProcessAffinityMask(process, &mask, &sys); + BOOL result = GetProcessAffinityMask(process, &mask, &sys); if (bVar && result) SetProcessAffinityMask(process, mask & ~1); @@ -3314,7 +4158,6 @@ void CSettings::LoadData() { CVARS_GET("chat_scale", strVar); stringstream ss(strVar); - ss >> strVar; m_pChatScaleX->SetText(SString("%1.1f", atof(strVar.c_str()))); ss >> strVar; m_pChatScaleY->SetText(SString("%1.1f", atof(strVar.c_str()))); @@ -3343,7 +4186,6 @@ void CSettings::LoadData() SetMilliseconds(m_pChatLineFadeout, iVar); } - // Chat position CVARS_GET("chat_position_horizontal", iVar); if (iVar > Chat::Position::Horizontal::RIGHT) iVar = Chat::Position::Horizontal::LEFT; @@ -3353,7 +4195,6 @@ void CSettings::LoadData() if (iVar > Chat::Position::Vertical::BOTTOM) iVar = Chat::Position::Vertical::TOP; m_pChatVerticalCombo->SetSelectedItemByIndex(iVar); - CVARS_GET("chat_text_alignment", iVar); if (iVar > Chat::Text::Align::RIGHT) iVar = Chat::Text::Align::LEFT; @@ -3388,7 +4229,9 @@ void CSettings::ReloadBrowserLists() m_bBrowserListsChanged = false; if (m_bBrowserListsLoadEnabled) { - auto pWebCore = g_pCore->GetWebCore(); + auto pWebCore = g_pCore->GetWebCore(); + if (!pWebCore) + return; std::vector> customBlacklist; pWebCore->GetFilterEntriesByType(customBlacklist, eWebFilterType::WEBFILTER_USER); for (std::vector>::iterator iter = customBlacklist.begin(); iter != customBlacklist.end(); ++iter) @@ -3451,6 +4294,8 @@ void CSettings::SaveData() pController->SetClassicControls(m_pClassicControls->GetSelected()); pController->SetVerticalAimSensitivity(m_pVerticalAimSensitivity->GetScrollPosition()); CVARS_SET("vertical_aim_sensitivity", pController->GetVerticalAimSensitivityRawValue()); + CVARS_SET("use_mouse_sensitivity_for_aiming", m_pCheckboxVerticalAimSensitivity->GetSelected()); + pController->SetVerticalAimSensitivitySameAsHorizontal(m_pCheckboxVerticalAimSensitivity->GetSelected()); // Video // get current @@ -3489,6 +4334,27 @@ void CSettings::SaveData() gameSettings->SetAntiAliasing(iAntiAliasing, true); gameSettings->SetDrawDistance((m_pDrawDistance->GetScrollPosition() * 0.875f) + 0.925f); gameSettings->SetBrightness(m_pBrightness->GetScrollPosition() * 384); + + const float borderlessGamma = DenormalizeSliderValue(m_pBorderlessGamma->GetScrollPosition(), kBorderlessGammaMin, kBorderlessGammaMax); + CVARS_SET("borderless_gamma_power", borderlessGamma); + + const float borderlessBrightness = DenormalizeSliderValue(m_pBorderlessBrightness->GetScrollPosition(), kBorderlessBrightnessMin, kBorderlessBrightnessMax); + CVARS_SET("borderless_brightness_scale", borderlessBrightness); + + const float borderlessContrast = DenormalizeSliderValue(m_pBorderlessContrast->GetScrollPosition(), kBorderlessContrastMin, kBorderlessContrastMax); + CVARS_SET("borderless_contrast_scale", borderlessContrast); + + const float borderlessSaturation = DenormalizeSliderValue(m_pBorderlessSaturation->GetScrollPosition(), kBorderlessSaturationMin, kBorderlessSaturationMax); + CVARS_SET("borderless_saturation_scale", borderlessSaturation); + + CVARS_SET("borderless_gamma_enabled", m_pBorderlessGammaToggle->GetSelected()); + CVARS_SET("borderless_brightness_enabled", m_pBorderlessBrightnessToggle->GetSelected()); + CVARS_SET("borderless_contrast_enabled", m_pBorderlessContrastToggle->GetSelected()); + CVARS_SET("borderless_saturation_enabled", m_pBorderlessSaturationToggle->GetSelected()); + CVARS_SET("borderless_apply_windowed", m_pCheckBoxApplyBorderless->GetSelected()); + CVARS_SET("borderless_apply_fullscreen", m_pCheckBoxApplyFullscreen->GetSelected()); + RefreshBorderlessDisplayCalibration(); + gameSettings->SetMouseSensitivity(m_pMouseSensitivity->GetScrollPosition()); gameSettings->SetMipMappingEnabled(m_pCheckBoxMipMapping->GetSelected()); SetApplicationSettingInt("customized-sa-files-request", bCustomizedSAFilesEnabled ? 1 : 0); @@ -3569,7 +4435,7 @@ void CSettings::SaveData() const char* state = _("Main menu"); if (g_pCore->IsConnected()) - { + { state = _("In-game"); const SString& serverName = g_pCore->GetLastConnectedServerName(); @@ -3694,7 +4560,7 @@ void CSettings::SaveData() DWORD_PTR sys; HANDLE process = GetCurrentProcess(); - BOOL result = GetProcessAffinityMask(process, &mask, &sys); + BOOL result = GetProcessAffinityMask(process, &mask, &sys); if (affinity && result) SetProcessAffinityMask(process, mask & ~1); @@ -3729,7 +4595,7 @@ void CSettings::SaveData() // Player map alpha SString sText = m_pMapAlphaValueLabel->GetText(); - float fMapAlpha = ((atof(sText.substr(0, sText.length() - 1).c_str())) / 100) * 255; + float fMapAlpha = ((atof(sText.substr(0, sText.length() - 1).c_str())) / 100) * 255; CVARS_SET("mapalpha", fMapAlpha); // Player map image @@ -3741,9 +4607,17 @@ void CSettings::SaveData() CGUIListItem* pItem = m_pInterfaceLanguageSelector->GetSelectedItem(); if (pItem) { - const char* szItemText = (const char*)pItem->GetData(); - CVARS_SET("locale", std::string(szItemText)); - SetApplicationSetting("locale", szItemText); + const char* szItemText = static_cast(pItem->GetData()); + SString strSelectedLocale = szItemText ? szItemText : ""; + + if (!strSelectedLocale.empty()) + { + SString strCurrentLocale; + CVARS_GET("locale", strCurrentLocale); + + if (strSelectedLocale != strCurrentLocale) + CLocalGUI::GetSingleton().RequestLocaleChange(strSelectedLocale); + } } // Chat @@ -3820,23 +4694,26 @@ void CSettings::SaveData() if (m_bBrowserListsLoadEnabled) { - auto pWebCore = g_pCore->GetWebCore(); - std::vector customBlacklist; - for (int i = 0; i < m_pGridBrowserBlacklist->GetRowCount(); ++i) + auto pWebCore = g_pCore->GetWebCore(); + if (pWebCore) { - customBlacklist.push_back(m_pGridBrowserBlacklist->GetItemText(i, 1)); - } - pWebCore->WriteCustomList("customblacklist", customBlacklist); + std::vector customBlacklist; + for (int i = 0; i < m_pGridBrowserBlacklist->GetRowCount(); ++i) + { + customBlacklist.push_back(m_pGridBrowserBlacklist->GetItemText(i, 1)); + } + pWebCore->WriteCustomList("customblacklist", customBlacklist); - std::vector customWhitelist; - for (int i = 0; i < m_pGridBrowserWhitelist->GetRowCount(); ++i) - { - customWhitelist.push_back(m_pGridBrowserWhitelist->GetItemText(i, 1)); - } - pWebCore->WriteCustomList("customwhitelist", customWhitelist); + std::vector customWhitelist; + for (int i = 0; i < m_pGridBrowserWhitelist->GetRowCount(); ++i) + { + customWhitelist.push_back(m_pGridBrowserWhitelist->GetItemText(i, 1)); + } + pWebCore->WriteCustomList("customwhitelist", customWhitelist); - if (m_bBrowserListsChanged) - bBrowserSettingChanged = true; + if (m_bBrowserListsChanged) + bBrowserSettingChanged = true; + } } bool bBrowserGPUEnabled = false; @@ -3894,6 +4771,8 @@ void CSettings::AddKeyBindSection(char* szSectionName) void CSettings::CreateChatColorTab(eChatColorType eType, const char* szName, CGUITabPanel* pParent) { CVector2D vecTemp; + CVector2D tabPanelSize; + pParent->GetSize(tabPanelSize); // Create the GUI Elements CGUI* pManager = g_pCore->GetGUI(); @@ -3920,70 +4799,99 @@ void CSettings::CreateChatColorTab(eChatColorType eType, const char* szName, CGU pLabel->SetFont("default-bold-small"); // Red - pLabel = reinterpret_cast(pManager->CreateLabel(pTab, strRed)); - pLabel->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 30.0f)); - pLabel->GetPosition(vecTemp); - pLabel->AutoSize(); + CGUILabel* pLabelRed = reinterpret_cast(pManager->CreateLabel(pTab, strRed)); + pLabelRed->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 30.0f)); + pLabelRed->AutoSize(); + CVector2D redLabelPos; + pLabelRed->GetPosition(redLabelPos); m_pChatRed[eType] = reinterpret_cast(pManager->CreateScrollBar(true, pTab)); - m_pChatRed[eType]->SetPosition(CVector2D(vecTemp.fX + fIndentX, vecTemp.fY - 2.0f)); - m_pChatRed[eType]->SetSize(CVector2D(175.0f, fLineSizeY)); + m_pChatRed[eType]->SetPosition(CVector2D(redLabelPos.fX + fIndentX, redLabelPos.fY - 2.0f)); + CVector2D redSliderPos; + m_pChatRed[eType]->GetPosition(redSliderPos); + const float chatSliderPreferredWidth = 175.0f; + m_pChatRed[eType]->SetSize(CVector2D(ComputeSliderWidth(tabPanelSize.fX, redSliderPos.fX, chatSliderPreferredWidth), fLineSizeY)); + CVector2D redSliderSize; + m_pChatRed[eType]->GetSize(redSliderSize); m_pChatRed[eType]->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnChatRedChanged, this)); m_pChatRed[eType]->SetProperty("StepSize", "0.004"); m_pChatRedValue[eType] = reinterpret_cast(pManager->CreateLabel(pTab, "0")); - m_pChatRedValue[eType]->SetPosition(CVector2D(vecTemp.fX + fIndentX + 185.0f, vecTemp.fY)); + m_pChatRedValue[eType]->SetPosition(CVector2D(redSliderPos.fX + redSliderSize.fX + kSliderLabelSpacing, redLabelPos.fY)); m_pChatRedValue[eType]->AutoSize("255 "); + FinalizeSliderRow(tabPanelSize.fX, m_pChatRed[eType], m_pChatRedValue[eType], chatSliderPreferredWidth, kSliderLabelSpacing, pLabelRed); // Green - pLabel = reinterpret_cast(pManager->CreateLabel(pTab, strGreen)); - pLabel->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + fLineSizeY + fLineGapY)); - pLabel->GetPosition(vecTemp); - pLabel->AutoSize(); + CGUILabel* pLabelGreen = reinterpret_cast(pManager->CreateLabel(pTab, strGreen)); + pLabelGreen->SetPosition(CVector2D(redLabelPos.fX, redLabelPos.fY + fLineSizeY + fLineGapY)); + pLabelGreen->AutoSize(); + CVector2D greenLabelPos; + pLabelGreen->GetPosition(greenLabelPos); m_pChatGreen[eType] = reinterpret_cast(pManager->CreateScrollBar(true, pTab)); - m_pChatGreen[eType]->SetPosition(CVector2D(vecTemp.fX + fIndentX, vecTemp.fY - 2.0f)); - m_pChatGreen[eType]->SetSize(CVector2D(175.0f, fLineSizeY)); + m_pChatGreen[eType]->SetPosition(CVector2D(greenLabelPos.fX + fIndentX, greenLabelPos.fY - 2.0f)); + CVector2D greenSliderPos; + m_pChatGreen[eType]->GetPosition(greenSliderPos); + m_pChatGreen[eType]->SetSize(CVector2D(ComputeSliderWidth(tabPanelSize.fX, greenSliderPos.fX, chatSliderPreferredWidth), fLineSizeY)); + CVector2D greenSliderSize; + m_pChatGreen[eType]->GetSize(greenSliderSize); m_pChatGreen[eType]->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnChatGreenChanged, this)); m_pChatGreen[eType]->SetProperty("StepSize", "0.004"); m_pChatGreenValue[eType] = reinterpret_cast(pManager->CreateLabel(pTab, "0")); - m_pChatGreenValue[eType]->SetPosition(CVector2D(vecTemp.fX + fIndentX + 185.0f, vecTemp.fY)); + m_pChatGreenValue[eType]->SetPosition(CVector2D(greenSliderPos.fX + greenSliderSize.fX + kSliderLabelSpacing, greenLabelPos.fY)); m_pChatGreenValue[eType]->AutoSize("255 "); + FinalizeSliderRow(tabPanelSize.fX, m_pChatGreen[eType], m_pChatGreenValue[eType], chatSliderPreferredWidth, kSliderLabelSpacing, pLabelGreen); // Blue - pLabel = reinterpret_cast(pManager->CreateLabel(pTab, strBlue)); - pLabel->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + fLineSizeY + fLineGapY)); - pLabel->GetPosition(vecTemp); - pLabel->AutoSize(); + CGUILabel* pLabelBlue = reinterpret_cast(pManager->CreateLabel(pTab, strBlue)); + pLabelBlue->SetPosition(CVector2D(greenLabelPos.fX, greenLabelPos.fY + fLineSizeY + fLineGapY)); + pLabelBlue->AutoSize(); + CVector2D blueLabelPos; + pLabelBlue->GetPosition(blueLabelPos); m_pChatBlue[eType] = reinterpret_cast(pManager->CreateScrollBar(true, pTab)); - m_pChatBlue[eType]->SetPosition(CVector2D(vecTemp.fX + fIndentX, vecTemp.fY - 2.0f)); - m_pChatBlue[eType]->SetSize(CVector2D(175.0f, fLineSizeY)); + m_pChatBlue[eType]->SetPosition(CVector2D(blueLabelPos.fX + fIndentX, blueLabelPos.fY - 2.0f)); + CVector2D blueSliderPos; + m_pChatBlue[eType]->GetPosition(blueSliderPos); + m_pChatBlue[eType]->SetSize(CVector2D(ComputeSliderWidth(tabPanelSize.fX, blueSliderPos.fX, chatSliderPreferredWidth), fLineSizeY)); + CVector2D blueSliderSize; + m_pChatBlue[eType]->GetSize(blueSliderSize); m_pChatBlue[eType]->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnChatBlueChanged, this)); m_pChatBlue[eType]->SetProperty("StepSize", "0.004"); m_pChatBlueValue[eType] = reinterpret_cast(pManager->CreateLabel(pTab, "0")); - m_pChatBlueValue[eType]->SetPosition(CVector2D(vecTemp.fX + fIndentX + 185.0f, vecTemp.fY)); + m_pChatBlueValue[eType]->SetPosition(CVector2D(blueSliderPos.fX + blueSliderSize.fX + kSliderLabelSpacing, blueLabelPos.fY)); m_pChatBlueValue[eType]->AutoSize("255 "); + FinalizeSliderRow(tabPanelSize.fX, m_pChatBlue[eType], m_pChatBlueValue[eType], chatSliderPreferredWidth, kSliderLabelSpacing, pLabelBlue); // Transparency - pLabel = reinterpret_cast(pManager->CreateLabel(pTab, strTransparency)); - pLabel->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + fLineSizeY + fLineGapY)); - pLabel->GetPosition(vecTemp); - pLabel->AutoSize(); + CGUILabel* pLabelAlpha = reinterpret_cast(pManager->CreateLabel(pTab, strTransparency)); + pLabelAlpha->SetPosition(CVector2D(blueLabelPos.fX, blueLabelPos.fY + fLineSizeY + fLineGapY)); + pLabelAlpha->AutoSize(); + CVector2D alphaLabelPos; + pLabelAlpha->GetPosition(alphaLabelPos); m_pChatAlpha[eType] = reinterpret_cast(pManager->CreateScrollBar(true, pTab)); - m_pChatAlpha[eType]->SetPosition(CVector2D(vecTemp.fX + fIndentX, vecTemp.fY - 2.0f)); - m_pChatAlpha[eType]->SetSize(CVector2D(175.0f, fLineSizeY)); + m_pChatAlpha[eType]->SetPosition(CVector2D(alphaLabelPos.fX + fIndentX, alphaLabelPos.fY - 2.0f)); + CVector2D alphaSliderPos; + m_pChatAlpha[eType]->GetPosition(alphaSliderPos); + m_pChatAlpha[eType]->SetSize(CVector2D(ComputeSliderWidth(tabPanelSize.fX, alphaSliderPos.fX, chatSliderPreferredWidth), fLineSizeY)); + CVector2D alphaSliderSize; + m_pChatAlpha[eType]->GetSize(alphaSliderSize); m_pChatAlpha[eType]->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnChatAlphaChanged, this)); m_pChatAlpha[eType]->SetProperty("StepSize", "0.004"); m_pChatAlphaValue[eType] = reinterpret_cast(pManager->CreateLabel(pTab, "0")); - m_pChatAlphaValue[eType]->SetPosition(CVector2D(vecTemp.fX + fIndentX + 185.0f, vecTemp.fY)); + m_pChatAlphaValue[eType]->SetPosition(CVector2D(alphaSliderPos.fX + alphaSliderSize.fX + kSliderLabelSpacing, alphaLabelPos.fY)); m_pChatAlphaValue[eType]->AutoSize("255 "); + FinalizeSliderRow(tabPanelSize.fX, m_pChatAlpha[eType], m_pChatAlphaValue[eType], chatSliderPreferredWidth, kSliderLabelSpacing, pLabelAlpha); - fMarginX = vecTemp.fX + fIndentX + 185.0f + pManager->GetTextExtent("255") + 30.0f; + CVector2D alphaValuePos; + m_pChatAlphaValue[eType]->GetPosition(alphaValuePos); + CVector2D alphaValueSize; + m_pChatAlphaValue[eType]->GetSize(alphaValueSize); + fMarginX = alphaValuePos.fX + alphaValueSize.fX + 30.0f; } // @@ -4114,10 +5022,10 @@ void CSettings::LoadChatColorFromString(eChatColorType eType, const string& strC try { ss >> iR >> iG >> iB >> iA; - pColor.R = iR; - pColor.G = iG; - pColor.B = iB; - pColor.A = iA; + pColor.R = static_cast(iR); + pColor.G = static_cast(iG); + pColor.B = static_cast(iB); + pColor.A = static_cast(iA); SetChatColorValues(eType, pColor); } catch (...) @@ -4358,6 +5266,117 @@ bool CSettings::OnBrightnessChanged(CGUIElement* pElement) return true; } +bool CSettings::OnBorderlessGammaChanged(CGUIElement* pElement) +{ + const float gammaValue = DenormalizeSliderValue(m_pBorderlessGamma->GetScrollPosition(), kBorderlessGammaMin, kBorderlessGammaMax); + m_pBorderlessGammaValueLabel->SetText(SString("%.2fx", gammaValue).c_str()); + CVARS_SET("borderless_gamma_power", gammaValue); + RefreshBorderlessDisplayCalibration(); + return true; +} + +bool CSettings::OnBorderlessBrightnessChanged(CGUIElement* pElement) +{ + const float brightnessValue = DenormalizeSliderValue(m_pBorderlessBrightness->GetScrollPosition(), kBorderlessBrightnessMin, kBorderlessBrightnessMax); + m_pBorderlessBrightnessValueLabel->SetText(SString("%.2fx", brightnessValue).c_str()); + CVARS_SET("borderless_brightness_scale", brightnessValue); + RefreshBorderlessDisplayCalibration(); + return true; +} + +bool CSettings::OnBorderlessContrastChanged(CGUIElement* pElement) +{ + const float contrastValue = DenormalizeSliderValue(m_pBorderlessContrast->GetScrollPosition(), kBorderlessContrastMin, kBorderlessContrastMax); + m_pBorderlessContrastValueLabel->SetText(SString("%.2fx", contrastValue).c_str()); + CVARS_SET("borderless_contrast_scale", contrastValue); + RefreshBorderlessDisplayCalibration(); + return true; +} + +bool CSettings::OnBorderlessSaturationChanged(CGUIElement* pElement) +{ + const float saturationValue = DenormalizeSliderValue(m_pBorderlessSaturation->GetScrollPosition(), kBorderlessSaturationMin, kBorderlessSaturationMax); + m_pBorderlessSaturationValueLabel->SetText(SString("%.2fx", saturationValue).c_str()); + CVARS_SET("borderless_saturation_scale", saturationValue); + RefreshBorderlessDisplayCalibration(); + return true; +} + +bool CSettings::OnBorderlessGammaToggleClicked(CGUIElement* pElement) +{ + const bool enabled = m_pBorderlessGammaToggle->GetSelected(); + CVARS_SET("borderless_gamma_enabled", enabled); + UpdateBorderlessAdjustmentControls(); + RefreshBorderlessDisplayCalibration(); + return true; +} + +bool CSettings::OnBorderlessBrightnessToggleClicked(CGUIElement* pElement) +{ + const bool enabled = m_pBorderlessBrightnessToggle->GetSelected(); + CVARS_SET("borderless_brightness_enabled", enabled); + UpdateBorderlessAdjustmentControls(); + RefreshBorderlessDisplayCalibration(); + return true; +} + +bool CSettings::OnBorderlessContrastToggleClicked(CGUIElement* pElement) +{ + const bool enabled = m_pBorderlessContrastToggle->GetSelected(); + CVARS_SET("borderless_contrast_enabled", enabled); + UpdateBorderlessAdjustmentControls(); + RefreshBorderlessDisplayCalibration(); + return true; +} + +bool CSettings::OnBorderlessSaturationToggleClicked(CGUIElement* pElement) +{ + const bool enabled = m_pBorderlessSaturationToggle->GetSelected(); + CVARS_SET("borderless_saturation_enabled", enabled); + UpdateBorderlessAdjustmentControls(); + RefreshBorderlessDisplayCalibration(); + return true; +} + +bool CSettings::OnBorderlessApplyBorderlessClicked(CGUIElement* pElement) +{ + const bool applyBorderless = m_pCheckBoxApplyBorderless->GetSelected(); + CVARS_SET("borderless_apply_windowed", applyBorderless); + + UpdateBorderlessAdjustmentControls(); + RefreshBorderlessDisplayCalibration(); + return true; +} + +bool CSettings::OnBorderlessApplyFullscreenClicked(CGUIElement* pElement) +{ + const bool applyFullscreen = m_pCheckBoxApplyFullscreen->GetSelected(); + CVARS_SET("borderless_apply_fullscreen", applyFullscreen); + + UpdateBorderlessAdjustmentControls(); + RefreshBorderlessDisplayCalibration(); + return true; +} + +bool CSettings::OnPostFXDefaultClick(CGUIElement* pElement) +{ + CVARS_SET("borderless_gamma_power", 1.0f); + CVARS_SET("borderless_brightness_scale", 1.0f); + CVARS_SET("borderless_contrast_scale", 1.0f); + CVARS_SET("borderless_saturation_scale", 1.0f); + + CVARS_SET("borderless_gamma_enabled", false); + CVARS_SET("borderless_brightness_enabled", false); + CVARS_SET("borderless_contrast_enabled", false); + CVARS_SET("borderless_saturation_enabled", false); + + CVARS_SET("borderless_apply_windowed", false); + CVARS_SET("borderless_apply_fullscreen", false); + + UpdatePostFxTab(); + return true; +} + bool CSettings::OnAnisotropicChanged(CGUIElement* pElement) { int iAnisotropic = std::min(m_iMaxAnisotropic, (m_pAnisotropic->GetScrollPosition()) * (m_iMaxAnisotropic + 1)); @@ -4672,7 +5691,7 @@ bool CSettings::OnAllowDiscordRPC(CGUIElement* pElement) g_pCore->GetDiscord()->SetDiscordRPCEnabled(isEnabled); if (isEnabled) - ShowRichPresenceShareDataQuestionBox(); // show question box + ShowRichPresenceShareDataQuestionBox(); // show question box return true; } @@ -4687,9 +5706,9 @@ static void ShowRichPresenceShareDataCallback(void* ptr, unsigned int uiButton) void CSettings::ShowRichPresenceShareDataQuestionBox() const { SStringX strMessage( - _("It seems that you have the Rich Presence connection option enabled." - "\nDo you want to allow servers to share their data?" - "\n\nThis includes yours unique ID identifier.")); + _("Rich Presence is currently enabled." + "\nDo you want to allow data sharing with servers you connect to?" + "\n\nThis includes your Discord client ID, and game state info.")); CQuestionBox* pQuestionBox = CCore::GetSingleton().GetLocalGUI()->GetMainMenu()->GetQuestionWindow(); pQuestionBox->Reset(); pQuestionBox->SetTitle(_("CONSENT TO ALLOW DATA SHARING")); @@ -4793,6 +5812,15 @@ static void DPIAwareQuestionCallBack(void* userdata, unsigned int uiButton) } } +// +// OnVSyncClick +// +bool CSettings::OnVSyncClick(CGUIElement* pElement) +{ + CCore::GetSingleton().GetFPSLimiter()->SetDisplayVSync(m_pCheckBoxVSync->GetSelected()); + return true; +} + static void CPUAffinityQuestionCallBack(void* userdata, unsigned int button) { CCore::GetSingleton().GetLocalGUI()->GetMainMenu()->GetQuestionWindow()->Reset(); @@ -4834,6 +5862,12 @@ bool CSettings::OnAffinityClick(CGUIElement* pElement) return true; } +bool CSettings::OnMouseAimingClick(CGUIElement* pElement) +{ + m_pVerticalAimSensitivity->SetEnabled(!m_pCheckboxVerticalAimSensitivity->GetSelected()); + return true; +} + bool CSettings::OnBrowserBlacklistAdd(CGUIElement* pElement) { SString strDomain = m_pEditBrowserBlacklistAdd->GetText(); @@ -4870,6 +5904,16 @@ bool CSettings::OnBrowserBlacklistRemove(CGUIElement* pElement) return true; } +bool CSettings::OnBrowserBlacklistRemoveAll(CGUIElement* pElement) +{ + if (m_pGridBrowserBlacklist->GetRowCount() > 0) + { + m_pGridBrowserBlacklist->Clear(); + m_bBrowserListsChanged = true; + } + return true; +} + bool CSettings::OnBrowserBlacklistDomainAddFocused(CGUIElement* pElement) { m_pLabelBrowserBlacklistAdd->SetVisible(false); @@ -4919,6 +5963,17 @@ bool CSettings::OnBrowserWhitelistRemove(CGUIElement* pElement) return true; } +bool CSettings::OnBrowserWhitelistRemoveAll(CGUIElement* pElement) +{ + if (m_pGridBrowserWhitelist->GetRowCount() > 0) + { + m_pGridBrowserWhitelist->Clear(); + m_bBrowserListsChanged = true; + } + + return true; +} + bool CSettings::OnBrowserWhitelistDomainAddFocused(CGUIElement* pElement) { m_pLabelBrowserWhitelistAdd->SetVisible(false); @@ -4934,7 +5989,7 @@ bool CSettings::OnBrowserWhitelistDomainAddDefocused(CGUIElement* pElement) void NewNicknameCallback(void* ptr, unsigned int uiButton, std::string strNick) { - if (uiButton == 1) // We hit OK + if (uiButton == 1) // We hit OK { if (!CCore::GetSingleton().IsValidNick(strNick.c_str())) CCore::GetSingleton().ShowMessageBox(_("Error") + _E("CC81"), _("Your nickname contains invalid characters!"), MB_BUTTON_OK | MB_ICON_INFO); diff --git a/Client/core/CSettings.h b/Client/core/CSettings.h index 91b136b53e5..23e1297b2a5 100644 --- a/Client/core/CSettings.h +++ b/Client/core/CSettings.h @@ -17,9 +17,9 @@ class CSettings; #include "CMainMenu.h" #include "CCore.h" -#define SKINS_PATH "skins/*" -#define CHAT_PRESETS_PATH "mta/config/chatboxpresets.xml" -#define CHAT_PRESETS_ROOT "chatboxpresets" +#define SKINS_PATH "skins/*" +#define CHAT_PRESETS_PATH "mta/config/chatboxpresets.xml" +#define CHAT_PRESETS_ROOT "chatboxpresets" // #define SHOWALLSETTINGS @@ -56,7 +56,7 @@ struct SKeyBindSection if (szOriginalTitle) delete[] szOriginalTitle; } - int currentIndex; // temporarily stores the index while the list is being created + int currentIndex; // temporarily stores the index while the list is being created char* szTitle; char* szOriginalTitle; int rowCount; @@ -103,6 +103,7 @@ class CSettings void UpdateAudioTab(); void UpdateVideoTab(); + void UpdatePostFxTab(); void PopulateResolutionComboBox(); void UpdateFullScreenComboBoxEnabled(); @@ -122,21 +123,28 @@ class CSettings void ShowRichPresenceShareDataQuestionBox() const; protected: - const static int SecKeyNum = 3; // Number of secondary keys + const static int SecKeyNum = 3; // Number of secondary keys // Keep these protected so we can access them in the event handlers of CClientGame - CGUIElement* m_pWindow; - CGUITabPanel* m_pTabs; - CGUITab* m_pTabInterface; - CGUITab* m_pTabBrowser; - CGUIButton* m_pButtonOK; - CGUIButton* m_pButtonCancel; - CGUILabel* m_pLabelNick; - CGUIButton* m_pButtonGenerateNick; - CGUIStaticImage* m_pButtonGenerateNickIcon; - CGUIEdit* m_pEditNick; - CGUICheckBox* m_pSavePasswords; - CGUICheckBox* m_pAutoRefreshBrowser; + CGUIElement* m_pWindow; + CGUITabPanel* m_pTabs; + CGUITab* m_pTabMultiplayer; + CGUITab* m_pTabVideo; + CGUITab* m_pTabInterface; + CGUITab* m_pTabBrowser; + CGUITab* m_pTabPostFX; + CGUITab* m_pTabAudio; + CGUITab* m_pTabBinds; + CGUITab* m_pTabControls; + CGUITab* m_pTabAdvanced; + CGUIButton* m_pButtonOK; + CGUIButton* m_pButtonCancel; + CGUILabel* m_pLabelNick; + CGUIButton* m_pButtonGenerateNick; + CGUIStaticImage* m_pButtonGenerateNickIcon; + CGUIEdit* m_pEditNick; + CGUICheckBox* m_pSavePasswords; + CGUICheckBox* m_pAutoRefreshBrowser; CGUILabel* m_pVideoGeneralLabel; CGUILabel* m_pVideoResolutionLabel; @@ -177,6 +185,21 @@ class CSettings CGUILabel* m_pBrightnessLabel; CGUIScrollBar* m_pBrightness; CGUILabel* m_pBrightnessValueLabel; + CGUICheckBox* m_pBorderlessGammaToggle; + CGUIScrollBar* m_pBorderlessGamma; + CGUILabel* m_pBorderlessGammaValueLabel; + CGUICheckBox* m_pBorderlessBrightnessToggle; + CGUIScrollBar* m_pBorderlessBrightness; + CGUILabel* m_pBorderlessBrightnessValueLabel; + CGUICheckBox* m_pBorderlessContrastToggle; + CGUIScrollBar* m_pBorderlessContrast; + CGUILabel* m_pBorderlessContrastValueLabel; + CGUICheckBox* m_pBorderlessSaturationToggle; + CGUIScrollBar* m_pBorderlessSaturation; + CGUILabel* m_pBorderlessSaturationValueLabel; + CGUICheckBox* m_pCheckBoxApplyBorderless; + CGUICheckBox* m_pCheckBoxApplyFullscreen; + CGUIButton* m_pPostFXDefButton; CGUILabel* m_pAnisotropicLabel; CGUIScrollBar* m_pAnisotropic; CGUILabel* m_pAnisotropicValueLabel; @@ -195,6 +218,7 @@ class CSettings CGUILabel* m_pAdvancedSettingDescriptionLabel; CGUILabel* m_pFullscreenStyleLabel; CGUIComboBox* m_pFullscreenStyleCombo; + CGUICheckBox* m_pCheckBoxVSync; CGUILabel* m_pPriorityLabel; CGUIComboBox* m_pPriorityCombo; CGUILabel* m_pPlayerMapImageLabel; @@ -281,6 +305,7 @@ class CSettings CGUILabel* m_pLabelVerticalAimSensitivity; CGUIScrollBar* m_pVerticalAimSensitivity; CGUILabel* m_pLabelVerticalAimSensitivityValue; + CGUICheckBox* m_pCheckboxVerticalAimSensitivity; CGUILabel* m_pControlsJoypadLabel; CGUIScrollPane* m_pControlsInputTypePane; @@ -338,12 +363,14 @@ class CSettings CGUIButton* m_pButtonBrowserBlacklistAdd; CGUIGridList* m_pGridBrowserBlacklist; CGUIButton* m_pButtonBrowserBlacklistRemove; + CGUIButton* m_pButtonBrowserBlacklistRemoveAll; CGUILabel* m_pLabelBrowserCustomWhitelist; CGUIEdit* m_pEditBrowserWhitelistAdd; CGUILabel* m_pLabelBrowserWhitelistAdd; CGUIButton* m_pButtonBrowserWhitelistAdd; CGUIGridList* m_pGridBrowserWhitelist; CGUIButton* m_pButtonBrowserWhitelistRemove; + CGUIButton* m_pButtonBrowserWhitelistRemoveAll; CGUICheckBox* m_pCheckBoxBrowserGPUEnabled; bool m_bBrowserListsChanged; bool m_bBrowserListsLoadEnabled; @@ -361,6 +388,17 @@ class CSettings bool OnFieldOfViewChanged(CGUIElement* pElement); bool OnDrawDistanceChanged(CGUIElement* pElement); bool OnBrightnessChanged(CGUIElement* pElement); + bool OnBorderlessGammaChanged(CGUIElement* pElement); + bool OnBorderlessBrightnessChanged(CGUIElement* pElement); + bool OnBorderlessContrastChanged(CGUIElement* pElement); + bool OnBorderlessSaturationChanged(CGUIElement* pElement); + bool OnBorderlessGammaToggleClicked(CGUIElement* pElement); + bool OnBorderlessBrightnessToggleClicked(CGUIElement* pElement); + bool OnBorderlessContrastToggleClicked(CGUIElement* pElement); + bool OnBorderlessSaturationToggleClicked(CGUIElement* pElement); + bool OnBorderlessApplyBorderlessClicked(CGUIElement* pElement); + bool OnBorderlessApplyFullscreenClicked(CGUIElement* pElement); + bool OnPostFXDefaultClick(CGUIElement* pElement); bool OnAnisotropicChanged(CGUIElement* pElement); bool OnMapAlphaChanged(CGUIElement* pElement); bool OnMasterVolumeChanged(CGUIElement* pElement); @@ -383,10 +421,12 @@ class CSettings bool OnVerticalAimSensitivityChanged(CGUIElement* pElement); bool OnBrowserBlacklistAdd(CGUIElement* pElement); bool OnBrowserBlacklistRemove(CGUIElement* pElement); + bool OnBrowserBlacklistRemoveAll(CGUIElement* pElement); bool OnBrowserBlacklistDomainAddFocused(CGUIElement* pElement); bool OnBrowserBlacklistDomainAddDefocused(CGUIElement* pElement); bool OnBrowserWhitelistAdd(CGUIElement* pElement); bool OnBrowserWhitelistRemove(CGUIElement* pElement); + bool OnBrowserWhitelistRemoveAll(CGUIElement* pElement); bool OnBrowserWhitelistDomainAddFocused(CGUIElement* pElement); bool OnBrowserWhitelistDomainAddDefocused(CGUIElement* pElement); @@ -406,10 +446,12 @@ class CSettings bool ShowUnsafeResolutionsClick(CGUIElement* pElement); bool OnWindowedClick(CGUIElement* pElement); bool OnDPIAwareClick(CGUIElement* pElement); + bool OnVSyncClick(CGUIElement* pElement); bool OnShowAdvancedSettingDescription(CGUIElement* pElement); bool OnHideAdvancedSettingDescription(CGUIElement* pElement); bool OnTabChanged(CGUIElement* pElement); bool OnAffinityClick(CGUIElement* pElement); + bool OnMouseAimingClick(CGUIElement* pElement); void ReloadBrowserLists(); private: @@ -436,6 +478,9 @@ class CSettings void ResetGTAVolume(); void SetRadioVolume(float fVolume); void SetSFXVolume(float fVolume); + void RefreshBorderlessDisplayCalibration(); + void UpdateBorderlessAdjustmentControls(); + void ResetGuiPointers(); unsigned int m_uiCaptureKey; bool m_bCaptureKey; diff --git a/Client/core/CSteamClient.cpp b/Client/core/CSteamClient.cpp index 50729f7e8c9..e0106c97604 100644 --- a/Client/core/CSteamClient.cpp +++ b/Client/core/CSteamClient.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #define STEAM_GTASA_APP_ID "12120" @@ -323,12 +324,19 @@ static bool IsSteamProcess(DWORD pid) HandleScope closeProcess{process}; - wchar_t processName[MAX_PATH]; + wchar_t processNameBuf[MAX_PATH]; + const DWORD processNameLen = GetProcessImageFileNameW(process, processNameBuf, MAX_PATH); - if (!GetModuleBaseNameW(process, nullptr, processName, sizeof(processName) / sizeof(wchar_t))) + if (!processNameLen) return false; - if (wcsicmp(processName, L"steam.exe") != 0) + CharLowerW(processNameBuf); + + std::wstring_view processName(processNameBuf, processNameLen); + + using namespace std::string_view_literals; + + if (processName != L"steam.exe"sv && !processName.ends_with(L"\\steam.exe"sv)) return false; DWORD exitCode = 0; @@ -377,9 +385,27 @@ bool CSteamClient::Load() return false; } + static auto pAddDllDirectory = ([]() -> decltype(&AddDllDirectory) { + if (const HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll"); kernel32 != nullptr) + { + decltype(&AddDllDirectory) addDllDirectory = nullptr; + if (!SharedUtil::TryGetProcAddress(kernel32, "AddDllDirectory", addDllDirectory)) + return nullptr; + return addDllDirectory; + } + + return nullptr; + })(); + + if (pAddDllDirectory == nullptr) + { + WriteErrorEvent("Your operating system is outdated and is missing the KB2533623 update package for AddDllDirectory"); + return false; + } + WriteDebugEvent(SString("Using steamclient.dll: %s", *ToUTF8(steamClientPath.value()))); SetEnvironmentVariableW(L"SteamAppId", L"" STEAM_GTASA_APP_ID); - AddDllDirectory(steamDirPath.c_str()); + pAddDllDirectory(steamDirPath.c_str()); { static wchar_t pathBuffer[65536]; GetEnvironmentVariableW(L"PATH", pathBuffer, sizeof(pathBuffer) / sizeof(wchar_t)); @@ -424,10 +450,8 @@ bool CSteamClient::Load() } releaseLibraryLock.reset(); - - Native::CreateInterface = reinterpret_cast(GetProcAddress(dll, "CreateInterface")); - if (!Native::CreateInterface) + if (!SharedUtil::TryGetProcAddress(dll, "CreateInterface", Native::CreateInterface)) { FreeLibrary(dll); return false; diff --git a/Client/core/CTrayIcon.cpp b/Client/core/CTrayIcon.cpp index 168aa256f1a..67ed3a5a126 100644 --- a/Client/core/CTrayIcon.cpp +++ b/Client/core/CTrayIcon.cpp @@ -13,10 +13,10 @@ #include #include "resource.h" -#define TRAY_DUMMY_WINDOW_NAME L"NotificationsDummy" -#define TRAY_BALLOON_TITLE L"Notification from MTA:SA server" -#define TRAY_ICON_TOOLTIP_TEXT L"Multi Theft Auto: San Andreas" -#define TRAY_BALLOON_INTERVAL 30000L // ms +#define TRAY_DUMMY_WINDOW_NAME L"NotificationsDummy" +#define TRAY_BALLOON_TITLE L"Notification from MTA:SA server" +#define TRAY_ICON_TOOLTIP_TEXT L"Multi Theft Auto: San Andreas" +#define TRAY_BALLOON_INTERVAL 30000L // ms extern HINSTANCE g_hModule; diff --git a/Client/core/CVersionUpdater.Util.hpp b/Client/core/CVersionUpdater.Util.hpp index b298fff277b..12f83ade156 100644 --- a/Client/core/CVersionUpdater.Util.hpp +++ b/Client/core/CVersionUpdater.Util.hpp @@ -31,8 +31,8 @@ class CVersionUpdater; - https://updatesa.mtasa.com/sa/version/?v=%VERSION%&id=%ID%&ty=%TYPE%&da=%DATA%&be=%BETA%&re=%REFER% https://updatesa.mtasa.com/sa/version/?v=%VERSION%&id=%ID%&ty=%TYPE%&da=%DATA%&be=%BETA%&re=%REFER% https://updatesa.multitheftauto.com/sa/version/?v=%VERSION%&id=%ID%&ty=%TYPE%&da=%DATA%&be=%BETA%&re=%REFER% 12h @@ -133,9 +133,12 @@ namespace BUTTON_3, }; - CQuestionBox& GetQuestionBox() { return *CCore::GetSingleton().GetLocalGUI()->GetMainMenu()->GetQuestionWindow(); } + CQuestionBox& GetQuestionBox() + { + return *CCore::GetSingleton().GetLocalGUI()->GetMainMenu()->GetQuestionWindow(); + } -} // namespace +} // namespace namespace { @@ -391,7 +394,7 @@ namespace SString GetAttribute(const SString& strName) const { const SString* pValue = MapFind(attributeMap, strName); - return pValue ? *pValue : ""; + return pValue ? *pValue : SStringX(""); } void SetAttribute(const SString& strName, const SString& strValue) { MapSet(attributeMap, strName, strValue); } }; @@ -606,7 +609,7 @@ namespace SaveReportSettings(); } - SString GetFilter() const { return strFilter != "" ? strFilter : "+all"; } + SString GetFilter() const { return strFilter != "" ? strFilter : SStringX("+all"); } int GetMinSize() const { return iMinSize; } @@ -656,7 +659,7 @@ namespace } }; -} // namespace +} // namespace namespace { @@ -755,7 +758,7 @@ namespace } }; -} // namespace +} // namespace namespace { @@ -858,7 +861,7 @@ namespace } slim; }; -} // namespace +} // namespace namespace { @@ -883,11 +886,11 @@ namespace CStringPair pair; pair.strValue1 = strValue1.ToLower(); pair.strValue2 = strValue2.ToLower(); - #if MTA_DEBUG +#if MTA_DEBUG CStringPair* pPair = MapFind(*this, strType.ToLower()); if (!pPair || pPair->strValue1 != pair.strValue1 || pPair->strValue2 != pair.strValue2) OutputDebugLine(SString("[Updater] SetCondition %s %s %s", strType.c_str(), strValue1.c_str(), strValue2.c_str())); - #endif +#endif MapSet(*this, strType.ToLower(), pair); } @@ -939,4 +942,4 @@ namespace class ExceptionQuitProgram : public std::exception { }; -} // namespace +} // namespace diff --git a/Client/core/CVersionUpdater.cpp b/Client/core/CVersionUpdater.cpp index 90c6e17ecb2..fbf3af664d4 100644 --- a/Client/core/CVersionUpdater.cpp +++ b/Client/core/CVersionUpdater.cpp @@ -90,6 +90,7 @@ class CVersionUpdater : public CVersionUpdaterInterface void _UseCrashDumpPostContent(); void _ShouldSendCrashDump(); void _ResetLastCrashDump(); + int ValidateCrashDumpPath(const SString& strPathFilename, SString* pOutErrorMsg, bool bCheckFileExists = false); void _ActionReconnect(); void _DialogHide(); void _ExitGame(); @@ -114,7 +115,7 @@ class CVersionUpdater : public CVersionUpdaterInterface void _DialogExeFilesResult(); void _StartDownload(); int _PollDownload(); - void _StartSendPost(); + bool _StartSendPost(); int _PollSendPost(); void _CheckSidegradeRequirements(); void _DoSidegradeLaunch(); @@ -1151,40 +1152,40 @@ void CVersionUpdater::ProcessCommand(EUpdaterProgramType eProgramType) /////////////////////////////////////////////////////////////// void CVersionUpdater::Program_VersionCheck() { - _UseVersionQueryURLs(); // Use VERSION_CHECKER_URL* - _StartDownload(); // Fetch update info from update server + _UseVersionQueryURLs(); // Use VERSION_CHECKER_URL* + _StartDownload(); // Fetch update info from update server _ProcessPatchFileQuery(); if (m_ConditionMap.IsConditionTrue("ProcessResponse.update")) - goto dload; // If update server says 'update' then goto dload + goto dload; // If update server says 'update' then goto dload if (m_ConditionMap.IsConditionTrue("ProcessResponse.files")) - goto dload; // If update server says 'files' then goto dload: + goto dload; // If update server says 'files' then goto dload: if (m_ConditionMap.IsConditionTrue("ProcessResponse.silent")) - goto silentdload; // If update server says 'silent' then goto silentdload: + goto silentdload; // If update server says 'silent' then goto silentdload: if (m_ConditionMap.IsConditionTrue("ProcessResponse.noupdate")) - goto noupdate; // If update server says 'noupdate' then goto noupdate: + goto noupdate; // If update server says 'noupdate' then goto noupdate: return; dload: - _DialogUpdateQuestion(); // Show "Update available" dialog + _DialogUpdateQuestion(); // Show "Update available" dialog if (m_ConditionMap.IsConditionTrue("QuestionResponse.!Yes")) - goto end; // If user says 'No', then goto end: - _DialogDownloading(); // Show "Downloading..." message + goto end; // If user says 'No', then goto end: + _DialogDownloading(); // Show "Downloading..." message _UseProvidedURLs(); - _StartDownload(); // Fetch update binary from update mirror + _StartDownload(); // Fetch update binary from update mirror _ProcessPatchFileDownload(); - _DialogUpdateResult(); // Show "Update ok/failed" message + _DialogUpdateResult(); // Show "Update ok/failed" message return; silentdload: _UseProvidedURLs(); - _StartDownload(); // Fetch update binary from update mirror + _StartDownload(); // Fetch update binary from update mirror _ProcessPatchFileDownload(); - _QUpdateResult(); // Maybe set OnRestartCommand + _QUpdateResult(); // Maybe set OnRestartCommand return; noupdate: - _ResetVersionCheckTimer(); // Wait 24hrs before checking again + _ResetVersionCheckTimer(); // Wait 24hrs before checking again return; end: @@ -1201,37 +1202,37 @@ void CVersionUpdater::Program_VersionCheck() /////////////////////////////////////////////////////////////// void CVersionUpdater::Program_ManualCheck() { - _UseVersionQueryURLs(); // Use VERSION_CHECKER_URL* - _DialogChecking(); // Show "Checking..." message - _StartDownload(); // Fetch update info from update server + _UseVersionQueryURLs(); // Use VERSION_CHECKER_URL* + _DialogChecking(); // Show "Checking..." message + _StartDownload(); // Fetch update info from update server _ProcessPatchFileQuery(); if (m_ConditionMap.IsConditionTrue("ProcessResponse.update")) - goto dload; // If update server says 'update' then goto dload: + goto dload; // If update server says 'update' then goto dload: if (m_ConditionMap.IsConditionTrue("ProcessResponse.files")) - goto dload; // If update server says 'files' then goto dload: + goto dload; // If update server says 'files' then goto dload: if (m_ConditionMap.IsConditionTrue("ProcessResponse.silent")) - goto dload; // If update server says 'silent' then goto dload: + goto dload; // If update server says 'silent' then goto dload: if (m_ConditionMap.IsConditionTrue("ProcessResponse.noupdate")) - goto noupdate; // If update server says 'noupdate' then goto noupdate: + goto noupdate; // If update server says 'noupdate' then goto noupdate: if (m_ConditionMap.IsConditionTrue("ProcessResponse.cancel")) goto end; _DialogUpdateQueryError(); return; dload: - _DialogUpdateQuestion(); // Show "Update available" dialog + _DialogUpdateQuestion(); // Show "Update available" dialog if (m_ConditionMap.IsConditionTrue("QuestionResponse.!Yes")) - goto end; // If user says 'No', then goto end: - _DialogDownloading(); // Show "Downloading..." message + goto end; // If user says 'No', then goto end: + _DialogDownloading(); // Show "Downloading..." message _UseProvidedURLs(); - _StartDownload(); // Fetch update binary from update mirror + _StartDownload(); // Fetch update binary from update mirror _ProcessPatchFileDownload(); - _DialogUpdateResult(); // Show "Update ok/failed" message + _DialogUpdateResult(); // Show "Update ok/failed" message return; noupdate: - _ResetManualCheckTimer(); // Wait 1min before checking again - _DialogNoUpdate(); // Show "No update available" dialog + _ResetManualCheckTimer(); // Wait 1min before checking again + _DialogNoUpdate(); // Show "No update available" dialog return; end: @@ -1247,7 +1248,7 @@ void CVersionUpdater::Program_ManualCheck() /////////////////////////////////////////////////////////////// void CVersionUpdater::Program_ManualCheckSim() { - _DialogNoUpdate(); // Show "No update available" dialog + _DialogNoUpdate(); // Show "No update available" dialog return; } @@ -1260,28 +1261,28 @@ void CVersionUpdater::Program_ManualCheckSim() /////////////////////////////////////////////////////////////// void CVersionUpdater::Program_ServerSaysUpdate() { - _UseVersionQueryURLs(); // Use VERSION_CHECKER_URL* - _DialogServerSaysUpdateQuestion(); // Show "Server says update" dialog + _UseVersionQueryURLs(); // Use VERSION_CHECKER_URL* + _DialogServerSaysUpdateQuestion(); // Show "Server says update" dialog if (m_ConditionMap.IsConditionTrue("QuestionResponse.!Yes")) - goto end; // If user says 'No', then goto end: - _DialogChecking(); // Show "Checking..." message - _StartDownload(); // Fetch update info from update server + goto end; // If user says 'No', then goto end: + _DialogChecking(); // Show "Checking..." message + _StartDownload(); // Fetch update info from update server _ProcessPatchFileQuery(); if (m_ConditionMap.IsConditionTrue("ProcessResponse.update")) - goto dload; // If update server says 'update' then goto dload: + goto dload; // If update server says 'update' then goto dload: if (m_ConditionMap.IsConditionTrue("ProcessResponse.files")) - goto dload; // If update server says 'files' then goto dload: + goto dload; // If update server says 'files' then goto dload: if (m_ConditionMap.IsConditionTrue("ProcessResponse.silent")) - goto dload; // If update server says 'silent' then goto dload: + goto dload; // If update server says 'silent' then goto dload: _DialogUpdateQueryError(); return; dload: - _DialogDownloading(); // Show "Downloading..." message + _DialogDownloading(); // Show "Downloading..." message _UseProvidedURLs(); - _StartDownload(); // Fetch update binary from update mirror + _StartDownload(); // Fetch update binary from update mirror _ProcessPatchFileDownload(); - _DialogUpdateResult(); // Show "Update ok/failed" message + _DialogUpdateResult(); // Show "Update ok/failed" message return; end: @@ -1297,37 +1298,37 @@ void CVersionUpdater::Program_ServerSaysUpdate() /////////////////////////////////////////////////////////////// void CVersionUpdater::Program_ServerSaysRecommend() { - _UseVersionQueryURLs(); // Use VERSION_CHECKER_URL* - _DialogConnectingWait(); // Show "Please wait..." message - _StartDownload(); // Fetch update info from update server + _UseVersionQueryURLs(); // Use VERSION_CHECKER_URL* + _DialogConnectingWait(); // Show "Please wait..." message + _StartDownload(); // Fetch update info from update server _ProcessPatchFileQuery(); if (m_ConditionMap.IsConditionTrue("ProcessResponse.update")) - goto dload; // If update server says 'update' then goto dload: + goto dload; // If update server says 'update' then goto dload: if (m_ConditionMap.IsConditionTrue("ProcessResponse.files")) - goto dload; // If update server says 'files' then goto dload: + goto dload; // If update server says 'files' then goto dload: if (m_ConditionMap.IsConditionTrue("ProcessResponse.silent")) - goto silentdload; // If update server says 'silent' then goto silentdload: + goto silentdload; // If update server says 'silent' then goto silentdload: _ActionReconnect(); return; dload: - _DialogServerSaysRecommendQuestion(); // Show "Server says update" dialog + _DialogServerSaysRecommendQuestion(); // Show "Server says update" dialog if (m_ConditionMap.IsConditionTrue("QuestionResponse.!Yes")) - goto reconnect; // If user says 'No', then goto reconnect: - _DialogDownloading(); // Show "Downloading..." message + goto reconnect; // If user says 'No', then goto reconnect: + _DialogDownloading(); // Show "Downloading..." message _UseProvidedURLs(); - _StartDownload(); // Fetch update binary from update mirror + _StartDownload(); // Fetch update binary from update mirror _ProcessPatchFileDownload(); - _DialogUpdateResult(); // Show "Update ok/failed" message + _DialogUpdateResult(); // Show "Update ok/failed" message return; silentdload: - _DialogHide(); // Don't show downloading progress - _ActionReconnect(); // Reconnect to game + _DialogHide(); // Don't show downloading progress + _ActionReconnect(); // Reconnect to game _UseProvidedURLs(); - _StartDownload(); // Fetch update binary from update mirror + _StartDownload(); // Fetch update binary from update mirror _ProcessPatchFileDownload(); - _QUpdateResult(); // Maybe set OnRestartCommand + _QUpdateResult(); // Maybe set OnRestartCommand return; reconnect: @@ -1357,8 +1358,8 @@ void CVersionUpdater::Program_ServerSaysDataFilesWrong() /////////////////////////////////////////////////////////////// void CVersionUpdater::Program_MasterFetch() { - _UseMasterFetchURLs(); // Use VERSION_CHECKER_URL* - _StartDownload(); // Fetch file info from server + _UseMasterFetchURLs(); // Use VERSION_CHECKER_URL* + _StartDownload(); // Fetch file info from server _ProcessMasterFetch(); if (m_ConditionMap.IsConditionTrue("ProcessResponse.!ok")) goto error1; @@ -1378,19 +1379,81 @@ void CVersionUpdater::Program_MasterFetch() /////////////////////////////////////////////////////////////// void CVersionUpdater::Program_SendCrashDump() { - _ShouldSendCrashDump(); // Have we already sent a matching dump? + bool bUploadSuccess = false; // Declare before any goto targets + + _ShouldSendCrashDump(); // Have we already sent a matching dump? if (m_ConditionMap.IsConditionTrue("ProcessResponse.!ok")) goto end; _UseCrashDumpQueryURLs(); _StartDownload(); - _ProcessCrashDumpQuery(); // Does the server want this dump? + _ProcessCrashDumpQuery(); // Does the server want this dump? if (m_ConditionMap.IsConditionTrue("ProcessResponse.!ok")) goto end; - _UseCrashDumpURLs(); // Use CRASH_DUMP_URL* - _UseCrashDumpPostContent(); // Use crash dump source - _StartSendPost(); // Send data + _UseCrashDumpURLs(); // Use CRASH_DUMP_URL* + _UseCrashDumpPostContent(); // Use crash dump source + + // Send data and check if upload succeeded + bUploadSuccess = _StartSendPost(); + + if (bUploadSuccess) + { + // Upload succeeded - clear all settings to prevent duplicate sends + SetApplicationSetting("diagnostics", "last-dump-save", ""); + SetApplicationSetting("diagnostics", "last-dump-load-retry", ""); + SetApplicationSetting("diagnostics", "last-dump-retry-time", ""); + SetApplicationSetting("diagnostics", "last-dump-complete", ""); + } + else + { + // Upload failed - retry with backoff + const int MAX_UPLOAD_RETRIES = 3; + int iCurrentRetry = GetApplicationSettingInt("diagnostics", "last-dump-load-retry"); + + if (iCurrentRetry < MAX_UPLOAD_RETRIES) + { + iCurrentRetry++; + SetApplicationSettingInt("diagnostics", "last-dump-load-retry", iCurrentRetry); + + // Store timestamp as string for backoff enforcement (prevents int overflow) + const long long llCurrentTimeSec = GetTickCount64_() / 1000; + SetApplicationSetting("diagnostics", "last-dump-retry-time", SString("%lld", llCurrentTimeSec)); + + // Calculate backoff delay + int iBackoffSeconds = 5; + for (int i = 1; i < iCurrentRetry; i++) + iBackoffSeconds *= 3; + + AddReportLog(9320, SString("Program_SendCrashDump: Upload failed (attempt %d/%d) - Will retry in %d seconds", iCurrentRetry, MAX_UPLOAD_RETRIES, + iBackoffSeconds)); + + // Reset flag to allow retry on next pulse + m_bSentCrashDump = false; + } + else + { + // Max retries exceeded - give up + AddReportLog(9321, SString("Program_SendCrashDump: Upload failed after %d attempts - Giving up", MAX_UPLOAD_RETRIES)); + _ResetLastCrashDump(); + } + } + return; + end: - _ResetLastCrashDump(); + // Only reset if we're not retrying + int iRetryCount = GetApplicationSettingInt("diagnostics", "last-dump-load-retry"); + if (iRetryCount == 0) + { + const SString strDumpSave = GetApplicationSetting("diagnostics", "last-dump-save"); + const SString strDumpComplete = GetApplicationSetting("diagnostics", "last-dump-complete"); + + if (strDumpSave.length() > 0 && strDumpComplete != "1") + { + } + else + { + _ResetLastCrashDump(); + } + } return; } @@ -1403,9 +1466,9 @@ void CVersionUpdater::Program_SendCrashDump() /////////////////////////////////////////////////////////////// void CVersionUpdater::Program_SendReportLog() { - _UseReportLogURLs(); // Use REPORT_LOG_URL* - _UseReportLogPostContent(); // Use report log source - _StartSendPost(); // Send data + _UseReportLogURLs(); // Use REPORT_LOG_URL* + _UseReportLogPostContent(); // Use report log source + _StartSendPost(); // Send data } /////////////////////////////////////////////////////////////// @@ -1417,37 +1480,37 @@ void CVersionUpdater::Program_SendReportLog() /////////////////////////////////////////////////////////////// void CVersionUpdater::Program_SidegradeLaunch() { - _CheckSidegradeRequirements(); // Check if other version already installed + _CheckSidegradeRequirements(); // Check if other version already installed if (m_ConditionMap.IsConditionTrue("ProcessResponse.!installed")) - goto notinstalled; // Other version present and valid? - _DialogSidegradeLaunchQuestion(); // Does user want to launch and connect using the other version? + goto notinstalled; // Other version present and valid? + _DialogSidegradeLaunchQuestion(); // Does user want to launch and connect using the other version? if (m_ConditionMap.IsConditionTrue("QuestionResponse.!Yes")) goto nolaunch; - _DoSidegradeLaunch(); // If user says 'Yes', then launch + _DoSidegradeLaunch(); // If user says 'Yes', then launch nolaunch: return; notinstalled: - _UseSidegradeURLs(); // Use sidegrade URLs - _StartDownload(); // Fetch file info from server + _UseSidegradeURLs(); // Use sidegrade URLs + _StartDownload(); // Fetch file info from server _ProcessPatchFileQuery(); if (m_ConditionMap.IsConditionTrue("ProcessResponse.update")) - goto hasfile; // Does server have the required file? - _DialogSidegradeQueryError(); // If no download available, show message + goto hasfile; // Does server have the required file? + _DialogSidegradeQueryError(); // If no download available, show message return; hasfile: - _DialogSidegradeDownloadQuestion(); // If it is downloadable, ask user what to do + _DialogSidegradeDownloadQuestion(); // If it is downloadable, ask user what to do if (m_ConditionMap.IsConditionTrue("QuestionResponse.Yes")) goto yesdownload; - return; // If user says 'No', then finish + return; // If user says 'No', then finish yesdownload: - _DialogDownloading(); // Show "Downloading..." message + _DialogDownloading(); // Show "Downloading..." message _UseProvidedURLs(); - _StartDownload(); // Fetch file binary from mirror + _StartDownload(); // Fetch file binary from mirror _ProcessPatchFileDownload(); - _DialogExeFilesResult(); // Show "ok/failed" message + _DialogExeFilesResult(); // Show "ok/failed" message return; } @@ -1460,24 +1523,24 @@ void CVersionUpdater::Program_SidegradeLaunch() /////////////////////////////////////////////////////////////// void CVersionUpdater::Program_NewsUpdate() { - _UseNewsUpdateURLs(); // Use news serverlist - _StartDownload(); // Fetch update info from update server + _UseNewsUpdateURLs(); // Use news serverlist + _StartDownload(); // Fetch update info from update server _ProcessPatchFileQuery(); if (m_ConditionMap.IsConditionTrue("ProcessResponse.silent")) - goto silentdload; // If update server says 'silent' then goto silentdload: + goto silentdload; // If update server says 'silent' then goto silentdload: if (m_ConditionMap.IsConditionTrue("ProcessResponse.noupdate")) - goto noupdate; // If update server says 'noupdate' then goto noupdate: + goto noupdate; // If update server says 'noupdate' then goto noupdate: return; silentdload: _UseProvidedURLs(); - _StartDownload(); // Fetch update binary from update mirror + _StartDownload(); // Fetch update binary from update mirror _ProcessPatchFileDownload(); - _QUpdateNewsResult(); // Maybe update news install queue + _QUpdateNewsResult(); // Maybe update news install queue return; noupdate: - _ResetNewsCheckTimer(); // Wait interval before checking again + _ResetNewsCheckTimer(); // Wait interval before checking again return; } @@ -2312,7 +2375,7 @@ void CVersionUpdater::_ProcessPatchFileQuery() // If version check file says there is a new master config file, force update next time m_VarConfig.master_lastCheckTime.SetFromSeconds(0); if (m_JobInfo.strStatus == "noupdate") - OnPossibleConfigProblem(); // Do it this time if no update here + OnPossibleConfigProblem(); // Do it this time if no update here } } @@ -2769,8 +2832,11 @@ int CVersionUpdater::_PollDownload() } if (m_JobInfo.bShowDownloadPercent) { - const bool bIsDownloadedSizeRight = m_JobInfo.uiBytesDownloaded > 0 && m_JobInfo.iFilesize >= m_JobInfo.uiBytesDownloaded; - const int fDownloadedPercent = bIsDownloadedSizeRight ? Round((float)m_JobInfo.uiBytesDownloaded / m_JobInfo.iFilesize * 100.f) : 0; + const unsigned int uiBytesDownloaded = m_JobInfo.uiBytesDownloaded; + const int iFilesize = m_JobInfo.iFilesize; + const bool bIsDownloadedSizeRight = uiBytesDownloaded > 0 && iFilesize > 0 && static_cast(iFilesize) >= uiBytesDownloaded; + const int fDownloadedPercent = + bIsDownloadedSizeRight ? Round(static_cast(uiBytesDownloaded) / static_cast(iFilesize) * 100.f) : 0; GetQuestionBox().SetMessage(SString(_("%3d %% completed"), fDownloadedPercent)); } if (m_JobInfo.iIdleTime > 1000 && m_JobInfo.iIdleTimeLeft > 500) @@ -2839,6 +2905,96 @@ void CVersionUpdater::_UseReportLogPostContent() GetReportWrap()->ClearLogContents("-all"); } +int CVersionUpdater::ValidateCrashDumpPath(const SString& strPathFilename, SString* pOutErrorMsg, bool bCheckFileExists) +{ + // Constants for validation with constexpr for compile-time evaluation + constexpr size_t MAX_PATH_LENGTH = 32767; + constexpr size_t MAX_DUMP_FILE_SIZE = 2 * 1024 * 1024; + constexpr size_t MAX_PATH_COMPONENTS = 256; + constexpr size_t PATH_PARTS_RESERVE = 32; + constexpr size_t MAX_DUMP_FILE_SIZE_MB = MAX_DUMP_FILE_SIZE / (1024 * 1024); + + if (const size_t pathLength = strPathFilename.length(); pathLength > MAX_PATH_LENGTH) + { + if (pOutErrorMsg) + *pOutErrorMsg = SString("Path too long (%d > %d)", pathLength, MAX_PATH_LENGTH); + return 9311; + } + + if (!strPathFilename.EndsWithI(".dmp")) + { + if (pOutErrorMsg) + *pOutErrorMsg = "Invalid file extension (must be .dmp)"; + return 9315; + } + + auto validatePathParts = [&](const SString& separator) noexcept -> int + { + std::vector pathParts; + pathParts.reserve(PATH_PARTS_RESERVE); + strPathFilename.Split(separator, pathParts); + + if (const size_t numParts = pathParts.size(); numParts > MAX_PATH_COMPONENTS) + { + if (pOutErrorMsg) + *pOutErrorMsg = SString("Too many path components (%d > %d)", numParts, MAX_PATH_COMPONENTS); + return 9315; + } + + for (const auto& part : pathParts) + { + if (part == "..") + { + if (pOutErrorMsg) + *pOutErrorMsg = "Path traversal detected"; + return 9312; + } + } + return 0; + }; + + if (const int result = validatePathParts(PATH_SEPERATOR); result != 0) + return result; + + if (const bool hasForwardSlash = strPathFilename.Contains("/"); hasForwardSlash) + { + if (const int result = validatePathParts("/"); result != 0) + return result; + } + + if (bCheckFileExists) + { + if (FILE* pFile = File::Fopen(strPathFilename, "rb"); !pFile) + { + if (pOutErrorMsg) + *pOutErrorMsg = "File does not exist or cannot be opened"; + return 9317; + } + else + { + if (const int seekResult = fseek(pFile, 0, SEEK_END); seekResult != 0) + { + fclose(pFile); + if (pOutErrorMsg) + *pOutErrorMsg = "Failed to seek in file"; + return 9317; + } + + const long fileSize = ftell(pFile); + fclose(pFile); + + if (const bool isInvalidSize = fileSize < 0 || static_cast(fileSize) > MAX_DUMP_FILE_SIZE; isInvalidSize) + { + if (pOutErrorMsg) + *pOutErrorMsg = SString("File too large (%d bytes, max %d MB)", fileSize, MAX_DUMP_FILE_SIZE_MB); + return 9316; + } + } + } + + return 0; +} + /////////////////////////////////////////////////////////////// // // CVersionUpdater::_ShouldSendCrashDump @@ -2848,59 +3004,122 @@ void CVersionUpdater::_UseReportLogPostContent() /////////////////////////////////////////////////////////////// void CVersionUpdater::_ShouldSendCrashDump() { - m_ConditionMap.SetCondition("ProcessResponse", ""); + // constexpr string literals for diagnostics settings keys + constexpr const char* DIAGNOSTICS_SECTION = "diagnostics"; + constexpr const char* LAST_DUMP_SAVE = "last-dump-save"; + constexpr const char* LAST_DUMP_TAG = "last-dump-tag"; + constexpr const char* LAST_DUMP_DATETIME = "last-dump-datetime"; + constexpr const char* PROCESS_RESPONSE = "ProcessResponse"; + constexpr const char* RESPONSE_OK = "ok"; + constexpr const char* EMPTY_VALUE = ""; - // Add to history - SString strPathFilename = GetApplicationSetting("diagnostics", "last-dump-save"); + m_ConditionMap.SetCondition(PROCESS_RESPONSE, EMPTY_VALUE); - // Extract module and address from filename - std::vector parts; - strPathFilename.Split("_", parts); - if (parts.size() > DUMP_PART_TIME) + if (const SString strPathFilename = GetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_SAVE); strPathFilename.empty()) + { + return; + } + else { - SString strVersionAndModuleAndOffset = parts[DUMP_PART_VERSION] + "_" + parts[DUMP_PART_MODULE] + "_" + parts[DUMP_PART_OFFSET]; + if (SString strErrorMsg; const int iValidationResult = ValidateCrashDumpPath(strPathFilename, &strErrorMsg, true)) + { + AddReportLog(iValidationResult, SString("_ShouldSendCrashDump: %s", *strErrorMsg)); + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_SAVE, EMPTY_VALUE); // Clear invalid path + return; + } + + SString strFilename; + strPathFilename.Split(PATH_SEPERATOR, nullptr, &strFilename, -1); + + // constexpr validation constants for compile-time evaluation + constexpr size_t MAX_FILENAME_LENGTH = 2048; + constexpr size_t MAX_FILENAME_PARTS = 64; + constexpr size_t PARTS_RESERVE = 8; + constexpr size_t MAX_TAG_LENGTH = 1024; + constexpr size_t MAX_DATETIME_LENGTH = 256; + constexpr size_t MAX_HISTORY_SIZE = 100000; + constexpr int MAX_DUPLICATE_COUNT = 10000; + + if (const size_t filenameLength = strFilename.length(); filenameLength > MAX_FILENAME_LENGTH) + { + AddReportLog(9325, SString("_ShouldSendCrashDump: Filename too long (%d > %d)", filenameLength, MAX_FILENAME_LENGTH)); + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_SAVE, EMPTY_VALUE); + return; + } + + std::vector parts; + parts.reserve(PARTS_RESERVE); + strFilename.Split("_", parts); + + if (const size_t numParts = parts.size(); numParts > MAX_FILENAME_PARTS) + { + AddReportLog(9315, SString("_ShouldSendCrashDump: Too many filename parts (%d > %d)", numParts, MAX_FILENAME_PARTS)); + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_SAVE, EMPTY_VALUE); + return; + } + + if (const size_t maxRequiredIndex = std::max({DUMP_PART_VERSION, DUMP_PART_MODULE, DUMP_PART_OFFSET, DUMP_PART_DATE, DUMP_PART_TIME}); + parts.size() <= maxRequiredIndex) + { + AddReportLog(9313, SString("_ShouldSendCrashDump: Insufficient filename parts (parts=%d, max index=%d)", parts.size(), maxRequiredIndex)); + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_SAVE, EMPTY_VALUE); + return; + } + + const SString strVersionAndModuleAndOffset = parts[DUMP_PART_VERSION] + "_" + parts[DUMP_PART_MODULE] + "_" + parts[DUMP_PART_OFFSET]; + + if (const size_t tagLength = strVersionAndModuleAndOffset.length(); tagLength > MAX_TAG_LENGTH) + { + AddReportLog(9326, SString("_ShouldSendCrashDump: Tag too long (%d > %d)", tagLength, MAX_TAG_LENGTH)); + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_SAVE, EMPTY_VALUE); + return; + } + SString strDateAndTime = parts[DUMP_PART_DATE] + "_" + parts[DUMP_PART_TIME]; - strDateAndTime.Split(".", &strDateAndTime, NULL); + strDateAndTime.Split(".", &strDateAndTime, nullptr); // Remove .dmp extension from time part + + if (const size_t dateTimeLength = strDateAndTime.length(); dateTimeLength > MAX_DATETIME_LENGTH) + { + AddReportLog(9327, SString("_ShouldSendCrashDump: Date/time string too long (%d > %d)", dateTimeLength, MAX_DATETIME_LENGTH)); + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_SAVE, EMPTY_VALUE); + return; + } - // Check history for duplicates CDataInfoSet& history = m_VarConfig.crashdump_history; - int iDuplicates = 0; - for (uint i = 0; i < history.size(); i++) - if (strVersionAndModuleAndOffset == history[i].GetAttribute("tag")) - iDuplicates++; - // Add to history - if (iDuplicates <= m_MasterConfig.crashdump.iDuplicates) + if (const size_t historySize = history.size(); historySize > MAX_HISTORY_SIZE) { - SDataInfoItem item; - item.strName = "dump"; - item.SetAttribute("tag", strVersionAndModuleAndOffset); - item.SetAttribute("date", strDateAndTime); - history.push_back(item); + AddReportLog(9318, SString("_ShouldSendCrashDump: History size limit exceeded (%d > %d)", historySize, MAX_HISTORY_SIZE)); + // Aggressively trim to half of max size with explicit calculation + constexpr size_t TRIM_TO_RATIO = 2; // Keep half when trimming + history.erase(history.begin(), history.begin() + (historySize - MAX_HISTORY_SIZE / TRIM_TO_RATIO)); + CCore::GetSingleton().SaveConfig(); } - else - return; - // Sort by date - for (int i = 0; i < (int)history.size() - 1; i++) + int iDuplicates = 0; + for (const auto& item : history) { - SDataInfoItem& a = history[i]; - SDataInfoItem& b = history[i + 1]; - if (a.GetAttribute("date") > b.GetAttribute("date")) + // Use if-init to cache GetAttribute result and compare + if (const SString& itemTag = item.GetAttribute("tag"); strVersionAndModuleAndOffset == itemTag) { - std::swap(a, b); - i = std::max(i - 2, -1); + if (++iDuplicates > MAX_DUPLICATE_COUNT) + { + AddReportLog(9314, SString("_ShouldSendCrashDump: Excessive duplicates detected (%d+)", MAX_DUPLICATE_COUNT)); + return; + } } } - // Remove oldest if required - int iNumToRemove = history.size() - m_MasterConfig.crashdump.iMaxHistoryLength; - if (iNumToRemove > 0) - history.erase(history.begin(), history.begin() + iNumToRemove); + if (const int duplicateLimit = static_cast(m_MasterConfig.crashdump.iDuplicates); iDuplicates > duplicateLimit) + { + AddReportLog(9314, SString("_ShouldSendCrashDump: Duplicate limit reached (%d/%d)", iDuplicates, duplicateLimit)); + return; + } - CCore::GetSingleton().SaveConfig(); + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_TAG, strVersionAndModuleAndOffset); + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_DATETIME, strDateAndTime); - m_ConditionMap.SetCondition("ProcessResponse", "ok"); + m_ConditionMap.SetCondition(PROCESS_RESPONSE, RESPONSE_OK); } } @@ -2914,6 +3133,11 @@ void CVersionUpdater::_ShouldSendCrashDump() void CVersionUpdater::_ResetLastCrashDump() { SetApplicationSetting("diagnostics", "last-dump-save", ""); + SetApplicationSetting("diagnostics", "last-dump-load-retry", ""); + SetApplicationSetting("diagnostics", "last-dump-retry-time", ""); + SetApplicationSetting("diagnostics", "last-dump-complete", ""); + SetApplicationSetting("diagnostics", "last-dump-tag", ""); + SetApplicationSetting("diagnostics", "last-dump-datetime", ""); } /////////////////////////////////////////////////////////////// @@ -2925,11 +3149,56 @@ void CVersionUpdater::_ResetLastCrashDump() /////////////////////////////////////////////////////////////// void CVersionUpdater::_UseCrashDumpQueryURLs() { + constexpr const char* DIAGNOSTICS_SECTION = "diagnostics"; + constexpr const char* LAST_DUMP_SAVE = "last-dump-save"; + constexpr const char* EMPTY_VALUE = ""; + + constexpr size_t MAX_POST_FILENAME_LENGTH = 1024; + constexpr unsigned char CONTROL_CHAR_THRESHOLD = 32; + constexpr unsigned char DELETE_CHAR = 127; + constexpr char REPLACEMENT_CHAR = '_'; + + // Initialize job info with server list m_JobInfo = SJobInfo(); m_JobInfo.serverList = MakeServerList(m_MasterConfig.crashdump.serverInfoMap); - SString strPathFilename = GetApplicationSetting("diagnostics", "last-dump-save"); - strPathFilename.Split(PATH_SEPERATOR, NULL, &m_JobInfo.strPostFilename, -1); + if (const SString strPathFilename = GetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_SAVE); strPathFilename.empty()) + { + return; + } + else + { + if (SString strErrorMsg; const int iValidationResult = ValidateCrashDumpPath(strPathFilename, &strErrorMsg)) + { + AddReportLog(iValidationResult, SString("_UseCrashDumpQueryURLs: %s", *strErrorMsg)); + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_SAVE, EMPTY_VALUE); // Clear invalid path + return; + } + + // Extract filename from path + SString strFilename; + strPathFilename.Split(PATH_SEPERATOR, nullptr, &strFilename, -1); + + if (const size_t queryFilenameLength = strFilename.length(); queryFilenameLength > MAX_POST_FILENAME_LENGTH) + { + AddReportLog(9328, SString("_UseCrashDumpQueryURLs: Filename too long (%d > %d)", queryFilenameLength, MAX_POST_FILENAME_LENGTH)); + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_SAVE, EMPTY_VALUE); + return; + } + + const auto is_control_char = [CONTROL_CHAR_THRESHOLD, DELETE_CHAR](unsigned char c) noexcept -> bool + { return c < CONTROL_CHAR_THRESHOLD || c == DELETE_CHAR; }; + + SString strSanitizedFilename = strFilename; + + for (auto& ch : strSanitizedFilename) + { + if (is_control_char(static_cast(ch))) + ch = REPLACEMENT_CHAR; + } + + m_JobInfo.strPostFilename = strSanitizedFilename; + } } /////////////////////////////////////////////////////////////// @@ -2941,16 +3210,84 @@ void CVersionUpdater::_UseCrashDumpQueryURLs() /////////////////////////////////////////////////////////////// void CVersionUpdater::_ProcessCrashDumpQuery() { - m_ConditionMap.SetCondition("ProcessResponse", ""); + constexpr const char* PROCESS_RESPONSE = "ProcessResponse"; + constexpr const char* DIAGNOSTICS_SECTION = "diagnostics"; + constexpr const char* LAST_DUMP_TAG = "last-dump-tag"; + constexpr const char* LAST_DUMP_DATETIME = "last-dump-datetime"; + constexpr const char* EMPTY_VALUE = ""; + constexpr const char* RESPONSE_OK = "ok"; + constexpr const char* RESPONSE_YES = "yes"; + constexpr const char* DUMP_ITEM_NAME = "dump"; + constexpr const char* TAG_ATTRIBUTE = "tag"; + constexpr const char* DATE_ATTRIBUTE = "date"; - if (m_JobInfo.downloadBuffer.size() == 0) + constexpr size_t MAX_RESPONSE_SIZE = 10 * 1024 * 1024; + + m_ConditionMap.SetCondition(PROCESS_RESPONSE, EMPTY_VALUE); + + // Early return if no download buffer + if (const bool hasData = !m_JobInfo.downloadBuffer.empty(); !hasData) return; - SStringX strResponse(&m_JobInfo.downloadBuffer[0], m_JobInfo.downloadBuffer.size()); + if (const size_t responseSize = m_JobInfo.downloadBuffer.size(); responseSize > MAX_RESPONSE_SIZE) + { + AddReportLog(9319, SString("_ProcessCrashDumpQuery: Response too large (%d > %d)", responseSize, MAX_RESPONSE_SIZE)); + return; + } - // Is the dump file wanted? - if (strResponse.BeginsWithI("yes")) - m_ConditionMap.SetCondition("ProcessResponse", "ok"); + const SStringX strResponse(m_JobInfo.downloadBuffer.data(), m_JobInfo.downloadBuffer.size()); + + // Check if dump is wanted + if (const bool isDumpWanted = strResponse.BeginsWithI(RESPONSE_YES); isDumpWanted) + { + // Server confirmed it wants the dump - retrieve metadata + if (const SString strTag = GetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_TAG), + strDateTime = GetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_DATETIME); + !strTag.empty() && !strDateTime.empty()) + { + CDataInfoSet& history = m_VarConfig.crashdump_history; + + // Add to history + SDataInfoItem item; + item.strName = DUMP_ITEM_NAME; + item.SetAttribute(TAG_ATTRIBUTE, strTag); + item.SetAttribute(DATE_ATTRIBUTE, strDateTime); + history.push_back(item); + + // Trim history if needed + if (const size_t historySize = history.size(); historySize > static_cast(m_MasterConfig.crashdump.iMaxHistoryLength)) + { + // Lambda for date comparison (GetAttribute is evaluated at runtime) + auto date_comparator = [](const SDataInfoItem& a, const SDataInfoItem& b) noexcept -> bool + { return a.GetAttribute("date") < b.GetAttribute("date"); }; + std::sort(history.begin(), history.end(), date_comparator); + + // Remove oldest entries + // Note: If numToRemove exceeds MAX_HISTORY_EXCESS, trim to safe limit to prevent oversized history + if (const size_t numToRemove = historySize - m_MasterConfig.crashdump.iMaxHistoryLength; numToRemove > 0) + { + constexpr size_t MAX_HISTORY_EXCESS = 1000; + const size_t actualRemove = (numToRemove > MAX_HISTORY_EXCESS) ? (historySize - MAX_HISTORY_EXCESS) : numToRemove; + history.erase(history.begin(), history.begin() + actualRemove); + } + } + + // Save config + CCore::GetSingleton().SaveConfig(); + + // Clear metadata settings using constexpr string literals + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_TAG, EMPTY_VALUE); + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_DATETIME, EMPTY_VALUE); + } + + m_ConditionMap.SetCondition(PROCESS_RESPONSE, RESPONSE_OK); + } + else + { + // Server rejected dump or sent invalid response - clear temporary metadata + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_TAG, EMPTY_VALUE); + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_DATETIME, EMPTY_VALUE); + } } /////////////////////////////////////////////////////////////// @@ -2970,27 +3307,179 @@ void CVersionUpdater::_UseCrashDumpURLs() // // CVersionUpdater::_UseCrashDumpPostContent // -// +// Load and prepare crash dump file for upload // /////////////////////////////////////////////////////////////// void CVersionUpdater::_UseCrashDumpPostContent() { - // Get filename to send - SString strPathFilename = GetApplicationSetting("diagnostics", "last-dump-save"); - if (!strPathFilename.length()) + constexpr const char* DIAGNOSTICS_SECTION = "diagnostics"; + constexpr const char* LAST_DUMP_SAVE = "last-dump-save"; + constexpr const char* SEND_DUMPS = "send-dumps"; + constexpr const char* NO_SEND = "no"; + constexpr const char* LAST_DUMP_COMPLETE = "last-dump-complete"; + constexpr const char* COMPLETE_FLAG = "1"; + constexpr const char* LAST_DUMP_LOAD_RETRY = "last-dump-load-retry"; + constexpr const char* LAST_DUMP_RETRY_TIME = "last-dump-retry-time"; + constexpr const char* LOG_PREFIX = "_UseCrashDumpPostContent: "; + + constexpr size_t MAX_POST_FILENAME_LENGTH = 1024; + constexpr size_t MAX_POST_CONTENT_SIZE = 2 * 1024 * 1024; // 2 MB for minidumps + constexpr int MAX_LOAD_RETRIES = 3; + constexpr int INITIAL_BACKOFF_SECONDS = 5; + constexpr int BACKOFF_MULTIPLIER = 3; + constexpr uint32_t MDMP_SIGNATURE = 0x504D444D; // "MDMP" in little-endian + constexpr size_t MIN_SIGNATURE_SIZE = sizeof(uint32_t); + constexpr int MILLISECONDS_PER_SECOND = 1000; + + if (const SString strPathFilename = GetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_SAVE); strPathFilename.empty()) + { return; - SetApplicationSetting("diagnostics", "last-dump-save", ""); + } + else + { + // Early return if user disabled dump sending + if (const SString strSendDumps = GetApplicationSetting(DIAGNOSTICS_SECTION, SEND_DUMPS); strSendDumps == NO_SEND) + { + _ResetLastCrashDump(); + return; + } - // Get user pref - if (GetApplicationSetting("diagnostics", "send-dumps") == "no") - return; + // Validate path and file + SString strErrorMsg; + if (const int iValidationResult = ValidateCrashDumpPath(strPathFilename, &strErrorMsg, true); iValidationResult != 0) + { + AddReportLog(iValidationResult, SString("%s%s", LOG_PREFIX, *strErrorMsg)); + _ResetLastCrashDump(); + return; + } - // Load into post buffer - if (FileLoad(strPathFilename, m_JobInfo.postContent)) - { - // Set post filename without path - strPathFilename.Split(PATH_SEPERATOR, NULL, &m_JobInfo.strPostFilename, -1); - m_JobInfo.bPostContentBinary = true; + // Extract filename from path + SString strFilename; + strPathFilename.Split(PATH_SEPERATOR, nullptr, &strFilename, -1); + + // Validate filename length + if (const size_t postFilenameLength = strFilename.length(); postFilenameLength > MAX_POST_FILENAME_LENGTH) + { + AddReportLog(9329, SString("%sFilename too long (%d > %d)", LOG_PREFIX, postFilenameLength, MAX_POST_FILENAME_LENGTH)); + _ResetLastCrashDump(); + return; + } + + // Check if dump file writing is complete + if (const SString strDumpComplete = GetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_COMPLETE); strDumpComplete != COMPLETE_FLAG) + { + AddReportLog(9320, SString("%sDump file not yet complete - waiting for write to finish", LOG_PREFIX)); + + // Don't start retry counter yet - just wait for next pulse + // This prevents premature file access while crash handler is still writing + m_bSentCrashDump = false; + return; + } + + // Get current retry count + const int iCurrentRetry = GetApplicationSettingInt(DIAGNOSTICS_SECTION, LAST_DUMP_LOAD_RETRY); + + // Lambda for backoff calculation with explicit return type + const auto calculate_backoff = [INITIAL_BACKOFF_SECONDS, BACKOFF_MULTIPLIER](int retry_count) noexcept -> int + { + if (retry_count <= 0) + return 0; + int backoff = INITIAL_BACKOFF_SECONDS; + for (int i = 1; i < retry_count; ++i) + backoff *= BACKOFF_MULTIPLIER; + return backoff; + }; + + // Calculate backoff for current retry + const int iBackoffSeconds = calculate_backoff(iCurrentRetry); + + // Check if we need to wait for retry backoff delay + if (iCurrentRetry > 0) + { + // Get retry timestamp + const long long llRetryTimeSec = GetApplicationSettingInt(DIAGNOSTICS_SECTION, LAST_DUMP_RETRY_TIME); + const long long llCurrentTimeSec = GetTickCount64_() / MILLISECONDS_PER_SECOND; + const long long llElapsedSec = llCurrentTimeSec - llRetryTimeSec; + + // Check if backoff delay has elapsed + if (llElapsedSec >= 0 && llElapsedSec < iBackoffSeconds) + { + // Still waiting for backoff delay + m_bSentCrashDump = false; + return; + } + } + + // Attempt to load file + if (const bool bLoadSuccess = FileLoad(strPathFilename, m_JobInfo.postContent); bLoadSuccess) + { + if (m_JobInfo.postContent.empty()) + { + AddReportLog(9317, SString("%sLoaded content is empty", LOG_PREFIX)); + _ResetLastCrashDump(); + return; + } + + // Validate content size + if (const size_t contentSize = m_JobInfo.postContent.size(); contentSize > MAX_POST_CONTENT_SIZE) + { + AddReportLog(9316, SString("%sLoaded content too large (%d > %d)", LOG_PREFIX, contentSize, MAX_POST_CONTENT_SIZE)); + m_JobInfo.postContent.clear(); + _ResetLastCrashDump(); + return; + } + + // Validate minidump signature + if (const size_t contentSize = m_JobInfo.postContent.size(); contentSize >= MIN_SIGNATURE_SIZE) + { + uint32_t signature; + memcpy(&signature, m_JobInfo.postContent.data(), sizeof(signature)); + + if (signature != MDMP_SIGNATURE) + { + AddReportLog(9322, SString("%sInvalid minidump signature (0x%08X, expected 0x%08X)", LOG_PREFIX, signature, MDMP_SIGNATURE)); + m_JobInfo.postContent.clear(); + _ResetLastCrashDump(); + return; + } + } + + // Set metadata - upload ready + m_JobInfo.strPostFilename = strFilename; + m_JobInfo.bPostContentBinary = true; + + // Don't clear settings yet - wait until upload succeeds + // Settings will be cleared in Program_SendCrashDump after _StartSendPost returns true + + AddReportLog(5200, SString("%sSuccessfully loaded crash dump file: %s (upload pending)", LOG_PREFIX, *strFilename)); + } + else + { + // File load failed - retry + if (const int iNextRetry = iCurrentRetry + 1; iNextRetry <= MAX_LOAD_RETRIES) + { + // Increment retry counter + SetApplicationSettingInt(DIAGNOSTICS_SECTION, LAST_DUMP_LOAD_RETRY, iNextRetry); + + // Store current timestamp for backoff delay + const long long llCurrentTimeSec = GetTickCount64_() / MILLISECONDS_PER_SECOND; + SetApplicationSetting(DIAGNOSTICS_SECTION, LAST_DUMP_RETRY_TIME, SString("%lld", llCurrentTimeSec)); + + // Calculate backoff for next retry + const int iNextBackoffSeconds = calculate_backoff(iNextRetry); + AddReportLog(9310, SString("%sFailed to load crash dump file (attempt %d/%d): %s - Will retry in %d seconds", LOG_PREFIX, iNextRetry, + MAX_LOAD_RETRIES, *strFilename, iNextBackoffSeconds)); + + // Reset flag to allow retry on next pulse (after backoff delay) + m_bSentCrashDump = false; + } + else + { + // Max retries exceeded - give up + AddReportLog(9324, SString("%sFailed to load crash dump file after %d attempts: %s - Giving up", LOG_PREFIX, MAX_LOAD_RETRIES, *strFilename)); + _ResetLastCrashDump(); + } + } } } @@ -2998,13 +3487,14 @@ void CVersionUpdater::_UseCrashDumpPostContent() // // CVersionUpdater::_StartSendPost // +// Returns true if upload succeeded, false on failure // // /////////////////////////////////////////////////////////////// -void CVersionUpdater::_StartSendPost() +bool CVersionUpdater::_StartSendPost() { if (!m_JobInfo.postContent.size()) - return; + return false; while (true) { @@ -3014,7 +3504,7 @@ void CVersionUpdater::_StartSendPost() case RES_FAIL: // Can't find any(more) servers to send a query to // Drop back to previous stack level - return; + return false; case RES_OK: { @@ -3022,11 +3512,10 @@ void CVersionUpdater::_StartSendPost() if (_PollSendPost() == RES_OK) { // Got a valid response - return; + return true; } // Connection to current server failed, try next server break; - break; } default: @@ -3114,7 +3603,7 @@ int CVersionUpdater::DoSendDownloadRequestToNextServer() unsigned short usNetRev = CCore::GetSingleton().GetNetwork()->GetNetRev(); unsigned short usNetRel = CCore::GetSingleton().GetNetwork()->GetNetRel(); SString strPlayerVersion("%d.%d.%d-%d.%05d.%d.%03d", MTASA_VERSION_MAJOR, MTASA_VERSION_MINOR, MTASA_VERSION_MAINTENANCE, MTASA_VERSION_TYPE, - MTASA_VERSION_BUILD, usNetRev, usNetRel); + MTASA_VERSION_BUILD, usNetRev, usNetRel); SString strUpdateBuildType; CVARS_GET("update_build_type", strUpdateBuildType); @@ -3131,9 +3620,9 @@ int CVersionUpdater::DoSendDownloadRequestToNextServer() fseek(fh, 0x38BDC80, SEEK_SET); for (uint i = 0; i < 20; i++) if (fgetc(fh)) - strSoundCut = "n"; // Non-zero found + strSoundCut = "n"; // Non-zero found if (ferror(fh)) - strSoundCut = "e"; // File error + strSoundCut = "e"; // File error fclose(fh); } } @@ -3155,69 +3644,80 @@ int CVersionUpdater::DoSendDownloadRequestToNextServer() iReqKB3035131 = IsHotFixInstalled("KB3035131") ? 0 : 1; } - bool bSecureBootEnabled = - (GetSystemRegistryValue((uint)HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\SecureBoot\\State", "UEFISecureBootEnabled") == "\x01"); + int secureBootStatus = 0; + const SString secureBootValue = + GetSystemRegistryValue((uint)HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\SecureBoot\\State", "UEFISecureBootEnabled", &secureBootStatus); + bool bSecureBootEnabled = false; + if (secureBootStatus > 0) + { + // Parse the registry value into a numeric flag + char* secureBootEnd = nullptr; + const long secureBootNumeric = strtol(secureBootValue.c_str(), &secureBootEnd, 10); + if (secureBootEnd != secureBootValue.c_str() && *secureBootEnd == '\0') + { + bSecureBootEnabled = secureBootNumeric != 0; + } + } // Compile some system stats SDxStatus dxStatus; g_pGraphics->GetRenderItemManager()->GetDxStatus(dxStatus); CGameSettings* gameSettings = CCore::GetSingleton().GetGame()->GetSettings(); SString strVideoCard = SStringX(g_pDeviceState->AdapterState.Name).Left(30); - std::replace_if( - strVideoCard.begin(), strVideoCard.end(), [](int c) { return !isalnum(c); }, '_'); + std::replace_if(strVideoCard.begin(), strVideoCard.end(), [](int c) { return !isalnum(c); }, '_'); SString strSystemStats( "1_%d_%d_%d_%d_%d" "_%d%d%d%d" "_%s", - static_cast(GetWMITotalPhysicalMemory() / 1024LL / 1024LL), // - g_pDeviceState->AdapterState.InstalledMemoryKB / 1024, // - gameSettings->GetCurrentVideoMode(), // - gameSettings->GetFXQuality(), // - dxStatus.settings.iDrawDistance, // - - GetVideoModeManager()->IsWindowed(), // - GetVideoModeManager()->IsMultiMonitor(), // - dxStatus.settings.bVolumetricShadows, // - dxStatus.settings.bAllowScreenUpload, // - - *GetApplicationSetting("real-os-version") // + static_cast(GetWMITotalPhysicalMemory() / 1024LL / 1024LL), // + g_pDeviceState->AdapterState.InstalledMemoryKB / 1024, // + gameSettings->GetCurrentVideoMode(), // + gameSettings->GetFXQuality(), // + dxStatus.settings.iDrawDistance, // + + GetVideoModeManager()->IsWindowed(), // + GetVideoModeManager()->IsMultiMonitor(), // + dxStatus.settings.bVolumetricShadows, // + dxStatus.settings.bAllowScreenUpload, // + + *GetApplicationSetting("real-os-version") // ); SString strSystemStats2( "2_%d_%d_%d" "_%d_%d_%d" "_%d_%d_%d_%d_%d_%x", - g_pGraphics->GetViewportWidth(), // - g_pGraphics->GetViewportHeight(), // - dxStatus.settings.b32BitColor, // - - GetApplicationSettingInt(DIAG_PRELOAD_UPGRADES_LOWEST_UNSAFE), // - GetApplicationSettingInt(DIAG_MINIDUMP_DETECTED_COUNT), // - GetApplicationSettingInt(DIAG_MINIDUMP_CONFIRMED_COUNT), // - - atoi(dxStatus.videoCard.strPSVersion), // - dxStatus.videoCard.iNumSimultaneousRTs, // - dxStatus.settings.iAntiAliasing, // - dxStatus.settings.iAnisotropicFiltering, // - (int)dxStatus.settings.fFieldOfView, // - dxStatus.videoCard.depthBufferFormat // + g_pGraphics->GetViewportWidth(), // + g_pGraphics->GetViewportHeight(), // + dxStatus.settings.b32BitColor, // + + GetApplicationSettingInt(DIAG_PRELOAD_UPGRADES_LOWEST_UNSAFE), // + GetApplicationSettingInt(DIAG_MINIDUMP_DETECTED_COUNT), // + GetApplicationSettingInt(DIAG_MINIDUMP_CONFIRMED_COUNT), // + + atoi(dxStatus.videoCard.strPSVersion), // + dxStatus.videoCard.iNumSimultaneousRTs, // + dxStatus.settings.iAntiAliasing, // + dxStatus.settings.iAnisotropicFiltering, // + (int)dxStatus.settings.fFieldOfView, // + dxStatus.videoCard.depthBufferFormat // ); SString strSystemStats3( - "3_0" // Was VS2013 runtime installed + "3_0" // Was VS2013 runtime installed "_%s_%s_%d" - "_0" // Was VS2015 runtime version + "_0" // Was VS2015 runtime version "_%d_%d_%d_%d_%d_%s_%s", - *GetApplicationSetting("real-os-build"), // - *GetApplicationSetting("locale").Replace("_", "-"), // - (uint)FileSize(PathJoin(GetSystemSystemPath(), "normaliz.dll")), // - - bSecureBootEnabled, // - static_cast(memoryStatus.ullTotalVirtual / 1024), // - Is64BitOS(), // - iReqKB3033929, // - iReqKB3035131, // - *verInfoKernel32.GetFileVersionString(), // - *verInfoNcrypt.GetFileVersionString() // + *GetApplicationSetting("real-os-build"), // + *GetApplicationSetting("locale").Replace("_", "-"), // + (uint)FileSize(PathJoin(GetSystemSystemPath(), "normaliz.dll")), // + + bSecureBootEnabled, // + static_cast(memoryStatus.ullTotalVirtual / 1024), // + Is64BitOS(), // + iReqKB3033929, // + iReqKB3035131, // + *verInfoKernel32.GetFileVersionString(), // + *verInfoNcrypt.GetFileVersionString() // ); SString strConnectUsage = SString("%i_%i", GetApplicationSettingInt("times-connected-editor"), GetApplicationSettingInt("times-connected")); @@ -3386,14 +3886,16 @@ int CVersionUpdater::DoSendPostToNextServer() // Get our serial number char szSerial[64]; CCore::GetSingleton().GetNetwork()->GetSerial(szSerial, sizeof(szSerial)); + szSerial[sizeof(szSerial) - 1] = '\0'; // Defensive null-termination char szStatus[128]; CCore::GetSingleton().GetNetwork()->GetStatus(szStatus, sizeof(szStatus)); + szStatus[sizeof(szStatus) - 1] = '\0'; // Defensive null-termination // Compose version string unsigned short usNetRev = CCore::GetSingleton().GetNetwork()->GetNetRev(); unsigned short usNetRel = CCore::GetSingleton().GetNetwork()->GetNetRel(); SString strPlayerVersion("%d.%d.%d-%d.%05d.%d.%03d", MTASA_VERSION_MAJOR, MTASA_VERSION_MINOR, MTASA_VERSION_MAINTENANCE, MTASA_VERSION_TYPE, - MTASA_VERSION_BUILD, usNetRev, usNetRel); + MTASA_VERSION_BUILD, usNetRev, usNetRel); // Make the query URL SString strQueryURL = strServerURL; diff --git a/Client/core/CVertexStreamBoundingBoxManager.cpp b/Client/core/CVertexStreamBoundingBoxManager.cpp index a122a550df2..9c1625c38a3 100644 --- a/Client/core/CVertexStreamBoundingBoxManager.cpp +++ b/Client/core/CVertexStreamBoundingBoxManager.cpp @@ -11,6 +11,7 @@ #include "StdInc.h" #include "CVertexStreamBoundingBoxManager.h" +#include "DXHook/CProxyDirect3DDevice9.h" CVertexStreamBoundingBoxManager* CVertexStreamBoundingBoxManager::ms_Singleton = NULL; @@ -37,7 +38,7 @@ namespace return fDistSq; } -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -59,6 +60,8 @@ CVertexStreamBoundingBoxManager::CVertexStreamBoundingBoxManager() /////////////////////////////////////////////////////////////// CVertexStreamBoundingBoxManager::~CVertexStreamBoundingBoxManager() { + m_StreamBoundsInfoMap.clear(); + m_pDevice = NULL; } /////////////////////////////////////////////////////////////// @@ -75,6 +78,20 @@ CVertexStreamBoundingBoxManager* CVertexStreamBoundingBoxManager::GetSingleton() return ms_Singleton; } +CVertexStreamBoundingBoxManager* CVertexStreamBoundingBoxManager::GetExistingSingleton() +{ + return ms_Singleton; +} + +void CVertexStreamBoundingBoxManager::DestroySingleton() +{ + if (ms_Singleton) + { + delete ms_Singleton; + ms_Singleton = NULL; + } +} + /////////////////////////////////////////////////////////////// // // CVertexStreamBoundingBoxManager::OnDeviceCreate @@ -97,6 +114,9 @@ void CVertexStreamBoundingBoxManager::OnDeviceCreate(IDirect3DDevice9* pDevice) float CVertexStreamBoundingBoxManager::GetDistanceSqToGeometry(D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) { + if (!m_pDevice) + return 0.f; + // Cache info SCurrentStateInfo2 state; @@ -203,12 +223,31 @@ bool CVertexStreamBoundingBoxManager::ComputeVertexStreamBoundingBox(SCurrentSta const uint StridePT = state.stream.Stride; + if (StridePT == 0) + return false; + uint NumVerts = ReadSize / StridePT; + if (NumVerts == 0) + return false; + + if ((ReadSize % StridePT) != 0) + return false; + // Adjust for the offset in the stream + if (ReadSize < state.stream.elementOffset) + return false; + ReadOffsetStart += state.stream.elementOffset; ReadSize -= state.stream.elementOffset; - if (ReadSize < 1) + if (ReadSize == 0) + return false; + + const UINT bufferSize = state.decl.VertexBufferDesc.Size; + if (ReadOffsetStart > bufferSize) + return false; + + if (ReadSize > bufferSize - ReadOffsetStart) return false; // Get the source vertex bytes @@ -226,13 +265,21 @@ bool CVertexStreamBoundingBoxManager::ComputeVertexStreamBoundingBox(SCurrentSta // Compute bounds { // Get index data - if (FAILED(m_pDevice->GetIndices(&state.pIndexData))) + if (FAILED(m_pDevice->GetIndices(&state.pIndexData)) || !state.pIndexData) return false; // Get index buffer desc D3DINDEXBUFFER_DESC IndexBufferDesc; state.pIndexData->GetDesc(&IndexBufferDesc); + uint indexStride = 0; + if (IndexBufferDesc.Format == D3DFMT_INDEX16) + indexStride = sizeof(WORD); + else if (IndexBufferDesc.Format == D3DFMT_INDEX32) + indexStride = sizeof(DWORD); + else + return false; + uint numIndices = state.args.primCount + 2; uint step = 1; if (state.args.PrimitiveType == D3DPT_TRIANGLELIST) @@ -240,17 +287,35 @@ bool CVertexStreamBoundingBoxManager::ComputeVertexStreamBoundingBox(SCurrentSta numIndices = state.args.primCount * 3; step = 3; } - assert(IndexBufferDesc.Size >= (numIndices + state.args.startIndex) * 2); - // Get index buffer data - std::vector indexArray; - indexArray.resize(numIndices * 2); - uchar* pIndexArrayBytes = &indexArray[0]; + size_t startByte = static_cast(state.args.startIndex) * indexStride; + size_t requiredBytes = static_cast(numIndices) * indexStride; + if (startByte > IndexBufferDesc.Size) + return false; + + if (requiredBytes > IndexBufferDesc.Size - startByte) + return false; + + std::vector indices(numIndices); { void* pIndexBytes = NULL; - if (FAILED(state.pIndexData->Lock(state.args.startIndex * 2, numIndices * 2, &pIndexBytes, D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) + if (FAILED( + state.pIndexData->Lock(static_cast(startByte), static_cast(requiredBytes), &pIndexBytes, D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) return false; - memcpy(pIndexArrayBytes, pIndexBytes, numIndices * 2); + + if (indexStride == sizeof(WORD)) + { + const WORD* pSrc = static_cast(pIndexBytes); + for (uint i = 0; i < numIndices; ++i) + indices[i] = pSrc[i]; + } + else + { + const DWORD* pSrc = static_cast(pIndexBytes); + for (uint i = 0; i < numIndices; ++i) + indices[i] = pSrc[i]; + } + state.pIndexData->Unlock(); } @@ -263,15 +328,15 @@ bool CVertexStreamBoundingBoxManager::ComputeVertexStreamBoundingBox(SCurrentSta for (uint i = 0; i < numIndices - 2; i += step) { // Get triangle vertex indici - WORD v0 = ((WORD*)pIndexArrayBytes)[i]; - WORD v1 = ((WORD*)pIndexArrayBytes)[i + 1]; - WORD v2 = ((WORD*)pIndexArrayBytes)[i + 2]; + uint32_t v0 = indices[i]; + uint32_t v1 = indices[i + 1]; + uint32_t v2 = indices[i + 2]; if (v0 >= NumVerts || v1 >= NumVerts || v2 >= NumVerts) - continue; // vert index out of range + continue; // vert index out of range if (v0 == v1 || v0 == v2 || v1 == v2) - continue; // degenerate tri + continue; // degenerate tri // Get vertex positions from original stream CVector* pPos0 = (CVector*)(pSourceArrayBytes + v0 * StridePT); @@ -314,6 +379,9 @@ bool CVertexStreamBoundingBoxManager::ComputeVertexStreamBoundingBox(SCurrentSta ///////////////////////////////////////////////////////////// bool CVertexStreamBoundingBoxManager::CheckCanDoThis(SCurrentStateInfo2& state) { + if (!m_pDevice) + return false; + // Only tri-lists and tri-strips if (state.args.PrimitiveType != D3DPT_TRIANGLESTRIP && state.args.PrimitiveType != D3DPT_TRIANGLELIST) return false; diff --git a/Client/core/CVertexStreamBoundingBoxManager.h b/Client/core/CVertexStreamBoundingBoxManager.h index 7f94c476b3b..f2c8d2b0718 100644 --- a/Client/core/CVertexStreamBoundingBoxManager.h +++ b/Client/core/CVertexStreamBoundingBoxManager.h @@ -75,16 +75,18 @@ struct SCurrentStateInfo2 SCurrentStateInfo2(const SCurrentStateInfo2& other); SCurrentStateInfo2& operator=(const SCurrentStateInfo2& other); -public: - SCurrentStateInfo2() { ZERO_POD_STRUCT(this); } - - ~SCurrentStateInfo2() + void ReleaseComReferences() { SAFE_RELEASE(stream.pStreamData); SAFE_RELEASE(pIndexData); SAFE_RELEASE(decl.pVertexDeclaration); } +public: + SCurrentStateInfo2() { ZERO_POD_STRUCT(this); } + + ~SCurrentStateInfo2() { ReleaseComReferences(); } + // Info to DrawIndexPrimitive struct { @@ -132,6 +134,8 @@ class CVertexStreamBoundingBoxManager void OnVertexBufferRangeInvalidated(IDirect3DVertexBuffer9* pStreamData, uint Offset, uint Size); static CVertexStreamBoundingBoxManager* GetSingleton(); + static CVertexStreamBoundingBoxManager* GetExistingSingleton(); + static void DestroySingleton(); protected: float CalcDistanceSq(const SCurrentStateInfo2& state, const CBox& boundingBox); diff --git a/Client/core/Core.cpp b/Client/core/Core.cpp index 26d00a4a60c..ef4e4677689 100644 --- a/Client/core/Core.cpp +++ b/Client/core/Core.cpp @@ -91,7 +91,7 @@ CORE_API int InitializeCore() return 4; // Group our processes and windows under a single taskbar button - SetCurrentProcessExplicitAppUserModelID(L"Multi Theft Auto"); + SetCurrentProcessExplicitAppUserModelID(L"Multi Theft Auto " MTA_STR(MTASA_VERSION_MAJOR) L"." MTA_STR(MTASA_VERSION_MINOR)); WriteDebugEvent(SString("ModuleFileName: %s", *GetLaunchPathFilename())); diff --git a/Client/core/CrashHandler.cpp b/Client/core/CrashHandler.cpp index 2343e5246ad..674257fea7d 100644 --- a/Client/core/CrashHandler.cpp +++ b/Client/core/CrashHandler.cpp @@ -5,167 +5,3379 @@ * FILE: core/CrashHandler.cpp * PURPOSE: Crash handling functions * - * THIS FILE IS PROPERTY OF - * "Debugging Applications" (Microsoft Press) - * Copyright (c) 1997-2000 John Robbins -- All rights reserved. + * THIS FILE CREDITS (IS BASED ON): "Debugging Applications" (Microsoft Press) by John Robbins + * Copyright (c) 1997-2000 John Robbins -- All rights reserved * * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ -/*---------------------------------------------------------------------- -CONDITIONAL COMPILATION : - WORK_AROUND_SRCLINE_BUG - Define this symbol to work around the - SymGetLineFromAddr bug; this bug causes PDB - file lookups to fail after the first lookup. - This bug is fixed in DBGHELP.DLL, but I - still keep the workaround for users - who might need to use the old IMAGEHLP.DLL - versions. -----------------------------------------------------------------------*/ - +#define BUGSUTIL_EXPORTS #include "StdInc.h" #include "CrashHandler.h" +#include "StackTraceHelpers.h" +#include "CExceptionInformation_Impl.h" #include +#include +#include +#include "../Shared/sdk/CrashTelemetry.h" -/*////////////////////////////////////////////////////////////////////// - File Scope Global Variables -//////////////////////////////////////////////////////////////////////*/ -// The custom unhandled exception filter (crash handler) -static PFNCHFILTFN g_pfnCallBack = NULL; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -// The original unhandled exception filter -static LPTOP_LEVEL_EXCEPTION_FILTER g_pfnOrigFilt = NULL; +#if defined(_MSC_VER) + #pragma comment(lib, "Psapi.lib") +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(_MSC_VER) + #include +#endif -/*////////////////////////////////////////////////////////////////////// - File Scope Function Declarations -//////////////////////////////////////////////////////////////////////*/ -// The exception handler -LONG __stdcall CrashHandlerExceptionFilter(EXCEPTION_POINTERS* pExPtrs); +#if defined(_MSC_VER) + #include +#endif -/*////////////////////////////////////////////////////////////////////// - Destructor Class -//////////////////////////////////////////////////////////////////////*/ -// See the note in MEMDUMPVALIDATOR.CPP about automatic classes. -// Turn off warning : initializers put in library initialization area -#pragma warning (disable : 4073) -#pragma init_seg(lib) -class CleanUpCrashHandler +#include + +using WerRegisterAppLocalDumpFn = HRESULT(WINAPI*)(PCWSTR); +static std::atomic g_bWerLocalDumpConfigured{false}; +thread_local bool g_bCrashHandlerStackOverflow{false}; + +[[nodiscard]] constexpr bool IsMemoryException(DWORD code) { -public: - CleanUpCrashHandler() {} - ~CleanUpCrashHandler() + return code == EXCEPTION_ACCESS_VIOLATION || code == EXCEPTION_IN_PAGE_ERROR; +} + +[[nodiscard]] constexpr bool IsFloatingPointException(DWORD code) +{ + return code >= EXCEPTION_FLT_DENORMAL_OPERAND && code <= EXCEPTION_FLT_UNDERFLOW; +} + +[[nodiscard]] constexpr bool IsIntegerException(DWORD code) +{ + return code == EXCEPTION_INT_DIVIDE_BY_ZERO || code == EXCEPTION_INT_OVERFLOW; +} + +[[nodiscard]] bool IsExceptionFromThirdParty(void* exceptionAddress) +{ + if (!exceptionAddress) [[unlikely]] + return false; + + HMODULE hModule{nullptr}; + if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, static_cast(exceptionAddress), + &hModule) == 0) [[unlikely]] + return false; + + char modulePath[256]{}; + if (GetModuleFileNameA(hModule, modulePath, sizeof(modulePath)) == 0) [[unlikely]] + return false; + + // Libraries with a lot of bogus breakpoints + return strstr(modulePath, "libcef.dll") != nullptr || strstr(modulePath, "chrome_elf.dll") != nullptr; +} + +// Helpers to isolate __try usage and prevent crashes in debug output itself +void OutputDebugStringSafeImpl(const char* message) +{ + if (g_bCrashHandlerStackOverflow) + return; + if (message == nullptr) + return; + + __try + { + OutputDebugStringA(message); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + } +} + +void SafeDebugPrintImpl(char* buffer, std::size_t bufferSize, const char* format, va_list args) +{ + if (g_bCrashHandlerStackOverflow) + return; + if (buffer == nullptr || bufferSize == 0 || format == nullptr) + return; + + std::memset(buffer, 0, bufferSize); + + __try { - if (NULL != g_pfnOrigFilt) + const int written = _vsnprintf_s(buffer, bufferSize, _TRUNCATE, format, args); + if (written > 0) { - // Restore the original unhandled exception filter. - SetUnhandledExceptionFilter(g_pfnOrigFilt); + OutputDebugStringSafeImpl(buffer); } } -}; + __except (EXCEPTION_EXECUTE_HANDLER) + { + OutputDebugStringSafeImpl("CrashHandler: Exception during debug print formatting\n"); + } +} -// The static class -static CleanUpCrashHandler g_cBeforeAndAfter; +void SafeDebugPrintPrefixedImpl(const char* prefix, std::size_t prefixLen, const char* format, va_list args) +{ + if (g_bCrashHandlerStackOverflow) + return; + char buffer[DEBUG_BUFFER_SIZE] = {}; -/*////////////////////////////////////////////////////////////////////// - Crash Handler Function Implementation -//////////////////////////////////////////////////////////////////////*/ + std::size_t offset = 0; + if (prefix != nullptr && prefixLen > 0) + { + offset = std::min(prefixLen, DEBUG_BUFFER_SIZE - 1); + std::memcpy(buffer, prefix, offset); + } -BOOL __stdcall SetCrashHandlerFilter(PFNCHFILTFN pFn) -{ - // A NULL parameter unhooks the callback. - if (NULL == pFn) + if (offset >= DEBUG_BUFFER_SIZE - 1) + { + buffer[DEBUG_BUFFER_SIZE - 1] = '\0'; + OutputDebugStringSafeImpl(buffer); + return; + } + + __try { - if (NULL != g_pfnOrigFilt) + const int written = _vsnprintf_s(buffer + offset, DEBUG_BUFFER_SIZE - offset, _TRUNCATE, format, args); + if (written > 0 || offset > 0) { - // Restore the original unhandled exception filter. - SetUnhandledExceptionFilter(g_pfnOrigFilt); - g_pfnOrigFilt = NULL; - g_pfnCallBack = NULL; + OutputDebugStringSafeImpl(buffer); } } - else + __except (EXCEPTION_EXECUTE_HANDLER) + { + OutputDebugStringSafeImpl("CrashHandler: Exception during debug print prefixed formatting\n"); + } +} + +#ifndef STATUS_INVALID_PARAMETER +inline constexpr DWORD STATUS_INVALID_PARAMETER = 0xC000000DL; +#endif + +inline std::optional g_lastExceptionInfo; +inline std::mutex g_exceptionInfoMutex; + +inline std::atomic g_initializationPhase{INIT_PHASE_MINIMAL}; + +using CrashHandlerResult = std::variant; + +#if defined(__cplusplus) +[[noreturn]] void __cdecl CppNewHandler(); +#endif + +#if defined(_MSC_VER) +static int __cdecl CppNewHandlerBridge(size_t size); +#else +static void CppNewHandlerBridge(); +#endif + +[[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall IsFatalException(DWORD exceptionCode) +{ + switch (exceptionCode) + { + case EXCEPTION_SINGLE_STEP: + case EXCEPTION_GUARD_PAGE: + case EXCEPTION_INVALID_HANDLE: + case EXCEPTION_FLT_DENORMAL_OPERAND: + case EXCEPTION_FLT_INEXACT_RESULT: + case EXCEPTION_FLT_UNDERFLOW: + return FALSE; + } + + if (exceptionCode == EXCEPTION_BREAKPOINT) + { + SafeDebugOutput("IsFatalException: BREAKPOINT - NON-FATAL (debugger will handle if attached)\n"); + return FALSE; + } + + switch (exceptionCode) + { + case EXCEPTION_STACK_OVERFLOW: + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + case STATUS_STACK_BUFFER_OVERRUN_CODE: + case STATUS_HEAP_CORRUPTION_CODE: + case STATUS_INVALID_CRUNTIME_PARAMETER_CODE: + case STATUS_FATAL_USER_CALLBACK_EXCEPTION: + case CPP_EXCEPTION_CODE: + case CUSTOM_EXCEPTION_CODE_OOM: + case CUSTOM_EXCEPTION_CODE_WATCHDOG_TIMEOUT: + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + case EXCEPTION_INT_DIVIDE_BY_ZERO: + case EXCEPTION_INT_OVERFLOW: + case EXCEPTION_PRIV_INSTRUCTION: + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_INVALID_OPERATION: + case EXCEPTION_FLT_OVERFLOW: + case EXCEPTION_FLT_STACK_CHECK: + return TRUE; + } + + if (IsMemoryException(exceptionCode)) [[unlikely]] + { + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), + "IsFatalException: Access violation/page fault 0x%08X - treating as fatal for dump generation\n", exceptionCode); + return TRUE; + } + + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), "IsFatalException: Unknown exception code 0x%08X, treating as non-fatal\n", exceptionCode); + return FALSE; +} + +static void LogBasicExceptionInfo(_EXCEPTION_POINTERS* exception) +{ + if (exception == nullptr || exception->ExceptionRecord == nullptr) + return; + + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "Exception 0x%08X at 0x%p (TID: %lu)\n", exception->ExceptionRecord->ExceptionCode, + exception->ExceptionRecord->ExceptionAddress, GetCurrentThreadId()); +} + +static void StoreBasicExceptionInfo(_EXCEPTION_POINTERS* pException) +{ + if (pException == nullptr || pException->ExceptionRecord == nullptr) [[unlikely]] + return; + + try { - if (TRUE == IsBadCodePtr((FARPROC)pFn)) + std::unique_lock lock{g_exceptionInfoMutex, std::try_to_lock}; + if (!lock.owns_lock()) [[unlikely]] { - return (FALSE); + LogBasicExceptionInfo(pException); + return; } - g_pfnCallBack = pFn; - // If a custom crash handler isn't already in use, enable - // CrashHandlerExceptionFilter and save the original unhandled - // exception filter. - if (NULL == g_pfnOrigFilt) + ENHANCED_EXCEPTION_INFO info{.exceptionCode = pException->ExceptionRecord->ExceptionCode, + .exceptionAddress = pException->ExceptionRecord->ExceptionAddress, + .timestamp = std::chrono::system_clock::now(), + .threadId = GetCurrentThreadId(), + .processId = GetCurrentProcessId()}; + + const auto telemetryNote = CrashTelemetry::BuildAllocationTelemetryNote(); + if (!telemetryNote.empty()) { - g_pfnOrigFilt = SetUnhandledExceptionFilter(CrashHandlerExceptionFilter); + info.additionalInfo = telemetryNote; + } - // Stop the OS from turning off our handler - // Ref: https://www.codeproject.com/Articles/154686/SetUnhandledExceptionFilter-and-the-C-C-Runtime-Li - LPTOP_LEVEL_EXCEPTION_FILTER(WINAPI * RedirectedSetUnhandledExceptionFilter) - (LPTOP_LEVEL_EXCEPTION_FILTER) = [](LPTOP_LEVEL_EXCEPTION_FILTER /*ExceptionInfo*/) -> LPTOP_LEVEL_EXCEPTION_FILTER { - // When the CRT calls SetUnhandledExceptionFilter with NULL parameter - // our handler will not get removed. - return 0; - }; - static_assert(std::is_same_v, - "invalid type of RedirectedSetUnhandledExceptionFilter"); + g_lastExceptionInfo = info; + } + catch (...) + { + LogBasicExceptionInfo(pException); + } +} - DetourLibraryFunction("kernel32.dll", "SetUnhandledExceptionFilter", RedirectedSetUnhandledExceptionFilter); - } +[[nodiscard]] static std::string_view GetExceptionCodeDescription(DWORD exceptionCode) +{ + switch (exceptionCode) + { + case EXCEPTION_ACCESS_VIOLATION: + return "Access Violation - Invalid memory access"; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + return "Array Bounds Exceeded"; + case EXCEPTION_BREAKPOINT: + return "Breakpoint Hit"; + case EXCEPTION_DATATYPE_MISALIGNMENT: + return "Data Type Misalignment"; + case EXCEPTION_FLT_DENORMAL_OPERAND: + return "Floating Point - Denormal Operand"; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + return "Floating Point - Divide by Zero"; + case EXCEPTION_FLT_INEXACT_RESULT: + return "Floating Point - Inexact Result"; + case EXCEPTION_FLT_INVALID_OPERATION: + return "Floating Point - Invalid Operation"; + case EXCEPTION_FLT_OVERFLOW: + return "Floating Point - Overflow"; + case EXCEPTION_FLT_STACK_CHECK: + return "Floating Point - Stack Check"; + case EXCEPTION_FLT_UNDERFLOW: + return "Floating Point - Underflow"; + case EXCEPTION_ILLEGAL_INSTRUCTION: + return "Illegal Instruction"; + case EXCEPTION_IN_PAGE_ERROR: + return "In Page Error - Page fault"; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + return "Integer Divide by Zero"; + case EXCEPTION_INT_OVERFLOW: + return "Integer Overflow"; + case EXCEPTION_INVALID_DISPOSITION: + return "Invalid Disposition"; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + return "Non-Continuable Exception"; + case EXCEPTION_PRIV_INSTRUCTION: + return "Privileged Instruction"; + case EXCEPTION_SINGLE_STEP: + return "Single Step (Debugging)"; + case EXCEPTION_STACK_OVERFLOW: + return "Stack Overflow"; + case EXCEPTION_GUARD_PAGE: + return "Guard Page Violation"; + case EXCEPTION_INVALID_HANDLE: + return "Invalid Handle"; + case CPP_EXCEPTION_CODE: + return "C++ Exception"; + case STATUS_STACK_BUFFER_OVERRUN_CODE: + return "Stack Buffer Overrun (Security Check)"; + case STATUS_INVALID_CRUNTIME_PARAMETER_CODE: + return "Invalid C Runtime Parameter"; + case STATUS_FATAL_USER_CALLBACK_EXCEPTION: + return "Fatal Exception in Windows Callback"; + case CUSTOM_EXCEPTION_CODE_OOM: + return "Out of Memory - Allocation Failure"; + case CUSTOM_EXCEPTION_CODE_WATCHDOG_TIMEOUT: + return "Watchdog Timeout - Application Freeze Detected"; + case STATUS_HEAP_CORRUPTION_CODE: + return "Heap Corruption Detected"; + case 0xC0000420: + return "Assertion Failure"; + case 0x40000015: + return "Fatal App Exit"; + case 0xC00002C9: + return "Register NaT Consumption"; + case 0xC0000194: + return "Possible Deadlock Condition"; + case 0x80000029: + return "Unwind Consolidate (Frame consolidation)"; + default: + return "Unknown Exception"; } - return (TRUE); } -LONG __stdcall CrashHandlerExceptionFilter(EXCEPTION_POINTERS* pExPtrs) +static void LogEnhancedExceptionInfo(_EXCEPTION_POINTERS* pException) { - LONG lRet = EXCEPTION_CONTINUE_SEARCH; - - // If the exception is an EXCEPTION_STACK_OVERFLOW, there isn't much - // you can do because the stack is blown. If you try to do anything, - // the odds are great that you'll just double-fault and bomb right - // out of your exception filter. Although I don't recommend doing so, - // you could play some games with the stack register and - // manipulate it so that you could regain enough space to run these - // functions. Of course, if you did change the stack register, you'd - // have problems walking the stack. - // I take the safe route and make some calls to OutputDebugString here. - // I still might double-fault, but because OutputDebugString does very - // little on the stack (something like 8-16 bytes), it's worth a - // shot. You can have your users download Mark Russinovich's - // DebugView/Enterprise Edition (www.sysinternals.com) so they can - // at least tell you what they see. - // The only problem is that I can't even be sure there's enough - // room on the stack to convert the instruction pointer. - // Fortunately, EXCEPTION_STACK_OVERFLOW doesn't happen very often. - - // Note that I still call your crash handler. I'm doing the logging - // work here in case the blown stack kills your crash handler. - if (EXCEPTION_STACK_OVERFLOW == pExPtrs->ExceptionRecord->ExceptionCode) - { - OutputDebugString("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); - OutputDebugString("EXCEPTION_STACK_OVERFLOW occurred\n"); - OutputDebugString("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + if (pException == nullptr || pException->ExceptionRecord == nullptr) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogEnhancedExceptionInfo - NULL exception pointers\n"); + return; } - __try + if (pException->ContextRecord == nullptr) { - if (NULL != g_pfnCallBack) + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogEnhancedExceptionInfo - NULL context record\n"); + LogBasicExceptionInfo(pException); + return; + } + + try + { + std::unique_lock lock{g_exceptionInfoMutex, std::try_to_lock}; + if (!lock.owns_lock()) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogEnhancedExceptionInfo - Failed to acquire lock, skipping global state update\n"); + return; + } + + ENHANCED_EXCEPTION_INFO info{}; + + info.exceptionCode = pException->ExceptionRecord->ExceptionCode; + info.exceptionAddress = pException->ExceptionRecord->ExceptionAddress; + info.timestamp = std::chrono::system_clock::now(); + info.threadId = GetCurrentThreadId(); + info.processId = GetCurrentProcessId(); + + info.eax = pException->ContextRecord->Eax; + info.ebx = pException->ContextRecord->Ebx; + info.ecx = pException->ContextRecord->Ecx; + info.edx = pException->ContextRecord->Edx; + info.esi = pException->ContextRecord->Esi; + info.edi = pException->ContextRecord->Edi; + info.ebp = pException->ContextRecord->Ebp; + info.esp = pException->ContextRecord->Esp; + info.eip = pException->ContextRecord->Eip; + info.cs = pException->ContextRecord->SegCs; + info.ds = pException->ContextRecord->SegDs; + info.es = pException->ContextRecord->SegEs; + info.fs = pException->ContextRecord->SegFs; + info.gs = pException->ContextRecord->SegGs; + info.ss = pException->ContextRecord->SegSs; + info.eflags = pException->ContextRecord->EFlags; + + CExceptionInformation_Impl moduleHelper; + std::array moduleBuffer{}; + void* moduleBase{nullptr}; + + // For EIP=0 crashes, resolve module from return address at [ESP] instead of EIP + void* addressToResolve{info.exceptionAddress}; + constexpr auto kNullAddress{uintptr_t{0}}; + + const auto exceptionAddressValue{reinterpret_cast(info.exceptionAddress)}; + + if (exceptionAddressValue == kNullAddress && info.eip == kNullAddress) + { + const auto espAddr{static_cast(info.esp)}; + const auto pReturnAddress{reinterpret_cast(espAddr)}; + + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogEnhancedExceptionInfo - EIP=0 detected (ESP=0x%08X), reading return address...\n", + static_cast(espAddr)); + + if (SharedUtil::IsReadablePointer(pReturnAddress, sizeof(void*))) + { + addressToResolve = *pReturnAddress; + + const auto returnAddressValue{reinterpret_cast(addressToResolve)}; + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogEnhancedExceptionInfo - Return address: 0x%08X (resolving module from this)\n", + static_cast(returnAddressValue)); + } + else + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogEnhancedExceptionInfo - ESP not readable (0x%08X), cannot read return address\n", + static_cast(espAddr)); + } + } + + if (moduleHelper.GetModule(addressToResolve, moduleBuffer.data(), static_cast(moduleBuffer.size()), &moduleBase)) + { + info.modulePathName = std::string{moduleBuffer.data()}; + + const std::string_view moduleView{moduleBuffer.data()}; + if (const auto pos = moduleView.rfind('\\'); pos != std::string_view::npos) + { + info.moduleName = std::string{moduleView.substr(pos + 1)}; + info.moduleBaseName = info.moduleName; + } + else + { + info.moduleName = std::string{moduleView}; + info.moduleBaseName = info.moduleName; + } + + if (moduleBase != nullptr) + { + // Use addressToResolve for offset calculation (handles EIP=0 return address case) + const uintptr_t resolvedAddr{reinterpret_cast(addressToResolve)}; + const uintptr_t baseAddr{reinterpret_cast(moduleBase)}; + + if (resolvedAddr >= baseAddr) + { + const uintptr_t offset{resolvedAddr - baseAddr}; + + if (offset <= UINT_MAX) + { + info.moduleOffset = static_cast(offset); + } + else + { + info.moduleOffset = 0; + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogEnhancedExceptionInfo - Module offset exceeds UINT_MAX\n"); + } + } + else + { + info.moduleOffset = 0; + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogEnhancedExceptionInfo - Exception address before module base\n"); + } + } + else + { + info.moduleOffset = 0; + } + } + else + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogEnhancedExceptionInfo - Failed to get module info\n"); + info.moduleName = "Unknown"; + info.moduleBaseName = "Unknown"; + info.modulePathName = "Unknown"; + info.moduleOffset = 0; + } + + std::vector stackTraceVec; + // For callback exceptions (0xC000041D), stack walking may fail due to corrupted frames + // Wrap in additional protection and accept partial traces + bool isCallbackException = (info.exceptionCode == 0xC000041D); + if (CaptureUnifiedStackTrace(pException, isCallbackException ? 16 : 32, &stackTraceVec)) + { + info.stackTrace = stackTraceVec; + info.hasDetailedStackTrace = !stackTraceVec.empty(); + if (isCallbackException && stackTraceVec.empty()) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogEnhancedExceptionInfo - Callback exception: stack trace empty (expected)\n"); + } + } + else + { + info.hasDetailedStackTrace = false; + if (isCallbackException) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogEnhancedExceptionInfo - Callback exception: stack capture failed (expected)\n"); + } + } + + info.uncaughtExceptionCount = std::uncaught_exceptions(); + if (info.uncaughtExceptionCount > 0) { - // Check that the crash handler still exists in memory - // before I call it. The user might have forgotten to - // unregister, and the crash handler is invalid because - // it got unloaded. If some other function loaded - // back into the same address, however, there isn't much - // I can do. - if (FALSE == IsBadCodePtr((FARPROC)g_pfnCallBack)) + try { - lRet = g_pfnCallBack(pExPtrs); + info.capturedException = std::current_exception(); } + catch (...) + { + info.capturedException = std::nullopt; + } + } + else + { + info.capturedException = std::nullopt; + } + + info.isFatal = IsFatalException(info.exceptionCode) != FALSE; + + switch (info.exceptionCode) + { + case EXCEPTION_ACCESS_VIOLATION: + info.exceptionType = "SEH:AccessViolation"; + break; + case EXCEPTION_STACK_OVERFLOW: + info.exceptionType = "SEH:StackOverflow"; + break; + case CPP_EXCEPTION_CODE: + info.exceptionType = "C++"; + break; + case STATUS_STACK_BUFFER_OVERRUN_CODE: + info.exceptionType = "SEH:BufferOverrun"; + break; + case STATUS_HEAP_CORRUPTION_CODE: + info.exceptionType = "SEH:HeapCorruption"; + break; + case STATUS_INVALID_CRUNTIME_PARAMETER_CODE: + info.exceptionType = "SEH:InvalidCRTParameter"; + break; + case EXCEPTION_BREAKPOINT: + info.exceptionType = "SEH:Breakpoint"; + break; + case EXCEPTION_SINGLE_STEP: + info.exceptionType = "SEH:SingleStep"; + break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + info.exceptionType = "SEH:ArrayBounds"; + break; + case EXCEPTION_FLT_DENORMAL_OPERAND: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_INEXACT_RESULT: + case EXCEPTION_FLT_INVALID_OPERATION: + case EXCEPTION_FLT_OVERFLOW: + case EXCEPTION_FLT_STACK_CHECK: + case EXCEPTION_FLT_UNDERFLOW: + info.exceptionType = "SEH:FloatingPoint"; + break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + case EXCEPTION_INT_OVERFLOW: + info.exceptionType = "SEH:IntegerMath"; + break; + case EXCEPTION_PRIV_INSTRUCTION: + info.exceptionType = "SEH:PrivilegedInstruction"; + break; + case EXCEPTION_ILLEGAL_INSTRUCTION: + info.exceptionType = "SEH:IllegalInstruction"; + break; + case EXCEPTION_DATATYPE_MISALIGNMENT: + info.exceptionType = "SEH:DataMisalignment"; + break; + case EXCEPTION_IN_PAGE_ERROR: + info.exceptionType = "SEH:PageError"; + break; + case EXCEPTION_GUARD_PAGE: + info.exceptionType = "SEH:GuardPage"; + break; + case CUSTOM_EXCEPTION_CODE_OOM: + info.exceptionType = "User:OutOfMemory"; + break; + case CUSTOM_EXCEPTION_CODE_WATCHDOG_TIMEOUT: + info.exceptionType = "User:WatchdogTimeout"; + break; + default: + if (info.exceptionCode >= 0xC0000000 && info.exceptionCode <= 0xCFFFFFFF) + { + info.exceptionType = "SEH:Unknown"; + } + else if (info.exceptionCode >= 0xE0000000) + { + info.exceptionType = "User"; + } + else + { + info.exceptionType = "Unknown"; + } + break; } + + info.exceptionDescription = GetExceptionCodeDescription(info.exceptionCode); + + if (auto telemetryNote = CrashTelemetry::BuildAllocationTelemetryNote(); !telemetryNote.empty()) + { + if (!info.additionalInfo.empty()) + { + info.additionalInfo.push_back('\n'); + } + info.additionalInfo += telemetryNote; + } + + g_lastExceptionInfo = info; } - __except (EXCEPTION_EXECUTE_HANDLER) + catch (...) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogEnhancedExceptionInfo - Exception during processing, using basic logging\n"); + LogBasicExceptionInfo(pException); + } +} + +static void CaptureAllocationTelemetry(_EXCEPTION_POINTERS* pException) +{ + if (pException == nullptr || pException->ExceptionRecord == nullptr) + return; + + StoreBasicExceptionInfo(pException); + LogEnhancedExceptionInfo(pException); +} + +static std::variant HandleExceptionModern(_EXCEPTION_POINTERS* pException) +{ + if (pException == nullptr || pException->ExceptionRecord == nullptr) + { + return std::string("Invalid exception pointers"); + } + + const EXCEPTION_RECORD* pRecord = pException->ExceptionRecord; + const DWORD exceptionCode = pRecord->ExceptionCode; + + LogEnhancedExceptionInfo(pException); + + CExceptionInformation_Impl exceptionInfo; + exceptionInfo.Set(exceptionCode, pException); + + std::string_view exceptionType = "Unknown"; + + switch (exceptionCode) + { + case EXCEPTION_ACCESS_VIOLATION: + exceptionType = "Access Violation"; + break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + exceptionType = "Array Bounds Exceeded"; + break; + case EXCEPTION_DATATYPE_MISALIGNMENT: + exceptionType = "Data Type Misalignment"; + break; + case EXCEPTION_FLT_DENORMAL_OPERAND: + exceptionType = "Floating Point Denormal Operand"; + break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + exceptionType = "Floating Point Divide by Zero"; + break; + case EXCEPTION_FLT_INEXACT_RESULT: + exceptionType = "Floating Point Inexact Result"; + break; + case EXCEPTION_FLT_INVALID_OPERATION: + exceptionType = "Floating Point Invalid Operation"; + break; + case EXCEPTION_FLT_OVERFLOW: + exceptionType = "Floating Point Overflow"; + break; + case EXCEPTION_FLT_STACK_CHECK: + exceptionType = "Floating Point Stack Check"; + break; + case EXCEPTION_FLT_UNDERFLOW: + exceptionType = "Floating Point Underflow"; + break; + case EXCEPTION_ILLEGAL_INSTRUCTION: + exceptionType = "Illegal Instruction"; + break; + case EXCEPTION_IN_PAGE_ERROR: + exceptionType = "In Page Error"; + break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + exceptionType = "Integer Divide by Zero"; + break; + case EXCEPTION_INT_OVERFLOW: + exceptionType = "Integer Overflow"; + break; + case EXCEPTION_INVALID_DISPOSITION: + exceptionType = "Invalid Disposition"; + break; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + exceptionType = "Noncontinuable Exception"; + break; + case EXCEPTION_PRIV_INSTRUCTION: + exceptionType = "Privileged Instruction"; + break; + case EXCEPTION_SINGLE_STEP: + exceptionType = "Single Step"; + break; + case EXCEPTION_STACK_OVERFLOW: + exceptionType = "Stack Overflow"; + break; + case CPP_EXCEPTION_CODE: + exceptionType = "C++ Exception"; + break; + case STATUS_INVALID_CRUNTIME_PARAMETER_CODE: + exceptionType = "Invalid CRT Parameter"; + break; + case STATUS_STACK_BUFFER_OVERRUN_CODE: + exceptionType = "Stack Buffer Overrun"; + break; + case STATUS_HEAP_CORRUPTION_CODE: + exceptionType = "Heap Corruption"; + break; + case STATUS_FATAL_USER_CALLBACK_EXCEPTION: + exceptionType = "Fatal User Callback Exception"; + break; + } + + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "%.*s (0x%08X) at 0x%p\n", static_cast(exceptionType.size()), exceptionType.data(), exceptionCode, + pRecord->ExceptionAddress); + + return exceptionCode; +} + +static std::mutex g_handlerStateMutex; +static std::atomic g_pfnCrashCallback{nullptr}; +static std::atomic g_pfnOrigFilt{nullptr}; +static std::atomic g_pfnOrigTerminate{nullptr}; +#if defined(_MSC_VER) +using CrtNewHandler = int(__cdecl*)(size_t); +static std::atomic g_pfnOrigNewHandler{nullptr}; +#else +static std::atomic g_pfnOrigNewHandler{nullptr}; +#endif +static std::atomic g_pfnKernelSetUnhandledExceptionFilter{nullptr}; +static decltype(&SetUnhandledExceptionFilter) g_kernelSetUnhandledExceptionFilterTrampoline = nullptr; + +static std::atomic g_bStackCookieCaptureEnabled{false}; +static std::atomic g_pfnOrigAbortHandler{nullptr}; +static std::atomic<_purecall_handler> g_pfnOrigPureCall{nullptr}; +static std::atomic g_bInAbortHandler{false}; +static std::atomic g_bInPureCallHandler{false}; +static std::atomic g_bInTerminateHandler{false}; +static std::atomic g_bInNewHandler{false}; + +static std::atomic g_symbolsInitialized{false}; +static std::atomic g_symbolProcess{nullptr}; +static std::mutex g_symbolMutex; + +using EnumProcessModulesExFn = BOOL(WINAPI*)(HANDLE, HMODULE*, DWORD, LPDWORD, DWORD); + +[[nodiscard]] static bool CollectProcessModules(HANDLE process, std::vector& modules) +{ + const HMODULE psapiModule = GetModuleHandleW(L"Psapi.dll"); + EnumProcessModulesExFn enumModulesEx = nullptr; + if (psapiModule != nullptr) + { + const auto procAddr = GetProcAddress(psapiModule, "EnumProcessModulesEx"); + if (procAddr) + { + static_assert(sizeof(enumModulesEx) == sizeof(procAddr), "Unexpected function pointer size"); + std::memcpy(&enumModulesEx, &procAddr, sizeof(enumModulesEx)); + } + } + + auto enumModules = [&](HMODULE* buffer, DWORD bufferSize, DWORD* bytesNeeded) -> BOOL + { + if (enumModulesEx) + return enumModulesEx(process, buffer, bufferSize, bytesNeeded, LIST_MODULES_ALL); + return EnumProcessModules(process, buffer, bufferSize, bytesNeeded); + }; + + DWORD bytesNeeded = 0; + if (enumModules(nullptr, 0, &bytesNeeded) == FALSE || bytesNeeded == 0) + return false; + + const auto moduleCapacity = bytesNeeded / static_cast(sizeof(HMODULE)); + modules.resize(moduleCapacity); + if (enumModules(modules.data(), bytesNeeded, &bytesNeeded) == FALSE || bytesNeeded == 0) + return false; + + modules.resize(bytesNeeded / static_cast(sizeof(HMODULE))); + return !modules.empty(); +} + +[[nodiscard]] static bool RegisterProcessModulesWithDbgHelp(HANDLE process) +{ + std::vector modules; + if (!CollectProcessModules(process, modules)) + { + SafeDebugOutput("CrashHandler: InitializeSymbolHandler - EnumProcessModules failed to enumerate modules\n"); + return false; + } + + DWORD modulesRegistered = 0; + DWORD failuresLogged = 0; + + for (HMODULE moduleHandle : modules) + { + const DWORD64 moduleBase = static_cast(reinterpret_cast(moduleHandle)); + if (SymGetModuleBase64(process, moduleBase) != 0) + continue; + + MODULEINFO moduleInfo{}; + if (GetModuleInformation(process, moduleHandle, &moduleInfo, sizeof(moduleInfo)) == FALSE) + continue; + + std::array modulePath{}; + if (GetModuleFileNameExA(process, moduleHandle, modulePath.data(), static_cast(modulePath.size())) == 0) + continue; + + const DWORD64 baseAddress = moduleBase; + const DWORD imageSize = moduleInfo.SizeOfImage; + + SetLastError(ERROR_SUCCESS); + if (SymLoadModuleEx(process, nullptr, modulePath.data(), nullptr, baseAddress, imageSize, nullptr, 0) != 0) + { + ++modulesRegistered; + } + else if (failuresLogged < 5) + { + const auto error = GetLastError(); + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), + "CrashHandler: InitializeSymbolHandler - SymLoadModuleEx failed via EnumProcessModules for %s (error 0x%08X)\n", + modulePath.data(), error); + ++failuresLogged; + } + } + + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), + "CrashHandler: InitializeSymbolHandler - Registered %lu modules via EnumProcessModules (failures=%lu)\n", modulesRegistered, + failuresLogged); + + return modulesRegistered != 0; +} + +[[nodiscard]] static bool RegisterModuleForAddress(HANDLE process, DWORD64 address) +{ + const auto addressPtr = reinterpret_cast(static_cast(address)); + + HMODULE moduleHandle{nullptr}; + if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, addressPtr, &moduleHandle) == 0) + { + const auto error = GetLastError(); + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), "CaptureUnifiedStackTrace - Unable to resolve module for address 0x%llX (error 0x%08X)\n", + address, error); + return false; + } + + const DWORD64 moduleBase = static_cast(reinterpret_cast(moduleHandle)); + if (SymGetModuleBase64(process, moduleBase) != 0) + return true; + + MODULEINFO moduleInfo{}; + if (GetModuleInformation(process, moduleHandle, &moduleInfo, sizeof(moduleInfo)) == FALSE) + { + const auto error = GetLastError(); + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), "CaptureUnifiedStackTrace - GetModuleInformation failed for address 0x%llX (error 0x%08X)\n", + address, error); + return false; + } + + std::array modulePath{}; + if (GetModuleFileNameExA(process, moduleHandle, modulePath.data(), static_cast(modulePath.size())) == 0) + { + const auto error = GetLastError(); + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), "CaptureUnifiedStackTrace - GetModuleFileNameEx failed for address 0x%llX (error 0x%08X)\n", + address, error); + return false; + } + + const DWORD imageSize = moduleInfo.SizeOfImage; + + SetLastError(ERROR_SUCCESS); + if (SymLoadModuleEx(process, nullptr, modulePath.data(), nullptr, moduleBase, imageSize, nullptr, 0) == 0) + { + const auto error = GetLastError(); + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), "CaptureUnifiedStackTrace - SymLoadModuleEx failed for %s (address 0x%llX, error 0x%08X)\n", + modulePath.data(), address, error); + return false; + } + + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), "CaptureUnifiedStackTrace - Registered module %s (base=0x%llX) for address 0x%llX\n", + modulePath.data(), moduleBase, address); + + return true; +} + +#if defined(_MSC_VER) +static int __cdecl CppNewHandlerBridge(size_t size) +{ + const auto telemetry = CrashTelemetry::CaptureContext(); + if ((!telemetry.hasData || telemetry.requestedSize == 0) && size > 0) + { + CrashTelemetry::SetAllocationContext(size, nullptr, "operator new", "std::new_handler"); + } + + if (auto previous = g_pfnOrigNewHandler.load(std::memory_order_acquire)) + { + return previous(size); + } + + CppNewHandler(); + return 0; +} +#else +static void CppNewHandlerBridge() +{ + const auto telemetry = CrashTelemetry::CaptureContext(); + if (!telemetry.hasData) + { + CrashTelemetry::SetAllocationContext(0, nullptr, "operator new", "std::new_handler"); + } + + if (auto previous = g_pfnOrigNewHandler.load(std::memory_order_acquire)) + { + previous(); + return; + } + + CppNewHandler(); +} +#endif + +LONG __stdcall CrashHandlerExceptionFilter(EXCEPTION_POINTERS* pExPtrs); + +[[noreturn]] void __cdecl CppTerminateHandler(); +void __cdecl AbortSignalHandler(int signal); +[[noreturn]] void __cdecl PureCallHandler(); + +static void InstallCppHandlers(); +static bool InstallSehHandler(); +static void InstallAbortHandlers(); +static bool ConfigureWerLocalDumps(); +static void UninstallCrashHandlers(); +static void ReportCurrentCppException(); + +[[nodiscard]] static bool BuildExceptionContext(EXCEPTION_POINTERS& outExPtrs, EXCEPTION_RECORD*& outExRecord, CONTEXT*& outCtx, DWORD dwExceptionCode); + +inline void InitializeExceptionRecord(EXCEPTION_RECORD* const pRecord, const DWORD code, const void* const address); + +static void LogHandlerEvent(const char* prefix, const char* event); + +// Single overload using string_view handles all string types efficiently +static void SignalSafeOutput(std::string_view message) +{ + SafeDebugOutput(message); +} + +static void SignalSafePrintPrefixed(std::string_view prefix, std::string_view message) +{ + if (!prefix.empty()) + { + SignalSafeOutput(prefix); + } + + if (!message.empty()) + { + SignalSafeOutput(message); + } +} + +static void LogHandlerEvent(const char* prefix, const char* event) +{ + if (prefix != nullptr && event != nullptr) + { + SafeDebugPrintPrefixed(prefix, "%s\n", event); + } +} + +[[noreturn]] static void TerminateSelfWithExitCode(DWORD exitCode) +{ + if (exitCode == 0) + { + exitCode = EXIT_CODE_CRASH; + } + + TerminateProcess(GetCurrentProcess(), exitCode); + _exit(static_cast(exitCode)); +} + +inline void InitializeExceptionRecord(EXCEPTION_RECORD* const pRecord, const DWORD code, const void* const address) +{ + if (pRecord == nullptr) + { + return; + } + + pRecord->ExceptionCode = code; + pRecord->ExceptionFlags = EXCEPTION_NONCONTINUABLE; + pRecord->ExceptionRecord = nullptr; + pRecord->ExceptionAddress = const_cast(address); + pRecord->NumberParameters = 0; + + for (auto& param : pRecord->ExceptionInformation) + param = 0; +} + +static LPTOP_LEVEL_EXCEPTION_FILTER WINAPI RedirectedSetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) +{ + std::array szLog{std::array{}}; + SAFE_DEBUG_PRINT(szLog, "%.*sIntercepted SetUnhandledExceptionFilter call with arg 0x%p\n", static_cast(DEBUG_PREFIX_CRASH.size()), + DEBUG_PREFIX_CRASH.data(), static_cast(lpTopLevelExceptionFilter)); + + if (lpTopLevelExceptionFilter == nullptr) + { + SafeDebugOutput("CrashHandler: Blocked attempt to remove exception filter\n"); + return CrashHandlerExceptionFilter; + } + + SafeDebugOutput("CrashHandler: Allowing non-nullptr exception filter change\n"); + auto kernelSet = g_pfnKernelSetUnhandledExceptionFilter.load(std::memory_order_acquire); + if (kernelSet == nullptr) + { + SafeDebugOutput("CrashHandler: WARNING - Original SetUnhandledExceptionFilter pointer missing\n"); + return lpTopLevelExceptionFilter; + } + + return kernelSet(lpTopLevelExceptionFilter); +} + +void __cdecl AbortSignalHandler([[maybe_unused]] int signal) +{ + bool expected{false}; + if (!g_bInAbortHandler.compare_exchange_strong(expected, true, std::memory_order_acq_rel)) + { + SignalSafePrintPrefixed(DEBUG_PREFIX_ABORT, "Recursive\n"); + TerminateSelfWithExitCode(STATUS_STACK_BUFFER_OVERRUN_CODE); + } + + SignalSafeOutput(DEBUG_SEPARATOR); + SignalSafePrintPrefixed(DEBUG_PREFIX_ABORT, "SIGABRT (STATUS_STACK_BUFFER_OVERRUN)\n"); + SignalSafeOutput(DEBUG_SEPARATOR); + + alignas(16) EXCEPTION_RECORD exRecord{}; + alignas(16) CONTEXT ctx{}; + + void* returnAddr{_ReturnAddress()}; + + InitializeExceptionRecord(&exRecord, STATUS_STACK_BUFFER_OVERRUN_CODE, returnAddr); + + ctx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; + RtlCaptureContext(&ctx); + + EXCEPTION_POINTERS exPtrs{}; + exPtrs.ExceptionRecord = &exRecord; + exPtrs.ContextRecord = &ctx; + + CaptureAllocationTelemetry(&exPtrs); + + PFNCHFILTFN callback = g_pfnCrashCallback.load(std::memory_order_acquire); + + if (callback != nullptr) + { + SignalSafePrintPrefixed(DEBUG_PREFIX_ABORT, "Calling handler\n"); + + try + { + callback(&exPtrs); + } + catch (...) + { + SignalSafePrintPrefixed(DEBUG_PREFIX_ABORT, "Handler exception\n"); + } + } + else + { + SignalSafePrintPrefixed(DEBUG_PREFIX_ABORT, "No handler\n"); + } + + SignalSafePrintPrefixed(DEBUG_PREFIX_ABORT, "Terminating\n"); + + TerminateSelfWithExitCode(STATUS_STACK_BUFFER_OVERRUN_CODE); +} + +[[noreturn]] void __cdecl PureCallHandler() +{ + bool expected{false}; + if (!g_bInPureCallHandler.compare_exchange_strong(expected, true, std::memory_order_acq_rel)) + { + SignalSafePrintPrefixed(DEBUG_PREFIX_PURECALL, "Recursive\n"); + TerminateSelfWithExitCode(EXCEPTION_NONCONTINUABLE_EXCEPTION); + } + + SafeDebugOutput(DEBUG_SEPARATOR); + LogHandlerEvent(DEBUG_PREFIX_PURECALL.data(), "Pure virtual function call detected"); + SafeDebugOutput(DEBUG_SEPARATOR); + + EXCEPTION_RECORD* pExRecord{nullptr}; + CONTEXT* pCtx{nullptr}; + EXCEPTION_POINTERS exPtrs{}; + + const bool haveContext = BuildExceptionContext(exPtrs, pExRecord, pCtx, EXCEPTION_NONCONTINUABLE_EXCEPTION); + if (haveContext) + { + CaptureAllocationTelemetry(&exPtrs); + } + + PFNCHFILTFN callback = g_pfnCrashCallback.load(std::memory_order_acquire); + + if (callback != nullptr && haveContext) + { + LogHandlerEvent(DEBUG_PREFIX_PURECALL.data(), "Calling crash handler callback"); + + try + { + callback(&exPtrs); + } + catch (...) + { + LogHandlerEvent(DEBUG_PREFIX_PURECALL.data(), "Exception in crash handler callback"); + } + } + + if (pCtx != nullptr) + { + LocalFree(pCtx); + } + + if (pExRecord != nullptr) + { + LocalFree(pExRecord); + } + + LogHandlerEvent(DEBUG_PREFIX_PURECALL.data(), "Terminating process"); + TerminateSelfWithExitCode(EXCEPTION_NONCONTINUABLE_EXCEPTION); +} + +#pragma warning(disable : 4073) +#pragma init_seg(lib) +class CleanUpCrashHandler +{ +public: + CleanUpCrashHandler() = default; + ~CleanUpCrashHandler() + { + std::scoped_lock lock{g_handlerStateMutex}; + + g_bStackCookieCaptureEnabled.store(false, std::memory_order_release); + g_pfnCrashCallback.store(nullptr, std::memory_order_release); + + if (g_symbolsInitialized.exchange(false, std::memory_order_acq_rel)) + { + if (HANDLE hProcess = g_symbolProcess.exchange(nullptr, std::memory_order_acq_rel); hProcess != nullptr) + { + SymCleanup(hProcess); + SafeDebugOutput("CrashHandler: Symbol handler cleaned up\n"); + } + } + + if (auto terminateHandler = g_pfnOrigTerminate.exchange(nullptr, std::memory_order_acq_rel); terminateHandler != nullptr) + { + std::set_terminate(terminateHandler); + } + + if (auto newHandler = g_pfnOrigNewHandler.exchange(nullptr, std::memory_order_acq_rel); newHandler != nullptr) + { +#if defined(_MSC_VER) + _set_new_handler(newHandler); +#else + std::set_new_handler(newHandler); +#endif + } + + if (auto abortHandler = g_pfnOrigAbortHandler.exchange(nullptr, std::memory_order_acq_rel); abortHandler != nullptr) + { + signal(SIGABRT, abortHandler); + } + + if (auto pureCallHandler = g_pfnOrigPureCall.exchange(nullptr, std::memory_order_acq_rel); pureCallHandler != nullptr) + { + _set_purecall_handler(pureCallHandler); + } + + if (auto previousFilter = g_pfnOrigFilt.exchange(nullptr, std::memory_order_acq_rel); previousFilter != nullptr) + { + SetUnhandledExceptionFilter(previousFilter); + } + + if (auto kernelSetUnhandled = g_pfnKernelSetUnhandledExceptionFilter.exchange(nullptr, std::memory_order_acq_rel); kernelSetUnhandled != nullptr) + { + g_kernelSetUnhandledExceptionFilterTrampoline = kernelSetUnhandled; + if (!SharedUtil::UndoFunctionDetour(g_kernelSetUnhandledExceptionFilterTrampoline, reinterpret_cast(RedirectedSetUnhandledExceptionFilter))) + { + SafeDebugOutput("CrashHandler: WARNING - Failed to undo SEH detour during cleanup\n"); + } + g_kernelSetUnhandledExceptionFilterTrampoline = nullptr; + } + } +}; + +static CleanUpCrashHandler g_cBeforeAndAfter; + +namespace CrashHandler +{ + + [[nodiscard]] const std::vector& GetPdbDirectories() + { + static std::once_flag onceFlag; + static std::vector pdbDirs; + + std::call_once(onceFlag, + [] + { + try + { + const SString& processDir = SharedUtil::GetMTAProcessBaseDir(); + + if (processDir.empty()) [[unlikely]] + return; + + const std::filesystem::path rootPath{FromUTF8(processDir)}; + std::error_code ec{}; + + if (!std::filesystem::exists(rootPath, ec) || !std::filesystem::is_directory(rootPath, ec)) + return; + + std::set uniqueDirs; + + constexpr auto options = std::filesystem::directory_options::skip_permission_denied; + std::filesystem::recursive_directory_iterator iter{rootPath, options, ec}; + + if (ec) [[unlikely]] + return; + + constexpr auto maxDepth = 256u; + + for (const auto end = std::filesystem::recursive_directory_iterator{}; iter != end;) + { + if (iter.depth() > maxDepth) [[unlikely]] + iter.disable_recursion_pending(); + + std::error_code entryEc{}; + const bool isSymlink = iter->is_symlink(entryEc); + + if (entryEc || isSymlink) [[unlikely]] + { + iter.increment(ec), ec ? ec.clear() : void(); + continue; + } + + const bool isRegularFile = iter->is_regular_file(entryEc); + + if (entryEc) [[unlikely]] + { + iter.increment(ec), ec ? ec.clear() : void(); + continue; + } + + if (isRegularFile) [[likely]] + { + const auto extension = iter->path().extension().wstring(); + + if (extension.size() == 4 && (extension[0] == L'.') && (extension[1] == L'p' || extension[1] == L'P') && + (extension[2] == L'd' || extension[2] == L'D') && (extension[3] == L'b' || extension[3] == L'B')) [[unlikely]] + { + const auto parentPath = iter->path().parent_path(); + if (!parentPath.empty()) + { + const auto parentStr = ToUTF8(parentPath.wstring()); + uniqueDirs.insert(std::string{parentStr.c_str()}); + } + } + } + + iter.increment(ec), ec ? ec.clear() : void(); + } + + pdbDirs.assign(uniqueDirs.begin(), uniqueDirs.end()); + } + catch (...) + { + } + }); + + return pdbDirs; + } + + [[nodiscard]] bool ProcessHasLocalDebugSymbols() + { + return !GetPdbDirectories().empty(); + } + + [[nodiscard]] static bool InitializeSymbolHandler() + { + std::scoped_lock lock{g_symbolMutex}; + + if (g_symbolsInitialized.load(std::memory_order_acquire)) + return true; + + const HANDLE hProcess = GetCurrentProcess(); + + DWORD symOptions = SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES | SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_NO_PROMPTS | SYMOPT_LOAD_ANYTHING; + +#ifdef _DEBUG + symOptions |= SYMOPT_DEBUG; + SafeDebugOutput("CrashHandler: InitializeSymbolHandler - SYMOPT_DEBUG enabled for diagnostics\n"); +#endif + + SymSetOptions(symOptions); + + std::string symbolPath; + const auto& pdbDirs = GetPdbDirectories(); + + if (!pdbDirs.empty()) [[likely]] + { + auto first{true}; + for (const auto& dir : pdbDirs) + { + if (!std::exchange(first, false)) + symbolPath += ";"; + symbolPath += dir; + } + } + else [[unlikely]] + { + const auto& processDir = SharedUtil::GetMTAProcessBaseDir(); + if (!processDir.empty()) + symbolPath = processDir.c_str(); + } + + std::array envBuffer{}; + if (const auto len = GetEnvironmentVariableA("_NT_SYMBOL_PATH", envBuffer.data(), static_cast(envBuffer.size())); + len > 0 && len < envBuffer.size()) + { + const std::string_view envPath{envBuffer.data(), len}; + if (envPath.find("http") == std::string_view::npos && envPath.find("SRV") == std::string_view::npos) [[likely]] + { + if (!symbolPath.empty()) + symbolPath += ";"; + symbolPath += envBuffer.data(); + } + } + + std::array debugBuffer{}; + + if (symbolPath.empty()) + { + SafeDebugOutput("CrashHandler: InitializeSymbolHandler - WARNING: Empty symbol search path, symbols may not load\n"); + } + else + { + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), "CrashHandler: InitializeSymbolHandler - Symbol search path (%zu chars): %s\n", + symbolPath.size(), symbolPath.c_str()); + } + + const char* pSymbolPath = symbolPath.empty() ? nullptr : symbolPath.c_str(); + + if (SymInitialize(hProcess, pSymbolPath, TRUE) == FALSE) [[unlikely]] + { + const auto error = GetLastError(); + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), + "CrashHandler: InitializeSymbolHandler - SymInitialize FAILED with error 0x%08X (path: %s)\n", error, + pSymbolPath ? pSymbolPath : ""); + + constexpr auto kErrorAlreadyExists = 0x000000B7; + constexpr auto kErrorFileNotFound = 0x00000002; + constexpr auto kErrorAccessDenied = 0x00000005; + + if (error == kErrorAlreadyExists) [[unlikely]] + { + SafeDebugOutput("CrashHandler: InitializeSymbolHandler - ERROR_ALREADY_EXISTS despite lock, forcing cleanup\n"); + SymCleanup(hProcess); + } + + return false; + } + + if (SymRefreshModuleList(hProcess) == FALSE) + { + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), "CrashHandler: InitializeSymbolHandler - WARNING: SymRefreshModuleList failed\n"); + } + + [[maybe_unused]] const bool modulesRegistered = RegisterProcessModulesWithDbgHelp(hProcess); + + auto moduleCount = DWORD{0}; + auto symbolsLoadedCount = DWORD{0}; + auto modulesNeedingLoad = DWORD{0}; + + auto enumerateModules = [&]() -> bool + { + moduleCount = 0; + symbolsLoadedCount = 0; + modulesNeedingLoad = 0; + + struct EnumContext + { + DWORD* pModuleCount; + DWORD* pSymbolsCount; + DWORD* pNeedingLoad; + HANDLE hProcess; + }; + + EnumContext enumCtx{&moduleCount, &symbolsLoadedCount, &modulesNeedingLoad, hProcess}; + + if (SymEnumerateModules64( + hProcess, + [](PCSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext) -> BOOL + { + auto* pCtx = static_cast(UserContext); + (*pCtx->pModuleCount)++; + + IMAGEHLP_MODULE64 moduleInfo{}; + moduleInfo.SizeOfStruct = sizeof(moduleInfo); + + if (SymGetModuleInfo64(pCtx->hProcess, BaseOfDll, &moduleInfo) != FALSE) + { + const bool hasSymbols = (moduleInfo.SymType != SymNone && moduleInfo.SymType != SymDeferred && moduleInfo.LoadedPdbName[0] != '\0'); + + if (hasSymbols) + { + (*pCtx->pSymbolsCount)++; +#ifdef _DEBUG + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), " Module: %s [Base: 0x%llX, SymType: %d, PDB: %s]\n", + ModuleName ? ModuleName : "", BaseOfDll, moduleInfo.SymType, moduleInfo.LoadedPdbName); +#endif + } + else + { + (*pCtx->pNeedingLoad)++; + if (ModuleName && ModuleName[0] != '\0') + { + const DWORD64 loadedBase = SymLoadModuleEx(pCtx->hProcess, nullptr, ModuleName, nullptr, BaseOfDll, 0, nullptr, 0); + if (loadedBase != 0) + { + (*pCtx->pSymbolsCount)++; +#ifdef _DEBUG + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), + " Module: %s [Base: 0x%llX] - Symbols loaded via SymLoadModuleEx\n", ModuleName, BaseOfDll); +#endif + } +#ifdef _DEBUG + else + { + const DWORD loadError = GetLastError(); + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), + " Module: %s [Base: 0x%llX] - SymLoadModuleEx FAILED (error 0x%08X)\n", ModuleName, BaseOfDll, + loadError); + } +#endif + } + } + } +#ifdef _DEBUG + else + { + const DWORD moduleInfoError = GetLastError(); + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), + " Module: %s [Base: 0x%llX] - SymGetModuleInfo64 FAILED (error 0x%08X)\n", + ModuleName ? ModuleName : "", BaseOfDll, moduleInfoError); + } +#endif + return TRUE; + }, + &enumCtx) == FALSE) + { + const DWORD enumError = GetLastError(); + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), + "CrashHandler: InitializeSymbolHandler - WARNING: SymEnumerateModules64 failed with error 0x%08X\n", enumError); + return false; + } + + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), + "CrashHandler: InitializeSymbolHandler - Enumerated %lu modules, %lu with symbols (%lu needed explicit load)\n", moduleCount, + symbolsLoadedCount, modulesNeedingLoad); + + if (symbolsLoadedCount == 0 && moduleCount > 0) + { + SafeDebugOutput("CrashHandler: InitializeSymbolHandler - CRITICAL: Zero symbols loaded despite modules present!\n"); + SafeDebugOutput("CrashHandler: InitializeSymbolHandler - Possible causes: PDB mismatch, wrong paths, or corrupted symbols\n"); + } + + return true; + }; + + bool enumerationOk = enumerateModules(); + + if ((!enumerationOk || moduleCount == 0) && RegisterProcessModulesWithDbgHelp(hProcess)) + { + SafeDebugOutput("CrashHandler: InitializeSymbolHandler - Module table rebuilt after EnumProcessModules registration\n"); + enumerationOk = enumerateModules(); + } + + if (!enumerationOk) + { + SafeDebugOutput("CrashHandler: InitializeSymbolHandler - ERROR: Unable to enumerate modules, cleaning up symbol handler\n"); + SymCleanup(hProcess); + return false; + } + + if (moduleCount == 0) + { + SafeDebugOutput("CrashHandler: InitializeSymbolHandler - ERROR: Symbol handler initialized but module list is empty\n"); + SymCleanup(hProcess); + return false; + } + + g_symbolProcess.store(hProcess, std::memory_order_release); + g_symbolsInitialized.store(true, std::memory_order_release); + + const auto validationOk = (symbolsLoadedCount > 0 || moduleCount == 0); + + if (validationOk) [[likely]] + { + SafeDebugOutput("CrashHandler: InitializeSymbolHandler - Symbol handler initialized successfully\n"); + } + else [[unlikely]] + { + SafeDebugOutput("CrashHandler: InitializeSymbolHandler - WARNING: Initialized but no symbols loaded!\n"); + } + + return true; + } + +} + +[[nodiscard]] BOOL __stdcall SetCrashHandlerFilter(PFNCHFILTFN pFn) +{ + if (pFn == nullptr) + { + UninstallCrashHandlers(); + return TRUE; + } + + g_pfnCrashCallback.store(pFn, std::memory_order_seq_cst); + + std::array debugBuffer{}; + SAFE_DEBUG_PRINT(debugBuffer, "%.*sInstalling handlers with callback at 0x%p\n", static_cast(DEBUG_PREFIX_CRASH.size()), DEBUG_PREFIX_CRASH.data(), + reinterpret_cast(pFn)); + + SafeDebugOutput("========================================\n"); + SafeDebugOutput("CrashHandler: Starting PDB detection and symbol initialization\n"); + SafeDebugOutput("========================================\n"); + + // Warm up PDB detection early to avoid filesystem scan during crash handling + // This performs the recursive directory search now rather than during exception processing + const bool hasSymbols = CrashHandler::ProcessHasLocalDebugSymbols(); + + SafeDebugOutput("========================================\n"); + SAFE_DEBUG_PRINT(debugBuffer, "%.*sDebug symbols %s\n", static_cast(DEBUG_PREFIX_CRASH.size()), DEBUG_PREFIX_CRASH.data(), + hasSymbols ? "DETECTED" : "not found"); + + if (hasSymbols) + { + if (CrashHandler::InitializeSymbolHandler()) + { + SafeDebugOutput("CrashHandler: Symbol handler pre-initialized successfully\n"); + } + else + { + SafeDebugOutput("CrashHandler: WARNING - Symbol handler pre-initialization failed\n"); + } + } + + if (const BOOL phaseResult = SetInitializationPhase(INIT_PHASE_MINIMAL); phaseResult == FALSE) + { + SafeDebugOutput("CrashHandler: WARNING - Failed to set initialization phase to minimal\n"); + } + + SafeDebugOutput("CrashHandler: Phase 0 - Minimal setup\n"); + SafeDebugOutput("CrashHandler: Vectored exception handling disabled (SEH-only mode)\n"); + + if (g_bStackCookieCaptureEnabled.load(std::memory_order_acquire)) + { + InstallAbortHandlers(); + SafeDebugOutput("CrashHandler: Abort and purecall handlers armed for stack cookie capture\n"); + } + + InstallCppHandlers(); + + SafeDebugOutput("CrashHandler: SEH handler deferred until post-initialization phase\n"); + SafeDebugOutput("CrashHandler: Phase 0 setup completed successfully\n"); + SafeDebugOutput("===========================================\n"); + + return TRUE; +} + +[[nodiscard]] BOOL __stdcall EnableStackCookieFailureCapture(BOOL bEnable) +{ + const bool bEnableBool = (bEnable != FALSE); + g_bStackCookieCaptureEnabled.store(bEnableBool, std::memory_order_release); + + std::array szDebug{}; + SAFE_DEBUG_PRINT(szDebug, "%.*sStack cookie failure capture %s\n", static_cast(DEBUG_PREFIX_CRASH.size()), DEBUG_PREFIX_CRASH.data(), + bEnableBool ? "ENABLED" : "DISABLED"); + + if (bEnableBool) + { + SafeDebugOutput("CrashHandler: Stack cookie capture enabled - call SetCrashHandlerFilter to activate\n"); + + ConfigureWerLocalDumps(); + + if (g_pfnCrashCallback.load(std::memory_order_acquire) != nullptr) + { + InstallAbortHandlers(); + } + } + else + { + std::scoped_lock lock{g_handlerStateMutex}; + + if (auto abortHandler = g_pfnOrigAbortHandler.exchange(nullptr, std::memory_order_acq_rel); abortHandler != nullptr) + { + if (void(__cdecl * previousHandler)(int) = signal(SIGABRT, abortHandler); previousHandler == SIG_ERR) + { + const int errnoValue = errno; + constexpr auto bufferSize = DEBUG_BUFFER_SIZE; + std::array szDebug{}; + SAFE_DEBUG_PRINT_C(szDebug.data(), bufferSize, "CrashHandler: WARNING - Failed to restore SIGABRT handler, errno: %d\n", errnoValue); + } + else + { + SafeDebugOutput("CrashHandler: SIGABRT handler restored\n"); + } + } + + if (auto pureCallHandler = g_pfnOrigPureCall.exchange(nullptr, std::memory_order_acq_rel); pureCallHandler != nullptr) + { + if (_purecall_handler previous = _set_purecall_handler(pureCallHandler); previous == nullptr) + { + SafeDebugOutput("CrashHandler: WARNING - Failed to restore pure call handler\n"); + } + else + { + SafeDebugOutput("CrashHandler: Pure call handler restored\n"); + } + } + + g_bInAbortHandler.store(false, std::memory_order_release); + } + + return TRUE; +} + +[[nodiscard]] BOOL __stdcall ConfigureWerForFailFast() +{ + return ConfigureWerLocalDumps() ? TRUE : FALSE; +} + +static void InstallCppHandlers() +{ + std::scoped_lock lock{g_handlerStateMutex}; + + if (g_pfnOrigTerminate.load(std::memory_order_acquire) == nullptr) + { + std::terminate_handler previous = std::set_terminate(CppTerminateHandler); + g_pfnOrigTerminate.store(previous, std::memory_order_release); + SafeDebugOutput("CrashHandler: C++ terminate handler installed\n"); + } + + if (g_pfnOrigNewHandler.load(std::memory_order_acquire) == nullptr) + { +#if defined(_MSC_VER) + CrtNewHandler previous = _set_new_handler(CppNewHandlerBridge); +#else + std::new_handler previous = std::set_new_handler(CppNewHandlerBridge); +#endif + g_pfnOrigNewHandler.store(previous, std::memory_order_release); + SafeDebugOutput("CrashHandler: C++ new handler installed\n"); + } +} + +static void InstallAbortHandlers() +{ + std::scoped_lock lock{g_handlerStateMutex}; + + if (!g_bStackCookieCaptureEnabled.load(std::memory_order_acquire)) + { + SafeDebugOutput("CrashHandler: Stack cookie capture disabled, skipping abort handlers\n"); + return; + } + + if (g_pfnCrashCallback.load(std::memory_order_acquire) == nullptr) + { + SafeDebugOutput("CrashHandler: WARNING - No callback set, skipping abort handlers\n"); + return; + } + + if (g_pfnOrigAbortHandler.load(std::memory_order_acquire) == nullptr) + { + if (void(__cdecl * prevHandler)(int) = signal(SIGABRT, AbortSignalHandler); prevHandler != SIG_ERR) + { + g_pfnOrigAbortHandler.store(prevHandler, std::memory_order_release); + SafeDebugOutput("CrashHandler: SIGABRT handler installed\n"); + } + else + { + const int errnoValue = errno; + constexpr auto bufferSize = DEBUG_BUFFER_SIZE; + std::array szDebug{}; + SAFE_DEBUG_PRINT_C(szDebug.data(), bufferSize, "CrashHandler: WARNING - Failed to install SIGABRT handler, errno: %d\n", errnoValue); + } + } + + if (g_pfnOrigPureCall.load(std::memory_order_acquire) == nullptr) + { + _purecall_handler previous = _set_purecall_handler(PureCallHandler); + g_pfnOrigPureCall.store(previous, std::memory_order_release); + SafeDebugOutput("CrashHandler: Pure virtual call handler installed\n"); + } +} + +static bool ConfigureWerLocalDumps() +{ + if (g_bWerLocalDumpConfigured.exchange(true, std::memory_order_acq_rel)) + { + return true; + } + + wchar_t modulePath[MAX_PATH]{}; + if (GetModuleFileNameW(nullptr, modulePath, MAX_PATH) == 0) + { + SafeDebugOutput("CrashHandler: WARNING - Failed to get module path for WER config\n"); + return false; + } + + const SString& baseDir = SharedUtil::GetMTAProcessBaseDir(); + SString mtaDumpPath = PathJoin(baseDir, "mta\\dumps\\private"); + + if (!CreateDirectoryA(PathJoin(baseDir, "mta\\dumps"), nullptr)) + { + if (GetLastError() != ERROR_ALREADY_EXISTS) + { + SafeDebugOutput("CrashHandler: WARNING - Failed to create mta\\dumps directory\n"); + } + } + + if (!CreateDirectoryA(mtaDumpPath, nullptr)) + { + if (GetLastError() != ERROR_ALREADY_EXISTS) + { + SafeDebugOutput("CrashHandler: WARNING - Failed to create mta\\dumps\\private directory\n"); + } + } + + std::wstring dumpPathW = MbUTF8ToUTF16(mtaDumpPath); + + // Dynamically load WerRegisterAppLocalDump to support older Windows versions + // The function is only available on Windows 10 1709 (build 16299) and later + HMODULE hWer = LoadLibraryW(L"wer.dll"); + if (hWer) + { + auto pfnWerRegisterAppLocalDump = reinterpret_cast(reinterpret_cast(GetProcAddress(hWer, "WerRegisterAppLocalDump"))); + + if (pfnWerRegisterAppLocalDump) + { + HRESULT hr = pfnWerRegisterAppLocalDump(dumpPathW.c_str()); + if (SUCCEEDED(hr)) + { + SafeDebugOutput("CrashHandler: WER app-local dump registered to MTA dumps folder\n"); + SafeDebugOutput("CrashHandler: Fail-fast exceptions (0xC0000409, 0xC0000374) will now generate dumps in mta\\dumps\\private\n"); + return true; + } + + if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_REGISTERED)) + { + SafeDebugOutput("CrashHandler: WER app-local dump already registered\n"); + return true; + } + + std::array debugBuffer{}; + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), "CrashHandler: WerRegisterAppLocalDump failed with 0x%08X, trying registry fallback\n", + static_cast(hr)); + } + else + { + SafeDebugOutput("CrashHandler: WerRegisterAppLocalDump not available (Windows 10 1709+ required), trying registry fallback\n"); + } + } + else + { + SafeDebugOutput("CrashHandler: Could not load wer.dll, trying registry fallback\n"); + } + + std::array debugBuffer{}; + + HKEY hKey = nullptr; + const wchar_t* exeName = wcsrchr(modulePath, L'\\'); + exeName = exeName ? exeName + 1 : modulePath; + + wchar_t regPath[512]{}; + _snwprintf_s(regPath, _countof(regPath), _TRUNCATE, L"SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\LocalDumps\\%s", exeName); + + // LocalDumps registry settings are only supported in HKEY_LOCAL_MACHINE (requires admin to write) + // First try to create/open with write access - succeeds if running as admin + // Use KEY_WOW64_64KEY to write to the 64-bit registry view. + // WER is a 64-bit system service that reads from the native 64-bit registry, + // not the WOW6432Node that 32-bit apps normally access. + LONG result = RegCreateKeyExW(HKEY_LOCAL_MACHINE, regPath, 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE | KEY_WOW64_64KEY, nullptr, &hKey, nullptr); + if (result == ERROR_SUCCESS) + { + // We have write access (running as admin) - update values to ensure correct path + // DumpType: 0=Custom, 1=MiniDump, 2=FullDump - use 1 for smaller dumps + DWORD dumpType = 1; + RegSetValueExW(hKey, L"DumpType", 0, REG_DWORD, reinterpret_cast(&dumpType), sizeof(dumpType)); + + DWORD dumpCount = 10; + RegSetValueExW(hKey, L"DumpCount", 0, REG_DWORD, reinterpret_cast(&dumpCount), sizeof(dumpCount)); + + RegSetValueExW(hKey, L"DumpFolder", 0, REG_EXPAND_SZ, reinterpret_cast(dumpPathW.c_str()), + static_cast((dumpPathW.length() + 1) * sizeof(wchar_t))); + + RegCloseKey(hKey); + + SafeDebugOutput("CrashHandler: WER LocalDumps configured via registry (admin access)\n"); + SafeDebugOutput("CrashHandler: Fail-fast exceptions should now generate dumps in mta\\dumps\\private\n"); + return true; + } + + // Can't write - check if key already exists and has correct values + result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, regPath, 0, KEY_READ | KEY_WOW64_64KEY, &hKey); + if (result == ERROR_SUCCESS) + { + wchar_t existingPath[MAX_PATH]{}; + DWORD pathSize = sizeof(existingPath); + DWORD pathType = 0; + + bool pathCorrect = false; + if (RegQueryValueExW(hKey, L"DumpFolder", nullptr, &pathType, reinterpret_cast(existingPath), &pathSize) == ERROR_SUCCESS) + { + if (pathType == REG_SZ || pathType == REG_EXPAND_SZ) + { + std::wstring existingPathStr(existingPath); + pathCorrect = (existingPathStr == dumpPathW); + } + } + + RegCloseKey(hKey); + + if (pathCorrect) + { + SafeDebugOutput("CrashHandler: WER LocalDumps registry key exists with correct path\n"); + SafeDebugOutput("CrashHandler: Fail-fast exceptions should generate dumps in mta\\dumps\\private\n"); + return true; + } + else + { + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), "CrashHandler: WARNING - WER LocalDumps exists but points to wrong path!\n"); + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), "CrashHandler: Expected: %s\n", ToUTF8(dumpPathW).c_str()); + SafeDebugOutput("CrashHandler: Run MTA as admin once OR reinstall to fix WER dump path\n"); + return false; + } + } + + // Neither write nor read succeeded - WER dumps won't work + SAFE_DEBUG_PRINT_C(debugBuffer.data(), debugBuffer.size(), "CrashHandler: Failed to access WER registry key in HKLM (error %ld)\n", result); + SafeDebugOutput("CrashHandler: WER LocalDumps requires either admin privileges or installer setup\n"); + SafeDebugOutput("CrashHandler: NOTE: Reinstall MTA or run as admin once to enable WER crash dumps\n"); + return false; +} + +[[nodiscard]] static bool TryReadEnvBool(const char* name, bool& outValue) +{ + std::array buffer{}; + DWORD length = GetEnvironmentVariableA(name, buffer.data(), static_cast(buffer.size())); + + if (length == 0 || length >= buffer.size()) + return false; + + const std::uint8_t rawChar{static_cast(buffer[0])}; + const char indicator{static_cast(std::tolower(rawChar))}; + outValue = !(indicator == '0' || indicator == 'f' || indicator == 'n'); + return true; +} + +[[nodiscard]] BOOL __stdcall GetCrashHandlerConfiguration(PCRASH_HANDLER_CONFIG pConfig) +{ + if (pConfig == nullptr) + return FALSE; + + memset(pConfig, 0, sizeof(CRASH_HANDLER_CONFIG)); + + auto disableSehDetourBool{false}; + auto forceSehDetourBool{false}; + [[maybe_unused]] const auto r1 = TryReadEnvBool("MTA_DISABLE_SEH_DETOUR", disableSehDetourBool); + [[maybe_unused]] const auto r2 = TryReadEnvBool("MTA_FORCE_SEH_DETOUR", forceSehDetourBool); + + pConfig->disableSehDetour = disableSehDetourBool ? TRUE : FALSE; + pConfig->forceSehDetour = forceSehDetourBool ? TRUE : FALSE; + + constexpr auto initDefaults = []() constexpr { return true; }; + static_assert(initDefaults(), "Configuration defaults validation"); + if (initDefaults()) + { + pConfig->enableStackCookieCapture = TRUE; + pConfig->enableEnhancedLogging = TRUE; + pConfig->enableSehHandler = TRUE; + pConfig->enableCppHandlers = TRUE; + pConfig->memoryReservationKB = 512; + pConfig->maxStackTraceFrames = 100; + pConfig->debugBufferSize = DEBUG_BUFFER_SIZE; + } + + return TRUE; +} + +// Helper to perform protected stack walk for callback exceptions +static BOOL ProtectedStackWalk64(DWORD machineType, HANDLE hProcess, HANDLE hThread, STACKFRAME64* frame, CONTEXT* context, + const StackTraceHelpers::StackWalkRoutines& routines) +{ + __try + { + return StackWalk64(machineType, hProcess, hThread, frame, context, routines.readMemory, routines.functionTableAccess, routines.moduleBase, nullptr); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return FALSE; + } +} + +// Helper to safely call SymFromAddr using only SEH +static bool SafeSymFromAddr(HANDLE hProcess, DWORD64 address, PSYMBOL_INFO pSymbol, bool isCallback) +{ + bool result{false}; + __try + { + if (SymFromAddr(hProcess, address, nullptr, pSymbol) != FALSE && pSymbol->Name != nullptr) + { + result = true; + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + if (isCallback) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - SymFromAddr faulted\n"); + } + } + return result; +} + +// Helper to safely call SymGetLineFromAddr64 using only SEH +static bool SafeSymGetLineFromAddr64(HANDLE hProcess, DWORD64 address, DWORD* pDisplacement, IMAGEHLP_LINE64* pLineInfo, bool isCallback) +{ + bool result{false}; + __try + { + if (SymGetLineFromAddr64(hProcess, address, pDisplacement, pLineInfo) != FALSE) + { + result = true; + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + if (isCallback) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - SymGetLineFromAddr64 faulted\n"); + } + } + return result; +} + +[[nodiscard]] BOOL __stdcall CaptureUnifiedStackTrace(_EXCEPTION_POINTERS* pException, DWORD maxFrames, std::vector* pOutTrace) +{ + if (pException == nullptr || pOutTrace == nullptr) + return FALSE; + + const auto hasSymbols = CrashHandler::ProcessHasLocalDebugSymbols(); + const auto initializedAtEntry = g_symbolsInitialized.load(std::memory_order_acquire); + + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Entry: hasSymbols=%s, initialized=%s\n", hasSymbols ? "true" : "false", + initializedAtEntry ? "true" : "false"); + + if (!hasSymbols) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - PDB detection returned FALSE - checking GetPdbDirectories()...\n"); + const auto& pdbDirs = CrashHandler::GetPdbDirectories(); + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - GetPdbDirectories() returned %zu directories\n", pdbDirs.size()); + } + + if (!hasSymbols) + { + static std::once_flag logOnce; + std::call_once(logOnce, + [] { SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - capturing without symbols (raw addresses only)\n"); }); + } + + // Check if this is a callback exception - these have special handling requirements + const bool isCallbackException = + (pException->ExceptionRecord != nullptr && pException->ExceptionRecord->ExceptionCode == STATUS_FATAL_USER_CALLBACK_EXCEPTION); + + // Handle null ContextRecord - can occur with callbacks and other severe exceptions + if (pException->ContextRecord == nullptr) + { + if (isCallbackException) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Callback exception has null context, cannot walk stack\n"); + } + else + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Null context record, cannot walk stack\n"); + } + return FALSE; + } + + if (isCallbackException) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Callback exception: using defensive stack capture\n"); + } + + pOutTrace->clear(); + + constexpr DWORD defaultMaxFrames = 32; + DWORD configMaxFrames = defaultMaxFrames; + if (CRASH_HANDLER_CONFIG config{}; GetCrashHandlerConfiguration(&config)) + { + configMaxFrames = config.maxStackTraceFrames; + } + + constexpr DWORD minFrames = 1; + constexpr DWORD maxAllowedFrames = 256; + const DWORD requestedFrames = maxFrames != 0 ? maxFrames : configMaxFrames; + const DWORD actualMaxFrames = std::clamp(requestedFrames, minFrames, maxAllowedFrames); + try + { + pOutTrace->reserve(actualMaxFrames); + } + catch (...) + { + } + + HANDLE hProcess = GetCurrentProcess(); + HANDLE hThread = GetCurrentThread(); + + CONTEXT context = *pException->ContextRecord; + STACKFRAME64 frame{}; + + // Verify CONTEXT_CONTROL is present before using Eip/Ebp/Esp for stack walking + const bool hasControlContext = (context.ContextFlags & CONTEXT_CONTROL) != 0; + if (!hasControlContext) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Incomplete context (flags=0x%08X), cannot walk stack%s\n", context.ContextFlags, + isCallbackException ? " (callback exception)" : ""); + return FALSE; + } + + // For EIP=0 crashes, start stack walk from return address at [ESP] + constexpr auto kNullAddress = uintptr_t{0}; + static_assert(kNullAddress == 0, "Null address constant must be zero"); + + const auto isNullJump = (context.Eip == kNullAddress); + + if (isNullJump) + { + // Try to read return address from [ESP] + const auto espAddr{static_cast(context.Esp)}; + const auto pReturnAddress{reinterpret_cast(espAddr)}; + + if (SharedUtil::IsReadablePointer(pReturnAddress, sizeof(void*))) + { + const auto returnAddr{reinterpret_cast(*pReturnAddress)}; + + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - EIP=0, starting stack walk from return address: 0x%08X\n", + static_cast(returnAddr)); + + // Start stack walk from return address instead of null EIP + frame.AddrPC.Offset = returnAddr; + frame.AddrFrame.Offset = context.Ebp; + frame.AddrStack.Offset = context.Esp; + } + else + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - EIP=0, ESP not readable (0x%08X), cannot capture stack\n", + static_cast(espAddr)); + return FALSE; + } + } + else + { + frame.AddrPC.Offset = context.Eip; + frame.AddrFrame.Offset = context.Ebp; + frame.AddrStack.Offset = context.Esp; + } + + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Mode = AddrModeFlat; + + auto symbolsAvailable = hasSymbols && initializedAtEntry; + + if (hasSymbols && !symbolsAvailable) [[unlikely]] + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Symbols detected but handler not initialized, attempting late init\n"); + symbolsAvailable = CrashHandler::InitializeSymbolHandler(); + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Late init result: %s\n", symbolsAvailable ? "SUCCESS" : "FAILED"); + } + + const auto useDbgHelp = symbolsAvailable; + const HANDLE symHandle = g_symbolProcess.load(std::memory_order_acquire); + + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Using DbgHelp: %s (symbolsAvailable=%s)\n", useDbgHelp ? "YES" : "NO", + symbolsAvailable ? "true" : "false"); + + if (useDbgHelp && symHandle != nullptr) + { + if (SymRefreshModuleList(symHandle) == FALSE) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - SymRefreshModuleList failed before stack walk\n"); + } + else + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - SymRefreshModuleList succeeded before stack walk\n"); + } + + [[maybe_unused]] const bool modulesRegistered = RegisterProcessModulesWithDbgHelp(symHandle); + } + + const auto routines = StackTraceHelpers::MakeStackWalkRoutines(useDbgHelp); + + constexpr auto kMaxSymbolNameLength = std::size_t{2048}; + constexpr auto symbolBufferSize = sizeof(SYMBOL_INFO) + kMaxSymbolNameLength; + + alignas(SYMBOL_INFO) auto symbolBuffer = std::array{}; + auto* const pSymbol = reinterpret_cast(symbolBuffer.data()); + pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); + pSymbol->MaxNameLen = kMaxSymbolNameLength; + + constexpr auto machineType = IMAGE_FILE_MACHINE_I386; + + for (auto frameIndex : std::views::iota(DWORD{0}, actualMaxFrames)) + { + // Always use protected stack walking as the stack might be corrupted + // (e.g. stack overflow, buffer overrun, or just garbage pointers) + BOOL bWalked = ProtectedStackWalk64(machineType, hProcess, hThread, &frame, &context, routines); + + if (bWalked == FALSE) + { + if (isCallbackException) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Exception during protected stack walk at frame %lu\n", frameIndex); + } + break; + } + + if (frame.AddrPC.Offset == 0) [[unlikely]] + break; + + const auto address = frame.AddrPC.Offset; + + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Frame %lu: address=0x%llX, useDbgHelp=%s\n", frameIndex, address, + useDbgHelp ? "true" : "false"); + + if (!useDbgHelp) [[unlikely]] + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Frame %lu: Using fallback formatting (no DbgHelp)\n", frameIndex); + pOutTrace->emplace_back(StackTraceHelpers::FormatAddressWithModuleAndAbsolute(address)); + continue; + } + + if (symHandle == nullptr) [[unlikely]] + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Frame %lu: symHandle is NULL\n", frameIndex); + pOutTrace->emplace_back(StackTraceHelpers::FormatAddressWithModuleAndAbsolute(address)); + continue; + } + + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Frame %lu: symHandle=0x%p\n", frameIndex, symHandle); + + auto moduleBase = SymGetModuleBase64(symHandle, address); + + if (moduleBase == 0) [[unlikely]] + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Frame %lu: Address not in any loaded module, attempting registration\n", + frameIndex); + + if (RegisterModuleForAddress(symHandle, address)) + { + moduleBase = SymGetModuleBase64(symHandle, address); + } + } + + if (moduleBase == 0) [[unlikely]] + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, + "CaptureUnifiedStackTrace - Frame %lu: Address still not associated with a module after registration attempt\n", frameIndex); + pOutTrace->emplace_back(StackTraceHelpers::FormatAddressWithModuleAndAbsolute(address)); + continue; + } + + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Frame %lu: moduleBase=0x%llX\n", frameIndex, moduleBase); + + std::string symbolName; + symbolName.resize(64); + _snprintf_s(symbolName.data(), symbolName.size(), _TRUNCATE, "0x%llX", address); + symbolName.resize(std::strlen(symbolName.c_str())); + + if (!SafeSymFromAddr(symHandle, address, pSymbol, isCallbackException)) [[unlikely]] + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Frame %lu: SymFromAddr failed\n", frameIndex); + symbolName.resize(64); + _snprintf_s(symbolName.data(), symbolName.size(), _TRUNCATE, "0x%llX [lookup failed]", address); + symbolName.resize(std::strlen(symbolName.c_str())); + } + else if (const auto nameView = std::string_view{pSymbol->Name ? pSymbol->Name : ""}; nameView.empty()) [[unlikely]] + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Frame %lu: Symbol lookup succeeded but name is empty\n", frameIndex); + symbolName.resize(64); + _snprintf_s(symbolName.data(), symbolName.size(), _TRUNCATE, "0x%llX [no symbol]", address); + symbolName.resize(std::strlen(symbolName.c_str())); + } + else [[likely]] + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Frame %lu: Resolved symbol '%s'\n", frameIndex, pSymbol->Name); + symbolName.assign(nameView.begin(), nameView.end()); + } + + IMAGEHLP_LINE64 lineInfo{.SizeOfStruct = sizeof(IMAGEHLP_LINE64)}; + auto lineDisplacement = DWORD{0}; + + std::string frameInfo; + + if (!SafeSymGetLineFromAddr64(symHandle, address, &lineDisplacement, &lineInfo, isCallbackException)) [[unlikely]] + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Frame %lu: No line info available\n", frameIndex); + frameInfo.resize(256); + _snprintf_s(frameInfo.data(), frameInfo.size(), _TRUNCATE, "%s [0x%llX]", symbolName.c_str(), address); + frameInfo.resize(std::strlen(frameInfo.c_str())); + } + else if (const auto fileName = std::string_view{lineInfo.FileName ? lineInfo.FileName : ""}; fileName.empty()) [[unlikely]] + { + frameInfo.resize(256); + _snprintf_s(frameInfo.data(), frameInfo.size(), _TRUNCATE, "%s [0x%llX]", symbolName.c_str(), address); + frameInfo.resize(std::strlen(frameInfo.c_str())); + } + else [[likely]] + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Frame %lu: Line info: %s:%lu\n", frameIndex, lineInfo.FileName, + lineInfo.LineNumber); + frameInfo.resize(512); + _snprintf_s(frameInfo.data(), frameInfo.size(), _TRUNCATE, "%s (%.*s:%lu) [0x%llX]", symbolName.c_str(), static_cast(fileName.size()), + fileName.data(), lineInfo.LineNumber, address); + frameInfo.resize(std::strlen(frameInfo.c_str())); + } + + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "CaptureUnifiedStackTrace - Frame %lu: Final: %s\n", frameIndex, frameInfo.c_str()); + + pOutTrace->emplace_back(std::move(frameInfo)); + } + + return !pOutTrace->empty(); +} + +static bool InstallSehHandler() +{ + std::scoped_lock lock{g_handlerStateMutex}; + + if (g_pfnOrigFilt.load(std::memory_order_acquire) != nullptr) + { + SafeDebugOutput("CrashHandler: SEH already installed\n"); + return true; + } + + LPTOP_LEVEL_EXCEPTION_FILTER previousFilter = SetUnhandledExceptionFilter(CrashHandlerExceptionFilter); + g_pfnOrigFilt.store(previousFilter, std::memory_order_release); + + bool success{true}; + + std::array szDebug{}; + if (previousFilter != nullptr) + { + SAFE_DEBUG_PRINT(szDebug, "%.*sSEH installed, previous filter at 0x%p\n", static_cast(DEBUG_PREFIX_CRASH.size()), DEBUG_PREFIX_CRASH.data(), + static_cast(previousFilter)); + } + else + { + SafeDebugOutput("CrashHandler: SEH installed - no previous filter present\n"); + } + + bool detourEnabled{true}; + bool detourForced{false}; + + if (CRASH_HANDLER_CONFIG config{}; GetCrashHandlerConfiguration(&config)) + { + const bool disableDetour{config.disableSehDetour != FALSE}; + const bool forceDetour{config.forceSehDetour != FALSE}; + + SAFE_DEBUG_PRINT(szDebug, "CrashHandler: SEH detour env check - MTA_DISABLE_SEH_DETOUR: %s, MTA_FORCE_SEH_DETOUR: %s\n", + disableDetour ? "true" : "false", forceDetour ? "true" : "false"); + + detourForced = forceDetour; + + if (disableDetour && !detourForced) [[unlikely]] + { + detourEnabled = false; + } + } + + const bool debuggerPresent{IsDebuggerPresent() != FALSE}; + SAFE_DEBUG_PRINT(szDebug, "CrashHandler: Debugger present: %s\n", debuggerPresent ? "true" : "false"); + + if (!detourEnabled) [[unlikely]] + { + SafeDebugOutput("CrashHandler: SEH detour protection disabled by configuration\n"); + return success; + } + + if (detourForced) + { + SafeDebugOutput("CrashHandler: SEH detour protection forced by configuration\n"); + } + else if (debuggerPresent) + { + SafeDebugOutput("CrashHandler: SEH detour protection enabled (debugger present)\n"); + } + else + { + SafeDebugOutput("CrashHandler: SEH detour protection enabled for production runtime\n"); + } + + if (g_pfnKernelSetUnhandledExceptionFilter.load(std::memory_order_acquire) != nullptr) + { + SafeDebugOutput("CrashHandler: SEH detour protection already installed\n"); + return success; + } + + if (HMODULE kernelModule = GetModuleHandleW(L"KERNEL32.DLL"); kernelModule == nullptr) + { + SafeDebugOutput("CrashHandler: WARNING - Failed to resolve KERNEL32.DLL handle\n"); + return success; + } + else + { + decltype(&SetUnhandledExceptionFilter) setUnhandled = nullptr; + if (SharedUtil::TryGetProcAddress(kernelModule, "SetUnhandledExceptionFilter", setUnhandled)) + { + g_kernelSetUnhandledExceptionFilterTrampoline = setUnhandled; + + if (SharedUtil::DetourFunction(g_kernelSetUnhandledExceptionFilterTrampoline, reinterpret_cast(RedirectedSetUnhandledExceptionFilter))) + { + g_pfnKernelSetUnhandledExceptionFilter.store(g_kernelSetUnhandledExceptionFilterTrampoline, std::memory_order_release); + SafeDebugOutput("CrashHandler: SEH detour protection installed\n"); + } + else + { + SafeDebugOutput("CrashHandler: WARNING - SEH detour protection FAILED (non-critical)\n"); + g_pfnKernelSetUnhandledExceptionFilter.store(nullptr, std::memory_order_release); + g_kernelSetUnhandledExceptionFilterTrampoline = nullptr; + success = false; + } + } + else + { + SafeDebugOutput("CrashHandler: WARNING - Failed to resolve SetUnhandledExceptionFilter address\n"); + success = false; + } + } + + return success; +} + +static void UninstallCrashHandlers() +{ + std::scoped_lock lock{g_handlerStateMutex}; + + SafeDebugOutput("CrashHandler: Unhooking crash handlers\n"); + + g_pfnCrashCallback.store(nullptr, std::memory_order_release); + g_bStackCookieCaptureEnabled.store(false, std::memory_order_release); + + if (auto terminateHandler = g_pfnOrigTerminate.exchange(nullptr, std::memory_order_acq_rel); terminateHandler != nullptr) + { + std::set_terminate(terminateHandler); + } + + if (auto newHandler = g_pfnOrigNewHandler.exchange(nullptr, std::memory_order_acq_rel); newHandler != nullptr) + { +#if defined(_MSC_VER) + _set_new_handler(newHandler); +#else + std::set_new_handler(newHandler); +#endif + } + + if (auto abortHandler = g_pfnOrigAbortHandler.exchange(nullptr, std::memory_order_acq_rel); abortHandler != nullptr) + { + signal(SIGABRT, reinterpret_cast(abortHandler)); + } + + if (auto pureCallHandler = g_pfnOrigPureCall.exchange(nullptr, std::memory_order_acq_rel); pureCallHandler != nullptr) + { + _set_purecall_handler(pureCallHandler); + } + + if (auto previousFilt = g_pfnOrigFilt.exchange(nullptr, std::memory_order_acq_rel); previousFilt != nullptr) + { + SetUnhandledExceptionFilter(previousFilt); + } + + if (auto kernelSetUnhandled = g_pfnKernelSetUnhandledExceptionFilter.exchange(nullptr, std::memory_order_acq_rel); kernelSetUnhandled != nullptr) + { + g_kernelSetUnhandledExceptionFilterTrampoline = kernelSetUnhandled; + if (!SharedUtil::UndoFunctionDetour(g_kernelSetUnhandledExceptionFilterTrampoline, reinterpret_cast(RedirectedSetUnhandledExceptionFilter))) + { + SafeDebugOutput("CrashHandler: WARNING - Failed to undo SEH detour\n"); + } + g_kernelSetUnhandledExceptionFilterTrampoline = nullptr; + } +} + +static bool BuildExceptionContext(EXCEPTION_POINTERS& outExPtrs, EXCEPTION_RECORD*& outExRecord, CONTEXT*& outCtx, DWORD dwExceptionCode) +{ + struct LocalAllocGuard + { + void* ptr; + explicit LocalAllocGuard(std::size_t size) : ptr(LocalAlloc(LPTR, size)) {} + ~LocalAllocGuard() + { + if (ptr) + LocalFree(ptr); + } + LocalAllocGuard(const LocalAllocGuard&) = delete; + LocalAllocGuard& operator=(const LocalAllocGuard&) = delete; + }; + + LocalAllocGuard exRecordGuard(sizeof(EXCEPTION_RECORD)); + LocalAllocGuard ctxGuard(sizeof(CONTEXT)); + + if (exRecordGuard.ptr == nullptr || ctxGuard.ptr == nullptr) + { + return false; + } + + outExRecord = static_cast(exRecordGuard.ptr); + outCtx = static_cast(ctxGuard.ptr); + + exRecordGuard.ptr = nullptr; + ctxGuard.ptr = nullptr; + + void* returnAddr{_ReturnAddress()}; + InitializeExceptionRecord(outExRecord, dwExceptionCode, returnAddr); + + outCtx->ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; + + try + { + RtlCaptureContext(outCtx); + } + catch (...) + { + SafeDebugOutput("BuildExceptionContext: RtlCaptureContext failed\n"); + + LocalFree(outExRecord); + LocalFree(outCtx); + outExRecord = nullptr; + outCtx = nullptr; + + return false; + } + + outExPtrs.ExceptionRecord = outExRecord; + outExPtrs.ContextRecord = outCtx; + + return true; +} + +[[noreturn]] void __cdecl CppTerminateHandler() +{ + bool expected = false; + if (!g_bInTerminateHandler.compare_exchange_strong(expected, true, std::memory_order_acq_rel)) + { + SignalSafePrintPrefixed(DEBUG_PREFIX_CPP, "Recursive\n"); + TerminateSelfWithExitCode(CPP_EXCEPTION_CODE); + } + + SafeDebugOutput(DEBUG_SEPARATOR); + SafeDebugPrintPrefixed(DEBUG_PREFIX_CPP, "Unhandled C++ exception detected\n"); + + ReportCurrentCppException(); + + SafeDebugOutput(DEBUG_SEPARATOR); + + if (auto telemetryNote = CrashTelemetry::BuildAllocationTelemetryNote(); !telemetryNote.empty()) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CPP, "%s\n", telemetryNote.c_str()); + } + + EXCEPTION_RECORD* pExRecord = nullptr; + CONTEXT* pCtx = nullptr; + EXCEPTION_POINTERS exPtrs{}; + + const bool haveContext = BuildExceptionContext(exPtrs, pExRecord, pCtx, CPP_EXCEPTION_CODE); + if (haveContext) + { + CaptureAllocationTelemetry(&exPtrs); + } + + PFNCHFILTFN callback = g_pfnCrashCallback.load(std::memory_order_acquire); + + if (callback != nullptr && haveContext) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CPP, "Calling crash handler callback\n"); + + try + { + callback(&exPtrs); + } + catch (...) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CPP, "Exception in crash handler callback\n"); + } + } + + if (pCtx != nullptr) + { + LocalFree(pCtx); + } + + if (pExRecord != nullptr) + { + LocalFree(pExRecord); + } + + SafeDebugPrintPrefixed(DEBUG_PREFIX_CPP, "Terminating process\n"); + TerminateSelfWithExitCode(CPP_EXCEPTION_CODE); +} + +static void ReportCurrentCppException() +{ + try + { + std::exception_ptr eptr = std::current_exception(); + if (!eptr) + { + return; + } + + std::rethrow_exception(eptr); + } + catch (const std::bad_array_new_length&) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CPP, "std::bad_array_new_length caught\n"); + } + catch (const std::bad_alloc&) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CPP, "std::bad_alloc caught - OUT OF MEMORY!\n"); + } + catch (const std::exception& e) + { + std::array szDebug{}; + SAFE_DEBUG_PRINT(szDebug, "%.*sstd::exception caught: %s\n", static_cast(DEBUG_PREFIX_CPP.size()), DEBUG_PREFIX_CPP.data(), e.what()); + } + catch (...) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CPP, "Unknown exception type\n"); + } +} + +[[noreturn]] void __cdecl CppNewHandler() +{ + bool expected = false; + if (!g_bInNewHandler.compare_exchange_strong(expected, true, std::memory_order_acq_rel)) + { + SignalSafeOutput("C++ NEW HANDLER: Recursive\n"); + TerminateSelfWithExitCode(STATUS_NO_MEMORY); + } + + SafeDebugOutput(DEBUG_SEPARATOR); + SafeDebugOutput("C++ NEW HANDLER: Memory allocation failed\n"); + SafeDebugOutput(DEBUG_SEPARATOR); + + if (auto telemetryNote = CrashTelemetry::BuildAllocationTelemetryNote(); !telemetryNote.empty()) + { + SafeDebugOutput(telemetryNote.c_str()); + SafeDebugOutput("\n"); + } + + std::terminate(); +} + +[[nodiscard]] BOOL __stdcall GetEnhancedExceptionInfo(PENHANCED_EXCEPTION_INFO pExceptionInfo) +{ + if (pExceptionInfo == nullptr) + return FALSE; + + std::unique_lock lock{g_exceptionInfoMutex, std::try_to_lock}; + if (!lock.owns_lock()) + { + return FALSE; + } + + if (!g_lastExceptionInfo) + return FALSE; + + *pExceptionInfo = *g_lastExceptionInfo; + return TRUE; +} + +[[nodiscard]] BOOL __stdcall CaptureCurrentException() +{ + try + { + std::unique_lock lock{g_exceptionInfoMutex, std::try_to_lock}; + if (!lock.owns_lock()) + { + return FALSE; + } + + ENHANCED_EXCEPTION_INFO info = {}; + info.capturedException = std::current_exception(); + info.uncaughtExceptionCount = std::uncaught_exceptions(); + info.timestamp = std::chrono::system_clock::now(); + info.threadId = GetCurrentThreadId(); + info.processId = GetCurrentProcessId(); + + g_lastExceptionInfo = info; + return TRUE; + } + catch (...) + { + return FALSE; + } +} + +// Helper to isolate try/catch from SEH in LogExceptionDetails +static BOOL TryLogEnhancedExceptionInfo(EXCEPTION_POINTERS* pException) +{ + try + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogExceptionDetails - Calling LogEnhancedExceptionInfo...\n"); + LogEnhancedExceptionInfo(pException); + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogExceptionDetails - LogEnhancedExceptionInfo completed\n"); + return TRUE; + } + catch (...) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogExceptionDetails - Exception caught in LogEnhancedExceptionInfo\n"); + return TRUE; // Return TRUE to indicate we handled the attempt, even if it failed + } +} + +[[nodiscard]] BOOL __stdcall LogExceptionDetails(EXCEPTION_POINTERS* pException) +{ + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "========================================\n"); + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogExceptionDetails - ENTRY\n"); + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "========================================\n"); + + if (pException == nullptr) + { + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogExceptionDetails - pException is NULL\n"); + return FALSE; + } + + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogExceptionDetails - pException OK\n"); + + if (pException->ExceptionRecord != nullptr) + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogExceptionDetails - ExceptionRecord OK\n"); + else + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogExceptionDetails - ExceptionRecord is NULL\n"); + + if (pException->ContextRecord != nullptr) + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogExceptionDetails - ContextRecord OK\n"); + else + SafeDebugPrintPrefixed(DEBUG_PREFIX_CRASH, "LogExceptionDetails - ContextRecord is NULL (THIS WILL PREVENT ENHANCED INFO)\n"); + + LogBasicExceptionInfo(pException); + StoreBasicExceptionInfo(pException); + + return TryLogEnhancedExceptionInfo(pException); +} + +// Helper to isolate SEH for logging in CrashHandlerExceptionFilter +static BOOL SEHLogExceptionDetails(EXCEPTION_POINTERS* pExPtrs) +{ + BOOL result = FALSE; + __try + { + result = LogExceptionDetails(pExPtrs); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + SafeDebugOutput("SEH: CRITICAL - Exception while logging exception details\n"); + result = FALSE; + } + return result; +} + +// Helper to isolate SEH for storing basic info in CrashHandlerExceptionFilter +static void SEHStoreBasicExceptionInfo(EXCEPTION_POINTERS* pExPtrs) +{ + __try + { + StoreBasicExceptionInfo(pExPtrs); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + SafeDebugOutput("SEH: CRITICAL - Exception while storing basic info during stack overflow\n"); + } +} + +// Helper to isolate try/catch for callback in CrashHandlerExceptionFilter +static LONG TryCallCrashCallback(PFNCHFILTFN callback, EXCEPTION_POINTERS* pExPtrs) +{ + try + { + return callback(pExPtrs); + } + catch (...) + { + SafeDebugOutput("SEH: CRITICAL - Exception in crash handler callback!\n"); + return EXCEPTION_CONTINUE_SEARCH; + } +} + +LONG __stdcall CrashHandlerExceptionFilter(EXCEPTION_POINTERS* pExPtrs) +{ + if (pExPtrs == nullptr || pExPtrs->ExceptionRecord == nullptr) + { + return EXCEPTION_CONTINUE_SEARCH; + } + + const DWORD dwExceptionCode{pExPtrs->ExceptionRecord->ExceptionCode}; + const bool isStackOverflow = (dwExceptionCode == EXCEPTION_STACK_OVERFLOW); + struct StackOverflowScope + { + bool active; + explicit StackOverflowScope(bool enable) : active(enable) + { + if (active) + g_bCrashHandlerStackOverflow = true; + } + ~StackOverflowScope() + { + if (active) + g_bCrashHandlerStackOverflow = false; + } + } stackOverflowScope(isStackOverflow); + + // Special handling for release build-affecting assertions from 3rd-party libs (e.g CEF) that overuse them + if (IsDebuggerPresent() == FALSE && pExPtrs->ContextRecord != nullptr) + { + void* exceptionAddr = pExPtrs->ExceptionRecord->ExceptionAddress; + if (IsExceptionFromThirdParty(exceptionAddr)) + { + if (dwExceptionCode == EXCEPTION_BREAKPOINT || dwExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION) + { + // Don't advance EIP - for EXCEPTION_BREAKPOINT, EIP already points past INT 3 + // For EXCEPTION_ILLEGAL_INSTRUCTION with UD2, we just continue from current EIP + SafeDebugOutput("SEH: Assertion in 3rd-party library - continuing execution\n"); + return EXCEPTION_CONTINUE_EXECUTION; + } + } + } + + if (IsFatalException(dwExceptionCode) == FALSE) [[unlikely]] + { + // Non-fatal exceptions that are not from 3rd-party libraries + std::array szDebug{}; + SAFE_DEBUG_PRINT_C(szDebug.data(), szDebug.size(), "SEH: Non-fatal exception 0x%08X - ignoring\n", dwExceptionCode); + return EXCEPTION_CONTINUE_SEARCH; + } + + LONG lRet{EXCEPTION_CONTINUE_SEARCH}; + + static std::atomic bHandlerActive{false}; + bool expected{false}; + + if (!bHandlerActive.compare_exchange_strong(expected, true, std::memory_order_acq_rel, std::memory_order_relaxed)) + { + return EXCEPTION_CONTINUE_SEARCH; + } + + // Handle Stack Overflow Recovery FIRST + if (dwExceptionCode == EXCEPTION_STACK_OVERFLOW) + { + if (_resetstkoflw()) + { + SafeDebugOutput("SEH: Stack overflow detected - _resetstkoflw() successful\n"); + } + else + { + SafeDebugOutput("SEH: FATAL - Stack overflow detected - _resetstkoflw() failed\n"); + // If we can't reset the stack, we can't safely do anything else. + // Attempting to log or call handlers will likely trigger another overflow immediately. + return EXCEPTION_CONTINUE_SEARCH; + } + } + + SafeDebugOutput("SEH: CrashHandlerExceptionFilter - ENTRY\n"); + + SafeDebugOutput(DEBUG_SEPARATOR); + SafeDebugOutput("SEH: FATAL - Unhandled exception filter triggered\n"); + + // Only attempt enhanced logging if NOT a stack overflow, or if we are feeling lucky. + // Enhanced logging uses significant stack space. + if (dwExceptionCode != EXCEPTION_STACK_OVERFLOW) + { + if (SEHLogExceptionDetails(pExPtrs) == FALSE) [[unlikely]] + { + SafeDebugOutput("SEH: WARNING - Failed to log exception details\n"); + // Fallback to basic logging if enhanced failed + LogBasicExceptionInfo(pExPtrs); + } + } + else + { + SafeDebugOutput("SEH: Stack overflow - skipping enhanced logging to preserve stack\n"); + LogBasicExceptionInfo(pExPtrs); + SEHStoreBasicExceptionInfo(pExPtrs); + } + + if (STATUS_INVALID_CRUNTIME_PARAMETER_CODE == dwExceptionCode || STATUS_STACK_BUFFER_OVERRUN_CODE == dwExceptionCode) + { + SafeDebugOutput("SEH: FATAL - STACK BUFFER OVERRUN (STATUS_STACK_BUFFER_OVERRUN)\n"); + } + else if (STATUS_HEAP_CORRUPTION_CODE == dwExceptionCode) + { + SafeDebugOutput("SEH: FATAL - HEAP CORRUPTION (STATUS_HEAP_CORRUPTION)\n"); + } + else if (STATUS_FATAL_USER_CALLBACK_EXCEPTION == dwExceptionCode) + { + SafeDebugOutput("SEH: FATAL - Exception in Windows callback - attempting recovery\n"); + SafeDebugOutput("SEH: Note - Stack may be corrupted, context may be incomplete\n"); + } + + SafeDebugOutput(DEBUG_SEPARATOR); + + if (PFNCHFILTFN callback = g_pfnCrashCallback.load(std::memory_order_acquire); callback != nullptr) + { + lRet = TryCallCrashCallback(callback, pExPtrs); + } + + bHandlerActive.store(false, std::memory_order_release); + + return lRet; +} + +[[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall EnableSehExceptionHandler() +{ + return InstallSehHandler() ? TRUE : FALSE; +} + +[[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall SetInitializationPhase(DWORD phase) +{ + constexpr DWORD maxPhase = INIT_PHASE_POST_D3D; + if (phase > maxPhase) + { + SafeDebugOutput("CrashHandler: Invalid initialization phase\n"); + return FALSE; + } + + DWORD oldPhase = g_initializationPhase.exchange(phase, std::memory_order_seq_cst); + + std::array debugBuffer{}; + SAFE_DEBUG_PRINT(debugBuffer, "CrashHandler: Initialization phase changed from %u to %u\n", oldPhase, phase); + + return TRUE; +} + +[[nodiscard]] DWORD BUGSUTIL_DLLINTERFACE __stdcall GetInitializationPhase() +{ + return g_initializationPhase.load(std::memory_order_acquire); +} + +[[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall EnableAllHandlersAfterInitialization() +{ + if (const BOOL phaseResult = SetInitializationPhase(INIT_PHASE_POST_D3D); phaseResult == FALSE) + { + SafeDebugOutput("CrashHandler: WARNING - Failed to set initialization phase to post D3D\n"); + } + + bool allHandlersEnabled = true; + SafeDebugOutput("CrashHandler: Vectored exception handling not available - proceeding with SEH-only pipeline\n"); + + if (const BOOL sehResult = EnableSehExceptionHandler(); sehResult == FALSE) + { + SafeDebugOutput("CrashHandler: WARNING - Failed to enable SEH exception handler\n"); + allHandlersEnabled = false; + } + else + { + SafeDebugOutput("CrashHandler: SEH exception handler enabled successfully\n"); + } + + InstallCppHandlers(); + SafeDebugOutput("CrashHandler: C++ handlers installed after D3D initialization\n"); + + if (g_bStackCookieCaptureEnabled.load(std::memory_order_seq_cst)) + { + InstallAbortHandlers(); + SafeDebugOutput("CrashHandler: Abort handlers installed after D3D initialization\n"); + } + + SafeDebugOutput("CrashHandler: Phase 2 - All handlers enabled after D3D initialization\n"); + + return allHandlersEnabled ? TRUE : FALSE; +} + +// +// Watchdog Thread Implementation +// Detects MTA freezes and triggers crash dumps with stack traces to find what froze +// + +namespace +{ +#ifdef __cpp_lib_hardware_interference_size + using std::hardware_destructive_interference_size; +#else + inline constexpr std::size_t hardware_destructive_interference_size = 64; +#endif + + [[nodiscard]] constexpr bool IsHandleValid(HANDLE handle) + { + return handle != nullptr && handle != INVALID_HANDLE_VALUE; + } + + class HandleGuard + { + public: + HandleGuard() = default; + explicit HandleGuard(HANDLE handle) : m_handle(handle) {} + ~HandleGuard() { reset(); } + + HandleGuard(const HandleGuard&) = delete; + HandleGuard& operator=(const HandleGuard&) = delete; + + HandleGuard(HandleGuard&& other) : m_handle(other.release()) {} + HandleGuard& operator=(HandleGuard&& other) + { + if (this != &other) + { + reset(); + m_handle = other.release(); + } + return *this; + } + + void reset(HANDLE handle = nullptr) + { + if (IsHandleValid(m_handle)) + CloseHandle(m_handle); + m_handle = handle; + } + + [[nodiscard]] HANDLE get() const { return m_handle; } + [[nodiscard]] HANDLE release() + { + HANDLE handle = m_handle; + m_handle = nullptr; + return handle; + } + [[nodiscard]] explicit operator bool() const { return IsHandleValid(m_handle); } + + private: + HANDLE m_handle = nullptr; + }; + + struct WatchdogState + { + // Cache-line aligned atomics to prevent false sharing between cores + alignas(hardware_destructive_interference_size) std::atomic running{false}; + alignas(hardware_destructive_interference_size) std::atomic shouldStop{false}; + alignas(hardware_destructive_interference_size) std::atomic lastHeartbeat{std::chrono::steady_clock::now()}; + alignas(hardware_destructive_interference_size) std::atomic targetThreadId{0}; + alignas(hardware_destructive_interference_size) std::atomic timeoutSeconds{20}; + + // Non-atomic handle doesn't need cache-line alignment + HANDLE watchdogThreadHandle{nullptr}; + + ~WatchdogState() + { + // Note: watchdogThreadHandle should be closed by StopWatchdogThread, + // but we close it here as a safety measure in case of abnormal termination + if (watchdogThreadHandle != nullptr && watchdogThreadHandle != INVALID_HANDLE_VALUE) + { + CloseHandle(watchdogThreadHandle); + watchdogThreadHandle = nullptr; + } + } + }; + + static_assert(std::is_trivially_copyable_v, "time_point must be trivially copyable for use with std::atomic"); + static_assert(std::has_unique_object_representations_v, + "time_point must have unique object representations for atomic operations"); + + static_assert(std::atomic::is_always_lock_free, "bool atomics must be lock-free on this platform"); + static_assert(std::atomic::is_always_lock_free, "DWORD atomics must be lock-free on this platform"); + + // Validate timeout constraints at compile-time using std::conjunction + template + using valid_range = std::conjunction 0)>, std::bool_constant<(Max >= Min)> >; + + inline WatchdogState g_watchdogState{}; + + static bool TryGenerateWatchdogDump(EXCEPTION_POINTERS* pExPtrs, CExceptionInformation_Impl* pExInfo) + { + __try + { + CCrashDumpWriter::DumpCoreLog(pExPtrs, pExInfo); + CCrashDumpWriter::DumpMiniDump(pExPtrs, pExInfo); + return true; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + } + + [[nodiscard]] static bool TriggerWatchdogException(HANDLE targetThread, DWORD targetThreadId, bool dumpOnly = false) + { + AddReportLog(9300, SString("Watchdog freeze detected after %u seconds (thread %u)", g_watchdogState.timeoutSeconds.load(std::memory_order_relaxed), + targetThreadId)); + + // Suspend the thread once and capture everything while suspended + if (SuspendThread(targetThread) == static_cast(-1)) + { + AddReportLog(9301, SString("Watchdog failed to suspend thread %u", targetThreadId)); + return false; + } + + // Thread is now suspended - capture context + CONTEXT context{}; + context.ContextFlags = CONTEXT_FULL; + + if (GetThreadContext(targetThread, &context) == FALSE) + { + AddReportLog(9302, SString("Watchdog failed to capture thread context for %u", targetThreadId)); + + // Must resume thread before returning! + if (ResumeThread(targetThread) == static_cast(-1)) + { + AddReportLog(9303, SString("Watchdog failed to resume thread %u after context error", targetThreadId)); + } + return false; + } + + // Create exception record and pointers for stack walking (thread still suspended) + EXCEPTION_RECORD exceptionRecord{}; + exceptionRecord.ExceptionCode = CUSTOM_EXCEPTION_CODE_WATCHDOG_TIMEOUT; + exceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + exceptionRecord.ExceptionAddress = reinterpret_cast(static_cast(context.Eip)); + exceptionRecord.NumberParameters = 2; + exceptionRecord.ExceptionInformation[0] = targetThreadId; + exceptionRecord.ExceptionInformation[1] = g_watchdogState.timeoutSeconds.load(std::memory_order_relaxed); + + // Use static storage to keep exception pointers alive + static thread_local CONTEXT s_capturedContext{}; + s_capturedContext = context; + + EXCEPTION_POINTERS exceptionPointers{}; + exceptionPointers.ExceptionRecord = &exceptionRecord; + exceptionPointers.ContextRecord = &s_capturedContext; + + // Capture stack trace NOW while thread is still suspended - prevents race conditions + std::vector stackTraceVec{}; + const auto stackCaptured = CaptureUnifiedStackTrace(&exceptionPointers, 32, &stackTraceVec); + + // Now we can safely resume the thread - we have everything we need + if (ResumeThread(targetThread) == static_cast(-1)) + { + OutputDebugStringA("WATCHDOG: Failed to resume thread after stack capture\n"); + AddReportLog(9304, SString("Watchdog failed to resume thread %u after stack capture", targetThreadId)); + // Continue anyway - we still want the crash dump even if resume failed + } + + AddReportLog(9305, SString("Watchdog captured context for thread %u", targetThreadId)); + + // Store enhanced exception info + try + { + // Use try_lock to avoid deadlock if main thread was suspended while holding the mutex + if (std::unique_lock lock{g_exceptionInfoMutex, std::try_to_lock}; lock.owns_lock()) + { + // For cleaner initialization + g_lastExceptionInfo = [&]() + { + ENHANCED_EXCEPTION_INFO info{}; + info.exceptionCode = CUSTOM_EXCEPTION_CODE_WATCHDOG_TIMEOUT; + info.exceptionAddress = exceptionRecord.ExceptionAddress; + info.timestamp = std::chrono::system_clock::now(); + info.threadId = targetThreadId; + info.processId = GetCurrentProcessId(); + info.exceptionType = "Watchdog Timeout (Application Freeze)"; + info.isFatal = true; + + const auto timeoutSecs = g_watchdogState.timeoutSeconds.load(std::memory_order_relaxed); + info.additionalInfo = "Application became unresponsive for " + std::to_string(timeoutSecs) + " seconds"; + + info.eax = s_capturedContext.Eax; + info.ebx = s_capturedContext.Ebx; + info.ecx = s_capturedContext.Ecx; + info.edx = s_capturedContext.Edx; + info.esi = s_capturedContext.Esi; + info.edi = s_capturedContext.Edi; + info.ebp = s_capturedContext.Ebp; + info.esp = s_capturedContext.Esp; + info.eip = s_capturedContext.Eip; + info.cs = s_capturedContext.SegCs; + info.ds = s_capturedContext.SegDs; + info.ss = s_capturedContext.SegSs; + info.es = s_capturedContext.SegEs; + info.fs = s_capturedContext.SegFs; + info.gs = s_capturedContext.SegGs; + info.eflags = s_capturedContext.EFlags; + + // Use the stack trace we captured while thread was suspended + if (stackCaptured != FALSE && !stackTraceVec.empty()) + { + info.stackTrace = std::move(stackTraceVec); + info.hasDetailedStackTrace = true; + } + + return info; // Guaranteed copy - no move, no copy + }(); + } + else + { + AddReportLog(9306, "Watchdog skipped enhanced info capture (mutex busy)"); + } + } + catch (...) + { + // To detect exception-during-exception scenarios + if (std::uncaught_exceptions() > 1) + { + AddReportLog(9307, "Watchdog exception while storing enhanced info during stack unwinding"); + } + else + { + AddReportLog(9308, "Watchdog exception while storing enhanced info"); + } + } + + if (dumpOnly) + { + // Write dump without dialog or termination so the + // contributor can continue debugging after a breakpoint pause. + auto* pExInfo = new (std::nothrow) CExceptionInformation_Impl; + if (pExInfo) + { + pExInfo->Set(exceptionRecord.ExceptionCode, &exceptionPointers); + + if (!TryGenerateWatchdogDump(&exceptionPointers, pExInfo)) + { + AddReportLog(9316, "Watchdog: SEH exception caught during dump generation"); + } + + delete pExInfo; + } + return true; + } + + // Trigger the global exception handler + CCrashDumpWriter::HandleExceptionGlobal(&exceptionPointers); + + return true; + } + + [[nodiscard]] static unsigned int __stdcall WatchdogThreadProc(void* /*pParameter*/) + { + AddReportLog(9309, "Watchdog thread started"); + + constexpr auto kCheckInterval = std::chrono::milliseconds{500}; + static_assert(kCheckInterval.count() > 0, "Check interval must be positive"); + + const auto targetThreadId = g_watchdogState.targetThreadId.load(std::memory_order_acquire); + + // Open handle to target thread + constexpr DWORD kThreadAccess = THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION; + HandleGuard targetThread{OpenThread(kThreadAccess, FALSE, targetThreadId)}; + + if (!targetThread) + { + AddReportLog(9310, SString("Watchdog failed to open thread %lu (error %lu)", targetThreadId, GetLastError())); + + g_watchdogState.running.store(false, std::memory_order_release); + return 1; + } + + // Note: targetThread handle is local to this thread - no global state needed + + while (!g_watchdogState.shouldStop.load(std::memory_order_acquire)) + { + const auto now = std::chrono::steady_clock::now(); + const auto lastBeat = g_watchdogState.lastHeartbeat.load(std::memory_order_acquire); + const auto elapsed = std::chrono::duration_cast(now - lastBeat); + const auto timeoutSecs = g_watchdogState.timeoutSeconds.load(std::memory_order_relaxed); + + if (elapsed.count() >= static_cast(timeoutSecs)) + { +#ifdef MTA_DEBUG + BOOL isDebuggerAttached = FALSE; + if (IsDebuggerPresent() != FALSE) + isDebuggerAttached = TRUE; + + if (isDebuggerAttached == FALSE) + CheckRemoteDebuggerPresent(GetCurrentProcess(), &isDebuggerAttached); + + if (isDebuggerAttached == FALSE) + { + // Check if parent process (e.g. VS attached to the launcher) has a debugger + if (HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); hSnapshot != INVALID_HANDLE_VALUE) + { + PROCESSENTRY32 pe32{}; + pe32.dwSize = sizeof(pe32); + if (Process32First(hSnapshot, &pe32)) + { + const DWORD currentPid = GetCurrentProcessId(); + do + { + if (pe32.th32ProcessID == currentPid) + { + if (HANDLE hParent = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ParentProcessID)) + { + CheckRemoteDebuggerPresent(hParent, &isDebuggerAttached); + CloseHandle(hParent); + } + break; + } + } while (Process32Next(hSnapshot, &pe32)); + } + CloseHandle(hSnapshot); + } + } + + if (isDebuggerAttached != FALSE) + { + // In debug builds with a debugger attached, the stall may just be a breakpoint pause. + // Generate a dump so the frozen stack is collected, then + // reset the heartbeat and keep monitoring instead of terminating. + OutputDebugStringA("WATCHDOG: Freeze detected - generating dump (no termination)\n"); + + AddReportLog(9311, SString("Watchdog detected freeze after %lld seconds (threshold %u, debugger attached)", + static_cast(elapsed.count()), timeoutSecs)); + + TriggerWatchdogException(targetThread.get(), targetThreadId, true); + + g_watchdogState.lastHeartbeat.store(std::chrono::steady_clock::now(), std::memory_order_release); + std::this_thread::sleep_for(kCheckInterval); + continue; + } +#endif + AddReportLog(9311, SString("Watchdog detected freeze after %lld seconds (threshold %u)", static_cast(elapsed.count()), timeoutSecs)); + + const bool triggered = TriggerWatchdogException(targetThread.get(), targetThreadId); + if (!triggered) + { + AddReportLog(9312, SString("Watchdog trigger failed for thread %u", targetThreadId)); + } + + // Exit after triggering - crash dump handler will terminate process + break; + } + + std::this_thread::sleep_for(kCheckInterval); + } + + AddReportLog(9313, "Watchdog thread stopping"); + + g_watchdogState.running.store(false, std::memory_order_release); + + return 0; + } +} + +[[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall StartWatchdogThread(DWORD mainThreadId, DWORD timeoutSeconds) +{ + // Pprevent race conditions on double-start + auto expected = false; + if (!g_watchdogState.running.compare_exchange_strong(expected, true, std::memory_order_acq_rel)) + { + AddReportLog(9314, "Watchdog thread already running"); + return FALSE; + } + + constexpr auto kMinTimeout = DWORD{5}; + constexpr auto kMaxTimeout = DWORD{300}; + static_assert(kMinTimeout > 0, "Minimum timeout must be positive"); + static_assert(kMaxTimeout >= kMinTimeout, "Maximum timeout must be >= minimum"); + + if (timeoutSeconds < kMinTimeout || timeoutSeconds > kMaxTimeout) + { + AddReportLog(9315, SString("Watchdog invalid timeout %u (allowed %u-%u)", timeoutSeconds, kMinTimeout, kMaxTimeout)); + + g_watchdogState.running.store(false, std::memory_order_release); + return FALSE; + } + + g_watchdogState.targetThreadId.store(mainThreadId, std::memory_order_release); + g_watchdogState.timeoutSeconds.store(timeoutSeconds, std::memory_order_release); + g_watchdogState.shouldStop.store(false, std::memory_order_release); + g_watchdogState.lastHeartbeat.store(std::chrono::steady_clock::now(), std::memory_order_release); + + constexpr unsigned int kStackSize = 0; + const auto threadHandle{reinterpret_cast(_beginthreadex(nullptr, kStackSize, WatchdogThreadProc, nullptr, 0, nullptr))}; + + HandleGuard watchdogHandle{threadHandle}; + + if (!watchdogHandle) + { + AddReportLog(9316, SString("Watchdog failed to create thread (error %u)", GetLastError())); + + g_watchdogState.running.store(false, std::memory_order_release); + return FALSE; + } + + g_watchdogState.watchdogThreadHandle = watchdogHandle.release(); + + AddReportLog(9317, SString("Watchdog monitoring thread %u with %u second timeout", mainThreadId, timeoutSeconds)); + + return TRUE; +} + +void BUGSUTIL_DLLINTERFACE __stdcall StopWatchdogThread() +{ + if (!g_watchdogState.running.load(std::memory_order_acquire)) + { + return; + } + + AddReportLog(9318, "Stopping watchdog thread"); + g_watchdogState.shouldStop.store(true, std::memory_order_release); + + if (g_watchdogState.watchdogThreadHandle != nullptr && g_watchdogState.watchdogThreadHandle != INVALID_HANDLE_VALUE) + { + constexpr DWORD kWaitTimeout = 5000; + if (const auto waitResult = WaitForSingleObject(g_watchdogState.watchdogThreadHandle, kWaitTimeout); waitResult != WAIT_OBJECT_0) + { + AddReportLog(9319, "Watchdog thread forced termination"); + TerminateThread(g_watchdogState.watchdogThreadHandle, 1); + WaitForSingleObject(g_watchdogState.watchdogThreadHandle, INFINITE); + } + + CloseHandle(g_watchdogState.watchdogThreadHandle); + g_watchdogState.watchdogThreadHandle = nullptr; + } + + AddReportLog(9320, "Watchdog thread stopped"); +} + +void BUGSUTIL_DLLINTERFACE __stdcall UpdateWatchdogHeartbeat() +{ + if (g_watchdogState.running.load(std::memory_order_acquire)) { - lRet = EXCEPTION_CONTINUE_SEARCH; + g_watchdogState.lastHeartbeat.store(std::chrono::steady_clock::now(), std::memory_order_release); } - return (lRet); } diff --git a/Client/core/CrashHandler.h b/Client/core/CrashHandler.h index 6738240012a..3c19a1ddf62 100644 --- a/Client/core/CrashHandler.h +++ b/Client/core/CrashHandler.h @@ -5,57 +5,277 @@ * FILE: core/CrashHandler.h * PURPOSE: Header file for crash handling functions * - * THIS FILE IS PROPERTY OF - * "Debugging Applications" (Microsoft Press) - * Copyright (c) 1997-2000 John Robbins -- All rights reserved. + * THIS FILE CREDITS (IS BASED ON): "Debugging Applications" (Microsoft Press) by John Robbins + * Copyright (c) 1997-2000 John Robbins -- All rights reserved * * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ -/*---------------------------------------------------------------------- -"Debugging Applications" (Microsoft Press) -Copyright (c) 1997-2000 John Robbins -- All rights reserved. -----------------------------------------------------------------------*/ - #pragma once #define WIN32_LEAN_AND_MEAN #include -#define BUGSUTIL_DLLINTERFACE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class SString; + +#if !defined(BUGSUTIL_DLLINTERFACE) + #if defined(BUGSUTIL_EXPORTS) + #define BUGSUTIL_DLLINTERFACE __declspec(dllexport) + #else + #define BUGSUTIL_DLLINTERFACE + #endif +#endif + +constexpr std::size_t DEBUG_BUFFER_SIZE = 256; +static_assert(DEBUG_BUFFER_SIZE > 1, "DEBUG_BUFFER_SIZE must allow for null termination"); + +constexpr DWORD CPP_EXCEPTION_CODE = 0xE06D7363; +constexpr DWORD STATUS_INVALID_CRUNTIME_PARAMETER_CODE = 0xC0000417; +constexpr DWORD STATUS_STACK_BUFFER_OVERRUN_CODE = 0xC0000409; +constexpr DWORD STATUS_HEAP_CORRUPTION_CODE = 0xC0000374; +// STATUS_FATAL_USER_CALLBACK_EXCEPTION (0xC000041D): +// This exception type occurs when an exception happens inside a Windows system callback +// (e.g., window procedures, DLL callbacks, kernel-to-user transitions) and cannot be +// properly unwound. Special handling is required as: +// - The stack may be corrupted or incomplete +// - Context may not have full information +// - Stack walking may fail or cause secondary exceptions +// - Module resolution may point to trampolines instead of actual code +constexpr DWORD STATUS_FATAL_USER_CALLBACK_EXCEPTION = 0xC000041D; +constexpr DWORD CUSTOM_EXCEPTION_CODE_WATCHDOG_TIMEOUT = 0xE0000001; + +constexpr DWORD INIT_PHASE_MINIMAL = 0; +constexpr DWORD INIT_PHASE_D3D_INIT = 1; +constexpr DWORD INIT_PHASE_POST_D3D = 2; + +constexpr int EXIT_CODE_CRASH = 3; + +constexpr std::size_t DEBUG_BUFFER_SIZE_LARGE = 512; + +constexpr DWORD EXCEPTION_BREAKPOINT_NONFATAL = 0x80000003; +constexpr DWORD EXCEPTION_SINGLE_STEP_NONFATAL = 0x80000004; +constexpr DWORD EXCEPTION_GUARD_PAGE_NONFATAL = 0x80000001; +constexpr DWORD EXCEPTION_INVALID_HANDLE_NONFATAL = 0xC0000008; +constexpr DWORD EXCEPTION_ARRAY_BOUNDS_EXCEEDED_NONFATAL = 0xC000008C; +constexpr DWORD EXCEPTION_FLT_DENORMAL_OPERAND_NONFATAL = 0xC000008D; +constexpr DWORD EXCEPTION_FLT_DIVIDE_BY_ZERO_NONFATAL = 0xC000008E; +constexpr DWORD EXCEPTION_FLT_INEXACT_RESULT_NONFATAL = 0xC000008F; +constexpr DWORD EXCEPTION_FLT_INVALID_OPERATION_NONFATAL = 0xC0000090; +constexpr DWORD EXCEPTION_FLT_OVERFLOW_NONFATAL = 0xC0000091; +constexpr DWORD EXCEPTION_FLT_STACK_CHECK_NONFATAL = 0xC0000092; +constexpr DWORD EXCEPTION_FLT_UNDERFLOW_NONFATAL = 0xC0000093; +constexpr DWORD EXCEPTION_INT_DIVIDE_BY_ZERO_NONFATAL = 0xC0000094; +constexpr DWORD EXCEPTION_INT_OVERFLOW_NONFATAL = 0xC0000095; +constexpr DWORD EXCEPTION_PRIV_INSTRUCTION_NONFATAL = 0xC0000096; +constexpr DWORD EXCEPTION_NONCONTINUABLE_EXCEPTION_NONFATAL = 0xC0000025; + +inline constexpr std::string_view DEBUG_PREFIX_CRASH = "CrashHandler: "; +inline constexpr std::string_view DEBUG_PREFIX_SEH = "SEH: "; +inline constexpr std::string_view DEBUG_PREFIX_CPP = "C++ TERMINATE: "; +inline constexpr std::string_view DEBUG_PREFIX_ABORT = "ABORT: "; +inline constexpr std::string_view DEBUG_PREFIX_PURECALL = "PURECALL: "; +inline constexpr std::string_view DEBUG_PREFIX_EXCEPTION_INFO = "ExceptionInfo: "; +inline constexpr std::string_view DEBUG_PREFIX_WATCHDOG = "WATCHDOG: "; +inline constexpr std::string_view DEBUG_SEPARATOR = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"; +// Helpers implemented in CrashHandler.cpp to avoid __try in inline functions +void OutputDebugStringSafeImpl(const char* message); +void SafeDebugPrintImpl(char* buffer, std::size_t bufferSize, const char* format, va_list args); +void SafeDebugPrintPrefixedImpl(const char* prefix, std::size_t prefixLen, const char* format, va_list args); +extern thread_local bool g_bCrashHandlerStackOverflow; + +// Helper to safely call OutputDebugStringA with SEH guards +inline void OutputDebugStringSafe(const char* message) +{ + if (g_bCrashHandlerStackOverflow) + return; + OutputDebugStringSafeImpl(message); +} +inline void SafeDebugOutput(std::string_view message) +{ + if (g_bCrashHandlerStackOverflow) + return; + const char* data = message.data(); + std::size_t remaining = message.size(); + + if (data == nullptr || remaining == 0) + { + return; + } + + char buffer[DEBUG_BUFFER_SIZE] = {}; + + while (remaining > 0) + { + const std::size_t chunkLength = std::min(remaining, DEBUG_BUFFER_SIZE - 1); + std::memcpy(buffer, data, chunkLength); + buffer[chunkLength] = '\0'; + OutputDebugStringSafeImpl(buffer); + + data += chunkLength; + remaining -= chunkLength; + } +} + +// Overload for C-string literals (backward compatibility) +inline void SafeDebugOutput(const char* message) +{ + if (g_bCrashHandlerStackOverflow) + return; + OutputDebugStringSafeImpl(message); +} + +// Overload for std::string (for string_view concatenation) +inline void SafeDebugOutput(const std::string& message) +{ + if (g_bCrashHandlerStackOverflow) + return; + if (!message.empty()) + { + OutputDebugStringSafeImpl(message.c_str()); + } +} + +template +inline void SafeDebugPrint(Buffer& buffer, const char* format, ...) +{ + if (format == nullptr) + return; + + auto* data = buffer.data(); + const std::size_t size = buffer.size(); + + if (data == nullptr || size == 0) + return; + + va_list args; + va_start(args, format); + SafeDebugPrintImpl(data, size, format, args); + va_end(args); +} + +inline void SafeDebugPrintC(char* buffer, std::size_t bufferSize, const char* format, ...) +{ + if (buffer == nullptr || bufferSize == 0 || format == nullptr) + return; + + va_list args; + va_start(args, format); + SafeDebugPrintImpl(buffer, bufferSize, format, args); + va_end(args); +} + +#define SAFE_DEBUG_PRINT(buffer, ...) SafeDebugPrint((buffer), __VA_ARGS__) +#define SAFE_DEBUG_PRINT_C(buffer, bufferSize, ...) SafeDebugPrintC((buffer), (bufferSize), __VA_ARGS__) + +inline void SafeDebugPrintPrefixed(std::string_view prefix, const char* format, ...) +{ + if (format == nullptr) + return; + + va_list args; + va_start(args, format); + SafeDebugPrintPrefixedImpl(prefix.data(), prefix.size(), format, args); + va_end(args); +} #ifdef __cplusplus + +using PFNCHFILTFN = LONG(__stdcall*)(EXCEPTION_POINTERS* pExPtrs); + +struct ENHANCED_EXCEPTION_INFO +{ + DWORD exceptionCode{}; + void* exceptionAddress{}; + std::string moduleName{}; + std::string modulePathName{}; + std::string moduleBaseName{}; + uint moduleOffset{}; + std::chrono::system_clock::time_point timestamp{}; + DWORD threadId{}; + DWORD processId{}; + std::optional> stackTrace{}; + std::optional capturedException{}; + int uncaughtExceptionCount{}; + std::string exceptionDescription{}; + bool hasDetailedStackTrace{}; + + DWORD eax{}, ebx{}, ecx{}, edx{}, esi{}, edi{}, ebp{}, esp{}, eip{}, eflags{}; + WORD cs{}, ds{}, ss{}, es{}, fs{}, gs{}; + + std::string exceptionType{}; + bool isFatal{}; + std::string additionalInfo{}; + + [[nodiscard]] auto operator<=>(const ENHANCED_EXCEPTION_INFO&) const = default; +}; +using PENHANCED_EXCEPTION_INFO = ENHANCED_EXCEPTION_INFO*; + extern "C" { -#endif //__cplusplus - - /*////////////////////////////////////////////////////////////////////// - Type Definitions - //////////////////////////////////////////////////////////////////////*/ - // The type for the filter function called by the Crash Handler API. - typedef LONG(__stdcall* PFNCHFILTFN)(EXCEPTION_POINTERS* pExPtrs); - - /*////////////////////////////////////////////////////////////////////// - Crash Handler Function Definitions - //////////////////////////////////////////////////////////////////////*/ - - /*---------------------------------------------------------------------- - FUNCTION : SetCrashHandlerFilter - DISCUSSION : - Sets the filter function that will be called when there is a fatal - crash. The passed in function will only be called if the crash is one - of the modules passed to AddCrashHandlerLimitModule. If no modules have - been added to narrow down the interested modules then the callback - filter function will always be called. - PARAMETERS : - pFn - A valid code pointer. If this is NULL, then the Crash Handler - filter function is removed. - RETURNS : - 1 - The crash handler was properly set. - 0 - There was a problem. - ----------------------------------------------------------------------*/ - BOOL BUGSUTIL_DLLINTERFACE __stdcall SetCrashHandlerFilter(PFNCHFILTFN pFn); +#endif + + [[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall SetCrashHandlerFilter(PFNCHFILTFN pFn); + + [[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall EnableStackCookieFailureCapture(BOOL bEnable); + + [[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall ConfigureWerForFailFast(); + + [[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall GetEnhancedExceptionInfo(PENHANCED_EXCEPTION_INFO pExceptionInfo); + + [[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall CaptureCurrentException(); + + [[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall LogExceptionDetails(EXCEPTION_POINTERS* pException); + + [[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall IsFatalException(DWORD exceptionCode); + + typedef struct _CRASH_HANDLER_CONFIG + { + BOOL disableSehDetour; + BOOL forceSehDetour; + BOOL enableStackCookieCapture; + BOOL enableEnhancedLogging; + BOOL enableSehHandler; + BOOL enableCppHandlers; + DWORD memoryReservationKB; + DWORD maxStackTraceFrames; + DWORD debugBufferSize; + } CRASH_HANDLER_CONFIG, *PCRASH_HANDLER_CONFIG; + + [[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall GetCrashHandlerConfiguration(PCRASH_HANDLER_CONFIG pConfig); + + [[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall CaptureUnifiedStackTrace(_EXCEPTION_POINTERS* pException, DWORD maxFrames, + std::vector* pOutTrace); + + [[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall EnableSehExceptionHandler(); + + [[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall SetInitializationPhase(DWORD phase); + + [[nodiscard]] DWORD BUGSUTIL_DLLINTERFACE __stdcall GetInitializationPhase(); + + [[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall EnableAllHandlersAfterInitialization(); + + [[nodiscard]] BOOL BUGSUTIL_DLLINTERFACE __stdcall StartWatchdogThread(DWORD mainThreadId, DWORD timeoutSeconds = 20); + + void BUGSUTIL_DLLINTERFACE __stdcall StopWatchdogThread(); + + void BUGSUTIL_DLLINTERFACE __stdcall UpdateWatchdogHeartbeat(); #ifdef __cplusplus } -#endif //__cplusplus +#endif + +namespace CrashHandler +{ + [[nodiscard]] bool ProcessHasLocalDebugSymbols(); +} diff --git a/Client/core/DXHook/CDirect3DData.cpp b/Client/core/DXHook/CDirect3DData.cpp index 08dd50d39ff..45c606eba0e 100644 --- a/Client/core/DXHook/CDirect3DData.cpp +++ b/Client/core/DXHook/CDirect3DData.cpp @@ -17,17 +17,8 @@ template <> CDirect3DData* CSingleton::m_pSingleton = NULL; CDirect3DData::CDirect3DData() + : m_mViewMatrix{}, m_mProjMatrix{}, m_mWorldMatrix{}, m_hDeviceWindow(0), m_dwViewportX(0), m_dwViewportY(0), m_dwViewportWidth(0), m_dwViewportHeight(0) { - // Zero out our matricies. - memset(&m_mViewMatrix, 0, sizeof(D3DMATRIX)); - memset(&m_mProjMatrix, 0, sizeof(D3DMATRIX)); - memset(&m_mWorldMatrix, 0, sizeof(D3DMATRIX)); - - m_hDeviceWindow = 0; - m_dwViewportX = 0; - m_dwViewportY = 0; - m_dwViewportWidth = 0; - m_dwViewportHeight = 0; } CDirect3DData::~CDirect3DData() @@ -36,49 +27,68 @@ CDirect3DData::~CDirect3DData() void CDirect3DData::StoreTransform(D3DTRANSFORMSTATETYPE dwMatrixToStore, const D3DMATRIX* pMatrix) { + if (!pMatrix) + return; + + // Only copy matrix if it has changed (avoid 64-byte copy) switch (dwMatrixToStore) { case D3DTS_VIEW: - // Copy the real view matrix. - memcpy(&m_mViewMatrix, pMatrix, sizeof(D3DMATRIX)); + if (memcmp(&m_mViewMatrix, pMatrix, sizeof(D3DMATRIX)) != 0) + m_mViewMatrix = *pMatrix; break; case D3DTS_PROJECTION: - // Copy the real projection marix. - memcpy(&m_mProjMatrix, pMatrix, sizeof(D3DMATRIX)); + if (memcmp(&m_mProjMatrix, pMatrix, sizeof(D3DMATRIX)) != 0) + m_mProjMatrix = *pMatrix; break; case D3DTS_WORLD: - // Copy the real world matrix. - memcpy(&m_mWorldMatrix, pMatrix, sizeof(D3DMATRIX)); + if (memcmp(&m_mWorldMatrix, pMatrix, sizeof(D3DMATRIX)) != 0) + m_mWorldMatrix = *pMatrix; break; default: - // Do nothing. + // Do nothing for unsupported transforms break; } } void CDirect3DData::GetTransform(D3DTRANSFORMSTATETYPE dwRequestedMatrix, D3DMATRIX* pMatrixOut) { + if (!pMatrixOut) + return; + + // Use direct assignment instead of memcpy for better performance switch (dwRequestedMatrix) { case D3DTS_VIEW: - // Copy the stored view matrix. - memcpy(pMatrixOut, &m_mViewMatrix, sizeof(D3DMATRIX)); + *pMatrixOut = m_mViewMatrix; break; case D3DTS_PROJECTION: - // Copy the stored projection matrix. - memcpy(pMatrixOut, &m_mProjMatrix, sizeof(D3DMATRIX)); + *pMatrixOut = m_mProjMatrix; break; case D3DTS_WORLD: - // Copy the stored world matrix. - memcpy(pMatrixOut, &m_mWorldMatrix, sizeof(D3DMATRIX)); + *pMatrixOut = m_mWorldMatrix; break; default: - // Zero out the structure for the user. - memset(pMatrixOut, 0, sizeof(D3DMATRIX)); + // Zero out for unsupported transforms + *pMatrixOut = {}; break; } +} - // assert ( 0 ); // Too expensive to be used because SetTransform is used too often +const D3DMATRIX* CDirect3DData::GetTransformPtr(D3DTRANSFORMSTATETYPE dwRequestedMatrix) const +{ + // Return direct pointer to cached matrix - avoids copy overhead + switch (dwRequestedMatrix) + { + case D3DTS_VIEW: + return &m_mViewMatrix; + case D3DTS_PROJECTION: + return &m_mProjMatrix; + case D3DTS_WORLD: + return &m_mWorldMatrix; + default: + return nullptr; + } } void CDirect3DData::StoreViewport(DWORD dwX, DWORD dwY, DWORD dwWidth, DWORD dwHeight) @@ -88,23 +98,3 @@ void CDirect3DData::StoreViewport(DWORD dwX, DWORD dwY, DWORD dwWidth, DWORD dwH m_dwViewportWidth = dwWidth; m_dwViewportHeight = dwHeight; } - -DWORD CDirect3DData::GetViewportX() -{ - return m_dwViewportX; -} - -DWORD CDirect3DData::GetViewportY() -{ - return m_dwViewportY; -} - -DWORD CDirect3DData::GetViewportWidth() -{ - return m_dwViewportWidth; -} - -DWORD CDirect3DData::GetViewportHeight() -{ - return m_dwViewportHeight; -} diff --git a/Client/core/DXHook/CDirect3DData.h b/Client/core/DXHook/CDirect3DData.h index 5e70a577b83..5beababf5fe 100644 --- a/Client/core/DXHook/CDirect3DData.h +++ b/Client/core/DXHook/CDirect3DData.h @@ -20,18 +20,19 @@ class CDirect3DData : public CSingleton CDirect3DData(); ~CDirect3DData(); - void StoreTransform(D3DTRANSFORMSTATETYPE dwMatrixToStore, const D3DMATRIX* pMatrix); - void GetTransform(D3DTRANSFORMSTATETYPE dwRequestedMatrix, D3DMATRIX* pMatrixOut); + void StoreTransform(D3DTRANSFORMSTATETYPE dwMatrixToStore, const D3DMATRIX* pMatrix); + void GetTransform(D3DTRANSFORMSTATETYPE dwRequestedMatrix, D3DMATRIX* pMatrixOut); + const D3DMATRIX* GetTransformPtr(D3DTRANSFORMSTATETYPE dwRequestedMatrix) const; HWND GetDeviceWindow() { return m_hDeviceWindow; }; void StoreDeviceWindow(HWND hDeviceWindow) { m_hDeviceWindow = hDeviceWindow; }; void StoreViewport(DWORD dwX, DWORD dwY, DWORD dwWidth, DWORD dwHeight); - DWORD GetViewportX(); - DWORD GetViewportY(); - DWORD GetViewportWidth(); - DWORD GetViewportHeight(); + DWORD GetViewportX() { return m_dwViewportX; } + DWORD GetViewportY() { return m_dwViewportY; } + DWORD GetViewportWidth() { return m_dwViewportWidth; } + DWORD GetViewportHeight() { return m_dwViewportHeight; } private: D3DMATRIX m_mViewMatrix; diff --git a/Client/core/DXHook/CDirect3DEvents9.cpp b/Client/core/DXHook/CDirect3DEvents9.cpp index 9406cfcefb5..41ec7a9f81d 100644 --- a/Client/core/DXHook/CDirect3DEvents9.cpp +++ b/Client/core/DXHook/CDirect3DEvents9.cpp @@ -10,30 +10,460 @@ *****************************************************************************/ #include "StdInc.h" +#include #include #define DECLARE_PROFILER_SECTION_CDirect3DEvents9 #include "profiler/SharedUtil.Profiler.h" #include "CProxyDirect3DVertexBuffer.h" #include "CProxyDirect3DIndexBuffer.h" #include "CProxyDirect3DTexture.h" +#include "CProxyDirect3DDevice9.h" #include "CAdditionalVertexStreamManager.h" #include "CVertexStreamBoundingBoxManager.h" #include "CProxyDirect3DVertexDeclaration.h" +#include "Graphics/CVideoModeManager.h" #include "Graphics/CRenderItem.EffectTemplate.h" -bool g_bInMTAScene = false; +std::atomic g_bInMTAScene{false}; +extern std::atomic g_bInGTAScene; +extern CProxyDirect3DDevice9* g_pProxyDevice; +void ResetGTASceneState(); // Other variables static uint ms_RequiredAnisotropicLevel = 1; static EDiagnosticDebugType ms_DiagnosticDebug = EDiagnosticDebug::NONE; +// Tracks frames since the last hardware fault caught by FilterException. +// Draw calls are skipped for a short cooldown to avoid repeated exceptions, +// then re-enabled as PresentGuarded increments this counter each frame. +// UINT_MAX = normal (no active fault) +// 0..N = frames elapsed since fault +static uint ms_uiFramesSinceDeviceFault = UINT_MAX; + // To reuse shader setups between calls to DrawIndexedPrimitive CShaderItem* g_pActiveShader = NULL; +namespace +{ + struct SResolvedShaderState + { + CShaderInstance* pInstance = nullptr; + CEffectWrap* pEffectWrap = nullptr; + ID3DXEffect* pEffect = nullptr; + }; + + bool TryResolveShaderState(CShaderItem* pShaderItem, SResolvedShaderState& outState) + { + if (!pShaderItem) + return false; + + CShaderInstance* pInstance = pShaderItem->m_pShaderInstance; + if (!pInstance) + return false; + + CEffectWrap* pEffectWrap = pInstance->m_pEffectWrap; + if (!pEffectWrap) + return false; + + outState.pInstance = pInstance; + outState.pEffectWrap = pEffectWrap; + outState.pEffect = pEffectWrap->m_pD3DEffect; + return true; + } +} + +namespace +{ + struct SToneMapVertex + { + static const DWORD FVF = D3DFVF_XYZRHW | D3DFVF_TEX1; + float x, y, z, w; + float u, v; + }; + + class BorderlessToneMapPass + { + public: + bool Apply(IDirect3DDevice9* device, float gammaPower, float brightnessScale, float contrastScale, float saturationScale); + void Release(); + + private: + bool EnsureResources(IDirect3DDevice9* device, UINT width, UINT height, D3DFORMAT format); + bool EnsureShader(IDirect3DDevice9* device); + bool EnsureStateBlock(IDirect3DDevice9* device); + void ReleaseTexture(); + void ReleaseShader(); + void ReleaseStateBlock(); + + IDirect3DTexture9* m_sourceTexture = nullptr; + IDirect3DSurface9* m_sourceSurface = nullptr; + IDirect3DPixelShader9* m_pixelShader = nullptr; + LPD3DXCONSTANTTABLE m_constantTable = nullptr; + D3DXHANDLE m_toneParamsHandle = nullptr; + IDirect3DStateBlock9* m_restoreStateBlock = nullptr; + IDirect3DStateBlock9* m_applyStateBlock = nullptr; + UINT m_width = 0; + UINT m_height = 0; + D3DFORMAT m_format = D3DFMT_UNKNOWN; + bool m_shaderFailed = false; + }; + + static BorderlessToneMapPass g_BorderlessToneMapPass; + + static void RunBorderlessToneMap(IDirect3DDevice9* device) + { + if (!device) + return; + + bool isWindowed = false; + bool havePresentationState = false; + if (CVideoModeManagerInterface* videoModeManager = GetVideoModeManager()) + { + isWindowed = videoModeManager->IsDisplayModeWindowed() || videoModeManager->IsDisplayModeFullScreenWindow(); + havePresentationState = true; + } + + if (!havePresentationState && g_pDeviceState) + { + const auto& params = g_pDeviceState->CreationState.PresentationParameters; + isWindowed = params.Windowed != 0; + havePresentationState = true; + } + + if (!havePresentationState) + return; + + float gammaPower = 1.0f; + float brightnessScale = 1.0f; + float contrastScale = 1.0f; + float saturationScale = 1.0f; + bool applyWindowed = true; + bool applyFullscreen = false; + BorderlessGamma::FetchSettings(gammaPower, brightnessScale, contrastScale, saturationScale, applyWindowed, applyFullscreen); + + const bool adjustmentsEnabled = isWindowed ? applyWindowed : applyFullscreen; + if (!adjustmentsEnabled) + { + g_BorderlessToneMapPass.Release(); + return; + } + + if (!BorderlessGamma::ShouldApplyAdjustments(gammaPower, brightnessScale, contrastScale, saturationScale)) + return; + + if (!g_BorderlessToneMapPass.Apply(device, gammaPower, brightnessScale, contrastScale, saturationScale)) + { + // Fallback: release resources to allow retry on future frames. + g_BorderlessToneMapPass.Release(); + } + } +} // namespace + +bool BorderlessToneMapPass::EnsureShader(IDirect3DDevice9* device) +{ + if (m_pixelShader) + return true; + + if (m_shaderFailed) + return false; + + static const char kShaderSource[] = + "sampler2D SourceSampler : register(s0);\n" + "float4 ToneParams;\n" + "float4 main(float2 uv : TEXCOORD0) : COLOR0\n" + "{\n" + " float4 color = tex2D(SourceSampler, uv);\n" + " float3 colorLinear = saturate(color.rgb);\n" + " float3 gammaAdjusted = pow(colorLinear, ToneParams.xxx);\n" + " float3 brightnessAdjusted = gammaAdjusted * ToneParams.y;\n" + " float3 pivot = float3(0.5f, 0.5f, 0.5f);\n" + " float3 contrasted = (brightnessAdjusted - pivot) * ToneParams.z + pivot;\n" + " float luminance = dot(contrasted, float3(0.299f, 0.587f, 0.114f));\n" + " float3 saturated = lerp(float3(luminance, luminance, luminance), contrasted, ToneParams.w);\n" + " color.rgb = saturate(saturated);\n" + " return color;\n" + "}\n"; + + LPD3DXBUFFER shaderBuffer = nullptr; + LPD3DXBUFFER errorBuffer = nullptr; + LPD3DXCONSTANTTABLE constantTable = nullptr; + + HRESULT hr = + D3DXCompileShader(kShaderSource, sizeof(kShaderSource) - 1, nullptr, nullptr, "main", "ps_2_0", 0, &shaderBuffer, &errorBuffer, &constantTable); + if (FAILED(hr)) + { + SString message("BorderlessToneMap: pixel shader compile failed (%08x)", hr); + if (errorBuffer && errorBuffer->GetBufferPointer()) + message += SString(" - %s", static_cast(errorBuffer->GetBufferPointer())); + WriteDebugEvent(message); + SAFE_RELEASE(shaderBuffer); + SAFE_RELEASE(errorBuffer); + SAFE_RELEASE(constantTable); + m_shaderFailed = true; + return false; + } + + hr = device->CreatePixelShader(reinterpret_cast(shaderBuffer->GetBufferPointer()), &m_pixelShader); + SAFE_RELEASE(shaderBuffer); + SAFE_RELEASE(errorBuffer); + if (FAILED(hr)) + { + WriteDebugEvent(SString("BorderlessToneMap: CreatePixelShader failed (%08x)", hr)); + SAFE_RELEASE(constantTable); + m_shaderFailed = true; + return false; + } + + m_constantTable = constantTable; + m_toneParamsHandle = m_constantTable ? m_constantTable->GetConstantByName(nullptr, "ToneParams") : nullptr; + m_shaderFailed = false; + return true; +} + +bool BorderlessToneMapPass::EnsureStateBlock(IDirect3DDevice9* device) +{ + if (!device) + return false; + + if (m_restoreStateBlock && m_applyStateBlock) + return true; + + // Create restore state block (captures current state for restoration) + if (!m_restoreStateBlock) + { + IDirect3DStateBlock9* restoreBlock = nullptr; + if (FAILED(device->CreateStateBlock(D3DSBT_ALL, &restoreBlock)) || !restoreBlock) + return false; + + if (FAILED(restoreBlock->Capture())) + { + restoreBlock->Release(); + return false; + } + m_restoreStateBlock = restoreBlock; + } + + // Create apply state block (captures our desired rendering state) + if (!m_applyStateBlock) + { + device->BeginStateBlock(); + + // Configure all render states for tone mapping pass + device->SetRenderState(D3DRS_ZENABLE, FALSE); + device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + device->SetRenderState(D3DRS_FOGENABLE, FALSE); + device->SetRenderState(D3DRS_STENCILENABLE, FALSE); + device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); + + device->SetPixelShader(m_pixelShader); + device->SetVertexShader(nullptr); + device->SetFVF(SToneMapVertex::FVF); + + device->SetTexture(0, m_sourceTexture); + device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE); + + IDirect3DStateBlock9* applyBlock = nullptr; + if (FAILED(device->EndStateBlock(&applyBlock)) || !applyBlock) + { + return false; + } + m_applyStateBlock = applyBlock; + } + + return true; +} + +bool BorderlessToneMapPass::EnsureResources(IDirect3DDevice9* device, UINT width, UINT height, D3DFORMAT format) +{ + if (!device) + return false; + + if (m_sourceTexture && (m_width != width || m_height != height || m_format != format)) + ReleaseTexture(); + + if (!m_sourceTexture) + { + HRESULT hr = device->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &m_sourceTexture, nullptr); + if (FAILED(hr)) + { + WriteDebugEvent(SString("BorderlessToneMap: CreateTexture failed (%08x)", hr)); + return false; + } + + hr = m_sourceTexture->GetSurfaceLevel(0, &m_sourceSurface); + if (FAILED(hr)) + { + WriteDebugEvent(SString("BorderlessToneMap: GetSurfaceLevel failed (%08x)", hr)); + ReleaseTexture(); + return false; + } + + m_width = width; + m_height = height; + m_format = format; + } + + return m_sourceTexture && m_sourceSurface; +} + +bool BorderlessToneMapPass::Apply(IDirect3DDevice9* device, float gammaPower, float brightnessScale, float contrastScale, float saturationScale) +{ + if (!device) + return false; + + if (!EnsureShader(device)) + return false; + + IDirect3DSurface9* backBuffer = nullptr; + HRESULT hr = device->GetRenderTarget(0, &backBuffer); + if (FAILED(hr) || !backBuffer) + return false; + + D3DSURFACE_DESC backBufferDesc; + backBuffer->GetDesc(&backBufferDesc); + + if (!EnsureResources(device, backBufferDesc.Width, backBufferDesc.Height, backBufferDesc.Format)) + { + SAFE_RELEASE(backBuffer); + return false; + } + + hr = device->StretchRect(backBuffer, nullptr, m_sourceSurface, nullptr, D3DTEXF_POINT); + if (FAILED(hr)) + { + WriteDebugEvent(SString("BorderlessToneMap: StretchRect failed (%08x)", hr)); + SAFE_RELEASE(backBuffer); + return false; + } + + if (!EnsureStateBlock(device)) + { + SAFE_RELEASE(backBuffer); + return false; + } + + m_restoreStateBlock->Capture(); + + // Apply all rendering state in one call using cached state block + m_applyStateBlock->Apply(); + + if (m_constantTable && m_toneParamsHandle) + { + const float toneParams[4] = {gammaPower, brightnessScale, contrastScale, saturationScale}; + m_constantTable->SetFloatArray(device, m_toneParamsHandle, toneParams, NUMELMS(toneParams)); + } + + // Pre-compute vertices to avoid per-frame allocation + const float left = -0.5f; + const float top = -0.5f; + const float right = static_cast(m_width) - 0.5f; + const float bottom = static_cast(m_height) - 0.5f; + + const SToneMapVertex vertices[6] = { + {left, top, 0.0f, 1.0f, 0.0f, 0.0f}, {right, top, 0.0f, 1.0f, 1.0f, 0.0f}, {left, bottom, 0.0f, 1.0f, 0.0f, 1.0f}, + {right, top, 0.0f, 1.0f, 1.0f, 0.0f}, {right, bottom, 0.0f, 1.0f, 1.0f, 1.0f}, {left, bottom, 0.0f, 1.0f, 0.0f, 1.0f}, + }; + + device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, vertices, sizeof(SToneMapVertex)); + + device->SetPixelShader(nullptr); + device->SetTexture(0, nullptr); + + m_restoreStateBlock->Apply(); + + SAFE_RELEASE(backBuffer); + return true; +} + +void BorderlessToneMapPass::ReleaseTexture() +{ + SAFE_RELEASE(m_sourceSurface); + SAFE_RELEASE(m_sourceTexture); + m_width = 0; + m_height = 0; + m_format = D3DFMT_UNKNOWN; + + // Invalidate apply state block since it captured the old texture pointer + SAFE_RELEASE(m_applyStateBlock); +} + +void BorderlessToneMapPass::ReleaseShader() +{ + SAFE_RELEASE(m_pixelShader); + SAFE_RELEASE(m_constantTable); + m_toneParamsHandle = nullptr; + m_shaderFailed = false; + + // Invalidate apply state block since it captured the shader pointer + SAFE_RELEASE(m_applyStateBlock); +} + +void BorderlessToneMapPass::ReleaseStateBlock() +{ + SAFE_RELEASE(m_restoreStateBlock); + SAFE_RELEASE(m_applyStateBlock); +} + +void BorderlessToneMapPass::Release() +{ + ReleaseTexture(); + ReleaseShader(); + ReleaseStateBlock(); +} + +bool CDirect3DEvents9::IsDeviceOperational(IDirect3DDevice9* pDevice, bool* pbTemporarilyLost, HRESULT* pHrCooperativeLevel) +{ + if (pHrCooperativeLevel) + *pHrCooperativeLevel = D3DERR_INVALIDCALL; + if (pbTemporarilyLost) + *pbTemporarilyLost = false; + + if (!pDevice) + { + if (pHrCooperativeLevel) + *pHrCooperativeLevel = D3DERR_INVALIDCALL; + return false; + } + + const HRESULT hr = pDevice->TestCooperativeLevel(); + if (pHrCooperativeLevel) + *pHrCooperativeLevel = hr; + if (hr == D3D_OK) + return true; + + if (hr == D3DERR_DEVICELOST || hr == D3DERR_DEVICENOTRESET) + { + if (pbTemporarilyLost) + *pbTemporarilyLost = true; + return false; + } + + const bool bSceneActive = g_bInMTAScene.load(std::memory_order_acquire) || g_bInGTAScene.load(std::memory_order_acquire); + if (hr == D3DERR_INVALIDCALL && bSceneActive) + { + if (pHrCooperativeLevel) + *pHrCooperativeLevel = D3D_OK; + return true; + } + + return false; +} + void CDirect3DEvents9::OnDirect3DDeviceCreate(IDirect3DDevice9* pDevice) { WriteDebugEvent("CDirect3DEvents9::OnDirect3DDeviceCreate"); + // Reset fault cooldown for the new device. + ms_uiFramesSinceDeviceFault = UINT_MAX; + // Create the GUI manager CCore::GetSingleton().InitGUI(pDevice); @@ -57,8 +487,12 @@ void CDirect3DEvents9::OnDirect3DDeviceDestroy(IDirect3DDevice9* pDevice) // Destroy the GUI elements CLocalGUI::GetSingleton().DestroyObjects(); + CAdditionalVertexStreamManager::DestroySingleton(); + CVertexStreamBoundingBoxManager::DestroySingleton(); + // De-initialize the GUI manager (destroying is done on Exit) CCore::GetSingleton().DeinitGUI(); + g_BorderlessToneMapPass.Release(); } void CDirect3DEvents9::OnBeginScene(IDirect3DDevice9* pDevice) @@ -76,6 +510,47 @@ void CDirect3DEvents9::OnInvalidate(IDirect3DDevice9* pDevice) { WriteDebugEvent("CDirect3DEvents9::OnInvalidate"); + const HRESULT hrCooperativeLevel = pDevice->TestCooperativeLevel(); + const bool bDeviceOperational = (hrCooperativeLevel == D3D_OK); + const bool bDeviceTemporarilyLost = (hrCooperativeLevel == D3DERR_DEVICELOST || hrCooperativeLevel == D3DERR_DEVICENOTRESET); + + if (!bDeviceOperational && !bDeviceTemporarilyLost) + WriteDebugEvent(SString("OnInvalidate: unexpected cooperative level %08x", hrCooperativeLevel)); + + const bool bInMTAScene = g_bInMTAScene.load(std::memory_order_acquire); + const bool bInGTAScene = g_bInGTAScene.load(std::memory_order_acquire); + const bool bInAnyScene = bInMTAScene || bInGTAScene; + + IDirect3DDevice9* pStateDevice = g_pProxyDevice ? static_cast(g_pProxyDevice) : pDevice; + + if (bDeviceOperational) + { + // Flush any pending operations before invalidation while the device still accepts work + g_pCore->GetGraphics()->GetRenderItemManager()->SaveReadableDepthBuffer(); + g_pCore->GetGraphics()->GetRenderItemManager()->FlushNonAARenderTarget(); + + CloseActiveShader(true, pStateDevice); + + if (bInAnyScene) + { + const ESceneOwner owner = bInMTAScene ? ESceneOwner::MTA : (bInGTAScene ? ESceneOwner::GTA : ESceneOwner::None); + if (owner != ESceneOwner::None && !EndSceneWithoutProxy(pDevice, owner)) + WriteDebugEvent("OnInvalidate: EndSceneWithoutProxy failed"); + } + } + else + { + CloseActiveShader(false, pStateDevice); + + if (bInAnyScene) + { + WriteDebugEvent("OnInvalidate: device lost, skipping EndScene and pending GPU work"); + } + } + + g_bInMTAScene.store(false, std::memory_order_release); + ResetGTASceneState(); + // Invalidate the VMR9 Manager // CVideoManager::GetSingleton ().OnLostDevice (); @@ -83,6 +558,7 @@ void CDirect3DEvents9::OnInvalidate(IDirect3DDevice9* pDevice) CLocalGUI::GetSingleton().Invalidate(); CGraphics::GetSingleton().OnDeviceInvalidate(pDevice); + g_BorderlessToneMapPass.Release(); } void CDirect3DEvents9::OnRestore(IDirect3DDevice9* pDevice) @@ -101,33 +577,63 @@ void CDirect3DEvents9::OnRestore(IDirect3DDevice9* pDevice) CCore::GetSingleton().OnDeviceRestore(); } -void CDirect3DEvents9::OnPresent(IDirect3DDevice9* pDevice) +void CDirect3DEvents9::OnPresent(IDirect3DDevice9* pDevice, IDirect3DDevice9* pStateDevice) { TIMING_CHECKPOINT("+OnPresent1"); + CGraphics::GetSingleton().SetSkipMTARenderThisFrame(false); // Start a new scene. This isn't ideal and is not really recommended by MSDN. // I tried disabling EndScene from GTA and just end it after this code ourselves // before present, but that caused graphical issues randomly with the sky. - if (pDevice->BeginScene() == D3D_OK) - g_bInMTAScene = true; + if (!BeginSceneWithoutProxy(pDevice, ESceneOwner::MTA)) + { + WriteDebugEvent("OnPresent: BeginSceneWithoutProxy failed"); + return; + } + + if (!pStateDevice) + pStateDevice = pDevice; // Reset samplers on first call static bool bDoneReset = false; if (!bDoneReset) { bDoneReset = true; - for (uint i = 0; i < 16; i++) + if (pStateDevice) { - pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + for (uint i = 0; i < 16; i++) + { + pStateDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + pStateDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + pStateDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + } } } + CGraphics::GetSingleton().RefreshViewportIfNeeded(); + CGraphics::GetSingleton().EnteringMTARenderZone(); + CGraphics::GetSingleton().ApplyMTARenderViewportIfNeeded(); // Tell everyone that the zbuffer will need clearing before use CGraphics::GetSingleton().OnZBufferModified(); + if (CGraphics::GetSingleton().ShouldSkipMTARenderThisFrame()) + { + CCore::GetSingleton().DoPostFramePulse(); + + CGraphics::GetSingleton().LeavingMTARenderZone(); + + // Finalize any lingering shader passes (same as normal path) + CloseActiveShader(); + + if (g_bInMTAScene.load(std::memory_order_acquire)) + { + if (!EndSceneWithoutProxy(pDevice, ESceneOwner::MTA)) + WriteDebugEvent("OnPresent: EndSceneWithoutProxy failed (skip)"); + } + return; + } + TIMING_CHECKPOINT("-OnPresent1"); // Make a screenshot if needed (before GUI) CScreenShot::CheckForScreenShot(true); @@ -169,13 +675,22 @@ void CDirect3DEvents9::OnPresent(IDirect3DDevice9* pDevice) // Redraw the mouse cursor so it will always be over other elements CLocalGUI::GetSingleton().DrawMouseCursor(); + RunBorderlessToneMap(pStateDevice); + CGraphics::GetSingleton().DidRenderScene(); CGraphics::GetSingleton().LeavingMTARenderZone(); + // Finalize any lingering shader passes before wrapping the scene + // (Added for alt-tab freeze fix - commit 3390d22/e556d42) + CloseActiveShader(); + // End the scene that we started. - pDevice->EndScene(); - g_bInMTAScene = false; + if (g_bInMTAScene.load(std::memory_order_acquire)) + { + if (!EndSceneWithoutProxy(pDevice, ESceneOwner::MTA)) + WriteDebugEvent("OnPresent: EndSceneWithoutProxy failed"); + } // Update incase settings changed int iAnisotropic; @@ -188,17 +703,19 @@ void CDirect3DEvents9::OnPresent(IDirect3DDevice9* pDevice) CScreenShot::CheckForScreenShot(false); TIMING_CHECKPOINT("-OnPresent2"); + + TIMING_CHECKPOINT(""); // End of frame for profiler } -#define SAVE_RENDERSTATE_AND_SET( reg, value ) \ +#define SAVE_RENDERSTATE_AND_SET(reg, value) \ const DWORD dwSaved_##reg = g_pDeviceState->RenderState.reg; \ - const bool bSet_##reg = ( dwSaved_##reg != value ); \ - if ( bSet_##reg ) \ - pDevice->SetRenderState ( D3DRS_##reg, value ) + const bool bSet_##reg = (dwSaved_##reg != value); \ + if (bSet_##reg) \ + pStateDevice->SetRenderState(D3DRS_##reg, value) -#define RESTORE_RENDERSTATE( reg ) \ - if ( bSet_##reg ) \ - pDevice->SetRenderState ( D3DRS_##reg, dwSaved_##reg ) +#define RESTORE_RENDERSTATE(reg) \ + if (bSet_##reg) \ + pStateDevice->SetRenderState(D3DRS_##reg, dwSaved_##reg) ///////////////////////////////////////////////////////////// // @@ -207,12 +724,15 @@ void CDirect3DEvents9::OnPresent(IDirect3DDevice9* pDevice) // May change render states for custom renderings // ///////////////////////////////////////////////////////////// -HRESULT CDirect3DEvents9::OnDrawPrimitive(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) +HRESULT CDirect3DEvents9::OnDrawPrimitive(IDirect3DDevice9* pDevice, IDirect3DDevice9* pStateDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, + UINT PrimitiveCount) { if (ms_DiagnosticDebug == EDiagnosticDebug::GRAPHICS_6734) return pDevice->DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount); - CloseActiveShader(); + if (!pStateDevice) + pStateDevice = pDevice; + CloseActiveShader(true, pStateDevice); // Any shader for this texture ? SShaderItemLayers* pLayers = @@ -230,7 +750,7 @@ HRESULT CDirect3DEvents9::OnDrawPrimitive(IDirect3DDevice9* pDevice, D3DPRIMITIV else { // Yes base shader - DrawPrimitiveShader(pDevice, PrimitiveType, StartVertex, PrimitiveCount, pLayers->pBase, false); + DrawPrimitiveShader(pDevice, pStateDevice, PrimitiveType, StartVertex, PrimitiveCount, pLayers->pBase, false); // Draw each layer if (!pLayers->layerList.empty()) @@ -250,7 +770,7 @@ HRESULT CDirect3DEvents9::OnDrawPrimitive(IDirect3DDevice9* pDevice, D3DPRIMITIV for (uint i = 0; i < pLayers->layerList.size(); i++) { - DrawPrimitiveShader(pDevice, PrimitiveType, StartVertex, PrimitiveCount, pLayers->layerList[i], true); + DrawPrimitiveShader(pDevice, pStateDevice, PrimitiveType, StartVertex, PrimitiveCount, pLayers->layerList[i], true); } RESTORE_RENDERSTATE(SLOPESCALEDEPTHBIAS); @@ -276,8 +796,8 @@ HRESULT CDirect3DEvents9::OnDrawPrimitive(IDirect3DDevice9* pDevice, D3DPRIMITIV // // ///////////////////////////////////////////////////////////// -HRESULT CDirect3DEvents9::DrawPrimitiveShader(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount, - CShaderItem* pShaderItem, bool bIsLayer) +HRESULT CDirect3DEvents9::DrawPrimitiveShader(IDirect3DDevice9* pDevice, IDirect3DDevice9* pStateDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, + UINT PrimitiveCount, CShaderItem* pShaderItem, bool bIsLayer) { if (!pShaderItem) { @@ -288,45 +808,115 @@ HRESULT CDirect3DEvents9::DrawPrimitiveShader(IDirect3DDevice9* pDevice, D3DPRIM else { // Yes shader for this texture - CShaderInstance* pShaderInstance = pShaderItem->m_pShaderInstance; + SResolvedShaderState shaderState; + if (!TryResolveShaderState(pShaderItem, shaderState) || !shaderState.pEffect) + { + if (!bIsLayer) + return DrawPrimitiveGuarded(pDevice, PrimitiveType, StartVertex, PrimitiveCount); + return D3D_OK; + } + + CShaderInstance* pShaderInstance = shaderState.pInstance; + CEffectWrap* pEffectWrap = shaderState.pEffectWrap; + ID3DXEffect* pD3DEffect = shaderState.pEffect; // Apply custom parameters pShaderInstance->ApplyShaderParameters(); // Apply common parameters - pShaderInstance->m_pEffectWrap->ApplyCommonHandles(); + pEffectWrap->ApplyCommonHandles(); // Apply mapped parameters - pShaderInstance->m_pEffectWrap->ApplyMappedHandles(); + pEffectWrap->ApplyMappedHandles(); // Remember vertex shader if original draw was using it IDirect3DVertexShader9* pOriginalVertexShader = NULL; pDevice->GetVertexShader(&pOriginalVertexShader); // Do shader passes - ID3DXEffect* pD3DEffect = pShaderInstance->m_pEffectWrap->m_pD3DEffect; + bool bEffectDeviceTemporarilyLost = false; + bool bEffectDeviceOperational = true; + IDirect3DDevice9* pEffectDevice = nullptr; + if (SUCCEEDED(pD3DEffect->GetDevice(&pEffectDevice)) && pEffectDevice) + { + bEffectDeviceOperational = IsDeviceOperational(pEffectDevice, &bEffectDeviceTemporarilyLost); + SAFE_RELEASE(pEffectDevice); + } + + if (!bEffectDeviceOperational) + { + SAFE_RELEASE(pOriginalVertexShader); + if (!bIsLayer && !bEffectDeviceTemporarilyLost) + return DrawPrimitiveGuarded(pDevice, PrimitiveType, StartVertex, PrimitiveCount); + return D3D_OK; + } + + DWORD dwFlags = D3DXFX_DONOTSAVESHADERSTATE; // D3DXFX_DONOTSAVE(SHADER|SAMPLER)STATE + uint uiNumPasses = 0; + HRESULT hrBegin = pEffectWrap->Begin(&uiNumPasses, dwFlags); + if (FAILED(hrBegin) || uiNumPasses == 0) + { + if (FAILED(hrBegin) && hrBegin != D3DERR_DEVICELOST && hrBegin != D3DERR_DEVICENOTRESET) + WriteDebugEvent(SString("DrawPrimitiveShader: Begin failed %08x", hrBegin)); - DWORD dwFlags = D3DXFX_DONOTSAVESHADERSTATE; // D3DXFX_DONOTSAVE(SHADER|SAMPLER)STATE - uint uiNumPasses = 0; - pShaderInstance->m_pEffectWrap->Begin(&uiNumPasses, dwFlags); + SAFE_RELEASE(pOriginalVertexShader); + if (!bIsLayer && hrBegin != D3DERR_DEVICELOST && hrBegin != D3DERR_DEVICENOTRESET) + return DrawPrimitiveGuarded(pDevice, PrimitiveType, StartVertex, PrimitiveCount); + return D3D_OK; + } + bool bCompletedAnyPass = false; + bool bEncounteredDeviceLoss = false; for (uint uiPass = 0; uiPass < uiNumPasses; uiPass++) { - pD3DEffect->BeginPass(uiPass); + HRESULT hrBeginPass = pD3DEffect->BeginPass(uiPass); + if (FAILED(hrBeginPass)) + { + if (hrBeginPass != D3DERR_DEVICELOST && hrBeginPass != D3DERR_DEVICENOTRESET) + WriteDebugEvent(SString("DrawPrimitiveShader: BeginPass %u failed %08x", uiPass, hrBeginPass)); + else + bEncounteredDeviceLoss = true; + break; + } // Apply original vertex shader if original draw was using it (i.e. for ped animation) - if (pOriginalVertexShader) - pDevice->SetVertexShader(pOriginalVertexShader); + if (pOriginalVertexShader && pStateDevice) + pStateDevice->SetVertexShader(pOriginalVertexShader); + + HRESULT hrDraw = DrawPrimitiveGuarded(pDevice, PrimitiveType, StartVertex, PrimitiveCount); + if (hrDraw == D3DERR_DEVICELOST || hrDraw == D3DERR_DEVICENOTRESET) + bEncounteredDeviceLoss = true; + + HRESULT hrEndPass = pD3DEffect->EndPass(); + if (FAILED(hrEndPass)) + { + if (hrEndPass != D3DERR_DEVICELOST && hrEndPass != D3DERR_DEVICENOTRESET) + WriteDebugEvent(SString("DrawPrimitiveShader: EndPass %u failed %08x", uiPass, hrEndPass)); + else + bEncounteredDeviceLoss = true; + break; + } - DrawPrimitiveGuarded(pDevice, PrimitiveType, StartVertex, PrimitiveCount); - pD3DEffect->EndPass(); + if (SUCCEEDED(hrDraw)) + bCompletedAnyPass = true; } - pShaderInstance->m_pEffectWrap->End(); + + HRESULT hrEnd = pEffectWrap->End(bEffectDeviceOperational && !bEncounteredDeviceLoss); + if (FAILED(hrEnd) && hrEnd != D3DERR_DEVICELOST && hrEnd != D3DERR_DEVICENOTRESET) + WriteDebugEvent(SString("DrawPrimitiveShader: End failed %08x", hrEnd)); // If we didn't get the effect to save the shader state, clear some things here if (dwFlags & D3DXFX_DONOTSAVESHADERSTATE) { - pDevice->SetVertexShader(pOriginalVertexShader); - pDevice->SetPixelShader(NULL); + if (pStateDevice) + { + pStateDevice->SetVertexShader(pOriginalVertexShader); + pStateDevice->SetPixelShader(nullptr); + } } + + SAFE_RELEASE(pOriginalVertexShader); + + if (!bCompletedAnyPass && !bIsLayer && !bEncounteredDeviceLoss) + return DrawPrimitiveGuarded(pDevice, PrimitiveType, StartVertex, PrimitiveCount); } return D3D_OK; @@ -339,26 +929,29 @@ HRESULT CDirect3DEvents9::DrawPrimitiveShader(IDirect3DDevice9* pDevice, D3DPRIM // May change render states for custom renderings // ///////////////////////////////////////////////////////////// -HRESULT CDirect3DEvents9::OnDrawIndexedPrimitive(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, - UINT NumVertices, UINT startIndex, UINT primCount) +HRESULT CDirect3DEvents9::OnDrawIndexedPrimitive(IDirect3DDevice9* pDevice, IDirect3DDevice9* pStateDevice, D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, + UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) { if (ms_DiagnosticDebug == EDiagnosticDebug::GRAPHICS_6734) return pDevice->DrawIndexedPrimitive(PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); + if (!pStateDevice) + pStateDevice = pDevice; + // Apply anisotropic filtering if required if (ms_RequiredAnisotropicLevel > 1) { - pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC); - pDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + pStateDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC); + pStateDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); if (ms_RequiredAnisotropicLevel > g_pDeviceState->SamplerState[0].MAXANISOTROPY) - pDevice->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, ms_RequiredAnisotropicLevel); + pStateDevice->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, ms_RequiredAnisotropicLevel); } // See if we can continue using the active shader if (g_pActiveShader) { - return DrawIndexedPrimitiveShader(pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount, g_pActiveShader, false, - false); + return DrawIndexedPrimitiveShader(pDevice, pStateDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount, + g_pActiveShader, false, false); } // Any shader for this texture ? @@ -377,8 +970,8 @@ HRESULT CDirect3DEvents9::OnDrawIndexedPrimitive(IDirect3DDevice9* pDevice, D3DP else { // Draw base shader - DrawIndexedPrimitiveShader(pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount, pLayers->pBase, false, - pLayers->layerList.empty()); + DrawIndexedPrimitiveShader(pDevice, pStateDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount, pLayers->pBase, + false, pLayers->layerList.empty()); // Draw each layer if (!pLayers->layerList.empty()) @@ -398,8 +991,8 @@ HRESULT CDirect3DEvents9::OnDrawIndexedPrimitive(IDirect3DDevice9* pDevice, D3DP for (uint i = 0; i < pLayers->layerList.size(); i++) { - DrawIndexedPrimitiveShader(pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount, pLayers->layerList[i], - true, false); + DrawIndexedPrimitiveShader(pDevice, pStateDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount, + pLayers->layerList[i], true, false); } RESTORE_RENDERSTATE(SLOPESCALEDEPTHBIAS); @@ -425,9 +1018,9 @@ HRESULT CDirect3DEvents9::OnDrawIndexedPrimitive(IDirect3DDevice9* pDevice, D3DP // // ///////////////////////////////////////////////////////////// -HRESULT CDirect3DEvents9::DrawIndexedPrimitiveShader(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, - UINT NumVertices, UINT startIndex, UINT primCount, CShaderItem* pShaderItem, bool bIsLayer, - bool bCanBecomeActiveShader) +HRESULT CDirect3DEvents9::DrawIndexedPrimitiveShader(IDirect3DDevice9* pDevice, IDirect3DDevice9* pStateDevice, D3DPRIMITIVETYPE PrimitiveType, + INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount, + CShaderItem* pShaderItem, bool bIsLayer, bool bCanBecomeActiveShader) { if (pShaderItem && pShaderItem->m_fMaxDistanceSq > 0) { @@ -442,7 +1035,7 @@ HRESULT CDirect3DEvents9::DrawIndexedPrimitiveShader(IDirect3DDevice9* pDevice, if (!pShaderItem) { - CloseActiveShader(); + CloseActiveShader(true, pStateDevice); // No shader for this texture if (!bIsLayer) @@ -453,80 +1046,193 @@ HRESULT CDirect3DEvents9::DrawIndexedPrimitiveShader(IDirect3DDevice9* pDevice, // See if we should use the previously setup shader if (g_pActiveShader) { + SResolvedShaderState activeState; + if (!TryResolveShaderState(g_pActiveShader, activeState) || !activeState.pEffect) + { + CloseActiveShader(false, pStateDevice); + if (!bIsLayer) + return DrawIndexedPrimitiveGuarded(pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); + return D3D_OK; + } + dassert(pShaderItem == g_pActiveShader); g_pDeviceState->FrameStats.iNumShadersReuseSetup++; - // Transfer any state changes to the active shader - CShaderInstance* pShaderInstance = g_pActiveShader->m_pShaderInstance; - bool bChanged = pShaderInstance->m_pEffectWrap->ApplyCommonHandles(); - bChanged |= pShaderInstance->m_pEffectWrap->ApplyMappedHandles(); + // Transfer any state changes to the active shader, but ensure the device still accepts work + CShaderInstance* pShaderInstance = activeState.pInstance; + CEffectWrap* pActiveEffectWrap = activeState.pEffectWrap; + ID3DXEffect* pActiveEffect = activeState.pEffect; + + bool bDeviceTemporarilyLost = false; + bool bDeviceOperational = true; + IDirect3DDevice9* pEffectDevice = nullptr; + if (SUCCEEDED(pActiveEffect->GetDevice(&pEffectDevice)) && pEffectDevice) + { + bDeviceOperational = IsDeviceOperational(pEffectDevice, &bDeviceTemporarilyLost); + SAFE_RELEASE(pEffectDevice); + } + + if (!bDeviceOperational) + { + CloseActiveShader(false, pStateDevice); + return D3D_OK; + } + + bool bChanged = pActiveEffectWrap->ApplyCommonHandles(); + bChanged |= pActiveEffectWrap->ApplyMappedHandles(); if (bChanged) - pShaderInstance->m_pEffectWrap->m_pD3DEffect->CommitChanges(); + { + HRESULT hrCommit = pActiveEffect->CommitChanges(); + if (FAILED(hrCommit)) + { + if (hrCommit != D3DERR_DEVICELOST && hrCommit != D3DERR_DEVICENOTRESET) + WriteDebugEvent(SString("DrawIndexedPrimitiveShader: CommitChanges failed %08x", hrCommit)); + CloseActiveShader(false, pStateDevice); + return D3D_OK; + } + } return DrawIndexedPrimitiveGuarded(pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); } g_pDeviceState->FrameStats.iNumShadersFullSetup++; // Yes shader for this texture - CShaderInstance* pShaderInstance = pShaderItem->m_pShaderInstance; + SResolvedShaderState shaderState; + if (!TryResolveShaderState(pShaderItem, shaderState) || !shaderState.pEffect) + { + if (!bIsLayer) + return DrawIndexedPrimitiveGuarded(pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); + return D3D_OK; + } + + CShaderInstance* pShaderInstance = shaderState.pInstance; + CEffectWrap* pEffectWrap = shaderState.pEffectWrap; + ID3DXEffect* pD3DEffect = shaderState.pEffect; // Add normal stream if shader wants it - if (pShaderInstance->m_pEffectWrap->m_pEffectTemplate->m_bRequiresNormals) + CAdditionalVertexStreamManager* pAdditionalStreamManager = CAdditionalVertexStreamManager::GetExistingSingleton(); + if (pEffectWrap->m_pEffectTemplate->m_bRequiresNormals && pAdditionalStreamManager) { // Find/create/set additional vertex stream - CAdditionalVertexStreamManager::GetSingleton()->MaybeSetAdditionalVertexStream(PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, - startIndex, primCount); + pAdditionalStreamManager->MaybeSetAdditionalVertexStream(PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); } // Apply custom parameters pShaderInstance->ApplyShaderParameters(); // Apply common parameters - pShaderInstance->m_pEffectWrap->ApplyCommonHandles(); + pEffectWrap->ApplyCommonHandles(); // Apply mapped parameters - pShaderInstance->m_pEffectWrap->ApplyMappedHandles(); + pEffectWrap->ApplyMappedHandles(); // Remember vertex shader if original draw was using it IDirect3DVertexShader9* pOriginalVertexShader = NULL; pDevice->GetVertexShader(&pOriginalVertexShader); // Do shader passes - ID3DXEffect* pD3DEffect = pShaderInstance->m_pEffectWrap->m_pD3DEffect; + bool bEffectDeviceTemporarilyLost = false; + bool bEffectDeviceOperational = true; + IDirect3DDevice9* pEffectDevice = nullptr; + if (SUCCEEDED(pD3DEffect->GetDevice(&pEffectDevice)) && pEffectDevice) + { + bEffectDeviceOperational = IsDeviceOperational(pEffectDevice, &bEffectDeviceTemporarilyLost); + SAFE_RELEASE(pEffectDevice); + } + + if (!bEffectDeviceOperational) + { + SAFE_RELEASE(pOriginalVertexShader); + if (pAdditionalStreamManager) + pAdditionalStreamManager->MaybeUnsetAdditionalVertexStream(); + if (!bEffectDeviceTemporarilyLost && !bIsLayer) + return DrawIndexedPrimitiveGuarded(pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); + return D3D_OK; + } - DWORD dwFlags = D3DXFX_DONOTSAVESHADERSTATE; // D3DXFX_DONOTSAVE(SHADER|SAMPLER)STATE - uint uiNumPasses = 0; - pShaderInstance->m_pEffectWrap->Begin(&uiNumPasses, dwFlags); + DWORD dwFlags = D3DXFX_DONOTSAVESHADERSTATE; // D3DXFX_DONOTSAVE(SHADER|SAMPLER)STATE + uint uiNumPasses = 0; + HRESULT hrBegin = pEffectWrap->Begin(&uiNumPasses, dwFlags); + if (FAILED(hrBegin) || uiNumPasses == 0) + { + if (FAILED(hrBegin) && hrBegin != D3DERR_DEVICELOST && hrBegin != D3DERR_DEVICENOTRESET) + WriteDebugEvent(SString("DrawIndexedPrimitiveShader: Begin failed %08x", hrBegin)); + + SAFE_RELEASE(pOriginalVertexShader); + if (pAdditionalStreamManager) + pAdditionalStreamManager->MaybeUnsetAdditionalVertexStream(); + + if (hrBegin != D3DERR_DEVICELOST && hrBegin != D3DERR_DEVICENOTRESET && !bIsLayer) + return DrawIndexedPrimitiveGuarded(pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); + return D3D_OK; + } + bool bCompletedAnyPass = false; + bool bEncounteredDeviceLoss = false; for (uint uiPass = 0; uiPass < uiNumPasses; uiPass++) { - pD3DEffect->BeginPass(uiPass); + HRESULT hrBeginPass = pD3DEffect->BeginPass(uiPass); + if (FAILED(hrBeginPass)) + { + if (hrBeginPass != D3DERR_DEVICELOST && hrBeginPass != D3DERR_DEVICENOTRESET) + WriteDebugEvent(SString("DrawIndexedPrimitiveShader: BeginPass %u failed %08x", uiPass, hrBeginPass)); + else + bEncounteredDeviceLoss = true; + break; + } // Apply original vertex shader if original draw was using it (i.e. for ped animation) - if (pOriginalVertexShader) - pDevice->SetVertexShader(pOriginalVertexShader); + if (pOriginalVertexShader && pStateDevice) + pStateDevice->SetVertexShader(pOriginalVertexShader); - DrawIndexedPrimitiveGuarded(pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); + HRESULT hrDraw = DrawIndexedPrimitiveGuarded(pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); + if (hrDraw == D3DERR_DEVICELOST || hrDraw == D3DERR_DEVICENOTRESET) + bEncounteredDeviceLoss = true; - if (uiNumPasses == 1 && bCanBecomeActiveShader && pOriginalVertexShader == NULL && g_pCore->IsRenderingGrass()) + if (uiNumPasses == 1 && bCanBecomeActiveShader && pOriginalVertexShader == NULL && g_pCore->IsRenderingGrass() && SUCCEEDED(hrDraw)) { // Make this the active shader for possible reuse dassert(dwFlags == D3DXFX_DONOTSAVESHADERSTATE); + pShaderItem->AddRef(); g_pActiveShader = pShaderItem; + SAFE_RELEASE(pOriginalVertexShader); return D3D_OK; } - pD3DEffect->EndPass(); + HRESULT hrEndPass = pD3DEffect->EndPass(); + if (FAILED(hrEndPass)) + { + if (hrEndPass != D3DERR_DEVICELOST && hrEndPass != D3DERR_DEVICENOTRESET) + WriteDebugEvent(SString("DrawIndexedPrimitiveShader: EndPass %u failed %08x", uiPass, hrEndPass)); + else + bEncounteredDeviceLoss = true; + break; + } + + if (SUCCEEDED(hrDraw)) + bCompletedAnyPass = true; } - pShaderInstance->m_pEffectWrap->End(); + + HRESULT hrEnd = pEffectWrap->End(bEffectDeviceOperational && !bEncounteredDeviceLoss); + if (FAILED(hrEnd) && hrEnd != D3DERR_DEVICELOST && hrEnd != D3DERR_DEVICENOTRESET) + WriteDebugEvent(SString("DrawIndexedPrimitiveShader: End failed %08x", hrEnd)); // If we didn't get the effect to save the shader state, clear some things here if (dwFlags & D3DXFX_DONOTSAVESHADERSTATE) { - pDevice->SetVertexShader(pOriginalVertexShader); - pDevice->SetPixelShader(NULL); + if (pStateDevice) + { + pStateDevice->SetVertexShader(pOriginalVertexShader); + pStateDevice->SetPixelShader(nullptr); + } } // Unset additional vertex stream - CAdditionalVertexStreamManager::GetSingleton()->MaybeUnsetAdditionalVertexStream(); + if (pAdditionalStreamManager) + pAdditionalStreamManager->MaybeUnsetAdditionalVertexStream(); + + SAFE_RELEASE(pOriginalVertexShader); + + if (!bCompletedAnyPass && !bEncounteredDeviceLoss && !bIsLayer) + return DrawIndexedPrimitiveGuarded(pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); } return D3D_OK; @@ -539,30 +1245,68 @@ HRESULT CDirect3DEvents9::DrawIndexedPrimitiveShader(IDirect3DDevice9* pDevice, // Finish the active shader if there is one // ///////////////////////////////////////////////////////////// -void CDirect3DEvents9::CloseActiveShader() +void CDirect3DEvents9::CloseActiveShader(bool bDeviceOperational, IDirect3DDevice9* pStateDevice) { - if (!g_pActiveShader) + CShaderItem* pShaderItem = g_pActiveShader; + g_pActiveShader = nullptr; + if (!pShaderItem) + return; + + if (!SharedUtil::IsReadablePointer(pShaderItem, sizeof(void*))) return; - ID3DXEffect* pD3DEffect = g_pActiveShader->m_pShaderInstance->m_pEffectWrap->m_pD3DEffect; + SResolvedShaderState shaderState; + bool bHasShaderState = TryResolveShaderState(pShaderItem, shaderState); + + if (bHasShaderState) + { + if (shaderState.pInstance && !SharedUtil::IsReadablePointer(shaderState.pInstance, sizeof(void*))) + bHasShaderState = false; + if (bHasShaderState && shaderState.pEffectWrap && !SharedUtil::IsReadablePointer(shaderState.pEffectWrap, sizeof(void*))) + bHasShaderState = false; + } + + ID3DXEffect* pD3DEffect = bHasShaderState ? shaderState.pEffect : nullptr; + IDirect3DDevice9* pDevice = g_pGraphics ? g_pGraphics->GetDevice() : nullptr; + if (!pStateDevice) + pStateDevice = pDevice; - pD3DEffect->EndPass(); + bool bAllowDeviceWork = bDeviceOperational; + if (pDevice) + { + bool bDeviceTemporarilyLost = false; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost)) + bAllowDeviceWork = !bDeviceTemporarilyLost && bDeviceOperational; + } + + if (pD3DEffect) + { + HRESULT hrEndPass = pD3DEffect->EndPass(); + if (FAILED(hrEndPass) && hrEndPass != D3DERR_DEVICELOST && hrEndPass != D3DERR_DEVICENOTRESET) + WriteDebugEvent(SString("CloseActiveShader: EndPass failed: %08x", hrEndPass)); + } + + // When the device is lost we intentionally skip touching the GPU beyond the required End call; the effect will be reset later. + if (bHasShaderState) + shaderState.pEffectWrap->End(bAllowDeviceWork); - g_pActiveShader->m_pShaderInstance->m_pEffectWrap->End(); - g_pActiveShader = NULL; + if (CAdditionalVertexStreamManager* pAdditionalStreamManager = CAdditionalVertexStreamManager::GetExistingSingleton()) + pAdditionalStreamManager->MaybeUnsetAdditionalVertexStream(); - // We didn't get the effect to save the shader state, clear some things here - IDirect3DDevice9* pDevice = g_pGraphics->GetDevice(); - pDevice->SetVertexShader(NULL); - pDevice->SetPixelShader(NULL); + if (bAllowDeviceWork && pDevice) + { + // We didn't get the effect to save the shader state, clear some things here + // Use raw device (not proxy) to avoid cache updates - matches upstream behavior + pDevice->SetVertexShader(nullptr); + pDevice->SetPixelShader(nullptr); + } - // Unset additional vertex stream - CAdditionalVertexStreamManager::GetSingleton()->MaybeUnsetAdditionalVertexStream(); + pShaderItem->Release(); } ///////////////////////////////////////////////////////////// // -// AreVertexStreamsAreBigEnough +// AreVertexStreamsBigEnough // // Occasionally, GTA tries to draw water/clouds/something with a vertex buffer that is // too small (which causes problems for some graphics drivers). @@ -570,7 +1314,7 @@ void CDirect3DEvents9::CloseActiveShader() // This function checks the sizes are valid // ///////////////////////////////////////////////////////////// -bool AreVertexStreamsAreBigEnough(IDirect3DDevice9* pDevice, uint viMinBased, uint viMaxBased) +bool AreVertexStreamsBigEnough(IDirect3DDevice9* pDevice, uint viMinBased, uint viMaxBased) { // Check each stream used for (uint i = 0; i < NUMELMS(g_pDeviceState->VertexDeclState.bUsesStreamAtIndex); i++) @@ -604,91 +1348,995 @@ bool AreVertexStreamsAreBigEnough(IDirect3DDevice9* pDevice, uint viMinBased, ui ///////////////////////////////////////////////////////////// // -// FilerException +// FilterException // // Check if exception should be handled by us // ///////////////////////////////////////////////////////////// -uint uiLastExceptionCode = 0; -int FilerException(uint ExceptionCode) +thread_local uint uiLastExceptionCode = 0; +int FilterException(uint exceptionCode) { - uiLastExceptionCode = ExceptionCode; - if (ExceptionCode == EXCEPTION_ACCESS_VIOLATION) + uiLastExceptionCode = exceptionCode; + if (exceptionCode == EXCEPTION_ACCESS_VIOLATION) return EXCEPTION_EXECUTE_HANDLER; - if (ExceptionCode == 0xE06D7363) + if (exceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION || exceptionCode == EXCEPTION_PRIV_INSTRUCTION) + { + // Corrupted vtable, overlay hooks, or driver code-page corruption can + // produce these inside D3D9 calls. Handle like access violations. + ms_uiFramesSinceDeviceFault = 0; + char buf[80]; + _snprintf_s(buf, _countof(buf), _TRUNCATE, "FilterException: caught instruction fault %08x", exceptionCode); + WriteDebugEvent(buf); + return EXCEPTION_EXECUTE_HANDLER; + } + if (exceptionCode == EXCEPTION_IN_PAGE_ERROR) + { + // Paging failure reading d3d9.dll from disk. + ms_uiFramesSinceDeviceFault = 0; + WriteDebugEvent("FilterException: caught in-page error"); return EXCEPTION_EXECUTE_HANDLER; + } + if (exceptionCode == 0xE06D7363) + { + WriteDebugEvent("FilterException: caught Microsoft C++ exception"); + return EXCEPTION_EXECUTE_HANDLER; + } return EXCEPTION_CONTINUE_SEARCH; } +namespace +{ + void WriteDebugEventFormatted(const char* format, HRESULT value) + { + char buffer[160]; + _snprintf_s(buffer, _countof(buffer), _TRUNCATE, format, value); + WriteDebugEvent(buffer); + } + + HRESULT CallSetRenderTargetWithGuard(IDirect3DDevice9* pDevice, DWORD renderTargetIndex, IDirect3DSurface9* pRenderTarget) + { + HRESULT hr = D3D_OK; + __try + { + hr = pDevice->SetRenderTarget(renderTargetIndex, pRenderTarget); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 15 * 1000000); + hr = D3DERR_INVALIDCALL; + } + return hr; + } + + HRESULT CallSetDepthStencilSurfaceWithGuard(IDirect3DDevice9* pDevice, IDirect3DSurface9* pNewZStencil) + { + HRESULT hr = D3D_OK; + __try + { + hr = pDevice->SetDepthStencilSurface(pNewZStencil); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 16 * 1000000); + hr = D3DERR_INVALIDCALL; + } + return hr; + } + + HRESULT CallCreateAdditionalSwapChainWithGuard(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** pSwapChain) + { + HRESULT hr = D3D_OK; + __try + { + hr = pDevice->CreateAdditionalSwapChain(pPresentationParameters, pSwapChain); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 17 * 1000000); + hr = D3DERR_INVALIDCALL; + } + return hr; + } +} + +///////////////////////////////////////////////////////////// +// +// DrawPrimitiveGuarded +// Catch access violations +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::DrawPrimitiveGuarded(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount); + + // Skip draws briefly after a hardware fault; PresentGuarded ticks the counter. + if (ms_uiFramesSinceDeviceFault < 2) + return D3D_OK; + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + // Check vertices used will be within the supplied vertex buffer bounds + if (PrimitiveType == D3DPT_TRIANGLELIST || PrimitiveType == D3DPT_TRIANGLESTRIP) + { + UINT NumVertices = PrimitiveCount + 2; + if (PrimitiveType == D3DPT_TRIANGLELIST) + NumVertices = PrimitiveCount * 3; + + uint viMinBased = StartVertex; + uint viMaxBased = NumVertices + StartVertex; + + if (!AreVertexStreamsBigEnough(pDevice, viMinBased, viMaxBased)) + return hr; + } + + __try + { + hr = pDevice->DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 1 * 1000000); + hr = D3DERR_INVALIDCALL; + } + return hr; +} + +///////////////////////////////////////////////////////////// +// +// DrawIndexedPrimitiveGuarded +// +// Catch access violations +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::DrawIndexedPrimitiveGuarded(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, + UINT NumVertices, UINT startIndex, UINT primCount) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->DrawIndexedPrimitive(PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); + + if (ms_uiFramesSinceDeviceFault < 2) + return D3D_OK; + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + RunBorderlessToneMap(pDevice); + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + // Check vertices used will be within the supplied vertex buffer bounds + uint viMinBased = MinVertexIndex + BaseVertexIndex; + uint viMaxBased = MinVertexIndex + NumVertices + BaseVertexIndex; + + if (!AreVertexStreamsBigEnough(pDevice, viMinBased, viMaxBased)) + return hr; + + __try + { + hr = pDevice->DrawIndexedPrimitive(PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 2 * 1000000); + hr = D3DERR_INVALIDCALL; + } + return hr; +} + +///////////////////////////////////////////////////////////// +// +// DrawPrimitiveUPGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::DrawPrimitiveUPGuarded(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, + CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->DrawPrimitiveUP(PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); + + if (ms_uiFramesSinceDeviceFault < 2) + return D3D_OK; + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + __try + { + hr = pDevice->DrawPrimitiveUP(PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 3 * 1000000); + hr = D3DERR_INVALIDCALL; + } + + return hr; +} + +///////////////////////////////////////////////////////////// +// +// DrawIndexedPrimitiveUPGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::DrawIndexedPrimitiveUPGuarded(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, + UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, + CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->DrawIndexedPrimitiveUP(PrimitiveType, MinVertexIndex, NumVertices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, + VertexStreamZeroStride); + + if (ms_uiFramesSinceDeviceFault < 2) + return D3D_OK; + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + __try + { + hr = pDevice->DrawIndexedPrimitiveUP(PrimitiveType, MinVertexIndex, NumVertices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, + VertexStreamZeroStride); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 4 * 1000000); + hr = D3DERR_INVALIDCALL; + } + + return hr; +} + +///////////////////////////////////////////////////////////// +// +// DrawRectPatchGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::DrawRectPatchGuarded(IDirect3DDevice9* pDevice, UINT Handle, CONST float* pNumSegs, CONST D3DRECTPATCH_INFO* pRectPatchInfo) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->DrawRectPatch(Handle, pNumSegs, pRectPatchInfo); + + if (ms_uiFramesSinceDeviceFault < 2) + return D3D_OK; + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + __try + { + hr = pDevice->DrawRectPatch(Handle, pNumSegs, pRectPatchInfo); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 6 * 1000000); + hr = D3DERR_INVALIDCALL; + } + + return hr; +} + +///////////////////////////////////////////////////////////// +// +// DrawTriPatchGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::DrawTriPatchGuarded(IDirect3DDevice9* pDevice, UINT Handle, CONST float* pNumSegs, CONST D3DTRIPATCH_INFO* pTriPatchInfo) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->DrawTriPatch(Handle, pNumSegs, pTriPatchInfo); + + if (ms_uiFramesSinceDeviceFault < 2) + return D3D_OK; + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + __try + { + hr = pDevice->DrawTriPatch(Handle, pNumSegs, pTriPatchInfo); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 7 * 1000000); + hr = D3DERR_INVALIDCALL; + } + + return hr; +} + +///////////////////////////////////////////////////////////// +// +// ProcessVerticesGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::ProcessVerticesGuarded(IDirect3DDevice9* pDevice, UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, + IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->ProcessVertices(SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, Flags); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + __try + { + hr = pDevice->ProcessVertices(SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, Flags); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 8 * 1000000); + hr = D3DERR_INVALIDCALL; + } + + return hr; +} + +///////////////////////////////////////////////////////////// +// +// ClearGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::ClearGuarded(IDirect3DDevice9* pDevice, DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->Clear(Count, pRects, Flags, Color, Z, Stencil); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + __try + { + hr = pDevice->Clear(Count, pRects, Flags, Color, Z, Stencil); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 9 * 1000000); + hr = D3DERR_INVALIDCALL; + } + + return hr; +} + +///////////////////////////////////////////////////////////// +// +// ColorFillGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::ColorFillGuarded(IDirect3DDevice9* pDevice, IDirect3DSurface9* pSurface, CONST RECT* pRect, D3DCOLOR color) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->ColorFill(pSurface, pRect, color); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + __try + { + hr = pDevice->ColorFill(pSurface, pRect, color); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 10 * 1000000); + hr = D3DERR_INVALIDCALL; + } + + return hr; +} + +///////////////////////////////////////////////////////////// +// +// UpdateSurfaceGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::UpdateSurfaceGuarded(IDirect3DDevice9* pDevice, IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, + IDirect3DSurface9* pDestinationSurface, CONST POINT* pDestPoint) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->UpdateSurface(pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + __try + { + hr = pDevice->UpdateSurface(pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 11 * 1000000); + hr = D3DERR_INVALIDCALL; + } + + return hr; +} + +///////////////////////////////////////////////////////////// +// +// UpdateTextureGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::UpdateTextureGuarded(IDirect3DDevice9* pDevice, IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->UpdateTexture(pSourceTexture, pDestinationTexture); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + __try + { + hr = pDevice->UpdateTexture(pSourceTexture, pDestinationTexture); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 12 * 1000000); + hr = D3DERR_INVALIDCALL; + } + + return hr; +} + ///////////////////////////////////////////////////////////// // -// DrawPrimitiveGuarded +// GetRenderTargetDataGuarded // -// Catch access violations +// Catch access violations and device-loss states // ///////////////////////////////////////////////////////////// -HRESULT CDirect3DEvents9::DrawPrimitiveGuarded(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) +HRESULT CDirect3DEvents9::GetRenderTargetDataGuarded(IDirect3DDevice9* pDevice, IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface) { if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) - return pDevice->DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount); + return pDevice->GetRenderTargetData(pRenderTarget, pDestSurface); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } HRESULT hr = D3D_OK; - // Check vertices used will be within the supplied vertex buffer bounds - if (PrimitiveType == D3DPT_TRIANGLELIST || PrimitiveType == D3DPT_TRIANGLESTRIP) + __try { - UINT NumVertices = PrimitiveCount + 2; - if (PrimitiveType == D3DPT_TRIANGLELIST) - NumVertices = PrimitiveCount * 3; + hr = pDevice->GetRenderTargetData(pRenderTarget, pDestSurface); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 13 * 1000000); + hr = D3DERR_INVALIDCALL; + } - uint viMinBased = StartVertex; - uint viMaxBased = NumVertices + StartVertex; + return hr; +} - if (!AreVertexStreamsAreBigEnough(pDevice, viMinBased, viMaxBased)) - return hr; +///////////////////////////////////////////////////////////// +// +// GetFrontBufferDataGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::GetFrontBufferDataGuarded(IDirect3DDevice9* pDevice, UINT iSwapChain, IDirect3DSurface9* pDestSurface) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->GetFrontBufferData(iSwapChain, pDestSurface); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; } + HRESULT hr = D3D_OK; + __try { - hr = pDevice->DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount); + hr = pDevice->GetFrontBufferData(iSwapChain, pDestSurface); } - __except (FilerException(GetExceptionCode())) + __except (FilterException(GetExceptionCode())) { - CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 1 * 1000000); + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 14 * 1000000); + hr = D3DERR_INVALIDCALL; } + return hr; } ///////////////////////////////////////////////////////////// // -// DrawIndexedPrimitiveGuarded +// SetRenderTargetGuarded // -// Catch access violations +// Catch access violations and device-loss states // ///////////////////////////////////////////////////////////// -HRESULT CDirect3DEvents9::DrawIndexedPrimitiveGuarded(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, - UINT NumVertices, UINT startIndex, UINT primCount) +HRESULT CDirect3DEvents9::SetRenderTargetGuarded(IDirect3DDevice9* pDevice, DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) { if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) - return pDevice->DrawIndexedPrimitive(PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); + return pDevice->SetRenderTarget(RenderTargetIndex, pRenderTarget); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + WriteDebugEventFormatted("CDirect3DEvents9::SetRenderTargetGuarded skipped due to device state: %08x", hrCooperativeLevel); + else if (hrCooperativeLevel != D3D_OK) + WriteDebugEventFormatted("CDirect3DEvents9::SetRenderTargetGuarded unexpected cooperative level: %08x", hrCooperativeLevel); + else + WriteDebugEvent("CDirect3DEvents9::SetRenderTargetGuarded invalid device state"); + + return (hrCooperativeLevel != D3D_OK) ? hrCooperativeLevel : D3DERR_INVALIDCALL; + } + + return CallSetRenderTargetWithGuard(pDevice, RenderTargetIndex, pRenderTarget); +} + +///////////////////////////////////////////////////////////// +// +// SetDepthStencilSurfaceGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::SetDepthStencilSurfaceGuarded(IDirect3DDevice9* pDevice, IDirect3DSurface9* pNewZStencil) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->SetDepthStencilSurface(pNewZStencil); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + WriteDebugEventFormatted("CDirect3DEvents9::SetDepthStencilSurfaceGuarded skipped due to device state: %08x", hrCooperativeLevel); + else if (hrCooperativeLevel != D3D_OK) + WriteDebugEventFormatted("CDirect3DEvents9::SetDepthStencilSurfaceGuarded unexpected cooperative level: %08x", hrCooperativeLevel); + else + WriteDebugEvent("CDirect3DEvents9::SetDepthStencilSurfaceGuarded invalid device state"); + + return (hrCooperativeLevel != D3D_OK) ? hrCooperativeLevel : D3DERR_INVALIDCALL; + } + + return CallSetDepthStencilSurfaceWithGuard(pDevice, pNewZStencil); +} + +///////////////////////////////////////////////////////////// +// +// CreateAdditionalSwapChainGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::CreateAdditionalSwapChainGuarded(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters, + IDirect3DSwapChain9** pSwapChain) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->CreateAdditionalSwapChain(pPresentationParameters, pSwapChain); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + WriteDebugEventFormatted("CDirect3DEvents9::CreateAdditionalSwapChainGuarded skipped due to device state: %08x", hrCooperativeLevel); + else if (hrCooperativeLevel != D3D_OK) + WriteDebugEventFormatted("CDirect3DEvents9::CreateAdditionalSwapChainGuarded unexpected cooperative level: %08x", hrCooperativeLevel); + else + WriteDebugEvent("CDirect3DEvents9::CreateAdditionalSwapChainGuarded invalid device state"); + + return (hrCooperativeLevel != D3D_OK) ? hrCooperativeLevel : D3DERR_INVALIDCALL; + } + + return CallCreateAdditionalSwapChainWithGuard(pDevice, pPresentationParameters, pSwapChain); +} + +///////////////////////////////////////////////////////////// +// +// CreateVolumeTextureGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::CreateVolumeTextureGuarded(IDirect3DDevice9* pDevice, UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, + D3DPOOL Pool, IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->CreateVolumeTexture(Width, Height, Depth, Levels, Usage, Format, Pool, ppVolumeTexture, pSharedHandle); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } HRESULT hr = D3D_OK; - // Check vertices used will be within the supplied vertex buffer bounds - uint viMinBased = MinVertexIndex + BaseVertexIndex; - uint viMaxBased = MinVertexIndex + NumVertices + BaseVertexIndex; + __try + { + hr = pDevice->CreateVolumeTexture(Width, Height, Depth, Levels, Usage, Format, Pool, ppVolumeTexture, pSharedHandle); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 18 * 1000000); + hr = D3DERR_INVALIDCALL; + } - if (!AreVertexStreamsAreBigEnough(pDevice, viMinBased, viMaxBased)) - return hr; + return hr; +} + +///////////////////////////////////////////////////////////// +// +// CreateCubeTextureGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::CreateCubeTextureGuarded(IDirect3DDevice9* pDevice, UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, + IDirect3DCubeTexture9** ppCubeTexture, HANDLE* pSharedHandle) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->CreateCubeTexture(EdgeLength, Levels, Usage, Format, Pool, ppCubeTexture, pSharedHandle); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; __try { - hr = pDevice->DrawIndexedPrimitive(PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); + hr = pDevice->CreateCubeTexture(EdgeLength, Levels, Usage, Format, Pool, ppCubeTexture, pSharedHandle); } - __except (FilerException(GetExceptionCode())) + __except (FilterException(GetExceptionCode())) { - CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 2 * 1000000); + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 19 * 1000000); + hr = D3DERR_INVALIDCALL; + } + + return hr; +} + +///////////////////////////////////////////////////////////// +// +// CreateRenderTargetGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::CreateRenderTargetGuarded(IDirect3DDevice9* pDevice, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, + DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->CreateRenderTarget(Width, Height, Format, MultiSample, MultisampleQuality, Lockable, ppSurface, pSharedHandle); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + __try + { + hr = pDevice->CreateRenderTarget(Width, Height, Format, MultiSample, MultisampleQuality, Lockable, ppSurface, pSharedHandle); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 20 * 1000000); + hr = D3DERR_INVALIDCALL; + } + + return hr; +} + +///////////////////////////////////////////////////////////// +// +// CreateDepthStencilSurfaceGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::CreateDepthStencilSurfaceGuarded(IDirect3DDevice9* pDevice, UINT Width, UINT Height, D3DFORMAT Format, + D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, + IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->CreateDepthStencilSurface(Width, Height, Format, MultiSample, MultisampleQuality, Discard, ppSurface, pSharedHandle); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + __try + { + hr = pDevice->CreateDepthStencilSurface(Width, Height, Format, MultiSample, MultisampleQuality, Discard, ppSurface, pSharedHandle); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 21 * 1000000); + hr = D3DERR_INVALIDCALL; + } + + return hr; +} + +///////////////////////////////////////////////////////////// +// +// CreateOffscreenPlainSurfaceGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::CreateOffscreenPlainSurfaceGuarded(IDirect3DDevice9* pDevice, UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, + IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) +{ + if (ms_DiagnosticDebug == EDiagnosticDebug::D3D_6732) + return pDevice->CreateOffscreenPlainSurface(Width, Height, Format, Pool, ppSurface, pSharedHandle); + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + __try + { + hr = pDevice->CreateOffscreenPlainSurface(Width, Height, Format, Pool, ppSurface, pSharedHandle); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 22 * 1000000); + hr = D3DERR_INVALIDCALL; + } + + return hr; +} + +///////////////////////////////////////////////////////////// +// +// PresentGuarded +// +// Catch access violations and device-loss states +// +///////////////////////////////////////////////////////////// +HRESULT CDirect3DEvents9::PresentGuarded(IDirect3DDevice9* pDevice, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, + CONST RGNDATA* pDirtyRegion) +{ + // Tick the fault cooldown so draw calls resume after a short skip. + if (ms_uiFramesSinceDeviceFault < UINT_MAX) + ++ms_uiFramesSinceDeviceFault; + + bool bDeviceTemporarilyLost = false; + HRESULT hrCooperativeLevel = D3DERR_INVALIDCALL; + if (!IsDeviceOperational(pDevice, &bDeviceTemporarilyLost, &hrCooperativeLevel)) + { + if (bDeviceTemporarilyLost) + return hrCooperativeLevel; + + if (hrCooperativeLevel != D3D_OK) + return hrCooperativeLevel; + + return D3DERR_INVALIDCALL; + } + + HRESULT hr = D3D_OK; + + __try + { + hr = pDevice->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); + } + __except (FilterException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastExceptionCode & 0xFFFF) + 5 * 1000000); + hr = D3DERR_INVALIDCALL; } + return hr; } @@ -788,7 +2436,6 @@ HRESULT CDirect3DEvents9::CreateTexture(IDirect3DDevice9* pDevice, UINT Width, U { SString strMessage("CreateTexture fail: hr:%x W:%x H:%x L:%x Usage:%x Format:%x Pool:%x", hr, Width, Height, Levels, Usage, Format, Pool); WriteDebugEvent(strMessage); - AddReportLog(8612, strMessage); CCore::GetSingleton().LogEvent(612, "CreateTexture", "", strMessage); return hr; } @@ -818,7 +2465,10 @@ IDirect3DVertexBuffer9* CDirect3DEvents9::GetRealVertexBuffer(IDirect3DVertexBuf // If so, use the original vertex buffer if (pProxy) + { pStreamData = pProxy->GetOriginal(); + SAFE_RELEASE(pProxy); + } } return pStreamData; @@ -841,7 +2491,10 @@ IDirect3DIndexBuffer9* CDirect3DEvents9::GetRealIndexBuffer(IDirect3DIndexBuffer // If so, use the original index buffer if (pProxy) + { pIndexData = pProxy->GetOriginal(); + SAFE_RELEASE(pProxy); + } } return pIndexData; } @@ -863,7 +2516,10 @@ IDirect3DBaseTexture9* CDirect3DEvents9::GetRealTexture(IDirect3DBaseTexture9* p // If so, use the original texture if (pProxy) + { pTexture = pProxy->GetOriginal(); + SAFE_RELEASE(pProxy); + } } return pTexture; } @@ -877,7 +2533,28 @@ IDirect3DBaseTexture9* CDirect3DEvents9::GetRealTexture(IDirect3DBaseTexture9* p ///////////////////////////////////////////////////////////// HRESULT CDirect3DEvents9::CreateVertexDeclaration(IDirect3DDevice9* pDevice, CONST D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl) { - HRESULT hr; + if (!pDevice) + { + WriteDebugEvent("CreateVertexDeclaration: pDevice is null"); + return D3DERR_INVALIDCALL; + } + + if (!pVertexElements) + { + WriteDebugEvent("CreateVertexDeclaration: pVertexElements is null"); + return D3DERR_INVALIDCALL; + } + + if (!ppDecl) + { + WriteDebugEvent("CreateVertexDeclaration: ppDecl is null"); + return D3DERR_INVALIDCALL; + } + + *ppDecl = nullptr; + + HRESULT hr = D3D_OK; + IDirect3DVertexDeclaration9* pOriginalDecl = nullptr; hr = pDevice->CreateVertexDeclaration(pVertexElements, ppDecl); if (FAILED(hr)) @@ -900,8 +2577,15 @@ HRESULT CDirect3DEvents9::CreateVertexDeclaration(IDirect3DDevice9* pDevice, CON return hr; } + pOriginalDecl = *ppDecl; + if (!pOriginalDecl) + { + WriteDebugEvent("CreateVertexDeclaration: driver returned a null declaration"); + return D3DERR_INVALIDCALL; + } + // Create proxy - *ppDecl = new CProxyDirect3DVertexDeclaration(pDevice, *ppDecl, pVertexElements); + *ppDecl = new CProxyDirect3DVertexDeclaration(pDevice, pOriginalDecl, pVertexElements); return hr; } @@ -926,9 +2610,15 @@ HRESULT CDirect3DEvents9::SetVertexDeclaration(IDirect3DDevice9* pDevice, IDirec pDecl = pProxy->GetOriginal(); // Update state info - CProxyDirect3DDevice9::SD3DVertexDeclState* pInfo = MapFind(g_pProxyDevice->m_VertexDeclMap, pProxy); - if (pInfo) - g_pDeviceState->VertexDeclState = *pInfo; + CScopedActiveProxyDevice proxyDevice; + if (proxyDevice) + { + CProxyDirect3DDevice9::SD3DVertexDeclState* pInfo = MapFind(proxyDevice->m_VertexDeclMap, pProxy); + if (pInfo) + g_pDeviceState->VertexDeclState = *pInfo; + } + + SAFE_RELEASE(pProxy); } } @@ -947,26 +2637,34 @@ ERenderFormat CDirect3DEvents9::DiscoverReadableDepthFormat(IDirect3DDevice9* pD IDirect3D9* pD3D = NULL; pDevice->GetDirect3D(&pD3D); - // Formats to check for - ERenderFormat checkList[] = {RFORMAT_INTZ, RFORMAT_DF24, RFORMAT_DF16, RFORMAT_RAWZ}; + ERenderFormat discoveredFormat = RFORMAT_UNKNOWN; - D3DDISPLAYMODE displayMode; - if (pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode) == D3D_OK) + if (pD3D) { - for (uint i = 0; i < NUMELMS(checkList); i++) + // Formats to check for + ERenderFormat checkList[] = {RFORMAT_INTZ, RFORMAT_DF24, RFORMAT_DF16, RFORMAT_RAWZ}; + + D3DDISPLAYMODE displayMode; + if (pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode) == D3D_OK) { - D3DFORMAT DepthFormat = (D3DFORMAT)checkList[i]; + for (uint i = 0; i < NUMELMS(checkList); i++) + { + D3DFORMAT DepthFormat = (D3DFORMAT)checkList[i]; - // Can use this format? - if (D3D_OK != pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, displayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, DepthFormat)) - continue; + // Can use this format? + if (D3D_OK != + pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, displayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, DepthFormat)) + continue; - // Don't check for compatibility with multisampling, as we turn AA off when using readable depth buffer + // Don't check for compatibility with multisampling, as we turn AA off when using readable depth buffer - // Found a working format - return checkList[i]; + // Found a working format + discoveredFormat = checkList[i]; + break; + } } } - return RFORMAT_UNKNOWN; + SAFE_RELEASE(pD3D); + return discoveredFormat; } diff --git a/Client/core/DXHook/CDirect3DEvents9.h b/Client/core/DXHook/CDirect3DEvents9.h index d946bd5a3bf..c8ca6fcfda2 100644 --- a/Client/core/DXHook/CDirect3DEvents9.h +++ b/Client/core/DXHook/CDirect3DEvents9.h @@ -18,22 +18,56 @@ class CDirect3DEvents9 public: static void OnDirect3DDeviceCreate(IDirect3DDevice9* pDevice); static void OnDirect3DDeviceDestroy(IDirect3DDevice9* pDevice); - static void OnPresent(IDirect3DDevice9* pDevice); + static void OnPresent(IDirect3DDevice9* pDevice, IDirect3DDevice9* pStateDevice); static void OnBeginScene(IDirect3DDevice9* pDevice); static bool OnEndScene(IDirect3DDevice9* pDevice); static void OnInvalidate(IDirect3DDevice9* pDevice); static void OnRestore(IDirect3DDevice9* pDevice); - static HRESULT OnDrawPrimitive(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount); - static HRESULT DrawPrimitiveShader(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount, - CShaderItem* pShaderItem, bool bIsLayer); - static HRESULT OnDrawIndexedPrimitive(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, - UINT startIndex, UINT primCount); - static HRESULT DrawIndexedPrimitiveShader(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, - UINT NumVertices, UINT startIndex, UINT primCount, CShaderItem* pShaderItem, bool bIsLayer, + static HRESULT OnDrawPrimitive(IDirect3DDevice9* pDevice, IDirect3DDevice9* pStateDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, + UINT PrimitiveCount); + static HRESULT DrawPrimitiveShader(IDirect3DDevice9* pDevice, IDirect3DDevice9* pStateDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, + UINT PrimitiveCount, CShaderItem* pShaderItem, bool bIsLayer); + static HRESULT OnDrawIndexedPrimitive(IDirect3DDevice9* pDevice, IDirect3DDevice9* pStateDevice, D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, + UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount); + static HRESULT DrawIndexedPrimitiveShader(IDirect3DDevice9* pDevice, IDirect3DDevice9* pStateDevice, D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, + UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount, CShaderItem* pShaderItem, bool bIsLayer, bool bCanBecomeActiveShader); static HRESULT DrawPrimitiveGuarded(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount); static HRESULT DrawIndexedPrimitiveGuarded(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount); + static HRESULT DrawPrimitiveUPGuarded(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, + UINT VertexStreamZeroStride); + static HRESULT DrawIndexedPrimitiveUPGuarded(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, + UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, + UINT VertexStreamZeroStride); + static HRESULT DrawRectPatchGuarded(IDirect3DDevice9* pDevice, UINT Handle, CONST float* pNumSegs, CONST D3DRECTPATCH_INFO* pRectPatchInfo); + static HRESULT DrawTriPatchGuarded(IDirect3DDevice9* pDevice, UINT Handle, CONST float* pNumSegs, CONST D3DTRIPATCH_INFO* pTriPatchInfo); + static HRESULT ProcessVerticesGuarded(IDirect3DDevice9* pDevice, UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, + IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags); + static HRESULT ClearGuarded(IDirect3DDevice9* pDevice, DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil); + static HRESULT ColorFillGuarded(IDirect3DDevice9* pDevice, IDirect3DSurface9* pSurface, CONST RECT* pRect, D3DCOLOR color); + static HRESULT UpdateSurfaceGuarded(IDirect3DDevice9* pDevice, IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, + IDirect3DSurface9* pDestinationSurface, CONST POINT* pDestPoint); + static HRESULT UpdateTextureGuarded(IDirect3DDevice9* pDevice, IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture); + static HRESULT GetRenderTargetDataGuarded(IDirect3DDevice9* pDevice, IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface); + static HRESULT GetFrontBufferDataGuarded(IDirect3DDevice9* pDevice, UINT iSwapChain, IDirect3DSurface9* pDestSurface); + static HRESULT SetRenderTargetGuarded(IDirect3DDevice9* pDevice, DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget); + static HRESULT SetDepthStencilSurfaceGuarded(IDirect3DDevice9* pDevice, IDirect3DSurface9* pNewZStencil); + static HRESULT CreateAdditionalSwapChainGuarded(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters, + IDirect3DSwapChain9** pSwapChain); + static HRESULT CreateVolumeTextureGuarded(IDirect3DDevice9* pDevice, UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, + D3DPOOL Pool, IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle); + static HRESULT CreateCubeTextureGuarded(IDirect3DDevice9* pDevice, UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, + IDirect3DCubeTexture9** ppCubeTexture, HANDLE* pSharedHandle); + static HRESULT CreateRenderTargetGuarded(IDirect3DDevice9* pDevice, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, + DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle); + static HRESULT CreateDepthStencilSurfaceGuarded(IDirect3DDevice9* pDevice, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, + DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle); + static HRESULT CreateOffscreenPlainSurfaceGuarded(IDirect3DDevice9* pDevice, UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, + IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle); + static HRESULT PresentGuarded(IDirect3DDevice9* pDevice, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, + CONST RGNDATA* pDirtyRegion); + static bool IsDeviceOperational(IDirect3DDevice9* pDevice, bool* pbTemporarilyLost = nullptr, HRESULT* pHrCooperativeLevel = nullptr); static HRESULT CreateVertexBuffer(IDirect3DDevice9* pDevice, UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle); static HRESULT CreateIndexBuffer(IDirect3DDevice9* pDevice, UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, @@ -45,7 +79,7 @@ class CDirect3DEvents9 static HRESULT SetVertexDeclaration(IDirect3DDevice9* pDevice, IDirect3DVertexDeclaration9* pDecl); static void CheckForScreenShot(); static ERenderFormat DiscoverReadableDepthFormat(IDirect3DDevice9* pDevice, D3DMULTISAMPLE_TYPE multisampleType, bool bWindowed); - static void CloseActiveShader(); + static void CloseActiveShader(bool bDeviceOperational = true, IDirect3DDevice9* pStateDevice = nullptr); static IDirect3DVertexBuffer9* GetRealVertexBuffer(IDirect3DVertexBuffer9* pVertexBuffer); static IDirect3DIndexBuffer9* GetRealIndexBuffer(IDirect3DIndexBuffer9* pIndexBuffer); diff --git a/Client/core/DXHook/CDirect3DHook9.cpp b/Client/core/DXHook/CDirect3DHook9.cpp index 21b0c86c2f7..339c8ee1590 100644 --- a/Client/core/DXHook/CDirect3DHook9.cpp +++ b/Client/core/DXHook/CDirect3DHook9.cpp @@ -87,17 +87,18 @@ IDirect3D9* CDirect3DHook9::API_Direct3DCreate9(UINT SDKVersion) CCore::GetSingleton().CreateGUI(); } - // D3DX_SDK_VERSION checks - // August 2009 SDK required for shaders to work properly - #if D3DX_SDK_VERSION != 42 +// D3DX_SDK_VERSION checks +// SDK required for shaders to work properly +// Accept the DirectX SDK shipped with August 2009 (42) or June 2010 (43) +#if (D3DX_SDK_VERSION != 42) && (D3DX_SDK_VERSION != 43) WriteDebugEvent("D3DX_SDK_VERSION incorrect " QUOTE_DEFINE(D3DX_SDK_VERSION)); - #pragma message( "WARNING: Microsoft DirectX SDK (August 2009) includes missing" ) - #ifndef CI_BUILD - #ifndef MTA_DEBUG - #error "Microsoft DirectX SDK (August 2009) includes missing" - #endif + #pragma message("WARNING: Microsoft DirectX SDK (August 2009 or June 2010) includes missing") + #ifndef CI_BUILD + #ifndef MTA_DEBUG + #error "Microsoft DirectX SDK (August 2009 or June 2010) includes missing" #endif #endif +#endif if (!D3DXCheckVersion(D3D_SDK_VERSION, D3DX_SDK_VERSION)) { SString strMessage("D3DXCheckVersion FAILED (D3D_SDK_VERSION: %d D3DX_SDK_VERSION: %d SDKVersion: %d)", D3D_SDK_VERSION, D3DX_SDK_VERSION, @@ -125,8 +126,8 @@ IDirect3D9* CDirect3DHook9::API_Direct3DCreate9(UINT SDKVersion) "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly."), _("Error") + _E("CC50"), - MB_OK | MB_ICONERROR | MB_TOPMOST); // Could not initialize Direct3D9. Please ensure the DirectX End-User Runtime and latest - // Windows Service Packs are installed correctly. + MB_OK | MB_ICONERROR | MB_TOPMOST); // Could not initialize Direct3D9. Please ensure the DirectX End-User Runtime and latest + // Windows Service Packs are installed correctly. return NULL; } diff --git a/Client/core/DXHook/CProxyComHelpers.h b/Client/core/DXHook/CProxyComHelpers.h new file mode 100644 index 00000000000..e512f5798ad --- /dev/null +++ b/Client/core/DXHook/CProxyComHelpers.h @@ -0,0 +1,108 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: core/DXHook/CProxyComHelpers.h + * PURPOSE: Shared COM interface helper functions for proxy classes + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include "ComPtrValidation.h" + +template +void ReleaseInterface(T*& pointer, int errorCode, const char* context = nullptr) +{ + if (!pointer) + return; + + T* heldPointer = pointer; + + const bool valid = IsValidComInterfacePointer(pointer, ComPtrValidation::ValidationMode::ForceRefresh); + + if (!valid) + { + SString label; + label = context ? context : "ReleaseInterface"; + SString message; + message.Format("%s: skipping Release on invalid COM pointer %p", label.c_str(), heldPointer); + AddReportLog(errorCode, message, 5); + ComPtrValidation::Invalidate(heldPointer); + pointer = nullptr; + return; + } + + heldPointer->Release(); + pointer = nullptr; +} + +template +void ReleaseInterface(T*& pointer) +{ + if (pointer) + { + pointer->Release(); + pointer = nullptr; + } +} + +template +void ReplaceInterface(T*& destination, T* source, int releaseErrorCode, int replaceErrorCode, const char* context = nullptr) +{ + if (destination == source) + return; + + ReleaseInterface(destination, releaseErrorCode, context); + + if (source && !IsValidComInterfacePointer(source, ComPtrValidation::ValidationMode::ForceRefresh)) + { + SString label; + label = context ? context : "ReplaceInterface"; + SString message; + message.Format("%s: refusing to assign invalid COM pointer %p", label.c_str(), source); + AddReportLog(replaceErrorCode, message, 5); + destination = nullptr; + return; + } + + destination = source; + if (destination) + destination->AddRef(); +} + +template +void ReplaceInterface(T*& destination, T* source) +{ + if (destination == source) + return; + + if (destination) + { + // Cached validation. All tracked objects are held via AddRef, + // so an external release cannot free them while our ref is live. + if (!ComPtrValidation::Validate(destination)) + { + AddReportLog(8799, SString("ReplaceInterface: skipping Release on stale COM pointer %p", destination), 5); + ComPtrValidation::Invalidate(destination); + } + else + { + destination->Release(); + } + destination = nullptr; + } + + destination = source; + if (destination) + destination->AddRef(); +} + +template +void ReplaceInterface(T*& destination, T* source, const char* context) +{ + constexpr int GENERIC_COM_ERROR = 8799; + ReplaceInterface(destination, source, GENERIC_COM_ERROR, GENERIC_COM_ERROR, context); +} diff --git a/Client/core/DXHook/CProxyDirect3D9.cpp b/Client/core/DXHook/CProxyDirect3D9.cpp index 609f49e8ac5..acc73034c2c 100644 --- a/Client/core/DXHook/CProxyDirect3D9.cpp +++ b/Client/core/DXHook/CProxyDirect3D9.cpp @@ -10,132 +10,275 @@ *****************************************************************************/ #include "StdInc.h" +#include "CProxyComHelpers.h" +#include "ComPtrValidation.h" #include +#include +#include #include extern HINSTANCE g_hModule; +namespace +{ + // Cached static Direct3D pointer for lockless fast-path access + std::atomic g_cachedStaticDirect3D{nullptr}; + std::atomic g_cachedDirect3DValid{false}; + // Cached adapter monitor for lockless fast-path access + std::atomic g_cachedAdapterMonitor{nullptr}; + std::atomic g_cachedAdapterMonitorValid{false}; + + IDirect3D9* GetFirstValidTrackedDirect3D(std::vector& trackedList) + { + // Return first element without expensive COM validation (called frequently) + return trackedList.empty() ? nullptr : trackedList.front(); + } +} // unnamed namespace + HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface); + std::vector ms_CreatedDirect3D9List; +std::mutex ms_Direct3D9ListMutex; bool CreateDeviceSecondCallCheck(HRESULT& hOutResult, IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface); +void ApplyBorderlessColorCorrection(CProxyDirect3DDevice9* proxyDevice, const D3DPRESENT_PARAMETERS& presentationParameters); -CProxyDirect3D9::CProxyDirect3D9(IDirect3D9* pInterface) +CProxyDirect3D9::CProxyDirect3D9(IDirect3D9* pInterface) : m_pDevice(nullptr), m_lRefCount(1) { WriteDebugEvent(SString("CProxyDirect3D9::CProxyDirect3D9 %08x", this)); + + if (!IsValidComInterfacePointer(pInterface, ComPtrValidation::ValidationMode::Default)) + { + SString message; + message.Format("CProxyDirect3D9 ctor: received invalid IDirect3D9 pointer %p, proxy will be non-functional", pInterface); + AddReportLog(8753, message, 5); + // Leave m_pDevice as nullptr - do not store invalid pointers + return; + } + + pInterface->AddRef(); m_pDevice = pInterface; - ms_CreatedDirect3D9List.push_back(m_pDevice); + + // Track this Direct3D9 instance for StaticGetDirect3D() lookups + if (m_pDevice) + { + if (IsValidComInterfacePointer(m_pDevice, ComPtrValidation::ValidationMode::Default)) + { + std::lock_guard lock(ms_Direct3D9ListMutex); + ms_CreatedDirect3D9List.push_back(m_pDevice); + // Update cache for lockless StaticGetDirect3D access + g_cachedStaticDirect3D.store(m_pDevice, std::memory_order_release); + g_cachedDirect3DValid.store(true, std::memory_order_release); + } + else + { + SString message; + message.Format("CProxyDirect3D9 ctor: not tracking invalid IDirect3D9 pointer %p", m_pDevice); + AddReportLog(8756, message, 5); + } + } } CProxyDirect3D9::~CProxyDirect3D9() { WriteDebugEvent(SString("CProxyDirect3D9::~CProxyDirect3D9 %08x", this)); - ListRemove(ms_CreatedDirect3D9List, m_pDevice); - m_pDevice = NULL; + { + std::lock_guard lock(ms_Direct3D9ListMutex); + ListRemove(ms_CreatedDirect3D9List, m_pDevice); + // Invalidate both caches when removing this device + g_cachedDirect3DValid.store(false, std::memory_order_release); + g_cachedAdapterMonitorValid.store(false, std::memory_order_release); + } + ReleaseInterface(m_pDevice, 8752); } /*** IUnknown methods ***/ HRESULT CProxyDirect3D9::QueryInterface(REFIID riid, void** ppvObj) { + if (!m_pDevice) + { + if (ppvObj) + *ppvObj = nullptr; + return E_POINTER; + } + return m_pDevice->QueryInterface(riid, ppvObj); } ULONG CProxyDirect3D9::AddRef() { - return m_pDevice->AddRef(); + LONG lNewRefCount = m_lRefCount.fetch_add(1, std::memory_order_relaxed) + 1; + + if (m_pDevice) + m_pDevice->AddRef(); + + return static_cast(lNewRefCount); } ULONG CProxyDirect3D9::Release() { - // Call original function - ULONG ulRefCount = m_pDevice->Release(); - if (ulRefCount == 0) + LONG lNewRefCount = m_lRefCount.fetch_sub(1, std::memory_order_acq_rel) - 1; + + if (lNewRefCount < 0) + { + SString message; + message.Format("CProxyDirect3D9::Release detected reference count underflow for proxy %p", this); + AddReportLog(8752, message, 5); + lNewRefCount = 0; + } + + if (m_pDevice && lNewRefCount > 0) + m_pDevice->Release(); + + if (lNewRefCount == 0) delete this; - return ulRefCount; + + return static_cast(lNewRefCount); } /*** IDirect3D9 methods ***/ HRESULT CProxyDirect3D9::RegisterSoftwareDevice(void* pInitializeFunction) { + if (!m_pDevice) + return D3DERR_INVALIDDEVICE; return m_pDevice->RegisterSoftwareDevice(pInitializeFunction); } UINT CProxyDirect3D9::GetAdapterCount() { + if (!m_pDevice) + return 0; return m_pDevice->GetAdapterCount(); } HRESULT CProxyDirect3D9::GetAdapterIdentifier(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier) { + if (!m_pDevice) + return D3DERR_INVALIDDEVICE; return m_pDevice->GetAdapterIdentifier(Adapter, Flags, pIdentifier); } UINT CProxyDirect3D9::GetAdapterModeCount(UINT Adapter, D3DFORMAT Format) { + if (!m_pDevice) + return 0; return m_pDevice->GetAdapterModeCount(Adapter, Format); } HRESULT CProxyDirect3D9::EnumAdapterModes(UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) { + if (!m_pDevice) + return D3DERR_INVALIDDEVICE; return m_pDevice->EnumAdapterModes(Adapter, Format, Mode, pMode); } HRESULT CProxyDirect3D9::GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE* pMode) { + if (!m_pDevice) + return D3DERR_INVALIDDEVICE; return m_pDevice->GetAdapterDisplayMode(Adapter, pMode); } HRESULT CProxyDirect3D9::CheckDeviceType(UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed) { + if (!m_pDevice) + return D3DERR_INVALIDDEVICE; return m_pDevice->CheckDeviceType(Adapter, DevType, AdapterFormat, BackBufferFormat, bWindowed); } HRESULT CProxyDirect3D9::CheckDeviceFormat(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) { + if (!m_pDevice) + return D3DERR_INVALIDDEVICE; return m_pDevice->CheckDeviceFormat(Adapter, DeviceType, AdapterFormat, Usage, RType, CheckFormat); } HRESULT CProxyDirect3D9::CheckDeviceMultiSampleType(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) { + if (!m_pDevice) + return D3DERR_INVALIDDEVICE; return m_pDevice->CheckDeviceMultiSampleType(Adapter, DeviceType, SurfaceFormat, Windowed, MultiSampleType, pQualityLevels); } HRESULT CProxyDirect3D9::CheckDepthStencilMatch(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) { + if (!m_pDevice) + return D3DERR_INVALIDDEVICE; return m_pDevice->CheckDepthStencilMatch(Adapter, DeviceType, AdapterFormat, RenderTargetFormat, DepthStencilFormat); } HRESULT CProxyDirect3D9::CheckDeviceFormatConversion(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) { + if (!m_pDevice) + return D3DERR_INVALIDDEVICE; return m_pDevice->CheckDeviceFormatConversion(Adapter, DeviceType, SourceFormat, TargetFormat); } HRESULT CProxyDirect3D9::GetDeviceCaps(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) { + if (!m_pDevice) + return D3DERR_INVALIDDEVICE; return m_pDevice->GetDeviceCaps(Adapter, DeviceType, pCaps); } HMONITOR CProxyDirect3D9::GetAdapterMonitor(UINT Adapter) { + if (!m_pDevice) + return NULL; return m_pDevice->GetAdapterMonitor(Adapter); } HMONITOR CProxyDirect3D9::StaticGetAdapterMonitor(UINT Adapter) { - if (ms_CreatedDirect3D9List.empty()) + // Fast path: use cached monitor without lock (for default adapter 0) + if (Adapter == 0 && g_cachedAdapterMonitorValid.load(std::memory_order_acquire)) + { + HMONITOR hMonitor = g_cachedAdapterMonitor.load(std::memory_order_acquire); + if (hMonitor) + return hMonitor; + } + + // Slow path: refresh cache under lock + std::lock_guard lock(ms_Direct3D9ListMutex); + IDirect3D9* pDirect3D = GetFirstValidTrackedDirect3D(ms_CreatedDirect3D9List); + if (!pDirect3D) return NULL; - return ms_CreatedDirect3D9List[0]->GetAdapterMonitor(Adapter); + + HMONITOR hMonitor = pDirect3D->GetAdapterMonitor(Adapter); + + // Cache result for default adapter + if (Adapter == 0 && hMonitor) + { + g_cachedAdapterMonitor.store(hMonitor, std::memory_order_release); + g_cachedAdapterMonitorValid.store(true, std::memory_order_release); + } + + return hMonitor; } IDirect3D9* CProxyDirect3D9::StaticGetDirect3D() { - if (ms_CreatedDirect3D9List.empty()) - return NULL; - return ms_CreatedDirect3D9List[0]; + // Fast path: use cached pointer without lock (called frequently) + if (g_cachedDirect3DValid.load(std::memory_order_acquire)) + { + IDirect3D9* pDirect3D = g_cachedStaticDirect3D.load(std::memory_order_acquire); + if (pDirect3D) + return pDirect3D; + } + + // Slow path: refresh cache under lock + std::lock_guard lock(ms_Direct3D9ListMutex); + IDirect3D9* pDirect3D = GetFirstValidTrackedDirect3D(ms_CreatedDirect3D9List); + if (pDirect3D) + { + g_cachedStaticDirect3D.store(pDirect3D, std::memory_order_release); + g_cachedDirect3DValid.store(true, std::memory_order_release); + } + return pDirect3D; } HRESULT CProxyDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, @@ -147,6 +290,22 @@ HRESULT CProxyDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND WriteDebugEvent("CProxyDirect3D9::CreateDevice"); + if (!ppReturnedDeviceInterface) + { + AddReportLog(8754, SStringX("CProxyDirect3D9::CreateDevice - missing ppReturnedDeviceInterface pointer"), 5); + return D3DERR_INVALIDCALL; + } + + if (!SharedUtil::IsReadablePointer(ppReturnedDeviceInterface, sizeof(*ppReturnedDeviceInterface))) + { + SString message; + message.Format("CProxyDirect3D9::CreateDevice - invalid ppReturnedDeviceInterface pointer %p", ppReturnedDeviceInterface); + AddReportLog(8754, message, 5); + return D3DERR_INVALIDCALL; + } + + *ppReturnedDeviceInterface = nullptr; + WriteDebugEvent(SString(" Adapter:%d DeviceType:%d BehaviorFlags:0x%x", Adapter, DeviceType, BehaviorFlags)); // Make sure DirectX Get calls will work @@ -164,15 +323,28 @@ HRESULT CProxyDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND WriteDebugEvent(SString(" FullScreen_RefreshRateInHz:%d PresentationInterval:0x%08x", pPresentationParameters->FullScreen_RefreshRateInHz, pPresentationParameters->PresentationInterval)); - // Change the window title to MTA: San Andreas - #ifdef MTA_DEBUG +// Change the window title to MTA: San Andreas +#ifdef MTA_DEBUG SetWindowTextW(hFocusWindow, MbUTF8ToUTF16("MTA: San Andreas [DEBUG]").c_str()); - #else +#else SetWindowTextW(hFocusWindow, MbUTF8ToUTF16("MTA: San Andreas").c_str()); - #endif +#endif // Set dark titlebar if needed - BOOL darkTitleBar = GetSystemRegistryValue((uint)HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", "AppsUseLightTheme") == "\x0"; + int themeStatus = 0; + const SString appsUseLightTheme = + GetSystemRegistryValue((uint)HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", "AppsUseLightTheme", &themeStatus); + BOOL darkTitleBar = FALSE; + if (themeStatus > 0) + { + // Parse the registry value into a numeric flag + char* themeEnd = nullptr; + const long themeNumeric = strtol(appsUseLightTheme.c_str(), &themeEnd, 10); + if (themeEnd != appsUseLightTheme.c_str() && *themeEnd == '\0') + { + darkTitleBar = (themeNumeric == 0); + } + } DwmSetWindowAttribute(hFocusWindow, DWMWA_USE_IMMERSIVE_DARK_MODE, &darkTitleBar, sizeof(darkTitleBar)); // Update icon @@ -191,7 +363,14 @@ HRESULT CProxyDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND // Redraw, we avoid possible problems with the fact that it won't replace the icon somewhere InvalidateRect(hFocusWindow, nullptr, TRUE); UpdateWindow(hFocusWindow); - + + // Check if proxy has valid device pointer + if (!m_pDevice) + { + AddReportLog(8754, SStringX("CProxyDirect3D9::CreateDevice - proxy has no valid IDirect3D9 device"), 5); + return D3DERR_INVALIDDEVICE; + } + // Detect if second call to CreateDevice if (CreateDeviceSecondCallCheck(hResult, m_pDevice, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface)) { @@ -207,10 +386,23 @@ HRESULT CProxyDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hResult = m_pDevice->CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); // Check if the result is correct (a custom d3d9.dll could return D3D_OK with a null pointer) - if (hResult == D3D_OK && *ppReturnedDeviceInterface == nullptr) + if (hResult == D3D_OK) { - WriteDebugEvent("CProxyDirect3D9::CreateDevice: CreateDevice succeeded, but IDirect3DDevice9* is a nullptr"); - hResult = D3DERR_INVALIDDEVICE; + IDirect3DDevice9* pCreatedDevice = *ppReturnedDeviceInterface; + if (!pCreatedDevice) + { + AddReportLog(8755, SStringX("CProxyDirect3D9::CreateDevice - driver returned nullptr device"), 5); + hResult = D3DERR_INVALIDDEVICE; + } + else if (!IsValidComInterfacePointer(pCreatedDevice, ComPtrValidation::ValidationMode::ForceRefresh)) + { + SString message; + message.Format("CProxyDirect3D9::CreateDevice - rejected invalid IDirect3DDevice9 pointer %p", pCreatedDevice); + AddReportLog(8755, message, 5); + ReleaseInterface(pCreatedDevice, 8755, "CProxyDirect3D9::CreateDevice invalid return"); + *ppReturnedDeviceInterface = nullptr; + hResult = D3DERR_INVALIDDEVICE; + } } // Store the rendering window in the direct 3d data @@ -233,7 +425,21 @@ HRESULT CProxyDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND CGraphics::GetSingleton().GetRenderItemManager()->SetDepthBufferFormat(ReadableDepthFormat); // Now create the proxy device. - *ppReturnedDeviceInterface = new CProxyDirect3DDevice9(*ppReturnedDeviceInterface); + IDirect3DDevice9* pOriginalDevice = *ppReturnedDeviceInterface; + *ppReturnedDeviceInterface = new CProxyDirect3DDevice9(pOriginalDevice); + if (pOriginalDevice) + { + if (IsValidComInterfacePointer(pOriginalDevice, ComPtrValidation::ValidationMode::ForceRefresh)) + { + pOriginalDevice->Release(); + } + else + { + SString message; + message.Format("CProxyDirect3D9::CreateDevice - skipping Release on invalid original device pointer %p", pOriginalDevice); + AddReportLog(8755, message, 5); + } + } // Debug output D3DDEVICE_CREATION_PARAMETERS parameters; @@ -246,6 +452,13 @@ HRESULT CProxyDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hResult = HandleCreateDeviceResult(hResult, m_pDevice, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); + // After successful device creation + if (SUCCEEDED(hResult) && *ppReturnedDeviceInterface) + { + // Check if we're in borderless mode + ApplyBorderlessColorCorrection(static_cast(*ppReturnedDeviceInterface), *pPresentationParameters); + } + return hResult; } @@ -316,10 +529,57 @@ namespace ms_strExtraLogBuffer += strText.Replace("\n", " ") + "\n"; WriteDebugEvent(strText); } - #define WriteDebugEvent WriteDebugEventTest +#define WriteDebugEvent WriteDebugEventTest uint ms_uiCreationAttempts = 0; -} // namespace +} // namespace + +void ApplyBorderlessColorCorrection(CProxyDirect3DDevice9* proxyDevice, const D3DPRESENT_PARAMETERS& presentationParameters) +{ + if (!proxyDevice) + return; + + bool bBorderless = false; + if (CVideoModeManagerInterface* videoModeManager = GetVideoModeManager()) + { + bBorderless = videoModeManager->IsDisplayModeWindowed() || videoModeManager->IsDisplayModeFullScreenWindow(); + } + else + { + bBorderless = (presentationParameters.Windowed != 0); + } + + float gammaPower = 1.0f; + float brightnessScale = 1.0f; + float contrastScale = 1.0f; + float saturationScale = 1.0f; + bool applyWindowed = true; + bool applyFullscreen = false; + BorderlessGamma::FetchSettings(gammaPower, brightnessScale, contrastScale, saturationScale, applyWindowed, applyFullscreen); + + const bool adjustmentsEnabled = bBorderless ? applyWindowed : applyFullscreen; + const bool hasAdjustments = adjustmentsEnabled && BorderlessGamma::ShouldApplyAdjustments(gammaPower, brightnessScale, contrastScale, saturationScale); + + if (!hasAdjustments) + { + proxyDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); + for (DWORD sampler = 0; sampler < 8; ++sampler) + { + proxyDevice->SetSamplerState(sampler, D3DSAMP_SRGBTEXTURE, FALSE); + } + if (bBorderless) + WriteDebugEvent("Cleared sRGB color correction for windowed/borderless mode"); + else + WriteDebugEvent("Cleared sRGB color correction for fullscreen mode"); + return; + } + + proxyDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, TRUE); + for (DWORD sampler = 0; sampler < 8; ++sampler) + { + proxyDevice->SetSamplerState(sampler, D3DSAMP_SRGBTEXTURE, TRUE); + } +} //////////////////////////////////////////////// // @@ -340,10 +600,23 @@ HRESULT CreateDeviceInsist(uint uiMinTries, uint uiTimeout, IDirect3D9* pDirect3 hResult = pDirect3D->CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); // Check if the result is correct (a custom d3d9.dll could return D3D_OK with a null pointer) - if (hResult == D3D_OK && *ppReturnedDeviceInterface == nullptr) + if (hResult == D3D_OK) { - WriteDebugEvent("CreateDeviceInsist: CreateDevice succeeded, but IDirect3DDevice9* is a nullptr"); - hResult = D3DERR_INVALIDDEVICE; + IDirect3DDevice9* pCreatedDevice = *ppReturnedDeviceInterface; + if (!pCreatedDevice) + { + AddReportLog(8755, SStringX("CreateDeviceInsist: driver returned nullptr device"), 5); + hResult = D3DERR_INVALIDDEVICE; + } + else if (!IsValidComInterfacePointer(pCreatedDevice, ComPtrValidation::ValidationMode::ForceRefresh)) + { + SString message; + message.Format("CreateDeviceInsist: rejected invalid IDirect3DDevice9 pointer %p", pCreatedDevice); + AddReportLog(8755, message, 5); + ReleaseInterface(pCreatedDevice, 8755, "CreateDeviceInsist invalid return"); + *ppReturnedDeviceInterface = nullptr; + hResult = D3DERR_INVALIDDEVICE; + } } if (hResult == D3D_OK) @@ -486,15 +759,15 @@ HRESULT DoCreateDevice(IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceTyp pPresentationParameters->SwapEffect = swapEffectList[iSwap]; pPresentationParameters->BackBufferFormat = format.rtFormatList[iRt]; pPresentationParameters->AutoDepthStencilFormat = format.depthFormatList[iDepth]; - #ifndef MTA_DEBUG +#ifndef MTA_DEBUG hResult = CreateDeviceInsist(2, 0, pDirect3D, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); - #else +#else WriteDebugEvent("--------------------------------"); WriteDebugEvent(ToString(Adapter, DeviceType, hFocusWindow, BehaviorFlags, *pPresentationParameters)); WriteDebugEvent(SString(" 32 result: %08x", hResult)); hResult = -1; - #endif +#endif if (hResult == D3D_OK) { WriteDebugEvent(SString(" Pass #4 SUCCESS with: {Res:%d, Color:%d, Refresh:%d}", iRes, iColor, iRefresh)); @@ -557,6 +830,22 @@ void AddCapsReport(UINT Adapter, IDirect3D9* pDirect3D, IDirect3DDevice9* pD3DDe { HRESULT hr; + if (!pDirect3D || !IsValidComInterfacePointer(pDirect3D, ComPtrValidation::ValidationMode::ForceRefresh)) + { + SString message; + message.Format("AddCapsReport: invalid IDirect3D9 pointer %p", pDirect3D); + AddReportLog(8748, message); + return; + } + + if (!pD3DDevice9 || !IsValidComInterfacePointer(pD3DDevice9, ComPtrValidation::ValidationMode::ForceRefresh)) + { + SString message; + message.Format("AddCapsReport: invalid IDirect3DDevice9 pointer %p", pD3DDevice9); + AddReportLog(8749, message); + return; + } + WriteDebugEvent(SString("ModuleFileName - %s ", *GetLaunchPathFilename())); // Get caps that GTA got @@ -569,21 +858,31 @@ void AddCapsReport(UINT Adapter, IDirect3D9* pDirect3D, IDirect3DDevice9* pD3DDe // Check device returns same D3D interface IDirect3D9* pDirect3DOther = NULL; pD3DDevice9->GetDirect3D(&pDirect3DOther); - if (pDirect3DOther != pDirect3D) + if (pDirect3DOther && !IsValidComInterfacePointer(pDirect3DOther, ComPtrValidation::ValidationMode::ForceRefresh)) + { + SString message; + message.Format("AddCapsReport: device returned invalid IDirect3D9 pointer %p", pDirect3DOther); + AddReportLog(8753, message, 5); + } + else if (pDirect3DOther != pDirect3D) { WriteDebugEvent(SString("IDirect3D9 differs: %x %x", pDirect3D, pDirect3DOther)); if (pDirect3DOther) { // Log graphic card name - D3DADAPTER_IDENTIFIER9 AdapterIdent1; - pDirect3D->GetAdapterIdentifier(Adapter, 0, &AdapterIdent1); + D3DADAPTER_IDENTIFIER9 AdapterIdent1{}; + hr = pDirect3D->GetAdapterIdentifier(Adapter, 0, &AdapterIdent1); + if (FAILED(hr)) + WriteDebugEvent(SString("Warning: pDirect3D->GetAdapterIdentifier failed: %08x", hr)); WriteDebugEvent("pDirect3D:"); WriteDebugEvent(ToString(AdapterIdent1)); // Log graphic card name - D3DADAPTER_IDENTIFIER9 AdapterIdent2; - pDirect3DOther->GetAdapterIdentifier(Adapter, 0, &AdapterIdent2); + D3DADAPTER_IDENTIFIER9 AdapterIdent2{}; + hr = pDirect3DOther->GetAdapterIdentifier(Adapter, 0, &AdapterIdent2); + if (FAILED(hr)) + WriteDebugEvent(SString("Warning: pDirect3DOther->GetAdapterIdentifier failed: %08x", hr)); WriteDebugEvent("pDirect3DOther:"); WriteDebugEvent(ToString(AdapterIdent2)); @@ -594,7 +893,7 @@ void AddCapsReport(UINT Adapter, IDirect3D9* pDirect3D, IDirect3DDevice9* pD3DDe } } - SAFE_RELEASE(pDirect3DOther); + ReleaseInterface(pDirect3DOther, 8799, "AddCapsReport GetDirect3D"); // Get caps from D3D D3DCAPS9 D3DCaps9; @@ -626,9 +925,9 @@ void AddCapsReport(UINT Adapter, IDirect3D9* pDirect3D, IDirect3DDevice9* pD3DDe // Try create D3DVERTEXELEMENT9 VertexElements[] = {{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}; VertexElements[0].Type = DeclTypesList[i].VertexType; - IDirect3DVertexDeclaration9* pD3DVertexDecl; + IDirect3DVertexDeclaration9* pD3DVertexDecl = nullptr; hr = pD3DDevice9->CreateVertexDeclaration(VertexElements, &pD3DVertexDecl); - SAFE_RELEASE(pD3DVertexDecl); + ReleaseInterface(pD3DVertexDecl, 8799, "AddCapsReport CreateVertexDeclaration"); // Check against device caps bool bCapsSaysOk = (DeviceCaps9.DeclTypes & DeclTypesList[i].CapsType) ? true : false; @@ -678,7 +977,7 @@ void AddCapsReport(UINT Adapter, IDirect3D9* pDirect3D, IDirect3DDevice9* pD3DDe else { WriteDebugEvent("Fixing GTA caps"); - memcpy(pGTACaps9, &DeviceCaps9, sizeof(D3DCAPS9)); + *pGTACaps9 = DeviceCaps9; } } } @@ -694,21 +993,30 @@ void AddCapsReport(UINT Adapter, IDirect3D9* pDirect3D, IDirect3DDevice9* pD3DDe bool CreateDeviceSecondCallCheck(HRESULT& hOutResult, IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface) { - static uint uiCreateCount = 0; + static uint uiCreateCount = 0; + static IDirect3D9* lastTrackedInterface = nullptr; - // Also check for invalid size - if (pPresentationParameters->BackBufferWidth == 0) + if (!IsMainThread()) { - WriteDebugEvent(SString(" Passing through call #%d to CreateDevice because size is invalid", uiCreateCount)); + SString strMessage; + strMessage = " Passing through CreateDevice because not main thread"; + WriteDebugEvent(strMessage); + AddReportLog(8627, strMessage); + hOutResult = pDirect3D->CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); return true; } - // Also check for calls from other threads - if (!IsMainThread()) + if (pDirect3D != lastTrackedInterface) { - SString strMessage(" Passing through call #%d to CreateDevice because not main thread", uiCreateCount); - WriteDebugEvent(strMessage); - AddReportLog(8627, strMessage); + lastTrackedInterface = pDirect3D; + uiCreateCount = 0; + } + + // Also check for invalid size + if (pPresentationParameters->BackBufferWidth == 0) + { + WriteDebugEvent(SString(" Passing through call #%d to CreateDevice because size is invalid", uiCreateCount)); + hOutResult = pDirect3D->CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); return true; } @@ -730,11 +1038,13 @@ HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Ad D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface) { // Log graphic card name - D3DADAPTER_IDENTIFIER9 AdapterIdent; - pDirect3D->GetAdapterIdentifier(Adapter, 0, &AdapterIdent); + D3DADAPTER_IDENTIFIER9 AdapterIdent{}; + HRESULT hr = pDirect3D->GetAdapterIdentifier(Adapter, 0, &AdapterIdent); + if (FAILED(hr)) + WriteDebugEvent(SString("Warning: GetAdapterIdentifier failed: %08x", hr)); WriteDebugEvent(ToString(AdapterIdent)); - uint uiCurrentStatus = 0; // 0-unknown 1-fail 2-success after retry 3-success + uint uiCurrentStatus = 0; // 0-unknown 1-fail 2-success after retry 3-success if (hResult == D3D_OK) { @@ -753,10 +1063,23 @@ HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Ad hResult = DoCreateDevice(pDirect3D, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); // Check if the result is correct (a custom d3d9.dll could return D3D_OK with a null pointer) - if (hResult == D3D_OK && *ppReturnedDeviceInterface == nullptr) + if (hResult == D3D_OK) { - WriteDebugEvent("HandleCreateDeviceResult: DoCreateDevice succeeded, but IDirect3DDevice9* is a nullptr"); - hResult = D3DERR_INVALIDDEVICE; + IDirect3DDevice9* pCreatedDevice = *ppReturnedDeviceInterface; + if (!pCreatedDevice) + { + AddReportLog(8755, SStringX("HandleCreateDeviceResult: DoCreateDevice returned nullptr device"), 5); + hResult = D3DERR_INVALIDDEVICE; + } + else if (!IsValidComInterfacePointer(pCreatedDevice, ComPtrValidation::ValidationMode::ForceRefresh)) + { + SString message; + message.Format("HandleCreateDeviceResult: rejected invalid IDirect3DDevice9 pointer %p", pCreatedDevice); + AddReportLog(8755, message, 5); + ReleaseInterface(pCreatedDevice, 8755, "HandleCreateDeviceResult invalid return"); + *ppReturnedDeviceInterface = nullptr; + hResult = D3DERR_INVALIDDEVICE; + } } // Handle retry result @@ -784,7 +1107,21 @@ HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Ad CGraphics::GetSingleton().GetRenderItemManager()->SetDepthBufferFormat(ReadableDepthFormat); // Now create the proxy device. - *ppReturnedDeviceInterface = new CProxyDirect3DDevice9(*ppReturnedDeviceInterface); + IDirect3DDevice9* pOriginalDevice = *ppReturnedDeviceInterface; + *ppReturnedDeviceInterface = new CProxyDirect3DDevice9(pOriginalDevice); + if (pOriginalDevice) + { + if (IsValidComInterfacePointer(pOriginalDevice, ComPtrValidation::ValidationMode::ForceRefresh)) + { + pOriginalDevice->Release(); + } + else + { + SString message; + message.Format("HandleCreateDeviceResult: skipping Release on invalid original device pointer %p", pOriginalDevice); + AddReportLog(8755, message, 5); + } + } // Debug output D3DDEVICE_CREATION_PARAMETERS parameters; @@ -792,6 +1129,8 @@ HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Ad WriteDebugEvent(SString(" Adapter:%d DeviceType:%d BehaviorFlags:0x%x ReadableDepth:%s", parameters.AdapterOrdinal, parameters.DeviceType, parameters.BehaviorFlags, ReadableDepthFormat ? std::string((char*)&ReadableDepthFormat, 4).c_str() : "None")); + + ApplyBorderlessColorCorrection(static_cast(*ppReturnedDeviceInterface), *pPresentationParameters); } } @@ -801,9 +1140,9 @@ HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Ad // Calc log level to use uint uiDiagnosticLogLevel = 0; if (uiLastStatus == CREATE_DEVICE_FAIL && uiCurrentStatus != CREATE_DEVICE_FAIL) - uiDiagnosticLogLevel = 1; // Log and continue - If changing from fail status + uiDiagnosticLogLevel = 1; // Log and continue - If changing from fail status if (uiCurrentStatus == CREATE_DEVICE_FAIL) - uiDiagnosticLogLevel = 2; // Log and wait - If fail status + uiDiagnosticLogLevel = 2; // Log and wait - If fail status bool bDetectOptimus = (GetModuleHandle("nvd3d9wrap.dll") != NULL); @@ -817,6 +1156,14 @@ HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Ad AddCapsReport(Adapter, pDirect3D, *ppReturnedDeviceInterface, bFixCaps); + // Get current refresh rate and set it + if (hResult == D3D_OK) + { + D3DDISPLAYMODE DisplayMode; + if (pDirect3D->GetAdapterDisplayMode(Adapter, &DisplayMode) == D3D_OK) + CCore::GetSingleton().SetCurrentRefreshRate(DisplayMode.RefreshRate); + } + if (uiDiagnosticLogLevel) { // Prevent statup warning in loader @@ -833,13 +1180,6 @@ HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Ad strMessage += SString("Direct3D CreateDevice error: %08x", hResult); BrowseToSolution("d3dcreatedevice-fail", EXIT_GAME_FIRST | ASK_GO_ONLINE, strMessage); } - else - { - // Get current refresh rate - D3DDISPLAYMODE DisplayMode; - if (pDirect3D->GetAdapterDisplayMode(Adapter, &DisplayMode) == D3D_OK) - CCore::GetSingleton().SetCurrentRefreshRate(DisplayMode.RefreshRate); - } return hResult; } @@ -848,7 +1188,7 @@ namespace { DWORD BehaviorFlagsOrig = 0; D3DPRESENT_PARAMETERS presentationParametersOrig; -} // namespace +} // namespace //////////////////////////////////////////////// // @@ -876,7 +1216,7 @@ void CCore::OnPreCreateDevice(IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE De WriteDebugEvent(ToString(Adapter, DeviceType, hFocusWindow, BehaviorFlags, *pPresentationParameters)); IDirect3DDevice9* pReturnedDeviceInterface = NULL; HRESULT hResult = pDirect3D->CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, &pReturnedDeviceInterface); - SAFE_RELEASE(pReturnedDeviceInterface); + ReleaseInterface(pReturnedDeviceInterface, 8799, "CCore::OnPreCreateDevice temp release"); WriteDebugEvent(SString(" Unmodified result is: %08x", hResult)); } @@ -910,7 +1250,37 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface) { if (!UsingAltD3DSetup()) - return D3D_OK; + return hResult; + + if (!ppReturnedDeviceInterface) + { + AddReportLog(8744, SStringX("CCore::OnPostCreateDevice - missing ppReturnedDeviceInterface pointer")); + return hResult; + } + + if (!SharedUtil::IsReadablePointer(ppReturnedDeviceInterface, sizeof(*ppReturnedDeviceInterface))) + { + SString message; + message.Format("CCore::OnPostCreateDevice - invalid ppReturnedDeviceInterface pointer %p", ppReturnedDeviceInterface); + AddReportLog(8745, message); + return hResult; + } + + if (!*ppReturnedDeviceInterface) + { + AddReportLog(8746, SStringX("CCore::OnPostCreateDevice - ppReturnedDeviceInterface dereferenced to nullptr")); + return hResult; + } + + if (!IsValidComInterfacePointer(*ppReturnedDeviceInterface, ComPtrValidation::ValidationMode::ForceRefresh)) + { + SString message; + message.Format("CCore::OnPostCreateDevice - invalid IDirect3DDevice9 pointer %p (via %p)", *ppReturnedDeviceInterface, ppReturnedDeviceInterface); + AddReportLog(8747, message); + return hResult; + } + + IDirect3DDevice9* pDevice = *ppReturnedDeviceInterface; // // - Allow create device with no changes @@ -924,9 +1294,10 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A else WriteDebugEvent("Initial CreateDevice succeeded"); - AddCapsReport(Adapter, pDirect3D, *ppReturnedDeviceInterface, false); + AddCapsReport(Adapter, pDirect3D, pDevice, false); - SAFE_RELEASE(*ppReturnedDeviceInterface); + ReleaseInterface(pDevice, 8799, "CCore::OnPostCreateDevice temp release"); + *ppReturnedDeviceInterface = pDevice; // // - Create device with required changes @@ -955,10 +1326,21 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A hResult = CreateDeviceInsist(2, 1000, pDirect3D, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); // Check if the result is correct (a custom d3d9.dll could return D3D_OK with a null pointer) - if (hResult == D3D_OK && *ppReturnedDeviceInterface == nullptr) + if (hResult == D3D_OK) { - WriteDebugEvent("CCore::OnPostCreateDevice: CreateDeviceInsist succeeded, but IDirect3DDevice9* is a nullptr"); - hResult = D3DERR_INVALIDDEVICE; + IDirect3DDevice9* pCreatedDevice = *ppReturnedDeviceInterface; + if (!pCreatedDevice) + { + AddReportLog(8755, "CCore::OnPostCreateDevice: CreateDeviceInsist returned nullptr device", 5); + hResult = D3DERR_INVALIDDEVICE; + } + else if (!IsValidComInterfacePointer(pCreatedDevice, ComPtrValidation::ValidationMode::ForceRefresh)) + { + AddReportLog(8755, SString("CCore::OnPostCreateDevice: rejected invalid IDirect3DDevice9 pointer %p", pCreatedDevice), 5); + ReleaseInterface(pCreatedDevice, 8755, "CCore::OnPostCreateDevice invalid return"); + *ppReturnedDeviceInterface = nullptr; + hResult = D3DERR_INVALIDDEVICE; + } } if (hResult != D3D_OK) @@ -966,18 +1348,21 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A else WriteDebugEvent("MTA CreateDevice succeeded"); - AddCapsReport(Adapter, pDirect3D, *ppReturnedDeviceInterface, true); + if (hResult == D3D_OK) + AddCapsReport(Adapter, pDirect3D, *ppReturnedDeviceInterface, true); - // Change the window title to MTA: San Andreas - #ifdef MTA_DEBUG +// Change the window title to MTA: San Andreas +#ifdef MTA_DEBUG SetWindowTextW(hFocusWindow, MbUTF8ToUTF16("MTA: San Andreas [DEBUG]").c_str()); - #else +#else SetWindowTextW(hFocusWindow, MbUTF8ToUTF16("MTA: San Andreas").c_str()); - #endif +#endif // Log graphic card name - D3DADAPTER_IDENTIFIER9 AdapterIdent; - pDirect3D->GetAdapterIdentifier(Adapter, 0, &AdapterIdent); + D3DADAPTER_IDENTIFIER9 AdapterIdent{}; + HRESULT hr = pDirect3D->GetAdapterIdentifier(Adapter, 0, &AdapterIdent); + if (FAILED(hr)) + WriteDebugEvent(SString("Warning: GetAdapterIdentifier failed: %08x", hr)); WriteDebugEvent(ToString(AdapterIdent)); // Store the rendering window in the direct 3d data @@ -1001,7 +1386,19 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A CGraphics::GetSingleton().GetRenderItemManager()->SetDepthBufferFormat(ReadableDepthFormat); // Now create the proxy device. - *ppReturnedDeviceInterface = new CProxyDirect3DDevice9(*ppReturnedDeviceInterface); + IDirect3DDevice9* pOriginalDevice = *ppReturnedDeviceInterface; + *ppReturnedDeviceInterface = new CProxyDirect3DDevice9(pOriginalDevice); + if (pOriginalDevice) + { + if (IsValidComInterfacePointer(pOriginalDevice, ComPtrValidation::ValidationMode::ForceRefresh)) + { + pOriginalDevice->Release(); + } + else + { + AddReportLog(8755, SString("CCore::OnPostCreateDevice - skipping Release on invalid original device pointer %p", pOriginalDevice), 5); + } + } // Debug output D3DDEVICE_CREATION_PARAMETERS parameters; @@ -1010,6 +1407,8 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A WriteDebugEvent(" Used creation parameters:"); WriteDebugEvent(SString(" Adapter:%d DeviceType:%d BehaviorFlags:0x%x ReadableDepth:%s", parameters.AdapterOrdinal, parameters.DeviceType, parameters.BehaviorFlags, ReadableDepthFormat ? std::string((char*)&ReadableDepthFormat, 4).c_str() : "None")); + + ApplyBorderlessColorCorrection(static_cast(*ppReturnedDeviceInterface), *pPresentationParameters); } bool bDetectOptimus = (GetModuleHandle("nvd3d9wrap.dll") != NULL); @@ -1017,9 +1416,9 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A // Calc log level to use uint uiDiagnosticLogLevel = 0; if (GetApplicationSettingInt("nvhacks", "optimus") || bDetectOptimus) - uiDiagnosticLogLevel = 1; // Log and continue + uiDiagnosticLogLevel = 1; // Log and continue if (hResult != D3D_OK) - uiDiagnosticLogLevel = 2; // Log and wait - If fail status + uiDiagnosticLogLevel = 2; // Log and wait - If fail status // Do diagnostic log now if needed if (uiDiagnosticLogLevel) diff --git a/Client/core/DXHook/CProxyDirect3D9.h b/Client/core/DXHook/CProxyDirect3D9.h index ab782208c85..8251bc58b18 100644 --- a/Client/core/DXHook/CProxyDirect3D9.h +++ b/Client/core/DXHook/CProxyDirect3D9.h @@ -21,32 +21,33 @@ class CProxyDirect3D9 : public IDirect3D9 ~CProxyDirect3D9(); /*** IUnknown methods ***/ virtual HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - virtual ULONG __stdcall AddRef(); - virtual ULONG __stdcall Release(); + virtual ULONG __stdcall AddRef(); + virtual ULONG __stdcall Release(); /*** IDirect3D9 methods ***/ - virtual HRESULT __stdcall RegisterSoftwareDevice(void* pInitializeFunction); - virtual UINT __stdcall GetAdapterCount(); - virtual HRESULT __stdcall GetAdapterIdentifier(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier); - virtual UINT __stdcall GetAdapterModeCount(UINT Adapter, D3DFORMAT Format); - virtual HRESULT __stdcall EnumAdapterModes(UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode); - virtual HRESULT __stdcall GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE* pMode); - virtual HRESULT __stdcall CheckDeviceType(UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed); - virtual HRESULT __stdcall CheckDeviceFormat(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, - D3DFORMAT CheckFormat); - virtual HRESULT __stdcall CheckDeviceMultiSampleType(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, - D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels); - virtual HRESULT __stdcall CheckDepthStencilMatch(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, - D3DFORMAT DepthStencilFormat); - virtual HRESULT __stdcall CheckDeviceFormatConversion(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat); - virtual HRESULT __stdcall GetDeviceCaps(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps); + virtual HRESULT __stdcall RegisterSoftwareDevice(void* pInitializeFunction); + virtual UINT __stdcall GetAdapterCount(); + virtual HRESULT __stdcall GetAdapterIdentifier(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier); + virtual UINT __stdcall GetAdapterModeCount(UINT Adapter, D3DFORMAT Format); + virtual HRESULT __stdcall EnumAdapterModes(UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode); + virtual HRESULT __stdcall GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE* pMode); + virtual HRESULT __stdcall CheckDeviceType(UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed); + virtual HRESULT __stdcall CheckDeviceFormat(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, + D3DFORMAT CheckFormat); + virtual HRESULT __stdcall CheckDeviceMultiSampleType(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, + D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels); + virtual HRESULT __stdcall CheckDepthStencilMatch(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, + D3DFORMAT DepthStencilFormat); + virtual HRESULT __stdcall CheckDeviceFormatConversion(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat); + virtual HRESULT __stdcall GetDeviceCaps(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps); virtual HMONITOR __stdcall GetAdapterMonitor(UINT Adapter); - virtual HRESULT __stdcall CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, - D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface); + virtual HRESULT __stdcall CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, + D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface); static HMONITOR StaticGetAdapterMonitor(UINT Adapter); static IDirect3D9* StaticGetDirect3D(); private: - IDirect3D9* m_pDevice; + IDirect3D9* m_pDevice; + std::atomic m_lRefCount; }; diff --git a/Client/core/DXHook/CProxyDirect3DDevice9.cpp b/Client/core/DXHook/CProxyDirect3DDevice9.cpp index 852ac0f7a41..453104bbe7d 100644 --- a/Client/core/DXHook/CProxyDirect3DDevice9.cpp +++ b/Client/core/DXHook/CProxyDirect3DDevice9.cpp @@ -10,122 +10,620 @@ *****************************************************************************/ #include "StdInc.h" +#include "CProxyComHelpers.h" +#include "ComPtrValidation.h" +#include +#include +#include +#include +#include +#include #include -bool g_bInGTAScene = false; +struct CProxyDirect3DDevice9; +extern std::atomic g_bInMTAScene; + +void ApplyBorderlessColorCorrection(CProxyDirect3DDevice9* proxyDevice, const D3DPRESENT_PARAMETERS& presentationParameters); + +namespace +{ + // SEH filter for pDevice->Reset(). Mirrors FilterException in CDirect3DEvents9.cpp. + // Stores the exception code for OnCrashAverted ID encoding and flags hardware + // faults so callers can break out of retry loops that won't recover. + uint uiLastResetExceptionCode = 0; + bool bResetHardwareFault = false; + + int FilterResetException(uint exceptionCode) + { + uiLastResetExceptionCode = exceptionCode; + bResetHardwareFault = false; + + if (exceptionCode == EXCEPTION_ACCESS_VIOLATION) + return EXCEPTION_EXECUTE_HANDLER; + if (exceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION || exceptionCode == EXCEPTION_PRIV_INSTRUCTION) + { + bResetHardwareFault = true; + char buf[80]; + _snprintf_s(buf, _countof(buf), _TRUNCATE, "FilterResetException: caught instruction fault %08x", exceptionCode); + WriteDebugEvent(buf); + return EXCEPTION_EXECUTE_HANDLER; + } + if (exceptionCode == EXCEPTION_IN_PAGE_ERROR) + { + bResetHardwareFault = true; + WriteDebugEvent("FilterResetException: caught in-page error"); + return EXCEPTION_EXECUTE_HANDLER; + } + if (exceptionCode == 0xE06D7363) // Microsoft C++ exception + { + WriteDebugEvent("FilterResetException: caught Microsoft C++ exception"); + return EXCEPTION_EXECUTE_HANDLER; + } + return EXCEPTION_CONTINUE_SEARCH; + } +} // unnamed namespace + +namespace BorderlessGamma +{ + const float kGammaMin = 0.5f; + const float kGammaMax = 2.0f; + const float kBrightnessMin = 0.5f; + const float kBrightnessMax = 2.0f; + const float kContrastMin = 0.5f; + const float kContrastMax = 2.0f; + const float kSaturationMin = 0.5f; + const float kSaturationMax = 2.0f; + + // Cache CVAR-derived values to avoid repeated string lookups on every frame. + struct CachedSettings + { + std::mutex updateMutex; + std::atomic revision; + std::atomic source; + std::atomic gammaPower; + std::atomic brightnessScale; + std::atomic contrastScale; + std::atomic saturationScale; + std::atomic gammaEnabled; + std::atomic brightnessEnabled; + std::atomic contrastEnabled; + std::atomic saturationEnabled; + std::atomic applyWindowed; + std::atomic applyFullscreen; + + CachedSettings() + : revision(-1), + source(nullptr), + gammaPower(1.0f), + brightnessScale(1.0f), + contrastScale(1.0f), + saturationScale(1.0f), + gammaEnabled(false), + brightnessEnabled(false), + contrastEnabled(false), + saturationEnabled(false), + applyWindowed(false), + applyFullscreen(false) + { + } + }; + + static CachedSettings g_cachedSettings; + + void RefreshCacheIfNeeded() + { + CClientVariables* cvars = CClientVariables::GetSingletonPtr(); + const CClientVariables* currentSource = cvars; + const int currentRevision = cvars ? cvars->GetRevision() : -1; + + const CClientVariables* cachedSource = g_cachedSettings.source.load(std::memory_order_relaxed); + const int cachedRevision = g_cachedSettings.revision.load(std::memory_order_relaxed); + + if (cachedSource == currentSource && cachedRevision == currentRevision) + return; + + std::lock_guard guard(g_cachedSettings.updateMutex); + + const CClientVariables* doubleCheckSource = g_cachedSettings.source.load(std::memory_order_relaxed); + const int doubleCheckRevision = g_cachedSettings.revision.load(std::memory_order_relaxed); + if (doubleCheckSource == currentSource && doubleCheckRevision == currentRevision) + return; + + float gammaPower = 1.0f; + float brightnessScale = 1.0f; + float contrastScale = 1.0f; + float saturationScale = 1.0f; + bool gammaEnabled = false; + bool brightnessEnabled = false; + bool contrastEnabled = false; + bool saturationEnabled = false; + bool applyWindowed = false; + bool applyFullscreen = false; + + if (cvars) + { + cvars->Get("borderless_gamma_power", gammaPower); + cvars->Get("borderless_brightness_scale", brightnessScale); + cvars->Get("borderless_contrast_scale", contrastScale); + cvars->Get("borderless_saturation_scale", saturationScale); + cvars->Get("borderless_gamma_enabled", gammaEnabled); + cvars->Get("borderless_brightness_enabled", brightnessEnabled); + cvars->Get("borderless_contrast_enabled", contrastEnabled); + cvars->Get("borderless_saturation_enabled", saturationEnabled); + cvars->Get("borderless_apply_windowed", applyWindowed); + cvars->Get("borderless_apply_fullscreen", applyFullscreen); + + if (!cvars->Exists("borderless_apply_windowed")) + { + bool legacyEnable = false; + cvars->Get("borderless_enable_srgb", legacyEnable); + applyWindowed = legacyEnable; + } + + if (!std::isfinite(gammaPower)) + gammaPower = 1.0f; + if (!std::isfinite(brightnessScale)) + brightnessScale = 1.0f; + if (!std::isfinite(contrastScale)) + contrastScale = 1.0f; + if (!std::isfinite(saturationScale)) + saturationScale = 1.0f; + + gammaPower = std::clamp(gammaPower, kGammaMin, kGammaMax); + brightnessScale = std::clamp(brightnessScale, kBrightnessMin, kBrightnessMax); + contrastScale = std::clamp(contrastScale, kContrastMin, kContrastMax); + saturationScale = std::clamp(saturationScale, kSaturationMin, kSaturationMax); + } + + g_cachedSettings.gammaPower.store(gammaPower, std::memory_order_relaxed); + g_cachedSettings.brightnessScale.store(brightnessScale, std::memory_order_relaxed); + g_cachedSettings.contrastScale.store(contrastScale, std::memory_order_relaxed); + g_cachedSettings.saturationScale.store(saturationScale, std::memory_order_relaxed); + g_cachedSettings.gammaEnabled.store(gammaEnabled, std::memory_order_relaxed); + g_cachedSettings.brightnessEnabled.store(brightnessEnabled, std::memory_order_relaxed); + g_cachedSettings.contrastEnabled.store(contrastEnabled, std::memory_order_relaxed); + g_cachedSettings.saturationEnabled.store(saturationEnabled, std::memory_order_relaxed); + g_cachedSettings.applyWindowed.store(applyWindowed, std::memory_order_relaxed); + g_cachedSettings.applyFullscreen.store(applyFullscreen, std::memory_order_relaxed); + g_cachedSettings.source.store(currentSource, std::memory_order_relaxed); + g_cachedSettings.revision.store(currentRevision, std::memory_order_release); + } + + void FetchSettings(float& gammaPower, float& brightnessScale, float& contrastScale, float& saturationScale, bool& applyWindowed, bool& applyFullscreen) + { + RefreshCacheIfNeeded(); + + const float cachedGammaPower = g_cachedSettings.gammaPower.load(std::memory_order_acquire); + const float cachedBrightness = g_cachedSettings.brightnessScale.load(std::memory_order_acquire); + const float cachedContrast = g_cachedSettings.contrastScale.load(std::memory_order_acquire); + const float cachedSaturation = g_cachedSettings.saturationScale.load(std::memory_order_acquire); + const bool gammaEnabled = g_cachedSettings.gammaEnabled.load(std::memory_order_acquire); + const bool brightnessEnabled = g_cachedSettings.brightnessEnabled.load(std::memory_order_acquire); + const bool contrastEnabled = g_cachedSettings.contrastEnabled.load(std::memory_order_acquire); + const bool saturationEnabled = g_cachedSettings.saturationEnabled.load(std::memory_order_acquire); + + gammaPower = gammaEnabled ? cachedGammaPower : 1.0f; + brightnessScale = brightnessEnabled ? cachedBrightness : 1.0f; + contrastScale = contrastEnabled ? cachedContrast : 1.0f; + saturationScale = saturationEnabled ? cachedSaturation : 1.0f; + + applyWindowed = g_cachedSettings.applyWindowed.load(std::memory_order_acquire); + applyFullscreen = g_cachedSettings.applyFullscreen.load(std::memory_order_acquire); + } + + bool ShouldApplyAdjustments(float gammaPower, float brightnessScale, float contrastScale, float saturationScale) + { + constexpr float epsilon = 0.001f; + return std::fabs(gammaPower - 1.0f) > epsilon || std::fabs(brightnessScale - 1.0f) > epsilon || std::fabs(contrastScale - 1.0f) > epsilon || + std::fabs(saturationScale - 1.0f) > epsilon; + } + +} // namespace BorderlessGamma + +using namespace BorderlessGamma; +std::mutex g_proxyDeviceMutex; +std::mutex g_gammaStateMutex; +std::mutex g_deviceStateMutex; +std::atomic g_proxyRegistrationCounter{0}; +std::atomic g_gtaSceneActiveCount{0}; +uint64_t g_activeProxyRegistrationId = 0; + +std::atomic g_bInGTAScene{false}; CProxyDirect3DDevice9* g_pProxyDevice = NULL; CProxyDirect3DDevice9::SD3DDeviceState* g_pDeviceState = NULL; +SGammaState g_GammaState; + +CProxyDirect3DDevice9::SMemoryState g_StaticMemoryState; + +thread_local bool g_bSuspendDeviceStateCache{false}; +thread_local uint g_uiSuspendDepth{0}; + +bool ShouldUpdateDeviceStateCache() +{ + if (g_bSuspendDeviceStateCache) + return false; + if (g_bInGTAScene.load(std::memory_order_acquire)) + return true; + return !g_bInMTAScene.load(std::memory_order_acquire); +} + +void SetSuspendDeviceStateCache(bool bSuspend) +{ + if (bSuspend) + { + g_uiSuspendDepth++; + g_bSuspendDeviceStateCache = true; + } + else + { + if (g_uiSuspendDepth > 0) + g_uiSuspendDepth--; + g_bSuspendDeviceStateCache = (g_uiSuspendDepth > 0); + } +} + +namespace +{ + uint64_t RegisterProxyDevice(CProxyDirect3DDevice9* instance) + { + std::lock_guard guard(g_proxyDeviceMutex); + const uint64_t registrationId = g_proxyRegistrationCounter.fetch_add(1, std::memory_order_relaxed) + 1; + g_pProxyDevice = instance; + g_activeProxyRegistrationId = registrationId; + { + std::lock_guard stateGuard(g_deviceStateMutex); + g_pDeviceState = instance ? &instance->DeviceState : nullptr; + } + return registrationId; + } + + bool UnregisterProxyDevice(CProxyDirect3DDevice9* instance, uint64_t registrationId) + { + std::lock_guard guard(g_proxyDeviceMutex); + if (g_pProxyDevice != instance) + return false; + + if (g_activeProxyRegistrationId != registrationId) + return false; + + g_pProxyDevice = nullptr; + g_activeProxyRegistrationId = 0; + { + std::lock_guard stateGuard(g_deviceStateMutex); + g_pDeviceState = nullptr; + } + return true; + } +} // namespace + +void IncrementGTASceneState() +{ + // Lockless atomic increment (called on every BeginScene) + g_gtaSceneActiveCount.fetch_add(1, std::memory_order_relaxed); + g_bInGTAScene.store(true, std::memory_order_release); +} + +void DecrementGTASceneState() +{ + // Prevent underflow if BeginScene failed but EndScene still called + uint expected = g_gtaSceneActiveCount.load(std::memory_order_acquire); + while (expected > 0) + { + if (g_gtaSceneActiveCount.compare_exchange_weak(expected, expected - 1, std::memory_order_acq_rel, std::memory_order_acquire)) + { + g_bInGTAScene.store(expected > 1, std::memory_order_release); + return; + } + } + g_bInGTAScene.store(false, std::memory_order_release); +} + +void ResetGTASceneState() +{ + // Lockless atomic reset + g_gtaSceneActiveCount.store(0, std::memory_order_relaxed); + g_bInGTAScene.store(false, std::memory_order_release); +} // Proxy constructor and destructor. +// Constructor performs heavy initialization; defer global registration until the end to avoid exposing a partially built object. CProxyDirect3DDevice9::CProxyDirect3DDevice9(IDirect3DDevice9* pDevice) -{ - WriteDebugEvent(SString("CProxyDirect3DDevice9::CProxyDirect3DDevice9 %08x (device: %08x)", this, pDevice)); + : m_pDevice(pDevice), + m_pData(nullptr), + m_lRefCount(1), + m_deviceRefCount(0), + m_bBeginSceneSuccess(false), + m_registrationToken(0), + m_lastTestCooperativeLevelResult(D3D_OK) +{ + struct DeviceRefGuard + { + IDirect3DDevice9* device; + bool active; + DeviceRefGuard(IDirect3DDevice9* d) : device(d), active(true) {} + ~DeviceRefGuard() + { + if (active && device) + device->Release(); + } + void Dismiss() { active = false; } + } deviceGuard(m_pDevice); - // Set our wrapped device. - m_pDevice = pDevice; + if (m_pDevice) + { + m_pDevice->AddRef(); + m_deviceRefCount.fetch_add(1, std::memory_order_relaxed); + } - // Get CDirect3DData pointer. m_pData = CDirect3DData::GetSingletonPtr(); - g_pProxyDevice = this; - g_pDeviceState = &DeviceState; - pDevice->GetDeviceCaps(&g_pDeviceState->DeviceCaps); + if (m_pDevice) + { + m_pDevice->GetDeviceCaps(&DeviceState.DeviceCaps); - // - // Get video card installed memory - // - D3DDEVICE_CREATION_PARAMETERS creationParameters; - m_pDevice->GetCreationParameters(&creationParameters); - int iAdapter = creationParameters.AdapterOrdinal; + D3DDEVICE_CREATION_PARAMETERS creationParameters; + m_pDevice->GetCreationParameters(&creationParameters); + int iAdapter = creationParameters.AdapterOrdinal; - IDirect3D9* pD3D9 = CProxyDirect3D9::StaticGetDirect3D(); - if (!pD3D9) - m_pDevice->GetDirect3D(&pD3D9); + IDirect3D9* pD3D9 = CProxyDirect3D9::StaticGetDirect3D(); + bool bNeedRelease = false; + if (!pD3D9) + { + m_pDevice->GetDirect3D(&pD3D9); + bNeedRelease = true; // GetDirect3D increments reference count + } - D3DADAPTER_IDENTIFIER9 adaptIdent; - ZeroMemory(&adaptIdent, sizeof(D3DADAPTER_IDENTIFIER9)); - pD3D9->GetAdapterIdentifier(iAdapter, 0, &adaptIdent); + if (pD3D9) + { + D3DADAPTER_IDENTIFIER9 adaptIdent; + HRESULT hr = pD3D9->GetAdapterIdentifier(iAdapter, 0, &adaptIdent); - int iVideoCardMemoryKBTotal = GetWMIVideoAdapterMemorySize(adaptIdent.VendorId, adaptIdent.DeviceId) / 1024; + if (SUCCEEDED(hr)) + { + // GetAdapterIdentifier succeeded - use adapter info + int iVideoCardMemoryKBTotal = GetWMIVideoAdapterMemorySize(adaptIdent.VendorId, adaptIdent.DeviceId) / 1024; - // Just incase, fallback to using texture memory stats - if (iVideoCardMemoryKBTotal < 16) - iVideoCardMemoryKBTotal = m_pDevice->GetAvailableTextureMem() / 1024; + // Just incase, fallback to using texture memory stats + if (iVideoCardMemoryKBTotal < 16) + iVideoCardMemoryKBTotal = m_pDevice->GetAvailableTextureMem() / 1024; - g_pDeviceState->AdapterState.InstalledMemoryKB = iVideoCardMemoryKBTotal; + DeviceState.AdapterState.InstalledMemoryKB = iVideoCardMemoryKBTotal; - // - // Get video card name - // - g_pDeviceState->AdapterState.Name = adaptIdent.Description; + // Get video card name + DeviceState.AdapterState.Name = adaptIdent.Description; - // - // Get max anisotropic setting - // - g_pDeviceState->AdapterState.MaxAnisotropicSetting = 0; + // Clipping is required for some graphic configurations - use direct C-string search to avoid heap allocation + DeviceState.AdapterState.bRequiresClipping = (strstr(adaptIdent.Description, "Intel") != nullptr); + } + else + { + // GetAdapterIdentifier failed - use defaults + DeviceState.AdapterState.InstalledMemoryKB = m_pDevice->GetAvailableTextureMem() / 1024; + DeviceState.AdapterState.Name = "Unknown"; + DeviceState.AdapterState.bRequiresClipping = false; + } - // Make sure device can do anisotropic minification and trilinear filtering - if ((g_pDeviceState->DeviceCaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) && - (g_pDeviceState->DeviceCaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR)) - { - int iLevel = std::max(1, g_pDeviceState->DeviceCaps.MaxAnisotropy); - // Convert level 1/2/4/8/16 into setting 0/1/2/3/4 - while (iLevel >>= 1) - g_pDeviceState->AdapterState.MaxAnisotropicSetting++; + // Release D3D9 interface if we obtained it via GetDirect3D + if (bNeedRelease) + { + ReleaseInterface(pD3D9, 8799, "CProxyDirect3DDevice9 ctor GetDirect3D"); + } + } + else + { + // Set default values + DeviceState.AdapterState.InstalledMemoryKB = m_pDevice->GetAvailableTextureMem() / 1024; + DeviceState.AdapterState.Name = "Unknown"; + DeviceState.AdapterState.bRequiresClipping = false; + } + + // Get max anisotropic setting + DeviceState.AdapterState.MaxAnisotropicSetting = 0; + + // Make sure device can do anisotropic minification and trilinear filtering + if ((DeviceState.DeviceCaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) && + (DeviceState.DeviceCaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR)) + { + int iLevel = std::max(1, DeviceState.DeviceCaps.MaxAnisotropy); + // Convert level 1/2/4/8/16 into setting 0/1/2/3/4 + while (iLevel >>= 1) + DeviceState.AdapterState.MaxAnisotropicSetting++; + } + + // Adapter info collected in DeviceState } - // Clipping is required for some graphic configurations - g_pDeviceState->AdapterState.bRequiresClipping = SStringX(adaptIdent.Description).Contains("Intel"); + const uint64_t registrationToken = RegisterProxyDevice(this); + struct RegistrationGuard + { + CProxyDirect3DDevice9* instance; + uint64_t token; + bool active; + RegistrationGuard(CProxyDirect3DDevice9* inst, uint64_t tok) : instance(inst), token(tok), active(true) {} + ~RegistrationGuard() + { + if (active && token != 0) + UnregisterProxyDevice(instance, token); + } + void Dismiss() { active = false; } + } registrationGuard(this, registrationToken); - WriteDebugEvent(SString("*** Using adapter: %s (Mem:%d KB, MaxAnisotropy:%d)", (const char*)g_pDeviceState->AdapterState.Name, - g_pDeviceState->AdapterState.InstalledMemoryKB, g_pDeviceState->AdapterState.MaxAnisotropicSetting)); + m_registrationToken = registrationToken; - // Give a default value for the streaming memory setting - if (g_pCore->GetCVars()->Exists("streaming_memory") == false) - g_pCore->GetCVars()->Set("streaming_memory", g_pCore->GetMaxStreamingMemory()); + // Give a default value for the streaming memory setting without assuming core lifetime + if (CClientVariables* cvars = CClientVariables::GetSingletonPtr()) + { + if (!cvars->Exists("streaming_memory")) + { + if (CCore* core = CCore::GetSingletonPtr()) + cvars->Set("streaming_memory", core->GetMaxStreamingMemory()); + } + } + + // Note: Pass raw device (m_pDevice), NOT proxy (this), to CGraphics. + // + // CGraphics::m_pDevice is used by CloseActiveShader() to null vertex/pixel shaders + // after effect passes complete. If we pass the proxy here, those SetVertexShader(nullptr) + // and SetPixelShader(nullptr) calls go through the proxy's ShouldUpdateDeviceStateCache() + // gating, which can prevent cache updates during MTA scenes. + // + // This causes a cache vs. real device desync: the cache thinks shaders are still set, + // but the real device has them nulled. When GTA's state block is restored via + // LeavingMTARenderZone(), the SAVE_RENDERSTATE_AND_SET macro reads stale cache values, + // leading to catastrophic graphics corruption (pink/blue world, missing textures). + // + // By passing the raw device, CloseActiveShader's shader nulling bypasses the proxy entirely. + CDirect3DEvents9::OnDirect3DDeviceCreate(m_pDevice); - // Call event handler - CDirect3DEvents9::OnDirect3DDeviceCreate(pDevice); + registrationGuard.Dismiss(); + deviceGuard.Dismiss(); } CProxyDirect3DDevice9::~CProxyDirect3DDevice9() { - WriteDebugEvent(SString("CProxyDirect3DDevice9::~CProxyDirect3DDevice9 %08x", this)); - g_pDeviceState = NULL; - g_pProxyDevice = NULL; + const bool bWasRegistered = UnregisterProxyDevice(this, m_registrationToken); + + bool bRestoreGamma = false; + UINT lastSwapChain = 0; + D3DGAMMARAMP originalGammaRamp{}; + + if (bWasRegistered) + { + ResetGTASceneState(); + + std::lock_guard gammaLock(g_gammaStateMutex); + if (g_GammaState.bOriginalGammaStored) + { + originalGammaRamp = g_GammaState.originalGammaRamp; + lastSwapChain = g_GammaState.lastSwapChain; + bRestoreGamma = true; + + g_GammaState.bOriginalGammaStored = false; + g_GammaState.bLastWasBorderless = false; + g_GammaState.originalGammaRamp = {}; + } + } + + if (bRestoreGamma && m_pDevice) + { + IDirect3DDevice9* pDevice = m_pDevice; + pDevice->AddRef(); + pDevice->SetGammaRamp(lastSwapChain, 0, &originalGammaRamp); + pDevice->Release(); + } + + // Release any cached COM references we held onto for diagnostics + ReleaseCachedResources(); + + // Release our reference(s) to the wrapped device + LONG remainingRefs = m_deviceRefCount.exchange(0, std::memory_order_acq_rel); + if (remainingRefs < 0) + { + remainingRefs = 0; + } + + while (remainingRefs-- > 0) + { + m_pDevice->Release(); + } + m_pDevice = nullptr; } /*** IUnknown methods ***/ HRESULT CProxyDirect3DDevice9::QueryInterface(REFIID riid, void** ppvObj) { + if (!ppvObj) + return E_POINTER; + + *ppvObj = nullptr; + + // Looking for me? (Proxy marker) + if (riid == CProxyDirect3DDevice9_GUID) + { + *ppvObj = static_cast(this); + AddRef(); + return S_OK; + } + + // Check if its for IUnknown or IDirect3DDevice9 + if (riid == IID_IUnknown || riid == IID_IDirect3DDevice9) + { + *ppvObj = static_cast(this); + AddRef(); + return S_OK; + } + + // For any other interface, forward to underlying device + // But this means the caller gets the underlying device, not our proxy return m_pDevice->QueryInterface(riid, ppvObj); } ULONG CProxyDirect3DDevice9::AddRef() { - return m_pDevice->AddRef(); + // Keep proxy and underlying device lifetimes aligned + LONG lNewRefCount = m_lRefCount.fetch_add(1, std::memory_order_relaxed) + 1; + if (m_pDevice) + { + m_pDevice->AddRef(); + m_deviceRefCount.fetch_add(1, std::memory_order_relaxed); + } + return static_cast(lNewRefCount); } ULONG CProxyDirect3DDevice9::Release() { - // Check if will be final release - m_pDevice->AddRef(); - ULONG ulRefCount = m_pDevice->Release(); - if (ulRefCount == 1) + LONG lNewRefCount = m_lRefCount.fetch_sub(1, std::memory_order_acq_rel) - 1; + + // Handle underflow: normalize to 0 and continue to destruction check + if (lNewRefCount < 0) + { + m_lRefCount.store(0, std::memory_order_release); + lNewRefCount = 0; + } + + // Release one device refcount (whether underflow or normal path) + if (m_pDevice) { - WriteDebugEvent("Releasing IDirect3DDevice9 Proxy..."); - // Call event handler - CDirect3DEvents9::OnDirect3DDeviceDestroy(m_pDevice); + const LONG prevDeviceRefs = m_deviceRefCount.fetch_sub(1, std::memory_order_relaxed); + if (prevDeviceRefs > 0) + { + m_pDevice->Release(); + } + else + { + m_deviceRefCount.store(0, std::memory_order_relaxed); + } + } + + // Destroy proxy when refcount reaches zero + if (lNewRefCount == 0) + { + CDirect3DEvents9::OnDirect3DDeviceDestroy(this); delete this; + return 0; } - return m_pDevice->Release(); + return static_cast(lNewRefCount); } /*** IDirect3DDevice9 methods ***/ HRESULT CProxyDirect3DDevice9::TestCooperativeLevel() { - return m_pDevice->TestCooperativeLevel(); + HRESULT hResult = m_pDevice->TestCooperativeLevel(); + + if (hResult != m_lastTestCooperativeLevelResult) + { + m_lastTestCooperativeLevelResult = hResult; + + // Additional safety for when transitioning to/from lost states + if (hResult == D3DERR_DEVICELOST || hResult == D3DERR_DEVICENOTRESET) + { + // Give the driver a moment to stabilize + Sleep(1); + } + } + + return hResult; } UINT CProxyDirect3DDevice9::GetAvailableTextureMem() @@ -175,7 +673,7 @@ BOOL CProxyDirect3DDevice9::ShowCursor(BOOL bShow) HRESULT CProxyDirect3DDevice9::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** pSwapChain) { - return m_pDevice->CreateAdditionalSwapChain(pPresentationParameters, pSwapChain); + return CDirect3DEvents9::CreateAdditionalSwapChainGuarded(m_pDevice, pPresentationParameters, pSwapChain); } HRESULT CProxyDirect3DDevice9::GetSwapChain(UINT iSwapChain, IDirect3DSwapChain9** pSwapChain) @@ -188,6 +686,23 @@ UINT CProxyDirect3DDevice9::GetNumberOfSwapChains() return m_pDevice->GetNumberOfSwapChains(); } +static HRESULT TryResetDevice(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters, uint crashAvertedBase, bool& bHardwareFaultOut) +{ + HRESULT hResult = D3DERR_DEVICELOST; + bHardwareFaultOut = false; + __try + { + hResult = pDevice->Reset(pPresentationParameters); + } + __except (FilterResetException(GetExceptionCode())) + { + CCore::GetSingleton().OnCrashAverted((uiLastResetExceptionCode & 0xFFFF) + crashAvertedBase); + hResult = D3DERR_DEVICELOST; + bHardwareFaultOut = bResetHardwareFault; + } + return hResult; +} + //////////////////////////////////////////////// // // ResetDeviceInsist @@ -202,7 +717,11 @@ HRESULT ResetDeviceInsist(uint uiMinTries, uint uiTimeout, IDirect3DDevice9* pDe uint uiRetryCount = 0; do { - hResult = pDevice->Reset(pPresentationParameters); + bool bHardwareFault = false; + hResult = TryResetDevice(pDevice, pPresentationParameters, 24 * 1000000, bHardwareFault); + // Instruction faults and paging errors won't clear on retry. + if (bHardwareFault) + break; if (hResult == D3D_OK) { WriteDebugEvent(SString(" -- ResetDeviceInsist succeeded on try #%d", uiRetryCount + 1)); @@ -223,19 +742,17 @@ HRESULT ResetDeviceInsist(uint uiMinTries, uint uiTimeout, IDirect3DDevice9* pDe //////////////////////////////////////////////// HRESULT DoResetDevice(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters, D3DPRESENT_PARAMETERS& presentationParametersOrig) { - HRESULT hResult; - hResult = pDevice->Reset(pPresentationParameters); + bool bHardwareFault = false; + HRESULT hResult = TryResetDevice(pDevice, pPresentationParameters, 23 * 1000000, bHardwareFault); if (SUCCEEDED(hResult)) { - // Log success - WriteDebugEvent("Reset success"); + return hResult; } else if (FAILED(hResult)) { // Handle failure of initial reset device call g_pCore->LogEvent(7124, "Direct3D", "Direct3DDevice9::Reset", SString("Fail0:%08x", hResult)); - WriteDebugEvent(SString("Reset failed #0: %08x", hResult)); // Try reset device again hResult = ResetDeviceInsist(5, 1000, pDevice, pPresentationParameters); @@ -245,7 +762,6 @@ HRESULT DoResetDevice(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresent { // Record problem g_pCore->LogEvent(7124, "Direct3D", "Direct3DDevice9::Reset", SString("Fail1:%08x", hResult)); - WriteDebugEvent(SString("Direct3DDevice9::Reset Fail1:%08x", hResult)); // Try with original presentation parameters *pPresentationParameters = presentationParametersOrig; @@ -255,7 +771,6 @@ HRESULT DoResetDevice(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresent { // Record problem g_pCore->LogEvent(7124, "Direct3D", "Direct3DDevice9::Reset", SString("Fail2:%08x", hResult)); - WriteDebugEvent(SString("Direct3DDevice9::Reset Fail2:%08x", hResult)); // Prevent statup warning in loader WatchDogCompletedSection("L3"); @@ -284,78 +799,288 @@ HRESULT DoResetDevice(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresent return hResult; } +static bool WaitForGpuIdle(IDirect3DDevice9* pDevice) +{ + if (!pDevice) + return false; + + IDirect3DQuery9* pEventQuery = nullptr; + const HRESULT hrCreate = pDevice->CreateQuery(D3DQUERYTYPE_EVENT, &pEventQuery); + if (FAILED(hrCreate) || !pEventQuery) + return false; + + bool bCompleted = false; + if (SUCCEEDED(pEventQuery->Issue(D3DISSUE_END))) + { + constexpr int kMaxAttempts = 16; + for (int attempt = 0; attempt < kMaxAttempts; ++attempt) + { + const HRESULT hrData = pEventQuery->GetData(nullptr, 0, D3DGETDATA_FLUSH); + if (hrData == S_OK) + { + bCompleted = true; + break; + } + if (hrData == D3DERR_DEVICELOST) + { + break; + } + + std::this_thread::yield(); + } + } + + pEventQuery->Release(); + return bCompleted; +} + HRESULT CProxyDirect3DDevice9::Reset(D3DPRESENT_PARAMETERS* pPresentationParameters) { - WriteDebugEvent("CProxyDirect3DDevice9::Reset"); + // Validate input parameters + if (!pPresentationParameters) + { + return D3DERR_INVALIDCALL; + } + + // Check cooperative level before attempting reset + HRESULT hCoopLevel = m_pDevice->TestCooperativeLevel(); + if (hCoopLevel == D3DERR_DEVICELOST) + { + // The caller (e.g. RW's _rwD3D9TestState) may have already released GPU + // resources before calling Reset. Run MTA invalidation so we don't hold + // stale pointers to surfaces/textures that were freed on the RW side. + CDirect3DEvents9::OnInvalidate(m_pDevice); + return hCoopLevel; + } + else if (hCoopLevel != D3DERR_DEVICENOTRESET && hCoopLevel != D3D_OK) + { + return hCoopLevel; + } + + // Preserve existing gamma snapshot so we can restore it if the reset fails. + // Placed after cooperative level check so gamma is untouched on early returns. + SGammaState previousGammaState; + bool gammaStateCleared = false; + { + std::lock_guard gammaLock(g_gammaStateMutex); + previousGammaState = g_GammaState; + g_GammaState = SGammaState(); + gammaStateCleared = true; + } // Save presentation parameters D3DPRESENT_PARAMETERS presentationParametersOrig = *pPresentationParameters; - GetVideoModeManager()->PreReset(pPresentationParameters); + CVideoModeManagerInterface* pVideoModeManager = GetVideoModeManager(); + if (pVideoModeManager) + { + pVideoModeManager->PreReset(pPresentationParameters); + } HRESULT hResult; // Call our event handler. CDirect3DEvents9::OnInvalidate(m_pDevice); + // Unbind all device state before releasing cached resources. + // D3D9 keeps internal refs to bound textures, streams, shaders, etc. If GTA SA + // freed any of them before Reset, drivers may crash iterating stale entries. + { + IDirect3DDevice9* const pDevice = m_pDevice; + + for (DWORD i = 0; i < NUMELMS(DeviceState.TextureState); ++i) + pDevice->SetTexture(i, nullptr); + + for (DWORD i = 0; i < NUMELMS(DeviceState.VertexStreams); ++i) + pDevice->SetStreamSource(i, nullptr, 0, 0); + + for (DWORD i = 1; i < 4; ++i) + pDevice->SetRenderTarget(i, nullptr); + + pDevice->SetIndices(nullptr); + pDevice->SetVertexShader(nullptr); + pDevice->SetPixelShader(nullptr); + pDevice->SetVertexDeclaration(nullptr); + pDevice->SetDepthStencilSurface(nullptr); + } + + // Release cached state so lingering references can't block Reset on default-pool resources + ReleaseCachedResources(); + + // Give GPU driver time to complete any pending operations. We keep the light Sleep as a + // conservative fallback but first rely on an event query, as recommended in Microsoft's GPU + // synchronization guidance, to ensure outstanding commands finish. + WaitForGpuIdle(m_pDevice); + + Sleep(1); + + // The device may have gone from DEVICENOTRESET to DEVICELOST during cleanup. + // Some drivers crash if Reset is called on a fully lost device. + if (const HRESULT hRecheck = m_pDevice->TestCooperativeLevel(); hRecheck == D3DERR_DEVICELOST) + { + if (gammaStateCleared) + { + std::lock_guard gammaLock(g_gammaStateMutex); + g_GammaState = previousGammaState; + } + return D3DERR_DEVICELOST; + } + // Call the real reset routine. hResult = DoResetDevice(m_pDevice, pPresentationParameters, presentationParametersOrig); - // Store actual present parameters used - IDirect3DSwapChain9* pSwapChain; - m_pDevice->GetSwapChain(0, &pSwapChain); - pSwapChain->GetPresentParameters(&g_pDeviceState->CreationState.PresentationParameters); - SAFE_RELEASE(pSwapChain); - - // Store device creation parameters as well - m_pDevice->GetCreationParameters(&g_pDeviceState->CreationState.CreationParameters); + if (SUCCEEDED(hResult)) + { + // Store actual present parameters used + IDirect3DSwapChain9* pSwapChain = nullptr; + HRESULT hrSwapChain = m_pDevice->GetSwapChain(0, &pSwapChain); + if (FAILED(hrSwapChain)) + { + } + else if (!pSwapChain) + { + } - g_pCore->LogEvent(7123, "Direct3D", "Direct3DDevice9::Reset", "Success"); - GetVideoModeManager()->PostReset(pPresentationParameters); + // Store device creation parameters as well, keeping both updates atomic relative to device state changes + HRESULT hrCreationParams = D3D_OK; + { + std::lock_guard stateGuard(g_deviceStateMutex); + if (g_pDeviceState) + { + if (SUCCEEDED(hrSwapChain) && pSwapChain) + { + pSwapChain->GetPresentParameters(&g_pDeviceState->CreationState.PresentationParameters); + } + hrCreationParams = m_pDevice->GetCreationParameters(&g_pDeviceState->CreationState.CreationParameters); + } + else + { + hrCreationParams = D3DERR_INVALIDCALL; + } + } - // Update our data. - m_pData->StoreViewport(0, 0, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight); + // Always release the swap chain if it was obtained, regardless of success/failure + ReleaseInterface(pSwapChain, 8799, "CProxyDirect3DDevice9::Reset GetSwapChain"); - // Call our event handler. - CDirect3DEvents9::OnRestore(m_pDevice); + if (FAILED(hrCreationParams)) + { + } - WriteDebugEvent(SString(" BackBufferWidth:%d Height:%d Format:%d Count:%d", pPresentationParameters->BackBufferWidth, - pPresentationParameters->BackBufferHeight, pPresentationParameters->BackBufferFormat, pPresentationParameters->BackBufferCount)); + // Only perform post-reset operations on successful reset + g_pCore->LogEvent(7123, "Direct3D", "Direct3DDevice9::Reset", "Success"); + if (pVideoModeManager) + { + pVideoModeManager->PostReset(pPresentationParameters); + } - WriteDebugEvent(SString(" MultiSampleType:%d Quality:%d", pPresentationParameters->MultiSampleType, pPresentationParameters->MultiSampleQuality)); + ApplyBorderlessColorCorrection(this, *pPresentationParameters); - WriteDebugEvent(SString(" SwapEffect:%d Windowed:%d EnableAutoDepthStencil:%d AutoDepthStencilFormat:%d Flags:0x%x", - pPresentationParameters->SwapEffect, pPresentationParameters->Windowed, pPresentationParameters->EnableAutoDepthStencil, - pPresentationParameters->AutoDepthStencilFormat, pPresentationParameters->Flags)); + // Update our data. Some windowed resets use 0x0 backbuffer sizes, so query the device. + const DWORD prevViewportWidth = m_pData->GetViewportWidth(); + const DWORD prevViewportHeight = m_pData->GetViewportHeight(); + D3DVIEWPORT9 viewport = {}; + bool haveViewport = false; + if (SUCCEEDED(m_pDevice->GetViewport(&viewport)) && viewport.Width > 0 && viewport.Height > 0) + { + haveViewport = true; + m_pData->StoreViewport(viewport.X, viewport.Y, viewport.Width, viewport.Height); + } + else if (pPresentationParameters->BackBufferWidth > 0 && pPresentationParameters->BackBufferHeight > 0) + { + m_pData->StoreViewport(0, 0, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight); + haveViewport = true; + } + else + { + IDirect3DSurface9* pBackBuffer = nullptr; + if (SUCCEEDED(m_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer)) && pBackBuffer) + { + D3DSURFACE_DESC backBufferDesc = {}; + if (SUCCEEDED(pBackBuffer->GetDesc(&backBufferDesc)) && backBufferDesc.Width > 0 && backBufferDesc.Height > 0) + { + m_pData->StoreViewport(0, 0, backBufferDesc.Width, backBufferDesc.Height); + haveViewport = true; + } + pBackBuffer->Release(); + } + } - WriteDebugEvent(SString(" FullScreen_RefreshRateInHz:%d PresentationInterval:0x%08x", pPresentationParameters->FullScreen_RefreshRateInHz, - pPresentationParameters->PresentationInterval)); + if (!haveViewport && prevViewportWidth > 0 && prevViewportHeight > 0) + { + m_pData->StoreViewport(0, 0, prevViewportWidth, prevViewportHeight); + } + else if (!haveViewport) + { + CGraphics::GetSingleton().MarkViewportRefreshPending(); + } - const D3DDEVICE_CREATION_PARAMETERS& parameters = g_pDeviceState->CreationState.CreationParameters; + // Ensure scene state is properly restored + // Call our event handler. + CDirect3DEvents9::OnRestore(m_pDevice); - WriteDebugEvent(SString(" Adapter:%d DeviceType:%d BehaviorFlags:0x%x", parameters.AdapterOrdinal, parameters.DeviceType, parameters.BehaviorFlags)); + // Additional sync point for GPU driver + if (BeginSceneWithoutProxy(m_pDevice, ESceneOwner::MTA)) + { + EndSceneWithoutProxy(m_pDevice, ESceneOwner::MTA); + } + } + else + { + if (gammaStateCleared) + { + std::lock_guard gammaLock(g_gammaStateMutex); + g_GammaState = previousGammaState; + } + } return hResult; } HRESULT CProxyDirect3DDevice9::Present(CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) { - CDirect3DEvents9::OnPresent(m_pDevice); + static thread_local bool s_inPresent = false; + if (s_inPresent) + { + return CDirect3DEvents9::PresentGuarded(m_pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); + } - // Reset frame stat counters + struct PresentGuard + { + bool& flag; + explicit PresentGuard(bool& inFlag) : flag(inFlag) { flag = true; } + ~PresentGuard() { flag = false; } + } guard(s_inPresent); + + // Reset frame stat counters - using memset for efficiency memset(&DeviceState.FrameStats, 0, sizeof(DeviceState.FrameStats)); + bool bDeviceTemporarilyLost = false; + HRESULT hrCoopLevel = D3DERR_INVALIDCALL; + if (!CDirect3DEvents9::IsDeviceOperational(m_pDevice, &bDeviceTemporarilyLost, &hrCoopLevel)) + { + return (hrCoopLevel != D3D_OK) ? hrCoopLevel : D3DERR_INVALIDCALL; + } + + CDirect3DEvents9::OnPresent(m_pDevice, static_cast(this)); + // A fog flicker fix for some ATI cards - D3DMATRIX projMatrix; - m_pData->GetTransform(D3DTS_PROJECTION, &projMatrix); - m_pDevice->SetTransform(D3DTS_PROJECTION, &projMatrix); + const D3DMATRIX* pCachedProjection = m_pData->GetTransformPtr(D3DTS_PROJECTION); + if (pCachedProjection) + { + m_pDevice->SetTransform(D3DTS_PROJECTION, pCachedProjection); + } TIMING_GRAPH("Present"); - HRESULT hr = m_pDevice->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); + HRESULT hr = CDirect3DEvents9::PresentGuarded(m_pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); TIMING_GRAPH("PostPresent"); return hr; } +HRESULT CProxyDirect3DDevice9::PresentWithoutProxy(CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) +{ + return CDirect3DEvents9::PresentGuarded(m_pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); +} + HRESULT CProxyDirect3DDevice9::GetBackBuffer(UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer) { return m_pDevice->GetBackBuffer(iSwapChain, iBackBuffer, Type, ppBackBuffer); @@ -373,12 +1098,154 @@ HRESULT CProxyDirect3DDevice9::SetDialogBoxMode(BOOL bEnableDialogs) VOID CProxyDirect3DDevice9::SetGammaRamp(UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP* pRamp) { + // Validate inputs first + if (!pRamp) + { + return; + } + + // Validate swap chain index + if (iSwapChain >= GetNumberOfSwapChains()) + { + return; + } + + // Get current display mode state - use a timeout to avoid race conditions during mode transitions + CVideoModeManagerInterface* pVideoModeManager = GetVideoModeManager(); + if (!pVideoModeManager) + { + // Fallback to original behavior if video mode manager is unavailable + m_pDevice->SetGammaRamp(iSwapChain, Flags, pRamp); + return; + } + + bool bIsBorderlessMode = pVideoModeManager->IsDisplayModeWindowed() || pVideoModeManager->IsDisplayModeFullScreenWindow(); + + // Fast-path: check cached state before expensive settings fetch + { + std::lock_guard gammaLock(g_gammaStateMutex); + if (g_GammaState.bOriginalGammaStored && g_GammaState.bLastWasBorderless == bIsBorderlessMode && g_GammaState.lastSwapChain == iSwapChain) + { + // State hasn't changed, apply ramp directly + m_pDevice->SetGammaRamp(iSwapChain, Flags, pRamp); + return; + } + } + + float gammaPower = 1.0f; + float brightnessScale = 1.0f; + float contrastScale = 1.0f; + float saturationScale = 1.0f; + bool applyWindowed = true; + bool applyFullscreen = false; + FetchSettings(gammaPower, brightnessScale, contrastScale, saturationScale, applyWindowed, applyFullscreen); + + const bool adjustmentsRequested = bIsBorderlessMode ? applyWindowed : applyFullscreen; + + // Store original gamma ramp on first call or mode change + { + std::lock_guard gammaLock(g_gammaStateMutex); + if (!g_GammaState.bOriginalGammaStored || g_GammaState.lastSwapChain != iSwapChain || g_GammaState.bLastWasBorderless != bIsBorderlessMode) + { + if (!g_GammaState.bOriginalGammaStored) + { + // Capture the original gamma only once per session + g_GammaState.originalGammaRamp = *pRamp; + g_GammaState.bOriginalGammaStored = true; + g_GammaState.lastSwapChain = iSwapChain; + } + g_GammaState.bLastWasBorderless = bIsBorderlessMode; + } + } + + if (adjustmentsRequested) + { + // Let the tone-mapping pass handle all presentation adjustments for this mode. + m_pDevice->SetGammaRamp(iSwapChain, Flags, pRamp); + return; + } + + if (bIsBorderlessMode) + { + // Windowed/borderless always rely on the tone-mapping pass. + m_pDevice->SetGammaRamp(iSwapChain, Flags, pRamp); + return; + } + + // In exclusive fullscreen mode with no adjustments requested, fall back to the original gamma ramp m_pDevice->SetGammaRamp(iSwapChain, Flags, pRamp); } +void CProxyDirect3DDevice9::ApplyBorderlessPresentationTuning() +{ + if (!m_pDevice) + return; + + D3DPRESENT_PARAMETERS presentationParameters{}; + bool havePresentationParameters = false; + { + std::lock_guard stateLock(g_deviceStateMutex); + if (g_pDeviceState) + { + presentationParameters = g_pDeviceState->CreationState.PresentationParameters; + havePresentationParameters = true; + } + } + + bool bIsBorderlessMode = false; + if (havePresentationParameters) + { + bIsBorderlessMode = (presentationParameters.Windowed != 0); + } + + if (!havePresentationParameters) + { + if (CVideoModeManagerInterface* pVideoModeManager = GetVideoModeManager()) + bIsBorderlessMode = pVideoModeManager->IsDisplayModeWindowed() || pVideoModeManager->IsDisplayModeFullScreenWindow(); + + // Provide a best-effort set of presentation parameters so sRGB state refreshes consistently. + presentationParameters.Windowed = bIsBorderlessMode ? TRUE : FALSE; + } + + ApplyBorderlessColorCorrection(this, presentationParameters); + + if (bIsBorderlessMode) + { + // Borderless tone mapping handles gamma/brightness adjustments when enabled. + return; + } + + UINT targetSwapChain = 0; + D3DGAMMARAMP baseRamp{}; + bool haveBaseRamp = false; + + { + std::lock_guard gammaLock(g_gammaStateMutex); + if (g_GammaState.bOriginalGammaStored) + { + baseRamp = g_GammaState.originalGammaRamp; + targetSwapChain = g_GammaState.lastSwapChain; + haveBaseRamp = true; + } + } + + if (!haveBaseRamp) + { + m_pDevice->GetGammaRamp(targetSwapChain, &baseRamp); + + std::lock_guard gammaLock(g_gammaStateMutex); + g_GammaState.originalGammaRamp = baseRamp; + g_GammaState.lastSwapChain = targetSwapChain; + g_GammaState.bOriginalGammaStored = true; + } + + D3DGAMMARAMP rampCopy = baseRamp; + SetGammaRamp(targetSwapChain, 0, &rampCopy); +} + VOID CProxyDirect3DDevice9::GetGammaRamp(UINT iSwapChain, D3DGAMMARAMP* pRamp) { - m_pDevice->GetGammaRamp(iSwapChain, pRamp); + return m_pDevice->GetGammaRamp(iSwapChain, pRamp); } HRESULT CProxyDirect3DDevice9::CreateTexture(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, @@ -390,13 +1257,13 @@ HRESULT CProxyDirect3DDevice9::CreateTexture(UINT Width, UINT Height, UINT Level HRESULT CProxyDirect3DDevice9::CreateVolumeTexture(UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle) { - return m_pDevice->CreateVolumeTexture(Width, Height, Depth, Levels, Usage, Format, Pool, ppVolumeTexture, pSharedHandle); + return CDirect3DEvents9::CreateVolumeTextureGuarded(m_pDevice, Width, Height, Depth, Levels, Usage, Format, Pool, ppVolumeTexture, pSharedHandle); } HRESULT CProxyDirect3DDevice9::CreateCubeTexture(UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture9** ppCubeTexture, HANDLE* pSharedHandle) { - return m_pDevice->CreateCubeTexture(EdgeLength, Levels, Usage, Format, Pool, ppCubeTexture, pSharedHandle); + return CDirect3DEvents9::CreateCubeTextureGuarded(m_pDevice, EdgeLength, Levels, Usage, Format, Pool, ppCubeTexture, pSharedHandle); } HRESULT CProxyDirect3DDevice9::CreateVertexBuffer(UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, @@ -414,57 +1281,73 @@ HRESULT CProxyDirect3DDevice9::CreateIndexBuffer(UINT Length, DWORD Usage, D3DFO HRESULT CProxyDirect3DDevice9::CreateRenderTarget(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) { - return m_pDevice->CreateRenderTarget(Width, Height, Format, MultiSample, MultisampleQuality, Lockable, ppSurface, pSharedHandle); + return CDirect3DEvents9::CreateRenderTargetGuarded(m_pDevice, Width, Height, Format, MultiSample, MultisampleQuality, Lockable, ppSurface, pSharedHandle); } HRESULT CProxyDirect3DDevice9::CreateDepthStencilSurface(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) { - return m_pDevice->CreateDepthStencilSurface(Width, Height, Format, MultiSample, MultisampleQuality, Discard, ppSurface, pSharedHandle); + return CDirect3DEvents9::CreateDepthStencilSurfaceGuarded(m_pDevice, Width, Height, Format, MultiSample, MultisampleQuality, Discard, ppSurface, + pSharedHandle); } HRESULT CProxyDirect3DDevice9::UpdateSurface(IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestinationSurface, CONST POINT* pDestPoint) { - return m_pDevice->UpdateSurface(pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint); + return CDirect3DEvents9::UpdateSurfaceGuarded(m_pDevice, pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint); } HRESULT CProxyDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture) { - return m_pDevice->UpdateTexture(pSourceTexture, pDestinationTexture); + return CDirect3DEvents9::UpdateTextureGuarded(m_pDevice, pSourceTexture, pDestinationTexture); } HRESULT CProxyDirect3DDevice9::GetRenderTargetData(IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface) { - return m_pDevice->GetRenderTargetData(pRenderTarget, pDestSurface); + return CDirect3DEvents9::GetRenderTargetDataGuarded(m_pDevice, pRenderTarget, pDestSurface); } HRESULT CProxyDirect3DDevice9::GetFrontBufferData(UINT iSwapChain, IDirect3DSurface9* pDestSurface) { - return m_pDevice->GetFrontBufferData(iSwapChain, pDestSurface); + return CDirect3DEvents9::GetFrontBufferDataGuarded(m_pDevice, iSwapChain, pDestSurface); } HRESULT CProxyDirect3DDevice9::StretchRect(IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestSurface, CONST RECT* pDestRect, D3DTEXTUREFILTERTYPE Filter) { - CGraphics::GetSingleton().GetRenderItemManager()->HandleStretchRect(pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter); - return D3D_OK; + if (!pSourceSurface || !pDestSurface) + return D3DERR_INVALIDCALL; + + static thread_local bool s_inStretchRect = false; + if (s_inStretchRect) + { + return m_pDevice->StretchRect(pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter); + } + + struct StretchRectGuard + { + bool& flag; + explicit StretchRectGuard(bool& inFlag) : flag(inFlag) { flag = true; } + ~StretchRectGuard() { flag = false; } + } guard(s_inStretchRect); + + return CGraphics::GetSingleton().GetRenderItemManager()->HandleStretchRect(pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter); } HRESULT CProxyDirect3DDevice9::ColorFill(IDirect3DSurface9* pSurface, CONST RECT* pRect, D3DCOLOR color) { - return m_pDevice->ColorFill(pSurface, pRect, color); + return CDirect3DEvents9::ColorFillGuarded(m_pDevice, pSurface, pRect, color); } HRESULT CProxyDirect3DDevice9::CreateOffscreenPlainSurface(UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) { - return m_pDevice->CreateOffscreenPlainSurface(Width, Height, Format, Pool, ppSurface, pSharedHandle); + return CDirect3DEvents9::CreateOffscreenPlainSurfaceGuarded(m_pDevice, Width, Height, Format, Pool, ppSurface, pSharedHandle); } HRESULT CProxyDirect3DDevice9::SetRenderTarget(DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) { - return m_pDevice->SetRenderTarget(RenderTargetIndex, pRenderTarget); + return CDirect3DEvents9::SetRenderTargetGuarded(m_pDevice, RenderTargetIndex, pRenderTarget); } HRESULT CProxyDirect3DDevice9::GetRenderTarget(DWORD RenderTargetIndex, IDirect3DSurface9** ppRenderTarget) @@ -474,7 +1357,7 @@ HRESULT CProxyDirect3DDevice9::GetRenderTarget(DWORD RenderTargetIndex, IDirect3 HRESULT CProxyDirect3DDevice9::SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil) { - return m_pDevice->SetDepthStencilSurface(pNewZStencil); + return CDirect3DEvents9::SetDepthStencilSurfaceGuarded(m_pDevice, pNewZStencil); } HRESULT CProxyDirect3DDevice9::GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface) @@ -489,38 +1372,45 @@ HRESULT CProxyDirect3DDevice9::BeginScene() // Call the real routine. hResult = m_pDevice->BeginScene(); if (hResult == D3D_OK) - g_bInGTAScene = true; + { + IncrementGTASceneState(); + m_bBeginSceneSuccess.store(true, std::memory_order_release); + } // Call our event handler. CDirect3DEvents9::OnBeginScene(m_pDevice); // Possible fix for missing textures on some chipsets - m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - - m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - m_pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); return hResult; } HRESULT CProxyDirect3DDevice9::EndScene() { + const bool bShouldDecrement = m_bBeginSceneSuccess.exchange(false, std::memory_order_acq_rel); + // Call our event handler. if (CDirect3DEvents9::OnEndScene(m_pDevice)) { // Call real routine. HRESULT hResult = m_pDevice->EndScene(); - g_bInGTAScene = false; CGraphics::GetSingleton().GetRenderItemManager()->SaveReadableDepthBuffer(); + if (bShouldDecrement) + DecrementGTASceneState(); return hResult; } + if (bShouldDecrement) + DecrementGTASceneState(); return D3D_OK; } @@ -530,15 +1420,21 @@ HRESULT CProxyDirect3DDevice9::Clear(DWORD Count, CONST D3DRECT* pRects, DWORD F if (Flags & D3DCLEAR_ZBUFFER) CGraphics::GetSingleton().GetRenderItemManager()->SaveReadableDepthBuffer(); - return m_pDevice->Clear(Count, pRects, Flags, Color, Z, Stencil); + return CDirect3DEvents9::ClearGuarded(m_pDevice, Count, pRects, Flags, Color, Z, Stencil); } HRESULT CProxyDirect3DDevice9::SetTransform(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) { + if (!pMatrix) + { + return D3DERR_INVALIDCALL; + } + // Store the matrix m_pData->StoreTransform(State, pMatrix); - DeviceState.TransformState.Raw(State) = *pMatrix; + if (ShouldUpdateDeviceStateCache()) + DeviceState.TransformState.Raw(State) = *pMatrix; // Call original return m_pDevice->SetTransform(State, pMatrix); @@ -546,6 +1442,17 @@ HRESULT CProxyDirect3DDevice9::SetTransform(D3DTRANSFORMSTATETYPE State, CONST D HRESULT CProxyDirect3DDevice9::GetTransform(D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) { + // Use cached data if available to avoid expensive device query + if (pMatrix) + { + const D3DMATRIX* pCached = m_pData->GetTransformPtr(State); + if (pCached) + { + *pMatrix = *pCached; + return D3D_OK; + } + } + // Fallback to device query for unsupported transform types return m_pDevice->GetTransform(State, pMatrix); } @@ -570,7 +1477,17 @@ HRESULT CProxyDirect3DDevice9::GetViewport(D3DVIEWPORT9* pViewport) HRESULT CProxyDirect3DDevice9::SetMaterial(CONST D3DMATERIAL9* pMaterial) { - DeviceState.Material = *pMaterial; + if (!pMaterial) + { + return D3DERR_INVALIDCALL; + } + + // Update cache if material has changed (avoid 68-byte copy) + if (ShouldUpdateDeviceStateCache()) + { + if (memcmp(&DeviceState.Material, pMaterial, sizeof(D3DMATERIAL9)) != 0) + DeviceState.Material = *pMaterial; + } return m_pDevice->SetMaterial(pMaterial); } @@ -581,8 +1498,17 @@ HRESULT CProxyDirect3DDevice9::GetMaterial(D3DMATERIAL9* pMaterial) HRESULT CProxyDirect3DDevice9::SetLight(DWORD Index, CONST D3DLIGHT9* pLight) { - if (Index < NUMELMS(DeviceState.Lights)) - DeviceState.Lights[Index] = *pLight; + if (!pLight) + { + return D3DERR_INVALIDCALL; + } + + // Update cache if light has changed (avoid 104-byte copy) + if (ShouldUpdateDeviceStateCache()) + { + if (Index < NUMELMS(DeviceState.Lights) && memcmp(&DeviceState.Lights[Index], pLight, sizeof(D3DLIGHT9)) != 0) + DeviceState.Lights[Index] = *pLight; + } return m_pDevice->SetLight(Index, pLight); } @@ -593,8 +1519,11 @@ HRESULT CProxyDirect3DDevice9::GetLight(DWORD Index, D3DLIGHT9* pLight) HRESULT CProxyDirect3DDevice9::LightEnable(DWORD Index, BOOL Enable) { - if (Index < NUMELMS(DeviceState.LightEnableState)) - DeviceState.LightEnableState[Index].Enable = Enable; + if (ShouldUpdateDeviceStateCache()) + { + if (Index < NUMELMS(DeviceState.LightEnableState)) + DeviceState.LightEnableState[Index].Enable = Enable; + } return m_pDevice->LightEnable(Index, Enable); } @@ -615,8 +1544,13 @@ HRESULT CProxyDirect3DDevice9::GetClipPlane(DWORD Index, float* pPlane) HRESULT CProxyDirect3DDevice9::SetRenderState(D3DRENDERSTATETYPE State, DWORD Value) { - if (State < NUMELMS(DeviceState.RenderState.Raw)) - DeviceState.RenderState.Raw[State] = Value; + // Update cache for state tracking + if (ShouldUpdateDeviceStateCache()) + { + if (State < NUMELMS(DeviceState.RenderState.Raw)) + DeviceState.RenderState.Raw[State] = Value; + } + return m_pDevice->SetRenderState(State, Value); } @@ -657,9 +1591,18 @@ HRESULT CProxyDirect3DDevice9::GetTexture(DWORD Stage, IDirect3DBaseTexture9** p HRESULT CProxyDirect3DDevice9::SetTexture(DWORD Stage, IDirect3DBaseTexture9* pTexture) { - CDirect3DEvents9::CloseActiveShader(); - if (Stage < NUMELMS(DeviceState.TextureState)) - DeviceState.TextureState[Stage].Texture = pTexture; + CDirect3DEvents9::CloseActiveShader(true, static_cast(this)); + if (ShouldUpdateDeviceStateCache()) + { + if (Stage < NUMELMS(DeviceState.TextureState)) + { + // Fast-path: avoid AddRef/Release if texture hasn't changed + if (DeviceState.TextureState[Stage].Texture != pTexture) + { + ReplaceInterface(DeviceState.TextureState[Stage].Texture, pTexture); + } + } + } return m_pDevice->SetTexture(Stage, CDirect3DEvents9::GetRealTexture(pTexture)); } @@ -670,9 +1613,14 @@ HRESULT CProxyDirect3DDevice9::GetTextureStageState(DWORD Stage, D3DTEXTURESTAGE HRESULT CProxyDirect3DDevice9::SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) { - if (Stage < NUMELMS(DeviceState.StageState)) - if (Type < NUMELMS(DeviceState.StageState[Stage].Raw)) - DeviceState.StageState[Stage].Raw[Type] = Value; + // Update cache for state tracking + if (ShouldUpdateDeviceStateCache()) + { + if (Stage < NUMELMS(DeviceState.StageState)) + if (Type < NUMELMS(DeviceState.StageState[Stage].Raw)) + DeviceState.StageState[Stage].Raw[Type] = Value; + } + return m_pDevice->SetTextureStageState(Stage, Type, Value); } @@ -683,9 +1631,14 @@ HRESULT CProxyDirect3DDevice9::GetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYP HRESULT CProxyDirect3DDevice9::SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) { - if (Sampler < NUMELMS(DeviceState.SamplerState)) - if (Type < NUMELMS(DeviceState.SamplerState[Sampler].Raw)) - DeviceState.SamplerState[Sampler].Raw[Type] = Value; + // Update cache for state tracking + if (ShouldUpdateDeviceStateCache()) + { + if (Sampler < NUMELMS(DeviceState.SamplerState)) + if (Type < NUMELMS(DeviceState.SamplerState[Sampler].Raw)) + DeviceState.SamplerState[Sampler].Raw[Type] = Value; + } + return m_pDevice->SetSamplerState(Sampler, Type, Value); } @@ -746,8 +1699,8 @@ FLOAT CProxyDirect3DDevice9::GetNPatchMode() HRESULT CProxyDirect3DDevice9::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) { - SetCallType(SCallState::DRAW_PRIMITIVE, 3, PrimitiveType, StartVertex, PrimitiveCount); - HRESULT hr = CDirect3DEvents9::OnDrawPrimitive(m_pDevice, PrimitiveType, StartVertex, PrimitiveCount); + SetCallType(SCallState::DRAW_PRIMITIVE, {PrimitiveType, static_cast(StartVertex), static_cast(PrimitiveCount)}); + HRESULT hr = CDirect3DEvents9::OnDrawPrimitive(m_pDevice, static_cast(this), PrimitiveType, StartVertex, PrimitiveCount); SetCallType(SCallState::NONE); return hr; } @@ -755,8 +1708,10 @@ HRESULT CProxyDirect3DDevice9::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UIN HRESULT CProxyDirect3DDevice9::DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) { - SetCallType(SCallState::DRAW_INDEXED_PRIMITIVE, 6, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); - HRESULT hr = CDirect3DEvents9::OnDrawIndexedPrimitive(m_pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); + SetCallType(SCallState::DRAW_INDEXED_PRIMITIVE, {PrimitiveType, BaseVertexIndex, static_cast(MinVertexIndex), static_cast(NumVertices), + static_cast(startIndex), static_cast(primCount)}); + HRESULT hr = CDirect3DEvents9::OnDrawIndexedPrimitive(m_pDevice, static_cast(this), PrimitiveType, BaseVertexIndex, MinVertexIndex, + NumVertices, startIndex, primCount); SetCallType(SCallState::NONE); return hr; } @@ -764,21 +1719,21 @@ HRESULT CProxyDirect3DDevice9::DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveTy HRESULT CProxyDirect3DDevice9::DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) { - return m_pDevice->DrawPrimitiveUP(PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); + return CDirect3DEvents9::DrawPrimitiveUPGuarded(m_pDevice, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); } HRESULT CProxyDirect3DDevice9::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) { - return m_pDevice->DrawIndexedPrimitiveUP(PrimitiveType, MinVertexIndex, NumVertices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, - VertexStreamZeroStride); + return CDirect3DEvents9::DrawIndexedPrimitiveUPGuarded(m_pDevice, PrimitiveType, MinVertexIndex, NumVertices, PrimitiveCount, pIndexData, IndexDataFormat, + pVertexStreamZeroData, VertexStreamZeroStride); } HRESULT CProxyDirect3DDevice9::ProcessVertices(UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) { - return m_pDevice->ProcessVertices(SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, Flags); + return CDirect3DEvents9::ProcessVerticesGuarded(m_pDevice, SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, Flags); } HRESULT CProxyDirect3DDevice9::CreateVertexDeclaration(CONST D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl) @@ -788,7 +1743,12 @@ HRESULT CProxyDirect3DDevice9::CreateVertexDeclaration(CONST D3DVERTEXELEMENT9* HRESULT CProxyDirect3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl) { - DeviceState.VertexDeclaration = pDecl; + // Avoid validation overhead since declarations come from D3D9 driver + if (ShouldUpdateDeviceStateCache()) + { + if (DeviceState.VertexDeclaration != pDecl) + ReplaceInterface(DeviceState.VertexDeclaration, pDecl); + } return CDirect3DEvents9::SetVertexDeclaration(m_pDevice, pDecl); } @@ -814,7 +1774,12 @@ HRESULT CProxyDirect3DDevice9::CreateVertexShader(CONST DWORD* pFunction, IDirec HRESULT CProxyDirect3DDevice9::SetVertexShader(IDirect3DVertexShader9* pShader) { - DeviceState.VertexShader = pShader; + // Avoid validation overhead since shaders come from D3D9 driver + if (ShouldUpdateDeviceStateCache()) + { + if (DeviceState.VertexShader != pShader) + ReplaceInterface(DeviceState.VertexShader, pShader); + } return m_pDevice->SetVertexShader(pShader); } @@ -855,9 +1820,11 @@ HRESULT CProxyDirect3DDevice9::GetVertexShaderConstantB(UINT StartRegister, BOOL HRESULT CProxyDirect3DDevice9::SetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) { - if (StreamNumber < NUMELMS(DeviceState.VertexStreams)) + if (StreamNumber < NUMELMS(DeviceState.VertexStreams) && ShouldUpdateDeviceStateCache()) { - DeviceState.VertexStreams[StreamNumber].StreamData = pStreamData; + // Avoid validation overhead since vertex buffers come from D3D9 driver + if (DeviceState.VertexStreams[StreamNumber].StreamData != pStreamData) + ReplaceInterface(DeviceState.VertexStreams[StreamNumber].StreamData, pStreamData); DeviceState.VertexStreams[StreamNumber].StreamOffset = OffsetInBytes; DeviceState.VertexStreams[StreamNumber].StreamStride = Stride; } @@ -881,7 +1848,12 @@ HRESULT CProxyDirect3DDevice9::GetStreamSourceFreq(UINT StreamNumber, UINT* pSet HRESULT CProxyDirect3DDevice9::SetIndices(IDirect3DIndexBuffer9* pIndexData) { - DeviceState.IndexBufferData = pIndexData; + // Avoid validation overhead since index buffers come from D3D9 driver + if (ShouldUpdateDeviceStateCache()) + { + if (DeviceState.IndexBufferData != pIndexData) + ReplaceInterface(DeviceState.IndexBufferData, pIndexData); + } return m_pDevice->SetIndices(CDirect3DEvents9::GetRealIndexBuffer(pIndexData)); } @@ -897,7 +1869,12 @@ HRESULT CProxyDirect3DDevice9::CreatePixelShader(CONST DWORD* pFunction, IDirect HRESULT CProxyDirect3DDevice9::SetPixelShader(IDirect3DPixelShader9* pShader) { - DeviceState.PixelShader = pShader; + // Avoid validation overhead since shaders come from D3D9 driver + if (ShouldUpdateDeviceStateCache()) + { + if (DeviceState.PixelShader != pShader) + ReplaceInterface(DeviceState.PixelShader, pShader); + } return m_pDevice->SetPixelShader(pShader); } @@ -938,12 +1915,12 @@ HRESULT CProxyDirect3DDevice9::GetPixelShaderConstantB(UINT StartRegister, BOOL* HRESULT CProxyDirect3DDevice9::DrawRectPatch(UINT Handle, CONST float* pNumSegs, CONST D3DRECTPATCH_INFO* pRectPatchInfo) { - return m_pDevice->DrawRectPatch(Handle, pNumSegs, pRectPatchInfo); + return CDirect3DEvents9::DrawRectPatchGuarded(m_pDevice, Handle, pNumSegs, pRectPatchInfo); } HRESULT CProxyDirect3DDevice9::DrawTriPatch(UINT Handle, CONST float* pNumSegs, CONST D3DTRIPATCH_INFO* pTriPatchInfo) { - return m_pDevice->DrawTriPatch(Handle, pNumSegs, pTriPatchInfo); + return CDirect3DEvents9::DrawTriPatchGuarded(m_pDevice, Handle, pNumSegs, pTriPatchInfo); } HRESULT CProxyDirect3DDevice9::DeletePatch(UINT Handle) @@ -956,17 +1933,125 @@ HRESULT CProxyDirect3DDevice9::CreateQuery(D3DQUERYTYPE Type, IDirect3DQuery9** return m_pDevice->CreateQuery(Type, ppQuery); } +void CProxyDirect3DDevice9::ReleaseCachedResources() +{ + for (uint i = 0; i < NUMELMS(DeviceState.TextureState); ++i) + { + ReleaseInterface(DeviceState.TextureState[i].Texture, 8799, "ReleaseCachedResources Texture"); + } + + for (uint i = 0; i < NUMELMS(DeviceState.VertexStreams); ++i) + { + ReleaseInterface(DeviceState.VertexStreams[i].StreamData, 8799, "ReleaseCachedResources VertexStream"); + DeviceState.VertexStreams[i].StreamOffset = 0; + DeviceState.VertexStreams[i].StreamStride = 0; + } + + ReleaseInterface(DeviceState.VertexDeclaration, 8799, "ReleaseCachedResources VertexDecl"); + ReleaseInterface(DeviceState.VertexShader, 8799, "ReleaseCachedResources VertexShader"); + ReleaseInterface(DeviceState.PixelShader, 8799, "ReleaseCachedResources PixelShader"); + ReleaseInterface(DeviceState.IndexBufferData, 8799, "ReleaseCachedResources IndexBuffer"); + ReleaseInterface(DeviceState.MainSceneState.DepthBuffer, 8799, "ReleaseCachedResources DepthBuffer"); +} + // For debugging -void CProxyDirect3DDevice9::SetCallType(SCallState::eD3DCallType callType, uint uiNumArgs, ...) +void CProxyDirect3DDevice9::SetCallType(SCallState::eD3DCallType callType, std::initializer_list args) { DeviceState.CallState.callType = callType; - DeviceState.CallState.uiNumArgs = uiNumArgs; - if (uiNumArgs) + + const uint maxArgs = static_cast(NUMELMS(DeviceState.CallState.args)); + const uint clampedCount = std::min(static_cast(args.size()), maxArgs); + DeviceState.CallState.uiNumArgs = clampedCount; + + uint index = 0; + for (int value : args) + { + if (index >= maxArgs) + break; + DeviceState.CallState.args[index++] = value; + } + + for (; index < maxArgs; ++index) + { + DeviceState.CallState.args[index] = 0; + } +} + +CProxyDirect3DDevice9* AcquireActiveProxyDevice() +{ + std::lock_guard guard(g_proxyDeviceMutex); + if (g_pProxyDevice) + g_pProxyDevice->AddRef(); + return g_pProxyDevice; +} + +void ReleaseActiveProxyDevice(CProxyDirect3DDevice9* pProxyDevice) +{ + if (pProxyDevice) + pProxyDevice->Release(); +} + +bool BeginSceneWithoutProxy(IDirect3DDevice9* pDevice, ESceneOwner owner) +{ + if (!pDevice || owner == ESceneOwner::None) + return false; + + const HRESULT hr = pDevice->BeginScene(); + if (FAILED(hr)) { - va_list vl; - va_start(vl, uiNumArgs); - for (uint i = 0; i < uiNumArgs && i < NUMELMS(DeviceState.CallState.args); i++) - DeviceState.CallState.args[i] = va_arg(vl, int); - va_end(vl); + return false; } + + if (owner == ESceneOwner::GTA) + { + IncrementGTASceneState(); + } + else if (owner == ESceneOwner::MTA) + { + g_bInMTAScene.store(true, std::memory_order_release); + } + + return true; +} + +bool EndSceneWithoutProxy(IDirect3DDevice9* pDevice, ESceneOwner owner) +{ + if (!pDevice || owner == ESceneOwner::None) + return false; + + const HRESULT hr = pDevice->EndScene(); + if (FAILED(hr)) + { + WriteDebugEvent(SString("EndSceneWithoutProxy failed: %08x", hr)); + if (owner == ESceneOwner::GTA) + { + ResetGTASceneState(); + } + else if (owner == ESceneOwner::MTA) + { + g_bInMTAScene.store(false, std::memory_order_release); + } + return false; + } + + if (owner == ESceneOwner::GTA) + { + DecrementGTASceneState(); + } + else if (owner == ESceneOwner::MTA) + { + g_bInMTAScene.store(false, std::memory_order_release); + } + + return true; +} + +CScopedActiveProxyDevice::CScopedActiveProxyDevice() : m_pProxy(AcquireActiveProxyDevice()) +{ +} + +CScopedActiveProxyDevice::~CScopedActiveProxyDevice() +{ + ReleaseActiveProxyDevice(m_pProxy); + m_pProxy = nullptr; } diff --git a/Client/core/DXHook/CProxyDirect3DDevice9.h b/Client/core/DXHook/CProxyDirect3DDevice9.h index fca2702cce0..fdad8b87d35 100644 --- a/Client/core/DXHook/CProxyDirect3DDevice9.h +++ b/Client/core/DXHook/CProxyDirect3DDevice9.h @@ -12,6 +12,7 @@ #pragma once #include +#include #include "CDirect3DData.h" interface CProxyDirect3DDevice9 : public IDirect3DDevice9 @@ -22,36 +23,38 @@ interface CProxyDirect3DDevice9 : public IDirect3DDevice9 /*** IUnknown methods ***/ virtual HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - virtual ULONG __stdcall AddRef(); - virtual ULONG __stdcall Release(); + virtual ULONG __stdcall AddRef(); + virtual ULONG __stdcall Release(); + HRESULT PresentWithoutProxy(CONST RECT * pSourceRect, CONST RECT * pDestRect, HWND hDestWindowOverride, CONST RGNDATA * pDirtyRegion); /*** IDirect3DDevice9 methods ***/ virtual HRESULT __stdcall TestCooperativeLevel(); - virtual UINT __stdcall GetAvailableTextureMem(); + virtual UINT __stdcall GetAvailableTextureMem(); virtual HRESULT __stdcall EvictManagedResources(); virtual HRESULT __stdcall GetDirect3D(IDirect3D9 * *ppD3D9); virtual HRESULT __stdcall GetDeviceCaps(D3DCAPS9 * pCaps); virtual HRESULT __stdcall GetDisplayMode(UINT iSwapChain, D3DDISPLAYMODE * pMode); virtual HRESULT __stdcall GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS * pParameters); virtual HRESULT __stdcall SetCursorProperties(UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9 * pCursorBitmap); - virtual void __stdcall SetCursorPosition(int X, int Y, DWORD Flags); - virtual BOOL __stdcall ShowCursor(BOOL bShow); + virtual void __stdcall SetCursorPosition(int X, int Y, DWORD Flags); + virtual BOOL __stdcall ShowCursor(BOOL bShow); virtual HRESULT __stdcall CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS * pPresentationParameters, IDirect3DSwapChain9 * *pSwapChain); virtual HRESULT __stdcall GetSwapChain(UINT iSwapChain, IDirect3DSwapChain9 * *pSwapChain); - virtual UINT __stdcall GetNumberOfSwapChains(); + virtual UINT __stdcall GetNumberOfSwapChains(); virtual HRESULT __stdcall Reset(D3DPRESENT_PARAMETERS * pPresentationParameters); virtual HRESULT __stdcall Present(CONST RECT * pSourceRect, CONST RECT * pDestRect, HWND hDestWindowOverride, CONST RGNDATA * pDirtyRegion); virtual HRESULT __stdcall GetBackBuffer(UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9 * *ppBackBuffer); virtual HRESULT __stdcall GetRasterStatus(UINT iSwapChain, D3DRASTER_STATUS * pRasterStatus); virtual HRESULT __stdcall SetDialogBoxMode(BOOL bEnableDialogs); - virtual VOID __stdcall SetGammaRamp(UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP * pRamp); - virtual VOID __stdcall GetGammaRamp(UINT iSwapChain, D3DGAMMARAMP * pRamp); + virtual VOID __stdcall SetGammaRamp(UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP * pRamp); + virtual VOID __stdcall GetGammaRamp(UINT iSwapChain, D3DGAMMARAMP * pRamp); virtual HRESULT __stdcall CreateTexture(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9 * *ppTexture, HANDLE * pSharedHandle); virtual HRESULT __stdcall CreateVolumeTexture(UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture9 * *ppVolumeTexture, HANDLE * pSharedHandle); virtual HRESULT __stdcall CreateCubeTexture(UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture9 * *ppCubeTexture, HANDLE * pSharedHandle); + void ApplyBorderlessPresentationTuning(); virtual HRESULT __stdcall CreateVertexBuffer(UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9 * *ppVertexBuffer, HANDLE * pSharedHandle); virtual HRESULT __stdcall CreateIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9 * *ppIndexBuffer, @@ -111,9 +114,9 @@ interface CProxyDirect3DDevice9 : public IDirect3DDevice9 virtual HRESULT __stdcall SetScissorRect(CONST RECT * pRect); virtual HRESULT __stdcall GetScissorRect(RECT * pRect); virtual HRESULT __stdcall SetSoftwareVertexProcessing(BOOL bSoftware); - virtual BOOL __stdcall GetSoftwareVertexProcessing(); + virtual BOOL __stdcall GetSoftwareVertexProcessing(); virtual HRESULT __stdcall SetNPatchMode(float nSegments); - virtual FLOAT __stdcall GetNPatchMode(); + virtual FLOAT __stdcall GetNPatchMode(); virtual HRESULT __stdcall DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount); virtual HRESULT __stdcall DrawIndexedPrimitive(D3DPRIMITIVETYPE, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount); @@ -159,8 +162,15 @@ interface CProxyDirect3DDevice9 : public IDirect3DDevice9 virtual HRESULT __stdcall CreateQuery(D3DQUERYTYPE Type, IDirect3DQuery9 * *ppQuery); private: + void ReleaseCachedResources(); + IDirect3DDevice9* m_pDevice; CDirect3DData* m_pData; + std::atomic m_lRefCount; + std::atomic m_deviceRefCount; + std::atomic m_bBeginSceneSuccess; + uint64_t m_registrationToken; + HRESULT m_lastTestCooperativeLevelResult; public: // @@ -172,8 +182,8 @@ interface CProxyDirect3DDevice9 : public IDirect3DDevice9 const static int D3DSAMP_MAX = 14; const static int D3DTS_MAX = 260; - #define DPAD(f,t) DWORD pad##f##_##t[(t)-(f)+1] - #define MPAD(f,t) D3DMATRIX pad##f##_##t[(t)-(f)+1] +#define DPAD(f, t) DWORD pad##f##_##t[(t) - (f) + 1] +#define MPAD(f, t) D3DMATRIX pad##f##_##t[(t) - (f) + 1] struct SD3DRenderState { @@ -183,127 +193,127 @@ interface CProxyDirect3DDevice9 : public IDirect3DDevice9 struct { DPAD(0, 6); - D3DZBUFFERTYPE ZENABLE; // = 7, /* D3DZBUFFERTYPE (or TRUE/FALSE for legacy) */ - D3DFILLMODE FILLMODE; // = 8, /* D3DFILLMODE */ - D3DSHADEMODE SHADEMODE; // = 9, /* D3DSHADEMODE */ + D3DZBUFFERTYPE ZENABLE; // = 7, /* D3DZBUFFERTYPE (or TRUE/FALSE for legacy) */ + D3DFILLMODE FILLMODE; // = 8, /* D3DFILLMODE */ + D3DSHADEMODE SHADEMODE; // = 9, /* D3DSHADEMODE */ DPAD(10, 13); - DWORD ZWRITEENABLE; // = 14, /* TRUE to enable z writes */ - DWORD ALPHATESTENABLE; // = 15, /* TRUE to enable alpha tests */ - DWORD LASTPIXEL; // = 16, /* TRUE for last-pixel on lines */ + DWORD ZWRITEENABLE; // = 14, /* TRUE to enable z writes */ + DWORD ALPHATESTENABLE; // = 15, /* TRUE to enable alpha tests */ + DWORD LASTPIXEL; // = 16, /* TRUE for last-pixel on lines */ DPAD(17, 18); - D3DBLEND SRCBLEND; // = 19, /* D3DBLEND */ - D3DBLEND DESTBLEND; // = 20, /* D3DBLEND */ + D3DBLEND SRCBLEND; // = 19, /* D3DBLEND */ + D3DBLEND DESTBLEND; // = 20, /* D3DBLEND */ DPAD(21, 21); - D3DCULL CULLMODE; // = 22, /* D3DCULL */ - D3DCMPFUNC ZFUNC; // = 23, /* D3DCMPFUNC */ - DWORD ALPHAREF; // = 24, /* D3DFIXED */ - D3DCMPFUNC ALPHAFUNC; // = 25, /* D3DCMPFUNC */ - DWORD DITHERENABLE; // = 26, /* TRUE to enable dithering */ - DWORD ALPHABLENDENABLE; // = 27, /* TRUE to enable alpha blending */ - DWORD FOGENABLE; // = 28, /* TRUE to enable fog blending */ - DWORD SPECULARENABLE; // = 29, /* TRUE to enable specular */ + D3DCULL CULLMODE; // = 22, /* D3DCULL */ + D3DCMPFUNC ZFUNC; // = 23, /* D3DCMPFUNC */ + DWORD ALPHAREF; // = 24, /* D3DFIXED */ + D3DCMPFUNC ALPHAFUNC; // = 25, /* D3DCMPFUNC */ + DWORD DITHERENABLE; // = 26, /* TRUE to enable dithering */ + DWORD ALPHABLENDENABLE; // = 27, /* TRUE to enable alpha blending */ + DWORD FOGENABLE; // = 28, /* TRUE to enable fog blending */ + DWORD SPECULARENABLE; // = 29, /* TRUE to enable specular */ DPAD(30, 33); - D3DCOLOR FOGCOLOR; // = 34, /* D3DCOLOR */ - D3DFOGMODE FOGTABLEMODE; // = 35, /* D3DFOGMODE */ - DWORD FOGSTART; // = 36, /* Fog start (for both vertex and pixel fog) */ - DWORD FOGEND; // = 37, /* Fog end */ - DWORD FOGDENSITY; // = 38, /* Fog density */ + D3DCOLOR FOGCOLOR; // = 34, /* D3DCOLOR */ + D3DFOGMODE FOGTABLEMODE; // = 35, /* D3DFOGMODE */ + DWORD FOGSTART; // = 36, /* Fog start (for both vertex and pixel fog) */ + DWORD FOGEND; // = 37, /* Fog end */ + DWORD FOGDENSITY; // = 38, /* Fog density */ DPAD(39, 47); - DWORD RANGEFOGENABLE; // = 48, /* Enables range-based fog */ + DWORD RANGEFOGENABLE; // = 48, /* Enables range-based fog */ DPAD(49, 51); - DWORD STENCILENABLE; // = 52, /* BOOL enable/disable stenciling */ - D3DSTENCILOP STENCILFAIL; // = 53, /* D3DSTENCILOP to do if stencil test fails */ - D3DSTENCILOP STENCILZFAIL; // = 54, /* D3DSTENCILOP to do if stencil test passes and Z test fails */ - D3DSTENCILOP STENCILPASS; // = 55, /* D3DSTENCILOP to do if both stencil and Z tests pass */ - D3DCMPFUNC STENCILFUNC; // = 56, /* D3DCMPFUNC fn. Stencil Test passes if ((ref & mask) stencilfn (stencil & mask)) is true */ - DWORD STENCILREF; // = 57, /* Reference value used in stencil test */ - DWORD STENCILMASK; // = 58, /* Mask value used in stencil test */ - DWORD STENCILWRITEMASK; // = 59, /* Write mask applied to values written to stencil buffer */ - D3DCOLOR TEXTUREFACTOR; // = 60, /* D3DCOLOR used for multi-texture blend */ + DWORD STENCILENABLE; // = 52, /* BOOL enable/disable stenciling */ + D3DSTENCILOP STENCILFAIL; // = 53, /* D3DSTENCILOP to do if stencil test fails */ + D3DSTENCILOP STENCILZFAIL; // = 54, /* D3DSTENCILOP to do if stencil test passes and Z test fails */ + D3DSTENCILOP STENCILPASS; // = 55, /* D3DSTENCILOP to do if both stencil and Z tests pass */ + D3DCMPFUNC STENCILFUNC; // = 56, /* D3DCMPFUNC fn. Stencil Test passes if ((ref & mask) stencilfn (stencil & mask)) is true */ + DWORD STENCILREF; // = 57, /* Reference value used in stencil test */ + DWORD STENCILMASK; // = 58, /* Mask value used in stencil test */ + DWORD STENCILWRITEMASK; // = 59, /* Write mask applied to values written to stencil buffer */ + D3DCOLOR TEXTUREFACTOR; // = 60, /* D3DCOLOR used for multi-texture blend */ DPAD(61, 127); - DWORD WRAP0; // = 128, /* wrap for 1st texture coord. set */ - DWORD WRAP1; // = 129, /* wrap for 2nd texture coord. set */ - DWORD WRAP2; // = 130, /* wrap for 3rd texture coord. set */ - DWORD WRAP3; // = 131, /* wrap for 4th texture coord. set */ - DWORD WRAP4; // = 132, /* wrap for 5th texture coord. set */ - DWORD WRAP5; // = 133, /* wrap for 6th texture coord. set */ - DWORD WRAP6; // = 134, /* wrap for 7th texture coord. set */ - DWORD WRAP7; // = 135, /* wrap for 8th texture coord. set */ - DWORD CLIPPING; // = 136, - DWORD LIGHTING; // = 137, + DWORD WRAP0; // = 128, /* wrap for 1st texture coord. set */ + DWORD WRAP1; // = 129, /* wrap for 2nd texture coord. set */ + DWORD WRAP2; // = 130, /* wrap for 3rd texture coord. set */ + DWORD WRAP3; // = 131, /* wrap for 4th texture coord. set */ + DWORD WRAP4; // = 132, /* wrap for 5th texture coord. set */ + DWORD WRAP5; // = 133, /* wrap for 6th texture coord. set */ + DWORD WRAP6; // = 134, /* wrap for 7th texture coord. set */ + DWORD WRAP7; // = 135, /* wrap for 8th texture coord. set */ + DWORD CLIPPING; // = 136, + DWORD LIGHTING; // = 137, DPAD(138, 138); - D3DCOLOR AMBIENT; // = 139, - DWORD FOGVERTEXMODE; // = 140, - DWORD COLORVERTEX; // = 141, - DWORD LOCALVIEWER; // = 142, - DWORD NORMALIZENORMALS; // = 143, + D3DCOLOR AMBIENT; // = 139, + DWORD FOGVERTEXMODE; // = 140, + DWORD COLORVERTEX; // = 141, + DWORD LOCALVIEWER; // = 142, + DWORD NORMALIZENORMALS; // = 143, DPAD(144, 144); - DWORD DIFFUSEMATERIALSOURCE; // = 145, - DWORD SPECULARMATERIALSOURCE; // = 146, - DWORD AMBIENTMATERIALSOURCE; // = 147, - DWORD EMISSIVEMATERIALSOURCE; // = 148, + DWORD DIFFUSEMATERIALSOURCE; // = 145, + DWORD SPECULARMATERIALSOURCE; // = 146, + DWORD AMBIENTMATERIALSOURCE; // = 147, + DWORD EMISSIVEMATERIALSOURCE; // = 148, DPAD(149, 150); - DWORD VERTEXBLEND; // = 151, - DWORD CLIPPLANEENABLE; // = 152, + DWORD VERTEXBLEND; // = 151, + DWORD CLIPPLANEENABLE; // = 152, DPAD(153, 153); - DWORD POINTSIZE; // = 154, /* float point size */ - DWORD POINTSIZE_MIN; // = 155, /* float point size min threshold */ - DWORD POINTSPRITEENABLE; // = 156, /* BOOL point texture coord control */ - DWORD POINTSCALEENABLE; // = 157, /* BOOL point size scale enable */ - DWORD POINTSCALE_A; // = 158, /* float point attenuation A value */ - DWORD POINTSCALE_B; // = 159, /* float point attenuation B value */ - DWORD POINTSCALE_C; // = 160, /* float point attenuation C value */ - DWORD MULTISAMPLEANTIALIAS; // = 161, // BOOL - set to do FSAA with multisample buffer - DWORD MULTISAMPLEMASK; // = 162, // DWORD -; //per-sample enable/disable - DWORD PATCHEDGESTYLE; // = 163, // Sets whether patch edges will use float style tessellation + DWORD POINTSIZE; // = 154, /* float point size */ + DWORD POINTSIZE_MIN; // = 155, /* float point size min threshold */ + DWORD POINTSPRITEENABLE; // = 156, /* BOOL point texture coord control */ + DWORD POINTSCALEENABLE; // = 157, /* BOOL point size scale enable */ + DWORD POINTSCALE_A; // = 158, /* float point attenuation A value */ + DWORD POINTSCALE_B; // = 159, /* float point attenuation B value */ + DWORD POINTSCALE_C; // = 160, /* float point attenuation C value */ + DWORD MULTISAMPLEANTIALIAS; // = 161, // BOOL - set to do FSAA with multisample buffer + DWORD MULTISAMPLEMASK; // = 162, // DWORD -; //per-sample enable/disable + DWORD PATCHEDGESTYLE; // = 163, // Sets whether patch edges will use float style tessellation DPAD(164, 164); - DWORD DEBUGMONITORTOKEN; // = 165, // DEBUG ONLY - token to debug monitor - DWORD POINTSIZE_MAX; // = 166, /* float point size max threshold */ - DWORD INDEXEDVERTEXBLENDENABLE; // = 167, - DWORD COLORWRITEENABLE; // = 168, // per-channel write enable + DWORD DEBUGMONITORTOKEN; // = 165, // DEBUG ONLY - token to debug monitor + DWORD POINTSIZE_MAX; // = 166, /* float point size max threshold */ + DWORD INDEXEDVERTEXBLENDENABLE; // = 167, + DWORD COLORWRITEENABLE; // = 168, // per-channel write enable DPAD(169, 169); - DWORD TWEENFACTOR; // = 170, // float tween factor - D3DBLENDOP BLENDOP; // = 171, // D3DBLENDOP setting - D3DDEGREETYPE POSITIONDEGREE; // = 172, // NPatch position interpolation degree. D3DDEGREE_LINEAR or D3DDEGREE_CUBIC (default) - D3DDEGREETYPE NORMALDEGREE; // = 173, // NPatch normal interpolation degree. D3DDEGREE_LINEAR (default) or D3DDEGREE_QUADRATIC - DWORD SCISSORTESTENABLE; // = 174, - DWORD SLOPESCALEDEPTHBIAS; // = 175, - DWORD ANTIALIASEDLINEENABLE; // = 176, + DWORD TWEENFACTOR; // = 170, // float tween factor + D3DBLENDOP BLENDOP; // = 171, // D3DBLENDOP setting + D3DDEGREETYPE POSITIONDEGREE; // = 172, // NPatch position interpolation degree. D3DDEGREE_LINEAR or D3DDEGREE_CUBIC (default) + D3DDEGREETYPE NORMALDEGREE; // = 173, // NPatch normal interpolation degree. D3DDEGREE_LINEAR (default) or D3DDEGREE_QUADRATIC + DWORD SCISSORTESTENABLE; // = 174, + DWORD SLOPESCALEDEPTHBIAS; // = 175, + DWORD ANTIALIASEDLINEENABLE; // = 176, DPAD(177, 177); - DWORD MINTESSELLATIONLEVEL; // = 178, - DWORD MAXTESSELLATIONLEVEL; // = 179, - DWORD ADAPTIVETESS_X; // = 180, - DWORD ADAPTIVETESS_Y; // = 181, - DWORD ADAPTIVETESS_Z; // = 182, - DWORD ADAPTIVETESS_W; // = 183, - DWORD ENABLEADAPTIVETESSELLATION; // = 184, - DWORD TWOSIDEDSTENCILMODE; // = 185, /* BOOL enable/disable 2 sided stenciling */ - D3DSTENCILOP CCW_STENCILFAIL; // = 186, /* D3DSTENCILOP to do if ccw stencil test fails */ - D3DSTENCILOP CCW_STENCILZFAIL; // = 187, /* D3DSTENCILOP to do if ccw stencil test passes and Z test fails */ - D3DSTENCILOP CCW_STENCILPASS; // = 188, /* D3DSTENCILOP to do if both ccw stencil and Z tests pass */ + DWORD MINTESSELLATIONLEVEL; // = 178, + DWORD MAXTESSELLATIONLEVEL; // = 179, + DWORD ADAPTIVETESS_X; // = 180, + DWORD ADAPTIVETESS_Y; // = 181, + DWORD ADAPTIVETESS_Z; // = 182, + DWORD ADAPTIVETESS_W; // = 183, + DWORD ENABLEADAPTIVETESSELLATION; // = 184, + DWORD TWOSIDEDSTENCILMODE; // = 185, /* BOOL enable/disable 2 sided stenciling */ + D3DSTENCILOP CCW_STENCILFAIL; // = 186, /* D3DSTENCILOP to do if ccw stencil test fails */ + D3DSTENCILOP CCW_STENCILZFAIL; // = 187, /* D3DSTENCILOP to do if ccw stencil test passes and Z test fails */ + D3DSTENCILOP CCW_STENCILPASS; // = 188, /* D3DSTENCILOP to do if both ccw stencil and Z tests pass */ D3DCMPFUNC - CCW_STENCILFUNC; // = 189, /* D3DCMPFUNC fn. ccw Stencil Test passes if ((ref & mask) stencilfn (stencil & mask)) is true */ - DWORD COLORWRITEENABLE1; // = 190, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS - // */ - DWORD COLORWRITEENABLE2; // = 191, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS - // */ - DWORD COLORWRITEENABLE3; // = 192, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS - // */ - D3DCOLOR BLENDFACTOR; // = 193, /* D3DCOLOR used for a constant blend factor during alpha blending for devices that support - // D3DPBLENDCAPS_BLENDFACTOR */ - DWORD SRGBWRITEENABLE; // = 194, /* Enable rendertarget writes to be DE-linearized to SRGB (for formats that expose - // D3DUSAGE_QUERY_SRGBWRITE) */ - DWORD DEPTHBIAS; // = 195, + CCW_STENCILFUNC; // = 189, /* D3DCMPFUNC fn. ccw Stencil Test passes if ((ref & mask) stencilfn (stencil & mask)) is true */ + DWORD COLORWRITEENABLE1; // = 190, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS + // */ + DWORD COLORWRITEENABLE2; // = 191, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS + // */ + DWORD COLORWRITEENABLE3; // = 192, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS + // */ + D3DCOLOR BLENDFACTOR; // = 193, /* D3DCOLOR used for a constant blend factor during alpha blending for devices that support + // D3DPBLENDCAPS_BLENDFACTOR */ + DWORD SRGBWRITEENABLE; // = 194, /* Enable rendertarget writes to be DE-linearized to SRGB (for formats that expose + // D3DUSAGE_QUERY_SRGBWRITE) */ + DWORD DEPTHBIAS; // = 195, DPAD(196, 197); - DWORD WRAP8; // = 198, /* Additional wrap states for vs_3_0+ attributes with D3DDECLUSAGE_TEXCOORD */ - DWORD WRAP9; // = 199, - DWORD WRAP10; // = 200, - DWORD WRAP11; // = 201, - DWORD WRAP12; // = 202, - DWORD WRAP13; // = 203, - DWORD WRAP14; // = 204, - DWORD WRAP15; // = 205, - DWORD SEPARATEALPHABLENDENABLE; // = 206, /* TRUE to enable a separate blending function for the alpha channel */ + DWORD WRAP8; // = 198, /* Additional wrap states for vs_3_0+ attributes with D3DDECLUSAGE_TEXCOORD */ + DWORD WRAP9; // = 199, + DWORD WRAP10; // = 200, + DWORD WRAP11; // = 201, + DWORD WRAP12; // = 202, + DWORD WRAP13; // = 203, + DWORD WRAP14; // = 204, + DWORD WRAP15; // = 205, + DWORD SEPARATEALPHABLENDENABLE; // = 206, /* TRUE to enable a separate blending function for the alpha channel */ DWORD SRCBLENDALPHA; // = 207, /* SRC blend factor for the alpha channel when DWORD SEPARATEDESTALPHAENABLE; //is TRUE */ DWORD DESTBLENDALPHA; // = 208, /* DST blend factor for the alpha channel when DWORD SEPARATEDESTALPHAENABLE; //is TRUE */ DWORD BLENDOPALPHA; // = 209, /* Blending operation for the alpha channel when DWORD SEPARATEDESTALPHAENABLE; //is TRUE */ @@ -319,27 +329,27 @@ interface CProxyDirect3DDevice9 : public IDirect3DDevice9 struct { DPAD(0, 0); - D3DTEXTUREOP COLOROP; // = 1, /* D3DTEXTUREOP - per-stage blending controls for color channels */ - DWORD COLORARG1; // = 2, /* D3DTA_* (texture arg) */ - DWORD COLORARG2; // = 3, /* D3DTA_* (texture arg) */ - D3DTEXTUREOP ALPHAOP; // = 4, /* D3DTEXTUREOP - per-stage blending controls for alpha channel */ - DWORD ALPHAARG1; // = 5, /* D3DTA_* (texture arg) */ - DWORD ALPHAARG2; // = 6, /* D3DTA_* (texture arg) */ - DWORD BUMPENVMAT00; // = 7, /* float (bump mapping matrix) */ - DWORD BUMPENVMAT01; // = 8, /* float (bump mapping matrix) */ - DWORD BUMPENVMAT10; // = 9, /* float (bump mapping matrix) */ - DWORD BUMPENVMAT11; // = 10, /* float (bump mapping matrix) */ - DWORD TEXCOORDINDEX; // = 11, /* identifies which set of texture coordinates index this texture */ + D3DTEXTUREOP COLOROP; // = 1, /* D3DTEXTUREOP - per-stage blending controls for color channels */ + DWORD COLORARG1; // = 2, /* D3DTA_* (texture arg) */ + DWORD COLORARG2; // = 3, /* D3DTA_* (texture arg) */ + D3DTEXTUREOP ALPHAOP; // = 4, /* D3DTEXTUREOP - per-stage blending controls for alpha channel */ + DWORD ALPHAARG1; // = 5, /* D3DTA_* (texture arg) */ + DWORD ALPHAARG2; // = 6, /* D3DTA_* (texture arg) */ + DWORD BUMPENVMAT00; // = 7, /* float (bump mapping matrix) */ + DWORD BUMPENVMAT01; // = 8, /* float (bump mapping matrix) */ + DWORD BUMPENVMAT10; // = 9, /* float (bump mapping matrix) */ + DWORD BUMPENVMAT11; // = 10, /* float (bump mapping matrix) */ + DWORD TEXCOORDINDEX; // = 11, /* identifies which set of texture coordinates index this texture */ DPAD(12, 21); - DWORD BUMPENVLSCALE; // = 22, /* float scale for bump map luminance */ - DWORD BUMPENVLOFFSET; // = 23, /* float offset for bump map luminance */ - D3DTEXTURETRANSFORMFLAGS TEXTURETRANSFORMFLAGS; // = 24, /* D3DTEXTURETRANSFORMFLAGS controls texture transform */ + DWORD BUMPENVLSCALE; // = 22, /* float scale for bump map luminance */ + DWORD BUMPENVLOFFSET; // = 23, /* float offset for bump map luminance */ + D3DTEXTURETRANSFORMFLAGS TEXTURETRANSFORMFLAGS; // = 24, /* D3DTEXTURETRANSFORMFLAGS controls texture transform */ DPAD(25, 25); - DWORD COLORARG0; // = 26, /* D3DTA_* third arg for triadic ops */ - DWORD ALPHAARG0; // = 27, /* D3DTA_* third arg for triadic ops */ - DWORD RESULTARG; // = 28, /* D3DTA_* arg for result (CURRENT or TEMP) */ + DWORD COLORARG0; // = 26, /* D3DTA_* third arg for triadic ops */ + DWORD ALPHAARG0; // = 27, /* D3DTA_* third arg for triadic ops */ + DWORD RESULTARG; // = 28, /* D3DTA_* arg for result (CURRENT or TEMP) */ DPAD(29, 31); - DWORD CONSTANT; // = 32, /* Per-stage constant D3DTA_CONSTANT */ + DWORD CONSTANT; // = 32, /* Per-stage constant D3DTA_CONSTANT */ }; }; }; @@ -352,23 +362,23 @@ interface CProxyDirect3DDevice9 : public IDirect3DDevice9 struct { DPAD(0, 0); - D3DTEXTUREADDRESS ADDRESSU; // = 1, /* D3DTEXTUREADDRESS for U coordinate */ - D3DTEXTUREADDRESS ADDRESSV; // = 2, /* D3DTEXTUREADDRESS for V coordinate */ - D3DTEXTUREADDRESS ADDRESSW; // = 3, /* D3DTEXTUREADDRESS for W coordinate */ - D3DCOLOR BORDERCOLOR; // = 4, /* D3DCOLOR */ - D3DTEXTUREFILTERTYPE MAGFILTER; // = 5, /* D3DTEXTUREFILTER filter to use for magnification */ - D3DTEXTUREFILTERTYPE MINFILTER; // = 6, /* D3DTEXTUREFILTER filter to use for minification */ - D3DTEXTUREFILTERTYPE MIPFILTER; // = 7, /* D3DTEXTUREFILTER filter to use between mipmaps during minification */ - DWORD MIPMAPLODBIAS; // = 8, /* float Mipmap LOD bias */ - DWORD MAXMIPLEVEL; // = 9, /* DWORD 0..(n-1) LOD index of largest map to use (0 == largest) */ - DWORD MAXANISOTROPY; // = 10, /* DWORD maximum anisotropy */ - DWORD SRGBTEXTURE; // = 11, /* Default = 0 (which means Gamma 1.0, - // no correction required.) else correct for - // Gamma = 2.2 */ - DWORD ELEMENTINDEX; // = 12, /* When multi-element texture is assigned to sampler, this - // indicates which element index to use. Default = 0. */ - DWORD DMAPOFFSET; // = 13, /* Offset in vertices in the pre-sampled displacement map. - // Only valid for D3DDMAPSAMPLER sampler */ + D3DTEXTUREADDRESS ADDRESSU; // = 1, /* D3DTEXTUREADDRESS for U coordinate */ + D3DTEXTUREADDRESS ADDRESSV; // = 2, /* D3DTEXTUREADDRESS for V coordinate */ + D3DTEXTUREADDRESS ADDRESSW; // = 3, /* D3DTEXTUREADDRESS for W coordinate */ + D3DCOLOR BORDERCOLOR; // = 4, /* D3DCOLOR */ + D3DTEXTUREFILTERTYPE MAGFILTER; // = 5, /* D3DTEXTUREFILTER filter to use for magnification */ + D3DTEXTUREFILTERTYPE MINFILTER; // = 6, /* D3DTEXTUREFILTER filter to use for minification */ + D3DTEXTUREFILTERTYPE MIPFILTER; // = 7, /* D3DTEXTUREFILTER filter to use between mipmaps during minification */ + DWORD MIPMAPLODBIAS; // = 8, /* float Mipmap LOD bias */ + DWORD MAXMIPLEVEL; // = 9, /* DWORD 0..(n-1) LOD index of largest map to use (0 == largest) */ + DWORD MAXANISOTROPY; // = 10, /* DWORD maximum anisotropy */ + DWORD SRGBTEXTURE; // = 11, /* Default = 0 (which means Gamma 1.0, + // no correction required.) else correct for + // Gamma = 2.2 */ + DWORD ELEMENTINDEX; // = 12, /* When multi-element texture is assigned to sampler, this + // indicates which element index to use. Default = 0. */ + DWORD DMAPOFFSET; // = 13, /* Offset in vertices in the pre-sampled displacement map. + // Only valid for D3DDMAPSAMPLER sampler */ }; }; }; @@ -380,9 +390,9 @@ interface CProxyDirect3DDevice9 : public IDirect3DDevice9 struct { D3DMATRIX DUMMY; - D3DMATRIX VIEWPROJ[2]; // D3D indices: 2 - 3 - D3DMATRIX TEXTUREn[8]; // D3D indices: 16 - 23 - D3DMATRIX WORLDn[4]; // D3D indices: 256 - 259 + D3DMATRIX VIEWPROJ[2]; // D3D indices: 2 - 3 + D3DMATRIX TEXTUREn[8]; // D3D indices: 16 - 23 + D3DMATRIX WORLDn[4]; // D3D indices: 256 - 259 D3DMATRIX& operator()(uint uiIndex) { // Map requested index to physical data @@ -406,22 +416,22 @@ interface CProxyDirect3DDevice9 : public IDirect3DDevice9 { D3DMATRIX DUMMY; // MPAD(0,1); - D3DMATRIX VIEW; // = 2, - D3DMATRIX PROJECTION; // = 3, + D3DMATRIX VIEW; // = 2, + D3DMATRIX PROJECTION; // = 3, // MPAD(4,15); - D3DMATRIX TEXTURE0; // = 16, - D3DMATRIX TEXTURE1; // = 17, - D3DMATRIX TEXTURE2; // = 18, - D3DMATRIX TEXTURE3; // = 19, - D3DMATRIX TEXTURE4; // = 20, - D3DMATRIX TEXTURE5; // = 21, - D3DMATRIX TEXTURE6; // = 22, - D3DMATRIX TEXTURE7; // = 23, + D3DMATRIX TEXTURE0; // = 16, + D3DMATRIX TEXTURE1; // = 17, + D3DMATRIX TEXTURE2; // = 18, + D3DMATRIX TEXTURE3; // = 19, + D3DMATRIX TEXTURE4; // = 20, + D3DMATRIX TEXTURE5; // = 21, + D3DMATRIX TEXTURE6; // = 22, + D3DMATRIX TEXTURE7; // = 23, // MPAD(24,255); - D3DMATRIX WORLD; // = 256, - D3DMATRIX WORLD1; // = 257, - D3DMATRIX WORLD2; // = 258, - D3DMATRIX WORLD3; // = 259, + D3DMATRIX WORLD; // = 256, + D3DMATRIX WORLD1; // = 257, + D3DMATRIX WORLD2; // = 258, + D3DMATRIX WORLD3; // = 259, }; }; }; @@ -551,8 +561,70 @@ interface CProxyDirect3DDevice9 : public IDirect3DDevice9 std::map m_VertexDeclMap; // Debugging - void SetCallType(SCallState::eD3DCallType callType, uint uiNumArgs = 0, ...); + void SetCallType(SCallState::eD3DCallType callType, std::initializer_list args = {}); }; -extern CProxyDirect3DDevice9* g_pProxyDevice; extern CProxyDirect3DDevice9::SD3DDeviceState* g_pDeviceState; +extern CProxyDirect3DDevice9::SMemoryState g_StaticMemoryState; + +// GTA scene tracking helpers +void ResetGTASceneState(); +void SetSuspendDeviceStateCache(bool bSuspend); + +enum class ESceneOwner +{ + None, + GTA, + MTA, +}; + +bool BeginSceneWithoutProxy(IDirect3DDevice9* pDevice, ESceneOwner owner); +bool EndSceneWithoutProxy(IDirect3DDevice9* pDevice, ESceneOwner owner); + +CProxyDirect3DDevice9* AcquireActiveProxyDevice(); +void ReleaseActiveProxyDevice(CProxyDirect3DDevice9* pProxyDevice); + +class CScopedActiveProxyDevice +{ +public: + CScopedActiveProxyDevice(); + ~CScopedActiveProxyDevice(); + + CScopedActiveProxyDevice(const CScopedActiveProxyDevice&) = delete; + CScopedActiveProxyDevice& operator=(const CScopedActiveProxyDevice&) = delete; + + CProxyDirect3DDevice9* operator->() const { return m_pProxy; } + CProxyDirect3DDevice9* Get() const { return m_pProxy; } + explicit operator bool() const { return m_pProxy != nullptr; } + +private: + CProxyDirect3DDevice9* m_pProxy; +}; + +// Add gamma state management +struct SGammaState +{ + bool bOriginalGammaStored; + bool bLastWasBorderless; + D3DGAMMARAMP originalGammaRamp; + UINT lastSwapChain; + + SGammaState() : bOriginalGammaStored(false), bLastWasBorderless(false), originalGammaRamp{}, lastSwapChain(0) {} +}; + +extern SGammaState g_GammaState; + +namespace BorderlessGamma +{ + extern const float kGammaMin; + extern const float kGammaMax; + extern const float kBrightnessMin; + extern const float kBrightnessMax; + extern const float kContrastMin; + extern const float kContrastMax; + extern const float kSaturationMin; + extern const float kSaturationMax; + + void FetchSettings(float& gammaPower, float& brightnessScale, float& contrastScale, float& saturationScale, bool& applyWindowed, bool& applyFullscreen); + bool ShouldApplyAdjustments(float gammaPower, float brightnessScale, float contrastScale, float saturationScale); +} diff --git a/Client/core/DXHook/CProxyDirect3DEffect.cpp b/Client/core/DXHook/CProxyDirect3DEffect.cpp index 7bb4a792612..2da4dede674 100644 --- a/Client/core/DXHook/CProxyDirect3DEffect.cpp +++ b/Client/core/DXHook/CProxyDirect3DEffect.cpp @@ -10,6 +10,7 @@ #include "StdInc.h" #include "CProxyDirect3DEffect.h" +#include "ComPtrValidation.h" ///////////////////////////////////////////////////////////// // @@ -18,11 +19,11 @@ // // ///////////////////////////////////////////////////////////// -CProxyDirect3DEffect::CProxyDirect3DEffect(IDirect3DDevice9* InD3DDevice9, ID3DXEffect* pOriginal) : m_stats(g_pDeviceState->MemoryState.Effect) +CProxyDirect3DEffect::CProxyDirect3DEffect(IDirect3DDevice9* InD3DDevice9, ID3DXEffect* pOriginal) + : m_pStats(&g_StaticMemoryState.Effect), m_pOriginal(pOriginal), m_lRefCount(1) { - m_pOriginal = pOriginal; - m_stats.iCurrentCount++; - m_stats.iCreatedCount++; + m_pStats->iCurrentCount++; + m_pStats->iCreatedCount++; } ///////////////////////////////////////////////////////////// @@ -34,8 +35,11 @@ CProxyDirect3DEffect::CProxyDirect3DEffect(IDirect3DDevice9* InD3DDevice9, ID3DX ///////////////////////////////////////////////////////////// CProxyDirect3DEffect::~CProxyDirect3DEffect() { - m_stats.iCurrentCount--; - m_stats.iDestroyedCount++; + if (m_pStats) + { + m_pStats->iCurrentCount--; + m_pStats->iDestroyedCount++; + } } ///////////////////////////////////////////////////////////// @@ -53,12 +57,58 @@ HRESULT CProxyDirect3DEffect::QueryInterface(REFIID riid, void** ppvObj) if (riid == CProxyDirect3DEffect_GUID) { *ppvObj = this; + AddRef(); return S_OK; } + if (!IsOriginalValid()) + return E_NOINTERFACE; + return m_pOriginal->QueryInterface(riid, ppvObj); } +///////////////////////////////////////////////////////////// +// +// CProxyDirect3DEffect::IsOriginalValid +// +// Check if the underlying ID3DXEffect pointer is still valid. +// Uses COM pointer validation to detect freed/invalid objects. +// +///////////////////////////////////////////////////////////// +bool CProxyDirect3DEffect::IsOriginalValid() const +{ + if (!m_pOriginal) + return false; + + return IsValidComInterfacePointer(m_pOriginal); +} + +///////////////////////////////////////////////////////////// +// +// CProxyDirect3DEffect::AddRef +// +// Increment reference count. Validates the original pointer +// before forwarding to avoid crashes on invalid COM objects. +// +///////////////////////////////////////////////////////////// +ULONG CProxyDirect3DEffect::AddRef() +{ + LONG newRefCount = m_lRefCount.fetch_add(1, std::memory_order_relaxed) + 1; + + if (IsOriginalValid()) + { + m_pOriginal->AddRef(); + } + else + { + // Original is invalid (e.g., d3d9on12 crash) - null it to prevent + // dangling pointer access from inline methods + m_pOriginal = nullptr; + } + + return static_cast(newRefCount); +} + ///////////////////////////////////////////////////////////// // // CProxyDirect3DEffect::Release @@ -68,16 +118,34 @@ HRESULT CProxyDirect3DEffect::QueryInterface(REFIID riid, void** ppvObj) ///////////////////////////////////////////////////////////// ULONG CProxyDirect3DEffect::Release() { - // Call original function - ULONG count = m_pOriginal->Release(); + LONG newRefCount = m_lRefCount.fetch_sub(1, std::memory_order_acq_rel) - 1; + + // Handle underflow + if (newRefCount < 0) + { + m_lRefCount.store(0, std::memory_order_release); + newRefCount = 0; + } - if (count == 0) + // Release the original if valid + if (IsOriginalValid()) { - // now, the Original Object has deleted itself, so do we here - delete this; // destructor will be called automatically + m_pOriginal->Release(); + } + else + { + // Original is invalid (e.g., d3d9on12 crash) - null it to prevent + // dangling pointer access from inline methods + m_pOriginal = nullptr; } - return count; + // Destroy proxy when refcount reaches 0 + if (newRefCount == 0) + { + delete this; + } + + return static_cast(newRefCount); } ///////////////////////////////////////////////////////////// @@ -89,8 +157,11 @@ ULONG CProxyDirect3DEffect::Release() ///////////////////////////////////////////////////////////// HRESULT CProxyDirect3DEffect::CloneEffect(LPDIRECT3DDEVICE9 pDevice, LPD3DXEFFECT* ppEffect) { + if (!IsOriginalValid()) + return E_FAIL; + HRESULT hr = m_pOriginal->CloneEffect(pDevice, ppEffect); - if (SUCCEEDED(hr)) + if (SUCCEEDED(hr) && ppEffect && *ppEffect) { // Create proxy so we can track when it's finished with *ppEffect = new CProxyDirect3DEffect(pDevice, *ppEffect); diff --git a/Client/core/DXHook/CProxyDirect3DEffect.h b/Client/core/DXHook/CProxyDirect3DEffect.h index 6fbdb129643..f3b91c68cda 100644 --- a/Client/core/DXHook/CProxyDirect3DEffect.h +++ b/Client/core/DXHook/CProxyDirect3DEffect.h @@ -8,6 +8,10 @@ * *****************************************************************************/ +#pragma once + +#include + DEFINE_GUID(CProxyDirect3DEffect_GUID, 0x128A025E, 0x0123, 0x04F1, 0x40, 0x60, 0x53, 0x19, 0x44, 0x56, 0x59, 0x42); class CProxyDirect3DEffect : public ID3DXEffect @@ -15,8 +19,8 @@ class CProxyDirect3DEffect : public ID3DXEffect public: // ID3DXBaseEffect HRESULT __stdcall QueryInterface(REFIID iid, LPVOID* ppv); - ULONG __stdcall AddRef() { return m_pOriginal->AddRef(); } - ULONG __stdcall Release(); + ULONG __stdcall AddRef(); + ULONG __stdcall Release(); // Descs HRESULT __stdcall GetDesc(D3DXEFFECT_DESC* pDesc) { return m_pOriginal->GetDesc(pDesc); } @@ -113,10 +117,10 @@ class CProxyDirect3DEffect : public ID3DXEffect HRESULT __stdcall GetPool(LPD3DXEFFECTPOOL* ppPool) { return m_pOriginal->GetPool(ppPool); } // Selecting and setting a technique - HRESULT __stdcall SetTechnique(D3DXHANDLE hTechnique) { return m_pOriginal->SetTechnique(hTechnique); } + HRESULT __stdcall SetTechnique(D3DXHANDLE hTechnique) { return m_pOriginal->SetTechnique(hTechnique); } D3DXHANDLE __stdcall GetCurrentTechnique() { return m_pOriginal->GetCurrentTechnique(); } - HRESULT __stdcall ValidateTechnique(D3DXHANDLE hTechnique) { return m_pOriginal->ValidateTechnique(hTechnique); } - HRESULT __stdcall FindNextValidTechnique(D3DXHANDLE hTechnique, D3DXHANDLE* pTechnique) + HRESULT __stdcall ValidateTechnique(D3DXHANDLE hTechnique) { return m_pOriginal->ValidateTechnique(hTechnique); } + HRESULT __stdcall FindNextValidTechnique(D3DXHANDLE hTechnique, D3DXHANDLE* pTechnique) { return m_pOriginal->FindNextValidTechnique(hTechnique, pTechnique); } @@ -145,10 +149,10 @@ class CProxyDirect3DEffect : public ID3DXEffect HRESULT __stdcall GetStateManager(LPD3DXEFFECTSTATEMANAGER* ppManager) { return m_pOriginal->GetStateManager(ppManager); } // Parameter blocks - HRESULT __stdcall BeginParameterBlock() { return m_pOriginal->BeginParameterBlock(); } + HRESULT __stdcall BeginParameterBlock() { return m_pOriginal->BeginParameterBlock(); } D3DXHANDLE __stdcall EndParameterBlock() { return m_pOriginal->EndParameterBlock(); } - HRESULT __stdcall ApplyParameterBlock(D3DXHANDLE hParameterBlock) { return m_pOriginal->ApplyParameterBlock(hParameterBlock); } - HRESULT __stdcall DeleteParameterBlock(D3DXHANDLE hParameterBlock) { return m_pOriginal->DeleteParameterBlock(hParameterBlock); } + HRESULT __stdcall ApplyParameterBlock(D3DXHANDLE hParameterBlock) { return m_pOriginal->ApplyParameterBlock(hParameterBlock); } + HRESULT __stdcall DeleteParameterBlock(D3DXHANDLE hParameterBlock) { return m_pOriginal->DeleteParameterBlock(hParameterBlock); } // Cloning HRESULT __stdcall CloneEffect(LPDIRECT3DDEVICE9 pDevice, LPD3DXEFFECT* ppEffect); @@ -164,10 +168,12 @@ class CProxyDirect3DEffect : public ID3DXEffect virtual ~CProxyDirect3DEffect(); ID3DXEffect* GetOriginal() { return m_pOriginal; } + bool IsOriginalValid() const; protected: ID3DXEffect* m_pOriginal; - CProxyDirect3DDevice9::SResourceMemory& m_stats; + CProxyDirect3DDevice9::SResourceMemory* m_pStats; + std::atomic m_lRefCount{1}; }; HRESULT WINAPI MyD3DXCreateEffectFromFile(LPDIRECT3DDEVICE9 pDevice, LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, diff --git a/Client/core/DXHook/CProxyDirect3DIndexBuffer.cpp b/Client/core/DXHook/CProxyDirect3DIndexBuffer.cpp index 63f00124327..34a55bcbe88 100644 --- a/Client/core/DXHook/CProxyDirect3DIndexBuffer.cpp +++ b/Client/core/DXHook/CProxyDirect3DIndexBuffer.cpp @@ -21,7 +21,7 @@ ///////////////////////////////////////////////////////////// CProxyDirect3DIndexBuffer::CProxyDirect3DIndexBuffer(IDirect3DDevice9* InD3DDevice9, IDirect3DIndexBuffer9* pOriginal, UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool) - : m_stats(Usage & D3DUSAGE_DYNAMIC ? g_pDeviceState->MemoryState.DynamicIndexBuffer : g_pDeviceState->MemoryState.StaticIndexBuffer) + : m_pStats(Usage & D3DUSAGE_DYNAMIC ? &g_StaticMemoryState.DynamicIndexBuffer : &g_StaticMemoryState.StaticIndexBuffer) { m_pOriginal = pOriginal; m_iMemUsed = Length; @@ -29,10 +29,10 @@ CProxyDirect3DIndexBuffer::CProxyDirect3DIndexBuffer(IDirect3DDevice9* InD3DDevi m_format = Format; m_pool = Pool; - m_stats.iCurrentCount++; - m_stats.iCurrentBytes += m_iMemUsed; - m_stats.iCreatedCount++; - m_stats.iCreatedBytes += m_iMemUsed; + m_pStats->iCurrentCount++; + m_pStats->iCurrentBytes += m_iMemUsed; + m_pStats->iCreatedCount++; + m_pStats->iCreatedBytes += m_iMemUsed; } ///////////////////////////////////////////////////////////// @@ -44,10 +44,13 @@ CProxyDirect3DIndexBuffer::CProxyDirect3DIndexBuffer(IDirect3DDevice9* InD3DDevi ///////////////////////////////////////////////////////////// CProxyDirect3DIndexBuffer::~CProxyDirect3DIndexBuffer() { - m_stats.iCurrentCount--; - m_stats.iCurrentBytes -= m_iMemUsed; - m_stats.iDestroyedCount++; - m_stats.iDestroyedBytes += m_iMemUsed; + if (m_pStats) + { + m_pStats->iCurrentCount--; + m_pStats->iCurrentBytes -= m_iMemUsed; + m_pStats->iDestroyedCount++; + m_pStats->iDestroyedBytes += m_iMemUsed; + } } ///////////////////////////////////////////////////////////// @@ -65,6 +68,7 @@ HRESULT CProxyDirect3DIndexBuffer::QueryInterface(REFIID riid, void** ppvObj) if (riid == CProxyDirect3DIndexBuffer_GUID) { *ppvObj = this; + AddRef(); return S_OK; } @@ -86,7 +90,7 @@ ULONG CProxyDirect3DIndexBuffer::Release() if (count == 0) { // now, the Original Object has deleted itself, so do we here - delete this; // destructor will be called automatically + delete this; // destructor will be called automatically } return count; @@ -101,7 +105,8 @@ ULONG CProxyDirect3DIndexBuffer::Release() ///////////////////////////////////////////////////////////// HRESULT CProxyDirect3DIndexBuffer::Lock(UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags) { - m_stats.iLockedCount++; + if (m_pStats) + m_pStats->iLockedCount++; *ppbData = NULL; HRESULT hr = m_pOriginal->Lock(OffsetToLock, SizeToLock, ppbData, Flags); diff --git a/Client/core/DXHook/CProxyDirect3DIndexBuffer.h b/Client/core/DXHook/CProxyDirect3DIndexBuffer.h index 8cda4774c4a..4da4b16d289 100644 --- a/Client/core/DXHook/CProxyDirect3DIndexBuffer.h +++ b/Client/core/DXHook/CProxyDirect3DIndexBuffer.h @@ -16,8 +16,8 @@ class CProxyDirect3DIndexBuffer : public IDirect3DIndexBuffer9 public: /*** IUnknown methods ***/ HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef() { return m_pOriginal->AddRef(); } - ULONG __stdcall Release(); + ULONG __stdcall AddRef() { return m_pOriginal->AddRef(); } + ULONG __stdcall Release(); /*** IDirect3DResource9 methods ***/ HRESULT __stdcall GetDevice(IDirect3DDevice9** ppDevice) { return m_pOriginal->GetDevice(ppDevice); } @@ -27,9 +27,9 @@ class CProxyDirect3DIndexBuffer : public IDirect3DIndexBuffer9 } HRESULT __stdcall GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData) { return m_pOriginal->GetPrivateData(refguid, pData, pSizeOfData); } HRESULT __stdcall FreePrivateData(REFGUID refguid) { return m_pOriginal->FreePrivateData(refguid); } - DWORD __stdcall SetPriority(DWORD PriorityNew) { return m_pOriginal->SetPriority(PriorityNew); } - DWORD __stdcall GetPriority() { return m_pOriginal->GetPriority(); } - void __stdcall PreLoad() { return m_pOriginal->PreLoad(); } + DWORD __stdcall SetPriority(DWORD PriorityNew) { return m_pOriginal->SetPriority(PriorityNew); } + DWORD __stdcall GetPriority() { return m_pOriginal->GetPriority(); } + void __stdcall PreLoad() { return m_pOriginal->PreLoad(); } D3DRESOURCETYPE __stdcall GetType() { return m_pOriginal->GetType(); } /*** IDirect3DIndexBuffer9 methods ***/ @@ -49,5 +49,5 @@ class CProxyDirect3DIndexBuffer : public IDirect3DIndexBuffer9 DWORD m_dwUsage; D3DFORMAT m_format; D3DPOOL m_pool; - CProxyDirect3DDevice9::SResourceMemory& m_stats; + CProxyDirect3DDevice9::SResourceMemory* m_pStats; }; diff --git a/Client/core/DXHook/CProxyDirect3DTexture.cpp b/Client/core/DXHook/CProxyDirect3DTexture.cpp index 81eb0c5327e..1f767c9f9cf 100644 --- a/Client/core/DXHook/CProxyDirect3DTexture.cpp +++ b/Client/core/DXHook/CProxyDirect3DTexture.cpp @@ -21,16 +21,16 @@ ///////////////////////////////////////////////////////////// CProxyDirect3DTexture::CProxyDirect3DTexture(IDirect3DDevice9* InD3DDevice9, IDirect3DTexture9* pOriginal, UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool) - : m_stats(Usage & D3DUSAGE_DYNAMIC ? g_pDeviceState->MemoryState.DynamicTexture : g_pDeviceState->MemoryState.StaticTexture) + : m_pStats(Usage & D3DUSAGE_DYNAMIC ? &g_StaticMemoryState.DynamicTexture : &g_StaticMemoryState.StaticTexture) { m_pOriginal = pOriginal; m_iMemUsed = CRenderItemManager::CalcD3DTextureMemoryKBUsage(pOriginal) * 1024; m_dwUsage = Usage; - m_stats.iCurrentCount++; - m_stats.iCurrentBytes += m_iMemUsed; - m_stats.iCreatedCount++; - m_stats.iCreatedBytes += m_iMemUsed; + m_pStats->iCurrentCount++; + m_pStats->iCurrentBytes += m_iMemUsed; + m_pStats->iCreatedCount++; + m_pStats->iCreatedBytes += m_iMemUsed; } ///////////////////////////////////////////////////////////// @@ -42,10 +42,13 @@ CProxyDirect3DTexture::CProxyDirect3DTexture(IDirect3DDevice9* InD3DDevice9, IDi ///////////////////////////////////////////////////////////// CProxyDirect3DTexture::~CProxyDirect3DTexture() { - m_stats.iCurrentCount--; - m_stats.iCurrentBytes -= m_iMemUsed; - m_stats.iDestroyedCount++; - m_stats.iDestroyedBytes += m_iMemUsed; + if (m_pStats) + { + m_pStats->iCurrentCount--; + m_pStats->iCurrentBytes -= m_iMemUsed; + m_pStats->iDestroyedCount++; + m_pStats->iDestroyedBytes += m_iMemUsed; + } } ///////////////////////////////////////////////////////////// @@ -63,6 +66,7 @@ HRESULT CProxyDirect3DTexture::QueryInterface(REFIID riid, void** ppvObj) if (riid == CProxyDirect3DTexture_GUID) { *ppvObj = this; + AddRef(); return S_OK; } @@ -84,7 +88,7 @@ ULONG CProxyDirect3DTexture::Release() if (count == 0) { // now, the Original Object has deleted itself, so do we here - delete this; // destructor will be called automatically + delete this; // destructor will be called automatically } return count; @@ -99,6 +103,7 @@ ULONG CProxyDirect3DTexture::Release() ///////////////////////////////////////////////////////////// HRESULT CProxyDirect3DTexture::LockRect(UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) { - m_stats.iLockedCount++; + if (m_pStats) + m_pStats->iLockedCount++; return m_pOriginal->LockRect(Level, pLockedRect, pRect, Flags); } diff --git a/Client/core/DXHook/CProxyDirect3DTexture.h b/Client/core/DXHook/CProxyDirect3DTexture.h index 96df4975dcc..1500e0e6ced 100644 --- a/Client/core/DXHook/CProxyDirect3DTexture.h +++ b/Client/core/DXHook/CProxyDirect3DTexture.h @@ -16,8 +16,8 @@ class CProxyDirect3DTexture : public IDirect3DTexture9 public: /*** IUnknown methods ***/ HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef() { return m_pOriginal->AddRef(); } - ULONG __stdcall Release(); + ULONG __stdcall AddRef() { return m_pOriginal->AddRef(); } + ULONG __stdcall Release(); /*** IDirect3DResource9 methods ***/ HRESULT __stdcall GetDevice(IDirect3DDevice9** ppDevice) { return m_pOriginal->GetDevice(ppDevice); } @@ -27,18 +27,18 @@ class CProxyDirect3DTexture : public IDirect3DTexture9 } HRESULT __stdcall GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData) { return m_pOriginal->GetPrivateData(refguid, pData, pSizeOfData); } HRESULT __stdcall FreePrivateData(REFGUID refguid) { return m_pOriginal->FreePrivateData(refguid); } - DWORD __stdcall SetPriority(DWORD PriorityNew) { return m_pOriginal->SetPriority(PriorityNew); } - DWORD __stdcall GetPriority() { return m_pOriginal->GetPriority(); } - void __stdcall PreLoad() { return m_pOriginal->PreLoad(); } + DWORD __stdcall SetPriority(DWORD PriorityNew) { return m_pOriginal->SetPriority(PriorityNew); } + DWORD __stdcall GetPriority() { return m_pOriginal->GetPriority(); } + void __stdcall PreLoad() { return m_pOriginal->PreLoad(); } D3DRESOURCETYPE __stdcall GetType() { return m_pOriginal->GetType(); } /*** IDirect3DBaseTexture9 methods ***/ - DWORD __stdcall SetLOD(DWORD LODNew) { return m_pOriginal->SetLOD(LODNew); } - DWORD __stdcall GetLOD() { return m_pOriginal->GetLOD(); } - DWORD __stdcall GetLevelCount() { return m_pOriginal->GetLevelCount(); } + DWORD __stdcall SetLOD(DWORD LODNew) { return m_pOriginal->SetLOD(LODNew); } + DWORD __stdcall GetLOD() { return m_pOriginal->GetLOD(); } + DWORD __stdcall GetLevelCount() { return m_pOriginal->GetLevelCount(); } HRESULT __stdcall SetAutoGenFilterType(D3DTEXTUREFILTERTYPE FilterType) { return m_pOriginal->SetAutoGenFilterType(FilterType); } D3DTEXTUREFILTERTYPE - __stdcall GetAutoGenFilterType() { return m_pOriginal->GetAutoGenFilterType(); } + __stdcall GetAutoGenFilterType() { return m_pOriginal->GetAutoGenFilterType(); } void __stdcall GenerateMipSubLevels() { return m_pOriginal->GenerateMipSubLevels(); } /*** IDirect3DTexture9 methods ***/ @@ -59,5 +59,5 @@ class CProxyDirect3DTexture : public IDirect3DTexture9 IDirect3DTexture9* m_pOriginal; int m_iMemUsed; DWORD m_dwUsage; - CProxyDirect3DDevice9::SResourceMemory& m_stats; + CProxyDirect3DDevice9::SResourceMemory* m_pStats; }; diff --git a/Client/core/DXHook/CProxyDirect3DVertexBuffer.cpp b/Client/core/DXHook/CProxyDirect3DVertexBuffer.cpp index 93d6b7deac5..3810d4760e5 100644 --- a/Client/core/DXHook/CProxyDirect3DVertexBuffer.cpp +++ b/Client/core/DXHook/CProxyDirect3DVertexBuffer.cpp @@ -2,8 +2,8 @@ * * PROJECT: Multi Theft Auto v1.0 * LICENSE: See LICENSE in the top level directory - * FILE: - * PURPOSE: + * FILE: core/CProxyDirect3DVertexBuffer.cpp + * PURPOSE: Direct3D 9 vertex buffer function hooking proxy * * Multi Theft Auto is available from https://www.multitheftauto.com/ * @@ -13,6 +13,8 @@ #include "CProxyDirect3DVertexBuffer.h" #include "CAdditionalVertexStreamManager.h" #include "CVertexStreamBoundingBoxManager.h" +#include +#include ///////////////////////////////////////////////////////////// // @@ -23,18 +25,22 @@ ///////////////////////////////////////////////////////////// CProxyDirect3DVertexBuffer::CProxyDirect3DVertexBuffer(IDirect3DDevice9* InD3DDevice9, IDirect3DVertexBuffer9* pOriginal, UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool) - : m_stats(Usage & D3DUSAGE_DYNAMIC ? g_pDeviceState->MemoryState.DynamicVertexBuffer : g_pDeviceState->MemoryState.StaticVertexBuffer) + : m_pStats(Usage & D3DUSAGE_DYNAMIC ? &g_StaticMemoryState.DynamicVertexBuffer : &g_StaticMemoryState.StaticVertexBuffer) { m_pOriginal = pOriginal; m_iMemUsed = Length; m_dwUsage = Usage; m_dwFVF = FVF; m_pool = Pool; + m_bFallbackActive = false; + m_fallbackOffset = 0; + m_fallbackSize = 0; + m_fallbackFlags = 0; - m_stats.iCurrentCount++; - m_stats.iCurrentBytes += m_iMemUsed; - m_stats.iCreatedCount++; - m_stats.iCreatedBytes += m_iMemUsed; + m_pStats->iCurrentCount++; + m_pStats->iCurrentBytes += m_iMemUsed; + m_pStats->iCreatedCount++; + m_pStats->iCreatedBytes += m_iMemUsed; } ///////////////////////////////////////////////////////////// @@ -46,13 +52,18 @@ CProxyDirect3DVertexBuffer::CProxyDirect3DVertexBuffer(IDirect3DDevice9* InD3DDe ///////////////////////////////////////////////////////////// CProxyDirect3DVertexBuffer::~CProxyDirect3DVertexBuffer() { - CAdditionalVertexStreamManager::GetSingleton()->OnVertexBufferDestroy(m_pOriginal); - CVertexStreamBoundingBoxManager::GetSingleton()->OnVertexBufferDestroy(m_pOriginal); + if (CAdditionalVertexStreamManager* pManager = CAdditionalVertexStreamManager::GetExistingSingleton()) + pManager->OnVertexBufferDestroy(m_pOriginal); + if (CVertexStreamBoundingBoxManager* pBoundingBoxManager = CVertexStreamBoundingBoxManager::GetExistingSingleton()) + pBoundingBoxManager->OnVertexBufferDestroy(m_pOriginal); - m_stats.iCurrentCount--; - m_stats.iCurrentBytes -= m_iMemUsed; - m_stats.iDestroyedCount++; - m_stats.iDestroyedBytes += m_iMemUsed; + if (m_pStats) + { + m_pStats->iCurrentCount--; + m_pStats->iCurrentBytes -= m_iMemUsed; + m_pStats->iDestroyedCount++; + m_pStats->iDestroyedBytes += m_iMemUsed; + } } ///////////////////////////////////////////////////////////// @@ -64,12 +75,13 @@ CProxyDirect3DVertexBuffer::~CProxyDirect3DVertexBuffer() ///////////////////////////////////////////////////////////// HRESULT CProxyDirect3DVertexBuffer::QueryInterface(REFIID riid, void** ppvObj) { - *ppvObj = NULL; + *ppvObj = nullptr; // Looking for me? if (riid == CProxyDirect3DVertexBuffer_GUID) { *ppvObj = this; + AddRef(); return S_OK; } @@ -86,15 +98,10 @@ HRESULT CProxyDirect3DVertexBuffer::QueryInterface(REFIID riid, void** ppvObj) ULONG CProxyDirect3DVertexBuffer::Release() { // Call original function - ULONG count = m_pOriginal->Release(); - - if (count == 0) - { - // now, the Original Object has deleted itself, so do we here - delete this; // destructor will be called automatically - } - - return count; + ULONG ulRefCount = m_pOriginal->Release(); + if (ulRefCount == 0) + delete this; + return ulRefCount; } ///////////////////////////////////////////////////////////// @@ -106,19 +113,164 @@ ULONG CProxyDirect3DVertexBuffer::Release() ///////////////////////////////////////////////////////////// HRESULT CProxyDirect3DVertexBuffer::Lock(UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags) { - m_stats.iLockedCount++; + if (m_pStats) + m_pStats->iLockedCount++; if ((Flags & D3DLOCK_READONLY) == 0) { - CAdditionalVertexStreamManager::GetSingleton()->OnVertexBufferRangeInvalidated(m_pOriginal, OffsetToLock, SizeToLock); - CVertexStreamBoundingBoxManager::GetSingleton()->OnVertexBufferRangeInvalidated(m_pOriginal, OffsetToLock, SizeToLock); + if (CAdditionalVertexStreamManager* pManager = CAdditionalVertexStreamManager::GetExistingSingleton()) + pManager->OnVertexBufferRangeInvalidated(m_pOriginal, OffsetToLock, SizeToLock); + if (CVertexStreamBoundingBoxManager* pBoundingBoxManager = CVertexStreamBoundingBoxManager::GetExistingSingleton()) + pBoundingBoxManager->OnVertexBufferRangeInvalidated(m_pOriginal, OffsetToLock, SizeToLock); } - *ppbData = NULL; + SharedUtil::CAutoCSLock fallbackGuard(m_fallbackCS); + + if (m_bFallbackActive) + { + if (ppbData) + *ppbData = nullptr; + + SString strMessage("Lock VertexBuffer: fallback still pending - refusing new lock (Offset:%x Size:%x Flags:%08x)", m_fallbackOffset, m_fallbackSize, + m_fallbackFlags); + WriteDebugEvent(strMessage); + AddReportLog(8624, strMessage); + CCore::GetSingleton().LogEvent(624, "Lock VertexBuffer", "", strMessage); + + return D3DERR_WASSTILLDRAWING; + } + + m_bFallbackActive = false; + m_fallbackOffset = 0; + m_fallbackSize = 0; + m_fallbackFlags = 0; + + *ppbData = nullptr; HRESULT hr = DoLock(OffsetToLock, SizeToLock, ppbData, Flags); + HRESULT originalHr = hr; + + bool bPointerNullEvent = SUCCEEDED(hr) && (*ppbData == nullptr); + bool bRetryAttempted = false; + bool bRetrySucceeded = false; + bool bFallbackUsed = false; + bool bUnlockedAfterNull = false; + DWORD retryFlags = Flags; + + if (bPointerNullEvent) + { + WriteDebugEvent( + SString("Lock VertexBuffer: initial pointer null (Usage:%08x Flags:%08x Offset:%x Size:%x)", m_dwUsage, Flags, OffsetToLock, SizeToLock)); + + // Retry once for dynamic buffers using DISCARD + if ((m_dwUsage & D3DUSAGE_DYNAMIC) && (Flags & D3DLOCK_READONLY) == 0) + { + bRetryAttempted = true; + + retryFlags &= ~(DWORD)(D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD | D3DLOCK_READONLY); + retryFlags |= D3DLOCK_DISCARD; + + // Release the bogus lock result before retrying + m_pOriginal->Unlock(); + bUnlockedAfterNull = true; + + void* pRetryData = nullptr; + hr = DoLock(OffsetToLock, SizeToLock, &pRetryData, retryFlags); + + if (SUCCEEDED(hr) && pRetryData != nullptr) + { + *ppbData = pRetryData; + bPointerNullEvent = false; + bRetrySucceeded = true; + WriteDebugEvent(SString("Lock VertexBuffer: retry with DISCARD succeeded (Flags:%08x)", retryFlags)); + } + else + { + // Ensure we unlock on success with null pointer to avoid leaving the resource locked + if (SUCCEEDED(hr)) + { + m_pOriginal->Unlock(); + bUnlockedAfterNull = true; + } + } + } + + if (bPointerNullEvent) + { + if (!bUnlockedAfterNull && SUCCEEDED(hr)) + { + m_pOriginal->Unlock(); + bUnlockedAfterNull = true; + } + // Fall back to artificial buffer + UINT clampedOffset = std::min(OffsetToLock, m_iMemUsed); + UINT clampedSize = SizeToLock; + if (clampedOffset + clampedSize > m_iMemUsed) + clampedSize = m_iMemUsed - clampedOffset; + if (clampedSize == 0 && clampedOffset < m_iMemUsed) + clampedSize = m_iMemUsed - clampedOffset; + + // Ensure we have some storage to hand back (even zero-sized locks receive a valid pointer) + size_t requiredStorage = std::max(static_cast(clampedSize), static_cast(1)); + if (m_fallbackStorage.size() < requiredStorage) + m_fallbackStorage.resize(requiredStorage); + + if (clampedSize > 0 && (Flags & D3DLOCK_READONLY)) + memset(m_fallbackStorage.data(), 0, clampedSize); + + *ppbData = m_fallbackStorage.data(); + + m_bFallbackActive = true; + m_fallbackOffset = clampedOffset; + m_fallbackSize = clampedSize; + m_fallbackFlags = Flags; + + bFallbackUsed = true; + bPointerNullEvent = true; + + hr = D3D_OK; + + WriteDebugEvent( + SString("Lock VertexBuffer: engaged fallback buffer (Offset:%x Size:%x Flags:%08x)", m_fallbackOffset, m_fallbackSize, m_fallbackFlags)); + } + } + + // Lock returned a failure HRESULT (device lost, out of vmem, etc.) and ppbData is still null. + // RenderWare discards the HRESULT and will write to the null pointer, so provide a fallback + // buffer to absorb the writes and prevent a crash. + // See also CrashFix_VBInstV3dNull and CrashFix_VBInstV3dMorphNull in CrashFixHacks + if (FAILED(hr) && *ppbData == nullptr) + { + WriteDebugEvent(SString("Lock VertexBuffer: HRESULT failed (%08x), providing fallback to prevent null write (Usage:%08x Flags:%08x Offset:%x Size:%x)", + hr, m_dwUsage, Flags, OffsetToLock, SizeToLock)); + + UINT fallbackOffset = std::min(OffsetToLock, m_iMemUsed); + UINT fallbackSize = SizeToLock; + if (fallbackOffset + fallbackSize > m_iMemUsed) + fallbackSize = m_iMemUsed - fallbackOffset; + if (fallbackSize == 0 && fallbackOffset < m_iMemUsed) + fallbackSize = m_iMemUsed - fallbackOffset; + + size_t requiredStorage = std::max(static_cast(fallbackSize), static_cast(1)); + if (m_fallbackStorage.size() < requiredStorage) + m_fallbackStorage.resize(requiredStorage); + + memset(m_fallbackStorage.data(), 0, requiredStorage); + + *ppbData = m_fallbackStorage.data(); + m_bFallbackActive = true; + m_fallbackOffset = fallbackOffset; + m_fallbackSize = fallbackSize; + m_fallbackFlags = Flags; + bFallbackUsed = true; + + // Override the failed hr so we report the fallback, and the caller + // (which may actually check hr unlike RW) doesn't propagate failure + originalHr = hr; + hr = D3D_OK; + } // Report problems - if (FAILED(hr) || *ppbData == NULL) + if (FAILED(hr) || bPointerNullEvent) { struct { @@ -126,17 +278,22 @@ HRESULT CProxyDirect3DVertexBuffer::Lock(UINT OffsetToLock, UINT SizeToLock, voi uint uiReportId; uint uiLogEventId; } info; - if (hr == D3D_OK) + HRESULT reportHr = FAILED(hr) ? hr : D3DERR_INVALIDCALL; + if (bPointerNullEvent && originalHr == D3D_OK) info = {"result NULL", 8621, 621}; - else if (hr == STATUS_ARRAY_BOUNDS_EXCEEDED) + else if (reportHr == STATUS_ARRAY_BOUNDS_EXCEEDED) info = {"offset out of range", 8622, 622}; - else if (hr == STATUS_ACCESS_VIOLATION) + else if (reportHr == STATUS_ACCESS_VIOLATION) info = {"access violation", 8623, 623}; else info = {"fail", 8620, 620}; - SString strMessage("Lock VertexBuffer [%s] hr:%x Length:%x Usage:%x FVF:%x Pool:%x OffsetToLock:%x SizeToLock:%x Flags:%x", info.szText, hr, m_iMemUsed, - m_dwUsage, m_dwFVF, m_pool, OffsetToLock, SizeToLock, Flags); + SString strMessage( + "Lock VertexBuffer [%s] hr:%x origHr:%x returnHr:%x pointerNull:%u retryAttempted:%u retrySucceeded:%u fallback:%u fallbackSize:%x fallbackFlags:%x" + " unlockedAfterNull:%u Length:%x Usage:%x FVF:%x Pool:%x OffsetToLock:%x SizeToLock:%x Flags:%x retryFlags:%x", + info.szText, reportHr, originalHr, hr, static_cast(bPointerNullEvent), static_cast(bRetryAttempted), static_cast(bRetrySucceeded), + static_cast(bFallbackUsed), m_fallbackSize, m_fallbackFlags, static_cast(bUnlockedAfterNull), m_iMemUsed, m_dwUsage, m_dwFVF, m_pool, + OffsetToLock, SizeToLock, Flags, retryFlags); WriteDebugEvent(strMessage); AddReportLog(info.uiReportId, strMessage); CCore::GetSingleton().LogEvent(info.uiLogEventId, "Lock VertexBuffer", "", strMessage); @@ -144,6 +301,93 @@ HRESULT CProxyDirect3DVertexBuffer::Lock(UINT OffsetToLock, UINT SizeToLock, voi return hr; } +///////////////////////////////////////////////////////////// +// +// CProxyDirect3DVertexBuffer::Unlock +// +// Apply fallback data if we had to hand out an artificial buffer +// +///////////////////////////////////////////////////////////// +HRESULT CProxyDirect3DVertexBuffer::Unlock() +{ + SharedUtil::CAutoCSLock fallbackGuard(m_fallbackCS); + + if (!m_bFallbackActive) + return m_pOriginal->Unlock(); + + HRESULT copyResult = D3D_OK; + bool bShouldRetryLater = false; + + if ((m_fallbackFlags & D3DLOCK_READONLY) == 0 && m_fallbackSize > 0) + { + UINT offset = std::min(m_fallbackOffset, m_iMemUsed); + UINT size = m_fallbackSize; + if (offset + size > m_iMemUsed) + size = (offset < m_iMemUsed) ? (m_iMemUsed - offset) : 0; + + if (size > 0) + { + DWORD writeFlags = m_fallbackFlags; + writeFlags &= ~(DWORD)(D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY); + if (m_dwUsage & D3DUSAGE_DYNAMIC) + writeFlags |= D3DLOCK_DISCARD; + + void* pReal = nullptr; + HRESULT lockHr = DoLock(offset, size, &pReal, writeFlags); + + if (SUCCEEDED(lockHr) && pReal != nullptr) + { + if (size > 0 && size <= m_fallbackStorage.size()) + { + memcpy(pReal, m_fallbackStorage.data(), size); + } + else + { + WriteDebugEvent(SString("Unlock VertexBuffer: fallback copy size mismatch (size:%x storage:%x)", size, m_fallbackStorage.size())); + copyResult = D3DERR_INVALIDCALL; + } + + HRESULT unlockHr = m_pOriginal->Unlock(); + if (FAILED(unlockHr)) + copyResult = unlockHr; + } + else + { + if (SUCCEEDED(lockHr)) + m_pOriginal->Unlock(); + + WriteDebugEvent( + SString("Unlock VertexBuffer: failed to copy fallback data (lockHr:%x offset:%x size:%x flags:%08x)", lockHr, offset, size, writeFlags)); + copyResult = FAILED(lockHr) ? lockHr : D3DERR_INVALIDCALL; + bShouldRetryLater = true; + } + } + else + { + bShouldRetryLater = true; + } + } + else if (m_fallbackSize == 0) + { + // No bytes were mapped, nothing to copy back - allow fallback to clear + } + + WriteDebugEvent(SString("Unlock VertexBuffer: fallback completed (offset:%x size:%x flags:%08x retryLater:%u result:%x)", m_fallbackOffset, m_fallbackSize, + m_fallbackFlags, static_cast(bShouldRetryLater), copyResult)); + + m_bFallbackActive = bShouldRetryLater ? m_bFallbackActive : false; + if (!m_bFallbackActive) + { + m_fallbackOffset = 0; + m_fallbackSize = 0; + m_fallbackFlags = 0; + m_fallbackStorage.clear(); + m_fallbackStorage.shrink_to_fit(); + } + + return copyResult; +} + ///////////////////////////////////////////////////////////// // // CProxyDirect3DVertexBuffer::DoLock diff --git a/Client/core/DXHook/CProxyDirect3DVertexBuffer.h b/Client/core/DXHook/CProxyDirect3DVertexBuffer.h index 5ca4ee6eb8a..e7e118e9b73 100644 --- a/Client/core/DXHook/CProxyDirect3DVertexBuffer.h +++ b/Client/core/DXHook/CProxyDirect3DVertexBuffer.h @@ -2,13 +2,21 @@ * * PROJECT: Multi Theft Auto v1.0 * LICENSE: See LICENSE in the top level directory - * FILE: - * PURPOSE: + * FILE: core/CProxyDirect3DVertexBuffer.h + * PURPOSE: Direct3D 9 vertex buffer function hooking proxy * * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ +#pragma once + +#include +#include +#include +#include "SharedUtil.Misc.h" +#include "CProxyDirect3DDevice9.h" // Include full definition for SResourceMemory + DEFINE_GUID(CProxyDirect3DVertexBuffer_GUID, 0x128A025E, 0x0100, 0x04F1, 0x40, 0x60, 0x53, 0x19, 0x44, 0x56, 0x59, 0x42); class CProxyDirect3DVertexBuffer : public IDirect3DVertexBuffer9 @@ -16,8 +24,8 @@ class CProxyDirect3DVertexBuffer : public IDirect3DVertexBuffer9 public: /*** IUnknown methods ***/ HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef() { return m_pOriginal->AddRef(); } - ULONG __stdcall Release(); + ULONG __stdcall AddRef() { return m_pOriginal->AddRef(); } + ULONG __stdcall Release(); /*** IDirect3DResource9 methods ***/ HRESULT __stdcall GetDevice(IDirect3DDevice9** ppDevice) { return m_pOriginal->GetDevice(ppDevice); } @@ -27,14 +35,14 @@ class CProxyDirect3DVertexBuffer : public IDirect3DVertexBuffer9 } HRESULT __stdcall GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData) { return m_pOriginal->GetPrivateData(refguid, pData, pSizeOfData); } HRESULT __stdcall FreePrivateData(REFGUID refguid) { return m_pOriginal->FreePrivateData(refguid); } - DWORD __stdcall SetPriority(DWORD PriorityNew) { return m_pOriginal->SetPriority(PriorityNew); } - DWORD __stdcall GetPriority() { return m_pOriginal->GetPriority(); } - void __stdcall PreLoad() { return m_pOriginal->PreLoad(); } + DWORD __stdcall SetPriority(DWORD PriorityNew) { return m_pOriginal->SetPriority(PriorityNew); } + DWORD __stdcall GetPriority() { return m_pOriginal->GetPriority(); } + void __stdcall PreLoad() { m_pOriginal->PreLoad(); } D3DRESOURCETYPE __stdcall GetType() { return m_pOriginal->GetType(); } /*** IDirect3DVertexBuffer9 methods ***/ - HRESULT __stdcall Lock(UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags); - HRESULT __stdcall Unlock() { return m_pOriginal->Unlock(); } + HRESULT __stdcall Lock(UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags) override; + HRESULT __stdcall Unlock() override; HRESULT __stdcall GetDesc(D3DVERTEXBUFFER_DESC* pDesc) { return m_pOriginal->GetDesc(pDesc); } // CProxyDirect3DVertexBuffer @@ -50,5 +58,12 @@ class CProxyDirect3DVertexBuffer : public IDirect3DVertexBuffer9 DWORD m_dwUsage; DWORD m_dwFVF; D3DPOOL m_pool; - CProxyDirect3DDevice9::SResourceMemory& m_stats; + CProxyDirect3DDevice9::SResourceMemory* m_pStats; + + bool m_bFallbackActive; + UINT m_fallbackOffset; + UINT m_fallbackSize; + DWORD m_fallbackFlags; + std::vector m_fallbackStorage; + SharedUtil::CCriticalSection m_fallbackCS; }; diff --git a/Client/core/DXHook/CProxyDirect3DVertexDeclaration.cpp b/Client/core/DXHook/CProxyDirect3DVertexDeclaration.cpp index 7b555aad621..edc719f7807 100644 --- a/Client/core/DXHook/CProxyDirect3DVertexDeclaration.cpp +++ b/Client/core/DXHook/CProxyDirect3DVertexDeclaration.cpp @@ -24,7 +24,7 @@ CProxyDirect3DVertexDeclaration::CProxyDirect3DVertexDeclaration(IDirect3DDevice { m_pOriginal = pOriginal; - CProxyDirect3DDevice9::SD3DVertexDeclState info; + CProxyDirect3DDevice9::SD3DVertexDeclState info{}; // Calc and cache info for (uint i = 0; i < MAXD3DDECLLENGTH; i++) @@ -70,7 +70,15 @@ CProxyDirect3DVertexDeclaration::CProxyDirect3DVertexDeclaration(IDirect3DDevice } // Add to cached info map - MapSet(g_pProxyDevice->m_VertexDeclMap, this, info); + CScopedActiveProxyDevice proxyDevice; + if (proxyDevice) + { + MapSet(proxyDevice->m_VertexDeclMap, this, info); + } + else + { + WriteDebugEvent("Warning: Unable to cache vertex declaration info because proxy device is unavailable"); + } } ///////////////////////////////////////////////////////////// @@ -83,7 +91,11 @@ CProxyDirect3DVertexDeclaration::CProxyDirect3DVertexDeclaration(IDirect3DDevice CProxyDirect3DVertexDeclaration::~CProxyDirect3DVertexDeclaration() { // Remove from cached info map - MapRemove(g_pProxyDevice->m_VertexDeclMap, this); + CScopedActiveProxyDevice proxyDevice; + if (proxyDevice) + { + MapRemove(proxyDevice->m_VertexDeclMap, this); + } } ///////////////////////////////////////////////////////////// @@ -101,6 +113,7 @@ HRESULT CProxyDirect3DVertexDeclaration::QueryInterface(REFIID riid, void** ppvO if (riid == CProxyDirect3DVertexDeclaration_GUID) { *ppvObj = this; + AddRef(); return S_OK; } @@ -122,7 +135,7 @@ ULONG CProxyDirect3DVertexDeclaration::Release() if (count == 0) { // now, the Original Object has deleted itself, so do we here - delete this; // destructor will be called automatically + delete this; // destructor will be called automatically } return count; diff --git a/Client/core/DXHook/CProxyDirect3DVertexDeclaration.h b/Client/core/DXHook/CProxyDirect3DVertexDeclaration.h index 70c3c2830b1..6ba2613ba84 100644 --- a/Client/core/DXHook/CProxyDirect3DVertexDeclaration.h +++ b/Client/core/DXHook/CProxyDirect3DVertexDeclaration.h @@ -16,8 +16,8 @@ class CProxyDirect3DVertexDeclaration : public IDirect3DVertexDeclaration9 public: /*** IUnknown methods ***/ HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj); - ULONG __stdcall AddRef() { return m_pOriginal->AddRef(); } - ULONG __stdcall Release(); + ULONG __stdcall AddRef() { return m_pOriginal->AddRef(); } + ULONG __stdcall Release(); /*** IDirect3DVertexDeclaration9 methods ***/ HRESULT __stdcall GetDevice(IDirect3DDevice9** ppDevice) { return m_pOriginal->GetDevice(ppDevice); } diff --git a/Client/core/DXHook/CProxyDirectInput8.cpp b/Client/core/DXHook/CProxyDirectInput8.cpp index 32b2eee9da7..cd4309c55b5 100644 --- a/Client/core/DXHook/CProxyDirectInput8.cpp +++ b/Client/core/DXHook/CProxyDirectInput8.cpp @@ -98,4 +98,4 @@ HRESULT CProxyDirectInput8::EnumDevicesBySemantics(LPCSTR a, LPDIACTIONFORMATA b HRESULT CProxyDirectInput8::ConfigureDevices(LPDICONFIGUREDEVICESCALLBACK a, LPDICONFIGUREDEVICESPARAMSA b, DWORD c, LPVOID d) { return m_pDevice->ConfigureDevices(a, b, c, d); -} \ No newline at end of file +} diff --git a/Client/core/DXHook/CProxyDirectInput8.h b/Client/core/DXHook/CProxyDirectInput8.h index ea1fe3b0c78..a5323f9abdc 100644 --- a/Client/core/DXHook/CProxyDirectInput8.h +++ b/Client/core/DXHook/CProxyDirectInput8.h @@ -23,8 +23,8 @@ class CProxyDirectInput8 : public IDirectInput8A ~CProxyDirectInput8(); /*** IUnknown methods ***/ virtual HRESULT __stdcall QueryInterface(REFIID riid, LPVOID* ppvObj); - virtual ULONG __stdcall AddRef(); - virtual ULONG __stdcall Release(); + virtual ULONG __stdcall AddRef(); + virtual ULONG __stdcall Release(); /*** IDirectInput8A methods ***/ virtual HRESULT __stdcall CreateDevice(REFGUID, LPDIRECTINPUTDEVICE8A*, LPUNKNOWN); diff --git a/Client/core/DXHook/CProxyDirectInputDevice8.h b/Client/core/DXHook/CProxyDirectInputDevice8.h index fd08f476165..a9795cad402 100644 --- a/Client/core/DXHook/CProxyDirectInputDevice8.h +++ b/Client/core/DXHook/CProxyDirectInputDevice8.h @@ -21,8 +21,8 @@ class CProxyDirectInputDevice8 : public IDirectInputDevice8A ~CProxyDirectInputDevice8(); /*** IUnknown methods ***/ virtual HRESULT __stdcall QueryInterface(REFIID riid, LPVOID* ppvObj); - virtual ULONG __stdcall AddRef(); - virtual ULONG __stdcall Release(); + virtual ULONG __stdcall AddRef(); + virtual ULONG __stdcall Release(); /*** IDirectInputDevice8A methods ***/ virtual HRESULT __stdcall GetCapabilities(LPDIDEVCAPS a); diff --git a/Client/core/DXHook/ComPtrValidation.h b/Client/core/DXHook/ComPtrValidation.h new file mode 100644 index 00000000000..a7f37d51af1 --- /dev/null +++ b/Client/core/DXHook/ComPtrValidation.h @@ -0,0 +1,172 @@ +#pragma once + +#include "StdInc.h" + +#include +#include +#include +#include +#include +#include + +namespace ComPtrValidation +{ + constexpr uint64_t kValidationThrottleMs = 200; + constexpr size_t kValidationCacheReserve = 256; + + inline uint64_t GetMonotonicMilliseconds() + { + using namespace std::chrono; + return static_cast(duration_cast(steady_clock::now().time_since_epoch()).count()); + } + + struct CacheEntry + { + uint64_t lastCheckMs{0}; + bool valid{false}; + }; + + struct CacheStorage + { + CacheStorage() + { + cache.reserve(kValidationCacheReserve); + cache.max_load_factor(0.5f); + } + + std::unordered_map cache; + }; + + inline std::atomic& InvalidationEpoch() + { + static std::atomic s_epoch{0}; + return s_epoch; + } + + inline std::shared_mutex& CacheMutex() + { + static std::shared_mutex s_mutex; + return s_mutex; + } + + inline std::unordered_map& Cache() + { + static CacheStorage s_storage; + return s_storage.cache; + } + + inline void Invalidate(const void* pointer) + { + if (!pointer) + return; + + { + std::unique_lock lock(CacheMutex()); + Cache().erase(pointer); + } + InvalidationEpoch().fetch_add(1, std::memory_order_acq_rel); + } + + enum class ValidationMode + { + Default, + ForceRefresh, + }; + + template + bool ValidateSlow(T* pointer) + { + if (!SharedUtil::IsReadablePointer(pointer, sizeof(void*))) + return false; + + void* const* vtablePtr = reinterpret_cast(pointer); + if (!vtablePtr) + return false; + + void* const vtable = *vtablePtr; + if (!vtable) + return false; + + constexpr size_t requiredBytes = sizeof(void*) * 3; + return SharedUtil::IsReadablePointer(vtable, requiredBytes); + } + + struct ThreadCache + { + const void* pointer{nullptr}; + CacheEntry entry{}; + uint64_t epoch{std::numeric_limits::max()}; + }; + + template + bool Validate(T* pointer, ValidationMode mode = ValidationMode::Default) + { + if (!pointer) + return true; + + thread_local ThreadCache s_threadCache; + + for (;;) + { + const uint64_t epoch = InvalidationEpoch().load(std::memory_order_acquire); + const uint64_t now = GetMonotonicMilliseconds(); + + if (mode == ValidationMode::Default && s_threadCache.pointer == pointer && s_threadCache.epoch == epoch) + { + const uint64_t last = s_threadCache.entry.lastCheckMs; + const uint64_t elapsed = (now >= last) ? now - last : 0; + if (elapsed < kValidationThrottleMs) + { + if (InvalidationEpoch().load(std::memory_order_acquire) == epoch) + return s_threadCache.entry.valid; + continue; + } + } + + if (mode == ValidationMode::Default) + { + std::shared_lock lock(CacheMutex()); + auto& cache = Cache(); + const auto iter = cache.find(pointer); + if (iter != cache.end()) + { + const uint64_t last = iter->second.lastCheckMs; + const uint64_t elapsed = (now >= last) ? now - last : 0; + if (elapsed < kValidationThrottleMs) + { + if (InvalidationEpoch().load(std::memory_order_acquire) == epoch) + { + s_threadCache.pointer = pointer; + s_threadCache.entry = iter->second; + s_threadCache.epoch = epoch; + return iter->second.valid; + } + continue; + } + } + } + + const bool valid = ValidateSlow(pointer); + const CacheEntry newEntry{now, valid}; + { + std::unique_lock lock(CacheMutex()); + Cache()[pointer] = newEntry; + } + + if (InvalidationEpoch().load(std::memory_order_acquire) != epoch) + continue; + + s_threadCache.pointer = pointer; + s_threadCache.entry = newEntry; + s_threadCache.epoch = epoch; + return valid; + } + } + +} + +template +bool IsValidComInterfacePointer(T* pointer, ComPtrValidation::ValidationMode mode = ComPtrValidation::ValidationMode::Default) +{ + return ComPtrValidation::Validate(pointer, mode); +} diff --git a/Client/core/FPSLimiter.cpp b/Client/core/FPSLimiter.cpp new file mode 100644 index 00000000000..d368ef3a329 --- /dev/null +++ b/Client/core/FPSLimiter.cpp @@ -0,0 +1,367 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: core/FPSLimiter.cpp + * PURPOSE: Provides methods to manage and enforce frame rates. + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include "FPSLimiter.h" +#include "CGraphStats.h" +#include + +namespace FPSLimiter +{ + constexpr std::uint16_t DEFAULT_FPS_VSYNC = 60; // Default user-defined FPS limit + + FPSLimiter::FPSLimiter() + + : m_frequency{0}, + m_lastFrameTime{0}, + m_lastFrameTSC{__rdtsc()}, + m_hTimer(nullptr), + m_serverEnforcedFps{0}, + m_clientEnforcedFps{0}, + m_userDefinedFps{0}, + m_displayRefreshRate{0}, + m_fpsTarget{FPSLimits::FPS_MIN}, + m_appliedThisFrame{false} + { + QueryPerformanceFrequency(&m_frequency); + QueryPerformanceCounter(&m_lastFrameTime); + Reset(); + } + + FPSLimiter::~FPSLimiter() + { + if (m_hTimer) + { + CloseHandle(m_hTimer); + m_hTimer = nullptr; + } + } + +#pragma region API + + void FPSLimiter::Reset() + { + OutputDebugLine("FPSLimiter::Reset"); + + m_serverEnforcedFps = 0; + m_clientEnforcedFps = 0; + m_userDefinedFps = 0; + + bool vSync; + CVARS_GET("vsync", vSync); + SetDisplayVSync(vSync); + + CalculateCurrentFPSLimit(); + } + + EnforcerType FPSLimiter::GetEnforcer() const noexcept + { + if (m_fpsTarget == FPSLimits::FPS_UNLIMITED) + return EnforcerType::None; + + std::uint16_t minFps = FPSLimits::FPS_MAX; + EnforcerType bestEnforcer = EnforcerType::None; + + // Check each enforcer and find the one with lowest valid FPS + auto checkEnforcer = [&](std::uint16_t fps, EnforcerType type) + { + if (fps >= FPSLimits::FPS_MIN && fps < minFps) + { + minFps = fps; + bestEnforcer = type; + } + }; + + checkEnforcer(m_serverEnforcedFps, EnforcerType::Server); + checkEnforcer(m_clientEnforcedFps, EnforcerType::Client); + checkEnforcer(m_userDefinedFps, EnforcerType::UserDefined); + checkEnforcer(m_displayRefreshRate, EnforcerType::VSync); + + return (minFps == m_fpsTarget) ? bestEnforcer : EnforcerType::None; + } + + void FPSLimiter::SetServerEnforcedFPS(std::uint16_t fps) + { + FPSLimits::IsValidAndSetValid(fps, m_serverEnforcedFps); + CalculateCurrentFPSLimit(); + } + + void FPSLimiter::SetClientEnforcedFPS(std::uint16_t fps) + { + FPSLimits::IsValidAndSetValid(fps, m_clientEnforcedFps); + CalculateCurrentFPSLimit(); + } + + void FPSLimiter::SetUserDefinedFPS(std::uint16_t fps) + { + FPSLimits::IsValidAndSetValid(fps, m_userDefinedFps); + CVARS_SET("fps_limit", m_userDefinedFps); + CalculateCurrentFPSLimit(); + } + + void FPSLimiter::SetDisplayVSync(bool enabled) + { + m_displayRefreshRate = enabled ? GetDisplayRefreshRate() : 0; + CVARS_SET("vsync", enabled); + CalculateCurrentFPSLimit(); + } + +#pragma endregion API + +#pragma region Internal + + std::uint16_t FPSLimiter::GetDisplayRefreshRate() + { + D3DDISPLAYMODE DisplayMode; + IDirect3D9* pD3D9 = CProxyDirect3D9::StaticGetDirect3D(); + if (pD3D9 && pD3D9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &DisplayMode) == D3D_OK) + { + std::uint16_t validFps; + if (FPSLimits::IsValidAndSetValid(static_cast(DisplayMode.RefreshRate), validFps)) + { + return validFps; + } + } + return DEFAULT_FPS_VSYNC; // Shouldn't happen, sane default + } + + void FPSLimiter::CalculateCurrentFPSLimit() + { + std::uint16_t previousTarget = m_fpsTarget; + + // Lambda to check and update minimum FPS + auto checkEnforcer = [](std::uint16_t fpsTarget, std::uint16_t& minFPS) + { + if (fpsTarget >= FPSLimits::FPS_MIN && fpsTarget < minFPS) + { + minFPS = fpsTarget; + } + }; + + // Find the minimum FPS among all enforced limits + std::uint16_t minFPS = FPSLimits::FPS_MAX; + checkEnforcer(m_serverEnforcedFps, minFPS); + checkEnforcer(m_clientEnforcedFps, minFPS); + checkEnforcer(m_userDefinedFps, minFPS); + checkEnforcer(m_displayRefreshRate, minFPS); + + if (minFPS == FPSLimits::FPS_MAX) + minFPS = FPSLimits::FPS_UNLIMITED; + + m_fpsTarget = minFPS; + + // If limit changed, reset frame timing + if (previousTarget != m_fpsTarget) + { + QueryPerformanceCounter(&m_lastFrameTime); + m_appliedThisFrame = false; + OnFPSLimitChange(); + } + + std::stringstream ss; + ss << "FPSLimiter: FPS limit changed to " << (m_fpsTarget == 0 ? "unlimited" : std::to_string(m_fpsTarget)); + ss << " (Enforced by: " << EnumToString(GetEnforcer()) << ")"; +#ifdef MTA_DEBUG + ss << " [Server: " << (m_serverEnforcedFps == 0 ? "unlimited" : std::to_string(m_serverEnforcedFps)); + ss << ", Client: " << (m_clientEnforcedFps == 0 ? "unlimited" : std::to_string(m_clientEnforcedFps)); + ss << ", User: " << (m_userDefinedFps == 0 ? "unlimited" : std::to_string(m_userDefinedFps)); + ss << ", VSync: " << (m_displayRefreshRate == 0 ? "unlimited" : std::to_string(m_displayRefreshRate)) << "]"; +#endif + auto* pConsole = CCore::GetSingleton().GetConsole(); + if (pConsole) + CCore::GetSingleton().GetConsole()->Print(ss.str().c_str()); + OutputDebugLine(ss.str().c_str()); + } + + void FPSLimiter::SetFrameRateThrottle() + { + TIMING_GRAPH("LimiterStart"); + auto defer = [&]() { TIMING_GRAPH("LimiterEnd"); }; + + if (m_fpsTarget == FPSLimits::FPS_UNLIMITED) + { + return defer(); + } + else if (m_appliedThisFrame) + { + OutputDebugLine("Warning: FPSLimiter::SetFrameRateThrottle called when already applied this frame"); + return defer(); + } + + m_appliedThisFrame = true; + + std::uint64_t currentTSC = __rdtsc(); + + // Initialize TSC frequency on first use + static double tscFrequency = 0.0; + if (tscFrequency == 0.0) + { + LARGE_INTEGER start, end; + std::uint64_t tscStart = __rdtsc(); + QueryPerformanceCounter(&start); + Sleep(10); // Short calibration period + QueryPerformanceCounter(&end); + std::uint64_t tscEnd = __rdtsc(); + + double qpcTicks = static_cast(end.QuadPart - start.QuadPart); + double tscTicks = static_cast(tscEnd - tscStart); + tscFrequency = (tscTicks / qpcTicks) * m_frequency.QuadPart; + } + + // Calculate target frame time in TSC ticks + const double targetFrameTime = tscFrequency / m_fpsTarget; + + // Calculate elapsed time since last frame + double elapsedTicks = static_cast(currentTSC - m_lastFrameTSC); + double elapsedMs = (elapsedTicks * 1000.0) / tscFrequency; + double targetFrameTimeMs = (targetFrameTime * 1000.0) / tscFrequency; + + // RDTSC spin wait - reusable for all spin scenarios + auto rdtscSpinWait = [&](std::uint64_t targetTSC) -> std::uint64_t + { + std::uint64_t lastMeasuredTSC = __rdtsc(); + std::uint64_t remaining = targetTSC - lastMeasuredTSC; + if (remaining > 10000) // > ~3us at 3GHz + { + // Long wait: check every ~1000 cycles + do + { + for (int i = 0; i < 250; ++i) + _mm_pause(); + lastMeasuredTSC = __rdtsc(); + } while (lastMeasuredTSC + 5000 < targetTSC); // Stop 5000 cycles early + } + + // Final precision loop + do + { + _mm_pause(); + lastMeasuredTSC = __rdtsc(); + } while (lastMeasuredTSC < targetTSC); + + return lastMeasuredTSC; + }; + + // Set timer resolution once per session + auto ensureTimerResolution = []() + { + static bool resolutionSet = false; + if (!resolutionSet) + { + using NtSetTimerResolution = LONG(NTAPI*)(ULONG, BOOLEAN, PULONG); + HMODULE ntdll = GetModuleHandleA("ntdll.dll"); + if (ntdll) + { + NtSetTimerResolution setRes = nullptr; + if (SharedUtil::TryGetProcAddress(ntdll, "NtSetTimerResolution", setRes)) + { + ULONG actualRes; + setRes(10000, TRUE, &actualRes); // 1ms in 100ns units + resolutionSet = true; + } + } + } + }; + + std::uint64_t frameEndTSC = currentTSC; + + // If we need to wait + if (elapsedTicks < targetFrameTime) + { + double waitTicks = targetFrameTime - elapsedTicks; + double waitTimeMs = (waitTicks * 1000.0) / tscFrequency; + + // Target TSC is ideal frame end time (no drift accumulation) + std::uint64_t targetTSC = m_lastFrameTSC + static_cast(targetFrameTime); + + if (waitTimeMs > 2.0) + { + ensureTimerResolution(); + + // Create timer on first use + if (!m_hTimer) + { + m_hTimer = CreateWaitableTimer(nullptr, TRUE, nullptr); + } + + if (m_hTimer) + { + double timerWaitMs = waitTimeMs - 1.0; // Leave margin for spin + if (timerWaitMs > 0.5) + { + LARGE_INTEGER dueTime; + dueTime.QuadPart = -1LL * static_cast(timerWaitMs * 10000.0); + + if (SetWaitableTimer(m_hTimer, &dueTime, 0, nullptr, nullptr, FALSE)) + { + WaitForSingleObject(m_hTimer, INFINITE); + frameEndTSC = rdtscSpinWait(targetTSC); + } + else + { + frameEndTSC = rdtscSpinWait(targetTSC); + } + } + else + { + frameEndTSC = rdtscSpinWait(targetTSC); + } + } + } + else if (waitTimeMs > 0.05) + { + frameEndTSC = rdtscSpinWait(targetTSC); + } + } + + // Adjust last frame TSC to maintain consistent frame pacing + if (elapsedTicks >= targetFrameTime) + m_lastFrameTSC = frameEndTSC; + else + m_lastFrameTSC += static_cast(targetFrameTime); + + return defer(); + } + +#pragma endregion Internal + +#pragma region Events + + void FPSLimiter::OnFrameStart() + { + // Reset the applied flag for the new frame + m_appliedThisFrame = false; + } + + void FPSLimiter::OnFrameEnd() + { + // Trigger fps limiting now + SetFrameRateThrottle(); + } + + void FPSLimiter::OnFPSLimitChange() + { + CCore::GetSingleton().OnFPSLimitChange(m_fpsTarget); + } + +#pragma endregion Events + + // Enum reflection for EnforcerType + + IMPLEMENT_ENUM_BEGIN(EnforcerType) + ADD_ENUM(EnforcerType::None, "none") + ADD_ENUM(EnforcerType::VSync, "vsync") + ADD_ENUM(EnforcerType::UserDefined, "user-defined") + ADD_ENUM(EnforcerType::Client, "client") + ADD_ENUM(EnforcerType::Server, "server") + IMPLEMENT_ENUM_END("EnforcerType"); + +}; // namespace FPSLimiter diff --git a/Client/core/FPSLimiter.h b/Client/core/FPSLimiter.h new file mode 100644 index 00000000000..c385c7acf63 --- /dev/null +++ b/Client/core/FPSLimiter.h @@ -0,0 +1,67 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: core/FPSLimiter.h + * PURPOSE: Provides methods to manage and enforce frame rates. + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include + +namespace FPSLimiter +{ + class FPSLimiter : public FPSLimiterInterface + { + public: + FPSLimiter(); + ~FPSLimiter(); + + private: + // Disallow copy and move + FPSLimiter(const FPSLimiter&) = delete; + FPSLimiter& operator=(const FPSLimiter&) = delete; + FPSLimiter(FPSLimiter&&) = delete; + FPSLimiter& operator=(FPSLimiter&&) = delete; + + public: + // API + void Reset(); + + std::uint16_t GetFPSTarget() const noexcept override { return m_fpsTarget; } + EnforcerType GetEnforcer() const noexcept override; + + void SetServerEnforcedFPS(std::uint16_t fps) override; + void SetClientEnforcedFPS(std::uint16_t fps) override; + void SetUserDefinedFPS(std::uint16_t fps) override; + void SetDisplayVSync(bool enabled) override; + + void OnFPSLimitChange() override; // Event handler called when the active frame rate limit changes + void OnFrameStart() override; // Event handler called at the start of each frame + void OnFrameEnd() override; // Event handler called at the end of each frame + + private: + // Internal + std::uint16_t GetDisplayRefreshRate(); + + void CalculateCurrentFPSLimit(); + void SetFrameRateThrottle(); + + private: + // Member data + LARGE_INTEGER m_frequency; + LARGE_INTEGER m_lastFrameTime; + std::uint64_t m_lastFrameTSC; + HANDLE m_hTimer; + std::uint16_t m_serverEnforcedFps; // Maximum FPS enforced by the server + std::uint16_t m_clientEnforcedFps; // Maximum FPS enforced by the client + std::uint16_t m_userDefinedFps; // Maximum FPS defined by the user (see `fps_limit` cvar) + std::uint16_t m_displayRefreshRate; // Refresh rate of the display aka VSync (see `vsync` cvar) + std::uint16_t m_fpsTarget; // Currently target FPS limit (0 = no limit) + bool m_appliedThisFrame; // Whether the FPS limit was applied in the current frame + }; +} // namespace FPSLimiter diff --git a/Client/core/FastFailCrashHandler/WerCrashHandler.cpp b/Client/core/FastFailCrashHandler/WerCrashHandler.cpp new file mode 100644 index 00000000000..c3c42d3b8c0 --- /dev/null +++ b/Client/core/FastFailCrashHandler/WerCrashHandler.cpp @@ -0,0 +1,1128 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Client/core/FastFailCrashHandler/WerCrashHandler.cpp + * PURPOSE: WER crash handler implementation. + * Capable of dump, register, and stacktrace collection fo 0xC0000409 / 0xC0000374 crashes. + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +// Self-contained module - compiled by both Loader and Core projects +// Do not use precompiled headers here + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MTA_CLIENT +#include +#include + +#include "WerCrashHandler.h" + +namespace +{ + constexpr DWORD kWerInfoTagStart = 'WERs'; + constexpr DWORD kWerInfoTagEnd = 'WERe'; + constexpr DWORD kDefaultDllBase = 0x10000000; + constexpr DWORD kDefaultExeBase = 0x00400000; + + struct MinidumpModuleInfo + { + SString name; + DWORD64 baseAddress = 0; + DWORD32 size = 0; + }; + + struct FormattedStackFrame + { + SString text; + bool isDll = false; + DWORD idaOffset = 0; + }; + + [[nodiscard]] FormattedStackFrame FormatAddressWithModules(DWORD64 address, const std::vector& modules) + { + FormattedStackFrame result; + for (const auto& mod : modules) + { + if (mod.size <= (0xFFFFFFFFFFFFFFFF - mod.baseAddress) && address >= mod.baseAddress && address < mod.baseAddress + mod.size) + { + const DWORD64 offset = address - mod.baseAddress; + result.text = SString("%s+0x%llX", mod.name.c_str(), static_cast(offset)); + result.isDll = mod.name.length() > 4 && mod.name.EndsWithI(".dll"); + if (result.isDll && offset <= (0xFFFFFFFF - kDefaultDllBase)) + result.idaOffset = kDefaultDllBase + static_cast(offset); + return result; + } + } + result.text = SString("0x%08X", static_cast(address)); + return result; + } + + [[nodiscard]] WerCrash::FileTimeDuration FileTimeToDuration(const FILETIME& value) noexcept + { + const auto combined = (static_cast(value.dwHighDateTime) << 32) | value.dwLowDateTime; + return WerCrash::FileTimeDuration{static_cast(combined)}; + } + + [[nodiscard]] bool IsWriteTimeRecentEnough(const FILETIME& ftWrite, std::uint64_t maxAgeMinutes) noexcept + { + FILETIME ftNow{}; + GetSystemTimeAsFileTime(&ftNow); + + const ULARGE_INTEGER uliNow{ftNow.dwLowDateTime, ftNow.dwHighDateTime}; + const ULARGE_INTEGER uliWrite{ftWrite.dwLowDateTime, ftWrite.dwHighDateTime}; + + constexpr ULONGLONG kFileTimeUnitsPerSecond = 10000000ULL; + const ULONGLONG maxAge = maxAgeMinutes * 60 * kFileTimeUnitsPerSecond; + + return uliNow.QuadPart >= uliWrite.QuadPart && (uliNow.QuadPart - uliWrite.QuadPart) < maxAge; + } + + [[nodiscard]] bool IsValidRva(SIZE_T mappedSize, RVA rva, SIZE_T dataSize) noexcept + { + return rva != 0 && dataSize != 0 && rva < mappedSize && dataSize <= mappedSize - rva; + } +} + +namespace WerCrash +{ + bool IsFileRecentEnough(HANDLE hFile, std::uint64_t maxAgeMinutes) noexcept + { + FILETIME ftCreate{}, ftAccess{}, ftWrite{}; + if (!GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite)) + return false; + + return IsWriteTimeRecentEnough(ftWrite, maxAgeMinutes); + } + + MinidumpRegisters ExtractRegistersFromMinidump(const SString& dumpPath) + { + MinidumpRegisters regs{}; + + const HANDLE hFile = CreateFileA(dumpPath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + if (hFile == INVALID_HANDLE_VALUE) + return regs; + + LARGE_INTEGER fileSize{}; + if (!GetFileSizeEx(hFile, &fileSize) || fileSize.QuadPart < 1024) + { + CloseHandle(hFile); + return regs; + } + const auto mappedSize = static_cast(fileSize.QuadPart); + + const HANDLE hMapping = CreateFileMappingA(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr); + if (!hMapping) + { + CloseHandle(hFile); + return regs; + } + + const LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); + if (!pBase) + { + CloseHandle(hMapping); + CloseHandle(hFile); + return regs; + } + + PMINIDUMP_DIRECTORY pExceptionDir = nullptr; + PVOID pExceptionStream = nullptr; + ULONG streamSize = 0; + + if (MiniDumpReadDumpStream(pBase, ExceptionStream, &pExceptionDir, &pExceptionStream, &streamSize)) + { + auto* pExInfo = static_cast(pExceptionStream); + if (pExInfo && streamSize >= sizeof(MINIDUMP_EXCEPTION_STREAM)) + { + regs.exceptionCode = pExInfo->ExceptionRecord.ExceptionCode; + regs.exceptionAddress = pExInfo->ExceptionRecord.ExceptionAddress; + + PMINIDUMP_DIRECTORY pThreadListDir = nullptr; + PVOID pThreadListStream = nullptr; + ULONG threadListSize = 0; + + if (MiniDumpReadDumpStream(pBase, ThreadListStream, &pThreadListDir, &pThreadListStream, &threadListSize)) + { + auto* pThreadList = static_cast(pThreadListStream); + if (pThreadList && pThreadList->NumberOfThreads > 0) + { + for (ULONG i = 0; i < pThreadList->NumberOfThreads; i++) + { + const auto& thread = pThreadList->Threads[i]; + if (thread.ThreadId != pExInfo->ThreadId) + continue; + + const MINIDUMP_LOCATION_DESCRIPTOR ctxLoc = thread.ThreadContext; + if (ctxLoc.DataSize < sizeof(CONTEXT) || !IsValidRva(mappedSize, ctxLoc.Rva, ctxLoc.DataSize)) + break; + + auto* pCtx = reinterpret_cast(static_cast(pBase) + ctxLoc.Rva); + + regs.eax = pCtx->Eax; + regs.ebx = pCtx->Ebx; + regs.ecx = pCtx->Ecx; + regs.edx = pCtx->Edx; + regs.esi = pCtx->Esi; + regs.edi = pCtx->Edi; + regs.ebp = pCtx->Ebp; + regs.esp = pCtx->Esp; + regs.eip = pCtx->Eip; + regs.eflags = pCtx->EFlags; + regs.cs = static_cast(pCtx->SegCs); + regs.ds = static_cast(pCtx->SegDs); + regs.es = static_cast(pCtx->SegEs); + regs.fs = static_cast(pCtx->SegFs); + regs.gs = static_cast(pCtx->SegGs); + regs.ss = static_cast(pCtx->SegSs); + regs.valid = true; + break; + } + } + } + } + } + + UnmapViewOfFile(pBase); + CloseHandle(hMapping); + CloseHandle(hFile); + return regs; + } + + SString ExtractStackTraceFromMinidump(const SString& dumpPath, const MinidumpRegisters& regs) + { + if (!regs.valid || regs.esp == 0) + return ""; + + constexpr size_t kMaxFrames = 64; + constexpr size_t kMinFramesBeforeRawScan = 3; + constexpr size_t kRawStackScanBytes = 8192; + constexpr DWORD kMinCodeAddress = 0x00400000; + constexpr DWORD kMaxCodeAddress = 0x7FFFFFFF; + + const HANDLE hFile = CreateFileA(dumpPath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + if (hFile == INVALID_HANDLE_VALUE) + return ""; + + LARGE_INTEGER fileSize{}; + if (!GetFileSizeEx(hFile, &fileSize) || fileSize.QuadPart < 1024) + { + CloseHandle(hFile); + return ""; + } + const auto mappedSize = static_cast(fileSize.QuadPart); + + const HANDLE hMapping = CreateFileMappingA(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr); + if (!hMapping) + { + CloseHandle(hFile); + return ""; + } + + const LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); + if (!pBase) + { + CloseHandle(hMapping); + CloseHandle(hFile); + return ""; + } + + std::vector modules; + PMINIDUMP_DIRECTORY pModuleListDir = nullptr; + PVOID pModuleListStream = nullptr; + ULONG moduleListSize = 0; + + if (MiniDumpReadDumpStream(pBase, ModuleListStream, &pModuleListDir, &pModuleListStream, &moduleListSize)) + { + auto* pModuleList = static_cast(pModuleListStream); + if (pModuleList && pModuleList->NumberOfModules > 0) + { + modules.reserve(pModuleList->NumberOfModules); + for (ULONG i = 0; i < pModuleList->NumberOfModules; i++) + { + const auto& mod = pModuleList->Modules[i]; + MinidumpModuleInfo info; + info.baseAddress = mod.BaseOfImage; + info.size = mod.SizeOfImage; + + if (mod.ModuleNameRva != 0 && mod.ModuleNameRva <= mappedSize - sizeof(ULONG32)) + { + auto* pModName = reinterpret_cast(static_cast(pBase) + mod.ModuleNameRva); + + if (pModName->Length > 0 && pModName->Length < 1024) + { + const SIZE_T availableForString = mappedSize - mod.ModuleNameRva - sizeof(ULONG32); + if (pModName->Length <= availableForString) + { + std::wstring wname(pModName->Buffer, pModName->Length / sizeof(wchar_t)); + auto lastSlash = wname.find_last_of(L"\\/"); + if (lastSlash != std::wstring::npos) + wname = wname.substr(lastSlash + 1); + + info.name = UTF16ToMbUTF8(wname); + } + } + } + + if (!info.name.empty()) + modules.push_back(std::move(info)); + } + } + } + + std::map> memoryRegions; + PMINIDUMP_DIRECTORY pMemoryListDir = nullptr; + PVOID pMemoryListStream = nullptr; + ULONG memoryListSize = 0; + + if (MiniDumpReadDumpStream(pBase, MemoryListStream, &pMemoryListDir, &pMemoryListStream, &memoryListSize)) + { + auto* pMemoryList = static_cast(pMemoryListStream); + if (pMemoryList && pMemoryList->NumberOfMemoryRanges > 0) + { + for (ULONG i = 0; i < pMemoryList->NumberOfMemoryRanges; i++) + { + const auto& range = pMemoryList->MemoryRanges[i]; + if (IsValidRva(mappedSize, range.Memory.Rva, range.Memory.DataSize)) + { + auto* pData = static_cast(pBase) + range.Memory.Rva; + memoryRegions[range.StartOfMemoryRange] = std::vector(pData, pData + range.Memory.DataSize); + } + } + } + } + + const auto readDword = [&memoryRegions](DWORD64 address) noexcept -> std::optional + { + for (const auto& [baseAddr, data] : memoryRegions) + { + if (address >= baseAddr && address + sizeof(DWORD) <= baseAddr + data.size()) + { + const auto offset = static_cast(address - baseAddr); + DWORD value = 0; + std::memcpy(&value, data.data() + offset, sizeof(DWORD)); + return value; + } + } + return std::nullopt; + }; + + const auto isAddressInModule = [&modules](DWORD64 addr) noexcept -> bool + { + for (const auto& mod : modules) + { + if (mod.size <= (0xFFFFFFFFFFFFFFFF - mod.baseAddress) && addr >= mod.baseAddress && addr < mod.baseAddress + mod.size) + return true; + } + return false; + }; + + const auto isLikelyCodeAddress = [&](DWORD addr) noexcept -> bool + { + if (addr < kMinCodeAddress || addr > kMaxCodeAddress) + return false; + return isAddressInModule(addr); + }; + + std::vector frames; + frames.reserve(kMaxFrames); + + std::set seenAddresses; + frames.push_back(regs.eip); + seenAddresses.insert(regs.eip); + + DWORD currentEbp = regs.ebp; + std::set visitedFrames; + + for (size_t i = 0; i < kMaxFrames && currentEbp != 0; i++) + { + if (visitedFrames.count(currentEbp)) + break; + visitedFrames.insert(currentEbp); + + auto returnAddr = readDword(static_cast(currentEbp) + sizeof(DWORD)); + if (!returnAddr) + break; + + if (*returnAddr != 0 && *returnAddr <= kMaxCodeAddress && !seenAddresses.count(*returnAddr)) + { + frames.push_back(*returnAddr); + seenAddresses.insert(*returnAddr); + } + + auto nextEbp = readDword(currentEbp); + if (!nextEbp) + break; + + if (*nextEbp <= currentEbp) + break; + + currentEbp = *nextEbp; + } + + if (frames.size() < kMinFramesBeforeRawScan) + { + DWORD64 stackPtr = regs.esp; + size_t bytesScanned = 0; + + while (bytesScanned < kRawStackScanBytes && frames.size() < kMaxFrames) + { + auto stackValue = readDword(stackPtr); + if (!stackValue) + { + stackPtr += sizeof(DWORD); + bytesScanned += sizeof(DWORD); + + if (bytesScanned % 256 == 0) + { + bool foundNextRegion = false; + for (const auto& [baseAddr, data] : memoryRegions) + { + if (baseAddr > stackPtr && baseAddr < stackPtr + 4096) + { + stackPtr = baseAddr; + foundNextRegion = true; + break; + } + } + if (!foundNextRegion) + break; + } + continue; + } + + const DWORD potentialAddr = *stackValue; + if (isLikelyCodeAddress(potentialAddr) && !seenAddresses.count(potentialAddr)) + { + frames.push_back(potentialAddr); + seenAddresses.insert(potentialAddr); + } + + stackPtr += sizeof(DWORD); + bytesScanned += sizeof(DWORD); + } + } + + if (frames.size() <= 1) + { + UnmapViewOfFile(pBase); + CloseHandle(hMapping); + CloseHandle(hFile); + return ""; + } + + SString stackTrace; + for (size_t i = 0; i < frames.size(); i++) + { + const auto addr = frames[i]; + const auto formatted = FormatAddressWithModules(addr, modules); + if (formatted.isDll) + stackTrace += SString("#%02u %s [0x%08X] - IDA Address: 0x%08X\n", static_cast(i), formatted.text.c_str(), + static_cast(addr), formatted.idaOffset); + else + stackTrace += SString("#%02u %s [0x%08X]\n", static_cast(i), formatted.text.c_str(), static_cast(addr)); + } + + UnmapViewOfFile(pBase); + CloseHandle(hMapping); + CloseHandle(hFile); + return stackTrace; + } + + void AppendWerInfoToDump(const SString& dumpPath, const SString& moduleName, DWORD offset, DWORD exceptionCode, const MinidumpRegisters& regs) + { + if (dumpPath.empty()) + return; + + const char* exceptionName = (exceptionCode == 0xC0000409) ? "Stack Buffer Overrun" + : (exceptionCode == 0xC0000374) ? "Heap Corruption" + : "Security Exception"; + const DWORD idaAddress = (offset <= (0xFFFFFFFF - kDefaultDllBase)) ? (kDefaultDllBase + offset) : 0; + + SYSTEMTIME st{}; + GetLocalTime(&st); + + SString werInfo; + werInfo += "WER Crash Info (Fail-Fast Exception)\n"; + werInfo += "=====================================\n"; + werInfo += SString("Exception: 0x%08X (%s)\n", exceptionCode, exceptionName); + werInfo += SString("Module: %s\n", moduleName.empty() ? "unknown" : moduleName.c_str()); + werInfo += SString("Offset: 0x%08X\n", offset); + werInfo += SString("IDA Address: 0x%08X (default base 0x10000000)\n", idaAddress); + werInfo += "Resolved Module Base: 0x10000000\n"; + werInfo += SString("Detected: %04d-%02d-%02d %02d:%02d:%02d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + werInfo += "Source: Windows Error Reporting (WER)\n"; + + if (regs.valid) + { + werInfo += "\nRegisters:\n"; + werInfo += SString("EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESI=%08X EDI=%08X\n", regs.eax, regs.ebx, regs.ecx, regs.edx, regs.esi, regs.edi); + werInfo += SString("EBP=%08X ESP=%08X EIP=%08X FLG=%08X\n", regs.ebp, regs.esp, regs.eip, regs.eflags); + werInfo += SString("CS=%04X DS=%04X SS=%04X ES=%04X FS=%04X GS=%04X\n", regs.cs, regs.ds, regs.ss, regs.es, regs.fs, regs.gs); + } + + const DWORD zero = 0; + const DWORD dataSize = static_cast(werInfo.length() + 1); + + std::vector buffer; + buffer.reserve(sizeof(DWORD) * 6 + dataSize); + + const auto appendDword = [&buffer](DWORD value) + { + const auto* bytes = reinterpret_cast(&value); + buffer.insert(buffer.end(), bytes, bytes + sizeof(DWORD)); + }; + + appendDword(zero); + appendDword(kWerInfoTagStart); + appendDword(dataSize); + buffer.insert(buffer.end(), werInfo.c_str(), werInfo.c_str() + dataSize); + appendDword(dataSize); + appendDword(kWerInfoTagEnd); + appendDword(zero); + + FileAppend(dumpPath, buffer.data(), static_cast(buffer.size())); + } + + SString RenameWerDumpToMtaFormat(const SString& sourcePath, const SString& dumpDir, const SString& moduleName, DWORD offset, DWORD exceptionCode, + const MinidumpRegisters& regs) + { + SYSTEMTIME st{}; + GetLocalTime(&st); + + SString cleanedModuleName = moduleName; + cleanedModuleName = cleanedModuleName.ReplaceI(".dll", "").Replace(".exe", "").Replace("_", "").Replace(".", "").Replace("-", ""); + if (cleanedModuleName.empty()) + cleanedModuleName = "unknown"; + + const auto strMTAVersionFull = SString("%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting("mta-version-ext").SplitRight(".", nullptr, -2)); + const auto strSerialPart = GetApplicationSetting("serial").substr(0, 5); + const auto uiServerIP = static_cast(GetApplicationSettingInt("last-server-ip")); + const auto uiServerPort = static_cast(GetApplicationSettingInt("last-server-port")); + const auto uiServerTime = static_cast(GetApplicationSettingInt("last-server-time")); + const auto currentTime = _time64(nullptr); + + std::int64_t rawDuration = 0; + if (currentTime != -1) + rawDuration = currentTime - static_cast(uiServerTime); + rawDuration = std::clamp(rawDuration, std::int64_t{0}, std::numeric_limits::max() - 1); + const int uiServerDuration = static_cast(std::clamp(rawDuration + 1, std::int64_t{1}, std::int64_t{0x0fff})); + + SString strPathCode; + { + std::vector parts; + PathConform(CalcMTASAPath("")).Split(PATH_SEPERATOR, parts); + for (const auto& part : parts) + { + if (!part.empty()) + strPathCode += part.Left(1).ToUpper(); + } + } + + SString newFilename = SString("client_%s_%s_%08x_%x_%s_%08X_%04X_%03X_%s_%04d%02d%02d_%02d%02d.dmp", strMTAVersionFull.c_str(), + cleanedModuleName.c_str(), offset, exceptionCode & 0xffff, strPathCode.c_str(), uiServerIP, uiServerPort, + uiServerDuration, strSerialPart.c_str(), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute); + + SString newPath = PathJoin(dumpDir, newFilename); + + if (!MoveFileA(sourcePath, newPath)) + return {}; + + AppendWerInfoToDump(newPath, moduleName, offset, exceptionCode, regs); + + const SString coreDmpPath = CalcMTASAPath("mta\\core.dmp"); + CopyFileA(newPath, coreDmpPath, FALSE); + + return newPath; + } + + WerDumpResult FindAndRenameWerDump(const SString& dumpDir, const SString& moduleName, DWORD offset, DWORD exceptionCode, + const std::optional& processCreationTime) + { + OutputDebugStringA(SString("FindAndRenameWerDump: dumpDir=%s module=%s\n", dumpDir.c_str(), moduleName.c_str())); + + auto werDumpFiles = FindFiles(PathJoin(dumpDir, "gta_sa.exe.*.dmp"), true, false, true); + OutputDebugStringA(SString("FindAndRenameWerDump: Found %zu WER dump files\n", werDumpFiles.size())); + + if (werDumpFiles.empty()) + return {}; + + SString selectedPath; + FILETIME selectedWrite{}; + bool hasSelected = false; + + for (const auto& dumpFile : werDumpFiles) + { + const SString fullPath = PathJoin(dumpDir, dumpFile); + OutputDebugStringA(SString("FindAndRenameWerDump: Checking %s\n", dumpFile.c_str())); + + const HANDLE hFile = CreateFileA(fullPath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + if (hFile == INVALID_HANDLE_VALUE) + { + OutputDebugStringA(SString("FindAndRenameWerDump: Failed to open file (error %lu)\n", GetLastError())); + continue; + } + + FILETIME ftWrite{}; + const BOOL gotTime = GetFileTime(hFile, nullptr, nullptr, &ftWrite); + CloseHandle(hFile); + + if (!gotTime) + { + OutputDebugStringA("FindAndRenameWerDump: Failed to get file time\n"); + continue; + } + + if (!IsWriteTimeRecentEnough(ftWrite, 15)) + { + OutputDebugStringA("FindAndRenameWerDump: File too old (>15 min)\n"); + continue; + } + + if (processCreationTime.has_value()) + { + const auto lastWrite = FileTimeToDuration(ftWrite); + if (lastWrite < *processCreationTime) + { + OutputDebugStringA("FindAndRenameWerDump: File older than process creation\n"); + continue; + } + } + + if (!hasSelected || CompareFileTime(&ftWrite, &selectedWrite) > 0) + { + selectedPath = fullPath; + selectedWrite = ftWrite; + hasSelected = true; + OutputDebugStringA(SString("FindAndRenameWerDump: Selected %s\n", dumpFile.c_str())); + } + } + + if (!hasSelected) + { + OutputDebugStringA("FindAndRenameWerDump: No suitable file found\n"); + return {}; + } + + const SString sourceFilename = ExtractFilename(selectedPath); + OutputDebugStringA(SString("FindAndRenameWerDump: Renaming %s\n", selectedPath.c_str())); + const MinidumpRegisters regs = ExtractRegistersFromMinidump(selectedPath); + const SString newPath = RenameWerDumpToMtaFormat(selectedPath, dumpDir, moduleName, offset, exceptionCode, regs); + if (newPath.empty()) + { + OutputDebugStringA(SString("FindAndRenameWerDump: Rename failed (error %lu)\n", GetLastError())); + WerDumpResult failResult; + failResult.sourceFilename = sourceFilename; + failResult.regs = regs; + if (regs.valid) + failResult.stackTrace = ExtractStackTraceFromMinidump(selectedPath, regs); + return failResult; + } + + OutputDebugStringA(SString("FindAndRenameWerDump: SUCCESS - renamed to %s\n", newPath.c_str())); + WerDumpResult result; + result.path = newPath; + result.sourceFilename = sourceFilename; + result.regs = regs; + if (result.regs.valid) + { + result.stackTrace = ExtractStackTraceFromMinidump(newPath, result.regs); + } + return result; + } + + void UpdateModuleBases() + { + HANDLE hProcess = GetCurrentProcess(); + + int prevChunkCount = GetApplicationSettingInt("diagnostics", "module-bases-chunks"); + if (prevChunkCount < 1) + prevChunkCount = 6; + if (prevChunkCount > 256) + prevChunkCount = 256; + + struct InternalModuleEntry + { + SString entry; + bool isMta; + }; + + auto storeCurrentOnly = [&, prevChunkCount](bool truncatedFlag) + { + HMODULE hCurrent = nullptr; + if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + reinterpret_cast(&UpdateModuleBases), &hCurrent)) + { + wchar_t wszModName[MAX_PATH]; + if (GetModuleFileNameExW(hProcess, hCurrent, wszModName, MAX_PATH)) + { + const wchar_t* wfilename = wcsrchr(wszModName, L'\\'); + wfilename = wfilename ? wfilename + 1 : wszModName; + SString filename = UTF16ToMbUTF8(wfilename); + + MODULEINFO modInfo = {}; + if (GetModuleInformation(hProcess, hCurrent, &modInfo, sizeof(modInfo))) + { + SString strEntry = SString("%s=%08X,%08X", filename.c_str(), static_cast(reinterpret_cast(modInfo.lpBaseOfDll)), + modInfo.SizeOfImage); + SetApplicationSetting("diagnostics", "module-bases", strEntry); + for (int i = 1; i < prevChunkCount; ++i) + SetApplicationSetting("diagnostics", SString("module-bases-%d", i), ""); + SetApplicationSettingInt("diagnostics", "module-bases-chunks", 1); + SetApplicationSettingInt("diagnostics", "module-bases-truncated", truncatedFlag ? 1 : 0); + } + } + } + }; + + DWORD cbNeeded = 0; + if (!EnumProcessModules(hProcess, nullptr, 0, &cbNeeded) || cbNeeded == 0) + { + storeCurrentOnly(false); + return; + } + + size_t moduleCount = cbNeeded / sizeof(HMODULE); + if (moduleCount == 0) + { + storeCurrentOnly(false); + return; + } + + std::vector hMods(moduleCount); + if (!EnumProcessModules(hProcess, hMods.data(), static_cast(hMods.size() * sizeof(HMODULE)), &cbNeeded)) + { + storeCurrentOnly(false); + return; + } + + if (cbNeeded > hMods.size() * sizeof(HMODULE)) + { + moduleCount = cbNeeded / sizeof(HMODULE); + hMods.resize(moduleCount); + if (!EnumProcessModules(hProcess, hMods.data(), static_cast(hMods.size() * sizeof(HMODULE)), &cbNeeded)) + { + storeCurrentOnly(false); + return; + } + } + + moduleCount = std::min(moduleCount, static_cast(cbNeeded / sizeof(HMODULE))); + + std::vector entries; + entries.reserve(moduleCount); + + for (size_t i = 0; i < moduleCount; ++i) + { + if (!hMods[i]) + continue; + + wchar_t wszModName[MAX_PATH]; + if (!GetModuleFileNameExW(hProcess, hMods[i], wszModName, MAX_PATH)) + continue; + + const wchar_t* wfilename = wcsrchr(wszModName, L'\\'); + wfilename = wfilename ? wfilename + 1 : wszModName; + SString filename = UTF16ToMbUTF8(wfilename); + + MODULEINFO modInfo = {}; + if (!GetModuleInformation(hProcess, hMods[i], &modInfo, sizeof(modInfo))) + continue; + + SString lower = filename.ToLower(); + bool isMta = lower.Contains("core") || lower.Contains("client") || lower.Contains("game_sa") || lower.Contains("multiplayer") || + lower.Contains("netc") || lower.Contains("gta_sa") || lower.Contains("proxy_sa") || lower.Contains("cef") || lower.Contains("mta") || + lower.Contains("deathmatch") || lower.Contains("gui") || lower.Contains("xmll") || lower.Contains("loader"); + + InternalModuleEntry m; + m.entry = SString("%s=%08X,%08X", filename.c_str(), static_cast(reinterpret_cast(modInfo.lpBaseOfDll)), modInfo.SizeOfImage); + m.isMta = isMta; + entries.push_back(m); + } + + const size_t maxValueLen = 60000; + const size_t maxChunks = 256; + bool truncated = false; + + std::vector chunks; + chunks.reserve(prevChunkCount > 0 ? static_cast(prevChunkCount) : 6); + + auto tryAppend = [&](const SString& entry) -> bool + { + if (entry.length() > maxValueLen) + { + truncated = true; + return false; + } + for (auto& buffer : chunks) + { + size_t extra = entry.length(); + if (!buffer.empty()) + extra += 1; + if (buffer.length() + extra > maxValueLen) + continue; + if (!buffer.empty()) + buffer += ";"; + buffer += entry; + return true; + } + + if (chunks.size() >= maxChunks) + { + truncated = true; + return false; + } + + chunks.emplace_back(entry); + return true; + }; + + auto appendEntries = [&](bool mtaFirst) + { + for (const auto& e : entries) + { + if (e.isMta != mtaFirst) + continue; + + if (tryAppend(e.entry)) + continue; + + truncated = true; + return; + } + }; + + appendEntries(true); + if (!truncated) + appendEntries(false); + + bool anyData = false; + for (const auto& c : chunks) + { + if (!c.empty()) + { + anyData = true; + break; + } + } + + if (!anyData) + { + storeCurrentOnly(truncated); + return; + } + + auto setChunk = [&](size_t idx, const SString& value) + { + if (idx == 0) + SetApplicationSetting("diagnostics", "module-bases", value); + else + SetApplicationSetting("diagnostics", SString("module-bases-%d", static_cast(idx)), value); + }; + + const size_t usedChunks = chunks.size(); + for (size_t i = 0; i < usedChunks; ++i) + setChunk(i, chunks[i]); + + const size_t clearFrom = usedChunks; + const size_t clearTo = static_cast(std::max(prevChunkCount, static_cast(usedChunks))); + for (size_t i = clearFrom; i < clearTo; ++i) + setChunk(i, ""); + + SetApplicationSettingInt("diagnostics", "module-bases-chunks", static_cast(usedChunks > 0 ? usedChunks : 1)); + SetApplicationSettingInt("diagnostics", "module-bases-truncated", truncated ? 1 : 0); + } + + std::vector GetModuleBasesFromRegistry() + { + std::vector modules; + + int chunkCount = GetApplicationSettingInt("diagnostics", "module-bases-chunks"); + if (chunkCount <= 0) + chunkCount = 6; + if (chunkCount > 256) + chunkCount = 256; + + SString strModuleBases; + for (int i = 0; i < chunkCount; ++i) + { + SString key; + if (i == 0) + key = "module-bases"; + else + key.Format("module-bases-%d", i); + + SString chunk = GetApplicationSetting("diagnostics", key); + if (chunk.empty()) + continue; + + if (!strModuleBases.empty()) + strModuleBases += ";"; + strModuleBases += chunk; + } + + if (strModuleBases.empty()) + return modules; + + std::vector entries; + entries.reserve(128); + strModuleBases.Split(";", entries, true); + + for (const SString& entry : entries) + { + std::vector parts; + entry.Split("=", parts); + if (parts.size() != 2) + continue; + + ModuleEntry mod; + mod.name = parts[0]; + + std::vector addrParts; + parts[1].Split(",", addrParts); + + if (addrParts.empty()) + continue; + + SString addrStr = addrParts[0]; + addrStr.Replace("0x", ""); + addrStr.Replace("0X", ""); + mod.base = static_cast(strtoull(addrStr.c_str(), nullptr, 16)); + + if (addrParts.size() >= 2) + { + SString sizeStr = addrParts[1]; + sizeStr.Replace("0x", ""); + sizeStr.Replace("0X", ""); + mod.size = static_cast(strtoull(sizeStr.c_str(), nullptr, 16)); + } + else + { + mod.size = 0x400000; + } + + if (!mod.name.empty() && mod.base != 0 && mod.size != 0) + modules.push_back(mod); + } + + return modules; + } + + ResolvedModule ResolveAddressToModule(DWORD crashAddress) + { + int chunkCount = GetApplicationSettingInt("diagnostics", "module-bases-chunks"); + if (chunkCount <= 0) + chunkCount = 6; + if (chunkCount > 256) + chunkCount = 256; + + ResolvedModule result = ResolveAddressToModule(crashAddress, GetModuleBasesFromRegistry()); + result.debugChunkCount = chunkCount; + return result; + } + + ResolvedModule ResolveAddressToModule(DWORD crashAddress, const std::vector& modules) + { + ResolvedModule result{}; + result.crashAddress = crashAddress; + result.resolved = false; + result.debugModuleCount = static_cast(modules.size()); + + if (modules.empty()) + { + result.debugFailReason = 2; + return result; + } + + for (const ModuleEntry& mod : modules) + { + if (mod.size > 0xFFFFFFFF - mod.base) + continue; + + const DWORD moduleEnd = mod.base + mod.size; + + if (crashAddress >= mod.base && crashAddress < moduleEnd) + { + result.moduleName = mod.name; + result.moduleBase = mod.base; + result.rva = crashAddress - mod.base; + + const bool isExe = result.moduleName.EndsWithI(".exe"); + const DWORD idaBase = isExe ? kDefaultExeBase : kDefaultDllBase; + if (result.rva <= (0xFFFFFFFF - idaBase)) + result.idaAddress = idaBase + result.rva; + result.resolved = true; + return result; + } + } + + result.debugFailReason = 3; + return result; + } + + ResolvedModule ResolveAddressFromMinidump(const SString& dumpPath, DWORD crashAddress) + { + ResolvedModule result{}; + result.crashAddress = crashAddress; + result.resolved = false; + + if (dumpPath.empty()) + { + result.debugFailReason = 1; + return result; + } + + const HANDLE hFile = CreateFileA(dumpPath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + if (hFile == INVALID_HANDLE_VALUE) + { + result.debugFailReason = 1; + return result; + } + + LARGE_INTEGER fileSize{}; + if (!GetFileSizeEx(hFile, &fileSize) || fileSize.QuadPart < 1024 || fileSize.QuadPart > 512 * 1024 * 1024) + { + CloseHandle(hFile); + result.debugFailReason = 1; + return result; + } + const auto mappedSize = static_cast(fileSize.QuadPart); + + const HANDLE hMapping = CreateFileMappingA(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr); + if (!hMapping) + { + CloseHandle(hFile); + result.debugFailReason = 1; + return result; + } + + const LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); + if (!pBase) + { + CloseHandle(hMapping); + CloseHandle(hFile); + result.debugFailReason = 1; + return result; + } + + PMINIDUMP_DIRECTORY pModuleListDir = nullptr; + PVOID pModuleListStream = nullptr; + ULONG moduleListSize = 0; + + if (MiniDumpReadDumpStream(pBase, ModuleListStream, &pModuleListDir, &pModuleListStream, &moduleListSize)) + { + if (moduleListSize < sizeof(ULONG32)) + { + result.debugFailReason = 2; + UnmapViewOfFile(pBase); + CloseHandle(hMapping); + CloseHandle(hFile); + return result; + } + + auto* pModuleList = static_cast(pModuleListStream); + if (pModuleList && pModuleList->NumberOfModules > 0 && pModuleList->NumberOfModules < 10000) + { + const SIZE_T requiredSize = sizeof(MINIDUMP_MODULE_LIST) + (static_cast(pModuleList->NumberOfModules) - 1) * sizeof(MINIDUMP_MODULE); + if (moduleListSize < requiredSize) + { + result.debugFailReason = 2; + UnmapViewOfFile(pBase); + CloseHandle(hMapping); + CloseHandle(hFile); + return result; + } + + result.debugModuleCount = static_cast(pModuleList->NumberOfModules); + + for (ULONG i = 0; i < pModuleList->NumberOfModules; i++) + { + const auto& mod = pModuleList->Modules[i]; + const DWORD64 modBase = mod.BaseOfImage; + const DWORD32 modSize = mod.SizeOfImage; + + if (modSize == 0 || modSize > 0xFFFFFFFF - modBase) + continue; + + if (crashAddress >= modBase && crashAddress < modBase + modSize) + { + SString modName; + if (mod.ModuleNameRva != 0 && mod.ModuleNameRva < mappedSize && mod.ModuleNameRva <= mappedSize - sizeof(ULONG32)) + { + auto* pModName = reinterpret_cast(static_cast(pBase) + mod.ModuleNameRva); + if (pModName->Length > 0 && pModName->Length < 1024) + { + const SIZE_T stringOffset = mod.ModuleNameRva + sizeof(ULONG32); + if (stringOffset < mappedSize) + { + const SIZE_T availableForString = mappedSize - stringOffset; + if (pModName->Length <= availableForString) + { + try + { + std::wstring wname(pModName->Buffer, pModName->Length / sizeof(wchar_t)); + auto lastSlash = wname.find_last_of(L"\\/"); + if (lastSlash != std::wstring::npos) + wname = wname.substr(lastSlash + 1); + std::string name(wname.begin(), wname.end()); + modName = name.c_str(); + } + catch (...) + { + } + } + } + } + } + + if (!modName.empty()) + { + result.moduleName = modName; + result.moduleBase = static_cast(modBase); + result.rva = crashAddress - static_cast(modBase); + + const bool isExe = result.moduleName.EndsWithI(".exe"); + const DWORD idaBase = isExe ? kDefaultExeBase : kDefaultDllBase; + if (result.rva <= (0xFFFFFFFF - idaBase)) + result.idaAddress = idaBase + result.rva; + result.resolved = true; + break; + } + } + } + + if (!result.resolved) + result.debugFailReason = 3; + } + else + { + result.debugFailReason = 2; + } + } + else + { + result.debugFailReason = 2; + } + + UnmapViewOfFile(pBase); + CloseHandle(hMapping); + CloseHandle(hFile); + return result; + } +} diff --git a/Client/core/FastFailCrashHandler/WerCrashHandler.h b/Client/core/FastFailCrashHandler/WerCrashHandler.h new file mode 100644 index 00000000000..154edbfd735 --- /dev/null +++ b/Client/core/FastFailCrashHandler/WerCrashHandler.h @@ -0,0 +1,89 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Client/core/FastFailCrashHandler/WerCrashHandler.h + * PURPOSE: WER crash handler declarations. + * Capable of dump, register, and stacktrace collection fo 0xC0000409 / 0xC0000374 crashes. + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include + +#include +#include +#include +#include + +#include "SString.h" + +namespace WerCrash +{ + using FileTimeDuration = std::chrono::duration>; + + struct MinidumpRegisters + { + bool valid = false; + DWORD eax = 0, ebx = 0, ecx = 0, edx = 0; + DWORD esi = 0, edi = 0, ebp = 0, esp = 0, eip = 0; + DWORD eflags = 0; + WORD cs = 0, ds = 0, es = 0, fs = 0, gs = 0, ss = 0; + DWORD exceptionCode = 0; + DWORD64 exceptionAddress = 0; + }; + + struct WerDumpResult + { + SString path; + SString sourceFilename; + MinidumpRegisters regs; + SString stackTrace; + }; + + struct ModuleEntry + { + SString name; + DWORD base = 0; + DWORD size = 0; + }; + + struct ResolvedModule + { + bool resolved = false; + SString moduleName; + DWORD moduleBase = 0; + DWORD crashAddress = 0; + DWORD rva = 0; + DWORD idaAddress = 0; + int debugChunkCount = 0; + int debugModuleCount = 0; + int debugFailReason = 0; + }; + + [[nodiscard]] MinidumpRegisters ExtractRegistersFromMinidump(const SString& dumpPath); + [[nodiscard]] SString ExtractStackTraceFromMinidump(const SString& dumpPath, const MinidumpRegisters& regs); + + void AppendWerInfoToDump(const SString& dumpPath, const SString& moduleName, DWORD offset, DWORD exceptionCode, const MinidumpRegisters& regs); + + [[nodiscard]] SString RenameWerDumpToMtaFormat(const SString& sourcePath, const SString& dumpDir, const SString& moduleName, DWORD offset, + DWORD exceptionCode, const MinidumpRegisters& regs); + + [[nodiscard]] WerDumpResult FindAndRenameWerDump(const SString& dumpDir, const SString& moduleName, DWORD offset, DWORD exceptionCode, + const std::optional& processCreationTime); + + [[nodiscard]] bool IsFileRecentEnough(HANDLE hFile, std::uint64_t maxAgeMinutes = 15) noexcept; + + void UpdateModuleBases(); + + [[nodiscard]] std::vector GetModuleBasesFromRegistry(); + + [[nodiscard]] ResolvedModule ResolveAddressToModule(DWORD crashAddress); + + [[nodiscard]] ResolvedModule ResolveAddressToModule(DWORD crashAddress, const std::vector& modules); + + [[nodiscard]] ResolvedModule ResolveAddressFromMinidump(const SString& dumpPath, DWORD crashAddress); +} diff --git a/Client/core/Graphics/CGraphics.cpp b/Client/core/Graphics/CGraphics.cpp index 7d0a0dac738..5f250f398e8 100644 --- a/Client/core/Graphics/CGraphics.cpp +++ b/Client/core/Graphics/CGraphics.cpp @@ -11,6 +11,8 @@ #include "StdInc.h" #include +#include +#include "DXHook/CProxyDirect3DDevice9.h" #include "CTileBatcher.h" #include "CLine3DBatcher.h" #include "CMaterialLine3DBatcher.h" @@ -19,9 +21,9 @@ #include "CPrimitive3DBatcher.h" #include "CMaterialPrimitive3DBatcher.h" #include "CAspectRatioConverter.h" -extern CCore* g_pCore; -extern bool g_bInGTAScene; -extern bool g_bInMTAScene; +extern CCore* g_pCore; +extern std::atomic g_bInGTAScene; +extern std::atomic g_bInMTAScene; using namespace std; @@ -29,15 +31,15 @@ template <> CGraphics* CSingleton::m_pSingleton = NULL; const SColor g_rectEdgePixelsData[] = { - 0x00FFFF00, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, // - 0x00FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF, // - 0x00FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF, // - 0x00FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF, // - 0x00FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF, // - 0x00FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF, // - 0x00FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF, // - 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, // - 0x00080008 // Plain pixels size info + 0x00FFFF00, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, // + 0x00FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF, // + 0x00FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF, // + 0x00FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF, // + 0x00FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF, // + 0x00FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF, // + 0x00FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF, // + 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, // + 0x00080008 // Plain pixels size info }; CGraphics::CGraphics(CLocalGUI* pGUI) @@ -51,37 +53,84 @@ CGraphics::CGraphics(CLocalGUI* pGUI) m_ActiveBlendMode = EBlendMode::BLEND; m_CurDrawMode = EDrawMode::NONE; m_CurBlendMode = EBlendMode::BLEND; - - m_pRenderItemManager = new CRenderItemManager(); - m_pTileBatcher = new CTileBatcher(); - m_pLine3DBatcherPreGUI = new CLine3DBatcher(true); - m_pLine3DBatcherPostFX = new CLine3DBatcher(true); - m_pLine3DBatcherPostGUI = new CLine3DBatcher(false); - m_pMaterialLine3DBatcherPreGUI = new CMaterialLine3DBatcher(true); - m_pMaterialLine3DBatcherPostFX = new CMaterialLine3DBatcher(true); - m_pMaterialLine3DBatcherPostGUI = new CMaterialLine3DBatcher(false); - m_pPrimitive3DBatcherPreGUI = new CPrimitive3DBatcher(true); - m_pPrimitive3DBatcherPostFX = new CPrimitive3DBatcher(true); - m_pPrimitive3DBatcherPostGUI = new CPrimitive3DBatcher(false); - m_pMaterialPrimitive3DBatcherPreGUI = new CMaterialPrimitive3DBatcher(true, this); - m_pMaterialPrimitive3DBatcherPostFX = new CMaterialPrimitive3DBatcher(true, this); - m_pMaterialPrimitive3DBatcherPostGUI = new CMaterialPrimitive3DBatcher(false, this); - m_pPrimitiveBatcher = new CPrimitiveBatcher(); - m_pPrimitiveMaterialBatcher = new CPrimitiveMaterialBatcher(this); - - m_pScreenGrabber = NewScreenGrabber(); - m_pPixelsManager = NewPixelsManager(); - m_LastLostDeviceTimer.SetMaxIncrement(250); - m_pAspectRatioConverter = new CAspectRatioConverter(); + m_bSkipMTARenderThisFrame = false; + auto renderItemManager = std::make_unique(); + auto tileBatcher = std::make_unique(); + auto line3DPreGUI = std::make_unique(true); + auto line3DPostFX = std::make_unique(true); + auto line3DPostGUI = std::make_unique(false); + auto materialLinePreGUI = std::make_unique(true); + auto materialLinePostFX = std::make_unique(true); + auto materialLinePostGUI = std::make_unique(false); + auto primitive3DPreGUI = std::make_unique(true); + auto primitive3DPostFX = std::make_unique(true); + auto primitive3DPostGUI = std::make_unique(false); + auto materialPrimitivePreGUI = std::make_unique(true, this); + auto materialPrimitivePostFX = std::make_unique(true, this); + auto materialPrimitivePostGUI = std::make_unique(false, this); + auto primitiveBatcher = std::make_unique(); + auto primitiveMaterialBatcher = std::make_unique(this); + auto screenGrabber = std::unique_ptr(NewScreenGrabber()); + auto pixelsManager = std::unique_ptr(NewPixelsManager()); + auto aspectRatioConverter = std::make_unique(); + + m_pRenderItemManager = renderItemManager.release(); + m_pTileBatcher = tileBatcher.release(); + m_pLine3DBatcherPreGUI = line3DPreGUI.release(); + m_pLine3DBatcherPostFX = line3DPostFX.release(); + m_pLine3DBatcherPostGUI = line3DPostGUI.release(); + m_pMaterialLine3DBatcherPreGUI = materialLinePreGUI.release(); + m_pMaterialLine3DBatcherPostFX = materialLinePostFX.release(); + m_pMaterialLine3DBatcherPostGUI = materialLinePostGUI.release(); + m_pPrimitive3DBatcherPreGUI = primitive3DPreGUI.release(); + m_pPrimitive3DBatcherPostFX = primitive3DPostFX.release(); + m_pPrimitive3DBatcherPostGUI = primitive3DPostGUI.release(); + m_pMaterialPrimitive3DBatcherPreGUI = materialPrimitivePreGUI.release(); + m_pMaterialPrimitive3DBatcherPostFX = materialPrimitivePostFX.release(); + m_pMaterialPrimitive3DBatcherPostGUI = materialPrimitivePostGUI.release(); + m_pPrimitiveBatcher = primitiveBatcher.release(); + m_pPrimitiveMaterialBatcher = primitiveMaterialBatcher.release(); + m_pScreenGrabber = screenGrabber.release(); + m_pPixelsManager = pixelsManager.release(); + m_pAspectRatioConverter = aspectRatioConverter.release(); } CGraphics::~CGraphics() { if (m_pLineInterface) + { m_pLineInterface->Release(); + m_pLineInterface = nullptr; + } + + // Ensure queued draw items release their allocations before we tear down batchers + ClearDrawQueue(m_PreGUIQueue); + ClearDrawQueue(m_PostGUIQueue); + + if (m_pPrimitiveBatcher) + m_pPrimitiveBatcher->ClearQueue(); + if (m_pPrimitiveMaterialBatcher) + m_pPrimitiveMaterialBatcher->ClearQueue(); + if (m_pPrimitive3DBatcherPreGUI) + m_pPrimitive3DBatcherPreGUI->ClearQueue(); + if (m_pPrimitive3DBatcherPostFX) + m_pPrimitive3DBatcherPostFX->ClearQueue(); + if (m_pPrimitive3DBatcherPostGUI) + m_pPrimitive3DBatcherPostGUI->ClearQueue(); + if (m_pMaterialPrimitive3DBatcherPreGUI) + m_pMaterialPrimitive3DBatcherPreGUI->ClearQueue(); + if (m_pMaterialPrimitive3DBatcherPostFX) + m_pMaterialPrimitive3DBatcherPostFX->ClearQueue(); + if (m_pMaterialPrimitive3DBatcherPostGUI) + m_pMaterialPrimitive3DBatcherPostGUI->ClearQueue(); DestroyStandardDXFonts(); + SAFE_RELEASE(m_pDXSprite); + SAFE_RELEASE(m_pSavedStateBlock); + SAFE_RELEASE(m_pSavedFrontBufferData); + SAFE_RELEASE(m_pTempBackBufferData); + SAFE_RELEASE(m_ProgressSpinnerTexture); SAFE_RELEASE(m_RectangleEdgeTexture); SAFE_DELETE(m_pRenderItemManager); @@ -241,15 +290,15 @@ void CGraphics::DrawRectangleInternal(float fX, float fY, float fWidth, float fH int overrideWidth; int overrideHeight; } static sectionList[] = { - {{3, 3, 5, 5}, 0, 0, 0, 0}, // Center - {{3, 0, 5, 2}, 0, -2, 0, 2}, // Top - {{0, 0, 2, 2}, -2, -2, 2, 2}, // Top left - {{0, 3, 2, 5}, -2, 0, 2, 0}, // Left - {{0, 6, 2, 8}, -2, 2, 2, 2}, // Bottom left - {{3, 6, 5, 8}, 0, 2, 0, 2}, // Bottom - {{6, 6, 8, 8}, 2, 2, 2, 2}, // Bottom right - {{6, 3, 8, 5}, 2, 0, 2, 0}, // Right - {{6, 0, 8, 2}, 2, -2, 2, 2}, // Top right + {{3, 3, 5, 5}, 0, 0, 0, 0}, // Center + {{3, 0, 5, 2}, 0, -2, 0, 2}, // Top + {{0, 0, 2, 2}, -2, -2, 2, 2}, // Top left + {{0, 3, 2, 5}, -2, 0, 2, 0}, // Left + {{0, 6, 2, 8}, -2, 2, 2, 2}, // Bottom left + {{3, 6, 5, 8}, 0, 2, 0, 2}, // Bottom + {{6, 6, 8, 8}, 2, 2, 2, 2}, // Bottom right + {{6, 3, 8, 5}, 2, 0, 2, 0}, // Right + {{6, 0, 8, 2}, 2, -2, 2, 2}, // Top right }; D3DXMATRIX matrix; @@ -735,7 +784,17 @@ void CGraphics::GetDXTextSize(CVector2D& vecSize, const char* szText, float fWid ulFormat |= DT_WORDBREAK; // Calculate the size of the text - RECT rect = {0, 0, fWidth / fScaleX, 0}; + const float fRectRight = fWidth / fScaleX; + LONG rectRight = 0; + if (fRectRight > 0.0f) + { + if (fRectRight >= static_cast(LONG_MAX)) + rectRight = LONG_MAX; + else + rectRight = static_cast(fRectRight); + } + + RECT rect = {0, 0, rectRight, 0}; pDXFont->DrawTextW(nullptr, strText.c_str(), strText.length(), &rect, ulFormat, D3DCOLOR_XRGB(0, 0, 0)); vecSize.fX = (rect.right - rect.left) * fScaleX; @@ -993,7 +1052,6 @@ void CGraphics::DrawMaterialPrimitive3DQueued(std::vectorAddPrimitive(eType, pMaterial, pVecVertices); else m_pMaterialPrimitive3DBatcherPostFX->AddPrimitive(eType, pMaterial, pVecVertices); - } void CGraphics::DrawMaterialPrimitiveQueued(std::vector* pVecVertices, D3DPRIMITIVETYPE eType, CMaterialItem* pMaterial, @@ -1209,7 +1267,7 @@ void CGraphics::DrawStringQueued(float fLeft, float fTop, float fRight, float fB else if (ulFormat & DT_VCENTER) fY = (fBottom + fTop - fTotalHeight) * 0.5f; else - fY = fTop; // DT_TOP + fY = fTop; // DT_TOP // Process each line SColor currentColor = dwColor; @@ -1243,7 +1301,7 @@ void CGraphics::DrawColorCodedTextLine(float fLeft, float fRight, float fY, SCol unsigned int uiSeekPos = 0; const wchar_t* wszSectionStart = wszSectionPos; SColor nextColor = currentColor; - while (*wszSectionPos != '\0') // find end of this section + while (*wszSectionPos != '\0') // find end of this section { if (IsColorCodeW(wszSectionPos)) { @@ -1297,7 +1355,7 @@ void CGraphics::DrawColorCodedTextLine(float fLeft, float fRight, float fY, SCol else if (ulFormat & DT_CENTER) fX = (fRight + fLeft - fTotalWidth) * 0.5f; else - fX = fLeft; // DT_LEFT + fX = fLeft; // DT_LEFT // Draw all the color sections for (std::list::const_iterator iter = sectionList.begin(); iter != sectionList.end(); ++iter) @@ -1435,13 +1493,13 @@ bool CGraphics::CreateStandardDXFontWithCustomScale(eFontType fontType, float fS bool CGraphics::LoadAdditionalDXFont(std::string strFontPath, std::string strFontName, unsigned int uiHeight, bool bBold, DWORD ulQuality, ID3DXFont** ppD3DXFont) { - int iLoaded = AddFontResourceEx(strFontPath.c_str(), FR_PRIVATE, 0); + int iLoaded = AddFontResourceEx(strFontPath.c_str(), FR_PRIVATE, 0); + bool bFontResourceAdded = (iLoaded > 0); int iWeight = bBold ? FW_BOLD : FW_NORMAL; *ppD3DXFont = NULL; bool bSuccess = true; - // Normal size if (!SUCCEEDED(D3DXCreateFont(m_pDevice, uiHeight, 0, iWeight, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ulQuality, DEFAULT_PITCH | FF_DONTCARE, strFontName.c_str(), ppD3DXFont))) { @@ -1449,7 +1507,18 @@ bool CGraphics::LoadAdditionalDXFont(std::string strFontPath, std::string strFon bSuccess = false; } - return bSuccess && (iLoaded == 1); + if (!bSuccess && bFontResourceAdded) + { + RemoveFontResourceEx(strFontPath.c_str(), FR_PRIVATE, 0); + } + + if (!bFontResourceAdded) + { + SAFE_RELEASE(*ppD3DXFont); + return false; + } + + return bSuccess; } bool CGraphics::LoadAdditionalDXFont(std::string strFontPath, std::string strFontName, unsigned int uiHeight, bool bBold, ID3DXFont** ppD3DXFont) @@ -1495,6 +1564,17 @@ void CGraphics::DrawTexture(CTextureItem* pTexture, float fX, float fY, float fS if (!pTexture) return; + if (CRenderTargetItem* pRenderTarget = DynamicCast(pTexture)) + { + if (!pRenderTarget->TryEnsureValid()) + return; + } + else if (CScreenSourceItem* pScreenSource = DynamicCast(pTexture)) + { + if (!pScreenSource->TryEnsureValid()) + return; + } + const float fSurfaceWidth = pTexture->m_uiSurfaceSizeX; const float fSurfaceHeight = pTexture->m_uiSurfaceSizeY; const float fFileWidth = pTexture->m_uiSizeX; @@ -1526,6 +1606,18 @@ void CGraphics::OnDeviceCreate(IDirect3DDevice9* pDevice) { m_pDevice = pDevice; + if (GetInitializationPhase() != INIT_PHASE_POST_D3D) + { + if (!EnableAllHandlersAfterInitialization()) + { + SafeDebugOutput("CGraphics::OnDeviceCreate - Failed to enable crash handlers after device creation\n"); + } + else + { + SafeDebugOutput("CGraphics::OnDeviceCreate - Crash handlers enabled after device creation\n"); + } + } + LoadStandardDXFonts(); // Create drawing devices @@ -1578,8 +1670,15 @@ void CGraphics::OnDeviceInvalidate(IDirect3DDevice9* pDevice) m_pRenderItemManager->OnLostDevice(); m_pScreenGrabber->OnLostDevice(); + SAFE_RELEASE(m_pSavedStateBlock); SAFE_RELEASE(m_pSavedFrontBufferData); SAFE_RELEASE(m_pTempBackBufferData); + + // Reset render zone tracking on device loss + m_MTARenderZone = MTA_RZONE_NONE; + m_iOutsideZoneCount = 0; + m_bRestoreViewportAfterMTA = false; + m_bRestoreScissorAfterMTA = false; } void CGraphics::OnDeviceRestore(IDirect3DDevice9* pDevice) @@ -1604,6 +1703,19 @@ void CGraphics::OnDeviceRestore(IDirect3DDevice9* pDevice) m_pRenderItemManager->OnResetDevice(); m_pScreenGrabber->OnResetDevice(); + + const uint uiViewportWidth = GetViewportWidth(); + const uint uiViewportHeight = GetViewportHeight(); + if (uiViewportWidth > 0 && uiViewportHeight > 0) + { + m_pRenderItemManager->OnViewportSizeChanged(uiViewportWidth, uiViewportHeight); + UpdateRenderTargetMatrices(uiViewportWidth, uiViewportHeight); + m_pAspectRatioConverter->Init(uiViewportHeight); + } + else + { + m_bPendingViewportRefresh = true; + } } void CGraphics::OnZBufferModified() @@ -1695,7 +1807,7 @@ void CGraphics::DrawQueue(std::vector& Queue) void CGraphics::AddQueueItem(const sDrawQueueItem& Item, bool bPostGUI) { // Add it to the correct queue - if (bPostGUI && !CCore::GetSingleton().IsMenuVisible()) // Don't draw over the main menu. Ever. + if (bPostGUI && !CCore::GetSingleton().IsMenuVisible()) // Don't draw over the main menu. Ever. m_PostGUIQueue.push_back(Item); else m_PreGUIQueue.push_back(Item); @@ -1761,7 +1873,7 @@ void CGraphics::DrawQueueItem(const sDrawQueueItem& Item) const float fPosFracY = Item.Text.fTop - rect.top; D3DXMATRIX matrix; D3DXVECTOR2 scaling(Item.Text.fScaleX, Item.Text.fScaleY); - D3DXVECTOR2 translation(fPosFracX * Item.Text.fScaleX, fPosFracY * Item.Text.fScaleY); // Sub-pixel positioning + D3DXVECTOR2 translation(fPosFracX * Item.Text.fScaleX, fPosFracY * Item.Text.fScaleY); // Sub-pixel positioning D3DXVECTOR2 rotcenter(Item.Text.fRotationCenterX, Item.Text.fRotationCenterY); D3DXVECTOR2* pRotcenter = Item.Text.fRotation ? &rotcenter : NULL; D3DXMatrixTransformation2D(&matrix, NULL, 0.0f, &scaling, pRotcenter, DegreesToRadians(Item.Text.fRotation), &translation); @@ -1776,6 +1888,29 @@ void CGraphics::DrawQueueItem(const sDrawQueueItem& Item) { if (CTextureItem* pTexture = DynamicCast(Item.Texture.pMaterial)) { + if (CRenderTargetItem* pRenderTarget = DynamicCast(pTexture)) + { + if (!pRenderTarget->TryEnsureValid()) + { + RemoveQueueRef(Item.Texture.pMaterial); + break; + } + } + else if (CScreenSourceItem* pScreenSource = DynamicCast(pTexture)) + { + if (!pScreenSource->TryEnsureValid()) + { + RemoveQueueRef(Item.Texture.pMaterial); + break; + } + } + + if (!pTexture->m_pD3DTexture) + { + RemoveQueueRef(Item.Texture.pMaterial); + break; + } + const sDrawQueueTexture& t = Item.Texture; RECT cutImagePos; const float fSurfaceWidth = pTexture->m_uiSurfaceSizeX; @@ -1837,6 +1972,7 @@ void CGraphics::DrawQueueItem(const sDrawQueueItem& Item) const sDrawQueuePrimitiveMaterial primitive = Item.PrimitiveMaterial; CheckModes(EDrawMode::PRIMITIVE_MATERIAL, Item.blendMode); m_pPrimitiveMaterialBatcher->AddPrimitive(primitive.eType, primitive.pMaterial, primitive.pVecVertices); + RemoveQueueRef(primitive.pMaterial); break; } } @@ -1855,7 +1991,7 @@ ID3DXFont* CGraphics::MaybeGetBigFont(ID3DXFont* pDXFont, float& fScaleX, float& { // Adjust scale to compensate for higher res font fScaleX *= 0.25f; - if (&fScaleX != &fScaleY) // Check fScaleY is not the same variable + if (&fScaleX != &fScaleY) // Check fScaleY is not the same variable fScaleY *= 0.25f; return m_pBigDXFonts[i]; } @@ -1873,9 +2009,25 @@ void CGraphics::ClearDrawQueue(std::vector& Queue) { const sDrawQueueItem& item = *iter; if (item.eType == QUEUE_TEXTURE || item.eType == QUEUE_SHADER) + { RemoveQueueRef(item.Texture.pMaterial); + } + else if (item.eType == QUEUE_PRIMITIVEMATERIAL) + { + if (item.PrimitiveMaterial.pMaterial) + RemoveQueueRef(item.PrimitiveMaterial.pMaterial); + // Flush any queued geometry that never reached the batcher + delete item.PrimitiveMaterial.pVecVertices; + } + else if (item.eType == QUEUE_PRIMITIVE) + { + // Prevent per-primitive allocations from leaking when we clear the queue early + delete item.Primitive.pVecVertices; + } else if (item.eType == QUEUE_TEXT) + { RemoveQueueRef(item.Text.pDXFont); + } } Queue.clear(); } @@ -1886,25 +2038,25 @@ void CGraphics::ClearDrawQueue(std::vector& Queue) void CGraphics::AddQueueRef(CRenderItem* pRenderItem) { pRenderItem->AddRef(); - m_iDebugQueueRefs++; // For debugging + m_iDebugQueueRefs++; // For debugging } void CGraphics::RemoveQueueRef(CRenderItem* pRenderItem) { pRenderItem->Release(); - m_iDebugQueueRefs--; // For debugging + m_iDebugQueueRefs--; // For debugging } void CGraphics::AddQueueRef(IUnknown* pUnknown) { pUnknown->AddRef(); - m_iDebugQueueRefs++; // For debugging + m_iDebugQueueRefs++; // For debugging } void CGraphics::RemoveQueueRef(IUnknown* pUnknown) { pUnknown->Release(); - m_iDebugQueueRefs--; // For debugging + m_iDebugQueueRefs--; // For debugging } // Notification that the render target will be changing @@ -1913,11 +2065,164 @@ void CGraphics::OnChangingRenderTarget(uint uiNewViewportSizeX, uint uiNewViewpo // Flush dx draws DrawPreGUIQueue(); // Inform batchers + UpdateRenderTargetMatrices(uiNewViewportSizeX, uiNewViewportSizeY); +} + +void CGraphics::UpdateRenderTargetMatrices(uint uiNewViewportSizeX, uint uiNewViewportSizeY) +{ m_pTileBatcher->OnChangingRenderTarget(uiNewViewportSizeX, uiNewViewportSizeY); m_pPrimitiveBatcher->OnChangingRenderTarget(uiNewViewportSizeX, uiNewViewportSizeY); m_pPrimitiveMaterialBatcher->OnChangingRenderTarget(uiNewViewportSizeX, uiNewViewportSizeY); } +void CGraphics::MarkViewportRefreshPending() +{ + m_bPendingViewportRefresh = true; + m_uiPendingViewportRefreshTries = 0; + m_bPendingBackbufferOverrideAttempted = false; + ++m_uiViewportRefreshSerial; + m_bForceFullViewportInMTA = false; + m_bForceFullScissorInMTA = false; +} + +void CGraphics::RefreshViewportIfNeeded() +{ + if (m_pDevice == nullptr) + return; + + const HRESULT hrCoop = m_pDevice->TestCooperativeLevel(); + if (hrCoop != D3D_OK) + { + return; + } + + D3DVIEWPORT9 viewport = {}; + if (FAILED(m_pDevice->GetViewport(&viewport)) || viewport.Width == 0 || viewport.Height == 0) + { + return; + } + + if (!m_pRenderItemManager || !m_pAspectRatioConverter) + return; + + const uint uiCachedWidth = GetViewportWidth(); + const uint uiCachedHeight = GetViewportHeight(); + if (!m_bPendingViewportRefresh && viewport.Width == uiCachedWidth && viewport.Height == uiCachedHeight) + return; + + constexpr uint kMinValidViewportSize = 16; + constexpr uint kMaxPendingRefreshTries = 60; + if (m_bPendingViewportRefresh && viewport.Width == uiCachedWidth && viewport.Height == uiCachedHeight) + { + if (m_uiPendingViewportRefreshTries++ < kMaxPendingRefreshTries) + return; + } + + uint targetWidth = viewport.Width; + uint targetHeight = viewport.Height; + if (m_bPendingViewportRefresh && (viewport.Width <= kMinValidViewportSize || viewport.Height <= kMinValidViewportSize)) + { + D3DSURFACE_DESC backBufferDesc = {}; + IDirect3DSurface9* pBackBuffer = nullptr; + if (SUCCEEDED(m_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer)) && pBackBuffer) + { + if (SUCCEEDED(pBackBuffer->GetDesc(&backBufferDesc)) && backBufferDesc.Width > 0 && backBufferDesc.Height > 0) + { + targetWidth = backBufferDesc.Width; + targetHeight = backBufferDesc.Height; + } + pBackBuffer->Release(); + } + } + else if (m_bPendingViewportRefresh && !m_bPendingBackbufferOverrideAttempted && m_uiViewportLastAppliedSerial < m_uiViewportRefreshSerial && + viewport.Width == uiCachedWidth && viewport.Height == uiCachedHeight) + { + D3DSURFACE_DESC backBufferDesc = {}; + IDirect3DSurface9* pBackBuffer = nullptr; + if (SUCCEEDED(m_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer)) && pBackBuffer) + { + if (SUCCEEDED(pBackBuffer->GetDesc(&backBufferDesc)) && backBufferDesc.Width > 0 && backBufferDesc.Height > 0 && + (backBufferDesc.Width != viewport.Width || backBufferDesc.Height != viewport.Height)) + { + targetWidth = backBufferDesc.Width; + targetHeight = backBufferDesc.Height; + } + pBackBuffer->Release(); + } + m_bPendingBackbufferOverrideAttempted = true; + } + + if (m_bPendingViewportRefresh && (viewport.X != 0 || viewport.Y != 0)) + { + m_bForceFullViewportInMTA = true; + m_uiForceViewportWidth = targetWidth; + m_uiForceViewportHeight = targetHeight; + } + + const bool wasPending = m_bPendingViewportRefresh; + CDirect3DData::GetSingleton().StoreViewport(viewport.X, viewport.Y, targetWidth, targetHeight); + m_pRenderItemManager->OnViewportSizeChanged(targetWidth, targetHeight); + UpdateRenderTargetMatrices(targetWidth, targetHeight); + m_pAspectRatioConverter->Init(targetHeight); + m_bPendingViewportRefresh = false; + m_uiPendingViewportRefreshTries = 0; + m_uiViewportLastAppliedSerial = m_uiViewportRefreshSerial; + if (wasPending) + { + m_uiForceViewportWidth = targetWidth; + m_uiForceViewportHeight = targetHeight; + m_bForceFullScissorInMTA = true; + } +} + +void CGraphics::ApplyMTARenderViewportIfNeeded() +{ + if ((!m_bForceFullViewportInMTA && !m_bForceFullScissorInMTA) || !m_pDevice) + return; + + const HRESULT hrCoop = m_pDevice->TestCooperativeLevel(); + if (hrCoop != D3D_OK) + return; + + uint targetWidth = m_uiForceViewportWidth; + uint targetHeight = m_uiForceViewportHeight; + if (targetWidth == 0 || targetHeight == 0) + { + D3DVIEWPORT9 viewport = {}; + if (FAILED(m_pDevice->GetViewport(&viewport)) || viewport.Width == 0 || viewport.Height == 0) + return; + targetWidth = viewport.Width; + targetHeight = viewport.Height; + } + + if (m_bForceFullViewportInMTA) + { + if (SUCCEEDED(m_pDevice->GetViewport(&m_prevViewportForMTA))) + m_bRestoreViewportAfterMTA = true; + + D3DVIEWPORT9 viewport = {}; + viewport.X = 0; + viewport.Y = 0; + viewport.Width = targetWidth; + viewport.Height = targetHeight; + viewport.MinZ = 0.0f; + viewport.MaxZ = 1.0f; + m_pDevice->SetViewport(&viewport); + m_bForceFullViewportInMTA = false; + } + + if (m_bForceFullScissorInMTA) + { + RECT fullRect = {0, 0, static_cast(targetWidth), static_cast(targetHeight)}; + if (SUCCEEDED(m_pDevice->GetScissorRect(&m_prevScissorForMTA))) + m_bRestoreScissorAfterMTA = true; + m_pDevice->GetRenderState(D3DRS_SCISSORTESTENABLE, &m_prevScissorEnableForMTA); + m_pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + m_pDevice->SetScissorRect(&fullRect); + m_bForceFullScissorInMTA = false; + } +} + //////////////////////////////////////////////////////////////// // // CGraphics::EnteringMTARenderZone @@ -1942,6 +2247,20 @@ void CGraphics::EnteringMTARenderZone() void CGraphics::LeavingMTARenderZone() { RestoreGTARenderStates(); + if (m_pDevice && m_pDevice->TestCooperativeLevel() == D3D_OK) + { + if (m_bRestoreViewportAfterMTA) + { + m_pDevice->SetViewport(&m_prevViewportForMTA); + m_bRestoreViewportAfterMTA = false; + } + if (m_bRestoreScissorAfterMTA) + { + m_pDevice->SetScissorRect(&m_prevScissorForMTA); + m_pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, m_prevScissorEnableForMTA); + m_bRestoreScissorAfterMTA = false; + } + } m_MTARenderZone = MTA_RZONE_NONE; m_iOutsideZoneCount = 0; } @@ -2003,9 +2322,24 @@ void CGraphics::MaybeLeavingMTARenderZone() //////////////////////////////////////////////////////////////// void CGraphics::SaveGTARenderStates() { + // Prevent GPU driver hang by checking device state before creating state blocks + if (m_pDevice->TestCooperativeLevel() != D3D_OK) + { + m_bSkipMTARenderThisFrame = true; + return; + } + SAFE_RELEASE(m_pSavedStateBlock); - // Create a state block. - m_pDevice->CreateStateBlock(D3DSBT_ALL, &m_pSavedStateBlock); + + // Add error handling for state block creation + HRESULT hr = m_pDevice->CreateStateBlock(D3DSBT_ALL, &m_pSavedStateBlock); + if (FAILED(hr)) + { + WriteDebugEvent(SString("CGraphics::SaveGTARenderStates - Failed to create state block: %08x", hr)); + m_pSavedStateBlock = nullptr; + m_bSkipMTARenderThisFrame = true; + return; + } // Make sure linear sampling is enabled m_pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); @@ -2025,6 +2359,13 @@ void CGraphics::SaveGTARenderStates() //////////////////////////////////////////////////////////////// void CGraphics::RestoreGTARenderStates() { + // Check device state before attempting to restore + if (m_pDevice->TestCooperativeLevel() != D3D_OK) + { + SAFE_RELEASE(m_pSavedStateBlock); + return; + } + // Restore these transforms to fix various weird stuff m_pDevice->SetTransform(D3DTS_PROJECTION, &g_pDeviceState->TransformState.PROJECTION); m_pDevice->SetTransform(D3DTS_WORLD, &g_pDeviceState->TransformState.WORLD); @@ -2033,7 +2374,12 @@ void CGraphics::RestoreGTARenderStates() // Restore the render states if (m_pSavedStateBlock) { - m_pSavedStateBlock->Apply(); + // Error handling for state block apply + HRESULT hr = m_pSavedStateBlock->Apply(); + if (FAILED(hr)) + { + WriteDebugEvent(SString("RestoreGTARenderStates: Failed to apply state block: %08x", hr)); + } SAFE_RELEASE(m_pSavedStateBlock); } } @@ -2119,11 +2465,52 @@ void CGraphics::DrawProgressMessage(bool bPreserveBackbuffer) if (m_LastLostDeviceTimer.Get() < 1000) return; - const bool bWasInScene = g_bInGTAScene || g_bInMTAScene; - bool bInScene = bWasInScene; + const auto determineOwner = []() -> ESceneOwner + { + if (g_bInMTAScene.load(std::memory_order_acquire)) + return ESceneOwner::MTA; + if (g_bInGTAScene.load(std::memory_order_acquire)) + return ESceneOwner::GTA; + return ESceneOwner::None; + }; + + const ESceneOwner originalOwner = determineOwner(); + ESceneOwner currentOwner = originalOwner; + + auto inScene = [&]() { return currentOwner != ESceneOwner::None; }; + + auto endCurrentScene = [&](const char* context) -> bool + { + if (!inScene()) + return true; + if (!EndSceneWithoutProxy(m_pDevice, currentOwner)) + { + SString msg; + msg.Format("%s: EndSceneWithoutProxy failed for owner %d", context, static_cast(currentOwner)); + WriteDebugEvent(msg); + return false; + } + currentOwner = ESceneOwner::None; + return true; + }; + + auto beginSceneAs = [&](ESceneOwner owner, const char* context) -> bool + { + if (owner == ESceneOwner::None) + return true; + if (!BeginSceneWithoutProxy(m_pDevice, owner)) + { + SString msg; + msg.Format("%s: BeginSceneWithoutProxy failed for owner %d", context, static_cast(owner)); + WriteDebugEvent(msg); + return false; + } + currentOwner = owner; + return true; + }; - // Skip of not in a scene and not forced with always flag - if (!bInScene && !g_pCore->GetDummyProgressUpdateAlways()) + // Skip if not in a scene and not forced with always flag + if (!inScene() && !g_pCore->GetDummyProgressUpdateAlways()) return; // Check if disabled @@ -2131,6 +2518,12 @@ void CGraphics::DrawProgressMessage(bool bPreserveBackbuffer) if (!bEnabled) return; + struct CacheSuspendScope + { + CacheSuspendScope() { SetSuspendDeviceStateCache(true); } + ~CacheSuspendScope() { SetSuspendDeviceStateCache(false); } + } cacheSuspendScope; + // // Save stuff // @@ -2151,10 +2544,10 @@ void CGraphics::DrawProgressMessage(bool bPreserveBackbuffer) { if (bPreserveBackbuffer) { - if (bInScene) + if (inScene()) { - m_pDevice->EndScene(); - bInScene = false; + if (!endCurrentScene("CGraphics::DrawProgressMessage (preserve setup)")) + break; } // Get backbuffer surface @@ -2211,10 +2604,10 @@ void CGraphics::DrawProgressMessage(bool bPreserveBackbuffer) break; } - if (!bInScene) + if (!inScene()) { - m_pDevice->BeginScene(); - bInScene = true; + if (!beginSceneAs(ESceneOwner::MTA, "CGraphics::DrawProgressMessage (draw setup)")) + break; } // Draw progress graphics on backbuffer surface @@ -2255,12 +2648,24 @@ void CGraphics::DrawProgressMessage(bool bPreserveBackbuffer) if (bPreserveBackbuffer) { - m_pDevice->EndScene(); - bInScene = false; + if (inScene()) + { + if (!endCurrentScene("CGraphics::DrawProgressMessage (pre-present)")) + break; + } // Flip backbuffer onto front buffer SAFE_RELEASE(pD3DBackBufferSurface); - hr = m_pDevice->Present(NULL, NULL, NULL, NULL); + IDirect3DDevice9* pPresentDevice = m_pDevice; + CScopedActiveProxyDevice proxyDevice; + if (proxyDevice && pPresentDevice == static_cast(proxyDevice.Get())) + { + hr = proxyDevice->PresentWithoutProxy(nullptr, nullptr, nullptr, nullptr); + } + else + { + hr = pPresentDevice->Present(nullptr, nullptr, nullptr, nullptr); + } if (FAILED(hr)) break; @@ -2269,9 +2674,14 @@ void CGraphics::DrawProgressMessage(bool bPreserveBackbuffer) if (FAILED(hr)) break; hr = m_pDevice->StretchRect(m_pTempBackBufferData->m_pD3DRenderTargetSurface, NULL, pD3DBackBufferSurface, NULL, D3DTEXF_POINT); + if (FAILED(hr)) + { + WriteDebugEvent("CGraphics::DrawProgressMessage: StretchRect restore failed"); + break; + } - m_pDevice->BeginScene(); - bInScene = true; + if (!beginSceneAs(ESceneOwner::MTA, "CGraphics::DrawProgressMessage (post-present)")) + break; } } while (false); @@ -2279,14 +2689,27 @@ void CGraphics::DrawProgressMessage(bool bPreserveBackbuffer) SAFE_RELEASE(pTempFrontBufferData); SAFE_RELEASE(pD3DBackBufferSurface); - // Ensure scene status is restored - if (bInScene != bWasInScene) + // Ensure scene status is restored to its original owner + if (currentOwner != originalOwner) { - if (bWasInScene) - m_pDevice->BeginScene(); - else - m_pDevice->EndScene(); - bInScene = bWasInScene; + bool restorePossible = true; + if (currentOwner != ESceneOwner::None) + restorePossible = endCurrentScene("CGraphics::DrawProgressMessage (restore current)"); + + if (restorePossible && originalOwner != ESceneOwner::None && currentOwner != originalOwner) + { + if (!beginSceneAs(originalOwner, "CGraphics::DrawProgressMessage (restore original)")) + { + if (originalOwner == ESceneOwner::GTA) + { + ResetGTASceneState(); + } + else if (originalOwner == ESceneOwner::MTA) + { + g_bInMTAScene.store(false, std::memory_order_release); + } + } + } } // @@ -2461,7 +2884,7 @@ namespace // Initial octahedron static SFixedArray vecPoints = {CVector(0, 0, 1), CVector(0, 0, -1), CVector(-1, -1, 0), - CVector(1, -1, 0), CVector(1, 1, 0), CVector(-1, 1, 0)}; + CVector(1, -1, 0), CVector(1, 1, 0), CVector(-1, 1, 0)}; static const SFixedArray indices = {0, 3, 4, 0, 4, 5, 0, 5, 2, 0, 2, 3, 1, 4, 3, 1, 5, 4, 1, 2, 5, 1, 3, 2}; for (uint i = 0; i < NUMELMS(vecPoints); i++) @@ -2520,7 +2943,7 @@ namespace for (int i = 0; i < (int)vertexList.size() - 1; i += 2) if ((from - vertexList[i]).LengthSquared() < 0.00001f) if ((to - vertexList[i + 1]).LengthSquared() < 0.00001f) - return; // Duplicated + return; // Duplicated // Add new line vertexList.push_back(from); @@ -2553,7 +2976,7 @@ namespace } return wireModel; } -} // namespace +} // namespace void CGraphics::DrawWiredSphere(CVector vecPosition, float fRadius, SColor color, float fLineWidth, int iterations) { diff --git a/Client/core/Graphics/CGraphics.h b/Client/core/Graphics/CGraphics.h index 0dac23e1d05..84186c13703 100644 --- a/Client/core/Graphics/CGraphics.h +++ b/Client/core/Graphics/CGraphics.h @@ -19,9 +19,9 @@ class CGraphics; #include "CSingleton.h" #include "CRenderItemManager.h" -#define DUMMY_PROGRESS_INITIAL_DELAY 1000 // Game stall time before spinner is displayed -#define DUMMY_PROGRESS_MIN_DISPLAY_TIME 1000 // Minimum time spinner is drawn (to prevent flicker) -#define DUMMY_PROGRESS_ANIMATION_INTERVAL 100 // Animation speed +#define DUMMY_PROGRESS_INITIAL_DELAY 1000 // Game stall time before spinner is displayed +#define DUMMY_PROGRESS_MIN_DISPLAY_TIME 1000 // Minimum time spinner is drawn (to prevent flicker) +#define DUMMY_PROGRESS_ANIMATION_INTERVAL 100 // Animation speed class CTileBatcher; class CLine3DBatcher; @@ -154,7 +154,8 @@ class CGraphics : public CGraphicsInterface, public CSingleton void DrawMaterialPrimitiveQueued(std::vector* vertices, D3DPRIMITIVETYPE type, CMaterialItem* pMaterial, bool bPostGUI); void DrawPrimitive3DQueued(std::vector* pVecVertices, D3DPRIMITIVETYPE eType, eRenderStage stage = eRenderStage::PRE_FX); - void DrawMaterialPrimitive3DQueued(std::vector* pVecVertices, D3DPRIMITIVETYPE eType, CMaterialItem* pMaterial, eRenderStage stage = eRenderStage::PRE_FX); + void DrawMaterialPrimitive3DQueued(std::vector* pVecVertices, D3DPRIMITIVETYPE eType, CMaterialItem* pMaterial, + eRenderStage stage = eRenderStage::PRE_FX); void DrawCircleQueued(float fX, float fY, float fRadius, float fStartAngle, float fStopAngle, unsigned long ulColor, unsigned long ulColorCenter, short siSegments, float fRatio, bool bPostGUI); @@ -169,6 +170,11 @@ class CGraphics : public CGraphicsInterface, public CSingleton CRenderItemManagerInterface* GetRenderItemManager() { return m_pRenderItemManager; } CScreenGrabberInterface* GetScreenGrabber() { return m_pScreenGrabber; } CPixelsManagerInterface* GetPixelsManager() { return m_pPixelsManager; } + void RetryInvalidRenderTargets() + { + if (m_pRenderItemManager) + m_pRenderItemManager->RetryInvalidRenderTargets(); + } // Transition between GTA and MTA controlled rendering virtual void EnteringMTARenderZone(); @@ -200,6 +206,11 @@ class CGraphics : public CGraphicsInterface, public CSingleton void SetProgressMessage(const SString& strMessage); void DrawProgressMessage(bool bPreserveBackbuffer = true); void DrawRectangleInternal(float fX, float fY, float fWidth, float fHeight, unsigned long ulColor, bool bSubPixelPositioning); + void MarkViewportRefreshPending(); + void RefreshViewportIfNeeded(); + void ApplyMTARenderViewportIfNeeded(); + void SetSkipMTARenderThisFrame(bool bSkip) { m_bSkipMTARenderThisFrame = bSkip; } + bool ShouldSkipMTARenderThisFrame() const { return m_bSkipMTARenderThisFrame; } private: void OnDeviceCreate(IDirect3DDevice9* pDevice); @@ -239,11 +250,17 @@ class CGraphics : public CGraphicsInterface, public CSingleton CPrimitiveMaterialBatcher* m_pPrimitiveMaterialBatcher = nullptr; CPrimitive3DBatcher* m_pPrimitive3DBatcherPreGUI = nullptr; CPrimitive3DBatcher* m_pPrimitive3DBatcherPostFX = nullptr; - CPrimitive3DBatcher* m_pPrimitive3DBatcherPostGUI = nullptr; + CPrimitive3DBatcher* m_pPrimitive3DBatcherPostGUI = nullptr; CMaterialPrimitive3DBatcher* m_pMaterialPrimitive3DBatcherPreGUI = nullptr; CMaterialPrimitive3DBatcher* m_pMaterialPrimitive3DBatcherPostFX = nullptr; CMaterialPrimitive3DBatcher* m_pMaterialPrimitive3DBatcherPostGUI = nullptr; CAspectRatioConverter* m_pAspectRatioConverter = nullptr; + bool m_bSkipMTARenderThisFrame = false; + D3DVIEWPORT9 m_prevViewportForMTA = {}; + RECT m_prevScissorForMTA = {}; + DWORD m_prevScissorEnableForMTA = FALSE; + bool m_bRestoreViewportAfterMTA = false; + bool m_bRestoreScissorAfterMTA = false; // Fonts ID3DXFont* m_pDXFonts[NUM_FONTS]; @@ -363,6 +380,7 @@ class CGraphics : public CGraphicsInterface, public CSingleton void RemoveQueueRef(CRenderItem* pRenderItem); void AddQueueRef(IUnknown* pUnknown); void RemoveQueueRef(IUnknown* pUnknown); + void UpdateRenderTargetMatrices(uint uiNewViewportSizeX, uint uiNewViewportSizeY); // Drawing types struct ID3DXLine* m_pLineInterface = nullptr; @@ -370,8 +388,8 @@ class CGraphics : public CGraphicsInterface, public CSingleton enum EMTARenderZone { MTA_RZONE_NONE, - MTA_RZONE_MAIN, // MTA rendering inside known areas. - MTA_RZONE_OUTSIDE, // MTA rendering outside known areas. i.e. During a keypress or GTA callback + MTA_RZONE_MAIN, // MTA rendering inside known areas. + MTA_RZONE_OUTSIDE, // MTA rendering outside known areas. i.e. During a keypress or GTA callback }; EMTARenderZone m_MTARenderZone; @@ -390,4 +408,13 @@ class CGraphics : public CGraphicsInterface, public CSingleton CElapsedTime m_ProgressAnimTimer; uint m_uiProgressAnimFrame; std::map m_CustomScaleFontMap; + bool m_bPendingViewportRefresh = false; + uint m_uiPendingViewportRefreshTries = 0; + uint m_uiViewportRefreshSerial = 0; + uint m_uiViewportLastAppliedSerial = 0; + bool m_bPendingBackbufferOverrideAttempted = false; + bool m_bForceFullViewportInMTA = false; + uint m_uiForceViewportWidth = 0; + uint m_uiForceViewportHeight = 0; + bool m_bForceFullScissorInMTA = false; }; diff --git a/Client/core/Graphics/CLine3DBatcher.cpp b/Client/core/Graphics/CLine3DBatcher.cpp index 6fbc53102b2..afff389b765 100644 --- a/Client/core/Graphics/CLine3DBatcher.cpp +++ b/Client/core/Graphics/CLine3DBatcher.cpp @@ -11,6 +11,7 @@ #include #include "CLine3DBatcher.h" +#include "DXHook/CProxyDirect3DDevice9.h" //////////////////////////////////////////////////////////////// // diff --git a/Client/core/Graphics/CLine3DBatcher.h b/Client/core/Graphics/CLine3DBatcher.h index 6320ab57331..abd21de68b8 100644 --- a/Client/core/Graphics/CLine3DBatcher.h +++ b/Client/core/Graphics/CLine3DBatcher.h @@ -16,12 +16,12 @@ struct SPDVertex DWORD color; }; -#define WRITE_PD_VERTEX(buf,fX,fY,fZ,dwColor) \ - buf->x = fX; \ - buf->y = fY; \ - buf->z = fZ; \ - buf->color = dwColor; \ - buf++; +#define WRITE_PD_VERTEX(buf, fX, fY, fZ, dwColor) \ + buf->x = fX; \ + buf->y = fY; \ + buf->z = fZ; \ + buf->color = dwColor; \ + buf++; struct SLine3DItem { diff --git a/Client/core/Graphics/CMaterialLine3DBatcher.cpp b/Client/core/Graphics/CMaterialLine3DBatcher.cpp index 7f087dbce14..3b81e44c8aa 100644 --- a/Client/core/Graphics/CMaterialLine3DBatcher.cpp +++ b/Client/core/Graphics/CMaterialLine3DBatcher.cpp @@ -12,6 +12,7 @@ #include #include "CTileBatcher.h" #include "CMaterialLine3DBatcher.h" +#include "DXHook/CProxyDirect3DDevice9.h" SMaterialLine3DItem* CMaterialLine3DBatcher::ms_pLines = NULL; @@ -36,6 +37,12 @@ CMaterialLine3DBatcher::CMaterialLine3DBatcher(bool bPreGUI) //////////////////////////////////////////////////////////////// CMaterialLine3DBatcher::~CMaterialLine3DBatcher() { + for (SMaterialLine3DItem& item : m_LineList) + { + if (item.pMaterial) + item.pMaterial->Release(); + } + m_LineList.clear(); } //////////////////////////////////////////////////////////////// @@ -271,8 +278,22 @@ void CMaterialLine3DBatcher::DrawBatch(const CVector& vecCameraPos, uint* pBatch if (CTextureItem* pTextureItem = DynamicCast(pMaterial)) { // Draw using texture - m_pDevice->SetTexture(0, pTextureItem->m_pD3DTexture); - m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); + bool bDrawTexture = true; + if (CRenderTargetItem* pRenderTarget = DynamicCast(pTextureItem)) + { + if (!pRenderTarget->TryEnsureValid()) + bDrawTexture = false; + } + else if (CScreenSourceItem* pScreenSource = DynamicCast(pTextureItem)) + { + if (!pScreenSource->TryEnsureValid()) + bDrawTexture = false; + } + if (bDrawTexture && pTextureItem->m_pD3DTexture) + { + m_pDevice->SetTexture(0, pTextureItem->m_pD3DTexture); + m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); + } } else if (CShaderInstance* pShaderInstance = DynamicCast(pMaterial)) { @@ -287,7 +308,7 @@ void CMaterialLine3DBatcher::DrawBatch(const CVector& vecCameraPos, uint* pBatch pShaderInstance->m_pEffectWrap->ApplyMappedHandles(); // Do shader passes - DWORD dwFlags = D3DXFX_DONOTSAVESHADERSTATE; // D3DXFX_DONOTSAVE(SHADER|SAMPLER)STATE + DWORD dwFlags = D3DXFX_DONOTSAVESHADERSTATE; // D3DXFX_DONOTSAVE(SHADER|SAMPLER)STATE uint uiNumPasses = 0; pShaderInstance->m_pEffectWrap->Begin(&uiNumPasses, dwFlags); diff --git a/Client/core/Graphics/CMaterialLine3DBatcher.h b/Client/core/Graphics/CMaterialLine3DBatcher.h index 8c3f1766c1e..1cce586df94 100644 --- a/Client/core/Graphics/CMaterialLine3DBatcher.h +++ b/Client/core/Graphics/CMaterialLine3DBatcher.h @@ -48,6 +48,6 @@ class CMaterialLine3DBatcher bool m_bPreGUI; IDirect3DDevice9* m_pDevice; std::vector m_LineList; - static SMaterialLine3DItem* ms_pLines; // Used in sort callback + static SMaterialLine3DItem* ms_pLines; // Used in sort callback ETextureAddress m_CurrentTextureAddress; }; diff --git a/Client/core/Graphics/CMaterialPrimitive3DBatcher.cpp b/Client/core/Graphics/CMaterialPrimitive3DBatcher.cpp index 0a8172c8b16..441fd29cd32 100644 --- a/Client/core/Graphics/CMaterialPrimitive3DBatcher.cpp +++ b/Client/core/Graphics/CMaterialPrimitive3DBatcher.cpp @@ -11,6 +11,7 @@ *****************************************************************************/ #include #include "CMaterialPrimitive3DBatcher.h" +#include "DXHook/CProxyDirect3DDevice9.h" //////////////////////////////////////////////////////////////// // // CMaterialPrimitive3DBatcher::CMaterialPrimitive3DBatcher @@ -21,6 +22,11 @@ CMaterialPrimitive3DBatcher::CMaterialPrimitive3DBatcher(bool bPreGUI, CGraphics* pGraphics) : m_bPreGUI(bPreGUI), m_pGraphics(pGraphics) { } + +CMaterialPrimitive3DBatcher::~CMaterialPrimitive3DBatcher() +{ + ClearQueue(); +} //////////////////////////////////////////////////////////////// // // CMaterialPrimitive3DBatcher::OnDeviceCreate @@ -118,6 +124,20 @@ void CMaterialPrimitive3DBatcher::Flush() if (CTextureItem* pTextureItem = DynamicCast(pMaterial)) { + if (CRenderTargetItem* pRenderTarget = DynamicCast(pTextureItem)) + { + if (!pRenderTarget->TryEnsureValid()) + continue; + } + else if (CScreenSourceItem* pScreenSource = DynamicCast(pTextureItem)) + { + if (!pScreenSource->TryEnsureValid()) + continue; + } + + if (!pTextureItem->m_pD3DTexture) + continue; + m_pDevice->SetTexture(0, pTextureItem->m_pD3DTexture); DrawPrimitive(primitive.eType, primitive.pVecVertices->size(), pVertexStreamZeroData, uiVertexStreamZeroStride); } @@ -158,6 +178,7 @@ void CMaterialPrimitive3DBatcher::Flush() } pLastMaterial = pMaterial; pMaterial->Release(); + primitive.pMaterial = nullptr; } // Clean up @@ -175,7 +196,9 @@ void CMaterialPrimitive3DBatcher::ClearQueue() // Clean up for (auto& primitive : m_primitiveList) { + SAFE_RELEASE(primitive.pMaterial); delete primitive.pVecVertices; + primitive.pVecVertices = nullptr; } m_primitiveList.clear(); diff --git a/Client/core/Graphics/CMaterialPrimitive3DBatcher.h b/Client/core/Graphics/CMaterialPrimitive3DBatcher.h index a8bc66efde5..a98031e7790 100644 --- a/Client/core/Graphics/CMaterialPrimitive3DBatcher.h +++ b/Client/core/Graphics/CMaterialPrimitive3DBatcher.h @@ -26,6 +26,7 @@ class CMaterialPrimitive3DBatcher { public: CMaterialPrimitive3DBatcher(bool bPreGUI, CGraphics* pGraphics); + ~CMaterialPrimitive3DBatcher(); void OnDeviceCreate(IDirect3DDevice9* pDevice, float fViewportSizeX, float fViewportSizeY); void Flush(); void AddPrimitive(D3DPRIMITIVETYPE eType, CMaterialItem* pMaterial, std::vector* pVecVertices); diff --git a/Client/core/Graphics/CPixelsManager.cpp b/Client/core/Graphics/CPixelsManager.cpp index b1d11f6e6c2..7eeb77007c3 100644 --- a/Client/core/Graphics/CPixelsManager.cpp +++ b/Client/core/Graphics/CPixelsManager.cpp @@ -11,6 +11,9 @@ #include "StdInc.h" #include "CFileFormat.h" #include "CPixelsManager.h" +#include "DXHook/CProxyDirect3DDevice9.h" + +extern CCore* g_pCore; /////////////////////////////////////////////////////////////// // Object creation @@ -629,7 +632,13 @@ bool CPixelsManager::GetPixelsSize(const CPixels& pixels, uint& uiOutWidth, uint } else if (format == EPixelsFormat::JPEG) { - return JpegGetDimensions(pixels.GetData(), pixels.GetSize(), uiOutWidth, uiOutHeight); + std::string strError; + if (JpegGetDimensions(pixels.GetData(), pixels.GetSize(), uiOutWidth, uiOutHeight, &strError)) + return true; + + if (!strError.empty() && g_pCore) + g_pCore->DebugEchoColor(("JPEG error: " + strError).c_str(), 255, 0, 0); + return false; } return false; @@ -693,21 +702,21 @@ bool CPixelsManager::IsPixels(const CPixels& pixels) //////////////////////////////////////////////////////////////// bool CPixelsManager::SetPlainDimensions(CPixels& pixels, uint uiWidth, uint uiHeight) { - uint uiDataSize = pixels.GetSize(); - const char* pData = pixels.GetData(); + uint uiDataSize = pixels.GetSize(); + char* pData = pixels.GetData(); - uint ReqSize = uiWidth * uiHeight * 4 + SIZEOF_PLAIN_TAIL; + if (uiWidth > 0xFFFF || uiHeight > 0xFFFF) + return false; - if (ReqSize == uiDataSize) - { - // Fixup plain format tail - WORD* pPlainTail = (WORD*)(pData + uiDataSize - SIZEOF_PLAIN_TAIL); - pPlainTail[0] = uiWidth; - pPlainTail[1] = uiHeight; - return true; - } + const uint64_t reqSize64 = static_cast(uiWidth) * static_cast(uiHeight) * 4ULL + SIZEOF_PLAIN_TAIL; + if (reqSize64 != uiDataSize) + return false; - return false; + // Fixup plain format tail + auto* pPlainTail = reinterpret_cast(pData + uiDataSize - SIZEOF_PLAIN_TAIL); + pPlainTail[0] = static_cast(uiWidth); + pPlainTail[1] = static_cast(uiHeight); + return true; } //////////////////////////////////////////////////////////////// @@ -765,7 +774,15 @@ bool CPixelsManager::ChangePixelsFormat(const CPixels& oldPixels, CPixels& newPi return false; if (newFormat == EPixelsFormat::JPEG) - return JpegEncode(uiWidth, uiHeight, uiQuality, oldPixels.GetData(), oldPixels.GetSize() - 4, newPixels.buffer); + { + std::string strError; + if (JpegEncode(uiWidth, uiHeight, uiQuality, oldPixels.GetData(), oldPixels.GetSize() - 4, newPixels.buffer, &strError)) + return true; + + if (!strError.empty() && g_pCore) + g_pCore->DebugEchoColor(("JPEG encode error: " + strError).c_str(), 255, 0, 0); + return false; + } else if (newFormat == EPixelsFormat::PNG) return PngEncode(uiWidth, uiHeight, oldPixels.GetData(), oldPixels.GetSize() - 4, newPixels.buffer); } @@ -774,12 +791,17 @@ bool CPixelsManager::ChangePixelsFormat(const CPixels& oldPixels, CPixels& newPi // Decode if (oldFormat == EPixelsFormat::JPEG) { - uint uiWidth, uiHeight; - if (JpegDecode(oldPixels.GetData(), oldPixels.GetSize(), &newPixels.buffer, uiWidth, uiHeight)) + uint uiWidth, uiHeight; + std::string strError; + if (JpegDecode(oldPixels.GetData(), oldPixels.GetSize(), &newPixels.buffer, uiWidth, uiHeight, &strError)) { newPixels.buffer.SetSize(uiWidth * uiHeight * 4 + SIZEOF_PLAIN_TAIL); return SetPlainDimensions(newPixels, uiWidth, uiHeight); } + + if (!strError.empty() && g_pCore) + g_pCore->DebugEchoColor(("JPEG decode error: " + strError).c_str(), 255, 0, 0); + return false; } else if (oldFormat == EPixelsFormat::PNG) { diff --git a/Client/core/Graphics/CPixelsManager.h b/Client/core/Graphics/CPixelsManager.h index 088472a433c..fb80c65e948 100644 --- a/Client/core/Graphics/CPixelsManager.h +++ b/Client/core/Graphics/CPixelsManager.h @@ -9,7 +9,7 @@ *****************************************************************************/ #define XRGB_BYTES_PER_PIXEL (4) -#define SIZEOF_PLAIN_TAIL (4) +#define SIZEOF_PLAIN_TAIL (4) // // Scope release and zeroing of pointer diff --git a/Client/core/Graphics/CPixelsManager_VolumeTexture.cpp b/Client/core/Graphics/CPixelsManager_VolumeTexture.cpp index ca862470d58..4511ec30ffc 100644 --- a/Client/core/Graphics/CPixelsManager_VolumeTexture.cpp +++ b/Client/core/Graphics/CPixelsManager_VolumeTexture.cpp @@ -400,7 +400,7 @@ bool CPixelsManager::D3DXGetVolumePixels(IDirect3DVolumeTexture9* pD3DVolumeText bool bNeedToConvert = dxFileFormat == D3DXIFF_DDS; if (bNeedToConvert && Desc.Format == dxFormat && !bMipMaps) - bNeedToConvert = false; // No need to convert DDS if compression is the same and no mipmaps required + bNeedToConvert = false; // No need to convert DDS if compression is the same and no mipmaps required ID3DXBuffer* dxBuffer; CAutoReleaseMe Thanks2(dxBuffer); diff --git a/Client/core/Graphics/CPrimitive3DBatcher.cpp b/Client/core/Graphics/CPrimitive3DBatcher.cpp index bdd496fd9a0..fdc9cc89df9 100644 --- a/Client/core/Graphics/CPrimitive3DBatcher.cpp +++ b/Client/core/Graphics/CPrimitive3DBatcher.cpp @@ -11,6 +11,7 @@ *****************************************************************************/ #include #include "CPrimitive3DBatcher.h" +#include "DXHook/CProxyDirect3DDevice9.h" //////////////////////////////////////////////////////////////// // // CPrimitive3DBatcher::CPrimitive3DBatcher @@ -21,6 +22,11 @@ CPrimitive3DBatcher::CPrimitive3DBatcher(bool bPreGUI) : m_bPreGUI(bPreGUI) { } + +CPrimitive3DBatcher::~CPrimitive3DBatcher() +{ + ClearQueue(); +} //////////////////////////////////////////////////////////////// // // CPrimitive3DBatcher::OnDeviceCreate @@ -97,13 +103,8 @@ void CPrimitive3DBatcher::Flush() DrawPrimitive(primitive.eType, primitive.pVecVertices->size(), &primitive.pVecVertices->at(0), VertexStreamZeroStride); } - // Clean up - for (auto& primitive : m_primitiveList) - { - delete primitive.pVecVertices; - } - - m_primitiveList.clear(); + // Clean up queued primitives now that they are flushed + ClearQueue(); if (g_pDeviceState->AdapterState.bRequiresClipping) m_pDevice->SetRenderState(D3DRS_CLIPPING, FALSE); @@ -156,3 +157,14 @@ void CPrimitive3DBatcher::AddPrimitive(D3DPRIMITIVETYPE eType, std::vector* pVecVertices); void DrawPrimitive(D3DPRIMITIVETYPE eType, size_t iCollectionSize, const void* pDataAddr, size_t uiVertexStride); bool HasItems() const { return !m_primitiveList.empty(); } + void ClearQueue(); protected: bool m_bPreGUI; diff --git a/Client/core/Graphics/CPrimitiveBatcher.cpp b/Client/core/Graphics/CPrimitiveBatcher.cpp index 9ccac7c922f..972f6748005 100644 --- a/Client/core/Graphics/CPrimitiveBatcher.cpp +++ b/Client/core/Graphics/CPrimitiveBatcher.cpp @@ -10,6 +10,7 @@ *****************************************************************************/ #include #include "CPrimitiveBatcher.h" +#include "DXHook/CProxyDirect3DDevice9.h" //////////////////////////////////////////////////////////////// // // CPrimitiveBatcher::CPrimitiveBatcher @@ -30,6 +31,7 @@ CPrimitiveBatcher::CPrimitiveBatcher() //////////////////////////////////////////////////////////////// CPrimitiveBatcher::~CPrimitiveBatcher() { + ClearQueue(); } //////////////////////////////////////////////////////////////// // @@ -41,6 +43,7 @@ CPrimitiveBatcher::~CPrimitiveBatcher() void CPrimitiveBatcher::OnDeviceCreate(IDirect3DDevice9* pDevice, float fViewportSizeX, float fViewportSizeY) { m_pDevice = pDevice; + // Cache matrices UpdateMatrices(fViewportSizeX, fViewportSizeY); } @@ -195,6 +198,7 @@ void CPrimitiveBatcher::ClearQueue() for (auto& primitive : m_primitiveList) { delete primitive.pVecVertices; + primitive.pVecVertices = nullptr; } size_t prevSize = m_primitiveList.size(); m_primitiveList.clear(); diff --git a/Client/core/Graphics/CPrimitiveMaterialBatcher.cpp b/Client/core/Graphics/CPrimitiveMaterialBatcher.cpp index a5b73abd2ce..b6862f1b5fc 100644 --- a/Client/core/Graphics/CPrimitiveMaterialBatcher.cpp +++ b/Client/core/Graphics/CPrimitiveMaterialBatcher.cpp @@ -10,6 +10,7 @@ *****************************************************************************/ #include #include "CPrimitiveMaterialBatcher.h" +#include "DXHook/CProxyDirect3DDevice9.h" //////////////////////////////////////////////////////////////// // // CPrimitiveMaterialBatcher::CPrimitiveMaterialBatcher @@ -30,6 +31,7 @@ CPrimitiveMaterialBatcher::CPrimitiveMaterialBatcher(CGraphics* graphics) //////////////////////////////////////////////////////////////// CPrimitiveMaterialBatcher::~CPrimitiveMaterialBatcher() { + ClearQueue(); } //////////////////////////////////////////////////////////////// // @@ -41,6 +43,7 @@ CPrimitiveMaterialBatcher::~CPrimitiveMaterialBatcher() void CPrimitiveMaterialBatcher::OnDeviceCreate(IDirect3DDevice9* pDevice, float fViewportSizeX, float fViewportSizeY) { m_pDevice = pDevice; + // Cache matrices UpdateMatrices(fViewportSizeX, fViewportSizeY); } @@ -159,6 +162,20 @@ void CPrimitiveMaterialBatcher::Flush() if (CTextureItem* pTextureItem = DynamicCast(pMaterial)) { // Draw using texture + if (CRenderTargetItem* pRenderTarget = DynamicCast(pTextureItem)) + { + if (!pRenderTarget->TryEnsureValid()) + continue; + } + else if (CScreenSourceItem* pScreenSource = DynamicCast(pTextureItem)) + { + if (!pScreenSource->TryEnsureValid()) + continue; + } + + if (!pTextureItem->m_pD3DTexture) + continue; + if (pMaterial != pLastMaterial) { m_pDevice->SetTexture(0, pTextureItem->m_pD3DTexture); @@ -203,6 +220,7 @@ void CPrimitiveMaterialBatcher::Flush() } pLastMaterial = pMaterial; m_pGraphics->RemoveQueueRef(pMaterial); + primitive.pMaterial = nullptr; } // Clean up @@ -257,7 +275,13 @@ void CPrimitiveMaterialBatcher::ClearQueue() // Clean up for (auto& primitive : m_primitiveList) { + if (primitive.pMaterial) + { + m_pGraphics->RemoveQueueRef(primitive.pMaterial); + primitive.pMaterial = nullptr; + } delete primitive.pVecVertices; + primitive.pVecVertices = nullptr; } size_t prevSize = m_primitiveList.size(); @@ -273,5 +297,7 @@ void CPrimitiveMaterialBatcher::ClearQueue() //////////////////////////////////////////////////////////////// void CPrimitiveMaterialBatcher::AddPrimitive(D3DPRIMITIVETYPE eType, CMaterialItem* pMaterial, std::vector* pVecVertices) { + if (pMaterial) + m_pGraphics->AddQueueRef(pMaterial); m_primitiveList.push_back({eType, pMaterial, pVecVertices}); } diff --git a/Client/core/Graphics/CRenderItem.EffectCloner.cpp b/Client/core/Graphics/CRenderItem.EffectCloner.cpp index f2817f929a6..449e100f9a6 100644 --- a/Client/core/Graphics/CRenderItem.EffectCloner.cpp +++ b/Client/core/Graphics/CRenderItem.EffectCloner.cpp @@ -24,6 +24,21 @@ CEffectCloner::CEffectCloner(CRenderItemManager* pManager) m_pManager = pManager; } +CEffectCloner::~CEffectCloner() +{ + for (auto& entry : m_ValidMap) + { + SAFE_RELEASE(entry.second); + } + m_ValidMap.clear(); + + for (CEffectTemplate* pTemplate : m_OldList) + { + SAFE_RELEASE(pTemplate); + } + m_OldList.clear(); +} + //////////////////////////////////////////////////////////////// // // CEffectCloner::CreateD3DEffect @@ -83,9 +98,9 @@ CEffectWrap* CEffectCloner::CreateD3DEffect(const SString& strFile, const SStrin if (!strReport.empty()) { - strReport += SString("[effects cur:%d created:%d dest:%d]", g_pDeviceState->MemoryState.Effect.iCurrentCount, - g_pDeviceState->MemoryState.Effect.iCreatedCount, g_pDeviceState->MemoryState.Effect.iDestroyedCount); - AddReportLog(7544, SString("NewEffectTemplate (call:%d) %s %s", uiCallCount, *strReport, *strFile)); + strReport += SString("[effects cur:%d created:%d dest:%d]", g_StaticMemoryState.Effect.iCurrentCount, g_StaticMemoryState.Effect.iCreatedCount, + g_StaticMemoryState.Effect.iDestroyedCount); + // AddReportLog(7544, SString("NewEffectTemplate (call:%d) %s %s", uiCallCount, *strReport, *strFile)); } if (!pEffectTemplate) return NULL; @@ -156,7 +171,7 @@ void CEffectCloner::MaybeTidyUp(bool bForceDrasticMeasures) int iTicks = static_cast((1 - fTicksAlpha * fTicksAlpha) * 30 * 60 * 1000) + 1000; #ifdef MTA_DEBUG - iTicks /= 60; // Mins to seconds for debug + iTicks /= 60; // Mins to seconds for debug #endif // Valid Effect not used for a little while can go diff --git a/Client/core/Graphics/CRenderItem.EffectCloner.h b/Client/core/Graphics/CRenderItem.EffectCloner.h index 3cbc486089b..8f8ad45df1b 100644 --- a/Client/core/Graphics/CRenderItem.EffectCloner.h +++ b/Client/core/Graphics/CRenderItem.EffectCloner.h @@ -46,6 +46,7 @@ class CEffectCloner { public: CEffectCloner(CRenderItemManager* pManager); + ~CEffectCloner(); void DoPulse(); CEffectWrap* CreateD3DEffect(const SString& strFile, const SString& strRootPath, bool bIsRawData, SString& strOutStatus, bool bDebug, const EffectMacroList& macros); @@ -56,6 +57,6 @@ class CEffectCloner CElapsedTime m_TidyupTimer; CRenderItemManager* m_pManager; - std::unordered_map m_ValidMap; // Active and files not changed since first created - std::vector m_OldList; // Active but files changed since first created + std::unordered_map m_ValidMap; // Active and files not changed since first created + std::vector m_OldList; // Active but files changed since first created }; diff --git a/Client/core/Graphics/CRenderItem.EffectParameters.cpp b/Client/core/Graphics/CRenderItem.EffectParameters.cpp index 3503cc63d81..de5558258c9 100644 --- a/Client/core/Graphics/CRenderItem.EffectParameters.cpp +++ b/Client/core/Graphics/CRenderItem.EffectParameters.cpp @@ -10,6 +10,12 @@ #include "StdInc.h" #include "CRenderItem.EffectParameters.h" +#include + +#include +#include +#include + IMPLEMENT_ENUM_BEGIN(EStateGroup) ADD_ENUM(STATE_GROUP_RENDER, "renderState") ADD_ENUM(STATE_GROUP_STAGE, "stageState") @@ -25,10 +31,10 @@ IMPLEMENT_ENUM_END("state-group") const STypeMapping TypeMappingList[] = { {TYPE_INT, D3DXPC_SCALAR, D3DXPT_INT, RegMap::Int2Int, 1}, - {TYPE_D3DCOLOR, D3DXPC_SCALAR, D3DXPT_INT, RegMap::Int2Int, 1}, // Can be read as float4 or DWORD color + {TYPE_D3DCOLOR, D3DXPC_SCALAR, D3DXPT_INT, RegMap::Int2Int, 1}, // Can be read as float4 or DWORD color {TYPE_D3DCOLOR, D3DXPC_VECTOR, D3DXPT_FLOAT, RegMap::Int2Color, 4}, - {TYPE_IFLOAT, D3DXPC_SCALAR, D3DXPT_FLOAT, RegMap::Int2Float, 1}, // Can be read as float or as int on float memory - {TYPE_IFLOAT, D3DXPC_SCALAR, D3DXPT_INT, RegMap::Int2Int, 1}, // Can be read as float or as int on float memory + {TYPE_IFLOAT, D3DXPC_SCALAR, D3DXPT_FLOAT, RegMap::Int2Float, 1}, // Can be read as float or as int on float memory + {TYPE_IFLOAT, D3DXPC_SCALAR, D3DXPT_INT, RegMap::Int2Int, 1}, // Can be read as float or as int on float memory {TYPE_FLOAT, D3DXPC_SCALAR, D3DXPT_FLOAT, RegMap::Float2Float, 1}, {TYPE_D3DCOLORVALUE, D3DXPC_VECTOR, D3DXPT_FLOAT, RegMap::Color2Color, 4}, {TYPE_VECTOR3, D3DXPC_VECTOR, D3DXPT_FLOAT, RegMap::Vector2Vector, 3}, @@ -44,191 +50,190 @@ const STypeMapping TypeMappingList[] = { // Big list of D3D registers // -#define ADD_REGISTER(type,name) \ - {offsetof(USING_STRUCT, name), USING_LIST, #name, type} +#define ADD_REGISTER(type, name) {offsetof(USING_STRUCT, name), USING_LIST, #name, type} const SRegisterInfo BigRegisterInfoList[] = { #define USING_STRUCT CProxyDirect3DDevice9::SD3DRenderState -#define USING_LIST "RenderState" - ADD_REGISTER(TYPE_INT, ZENABLE), // = 7, /* D3DZBUFFERTYPE (or TRUE/FALSE for legacy) */ - ADD_REGISTER(TYPE_INT, FILLMODE), // = 8, /* D3DFILLMODE */ - ADD_REGISTER(TYPE_INT, SHADEMODE), // = 9, /* D3DSHADEMODE */ - ADD_REGISTER(TYPE_INT, ZWRITEENABLE), // = 14, /* TRUE to enable z writes */ - ADD_REGISTER(TYPE_INT, ALPHATESTENABLE), // = 15, /* TRUE to enable alpha tests */ - ADD_REGISTER(TYPE_INT, LASTPIXEL), // = 16, /* TRUE for last-pixel on lines */ - ADD_REGISTER(TYPE_INT, SRCBLEND), // = 19, /* D3DBLEND */ - ADD_REGISTER(TYPE_INT, DESTBLEND), // = 20, /* D3DBLEND */ - ADD_REGISTER(TYPE_INT, CULLMODE), // = 22, /* D3DCULL */ - ADD_REGISTER(TYPE_INT, ZFUNC), // = 23, /* D3DCMPFUNC */ - ADD_REGISTER(TYPE_INT, ALPHAREF), // = 24, /* D3DFIXED */ - ADD_REGISTER(TYPE_INT, ALPHAFUNC), // = 25, /* D3DCMPFUNC */ - ADD_REGISTER(TYPE_INT, DITHERENABLE), // = 26, /* TRUE to enable dithering */ - ADD_REGISTER(TYPE_INT, ALPHABLENDENABLE), // = 27, /* TRUE to enable alpha blending */ - ADD_REGISTER(TYPE_INT, FOGENABLE), // = 28, /* TRUE to enable fog blending */ - ADD_REGISTER(TYPE_INT, SPECULARENABLE), // = 29, /* TRUE to enable specular */ - ADD_REGISTER(TYPE_D3DCOLOR, FOGCOLOR), // = 34, /* D3DCOLOR */ - ADD_REGISTER(TYPE_INT, FOGTABLEMODE), // = 35, /* D3DFOGMODE */ - ADD_REGISTER(TYPE_IFLOAT, FOGSTART), // = 36, /* Fog start (for both vertex and pixel fog) */ - ADD_REGISTER(TYPE_IFLOAT, FOGEND), // = 37, /* Fog end */ - ADD_REGISTER(TYPE_IFLOAT, FOGDENSITY), // = 38, /* Fog density */ - ADD_REGISTER(TYPE_INT, RANGEFOGENABLE), // = 48, /* Enables range-based fog */ - ADD_REGISTER(TYPE_INT, STENCILENABLE), // = 52, /* BOOL enable/disable stenciling */ - ADD_REGISTER(TYPE_INT, STENCILFAIL), // = 53, /* D3DSTENCILOP to do if stencil test fails */ - ADD_REGISTER(TYPE_INT, STENCILZFAIL), // = 54, /* D3DSTENCILOP to do if stencil test passes and Z test fails */ - ADD_REGISTER(TYPE_INT, STENCILPASS), // = 55, /* D3DSTENCILOP to do if both stencil and Z tests pass */ - ADD_REGISTER(TYPE_INT, STENCILFUNC), // = 56, /* D3DCMPFUNC fn. */ - ADD_REGISTER(TYPE_INT, STENCILREF), // = 57, /* Reference value used in stencil test */ - ADD_REGISTER(TYPE_INT, STENCILMASK), // = 58, /* Mask value used in stencil test */ - ADD_REGISTER(TYPE_INT, STENCILWRITEMASK), // = 59, /* Write mask applied to values written to stencil buffer */ - ADD_REGISTER(TYPE_D3DCOLOR, TEXTUREFACTOR), // = 60, /* D3DCOLOR used for multi-texture blend */ - ADD_REGISTER(TYPE_INT, WRAP0), // = 128, /* wrap for 1st texture coord. set */ - ADD_REGISTER(TYPE_INT, WRAP1), // = 129, /* wrap for 2nd texture coord. set */ - ADD_REGISTER(TYPE_INT, WRAP2), // = 130, /* wrap for 3rd texture coord. set */ - ADD_REGISTER(TYPE_INT, WRAP3), // = 131, /* wrap for 4th texture coord. set */ - ADD_REGISTER(TYPE_INT, WRAP4), // = 132, /* wrap for 5th texture coord. set */ - ADD_REGISTER(TYPE_INT, WRAP5), // = 133, /* wrap for 6th texture coord. set */ - ADD_REGISTER(TYPE_INT, WRAP6), // = 134, /* wrap for 7th texture coord. set */ - ADD_REGISTER(TYPE_INT, WRAP7), // = 135, /* wrap for 8th texture coord. set */ - ADD_REGISTER(TYPE_INT, CLIPPING), // = 136, - ADD_REGISTER(TYPE_INT, LIGHTING), // = 137, - ADD_REGISTER(TYPE_D3DCOLOR, AMBIENT), // = 139, - ADD_REGISTER(TYPE_INT, FOGVERTEXMODE), // = 140, - ADD_REGISTER(TYPE_INT, COLORVERTEX), // = 141, - ADD_REGISTER(TYPE_INT, LOCALVIEWER), // = 142, - ADD_REGISTER(TYPE_INT, NORMALIZENORMALS), // = 143, - ADD_REGISTER(TYPE_INT, DIFFUSEMATERIALSOURCE), // = 145, - ADD_REGISTER(TYPE_INT, SPECULARMATERIALSOURCE), // = 146, - ADD_REGISTER(TYPE_INT, AMBIENTMATERIALSOURCE), // = 147, - ADD_REGISTER(TYPE_INT, EMISSIVEMATERIALSOURCE), // = 148, - ADD_REGISTER(TYPE_INT, VERTEXBLEND), // = 151, - ADD_REGISTER(TYPE_INT, CLIPPLANEENABLE), // = 152, - ADD_REGISTER(TYPE_IFLOAT, POINTSIZE), // = 154, /* float point size */ - ADD_REGISTER(TYPE_IFLOAT, POINTSIZE_MIN), // = 155, /* float point size min threshold */ - ADD_REGISTER(TYPE_INT, POINTSPRITEENABLE), // = 156, /* BOOL point texture coord control */ - ADD_REGISTER(TYPE_INT, POINTSCALEENABLE), // = 157, /* BOOL point size scale enable */ - ADD_REGISTER(TYPE_IFLOAT, POINTSCALE_A), // = 158, /* float point attenuation A value */ - ADD_REGISTER(TYPE_IFLOAT, POINTSCALE_B), // = 159, /* float point attenuation B value */ - ADD_REGISTER(TYPE_IFLOAT, POINTSCALE_C), // = 160, /* float point attenuation C value */ - ADD_REGISTER(TYPE_INT, MULTISAMPLEANTIALIAS), // = 161, // BOOL - set to do FSAA with multisample buffer - ADD_REGISTER(TYPE_INT, MULTISAMPLEMASK), // = 162, // DWORD - ) //per-sample enable/disable - ADD_REGISTER(TYPE_INT, PATCHEDGESTYLE), // = 163, // Sets whether patch edges will use float style tessellation - ADD_REGISTER(TYPE_INT, DEBUGMONITORTOKEN), // = 165, // DEBUG ONLY - token to debug monitor - ADD_REGISTER(TYPE_IFLOAT, POINTSIZE_MAX), // = 166, /* float point size max threshold */ - ADD_REGISTER(TYPE_INT, INDEXEDVERTEXBLENDENABLE), // = 167, - ADD_REGISTER(TYPE_INT, COLORWRITEENABLE), // = 168, // per-channel write enable - ADD_REGISTER(TYPE_IFLOAT, TWEENFACTOR), // = 170, // float tween factor - ADD_REGISTER(TYPE_INT, BLENDOP), // = 171, // D3DBLENDOP setting - ADD_REGISTER(TYPE_INT, POSITIONDEGREE), // = 172, // NPatch position interpolation degree. D3DDEGREE_LINEAR or D3DDEGREE_CUBIC (default) - ADD_REGISTER(TYPE_INT, NORMALDEGREE), // = 173, aa NPatch normal interpolation degree. D3DDEGREE_LINEAR (default) or D3DDEGREE_QUADRATIC - ADD_REGISTER(TYPE_INT, SCISSORTESTENABLE), // = 174 - ADD_REGISTER(TYPE_INT, SLOPESCALEDEPTHBIAS), // = 175, - ADD_REGISTER(TYPE_INT, ANTIALIASEDLINEENABLE), // = 176, - ADD_REGISTER(TYPE_INT, MINTESSELLATIONLEVEL), // = 178, - ADD_REGISTER(TYPE_INT, MAXTESSELLATIONLEVEL), // = 179, - ADD_REGISTER(TYPE_INT, ADAPTIVETESS_X), // = 180, - ADD_REGISTER(TYPE_INT, ADAPTIVETESS_Y), // = 181, - ADD_REGISTER(TYPE_INT, ADAPTIVETESS_Z), // = 182, - ADD_REGISTER(TYPE_INT, ADAPTIVETESS_W), // = 183, - ADD_REGISTER(TYPE_INT, ENABLEADAPTIVETESSELLATION), // = 184, - ADD_REGISTER(TYPE_INT, TWOSIDEDSTENCILMODE), // = 185, /* BOOL enable/disable 2 sided stenciling */ - ADD_REGISTER(TYPE_INT, CCW_STENCILFAIL), // = 186, /* D3DSTENCILOP to do if ccw stencil test fails */ - ADD_REGISTER(TYPE_INT, CCW_STENCILZFAIL), // = 187, /* D3DSTENCILOP to do if ccw stencil test passes and Z test fails */ - ADD_REGISTER(TYPE_INT, CCW_STENCILPASS), // = 188, /* D3DSTENCILOP to do if both ccw stencil and Z tests pass */ - ADD_REGISTER(TYPE_INT, CCW_STENCILFUNC), // = 189, /* D3DCMPFUNC fn. */ - ADD_REGISTER(TYPE_INT, COLORWRITEENABLE1), // = 190, /* Additional ColorWriteEnables */ - ADD_REGISTER(TYPE_INT, COLORWRITEENABLE2), // = 191, /* Additional ColorWriteEnables */ - ADD_REGISTER(TYPE_INT, COLORWRITEENABLE3), // = 192, /* Additional ColorWriteEnables */ - ADD_REGISTER(TYPE_D3DCOLOR, BLENDFACTOR), // = 193, /* D3DCOLOR used for a constant blend factor during alpha blending*/ - ADD_REGISTER(TYPE_INT, SRGBWRITEENABLE), // = 194, /* Enable rendertarget writes to be DE-linearized to SRGB */ - ADD_REGISTER(TYPE_INT, DEPTHBIAS), // = 195, - ADD_REGISTER(TYPE_INT, WRAP8), // = 198, /* Additional wrap states for vs_3_0+ attributes with D3DDECLUSAGE_TEXCOORD */ - ADD_REGISTER(TYPE_INT, WRAP9), // = 199, - ADD_REGISTER(TYPE_INT, WRAP10), // = 200, - ADD_REGISTER(TYPE_INT, WRAP11), // = 201, - ADD_REGISTER(TYPE_INT, WRAP12), // = 202, - ADD_REGISTER(TYPE_INT, WRAP13), // = 203, - ADD_REGISTER(TYPE_INT, WRAP14), // = 204, - ADD_REGISTER(TYPE_INT, WRAP15), // = 205, - ADD_REGISTER(TYPE_INT, SEPARATEALPHABLENDENABLE), // = 206, /* TRUE to enable a separate blending function for the alpha channel */ - ADD_REGISTER(TYPE_INT, SRCBLENDALPHA), // = 207, /* SRC blend factor for the alpha channel when DWORD SEPARATEDESTALPHAENABLE ) */ - ADD_REGISTER(TYPE_INT, DESTBLENDALPHA), // = 208, /* DST blend factor for the alpha channel when DWORD SEPARATEDESTALPHAENABLE ) */ - ADD_REGISTER(TYPE_INT, BLENDOPALPHA), // = 209, /* Blending operation for the alpha channel when DWORD SEPARATEDESTALPHAENABLE ) */ -#undef USING_STRUCT -#undef USING_LIST +#define USING_LIST "RenderState" + ADD_REGISTER(TYPE_INT, ZENABLE), // = 7, /* D3DZBUFFERTYPE (or TRUE/FALSE for legacy) */ + ADD_REGISTER(TYPE_INT, FILLMODE), // = 8, /* D3DFILLMODE */ + ADD_REGISTER(TYPE_INT, SHADEMODE), // = 9, /* D3DSHADEMODE */ + ADD_REGISTER(TYPE_INT, ZWRITEENABLE), // = 14, /* TRUE to enable z writes */ + ADD_REGISTER(TYPE_INT, ALPHATESTENABLE), // = 15, /* TRUE to enable alpha tests */ + ADD_REGISTER(TYPE_INT, LASTPIXEL), // = 16, /* TRUE for last-pixel on lines */ + ADD_REGISTER(TYPE_INT, SRCBLEND), // = 19, /* D3DBLEND */ + ADD_REGISTER(TYPE_INT, DESTBLEND), // = 20, /* D3DBLEND */ + ADD_REGISTER(TYPE_INT, CULLMODE), // = 22, /* D3DCULL */ + ADD_REGISTER(TYPE_INT, ZFUNC), // = 23, /* D3DCMPFUNC */ + ADD_REGISTER(TYPE_INT, ALPHAREF), // = 24, /* D3DFIXED */ + ADD_REGISTER(TYPE_INT, ALPHAFUNC), // = 25, /* D3DCMPFUNC */ + ADD_REGISTER(TYPE_INT, DITHERENABLE), // = 26, /* TRUE to enable dithering */ + ADD_REGISTER(TYPE_INT, ALPHABLENDENABLE), // = 27, /* TRUE to enable alpha blending */ + ADD_REGISTER(TYPE_INT, FOGENABLE), // = 28, /* TRUE to enable fog blending */ + ADD_REGISTER(TYPE_INT, SPECULARENABLE), // = 29, /* TRUE to enable specular */ + ADD_REGISTER(TYPE_D3DCOLOR, FOGCOLOR), // = 34, /* D3DCOLOR */ + ADD_REGISTER(TYPE_INT, FOGTABLEMODE), // = 35, /* D3DFOGMODE */ + ADD_REGISTER(TYPE_IFLOAT, FOGSTART), // = 36, /* Fog start (for both vertex and pixel fog) */ + ADD_REGISTER(TYPE_IFLOAT, FOGEND), // = 37, /* Fog end */ + ADD_REGISTER(TYPE_IFLOAT, FOGDENSITY), // = 38, /* Fog density */ + ADD_REGISTER(TYPE_INT, RANGEFOGENABLE), // = 48, /* Enables range-based fog */ + ADD_REGISTER(TYPE_INT, STENCILENABLE), // = 52, /* BOOL enable/disable stenciling */ + ADD_REGISTER(TYPE_INT, STENCILFAIL), // = 53, /* D3DSTENCILOP to do if stencil test fails */ + ADD_REGISTER(TYPE_INT, STENCILZFAIL), // = 54, /* D3DSTENCILOP to do if stencil test passes and Z test fails */ + ADD_REGISTER(TYPE_INT, STENCILPASS), // = 55, /* D3DSTENCILOP to do if both stencil and Z tests pass */ + ADD_REGISTER(TYPE_INT, STENCILFUNC), // = 56, /* D3DCMPFUNC fn. */ + ADD_REGISTER(TYPE_INT, STENCILREF), // = 57, /* Reference value used in stencil test */ + ADD_REGISTER(TYPE_INT, STENCILMASK), // = 58, /* Mask value used in stencil test */ + ADD_REGISTER(TYPE_INT, STENCILWRITEMASK), // = 59, /* Write mask applied to values written to stencil buffer */ + ADD_REGISTER(TYPE_D3DCOLOR, TEXTUREFACTOR), // = 60, /* D3DCOLOR used for multi-texture blend */ + ADD_REGISTER(TYPE_INT, WRAP0), // = 128, /* wrap for 1st texture coord. set */ + ADD_REGISTER(TYPE_INT, WRAP1), // = 129, /* wrap for 2nd texture coord. set */ + ADD_REGISTER(TYPE_INT, WRAP2), // = 130, /* wrap for 3rd texture coord. set */ + ADD_REGISTER(TYPE_INT, WRAP3), // = 131, /* wrap for 4th texture coord. set */ + ADD_REGISTER(TYPE_INT, WRAP4), // = 132, /* wrap for 5th texture coord. set */ + ADD_REGISTER(TYPE_INT, WRAP5), // = 133, /* wrap for 6th texture coord. set */ + ADD_REGISTER(TYPE_INT, WRAP6), // = 134, /* wrap for 7th texture coord. set */ + ADD_REGISTER(TYPE_INT, WRAP7), // = 135, /* wrap for 8th texture coord. set */ + ADD_REGISTER(TYPE_INT, CLIPPING), // = 136, + ADD_REGISTER(TYPE_INT, LIGHTING), // = 137, + ADD_REGISTER(TYPE_D3DCOLOR, AMBIENT), // = 139, + ADD_REGISTER(TYPE_INT, FOGVERTEXMODE), // = 140, + ADD_REGISTER(TYPE_INT, COLORVERTEX), // = 141, + ADD_REGISTER(TYPE_INT, LOCALVIEWER), // = 142, + ADD_REGISTER(TYPE_INT, NORMALIZENORMALS), // = 143, + ADD_REGISTER(TYPE_INT, DIFFUSEMATERIALSOURCE), // = 145, + ADD_REGISTER(TYPE_INT, SPECULARMATERIALSOURCE), // = 146, + ADD_REGISTER(TYPE_INT, AMBIENTMATERIALSOURCE), // = 147, + ADD_REGISTER(TYPE_INT, EMISSIVEMATERIALSOURCE), // = 148, + ADD_REGISTER(TYPE_INT, VERTEXBLEND), // = 151, + ADD_REGISTER(TYPE_INT, CLIPPLANEENABLE), // = 152, + ADD_REGISTER(TYPE_IFLOAT, POINTSIZE), // = 154, /* float point size */ + ADD_REGISTER(TYPE_IFLOAT, POINTSIZE_MIN), // = 155, /* float point size min threshold */ + ADD_REGISTER(TYPE_INT, POINTSPRITEENABLE), // = 156, /* BOOL point texture coord control */ + ADD_REGISTER(TYPE_INT, POINTSCALEENABLE), // = 157, /* BOOL point size scale enable */ + ADD_REGISTER(TYPE_IFLOAT, POINTSCALE_A), // = 158, /* float point attenuation A value */ + ADD_REGISTER(TYPE_IFLOAT, POINTSCALE_B), // = 159, /* float point attenuation B value */ + ADD_REGISTER(TYPE_IFLOAT, POINTSCALE_C), // = 160, /* float point attenuation C value */ + ADD_REGISTER(TYPE_INT, MULTISAMPLEANTIALIAS), // = 161, // BOOL - set to do FSAA with multisample buffer + ADD_REGISTER(TYPE_INT, MULTISAMPLEMASK), // = 162, // DWORD - ) //per-sample enable/disable + ADD_REGISTER(TYPE_INT, PATCHEDGESTYLE), // = 163, // Sets whether patch edges will use float style tessellation + ADD_REGISTER(TYPE_INT, DEBUGMONITORTOKEN), // = 165, // DEBUG ONLY - token to debug monitor + ADD_REGISTER(TYPE_IFLOAT, POINTSIZE_MAX), // = 166, /* float point size max threshold */ + ADD_REGISTER(TYPE_INT, INDEXEDVERTEXBLENDENABLE), // = 167, + ADD_REGISTER(TYPE_INT, COLORWRITEENABLE), // = 168, // per-channel write enable + ADD_REGISTER(TYPE_IFLOAT, TWEENFACTOR), // = 170, // float tween factor + ADD_REGISTER(TYPE_INT, BLENDOP), // = 171, // D3DBLENDOP setting + ADD_REGISTER(TYPE_INT, POSITIONDEGREE), // = 172, // NPatch position interpolation degree. D3DDEGREE_LINEAR or D3DDEGREE_CUBIC (default) + ADD_REGISTER(TYPE_INT, NORMALDEGREE), // = 173, aa NPatch normal interpolation degree. D3DDEGREE_LINEAR (default) or D3DDEGREE_QUADRATIC + ADD_REGISTER(TYPE_INT, SCISSORTESTENABLE), // = 174 + ADD_REGISTER(TYPE_INT, SLOPESCALEDEPTHBIAS), // = 175, + ADD_REGISTER(TYPE_INT, ANTIALIASEDLINEENABLE), // = 176, + ADD_REGISTER(TYPE_INT, MINTESSELLATIONLEVEL), // = 178, + ADD_REGISTER(TYPE_INT, MAXTESSELLATIONLEVEL), // = 179, + ADD_REGISTER(TYPE_INT, ADAPTIVETESS_X), // = 180, + ADD_REGISTER(TYPE_INT, ADAPTIVETESS_Y), // = 181, + ADD_REGISTER(TYPE_INT, ADAPTIVETESS_Z), // = 182, + ADD_REGISTER(TYPE_INT, ADAPTIVETESS_W), // = 183, + ADD_REGISTER(TYPE_INT, ENABLEADAPTIVETESSELLATION), // = 184, + ADD_REGISTER(TYPE_INT, TWOSIDEDSTENCILMODE), // = 185, /* BOOL enable/disable 2 sided stenciling */ + ADD_REGISTER(TYPE_INT, CCW_STENCILFAIL), // = 186, /* D3DSTENCILOP to do if ccw stencil test fails */ + ADD_REGISTER(TYPE_INT, CCW_STENCILZFAIL), // = 187, /* D3DSTENCILOP to do if ccw stencil test passes and Z test fails */ + ADD_REGISTER(TYPE_INT, CCW_STENCILPASS), // = 188, /* D3DSTENCILOP to do if both ccw stencil and Z tests pass */ + ADD_REGISTER(TYPE_INT, CCW_STENCILFUNC), // = 189, /* D3DCMPFUNC fn. */ + ADD_REGISTER(TYPE_INT, COLORWRITEENABLE1), // = 190, /* Additional ColorWriteEnables */ + ADD_REGISTER(TYPE_INT, COLORWRITEENABLE2), // = 191, /* Additional ColorWriteEnables */ + ADD_REGISTER(TYPE_INT, COLORWRITEENABLE3), // = 192, /* Additional ColorWriteEnables */ + ADD_REGISTER(TYPE_D3DCOLOR, BLENDFACTOR), // = 193, /* D3DCOLOR used for a constant blend factor during alpha blending*/ + ADD_REGISTER(TYPE_INT, SRGBWRITEENABLE), // = 194, /* Enable rendertarget writes to be DE-linearized to SRGB */ + ADD_REGISTER(TYPE_INT, DEPTHBIAS), // = 195, + ADD_REGISTER(TYPE_INT, WRAP8), // = 198, /* Additional wrap states for vs_3_0+ attributes with D3DDECLUSAGE_TEXCOORD */ + ADD_REGISTER(TYPE_INT, WRAP9), // = 199, + ADD_REGISTER(TYPE_INT, WRAP10), // = 200, + ADD_REGISTER(TYPE_INT, WRAP11), // = 201, + ADD_REGISTER(TYPE_INT, WRAP12), // = 202, + ADD_REGISTER(TYPE_INT, WRAP13), // = 203, + ADD_REGISTER(TYPE_INT, WRAP14), // = 204, + ADD_REGISTER(TYPE_INT, WRAP15), // = 205, + ADD_REGISTER(TYPE_INT, SEPARATEALPHABLENDENABLE), // = 206, /* TRUE to enable a separate blending function for the alpha channel */ + ADD_REGISTER(TYPE_INT, SRCBLENDALPHA), // = 207, /* SRC blend factor for the alpha channel when DWORD SEPARATEDESTALPHAENABLE ) */ + ADD_REGISTER(TYPE_INT, DESTBLENDALPHA), // = 208, /* DST blend factor for the alpha channel when DWORD SEPARATEDESTALPHAENABLE ) */ + ADD_REGISTER(TYPE_INT, BLENDOPALPHA), // = 209, /* Blending operation for the alpha channel when DWORD SEPARATEDESTALPHAENABLE ) */ +#undef USING_STRUCT +#undef USING_LIST #define USING_STRUCT CProxyDirect3DDevice9::SD3DStageState -#define USING_LIST "StageState" - ADD_REGISTER(TYPE_INT, COLOROP), // = 1, /* D3DTEXTUREOP - per-stage blending controls for color channels */ - ADD_REGISTER(TYPE_INT, COLORARG1), // = 2, /* D3DTA_* (texture arg) */ - ADD_REGISTER(TYPE_INT, COLORARG2), // = 3, /* D3DTA_* (texture arg) */ - ADD_REGISTER(TYPE_INT, ALPHAOP), // = 4, /* D3DTEXTUREOP - per-stage blending controls for alpha channel */ - ADD_REGISTER(TYPE_INT, ALPHAARG1), // = 5, /* D3DTA_* (texture arg) */ - ADD_REGISTER(TYPE_INT, ALPHAARG2), // = 6, /* D3DTA_* (texture arg) */ - ADD_REGISTER(TYPE_INT, BUMPENVMAT00), // = 7, /* float (bump mapping matrix) */ - ADD_REGISTER(TYPE_INT, BUMPENVMAT01), // = 8, /* float (bump mapping matrix) */ - ADD_REGISTER(TYPE_INT, BUMPENVMAT10), // = 9, /* float (bump mapping matrix) */ - ADD_REGISTER(TYPE_INT, BUMPENVMAT11), // = 10, /* float (bump mapping matrix) */ - ADD_REGISTER(TYPE_INT, TEXCOORDINDEX), // = 11, /* identifies which set of texture coordinates index this texture */ - ADD_REGISTER(TYPE_INT, BUMPENVLSCALE), // = 22, /* float scale for bump map luminance */ - ADD_REGISTER(TYPE_INT, BUMPENVLOFFSET), // = 23, /* float offset for bump map luminance */ - ADD_REGISTER(TYPE_INT, TEXTURETRANSFORMFLAGS), // = 24, /* D3DTEXTURETRANSFORMFLAGS controls texture transform */ - ADD_REGISTER(TYPE_INT, COLORARG0), // = 26, /* D3DTA_* third arg for triadic ops */ - ADD_REGISTER(TYPE_INT, ALPHAARG0), // = 27, /* D3DTA_* third arg for triadic ops */ - ADD_REGISTER(TYPE_INT, RESULTARG), // = 28, /* D3DTA_* arg for result (CURRENT or TEMP) */ - ADD_REGISTER(TYPE_INT, CONSTANT), // = 32, /* Per-stage constant D3DTA_CONSTANT */ -#undef USING_STRUCT -#undef USING_LIST +#define USING_LIST "StageState" + ADD_REGISTER(TYPE_INT, COLOROP), // = 1, /* D3DTEXTUREOP - per-stage blending controls for color channels */ + ADD_REGISTER(TYPE_INT, COLORARG1), // = 2, /* D3DTA_* (texture arg) */ + ADD_REGISTER(TYPE_INT, COLORARG2), // = 3, /* D3DTA_* (texture arg) */ + ADD_REGISTER(TYPE_INT, ALPHAOP), // = 4, /* D3DTEXTUREOP - per-stage blending controls for alpha channel */ + ADD_REGISTER(TYPE_INT, ALPHAARG1), // = 5, /* D3DTA_* (texture arg) */ + ADD_REGISTER(TYPE_INT, ALPHAARG2), // = 6, /* D3DTA_* (texture arg) */ + ADD_REGISTER(TYPE_INT, BUMPENVMAT00), // = 7, /* float (bump mapping matrix) */ + ADD_REGISTER(TYPE_INT, BUMPENVMAT01), // = 8, /* float (bump mapping matrix) */ + ADD_REGISTER(TYPE_INT, BUMPENVMAT10), // = 9, /* float (bump mapping matrix) */ + ADD_REGISTER(TYPE_INT, BUMPENVMAT11), // = 10, /* float (bump mapping matrix) */ + ADD_REGISTER(TYPE_INT, TEXCOORDINDEX), // = 11, /* identifies which set of texture coordinates index this texture */ + ADD_REGISTER(TYPE_INT, BUMPENVLSCALE), // = 22, /* float scale for bump map luminance */ + ADD_REGISTER(TYPE_INT, BUMPENVLOFFSET), // = 23, /* float offset for bump map luminance */ + ADD_REGISTER(TYPE_INT, TEXTURETRANSFORMFLAGS), // = 24, /* D3DTEXTURETRANSFORMFLAGS controls texture transform */ + ADD_REGISTER(TYPE_INT, COLORARG0), // = 26, /* D3DTA_* third arg for triadic ops */ + ADD_REGISTER(TYPE_INT, ALPHAARG0), // = 27, /* D3DTA_* third arg for triadic ops */ + ADD_REGISTER(TYPE_INT, RESULTARG), // = 28, /* D3DTA_* arg for result (CURRENT or TEMP) */ + ADD_REGISTER(TYPE_INT, CONSTANT), // = 32, /* Per-stage constant D3DTA_CONSTANT */ +#undef USING_STRUCT +#undef USING_LIST #define USING_STRUCT CProxyDirect3DDevice9::SD3DSamplerState -#define USING_LIST "SamplerState" - ADD_REGISTER(TYPE_INT, ADDRESSU), // = 1, /* D3DTEXTUREADDRESS for U coordinate */ - ADD_REGISTER(TYPE_INT, ADDRESSV), // = 2, /* D3DTEXTUREADDRESS for V coordinate */ - ADD_REGISTER(TYPE_INT, ADDRESSW), // = 3, /* D3DTEXTUREADDRESS for W coordinate */ - ADD_REGISTER(TYPE_D3DCOLOR, BORDERCOLOR), // = 4, /* D3DCOLOR */ - ADD_REGISTER(TYPE_INT, MAGFILTER), // = 5, /* D3DTEXTUREFILTER filter to use for magnification */ - ADD_REGISTER(TYPE_INT, MINFILTER), // = 6, /* D3DTEXTUREFILTER filter to use for minification */ - ADD_REGISTER(TYPE_INT, MIPFILTER), // = 7, /* D3DTEXTUREFILTER filter to use between mipmaps during minification */ - ADD_REGISTER(TYPE_INT, MIPMAPLODBIAS), // = 8, /* float Mipmap LOD bias */ - ADD_REGISTER(TYPE_INT, MAXMIPLEVEL), // = 9, /* DWORD 0..(n-1) LOD index of largest map to use (0 == largest) */ - ADD_REGISTER(TYPE_INT, MAXANISOTROPY), // = 10, /* DWORD maximum anisotropy */ - ADD_REGISTER(TYPE_INT, SRGBTEXTURE), // = 11, /* Default = 0 (which means Gamma 1.0, no correction required.) else correct for Gamma = 2.2 */ - ADD_REGISTER(TYPE_INT, ELEMENTINDEX), // = 12, When multi-element texture is assigned to sampler, this indicates which element index to use. - ADD_REGISTER(TYPE_INT, DMAPOFFSET), // = 13, /* Offset in vertices in the pre-sampled displacement map. */ -#undef USING_STRUCT -#undef USING_LIST +#define USING_LIST "SamplerState" + ADD_REGISTER(TYPE_INT, ADDRESSU), // = 1, /* D3DTEXTUREADDRESS for U coordinate */ + ADD_REGISTER(TYPE_INT, ADDRESSV), // = 2, /* D3DTEXTUREADDRESS for V coordinate */ + ADD_REGISTER(TYPE_INT, ADDRESSW), // = 3, /* D3DTEXTUREADDRESS for W coordinate */ + ADD_REGISTER(TYPE_D3DCOLOR, BORDERCOLOR), // = 4, /* D3DCOLOR */ + ADD_REGISTER(TYPE_INT, MAGFILTER), // = 5, /* D3DTEXTUREFILTER filter to use for magnification */ + ADD_REGISTER(TYPE_INT, MINFILTER), // = 6, /* D3DTEXTUREFILTER filter to use for minification */ + ADD_REGISTER(TYPE_INT, MIPFILTER), // = 7, /* D3DTEXTUREFILTER filter to use between mipmaps during minification */ + ADD_REGISTER(TYPE_INT, MIPMAPLODBIAS), // = 8, /* float Mipmap LOD bias */ + ADD_REGISTER(TYPE_INT, MAXMIPLEVEL), // = 9, /* DWORD 0..(n-1) LOD index of largest map to use (0 == largest) */ + ADD_REGISTER(TYPE_INT, MAXANISOTROPY), // = 10, /* DWORD maximum anisotropy */ + ADD_REGISTER(TYPE_INT, SRGBTEXTURE), // = 11, /* Default = 0 (which means Gamma 1.0, no correction required.) else correct for Gamma = 2.2 */ + ADD_REGISTER(TYPE_INT, ELEMENTINDEX), // = 12, When multi-element texture is assigned to sampler, this indicates which element index to use. + ADD_REGISTER(TYPE_INT, DMAPOFFSET), // = 13, /* Offset in vertices in the pre-sampled displacement map. */ +#undef USING_STRUCT +#undef USING_LIST #define USING_STRUCT D3DMATERIAL9 -#define USING_LIST "MaterialState" +#define USING_LIST "MaterialState" ADD_REGISTER(TYPE_D3DCOLORVALUE, Diffuse), /* Diffuse color RGBA */ ADD_REGISTER(TYPE_D3DCOLORVALUE, Ambient), /* Ambient color RGB */ ADD_REGISTER(TYPE_D3DCOLORVALUE, Specular), /* Specular 'shininess' */ ADD_REGISTER(TYPE_D3DCOLORVALUE, Emissive), /* Emissive color RGB */ ADD_REGISTER(TYPE_FLOAT, Power), /* Sharpness if specular highlight */ -#undef USING_STRUCT -#undef USING_LIST +#undef USING_STRUCT +#undef USING_LIST #define USING_STRUCT CProxyDirect3DDevice9::SD3DTransformState -#define USING_LIST "TransformState" - ADD_REGISTER(TYPE_MATRIX, VIEW), // = 2, - ADD_REGISTER(TYPE_MATRIX, PROJECTION), // = 3, - ADD_REGISTER(TYPE_MATRIX, TEXTURE0), // = 16, - ADD_REGISTER(TYPE_MATRIX, TEXTURE1), // = 17, - ADD_REGISTER(TYPE_MATRIX, TEXTURE2), // = 18, - ADD_REGISTER(TYPE_MATRIX, TEXTURE3), // = 19, - ADD_REGISTER(TYPE_MATRIX, TEXTURE4), // = 20, - ADD_REGISTER(TYPE_MATRIX, TEXTURE5), // = 21, - ADD_REGISTER(TYPE_MATRIX, TEXTURE6), // = 22, - ADD_REGISTER(TYPE_MATRIX, TEXTURE7), // = 23, - ADD_REGISTER(TYPE_MATRIX, WORLD), // = 256, - ADD_REGISTER(TYPE_MATRIX, WORLD1), // = 257, - ADD_REGISTER(TYPE_MATRIX, WORLD2), // = 258, - ADD_REGISTER(TYPE_MATRIX, WORLD3), // = 259, -#undef USING_STRUCT -#undef USING_LIST +#define USING_LIST "TransformState" + ADD_REGISTER(TYPE_MATRIX, VIEW), // = 2, + ADD_REGISTER(TYPE_MATRIX, PROJECTION), // = 3, + ADD_REGISTER(TYPE_MATRIX, TEXTURE0), // = 16, + ADD_REGISTER(TYPE_MATRIX, TEXTURE1), // = 17, + ADD_REGISTER(TYPE_MATRIX, TEXTURE2), // = 18, + ADD_REGISTER(TYPE_MATRIX, TEXTURE3), // = 19, + ADD_REGISTER(TYPE_MATRIX, TEXTURE4), // = 20, + ADD_REGISTER(TYPE_MATRIX, TEXTURE5), // = 21, + ADD_REGISTER(TYPE_MATRIX, TEXTURE6), // = 22, + ADD_REGISTER(TYPE_MATRIX, TEXTURE7), // = 23, + ADD_REGISTER(TYPE_MATRIX, WORLD), // = 256, + ADD_REGISTER(TYPE_MATRIX, WORLD1), // = 257, + ADD_REGISTER(TYPE_MATRIX, WORLD2), // = 258, + ADD_REGISTER(TYPE_MATRIX, WORLD3), // = 259, +#undef USING_STRUCT +#undef USING_LIST #define USING_STRUCT D3DLIGHT9 -#define USING_LIST "LightState" +#define USING_LIST "LightState" ADD_REGISTER(TYPE_INT, Type), /* Type of light source */ ADD_REGISTER(TYPE_D3DCOLORVALUE, Diffuse), /* Diffuse color of light */ ADD_REGISTER(TYPE_D3DCOLORVALUE, Specular), /* Specular color of light */ @@ -242,23 +247,23 @@ const SRegisterInfo BigRegisterInfoList[] = { ADD_REGISTER(TYPE_FLOAT, Attenuation2), /* Quadratic attenuation */ ADD_REGISTER(TYPE_FLOAT, Theta), /* Inner angle of spotlight cone */ ADD_REGISTER(TYPE_FLOAT, Phi), /* Outer angle of spotlight cone */ -#undef USING_STRUCT -#undef USING_LIST +#undef USING_STRUCT +#undef USING_LIST #define USING_STRUCT CProxyDirect3DDevice9::SD3DLightEnableState -#define USING_LIST "LightEnableState" +#define USING_LIST "LightEnableState" ADD_REGISTER(TYPE_INT, Enable), -#undef USING_STRUCT -#undef USING_LIST +#undef USING_STRUCT +#undef USING_LIST #define USING_STRUCT CProxyDirect3DDevice9::SD3DTextureState -#define USING_LIST "TextureState" +#define USING_LIST "TextureState" ADD_REGISTER(TYPE_TEXTURE, Texture), -#undef USING_STRUCT -#undef USING_LIST +#undef USING_STRUCT +#undef USING_LIST #define USING_STRUCT D3DCAPS9 -#define USING_LIST "DeviceCaps" +#define USING_LIST "DeviceCaps" ADD_REGISTER(TYPE_INT, DeviceType), ADD_REGISTER(TYPE_INT, AdapterOrdinal), ADD_REGISTER(TYPE_INT, Caps), /* Caps from DX7 Draw */ @@ -275,12 +280,12 @@ const SRegisterInfo BigRegisterInfoList[] = { ADD_REGISTER(TYPE_INT, AlphaCmpCaps), ADD_REGISTER(TYPE_INT, ShadeCaps), ADD_REGISTER(TYPE_INT, TextureCaps), - ADD_REGISTER(TYPE_INT, TextureFilterCaps), // D3DPTFILTERCAPS for IDirect3DTexture9's - ADD_REGISTER(TYPE_INT, CubeTextureFilterCaps), // D3DPTFILTERCAPS for IDirect3DCubeTexture9's - ADD_REGISTER(TYPE_INT, VolumeTextureFilterCaps), // D3DPTFILTERCAPS for IDirect3DVolumeTexture9's - ADD_REGISTER(TYPE_INT, TextureAddressCaps), // D3DPTADDRESSCAPS for IDirect3DTexture9's - ADD_REGISTER(TYPE_INT, VolumeTextureAddressCaps), // D3DPTADDRESSCAPS for IDirect3DVolumeTexture9's - ADD_REGISTER(TYPE_INT, LineCaps), // D3DLINECAPS + ADD_REGISTER(TYPE_INT, TextureFilterCaps), // D3DPTFILTERCAPS for IDirect3DTexture9's + ADD_REGISTER(TYPE_INT, CubeTextureFilterCaps), // D3DPTFILTERCAPS for IDirect3DCubeTexture9's + ADD_REGISTER(TYPE_INT, VolumeTextureFilterCaps), // D3DPTFILTERCAPS for IDirect3DVolumeTexture9's + ADD_REGISTER(TYPE_INT, TextureAddressCaps), // D3DPTADDRESSCAPS for IDirect3DTexture9's + ADD_REGISTER(TYPE_INT, VolumeTextureAddressCaps), // D3DPTADDRESSCAPS for IDirect3DVolumeTexture9's + ADD_REGISTER(TYPE_INT, LineCaps), // D3DLINECAPS ADD_REGISTER(TYPE_INT, MaxTextureWidth), ADD_REGISTER(TYPE_INT, MaxTextureHeight), ADD_REGISTER(TYPE_INT, MaxVolumeExtent), @@ -304,23 +309,23 @@ const SRegisterInfo BigRegisterInfoList[] = { ADD_REGISTER(TYPE_INT, MaxVertexBlendMatrices), ADD_REGISTER(TYPE_INT, MaxVertexBlendMatrixIndex), ADD_REGISTER(TYPE_FLOAT, MaxPointSize), - ADD_REGISTER(TYPE_INT, MaxPrimitiveCount), // max number of primitives per DrawPrimitive call + ADD_REGISTER(TYPE_INT, MaxPrimitiveCount), // max number of primitives per DrawPrimitive call ADD_REGISTER(TYPE_INT, MaxVertexIndex), ADD_REGISTER(TYPE_INT, MaxStreams), - ADD_REGISTER(TYPE_INT, MaxStreamStride), // max stride for SetStreamSource + ADD_REGISTER(TYPE_INT, MaxStreamStride), // max stride for SetStreamSource ADD_REGISTER(TYPE_INT, VertexShaderVersion), - ADD_REGISTER(TYPE_INT, MaxVertexShaderConst), // number of vertex shader constant registers + ADD_REGISTER(TYPE_INT, MaxVertexShaderConst), // number of vertex shader constant registers ADD_REGISTER(TYPE_INT, PixelShaderVersion), - ADD_REGISTER(TYPE_FLOAT, PixelShader1xMaxValue), // max value storable in registers of ps.1.x shaders - ADD_REGISTER(TYPE_INT, DevCaps2), // Here are the DX9 specific ones + ADD_REGISTER(TYPE_FLOAT, PixelShader1xMaxValue), // max value storable in registers of ps.1.x shaders + ADD_REGISTER(TYPE_INT, DevCaps2), // Here are the DX9 specific ones ADD_REGISTER(TYPE_FLOAT, MaxNpatchTessellationLevel), ADD_REGISTER(TYPE_INT, Reserved5), - ADD_REGISTER(TYPE_INT, MasterAdapterOrdinal), // ordinal of master adaptor for adapter group - ADD_REGISTER(TYPE_INT, AdapterOrdinalInGroup), // ordinal inside the adapter group - ADD_REGISTER(TYPE_INT, NumberOfAdaptersInGroup), // number of adapters in this adapter group (only if master) - ADD_REGISTER(TYPE_INT, DeclTypes), // Data types, supported in vertex declarations - ADD_REGISTER(TYPE_INT, NumSimultaneousRTs), // Will be at least 1 - ADD_REGISTER(TYPE_INT, StretchRectFilterCaps), // Filter caps supported by StretchRect + ADD_REGISTER(TYPE_INT, MasterAdapterOrdinal), // ordinal of master adaptor for adapter group + ADD_REGISTER(TYPE_INT, AdapterOrdinalInGroup), // ordinal inside the adapter group + ADD_REGISTER(TYPE_INT, NumberOfAdaptersInGroup), // number of adapters in this adapter group (only if master) + ADD_REGISTER(TYPE_INT, DeclTypes), // Data types, supported in vertex declarations + ADD_REGISTER(TYPE_INT, NumSimultaneousRTs), // Will be at least 1 + ADD_REGISTER(TYPE_INT, StretchRectFilterCaps), // Filter caps supported by StretchRect ADD_REGISTER(TYPE_INT, VS20Caps.Caps), ADD_REGISTER(TYPE_INT, VS20Caps.DynamicFlowControlDepth), ADD_REGISTER(TYPE_INT, VS20Caps.NumTemps), @@ -330,25 +335,25 @@ const SRegisterInfo BigRegisterInfoList[] = { ADD_REGISTER(TYPE_INT, PS20Caps.NumTemps), ADD_REGISTER(TYPE_INT, PS20Caps.StaticFlowControlDepth), ADD_REGISTER(TYPE_INT, PS20Caps.NumInstructionSlots), - ADD_REGISTER(TYPE_INT, VertexTextureFilterCaps), // D3DPTFILTERCAPS for IDirect3DTexture9's for texture, used in vertex shaders - ADD_REGISTER(TYPE_INT, MaxVShaderInstructionsExecuted), // maximum number of vertex shader instructions that can be executed - ADD_REGISTER(TYPE_INT, MaxPShaderInstructionsExecuted), // maximum number of pixel shader instructions that can be executed + ADD_REGISTER(TYPE_INT, VertexTextureFilterCaps), // D3DPTFILTERCAPS for IDirect3DTexture9's for texture, used in vertex shaders + ADD_REGISTER(TYPE_INT, MaxVShaderInstructionsExecuted), // maximum number of vertex shader instructions that can be executed + ADD_REGISTER(TYPE_INT, MaxPShaderInstructionsExecuted), // maximum number of pixel shader instructions that can be executed ADD_REGISTER(TYPE_INT, MaxVertexShader30InstructionSlots), ADD_REGISTER(TYPE_INT, MaxPixelShader30InstructionSlots), -#undef USING_STRUCT -#undef USING_LIST +#undef USING_STRUCT +#undef USING_LIST #define USING_STRUCT CProxyDirect3DDevice9::SD3DVertexDeclState -#define USING_LIST "VertexDeclState" - ADD_REGISTER(TYPE_INT, Position), // Does each vertex have these components ? +#define USING_LIST "VertexDeclState" + ADD_REGISTER(TYPE_INT, Position), // Does each vertex have these components ? ADD_REGISTER(TYPE_INT, PositionT), ADD_REGISTER(TYPE_INT, Normal), ADD_REGISTER(TYPE_INT, Color0), ADD_REGISTER(TYPE_INT, Color1), ADD_REGISTER(TYPE_INT, TexCoord0), ADD_REGISTER(TYPE_INT, TexCoord1), -#undef USING_STRUCT -#undef USING_LIST +#undef USING_STRUCT +#undef USING_LIST }; //////////////////////////////////////////////////////////////// @@ -361,31 +366,58 @@ const SRegisterInfo BigRegisterInfoList[] = { //////////////////////////////////////////////////////////////// HRESULT CEffectParameters::Begin(UINT* pPasses, DWORD Flags, bool bWorldRender) { + if (!m_pD3DEffect) + return D3DERR_INVALIDCALL; + if (m_bUsesDepthBuffer && !bWorldRender) { // Ensure readable depth buffer is ready to be read CGraphics::GetSingleton().GetRenderItemManager()->SaveReadableDepthBuffer(); } - for (uint i = 0; i < m_SecondaryRenderTargetList.size(); i++) + LPDIRECT3DDEVICE9 pDevice = nullptr; + m_pD3DEffect->GetDevice(&pDevice); + + bool bCanBindRenderTargets = (pDevice != nullptr); + CScopedActiveProxyDevice proxyDevice; + IDirect3DDevice9* pStateDevice = proxyDevice ? static_cast(proxyDevice.Get()) : pDevice; + if (pDevice) { - D3DXHANDLE hTexture = m_SecondaryRenderTargetList[i]; - IDirect3DBaseTexture9* pD3DTexture = NULL; - HRESULT hr = m_pD3DEffect->GetTexture(hTexture, &pD3DTexture); - if (hr == D3D_OK && pD3DTexture && pD3DTexture->GetType() == D3DRTYPE_TEXTURE) + const HRESULT hrCooperativeLevel = pDevice->TestCooperativeLevel(); + if (hrCooperativeLevel != D3D_OK) { - IDirect3DSurface9* pD3DSurface = NULL; - HRESULT hr = ((IDirect3DTexture9*)pD3DTexture)->GetSurfaceLevel(0, &pD3DSurface); - if (hr == D3D_OK && pD3DSurface) + bCanBindRenderTargets = false; + if (hrCooperativeLevel != D3DERR_DEVICELOST && hrCooperativeLevel != D3DERR_DEVICENOTRESET) + WriteDebugEvent(SString("CEffectParameters::Begin: unexpected cooperative level %08x", hrCooperativeLevel)); + } + } + + if (bCanBindRenderTargets) + { + for (uint i = 0; i < m_SecondaryRenderTargetList.size(); i++) + { + D3DXHANDLE hTexture = m_SecondaryRenderTargetList[i]; + IDirect3DBaseTexture9* pD3DTexture = nullptr; + HRESULT hr = m_pD3DEffect->GetTexture(hTexture, &pD3DTexture); + if (SUCCEEDED(hr) && pD3DTexture) { - LPDIRECT3DDEVICE9 pDevice; - m_pD3DEffect->GetDevice(&pDevice); - pDevice->SetRenderTarget(i + 1, pD3DSurface); - SAFE_RELEASE(pD3DSurface); + if (pD3DTexture->GetType() == D3DRTYPE_TEXTURE) + { + IDirect3DSurface9* pD3DSurface = nullptr; + HRESULT hrSurface = ((IDirect3DTexture9*)pD3DTexture)->GetSurfaceLevel(0, &pD3DSurface); + if (hrSurface == D3D_OK && pD3DSurface) + { + if (pStateDevice) + pStateDevice->SetRenderTarget(i + 1, pD3DSurface); + SAFE_RELEASE(pD3DSurface); + } + } } SAFE_RELEASE(pD3DTexture); } } + + SAFE_RELEASE(pDevice); return m_pD3DEffect->Begin(pPasses, Flags); } @@ -397,15 +429,40 @@ HRESULT CEffectParameters::Begin(UINT* pPasses, DWORD Flags, bool bWorldRender) // Ensures secondary render targets are unset // //////////////////////////////////////////////////////////////// -HRESULT CEffectParameters::End() +HRESULT CEffectParameters::End(bool bDeviceOperational) { + if (!m_pD3DEffect) + return D3D_OK; + HRESULT hResult = m_pD3DEffect->End(); - for (uint i = 0; i < m_SecondaryRenderTargetList.size(); i++) + + if (!m_SecondaryRenderTargetList.empty()) { - LPDIRECT3DDEVICE9 pDevice; + LPDIRECT3DDEVICE9 pDevice = nullptr; m_pD3DEffect->GetDevice(&pDevice); - pDevice->SetRenderTarget(i + 1, NULL); + CScopedActiveProxyDevice proxyDevice; + IDirect3DDevice9* pStateDevice = proxyDevice ? static_cast(proxyDevice.Get()) : pDevice; + + if (pDevice) + { + bool bCanTouchDevice = bDeviceOperational; + if (!bCanTouchDevice) + { + const HRESULT hrCooperativeLevel = pDevice->TestCooperativeLevel(); + bCanTouchDevice = (hrCooperativeLevel == D3D_OK); + } + + if (bCanTouchDevice) + { + for (uint i = 0; i < m_SecondaryRenderTargetList.size(); i++) + if (pStateDevice) + pStateDevice->SetRenderTarget(i + 1, nullptr); + } + + SAFE_RELEASE(pDevice); + } } + return hResult; } @@ -422,8 +479,14 @@ bool CEffectParameters::ApplyCommonHandles() if (!m_bUsesCommonHandles) return false; - LPDIRECT3DDEVICE9 pDevice; - m_pD3DEffect->GetDevice(&pDevice); + if (!m_pD3DEffect) + return false; + + assert(g_pDeviceState); + + LPDIRECT3DDEVICE9 pDevice = nullptr; + if (FAILED(m_pD3DEffect->GetDevice(&pDevice)) || !pDevice) + return false; D3DXMATRIX matWorld, matView, matProjection; pDevice->GetTransform(D3DTS_WORLD, &matWorld); @@ -569,6 +632,7 @@ bool CEffectParameters::ApplyCommonHandles() if (m_CommonHandles.hProjectionMainScene) m_pD3DEffect->SetMatrix(m_CommonHandles.hProjectionMainScene, (D3DXMATRIX*)&g_pDeviceState->MainSceneState.TransformState.PROJECTION); + SAFE_RELEASE(pDevice); return true; }; @@ -580,6 +644,35 @@ void BOUNDS_CHECK(const void* ptr, int ptrsize, const void* bufstart, int bufsiz assert((uchar*)ptr + ptrsize <= (uchar*)bufstart + bufsize); } +static SString TrimAsciiWhitespace(const SString& value) +{ + size_t start = 0; + size_t end = value.length(); + + while (start < end && std::isspace(static_cast(value[start]))) + ++start; + + while (end > start && std::isspace(static_cast(value[end - 1]))) + --end; + + return value.substr(start, end - start); +} + +static bool DoesStateGroupUseStageIndex(EStateGroup stateGroup) +{ + switch (stateGroup) + { + case STATE_GROUP_STAGE: + case STATE_GROUP_SAMPLER: + case STATE_GROUP_TEXTURE: + case STATE_GROUP_LIGHT: + case STATE_GROUP_LIGHT_ENABLE: + return true; + default: + return false; + } +} + //////////////////////////////////////////////////////////////// // // CEffectParameters::ApplyMappedHandles @@ -593,6 +686,11 @@ bool CEffectParameters::ApplyMappedHandles() if (!m_bUsesMappedHandles) return false; + if (!m_pD3DEffect) + return false; + + assert(g_pDeviceState); + ////////////////////////////////////////// // // RenderState @@ -848,6 +946,9 @@ const std::set& CEffectParameters::GetModifiedParameters() //////////////////////////////////////////////////////////////// void CEffectParameters::RestoreParametersDefaultValue(const std::vector& parameterList) { + if (!m_pD3DEffect) + return; + for (auto hParameter : parameterList) { std::vector* pBuffer = MapFind(m_defaultValues, hParameter); @@ -866,6 +967,9 @@ void CEffectParameters::RestoreParametersDefaultValue(const std::vectorGetDesc(&EffectDesc); @@ -917,12 +1021,21 @@ void CEffectParameters::ReadParameterHandles() //////////////////////////////////////////////////////////////// SString CEffectParameters::GetAnnotationNameAndValue(D3DXHANDLE hParameter, uint uiIndex, SString& strOutValue) { - D3DXHANDLE hAnnotation = m_pD3DEffect->GetAnnotation(hParameter, uiIndex); + if (!m_pD3DEffect) + return ""; + + D3DXHANDLE hAnnotation = m_pD3DEffect->GetAnnotation(hParameter, uiIndex); + if (!hAnnotation) + return ""; + D3DXPARAMETER_DESC AnnotDesc; - m_pD3DEffect->GetParameterDesc(hAnnotation, &AnnotDesc); - LPCSTR szAnnotValue; - if (SUCCEEDED(m_pD3DEffect->GetString(hAnnotation, &szAnnotValue))) + if (FAILED(m_pD3DEffect->GetParameterDesc(hAnnotation, &AnnotDesc)) || !AnnotDesc.Name) + return ""; + + LPCSTR szAnnotValue = nullptr; + if (SUCCEEDED(m_pD3DEffect->GetString(hAnnotation, &szAnnotValue)) && szAnnotValue) strOutValue = szAnnotValue; + return AnnotDesc.Name; } @@ -935,6 +1048,9 @@ SString CEffectParameters::GetAnnotationNameAndValue(D3DXHANDLE hParameter, uint //////////////////////////////////////////////////////////////// bool CEffectParameters::TryParseSpecialParameter(D3DXHANDLE hParameter, const D3DXPARAMETER_DESC& ParameterDesc) { + if (!m_pD3DEffect) + return false; + // Use semantic if it exists SString strName = ParameterDesc.Semantic ? ParameterDesc.Semantic : ParameterDesc.Name; if (strName.CompareI("CUSTOMFLAGS")) @@ -989,6 +1105,9 @@ bool CEffectParameters::IsSecondaryRenderTarget(D3DXHANDLE hParameter, const D3D //////////////////////////////////////////////////////////////// bool CEffectParameters::AddStandardParameter(D3DXHANDLE hParameter, const D3DXPARAMETER_DESC& ParameterDesc) { + if (!m_pD3DEffect) + return false; + // Use semantic if it exists SString strName = ParameterDesc.Semantic ? ParameterDesc.Semantic : ParameterDesc.Name; // Add to correct lookup map @@ -1013,8 +1132,10 @@ bool CEffectParameters::AddStandardParameter(D3DXHANDLE hParameter, const D3DXPA { std::vector buffer; buffer.resize(ParameterDesc.Bytes); - m_pD3DEffect->GetValue(hParameter, buffer.data(), buffer.size()); - MapSet(m_defaultValues, hParameter, buffer); + if (SUCCEEDED(m_pD3DEffect->GetValue(hParameter, buffer.data(), buffer.size()))) + { + MapSet(m_defaultValues, hParameter, buffer); + } } return true; } @@ -1042,8 +1163,57 @@ bool CEffectParameters::TryMappingParameterToRegister(D3DXHANDLE hParameter, con } // Extract prepended stage number, if any - int iStage = atoi(strAnnotValue); - SString strName = strAnnotValue.SplitRight(",", NULL, -1); + SString strStagePart; + SString strName; + const bool bHasStagePart = strAnnotValue.Split(",", &strStagePart, &strName, -1); + if (!bHasStagePart) + strName = strAnnotValue; + + strName = TrimAsciiWhitespace(strName); + strStagePart = TrimAsciiWhitespace(strStagePart); + + if (strName.empty()) + continue; + + int iStage = 0; + const bool bGroupUsesStage = DoesStateGroupUseStageIndex(stateGroup); + if (bHasStagePart) + { + if (!bGroupUsesStage) + { + // Stage index supplied where it is not expected + continue; + } + + if (strStagePart.empty()) + continue; + + char* pParseEnd = nullptr; + const long parsedStage = strtol(strStagePart.c_str(), &pParseEnd, 10); + if (!pParseEnd || *pParseEnd != '\0') + continue; + + if (parsedStage < 0 || parsedStage > std::numeric_limits::max()) + continue; + + iStage = static_cast(parsedStage); + } + else if (!bGroupUsesStage) + { + iStage = 0; + } + + if (bGroupUsesStage) + { + const int kMaxFixedStageCount = 8; + if (iStage < 0 || iStage >= kMaxFixedStageCount) + continue; + } + else if (bHasStagePart) + { + // Already handled above, but keep guard for readability + continue; + } // Find D3D register line for this group+name const SRegisterInfo* pRegsiterInfo = GetRegisterInfo(stateGroup, strName); @@ -1068,7 +1238,7 @@ bool CEffectParameters::TryMappingParameterToRegister(D3DXHANDLE hParameter, con var.iSize = pTypeMapping->OutSize; AddStateMappedParameter(stateGroup, var); m_bUsesMappedHandles = true; - return true; // We have a weiner + return true; // We have a weiner } return false; diff --git a/Client/core/Graphics/CRenderItem.EffectParameters.h b/Client/core/Graphics/CRenderItem.EffectParameters.h index b0f68116e31..2b67e29f03f 100644 --- a/Client/core/Graphics/CRenderItem.EffectParameters.h +++ b/Client/core/Graphics/CRenderItem.EffectParameters.h @@ -24,13 +24,13 @@ DECLARE_ENUM(EStateGroup) enum EReadableAsType { - TYPE_INT, // int - TYPE_D3DCOLOR, // Can be read as float4 or DWORD color - TYPE_IFLOAT, // Can be read as float or as int on float memory - TYPE_D3DCOLORVALUE, // float4 - TYPE_FLOAT, // float - TYPE_VECTOR3, // float3 - TYPE_MATRIX, // float4x4 + TYPE_INT, // int + TYPE_D3DCOLOR, // Can be read as float4 or DWORD color + TYPE_IFLOAT, // Can be read as float or as int on float memory + TYPE_D3DCOLORVALUE, // float4 + TYPE_FLOAT, // float + TYPE_VECTOR3, // float3 + TYPE_MATRIX, // float4x4 TYPE_TEXTURE, }; @@ -50,7 +50,7 @@ namespace RegMap Matrix2Matrix, Texture2Texture, }; -} // namespace RegMap +} // namespace RegMap // Map effect parameter to something struct STypeMapping @@ -95,7 +95,7 @@ class CEffectParameters : public CRenderItem bool ApplyCommonHandles(); bool ApplyMappedHandles(); HRESULT Begin(UINT* pPasses, DWORD Flags, bool bWorldRender = true); - HRESULT End(); + HRESULT End(bool bDeviceOperational = true); void NotifyModifiedParameter(D3DXHANDLE hParameter); const std::set& GetModifiedParameters(); void RestoreParametersDefaultValue(const std::vector& parameterList); diff --git a/Client/core/Graphics/CRenderItem.EffectTemplate.cpp b/Client/core/Graphics/CRenderItem.EffectTemplate.cpp index 618b890e9f6..506524e9d8e 100644 --- a/Client/core/Graphics/CRenderItem.EffectTemplate.cpp +++ b/Client/core/Graphics/CRenderItem.EffectTemplate.cpp @@ -9,6 +9,7 @@ #include "StdInc.h" #include "CRenderItem.EffectTemplate.h" +#include #include /////////////////////////////////////////////////////////////// @@ -47,7 +48,7 @@ namespace SString m_strReport; std::map m_FileMD5Map; - CIncludeManager::CIncludeManager(const SString& strRootPath, const SString& strCurrentPath) + CIncludeManager(const SString& strRootPath, const SString& strCurrentPath) { m_strRootPath = strRootPath; m_strCurrentPath = strCurrentPath; @@ -108,11 +109,11 @@ namespace STDMETHOD(Close)(LPCVOID pData) { // Free memory allocated for file contents - delete pData; + free(const_cast(pData)); return S_OK; } }; -} // namespace +} // namespace //////////////////////////////////////////////////////////////// // @@ -153,7 +154,7 @@ void CEffectTemplate::PreDestruct() int CEffectTemplate::GetTicksSinceLastUsed() { if (m_uiCloneCount != 0) - return 0; // Used right now + return 0; // Used right now CTickCount delta = CTickCount::Now(true) - m_TickCountLastUsed; return static_cast(delta.ToLongLong()) + 1; @@ -224,11 +225,11 @@ void CEffectTemplate::CreateUnderlyingData(const SString& strFile, const SString macroList.back().Definition = NULL; // Compile effect - DWORD dwFlags = D3DXFX_LARGEADDRESSAWARE; // D3DXSHADER_PARTIALPRECISION, D3DXSHADER_DEBUG, D3DXFX_NOT_CLONEABLE; + DWORD dwFlags = D3DXFX_LARGEADDRESSAWARE; // D3DXSHADER_PARTIALPRECISION, D3DXSHADER_DEBUG, D3DXFX_NOT_CLONEABLE; if (bDebug) dwFlags |= D3DXSHADER_DEBUG; - SString strMetaPath = bIsRawData ? "" : strFile.Right(strFile.length() - strRootPath.length()); + SString strMetaPath = bIsRawData ? SStringX("") : strFile.Right(strFile.length() - strRootPath.length()); CIncludeManager IncludeManager(strRootPath, ExtractPath(strMetaPath)); LPD3DXBUFFER pBufferErrors = NULL; if (bIsRawData) @@ -300,14 +301,22 @@ void CEffectTemplate::CreateUnderlyingData(const SString& strFile, const SString } // Try resetting samplers if 1st attempt failed - LPDIRECT3DDEVICE9 pDevice; - m_pD3DEffect->GetDevice(&pDevice); - for (uint i = 0; i < 16; i++) + CScopedActiveProxyDevice proxyDevice; + IDirect3DDevice9* pSamplerDevice = proxyDevice ? static_cast(proxyDevice.Get()) : nullptr; + LPDIRECT3DDEVICE9 pDevice = nullptr; + if (!pSamplerDevice && SUCCEEDED(m_pD3DEffect->GetDevice(&pDevice)) && pDevice) + pSamplerDevice = pDevice; + + if (pSamplerDevice) { - pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + for (uint i = 0; i < 16; i++) + { + pSamplerDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + pSamplerDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + pSamplerDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + } } + SAFE_RELEASE(pDevice); } // Set technique diff --git a/Client/core/Graphics/CRenderItem.EffectWrap.cpp b/Client/core/Graphics/CRenderItem.EffectWrap.cpp index 983d2f6bc05..41c7de8a65f 100644 --- a/Client/core/Graphics/CRenderItem.EffectWrap.cpp +++ b/Client/core/Graphics/CRenderItem.EffectWrap.cpp @@ -95,9 +95,9 @@ HRESULT CEffectWrap::Begin(UINT* pPasses, DWORD Flags, bool bWorldRender) // Ensures secondary render targets are unset // //////////////////////////////////////////////////////////////// -HRESULT CEffectWrap::End() +HRESULT CEffectWrap::End(bool bDeviceOperational) { - return m_pEffectTemplate->End(); + return m_pEffectTemplate->End(bDeviceOperational); } //////////////////////////////////////////////////////////////// diff --git a/Client/core/Graphics/CRenderItem.FileTexture.cpp b/Client/core/Graphics/CRenderItem.FileTexture.cpp index d8ccbddefdd..7f9d4aa148d 100644 --- a/Client/core/Graphics/CRenderItem.FileTexture.cpp +++ b/Client/core/Graphics/CRenderItem.FileTexture.cpp @@ -175,20 +175,20 @@ void CFileTextureItem::CreateUnderlyingData(const CPixels* pInPixels, bool bMipM D3DFORMAT D3DFormat = (D3DFORMAT)format; int iMipMaps = bMipMaps ? D3DX_DEFAULT : 1; - if (FAILED(D3DXCreateTextureFromFileInMemoryEx(m_pDevice, //__in LPDIRECT3DDEVICE9 pDevice, - pPixels->GetData(), //__in LPCVOID pSrcData, - pPixels->GetSize(), //__in UINT SrcDataSize, - D3DX_DEFAULT, //__in UINT Width, - D3DX_DEFAULT, //__in UINT Height, - iMipMaps, //__in UINT MipLevels, - 0, //__in DWORD Usage, - D3DFormat, //__in D3DFORMAT Format, - D3DPOOL_MANAGED, //__in D3DPOOL Pool, - D3DX_DEFAULT, //__in DWORD Filter, - D3DX_DEFAULT, //__in DWORD MipFilter, - 0, //__in D3DCOLOR ColorKey, - &imageInfo, //__inout D3DXIMAGE_INFO *pSrcInfo, - NULL, //__out PALETTEENTRY *pPalette, + if (FAILED(D3DXCreateTextureFromFileInMemoryEx(m_pDevice, //__in LPDIRECT3DDEVICE9 pDevice, + pPixels->GetData(), //__in LPCVOID pSrcData, + pPixels->GetSize(), //__in UINT SrcDataSize, + D3DX_DEFAULT, //__in UINT Width, + D3DX_DEFAULT, //__in UINT Height, + iMipMaps, //__in UINT MipLevels, + 0, //__in DWORD Usage, + D3DFormat, //__in D3DFORMAT Format, + D3DPOOL_MANAGED, //__in D3DPOOL Pool, + D3DX_DEFAULT, //__in DWORD Filter, + D3DX_DEFAULT, //__in DWORD MipFilter, + 0, //__in D3DCOLOR ColorKey, + &imageInfo, //__inout D3DXIMAGE_INFO *pSrcInfo, + NULL, //__out PALETTEENTRY *pPalette, (IDirect3DTexture9**)&m_pD3DTexture))) return; @@ -228,37 +228,37 @@ void CFileTextureItem::CreateUnderlyingData(bool bMipMaps, uint uiSizeX, uint ui if (textureType == D3DRTYPE_VOLUMETEXTURE) { - if (FAILED(D3DXCreateVolumeTexture(m_pDevice, //__in LPDIRECT3DDEVICE9 pDevice, - uiSizeX, //__in UINT Width, - uiSizeY, //__in UINT Height, - uiVolumeDepth, //__in UINT Depth, - iMipMaps, //__in UINT MipLevels, - 0, //__in DWORD Usage, - D3DFormat, //__in D3DFORMAT Format, - D3DPOOL_MANAGED, //__in D3DPOOL Pool, + if (FAILED(D3DXCreateVolumeTexture(m_pDevice, //__in LPDIRECT3DDEVICE9 pDevice, + uiSizeX, //__in UINT Width, + uiSizeY, //__in UINT Height, + uiVolumeDepth, //__in UINT Depth, + iMipMaps, //__in UINT MipLevels, + 0, //__in DWORD Usage, + D3DFormat, //__in D3DFORMAT Format, + D3DPOOL_MANAGED, //__in D3DPOOL Pool, (IDirect3DVolumeTexture9**)&m_pD3DTexture))) return; } else if (textureType == D3DRTYPE_CUBETEXTURE) { - if (FAILED(D3DXCreateCubeTexture(m_pDevice, //__in LPDIRECT3DDEVICE9 pDevice, - uiSizeX, //__in UINT Width, - iMipMaps, //__in UINT MipLevels, - 0, //__in DWORD Usage, - D3DFormat, //__in D3DFORMAT Format, - D3DPOOL_MANAGED, //__in D3DPOOL Pool, + if (FAILED(D3DXCreateCubeTexture(m_pDevice, //__in LPDIRECT3DDEVICE9 pDevice, + uiSizeX, //__in UINT Width, + iMipMaps, //__in UINT MipLevels, + 0, //__in DWORD Usage, + D3DFormat, //__in D3DFORMAT Format, + D3DPOOL_MANAGED, //__in D3DPOOL Pool, (IDirect3DCubeTexture9**)&m_pD3DTexture))) return; } else { - if (FAILED(D3DXCreateTexture(m_pDevice, //__in LPDIRECT3DDEVICE9 pDevice, - uiSizeX, //__in UINT Width, - uiSizeY, //__in UINT Height, - iMipMaps, //__in UINT MipLevels, - 0, //__in DWORD Usage, - D3DFormat, //__in D3DFORMAT Format, - D3DPOOL_MANAGED, //__in D3DPOOL Pool, + if (FAILED(D3DXCreateTexture(m_pDevice, //__in LPDIRECT3DDEVICE9 pDevice, + uiSizeX, //__in UINT Width, + uiSizeY, //__in UINT Height, + iMipMaps, //__in UINT MipLevels, + 0, //__in DWORD Usage, + D3DFormat, //__in D3DFORMAT Format, + D3DPOOL_MANAGED, //__in D3DPOOL Pool, (IDirect3DTexture9**)&m_pD3DTexture))) return; diff --git a/Client/core/Graphics/CRenderItem.RenderTarget.cpp b/Client/core/Graphics/CRenderItem.RenderTarget.cpp index 06001ab6a57..10dfb3cf29d 100644 --- a/Client/core/Graphics/CRenderItem.RenderTarget.cpp +++ b/Client/core/Graphics/CRenderItem.RenderTarget.cpp @@ -67,6 +67,8 @@ bool CRenderTargetItem::IsValid() void CRenderTargetItem::OnLostDevice() { ReleaseUnderlyingData(); + m_uiLastEnsureAttempt = 0; + m_uiEnsureDelayMs = 0; } //////////////////////////////////////////////////////////////// @@ -79,6 +81,48 @@ void CRenderTargetItem::OnLostDevice() void CRenderTargetItem::OnResetDevice() { CreateUnderlyingData(); + m_uiLastEnsureAttempt = 0; + m_uiEnsureDelayMs = 0; +} + +//////////////////////////////////////////////////////////////// +// +// CRenderTargetItem::TryEnsureValid +// +// Attempt to (re)create device resources if missing +// +//////////////////////////////////////////////////////////////// +bool CRenderTargetItem::TryEnsureValid() +{ + if (IsValid()) + return true; + + if (!m_pManager || m_pManager->GetDeviceCooperativeLevel("RenderTargetTryEnsureValid", false) != D3D_OK) + return false; + + const uint kRetryIntervalMinMs = 250; + const uint kRetryIntervalMaxMs = 2000; + const uint uiNow = GetTickCount32(); + if (m_uiEnsureDelayMs == 0) + m_uiEnsureDelayMs = kRetryIntervalMinMs; + + if (uiNow - m_uiLastEnsureAttempt < m_uiEnsureDelayMs) + return false; + + m_uiLastEnsureAttempt = uiNow; + + if (m_pD3DRenderTargetSurface || m_pD3DTexture || m_pD3DZStencilSurface || m_pD3DReadSurface) + ReleaseUnderlyingData(); + + CreateUnderlyingData(); + if (IsValid()) + { + m_uiEnsureDelayMs = kRetryIntervalMinMs; + return true; + } + + m_uiEnsureDelayMs = std::min(m_uiEnsureDelayMs * 2, kRetryIntervalMaxMs); + return false; } //////////////////////////////////////////////////////////////// @@ -142,6 +186,7 @@ void CRenderTargetItem::CreateUnderlyingData() // Check depth buffer created if (!m_pD3DZStencilSurface) { + SAFE_RELEASE(m_pD3DRenderTargetSurface); SAFE_RELEASE(m_pD3DTexture); return; } diff --git a/Client/core/Graphics/CRenderItem.ScreenSource.cpp b/Client/core/Graphics/CRenderItem.ScreenSource.cpp index 25e79cdb7de..46306bb95b0 100644 --- a/Client/core/Graphics/CRenderItem.ScreenSource.cpp +++ b/Client/core/Graphics/CRenderItem.ScreenSource.cpp @@ -63,6 +63,8 @@ bool CScreenSourceItem::IsValid() void CScreenSourceItem::OnLostDevice() { ReleaseUnderlyingData(); + m_uiLastEnsureAttempt = 0; + m_uiEnsureDelayMs = 0; } //////////////////////////////////////////////////////////////// @@ -75,6 +77,48 @@ void CScreenSourceItem::OnLostDevice() void CScreenSourceItem::OnResetDevice() { CreateUnderlyingData(); + m_uiLastEnsureAttempt = 0; + m_uiEnsureDelayMs = 0; +} + +//////////////////////////////////////////////////////////////// +// +// CScreenSourceItem::TryEnsureValid +// +// Attempt to (re)create device resources if missing +// +//////////////////////////////////////////////////////////////// +bool CScreenSourceItem::TryEnsureValid() +{ + if (IsValid()) + return true; + + if (!m_pManager || m_pManager->GetDeviceCooperativeLevel("ScreenSourceTryEnsureValid", false) != D3D_OK) + return false; + + const uint kRetryIntervalMinMs = 250; + const uint kRetryIntervalMaxMs = 2000; + const uint uiNow = GetTickCount32(); + if (m_uiEnsureDelayMs == 0) + m_uiEnsureDelayMs = kRetryIntervalMinMs; + + if (uiNow - m_uiLastEnsureAttempt < m_uiEnsureDelayMs) + return false; + + m_uiLastEnsureAttempt = uiNow; + + if (m_pD3DRenderTargetSurface || m_pD3DTexture) + ReleaseUnderlyingData(); + + CreateUnderlyingData(); + if (IsValid()) + { + m_uiEnsureDelayMs = kRetryIntervalMinMs; + return true; + } + + m_uiEnsureDelayMs = std::min(m_uiEnsureDelayMs * 2, kRetryIntervalMaxMs); + return false; } //////////////////////////////////////////////////////////////// diff --git a/Client/core/Graphics/CRenderItem.Shader.cpp b/Client/core/Graphics/CRenderItem.Shader.cpp index b18e1b30b63..2510f6cfdc6 100644 --- a/Client/core/Graphics/CRenderItem.Shader.cpp +++ b/Client/core/Graphics/CRenderItem.Shader.cpp @@ -24,7 +24,7 @@ void CShaderItem::PostConstruct(CRenderItemManager* pManager, const SString& str float fPriority, float fMaxDistance, bool bLayered, bool bDebug, int iTypeMask, const EffectMacroList& macros) { m_fPriority = fPriority; - m_uiCreateTime = ms_uiCreateTimeCounter++; // Priority tie breaker + m_uiCreateTime = ms_uiCreateTimeCounter++; // Priority tie breaker m_fMaxDistanceSq = fMaxDistance * fMaxDistance; m_bLayered = bLayered; m_iTypeMask = iTypeMask; diff --git a/Client/core/Graphics/CRenderItem.ShaderInstance.cpp b/Client/core/Graphics/CRenderItem.ShaderInstance.cpp index 1d550021d3b..f1e8b4ec786 100644 --- a/Client/core/Graphics/CRenderItem.ShaderInstance.cpp +++ b/Client/core/Graphics/CRenderItem.ShaderInstance.cpp @@ -150,7 +150,8 @@ void CShaderInstance::SetTextureValue(D3DXHANDLE hHandle, CTextureItem* pTexture // Set as texture pParam->cType = 't'; pParam->pTextureItem = pTextureItem; - pParam->pTextureItem->AddRef(); + if (pParam->pTextureItem) + pParam->pTextureItem->AddRef(); } //////////////////////////////////////////////////////////////// @@ -179,10 +180,11 @@ void CShaderInstance::SetFloatsValue(D3DXHANDLE hHandle, const float* pfValues, { SShaderValue* pParam = GetParam(hHandle); // Set as float - uiCount = std::min(uiCount, NUMELMS(pParam->floatList)); + const uint uiMaxCount = static_cast(NUMELMS(pParam->floatList)); + uiCount = std::min(uiCount, uiMaxCount); pParam->cType = 'f'; memcpy(pParam->floatList, pfValues, sizeof(float) * uiCount); - pParam->cCount = uiCount; + pParam->cCount = static_cast(uiCount); } //////////////////////////////////////////////////////////////// @@ -221,7 +223,8 @@ bool CShaderInstance::CmpBoolValue(D3DXHANDLE hHandle, bool bValue) bool CShaderInstance::CmpFloatsValue(D3DXHANDLE hHandle, const float* pfValues, uint uiCount) { SShaderValue* pParam = GetParam(hHandle); - return pParam->cType == 'f' && pParam->cCount == uiCount && memcmp(pParam->floatList, pfValues, sizeof(float) * uiCount) == 0; + const uint storedCount = static_cast(pParam->cCount); + return pParam->cType == 'f' && storedCount == uiCount && memcmp(pParam->floatList, pfValues, sizeof(float) * uiCount) == 0; } //////////////////////////////////////////////////////////////// @@ -283,8 +286,40 @@ void CShaderInstance::ApplyShaderParameters() switch (iter->second.cType) { case 't': - pD3DEffect->SetTexture(iter->first, iter->second.pTextureItem->m_pD3DTexture); + { + CTextureItem* pTextureItem = iter->second.pTextureItem; + if (!pTextureItem) + { + pD3DEffect->SetTexture(iter->first, nullptr); + break; + } + + if (CRenderTargetItem* pRenderTarget = DynamicCast(pTextureItem)) + { + if (!pRenderTarget->TryEnsureValid()) + { + pD3DEffect->SetTexture(iter->first, nullptr); + break; + } + } + else if (CScreenSourceItem* pScreenSource = DynamicCast(pTextureItem)) + { + if (!pScreenSource->TryEnsureValid()) + { + pD3DEffect->SetTexture(iter->first, nullptr); + break; + } + } + + if (!pTextureItem->m_pD3DTexture) + { + pD3DEffect->SetTexture(iter->first, nullptr); + break; + } + + pD3DEffect->SetTexture(iter->first, pTextureItem->m_pD3DTexture); break; + } case 'b': pD3DEffect->SetBool(iter->first, iter->second.bValue); diff --git a/Client/core/Graphics/CRenderItem.VectorGraphic.cpp b/Client/core/Graphics/CRenderItem.VectorGraphic.cpp index 61daa79d55c..20cbe454328 100644 --- a/Client/core/Graphics/CRenderItem.VectorGraphic.cpp +++ b/Client/core/Graphics/CRenderItem.VectorGraphic.cpp @@ -53,6 +53,46 @@ bool CVectorGraphicItem::IsValid() return m_pD3DTexture != nullptr; } +//////////////////////////////////////////////////////////////// +// +// CVectorGraphicItem::TryEnsureValid +// +// Attempt to (re)create device resources if missing +// +//////////////////////////////////////////////////////////////// +bool CVectorGraphicItem::TryEnsureValid() +{ + if (IsValid()) + return true; + + if (!m_pManager || m_pManager->GetDeviceCooperativeLevel("VectorGraphicTryEnsureValid", false) != D3D_OK) + return false; + + const uint kRetryIntervalMinMs = 250; + const uint kRetryIntervalMaxMs = 2000; + const uint uiNow = GetTickCount32(); + if (m_uiEnsureDelayMs == 0) + m_uiEnsureDelayMs = kRetryIntervalMinMs; + + if (uiNow - m_uiLastEnsureAttempt < m_uiEnsureDelayMs) + return false; + + m_uiLastEnsureAttempt = uiNow; + + if (m_pD3DRenderTargetSurface || m_pD3DTexture) + ReleaseUnderlyingData(); + + CreateUnderlyingData(); + if (IsValid()) + { + m_uiEnsureDelayMs = kRetryIntervalMinMs; + return true; + } + + m_uiEnsureDelayMs = std::min(m_uiEnsureDelayMs * 2, kRetryIntervalMaxMs); + return false; +} + //////////////////////////////////////////////////////////////// // // CVectorGraphicItem::OnLostDevice diff --git a/Client/core/Graphics/CRenderItemManager.cpp b/Client/core/Graphics/CRenderItemManager.cpp index 3351350ba9c..7f179d82cca 100644 --- a/Client/core/Graphics/CRenderItemManager.cpp +++ b/Client/core/Graphics/CRenderItemManager.cpp @@ -11,8 +11,12 @@ #include #include #include +#include "DXHook/CProxyDirect3DDevice9.h" #include "CRenderItem.EffectCloner.h" +extern std::atomic g_bInMTAScene; +extern std::atomic g_bInGTAScene; + // Type of vertex used to emulate StretchRect for SwiftShader bug struct SRTVertex { @@ -29,6 +33,7 @@ struct SRTVertex // //////////////////////////////////////////////////////////////// CRenderItemManager::CRenderItemManager() + : m_uiLastRenderTargetRetryTime(0), m_uiRenderTargetRetryDelayMs(0), m_uiRenderTargetRetryAttempts(0), m_uiRenderTargetRetryCooldownUntil(0) { m_pEffectCloner = new CEffectCloner(this); } @@ -45,6 +50,30 @@ CRenderItemManager::~CRenderItemManager() SAFE_DELETE(m_pEffectCloner); } +//////////////////////////////////////////////////////////////// +// +// CRenderItemManager::GetDeviceCooperativeLevel +// +// Helper to evaluate device readiness for GPU operations +// +//////////////////////////////////////////////////////////////// +HRESULT CRenderItemManager::GetDeviceCooperativeLevel(const char* szContext, bool bLogLost) const +{ + if (!m_pDevice) + return D3DERR_INVALIDCALL; + + const HRESULT hrCoopLevel = m_pDevice->TestCooperativeLevel(); + if (hrCoopLevel == D3D_OK) + return hrCoopLevel; + + if (bLogLost) // Expand (without log spam) later + { + (void)szContext; + } + + return hrCoopLevel; +} + //////////////////////////////////////////////////////////////// // // CRenderItemManager::OnDeviceCreate @@ -95,8 +124,16 @@ void CRenderItemManager::OnDeviceCreate(IDirect3DDevice9* pDevice, float fViewpo //////////////////////////////////////////////////////////////// void CRenderItemManager::OnLostDevice() { - for (std::set::iterator iter = m_CreatedItemList.begin(); iter != m_CreatedItemList.end(); iter++) - (*iter)->OnLostDevice(); + for (std::set::iterator iter = m_CreatedItemList.begin(); iter != m_CreatedItemList.end();) + { + std::set::iterator current = iter++; + (*current)->OnLostDevice(); + } + + m_uiLastRenderTargetRetryTime = 0; + m_uiRenderTargetRetryDelayMs = 0; + m_uiRenderTargetRetryAttempts = 0; + m_uiRenderTargetRetryCooldownUntil = 0; SAFE_RELEASE(m_pSavedSceneDepthSurface); SAFE_RELEASE(m_pSavedSceneRenderTargetAA); @@ -104,6 +141,8 @@ void CRenderItemManager::OnLostDevice() SAFE_RELEASE(m_pNonAARenderTargetTexture); SAFE_RELEASE(m_pNonAARenderTarget); SAFE_RELEASE(m_pNonAADepthSurface2); + SAFE_RELEASE(m_pDefaultD3DRenderTarget); + SAFE_RELEASE(m_pDefaultD3DZStencilSurface); } //////////////////////////////////////////////////////////////// @@ -118,9 +157,24 @@ void CRenderItemManager::OnResetDevice() for (std::set::iterator iter = m_CreatedItemList.begin(); iter != m_CreatedItemList.end(); iter++) (*iter)->OnResetDevice(); + m_uiLastRenderTargetRetryTime = 0; + m_uiRenderTargetRetryDelayMs = 0; + m_uiRenderTargetRetryAttempts = 0; + m_uiRenderTargetRetryCooldownUntil = 0; + UpdateMemoryUsage(); } +void CRenderItemManager::OnViewportSizeChanged(uint uiNewViewportSizeX, uint uiNewViewportSizeY) +{ + if (m_uiDefaultViewportSizeX == uiNewViewportSizeX && m_uiDefaultViewportSizeY == uiNewViewportSizeY) + return; + + m_uiDefaultViewportSizeX = uiNewViewportSizeX; + m_uiDefaultViewportSizeY = uiNewViewportSizeY; + m_bBackBufferCopyMaybeNeedsResize = true; +} + //////////////////////////////////////////////////////////////// // // CRenderItemManager::CreateTexture @@ -182,7 +236,7 @@ CRenderTargetItem* CRenderItemManager::CreateRenderTarget(uint uiSizeX, uint uiS bool bForce) { if (!bForce && !CanCreateRenderItem(CRenderTargetItem::GetClassId())) - return NULL; + return nullptr; // Include in memory stats only if render target is not for MTA internal use bool bIncludeInMemoryStats = (bForce == false); @@ -192,8 +246,12 @@ CRenderTargetItem* CRenderItemManager::CreateRenderTarget(uint uiSizeX, uint uiS if (!pRenderTargetItem->IsValid()) { - SAFE_RELEASE(pRenderTargetItem); - return NULL; + const bool bAllowDeferredCreate = !bForce; + if (!bAllowDeferredCreate || GetDeviceCooperativeLevel("CreateRenderTarget", false) == D3D_OK) + { + SAFE_RELEASE(pRenderTargetItem); + return nullptr; + } } UpdateMemoryUsage(); @@ -211,7 +269,7 @@ CRenderTargetItem* CRenderItemManager::CreateRenderTarget(uint uiSizeX, uint uiS CScreenSourceItem* CRenderItemManager::CreateScreenSource(uint uiSizeX, uint uiSizeY) { if (!CanCreateRenderItem(CScreenSourceItem::GetClassId())) - return NULL; + return nullptr; CScreenSourceItem* pScreenSourceItem = new CScreenSourceItem(); pScreenSourceItem->PostConstruct(this, uiSizeX, uiSizeY); @@ -219,7 +277,7 @@ CScreenSourceItem* CRenderItemManager::CreateScreenSource(uint uiSizeX, uint uiS if (!pScreenSourceItem->IsValid()) { SAFE_RELEASE(pScreenSourceItem); - return NULL; + return nullptr; } UpdateMemoryUsage(); @@ -237,7 +295,7 @@ CScreenSourceItem* CRenderItemManager::CreateScreenSource(uint uiSizeX, uint uiS CWebBrowserItem* CRenderItemManager::CreateWebBrowser(uint uiSizeX, uint uiSizeY) { if (!CanCreateRenderItem(CWebBrowserItem::GetClassId())) - return NULL; + return nullptr; CWebBrowserItem* pWebBrowserItem = new CWebBrowserItem; pWebBrowserItem->PostConstruct(this, uiSizeX, uiSizeY); @@ -245,7 +303,7 @@ CWebBrowserItem* CRenderItemManager::CreateWebBrowser(uint uiSizeX, uint uiSizeY if (!pWebBrowserItem->IsValid()) { SAFE_RELEASE(pWebBrowserItem); - return NULL; + return nullptr; } UpdateMemoryUsage(); @@ -264,7 +322,7 @@ CShaderItem* CRenderItemManager::CreateShader(const SString& strFile, const SStr float fMaxDistance, bool bLayered, bool bDebug, int iTypeMask, const EffectMacroList& macros) { if (!CanCreateRenderItem(CShaderItem::GetClassId())) - return NULL; + return nullptr; strOutStatus = ""; @@ -274,7 +332,7 @@ CShaderItem* CRenderItemManager::CreateShader(const SString& strFile, const SStr if (!pShaderItem->IsValid()) { SAFE_RELEASE(pShaderItem); - return NULL; + return nullptr; } return pShaderItem; @@ -290,7 +348,7 @@ CShaderItem* CRenderItemManager::CreateShader(const SString& strFile, const SStr CDxFontItem* CRenderItemManager::CreateDxFont(const SString& strFullFilePath, uint uiSize, bool bBold, DWORD ulQuality) { if (!CanCreateRenderItem(CDxFontItem::GetClassId())) - return NULL; + return nullptr; CDxFontItem* pDxFontItem = new CDxFontItem(); pDxFontItem->PostConstruct(this, strFullFilePath, uiSize, bBold, ulQuality); @@ -298,7 +356,7 @@ CDxFontItem* CRenderItemManager::CreateDxFont(const SString& strFullFilePath, ui if (!pDxFontItem->IsValid()) { SAFE_RELEASE(pDxFontItem); - return NULL; + return nullptr; } UpdateMemoryUsage(); @@ -316,7 +374,7 @@ CDxFontItem* CRenderItemManager::CreateDxFont(const SString& strFullFilePath, ui CGuiFontItem* CRenderItemManager::CreateGuiFont(const SString& strFullFilePath, const SString& strFontName, uint uiSize) { if (!CanCreateRenderItem(CGuiFontItem::GetClassId())) - return NULL; + return nullptr; CGuiFontItem* pGuiFontItem = new CGuiFontItem(); pGuiFontItem->PostConstruct(this, strFullFilePath, strFontName, uiSize); @@ -324,7 +382,7 @@ CGuiFontItem* CRenderItemManager::CreateGuiFont(const SString& strFullFilePath, if (!pGuiFontItem->IsValid()) { SAFE_RELEASE(pGuiFontItem); - return NULL; + return nullptr; } UpdateMemoryUsage(); @@ -393,6 +451,88 @@ void CRenderItemManager::DoPulse() UpdateBackBufferCopy(); } +void CRenderItemManager::RetryInvalidRenderTargets() +{ + TryRecreateInvalidRenderTargets(); +} + +//////////////////////////////////////////////////////////////// +// +// CRenderItemManager::TryRecreateInvalidRenderTargets +// +// Retry render target creation when the device is ready +// +//////////////////////////////////////////////////////////////// +void CRenderItemManager::TryRecreateInvalidRenderTargets() +{ + if (GetDeviceCooperativeLevel("TryRecreateInvalidRenderTargets", false) != D3D_OK) + return; + + const uint kRetryIntervalMinMs = 250; + const uint kRetryIntervalMaxMs = 2000; + const uint kRetryAttemptCap = 20; + const uint kRetryCooldownMs = 15000; + + const uint uiNow = GetTickCount32(); + if (m_uiRenderTargetRetryAttempts >= kRetryAttemptCap) + { + if (m_uiRenderTargetRetryCooldownUntil == 0) + m_uiRenderTargetRetryCooldownUntil = uiNow + kRetryCooldownMs; + + if (uiNow < m_uiRenderTargetRetryCooldownUntil) + return; + + m_uiRenderTargetRetryAttempts = 0; + m_uiRenderTargetRetryDelayMs = kRetryIntervalMinMs; + m_uiRenderTargetRetryCooldownUntil = 0; + } + + if (m_uiRenderTargetRetryDelayMs == 0) + m_uiRenderTargetRetryDelayMs = kRetryIntervalMinMs; + + if (uiNow - m_uiLastRenderTargetRetryTime < m_uiRenderTargetRetryDelayMs) + return; + + m_uiLastRenderTargetRetryTime = uiNow; + + bool anyInvalid = false; + bool anyRecreated = false; + for (CRenderItem* pItem : m_CreatedItemList) + { + if (CRenderTargetItem* pRenderTarget = DynamicCast(pItem)) + { + if (pRenderTarget->IsValid()) + continue; + + anyInvalid = true; + if (pRenderTarget->TryEnsureValid()) + anyRecreated = true; + } + else if (CScreenSourceItem* pScreenSource = DynamicCast(pItem)) + { + if (pScreenSource->IsValid()) + continue; + + anyInvalid = true; + if (pScreenSource->TryEnsureValid()) + anyRecreated = true; + } + } + + if (!anyInvalid) + return; + + if (anyRecreated) + { + m_uiRenderTargetRetryAttempts = 0; + m_uiRenderTargetRetryDelayMs = kRetryIntervalMinMs; + return; + } + + ++m_uiRenderTargetRetryAttempts; + m_uiRenderTargetRetryDelayMs = std::min(m_uiRenderTargetRetryDelayMs * 2, kRetryIntervalMaxMs); +} + //////////////////////////////////////////////////////////////// // // CRenderItemManager::UpdateBackBufferCopy @@ -410,16 +550,28 @@ void CRenderItemManager::UpdateBackBufferCopy() return; // Try to get the back buffer - IDirect3DSurface9* pD3DBackBufferSurface = NULL; + IDirect3DSurface9* pD3DBackBufferSurface = nullptr; m_pDevice->GetRenderTarget(0, &pD3DBackBufferSurface); if (!pD3DBackBufferSurface) return; // Copy back buffer into our private render target - D3DTEXTUREFILTERTYPE FilterType = D3DTEXF_LINEAR; - HRESULT hr = m_pDevice->StretchRect(pD3DBackBufferSurface, NULL, m_pBackBufferCopy->m_pD3DRenderTargetSurface, NULL, FilterType); + if (!m_pBackBufferCopy->m_pD3DRenderTargetSurface) + { + SAFE_RELEASE(pD3DBackBufferSurface); + return; + } - m_uiBackBufferCopyRevision++; + D3DTEXTUREFILTERTYPE FilterType = D3DTEXF_LINEAR; + const HRESULT hr = m_pDevice->StretchRect(pD3DBackBufferSurface, nullptr, m_pBackBufferCopy->m_pD3DRenderTargetSurface, nullptr, FilterType); + if (SUCCEEDED(hr)) + { + ++m_uiBackBufferCopyRevision; + } + else + { + WriteDebugEvent(SString("CRenderItemManager::UpdateBackBufferCopy: StretchRect failed: %08x", hr)); + } // Clean up SAFE_RELEASE(pD3DBackBufferSurface); @@ -435,20 +587,31 @@ void CRenderItemManager::UpdateBackBufferCopy() //////////////////////////////////////////////////////////////// void CRenderItemManager::UpdateScreenSource(CScreenSourceItem* pScreenSourceItem, bool bResampleNow) { + if (!pScreenSourceItem) + return; + + if (!pScreenSourceItem->IsValid() && !pScreenSourceItem->TryEnsureValid()) + { + return; + } + if (bResampleNow) { // Tell graphics things are about to change CGraphics::GetSingleton().OnChangingRenderTarget(m_uiDefaultViewportSizeX, m_uiDefaultViewportSizeY); // Try to get the back buffer - IDirect3DSurface9* pD3DBackBufferSurface = NULL; + IDirect3DSurface9* pD3DBackBufferSurface = nullptr; m_pDevice->GetRenderTarget(0, &pD3DBackBufferSurface); if (!pD3DBackBufferSurface) return; // Copy back buffer into our private render target - D3DTEXTUREFILTERTYPE FilterType = D3DTEXF_LINEAR; - HRESULT hr = m_pDevice->StretchRect(pD3DBackBufferSurface, NULL, pScreenSourceItem->m_pD3DRenderTargetSurface, NULL, FilterType); + if (pScreenSourceItem->m_pD3DRenderTargetSurface) + { + D3DTEXTUREFILTERTYPE FilterType = D3DTEXF_LINEAR; + m_pDevice->StretchRect(pD3DBackBufferSurface, nullptr, pScreenSourceItem->m_pD3DRenderTargetSurface, nullptr, FilterType); + } // Clean up SAFE_RELEASE(pD3DBackBufferSurface); @@ -461,10 +624,10 @@ void CRenderItemManager::UpdateScreenSource(CScreenSourceItem* pScreenSourceItem pScreenSourceItem->m_uiRevision = m_uiBackBufferCopyRevision; - if (m_pBackBufferCopy) + if (m_pBackBufferCopy && m_pBackBufferCopy->m_pD3DRenderTargetSurface && pScreenSourceItem->m_pD3DRenderTargetSurface) { D3DTEXTUREFILTERTYPE FilterType = D3DTEXF_LINEAR; - m_pDevice->StretchRect(m_pBackBufferCopy->m_pD3DRenderTargetSurface, NULL, pScreenSourceItem->m_pD3DRenderTargetSurface, NULL, FilterType); + m_pDevice->StretchRect(m_pBackBufferCopy->m_pD3DRenderTargetSurface, nullptr, pScreenSourceItem->m_pD3DRenderTargetSurface, nullptr, FilterType); } } @@ -512,13 +675,28 @@ void CRenderItemManager::UpdateBackBufferCopySize() //////////////////////////////////////////////////////////////// bool CRenderItemManager::SetRenderTarget(CRenderTargetItem* pItem, bool bClear) { + if (GetDeviceCooperativeLevel("SetRenderTarget") != D3D_OK) + return false; + + if (pItem && !pItem->IsValid()) + pItem->TryEnsureValid(); + + if (!pItem || !pItem->IsValid()) + { + if (!m_pDefaultD3DRenderTarget) + SaveDefaultRenderTarget(); + RestoreDefaultRenderTarget(); + return false; + } + if (!m_pDefaultD3DRenderTarget) SaveDefaultRenderTarget(); - ChangeRenderTarget(pItem->m_uiSizeX, pItem->m_uiSizeY, pItem->m_pD3DRenderTargetSurface, pItem->m_pD3DZStencilSurface); + if (!ChangeRenderTarget(pItem->m_uiSizeX, pItem->m_uiSizeY, pItem->m_pD3DRenderTargetSurface, pItem->m_pD3DZStencilSurface)) + return false; if (bClear) - m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); + m_pDevice->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); return true; } @@ -556,21 +734,47 @@ void CRenderItemManager::EnableSetRenderTargetOldVer(bool bEnable) //////////////////////////////////////////////////////////////// bool CRenderItemManager::SaveDefaultRenderTarget() { + if (GetDeviceCooperativeLevel("SaveDefaultRenderTarget") != D3D_OK) + return false; + // Make sure any special depth buffer has been removed SaveReadableDepthBuffer(); // Update our info about what rendertarget is active - IDirect3DSurface9* pActiveD3DRenderTarget; - IDirect3DSurface9* pActiveD3DZStencilSurface; - m_pDevice->GetRenderTarget(0, &pActiveD3DRenderTarget); - m_pDevice->GetDepthStencilSurface(&pActiveD3DZStencilSurface); + IDirect3DSurface9* pActiveD3DRenderTarget = nullptr; + const HRESULT hrRenderTarget = m_pDevice->GetRenderTarget(0, &pActiveD3DRenderTarget); + if (FAILED(hrRenderTarget) || !pActiveD3DRenderTarget) + { + SAFE_RELEASE(pActiveD3DRenderTarget); + SAFE_RELEASE(m_pDefaultD3DRenderTarget); + SAFE_RELEASE(m_pDefaultD3DZStencilSurface); + return false; + } + + IDirect3DSurface9* pActiveD3DZStencilSurface = nullptr; + const HRESULT hrDepthStencil = m_pDevice->GetDepthStencilSurface(&pActiveD3DZStencilSurface); + if (FAILED(hrDepthStencil) && hrDepthStencil != D3DERR_NOTFOUND) + { + SAFE_RELEASE(pActiveD3DRenderTarget); + SAFE_RELEASE(pActiveD3DZStencilSurface); + SAFE_RELEASE(m_pDefaultD3DRenderTarget); + SAFE_RELEASE(m_pDefaultD3DZStencilSurface); + return false; + } + + SAFE_RELEASE(m_pDefaultD3DRenderTarget); + SAFE_RELEASE(m_pDefaultD3DZStencilSurface); m_pDefaultD3DRenderTarget = pActiveD3DRenderTarget; + if (m_pDefaultD3DRenderTarget) + m_pDefaultD3DRenderTarget->AddRef(); + m_pDefaultD3DZStencilSurface = pActiveD3DZStencilSurface; + if (m_pDefaultD3DZStencilSurface) + m_pDefaultD3DZStencilSurface->AddRef(); - // Don't hold any refs because it goes all funny during fullscreen minimize/maximize, even if they are released at onLostDevice - SAFE_RELEASE(pActiveD3DRenderTarget) - SAFE_RELEASE(pActiveD3DZStencilSurface) + SAFE_RELEASE(pActiveD3DRenderTarget); + SAFE_RELEASE(pActiveD3DZStencilSurface); // Do this in case dxSetRenderTarget is being called from some unexpected place CGraphics::GetSingleton().MaybeEnteringMTARenderZone(); @@ -589,11 +793,18 @@ bool CRenderItemManager::RestoreDefaultRenderTarget() // Only need to change if we have info if (m_pDefaultD3DRenderTarget) { - ChangeRenderTarget(m_uiDefaultViewportSizeX, m_uiDefaultViewportSizeY, m_pDefaultD3DRenderTarget, m_pDefaultD3DZStencilSurface); - m_pDefaultD3DRenderTarget = NULL; + if (ChangeRenderTarget(m_uiDefaultViewportSizeX, m_uiDefaultViewportSizeY, m_pDefaultD3DRenderTarget, m_pDefaultD3DZStencilSurface)) + { + SAFE_RELEASE(m_pDefaultD3DRenderTarget); + SAFE_RELEASE(m_pDefaultD3DZStencilSurface); - // Do this in case dxSetRenderTarget is being called from some unexpected place - CGraphics::GetSingleton().MaybeLeavingMTARenderZone(); + // Do this in case dxSetRenderTarget is being called from some unexpected place + CGraphics::GetSingleton().MaybeLeavingMTARenderZone(); + } + else + { + return false; + } } return true; @@ -609,7 +820,7 @@ bool CRenderItemManager::RestoreDefaultRenderTarget() bool CRenderItemManager::IsUsingDefaultRenderTarget() { // If this is NULL, it means we haven't saved it, so aren't using another render target - return m_pDefaultD3DRenderTarget == NULL; + return m_pDefaultD3DRenderTarget == nullptr; } //////////////////////////////////////////////////////////////// @@ -619,32 +830,62 @@ bool CRenderItemManager::IsUsingDefaultRenderTarget() // Worker function to change the D3D render target // //////////////////////////////////////////////////////////////// -void CRenderItemManager::ChangeRenderTarget(uint uiSizeX, uint uiSizeY, IDirect3DSurface9* pD3DRenderTarget, IDirect3DSurface9* pD3DZStencilSurface) +bool CRenderItemManager::ChangeRenderTarget(uint uiSizeX, uint uiSizeY, IDirect3DSurface9* pD3DRenderTarget, IDirect3DSurface9* pD3DZStencilSurface) { + if (GetDeviceCooperativeLevel("ChangeRenderTarget") != D3D_OK) + return false; + // Make sure any special depth buffer has been removed SaveReadableDepthBuffer(); // Check if we need to change - IDirect3DSurface9* pCurrentRenderTarget; - IDirect3DSurface9* pCurrentZStencilSurface; - m_pDevice->GetRenderTarget(0, &pCurrentRenderTarget); - m_pDevice->GetDepthStencilSurface(&pCurrentZStencilSurface); + IDirect3DSurface9* pCurrentRenderTarget = nullptr; + HRESULT hrRenderTarget = m_pDevice->GetRenderTarget(0, &pCurrentRenderTarget); + if (FAILED(hrRenderTarget) || !pCurrentRenderTarget) + { + SAFE_RELEASE(pCurrentRenderTarget); + return false; + } - bool bAlreadySet = (pD3DRenderTarget == pCurrentRenderTarget && pD3DZStencilSurface == pCurrentZStencilSurface); + IDirect3DSurface9* pCurrentZStencilSurface = nullptr; + HRESULT hrDepthStencil = m_pDevice->GetDepthStencilSurface(&pCurrentZStencilSurface); + if (FAILED(hrDepthStencil) && hrDepthStencil != D3DERR_NOTFOUND) + { + SAFE_RELEASE(pCurrentRenderTarget); + SAFE_RELEASE(pCurrentZStencilSurface); + return false; + } - SAFE_RELEASE(pCurrentRenderTarget); - SAFE_RELEASE(pCurrentZStencilSurface); + const bool bAlreadySet = (pD3DRenderTarget == pCurrentRenderTarget && pD3DZStencilSurface == pCurrentZStencilSurface); - // Already set? if (bAlreadySet) - return; + { + SAFE_RELEASE(pCurrentRenderTarget); + SAFE_RELEASE(pCurrentZStencilSurface); + return true; + } // Tell graphics things are about to change CGraphics::GetSingleton().OnChangingRenderTarget(uiSizeX, uiSizeY); // Do change - m_pDevice->SetRenderTarget(0, pD3DRenderTarget); - m_pDevice->SetDepthStencilSurface(pD3DZStencilSurface); + hrRenderTarget = m_pDevice->SetRenderTarget(0, pD3DRenderTarget); + if (FAILED(hrRenderTarget)) + { + SAFE_RELEASE(pCurrentRenderTarget); + SAFE_RELEASE(pCurrentZStencilSurface); + return false; + } + + HRESULT hrSetDepth = m_pDevice->SetDepthStencilSurface(pD3DZStencilSurface); + if (FAILED(hrSetDepth)) + { + m_pDevice->SetRenderTarget(0, pCurrentRenderTarget); + m_pDevice->SetDepthStencilSurface(pCurrentZStencilSurface); + SAFE_RELEASE(pCurrentRenderTarget); + SAFE_RELEASE(pCurrentZStencilSurface); + return false; + } D3DVIEWPORT9 viewport; viewport.X = 0; @@ -654,6 +895,11 @@ void CRenderItemManager::ChangeRenderTarget(uint uiSizeX, uint uiSizeY, IDirect3 viewport.MinZ = 0.0f; viewport.MaxZ = 1.0f; m_pDevice->SetViewport(&viewport); + + SAFE_RELEASE(pCurrentRenderTarget); + SAFE_RELEASE(pCurrentZStencilSurface); + + return true; } //////////////////////////////////////////////////////////////// @@ -723,7 +969,7 @@ void CRenderItemManager::UpdateMemoryUsage() continue; int iMemoryKBUsed = pRenderItem->GetVideoMemoryKBUsed(); - if (pRenderItem->IsA(CFileTextureItem::GetClassId())) + if (pRenderItem->IsA(CFileTextureItem::GetClassId()) || pRenderItem->IsA(CVectorGraphicItem::GetClassId())) m_iTextureMemoryKBUsed += iMemoryKBUsed; else if (pRenderItem->IsA(CRenderTargetItem::GetClassId()) || pRenderItem->IsA(CScreenSourceItem::GetClassId())) m_iRenderTargetMemoryKBUsed += iMemoryKBUsed; @@ -890,7 +1136,7 @@ int CRenderItemManager::GetBitsPerPixel(D3DFORMAT Format) return 4; default: - return 32; // unknown - guess at 32 + return 32; // unknown - guess at 32 } } @@ -1108,7 +1354,7 @@ void CRenderItemManager::PreDrawWorld() { // Create readable depth buffer m_pDevice->CreateTexture(m_uiDefaultViewportSizeX, m_uiDefaultViewportSizeY, 1, D3DUSAGE_DEPTHSTENCIL, (D3DFORMAT)m_depthBufferFormat, D3DPOOL_DEFAULT, - &pReadableDepthBuffer, NULL); + &pReadableDepthBuffer, nullptr); } if (bRequireNonAADisplay && !m_pNonAARenderTarget) { @@ -1117,31 +1363,61 @@ void CRenderItemManager::PreDrawWorld() assert(!m_pNonAADepthSurface2); const D3DPRESENT_PARAMETERS& pp = g_pDeviceState->CreationState.PresentationParameters; + HRESULT hr = D3D_OK; if (!m_bIsSwiftShader) - m_pDevice->CreateRenderTarget(m_uiDefaultViewportSizeX, m_uiDefaultViewportSizeY, pp.BackBufferFormat, D3DMULTISAMPLE_NONE, 0, false, - &m_pNonAARenderTarget, NULL); + { + hr = m_pDevice->CreateRenderTarget(m_uiDefaultViewportSizeX, m_uiDefaultViewportSizeY, pp.BackBufferFormat, D3DMULTISAMPLE_NONE, 0, false, + &m_pNonAARenderTarget, nullptr); + if (FAILED(hr) || !m_pNonAARenderTarget) + { + SAFE_RELEASE(m_pNonAARenderTarget); + hr = FAILED(hr) ? hr : E_FAIL; + } + } else { // Render target texture is needed when emulating StretchRect - m_pDevice->CreateTexture(m_uiDefaultViewportSizeX, m_uiDefaultViewportSizeY, 1, D3DUSAGE_RENDERTARGET, pp.BackBufferFormat, D3DPOOL_DEFAULT, - &m_pNonAARenderTargetTexture, NULL); - if (m_pNonAARenderTargetTexture) - m_pNonAARenderTargetTexture->GetSurfaceLevel(0, &m_pNonAARenderTarget); + hr = m_pDevice->CreateTexture(m_uiDefaultViewportSizeX, m_uiDefaultViewportSizeY, 1, D3DUSAGE_RENDERTARGET, pp.BackBufferFormat, D3DPOOL_DEFAULT, + &m_pNonAARenderTargetTexture, nullptr); + if (FAILED(hr) || !m_pNonAARenderTargetTexture) + { + SAFE_RELEASE(m_pNonAARenderTargetTexture); + hr = FAILED(hr) ? hr : E_FAIL; + } + else + { + hr = m_pNonAARenderTargetTexture->GetSurfaceLevel(0, &m_pNonAARenderTarget); + if (FAILED(hr) || !m_pNonAARenderTarget) + { + SAFE_RELEASE(m_pNonAARenderTarget); + SAFE_RELEASE(m_pNonAARenderTargetTexture); + hr = FAILED(hr) ? hr : E_FAIL; + } + } } - m_pDevice->CreateDepthStencilSurface(m_uiDefaultViewportSizeX, m_uiDefaultViewportSizeY, pp.AutoDepthStencilFormat, D3DMULTISAMPLE_NONE, 0, true, - &m_pNonAADepthSurface2, NULL); + if (SUCCEEDED(hr)) + { + hr = m_pDevice->CreateDepthStencilSurface(m_uiDefaultViewportSizeX, m_uiDefaultViewportSizeY, pp.AutoDepthStencilFormat, D3DMULTISAMPLE_NONE, 0, + true, &m_pNonAADepthSurface2, nullptr); + if (FAILED(hr) || !m_pNonAADepthSurface2) + { + SAFE_RELEASE(m_pNonAADepthSurface2); + SAFE_RELEASE(m_pNonAARenderTarget); + SAFE_RELEASE(m_pNonAARenderTargetTexture); + } + } } // Set depth buffer and maybe render target - if ((pReadableDepthBuffer || m_pNonAADepthSurface2) && m_pSavedSceneDepthSurface == NULL) + if ((pReadableDepthBuffer || m_pNonAADepthSurface2) && m_pSavedSceneDepthSurface == nullptr) { if (m_pDevice->GetDepthStencilSurface(&m_pSavedSceneDepthSurface) == D3D_OK) { if (pReadableDepthBuffer) { // Set readable depth buffer - IDirect3DSurface9* pSurf = NULL; + IDirect3DSurface9* pSurf = nullptr; if (pReadableDepthBuffer->GetSurfaceLevel(0, &pSurf) == D3D_OK) { m_pDevice->SetDepthStencilSurface(pSurf); @@ -1163,7 +1439,7 @@ void CRenderItemManager::PreDrawWorld() m_pDevice->SetRenderTarget(0, m_pNonAARenderTarget); } } - m_pDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); + m_pDevice->Clear(0, nullptr, D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); } } } @@ -1181,21 +1457,58 @@ void CRenderItemManager::SaveReadableDepthBuffer() { m_bUsingReadableDepthBuffer = false; + const HRESULT hrDeviceState = GetDeviceCooperativeLevel("SaveReadableDepthBuffer"); + const bool bDeviceReady = (hrDeviceState == D3D_OK); + + // Ensure device operations are synchronous for GPU driver (especially Nvidia) compatibility + if (bDeviceReady) + { + IDirect3DSurface9* pCurrentDepthSurface = nullptr; + if (SUCCEEDED(m_pDevice->GetDepthStencilSurface(&pCurrentDepthSurface))) + { + // Force GPU to complete any pending depth buffer operations + D3DLOCKED_RECT lockedRect; + if (SUCCEEDED(pCurrentDepthSurface->LockRect(&lockedRect, nullptr, D3DLOCK_READONLY | D3DLOCK_DONOTWAIT))) + { + pCurrentDepthSurface->UnlockRect(); + } + SAFE_RELEASE(pCurrentDepthSurface); + } + } + if (m_pNonAADepthSurface2) { // If using AA hacks, change to the other depth buffer we created - m_pDevice->SetDepthStencilSurface(m_pNonAADepthSurface2); - m_pDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); + if (bDeviceReady) + { + m_pDevice->SetDepthStencilSurface(m_pNonAADepthSurface2); + m_pDevice->Clear(0, nullptr, D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); + } } else { // If not using AA hacks, just change back to the GTA depth buffer if (m_pSavedSceneDepthSurface) { - m_pDevice->SetDepthStencilSurface(m_pSavedSceneDepthSurface); + if (bDeviceReady) + m_pDevice->SetDepthStencilSurface(m_pSavedSceneDepthSurface); SAFE_RELEASE(m_pSavedSceneDepthSurface); } } + + // Additional sync point for GPU driver + // Force immediate execution of depth buffer state changes when we can safely begin a scene + if (bDeviceReady && !g_bInMTAScene.load(std::memory_order_acquire) && !g_bInGTAScene.load(std::memory_order_acquire)) + { + if (!BeginSceneWithoutProxy(m_pDevice, ESceneOwner::MTA)) + { + WriteDebugEvent("CRenderItemManager::SaveReadableDepthBuffer - BeginSceneWithoutProxy failed"); + } + else if (!EndSceneWithoutProxy(m_pDevice, ESceneOwner::MTA)) + { + WriteDebugEvent("CRenderItemManager::SaveReadableDepthBuffer - EndSceneWithoutProxy failed"); + } + } } } @@ -1208,74 +1521,81 @@ void CRenderItemManager::SaveReadableDepthBuffer() //////////////////////////////////////////////////////////////// void CRenderItemManager::FlushNonAARenderTarget() { + const HRESULT hrDeviceState = GetDeviceCooperativeLevel("FlushNonAARenderTarget"); + const bool bDeviceReady = (hrDeviceState == D3D_OK); + if (m_pSavedSceneDepthSurface) { - m_pDevice->SetDepthStencilSurface(m_pSavedSceneDepthSurface); + if (bDeviceReady) + m_pDevice->SetDepthStencilSurface(m_pSavedSceneDepthSurface); SAFE_RELEASE(m_pSavedSceneDepthSurface); } if (m_pSavedSceneRenderTargetAA) { // Restore GTA AA render target, and copy our non-AA data to it - m_pDevice->SetRenderTarget(0, m_pSavedSceneRenderTargetAA); - - if (m_pNonAARenderTarget) + if (bDeviceReady && SUCCEEDED(m_pDevice->SetRenderTarget(0, m_pSavedSceneRenderTargetAA))) { - if (!m_bIsSwiftShader) - m_pDevice->StretchRect(m_pNonAARenderTarget, NULL, m_pSavedSceneRenderTargetAA, NULL, D3DTEXF_POINT); - else + if (m_pNonAARenderTarget) { - // Emulate StretchRect using DrawPrimitive - - // Save render states - IDirect3DStateBlock9* pSavedStateBlock = NULL; - m_pDevice->CreateStateBlock(D3DSBT_ALL, &pSavedStateBlock); - - // Prepare vertex buffer - float fX1 = -0.5f; - float fY1 = -0.5f; - float fX2 = m_uiDefaultViewportSizeX + fX1; - float fY2 = m_uiDefaultViewportSizeY + fY1; - float fU1 = 0; - float fV1 = 0; - float fU2 = 1; - float fV2 = 1; - - const SRTVertex vertices[] = {{fX1, fY1, 0, 1, fU1, fV1}, {fX2, fY1, 0, 1, fU2, fV1}, {fX1, fY2, 0, 1, fU1, fV2}, - {fX2, fY1, 0, 1, fU2, fV1}, {fX2, fY2, 0, 1, fU2, fV2}, {fX1, fY2, 0, 1, fU1, fV2}}; - - // Set vertex stream - uint PrimitiveCount = NUMELMS(vertices) / 3; - const void* pVertexStreamZeroData = &vertices[0]; - uint VertexStreamZeroStride = sizeof(SRTVertex); - m_pDevice->SetFVF(SRTVertex::FVF); - - // Set render states - m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); - m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - m_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE); - m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - m_pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - m_pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - m_pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - m_pDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); - - // Draw using texture - m_pDevice->SetTexture(0, m_pNonAARenderTargetTexture); - m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); - - // Restore render states - if (pSavedStateBlock) + if (!m_bIsSwiftShader) + { + m_pDevice->StretchRect(m_pNonAARenderTarget, nullptr, m_pSavedSceneRenderTargetAA, nullptr, D3DTEXF_POINT); + } + else { - pSavedStateBlock->Apply(); - SAFE_RELEASE(pSavedStateBlock); + // Emulate StretchRect using DrawPrimitive + + // Save render states + IDirect3DStateBlock9* pSavedStateBlock = nullptr; + m_pDevice->CreateStateBlock(D3DSBT_ALL, &pSavedStateBlock); + + // Prepare vertex buffer + float fX1 = -0.5f; + float fY1 = -0.5f; + float fX2 = m_uiDefaultViewportSizeX + fX1; + float fY2 = m_uiDefaultViewportSizeY + fY1; + float fU1 = 0; + float fV1 = 0; + float fU2 = 1; + float fV2 = 1; + + const SRTVertex vertices[] = {{fX1, fY1, 0, 1, fU1, fV1}, {fX2, fY1, 0, 1, fU2, fV1}, {fX1, fY2, 0, 1, fU1, fV2}, + {fX2, fY1, 0, 1, fU2, fV1}, {fX2, fY2, 0, 1, fU2, fV2}, {fX1, fY2, 0, 1, fU1, fV2}}; + + // Set vertex stream + uint PrimitiveCount = NUMELMS(vertices) / 3; + const void* pVertexStreamZeroData = &vertices[0]; + uint VertexStreamZeroStride = sizeof(SRTVertex); + m_pDevice->SetFVF(SRTVertex::FVF); + + // Set render states + m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); + m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + m_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + m_pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + m_pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + m_pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + m_pDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); + + // Draw using texture + m_pDevice->SetTexture(0, m_pNonAARenderTargetTexture); + m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); + + // Restore render states + if (pSavedStateBlock) + { + pSavedStateBlock->Apply(); + SAFE_RELEASE(pSavedStateBlock); + } } } } @@ -1290,20 +1610,31 @@ void CRenderItemManager::FlushNonAARenderTarget() // Maybe replace source surface with our non-AA rt, depending on things // //////////////////////////////////////////////////////////////// -void CRenderItemManager::HandleStretchRect(IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestSurface, CONST RECT* pDestRect, - int Filter) +HRESULT CRenderItemManager::HandleStretchRect(IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestSurface, + CONST RECT* pDestRect, int Filter) { + if (!pSourceSurface || !pDestSurface) + return D3DERR_INVALIDCALL; + + const HRESULT hrDeviceState = GetDeviceCooperativeLevel("HandleStretchRect"); + if (hrDeviceState != D3D_OK) + return hrDeviceState; + if (pSourceSurface == m_pSavedSceneRenderTargetAA) { // If trying to copy from the saved render target, use the active render target instead - if (m_pDevice->GetRenderTarget(0, &pSourceSurface) == D3D_OK) + IDirect3DSurface9* pActiveRenderTarget = nullptr; + const HRESULT hrGetRenderTarget = m_pDevice->GetRenderTarget(0, &pActiveRenderTarget); + if (SUCCEEDED(hrGetRenderTarget) && pActiveRenderTarget) { - m_pDevice->StretchRect(pSourceSurface, pSourceRect, pDestSurface, pDestRect, (D3DTEXTUREFILTERTYPE)Filter); - SAFE_RELEASE(pSourceSurface); + const HRESULT hrStretch = m_pDevice->StretchRect(pActiveRenderTarget, pSourceRect, pDestSurface, pDestRect, (D3DTEXTUREFILTERTYPE)Filter); + SAFE_RELEASE(pActiveRenderTarget); + return hrStretch; } + + SAFE_RELEASE(pActiveRenderTarget); + return SUCCEEDED(hrGetRenderTarget) ? D3DERR_INVALIDCALL : hrGetRenderTarget; } - else - { - m_pDevice->StretchRect(pSourceSurface, pSourceRect, pDestSurface, pDestRect, (D3DTEXTUREFILTERTYPE)Filter); - } + + return m_pDevice->StretchRect(pSourceSurface, pSourceRect, pDestSurface, pDestRect, (D3DTEXTUREFILTERTYPE)Filter); } diff --git a/Client/core/Graphics/CRenderItemManager.h b/Client/core/Graphics/CRenderItemManager.h index 22764c56360..8aa7cef4c51 100644 --- a/Client/core/Graphics/CRenderItemManager.h +++ b/Client/core/Graphics/CRenderItemManager.h @@ -56,7 +56,7 @@ class CRenderItemManager : public CRenderItemManagerInterface virtual ERenderFormat GetDepthBufferFormat() { return m_depthBufferFormat; } virtual void SaveReadableDepthBuffer(); virtual void FlushNonAARenderTarget(); - virtual void HandleStretchRect(IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestSurface, CONST RECT* pDestRect, + virtual HRESULT HandleStretchRect(IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestSurface, CONST RECT* pDestRect, int Filter); // CRenderItemManager @@ -65,16 +65,21 @@ class CRenderItemManager : public CRenderItemManagerInterface void OnDeviceCreate(IDirect3DDevice9* pDevice, float fViewportSizeX, float fViewportSizeY); void OnLostDevice(); void OnResetDevice(); + void OnViewportSizeChanged(uint uiNewViewportSizeX, uint uiNewViewportSizeY); void UpdateBackBufferCopySize(); bool SaveDefaultRenderTarget(); bool IsUsingDefaultRenderTarget(); - void ChangeRenderTarget(uint uiSizeX, uint uiSizeY, IDirect3DSurface9* pD3DRenderTarget, IDirect3DSurface9* pD3DZStencilSurface); + bool ChangeRenderTarget(uint uiSizeX, uint uiSizeY, IDirect3DSurface9* pD3DRenderTarget, IDirect3DSurface9* pD3DZStencilSurface); void RemoveShaderItemFromWatchLists(CShaderItem* pShaderItem); void UpdateMemoryUsage(); bool CanCreateRenderItem(ClassId classId); void NotifyShaderItemUsesDepthBuffer(CShaderItem* pShaderItem, bool bUsesDepthBuffer); void NotifyShaderItemUsesMultipleRenderTargets(CShaderItem* pShaderItem, bool bUsesMultipleRenderTargets); + HRESULT GetDeviceCooperativeLevel(const char* szContext, bool bLogLost = true) const; + + void RetryInvalidRenderTargets(); + static int GetBitsPerPixel(D3DFORMAT Format); static int GetPitchDivisor(D3DFORMAT Format); static int CalcD3DResourceMemoryKBUsage(IDirect3DResource9* pD3DResource); @@ -86,6 +91,8 @@ class CRenderItemManager : public CRenderItemManagerInterface IDirect3DDevice9* m_pDevice; protected: + void TryRecreateInvalidRenderTargets(); + std::set m_CreatedItemList; IDirect3DSurface9* m_pDefaultD3DRenderTarget; IDirect3DSurface9* m_pDefaultD3DZStencilSurface; @@ -118,4 +125,8 @@ class CRenderItemManager : public CRenderItemManagerInterface IDirect3DSurface9* m_pNonAARenderTarget; IDirect3DTexture9* m_pNonAARenderTargetTexture; bool m_bIsSwiftShader; + uint m_uiLastRenderTargetRetryTime; + uint m_uiRenderTargetRetryDelayMs; + uint m_uiRenderTargetRetryAttempts; + uint m_uiRenderTargetRetryCooldownUntil; }; diff --git a/Client/core/Graphics/CTileBatcher.cpp b/Client/core/Graphics/CTileBatcher.cpp index ced7c247fe7..e4b4cc3a688 100644 --- a/Client/core/Graphics/CTileBatcher.cpp +++ b/Client/core/Graphics/CTileBatcher.cpp @@ -11,7 +11,8 @@ #include #include "CTileBatcher.h" -#define DEG2RAD(deg) ( (deg) * (6.2832f/360.f) ) +#include "DXHook/CProxyDirect3DDevice9.h" +#define DEG2RAD(deg) ((deg) * (6.2832f / 360.f)) //////////////////////////////////////////////////////////////// // @@ -190,9 +191,23 @@ void CTileBatcher::Flush() if (CTextureItem* pTextureItem = DynamicCast(m_pCurrentMaterial)) { // Draw using texture - m_pDevice->SetTexture(0, pTextureItem->m_pD3DTexture); - m_pDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, NumVertices, PrimitiveCount, pIndexData, D3DFMT_INDEX16, pVertexStreamZeroData, - VertexStreamZeroStride); + bool bDrawTexture = true; + if (CRenderTargetItem* pRenderTarget = DynamicCast(pTextureItem)) + { + if (!pRenderTarget->TryEnsureValid()) + bDrawTexture = false; + } + else if (CScreenSourceItem* pScreenSource = DynamicCast(pTextureItem)) + { + if (!pScreenSource->TryEnsureValid()) + bDrawTexture = false; + } + if (bDrawTexture && pTextureItem->m_pD3DTexture) + { + m_pDevice->SetTexture(0, pTextureItem->m_pD3DTexture); + m_pDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, NumVertices, PrimitiveCount, pIndexData, D3DFMT_INDEX16, pVertexStreamZeroData, + VertexStreamZeroStride); + } } else if (CShaderInstance* pShaderInstance = DynamicCast(m_pCurrentMaterial)) { @@ -207,7 +222,7 @@ void CTileBatcher::Flush() pShaderInstance->m_pEffectWrap->ApplyMappedHandles(); // Do shader passes - DWORD dwFlags = D3DXFX_DONOTSAVESHADERSTATE; // D3DXFX_DONOTSAVE(SHADER|SAMPLER)STATE + DWORD dwFlags = D3DXFX_DONOTSAVESHADERSTATE; // D3DXFX_DONOTSAVE(SHADER|SAMPLER)STATE uint uiNumPasses = 0; pShaderInstance->m_pEffectWrap->Begin(&uiNumPasses, dwFlags, false); diff --git a/Client/core/Graphics/CTileBatcher.h b/Client/core/Graphics/CTileBatcher.h index b80b01fb8ff..e9ef2bc1eb9 100644 --- a/Client/core/Graphics/CTileBatcher.h +++ b/Client/core/Graphics/CTileBatcher.h @@ -17,22 +17,22 @@ struct SPDTVertex float u, v; }; -#define WRITE_PDT_VERTEX(buf,fX,fY,fZ,dwColor,fU,fV) \ - buf->x = fX; \ - buf->y = fY; \ - buf->z = fZ; \ - buf->color = dwColor; \ - buf->u = fU; \ - buf->v = fV; \ - buf++; +#define WRITE_PDT_VERTEX(buf, fX, fY, fZ, dwColor, fU, fV) \ + buf->x = fX; \ + buf->y = fY; \ + buf->z = fZ; \ + buf->color = dwColor; \ + buf->u = fU; \ + buf->v = fV; \ + buf++; -#define WRITE_QUAD_INDICES(buf,row0,row1) \ - *buf++ = (row0); \ - *buf++ = (row0) + 1; \ - *buf++ = (row1); \ - *buf++ = (row1); \ - *buf++ = (row0) + 1; \ - *buf++ = (row1) + 1; +#define WRITE_QUAD_INDICES(buf, row0, row1) \ + *buf++ = static_cast(row0); \ + *buf++ = static_cast((row0) + 1); \ + *buf++ = static_cast(row1); \ + *buf++ = static_cast(row1); \ + *buf++ = static_cast((row0) + 1); \ + *buf++ = static_cast((row1) + 1); // // Batches draws using the same material diff --git a/Client/core/Graphics/CVideoModeManager.cpp b/Client/core/Graphics/CVideoModeManager.cpp index 77f0da6c71f..a09f02d4e36 100644 --- a/Client/core/Graphics/CVideoModeManager.cpp +++ b/Client/core/Graphics/CVideoModeManager.cpp @@ -10,6 +10,8 @@ *****************************************************************************/ #include "StdInc.h" +#include "CVideoModeManager.h" +#include #include #include @@ -26,24 +28,24 @@ class CVideoModeManager : public CVideoModeManagerInterface ~CVideoModeManager(); // CVideoModeManagerInterface methods - virtual void PreCreateDevice(D3DPRESENT_PARAMETERS* pp); - virtual void PostCreateDevice(IDirect3DDevice9* pD3DDevice, D3DPRESENT_PARAMETERS* pp); - virtual void PreReset(D3DPRESENT_PARAMETERS* pp); - virtual void PostReset(D3DPRESENT_PARAMETERS* pp); - virtual void GetNextVideoMode(int& iOutNextVideoMode, bool& bOutNextWindowed, bool& bOutNextFullScreenMinimize, int& iNextFullscreenStyle); - virtual bool SetVideoMode(int nextVideoMode, bool bNextWindowed, bool bNextFullScreenMinimize, int iNextFullscreenStyle); - virtual bool IsWindowed(); - virtual bool IsMultiMonitor(); - virtual bool IsMinimizeEnabled(); - virtual void OnGainFocus(); - virtual void OnLoseFocus(); - virtual void OnPaint(); - virtual bool GetRequiredDisplayResolution(int& iOutWidth, int& iOutHeight, int& iOutColorBits, int& iOutAdapterIndex); - virtual int GetFullScreenStyle() { return m_iCurrentFullscreenStyle; } - virtual bool IsDisplayModeWindowed(); + virtual void PreCreateDevice(D3DPRESENT_PARAMETERS* pp) override; + virtual void PostCreateDevice(IDirect3DDevice9* pD3DDevice, D3DPRESENT_PARAMETERS* pp) override; + virtual void PreReset(D3DPRESENT_PARAMETERS* pp) override; + virtual void PostReset(D3DPRESENT_PARAMETERS* pp) override; + virtual void GetNextVideoMode(int& iOutNextVideoMode, bool& bOutNextWindowed, bool& bOutNextFullScreenMinimize, int& iNextFullscreenStyle) override; + virtual bool SetVideoMode(int nextVideoMode, bool bNextWindowed, bool bNextFullScreenMinimize, int iNextFullscreenStyle) override; + virtual bool IsWindowed() override; + virtual bool IsMultiMonitor() override; + virtual bool IsMinimizeEnabled() override; + virtual void OnGainFocus() override; + virtual void OnLoseFocus() override; + virtual void OnPaint() override; + virtual bool GetRequiredDisplayResolution(int& iOutWidth, int& iOutHeight, int& iOutColorBits, int& iOutAdapterIndex) override; + virtual int GetFullScreenStyle() override { return m_iCurrentFullscreenStyle; } + virtual bool IsDisplayModeWindowed() override; + virtual bool IsDisplayModeFullScreenWindow() override; bool IsDisplayModeFullScreen(); - bool IsDisplayModeFullScreenWindow(); bool GetCurrentAdapterRect(LPRECT pOutRect); SString GetCurrentAdapterDeviceName(); @@ -51,23 +53,23 @@ class CVideoModeManager : public CVideoModeManagerInterface void LoadCVars(); void SaveCVars(); bool GameResMatchesCurrentAdapter(); - SString MakeResolutionString(uint uiWidth, uint uiHeight, uint uiDepth, uint uiAdapter); + SString MakeResolutionString(UINT uiWidth, UINT uiHeight, UINT uiDepth, UINT uiAdapter); void UpdateMonitor(); - unsigned long m_ulForceBackBufferWidth; - unsigned long m_ulForceBackBufferHeight; - unsigned long m_ulForceBackBufferColorDepth; + ULONG m_ulForceBackBufferWidth; + ULONG m_ulForceBackBufferHeight; + ULONG m_ulForceBackBufferColorDepth; HWND m_hDeviceWindow; CGameSettings* m_pGameSettings; - unsigned long m_ulMonitorCount; + ULONG m_ulMonitorCount; - int m_iCurrentVideoMode; // VideoMode this run + int m_iCurrentVideoMode; // VideoMode this run int m_iCurrentAdapter; bool m_bCurrentWindowed; bool m_bCurrentFullScreenMinimize; int m_iCurrentFullscreenStyle; - int m_iNextVideoMode; // VideoMode next run + int m_iNextVideoMode; // VideoMode next run int m_iNextAdapter; bool m_bNextWindowed; int m_iNextFullscreenStyle; @@ -87,7 +89,7 @@ CVideoModeManagerInterface* NewVideoModeManager() return new CVideoModeManager(); } -CVideoModeManagerInterface* g_pVideoModeManager = NULL; +CVideoModeManagerInterface* g_pVideoModeManager = nullptr; CVideoModeManagerInterface* GetVideoModeManager() { @@ -102,12 +104,26 @@ CVideoModeManagerInterface* GetVideoModeManager() // /////////////////////////////////////////////////////////////// CVideoModeManager::CVideoModeManager() + : m_ulForceBackBufferWidth(0), + m_ulForceBackBufferHeight(0), + m_ulForceBackBufferColorDepth(32), + m_hDeviceWindow(nullptr), + m_pGameSettings(nullptr), + m_ulMonitorCount(0), + m_iCurrentVideoMode(1), + m_iCurrentAdapter(0), + m_bCurrentWindowed(false), + m_bCurrentFullScreenMinimize(false), + m_iCurrentFullscreenStyle(FULLSCREEN_STANDARD), + m_iNextVideoMode(1), + m_iNextAdapter(0), + m_bNextWindowed(false), + m_iNextFullscreenStyle(FULLSCREEN_STANDARD), + m_hCurrentMonitor(nullptr), + m_bPendingGainFocus(false), + m_bOriginalDesktopResMatches(false) { m_pGameSettings = CCore::GetSingleton().GetGame()->GetSettings(); - m_iCurrentVideoMode = 1; - m_bCurrentWindowed = false; - m_iNextVideoMode = 1; - m_bNextWindowed = false; } CVideoModeManager::~CVideoModeManager() @@ -123,6 +139,9 @@ CVideoModeManager::~CVideoModeManager() /////////////////////////////////////////////////////////////// void CVideoModeManager::PreCreateDevice(D3DPRESENT_PARAMETERS* pp) { + if (!pp) + return; + m_hDeviceWindow = pp->hDeviceWindow; // Load settings @@ -140,20 +159,28 @@ void CVideoModeManager::PreCreateDevice(D3DPRESENT_PARAMETERS* pp) if (IsDisplayModeWindowed()) { RECT rc; - GetCurrentAdapterRect(&rc); - int iPosX = (rc.left + rc.right) / 2 - (pp->BackBufferWidth / 2); - int iPosY = (rc.top + rc.bottom) / 2 - (pp->BackBufferHeight / 2); - SetWindowLong(m_hDeviceWindow, GWL_STYLE, WS_POPUP); - MoveWindow(m_hDeviceWindow, iPosX, iPosY, pp->BackBufferWidth, pp->BackBufferHeight, TRUE); - pp->Windowed = true; + if (GetCurrentAdapterRect(&rc)) + { + int iPosX = (rc.left + rc.right) / 2 - static_cast(pp->BackBufferWidth) / 2; + int iPosY = (rc.top + rc.bottom) / 2 - static_cast(pp->BackBufferHeight) / 2; + + if (m_hDeviceWindow) + { + SetWindowLong(m_hDeviceWindow, GWL_STYLE, WS_POPUP); + MoveWindow(m_hDeviceWindow, iPosX, iPosY, static_cast(pp->BackBufferWidth), static_cast(pp->BackBufferHeight), TRUE); + } + } + pp->Windowed = TRUE; } else if (IsDisplayModeFullScreenWindow()) { RECT rc; - GetCurrentAdapterRect(&rc); - SetWindowLong(m_hDeviceWindow, GWL_STYLE, WS_POPUP); - MoveWindow(m_hDeviceWindow, rc.left, rc.top, pp->BackBufferWidth, pp->BackBufferHeight, TRUE); - pp->Windowed = true; + if (GetCurrentAdapterRect(&rc) && m_hDeviceWindow) + { + SetWindowLong(m_hDeviceWindow, GWL_STYLE, WS_POPUP); + MoveWindow(m_hDeviceWindow, rc.left, rc.top, static_cast(pp->BackBufferWidth), static_cast(pp->BackBufferHeight), TRUE); + } + pp->Windowed = TRUE; } if (pp->SwapEffect == D3DSWAPEFFECT_FLIP && IsDisplayModeWindowed()) @@ -178,6 +205,22 @@ void CVideoModeManager::PreCreateDevice(D3DPRESENT_PARAMETERS* pp) /////////////////////////////////////////////////////////////// void CVideoModeManager::PostCreateDevice(IDirect3DDevice9* pD3DDevice, D3DPRESENT_PARAMETERS* pp) { + if (!pD3DDevice || !pp) + return; + +#ifdef MTA_DEBUG + { + // `PostCreateDevice` intentionally operates on the real device (it may call Reset immediately). + // Log if we ever see the proxy here, as that can introduce recursion/state tracking side-effects. + IUnknown* pProxyMarker = nullptr; + const HRESULT hr = pD3DDevice->QueryInterface(CProxyDirect3DDevice9_GUID, reinterpret_cast(&pProxyMarker)); + if (SUCCEEDED(hr) && pProxyMarker) + { + pProxyMarker->Release(); + } + } +#endif + if (IsDisplayModeWindowed() || IsDisplayModeFullScreenWindow()) pD3DDevice->Reset(pp); } @@ -191,6 +234,9 @@ void CVideoModeManager::PostCreateDevice(IDirect3DDevice9* pD3DDevice, D3DPRESEN /////////////////////////////////////////////////////////////// void CVideoModeManager::PreReset(D3DPRESENT_PARAMETERS* pp) { + if (!pp) + return; + if (IsDisplayModeWindowed() || IsDisplayModeFullScreenWindow()) { pp->Windowed = true; @@ -210,6 +256,9 @@ void CVideoModeManager::PreReset(D3DPRESENT_PARAMETERS* pp) /////////////////////////////////////////////////////////////// void CVideoModeManager::PostReset(D3DPRESENT_PARAMETERS* pp) { + if (!pp || !m_hDeviceWindow) + return; + if (pp->Windowed) { // Add frame @@ -219,7 +268,7 @@ void CVideoModeManager::PostReset(D3DPRESENT_PARAMETERS* pp) SetWindowLong(m_hDeviceWindow, GWL_STYLE, Style); - LONG ExStyle = 0; // WS_EX_WINDOWEDGE; + LONG ExStyle = 0; // WS_EX_WINDOWEDGE; SetWindowLong(m_hDeviceWindow, GWL_EXSTYLE, ExStyle); // Ensure client area of window is correct size @@ -302,7 +351,8 @@ void CVideoModeManager::OnLoseFocus() if (!IsMultiMonitor() || IsMinimizeEnabled()) { HWND hWnd = CCore::GetSingleton().GetHookedWindow(); - ShowWindow(hWnd, SW_MINIMIZE); + if (hWnd) + ShowWindow(hWnd, SW_MINIMIZE); if (!m_bOriginalDesktopResMatches && (m_iCurrentFullscreenStyle == FULLSCREEN_BORDERLESS)) { @@ -310,16 +360,17 @@ void CVideoModeManager::OnLoseFocus() memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); dmScreenSettings.dmSize = sizeof(dmScreenSettings); - if (!EnumDisplaySettings(GetCurrentAdapterDeviceName(), ENUM_REGISTRY_SETTINGS, &dmScreenSettings)) + SString deviceName = GetCurrentAdapterDeviceName(); + if (!EnumDisplaySettingsA(deviceName.c_str(), ENUM_REGISTRY_SETTINGS, &dmScreenSettings)) { - AddReportLog(7340, SString("EnumDisplaySettings failed for %s", *GetCurrentAdapterDeviceName())); + AddReportLog(7340, SString("EnumDisplaySettings failed for %s", deviceName.c_str())); return; } - int iChangeResult = ChangeDisplaySettingsEx(GetCurrentAdapterDeviceName(), &dmScreenSettings, NULL, CDS_RESET, NULL); + int iChangeResult = ChangeDisplaySettingsExA(deviceName.c_str(), &dmScreenSettings, nullptr, CDS_RESET, nullptr); if (iChangeResult != DISP_CHANGE_SUCCESSFUL) { - AddReportLog(7341, SString("ChangeDisplaySettingsEx failed for %s (%d)", *GetCurrentAdapterDeviceName(), iChangeResult)); + AddReportLog(7341, SString("ChangeDisplaySettingsEx failed for %s (%d)", deviceName.c_str(), iChangeResult)); return; } } @@ -336,11 +387,13 @@ void CVideoModeManager::OnLoseFocus() /////////////////////////////////////////////////////////////// void CVideoModeManager::OnPaint() { - if (IsDisplayModeFullScreenWindow()) + if (IsDisplayModeFullScreenWindow() && m_hDeviceWindow) { RECT rc; - GetCurrentAdapterRect(&rc); - MoveWindow(m_hDeviceWindow, rc.left, rc.top, m_ulForceBackBufferWidth, m_ulForceBackBufferHeight, FALSE); + if (GetCurrentAdapterRect(&rc)) + { + MoveWindow(m_hDeviceWindow, rc.left, rc.top, static_cast(m_ulForceBackBufferWidth), static_cast(m_ulForceBackBufferHeight), FALSE); + } } } @@ -371,7 +424,7 @@ bool CVideoModeManager::SetVideoMode(int iNextVideoMode, bool bNextWindowed, boo bool bRequiresRestart = false; // Resolution - if (iNextVideoMode > 0 && iNextVideoMode < (int)m_pGameSettings->GetNumVideoModes()) + if (iNextVideoMode > 0 && m_pGameSettings && iNextVideoMode < static_cast(m_pGameSettings->GetNumVideoModes())) { if (m_iNextVideoMode != iNextVideoMode) { @@ -459,16 +512,20 @@ void CVideoModeManager::LoadCVars() /////////////////////////////////////////////////////////////// void CVideoModeManager::SaveCVars() { - m_pGameSettings->SetCurrentVideoMode(m_iNextVideoMode, true); + if (m_pGameSettings) + { + m_pGameSettings->SetCurrentVideoMode(m_iNextVideoMode, true); + + VideoMode info; + if (m_pGameSettings->GetVideoModeInfo(&info, m_iNextVideoMode)) + { + CVARS_SET("display_resolution", MakeResolutionString(info.width, info.height, info.depth, static_cast(m_iNextAdapter))); + } + } + CVARS_SET("display_windowed", m_bNextWindowed); CVARS_SET("display_fullscreen_style", m_iNextFullscreenStyle); CVARS_SET("multimon_fullscreen_minimize", m_bCurrentFullScreenMinimize); - - VideoMode info; - if (m_pGameSettings->GetVideoModeInfo(&info, m_iNextVideoMode)) - { - CVARS_SET("display_resolution", MakeResolutionString(info.width, info.height, info.depth, m_iNextAdapter)); - } } /////////////////////////////////////////////////////////////// @@ -501,13 +558,12 @@ bool CVideoModeManager::IsMultiMonitor() device.cb = sizeof(device); // Get next DISPLAY_DEVICE from the system - if (!EnumDisplayDevicesA(NULL, i, &device, 0)) + if (!EnumDisplayDevicesA(nullptr, static_cast(i), &device, 0)) break; // Calc flags bool bAttachedToDesktop = (device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != 0; bool bMirroringDriver = (device.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) != 0; - bool bPrimaryDevice = (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0; // Ignore devices that are not required if (!bAttachedToDesktop || bMirroringDriver) @@ -578,15 +634,24 @@ bool CVideoModeManager::IsDisplayModeFullScreenWindow() bool CVideoModeManager::GameResMatchesCurrentAdapter() { RECT rc; - GetCurrentAdapterRect(&rc); + if (!GetCurrentAdapterRect(&rc)) + return false; + int iAdapterResX = rc.right - rc.left; int iAdapterResY = rc.bottom - rc.top; // Here we hope that the color depth is the same across all monitors - HDC hdcPrimaryMonitor = GetDC(NULL); - int iDesktopColorDepth = GetDeviceCaps(hdcPrimaryMonitor, BITSPIXEL); + HDC hdcPrimaryMonitor = GetDC(nullptr); + int iDesktopColorDepth = 32; // Default fallback - if (iAdapterResX == m_ulForceBackBufferWidth && iAdapterResY == m_ulForceBackBufferHeight && iDesktopColorDepth == m_ulForceBackBufferColorDepth) + if (hdcPrimaryMonitor) + { + iDesktopColorDepth = GetDeviceCaps(hdcPrimaryMonitor, BITSPIXEL); + ReleaseDC(nullptr, hdcPrimaryMonitor); + } + + if (iAdapterResX == static_cast(m_ulForceBackBufferWidth) && iAdapterResY == static_cast(m_ulForceBackBufferHeight) && + iDesktopColorDepth == static_cast(m_ulForceBackBufferColorDepth)) { return true; } @@ -601,7 +666,7 @@ bool CVideoModeManager::GameResMatchesCurrentAdapter() // Make a frendly string for saving to the config file // /////////////////////////////////////////////////////////////// -SString CVideoModeManager::MakeResolutionString(uint uiWidth, uint uiHeight, uint uiDepth, uint uiAdapter) +SString CVideoModeManager::MakeResolutionString(UINT uiWidth, UINT uiHeight, UINT uiDepth, UINT uiAdapter) { SString strRes("%dx%dx%d", uiWidth, uiHeight, uiDepth); if (uiAdapter > 0) @@ -619,7 +684,7 @@ SString CVideoModeManager::MakeResolutionString(uint uiWidth, uint uiHeight, uin /////////////////////////////////////////////////////////////// void CVideoModeManager::UpdateMonitor() { - if (IsDisplayModeFullScreenWindow()) + if (IsDisplayModeFullScreenWindow() && m_hDeviceWindow) { m_hCurrentMonitor = MonitorFromWindow(m_hDeviceWindow, MONITOR_DEFAULTTONEAREST); } @@ -645,18 +710,45 @@ bool CVideoModeManager::GetRequiredDisplayResolution(int& iOutWidth, int& iOutHe // Parse string from config std::vector parts; strResString.ToLower().Replace(" ", "").Split("x", parts); + if (parts.size() > 1) { - iOutWidth = atoi(parts[0]); - iOutHeight = atoi(parts[1]); + const char* widthStr = parts[0].c_str(); + const char* heightStr = parts[1].c_str(); + + if (widthStr && heightStr) + { + long width = strtol(widthStr, nullptr, 10); + long height = strtol(heightStr, nullptr, 10); + + if (width > 0 && width <= 65535 && height > 0 && height <= 65535) + { + iOutWidth = static_cast(width); + iOutHeight = static_cast(height); + } + } } + if (parts.size() > 2) { - iOutColorBits = atoi(parts[2]); + const char* colorStr = parts[2].c_str(); + if (colorStr) + { + long colorBits = strtol(colorStr, nullptr, 10); + if (colorBits == 16 || colorBits == 32) + iOutColorBits = static_cast(colorBits); + } } + if (parts.size() > 3) { - iOutAdapterIndex = atoi(parts[3]); + const char* adapterStr = parts[3].c_str(); + if (adapterStr) + { + long adapter = strtol(adapterStr, nullptr, 10); + if (adapter >= 0) + iOutAdapterIndex = static_cast(adapter); + } } return (iOutWidth > 0) && (iOutHeight > 0) && (iOutColorBits == 16 || iOutColorBits == 32); @@ -671,11 +763,29 @@ bool CVideoModeManager::GetRequiredDisplayResolution(int& iOutWidth, int& iOutHe /////////////////////////////////////////////////////////////// bool CVideoModeManager::GetCurrentAdapterRect(LPRECT pOutRect) { - MONITORINFOEX monitorInfo; + if (!pOutRect) + return false; + + // Initialize to safe defaults + pOutRect->left = 0; + pOutRect->top = 0; + pOutRect->right = 1024; + pOutRect->bottom = 768; + + if (!m_hCurrentMonitor) + return false; + + MONITORINFOEX monitorInfo{}; monitorInfo.cbSize = sizeof(MONITORINFOEX); - BOOL bResult = GetMonitorInfo(m_hCurrentMonitor, &monitorInfo); - *pOutRect = monitorInfo.rcMonitor; - return bResult != 0; + + BOOL bResult = GetMonitorInfoA(m_hCurrentMonitor, &monitorInfo); + if (bResult) + { + *pOutRect = monitorInfo.rcMonitor; + return true; + } + + return false; } /////////////////////////////////////////////////////////////// @@ -687,9 +797,18 @@ bool CVideoModeManager::GetCurrentAdapterRect(LPRECT pOutRect) /////////////////////////////////////////////////////////////// SString CVideoModeManager::GetCurrentAdapterDeviceName() { - MONITORINFOEX monitorInfo; + if (!m_hCurrentMonitor) + return ""; + + MONITORINFOEX monitorInfo{}; monitorInfo.cbSize = sizeof(MONITORINFOEX); - if (GetMonitorInfo(m_hCurrentMonitor, &monitorInfo)) - return monitorInfo.szDevice; + + if (GetMonitorInfoA(m_hCurrentMonitor, &monitorInfo)) + { + // Ensure null termination for x86 safety + monitorInfo.szDevice[sizeof(monitorInfo.szDevice) - 1] = '\0'; + return std::string(monitorInfo.szDevice); + } + return ""; } diff --git a/Client/core/Graphics/CVideoModeManager.h b/Client/core/Graphics/CVideoModeManager.h index 803bcb8df07..899b57c48ea 100644 --- a/Client/core/Graphics/CVideoModeManager.h +++ b/Client/core/Graphics/CVideoModeManager.h @@ -37,6 +37,7 @@ class CVideoModeManagerInterface virtual bool GetRequiredDisplayResolution(int& iOutWidth, int& iOutHeight, int& iOutColorBits, int& iOutAdapterIndex) = 0; virtual int GetFullScreenStyle() = 0; virtual bool IsDisplayModeWindowed() = 0; + virtual bool IsDisplayModeFullScreenWindow() = 0; }; CVideoModeManagerInterface* GetVideoModeManager(); diff --git a/Client/core/ServerBrowser/CServerBrowser.MasterServerManager.cpp b/Client/core/ServerBrowser/CServerBrowser.MasterServerManager.cpp index 8cb9b70342a..5555c91b1f7 100644 --- a/Client/core/ServerBrowser/CServerBrowser.MasterServerManager.cpp +++ b/Client/core/ServerBrowser/CServerBrowser.MasterServerManager.cpp @@ -24,6 +24,7 @@ class CMasterServerManager : public CMasterServerManagerInterface virtual void Refresh(); virtual bool HasData(); virtual bool ParseList(CServerListItemList& itemList); + virtual void CancelRefresh(); // CMasterServerManager protected: @@ -65,6 +66,7 @@ CMasterServerManager::CMasterServerManager() /////////////////////////////////////////////////////////////// CMasterServerManager::~CMasterServerManager() { + CancelRefresh(); for (uint i = 0; i < m_MasterServerList.size(); i++) SAFE_RELEASE(m_MasterServerList[i]); @@ -152,3 +154,15 @@ bool CMasterServerManager::ParseList(CServerListItemList& itemList) return uiParsedCount > 0; } + +void CMasterServerManager::CancelRefresh() +{ + for (uint i = 0; i < m_MasterServerList.size(); ++i) + { + if (m_MasterServerList[i]) + m_MasterServerList[i]->Cancel(); + } + + m_iActiveAmount = 0; + m_ElapsedTime.Reset(); +} diff --git a/Client/core/ServerBrowser/CServerBrowser.MasterServerManager.h b/Client/core/ServerBrowser/CServerBrowser.MasterServerManager.h index 911f75d1e84..bb24aa94054 100644 --- a/Client/core/ServerBrowser/CServerBrowser.MasterServerManager.h +++ b/Client/core/ServerBrowser/CServerBrowser.MasterServerManager.h @@ -11,6 +11,7 @@ class CMasterServerManagerInterface virtual void Refresh() = 0; virtual bool HasData() = 0; virtual bool ParseList(CServerListItemList& itemList) = 0; + virtual void CancelRefresh() = 0; }; CMasterServerManagerInterface* NewMasterServerManager(); diff --git a/Client/core/ServerBrowser/CServerBrowser.RemoteMasterServer.cpp b/Client/core/ServerBrowser/CServerBrowser.RemoteMasterServer.cpp index 2a169c2ae3b..9ea0f81448a 100644 --- a/Client/core/ServerBrowser/CServerBrowser.RemoteMasterServer.cpp +++ b/Client/core/ServerBrowser/CServerBrowser.RemoteMasterServer.cpp @@ -23,6 +23,7 @@ class CRemoteMasterServer : public CRemoteMasterServerInterface virtual void Refresh(); virtual bool HasData(); virtual bool ParseList(CServerListItemList& itemList); + virtual void Cancel(); // CRemoteMasterServer void Init(const SString& strURL); @@ -42,6 +43,7 @@ class CRemoteMasterServer : public CRemoteMasterServerInterface SString m_strStage; SString m_strURL; CBuffer m_Data; + bool m_bPendingDownload = false; }; /////////////////////////////////////////////////////////////// @@ -90,7 +92,9 @@ CRemoteMasterServer::~CRemoteMasterServer() void CRemoteMasterServer::Init(const SString& strURL) { m_strURL = strURL; - GetHTTP()->SetMaxConnections(5); + CNetHTTPDownloadManagerInterface* pHTTP = GetHTTP(); + if (pHTTP) + pHTTP->SetMaxConnections(5); } /////////////////////////////////////////////////////////////// @@ -118,13 +122,55 @@ void CRemoteMasterServer::Refresh() if (GetTickCount64_() - m_llLastRefreshTime < 60000 && m_strStage == "hasdata") return; + CNetHTTPDownloadManagerInterface* pHTTP = GetHTTP(); + if (!pHTTP) + { + m_strStage = "nogood"; + return; + } + // Send new request m_strStage = "waitingreply"; m_llLastRefreshTime = GetTickCount64_(); - AddRef(); // Keep alive SHttpRequestOptions options; options.uiConnectionAttempts = 1; - GetHTTP()->QueueFile(m_strURL, NULL, this, &CRemoteMasterServer::StaticDownloadFinished, options); + if (pHTTP->QueueFile(m_strURL, NULL, this, &CRemoteMasterServer::StaticDownloadFinished, options)) + { + m_bPendingDownload = true; + AddRef(); // Keep alive + } + else + { + m_strStage = "nogood"; + } +} + +void CRemoteMasterServer::Cancel() +{ + if (!m_bPendingDownload) + return; + + CNetHTTPDownloadManagerInterface* pHTTP = GetHTTP(); + if (!pHTTP) + { + // HTTP manager destroyed - callback won't be called, so Release() here + m_bPendingDownload = false; + m_strStage.clear(); + Release(); + return; + } + + if (pHTTP->CancelDownload(this, &CRemoteMasterServer::StaticDownloadFinished)) + { + m_bPendingDownload = false; + m_strStage.clear(); + Release(); + } + else + { + m_bPendingDownload = false; + m_strStage.clear(); + } } /////////////////////////////////////////////////////////////// @@ -138,7 +184,7 @@ void CRemoteMasterServer::StaticDownloadFinished(const SHttpDownloadResult& resu { CRemoteMasterServer* pRemoteMasterServer = (CRemoteMasterServer*)result.pObj; pRemoteMasterServer->DownloadFinished(result); - pRemoteMasterServer->Release(); // Unkeep alive + pRemoteMasterServer->Release(); // Unkeep alive } /////////////////////////////////////////////////////////////// @@ -150,6 +196,8 @@ void CRemoteMasterServer::StaticDownloadFinished(const SHttpDownloadResult& resu /////////////////////////////////////////////////////////////// void CRemoteMasterServer::DownloadFinished(const SHttpDownloadResult& result) { + m_bPendingDownload = false; + if (result.bSuccess) { if (m_strStage == "waitingreply") @@ -171,7 +219,9 @@ void CRemoteMasterServer::DownloadFinished(const SHttpDownloadResult& result) /////////////////////////////////////////////////////////////// bool CRemoteMasterServer::HasData() { - GetHTTP()->ProcessQueuedFiles(); + CNetHTTPDownloadManagerInterface* pHTTP = GetHTTP(); + if (pHTTP) + pHTTP->ProcessQueuedFiles(); return m_strStage == "hasdata"; } @@ -299,10 +349,12 @@ bool CRemoteMasterServer::ParseListVer0(CServerListItemList& itemList) uint uiNumServersBefore = itemList.size(); #endif + uint uiTieBreakCounter = 0; + while (!stream.AtEnd(6) && usCount--) { - in_addr Address; // IP-address - unsigned short usQueryPort; // Query port + in_addr Address; // IP-address + unsigned short usQueryPort; // Query port stream.Read(Address.S_un.S_un_b.s_b1); stream.Read(Address.S_un.S_un_b.s_b2); @@ -313,6 +365,14 @@ bool CRemoteMasterServer::ParseListVer0(CServerListItemList& itemList) // Add or find item to update CServerListItem* pItem = GetServerListItem(itemList, Address, usQueryPort - SERVER_LIST_QUERY_PORT_OFFSET); + if (pItem->uiTieBreakPosition != uiTieBreakCounter) + { + pItem->uiTieBreakPosition = uiTieBreakCounter; + pItem->strTieBreakSortKey = SString("%04d", pItem->uiTieBreakPosition); + pItem->uiRevision++; + } + uiTieBreakCounter++; + if (pItem->ShouldAllowDataQuality(SERVER_INFO_ASE_0)) { pItem->SetDataQuality(SERVER_INFO_ASE_0); @@ -395,15 +455,17 @@ bool CRemoteMasterServer::ParseListVer2(CServerListItemList& itemList) uint uiNumServersBefore = itemList.size(); #endif + uint uiTieBreakCounter = 0; + // Add all servers until we hit the count or run out of data while (!stream.AtEnd(6) && uiCount--) { - ushort usLength = 0; // Length of data for this server + ushort usLength = 0; // Length of data for this server stream.Read(usLength); uint uiSkipPos = stream.Tell() + usLength - 2; - in_addr Address; // IP-address - unsigned short usGamePort; // Game port + in_addr Address; // IP-address + unsigned short usGamePort; // Game port stream.Read(Address.S_un.S_addr); stream.Read(usGamePort); @@ -411,10 +473,21 @@ bool CRemoteMasterServer::ParseListVer2(CServerListItemList& itemList) // Add or find item to update CServerListItem* pItem = GetServerListItem(itemList, Address, usGamePort); + if (pItem->uiTieBreakPosition != uiTieBreakCounter) + { + pItem->uiTieBreakPosition = uiTieBreakCounter; + pItem->strTieBreakSortKey = SString("%04d", pItem->uiTieBreakPosition); + pItem->uiRevision++; + } + uiTieBreakCounter++; + if (pItem->ShouldAllowDataQuality(uiDataQuality)) { pItem->SetDataQuality(uiDataQuality); + // Remember previous no-response + bool bWasPreviouslyMarkedNoResponse = pItem->bMasterServerSaysNoResponse; + if (bHasPlayerCount) stream.Read(pItem->nPlayers); if (bHasMaxPlayerCount) @@ -453,6 +526,11 @@ bool CRemoteMasterServer::ParseListVer2(CServerListItemList& itemList) { stream.Read(pItem->bMasterServerSaysNoResponse); } + else if (bWasPreviouslyMarkedNoResponse) + { + // Reset no-response flag when server reappears in master list without responding flag + pItem->bMasterServerSaysNoResponse = false; + } if (bHasRestrictionFlags) { diff --git a/Client/core/ServerBrowser/CServerBrowser.RemoteMasterServer.h b/Client/core/ServerBrowser/CServerBrowser.RemoteMasterServer.h index b17f3afa3fa..1fc5697d97a 100644 --- a/Client/core/ServerBrowser/CServerBrowser.RemoteMasterServer.h +++ b/Client/core/ServerBrowser/CServerBrowser.RemoteMasterServer.h @@ -16,6 +16,7 @@ class CRemoteMasterServerInterface : public CRefCountable virtual void Refresh() = 0; virtual bool HasData() = 0; virtual bool ParseList(CServerListItemList& itemList) = 0; + virtual void Cancel() = 0; }; CRemoteMasterServerInterface* NewRemoteMasterServer(const SString& strURL); diff --git a/Client/core/ServerBrowser/CServerBrowser.cpp b/Client/core/ServerBrowser/CServerBrowser.cpp index 61c5b0e2241..a4025b8417a 100644 --- a/Client/core/ServerBrowser/CServerBrowser.cpp +++ b/Client/core/ServerBrowser/CServerBrowser.cpp @@ -10,6 +10,10 @@ *****************************************************************************/ #include "StdInc.h" +#include +#include +#include +#include #include "CServerCache.h" using namespace std; @@ -19,21 +23,39 @@ extern CCore* g_pCore; template <> CServerBrowser* CSingleton::m_pSingleton = NULL; -#define SB_SPAN 0.85f // How much % of the screen the server browser should fill -#define SB_NAVBAR_SIZE_Y 40 // Navbar button size -#define SB_BUTTON_SIZE_X 26 -#define SB_BUTTON_SIZE_Y 26 -#define SB_SPACER 10 // Spacer between searchbar and navbar -#define SB_SMALL_SPACER 5 -#define SB_SEARCHBAR_COMBOBOX_SIZE_X 45 // Mow much the search type combobox occupies of searchbar +#define SB_SPAN 0.85f // How much % of the screen the server browser should fill +#define SB_NAVBAR_SIZE_Y 40 // Navbar button size +#define SB_BUTTON_SIZE_X 26 +#define SB_BUTTON_SIZE_Y 26 +#define SB_SPACER 10 // Spacer between searchbar and navbar +#define SB_SMALL_SPACER 5 +#define SB_SEARCHBAR_COMBOBOX_SIZE_X 45 // Mow much the search type combobox occupies of searchbar #define SB_SEARCHBAR_COMBOBOX_SIZE_Y 22 -#define SB_PLAYERLIST_SIZE_X 200 // Width of players list [NB. adjusted for low resolutions in CServerBrowser::CreateTab] -#define SB_BACK_BUTTON_SIZE_Y 40 // Size of the back butt -#define COMBOBOX_ARROW_SIZE_X 23 // Fixed CEGUI size of the 'combobox' arrow -#define TAB_SIZE_Y 25 // Fixed CEGUI size of the Tab in a tab panel +#define SB_PLAYERLIST_SIZE_X 200 // Width of players list [NB. adjusted for low resolutions in CServerBrowser::CreateTab] +#define SB_BACK_BUTTON_SIZE_Y 40 // Size of the back butt +#define COMBOBOX_ARROW_SIZE_X 23 // Fixed CEGUI size of the 'combobox' arrow +#define TAB_SIZE_Y 25 // Fixed CEGUI size of the Tab in a tab panel #define CONNECT_HISTORY_LIMIT 20 +namespace +{ + constexpr unsigned long SERVER_BROWSER_CONFIG_SAVE_DELAY = 250UL; // Delay (ms) before committing queued config saves + constexpr unsigned long SERVER_BROWSER_CONFIG_SAVE_VISIBLE_GRACE = 5000UL; // Extra delay (ms) before writing while UI is visible + constexpr unsigned long SERVER_BROWSER_FILTER_UPDATE_DELAY = 50UL; // Delay (ms) before applying search filter changes + constexpr std::size_t SERVER_BROWSER_FILTER_UPDATE_BATCH_SIZE = 250U; // Servers processed per frame during deferred rebuild + constexpr std::size_t SERVER_BROWSER_SLOW_BATCH_MIN = 10; + constexpr std::size_t SERVER_BROWSER_SLOW_BATCH_DIVISOR = 6; + constexpr std::size_t SERVER_BROWSER_HIDDEN_REFRESH_MULTIPLIER = 6; + constexpr std::size_t SERVER_BROWSER_FAST_BATCH_MULTIPLIER = 2; + constexpr int SERVER_BROWSER_SPEED_SLOW = 0; + constexpr int SERVER_BROWSER_SPEED_DEFAULT = 1; + constexpr int SERVER_BROWSER_SPEED_FAST = 2; + constexpr unsigned long SERVER_BROWSER_LAZY_LAYOUT_INTERVAL_DEFAULT = 100UL; // Minimum ms between GUI ForceUpdate while refreshing + constexpr unsigned long SERVER_BROWSER_HIDDEN_REFRESH_DELAY = 200UL; // Delay (ms) before using hidden refresh acceleration + constexpr unsigned long SERVER_BROWSER_REFRESH_FRAME_BUDGET_MS = 33; // Time budget per frame for refresh batching (increased for faster filtering) +} + // // Local helper // @@ -60,12 +82,94 @@ CServerBrowser::CServerBrowser() m_uiIsUsingTempTab = 0; m_BeforeTempServerBrowserType = ServerBrowserTypes::INTERNET; m_llLastGeneralHelpTime = 0; + m_bPendingConfigSave = false; + m_ulNextConfigSaveTime = 0; + m_bHistoryListDirty = true; + m_ulHiddenRefreshBoostEnableTime = 0; + + m_pFrame = nullptr; + m_pTopWindow = nullptr; + m_pPanel = nullptr; + m_pLockedIcon = nullptr; + m_pQuickConnectHelpWindow = nullptr; + m_pGeneralHelpWindow = nullptr; + + for (std::size_t i = 0; i < std::size(m_pSearchIcons); ++i) + { + m_pSearchIcons[i] = nullptr; + m_szSearchTypePath[i] = nullptr; + } + + for (std::size_t i = 0; i < std::size(m_pTab); ++i) + { + m_pTab[i] = nullptr; + m_pServerList[i] = nullptr; + m_pServerListRevision[i] = 0; + m_pServerPlayerListLabel[i] = nullptr; + m_pServerPlayerList[i] = nullptr; + m_pEditServerSearch[i] = nullptr; + m_pServerSearchIcon[i] = nullptr; + m_pLabelInclude[i] = nullptr; + m_pIncludeEmpty[i] = nullptr; + m_pIncludeFull[i] = nullptr; + m_pIncludeLocked[i] = nullptr; + m_pIncludeOffline[i] = nullptr; + m_pIncludeOtherVersions[i] = nullptr; + m_pButtonConnect[i] = nullptr; + m_pButtonConnectIcon[i] = nullptr; + m_pButtonRefresh[i] = nullptr; + m_pButtonRefreshIcon[i] = nullptr; + m_pButtonInfo[i] = nullptr; + m_pButtonInfoIcon[i] = nullptr; + m_pButtonFavourites[i] = nullptr; + m_pEditAddress[i] = nullptr; + m_pLabelAddressDescription[i] = nullptr; + m_pComboAddressHistory[i] = nullptr; + m_pSearchTypeIcon[i] = nullptr; + m_pAddressFavoriteIcon[i] = nullptr; + m_pRemoveFromRecentIcon[i] = nullptr; + m_pComboSearchType[i] = nullptr; + m_pEditSearch[i] = nullptr; + m_pLabelSearchDescription[i] = nullptr; + m_pLabelPassword[i] = nullptr; + m_pEditPassword[i] = nullptr; + m_pServerListStatus[i] = nullptr; + m_pButtonBack[i] = nullptr; + m_pButtonGeneralHelp[i] = nullptr; + m_iSelectedServer[i] = -1; + m_hVersion[i] = CGUIHandle(); + m_hLocked[i] = CGUIHandle(); + m_hName[i] = CGUIHandle(); + m_hPing[i] = CGUIHandle(); + m_hPlayers[i] = CGUIHandle(); + m_hHost[i] = CGUIHandle(); + m_hGame[i] = CGUIHandle(); + m_hMap[i] = CGUIHandle(); + m_hPlayerName[i] = CGUIHandle(); + m_FlashSearchBox[i].uiCount = 0; + m_FlashSearchBox[i].uiNextTime = 0; + m_bInitialRefreshDone[i] = false; + m_bPendingRefresh[i] = false; + m_bPendingFilterUpdate[i] = false; + m_ulNextFilterUpdateTime[i] = 0; + m_FilterState[i].searchText.clear(); + m_FilterState[i].searchType = -1; + m_FilterState[i].includeEmpty = false; + m_FilterState[i].includeFull = false; + m_FilterState[i].includeLocked = false; + m_FilterState[i].includeOffline = false; + m_FilterState[i].includeOtherVersions = false; + m_ListRefreshState[i].bActive = false; + m_ulNextListLayoutTime[i] = 0; + m_pLastSelectedServerForPlayerList[i] = nullptr; + m_msLastPlayerListQueryRetryTime[i] = std::chrono::milliseconds(0); + } // Do some initial math CVector2D resolution = CCore::GetSingleton().GetGUI()->GetResolution(); bool bCreateFrame = true; - if (resolution.fY <= 600) // Make our window bigger at small resolutions + if (resolution.fY <= 600) // Make our window bigger at small resolutions { m_WidgetSize = CVector2D(resolution.fX, resolution.fY); bCreateFrame = false; @@ -121,7 +225,7 @@ CServerBrowser::CServerBrowser() m_szSearchTypePath[SearchTypes::SERVERS] = "cgui\\images\\serverbrowser\\search-servers.png"; m_szSearchTypePath[SearchTypes::PLAYERS] = "cgui\\images\\serverbrowser\\search-players.png"; - for (unsigned int i = 0; i != SearchTypes::MAX_SEARCH_TYPES; i++) + for (std::size_t i = 0; i < std::size(m_pSearchIcons); ++i) { m_pSearchIcons[i] = reinterpret_cast(pManager->CreateStaticImage()); m_pSearchIcons[i]->SetVisible(false); @@ -138,11 +242,27 @@ CServerBrowser::CServerBrowser() // Load options LoadOptions(CCore::GetSingletonPtr()->GetConfig()->FindSubNode(CONFIG_NODE_SERVER_OPTIONS)); + // Load favorites, recent, and history lists from config + CXMLNode* pConfig = CCore::GetSingletonPtr()->GetConfig(); + LoadServerList(pConfig->FindSubNode(CONFIG_NODE_SERVER_FAV), CONFIG_FAVOURITE_LIST_TAG, GetFavouritesList()); + LoadServerList(pConfig->FindSubNode(CONFIG_NODE_SERVER_REC), CONFIG_RECENT_LIST_TAG, GetRecentList()); + LoadServerList(pConfig->FindSubNode(CONFIG_NODE_SERVER_HISTORY), CONFIG_HISTORY_LIST_TAG, GetHistoryList()); + + CServerCacheInterface* pCache = GetServerCache(); + if (pCache) + { + pCache->GenerateServerList(&m_ServersInternet, true); + pCache->GetServerListCachedInfo(&m_ServersInternet); + pCache->GetServerListCachedInfo(&m_ServersFavourites); + pCache->GetServerListCachedInfo(&m_ServersRecent); + pCache->GetServerListCachedInfo(&m_ServersHistory); + } + // Save the active tab, needs to be done after at least one tab exists m_pPanel->SetSelectionHandler(GUI_CALLBACK(&CServerBrowser::OnTabChanged, this)); // Attach some editbox handlers, also must be done after full creation - for (unsigned int i = 0; i < SERVER_BROWSER_TYPE_COUNT; i++) + for (std::size_t i = 0; i < std::size(m_pEditAddress); ++i) { m_pEditAddress[i]->SetActivateHandler(GUI_CALLBACK(&CServerBrowser::OnAddressFocused, this)); m_pEditAddress[i]->SetDeactivateHandler(GUI_CALLBACK(&CServerBrowser::OnAddressDefocused, this)); @@ -210,7 +330,7 @@ CServerBrowser::CServerBrowser() m_pGeneralHelpWindow->SetDeactivateHandler(GUI_CALLBACK(&CServerBrowser::OnGeneralHelpDeactivate, this)); float fMaxLeft = pManager->CGUI_GetMaxTextExtent("default-normal", _("Refresh"), _("Add Favorite"), _("Connect"), _("Server information")); - float fMaxRight = pManager->CGUI_GetMaxTextExtent("default-normal", _("Search servers"), _("Search players"), _("Start search")); + float fMaxRight = pManager->CGUI_GetMaxTextExtent("default-normal", _("Search servers"), _("Search players"), _("Start search"), _("Delete from recent")); CVector2D generalHelpSize(80 + fMaxLeft + 80 + fMaxRight, 160); CVector2D generalHelpPos = helpButtonPos - generalHelpSize + CVector2D(helpButtonSize.fX, 0); @@ -233,9 +353,10 @@ CServerBrowser::CServerBrowser() {80 + static_cast(fMaxLeft), iBase + iGap * 0 + 5, 29, 16, "cgui\\images\\serverbrowser\\search-servers.png"}, {80 + static_cast(fMaxLeft), iBase + iGap * 1 + 5, 29, 16, "cgui\\images\\serverbrowser\\search-players.png"}, {80 + static_cast(fMaxLeft), iBase + iGap * 2 + 5, 16, 16, "cgui\\images\\serverbrowser\\search.png"}, + {80 + static_cast(fMaxLeft), iBase + iGap * 3 + 5, 16, 16, "cgui\\images\\serverbrowser\\trashcan.png"}, }; - for (uint i = 0; i < NUMELMS(iconInfoList); i++) + for (std::size_t i = 0; i < std::size(iconInfoList); ++i) { CGUIStaticImage* pIcon = reinterpret_cast(pManager->CreateStaticImage(m_pGeneralHelpWindow)); pIcon->SetPosition(CVector2D(iconInfoList[i].x, iconInfoList[i].y)); @@ -256,9 +377,10 @@ CServerBrowser::CServerBrowser() {80 + static_cast(fMaxLeft), iBase + iGap * 0, _("Search servers")}, {80 + static_cast(fMaxLeft), iBase + iGap * 1, _("Search players")}, {80 + static_cast(fMaxLeft), iBase + iGap * 2, _("Start search")}, + {80 + static_cast(fMaxLeft), iBase + iGap * 3, _("Delete from recent")}, }; - for (uint i = 0; i < NUMELMS(helpInfoList); i++) + for (std::size_t i = 0; i < std::size(helpInfoList); ++i) { CGUILabel* pLabel = reinterpret_cast(pManager->CreateLabel(m_pGeneralHelpWindow, "")); pLabel->SetText(SString(" - %s", helpInfoList[i].strDesc.c_str())); @@ -270,9 +392,20 @@ CServerBrowser::CServerBrowser() CServerBrowser::~CServerBrowser() { + // Suspend all server list activity and cancel pending network operations FIRST + // This must be done before DeleteTab() destroys the server lists, and while + // the network subsystem is still available (it may be destroyed before this destructor) + SuspendServerLists(); + // Save options now and disable selection handler - SaveOptions(); - m_pPanel->SetSelectionHandler(nullptr); + SaveOptions(true); + if (m_pPanel) + m_pPanel->SetSelectionHandler(GUI_CALLBACK()); + + // Persist cache to disk before cleanup + CServerCacheInterface* pCache = GetServerCache(); + if (pCache) + pCache->SaveServerCache(true); // Delete the Tabs DeleteTab(ServerBrowserTypes::INTERNET); @@ -280,19 +413,44 @@ CServerBrowser::~CServerBrowser() DeleteTab(ServerBrowserTypes::FAVOURITES); DeleteTab(ServerBrowserTypes::RECENTLY_PLAYED); - // Unload the icon - m_pLockedIcon->Clear(); - for (unsigned int i = 0; i != SearchTypes::MAX_SEARCH_TYPES; i++) - m_pSearchIcons[i]->Clear(); + if (m_pGeneralHelpWindow) + { + m_pGeneralHelpWindow->SetVisible(false); + m_pGeneralHelpWindow->SetDeactivateHandler(GUI_CALLBACK()); // Avoid callbacks during destruction + } + + if (m_pLockedIcon) + { + m_pLockedIcon->Clear(); + SAFE_DELETE(m_pLockedIcon); + } + + for (std::size_t i = 0; i < std::size(m_pSearchIcons); ++i) + { + if (m_pSearchIcons[i]) + { + m_pSearchIcons[i]->Clear(); + SAFE_DELETE(m_pSearchIcons[i]); + } + } + + SAFE_DELETE(m_pQuickConnectHelpWindow); + SAFE_DELETE(m_pGeneralHelpWindow); - // Delete the GUI items - delete m_pTopWindow; + CGUIElement* pTopWindow = m_pTopWindow; + m_pTopWindow = nullptr; + m_pPanel = nullptr; + m_pFrame = nullptr; + SAFE_DELETE(pTopWindow); } void CServerBrowser::CreateTab(ServerBrowserType type, const char* szName) { CGUI* pManager = g_pCore->GetGUI(); + m_bInitialRefreshDone[type] = false; + m_bPendingRefresh[type] = false; + m_pTab[type] = m_pPanel->CreateTab(szName); float fPlayerListSizeX = SB_PLAYERLIST_SIZE_X; @@ -400,7 +558,7 @@ void CServerBrowser::CreateTab(ServerBrowserType type, const char* szName) m_pComboSearchType[type]->SetPosition(CVector2D(fX, fY + (SB_BUTTON_SIZE_Y - SB_SEARCHBAR_COMBOBOX_SIZE_Y) / 2), false); m_pComboSearchType[type]->SetSize(CVector2D(SB_SEARCHBAR_COMBOBOX_SIZE_X, 80), false); - for (unsigned int i = 0; i != SearchTypes::MAX_SEARCH_TYPES; i++) + for (std::size_t i = 0; i < std::size(m_pSearchIcons); ++i) m_pComboSearchType[type]->AddItem(m_pSearchIcons[i]); m_pComboSearchType[type]->SetReadOnly(true); @@ -445,6 +603,7 @@ void CServerBrowser::CreateTab(ServerBrowserType type, const char* szName) m_pServerList[type]->SetSize(CVector2D(fWidth, fHeight), false); m_pServerList[type]->SetIgnoreTextSpacer(true); m_pServerList[type]->SetClickHandler(GUI_CALLBACK(&CServerBrowser::OnClick, this)); + m_pServerList[type]->SetSelectionHandler(GUI_CALLBACK(&CServerBrowser::OnClick, this)); m_pServerListRevision[type] = 0; // Server List Columns @@ -462,7 +621,7 @@ void CServerBrowser::CreateTab(ServerBrowserType type, const char* szName) m_pServerList[type]->SetColumnWidth(m_hPing[type], 35, false); // We give Name and Gamemode 65% and 35% of the remaining length respectively - float fRemainingWidth = fWidth - 25 - 16 - 70 - 35 - 50; // All the fixed sizes plus 50 for the scrollbar + float fRemainingWidth = fWidth - 25 - 16 - 70 - 35 - 50; // All the fixed sizes plus 50 for the scrollbar m_pServerList[type]->SetColumnWidth(m_hGame[type], fRemainingWidth * 0.35, false); m_pServerList[type]->SetColumnWidth(m_hName[type], fRemainingWidth * 0.65, false); @@ -477,10 +636,14 @@ void CServerBrowser::CreateTab(ServerBrowserType type, const char* szName) // Player List Columns m_hPlayerName[type] = m_pServerPlayerList[type]->AddColumn(_("Player list"), 0.75f); + // Create a companion label now so the destructor can safely clean it up later. + m_pServerPlayerListLabel[type] = reinterpret_cast(pManager->CreateLabel(m_pTab[type], "")); + m_pServerPlayerListLabel[type]->SetVisible(false); + // Filters float fLineHeight = SB_BACK_BUTTON_SIZE_Y / 2; fX = SB_SMALL_SPACER; - fY = m_WidgetSize.fY - SB_SMALL_SPACER / 2 - SB_BACK_BUTTON_SIZE_Y - TAB_SIZE_Y; + fY = m_WidgetSize.fY - (SB_SMALL_SPACER * 0.5f) - SB_BACK_BUTTON_SIZE_Y - TAB_SIZE_Y; // Include label m_pLabelInclude[type] = reinterpret_cast(pManager->CreateLabel(m_pTab[type], _("Include:"))); @@ -574,6 +737,12 @@ void CServerBrowser::CreateTab(ServerBrowserType type, const char* szName) m_pServerList[type]->SetEnterKeyHandler(GUI_CALLBACK(&CServerBrowser::OnDoubleClick, this)); m_pServerList[type]->SetDoubleClickHandler(GUI_CALLBACK(&CServerBrowser::OnDoubleClick, this)); m_pServerList[type]->SetKeyDownHandler(GUI_CALLBACK_KEY(&CServerBrowser::OnServerListKeyDown, this)); + // Track the user sorting actions so we can preserve the sort state while + // rebuilding the list (e.g. while filtering). This avoids the visual + // behaviour where the sort disappears when the filter is applied. + m_pServerList[type]->SetSortColumnHandler(GUI_CALLBACK(&CServerBrowser::OnServerListSortChanged, this)); + // Record initial sort (if any) so it can be reapplied by the list refresh + UpdateSortState(type); // If any of the include checkboxes overlap with the help/back buttons, we move them down - next to the status bar. CVector2D vecButtonPos = m_pButtonGeneralHelp[type]->GetPosition(); @@ -585,47 +754,215 @@ void CServerBrowser::CreateTab(ServerBrowserType type, const char* szName) for (std::vector::iterator iter = pCheckBox.begin(); iter != pCheckBox.end(); ++iter) if ((*iter) != NULL && (((*iter)->GetPosition(false).fX + (*iter)->GetSize(false).fX) > vecButtonPos.fX)) (*iter)->SetPosition(CVector2D(fMoveX += -SB_SPACER - (*iter)->GetSize(false).fX, m_pServerListStatus[type]->GetPosition().fY)); + + m_FilterState[type] = CaptureFilterState(type); } void CServerBrowser::DeleteTab(ServerBrowserType type) { - delete m_pButtonConnect[type]; - delete m_pButtonRefresh[type]; + if (m_pButtonConnect[type]) + { + m_pButtonConnect[type]->SetClickHandler(GUI_CALLBACK()); + delete m_pButtonConnect[type]; + m_pButtonConnect[type] = nullptr; + } + + if (m_pButtonRefresh[type]) + { + m_pButtonRefresh[type]->SetClickHandler(GUI_CALLBACK()); + delete m_pButtonRefresh[type]; + m_pButtonRefresh[type] = nullptr; + } + + if (m_pEditAddress[type]) + { + m_pEditAddress[type]->SetTextAcceptedHandler(GUI_CALLBACK()); + m_pEditAddress[type]->SetTextChangedHandler(GUI_CALLBACK()); + m_pEditAddress[type]->SetActivateHandler(GUI_CALLBACK()); + m_pEditAddress[type]->SetDeactivateHandler(GUI_CALLBACK()); + delete m_pEditAddress[type]; + m_pEditAddress[type] = nullptr; + } + + if (m_pComboSearchType[type]) + { + m_pComboSearchType[type]->SetSelectionHandler(GUI_CALLBACK()); + delete m_pComboSearchType[type]; + m_pComboSearchType[type] = nullptr; + } - delete m_pEditAddress[type]; - delete m_pComboSearchType[type]; delete m_pSearchTypeIcon[type]; + m_pSearchTypeIcon[type] = nullptr; + delete m_pServerSearchIcon[type]; + m_pServerSearchIcon[type] = nullptr; + delete m_pButtonInfoIcon[type]; + m_pButtonInfoIcon[type] = nullptr; + delete m_pButtonConnectIcon[type]; + m_pButtonConnectIcon[type] = nullptr; + + if (m_pComboAddressHistory[type]) + { + m_pComboAddressHistory[type]->SetSelectionHandler(GUI_CALLBACK()); + m_pComboAddressHistory[type]->SetDropListRemoveHandler(GUI_CALLBACK()); + delete m_pComboAddressHistory[type]; + m_pComboAddressHistory[type] = nullptr; + } - // Remove handler to prevent unwanted events during delete - m_pComboAddressHistory[type]->SetDropListRemoveHandler(NULL); - delete m_pComboAddressHistory[type]; + if (m_pLabelAddressDescription[type]) + { + delete m_pLabelAddressDescription[type]; + m_pLabelAddressDescription[type] = nullptr; + } + + if (m_pAddressFavoriteIcon[type]) + { + m_pAddressFavoriteIcon[type]->SetClickHandler(GUI_CALLBACK()); + delete m_pAddressFavoriteIcon[type]; + m_pAddressFavoriteIcon[type] = nullptr; + } - delete m_pAddressFavoriteIcon[type]; if (type == ServerBrowserTypes::RECENTLY_PLAYED) - delete m_pRemoveFromRecentIcon[type]; - delete m_pEditSearch[type]; + { + if (m_pRemoveFromRecentIcon[type]) + { + m_pRemoveFromRecentIcon[type]->SetClickHandler(GUI_CALLBACK()); + delete m_pRemoveFromRecentIcon[type]; + m_pRemoveFromRecentIcon[type] = nullptr; + } + } + + if (m_pEditSearch[type]) + { + m_pEditSearch[type]->SetTextChangedHandler(GUI_CALLBACK()); + m_pEditSearch[type]->SetActivateHandler(GUI_CALLBACK()); + m_pEditSearch[type]->SetDeactivateHandler(GUI_CALLBACK()); + delete m_pEditSearch[type]; + m_pEditSearch[type] = nullptr; + } + + if (m_pLabelSearchDescription[type]) + { + delete m_pLabelSearchDescription[type]; + m_pLabelSearchDescription[type] = nullptr; + } + delete m_pButtonRefreshIcon[type]; + m_pButtonRefreshIcon[type] = nullptr; delete m_pLabelInclude[type]; - delete m_pIncludeEmpty[type]; - delete m_pIncludeFull[type]; - delete m_pIncludeLocked[type]; - delete m_pIncludeOtherVersions[type]; + m_pLabelInclude[type] = nullptr; + + if (m_pIncludeEmpty[type]) + { + m_pIncludeEmpty[type]->SetClickHandler(GUI_CALLBACK()); + delete m_pIncludeEmpty[type]; + m_pIncludeEmpty[type] = nullptr; + } + + if (m_pIncludeFull[type]) + { + m_pIncludeFull[type]->SetClickHandler(GUI_CALLBACK()); + delete m_pIncludeFull[type]; + m_pIncludeFull[type] = nullptr; + } + + if (m_pIncludeLocked[type]) + { + m_pIncludeLocked[type]->SetClickHandler(GUI_CALLBACK()); + delete m_pIncludeLocked[type]; + m_pIncludeLocked[type] = nullptr; + } + + if (m_pIncludeOtherVersions[type]) + { + m_pIncludeOtherVersions[type]->SetClickHandler(GUI_CALLBACK()); + delete m_pIncludeOtherVersions[type]; + m_pIncludeOtherVersions[type] = nullptr; + } if (m_pIncludeOffline[type]) { + m_pIncludeOffline[type]->SetClickHandler(GUI_CALLBACK()); delete m_pIncludeOffline[type]; + m_pIncludeOffline[type] = nullptr; + } + + if (m_pLabelPassword[type]) + { + delete m_pLabelPassword[type]; + m_pLabelPassword[type] = nullptr; + } + + if (m_pEditPassword[type]) + { + m_pEditPassword[type]->SetTextAcceptedHandler(GUI_CALLBACK()); + m_pEditPassword[type]->SetTextChangedHandler(GUI_CALLBACK()); + delete m_pEditPassword[type]; + m_pEditPassword[type] = nullptr; } delete m_pServerPlayerList[type]; + m_pServerPlayerList[type] = nullptr; delete m_pServerListStatus[type]; + m_pServerListStatus[type] = nullptr; + + if (m_pServerPlayerListLabel[type]) + { + delete m_pServerPlayerListLabel[type]; + m_pServerPlayerListLabel[type] = nullptr; + } + + if (m_pButtonInfo[type]) + { + m_pButtonInfo[type]->SetClickHandler(GUI_CALLBACK()); + delete m_pButtonInfo[type]; + m_pButtonInfo[type] = nullptr; + } + + if (m_pButtonBack[type]) + { + m_pButtonBack[type]->SetClickHandler(GUI_CALLBACK()); + delete m_pButtonBack[type]; + m_pButtonBack[type] = nullptr; + } + + if (m_pButtonFavourites[type]) + { + m_pButtonFavourites[type]->SetClickHandler(GUI_CALLBACK()); + delete m_pButtonFavourites[type]; + m_pButtonFavourites[type] = nullptr; + } + + if (m_pButtonGeneralHelp[type]) + { + m_pButtonGeneralHelp[type]->SetClickHandler(GUI_CALLBACK()); + delete m_pButtonGeneralHelp[type]; + m_pButtonGeneralHelp[type] = nullptr; + } + + if (m_pServerList[type]) + { + m_pServerList[type]->SetEnterKeyHandler(GUI_CALLBACK()); + m_pServerList[type]->SetDoubleClickHandler(GUI_CALLBACK()); + m_pServerList[type]->SetKeyDownHandler(GUI_CALLBACK_KEY()); + m_pServerList[type]->SetSortColumnHandler(GUI_CALLBACK()); + m_pServerList[type]->SetSelectionHandler(GUI_CALLBACK()); + delete m_pServerList[type]; + m_pServerList[type] = nullptr; + } + + if (m_pTab[type]) + { + delete m_pTab[type]; + m_pTab[type] = nullptr; + } - delete m_pServerList[type]; - delete m_pTab[type]; + m_bInitialRefreshDone[type] = false; + m_bPendingRefresh[type] = false; } ServerBrowserType CServerBrowser::GetCurrentServerBrowserTypeForSave() @@ -661,11 +998,63 @@ ServerBrowserType CServerBrowser::GetCurrentServerBrowserType() return currentServerBrowserType; } +void CServerBrowser::EnsureRefreshFor(ServerBrowserType type, bool bAutoRefreshEnabled, bool bForceOnFirstView) +{ + const auto index = static_cast(type); + if (index >= std::size(m_pServerListStatus)) + return; + + if (auto* statusLabel = m_pServerListStatus[index]; statusLabel == nullptr) + return; + + const bool bNeedsInitialRefresh = !m_bInitialRefreshDone[index]; + if (!bNeedsInitialRefresh && !bAutoRefreshEnabled && !bForceOnFirstView) + return; + + m_pServerListStatus[index]->SetText(_("Loading...")); + m_iSelectedServer[index] = -1; + m_bPendingRefresh[index] = true; +} + +void CServerBrowser::StartRefresh(ServerBrowserType type) +{ + const auto index = static_cast(type); + if (index >= std::size(m_pServerListStatus)) + return; + + if (auto* pList = GetServerList(type)) + { + if (m_pServerListStatus[index]) + m_pServerListStatus[index]->SetText(_("Loading...")); + + m_iSelectedServer[index] = -1; + m_bPendingRefresh[index] = false; + + // Cancel any in-progress batch refresh to prevent iterator invalidation + // when pList->Refresh() calls Clear() on the server list + m_ListRefreshState[index].bActive = false; + m_ListRefreshState[index].pList = nullptr; + m_ListRefreshState[index].filterSnapshot.reset(); + + pList->Refresh(); + m_bInitialRefreshDone[index] = true; + } +} + void CServerBrowser::Update() { ServerBrowserType Type = GetCurrentServerBrowserType(); CServerList* pList = GetServerList(Type); + if (IsVisible()) + { + for (std::size_t i = 0; i < std::size(m_bPendingRefresh); ++i) + { + if (m_bPendingRefresh[i]) + StartRefresh(static_cast(i)); + } + } + if (m_bFocusTextEdit) { m_bFocusTextEdit = false; @@ -682,7 +1071,8 @@ void CServerBrowser::Update() } // If an update is needed, the serverbrowser is visible and it has gone some time since last update - if ((pList->IsUpdated() || m_PrevServerBrowserType != Type) && m_ulLastUpdateTime < CClientTime::GetTime() - SERVER_BROWSER_UPDATE_INTERVAL) + if (IsVisible() && !IsListRefreshInProgress(Type) && (pList->IsUpdated() || m_PrevServerBrowserType != Type) && + m_ulLastUpdateTime < CClientTime::GetTime() - SERVER_BROWSER_UPDATE_INTERVAL) { // Update the GUI UpdateServerList(Type, Type == ServerBrowserTypes::RECENTLY_PLAYED); @@ -710,6 +1100,27 @@ void CServerBrowser::Update() m_FlashSearchBox[Type].uiNextTime = GetTickCount32() + 100; } } + + if (IsVisible()) + { + unsigned long ulNow = CClientTime::GetTime(); + for (std::size_t i = 0; i < std::size(m_bPendingFilterUpdate); ++i) + { + if (m_bPendingFilterUpdate[i] && ulNow >= m_ulNextFilterUpdateTime[i]) + { + m_bPendingFilterUpdate[i] = false; + m_ulNextFilterUpdateTime[i] = 0; + ServerBrowserType queuedType = static_cast(i); + const auto batchSize = GetListRefreshBatchSize(); + BeginServerListRefresh(queuedType, true, true); + ProcessServerListRefreshBatch(queuedType, batchSize); + } + } + + ProcessPendingListRefreshes(); + } + + ProcessPendingConfigSave(); } void CServerBrowser::SetVisible(bool bVisible) @@ -731,20 +1142,31 @@ void CServerBrowser::SetVisible(bool bVisible) { bool bAutoRefresh = false; CVARS_GET("auto_refresh_browser", bAutoRefresh); + ServerBrowserType currentType = GetCurrentServerBrowserType(); + + for (std::size_t i = 0; i < std::size(m_pTab); ++i) + { + const auto type = static_cast(i); + const bool bForceInitialRefresh = m_bFirstTimeBrowseServer && type == currentType; + EnsureRefreshFor(type, bAutoRefresh, bForceInitialRefresh); + } - // Start loading all servers (if needed). - for (unsigned int i = 0; i < SERVER_BROWSER_TYPE_COUNT; i++) + // Start refresh for current tab immediately to avoid first-display timing issues + if (m_bPendingRefresh[currentType]) + StartRefresh(currentType); + + // Populate GUI immediately from available data (cache or fresh) + if (CServerList* pCurrentList = GetServerList(currentType)) { - // Don't refresh Internet unless it's activated or needed. - if (i != ServerBrowserTypes::INTERNET || m_bFirstTimeBrowseServer || bAutoRefresh) + if (pCurrentList->GetServerCount() > 0 || pCurrentList->IsUpdated()) { - m_pServerListStatus[i]->SetText(_("Loading...")); - m_iSelectedServer[i] = -1; - GetServerList((ServerBrowserType)i)->Refresh(); + UpdateServerList(currentType, currentType == ServerBrowserTypes::RECENTLY_PLAYED); + m_ulLastUpdateTime = CClientTime::GetTime(); } } - CreateHistoryList(); + if (m_bHistoryListDirty) + CreateHistoryList(); if (m_bFirstTimeBrowseServer) m_bFirstTimeBrowseServer = false; @@ -762,11 +1184,13 @@ void CServerBrowser::SetVisible(bool bVisible) m_pEditAddress[Type]->SetCaretAtEnd(); // Flash search box if it is not empty - for (uint i = 0; i < SERVER_BROWSER_TYPE_COUNT; i++) + for (std::size_t i = 0; i < std::size(m_FlashSearchBox); ++i) { - m_FlashSearchBox[i].uiCount = m_pEditSearch[i]->GetText().empty() ? 0 : 15; - m_FlashSearchBox[Type].uiNextTime = 0; + m_FlashSearchBox[i].uiCount = m_pEditSearch[i]->GetText().empty() ? 0U : 15U; } + m_FlashSearchBox[Type].uiNextTime = 0; + + m_ulHiddenRefreshBoostEnableTime = CClientTime::GetTime() + SERVER_BROWSER_HIDDEN_REFRESH_DELAY; } else { @@ -775,14 +1199,19 @@ void CServerBrowser::SetVisible(bool bVisible) m_pQuickConnectHelpWindow->SetVisible(false); CServerInfo::GetSingletonPtr()->Hide(); - for (uint i = 0; i < SERVER_BROWSER_TYPE_COUNT; i++) + for (std::size_t i = 0; i < std::size(m_FlashSearchBox); ++i) { m_FlashSearchBox[i].uiCount = 0; } + + m_ulHiddenRefreshBoostEnableTime = CClientTime::GetTime() + SERVER_BROWSER_HIDDEN_REFRESH_DELAY; + + SuspendServerLists(); + ProcessPendingConfigSave(); } } -bool CServerBrowser::IsVisible() +bool CServerBrowser::IsVisible() const { return m_pTopWindow && m_pTopWindow->IsVisible(); } @@ -806,104 +1235,14 @@ bool CServerBrowser::CanBrowseVersion(const SString& strVersion) void CServerBrowser::UpdateServerList(ServerBrowserType Type, bool bClearServerList) { - GetVersionUpdater()->GetBrowseVersionMaps(m_blockedVersionMap, m_allowedVersionMap); - -#if MTA_DEBUG - // Selecting 'Nightly update' in debug build will show other versions - SString strUpdateBuildType; - CVARS_GET("update_build_type", strUpdateBuildType); - if (strUpdateBuildType == "2") - { - m_blockedVersionMap.clear(); - m_allowedVersionMap.clear(); - } -#endif - - // Setting this in coreconfig will show other versions - bool bForceBrowseOtherVersions = false; - CVARS_GET("force_browse_other_versions", bForceBrowseOtherVersions); - if (bForceBrowseOtherVersions) - { - m_blockedVersionMap.clear(); - m_allowedVersionMap.clear(); - } - - // Save sort info - uint uiSortColumn; - SortDirection sortDirection; - m_pServerList[Type]->GetSort(uiSortColumn, sortDirection); - - // Disable sorting - m_pServerList[Type]->Sort(uiSortColumn, SortDirections::None); - - // Get the appropriate server list - CServerList* pList = GetServerList(Type); - - bool bGetListsCleared = pList->GetRevision() != m_pServerListRevision[Type] || bClearServerList; - if (bGetListsCleared) - { - m_pServerListRevision[Type] = pList->GetRevision(); - - // Clear current list - m_pServerList[Type]->Clear(); - - // Clear the player lists - m_pServerPlayerList[Type]->Clear(); - } - - bool didUpdateRowIndices = false; - - // Loop the server list - for (CServerListIterator it = pList->IteratorBegin(); it != pList->IteratorEnd(); it++) - { - CServerListItem* pServer = *it; - - if (bGetListsCleared) - pServer->iRowIndex = -1; - - // Find info from server cache for favourites and recent - if (Type == ServerBrowserType::FAVOURITES || Type == ServerBrowserType::RECENTLY_PLAYED) - GetServerCache()->GetServerCachedInfo(pServer); - - // Add/update/remove the item to the list - if (pServer->revisionInList[Type] != pServer->uiRevision || bClearServerList) - { - if (!didUpdateRowIndices) - { - UpdateRowIndexMembers(Type); - didUpdateRowIndices = true; - } - - pServer->revisionInList[Type] = pServer->uiRevision; - AddServerToList(pServer, Type); - } - } - bool bIncludeOtherVersions = m_pIncludeOtherVersions[Type]->GetSelected(); - ServerBrowserType type = Type; - - if (bIncludeOtherVersions) - { - m_pServerList[type]->SetColumnWidth(1, 34, false); - } - else - { - m_pServerList[type]->SetColumnWidth(1, 0.03f, true); - } - - // Re-enable sorting - m_pServerList[Type]->Sort(uiSortColumn, sortDirection); - - m_pServerList[Type]->ForceUpdate(); - pList->SetUpdated(false); - - if (Type == ServerBrowserTypes::RECENTLY_PLAYED) - m_pRemoveFromRecentIcon[Type]->SetAlpha(0.3f); + BeginServerListRefresh(Type, bClearServerList, false); + ProcessServerListRefreshBatch(Type, GetListRefreshBatchSize()); } void CServerBrowser::CreateHistoryList() { // Clear our combo boxes first - for (unsigned int i = 0; i < SERVER_BROWSER_TYPE_COUNT; i++) + for (std::size_t i = 0; i < std::size(m_pComboAddressHistory); ++i) { m_pComboAddressHistory[i]->Clear(); } @@ -917,7 +1256,7 @@ void CServerBrowser::CreateHistoryList() if (pServer->strEndpoint) { bEmpty = false; - for (unsigned int i = 0; i < SERVER_BROWSER_TYPE_COUNT; i++) + for (std::size_t i = 0; i < std::size(m_pComboAddressHistory); ++i) { m_pComboAddressHistory[i]->AddItem(("mtasa://" + pServer->strEndpoint).c_str())->SetData(pServer->strEndpoint.c_str()); } @@ -925,12 +1264,13 @@ void CServerBrowser::CreateHistoryList() } m_ServersHistory.Refresh(); + m_bHistoryListDirty = false; } void CServerBrowser::UpdateHistoryList() { // Assume our type is 0, then update all fields when appropriate - unsigned int Type = 0; + std::size_t Type = 0; // Look through our combo box and process each item CGUIComboBox* pServerList = m_pComboAddressHistory[Type]; @@ -946,9 +1286,9 @@ void CServerBrowser::UpdateHistoryList() CServerListItem* pServer = *it; if (pServer->strEndpoint == szAddress) { - if (pServer->strEndpoint != pServer->strName) // Do we have a real name for the server? + if (pServer->strEndpoint != pServer->strName) // Do we have a real name for the server? { - for (unsigned int index = 0; index < SERVER_BROWSER_TYPE_COUNT; index++) + for (std::size_t index = 0; index < std::size(m_pComboAddressHistory); ++index) { m_pComboAddressHistory[index]->SetItemText(i, ("mtasa://" + pServer->strEndpoint + " | " + pServer->strName).c_str()); } @@ -959,17 +1299,18 @@ void CServerBrowser::UpdateHistoryList() } } -void CServerBrowser::AddServerToList(CServerListItem* pServer, const ServerBrowserType Type) +void CServerBrowser::AddServerToList(CServerListItem* pServer, ServerBrowserType Type, const SFilterState& filterState) { - bool bIncludeEmpty = m_pIncludeEmpty[Type]->GetSelected(); - bool bIncludeFull = m_pIncludeFull[Type]->GetSelected(); - bool bIncludeLocked = m_pIncludeLocked[Type]->GetSelected(); - bool bIncludeOffline = m_pIncludeOffline[Type] && m_pIncludeOffline[Type]->GetSelected(); - bool bIncludeOtherVersions = m_pIncludeOtherVersions[Type]->GetSelected(); + const bool bIncludeEmpty = filterState.includeEmpty; + const bool bIncludeFull = filterState.includeFull; + const bool bIncludeLocked = filterState.includeLocked; + const bool bIncludeOffline = filterState.includeOffline; + const bool bIncludeOtherVersions = filterState.includeOtherVersions; + const std::string& strServerSearchText = filterState.searchText; + const int iCurrentSearchType = filterState.searchType; + bool bServerSearchFound = true; - std::string strServerSearchText = m_pEditSearch[Type]->GetText(); - int iCurrentSearchType = m_pComboSearchType[Type]->GetSelectedItemIndex(); if (!strServerSearchText.empty()) { if (iCurrentSearchType == SearchTypes::SERVERS) @@ -985,7 +1326,7 @@ void CServerBrowser::AddServerToList(CServerListItem* pServer, const ServerBrows if (pServer->nPlayers > 0) { // Search for the search text in the names of the players in the server - for (unsigned int i = 0; i < pServer->vecPlayers.size(); i++) + for (std::size_t i = 0; i < pServer->vecPlayers.size(); ++i) { SString strPlayerName = pServer->vecPlayers[i]; @@ -1016,9 +1357,12 @@ void CServerBrowser::AddServerToList(CServerListItem* pServer, const ServerBrows bool bIsBlockedVersion = bIsOtherVersion && !CanBrowseVersion(pServer->strVersion); bool bIsBlockedServer = (pServer->uiMasterServerSaysRestrictions & RESTRICTION_BLOCK_SERVER) != false; - if ((!pServer->strVersion.empty() || bIsOffline) && (!bLowQuality || bIsOffline) && (!bIsEmpty || bIncludeEmpty) && (!bIsFull || bIncludeFull) && - (!bIsLocked || bIncludeLocked) && (!bIsOffline || bIncludeOffline || bWasGoodNowFailing) && (!bIsOtherVersion || bIncludeOtherVersions) && - (!bIsBlockedVersion) && (!bIsBlockedServer) && (bServerSearchFound)) + bool bMasterServerOffline = (pServer->uiMasterServerSaysRestrictions == 0); + bool bAllowLowQuality = bIsOffline || bMasterServerOffline; + + if ((!bLowQuality || bAllowLowQuality) && (!bIsEmpty || bIncludeEmpty) && (!bIsFull || bIncludeFull) && (!bIsLocked || bIncludeLocked) && + (!bIsOffline || bIncludeOffline || bWasGoodNowFailing) && (!bIsOtherVersion || bIncludeOtherVersions) && (!bIsBlockedVersion) && (!bIsBlockedServer) && + (bServerSearchFound) && (!pServer->strVersion.empty() || bIsOffline)) { bAddServer = true; } @@ -1032,11 +1376,11 @@ void CServerBrowser::AddServerToList(CServerListItem* pServer, const ServerBrows // // Remove server from list // - int iIndex = pServer->iRowIndex; + int iIndex = pServer->iRowIndex[Type]; if (iIndex != -1) { m_pServerList[Type]->RemoveRow(iIndex); - pServer->iRowIndex = -1; + pServer->iRowIndex[Type] = -1; UpdateRowIndexMembers(Type); } } @@ -1047,21 +1391,22 @@ void CServerBrowser::AddServerToList(CServerListItem* pServer, const ServerBrows // // Get existing row or create a new row if not found - int iIndex = pServer->iRowIndex; + int iIndex = pServer->iRowIndex[Type]; if (iIndex == -1) { iIndex = m_pServerList[Type]->AddRow(true); - pServer->iRowIndex = iIndex; + pServer->iRowIndex[Type] = iIndex; } - const SString strVersion = !bIncludeOtherVersions ? "" : pServer->strVersion; + const SString strVersion = !bIncludeOtherVersions ? SStringX("") : pServer->strVersion; const SString strVersionSortKey = pServer->strVersionSortKey + pServer->strTieBreakSortKey; const SString strVerified = pServer->isStatusVerified ? "" : "*"; - const SString strPlayers = pServer->nMaxPlayers == 0 ? "" : SString("%d / %d %s", pServer->nPlayers, pServer->nMaxPlayers, *strVerified); + const SString strPlayers = + (pServer->nMaxPlayers == 0) ? SStringX("0 / 0") : SString("%d / %d %s", pServer->nPlayers, pServer->nMaxPlayers, *strVerified); const SString strPlayersSortKey = SString("%04d-", pServer->nMaxPlayers ? pServer->nPlayers + 1 : 0) + pServer->strTieBreakSortKey; - const SString strPing = pServer->nPing == 9999 ? "" : SString("%d", pServer->nPing); + const SString strPing = pServer->nPing == 9999 ? SStringX("") : SString("%d", pServer->nPing); const SString strPingSortKey = SString("%04d-", pServer->nPing) + pServer->strTieBreakSortKey; // The row index could change at any point here if list sorting is enabled @@ -1109,7 +1454,7 @@ void CServerBrowser::AddServerToList(CServerListItem* pServer, const ServerBrows } // If the index was modified from the original, then update all indexes because it means there was some sort - if (pServer->iRowIndex != iIndex) + if (pServer->iRowIndex[Type] != iIndex) UpdateRowIndexMembers(Type); } } @@ -1172,8 +1517,10 @@ bool CServerBrowser::OnClick(CGUIElement* pElement) for (i = i_b; i != i_e; i++) { CServerListItem* pServer = *i; + if (!pServer || !CServerListItem::StaticIsValid(pServer)) + continue; - for (unsigned int j = 0; j < pServer->vecPlayers.size(); j++) + for (std::size_t j = 0; j < pServer->vecPlayers.size(); ++j) { std::string strPlayerName = pServer->vecPlayers[j].c_str(); if (strPlayerName.compare(strSelectedPlayerName) == 0) @@ -1211,7 +1558,7 @@ bool CServerBrowser::OnClick(CGUIElement* pElement) if (pServer) { // We found the server, add all the players - for (unsigned int j = 0; j < pServer->vecPlayers.size(); j++) + for (std::size_t j = 0; j < pServer->vecPlayers.size(); ++j) { int k = m_pServerPlayerList[Type]->AddRow(); m_pServerPlayerList[Type]->SetItemText(k, m_hPlayerName[Type], pServer->vecPlayers[j].c_str()); @@ -1269,7 +1616,7 @@ bool CServerBrowser::OnConnectClick(CGUIElement* pElement) strURI = "mtasa://" + strURI; SetAddressBarText(strURI); } - else if (strURI.substr(0, iProtocolEnd) != "mtasa") // Is it the mtasa:// protocol? Don't want noobs trying http etc + else if (strURI.substr(0, iProtocolEnd) != "mtasa") // Is it the mtasa:// protocol? Don't want noobs trying http etc { CCore::GetSingleton().ShowMessageBox(_("Unknown protocol") + _E("CC71"), _("Please use the mtasa:// protocol!"), MB_BUTTON_OK | MB_ICON_INFO); return true; @@ -1308,7 +1655,9 @@ void CServerBrowser::NotifyServerExists(in_addr Address, ushort usPort) CServerListItem* pLast = *pHistoryList->IteratorBegin(); pHistoryList->Remove(pLast->Address, pLast->usGamePort); } - CreateHistoryList(); + m_bHistoryListDirty = true; + if (IsVisible()) + CreateHistoryList(); SaveRecentlyPlayedList(); } @@ -1344,13 +1693,16 @@ bool CServerBrowser::ConnectToSelectedServer() // Password buffer SString strPassword = ""; - if (pServer->bPassworded) // The server is passworded, let's try and grab a saved password + if (pServer->bPassworded) // The server is passworded, let's try and grab a saved password { strPassword = GetServerPassword(pServer->GetEndpoint().c_str()); - if (strPassword.empty()) // No password could be found, popup password entry. + if (strPassword.empty()) // No password could be found, popup password entry. { - CServerInfo::GetSingletonPtr()->Show(eWindowTypes::SERVER_INFO_PASSWORD, pServer->strHost.c_str(), pServer->usGamePort, "", pServer); + if (CServerInfo* pServerInfo = CServerInfo::GetSingletonPtr()) + { + pServerInfo->Show(eWindowTypes::SERVER_INFO_PASSWORD, pServer->strHost.c_str(), pServer->usGamePort, "", pServer); + } return true; } } @@ -1369,16 +1721,38 @@ bool CServerBrowser::OnRefreshClick(CGUIElement* pElement) { ServerBrowserType Type = GetCurrentServerBrowserType(); - GetServerList(Type)->Refresh(); + if (m_pServerListStatus[Type]) + m_pServerListStatus[Type]->SetText(_("Loading...")); + + m_iSelectedServer[Type] = -1; + StartRefresh(Type); return true; } bool CServerBrowser::OnInfoClick(CGUIElement* pElement) { + ServerBrowserType Type = GetCurrentServerBrowserType(); + + // First try to get the selected server from the list + CServerListItem* pServer = FindSelectedServer(Type); + if (pServer && CServerListItem::StaticIsValid(pServer) && pServer->Address.s_addr != 0 && pServer->usGamePort != 0 && !pServer->strHost.empty()) + { + // Use the selected server's information directly + const SString& strHost = pServer->strHost; + unsigned short usPort = pServer->usGamePort; + + if (CServerInfo* pServerInfo = CServerInfo::GetSingletonPtr()) + { + pServerInfo->Show(eWindowTypes::SERVER_INFO_RAW, strHost.c_str(), usPort, "", pServer); + return true; + } + } + + // Fallback to using the address bar if no server is selected unsigned short usPort; std::string strHost, strNick, strPassword; - SString strURI = m_pEditAddress[GetCurrentServerBrowserType()]->GetText(); + SString strURI = m_pEditAddress[Type]->GetText(); // Trim leading spaces from the URI strURI = strURI.TrimStart(" "); @@ -1392,7 +1766,10 @@ bool CServerBrowser::OnInfoClick(CGUIElement* pElement) g_pCore->GetConnectParametersFromURI(strURI.c_str(), strHost, usPort, strNick, strPassword); - CServerInfo::GetSingletonPtr()->Show(eWindowTypes::SERVER_INFO_RAW, strHost.c_str(), usPort, strPassword.c_str()); + if (CServerInfo* pServerInfo = CServerInfo::GetSingletonPtr()) + { + pServerInfo->Show(eWindowTypes::SERVER_INFO_RAW, strHost.c_str(), usPort, strPassword.c_str(), nullptr); + } return true; } @@ -1414,10 +1791,10 @@ bool CServerBrowser::OnFavouritesClick(CGUIElement* pElement) if (m_ServersFavourites.Remove(Address, usPort)) { SaveFavouritesList(); - UpdateServerList(ServerBrowserTypes::FAVOURITES, true); - for (unsigned int i = 0; i < SERVER_BROWSER_TYPE_COUNT; i++) + RequestFilterRefresh(ServerBrowserTypes::FAVOURITES, true); + for (std::size_t iconIndex = 0; iconIndex < std::size(m_pAddressFavoriteIcon); ++iconIndex) { - m_pAddressFavoriteIcon[i]->SetAlpha(0.3f); + m_pAddressFavoriteIcon[iconIndex]->SetAlpha(0.3f); } return true; } @@ -1425,10 +1802,10 @@ bool CServerBrowser::OnFavouritesClick(CGUIElement* pElement) if (m_ServersFavourites.AddUnique(Address, usPort)) { SaveFavouritesList(); - UpdateServerList(ServerBrowserTypes::FAVOURITES, true); - for (unsigned int i = 0; i < SERVER_BROWSER_TYPE_COUNT; i++) + RequestFilterRefresh(ServerBrowserTypes::FAVOURITES, true); + for (std::size_t iconIndex = 0; iconIndex < std::size(m_pAddressFavoriteIcon); ++iconIndex) { - m_pAddressFavoriteIcon[i]->SetAlpha(1.0f); + m_pAddressFavoriteIcon[iconIndex]->SetAlpha(1.0f); } } } @@ -1449,9 +1826,10 @@ bool CServerBrowser::OnAddressChanged(CGUIElement* pElement) g_pCore->GetConnectParametersFromURI(strURI.c_str(), strHost, usPort, strNick, strPassword); // Adjust our other address bars to be consistent - for (unsigned int i = 0; i < SERVER_BROWSER_TYPE_COUNT; i++) + for (std::size_t i = 0; i < std::size(m_pEditAddress); ++i) { - if ((i != Type) && (strURI != m_pEditAddress[i]->GetText())) + const auto otherType = static_cast(i); + if ((otherType != Type) && (strURI != m_pEditAddress[i]->GetText())) m_pEditAddress[i]->SetText(strURI.c_str()); } @@ -1460,18 +1838,20 @@ bool CServerBrowser::OnAddressChanged(CGUIElement* pElement) for (CServerListIterator i = i_b; i != i_e; i++) { CServerListItem* pServer = *i; + if (!pServer || !CServerListItem::StaticIsValid(pServer)) + continue; if (pServer->strHost == strHost && pServer->usGamePort == usPort) { - for (unsigned int i = 0; i < SERVER_BROWSER_TYPE_COUNT; i++) + for (std::size_t iconIndex = 0; iconIndex < std::size(m_pAddressFavoriteIcon); ++iconIndex) { - m_pAddressFavoriteIcon[i]->SetAlpha(1.0f); + m_pAddressFavoriteIcon[iconIndex]->SetAlpha(1.0f); } return true; } } - for (unsigned int i = 0; i < SERVER_BROWSER_TYPE_COUNT; i++) + for (std::size_t iconIndex = 0; iconIndex < std::size(m_pAddressFavoriteIcon); ++iconIndex) { - m_pAddressFavoriteIcon[i]->SetAlpha(0.3f); + m_pAddressFavoriteIcon[iconIndex]->SetAlpha(0.3f); } return true; } @@ -1514,7 +1894,7 @@ bool CServerBrowser::OnHistoryDropListRemove(CGUIElement* pElementx) if (cursor.x < pos.fX + size.fX) if (cursor.y > pos.fY) if (cursor.y < pos.fY + size.fY) - m_bFocusTextEdit = true; // Focus the text edit next frame + m_bFocusTextEdit = true; // Focus the text edit next frame return true; } @@ -1528,11 +1908,14 @@ bool CServerBrowser::OnSearchTypeSelected(CGUIElement* pElement) OnSearchDefocused(pElement); - // Don't bother doing anything if the search bar is empty - if (m_pEditSearch[Type]->GetText().empty()) + SFilterState newState = CaptureFilterState(Type); + bool bStateChanged = FilterStateChanged(Type, newState); + m_FilterState[Type] = newState; + + if (m_pEditSearch[Type]->GetText().empty() || !bStateChanged) return true; - UpdateServerList(GetCurrentServerBrowserType(), true); + RequestFilterRefresh(Type, true); return true; } @@ -1540,7 +1923,7 @@ bool CServerBrowser::OnBackClick(CGUIElement* pElement) { CMainMenu* pMainMenu = CLocalGUI::GetSingleton().GetMainMenu(); - m_pTopWindow->SetVisible(false); + SetVisible(false); pMainMenu->m_bIsInSubWindow = false; SaveOptions(); @@ -1632,7 +2015,30 @@ bool CServerBrowser::OnMouseDoubleClick(CGUIMouseEventArgs Args) bool CServerBrowser::OnFilterChanged(CGUIElement* pElement) { - UpdateServerList(GetCurrentServerBrowserType(), true); + ServerBrowserType detectedType = GetCurrentServerBrowserType(); + + if (pElement) + { + for (std::size_t i = 0; i < std::size(m_pEditSearch); ++i) + { + if (pElement == m_pEditSearch[i] || pElement == m_pIncludeEmpty[i] || pElement == m_pIncludeFull[i] || pElement == m_pIncludeLocked[i] || + (m_pIncludeOffline[i] && pElement == m_pIncludeOffline[i]) || pElement == m_pIncludeOtherVersions[i]) + { + detectedType = static_cast(i); + break; + } + } + } + + bool bImmediate = (pElement && pElement != m_pEditSearch[detectedType]); + + SFilterState newState = CaptureFilterState(detectedType); + if (!FilterStateChanged(detectedType, newState)) + return true; + + m_FilterState[detectedType] = newState; + + RequestFilterRefresh(detectedType, bImmediate); // SaveOptions ( ); Slow return true; @@ -1650,6 +2056,10 @@ bool CServerBrowser::OnTabChanged(CGUIElement* pElement) OnAddressFocused(pElement); OnSearchDefocused(pElement); OnAddressDefocused(pElement); + + bool bAutoRefresh = false; + CVARS_GET("auto_refresh_browser", bAutoRefresh); + EnsureRefreshFor(GetCurrentServerBrowserType(), bAutoRefresh, false); return true; } @@ -1709,8 +2119,8 @@ bool CServerBrowser::LoadServerList(CXMLNode* pNode, const std::string& strTagNa return false; // Loop through all subnodes looking for relevant nodes - unsigned int uiCount = pNode->GetSubNodeCount(); - for (unsigned int i = 0; i < uiCount; i++) + const auto subNodeCount = pNode->GetSubNodeCount(); + for (std::size_t i = 0; i < subNodeCount; ++i) { pSubNode = pNode->GetSubNode(i); if (pSubNode && pSubNode->GetTagName().compare(strTagName) == 0) @@ -1723,8 +2133,8 @@ bool CServerBrowser::LoadServerList(CXMLNode* pNode, const std::string& strTagNa if (CServerListItem::Parse(pHostAttribute->GetValue().c_str(), Address)) { iPort = atoi(pPortAttribute->GetValue().c_str()); - if (iPort > 0) - pList->AddUnique(Address, iPort); + if (iPort > 0 && iPort <= 0xFFFF) + pList->AddUnique(Address, static_cast(iPort)); } } } @@ -1746,6 +2156,17 @@ void CServerBrowser::SaveRecentlyPlayedList() if (!pHistory) pHistory = pConfig->CreateSubNode(CONFIG_NODE_SERVER_HISTORY); SaveServerList(pHistory, CONFIG_HISTORY_LIST_TAG, GetHistoryList(), CONNECT_HISTORY_LIMIT); + + // Sync both recent and history servers with cache and persist to disk + CServerCacheInterface* pCache = GetServerCache(); + if (pCache) + { + pCache->SetServerListCachedInfo(&m_ServersRecent); + pCache->SetServerListCachedInfo(&m_ServersHistory); + pCache->SaveServerCache(false); // Non-blocking save + } + + RequestConfigSave(false); } void CServerBrowser::SaveFavouritesList() @@ -1755,6 +2176,16 @@ void CServerBrowser::SaveFavouritesList() if (!pFavourites) pFavourites = pConfig->CreateSubNode(CONFIG_NODE_SERVER_FAV); SaveServerList(pFavourites, CONFIG_FAVOURITE_LIST_TAG, GetFavouritesList()); + + // Sync favorite servers with cache and persist to disk + CServerCacheInterface* pCache = GetServerCache(); + if (pCache) + { + pCache->SetServerListCachedInfo(&m_ServersFavourites); + pCache->SaveServerCache(false); // Non-blocking save + } + + RequestConfigSave(false); } bool CServerBrowser::SaveServerList(CXMLNode* pNode, const std::string& strTagName, CServerList* pList, unsigned int iLimit) @@ -1773,6 +2204,8 @@ bool CServerBrowser::SaveServerList(CXMLNode* pNode, const std::string& strTagNa if (iLimit && iProcessed == iLimit) break; CServerListItem* pServer = *i; + if (!pServer || !CServerListItem::StaticIsValid(pServer)) + continue; // Add the item to the node CXMLNode* pSubNode = pNode->CreateSubNode(strTagName.c_str()); @@ -1802,8 +2235,8 @@ void CServerBrowser::LoadOptions(CXMLNode* pNode) } // loop through all subnodes - unsigned int uiCount = pNode->GetSubNodeCount(); - for (unsigned int ui = 0; ui < uiCount; ui++) + const auto subNodeCount = pNode->GetSubNodeCount(); + for (std::size_t ui = 0; ui < subNodeCount; ++ui) { CXMLNode* pSubNode = pNode->GetSubNode(ui); if (pSubNode && pSubNode->GetTagName().compare("list") == 0) @@ -1815,52 +2248,56 @@ void CServerBrowser::LoadOptions(CXMLNode* pNode) int i = atoi(pListID->GetValue().c_str()); if (i >= 0 && i < SERVER_BROWSER_TYPE_COUNT) { + const auto listIndex = static_cast(i); // load all checkbox options CXMLAttribute* pIncludeEmpty = pSubNode->GetAttributes().Find("include_empty"); if (pIncludeEmpty) - m_pIncludeEmpty[i]->SetSelected(pIncludeEmpty->GetValue().compare("1") == 0); + m_pIncludeEmpty[listIndex]->SetSelected(pIncludeEmpty->GetValue().compare("1") == 0); CXMLAttribute* pIncludeFull = pSubNode->GetAttributes().Find("include_full"); if (pIncludeFull) - m_pIncludeFull[i]->SetSelected(pIncludeFull->GetValue().compare("1") == 0); + m_pIncludeFull[listIndex]->SetSelected(pIncludeFull->GetValue().compare("1") == 0); CXMLAttribute* pIncludeLocked = pSubNode->GetAttributes().Find("include_locked"); if (pIncludeLocked) - m_pIncludeLocked[i]->SetSelected(pIncludeLocked->GetValue().compare("1") == 0); + m_pIncludeLocked[listIndex]->SetSelected(pIncludeLocked->GetValue().compare("1") == 0); // CXMLAttribute* pIncludeOtherVersions = pSubNode->GetAttributes ( ).Find ( "include_other_versions" ); // if ( pIncludeOtherVersions ) // m_pIncludeOtherVersions[ i ]->SetSelected ( pIncludeOtherVersions->GetValue ( ).compare ( "1" ) == 0 ); // load 'include offline' if the checkbox exists - if (m_pIncludeOffline[i]) + if (m_pIncludeOffline[listIndex]) { CXMLAttribute* pIncludeOffline = pSubNode->GetAttributes().Find("include_offline"); if (pIncludeOffline) - m_pIncludeOffline[i]->SetSelected(pIncludeOffline->GetValue().compare("1") == 0); + m_pIncludeOffline[listIndex]->SetSelected(pIncludeOffline->GetValue().compare("1") == 0); } CXMLAttribute* pDisabled = pSubNode->GetAttributes().Find("disabled"); if (pDisabled) - m_pTab[i]->SetEnabled(pDisabled->GetValue().compare("1") == 0); + m_pTab[listIndex]->SetEnabled(pDisabled->GetValue().compare("1") == 0); // restore the active tab CXMLAttribute* pActiveTab = pSubNode->GetAttributes().Find("active"); if (pActiveTab && pActiveTab->GetValue().compare("1") == 0) - m_pPanel->SetSelectedTab(m_pTab[i]); + m_pPanel->SetSelectedTab(m_pTab[listIndex]); // restore the search field contents std::string strSearch = pSubNode->GetTagContent(); if (strSearch.length() > 0) - m_pEditSearch[i]->SetText(strSearch.c_str()); + m_pEditSearch[listIndex]->SetText(strSearch.c_str()); } } } } m_bOptionsLoaded = true; + + for (std::size_t ui = 0; ui < std::size(m_FilterState); ++ui) + m_FilterState[ui] = CaptureFilterState(static_cast(ui)); } -void CServerBrowser::SaveOptions() +void CServerBrowser::SaveOptions(bool bForceSave) { // Check to make sure if the options were loaded yet, if not the 'changed' events might screw up if (!m_bOptionsLoaded) @@ -1881,14 +2318,14 @@ void CServerBrowser::SaveOptions() int iCurrentType = GetCurrentServerBrowserTypeForSave(); // Save the options for all four lists - for (unsigned int ui = 0; ui < SERVER_BROWSER_TYPE_COUNT; ui++) + for (std::size_t ui = 0; ui < std::size(m_pIncludeEmpty); ++ui) { CXMLNode* pSubNode = pOptions->CreateSubNode("list"); if (pSubNode) { // ID of the list to save CXMLAttribute* pListID = pSubNode->GetAttributes().Create("id"); - pListID->SetValue(ui); + pListID->SetValue(static_cast(ui)); // Checkboxes CXMLAttribute* pIncludeEmpty = pSubNode->GetAttributes().Create("include_empty"); @@ -1931,9 +2368,432 @@ void CServerBrowser::SaveOptions() } } } + + RequestConfigSave(bForceSave); +} + +void CServerBrowser::RequestConfigSave(bool bForceImmediate) +{ + if (bForceImmediate) + { + m_bPendingConfigSave = false; + m_ulNextConfigSaveTime = 0; + g_pCore->SaveConfig(); + return; + } + + m_bPendingConfigSave = true; + m_ulNextConfigSaveTime = CClientTime::GetTime() + SERVER_BROWSER_CONFIG_SAVE_DELAY; +} + +void CServerBrowser::ProcessPendingConfigSave() +{ + if (!m_bPendingConfigSave) + return; + + unsigned long ulNow = CClientTime::GetTime(); + + if (ulNow < m_ulNextConfigSaveTime) + return; + + if (IsVisible() && ulNow < m_ulNextConfigSaveTime + SERVER_BROWSER_CONFIG_SAVE_VISIBLE_GRACE) + return; + + m_bPendingConfigSave = false; + m_ulNextConfigSaveTime = 0; g_pCore->SaveConfig(); } +void CServerBrowser::RequestFilterRefresh(ServerBrowserType type, bool bImmediate) +{ + const auto index = static_cast(type); + if (index >= std::size(m_bPendingFilterUpdate)) + return; + + const bool bProcessNow = bImmediate && IsVisible(); + + if (bProcessNow) + { + m_bPendingFilterUpdate[index] = false; + m_ulNextFilterUpdateTime[index] = 0; + if (const auto batchSize = GetListRefreshBatchSize(); batchSize > 0) + { + BeginServerListRefresh(type, true, true); + ProcessServerListRefreshBatch(type, batchSize); + } + return; + } + + m_bPendingFilterUpdate[index] = true; + m_ulNextFilterUpdateTime[index] = CClientTime::GetTime() + SERVER_BROWSER_FILTER_UPDATE_DELAY; +} + +CServerBrowser::SFilterState CServerBrowser::CaptureFilterState(ServerBrowserType type) +{ + SFilterState state; + state.searchText = m_pEditSearch[type] ? m_pEditSearch[type]->GetText() : std::string(); + state.searchType = m_pComboSearchType[type] ? m_pComboSearchType[type]->GetSelectedItemIndex() : 0; + state.includeEmpty = m_pIncludeEmpty[type] && m_pIncludeEmpty[type]->GetSelected(); + state.includeFull = m_pIncludeFull[type] && m_pIncludeFull[type]->GetSelected(); + state.includeLocked = m_pIncludeLocked[type] && m_pIncludeLocked[type]->GetSelected(); + state.includeOffline = m_pIncludeOffline[type] && m_pIncludeOffline[type]->GetSelected(); + state.includeOtherVersions = m_pIncludeOtherVersions[type] && m_pIncludeOtherVersions[type]->GetSelected(); + return state; +} + +bool CServerBrowser::FilterStateChanged(ServerBrowserType type, const SFilterState& newState) const +{ + const SFilterState& current = m_FilterState[type]; + if (current.searchType != newState.searchType) + return true; + if (current.searchText != newState.searchText) + return true; + if (current.includeEmpty != newState.includeEmpty) + return true; + if (current.includeFull != newState.includeFull) + return true; + if (current.includeLocked != newState.includeLocked) + return true; + if (current.includeOffline != newState.includeOffline) + return true; + if (current.includeOtherVersions != newState.includeOtherVersions) + return true; + return false; +} + +void CServerBrowser::BeginServerListRefresh(ServerBrowserType type, bool bClearServerList, bool bForceRestart) +{ + const auto index = static_cast(type); + if (index >= std::size(m_ListRefreshState)) + return; + + SListRefreshState& state = m_ListRefreshState[index]; + + if (!m_pServerList[index]) + return; + + if (state.bActive && !bForceRestart) + { + if (bClearServerList && !state.bClearServerList) + { + state.bClearServerList = true; + state.bNeedsListClear = true; + } + // Check if sort order has changed - if so, need to restart the batch + unsigned int currentColumn = 0; + SortDirection currentDirection = SortDirections::None; + m_pServerList[index]->GetSort(currentColumn, currentDirection); + if (currentDirection != state.sortDirection || (currentDirection != SortDirections::None && currentColumn != state.uiSortColumn)) + { + // Sort order changed during refresh - restart with new sort state + bForceRestart = true; + } + else + { + return; + } + } + + if (state.bActive && !bClearServerList && !bForceRestart) + m_pServerList[index]->Sort(state.uiSortColumn, state.sortDirection); + + state.bActive = false; + state.filterSnapshot.reset(); + state.pList = GetServerList(type); + if (!state.pList) + return; + + GetVersionUpdater()->GetBrowseVersionMaps(m_blockedVersionMap, m_allowedVersionMap); + +#if MTA_DEBUG + // Selecting 'Nightly update' in debug build will show other versions + SString strUpdateBuildType; + CVARS_GET("update_build_type", strUpdateBuildType); + if (strUpdateBuildType == "2") + { + m_blockedVersionMap.clear(); + m_allowedVersionMap.clear(); + } +#endif + + bool bForceBrowseOtherVersions = false; + CVARS_GET("force_browse_other_versions", bForceBrowseOtherVersions); + if (bForceBrowseOtherVersions) + { + m_blockedVersionMap.clear(); + m_allowedVersionMap.clear(); + } + + state.bClearServerList = bClearServerList; + state.bNeedsListClear = state.pList->GetRevision() != m_pServerListRevision[index] || bClearServerList; + state.bDidUpdateRowIndices = false; + unsigned int currentColumn = 0; + SortDirection currentDirection = SortDirections::None; + m_pServerList[index]->GetSort(currentColumn, currentDirection); + // If the UI gridlist currently reports no active sort, attempt to use + // the last saved user sort state (as the GUI may clear its internal + // sort indicator when rebuilt). This preserves sort across filter + // and rebuild operations. + if (currentDirection == SortDirections::None && m_SortState[index].direction != SortDirections::None) + { + currentColumn = m_SortState[index].uiColumn; + currentDirection = m_SortState[index].direction; + } + state.uiSortColumn = (currentDirection == SortDirections::None) ? 0U : (currentColumn ? currentColumn : 1U); + state.sortDirection = currentDirection; + + if (state.bNeedsListClear) + { + m_pServerListRevision[index] = state.pList->GetRevision(); + m_pServerList[index]->Clear(); + m_pServerPlayerList[index]->Clear(); + + // Sort the data list before populating the GUI list (only once per refresh) + // This ensures items are added in correct order without needing UI-side sorting + unsigned int uiLogicalColumn = 0; + if (state.uiSortColumn == m_hVersion[index]) + uiLogicalColumn = 1; + else if (state.uiSortColumn == m_hLocked[index]) + uiLogicalColumn = 2; + else if (state.uiSortColumn == m_hName[index]) + uiLogicalColumn = 3; + else if (state.uiSortColumn == m_hPlayers[index]) + uiLogicalColumn = 4; + else if (state.uiSortColumn == m_hPing[index]) + uiLogicalColumn = 5; + else if (state.uiSortColumn == m_hGame[index]) + uiLogicalColumn = 6; + + // Convert SortDirection enum to int (0=None, 1=Ascending, 2=Descending) + int iDirection = (int)state.sortDirection; + if (state.pList) + state.pList->Sort(uiLogicalColumn, iDirection); + + // Disable auto-sorting during population to improve performance while keeping the sort indicator + m_pServerList[index]->SetAutoSortSuppressed(true); + } + + state.iterator = state.pList->IteratorBegin(); + state.endIterator = state.pList->IteratorEnd(); + state.filterSnapshot = m_FilterState[index]; + state.bActive = true; + m_ulNextListLayoutTime[index] = CClientTime::GetTime(); +} + +bool CServerBrowser::ProcessServerListRefreshBatch(ServerBrowserType type, size_t uiMaxSteps) +{ + const auto index = static_cast(type); + if (index >= std::size(m_ListRefreshState)) + return true; + + SListRefreshState& state = m_ListRefreshState[index]; + if (!state.bActive || !state.pList) + return true; + + if (!state.filterSnapshot) + state.filterSnapshot = m_FilterState[index]; + + if (!state.filterSnapshot) + return true; + + const SFilterState& activeFilter = *state.filterSnapshot; + const bool bHiddenBoost = ShouldUseHiddenRefreshAcceleration(); + const auto frameBudget = + std::chrono::milliseconds{bHiddenBoost ? SERVER_BROWSER_REFRESH_FRAME_BUDGET_MS * static_cast(SERVER_BROWSER_HIDDEN_REFRESH_MULTIPLIER) + : SERVER_BROWSER_REFRESH_FRAME_BUDGET_MS}; + const auto frameStart = std::chrono::steady_clock::now(); + + size_t processed = 0; + while (state.iterator != state.endIterator && processed < uiMaxSteps) + { + CServerListItem* pServer = *state.iterator; + + // The list can briefly hand us null if an item was erased between batches + if (!pServer) + { + ++state.iterator; + state.bNeedsListClear = true; + continue; + } + + // Skip entries that were removed from the list while we were waiting to process them + if (!CServerListItem::StaticIsValid(pServer)) + { + ++state.iterator; + state.bNeedsListClear = true; + continue; + } + + // Additional safety check before accessing members + if (state.bNeedsListClear) + pServer->iRowIndex[0] = pServer->iRowIndex[1] = pServer->iRowIndex[2] = pServer->iRowIndex[3] = -1; + + if (type == ServerBrowserTypes::FAVOURITES || type == ServerBrowserTypes::RECENTLY_PLAYED) + { + if (pServer && pServer->Address.s_addr != 0 && pServer->usGamePort != 0) + { + CServerCacheInterface* pCache = GetServerCache(); + if (pCache) + pCache->GetServerCachedInfo(pServer); + } + } + + if (pServer && (pServer->revisionInList[type] != pServer->uiRevision || state.bClearServerList)) + { + if (!state.bDidUpdateRowIndices) + { + UpdateRowIndexMembers(type); + state.bDidUpdateRowIndices = true; + } + + pServer->revisionInList[type] = pServer->uiRevision; + AddServerToList(pServer, type, activeFilter); + } + + ++state.iterator; + ++processed; + + if (std::chrono::steady_clock::now() - frameStart >= frameBudget) + break; + } + + if (state.iterator != state.endIterator) + { + if (processed > 0) + { + unsigned long ulNow = CClientTime::GetTime(); + auto layoutIntervalSetting = static_cast(SERVER_BROWSER_LAZY_LAYOUT_INTERVAL_DEFAULT); + CVARS_GET("browser_layout_interval_ms", layoutIntervalSetting); + const auto layoutInterval = std::chrono::milliseconds{layoutIntervalSetting}; + if (ulNow >= m_ulNextListLayoutTime[index]) + { + m_ulNextListLayoutTime[index] = ulNow + static_cast(layoutInterval.count()); + m_pServerList[index]->ForceUpdate(); + // Update player count status with filtered results from data list + // Pass data list to show accurate counts while GUI is being rebuilt + UpdateFilteredPlayerCountStatus(type, state.pList); + // Periodically cache server data as they respond to keep player counts up to date + GetServerCache()->SetServerListCachedInfo(state.pList); + } + } + return false; + } + + const bool bIncludeOtherVersions = + state.filterSnapshot ? state.filterSnapshot->includeOtherVersions : (m_pIncludeOtherVersions[index] && m_pIncludeOtherVersions[index]->GetSelected()); + if (bIncludeOtherVersions) + m_pServerList[index]->SetColumnWidth(1, 34, false); + else + m_pServerList[index]->SetColumnWidth(1, 0.03f, true); + + m_pServerList[index]->SetAutoSortSuppressed(false); + + // Apply sort to UI list as final guarantee of correct visual order + // (items should already be in correct order from data list pre-sort, but this ensures it) + if (!state.bClearServerList && state.sortDirection != SortDirections::None && state.uiSortColumn != 0) + m_pServerList[index]->Sort(state.uiSortColumn, state.sortDirection); + m_pServerList[index]->ForceUpdate(); + + // Update status with final filtered player counts after all batch processing is done + // Pass data list to ensure counts reflect all filtered servers + UpdateFilteredPlayerCountStatus(type, state.pList); + + state.pList->SetUpdated(false); + + if (state.pList->GetRevision() != m_pServerListRevision[index]) + state.pList->SetUpdated(true); + + if (type == ServerBrowserTypes::RECENTLY_PLAYED) + m_pRemoveFromRecentIcon[index]->SetAlpha(0.3f); + + state.bActive = false; + state.pList = nullptr; + state.filterSnapshot.reset(); + return true; +} + +void CServerBrowser::ProcessPendingListRefreshes() +{ + if (!IsVisible()) + return; + + const bool bHiddenBoost = ShouldUseHiddenRefreshAcceleration(); + const auto batchSize = bHiddenBoost ? GetHiddenListRefreshBatchSize() : GetListRefreshBatchSize(); + + for (std::size_t i = 0; i < std::size(m_ListRefreshState); ++i) + { + if (m_ListRefreshState[i].bActive) + ProcessServerListRefreshBatch(static_cast(i), batchSize); + } +} + +void CServerBrowser::SuspendServerLists() +{ + for (std::size_t i = 0; i < std::size(m_ListRefreshState); ++i) + { + const auto type = static_cast(i); + if (CServerList* pList = GetServerList(type)) + pList->SuspendActivity(); + + if (m_pServerList[i]) + m_pServerList[i]->SetAutoSortSuppressed(false); + + m_ListRefreshState[i].bActive = false; + m_ListRefreshState[i].pList = nullptr; + m_ListRefreshState[i].filterSnapshot.reset(); + m_bPendingFilterUpdate[i] = false; + m_ulNextFilterUpdateTime[i] = 0; + m_bPendingRefresh[i] = false; + m_ulNextListLayoutTime[i] = 0; + + if (type != ServerBrowserTypes::INTERNET) + { + // Non-internet tabs previously refreshed automatically every time the UI opened. + // Reset their "initial" flag so EnsureRefreshFor() schedules a new refresh on resume. + m_bInitialRefreshDone[i] = false; + } + } + + m_ServersHistory.SuspendActivity(); + m_ulLastUpdateTime = 0; +} + +bool CServerBrowser::ShouldUseHiddenRefreshAcceleration() const +{ + return !IsVisible() && CClientTime::GetTime() >= m_ulHiddenRefreshBoostEnableTime; +} + +bool CServerBrowser::IsListRefreshInProgress(ServerBrowserType type) const +{ + const auto index = static_cast(type); + if (index >= std::size(m_ListRefreshState)) + return false; + + return m_ListRefreshState[index].bActive; +} + +std::size_t CServerBrowser::GetListRefreshBatchSize() const +{ + auto browserSpeed = SERVER_BROWSER_SPEED_DEFAULT; + CVARS_GET("browser_speed", browserSpeed); + + switch (browserSpeed) + { + case SERVER_BROWSER_SPEED_SLOW: // Very slow + return std::max(SERVER_BROWSER_SLOW_BATCH_MIN, SERVER_BROWSER_FILTER_UPDATE_BATCH_SIZE / SERVER_BROWSER_SLOW_BATCH_DIVISOR); + case SERVER_BROWSER_SPEED_FAST: // Fast + return SERVER_BROWSER_FILTER_UPDATE_BATCH_SIZE * SERVER_BROWSER_FAST_BATCH_MULTIPLIER; + default: // Default + return SERVER_BROWSER_FILTER_UPDATE_BATCH_SIZE; + } +} + +std::size_t CServerBrowser::GetHiddenListRefreshBatchSize() const +{ + const auto baseBatchSize = GetListRefreshBatchSize(); + return std::max(baseBatchSize, baseBatchSize * SERVER_BROWSER_HIDDEN_REFRESH_MULTIPLIER); +} + void CServerBrowser::SetServerPassword(const std::string& strHost, const std::string& strPassword) { bool bSavedPasswords; @@ -1948,7 +2808,8 @@ void CServerBrowser::SetServerPassword(const std::string& strHost, const std::st pServerPasswords = pConfig->CreateSubNode(CONFIG_NODE_SERVER_SAVED); } // Check if the server password already exists - for (unsigned int i = 0; i < pServerPasswords->GetSubNodeCount(); i++) + const auto subNodeCount = pServerPasswords->GetSubNodeCount(); + for (std::size_t i = 0; i < subNodeCount; ++i) { CXMLAttributes* pAttributes = &(pServerPasswords->GetSubNode(i)->GetAttributes()); if (pAttributes->Find("host")) @@ -1972,6 +2833,8 @@ void CServerBrowser::SetServerPassword(const std::string& strHost, const std::st pHostAttribute->SetValue(strHost.c_str()); CXMLAttribute* pPasswordAttribute = pNode->GetAttributes().Create("password"); pPasswordAttribute->SetValue(strPassword.c_str()); + + RequestConfigSave(false); } std::string CServerBrowser::GetServerPassword(const std::string& strHost) @@ -1989,7 +2852,8 @@ std::string CServerBrowser::GetServerPassword(const std::string& strHost) pServerPasswords = pConfig->CreateSubNode(CONFIG_NODE_SERVER_SAVED); } // Check if the server password already exists - for (unsigned int i = 0; i < pServerPasswords->GetSubNodeCount(); i++) + const auto subNodeCount = pServerPasswords->GetSubNodeCount(); + for (std::size_t i = 0; i < subNodeCount; ++i) { CXMLAttributes* pAttributes = &(pServerPasswords->GetSubNode(i)->GetAttributes()); if (pAttributes->Find("host")) @@ -2018,6 +2882,8 @@ void CServerBrowser::ClearServerPasswords() pServerPasswords->DeleteAllSubNodes(); pConfig->DeleteSubNode(pServerPasswords); } + + RequestConfigSave(false); } ///////////////////////////////////////////////////////////////// @@ -2069,6 +2935,8 @@ CServerListItem* CServerBrowser::FindServer(const std::string& strHost, unsigned for (CServerListIterator i = i_b; i != i_e; i++) { CServerListItem* pServer = *i; + if (!pServer || !CServerListItem::StaticIsValid(pServer)) + continue; if (pServer->strHost == strHost && pServer->usGamePort == usPort) return pServer; } @@ -2089,6 +2957,8 @@ unsigned short CServerBrowser::FindServerHttpPort(const std::string& strHost, un for (CServerListIterator i = i_b; i != i_e; i++) { CServerListItem* pServer = *i; + if (!pServer || !CServerListItem::StaticIsValid(pServer)) + continue; if (pServer->strHost == strHost && pServer->usGamePort == usPort) return pServer->m_usHttpPort; } @@ -2110,7 +2980,9 @@ void CServerBrowser::UpdateRowIndexMembers(ServerBrowserType Type) for (int iRowIndex = 0; iRowIndex < iRowCount; iRowIndex++) { CServerListItem* pServer = (CServerListItem*)pServerList->GetItemData(iRowIndex, DATA_PSERVER); - pServer->iRowIndex = iRowIndex; + if (!pServer || !CServerListItem::StaticIsValid(pServer)) + continue; + pServer->iRowIndex[Type] = iRowIndex; } } @@ -2123,44 +2995,83 @@ void CServerBrowser::UpdateRowIndexMembers(ServerBrowserType Type) ///////////////////////////////////////////////////////////////// void CServerBrowser::UpdateSelectedServerPlayerList(ServerBrowserType Type) { - // If there is one item selected - if (m_pServerList[Type]->GetSelectedCount() >= 1) + // Only process player list updates if a server is actually selected + if (m_pServerList[Type]->GetSelectedCount() < 1) { - // Get the selected row - int iSelectedIndex = m_pServerList[Type]->GetSelectedItemRow(); - - // Get number of players as defined in the gridlist - int iNumPlayers = atoi(m_pServerList[Type]->GetItemText(iSelectedIndex, m_hPlayers[Type])); + // Clear the player list if nothing is selected + const auto typeIndex = static_cast(Type); + m_pLastSelectedServerForPlayerList[typeIndex] = nullptr; + m_msLastPlayerListQueryRetryTime[typeIndex] = std::chrono::milliseconds(0); + return; + } - // Get number of rows in the gui player list - int iNumPlayerRows = m_pServerPlayerList[Type]->GetRowCount(); + // Get the selected row + const int iSelectedIndex = m_pServerList[Type]->GetSelectedItemRow(); - // If number of rows in player list is less than number of players in server item, - if (iNumPlayers > iNumPlayerRows || iNumPlayerRows == 1 && iNumPlayers == 1) + // Get number of players as defined in the gridlist + const char* szPlayerCount = m_pServerList[Type]->GetItemText(iSelectedIndex, m_hPlayers[Type]); + int iNumPlayers = 0; + if (szPlayerCount && *szPlayerCount) + { + try { - // find server item - CServerListItem* pServer = FindSelectedServer(Type); + iNumPlayers = std::stoi(szPlayerCount); + } + catch (const std::invalid_argument&) + { + iNumPlayers = 0; + } + catch (const std::out_of_range&) + { + iNumPlayers = 0; + } + } + + // Get number of rows in the gui player list + const int iNumPlayerRows = m_pServerPlayerList[Type]->GetRowCount(); + + // Find the selected server + CServerListItem* const pServer = FindSelectedServer(Type); + const auto typeIndex = static_cast(Type); - if (pServer && pServer->vecPlayers.size() > 0) + // If number of rows in player list is less than number of players in server item, + if (iNumPlayers > iNumPlayerRows || (iNumPlayerRows == 1 && iNumPlayers == 1)) + { + if (pServer && !pServer->vecPlayers.empty()) + { + bool bUpdatePlayerList = false; + if (iNumPlayerRows == 1 && pServer->vecPlayers.size() == 1) + { + const SString strPlayerName = m_pServerPlayerList[Type]->GetItemText(0, m_hPlayerName[Type]); + if (strPlayerName == _(" ..loading..")) + bUpdatePlayerList = true; + } + if (static_cast(pServer->vecPlayers.size()) > iNumPlayerRows || bUpdatePlayerList) { - bool bUpdatePlayerList = false; - if (iNumPlayerRows == 1 && pServer->vecPlayers.size() == 1) + m_pServerPlayerList[Type]->Clear(); + + // Add all the players (player names only, not counts) + for (const auto& playerName : pServer->vecPlayers) { - SString strPlayerName = m_pServerPlayerList[Type]->GetItemText(0, m_hPlayerName[Type]); - if (strPlayerName == _(" ..loading..")) - bUpdatePlayerList = true; + const int k = m_pServerPlayerList[Type]->AddRow(); + m_pServerPlayerList[Type]->SetItemText(k, m_hPlayerName[Type], playerName.c_str()); } - if ((int)pServer->vecPlayers.size() > iNumPlayerRows || bUpdatePlayerList) - { - m_pServerPlayerList[Type]->Clear(); + } + } - // Add all the players - for (unsigned int j = 0; j < pServer->vecPlayers.size(); j++) - { - int k = m_pServerPlayerList[Type]->AddRow(); - m_pServerPlayerList[Type]->SetItemText(k, m_hPlayerName[Type], pServer->vecPlayers[j].c_str()); - } - } + // Retry player list query if loading (only when server is actually selected) + if (pServer && pServer->nPlayers && pServer->vecPlayers.empty()) + { + // Check if enough time has passed since last retry attempt + const auto now = std::chrono::milliseconds(CClientTime::GetTime()); + constexpr auto PLAYER_LIST_RETRY_INTERVAL = std::chrono::milliseconds(2000); + + if (pServer != m_pLastSelectedServerForPlayerList[typeIndex] || now >= m_msLastPlayerListQueryRetryTime[typeIndex] + PLAYER_LIST_RETRY_INTERVAL) + { + // New server or retry time has elapsed - send query + m_pLastSelectedServerForPlayerList[typeIndex] = pServer; + m_msLastPlayerListQueryRetryTime[typeIndex] = now; + pServer->Query(); } } } @@ -2189,19 +3100,89 @@ void CServerBrowser::GetVisibleEndPointList(std::vector& outEndpoi } } -void CServerBrowser::SetStatusText(std::string strStatus) +void CServerBrowser::SetStatusText(std::string_view strStatus) +{ + for (auto* pStatusElement : m_pServerListStatus) + { + if (pStatusElement) + pStatusElement->SetText(strStatus.data()); + } +} + +void CServerBrowser::UpdateFilteredPlayerCountStatus(ServerBrowserType Type, CServerList* pDataList) { - for (unsigned int i = 0; i < SERVER_BROWSER_TYPE_COUNT; i++) + const auto index = static_cast(Type); + if (index >= std::size(m_pServerList) || !m_pServerList[index]) + return; + + std::uint32_t uiVisibleServers = 0; + std::uint32_t uiVisiblePlayers = 0; + std::uint32_t uiVisibleTotalSlots = 0; + + // If a data list is provided (during batch refresh), calculate from it instead of GUI + // This prevents showing 0 players while the GUI list is being rebuilt + if (pDataList) + { + for (auto it = pDataList->IteratorBegin(); it != pDataList->IteratorEnd(); ++it) + { + auto pServer = *it; + if (!pServer || !CServerListItem::StaticIsValid(pServer)) + continue; + + if (pServer->nMaxPlayers > 0 && !pServer->bSkipped && !pServer->MaybeWontRespond()) + { + ++uiVisibleServers; + uiVisibleTotalSlots += pServer->nMaxPlayers; + uiVisiblePlayers += pServer->nPlayers; + } + } + } + else + { + // Calculate from visible GUI list rows when no data list provided + const int iRowCount = m_pServerList[index]->GetRowCount(); + for (int i = 0; i < iRowCount; ++i) + { + const auto pServer = static_cast(m_pServerList[index]->GetItemData(i, DATA_PSERVER)); + if (!pServer || !CServerListItem::StaticIsValid(pServer)) + continue; + + if (pServer->nMaxPlayers > 0 && !pServer->bSkipped && !pServer->MaybeWontRespond()) + { + ++uiVisibleServers; + uiVisibleTotalSlots += pServer->nMaxPlayers; + uiVisiblePlayers += pServer->nPlayers; + } + } + } + + // Build status string with filtered counts + SString statusMessage = " "; + + if (uiVisibleTotalSlots > 0) { - m_pServerListStatus[i]->SetText(strStatus.c_str()); + const SString strPlayersString = _tn("player", "players", uiVisiblePlayers); + SString strPlayersLine; + strPlayersLine.Format("%u %s %s ", uiVisiblePlayers, *strPlayersString, *_(("on"))); + statusMessage += strPlayersLine; } + + const SString strServersString = _tn("server", "servers", uiVisibleServers); + SString strServersLine; + strServersLine.Format("%u %s", uiVisibleServers, *strServersString); + statusMessage += strServersLine; + + // Update status text for this tab + if (auto* const pStatusElement = m_pServerListStatus[index]) + pStatusElement->SetText(*statusMessage); } -void CServerBrowser::SetAddressBarText(std::string strText) +void CServerBrowser::SetAddressBarText(std::string_view strText) { - for (unsigned int i = 0; i < SERVER_BROWSER_TYPE_COUNT; i++) + for (auto* pAddressElement : m_pEditAddress) { - m_pEditAddress[i]->SetText(strText.c_str()); + if (pAddressElement) + pAddressElement->SetText(strText.data()); } } @@ -2227,7 +3208,7 @@ void CServerBrowser::SetNextHistoryText(bool bDown) i = bDown ? i + 1 : i - 1; // Ensure we're in range - i = Clamp(0, i, pServerList->GetItemCount() - 1); + i = std::clamp(i, 0, static_cast(pServerList->GetItemCount()) - 1); SetAddressBarText(std::string("mtasa://") + (const char*)pServerList->GetItemByIndex(i)->GetData()); m_pEditAddress[Type]->SetCaretAtEnd(); return; @@ -2274,7 +3255,7 @@ bool CServerBrowser::OnServerListChangeRow(CGUIKeyEventArgs Args) if (iSelectedItem > 0) { m_pServerList[Type]->SetSelectedItem(iSelectedItem - 1, 1, true); - OnClick(m_pServerPlayerList[Type]); // hacky + OnClick(m_pServerPlayerList[Type]); // hacky } break; } @@ -2283,7 +3264,7 @@ bool CServerBrowser::OnServerListChangeRow(CGUIKeyEventArgs Args) if (iSelectedItem < (iMax - 1)) { m_pServerList[Type]->SetSelectedItem(iSelectedItem + 1, 1, true); - OnClick(m_pServerPlayerList[Type]); // hacky + OnClick(m_pServerPlayerList[Type]); // hacky } break; } @@ -2317,6 +3298,67 @@ bool CServerBrowser::OnServerListKeyDown(CGUIKeyEventArgs Args) return true; } +bool CServerBrowser::OnServerListSortChanged(CGUIElement* pElement) +{ + if (m_iIgnoreSortCallbacks > 0) + return true; + + // Determine which tab raised the sort column event and persist the + // selected sort state so it can be restored after rebuilding lists. + auto it = std::find(std::begin(m_pServerList), std::end(m_pServerList), pElement); + if (it != std::end(m_pServerList)) + { + const auto i = std::distance(std::begin(m_pServerList), it); + + unsigned int uiColumn = 0; + SortDirection dir = SortDirections::None; + m_pServerList[i]->GetSort(uiColumn, dir); + m_SortState[i] = {uiColumn, dir}; + + // Also update the active list refresh state if one exists. + if (m_ListRefreshState[i].bActive) + { + m_ListRefreshState[i].uiSortColumn = (dir == SortDirections::None) ? 0U : (uiColumn ? uiColumn : 1U); + m_ListRefreshState[i].sortDirection = dir; + } + } + return true; +} + +void CServerBrowser::UpdateSortState(ServerBrowserType type) +{ + const auto index = static_cast(type); + if (index >= std::size(m_pServerList)) + return; + + unsigned int uiColumn = 0; + SortDirection dir = SortDirections::None; + if (m_pServerList[index]) + m_pServerList[index]->GetSort(uiColumn, dir); + + if (dir == SortDirections::None && m_SortState[index].direction != SortDirections::None) + { + uiColumn = m_SortState[index].uiColumn; + dir = m_SortState[index].direction; + } + m_SortState[index] = {uiColumn, dir}; +} + +void CServerBrowser::ApplyListSort(ServerBrowserType type, unsigned int uiColumn, SortDirection direction, bool bUpdateStoredState) +{ + const auto index = static_cast(type); + if (index >= std::size(m_pServerList)) + return; + + if (m_pServerList[index]) + { + m_pServerList[index]->Sort(uiColumn, direction); + if (bUpdateStoredState) + { + m_SortState[index] = {uiColumn, direction}; + } + } +} void CServerBrowser::SetSelectedIndex(unsigned int uiIndex) { diff --git a/Client/core/ServerBrowser/CServerBrowser.h b/Client/core/ServerBrowser/CServerBrowser.h index 315eb5d52a2..a44f8753b96 100644 --- a/Client/core/ServerBrowser/CServerBrowser.h +++ b/Client/core/ServerBrowser/CServerBrowser.h @@ -14,19 +14,22 @@ class CServerBrowser; #pragma once // Amount of server lists/tabs (ServerBrowserType) -#define SERVER_BROWSER_TYPE_COUNT 4 +#define SERVER_BROWSER_TYPE_COUNT 4 // Amount of search types -#define SERVER_BROWSER_SEARCH_TYPE_COUNT 2 +#define SERVER_BROWSER_SEARCH_TYPE_COUNT 2 // Server browser list update interval (in ms) -#define SERVER_BROWSER_UPDATE_INTERVAL 1000 +#define SERVER_BROWSER_UPDATE_INTERVAL 1000 #include "CMainMenu.h" #include "CServerList.h" #include "CSingleton.h" #include "CServerInfo.h" #include +#include +#include +#include namespace ServerBrowserTypes { @@ -64,7 +67,7 @@ class CServerBrowser : public CSingleton void Update(); void SetVisible(bool bVisible); - bool IsVisible(); + bool IsVisible() const; bool ConnectToSelectedServer(); @@ -79,7 +82,7 @@ class CServerBrowser : public CSingleton void SaveFavouritesList(); void LoadOptions(CXMLNode* pNode); - void SaveOptions(); + void SaveOptions(bool bForceSave = false); bool LoadServerList(CXMLNode* pNode, const std::string& strTagName, CServerList* pList); bool SaveServerList(CXMLNode* pNode, const std::string& strTagName, CServerList* pList, unsigned int iLimit = 0); @@ -88,8 +91,8 @@ class CServerBrowser : public CSingleton std::string GetServerPassword(const std::string& strHost); void ClearServerPasswords(); - void SetStatusText(std::string strStatus); - void SetAddressBarText(std::string strText); + void SetStatusText(std::string_view strStatus); + void SetAddressBarText(std::string_view strText); CServerListItem* FindSelectedServer(ServerBrowserType Type); CServerListItem* FindServerFromRow(ServerBrowserType Type, int iRow); @@ -197,19 +200,24 @@ class CServerBrowser : public CSingleton } m_FlashSearchBox[SERVER_BROWSER_TYPE_COUNT]; private: + struct SFilterState; + struct SListRefreshState; + struct SSortState; + enum { - DATA_PSERVER = 1, // Column which stores server pointer + DATA_PSERVER = 1, // Column which stores server pointer }; void CreateTab(ServerBrowserType type, const char* szName); void DeleteTab(ServerBrowserType type); - void UpdateServerList(ServerBrowserType Type, bool bClearServerList = false); - void UpdateHistoryList(); - CServerList* GetServerList(ServerBrowserType Type); - void AddServerToList(CServerListItem* pServer, const ServerBrowserType Type); - bool RemoveSelectedServerFromRecentlyPlayedList(); + void UpdateServerList(ServerBrowserType Type, bool bClearServerList = false); + void UpdateHistoryList(); + [[nodiscard]] CServerList* GetServerList(ServerBrowserType Type); + void AddServerToList(CServerListItem* pServer, ServerBrowserType Type, const SFilterState& filterState); + bool RemoveSelectedServerFromRecentlyPlayedList(); + void UpdateFilteredPlayerCountStatus(ServerBrowserType Type, CServerList* pDataList = nullptr); bool OnClick(CGUIElement* pElement); bool OnDoubleClick(CGUIElement* pElement); @@ -236,10 +244,62 @@ class CServerBrowser : public CSingleton bool OnServerListChangeRow(CGUIKeyEventArgs Args); bool OnServerListKeyDown(CGUIKeyEventArgs Args); + bool OnServerListSortChanged(CGUIElement* pElement); ServerBrowserType GetCurrentServerBrowserType(); ServerBrowserType GetCurrentServerBrowserTypeForSave(); + void EnsureRefreshFor(ServerBrowserType type, bool bAutoRefreshEnabled, bool bForceOnFirstView); + void StartRefresh(ServerBrowserType type); + + void RequestConfigSave(bool bForceImmediate); + void ProcessPendingConfigSave(); + void RequestFilterRefresh(ServerBrowserType type, bool bImmediate); + void BeginServerListRefresh(ServerBrowserType type, bool bClearServerList, bool bForceRestart); + bool ProcessServerListRefreshBatch(ServerBrowserType type, std::size_t uiMaxSteps); + void ProcessPendingListRefreshes(); + void SuspendServerLists(); + void UpdateSortState(ServerBrowserType type); + void ApplyListSort(ServerBrowserType type, unsigned int uiColumn, SortDirection direction, bool bUpdateStoredState = false); + [[nodiscard]] bool IsListRefreshInProgress(ServerBrowserType type) const; + [[nodiscard]] std::size_t GetListRefreshBatchSize() const; + [[nodiscard]] std::size_t GetHiddenListRefreshBatchSize() const; + [[nodiscard]] bool ShouldUseHiddenRefreshAcceleration() const; + + struct SFilterState + { + std::string searchText; + int searchType; + bool includeEmpty; + bool includeFull; + bool includeLocked; + bool includeOffline; + bool includeOtherVersions; + }; + + [[nodiscard]] SFilterState CaptureFilterState(ServerBrowserType type); + [[nodiscard]] bool FilterStateChanged(ServerBrowserType type, const SFilterState& newState) const; + + struct SListRefreshState + { + bool bActive = false; + bool bClearServerList = false; + bool bNeedsListClear = false; + bool bDidUpdateRowIndices = false; + uint uiSortColumn = 0; + SortDirection sortDirection = SortDirections::None; + CServerList* pList = nullptr; + CServerListIterator iterator; + CServerListIterator endIterator; + std::optional filterSnapshot; + }; + + struct SSortState + { + unsigned int uiColumn = 0; + SortDirection direction = SortDirections::None; + }; + CServerListInternet m_ServersInternet; CServerListLAN m_ServersLAN; CServerList m_ServersFavourites; @@ -262,4 +322,23 @@ class CServerBrowser : public CSingleton ServerBrowserType m_BeforeTempServerBrowserType; CGUIWindow* m_pGeneralHelpWindow; long long m_llLastGeneralHelpTime; + + bool m_bInitialRefreshDone[SERVER_BROWSER_TYPE_COUNT]; + bool m_bPendingRefresh[SERVER_BROWSER_TYPE_COUNT]; + bool m_bHistoryListDirty; + bool m_bPendingFilterUpdate[SERVER_BROWSER_TYPE_COUNT]; + unsigned long m_ulNextFilterUpdateTime[SERVER_BROWSER_TYPE_COUNT]; + SFilterState m_FilterState[SERVER_BROWSER_TYPE_COUNT]; + SSortState m_SortState[SERVER_BROWSER_TYPE_COUNT]; + + bool m_bPendingConfigSave; + unsigned long m_ulNextConfigSaveTime; + SListRefreshState m_ListRefreshState[SERVER_BROWSER_TYPE_COUNT]; + unsigned long m_ulNextListLayoutTime[SERVER_BROWSER_TYPE_COUNT] = {}; + unsigned long m_ulHiddenRefreshBoostEnableTime = 0; + int m_iIgnoreSortCallbacks = 0; + + // Player list retry tracking - retry queries for servers that haven't responded with player data + CServerListItem* m_pLastSelectedServerForPlayerList[SERVER_BROWSER_TYPE_COUNT] = {}; + std::chrono::milliseconds m_msLastPlayerListQueryRetryTime[SERVER_BROWSER_TYPE_COUNT] = {}; }; diff --git a/Client/core/ServerBrowser/CServerCache.cpp b/Client/core/ServerBrowser/CServerCache.cpp index e39100cd7d1..1c87505ba2a 100644 --- a/Client/core/ServerBrowser/CServerCache.cpp +++ b/Client/core/ServerBrowser/CServerCache.cpp @@ -25,24 +25,24 @@ namespace struct CCachedInfo { - CValueInt nPlayers; // Current players - CValueInt nMaxPlayers; // Maximum players - CValueInt nPing; // Ping time - CValueInt bPassworded; // Password protected + CValueInt nPlayers; // Current players + CValueInt nMaxPlayers; // Maximum players + CValueInt nPing; // Ping time + CValueInt bPassworded; // Password protected CValueInt bKeepFlag; CValueInt uiCacheNoReplyCount; CValueInt usHttpPort; CValueInt ucSpecialFlags; - SString strName; // Server name - SString strGameMode; // Game mode - SString strMap; // Map name - SString strVersion; // Version + SString strName; // Server name + SString strGameMode; // Game mode + SString strMap; // Map name + SString strVersion; // Version }; // Variables used for saving the server cache file on a separate thread static bool ms_bIsSaving = false; static std::map ms_ServerCachedMap; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -59,15 +59,16 @@ class CServerCache : public CServerCacheInterface virtual void GetServerCachedInfo(CServerListItem* pItem); virtual void SetServerCachedInfo(const CServerListItem* pItem); virtual void GetServerListCachedInfo(CServerList* pList); - virtual bool GenerateServerList(CServerList* pList); + virtual bool GenerateServerList(CServerList* pList, bool bAllowNonResponding = false); + virtual void SetServerListCachedInfo(CServerList* pList); CServerCache(); ~CServerCache(); protected: - bool LoadServerCache(); - static DWORD StaticThreadProc(LPVOID lpdwThreadParam); - static void StaticSaveServerCache(); + bool LoadServerCache(); + static DWORD WINAPI StaticThreadProc(LPVOID lpdwThreadParam); + static void StaticSaveServerCache(); bool m_bListChanged; std::map m_ServerCachedMap; @@ -93,7 +94,9 @@ CServerCacheInterface* GetServerCache() // // CServerCache::CServerCache // -// +// Initialize server cache by loading from persistent disk storage. +// The cache file (servercache.xml) is never deleted and persists across sessions. +// Cache entries are synced (updated) on each session, not regenerated. // /////////////////////////////////////////////////////////////// CServerCache::CServerCache() @@ -117,6 +120,8 @@ CServerCache::~CServerCache() // CServerCache::LoadServerCache // // Load cache data from config +// The in-memory cache is cleared and reloaded from disk. +// The disk file is never deleted; it persists across game sessions. // /////////////////////////////////////////////////////////////// bool CServerCache::LoadServerCache() @@ -155,7 +160,11 @@ bool CServerCache::LoadServerCache() if (const SString* pString = MapFind(item.attributeMap, "ip")) key.ulIp = inet_addr(*pString); if (const SString* pString = MapFind(item.attributeMap, "port")) - key.usGamePort = atoi(*pString); + { + const int iPort = atoi(*pString); + if (iPort > 0 && iPort <= 0xFFFF) + key.usGamePort = static_cast(iPort); + } if (const SString* pString = MapFind(item.attributeMap, "nPlayers")) info.nPlayers.SetFromString(*pString); if (const SString* pString = MapFind(item.attributeMap, "nMaxPlayers")) @@ -181,7 +190,7 @@ bool CServerCache::LoadServerCache() if (const SString* pString = MapFind(item.attributeMap, "strVersion")) info.strVersion = *pString; - if (key.ulIp == 0) + if (key.ulIp == 0 || key.usGamePort == 0) continue; MapSet(m_ServerCachedMap, key, info); @@ -197,7 +206,8 @@ bool CServerCache::LoadServerCache() // // CServerCache::SaveServerCache // -// Save cache data to config +// Persist cache changes to disk when data has been modified. +// Always syncs complete state; never clears the disk file. // /////////////////////////////////////////////////////////////// void CServerCache::SaveServerCache(bool bWaitUntilFinished) @@ -211,7 +221,7 @@ void CServerCache::SaveServerCache(bool bWaitUntilFinished) ms_ServerCachedMap = m_ServerCachedMap; // Start save thread - HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CServerCache::StaticThreadProc, NULL, CREATE_SUSPENDED, NULL); + HANDLE hThread = CreateThread(NULL, 0, &CServerCache::StaticThreadProc, NULL, CREATE_SUSPENDED, NULL); if (!hThread) { CCore::GetSingleton().GetConsole()->Printf("Could not create server cache thread."); @@ -220,7 +230,14 @@ void CServerCache::SaveServerCache(bool bWaitUntilFinished) { ms_bIsSaving = true; SetThreadPriority(hThread, THREAD_PRIORITY_LOWEST); - ResumeThread(hThread); + + if (ResumeThread(hThread) == static_cast(-1)) + { + CCore::GetSingleton().GetConsole()->Printf("Could not start server cache thread."); + ms_bIsSaving = false; + } + + CloseHandle(hThread); } } @@ -238,7 +255,7 @@ void CServerCache::SaveServerCache(bool bWaitUntilFinished) // SaveServerCache thread // /////////////////////////////////////////////////////////////// -DWORD CServerCache::StaticThreadProc(LPVOID lpdwThreadParam) +DWORD WINAPI CServerCache::StaticThreadProc(LPVOID lpdwThreadParam) { StaticSaveServerCache(); ms_bIsSaving = false; @@ -249,7 +266,9 @@ DWORD CServerCache::StaticThreadProc(LPVOID lpdwThreadParam) // // CServerCache::StaticSaveServerCache // -// +// Synchronize cache to disk by writing all current in-memory entries. +// The XML tree is rebuilt on each save (not appended to) for consistency, +// but the file itself is never deleted. Servers are synced, not purged. // /////////////////////////////////////////////////////////////// void CServerCache::StaticSaveServerCache() @@ -266,18 +285,16 @@ void CServerCache::StaticSaveServerCache() if (!pNode) return; - // Start by clearing out all previous nodes + // Clear in-memory XML structure and rebuild from current cache state. + // This does NOT delete the disk file; it only rewrites its contents with current data. pNode->DeleteAllSubNodes(); // Transfer each item from m_ServerCachedMap into dataSet CDataInfoSet dataSet; - for (std::map::iterator it = ms_ServerCachedMap.begin(); it != ms_ServerCachedMap.end(); ++it) + for (const auto& [key, info] : ms_ServerCachedMap) { - const CCachedKey& key = it->first; - const CCachedInfo& info = it->second; - - // Don't save cache of non responding servers - if (info.nMaxPlayers == 0 || info.uiCacheNoReplyCount > 3) + // Only exclude servers that have failed multiple consecutive query attempts + if (info.uiCacheNoReplyCount > 3) continue; SDataInfoItem item; @@ -320,6 +337,9 @@ void CServerCache::StaticSaveServerCache() /////////////////////////////////////////////////////////////// void CServerCache::GetServerCachedInfo(CServerListItem* pItem) { + if (!pItem) + return; + CCachedKey key; key.ulIp = pItem->Address.s_addr; key.usGamePort = pItem->usGamePort; @@ -329,9 +349,9 @@ void CServerCache::GetServerCachedInfo(CServerListItem* pItem) { pItem->SetDataQuality(SERVER_INFO_CACHE); - pItem->nPlayers = pInfo->nPlayers; - pItem->nMaxPlayers = pInfo->nMaxPlayers; - pItem->nPing = pInfo->nPing; + pItem->nPlayers = static_cast(pInfo->nPlayers); + pItem->nMaxPlayers = static_cast(pInfo->nMaxPlayers); + pItem->nPing = static_cast(pInfo->nPing); pItem->bPassworded = (pInfo->bPassworded != 0); pItem->bKeepFlag = (pInfo->bKeepFlag != 0); pItem->strName = pInfo->strName; @@ -339,8 +359,8 @@ void CServerCache::GetServerCachedInfo(CServerListItem* pItem) pItem->strMap = pInfo->strMap; pItem->strVersion = pInfo->strVersion; pItem->uiCacheNoReplyCount = pInfo->uiCacheNoReplyCount; - pItem->m_usHttpPort = pInfo->usHttpPort; - pItem->m_ucSpecialFlags = pInfo->ucSpecialFlags; + pItem->m_usHttpPort = static_cast(pInfo->usHttpPort); + pItem->m_ucSpecialFlags = static_cast(pInfo->ucSpecialFlags); pItem->PostChange(); } else if (pItem->GetDataQuality() < SERVER_INFO_QUERY) @@ -353,11 +373,11 @@ void CServerCache::GetServerCachedInfo(CServerListItem* pItem) if (pItem->strVersion.empty()) pItem->strVersion = pInfo->strVersion; if (pItem->nPing == 9999) - pItem->nPing = pInfo->nPing; + pItem->nPing = static_cast(pInfo->nPing); if (pItem->m_usHttpPort == 0) - pItem->m_usHttpPort = pInfo->usHttpPort; + pItem->m_usHttpPort = static_cast(pInfo->usHttpPort); if (pItem->m_ucSpecialFlags == 0) - pItem->m_ucSpecialFlags = pInfo->ucSpecialFlags; + pItem->m_ucSpecialFlags = static_cast(pInfo->ucSpecialFlags); } } } @@ -371,6 +391,9 @@ void CServerCache::GetServerCachedInfo(CServerListItem* pItem) /////////////////////////////////////////////////////////////// void CServerCache::SetServerCachedInfo(const CServerListItem* pItem) { + if (!pItem) + return; + CCachedKey key; key.ulIp = pItem->Address.s_addr; key.usGamePort = pItem->usGamePort; @@ -417,16 +440,22 @@ void CServerCache::SetServerCachedInfo(const CServerListItem* pItem) /////////////////////////////////////////////////////////////// void CServerCache::GetServerListCachedInfo(CServerList* pList) { - // Get cached info for each server - for (CServerListIterator it = pList->IteratorBegin(); it != pList->IteratorEnd(); it++) - GetServerCachedInfo(*it); + if (!pList) + return; + + for (auto it = pList->IteratorBegin(); it != pList->IteratorEnd(); ++it) + { + if (*it) + GetServerCachedInfo(*it); + } - // Remove servers not in serverlist from cache std::map nextServerCachedMap; - for (CServerListIterator it = pList->IteratorBegin(); it != pList->IteratorEnd(); it++) + for (auto it = pList->IteratorBegin(); it != pList->IteratorEnd(); ++it) { CServerListItem* pItem = *it; - CCachedKey key; + if (!pItem) + continue; + CCachedKey key; key.ulIp = pItem->Address.s_addr; key.usGamePort = pItem->usGamePort; if (CCachedInfo* pInfo = MapFind(m_ServerCachedMap, key)) @@ -435,6 +464,25 @@ void CServerCache::GetServerListCachedInfo(CServerList* pList) m_ServerCachedMap = nextServerCachedMap; } +/////////////////////////////////////////////////////////////// +// +// CServerCache::SetServerListCachedInfo +// +// Cache all servers in list +// +/////////////////////////////////////////////////////////////// +void CServerCache::SetServerListCachedInfo(CServerList* pList) +{ + if (!pList) + return; + + for (auto it = pList->IteratorBegin(); it != pList->IteratorEnd(); ++it) + { + if (*it) + SetServerCachedInfo(*it); + } +} + /////////////////////////////////////////////////////////////// // // CServerCache::GenerateServerList @@ -442,15 +490,17 @@ void CServerCache::GetServerListCachedInfo(CServerList* pList) // Create serverlist content from the cache // /////////////////////////////////////////////////////////////// -bool CServerCache::GenerateServerList(CServerList* pList) +bool CServerCache::GenerateServerList(CServerList* pList, bool bAllowNonResponding) { - for (std::map::iterator it = m_ServerCachedMap.begin(); it != m_ServerCachedMap.end(); ++it) - { - const CCachedKey& key = it->first; - const CCachedInfo& info = it->second; + if (!pList) + return false; - // Don't add non responding servers - if (info.nMaxPlayers == 0 || info.uiCacheNoReplyCount > 3) + for (const auto& [key, info] : m_ServerCachedMap) + { + // When master server is offline, include all cached servers. Otherwise exclude servers that + // have consistently failed to respond (uiCacheNoReplyCount > 3). New servers without response data + // should still be included since they may not have been queried yet. + if (!bAllowNonResponding && (info.uiCacheNoReplyCount > 3)) continue; ushort usGamePort = key.usGamePort; diff --git a/Client/core/ServerBrowser/CServerCache.h b/Client/core/ServerBrowser/CServerCache.h index 4fa83c0c6c6..ec8327553cb 100644 --- a/Client/core/ServerBrowser/CServerCache.h +++ b/Client/core/ServerBrowser/CServerCache.h @@ -10,6 +10,9 @@ * *****************************************************************************/ +class CServerList; +class CServerListItem; + class CServerCacheInterface { public: @@ -18,7 +21,8 @@ class CServerCacheInterface virtual void GetServerCachedInfo(CServerListItem* pItem) = 0; virtual void SetServerCachedInfo(const CServerListItem* pItem) = 0; virtual void GetServerListCachedInfo(CServerList* pList) = 0; - virtual bool GenerateServerList(CServerList* pList) = 0; + virtual bool GenerateServerList(CServerList* pList, bool bAllowNonResponding = false) = 0; + virtual void SetServerListCachedInfo(CServerList* pList) = 0; // Cache all servers in the list }; CServerCacheInterface* GetServerCache(); diff --git a/Client/core/ServerBrowser/CServerInfo.cpp b/Client/core/ServerBrowser/CServerInfo.cpp index 8cdf4f8515b..acef9c7c1e0 100644 --- a/Client/core/ServerBrowser/CServerInfo.cpp +++ b/Client/core/ServerBrowser/CServerInfo.cpp @@ -48,7 +48,7 @@ CServerInfo::CServerInfo() unsigned int LabelPosX = LabelTitlePosX + LabelTitleSizeX + 2; unsigned int LabelSizeX = INFO_WINDOW_DEFAULTWIDTH; unsigned int LabelSizeY = 15; - unsigned int DrawPosY = 10; // Start position + unsigned int DrawPosY = 10; // Start position // Server Name m_pServerNameLabelTitle = reinterpret_cast(pManager->CreateLabel(m_pWindow, _("Name:"))); m_pServerNameLabelTitle->SetPosition(CVector2D(LabelTitlePosX, DrawPosY += INFO_LABEL_VSPACING + LabelSizeY), false); @@ -178,15 +178,12 @@ CServerInfo::CServerInfo() m_pCheckboxAutojoin->AutoSize(m_pCheckboxAutojoin->GetText().c_str(), 20.0f, LabelSizeY); m_pCheckboxAutojoin->SetPosition( CVector2D((INFO_WINDOW_DEFAULTWIDTH - m_pCheckboxAutojoin->GetSize().fX) / 2, DrawPosY - INFO_WINDOW_VSPACING - LabelSizeY * 2), - false); // Horizontally center align + false); // Horizontally center align } CServerInfo::~CServerInfo() { // Delete our GUI elements - delete m_pWindow; - m_pWindow = 0; - delete m_pServerNameLabel; m_pServerNameLabel = 0; @@ -246,6 +243,9 @@ CServerInfo::~CServerInfo() delete m_pEnterPasswordEdit; m_pEnterPasswordEdit = 0; + + delete m_pWindow; + m_pWindow = 0; } bool CServerInfo::OnCloseClicked(CGUIElement* pElement) @@ -333,84 +333,166 @@ void CServerInfo::Show(eWindowType WindowType, const char* szHost, unsigned shor void CServerInfo::SetServerInformation(const char* szHost, unsigned short usPort, const char* szPassword, CServerListItem* pInitialServerListItem) { - // Store the parameters in our class instance for later use m_usPort = usPort; + m_strPassword = szPassword ? szPassword : ""; + m_strHost = szHost ? szHost : ""; - m_strPassword = szPassword; - m_strHost = szHost; - - // Create a winsock address endpoint and parse the IP into it in_addr Address; - CServerListItem::Parse(szHost, Address); - - // Set our server query's address, query port and game port + memset(&Address, 0, sizeof(Address)); + if (!CServerListItem::Parse(szHost, Address)) + Address.S_un.S_addr = 0; + + m_Server.CancelPendingQuery(); + + // Clear stale address data before applying the new endpoint + m_Server.Address.S_un.S_addr = 0; + m_Server.AddressCopy.S_un.S_addr = 0; + m_Server.usGamePort = 0; + m_Server.usGamePortCopy = 0; + m_Server.strHost = ""; + m_Server.strEndpoint = ""; + m_Server.strEndpointSortKey = ""; + m_Server.bScanned = false; + m_Server.bSkipped = false; + + // Assign the new address details m_Server.ChangeAddress(Address, usPort); - if (pInitialServerListItem) // If we have a pointer to an already scanned server, we initially set text to this - ResetServerGUI(pInitialServerListItem); - else // Otherwise, reset it to blank text + if (m_Server.Address.S_un.S_addr != Address.S_un.S_addr || m_Server.usGamePort != usPort) + { + m_Server.Address = Address; + m_Server.usGamePort = usPort; + } + + m_Server.AddressCopy = m_Server.Address; + m_Server.usGamePortCopy = m_Server.usGamePort; + + const uchar* addressBytes = reinterpret_cast(&m_Server.Address.S_un.S_addr); + SString strAddressHost = inet_ntoa(m_Server.Address); + if (strAddressHost.empty()) + strAddressHost = szHost; + m_Server.strHost = strAddressHost; + m_Server.strEndpoint = SString("%s:%u", *strAddressHost, m_Server.usGamePort); + m_Server.strEndpointSortKey = SString("%02x%02x%02x%02x-%04x", addressBytes[0], addressBytes[1], addressBytes[2], addressBytes[3], m_Server.usGamePort); + + if (pInitialServerListItem && CServerListItem::StaticIsValid(pInitialServerListItem)) + { + m_Server.strName = pInitialServerListItem->strName; + m_Server.strSearchableName = pInitialServerListItem->strSearchableName; + m_Server.strHostName = pInitialServerListItem->strHostName; + m_Server.strGameName = pInitialServerListItem->strGameName; + m_Server.strGameMode = pInitialServerListItem->strGameMode; + m_Server.strMap = pInitialServerListItem->strMap; + m_Server.strVersion = pInitialServerListItem->strVersion; + m_Server.nPlayers = pInitialServerListItem->nPlayers; + m_Server.nMaxPlayers = pInitialServerListItem->nMaxPlayers; + m_Server.nPing = pInitialServerListItem->nPing; + m_Server.bPassworded = pInitialServerListItem->bPassworded; + m_Server.bSerials = pInitialServerListItem->bSerials; + m_Server.isStatusVerified = pInitialServerListItem->isStatusVerified; + m_Server.bMaybeOffline = pInitialServerListItem->bMaybeOffline; + m_Server.bMasterServerSaysNoResponse = pInitialServerListItem->bMasterServerSaysNoResponse; + m_Server.uiMasterServerSaysRestrictions = pInitialServerListItem->uiMasterServerSaysRestrictions; + m_Server.vecPlayers = pInitialServerListItem->vecPlayers; + m_Server.uiTieBreakPosition = pInitialServerListItem->uiTieBreakPosition; + m_Server.strTieBreakSortKey = pInitialServerListItem->strTieBreakSortKey; + m_Server.strNameSortKey = pInitialServerListItem->strNameSortKey; + m_Server.strVersionSortKey = pInitialServerListItem->strVersionSortKey; + m_Server.m_iBuildType = pInitialServerListItem->m_iBuildType; + m_Server.m_iBuildNumber = pInitialServerListItem->m_iBuildNumber; + m_Server.m_usHttpPort = pInitialServerListItem->m_usHttpPort; + m_Server.m_ucSpecialFlags = pInitialServerListItem->m_ucSpecialFlags; + m_Server.SetDataQuality(pInitialServerListItem->GetDataQuality()); + m_Server.bScanned = true; + m_Server.bSkipped = false; + + if (!pInitialServerListItem->strHost.empty()) + m_Server.strHost = pInitialServerListItem->strHost; + if (!pInitialServerListItem->strEndpoint.empty()) + m_Server.strEndpoint = pInitialServerListItem->strEndpoint; + if (!pInitialServerListItem->strEndpointSortKey.empty()) + m_Server.strEndpointSortKey = pInitialServerListItem->strEndpointSortKey; + + ResetServerGUI(&m_Server); + } + else + { Reset(); + } - m_pServerAddressLabel->SetText(SString("%s:%u", szHost, usPort)); + const SString strDisplayedEndpoint = !m_Server.strEndpoint.empty() ? m_Server.strEndpoint : SString("%s:%u", szHost, usPort); + m_pServerAddressLabel->SetText(strDisplayedEndpoint); - // Lets query the server now, as the previous data is out of date + // Start a fresh query so we get the latest data for this server Refresh(); } void CServerInfo::DoPulse() { - // Are we visible? - if (IsVisible()) + if (!IsVisible()) { - // Pulse the server query - m_Server.Pulse(true); - - // Do we need a refresh? - if ((m_Server.bScanned && (CClientTime::GetTime() - m_ulLastUpdateTime) >= SERVER_UPDATE_INTERVAL)) + if (m_bWaitingToActivatePassword) { - // Are we queing, and is auto join enabled? - if (m_pCurrentWindowType == eWindowTypes::SERVER_INFO_QUEUE && m_pCheckboxAutojoin->GetSelected()) - { - // Is a slot available? - if (m_Server.nPlayers < m_Server.nMaxPlayers) - { - // Lets attempt to connect - Connect(); - return; - } - } + m_bWaitingToActivatePassword = false; + m_pWindow->Activate(); + m_pEnterPasswordEdit->Activate(); + } + return; + } - ResetServerGUI(&m_Server); + const unsigned long ulNow = CClientTime::GetTime(); + bool bRefreshed = false; - m_ulLastUpdateTime = CClientTime::GetTime(); + m_Server.Pulse(true); - // Query the server - Refresh(); - } - else if (m_Server.bSkipped) // Server query timed out - { - // Should we try to query again? - if (CClientTime::GetTime() - m_ulLastUpdateTime >= SERVER_UPDATE_INTERVAL) - { - // Query the server - Refresh(); - } + in_addr expectedAddress; + memset(&expectedAddress, 0, sizeof(expectedAddress)); + const bool bHasExpectedAddress = !m_strHost.empty() && CServerListItem::Parse(m_strHost.c_str(), expectedAddress); + const bool bAddressMatches = !bHasExpectedAddress || (expectedAddress.S_un.S_addr == m_Server.Address.S_un.S_addr && m_usPort == m_Server.usGamePort); + if (m_Server.bScanned) + { + if (bAddressMatches) + { ResetServerGUI(&m_Server); - // The server has timed out - m_pLatencyLabel->SetText(_("Timed Out")); + if (m_pCurrentWindowType == eWindowTypes::SERVER_INFO_QUEUE && m_pCheckboxAutojoin->GetSelected() && m_Server.nPlayers < m_Server.nMaxPlayers) + { + Connect(); + return; + } - m_ulLastUpdateTime = CClientTime::GetTime(); + m_ulLastUpdateTime = ulNow; } - - if (m_bWaitingToActivatePassword) + else { - m_bWaitingToActivatePassword = false; - m_pWindow->Activate(); - m_pEnterPasswordEdit->Activate(); + Refresh(); + bRefreshed = true; + m_ulLastUpdateTime = ulNow; } } + else if (m_Server.bSkipped) + { + ResetServerGUI(&m_Server); + m_pLatencyLabel->SetText(_("Timed Out")); + m_ulLastUpdateTime = ulNow; + + Refresh(); + bRefreshed = true; + } + + if (!bRefreshed && (ulNow - m_ulLastUpdateTime) >= SERVER_UPDATE_INTERVAL) + { + Refresh(); + m_ulLastUpdateTime = ulNow; + } + + if (m_bWaitingToActivatePassword) + { + m_bWaitingToActivatePassword = false; + m_pWindow->Activate(); + m_pEnterPasswordEdit->Activate(); + } } void CServerInfo::Refresh() @@ -451,12 +533,12 @@ void CServerInfo::Connect() std::string strPassword = m_strPassword; if (m_pCurrentWindowType == eWindowTypes::SERVER_INFO_PASSWORD) strPassword = m_pEnterPasswordEdit->GetText(); - else if (m_Server.bPassworded) // If we're not in a passworded window, but the server is passworded + else if (m_Server.bPassworded) // If we're not in a passworded window, but the server is passworded { // Try to grab a saved password strPassword = g_pCore->GetLocalGUI()->GetMainMenu()->GetServerBrowser()->GetServerPassword(m_Server.GetEndpoint().c_str()); - if (strPassword.empty()) // No password could be found, repopup the window in password mode. + if (strPassword.empty()) // No password could be found, repopup the window in password mode. { Show(eWindowTypes::SERVER_INFO_PASSWORD, m_Server.strHost.c_str(), m_Server.usGamePort, "", &m_Server); return; @@ -477,7 +559,7 @@ void CServerInfo::ResetServerGUI(CServerListItem* pServer) m_pGamemodeLabel->SetText(pServer->strGameMode.c_str()); m_pMapLabel->SetText(pServer->strMap.c_str()); m_pPlayersLabel->SetText(SString("%d / %d %s", pServer->nPlayers, pServer->nMaxPlayers, *strVerified).c_str()); - + m_pPasswordedLabel->SetText(pServer->bPassworded ? _("Yes") : _("No")); m_pLatencyLabel->SetText(SString("%i", pServer->nPing)); diff --git a/Client/core/ServerBrowser/CServerInfo.h b/Client/core/ServerBrowser/CServerInfo.h index a8de728e21d..4495310eb73 100644 --- a/Client/core/ServerBrowser/CServerInfo.h +++ b/Client/core/ServerBrowser/CServerInfo.h @@ -17,14 +17,14 @@ class CServerInfo; #define SERVER_UPDATE_INTERVAL 2500 // Dimensions for our window -#define INFO_WINDOW_DEFAULTWIDTH 370.0f +#define INFO_WINDOW_DEFAULTWIDTH 370.0f #define INFO_WINDOW_DEFAULTHEIGHT 400.0f #define INFO_WINDOW_HSPACING 20 -#define INFO_LABEL_VSPACING 0 +#define INFO_LABEL_VSPACING 0 #define INFO_WINDOW_VSPACING 10 -#define INFO_BUTTON_HEIGHT 25 -#define INFO_BUTTON_WIDTH 110 +#define INFO_BUTTON_HEIGHT 25 +#define INFO_BUTTON_WIDTH 110 #include "CServerList.h" #include "CSingleton.h" diff --git a/Client/core/ServerBrowser/CServerList.cpp b/Client/core/ServerBrowser/CServerList.cpp index 9a30719f444..9c2b1d046ee 100644 --- a/Client/core/ServerBrowser/CServerList.cpp +++ b/Client/core/ServerBrowser/CServerList.cpp @@ -48,6 +48,22 @@ void CServerList::Clear() m_llLastTickCount = 0; } +void CServerList::SuspendActivity() +{ + for (auto it = m_Servers.begin(); it != m_Servers.end(); ++it) + { + if (CServerListItem* pServer = *it) + pServer->CancelPendingQuery(); + } + + m_iPass = 0; + m_nScanned = 0; + m_nSkipped = 0; + m_llLastTickCount = 0; + m_strStatus = _("Idle"); + m_strStatus2.clear(); +} + void CServerList::Pulse() { // Get QueriesPerSecond setting @@ -90,7 +106,7 @@ void CServerList::Pulse() std::vector endpointList; CCore::GetSingleton().GetLocalGUI()->GetMainMenu()->GetServerBrowser()->GetVisibleEndPointList(endpointList); - for (std::vector::iterator iter = endpointList.begin(); iter != endpointList.end(); ++iter) + for (auto iter = endpointList.begin(); iter != endpointList.end(); ++iter) { CServerListItem* pServer = m_Servers.Find((in_addr&)iter->m_ulIp, iter->m_usPort); if (pServer && pServer->WaitingToSendQuery()) @@ -105,13 +121,15 @@ void CServerList::Pulse() } // Scan all servers in our list, and keep the value of scanned servers - for (CServerListIterator i = m_Servers.begin(); i != m_Servers.end(); i++) + for (auto i = m_Servers.begin(); i != m_Servers.end(); ++i) { CServerListItem* pServer = *i; - uint uiPrevRevision = pServer->uiRevision; - std::string strResult = pServer->Pulse((int)(uiQueriesSent /*+ uiQueriesResent*/) < iNumQueries, bRemoveNonResponding); + if (!pServer) + continue; + uint uiPrevRevision = pServer->uiRevision; + std::string strResult = pServer->Pulse((int)(uiQueriesSent /*+ uiQueriesResent*/) < iNumQueries, bRemoveNonResponding); if (uiPrevRevision != pServer->uiRevision) - m_bUpdated |= true; // Flag GUI update + m_bUpdated |= true; // Flag GUI update if (strResult == "SentQuery") uiQueriesSent++; else if (strResult == "ResentQuery") @@ -121,7 +139,7 @@ void CServerList::Pulse() else if (strResult == "NoReply") uiNoReplies++; - if (pServer->nMaxPlayers && !pServer->bMaybeOffline && !pServer->MaybeWontRespond()) + if (pServer->nMaxPlayers > 0) { uiActiveServers++; uiTotalSlots += pServer->nMaxPlayers; @@ -176,12 +194,12 @@ bool CServerList::Remove(in_addr Address, ushort usGamePort) } void CServerList::Refresh() -{ // Assumes we already have a (saved) list of servers, so we just need to refresh +{ // Assumes we already have a (saved) list of servers, so we just need to refresh // Reinitialize each server list item - for (std::list::iterator iter = m_Servers.begin(); iter != m_Servers.end(); iter++) + for (auto it = m_Servers.begin(); it != m_Servers.end(); ++it) { - CServerListItem* pOldItem = *iter; + CServerListItem* pOldItem = *it; assert(pOldItem->m_pItemList == &m_Servers); pOldItem->ResetForRefresh(); } @@ -200,24 +218,58 @@ CServerListInternet::CServerListInternet() CServerListInternet::~CServerListInternet() { + if (m_pMasterServerManager) + m_pMasterServerManager->CancelRefresh(); delete m_pMasterServerManager; m_pMasterServerManager = NULL; } +void CServerListInternet::SuspendActivity() +{ + CServerList::SuspendActivity(); + if (m_pMasterServerManager) + m_pMasterServerManager->CancelRefresh(); +} + void CServerListInternet::Refresh() -{ // Gets the server list from the master server and refreshes +{ // Gets the server list from the master server and refreshes m_ElapsedTime.Reset(); + + // Load from cache first to ensure servers are always available instantly + // This populates the list with cached server data before fetching fresh data + if (m_Servers.size() == 0) + { + GetServerCache()->GenerateServerList(this, true); // true = allow all cached servers + GetServerCache()->GetServerListCachedInfo(this); + } + + // Reset no-reply counters to retry previously non-responding servers + // This is called on manual refresh via button click + RetryNonRespondingServers(); + m_pMasterServerManager->Refresh(); m_iPass = 1; m_bUpdated = true; + m_bMasterServerOffline = false; // Reset offline flag on refresh attempt - // Clear the previous server list - Clear(); + // Don't clear the list - keep cached servers available while fetching fresh data + // Only reset servers for refresh without losing the cache + for (auto it = m_Servers.begin(); it != m_Servers.end(); ++it) + { + CServerListItem* pServer = *it; + if (pServer) + pServer->ResetForRefresh(); + } + m_nScanned = 0; + m_nSkipped = 0; + m_iRevision++; } static bool SortByASEVersionCallback(const CServerListItem* const d1, const CServerListItem* const d2) { - return d1->strVersionSortKey < d2->strVersionSortKey; + if (d1->strVersionSortKey != d2->strVersionSortKey) + return d1->strVersionSortKey < d2->strVersionSortKey; + return d1->uiTieBreakPosition < d2->uiTieBreakPosition; }; // @@ -228,8 +280,27 @@ void CServerList::SortByASEVersion() m_Servers.GetList().sort(SortByASEVersionCallback); } +/////////////////////////////////////////////////////////////// +// +// CServerList::RetryNonRespondingServers +// +// Reset no-reply counters for cached servers to give them another chance +// Called during manual refresh via button click +// +/////////////////////////////////////////////////////////////// +void CServerList::RetryNonRespondingServers() +{ + for (auto it = m_Servers.begin(); it != m_Servers.end(); ++it) + { + if (CServerListItem* pServer = *it) + { + pServer->ClearNoReplyCountForRetry(); + } + } +} + void CServerListInternet::Pulse() -{ // We also need to take care of the master server list here +{ // We also need to take care of the master server list here unsigned long ulTime = m_ElapsedTime.Get(); if (m_iPass == 1) @@ -245,8 +316,11 @@ void CServerListInternet::Pulse() if (m_pMasterServerManager->ParseList(m_Servers)) { m_iPass++; + // Cache all newly discovered servers from the master list + GetServerCache()->SetServerListCachedInfo(this); GetServerCache()->GetServerListCachedInfo(this); SortByASEVersion(); + m_iRevision++; } else { @@ -267,10 +341,16 @@ void CServerListInternet::Pulse() } if (m_iPass == 0) { - // If query failed, load from backup - GetServerCache()->GenerateServerList(this); + // If query failed, mark master server as offline and load from backup + m_bMasterServerOffline = true; + GetServerCache()->GenerateServerList(this, true); // true = allow all cached servers GetServerCache()->GetServerListCachedInfo(this); + + // Reset no-reply counters for cached servers to give them another chance + RetryNonRespondingServers(); + SortByASEVersion(); + m_iRevision++; m_strStatus2 = " " + _("(Backup server list)"); m_iPass = 2; } @@ -282,6 +362,24 @@ void CServerListInternet::Pulse() } } +/////////////////////////////////////////////////////////////// +// +// CServerListInternet::RemoveNonResponding +// +// Override to prevent removing servers when master server is offline +// +/////////////////////////////////////////////////////////////// +bool CServerListInternet::RemoveNonResponding() +{ + // Don't remove non-responding servers if master server is offline + // This allows cached servers to be retained and queried + if (m_bMasterServerOffline) + return false; + + // Otherwise, use standard logic: Don't remove until net access is confirmed + return m_nScanned > 10; +} + void CServerListLAN::Pulse() { char szBuffer[32]; @@ -312,17 +410,27 @@ void CServerListLAN::Pulse() } void CServerListLAN::Refresh() -{ // Gets the server list from LAN-broadcasting servers +{ // Gets the server list from LAN-broadcasting servers m_iPass = 1; m_bUpdated = true; // Create the LAN-broadcast socket - closesocket(m_Socket); + if (m_Socket != INVALID_SOCKET) + closesocket(m_Socket); + m_Socket = socket(AF_INET, SOCK_DGRAM, 0); + if (m_Socket == INVALID_SOCKET) + { + m_strStatus = _("Cannot create LAN-broadcast socket"); + return; + } + const int Flags = 1; - setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&Flags, sizeof(Flags)); - if (setsockopt(m_Socket, SOL_SOCKET, SO_BROADCAST, (const char*)&Flags, sizeof(Flags)) != 0) + if (setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&Flags, sizeof(Flags)) != 0 || + setsockopt(m_Socket, SOL_SOCKET, SO_BROADCAST, (const char*)&Flags, sizeof(Flags)) != 0) { + closesocket(m_Socket); + m_Socket = INVALID_SOCKET; m_strStatus = _("Cannot bind LAN-broadcast socket"); return; } @@ -340,11 +448,38 @@ void CServerListLAN::Refresh() Discover(); } +CServerListLAN::CServerListLAN() : m_Socket(INVALID_SOCKET), m_ulStartTime(0) +{ + memset(&m_Remote, 0, sizeof(m_Remote)); +} + +CServerListLAN::~CServerListLAN() +{ + if (m_Socket != INVALID_SOCKET) + { + closesocket(m_Socket); + m_Socket = INVALID_SOCKET; + } +} + +void CServerListLAN::SuspendActivity() +{ + CServerList::SuspendActivity(); + if (m_Socket != INVALID_SOCKET) + { + closesocket(m_Socket); + m_Socket = INVALID_SOCKET; + } +} + void CServerListLAN::Discover() { m_strStatus = _("Attempting to discover LAN servers"); // Send out the broadcast packet + if (m_Socket == INVALID_SOCKET) + return; + std::string strQuery = std::string(SERVER_LIST_CLIENT_BROADCAST_STR) + " " + std::string(MTA_DM_ASE_VERSION); sendto(m_Socket, strQuery.c_str(), strQuery.length() + 1, 0, (sockaddr*)&m_Remote, sizeof(m_Remote)); @@ -353,7 +488,7 @@ void CServerListLAN::Discover() } std::string CServerListItem::Pulse(bool bCanSendQuery, bool bRemoveNonResponding) -{ // Queries the server on it's query port (ASE protocol) +{ // Queries the server on it's query port (ASE protocol) // and returns whether it is done scanning if (bScanned || bSkipped) return "Done"; @@ -375,8 +510,8 @@ std::string CServerListItem::Pulse(bool bCanSendQuery, bool bRemoveNonResponding bMaybeOffline = false; SetDataQuality(SERVER_INFO_QUERY); uiCacheNoReplyCount = 0; - uiRevision++; // To flag browser gui update - GetServerCache()->SetServerCachedInfo(this); // Save parsed info in the cache + uiRevision++; // To flag browser gui update + GetServerCache()->SetServerCachedInfo(this); // Save parsed info in the cache return "ParsedQuery"; } @@ -414,16 +549,18 @@ std::string CServerListItem::Pulse(bool bCanSendQuery, bool bRemoveNonResponding if (bRemoveNonResponding) { - bMaybeOffline = true; // Flag to help 'Include offline' browser option - nPlayers = 0; // We don't have player names, so zero this now + bMaybeOffline = true; // Flag to help 'Include offline' browser option + // Don't zero nPlayers - preserve last known count from master list or previous query + // Only zero vecPlayers since we don't have the actual player list + vecPlayers.clear(); } - uiRevision++; // To flag browser gui update + uiRevision++; // To flag browser gui update if (uiQueryRetryCount < GetMaxRetries()) { // Try again uiQueryRetryCount++; - uiRevision++; // To flag browser gui update + uiRevision++; // To flag browser gui update if (GetDataQuality() > SERVER_INFO_ASE_0) GetServerCache()->SetServerCachedInfo(this); Query(); @@ -433,12 +570,12 @@ std::string CServerListItem::Pulse(bool bCanSendQuery, bool bRemoveNonResponding { // Give up queryReceiver.InvalidateSocket(); - uiRevision++; // To flag browser gui update + uiRevision++; // To flag browser gui update if (bRemoveNonResponding) { - uiCacheNoReplyCount++; // Keep a persistent count of failures. (When uiCacheNoReplyCount gets to 3, the server is removed from - // the Server Cache) + uiCacheNoReplyCount++; // Keep a persistent count of failures. (When uiCacheNoReplyCount gets to 3, the server is removed from + // the Server Cache) bSkipped = true; if (GetDataQuality() > SERVER_INFO_ASE_0) GetServerCache()->SetServerCachedInfo(this); @@ -463,7 +600,7 @@ unsigned short CServerListItem::GetQueryPort() } void CServerListItem::Query() -{ // Performs a query according to ASE protocol +{ // Performs a query according to ASE protocol queryReceiver.RequestQuery(Address, GetQueryPort()); } @@ -480,38 +617,40 @@ bool CServerListItem::ParseQuery() nPing = info.pingTime; // Only use info from server query if master list allows it - if ((uiMasterServerSaysRestrictions & RESTRICTION_GAME_NAME) == false) + bool bMasterServerOffline = (uiMasterServerSaysRestrictions == 0); + + if (bMasterServerOffline || (uiMasterServerSaysRestrictions & RESTRICTION_GAME_NAME) == false) strGameName = info.gameName; - if ((uiMasterServerSaysRestrictions & RESTRICTION_SERVER_NAME) == false) + if (bMasterServerOffline || (uiMasterServerSaysRestrictions & RESTRICTION_SERVER_NAME) == false) strName = info.serverName; - if ((uiMasterServerSaysRestrictions & RESTRICTION_GAME_MODE) == false) + if (bMasterServerOffline || (uiMasterServerSaysRestrictions & RESTRICTION_GAME_MODE) == false) strGameMode = info.gameType; - if ((uiMasterServerSaysRestrictions & RESTRICTION_MAP_NAME) == false) + if (bMasterServerOffline || (uiMasterServerSaysRestrictions & RESTRICTION_MAP_NAME) == false) strMap = info.mapName; - if ((uiMasterServerSaysRestrictions & RESTRICTION_SERVER_VERSION) == false) + if (bMasterServerOffline || (uiMasterServerSaysRestrictions & RESTRICTION_SERVER_VERSION) == false) strVersion = info.versionText; - if ((uiMasterServerSaysRestrictions & RESTRICTION_PASSWORDED_FLAG) == false) + if (bMasterServerOffline || (uiMasterServerSaysRestrictions & RESTRICTION_PASSWORDED_FLAG) == false) bPassworded = info.isPassworded; - if ((uiMasterServerSaysRestrictions & RESTRICTION_SERIALS_FLAG) == false) + if (bMasterServerOffline || (uiMasterServerSaysRestrictions & RESTRICTION_SERIALS_FLAG) == false) bSerials = info.serials; - if ((uiMasterServerSaysRestrictions & RESTRICTION_PLAYER_COUNT) == false) + if (bMasterServerOffline || (uiMasterServerSaysRestrictions & RESTRICTION_PLAYER_COUNT) == false) nPlayers = info.players; - if ((uiMasterServerSaysRestrictions & RESTRICTION_MAX_PLAYER_COUNT) == false) + if (bMasterServerOffline || (uiMasterServerSaysRestrictions & RESTRICTION_MAX_PLAYER_COUNT) == false) nMaxPlayers = info.playerSlot; m_iBuildType = info.buildType; m_iBuildNumber = info.buildNum; m_usHttpPort = info.httpPort; - if ((uiMasterServerSaysRestrictions & RESTRICTION_PLAYER_LIST) == false) + if (bMasterServerOffline || (uiMasterServerSaysRestrictions & RESTRICTION_PLAYER_LIST) == false) vecPlayers = info.playersPool; isStatusVerified = info.isStatusVerified; @@ -698,6 +837,34 @@ void CServerListItem::ResetForRefresh() bMaybeOffline = false; } +/////////////////////////////////////////////////////////////// +// +// CServerListItem::ClearNoReplyCountForRetry +// +// Reset no-reply counter to allow retrying previously non-responding servers +// Called on manual refresh to give cached servers another chance +// +/////////////////////////////////////////////////////////////// +void CServerListItem::ClearNoReplyCountForRetry() +{ + // Only reset for servers that had some failures + if (uiCacheNoReplyCount > 0) + { + // Don't completely reset - just reduce to allow retries + // This way if a server is permanently down, it will accumulate again + uiCacheNoReplyCount = 0; + bSkipped = false; + uiQueryRetryCount = 0; + } +} + +void CServerListItem::CancelPendingQuery() +{ + queryReceiver.InvalidateSocket(); + m_bDoneTcpSend = false; + m_bDoPostTcpQuery = false; +} + void CServerListItem::ChangeAddress(in_addr _Address, unsigned short _usGamePort) { if (m_pItemList) @@ -710,3 +877,121 @@ void CServerListItem::ChangeAddress(in_addr _Address, unsigned short _usGamePort usGamePort = _usGamePort; } } + +namespace +{ + // Comparators + bool CompareVersionAsc(const CServerListItem* a, const CServerListItem* b) + { + return a->strVersionSortKey < b->strVersionSortKey; + } + bool CompareVersionDesc(const CServerListItem* a, const CServerListItem* b) + { + return a->strVersionSortKey > b->strVersionSortKey; + } + + bool CompareLockedAsc(const CServerListItem* a, const CServerListItem* b) + { + if (a->bPassworded != b->bPassworded) + return a->bPassworded < b->bPassworded; + return a->strNameSortKey < b->strNameSortKey; + } + bool CompareLockedDesc(const CServerListItem* a, const CServerListItem* b) + { + if (a->bPassworded != b->bPassworded) + return a->bPassworded > b->bPassworded; + return a->strNameSortKey < b->strNameSortKey; + } + + bool CompareNameAsc(const CServerListItem* a, const CServerListItem* b) + { + return a->strNameSortKey < b->strNameSortKey; + } + bool CompareNameDesc(const CServerListItem* a, const CServerListItem* b) + { + return a->strNameSortKey > b->strNameSortKey; + } + + bool ComparePlayersAsc(const CServerListItem* a, const CServerListItem* b) + { + if (a->nPlayers != b->nPlayers) + return a->nPlayers < b->nPlayers; + if (a->nMaxPlayers != b->nMaxPlayers) + return a->nMaxPlayers < b->nMaxPlayers; + return a->strNameSortKey < b->strNameSortKey; + } + bool ComparePlayersDesc(const CServerListItem* a, const CServerListItem* b) + { + if (a->nPlayers != b->nPlayers) + return a->nPlayers > b->nPlayers; + if (a->nMaxPlayers != b->nMaxPlayers) + return a->nMaxPlayers > b->nMaxPlayers; + return a->strNameSortKey < b->strNameSortKey; + } + + bool ComparePingAsc(const CServerListItem* a, const CServerListItem* b) + { + if (a->nPing != b->nPing) + return a->nPing < b->nPing; + return a->strNameSortKey < b->strNameSortKey; + } + bool ComparePingDesc(const CServerListItem* a, const CServerListItem* b) + { + if (a->nPing != b->nPing) + return a->nPing > b->nPing; + return a->strNameSortKey < b->strNameSortKey; + } + + bool CompareGameModeAsc(const CServerListItem* a, const CServerListItem* b) + { + int cmp = a->strGameMode.CompareI(b->strGameMode); + if (cmp != 0) + return cmp < 0; + return a->strNameSortKey < b->strNameSortKey; + } + bool CompareGameModeDesc(const CServerListItem* a, const CServerListItem* b) + { + int cmp = a->strGameMode.CompareI(b->strGameMode); + if (cmp != 0) + return cmp > 0; + return a->strNameSortKey < b->strNameSortKey; + } +} + +void CServerListItemList::Sort(unsigned int uiColumn, int direction) +{ + if (direction == 0) // SortDirections::None + return; + + bool asc = (direction == 1); // SortDirections::Ascending + + switch (uiColumn) + { + case 1: // Version + m_List.sort(asc ? CompareVersionAsc : CompareVersionDesc); + break; + case 2: // Locked + m_List.sort(asc ? CompareLockedAsc : CompareLockedDesc); + break; + case 3: // Name + m_List.sort(asc ? CompareNameAsc : CompareNameDesc); + break; + case 4: // Players + m_List.sort(asc ? ComparePlayersAsc : ComparePlayersDesc); + break; + case 5: // Ping + m_List.sort(asc ? ComparePingAsc : ComparePingDesc); + break; + case 6: // Gamemode + m_List.sort(asc ? CompareGameModeAsc : CompareGameModeDesc); + break; + default: + // Invalid column - no sort applied + break; + } +} + +void CServerList::Sort(unsigned int uiColumn, int direction) +{ + m_Servers.Sort(uiColumn, direction); +} diff --git a/Client/core/ServerBrowser/CServerList.h b/Client/core/ServerBrowser/CServerList.h index 9215ed4d274..c1bd07a67f3 100644 --- a/Client/core/ServerBrowser/CServerList.h +++ b/Client/core/ServerBrowser/CServerList.h @@ -23,22 +23,22 @@ class CMasterServerManagerInterface; #include "CSingleton.h" // Master server list URL -#define SERVER_LIST_MASTER_URL "https://master.multitheftauto.com/ase/mta/" +#define SERVER_LIST_MASTER_URL "https://master.multitheftauto.com/ase/mta/" // Query response data buffer -#define SERVER_LIST_QUERY_BUFFER 4096 +#define SERVER_LIST_QUERY_BUFFER 4096 // Master server list timeout (in ms) -#define SERVER_LIST_MASTER_TIMEOUT 10000 +#define SERVER_LIST_MASTER_TIMEOUT 10000 // Maximum amount of server queries per pulse (so the list gradually streams in) -#define SERVER_LIST_QUERIES_PER_PULSE 2 +#define SERVER_LIST_QUERIES_PER_PULSE 2 // LAN packet broadcasting interval (in ms) -#define SERVER_LIST_BROADCAST_REFRESH 2000 +#define SERVER_LIST_BROADCAST_REFRESH 2000 // Timeout for one server in the server list to respond to a query (in ms) -#define SERVER_LIST_ITEM_TIMEOUT 8000 +#define SERVER_LIST_ITEM_TIMEOUT 8000 enum { @@ -142,7 +142,7 @@ class CServerListItem isStatusVerified = true; bPassworded = false; bKeepFlag = false; - iRowIndex = -1; + iRowIndex[0] = iRowIndex[1] = iRowIndex[2] = iRowIndex[3] = -1; nPlayers = 0; nMaxPlayers = 0; @@ -153,8 +153,7 @@ class CServerListItem bMaybeOffline = false; bMasterServerSaysNoResponse = false; uiMasterServerSaysRestrictions = 0; - for (int i = 0; i < SERVER_BROWSER_TYPE_COUNT; i++) - revisionInList[i] = -1; + revisionInList[0] = revisionInList[1] = revisionInList[2] = revisionInList[3] = -1; strHost = inet_ntoa(Address); strName = SString("%s:%d", inet_ntoa(Address), usGamePort); @@ -174,18 +173,20 @@ class CServerListItem std::string Pulse(bool bCanSendQuery, bool bRemoveNonResponding = false); void ResetForRefresh(); + void ClearNoReplyCountForRetry(); + void CancelPendingQuery(); unsigned short GetQueryPort(); - in_addr AddressCopy; // Copy to ensure it doesn't get changed without us knowing + in_addr AddressCopy; // Copy to ensure it doesn't get changed without us knowing unsigned short usGamePortCopy; - in_addr Address; // IP-address - unsigned short usGamePort; // Game port - unsigned short nPlayers; // Current players - unsigned short nMaxPlayers; // Maximum players - unsigned short nPing; // Ping time - bool isStatusVerified; // Ping status verified - bool bPassworded; // Password protected - bool bSerials; // Serial verification on + in_addr Address; // IP-address + unsigned short usGamePort; // Game port + unsigned short nPlayers; // Current players + unsigned short nMaxPlayers; // Maximum players + unsigned short nPing; // Ping time + bool isStatusVerified; // Ping status verified + bool bPassworded; // Password protected + bool bSerials; // Serial verification on bool bScanned; bool bSkipped; bool bMaybeOffline; @@ -196,26 +197,26 @@ class CServerListItem uint uiQueryRetryCount; uint uiRevision; bool bKeepFlag; - int iRowIndex; - - SString strGameName; // Game name. Always 'mta' - SString strVersion; // Game version - SString strName; // Server name - SString strSearchableName; // Server name to use for searches - SString strHost; // Server host as IP - SString strHostName; // Server host as name - SString strGameMode; // Gamemode - SString strMap; // Map name - SString strEndpoint; // IP:port as a string - - int m_iBuildType; // 9=release - int m_iBuildNumber; // 00000 and up + int iRowIndex[SERVER_BROWSER_TYPE_COUNT]; // Row index for each server browser tab - placed here for cache locality + + SString strGameName; // Game name. Always 'mta' + SString strVersion; // Game version + SString strName; // Server name + SString strSearchableName; // Server name to use for searches + SString strHost; // Server host as IP + SString strHostName; // Server host as name + SString strGameMode; // Gamemode + SString strMap; // Map name + SString strEndpoint; // IP:port as a string + + int m_iBuildType; // 9=release + int m_iBuildNumber; // 00000 and up ushort m_usHttpPort; uchar m_ucSpecialFlags; - SString strNameSortKey; // Server name as a sortable string - SString strVersionSortKey; // Game version as a sortable string - SString strEndpointSortKey; // IP:port as a sortable string + SString strNameSortKey; // Server name as a sortable string + SString strVersionSortKey; // Game version as a sortable string + SString strEndpointSortKey; // IP:port as a sortable string uint uiTieBreakPosition; SString strTieBreakSortKey; @@ -353,6 +354,7 @@ class CServerListItemList bool Remove(in_addr Address, ushort usGamePort); void RemoveItem(CServerListItem* pItem); void OnItemChangeAddress(CServerListItem* pItem, in_addr Address, ushort usGamePort); + void Sort(unsigned int uiColumn, int direction); }; class CServerList @@ -365,6 +367,7 @@ class CServerList virtual void Pulse(); virtual void Refresh(); virtual bool RemoveNonResponding() { return true; } + virtual void SuspendActivity(); CServerListIterator IteratorBegin() { return m_Servers.begin(); }; CServerListIterator IteratorEnd() { return m_Servers.end(); }; @@ -381,6 +384,8 @@ class CServerList void SetUpdated(bool bUpdated) { m_bUpdated = bUpdated; }; int GetRevision() { return m_iRevision; } void SortByASEVersion(); + void Sort(unsigned int uiColumn, int direction); + void RetryNonRespondingServers(); // Reset no-reply counters for cached servers protected: bool m_bUpdated; @@ -399,22 +404,28 @@ class CServerListInternet : public CServerList { public: CServerListInternet(); - ~CServerListInternet(); - void Pulse(); - void Refresh(); - bool RemoveNonResponding() { return m_nScanned > 10; } // Don't remove until net access is confirmed + ~CServerListInternet() override; + void Pulse() override; + void Refresh() override; + void SuspendActivity() override; + bool RemoveNonResponding() override; + bool IsMasterServerOffline() const { return m_bMasterServerOffline; } private: CMasterServerManagerInterface* m_pMasterServerManager; CElapsedTime m_ElapsedTime; + bool m_bMasterServerOffline = false; }; // LAN list (scans for LAN-broadcasted servers on refresh) class CServerListLAN : public CServerList { public: - void Pulse(); - void Refresh(); + CServerListLAN(); + ~CServerListLAN() override; + void Pulse() override; + void Refresh() override; + void SuspendActivity() override; private: void Discover(); diff --git a/Client/core/StackTraceHelpers.h b/Client/core/StackTraceHelpers.h new file mode 100644 index 00000000000..1611606363b --- /dev/null +++ b/Client/core/StackTraceHelpers.h @@ -0,0 +1,178 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: core/StackTraceHelpers.h + * PURPOSE: Crash handler component + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace StackTraceHelpers +{ + struct StackWalkRoutines + { + PREAD_PROCESS_MEMORY_ROUTINE64 readMemory = nullptr; + PFUNCTION_TABLE_ACCESS_ROUTINE64 functionTableAccess = nullptr; + PGET_MODULE_BASE_ROUTINE64 moduleBase = nullptr; + + bool operator==(const StackWalkRoutines&) const noexcept = default; + }; + + inline BOOL __stdcall LocalReadProcessMemory(HANDLE /*process*/, DWORD64 baseAddress, PVOID buffer, DWORD size, LPDWORD bytesRead) noexcept + { + if (buffer == nullptr || size == 0) [[unlikely]] + { + if (bytesRead) + *bytesRead = 0; + return FALSE; + } + + if (baseAddress > static_cast(UINT32_MAX)) [[unlikely]] + { + if (bytesRead) + *bytesRead = 0; + return FALSE; + } + + __try + { + const auto srcAddr = static_cast(baseAddress); + const auto srcPtr = reinterpret_cast(static_cast(srcAddr)); + const auto dest = std::span{reinterpret_cast(buffer), size}; + const auto srcSpan = std::span{srcPtr, size}; + std::ranges::copy(srcSpan, dest.begin()); + if (bytesRead) + *bytesRead = size; + return TRUE; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + if (bytesRead) + *bytesRead = 0; + return FALSE; + } + } + + inline DWORD64 __stdcall LocalGetModuleBase(HANDLE /*process*/, DWORD64 address) noexcept + { + constexpr DWORD64 max32BitAddress = static_cast(UINT32_MAX); + if (address > max32BitAddress) [[unlikely]] + return 0; + + MEMORY_BASIC_INFORMATION mbi{}; + const auto addr32 = static_cast(address); + if (VirtualQuery(reinterpret_cast(static_cast(addr32)), &mbi, sizeof(mbi)) == 0) [[unlikely]] + return 0; + + if (mbi.AllocationBase == nullptr) [[unlikely]] + return 0; + + return static_cast(reinterpret_cast(mbi.AllocationBase)); + } + + [[nodiscard]] inline StackWalkRoutines MakeStackWalkRoutines(bool useDbgHelp) noexcept + { + if (useDbgHelp) + { + return StackWalkRoutines{.readMemory = &LocalReadProcessMemory, .functionTableAccess = SymFunctionTableAccess64, .moduleBase = SymGetModuleBase64}; + } + + return StackWalkRoutines{.readMemory = &LocalReadProcessMemory, .functionTableAccess = nullptr, .moduleBase = &LocalGetModuleBase}; + } + + struct ModuleAddressInfo + { + std::string name; + DWORD64 base; + + bool operator==(const ModuleAddressInfo&) const noexcept = default; + }; + + [[nodiscard]] inline std::optional DescribeModule(DWORD64 address) + { + if (address == 0) [[unlikely]] + return std::nullopt; + + constexpr DWORD64 max32BitAddress = static_cast(UINT32_MAX); + if (address > max32BitAddress) [[unlikely]] + return std::nullopt; + + MEMORY_BASIC_INFORMATION mbi{}; + if (const auto addr32 = static_cast(address); + VirtualQuery(reinterpret_cast(static_cast(addr32)), &mbi, sizeof(mbi)) == 0) [[unlikely]] + return std::nullopt; + + if (mbi.AllocationBase == nullptr) [[unlikely]] + return std::nullopt; + + std::array modulePath{}; + const DWORD pathLen = GetModuleFileNameA(reinterpret_cast(mbi.AllocationBase), modulePath.data(), static_cast(modulePath.size())); + + if (pathLen == 0) [[unlikely]] + return std::nullopt; + + if (pathLen >= modulePath.size()) [[unlikely]] + { + modulePath.back() = '\0'; + return std::nullopt; + } + + const std::string_view modulePathView{modulePath.data(), pathLen}; + const auto lastSlash = modulePathView.find_last_of("\\/"); + const std::string_view moduleName = (lastSlash != std::string_view::npos) ? modulePathView.substr(lastSlash + 1) : modulePathView; + + ModuleAddressInfo info{.name = std::string{moduleName}, .base = static_cast(reinterpret_cast(mbi.AllocationBase))}; + return info; + } + + [[nodiscard]] inline std::string FormatAddressWithModule(DWORD64 address) + { + try + { + if (const auto moduleInfo = DescribeModule(address)) [[likely]] + { + const auto& [name, base] = *moduleInfo; + + if (address < base) [[unlikely]] + return std::format("0x{:X}", address); + + const DWORD64 offset = address - base; + return std::format("{}+0x{:X}", name, offset); + } + + return std::format("0x{:X}", address); + } + catch (const std::format_error&) + { + return ""; + } + } + + [[nodiscard]] inline std::string FormatAddressWithModuleAndAbsolute(DWORD64 address) + { + try + { + return std::format("{} [0x{:X}]", FormatAddressWithModule(address), address); + } + catch (const std::format_error&) + { + return ""; + } + } +} // namespace StackTraceHelpers diff --git a/Client/core/StdInc.cpp b/Client/core/StdInc.cpp index 2594336e532..4b8efdaa55b 100644 --- a/Client/core/StdInc.cpp +++ b/Client/core/StdInc.cpp @@ -1,2 +1,3 @@ // StdInc.h +#define BUGSUTIL_EXPORTS #include "StdInc.h" diff --git a/Client/core/StdInc.h b/Client/core/StdInc.h index cfebe65b270..ed062056554 100644 --- a/Client/core/StdInc.h +++ b/Client/core/StdInc.h @@ -1,7 +1,7 @@ // Pragmas -#pragma warning (disable:4995) -#pragma warning (disable:4244) +#pragma warning(disable : 4995) +#pragma warning(disable : 4244) // #define WIN32_LEAN_AND_MEAN #include @@ -9,6 +9,7 @@ #define SHARED_UTIL_WITH_FAST_HASH_MAP #define SHARED_UTIL_WITH_SYS_INFO #include "SharedUtil.h" +#include #include #include diff --git a/Client/core/premake5.lua b/Client/core/premake5.lua index 51bdad92ea2..961d09dc0f6 100644 --- a/Client/core/premake5.lua +++ b/Client/core/premake5.lua @@ -3,10 +3,10 @@ project "Client Core" kind "SharedLib" targetname "core" targetdir(buildpath("mta")) + clangtidy "On" filter "system:windows" includedirs { "../../vendor/sparsehash/src/windows" } - linkoptions { "/SAFESEH:NO" } buildoptions { "-Zm130" } filter {} @@ -14,6 +14,7 @@ project "Client Core" "../../Shared/sdk", ".", "../sdk", + "../../vendor/cegui-0.4.0-custom/include", "../../vendor/tinygettext", "../../vendor/zlib", "../../vendor/jpeg-9f", @@ -26,6 +27,11 @@ project "Client Core" pchheader "StdInc.h" pchsource "StdInc.cpp" + filter { "files:FastFailCrashHandler/WerCrashHandler.cpp" } + flags { "NoPCH" } + + filter {} + vpaths { ["Headers/*"] = {"**.h", "**.hpp"}, ["Sources/*"] = "**.cpp", @@ -48,11 +54,12 @@ project "Client Core" "ws2_32", "d3dx9", "Userenv", "DbgHelp", "xinput", "Imagehlp", "dxguid", "dinput8", "strmiids", "odbc32", "odbccp32", "shlwapi", "winmm", "gdi32", "Imm32", "Psapi", "dwmapi", "pthread", "libpng", "jpeg", "zlib", "tinygettext", "discord-rpc", "wintrust", "crypt32", + "bcrypt", } defines { "INITGUID", - "PNG_SETJMP_NOT_SUPPORTED" + "PNG_SETJMP_NOT_SUPPORTED", } prebuildcommands { diff --git a/Client/core/resource.h b/Client/core/resource.h index ffb6873a394..e4d6b6aad53 100644 --- a/Client/core/resource.h +++ b/Client/core/resource.h @@ -2,15 +2,15 @@ // Microsoft Visual C++ generated include file. // Used by core.rc // -#define IDI_ICON1 101 +#define IDI_ICON1 101 // Next default values for new objects // #ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif + #ifndef APSTUDIO_READONLY_SYMBOLS + #define _APS_NEXT_RESOURCE_VALUE 102 + #define _APS_NEXT_COMMAND_VALUE 40001 + #define _APS_NEXT_CONTROL_VALUE 1001 + #define _APS_NEXT_SYMED_VALUE 101 + #endif #endif diff --git a/Client/game_sa/C3DMarkerSA.h b/Client/game_sa/C3DMarkerSA.h index 3807252b750..3d606ff170b 100644 --- a/Client/game_sa/C3DMarkerSA.h +++ b/Client/game_sa/C3DMarkerSA.h @@ -17,33 +17,33 @@ class C3DMarkerSAInterface { public: - CMatrix_Padded m_mat; // local space to world space transform // 0 - DWORD dwPad, dwPad2; // not sure why we need these, it appears to be this way though (eAi) // 64/68 - RpClump* m_pRwObject; // 72 - DWORD* m_pMaterial; // 76 + CMatrix_Padded m_mat; // local space to world space transform // 0 + DWORD dwPad, dwPad2; // not sure why we need these, it appears to be this way though (eAi) // 64/68 + RpClump* m_pRwObject; // 72 + DWORD* m_pMaterial; // 76 - WORD m_nType; // 80 - bool m_bIsUsed; // has this marker been allocated this frame? // 82 - DWORD m_nIdentifier; // 84 + WORD m_nType; // 80 + bool m_bIsUsed; // has this marker been allocated this frame? // 82 + DWORD m_nIdentifier; // 84 - DWORD rwColour; // 88 - WORD m_nPulsePeriod; // 92 - short m_nRotateRate; // deg per frame (in either direction) // 94 - DWORD m_nStartTime; // 96 - float m_fPulseFraction; // 100 - float m_fStdSize; // 104 - float m_fSize; // 108 - float m_fBrightness; // 112 - float m_fCameraRange; // 116 + DWORD rwColour; // 88 + WORD m_nPulsePeriod; // 92 + short m_nRotateRate; // deg per frame (in either direction) // 94 + DWORD m_nStartTime; // 96 + float m_fPulseFraction; // 100 + float m_fStdSize; // 104 + float m_fSize; // 108 + float m_fBrightness; // 112 + float m_fCameraRange; // 116 - CVector m_normal; // Normal of the object point at // 120 + CVector m_normal; // Normal of the object point at // 120 // the following variables remember the last time we read the heigh of the // map. Using this we don't have to do this every frame and we can still have moving markers. - WORD m_LastMapReadX, m_LastMapReadY; // 132 / 134 - float m_LastMapReadResultZ; // 136 - float m_roofHeight; // 140 - CVector m_lastPosition; // 144 - DWORD m_OnScreenTestTime; // time last screen check was done // 156 + WORD m_LastMapReadX, m_LastMapReadY; // 132 / 134 + float m_LastMapReadResultZ; // 136 + float m_roofHeight; // 140 + CVector m_lastPosition; // 144 + DWORD m_OnScreenTestTime; // time last screen check was done // 156 }; class C3DMarkerSA : public C3DMarker @@ -60,12 +60,12 @@ class C3DMarkerSA : public C3DMarker void SetMatrix(CMatrix* pMatrix); void SetPosition(CVector* vecPosition); CVector* GetPosition(); - DWORD GetType(); // need enum? - void SetType(DWORD dwType); // doesn't work propperly (not virtualed) + DWORD GetType(); // need enum? + void SetType(DWORD dwType); // doesn't work propperly (not virtualed) bool IsActive(); DWORD GetIdentifier(); SharedUtil::SColor GetColor(); - void SetColor(const SharedUtil::SColor color); // actually BGRA + void SetColor(const SharedUtil::SColor color); // actually BGRA void SetPulsePeriod(WORD wPulsePeriod); void SetRotateRate(short RotateRate); float GetSize(); @@ -73,7 +73,7 @@ class C3DMarkerSA : public C3DMarker float GetBrightness(); void SetBrightness(float fBrightness); void SetCameraRange(float fCameraRange); - void SetPulseFraction(float fPulseFraction); // doesn't work propperly (not virtualed) + void SetPulseFraction(float fPulseFraction); // doesn't work propperly (not virtualed) float GetPulseFraction(); void Disable(); void Reset(); diff --git a/Client/game_sa/C3DMarkersSA.cpp b/Client/game_sa/C3DMarkersSA.cpp index 94c67988e26..c2f055d4708 100644 --- a/Client/game_sa/C3DMarkersSA.cpp +++ b/Client/game_sa/C3DMarkersSA.cpp @@ -43,27 +43,10 @@ C3DMarker* C3DMarkersSA::CreateMarker(DWORD Identifier, T3DMarkerType dwType, CV DWORD dwFunc = FUNC_PlaceMarker; DWORD dwReturn = 0; - _asm - { - push bZCheck // zCheck ##SA## - push 0 // normalZ ##SA## - push 0 // normalY ##SA## - push 0 // normalX ##SA## - push 0 // rotate rate - push fPulseFraction // pulse - push 0 // period - push a // alpha - push b // blue - push g // green - push r // red - push fSize // size - push vecPosition // position - push dwType // type - push Identifier // identifier - call dwFunc - mov dwReturn, eax - add esp, 0x3C - } + // clang-format off + using func_t = decltype(dwReturn) (__cdecl*)(decltype(Identifier), decltype(dwType), decltype(vecPosition), decltype(fSize), decltype(r), decltype(g), decltype(b), decltype(a), decltype(0), decltype(fPulseFraction), decltype(0), decltype(0), decltype(0), decltype(0), decltype(bZCheck)); +dwReturn = reinterpret_cast(dwFunc)(Identifier, dwType, vecPosition, fSize, r, g, b, a, 0, fPulseFraction, 0, 0, 0, 0, bZCheck); + // clang-format on if (dwReturn) { @@ -102,7 +85,7 @@ C3DMarker* C3DMarkersSA::FindMarker(DWORD Identifier) void C3DMarkersSA::ReinitMarkers() { - using Function_ShutdownMarkers = void(__cdecl *)(); + using Function_ShutdownMarkers = void(__cdecl*)(); auto shutdownMarkers = reinterpret_cast(0x722710); using Function_InitMarkers = void(__cdecl*)(); diff --git a/Client/game_sa/C3DMarkersSA.h b/Client/game_sa/C3DMarkersSA.h index 13f8dd21dde..0387026789d 100644 --- a/Client/game_sa/C3DMarkersSA.h +++ b/Client/game_sa/C3DMarkersSA.h @@ -14,10 +14,10 @@ #include #include "C3DMarkerSA.h" -#define FUNC_PlaceMarker 0x725120 -#define ARRAY_3D_MARKERS 0xC7DD58 +#define FUNC_PlaceMarker 0x725120 +#define ARRAY_3D_MARKERS 0xC7DD58 -#define MAX_3D_MARKERS 32 +#define MAX_3D_MARKERS 32 class C3DMarkersSA : public C3DMarkers { diff --git a/Client/game_sa/CAEAudioHardwareSA.cpp b/Client/game_sa/CAEAudioHardwareSA.cpp index 70680d267f2..6d9c6872d9b 100644 --- a/Client/game_sa/CAEAudioHardwareSA.cpp +++ b/Client/game_sa/CAEAudioHardwareSA.cpp @@ -24,14 +24,10 @@ bool CAEAudioHardwareSA::IsSoundBankLoaded(short wSoundBankID, short wSoundBankS DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAEAudioHardware__IsSoundBankLoaded; bool bReturn = false; - _asm - { - push dwSoundBankSlotID - push dwSoundBankID - mov ecx, dwThis - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThis), decltype(dwSoundBankID), decltype(dwSoundBankSlotID)); +bReturn = reinterpret_cast(dwFunc)(dwThis, dwSoundBankID, dwSoundBankSlotID); + // clang-format on return bReturn; } @@ -41,11 +37,8 @@ void CAEAudioHardwareSA::LoadSoundBank(short wSoundBankID, short wSoundBankSlotI DWORD dwSoundBankSlotID = wSoundBankSlotID; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAEAudioHardware__LoadSoundBank; - _asm - { - push dwSoundBankSlotID - push dwSoundBankID - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwSoundBankID), decltype(dwSoundBankSlotID)); + reinterpret_cast(dwFunc)(dwThis, dwSoundBankID, dwSoundBankSlotID); + // clang-format on } diff --git a/Client/game_sa/CAEAudioHardwareSA.h b/Client/game_sa/CAEAudioHardwareSA.h index 8f6210d9945..8ab5f343dae 100644 --- a/Client/game_sa/CAEAudioHardwareSA.h +++ b/Client/game_sa/CAEAudioHardwareSA.h @@ -13,10 +13,10 @@ #include -#define FUNC_CAEAudioHardware__IsSoundBankLoaded 0x4D88C0 -#define FUNC_CAEAudioHardware__LoadSoundBank 0x4D88A0 +#define FUNC_CAEAudioHardware__IsSoundBankLoaded 0x4D88C0 +#define FUNC_CAEAudioHardware__LoadSoundBank 0x4D88A0 -#define CLASS_CAEAudioHardware 0xB5F8B8 +#define CLASS_CAEAudioHardware 0xB5F8B8 class CAEAudioHardwareSAInterface { diff --git a/Client/game_sa/CAERadioTrackManagerSA.cpp b/Client/game_sa/CAERadioTrackManagerSA.cpp index 30058a21179..356cb251d80 100644 --- a/Client/game_sa/CAERadioTrackManagerSA.cpp +++ b/Client/game_sa/CAERadioTrackManagerSA.cpp @@ -16,12 +16,10 @@ BYTE CAERadioTrackManagerSA::GetCurrentRadioStationID() { DWORD dwFunc = FUNC_GetCurrentRadioStationID; BYTE bReturn = 0; - _asm - { - mov ecx, CLASS_CAERadioTrackManager - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(0x8CB6F8) ); +bReturn = reinterpret_cast(dwFunc)(0x8CB6F8); + // clang-format on return bReturn; } @@ -30,12 +28,10 @@ BYTE CAERadioTrackManagerSA::IsVehicleRadioActive() { DWORD dwFunc = FUNC_IsVehicleRadioActive; BYTE bReturn = 0; - _asm - { - mov ecx, CLASS_CAERadioTrackManager - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(0x8CB6F8) ); +bReturn = reinterpret_cast(dwFunc)(0x8CB6F8); + // clang-format on return bReturn; } @@ -45,13 +41,10 @@ char* CAERadioTrackManagerSA::GetRadioStationName(BYTE bStationID) DWORD dwFunc = FUNC_GetRadioStationName; char* cReturn = 0; DWORD dwStationID = bStationID; - _asm - { - mov ecx, CLASS_CAERadioTrackManager - push dwStationID - call dwFunc - mov cReturn, eax - } + // clang-format off + using func_t = decltype(cReturn) (__thiscall*)(decltype(0x8CB6F8), decltype(dwStationID)); +cReturn = reinterpret_cast(dwFunc)(0x8CB6F8, dwStationID); + // clang-format on return cReturn; } @@ -60,12 +53,10 @@ bool CAERadioTrackManagerSA::IsRadioOn() { DWORD dwFunc = FUNC_IsRadioOn; bool bReturn = false; - _asm - { - mov ecx, CLASS_CAERadioTrackManager - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(0x8CB6F8) ); +bReturn = reinterpret_cast(dwFunc)(0x8CB6F8); + // clang-format on return bReturn; } @@ -73,23 +64,19 @@ bool CAERadioTrackManagerSA::IsRadioOn() void CAERadioTrackManagerSA::SetBassSetting(DWORD dwBass) { DWORD dwFunc = FUNC_SetBassSetting; - _asm - { - mov ecx, CLASS_CAERadioTrackManager - push 0x3F800000 // 1.0f - push dwBass - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0x8CB6F8), decltype(dwBass), decltype(0x3F800000)); + reinterpret_cast(dwFunc)(0x8CB6F8, dwBass, 0x3F800000); + // clang-format on } void CAERadioTrackManagerSA::Reset() { DWORD dwFunc = FUNC_Reset; - _asm - { - mov ecx, CLASS_CAERadioTrackManager - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0x8CB6F8) ); + reinterpret_cast(dwFunc)(0x8CB6F8); + // clang-format on } void CAERadioTrackManagerSA::StartRadio(BYTE bStationID, BYTE bUnknown) @@ -97,15 +84,10 @@ void CAERadioTrackManagerSA::StartRadio(BYTE bStationID, BYTE bUnknown) DWORD dwFunc = FUNC_StartRadio; DWORD dwStationID = bStationID; DWORD dwUnknown = bUnknown; - _asm - { - mov ecx, CLASS_CAERadioTrackManager - push 0 - push 0 - push dwUnknown - push dwStationID - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0x8CB6F8), decltype(dwStationID), decltype(dwUnknown), decltype(0), decltype(0)); + reinterpret_cast(dwFunc)(0x8CB6F8, dwStationID, dwUnknown, 0, 0); + // clang-format on } bool CAERadioTrackManagerSA::IsStationLoading() const diff --git a/Client/game_sa/CAERadioTrackManagerSA.h b/Client/game_sa/CAERadioTrackManagerSA.h index 00f66a7f0a0..c86423e1a6b 100644 --- a/Client/game_sa/CAERadioTrackManagerSA.h +++ b/Client/game_sa/CAERadioTrackManagerSA.h @@ -13,15 +13,15 @@ #include -#define FUNC_GetCurrentRadioStationID 0x4E83F0 -#define FUNC_IsVehicleRadioActive 0x4E9800 -#define FUNC_GetRadioStationName 0x4E9E10 -#define FUNC_IsRadioOn 0x4E8350 -#define FUNC_SetBassSetting 0x4E82F0 -#define FUNC_Reset 0x4E7F80 -#define FUNC_StartRadio 0x4EB3C0 +#define FUNC_GetCurrentRadioStationID 0x4E83F0 +#define FUNC_IsVehicleRadioActive 0x4E9800 +#define FUNC_GetRadioStationName 0x4E9E10 +#define FUNC_IsRadioOn 0x4E8350 +#define FUNC_SetBassSetting 0x4E82F0 +#define FUNC_Reset 0x4E7F80 +#define FUNC_StartRadio 0x4EB3C0 -#define CLASS_CAERadioTrackManager 0x8CB6F8 +#define CLASS_CAERadioTrackManager 0x8CB6F8 enum class eRadioTrackMode { @@ -119,5 +119,5 @@ class CAERadioTrackManagerSA : public CAERadioTrackManager void SetBassSetting(DWORD dwBass); void Reset(); void StartRadio(BYTE bStationID, BYTE bUnknown); - bool IsStationLoading() const; + bool IsStationLoading() const; }; diff --git a/Client/game_sa/CAESoundManagerSA.h b/Client/game_sa/CAESoundManagerSA.h index 882929d410d..eab09198450 100644 --- a/Client/game_sa/CAESoundManagerSA.h +++ b/Client/game_sa/CAESoundManagerSA.h @@ -13,24 +13,24 @@ #include #include "CAudioEngineSA.h" -#define CLASS_CAESoundManager 0xB62CB0 +#define CLASS_CAESoundManager 0xB62CB0 class CAESoundManagerSAInterface { - int16_t m_wNumAvailableChannels; // + 0x0000 // = CAEAudioHardware::GetNumAvailableChannels(...), [10, 300] - int16_t m_wChannel; // + 0x0002 // = CAEAudioHardware::AllocateChannels(...), could be -1 - CAESound m_aSound[300]; // + 0x0004 - int16_t* m_aChannelSoundTable; // + 0x87F4 // = new short[m_wNumAvailableChannels] - int16_t* m_aChannelSoundPosition; // + 0x87F8 // = new short[m_wNumAvailableChannels] - int16_t* m_aChannelSoundUncancellable; // + 0x87FC // = new short[m_wNumAvailableChannels] - int16_t m_wSoundLength[300]; // + 0x8800 // = -1 (0xFFFF) when initialized - int16_t m_wSoundLoopStartTime[300]; // + 0x8A58 // = -1 (0xFFFF) when initialized - uint32_t m_uiUpdateTime; // + 0x8CB0 - int8_t m_bPauseTimeInUse; // + 0x8CB4 - int8_t m_bPaused; // + 0x8CB5 + int16_t m_wNumAvailableChannels; // + 0x0000 // = CAEAudioHardware::GetNumAvailableChannels(...), [10, 300] + int16_t m_wChannel; // + 0x0002 // = CAEAudioHardware::AllocateChannels(...), could be -1 + CAESound m_aSound[300]; // + 0x0004 + int16_t* m_aChannelSoundTable; // + 0x87F4 // = new short[m_wNumAvailableChannels] + int16_t* m_aChannelSoundPosition; // + 0x87F8 // = new short[m_wNumAvailableChannels] + int16_t* m_aChannelSoundUncancellable; // + 0x87FC // = new short[m_wNumAvailableChannels] + int16_t m_wSoundLength[300]; // + 0x8800 // = -1 (0xFFFF) when initialized + int16_t m_wSoundLoopStartTime[300]; // + 0x8A58 // = -1 (0xFFFF) when initialized + uint32_t m_uiUpdateTime; // + 0x8CB0 + int8_t m_bPauseTimeInUse; // + 0x8CB4 + int8_t m_bPaused; // + 0x8CB5 int8_t field_8CB6; int8_t field_8CB7; - uint32_t m_uiPauseUpdateTime; // + 0x8CB8 + uint32_t m_uiPauseUpdateTime; // + 0x8CB8 }; static_assert(sizeof(CAESoundManagerSAInterface) == 0x8CBC, "Invalid size for CAESoundManagerSAInterface"); diff --git a/Client/game_sa/CAEVehicleAudioEntitySA.cpp b/Client/game_sa/CAEVehicleAudioEntitySA.cpp index a8550d9a0c1..1ed1ae9d233 100644 --- a/Client/game_sa/CAEVehicleAudioEntitySA.cpp +++ b/Client/game_sa/CAEVehicleAudioEntitySA.cpp @@ -22,11 +22,10 @@ void CAEVehicleAudioEntitySA::JustGotInVehicleAsDriver() m_pInterface->m_bPlayerDriver = true; DWORD dwFunc = FUNC_CAEVehicleAudioEntity__JustGotInVehicleAsDriver; DWORD dwThis = (DWORD)m_pInterface; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } void CAEVehicleAudioEntitySA::JustGotOutOfVehicleAsDriver() @@ -34,22 +33,20 @@ void CAEVehicleAudioEntitySA::JustGotOutOfVehicleAsDriver() m_pInterface->m_bPlayerDriver = false; DWORD dwFunc = FUNC_CAEVehicleAudioEntity__JustGotOutOfVehicleAsDriver; DWORD dwThis = (DWORD)m_pInterface; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } void CAEVehicleAudioEntitySA::TurnOnRadioForVehicle() { DWORD dwFunc = FUNC_CAEVehicleAudioEntity__TurnOnRadioForVehicle; DWORD dwThis = (DWORD)m_pInterface; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } void CAEVehicleAudioEntitySA::StopVehicleEngineSound(unsigned char ucSlot) @@ -59,10 +56,9 @@ void CAEVehicleAudioEntitySA::StopVehicleEngineSound(unsigned char ucSlot) if (pVehicleSound->m_pSound) { DWORD dwThis = (DWORD)pVehicleSound->m_pSound; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } } diff --git a/Client/game_sa/CAEVehicleAudioEntitySA.h b/Client/game_sa/CAEVehicleAudioEntitySA.h index 5294597b029..b9dc54e9605 100644 --- a/Client/game_sa/CAEVehicleAudioEntitySA.h +++ b/Client/game_sa/CAEVehicleAudioEntitySA.h @@ -15,11 +15,11 @@ #include #include "CAudioEngineSA.h" -#define FUNC_CAEVehicleAudioEntity__JustGotInVehicleAsDriver 0x4F5700 -#define FUNC_CAEVehicleAudioEntity__TurnOnRadioForVehicle 0x4F5B20 -#define FUNC_CAEVehicleAudioEntity__JustGotOutOfVehicleAsDriver 0x4FCF40 -#define FUNC_CAEVehicleAudioEntity__ProcessAIProp 0x4FDFD0 -#define FUNC_CAEVehicleAudioEntity__ProcessAIHeli 0x4FEE20 +#define FUNC_CAEVehicleAudioEntity__JustGotInVehicleAsDriver 0x4F5700 +#define FUNC_CAEVehicleAudioEntity__TurnOnRadioForVehicle 0x4F5B20 +#define FUNC_CAEVehicleAudioEntity__JustGotOutOfVehicleAsDriver 0x4FCF40 +#define FUNC_CAEVehicleAudioEntity__ProcessAIProp 0x4FDFD0 +#define FUNC_CAEVehicleAudioEntity__ProcessAIHeli 0x4FEE20 class CVehicleSAInterface; @@ -53,83 +53,83 @@ static_assert(sizeof(CAETwinLoopSoundEntity) == 0xA8, "Invalid size for CAETwinL class CAEVehicleAudioEntitySAInterface : public CAEAudioEntity { public: - void AddAudioEvent(int eventId, float volume) { ((void(__thiscall*)(CAEVehicleAudioEntitySAInterface*, int, float))0x4F6420)(this, eventId, volume); } - bool TerminateAudio() { return ((bool(__thiscall*)(CAEVehicleAudioEntitySAInterface*))0x4FB8C0)(this); } - bool SoundJoin() { return ((bool(__thiscall*)(CAEVehicleAudioEntitySAInterface*))0x4F5700)(this); } + void AddAudioEvent(int eventId, float volume) { ((void(__thiscall*)(CAEVehicleAudioEntitySAInterface*, int, float))0x4F6420)(this, eventId, volume); } + bool TerminateAudio() { return ((bool(__thiscall*)(CAEVehicleAudioEntitySAInterface*))0x4FB8C0)(this); } + bool SoundJoin() { return ((bool(__thiscall*)(CAEVehicleAudioEntitySAInterface*))0x4F5700)(this); } int16_t InitAudio(CVehicleSAInterface* vehicle) { return ((int16_t(__thiscall*)(CAEVehicleAudioEntitySAInterface*, CVehicleSAInterface*))0x4F7670)(this, vehicle); } - short unk1; // +124 - char unk2[2]; // +126 - tVehicleAudioSettings m_nSettings; // +128 - bool m_bEnabled; // +164 - bool m_bPlayerDriver; // +165 - bool m_bPlayerPassenger; // +166 - bool m_bVehicleRadioPaused; // +167 - bool m_bSoundsStopped; // +168 - char m_nEngineState; // +169 - char unk3; // +170 - char unk4; // +171 - int unk5; // +172 - bool m_bInhibitAccForLowSpeed; // +176 - char unk6; // +177 - short m_wRainDropCounter; // +178 - short unk7; // +180 - char pad1[2]; // +182 - int unk8; // +184 - char unk9; // +188 - bool m_bDisableHeliEngineSounds; // +189 - char unk10; // +190 - bool m_bSirenOrAlarmPlaying; // +191 - bool m_bHornPlaying; // +192 - char pad2[3]; // +193 - float m_fSirenVolume; // +196 - bool m_bModelWithSiren; // +200 - char pad3[3]; // +201 - unsigned int m_dwBoatHitWaveLastPlayedTime; // +204 - unsigned int m_dwTimeToInhibitAcc; // +208 - unsigned int m_dwTimeToInhibitCrz; // +212 - float m_fGeneralVehicleSoundVolume; // +216 - short m_wEngineDecelerateSoundBankId; // +220 - short m_wEngineAccelerateSoundBankId; // +222 - short m_wEngineBankSlotId; // +224 - short unk11; // +226 - tVehicleSound m_aEngineSounds[12]; // +228 - int unk12; // +324 - short unk13; // +328 - short unk14; // +330 - short unk15; // +332 - short unk16; // +334 - int unk17; // some time in ms (@0x4F5638) // +336 - short unk18; // +340 - short m_wSkidSoundType; // +342 - CAESound* unk19; // +344 - short m_wRoadNoiseSoundType; // +348 - char pad4[2]; // +350 - CAESound* m_pRoadNoiseSound; // +352 - short m_wFlatTyreSoundType; // +356 - char pad5[2]; // +358 - CAESound* m_pFlatTyreSound; // +360 - short m_wReverseGearSoundType; // +364 - char pad6[2]; // +366 - CAESound* m_pReverseGearSound; // +368 - char pad7[4]; // +372 - CAESound* m_pHornTonSound; // +376 - CAESound* m_pSirenSound; // +380 - CAESound* m_pPoliceSirenSound; // +384 - CAETwinLoopSoundEntity m_nTwinLoopSoundEntity; // +388 - float unk20; // +556 - float unk21; // +560 - float unk22; // +564 - float unk23; // +568 - float unk24; // +572 - int unk25; // +576 - bool m_bNitroSoundPresent; // +580 - char unk26; // +581 - float unk27; // +582 + short unk1; // +124 + char unk2[2]; // +126 + tVehicleAudioSettings m_nSettings; // +128 + bool m_bEnabled; // +164 + bool m_bPlayerDriver; // +165 + bool m_bPlayerPassenger; // +166 + bool m_bVehicleRadioPaused; // +167 + bool m_bSoundsStopped; // +168 + char m_nEngineState; // +169 + char unk3; // +170 + char unk4; // +171 + int unk5; // +172 + bool m_bInhibitAccForLowSpeed; // +176 + char unk6; // +177 + short m_wRainDropCounter; // +178 + short unk7; // +180 + char pad1[2]; // +182 + int unk8; // +184 + char unk9; // +188 + bool m_bDisableHeliEngineSounds; // +189 + char unk10; // +190 + bool m_bSirenOrAlarmPlaying; // +191 + bool m_bHornPlaying; // +192 + char pad2[3]; // +193 + float m_fSirenVolume; // +196 + bool m_bModelWithSiren; // +200 + char pad3[3]; // +201 + unsigned int m_dwBoatHitWaveLastPlayedTime; // +204 + unsigned int m_dwTimeToInhibitAcc; // +208 + unsigned int m_dwTimeToInhibitCrz; // +212 + float m_fGeneralVehicleSoundVolume; // +216 + short m_wEngineDecelerateSoundBankId; // +220 + short m_wEngineAccelerateSoundBankId; // +222 + short m_wEngineBankSlotId; // +224 + short unk11; // +226 + tVehicleSound m_aEngineSounds[12]; // +228 + int unk12; // +324 + short unk13; // +328 + short unk14; // +330 + short unk15; // +332 + short unk16; // +334 + int unk17; // some time in ms (@0x4F5638) // +336 + short unk18; // +340 + short m_wSkidSoundType; // +342 + CAESound* unk19; // +344 + short m_wRoadNoiseSoundType; // +348 + char pad4[2]; // +350 + CAESound* m_pRoadNoiseSound; // +352 + short m_wFlatTyreSoundType; // +356 + char pad5[2]; // +358 + CAESound* m_pFlatTyreSound; // +360 + short m_wReverseGearSoundType; // +364 + char pad6[2]; // +366 + CAESound* m_pReverseGearSound; // +368 + char pad7[4]; // +372 + CAESound* m_pHornTonSound; // +376 + CAESound* m_pSirenSound; // +380 + CAESound* m_pPoliceSirenSound; // +384 + CAETwinLoopSoundEntity m_nTwinLoopSoundEntity; // +388 + float unk20; // +556 + float unk21; // +560 + float unk22; // +564 + float unk23; // +568 + float unk24; // +572 + int unk25; // +576 + bool m_bNitroSoundPresent; // +580 + char unk26; // +581 + float unk27; // +582 }; static_assert(sizeof(CAEVehicleAudioEntitySAInterface) == 0x24C, "Invalid size for CAEVehicleAudioEntitySAInterface"); @@ -137,10 +137,10 @@ class CAEVehicleAudioEntitySA : public CAEVehicleAudioEntity { public: CAEVehicleAudioEntitySA(CAEVehicleAudioEntitySAInterface* pInterface); - void JustGotInVehicleAsDriver(); - void JustGotOutOfVehicleAsDriver(); - void TurnOnRadioForVehicle(); - void StopVehicleEngineSound(unsigned char ucSlot); + void JustGotInVehicleAsDriver(); + void JustGotOutOfVehicleAsDriver(); + void TurnOnRadioForVehicle(); + void StopVehicleEngineSound(unsigned char ucSlot); CAEVehicleAudioEntitySAInterface* GetInterface() { return m_pInterface; }; private: diff --git a/Client/game_sa/CAEWeaponAudioEntitySA.h b/Client/game_sa/CAEWeaponAudioEntitySA.h index 0f35260de07..d4534638a93 100644 --- a/Client/game_sa/CAEWeaponAudioEntitySA.h +++ b/Client/game_sa/CAEWeaponAudioEntitySA.h @@ -40,12 +40,12 @@ class CAEWeaponAudioEntitySAInterface : public CAEAudioEntity eMiniGunState m_miniGunState; eChainsawState m_chainsawState; - std::uint32_t m_lastFlamethrowerFireTimeInMS; - std::uint32_t m_lastSpraycanFireTimeInMS; - std::uint32_t m_lastFireExtinguisherFireTimeInMS; - std::uint32_t m_lastMinigunFireTimeInMS; - std::uint32_t m_lastChainsawFireTimeInMS; - std::uint32_t m_lastGunFireTimeInMS; + std::uint32_t m_lastFlamethrowerFireTimeInMS; + std::uint32_t m_lastSpraycanFireTimeInMS; + std::uint32_t m_lastFireExtinguisherFireTimeInMS; + std::uint32_t m_lastMinigunFireTimeInMS; + std::uint32_t m_lastChainsawFireTimeInMS; + std::uint32_t m_lastGunFireTimeInMS; CAESound* m_flameThrowerIdleGasLoopSound{}; }; diff --git a/Client/game_sa/CAnimBlendAssocGroupSA.cpp b/Client/game_sa/CAnimBlendAssocGroupSA.cpp index 09d69bdba78..7ca242512f6 100644 --- a/Client/game_sa/CAnimBlendAssocGroupSA.cpp +++ b/Client/game_sa/CAnimBlendAssocGroupSA.cpp @@ -29,13 +29,10 @@ CAnimBlendAssociationSAInterface* CAnimBlendAssocGroupSA::CopyAnimation(unsigned DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendAssocGroup_CopyAnimation; - _asm - { - mov ecx, dwThis - push AnimID - call dwFunc - mov pAnimAssociationReturn, eax - } + // clang-format off + using func_t = decltype(pAnimAssociationReturn) (__thiscall*)(decltype(dwThis), decltype(AnimID)); +pAnimAssociationReturn = reinterpret_cast(dwFunc)(dwThis, AnimID); + // clang-format on return pAnimAssociationReturn; } @@ -43,12 +40,10 @@ void CAnimBlendAssocGroupSA::InitEmptyAssociations(RpClump* pClump) { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendAssocGroup_InitEmptyAssociations; - _asm - { - mov ecx, dwThis - push pClump - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pClump)); + reinterpret_cast(dwFunc)(dwThis, pClump); + // clang-format on } bool CAnimBlendAssocGroupSA::IsCreated() @@ -56,12 +51,10 @@ bool CAnimBlendAssocGroupSA::IsCreated() bool bReturn; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendAssocGroup_IsCreated; - _asm - { - mov ecx, dwThis - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThis) ); +bReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on return bReturn; } @@ -70,12 +63,10 @@ int CAnimBlendAssocGroupSA::GetNumAnimations() int iReturn; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendAssocGroup_GetNumAnimations; - _asm - { - mov ecx, dwThis - call dwFunc - mov iReturn, eax - } + // clang-format off + using func_t = decltype(iReturn) (__thiscall*)(decltype(dwThis) ); +iReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on return iReturn; } @@ -92,13 +83,10 @@ CAnimBlendStaticAssociation* CAnimBlendAssocGroupSA::GetAnimation(unsigned int I CAnimBlendStaticAssociation* pReturn; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendAssocGroup_GetAnimation; - _asm - { - mov ecx, dwThis - push ID - call dwFunc - mov pReturn, eax - } + // clang-format off + using func_t = decltype(pReturn) (__thiscall*)(decltype(dwThis), decltype(ID)); +pReturn = reinterpret_cast(dwFunc)(dwThis, ID); + // clang-format on return pReturn; } @@ -124,12 +112,10 @@ void CAnimBlendAssocGroupSA::CreateAssociations(const char* szBlockName) { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendAssocGroup_CreateAssociations; - _asm - { - mov ecx, dwThis - push szBlockName - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(szBlockName)); + reinterpret_cast(dwFunc)(dwThis, szBlockName); + // clang-format on } void CAnimBlendAssocGroupSA::SetupAnimBlock() diff --git a/Client/game_sa/CAnimBlendAssociationSA.cpp b/Client/game_sa/CAnimBlendAssociationSA.cpp index 98f28dede1e..5c231bcfc7e 100644 --- a/Client/game_sa/CAnimBlendAssociationSA.cpp +++ b/Client/game_sa/CAnimBlendAssociationSA.cpp @@ -32,25 +32,20 @@ CAnimBlendAssociationSAInterface* CAnimBlendAssociationSA::Constructor(CAnimBlen { DWORD DwFunc = 0x4CF080; DWORD DwThisInterface = reinterpret_cast(m_pInterface); - _asm - { - mov ecx, DwThisInterface - push staticAssociationByReference - call DwFunc - }; + // clang-format off + using func_t = void (__thiscall*)(decltype(DwThisInterface), decltype(staticAssociationByReference)); + reinterpret_cast(DwFunc)(DwThisInterface, staticAssociationByReference); + // clang-format on; } CAnimBlendAssociationSAInterface* CAnimBlendAssociationSA::Constructor(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy) { DWORD DwFunc = 0x4CEFC0; DWORD DwThisInterface = reinterpret_cast(m_pInterface); - _asm - { - mov ecx, DwThisInterface - push pAnimHierarchy - push pClump - call DwFunc - }; + // clang-format off + using func_t = void (__thiscall*)(decltype(DwThisInterface), decltype(pClump), decltype(pAnimHierarchy)); + reinterpret_cast(DwFunc)(DwThisInterface, pClump, pAnimHierarchy); + // clang-format on; } CAnimBlendAssociationSAInterface* CAnimBlendAssociationSA::InitializeForCustomAnimation(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy) @@ -76,36 +71,30 @@ void CAnimBlendAssociationSA::Init(RpClump* pClump, CAnimBlendHierarchySAInterfa { DWORD DwFunc = 0x4CED50; DWORD DwThisInterface = reinterpret_cast(m_pInterface); - _asm - { - mov ecx, DwThisInterface - push pAnimHierarchy - push pClump - call DwFunc - }; + // clang-format off + using func_t = void (__thiscall*)(decltype(DwThisInterface), decltype(pClump), decltype(pAnimHierarchy)); + reinterpret_cast(DwFunc)(DwThisInterface, pClump, pAnimHierarchy); + // clang-format on; } void CAnimBlendAssociationSA::AllocateAnimBlendNodeArray(int iCount) { DWORD DwFunc = 0x4CE9F0; DWORD DwThisInterface = reinterpret_cast(m_pInterface); - _asm - { - mov ecx, DwThisInterface - push iCount - call DwFunc - }; + // clang-format off + using func_t = void (__thiscall*)(decltype(DwThisInterface), decltype(iCount)); + reinterpret_cast(DwFunc)(DwThisInterface, iCount); + // clang-format on; } void CAnimBlendAssociationSA::FreeAnimBlendNodeArray() { DWORD DwFunc = 0x4CEA40; DWORD DwThisInterface = reinterpret_cast(m_pInterface); - _asm - { - mov ecx, DwThisInterface - call DwFunc - }; + // clang-format off + using func_t = void (__thiscall*)(decltype(DwThisInterface) ); + reinterpret_cast(DwFunc)(DwThisInterface); + // clang-format on; } std::unique_ptr CAnimBlendAssociationSA::GetAnimHierarchy() @@ -124,10 +113,8 @@ void CAnimBlendAssociationSA::SetCurrentProgress(float fProgress) DWORD DwFunc = 0x4CEA80; DWORD DwThisInterface = reinterpret_cast(m_pInterface); - _asm - { - mov ecx, DwThisInterface - push fTime - call DwFunc - }; + // clang-format off + using func_t = void (__thiscall*)(decltype(DwThisInterface), decltype(fTime)); + reinterpret_cast(DwFunc)(DwThisInterface, fTime); + // clang-format on; } diff --git a/Client/game_sa/CAnimBlendAssociationSA.h b/Client/game_sa/CAnimBlendAssociationSA.h index 871fc177cf3..4d74bbf8a24 100644 --- a/Client/game_sa/CAnimBlendAssociationSA.h +++ b/Client/game_sa/CAnimBlendAssociationSA.h @@ -34,14 +34,14 @@ class AnimBlendFrameData { struct { - unsigned char m_bf1 : 1; // doesn't seem to be used - unsigned char m_IsIFrameOrientationToAffectedByNodes : 1; // m_IFrame orientation will be affected - unsigned char m_IsIFrameTranslationToAffectedByNodes : 1; // m_IFrame translation will be affected + unsigned char m_bf1 : 1; // doesn't seem to be used + unsigned char m_IsIFrameOrientationToAffectedByNodes : 1; // m_IFrame orientation will be affected + unsigned char m_IsIFrameTranslationToAffectedByNodes : 1; // m_IFrame translation will be affected unsigned char m_bIsInitialized : 1; unsigned char m_bUpdateSkinnedWith3dVelocityExtraction : 1; - unsigned char m_bCheckBlendNodeClumpKeyFrames : 1; // key frames of CAninBlendNode bones will be checked + unsigned char m_bCheckBlendNodeClumpKeyFrames : 1; // key frames of CAninBlendNode bones will be checked unsigned char m_bIsCompressed : 1; - unsigned char m_bUpdatingFrame : 1; // doesn't seem to be used + unsigned char m_bUpdatingFrame : 1; // doesn't seem to be used }; unsigned char m_nFlags; }; @@ -86,49 +86,49 @@ class CAnimBlendAssociationSAInterface DWORD* vTable; RwListEntry listEntry; unsigned short cNumBlendNodes; - short sAnimGroup; // 14 - CAnimBlendNodeSAInterface* pAnimBlendNodeArray; // CAnimBlendNode pp? // 16 - CAnimBlendHierarchySAInterface* pAnimHierarchy; // 20 - float fBlendAmount; // 24 - float fBlendDelta; // 28 - float fCurrentTime; // 32 - float fSpeed; // 36 - float fTimeStep; // 40 - short sAnimID; // 44 + short sAnimGroup; // 14 + CAnimBlendNodeSAInterface* pAnimBlendNodeArray; // CAnimBlendNode pp? // 16 + CAnimBlendHierarchySAInterface* pAnimHierarchy; // 20 + float fBlendAmount; // 24 + float fBlendDelta; // 28 + float fCurrentTime; // 32 + float fSpeed; // 36 + float fTimeStep; // 40 + short sAnimID; // 44 union { struct { - unsigned short m_bPlaying : 1; // Anim will stop playing if flag is not set - unsigned short m_bLooped : 1; // Anim will always restart when it completes - unsigned short m_bFreezeLastFrame : 1; // Anim will freeze on last frame + unsigned short m_bPlaying : 1; // Anim will stop playing if flag is not set + unsigned short m_bLooped : 1; // Anim will always restart when it completes + unsigned short m_bFreezeLastFrame : 1; // Anim will freeze on last frame // When this flag is Set, IF m_bLooped == false, m_bPlaying == true, and anim progress >= total anim time // THEN m_bFreezeLastFrame is set to TRUE and m_fBlendDelta is set to -4.0. // Result: https://i.imgur.com/idw0jsX.png unsigned short m_bLockLastFrame : 1; - unsigned short m_bPartial : 1; // Partial anims run along other anims - unsigned short m_bEnableMovement : 1; // blends all playing anims together if set + unsigned short m_bPartial : 1; // Partial anims run along other anims + unsigned short m_bEnableMovement : 1; // blends all playing anims together if set // Camera will not move with ped, and ped will go back to the initial position when anim is over unsigned short m_bLockLastX : 1; - unsigned short m_bLockLastY : 1; // only applies if m_bLockLastX is set + unsigned short m_bLockLastY : 1; // only applies if m_bLockLastX is set - unsigned short m_bf9 : 1; // doesn't seem to be used - unsigned short m_bf10 : 1; // doesn't seem to be used + unsigned short m_bf9 : 1; // doesn't seem to be used + unsigned short m_bf10 : 1; // doesn't seem to be used // If set to TRUE, then result: // Before = https://i.imgur.com/c8T7xNK.png | AFTER = https://i.imgur.com/4gqlA4n.png unsigned short m_bAddAnimBlendToTotalBlend : 1; - unsigned short m_bf12 : 1; // doesn't seem to be used - unsigned short m_bSecondaryTaskAnim : 1; // doesn't seem to be used + unsigned short m_bf12 : 1; // doesn't seem to be used + unsigned short m_bSecondaryTaskAnim : 1; // doesn't seem to be used // Anim will play. Translation values will be ignored for anim (m_bEnableTranslation // is ignored if set), and it only applies to some anims though unsigned short m_bFreezeTranslation : 1; - unsigned short m_bBlockReferenced : 1; // anim block can't be unloaded if it's referenced by an anim. + unsigned short m_bBlockReferenced : 1; // anim block can't be unloaded if it's referenced by an anim. // Anim will not be destroyed. It will be played simultaneously with other anims // (multiple anims at once) if you set this flag while sitting in a car, you'll still be @@ -138,10 +138,10 @@ class CAnimBlendAssociationSAInterface }; unsigned short m_nFlags; }; - unsigned int uiCallbackType; // 48: 1 means finished and 2 means delete - DWORD* pCallbackFunc; // 52 - DWORD* pCallbackData; // 56 - // Total: 60 bytes + unsigned int uiCallbackType; // 48: 1 means finished and 2 means delete + DWORD* pCallbackFunc; // 52 + DWORD* pCallbackData; // 56 + // Total: 60 bytes }; static_assert(sizeof(CAnimBlendAssociationSAInterface) == 0x3C, "Incorrect class size: CAnimBlendAssociationSAInterface"); @@ -150,16 +150,16 @@ class CAnimBlendAssociationSA : public CAnimBlendAssociation public: CAnimBlendAssociationSA(CAnimBlendAssociationSAInterface* pInterface) { m_pInterface = pInterface; } - CAnimBlendAssociationSAInterface* Constructor(CAnimBlendStaticAssociationSAInterface& StaticAssociationByReference); - CAnimBlendAssociationSAInterface* Constructor(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy); - CAnimBlendAssociationSAInterface* InitializeForCustomAnimation(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy); - void Init(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy); - void AllocateAnimBlendNodeArray(int count); - void FreeAnimBlendNodeArray(); - CAnimBlendAssociationSAInterface* GetInterface() { return m_pInterface; } - eAnimGroup GetAnimGroup() { return static_cast(m_pInterface->sAnimGroup); } - eAnimID GetAnimID() { return static_cast(m_pInterface->sAnimID); } - std::unique_ptr GetAnimHierarchy(); + CAnimBlendAssociationSAInterface* Constructor(CAnimBlendStaticAssociationSAInterface& StaticAssociationByReference); + CAnimBlendAssociationSAInterface* Constructor(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy); + CAnimBlendAssociationSAInterface* InitializeForCustomAnimation(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy); + void Init(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy); + void AllocateAnimBlendNodeArray(int count); + void FreeAnimBlendNodeArray(); + CAnimBlendAssociationSAInterface* GetInterface() { return m_pInterface; } + eAnimGroup GetAnimGroup() { return static_cast(m_pInterface->sAnimGroup); } + eAnimID GetAnimID() { return static_cast(m_pInterface->sAnimID); } + std::unique_ptr GetAnimHierarchy(); const std::unique_ptr GetAnimHierarchy() const noexcept; float GetBlendAmount() { return m_pInterface->fBlendAmount; } diff --git a/Client/game_sa/CAnimBlendHierarchySA.cpp b/Client/game_sa/CAnimBlendHierarchySA.cpp index 46ea9f32a64..2ae56da96b8 100644 --- a/Client/game_sa/CAnimBlendHierarchySA.cpp +++ b/Client/game_sa/CAnimBlendHierarchySA.cpp @@ -35,56 +35,50 @@ void CAnimBlendHierarchySA::SetName(const char* szName) { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendHierarchy_SetName; - _asm - { - push szName - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(szName)); + reinterpret_cast(dwFunc)(dwThis, szName); + // clang-format on } void CAnimBlendHierarchySA::RemoveAnimSequences() { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendHierarchy_RemoveAnimSequences; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } void CAnimBlendHierarchySA::RemoveFromUncompressedCache() { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendHierarchy_RemoveFromUncompressedCache; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } void CAnimBlendHierarchySA::RemoveQuaternionFlips() { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendHierarchy_RemoveQuaternionFlips; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } void CAnimBlendHierarchySA::CalculateTotalTime() { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendHierarchy_CalculateTotalTime; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } CAnimBlendSequenceSAInterface* CAnimBlendHierarchySA::GetSequence(DWORD dwIndex) diff --git a/Client/game_sa/CAnimBlendSequenceSA.cpp b/Client/game_sa/CAnimBlendSequenceSA.cpp index bf5bb8d55c7..1178d9dffad 100644 --- a/Client/game_sa/CAnimBlendSequenceSA.cpp +++ b/Client/game_sa/CAnimBlendSequenceSA.cpp @@ -24,39 +24,30 @@ void CAnimBlendSequenceSA::SetName(const char* szName) { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendSequence_SetName; - _asm - { - push szName - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(szName)); + reinterpret_cast(dwFunc)(dwThis, szName); + // clang-format on } void CAnimBlendSequenceSA::SetBoneTag(int32_t i32BoneID) { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendSequence_SetBoneTag; - _asm - { - push i32BoneID - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(i32BoneID)); + reinterpret_cast(dwFunc)(dwThis, i32BoneID); + // clang-format on } void CAnimBlendSequenceSA::SetKeyFrames(size_t cKeyFrames, bool bRoot, bool bCompressed, void* pKeyFrames) { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendSequence_SetKeyFrames; - _asm - { - push pKeyFrames - push bCompressed - push bRoot - push cKeyFrames - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(cKeyFrames), decltype(bRoot), decltype(bCompressed), decltype(pKeyFrames)); + reinterpret_cast(dwFunc)(dwThis, cKeyFrames, bRoot, bCompressed, pKeyFrames); + // clang-format on } void CAnimBlendSequenceSA::CopySequenceProperties(CAnimBlendSequenceSAInterface* pAnimSequenceInterface) diff --git a/Client/game_sa/CAnimBlendSequenceSA.h b/Client/game_sa/CAnimBlendSequenceSA.h index 4b9bafca943..9eaffe4a315 100644 --- a/Client/game_sa/CAnimBlendSequenceSA.h +++ b/Client/game_sa/CAnimBlendSequenceSA.h @@ -22,8 +22,8 @@ class CAnimBlendSequenceSAInterface public: union { - uint16_t m_boneId; // m_boneId is set if ( sFlags & 0x10u ) is true - uint32_t m_hash; // otherwise m_hash is set + uint16_t m_boneId; // m_boneId is set if ( sFlags & 0x10u ) is true + uint32_t m_hash; // otherwise m_hash is set }; unsigned short sFlags; unsigned short sNumKeyFrames; diff --git a/Client/game_sa/CAnimBlendStaticAssociationSA.cpp b/Client/game_sa/CAnimBlendStaticAssociationSA.cpp index 674704fb70d..4ca41b160b4 100644 --- a/Client/game_sa/CAnimBlendStaticAssociationSA.cpp +++ b/Client/game_sa/CAnimBlendStaticAssociationSA.cpp @@ -16,11 +16,8 @@ void CAnimBlendStaticAssociationSA::Initialize(RpClump* pClump, CAnimBlendHierar { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAnimBlendStaticAssociation_Initialize; - _asm - { - push pAnimBlendHierarchyInterface - push pClump - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pClump), decltype(pAnimBlendHierarchyInterface)); + reinterpret_cast(dwFunc)(dwThis, pClump, pAnimBlendHierarchyInterface); + // clang-format on } diff --git a/Client/game_sa/CAnimBlockSA.h b/Client/game_sa/CAnimBlockSA.h index 7967874de85..3a872e16e83 100644 --- a/Client/game_sa/CAnimBlockSA.h +++ b/Client/game_sa/CAnimBlockSA.h @@ -15,13 +15,13 @@ class CAnimBlendAssocGroupSA; -class CAnimBlockSAInterface // 32 bytes +class CAnimBlockSAInterface // 32 bytes { public: - int GetIndex(); // hacky, i know + int GetIndex(); // hacky, i know char szName[16]; - bool bLoaded; // ? + bool bLoaded; // ? BYTE pad[1]; unsigned short usRefs; int idOffset; diff --git a/Client/game_sa/CAnimManagerSA.cpp b/Client/game_sa/CAnimManagerSA.cpp index e69b2119a83..5ff91c6b751 100644 --- a/Client/game_sa/CAnimManagerSA.cpp +++ b/Client/game_sa/CAnimManagerSA.cpp @@ -41,19 +41,19 @@ CAnimManagerSA::~CAnimManagerSA() void CAnimManagerSA::Initialize() { DWORD dwFunc = FUNC_CAnimManager_Initialize; - _asm - { - call dwFunc - } + // clang-format off + using func_t = void (__cdecl*)(); + reinterpret_cast(dwFunc)(); + // clang-format on } void CAnimManagerSA::Shutdown() { DWORD dwFunc = FUNC_CAnimManager_Shutdown; - _asm - { - call dwFunc - } + // clang-format off + using func_t = void (__cdecl*)(); + reinterpret_cast(dwFunc)(); + // clang-format on } int CAnimManagerSA::GetNumAnimations() @@ -71,17 +71,15 @@ int CAnimManagerSA::GetNumAnimAssocDefinitions() return *(int*)(VAR_CAnimManager_NumAnimAssocDefinitions); } +// Returns wrapper for animation hierarchy std::unique_ptr CAnimManagerSA::GetAnimation(int ID) { CAnimBlendHierarchySAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_CAnimManager_GetAnimation_int; - _asm - { - push ID - call dwFunc - mov pInterface, eax - add esp, 0x4 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(ID)); +pInterface = reinterpret_cast(dwFunc)(ID); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -94,14 +92,10 @@ std::unique_ptr CAnimManagerSA::GetAnimation(const char* sz CAnimBlendHierarchySAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_CAnimManager_GetAnimation_str_block; CAnimBlockSAInterface* pBlockInterface = pBlock->GetInterface(); - _asm - { - push pBlockInterface - push szName - call dwFunc - mov pInterface, eax - add esp, 0x8 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(szName), decltype(pBlockInterface)); +pInterface = reinterpret_cast(dwFunc)(szName, pBlockInterface); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -115,14 +109,10 @@ std::unique_ptr CAnimManagerSA::GetAnimation(unsigned int u ; DWORD dwFunc = FUNC_CAnimManager_GetAnimation_int_block; CAnimBlockSAInterface* pBlockInterface = pBlock->GetInterface(); - _asm - { - push pBlockInterface - push uiIndex - call dwFunc - mov pInterface, eax - add esp, 0x8 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(uiIndex), decltype(pBlockInterface)); +pInterface = reinterpret_cast(dwFunc)(uiIndex, pBlockInterface); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -134,13 +124,10 @@ std::unique_ptr CAnimManagerSA::GetAnimationBlock(int ID) { CAnimBlockSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_CAnimManager_GetAnimationBlock_int; - _asm - { - push ID - call dwFunc - mov pInterface, eax - add esp, 0x4 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(ID)); +pInterface = reinterpret_cast(dwFunc)(ID); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -152,13 +139,10 @@ std::unique_ptr CAnimManagerSA::GetAnimationBlock(const char* szName { CAnimBlockSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_CAnimManager_GetAnimationBlock_str; - _asm - { - push szName - call dwFunc - mov pInterface, eax - add esp, 0x4 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(szName)); +pInterface = reinterpret_cast(dwFunc)(szName); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -170,13 +154,10 @@ int CAnimManagerSA::GetAnimationBlockIndex(const char* szName) { int iReturn; DWORD dwFunc = FUNC_CAnimManager_GetAnimationBlockIndex; - _asm - { - push szName - call dwFunc - mov iReturn, eax - add esp, 0x4 - } + // clang-format off + using func_t = decltype(iReturn) (__cdecl*)(decltype(szName)); +iReturn = reinterpret_cast(dwFunc)(szName); + // clang-format on return iReturn; } @@ -184,13 +165,10 @@ int CAnimManagerSA::RegisterAnimBlock(const char* szName) { int iReturn; DWORD dwFunc = FUNC_CAnimManager_RegisterAnimBlock; - _asm - { - push szName - call dwFunc - mov iReturn, eax - add esp, 0x4 - } + // clang-format off + using func_t = decltype(iReturn) (__cdecl*)(decltype(szName)); +iReturn = reinterpret_cast(dwFunc)(szName); + // clang-format on return iReturn; } @@ -198,13 +176,10 @@ std::unique_ptr CAnimManagerSA::GetAnimBlendAssoc(AssocGro { CAnimBlendAssocGroupSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_CAnimManager_GetAnimBlendAssoc; - _asm - { - push groupID - call dwFunc - mov pInterface, eax - add esp, 0x4 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(groupID)); +pInterface = reinterpret_cast(dwFunc)(groupID); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -216,13 +191,10 @@ AssocGroupId CAnimManagerSA::GetFirstAssocGroup(const char* szName) { AssocGroupId groupReturn; DWORD dwFunc = FUNC_CAnimManager_GetFirstAssocGroup; - _asm - { - push szName - call dwFunc - mov groupReturn, eax - add esp, 0x4 - } + // clang-format off + using func_t = decltype(groupReturn) (__cdecl*)(decltype(szName)); +groupReturn = reinterpret_cast(dwFunc)(szName); + // clang-format on return groupReturn; } @@ -230,13 +202,10 @@ const char* CAnimManagerSA::GetAnimGroupName(AssocGroupId groupID) { const char* szReturn; DWORD dwFunc = FUNC_CAnimManager_GetAnimGroupName; - _asm - { - push groupID - call dwFunc - mov szReturn, eax - add esp, 0x4 - } + // clang-format off + using func_t = decltype(szReturn) (__cdecl*)(decltype(groupID)); +szReturn = reinterpret_cast(dwFunc)(groupID); + // clang-format on return szReturn; } @@ -244,13 +213,10 @@ const char* CAnimManagerSA::GetAnimBlockName(AssocGroupId groupID) { const char* szReturn; DWORD dwFunc = FUNC_CAnimManager_GetAnimBlockName; - _asm - { - push groupID - call dwFunc - mov szReturn, eax - add esp, 0x4 - } + // clang-format off + using func_t = decltype(szReturn) (__cdecl*)(decltype(groupID)); +szReturn = reinterpret_cast(dwFunc)(groupID); + // clang-format on return szReturn; } @@ -258,14 +224,10 @@ std::unique_ptr CAnimManagerSA::CreateAnimAssociation(Ass { CAnimBlendAssociationSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_CAnimManager_CreateAnimAssociation; - _asm - { - push animID - push animGroup - call dwFunc - mov pInterface, eax - add esp, 0x8 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(animGroup), decltype(animID)); +pInterface = reinterpret_cast(dwFunc)(animGroup, animID); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -281,14 +243,10 @@ CAnimManagerSA::StaticAssocIntface_type CAnimManagerSA::GetAnimStaticAssociation CAnimBlendStaticAssociationSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_CAnimManager_GetAnimAssociation; - _asm - { - push animID - push animGroup - call dwFunc - mov pInterface, eax - add esp, 0x8 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(animGroup), decltype(animID)); +pInterface = reinterpret_cast(dwFunc)(animGroup, animID); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -304,14 +262,10 @@ std::unique_ptr CAnimManagerSA::GetAnimAssociation(AssocG CAnimBlendAssociationSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_CAnimManager_GetAnimAssociation_str; - _asm - { - push szAnimName - push animGroup - call dwFunc - mov pInterface, eax - add esp, 0x8 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(animGroup), decltype(szAnimName)); +pInterface = reinterpret_cast(dwFunc)(animGroup, szAnimName); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -326,15 +280,10 @@ std::unique_ptr CAnimManagerSA::AddAnimation(RpClump* pCl CAnimBlendAssociationSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_CAnimManager_AddAnimation; - _asm - { - push animID - push animGroup - push pClump - call dwFunc - mov pInterface, eax - add esp, 0xC - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(pClump), decltype(animGroup), decltype(animID)); +pInterface = reinterpret_cast(dwFunc)(pClump, animGroup, animID); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -350,15 +299,10 @@ std::unique_ptr CAnimManagerSA::AddAnimation(RpClump* pCl CAnimBlendAssociationSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_CAnimManager_AddAnimation_hier; CAnimBlendHierarchySAInterface* pHierarchyInterface = pHierarchy->GetInterface(); - _asm - { - push ID - push pHierarchyInterface - push pClump - call dwFunc - mov pInterface, eax - add esp, 0xC - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(pClump), decltype(pHierarchyInterface), decltype(ID)); +pInterface = reinterpret_cast(dwFunc)(pClump, pHierarchyInterface, ID); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -375,16 +319,10 @@ std::unique_ptr CAnimManagerSA::AddAnimationAndSync(RpClu CAnimBlendAssociationSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_CAnimManager_AddAnimationAndSync; CAnimBlendAssociationSAInterface* pAssociationInterface = pAssociation->GetInterface(); - _asm - { - push animID - push animGroup - push pAssociationInterface - push pClump - call dwFunc - mov pInterface, eax - add esp, 0x10 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(pClump), decltype(pAssociationInterface), decltype(animGroup), decltype(animID)); +pInterface = reinterpret_cast(dwFunc)(pClump, pAssociationInterface, animGroup, animID); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -399,16 +337,10 @@ std::unique_ptr CAnimManagerSA::BlendAnimation(RpClump* p CAnimBlendAssociationSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_CAnimManager_BlendAnimation; - _asm - { - push fBlendDelta - push animID - push animGroup - push pClump - call dwFunc - mov pInterface, eax - add esp, 0x10 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(pClump), decltype(animGroup), decltype(animID), decltype(fBlendDelta)); +pInterface = reinterpret_cast(dwFunc)(pClump, animGroup, animID, fBlendDelta); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -424,16 +356,10 @@ std::unique_ptr CAnimManagerSA::BlendAnimation(RpClump* p CAnimBlendAssociationSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_CAnimManager_BlendAnimation_hier; CAnimBlendHierarchySAInterface* pHierarchyInterface = pHierarchy->GetInterface(); - _asm - { - push fBlendDelta - push ID - push pHierarchyInterface - push pClump - call dwFunc - mov pInterface, eax - add esp, 0x10 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(pClump), decltype(pHierarchyInterface), decltype(ID), decltype(fBlendDelta)); +pInterface = reinterpret_cast(dwFunc)(pClump, pHierarchyInterface, ID, fBlendDelta); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -444,61 +370,51 @@ std::unique_ptr CAnimManagerSA::BlendAnimation(RpClump* p void CAnimManagerSA::AddAnimBlockRef(int ID) { DWORD dwFunc = FUNC_CAnimManager_AddAnimBlockRef; - _asm - { - push ID - call dwFunc - add esp, 0x4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(ID)); + reinterpret_cast(dwFunc)(ID); + // clang-format on } void CAnimManagerSA::RemoveAnimBlockRef(int ID) { DWORD dwFunc = FUNC_CAnimManager_RemoveAnimBlockRef; - _asm - { - push ID - call dwFunc - add esp, 0x4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(ID)); + reinterpret_cast(dwFunc)(ID); + // clang-format on } void CAnimManagerSA::RemoveAnimBlockRefWithoutDelete(int ID) { DWORD dwFunc = FUNC_CAnimManager_RemoveAnimBlockRefWithoutDelete; - _asm - { - push ID - call dwFunc - add esp, 0x4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(ID)); + reinterpret_cast(dwFunc)(ID); + // clang-format on } int CAnimManagerSA::GetNumRefsToAnimBlock(int ID) { int iReturn; DWORD dwFunc = FUNC_CAnimManager_GetNumRefsToAnimBlock; - _asm - { - push ID - call dwFunc - mov iReturn, eax - add esp, 0x4 - } + // clang-format off + using func_t = decltype(iReturn) (__cdecl*)(decltype(ID)); +iReturn = reinterpret_cast(dwFunc)(ID); + // clang-format on return iReturn; } void CAnimManagerSA::RemoveAnimBlock(int ID) { DWORD dwFunc = FUNC_CAnimManager_RemoveAnimBlock; - _asm - { - push ID - call dwFunc - add esp, 0x4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(ID)); + reinterpret_cast(dwFunc)(ID); + // clang-format on } +// Returns a pointer to GTA SA's internal animation association definition AnimAssocDefinition* CAnimManagerSA::AddAnimAssocDefinition(const char* szBlockName, const char* szAnimName, AssocGroupId animGroup, AnimationId animID, AnimDescriptor* pDescriptor) { @@ -507,151 +423,124 @@ AnimAssocDefinition* CAnimManagerSA::AddAnimAssocDefinition(const char* szBlockN AnimAssocDefinition* pReturn{}; DWORD dwFunc = FUNC_CAnimManager_AddAnimAssocDefinition; - _asm - { - push pDescriptor - push animID - push animGroup - push szAnimName - push szBlockName - call dwFunc - mov pReturn, eax - add esp, 0x14 - } + // clang-format off + using func_t = decltype(pReturn) (__cdecl*)(decltype(szBlockName), decltype(szAnimName), decltype(animGroup), decltype(animID), decltype(pDescriptor)); +pReturn = reinterpret_cast(dwFunc)(szBlockName, szAnimName, animGroup, animID, pDescriptor); + // clang-format on return pReturn; } void CAnimManagerSA::ReadAnimAssociationDefinitions() { DWORD dwFunc = FUNC_CAnimManager_ReadAnimAssociationDefinitions; - _asm - { - call dwFunc - } + // clang-format off + using func_t = void (__cdecl*)(); + reinterpret_cast(dwFunc)(); + // clang-format on } void CAnimManagerSA::CreateAnimAssocGroups() { DWORD dwFunc = FUNC_CAnimManager_CreateAnimAssocGroups; - _asm - { - call dwFunc - } + // clang-format off + using func_t = void (__cdecl*)(); + reinterpret_cast(dwFunc)(); + // clang-format on } void CAnimManagerSA::UncompressAnimation(CAnimBlendHierarchy* pHierarchy) { DWORD dwFunc = FUNC_CAnimManager_UncompressAnimation; CAnimBlendHierarchySAInterface* pHierarchyInterface = pHierarchy->GetInterface(); - _asm - { - push pHierarchyInterface - call dwFunc - add esp, 0x4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(pHierarchyInterface)); + reinterpret_cast(dwFunc)(pHierarchyInterface); + // clang-format on } void CAnimManagerSA::RemoveFromUncompressedCache(CAnimBlendHierarchy* pHierarchy) { DWORD dwFunc = FUNC_CAnimManager_RemoveFromUncompressedCache; CAnimBlendHierarchySAInterface* pHierarchyInterface = pHierarchy->GetInterface(); - _asm - { - push pHierarchyInterface - call dwFunc - add esp, 0x4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(pHierarchyInterface)); + reinterpret_cast(dwFunc)(pHierarchyInterface); + // clang-format on } void CAnimManagerSA::RemoveFromUncompressedCache(CAnimBlendHierarchySAInterface* pHierarchyInterface) { DWORD dwFunc = FUNC_CAnimManager_RemoveFromUncompressedCache; - _asm - { - push pHierarchyInterface - call dwFunc - add esp, 0x4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(pHierarchyInterface)); + reinterpret_cast(dwFunc)(pHierarchyInterface); + // clang-format on } void CAnimManagerSA::LoadAnimFile(const char* szFile) { DWORD dwFunc = FUNC_CAnimManager_LoadAnimFile; - _asm - { - push szFile - call dwFunc - add esp, 0x4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(szFile)); + reinterpret_cast(dwFunc)(szFile); + // clang-format on } void CAnimManagerSA::LoadAnimFile(RwStream* pStream, bool b1, const char* sz1) { DWORD dwFunc = FUNC_CAnimManager_LoadAnimFile_stream; - _asm - { - push sz1 - push b1 - push pStream - call dwFunc - add esp, 0xC - } + // clang-format off + using func_t = void (__cdecl*)(decltype(pStream), decltype(b1), decltype(sz1)); + reinterpret_cast(dwFunc)(pStream, b1, sz1); + // clang-format on } void CAnimManagerSA::LoadAnimFiles() { DWORD dwFunc = FUNC_CAnimManager_LoadAnimFiles; - _asm - { - call dwFunc - } + // clang-format off + using func_t = void (__cdecl*)(); + reinterpret_cast(dwFunc)(); + // clang-format on } void CAnimManagerSA::RemoveLastAnimFile() { DWORD dwFunc = FUNC_CAnimManager_RemoveLastAnimFile; - _asm - { - call dwFunc - } + // clang-format off + using func_t = void (__cdecl*)(); + reinterpret_cast(dwFunc)(); + // clang-format on } BYTE* CAnimManagerSA::AllocateKeyFramesMemory(uint32_t u32BytesToAllocate) { BYTE* pKeyFrames = nullptr; DWORD dwFunc = FUNC_CAnimManager_AllocateKeyFramesMemory; - _asm - { - push u32BytesToAllocate - call dwFunc - add esp, 0x4 - mov pKeyFrames, eax - } + // clang-format off + using func_t = decltype(pKeyFrames) (__cdecl*)(decltype(u32BytesToAllocate)); +pKeyFrames = reinterpret_cast(dwFunc)(u32BytesToAllocate); + // clang-format on return pKeyFrames; } void CAnimManagerSA::FreeKeyFramesMemory(void* pKeyFrames) { DWORD dwFunc = FUNC_CAnimManager_FreeKeyFramesMemory; - _asm - { - push pKeyFrames - call dwFunc - add esp, 0x4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(pKeyFrames)); + reinterpret_cast(dwFunc)(pKeyFrames); + // clang-format on } bool CAnimManagerSA::HasAnimGroupLoaded(AssocGroupId groupID) { bool bReturn; DWORD dwFunc = FUNC_HasAnimGroupLoaded; - _asm - { - push groupID - call dwFunc - mov bReturn, al - add esp, 0x4 - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(groupID)); +bReturn = reinterpret_cast(dwFunc)(groupID); + // clang-format on return bReturn; } @@ -662,13 +551,10 @@ std::unique_ptr CAnimManagerSA::RpAnimBlendClumpGetFirstA CAnimBlendAssociationSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_RpAnimBlendClumpGetFirstAssociation; - _asm - { - push pClump - call dwFunc - mov pInterface, eax - add esp, 0x4 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(pClump)); +pInterface = reinterpret_cast(dwFunc)(pClump); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -683,14 +569,10 @@ std::unique_ptr CAnimManagerSA::RpAnimBlendClumpGetAssoci CAnimBlendAssociationSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_RpAnimBlendClumpGetAssociation_str; - _asm - { - push szAnimName - push pClump - call dwFunc - mov pInterface, eax - add esp, 0x8 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(pClump), decltype(szAnimName)); +pInterface = reinterpret_cast(dwFunc)(pClump, szAnimName); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -705,14 +587,10 @@ std::unique_ptr CAnimManagerSA::RpAnimBlendClumpGetAssoci CAnimBlendAssociationSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_RpAnimBlendClumpGetAssociation_int; - _asm - { - push animID - push pClump - call dwFunc - mov pInterface, eax - add esp, 0x8 - } + // clang-format off + using func_t = decltype(pInterface) (__cdecl*)(decltype(pClump), decltype(animID)); +pInterface = reinterpret_cast(dwFunc)(pClump, animID); + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -725,13 +603,15 @@ std::unique_ptr CAnimManagerSA::RpAnimBlendGetNextAssocia CAnimBlendAssociationSAInterface* pInterface = nullptr; DWORD dwFunc = FUNC_RpAnimBlendGetNextAssociation; CAnimBlendAssociationSAInterface* pAssociationInterface = pAssociation->GetInterface(); - _asm + // clang-format off + __asm { push pAssociationInterface call dwFunc mov pInterface, eax add esp, 0x4 } + // clang-format on if (pInterface) { return std::make_unique(pInterface); @@ -746,13 +626,10 @@ int CAnimManagerSA::RpAnimBlendClumpGetNumAssociations(RpClump* pClump) int iReturn; DWORD dwFunc = FUNC_RpAnimBlendClumpGetNumAssociations; - _asm - { - push pClump - call dwFunc - mov iReturn, eax - add esp, 0x4 - } + // clang-format off + using func_t = decltype(iReturn) (__cdecl*)(decltype(pClump)); +iReturn = reinterpret_cast(dwFunc)(pClump); + // clang-format on return iReturn; } @@ -762,14 +639,10 @@ void CAnimManagerSA::RpAnimBlendClumpUpdateAnimations(RpClump* pClump, float f1, return; DWORD dwFunc = FUNC_RpAnimBlendClumpUpdateAnimations; - _asm - { - push b1 - push f1 - push pClump - call dwFunc - add esp, 0xC - } + // clang-format off + using func_t = void (__cdecl*)(decltype(pClump), decltype(f1), decltype(b1)); + reinterpret_cast(dwFunc)(pClump, f1, b1); + // clang-format on } std::unique_ptr CAnimManagerSA::GetAnimBlendAssociation(CAnimBlendAssociationSAInterface* pInterface) diff --git a/Client/game_sa/CAnimManagerSA.h b/Client/game_sa/CAnimManagerSA.h index 2268270044a..3e2d0a293d9 100644 --- a/Client/game_sa/CAnimManagerSA.h +++ b/Client/game_sa/CAnimManagerSA.h @@ -17,58 +17,58 @@ #include #include -#define FUNC_CAnimManager_Initialize 0x5bf6b0 -#define FUNC_CAnimManager_Shutdown 0x4d4130 -#define FUNC_CAnimManager_GetAnimationBlock_int 0x406f90 -#define FUNC_CAnimManager_GetAnimationBlock_str 0x4d3940 -#define FUNC_CAnimManager_GetAnimationBlockIndex 0x4d3990 -#define FUNC_CAnimManager_RegisterAnimBlock 0x4d3e50 -#define FUNC_CAnimManager_GetAnimBlendAssoc 0x45b0e0 -#define FUNC_CAnimManager_GetFirstAssocGroup 0x4d39b0 -#define FUNC_CAnimManager_GetAnimation_int 0x4cde50 -#define FUNC_CAnimManager_GetAnimation_str_block 0x4d42f0 -#define FUNC_CAnimManager_GetAnimation_int_block 0x4d39f0 -#define FUNC_CAnimManager_GetAnimGroupName 0x4d3a20 -#define FUNC_CAnimManager_GetAnimBlockName 0x4d3a30 -#define FUNC_CAnimManager_AddAnimBlockRef 0x4d3fb0 -#define FUNC_CAnimManager_RemoveAnimBlockRef 0x4d3fd0 -#define FUNC_CAnimManager_RemoveAnimBlockRefWithoutDelete 0x4d3ff0 -#define FUNC_CAnimManager_GetNumRefsToAnimBlock 0x4d4010 -#define FUNC_CAnimManager_RemoveAnimBlock 0x4d3f40 -#define FUNC_CAnimManager_RemoveLastAnimFile 0x4d3ed0 -#define FUNC_CAnimManager_AddAnimation 0x4d3aa0 -#define FUNC_CAnimManager_AddAnimation_hier 0x4d4330 -#define FUNC_CAnimManager_BlendAnimation 0x4d4610 -#define FUNC_CAnimManager_BlendAnimation_hier 0x4d4410 -#define FUNC_CAnimManager_AddAnimationAndSync 0x4d3b30 -#define FUNC_CAnimManager_CreateAnimAssociation 0x4d3a40 -#define FUNC_CAnimManager_GetAnimAssociation 0x4d3a60 -#define FUNC_CAnimManager_GetAnimAssociation_str 0x4d3a80 -#define FUNC_CAnimManager_AddAnimAssocDefinition 0x4d3ba0 -#define FUNC_CAnimManager_ReadAnimAssociationDefinitions 0x5bc910 -#define FUNC_CAnimManager_CreateAnimAssocGroups 0x4d3cc0 -#define FUNC_CAnimManager_UncompressAnimation 0x4d41c0 -#define FUNC_CAnimManager_RemoveFromUncompressedCache 0x4d42a0 -#define FUNC_CAnimManager_LoadAnimFile 0x4d55d0 -#define FUNC_CAnimManager_LoadAnimFile_stream 0x4d47f0 -#define FUNC_CAnimManager_LoadAnimFiles 0x4d5620 -#define FUNC_CAnimManager_AllocateKeyFramesMemory 0x72F420 -#define FUNC_CAnimManager_FreeKeyFramesMemory 0x72F430 -#define ARRAY_CAnimManager_AnimAssocGroups 0xb4ea34 -#define ARRAY_CAnimManager_Animations 0xb4ea40 -#define ARRAY_CAnimManager_AnimBlocks 0xb5d4a0 -#define VAR_CAnimManager_NumAnimAssocDefinitions 0xb4ea28 -#define VAR_CAnimManager_NumAnimations 0xb4ea2c -#define VAR_CAnimManager_NumAnimBlocks 0xb4ea30 +#define FUNC_CAnimManager_Initialize 0x5bf6b0 +#define FUNC_CAnimManager_Shutdown 0x4d4130 +#define FUNC_CAnimManager_GetAnimationBlock_int 0x406f90 +#define FUNC_CAnimManager_GetAnimationBlock_str 0x4d3940 +#define FUNC_CAnimManager_GetAnimationBlockIndex 0x4d3990 +#define FUNC_CAnimManager_RegisterAnimBlock 0x4d3e50 +#define FUNC_CAnimManager_GetAnimBlendAssoc 0x45b0e0 +#define FUNC_CAnimManager_GetFirstAssocGroup 0x4d39b0 +#define FUNC_CAnimManager_GetAnimation_int 0x4cde50 +#define FUNC_CAnimManager_GetAnimation_str_block 0x4d42f0 +#define FUNC_CAnimManager_GetAnimation_int_block 0x4d39f0 +#define FUNC_CAnimManager_GetAnimGroupName 0x4d3a20 +#define FUNC_CAnimManager_GetAnimBlockName 0x4d3a30 +#define FUNC_CAnimManager_AddAnimBlockRef 0x4d3fb0 +#define FUNC_CAnimManager_RemoveAnimBlockRef 0x4d3fd0 +#define FUNC_CAnimManager_RemoveAnimBlockRefWithoutDelete 0x4d3ff0 +#define FUNC_CAnimManager_GetNumRefsToAnimBlock 0x4d4010 +#define FUNC_CAnimManager_RemoveAnimBlock 0x4d3f40 +#define FUNC_CAnimManager_RemoveLastAnimFile 0x4d3ed0 +#define FUNC_CAnimManager_AddAnimation 0x4d3aa0 +#define FUNC_CAnimManager_AddAnimation_hier 0x4d4330 +#define FUNC_CAnimManager_BlendAnimation 0x4d4610 +#define FUNC_CAnimManager_BlendAnimation_hier 0x4d4410 +#define FUNC_CAnimManager_AddAnimationAndSync 0x4d3b30 +#define FUNC_CAnimManager_CreateAnimAssociation 0x4d3a40 +#define FUNC_CAnimManager_GetAnimAssociation 0x4d3a60 +#define FUNC_CAnimManager_GetAnimAssociation_str 0x4d3a80 +#define FUNC_CAnimManager_AddAnimAssocDefinition 0x4d3ba0 +#define FUNC_CAnimManager_ReadAnimAssociationDefinitions 0x5bc910 +#define FUNC_CAnimManager_CreateAnimAssocGroups 0x4d3cc0 +#define FUNC_CAnimManager_UncompressAnimation 0x4d41c0 +#define FUNC_CAnimManager_RemoveFromUncompressedCache 0x4d42a0 +#define FUNC_CAnimManager_LoadAnimFile 0x4d55d0 +#define FUNC_CAnimManager_LoadAnimFile_stream 0x4d47f0 +#define FUNC_CAnimManager_LoadAnimFiles 0x4d5620 +#define FUNC_CAnimManager_AllocateKeyFramesMemory 0x72F420 +#define FUNC_CAnimManager_FreeKeyFramesMemory 0x72F430 +#define ARRAY_CAnimManager_AnimAssocGroups 0xb4ea34 +#define ARRAY_CAnimManager_Animations 0xb4ea40 +#define ARRAY_CAnimManager_AnimBlocks 0xb5d4a0 +#define VAR_CAnimManager_NumAnimAssocDefinitions 0xb4ea28 +#define VAR_CAnimManager_NumAnimations 0xb4ea2c +#define VAR_CAnimManager_NumAnimBlocks 0xb4ea30 // Non members -#define FUNC_HasAnimGroupLoaded 0x45b130 -#define FUNC_RpAnimBlendClumpGetFirstAssociation 0x4d15e0 -#define FUNC_RpAnimBlendClumpGetAssociation_str 0x4d6870 -#define FUNC_RpAnimBlendClumpGetAssociation_int 0x4d68b0 -#define FUNC_RpAnimBlendGetNextAssociation 0x4d6ab0 -#define FUNC_RpAnimBlendClumpGetNumAssociations 0x4d6b60 -#define FUNC_RpAnimBlendClumpUpdateAnimations 0x4d34f0 +#define FUNC_HasAnimGroupLoaded 0x45b130 +#define FUNC_RpAnimBlendClumpGetFirstAssociation 0x4d15e0 +#define FUNC_RpAnimBlendClumpGetAssociation_str 0x4d6870 +#define FUNC_RpAnimBlendClumpGetAssociation_int 0x4d68b0 +#define FUNC_RpAnimBlendGetNextAssociation 0x4d6ab0 +#define FUNC_RpAnimBlendClumpGetNumAssociations 0x4d6b60 +#define FUNC_RpAnimBlendClumpUpdateAnimations 0x4d34f0 class CAnimManagerSA : public CAnimManager { diff --git a/Client/game_sa/CAudioContainerLookupTableSA.h b/Client/game_sa/CAudioContainerLookupTableSA.h index 077c865aa35..52dde675c58 100644 --- a/Client/game_sa/CAudioContainerLookupTableSA.h +++ b/Client/game_sa/CAudioContainerLookupTableSA.h @@ -34,5 +34,5 @@ struct SAudioLookupEntrySA uint8 filter[3]; uint32 offset; uint32 length; -}; // size = 12 = 0xC +}; // size = 12 = 0xC static_assert(sizeof(SAudioLookupEntrySA) == 0xC, "Invalid size for SAudioLookupEntrySA"); diff --git a/Client/game_sa/CAudioContainerSA.cpp b/Client/game_sa/CAudioContainerSA.cpp index b8fbfc32321..794dda76d08 100644 --- a/Client/game_sa/CAudioContainerSA.cpp +++ b/Client/game_sa/CAudioContainerSA.cpp @@ -54,20 +54,20 @@ bool CAudioContainerSA::GetAudioData(eAudioLookupIndex lookupIndex, int bankInde // Add the RIFF Wave header since BASS does not support raw data SRiffWavePCMHeader waveHeader; - waveHeader.chunkId = EndianSwap32(0x52494646); // "RIFF" in ASCII, big-Endian + waveHeader.chunkId = EndianSwap32(0x52494646); // "RIFF" in ASCII, big-Endian waveHeader.chunkSize = 36 + rawAudioLength; - waveHeader.format = EndianSwap32(0x57415645); // "WAVE" in ASCII, big-Endian + waveHeader.format = EndianSwap32(0x57415645); // "WAVE" in ASCII, big-Endian - waveHeader.subchunk1Id = EndianSwap32(0x666d7420); // "fmt " in ASCII, big-Endian - waveHeader.subchunk1Size = 16; // 16 for PCM - waveHeader.audioFormat = 0x1; // PCM - waveHeader.numChannels = 1; // Mono + waveHeader.subchunk1Id = EndianSwap32(0x666d7420); // "fmt " in ASCII, big-Endian + waveHeader.subchunk1Size = 16; // 16 for PCM + waveHeader.audioFormat = 0x1; // PCM + waveHeader.numChannels = 1; // Mono waveHeader.sampleRate = iSampleRate; - waveHeader.bitsPerSample = 16; // 16-Bit PCM + waveHeader.bitsPerSample = 16; // 16-Bit PCM waveHeader.byteRate = waveHeader.sampleRate * waveHeader.numChannels * waveHeader.bitsPerSample / 8; waveHeader.blockAlign = waveHeader.numChannels * waveHeader.bitsPerSample / 8; - waveHeader.subchunk2Id = EndianSwap32(0x64617461); // "data" in ASCII, big-endian + waveHeader.subchunk2Id = EndianSwap32(0x64617461); // "data" in ASCII, big-endian waveHeader.subchunk2Size = rawAudioLength; // Allocate a second buffer as we've to insert the wave pcm header at the beginning @@ -94,10 +94,13 @@ bool CAudioContainerSA::GetRawAudioData(eAudioLookupIndex lookupIndex, int bankI if (numBanks == 0) return false; + if (bankIndex < 0 || bankIndex >= numBanks || bankIndex > 0xFF) + return false; + // Get archive file size std::ifstream archive(FromUTF8(GetAudioArchiveName(lookupIndex)), std::ios::binary); - SAudioLookupEntrySA* lookupEntry = m_pLookupTable->GetEntry(lookupIndex, bankIndex); + SAudioLookupEntrySA* lookupEntry = m_pLookupTable->GetEntry(lookupIndex, static_cast(bankIndex)); if (!lookupEntry) return false; @@ -115,7 +118,7 @@ bool CAudioContainerSA::GetRawAudioData(eAudioLookupIndex lookupIndex, int bankI return false; unsigned int rawLength; - if (audioIndex + 1 < bankHeader.numSounds) // hacky fix: audioIndex starts at 0 + if (audioIndex + 1 < bankHeader.numSounds) // hacky fix: audioIndex starts at 0 { SAudioEntrySA* nextAudioEntry = &bankHeader.sounds[audioIndex + 1]; if (!nextAudioEntry) @@ -127,8 +130,9 @@ bool CAudioContainerSA::GetRawAudioData(eAudioLookupIndex lookupIndex, int bankI { rawLength = lookupEntry->length - audioEntry->offset; } - else + else { return false; +} // 2MB check in case of user modification errors (Max length of standard audio files is 560KB) if (rawLength > 2 * 1024 * 1024) @@ -142,8 +146,7 @@ bool CAudioContainerSA::GetRawAudioData(eAudioLookupIndex lookupIndex, int bankI iSampleRateOut = audioEntry->sampleRate; // Seek to the correct offset and read - archive.seekg(lookupEntry->offset + sizeof(SAudioBankHeaderSA) + - audioEntry->offset); // Or just archive.seekg ( archive.tellg() + audioEntry->offset ) + archive.seekg(lookupEntry->offset + sizeof(SAudioBankHeaderSA) + audioEntry->offset); // Or just archive.seekg ( archive.tellg() + audioEntry->offset ) archive.read(reinterpret_cast(buffer), rawLength); return !archive.fail(); diff --git a/Client/game_sa/CAudioContainerSA.h b/Client/game_sa/CAudioContainerSA.h index 9f412c0de19..a2376dd356a 100644 --- a/Client/game_sa/CAudioContainerSA.h +++ b/Client/game_sa/CAudioContainerSA.h @@ -17,8 +17,8 @@ class CAudioContainerLookupTableSA; #define VALIDATE_BUFFER_SIZE 4096 -#define NUM_BEAT_ENTRIES 1000 -#define NUM_LENGTH_ENTRIES 8 +#define NUM_BEAT_ENTRIES 1000 +#define NUM_LENGTH_ENTRIES 8 struct SAudioEntrySA { @@ -32,27 +32,27 @@ static_assert(sizeof(SAudioEntrySA) == 0xC, "Invalid size for SAudioLookupEntryS struct SAudioBankHeaderSA { int numSounds; - SAudioEntrySA sounds[400]; // Todo: optimize this (dynamic allocation) + SAudioEntrySA sounds[400]; // Todo: optimize this (dynamic allocation) }; struct SRiffWavePCMHeader { - uint32 chunkId; // big-endian // 0 - uint32 chunkSize; // 4 - uint32 format; // big-endian // 8 - - uint32 subchunk1Id; // big-endian // 12 - uint32 subchunk1Size; // 16 - uint16 audioFormat; // 20 - uint16 numChannels; // 22 - uint32 sampleRate; // 24 - uint32 byteRate; // 28 - uint16 blockAlign; // 32 - uint16 bitsPerSample; // 34 - - uint32 subchunk2Id; // big-endian // 36 - uint32 subchunk2Size; // 40 -}; // size = 44 = 0x2C + uint32 chunkId; // big-endian // 0 + uint32 chunkSize; // 4 + uint32 format; // big-endian // 8 + + uint32 subchunk1Id; // big-endian // 12 + uint32 subchunk1Size; // 16 + uint16 audioFormat; // 20 + uint16 numChannels; // 22 + uint32 sampleRate; // 24 + uint32 byteRate; // 28 + uint16 blockAlign; // 32 + uint16 bitsPerSample; // 34 + + uint32 subchunk2Id; // big-endian // 36 + uint32 subchunk2Size; // 40 +}; // size = 44 = 0x2C static_assert(sizeof(SRiffWavePCMHeader) == 0x2C, "Invalid size for SRiffWavePCMHeader"); // Documentation by SAAT // diff --git a/Client/game_sa/CAudioEngineSA.cpp b/Client/game_sa/CAudioEngineSA.cpp index 28630c53e6b..a1e57cf5181 100644 --- a/Client/game_sa/CAudioEngineSA.cpp +++ b/Client/game_sa/CAudioEngineSA.cpp @@ -11,6 +11,7 @@ #include "StdInc.h" #include "CAESoundManagerSA.h" +#include "CAEAudioHardwareSA.h" #include "CAudioEngineSA.h" #include "CGameSA.h" #include "CPhysicalSA.h" @@ -18,11 +19,35 @@ extern CGameSA* pGame; -#define HOOKPOS_CAEAmbienceTrackManager_CheckForPause 0x4D6E21 +#define NUM_MaxWorldSoundIndex 399 +#define NUM_FallbackWorldSoundBankSlotCount (BANKSLOT_44 + 1) +#define NUM_AudioHardwareBankLoaderOffset 0xD98 +#define NUM_BankLoaderSlotCountOffset 0x0C + +namespace +{ + bool IsValidWorldSoundBankSlot(unsigned short usBankSlot) noexcept + { + auto* pAudioHardware = reinterpret_cast(CLASS_CAEAudioHardware); + auto* pBankLoader = *reinterpret_cast(pAudioHardware + NUM_AudioHardwareBankLoaderOffset); + if (!pBankLoader) + return usBankSlot < NUM_FallbackWorldSoundBankSlotCount; + + const auto usBankSlotCount = *reinterpret_cast(reinterpret_cast(pBankLoader) + NUM_BankLoaderSlotCountOffset); + return usBankSlot < usBankSlotCount; + } + + bool IsValidWorldSoundRequest(const CAESound* pAESound) noexcept + { + return pAESound && pAESound->usIndex <= NUM_MaxWorldSoundIndex && IsValidWorldSoundBankSlot(pAESound->usGroup); + } +} + +#define HOOKPOS_CAEAmbienceTrackManager_CheckForPause 0x4D6E21 DWORD RETURN_CAEAmbienceTrackManager_CheckForPause = 0x4D6E27; void HOOK_CAEAmbienceTrackManager_CheckForPause(); -#define HOOKPOS_CAESoundManager_RequestNewSound 0x4EFB10 +#define HOOKPOS_CAESoundManager_RequestNewSound 0x4EFB10 DWORD RETURN_CAESoundManager_RequestNewSound = 0x4EFB15; void HOOK_CAESoundManager_RequestNewSound(); @@ -44,13 +69,13 @@ CAudioEngineSA::CAudioEngineSA(CAudioEngineSAInterface* pInterface) HookInstall(HOOKPOS_CAEAmbienceTrackManager_CheckForPause, (DWORD)HOOK_CAEAmbienceTrackManager_CheckForPause, 6); // Make room for hook - MemPut(0x4EFB15 + 0, 0x0F); // movsx eax, si + MemPut(0x4EFB15 + 0, 0x0F); // movsx eax, si MemPut(0x4EFB15 + 1, 0xBF); MemPut(0x4EFB15 + 2, 0xC6); - MemPut(0x4EFB15 + 3, 0x6B); // imul eax, 74h + MemPut(0x4EFB15 + 3, 0x6B); // imul eax, 74h MemPut(0x4EFB15 + 4, 0xC0); MemPut(0x4EFB15 + 5, 0x74); - MemPut(0x4EFB29, 0xEB); // Move jump forward one byte + MemPut(0x4EFB29, 0xEB); // Move jump forward one byte HookInstall(HOOKPOS_CAESoundManager_RequestNewSound, (DWORD)HOOK_CAESoundManager_RequestNewSound, 5); } @@ -59,9 +84,10 @@ void CAudioEngineSA::StopRadio() m_bRadioOn = false; // DWORD dwFunc = FUNC_StopRadio; - DWORD dwFunc = 0x4E9823; // Some function CAudio::StopRadio jumps to immediately + DWORD dwFunc = 0x4E9823; // Some function CAudio::StopRadio jumps to immediately - _asm + // clang-format off + __asm { // This doesn't work anymore because we've // returned out the function. @@ -91,11 +117,15 @@ void CAudioEngineSA::StopRadio() retpoint: } + // clang-format on } void CAudioEngineSA::StartRadio(unsigned int station) { - m_ucRadioChannel = station; + if (station > 0xFF) + return; + + m_ucRadioChannel = static_cast(station); m_bRadioOn = true; // Make sure we have the correct muted state @@ -105,7 +135,8 @@ void CAudioEngineSA::StartRadio(unsigned int station) DWORD dwFunc = 0x4DBEC3; DWORD dwFunc2 = 0x4EB3C3; - _asm + // clang-format off + __asm { // We can't do this anymore as we've returned out StartRadio /* @@ -151,6 +182,7 @@ void CAudioEngineSA::StartRadio(unsigned int station) skip: } + // clang-format on } // 43 = race one @@ -158,19 +190,15 @@ void CAudioEngineSA::StartRadio(unsigned int station) // 13 = camera take picture void CAudioEngineSA::PlayFrontEndSound(DWORD dwEventID) { - if (*(DWORD*)VAR_AudioEventVolumes != 0 && dwEventID <= 101) // may prevent a crash + if (*(DWORD*)VAR_AudioEventVolumes != 0 && dwEventID <= 101) // may prevent a crash { DWORD dwFunc = FUNC_ReportFrontendAudioEvent; float fSpeed = 1.0f; float fVolumeChange = 0.0f; - _asm - { - push fSpeed - push fVolumeChange - push dwEventID - mov ecx, CLASS_CAudioEngine - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB6BC90), decltype(dwEventID), decltype(fVolumeChange), decltype(fSpeed)); + reinterpret_cast(dwFunc)(0xB6BC90, dwEventID, fVolumeChange, fSpeed); + // clang-format on } } @@ -178,24 +206,20 @@ void CAudioEngineSA::SetEffectsMasterVolume(BYTE bVolume) { DWORD dwFunc = FUNC_SetEffectsMasterVolume; DWORD dwVolume = bVolume; - _asm - { - mov ecx, CLASS_CAudioEngine - push dwVolume - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB6BC90), decltype(dwVolume)); + reinterpret_cast(dwFunc)(0xB6BC90, dwVolume); + // clang-format on } void CAudioEngineSA::SetMusicMasterVolume(BYTE bVolume) { DWORD dwFunc = FUNC_SetMusicMasterVolume; DWORD dwVolume = bVolume; - _asm - { - mov ecx, CLASS_CAudioEngine - push dwVolume - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB6BC90), decltype(dwVolume)); + reinterpret_cast(dwFunc)(0xB6BC90, dwVolume); + // clang-format on // // See if radio stream should be stopped/started @@ -217,83 +241,68 @@ void CAudioEngineSA::SetMusicMasterVolume(BYTE bVolume) { // unmute -> mute StopRadio(); - m_bRadioOn = true; // StopRadio was only called to stop the radio stream. Radio is logically still on + m_bRadioOn = true; // StopRadio was only called to stop the radio stream. Radio is logically still on } } } void CAudioEngineSA::PlayBeatTrack(short iTrack) { - if (*(DWORD*)VAR_AudioEventVolumes != 0) // may prevent a crash + if (*(DWORD*)VAR_AudioEventVolumes != 0) // may prevent a crash { DWORD dwFunc = FUNC_PreloadBeatTrack; DWORD dwTrack = iTrack; - _asm - { - mov ecx, CLASS_CAudioEngine - push dwTrack - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB6BC90), decltype(dwTrack)); + reinterpret_cast(dwFunc)(0xB6BC90, dwTrack); + // clang-format on dwFunc = FUNC_PlayPreloadedBeatTrack; - _asm - { - mov ecx, CLASS_CAudioEngine - push 1 - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB6BC90), decltype(1)); + reinterpret_cast(dwFunc)(0xB6BC90, 1); + // clang-format on } } void CAudioEngineSA::ClearMissionAudio(int slot) { - DWORD dwFunc = 0x5072F0; // CAudioEngine::ClearMissionAudio(unsigned char) - _asm - { - mov ecx, CLASS_CAudioEngine - push slot // sound bank slot? - call dwFunc - } + DWORD dwFunc = 0x5072F0; // CAudioEngine::ClearMissionAudio(unsigned char) + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB6BC90), decltype(slot)); + reinterpret_cast(dwFunc)(0xB6BC90, slot); + // clang-format on } bool CAudioEngineSA::IsMissionAudioSampleFinished(int slot) { - DWORD dwFunc = 0x5072C0; // CAudioEngine::IsMissionAudioSampleFinished + DWORD dwFunc = 0x5072C0; // CAudioEngine::IsMissionAudioSampleFinished bool cret = 0; - _asm - { - mov ecx, CLASS_CAudioEngine - push slot - call dwFunc - mov cret, al - } + // clang-format off + using func_t = decltype(cret) (__thiscall*)(decltype(0xB6BC90), decltype(slot)); +cret = reinterpret_cast(dwFunc)(0xB6BC90, slot); + // clang-format on return cret; } void CAudioEngineSA::PreloadMissionAudio(unsigned short usAudioEvent, int slot) { - DWORD dwFunc = 0x507290; // CAudioEngine__PreloadMissionAudio + DWORD dwFunc = 0x507290; // CAudioEngine__PreloadMissionAudio DWORD AudioEvent = usAudioEvent; - _asm - { - mov ecx, CLASS_CAudioEngine - push AudioEvent - push slot - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB6BC90), decltype(slot), decltype(AudioEvent)); + reinterpret_cast(dwFunc)(0xB6BC90, slot, AudioEvent); + // clang-format on } unsigned char CAudioEngineSA::GetMissionAudioLoadingStatus(int slot) { - DWORD dwFunc = 0x5072A0; // get load status + DWORD dwFunc = 0x5072A0; // get load status unsigned char cret = 0; - _asm - { - mov ecx, CLASS_CAudioEngine - push slot - call dwFunc - mov cret, al - } + // clang-format off + using func_t = decltype(cret) (__thiscall*)(decltype(0xB6BC90), decltype(slot)); +cret = reinterpret_cast(dwFunc)(0xB6BC90, slot); + // clang-format on return cret; } @@ -307,39 +316,31 @@ void CAudioEngineSA::AttachMissionAudioToPhysical(CPhysical* physical, int slot) entity = pPhysical->GetInterface(); } - DWORD dwFunc = 0x507330; // AttachMissionAudioToPhysical - _asm - { - mov ecx, CLASS_CAudioEngine - push entity - push slot - call dwFunc - } + DWORD dwFunc = 0x507330; // AttachMissionAudioToPhysical + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB6BC90), decltype(slot), decltype(entity)); + reinterpret_cast(dwFunc)(0xB6BC90, slot, entity); + // clang-format on } void CAudioEngineSA::SetMissionAudioPosition(CVector* position, int slot) { - DWORD dwFunc = 0x507300; // CAudioEngine__SetMissionAudioPosition - _asm - { - mov ecx, CLASS_CAudioEngine - push position - push slot - call dwFunc - } + DWORD dwFunc = 0x507300; // CAudioEngine__SetMissionAudioPosition + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB6BC90), decltype(slot), decltype(position)); + reinterpret_cast(dwFunc)(0xB6BC90, slot, position); + // clang-format on } bool CAudioEngineSA::PlayLoadedMissionAudio(int slot) { if (GetMissionAudioLoadingStatus(slot) == 1) { - DWORD dwFunc = 0x5072B0; // CAudioEngine::PlayLoadedMissionAudio(unsigned char) - _asm - { - mov ecx, CLASS_CAudioEngine - push slot - call dwFunc - } + DWORD dwFunc = 0x5072B0; // CAudioEngine::PlayLoadedMissionAudio(unsigned char) + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB6BC90), decltype(slot)); + reinterpret_cast(dwFunc)(0xB6BC90, slot); + // clang-format on return true; } return false; @@ -350,20 +351,18 @@ void CAudioEngineSA::PauseAllSound(bool bPaused) if (bPaused) { DWORD dwFunc = FUNC_PauseAllSounds; - _asm - { - mov ecx, CLASS_CAudioEngine - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB6BC90) ); + reinterpret_cast(dwFunc)(0xB6BC90); + // clang-format on } else { DWORD dwFunc = FUNC_ResumeAllSounds; - _asm - { - mov ecx, CLASS_CAudioEngine - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB6BC90) ); + reinterpret_cast(dwFunc)(0xB6BC90); + // clang-format on } } @@ -390,13 +389,14 @@ bool CAudioEngineSA::IsAmbientSoundEnabled(eAmbientSoundType eType) { if (m_bAmbientSoundsPaused) return false; - if (eType == AMBIENT_SOUND_GENERAL) + if (eType == AMBIENT_SOUND_GENERAL) { return m_bAmbientGeneralEnabled; - else if (eType == AMBIENT_SOUND_GUNFIRE) + } else if (eType == AMBIENT_SOUND_GUNFIRE) { return m_bAmbientGunfireEnabled; - else + } else { return false; } +} void CAudioEngineSA::ResetAmbientSounds() { @@ -408,37 +408,37 @@ void CAudioEngineSA::UpdateAmbientSoundSettings() { // Update gunfire setting if (IsAmbientSoundEnabled(AMBIENT_SOUND_GUNFIRE)) - MemPut(0x507814, 0x85); // Enable gunfire (default) + MemPut(0x507814, 0x85); // Enable gunfire (default) else - MemPut(0x507814, 0x33); // No gunfire + MemPut(0x507814, 0x33); // No gunfire } -__declspec(noinline) bool _cdecl IsAmbientSoundGeneralEnabled() +static bool IsAmbientSoundGeneralEnabled() { - if (pGame) - { - return pGame->GetAudioEngine()->IsAmbientSoundEnabled(AMBIENT_SOUND_GENERAL); - } - return false; + return pGame && pGame->GetAudioEngine()->IsAmbientSoundEnabled(AMBIENT_SOUND_GENERAL); } // Hook for manual ambient sound pause -void _declspec(naked) HOOK_CAEAmbienceTrackManager_CheckForPause() +static void __declspec(naked) HOOK_CAEAmbienceTrackManager_CheckForPause() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - // Hooked from 004D6E21 6 bytes - call IsAmbientSoundGeneralEnabled - test al, al - jnz skip - mov dword ptr [esp+08h], 0 // Pause - skip: - - // orig - mov edi, [esp+08h] + pushad + call IsAmbientSoundGeneralEnabled + test al, al + popad + jnz continueWithOriginalCode + mov dword ptr [esp+8], 0 // Pause by setting 0.0f for the last argument to CAEAudioHardware::SetChannelFrequencyScalingFactor + + continueWithOriginalCode: + mov edi, [esp+8] xor ecx, ecx - jmp RETURN_CAEAmbienceTrackManager_CheckForPause // 4D6E27 + jmp RETURN_CAEAmbienceTrackManager_CheckForPause } + // clang-format on } // @@ -457,8 +457,9 @@ void CAudioEngineSA::SetWorldSoundEnabled(uint uiGroup, uint uiIndex, bool bEnab if (bImmediate) g_pAESoundManagerSA->CancelSoundsInBankSlot(uiGroup, uiIndex); } - else - m_DisabledWorldSounds.UnsetRange(uiFirst, uiLast - uiFirst + 1); + else { + m +}_DisabledWorldSounds.UnsetRange(uiFirst, uiLast - uiFirst + 1); } // uiIndex = -1 for all in group @@ -481,6 +482,9 @@ void CAudioEngineSA::SetWorldSoundHandler(WorldSoundHandler* pHandler) bool CAudioEngineSA::OnWorldSound(CAESound* pAESound) { + if (!IsValidWorldSoundRequest(pAESound)) + return false; + if (!IsWorldSoundEnabled(pAESound->usGroup, pAESound->usIndex)) return false; @@ -506,34 +510,40 @@ bool CAudioEngineSA::OnWorldSound(CAESound* pAESound) //////////////////////////////////////////////////////////////////////////////////////////////// // Return false to skip sound -__declspec(noinline) bool _cdecl On_CAESoundManager_RequestNewSound(CAESound* pAESound) +static bool _cdecl OnRequestNewSound(CAESound* pAESound) { + if (!IsValidWorldSoundRequest(pAESound) || !g_pAudioSA) + return false; + return g_pAudioSA->OnWorldSound(pAESound); } -void _declspec(naked) HOOK_CAESoundManager_RequestNewSound() +static void __declspec(naked) HOOK_CAESoundManager_RequestNewSound() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*1] - call On_CAESoundManager_RequestNewSound - add esp, 4*1 - cmp al, 0 - jz skip + call OnRequestNewSound + add esp, 4 + test al, al popad + jnz continueWithOriginalCode + + // Skip playing sound + xor eax, eax + retn 4 - // Continue with standard code + continueWithOriginalCode: push esi push edi xor esi, esi jmp RETURN_CAESoundManager_RequestNewSound - -skip: // Skip playing sound - popad - xor eax, eax - retn 4 } + // clang-format on } void CAudioEngineSA::ReportBulletHit(CEntity* pEntity, unsigned char ucSurfaceType, CVector* pvecPosition, float f_2) @@ -543,15 +553,10 @@ void CAudioEngineSA::ReportBulletHit(CEntity* pEntity, unsigned char ucSurfaceTy dwEntityInterface = (DWORD)pEntity->GetInterface(); DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAudioEngine_ReportBulletHit; - _asm - { - mov ecx, dwThis - push f_2 - push pvecPosition - push ucSurfaceType - push dwEntityInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwEntityInterface), decltype(ucSurfaceType), decltype(pvecPosition), decltype(f_2)); + reinterpret_cast(dwFunc)(dwThis, dwEntityInterface, ucSurfaceType, pvecPosition, f_2); + // clang-format on } void CAudioEngineSA::ReportWeaponEvent(int iEvent, eWeaponType weaponType, CPhysical* pPhysical) @@ -561,12 +566,8 @@ void CAudioEngineSA::ReportWeaponEvent(int iEvent, eWeaponType weaponType, CPhys dwPhysicalInterface = (DWORD)pPhysical->GetInterface(); DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAudioEngine_ReportWeaponEvent; - _asm - { - mov ecx, dwThis - push dwPhysicalInterface - push weaponType - push iEvent - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(iEvent), decltype(weaponType), decltype(dwPhysicalInterface)); + reinterpret_cast(dwFunc)(dwThis, iEvent, weaponType, dwPhysicalInterface); + // clang-format on } diff --git a/Client/game_sa/CAudioEngineSA.h b/Client/game_sa/CAudioEngineSA.h index 2b9d77b8662..f86f5d8b0ce 100644 --- a/Client/game_sa/CAudioEngineSA.h +++ b/Client/game_sa/CAudioEngineSA.h @@ -13,29 +13,29 @@ #include -#define FUNC_ReportFrontendAudioEvent 0x506EA0 -#define FUNC_PreloadBeatTrack 0x507F40 -#define FUNC_PlayPreloadedBeatTrack 0x507180 +#define FUNC_ReportFrontendAudioEvent 0x506EA0 +#define FUNC_PreloadBeatTrack 0x507F40 +#define FUNC_PlayPreloadedBeatTrack 0x507180 -#define FUNC_SetEffectsMasterVolume 0x506E10 -#define FUNC_SetMusicMasterVolume 0x506DE0 +#define FUNC_SetEffectsMasterVolume 0x506E10 +#define FUNC_SetMusicMasterVolume 0x506DE0 -#define FUNC_ReportMissionAudioEvent_Vehicle 0x507390 -#define FUNC_ReportMissionAudioEvent_Vector 0x507340 -#define FUNC_PauseAllSounds 0x507430 -#define FUNC_ResumeAllSounds 0x507440 -#define FUNC_StopRadio 0x506F70 -#define FUNC_StartRadio2 0x507DC0 +#define FUNC_ReportMissionAudioEvent_Vehicle 0x507390 +#define FUNC_ReportMissionAudioEvent_Vector 0x507340 +#define FUNC_PauseAllSounds 0x507430 +#define FUNC_ResumeAllSounds 0x507440 +#define FUNC_StopRadio 0x506F70 +#define FUNC_StartRadio2 0x507DC0 -#define VAR_AudioEventVolumes 0xBD00F8 // m_pAudioEventVolumes +#define VAR_AudioEventVolumes 0xBD00F8 // m_pAudioEventVolumes -#define CLASS_CAudioEngine 0xB6BC90 -#define CLASS_AERadioTrackManager 0x8CB6F8 -#define CLASS_AECutsceneTrackManager 0x8AE554 -#define FUNC_CAudioEngine_ReportBulletHit 0x506ec0 -#define FUNC_CAudioEngine_ReportWeaponEvent 0x506f40 +#define CLASS_CAudioEngine 0xB6BC90 +#define CLASS_AERadioTrackManager 0x8CB6F8 +#define CLASS_AECutsceneTrackManager 0x8AE554 +#define FUNC_CAudioEngine_ReportBulletHit 0x506ec0 +#define FUNC_CAudioEngine_ReportWeaponEvent 0x506f40 -#define FUNC_CAESound__Stop 0x4EF1C0 +#define FUNC_CAESound__Stop 0x4EF1C0 class CAudioEngineSAInterface { @@ -50,33 +50,33 @@ class CAEAudioEntity public: CAEAudioEntityVTBL* vtbl; CEntitySAInterface* pEntity; - char m_tempSound[0x74]; // CAESound + char m_tempSound[0x74]; // CAESound }; static_assert(sizeof(CAEAudioEntity) == 0x7C, "Invalid size for CAEAudioEntity"); class CAESound { public: - ushort usGroup; // +0 - ushort usIndex; // +2 - CAEAudioEntity* pAudioEntity; // +4 - CEntitySAInterface* pGameEntity; // +8 Either a player or NULL - unsigned int m_dwEvent; // +12 - float m_fMaxVolume; // +16 - float m_fVolume; // +20 - float m_fSoundDistance; // +24 - float m_fSpeed; // +28 - float unk1; // +32 - CVector m_vCurrPosn; // +36 - CVector m_vPrevPosn; // +48 - int m_dwLastFrameUpdate; // +60 - int m_dwCurrTimeUpdate; // +64 - int m_dwPrevTimeUpdate; // +68 - float m_fCurrCamDist; // +72 - float m_fPrevCamDist; // +76 - float m_fTimeScale; // +80 - char unk2; // +84 = 31488 - char unk3; // +85 = 1005 + ushort usGroup; // +0 + ushort usIndex; // +2 + CAEAudioEntity* pAudioEntity; // +4 + CEntitySAInterface* pGameEntity; // +8 Either a player or NULL + unsigned int m_dwEvent; // +12 + float m_fMaxVolume; // +16 + float m_fVolume; // +20 + float m_fSoundDistance; // +24 + float m_fSpeed; // +28 + float unk1; // +32 + CVector m_vCurrPosn; // +36 + CVector m_vPrevPosn; // +48 + int m_dwLastFrameUpdate; // +60 + int m_dwCurrTimeUpdate; // +64 + int m_dwPrevTimeUpdate; // +68 + float m_fCurrCamDist; // +72 + float m_fPrevCamDist; // +76 + float m_fTimeScale; // +80 + char unk2; // +84 = 31488 + char unk3; // +85 = 1005 union { unsigned short m_wEnvironmentFlags; @@ -97,17 +97,17 @@ class CAESound unsigned short m_bForcedFront : 1; }; }; - unsigned short m_wIsUsed; // +88 - short unk4; // +90 = 1005 - short m_wCurrentPlayPosition; // +92 - short unk5; // +94 = 0 - float m_fFinalVolume; // +96 - float m_fFrequency; // +100 - short m_wPlayingState; // +104 - char unk6[2]; // +106 - float m_fSoundHeadRoom; // +108 - short m_wSoundLength; // +112 - short unk8; // +114 + unsigned short m_wIsUsed; // +88 + short unk4; // +90 = 1005 + short m_wCurrentPlayPosition; // +92 + short unk5; // +94 = 0 + float m_fFinalVolume; // +96 + float m_fFrequency; // +100 + short m_wPlayingState; // +104 + char unk6[2]; // +106 + float m_fSoundHeadRoom; // +108 + short m_wSoundLength; // +112 + short unk8; // +114 }; static_assert(sizeof(CAESound) == 0x74, "Invalid size for CAESound"); @@ -118,7 +118,7 @@ class CAudioEngineSA : public CAudioEngine void PlayFrontEndSound(DWORD dwSound); void PlayBeatTrack(short iTrack); - void SetEffectsMasterVolume(BYTE bVolume); // 64 = max volume + void SetEffectsMasterVolume(BYTE bVolume); // 64 = max volume void SetMusicMasterVolume(BYTE bVolume); void ClearMissionAudio(int slot = 1); void PreloadMissionAudio(unsigned short usAudioEvent, int slot = 1); diff --git a/Client/game_sa/CAutomobileSA.cpp b/Client/game_sa/CAutomobileSA.cpp index 8a588694586..0f18c6491f2 100644 --- a/Client/game_sa/CAutomobileSA.cpp +++ b/Client/game_sa/CAutomobileSA.cpp @@ -1,6 +1,6 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: game_sa/CAutomobileSA.cpp * PURPOSE: Automobile vehicle entity @@ -21,6 +21,17 @@ CAutomobileSA::CAutomobileSA(CAutomobileSAInterface* pInterface) Init(); } +// Returns true when any wheel is partially compressed (not fully relaxed) +bool CAutomobileSA::IsAnyWheelTouchingGround() const +{ + CAutomobileSAInterface* autoInterface = GetAutomobileInterface(); + if (!autoInterface) + return false; + + return autoInterface->m_wheelRatios[0] < 1.0f || autoInterface->m_wheelRatios[1] < 1.0f || autoInterface->m_wheelRatios[2] < 1.0f || + autoInterface->m_wheelRatios[3] < 1.0f; +} + void CAutomobileSAInterface::SetPanelDamage(std::uint8_t panelId, bool breakGlass, bool spawnFlyingComponent) { int nodeId = CDamageManagerSA::GetCarNodeIndexFromPanel(panelId); @@ -44,7 +55,7 @@ void CAutomobileSAInterface::SetPanelDamage(std::uint8_t panelId, bool breakGlas { case DT_PANEL_DAMAGED: { - if ((pHandlingData->uiModelFlags & 0x10000000) != 0) // check bouncePanels flag + if ((pHandlingData->uiModelFlags & 0x10000000) != 0) // check bouncePanels flag return; if (node != eCarNodes::WINDSCREEN && node != eCarNodes::WING_LF && node != eCarNodes::WING_RF) @@ -54,13 +65,16 @@ void CAutomobileSAInterface::SetPanelDamage(std::uint8_t panelId, bool breakGlas { if (panel.m_nFrameId == (std::uint16_t)0xFFFF) { - panel.SetPanel(nodeId, 1, GetRandomNumberInRange(-0.2f, -0.5f)); + if (nodeId < 0 || nodeId > 0x7FFF) + return; + + panel.SetPanel(static_cast(nodeId), static_cast(1), GetRandomNumberInRange(-0.2f, -0.5f)); break; } } } - SetComponentVisibility(frame, 2); // ATOMIC_IS_DAM_STATE + SetComponentVisibility(frame, 2); // ATOMIC_IS_DAM_STATE break; } case DT_PANEL_OPENED: @@ -68,7 +82,7 @@ void CAutomobileSAInterface::SetPanelDamage(std::uint8_t panelId, bool breakGlas if (panelId == WINDSCREEN_PANEL) m_VehicleAudioEntity.AddAudioEvent(91, 0.0f); - SetComponentVisibility(frame, 2); // ATOMIC_IS_DAM_STATE + SetComponentVisibility(frame, 2); // ATOMIC_IS_DAM_STATE break; } case DT_PANEL_OPENED_DAMAGED: @@ -76,13 +90,13 @@ void CAutomobileSAInterface::SetPanelDamage(std::uint8_t panelId, bool breakGlas if (panelId == WINDSCREEN_PANEL) { if (breakGlass) - ((void(__cdecl*)(CAutomobileSAInterface*, bool))0x71C2B0)(this, false); // Call CGlass::CarWindscreenShatters + ((void(__cdecl*)(CAutomobileSAInterface*, bool))0x71C2B0)(this, false); // Call CGlass::CarWindscreenShatters } if (spawnFlyingComponent && (panelId != WINDSCREEN_PANEL || (panelId == WINDSCREEN_PANEL && !breakGlass))) SpawnFlyingComponent(node, eCarComponentCollisionTypes::COL_NODE_PANEL); - SetComponentVisibility(frame, 0); // ATOMIC_IS_NOT_PRESENT + SetComponentVisibility(frame, 0); // ATOMIC_IS_NOT_PRESENT break; } } diff --git a/Client/game_sa/CAutomobileSA.h b/Client/game_sa/CAutomobileSA.h index 3aa3a6286dd..c6be89310a0 100644 --- a/Client/game_sa/CAutomobileSA.h +++ b/Client/game_sa/CAutomobileSA.h @@ -1,6 +1,6 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: game_sa/CAutomobileSA.h * PURPOSE: Header file for automobile vehicle entity class @@ -16,10 +16,10 @@ #include "CDoorSA.h" #include "CVehicleSA.h" -#define FUNC_CAutomobile_SetTaxiLight 0x6A3740 +#define FUNC_CAutomobile_SetTaxiLight 0x6A3740 -#define MAX_PASSENGER_COUNT 8 -#define MAX_DOORS 6 // also in CDamageManager +#define MAX_PASSENGER_COUNT 8 +#define MAX_DOORS 6 // also in CDamageManager class CBouncingPanelSAInterface { @@ -44,7 +44,7 @@ class CAutomobileSAInterface : public CVehicleSAInterface CObjectSAInterface* SpawnFlyingComponent(const eCarNodes& nodeId, const eCarComponentCollisionTypes& collType) { - return ((CObjectSAInterface*(__thiscall*)(CAutomobileSAInterface*, eCarNodes, eCarComponentCollisionTypes))0x6a8580)(this, nodeId, collType); + return ((CObjectSAInterface * (__thiscall*)(CAutomobileSAInterface*, eCarNodes, eCarComponentCollisionTypes))0x6a8580)(this, nodeId, collType); } CDamageManagerSAInterface m_damageManager; @@ -53,8 +53,8 @@ class CAutomobileSAInterface : public CVehicleSAInterface CBouncingPanelSAInterface m_panels[3]; CDoorSAInterface m_swingingChassis; CColPointSAInterface m_wheelColPoint[MAX_WHEELS]; - float m_wheelsDistancesToGround1[4]; - float m_wheelsDistancesToGround2[4]; + float m_wheelRatios[4]; // suspension compression, 0 = fully compressed, 1 = fully relaxed + float m_prevWheelRatios[4]; float m_wheelCollisionState[4]; float field_800; float field_804; @@ -81,7 +81,7 @@ class CAutomobileSAInterface : public CVehicleSAInterface float m_fCarTraction; float m_fNitroValue; int field_8A4; - int m_fRotationBalance; // used in CHeli::TestSniperCollision + int m_fRotationBalance; // used in CHeli::TestSniperCollision float m_fMoveDirection; int field_8B4[6]; int field_8C8[6]; @@ -123,8 +123,8 @@ class CAutomobileSAInterface : public CVehicleSAInterface float m_fForcedOrientation; float m_fUpDownLightAngle[2]; unsigned char m_nNumContactWheels; - unsigned char m_nWheelsOnGround; - char field_962; + unsigned char m_wheelsOnGround; + unsigned char m_prevWheelsOnGround; char field_963; float field_964; int m_wheelFrictionState[4]; @@ -143,4 +143,7 @@ class CAutomobileSA : public virtual CAutomobile, public virtual CVehicleSA CAutomobileSA(CAutomobileSAInterface* pInterface); CAutomobileSAInterface* GetAutomobileInterface() { return reinterpret_cast(GetInterface()); } + CAutomobileSAInterface* GetAutomobileInterface() const { return reinterpret_cast(GetInterface()); } + + bool IsAnyWheelTouchingGround() const override; }; diff --git a/Client/game_sa/CBikeHandlingEntrySA.cpp b/Client/game_sa/CBikeHandlingEntrySA.cpp index ad5aacff975..68a06af004c 100644 --- a/Client/game_sa/CBikeHandlingEntrySA.cpp +++ b/Client/game_sa/CBikeHandlingEntrySA.cpp @@ -25,7 +25,10 @@ CBikeHandlingEntrySA::CBikeHandlingEntrySA(tBikeHandlingDataSA* pOriginal) void CBikeHandlingEntrySA::Assign(const CBikeHandlingEntry* pData) { - const CBikeHandlingEntrySA* pEntrySA = static_cast(pData); + if (!pData) + return; + + const auto* pEntrySA = static_cast(pData); m_BikeHandling = pEntrySA->m_BikeHandling; } diff --git a/Client/game_sa/CBikeSA.cpp b/Client/game_sa/CBikeSA.cpp index b39eb1d9f11..dd26c142027 100644 --- a/Client/game_sa/CBikeSA.cpp +++ b/Client/game_sa/CBikeSA.cpp @@ -37,3 +37,13 @@ void CBikeSA::RecalculateBikeHandling() if (m_pBikeHandlingData) m_pBikeHandlingData->Recalculate(); } + +bool CBikeSA::IsAnyWheelTouchingGround() const +{ + CBikeSAInterface* bikeInterface = GetBikeInterface(); + if (!bikeInterface) + return false; + + return bikeInterface->m_wheelRatios[0] < 1.0f || bikeInterface->m_wheelRatios[1] < 1.0f || bikeInterface->m_wheelRatios[2] < 1.0f || + bikeInterface->m_wheelRatios[3] < 1.0f; +} diff --git a/Client/game_sa/CBikeSA.h b/Client/game_sa/CBikeSA.h index 8cf4ad282cc..0d372e31761 100644 --- a/Client/game_sa/CBikeSA.h +++ b/Client/game_sa/CBikeSA.h @@ -1,6 +1,6 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: game_sa/CBikeSA.h * PURPOSE: Header file for bike vehicle entity class @@ -47,7 +47,7 @@ class CBikeSAInterface : public CVehicleSAInterface public: RwFrame* m_apModelNodes[static_cast(eBikeNodes::NUM_NODES)]; int8 m_bLeanMatrixCalculated; - int8 pad0[3]; // Maybe prev value is int32 + int8 pad0[3]; // Maybe prev value is int32 int8 m_mLeanMatrix[72]; int8 m_cDamageFlags; int8 pad1[27]; @@ -58,8 +58,8 @@ class CBikeSAInterface : public CVehicleSAInterface int8 field_65E; int8 field_65F; int8 m_anWheelColPoint[176]; - float m_afWheelDistanceToGround[4]; - int32 field_720[4]; + float m_wheelRatios[4]; + float m_prevWheelRatios[4]; int32 field_730[4]; int32 field_740; int32 m_aiWheelSurfaceType[2]; @@ -110,9 +110,11 @@ class CBikeSA : public virtual CBike, public virtual CVehicleSA CBikeSA(CBikeSAInterface* pInterface); CBikeSAInterface* GetBikeInterface() { return reinterpret_cast(GetInterface()); } + CBikeSAInterface* GetBikeInterface() const { return reinterpret_cast(GetInterface()); } CBikeHandlingEntry* GetBikeHandlingData(); void SetBikeHandlingData(CBikeHandlingEntry* pHandling); void RecalculateBikeHandling(); + bool IsAnyWheelTouchingGround() const override; }; diff --git a/Client/game_sa/CBoatHandlingEntrySA.cpp b/Client/game_sa/CBoatHandlingEntrySA.cpp index 7f54a875113..39d378804c3 100644 --- a/Client/game_sa/CBoatHandlingEntrySA.cpp +++ b/Client/game_sa/CBoatHandlingEntrySA.cpp @@ -24,6 +24,9 @@ CBoatHandlingEntrySA::CBoatHandlingEntrySA(tBoatHandlingDataSA* pOriginal) void CBoatHandlingEntrySA::Assign(const CBoatHandlingEntry* pData) { - const CBoatHandlingEntrySA* pEntrySA = static_cast(pData); + if (!pData) + return; + + const auto* pEntrySA = static_cast(pData); m_pBoatHandlingSA = pEntrySA->m_pBoatHandlingSA; } diff --git a/Client/game_sa/CBoatSA.h b/Client/game_sa/CBoatSA.h index d7def954e13..1cfd591755f 100644 --- a/Client/game_sa/CBoatSA.h +++ b/Client/game_sa/CBoatSA.h @@ -35,23 +35,23 @@ enum class eBoatNodes class CBoatSAInterface : public CVehicleSAInterface { public: - uint32 pad1[3]; // 1440 - uint32 BoatFlags; // 1452 - RwFrame* pBoatParts[static_cast(eBoatNodes::NUM_NODES)]; // 1456 - uint32 pad2[3]; // 1500 - uint16 pad3; // 1512 - uint8 pad4[2]; // 1514 - uint32 pad5[3]; // 1516 - tBoatHandlingDataSA* pBoatHandlingData; // 1528 - uint32 pad6[5]; // 1532 - CVector vecUnk1; // 1552 - CVector vecUnk2; // 1564 - class CParticleFx* pBoatPropellerSplashParticle; // 1576 - uint32 pad7[4]; // 1580 - uint8 pad8; // 1596 - uint8 ucPadUsingBoat; // 1597 [[ see class CPad - uint8 pad9[2]; // 1598 - uint32 pad10[106]; // 1600 + uint32 pad1[3]; // 1440 + uint32 BoatFlags; // 1452 + RwFrame* pBoatParts[static_cast(eBoatNodes::NUM_NODES)]; // 1456 + uint32 pad2[3]; // 1500 + uint16 pad3; // 1512 + uint8 pad4[2]; // 1514 + uint32 pad5[3]; // 1516 + tBoatHandlingDataSA* pBoatHandlingData; // 1528 + uint32 pad6[5]; // 1532 + CVector vecUnk1; // 1552 + CVector vecUnk2; // 1564 + class CParticleFx* pBoatPropellerSplashParticle; // 1576 + uint32 pad7[4]; // 1580 + uint8 pad8; // 1596 + uint8 ucPadUsingBoat; // 1597 [[ see class CPad + uint8 pad9[2]; // 1598 + uint32 pad10[106]; // 1600 }; class CBoatSA final : public virtual CBoat, public virtual CVehicleSA diff --git a/Client/game_sa/CBuildingRemovalSA.cpp b/Client/game_sa/CBuildingRemovalSA.cpp index f83c446c843..367b3e98851 100644 --- a/Client/game_sa/CBuildingRemovalSA.cpp +++ b/Client/game_sa/CBuildingRemovalSA.cpp @@ -15,9 +15,67 @@ #include "CWorldSA.h" #include "CGameSA.h" #include "CPoolsSA.h" +#include "HookSystem.h" extern CGameSA* pGame; +// Checks whether pEntity still occupies a live slot in the building, dummy, or object pool. +static bool IsEntityPoolSlotOccupied(CEntitySAInterface* pEntity) +{ + CPoolSAInterface* pBuildingPool = *reinterpret_cast**>(CLASS_CBuildingPool); + if (pBuildingPool) + { + std::int32_t iIndex = pBuildingPool->GetObjectIndexSafe(reinterpret_cast(pEntity)); + if (iIndex != -1) + return pBuildingPool->IsContains(iIndex); + } + + CPoolSAInterface* pDummyPool = *reinterpret_cast**>(CLASS_CDummyPool); + if (pDummyPool) + { + std::int32_t iIndex = pDummyPool->GetObjectIndexSafe(pEntity); + if (iIndex != -1) + return pDummyPool->IsContains(iIndex); + } + + CPoolSAInterface* pObjectPool = *reinterpret_cast**>(CLASS_CObjectPool); + if (pObjectPool) + { + std::int32_t iIndex = pObjectPool->GetObjectIndexSafe(reinterpret_cast(pEntity)); + if (iIndex != -1) + return pObjectPool->IsContains(iIndex); + } + + return false; +} + +static bool IsExpectedRemovalModel(CEntitySAInterface* pEntity, uint16_t usExpectedModel) +{ + if (!pEntity) + return false; + + const int iModelIndex = pEntity->m_nModelIndex; + if (iModelIndex < 0 || iModelIndex > 0xFFFF) + return false; + + return static_cast(iModelIndex) == usExpectedModel; +} + +static void LogStaleTrackedEntity(const char* szContext, CEntitySAInterface* pEntity, const char* szReason, int& iLogCount, bool& bSuppressed) +{ + constexpr int kMaxStaleLogsPerCall = 32; + if (iLogCount < kMaxStaleLogsPerCall) + { + AddReportLog(5562, SString("%s: stale entity 0x%08x skipped (%s)", szContext, pEntity, szReason), 10); + ++iLogCount; + } + else if (!bSuppressed) + { + AddReportLog(5562, SString("%s: additional stale entities suppressed this call", szContext), 10); + bSuppressed = true; + } +} + CBuildingRemovalSA::CBuildingRemovalSA() { m_pBuildingRemovals = new std::multimap; @@ -25,6 +83,16 @@ CBuildingRemovalSA::CBuildingRemovalSA() m_pBinaryBuildings = new std::multimap; } +void CBuildingRemovalSA::ClearEntityTracking(CEntitySAInterface* pInterface) +{ + if (!pInterface) + return; + + const DWORD dwEntityKey = reinterpret_cast(pInterface); + m_pRemovedEntities.erase(dwEntityKey); + m_pAddedEntities.erase(dwEntityKey); +} + void CBuildingRemovalSA::RemoveBuilding(uint16_t usModelToRemove, float fRange, float fX, float fY, float fZ, char cInterior, size_t* pOutAmount) { // New building Removal @@ -41,8 +109,8 @@ void CBuildingRemovalSA::RemoveBuilding(uint16_t usModelToRemove, float fRange, bool bFound = false; uint uiAmount = 0; // Init loop variables - std::pair::iterator, std::multimap::iterator> - iterators = m_pDataBuildings->equal_range(usModelToRemove); + std::pair::iterator, std::multimap::iterator> iterators = + m_pDataBuildings->equal_range(usModelToRemove); std::multimap::const_iterator iter = iterators.first; for (; iter != iterators.second; ++iter) { @@ -83,7 +151,7 @@ void CBuildingRemovalSA::RemoveBuilding(uint16_t usModelToRemove, float fRange, if (!pInterface->IsPlaceableVTBL()) { // Add the Data Building to the list - pRemoval->AddDataBuilding(pInterface); + pRemoval->AddDataBuilding(pInterface, pInterface->m_iplIndex); // Remove the model from the world pGame->GetWorld()->Remove(pInterface, BuildingRemoval2); m_pRemovedEntities[(DWORD)pInterface] = true; @@ -142,7 +210,7 @@ void CBuildingRemovalSA::RemoveBuilding(uint16_t usModelToRemove, float fRange, if (!pInterface->IsPlaceableVTBL()) { // Add the Data Building to the list - pRemoval->AddBinaryBuilding(pInterface); + pRemoval->AddBinaryBuilding(pInterface, pInterface->m_iplIndex); // Remove the model from the world pGame->GetWorld()->Remove(pInterface, BuildingRemoval2); m_pRemovedEntities[(DWORD)pInterface] = true; @@ -170,6 +238,8 @@ bool CBuildingRemovalSA::RestoreBuilding(uint16_t usModelToRestore, float fRange { bool bSuccess = false; uint uiAmount = 0; + int iStaleLogCount = 0; + bool bStaleLogSuppressed = false; // Init some variables std::pair::iterator, std::multimap::iterator> iterators = @@ -192,23 +262,35 @@ bool CBuildingRemovalSA::RestoreBuilding(uint16_t usModelToRestore, float fRange if (fDistance <= pFind->m_fRadius && (cInterior == -1 || pFind->m_cInterior == cInterior)) { // Init some variables - CEntitySAInterface* pEntity = NULL; - std::list::const_iterator entityIter = pFind->m_pBinaryRemoveList->begin(); + CEntitySAInterface* pEntity = NULL; + std::list::const_iterator entityIter = pFind->m_pBinaryRemoveList->begin(); if (pFind->m_pBinaryRemoveList->empty() == false) { // Loop through the Binary object list for (; entityIter != pFind->m_pBinaryRemoveList->end();) { // Grab the pEntity - pEntity = (*entityIter); + pEntity = entityIter->m_pInterface; // if it's valid re-add it to the world. if (pEntity != NULL) { // Remove it from the binary list pFind->m_pBinaryRemoveList->erase(entityIter++); + + // Skip if pool slot was freed or reused with a different model + if (!IsEntityPoolSlotOccupied(pEntity)) + { + LogStaleTrackedEntity("RestoreBuilding", pEntity, "pool slot freed", iStaleLogCount, bStaleLogSuppressed); + ClearEntityTracking(pEntity); + } + else if (!IsExpectedRemovalModel(pEntity, pFind->m_usModel)) + { + LogStaleTrackedEntity("RestoreBuilding", pEntity, "model mismatch", iStaleLogCount, bStaleLogSuppressed); + ClearEntityTracking(pEntity); + } // if the building type is dummy or building and it's not already being removed - if ((pEntity->nType == ENTITY_TYPE_BUILDING || pEntity->nType == ENTITY_TYPE_DUMMY || pEntity->nType == ENTITY_TYPE_OBJECT) && - pEntity->bRemoveFromWorld != 1) + else if ((pEntity->nType == ENTITY_TYPE_BUILDING || pEntity->nType == ENTITY_TYPE_DUMMY || pEntity->nType == ENTITY_TYPE_OBJECT) && + pEntity->bRemoveFromWorld != 1) { // Don't call this on entities being removed. if (!pEntity->IsPlaceableVTBL()) @@ -222,8 +304,9 @@ bool CBuildingRemovalSA::RestoreBuilding(uint16_t usModelToRestore, float fRange } } } - else + else { ++entityIter; +} } } // Start the iterator with the data remove list first item @@ -234,14 +317,26 @@ bool CBuildingRemovalSA::RestoreBuilding(uint16_t usModelToRestore, float fRange for (; entityIter != pFind->m_pDataRemoveList->end();) { // Grab the pEntity - pEntity = (*entityIter); + pEntity = entityIter->m_pInterface; // if it's valid re-add it to the world. if (pEntity != NULL) { pFind->m_pDataRemoveList->erase(entityIter++); + + // Skip if pool slot was freed or reused with a different model + if (!IsEntityPoolSlotOccupied(pEntity)) + { + LogStaleTrackedEntity("RestoreBuilding", pEntity, "pool slot freed", iStaleLogCount, bStaleLogSuppressed); + ClearEntityTracking(pEntity); + } + else if (!IsExpectedRemovalModel(pEntity, pFind->m_usModel)) + { + LogStaleTrackedEntity("RestoreBuilding", pEntity, "model mismatch", iStaleLogCount, bStaleLogSuppressed); + ClearEntityTracking(pEntity); + } // if the building type is dummy or building and it's not already being removed - if ((pEntity->nType == ENTITY_TYPE_BUILDING || pEntity->nType == ENTITY_TYPE_DUMMY || pEntity->nType == ENTITY_TYPE_OBJECT) && - pEntity->bRemoveFromWorld != 1) + else if ((pEntity->nType == ENTITY_TYPE_BUILDING || pEntity->nType == ENTITY_TYPE_DUMMY || pEntity->nType == ENTITY_TYPE_OBJECT) && + pEntity->bRemoveFromWorld != 1) { if (!pEntity->IsPlaceableVTBL()) { @@ -262,14 +357,16 @@ bool CBuildingRemovalSA::RestoreBuilding(uint16_t usModelToRestore, float fRange // Success! don't return incase there are any others to delete bSuccess = true; } - else + else { iter++; +} } - else + else { iter++; +} } std::pair::iterator, std::multimap::iterator> - dataBuildingIterators = m_pDataBuildings->equal_range(usModelToRestore); + dataBuildingIterators = m_pDataBuildings->equal_range(usModelToRestore); std::multimap::const_iterator iterator = dataBuildingIterators.first; for (; iterator != dataBuildingIterators.second; ++iterator) { @@ -300,8 +397,8 @@ bool CBuildingRemovalSA::RestoreBuilding(uint16_t usModelToRestore, float fRange } } - std::pair::iterator, std::multimap::iterator> - binaryBuildingIterators = m_pBinaryBuildings->equal_range(usModelToRestore); + std::pair::iterator, std::multimap::iterator> binaryBuildingIterators = + m_pBinaryBuildings->equal_range(usModelToRestore); std::multimap::const_iterator iteratorBinary = binaryBuildingIterators.first; for (; iteratorBinary != binaryBuildingIterators.second; ++iteratorBinary) { @@ -342,9 +439,15 @@ bool CBuildingRemovalSA::RestoreBuilding(uint16_t usModelToRestore, float fRange bool CBuildingRemovalSA::IsRemovedModelInRadius(SIPLInst* pInst) { // Init some variables + const int modelIndex = pInst->m_nModelIndex; + if (modelIndex < 0 || modelIndex > 0xFFFF) + return false; + + const uint16_t usModelIndex = static_cast(modelIndex); std::pair::iterator, std::multimap::iterator> iterators = - m_pBuildingRemovals->equal_range(pInst->m_nModelIndex); + m_pBuildingRemovals->equal_range(usModelIndex); std::multimap::const_iterator iter = iterators.first; + // Loop through the buildings list for (; iter != iterators.second; ++iter) { @@ -372,8 +475,13 @@ bool CBuildingRemovalSA::IsRemovedModelInRadius(SIPLInst* pInst) bool CBuildingRemovalSA::IsObjectRemoved(CEntitySAInterface* pInterface) { // Init some variables + const int modelIndex = pInterface->m_nModelIndex; + if (modelIndex < 0 || modelIndex > 0xFFFF) + return false; + + const uint16_t usModelIndex = static_cast(modelIndex); std::pair::iterator, std::multimap::iterator> iterators = - m_pBuildingRemovals->equal_range(pInterface->m_nModelIndex); + m_pBuildingRemovals->equal_range(usModelIndex); std::multimap::const_iterator iter = iterators.first; // Loop through the buildings list for (; iter != iterators.second; ++iter) @@ -431,7 +539,9 @@ bool CBuildingRemovalSA::IsEntityRemoved(CEntitySAInterface* pInterface) void CBuildingRemovalSA::ClearRemovedBuildingLists(uint* pOutAmount) { // Ensure no memory leaks by deleting items. - uint uiAmount = 0; + uint uiAmount = 0; + int iStaleLogCount = 0; + bool bStaleLogSuppressed = false; std::multimap::const_iterator iter = m_pBuildingRemovals->begin(); for (; iter != m_pBuildingRemovals->end();) @@ -440,21 +550,32 @@ void CBuildingRemovalSA::ClearRemovedBuildingLists(uint* pOutAmount) if (pFind) { // Init some variables - CEntitySAInterface* pEntity = NULL; - std::list::const_iterator entityIter = pFind->m_pBinaryRemoveList->begin(); + CEntitySAInterface* pEntity = NULL; + std::list::const_iterator entityIter = pFind->m_pBinaryRemoveList->begin(); if (pFind->m_pBinaryRemoveList->empty() == false) { // Loop through the Binary remove list for (; entityIter != pFind->m_pBinaryRemoveList->end(); ++entityIter) { // Grab the pEntity - pEntity = (*entityIter); + pEntity = entityIter->m_pInterface; // if it's valid re-add it to the world. if (pEntity && pEntity != NULL) { + // Skip if pool slot was freed or reused with a different model + if (!IsEntityPoolSlotOccupied(pEntity)) + { + ClearEntityTracking(pEntity); + LogStaleTrackedEntity("ClearRemovedBuildingLists", pEntity, "pool slot freed", iStaleLogCount, bStaleLogSuppressed); + } + else if (!IsExpectedRemovalModel(pEntity, pFind->m_usModel)) + { + ClearEntityTracking(pEntity); + LogStaleTrackedEntity("ClearRemovedBuildingLists", pEntity, "model mismatch", iStaleLogCount, bStaleLogSuppressed); + } // if the building type is dummy or building and it's not already being removed - if ((pEntity->nType == ENTITY_TYPE_BUILDING || pEntity->nType == ENTITY_TYPE_DUMMY || pEntity->nType == ENTITY_TYPE_OBJECT) && - pEntity->bRemoveFromWorld != 1) + else if ((pEntity->nType == ENTITY_TYPE_BUILDING || pEntity->nType == ENTITY_TYPE_DUMMY || pEntity->nType == ENTITY_TYPE_OBJECT) && + pEntity->bRemoveFromWorld != 1) { // Don't call this on entities being removed. if (!pEntity->IsPlaceableVTBL()) @@ -474,13 +595,24 @@ void CBuildingRemovalSA::ClearRemovedBuildingLists(uint* pOutAmount) for (; entityIter != pFind->m_pDataRemoveList->end(); ++entityIter) { // Grab the pEntity - pEntity = (*entityIter); + pEntity = entityIter->m_pInterface; // if it's valid re-add it to the world. if (pEntity && pEntity != NULL) { + // Skip if pool slot was freed or reused with a different model + if (!IsEntityPoolSlotOccupied(pEntity)) + { + ClearEntityTracking(pEntity); + LogStaleTrackedEntity("ClearRemovedBuildingLists", pEntity, "pool slot freed", iStaleLogCount, bStaleLogSuppressed); + } + else if (!IsExpectedRemovalModel(pEntity, pFind->m_usModel)) + { + ClearEntityTracking(pEntity); + LogStaleTrackedEntity("ClearRemovedBuildingLists", pEntity, "model mismatch", iStaleLogCount, bStaleLogSuppressed); + } // if the building type is dummy or building and it's not already being removed - if ((pEntity->nType == ENTITY_TYPE_BUILDING || pEntity->nType == ENTITY_TYPE_DUMMY || pEntity->nType == ENTITY_TYPE_OBJECT) && - pEntity->bRemoveFromWorld != 1) + else if ((pEntity->nType == ENTITY_TYPE_BUILDING || pEntity->nType == ENTITY_TYPE_DUMMY || pEntity->nType == ENTITY_TYPE_OBJECT) && + pEntity->bRemoveFromWorld != 1) { // Don't call this on entities being removed. if (!pEntity->IsPlaceableVTBL()) @@ -493,9 +625,11 @@ void CBuildingRemovalSA::ClearRemovedBuildingLists(uint* pOutAmount) } } m_pBuildingRemovals->erase(iter++); + delete pFind; } - else + else { iter++; +} } // Init some variables std::multimap::const_iterator iterator = m_pDataBuildings->begin(); @@ -526,6 +660,7 @@ void CBuildingRemovalSA::ClearRemovedBuildingLists(uint* pOutAmount) // Create new m_pBuildingRemovals = new std::multimap; m_pRemovedEntities.clear(); + m_pAddedEntities.clear(); if (pOutAmount) *pOutAmount = uiAmount; @@ -535,8 +670,13 @@ void CBuildingRemovalSA::ClearRemovedBuildingLists(uint* pOutAmount) SBuildingRemoval* CBuildingRemovalSA::GetBuildingRemoval(CEntitySAInterface* pInterface) { // Init some variables + const int modelIndex = pInterface->m_nModelIndex; + if (modelIndex < 0 || modelIndex > 0xFFFF) + return NULL; + + const uint16_t usModelIndex = static_cast(modelIndex); std::pair::iterator, std::multimap::iterator> iterators = - m_pBuildingRemovals->equal_range(pInterface->m_nModelIndex); + m_pBuildingRemovals->equal_range(usModelIndex); std::multimap::const_iterator iter = iterators.first; // Loop through the buildings list for (; iter != iterators.second; ++iter) @@ -565,17 +705,23 @@ SBuildingRemoval* CBuildingRemovalSA::GetBuildingRemoval(CEntitySAInterface* pIn } } } - return NULL; + return nullptr; } void CBuildingRemovalSA::AddDataBuilding(CEntitySAInterface* pInterface) { + const int modelIndex = pInterface->m_nModelIndex; + if (modelIndex < 0 || modelIndex > 0xFFFF) + return; + + const uint16_t usModelIndex = static_cast(modelIndex); if (m_pAddedEntities.find((DWORD)pInterface) == m_pAddedEntities.end() || m_pAddedEntities[(DWORD)pInterface] == false) { // Create a new building removal sDataBuildingRemovalItem* pBuildingRemoval = new sDataBuildingRemovalItem(pInterface, true); + pBuildingRemoval->m_iplIndex = pInterface->m_iplIndex; // CEntitySAInterface is forward-decl in the SDK header; m_iplIndex only accessible here // Insert it with the model index so we can fast lookup - m_pDataBuildings->insert(std::pair((uint16_t)pInterface->m_nModelIndex, pBuildingRemoval)); + m_pDataBuildings->insert(std::pair(usModelIndex, pBuildingRemoval)); m_pAddedEntities[(DWORD)pInterface] = true; m_pRemovedEntities[(DWORD)pInterface] = false; } @@ -583,12 +729,18 @@ void CBuildingRemovalSA::AddDataBuilding(CEntitySAInterface* pInterface) void CBuildingRemovalSA::AddBinaryBuilding(CEntitySAInterface* pInterface) { + const int modelIndex = pInterface->m_nModelIndex; + if (modelIndex < 0 || modelIndex > 0xFFFF) + return; + + const uint16_t usModelIndex = static_cast(modelIndex); if (m_pAddedEntities.find((DWORD)pInterface) == m_pAddedEntities.end() || m_pAddedEntities[(DWORD)pInterface] == false) { // Create a new building removal sBuildingRemovalItem* pBuildingRemoval = new sBuildingRemovalItem(pInterface, false); + pBuildingRemoval->m_iplIndex = pInterface->m_iplIndex; // CEntitySAInterface is forward-decl in the SDK header; m_iplIndex only accessible here // Insert it with the model index so we can fast lookup - m_pBinaryBuildings->insert(std::pair((uint16_t)pInterface->m_nModelIndex, pBuildingRemoval)); + m_pBinaryBuildings->insert(std::pair(usModelIndex, pBuildingRemoval)); m_pAddedEntities[(DWORD)pInterface] = true; m_pRemovedEntities[(DWORD)pInterface] = false; } @@ -596,8 +748,13 @@ void CBuildingRemovalSA::AddBinaryBuilding(CEntitySAInterface* pInterface) void CBuildingRemovalSA::RemoveWorldBuildingFromLists(CEntitySAInterface* pInterface) { + const int modelIndex = pInterface->m_nModelIndex; + if (modelIndex < 0 || modelIndex > 0xFFFF) + return; + + const uint16_t usModelIndex = static_cast(modelIndex); std::pair::iterator, std::multimap::iterator> iterators = - m_pBuildingRemovals->equal_range(pInterface->m_nModelIndex); + m_pBuildingRemovals->equal_range(usModelIndex); std::multimap::const_iterator iter = iterators.first; // Loop through the buildings list @@ -612,45 +769,47 @@ void CBuildingRemovalSA::RemoveWorldBuildingFromLists(CEntitySAInterface* pInter if (pFind->m_pBinaryRemoveList->empty() == false) { // grab the beginning - std::list::const_iterator entityIter = pFind->m_pBinaryRemoveList->begin(); + std::list::const_iterator entityIter = pFind->m_pBinaryRemoveList->begin(); // Loop through the binary remove list for (; entityIter != pFind->m_pBinaryRemoveList->end();) { - pEntity = (*entityIter); + pEntity = entityIter->m_pInterface; // is the pointer the same as the one being deleted if ((DWORD)pEntity == (DWORD)pInterface) { // remove it from the binary removed list for this removal pFind->m_pBinaryRemoveList->erase(entityIter++); } - else + else { entityIter++; +} } } if (pFind->m_pDataRemoveList->empty() == false) { - std::list::const_iterator entityIter = pFind->m_pDataRemoveList->begin(); + std::list::const_iterator entityIter = pFind->m_pDataRemoveList->begin(); // Loop through the Data list for (; entityIter != pFind->m_pDataRemoveList->end();) { // Grab the pEntity - pEntity = (*entityIter); + pEntity = entityIter->m_pInterface; // is the pointer the same as the one being deleted if ((DWORD)pEntity == (DWORD)pInterface) { // remove it from the data removed list for this removal pFind->m_pDataRemoveList->erase(entityIter++); } - else + else { entityIter++; +} } } } } { // Init some variables - std::pair::iterator, std::multimap::iterator> - dataIterators = m_pDataBuildings->equal_range(pInterface->m_nModelIndex); + std::pair::iterator, std::multimap::iterator> dataIterators = + m_pDataBuildings->equal_range(usModelIndex); std::multimap::const_iterator iterator = dataIterators.first; for (; iterator != dataIterators.second;) { @@ -664,17 +823,19 @@ void CBuildingRemovalSA::RemoveWorldBuildingFromLists(CEntitySAInterface* pInter // remove it from the data buildings list so we don't try and remove or add it again. m_pDataBuildings->erase(iterator++); } - else + else { iterator++; +} } - else + else { iterator++; +} } } { // Init some variables - std::pair::iterator, std::multimap::iterator> - binaryIterators = m_pBinaryBuildings->equal_range(pInterface->m_nModelIndex); + std::pair::iterator, std::multimap::iterator> binaryIterators = + m_pBinaryBuildings->equal_range(usModelIndex); std::multimap::const_iterator iteratorBinary = binaryIterators.first; for (; iteratorBinary != binaryIterators.second;) { @@ -688,15 +849,16 @@ void CBuildingRemovalSA::RemoveWorldBuildingFromLists(CEntitySAInterface* pInter // remove it from the data buildings list so we don't try and remove or add it again. m_pBinaryBuildings->erase(iteratorBinary++); } - else + else { iteratorBinary++; +} } - else + else { iteratorBinary++; +} } } - m_pRemovedEntities[(DWORD)pInterface] = false; - m_pAddedEntities[(DWORD)pInterface] = false; + ClearEntityTracking(pInterface); } void CBuildingRemovalSA::DropCaches() @@ -717,9 +879,227 @@ void CBuildingRemovalSA::DropCaches() m_pBinaryBuildings->clear(); m_pDataBuildings->clear(); - for (auto &pRemoval : *m_pBuildingRemovals) + for (auto& pRemoval : *m_pBuildingRemovals) { pRemoval.second->m_pDataRemoveList->clear(); pRemoval.second->m_pBinaryRemoveList->clear(); } } + +void CBuildingRemovalSA::OnRemoveIpl(int iplSlotIndex) +{ + // m_iplIndex is a BYTE, so only slots 0-255 can be matched by IPL index. + const bool canMatchByIpl = (iplSlotIndex >= 0 && iplSlotIndex <= 255); + const BYTE iplIndex = canMatchByIpl ? static_cast(iplSlotIndex) : 0; + + // Purge matching entity pointers from all SBuildingRemoval tracked lists + for (auto& entry : *m_pBuildingRemovals) + { + SBuildingRemoval* pRemoval = entry.second; + if (!pRemoval) + continue; + + for (auto it = pRemoval->m_pBinaryRemoveList->begin(); it != pRemoval->m_pBinaryRemoveList->end();) + { + CEntitySAInterface* pEntity = it->m_pInterface; + if (!pEntity) + { + ++it; + continue; + } + + // m_iplIndex was cached when the entity was first tracked. + // Skip pool-slot and model checks for entries from a different IPL. + if (canMatchByIpl && it->m_iplIndex != iplIndex) + { + ++it; + continue; + } + + bool bPoolSlotOccupied = IsEntityPoolSlotOccupied(pEntity); + bool bMatchesIpl = false; + if (bPoolSlotOccupied) + { + if (!IsExpectedRemovalModel(pEntity, pRemoval->m_usModel)) + bPoolSlotOccupied = false; + else + bMatchesIpl = canMatchByIpl && pEntity->m_iplIndex == iplIndex; + } + + if (!bPoolSlotOccupied || bMatchesIpl) + { + ClearEntityTracking(pEntity); + it = pRemoval->m_pBinaryRemoveList->erase(it); + } + else + ++it; + } + + for (auto it = pRemoval->m_pDataRemoveList->begin(); it != pRemoval->m_pDataRemoveList->end();) + { + CEntitySAInterface* pEntity = it->m_pInterface; + if (!pEntity) + { + ++it; + continue; + } + + // Same m_iplIndex early-out as the binary list loop above. + if (canMatchByIpl && it->m_iplIndex != iplIndex) + { + ++it; + continue; + } + + bool bPoolSlotOccupied = IsEntityPoolSlotOccupied(pEntity); + bool bMatchesIpl = false; + if (bPoolSlotOccupied) + { + if (!IsExpectedRemovalModel(pEntity, pRemoval->m_usModel)) + bPoolSlotOccupied = false; + else + bMatchesIpl = canMatchByIpl && pEntity->m_iplIndex == iplIndex; + } + + if (!bPoolSlotOccupied || bMatchesIpl) + { + ClearEntityTracking(pEntity); + it = pRemoval->m_pDataRemoveList->erase(it); + } + else + ++it; + } + } + + // Purge matching entries from the data buildings catalog + for (auto it = m_pDataBuildings->begin(); it != m_pDataBuildings->end();) + { + sDataBuildingRemovalItem* pItem = it->second; + CEntitySAInterface* pEntity = pItem ? pItem->m_pInterface : nullptr; + if (!pEntity) + { + ++it; + continue; + } + + // m_iplIndex was cached when the entity was first tracked (entity was live at that + // point). Skip pool-slot and model checks for entries from a different IPL; those + // entities remain in the world and are visited when their own IPL unloads. + if (canMatchByIpl && pItem->m_iplIndex != iplIndex) + { + ++it; + continue; + } + + bool bPoolSlotOccupied = IsEntityPoolSlotOccupied(pEntity); + bool bMatchesIpl = false; + if (bPoolSlotOccupied) + { + if (!IsExpectedRemovalModel(pEntity, it->first)) { + bPoolSlotOccupied = false; + } else { + bMatchesIpl = canMatchByIpl && pEntity->m_iplIndex == iplIndex; +} + } + + if (!bPoolSlotOccupied || bMatchesIpl) + { + ClearEntityTracking(pEntity); + delete pItem; + it = m_pDataBuildings->erase(it); + } + else { + ++it; +} + } + + // Purge matching entries from the binary buildings catalog + for (auto it = m_pBinaryBuildings->begin(); it != m_pBinaryBuildings->end();) + { + sBuildingRemovalItem* pItem = it->second; + CEntitySAInterface* pEntity = pItem ? pItem->m_pInterface : nullptr; + if (!pEntity) + { + ++it; + continue; + } + + // Same m_iplIndex early-out as the data buildings loop above. + if (canMatchByIpl && pItem->m_iplIndex != iplIndex) + { + ++it; + continue; + } + + bool bPoolSlotOccupied = IsEntityPoolSlotOccupied(pEntity); + bool bMatchesIpl = false; + if (bPoolSlotOccupied) + { + if (!IsExpectedRemovalModel(pEntity, it->first)) { + bPoolSlotOccupied = false; + } else { + bMatchesIpl = canMatchByIpl && pEntity->m_iplIndex == iplIndex; +} + } + + if (!bPoolSlotOccupied || bMatchesIpl) + { + ClearEntityTracking(pEntity); + delete pItem; + it = m_pBinaryBuildings->erase(it); + } + else { + ++it; +} + } +} + +// Pre-hook for CIplStore::RemoveIpl (0x404B20). +// When GTA streams out an IPL sector, it frees all entity pool slots in that sector. +// We hook in before that happens to purge tracked pointers that are about to become stale. + +#define HOOKPOS_CIplStore_RemoveIpl 0x404B20 +#define HOOKSIZE_CIplStore_RemoveIpl 5 +static DWORD RETURN_CIplStore_RemoveIpl = 0x404B25; + +#define VAR_CIplStore_msPool 0x8E3FB0 + +static void __cdecl OnIplRemovePre(int iplSlotIndex) +{ + if (!pGame) + return; + + auto* pBuildingRemoval = static_cast(pGame->GetBuildingRemoval()); + if (pBuildingRemoval) + pBuildingRemoval->OnRemoveIpl(iplSlotIndex); +} + +static void __declspec(naked) HOOK_CIplStore_RemoveIpl() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + pushad + push [esp+32+4] // iplSlotIndex (past 8 pushad regs + return address) + call OnIplRemovePre + add esp, 4 + popad + + // Overwritten instruction: mov eax, ds:[CIplStore::ms_pPool] + mov eax, ds:[VAR_CIplStore_msPool] + jmp RETURN_CIplStore_RemoveIpl + } + // clang-format on +} + +void CBuildingRemovalSA::StaticSetHooks() +{ + static bool bHooksInstalled = false; + if (bHooksInstalled) + return; + + EZHookInstall(CIplStore_RemoveIpl); + bHooksInstalled = true; +} diff --git a/Client/game_sa/CBuildingRemovalSA.h b/Client/game_sa/CBuildingRemovalSA.h index 9796f0b38bf..c11fe8f208b 100644 --- a/Client/game_sa/CBuildingRemovalSA.h +++ b/Client/game_sa/CBuildingRemovalSA.h @@ -34,12 +34,20 @@ class CBuildingRemovalSA : public CBuildingRemoval bool IsObjectRemoved(CEntitySAInterface* pInterface) override; bool IsDataModelRemoved(uint16_t usModelID) override; bool IsEntityRemoved(CEntitySAInterface* pInterface) override; - void DropCaches(); + void DropCaches(); + + // Called from the CIplStore::RemoveIpl hook before GTA frees the entities. + // Purges tracked pointers belonging to the given IPL slot. + void OnRemoveIpl(int iplSlotIndex); + + static void StaticSetHooks(); private: - std::multimap* m_pBuildingRemovals; - std::multimap* m_pDataBuildings; - std::multimap* m_pBinaryBuildings; - std::map m_pRemovedEntities; - std::map m_pAddedEntities; + void ClearEntityTracking(CEntitySAInterface* pInterface); + + std::multimap* m_pBuildingRemovals; + std::multimap* m_pDataBuildings; + std::multimap* m_pBinaryBuildings; + std::map m_pRemovedEntities; + std::map m_pAddedEntities; }; diff --git a/Client/game_sa/CBuildingsPoolSA.cpp b/Client/game_sa/CBuildingsPoolSA.cpp index c3d4216ca81..0521dcba6d1 100644 --- a/Client/game_sa/CBuildingsPoolSA.cpp +++ b/Client/game_sa/CBuildingsPoolSA.cpp @@ -18,8 +18,11 @@ #include "CPtrNodeSingleListSA.h" #include "MemSA.h" #include "CVehicleSA.h" +#include "CObjectSA.h" #include "CBuildingRemovalSA.h" #include "CPlayerPedSA.h" +#include "CPoolsSA.h" +#include "CWorldSA.h" extern CGameSA* pGame; @@ -38,11 +41,11 @@ inline bool CBuildingsPoolSA::AddBuildingToPool(CClientBuilding* pClientBuilding if (!pInterface) return false; - uint32_t dwElementIndexInPool = (*m_ppBuildingPoolInterface)->GetObjectIndexSafe(pInterface); - if (dwElementIndexInPool == UINT_MAX) + std::int32_t iElementIndexInPool = (*m_ppBuildingPoolInterface)->GetObjectIndexSafe(pInterface); + if (iElementIndexInPool == -1) return false; - m_buildingPool.entities[dwElementIndexInPool] = {pBuilding, (CClientEntity*)pClientBuilding}; + m_buildingPool.entities[static_cast(iElementIndexInPool)] = {pBuilding, (CClientEntity*)pClientBuilding}; // Increase the count of objects ++m_buildingPool.count; @@ -52,12 +55,12 @@ inline bool CBuildingsPoolSA::AddBuildingToPool(CClientBuilding* pClientBuilding CClientEntity* CBuildingsPoolSA::GetClientBuilding(CBuildingSAInterface* pGameInterface) const noexcept { - std::uint32_t poolIndex = (*m_ppBuildingPoolInterface)->GetObjectIndexSafe(pGameInterface); + std::int32_t poolIndex = (*m_ppBuildingPoolInterface)->GetObjectIndexSafe(pGameInterface); - if (poolIndex == static_cast(-1)) + if (poolIndex == -1) return nullptr; - return m_buildingPool.entities[poolIndex].pClientEntity; + return m_buildingPool.entities[static_cast(poolIndex)].pClientEntity; } CBuilding* CBuildingsPoolSA::AddBuilding(CClientBuilding* pClientBuilding, uint16_t modelId, CVector* vPos, CVector* vRot, uint8_t interior) @@ -126,12 +129,12 @@ void CBuildingsPoolSA::RemoveBuilding(CBuilding* pBuilding) CBuildingSAInterface* pInterface = pBuilding->GetBuildingInterface(); - uint32_t dwElementIndexInPool = (*m_ppBuildingPoolInterface)->GetObjectIndexSafe(pInterface); - if (dwElementIndexInPool == UINT_MAX) + std::int32_t iElementIndexInPool = (*m_ppBuildingPoolInterface)->GetObjectIndexSafe(pInterface); + if (iElementIndexInPool == -1) return; // Remove references to allocated matrix - auto* pBuildingSA = m_buildingPool.entities[dwElementIndexInPool].pEntity; + auto* pBuildingSA = m_buildingPool.entities[static_cast(iElementIndexInPool)].pEntity; pBuildingSA->RemoveAllocatedMatrix(); // Remove building from cover list @@ -156,10 +159,10 @@ void CBuildingsPoolSA::RemoveBuilding(CBuilding* pBuilding) modelInfo->RemoveColRef(); // Remove building from SA pool - (*m_ppBuildingPoolInterface)->Release(dwElementIndexInPool); + (*m_ppBuildingPoolInterface)->Release(static_cast(iElementIndexInPool)); // Remove from BuildingSA pool - m_buildingPool.entities[dwElementIndexInPool] = {nullptr, nullptr}; + m_buildingPool.entities[static_cast(iElementIndexInPool)] = {nullptr, nullptr}; // Delete it from memory delete pBuildingSA; @@ -173,10 +176,21 @@ void CBuildingsPoolSA::RemoveAllWithBackup() if (m_pOriginalBuildingsBackup) return; - m_pOriginalBuildingsBackup = std::make_unique(); + auto pBuildsingsPool = (*m_ppBuildingPoolInterface); + const size_t poolSize = static_cast(pBuildsingsPool->m_nSize); - auto pBuildsingsPool = (*m_ppBuildingPoolInterface); - for (size_t i = 0; i < MAX_BUILDINGS; i++) + m_pOriginalBuildingsBackup = std::make_unique(poolSize); + + // Clear ped/vehicle entity pointers that may reference buildings about to be freed. + // Without this, fields like CPed::pContactEntity can become dangling after pool slots + // are released, causing crashes in SA code that reads m_nModelIndex from them + // (e.g. CEventScanner::ScanForEvents). Mirrors the cleanup already done in Resize(). + RemoveVehicleDamageLinks(); + RemovePedsContactEnityLinks(); + RemoveObjectEntityLinks(); + m_bLinkSweepsDone = true; + + for (size_t i = 0; i < poolSize; i++) { if (pBuildsingsPool->IsContains(i)) { @@ -207,9 +221,10 @@ void CBuildingsPoolSA::RestoreBackup() auto* worldSA = pGame->GetWorld(); auto* buildingRemovealSA = static_cast(pGame->GetBuildingRemoval()); - auto& originalData = *m_pOriginalBuildingsBackup; - auto pBuildsingsPool = (*m_ppBuildingPoolInterface); - for (size_t i = 0; i < MAX_BUILDINGS; i++) + auto& originalData = *m_pOriginalBuildingsBackup; + auto pBuildsingsPool = (*m_ppBuildingPoolInterface); + const size_t restoreCount = std::min(originalData.size(), static_cast(pBuildsingsPool->m_nSize)); + for (size_t i = 0; i < restoreCount; i++) { if (originalData[i].first) { @@ -231,15 +246,65 @@ void CBuildingsPoolSA::RemoveBuildingFromWorld(CBuildingSAInterface* pBuilding) pBuilding->RemoveRWObjectWithReferencesCleanup(); } +void CBuildingsPoolSA::PurgeStaleSectorEntries(void* oldPool, int poolSize) +{ + if (!oldPool || poolSize <= 0) + return; + + const auto poolStart = reinterpret_cast(oldPool); + const auto poolEnd = poolStart + static_cast(poolSize) * sizeof(CBuildingSAInterface); + + // ARRAY_StreamSectors is a flat array of CSector[120][120]. + // Each CSector is { CPtrListSingleLink m_buildings; CPtrListDoubleLink m_dummies } = 2 DWORDs. + // We only scan m_buildings (even-indexed DWORDs). + auto* sectorDwords = reinterpret_cast(ARRAY_StreamSectors); + constexpr int kSectorCount = NUM_StreamSectorRows * NUM_StreamSectorCols; + + for (int i = 0; i < kSectorCount; ++i) + { + // A stale entry can only exist in a sector that has nodes; null head means empty list. + if (sectorDwords[i * 2] == 0) + continue; + + auto* pList = reinterpret_cast*>(§orDwords[i * 2]); + auto* pNode = reinterpret_cast*>(sectorDwords[i * 2]); + + while (pNode) + { + // Pre-cache next before RemoveItem, which frees the current node. + auto* pNext = pNode->pNext; + auto entityAddr = reinterpret_cast(pNode->pItem); + + if (entityAddr >= poolStart && entityAddr < poolEnd) + pList->RemoveItem(pNode->pItem); + + pNode = pNext; + } + } +} + bool CBuildingsPoolSA::Resize(int size) { auto* pool = (*m_ppBuildingPoolInterface); const int currentSize = pool->m_nSize; + // Clear before the malloc calls so the rollback Resize(currentSize), called on + // allocation failure below, always runs the link sweeps regardless of whether + // RemoveAllWithBackup had set this flag before the outer call. + const bool skipLinkSweeps = m_bLinkSweepsDone; + m_bLinkSweepsDone = false; + m_buildingPool.entities.resize(size); void* oldPool = pool->m_pObjects; + // Safety scan: remove any sector building list nodes still referencing the + // old pool.. RemoveAllWithBackup should have removed them all via CWorld::Remove, + // but that call relies on GetBoundRect that can miss entities whose collision + // model is unloaded. Leaving stale nodes causes a crash in DeleteAllRwObjects. + if (oldPool != nullptr) + PurgeStaleSectorEntries(oldPool, currentSize); + if (oldPool != nullptr) { MemSA::free(pool->m_pObjects); @@ -290,8 +355,14 @@ bool CBuildingsPoolSA::Resize(int size) pGame->GetPools()->GetDummyPool().UpdateBuildingLods(offset); - RemoveVehicleDamageLinks(); - RemovePedsContactEnityLinks(); + // RemoveAllWithBackup already ran these in the same remove/resize cycle; skip them. + // Run when Resize is called directly without a prior backup (e.g. pool size change). + if (!skipLinkSweeps) + { + RemoveVehicleDamageLinks(); + RemovePedsContactEnityLinks(); + RemoveObjectEntityLinks(); + } return true; } @@ -311,9 +382,11 @@ void CBuildingsPoolSA::UpdateIplEntrysPointers(uint32_t offset) return; } size_t arraySize = MemSA::msize(*ppArray) / sizeof(CBuildingSAInterface*); - for (auto j = 0; j < arraySize; j++) + for (size_t j = 0; j < arraySize; j++) { CBuildingSAInterface* object = (*ppArray)[j]; + if (object == nullptr) + continue; (*ppArray)[j] = (CBuildingSAInterface*)((uint32_t)object + offset); } @@ -322,13 +395,13 @@ void CBuildingsPoolSA::UpdateIplEntrysPointers(uint32_t offset) void CBuildingsPoolSA::UpdateBackupLodPointers(uint32_t offset) { - backup_array_t* arr = m_pOriginalBuildingsBackup.get(); - for (auto i = 0; i < MAX_BUILDINGS; i++) + auto& arr = *m_pOriginalBuildingsBackup; + for (size_t i = 0; i < arr.size(); ++i) { - std::pair* data = &(*arr)[i]; - if (data->first) + auto& data = arr[i]; + if (data.first) { - CBuildingSAInterface* building = reinterpret_cast(&data->second); + CBuildingSAInterface* building = reinterpret_cast(&data.second); if (building->m_pLod != nullptr) { building->m_pLod = (CBuildingSAInterface*)((uint32_t)building->m_pLod + offset); @@ -339,44 +412,85 @@ void CBuildingsPoolSA::UpdateBackupLodPointers(uint32_t offset) void CBuildingsPoolSA::RemoveVehicleDamageLinks() { - const int count = pGame->GetPools()->GetVehicleCount(); - for (int i = 0; i < count; i++) + auto* pVehiclePool = *reinterpret_cast**>(CLASS_CVehiclePool); + if (!pVehiclePool) + return; + + // GTA SA vehicle pool slot stride (2584) differs from sizeof(CVehicleSAInterface) (1440) + // because the pool accommodates CAutomobile and other derived vehicle types. + constexpr std::uint32_t vehicleStride = 2584; + auto* pPoolBase = reinterpret_cast(pVehiclePool->m_pObjects); + + for (int i = 0; i < pVehiclePool->m_nSize; i++) { - auto* vehLinks = pGame->GetPools()->GetVehicle(i); - if (vehLinks->pEntity) - { - CVehicleSAInterface* vehicle = vehLinks->pEntity->GetVehicleInterface(); - vehicle->m_pCollidedEntity = nullptr; - vehicle->pLastContactedEntity[0] = nullptr; - vehicle->pLastContactedEntity[1] = nullptr; - vehicle->pLastContactedEntity[2] = nullptr; - vehicle->pLastContactedEntity[3] = nullptr; - vehicle->m_ucCollisionState = 0; - } + if (pVehiclePool->IsEmpty(i)) + continue; + + auto* vehicle = reinterpret_cast(pPoolBase + i * vehicleStride); + vehicle->m_pCollidedEntity = nullptr; + vehicle->pLastContactedEntity[0] = nullptr; + vehicle->pLastContactedEntity[1] = nullptr; + vehicle->pLastContactedEntity[2] = nullptr; + vehicle->pLastContactedEntity[3] = nullptr; + vehicle->m_ucCollisionState = 0; } } void CBuildingsPoolSA::RemovePedsContactEnityLinks() { - const int count = pGame->GetPools()->GetPedCount(); - for (int i = 0; i < count; i++) + auto* pPedPool = *reinterpret_cast**>(CLASS_CPedPool); + if (!pPedPool) + return; + + // GTA SA ped pool slot stride (1988) differs from sizeof(CPedSAInterface) (1948) + // because the pool accommodates CPlayerPed and related derived types. + constexpr std::uint32_t pedStride = 1988; + auto* pPoolBase = reinterpret_cast(pPedPool->m_pObjects); + + for (int i = 0; i < pPedPool->m_nSize; i++) + { + if (pPedPool->IsEmpty(i)) + continue; + + auto* ped = reinterpret_cast(pPoolBase + i * pedStride); + ped->m_pCollidedEntity = nullptr; + ped->pContactEntity = nullptr; + ped->pLastContactEntity = nullptr; + ped->pLastContactedEntity[0] = nullptr; + ped->pLastContactedEntity[1] = nullptr; + ped->pLastContactedEntity[2] = nullptr; + ped->pLastContactedEntity[3] = nullptr; + ped->m_ucCollisionState = 0; + } + + // Clear local player's targeted entity (player ped is always at pool index 0) + if (pPedPool->IsContains(0)) + reinterpret_cast(pPoolBase)->mouseTargetEntity = nullptr; +} + +void CBuildingsPoolSA::RemoveObjectEntityLinks() +{ + auto* pObjectPool = *reinterpret_cast**>(CLASS_CObjectPool); + if (!pObjectPool) + return; + + // GTA SA object pool slot stride (412) differs from sizeof(CObjectSAInterface) (380) + // because pool slots include alignment padding beyond the struct size. + constexpr std::uint32_t objectStride = 412; + auto* pPoolBase = reinterpret_cast(pObjectPool->m_pObjects); + + for (int i = 0; i < pObjectPool->m_nSize; i++) { - auto* pedLinks = pGame->GetPools()->GetPed(i); - if (pedLinks->pEntity) - { - CPedSAInterface* ped = pedLinks->pEntity->GetPedInterface(); - ped->m_pCollidedEntity = nullptr; - ped->pContactEntity = nullptr; - ped->pLastContactEntity = nullptr; - ped->pLastContactedEntity[0] = nullptr; - ped->pLastContactedEntity[1] = nullptr; - ped->pLastContactedEntity[2] = nullptr; - ped->pLastContactedEntity[3] = nullptr; - ped->m_ucCollisionState = 0; - - if (auto* playerPed = dynamic_cast(pedLinks->pEntity)) - playerPed->SetTargetedEntity(nullptr); - } + if (pObjectPool->IsEmpty(i)) + continue; + + auto* object = reinterpret_cast(pPoolBase + i * objectStride); + object->m_pCollidedEntity = nullptr; + object->pLastContactedEntity[0] = nullptr; + object->pLastContactedEntity[1] = nullptr; + object->pLastContactedEntity[2] = nullptr; + object->pLastContactedEntity[3] = nullptr; + object->m_ucCollisionState = 0; } } diff --git a/Client/game_sa/CBuildingsPoolSA.h b/Client/game_sa/CBuildingsPoolSA.h index 033b39b870c..e4b16021e81 100644 --- a/Client/game_sa/CBuildingsPoolSA.h +++ b/Client/game_sa/CBuildingsPoolSA.h @@ -26,10 +26,10 @@ class CBuildingsPoolSA : public CBuildingsPool void RemoveBuilding(CBuilding* pBuilding); bool HasFreeBuildingSlot(); - void RemoveAllWithBackup() override; - void RestoreBackup() override; - bool Resize(int size) override; - int GetSize() const override { return (*m_ppBuildingPoolInterface)->m_nSize; }; + void RemoveAllWithBackup() override; + void RestoreBackup() override; + bool Resize(int size) override; + int GetSize() const override { return (m_ppBuildingPoolInterface && *m_ppBuildingPoolInterface) ? (*m_ppBuildingPoolInterface)->m_nSize : 0; }; CClientEntity* GetClientBuilding(CBuildingSAInterface* pGameInterface) const noexcept; private: @@ -39,13 +39,21 @@ class CBuildingsPoolSA : public CBuildingsPool void UpdateBackupLodPointers(uint32_t offset); void RemoveVehicleDamageLinks(); void RemovePedsContactEnityLinks(); + void RemoveObjectEntityLinks(); + void PurgeStaleSectorEntries(void* oldPool, int poolSize); private: SVectorPoolData m_buildingPool{MAX_BUILDINGS}; CPoolSAInterface** m_ppBuildingPoolInterface; using building_buffer_t = std::uint8_t[sizeof(CBuildingSAInterface)]; - using backup_array_t = std::array, MAX_BUILDINGS>; + using backup_entry_t = std::pair; + using backup_container_t = std::vector; - std::unique_ptr m_pOriginalBuildingsBackup; + std::unique_ptr m_pOriginalBuildingsBackup; + + // Set by RemoveAllWithBackup after sweeping stale entity links (vehicle damage, + // ped contact, object entity refs). Cleared by Resize to skip a redundant pass + // when SetBuildingPoolSize calls both in the same remove/resize cycle. + bool m_bLinkSweepsDone{false}; }; diff --git a/Client/game_sa/CCamSA.cpp b/Client/game_sa/CCamSA.cpp index d7e347c8193..d42f228aa71 100644 --- a/Client/game_sa/CCamSA.cpp +++ b/Client/game_sa/CCamSA.cpp @@ -12,34 +12,96 @@ #include "StdInc.h" #include "CCamSA.h" #include "CGameSA.h" +#include +#include + +namespace +{ + constexpr float kPi = 3.14159265358979323846f; + constexpr float kTwoPi = 6.28318530717958647692f; + + inline float WrapAngleRad(float angle) noexcept + { + angle -= kTwoPi * std::floor((angle + kPi) / kTwoPi); + if (angle <= -kPi) { + angle += kTwoPi; + } else if (angle > kPi) { + angle -= kTwoPi; +} + return angle; + } +} extern CGameSA* pGame; CEntity* CCamSA::GetTargetEntity() const { + if (!m_pInterface) + return nullptr; + + if (!pGame) + return nullptr; + CEntitySAInterface* pInterface = m_pInterface->CamTargetEntity; if (pInterface) { CPools* pPools = pGame->GetPools(); - return pPools->GetEntity((DWORD*)pInterface); + if (pPools) + return pPools->GetEntity((DWORD*)pInterface); } return nullptr; } void CCamSA::SetTargetEntity(CEntity* pEntity) { - m_pInterface->CamTargetEntity = pEntity->GetInterface(); + if (!m_pInterface) + return; + + if (pEntity) + { + auto pEntityInterface = pEntity->GetInterface(); + if (!pEntityInterface) + return; + + m_pInterface->CamTargetEntity = pEntityInterface; + } + else + { + m_pInterface->CamTargetEntity = nullptr; + } } void CCamSA::GetDirection(float& fHorizontal, float& fVertical) { - fHorizontal = m_pInterface->m_fHorizontalAngle; - fVertical = m_pInterface->m_fVerticalAngle; + if (!m_pInterface) + { + fHorizontal = 0.0f; + fVertical = 0.0f; + return; + } + + const float fHoriz = std::isfinite(m_pInterface->m_fHorizontalAngle) ? WrapAngleRad(m_pInterface->m_fHorizontalAngle) : 0.0f; + const float fVert = std::isfinite(m_pInterface->m_fVerticalAngle) ? WrapAngleRad(m_pInterface->m_fVerticalAngle) : 0.0f; + + if (!std::isfinite(m_pInterface->m_fHorizontalAngle) || !std::isfinite(m_pInterface->m_fVerticalAngle)) + { + m_pInterface->m_fHorizontalAngle = fHoriz; + m_pInterface->m_fVerticalAngle = fVert; + } + + fHorizontal = fHoriz; + fVertical = fVert; } void CCamSA::SetDirection(float fHorizontal, float fVertical) { - // Calculation @ sub 0x50F970 - m_pInterface->m_fHorizontalAngle = fHorizontal; - m_pInterface->m_fVerticalAngle = fVertical; + if (!m_pInterface) + return; + + // Validate input float values + if (!std::isfinite(fHorizontal) || !std::isfinite(fVertical)) + return; + + m_pInterface->m_fHorizontalAngle = WrapAngleRad(fHorizontal); + m_pInterface->m_fVerticalAngle = WrapAngleRad(fVertical); } diff --git a/Client/game_sa/CCamSA.h b/Client/game_sa/CCamSA.h index f31e55b2147..90284b66f9c 100644 --- a/Client/game_sa/CCamSA.h +++ b/Client/game_sa/CCamSA.h @@ -17,142 +17,142 @@ #include "CPedSA.h" const int NUMBER_OF_VECTORS_FOR_AVERAGE = 2; -#define CAM_NUM_TARGET_HISTORY 4 +#define CAM_NUM_TARGET_HISTORY 4 class CCamSAInterface { public: - bool bBelowMinDist; // used for follow ped mode - bool bBehindPlayerDesired; // used for follow ped mode + bool bBelowMinDist; // used for follow ped mode + bool bBehindPlayerDesired; // used for follow ped mode bool m_bCamLookingAtVector; bool m_bCollisionChecksOn; - bool m_bFixingBeta; // used for camera on a string // 4 + bool m_bFixingBeta; // used for camera on a string // 4 bool m_bTheHeightFixerVehicleIsATrain; bool LookBehindCamWasInFront; bool LookingBehind; - bool LookingLeft; // 8 + bool LookingLeft; // 8 bool LookingRight; - bool ResetStatics; // for interpolation type stuff to work + bool ResetStatics; // for interpolation type stuff to work bool Rotating; - short Mode; // CameraMode // 12 - unsigned int m_uiFinishTime; // 14 + short Mode; // CameraMode // 12 + unsigned int m_uiFinishTime; // 14 - int m_iDoCollisionChecksOnFrameNum; // 18 + int m_iDoCollisionChecksOnFrameNum; // 18 int m_iDoCollisionCheckEveryNumOfFrames; int m_iFrameNumWereAt; - int m_iRunningVectorArrayPos; // 32 + int m_iRunningVectorArrayPos; // 32 int m_iRunningVectorCounter; - int DirectionWasLooking; // 40 + int DirectionWasLooking; // 40 - float f_max_role_angle; //=DEGTORAD(5.0f); // 44 - float f_Roll; // used for adding a slight roll to the camera in the - float f_rollSpeed; // camera on a string mode - float m_fSyphonModeTargetZOffSet; // 56 + float f_max_role_angle; //=DEGTORAD(5.0f); // 44 + float f_Roll; // used for adding a slight roll to the camera in the + float f_rollSpeed; // camera on a string mode + float m_fSyphonModeTargetZOffSet; // 56 float m_fAmountFractionObscured; - float m_fAlphaSpeedOverOneFrame; // 64 + float m_fAlphaSpeedOverOneFrame; // 64 float m_fBetaSpeedOverOneFrame; - float m_fBufferedTargetBeta; // 72 + float m_fBufferedTargetBeta; // 72 float m_fBufferedTargetOrientation; - float m_fBufferedTargetOrientationSpeed; // 80 + float m_fBufferedTargetOrientationSpeed; // 80 float m_fCamBufferedHeight; float m_fCamBufferedHeightSpeed; - float m_fCloseInPedHeightOffset; // 92 + float m_fCloseInPedHeightOffset; // 92 float m_fCloseInPedHeightOffsetSpeed; float m_fCloseInCarHeightOffset; - float m_fCloseInCarHeightOffsetSpeed; // 104 + float m_fCloseInCarHeightOffsetSpeed; // 104 float m_fDimensionOfHighestNearCar; - float m_fDistanceBeforeChanges; // 112 + float m_fDistanceBeforeChanges; // 112 float m_fFovSpeedOverOneFrame; - float m_fMinDistAwayFromCamWhenInterPolating; // 120 + float m_fMinDistAwayFromCamWhenInterPolating; // 120 float m_fPedBetweenCameraHeightOffset; - float m_fPlayerInFrontSyphonAngleOffSet; // 128 + float m_fPlayerInFrontSyphonAngleOffSet; // 128 float m_fRadiusForDead; - float m_fRealGroundDist; // used for follow ped mode // 136 + float m_fRealGroundDist; // used for follow ped mode // 136 float m_fTargetBeta; float m_fTimeElapsedFloat; - float m_fTilt; // 148 - float m_fTiltSpeed; // 152 - - float m_fTransitionBeta; // 156 - float m_fTrueBeta; // 160 - float m_fTrueAlpha; // 164 - float m_fInitialPlayerOrientation; // used for first person // 168 - - float m_fVerticalAngle; // alpha // 172 - float AlphaSpeed; // 176 - float FOV; // 180 - float FOVSpeed; // 184 - float m_fHorizontalAngle; // beta // 188 - float BetaSpeed; // 192 - float Distance; // 196 + float m_fTilt; // 148 + float m_fTiltSpeed; // 152 + + float m_fTransitionBeta; // 156 + float m_fTrueBeta; // 160 + float m_fTrueAlpha; // 164 + float m_fInitialPlayerOrientation; // used for first person // 168 + + float m_fVerticalAngle; // alpha // 172 + float AlphaSpeed; // 176 + float FOV; // 180 + float FOVSpeed; // 184 + float m_fHorizontalAngle; // beta // 188 + float BetaSpeed; // 192 + float Distance; // 196 float DistanceSpeed; - float CA_MIN_DISTANCE; // 204 + float CA_MIN_DISTANCE; // 204 float CA_MAX_DISTANCE; float SpeedVar; - float m_fCameraHeightMultiplier; // used by TwoPlayer_Separate_Cars_TopDown // 216 + float m_fCameraHeightMultiplier; // used by TwoPlayer_Separate_Cars_TopDown // 216 // ped onfoot zoom distance - float m_fTargetZoomGroundOne; // 220 + float m_fTargetZoomGroundOne; // 220 float m_fTargetZoomGroundTwo; - float m_fTargetZoomGroundThree; // 228 + float m_fTargetZoomGroundThree; // 228 // ped onfoot alpha angle offset float m_fTargetZoomOneZExtra; float m_fTargetZoomTwoZExtra; - float m_fTargetZoomTwoInteriorZExtra; // extra one for interior - float m_fTargetZoomThreeZExtra; // 244 + float m_fTargetZoomTwoInteriorZExtra; // extra one for interior + float m_fTargetZoomThreeZExtra; // 244 - float m_fTargetZoomZCloseIn; // 248 + float m_fTargetZoomZCloseIn; // 248 float m_fMinRealGroundDist; float m_fTargetCloseInDist; // For targetting in cooperative mode. - float Beta_Targeting; // 260 + float Beta_Targeting; // 260 float X_Targetting, Y_Targetting; - int CarWeAreFocussingOn; // which car is closer to the camera in 2 player cooperative mode with separate cars. // 272 - float CarWeAreFocussingOnI; // interpolated version + int CarWeAreFocussingOn; // which car is closer to the camera in 2 player cooperative mode with separate cars. // 272 + float CarWeAreFocussingOnI; // interpolated version - float m_fCamBumpedHorz; // 280 + float m_fCamBumpedHorz; // 280 float m_fCamBumpedVert; - int m_nCamBumpedTime; // 288 + int m_nCamBumpedTime; // 288 static int CAM_BUMPED_SWING_PERIOD; static int CAM_BUMPED_END_TIME; static float CAM_BUMPED_DAMP_RATE; static float CAM_BUMPED_MOVE_MULT; - CVector m_cvecSourceSpeedOverOneFrame; // 292 - CVector m_cvecTargetSpeedOverOneFrame; // 304 - CVector m_cvecUpOverOneFrame; // 316 + CVector m_cvecSourceSpeedOverOneFrame; // 292 + CVector m_cvecTargetSpeedOverOneFrame; // 304 + CVector m_cvecUpOverOneFrame; // 316 - CVector m_cvecTargetCoorsForFudgeInter; // 328 - CVector m_cvecCamFixedModeVector; // 340 - CVector m_cvecCamFixedModeSource; // 352 - CVector m_cvecCamFixedModeUpOffSet; // 364 - CVector m_vecLastAboveWaterCamPosition; // 376 //helper for when the player has gone under the water + CVector m_cvecTargetCoorsForFudgeInter; // 328 + CVector m_cvecCamFixedModeVector; // 340 + CVector m_cvecCamFixedModeSource; // 352 + CVector m_cvecCamFixedModeUpOffSet; // 364 + CVector m_vecLastAboveWaterCamPosition; // 376 //helper for when the player has gone under the water - CVector m_vecBufferedPlayerBodyOffset; // 388 + CVector m_vecBufferedPlayerBodyOffset; // 388 // The three vectors that determine this camera for this frame - CVector Front; // 400 // Direction of looking in - CVector Source; // Coors in world space - CVector SourceBeforeLookBehind; // 424 - CVector Up; // Just that - CVector m_arrPreviousVectors[NUMBER_OF_VECTORS_FOR_AVERAGE]; // used to average stuff // 448 + CVector Front; // 400 // Direction of looking in + CVector Source; // Coors in world space + CVector SourceBeforeLookBehind; // 424 + CVector Up; // Just that + CVector m_arrPreviousVectors[NUMBER_OF_VECTORS_FOR_AVERAGE]; // used to average stuff // 448 - CVector m_aTargetHistoryPos[CAM_NUM_TARGET_HISTORY]; // 472 - DWORD m_nTargetHistoryTime[CAM_NUM_TARGET_HISTORY]; // 520 - DWORD m_nCurrentHistoryPoints; // 536 + CVector m_aTargetHistoryPos[CAM_NUM_TARGET_HISTORY]; // 472 + DWORD m_nTargetHistoryTime[CAM_NUM_TARGET_HISTORY]; // 520 + DWORD m_nCurrentHistoryPoints; // 536 CEntitySAInterface* CamTargetEntity; public: - float m_fCameraDistance; // 544 + float m_fCameraDistance; // 544 float m_fIdealAlpha; - float m_fPlayerVelocity; // 552 + float m_fPlayerVelocity; // 552 // CVector TempRight; - CAutomobileSAInterface* m_pLastCarEntered; // So interpolation works - CPedSAInterface* m_pLastPedLookedAt; // So interpolation works - bool m_bFirstPersonRunAboutActive; // 564 + CAutomobileSAInterface* m_pLastCarEntered; // So interpolation works + CPedSAInterface* m_pLastPedLookedAt; // So interpolation works + bool m_bFirstPersonRunAboutActive; // 564 }; static_assert(sizeof(CCamSAInterface) == 0x238, "Invalid size for CCamSAInterface"); @@ -162,22 +162,54 @@ class CCamSA : public CCam CCamSAInterface* m_pInterface; public: - CCamSA(CCamSAInterface* pInterface) { m_pInterface = pInterface; } + CCamSA(CCamSAInterface* pInterface) : m_pInterface(pInterface) + { + if (!pInterface) + { + m_pInterface = nullptr; + } + } + CCamSAInterface* GetInterface() { return m_pInterface; } - CVector* GetFront() const { return &m_pInterface->Front; } - CVector* GetUp() const { return &m_pInterface->Up; } - CVector* GetSource() const { return &m_pInterface->Source; } - unsigned int GetMode() const { return m_pInterface->Mode; } - float GetFOV() const { return m_pInterface->FOV; } - void SetFOV(float fFOV) { m_pInterface->FOV = fFOV; } - void GetDirection(float& fHorizontal, float& fVertical); - void SetDirection(float fHorizontal, float fVertical); + CVector* GetFront() const override { return m_pInterface ? &m_pInterface->Front : nullptr; } + + CVector* GetUp() const override { return m_pInterface ? &m_pInterface->Up : nullptr; } + + CVector* GetSource() const override { return m_pInterface ? &m_pInterface->Source : nullptr; } + + unsigned int GetMode() const override { return m_pInterface ? static_cast(m_pInterface->Mode) : 0; } + + float GetFOV() const override + { + if (!m_pInterface) + return 70.0f; // Default FOV + + float fov = m_pInterface->FOV; + return std::isfinite(fov) ? fov : 70.0f; + } + + void SetFOV(float fFOV) override + { + if (!m_pInterface) + return; + + // Validate FOV range + if (!std::isfinite(fFOV) || fFOV <= 0.0f || fFOV >= 180.0f) + return; + + m_pInterface->FOV = fFOV; + } + + void GetDirection(float& fHorizontal, float& fVertical) override; + void SetDirection(float fHorizontal, float fVertical) override; + + CVector* GetFixedModeSource() const override { return m_pInterface ? &m_pInterface->m_cvecCamFixedModeSource : nullptr; } + + CVector* GetFixedModeVector() const override { return m_pInterface ? &m_pInterface->m_cvecCamFixedModeVector : nullptr; } - CVector* GetFixedModeSource() const { return &m_pInterface->m_cvecCamFixedModeSource; } - CVector* GetFixedModeVector() const { return &m_pInterface->m_cvecCamFixedModeVector; } - CVector* GetTargetHistoryPos() const { return m_pInterface->m_aTargetHistoryPos; } + CVector* GetTargetHistoryPos() const override { return m_pInterface ? m_pInterface->m_aTargetHistoryPos : nullptr; } - CEntity* GetTargetEntity() const; + CEntity* GetTargetEntity() const override; void SetTargetEntity(CEntity* pEntity) override; }; diff --git a/Client/game_sa/CCameraSA.cpp b/Client/game_sa/CCameraSA.cpp index 74a368bc406..1b3da789223 100644 --- a/Client/game_sa/CCameraSA.cpp +++ b/Client/game_sa/CCameraSA.cpp @@ -12,27 +12,85 @@ #include "StdInc.h" #include "CCameraSA.h" #include "CGameSA.h" +#include +#include +#include + +namespace +{ + constexpr float kPi = 3.14159265358979323846f; + constexpr float kTwoPi = 6.28318530717958647692f; + + inline float WrapAngleRad(float angle) noexcept + { + // Wrap into [-pi, pi] using one multiplication and floor + angle -= kTwoPi * std::floor((angle + kPi) / kTwoPi); + if (angle <= -kPi) { + angle += kTwoPi; + } else if (angle > kPi) { + angle -= kTwoPi; +} + return angle; + } + + inline bool IsFiniteVector(const CVector& vec) noexcept + { + return std::isfinite(vec.fX) && std::isfinite(vec.fY) && std::isfinite(vec.fZ); + } +} extern CGameSA* pGame; -static bool bCameraClipObjects; -static bool bCameraClipVehicles; +enum class CameraClipFlags : uint8_t +{ + Objects = 1u << 0, + Vehicles = 1u << 1, +}; + +static std::atomic s_cameraClipMask{static_cast(CameraClipFlags::Objects) | static_cast(CameraClipFlags::Vehicles)}; -#define VAR_CameraClipVehicles 0x8A5B14 -#define VAR_CameraClipDynamicObjects 0x8A5B15 -#define VAR_CameraClipStaticObjects 0x8A5B16 +#define VAR_CameraClipVehicles 0x8A5B14 +#define VAR_CameraClipDynamicObjects 0x8A5B15 +#define VAR_CameraClipStaticObjects 0x8A5B16 -#define HOOKPOS_Camera_CollisionDetection 0x520190 +#define HOOKPOS_Camera_CollisionDetection 0x520190 DWORD RETURN_Camera_CollisionDetection = 0x520195; void HOOK_Camera_CollisionDetection(); CCameraSA::CCameraSA(CCameraSAInterface* cameraInterface) { + if (!cameraInterface) + { + internalInterface = nullptr; + // Initialize all camera pointers to null + for (int i = 0; i < MAX_CAMS; i++) + Cams[i] = nullptr; + return; + } + internalInterface = cameraInterface; + for (int i = 0; i < MAX_CAMS; i++) - Cams[i] = new CCamSA(&internalInterface->Cams[i]); - bCameraClipObjects = true; - bCameraClipVehicles = true; + { + try + { + Cams[i] = new CCamSA(&internalInterface->Cams[i]); + } + catch (...) + { + // Clean up on failure + for (int j = 0; j < i; j++) + { + delete Cams[j]; + Cams[j] = nullptr; + } + internalInterface = nullptr; + throw; + } + } + + s_cameraClipMask.store(static_cast(CameraClipFlags::Objects) | static_cast(CameraClipFlags::Vehicles), std::memory_order_relaxed); + HookInstall(HOOKPOS_Camera_CollisionDetection, (DWORD)HOOK_Camera_CollisionDetection, 5); } @@ -40,36 +98,42 @@ CCameraSA::~CCameraSA() { for (int i = 0; i < MAX_CAMS; i++) { - delete Cams[i]; + if (Cams[i]) + { + delete Cams[i]; + Cams[i] = nullptr; + } } } void CCameraSA::Restore() { - DWORD dwFunc = FUNC_Restore; CCameraSAInterface* cameraInterface = GetInterface(); - _asm - { - mov ecx, cameraInterface - call dwFunc - } + if (!cameraInterface) + return; + + DWORD dwFunc = FUNC_Restore; + // clang-format off + using func_t = void (__thiscall*)(decltype(cameraInterface) ); + reinterpret_cast(dwFunc)(cameraInterface); + // clang-format on } void CCameraSA::RestoreWithJumpCut() { CCameraSAInterface* cameraInterface = GetInterface(); - DWORD dwFunc = 0x50BD40; - _asm - { - mov ecx, cameraInterface - call dwFunc - } + if (!cameraInterface) + return; + DWORD dwFunc = 0x50BD40; + // clang-format off + using func_t = void (__thiscall*)(decltype(cameraInterface) ); + reinterpret_cast(dwFunc)(cameraInterface); + // clang-format on dwFunc = 0x50BAB0; - _asm - { - mov ecx, cameraInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(cameraInterface) ); + reinterpret_cast(dwFunc)(cameraInterface); + // clang-format on } /** @@ -77,36 +141,55 @@ void CCameraSA::RestoreWithJumpCut() */ void CCameraSA::TakeControl(CEntity* entity, eCamMode CamMode, int CamSwitchStyle) { + if (!entity) + return; + CEntitySA* pEntitySA = dynamic_cast(entity); if (!pEntitySA) return; CEntitySAInterface* entityInterface = pEntitySA->GetInterface(); + if (!entityInterface) + return; + CCameraSAInterface* cameraInterface = GetInterface(); - // __thiscall + if (!cameraInterface) + return; + + if (CamSwitchStyle < 0) { + CamSwitchStyle = 0; + } else if (CamSwitchStyle > 10) { + CamSwitchStyle = 10; +} DWORD CCamera__TakeControl = FUNC_TakeControl; - _asm - { - mov ecx, cameraInterface - push 1 - push CamSwitchStyle - push CamMode - push entityInterface - call CCamera__TakeControl - } + // clang-format off + using func_t = void (__thiscall*)(decltype(cameraInterface), decltype(entityInterface), decltype(CamMode), decltype(CamSwitchStyle), decltype(1)); + reinterpret_cast(CCamera__TakeControl)(cameraInterface, entityInterface, CamMode, CamSwitchStyle, 1); + // clang-format on } void CCameraSA::TakeControl(CVector* position, int CamSwitchStyle) { + if (!position) + return; + CCameraSAInterface* cameraInterface = GetInterface(); + if (!cameraInterface) + return; + + if (CamSwitchStyle < 0) { + CamSwitchStyle = 0; + } else if (CamSwitchStyle > 10) { + CamSwitchStyle = 10; +} // __thiscall CVector vecOffset; /* vecOffset.fZ = 0.5f; vecOffset.fY = 0.5f; vecOffset.fX = 0.5f;*/ /* DWORD dwFunc = 0x50BEC0; - _asm + __asm { mov ecx, cameraInterface lea eax, vecOffset @@ -116,17 +199,14 @@ void CCameraSA::TakeControl(CVector* position, int CamSwitchStyle) }*/ DWORD CCamera__TakeControlNoEntity = FUNC_TakeControlNoEntity; - _asm - { - mov ecx, cameraInterface - push 1 - push CamSwitchStyle - push position - call CCamera__TakeControlNoEntity - } + // clang-format off + using func_t = void (__thiscall*)(decltype(cameraInterface), decltype(position), decltype(CamSwitchStyle), decltype(1)); + reinterpret_cast(CCamera__TakeControlNoEntity)(cameraInterface, position, CamSwitchStyle, 1); + // clang-format on DWORD dwFunc = 0x50BEC0; - _asm + // clang-format off + __asm { mov ecx, cameraInterface lea eax, vecOffset @@ -134,6 +214,7 @@ void CCameraSA::TakeControl(CVector* position, int CamSwitchStyle) push position call dwFunc } + // clang-format on } // LSOD recovery @@ -144,6 +225,9 @@ void CCameraSA::RestoreLastGoodState() CCameraSAInterface* pCameraInterface = GetInterface(); + if (!pCameraInterface) + return; + pCameraInterface->m_CameraAverageSpeed = 0; pCameraInterface->m_CameraSpeedSoFar = 0; pCameraInterface->m_PreviousCameraPosition = CVector(); @@ -187,7 +271,17 @@ void CCameraSA::RestoreLastGoodState() CMatrix* CCameraSA::GetMatrix(CMatrix* matrix) { - CMatrix_Padded* pCamMatrix = &GetInterface()->m_cameraMatrix; // ->matrix; + if (!matrix) + return nullptr; + + CCameraSAInterface* cameraInterface = GetInterface(); + if (!cameraInterface) + { + *matrix = CMatrix(); + return matrix; + } + + CMatrix_Padded* pCamMatrix = &cameraInterface->m_cameraMatrix; if (pCamMatrix) { matrix->vFront = pCamMatrix->vFront; @@ -210,7 +304,14 @@ CMatrix* CCameraSA::GetMatrix(CMatrix* matrix) void CCameraSA::SetMatrix(CMatrix* matrix) { - CMatrix_Padded* pCamMatrix = GetInterface()->matrix; + if (!matrix) + return; + + CCameraSAInterface* cameraInterface = GetInterface(); + if (!cameraInterface) + return; + + CMatrix_Padded* pCamMatrix = &cameraInterface->m_cameraMatrix; if (pCamMatrix) { pCamMatrix->vFront = matrix->vFront; @@ -222,41 +323,56 @@ void CCameraSA::SetMatrix(CMatrix* matrix) void CCameraSA::Find3rdPersonCamTargetVector(float fDistance, CVector* vecGunMuzzle, CVector* vecSource, CVector* vecTarget) { - float fOriginX = vecGunMuzzle->fX; - float fOriginY = vecGunMuzzle->fY; - float fOriginZ = vecGunMuzzle->fZ; + if (!vecGunMuzzle || !vecSource || !vecTarget) + return; + + // Validate float parameter to prevent NaN/infinity issues + if (!std::isfinite(fDistance) || fDistance < 0.0f) + return; + + float fOriginX = vecGunMuzzle->fX; + float fOriginY = vecGunMuzzle->fY; + float fOriginZ = vecGunMuzzle->fZ; + + if (!std::isfinite(fOriginX) || !std::isfinite(fOriginY) || !std::isfinite(fOriginZ)) + return; + DWORD dwFunc = FUNC_Find3rdPersonCamTargetVector; CCameraSAInterface* cameraInterface = GetInterface(); - _asm - { - mov ecx, cameraInterface - push vecTarget - push vecSource - push fOriginZ - push fOriginY - push fOriginX - push fDistance - call dwFunc - } + + if (!cameraInterface) + return; + + // clang-format off + using func_t = void (__thiscall*)(decltype(cameraInterface), decltype(fDistance), decltype(fOriginX), decltype(fOriginY), decltype(fOriginZ), decltype(vecSource), decltype(vecTarget)); + reinterpret_cast(dwFunc)(cameraInterface, fDistance, fOriginX, fOriginY, fOriginZ, vecSource, vecTarget); + // clang-format on } float CCameraSA::Find3rdPersonQuickAimPitch() { - float fReturn; - DWORD dwFunc = FUNC_Find3rdPersonQuickAimPitch; CCameraSAInterface* cameraInterface = GetInterface(); - _asm + if (!cameraInterface) + return 0.0f; + + float fReturn; + DWORD dwFunc = FUNC_Find3rdPersonQuickAimPitch; + // clang-format off + __asm { mov ecx, cameraInterface call dwFunc fstp fReturn } + // clang-format on return fReturn; } BYTE CCameraSA::GetActiveCam() { CCameraSAInterface* cameraInterface = GetInterface(); + if (!cameraInterface) + return 0; return cameraInterface->ActiveCam; } @@ -283,12 +399,17 @@ CCam* CCameraSA::GetCam(CCamSAInterface* camInterface) void CCameraSA::SetWidescreen(bool bWidescreen) { - GetInterface()->m_WideScreenOn = bWidescreen; + CCameraSAInterface* cameraInterface = GetInterface(); + if (!cameraInterface) + return; + cameraInterface->m_WideScreenOn = bWidescreen; } bool CCameraSA::GetWidescreen() { CCameraSAInterface* cameraInterface = GetInterface(); + if (!cameraInterface) + return false; return cameraInterface->m_WideScreenOn; } @@ -296,13 +417,13 @@ bool CCameraSA::IsFading() { DWORD dwFunc = FUNC_GetFading; CCameraSAInterface* cameraInterface = GetInterface(); - bool bRet = false; - _asm - { - mov ecx, cameraInterface - call dwFunc - mov bRet, al - } + if (!cameraInterface) + return false; + bool bRet = false; + // clang-format off + using func_t = decltype(bRet) (__thiscall*)(decltype(cameraInterface) ); +bRet = reinterpret_cast(dwFunc)(cameraInterface); + // clang-format on return bRet; } @@ -310,44 +431,58 @@ int CCameraSA::GetFadingDirection() { DWORD dwFunc = FUNC_GetFadingDirection; CCameraSAInterface* cameraInterface = GetInterface(); - int dwRet = false; - _asm - { - mov ecx, cameraInterface - call dwFunc - mov dwRet, eax - } + if (!cameraInterface) + return 0; + int dwRet = false; + // clang-format off + using func_t = decltype(dwRet) (__thiscall*)(decltype(cameraInterface) ); +dwRet = reinterpret_cast(dwFunc)(cameraInterface); + // clang-format on return dwRet; } void CCameraSA::Fade(float fFadeOutTime, int iOutOrIn) { + if (!std::isfinite(fFadeOutTime)) + return; + + if (fFadeOutTime < 0.0f) { + fFadeOutTime = 0.0f; + } else if (fFadeOutTime > 60.0f) { + fFadeOutTime = 60.0f; +} + + if (iOutOrIn < 0) { + iOutOrIn = 0; + } else if (iOutOrIn > 1) { + iOutOrIn = 1; +} + DWORD dwFunc = FUNC_Fade; CCameraSAInterface* cameraInterface = GetInterface(); - _asm - { - mov ecx, cameraInterface - push iOutOrIn - push fFadeOutTime - call dwFunc - } + + if (!cameraInterface) + return; + + // clang-format off + using func_t = void (__thiscall*)(decltype(cameraInterface), decltype(fFadeOutTime), decltype(iOutOrIn)); + reinterpret_cast(dwFunc)(cameraInterface, fFadeOutTime, iOutOrIn); + // clang-format on } void CCameraSA::SetFadeColor(unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue) { DWORD dwFunc = FUNC_SetFadeColour; CCameraSAInterface* cameraInterface = GetInterface(); - DWORD dwRed = ucRed; - DWORD dwGreen = ucGreen; - DWORD dwBlue = ucBlue; - _asm - { - mov ecx, cameraInterface - push dwBlue - push dwGreen - push dwRed - call dwFunc - } + if (!cameraInterface) + return; + DWORD dwRed = ucRed; + DWORD dwGreen = ucGreen; + DWORD dwBlue = ucBlue; + // clang-format off + using func_t = void (__thiscall*)(decltype(cameraInterface), decltype(dwRed), decltype(dwGreen), decltype(dwBlue)); + reinterpret_cast(dwFunc)(cameraInterface, dwRed, dwGreen, dwBlue); + // clang-format on } float CCameraSA::GetCameraRotation() @@ -357,16 +492,36 @@ float CCameraSA::GetCameraRotation() RwMatrix* CCameraSA::GetLTM() { + CCameraSAInterface* cameraInterface = GetInterface(); + if (!cameraInterface) + return nullptr; + + if (!cameraInterface->m_pRwCamera) + return nullptr; + + if (!cameraInterface->m_pRwCamera->object.object.parent) + return nullptr; + // RwFrameGetLTM - return ((RwMatrix*(_cdecl*)(void*))0x7F0990)(GetInterface()->m_pRwCamera->object.object.parent); + return ((RwMatrix * (_cdecl*)(void*))0x7F0990)(cameraInterface->m_pRwCamera->object.object.parent); } CEntity* CCameraSA::GetTargetEntity() { - CEntitySAInterface* pInterface = GetInterface()->pTargetEntity; + CCameraSAInterface* cameraInterface = GetInterface(); + if (!cameraInterface) + return nullptr; + + if (!pGame) + return nullptr; + + CEntitySAInterface* pInterface = cameraInterface->pTargetEntity; if (pInterface) { CPools* pPools = pGame->GetPools(); + if (!pPools) + return nullptr; + return pPools->GetEntity((DWORD*)pInterface); } return nullptr; @@ -374,42 +529,59 @@ CEntity* CCameraSA::GetTargetEntity() void CCameraSA::SetCameraClip(bool bObjects, bool bVehicles) { - bCameraClipObjects = bObjects; - bCameraClipVehicles = bVehicles; + uint8_t newMask = 0; + if (bObjects) + newMask |= static_cast(CameraClipFlags::Objects); + if (bVehicles) + newMask |= static_cast(CameraClipFlags::Vehicles); + s_cameraClipMask.store(newMask, std::memory_order_relaxed); } void CCameraSA::GetCameraClip(bool& bObjects, bool& bVehicles) { - bObjects = bCameraClipObjects; - bVehicles = bCameraClipVehicles; + const uint8_t mask = s_cameraClipMask.load(std::memory_order_relaxed); + bObjects = (mask & static_cast(CameraClipFlags::Objects)) != 0; + bVehicles = (mask & static_cast(CameraClipFlags::Vehicles)) != 0; } -__declspec(noinline) void _cdecl DoCameraCollisionDetectionPokes() +static void _cdecl DoCameraCollisionDetectionPokes() { - if (!bCameraClipObjects) + const uint8_t mask = s_cameraClipMask.load(std::memory_order_relaxed); + if ((mask & static_cast(CameraClipFlags::Objects)) == 0) { MemPutFast(VAR_CameraClipDynamicObjects, 0); MemPutFast(VAR_CameraClipStaticObjects, 0); } else + { + MemPutFast(VAR_CameraClipDynamicObjects, 1); MemPutFast(VAR_CameraClipStaticObjects, 1); + } - if (!bCameraClipVehicles) + if ((mask & static_cast(CameraClipFlags::Vehicles)) == 0) { MemPutFast(VAR_CameraClipVehicles, 0); + } else { + MemPutFast(VAR_CameraClipVehicles, 1); +} } -void _declspec(naked) HOOK_Camera_CollisionDetection() +static void __declspec(naked) HOOK_Camera_CollisionDetection() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad - call DoCameraCollisionDetectionPokes + call DoCameraCollisionDetectionPokes popad - sub esp,24h - push ebx - push ebp - jmp RETURN_Camera_CollisionDetection + + sub esp, 24h + push ebx + push ebp + jmp RETURN_Camera_CollisionDetection } + // clang-format on } BYTE CCameraSA::GetCameraVehicleViewMode() @@ -435,18 +607,24 @@ void CCameraSA::SetCameraPedViewMode(BYTE dwCamMode) void CCameraSA::SetShakeForce(float fShakeForce) { CCameraSAInterface* pCameraInterface = GetInterface(); + if (!pCameraInterface) + return; pCameraInterface->m_fCamShakeForce = fShakeForce; } float CCameraSA::GetShakeForce() { CCameraSAInterface* pCameraInterface = GetInterface(); + if (!pCameraInterface) + return 0.0f; return pCameraInterface->m_fCamShakeForce; } void CCameraSA::ShakeCamera(float radius, float x, float y, float z) noexcept { - static CCameraSAInterface* cameraInterface = GetInterface(); + CCameraSAInterface* cameraInterface = GetInterface(); + if (!cameraInterface) + return; if (radius <= 0.0f) return ResetShakeCamera(); @@ -456,10 +634,65 @@ void CCameraSA::ShakeCamera(float radius, float x, float y, float z) noexcept void CCameraSA::ResetShakeCamera() noexcept { - GetInterface()->m_fCamShakeForce = 0.0f; + CCameraSAInterface* cameraInterface = GetInterface(); + if (!cameraInterface) + return; + cameraInterface->m_fCamShakeForce = 0.0f; +} + +std::uint8_t CCameraSA::GetTransitionState() const +{ + const CCameraSAInterface* cameraInterface = GetInterface(); + return cameraInterface ? cameraInterface->m_uiTransitionState : 0; +} + +bool CCameraSA::IsInTransition() const +{ + return GetTransitionState() != 0; } -std::uint8_t CCameraSA::GetTransitionState() +float CCameraSA::GetTransitionFOV() const { - return GetInterface()->m_uiTransitionState; + CCameraSAInterface* cameraInterface = GetInterface(); + return cameraInterface ? cameraInterface->FOVDuringInter : DEFAULT_FOV; +} + +bool CCameraSA::GetTransitionMatrix(CMatrix& matrix) const +{ + CCameraSAInterface* cameraInterface = GetInterface(); + if (!cameraInterface || !IsInTransition()) + return false; + + CVector source = cameraInterface->SourceDuringInter; + CVector target = cameraInterface->TargetDuringInter; + CVector up = cameraInterface->UpDuringInter; + + if (!IsFiniteVector(source) || !IsFiniteVector(target) || !IsFiniteVector(up)) + return false; + + CVector forward = target - source; + if (forward.Length() < FLOAT_EPSILON) { + forward = CVector(0.0f, 1.0f, 0.0f); + } else { + forward.Normalize(); +} + + CVector right = CVector(forward.fY, -forward.fX, 0.0f); + if (right.Length() < FLOAT_EPSILON) { + right = CVector(1.0f, 0.0f, 0.0f); + } else { + right.Normalize(); +} + + CVector correctedUp = right; + correctedUp.CrossProduct(&forward); + correctedUp.Normalize(); + + matrix.vPos = source; + matrix.vFront = forward; + matrix.vRight = -right; + matrix.vUp = correctedUp; + matrix.OrthoNormalize(CMatrix::AXIS_FRONT, CMatrix::AXIS_UP); + + return true; } diff --git a/Client/game_sa/CCameraSA.h b/Client/game_sa/CCameraSA.h index 2f06c0689fb..c8e4abaf21b 100644 --- a/Client/game_sa/CCameraSA.h +++ b/Client/game_sa/CCameraSA.h @@ -17,29 +17,29 @@ #include "CGarageSA.h" #include "CEntitySA.h" -#define FUNC_TakeControl 0x50C7C0 -#define FUNC_TakeControlNoEntity 0x50C8B0 -#define FUNC_Restore 0x50B930 +#define FUNC_TakeControl 0x50C7C0 +#define FUNC_TakeControlNoEntity 0x50C8B0 +#define FUNC_Restore 0x50B930 -#define FUNC_Find3rdPersonCamTargetVector 0x514970 -#define FUNC_Find3rdPersonQuickAimPitch 0x50AD40 -#define FUNC_GetFadingDirection 0x50ADF0 -#define FUNC_GetFading 0x50ADE0 -#define FUNC_Fade 0x50AC20 -#define FUNC_SetFadeColour 0x50BF00 -#define FUNC_ShakeCam 0x50A9F0 +#define FUNC_Find3rdPersonCamTargetVector 0x514970 +#define FUNC_Find3rdPersonQuickAimPitch 0x50AD40 +#define FUNC_GetFadingDirection 0x50ADF0 +#define FUNC_GetFading 0x50ADE0 +#define FUNC_Fade 0x50AC20 +#define FUNC_SetFadeColour 0x50BF00 +#define FUNC_ShakeCam 0x50A9F0 -#define VAR_CameraRotation 0xB6F178 // used for controling where the player faces -#define VAR_VehicleCameraView 0xB6F0DC -#define VAR_PedCameraView 0xB6F0F0 +#define VAR_CameraRotation 0xB6F178 // used for controling where the player faces +#define VAR_VehicleCameraView 0xB6F0DC +#define VAR_PedCameraView 0xB6F0F0 -#define MAX_CAMS 3 +#define MAX_CAMS 3 -#define MAX_NUM_OF_NODES 800 // for trains +#define MAX_NUM_OF_NODES 800 // for trains /*** R* Defines ***/ #define NUMBER_OF_VECTORS_FOR_AVERAGE 2 -#define MAX_NUM_OF_SPLINETYPES (4) +#define MAX_NUM_OF_SPLINETYPES (4) /*** END R* Defines ***/ /*** BEGIN PURE R* CLASSES ***/ @@ -51,15 +51,15 @@ class CCamPathSplines { MAXPATHLENGTH = 800 }; - float* m_arr_PathData; // FLOAT m_arr_PathData[MAXPATHLENGTH]; + float* m_arr_PathData; // FLOAT m_arr_PathData[MAXPATHLENGTH]; }; class CQueuedMode { public: - short Mode; // CameraMode - float Duration; // How long for (<0.0f -> indefinately) - short MinZoom, MaxZoom; // How far is player allowed to zoom in & out + short Mode; // CameraMode + float Duration; // How long for (<0.0f -> indefinately) + short MinZoom, MaxZoom; // How far is player allowed to zoom in & out }; class CTrainCamNode @@ -67,9 +67,9 @@ class CTrainCamNode public: CVector m_cvecCamPosition; CVector m_cvecPointToLookAt; - CVector m_cvecMinPointInRange; // this is the minimum required distance the train has to be to the camera to + CVector m_cvecMinPointInRange; // this is the minimum required distance the train has to be to the camera to // allow a switch to the node cam - CVector m_cvecMaxPointInRange; // this is the minimum required distance the train has to be to from the camera + CVector m_cvecMaxPointInRange; // this is the minimum required distance the train has to be to from the camera float m_fDesiredFOV; float m_fNearClip; // to switch from the the node cam @@ -88,7 +88,7 @@ class CCameraSAInterface : public CPlaceableSAInterface bool m_bCameraJustRestored; bool m_bcutsceneFinished; bool m_bCullZoneChecksOn; - bool m_bFirstPersonBeingUsed; // To indicate if the m_bFirstPersonBeingUsed viewer is being used. + bool m_bFirstPersonBeingUsed; // To indicate if the m_bFirstPersonBeingUsed viewer is being used. bool m_bJustJumpedOutOf1stPersonBecauseOfTarget; bool m_bIdleOn; bool m_bInATunnelAndABigVehicle; @@ -98,8 +98,8 @@ class CCameraSAInterface : public CPlaceableSAInterface bool m_bPlayerIsInGarage; bool m_bPlayerWasOnBike; bool m_bJustCameOutOfGarage; - bool m_bJustInitalised; // Just so the speed thingy doesn't go mad right at the start - unsigned char m_bJust_Switched; // Variable to indicate that we have jumped somewhere, Raymond needs this for the audio engine + bool m_bJustInitalised; // Just so the speed thingy doesn't go mad right at the start + unsigned char m_bJust_Switched; // Variable to indicate that we have jumped somewhere, Raymond needs this for the audio engine bool m_bLookingAtPlayer; bool m_bLookingAtVector; bool m_bMoveCamToAvoidGeom; @@ -109,14 +109,14 @@ class CCameraSAInterface : public CPlaceableSAInterface bool m_bUseNearClipScript; bool m_bStartInterScript; unsigned char m_bStartingSpline; - bool m_bTargetJustBeenOnTrain; // this variable is needed to be able to restore the camera + bool m_bTargetJustBeenOnTrain; // this variable is needed to be able to restore the camera bool m_bTargetJustCameOffTrain; bool m_bUseSpecialFovTrain; bool m_bUseTransitionBeta; bool m_bUseScriptZoomValuePed; bool m_bUseScriptZoomValueCar; bool m_bWaitForInterpolToFinish; - bool m_bItsOkToLookJustAtThePlayer; // Used when interpolating + bool m_bItsOkToLookJustAtThePlayer; // Used when interpolating bool m_bWantsToSwitchWidescreenOff; bool m_WideScreenOn; bool m_1rstPersonRunCloseToAWall; @@ -138,42 +138,42 @@ class CCameraSAInterface : public CPlaceableSAInterface bool m_vecDoingSpecialInterPolation; bool m_bScriptParametersSetForInterPol; - bool m_bFading; // to indicate that we are fading + bool m_bFading; // to indicate that we are fading bool m_bMusicFading; bool m_bMusicFadedOut; bool m_bFailedCullZoneTestPreviously; - bool m_FadeTargetIsSplashScreen; // used as hack for fading - bool WorldViewerBeingUsed; // To indicate if the world viewer is being used. - - unsigned char m_uiTransitionJUSTStarted; // This is the first frame of a transition. - unsigned char m_uiTransitionState; // 0:one mode 1:transition - unsigned char ActiveCam; // Which one at the moment (0 or 1) - // Their is a fudge at the end when the renderware matrix will receive either - // the active camera or the worldviewer camera - unsigned int m_uiCamShakeStart; // When did the camera shake start. + bool m_FadeTargetIsSplashScreen; // used as hack for fading + bool WorldViewerBeingUsed; // To indicate if the world viewer is being used. + + unsigned char m_uiTransitionJUSTStarted; // This is the first frame of a transition. + unsigned char m_uiTransitionState; // 0:one mode 1:transition + unsigned char ActiveCam; // Which one at the moment (0 or 1) + // Their is a fudge at the end when the renderware matrix will receive either + // the active camera or the worldviewer camera + unsigned int m_uiCamShakeStart; // When did the camera shake start. unsigned int m_uiFirstPersonCamLastInputTime; unsigned int m_uiLongestTimeInMill; unsigned int m_uiNumberOfTrainCamNodes; unsigned int m_uiTimeLastChange; unsigned int m_uiTimeWeLeftIdle_StillNoInput; unsigned int m_uiTimeWeEnteredIdle; - unsigned int m_uiTimeTransitionStart; // When was the transition started ? - unsigned int m_uiTransitionDuration; // How long does the transition take ? + unsigned int m_uiTimeTransitionStart; // When was the transition started ? + unsigned int m_uiTransitionDuration; // How long does the transition take ? unsigned int m_uiTransitionDurationTargetCoors; int m_BlurBlue; int m_BlurGreen; int m_BlurRed; int m_BlurType; - int m_iWorkOutSpeedThisNumFrames; // duh - int m_iNumFramesSoFar; // counter - int m_iCurrentTrainCamNode; // variable indicating which camera node we are at for the train - int m_motionBlur; // to indicate that we are fading + int m_iWorkOutSpeedThisNumFrames; // duh + int m_iNumFramesSoFar; // counter + int m_iCurrentTrainCamNode; // variable indicating which camera node we are at for the train + int m_motionBlur; // to indicate that we are fading int m_imotionBlurAddAlpha; int m_iCheckCullZoneThisNumFrames; int m_iZoneCullFrameNumWereAt; - int WhoIsInControlOfTheCamera; // to discern between obbe and scripts + int WhoIsInControlOfTheCamera; // to discern between obbe and scripts // float CarZoomIndicator; // float CarZoomValue; @@ -183,23 +183,23 @@ class CCameraSAInterface : public CPlaceableSAInterface // float m_fPedZoomValue; // float m_fPedZoomValueSmooth; // float m_fPedZoomValueScript; - int m_nCarZoom; // store zoom index - float m_fCarZoomBase; // store base zoom distance from index - float m_fCarZoomTotal; // store total zoom after modded by camera modes - float m_fCarZoomSmoothed; // buffered version of the var above + int m_nCarZoom; // store zoom index + float m_fCarZoomBase; // store base zoom distance from index + float m_fCarZoomTotal; // store total zoom after modded by camera modes + float m_fCarZoomSmoothed; // buffered version of the var above float m_fCarZoomValueScript; - int m_nPedZoom; // store zoom index - float m_fPedZoomBase; // store base zoom distance from index - float m_fPedZoomTotal; // store total zoom after modded by camera modes - float m_fPedZoomSmoothed; // buffered version of the var above + int m_nPedZoom; // store zoom index + float m_fPedZoomBase; // store base zoom distance from index + float m_fPedZoomTotal; // store total zoom after modded by camera modes + float m_fPedZoomSmoothed; // buffered version of the var above float m_fPedZoomValueScript; float CamFrontXNorm, CamFrontYNorm; float DistanceToWater; float HeightOfNearestWater; float FOVDuringInter; - float LODDistMultiplier; // This takes into account the FOV and the standard LOD multiplier Smaller aperture->bigger LOD multipliers. - float GenerationDistMultiplier; // This takes into account the FOV but noy the standard LOD multiplier + float LODDistMultiplier; // This takes into account the FOV and the standard LOD multiplier Smaller aperture->bigger LOD multipliers. + float GenerationDistMultiplier; // This takes into account the FOV but noy the standard LOD multiplier float m_fAlphaSpeedAtStartInter; float m_fAlphaWhenInterPol; @@ -213,47 +213,47 @@ class CCameraSAInterface : public CPlaceableSAInterface float m_fStartingAlphaForInterPol; float m_PedOrientForBehindOrInFront; - float m_CameraAverageSpeed; // this is an average depending on how many frames we work it out - float m_CameraSpeedSoFar; // this is a running total - float m_fCamShakeForce; // How severe is the camera shake. + float m_CameraAverageSpeed; // this is an average depending on how many frames we work it out + float m_CameraSpeedSoFar; // this is a running total + float m_fCamShakeForce; // How severe is the camera shake. float m_fFovForTrain; float m_fFOV_Wide_Screen; float m_fNearClipScript; - float m_fOldBetaDiff; // Needed for interpolation between 2 modes - float m_fPositionAlongSpline; // Variable used to indicate how far along the spline we are 0-1 for started to completed respectively + float m_fOldBetaDiff; // Needed for interpolation between 2 modes + float m_fPositionAlongSpline; // Variable used to indicate how far along the spline we are 0-1 for started to completed respectively float m_ScreenReductionPercentage; float m_ScreenReductionSpeed; float m_AlphaForPlayerAnim1rstPerson; - float Orientation; // The orientation of the camera. Used for peds walking. - float PlayerExhaustion; // How tired is player (inaccurate sniping) 0.0f-1.0f - // The following things are used by the sound code to - // play reverb depending on the surroundings. From a point - // in front of the camera the disance is measured to the - // nearest obstacle (building) - float SoundDistUp; //, SoundDistLeft, SoundDistRight; // These ones are buffered and should be used by the audio - float SoundDistUpAsRead; //, SoundDistLeftAsRead, SoundDistRightAsRead; - float SoundDistUpAsReadOld; //, SoundDistLeftAsReadOld, SoundDistRightAsReadOld; - // Very rough distance to the nearest water for the sound to use - // Front vector X&Y normalised to 1. Used by loads of stuff. + float Orientation; // The orientation of the camera. Used for peds walking. + float PlayerExhaustion; // How tired is player (inaccurate sniping) 0.0f-1.0f + // The following things are used by the sound code to + // play reverb depending on the surroundings. From a point + // in front of the camera the disance is measured to the + // nearest obstacle (building) + float SoundDistUp; //, SoundDistLeft, SoundDistRight; // These ones are buffered and should be used by the audio + float SoundDistUpAsRead; //, SoundDistLeftAsRead, SoundDistRightAsRead; + float SoundDistUpAsReadOld; //, SoundDistLeftAsReadOld, SoundDistRightAsReadOld; + // Very rough distance to the nearest water for the sound to use + // Front vector X&Y normalised to 1. Used by loads of stuff. float m_fAvoidTheGeometryProbsTimer; short m_nAvoidTheGeometryProbsDirn; - float m_fWideScreenReductionAmount; // 0 for not reduced 1 for fully reduced (Variable for Les) + float m_fWideScreenReductionAmount; // 0 for not reduced 1 for fully reduced (Variable for Les) float m_fStartingFOVForInterPol; // These ones are static so that they don't get cleared in CCamera::Init() - static float m_fMouseAccelHorzntl; // acceleration multiplier for 1st person controls - static float m_fMouseAccelVertical; // acceleration multiplier for 1st person controls + static float m_fMouseAccelHorzntl; // acceleration multiplier for 1st person controls + static float m_fMouseAccelVertical; // acceleration multiplier for 1st person controls static float m_f3rdPersonCHairMultX; static float m_f3rdPersonCHairMultY; - CCamSAInterface Cams[3]; // The actual cameras (usually only one of the two is active) - // And to complicate this we have a third camera, this camera is - // used for debugging when we want to have a look at the world. - // We can't change the camera mode because other objects depend on their + CCamSAInterface Cams[3]; // The actual cameras (usually only one of the two is active) + // And to complicate this we have a third camera, this camera is + // used for debugging when we want to have a look at the world. + // We can't change the camera mode because other objects depend on their // #########################################// // DATA NOT UPDATED FOR SA BELOW HERE!!!!! // @@ -266,10 +266,10 @@ class CCameraSAInterface : public CPlaceableSAInterface // for the sniper mode and rocket launcher mode. // This one overwrites the m_PlayerMode above. CQueuedMode PlayerWeaponMode; - CVector m_PreviousCameraPosition; // needed to work out speed - CVector m_RealPreviousCameraPosition; // This cane be used by stuff outside the camera code. The one above is the same as the current coordinates - // outwidth the camera code. an active camera for range finding etc - CVector m_cvecAimingTargetCoors; // Coors to look at with Gordons aiming thing + CVector m_PreviousCameraPosition; // needed to work out speed + CVector m_RealPreviousCameraPosition; // This cane be used by stuff outside the camera code. The one above is the same as the current coordinates + // outwidth the camera code. an active camera for range finding etc + CVector m_cvecAimingTargetCoors; // Coors to look at with Gordons aiming thing // The player camera that is waiting to be used // This camera can replace the default camera where this is // needed (in tricky situations like tunnels for instance) @@ -290,9 +290,9 @@ class CCameraSAInterface : public CPlaceableSAInterface CVector m_vecGameCamPos; CVector SourceDuringInter, TargetDuringInter, UpDuringInter; - CVector m_vecAttachedCamOffset; // for attaching the camera to a ped or vehicle (set by level designers for use in cutscenes) + CVector m_vecAttachedCamOffset; // for attaching the camera to a ped or vehicle (set by level designers for use in cutscenes) CVector m_vecAttachedCamLookAt; - float m_fAttachedCamAngle; // for giving the attached camera a tilt. + float m_fAttachedCamAngle; // for giving the attached camera a tilt. // RenderWare camera pointer RwCamera* m_pRwCamera; @@ -300,7 +300,7 @@ class CCameraSAInterface : public CPlaceableSAInterface CEntitySAInterface* pTargetEntity; CEntitySAInterface* pAttachedEntity; // CVector CutScene; - CCamPathSplines m_arrPathArray[MAX_NUM_OF_SPLINETYPES]; // These only get created when the script calls the load splines function + CCamPathSplines m_arrPathArray[MAX_NUM_OF_SPLINETYPES]; // These only get created when the script calls the load splines function // maybe this shouldn't be here depends if GTA_TRAIN is defined (its not) // CTrainCamNode m_arrTrainCamNode[MAX_NUM_OF_NODES]; @@ -343,7 +343,7 @@ class CCameraSAInterface : public CPlaceableSAInterface CVector m_vecOldFrontForInter; CVector m_vecOldUpForInter; float m_vecOldFOVForInter; - float m_fFLOATingFade; // variable representing the FLOAT version of CDraw::Fade. Necessary to stop loss of precision + float m_fFLOATingFade; // variable representing the FLOAT version of CDraw::Fade. Necessary to stop loss of precision float m_fFLOATingFadeMusic; float m_fTimeToFadeOut; float m_fTimeToFadeMusic; @@ -381,41 +381,46 @@ class CCameraSA : public CCamera CCameraSA(CCameraSAInterface* cameraInterface); ~CCameraSA(); - CCameraSAInterface* GetInterface() { return internalInterface; }; - void TakeControl(CEntity* entity, eCamMode CamMode, int CamSwitchStyle); - void TakeControl(CVector* position, int CamSwitchStyle); - void Restore(); - void RestoreWithJumpCut(); - CMatrix* GetMatrix(CMatrix* matrix); - void SetMatrix(CMatrix* matrix); - void Find3rdPersonCamTargetVector(float fDistance, CVector* vecGunMuzzle, CVector* vecSource, CVector* vecTarget); - float Find3rdPersonQuickAimPitch(); - BYTE GetActiveCam(); - - CCam* GetCam(BYTE bCameraID); + CCameraSAInterface* GetInterface() const noexcept { return internalInterface; } + + // CCamera interface implementation + void TakeControl(CEntity* entity, eCamMode CamMode, int CamSwitchStyle) override; + void TakeControl(CVector* position, int CamSwitchStyle) override; + void Restore() override; + void RestoreWithJumpCut() override; + CMatrix* GetMatrix(CMatrix* matrix) override; + void SetMatrix(CMatrix* matrix) override; + void Find3rdPersonCamTargetVector(float fDistance, CVector* vecGunMuzzle, CVector* vecSource, CVector* vecTarget) override; + float Find3rdPersonQuickAimPitch() override; + BYTE GetActiveCam() override; + CCam* GetCam(BYTE bCameraID) override; + void SetWidescreen(bool bWidescreen) override; + bool GetWidescreen() override; + bool IsFading() override; + int GetFadingDirection() override; + void Fade(float fFadeOutTime, int iOutOrIn) override; + void SetFadeColor(unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue) override; + float GetCameraRotation() override; + RwMatrix* GetLTM() override; + CEntity* GetTargetEntity() override; + void SetCameraClip(bool bObjects, bool bVehicles) override; + void GetCameraClip(bool& bObjects, bool& bVehicles) override; + BYTE GetCameraVehicleViewMode() override; + BYTE GetCameraPedViewMode() override; + void SetCameraVehicleViewMode(BYTE dwCamMode) override; + void SetCameraPedViewMode(BYTE dwCamMode) override; + void SetShakeForce(float fShakeForce) override; + float GetShakeForce() override; + void ShakeCamera(float radius, float x, float y, float z) noexcept override; + void ResetShakeCamera() noexcept override; + std::uint8_t GetTransitionState() const override; + bool IsInTransition() const override; + float GetTransitionFOV() const override; + bool GetTransitionMatrix(CMatrix& matrix) const override; + + // Additional overload not in base interface virtual CCam* GetCam(CCamSAInterface* camInterface); - void SetWidescreen(bool bWidescreen); - bool GetWidescreen(); - bool IsFading(); - int GetFadingDirection(); - void Fade(float fFadeOutTime, int iOutOrIn); - void SetFadeColor(unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue); - float GetCameraRotation(); - RwMatrix* GetLTM(); - CEntity* GetTargetEntity(); - void SetCameraClip(bool bObjects, bool bVehicles); - void GetCameraClip(bool& bObjects, bool& bVehicles); - BYTE GetCameraVehicleViewMode(); - BYTE GetCameraPedViewMode(); - void SetCameraVehicleViewMode(BYTE dwCamMode); - void SetCameraPedViewMode(BYTE dwCamMode); - void RestoreLastGoodState(); - void SetShakeForce(float fShakeForce); - float GetShakeForce(); - - void ShakeCamera(float radius, float x, float y, float z) noexcept override; - void ResetShakeCamera() noexcept override; - - std::uint8_t GetTransitionState(); + // Additional methods + void RestoreLastGoodState(); }; diff --git a/Client/game_sa/CCarEnterExitSA.cpp b/Client/game_sa/CCarEnterExitSA.cpp index 5a9fef73f4a..d7bcd397166 100644 --- a/Client/game_sa/CCarEnterExitSA.cpp +++ b/Client/game_sa/CCarEnterExitSA.cpp @@ -26,16 +26,10 @@ bool CCarEnterExitSA::GetNearestCarDoor(CPed* pPed, CVehicle* pVehicle, CVector* { CPedSAInterface* pPedInterface = pPedSA->GetPedInterface(); CVehicleSAInterface* pVehicleInterface = pVehicleSA->GetVehicleInterface(); - _asm - { - push pDoor - push pVector - push pVehicleInterface - push pPedInterface - call dwFunc - add esp, 0x10 - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(pPedInterface), decltype(pVehicleInterface), decltype(pVector), decltype(pDoor)); +bReturn = reinterpret_cast(dwFunc)(pPedInterface, pVehicleInterface, pVector, pDoor); + // clang-format on } return bReturn; @@ -54,7 +48,8 @@ bool CCarEnterExitSA::GetNearestCarPassengerDoor(CPed* pPed, CVehicle* pVehicle, { CPedSAInterface* pPedInterface = pPedSA->GetPedInterface(); CVehicleSAInterface* pVehicleInterface = pVehicleSA->GetVehicleInterface(); - _asm + // clang-format off + __asm { push ebx xor ebx, ebx @@ -73,6 +68,7 @@ bool CCarEnterExitSA::GetNearestCarPassengerDoor(CPed* pPed, CVehicle* pVehicle, mov bReturn, al pop ebx } + // clang-format on } return bReturn; @@ -103,14 +99,10 @@ int CCarEnterExitSA::ComputeTargetDoorToExit(CPed* pPed, CVehicle* pVehicle) { CPedSAInterface* pPedInterface = pPedSA->GetPedInterface(); CVehicleSAInterface* pVehicleInterface = pVehicleSA->GetVehicleInterface(); - _asm - { - push pPedInterface - push pVehicleInterface - call dwFunc - add esp, 8 - mov door, eax - } + // clang-format off + using func_t = decltype(door) (__cdecl*)(decltype(pVehicleInterface), decltype(pPedInterface)); +door = reinterpret_cast(dwFunc)(pVehicleInterface, pPedInterface); + // clang-format on switch (door) { @@ -185,15 +177,10 @@ bool CCarEnterExitSA::IsRoomForPedToLeaveCar(CVehicle* pVehicle, int iDoor, CVec if (pVehicleSA) { CVehicleSAInterface* pVehicleInterface = pVehicleSA->GetVehicleInterface(); - _asm - { - push pUnknown - push dwIdx - push pVehicleInterface - call dwFunc - add esp, 12 - mov bRet, al - } + // clang-format off + using func_t = decltype(bRet) (__cdecl*)(decltype(pVehicleInterface), decltype(dwIdx), decltype(pUnknown)); +bRet = reinterpret_cast(dwFunc)(pVehicleInterface, dwIdx, pUnknown); + // clang-format on } } diff --git a/Client/game_sa/CCarEnterExitSA.h b/Client/game_sa/CCarEnterExitSA.h index f8bb9e621f2..58eb9c31b3a 100644 --- a/Client/game_sa/CCarEnterExitSA.h +++ b/Client/game_sa/CCarEnterExitSA.h @@ -13,11 +13,11 @@ #include -#define FUNC_GetNearestCarDoor 0x6528F0 -#define FUNC_GetNearestCarPassengerDoor 0x650BB0 -#define FUNC_ComputeTargetDoorToExit 0x64F110 -#define FUNC_IsRoomForPedToLeaveCar 0x6504C0 -#define FUNC_GetPositionToOpenCarDoor 0x64E740 +#define FUNC_GetNearestCarDoor 0x6528F0 +#define FUNC_GetNearestCarPassengerDoor 0x650BB0 +#define FUNC_ComputeTargetDoorToExit 0x64F110 +#define FUNC_IsRoomForPedToLeaveCar 0x6504C0 +#define FUNC_GetPositionToOpenCarDoor 0x64E740 class CCarEnterExitSA : public CCarEnterExit { diff --git a/Client/game_sa/CCheckpointSA.cpp b/Client/game_sa/CCheckpointSA.cpp index fa1fc40aa74..3952621b853 100644 --- a/Client/game_sa/CCheckpointSA.cpp +++ b/Client/game_sa/CCheckpointSA.cpp @@ -153,19 +153,28 @@ static void __cdecl RenderTargetArrow(CCheckpointSAInterface* pCheckpoint) CVector* direction = checkpoint->GetPointDirection(); SColor color = checkpoint->GetTargetArrowColor(); - ((void(__cdecl*)(float, float, float, float, std::uint8_t, std::uint8_t, std::uint8_t, std::uint8_t, float, float, float))C3dMarkers_DirectionArrowSet)(position->fX, position->fY, position->fZ, checkpoint->GetTargetArrowSize(), color.R, color.G, color.B, color.A, -direction->fX, -direction->fY, -direction->fZ); + ((void(__cdecl*)(float, float, float, float, std::uint8_t, std::uint8_t, std::uint8_t, std::uint8_t, float, float, float))C3dMarkers_DirectionArrowSet)( + position->fX, position->fY, position->fZ, checkpoint->GetTargetArrowSize(), color.R, color.G, color.B, color.A, -direction->fX, -direction->fY, + -direction->fZ); } -static void _declspec(naked) HOOK_CCheckpoint__Render() +#define HOOKPOS_CCheckpoint__Render 0x725E56 +#define HOOKSIZE_CCheckpoint__Render 5 +static constexpr intptr_t RETURN_CCheckpoint__Render = 0x725E5B; +static void __declspec(naked) HOOK_CCheckpoint__Render() { - _asm { - pushad - push esi - call RenderTargetArrow - add esp, 4 - popad + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + push esi + call RenderTargetArrow + add esp, 4 + jmp RETURN_CCheckpoint__Render } + // clang-format on } void CCheckpointSA::StaticSetHooks() diff --git a/Client/game_sa/CCheckpointSA.h b/Client/game_sa/CCheckpointSA.h index 9e6a3931195..454baa6cc35 100644 --- a/Client/game_sa/CCheckpointSA.h +++ b/Client/game_sa/CCheckpointSA.h @@ -14,10 +14,6 @@ #include #include -#define HOOKPOS_CCheckpoint__Render 0x725E56 -#define HOOKSIZE_CCheckpoint__Render 0x5 -static constexpr std::uint32_t RETURN_CCheckpoint__Render = 0x725E5B; - #define C3dMarkers_DirectionArrowSet 0x721140 class CCheckpointSAInterface @@ -29,7 +25,7 @@ class CCheckpointSAInterface DWORD m_nIdentifier; DWORD rwColour; WORD m_nPulsePeriod; - short m_nRotateRate; // deg per frame (in either direction) + short m_nRotateRate; // deg per frame (in either direction) CVector m_pos; CVector m_pointDir; float m_fPulseFraction; @@ -56,8 +52,8 @@ class CCheckpointSA : public CCheckpoint CVector* GetPosition(); void SetPointDirection(CVector* vecPointDirection); CVector* GetPointDirection(); - DWORD GetType(); // need enum? - void SetType(WORD wType); // doesn't work propperly (not virtualed) + DWORD GetType(); // need enum? + void SetType(WORD wType); // doesn't work propperly (not virtualed) bool IsActive(); void Activate(); DWORD GetIdentifier(); @@ -69,7 +65,7 @@ class CCheckpointSA : public CCheckpoint float GetSize(); void SetSize(float fSize); void SetCameraRange(float fCameraRange); - void SetPulseFraction(float fPulseFraction); // doesn't work propperly (not virtualed) + void SetPulseFraction(float fPulseFraction); // doesn't work propperly (not virtualed) float GetPulseFraction(); void Remove(); SColor GetTargetArrowColor() const noexcept override { return m_targetArrowColor; }; diff --git a/Client/game_sa/CCheckpointsSA.h b/Client/game_sa/CCheckpointsSA.h index b8f44914bf2..d1cfa913a62 100644 --- a/Client/game_sa/CCheckpointsSA.h +++ b/Client/game_sa/CCheckpointsSA.h @@ -18,10 +18,10 @@ class CVector; // 00722c40 public: static class CCheckpoint * __cdecl CCheckpoints::PlaceMarker(unsigned int,unsigned short,class CVector &,class CVector &,float,unsigned // char,unsigned char,unsigned char,unsigned char,unsigned short,float,short) -#define FUNC_CCheckpoints__PlaceMarker 0x722c40 +#define FUNC_CCheckpoints__PlaceMarker 0x722c40 -#define MAX_CHECKPOINTS 32 -#define ARRAY_CHECKPOINTS 0xC7F158 +#define MAX_CHECKPOINTS 32 +#define ARRAY_CHECKPOINTS 0xC7F158 class CCheckpointsSA : public CCheckpoints { diff --git a/Client/game_sa/CClockSA.cpp b/Client/game_sa/CClockSA.cpp index a197b8151f9..e6a26ad67dc 100644 --- a/Client/game_sa/CClockSA.cpp +++ b/Client/game_sa/CClockSA.cpp @@ -33,10 +33,11 @@ void CClockSA::Get(BYTE* bHour, BYTE* bMinute) bool CClockSA::SetTimeFrozen(bool value) noexcept { - if (value) + if (value) { MemSet((void*)0x53BFBD, 0x90, 5); - else + } else { MemCpy((void*)0x53BFBD, "\xE8\x4E\x0F\xFF\xFF", 5); +} m_bTimeCycleFrozen = value; return true; diff --git a/Client/game_sa/CClockSA.h b/Client/game_sa/CClockSA.h index 44d0cf5c840..b7d128cef17 100644 --- a/Client/game_sa/CClockSA.h +++ b/Client/game_sa/CClockSA.h @@ -13,9 +13,9 @@ #include -#define VAR_TimeMinutes 0xB70152 -#define VAR_TimeHours 0xB70153 -#define VAR_TimeOfLastMinuteChange 0xB70158 +#define VAR_TimeMinutes 0xB70152 +#define VAR_TimeHours 0xB70153 +#define VAR_TimeOfLastMinuteChange 0xB70158 class CClockSA : public CClock { diff --git a/Client/game_sa/CColModelGuard.h b/Client/game_sa/CColModelGuard.h new file mode 100644 index 00000000000..6d029cc995b --- /dev/null +++ b/Client/game_sa/CColModelGuard.h @@ -0,0 +1,129 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CColModelGuard.h + * PURPOSE: Wrapper for collision model access with automatic reference counting + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include "CModelInfoSA.h" + +// Guard: Protects collision model from streaming GC +class CColModelGuard +{ +public: + // Increment ref count for pModelInfo's collision + explicit CColModelGuard(CModelInfoSA* pModelInfo) : m_pModelInfo(pModelInfo), m_bValid(false), m_pColModel(nullptr), m_pColData(nullptr) + { + if (!m_pModelInfo) + return; + + // Check and protect collision atomically + if (m_pModelInfo->IsCollisionLoaded()) + { + m_pModelInfo->AddColRef(); + bool bRefAdded = true; + + try + { + // Cache pointers while protected + CBaseModelInfoSAInterface* pInterface = m_pModelInfo->GetInterface(); + if (pInterface && pInterface->pColModel) + { + m_pColModel = pInterface->pColModel; + m_pColData = m_pColModel->m_data; + m_bValid = (m_pColData != nullptr); + } + + // Release ref if validation failed + if (!m_bValid) + { + m_pModelInfo->RemoveColRef(); + bRefAdded = false; + } + } + catch (...) + { + // Release reference on exception + if (bRefAdded) + m_pModelInfo->RemoveColRef(); + throw; + } + + // Prevent double-release in destructor + if (!bRefAdded) + m_pModelInfo = nullptr; + } + } + + // Decrement ref count on destruction + ~CColModelGuard() noexcept + { + if (m_bValid && m_pModelInfo) + { + m_pModelInfo->RemoveColRef(); + } + } + + // Prevent copying + CColModelGuard(const CColModelGuard&) = delete; + CColModelGuard& operator=(const CColModelGuard&) = delete; + + // Allow moving + CColModelGuard(CColModelGuard&& other) noexcept + : m_pModelInfo(other.m_pModelInfo), m_bValid(other.m_bValid), m_pColModel(other.m_pColModel), m_pColData(other.m_pColData) + { + // Transfer ownership + other.m_pModelInfo = nullptr; + other.m_bValid = false; + other.m_pColModel = nullptr; + other.m_pColData = nullptr; + } + + CColModelGuard& operator=(CColModelGuard&& other) noexcept + { + if (this != &other) + { + // Release current, transfer from source + if (m_bValid && m_pModelInfo) + m_pModelInfo->RemoveColRef(); + + // Transfer ownership from source + m_pModelInfo = other.m_pModelInfo; + m_bValid = other.m_bValid; + m_pColModel = other.m_pColModel; + m_pColData = other.m_pColData; + + // Prevent double-release + other.m_pModelInfo = nullptr; + other.m_bValid = false; + other.m_pColModel = nullptr; + other.m_pColData = nullptr; + } + return *this; + } + + // Check if collision is protected + [[nodiscard]] bool IsValid() const noexcept { return m_bValid; } + + // Get collision data (check IsValid first) + // Returns cached pointer or nullptr + [[nodiscard]] CColDataSA* GetColData() const noexcept { return m_bValid ? m_pColData : nullptr; } + + // Get collision model (check IsValid first) + // Returns cached pointer or nullptr + [[nodiscard]] CColModelSAInterface* GetColModel() const noexcept { return m_bValid ? m_pColModel : nullptr; } + + explicit operator bool() const noexcept { return m_bValid; } + +private: + CModelInfoSA* m_pModelInfo; + bool m_bValid; + CColModelSAInterface* m_pColModel; // Cached during construction + CColDataSA* m_pColData; // Cached during construction +}; diff --git a/Client/game_sa/CColModelSA.cpp b/Client/game_sa/CColModelSA.cpp index 50da43f76e0..53b5a3da787 100644 --- a/Client/game_sa/CColModelSA.cpp +++ b/Client/game_sa/CColModelSA.cpp @@ -12,36 +12,92 @@ #include "StdInc.h" #include "CColModelSA.h" -CColModelSA::CColModelSA() +#include + +namespace { - m_pInterface = new CColModelSAInterface; - DWORD dwThis = (DWORD)m_pInterface; - DWORD dwFunc = FUNC_CColModel_Constructor; - _asm + bool CallNativeColModelConstructor(CColModelSAInterface* pInterface) noexcept { - mov ecx, dwThis - call dwFunc + if (!pInterface) + return false; + + uintptr_t dwThis = reinterpret_cast(pInterface); + DWORD dwFunc = FUNC_CColModel_Constructor; + + __try + { + // clang-format off + __asm + { + mov ecx, dwThis + call dwFunc + } + // clang-format on + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + + return true; + } + + void CallNativeColModelDestructor(CColModelSAInterface* pInterface) noexcept + { + if (!pInterface) + return; + + uintptr_t dwThis = reinterpret_cast(pInterface); + DWORD dwFunc = FUNC_CColModel_Destructor; + + __try + { + // clang-format off + __asm + { + mov ecx, dwThis + call dwFunc + } + // clang-format on + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + } + } +} + +CColModelSA::CColModelSA() : m_pInterface(new CColModelSAInterface), m_bDestroyInterface(false), m_bValid(false) +{ + if (!CallNativeColModelConstructor(m_pInterface)) + { + delete m_pInterface; + m_pInterface = nullptr; + throw std::runtime_error("CColModelSA native constructor failed"); } m_bDestroyInterface = true; + m_bValid = true; } CColModelSA::CColModelSA(CColModelSAInterface* pInterface) { m_pInterface = pInterface; m_bDestroyInterface = false; + m_bValid = true; } CColModelSA::~CColModelSA() { - if (m_bDestroyInterface) + m_bValid = false; + + if (m_bDestroyInterface && m_pInterface) { - DWORD dwThis = (DWORD)m_pInterface; - DWORD dwFunc = FUNC_CColModel_Destructor; - _asm - { - mov ecx, dwThis - call dwFunc - } + CallNativeColModelDestructor(m_pInterface); delete m_pInterface; + m_pInterface = nullptr; } } + +void CColModelSA::Destroy() +{ + delete this; +} diff --git a/Client/game_sa/CColModelSA.h b/Client/game_sa/CColModelSA.h index fe334ae3db0..c655085ed13 100644 --- a/Client/game_sa/CColModelSA.h +++ b/Client/game_sa/CColModelSA.h @@ -16,8 +16,8 @@ #include #include "CCompressedVectorSA.h" -#define FUNC_CColModel_Constructor 0x40FB60 -#define FUNC_CColModel_Destructor 0x40F700 +#define FUNC_CColModel_Constructor 0x40FB60 +#define FUNC_CColModel_Destructor 0x40F700 struct CBoxSA { @@ -65,6 +65,9 @@ struct CSphereSA { CVector m_center; float m_radius; + + // Validate radius is finite and non-negative + bool IsValidRadius() const { return std::isfinite(m_radius) && m_radius >= 0.0f && m_radius < 1000000.0f; } }; static_assert(sizeof(CSphereSA) == 0x10, "Invalid size for CSphereSA"); @@ -97,10 +100,10 @@ struct CColSphereSA : CSphereSA std::uint8_t m_light{}; CColSphereSA() = default; - CColSphereSA(const CSphereSA& sp) : - CSphereSA{ sp } - { - } + CColSphereSA(const CSphereSA& sp) : CSphereSA{sp} {} + + // Validate material enum is in valid range + bool IsValidMaterial() const { return static_cast(m_material) < static_cast(EColSurfaceValue::SIZE); } }; static_assert(sizeof(CColSphereSA) == 0x14, "Invalid size for CColSphereSA"); @@ -109,6 +112,12 @@ struct CColTriangleSA std::uint16_t m_indices[3]; EColSurface m_material; CColLighting m_lighting; + + // Validate material enum is in valid range + bool IsValidMaterial() const { return static_cast(m_material) < static_cast(EColSurfaceValue::SIZE); } + + // Validate indices are within vertex count bounds + bool IsValidIndices(std::uint16_t numVertices) const { return m_indices[0] < numVertices && m_indices[1] < numVertices && m_indices[2] < numVertices; } }; static_assert(sizeof(CColTriangleSA) == 0x8, "Invalid size for CColTriangleSA"); @@ -178,10 +187,12 @@ class CColModelSA : public CColModel CColModelSA(CColModelSAInterface* pInterface); ~CColModelSA(); - CColModelSAInterface* GetInterface() override { return m_pInterface; } - void Destroy() override { delete this; } + CColModelSAInterface* GetInterface() override { return m_bValid ? m_pInterface : nullptr; } + void Destroy() override; + bool IsValid() const { return m_bValid; } private: CColModelSAInterface* m_pInterface; bool m_bDestroyInterface; + bool m_bValid; }; diff --git a/Client/game_sa/CColPointSA.h b/Client/game_sa/CColPointSA.h index 247e0e5c258..e2ab73ab304 100644 --- a/Client/game_sa/CColPointSA.h +++ b/Client/game_sa/CColPointSA.h @@ -17,19 +17,19 @@ class CColPointSAInterface { public: - CVector Position; // 0 - float fUnknown1; // 12 - CVector Normal; // 16 - float fUnknown2; // 28 - EColSurface ucSurfaceTypeA; // 32 - uint8 ucPieceTypeA; // 33 - CColLighting lightingA; // 34 - EColSurface ucSurfaceTypeB; // 35 - uint8 ucPieceTypeB; // 36 - CColLighting lightingB; // 37 - uint8 pad1; // 38 - uint8 pad2; // 39 - float fDepth; // 40 + CVector Position; // 0 + float fUnknown1; // 12 + CVector Normal; // 16 + float fUnknown2; // 28 + EColSurface ucSurfaceTypeA; // 32 + uint8 ucPieceTypeA; // 33 + CColLighting lightingA; // 34 + EColSurface ucSurfaceTypeB; // 35 + uint8 ucPieceTypeB; // 36 + CColLighting lightingB; // 37 + uint8 pad1; // 38 + uint8 pad2; // 39 + float fDepth; // 40 }; static_assert(sizeof(CColPointSAInterface) == 0x2C, "Invalid size for CColPointSAInterface"); diff --git a/Client/game_sa/CColStoreSA.cpp b/Client/game_sa/CColStoreSA.cpp index 36614fb4e03..436399e0bc2 100644 --- a/Client/game_sa/CColStoreSA.cpp +++ b/Client/game_sa/CColStoreSA.cpp @@ -10,6 +10,9 @@ #include "StdInc.h" #include "CColStoreSA.h" +#include "CGameSA.h" + +extern CGameSA* pGame; void CColStoreSA::Initialise() { @@ -41,9 +44,11 @@ int CColStoreSA::AddColSlot(const char* name) bool CColStoreSA::IsValidSlot(CollisionSlot slot) { - using Signature = bool(__cdecl*)(CollisionSlot); + // Native signature: bool __cdecl sub_410660(int a1) + // Must use int to match GTA SA's ABI - it reads a full DWORD from stack + using Signature = bool(__cdecl*)(int); const auto function = reinterpret_cast(0x410660); - return function(slot); + return function(static_cast(slot)); } void CColStoreSA::AddCollisionNeededAtPosition(const CVector& position) @@ -55,6 +60,22 @@ void CColStoreSA::AddCollisionNeededAtPosition(const CVector& position) void CColStoreSA::EnsureCollisionIsInMemory(const CVector& position) { + // Wait for GTA to complete initialization before calling collision functions + // Race condition: MTA can trigger streaming/collision operations before GTA completes initialization. + // GTA calls CTimer::Initialise at 0x53BDE6 during startup, which sets _timerFunction at 0x56189E. + // If called before GTA reaches GS_INIT_PLAYING_GAME, the timer isn't initialized > crash at 0x5619E9 (CTimer::Suspend) + + if (!pGame || pGame->GetSystemState() < SystemState::GS_INIT_PLAYING_GAME) + return; // GTA not ready yet - skip (will retry on next streaming update) + + // Just in case + constexpr auto ADDR_timerFunction = 0xB7CB28; + const auto timerFunction = *reinterpret_cast(ADDR_timerFunction); + if (!timerFunction) + return; // Timer not initialized yet - skip + + // SA function signature: void __cdecl CColStore::EnsureCollisionIsInMemory(const CVector2D&) + // CVector implicitly converts to CVector2D (uses x, y components only) using Signature = void(__cdecl*)(const CVector&); const auto function = reinterpret_cast(0x410AD0); function(position); @@ -90,30 +111,36 @@ void CColStoreSA::RemoveAllCollision() void CColStoreSA::AddRef(CollisionSlot slot) { - using Signature = void(__cdecl*)(CollisionSlot); + // Native signature: void __cdecl CColStore::AddRef(int) + // Must use int to match GTA SA's ABI - it reads a full DWORD from stack + using Signature = void(__cdecl*)(int); const auto function = reinterpret_cast(0x4107A0); - function(slot); + function(static_cast(slot)); } void CColStoreSA::RemoveRef(CollisionSlot slot) { - using Signature = void(__cdecl*)(CollisionSlot); + // Native signature: void __cdecl CColStore::RemoveRef(int) + // Must use int to match GTA SA's ABI - it reads a full DWORD from stack + using Signature = void(__cdecl*)(int); const auto function = reinterpret_cast(0x4107D0); - function(slot); + function(static_cast(slot)); } void CColStoreSA::RemoveCol(CollisionSlot slot) { - using Signature = void(__cdecl*)(CollisionSlot); + // Native expects int parameter + using Signature = void(__cdecl*)(int); const auto function = reinterpret_cast(0x410730); - function(slot); + function(static_cast(slot)); } void CColStoreSA::RemoveColSlot(CollisionSlot slot) { - using Signature = void(__cdecl*)(CollisionSlot); + // Native expects int parameter + using Signature = void(__cdecl*)(int); const auto function = reinterpret_cast(0x411330); - function(slot); + function(static_cast(slot)); } void CColStoreSA::LoadAllBoundingBoxes() @@ -125,28 +152,32 @@ void CColStoreSA::LoadAllBoundingBoxes() CColStore::BoundingBox CColStoreSA::GetBoundingBox(CollisionSlot slot) { - using Signature = BoundingBox&(__cdecl*)(CollisionSlot); + // Native expects int parameter + using Signature = BoundingBox&(__cdecl*)(int); const auto function = reinterpret_cast(0x410800); - return function(slot); + return function(static_cast(slot)); } void CColStoreSA::IncludeModelIndex(CollisionSlot slot, std::uint16_t model) { - using Signature = void(__cdecl*)(CollisionSlot, int); + // Native expects int parameters + using Signature = void(__cdecl*)(int, int); const auto function = reinterpret_cast(0x410820); - function(slot, model); + function(static_cast(slot), static_cast(model)); } int CColStoreSA::GetFirstModel(CollisionSlot slot) { - using Signature = int(__cdecl*)(CollisionSlot); + // Native expects int parameter + using Signature = int(__cdecl*)(int); const auto function = reinterpret_cast(0x537A80); - return function(slot); + return function(static_cast(slot)); } int CColStoreSA::GetLastModel(CollisionSlot slot) { - using Signature = int(__cdecl*)(CollisionSlot); + // Native expects int parameter + using Signature = int(__cdecl*)(int); const auto function = reinterpret_cast(0x537AB0); - return function(slot); + return function(static_cast(slot)); } diff --git a/Client/game_sa/CCollisionSA.h b/Client/game_sa/CCollisionSA.h index e17a8f97dff..97209b3dd0a 100644 --- a/Client/game_sa/CCollisionSA.h +++ b/Client/game_sa/CCollisionSA.h @@ -13,7 +13,8 @@ #include "game/CCollision.h" -class CCollisionSA : CCollision { +class CCollisionSA : CCollision +{ public: bool TestLineSphere(const CColLineSA& line, const CColSphereSA& sphere) const override; }; diff --git a/Client/game_sa/CControllerConfigManagerSA.cpp b/Client/game_sa/CControllerConfigManagerSA.cpp index 95ea7431bc8..0786f65c4fe 100644 --- a/Client/game_sa/CControllerConfigManagerSA.cpp +++ b/Client/game_sa/CControllerConfigManagerSA.cpp @@ -12,11 +12,12 @@ #include "StdInc.h" #include "CControllerConfigManagerSA.h" -#define VAR_InputType ( ( BYTE * ) ( 0xB6EC2E ) ) -#define VAR_MouseInverted ( ( BYTE * ) ( 0xBA6745 ) ) -#define VAR_FlyWithMouse ( ( BYTE * ) ( 0xC1CC03 ) ) -#define VAR_SteerWithMouse ( ( BYTE * ) ( 0xC1CC02 ) ) -#define VAR_VerticalAimSensitivity ( ( float * ) ( 0xB6EC18 ) ) +#define VAR_InputType ((BYTE*)(0xB6EC2E)) +#define VAR_MouseInverted ((BYTE*)(0xBA6745)) +#define VAR_FlyWithMouse ((BYTE*)(0xC1CC03)) +#define VAR_SteerWithMouse ((BYTE*)(0xC1CC02)) +#define VAR_VerticalAimSensitivity ((float*)(0xB6EC18)) +#define VAR_HorizontalMouseSensitivity 0xB6EC1C static const float VERTICAL_AIM_SENSITIVITY_MIN = 0.000312f; static const float VERTICAL_AIM_SENSITIVITY_DEFAULT = 0.0015f; @@ -28,34 +29,26 @@ CControllerConfigManagerSA::CControllerConfigManagerSA() // Get initial settings m_bSteerWithMouse = *VAR_FlyWithMouse != 0; m_bFlyWithMouse = *VAR_SteerWithMouse != 0; - MemSet((void*)0x5BC7B4, 0x90, 10); // Stop vertical aim sensitivity value reset + MemSet((void*)0x5BC7B4, 0x90, 10); // Stop vertical aim sensitivity value reset } void CControllerConfigManagerSA::SetControllerKeyAssociatedWithAction(eControllerAction action, int iKey, eControllerType controllerType) { DWORD dwFunc = FUNC_SetControllerKeyAssociatedWithAction; - _asm - { - mov ecx, CLASS_CControllerConfigManager - push controllerType - push iKey - push action - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB70198), decltype(action), decltype(iKey), decltype(controllerType)); + reinterpret_cast(dwFunc)(0xB70198, action, iKey, controllerType); + // clang-format on } int CControllerConfigManagerSA::GetControllerKeyAssociatedWithAction(eControllerAction action, eControllerType controllerType) { int iReturn = 0; DWORD dwFunc = FUNC_GetControllerKeyAssociatedWithAction; - _asm - { - mov ecx, CLASS_CControllerConfigManager - push controllerType - push action - call dwFunc - mov iReturn, eax - } + // clang-format off + using func_t = decltype(iReturn) (__thiscall*)(decltype(0xB70198), decltype(action), decltype(controllerType)); +iReturn = reinterpret_cast(dwFunc)(0xB70198, action, controllerType); + // clang-format on return iReturn; } @@ -63,26 +56,20 @@ int CControllerConfigManagerSA::GetNumOfSettingsForAction(eControllerAction acti { int iReturn = 0; DWORD dwFunc = FUNC_GetNumOfSettingsForAction; - _asm - { - mov ecx, CLASS_CControllerConfigManager - push action - call dwFunc - mov iReturn, eax - } + // clang-format off + using func_t = decltype(iReturn) (__thiscall*)(decltype(0xB70198), decltype(action)); +iReturn = reinterpret_cast(dwFunc)(0xB70198, action); + // clang-format on return iReturn; } void CControllerConfigManagerSA::ClearSettingsAssociatedWithAction(eControllerAction action, eControllerType controllerType) { DWORD dwFunc = FUNC_ClearSettingsAssociatedWithAction; - _asm - { - mov ecx, CLASS_CControllerConfigManager - push controllerType - push action - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB70198), decltype(action), decltype(controllerType)); + reinterpret_cast(dwFunc)(0xB70198, action, controllerType); + // clang-format on } void CControllerConfigManagerSA::SetClassicControls(bool bClassicControls) @@ -130,7 +117,7 @@ void CControllerConfigManagerSA::ApplySteerAndFlyWithMouseSettings() float CControllerConfigManagerSA::GetVerticalAimSensitivity() { float fRawValue = GetVerticalAimSensitivityRawValue(); - return UnlerpClamped(VERTICAL_AIM_SENSITIVITY_MIN, fRawValue, VERTICAL_AIM_SENSITIVITY_MAX); // Remap to 0-1 + return UnlerpClamped(VERTICAL_AIM_SENSITIVITY_MIN, fRawValue, VERTICAL_AIM_SENSITIVITY_MAX); // Remap to 0-1 } void CControllerConfigManagerSA::SetVerticalAimSensitivity(float fSensitivity) @@ -149,3 +136,14 @@ void CControllerConfigManagerSA::SetVerticalAimSensitivityRawValue(float fRawVal { MemPutFast(VAR_VerticalAimSensitivity, fRawValue); } + +void CControllerConfigManagerSA::SetVerticalAimSensitivitySameAsHorizontal(bool enabled) +{ + std::uintptr_t varToUse = enabled ? VAR_HorizontalMouseSensitivity : reinterpret_cast(VAR_VerticalAimSensitivity); + + MemPut(0x50F048, varToUse); // CCam::Process_1rstPersonPedOnPC + MemPut(0x50FB28, varToUse); // CCam::Process_FollowPedWithMouse + MemPut(0x510C28, varToUse); // CCam::Process_M16_1stPerson + MemPut(0x511E0A, varToUse); // CCam::Process_Rocket + MemPut(0x52228E, varToUse); // CCam::Process_AimWeapon +} diff --git a/Client/game_sa/CControllerConfigManagerSA.h b/Client/game_sa/CControllerConfigManagerSA.h index ef8236786b0..496f7a0718b 100644 --- a/Client/game_sa/CControllerConfigManagerSA.h +++ b/Client/game_sa/CControllerConfigManagerSA.h @@ -13,12 +13,12 @@ #include -#define FUNC_SetControllerKeyAssociatedWithAction 0x530490 -#define FUNC_GetControllerKeyAssociatedWithAction 0x52F4F0 -#define FUNC_GetNumOfSettingsForAction 0x52F4A0 -#define FUNC_ClearSettingsAssociatedWithAction 0x52FD70 +#define FUNC_SetControllerKeyAssociatedWithAction 0x530490 +#define FUNC_GetControllerKeyAssociatedWithAction 0x52F4F0 +#define FUNC_GetNumOfSettingsForAction 0x52F4A0 +#define FUNC_ClearSettingsAssociatedWithAction 0x52FD70 -#define CLASS_CControllerConfigManager 0xB70198 +#define CLASS_CControllerConfigManager 0xB70198 class CControllerConfigManagerSA : public CControllerConfigManager { @@ -37,6 +37,7 @@ class CControllerConfigManagerSA : public CControllerConfigManager void SetVerticalAimSensitivity(float fSensitivity); float GetVerticalAimSensitivityRawValue(); void SetVerticalAimSensitivityRawValue(float fRawValue); + void SetVerticalAimSensitivitySameAsHorizontal(bool enabled) override; // CControllerConfigManagerSA void ApplySteerAndFlyWithMouseSettings(); diff --git a/Client/game_sa/CCoronasSA.cpp b/Client/game_sa/CCoronasSA.cpp index e1907f6a912..a908bcf7b41 100644 --- a/Client/game_sa/CCoronasSA.cpp +++ b/Client/game_sa/CCoronasSA.cpp @@ -83,10 +83,22 @@ CRegisteredCorona* CCoronasSA::FindCorona(DWORD Identifier) RwTexture* CCoronasSA::GetTexture(CoronaType type) { - if ((DWORD)type < MAX_CORONA_TEXTURES) - return (RwTexture*)(*(DWORD*)(ARRAY_CORONA_TEXTURES + static_cast(type) * sizeof(DWORD))); - else - return NULL; + // Validate enum is within valid range + if (static_cast(type) >= MAX_CORONA_TEXTURES) [[unlikely]] + return nullptr; + + // Read texture pointer from array with validation + DWORD* pTextureArray = reinterpret_cast(ARRAY_CORONA_TEXTURES); + if (!pTextureArray) [[unlikely]] + return nullptr; + + DWORD textureAddr = pTextureArray[static_cast(type)]; + if (!textureAddr) [[unlikely]] + return nullptr; + + RwTexture* pTexture = reinterpret_cast(textureAddr); + + return pTexture; } void CCoronasSA::DisableSunAndMoon(bool bDisabled) diff --git a/Client/game_sa/CCoronasSA.h b/Client/game_sa/CCoronasSA.h index e0e3297d1b4..3a5e039f611 100644 --- a/Client/game_sa/CCoronasSA.h +++ b/Client/game_sa/CCoronasSA.h @@ -18,12 +18,12 @@ class CRegisteredCorona; class CRegisteredCoronaSA; struct RwTexture; -#define FUNC_DoSunAndMoon 0x6FC5A0 +#define FUNC_DoSunAndMoon 0x6FC5A0 -#define MAX_CORONAS 64 -#define MAX_CORONA_TEXTURES 9 -#define ARRAY_CORONAS 0xC3E058 // also in CRegisteredCoronasSA.h -#define ARRAY_CORONA_TEXTURES 0xC3E000 +#define MAX_CORONAS 64 +#define MAX_CORONA_TEXTURES 9 +#define ARRAY_CORONAS 0xC3E058 // also in CRegisteredCoronasSA.h +#define ARRAY_CORONA_TEXTURES 0xC3E000 class CCoronasSA : public CCoronas { diff --git a/Client/game_sa/CDamageManagerSA.cpp b/Client/game_sa/CDamageManagerSA.cpp index b269744ffc5..ba1c9ba2522 100644 --- a/Client/game_sa/CDamageManagerSA.cpp +++ b/Client/game_sa/CDamageManagerSA.cpp @@ -53,13 +53,10 @@ void CDamageManagerSA::SetDoorStatus(eDoors bDoor, BYTE bDoorStatus, bool spawnF DWORD dwThis = (DWORD)internalEntityInterface; int iCarNodeIndex = s_iCarNodeIndexes[bDoor]; DWORD dwDoor = (DWORD)bDoor; - _asm - { - mov ecx, dwThis - push dwDoor - push iCarNodeIndex - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(iCarNodeIndex), decltype(dwDoor)); + reinterpret_cast(dwFunc)(dwThis, iCarNodeIndex, dwDoor); + // clang-format on } else { @@ -68,13 +65,10 @@ void CDamageManagerSA::SetDoorStatus(eDoors bDoor, BYTE bDoorStatus, bool spawnF DWORD dwThis = (DWORD)internalEntityInterface; DWORD dwDoor = (DWORD)bDoor; bool bQuiet = !spawnFlyingComponent; - _asm - { - mov ecx, dwThis - push bQuiet - push dwDoor - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwDoor), decltype(bQuiet)); + reinterpret_cast(dwFunc)(dwThis, dwDoor, bQuiet); + // clang-format on } } } @@ -112,13 +106,10 @@ void CDamageManagerSA::SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawn DWORD dwThis = (DWORD)internalInterface; DWORD dwPanel = bPanel; DWORD dwStatus = bPanelStatus; - _asm - { - mov ecx, dwThis - push dwStatus - push dwPanel - call dwFunction - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwPanel), decltype(dwStatus)); + reinterpret_cast(dwFunction)(dwThis, dwPanel, dwStatus); + // clang-format on // Intact? if (bPanelStatus == DT_PANEL_INTACT) @@ -130,27 +121,23 @@ void CDamageManagerSA::SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawn if (carNodeIndex < 0) return; - _asm - { - mov ecx, dwThis - push dwPanel - push carNodeIndex - call dwFunction - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(carNodeIndex), decltype(dwPanel)); + reinterpret_cast(dwFunction)(dwThis, carNodeIndex, dwPanel); + // clang-format on } - else - reinterpret_cast(internalEntityInterface)->SetPanelDamage(dwPanel, breakGlass, spawnFlyingComponent); + else { reinterpret_cast(internalEntityInterface)->SetPanelDamage(bPanel, breakGlass, spawnFlyingComponent); +} } } } void CDamageManagerSA::SetPanelStatus(unsigned long ulStatus, bool spawnFlyingComponent, bool breakGlass) { - unsigned int uiIndex; - - for (uiIndex = 0; uiIndex < MAX_PANELS; uiIndex++) + for (unsigned int uiIndex = 0; uiIndex < MAX_PANELS; ++uiIndex) { - SetPanelStatus(static_cast(uiIndex), static_cast(ulStatus), spawnFlyingComponent, breakGlass); + const BYTE bPanelStatus = static_cast(ulStatus & 0x0F); + SetPanelStatus(static_cast(uiIndex), bPanelStatus, spawnFlyingComponent, breakGlass); ulStatus >>= 4; } } @@ -171,13 +158,10 @@ void CDamageManagerSA::SetLightStatus(BYTE bLight, BYTE bLightStatus) DWORD dwPointer = (DWORD)internalInterface; DWORD dwLight = bLight; DWORD dwStatus = bLightStatus; - _asm - { - mov ecx, dwPointer - push dwStatus - push dwLight - call dwFunction - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwPointer), decltype(dwLight), decltype(dwStatus)); + reinterpret_cast(dwFunction)(dwPointer, dwLight, dwStatus); + // clang-format on } void CDamageManagerSA::SetLightStatus(unsigned char ucStatus) @@ -191,13 +175,10 @@ BYTE CDamageManagerSA::GetLightStatus(BYTE bLight) DWORD dwPointer = (DWORD)internalInterface; BYTE bReturn = 0; DWORD dwLight = bLight; - _asm - { - mov ecx, dwPointer - push dwLight - call dwFunction - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwPointer), decltype(dwLight)); +bReturn = reinterpret_cast(dwFunction)(dwPointer, dwLight); + // clang-format on return bReturn; } @@ -211,13 +192,10 @@ void CDamageManagerSA::SetAeroplaneCompStatus(BYTE CompID, BYTE Status) DWORD dwFunction = FUNC_SetAeroplaneCompStatus; DWORD dwPointer = (DWORD)internalInterface; DWORD dwPannel = CompID; - _asm - { - mov ecx, dwPointer - push Status - push dwPannel - call dwFunction - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwPointer), decltype(dwPannel), decltype(Status)); + reinterpret_cast(dwFunction)(dwPointer, dwPannel, Status); + // clang-format on } BYTE CDamageManagerSA::GetAeroplaneCompStatus(BYTE CompID) @@ -226,13 +204,10 @@ BYTE CDamageManagerSA::GetAeroplaneCompStatus(BYTE CompID) DWORD dwPointer = (DWORD)internalInterface; BYTE bReturn = 0; DWORD dwPannel = CompID; - _asm - { - mov ecx, dwPointer - push dwPannel - call dwFunction - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwPointer), decltype(dwPannel)); +bReturn = reinterpret_cast(dwFunction)(dwPointer, dwPannel); + // clang-format on return bReturn; } @@ -240,12 +215,10 @@ void CDamageManagerSA::FuckCarCompletely(bool bKeepWheels) { DWORD dwFunc = FUNC_FuckCarCompletely; DWORD dwPointer = (DWORD)internalInterface; - _asm - { - mov ecx, dwPointer - push bKeepWheels - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwPointer), decltype(bKeepWheels)); + reinterpret_cast(dwFunc)(dwPointer, bKeepWheels); + // clang-format on } int CDamageManagerSA::GetCarNodeIndexFromPanel(std::uint8_t panelId) noexcept @@ -255,19 +228,19 @@ int CDamageManagerSA::GetCarNodeIndexFromPanel(std::uint8_t panelId) noexcept switch (panelId) { case 0: - index = 15; // PANEL_WING_LF + index = 15; // PANEL_WING_LF break; case 1: - index = 14; // PANEL_WING_RF + index = 14; // PANEL_WING_RF break; case 4: - index = 18; // PANEL_WINDSCREEN + index = 18; // PANEL_WINDSCREEN break; case 5: - index = 12; // BUMP_FRONT + index = 12; // BUMP_FRONT break; case 6: - index = 13; // BUMP_REAR + index = 13; // BUMP_REAR break; } diff --git a/Client/game_sa/CDamageManagerSA.h b/Client/game_sa/CDamageManagerSA.h index cf1b66bc1a8..cccaf35f143 100644 --- a/Client/game_sa/CDamageManagerSA.h +++ b/Client/game_sa/CDamageManagerSA.h @@ -21,10 +21,10 @@ #define FUNC_GetAeroplaneCompStatus 0x6C2300 #define FUNC_FuckCarCompletely 0x6c25d0 -#define MAX_DOORS 6 // also in CAutomobile -#define MAX_WHEELS 4 +#define MAX_DOORS 6 // also in CAutomobile +#define MAX_WHEELS 4 -class CDamageManagerSAInterface // 28 bytes due to the way its packed (24 containing actual data) +class CDamageManagerSAInterface // 28 bytes due to the way its packed (24 containing actual data) { public: std::uint8_t GetPanelStatus(std::uint8_t panelId) @@ -36,11 +36,11 @@ class CDamageManagerSAInterface // 28 bytes due to the way its packed } float fWheelDamageEffect; - BYTE bEngineStatus; // old - wont be used + BYTE bEngineStatus; // old - wont be used BYTE Wheel[MAX_WHEELS]; BYTE Door[MAX_DOORS]; - DWORD Lights; // 2 bits per light - DWORD Panels; // 4 bits per panel + DWORD Lights; // 2 bits per light + DWORD Panels; // 4 bits per panel }; static_assert(sizeof(CDamageManagerSAInterface) == 0x18, "Invalid size for CDamageManagerSAInterface"); diff --git a/Client/game_sa/CDirectorySA.cpp b/Client/game_sa/CDirectorySA.cpp index 97b9c910e80..d2d4fdbcb78 100644 --- a/Client/game_sa/CDirectorySA.cpp +++ b/Client/game_sa/CDirectorySA.cpp @@ -37,14 +37,21 @@ bool CDirectorySAInterface::RemoveEntry(const char* fileName) if (m_numEntries == 0) return false; + if (m_entries == nullptr) + return false; + DirectoryInfoSA* entry = GetModelEntry(fileName); if (!entry) return false; - std::ptrdiff_t index = entry - m_entries; + const std::ptrdiff_t index = entry - m_entries; + if (index < 0 || static_cast(index) >= m_numEntries) + return false; + + const std::uint32_t uiIndex = static_cast(index); - if (index < m_numEntries - 1) + if (uiIndex < m_numEntries - 1) { DirectoryInfoSA* lastEntry = m_entries + m_numEntries - 1; entry->m_offset = lastEntry->m_offset + lastEntry->m_sizeInArchive; @@ -52,8 +59,8 @@ bool CDirectorySAInterface::RemoveEntry(const char* fileName) m_numEntries--; - if (index < m_numEntries) - std::memmove(entry, entry + 1, (m_numEntries - index) * sizeof(DirectoryInfoSA)); + if (uiIndex < m_numEntries) + std::memmove(entry, entry + 1, static_cast(m_numEntries - uiIndex) * sizeof(DirectoryInfoSA)); return true; } @@ -77,12 +84,13 @@ DirectoryInfoSA* CDirectorySAInterface::GetModelEntry(std::uint16_t modelId) if (m_numEntries == 0) return nullptr; - DirectoryInfoSA* entry = m_entries + modelId; + if (m_entries == nullptr) + return nullptr; - if (!entry) + if (modelId >= m_numEntries) return nullptr; - return entry; + return m_entries + modelId; } bool CDirectorySAInterface::SetModelStreamingSize(std::uint16_t modelId, std::uint16_t size) @@ -96,7 +104,6 @@ bool CDirectorySAInterface::SetModelStreamingSize(std::uint16_t modelId, std::ui return true; } - std::uint16_t CDirectorySAInterface::GetModelStreamingSize(std::uint16_t modelId) { DirectoryInfoSA* entry = GetModelEntry(modelId); diff --git a/Client/game_sa/CDirectorySA.h b/Client/game_sa/CDirectorySA.h index 49d8812145a..13e0f4e3d23 100644 --- a/Client/game_sa/CDirectorySA.h +++ b/Client/game_sa/CDirectorySA.h @@ -20,18 +20,18 @@ struct DirectoryInfoSA class CDirectorySAInterface { - public: - bool AddEntry(DirectoryInfoSA& entry); - bool RemoveEntry(const char* fileName); +public: + bool AddEntry(DirectoryInfoSA& entry); + bool RemoveEntry(const char* fileName); - DirectoryInfoSA* GetModelEntry(const char* fileName); - DirectoryInfoSA* GetModelEntry(std::uint16_t modelId); - bool SetModelStreamingSize(std::uint16_t modelId, std::uint16_t size); - std::uint16_t GetModelStreamingSize(std::uint16_t modelId); + DirectoryInfoSA* GetModelEntry(const char* fileName); + DirectoryInfoSA* GetModelEntry(std::uint16_t modelId); + bool SetModelStreamingSize(std::uint16_t modelId, std::uint16_t size); + std::uint16_t GetModelStreamingSize(std::uint16_t modelId); - private: - DirectoryInfoSA* m_entries{}; - std::uint32_t m_capacity{}; - std::uint32_t m_numEntries{}; - bool m_ownsEntries{}; +private: + DirectoryInfoSA* m_entries{}; + std::uint32_t m_capacity{}; + std::uint32_t m_numEntries{}; + bool m_ownsEntries{}; }; diff --git a/Client/game_sa/CDoorSA.cpp b/Client/game_sa/CDoorSA.cpp index adab92f7d85..25ebd5ea9cb 100644 --- a/Client/game_sa/CDoorSA.cpp +++ b/Client/game_sa/CDoorSA.cpp @@ -24,12 +24,14 @@ float CDoorSA::GetAngleOpenRatio() if (dwPointer != 0) { - _asm + // clang-format off + __asm { mov ecx, dwPointer call dwFunction fstp fReturn } + // clang-format on } return fReturn; @@ -47,12 +49,10 @@ bool CDoorSA::IsClosed() if (dwPointer != 0) { - _asm - { - mov ecx, dwPointer - call dwFunction - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwPointer) ); +bReturn = reinterpret_cast(dwFunction)(dwPointer); + // clang-format on } return bReturn; @@ -71,12 +71,10 @@ bool CDoorSA::IsFullyOpen() if (dwPointer != 0) { - _asm - { - mov ecx, dwPointer - call dwFunction - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwPointer) ); +bReturn = reinterpret_cast(dwFunction)(dwPointer); + // clang-format on } return bReturn; @@ -94,11 +92,9 @@ void CDoorSA::Open(float fOpenRatio) if (dwPointer != 0) { - _asm - { - mov ecx, dwPointer - push fOpenRatio - call dwFunction - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwPointer), decltype(fOpenRatio)); + reinterpret_cast(dwFunction)(dwPointer, fOpenRatio); + // clang-format on } } diff --git a/Client/game_sa/CDoorSA.h b/Client/game_sa/CDoorSA.h index 7286227d91e..33d0775c07e 100644 --- a/Client/game_sa/CDoorSA.h +++ b/Client/game_sa/CDoorSA.h @@ -13,10 +13,10 @@ #include -#define FUNC_GetAngleOpenRatio 0x6f47e0 -#define FUNC_IsClosed 0x6f4800 -#define FUNC_IsFullyOpen 0x6f4820 -#define FUNC_Open 0x6f4790 +#define FUNC_GetAngleOpenRatio 0x6f47e0 +#define FUNC_IsClosed 0x6f4800 +#define FUNC_IsFullyOpen 0x6f4820 +#define FUNC_Open 0x6f4790 class CDoorSAInterface { @@ -45,9 +45,9 @@ class CDoorSA : public CDoor void SetInterface(CDoorSAInterface* doorInterface) { internalInterface = doorInterface; } CDoorSAInterface* GetInterface() { return internalInterface; }; - float GetAngleOpenRatio(); - bool IsClosed(); - bool IsFullyOpen(); - void Open(float fOpenRatio); + float GetAngleOpenRatio(); + bool IsClosed(); + bool IsFullyOpen(); + void Open(float fOpenRatio); DoorState GetDoorState() { return (DoorState)GetInterface()->m_nDoorState; }; }; diff --git a/Client/game_sa/CDummyPoolSA.cpp b/Client/game_sa/CDummyPoolSA.cpp index a00ce49512a..96ab09c4344 100644 --- a/Client/game_sa/CDummyPoolSA.cpp +++ b/Client/game_sa/CDummyPoolSA.cpp @@ -76,11 +76,12 @@ void CDummyPoolSA::RestoreBackup() void CDummyPoolSA::UpdateBuildingLods(const std::uint32_t offset) { - if (m_pOriginalElementsBackup) + if (m_pOriginalElementsBackup) { UpdateBackupLodOffset(offset); - else + } else { UpdateLodsOffestInPool(offset); } +} void CDummyPoolSA::UpdateBackupLodOffset(const std::uint32_t offset) { diff --git a/Client/game_sa/CDummyPoolSA.h b/Client/game_sa/CDummyPoolSA.h index 5b954a5a4a5..2cecf7ae8c3 100644 --- a/Client/game_sa/CDummyPoolSA.h +++ b/Client/game_sa/CDummyPoolSA.h @@ -33,7 +33,7 @@ class CDummyPoolSA final : public CDummyPool void UpdateLodsOffestInPool(const std::uint32_t offset); private: - CPoolSAInterface** m_ppDummyPoolInterface; + CPoolSAInterface** m_ppDummyPoolInterface; using building_buffer_t = std::uint8_t[sizeof(CEntitySAInterface)]; using pool_backup_t = std::array, MAX_DUMMIES_DEFAULT>; diff --git a/Client/game_sa/CDynamicPool.h b/Client/game_sa/CDynamicPool.h index 2bff987946c..dbc93db74c4 100644 --- a/Client/game_sa/CDynamicPool.h +++ b/Client/game_sa/CDynamicPool.h @@ -84,6 +84,8 @@ class CDynamicPool { assert(false && "Could not allocate a memory for CDynamicPoolPart"); } + + return nullptr; } void RemoveItem(PoolObjT* item) @@ -118,7 +120,8 @@ class CDynamicPool return size; } - bool SetCapacity(std::size_t newSize) { + bool SetCapacity(std::size_t newSize) + { if (newSize == 0) return false; @@ -161,7 +164,7 @@ class CDynamicPool return true; } } - + return true; } diff --git a/Client/game_sa/CEntitySA.cpp b/Client/game_sa/CEntitySA.cpp index 17eb7c615ec..725b978f01d 100644 --- a/Client/game_sa/CEntitySA.cpp +++ b/Client/game_sa/CEntitySA.cpp @@ -43,9 +43,33 @@ void CEntitySAInterface::UpdateRpHAnim() ((void(__thiscall*)(CEntitySAInterface*))0x532B20)(this); } +// Probes a CColModel pointer for accessibility via SEH. +// Building removal can re-add entities whose collision sector was unloaded, +// leaving pColModel as a non-null dangling pointer (the streaming system +// strips collision data but doesnt null the pointer in model info). +// SEH costs only a few instructions for frame setup (unless there's exceptions), don't consider using IsReadablePointer here as its expensive. +static bool IsColModelAccessible(CColModelSAInterface* pColModel) +{ + __try + { + volatile auto probe = pColModel->m_bounds.m_vecMin.fX; + (void)probe; + return true; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } +} + CRect* CEntitySAInterface::GetBoundRect_(CRect* pRect) { - CColModelSAInterface* colModel = CModelInfoSAInterface::GetModelInfo(m_nModelIndex)->pColModel; + CBaseModelInfoSAInterface* pModelInfo = CModelInfoSAInterface::GetModelInfo(m_nModelIndex); + + if (!pModelInfo || !pModelInfo->pColModel || !IsColModelAccessible(pModelInfo->pColModel)) + return pRect; + + CColModelSAInterface* colModel = pModelInfo->pColModel; CVector vecMin = colModel->m_bounds.m_vecMin; CVector vecMax = colModel->m_bounds.m_vecMax; CRect rect; @@ -62,7 +86,7 @@ CRect* CEntitySAInterface::GetBoundRect_(CRect* pRect) TransformFromObjectSpace(point, vecMax); rect.StretchToPoint(point.fX, point.fY); *pRect = rect; - pRect->FixIncorrectTopLeft(); // Fix #1613: custom map collision crashes in CPhysical class (infinite loop) + pRect->FixIncorrectTopLeft(); // Fix #1613: custom map collision crashes in CPhysical class (infinite loop) return pRect; } @@ -100,6 +124,9 @@ bool CEntitySA::SetScaleInternal(const CVector& scale) void CEntitySA::SetPosition(float fX, float fY, float fZ) { // Remove & add to world? + if (std::isnan(fX) || std::isnan(fY) || std::isnan(fZ) || std::isinf(fX) || std::isinf(fY) || std::isinf(fZ)) + return; + CVector* vecPos; if (m_pInterface->matrix) { @@ -125,11 +152,10 @@ void CEntitySA::SetPosition(float fX, float fY, float fZ) // If it's a train, recalculate its rail position parameter (does not affect derailed state) DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CTrain_FindPositionOnTrackFromCoors; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } if (m_pInterface->nType == ENTITY_TYPE_OBJECT) { @@ -139,6 +165,9 @@ void CEntitySA::SetPosition(float fX, float fY, float fZ) void CEntitySA::Teleport(float fX, float fY, float fZ) { + if (std::isnan(fX) || std::isnan(fY) || std::isnan(fZ) || std::isinf(fX) || std::isinf(fY) || std::isinf(fZ)) + return; + if (m_pInterface->matrix) { SetPosition(fX, fY, fZ); @@ -164,13 +193,12 @@ void CEntitySA::SetupLighting() void CEntitySA::Render() { // This function may use m_pInterface->Render() - DWORD dwFunc = 0x59F180; // m_pInterface->vtbl->Render; + DWORD dwFunc = 0x59F180; // m_pInterface->vtbl->Render; DWORD dwThis = (DWORD)m_pInterface; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } void CEntitySA::SetOrientation(float fX, float fY, float fZ) @@ -181,18 +209,16 @@ void CEntitySA::SetOrientation(float fX, float fY, float fZ) DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = 0x446F90; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on dwFunc = 0x532B00; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on if (m_pInterface->nType == ENTITY_TYPE_OBJECT) { @@ -207,18 +233,16 @@ void CEntitySA::FixBoatOrientation() pGame->GetWorld()->Remove(this, CEntity_FixBoatOrientation); DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = 0x446F90; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on dwFunc = 0x532B00; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on pGame->GetWorld()->Add(this, CEntity_FixBoatOrientation); } @@ -258,11 +282,12 @@ CVector* CEntitySA::GetPosition() CVector* CEntitySA::GetPositionInternal() { - if (m_pInterface->matrix) + if (m_pInterface->matrix) { return &m_pInterface->matrix->vPos; - else + } else { return &m_pInterface->m_transform.m_translate; } +} // // Get entity matrix. Fixes bad numbers @@ -300,7 +325,7 @@ CMatrix* CEntitySA::GetMatrixInternal(CMatrix* matrix) void CEntitySA::SetMatrix(CMatrix* matrix) { - if (m_pInterface->matrix && matrix) + if (m_pInterface->matrix && matrix && IsValidMatrix(*matrix)) { OnChangingPosition(matrix->vPos); @@ -318,11 +343,13 @@ void CEntitySA::SetMatrix(CMatrix* matrix) { DWORD dwThis = (DWORD) m_pInterface; DWORD dwFunc = 0x6F6CC0; - _asm + // clang-format off + __asm { mov ecx, dwThis call dwFunc } + // clang-format on //OutputDebugString ( "Set train position on tracks (matrix)!\n" ); } @@ -330,19 +357,17 @@ void CEntitySA::SetMatrix(CMatrix* matrix) pGame->GetWorld()->Remove(this, CEntity_SetMatrix); DWORD dwThis = (DWORD)m_pInterface; - DWORD dwFunc = 0x446F90; // CEntity::UpdateRwMatrix - _asm - { - mov ecx, dwThis - call dwFunc - } - - dwFunc = 0x532B00; // CEntity::UpdateRwFrame - _asm - { - mov ecx, dwThis - call dwFunc - } + DWORD dwFunc = 0x446F90; // CEntity::UpdateRwMatrix + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on + + dwFunc = 0x532B00; // CEntity::UpdateRwFrame + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on if (m_pInterface->nType == ENTITY_TYPE_OBJECT) { @@ -368,12 +393,14 @@ float CEntitySA::GetDistanceFromCentreOfMassToBaseOfModel() DWORD dwFunc = FUNC_GetDistanceFromCentreOfMassToBaseOfModel; DWORD dwThis = (DWORD)m_pInterface; float fReturn; - _asm + // clang-format off + __asm { mov ecx, dwThis call dwFunc fstp fReturn } + // clang-format on return fReturn; } @@ -390,7 +417,7 @@ eEntityStatus CEntitySA::GetEntityStatus() RwFrame* CEntitySA::GetFrameFromId(int id) { // CClumpModelInfo::GetFrameFromId - return ((RwFrame*(_cdecl*)(RpClump*, int))0x4C53C0)(m_pInterface->m_pRwObject, id); + return ((RwFrame * (_cdecl*)(RpClump*, int))0x4C53C0)(m_pInterface->m_pRwObject, id); } RpClump* CEntitySA::GetRpClump() @@ -401,19 +428,17 @@ RpClump* CEntitySA::GetRpClump() RwMatrix* CEntitySA::GetLTMFromId(int id) { // RwFrameGetLTM - return ((RwMatrix*(_cdecl*)(RwFrame*))0x7F0990)(GetFrameFromId(id)); + return ((RwMatrix * (_cdecl*)(RwFrame*))0x7F0990)(GetFrameFromId(id)); } void CEntitySA::SetAlpha(DWORD dwAlpha) { DWORD dwFunc = FUNC_SetRwObjectAlpha; DWORD dwThis = (DWORD)m_pInterface; - _asm - { - mov ecx, dwThis - push dwAlpha - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwAlpha)); + reinterpret_cast(dwFunc)(dwThis, dwAlpha); + // clang-format on } bool CEntitySA::IsOnScreen() @@ -421,12 +446,10 @@ bool CEntitySA::IsOnScreen() DWORD dwFunc = FUNC_IsVisible; DWORD dwThis = (DWORD)m_pInterface; bool bReturn = false; - _asm - { - mov ecx, dwThis - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThis) ); +bReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on return bReturn; } @@ -457,15 +480,10 @@ void CEntitySA::MatrixConvertFromEulerAngles(float fX, float fY, float fZ, int i if (matrixPadded) { DWORD dwFunc = FUNC_CMatrix__ConvertFromEulerAngles; - _asm - { - push iUnknown - push fZ - push fY - push fX - mov ecx, matrixPadded - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(matrixPadded), decltype(fX), decltype(fY), decltype(fZ), decltype(iUnknown)); + reinterpret_cast(dwFunc)(matrixPadded, fX, fY, fZ, iUnknown); + // clang-format on } } @@ -475,15 +493,10 @@ void CEntitySA::MatrixConvertToEulerAngles(float* fX, float* fY, float* fZ, int if (matrixPadded) { DWORD dwFunc = FUNC_CMatrix__ConvertToEulerAngles; - _asm - { - push iUnknown - push fZ - push fY - push fX - mov ecx, matrixPadded - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(matrixPadded), decltype(fX), decltype(fY), decltype(fZ), decltype(iUnknown)); + reinterpret_cast(dwFunc)(matrixPadded, fX, fY, fZ, iUnknown); + // clang-format on } } @@ -493,14 +506,10 @@ bool CEntitySA::IsPlayingAnimation(char* szAnimName) DWORD dwFunc = FUNC_RpAnimBlendClumpGetAssociation; DWORD dwThis = (DWORD)m_pInterface->m_pRwObject; - _asm - { - push szAnimName - push dwThis - call dwFunc - add esp, 8 - mov dwReturn, eax - } + // clang-format off + using func_t = decltype(dwReturn) (__cdecl*)(decltype(dwThis), decltype(szAnimName)); +dwReturn = reinterpret_cast(dwFunc)(dwThis, szAnimName); + // clang-format on if (dwReturn) return true; else return false; } @@ -561,7 +570,7 @@ bool CEntitySA::GetBoneRotationQuat(eBone boneId, float& x, float& y, float& z, RpClump* clump = GetRpClump(); if (!clump) return false; - + // updating the bone frame orientation will also update its children // This rotation is only applied when UpdateElementRpHAnim is called auto* clumpDataInterface = *pGame->GetClumpData(clump); @@ -582,21 +591,21 @@ bool CEntitySA::SetBoneRotation(eBone boneId, float yaw, float pitch, float roll RpClump* clump = GetRpClump(); if (!clump) return false; - + // updating the bone frame orientation will also update its children // This rotation is only applied when UpdateElementRpHAnim is called auto* clumpDataInterface = *pGame->GetClumpData(clump); auto* frameData = clumpDataInterface->GetFrameDataByNodeId(boneId); if (!frameData) return false; - + RtQuat* boneOrientation = &frameData->m_pIFrame->orientation; - RwV3d angles = { yaw, roll, pitch }; + RwV3d angles = {yaw, roll, pitch}; BoneNode_cSAInterface::EulerToQuat(&angles, boneOrientation); CEntitySAInterface* theInterface = GetInterface(); if (theInterface) theInterface->bDontUpdateHierarchy = false; - + return true; } @@ -605,7 +614,7 @@ bool CEntitySA::SetBoneRotationQuat(eBone boneId, float x, float y, float z, flo RpClump* clump = GetRpClump(); if (!clump) return false; - + // updating the bone frame orientation will also update its children // This rotation is only applied when UpdateElementRpHAnim is called auto* clumpDataInterface = *pGame->GetClumpData(clump); @@ -621,7 +630,7 @@ bool CEntitySA::SetBoneRotationQuat(eBone boneId, float x, float y, float z, flo CEntitySAInterface* theInterface = GetInterface(); if (theInterface) theInterface->bDontUpdateHierarchy = false; - + return true; } @@ -642,7 +651,7 @@ bool CEntitySA::SetBonePosition(eBone boneId, const CVector& position) RwMatrix* rwBoneMatrix = GetBoneRwMatrix(boneId); if (!rwBoneMatrix) return false; - + CMatrixSAInterface boneMatrix(rwBoneMatrix, false); boneMatrix.SetTranslateOnly(position); boneMatrix.UpdateRW(); diff --git a/Client/game_sa/CEntitySA.h b/Client/game_sa/CEntitySA.h index 8cfff9d692e..ef69c6fbf27 100644 --- a/Client/game_sa/CEntitySA.h +++ b/Client/game_sa/CEntitySA.h @@ -16,17 +16,17 @@ #include #include -#define FUNC_GetDistanceFromCentreOfMassToBaseOfModel 0x536BE0 +#define FUNC_GetDistanceFromCentreOfMassToBaseOfModel 0x536BE0 -#define FUNC_SetRwObjectAlpha 0x5332C0 +#define FUNC_SetRwObjectAlpha 0x5332C0 -#define FUNC_CMatrix__ConvertToEulerAngles 0x59A840 -#define FUNC_CMatrix__ConvertFromEulerAngles 0x59AA40 +#define FUNC_CMatrix__ConvertToEulerAngles 0x59A840 +#define FUNC_CMatrix__ConvertFromEulerAngles 0x59AA40 -#define FUNC_IsVisible 0x536BC0 +#define FUNC_IsVisible 0x536BC0 // not in CEntity really -#define FUNC_RpAnimBlendClumpGetAssociation 0x4D6870 +#define FUNC_RpAnimBlendClumpGetAssociation 0x4D6870 class CPhysicalSAInterface; class CRect; @@ -52,8 +52,8 @@ class CMatrixEx { public: CMatrix_Padded matrix; - CMatrix* pMatrix; // usually not initialized - void* haveRwMatrix; // unknown pointer + CMatrix* pMatrix; // usually not initialized + void* haveRwMatrix; // unknown pointer }; class XYZ @@ -106,69 +106,68 @@ class CEntitySAInterface : public CPlaceableSAInterface virtual void FlagToDestroyWhenNextProcessed() = 0; public: - RpClump* m_pRwObject; // 24 + RpClump* m_pRwObject; // 24 /********** BEGIN CFLAGS **************/ - unsigned long bUsesCollision : 1; // does entity use collision - unsigned long bCollisionProcessed : 1; // has object been processed by a ProcessEntityCollision function - unsigned long bIsStatic : 1; // is entity static - unsigned long bHasContacted : 1; // has entity processed some contact forces - unsigned long bIsStuck : 1; // is entity stuck - unsigned long bIsInSafePosition : 1; // is entity in a collision free safe position - unsigned long bWasPostponed : 1; // was entity control processing postponed - unsigned long bIsVisible : 1; // is the entity visible - - unsigned long bIsBIGBuilding : 1; // Set if this entity is a big building - unsigned long bRenderDamaged : 1; // use damaged LOD models for objects with applicable damage - unsigned long bStreamingDontDelete : 1; // Dont let the streaming remove this - unsigned long bRemoveFromWorld : 1; // remove this entity next time it should be processed - unsigned long bHasHitWall : 1; // has collided with a building (changes subsequent collisions) - unsigned long bImBeingRendered : 1; // don't delete me because I'm being rendered - unsigned long bDrawLast : 1; // draw object last - unsigned long bDistanceFade : 1; // Fade entity because it is far away + unsigned long bUsesCollision : 1; // does entity use collision + unsigned long bCollisionProcessed : 1; // has object been processed by a ProcessEntityCollision function + unsigned long bIsStatic : 1; // is entity static + unsigned long bHasContacted : 1; // has entity processed some contact forces + unsigned long bIsStuck : 1; // is entity stuck + unsigned long bIsInSafePosition : 1; // is entity in a collision free safe position + unsigned long bWasPostponed : 1; // was entity control processing postponed + unsigned long bIsVisible : 1; // is the entity visible + + unsigned long bIsBIGBuilding : 1; // Set if this entity is a big building + unsigned long bRenderDamaged : 1; // use damaged LOD models for objects with applicable damage + unsigned long bStreamingDontDelete : 1; // Dont let the streaming remove this + unsigned long bRemoveFromWorld : 1; // remove this entity next time it should be processed + unsigned long bHasHitWall : 1; // has collided with a building (changes subsequent collisions) + unsigned long bImBeingRendered : 1; // don't delete me because I'm being rendered + unsigned long bDrawLast : 1; // draw object last + unsigned long bDistanceFade : 1; // Fade entity because it is far away unsigned long bDontCastShadowsOn : 1; // Dont cast shadows on this object unsigned long bOffscreen : 1; // offscreen flag. This can only be trusted when it is set to true - unsigned long - bIsStaticWaitingForCollision : 1; // this is used by script created entities - they are static until the collision is loaded below them - unsigned long bDontStream : 1; // tell the streaming not to stream me - unsigned long bUnderwater : 1; // this object is underwater change drawing order - unsigned long bHasPreRenderEffects : 1; // Object has a prerender effects attached to it - unsigned long bIsTempBuilding : 1; // whether or not the building is temporary (i.e. can be created and deleted more than once) - unsigned long bDontUpdateHierarchy : 1; // Don't update the aniamtion hierarchy this frame - - unsigned long bHasRoadsignText : 1; // entity is roadsign and has some 2deffect text stuff to be rendered + unsigned long bIsStaticWaitingForCollision : 1; // this is used by script created entities - they are static until the collision is loaded below them + unsigned long bDontStream : 1; // tell the streaming not to stream me + unsigned long bUnderwater : 1; // this object is underwater change drawing order + unsigned long bHasPreRenderEffects : 1; // Object has a prerender effects attached to it + unsigned long bIsTempBuilding : 1; // whether or not the building is temporary (i.e. can be created and deleted more than once) + unsigned long bDontUpdateHierarchy : 1; // Don't update the aniamtion hierarchy this frame + + unsigned long bHasRoadsignText : 1; // entity is roadsign and has some 2deffect text stuff to be rendered unsigned long bDisplayedSuperLowLOD : 1; - unsigned long bIsProcObject : 1; // set object has been generate by procedural object generator - unsigned long bBackfaceCulled : 1; // has backface culling on - unsigned long bLightObject : 1; // light object with directional lights - unsigned long bUnimportantStream : 1; // set that this object is unimportant, if streaming is having problems - unsigned long bTunnel : 1; // Is this model part of a tunnel - unsigned long bTunnelTransition : 1; // This model should be rendered from within and outside of the tunnel + unsigned long bIsProcObject : 1; // set object has been generate by procedural object generator + unsigned long bBackfaceCulled : 1; // has backface culling on + unsigned long bLightObject : 1; // light object with directional lights + unsigned long bUnimportantStream : 1; // set that this object is unimportant, if streaming is having problems + unsigned long bTunnel : 1; // Is this model part of a tunnel + unsigned long bTunnelTransition : 1; // This model should be rendered from within and outside of the tunnel /********** END CFLAGS **************/ - WORD RandomSeed; // 32 - WORD m_nModelIndex; // 34 - CReferences* pReferences; // 36 + WORD RandomSeed; // 32 + WORD m_nModelIndex; // 34 + CReferences* pReferences; // 36 - DWORD* m_pLastRenderedLink; // CLink* m_pLastRenderedLink; +40 + DWORD* m_pLastRenderedLink; // CLink* m_pLastRenderedLink; +40 - WORD m_nScanCode; // 44 - BYTE m_iplIndex; // used to define which IPL file object is in +46 - BYTE m_areaCode; // used to define what objects are visible at this point +47 + WORD m_nScanCode; // 44 + BYTE m_iplIndex; // used to define which IPL file object is in +46 + BYTE m_areaCode; // used to define what objects are visible at this point +47 // LOD shit - CEntitySAInterface* m_pLod; // 48 + CEntitySAInterface* m_pLod; // 48 // num child higher level LODs - BYTE numLodChildren; // 52 + BYTE numLodChildren; // 52 // num child higher level LODs that have been rendered - signed char numLodChildrenRendered; // 53 + signed char numLodChildrenRendered; // 53 //********* BEGIN CEntityInfo **********// - BYTE nType : 3; // what type is the entity // 54 (2 == Vehicle) - BYTE nStatus : 5; // control status // 54 + BYTE nType : 3; // what type is the entity // 54 (2 == Vehicle) + BYTE nStatus : 5; // control status // 54 //********* END CEntityInfo **********// - uint8 m_pad0; // 55 + uint8 m_pad0; // 55 CRect* GetBoundRect_(CRect* pRect); void TransformFromObjectSpace(CVector& outPosn, CVector const& offset); @@ -181,7 +180,7 @@ class CEntitySAInterface : public CPlaceableSAInterface // Functions to hide member variable misuse // - void SetLod(CEntitySAInterface* pLod) noexcept { m_pLod = pLod; }; + void SetLod(CEntitySAInterface* pLod) noexcept { m_pLod = pLod; }; CEntitySAInterface* GetLod() const noexcept { return m_pLod; }; // Sets @@ -219,7 +218,8 @@ class CEntitySAInterface : public CPlaceableSAInterface ((CStencilShadow_dtorByOwner)0x711730)(this); }; - void RemoveRWObjectWithReferencesCleanup() { + void RemoveRWObjectWithReferencesCleanup() + { DeleteRwObject(); ResolveReferences(); RemoveShadows(); @@ -237,6 +237,7 @@ class CEntitySA : public virtual CEntity CEntitySA(); CEntitySAInterface* GetInterface() { return m_pInterface; }; + CEntitySAInterface* GetInterface() const { return m_pInterface; }; void SetInterface(CEntitySAInterface* intInterface) { m_pInterface = intInterface; }; bool IsPed() { return GetEntityType() == ENTITY_TYPE_PED; } @@ -248,7 +249,7 @@ class CEntitySA : public virtual CEntity void SetupLighting(); void Render(); void SetOrientation(float fX, float fY, float fZ); - void FixBoatOrientation(); // eAi you might want to rename this + void FixBoatOrientation(); // eAi you might want to rename this void SetPosition(CVector* vecPosition); void SetUnderwater(bool bUnderwater); @@ -281,8 +282,8 @@ class CEntitySA : public virtual CEntity RpClump* GetRpClump(); - bool BeingDeleted; // to prevent it trying to delete twice - bool DoNotRemoveFromGame; // when deleted, if this is true, it won't be removed from the game + bool BeingDeleted; // to prevent it trying to delete twice + bool DoNotRemoveFromGame; // when deleted, if this is true, it won't be removed from the game void SetDoNotRemoveFromGameWhenDeleted(bool bDoNotRemoveFromGame) { DoNotRemoveFromGame = bDoNotRemoveFromGame; }; bool IsStatic() { return m_pInterface->bIsStatic; } diff --git a/Client/game_sa/CEventDamageSA.cpp b/Client/game_sa/CEventDamageSA.cpp index b0ec4c0c33b..97ed9b2c044 100644 --- a/Client/game_sa/CEventDamageSA.cpp +++ b/Client/game_sa/CEventDamageSA.cpp @@ -27,18 +27,10 @@ CEventDamageSA::CEventDamageSA(CEntity* pEntity, unsigned int i_1, eWeaponType w DWORD dwEntityInterface = (DWORD)pEntity->GetInterface(); DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CEventDamage_Constructor; - _asm - { - mov ecx, dwThis - push b_4 - push b_3 - push uc_2 - push hitZone - push weaponType - push i_1 - push dwEntityInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwEntityInterface), decltype(i_1), decltype(weaponType), decltype(hitZone), decltype(uc_2), decltype(b_3), decltype(b_4)); + reinterpret_cast(dwFunc)(dwThis, dwEntityInterface, i_1, weaponType, hitZone, uc_2, b_3, b_4); + // clang-format on } CEventDamageSA::CEventDamageSA(CEventDamageSAInterface* pInterface) @@ -57,11 +49,10 @@ CEventDamageSA::~CEventDamageSA() { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CEventDamage_Destructor; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on delete m_pInterface; } } @@ -83,12 +74,10 @@ bool CEventDamageSA::HasKilledPed() DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CEventDamage_HasKilledPed; bool bReturn = false; - _asm - { - mov ecx, dwThis - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThis) ); +bReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on return bReturn; } @@ -97,12 +86,14 @@ float CEventDamageSA::GetDamageApplied() DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CEventDamage_GetDamageApplied; float fReturn = 0.0f; - _asm + // clang-format off + __asm { mov ecx, dwThis call dwFunc fstp fReturn } + // clang-format on return fReturn; } @@ -111,12 +102,10 @@ AssocGroupId CEventDamageSA::GetAnimGroup() DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CEventDamage_GetAnimGroup; AssocGroupId animGroup = 0; - _asm - { - mov ecx, dwThis - call dwFunc - mov animGroup, eax - } + // clang-format off + using func_t = decltype(animGroup) (__thiscall*)(decltype(dwThis) ); +animGroup = reinterpret_cast(dwFunc)(dwThis); + // clang-format on return animGroup; } @@ -125,12 +114,10 @@ AnimationId CEventDamageSA::GetAnimId() DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CEventDamage_GetAnimId; AnimationId animID = 0; - _asm - { - mov ecx, dwThis - call dwFunc - mov animID, eax - } + // clang-format off + using func_t = decltype(animID) (__thiscall*)(decltype(dwThis) ); +animID = reinterpret_cast(dwFunc)(dwThis); + // clang-format on return animID; } @@ -139,12 +126,10 @@ bool CEventDamageSA::GetAnimAdded() bool bReturn; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CEventDamage_GetAnimAdded; - _asm - { - mov ecx, dwThis - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThis) ); +bReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on return bReturn; } @@ -153,13 +138,10 @@ void CEventDamageSA::ComputeDeathAnim(CPed* pPed, bool bUnk) DWORD dwThis = (DWORD)m_pInterface; DWORD dwPed = (DWORD)pPed->GetInterface(); DWORD dwFunc = FUNC_CEventDamage_ComputeDeathAnim; - _asm - { - mov ecx, dwThis - push bUnk - push dwPed - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwPed), decltype(bUnk)); + reinterpret_cast(dwFunc)(dwThis, dwPed, bUnk); + // clang-format on } void CEventDamageSA::ComputeDamageAnim(CPed* pPed, bool bUnk) @@ -167,13 +149,10 @@ void CEventDamageSA::ComputeDamageAnim(CPed* pPed, bool bUnk) DWORD dwThis = (DWORD)m_pInterface; DWORD dwPed = (DWORD)pPed->GetInterface(); DWORD dwFunc = FUNC_CEventDamage_ComputeDamageAnim; - _asm - { - mov ecx, dwThis - push bUnk - push dwPed - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwPed), decltype(bUnk)); + reinterpret_cast(dwFunc)(dwThis, dwPed, bUnk); + // clang-format on } bool CEventDamageSA::AffectsPed(CPed* pPed) @@ -182,12 +161,9 @@ bool CEventDamageSA::AffectsPed(CPed* pPed) DWORD dwPedInterface = (DWORD)pPed->GetInterface(); DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CEventDamage_AffectsPed; - _asm - { - mov ecx, dwThis - push dwPedInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThis), decltype(dwPedInterface)); +bReturn = reinterpret_cast(dwFunc)(dwThis, dwPedInterface); + // clang-format on return bReturn; } diff --git a/Client/game_sa/CEventDamageSA.h b/Client/game_sa/CEventDamageSA.h index 949fad4c061..92e0d0e51cd 100644 --- a/Client/game_sa/CEventDamageSA.h +++ b/Client/game_sa/CEventDamageSA.h @@ -18,44 +18,44 @@ class CEntitySAInterface; enum eWeaponType; enum ePedPieceTypes; -#define FUNC_CEventDamage_Constructor 0x4ad830 -#define FUNC_CEventDamage_Destructor 0x4ad960 -#define FUNC_CEventDamage_HasKilledPed 0x4ABCA0 -#define FUNC_CEventDamage_GetDamageApplied 0x4ABCE0 -#define FUNC_CEventDamage_GetAnimGroup 0x4B8060 -#define FUNC_CEventDamage_GetAnimId 0x4B8070 -#define FUNC_CEventDamage_GetAnimAdded 0x4b80a0 -#define FUNC_CEventDamage_ComputeDeathAnim 0x4B3A60 -#define FUNC_CEventDamage_ComputeDamageAnim 0x4b3fc0 -#define FUNC_CEventDamage_AffectsPed 0x4b35a0 +#define FUNC_CEventDamage_Constructor 0x4ad830 +#define FUNC_CEventDamage_Destructor 0x4ad960 +#define FUNC_CEventDamage_HasKilledPed 0x4ABCA0 +#define FUNC_CEventDamage_GetDamageApplied 0x4ABCE0 +#define FUNC_CEventDamage_GetAnimGroup 0x4B8060 +#define FUNC_CEventDamage_GetAnimId 0x4B8070 +#define FUNC_CEventDamage_GetAnimAdded 0x4b80a0 +#define FUNC_CEventDamage_ComputeDeathAnim 0x4B3A60 +#define FUNC_CEventDamage_ComputeDamageAnim 0x4b3fc0 +#define FUNC_CEventDamage_AffectsPed 0x4b35a0 class CEventDamageSAInterface { public: - DWORD vmt; // 0 - DWORD ticks; // 4 - BYTE unk8; // 8 - BYTE unk9; // 9 - BYTE unkA; // Ah - BYTE unkB; // Bh - BYTE unkC; // Ch - BYTE unkD; // Dh - WORD unkE; // Eh - WORD unk10; // 10h - WORD unk12; // 12h - CEntitySAInterface* pInflictor; // 14h - DWORD damageTime; // 18h - eWeaponType weaponUsed; // 1Ch - ePedPieceTypes pedPieceType; // 20h - BYTE ucDirection; // 24h - BYTE ucFlags; // 25h - BYTE unk26; // 26h - BYTE unk27; // 27h - DWORD dwAnimGroup; // 28h - DWORD dwAnimID; // 2Ch - float fAnimBlend; // 30h - float fAnimSpeed; // 34h - CPedDamageResponseSAInterface damageResponseData; // 38h + DWORD vmt; // 0 + DWORD ticks; // 4 + BYTE unk8; // 8 + BYTE unk9; // 9 + BYTE unkA; // Ah + BYTE unkB; // Bh + BYTE unkC; // Ch + BYTE unkD; // Dh + WORD unkE; // Eh + WORD unk10; // 10h + WORD unk12; // 12h + CEntitySAInterface* pInflictor; // 14h + DWORD damageTime; // 18h + eWeaponType weaponUsed; // 1Ch + ePedPieceTypes pedPieceType; // 20h + BYTE ucDirection; // 24h + BYTE ucFlags; // 25h + BYTE unk26; // 26h + BYTE unk27; // 27h + DWORD dwAnimGroup; // 28h + DWORD dwAnimID; // 2Ch + float fAnimBlend; // 30h + float fAnimSpeed; // 34h + CPedDamageResponseSAInterface damageResponseData; // 38h }; class CEventDamageSA : public CEventDamage diff --git a/Client/game_sa/CExplosionManagerSA.cpp b/Client/game_sa/CExplosionManagerSA.cpp index d62c2d81cf8..a431055646b 100644 --- a/Client/game_sa/CExplosionManagerSA.cpp +++ b/Client/game_sa/CExplosionManagerSA.cpp @@ -40,7 +40,8 @@ CExplosion* CExplosionManagerSA::AddExplosion(CEntity* pExplodingEntity, CEntity CExplosion* explosion = CExplosionManagerSA::FindFreeExplosion(); bool bReturn; DWORD dwFunc = FUNC_CExplosion_AddExplosion; - _asm + // clang-format off + __asm { push bNoDamage push fCamShake @@ -68,6 +69,7 @@ CExplosion* CExplosionManagerSA::AddExplosion(CEntity* pExplodingEntity, CEntity add esp, 0x28 mov bReturn, al } + // clang-format on if (bReturn) return explosion; return NULL; @@ -75,10 +77,11 @@ CExplosion* CExplosionManagerSA::AddExplosion(CEntity* pExplodingEntity, CEntity void CExplosionManagerSA::RemoveAllExplosions() { - for (int i = 0; i < MAX_EXPLOSIONS; i++) + for (int i = 0; i < MAX_EXPLOSIONS; i++) { if (Explosions[i]->IsActive()) Explosions[i]->Remove(); } +} CExplosion* CExplosionManagerSA::GetExplosion(DWORD ID) { @@ -87,8 +90,9 @@ CExplosion* CExplosionManagerSA::GetExplosion(DWORD ID) CExplosion* CExplosionManagerSA::FindFreeExplosion() { - for (int i = 0; i < MAX_EXPLOSIONS; i++) + for (int i = 0; i < MAX_EXPLOSIONS; i++) { if (!Explosions[i]->IsActive()) return Explosions[i]; +} return NULL; } diff --git a/Client/game_sa/CExplosionManagerSA.h b/Client/game_sa/CExplosionManagerSA.h index db6c6c2e9e6..0795e9f898f 100644 --- a/Client/game_sa/CExplosionManagerSA.h +++ b/Client/game_sa/CExplosionManagerSA.h @@ -16,10 +16,10 @@ class CExplosion; class CExplosionSA; -#define FUNC_CExplosion_AddExplosion 0x736A50 +#define FUNC_CExplosion_AddExplosion 0x736A50 -#define ARRAY_Explosions 0xC88950 -#define MAX_EXPLOSIONS 48 +#define ARRAY_Explosions 0xC88950 +#define MAX_EXPLOSIONS 48 class CExplosionManagerSA : public CExplosionManager { diff --git a/Client/game_sa/CExplosionSA.h b/Client/game_sa/CExplosionSA.h index 1d19925153d..54790c4298b 100644 --- a/Client/game_sa/CExplosionSA.h +++ b/Client/game_sa/CExplosionSA.h @@ -16,7 +16,7 @@ class CEntitySAInterface; -class CExplosionSAInterface // 124 bytes, ok +class CExplosionSAInterface // 124 bytes, ok { public: eExplosionType m_ExplosionType; @@ -24,15 +24,15 @@ class CExplosionSAInterface // 124 bytes, ok float m_fExplosionRadius; float m_fExplosionPropagationRate; CEntitySAInterface* m_pEntExplosionOwner; - CEntitySAInterface* m_pExplodingEntity; // 28 + CEntitySAInterface* m_pExplodingEntity; // 28 DWORD m_TimeExpires; float m_DamagePercentage; - BYTE m_cExplosionActive; // 36 + BYTE m_cExplosionActive; // 36 BYTE m_nTriggerExplosionSfx; BYTE m_bMakeSound; - float m_ParticleTimer; // 40 - DWORD m_ActivationTime; // 44 - float m_fExplosionForce; // 48 + float m_ParticleTimer; // 40 + DWORD m_ActivationTime; // 44 + float m_fExplosionForce; // 48 float m_fGroundZ; DWORD m_fuelTime; CVector m_fuelDir[3]; diff --git a/Client/game_sa/CFileLoaderSA.cpp b/Client/game_sa/CFileLoaderSA.cpp index 19b721581a5..3b726c9202b 100644 --- a/Client/game_sa/CFileLoaderSA.cpp +++ b/Client/game_sa/CFileLoaderSA.cpp @@ -34,18 +34,24 @@ CEntitySAInterface* CFileLoaderSA::LoadObjectInstance(SFileObjectInstance* obj) return ((CEntitySAInterface * (__cdecl*)(SFileObjectInstance*, const char*))0x538090)(obj, nullptr); } +CEntitySAInterface* CFileLoaderSA::LoadObjectInstance(const char* szLine) +{ + // Delegate to the global function that does the actual work + return CFileLoader_LoadObjectInstance(szLine); +} + class CAtomicModelInfo { public: - void CAtomicModelInfo::DeleteRwObject() { ((void(__thiscall*)(CAtomicModelInfo*))(*(void***)this)[8])(this); } + void DeleteRwObject() { ((void(__thiscall*)(CAtomicModelInfo*))(*(void***)this)[8])(this); } - void CAtomicModelInfo::SetAtomic(RpAtomic* atomic) { ((void(__thiscall*)(CAtomicModelInfo*, RpAtomic*))(*(void***)this)[15])(this, atomic); } + void SetAtomic(RpAtomic* atomic) { ((void(__thiscall*)(CAtomicModelInfo*, RpAtomic*))(*(void***)this)[15])(this, atomic); } }; class CDamagableModelInfo { public: - void CDamagableModelInfo::SetDamagedAtomic(RpAtomic* atomic) { ((void(__thiscall*)(CDamagableModelInfo*, RpAtomic*))0x4C48D0)(this, atomic); } + void SetDamagedAtomic(RpAtomic* atomic) { ((void(__thiscall*)(CDamagableModelInfo*, RpAtomic*))0x4C48D0)(this, atomic); } }; static char* GetFrameNodeName(RwFrame* frame) @@ -60,7 +66,8 @@ void GetNameAndDamage(const char* nodeName, char (&outName)[OutBuffSize], bool& { const auto nodeNameLen = strlen(nodeName); - const auto NodeNameEndsWith = [=](const char* with) { + const auto NodeNameEndsWith = [=](const char* with) + { const auto withLen = strlen(with); // dassert(withLen <= nodeNameLen); return withLen <= nodeNameLen /*dont bother checking otherwise, because it might cause a crash*/ @@ -69,10 +76,12 @@ void GetNameAndDamage(const char* nodeName, char (&outName)[OutBuffSize], bool& // Copy `nodeName` into `outName` with `off` trimmed from the end // Eg.: `dmg_dam` with `off = 4` becomes `dmg` - const auto TerminatedCopy = [&](size_t off) { - dassert(nodeNameLen - off < OutBuffSize); - strncpy_s(outName, nodeName, - std::min(nodeNameLen - off, OutBuffSize - 1)); // By providing `OutBuffSize - 1` it is ensured the array will be null terminated + const auto TerminatedCopy = [&](size_t off) + { + dassert(nodeNameLen >= off && nodeNameLen - off < OutBuffSize); + const size_t copyLen = std::min(nodeNameLen - off, OutBuffSize - 1); + strncpy_s(outName, nodeName, copyLen); + outName[copyLen] = '\0'; // Ensure null termination }; if (NodeNameEndsWith("_dam")) @@ -90,7 +99,9 @@ void GetNameAndDamage(const char* nodeName, char (&outName)[OutBuffSize], bool& else { dassert(nodeNameLen < OutBuffSize); - strncpy_s(outName, OutBuffSize, nodeName, OutBuffSize - 1); + const size_t copyLen = std::min(nodeNameLen, OutBuffSize - 1); + strncpy_s(outName, OutBuffSize, nodeName, copyLen); + outName[copyLen] = '\0'; // Ensure null termination } } } @@ -118,6 +129,14 @@ static void CVehicleModelInfo_StopUsingCommonVehicleTexDicationary() static auto CModelInfo_ms_modelInfoPtrs = (CBaseModelInfoSAInterface**)ARRAY_ModelInfo; static unsigned int& gAtomicModelId = *reinterpret_cast(DWORD_AtomicsReplacerModelID); +namespace +{ + bool RelatedModelInfoShim(RpAtomic* atomic, void* context) + { + return CFileLoader_SetRelatedModelInfoCB(atomic, static_cast(context)) != nullptr; + } +} + bool CFileLoader_LoadAtomicFile(RwStream* stream, unsigned int modelId) { CBaseModelInfoSAInterface* pBaseModelInfo = CModelInfo_ms_modelInfoPtrs[modelId]; @@ -148,7 +167,7 @@ bool CFileLoader_LoadAtomicFile(RwStream* stream, unsigned int modelId) relatedModelInfo.pClump = pReadClump; relatedModelInfo.bDeleteOldRwObject = false; - RpClumpForAllAtomics(pReadClump, reinterpret_cast(CFileLoader_SetRelatedModelInfoCB), &relatedModelInfo); + RpClumpForAllAtomics(pReadClump, RelatedModelInfoShim, &relatedModelInfo); RpClumpDestroy(pReadClump); } @@ -172,7 +191,19 @@ RpAtomic* CFileLoader_SetRelatedModelInfoCB(RpAtomic* atomic, SRelatedModelInfo* RwFrame* pOldFrame = reinterpret_cast(atomic->object.object.parent); char* frameNodeName = GetFrameNodeName(pOldFrame); bool bDamage = false; - GetNameAndDamage(frameNodeName, name, bDamage); + + // Check for null pointers before using them + if (!frameNodeName) + { + // Handle case where frame node name is null + strcpy_s(name, sizeof(name), "unknown"); + bDamage = false; + } + else + { + GetNameAndDamage(frameNodeName, name, bDamage); + } + CVisibilityPlugins_SetAtomicRenderCallback(atomic, 0); RpAtomic* pOldAtomic = reinterpret_cast(pBaseModelInfo->pRwObject); @@ -212,16 +243,35 @@ CEntitySAInterface* CFileLoader_LoadObjectInstance(const char* szLine) char szModelName[24]; SFileObjectInstance inst; - sscanf(szLine, "%d %s %d %f %f %f %f %f %f %f %d", &inst.modelID, szModelName, &inst.interiorID, &inst.position.fX, &inst.position.fY, &inst.position.fZ, - &inst.rotation.fX, &inst.rotation.fY, &inst.rotation.fZ, &inst.rotation.fW, &inst.lod); + // Use safer scanf with width specifier to prevent buffer overflow + int result = sscanf(szLine, "%d %23s %d %f %f %f %f %f %f %f %d", &inst.modelID, szModelName, &inst.interiorID, &inst.position.fX, &inst.position.fY, + &inst.position.fZ, &inst.rotation.fX, &inst.rotation.fY, &inst.rotation.fZ, &inst.rotation.fW, &inst.lod); + + // Check if all expected fields were parsed + if (result != 11) + { + // Return null or handle error appropriately + return nullptr; + } /* - A quaternion is must be normalized. GTA is relying on an internal R* exporter and everything is OK, + A quaternion must be normalized. GTA is relying on an internal R* exporter and everything is OK, but custom exporters might not contain the normalization. And we must do it instead. */ const float fLenSq = inst.rotation.LengthSquared(); if (fLenSq > 0.0f && std::fabs(fLenSq - 1.0f) > std::numeric_limits::epsilon()) - inst.rotation /= std::sqrt(fLenSq); + { + const float fLength = std::sqrt(fLenSq); + inst.rotation /= fLength; + } + else if (fLenSq <= 0.0f) + { + // Handle degenerate case: set to identity quaternion + inst.rotation.fX = 0.0f; + inst.rotation.fY = 0.0f; + inst.rotation.fZ = 0.0f; + inst.rotation.fW = 1.0f; + } return ((CEntitySAInterface * (__cdecl*)(SFileObjectInstance*))0x538090)(&inst); } diff --git a/Client/game_sa/CFileLoaderSA.h b/Client/game_sa/CFileLoaderSA.h index 260bc93cb24..7819aebc92c 100644 --- a/Client/game_sa/CFileLoaderSA.h +++ b/Client/game_sa/CFileLoaderSA.h @@ -3,6 +3,7 @@ #include "CVector.h" #include "CVector4D.h" +// Forward declarations class CEntitySAInterface; struct RpAtomic; struct RpClump; @@ -29,11 +30,14 @@ class CFileLoaderSA CFileLoaderSA(); ~CFileLoaderSA(); - static CEntitySAInterface* LoadObjectInstance(SFileObjectInstance*); + // Two overloads for different use cases + static CEntitySAInterface* LoadObjectInstance(SFileObjectInstance* obj); + static CEntitySAInterface* LoadObjectInstance(const char* szLine); static void StaticSetHooks(); }; +// Global functions that are hooked/called by the game bool CFileLoader_LoadAtomicFile(RwStream* stream, unsigned int modelId); RpAtomic* CFileLoader_SetRelatedModelInfoCB(RpAtomic* atomic, SRelatedModelInfo* pRelatedModelInfo); CEntitySAInterface* CFileLoader_LoadObjectInstance(const char* szLine); diff --git a/Client/game_sa/CFireManagerSA.cpp b/Client/game_sa/CFireManagerSA.cpp index cd04f962dca..5f176a44c14 100644 --- a/Client/game_sa/CFireManagerSA.cpp +++ b/Client/game_sa/CFireManagerSA.cpp @@ -19,8 +19,7 @@ extern CGameSA* pGame; CFireManagerSA::CFireManagerSA() { for (int i = 0; i < MAX_FIRES; i++) - Fires[i] = new CFireSA( - (CFireSAInterface*)(CLASS_CFireManager + 40 * i)); // + 4 because thats the position of CFire array in CFireManager (see source) + Fires[i] = new CFireSA((CFireSAInterface*)(CLASS_CFireManager + 40 * i)); // + 4 because thats the position of CFire array in CFireManager (see source) } CFireManagerSA::~CFireManagerSA() @@ -38,15 +37,10 @@ void CFireManagerSA::ExtinguishPoint(CVector& vecPosition, float fRadius) float fZ = vecPosition.fZ; DWORD dwFunction = FUNC_ExtinguishPoint; - _asm - { - mov ecx, CLASS_CFireManager - push fRadius - push fZ - push fY - push fX - call dwFunction - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0xB71F80), decltype(fX), decltype(fY), decltype(fZ), decltype(fRadius)); + reinterpret_cast(dwFunction)(0xB71F80, fX, fY, fZ, fRadius); + // clang-format on } CFire* CFireManagerSA::StartFire(CEntity* entityTarget, CEntity* entityCreator, float fSize = DEFAULT_FIRE_PARTICLE_SIZE) @@ -94,11 +88,12 @@ void CFireManagerSA::ExtinguishAllFires() CFire* CFireManagerSA::GetFire(DWORD ID) { - if (ID < MAX_FIRES) + if (ID < MAX_FIRES) { return Fires[ID]; - else + } else { return NULL; } +} DWORD CFireManagerSA::GetFireCount() { diff --git a/Client/game_sa/CFireManagerSA.h b/Client/game_sa/CFireManagerSA.h index 8f0315ccafe..f1d4da3e23d 100644 --- a/Client/game_sa/CFireManagerSA.h +++ b/Client/game_sa/CFireManagerSA.h @@ -17,13 +17,13 @@ class CEntity; class CFireSA; class CFireSAInterface; -#define FUNC_ExtinguishPoint 0x539450 +#define FUNC_ExtinguishPoint 0x539450 -#define ARRAY_CFire (VAR_CFireCount + 4) -#define CLASS_CFireManager 0xB71F80 +#define ARRAY_CFire (VAR_CFireCount + 4) +#define CLASS_CFireManager 0xB71F80 -#define DEFAULT_FIRE_PARTICLE_SIZE 1.8 -#define MAX_FIRES 60 +#define DEFAULT_FIRE_PARTICLE_SIZE 1.8 +#define MAX_FIRES 60 class CFireManagerSA : public CFireManager { diff --git a/Client/game_sa/CFireSA.cpp b/Client/game_sa/CFireSA.cpp index e0321aec944..c08fe5e97e9 100644 --- a/Client/game_sa/CFireSA.cpp +++ b/Client/game_sa/CFireSA.cpp @@ -26,11 +26,10 @@ void CFireSA::Extinguish() { DWORD dwFunction = FUNC_Extinguish; DWORD dwPointer = (DWORD)internalInterface; - _asm - { - mov ecx, dwPointer - call dwFunction - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwPointer) ); + reinterpret_cast(dwFunction)(dwPointer); + // clang-format on internalInterface->bActive = false; } @@ -161,11 +160,12 @@ bool CFireSA::IsIgnited() bool CFireSA::IsFree() { - if (!internalInterface->bActive && !internalInterface->bCreatedByScript) + if (!internalInterface->bActive && !internalInterface->bCreatedByScript) { return true; - else + } else { return false; } +} void CFireSA::SetSilent(bool bSilent) { @@ -184,13 +184,10 @@ void CFireSA::Ignite() CVector* vecPosition = GetPosition(); DWORD dwFunc = FUNC_CreateFxSysForStrength; DWORD dwThis = (DWORD)internalInterface; - _asm - { - mov ecx, dwThis - push 0 - push vecPosition - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(vecPosition), decltype(0)); + reinterpret_cast(dwFunc)(dwThis, vecPosition, 0); + // clang-format on internalInterface->bBeingExtinguished = 0; internalInterface->bFirstGeneration = 1; @@ -234,26 +231,34 @@ static void AbortFireTask(CEntitySAInterface* entityOnFire, DWORD returnAddress) taskManager->RemoveTaskSecondary(TASK_SECONDARY_PARTIAL_ANIM, TASK_SIMPLE_PLAYER_ON_FIRE); } -#define HOOKPOS_CFire_Extinguish 0x539429 +#define HOOKPOS_CFire_Extinguish 0x539429 #define HOOKSIZE_CFire_Extinguish 6 -static constexpr std::uintptr_t CONTINUE_CFire_Extinguish = 0x53942F; -static void _declspec(naked) HOOK_CFire_Extinguish() +static constexpr intptr_t CONTINUE_CFire_Extinguish = 0x53942F; +static void __declspec(naked) HOOK_CFire_Extinguish() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - mov [eax+730h], edi + mov [eax+730h], edi - push ebx - mov ebx, [esp+0Ch] + push ebx + mov ebx, [esp+12] + push edi + push esi - push ebx - push eax - call AbortFireTask - add esp, 8 + push ebx // returnAddress + push eax // entityOnFire + call AbortFireTask + add esp, 8 - pop ebx - jmp CONTINUE_CFire_Extinguish + pop esi + pop edi + pop ebx + jmp CONTINUE_CFire_Extinguish } + // clang-format on } void CFireSA::StaticSetHooks() diff --git a/Client/game_sa/CFireSA.h b/Client/game_sa/CFireSA.h index 6a3e66a58ed..67a5e74eaac 100644 --- a/Client/game_sa/CFireSA.h +++ b/Client/game_sa/CFireSA.h @@ -17,8 +17,8 @@ class CEntitySAInterface; class FxSystem_c; -#define FUNC_Extinguish 0x5393F0 -#define FUNC_CreateFxSysForStrength 0x539360 +#define FUNC_Extinguish 0x5393F0 +#define FUNC_CreateFxSysForStrength 0x539360 class CFireSAInterface { diff --git a/Client/game_sa/CFontSA.cpp b/Client/game_sa/CFontSA.cpp index d9a724285c3..1e00158cf45 100644 --- a/Client/game_sa/CFontSA.cpp +++ b/Client/game_sa/CFontSA.cpp @@ -14,7 +14,7 @@ void CFontSA::PrintChar(float x, float y, char character) { - // Call CFont::PrintChar + // Call CFont::PrintChar ((void(_cdecl*)(float, float, char))0x718A10)(x, y, character); } @@ -179,5 +179,9 @@ eFontStyle CFontSA::GetFontStyle() return eFontStyle::FONT_PRICEDOWN; case 2: return eFontStyle::FONT_MENU; + default: + break; } + + return eFontStyle::FONT_MENU; } diff --git a/Client/game_sa/CFontSA.h b/Client/game_sa/CFontSA.h index 2d724be8bfa..6651f42895e 100644 --- a/Client/game_sa/CFontSA.h +++ b/Client/game_sa/CFontSA.h @@ -65,7 +65,7 @@ class CFontSA static void SetRightJustifyWrap(float wrap); static void SetDropShadowPosition(std::int16_t offset); - static void SetEdge(std::int16_t edgeSize); // outline + static void SetEdge(std::int16_t edgeSize); // outline static void SetProportional(bool enable); diff --git a/Client/game_sa/CFxManagerSA.cpp b/Client/game_sa/CFxManagerSA.cpp index 09177318c04..ab58f756b20 100644 --- a/Client/game_sa/CFxManagerSA.cpp +++ b/Client/game_sa/CFxManagerSA.cpp @@ -21,16 +21,10 @@ CFxSystem* CFxManagerSA::CreateFxSystem(const char* szBlueprint, const CVector& DWORD dwFunc = FUNC_FxManager_c__CreateFxSystem; CFxSystemSAInterface* pFxSystem; - _asm - { - mov ecx, dwThis - push bSkipCameraFrustumCheck - push pRwMatrixTag - push pvecPosition - push szBlueprint - call dwFunc - mov pFxSystem, eax - } + // clang-format off + using func_t = decltype(pFxSystem) (__thiscall*)(decltype(dwThis), decltype(szBlueprint), decltype(pvecPosition), decltype(pRwMatrixTag), decltype(bSkipCameraFrustumCheck)); +pFxSystem = reinterpret_cast(dwFunc)(dwThis, szBlueprint, pvecPosition, pRwMatrixTag, bSkipCameraFrustumCheck); + // clang-format on if (pFxSystem) { @@ -50,12 +44,10 @@ void CFxManagerSA::DestroyFxSystem(CFxSystem* pFxSystem) void* pFxSA = pFxSystem->GetInterface(); - _asm - { - mov ecx, dwThis - push pFxSA - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pFxSA)); + reinterpret_cast(dwFunc)(dwThis, pFxSA); + // clang-format on } // diff --git a/Client/game_sa/CFxManagerSA.h b/Client/game_sa/CFxManagerSA.h index 5a8238bb2b3..c1f72389143 100644 --- a/Client/game_sa/CFxManagerSA.h +++ b/Client/game_sa/CFxManagerSA.h @@ -12,9 +12,9 @@ #include -#define FUNC_FxManager_c__CreateFxSystem 0x4A9BE0 -#define FUNC_FxManager_c__DestroyFxSystem 0x4A9810 -#define FUNC_FxManager_c__GetSystemByName 0x4A9360 +#define FUNC_FxManager_c__CreateFxSystem 0x4A9BE0 +#define FUNC_FxManager_c__DestroyFxSystem 0x4A9810 +#define FUNC_FxManager_c__GetSystemByName 0x4A9360 class CFxSystemBPSAInterface; class CFxSystemSAInterface; @@ -28,32 +28,32 @@ class CFxMemoryPoolSAInterface int unk; }; -class CFxManagerSAInterface // FxManager_c +class CFxManagerSAInterface // FxManager_c { public: // List_c - CFxSystemBPSAInterface* pFirstFxBlueprint; // 0x00 - CFxSystemBPSAInterface* pUnknownFxBlueprint; // 0x04 - unsigned int uiBlueprintCount; // 0x08 + CFxSystemBPSAInterface* pFirstFxBlueprint; // 0x00 + CFxSystemBPSAInterface* pUnknownFxBlueprint; // 0x04 + unsigned int uiBlueprintCount; // 0x08 // List_c - CFxSystemSAInterface* pFirstFxSystem; // 0x0C - CFxSystemSAInterface* pUnknownFxSystem; // 0x10 - unsigned int uiFxSystemCount; // 0x14 + CFxSystemSAInterface* pFirstFxSystem; // 0x0C + CFxSystemSAInterface* pUnknownFxSystem; // 0x10 + unsigned int uiFxSystemCount; // 0x14 void* pUnk; // List_c - CFxEmitterSAInterface* pFirstFxEmitter; // 0x18 - CFxEmitterSAInterface* pUnknownFxEmitter; // 0x1C - unsigned int uiFxEmitterCount; // 0x20 + CFxEmitterSAInterface* pFirstFxEmitter; // 0x18 + CFxEmitterSAInterface* pUnknownFxEmitter; // 0x1C + unsigned int uiFxEmitterCount; // 0x20 - int iTxdSlot; // 0x24 - CVector* pvecWindDirection; // 0x28 - float fWindStrength; // 0x2C - int unk[21]; // 0x30 (at least partially) Frustrum info - int iCurrentMatrix; // 0x88 - RwMatrix* apmatMatrices[8]; // 0x8C - CFxMemoryPoolSAInterface fxMemoryPool; // 0xAC + int iTxdSlot; // 0x24 + CVector* pvecWindDirection; // 0x28 + float fWindStrength; // 0x2C + int unk[21]; // 0x30 (at least partially) Frustrum info + int iCurrentMatrix; // 0x88 + RwMatrix* apmatMatrices[8]; // 0x8C + CFxMemoryPoolSAInterface fxMemoryPool; // 0xAC }; static_assert(sizeof(CFxManagerSAInterface) == 0xB8, "Invalid size for CFxManagerSAInterface"); diff --git a/Client/game_sa/CFxSA.cpp b/Client/game_sa/CFxSA.cpp index 30107e4fa3a..95ce5a51e3a 100644 --- a/Client/game_sa/CFxSA.cpp +++ b/Client/game_sa/CFxSA.cpp @@ -19,15 +19,10 @@ void CFxSA::AddBlood(CVector& vecPosition, CVector& vecDirection, int iCount, fl CVector* pvecDirection = &vecDirection; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CFx_AddBlood; - _asm - { - mov ecx, dwThis - push fBrightness - push iCount - push pvecDirection - push pvecPosition - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pvecPosition), decltype(pvecDirection), decltype(iCount), decltype(fBrightness)); + reinterpret_cast(dwFunc)(dwThis, pvecPosition, pvecDirection, iCount, fBrightness); + // clang-format on } void CFxSA::AddWood(CVector& vecPosition, CVector& vecDirection, int iCount, float fBrightness) @@ -36,15 +31,10 @@ void CFxSA::AddWood(CVector& vecPosition, CVector& vecDirection, int iCount, flo CVector* pvecDirection = &vecDirection; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CFx_AddWood; - _asm - { - mov ecx, dwThis - push fBrightness - push iCount - push pvecDirection - push pvecPosition - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pvecPosition), decltype(pvecDirection), decltype(iCount), decltype(fBrightness)); + reinterpret_cast(dwFunc)(dwThis, pvecPosition, pvecDirection, iCount, fBrightness); + // clang-format on } void CFxSA::AddSparks(CVector& vecPosition, CVector& vecDirection, float fForce, int iCount, CVector vecAcrossLine, unsigned char ucBlurIf0, float fSpread, @@ -55,21 +45,10 @@ void CFxSA::AddSparks(CVector& vecPosition, CVector& vecDirection, float fForce, float fX = vecAcrossLine.fX, fY = vecAcrossLine.fY, fZ = vecAcrossLine.fZ; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CFx_AddSparks; - _asm - { - mov ecx, dwThis - push fLife - push fSpread - push ucBlurIf0 - push fZ - push fY - push fX - push iCount - push fForce - push pvecDirection - push pvecPosition - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pvecPosition), decltype(pvecDirection), decltype(fForce), decltype(iCount), decltype(fX), decltype(fY), decltype(fZ), decltype(ucBlurIf0), decltype(fSpread), decltype(fLife)); + reinterpret_cast(dwFunc)(dwThis, pvecPosition, pvecDirection, fForce, iCount, fX, fY, fZ, ucBlurIf0, fSpread, fLife); + // clang-format on } void CFxSA::AddTyreBurst(CVector& vecPosition, CVector& vecDirection) @@ -78,13 +57,10 @@ void CFxSA::AddTyreBurst(CVector& vecPosition, CVector& vecDirection) CVector* pvecDirection = &vecDirection; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CFx_AddTyreBurst; - _asm - { - mov ecx, dwThis - push pvecDirection - push pvecPosition - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pvecPosition), decltype(pvecDirection)); + reinterpret_cast(dwFunc)(dwThis, pvecPosition, pvecDirection); + // clang-format on } void CFxSA::AddBulletImpact(CVector& vecPosition, CVector& vecDirection, int iSmokeSize, int iSparkCount, float fSmokeIntensity) @@ -93,16 +69,10 @@ void CFxSA::AddBulletImpact(CVector& vecPosition, CVector& vecDirection, int iSm CVector* pvecDirection = &vecDirection; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CFx_AddBulletImpact; - _asm - { - mov ecx, dwThis - push fSmokeIntensity - push iSparkCount - push iSmokeSize - push pvecDirection - push pvecPosition - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pvecPosition), decltype(pvecDirection), decltype(iSmokeSize), decltype(iSparkCount), decltype(fSmokeIntensity)); + reinterpret_cast(dwFunc)(dwThis, pvecPosition, pvecDirection, iSmokeSize, iSparkCount, fSmokeIntensity); + // clang-format on } void CFxSA::AddPunchImpact(CVector& vecPosition, CVector& vecDirection, int i) @@ -111,14 +81,10 @@ void CFxSA::AddPunchImpact(CVector& vecPosition, CVector& vecDirection, int i) CVector* pvecDirection = &vecDirection; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CFx_AddPunchImpact; - _asm - { - mov ecx, dwThis - push i - push pvecDirection - push pvecPosition - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pvecPosition), decltype(pvecDirection), decltype(i)); + reinterpret_cast(dwFunc)(dwThis, pvecPosition, pvecDirection, i); + // clang-format on } void CFxSA::AddDebris(CVector& vecPosition, RwColor& rwColor, float fDebrisScale, int iCount) @@ -127,15 +93,10 @@ void CFxSA::AddDebris(CVector& vecPosition, RwColor& rwColor, float fDebrisScale RwColor* pColor = &rwColor; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CFx_AddDebris; - _asm - { - mov ecx, dwThis - push iCount - push fDebrisScale - push pColor - push pvecPosition - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pvecPosition), decltype(pColor), decltype(fDebrisScale), decltype(iCount)); + reinterpret_cast(dwFunc)(dwThis, pvecPosition, pColor, fDebrisScale, iCount); + // clang-format on } void CFxSA::AddGlass(CVector& vecPosition, RwColor& rwColor, float fDebrisScale, int iCount) @@ -144,15 +105,10 @@ void CFxSA::AddGlass(CVector& vecPosition, RwColor& rwColor, float fDebrisScale, RwColor* pColor = &rwColor; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CFx_AddGlass; - _asm - { - mov ecx, dwThis - push iCount - push fDebrisScale - push pColor - push pvecPosition - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pvecPosition), decltype(pColor), decltype(fDebrisScale), decltype(iCount)); + reinterpret_cast(dwFunc)(dwThis, pvecPosition, pColor, fDebrisScale, iCount); + // clang-format on } void CFxSA::TriggerWaterHydrant(CVector& vecPosition) @@ -160,12 +116,10 @@ void CFxSA::TriggerWaterHydrant(CVector& vecPosition) CVector* pvecPosition = &vecPosition; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CFx_TriggerWaterHydrant; - _asm - { - mov ecx, dwThis - push pvecPosition - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pvecPosition)); + reinterpret_cast(dwFunc)(dwThis, pvecPosition); + // clang-format on } void CFxSA::TriggerGunshot(CEntity* pEntity, CVector& vecPosition, CVector& vecDirection, bool bIncludeSparks) @@ -175,15 +129,10 @@ void CFxSA::TriggerGunshot(CEntity* pEntity, CVector& vecPosition, CVector& vecD CVector* pvecDirection = &vecDirection; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CFx_TriggerGunshot; - _asm - { - mov ecx, dwThis - push bIncludeSparks - push pvecDirection - push pvecPosition - push dwEntity - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwEntity), decltype(pvecPosition), decltype(pvecDirection), decltype(bIncludeSparks)); + reinterpret_cast(dwFunc)(dwThis, dwEntity, pvecPosition, pvecDirection, bIncludeSparks); + // clang-format on } void CFxSA::TriggerTankFire(CVector& vecPosition, CVector& vecDirection) @@ -192,13 +141,10 @@ void CFxSA::TriggerTankFire(CVector& vecPosition, CVector& vecDirection) CVector* pvecDirection = &vecDirection; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CFx_TriggerTankFire; - _asm - { - mov ecx, dwThis - push pvecDirection - push pvecPosition - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pvecPosition), decltype(pvecDirection)); + reinterpret_cast(dwFunc)(dwThis, pvecPosition, pvecDirection); + // clang-format on } void CFxSA::TriggerWaterSplash(CVector& vecPosition) @@ -206,12 +152,10 @@ void CFxSA::TriggerWaterSplash(CVector& vecPosition) CVector* pvecPosition = &vecPosition; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CFx_TriggerWaterSplash; - _asm - { - mov ecx, dwThis - push pvecPosition - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pvecPosition)); + reinterpret_cast(dwFunc)(dwThis, pvecPosition); + // clang-format on } void CFxSA::TriggerBulletSplash(CVector& vecPosition) @@ -219,12 +163,10 @@ void CFxSA::TriggerBulletSplash(CVector& vecPosition) CVector* pvecPosition = &vecPosition; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CFx_TriggerBulletSplash; - _asm - { - mov ecx, dwThis - push pvecPosition - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pvecPosition)); + reinterpret_cast(dwFunc)(dwThis, pvecPosition); + // clang-format on } void CFxSA::TriggerFootSplash(CVector& vecPosition) @@ -232,18 +174,17 @@ void CFxSA::TriggerFootSplash(CVector& vecPosition) CVector* pvecPosition = &vecPosition; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CFx_TriggerFootSplash; - _asm - { - mov ecx, dwThis - push pvecPosition - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(pvecPosition)); + reinterpret_cast(dwFunc)(dwThis, pvecPosition); + // clang-format on } -void CFxSA::AddParticle(FxParticleSystems eFxParticle, const CVector& vecPosition, const CVector& vecDirection, float fR, float fG, float fB, float fA, bool bRandomizeColors, std::uint32_t iCount, float fBrightness, float fSize, bool bRandomizeSizes, float fLife) +void CFxSA::AddParticle(FxParticleSystems eFxParticle, const CVector& vecPosition, const CVector& vecDirection, float fR, float fG, float fB, float fA, + bool bRandomizeColors, std::uint32_t iCount, float fBrightness, float fSize, bool bRandomizeSizes, float fLife) { // Init our own FxPrtMult struct - FxPrtMult_c fxPrt{{fR,fG,fB,fA}, fSize, 0, fLife}; + FxPrtMult_c fxPrt{{fR, fG, fB, fA}, fSize, 0, fLife}; CVector newDirection; FxSystem_c* fxParticleSystem; @@ -315,9 +256,10 @@ void CFxSA::AddParticle(FxParticleSystems eFxParticle, const CVector& vecPositio fxPrt.m_color.blue = (rand() % 10000) * 0.0001f * fB + 0.04f; } - if (bRandomizeSizes) + if (bRandomizeSizes) { // 0x49EF21 - Calculate random size for each particle fxPrt.m_fSize = (rand() % 10000) * 0.0001f * fSize + 0.3f; +} // 0x49EF4C - Calculate random direction for each particle newDirection = CVector(vecDirection.fX * 4, vecDirection.fY * 4, vecDirection.fZ * 4); @@ -326,6 +268,7 @@ void CFxSA::AddParticle(FxParticleSystems eFxParticle, const CVector& vecPositio newDirection.fZ = (rand() % 10000) * 0.0001f * 4 - 2 + newDirection.fZ; // Call FxSystem_c::AddParticle - ((int(__thiscall*)(FxSystem_c*, const CVector*, const CVector*, float, FxPrtMult_c*, float, float, float, int))FUNC_FXSystem_c_AddParticle)(fxParticleSystem, &vecPosition, &newDirection, 0, &fxPrt, -1.0f, fBrightness, 0, 0); + ((int(__thiscall*)(FxSystem_c*, const CVector*, const CVector*, float, FxPrtMult_c*, float, float, float, int))FUNC_FXSystem_c_AddParticle)( + fxParticleSystem, &vecPosition, &newDirection, 0, &fxPrt, -1.0f, fBrightness, 0, 0); } } diff --git a/Client/game_sa/CFxSA.h b/Client/game_sa/CFxSA.h index efb7d0403f8..f846c0d444a 100644 --- a/Client/game_sa/CFxSA.h +++ b/Client/game_sa/CFxSA.h @@ -16,21 +16,21 @@ struct RwColor; class FxSystem_c; -#define FUNC_CFx_AddBlood 0x49eb00 -#define FUNC_CFx_AddWood 0x49ee10 -#define FUNC_CFx_AddSparks 0x49f040 -#define FUNC_CFx_AddTyreBurst 0x49f300 -#define FUNC_CFx_AddBulletImpact 0x49f3d0 -#define FUNC_CFx_AddPunchImpact 0x49f670 -#define FUNC_CFx_AddDebris 0x49f750 -#define FUNC_CFx_AddGlass 0x49f970 -#define FUNC_CFx_TriggerWaterHydrant 0x4a0d70 -#define FUNC_CFx_TriggerGunshot 0x4a0de0 -#define FUNC_CFx_TriggerTankFire 0x4a0fa0 -#define FUNC_CFx_TriggerWaterSplash 0x4a1070 -#define FUNC_CFx_TriggerBulletSplash 0x4a10e0 -#define FUNC_CFx_TriggerFootSplash 0x4a1150 -#define FUNC_FXSystem_c_AddParticle 0x4AA440 +#define FUNC_CFx_AddBlood 0x49eb00 +#define FUNC_CFx_AddWood 0x49ee10 +#define FUNC_CFx_AddSparks 0x49f040 +#define FUNC_CFx_AddTyreBurst 0x49f300 +#define FUNC_CFx_AddBulletImpact 0x49f3d0 +#define FUNC_CFx_AddPunchImpact 0x49f670 +#define FUNC_CFx_AddDebris 0x49f750 +#define FUNC_CFx_AddGlass 0x49f970 +#define FUNC_CFx_TriggerWaterHydrant 0x4a0d70 +#define FUNC_CFx_TriggerGunshot 0x4a0de0 +#define FUNC_CFx_TriggerTankFire 0x4a0fa0 +#define FUNC_CFx_TriggerWaterSplash 0x4a1070 +#define FUNC_CFx_TriggerBulletSplash 0x4a10e0 +#define FUNC_CFx_TriggerFootSplash 0x4a1150 +#define FUNC_FXSystem_c_AddParticle 0x4AA440 class CFxSAInterface { @@ -76,7 +76,8 @@ class CFxSA : public CFx void TriggerWaterSplash(CVector& vecPosition); void TriggerBulletSplash(CVector& vecPosition); void TriggerFootSplash(CVector& vecPosition); - void AddParticle(FxParticleSystems eFxParticle, const CVector& vecPosition, const CVector& vecDirection, float fR, float fG, float fB, float fA, bool bRandomizeColors, std::uint32_t iCount, float fBrightness, float fSize, bool bRandomizeSizes, float fLife); + void AddParticle(FxParticleSystems eFxParticle, const CVector& vecPosition, const CVector& vecDirection, float fR, float fG, float fB, float fA, + bool bRandomizeColors, std::uint32_t iCount, float fBrightness, float fSize, bool bRandomizeSizes, float fLife); private: CFxSAInterface* m_pInterface; diff --git a/Client/game_sa/CFxSystemBPSA.h b/Client/game_sa/CFxSystemBPSA.h index c0e24460b83..5283dfacfbd 100644 --- a/Client/game_sa/CFxSystemBPSA.h +++ b/Client/game_sa/CFxSystemBPSA.h @@ -17,18 +17,18 @@ class CFxSystemBPSAInterface { public: // inherited from ListItem_c - CFxSystemBPSAInterface* pPrevious; // 0x00 - CFxSystemBPSAInterface* pNext; // 0x04 + CFxSystemBPSAInterface* pPrevious; // 0x00 + CFxSystemBPSAInterface* pNext; // 0x04 // Actual members - char* szNameHash; // 0x08 - float fLength; // 0x0C - float fLoopIntervalMinimum; // 0x10 - float fLoopIntervalLength; // 0x14 - ushort usCullDistance; // 0x18 - char cPlayMode; // 0x1A - char cNumOfPrims; // 0x1B - CFxEmitterBPSAInterface** pPrims; // 0x1C (pPrims[0] to pPrims[cNumOfPrims-1]) - void* pBoundingSphere; // 0x20 + char* szNameHash; // 0x08 + float fLength; // 0x0C + float fLoopIntervalMinimum; // 0x10 + float fLoopIntervalLength; // 0x14 + ushort usCullDistance; // 0x18 + char cPlayMode; // 0x1A + char cNumOfPrims; // 0x1B + CFxEmitterBPSAInterface** pPrims; // 0x1C (pPrims[0] to pPrims[cNumOfPrims-1]) + void* pBoundingSphere; // 0x20 }; static_assert(sizeof(CFxSystemBPSAInterface) == 0x24, "Invalid size for CFxSystemBPSAInterface"); diff --git a/Client/game_sa/CFxSystemSA.cpp b/Client/game_sa/CFxSystemSA.cpp index ea8268da81f..71599d93c31 100644 --- a/Client/game_sa/CFxSystemSA.cpp +++ b/Client/game_sa/CFxSystemSA.cpp @@ -43,11 +43,10 @@ void CFxSystemSA::PlayAndKill() { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_FxSystem_c__PlayAndKill; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } void CFxSystemSA::GetMatrix(CMatrix& matrix) @@ -116,11 +115,12 @@ void CFxSystemSA::SetDrawDistance(float fDrawDistance) float CFxSystemSA::GetDrawDistance() { - if (HasCustomDrawDistance()) + if (HasCustomDrawDistance()) { return m_fDrawDistance; - else + } else { return m_pInterface->pBlueprint->usCullDistance / 256.f; } +} bool CFxSystemSA::HasCustomDrawDistance() { @@ -145,9 +145,10 @@ __declspec(noinline) void OnMY_FxSystem_c_Update_MidA_Pre(CFxSystemSAInterface* pFxSystemSAInterface->pBlueprint->usCullDistance = (ushort)(ms_fUsingDrawDistance * 8); ms_fFxSystemUpdateCullDistMultiplier = 1 / 8.f; } - else + else { ms_fUsingDrawDistance = 0; } +} __declspec(noinline) void OnMY_FxSystem_c_Update_MidA_Post() { @@ -162,13 +163,16 @@ __declspec(noinline) void OnMY_FxSystem_c_Update_MidA_Post() } // Hook info -#define HOOKCHECK_FxSystem_c_Update_MidA 0x83 -#define HOOKPOS_FxSystem_c_Update_MidA 0x04AAF70 -#define HOOKSIZE_FxSystem_c_Update_MidA 5 -DWORD RETURN_FxSystem_c_Update_MidA = 0x04AAF75; -void _declspec(naked) HOOK_FxSystem_c_Update_MidA() +#define HOOKCHECK_FxSystem_c_Update_MidA 0x83 +#define HOOKPOS_FxSystem_c_Update_MidA 0x04AAF70 +#define HOOKSIZE_FxSystem_c_Update_MidA 5 +DWORD RETURN_FxSystem_c_Update_MidA = 0x04AAF75; +static void __declspec(naked) HOOK_FxSystem_c_Update_MidA() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push ecx @@ -191,6 +195,7 @@ void _declspec(naked) HOOK_FxSystem_c_Update_MidA() push ebp jmp RETURN_FxSystem_c_Update_MidA } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -230,13 +235,16 @@ __declspec(noinline) void OnMY_FxSystem_c_Update_MidB_Post() } // Hook info -#define HOOKCHECK_FxSystem_c_Update_MidB 0x83 -#define HOOKPOS_FxSystem_c_Update_MidB 0x04AB21D -#define HOOKSIZE_FxSystem_c_Update_MidB 7 -DWORD RETURN_FxSystem_c_Update_MidB = 0x04AB224; -void _declspec(naked) HOOK_FxSystem_c_Update_MidB() +#define HOOKCHECK_FxSystem_c_Update_MidB 0x83 +#define HOOKPOS_FxSystem_c_Update_MidB 0x04AB21D +#define HOOKSIZE_FxSystem_c_Update_MidB 7 +DWORD RETURN_FxSystem_c_Update_MidB = 0x04AB224; +static void __declspec(naked) HOOK_FxSystem_c_Update_MidB() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push ecx @@ -254,6 +262,7 @@ void _declspec(naked) HOOK_FxSystem_c_Update_MidB() jmp RETURN_FxSystem_c_Update_MidB } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/game_sa/CFxSystemSA.h b/Client/game_sa/CFxSystemSA.h index 42a4cf04dfa..5a4bd2685ea 100644 --- a/Client/game_sa/CFxSystemSA.h +++ b/Client/game_sa/CFxSystemSA.h @@ -19,8 +19,8 @@ #define VAR_FxSystemUpdateCullDistMultiplier 0x4AB032 #define VAR_FxCreateParticleCullDistMultiplierA 0x4A4247 #define VAR_FxCreateParticleCullDistMultiplierB 0x4A4255 -#define FX_SYSTEM_UPDATE_CULL_DIST_MULTIPLIER_DEFAULT ( 1 / 256.f ) -#define FX_CREATE_PARTICLE_CULL_DIST_MULTIPLIER_DEFAULT ( 1 / 64.f ) +#define FX_SYSTEM_UPDATE_CULL_DIST_MULTIPLIER_DEFAULT (1 / 256.f) +#define FX_CREATE_PARTICLE_CULL_DIST_MULTIPLIER_DEFAULT (1 / 64.f) class CAEFireAudioEntitySAInterface { @@ -29,39 +29,39 @@ class CAEFireAudioEntitySAInterface // todo: reverse this structure and CAEAudioEntity std::int32_t pad1[0x21]; - void* audio; // 0x84 // TODO: Reverse what this __exactly__ is + void* audio; // 0x84 // TODO: Reverse what this __exactly__ is }; static_assert(sizeof(CAEFireAudioEntitySAInterface) == 0x88, "Invalid size for CAEFireAudioEntitySAInterface"); class FxInfoSAInterface; class CFxSystemBPSAInterface; -class CFxSystemSAInterface // Internal SA Name: FxSystem_c +class CFxSystemSAInterface // Internal SA Name: FxSystem_c { public: // Based upon ListItem_c - CFxSystemSAInterface* pPrevious; // 0x00 - CFxSystemSAInterface* pNext; // 0x04 + CFxSystemSAInterface* pPrevious; // 0x00 + CFxSystemSAInterface* pNext; // 0x04 // Actual members - CFxSystemBPSAInterface* pBlueprint; // 0x08 - RwMatrix* pmatUnknown; // 0x10 - RwMatrix matPosition; // 0x0C - char cPlayStatus; // 0x50 - char cUnknownFlag; // 0x51 - char cConstTime; // 0x52 - char pad; // 0x53 - int unk2[2]; // 0x54 - short sConstTimeMult; // 0x5C - short sRateMult; // 0x5E (This controls how often the effect is renewed) - short sTimeMult; // 0x60 (This controls how fast the effect plays) - char cFlags; // 0x62 - char pad2; // 0x63 - int unk3; // 0x64 - CVector vecVelocity; // 0x68 - void* pSphere; // 0x74 - void** ppParticleEmitters; // 0x78 (Array of particle emitters, amount is defined by the blueprint) - CAEFireAudioEntitySAInterface audioEntity; // 0x7C + CFxSystemBPSAInterface* pBlueprint; // 0x08 + RwMatrix* pmatUnknown; // 0x10 + RwMatrix matPosition; // 0x0C + char cPlayStatus; // 0x50 + char cUnknownFlag; // 0x51 + char cConstTime; // 0x52 + char pad; // 0x53 + int unk2[2]; // 0x54 + short sConstTimeMult; // 0x5C + short sRateMult; // 0x5E (This controls how often the effect is renewed) + short sTimeMult; // 0x60 (This controls how fast the effect plays) + char cFlags; // 0x62 + char pad2; // 0x63 + int unk3; // 0x64 + CVector vecVelocity; // 0x68 + void* pSphere; // 0x74 + void** ppParticleEmitters; // 0x78 (Array of particle emitters, amount is defined by the blueprint) + CAEFireAudioEntitySAInterface audioEntity; // 0x7C }; static_assert(sizeof(CFxSystemSAInterface) == 0x104, "Invalid size for CFxSystemSAInterface"); @@ -103,44 +103,44 @@ class CFxSystemSA : public CFxSystem class FxInfoManagerSAInterface { public: - uint32_t m_nNumInfos; // 0x00 - FxInfoSAInterface* m_pInfos; // 0x04 - uint8_t m_nFirstMovementInfo; // 0x08 - uint8_t m_nFirstRenderInfo; // 0x09 + uint32_t m_nNumInfos; // 0x00 + FxInfoSAInterface* m_pInfos; // 0x04 + uint8_t m_nFirstMovementInfo; // 0x08 + uint8_t m_nFirstRenderInfo; // 0x09 }; static_assert(sizeof(FxInfoManagerSAInterface) == 0xC, "Invalid size for FxInfoManagerSAInterface"); class FxPrimBPSAInterface { public: - void* vtbl; // 0x00 - uint8_t field_4; // 0x04 - uint8_t m_nSrcBlendId; // 0x05 - uint8_t m_nDstBlendId; // 0x06 - uint8_t m_bAlphaOn; // 0x07 - void* m_pCompressedInitialMatrix; // 0x08 - RwTexture* m_apTextures[4]; // 0x0C - void* field_1C; // 0x1C - uint32_t particlesList[3]; // 0x20 -- List_c - FxInfoManagerSAInterface m_infoManager; // 0x2C + void* vtbl; // 0x00 + uint8_t field_4; // 0x04 + uint8_t m_nSrcBlendId; // 0x05 + uint8_t m_nDstBlendId; // 0x06 + uint8_t m_bAlphaOn; // 0x07 + void* m_pCompressedInitialMatrix; // 0x08 + RwTexture* m_apTextures[4]; // 0x0C + void* field_1C; // 0x1C + uint32_t particlesList[3]; // 0x20 -- List_c + FxInfoManagerSAInterface m_infoManager; // 0x2C }; static_assert(sizeof(FxPrimBPSAInterface) == 0x38, "Invalid size for FxPrimBPSAInterface"); class CFxEmitterBPSAInterface : public FxPrimBPSAInterface { public: - uint16_t m_nLodStart; // 0x38 - uint16_t m_nLodEnd; // 0x3A - bool m_bHasInfoFlatData; // 0x3C - bool m_bHasInfoHeatHazeData; // 0x3C + uint16_t m_nLodStart; // 0x38 + uint16_t m_nLodEnd; // 0x3A + bool m_bHasInfoFlatData; // 0x3C + bool m_bHasInfoHeatHazeData; // 0x3C }; static_assert(sizeof(CFxEmitterBPSAInterface) == 0x40, "Invalid size for CFxEmitterBPSAInterface"); class CFxEmitterSAInterface { public: - void* vtbl; // 0x00 - CFxEmitterBPSAInterface* pBlueprint; // 0x04 - CFxSystemSAInterface* pOwner; // 0x08 + void* vtbl; // 0x00 + CFxEmitterBPSAInterface* pBlueprint; // 0x04 + CFxSystemSAInterface* pOwner; // 0x08 // TODO the rest }; diff --git a/Client/game_sa/CGameSA.cpp b/Client/game_sa/CGameSA.cpp index 7cac177f422..980f8b764b3 100644 --- a/Client/game_sa/CGameSA.cpp +++ b/Client/game_sa/CGameSA.cpp @@ -47,6 +47,7 @@ #include "CRopesSA.h" #include "CSettingsSA.h" #include "CStatsSA.h" +#include "CStreamingGC.h" #include "CTaskManagementSystemSA.h" #include "CTasksSA.h" #include "CVisibilityPluginsSA.h" @@ -63,9 +64,9 @@ extern CGameSA* pGame; -unsigned int& CGameSA::ClumpOffset = *(unsigned int*)0xB5F878; +unsigned int& CGameSA::ClumpOffset = *(unsigned int*)0xB5F878; -unsigned int OBJECTDYNAMICINFO_MAX = *(uint32_t*)0x59FB4C != 0x90909090 ? *(uint32_t*)0x59FB4C : 160; // default: 160 +unsigned int OBJECTDYNAMICINFO_MAX = *(uint32_t*)0x59FB4C != 0x90909090 ? *(uint32_t*)0x59FB4C : 160; // default: 160 /** * \todo allow the addon to change the size of the pools (see 0x4C0270 - CPools::Initialise) (in start game?) @@ -97,9 +98,9 @@ CGameSA::CGameSA() } // Prepare all object dynamic infos for CObjectGroupPhysicalPropertiesSA instances - for (unsigned int i = 0; i < OBJECTDYNAMICINFO_MAX; i++) + for (unsigned char i = 0; i < OBJECTDYNAMICINFO_MAX; i++) { - ObjectGroupsInfo[i].SetGroup(i); + ObjectGroupsInfo[i].SetGroup(static_cast(i)); } m_pAudioEngine = new CAudioEngineSA((CAudioEngineSAInterface*)CLASS_CAudioEngine); @@ -212,24 +213,24 @@ CGameSA::CGameSA() m_Cheats[CHEAT_HEALTARMORMONEY] = new SCheatSA((BYTE*)VAR_HealthArmorMoney, false); // Change pool sizes here - m_Pools->SetPoolCapacity(TASK_POOL, 5000); // Default is 500 - m_Pools->SetPoolCapacity(OBJECT_POOL, MAX_OBJECTS); // Default is 350 - m_Pools->SetPoolCapacity(EVENT_POOL, 5000); // Default is 200 - m_Pools->SetPoolCapacity(COL_MODEL_POOL, 12000); // Default is 10150 - m_Pools->SetPoolCapacity(ENV_MAP_MATERIAL_POOL, 16000); // Default is 4096 - m_Pools->SetPoolCapacity(ENV_MAP_ATOMIC_POOL, 4000); // Default is 1024 - m_Pools->SetPoolCapacity(SPEC_MAP_MATERIAL_POOL, 16000); // Default is 4096 - m_Pools->SetPoolCapacity(ENTRY_INFO_NODE_POOL, MAX_ENTRY_INFO_NODES); // Default is 500 - m_Pools->SetPoolCapacity(POINTER_SINGLE_LINK_POOL, MAX_POINTER_SINGLE_LINKS); // Default is 70000 - m_Pools->SetPoolCapacity(POINTER_DOUBLE_LINK_POOL, MAX_POINTER_DOUBLE_LINKS); // Default is 3200 + m_Pools->SetPoolCapacity(TASK_POOL, 5000); // Default is 500 + m_Pools->SetPoolCapacity(OBJECT_POOL, MAX_OBJECTS); // Default is 350 + m_Pools->SetPoolCapacity(EVENT_POOL, 5000); // Default is 200 + m_Pools->SetPoolCapacity(COL_MODEL_POOL, 12000); // Default is 10150 + m_Pools->SetPoolCapacity(ENV_MAP_MATERIAL_POOL, 16000); // Default is 4096 + m_Pools->SetPoolCapacity(ENV_MAP_ATOMIC_POOL, 4000); // Default is 1024 + m_Pools->SetPoolCapacity(SPEC_MAP_MATERIAL_POOL, 16000); // Default is 4096 + m_Pools->SetPoolCapacity(ENTRY_INFO_NODE_POOL, MAX_ENTRY_INFO_NODES); // Default is 500 + m_Pools->SetPoolCapacity(POINTER_SINGLE_LINK_POOL, MAX_POINTER_SINGLE_LINKS); // Default is 70000 + m_Pools->SetPoolCapacity(POINTER_DOUBLE_LINK_POOL, MAX_POINTER_DOUBLE_LINKS); // Default is 3200 dassert(m_Pools->GetPoolCapacity(POINTER_SINGLE_LINK_POOL) == MAX_POINTER_SINGLE_LINKS); // Increase streaming object instances list size - MemPut(0x05B8E55, MAX_RWOBJECT_INSTANCES * 12); // Default is 1000 * 12 - MemPut(0x05B8EB0, MAX_RWOBJECT_INSTANCES * 12); // Default is 1000 * 12 + MemPut(0x05B8E55, MAX_RWOBJECT_INSTANCES * 12); // Default is 1000 * 12 + MemPut(0x05B8EB0, MAX_RWOBJECT_INSTANCES * 12); // Default is 1000 * 12 // Increase matrix array size - MemPut(0x054F3A1, MAX_OBJECTS * 3); // Default is 900 + MemPut(0x054F3A1, MAX_OBJECTS * 3); // Default is 900 CEntitySAInterface::StaticSetHooks(); CPhysicalSAInterface::StaticSetHooks(); @@ -250,6 +251,8 @@ CGameSA::CGameSA() CFireSA::StaticSetHooks(); CPtrNodeSingleLinkPoolSA::StaticSetHooks(); CVehicleAudioSettingsManagerSA::StaticSetHooks(); + CPointLightsSA::StaticSetHooks(); + CBuildingRemovalSA::StaticSetHooks(); } catch (const std::bad_alloc& e) { @@ -277,6 +280,9 @@ CGameSA::CGameSA() CGameSA::~CGameSA() { + // Shutdown streaming GC hooks + CStreamingGC::Shutdown(); + delete reinterpret_cast(m_pPlayerInfo); for (int i = 0; i < NUM_WeaponInfosTotal; i++) @@ -346,18 +352,23 @@ CWeaponInfo* CGameSA::GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill) } return WeaponInfos[offset + weapon]; } - else + else { return NULL; } +} void CGameSA::Pause(bool bPaused) { - MemPutFast(0xB7CB49, bPaused); // CTimer::m_UserPause + MemPutFast(0xB7CB49, bPaused); // CTimer::m_UserPause } CModelInfo* CGameSA::GetModelInfo(DWORD dwModelID, bool bCanBeInvalid) { - if (dwModelID < GetCountOfAllFileIDs()) + const int32_t count = GetCountOfAllFileIDs(); + if (count <= 0) + return nullptr; + + if (dwModelID < static_cast(count)) { if (ModelInfo[dwModelID].IsValid() || bCanBeInvalid) { @@ -375,8 +386,8 @@ CModelInfo* CGameSA::GetModelInfo(DWORD dwModelID, bool bCanBeInvalid) void CGameSA::StartGame() { SetSystemState(SystemState::GS_INIT_PLAYING_GAME); - MemPutFast(0xB7CB49, 0); // CTimer::m_UserPause - MemPutFast(0xBA67A4, 0); // FrontEndMenuManager + 0x5C + MemPutFast(0xB7CB49, 0); // CTimer::m_UserPause + MemPutFast(0xBA67A4, 0); // FrontEndMenuManager + 0x5C } /** @@ -385,12 +396,12 @@ void CGameSA::StartGame() */ void CGameSA::SetSystemState(SystemState State) { - MemPutFast(0xC8D4C0, (DWORD)State); // gGameState + MemPutFast(0xC8D4C0, (DWORD)State); // gGameState } SystemState CGameSA::GetSystemState() { - return *(SystemState*)0xC8D4C0; // gGameState + return *(SystemState*)0xC8D4C0; // gGameState } /** @@ -450,7 +461,7 @@ void CGameSA::Reset() m_pCamera->SetFadeColor(0, 0, 0); m_pCamera->Fade(0, FADE_OUT); - Pause(false); // We don't have to pause as the fadeout will stop the sound. Pausing it will make the fadein next start ugly + Pause(false); // We don't have to pause as the fadeout will stop the sound. Pausing it will make the fadein next start ugly m_pHud->Disable(false); // Restore the HUD @@ -471,6 +482,10 @@ void CGameSA::Reset() // Restore default world state RestoreGameWorld(); + + // Reset building pool to default capacity if a server enlarged it + if (m_Pools->GetBuildingsPool().GetSize() != MAX_BUILDINGS) + SetBuildingPoolSize(MAX_BUILDINGS); } } @@ -479,24 +494,38 @@ void CGameSA::Terminate() // Initiate the destruction delete this; - // Dump any memory leaks if DETECT_LEAK is defined - #ifdef DETECT_LEAKS +// Dump any memory leaks if DETECT_LEAK is defined +#ifdef DETECT_LEAKS DumpUnfreed(); - #endif +#endif } void CGameSA::Initialize() { + // Expand TXD pool from SA's default 5000 to our maximum capacity. + // Can't run in CTxdPoolSA's constructor (pool at 0xC8800C doesn't + // exist yet). Safe here: pool access is main-thread only and SA + // derefs m_pObjects on every access (no cached pointers). + static_cast(m_Pools->GetTxdPool()).InitialisePool(); + // Initialize garages m_pGarages->Initialize(); SetupSpecialCharacters(); SetupBrokenModels(); m_pRenderWare->Initialize(); + // Initialize streaming GC protection hooks + CStreamingGC::Initialize(); + // *Sebas* Hide the GTA:SA Main menu. MemPutFast(CLASS_CMenuManager + 0x5C, 0); } +StreamingRemoveModelCallback CGameSA::GetStreamingRemoveModelCallback() const noexcept +{ + return &CStreamingGC::OnRemoveModel; +} + eGameVersion CGameSA::GetGameVersion() { return m_eGameVersion; @@ -528,47 +557,47 @@ eGameVersion CGameSA::FindGameVersion() float CGameSA::GetFPS() { - return *(float*)0xB7CB50; // CTimer::game_FPS + return *(float*)0xB7CB50; // CTimer::game_FPS } float CGameSA::GetTimeStep() { - return *(float*)0xB7CB5C; // CTimer::ms_fTimeStep + return *(float*)0xB7CB5C; // CTimer::ms_fTimeStep } float CGameSA::GetOldTimeStep() { - return *(float*)0xB7CB54; // CTimer::ms_fOldTimeStep + return *(float*)0xB7CB54; // CTimer::ms_fOldTimeStep } float CGameSA::GetTimeScale() { - return *(float*)0xB7CB64; // CTimer::ms_fTimeScale + return *(float*)0xB7CB64; // CTimer::ms_fTimeScale } void CGameSA::SetTimeScale(float fTimeScale) { - MemPutFast(0xB7CB64, fTimeScale); // CTimer::ms_fTimeScale + MemPutFast(0xB7CB64, fTimeScale); // CTimer::ms_fTimeScale } unsigned char CGameSA::GetBlurLevel() { - return *(unsigned char*)0x8D5104; // CPostEffects::m_SpeedFXAlpha + return *(unsigned char*)0x8D5104; // CPostEffects::m_SpeedFXAlpha } void CGameSA::SetBlurLevel(unsigned char ucLevel) { - MemPutFast(0x8D5104, ucLevel); // CPostEffects::m_SpeedFXAlpha + MemPutFast(0x8D5104, ucLevel); // CPostEffects::m_SpeedFXAlpha } unsigned long CGameSA::GetMinuteDuration() { - return *(unsigned long*)0xB7015C; // CClock::ms_nMillisecondsPerGameMinute + return *(unsigned long*)0xB7015C; // CClock::ms_nMillisecondsPerGameMinute } void CGameSA::SetMinuteDuration(unsigned long ulTime) { - MemPutFast(0xB7015C, ulTime); // CClock::ms_nMillisecondsPerGameMinute + MemPutFast(0xB7015C, ulTime); // CClock::ms_nMillisecondsPerGameMinute } bool CGameSA::IsCheatEnabled(const char* szCheatName) @@ -697,7 +726,7 @@ void CGameSA::SetCoronaZTestEnabled(bool isEnabled) m_isCoronaZTestEnabled = isEnabled; } -void CGameSA::SetWaterCreaturesEnabled(bool isEnabled) +void CGameSA::SetWaterCreaturesEnabled(bool isEnabled) { if (isEnabled == m_areWaterCreaturesEnabled) return; @@ -722,20 +751,20 @@ void CGameSA::SetTunnelWeatherBlendEnabled(bool isEnabled) if (isEnabled == m_isTunnelWeatherBlendEnabled) return; // CWeather::UpdateInTunnelness - DWORD functionAddress = 0x72B630; + DWORD functionAddress = 0x72B630; if (isEnabled) { // Restore original bytes: 83 EC 20 - MemPut(functionAddress, 0x83); // Restore 83 - MemPut(functionAddress + 1, 0xEC); // Restore EC - MemPut(functionAddress + 2, 0x20); // Restore 20 + MemPut(functionAddress, 0x83); // Restore 83 + MemPut(functionAddress + 1, 0xEC); // Restore EC + MemPut(functionAddress + 2, 0x20); // Restore 20 } else { // Patch CWeather::UpdateInTunnelness (Found By AlexTMjugador) - MemPut(functionAddress, 0xC3); // Write C3 (RET) - MemPut(functionAddress + 1, 0x90); // Write 90 (NOP) - MemPut(functionAddress + 2, 0x90); // Write 90 (NOP) + MemPut(functionAddress, 0xC3); // Write C3 (RET) + MemPut(functionAddress + 1, 0x90); // Write 90 (NOP) + MemPut(functionAddress + 2, 0x90); // Write 90 (NOP) } m_isTunnelWeatherBlendEnabled = isEnabled; } @@ -780,13 +809,13 @@ void CGameSA::SetFireballDestructEnabled(bool isEnabled) if (isEnabled) { BYTE originalCodes[7] = {0x81, 0x66, 0x1C, 0x7E, 0xFF, 0xFF, 0xFF}; - MemCpy((void*)0x6CCE45, &originalCodes, 7); // CPlane::BlowUpCar - MemCpy((void*)0x6C6E01, &originalCodes, 7); // CHeli::BlowUpCar + MemCpy((void*)0x6CCE45, &originalCodes, 7); // CPlane::BlowUpCar + MemCpy((void*)0x6C6E01, &originalCodes, 7); // CHeli::BlowUpCar } else { - MemSet((void*)0x6CCE45, 0x90, 7); // CPlane::BlowUpCar - MemSet((void*)0x6C6E01, 0x90, 7); // CHeli::BlowUpCar + MemSet((void*)0x6CCE45, 0x90, 7); // CPlane::BlowUpCar + MemSet((void*)0x6C6E01, 0x90, 7); // CHeli::BlowUpCar } m_isFireballDestructEnabled = isEnabled; @@ -800,8 +829,8 @@ void CGameSA::SetExtendedWaterCannonsEnabled(bool isEnabled) // Allocate memory for new bigger array or use default aCannons array void* aCannons = isEnabled ? malloc(MAX_WATER_CANNONS * SIZE_CWaterCannon) : (void*)ARRAY_aCannons; - int newLimit = isEnabled ? MAX_WATER_CANNONS : NUM_CWaterCannon_DefaultLimit; // default: 3 - MemSetFast(aCannons, 0, newLimit * SIZE_CWaterCannon); // clear aCannons array + int newLimit = isEnabled ? MAX_WATER_CANNONS : NUM_CWaterCannon_DefaultLimit; // default: 3 + MemSetFast(aCannons, 0, newLimit * SIZE_CWaterCannon); // clear aCannons array // Get current limit int currentLimit = *(int*)NUM_WaterCannon_Limit; @@ -814,8 +843,10 @@ void CGameSA::SetExtendedWaterCannonsEnabled(bool isEnabled) { char* currentCannon = (char*)currentACannons + i * SIZE_CWaterCannon; - ((void(__thiscall*)(int, void*, bool))FUNC_CAESoundManager_CancelSoundsOwnedByAudioEntity)(STRUCT_CAESoundManager, currentCannon + NUM_CWaterCannon_Audio_Offset, true); // CAESoundManager::CancelSoundsOwnedByAudioEntity to prevent random crashes from CAESound::UpdateParameters - ((void(__thiscall*)(void*))FUNC_CWaterCannon_Destructor)(currentCannon); // CWaterCannon::~CWaterCannon + ((void(__thiscall*)(int, void*, bool))FUNC_CAESoundManager_CancelSoundsOwnedByAudioEntity)( + STRUCT_CAESoundManager, currentCannon + NUM_CWaterCannon_Audio_Offset, + true); // CAESoundManager::CancelSoundsOwnedByAudioEntity to prevent random crashes from CAESound::UpdateParameters + ((void(__thiscall*)(void*))FUNC_CWaterCannon_Destructor)(currentCannon); // CWaterCannon::~CWaterCannon } // Call CWaterCannon constructor & CWaterCannon::Init @@ -823,41 +854,43 @@ void CGameSA::SetExtendedWaterCannonsEnabled(bool isEnabled) { char* currentCannon = (char*)aCannons + i * SIZE_CWaterCannon; - ((void(__thiscall*)(void*))FUNC_CWaterCannon_Constructor)(currentCannon); // CWaterCannon::CWaterCannon - ((void(__thiscall*)(void*))FUNC_CWaterCannon_Init)(currentCannon); // CWaterCannon::Init + ((void(__thiscall*)(void*))FUNC_CWaterCannon_Constructor)(currentCannon); // CWaterCannon::CWaterCannon + ((void(__thiscall*)(void*))FUNC_CWaterCannon_Init)(currentCannon); // CWaterCannon::Init } // Patch references to array - MemPut((void*)0x728C83, aCannons); // CWaterCannons::Init - MemPut((void*)0x728CCB, aCannons); // CWaterCannons::UpdateOne - MemPut((void*)0x728CEB, aCannons); // CWaterCannons::UpdateOne - MemPut((void*)0x728D0D, aCannons); // CWaterCannons::UpdateOne - MemPut((void*)0x728D71, aCannons); // CWaterCannons::UpdateOne - MemPutFast((void*)0x729B33, aCannons); // CWaterCannons::Render - MemPut((void*)0x72A3C5, aCannons); // CWaterCannons::UpdateOne - MemPut((void*)0x855432, aCannons); // 0x855431 - MemPut((void*)0x856BFD, aCannons); // 0x856BFC + MemPut((void*)0x728C83, aCannons); // CWaterCannons::Init + MemPut((void*)0x728CCB, aCannons); // CWaterCannons::UpdateOne + MemPut((void*)0x728CEB, aCannons); // CWaterCannons::UpdateOne + MemPut((void*)0x728D0D, aCannons); // CWaterCannons::UpdateOne + MemPut((void*)0x728D71, aCannons); // CWaterCannons::UpdateOne + MemPutFast((void*)0x729B33, aCannons); // CWaterCannons::Render + MemPut((void*)0x72A3C5, aCannons); // CWaterCannons::UpdateOne + MemPut((void*)0x855432, aCannons); // 0x855431 + MemPut((void*)0x856BFD, aCannons); // 0x856BFC + + const auto ucNewLimit = static_cast(newLimit); // CWaterCannons::Init - MemPut(0x728C88, newLimit); + MemPut(0x728C88, static_cast(newLimit)); // CWaterCannons::Update - MemPut(0x72A3F2, newLimit); + MemPut(0x72A3F2, static_cast(newLimit)); // CWaterCanons::UpdateOne - MemPut(0x728CD4, newLimit); - MemPut(0x728CF6, newLimit); - MemPut(0x728CFF, newLimit); - MemPut(0x728D62, newLimit); + MemPut(0x728CD4, static_cast(newLimit)); + MemPut(0x728CF6, static_cast(newLimit)); + MemPut(0x728CFF, static_cast(newLimit)); + MemPut(0x728D62, static_cast(newLimit)); // CWaterCannons::Render - MemPutFast(0x729B38, newLimit); + MemPutFast(0x729B38, static_cast(newLimit)); // 0x85542A - MemPut(0x85542B, newLimit); + MemPut(0x85542B, static_cast(newLimit)); // 0x856BF5 - MemPut(0x856BF6, newLimit); + MemPut(0x856BF6, static_cast(newLimit)); // Free previous allocated memory if (!isEnabled && currentACannons != nullptr) @@ -884,15 +917,16 @@ void CGameSA::SetIgnoreFireStateEnabled(bool isEnabled) if (isEnabled) { - MemSet((void*)0x6511B9, 0x90, 10); // CCarEnterExit::IsVehicleStealable - MemSet((void*)0x643A95, 0x90, 14); // CTaskComplexEnterCar::CreateFirstSubTask - MemSet((void*)0x6900B5, 0x90, 14); // CTaskComplexCopInCar::ControlSubTask - MemSet((void*)0x64F3DB, 0x90, 14); // CCarEnterExit::IsPlayerToQuitCarEnter - - MemSet((void*)0x685A7F, 0x90, 14); // CTaskSimplePlayerOnFoot::ProcessPlayerWeapon - - MemSet((void*)0x53A899, 0x90, 5); // CFire::ProcessFire - MemSet((void*)0x53A990, 0x90, 5); // CFire::ProcessFire + // All these patches disable fire state checks (m_pFire != nullptr) + // Related crash protection is handled by checks in TaskSA.cpp and CTaskManagementSystemSA.cpp + MemSet((void*)0x6511B9, 0x90, 10); // CCarEnterExit::IsVehicleStealable - fire check + MemSet((void*)0x643A95, 0x90, 14); // CTaskComplexEnterCar::CreateFirstSubTask - fire check + MemSet((void*)0x6900B5, 0x90, 14); // CTaskComplexCopInCar::ControlSubTask - fire check + MemSet((void*)0x64F3DB, 0x90, 14); // CCarEnterExit::IsPlayerToQuitCarEnter - fire check + MemSet((void*)0x685A7F, 0x90, 14); // CTaskSimplePlayerOnFoot::ProcessPlayerWeapon - fire check + + MemSet((void*)0x53A899, 0x90, 5); // CFire::ProcessFire + MemSet((void*)0x53A990, 0x90, 5); // CFire::ProcessFire } else { @@ -918,8 +952,8 @@ void CGameSA::SetVehicleBurnExplosionsEnabled(bool isEnabled) if (isEnabled) { - MemCpy((void*)0x6A74EA, "\xE8\x61\xF5\x08\x00", 5); // CAutomobile::ProcessCarOnFireAndExplode - MemCpy((void*)0x737929, "\xE8\x22\xF1\xFF\xFF", 5); // CExplosion::Update + MemCpy((void*)0x6A74EA, "\xE8\x61\xF5\x08\x00", 5); // CAutomobile::ProcessCarOnFireAndExplode + MemCpy((void*)0x737929, "\xE8\x22\xF1\xFF\xFF", 5); // CExplosion::Update } else { @@ -1111,10 +1145,26 @@ void CGameSA::RestoreGameWorld() bool CGameSA::SetBuildingPoolSize(size_t size) { const bool shouldRemoveWorld = !m_isGameWorldRemoved; - if (shouldRemoveWorld) + + const int iCurrentBuildingPoolSize = m_Pools->GetBuildingsPool().GetSize(); + if (iCurrentBuildingPoolSize >= 0 && static_cast(iCurrentBuildingPoolSize) == size) + { + // Keep same-size behavior unchanged while world is active. + // If world is already removed, skip no-op resize and only drop caches. + if (!shouldRemoveWorld) + { + static_cast(m_pBuildingRemoval)->DropCaches(); + return true; + } + + // World is active here, so continue with remove and restore flow. + } + + if (shouldRemoveWorld) { RemoveGameWorld(); - else - static_cast(m_pBuildingRemoval)->DropCaches(); + } else { + s +}tatic_cast(m_pBuildingRemoval)->DropCaches(); bool status = m_Pools->GetBuildingsPool().Resize(size); @@ -1150,7 +1200,7 @@ void CGameSA::ResetAlphaTransparencies() // Note #2: Some players do not need this to disable VSync. (Possibly because their video card driver settings override it somewhere) void CGameSA::DisableVSync() { - MemPutFast(0xBAB318, 0); // CLoadingScreen::m_bActive + MemPutFast(0xBAB318, 0); // CLoadingScreen::m_bActive } CWeapon* CGameSA::CreateWeapon() { @@ -1170,9 +1220,9 @@ void CGameSA::SetWeaponRenderEnabled(bool enabled) if (!enabled) { // Disable calls to CVisibilityPlugins::RenderWeaponPedsForPC - MemSet((void*)0x53EAC4, 0x90, 5); // Idle - MemSet((void*)0x705322, 0x90, 5); // CPostEffects::Render - MemSet((void*)0x7271E3, 0x90, 5); // CMirrors::BeforeMainRender + MemSet((void*)0x53EAC4, 0x90, 5); // Idle + MemSet((void*)0x705322, 0x90, 5); // CPostEffects::Render + MemSet((void*)0x7271E3, 0x90, 5); // CMirrors::BeforeMainRender } else { diff --git a/Client/game_sa/CGameSA.h b/Client/game_sa/CGameSA.h index 9ed552b92d8..782c13ffe4e 100644 --- a/Client/game_sa/CGameSA.h +++ b/Client/game_sa/CGameSA.h @@ -24,65 +24,65 @@ class CAnimBlendClumpDataSAInterface; class CObjectGroupPhysicalPropertiesSA; class CTaskManagementSystemSA; -extern unsigned int OBJECTDYNAMICINFO_MAX; // default: 160 - -#define CLASS_CPlayerInfo 0xB7CD98 -#define CLASS_CCamera 0xB6F028 -#define CLASS_CPad 0xB73458 -#define CLASS_CFx 0xa9ae00 -#define CLASS_CFxManager 0xA9AE80 -#define CLASS_CMenuManager 0xBA6748 -#define CLASS_RwCamera 0xB6F97C - -#define ARRAY_WeaponInfo 0xC8AAB8 -#define CLASSSIZE_WeaponInfo 112 -#define NUM_WeaponInfosStdSkill WEAPONTYPE_LAST_WEAPONTYPE -#define NUM_WeaponInfosOtherSkill 11 -#define NUM_WeaponInfosTotal (NUM_WeaponInfosStdSkill + (3*NUM_WeaponInfosOtherSkill)) // std, (poor, pro, special) - -#define MODELINFO_DFF_MAX 20000 -#define MODELINFO_TXD_MAX 25000 -#define MODELINFO_MAX 26000 // Actual max is 25755 - -#define VAR_FlyingCarsEnabled 0x969160 -#define VAR_ExtraBunnyhopEnabled 0x969161 -#define VAR_HoveringCarsEnabled 0x969152 -#define VAR_ExtraJumpEnabled 0x96916C -#define VAR_TankModeEnabled 0x969164 -#define VAR_NoReloadEnabled 0x969178 -#define VAR_PerfectHandling 0x96914C -#define VAR_AllCarsHaveNitro 0x969165 -#define VAR_BoatsCanFly 0x969153 -#define VAR_InfiniteOxygen 0x96916E -#define VAR_FasterClock 0x96913B -#define VAR_FasterGameplay 0x96913C -#define VAR_SlowerGameplay 0x96913D -#define VAR_AlwaysMidnight 0x969167 -#define VAR_FullWeaponAiming 0x969179 -#define VAR_InfiniteHealth 0x96916D -#define VAR_NeverWanted 0x969171 -#define VAR_HealthArmorMoney 0x969133 -#define VAR_WalkUnderwater 0x6C2759 - -#define CHEAT_HOVERINGCARS "hovercars" -#define CHEAT_FLYINGCARS "aircars" -#define CHEAT_EXTRABUNNYHOP "extrabunny" -#define CHEAT_EXTRAJUMP "extrajump" -#define CHEAT_TANKMODE "tankmode" -#define CHEAT_NORELOAD "noreload" -#define CHEAT_PERFECTHANDLING "perfecthandling" -#define CHEAT_ALLCARSHAVENITRO "allcarshavenitro" -#define CHEAT_BOATSCANFLY "airboats" -#define CHEAT_INFINITEOXYGEN "infiniteoxygen" -#define CHEAT_WALKUNDERWATER "walkunderwater" -#define CHEAT_FASTERCLOCK "fasterclock" -#define CHEAT_FASTERGAMEPLAY "fastergameplay" -#define CHEAT_SLOWERGAMEPLAY "slowergameplay" -#define CHEAT_ALWAYSMIDNIGHT "alwaysmidnight" -#define CHEAT_FULLWEAPONAIMING "fullweaponaiming" -#define CHEAT_INFINITEHEALTH "infinitehealth" -#define CHEAT_NEVERWANTED "neverwanted" -#define CHEAT_HEALTARMORMONEY "healtharmormoney" +extern unsigned int OBJECTDYNAMICINFO_MAX; // default: 160 + +#define CLASS_CPlayerInfo 0xB7CD98 +#define CLASS_CCamera 0xB6F028 +#define CLASS_CPad 0xB73458 +#define CLASS_CFx 0xa9ae00 +#define CLASS_CFxManager 0xA9AE80 +#define CLASS_CMenuManager 0xBA6748 +#define CLASS_RwCamera 0xB6F97C + +#define ARRAY_WeaponInfo 0xC8AAB8 +#define CLASSSIZE_WeaponInfo 112 +#define NUM_WeaponInfosStdSkill WEAPONTYPE_LAST_WEAPONTYPE +#define NUM_WeaponInfosOtherSkill 11 +#define NUM_WeaponInfosTotal (NUM_WeaponInfosStdSkill + (3 * NUM_WeaponInfosOtherSkill)) // std, (poor, pro, special) + +#define MODELINFO_DFF_MAX 20000 +#define MODELINFO_TXD_MAX 25000 +#define MODELINFO_MAX 26000 // Actual max is 25755 + +#define VAR_FlyingCarsEnabled 0x969160 +#define VAR_ExtraBunnyhopEnabled 0x969161 +#define VAR_HoveringCarsEnabled 0x969152 +#define VAR_ExtraJumpEnabled 0x96916C +#define VAR_TankModeEnabled 0x969164 +#define VAR_NoReloadEnabled 0x969178 +#define VAR_PerfectHandling 0x96914C +#define VAR_AllCarsHaveNitro 0x969165 +#define VAR_BoatsCanFly 0x969153 +#define VAR_InfiniteOxygen 0x96916E +#define VAR_FasterClock 0x96913B +#define VAR_FasterGameplay 0x96913C +#define VAR_SlowerGameplay 0x96913D +#define VAR_AlwaysMidnight 0x969167 +#define VAR_FullWeaponAiming 0x969179 +#define VAR_InfiniteHealth 0x96916D +#define VAR_NeverWanted 0x969171 +#define VAR_HealthArmorMoney 0x969133 +#define VAR_WalkUnderwater 0x6C2759 + +#define CHEAT_HOVERINGCARS "hovercars" +#define CHEAT_FLYINGCARS "aircars" +#define CHEAT_EXTRABUNNYHOP "extrabunny" +#define CHEAT_EXTRAJUMP "extrajump" +#define CHEAT_TANKMODE "tankmode" +#define CHEAT_NORELOAD "noreload" +#define CHEAT_PERFECTHANDLING "perfecthandling" +#define CHEAT_ALLCARSHAVENITRO "allcarshavenitro" +#define CHEAT_BOATSCANFLY "airboats" +#define CHEAT_INFINITEOXYGEN "infiniteoxygen" +#define CHEAT_WALKUNDERWATER "walkunderwater" +#define CHEAT_FASTERCLOCK "fasterclock" +#define CHEAT_FASTERGAMEPLAY "fastergameplay" +#define CHEAT_SLOWERGAMEPLAY "slowergameplay" +#define CHEAT_ALWAYSMIDNIGHT "alwaysmidnight" +#define CHEAT_FULLWEAPONAIMING "fullweaponaiming" +#define CHEAT_INFINITEHEALTH "infinitehealth" +#define CHEAT_NEVERWANTED "neverwanted" +#define CHEAT_HEALTARMORMONEY "healtharmormoney" #define FUNC_CAESoundManager_CancelSoundsOwnedByAudioEntity 0x4EFCD0 #define STRUCT_CAESoundManager 0xB62CB0 @@ -96,13 +96,13 @@ extern unsigned int OBJECTDYNAMICINFO_MAX; // default: 160 #define NUM_CWaterCannon_Audio_Offset 0x32C #define NUM_CWaterCannon_DefaultLimit 3 -constexpr int MAX_WATER_CANNONS = 30; // extended CWaterCannon limit, it can be increased +constexpr int MAX_WATER_CANNONS = 30; // extended CWaterCannon limit, it can be increased struct SCheatSA { - BYTE* m_byAddress; // Cheat Address - bool m_bEnabled; // Cheat State - bool m_bCanBeSet; // Cheat can be set with setWorldSpecialPropertyEnabled + BYTE* m_byAddress; // Cheat Address + bool m_bEnabled; // Cheat State + bool m_bCanBeSet; // Cheat can be set with setWorldSpecialPropertyEnabled SCheatSA(BYTE* Address, bool bCanBeSet = true) { m_byAddress = Address; @@ -176,34 +176,31 @@ class CGameSA : public CGame CBuildingRemoval* GetBuildingRemoval() { return m_pBuildingRemoval; } CRenderer* GetRenderer() const noexcept override { return m_pRenderer.get(); } - CVehicleAudioSettingsManager* GetVehicleAudioSettingsManager() const noexcept override - { - return m_pVehicleAudioSettingsManager.get(); - } + CVehicleAudioSettingsManager* GetVehicleAudioSettingsManager() const noexcept override { return m_pVehicleAudioSettingsManager.get(); } CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD); CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false); CObjectGroupPhysicalProperties* GetObjectGroupPhysicalProperties(unsigned char ucObjectGroup); - int32_t GetBaseIDforDFF() { return 0; } - int32_t GetBaseIDforTXD() { return *(int32_t*)(0x407104 + 2); } - int32_t GetBaseIDforCOL() { return *(int32_t*)(0x410344 + 2); } - int32_t GetBaseIDforIPL() { return *(int32_t*)(0x4044F4 + 2); } - int32_t GetBaseIDforDAT() { return *(int32_t*)(0x44D064 + 2); } - int32_t GetBaseIDforIFP() { return *(int32_t*)(0x407124 + 2); } - int32_t GetBaseIDforRRR() { return *(int32_t*)(0x4594A1 + 2); } - int32_t GetBaseIDforSCM() { return *(int32_t*)(0x46A574 + 2); } - int32_t GetCountOfAllFileIDs() { return (*(char**)(0x5B8AFA + 2) - *(char**)(0x5B8B08 + 6)) / sizeof(CStreamingInfo); } + uint32_t GetBaseIDforDFF() override { return 0; } + uint32_t GetBaseIDforTXD() override { return *(uint32_t*)(0x407104 + 2); } + uint32_t GetBaseIDforCOL() override { return *(uint32_t*)(0x410344 + 2); } + uint32_t GetBaseIDforIPL() override { return *(uint32_t*)(0x4044F4 + 2); } + uint32_t GetBaseIDforDAT() override { return *(uint32_t*)(0x44D064 + 2); } + uint32_t GetBaseIDforIFP() override { return *(uint32_t*)(0x407124 + 2); } + uint32_t GetBaseIDforRRR() override { return *(uint32_t*)(0x4594A1 + 2); } + uint32_t GetBaseIDforSCM() override { return *(uint32_t*)(0x46A574 + 2); } + uint32_t GetCountOfAllFileIDs() override { return (*(char**)(0x5B8AFA + 2) - *(char**)(0x5B8B08 + 6)) / sizeof(CStreamingInfo); } - DWORD GetSystemTime() { return *(DWORD*)0xB7CB84; } // CTimer::m_snTimeInMilliseconds - int GetSystemFrameCounter() const { return *(int*)0xB7CB4C; } // CTimer::m_FrameCounter + DWORD GetSystemTime() { return *(DWORD*)0xB7CB84; } // CTimer::m_snTimeInMilliseconds + int GetSystemFrameCounter() const { return *(int*)0xB7CB4C; } // CTimer::m_FrameCounter - bool IsAtMenu() { return *(unsigned long*)0xBA677B != 0; } // FrontEndMenuManager + 0x33 + bool IsAtMenu() { return *(unsigned long*)0xBA677B != 0; } // FrontEndMenuManager + 0x33 - void StartGame(); - void SetSystemState(SystemState State); - SystemState GetSystemState(); - void Pause(bool bPaused); + void StartGame(); + void SetSystemState(SystemState State); + SystemState GetSystemState(); + void Pause(bool bPaused); void Initialize(); void Reset(); @@ -313,6 +310,8 @@ class CGameSA : public CGame void SetTaskSimpleBeHitHandler(TaskSimpleBeHitHandler* pTaskSimpleBeHitHandler) { m_pTaskSimpleBeHitHandler = pTaskSimpleBeHitHandler; } CAnimBlendClumpDataSAInterface** GetClumpData(RpClump* clump) { return RWPLUGINOFFSET(CAnimBlendClumpDataSAInterface*, clump, ClumpOffset); } + StreamingRemoveModelCallback GetStreamingRemoveModelCallback() const noexcept override; + PreWeaponFireHandler* m_pPreWeaponFireHandler; PostWeaponFireHandler* m_pPostWeaponFireHandler; TaskSimpleBeHitHandler* m_pTaskSimpleBeHitHandler; @@ -362,7 +361,7 @@ class CGameSA : public CGame std::unique_ptr m_pVehicleAudioSettingsManager; - std::unique_ptr m_pRenderer; + std::unique_ptr m_pRenderer; CPad* m_pPad; CAERadioTrackManager* m_pCAERadioTrackManager; @@ -371,7 +370,7 @@ class CGameSA : public CGame CAESoundManager* m_pAESoundManager; CAudioContainer* m_pAudioContainer; CStats* m_pStats; - CTaskManagementSystemSA* m_pTaskManagementSystem; // not used outside the game_sa + CTaskManagementSystemSA* m_pTaskManagementSystem; // not used outside the game_sa CTasks* m_pTasks; CGameSettings* m_pSettings; CCarEnterExit* m_pCarEnterExit; @@ -385,7 +384,7 @@ class CGameSA : public CGame int m_iCheckStatus; bool m_bUnderworldWarp; bool m_isCoronaZTestEnabled{true}; - bool m_isTunnelWeatherBlendEnabled{true}; + bool m_isTunnelWeatherBlendEnabled{true}; bool m_areWaterCreaturesEnabled{true}; bool m_isBurnFlippedCarsEnabled{true}; bool m_isFireballDestructEnabled{true}; @@ -395,7 +394,7 @@ class CGameSA : public CGame bool m_isIgnoreFireStateEnabled{false}; bool m_isVehicleBurnExplosionsEnabled{true}; - static unsigned int& ClumpOffset; + static unsigned int& ClumpOffset; std::map m_Cheats; diff --git a/Client/game_sa/CGarageSA.cpp b/Client/game_sa/CGarageSA.cpp index 945f6abcd30..a43e94800f5 100644 --- a/Client/game_sa/CGarageSA.cpp +++ b/Client/game_sa/CGarageSA.cpp @@ -53,11 +53,12 @@ void CGarageSA::GetBoundingBox(float& left, float& right, float& front, float& b void CGarageSA::SetOpen(bool bOpen) { - if (bOpen) + if (bOpen) { internalInterface->DoorState = 3; - else + } else { internalInterface->DoorState = 2; } +} bool CGarageSA::IsOpen() const { diff --git a/Client/game_sa/CGarageSA.h b/Client/game_sa/CGarageSA.h index cf8d2424419..55126c938af 100644 --- a/Client/game_sa/CGarageSA.h +++ b/Client/game_sa/CGarageSA.h @@ -17,20 +17,20 @@ class CGarageSAInterface { public: - CVector vecPosition; // 0 - float DirectionA_X, DirectionA_Y; // 12 - float DirectionB_X, DirectionB_Y; // 20 - float Height, Width, Depth; // 28 - float Left, Right, Front, Back; // 40 - float DoorPosition; // 56 - DWORD pad; // 60 - DWORD pad2; // 64 - char Name[8]; // 68 - BYTE Type; // 76 - BYTE DoorState; // 77 - BYTE DoorFlags; // 78 - BYTE OriginalType; // 79 - BYTE pad3[132]; // 80 + CVector vecPosition; // 0 + float DirectionA_X, DirectionA_Y; // 12 + float DirectionB_X, DirectionB_Y; // 20 + float Height, Width, Depth; // 28 + float Left, Right, Front, Back; // 40 + float DoorPosition; // 56 + DWORD pad; // 60 + DWORD pad2; // 64 + char Name[8]; // 68 + BYTE Type; // 76 + BYTE DoorState; // 77 + BYTE DoorFlags; // 78 + BYTE OriginalType; // 79 + BYTE pad3[132]; // 80 }; class CGarageSA : public CGarage diff --git a/Client/game_sa/CHandlingEntrySA.cpp b/Client/game_sa/CHandlingEntrySA.cpp index 3e38045ddae..fa7c372bd84 100644 --- a/Client/game_sa/CHandlingEntrySA.cpp +++ b/Client/game_sa/CHandlingEntrySA.cpp @@ -42,7 +42,7 @@ void CHandlingEntrySA::Assign(const CHandlingEntry* const pEntry) noexcept return; // Copy the data - const CHandlingEntrySA* const pEntrySA = static_cast(pEntry); + const CHandlingEntrySA* const pEntrySA = static_cast(pEntry); m_Handling = pEntrySA->m_Handling; } @@ -52,49 +52,63 @@ void CHandlingEntrySA::Recalculate() noexcept if (!m_HandlingSA) return; - // Copy our stored field to GTA's + // Copy our stored field to GTA's MemCpyFast(m_HandlingSA.get(), &m_Handling, sizeof(m_Handling)); ((void(_stdcall*)(tHandlingDataSA*))FUNC_HandlingDataMgr_ConvertDataToGameUnits)(m_HandlingSA.get()); } void CHandlingEntrySA::SetSuspensionForceLevel(float fForce) noexcept { + if (!std::isfinite(fForce)) [[unlikely]] + return; CheckSuspensionChanges(); m_Handling.fSuspensionForceLevel = fForce; } void CHandlingEntrySA::SetSuspensionDamping(float fDamping) noexcept { + if (!std::isfinite(fDamping)) [[unlikely]] + return; CheckSuspensionChanges(); m_Handling.fSuspensionDamping = fDamping; } void CHandlingEntrySA::SetSuspensionHighSpeedDamping(float fDamping) noexcept { + if (!std::isfinite(fDamping)) [[unlikely]] + return; CheckSuspensionChanges(); m_Handling.fSuspensionHighSpdDamping = fDamping; } void CHandlingEntrySA::SetSuspensionUpperLimit(float fUpperLimit) noexcept { + if (!std::isfinite(fUpperLimit)) [[unlikely]] + return; CheckSuspensionChanges(); m_Handling.fSuspensionUpperLimit = fUpperLimit; } void CHandlingEntrySA::SetSuspensionLowerLimit(float fLowerLimit) noexcept { + if (!std::isfinite(fLowerLimit)) [[unlikely]] + return; CheckSuspensionChanges(); m_Handling.fSuspensionLowerLimit = fLowerLimit; } void CHandlingEntrySA::SetSuspensionFrontRearBias(float fBias) noexcept { + if (!std::isfinite(fBias)) [[unlikely]] + return; CheckSuspensionChanges(); m_Handling.fSuspensionFrontRearBias = fBias; } void CHandlingEntrySA::SetSuspensionAntiDiveMultiplier(float fAntidive) noexcept { + if (!std::isfinite(fAntidive)) [[unlikely]] + return; CheckSuspensionChanges(); m_Handling.fSuspensionAntiDiveMultiplier = fAntidive; } diff --git a/Client/game_sa/CHandlingEntrySA.h b/Client/game_sa/CHandlingEntrySA.h index 2f515b1a04e..ab17d26dfe6 100644 --- a/Client/game_sa/CHandlingEntrySA.h +++ b/Client/game_sa/CHandlingEntrySA.h @@ -21,67 +21,67 @@ class CTransmissionSAInterface { public: - float fUnknown[18]; // +40 + float fUnknown[18]; // +40 - unsigned char ucDriveType : 8; // +112 - unsigned char ucEngineType : 8; // +113 - unsigned char ucNumberOfGears : 8; // +114 - unsigned char ucUnknown : 8; // +115 + unsigned char ucDriveType : 8; // +112 + unsigned char ucEngineType : 8; // +113 + unsigned char ucNumberOfGears : 8; // +114 + unsigned char ucUnknown : 8; // +115 - unsigned int uiHandlingFlags; // +116 + unsigned int uiHandlingFlags; // +116 - float fEngineAcceleration; // +120 (value in handling.cfg * 0x86A950) - float fEngineInertia; // +124 - float fMaxVelocity; // +128 + float fEngineAcceleration; // +120 (value in handling.cfg * 0x86A950) + float fEngineInertia; // +124 + float fMaxVelocity; // +128 - float fUnknown2[3]; // +132 + float fUnknown2[3]; // +132 }; struct tHandlingDataSA { - int iVehicleID; // +0 + int iVehicleID; // +0 - float fMass; // +4 + float fMass; // +4 - float fUnknown1; // +8 Automatically calculated + float fUnknown1; // +8 Automatically calculated - float fTurnMass; // +12 - float fDragCoeff; // +16 - CVector vecCenterOfMass; // +20 - unsigned int uiPercentSubmerged; // +32 + float fTurnMass; // +12 + float fDragCoeff; // +16 + CVector vecCenterOfMass; // +20 + unsigned int uiPercentSubmerged; // +32 - float fUnknown2; // +36 Automatically calculated + float fUnknown2; // +36 Automatically calculated - float fTractionMultiplier; // +40 + float fTractionMultiplier; // +40 - CTransmissionSAInterface Transmission; // +44 - float fBrakeDeceleration; // +148 - float fBrakeBias; // +152 - bool bABS; // +156 - char fUnknown[3]; // +157 + CTransmissionSAInterface Transmission; // +44 + float fBrakeDeceleration; // +148 + float fBrakeBias; // +152 + bool bABS; // +156 + char fUnknown[3]; // +157 - float fSteeringLock; // +160 - float fTractionLoss; // +164 - float fTractionBias; // +168 + float fSteeringLock; // +160 + float fTractionLoss; // +164 + float fTractionBias; // +168 - float fSuspensionForceLevel; // +172 - float fSuspensionDamping; // +176 - float fSuspensionHighSpdDamping; // +180 - float fSuspensionUpperLimit; // +184 - float fSuspensionLowerLimit; // +188 - float fSuspensionFrontRearBias; // +192 - float fSuspensionAntiDiveMultiplier; // +196 + float fSuspensionForceLevel; // +172 + float fSuspensionDamping; // +176 + float fSuspensionHighSpdDamping; // +180 + float fSuspensionUpperLimit; // +184 + float fSuspensionLowerLimit; // +188 + float fSuspensionFrontRearBias; // +192 + float fSuspensionAntiDiveMultiplier; // +196 - float fCollisionDamageMultiplier; // +200 + float fCollisionDamageMultiplier; // +200 - unsigned int uiModelFlags; // +204 - unsigned int uiHandlingFlags; // +208 - float fSeatOffsetDistance; // +212 - unsigned int uiMonetary; // +216 + unsigned int uiModelFlags; // +204 + unsigned int uiHandlingFlags; // +208 + float fSeatOffsetDistance; // +212 + unsigned int uiMonetary; // +216 - unsigned char ucHeadLight : 8; // +220 - unsigned char ucTailLight : 8; // +221 - unsigned char ucAnimGroup : 8; // +222 + unsigned char ucHeadLight : 8; // +220 + unsigned char ucTailLight : 8; // +221 + unsigned char ucAnimGroup : 8; // +222 }; class CHandlingEntrySA : public CHandlingEntry @@ -93,7 +93,7 @@ class CHandlingEntrySA : public CHandlingEntry // Constructor for original entries CHandlingEntrySA(const tHandlingDataSA* const pOriginal); - virtual ~CHandlingEntrySA(){}; + virtual ~CHandlingEntrySA() {}; // Use this to copy data from an another handling class to this void Assign(const CHandlingEntry* const pEntry) noexcept; diff --git a/Client/game_sa/CHandlingManagerSA.cpp b/Client/game_sa/CHandlingManagerSA.cpp index 8883e361e26..74cbbc9cf23 100644 --- a/Client/game_sa/CHandlingManagerSA.cpp +++ b/Client/game_sa/CHandlingManagerSA.cpp @@ -22,11 +22,11 @@ extern CCoreInterface* g_pCore; extern CGameSA* pGame; -#define ARRAY_HANDLINGDATA 0xC2B9DC +#define ARRAY_HANDLINGDATA 0xC2B9DC -#define Func_Calculate 0x6F5080 -#define Var_fTurnMassMultiplier 0x858B8C -#define Var_fBasicDragCoeff 0x858C58 +#define Func_Calculate 0x6F5080 +#define Var_fTurnMassMultiplier 0x858B8C +#define Var_fBasicDragCoeff 0x858C58 #define DUMP_HANDLING_DATA 0 @@ -107,21 +107,25 @@ __declspec(noinline) void DumpHandlingData(tHandlingDataSA* pData) static __declspec(naked) void Hook_Calculate() { - tHandlingDataSA* pData; - DWORD dwHandlingData; - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - mov eax, [esp+4] - mov dwHandlingData, eax - } + mov eax, [esp+4] - pData = reinterpret_cast(dwHandlingData); - DumpHandlingData(pData); + push ecx // As in the original code + push eax // We use this value to pop it into ecx later - _asm - { - ret 4 + push eax + call DumpHandlingData + add esp, 4 + + pop ecx // adapted from original code: mov ecx, [esp+4+arg_0] + mov eax, 6F5085h + jmp eax } + // clang-format on } CHandlingManagerSA::CHandlingManagerSA() @@ -151,42 +155,42 @@ CHandlingManagerSA::CHandlingManagerSA() } #if DUMP_HANDLING_DATA - HookInstall(Func_Calculate, (DWORD)Hook_Calculate, 11); + HookInstall(Func_Calculate, (DWORD)Hook_Calculate, 5); #endif - m_HandlingNames["mass"] = HandlingProperty::HANDLING_MASS; // works (mass > 0) - m_HandlingNames["turnMass"] = HandlingProperty::HANDLING_TURNMASS; // works - m_HandlingNames["dragCoeff"] = HandlingProperty::HANDLING_DRAGCOEFF; // works - m_HandlingNames["centerOfMass"] = HandlingProperty::HANDLING_CENTEROFMASS; // works - m_HandlingNames["percentSubmerged"] = HandlingProperty::HANDLING_PERCENTSUBMERGED; // works - m_HandlingNames["tractionMultiplier"] = HandlingProperty::HANDLING_TRACTIONMULTIPLIER; // works - m_HandlingNames["driveType"] = HandlingProperty::HANDLING_DRIVETYPE; // works - m_HandlingNames["engineType"] = HandlingProperty::HANDLING_ENGINETYPE; // works - m_HandlingNames["numberOfGears"] = HandlingProperty::HANDLING_NUMOFGEARS; // works - m_HandlingNames["engineAcceleration"] = HandlingProperty::HANDLING_ENGINEACCELERATION; // works - m_HandlingNames["engineInertia"] = HandlingProperty::HANDLING_ENGINEINERTIA; // works - m_HandlingNames["maxVelocity"] = HandlingProperty::HANDLING_MAXVELOCITY; // works - m_HandlingNames["brakeDeceleration"] = HandlingProperty::HANDLING_BRAKEDECELERATION; // works - m_HandlingNames["brakeBias"] = HandlingProperty::HANDLING_BRAKEBIAS; // works - m_HandlingNames["ABS"] = HandlingProperty::HANDLING_ABS; // has no effect in vanilla gta either - m_HandlingNames["steeringLock"] = HandlingProperty::HANDLING_STEERINGLOCK; // works - m_HandlingNames["tractionLoss"] = HandlingProperty::HANDLING_TRACTIONLOSS; // works - m_HandlingNames["tractionBias"] = HandlingProperty::HANDLING_TRACTIONBIAS; // works - m_HandlingNames["suspensionForceLevel"] = HandlingProperty::HANDLING_SUSPENSION_FORCELEVEL; // works - m_HandlingNames["suspensionDamping"] = HandlingProperty::HANDLING_SUSPENSION_DAMPING; // works - m_HandlingNames["suspensionHighSpeedDamping"] = HandlingProperty::HANDLING_SUSPENSION_HIGHSPEEDDAMPING; // works - m_HandlingNames["suspensionUpperLimit"] = HandlingProperty::HANDLING_SUSPENSION_UPPER_LIMIT; // works - m_HandlingNames["suspensionLowerLimit"] = HandlingProperty::HANDLING_SUSPENSION_LOWER_LIMIT; // works - m_HandlingNames["suspensionFrontRearBias"] = HandlingProperty::HANDLING_SUSPENSION_FRONTREARBIAS; // works - m_HandlingNames["suspensionAntiDiveMultiplier"] = HandlingProperty::HANDLING_SUSPENSION_ANTIDIVEMULTIPLIER; // works - m_HandlingNames["collisionDamageMultiplier"] = HandlingProperty::HANDLING_COLLISIONDAMAGEMULTIPLIER; // works - m_HandlingNames["seatOffsetDistance"] = HandlingProperty::HANDLING_SEATOFFSETDISTANCE; // works - m_HandlingNames["monetary"] = HandlingProperty::HANDLING_MONETARY; // useless as it only influences SP stats (value of damaged property) - m_HandlingNames["handlingFlags"] = HandlingProperty::HANDLING_HANDLINGFLAGS; // works - m_HandlingNames["modelFlags"] = HandlingProperty::HANDLING_MODELFLAGS; // works - m_HandlingNames["headLight"] = HandlingProperty::HANDLING_HEADLIGHT; // doesn't work - m_HandlingNames["tailLight"] = HandlingProperty::HANDLING_TAILLIGHT; // doesn't seem to work* - m_HandlingNames["animGroup"] = HandlingProperty::HANDLING_ANIMGROUP; // works model based + m_HandlingNames["mass"] = HandlingProperty::HANDLING_MASS; // works (mass > 0) + m_HandlingNames["turnMass"] = HandlingProperty::HANDLING_TURNMASS; // works + m_HandlingNames["dragCoeff"] = HandlingProperty::HANDLING_DRAGCOEFF; // works + m_HandlingNames["centerOfMass"] = HandlingProperty::HANDLING_CENTEROFMASS; // works + m_HandlingNames["percentSubmerged"] = HandlingProperty::HANDLING_PERCENTSUBMERGED; // works + m_HandlingNames["tractionMultiplier"] = HandlingProperty::HANDLING_TRACTIONMULTIPLIER; // works + m_HandlingNames["driveType"] = HandlingProperty::HANDLING_DRIVETYPE; // works + m_HandlingNames["engineType"] = HandlingProperty::HANDLING_ENGINETYPE; // works + m_HandlingNames["numberOfGears"] = HandlingProperty::HANDLING_NUMOFGEARS; // works + m_HandlingNames["engineAcceleration"] = HandlingProperty::HANDLING_ENGINEACCELERATION; // works + m_HandlingNames["engineInertia"] = HandlingProperty::HANDLING_ENGINEINERTIA; // works + m_HandlingNames["maxVelocity"] = HandlingProperty::HANDLING_MAXVELOCITY; // works + m_HandlingNames["brakeDeceleration"] = HandlingProperty::HANDLING_BRAKEDECELERATION; // works + m_HandlingNames["brakeBias"] = HandlingProperty::HANDLING_BRAKEBIAS; // works + m_HandlingNames["ABS"] = HandlingProperty::HANDLING_ABS; // has no effect in vanilla gta either + m_HandlingNames["steeringLock"] = HandlingProperty::HANDLING_STEERINGLOCK; // works + m_HandlingNames["tractionLoss"] = HandlingProperty::HANDLING_TRACTIONLOSS; // works + m_HandlingNames["tractionBias"] = HandlingProperty::HANDLING_TRACTIONBIAS; // works + m_HandlingNames["suspensionForceLevel"] = HandlingProperty::HANDLING_SUSPENSION_FORCELEVEL; // works + m_HandlingNames["suspensionDamping"] = HandlingProperty::HANDLING_SUSPENSION_DAMPING; // works + m_HandlingNames["suspensionHighSpeedDamping"] = HandlingProperty::HANDLING_SUSPENSION_HIGHSPEEDDAMPING; // works + m_HandlingNames["suspensionUpperLimit"] = HandlingProperty::HANDLING_SUSPENSION_UPPER_LIMIT; // works + m_HandlingNames["suspensionLowerLimit"] = HandlingProperty::HANDLING_SUSPENSION_LOWER_LIMIT; // works + m_HandlingNames["suspensionFrontRearBias"] = HandlingProperty::HANDLING_SUSPENSION_FRONTREARBIAS; // works + m_HandlingNames["suspensionAntiDiveMultiplier"] = HandlingProperty::HANDLING_SUSPENSION_ANTIDIVEMULTIPLIER; // works + m_HandlingNames["collisionDamageMultiplier"] = HandlingProperty::HANDLING_COLLISIONDAMAGEMULTIPLIER; // works + m_HandlingNames["seatOffsetDistance"] = HandlingProperty::HANDLING_SEATOFFSETDISTANCE; // works + m_HandlingNames["monetary"] = HandlingProperty::HANDLING_MONETARY; // useless as it only influences SP stats (value of damaged property) + m_HandlingNames["handlingFlags"] = HandlingProperty::HANDLING_HANDLINGFLAGS; // works + m_HandlingNames["modelFlags"] = HandlingProperty::HANDLING_MODELFLAGS; // works + m_HandlingNames["headLight"] = HandlingProperty::HANDLING_HEADLIGHT; // doesn't work + m_HandlingNames["tailLight"] = HandlingProperty::HANDLING_TAILLIGHT; // doesn't seem to work* + m_HandlingNames["animGroup"] = HandlingProperty::HANDLING_ANIMGROUP; // works model based } CHandlingManagerSA::~CHandlingManagerSA() @@ -240,10 +244,11 @@ const CFlyingHandlingEntry* CHandlingManagerSA::GetOriginalFlyingHandlingData(st // Get our Handling ID, the default value will be HT_LANDSTAL const HandlingType eHandling = GetHandlingID(model); // Original GTA:SA behavior - if (eHandling < HandlingType::HT_SEAPLANE || eHandling > HandlingType::HT_RCRAIDER) + if (eHandling < HandlingType::HT_SEAPLANE || eHandling > HandlingType::HT_RCRAIDER) { return m_OriginalFlyingEntries[0].get(); - else - return m_OriginalFlyingEntries[static_cast(eHandling) - static_cast(HandlingType::HT_SEAPLANE)].get(); + } else { + r +}eturn m_OriginalFlyingEntries[static_cast(eHandling) - static_cast(HandlingType::HT_SEAPLANE)].get(); } const CBoatHandlingEntry* CHandlingManagerSA::GetOriginalBoatHandlingData(std::uint32_t model) const noexcept @@ -255,10 +260,11 @@ const CBoatHandlingEntry* CHandlingManagerSA::GetOriginalBoatHandlingData(std::u // Get our Handling ID, the default value will be HT_LANDSTAL const HandlingType eHandling = GetHandlingID(model); // Original GTA:SA behavior - if (eHandling < HandlingType::HT_PREDATOR || eHandling > HandlingType::HT_SEAPLANE) + if (eHandling < HandlingType::HT_PREDATOR || eHandling > HandlingType::HT_SEAPLANE) { return m_OriginalBoatEntries[0].get(); - else - return m_OriginalBoatEntries[static_cast(eHandling) - static_cast(HandlingType::HT_PREDATOR)].get(); + } else { + r +}eturn m_OriginalBoatEntries[static_cast(eHandling) - static_cast(HandlingType::HT_PREDATOR)].get(); } const CBikeHandlingEntry* CHandlingManagerSA::GetOriginalBikeHandlingData(std::uint32_t model) const noexcept @@ -269,13 +275,14 @@ const CBikeHandlingEntry* CHandlingManagerSA::GetOriginalBikeHandlingData(std::u // Get our Handling ID, the default value will be HT_LANDSTAL const HandlingType eHandling = GetHandlingID(model); - if (eHandling >= HandlingType::HT_BIKE && eHandling <= HandlingType::HT_FREEWAY) + if (eHandling >= HandlingType::HT_BIKE && eHandling <= HandlingType::HT_FREEWAY) { return m_OriginalBikeEntries[static_cast(eHandling) - static_cast(HandlingType::HT_BIKE)].get(); - else if (eHandling == HandlingType::HT_FAGGIO) + } else if (eHandling == HandlingType::HT_FAGGIO) { return m_OriginalBikeEntries[13].get(); - else + } else { return nullptr; } +} // Return the handling manager id HandlingType CHandlingManagerSA::GetHandlingID(std::uint32_t model) noexcept @@ -8274,28 +8281,28 @@ void CHandlingManagerSA::InitializeDefaultHandlings() noexcept m_OriginalHandlingData[209].ucTailLight = 1; m_OriginalHandlingData[209].ucAnimGroup = 0; - m_OriginalHandlingData[210] = m_OriginalHandlingData[69]; // HT_HOTRINA = HT_HOTRING + m_OriginalHandlingData[210] = m_OriginalHandlingData[69]; // HT_HOTRINA = HT_HOTRING m_OriginalHandlingData[210].iVehicleID = 210; - m_OriginalHandlingData[211] = m_OriginalHandlingData[69]; // HT_HOTRINB = HT_HOTRING + m_OriginalHandlingData[211] = m_OriginalHandlingData[69]; // HT_HOTRINB = HT_HOTRING m_OriginalHandlingData[211].iVehicleID = 211; - m_OriginalHandlingData[212] = m_OriginalHandlingData[103]; // HT_SADLSHIT = HT_SADLER + m_OriginalHandlingData[212] = m_OriginalHandlingData[103]; // HT_SADLSHIT = HT_SADLER m_OriginalHandlingData[212].iVehicleID = 212; - m_OriginalHandlingData[213] = m_OriginalHandlingData[52]; // HT_GLENSHIT = HT_GLENDALE + m_OriginalHandlingData[213] = m_OriginalHandlingData[52]; // HT_GLENSHIT = HT_GLENDALE m_OriginalHandlingData[213].iVehicleID = 213; - m_OriginalHandlingData[214] = m_OriginalHandlingData[163]; // HT_FAGGIO = HT_PIZZABOY + m_OriginalHandlingData[214] = m_OriginalHandlingData[163]; // HT_FAGGIO = HT_PIZZABOY m_OriginalHandlingData[214].iVehicleID = 214; - m_OriginalHandlingData[215] = m_OriginalHandlingData[7]; // HT_FIRELA = HT_FIRETRUK + m_OriginalHandlingData[215] = m_OriginalHandlingData[7]; // HT_FIRELA = HT_FIRETRUK m_OriginalHandlingData[215].iVehicleID = 215; - m_OriginalHandlingData[216] = m_OriginalHandlingData[65]; // HT_RNCHLURE = HT_RANCHER + m_OriginalHandlingData[216] = m_OriginalHandlingData[65]; // HT_RNCHLURE = HT_RANCHER m_OriginalHandlingData[216].iVehicleID = 216; - m_OriginalHandlingData[217] = m_OriginalHandlingData[126]; // HT_FREIBOX = HT_FREIFLAT + m_OriginalHandlingData[217] = m_OriginalHandlingData[126]; // HT_FREIBOX = HT_FREIFLAT m_OriginalHandlingData[217].iVehicleID = 217; // Aircrafts handling @@ -9125,7 +9132,7 @@ void CHandlingManagerSA::InitializeDefaultHandlings() noexcept m_OriginalBikeHandlingData[12].fWheelieStabMult = 0.5f; m_OriginalBikeHandlingData[12].fStoppieStabMult = 0.3f; - m_OriginalBikeHandlingData[13] = m_OriginalBikeHandlingData[1]; // HT_FAGGIO = HT_PIZZABOY + m_OriginalBikeHandlingData[13] = m_OriginalBikeHandlingData[1]; // HT_FAGGIO = HT_PIZZABOY m_OriginalBikeHandlingData[13].iVehicleID = 214; } @@ -9153,20 +9160,21 @@ void CHandlingManagerSA::CheckSuspensionChanges(const CHandlingEntry* const entr bool isChanged = false; // Find changes - if (entry->GetSuspensionAntiDiveMultiplier() != entries->GetSuspensionAntiDiveMultiplier()) + if (entry->GetSuspensionAntiDiveMultiplier() != entries->GetSuspensionAntiDiveMultiplier()) { isChanged = true; - else if (entry->GetSuspensionDamping() != entries->GetSuspensionDamping()) + } else if (entry->GetSuspensionDamping() != entries->GetSuspensionDamping()) { isChanged = true; - else if (entry->GetSuspensionForceLevel() != entries->GetSuspensionForceLevel()) + } else if (entry->GetSuspensionForceLevel() != entries->GetSuspensionForceLevel()) { isChanged = true; - else if (entry->GetSuspensionFrontRearBias() != entries->GetSuspensionFrontRearBias()) + } else if (entry->GetSuspensionFrontRearBias() != entries->GetSuspensionFrontRearBias()) { isChanged = true; - else if (entry->GetSuspensionHighSpeedDamping() != entries->GetSuspensionHighSpeedDamping()) + } else if (entry->GetSuspensionHighSpeedDamping() != entries->GetSuspensionHighSpeedDamping()) { isChanged = true; - else if (entry->GetSuspensionLowerLimit() != entries->GetSuspensionLowerLimit()) + } else if (entry->GetSuspensionLowerLimit() != entries->GetSuspensionLowerLimit()) { isChanged = true; - else if (entry->GetSuspensionUpperLimit() != entries->GetSuspensionUpperLimit()) + } else if (entry->GetSuspensionUpperLimit() != entries->GetSuspensionUpperLimit()) { isChanged = true; +} if (!isChanged) return; diff --git a/Client/game_sa/CHeliSA.h b/Client/game_sa/CHeliSA.h index 67579883e61..eebba976146 100644 --- a/Client/game_sa/CHeliSA.h +++ b/Client/game_sa/CHeliSA.h @@ -16,37 +16,37 @@ class CHeliSAInterface : public CAutomobileSAInterface { public: - std::uint8_t m_nHeliFlags; // 0x988 - std::uint8_t ___pad1[3]; // 0x989 - float m_fLeftRightSkid; // 0x98C - float m_fSteeringUpDown; // 0x990 - float m_fSteeringLeftRight; // 0x994 - float m_fAccelerationBreakStatus; // 0x998 - std::int32_t field_99C; // 0x99C - float m_fRotorZ; // 0x9A0 - float m_fSecondRotorZ; // 0x9A4 - float m_fMaxAltitude; // 0x9A8 - std::int32_t field_9AC; // 0x9AC - float m_fMinAltitude; // 0x9B0 - std::int32_t field_9B4; // 0x9B4 - std::uint8_t field_9B8; // 0x9B8 - std::uint8_t m_nNumSwatOccupants; // 0x9B9 - std::uint8_t m_anSwatIDs[4]; // 0x9BA - std::uint8_t ___pad2[2]; // 0x9BE - std::uint32_t field_9C0[4]; // 0x9C0 - std::int32_t field_9D0; // 0x9D0 - FxSystem_c** m_pParticlesList; // 0x9D4 - std::uint8_t field_9D8[24]; // 0x9D8 - std::int32_t field_9F0; // 0x9F0 - CVector m_vecSearchLightTarget; // 0x9F4 - float m_fSearchLightIntensity; // 0xA00 - std::int32_t field_A04; // 0xA04 - std::int32_t field_A08; // 0xA08 - FxSystem_c** m_ppGunflashFx; // 0xA0C - std::uint8_t m_nFiringMultiplier; // 0xA10 - bool m_bSearchLightEnabled; // 0xA11 - std::uint8_t ___pad3[2]; // 0xA12 - std::int32_t field_A14; // 0xA14 + std::uint8_t m_nHeliFlags; // 0x988 + std::uint8_t ___pad1[3]; // 0x989 + float m_fLeftRightSkid; // 0x98C + float m_fSteeringUpDown; // 0x990 + float m_fSteeringLeftRight; // 0x994 + float m_fAccelerationBreakStatus; // 0x998 + std::int32_t field_99C; // 0x99C + float m_fRotorZ; // 0x9A0 + float m_fSecondRotorZ; // 0x9A4 + float m_fMaxAltitude; // 0x9A8 + std::int32_t field_9AC; // 0x9AC + float m_fMinAltitude; // 0x9B0 + std::int32_t field_9B4; // 0x9B4 + std::uint8_t field_9B8; // 0x9B8 + std::uint8_t m_nNumSwatOccupants; // 0x9B9 + std::uint8_t m_anSwatIDs[4]; // 0x9BA + std::uint8_t ___pad2[2]; // 0x9BE + std::uint32_t field_9C0[4]; // 0x9C0 + std::int32_t field_9D0; // 0x9D0 + FxSystem_c** m_pParticlesList; // 0x9D4 + std::uint8_t field_9D8[24]; // 0x9D8 + std::int32_t field_9F0; // 0x9F0 + CVector m_vecSearchLightTarget; // 0x9F4 + float m_fSearchLightIntensity; // 0xA00 + std::int32_t field_A04; // 0xA04 + std::int32_t field_A08; // 0xA08 + FxSystem_c** m_ppGunflashFx; // 0xA0C + std::uint8_t m_nFiringMultiplier; // 0xA10 + bool m_bSearchLightEnabled; // 0xA11 + std::uint8_t ___pad3[2]; // 0xA12 + std::int32_t field_A14; // 0xA14 }; static_assert(sizeof(CHeliSAInterface) == 0xA18, "Invalid size for CHeliSAInterface"); diff --git a/Client/game_sa/CHudSA.cpp b/Client/game_sa/CHudSA.cpp index e379ea3dc0b..e649ed2dcb5 100644 --- a/Client/game_sa/CHudSA.cpp +++ b/Client/game_sa/CHudSA.cpp @@ -24,7 +24,7 @@ char szZoneName[50] = {'\0'}; static ComponentProperties componentProperties; -RsGlobal* CHudSA::rsGlobal = reinterpret_cast(VAR_RSGlobal); +RsGlobal* CHudSA::rsGlobal = reinterpret_cast(VAR_RSGlobal); std::int16_t* CHudSA::itemToFlash = reinterpret_cast(VAR_ItemToFlash); float CHudSA::calcStreetchX = 0.0f; @@ -43,14 +43,22 @@ std::unordered_map defaultComponentProperties {HUD_BREATH, {CHudSA::GetHUDColour(eHudColour::LIGHT_BLUE)}}, {HUD_ARMOUR, {CHudSA::GetHUDColour(eHudColour::LIGHT_GRAY)}}, {HUD_CLOCK, {CHudSA::GetHUDColour(eHudColour::LIGHT_GRAY), {}, false, false, COLOR_BLACK, eFontAlignment::ALIGN_RIGHT, eFontStyle::FONT_PRICEDOWN, 2}}, - {HUD_MONEY, {CHudSA::GetHUDColour(eHudColour::GREEN), CHudSA::GetHUDColour(eHudColour::RED), false, false, COLOR_BLACK, eFontAlignment::ALIGN_RIGHT, eFontStyle::FONT_PRICEDOWN, 2}}, - {HUD_AMMO, {CHudSA::GetHUDColour(eHudColour::LIGHT_BLUE), {}, false, false, COLOR_BLACK, eFontAlignment::ALIGN_CENTER, eFontStyle::FONT_SUBTITLES, 1, 0, true}}, - {HUD_VEHICLE_NAME, {CHudSA::GetHUDColour(eHudColour::GREEN), {}, false, false, COLOR_BLACK, eFontAlignment::ALIGN_CENTER, eFontStyle::FONT_MENU, 2, 0, true}}, - {HUD_AREA_NAME, {CHudSA::GetHUDColour(eHudColour::LIGHT_BLUE), {}, false, false, COLOR_BLACK, eFontAlignment::ALIGN_CENTER, eFontStyle::FONT_GOTHIC, 2, 0, true}}, - {HUD_RADIO, {CHudSA::GetHUDColour(eHudColour::GOLD), CHudSA::GetHUDColour(eHudColour::DARK_GRAY), false, false, COLOR_BLACK, eFontAlignment::ALIGN_CENTER, eFontStyle::FONT_MENU, 1, 0, true}}, + {HUD_MONEY, + {CHudSA::GetHUDColour(eHudColour::GREEN), CHudSA::GetHUDColour(eHudColour::RED), false, false, COLOR_BLACK, eFontAlignment::ALIGN_RIGHT, + eFontStyle::FONT_PRICEDOWN, 2}}, + {HUD_AMMO, + {CHudSA::GetHUDColour(eHudColour::LIGHT_BLUE), {}, false, false, COLOR_BLACK, eFontAlignment::ALIGN_CENTER, eFontStyle::FONT_SUBTITLES, 1, 0, true}}, + {HUD_VEHICLE_NAME, + {CHudSA::GetHUDColour(eHudColour::GREEN), {}, false, false, COLOR_BLACK, eFontAlignment::ALIGN_CENTER, eFontStyle::FONT_MENU, 2, 0, true}}, + {HUD_AREA_NAME, + {CHudSA::GetHUDColour(eHudColour::LIGHT_BLUE), {}, false, false, COLOR_BLACK, eFontAlignment::ALIGN_CENTER, eFontStyle::FONT_GOTHIC, 2, 0, true}}, + {HUD_RADIO, + {CHudSA::GetHUDColour(eHudColour::GOLD), CHudSA::GetHUDColour(eHudColour::DARK_GRAY), false, false, COLOR_BLACK, eFontAlignment::ALIGN_CENTER, + eFontStyle::FONT_MENU, 1, 0, true}}, {HUD_WEAPON, {RwColor{255, 255, 255, 255}, RwColor{255, 255, 255, 255}}}, - {HUD_WANTED, {CHudSA::GetHUDColour(eHudColour::GOLD), RwColor{0, 0, 0, 170}, false, false, COLOR_BLACK, eFontAlignment::ALIGN_RIGHT, eFontStyle::FONT_GOTHIC, 1, 0, true}} -}; + {HUD_WANTED, + {CHudSA::GetHUDColour(eHudColour::GOLD), RwColor{0, 0, 0, 170}, false, false, COLOR_BLACK, eFontAlignment::ALIGN_RIGHT, eFontStyle::FONT_GOTHIC, 1, 0, + true}}}; CHudSA::CHudSA() { @@ -122,6 +130,9 @@ void CHudSA::InitComponentList() {1, HUD_VEHICLE_NAME, 1, FUNC_DrawVehicleName, 1, 0xCC, 0xC3}, {1, HUD_AREA_NAME, 1, FUNC_DrawAreaName, 1, 0xCC, 0xC3}, {1, HUD_RADAR, 1, FUNC_DrawRadar, 1, 0xCC, 0xC3}, + {1, HUD_RADAR_MAP, 1, FUNC_CRadar_DrawMap, 1, 0xCC, 0xC3}, + {1, HUD_RADAR_BLIPS, 1, FUNC_CRadar_DrawBlips, 1, 0xCC, 0xC3}, + {1, HUD_RADAR_ALTIMETER, 1, CODE_ShowRadarAltimeter, 2, 0xCC, 0xEB30}, {1, HUD_CLOCK, 0, VAR_DisableClock, 1, 1, 0}, {1, HUD_RADIO, 1, FUNC_DrawRadioName, 1, 0xCC, 0xC3}, {1, HUD_WANTED, 1, FUNC_DrawWantedLevel, 1, 0xCC, 0xC3}, @@ -190,7 +201,7 @@ bool CHudSA::IsComponentVisible(eHudComponent component) uchar* pSrc = (uchar*)(&pComponent->disabledData); uchar* pDest = (uchar*)(pComponent->uiDataAddr); if (memcmp(pDest, pSrc, pComponent->uiDataSize) == 0) - return false; // Matches disabled bytes + return false; // Matches disabled bytes return true; } return false; @@ -299,8 +310,8 @@ bool CHudSA::IsCrosshairVisible() eCamMode cameraViewMode = static_cast(camera->GetCam(camera->GetActiveCam())->GetMode()); // Get player - CPed* playerPed = pGame->GetPedContext(); - CWeapon* weapon = nullptr; + CPed* playerPed = pGame->GetPedContext(); + CWeapon* weapon = nullptr; eWeaponType weaponType; // Get player current weapon @@ -312,24 +323,29 @@ bool CHudSA::IsCrosshairVisible() } // Special aiming - if (cameraViewMode == MODE_SNIPER || cameraViewMode == MODE_1STPERSON || cameraViewMode == MODE_ROCKETLAUNCHER || cameraViewMode == MODE_ROCKETLAUNCHER_HS || cameraViewMode == MODE_M16_1STPERSON || cameraViewMode == MODE_HELICANNON_1STPERSON || cameraViewMode == MODE_CAMERA) + if (cameraViewMode == MODE_SNIPER || cameraViewMode == MODE_1STPERSON || cameraViewMode == MODE_ROCKETLAUNCHER || + cameraViewMode == MODE_ROCKETLAUNCHER_HS || cameraViewMode == MODE_M16_1STPERSON || cameraViewMode == MODE_HELICANNON_1STPERSON || + cameraViewMode == MODE_CAMERA) { if (weapon && cameraViewMode != MODE_1STPERSON && pGame->GetWeaponInfo(weaponType, WEAPONSKILL_STD)->GetFireType() != FIRETYPE_MELEE) specialAiming = true; } // Simple aiming - if (cameraViewMode == MODE_M16_1STPERSON_RUNABOUT || cameraViewMode == MODE_ROCKETLAUNCHER_RUNABOUT || cameraViewMode == MODE_ROCKETLAUNCHER_RUNABOUT_HS || cameraViewMode == MODE_SNIPER_RUNABOUT) + if (cameraViewMode == MODE_M16_1STPERSON_RUNABOUT || cameraViewMode == MODE_ROCKETLAUNCHER_RUNABOUT || cameraViewMode == MODE_ROCKETLAUNCHER_RUNABOUT_HS || + cameraViewMode == MODE_SNIPER_RUNABOUT) simpleAiming = true; if ((playerPed && weapon) && !playerPed->GetTargetedObject() && playerPed->GetPedInterface()->pPlayerData->m_bFreeAiming) { CTaskSimpleUseGun* taskUseGun = playerPed->GetPedIntelligence()->GetTaskUseGun(); - if ((!taskUseGun || !taskUseGun->GetSkipAim()) && (cameraViewMode == MODE_AIMWEAPON || cameraViewMode == MODE_AIMWEAPON_FROMCAR || cameraViewMode == MODE_AIMWEAPON_ATTACHED)) + if ((!taskUseGun || !taskUseGun->GetSkipAim()) && + (cameraViewMode == MODE_AIMWEAPON || cameraViewMode == MODE_AIMWEAPON_FROMCAR || cameraViewMode == MODE_AIMWEAPON_ATTACHED)) { if (playerPed->GetPedState() != PedState::PED_ENTER_CAR && playerPed->GetPedState() != PedState::PED_CARJACK) { - if ((weaponType >= WEAPONTYPE_PISTOL && weaponType <= WEAPONTYPE_M4) || weaponType == WEAPONTYPE_TEC9 || weaponType == WEAPONTYPE_COUNTRYRIFLE || weaponType == WEAPONTYPE_MINIGUN || weaponType == WEAPONTYPE_FLAMETHROWER) + if ((weaponType >= WEAPONTYPE_PISTOL && weaponType <= WEAPONTYPE_M4) || weaponType == WEAPONTYPE_TEC9 || + weaponType == WEAPONTYPE_COUNTRYRIFLE || weaponType == WEAPONTYPE_MINIGUN || weaponType == WEAPONTYPE_FLAMETHROWER) simpleAiming = cameraViewMode != MODE_AIMWEAPON || camera->GetTransitionState() == 0; } } @@ -515,7 +531,11 @@ SHudComponentData& CHudSA::GetHudComponentRef(const eHudComponent& component) co return componentProperties.weaponIcon; case HUD_WANTED: return componentProperties.wanted; + default: + break; } + + return componentProperties.hpBar; } void CHudSA::ResetComponentPlacement(const eHudComponent& component, bool resetSize) noexcept @@ -537,7 +557,7 @@ void CHudSA::ResetComponentPlacement(const eHudComponent& component, bool resetS } void CHudSA::SetComponentColor(const eHudComponent& component, std::uint32_t color, bool secondColor) noexcept -{ +{ SColor newColor = TOCOLOR2SCOLOR(color); auto& compRef = GetHudComponentRef(component); @@ -555,11 +575,12 @@ void CHudSA::ResetComponentColor(const eHudComponent& component, bool secondColo const auto& defaultRef = MapGet(defaultComponentProperties, component); - if (!secondColor) + if (!secondColor) { componentData.fillColor = defaultRef.fillColor; - else + } else { componentData.fillColorSecondary = defaultRef.fillColorSecondary; } +} void CHudSA::SetComponentFontDropColor(const eHudComponent& component, std::uint32_t color) noexcept { @@ -601,7 +622,7 @@ SColor CHudSA::GetComponentSecondaryColor(const eHudComponent& component) const SColor CHudSA::GetComponentFontDropColor(const eHudComponent& component) const { - const auto& ref = GetHudComponentRef(component); + const auto& ref = GetHudComponentRef(component); const RwColor& color = CFontSA::GetDropColor(); return SColorRGBA(color.r, color.g, color.b, color.a); } @@ -610,7 +631,7 @@ void CHudSA::RenderHealthBar(int x, int y) { // Flash each 8 frames bool isValidFrame = (pGame->GetSystemFrameCounter() & 8) == 0; - if (*itemToFlash == 4 && isValidFrame) // 4 = HEALTH_BAR + if (*itemToFlash == 4 && isValidFrame) // 4 = HEALTH_BAR return; CPed* playerPed = pGame->GetPedContext(); @@ -620,8 +641,8 @@ void CHudSA::RenderHealthBar(int x, int y) // Save default position once if (!componentProperties.hpBar.placement.setDefaultXY) { - componentProperties.hpBar.placement.x = x; - componentProperties.hpBar.placement.y = y; + componentProperties.hpBar.placement.x = static_cast(x); + componentProperties.hpBar.placement.y = static_cast(y); componentProperties.hpBar.placement.setDefaultXY = true; } @@ -635,21 +656,26 @@ void CHudSA::RenderHealthBar(int x, int y) float barWidth = useCustomSize ? componentProperties.hpBar.placement.customWidth : componentProperties.hpBar.placement.width; // Calc bar width depending on MAX_HEALTH stat - double statModifier = ((double(__cdecl*)(int))FUNC_CStats_GetFatAndMuscleModifier)(10); - float totalWidth = (barWidth * maxHealth) / statModifier; + const double statModifier = ((double(__cdecl*)(int))FUNC_CStats_GetFatAndMuscleModifier)(10); + if (statModifier <= 0.0) + return; + + const float totalWidth = static_cast((static_cast(barWidth) * maxHealth) / statModifier); - float posX = useCustomPosition ? componentProperties.hpBar.placement.customX : (barWidth - totalWidth + x); - float posY = useCustomPosition ? componentProperties.hpBar.placement.customY : y; - std::uint32_t barHeight = static_cast(useCustomSize ? componentProperties.hpBar.placement.customHeight : componentProperties.hpBar.placement.height); + const float posX = useCustomPosition ? componentProperties.hpBar.placement.customX : (barWidth - totalWidth + static_cast(x)); + const float posY = useCustomPosition ? componentProperties.hpBar.placement.customY : static_cast(y); + std::uint32_t barHeight = + static_cast(useCustomSize ? componentProperties.hpBar.placement.customHeight : componentProperties.hpBar.placement.height); // call CSprite2d::DrawBarChart - DrawBarChart(posX, posY, static_cast(totalWidth), barHeight, playerPed->GetHealth() * 100.0f / maxHealth, false, componentProperties.hpBar.drawPercentage, componentProperties.hpBar.drawBlackBorder, componentProperties.hpBar.fillColor, COLOR_BLACK); + DrawBarChart(posX, posY, static_cast(totalWidth), barHeight, playerPed->GetHealth() * 100.0f / maxHealth, false, + componentProperties.hpBar.drawPercentage, componentProperties.hpBar.drawBlackBorder, componentProperties.hpBar.fillColor, COLOR_BLACK); } void CHudSA::RenderBreathBar(int x, int y) { // Flash each 8 frames - if (*itemToFlash == 10 && (pGame->GetSystemFrameCounter() & 8) == 0) // 10 = BREATH_BAR + if (*itemToFlash == 10 && (pGame->GetSystemFrameCounter() & 8) == 0) // 10 = BREATH_BAR return; CPed* playerPed = pGame->GetPedContext(); @@ -659,31 +685,37 @@ void CHudSA::RenderBreathBar(int x, int y) // Save default position once if (!componentProperties.breathBar.placement.setDefaultXY) { - componentProperties.breathBar.placement.x = x; - componentProperties.breathBar.placement.y = y; + componentProperties.breathBar.placement.x = static_cast(x); + componentProperties.breathBar.placement.y = static_cast(y); componentProperties.breathBar.placement.setDefaultXY = true; } // Calc bar width depending on AIR_IN_LUNG stat - double statModifier = ((double(__cdecl*)(int))FUNC_CStats_GetFatAndMuscleModifier)(8); + const double statModifier = ((double(__cdecl*)(int))FUNC_CStats_GetFatAndMuscleModifier)(8); + if (statModifier <= 0.0) + return; // Use custom position/size? bool useCustomPosition = componentProperties.breathBar.placement.useCustomPosition; bool useCustomSize = componentProperties.breathBar.placement.useCustomSize; - float posX = useCustomPosition ? componentProperties.breathBar.placement.customX : x; - float posY = useCustomPosition ? componentProperties.breathBar.placement.customY : y; - std::uint16_t barWidth = static_cast(useCustomSize ? componentProperties.breathBar.placement.customWidth : componentProperties.breathBar.placement.width); - std::uint32_t barHeight = static_cast(useCustomSize ? componentProperties.breathBar.placement.customHeight : componentProperties.breathBar.placement.height); + const float posX = useCustomPosition ? componentProperties.breathBar.placement.customX : static_cast(x); + const float posY = useCustomPosition ? componentProperties.breathBar.placement.customY : static_cast(y); + std::uint16_t barWidth = + static_cast(useCustomSize ? componentProperties.breathBar.placement.customWidth : componentProperties.breathBar.placement.width); + std::uint32_t barHeight = + static_cast(useCustomSize ? componentProperties.breathBar.placement.customHeight : componentProperties.breathBar.placement.height); // call CSprite2d::DrawBarChart - DrawBarChart(posX, posY, barWidth, barHeight, playerPed->GetOxygenLevel() / statModifier * 100.0f, false, componentProperties.breathBar.drawPercentage, componentProperties.breathBar.drawBlackBorder, componentProperties.breathBar.fillColor, COLOR_BLACK); + const float breathPercent = static_cast((static_cast(playerPed->GetOxygenLevel()) / statModifier) * 100.0); + DrawBarChart(posX, posY, barWidth, barHeight, breathPercent, false, componentProperties.breathBar.drawPercentage, + componentProperties.breathBar.drawBlackBorder, componentProperties.breathBar.fillColor, COLOR_BLACK); } void CHudSA::RenderArmorBar(int x, int y) { // Flash each 8 frames - if (*itemToFlash == 3 && (pGame->GetSystemFrameCounter() & 8) == 0) // 3 = ARMOR_BAR + if (*itemToFlash == 3 && (pGame->GetSystemFrameCounter() & 8) == 0) // 3 = ARMOR_BAR return; CPed* playerPed = pGame->GetPedContext(); @@ -693,8 +725,8 @@ void CHudSA::RenderArmorBar(int x, int y) // Save default position once if (!componentProperties.armorBar.placement.setDefaultXY) { - componentProperties.armorBar.placement.x = x; - componentProperties.armorBar.placement.y = y; + componentProperties.armorBar.placement.x = static_cast(x); + componentProperties.armorBar.placement.y = static_cast(y); componentProperties.armorBar.placement.setDefaultXY = true; } @@ -702,13 +734,17 @@ void CHudSA::RenderArmorBar(int x, int y) bool useCustomPosition = componentProperties.hpBar.placement.useCustomPosition; bool useCustomSize = componentProperties.hpBar.placement.useCustomSize; - float posX = useCustomPosition ? componentProperties.armorBar.placement.customX : x; - float posY = useCustomPosition ? componentProperties.armorBar.placement.customY : y; - std::uint16_t barWidth = static_cast(useCustomSize ? componentProperties.armorBar.placement.customWidth : componentProperties.armorBar.placement.width); - std::uint32_t barHeight = static_cast(useCustomSize ? componentProperties.armorBar.placement.customHeight : componentProperties.armorBar.placement.height); + const float posX = useCustomPosition ? componentProperties.armorBar.placement.customX : static_cast(x); + const float posY = useCustomPosition ? componentProperties.armorBar.placement.customY : static_cast(y); + std::uint16_t barWidth = + static_cast(useCustomSize ? componentProperties.armorBar.placement.customWidth : componentProperties.armorBar.placement.width); + std::uint32_t barHeight = + static_cast(useCustomSize ? componentProperties.armorBar.placement.customHeight : componentProperties.armorBar.placement.height); // call CSprite2d::DrawBarChart - DrawBarChart(posX, posY, barWidth, barHeight, playerPed->GetArmor() / static_cast(pGame->GetPlayerInfo()->GetMaxArmor()) * 100.0f, false, componentProperties.armorBar.drawPercentage, componentProperties.armorBar.drawBlackBorder, componentProperties.armorBar.fillColor, COLOR_BLACK); + DrawBarChart(posX, posY, barWidth, barHeight, playerPed->GetArmor() / static_cast(pGame->GetPlayerInfo()->GetMaxArmor()) * 100.0f, false, + componentProperties.armorBar.drawPercentage, componentProperties.armorBar.drawBlackBorder, componentProperties.armorBar.fillColor, + COLOR_BLACK); } void CHudSA::RenderText(float x, float y, const char* text, SHudComponentData& properties, bool useSecondColor, bool drawFromBottom, bool scaleForLanguage) @@ -720,10 +756,11 @@ void CHudSA::RenderText(float x, float y, const char* text, SHudComponentData& p float scaleX = useCustomSize ? properties.placement.customWidth : properties.placement.width; float scaleY = useCustomSize ? properties.placement.customHeight : properties.placement.height; - if (!scaleForLanguage) + if (!scaleForLanguage) { CFontSA::SetScale(scaleX, scaleY); - else + } else { CFontSA::SetScaleForCurrentLanguage(scaleX, scaleY); +} CFontSA::SetProportional(properties.proportional); @@ -742,7 +779,9 @@ void CHudSA::RenderText(float x, float y, const char* text, SHudComponentData& p if (!properties.useCustomAlpha) { CFontSA::SetDropColor(RwColor{properties.dropColor.r, properties.dropColor.g, properties.dropColor.b, CFontSA::GetColor().a}); - CFontSA::SetColor(useSecondColor ? RwColor{properties.fillColorSecondary.r, properties.fillColorSecondary.g, properties.fillColorSecondary.b, CFontSA::GetColor().a} : RwColor{properties.fillColor.r, properties.fillColor.g, properties.fillColor.b, CFontSA::GetColor().a}); + CFontSA::SetColor( + useSecondColor ? RwColor{properties.fillColorSecondary.r, properties.fillColorSecondary.g, properties.fillColorSecondary.b, CFontSA::GetColor().a} + : RwColor{properties.fillColor.r, properties.fillColor.g, properties.fillColor.b, CFontSA::GetColor().a}); } else { @@ -765,11 +804,12 @@ void CHudSA::RenderText(float x, float y, const char* text, SHudComponentData& p float posX = useCustomPosition ? properties.placement.customX : x; float posY = useCustomPosition ? properties.placement.customY : y; - if (!drawFromBottom) + if (!drawFromBottom) { CFontSA::PrintString(posX, posY, text); - else + } else { CFontSA::PrintStringFromBottom(posX, posY, text); } +} void CHudSA::RenderClock(float x, float y, const char* strTime) { @@ -840,7 +880,8 @@ void __fastcall CHudSA::RenderWeaponIcon_Sprite(void* sprite, void*, CRect* rect ((void(__thiscall*)(void*, CRect*, RwColor*))FUNC_CSprite2d_Draw)(sprite, rect, color); } -void CHudSA::RenderWeaponIcon_XLU(CVector pos, CVector2D halfSize, std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint16_t intensity, float rhw, std::uint8_t a, std::uint8_t uDir, std::uint8_t vDir) +void CHudSA::RenderWeaponIcon_XLU(CVector pos, CVector2D halfSize, std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint16_t intensity, float rhw, + std::uint8_t a, std::uint8_t uDir, std::uint8_t vDir) { // Use custom position/size? SHudComponentData& properties = componentProperties.weaponIcon; @@ -881,7 +922,8 @@ void CHudSA::RenderWeaponIcon_XLU(CVector pos, CVector2D halfSize, std::uint8_t } // Call CSprite::RenderOneXLUSprite - ((void(__cdecl*)(CVector, CVector2D, std::uint8_t, std::uint8_t, std::uint8_t, std::uint16_t, float, std::uint8_t, std::uint8_t, std::uint8_t))FUNC_CSprite_RenderOneXLUSprite)(pos, halfSize, r, g, b, intensity, rhw, a, uDir, vDir); + ((void(__cdecl*)(CVector, CVector2D, std::uint8_t, std::uint8_t, std::uint8_t, std::uint16_t, float, std::uint8_t, std::uint8_t, + std::uint8_t))FUNC_CSprite_RenderOneXLUSprite)(pos, halfSize, r, g, b, intensity, rhw, a, uDir, vDir); } void CHudSA::RenderWanted(bool empty, float x, float y, const char* strLevel) @@ -890,37 +932,42 @@ void CHudSA::RenderWanted(bool empty, float x, float y, const char* strLevel) } static constexpr std::uintptr_t CONTINUE_RenderWanted = 0x58DFD8; -static void _declspec(naked) HOOK_RenderWanted() +static void __declspec(naked) HOOK_RenderWanted() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - cmp ebp, edi - jle empty + cmp ebp, edi + jle empty - push 0 - jmp render + push 0 + jmp render empty: - push 1 + push 1 render: - call CHudSA::RenderWanted - add esp,4 + call CHudSA::RenderWanted + add esp, 4 - jmp CONTINUE_RenderWanted + jmp CONTINUE_RenderWanted } + // clang-format on } static void HOOK_RenderHudBar(int playerId, int x, int y) { void* returnAdress = _ReturnAddress(); - if (returnAdress == (void*)0x58EE9F || returnAdress == (void*)0x58EF12) + if (returnAdress == (void*)0x58EE9F || returnAdress == (void*)0x58EF12) { CHudSA::RenderHealthBar(x, y); - else if (returnAdress == (void*)0x58F136 || returnAdress == (void*)0x58F1B2) + } else if (returnAdress == (void*)0x58F136 || returnAdress == (void*)0x58F1B2) { CHudSA::RenderBreathBar(x, y); - else if (returnAdress == (void*)0x58EF70 || returnAdress == (void*)0x58EFE3) + } else if (returnAdress == (void*)0x58EF70 || returnAdress == (void*)0x58EFE3) { CHudSA::RenderArmorBar(x, y); } +} void CHudSA::StaticSetHooks() { diff --git a/Client/game_sa/CHudSA.h b/Client/game_sa/CHudSA.h index 4e0d830b1cc..520bd053a0c 100644 --- a/Client/game_sa/CHudSA.h +++ b/Client/game_sa/CHudSA.h @@ -17,39 +17,43 @@ #include "CFontSA.h" #include "CRect.h" -#define FUNC_Draw 0x58FAE0 +#define FUNC_Draw 0x58FAE0 -#define VAR_DisableClock 0xBAA400 +#define VAR_DisableClock 0xBAA400 // X -#define VAR_AspectRatioMultX 0x859520 +#define VAR_AspectRatioMultX 0x859520 // Y -#define VAR_AspectRatioMult 0x859524 - -#define VAR_CameraCrosshairScale 0x866C74 - -#define FUNC_DrawAmmo 0x5893B0 -#define FUNC_DrawWeaponIcon 0x58D7D0 -#define FUNC_RenderHealthBar 0x589270 -#define FUNC_RenderBreathBar 0x589190 -#define FUNC_RenderArmorBar 0x5890A0 - -#define FUNC_DrawVitalStats 0x589650 -#define FUNC_DrawVehicleName 0x58AEA0 -#define FUNC_DrawHelpText 0x58B6E0 -#define FUNC_DrawAreaName 0x58AA50 -#define FUNC_DrawRadar 0x58A330 -#define FUNC_DrawRadarPlanB 0x58A335 -#define FUNC_DrawRadioName 0x4E9E50 -#define FUNC_DrawWantedLevel 0x58D9A0 -#define FUNC_DrawCrosshair 0x58E020 +#define VAR_AspectRatioMult 0x859524 + +#define VAR_CameraCrosshairScale 0x866C74 + +#define FUNC_DrawAmmo 0x5893B0 +#define FUNC_DrawWeaponIcon 0x58D7D0 +#define FUNC_RenderHealthBar 0x589270 +#define FUNC_RenderBreathBar 0x589190 +#define FUNC_RenderArmorBar 0x5890A0 + +#define FUNC_DrawVitalStats 0x589650 +#define FUNC_DrawVehicleName 0x58AEA0 +#define FUNC_DrawHelpText 0x58B6E0 +#define FUNC_DrawAreaName 0x58AA50 +#define FUNC_DrawRadar 0x58A330 +#define FUNC_DrawRadarPlanB 0x58A335 +#define FUNC_DrawRadioName 0x4E9E50 +#define FUNC_DrawWantedLevel 0x58D9A0 +#define FUNC_DrawCrosshair 0x58E020 #define FUNC_CStats_GetFatAndMuscleModifier 0x559AF0 #define FUNC_CSprite2d_DrawBarChart 0x728640 -#define FUNC_CSprite2d_Draw 0x728350 +#define FUNC_CSprite2d_Draw 0x728350 #define FUNC_CSprite_RenderOneXLUSprite 0x70D000 -#define CODE_ShowMoney 0x58F47D +#define FUNC_CRadar_DrawMap 0x586B00 +#define FUNC_CRadar_DrawBlips 0x588050 + +#define CODE_ShowMoney 0x58F47D +#define CODE_ShowRadarAltimeter 0x58A5A6 #define VAR_CTheScripts_bDrawCrossHair 0xA44490 #define VAR_RSGlobal 0xC17040 @@ -93,68 +97,62 @@ struct RsGlobal std::int32_t frameLimit; bool quit; void* ps; - std::uint8_t keyboard[12]; // RsInputDevice - std::uint8_t mouse[12]; // RsInputDevice - std::uint8_t pad[12]; // RsInputDevice + std::uint8_t keyboard[12]; // RsInputDevice + std::uint8_t mouse[12]; // RsInputDevice + std::uint8_t pad[12]; // RsInputDevice }; struct SComponentPlacement { // Original position & size - float x{0.0f}, y{0.0f}; // for getter function only + float x{0.0f}, y{0.0f}; // for getter function only float width{0.0f}, height{0.0f}; - float stringWidth{0.0f}, stringHeight{0.0f}; // for getter function only + float stringWidth{0.0f}, stringHeight{0.0f}; // for getter function only // Custom position & size float customX{0.0f}, customY{0.0f}; float customWidth{0.0f}, customHeight{0.0f}; - bool useCustomPosition{false}; - bool useCustomSize{false}; - bool setDefaultXY{false}; + bool useCustomPosition{false}; + bool useCustomSize{false}; + bool setDefaultXY{false}; }; struct SHudComponentData { SComponentPlacement placement{}; RwColor fillColor{}; - RwColor fillColorSecondary{0,0,0,255}; + RwColor fillColorSecondary{0, 0, 0, 255}; // Bar bool drawBlackBorder{true}; bool drawPercentage{false}; // Text - RwColor dropColor{0,0,0,255}; - eFontAlignment alignment{}; - eFontStyle style{}; - std::int16_t textOutline{0}; - std::int16_t textShadow{0}; - bool proportional{false}; - bool useCustomAlpha{false}; - - SHudComponentData( - RwColor fill = {}, - RwColor fillSecondary = {0, 0, 0, 255}, - bool blackBorder = true, - bool percentage = false, - RwColor drop = {}, - eFontAlignment align = eFontAlignment::ALIGN_LEFT, - eFontStyle fontStyle = eFontStyle::FONT_PRICEDOWN, - std::int16_t outline = 0, - std::int16_t shadow = 0, - bool prop = false, - bool useCustomAlpha = false) : fillColor(fill), - fillColorSecondary(fillSecondary), - drawBlackBorder(blackBorder), - drawPercentage(percentage), - dropColor(drop), - alignment(align), - style(fontStyle), - textOutline(outline), - textShadow(shadow), + RwColor dropColor{0, 0, 0, 255}; + eFontAlignment alignment{}; + eFontStyle style{}; + std::int16_t textOutline{0}; + std::int16_t textShadow{0}; + bool proportional{false}; + bool useCustomAlpha{false}; + + SHudComponentData(RwColor fill = {}, RwColor fillSecondary = {0, 0, 0, 255}, bool blackBorder = true, bool percentage = false, RwColor drop = {}, + eFontAlignment align = eFontAlignment::ALIGN_LEFT, eFontStyle fontStyle = eFontStyle::FONT_PRICEDOWN, std::int16_t outline = 0, + std::int16_t shadow = 0, bool prop = false, bool useCustomAlpha = false) + : fillColor(fill), + fillColorSecondary(fillSecondary), + drawBlackBorder(blackBorder), + drawPercentage(percentage), + dropColor(drop), + alignment(align), + style(fontStyle), + textOutline(outline), + textShadow(shadow), proportional(prop), - useCustomAlpha(useCustomAlpha) {} + useCustomAlpha(useCustomAlpha) + { + } }; struct ComponentProperties @@ -192,8 +190,14 @@ class CHudSA : public CHud void SetComponentPlacementPosition(SComponentPlacement& placement, const CVector2D& position) noexcept; void SetComponentPlacementSize(SComponentPlacement& placement, const CVector2D& size) noexcept; - void SetComponentPosition(const eHudComponent& component, const CVector2D& position) noexcept override { SetComponentPlacementPosition(GetHudComponentRef(component).placement, position); } - void SetComponentSize(const eHudComponent& component, const CVector2D& size) noexcept override { SetComponentPlacementSize(GetHudComponentRef(component).placement, size); } + void SetComponentPosition(const eHudComponent& component, const CVector2D& position) noexcept override + { + SetComponentPlacementPosition(GetHudComponentRef(component).placement, position); + } + void SetComponentSize(const eHudComponent& component, const CVector2D& size) noexcept override + { + SetComponentPlacementSize(GetHudComponentRef(component).placement, size); + } void ResetComponentPlacement(const eHudComponent& component, bool resetSize) noexcept override; @@ -205,19 +209,40 @@ class CHudSA : public CHud void SetHealthBarBlinkingValue(float minHealth) noexcept override { blinkingBarHPValue = minHealth; } void SetComponentFontDropColor(const eHudComponent& component, std::uint32_t color) noexcept override; - void SetComponentFontOutline(const eHudComponent& component, float outline) noexcept override { GetHudComponentRef(component).textOutline = static_cast(outline); } - void SetComponentFontShadow(const eHudComponent& component, float shadow) noexcept override { GetHudComponentRef(component).textShadow = static_cast(shadow); } + void SetComponentFontOutline(const eHudComponent& component, float outline) noexcept override + { + GetHudComponentRef(component).textOutline = static_cast(outline); + } + void SetComponentFontShadow(const eHudComponent& component, float shadow) noexcept override + { + GetHudComponentRef(component).textShadow = static_cast(shadow); + } void SetComponentFontStyle(const eHudComponent& component, const eFontStyle& style) noexcept override { GetHudComponentRef(component).style = style; } - void SetComponentFontAlignment(const eHudComponent& component, const eFontAlignment& alignment) noexcept override { GetHudComponentRef(component).alignment = alignment; } - void SetComponentFontProportional(const eHudComponent& component, bool proportional) noexcept override { GetHudComponentRef(component).proportional = proportional; } - - void SetComponentUseCustomAlpha(const eHudComponent& component, bool useCustomAlpha) noexcept override { GetHudComponentRef(component).useCustomAlpha = useCustomAlpha; } + void SetComponentFontAlignment(const eHudComponent& component, const eFontAlignment& alignment) noexcept override + { + GetHudComponentRef(component).alignment = alignment; + } + void SetComponentFontProportional(const eHudComponent& component, bool proportional) noexcept override + { + GetHudComponentRef(component).proportional = proportional; + } + + void SetComponentUseCustomAlpha(const eHudComponent& component, bool useCustomAlpha) noexcept override + { + GetHudComponentRef(component).useCustomAlpha = useCustomAlpha; + } void ResetComponentFontOutline(const eHudComponent& component) noexcept override { ResetComponentFontData(component, eHudComponentProperty::TEXT_OUTLINE); } void ResetComponentFontShadow(const eHudComponent& component) noexcept override { ResetComponentFontData(component, eHudComponentProperty::TEXT_SHADOW); } void ResetComponentFontStyle(const eHudComponent& component) noexcept override { ResetComponentFontData(component, eHudComponentProperty::TEXT_STYLE); } - void ResetComponentFontAlignment(const eHudComponent& component) noexcept override { ResetComponentFontData(component, eHudComponentProperty::TEXT_ALIGNMENT); } - void ResetComponentFontProportional(const eHudComponent& component) noexcept override { ResetComponentFontData(component, eHudComponentProperty::TEXT_PROPORTIONAL); } + void ResetComponentFontAlignment(const eHudComponent& component) noexcept override + { + ResetComponentFontData(component, eHudComponentProperty::TEXT_ALIGNMENT); + } + void ResetComponentFontProportional(const eHudComponent& component) noexcept override + { + ResetComponentFontData(component, eHudComponentProperty::TEXT_PROPORTIONAL); + } CVector2D GetComponentPosition(const eHudComponent& component) const noexcept override; CVector2D GetComponentSize(const eHudComponent& component) const noexcept override; @@ -254,10 +279,11 @@ class CHudSA : public CHud void UpdateStreetchCalculations(); void ResetComponent(SComponentPlacement& placement, bool resetSize) noexcept; void ResetComponentFontData(const eHudComponent& component, const eHudComponentProperty& property) noexcept; - + SHudComponentData& GetHudComponentRef(const eHudComponent& component) const noexcept; - static void RenderText(float x, float y, const char* text, SHudComponentData& properties, bool useSecondColor = false, bool drawFromBottom = false, bool scaleForLanguage = false); + static void RenderText(float x, float y, const char* text, SHudComponentData& properties, bool useSecondColor = false, bool drawFromBottom = false, + bool scaleForLanguage = false); static void RenderClock(float x, float y, const char* strTime); static void RenderMoney(float x, float y, const char* strMoney); static void RenderAmmo(float x, float y, const char* strAmmo); @@ -266,7 +292,8 @@ class CHudSA : public CHud static void RenderRadioName(float x, float y, const char* strRadio); static void __fastcall RenderWeaponIcon_Sprite(void* sprite, void*, CRect* rect, RwColor* color); - static void RenderWeaponIcon_XLU(CVector pos, CVector2D halfSize, std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint16_t intensity, float rhw, std::uint8_t a, std::uint8_t uDir, std::uint8_t vDir); + static void RenderWeaponIcon_XLU(CVector pos, CVector2D halfSize, std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint16_t intensity, float rhw, + std::uint8_t a, std::uint8_t uDir, std::uint8_t vDir); static void RenderWanted(bool empty, float x, float y, const char* strLevel); @@ -277,7 +304,7 @@ class CHudSA : public CHud float* m_pfCameraCrosshairScale; float m_fSniperCrosshairScale; - static RsGlobal* rsGlobal; + static RsGlobal* rsGlobal; static std::int16_t* itemToFlash; static float calcStreetchX; diff --git a/Client/game_sa/CIplSA.h b/Client/game_sa/CIplSA.h index e6ca52cfa31..fb734833801 100644 --- a/Client/game_sa/CIplSA.h +++ b/Client/game_sa/CIplSA.h @@ -17,8 +17,8 @@ class CIplSAInterface { public: - CRect rect; - char name[16]; + CRect rect; + char name[16]; uint16_t unk; uint16_t minBuildId; uint16_t maxBuildId; diff --git a/Client/game_sa/CIplStoreSA.cpp b/Client/game_sa/CIplStoreSA.cpp index 2b73b1383eb..6d788546175 100644 --- a/Client/game_sa/CIplStoreSA.cpp +++ b/Client/game_sa/CIplStoreSA.cpp @@ -22,16 +22,52 @@ CIplStoreSA::CIplStoreSA() : m_isStreamingEnabled(true), m_ppIplPoolInterface((C void CIplStoreSA::UnloadAndDisableStreaming(int iplId) { + // Is pool valid? + if (!m_ppIplPoolInterface) + return; + + // Is pool object valid? + auto pool = *m_ppIplPoolInterface; + if (!pool) + return; + + // Is IPL in pool? + if (!pool->IsContains(iplId)) + return; + + // Is IPL object valid? + auto ipl = pool->GetObject(iplId); + if (!ipl) + return; + typedef void*(__cdecl * Function_EnableStreaming)(int); ((Function_EnableStreaming)(0x405890))(iplId); } void CIplStoreSA::EnableStreaming(int iplId) { - auto ipl = (*m_ppIplPoolInterface)->GetObject(iplId); + // Is pool valid? + if (!m_ppIplPoolInterface) + return; + + // Is pool object valid? + auto pool = *m_ppIplPoolInterface; + if (!pool) + return; + + // Is IPL in pool? + if (!pool->IsContains(iplId)) + return; + + // Is IPL object valid? + auto ipl = pool->GetObject(iplId); + if (!ipl) + return; + ipl->bDisabledStreaming = false; - (*gIplQuadTree)->AddItem(ipl, &ipl->rect); + if (*gIplQuadTree) + (*gIplQuadTree)->AddItem(ipl, &ipl->rect); } void CIplStoreSA::SetDynamicIplStreamingEnabled(bool state) @@ -42,27 +78,33 @@ void CIplStoreSA::SetDynamicIplStreamingEnabled(bool state) // Ipl with 0 index is generic // We don't unload this IPL - auto pPool = *m_ppIplPoolInterface; + auto pool = *m_ppIplPoolInterface; + if (!pool) + return; + + // Collect all IPL ids + std::vector iplIds; + iplIds.reserve(pool->m_nSize); + + for (int i = 1; i < pool->m_nSize; i++) + { + if (pool->IsContains(i)) + iplIds.push_back(i); + } + + // Now enable/disable streaming for all IPLs if (!state) { - for (int i = 1; i < pPool->m_nSize; i++) - { - if (pPool->IsContains(i)) - { - UnloadAndDisableStreaming(i); - } - } - (*gIplQuadTree)->RemoveAllItems(); + for (int iplId : iplIds) + UnloadAndDisableStreaming(iplId); + + if (*gIplQuadTree) + (*gIplQuadTree)->RemoveAllItems(); } else { - for (int i = 1; i < pPool->m_nSize; i++) - { - if (pPool->IsContains(i)) - { - EnableStreaming(i); - } - } + for (int iplId : iplIds) + EnableStreaming(iplId); } m_isStreamingEnabled = state; @@ -76,27 +118,34 @@ void CIplStoreSA::SetDynamicIplStreamingEnabled(bool state, std::function iplIds; + iplIds.reserve(pool->m_nSize); + + for (int i = 1; i < pool->m_nSize; i++) + { + auto ipl = pool->GetObject(i); + if (ipl && pool->IsContains(i) && filter(ipl)) + iplIds.push_back(i); + } + + // Apply the streaming state change if (!state) { - for (int i = 1; i < pPool->m_nSize; i++) - { - if (pPool->IsContains(i) && filter(pPool->GetObject(i))) - { - UnloadAndDisableStreaming(i); - } - } - (*gIplQuadTree)->RemoveAllItems(); + for (int iplId : iplIds) + UnloadAndDisableStreaming(iplId); + + if (*gIplQuadTree) + (*gIplQuadTree)->RemoveAllItems(); } else { - for (int i = 1; i < pPool->m_nSize; i++) - { - if (pPool->IsContains(i) && filter(pPool->GetObject(i))) - { - EnableStreaming(i); - } - } + for (int iplId : iplIds) + EnableStreaming(iplId); } m_isStreamingEnabled = state; diff --git a/Client/game_sa/CIplStoreSA.h b/Client/game_sa/CIplStoreSA.h index ec0a2693290..699bce1fcdd 100644 --- a/Client/game_sa/CIplStoreSA.h +++ b/Client/game_sa/CIplStoreSA.h @@ -23,7 +23,7 @@ class CIplStoreSA : public CIplStore ~CIplStoreSA() = default; void SetDynamicIplStreamingEnabled(bool state); - void SetDynamicIplStreamingEnabled(bool state, std::function filter); + void SetDynamicIplStreamingEnabled(bool state, std::function filter); private: void UnloadAndDisableStreaming(int iplId); diff --git a/Client/game_sa/CKeyGenSA.cpp b/Client/game_sa/CKeyGenSA.cpp index 03355eb6b70..d20123d3fe6 100644 --- a/Client/game_sa/CKeyGenSA.cpp +++ b/Client/game_sa/CKeyGenSA.cpp @@ -16,14 +16,10 @@ unsigned int CKeyGenSA::GetKey(const char* szString, int iLength) { unsigned int uiReturn; DWORD dwFunc = FUNC_CKeyGen_GetKey_len; - _asm - { - push iLength - push szString - call dwFunc - add esp, 0x8 - mov uiReturn, eax - } + // clang-format off + using func_t = decltype(uiReturn) (__cdecl*)(decltype(szString), decltype(iLength)); +uiReturn = reinterpret_cast(dwFunc)(szString, iLength); + // clang-format on return uiReturn; } @@ -31,13 +27,10 @@ unsigned int CKeyGenSA::GetKey(const char* szString) { unsigned int uiReturn; DWORD dwFunc = FUNC_CKeyGen_GetKey; - _asm - { - push szString - call dwFunc - add esp, 0x4 - mov uiReturn, eax - } + // clang-format off + using func_t = decltype(uiReturn) (__cdecl*)(decltype(szString)); +uiReturn = reinterpret_cast(dwFunc)(szString); + // clang-format on return uiReturn; } @@ -45,13 +38,10 @@ unsigned int CKeyGenSA::GetUppercaseKey(const char* szString) { unsigned int uiReturn; DWORD dwFunc = FUNC_CKeyGen_GetUppercaseKey; - _asm - { - push szString - call dwFunc - add esp, 0x4 - mov uiReturn, eax - } + // clang-format off + using func_t = decltype(uiReturn) (__cdecl*)(decltype(szString)); +uiReturn = reinterpret_cast(dwFunc)(szString); + // clang-format on return uiReturn; } @@ -59,13 +49,9 @@ unsigned int CKeyGenSA::AppendStringToKey(unsigned int uiKey, const char* szStri { unsigned int uiReturn; DWORD dwFunc = FUNC_CKeyGen_AppendStringToKey; - _asm - { - push szString - push uiKey - call dwFunc - add esp, 0x8 - mov uiReturn, eax - } + // clang-format off + using func_t = decltype(uiReturn) (__cdecl*)(decltype(uiKey), decltype(szString)); +uiReturn = reinterpret_cast(dwFunc)(uiKey, szString); + // clang-format on return uiReturn; } diff --git a/Client/game_sa/CKeyGenSA.h b/Client/game_sa/CKeyGenSA.h index c402e5c34f4..2838346063b 100644 --- a/Client/game_sa/CKeyGenSA.h +++ b/Client/game_sa/CKeyGenSA.h @@ -13,10 +13,10 @@ #include -#define FUNC_CKeyGen_GetKey_len 0x53ced0 -#define FUNC_CKeyGen_GetKey 0x53cf00 -#define FUNC_CKeyGen_GetUppercaseKey 0x53cf30 -#define FUNC_CKeyGen_AppendStringToKey 0x53cf70 +#define FUNC_CKeyGen_GetKey_len 0x53ced0 +#define FUNC_CKeyGen_GetKey 0x53cf00 +#define FUNC_CKeyGen_GetUppercaseKey 0x53cf30 +#define FUNC_CKeyGen_AppendStringToKey 0x53cf70 class CKeyGenSA : public CKeyGen { diff --git a/Client/game_sa/CMarkerSA.cpp b/Client/game_sa/CMarkerSA.cpp index f8e45d12910..6c504532323 100644 --- a/Client/game_sa/CMarkerSA.cpp +++ b/Client/game_sa/CMarkerSA.cpp @@ -30,7 +30,7 @@ void CMarkerSA::Init() internalInterface->bBlipFade = false; internalInterface->nBlipDisplayFlag = (BYTE)MarkerDisplay::MARKER_DISPLAY_BLIPONLY; internalInterface->nBlipSprite = (BYTE)RadarSprite::RADAR_SPRITE_NONE; - #define COORD_BLIP_APPEARANCE_NORMAL 0 +#define COORD_BLIP_APPEARANCE_NORMAL 0 internalInterface->nCoordBlipAppearance = COORD_BLIP_APPEARANCE_NORMAL; internalInterface->pEntryExit = nullptr; } diff --git a/Client/game_sa/CMarkerSA.h b/Client/game_sa/CMarkerSA.h index 75e26637520..18d4c0e0d17 100644 --- a/Client/game_sa/CMarkerSA.h +++ b/Client/game_sa/CMarkerSA.h @@ -23,7 +23,7 @@ class CMarkerSAInterface // The following parameter is used when Blip Type is CAR, CHAR or OBJECT long PoolIndex; // The following parameter is used when Blip Type is COORDS - CVector position; // vec2DBlip; + CVector position; // vec2DBlip; WORD ReferenceIndex; diff --git a/Client/game_sa/CMatrixSA.h b/Client/game_sa/CMatrixSA.h index 7b41c3ea754..349615493d8 100644 --- a/Client/game_sa/CMatrixSA.h +++ b/Client/game_sa/CMatrixSA.h @@ -27,12 +27,12 @@ class CMatrixSAInterface public: RwMatrix* m_pAttachMatrix = nullptr; - bool m_bOwnsAttachedMatrix = false; // do we need to delete attaching matrix at detaching + bool m_bOwnsAttachedMatrix = false; // do we need to delete attaching matrix at detaching CMatrixSAInterface() : m_right{}, flags{}, m_forward{}, pad1{}, m_up{}, pad2{}, m_pos{}, pad3{} {}; CMatrixSAInterface(CMatrixSAInterface const& matrix); - CMatrixSAInterface(RwMatrix* matrix, bool temporary); // like previous + attach - ~CMatrixSAInterface(); // destructor detaches matrix if attached + CMatrixSAInterface(RwMatrix* matrix, bool temporary); // like previous + attach + ~CMatrixSAInterface(); // destructor detaches matrix if attached void ConvertToEulerAngles(float& x, float& y, float& z, std::int32_t flags); void ConvertFromEulerAngles(float x, float y, float z, std::int32_t flags); diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 8b7dd500717..f36db5bd231 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -10,6 +10,9 @@ *****************************************************************************/ #include "StdInc.h" +#include +#include +#include #include #include "CColModelSA.h" #include "CColStoreSA.h" @@ -26,15 +29,28 @@ extern CGameSA* pGame; CBaseModelInfoSAInterface** CModelInfoSAInterface::ms_modelInfoPtrs = (CBaseModelInfoSAInterface**)ARRAY_ModelInfo; CBaseModelInfoSAInterface** ppModelInfo = (CBaseModelInfoSAInterface**)ARRAY_ModelInfo; -std::map CModelInfoSA::ms_RestreamTxdIDMap; -std::map CModelInfoSA::ms_ModelDefaultLodDistanceMap; -std::map CModelInfoSA::ms_ModelDefaultFlagsMap; -std::map CModelInfoSA::ms_ModelDefaultAlphaTransparencyMap; +std::map CModelInfoSA::ms_RestreamTxdIDMap; +std::map CModelInfoSA::ms_ModelDefaultLodDistanceMap; +std::map CModelInfoSA::ms_ModelDefaultFlagsMap; +std::map CModelInfoSA::ms_ModelDefaultAlphaTransparencyMap; std::unordered_map> CModelInfoSA::ms_ModelDefaultDummiesPosition; -std::map CModelInfoSA::ms_ModelDefaultModelTimeInfo; -std::unordered_map CModelInfoSA::ms_OriginalObjectPropertiesGroups; -std::unordered_map> CModelInfoSA::ms_VehicleModelDefaultWheelSizes; -std::map CModelInfoSA::ms_DefaultTxdIDMap; +std::map CModelInfoSA::ms_ModelDefaultModelTimeInfo; +std::unordered_map CModelInfoSA::ms_OriginalObjectPropertiesGroups; +std::unordered_map> CModelInfoSA::ms_VehicleModelDefaultWheelSizes; +std::map CModelInfoSA::ms_DefaultTxdIDMap; +std::uint32_t CModelInfoSA::ms_uiTxdAssignmentGeneration = 0; + +void CModelInfoSA::ClearModelDefaults(DWORD modelId) +{ + ms_DefaultTxdIDMap.erase(static_cast(modelId)); + ms_ModelDefaultFlagsMap.erase(modelId); + ms_ModelDefaultLodDistanceMap.erase(modelId); + ms_ModelDefaultAlphaTransparencyMap.erase(modelId); + ms_OriginalObjectPropertiesGroups.erase(modelId); + ms_ModelDefaultDummiesPosition.erase(modelId); + ms_VehicleModelDefaultWheelSizes.erase(modelId); + ms_ModelDefaultModelTimeInfo.erase(modelId); +} union tIdeFlags { @@ -89,20 +105,134 @@ static void CColAccel_addCacheCol(int idx, const CColModelSAInterface* colModel) function(idx, colModel); } +// Validates model info pointer by checking VFTBL is in valid GTA:SA code range. +// Uses SEH for crash protection when reading the VFTBL field, but avoids +// the expensive volatile read of VFTBL->Destructor by using address validation. +static bool IsValidModelInfoPtr(const void* ptr) noexcept +{ + if (!ptr) + return false; + + __try + { + const auto* p = static_cast(ptr); + const DWORD vftbl = reinterpret_cast(p->VFTBL); + // VFTBL must be in valid GTA:SA code range - this implicitly validates + // the pointer since garbage/freed memory won't have valid VFTBL addresses + return SharedUtil::IsValidGtaSaPtr(vftbl); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } +} + +// IsValidModelInfoPtr only validates via reads, so stale pointers in readable +// but non-writable memory pass. VirtualQuery checks the actual page protection +// to confirm the pointer is in committed writable memory. +static bool IsWritableModelInfoPtr(CBaseModelInfoSAInterface* ptr) noexcept +{ + if (!ptr) + return false; + + MEMORY_BASIC_INFORMATION mbi{}; + if (VirtualQuery(ptr, &mbi, sizeof(mbi)) == 0 || mbi.State != MEM_COMMIT) + return false; + + constexpr DWORD writableMask = PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY; + return (mbi.Protect & writableMask) != 0 && (mbi.Protect & PAGE_GUARD) == 0; +} + +static bool SafeReadColSlot(CColModelSAInterface* pColModel, unsigned short* pOut) noexcept +{ + __try + { + *pOut = pColModel->m_sphere.m_collisionSlot; + return true; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } +} + +static bool SafeReadColData(CColModelSAInterface* pColModel, CColDataSA** pOut) noexcept +{ + __try + { + *pOut = pColModel->m_data; + return true; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } +} + +static bool SafeReadSuspLines(CColDataSA* pColData, void** pOut) noexcept +{ + __try + { + *pOut = pColData->m_suspensionLines; + return true; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } +} + +static bool SafeSwapSuspLines(CColDataSA* pColData, void* pNew, void** pOld) noexcept +{ + __try + { + *pOld = pColData->m_suspensionLines; + pColData->m_suspensionLines = reinterpret_cast(pNew); + return true; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } +} + CModelInfoSA::CModelInfoSA() { m_pInterface = NULL; m_dwModelID = 0xFFFFFFFF; + m_dwParentID = 0; m_dwReferences = 0; m_dwPendingInterfaceRef = 0; m_pOriginalColModelInterface = NULL; + m_colRefCount = 0; + m_usColSlot = 0xFFFF; m_pCustomClump = NULL; m_pCustomColModel = NULL; } CBaseModelInfoSAInterface* CModelInfoSA::GetInterface() { - return m_pInterface = ppModelInfo[m_dwModelID]; + m_pInterface = ppModelInfo[m_dwModelID]; + if (!m_pInterface) + return nullptr; + + if (!IsValidModelInfoPtr(m_pInterface)) + { + m_pInterface = nullptr; + return nullptr; + } + if (m_usColSlot == 0xFFFF && m_pInterface->pColModel) + { + unsigned short slot; + if (!SafeReadColSlot(m_pInterface->pColModel, &slot)) + { + AddReportLog(5553, SString("GetInterface: pColModel access failed for model %u", m_dwModelID), 10); + m_pInterface = nullptr; + return nullptr; + } + m_usColSlot = slot; + } + return m_pInterface; } bool CModelInfoSA::IsBoat() @@ -110,13 +240,10 @@ bool CModelInfoSA::IsBoat() DWORD dwFunction = FUNC_IsBoatModel; DWORD ModelID = m_dwModelID; bool bReturn = false; - _asm - { - push ModelID - call dwFunction - mov bReturn, al - add esp, 4 - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(ModelID)); +bReturn = reinterpret_cast(dwFunction)(ModelID); + // clang-format on return bReturn; } @@ -125,13 +252,10 @@ bool CModelInfoSA::IsCar() DWORD dwFunction = FUNC_IsCarModel; DWORD ModelID = m_dwModelID; bool bReturn = false; - _asm - { - push ModelID - call dwFunction - mov bReturn, al - add esp, 4 - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(ModelID)); +bReturn = reinterpret_cast(dwFunction)(ModelID); + // clang-format on return bReturn; } @@ -140,13 +264,10 @@ bool CModelInfoSA::IsTrain() DWORD dwFunction = FUNC_IsTrainModel; DWORD ModelID = m_dwModelID; bool bReturn = false; - _asm - { - push ModelID - call dwFunction - mov bReturn, al - add esp, 4 - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(ModelID)); +bReturn = reinterpret_cast(dwFunction)(ModelID); + // clang-format on return bReturn; } @@ -155,13 +276,10 @@ bool CModelInfoSA::IsHeli() DWORD dwFunction = FUNC_IsHeliModel; DWORD ModelID = m_dwModelID; bool bReturn = false; - _asm - { - push ModelID - call dwFunction - mov bReturn, al - add esp, 4 - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(ModelID)); +bReturn = reinterpret_cast(dwFunction)(ModelID); + // clang-format on return bReturn; } @@ -170,13 +288,10 @@ bool CModelInfoSA::IsPlane() DWORD dwFunction = FUNC_IsPlaneModel; DWORD ModelID = m_dwModelID; bool bReturn = false; - _asm - { - push ModelID - call dwFunction - mov bReturn, al - add esp, 4 - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(ModelID)); +bReturn = reinterpret_cast(dwFunction)(ModelID); + // clang-format on return bReturn; } @@ -185,13 +300,10 @@ bool CModelInfoSA::IsBike() DWORD dwFunction = FUNC_IsBikeModel; DWORD ModelID = m_dwModelID; bool bReturn = false; - _asm - { - push ModelID - call dwFunction - mov bReturn, al - add esp, 4 - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(ModelID)); +bReturn = reinterpret_cast(dwFunction)(ModelID); + // clang-format on return bReturn; } @@ -200,13 +312,10 @@ bool CModelInfoSA::IsFakePlane() DWORD dwFunction = FUNC_IsFakePlaneModel; DWORD ModelID = m_dwModelID; bool bReturn = false; - _asm - { - push ModelID - call dwFunction - mov bReturn, al - add esp, 4 - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(ModelID)); +bReturn = reinterpret_cast(dwFunction)(ModelID); + // clang-format on return bReturn; } @@ -215,13 +324,10 @@ bool CModelInfoSA::IsMonsterTruck() DWORD dwFunction = FUNC_IsMonsterTruckModel; DWORD ModelID = m_dwModelID; bool bReturn = false; - _asm - { - push ModelID - call dwFunction - mov bReturn, al - add esp, 4 - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(ModelID)); +bReturn = reinterpret_cast(dwFunction)(ModelID); + // clang-format on return bReturn; } @@ -230,13 +336,10 @@ bool CModelInfoSA::IsQuadBike() DWORD dwFunction = FUNC_IsQuadBikeModel; DWORD ModelID = m_dwModelID; bool bReturn = false; - _asm - { - push ModelID - call dwFunction - mov bReturn, al - add esp, 4 - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(ModelID)); +bReturn = reinterpret_cast(dwFunction)(ModelID); + // clang-format on return bReturn; } @@ -245,13 +348,10 @@ bool CModelInfoSA::IsBmx() DWORD dwFunction = FUNC_IsBmxModel; DWORD ModelID = m_dwModelID; bool bReturn = false; - _asm - { - push ModelID - call dwFunction - mov bReturn, al - add esp, 4 - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(ModelID)); +bReturn = reinterpret_cast(dwFunction)(ModelID); + // clang-format on return bReturn; } @@ -260,13 +360,10 @@ bool CModelInfoSA::IsTrailer() DWORD dwFunction = FUNC_IsTrailerModel; DWORD ModelID = m_dwModelID; bool bReturn = false; - _asm - { - push ModelID - call dwFunction - mov bReturn, al - add esp, 4 - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(ModelID)); +bReturn = reinterpret_cast(dwFunction)(ModelID); + // clang-format on return bReturn; } @@ -289,9 +386,11 @@ bool CModelInfoSA::IsVehicle() const if (!IsAllocatedInArchive()) return false; - // NOTE(botder): m_pInterface might be a nullptr here, we can't use it CBaseModelInfoSAInterface* model = ppModelInfo[m_dwModelID]; - return model && reinterpret_cast(model->VFTBL) == vftable_CVehicleModelInfo; + if (!IsValidModelInfoPtr(model)) + return false; + + return reinterpret_cast(model->VFTBL) == vftable_CVehicleModelInfo; } bool CModelInfoSA::IsVehicleModel(std::uint32_t model) noexcept @@ -302,7 +401,8 @@ bool CModelInfoSA::IsVehicleModel(std::uint32_t model) noexcept bool CModelInfoSA::IsPlayerModel() { - return (GetInterface() && GetInterface()->pColModel && GetInterface()->pColModel == (CColModelSAInterface*)VAR_CTempColModels_ModelPed1); + CBaseModelInfoSAInterface* pInterface = GetInterface(); + return pInterface && pInterface->pColModel && pInterface->pColModel == (CColModelSAInterface*)VAR_CTempColModels_ModelPed1; } bool CModelInfoSA::IsUpgrade() @@ -317,7 +417,8 @@ char* CModelInfoSA::GetNameIfVehicle() DWORD ModelID = m_dwModelID; DWORD dwReturn = 0; - _asm + // clang-format off + __asm { push eax push ebx @@ -339,23 +440,25 @@ char* CModelInfoSA::GetNameIfVehicle() pop ebx pop eax } + // clang-format on return (char*)dwReturn; } uint CModelInfoSA::GetAnimFileIndex() { + if (!m_pInterface || !m_pInterface->VFTBL) + return 0xFFFFFFFF; + DWORD dwFunc = m_pInterface->VFTBL->GetAnimFileIndex; + if (!SharedUtil::IsValidGtaSaPtr(dwFunc)) + return 0xFFFFFFFF; + DWORD dwThis = (DWORD)m_pInterface; uint uiReturn = 0; - if (dwFunc) - { - _asm - { - mov ecx, dwThis - call dwFunc - mov uiReturn, eax - } - } + // clang-format off + using func_t = decltype(uiReturn) (__thiscall*)(decltype(dwThis) ); +uiReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on return uiReturn; } @@ -365,6 +468,10 @@ void CModelInfoSA::Request(EModelRequestType requestType, const char* szTag) if (IsLoaded()) return; + // Don't request deallocated models (ppModelInfo[id] is NULL) + if (!IsValid()) + return; + // Bikes can sometimes get stuck when loading unless the anim file is handled like what is does here // Don't change the code below unless you can test it (by recreating the problem it solves) if (IsVehicle()) @@ -395,6 +502,7 @@ void CModelInfoSA::Request(EModelRequestType requestType, const char* szTag) if (requestType == BLOCKING) { pGame->GetStreaming()->RequestModel(m_dwModelID, 0x16); + uint32_t blockingStartTick = GetTickCount32(); pGame->GetStreaming()->LoadAllRequestedModels(true, szTag); if (!IsLoaded()) { @@ -402,6 +510,11 @@ void CModelInfoSA::Request(EModelRequestType requestType, const char* szTag) int iCount = 0; while (iCount++ < 10 && !IsLoaded()) { + // Cap total blocking time (including the first load attempt above) + // to prevent extended freezes from persistent streaming I/O issues + if ((GetTickCount32() - blockingStartTick) > 10000) + break; + bool bOnlyPriorityModels = (iCount < 3 || iCount & 1); pGame->GetStreaming()->LoadAllRequestedModels(bOnlyPriorityModels, szTag); } @@ -429,11 +542,18 @@ void CModelInfoSA::Remove() // Don't remove if GTA refers to it somehow. // Or we'll screw up SA's map for example. - m_pInterface = ppModelInfo[m_dwModelID]; + m_pInterface = GetInterface(); + if (!m_pInterface) + return; // Remove our reference if (m_pInterface->usNumberOfRefs > 0) + { + if (pGame && !pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(m_pInterface->usTextureDictionary) && + CTxdStore_GetTxd(m_pInterface->usTextureDictionary) != nullptr) + CTxdStore_RemoveRef(m_pInterface->usTextureDictionary); m_pInterface->usNumberOfRefs--; + } // No references left? if (m_pInterface->usNumberOfRefs == 0 && !m_pCustomClump && !m_pCustomColModel) @@ -445,6 +565,10 @@ void CModelInfoSA::Remove() bool CModelInfoSA::UnloadUnused() { + m_pInterface = GetInterface(); + if (!m_pInterface) + return false; + if (m_pInterface->usNumberOfRefs == 0 && !m_pCustomClump && !m_pCustomColModel) { pGame->GetStreaming()->RemoveModel(m_dwModelID); @@ -460,29 +584,77 @@ bool CModelInfoSA::IsLoaded() if (m_dwPendingInterfaceRef) { assert(m_dwReferences > 0); - m_pInterface = ppModelInfo[m_dwModelID]; - m_pInterface->usNumberOfRefs++; - m_dwPendingInterfaceRef = 0; + CBaseModelInfoSAInterface* pInterface = GetInterface(); + if (pInterface) + { + pInterface->usNumberOfRefs++; + CTxdStore_AddRef(pInterface->usTextureDictionary); + m_dwPendingInterfaceRef = 0; + } } return true; } return false; } +static void UnlinkStreamingInfoNeighbors(CStreamingInfo* pStreamInfo) +{ + if (!pStreamInfo || !pGame) + return; + + if (pStreamInfo->loadState == eModelLoadState::LOADSTATE_NOT_LOADED) + return; + + CStreaming* pStreaming = pGame->GetStreaming(); + if (!pStreaming) + return; + + constexpr unsigned short kInvalid = static_cast(-1); + const unsigned short prev = pStreamInfo->prevId; + const unsigned short next = pStreamInfo->nextId; + + CStreamingInfo* pPrev = (prev != kInvalid) ? pStreaming->GetStreamingInfo(prev) : nullptr; + CStreamingInfo* pNext = (next != kInvalid) ? pStreaming->GetStreamingInfo(next) : nullptr; + + // If one side already points outside the streaming array, cut the + // reachable side instead of copying the bad link forward. + if (pPrev) + pPrev->nextId = (next == kInvalid || pNext) ? next : kInvalid; + if (pNext) + pNext->prevId = (prev == kInvalid || pPrev) ? prev : kInvalid; +} + bool CModelInfoSA::DoIsLoaded() { // return (BOOL)*(BYTE *)(ARRAY_ModelLoaded + 20*dwModelID); bool bLoaded = pGame->GetStreaming()->HasModelLoaded(m_dwModelID); - if (m_dwModelID < pGame->GetBaseIDforTXD()) + const int32_t baseTxdId = pGame->GetBaseIDforTXD(); + if (baseTxdId > 0 && m_dwModelID < static_cast(baseTxdId)) { - m_pInterface = ppModelInfo[m_dwModelID]; + m_pInterface = GetInterface(); if (bLoaded) { - // Check rw object is there if (!m_pInterface || !m_pInterface->pRwObject) + { + CStreamingInfo* pStreamInfo = pGame->GetStreaming()->GetStreamingInfo(m_dwModelID); + if (pStreamInfo) + { + // Unlink from SA's loaded-entry list before zeroing the link fields to avoid linked list corruptin + UnlinkStreamingInfoNeighbors(pStreamInfo); + pStreamInfo->prevId = static_cast(-1); + pStreamInfo->nextId = static_cast(-1); + pStreamInfo->nextInImg = static_cast(-1); + pStreamInfo->loadState = eModelLoadState::LOADSTATE_NOT_LOADED; + } + if (!m_pInterface) + { + m_dwPendingInterfaceRef = 0; + m_dwReferences = 0; + } return false; + } } } return bLoaded; @@ -490,7 +662,10 @@ bool CModelInfoSA::DoIsLoaded() unsigned short CModelInfoSA::GetFlags() { - return ppModelInfo[m_dwModelID]->usFlags; + CBaseModelInfoSAInterface* pInterface = ppModelInfo[m_dwModelID]; + if (!IsValidModelInfoPtr(pInterface)) + return 0; + return pInterface->usFlags; } unsigned short CModelInfoSA::GetOriginalFlags() @@ -498,12 +673,15 @@ unsigned short CModelInfoSA::GetOriginalFlags() if (MapContains(ms_ModelDefaultFlagsMap, m_dwModelID)) return MapGet(ms_ModelDefaultFlagsMap, m_dwModelID); - return ppModelInfo[m_dwModelID]->usFlags; + CBaseModelInfoSAInterface* pInterface = ppModelInfo[m_dwModelID]; + if (!IsValidModelInfoPtr(pInterface)) + return 0; + return pInterface->usFlags; } void CModelInfoSA::SetFlags(unsigned short usFlags) { - m_pInterface = ppModelInfo[m_dwModelID]; + m_pInterface = GetInterface(); if (!m_pInterface) return; @@ -512,15 +690,15 @@ void CModelInfoSA::SetFlags(unsigned short usFlags) MapSet(ms_ModelDefaultFlagsMap, m_dwModelID, m_pInterface->usFlags); // Don't change bIsColLoaded flag - usFlags &= 0xFF7F; // Disable flag in input - usFlags |= m_pInterface->usFlags & 0x80; // Apply current bIsColLoaded flag + usFlags &= 0xFF7F; // Disable flag in input + usFlags |= m_pInterface->usFlags & 0x80; // Apply current bIsColLoaded flag m_pInterface->usFlags = usFlags; } void CModelInfoSA::SetIdeFlags(unsigned int uiFlags) { - m_pInterface = ppModelInfo[m_dwModelID]; + m_pInterface = GetInterface(); if (!m_pInterface) return; @@ -533,7 +711,7 @@ void CModelInfoSA::SetIdeFlags(unsigned int uiFlags) // Default value is 0xC0 (bIsColLoaded + bIsBackfaceCulled) // But bIsColLoaded should not be changed - m_pInterface->usFlags &= 0x80; // Reset all flags except bIsColLoaded + m_pInterface->usFlags &= 0x80; // Reset all flags except bIsColLoaded m_pInterface->bIsBackfaceCulled = true; // setBaseModelInfoFlags @@ -558,24 +736,25 @@ void CModelInfoSA::SetIdeFlags(unsigned int uiFlags) m_pInterface->bDontCollideWithFlyer = ideFlags.bDontCollideWithFlyer; - if (ideFlags.bFlag20) + if (ideFlags.bFlag20) { m_pInterface->eSpecialModelType = eModelSpecialType::CRANE; - else if (ideFlags.bFlag24) + } else if (ideFlags.bFlag24) { m_pInterface->eSpecialModelType = eModelSpecialType::UNKNOW_1; - else if (ideFlags.bIsBreakableStatue) + } else if (ideFlags.bIsBreakableStatue) { m_pInterface->eSpecialModelType = eModelSpecialType::BREAKABLE_STATUE; - else if (ideFlags.bIsTag) + } else if (ideFlags.bIsTag) { m_pInterface->eSpecialModelType = eModelSpecialType::TAG; - else if (ideFlags.bIsPalm) + } else if (ideFlags.bIsPalm) { m_pInterface->eSpecialModelType = eModelSpecialType::PALM; - else if (ideFlags.bIsTree) + } else if (ideFlags.bIsTree) { m_pInterface->eSpecialModelType = eModelSpecialType::TREE; - else if (ideFlags.bIsGarageDoor) + } else if (ideFlags.bIsGarageDoor) { m_pInterface->eSpecialModelType = eModelSpecialType::GARAGE_DOOR; - else if (ideFlags.bIsGlassType2) + } else if (ideFlags.bIsGlassType2) { m_pInterface->eSpecialModelType = eModelSpecialType::GLASS_2; - else if (ideFlags.bIsGlassType1) + } else if (ideFlags.bIsGlassType1) { m_pInterface->eSpecialModelType = eModelSpecialType::GLASS_1; +} break; } case eModelInfoType::CLUMP: @@ -590,7 +769,7 @@ void CModelInfoSA::SetIdeFlags(unsigned int uiFlags) void CModelInfoSA::SetIdeFlag(eModelIdeFlag eIdeFlag, bool bState) { - m_pInterface = ppModelInfo[m_dwModelID]; + m_pInterface = GetInterface(); if (!m_pInterface) return; @@ -656,7 +835,7 @@ void CModelInfoSA::SetIdeFlag(eModelIdeFlag eIdeFlag, bool bState) bool CModelInfoSA::GetIdeFlag(eModelIdeFlag eIdeFlag) { - m_pInterface = ppModelInfo[m_dwModelID]; + m_pInterface = GetInterface(); if (!m_pInterface) return false; @@ -691,7 +870,12 @@ bool CModelInfoSA::GetIdeFlag(eModelIdeFlag eIdeFlag) case eModelIdeFlag::IS_CRANE: return m_pInterface->eSpecialModelType == eModelSpecialType::CRANE; case eModelIdeFlag::IS_DAMAGABLE: - return ((bool (*)())m_pInterface->VFTBL->AsDamageAtomicModelInfoPtr)(); + { + DWORD funcAddr = m_pInterface->VFTBL->AsDamageAtomicModelInfoPtr; + if (!SharedUtil::IsValidGtaSaPtr(funcAddr)) + return false; + return ((bool (*)())funcAddr)(); + } case eModelIdeFlag::DOES_NOT_COLLIDE_WITH_FLYER: return m_pInterface->bDontCollideWithFlyer; case eModelIdeFlag::DISABLE_BACKFACE_CULLING: @@ -703,29 +887,30 @@ bool CModelInfoSA::GetIdeFlag(eModelIdeFlag eIdeFlag) void CModelInfoSA::SetModelSpecialType(eModelSpecialType eType, bool bState) { - if (bState) + if (bState) { m_pInterface->eSpecialModelType = eType; - else if (m_pInterface->eSpecialModelType == eType) + } else if (m_pInterface->eSpecialModelType == eType) { m_pInterface->eSpecialModelType = eModelSpecialType::NONE; } +} void CModelInfoSA::StaticResetFlags() { - // Restore default values - for (std::map::const_iterator iter = ms_ModelDefaultFlagsMap.begin(); iter != ms_ModelDefaultFlagsMap.end(); ++iter) + for (auto iter = ms_ModelDefaultFlagsMap.begin(); iter != ms_ModelDefaultFlagsMap.end();) { CBaseModelInfoSAInterface* pInterface = ppModelInfo[iter->first]; - if (pInterface) + if (!IsValidModelInfoPtr(pInterface)) { - // Don't change bIsColLoaded flag - ushort usFlags = iter->second; - usFlags &= 0xFF7F; - usFlags |= pInterface->usFlags & 0x80; - pInterface->usFlags = usFlags; + iter = ms_ModelDefaultFlagsMap.erase(iter); + continue; } - } - ms_ModelDefaultFlagsMap.clear(); + ushort usFlags = iter->second; + usFlags &= 0xFF7F; + usFlags |= pInterface->usFlags & 0x80; + pInterface->usFlags = usFlags; + iter = ms_ModelDefaultFlagsMap.erase(iter); + } } CBoundingBox* CModelInfoSA::GetBoundingBox() @@ -733,33 +918,82 @@ CBoundingBox* CModelInfoSA::GetBoundingBox() DWORD dwFunc = FUNC_GetBoundingBox; DWORD ModelID = m_dwModelID; CBoundingBox* dwReturn = 0; - _asm - { - push ModelID - call dwFunc - add esp, 4 - mov dwReturn, eax - } + // clang-format off + using func_t = decltype(dwReturn) (__cdecl*)(decltype(ModelID)); +dwReturn = reinterpret_cast(dwFunc)(ModelID); + // clang-format on return dwReturn; } +bool CModelInfoSA::IsCollisionLoaded() const noexcept +{ + if (m_dwModelID >= MODELINFO_DFF_MAX) + return false; + + const CBaseModelInfoSAInterface* pInterface = ppModelInfo[m_dwModelID]; + return IsValidModelInfoPtr(pInterface) && pInterface->pColModel != nullptr; +} + +bool CModelInfoSA::IsRwObjectLoaded() const noexcept +{ + if (m_dwModelID >= MODELINFO_DFF_MAX) + return false; + + const CBaseModelInfoSAInterface* pInterface = ppModelInfo[m_dwModelID]; + return IsValidModelInfoPtr(pInterface) && pInterface->pRwObject != nullptr; +} + +void CModelInfoSA::WaitForModelFullyLoaded(std::chrono::milliseconds timeout) +{ + if (!IsValid()) + return; + + if (IsLoaded()) + return; + + const bool hasTimeout = timeout.count() > 0; + auto start = std::chrono::steady_clock::now(); + + do + { + Request(hasTimeout ? NON_BLOCKING : BLOCKING, "WaitForModelFullyLoaded"); + + if (!hasTimeout) + return; + + pGame->GetStreaming()->LoadAllRequestedModels(false, "WaitForModelFullyLoaded"); + + if (IsLoaded()) + return; + } while (std::chrono::steady_clock::now() - start < timeout); +} + bool CModelInfoSA::IsValid() { if (m_dwModelID >= MODELINFO_DFF_MAX && m_dwModelID < MODELINFO_TXD_MAX) return !pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(m_dwModelID - MODELINFO_DFF_MAX); - - if (m_dwModelID >= pGame->GetBaseIDforTXD() && m_dwModelID < pGame->GetCountOfAllFileIDs()) - return true; - if (!ppModelInfo[m_dwModelID]) + const int32_t baseTxdId = pGame->GetBaseIDforTXD(); + const int32_t countOfAllFileIds = pGame->GetCountOfAllFileIDs(); + if (baseTxdId > 0 && countOfAllFileIds > baseTxdId) + { + const DWORD baseTxdIdDw = static_cast(baseTxdId); + const DWORD countDw = static_cast(countOfAllFileIds); + if (m_dwModelID >= baseTxdIdDw && m_dwModelID < countDw) + return true; + } + + if (m_dwModelID >= MODELINFO_DFF_MAX) return false; - return true; + m_pInterface = GetInterface(); + return m_pInterface != nullptr; } bool CModelInfoSA::IsAllocatedInArchive() const noexcept { - return pGame->GetStreaming()->GetStreamingInfo(m_dwModelID)->sizeInBlocks > 0; + CStreamingInfo* pStreamingInfo = pGame->GetStreaming()->GetStreamingInfo(m_dwModelID); + return pStreamingInfo && pStreamingInfo->sizeInBlocks > 0; } float CModelInfoSA::GetDistanceFromCentreOfMassToBaseOfModel() @@ -767,7 +1001,7 @@ float CModelInfoSA::GetDistanceFromCentreOfMassToBaseOfModel() DWORD dwModelInfo = 0; DWORD ModelID = m_dwModelID; float fReturn = 0; - _asm { + __asm { mov eax, ModelID push ecx @@ -788,92 +1022,203 @@ float CModelInfoSA::GetDistanceFromCentreOfMassToBaseOfModel() unsigned short CModelInfoSA::GetTextureDictionaryID() { - m_pInterface = ppModelInfo[m_dwModelID]; - if (m_pInterface) - return m_pInterface->usTextureDictionary; - - return 0; + CBaseModelInfoSAInterface* pInterface = GetInterface(); + return pInterface ? pInterface->usTextureDictionary : 0; } void CModelInfoSA::SetTextureDictionaryID(unsigned short usID) { - m_pInterface = ppModelInfo[m_dwModelID]; + m_pInterface = GetInterface(); if (!m_pInterface) return; - // CBaseModelInfo::AddRef adds references to model and TXD - // We need transfer added references from old TXD to new TXD - size_t referencesCount = m_pInterface->usNumberOfRefs; + // This check should be sufficient - dont consider using IsWritableModelInfoPtr here in the future without good reason + if (m_pInterface != ppModelInfo[m_dwModelID]) + { + m_pInterface = nullptr; + return; + } + + unsigned short usOldTxdId = m_pInterface->usTextureDictionary; + if (usOldTxdId == usID) + return; + + // CTxdStore functions (GetTxd, AddRef, RemoveRef) crash on free pool entries. + if (!pGame || pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(usID)) + return; + + // Slot allocated (e.g. via engineRequestTXD) but TXD data isn't loaded yet. + // For unloaded models without geometry, record the new TXD ID and transfer + // entity refs so callers' pre-added refs are consumed. Loaded models fall + // through to the ref-transfer path below. CTxdStore_AddRef only touches + // usUsagesCount (never dereferences rwTexDictonary), and BuildTxdTextureMap + // returns an empty map for null TXDs, making the rebind a no-op. The real + // texture data arrives later via engineImageLinkTXD + restream. + if (CTxdStore_GetTxd(usID) == nullptr) + { + if (!m_pInterface->pRwObject) + { + if (!MapContains(ms_DefaultTxdIDMap, static_cast(m_dwModelID))) + ms_DefaultTxdIDMap[static_cast(m_dwModelID)] = usOldTxdId; + + ++ms_uiTxdAssignmentGeneration; + m_pInterface->usTextureDictionary = usID; + + // Transfer entity refs between TXDs even without geometry loaded. + // Callers that pre-add refs to prevent underflow expect them to be + // consumed here; skipping this leaks refs on the old TXD. + size_t referencesCount = m_pInterface->usNumberOfRefs; + for (size_t i = 0; i < referencesCount; i++) + CTxdStore_AddRef(usID); + + if (!pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(usOldTxdId) && CTxdStore_GetTxd(usOldTxdId) != nullptr) + { + for (size_t i = 0; i < referencesCount; i++) + CTxdStore_RemoveRef(usOldTxdId); + } + return; + } + + // Loaded model: fall through to ref-transfer path + } - // +1 reference for active rwObject - // The current textures will be removed in RpAtomicDestroy - // RenderWare uses an additional reference counter per texture + size_t referencesCount = m_pInterface->usNumberOfRefs; if (m_pInterface->pRwObject) referencesCount++; - for (size_t i = 0; i < referencesCount; i++) - CTxdStore_RemoveRef(m_pInterface->usTextureDictionary); - - // Store vanilla TXD ID - if (!MapContains(ms_DefaultTxdIDMap, m_dwModelID)) - ms_DefaultTxdIDMap[m_dwModelID] = m_pInterface->usTextureDictionary; + if (!MapContains(ms_DefaultTxdIDMap, static_cast(m_dwModelID))) + ms_DefaultTxdIDMap[static_cast(m_dwModelID)] = usOldTxdId; - // Set new TXD and increase ref of it + ++ms_uiTxdAssignmentGeneration; m_pInterface->usTextureDictionary = usID; + // Pin the new TXD before rebinding so textures remain valid during the switch for (size_t i = 0; i < referencesCount; i++) CTxdStore_AddRef(usID); + + // Rebind loaded model's material textures to the new TXD. + // Without this, material->texture pointers would become stale when the old TXD is released. + if (m_pInterface->pRwObject) + { + eModelInfoType modelType = GetModelType(); + switch (modelType) + { + case eModelInfoType::PED: + case eModelInfoType::WEAPON: + case eModelInfoType::VEHICLE: + case eModelInfoType::CLUMP: + case eModelInfoType::UNKNOWN: + { + RpClump* pGameClump = reinterpret_cast(m_pInterface->pRwObject); + if (pGame) + { + CRenderWare* pRenderWare = pGame->GetRenderWare(); + if (pRenderWare) + pRenderWare->RebindClumpTexturesToTxd(pGameClump, usID); + } + break; + } + case eModelInfoType::ATOMIC: + case eModelInfoType::LOD_ATOMIC: + case eModelInfoType::TIME: + { + RpAtomic* pAtomic = reinterpret_cast(m_pInterface->pRwObject); + if (pGame) + { + CRenderWare* pRenderWare = pGame->GetRenderWare(); + if (pRenderWare) + pRenderWare->RebindAtomicTexturesToTxd(pAtomic, usID); + } + break; + } + default: + break; + } + } + + // Release old TXD refs after rebinding. Skip if the slot was freed between + // capturing usOldTxdId and here - CTxdStore functions crash on free entries. + if (!pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(usOldTxdId) && CTxdStore_GetTxd(usOldTxdId) != nullptr) + { + for (size_t i = 0; i < referencesCount; i++) + CTxdStore_RemoveRef(usOldTxdId); + } } void CModelInfoSA::ResetTextureDictionaryID() { - const auto it = ms_DefaultTxdIDMap.find(m_dwModelID); - if (it == ms_DefaultTxdIDMap.end()) { + const auto it = ms_DefaultTxdIDMap.find(static_cast(m_dwModelID)); + if (it == ms_DefaultTxdIDMap.end()) + { + return; + } + + if (!GetInterface()) + { + return; + } + + const auto targetId = static_cast(it->second); + + // If the target TXD pool slot was freed, we can't restore to it. + // When the slot is allocated but its data is unloaded (rwTexDictionary + // null), let SetTextureDictionaryID handle it -- it supports that case. + if (pGame && pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(targetId)) + { + ms_DefaultTxdIDMap.erase(it); + AddReportLog(9401, SString("ResetTextureDictionaryID: target TXD %u freed, model %u stays on TXD %u", targetId, static_cast(m_dwModelID), + static_cast(GetInterface()->usTextureDictionary))); return; } - SetTextureDictionaryID(it->second); - ms_DefaultTxdIDMap.erase(it); // Only erase after calling the function above [otherwise gets reinserted] + + SetTextureDictionaryID(targetId); + if (GetTextureDictionaryID() == targetId) + ms_DefaultTxdIDMap.erase(it); } void CModelInfoSA::StaticResetTextureDictionaries() { - while (!ms_DefaultTxdIDMap.empty()) + std::vector modelIds; + modelIds.reserve(ms_DefaultTxdIDMap.size()); + for (const auto& pair : ms_DefaultTxdIDMap) + modelIds.push_back(pair.first); + + for (auto modelId : modelIds) { - const auto mi = pGame->GetModelInfo(ms_DefaultTxdIDMap.begin()->first); + const auto mi = pGame->GetModelInfo(modelId); if (mi) { mi->ResetTextureDictionaryID(); } else { - // Model was deallocated. Skip and remove it from our list. - ms_DefaultTxdIDMap.erase(ms_DefaultTxdIDMap.begin()); + ms_DefaultTxdIDMap.erase(modelId); } } } float CModelInfoSA::GetLODDistance() { - m_pInterface = ppModelInfo[m_dwModelID]; - if (m_pInterface) - return m_pInterface->fLodDistanceUnscaled; - - return 0.0f; + CBaseModelInfoSAInterface* pInterface = GetInterface(); + return pInterface ? pInterface->fLodDistanceUnscaled : 0.0f; } bool CModelInfoSA::SetTime(char cHourOn, char cHourOff) { m_pInterface = ppModelInfo[m_dwModelID]; - if (!m_pInterface) + if (!IsValidModelInfoPtr(m_pInterface)) + { + m_pInterface = nullptr; return false; + } if (GetModelType() != eModelInfoType::TIME) return false; CTimeInfoSAInterface* pTime = &static_cast(m_pInterface)->timeInfo; - if (!MapContains(ms_ModelDefaultModelTimeInfo, pTime)) - MapSet(ms_ModelDefaultModelTimeInfo, pTime, new CTimeInfoSAInterface(pTime->m_nTimeOn, pTime->m_nTimeOff, pTime->m_wOtherTimeModel)); + if (!MapContains(ms_ModelDefaultModelTimeInfo, m_dwModelID)) + MapSet(ms_ModelDefaultModelTimeInfo, m_dwModelID, *pTime); pTime->m_nTimeOn = cHourOn; pTime->m_nTimeOff = cHourOff; @@ -883,8 +1228,11 @@ bool CModelInfoSA::SetTime(char cHourOn, char cHourOff) bool CModelInfoSA::GetTime(char& cHourOn, char& cHourOff) { m_pInterface = ppModelInfo[m_dwModelID]; - if (!m_pInterface) + if (!IsValidModelInfoPtr(m_pInterface)) + { + m_pInterface = nullptr; return false; + } if (GetModelType() != eModelInfoType::TIME) return false; @@ -898,20 +1246,47 @@ bool CModelInfoSA::GetTime(char& cHourOn, char& cHourOff) void CModelInfoSA::StaticResetModelTimes() { - for (auto const& x : ms_ModelDefaultModelTimeInfo) + for (auto it = ms_ModelDefaultModelTimeInfo.begin(); it != ms_ModelDefaultModelTimeInfo.end();) { - x.first->m_nTimeOn = x.second->m_nTimeOn; - x.first->m_nTimeOff = x.second->m_nTimeOff; - } - ms_ModelDefaultModelTimeInfo.clear(); -} + const DWORD modelId = it->first; + CBaseModelInfoSAInterface* pInterface = ppModelInfo[modelId]; + if (!IsValidModelInfoPtr(pInterface)) + { + it = ms_ModelDefaultModelTimeInfo.erase(it); + continue; + } -float CModelInfoSA::GetOriginalLODDistance() -{ + DWORD funcAddr = pInterface->VFTBL->GetModelType; + if (!SharedUtil::IsValidGtaSaPtr(funcAddr)) + { + it = ms_ModelDefaultModelTimeInfo.erase(it); + continue; + } + const eModelInfoType modelType = ((eModelInfoType (*)())funcAddr)(); + if (modelType != eModelInfoType::TIME) + { + it = ms_ModelDefaultModelTimeInfo.erase(it); + continue; + } + + auto* pTime = &static_cast(pInterface)->timeInfo; + pTime->m_nTimeOn = it->second.m_nTimeOn; + pTime->m_nTimeOff = it->second.m_nTimeOff; + pTime->m_wOtherTimeModel = it->second.m_wOtherTimeModel; + it = ms_ModelDefaultModelTimeInfo.erase(it); + } +} + +float CModelInfoSA::GetOriginalLODDistance() +{ // Return default LOD distance value (if doesn't exist, LOD distance hasn't been changed) if (MapContains(ms_ModelDefaultLodDistanceMap, m_dwModelID)) return MapGet(ms_ModelDefaultLodDistanceMap, m_dwModelID); + CBaseModelInfoSAInterface* pInterface = ppModelInfo[m_dwModelID]; + if (IsValidModelInfoPtr(pInterface)) + return pInterface->fLodDistanceUnscaled; + return 0.0f; } @@ -950,7 +1325,7 @@ void CModelInfoSA::SetLODDistance(float fDistance, bool bOverrideMaxDistance) fDistance = std::min(fDistance, 325.f); } - m_pInterface = ppModelInfo[m_dwModelID]; + m_pInterface = GetInterface(); if (m_pInterface) { // Save default value if not done yet @@ -962,106 +1337,325 @@ void CModelInfoSA::SetLODDistance(float fDistance, bool bOverrideMaxDistance) void CModelInfoSA::StaticResetLodDistances() { - // Restore default values - for (std::map::const_iterator iter = ms_ModelDefaultLodDistanceMap.begin(); iter != ms_ModelDefaultLodDistanceMap.end(); ++iter) + for (auto iter = ms_ModelDefaultLodDistanceMap.begin(); iter != ms_ModelDefaultLodDistanceMap.end();) { CBaseModelInfoSAInterface* pInterface = ppModelInfo[iter->first]; - if (pInterface) - pInterface->fLodDistanceUnscaled = iter->second; - } + if (!IsValidModelInfoPtr(pInterface)) + { + iter = ms_ModelDefaultLodDistanceMap.erase(iter); + continue; + } - ms_ModelDefaultLodDistanceMap.clear(); + pInterface->fLodDistanceUnscaled = iter->second; + iter = ms_ModelDefaultLodDistanceMap.erase(iter); + } } void CModelInfoSA::RestreamIPL() { // IPLs should not contain peds, weapons, vehicles and vehicle upgrades if (m_dwModelID > 611 && (m_dwModelID < 1000 || m_dwModelID > 1193)) - MapSet(ms_RestreamTxdIDMap, GetTextureDictionaryID(), 0); + { + constexpr std::size_t kMaxPendingTxdIDs = 1000; + if (ms_RestreamTxdIDMap.size() >= kMaxPendingTxdIDs) + return; + + auto txdId = GetTextureDictionaryID(); + if (txdId == 0) + return; + + MapSet(ms_RestreamTxdIDMap, txdId, 0); + } +} + +// Helper to call entity's DeleteRwObject virtual method +static void DeleteEntityRwObject(CEntitySAInterface* pEntity) +{ + _asm + { + mov ecx, pEntity + mov eax, [ecx] + call dword ptr [eax+20h] + } +} + +#define FUNC_CEntity_DeleteRwObject 0x534030 +#define NUM_MinValidEntityAddr 0x10000 + +// Validates entity vtable pointer with SEH protection. +// If bCheckDeleteRwObject is true, also verifies DeleteRwObject is the CEntity +// base implementation - only valid for CBuilding/CDummy sector entities. +static bool HasValidEntityVtablePtr(CEntitySAInterface* pEntity, bool bCheckDeleteRwObject) +{ + DWORD dwEntityAddr = reinterpret_cast(pEntity); + if (dwEntityAddr < NUM_MinValidEntityAddr || (dwEntityAddr & 3) != 0) + return false; + + __try + { + DWORD* pdwVtbl = reinterpret_cast(pEntity->GetVTBL()); + if (!SharedUtil::IsValidGtaSaPtr(reinterpret_cast(pdwVtbl))) + return false; + + if (bCheckDeleteRwObject && pdwVtbl[8] != FUNC_CEntity_DeleteRwObject) + return false; + + return true; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } +} + +// Tracks log-throttle counters for invalid entity reports during restream +struct SRestreamLogState +{ + static constexpr int MAX_LOGS_PER_CALL = 32; + + int iStreamCount = 0; + int iRepeatCount = 0; + bool bStreamSuppressed = false; + bool bRepeatSuppressed = false; + + void LogInvalidEntity(bool bIsStreamSector, int iSectorIndex, CEntitySAInterface* pEntity) + { + if (bIsStreamSector) + { + if (iStreamCount < MAX_LOGS_PER_CALL) + { + AddReportLog(5560, + SString("Entity 0x%08x at ARRAY_StreamSectors[%d,%d] has invalid vtable", pEntity, iSectorIndex / 2 % NUM_StreamSectorRows, + iSectorIndex / 2 / NUM_StreamSectorCols), + 10); + ++iStreamCount; + } + else if (!bStreamSuppressed) + { + AddReportLog(5560, "Additional invalid StreamSectors entities suppressed this call", 10); + bStreamSuppressed = true; + } + } + else + { + if (iRepeatCount < MAX_LOGS_PER_CALL) + { + AddReportLog(5561, SString("Entity 0x%08x at ARRAY_StreamRepeatSectors[%d] has invalid vtable", pEntity, iSectorIndex), 10); + ++iRepeatCount; + } + else if (!bRepeatSuppressed) + { + AddReportLog(5561, "Additional invalid StreamRepeatSectors entities suppressed this call", 10); + bRepeatSuppressed = true; + } + } + } +}; + +// Process entities from a sector list, skipping any with corrupted/invalid vtables. +// StreamSectors (buildings/dummies): full vtable check including DeleteRwObject validation. +// StreamRepeatSectors (vehicles/peds/objects): vtable pointer range check only, because +// these entity types override DeleteRwObject and can't be validated by vtable content. +static void ProcessRestreamSectorList(DWORD* pSectorEntry, bool bIsStreamSector, int iSectorIndex, SRestreamLogState& logState, + std::unordered_set& processedTxdIDs, std::unordered_set& pendingTxdIDs, + std::unordered_set& modelsToUnload, const std::map& mapRestreamTxdIDs) +{ + while (pSectorEntry) + { + auto* pEntity = reinterpret_cast(pSectorEntry[0]); + if (!pEntity) + { + pSectorEntry = reinterpret_cast(pSectorEntry[1]); + continue; + } + + if (!HasValidEntityVtablePtr(pEntity, bIsStreamSector)) + { + logState.LogInvalidEntity(bIsStreamSector, iSectorIndex, pEntity); + pSectorEntry = reinterpret_cast(pSectorEntry[1]); + continue; + } + + auto* pModelInfo = pGame->GetModelInfo(pEntity->m_nModelIndex); + if (!pModelInfo) + { + pSectorEntry = reinterpret_cast(pSectorEntry[1]); + continue; + } + + unsigned short usTxdID = pModelInfo->GetTextureDictionaryID(); + if (MapContains(mapRestreamTxdIDs, usTxdID)) + { + if (!pEntity->bStreamingDontDelete && !pEntity->bImBeingRendered) + { + DeleteEntityRwObject(pEntity); + processedTxdIDs.insert(usTxdID); + modelsToUnload.insert(pEntity->m_nModelIndex); + } + else + { + pendingTxdIDs.insert(usTxdID); + } + } + + pSectorEntry = reinterpret_cast(pSectorEntry[1]); + } } void CModelInfoSA::StaticFlushPendingRestreamIPL() { if (ms_RestreamTxdIDMap.empty()) return; + // This function restreams all instances of the model *that are from the default SA world (ipl)*. // In other words, it does not affect elements created by MTA. // It's mostly a reimplementation of SA's DeleteAllRwObjects, except that it filters by model ID. - ((void (*)())FUNC_FlushRequestList)(); + reinterpret_cast(FUNC_FlushRequestList)(); + + std::unordered_set processedTxdIDs; + std::unordered_set pendingTxdIDs; + + // Models to unload - includes processed entities, timed-out, and unprocessed TXD models + std::unordered_set modelsToUnload; - std::set removedModels; + // Sector array constants + constexpr int kStreamSectorCount = 2 * NUM_StreamSectorRows * NUM_StreamSectorCols; + constexpr int kRepeatSectorCount = NUM_StreamRepeatSectorRows * NUM_StreamRepeatSectorCols; + constexpr int kRepeatSectorStride = 3; // StreamRepeatSectors uses stride of 3, we access element [2] - for (int i = 0; i < 2 * NUM_StreamSectorRows * NUM_StreamSectorCols; i++) + SRestreamLogState logState; + + // Process StreamSectors (skip null entries for efficiency) + for (int i = 0; i < kStreamSectorCount; i++) { - DWORD* pSectorEntry = ((DWORD**)ARRAY_StreamSectors)[i]; - while (pSectorEntry) - { - CEntitySAInterface* pEntity = (CEntitySAInterface*)pSectorEntry[0]; + auto* pSectorEntry = reinterpret_cast(reinterpret_cast(ARRAY_StreamSectors)[i]); + if (pSectorEntry) + ProcessRestreamSectorList(pSectorEntry, true, i, logState, processedTxdIDs, pendingTxdIDs, modelsToUnload, ms_RestreamTxdIDMap); + } - // Possible bug - pEntity seems to be invalid here occasionally - constexpr auto CEntity_DeleteRwObject_VTBL_OFFSET = 8; - if (static_cast(pEntity->GetVTBL())[CEntity_DeleteRwObject_VTBL_OFFSET] != 0x00534030) - { - // Log info - OutputDebugString(SString("Entity 0x%08x (with model %d) at ARRAY_StreamSectors[%d,%d] is invalid\n", pEntity, pEntity->m_nModelIndex, - i / 2 % NUM_StreamSectorRows, i / 2 / NUM_StreamSectorCols)); - // Assert in debug - #if MTA_DEBUG - assert(static_cast(pEntity->GetVTBL())[CEntity_DeleteRwObject_VTBL_OFFSET] != 0x00534030); - #endif - pSectorEntry = (DWORD*)pSectorEntry[1]; - continue; - } + // Process StreamRepeatSectors (skip null entries for efficiency) + for (int i = 0; i < kRepeatSectorCount; i++) + { + auto* pSectorEntry = reinterpret_cast(reinterpret_cast(ARRAY_StreamRepeatSectors)[kRepeatSectorStride * i + 2]); + if (pSectorEntry) + ProcessRestreamSectorList(pSectorEntry, false, i, logState, processedTxdIDs, pendingTxdIDs, modelsToUnload, ms_RestreamTxdIDMap); + } - if (MapContains(ms_RestreamTxdIDMap, pGame->GetModelInfo(pEntity->m_nModelIndex)->GetTextureDictionaryID())) - { - if (!pEntity->bStreamingDontDelete && !pEntity->bImBeingRendered) - { - _asm - { - mov ecx, pEntity - mov eax, [ecx] - call dword ptr [eax+20h] - } - removedModels.insert(pEntity->m_nModelIndex); - } - } + // Determine which TXD IDs had no entities found at all (buildings not yet streamed in) + std::unordered_set unprocessedTxdIDs; + for (const auto& entry : ms_RestreamTxdIDMap) + { + if (!processedTxdIDs.count(entry.first) && !pendingTxdIDs.count(entry.first)) + unprocessedTxdIDs.insert(entry.first); + } + + // Only remove fully processed TXD IDs from the map + // Keep: pendingTxdIDs (entities being rendered) + unprocessedTxdIDs (no entities found yet) + for (auto txdID : processedTxdIDs) + { + if (!pendingTxdIDs.count(txdID)) + ms_RestreamTxdIDMap.erase(txdID); + } - pSectorEntry = (DWORD*)pSectorEntry[1]; + // Increment retry counter ONLY for pending TXD IDs (entities being rendered) + // Don't increment for: unprocessed (will be erased below) + // Note: processedTxdIDs that are also in pendingTxdIDs stay in map and need counter incremented + constexpr int kMaxRetryFrames = 300; // ~5 seconds at 60fps + std::unordered_set timedOutTxdIDs; + for (auto it = ms_RestreamTxdIDMap.begin(); it != ms_RestreamTxdIDMap.end();) + { + // Skip if unprocessed - those will be erased below after model unload attempt + if (unprocessedTxdIDs.count(it->first)) + { + ++it; + continue; } + + it->second++; // Increment retry counter for pending TXD IDs + if (it->second > kMaxRetryFrames) + { + // Timed out - entity was always being rendered. Force unload the models. + timedOutTxdIDs.insert(it->first); + it = ms_RestreamTxdIDMap.erase(it); + } + else { + ++it; +} } - for (int i = 0; i < NUM_StreamRepeatSectorRows * NUM_StreamRepeatSectorCols; i++) + // Force unload models for timed-out TXD IDs (entities that were always being rendered) + // This is needed because we can't delete RwObject while entity is being rendered, + // but we still need to refresh the textures eventually. + if (!timedOutTxdIDs.empty()) { - DWORD* pSectorEntry = ((DWORD**)ARRAY_StreamRepeatSectors)[3 * i + 2]; - while (pSectorEntry) + const auto maxModelId = static_cast(pGame->GetBaseIDforTXD()); + + for (DWORD modelId = 612; modelId < 1000; modelId++) { - CEntitySAInterface* pEntity = (CEntitySAInterface*)pSectorEntry[0]; - if (MapContains(ms_RestreamTxdIDMap, pGame->GetModelInfo(pEntity->m_nModelIndex)->GetTextureDictionaryID())) - { - if (!pEntity->bStreamingDontDelete && !pEntity->bImBeingRendered) - { - _asm - { - mov ecx, pEntity - mov eax, [ecx] - call dword ptr [eax+20h] - } - removedModels.insert(pEntity->m_nModelIndex); - } - } - pSectorEntry = (DWORD*)pSectorEntry[1]; + auto* pModelInfo = pGame->GetModelInfo(modelId); + if (!pModelInfo) + continue; + auto txdId = pModelInfo->GetTextureDictionaryID(); + if (txdId != 0 && timedOutTxdIDs.count(txdId)) + modelsToUnload.insert(static_cast(modelId)); + } + + for (DWORD modelId = 1194; modelId < maxModelId; modelId++) + { + auto* pModelInfo = pGame->GetModelInfo(modelId); + if (!pModelInfo) + continue; + auto txdId = pModelInfo->GetTextureDictionaryID(); + if (txdId != 0 && timedOutTxdIDs.count(txdId)) + modelsToUnload.insert(static_cast(modelId)); } } - ms_RestreamTxdIDMap.clear(); + // For unprocessed TXD IDs (no entities visible), try to unload the actual models + // This handles the cases where models are loaded with old textures but not yet streamed as entities + if (!unprocessedTxdIDs.empty()) + { + const auto maxModelId = static_cast(pGame->GetBaseIDforTXD()); + + auto tryQueueModelUnload = [&](DWORD modelId) + { + auto* pStreamingInfo = pGame->GetStreaming()->GetStreamingInfo(modelId); + if (!pStreamingInfo || pStreamingInfo->loadState == eModelLoadState::LOADSTATE_NOT_LOADED) + return; + + auto* pModelInfo = pGame->GetModelInfo(modelId); + if (!pModelInfo) + return; - std::set::iterator it; - for (it = removedModels.begin(); it != removedModels.end(); it++) + auto modelTxdId = pModelInfo->GetTextureDictionaryID(); + if (modelTxdId == 0 || !unprocessedTxdIDs.count(modelTxdId)) + return; + + auto* pInterface = pModelInfo->GetInterface(); + if (pInterface && pInterface->usNumberOfRefs == 0) + modelsToUnload.insert(static_cast(modelId)); + }; + + // Building model ranges matching RestreamIPL filter: > 611 && (< 1000 || > 1193) + for (DWORD modelId = 612; modelId < 1000; modelId++) + tryQueueModelUnload(modelId); + + for (DWORD modelId = 1194; modelId < maxModelId; modelId++) + tryQueueModelUnload(modelId); + + // Clear unprocessed TXD IDs - we've done what we can + for (auto txdID : unprocessedTxdIDs) + ms_RestreamTxdIDMap.erase(txdID); + } + + // Unload models to force texture re-binding on reload + for (auto modelId : modelsToUnload) { - pGame->GetStreaming()->RemoveModel(*it); - pGame->GetStreaming()->GetStreamingInfo(*it)->loadState = eModelLoadState::LOADSTATE_NOT_LOADED; + pGame->GetStreaming()->RemoveModel(modelId); + CStreamingInfo* pStreamingInfo = pGame->GetStreaming()->GetStreamingInfo(modelId); + if (pStreamingInfo) + pStreamingInfo->loadState = eModelLoadState::LOADSTATE_NOT_LOADED; } } @@ -1084,15 +1678,52 @@ void CModelInfoSA::ModelAddRef(EModelRequestType requestType, const char* szTag) if (IsLoaded()) { m_pInterface = ppModelInfo[m_dwModelID]; - m_pInterface->usNumberOfRefs++; + if (IsValidModelInfoPtr(m_pInterface)) + { + m_pInterface->usNumberOfRefs++; + CTxdStore_AddRef(m_pInterface->usTextureDictionary); + } + else { + m_pInterface = nullptr; +} } - else - m_dwPendingInterfaceRef = 1; + else { + m +}_dwPendingInterfaceRef = 1; } m_dwReferences++; } +void CModelInfoSA::ModelAddRefNonBlocking(const char* szTag) +{ + ModelAddRef(NON_BLOCKING, szTag); +} + +bool CModelInfoSA::TryAddRefIfLoaded() +{ + if (!IsLoaded()) + return false; + + if (m_dwReferences == 0) + { + assert(!m_dwPendingInterfaceRef); + + m_pInterface = ppModelInfo[m_dwModelID]; + if (!IsValidModelInfoPtr(m_pInterface)) + { + m_pInterface = nullptr; + return false; + } + + m_pInterface->usNumberOfRefs++; + CTxdStore_AddRef(m_pInterface->usTextureDictionary); + } + + m_dwReferences++; + return true; +} + int CModelInfoSA::GetRefCount() { return static_cast(m_dwReferences); @@ -1114,15 +1745,12 @@ void CModelInfoSA::RemoveRef(bool bRemoveExtraGTARef) if (bRemoveExtraGTARef) { // Remove ref added by GTA. - if (m_pInterface->usNumberOfRefs > 1) + CBaseModelInfoSAInterface* pInterface = GetInterface(); + if (pInterface && pInterface->usNumberOfRefs > 1) { - DWORD dwFunction = FUNC_RemoveRef; - CBaseModelInfoSAInterface* pInterface = m_pInterface; - _asm - { - mov ecx, pInterface - call dwFunction - } + DWORD dwFunction = FUNC_RemoveRef; + using func_t = void (__thiscall*)(decltype(pInterface) ); + reinterpret_cast(dwFunction)(pInterface); } } @@ -1136,7 +1764,7 @@ void CModelInfoSA::RemoveRef(bool bRemoveExtraGTARef) void CModelInfoSA::SetAlphaTransparencyEnabled(bool bEnabled) { - m_pInterface = ppModelInfo[m_dwModelID]; + m_pInterface = GetInterface(); if (m_pInterface) { if (!MapContains(ms_ModelDefaultAlphaTransparencyMap, m_dwModelID)) @@ -1149,31 +1777,29 @@ void CModelInfoSA::SetAlphaTransparencyEnabled(bool bEnabled) bool CModelInfoSA::IsAlphaTransparencyEnabled() { - m_pInterface = ppModelInfo[m_dwModelID]; - if (m_pInterface) - { - return m_pInterface->bAlphaTransparency; - } - return false; + CBaseModelInfoSAInterface* pInterface = GetInterface(); + return pInterface ? pInterface->bAlphaTransparency : false; } void CModelInfoSA::StaticResetAlphaTransparencies() { - for (std::map::const_iterator iter = ms_ModelDefaultAlphaTransparencyMap.begin(); iter != ms_ModelDefaultAlphaTransparencyMap.end(); iter++) + for (auto iter = ms_ModelDefaultAlphaTransparencyMap.begin(); iter != ms_ModelDefaultAlphaTransparencyMap.end();) { CBaseModelInfoSAInterface* pInterface = ppModelInfo[iter->first]; - if (pInterface) + if (!IsValidModelInfoPtr(pInterface)) { - pInterface->bAlphaTransparency = iter->second; + iter = ms_ModelDefaultAlphaTransparencyMap.erase(iter); + continue; } - } - ms_ModelDefaultAlphaTransparencyMap.clear(); + pInterface->bAlphaTransparency = iter->second; + iter = ms_ModelDefaultAlphaTransparencyMap.erase(iter); + } } void CModelInfoSA::ResetAlphaTransparency() { - m_pInterface = ppModelInfo[m_dwModelID]; + m_pInterface = GetInterface(); if (m_pInterface) { BYTE* pbEnabled = MapFind(ms_ModelDefaultAlphaTransparencyMap, m_dwModelID); @@ -1191,7 +1817,8 @@ short CModelInfoSA::GetAvailableVehicleMod(unsigned short usUpgrade) if (usUpgrade >= 1000 && usUpgrade <= 1193) { DWORD ModelID = m_dwModelID; - _asm + // clang-format off + __asm { mov eax, ModelID @@ -1205,6 +1832,7 @@ short CModelInfoSA::GetAvailableVehicleMod(unsigned short usUpgrade) mov ax, [eax+edx*2+0x2D6] mov sreturn, ax } + // clang-format on } return sreturn; } @@ -1213,7 +1841,8 @@ bool CModelInfoSA::IsUpgradeAvailable(eVehicleUpgradePosn posn) { bool bRet = false; DWORD ModelID = m_dwModelID; - _asm + // clang-format off + __asm { mov eax, ModelID mov ecx, dword ptr[ARRAY_ModelInfo] @@ -1232,6 +1861,7 @@ bool CModelInfoSA::IsUpgradeAvailable(eVehicleUpgradePosn posn) mov bRet, al } + // clang-format on return bRet; } @@ -1239,7 +1869,8 @@ void CModelInfoSA::SetCustomCarPlateText(const char* szText) { char* szStoredText; DWORD ModelID = m_dwModelID; - _asm + // clang-format off + __asm { push ecx mov ecx, ModelID @@ -1253,9 +1884,10 @@ void CModelInfoSA::SetCustomCarPlateText(const char* szText) mov szStoredText, ecx pop ecx } + // clang-format on if (szText) strncpy(szStoredText, szText, 8); - else szStoredText[0] = 0; + else szStoredText[0] = '\0'; } unsigned int CModelInfoSA::GetNumRemaps() @@ -1263,7 +1895,8 @@ unsigned int CModelInfoSA::GetNumRemaps() DWORD dwFunc = FUNC_CVehicleModelInfo__GetNumRemaps; DWORD ModelID = m_dwModelID; unsigned int uiReturn = 0; - _asm + // clang-format off + __asm { mov ecx, ModelID @@ -1275,20 +1908,112 @@ unsigned int CModelInfoSA::GetNumRemaps() call dwFunc mov uiReturn, eax } + // clang-format on return uiReturn; } void* CModelInfoSA::GetVehicleSuspensionData() { - return GetInterface()->pColModel->m_data->m_suspensionLines; + CBaseModelInfoSAInterface* pInterface = GetInterface(); + if (!pInterface) + { + Request(BLOCKING, "GetVehicleSuspensionData"); + pInterface = GetInterface(); + if (!pInterface) + return nullptr; + } + + CColModelSAInterface* pColModel = pInterface->pColModel; + if (!pColModel) + return nullptr; + + CColDataSA* pColData = nullptr; + if (!SafeReadColData(pColModel, &pColData)) + { + AddReportLog(5554, SString("GetVehicleSuspensionData: ColData read failed for model %u", m_dwModelID), 10); + return nullptr; + } + + if (!pColData) + { + unsigned short slot; + if (!SafeReadColSlot(pColModel, &slot)) + { + AddReportLog(5554, SString("GetVehicleSuspensionData: ColSlot read failed for model %u", m_dwModelID), 10); + return nullptr; + } + const DWORD colId = static_cast(RESOURCE_ID_COL + slot); + pGame->GetStreaming()->RequestModel(colId, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(true, "GetVehicleSuspensionData"); + + if (!SafeReadColData(pColModel, &pColData)) + { + AddReportLog(5554, SString("GetVehicleSuspensionData: ColData read failed post-load for model %u", m_dwModelID), 10); + return nullptr; + } + if (!pColData) + return nullptr; + } + + void* pLines = nullptr; + if (!SafeReadSuspLines(pColData, &pLines)) + { + AddReportLog(5554, SString("GetVehicleSuspensionData: SuspLines read failed for model %u", m_dwModelID), 10); + return nullptr; + } + return pLines; } void* CModelInfoSA::SetVehicleSuspensionData(void* pSuspensionLines) { - CColDataSA* pColData = GetInterface()->pColModel->m_data; - void* pOrigSuspensionLines = pColData->m_suspensionLines; - pColData->m_suspensionLines = reinterpret_cast(pSuspensionLines); - return pOrigSuspensionLines; + CBaseModelInfoSAInterface* pInterface = GetInterface(); + if (!pInterface) + { + Request(BLOCKING, "SetVehicleSuspensionData"); + pInterface = GetInterface(); + if (!pInterface) + return nullptr; + } + + CColModelSAInterface* pColModel = pInterface->pColModel; + if (!pColModel) + return nullptr; + + CColDataSA* pColData = nullptr; + if (!SafeReadColData(pColModel, &pColData)) + { + AddReportLog(5555, SString("SetVehicleSuspensionData: ColData read failed for model %u", m_dwModelID), 10); + return nullptr; + } + + if (!pColData) + { + unsigned short slot; + if (!SafeReadColSlot(pColModel, &slot)) + { + AddReportLog(5555, SString("SetVehicleSuspensionData: ColSlot read failed for model %u", m_dwModelID), 10); + return nullptr; + } + const DWORD colId = static_cast(RESOURCE_ID_COL + slot); + pGame->GetStreaming()->RequestModel(colId, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(true, "SetVehicleSuspensionData"); + + if (!SafeReadColData(pColModel, &pColData)) + { + AddReportLog(5555, SString("SetVehicleSuspensionData: ColData read failed post-load for model %u", m_dwModelID), 10); + return nullptr; + } + if (!pColData) + return nullptr; + } + + void* pOld = nullptr; + if (!SafeSwapSuspLines(pColData, pSuspensionLines, &pOld)) + { + AddReportLog(5555, SString("SetVehicleSuspensionData: SuspLines swap failed for model %u", m_dwModelID), 10); + return nullptr; + } + return pOld; } CVector CModelInfoSA::GetVehicleExhaustFumesPosition() @@ -1306,7 +2031,11 @@ bool CModelInfoSA::GetVehicleDummyPositions(std::array(m_pInterface)->pVisualInfo->vecDummies; + auto pVehicleModel = reinterpret_cast(ppModelInfo[m_dwModelID]); + if (!IsValidModelInfoPtr(pVehicleModel) || !pVehicleModel->pVisualInfo) + return false; + + CVector* dummyPositions = pVehicleModel->pVisualInfo->vecDummies; std::copy(dummyPositions, dummyPositions + positions.size(), positions.begin()); return true; } @@ -1330,7 +2059,12 @@ CVector CModelInfoSA::GetVehicleDummyDefaultPosition(VehicleDummies eDummy) ModelAddRef(BLOCKING, "GetVehicleDummyDefaultPosition"); - auto modelInfo = reinterpret_cast(GetInterface()); + auto modelInfo = reinterpret_cast(GetInterface()); + if (!modelInfo || !modelInfo->pVisualInfo) + { + RemoveRef(); + return CVector(); + } CVector vec = modelInfo->pVisualInfo->vecDummies[(std::size_t)eDummy]; RemoveRef(); @@ -1347,7 +2081,10 @@ CVector CModelInfoSA::GetVehicleDummyPosition(VehicleDummies eDummy) if (!IsLoaded()) Request(BLOCKING, "GetVehicleDummyPosition"); - auto pVehicleModel = reinterpret_cast(m_pInterface); + auto* pVehicleModel = static_cast(GetInterface()); + if (!pVehicleModel || !pVehicleModel->pVisualInfo) + return CVector(); + return pVehicleModel->pVisualInfo->vecDummies[(std::size_t)eDummy]; } @@ -1360,16 +2097,20 @@ void CModelInfoSA::SetVehicleDummyPosition(VehicleDummies eDummy, const CVector& if (!IsLoaded()) Request(BLOCKING, "SetVehicleDummyPosition"); + auto* pVehicleModel = static_cast(GetInterface()); + if (!pVehicleModel || !pVehicleModel->pVisualInfo) + return; + // Store default position in map auto iter = ms_ModelDefaultDummiesPosition.find(m_dwModelID); if (iter == ms_ModelDefaultDummiesPosition.end()) { ms_ModelDefaultDummiesPosition.insert({m_dwModelID, std::map()}); // Increment this model references count, so we don't unload it before we have a chance to reset the positions - m_pInterface->usNumberOfRefs++; + pVehicleModel->usNumberOfRefs++; + CTxdStore_AddRef(pVehicleModel->usTextureDictionary); } - auto pVehicleModel = reinterpret_cast(m_pInterface); if (ms_ModelDefaultDummiesPosition[m_dwModelID].find(eDummy) == ms_ModelDefaultDummiesPosition[m_dwModelID].end()) { ms_ModelDefaultDummiesPosition[m_dwModelID][eDummy] = pVehicleModel->pVisualInfo->vecDummies[(std::size_t)eDummy]; @@ -1386,32 +2127,90 @@ void CModelInfoSA::ResetVehicleDummies(bool bRemoveFromDummiesMap) auto iter = ms_ModelDefaultDummiesPosition.find(m_dwModelID); if (iter == ms_ModelDefaultDummiesPosition.end()) - return; // Early out in case the model doesn't have any dummies modified + return; // Early out in case the model doesn't have any dummies modified - auto pVehicleModel = reinterpret_cast(m_pInterface); - for (const auto& dummy : ms_ModelDefaultDummiesPosition[m_dwModelID]) + auto* pVehicleModel = static_cast(GetInterface()); + if (!pVehicleModel || !pVehicleModel->pVisualInfo) { - if (pVehicleModel->pVisualInfo != nullptr) - pVehicleModel->pVisualInfo->vecDummies[static_cast(dummy.first)] = dummy.second; + Request(BLOCKING, "ResetVehicleDummies"); + pVehicleModel = static_cast(GetInterface()); + if (!pVehicleModel || !pVehicleModel->pVisualInfo) + { + if (pVehicleModel && pVehicleModel->usNumberOfRefs > 0) + { + if (pGame && !pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(pVehicleModel->usTextureDictionary) && + CTxdStore_GetTxd(pVehicleModel->usTextureDictionary) != nullptr) + CTxdStore_RemoveRef(pVehicleModel->usTextureDictionary); + pVehicleModel->usNumberOfRefs--; + } + if (bRemoveFromDummiesMap) + ms_ModelDefaultDummiesPosition.erase(iter); + return; + } + } + + for (const auto& dummy : iter->second) + { + pVehicleModel->pVisualInfo->vecDummies[static_cast(dummy.first)] = dummy.second; + } + + if (pVehicleModel->usNumberOfRefs > 0) + { + if (pGame && !pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(pVehicleModel->usTextureDictionary) && + CTxdStore_GetTxd(pVehicleModel->usTextureDictionary) != nullptr) + CTxdStore_RemoveRef(pVehicleModel->usTextureDictionary); + pVehicleModel->usNumberOfRefs--; } - // Decrement reference counter, since we reverted all position changes, the model can be safely unloaded - pVehicleModel->usNumberOfRefs--; if (bRemoveFromDummiesMap) - ms_ModelDefaultDummiesPosition.erase(m_dwModelID); + ms_ModelDefaultDummiesPosition.erase(iter); } void CModelInfoSA::ResetAllVehicleDummies() { CGame* game = g_pCore->GetGame(); - for (auto& info : ms_ModelDefaultDummiesPosition) + for (auto it = ms_ModelDefaultDummiesPosition.begin(); it != ms_ModelDefaultDummiesPosition.end();) { - CModelInfo* modelInfo = game->GetModelInfo(info.first); - if (modelInfo) - modelInfo->ResetVehicleDummies(false); - } + CModelInfo* modelInfo = game->GetModelInfo(it->first); + if (!modelInfo || !modelInfo->IsVehicle()) + { + it = ms_ModelDefaultDummiesPosition.erase(it); + continue; + } + + auto* pModelInfoSA = static_cast(modelInfo); + auto* pVehicleModel = static_cast(pModelInfoSA->GetInterface()); + if (!pVehicleModel || !pVehicleModel->pVisualInfo) + { + pModelInfoSA->Request(BLOCKING, "ResetAllVehicleDummies"); + pVehicleModel = static_cast(pModelInfoSA->GetInterface()); + if (!pVehicleModel || !pVehicleModel->pVisualInfo) + { + if (pVehicleModel && pVehicleModel->usNumberOfRefs > 0) + { + if (pGame && !pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(pVehicleModel->usTextureDictionary) && + CTxdStore_GetTxd(pVehicleModel->usTextureDictionary) != nullptr) + CTxdStore_RemoveRef(pVehicleModel->usTextureDictionary); + pVehicleModel->usNumberOfRefs--; + } + it = ms_ModelDefaultDummiesPosition.erase(it); + continue; + } + } - ms_ModelDefaultDummiesPosition.clear(); + for (const auto& dummy : it->second) + pVehicleModel->pVisualInfo->vecDummies[static_cast(dummy.first)] = dummy.second; + + if (pVehicleModel->usNumberOfRefs > 0) + { + if (pGame && !pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(pVehicleModel->usTextureDictionary) && + CTxdStore_GetTxd(pVehicleModel->usTextureDictionary) != nullptr) + CTxdStore_RemoveRef(pVehicleModel->usTextureDictionary); + pVehicleModel->usNumberOfRefs--; + } + + it = ms_ModelDefaultDummiesPosition.erase(it); + } } float CModelInfoSA::GetVehicleWheelSize(ResizableVehicleWheelGroup eWheelGroup) @@ -1419,16 +2218,19 @@ float CModelInfoSA::GetVehicleWheelSize(ResizableVehicleWheelGroup eWheelGroup) if (!IsVehicle()) return 0.0f; - auto pVehicleModel = reinterpret_cast(GetInterface()); + auto* pVehicleModel = static_cast(GetInterface()); + if (!pVehicleModel) + return 0.0f; + switch (eWheelGroup) { case ResizableVehicleWheelGroup::FRONT_AXLE: return pVehicleModel->fWheelSizeFront; case ResizableVehicleWheelGroup::REAR_AXLE: return pVehicleModel->fWheelSizeRear; + default: + return 0.0f; } - - return 0.0f; } void CModelInfoSA::SetVehicleWheelSize(ResizableVehicleWheelGroup eWheelGroup, float fWheelSize) @@ -1436,9 +2238,10 @@ void CModelInfoSA::SetVehicleWheelSize(ResizableVehicleWheelGroup eWheelGroup, f if (!IsVehicle()) return; - auto pVehicleModel = reinterpret_cast(GetInterface()); + auto* pVehicleModel = static_cast(GetInterface()); + if (!pVehicleModel) + return; - // Store default wheel sizes in map if (!MapFind(ms_VehicleModelDefaultWheelSizes, m_dwModelID)) MapSet(ms_VehicleModelDefaultWheelSizes, m_dwModelID, std::make_pair(pVehicleModel->fWheelSizeFront, pVehicleModel->fWheelSizeRear)); @@ -1462,39 +2265,46 @@ void CModelInfoSA::ResetVehicleWheelSizes(std::pair* defaultSizes) if (!IsVehicle()) return; - std::pair* sizesPair; - if (!defaultSizes) - { - sizesPair = MapFind(ms_VehicleModelDefaultWheelSizes, m_dwModelID); - MapRemove(ms_VehicleModelDefaultWheelSizes, m_dwModelID); - } - else - { - sizesPair = defaultSizes; - } + std::pair* sizesPair = defaultSizes ? defaultSizes : MapFind(ms_VehicleModelDefaultWheelSizes, m_dwModelID); - // Default values not found in map if (!sizesPair) return; - auto pVehicleModel = reinterpret_cast(m_pInterface); + auto* pVehicleModel = static_cast(GetInterface()); + if (!pVehicleModel) + return; + pVehicleModel->fWheelSizeFront = sizesPair->first; pVehicleModel->fWheelSizeRear = sizesPair->second; + + if (!defaultSizes) + MapRemove(ms_VehicleModelDefaultWheelSizes, m_dwModelID); } void CModelInfoSA::ResetAllVehiclesWheelSizes() { CGame* game = g_pCore->GetGame(); - for (auto& info : ms_VehicleModelDefaultWheelSizes) + for (auto it = ms_VehicleModelDefaultWheelSizes.begin(); it != ms_VehicleModelDefaultWheelSizes.end();) { - CModelInfo* modelInfo = game->GetModelInfo(info.first); - if (modelInfo) + CModelInfo* modelInfo = game->GetModelInfo(it->first); + if (!modelInfo || !modelInfo->IsVehicle()) { - modelInfo->ResetVehicleWheelSizes(&info.second); + it = ms_VehicleModelDefaultWheelSizes.erase(it); + continue; + } + + auto* pModelInfoSA = static_cast(modelInfo); + auto* pVehicleModel = static_cast(pModelInfoSA->GetInterface()); + if (!pVehicleModel) + { + it = ms_VehicleModelDefaultWheelSizes.erase(it); + continue; } - } - ms_VehicleModelDefaultWheelSizes.clear(); + pVehicleModel->fWheelSizeFront = it->second.first; + pVehicleModel->fWheelSizeRear = it->second.second; + it = ms_VehicleModelDefaultWheelSizes.erase(it); + } } bool CModelInfoSA::SetCustomModel(RpClump* pClump) @@ -1520,6 +2330,7 @@ bool CModelInfoSA::SetCustomModel(RpClump* pClump) success = pGame->GetRenderWare()->ReplaceWeaponModel(pClump, static_cast(m_dwModelID)); break; case eModelInfoType::VEHICLE: + // ReplaceVehicleModele handles collision preservation internally success = pGame->GetRenderWare()->ReplaceVehicleModel(pClump, static_cast(m_dwModelID)); break; case eModelInfoType::ATOMIC: @@ -1527,33 +2338,109 @@ bool CModelInfoSA::SetCustomModel(RpClump* pClump) case eModelInfoType::TIME: success = pGame->GetRenderWare()->ReplaceAllAtomicsInModel(pClump, static_cast(m_dwModelID)); break; + case eModelInfoType::CLUMP: + success = pGame->GetRenderWare()->ReplaceClumpModel(pClump, static_cast(m_dwModelID)); + break; + case eModelInfoType::UNKNOWN: + // Weapon models (321-372) may return UNKNOWN type during streaming. Using ReplaceAllAtomicsInModel + // for weapons would skip CWeaponModelInfo::SetClump, leaving the frame plugin's m_modelInfo NULL, + // which crashes in CVisibilityPlugins::RenderWeaponCB due to nullptr deref. + if (m_dwModelID >= 321 && m_dwModelID <= 372) { + success = pGame->GetRenderWare()->ReplaceWeaponModel(pClump, static_cast(m_dwModelID)); + } else { + success = pGame->GetRenderWare()->ReplaceAllAtomicsInModel(pClump, static_cast(m_dwModelID)); +} + break; default: + AddReportLog(8634, SString("SetCustomModel: Unhandled model type %d for model %u", static_cast(GetModelType()), + static_cast(m_dwModelID))); break; } - m_pCustomClump = success ? pClump : nullptr; + if (success) + { + m_pCustomClump = pClump; + + // Rebind texture pointers in the GAME's clump to current TXD textures. + // ReplaceModel clones the input clump, so we must rebind the ACTUAL clump the game is using. + // This is needed because the TXD may contain replacement textures (via engineImportTXD), + // but the DFF's materials still point to old/original textures from when it was loaded. + // Without this fix, shader texture replacement fails on custom DFF models. + eModelInfoType modelType = GetModelType(); + switch (modelType) + { + case eModelInfoType::PED: + case eModelInfoType::WEAPON: + case eModelInfoType::VEHICLE: + case eModelInfoType::CLUMP: + case eModelInfoType::UNKNOWN: + { + RpClump* pGameClump = reinterpret_cast(GetRwObject()); + if (pGameClump && pGame) + { + CRenderWare* pRenderWare = pGame->GetRenderWare(); + if (pRenderWare) + pRenderWare->RebindClumpTexturesToTxd(pGameClump, GetTextureDictionaryID()); + } + break; + } + case eModelInfoType::ATOMIC: + case eModelInfoType::LOD_ATOMIC: + case eModelInfoType::TIME: + { + RpAtomic* pAtomic = reinterpret_cast(GetRwObject()); + if (pAtomic && pGame) + { + CRenderWare* pRenderWare = pGame->GetRenderWare(); + if (pRenderWare) + pRenderWare->RebindAtomicTexturesToTxd(pAtomic, GetTextureDictionaryID()); + } + break; + } + default: + break; + } + } + else + { + m_pCustomClump = nullptr; + } + return success; } void CModelInfoSA::RestoreOriginalModel() { - // Are we loaded? if (IsLoaded()) { - pGame->GetStreaming()->RemoveModel(m_dwModelID); + CBaseModelInfoSAInterface* pInterface = GetInterface(); + // SA's streaming GC (DeleteLeastUsedEntityRwObject, 0x409640) never removes + // models with active refs. Removing with refs > 0 causes TXD ref mismatches + // when entities eventually detach, because m_wTxdIndex may have changed. + if (pInterface && pInterface->usNumberOfRefs == 0) + pGame->GetStreaming()->RemoveModel(m_dwModelID); } - // Reset the stored custom vehicle clump - m_pCustomClump = NULL; + m_pCustomClump = nullptr; +} + +void CModelInfoSA::ClearCustomModel() +{ + m_pCustomClump = nullptr; } void CModelInfoSA::SetColModel(CColModel* pColModel) { + if (!pColModel) + return; + // Grab the interfaces CColModelSAInterface* pColModelInterface = pColModel->GetInterface(); + if (!pColModelInterface) + return; - // Skip setting if already done - if (m_pCustomColModel == pColModel) + m_pInterface = ppModelInfo[m_dwModelID]; + if (IsValidModelInfoPtr(m_pInterface) && m_pCustomColModel == pColModel && m_pInterface->pColModel == pColModelInterface) return; // Store the col model we set @@ -1562,29 +2449,41 @@ void CModelInfoSA::SetColModel(CColModel* pColModel) // Do the following only if we're loaded m_pInterface = ppModelInfo[m_dwModelID]; - if (m_pInterface) + if (IsValidModelInfoPtr(m_pInterface)) { - // If no collision model has been set before, store the original in case we want to restore it if (!m_pOriginalColModelInterface) { m_pOriginalColModelInterface = m_pInterface->pColModel; m_originalFlags = GetOriginalFlags(); + if (m_pOriginalColModelInterface) + { + unsigned short slot; + if (!SafeReadColSlot(m_pOriginalColModelInterface, &slot)) + { + AddReportLog(5556, SString("SetColModel: pColModel access failed for model %u", m_dwModelID), 10); + m_pOriginalColModelInterface = nullptr; + } + else + { + m_usColSlot = slot; + } + } } - // Apply some low-level hacks - pColModelInterface->m_sphere.m_collisionSlot = 0xA9; + // Set collision slot to 0 (the "generic" slot) for custom collision models. + // Slot 0 is always allocated in CColStore::Initialise(). Using an unallocated + // slot ID (like the previous 0xA9) causes CColStore::AddRef to access garbage + // memory since native GTA doesn't validate slot existence before pool indexing. + pColModelInterface->m_sphere.m_collisionSlot = 0; CBaseModelInfo_SetColModel(m_pInterface, pColModelInterface, true); CColAccel_addCacheCol(m_dwModelID, pColModelInterface); - // SetColModel sets bDoWeOwnTheColModel if the last parameter is truthy m_pInterface->bDoWeOwnTheColModel = false; m_pInterface->bIsColLoaded = false; - // Fix random foliage on custom collisions by calling CPlantMgr::SetPlantFriendlyFlagInAtomicMI (reinterpret_cast(0x5DB650))(m_pInterface); - // Set some lighting for this collision if not already present CColDataSA* pColData = pColModelInterface->m_data; if (pColData) @@ -1605,7 +2504,23 @@ void CModelInfoSA::SetColModel(CColModel* pColModel) void CModelInfoSA::RestoreColModel() { + if (!m_pOriginalColModelInterface || !m_pCustomColModel) + { + m_pCustomColModel = nullptr; + m_pOriginalColModelInterface = nullptr; + m_originalFlags = 0; + return; + } + m_pInterface = ppModelInfo[m_dwModelID]; + if (!IsValidModelInfoPtr(m_pInterface)) + { + m_pInterface = nullptr; + m_pCustomColModel = nullptr; + m_pOriginalColModelInterface = nullptr; + m_originalFlags = 0; + return; + } // Restore original collision model and flags if (m_pInterface && m_pOriginalColModelInterface && m_pCustomColModel) @@ -1615,15 +2530,25 @@ void CModelInfoSA::RestoreColModel() m_pInterface->usFlags = m_originalFlags; - // Force the game to load the original collision model data, if we applied a custom collision model before - // there was any object/building, which would've provoked CColStore to request it. - if (!m_pInterface->pColModel->m_data && m_dwReferences > 1) + CColDataSA* pColData = nullptr; + unsigned short slot = 0xFFFF; + if (m_pInterface->pColModel) { - pGame->GetStreaming()->RemoveModel(RESOURCE_ID_COL + m_pInterface->pColModel->m_sphere.m_collisionSlot); + if (!SafeReadColData(m_pInterface->pColModel, &pColData)) + { + AddReportLog(5559, SString("RestoreColModel: ColData read failed for model %u", m_dwModelID), 10); + } + else if (!pColData && m_dwReferences > 1) + { + if (SafeReadColSlot(m_pInterface->pColModel, &slot)) { + pGame->GetStreaming()->RemoveModel(RESOURCE_ID_COL + slot); + } else { + AddReportLog(5559, SString("RestoreColModel: ColSlot read failed for model %u", m_dwModelID), 10); +} + } } } - // We currently have no custom model loaded m_pCustomColModel = nullptr; m_pOriginalColModelInterface = nullptr; m_originalFlags = 0; @@ -1634,7 +2559,23 @@ void CModelInfoSA::MakeCustomModel() // We have a custom model? if (m_pCustomClump) { - SetCustomModel(m_pCustomClump); + // Store and clear m_pCustomClump BEFORE calling SetCustomModel to prevent recursive calls. + // SetCustomModel may trigger LoadAllRequestedModels which can recursively call MakeCustomModel + // on the same model (via the streaming hook) if the custom DFF lacks embedded collision. + RpClump* pClumpToSet = m_pCustomClump; + m_pCustomClump = nullptr; + + if (!SetCustomModel(pClumpToSet)) + { + // SetCustomModel failed, restore the custom clump for retry on next stream-in + m_pCustomClump = pClumpToSet; + } + else + { + // Preserve the custom clump pointer for restream/retry paths + m_pCustomClump = pClumpToSet; + // Note: SetCustomModel now handles RebindClumpTexturesToTxd internally after successful replacement + } } // Custom collision model is not NULL and it's different from the original? @@ -1648,50 +2589,123 @@ void CModelInfoSA::AddColRef() { CColModelSAInterface* originalColModel = nullptr; - // Always increase the reference count for the collision slot of the original collision model, - // to prevent the game logic from deleting the original when we restore it. - if (m_pOriginalColModelInterface && m_pCustomColModel) - { + if (m_pOriginalColModelInterface && m_pCustomColModel) { originalColModel = m_pOriginalColModelInterface; - } - else + } else { - originalColModel = GetInterface()->pColModel; + CBaseModelInfoSAInterface* pInterface = GetInterface(); + if (pInterface) { + originalColModel = pInterface->pColModel; + } else { + AddReportLog(5552, SString("AddColRef called with null/invalid interface for model %u", m_dwModelID), 10); +} } + unsigned short slot = m_usColSlot; if (originalColModel) { - pGame->GetCollisionStore()->AddRef(originalColModel->m_sphere.m_collisionSlot); + unsigned short readSlot; + if (SafeReadColSlot(originalColModel, &readSlot)) + { + slot = readSlot; + m_usColSlot = slot; + } + else + { + AddReportLog(5557, SString("AddColRef: pColModel access failed for model %u", m_dwModelID), 10); + } + } + + if (slot == 0xFFFF || slot > 0xFF) + return; + + if (pGame) + { + auto* pColStore = pGame->GetCollisionStore(); + if (pColStore) + { + // Validate slot exists in pool before calling native AddRef. + // GTA SA's CColStore::AddRef (0x4107A0) doesn't validate slot existence, + // it directly indexes the pool causing crashes on unallocated slots. + const CollisionSlot colSlot = static_cast(slot); + if (pColStore->IsValidSlot(colSlot)) + { + pColStore->AddRef(colSlot); + ++m_colRefCount; + } + } } } void CModelInfoSA::RemoveColRef() { + if (m_colRefCount == 0) + return; + CColModelSAInterface* originalColModel = nullptr; - // Always decrease the reference count for the collision slot of the original collision model, - // to prevent the game logic from deleting the original when we restore it. - if (m_pOriginalColModelInterface && m_pCustomColModel) - { + if (m_pOriginalColModelInterface && m_pCustomColModel) { originalColModel = m_pOriginalColModelInterface; + } else + { + CBaseModelInfoSAInterface* pInterface = GetInterface(); + if (pInterface) + originalColModel = pInterface->pColModel; + } + + unsigned short slot = 0xFFFF; + if (originalColModel) + { + if (!SafeReadColSlot(originalColModel, &slot)) + { + AddReportLog(5558, SString("RemoveColRef: pColModel access failed for model %u", m_dwModelID), 10); + slot = m_usColSlot; + } } else { - originalColModel = GetInterface()->pColModel; + slot = m_usColSlot; } - if (originalColModel) + if (slot == 0xFFFF || slot > 0xFF) + return; + + if (!pGame) + return; + + auto* pColStore = pGame->GetCollisionStore(); + if (!pColStore) + return; + + // Validate slot exists in pool before calling native RemoveRef. + // GTA SA's CColStore::RemoveRef (0x4107D0) doesn't validate slot existence. + const CollisionSlot colSlot = static_cast(slot); + if (pColStore->IsValidSlot(colSlot)) { - pGame->GetCollisionStore()->RemoveRef(originalColModel->m_sphere.m_collisionSlot); + pColStore->RemoveRef(colSlot); + if (m_colRefCount > 0) + --m_colRefCount; } + if (m_colRefCount == 0) + m_usColSlot = 0xFFFF; } void CModelInfoSA::GetVoice(short* psVoiceType, short* psVoiceID) { + CPedModelInfoSAInterface* pInterface = GetPedModelInfoInterface(); + if (!pInterface) + { + if (psVoiceType) + *psVoiceType = 0; + if (psVoiceID) + *psVoiceID = 0; + return; + } + if (psVoiceType) - *psVoiceType = GetPedModelInfoInterface()->sVoiceType; + *psVoiceType = pInterface->sVoiceType; if (psVoiceID) - *psVoiceID = GetPedModelInfoInterface()->sFirstVoice; + *psVoiceID = pInterface->sFirstVoice; } void CModelInfoSA::GetVoice(const char** pszVoiceType, const char** pszVoice) @@ -1706,10 +2720,14 @@ void CModelInfoSA::GetVoice(const char** pszVoiceType, const char** pszVoice) void CModelInfoSA::SetVoice(short sVoiceType, short sVoiceID) { - GetPedModelInfoInterface()->sVoiceType = sVoiceType; - GetPedModelInfoInterface()->sFirstVoice = sVoiceID; - GetPedModelInfoInterface()->sLastVoice = sVoiceID; - GetPedModelInfoInterface()->sNextVoice = sVoiceID; + CPedModelInfoSAInterface* pInterface = GetPedModelInfoInterface(); + if (!pInterface) + return; + + pInterface->sVoiceType = sVoiceType; + pInterface->sFirstVoice = sVoiceID; + pInterface->sLastVoice = sVoiceID; + pInterface->sNextVoice = sVoiceID; } void CModelInfoSA::SetVoice(const char* szVoiceType, const char* szVoice) @@ -1723,18 +2741,33 @@ void CModelInfoSA::SetVoice(const char* szVoiceType, const char* szVoice) SetVoice(sVoiceType, sVoiceID); } +static void UnlinkAndResetStreamingInfo(CStreamingInfo* pStreamInfo) +{ + if (!pStreamInfo) + return; + + UnlinkStreamingInfoNeighbors(pStreamInfo); + *pStreamInfo = CStreamingInfo{}; + pStreamInfo->prevId = static_cast(-1); + pStreamInfo->nextId = static_cast(-1); + pStreamInfo->nextInImg = static_cast(-1); +} + void CModelInfoSA::CopyStreamingInfoFromModel(ushort usBaseModelID) { CStreamingInfo* pBaseModelStreamingInfo = pGame->GetStreaming()->GetStreamingInfo(usBaseModelID); CStreamingInfo* pTargetModelStreamingInfo = pGame->GetStreaming()->GetStreamingInfo(m_dwModelID); - *pTargetModelStreamingInfo = CStreamingInfo{}; + if (!pBaseModelStreamingInfo || !pTargetModelStreamingInfo) + return; + + UnlinkAndResetStreamingInfo(pTargetModelStreamingInfo); pTargetModelStreamingInfo->archiveId = pBaseModelStreamingInfo->archiveId; pTargetModelStreamingInfo->offsetInBlocks = pBaseModelStreamingInfo->offsetInBlocks; pTargetModelStreamingInfo->sizeInBlocks = pBaseModelStreamingInfo->sizeInBlocks; } -void CModelInfoSA::MakePedModel(char* szTexture) +void CModelInfoSA::MakePedModel(const char* szTexture) { // Create a new CPedModelInfo CPedModelInfoSA pedModelInfo; @@ -1743,18 +2776,57 @@ void CModelInfoSA::MakePedModel(char* szTexture) pGame->GetStreaming()->RequestSpecialModel(m_dwModelID, szTexture, 0); } -void CModelInfoSA::MakeObjectModel(ushort usBaseID) +void CModelInfoSA::MakePedModel(ushort usParentID) { - CBaseModelInfoSAInterface* m_pInterface = new CBaseModelInfoSAInterface(); + CBaseModelInfoSAInterface* pParentInfo = ppModelInfo[usParentID]; + if (!IsValidModelInfoPtr(pParentInfo)) + { + ppModelInfo[m_dwModelID] = nullptr; + m_pInterface = nullptr; + m_dwParentID = 0; + ClearModelDefaults(m_dwModelID); + + UnlinkAndResetStreamingInfo(pGame->GetStreaming()->GetStreamingInfo(m_dwModelID)); + return; + } + + CPedModelInfoSAInterface* pNewInterface = new CPedModelInfoSAInterface(); + MemCpyFast(pNewInterface, pParentInfo, sizeof(CPedModelInfoSAInterface)); + pNewInterface->usNumberOfRefs = 0; + pNewInterface->pRwObject = nullptr; + pNewInterface->usUnknown = 65535; + pNewInterface->usDynamicIndex = 65535; + pNewInterface->pHitColModel = nullptr; + pNewInterface->bIsColLoaded = 0; + + ppModelInfo[m_dwModelID] = pNewInterface; + + m_dwParentID = usParentID; + CopyStreamingInfoFromModel(usParentID); +} +void CModelInfoSA::MakeObjectModel(ushort usBaseID) +{ CBaseModelInfoSAInterface* pBaseObjectInfo = ppModelInfo[usBaseID]; - MemCpyFast(m_pInterface, pBaseObjectInfo, sizeof(CBaseModelInfoSAInterface)); - m_pInterface->usNumberOfRefs = 0; - m_pInterface->pRwObject = nullptr; - m_pInterface->usUnknown = 65535; - m_pInterface->usDynamicIndex = 65535; + if (!IsValidModelInfoPtr(pBaseObjectInfo)) + { + ppModelInfo[m_dwModelID] = nullptr; + m_pInterface = nullptr; + m_dwParentID = 0; + ClearModelDefaults(m_dwModelID); - ppModelInfo[m_dwModelID] = m_pInterface; + UnlinkAndResetStreamingInfo(pGame->GetStreaming()->GetStreamingInfo(m_dwModelID)); + return; + } + + CBaseModelInfoSAInterface* pNewInterface = new CBaseModelInfoSAInterface(); + MemCpyFast(pNewInterface, pBaseObjectInfo, sizeof(CBaseModelInfoSAInterface)); + pNewInterface->usNumberOfRefs = 0; + pNewInterface->pRwObject = nullptr; + pNewInterface->usUnknown = 65535; + pNewInterface->usDynamicIndex = 65535; + + ppModelInfo[m_dwModelID] = pNewInterface; m_dwParentID = usBaseID; CopyStreamingInfoFromModel(usBaseID); @@ -1762,17 +2834,27 @@ void CModelInfoSA::MakeObjectModel(ushort usBaseID) void CModelInfoSA::MakeObjectDamageableModel(std::uint16_t baseModel) { - CDamageableModelInfoSAInterface* m_pInterface = new CDamageableModelInfoSAInterface(); - CDamageableModelInfoSAInterface* pBaseObjectInfo = static_cast(ppModelInfo[baseModel]); - MemCpyFast(m_pInterface, pBaseObjectInfo, sizeof(CDamageableModelInfoSAInterface)); - m_pInterface->usNumberOfRefs = 0; - m_pInterface->pRwObject = nullptr; - m_pInterface->usUnknown = 65535; - m_pInterface->usDynamicIndex = 65535; - m_pInterface->m_damagedAtomic = nullptr; + if (!IsValidModelInfoPtr(pBaseObjectInfo)) + { + ppModelInfo[m_dwModelID] = nullptr; + m_pInterface = nullptr; + m_dwParentID = 0; + ClearModelDefaults(m_dwModelID); + + UnlinkAndResetStreamingInfo(pGame->GetStreaming()->GetStreamingInfo(m_dwModelID)); + return; + } + + CDamageableModelInfoSAInterface* pNewInterface = new CDamageableModelInfoSAInterface(); + MemCpyFast(pNewInterface, pBaseObjectInfo, sizeof(CDamageableModelInfoSAInterface)); + pNewInterface->usNumberOfRefs = 0; + pNewInterface->pRwObject = nullptr; + pNewInterface->usUnknown = 65535; + pNewInterface->usDynamicIndex = 65535; + pNewInterface->m_damagedAtomic = nullptr; - ppModelInfo[m_dwModelID] = m_pInterface; + ppModelInfo[m_dwModelID] = pNewInterface; m_dwParentID = baseModel; CopyStreamingInfoFromModel(baseModel); @@ -1780,17 +2862,27 @@ void CModelInfoSA::MakeObjectDamageableModel(std::uint16_t baseModel) void CModelInfoSA::MakeTimedObjectModel(ushort usBaseID) { - CTimeModelInfoSAInterface* m_pInterface = new CTimeModelInfoSAInterface(); - CTimeModelInfoSAInterface* pBaseObjectInfo = static_cast(ppModelInfo[usBaseID]); - MemCpyFast(m_pInterface, pBaseObjectInfo, sizeof(CTimeModelInfoSAInterface)); - m_pInterface->usNumberOfRefs = 0; - m_pInterface->pRwObject = nullptr; - m_pInterface->usUnknown = 65535; - m_pInterface->usDynamicIndex = 65535; - m_pInterface->timeInfo.m_wOtherTimeModel = 0; + if (!IsValidModelInfoPtr(pBaseObjectInfo)) + { + ppModelInfo[m_dwModelID] = nullptr; + m_pInterface = nullptr; + m_dwParentID = 0; + ClearModelDefaults(m_dwModelID); + + UnlinkAndResetStreamingInfo(pGame->GetStreaming()->GetStreamingInfo(m_dwModelID)); + return; + } + + CTimeModelInfoSAInterface* pNewInterface = new CTimeModelInfoSAInterface(); + MemCpyFast(pNewInterface, pBaseObjectInfo, sizeof(CTimeModelInfoSAInterface)); + pNewInterface->usNumberOfRefs = 0; + pNewInterface->pRwObject = nullptr; + pNewInterface->usUnknown = 65535; + pNewInterface->usDynamicIndex = 65535; + pNewInterface->timeInfo.m_wOtherTimeModel = -1; - ppModelInfo[m_dwModelID] = m_pInterface; + ppModelInfo[m_dwModelID] = pNewInterface; m_dwParentID = usBaseID; CopyStreamingInfoFromModel(usBaseID); @@ -1798,8 +2890,19 @@ void CModelInfoSA::MakeTimedObjectModel(ushort usBaseID) void CModelInfoSA::MakeClumpModel(ushort usBaseID) { - CClumpModelInfoSAInterface* pNewInterface = new CClumpModelInfoSAInterface(); CBaseModelInfoSAInterface* pBaseObjectInfo = ppModelInfo[usBaseID]; + if (!IsValidModelInfoPtr(pBaseObjectInfo)) + { + ppModelInfo[m_dwModelID] = nullptr; + m_pInterface = nullptr; + m_dwParentID = 0; + ClearModelDefaults(m_dwModelID); + + UnlinkAndResetStreamingInfo(pGame->GetStreaming()->GetStreamingInfo(m_dwModelID)); + return; + } + + CClumpModelInfoSAInterface* pNewInterface = new CClumpModelInfoSAInterface(); MemCpyFast(pNewInterface, pBaseObjectInfo, sizeof(CClumpModelInfoSAInterface)); pNewInterface->usNumberOfRefs = 0; pNewInterface->pRwObject = nullptr; @@ -1814,56 +2917,191 @@ void CModelInfoSA::MakeClumpModel(ushort usBaseID) void CModelInfoSA::MakeVehicleAutomobile(ushort usBaseID) { - CVehicleModelInfoSAInterface* m_pInterface = new CVehicleModelInfoSAInterface(); + CBaseModelInfoSAInterface* pBaseObjectInfo = ppModelInfo[usBaseID]; + if (!IsValidModelInfoPtr(pBaseObjectInfo)) + { + ppModelInfo[m_dwModelID] = nullptr; + m_pInterface = nullptr; + m_dwParentID = 0; + ClearModelDefaults(m_dwModelID); - CBaseModelInfoSAInterface* pBaseObjectInfo = (CBaseModelInfoSAInterface*)ppModelInfo[usBaseID]; - MemCpyFast(m_pInterface, pBaseObjectInfo, sizeof(CVehicleModelInfoSAInterface)); - m_pInterface->usNumberOfRefs = 0; - m_pInterface->pRwObject = nullptr; - m_pInterface->pVisualInfo = nullptr; - m_pInterface->usUnknown = 65535; - m_pInterface->usDynamicIndex = 65535; + UnlinkAndResetStreamingInfo(pGame->GetStreaming()->GetStreamingInfo(m_dwModelID)); + return; + } + + CVehicleModelInfoSAInterface* pNewInterface = new CVehicleModelInfoSAInterface(); + MemCpyFast(pNewInterface, pBaseObjectInfo, sizeof(CVehicleModelInfoSAInterface)); + pNewInterface->usNumberOfRefs = 0; + pNewInterface->pRwObject = nullptr; + pNewInterface->pVisualInfo = nullptr; + pNewInterface->usUnknown = 65535; + pNewInterface->usDynamicIndex = 65535; - ppModelInfo[m_dwModelID] = m_pInterface; + ppModelInfo[m_dwModelID] = pNewInterface; m_dwParentID = usBaseID; CopyStreamingInfoFromModel(usBaseID); } -void CModelInfoSA::DeallocateModel(void) +void CModelInfoSA::DeallocateModel() { - Remove(); + CBaseModelInfoSAInterface* pInterfaceToDelete = ppModelInfo[m_dwModelID]; - switch (GetModelType()) + if (!IsValidModelInfoPtr(pInterfaceToDelete)) + { + if (pInterfaceToDelete) + ppModelInfo[m_dwModelID] = nullptr; + + ms_DefaultTxdIDMap.erase(static_cast(m_dwModelID)); + ms_ModelDefaultFlagsMap.erase(m_dwModelID); + ms_ModelDefaultLodDistanceMap.erase(m_dwModelID); + ms_ModelDefaultAlphaTransparencyMap.erase(m_dwModelID); + ms_OriginalObjectPropertiesGroups.erase(m_dwModelID); + ms_ModelDefaultDummiesPosition.erase(m_dwModelID); + ms_VehicleModelDefaultWheelSizes.erase(m_dwModelID); + ms_ModelDefaultModelTimeInfo.erase(m_dwModelID); + + m_pInterface = nullptr; + m_dwReferences = 0; + m_dwPendingInterfaceRef = 0; + m_dwParentID = 0; + m_pCustomClump = nullptr; + m_pCustomColModel = nullptr; + m_pOriginalColModelInterface = nullptr; + if (m_colRefCount > 0 && m_usColSlot != 0xFFFF && m_usColSlot <= 0xFF && pGame) + { + auto* pColStore = pGame->GetCollisionStore(); + if (pColStore) + { + const CollisionSlot colSlot = static_cast(m_usColSlot); + if (pColStore->IsValidSlot(colSlot)) + { + for (std::uint32_t i = 0; i < m_colRefCount; ++i) + pColStore->RemoveRef(colSlot); + } + } + } + m_colRefCount = 0; + m_usColSlot = 0xFFFF; + m_originalFlags = 0; + m_ModelSupportedUpgrades.Reset(); + return; + } + + // GTA's destructors (e.g. CObject at 0x4C4BB0) access ppModelInfo[] during cleanup. + // Block deletion while refs > 0 to avoid null pointer crash. + if (pInterfaceToDelete->usNumberOfRefs > 0) + { + AddReportLog(5550, SString("Blocked DeallocateModel for model %u with %u active refs to prevent crash at 0x4C4BB0", m_dwModelID, + static_cast(pInterfaceToDelete->usNumberOfRefs))); + + m_pInterface = pInterfaceToDelete; + + // Clear custom model pointers to prevent use-after-free on later RemoveRef calls + m_pCustomClump = nullptr; + m_pCustomColModel = nullptr; + m_pOriginalColModelInterface = nullptr; + m_originalFlags = 0; + + // Keep m_dwReferences and TXD mapping intact - model still in use + // Tradeoff: interface leaks until refs hit 0, model ID stays occupied + return; + } + + // Clear stored defaults so they don't leak to a model that reuses this ID + ms_DefaultTxdIDMap.erase(static_cast(m_dwModelID)); + ms_ModelDefaultFlagsMap.erase(m_dwModelID); + ms_ModelDefaultLodDistanceMap.erase(m_dwModelID); + ms_ModelDefaultAlphaTransparencyMap.erase(m_dwModelID); + ms_OriginalObjectPropertiesGroups.erase(m_dwModelID); + ms_ModelDefaultDummiesPosition.erase(m_dwModelID); + ms_VehicleModelDefaultWheelSizes.erase(m_dwModelID); + + pGame->GetStreaming()->RemoveModel(m_dwModelID); + + // Capture model type and damageability BEFORE nulling the array entry. + eModelInfoType modelType = eModelInfoType::UNKNOWN; + bool isDamageableAtomic = false; + if (pInterfaceToDelete->VFTBL) + { + DWORD typeFunc = pInterfaceToDelete->VFTBL->GetModelType; + if (SharedUtil::IsValidGtaSaPtr(typeFunc)) + modelType = ((eModelInfoType (*)())typeFunc)(); + + if (modelType == eModelInfoType::ATOMIC || modelType == eModelInfoType::LOD_ATOMIC) + { + DWORD damageFunc = pInterfaceToDelete->VFTBL->AsDamageAtomicModelInfoPtr; + if (SharedUtil::IsValidGtaSaPtr(damageFunc)) + { + void* asDamageable = ((void* (*)())damageFunc)(); + isDamageableAtomic = (asDamageable != nullptr); + } + } + } + + ms_ModelDefaultModelTimeInfo.erase(m_dwModelID); + + // Null the array entry BEFORE delete for fail-fast if anything tries to access it during deletion + ppModelInfo[m_dwModelID] = nullptr; + + // Reset wrapper state - this object persists and may be reused for a new model + m_pInterface = nullptr; + m_dwReferences = 0; + m_dwPendingInterfaceRef = 0; + m_dwParentID = 0; + m_pCustomClump = nullptr; + m_pCustomColModel = nullptr; + m_pOriginalColModelInterface = nullptr; + if (m_colRefCount > 0 && m_usColSlot != 0xFFFF && m_usColSlot <= 0xFF && pGame) + { + auto* pColStore = pGame->GetCollisionStore(); + if (pColStore) + { + const CollisionSlot colSlot = static_cast(m_usColSlot); + if (pColStore->IsValidSlot(colSlot)) + { + for (std::uint32_t i = 0; i < m_colRefCount; ++i) + pColStore->RemoveRef(colSlot); + } + } + } + m_colRefCount = 0; + m_usColSlot = 0xFFFF; + m_originalFlags = 0; + m_ModelSupportedUpgrades.Reset(); + + switch (modelType) { case eModelInfoType::VEHICLE: - delete reinterpret_cast(ppModelInfo[m_dwModelID]); + delete reinterpret_cast(pInterfaceToDelete); break; case eModelInfoType::PED: - delete reinterpret_cast(ppModelInfo[m_dwModelID]); + delete reinterpret_cast(pInterfaceToDelete); break; case eModelInfoType::ATOMIC: - if (IsDamageableAtomic()) + case eModelInfoType::LOD_ATOMIC: + if (isDamageableAtomic) { - delete reinterpret_cast(ppModelInfo[m_dwModelID]); + delete reinterpret_cast(pInterfaceToDelete); } else { - delete reinterpret_cast(ppModelInfo[m_dwModelID]); + delete reinterpret_cast(pInterfaceToDelete); } break; + case eModelInfoType::WEAPON: case eModelInfoType::CLUMP: - delete reinterpret_cast(ppModelInfo[m_dwModelID]); + delete reinterpret_cast(pInterfaceToDelete); break; case eModelInfoType::TIME: - delete reinterpret_cast(ppModelInfo[m_dwModelID]); + delete reinterpret_cast(pInterfaceToDelete); break; default: - break; + AddReportLog(5551, SString("Unknown model type %d for model %u - memory leaked to prevent corruption", static_cast(modelType), m_dwModelID)); + return; } - ppModelInfo[m_dwModelID] = nullptr; - *pGame->GetStreaming()->GetStreamingInfo(m_dwModelID) = CStreamingInfo{}; + UnlinkAndResetStreamingInfo(pGame->GetStreaming()->GetStreamingInfo(m_dwModelID)); } ////////////////////////////////////////////////////////////////////////////////////////// // @@ -1889,12 +3127,15 @@ __declspec(noinline) void OnMY_NodeNameStreamRead(RwStream* stream, char* pDest, } // Hook info -#define HOOKPOS_NodeNameStreamRead 0x072FA68 -#define HOOKSIZE_NodeNameStreamRead 15 -DWORD RETURN_NodeNameStreamRead = 0x072FA77; -void _declspec(naked) HOOK_NodeNameStreamRead() +#define HOOKPOS_NodeNameStreamRead 0x072FA68 +#define HOOKSIZE_NodeNameStreamRead 15 +DWORD RETURN_NodeNameStreamRead = 0x072FA77; +static void __declspec(naked) HOOK_NodeNameStreamRead() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push edi @@ -1906,6 +3147,7 @@ void _declspec(naked) HOOK_NodeNameStreamRead() jmp RETURN_NodeNameStreamRead } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -2031,48 +3273,79 @@ void CModelInfoSA::ResetSupportedUpgrades() void CModelInfoSA::SetObjectPropertiesGroup(unsigned short usNewGroup) { - unsigned short usOrgGroup = GetObjectPropertiesGroup(); + CBaseModelInfoSAInterface* pInterface = GetInterface(); + if (!pInterface) + return; + + unsigned short usOrgGroup = pInterface->usDynamicIndex; if (usOrgGroup == usNewGroup) return; if (!MapFind(ms_OriginalObjectPropertiesGroups, m_dwModelID)) MapSet(ms_OriginalObjectPropertiesGroups, m_dwModelID, usOrgGroup); - GetInterface()->usDynamicIndex = usNewGroup; + pInterface->usDynamicIndex = usNewGroup; } unsigned short CModelInfoSA::GetObjectPropertiesGroup() { - return GetInterface()->usDynamicIndex; + CBaseModelInfoSAInterface* pInterface = GetInterface(); + if (pInterface) + return pInterface->usDynamicIndex; + return 0; } void CModelInfoSA::RestoreObjectPropertiesGroup() { unsigned short* usGroupInMap = MapFind(ms_OriginalObjectPropertiesGroups, m_dwModelID); - if (usGroupInMap) + if (!usGroupInMap) + return; + + CBaseModelInfoSAInterface* pInterface = GetInterface(); + if (!pInterface) { - GetInterface()->usDynamicIndex = *usGroupInMap; MapRemove(ms_OriginalObjectPropertiesGroups, m_dwModelID); + return; } + + pInterface->usDynamicIndex = *usGroupInMap; + MapRemove(ms_OriginalObjectPropertiesGroups, m_dwModelID); } void CModelInfoSA::RestoreAllObjectsPropertiesGroups() { - for (const auto& pair : ms_OriginalObjectPropertiesGroups) + for (auto it = ms_OriginalObjectPropertiesGroups.begin(); it != ms_OriginalObjectPropertiesGroups.end();) { - CBaseModelInfoSAInterface* pInterface = pGame->GetModelInfo(pair.first, true)->GetInterface(); - if (pInterface) - pInterface->usDynamicIndex = pair.second; + auto* pModelInfo = pGame->GetModelInfo(it->first, true); + if (!pModelInfo) + { + it = ms_OriginalObjectPropertiesGroups.erase(it); + continue; + } + + CBaseModelInfoSAInterface* pInterface = pModelInfo->GetInterface(); + if (!pInterface) + { + it = ms_OriginalObjectPropertiesGroups.erase(it); + continue; + } + + pInterface->usDynamicIndex = it->second; + it = ms_OriginalObjectPropertiesGroups.erase(it); } - ms_OriginalObjectPropertiesGroups.clear(); } eModelInfoType CModelInfoSA::GetModelType() { - if (auto pInterface = GetInterface()) - return ((eModelInfoType(*)())pInterface->VFTBL->GetModelType)(); + auto pInterface = GetInterface(); + if (!pInterface || !pInterface->VFTBL) + return eModelInfoType::UNKNOWN; - return eModelInfoType::UNKNOWN; + DWORD funcAddr = pInterface->VFTBL->GetModelType; + if (!SharedUtil::IsValidGtaSaPtr(funcAddr)) + return eModelInfoType::UNKNOWN; + + return ((eModelInfoType (*)())funcAddr)(); } bool CModelInfoSA::IsTowableBy(CModelInfo* towingModel) @@ -2107,8 +3380,16 @@ bool CModelInfoSA::IsTowableBy(CModelInfo* towingModel) bool CModelInfoSA::IsDamageableAtomic() { - void* asDamagable = ((void* (*)())m_pInterface->VFTBL->AsDamageAtomicModelInfoPtr)(); - return asDamagable != nullptr; + CBaseModelInfoSAInterface* pInterface = GetInterface(); + if (!pInterface || !pInterface->VFTBL) + return false; + + DWORD funcAddr = pInterface->VFTBL->AsDamageAtomicModelInfoPtr; + if (!SharedUtil::IsValidGtaSaPtr(funcAddr)) + return false; + + void* asDamageable = ((void* (*)())funcAddr)(); + return asDamageable != nullptr; } ////////////////////////////////////////////////////////////////////////////////////////// @@ -2130,27 +3411,29 @@ bool CModelInfoSA::IsDamageableAtomic() ////////////////////////////////////////////////////////////////////////////////////////// bool CModelInfoSA::ForceUnload() { - CBaseModelInfoSAInterface* pModelInfoSAInterface = GetInterface(); + CBaseModelInfoSAInterface* pInterface = GetInterface(); + if (!pInterface) + return false; - // Need to have at least one ref to delete pRwObject - if (pModelInfoSAInterface->usNumberOfRefs == 0 && pModelInfoSAInterface->pRwObject != NULL) - { - pModelInfoSAInterface->usNumberOfRefs++; - } + m_dwReferences = 0; + m_dwPendingInterfaceRef = 0; - // Keep removing refs from the model until is it gone - uint uiLimit = 100; - while (pModelInfoSAInterface->usNumberOfRefs > 0 && uiLimit--) + if (pInterface->usNumberOfRefs == 0 && pInterface->pRwObject != nullptr) + pInterface->usNumberOfRefs++; + + DWORD dwFunction = FUNC_RemoveRef; + uint uiLimit = 100; + while (pInterface->usNumberOfRefs > 0 && uiLimit--) { - RemoveRef(); + using func_t = void (__thiscall*)(decltype(pInterface) ); + reinterpret_cast(dwFunction)(pInterface); } - // Did it work? - if (pModelInfoSAInterface->usNumberOfRefs > 0 || pModelInfoSAInterface->pRwObject != NULL) + if (pInterface->usNumberOfRefs > 0 || pInterface->pRwObject != nullptr) return false; // If success, then remove txd - ushort usTxdId = GetTextureDictionaryID(); + ushort usTxdId = pInterface->usTextureDictionary; if (usTxdId) pGame->GetRenderWare()->TxdForceUnload(usTxdId, true); diff --git a/Client/game_sa/CModelInfoSA.h b/Client/game_sa/CModelInfoSA.h index d083209a2a1..142cfd2e90f 100644 --- a/Client/game_sa/CModelInfoSA.h +++ b/Client/game_sa/CModelInfoSA.h @@ -21,48 +21,51 @@ class CPedModelInfoSAInterface; struct CColModelSAInterface; struct RpMaterial; -#define RpGetFrame(__c) ((RwFrame*)(((RwObject *)(__c))->parent)) +#define RpGetFrame(__c) ((RwFrame*)(((RwObject*)(__c))->parent)) // #define ARRAY_ModelLoaded 0x8E4CD0 // ##SA## static void* CStreaming__ms_aInfoForModel = *(void**)(0x5B8B08 + 6); static void* ARRAY_ModelLoaded = (char*)CStreaming__ms_aInfoForModel + 0x10; -#define FUNC_CStreaming__HasModelLoaded 0x4044C0 +#define FUNC_CStreaming__HasModelLoaded 0x4044C0 + +#define NUM_INVALID_PTR_THRESHOLD 0x10000 // CModelInfo/ARRAY_ModelInfo __thiscall to load/replace vehicle models -#define FUNC_LoadVehicleModel 0x4C95C0 -#define FUNC_LoadWeaponModel 0x4C9910 -#define FUNC_LoadPedModel 0x4C7340 +#define FUNC_LoadVehicleModel 0x4C95C0 +#define FUNC_LoadClumpModel 0x4C4F70 +#define FUNC_LoadWeaponModel 0x4C9910 +#define FUNC_LoadPedModel 0x4C7340 -#define DWORD_AtomicsReplacerModelID 0xB71840 -#define FUNC_AtomicsReplacer 0x537150 +#define DWORD_AtomicsReplacerModelID 0xB71840 +#define FUNC_AtomicsReplacer 0x537150 // #define ARRAY_ModelInfo 0xA9B0C8 static void* ARRAY_ModelInfo = *(void**)(0x403DA4 + 3); -#define CLASS_CText 0xC1B340 -#define FUNC_CText_Get 0x6A0050 -#define FUNC_GetBoundingBox 0x4082F0 - -#define FUNC_RemoveRef 0x4C4BB0 -#define FUNC_IsBoatModel 0x4c5a70 -#define FUNC_IsCarModel 0x4c5aa0 -#define FUNC_IsTrainModel 0x4c5ad0 -#define FUNC_IsHeliModel 0x4c5b00 -#define FUNC_IsPlaneModel 0x4c5b30 -#define FUNC_IsBikeModel 0x4c5b60 -#define FUNC_IsFakePlaneModel 0x4c5b90 -#define FUNC_IsMonsterTruckModel 0x4c5bc0 -#define FUNC_IsQuadBikeModel 0x4c5bf0 -#define FUNC_IsBmxModel 0x4c5c20 -#define FUNC_IsTrailerModel 0x4c5c50 -#define FUNC_IsVehicleModelType 0x4c5c80 -#define FUNC_RemoveModel 0x4089a0 -#define FUNC_FlushRequestList 0x40E4E0 -#define FUNC_RequestVehicleUpgrade 0x408C70 - -#define FUNC_CVehicleModelInfo__GetNumRemaps 0x4C86B0 - -#define VAR_CTempColModels_ModelPed1 0x968DF0 +#define CLASS_CText 0xC1B340 +#define FUNC_CText_Get 0x6A0050 +#define FUNC_GetBoundingBox 0x4082F0 + +#define FUNC_RemoveRef 0x4C4BB0 +#define FUNC_IsBoatModel 0x4c5a70 +#define FUNC_IsCarModel 0x4c5aa0 +#define FUNC_IsTrainModel 0x4c5ad0 +#define FUNC_IsHeliModel 0x4c5b00 +#define FUNC_IsPlaneModel 0x4c5b30 +#define FUNC_IsBikeModel 0x4c5b60 +#define FUNC_IsFakePlaneModel 0x4c5b90 +#define FUNC_IsMonsterTruckModel 0x4c5bc0 +#define FUNC_IsQuadBikeModel 0x4c5bf0 +#define FUNC_IsBmxModel 0x4c5c20 +#define FUNC_IsTrailerModel 0x4c5c50 +#define FUNC_IsVehicleModelType 0x4c5c80 +#define FUNC_RemoveModel 0x4089a0 +#define FUNC_FlushRequestList 0x40E4E0 +#define FUNC_RequestVehicleUpgrade 0x408C70 + +#define FUNC_CVehicleModelInfo__GetNumRemaps 0x4C86B0 + +#define VAR_CTempColModels_ModelPed1 0x968DF0 class CBaseModelInfoSAInterface; class CModelInfoSAInterface @@ -80,25 +83,25 @@ class CBaseModelInfo_SA_VTBL { public: DWORD Destructor; - DWORD AsAtomicModelInfoPtr; // () - DWORD AsDamageAtomicModelInfoPtr; // () - DWORD AsLodAtomicModelInfoPtr; // () - DWORD GetModelType; // () - Not defined in the base - DWORD GetTimeInfo; // () - DWORD Init; // () - DWORD Shutdown; // () - DWORD DeleteRwObject; // () - Not defined in the base - DWORD GetRwModelType; // () - Not defined in the base - DWORD CreateInstance_; // (RwMatrix*) - Not defined in the base - DWORD CreateInstance; // () - Not defined in the base - DWORD SetAnimFile; // (char const*) - DWORD ConvertAnimFileIndex; // () - DWORD GetAnimFileIndex; // () + DWORD AsAtomicModelInfoPtr; // () + DWORD AsDamageAtomicModelInfoPtr; // () + DWORD AsLodAtomicModelInfoPtr; // () + DWORD GetModelType; // () - Not defined in the base + DWORD GetTimeInfo; // () + DWORD Init; // () + DWORD Shutdown; // () + DWORD DeleteRwObject; // () - Not defined in the base + DWORD GetRwModelType; // () - Not defined in the base + DWORD CreateInstance_; // (RwMatrix*) - Not defined in the base + DWORD CreateInstance; // () - Not defined in the base + DWORD SetAnimFile; // (char const*) + DWORD ConvertAnimFileIndex; // () + DWORD GetAnimFileIndex; // () }; class CAtomicModelInfo_SA_VTBL : public CBaseModelInfo_SA_VTBL { - DWORD SetAtomic; // (RpAtomic*) + DWORD SetAtomic; // (RpAtomic*) }; class CDamageAtomicModelInfo_SA_VTBL : public CAtomicModelInfo_SA_VTBL @@ -119,7 +122,7 @@ class CLodTimeModelInfo_SA_VTBL : public CLodAtomicModelInfo_SA_VTBL class CClumpModelInfo_SA_VTBL : public CBaseModelInfo_SA_VTBL { - DWORD SetClump; // (RpClump*) + DWORD SetClump; // (RpClump*) }; class CWeaponModelInfo_SA_VTBL : public CClumpModelInfo_SA_VTBL @@ -143,33 +146,33 @@ enum class eModelSpecialType : unsigned char GLASS_2 = 5, TAG = 6, GARAGE_DOOR = 7, - CRANE = 9, // Not present in IDE but used in gta - UNKNOW_1 = 10, // Read only + CRANE = 9, // Not present in IDE but used in gta + UNKNOW_1 = 10, // Read only BREAKABLE_STATUE = 11, }; class CBaseModelInfoSAInterface { public: - CBaseModelInfo_SA_VTBL* VFTBL; // +0 + CBaseModelInfo_SA_VTBL* VFTBL; // +0 - unsigned long ulHashKey; // +4 Generated by CKeyGen::GetUppercaseKey(char const *) called by CBaseModelInfo::SetModelName(char const *) - unsigned short usNumberOfRefs : 16; // +8 - unsigned short usTextureDictionary : 16; // +10 - unsigned char ucAlpha : 8; // +12 + unsigned long ulHashKey; // +4 Generated by CKeyGen::GetUppercaseKey(char const *) called by CBaseModelInfo::SetModelName(char const *) + unsigned short usNumberOfRefs : 16; // +8 + unsigned short usTextureDictionary : 16; // +10 + unsigned char ucAlpha : 8; // +12 - unsigned char ucNumOf2DEffects : 8; // +13 - unsigned short usUnknown : 16; // +14 Something with 2d effects + unsigned char ucNumOf2DEffects : 8; // +13 + unsigned short usUnknown : 16; // +14 Something with 2d effects - unsigned short usDynamicIndex : 16; // +16 + unsigned short usDynamicIndex : 16; // +16 // Flags used by CBaseModelInfo union { struct { - unsigned char bHasBeenPreRendered : 1; // we use this because we need to apply changes only once - unsigned char bAlphaTransparency : 1; // bDrawLast + unsigned char bHasBeenPreRendered : 1; // we use this because we need to apply changes only once + unsigned char bAlphaTransparency : 1; // bDrawLast unsigned char bAdditiveRender : 1; unsigned char bDontWriteZBuffer : 1; unsigned char bDontCastShadowsOn : 1; @@ -180,16 +183,16 @@ class CBaseModelInfoSAInterface unsigned char bHasComplexHierarchy : 1; unsigned char bDontCollideWithFlyer : 1; eModelSpecialType eSpecialModelType : 4; - unsigned char bWetRoadReflection : 1; // Used for tags + unsigned char bWetRoadReflection : 1; // Used for tags }; unsigned short usFlags; }; - CColModelSAInterface* pColModel; // +20 CColModel: public CBoundingBox + CColModelSAInterface* pColModel; // +20 CColModel: public CBoundingBox - float fLodDistanceUnscaled; // +24 Scaled is this value multiplied with flt_B6F118 - RwObject* pRwObject; // +28 + float fLodDistanceUnscaled; // +24 Scaled is this value multiplied with flt_B6F118 + RwObject* pRwObject; // +28 // CWeaponModelInfo: // +36 = Weapon info as int @@ -237,8 +240,8 @@ static_assert(sizeof(CBaseModelInfoSAInterface) == 0x20, "Invalid size for CBase struct CTimeInfoSAInterface { - CTimeInfoSAInterface() : m_nTimeOn(20), m_nTimeOff(6), m_wOtherTimeModel(0){}; - CTimeInfoSAInterface(char timeOn, char timeOff, short OtherTimeModel) : m_nTimeOn(timeOn), m_nTimeOff(timeOff), m_wOtherTimeModel(OtherTimeModel){}; + CTimeInfoSAInterface() : m_nTimeOn(20), m_nTimeOff(6), m_wOtherTimeModel(0) {}; + CTimeInfoSAInterface(char timeOn, char timeOff, short OtherTimeModel) : m_nTimeOn(timeOn), m_nTimeOff(timeOff), m_wOtherTimeModel(OtherTimeModel) {}; char m_nTimeOn; char m_nTimeOff; short m_wOtherTimeModel; @@ -274,7 +277,7 @@ class CDamageableModelInfoSAInterface : public CBaseModelInfoSAInterface void* m_damagedAtomic; }; -class CVehicleModelVisualInfoSAInterface // Not sure about this name. If somebody knows more, please change +class CVehicleModelVisualInfoSAInterface // Not sure about this name. If somebody knows more, please change { public: CVector vecDummies[15]; @@ -311,7 +314,7 @@ class CVehicleModelInfoSAInterface : public CClumpModelInfoSAInterface std::int16_t vehFrequency; std::uint32_t componentRules; float bikeSteeringAngle; - CVehicleModelVisualInfoSAInterface* pVisualInfo; // vehicleStruct + CVehicleModelVisualInfoSAInterface* pVisualInfo; // vehicleStruct std::uint8_t field_60[464]; RpMaterial** m_dirtMaterials; std::size_t m_numDirtMaterials; @@ -329,32 +332,36 @@ class CVehicleModelInfoSAInterface : public CClumpModelInfoSAInterface std::uint8_t upgrades[36]; std::uint8_t anRemapTXDs[8]; std::uint8_t field_302[2]; - void* pAnimBlock; // CAnimBlock* + void* pAnimBlock; // CAnimBlock* }; static_assert(sizeof(CVehicleModelInfoSAInterface) == 0x308, "Invalid size of CVehicleModelInfoSAInterface class"); class CModelInfoSA : public CModelInfo { protected: - CBaseModelInfoSAInterface* m_pInterface; - DWORD m_dwModelID; - DWORD m_dwParentID; - DWORD m_dwReferences; - DWORD m_dwPendingInterfaceRef; - CColModel* m_pCustomColModel; - CColModelSAInterface* m_pOriginalColModelInterface; - std::uint16_t m_originalFlags = 0; - RpClump* m_pCustomClump; - static std::map ms_RestreamTxdIDMap; - static std::map ms_ModelDefaultLodDistanceMap; - static std::map ms_ModelDefaultFlagsMap; - static std::map ms_ModelDefaultAlphaTransparencyMap; + CBaseModelInfoSAInterface* m_pInterface; + DWORD m_dwModelID; + DWORD m_dwParentID; + DWORD m_dwReferences; + DWORD m_dwPendingInterfaceRef; + CColModel* m_pCustomColModel; + CColModelSAInterface* m_pOriginalColModelInterface; + std::uint32_t m_colRefCount = 0; + unsigned short m_usColSlot = 0xFFFF; + std::uint16_t m_originalFlags = 0; + RpClump* m_pCustomClump; + static std::map ms_RestreamTxdIDMap; + static std::map ms_ModelDefaultLodDistanceMap; + static std::map ms_ModelDefaultFlagsMap; + static std::map ms_ModelDefaultAlphaTransparencyMap; static std::unordered_map> ms_ModelDefaultDummiesPosition; - static std::map ms_ModelDefaultModelTimeInfo; - static std::unordered_map ms_OriginalObjectPropertiesGroups; - static std::unordered_map> ms_VehicleModelDefaultWheelSizes; - static std::map ms_DefaultTxdIDMap; - SVehicleSupportedUpgrades m_ModelSupportedUpgrades; + static std::map ms_ModelDefaultModelTimeInfo; + static std::unordered_map ms_OriginalObjectPropertiesGroups; + static std::unordered_map> ms_VehicleModelDefaultWheelSizes; + static std::map ms_DefaultTxdIDMap; + static std::uint32_t ms_uiTxdAssignmentGeneration; + SVehicleSupportedUpgrades m_ModelSupportedUpgrades; + static void ClearModelDefaults(DWORD modelId); public: CModelInfoSA(); @@ -384,37 +391,42 @@ class CModelInfoSA : public CModelInfo char* GetNameIfVehicle(); - BYTE GetVehicleType() const noexcept; - void Request(EModelRequestType requestType, const char* szTag); - void Remove(); - bool UnloadUnused(); - bool IsLoaded(); - bool DoIsLoaded(); - unsigned short GetFlags(); - unsigned short GetOriginalFlags(); - void SetIdeFlags(unsigned int uiFlags); - void SetIdeFlag(eModelIdeFlag eIdeFlag, bool bState); - bool GetIdeFlag(eModelIdeFlag eIdeFlag); - void SetFlags(unsigned short usFlags); - static void StaticResetFlags(); - CBoundingBox* GetBoundingBox(); - bool IsValid(); - bool IsAllocatedInArchive() const noexcept; - float GetDistanceFromCentreOfMassToBaseOfModel(); - unsigned short GetTextureDictionaryID(); - void SetTextureDictionaryID(unsigned short usID); - void ResetTextureDictionaryID(); - static void StaticResetTextureDictionaries(); - float GetLODDistance(); - float GetOriginalLODDistance(); - void SetLODDistance(float fDistance, bool bOverrideMaxDistance = false); - static void StaticResetLodDistances(); - void RestreamIPL(); - static void StaticFlushPendingRestreamIPL(); - static void StaticSetHooks(); - bool GetTime(char& cHourOn, char& cHourOff); - bool SetTime(char cHourOn, char cHourOff); - static void StaticResetModelTimes(); + BYTE GetVehicleType() const noexcept; + void Request(EModelRequestType requestType, const char* szTag); + void Remove(); + bool UnloadUnused(); + bool IsLoaded(); + bool DoIsLoaded(); + unsigned short GetFlags(); + unsigned short GetOriginalFlags(); + void SetIdeFlags(unsigned int uiFlags); + void SetIdeFlag(eModelIdeFlag eIdeFlag, bool bState); + bool GetIdeFlag(eModelIdeFlag eIdeFlag); + void SetFlags(unsigned short usFlags); + static void StaticResetFlags(); + CBoundingBox* GetBoundingBox(); + [[nodiscard]] bool IsCollisionLoaded() const noexcept; + [[nodiscard]] bool IsRwObjectLoaded() const noexcept; + void WaitForModelFullyLoaded(std::chrono::milliseconds timeout); + bool IsValid(); + bool IsAllocatedInArchive() const noexcept; + float GetDistanceFromCentreOfMassToBaseOfModel(); + unsigned short GetTextureDictionaryID(); + void SetTextureDictionaryID(unsigned short usID); + void ResetTextureDictionaryID(); + static void StaticResetTextureDictionaries(); + static std::uint32_t GetTxdAssignmentGeneration() noexcept { return ms_uiTxdAssignmentGeneration; } + float GetLODDistance(); + float GetOriginalLODDistance(); + void SetLODDistance(float fDistance, bool bOverrideMaxDistance = false); + static void StaticResetLodDistances(); + void RestreamIPL(); + static void StaticFlushPendingRestreamIPL(); + static void StaticSetHooks(); + bool GetTime(char& cHourOn, char& cHourOff); + bool SetTime(char cHourOn, char cHourOff); + static void StaticResetModelTimes(); + static void ClearModelDefaults(); void SetAlphaTransparencyEnabled(bool bEnabled); bool IsAlphaTransparencyEnabled(); @@ -422,6 +434,8 @@ class CModelInfoSA : public CModelInfo static void StaticResetAlphaTransparencies(); void ModelAddRef(EModelRequestType requestType, const char* szTag); + void ModelAddRefNonBlocking(const char* szTag); + bool TryAddRefIfLoaded(); int GetRefCount(); void RemoveRef(bool bRemoveExtraGTARef = false); bool ForceUnload(); @@ -467,17 +481,23 @@ class CModelInfoSA : public CModelInfo void SetModelID(DWORD dwModelID) { m_dwModelID = dwModelID; } - RwObject* GetRwObject() { return m_pInterface ? m_pInterface->pRwObject : NULL; } + RwObject* GetRwObject() + { + auto* pInterface = GetInterface(); + return pInterface ? pInterface->pRwObject : NULL; + } // CModelInfoSA methods - void MakePedModel(char* szTexture); + void MakePedModel(const char* szTexture); + void MakePedModel(ushort usParentID); void MakeObjectModel(ushort usBaseModelID); void MakeObjectDamageableModel(std::uint16_t usBaseModelID) override; void MakeVehicleAutomobile(ushort usBaseModelID); void MakeTimedObjectModel(ushort usBaseModelID); void MakeClumpModel(ushort usBaseModelID); - void DeallocateModel(void); - unsigned int GetParentID() { return m_dwParentID; }; + void DeallocateModel(); + unsigned int GetParentID() override { return m_dwParentID; } + void SetParentID(unsigned int id) override { m_dwParentID = id; } SVehicleSupportedUpgrades GetVehicleSupportedUpgrades() { return m_ModelSupportedUpgrades; } @@ -492,8 +512,9 @@ class CModelInfoSA : public CModelInfo // Vehicle towing functions bool IsTowableBy(CModelInfo* towingModel) override; - bool IsDynamic() { return m_pInterface ? m_pInterface->usDynamicIndex != MODEL_PROPERTIES_GROUP_STATIC : false; }; + bool IsDynamic() override { return m_pInterface ? m_pInterface->usDynamicIndex != MODEL_PROPERTIES_GROUP_STATIC : false; }; bool IsDamageableAtomic() override; + void ClearCustomModel() override; static bool IsVehicleModel(std::uint32_t model) noexcept; diff --git a/Client/game_sa/CObjectGroupPhysicalPropertiesSA.h b/Client/game_sa/CObjectGroupPhysicalPropertiesSA.h index 1ff405b9e74..d5d8c9c9806 100644 --- a/Client/game_sa/CObjectGroupPhysicalPropertiesSA.h +++ b/Client/game_sa/CObjectGroupPhysicalPropertiesSA.h @@ -61,42 +61,42 @@ class CObjectGroupPhysicalPropertiesSA : public CObjectGroupPhysicalProperties void RestoreDefault(); static void RestoreDefaultValues(); - void SetMass(float fMass); - float GetMass() const; - void SetTurnMass(float fTurnMass); - float GetTurnMass() const; - void SetAirResistance(float fAirResistance); - float GetAirResistance() const; - void SetElasticity(float fElasticity); - float GetElasticity() const; - void SetBuoyancy(float fBuoyancy); - float GetBuoyancy() const; - void SetUprootLimit(float fUprootLimit); - float GetUprootLimit() const; - void SetCollisionDamageMultiplier(float fColMult); - float GetCollisionDamageMultiplier() const; - void SetCollisionDamageEffect(ObjectGroupPhysicalProperties::DamageEffect ucDamageEffect); + void SetMass(float fMass); + float GetMass() const; + void SetTurnMass(float fTurnMass); + float GetTurnMass() const; + void SetAirResistance(float fAirResistance); + float GetAirResistance() const; + void SetElasticity(float fElasticity); + float GetElasticity() const; + void SetBuoyancy(float fBuoyancy); + float GetBuoyancy() const; + void SetUprootLimit(float fUprootLimit); + float GetUprootLimit() const; + void SetCollisionDamageMultiplier(float fColMult); + float GetCollisionDamageMultiplier() const; + void SetCollisionDamageEffect(ObjectGroupPhysicalProperties::DamageEffect ucDamageEffect); ObjectGroupPhysicalProperties::DamageEffect GetCollisionDamageEffect() const; - void SetCollisionSpecialResponseCase(ObjectGroupPhysicalProperties::CollisionResponse ucResponseCase); + void SetCollisionSpecialResponseCase(ObjectGroupPhysicalProperties::CollisionResponse ucResponseCase); ObjectGroupPhysicalProperties::CollisionResponse GetCollisionSpecialResponseCase() const; - void SetCameraAvoidObject(bool bAvoid); - bool GetCameraAvoidObject() const; - void SetCausesExplosion(bool bExplodes); - bool GetCausesExplosion() const; - void SetFxType(ObjectGroupPhysicalProperties::FxType eFxType); + void SetCameraAvoidObject(bool bAvoid); + bool GetCameraAvoidObject() const; + void SetCausesExplosion(bool bExplodes); + bool GetCausesExplosion() const; + void SetFxType(ObjectGroupPhysicalProperties::FxType eFxType); ObjectGroupPhysicalProperties::FxType GetFxType() const; - void SetFxOffset(CVector vecOffset); - CVector GetFxOffset() const; - bool SetFxParticleSystem(CFxSystemBPSAInterface* pBlueprint); - void RemoveFxParticleSystem(); - void SetSmashMultiplier(float fMult); - float GetSmashMultiplier() const; - void SetBreakVelocity(CVector vecVelocity); - CVector GetBreakVelocity() const; - void SetBreakVelocityRandomness(float fRand); - float GetBreakVelocityRandomness() const; - void SetBreakMode(ObjectGroupPhysicalProperties::BreakMode eBreakMode); + void SetFxOffset(CVector vecOffset); + CVector GetFxOffset() const; + bool SetFxParticleSystem(CFxSystemBPSAInterface* pBlueprint); + void RemoveFxParticleSystem(); + void SetSmashMultiplier(float fMult); + float GetSmashMultiplier() const; + void SetBreakVelocity(CVector vecVelocity); + CVector GetBreakVelocity() const; + void SetBreakVelocityRandomness(float fRand); + float GetBreakVelocityRandomness() const; + void SetBreakMode(ObjectGroupPhysicalProperties::BreakMode eBreakMode); ObjectGroupPhysicalProperties::BreakMode GetBreakMode() const; - void SetSparksOnImpact(bool bSparks); - bool GetSparksOnImpact() const; + void SetSparksOnImpact(bool bSparks); + bool GetSparksOnImpact() const; }; diff --git a/Client/game_sa/CObjectSA.cpp b/Client/game_sa/CObjectSA.cpp index 5d29697eca8..2d2633d4235 100644 --- a/Client/game_sa/CObjectSA.cpp +++ b/Client/game_sa/CObjectSA.cpp @@ -26,19 +26,23 @@ static void CObject_PreRender(CObjectSAInterface* objectInterface) objectEntity->pEntity->SetPreRenderRequired(true); } -const std::uintptr_t RETURN_CCObject_PreRender = 0x59FD56; -static void _declspec(naked) HOOK_CCObject_PreRender() +const std::uintptr_t RETURN_CCObject_PreRender = 0x59FD56; +static void __declspec(naked) HOOK_CCObject_PreRender() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off __asm { - push ecx - call CObject_PreRender - pop ecx - sub esp, 10h - push esi - mov esi, ecx - jmp RETURN_CCObject_PreRender + push ecx + call CObject_PreRender + pop ecx + sub esp, 16 + push esi + mov esi, ecx + jmp RETURN_CCObject_PreRender } + // clang-format on } void CObjectSA::StaticSetHooks() @@ -62,10 +66,10 @@ struct CFileObjectInstance float rx; float ry; float rz; - float rr; // = 1 + float rr; // = 1 DWORD modelId; DWORD areaNumber; - long flags; // = -1 + long flags; // = -1 }; CObjectSA::CObjectSA(CObjectSAInterface* objectInterface) @@ -89,14 +93,10 @@ CObjectSA::CObjectSA(DWORD dwModel, bool bBreakingDisabled) { DWORD CObjectCreate = FUNC_CObject_Create; DWORD dwObjectPtr = 0; - _asm - { - push 1 - push dwModel - call CObjectCreate - add esp, 8 - mov dwObjectPtr, eax - } + // clang-format off + using func_t = decltype(dwObjectPtr) (__cdecl*)(decltype(dwModel), decltype(1)); +dwObjectPtr = reinterpret_cast(CObjectCreate)(dwModel, 1); + // clang-format on if (dwObjectPtr) { @@ -165,11 +165,10 @@ void CObjectSA::Explode() DWORD dwFunc = FUNC_CObject_Explode; DWORD dwThis = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } void CObjectSA::Break() @@ -177,18 +176,12 @@ void CObjectSA::Break() DWORD dwFunc = 0x5A0D90; DWORD dwThis = (DWORD)GetInterface(); - float fHitVelocity = 1000.0f; // has no direct influence, but should be high enough to trigger the break (effect) + float fHitVelocity = 1000.0f; // has no direct influence, but should be high enough to trigger the break (effect) - _asm - { - push 32h // most cases: between 30 and 37 - push 0 // colliding entity. To ignore it, we can set it to 0 - push 0B73710h // vecCollisionImpactVelocity - push 0 // vecCollisionLastPos - push fHitVelocity - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(fHitVelocity), decltype(0), decltype(0x0B73710), decltype(0), decltype(0x32)); + reinterpret_cast(dwFunc)(dwThis, fHitVelocity, 0, 0x0B73710, 0, 0x32); + // clang-format on if (IsGlass()) { @@ -197,20 +190,10 @@ void CObjectSA::Break() float fZ = 0.0f; dwFunc = FUNC_CGlass_WindowRespondsToCollision; - _asm - { - push 0 - push fZ - push fY - push fX - push 0 - push 0 - push 0 - push fHitVelocity - push dwThis - call dwFunc - add esp, 24h - } + // clang-format off + using func_t = void (__cdecl*)(decltype(dwThis), decltype(fHitVelocity), decltype(0), decltype(0), decltype(0), decltype(fX), decltype(fY), decltype(fZ), decltype(0)); + reinterpret_cast(dwFunc)(dwThis, fHitVelocity, 0, 0, 0, fX, fY, fZ, 0); + // clang-format on } } @@ -261,13 +244,10 @@ bool CObjectSA::IsGlass() DWORD dwThis = (DWORD)GetInterface(); bool bResult; - _asm - { - push dwThis - call dwFunc - mov bResult, al - add esp, 4 - } + // clang-format off + using func_t = decltype(bResult) (__cdecl*)(decltype(dwThis)); +bResult = reinterpret_cast(dwFunc)(dwThis); + // clang-format on return bResult; } diff --git a/Client/game_sa/CObjectSA.h b/Client/game_sa/CObjectSA.h index 8b1d18b35e6..91e5636b38c 100644 --- a/Client/game_sa/CObjectSA.h +++ b/Client/game_sa/CObjectSA.h @@ -16,33 +16,33 @@ class CFireSAInterface; -#define FUNC_CObject_Create 0x5A1F60 -#define FUNC_CObject_Explode 0x5A1340 +#define FUNC_CObject_Create 0x5A1F60 +#define FUNC_CObject_Explode 0x5A1340 #define FUNC_CGlass_WindowRespondsToCollision 0x71BC40 class CObjectInfo { public: - float fMass; // 0 - float fTurnMass; // 4 - float fAirResistance; // 8 - float fElasticity; // 12 - float fBuoyancy; // 16 - float fUprootLimit; // 20 - float fColDamageMultiplier; // 24 - uint8 ucColDamageEffect; // 28 - uint8 ucSpecialColResponseCase; // 29 - uint8 ucCameraAvoidObject; // 30 - uint8 ucCausesExplosion; // 31 - uint8 ucFxType; // 32 - uint8 pad1[3]; // 33 - CVector vecFxOffset; // 36 - void* pFxSystem; // ret from CParticleData::GetDataFromName // 48 - float fSmashMultiplier; // 52 - CVector vecBreakVelocity; // 56 - float fBreakVelocityRand; // 68 - uint32 uiGunBreakMode; // 72 - uint32 uiSparksOnImpact; // 76 + float fMass; // 0 + float fTurnMass; // 4 + float fAirResistance; // 8 + float fElasticity; // 12 + float fBuoyancy; // 16 + float fUprootLimit; // 20 + float fColDamageMultiplier; // 24 + uint8 ucColDamageEffect; // 28 + uint8 ucSpecialColResponseCase; // 29 + uint8 ucCameraAvoidObject; // 30 + uint8 ucCausesExplosion; // 31 + uint8 ucFxType; // 32 + uint8 pad1[3]; // 33 + CVector vecFxOffset; // 36 + void* pFxSystem; // ret from CParticleData::GetDataFromName // 48 + float fSmashMultiplier; // 52 + CVector vecBreakVelocity; // 56 + float fBreakVelocityRand; // 68 + uint32 uiGunBreakMode; // 72 + uint32 uiSparksOnImpact; // 76 }; // TODO: Find out correct size // static_assert(sizeof(CObjectInfo) == 0x50, "Invalid size for CObjectInfo"); @@ -50,13 +50,13 @@ class CObjectInfo class CObjectSAInterface : public CPhysicalSAInterface { public: - void* pObjectList; // 312 - uint8 pad1; // 316 - uint8 pad2; // 317 - uint16 pad3; // 318 + void* pObjectList; // 312 + uint8 pad1; // 316 + uint8 pad2; // 317 + uint16 pad3; // 318 // flags - uint32 b0x01 : 1; // 320 + uint32 b0x01 : 1; // 320 uint32 b0x02 : 1; uint32 b0x04 : 1; uint32 b0x08 : 1; @@ -65,16 +65,16 @@ class CObjectSAInterface : public CPhysicalSAInterface uint32 bExploded : 1; uint32 b0x80 : 1; - uint32 b0x100 : 1; // 321 + uint32 b0x100 : 1; // 321 uint32 b0x200 : 1; uint32 b0x400 : 1; - uint32 bIsTrainNearCrossing : 1; // Train crossing will be opened if flag is set (distance < 120.0f) + uint32 bIsTrainNearCrossing : 1; // Train crossing will be opened if flag is set (distance < 120.0f) uint32 b0x1000 : 1; uint32 b0x2000 : 1; uint32 bIsDoorMoving : 1; uint32 bIsDoorOpen : 1; - uint32 b0x10000 : 1; // 322 + uint32 b0x10000 : 1; // 322 uint32 bUpdateScale : 1; uint32 b0x40000 : 1; uint32 b0x80000 : 1; @@ -83,7 +83,7 @@ class CObjectSAInterface : public CPhysicalSAInterface uint32 b0x400000 : 1; uint32 b0x800000 : 1; - uint32 b0x1000000 : 1; // 323 + uint32 b0x1000000 : 1; // 323 uint32 b0x2000000 : 1; uint32 b0x4000000 : 1; uint32 b0x8000000 : 1; @@ -92,29 +92,29 @@ class CObjectSAInterface : public CPhysicalSAInterface uint32 b0x40000000 : 1; uint32 b0x80000000 : 1; - uint8 ucColDamageEffect; // 324 - uint8 pad4; // 325 - uint8 pad5; // 326 - uint8 pad6; // 327 - uint8 pad7; // 328 - uint8 pad8; // 329 - uint16 pad9; // 330 - uint8 pad10; // 332 - uint8 pad11; // 333 - uint8 pad12; // 334 - uint8 pad13; // 335 - uint32 uiObjectRemovalTime; // 336 - float fHealth; // 340 - uint32 pad15; // 344 - float fScale; // 348 - CObjectInfo* pObjectInfo; // 352 - CFireSAInterface* pFire; // 356 - uint16 pad17; // 360 - uint16 pad18; // 362 - uint32 pad19; // 364 - CEntitySAInterface* pLinkedObjectDummy; // 368 CDummyObject - Is used for dynamic objects like garage doors, train crossings etc. - uint32 pad21; // 372 - uint32 pad22; // 376 + uint8 ucColDamageEffect; // 324 + uint8 pad4; // 325 + uint8 pad5; // 326 + uint8 pad6; // 327 + uint8 pad7; // 328 + uint8 pad8; // 329 + uint16 pad9; // 330 + uint8 pad10; // 332 + uint8 pad11; // 333 + uint8 pad12; // 334 + uint8 pad13; // 335 + uint32 uiObjectRemovalTime; // 336 + float fHealth; // 340 + uint32 pad15; // 344 + float fScale; // 348 + CObjectInfo* pObjectInfo; // 352 + CFireSAInterface* pFire; // 356 + uint16 pad17; // 360 + uint16 pad18; // 362 + uint32 pad19; // 364 + CEntitySAInterface* pLinkedObjectDummy; // 368 CDummyObject - Is used for dynamic objects like garage doors, train crossings etc. + uint32 pad21; // 372 + uint32 pad22; // 376 }; static_assert(sizeof(CObjectSAInterface) == 0x17C, "Invalid size for CObjectSAInterface"); diff --git a/Client/game_sa/CPadSA.cpp b/Client/game_sa/CPadSA.cpp index b0e8401ad4d..aa30afb5263 100644 --- a/Client/game_sa/CPadSA.cpp +++ b/Client/game_sa/CPadSA.cpp @@ -62,7 +62,7 @@ void CPadSA::Disable(bool bDisable) void CPadSA::Clear() { - CControllerState cs; // create a null controller (class is inited to null) + CControllerState cs; // create a null controller (class is inited to null) SetCurrentControllerState(&cs); SetLastControllerState(&cs); } diff --git a/Client/game_sa/CPadSA.h b/Client/game_sa/CPadSA.h index cae84ef592c..3b9e0cca010 100644 --- a/Client/game_sa/CPadSA.h +++ b/Client/game_sa/CPadSA.h @@ -13,19 +13,19 @@ #include -#define MAX_HORN_HISTORY 5 -#define STEERINGBUFFERLENGTH 10 +#define MAX_HORN_HISTORY 5 +#define STEERINGBUFFERLENGTH 10 -#define FUNC_CPad_UpdatePads 0x541DD0 +#define FUNC_CPad_UpdatePads 0x541DD0 class CPadSAInterface { public: - CControllerState NewState; // 0 - CControllerState OldState; // 48 + CControllerState NewState; // 0 + CControllerState OldState; // 48 - signed short SteeringLeftRightBuffer[STEERINGBUFFERLENGTH]; // 96 - signed long DrunkDrivingBufferUsed; // 116 + signed short SteeringLeftRightBuffer[STEERINGBUFFERLENGTH]; // 96 + signed long DrunkDrivingBufferUsed; // 116 // 120 CControllerState PCTempKeyState; @@ -34,24 +34,24 @@ class CPadSAInterface // 216 CControllerState PCTempMouseState; // 264 - BYTE Phase; // needed for switching into right state (analogue, pressure sensitive etc) - WORD Mode; // Configuration of keys as selected by the player - signed short ShakeDur; // How long will shake go on for (in msecs) - WORD DisablePlayerControls; // If TRUE then the player cannot move, shoot, etc. - BYTE ShakeFreq; // What is the frequency of the shake - bool bHornHistory[MAX_HORN_HISTORY]; // Store last 4 states of the horn key TRUE on else FALSE - BYTE iCurrHornHistory; // Where to store new history value - BYTE JustOutOfFrontEnd; // Number of frames we want some of the controls disabled for. - bool bApplyBrakes; // If TRUE then apply the brakes to the player's vehicle - bool bDisablePlayerEnterCar; // Script can set this so that the Enter Car button can be used to pick up objects - bool bDisablePlayerDuck; // Script can set this - bool bDisablePlayerFireWeapon; // Script can set this - bool bDisablePlayerFireWeaponWithL1; // Script can set this - for Judith's mission where L1 is needed to pick up objects - bool bDisablePlayerCycleWeapon; // Script can set this - bool bDisablePlayerJump; // Script can set this - bool bDisablePlayerDisplayVitalStats; // Script can set this - DWORD LastTimeTouched; // The time the last input was applied by the player - signed long AverageWeapon; // Average value of the weapon button (analogue) since last reset + BYTE Phase; // needed for switching into right state (analogue, pressure sensitive etc) + WORD Mode; // Configuration of keys as selected by the player + signed short ShakeDur; // How long will shake go on for (in msecs) + WORD DisablePlayerControls; // If TRUE then the player cannot move, shoot, etc. + BYTE ShakeFreq; // What is the frequency of the shake + bool bHornHistory[MAX_HORN_HISTORY]; // Store last 4 states of the horn key TRUE on else FALSE + BYTE iCurrHornHistory; // Where to store new history value + BYTE JustOutOfFrontEnd; // Number of frames we want some of the controls disabled for. + bool bApplyBrakes; // If TRUE then apply the brakes to the player's vehicle + bool bDisablePlayerEnterCar; // Script can set this so that the Enter Car button can be used to pick up objects + bool bDisablePlayerDuck; // Script can set this + bool bDisablePlayerFireWeapon; // Script can set this + bool bDisablePlayerFireWeaponWithL1; // Script can set this - for Judith's mission where L1 is needed to pick up objects + bool bDisablePlayerCycleWeapon; // Script can set this + bool bDisablePlayerJump; // Script can set this + bool bDisablePlayerDisplayVitalStats; // Script can set this + DWORD LastTimeTouched; // The time the last input was applied by the player + signed long AverageWeapon; // Average value of the weapon button (analogue) since last reset signed long AverageEntries; DWORD NoShakeBeforeThis; diff --git a/Client/game_sa/CPedDamageResponseCalculatorSA.cpp b/Client/game_sa/CPedDamageResponseCalculatorSA.cpp index c7bd46b9b10..2b152cbd9cf 100644 --- a/Client/game_sa/CPedDamageResponseCalculatorSA.cpp +++ b/Client/game_sa/CPedDamageResponseCalculatorSA.cpp @@ -23,16 +23,10 @@ CPedDamageResponseCalculatorSA::CPedDamageResponseCalculatorSA(CEntity* pEntity, DWORD dwEntityInterface = (DWORD)pEntity->GetInterface(); DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CPedDamageResponseCalculator_Constructor; - _asm - { - mov ecx, dwThis - push b_1 - push bodyPart - push weaponType - push fDamage - push dwEntityInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwEntityInterface), decltype(fDamage), decltype(weaponType), decltype(bodyPart), decltype(b_1)); + reinterpret_cast(dwFunc)(dwThis, dwEntityInterface, fDamage, weaponType, bodyPart, b_1); + // clang-format on } CPedDamageResponseCalculatorSA::CPedDamageResponseCalculatorSA(CPedDamageResponseCalculatorSAInterface* pInterface) @@ -47,11 +41,10 @@ CPedDamageResponseCalculatorSA::~CPedDamageResponseCalculatorSA() { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CPedDamageResponseCalculator_Destructor; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on delete m_pInterface; } } @@ -62,12 +55,8 @@ void CPedDamageResponseCalculatorSA::ComputeDamageResponse(CPed* pPed, CPedDamag DWORD dwResponseInterface = (DWORD)pDamageResponse->GetInterface(); DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CPedDamageResponseCalculator_ComputeDamageResponse; - _asm - { - mov ecx, dwThis - push bSpeak - push dwResponseInterface - push dwPedInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwPedInterface), decltype(dwResponseInterface), decltype(bSpeak)); + reinterpret_cast(dwFunc)(dwThis, dwPedInterface, dwResponseInterface, bSpeak); + // clang-format on } diff --git a/Client/game_sa/CPedDamageResponseCalculatorSA.h b/Client/game_sa/CPedDamageResponseCalculatorSA.h index 40f70ccd339..713348b539c 100644 --- a/Client/game_sa/CPedDamageResponseCalculatorSA.h +++ b/Client/game_sa/CPedDamageResponseCalculatorSA.h @@ -19,9 +19,9 @@ class CEntitySAInterface; class CPed; class CPedDamageResponse; -#define FUNC_CPedDamageResponseCalculator_Constructor 0x4ad3f0 -#define FUNC_CPedDamageResponseCalculator_Destructor 0x4ad420 -#define FUNC_CPedDamageResponseCalculator_ComputeDamageResponse 0x4b5ac0 +#define FUNC_CPedDamageResponseCalculator_Constructor 0x4ad3f0 +#define FUNC_CPedDamageResponseCalculator_Destructor 0x4ad420 +#define FUNC_CPedDamageResponseCalculator_ComputeDamageResponse 0x4b5ac0 class CPedDamageResponseCalculatorSAInterface { @@ -30,7 +30,7 @@ class CPedDamageResponseCalculatorSAInterface float fDamage; ePedPieceTypes bodyPart; eWeaponType weaponType; - bool bSpeak; // refers to a CPed::Say call (the dying scream?) + bool bSpeak; // refers to a CPed::Say call (the dying scream?) }; class CPedDamageResponseCalculatorSA : public CPedDamageResponseCalculator diff --git a/Client/game_sa/CPedIKSA.h b/Client/game_sa/CPedIKSA.h index 19aca735d6e..b1558928f2a 100644 --- a/Client/game_sa/CPedIKSA.h +++ b/Client/game_sa/CPedIKSA.h @@ -49,7 +49,7 @@ typedef struct class CPedIKSAInterface { public: - CPedSAInterface* ThisPed; // 528 + CPedSAInterface* ThisPed; // 528 LimbOrientation m_torsoOrien; float m_fSlopePitch; float m_fSlopePitchLimitMult; diff --git a/Client/game_sa/CPedIntelligenceSA.cpp b/Client/game_sa/CPedIntelligenceSA.cpp index 925ac1ee47f..8a78585cb6d 100644 --- a/Client/game_sa/CPedIntelligenceSA.cpp +++ b/Client/game_sa/CPedIntelligenceSA.cpp @@ -40,14 +40,10 @@ bool CPedIntelligenceSA::TestForStealthKill(CPed* pPed, bool bUnk) DWORD dwThis = (DWORD)internalInterface; DWORD dwPed = (DWORD)pPed->GetInterface(); DWORD dwFunc = FUNC_CPedIntelligence_TestForStealthKill; - _asm - { - mov ecx, dwThis - push bUnk - push dwPed - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThis), decltype(dwPed), decltype(bUnk)); +bReturn = reinterpret_cast(dwFunc)(dwThis, dwPed, bUnk); + // clang-format on return bReturn; } @@ -69,3 +65,16 @@ CTaskSimpleUseGun* CPedIntelligenceSA::GetTaskUseGun() return nullptr; } + +CTaskSimpleFight* CPedIntelligenceSA::GetFightTask() +{ + CTaskManager* taskMgr = GetTaskManager(); + if (!taskMgr) + return nullptr; + + CTask* secondaryTask = taskMgr->GetTaskSecondary(TASK_SECONDARY_ATTACK); + if (secondaryTask && secondaryTask->GetTaskType() == TASK_SIMPLE_FIGHT) + return dynamic_cast(secondaryTask); + + return nullptr; +} diff --git a/Client/game_sa/CPedIntelligenceSA.h b/Client/game_sa/CPedIntelligenceSA.h index 59870278f26..2b0293cf8a2 100644 --- a/Client/game_sa/CPedIntelligenceSA.h +++ b/Client/game_sa/CPedIntelligenceSA.h @@ -16,7 +16,7 @@ class CPedSAInterface; class CTaskManagerSA; -#define FUNC_CPedIntelligence_TestForStealthKill 0x601E00 +#define FUNC_CPedIntelligence_TestForStealthKill 0x601E00 class CFightManagerInterface { @@ -33,11 +33,11 @@ class CPedIntelligenceSAInterface public: // CEventHandlerHistory @ + 56 CPedSAInterface* pPed; - DWORD taskManager; // +4 (really CTaskManagerSAInterface) + DWORD taskManager; // +4 (really CTaskManagerSAInterface) BYTE bPad[16]; - CFightManagerInterface* fightInterface; // +24 + CFightManagerInterface* fightInterface; // +24 BYTE bPad2[184]; - DWORD vehicleScanner; // +212 (really CVehicleScannerSAInterface) + DWORD vehicleScanner; // +212 (really CVehicleScannerSAInterface) }; class CPedIntelligenceSA : public CPedIntelligence @@ -55,4 +55,5 @@ class CPedIntelligenceSA : public CPedIntelligence bool TestForStealthKill(CPed* pPed, bool bUnk); CTaskSAInterface* SetTaskDuckSecondary(unsigned short nLengthOfDuck); CTaskSimpleUseGun* GetTaskUseGun(); + CTaskSimpleFight* GetFightTask(); }; diff --git a/Client/game_sa/CPedModelInfoSA.cpp b/Client/game_sa/CPedModelInfoSA.cpp index b41905fd9d6..c4b9f110227 100644 --- a/Client/game_sa/CPedModelInfoSA.cpp +++ b/Client/game_sa/CPedModelInfoSA.cpp @@ -29,10 +29,8 @@ void CPedModelInfoSA::SetMotionAnimGroup(AssocGroupId animGroup) { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = (DWORD)FUNC_SetMotionAnimGroup; - _asm - { - mov ecx, dwThis - push animGroup - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(animGroup)); + reinterpret_cast(dwFunc)(dwThis, animGroup); + // clang-format on } diff --git a/Client/game_sa/CPedModelInfoSA.h b/Client/game_sa/CPedModelInfoSA.h index f2d311688eb..df1229ae552 100644 --- a/Client/game_sa/CPedModelInfoSA.h +++ b/Client/game_sa/CPedModelInfoSA.h @@ -17,9 +17,9 @@ class ePedStats; typedef long AssocGroupID; -#define FUNC_SetMotionAnimGroup 0x5b3580 -#define FUNC_CPedModelInfo_Constructor 0x4c57a0 -#define VAR_CPedModelInfo_VTBL 0x85bdc0 +#define FUNC_SetMotionAnimGroup 0x5b3580 +#define FUNC_CPedModelInfo_Constructor 0x4c57a0 +#define VAR_CPedModelInfo_VTBL 0x85bdc0 // CPedModelInfo: // +36 = Motion anim group (AssocGroupID, long) @@ -41,22 +41,22 @@ class CPedModelInfoSAInterface : public CBaseModelInfoSAInterface public: CPedModelInfoSAInterface(); - BYTE pad[4]; // 32 - AssocGroupID motionAnimGroup; // 36 Motion anim group (AssocGroupID, long) - DWORD pedType; // 40 Default ped type (long) - ePedStats* pedStats; // 44 Default ped stats (ePedStats) - BYTE bCanDriveCars; // 48 Can drive cars (byte) - BYTE pad2[1]; // 49 - short pedFlags; // 50 Ped flags (short) - CColModel* pHitColModel; // 52 Hit col model (CColModel*) - BYTE bFirstRadioStation; // 56 First radio station - BYTE bSecondRadioStation; // 57 Second radio station - BYTE bIsInRace; // 58 Race (byte) - BYTE pad3[1]; // 59 - short sVoiceType; // 60 Voice type - short sFirstVoice; // 62 First voice - short sLastVoice; // 64 Last voice - short sNextVoice; // 66 Next voice + BYTE pad[4]; // 32 + AssocGroupID motionAnimGroup; // 36 Motion anim group (AssocGroupID, long) + DWORD pedType; // 40 Default ped type (long) + ePedStats* pedStats; // 44 Default ped stats (ePedStats) + BYTE bCanDriveCars; // 48 Can drive cars (byte) + BYTE pad2[1]; // 49 + short pedFlags; // 50 Ped flags (short) + CColModel* pHitColModel; // 52 Hit col model (CColModel*) + BYTE bFirstRadioStation; // 56 First radio station + BYTE bSecondRadioStation; // 57 Second radio station + BYTE bIsInRace; // 58 Race (byte) + BYTE pad3[1]; // 59 + short sVoiceType; // 60 Voice type + short sFirstVoice; // 62 First voice + short sLastVoice; // 64 Last voice + short sNextVoice; // 66 Next voice }; class CPedModelInfoSA : public CModelInfoSA, public CPedModelInfo diff --git a/Client/game_sa/CPedSA.cpp b/Client/game_sa/CPedSA.cpp index ef718d32d1e..40654df9e8b 100644 --- a/Client/game_sa/CPedSA.cpp +++ b/Client/game_sa/CPedSA.cpp @@ -20,6 +20,7 @@ #include "CProjectileInfoSA.h" #include "CWeaponStatManagerSA.h" #include "CFireManagerSA.h" +#include "gamesa_renderware.h" extern CGameSA* pGame; @@ -56,9 +57,9 @@ void CPedSA::Init() for (std::size_t i = 0; i < WEAPONSLOT_MAX; i++) m_weapons[i] = std::make_unique(&(pedInterface->Weapons[i]), this, static_cast(i)); - #ifdef PedIK_SA - this->m_pPedIK = new Cm_pPedIKSA(&(pedInterface->m_pPedIK)); - #endif +#ifdef PedIK_SA + this->m_pPedIK = new Cm_pPedIKSA(&(pedInterface->m_pPedIK)); +#endif } void CPedSA::SetModelIndex(std::uint32_t modelIndex) @@ -85,7 +86,8 @@ bool CPedSA::AddProjectile(eWeaponType weaponType, CVector origin, float force, if (!projectileInfo) return false; - return projectileInfo->AddProjectile(static_cast(this), weaponType, origin, force, const_cast(target), const_cast(targetEntity)); + return projectileInfo->AddProjectile(static_cast(this), weaponType, origin, force, const_cast(target), + const_cast(targetEntity)); } void CPedSA::DetachPedFromEntity() @@ -98,13 +100,15 @@ bool CPedSA::InternalAttachEntityToEntity(DWORD entityInteface, const CVector* p { // sDirection and fRotationLimit only apply to first-person shooting (bChangeCamera) CPedSAInterface* pedInterface = GetPedInterface(); - std::uint8_t pedType = pedInterface->bPedType; + int pedType = pedInterface->bPedType; // Hack the CPed type(?) to non-player so the camera doesn't get changed pedInterface->bPedType = 2; // CEntity *__thiscall CPed::AttachPedToEntity(CPed *this, CEntity *a2, float arg4, float a4, float a5, __int16 a6, int a7, eWeaponType a3) - ((CEntitySAInterface*(__thiscall*)(CEntitySAInterface*, CEntitySAInterface*, float, float, float, std::uint16_t, int, eWeaponType))FUNC_AttachPedToEntity)(m_pInterface, reinterpret_cast(entityInteface), position->fX, position->fY, position->fZ, 0, 0, WEAPONTYPE_UNARMED); + ((CEntitySAInterface * (__thiscall*)(CEntitySAInterface*, CEntitySAInterface*, float, float, float, std::uint16_t, int, eWeaponType)) + FUNC_AttachPedToEntity)(m_pInterface, reinterpret_cast(entityInteface), position->fX, position->fY, position->fZ, 0, 0, + WEAPONTYPE_UNARMED); // Hack the CPed type(?) to whatever it was set to pedInterface->bPedType = pedType; @@ -128,29 +132,32 @@ CVehicle* CPedSA::GetVehicle() const void CPedSA::Respawn(CVector* position, bool cameraCut) { - if (!cameraCut) + if (!cameraCut) { // CGameLogic::RestorePlayerStuffDuringResurrection // Disable calls to CCamera::SetCameraDirectlyBehindForFollowPed_CamOnAString & CCamera::RestoreWithJumpCut MemSet((void*)0x4422EA, 0x90, 20); +} // void __cdecl CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *player, __int128 a2) - ((void(__cdecl*)(CEntitySAInterface*, float, float, float, float))FUNC_RestorePlayerStuffDuringResurrection)(m_pInterface, position->fX, position->fY, position->fZ, 1.0f); + ((void(__cdecl*)(CEntitySAInterface*, float, float, float, float))FUNC_RestorePlayerStuffDuringResurrection)(m_pInterface, position->fX, position->fY, + position->fZ, 1.0f); - #ifdef SortOutStreamingAndMemory // Disabled to see if it reduces crashes - float angle = 10.0f; // angle for CRenderer::RequestObjectsInDirection +#ifdef SortOutStreamingAndMemory // Disabled to see if it reduces crashes + float angle = 10.0f; // angle for CRenderer::RequestObjectsInDirection - // void __cdecl CGameLogic::SortOutStreamingAndMemory(CVector *translation, float angle) - ((void(__cdecl*)(CVector*, float))FUNC_SortOutStreamingAndMemory)(position, angle); - #endif + // void __cdecl CGameLogic::SortOutStreamingAndMemory(CVector *translation, float angle) + ((void(__cdecl*)(CVector*, float))FUNC_SortOutStreamingAndMemory)(position, angle); +#endif // BYTE *__thiscall CPed::RemoveGogglesModel(CPed *this) ((std::uint8_t*(__thiscall*)(CEntitySAInterface*))FUNC_RemoveGogglesModel)(m_pInterface); - if (!cameraCut) + if (!cameraCut) { // Re-enable calls to CCamera::SetCameraDirectlyBehindForFollowPed_CamOnAString & CCamera::RestoreWithJumpCut // Restore original bytes MemCpy((void*)0x4422EA, "\xB9\x28\xF0\xB6\x00\xE8\x4C\x9A\x0C\x00\xB9\x28\xF0\xB6\x00\xE8\xB2\x97\x0C\x00", 20); } +} CWeapon* CPedSA::GiveWeapon(eWeaponType weaponType, std::uint32_t ammo, eWeaponSkill skill) { @@ -166,7 +173,7 @@ CWeapon* CPedSA::GiveWeapon(eWeaponType weaponType, std::uint32_t ammo, eWeaponS modelInfo->Request(BLOCKING, "CPedSA::GiveWeapon"); modelInfo->MakeCustomModel(); } - + // If the weapon is satchels, load the detonator too if (weaponType == WEAPONTYPE_REMOTE_SATCHEL_CHARGE) GiveWeapon(WEAPONTYPE_DETONATOR, 1, WEAPONSKILL_STD); @@ -175,7 +182,8 @@ CWeapon* CPedSA::GiveWeapon(eWeaponType weaponType, std::uint32_t ammo, eWeaponS // eWeaponType __thiscall CPed::GiveWeapon(CPed *this, eWeaponType weaponID, signed int ammo, int a4) // Last argument is unused - eWeaponSlot weaponSlot = ((eWeaponSlot(__thiscall*)(CEntitySAInterface*, eWeaponType, std::uint32_t, int))FUNC_GiveWeapon)(m_pInterface, weaponType, ammo, 1); + eWeaponSlot weaponSlot = + ((eWeaponSlot(__thiscall*)(CEntitySAInterface*, eWeaponType, std::uint32_t, int))FUNC_GiveWeapon)(m_pInterface, weaponType, ammo, 1); return GetWeapon(weaponSlot); } @@ -214,7 +222,7 @@ void CPedSA::RemoveWeaponModel(std::uint32_t model) void CPedSA::ClearWeapon(eWeaponType weaponType) { // BYTE *__thiscall CPed::ClearWeapon(CPed *this, eWeaponType a2) - ((std::uint8_t * (__thiscall*)(CEntitySAInterface*, eWeaponType)) FUNC_ClearWeapon)(m_pInterface, weaponType); + ((std::uint8_t*(__thiscall*)(CEntitySAInterface*, eWeaponType))FUNC_ClearWeapon)(m_pInterface, weaponType); } void CPedSA::SetIsStanding(bool standing) @@ -267,9 +275,10 @@ void CPedSA::SetCurrentWeaponSlot(eWeaponSlot weaponSlot) // void __thiscall CPlayerPed::MakeChangesForNewWeapon(CPlayerPed *this, int a3) changeWeaponFunc = FUNC_MakeChangesForNewWeapon_Slot; } - else + else { // void __thiscall CPed::SetCurrentWeapon(CPed *this, int slot) changeWeaponFunc = FUNC_SetCurrentWeapon; +} ((void(__thiscall*)(CEntitySAInterface*, eWeaponSlot))changeWeaponFunc)(m_pInterface, weaponSlot); } @@ -281,9 +290,10 @@ CVector* CPedSA::GetBonePosition(eBone bone, CVector* position) // NOTE(botder): A crash used to occur at 0x749B7B in RpClumpForAllAtomics, because the clump pointer might have been null // for a broken model. - if (entity->m_pRwObject) + if (entity->m_pRwObject) { // int __thiscall CPed::GetBonePosition(CPed *this, CVector *pPoint, int bone_id, bool bDynamic) ((void(__thiscall*)(CEntitySAInterface*, CVector*, eBone, bool))FUNC_GetBonePosition)(entity, position, bone, true); +} // Clamp to a sane range as this function can occasionally return massive values, // which causes ProcessLineOfSight to effectively freeze @@ -300,9 +310,13 @@ CVector* CPedSA::GetTransformedBonePosition(eBone bone, CVector* position) // NOTE(botder): A crash used to occur at 0x7C51A8 in RpHAnimIDGetIndex, because the clump pointer might have been null // for a broken model. - if (entity->m_pRwObject) + // NOTE: A further crash occurs at 0x7C51B9 in RpHAnimIDGetIndex when the clump exists but lacks animation hierarchy data, + // because GTA:SA's GetTransformedBonePosition doesn't check if GetAnimHierarchyFromSkinClump returns NULL. + RpClump* clump = reinterpret_cast(entity->m_pRwObject); + if (clump && GetAnimHierarchyFromSkinClump(clump)) { // RwV3D *__thiscall CPed::GetTransformedBonePosition(CPed *this, RwV3D *pointsIn, int boneId, char bUpdateBones) - ((RwV3d*(__thiscall*)(CEntitySAInterface*, CVector*, eBone, bool))FUNC_GetTransformedBonePosition)(entity, position, bone, true); + ((RwV3d * (__thiscall*)(CEntitySAInterface*, CVector*, eBone, bool)) FUNC_GetTransformedBonePosition)(entity, position, bone, true); +} // Clamp to a sane range as this function can occasionally return massive values, // which causes ProcessLineOfSight to effectively freeze @@ -350,7 +364,8 @@ void CPedSA::SetClothesTextureAndModel(const char* texture, const char* model, i // int __fastcall CPedClothesDesc::SetTextureAndModel(DWORD* this, int unknown, char* textureName, char* modelName, eClothesTexturePart texturePart) // Second argument is unused in CKeyGen::GetUppercaseKey - ((void(__fastcall*)(CPedClothesDesc*, int, const char*, const char*, std::uint8_t))FUNC_CPedClothesDesc__SetTextureAndModel)(clothes, 0, texture, model, textureType); + ((void(__fastcall*)(CPedClothesDesc*, int, const char*, const char*, std::uint8_t))FUNC_CPedClothesDesc__SetTextureAndModel)( + clothes, 0, texture, model, static_cast(textureType)); } void CPedSA::RebuildPlayer() @@ -399,7 +414,7 @@ void CPedSA::SetFootBlood(std::uint32_t footBlood) std::uint32_t CPedSA::GetFootBlood() const { CPedSAInterface* pedInterface = GetPedInterface(); - + // If the foot blood flag is activated, return the amount of foot blood return pedInterface->pedFlags.bDoBloodyFootprints ? pedInterface->timeWhenDead : 0; } @@ -515,7 +530,8 @@ float CPedSA::GetCurrentWeaponRange() const void CPedSA::AddWeaponAudioEvent(EPedWeaponAudioEventType audioEventType) { // void __thiscall CAEPedWeaponAudioEntity::AddAudioEvent(CAEPedWeaponAudioEntity *this, int audioEventId) - ((void(__thiscall*)(CPedWeaponAudioEntitySAInterface*, std::uint16_t))FUNC_CAEPedWeaponAudioEntity__AddAudioEvent)(&GetPedInterface()->weaponAudioEntity, static_cast(audioEventType)); + ((void(__thiscall*)(CPedWeaponAudioEntitySAInterface*, std::uint16_t))FUNC_CAEPedWeaponAudioEntity__AddAudioEvent)( + &GetPedInterface()->weaponAudioEntity, static_cast(audioEventType)); } bool CPedSA::IsDoingGangDriveby() const @@ -540,17 +556,18 @@ void CPedSA::SetOxygenLevel(float oxygen) void CPedSA::Say(const ePedSpeechContext& speechId, float probability) { // Call CPed::Say - ((void(__thiscall*)(CPedSAInterface*, ePedSpeechContext, int, float, bool, bool, bool))FUNC_CPed_Say)(GetPedInterface(), speechId, 0, probability, false, false, false); + ((void(__thiscall*)(CPedSAInterface*, ePedSpeechContext, int, float, bool, bool, bool))FUNC_CPed_Say)(GetPedInterface(), speechId, 0, probability, false, + false, false); } void CPedSA::GetAttachedSatchels(std::vector& satchelsList) const { // Array of projectiles objects - auto** projectilesArray = reinterpret_cast(ARRAY_CProjectile); - CProjectileSAInterface* projectileInterface = nullptr; + auto** projectilesArray = reinterpret_cast(ARRAY_CProjectile); + CProjectileSAInterface* projectileInterface = nullptr; // Array of projectiles infos - auto* projectilesInfoArray = reinterpret_cast(ARRAY_CProjectileInfo); + auto* projectilesInfoArray = reinterpret_cast(ARRAY_CProjectileInfo); CProjectileInfoSAInterface* projectileInfoInterface = nullptr; satchelsList.reserve(PROJECTILE_COUNT); @@ -576,6 +593,16 @@ void CPedSA::GetAttachedSatchels(std::vector& satchelsList) const } } +void CPedSA::SetInWaterFlags(bool inWater) +{ + auto* physicalInterface = static_cast(m_pInterface); + if (!physicalInterface) + return; + + physicalInterface->bTouchingWater = inWater; + physicalInterface->bSubmergedInWater = inWater; +} + //////////////////////////////////////////////////////////////// // // CPed_PreRenderAfterTest @@ -584,35 +611,39 @@ void CPedSA::GetAttachedSatchels(std::vector& satchelsList) const // Check if they have already been applied. // //////////////////////////////////////////////////////////////// -#define HOOKPOS_CPed_PreRenderAfterTest 0x5E65A0 +#define HOOKPOS_CPed_PreRenderAfterTest 0x5E65A0 #define HOOKSIZE_CPed_PreRenderAfterTest 15 static constexpr std::uintptr_t RETURN_CPed_PreRenderAfterTest = 0x5E65AF; static constexpr std::uintptr_t RETURN_CPed_PreRenderAfterTestSkip = 0x5E6658; -static void _declspec(naked) HOOK_CPed_PreRenderAfterTest() +static void __declspec(naked) HOOK_CPed_PreRenderAfterTest() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Replaced code - sub esp,70h - push ebx - push ebp - push esi - mov ebp, ecx - mov ecx, dword ptr [ebp+47Ch] - push edi + sub esp, 70h + push ebx + push ebp + push esi + mov ebp, ecx + mov ecx, dword ptr [ebp+47Ch] + push edi // Check what to do - mov eax, [ebp+474h] // Load m_nThirdPedFlags - test eax, 400h // check bCalledPreRender flag - jnz skip_rotation_update + mov eax, [ebp+474h] // Load m_nThirdPedFlags + test eax, 400h // check bCalledPreRender flag + jnz skip_rotation_update // Run code at start of CPed::PreRenderAfterTest - jmp RETURN_CPed_PreRenderAfterTest + jmp RETURN_CPed_PreRenderAfterTest -skip_rotation_update: + skip_rotation_update: // Skip code at start of CPed::PreRenderAfterTest - jmp RETURN_CPed_PreRenderAfterTestSkip + jmp RETURN_CPed_PreRenderAfterTestSkip } + // clang-format on } //////////////////////////////////////////////////////////////// @@ -623,28 +654,32 @@ static void _declspec(naked) HOOK_CPed_PreRenderAfterTest() // Check if it should not be called because we only wanted to do the extra rotations // //////////////////////////////////////////////////////////////// -#define HOOKPOS_CPed_PreRenderAfterTest_Mid 0x5E6669 +#define HOOKPOS_CPed_PreRenderAfterTest_Mid 0x5E6669 #define HOOKSIZE_CPed_PreRenderAfterTest_Mid 5 static constexpr std::uintptr_t RETURN_CPed_PreRenderAfterTest_Mid = 0x5E666E; static constexpr std::uintptr_t RETURN_CPed_PreRenderAfterTest_MidSkip = 0x5E766F; -static void _declspec(naked) HOOK_CPed_PreRenderAfterTest_Mid() +static void __declspec(naked) HOOK_CPed_PreRenderAfterTest_Mid() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Check what to do - movzx eax, byte ptr g_onlyUpdateRotations - test eax, eax - jnz skip_tail + movzx eax, byte ptr g_onlyUpdateRotations + test eax, eax + jnz skip_tail // Replaced code - mov al, byte ptr ds:[00B7CB89h] + mov al, byte ptr ds:[00B7CB89h] // Run code at mid of CPed::PreRenderAfterTest - jmp RETURN_CPed_PreRenderAfterTest_Mid + jmp RETURN_CPed_PreRenderAfterTest_Mid -skip_tail: + skip_tail: // Skip code at mid of CPed::PreRenderAfterTest - jmp RETURN_CPed_PreRenderAfterTest_MidSkip + jmp RETURN_CPed_PreRenderAfterTest_MidSkip } + // clang-format on } //////////////////////////////////////////////////////////////// diff --git a/Client/game_sa/CPedSA.h b/Client/game_sa/CPedSA.h index 7dbd4b0de7a..a45397f1e97 100644 --- a/Client/game_sa/CPedSA.h +++ b/Client/game_sa/CPedSA.h @@ -27,99 +27,99 @@ class CPlayerPedDataSAInterface; class CVehicleSAInterface; // CPed -#define FUNC_AttachPedToEntity 0x5E7CB0 // CPed::AttachPedToEntity -#define FUNC_DetachPedFromEntity 0x5E7EC0 // CPed::DettachPedFromEntity -#define FUNC_SetModelIndex 0x5E4880 // CPed::SetModelIndex -#define FUNC_SetIsStanding 0x4ABBE0 // CPed::SetIsStanding -#define FUNC_SetCurrentWeapon 0x5E61F0 // CPed::SetCurrentWeapon -#define FUNC_GiveWeapon 0x5E6080 // CPed::GiveWeapon -#define FUNC_ClearWeapon 0x5E62B0 // CPed::ClearWeapon -#define FUNC_RemoveWeaponModel 0x5E3990 // CPed::RemoveWeaponModel -#define FUNC_GetBonePosition 0x5E4280 // CPed::GetBonePosition -#define FUNC_GetTransformedBonePosition 0x5E01C0 // CPed::GetTransformedBonePosition -#define FUNC_TakeOffGoggles 0x5E6010 // CPed::TakeOffGoggles -#define FUNC_PutOnGoggles 0x5E3AE0 // CPed::PutOnGoggles -#define FUNC_RemoveGogglesModel 0x5DF170 // CPed::RemoveGogglesModel -#define FUNC_CPed_RemoveBodyPart 0x5F0140 // CPed::RemoveBodyPart -#define FUNC_PreRenderAfterTest 0x5E65A0 // CPed::PreRenderAfterTest +#define FUNC_AttachPedToEntity 0x5E7CB0 // CPed::AttachPedToEntity +#define FUNC_DetachPedFromEntity 0x5E7EC0 // CPed::DettachPedFromEntity +#define FUNC_SetModelIndex 0x5E4880 // CPed::SetModelIndex +#define FUNC_SetIsStanding 0x4ABBE0 // CPed::SetIsStanding +#define FUNC_SetCurrentWeapon 0x5E61F0 // CPed::SetCurrentWeapon +#define FUNC_GiveWeapon 0x5E6080 // CPed::GiveWeapon +#define FUNC_ClearWeapon 0x5E62B0 // CPed::ClearWeapon +#define FUNC_RemoveWeaponModel 0x5E3990 // CPed::RemoveWeaponModel +#define FUNC_GetBonePosition 0x5E4280 // CPed::GetBonePosition +#define FUNC_GetTransformedBonePosition 0x5E01C0 // CPed::GetTransformedBonePosition +#define FUNC_TakeOffGoggles 0x5E6010 // CPed::TakeOffGoggles +#define FUNC_PutOnGoggles 0x5E3AE0 // CPed::PutOnGoggles +#define FUNC_RemoveGogglesModel 0x5DF170 // CPed::RemoveGogglesModel +#define FUNC_CPed_RemoveBodyPart 0x5F0140 // CPed::RemoveBodyPart +#define FUNC_PreRenderAfterTest 0x5E65A0 // CPed::PreRenderAfterTest #define FUNC_CPed_Say 0x5EFFE0 // CPlayerPed -#define FUNC_MakeChangesForNewWeapon_Slot 0x60D000 // CPlayerPed::MakeChangesForNewWeapon +#define FUNC_MakeChangesForNewWeapon_Slot 0x60D000 // CPlayerPed::MakeChangesForNewWeapon // CPedClothesDesc && CClothes -#define FUNC_CPedClothesDesc__SetTextureAndModel 0x5A8080 // CPedClothesDesc::SetTextureAndModel -#define FUNC_CClothes__RebuildPlayer 0x5A82C0 // CClothes::RebuildPlayer +#define FUNC_CPedClothesDesc__SetTextureAndModel 0x5A8080 // CPedClothesDesc::SetTextureAndModel +#define FUNC_CClothes__RebuildPlayer 0x5A82C0 // CClothes::RebuildPlayer // CAEPedWeaponAudioEntity -#define FUNC_CAEPedWeaponAudioEntity__AddAudioEvent 0x4E69F0 // CAEPedWeaponAudioEntity::AddAudioEvent +#define FUNC_CAEPedWeaponAudioEntity__AddAudioEvent 0x4E69F0 // CAEPedWeaponAudioEntity::AddAudioEvent // CGameLogic -#define FUNC_RestorePlayerStuffDuringResurrection 0x442060 // CGameLogic::RestorePlayerStuffDuringResurrection -#define FUNC_SortOutStreamingAndMemory 0x441440 // CGameLogic::SortOutStreamingAndMemory +#define FUNC_RestorePlayerStuffDuringResurrection 0x442060 // CGameLogic::RestorePlayerStuffDuringResurrection +#define FUNC_SortOutStreamingAndMemory 0x441440 // CGameLogic::SortOutStreamingAndMemory class CPedFlags { public: // m_nPedFlags - unsigned int bIsStanding : 1; // is ped standing on something - unsigned int bWasStanding : 1; // was ped standing on something - unsigned int bIsLooking : 1; // is ped looking at something or in a direction - unsigned int bIsRestoringLook : 1; // is ped restoring head postion from a look - unsigned int bIsAimingGun : 1; // is ped aiming gun - unsigned int bIsRestoringGun : 1; // is ped moving gun back to default posn - unsigned int bCanPointGunAtTarget : 1; // can ped point gun at target - unsigned int bIsTalking : 1; // is ped talking(see Chat()) - - unsigned int bInVehicle : 1; // is in a vehicle - unsigned int bIsInTheAir : 1; // is in the air - unsigned int bIsLanding : 1; // is landing after being in the air - unsigned int bHitSomethingLastFrame : 1; // has been in a collision last fram - unsigned int bIsNearCar : 1; // has been in a collision last fram - unsigned int bRenderPedInCar : 1; // has been in a collision last fram - unsigned int bUpdateAnimHeading : 1; // update ped heading due to heading change during anim sequence - unsigned int bRemoveHead : 1; // waiting on AntiSpazTimer to remove head - - unsigned int bFiringWeapon : 1; // is pulling trigger - unsigned int bHasACamera : 1; // does ped possess a camera to document accidents - unsigned int bPedIsBleeding : 1; // Ped loses a lot of blood if true - unsigned int bStopAndShoot : 1; // Ped cannot reach target to attack with fist, need to use gun - unsigned int bIsPedDieAnimPlaying : 1; // is ped die animation finished so can dead now - unsigned int bStayInSamePlace : 1; // when set, ped stays put - unsigned int bKindaStayInSamePlace : 1; // when set, ped doesn't seek out opponent or cover large distances. Will still shuffle and look for cover - unsigned int bBeingChasedByPolice : 1; // use nodes for routefind - - unsigned int bNotAllowedToDuck : 1; // Is this ped allowed to duck at all? - unsigned int bCrouchWhenShooting : 1; // duck behind cars etc - unsigned int bIsDucking : 1; // duck behind cars etc - unsigned int bGetUpAnimStarted : 1; // don't want to play getup anim if under something - unsigned int bDoBloodyFootprints : 1; // unsigned int bIsLeader :1; + unsigned int bIsStanding : 1; // is ped standing on something + unsigned int bWasStanding : 1; // was ped standing on something + unsigned int bIsLooking : 1; // is ped looking at something or in a direction + unsigned int bIsRestoringLook : 1; // is ped restoring head postion from a look + unsigned int bIsAimingGun : 1; // is ped aiming gun + unsigned int bIsRestoringGun : 1; // is ped moving gun back to default posn + unsigned int bCanPointGunAtTarget : 1; // can ped point gun at target + unsigned int bIsTalking : 1; // is ped talking(see Chat()) + + unsigned int bInVehicle : 1; // is in a vehicle + unsigned int bIsInTheAir : 1; // is in the air + unsigned int bIsLanding : 1; // is landing after being in the air + unsigned int bHitSomethingLastFrame : 1; // has been in a collision last fram + unsigned int bIsNearCar : 1; // has been in a collision last fram + unsigned int bRenderPedInCar : 1; // has been in a collision last fram + unsigned int bUpdateAnimHeading : 1; // update ped heading due to heading change during anim sequence + unsigned int bRemoveHead : 1; // waiting on AntiSpazTimer to remove head + + unsigned int bFiringWeapon : 1; // is pulling trigger + unsigned int bHasACamera : 1; // does ped possess a camera to document accidents + unsigned int bPedIsBleeding : 1; // Ped loses a lot of blood if true + unsigned int bStopAndShoot : 1; // Ped cannot reach target to attack with fist, need to use gun + unsigned int bIsPedDieAnimPlaying : 1; // is ped die animation finished so can dead now + unsigned int bStayInSamePlace : 1; // when set, ped stays put + unsigned int bKindaStayInSamePlace : 1; // when set, ped doesn't seek out opponent or cover large distances. Will still shuffle and look for cover + unsigned int bBeingChasedByPolice : 1; // use nodes for routefind + + unsigned int bNotAllowedToDuck : 1; // Is this ped allowed to duck at all? + unsigned int bCrouchWhenShooting : 1; // duck behind cars etc + unsigned int bIsDucking : 1; // duck behind cars etc + unsigned int bGetUpAnimStarted : 1; // don't want to play getup anim if under something + unsigned int bDoBloodyFootprints : 1; // unsigned int bIsLeader :1; unsigned int bDontDragMeOutCar : 1; - unsigned int bStillOnValidPoly : 1; // set if the polygon the ped is on is still valid for collision + unsigned int bStillOnValidPoly : 1; // set if the polygon the ped is on is still valid for collision unsigned int bAllowMedicsToReviveMe : 1; // m_nSecondPedFlags unsigned int bResetWalkAnims : 1; - unsigned int bOnBoat : 1; // flee but only using nodes - unsigned int bBusJacked : 1; // flee but only using nodes - unsigned int bFadeOut : 1; // set if you want ped to fade out - unsigned int bKnockedUpIntoAir : 1; // has ped been knocked up into the air by a car collision - unsigned int bHitSteepSlope : 1; // has ped collided/is standing on a steep slope (surface type) - unsigned int bCullExtraFarAway : 1; // special ped only gets culled if it's extra far away (for roadblocks) - unsigned int bTryingToReachDryLand : 1; // has ped just exited boat and trying to get to dry land + unsigned int bOnBoat : 1; // flee but only using nodes + unsigned int bBusJacked : 1; // flee but only using nodes + unsigned int bFadeOut : 1; // set if you want ped to fade out + unsigned int bKnockedUpIntoAir : 1; // has ped been knocked up into the air by a car collision + unsigned int bHitSteepSlope : 1; // has ped collided/is standing on a steep slope (surface type) + unsigned int bCullExtraFarAway : 1; // special ped only gets culled if it's extra far away (for roadblocks) + unsigned int bTryingToReachDryLand : 1; // has ped just exited boat and trying to get to dry land unsigned int bCollidedWithMyVehicle : 1; - unsigned int bRichFromMugging : 1; // ped has lots of cash cause they've been mugging people - unsigned int bChrisCriminal : 1; // Is a criminal as killed during Chris' police mission (should be counted as such) - unsigned int bShakeFist : 1; // test shake hand at look entity - unsigned int bNoCriticalHits : 1; // ped cannot be killed by a single bullet - unsigned int bHasAlreadyBeenRecorded : 1; // Used for replays - unsigned int bUpdateMatricesRequired : 1; // if PedIK has altered bones so matrices need updated this frame - unsigned int bFleeWhenStanding : 1; // - - unsigned int bMiamiViceCop : 1; // - unsigned int bMoneyHasBeenGivenByScript : 1; // - unsigned int bHasBeenPhotographed : 1; // + unsigned int bRichFromMugging : 1; // ped has lots of cash cause they've been mugging people + unsigned int bChrisCriminal : 1; // Is a criminal as killed during Chris' police mission (should be counted as such) + unsigned int bShakeFist : 1; // test shake hand at look entity + unsigned int bNoCriticalHits : 1; // ped cannot be killed by a single bullet + unsigned int bHasAlreadyBeenRecorded : 1; // Used for replays + unsigned int bUpdateMatricesRequired : 1; // if PedIK has altered bones so matrices need updated this frame + unsigned int bFleeWhenStanding : 1; // + + unsigned int bMiamiViceCop : 1; // + unsigned int bMoneyHasBeenGivenByScript : 1; // + unsigned int bHasBeenPhotographed : 1; // unsigned int bIsDrowning : 1; unsigned int bDrownsInWater : 1; unsigned int bHeadStuckInCollision : 1; @@ -129,7 +129,7 @@ class CPedFlags unsigned int bDontFight : 1; unsigned int bDoomAim : 1; unsigned int bCanBeShotInVehicle : 1; - unsigned int bPushedAlongByCar : 1; // ped is getting pushed along by car collision (so don't take damage from horz velocity) + unsigned int bPushedAlongByCar : 1; // ped is getting pushed along by car collision (so don't take damage from horz velocity) unsigned int bNeverEverTargetThisPed : 1; unsigned int bThisPedIsATargetPriority : 1; unsigned int bCrouchWhenScared : 1; @@ -148,11 +148,11 @@ class CPedFlags unsigned int bKilledByStealth : 1; unsigned int bDoesntDropWeaponsWhenDead : 1; unsigned int bCalledPreRender : 1; - unsigned int bBloodPuddleCreated : 1; // Has a static puddle of blood been created yet + unsigned int bBloodPuddleCreated : 1; // Has a static puddle of blood been created yet unsigned int bPartOfAttackWave : 1; unsigned int bClearRadarBlipOnDeath : 1; - unsigned int bNeverLeavesGroup : 1; // flag that we want to test 3 extra spheres on col model - unsigned int bTestForBlockedPositions : 1; // this sets these indicator flags for various posisions on the front of the ped + unsigned int bNeverLeavesGroup : 1; // flag that we want to test 3 extra spheres on col model + unsigned int bTestForBlockedPositions : 1; // this sets these indicator flags for various posisions on the front of the ped unsigned int bRightArmBlocked : 1; unsigned int bLeftArmBlocked : 1; @@ -166,29 +166,29 @@ class CPedFlags unsigned int bWaitingForScriptBrainToLoad : 1; unsigned int bHasGroupDriveTask : 1; unsigned int bCanExitCar : 1; - unsigned int CantBeKnockedOffBike : 2; // 0=Default(harder for mission peds) 1=Never 2=Always normal(also for mission peds) + unsigned int CantBeKnockedOffBike : 2; // 0=Default(harder for mission peds) 1=Never 2=Always normal(also for mission peds) unsigned int bHasBeenRendered : 1; unsigned int bIsCached : 1; - unsigned int bPushOtherPeds : 1; // GETS RESET EVERY FRAME - SET IN TASK: want to push other peds around (eg. leader of a group or ped trying to - // get in a car) + unsigned int bPushOtherPeds : 1; // GETS RESET EVERY FRAME - SET IN TASK: want to push other peds around (eg. leader of a group or ped trying to + // get in a car) // m_nFourthPedFlags unsigned int bHasBulletProofVest : 1; unsigned int bUsingMobilePhone : 1; unsigned int bUpperBodyDamageAnimsOnly : 1; unsigned int bStuckUnderCar : 1; - unsigned int bKeepTasksAfterCleanUp : 1; // If true ped will carry on with task even after cleanup + unsigned int bKeepTasksAfterCleanUp : 1; // If true ped will carry on with task even after cleanup unsigned int bIsDyingStuck : 1; - unsigned int bIgnoreHeightCheckOnGotoPointTask : 1; // set when walking round buildings, reset when task quits + unsigned int bIgnoreHeightCheckOnGotoPointTask : 1; // set when walking round buildings, reset when task quits unsigned int bForceDieInCar : 1; unsigned int bCheckColAboveHead : 1; unsigned int bIgnoreWeaponRange : 1; unsigned int bDruggedUp : 1; - unsigned int bWantedByPolice : 1; // if this is set, the cops will always go after this ped when they are doing a KillCriminal task + unsigned int bWantedByPolice : 1; // if this is set, the cops will always go after this ped when they are doing a KillCriminal task unsigned int bSignalAfterKill : 1; unsigned int bCanClimbOntoBoat : 1; - unsigned int bPedHitWallLastFrame : 1; // useful to store this so that AI knows (normal will still be available) + unsigned int bPedHitWallLastFrame : 1; // useful to store this so that AI knows (normal will still be available) unsigned int bIgnoreHeightDifferenceFollowingNodes : 1; unsigned int bMoveAnimSpeedHasBeenSetByTask : 1; @@ -196,7 +196,7 @@ class CPedFlags unsigned int bJustGotOffTrain : 1; unsigned int bDeathPickupsPersist : 1; unsigned int bTestForShotInVehicle : 1; - unsigned int bUsedForReplay : 1; // This ped is controlled by replay and should be removed when replay is done. + unsigned int bUsedForReplay : 1; // This ped is controlled by replay and should be removed when replay is done. }; class CPedAcquaintanceSAInterface @@ -229,117 +229,117 @@ static_assert(sizeof(CPedStatSAInterface) == 0x34, "Invalid size for CPedStatSAI class CPedSAInterface : public CPhysicalSAInterface { public: - CPedSoundEntitySAInterface pedAudio; // CAEPedAudioEntity - CPedSoundSAInterface pedSound; // CAEPedSpeechAudioEntity - CPedWeaponAudioEntitySAInterface weaponAudioEntity; // CAEPedWeaponAudioEntity - - std::uint8_t unk_43C[36]; - CPedSAInterface* roadRageWith; - std::uint8_t unk_464[8]; - - CPedFlags pedFlags; - CPedIntelligenceSAInterface* pPedIntelligence; - CPlayerPedDataSAInterface* pPlayerData; - - std::uint8_t createdBy; - void* pedNodes[19]; // AnimBlendFrameData* - int iMoveAnimGroup; - CVector2D vecAnimMovingShiftLocal; - CPedAcquaintanceSAInterface pedAcquaintance; - - RpClump* pWeaponObject; - RwFrame* pGunflashObject; - RpClump* pGogglesObject; - bool* pGogglesState; - - std::int16_t weaponGunflashStateRightHand; - std::int16_t weaponGunFlashAlphaProgMP1; - std::int16_t weaponGunflashStateLeftHand; - std::int16_t weaponGunFlashAlphaProgMP2; - - CPedIKSAInterface pedIK; - int unk_52C; - - int pedState; - int moveState; - int swimmingMoveState; - - int unk_53C; - float fHealth; - float fMaxHealth; - float fArmor; - - std::uint32_t timeTillWeNeedThisPed; - CVector2D vecAnimMovingShift; - float fCurrentRotation; - float fTargetRotation; - float fRotationSpeed; - float fMoveAnim; - - CEntitySAInterface* pContactEntity; - CVector unk_56C; - CVector unk_578; - CEntitySAInterface* pLastContactEntity; - - CVehicleSAInterface* pLastVehicle; - CVehicleSAInterface* pVehicle; - CVehicleSAInterface* vehicleDeadInFrontOf; - - int unk_594; - int bPedType; // ped type? 0 = player, >1 = ped? - CPedStatSAInterface* pPedStats; - CWeaponSAInterface Weapons[WEAPONSLOT_MAX]; - eWeaponType savedWeapon; - eWeaponType delayedWeapon; - std::uint32_t delayedWeaponAmmo; - std::uint8_t bCurrentWeaponSlot; - std::uint8_t weaponShootingRate; - std::uint8_t weaponAccuracy; - - CEntitySAInterface* pTargetedObject; - int unk_720; - int unk_724; - int unk_728; - - eWeaponSkill weaponSkill; - eFightingStyle bFightingStyle; - std::uint8_t bFightingStyleExtra; - std::uint8_t bPad7; - - CFireSAInterface* pFireOnPed; - float fireDamageMult; - - CEntitySAInterface* pLookAtEntity; - float fLookHeading; - - std::uint32_t weaponModelID; - int unk_744; - std::uint32_t lookTime; - int unk_74C; - std::uint32_t timeWhenDead; // death time in MS - std::uint8_t bodyPartToRemove; - std::int16_t unk_755; - std::int16_t moneyCount; - std::int16_t unk_758; - int unk_75C; - std::uint8_t lastWeaponDamage; - std::uint8_t unk_761[3]; - CEntitySAInterface* lastDamagedEntity; - std::int16_t unk_768; - - CVector vecTurretOffset; - float fTurretAngleA; - float fTurretAngleB; - std::uint32_t turretPosnMode; - std::uint32_t turretAmmo; - - void* pCoverPoint; // CCoverPoint* - void* pEnex; // CEntryExit* - float fRemovalDistMultiplier; - std::int16_t specialModelIndex; // StreamedScriptBrainToLoad - - std::int16_t unk_796; - int unk_798; + CPedSoundEntitySAInterface pedAudio; // CAEPedAudioEntity + CPedSoundSAInterface pedSound; // CAEPedSpeechAudioEntity + CPedWeaponAudioEntitySAInterface weaponAudioEntity; // CAEPedWeaponAudioEntity + + std::uint8_t unk_43C[36]; + CPedSAInterface* roadRageWith; + std::uint8_t unk_464[8]; + + CPedFlags pedFlags; + CPedIntelligenceSAInterface* pPedIntelligence; + CPlayerPedDataSAInterface* pPlayerData; + + std::uint8_t createdBy; + void* pedNodes[19]; // AnimBlendFrameData* + int iMoveAnimGroup; + CVector2D vecAnimMovingShiftLocal; + CPedAcquaintanceSAInterface pedAcquaintance; + + RpClump* pWeaponObject; + RwFrame* pGunflashObject; + RpClump* pGogglesObject; + bool* pGogglesState; + + std::int16_t weaponGunflashStateRightHand; + std::int16_t weaponGunFlashAlphaProgMP1; + std::int16_t weaponGunflashStateLeftHand; + std::int16_t weaponGunFlashAlphaProgMP2; + + CPedIKSAInterface pedIK; + int unk_52C; + + int pedState; + PedMoveState::Enum moveState; + int swimmingMoveState; + + int unk_53C; + float fHealth; + float fMaxHealth; + float fArmor; + + std::uint32_t timeTillWeNeedThisPed; + CVector2D vecAnimMovingShift; + float fCurrentRotation; + float fTargetRotation; + float fRotationSpeed; + float fMoveAnim; + + CEntitySAInterface* pContactEntity; // m_standingOnEntity + CVector unk_56C; + CVector unk_578; + CEntitySAInterface* pLastContactEntity; // m_contactEntity + + CVehicleSAInterface* pLastVehicle; + CVehicleSAInterface* pVehicle; + CVehicleSAInterface* vehicleDeadInFrontOf; + + int unk_594; + int bPedType; // ped type? 0 = player, >1 = ped? + CPedStatSAInterface* pPedStats; + CWeaponSAInterface Weapons[WEAPONSLOT_MAX]; + eWeaponType savedWeapon; + eWeaponType delayedWeapon; + std::uint32_t delayedWeaponAmmo; + std::uint8_t bCurrentWeaponSlot; + std::uint8_t weaponShootingRate; + std::uint8_t weaponAccuracy; + + CEntitySAInterface* pTargetedObject; + int unk_720; + int unk_724; + int unk_728; + + eWeaponSkill weaponSkill; + eFightingStyle bFightingStyle; + std::uint8_t bFightingStyleExtra; + std::uint8_t bPad7; + + CFireSAInterface* pFireOnPed; + float fireDamageMult; + + CEntitySAInterface* pLookAtEntity; + float fLookHeading; + + std::uint32_t weaponModelID; + int unk_744; + std::uint32_t lookTime; + int unk_74C; + std::uint32_t timeWhenDead; // death time in MS + std::uint8_t bodyPartToRemove; + std::int16_t unk_755; + std::int16_t moneyCount; + std::int16_t unk_758; + int unk_75C; + std::uint8_t lastWeaponDamage; + std::uint8_t unk_761[3]; + CEntitySAInterface* lastDamagedEntity; + std::int16_t unk_768; + + CVector vecTurretOffset; + float fTurretAngleA; + float fTurretAngleB; + std::uint32_t turretPosnMode; + std::uint32_t turretAmmo; + + void* pCoverPoint; // CCoverPoint* + void* pEnex; // CEntryExit* + float fRemovalDistMultiplier; + std::int16_t specialModelIndex; // StreamedScriptBrainToLoad + + std::int16_t unk_796; + int unk_798; }; static_assert(sizeof(CPedSAInterface) == 0x79C, "Invalid size for CPedSAInterface"); @@ -355,7 +355,7 @@ class CPedSA : public virtual CPed, public virtual CPhysicalSA CPedSAInterface* GetPedInterface() const noexcept { return static_cast(m_pInterface); } void Init(); - + void SetModelIndex(std::uint32_t modelIndex) override; bool InternalAttachEntityToEntity(DWORD entityInterface, const CVector* position, const CVector* rotation) override; @@ -384,8 +384,8 @@ class CPedSA : public virtual CPed, public virtual CPhysicalSA void SetIsStanding(bool standing) override; - std::uint32_t GetType() const noexcept override { return m_type; } - void SetType(std::uint32_t type) noexcept { m_type = type; } + std::uint32_t GetType() const noexcept override { return m_type; } + void SetType(std::uint32_t type) noexcept { m_type = type; } CPedIntelligence* GetPedIntelligence() const noexcept override { return m_pedIntelligence.get(); } CPedSound* GetPedSound() const noexcept override { return m_pedSound.get(); } @@ -409,7 +409,7 @@ class CPedSA : public virtual CPed, public virtual CPhysicalSA bool IsInWater() const override; std::uint32_t GetCantBeKnockedOffBike() const override { return GetPedInterface()->pedFlags.CantBeKnockedOffBike; } - void SetCantBeKnockedOffBike(std::uint32_t cantBeKnockedOffBike) override { GetPedInterface()->pedFlags.CantBeKnockedOffBike = cantBeKnockedOffBike; } + void SetCantBeKnockedOffBike(std::uint32_t cantBeKnockedOffBike) override { GetPedInterface()->pedFlags.CantBeKnockedOffBike = cantBeKnockedOffBike; } bool IsWearingGoggles() const override { return GetPedInterface()->pGogglesObject != nullptr; } void SetGogglesState(bool isWearingThem) override; @@ -421,17 +421,18 @@ class CPedSA : public virtual CPed, public virtual CPhysicalSA void SetFightingStyle(eFightingStyle style, std::uint8_t styleExtra = 6) override; CEntity* GetContactEntity() const override; + bool IsStandingOnEntity() const override { return GetPedInterface()->pContactEntity != nullptr; }; - int GetRunState() const override { return GetPedInterface()->moveState; } + PedMoveState::Enum GetMoveState() const override { return GetPedInterface()->moveState; } - bool GetCanBeShotInVehicle() const override{ return GetPedInterface()->pedFlags.bCanBeShotInVehicle; } + bool GetCanBeShotInVehicle() const override { return GetPedInterface()->pedFlags.bCanBeShotInVehicle; } bool GetTestForShotInVehicle() const override { return GetPedInterface()->pedFlags.bTestForShotInVehicle; } void SetCanBeShotInVehicle(bool shot) override { GetPedInterface()->pedFlags.bCanBeShotInVehicle = shot; } void SetTestForShotInVehicle(bool test) override { GetPedInterface()->pedFlags.bTestForShotInVehicle = test; } std::uint8_t GetOccupiedSeat() const noexcept override { return m_occupiedSeat; } - void SetOccupiedSeat(std::uint8_t seat) noexcept override { m_occupiedSeat = seat; } + void SetOccupiedSeat(std::uint8_t seat) noexcept override { m_occupiedSeat = seat; } void RemoveBodyPart(std::uint8_t boneID, std::uint8_t direction) override; @@ -470,14 +471,16 @@ class CPedSA : public virtual CPed, public virtual CPhysicalSA std::unique_ptr GetPedIK() override { return std::make_unique(GetPedIKInterface()); } CEntitySAInterface* GetTargetedObject() const override { return GetPedInterface()->pTargetedObject; } - PedState GetPedState() const override { return static_cast(GetPedInterface()->pedState); } + PedState GetPedState() const override { return static_cast(GetPedInterface()->pedState); } + + void GetAttachedSatchels(std::vector& satchelsList) const override; - void GetAttachedSatchels(std::vector &satchelsList) const override; + void SetInWaterFlags(bool inWater) override; static void StaticSetHooks(); private: - void ApplySwimAndSlopeRotations(); + void ApplySwimAndSlopeRotations(); protected: int m_iCustomMoveAnim{0}; diff --git a/Client/game_sa/CPedSoundSA.cpp b/Client/game_sa/CPedSoundSA.cpp index a2faafb3ff9..47a21d116bd 100644 --- a/Client/game_sa/CPedSoundSA.cpp +++ b/Client/game_sa/CPedSoundSA.cpp @@ -43,12 +43,10 @@ bool CPedSoundSA::IsSpeechDisabled() bool bReturn; DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAEPedSound__IsSpeedDisabled; - _asm - { - mov ecx, dwThis - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThis) ); +bReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on return bReturn; } @@ -56,23 +54,20 @@ void CPedSoundSA::EnablePedSpeech() { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAEPedSound__EnablePedSpeech; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } void CPedSoundSA::DisablePedSpeech(bool bStopCurrent) { DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CAEPedSound__DisablePedSpeech; - _asm - { - mov ecx, dwThis - push bStopCurrent - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(bStopCurrent)); + reinterpret_cast(dwFunc)(dwThis, bStopCurrent); + // clang-format on } short CPedSoundSA::GetVoiceTypeIDFromName(const char* szVoiceTypeName) @@ -80,13 +75,10 @@ short CPedSoundSA::GetVoiceTypeIDFromName(const char* szVoiceTypeName) DWORD dwFunc = (DWORD)FUNC_CAEPedSound__GetAudioPedType; short sVoiceTypeID; - _asm - { - push szVoiceTypeName - call dwFunc - add esp, 4 - mov sVoiceTypeID, ax - } + // clang-format off + using func_t = decltype(sVoiceTypeID) (__cdecl*)(decltype(szVoiceTypeName)); +sVoiceTypeID = reinterpret_cast(dwFunc)(szVoiceTypeName); + // clang-format on return sVoiceTypeID; } @@ -95,7 +87,8 @@ short CPedSoundSA::GetVoiceIDFromName(short sVoiceTypeID, const char* szVoiceNam DWORD dwFunc = (DWORD)FUNC_CAEPedSound__GetVoice; short sVoiceID; - _asm + // clang-format off + __asm { movzx eax, sVoiceTypeID push eax @@ -104,6 +97,7 @@ short CPedSoundSA::GetVoiceIDFromName(short sVoiceTypeID, const char* szVoiceNam add esp, 8 mov sVoiceID, ax } + // clang-format on return sVoiceID; } diff --git a/Client/game_sa/CPedSoundSA.h b/Client/game_sa/CPedSoundSA.h index 84abf355d37..00f91c6667f 100644 --- a/Client/game_sa/CPedSoundSA.h +++ b/Client/game_sa/CPedSoundSA.h @@ -18,20 +18,20 @@ class CPedSAInterface; -#define FUNC_CAEPedSound__GetVoice 0x4E3CD0 // 4E3CD0 ; public: static short __cdecl CAEPedSound::GetVoice(char *,short) -#define FUNC_CAEPedSound__GetAudioPedType 0x4E3C60 // 4E3C60 ; public: static short __cdecl CAEPedSound::GetAudioPedType(char *) -#define FUNC_CAEPedSound__SetPed 0x4E68D0 // 4E69D0 ; public: void __thiscall CAEPedSound::SetPed(CPedSAInterface *) -#define FUNC_CAEPedSound__EnablePedSpeech 0x4e3f70 -#define FUNC_CAEPedSound__DisablePedSpeech 0x4e56d0 -#define FUNC_CAEPedSound__IsSpeedDisabled 0x4e34d0 +#define FUNC_CAEPedSound__GetVoice 0x4E3CD0 // 4E3CD0 ; public: static short __cdecl CAEPedSound::GetVoice(char *,short) +#define FUNC_CAEPedSound__GetAudioPedType 0x4E3C60 // 4E3C60 ; public: static short __cdecl CAEPedSound::GetAudioPedType(char *) +#define FUNC_CAEPedSound__SetPed 0x4E68D0 // 4E69D0 ; public: void __thiscall CAEPedSound::SetPed(CPedSAInterface *) +#define FUNC_CAEPedSound__EnablePedSpeech 0x4e3f70 +#define FUNC_CAEPedSound__DisablePedSpeech 0x4e56d0 +#define FUNC_CAEPedSound__IsSpeedDisabled 0x4e34d0 -#define VAR_CAEPedSound__VoiceTypeNames 0x8C8108 // Array of 6 pointers to strings +#define VAR_CAEPedSound__VoiceTypeNames 0x8C8108 // Array of 6 pointers to strings -#define VAR_CAEPedSound__VoiceNames_GEN 0x8AE6A8 // 20 bytes per voice name -#define VAR_CAEPedSound__VoiceNames_EMG 0x8BA0D8 -#define VAR_CAEPedSound__VoiceNames_PLAYER 0x8BBD40 -#define VAR_CAEPedSound__VoiceNames_GANG 0x8BE1A8 -#define VAR_CAEPedSound__VoiceNames_GFD 0x8C4120 +#define VAR_CAEPedSound__VoiceNames_GEN 0x8AE6A8 // 20 bytes per voice name +#define VAR_CAEPedSound__VoiceNames_EMG 0x8BA0D8 +#define VAR_CAEPedSound__VoiceNames_PLAYER 0x8BBD40 +#define VAR_CAEPedSound__VoiceNames_GANG 0x8BE1A8 +#define VAR_CAEPedSound__VoiceNames_GFD 0x8C4120 #define NUM_PED_VOICE_TYPES 5 @@ -45,11 +45,11 @@ enum ePedVoiceType : std::uint16_t PED_TYPE_SPC }; -#define NUM_GEN_VOICES 209 -#define NUM_EMG_VOICES 46 -#define NUM_PLAYER_VOICES 20 -#define NUM_GANG_VOICES 52 -#define NUM_GFD_VOICES 18 +#define NUM_GEN_VOICES 209 +#define NUM_EMG_VOICES 46 +#define NUM_PLAYER_VOICES 20 +#define NUM_GANG_VOICES 52 +#define NUM_GFD_VOICES 18 typedef struct { @@ -114,7 +114,7 @@ static_assert(sizeof(CPedSoundEntitySAInterface) == 0x15C, "Invalid size for CPe class CPedWeaponAudioEntitySAInterface : public CAEWeaponAudioEntitySAInterface { public: - bool m_bIsInitialised; + bool m_bIsInitialised; CPedSAInterface* m_ped; }; static_assert(sizeof(CPedWeaponAudioEntitySAInterface) == 0xA8, "Invalid size for CPedWeaponAudioEntitySAInterface"); diff --git a/Client/game_sa/CPhysicalSA.cpp b/Client/game_sa/CPhysicalSA.cpp index a9a104364b9..f352935adfb 100644 --- a/Client/game_sa/CPhysicalSA.cpp +++ b/Client/game_sa/CPhysicalSA.cpp @@ -20,11 +20,18 @@ extern CGameSA* pGame; CRect* CPhysicalSAInterface::GetBoundRect_(CRect* pRect) { + // Validate collision model before accessing radius CVector boundCentre; CEntitySAInterface::GetBoundCentre(&boundCentre); - float fRadius = CModelInfoSAInterface::GetModelInfo(m_nModelIndex)->pColModel->m_sphere.m_radius; + CBaseModelInfoSAInterface* pModelInfo = CModelInfoSAInterface::GetModelInfo(m_nModelIndex); + + // Validate model info and collision model before accessing + if (!pModelInfo || !pModelInfo->pColModel) + return pRect; + + float fRadius = pModelInfo->pColModel->m_sphere.m_radius; *pRect = CRect(boundCentre.fX - fRadius, boundCentre.fY - fRadius, boundCentre.fX + fRadius, boundCentre.fY + fRadius); - pRect->FixIncorrectTopLeft(); // Fix #1613: custom map collision crashes in CPhysical class (infinite loop) + pRect->FixIncorrectTopLeft(); // Fix #1613: custom map collision crashes in CPhysical class (infinite loop) return pRect; } @@ -75,12 +82,10 @@ CVector* CPhysicalSA::GetMoveSpeedInternal(CVector* vecMoveSpeed) DWORD dwFunc = FUNC_GetMoveSpeed; DWORD dwThis = (DWORD)((CPhysicalSAInterface*)GetInterface()); DWORD dwReturn = 0; - _asm - { - mov ecx, dwThis - call dwFunc - mov dwReturn, eax - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(dwThis) ); +dwReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on MemCpyFast(vecMoveSpeed, (void*)dwReturn, sizeof(CVector)); return vecMoveSpeed; } @@ -90,12 +95,10 @@ CVector* CPhysicalSA::GetTurnSpeedInternal(CVector* vecTurnSpeed) DWORD dwFunc = FUNC_GetTurnSpeed; DWORD dwThis = (DWORD)((CPhysicalSAInterface*)GetInterface()); DWORD dwReturn = 0; - _asm - { - mov ecx, dwThis - call dwFunc - mov dwReturn, eax - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(dwThis) ); +dwReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on MemCpyFast(vecTurnSpeed, (void*)dwReturn, sizeof(CVector)); return vecTurnSpeed; } @@ -106,12 +109,10 @@ void CPhysicalSA::SetMoveSpeed(const CVector& vecMoveSpeed) noexcept DWORD dwThis = (DWORD)((CPhysicalSAInterface*)GetInterface()); DWORD dwReturn = 0; - __asm - { - mov ecx, dwThis - call dwFunc - mov dwReturn, eax - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(dwThis) ); +dwReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on MemCpyFast((void*)dwReturn, &vecMoveSpeed, sizeof(CVector)); if (GetInterface()->nType == ENTITY_TYPE_OBJECT) @@ -197,11 +198,10 @@ void CPhysicalSA::ProcessCollision() DWORD dwFunc = FUNC_ProcessCollision; DWORD dwThis = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } void CPhysicalSA::AddToMovingList() @@ -209,11 +209,10 @@ void CPhysicalSA::AddToMovingList() DWORD dwFunc = FUNC_CPhysical_AddToMovingList; DWORD dwThis = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } float CPhysicalSA::GetDamageImpulseMagnitude() @@ -237,6 +236,8 @@ CEntity* CPhysicalSA::GetDamageEntity() return nullptr; } +// Stores a raw pointer to the entity. Call ResetLastDamage() when the entity +// is destroyed to prevent dangling pointer access. void CPhysicalSA::SetDamageEntity(CEntity* pEntity) { CEntitySA* pEntitySA = dynamic_cast(pEntity); @@ -244,6 +245,7 @@ void CPhysicalSA::SetDamageEntity(CEntity* pEntity) ((CPhysicalSAInterface*)GetInterface())->m_pCollidedEntity = pEntitySA->GetInterface(); } +// Clears the damage entity pointer and magnitude void CPhysicalSA::ResetLastDamage() { ((CPhysicalSAInterface*)GetInterface())->m_fDamageImpulseMagnitude = 0.0f; @@ -279,15 +281,10 @@ void CPhysicalSA::DetachEntityFromEntity(float fUnkX, float fUnkY, float fUnkZ, if (((CPhysicalSAInterface*)GetInterface())->m_pAttachedEntity == NULL) return; - _asm - { - push bUnk - push fUnkZ - push fUnkY - push fUnkX - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(fUnkX), decltype(fUnkY), decltype(fUnkZ), decltype(bUnk)); + reinterpret_cast(dwFunc)(dwThis, fUnkX, fUnkY, fUnkZ, bUnk); + // clang-format on } bool CPhysicalSA::InternalAttachEntityToEntity(DWORD dwEntityInterface, const CVector* vecPosition, const CVector* vecRotation) @@ -295,7 +292,8 @@ bool CPhysicalSA::InternalAttachEntityToEntity(DWORD dwEntityInterface, const CV DWORD dwFunc = FUNC_AttachEntityToEntity; DWORD dwThis = (DWORD)GetInterface(); DWORD dwReturn = 0; - _asm + // clang-format off + __asm { mov ecx, vecRotation push [ecx+8] @@ -310,6 +308,7 @@ bool CPhysicalSA::InternalAttachEntityToEntity(DWORD dwEntityInterface, const CV call dwFunc mov dwReturn, eax } + // clang-format on return (dwReturn != NULL); } diff --git a/Client/game_sa/CPhysicalSA.h b/Client/game_sa/CPhysicalSA.h index c1de3599375..c81fc318639 100644 --- a/Client/game_sa/CPhysicalSA.h +++ b/Client/game_sa/CPhysicalSA.h @@ -18,26 +18,26 @@ class CColPointSAInterface; -#define FUNC_GetMoveSpeed 0x404460 -#define FUNC_GetTurnSpeed 0x470030 -#define FUNC_ProcessCollision 0x54DFB0 -#define FUNC_AttachEntityToEntity 0x54D570 -#define FUNC_DetatchEntityFromEntity 0x5442F0 -#define FUNC_CPhysical_AddToMovingList 0x542800 -#define FUNC_CPhysical_RemoveFromMovingList 0x542860 +#define FUNC_GetMoveSpeed 0x404460 +#define FUNC_GetTurnSpeed 0x470030 +#define FUNC_ProcessCollision 0x54DFB0 +#define FUNC_AttachEntityToEntity 0x54D570 +#define FUNC_DetatchEntityFromEntity 0x5442F0 +#define FUNC_CPhysical_AddToMovingList 0x542800 +#define FUNC_CPhysical_RemoveFromMovingList 0x542860 -#define PHYSICAL_MAXNOOFCOLLISIONRECORDS 6 -#define PHYSICAL_MAXMASS 99999.0 +#define PHYSICAL_MAXNOOFCOLLISIONRECORDS 6 +#define PHYSICAL_MAXMASS 99999.0 class CPhysicalSAInterface : public CEntitySAInterface { virtual std::int32_t ProcessEntityCollision(CEntitySAInterface* entity, CColPointSAInterface* colPoint) = 0; public: - float pad1; // 56 - uint32 pad2; // 60 + float pad1; // 56 + uint32 pad2; // 60 - uint32 b0x01 : 1; // 64 + uint32 b0x01 : 1; // 64 uint32 bApplyGravity : 1; uint32 bDisableFriction : 1; uint32 bCollidable : 1; @@ -46,17 +46,17 @@ class CPhysicalSAInterface : public CEntitySAInterface uint32 b0x40 : 1; uint32 b0x80 : 1; - uint32 bSubmergedInWater : 1; // 65 + uint32 bSubmergedInWater : 1; // 65 uint32 bOnSolidSurface : 1; uint32 bBroken : 1; - uint32 b0x800 : 1; // ref @ 0x6F5CF0 - uint32 b0x1000 : 1; // - uint32 bDontApplySpeed : 1; // - uint32 b0x4000 : 1; // - uint32 b0x8000 : 1; // - - uint32 b0x10000 : 1; // 66 - uint32 b0x20000 : 1; // ref @ CPhysical__processCollision + uint32 b0x800 : 1; // ref @ 0x6F5CF0 + uint32 b0x1000 : 1; // + uint32 bDontApplySpeed : 1; // + uint32 b0x4000 : 1; // + uint32 b0x8000 : 1; // + + uint32 b0x10000 : 1; // 66 + uint32 b0x20000 : 1; // ref @ CPhysical__processCollision uint32 bBulletProof : 1; uint32 bFireProof : 1; uint32 bCollisionProof : 1; @@ -64,7 +64,7 @@ class CPhysicalSAInterface : public CEntitySAInterface uint32 bInvulnerable : 1; uint32 bExplosionProof : 1; - uint32 b0x1000000 : 1; // 67 + uint32 b0x1000000 : 1; // 67 uint32 bAttachedToEntity : 1; uint32 b0x4000000 : 1; uint32 bTouchingWater : 1; @@ -73,44 +73,44 @@ class CPhysicalSAInterface : public CEntitySAInterface uint32 b0x40000000 : 1; uint32 b0x80000000 : 1; - CVector m_vecLinearVelocity; // 68 - CVector m_vecAngularVelocity; // 80 - CVector m_vecCollisionLinearVelocity; // 92 - CVector m_vecCollisionAngularVelocity; // 104 - CVector m_vecOffsetUnk5; // 116 - CVector m_vecOffsetUnk6; // 128 - float m_fMass; // 140 - float m_fTurnMass; // 144 - float m_pad1; // 148 - float m_fAirResistance; // 152 - float m_fElasticity; // 156 - float m_fBuoyancyConstant; // 160 - CVector m_vecCenterOfMass; // 164 - uint32* m_pCollisionList; // 176 - uint32* m_pMovingList; // 180 - uint8 m_ucColFlag1; // 184 - uint8 m_ucCollisionState; // 185 - uint8 m_ucCollisionContactSurfaceType; // 186 - uint8 m_ucColFlag4; // 187 - CEntity* pLastContactedEntity[4]; // 188 - float m_field_cc; // 204 - float m_pad4c; // 208 - float m_pad4d; // 212 - float m_fDamageImpulseMagnitude; // 216 - CEntitySAInterface* m_pCollidedEntity; // 220 - CVector m_vecCollisionImpactVelocity; // 224 - CVector m_vecCollisionPosition; // 236 - uint16 m_usPieceType; // 248 - uint16 m_pad3; // 250 - CEntitySAInterface* m_pAttachedEntity; // 252 - CVector m_vecAttachedOffset; // 256 - CVector m_vecAttachedRotation; // 268 - CVector m_vecUnk; // 280 - uint32 m_pad4; // 292 - CPtrNodeDoubleLink* m_pControlCodeNodeLink; // 296 - float m_fLighting; // 300 surface brightness - float m_fLighting2; // 304 dynamic lighting (unused, always set to 0 in the GTA code) - class CShadowDataSA* m_pShadowData; // 308 + CVector m_vecLinearVelocity; // 68 + CVector m_vecAngularVelocity; // 80 + CVector m_vecCollisionLinearVelocity; // 92 + CVector m_vecCollisionAngularVelocity; // 104 + CVector m_vecOffsetUnk5; // 116 + CVector m_vecOffsetUnk6; // 128 + float m_fMass; // 140 + float m_fTurnMass; // 144 + float m_pad1; // 148 + float m_fAirResistance; // 152 + float m_fElasticity; // 156 + float m_fBuoyancyConstant; // 160 + CVector m_vecCenterOfMass; // 164 + uint32* m_pCollisionList; // 176 + uint32* m_pMovingList; // 180 + uint8 m_ucColFlag1; // 184 + uint8 m_ucCollisionState; // 185 + uint8 m_ucCollisionContactSurfaceType; // 186 + uint8 m_ucColFlag4; // 187 + CEntity* pLastContactedEntity[4]; // 188 + float m_field_cc; // 204 + float m_pad4c; // 208 + float m_pad4d; // 212 + float m_fDamageImpulseMagnitude; // 216 + CEntitySAInterface* m_pCollidedEntity; // 220 + CVector m_vecCollisionImpactVelocity; // 224 + CVector m_vecCollisionPosition; // 236 + uint16 m_usPieceType; // 248 + uint16 m_pad3; // 250 + CEntitySAInterface* m_pAttachedEntity; // 252 + CVector m_vecAttachedOffset; // 256 + CVector m_vecAttachedRotation; // 268 + CVector m_vecUnk; // 280 + uint32 m_pad4; // 292 + CPtrNodeDoubleLink* m_pControlCodeNodeLink; // 296 + float m_fLighting; // 300 surface brightness + float m_fLighting2; // 304 dynamic lighting (unused, always set to 0 in the GTA code) + class CShadowDataSA* m_pShadowData; // 308 CRect* GetBoundRect_(CRect* pRect); static void StaticSetHooks(); diff --git a/Client/game_sa/CPickupSA.cpp b/Client/game_sa/CPickupSA.cpp index 4256f22a489..fde7508e169 100644 --- a/Client/game_sa/CPickupSA.cpp +++ b/Client/game_sa/CPickupSA.cpp @@ -121,18 +121,16 @@ BYTE CPickupSA::IsNearby() return GetInterface()->bIsPickupNearby; } -void CPickupSA::GiveUsAPickUpObject(int ForcedObjectIndex) +bool CPickupSA::GiveUsAPickUpObject(int ForcedObjectIndex) { DWORD GiveUsAPickUpObject = FUNC_GIVEUSAPICKUP; DWORD dwObject = (DWORD) & (GetInterface()->pObject); DWORD dwThis = (DWORD)GetInterface(); - _asm - { - push ForcedObjectIndex - push dwObject - mov ecx, dwThis - call GiveUsAPickUpObject - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwObject), decltype(ForcedObjectIndex)); + reinterpret_cast(GiveUsAPickUpObject)(dwThis, dwObject, ForcedObjectIndex); + // clang-format on + if (GetInterface()->pObject) { if (object) @@ -140,9 +138,10 @@ void CPickupSA::GiveUsAPickUpObject(int ForcedObjectIndex) ((CEntitySA*)object)->DoNotRemoveFromGame = true; delete object; } - object = new CObjectSA(GetInterface()->pObject); + return true; } + return false; } void CPickupSA::GetRidOfObjects() @@ -154,25 +153,26 @@ void CPickupSA::GetRidOfObjects() { ((CEntitySA*)object)->DoNotRemoveFromGame = true; delete object; - object = NULL; + object = nullptr; } + + GetInterface()->pObject = nullptr; } void CPickupSA::Remove() { DWORD dwFunc = FUNC_CPickup_Remove; DWORD dwThis = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on // CPickup::Remove also destroys the owned object, so we need to delete our CObjectSA class if (object) { ((CEntitySA*)object)->DoNotRemoveFromGame = true; delete object; - object = NULL; + object = nullptr; } } diff --git a/Client/game_sa/CPickupSA.h b/Client/game_sa/CPickupSA.h index 807988b5f08..fd0bcc7937a 100644 --- a/Client/game_sa/CPickupSA.h +++ b/Client/game_sa/CPickupSA.h @@ -17,26 +17,26 @@ class CObjectSAInterface; class CObjectSA; -#define FUNC_GIVEUSAPICKUP 0x4567e0 -#define FUNC_CPickup_Remove 0x4556C0 +#define FUNC_GIVEUSAPICKUP 0x4567e0 +#define FUNC_CPickup_Remove 0x4556C0 class CPickupSAInterface { public: - float CurrentValue; // For the revenue pickups 0 - CObjectSAInterface* pObject; // 4 - long MonetaryValue; // 8 - DWORD RegenerationTime; // 12 - short CoorsX, CoorsY, CoorsZ; // 16 // 18 // 20 - WORD MoneyPerDay; // 22 - WORD MI; // 24 - WORD ReferenceIndex; // 26 - BYTE Type; // 28 - BYTE State : 1; // 29 + float CurrentValue; // For the revenue pickups 0 + CObjectSAInterface* pObject; // 4 + long MonetaryValue; // 8 + DWORD RegenerationTime; // 12 + short CoorsX, CoorsY, CoorsZ; // 16 // 18 // 20 + WORD MoneyPerDay; // 22 + WORD MI; // 24 + WORD ReferenceIndex; // 26 + BYTE Type; // 28 + BYTE State : 1; // 29 BYTE bNoAmmo : 1; BYTE bHelpMessageDisplayed : 1; - BYTE bIsPickupNearby : 1; // If the pickup is nearby it will get an object and it will get updated. - BYTE TextIndex : 3; // What text label do we print out above it. + BYTE bIsPickupNearby : 1; // If the pickup is nearby it will get an object and it will get updated. + BYTE TextIndex : 3; // What text label do we print out above it. }; class CPickupSA : public CPickup @@ -47,29 +47,29 @@ class CPickupSA : public CPickup public: CPickupSA(CPickupSAInterface* pickupInterface); - CPickupSAInterface* GetInterface() { return internalInterface; }; // not to be exported + CPickupSAInterface* GetInterface() { return internalInterface; }; // not to be exported CObject* GetObject() { return object; }; void SetPosition(CVector* vecPosition); CVector* GetPosition(CVector* vecPosition); PickupType GetType(); - void SetType(PickupType type); - float GetCurrentValue(); - void SetCurrentValue(float fCurrentValue); - void SetRegenerationTime(DWORD dwTime); - void SetMoneyPerDay(WORD wMoneyPerDay); - WORD GetMoneyPerDay(); - WORD GetModel(); - void SetModel(WORD wModelIndex); // do not export + void SetType(PickupType type); + float GetCurrentValue(); + void SetCurrentValue(float fCurrentValue); + void SetRegenerationTime(DWORD dwTime); + void SetMoneyPerDay(WORD wMoneyPerDay); + WORD GetMoneyPerDay(); + WORD GetModel(); + void SetModel(WORD wModelIndex); // do not export PickupState GetState(); - void SetState(PickupState bState); - BYTE GetAmmo(); - void SetAmmo(BYTE bAmmo); - long GetMonetaryValue(); - void SetMonetaryValue(long lMonetaryValue); - BYTE IsNearby(); - void GiveUsAPickUpObject(int ForcedObjectIndex = -1); - void GetRidOfObjects(); - void Remove(); + void SetState(PickupState bState); + BYTE GetAmmo(); + void SetAmmo(BYTE bAmmo); + long GetMonetaryValue(); + void SetMonetaryValue(long lMonetaryValue); + BYTE IsNearby(); + bool GiveUsAPickUpObject(int ForcedObjectIndex = -1); + void GetRidOfObjects(); + void Remove(); }; diff --git a/Client/game_sa/CPickupsSA.cpp b/Client/game_sa/CPickupsSA.cpp index 71bcee5a96f..c7faf6d9e4f 100644 --- a/Client/game_sa/CPickupsSA.cpp +++ b/Client/game_sa/CPickupsSA.cpp @@ -74,7 +74,7 @@ CPickup* CPickupsSA::CreatePickup(CVector* position, DWORD ModelIndex, PickupTyp } if (FreeSlot >= MAX_PICKUPS) - { // In that case use the first PICKUP_ONCE_TIMEOUT + { // In that case use the first PICKUP_ONCE_TIMEOUT FreeSlot = 0; while (FreeSlot < MAX_PICKUPS && Pickups[FreeSlot]->GetInterface()->Type != (BYTE)PickupType::PICKUP_ONCE_TIMEOUT && Pickups[FreeSlot]->GetInterface()->Type != (BYTE)PickupType::PICKUP_ONCE_TIMEOUT_SLOW) @@ -85,8 +85,8 @@ CPickup* CPickupsSA::CreatePickup(CVector* position, DWORD ModelIndex, PickupTyp // We need to tidy up the objects that go with this pickup if (FreeSlot >= MAX_PICKUPS) - { // Couldn't find one. Let's just hope we don't break anything in the scripts. - // ASSERTMSG(0, "Ran out of pickups"); + { // Couldn't find one. Let's just hope we don't break anything in the scripts. + // ASSERTMSG(0, "Ran out of pickups"); return (CPickup*)NULL; } else @@ -118,17 +118,17 @@ CPickup* CPickupsSA::CreatePickup(CVector* position, DWORD ModelIndex, PickupTyp } if (Type == PickupType::PICKUP_MONEY) { - pickup->SetRegenerationTime(pGame->GetSystemTime() + 30000); // Money stays for 30 secs + pickup->SetRegenerationTime(pGame->GetSystemTime() + 30000); // Money stays for 30 secs } if (Type == PickupType::PICKUP_MINE_INACTIVE || Type == PickupType::PICKUP_MINE_ARMED) { pickup->SetType(PickupType::PICKUP_MINE_INACTIVE); - pickup->SetRegenerationTime(pGame->GetSystemTime() + 1500); // Mines get activated after 2 secs + pickup->SetRegenerationTime(pGame->GetSystemTime() + 1500); // Mines get activated after 2 secs } if (Type == PickupType::PICKUP_NAUTICAL_MINE_INACTIVE || Type == PickupType::PICKUP_NAUTICAL_MINE_ARMED) { pickup->SetType(PickupType::PICKUP_NAUTICAL_MINE_INACTIVE); - pickup->GetInterface()->RegenerationTime = pGame->GetSystemTime() + 1500; // Mines get activated after 2 secs + pickup->GetInterface()->RegenerationTime = pGame->GetSystemTime() + 1500; // Mines get activated after 2 secs } pickup->SetModel((WORD)ModelIndex); diff --git a/Client/game_sa/CPickupsSA.h b/Client/game_sa/CPickupsSA.h index 5c5b82a4462..9025f806abe 100644 --- a/Client/game_sa/CPickupsSA.h +++ b/Client/game_sa/CPickupsSA.h @@ -15,11 +15,11 @@ class CPickupSA; -#define MAX_PICKUPS 620 -#define MAX_PICKUPS_ALWAYS_UPDATED 16 +#define MAX_PICKUPS 620 +#define MAX_PICKUPS_ALWAYS_UPDATED 16 -#define ARRAY_PICKUPS 0x9788C0 -#define FUNC_CPickups__Update 0x458DE0 +#define ARRAY_PICKUPS 0x9788C0 +#define FUNC_CPickups__Update 0x458DE0 class CPickupsSA : public CPickups { diff --git a/Client/game_sa/CPlaceableSA.h b/Client/game_sa/CPlaceableSA.h index d2b713da734..858263e1de6 100644 --- a/Client/game_sa/CPlaceableSA.h +++ b/Client/game_sa/CPlaceableSA.h @@ -10,7 +10,7 @@ #include #include -class CSimpleTransformSAInterface // 16 bytes +class CSimpleTransformSAInterface // 16 bytes { public: CVector m_translate; @@ -33,6 +33,6 @@ class CPlaceableSAInterface public: CSimpleTransformSAInterface m_transform; - CMatrix_Padded* matrix; // This is actually XYZ*, change later + CMatrix_Padded* matrix; // This is actually XYZ*, change later }; static_assert(sizeof(CPlaceableSAInterface) == 0x18, "Invalid size for CPlaceableSAInterface"); diff --git a/Client/game_sa/CPlaneSA.h b/Client/game_sa/CPlaneSA.h index 9d311a1ccd5..e59b7f50641 100644 --- a/Client/game_sa/CPlaneSA.h +++ b/Client/game_sa/CPlaneSA.h @@ -26,7 +26,7 @@ class CPlaneSAInterface : public CAutomobileSAInterface float m_fAccelerationBreakStatusPrev; float m_fSteeringFactor; float field_9A0; - float m_planeCreationHeading; // The heading when plane is created or placed on road properly + float m_planeCreationHeading; // The heading when plane is created or placed on road properly float m_maxAltitude; float m_altitude; float m_minAltitude; @@ -34,7 +34,7 @@ class CPlaneSAInterface : public CAutomobileSAInterface float m_planeHeadingPrev; float m_forwardZ; uint32_t m_nStartedFlyingTime; - float m_fPropSpeed; // Rotor speed 0x09C4 + float m_fPropSpeed; // Rotor speed 0x09C4 float field_9C8; float m_fLandingGearStatus; int32_t m_planeDamageWave; diff --git a/Client/game_sa/CPlantManagerSA.cpp b/Client/game_sa/CPlantManagerSA.cpp index aef1849aae9..f7e5b2f9d8a 100644 --- a/Client/game_sa/CPlantManagerSA.cpp +++ b/Client/game_sa/CPlantManagerSA.cpp @@ -9,14 +9,15 @@ class CPlantColEntEntry { public: CEntitySAInterface* m_Entity; - CPlantLocTri** m_Objects; - uint16 m_numTriangles; - CPlantColEntEntry* m_NextEntry; - CPlantColEntEntry* m_PrevEntry; + CPlantLocTri** m_Objects; + uint16 m_numTriangles; + CPlantColEntEntry* m_NextEntry; + CPlantColEntEntry* m_PrevEntry; public: - void ReleaseEntry() { - using CPlantColEntEntry_ReleaseEntry = void* ( __thiscall *)(CPlantColEntEntry*); + void ReleaseEntry() + { + using CPlantColEntEntry_ReleaseEntry = void*(__thiscall*)(CPlantColEntEntry*); ((CPlantColEntEntry_ReleaseEntry)0x5DB8A0)(this); }; }; diff --git a/Client/game_sa/CPlayerInfoSA.h b/Client/game_sa/CPlayerInfoSA.h index ed618d5ad83..bcad187ce8e 100644 --- a/Client/game_sa/CPlayerInfoSA.h +++ b/Client/game_sa/CPlayerInfoSA.h @@ -25,7 +25,7 @@ class CPlayerCrossHairSAInterface { public: bool bActivated; - float TargetX, TargetY; // -1 ... 1 on screen + float TargetX, TargetY; // -1 ... 1 on screen }; // Note: Information below may be incorrect. Please check before using. @@ -34,50 +34,50 @@ class CPlayerCrossHairSAInterface class CPlayerPedDataSAInterface { public: - CWantedSAInterface* m_Wanted; // 0 - CPedClothesDesc* m_pClothes; // 4 + CWantedSAInterface* m_Wanted; // 0 + CPedClothesDesc* m_pClothes; // 4 - CPedSAInterface* m_ArrestingOfficer; // actually CCopPed * // 8 + CPedSAInterface* m_ArrestingOfficer; // actually CCopPed * // 8 - CVector2D m_vecFightMovement; // 12 - float m_moveBlendRatio; // 20 + CVector2D m_vecFightMovement; // 12 + float m_moveBlendRatio; // 20 float m_fTimeCanRun; float m_fSprintEnergy; - BYTE m_nChosenWeapon; // 28 - BYTE m_nCarDangerCounter; // 29 - BYTE m_pad0; // 30 - BYTE m_pad1; // 31 - long m_nStandStillTimer; // 32 - DWORD m_nHitAnimDelayTimer; // 36 - float m_fAttackButtonCounter; // 40 - CAutomobileSAInterface* m_pDangerCar; // 44 + BYTE m_nChosenWeapon; // 28 + BYTE m_nCarDangerCounter; // 29 + BYTE m_pad0; // 30 + BYTE m_pad1; // 31 + long m_nStandStillTimer; // 32 + DWORD m_nHitAnimDelayTimer; // 36 + float m_fAttackButtonCounter; // 40 + CAutomobileSAInterface* m_pDangerCar; // 44 - DWORD m_bStoppedMoving : 1; // 48 + DWORD m_bStoppedMoving : 1; // 48 DWORD m_bAdrenaline : 1; - DWORD m_bHaveTargetSelected : 1; // Needed to work out whether we lost target this frame + DWORD m_bHaveTargetSelected : 1; // Needed to work out whether we lost target this frame DWORD m_bFreeAiming : 1; DWORD bCanBeDamaged : 1; - DWORD bAllMeleeAttackPtsBlocked : 1; // if all of m_pMeleeAttackers[] is blocked by collision, just attack straight ahead - DWORD m_JustBeenSnacking : 1; // If this bit is true we have just bought something from a vending machine - DWORD m_bRequireHandleBreath : 1; // + DWORD bAllMeleeAttackPtsBlocked : 1; // if all of m_pMeleeAttackers[] is blocked by collision, just attack straight ahead + DWORD m_JustBeenSnacking : 1; // If this bit is true we have just bought something from a vending machine + DWORD m_bRequireHandleBreath : 1; // // The player runs a group. Player is the leader. Player can go up to gang-members and make them join his group. // 50 - DWORD m_GroupStuffDisabled : 1; // 52 // if this is true the player can't recrout or give his group commands. - DWORD m_GroupAlwaysFollow : 1; // The group is told to always follow the player (used for girlfriend missions) - DWORD m_GroupNeverFollow : 1; // The group is told to always follow the player (used for girlfriend missions) - DWORD m_bInVehicleDontAllowWeaponChange : 1; // stop weapon change once driveby weapon has been given - DWORD m_bRenderWeapon : 1; // set to false during cutscenes so that knuckledusters are not rendered + DWORD m_GroupStuffDisabled : 1; // 52 // if this is true the player can't recrout or give his group commands. + DWORD m_GroupAlwaysFollow : 1; // The group is told to always follow the player (used for girlfriend missions) + DWORD m_GroupNeverFollow : 1; // The group is told to always follow the player (used for girlfriend missions) + DWORD m_bInVehicleDontAllowWeaponChange : 1; // stop weapon change once driveby weapon has been given + DWORD m_bRenderWeapon : 1; // set to false during cutscenes so that knuckledusters are not rendered - long m_PlayerGroup; // 60 + long m_PlayerGroup; // 60 - DWORD m_AdrenalineEndTime; // 64 - BYTE m_nDrunkenness; // 68 - bool m_bFadeDrunkenness; // 69 - BYTE m_nDrugLevel; // 70 - BYTE m_nScriptLimitToGangSize; // 71 + DWORD m_AdrenalineEndTime; // 64 + BYTE m_nDrunkenness; // 68 + bool m_bFadeDrunkenness; // 69 + BYTE m_nDrugLevel; // 70 + BYTE m_nScriptLimitToGangSize; // 71 - float m_fBreath; // for holding breath (ie underwater) // 72 + float m_fBreath; // for holding breath (ie underwater) // 72 // once a set of melee weapon anims have been loaded and referenced for the player // we need to remember what we've referenced @@ -90,7 +90,7 @@ class CPlayerPedDataSAInterface float m_fSkateBoardSpeed; float m_fSkateBoardLean; - DWORD* m_pSpecialAtomic; // was rpAtomic + DWORD* m_pSpecialAtomic; // was rpAtomic float m_fGunSpinSpeed; float m_fGunSpinAngle; @@ -139,48 +139,48 @@ class CPlayerInfoSAInterface PLAYERSTATE_LEFTGAME }; - class CPlayerPedSAInterface* pPed; // Pointer to the player ped (should always be set) - CPlayerPedDataSAInterface PlayerPedData; // instance of player variables - CVehicleSAInterface* pRemoteVehicle; // Pointer to vehicle player is driving remotely at the moment.(NULL if on foot) - CVehicleSAInterface* pSpecCar; // which car is using the special collision model - long Score; // Points for this player - long DisplayScore; // Points as they would be displayed - long CollectablesPickedUp; // How many bags of sugar do we have - long TotalNumCollectables; // How many bags of sugar are there to be had in the game + class CPlayerPedSAInterface* pPed; // Pointer to the player ped (should always be set) + CPlayerPedDataSAInterface PlayerPedData; // instance of player variables + CVehicleSAInterface* pRemoteVehicle; // Pointer to vehicle player is driving remotely at the moment.(NULL if on foot) + CVehicleSAInterface* pSpecCar; // which car is using the special collision model + long Score; // Points for this player + long DisplayScore; // Points as they would be displayed + long CollectablesPickedUp; // How many bags of sugar do we have + long TotalNumCollectables; // How many bags of sugar are there to be had in the game - DWORD nLastBumpPlayerCarTimer; // Keeps track of when the last ped bumped into the player car + DWORD nLastBumpPlayerCarTimer; // Keeps track of when the last ped bumped into the player car - DWORD TaxiTimer; // Keeps track of how long the player has been in a taxi with a passenger (in msecs) - DWORD vehicle_time_counter; // keeps track of how long player has been in car for driving skill - bool bTaxiTimerScore; // If TRUE then add 1 to score for each second that the player is driving a taxi - bool m_bTryingToExitCar; // if player holds exit car button, want to trigger getout once car slowed enough - // with a passenger + DWORD TaxiTimer; // Keeps track of how long the player has been in a taxi with a passenger (in msecs) + DWORD vehicle_time_counter; // keeps track of how long player has been in car for driving skill + bool bTaxiTimerScore; // If TRUE then add 1 to score for each second that the player is driving a taxi + bool m_bTryingToExitCar; // if player holds exit car button, want to trigger getout once car slowed enough + // with a passenger - CVehicleSAInterface* pLastTargetVehicle; // Last vehicle player tried to enter. + CVehicleSAInterface* pLastTargetVehicle; // Last vehicle player tried to enter. - BYTE PlayerState; // What's going on. + BYTE PlayerState; // What's going on. bool bAfterRemoteVehicleExplosion; bool bCreateRemoteVehicleExplosion; bool bFadeAfterRemoteVehicleExplosion; DWORD TimeOfRemoteVehicleExplosion; - DWORD LastTimeEnergyLost; // To make numbers flash on the HUD + DWORD LastTimeEnergyLost; // To make numbers flash on the HUD DWORD LastTimeArmourLost; - DWORD LastTimeBigGunFired; // Tank guns etc - DWORD TimesUpsideDownInARow; // Make car blow up if car upside down - DWORD TimesStuckInARow; // Make car blow up if player cannot get out. + DWORD LastTimeBigGunFired; // Tank guns etc + DWORD TimesUpsideDownInARow; // Make car blow up if car upside down + DWORD TimesStuckInARow; // Make car blow up if player cannot get out. // working counters to calculate how long player managed stuff - DWORD nCarTwoWheelCounter; // how long has player's car been on two wheels + DWORD nCarTwoWheelCounter; // how long has player's car been on two wheels float fCarTwoWheelDist; - DWORD nCarLess3WheelCounter; // how long has player's car been on less than 3 wheels - DWORD nBikeRearWheelCounter; // how long has player's bike been on rear wheel only + DWORD nCarLess3WheelCounter; // how long has player's car been on less than 3 wheels + DWORD nBikeRearWheelCounter; // how long has player's bike been on rear wheel only float fBikeRearWheelDist; - DWORD nBikeFrontWheelCounter; // how long has player's bike been on front wheel only + DWORD nBikeFrontWheelCounter; // how long has player's bike been on front wheel only float fBikeFrontWheelDist; - DWORD nTempBufferCounter; // so wheels can leave the ground for a few frames without stopping above counters + DWORD nTempBufferCounter; // so wheels can leave the ground for a few frames without stopping above counters // best values for the script to check - will be zero most of the time, only value // when finished trick - script should retreve value then reset to zero DWORD nBestCarTwoWheelsTimeMs; @@ -191,14 +191,14 @@ class CPlayerInfoSAInterface float fBestBikeStoppieDistM; WORD CarDensityForCurrentZone; - float RoadDensityAroundPlayer; // 1.0f for an average city. + float RoadDensityAroundPlayer; // 1.0f for an average city. DWORD TimeOfLastCarExplosionCaused; long ExplosionMultiplier; - long HavocCaused; // A counter going up when the player does bad stuff. - short TimeLastEaten; // A counter that starts at 5000, increases by 1 every minute + long HavocCaused; // A counter going up when the player does bad stuff. + short TimeLastEaten; // A counter that starts at 5000, increases by 1 every minute - float CurrentChaseValue; // How 'ill' is the chase at the moment + float CurrentChaseValue; // How 'ill' is the chase at the moment // 'Special' abilities that gets awarded during the game bool DoesNotGetTired; @@ -208,8 +208,8 @@ class CPlayerInfoSAInterface BYTE MaxArmour; // Get-out-of-jail-free & Free-medical-care cards - bool bGetOutOfJailFree; // Player doesn't lose money/weapons next time arrested - bool bFreeHealthCare; // Player doesn't lose money nexed time patched up at hospital + bool bGetOutOfJailFree; // Player doesn't lose money/weapons next time arrested + bool bFreeHealthCare; // Player doesn't lose money nexed time patched up at hospital bool bCanDoDriveBy; @@ -235,7 +235,7 @@ class CPlayerInfoSA : public CPlayerInfo CPlayerInfoSA(CPlayerInfoSAInterface* playerInfoInterface) { internalInterface = playerInfoInterface; - wanted = NULL; // we can't init it yet, as our interface hasn't been inited yet + wanted = NULL; // we can't init it yet, as our interface hasn't been inited yet } ~CPlayerInfoSA() @@ -261,13 +261,13 @@ class CPlayerInfoSA : public CPlayerInfo byte GetCamDrunkLevel(); void SetCamDrunkLevel(byte level); - DWORD GetCarTwoWheelCounter() { return internalInterface->nCarTwoWheelCounter; } - float GetCarTwoWheelDist() { return internalInterface->fCarTwoWheelDist; } - DWORD GetCarLess3WheelCounter() { return internalInterface->nCarLess3WheelCounter; } - DWORD GetBikeRearWheelCounter() { return internalInterface->nBikeRearWheelCounter; } - float GetBikeRearWheelDist() { return internalInterface->fBikeRearWheelDist; } - DWORD GetBikeFrontWheelCounter() { return internalInterface->nBikeFrontWheelCounter; } - float GetBikeFrontWheelDist() { return internalInterface->fBikeFrontWheelDist; } + DWORD GetCarTwoWheelCounter() { return internalInterface->nCarTwoWheelCounter; } + float GetCarTwoWheelDist() { return internalInterface->fCarTwoWheelDist; } + DWORD GetCarLess3WheelCounter() { return internalInterface->nCarLess3WheelCounter; } + DWORD GetBikeRearWheelCounter() { return internalInterface->nBikeRearWheelCounter; } + float GetBikeRearWheelDist() { return internalInterface->fBikeRearWheelDist; } + DWORD GetBikeFrontWheelCounter() { return internalInterface->nBikeFrontWheelCounter; } + float GetBikeFrontWheelDist() { return internalInterface->fBikeFrontWheelDist; } std::uint8_t GetMaxHealth() const { return internalInterface->MaxHealth; } std::uint8_t GetMaxArmor() const { return internalInterface->MaxArmour; } }; diff --git a/Client/game_sa/CPlayerPedSA.cpp b/Client/game_sa/CPlayerPedSA.cpp index 2a2f434cca8..fab6dd993cb 100644 --- a/Client/game_sa/CPlayerPedSA.cpp +++ b/Client/game_sa/CPlayerPedSA.cpp @@ -36,7 +36,8 @@ CPlayerPedSA::CPlayerPedSA(unsigned int nModelIndex) DWORD CPlayerPedConstructor = FUNC_CPlayerPedConstructor; DWORD dwPedPointer = 0; - _asm + // clang-format off + __asm { push SIZEOF_CPLAYERPED call CPedOperatorNew @@ -49,10 +50,11 @@ CPlayerPedSA::CPlayerPedSA(unsigned int nModelIndex) push 1 call CPlayerPedConstructor } + // clang-format on SetInterface((CEntitySAInterface*)dwPedPointer); - Init(); // init our interfaces + Init(); // init our interfaces CPoolsSA* pools = (CPoolsSA*)pGame->GetPools(); CWorldSA* world = (CWorldSA*)pGame->GetWorld(); @@ -162,12 +164,10 @@ void CPlayerPedSA::SetInitialState() DWORD dwUnknown = 1; DWORD dwFunction = FUNC_SetInitialState; DWORD dwThis = (DWORD)m_pInterface; - _asm - { - push dwUnknown - mov ecx, dwThis - call dwFunction - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwUnknown)); + reinterpret_cast(dwFunction)(dwThis, dwUnknown); + // clang-format on // Avoid direction locks for respawning after a jump GetPlayerPedInterface()->pedFlags.bIsLanding = false; @@ -263,7 +263,7 @@ void CPlayerPedSA::SetMoveAnim(eMoveAnim iAnimGroup) if (pAnimBlock && !pAnimBlock->IsLoaded()) { pAnimBlock->Request(BLOCKING, true); - MapInsert(ms_DoneAnimBlockRefMap, strBlockName); // Request() adds a ref for us + MapInsert(ms_DoneAnimBlockRefMap, strBlockName); // Request() adds a ref for us } // Load fail? @@ -293,11 +293,10 @@ void CPlayerPedSA::SetMoveAnim(eMoveAnim iAnimGroup) DWORD dwThis = (DWORD)pedInterface; DWORD dwFunc = FUNC_CPlayerPed_ReApplyMoveAnims; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } CEntity* CPlayerPedSA::GetTargetedEntity() const @@ -440,12 +439,15 @@ __declspec(noinline) int _cdecl OnCPlayerPed_ProcessAnimGroups_Mid(CPlayerPedSAI } // Hook info -#define HOOKPOS_CPlayerPed_ProcessAnimGroups_Mid 0x0609A44 -#define HOOKSIZE_CPlayerPed_ProcessAnimGroups_Mid 6 -DWORD RETURN_CPlayerPed_ProcessAnimGroups_Mid = 0x0609A4A; -void _declspec(naked) HOOK_CPlayerPed_ProcessAnimGroups_Mid() +#define HOOKPOS_CPlayerPed_ProcessAnimGroups_Mid 0x0609A44 +#define HOOKSIZE_CPlayerPed_ProcessAnimGroups_Mid 6 +DWORD RETURN_CPlayerPed_ProcessAnimGroups_Mid = 0x0609A4A; +static void __declspec(naked) HOOK_CPlayerPed_ProcessAnimGroups_Mid() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push eax @@ -460,6 +462,7 @@ void _declspec(naked) HOOK_CPlayerPed_ProcessAnimGroups_Mid() jmp RETURN_CPlayerPed_ProcessAnimGroups_Mid } + // clang-format on } //////////////////////////////////////////////////////////////// @@ -492,12 +495,15 @@ __declspec(noinline) int _cdecl OnCClothes_GetDefaultPlayerMotionGroup(int iReqM } // Hook info -#define HOOKPOS_CClothes_GetDefaultPlayerMotionGroup 0x05A81B0 -#define HOOKSIZE_CClothes_GetDefaultPlayerMotionGroup 5 -DWORD RETURN_CClothes_GetDefaultPlayerMotionGroup = 0x05A81B5; -void _declspec(naked) HOOK_CClothes_GetDefaultPlayerMotionGroup() +#define HOOKPOS_CClothes_GetDefaultPlayerMotionGroup 0x05A81B0 +#define HOOKSIZE_CClothes_GetDefaultPlayerMotionGroup 5 +DWORD RETURN_CClothes_GetDefaultPlayerMotionGroup = 0x05A81B5; +static void __declspec(naked) HOOK_CClothes_GetDefaultPlayerMotionGroup() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov eax, 0x05A7FB0 // CClothes::GetPlayerMotionGroupToLoad call eax @@ -505,13 +511,14 @@ void _declspec(naked) HOOK_CClothes_GetDefaultPlayerMotionGroup() pushad push eax call OnCClothes_GetDefaultPlayerMotionGroup - mov [esp+0],eax // Put temp + mov [esp+0], eax // Put temp add esp, 4*1 popad mov eax,[esp-32-4*1] // Get temp jmp RETURN_CClothes_GetDefaultPlayerMotionGroup } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/game_sa/CPlayerPedSA.h b/Client/game_sa/CPlayerPedSA.h index 90e62ade8cd..df001965606 100644 --- a/Client/game_sa/CPlayerPedSA.h +++ b/Client/game_sa/CPlayerPedSA.h @@ -15,18 +15,18 @@ #include "CPedSA.h" #include "CWantedSA.h" -#define FUNC_SetInitialState 0x60CD20 -#define FUNC_ClearWeaponTarget 0x533B30 +#define FUNC_SetInitialState 0x60CD20 +#define FUNC_ClearWeaponTarget 0x533B30 -#define FUNC_CPedOperatorNew 0x5E4720 // ##SA## -#define FUNC_CPlayerPedConstructor 0x60D5B0 // ##SA## +#define FUNC_CPedOperatorNew 0x5E4720 // ##SA## +#define FUNC_CPlayerPedConstructor 0x60D5B0 // ##SA## -#define FUNC_CPlayerPedDestructor 0x6093B0 // ##SA## -#define FUNC_CPlayerPedOperatorDelete 0x5E4760 // ##SA## +#define FUNC_CPlayerPedDestructor 0x6093B0 // ##SA## +#define FUNC_CPlayerPedOperatorDelete 0x5E4760 // ##SA## -#define FUNC_CPlayerPed_ReApplyMoveAnims 0x609650 +#define FUNC_CPlayerPed_ReApplyMoveAnims 0x609650 -#define SIZEOF_CPLAYERPED 1956 +#define SIZEOF_CPLAYERPED 1956 class CPlayerPedSAInterface : public CPedSAInterface { @@ -56,7 +56,7 @@ class CPlayerPedSA : public virtual CPlayerPed, public virtual CPedSA void SetMoveAnim(eMoveAnim iAnimGroup); CEntity* GetTargetedEntity() const override; - void SetTargetedEntity(CEntity* targetEntity) override; + void SetTargetedEntity(CEntity* targetEntity) override; CPlayerPedSAInterface* GetPlayerPedInterface() const noexcept { return static_cast(m_pInterface); }; diff --git a/Client/game_sa/CPointLightsSA.cpp b/Client/game_sa/CPointLightsSA.cpp index e452a210acf..0076e8951dd 100644 --- a/Client/game_sa/CPointLightsSA.cpp +++ b/Client/game_sa/CPointLightsSA.cpp @@ -18,6 +18,9 @@ using CHeli_SearchLightCone_t = void(__cdecl*)(int handleId, CVector startPos, C using CHeli_PreSearchLightCone_t = int(__cdecl*)(); using CHeli_PostSearchLightCone_t = int(__cdecl*)(); +// Init default searchlight color +static SColor searchLightColor = SColorRGBA(200, 200, 255, 0); + void CPointLightsSA::AddLight(int iMode, const CVector vecPosition, CVector vecDirection, float fRadius, SharedUtil::SColor color, unsigned char uc_8, bool bCreatesShadow, CEntity* pAffected) { @@ -28,25 +31,10 @@ void CPointLightsSA::AddLight(int iMode, const CVector vecPosition, CVector vecD float fPosX = vecPosition.fX, fPosY = vecPosition.fY, fPosZ = vecPosition.fZ; float fDirX = vecDirection.fX, fDirY = vecDirection.fY, fDirZ = vecDirection.fZ; float fRed = (float)color.R / 255, fGreen = (float)color.G / 255, fBlue = (float)color.B / 255; - _asm - { - push dwEntityInterface - push bCreatesShadow - push uc_8 - push fBlue - push fGreen - push fRed - push fRadius - push fDirZ - push fDirY - push fDirX - push fPosZ - push fPosY - push fPosX - push iMode - call dwFunc - add esp, 56 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(iMode), decltype(fPosX), decltype(fPosY), decltype(fPosZ), decltype(fDirX), decltype(fDirY), decltype(fDirZ), decltype(fRadius), decltype(fRed), decltype(fGreen), decltype(fBlue), decltype(uc_8), decltype(bCreatesShadow), decltype(dwEntityInterface)); + reinterpret_cast(dwFunc)(iMode, fPosX, fPosY, fPosZ, fDirX, fDirY, fDirZ, fRadius, fRed, fGreen, fBlue, uc_8, bCreatesShadow, dwEntityInterface); + // clang-format on } void CPointLightsSA::PreRenderHeliLights() @@ -61,13 +49,81 @@ void CPointLightsSA::PostRenderHeliLights() CHeli_PostSearchLightCone(); } -void CPointLightsSA::RenderHeliLight(const CVector& vecStart, const CVector& vecEnd, float startRadius, float endRadius, bool renderSpot) +void CPointLightsSA::RenderHeliLight(const CVector& vecStart, const CVector& vecEnd, float startRadius, float endRadius, bool renderSpot, + const SharedUtil::SColor& color) { auto CHeli_SearchLightCone = (CHeli_SearchLightCone_t)FUNC_CHeli_SearchLightCone; // 3x3 translation matrix (initialised by the game) CVector mat[] = {CVector(), CVector(), CVector()}; + // Set color + SColor originalColor = searchLightColor; + searchLightColor = color; + // Set render states and render CHeli_SearchLightCone(0, vecStart, vecEnd, endRadius, 1.0f, 0, renderSpot, &mat[0], &mat[1], &mat[2], 1, startRadius); + + // Set previous color + // Keep the maverick default searchlight color + searchLightColor = originalColor; +} + +struct RxObjSpace3DVertex +{ + CVector pos; + CVector normal; + int color; + float u; + float v; +}; + +static RxObjSpace3DVertex* CSearchLight_PreRender3DVertexBuffer(RxObjSpace3DVertex* buffer, std::uint32_t numVerts, RwMatrix* ltm, std::uint32_t flags) +{ + // Light cone color + if (buffer && numVerts > 0) + { + for (int i = 0; i < numVerts; i++) + { + float intensity = (buffer[i].color & 0xFF) / 255.0f; // Get original intensity + + buffer[i].color = COLOR_RGBA(static_cast(searchLightColor.R * intensity), static_cast(searchLightColor.G * intensity), + static_cast(searchLightColor.B * intensity), 0); + } + } + + // Call RwIm3DTransform + return ((RxObjSpace3DVertex * (__cdecl*)(RxObjSpace3DVertex*, std::uint32_t, RwMatrix*, std::uint32_t))0x7EF450)(buffer, numVerts, ltm, flags); +} + +static void CSearchLight_RenderShadow(char type, void* texture, CVector* pos, float x1, float y1, float x2, float y2, std::int16_t intensity, char r, char g, + char b, float zDistance, bool drawOnWater, float scale, void* shadowData, bool drawOnBuildings) +{ + // Get original color intensity multiplier + float colorIntensity = static_cast(intensity) / 128.0f; + + // CShadows::StoreShadowToBeRendered + ((void(__cdecl*)(char, void*, CVector*, float, float, float, float, std::int16_t, unsigned char, unsigned char, unsigned char, float, bool, float, void*, + bool))0x707390)(type, texture, pos, x1, y1, x2, y2, intensity, static_cast(searchLightColor.R * colorIntensity), + static_cast(searchLightColor.G * colorIntensity), + static_cast(searchLightColor.B * colorIntensity), zDistance, drawOnWater, scale, shadowData, + drawOnBuildings); +} + +static void CSearchLight_RenderCorona(int ID, void* entity, unsigned char r, unsigned char g, unsigned char b, unsigned char a, CVector* pos, float radius, + float farClip, int type, char flareType, bool enableReflection, bool checkObstacles, int unknownUnused, float angle, + bool longDistance, float nearClip, bool fadeState, float fadeSpeed, bool onlyFromBelow, bool reflectionDelay) +{ + // CCoronas::RegisterCorona + ((void(__cdecl*)(int, void*, unsigned char, unsigned char, unsigned char, unsigned char, CVector*, float, float, int, char, bool, bool, int, float, bool, + float, bool, float, bool, bool))0x6FC580)(ID, entity, searchLightColor.R, searchLightColor.G, searchLightColor.B, a, pos, radius, farClip, + type, flareType, enableReflection, checkObstacles, unknownUnused, angle, longDistance, nearClip, + fadeState, fadeSpeed, onlyFromBelow, reflectionDelay); +} + +void CPointLightsSA::StaticSetHooks() +{ + HookInstallCall(0x6C628E, (DWORD)CSearchLight_PreRender3DVertexBuffer); + HookInstallCall(0x6C64F7, (DWORD)CSearchLight_RenderShadow); + HookInstallCall(0x6C5B1F, (DWORD)CSearchLight_RenderCorona); } diff --git a/Client/game_sa/CPointLightsSA.h b/Client/game_sa/CPointLightsSA.h index 5d5338d6299..3dbe3b86e3a 100644 --- a/Client/game_sa/CPointLightsSA.h +++ b/Client/game_sa/CPointLightsSA.h @@ -26,6 +26,9 @@ class CPointLightsSA : public CPointLights virtual void PreRenderHeliLights() override; virtual void PostRenderHeliLights() override; - virtual void RenderHeliLight(const CVector& vecStart, const CVector& vecEnd, float startRadius, float endRadius, bool renderSpot) override; + virtual void RenderHeliLight(const CVector& vecStart, const CVector& vecEnd, float startRadius, float endRadius, bool renderSpot, + const SharedUtil::SColor& color) override; ; + + static void StaticSetHooks(); }; diff --git a/Client/game_sa/CPoolSAInterface.h b/Client/game_sa/CPoolSAInterface.h index 668beb75360..829c8d11ccb 100644 --- a/Client/game_sa/CPoolSAInterface.h +++ b/Client/game_sa/CPoolSAInterface.h @@ -26,6 +26,38 @@ union tPoolObjectFlags unsigned char nValue; }; +// GTA SA pool slot stride for each interface type. +// Most pools use sizeof(T), but vehicle, ped, and object pools allocate +// slots larger than the base interface to accommodate derived types +// (e.g. CAutomobileSAInterface inside the vehicle pool). +template +struct PoolAllocStride +{ + static constexpr std::uint32_t value = sizeof(T); +}; + +class CVehicleSAInterface; +class CPedSAInterface; +class CObjectSAInterface; + +template <> +struct PoolAllocStride +{ + static constexpr std::uint32_t value = 2584; +}; + +template <> +struct PoolAllocStride +{ + static constexpr std::uint32_t value = 1988; +}; + +template <> +struct PoolAllocStride +{ + static constexpr std::uint32_t value = 412; +}; + template class CPoolSAInterface { @@ -50,15 +82,21 @@ class CPoolSAInterface uint GetFreeSlot() { + if (m_nSize <= 0 || m_byteMap == nullptr) + return static_cast(-1); + bool bLooped = false; - uint index = m_nFirstFree + 1; + int index = m_nFirstFree + 1; + + if (index < 0 || index >= m_nSize) + index = 0; while (true) { if (index >= m_nSize) { if (bLooped) - return -1; + return static_cast(-1); index = 0; bLooped = true; @@ -67,21 +105,30 @@ class CPoolSAInterface if (m_byteMap[index].bEmpty) { m_nFirstFree = index; - return index; + return static_cast(index); } index++; } - return -1; + return static_cast(-1); }; B* Allocate() { - m_nFirstFree++; // Continue after the last allocated slot - const auto sz = m_nSize; // Storing size to avoid reloads from memory - should help out the optimizer - for (auto i = 0u; i < sz; i++) + if (m_nSize <= 0 || m_pObjects == nullptr || m_byteMap == nullptr) + return nullptr; + + m_nFirstFree++; // Continue after the last allocated slot + const auto sz = m_nSize; // Storing size to avoid reloads from memory - should help out the optimizer + + if (m_nFirstFree < 0 || m_nFirstFree >= sz) + m_nFirstFree = 0; + + for (int i = 0; i < sz; i++) { - const auto slot = (m_nFirstFree + i) % sz; + int slot = m_nFirstFree + i; + if (slot >= sz) + slot -= sz; const auto e = &m_byteMap[slot]; if (!e->bEmpty) { @@ -90,18 +137,19 @@ class CPoolSAInterface m_nFirstFree = slot; e->bEmpty = false; e->nId++; - return &m_pObjects[slot]; + return reinterpret_cast(reinterpret_cast(m_pObjects) + slot * PoolAllocStride::value); } return nullptr; } B* AllocateAt(uint uiSlot) { - m_pObjects[uiSlot] = B(); + B* pSlot = reinterpret_cast(reinterpret_cast(m_pObjects) + uiSlot * PoolAllocStride::value); + *pSlot = B(); m_byteMap[uiSlot].bEmpty = false; m_byteMap[uiSlot].nId ^= uiSlot ^ (uiSlot + 1); - return &m_pObjects[uiSlot]; + return pSlot; } B* AllocateAtNoInit(std::uint32_t uiSlot) @@ -109,7 +157,7 @@ class CPoolSAInterface m_byteMap[uiSlot].bEmpty = false; m_byteMap[uiSlot].nId ^= uiSlot ^ (uiSlot + 1); - return &m_pObjects[uiSlot]; + return reinterpret_cast(reinterpret_cast(m_pObjects) + uiSlot * PoolAllocStride::value); } void Release(uint index) @@ -123,22 +171,34 @@ class CPoolSAInterface void Delete(uint index) { Release(index); } std::int32_t Size() const noexcept { return m_nSize; }; - bool IsEmpty(std::int32_t objectIndex) const { return m_byteMap[objectIndex].bEmpty; } - bool IsContains(uint index) const + bool IsEmpty(std::int32_t objectIndex) const { return m_byteMap[objectIndex].bEmpty; } + bool IsContains(std::int32_t index) const { - if (m_nSize <= index) + if (m_nSize <= 0) + return false; + + if (index < 0 || index >= m_nSize) return false; return !IsEmpty(index); } - B* GetObject(std::int32_t objectIndex) { return &m_pObjects[objectIndex]; } + B* GetObject(std::int32_t objectIndex) + { + return reinterpret_cast(reinterpret_cast(m_pObjects) + objectIndex * PoolAllocStride::value); + } - uint GetObjectIndex(B* pObject) { return ((DWORD)pObject - (DWORD)m_pObjects) / sizeof(B); } + uint GetObjectIndex(B* pObject) + { + return static_cast((reinterpret_cast(pObject) - reinterpret_cast(m_pObjects)) / PoolAllocStride::value); + } - uint32_t GetObjectIndexSafe(B* pObject) + std::int32_t GetObjectIndexSafe(B* pObject) { uint32_t index = GetObjectIndex(pObject); - return index > m_nSize ? UINT_MAX : index; + if (m_nSize <= 0) + return -1; + + return index >= static_cast(m_nSize) ? -1 : static_cast(index); } }; @@ -166,8 +226,5 @@ struct SVectorPoolData size_t count; public: - SVectorPoolData(size_t defaultSize) : count(0) - { - entities.resize(defaultSize, {nullptr, nullptr}); - } + SVectorPoolData(size_t defaultSize) : count(0) { entities.resize(defaultSize, {nullptr, nullptr}); } }; diff --git a/Client/game_sa/CPoolsSA.cpp b/Client/game_sa/CPoolsSA.cpp index b0ce14b2969..af6907175f0 100644 --- a/Client/game_sa/CPoolsSA.cpp +++ b/Client/game_sa/CPoolsSA.cpp @@ -14,8 +14,10 @@ #include "CBmxSA.h" #include "CBoatSA.h" #include "CBuildingSA.h" +#include "CColModelSA.h" #include "CGameSA.h" #include "CHeliSA.h" +#include "CModelInfoSA.h" #include "CMonsterTruckSA.h" #include "CPlaneSA.h" #include "CPlayerPedSA.h" @@ -26,6 +28,7 @@ #include "CWorldSA.h" #include "enums/VehicleClass.h" +#include extern CGameSA* pGame; @@ -78,18 +81,47 @@ CVehicle* CPoolsSA::AddVehicle(CClientVehicle* pClientVehicle, std::uint16_t mod if (m_vehiclePool.ulCount >= MAX_VEHICLES) return nullptr; + CModelInfoSA* pModelInfo = static_cast(pGame->GetModelInfo(model)); + if (!pModelInfo) + return nullptr; + + if (!pModelInfo->GetInterface()) + { + pGame->GetStreaming()->RequestModel(model, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(true, "CPoolsSA::AddVehicle"); + if (!pModelInfo->GetInterface()) + return nullptr; + } + + CBaseModelInfoSAInterface* pModelInterface = pModelInfo->GetInterface(); + + if (!pModelInterface->pColModel) + { + pGame->GetStreaming()->LoadAllRequestedModels(false, "CPoolsSA::AddVehicle"); + + pModelInterface = pModelInfo->GetInterface(); + if (!pModelInterface) + return nullptr; + + if (!pModelInterface->pColModel) + return nullptr; + } + + // Note: Vehicles with custom DFFs (no embedded collision) are handled in CModelInfoSA::SetCustomModel + // where collision is reloaded after SetClump to restore pool-managed collision data + MemSetFast((void*)VAR_CVehicle_Variation1, variation, 1); MemSetFast((void*)VAR_CVehicle_Variation2, variation2, 1); + // Valid model? + if (!CModelInfoSA::IsVehicleModel(model)) + return nullptr; + // CCarCtrl::CreateCarForScript auto* pInterface = ((CVehicleSAInterface * (__cdecl*)(int, CVector, std::uint8_t)) FUNC_CCarCtrlCreateCarForScript)(model, CVector(), 0); if (!pInterface) return nullptr; - // Valid model? - if (!CModelInfoSA::IsVehicleModel(model)) - return nullptr; - auto vehicleClass = static_cast(pGame->GetModelInfo(model)->GetVehicleType()); std::unique_ptr vehicle = nullptr; @@ -190,7 +222,14 @@ SClientEntity* CPoolsSA::GetVehicle(DWORD* pGameInterface) if (dwElementIndexInPool < MAX_VEHICLES) { - return &m_vehiclePool.arrayOfClientEntities[dwElementIndexInPool]; + // Return only if MTA has an entity for this slot + // This filters out non-MTA managed vehicles (where pEntity is null) without + // being overly strict about GTA pool state during timing edge cases or internal transitions from GTA-side to MTA vehicles + SClientEntity* pSlot = &m_vehiclePool.arrayOfClientEntities[dwElementIndexInPool]; + if (!pSlot->pEntity) + return nullptr; + + return pSlot; } } } @@ -242,7 +281,22 @@ CObject* CPoolsSA::AddObject(CClientObject* pClientObject, DWORD dwModelID, bool if (m_objectPool.ulCount < MAX_OBJECTS) { - pObject = new CObjectSA(dwModelID, bBreakingDisabled); + CModelInfoSA* pModelInfo = static_cast(pGame->GetModelInfo(dwModelID)); + if (!pModelInfo) + return nullptr; + + if (!pModelInfo->GetInterface()) + { + pGame->GetStreaming()->RequestModel(dwModelID, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(true, "CPoolsSA::AddObject"); + if (!pModelInfo->GetInterface()) + { + AddReportLog(5552, SString("Failed to create object with model %d - model invalid or deallocated", dwModelID)); + return nullptr; + } + } + + pObject = new (std::nothrow) CObjectSA(dwModelID, bBreakingDisabled); if (pObject && AddObjectToPool(pClientObject, pObject)) { @@ -253,8 +307,9 @@ CObject* CPoolsSA::AddObject(CClientObject* pClientObject, DWORD dwModelID, bool // Set super hacky flag to indicate this is a special low lod object pObject->m_pInterface->SetIsLowLodEntity(); } - else + else { pObject->m_pInterface->SetIsHighLodEntity(); +} } else { @@ -307,7 +362,12 @@ SClientEntity* CPoolsSA::GetObject(DWORD* pGameInterface) if (dwElementIndexInPool < MAX_OBJECTS) { - return &m_objectPool.arrayOfClientEntities[dwElementIndexInPool]; + // Return only if MTA has an entity for this slot + SClientEntity* pSlot = &m_objectPool.arrayOfClientEntities[dwElementIndexInPool]; + if (!pSlot->pEntity) + return nullptr; + + return pSlot; } } return nullptr; @@ -420,7 +480,7 @@ CPed* CPoolsSA::AddPed(CClientPed* pClientPed, DWORD* pGameInterface) void CPoolsSA::RemovePed(CPed* pPed, bool bDelete) { - static bool bIsDeletingPedAlready = false; // to prevent delete being called twice + static bool bIsDeletingPedAlready = false; // to prevent delete being called twice if (!bIsDeletingPedAlready) { @@ -476,7 +536,12 @@ SClientEntity* CPoolsSA::GetPed(DWORD* pGameInterface) if (dwElementIndexInPool < MAX_PEDS) { - return &m_pedPool.arrayOfClientEntities[dwElementIndexInPool]; + // Return only if MTA has an entity for this slot + SClientEntity* pSlot = &m_pedPool.arrayOfClientEntities[dwElementIndexInPool]; + if (!pSlot->pEntity) + return nullptr; + + return pSlot; } } return nullptr; @@ -503,7 +568,7 @@ CPedSAInterface* CPoolsSA::GetPedInterface(DWORD dwGameRef) DWORD dwReturn; DWORD dwFunction = FUNC_GetPed; - _asm { + __asm { mov ecx, dword ptr ds : [CLASS_CPool_Ped] push dwGameRef call dwFunction @@ -581,8 +646,8 @@ CClientEntity* CPoolsSA::GetClientEntity(DWORD* pGameInterface) static void CreateMissionTrain(const CVector& vecPos, bool bDirection, std::uint32_t uiTrainType, CTrainSAInterface** ppTrainBeginning, CTrainSAInterface** ppTrainEnd, int iNodeIndex, int iTrackId, bool bMissionTrain) noexcept { - auto createMissionTrain = reinterpret_cast(FUNC_CTrain_CreateMissionTrain); + auto createMissionTrain = reinterpret_cast( + FUNC_CTrain_CreateMissionTrain); createMissionTrain(vecPos, bDirection, uiTrainType, ppTrainBeginning, ppTrainEnd, iNodeIndex, iTrackId, bMissionTrain); } @@ -603,6 +668,8 @@ CVehicle* CPoolsSA::AddTrain(CClientVehicle* pClientVehicle, const CVector& vecP if (model == 449 || model == 537 || model == 538 || model == 569 || model == 590 || model == 570) { + if (count >= 32) + return nullptr; MemPutFast(VAR_TrainModelArray + count * 4, model); count += 1; } @@ -629,7 +696,15 @@ CVehicle* CPoolsSA::AddTrain(CClientVehicle* pClientVehicle, const CVector& vecP std::size_t vehicleIndex = 0; - std::unique_ptr train = std::make_unique(pTrainBeginning); + std::unique_ptr train; + try + { + train = std::make_unique(pTrainBeginning); + } + catch (...) + { + return nullptr; + } if (!train || !AddVehicleToPool(pClientVehicle, train.get())) return nullptr; @@ -642,7 +717,15 @@ CVehicle* CPoolsSA::AddTrain(CClientVehicle* pClientVehicle, const CVector& vecP if (!pVehCarriage) break; - auto newCarriage = std::make_unique(pVehCarriage); + std::unique_ptr newCarriage; + try + { + newCarriage = std::make_unique(pVehCarriage); + } + catch (...) + { + break; + } if (!newCarriage || !AddVehicleToPool(pClientVehicle, newCarriage.get())) { newCarriage.reset(); @@ -666,7 +749,7 @@ DWORD CPoolsSA::GetPedPoolIndex(std::uint8_t* pInterface) { return MAX_PEDS; } - return ((pInterface - pTheObjects) / dwAlignedSize); + return ((pInterface - pTheObjects) / dwAlignedSize); } DWORD CPoolsSA::GetVehiclePoolIndex(std::uint8_t* pInterface) @@ -737,10 +820,38 @@ uint CPoolsSA::GetModelIdFromClump(RpClump* pRpClump) unsigned int NUMBER_OF_MODELS = pGame->GetBaseIDforTXD(); + auto isValidPtr = [](const void* ptr) noexcept -> bool + { + if (!ptr) + return false; + + __try + { + const auto* p = static_cast(ptr); + const auto* v = p->VFTBL; + if (!v) + return false; + + volatile DWORD test = v->Destructor; + static_cast(test); + return true; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + }; + for (uint i = 1; i < NUMBER_OF_MODELS; i++) { - CBaseModelInfoSAInterface* m_pInterface = ppModelInfo[i]; - if (m_pInterface && m_pInterface->pRwObject == (RwObject*)pRpClump) + CBaseModelInfoSAInterface* pInterface = ppModelInfo[i]; + if (!pInterface) + continue; + + if (!isValidPtr(pInterface)) + continue; + + if (pInterface->pRwObject == (RwObject*)pRpClump) { return i; } @@ -757,17 +868,17 @@ int CPoolsSA::GetPoolDefaultCapacity(ePools pool) case PED_POOL: return 140; case OBJECT_POOL: - return 350; // Modded to 700 @ CGameSA.cpp + return 350; // Modded to 700 @ CGameSA.cpp case DUMMY_POOL: return 2500; case VEHICLE_POOL: return 110; case COL_MODEL_POOL: - return 10150; // Modded to 12000 @ CGameSA.cpp + return 10150; // Modded to 12000 @ CGameSA.cpp case TASK_POOL: - return 500; // Modded to 5000 @ CGameSA.cpp + return 500; // Modded to 5000 @ CGameSA.cpp case EVENT_POOL: - return 200; // Modded to 5000 @ CGameSA.cpp + return 200; // Modded to 5000 @ CGameSA.cpp case TASK_ALLOCATOR_POOL: return 16; case PED_INTELLIGENCE_POOL: @@ -775,7 +886,7 @@ int CPoolsSA::GetPoolDefaultCapacity(ePools pool) case PED_ATTRACTOR_POOL: return 64; case ENTRY_INFO_NODE_POOL: - return 500; // Modded to 4096 @ CGameSA.cpp + return 500; // Modded to 4096 @ CGameSA.cpp case NODE_ROUTE_POOL: return 64; case PATROL_ROUTE_POOL: @@ -783,15 +894,15 @@ int CPoolsSA::GetPoolDefaultCapacity(ePools pool) case POINT_ROUTE_POOL: return 64; case POINTER_DOUBLE_LINK_POOL: - return 3200; // Modded to 8000 @ CGameSA.cpp + return 3200; // Modded to 8000 @ CGameSA.cpp case POINTER_SINGLE_LINK_POOL: return 70000; case ENV_MAP_MATERIAL_POOL: - return 4096; // Modded to 16000 @ CGameSA.cpp + return 4096; // Modded to 16000 @ CGameSA.cpp case ENV_MAP_ATOMIC_POOL: - return 1024; // Modded to 8000 @ CGameSA.cpp + return 1024; // Modded to 8000 @ CGameSA.cpp case SPEC_MAP_MATERIAL_POOL: - return 4096; // Modded to 16000 @ CGameSA.cpp + return 4096; // Modded to 16000 @ CGameSA.cpp } return 0; } @@ -951,25 +1062,25 @@ void CPoolsSA::SetPoolCapacity(ePools pool, int iValue) break; case TASK_ALLOCATOR_POOL: cPtr = 0x55124E; - break; // 0 - 127 + break; // 0 - 127 case PED_INTELLIGENCE_POOL: iPtr = 0x551283; break; case PED_ATTRACTOR_POOL: cPtr = 0x5512BB; - break; // 0 - 127 + break; // 0 - 127 case ENTRY_INFO_NODE_POOL: iPtr = 0x550FBA; break; case NODE_ROUTE_POOL: cPtr = 0x551218; - break; // 0 - 127 + break; // 0 - 127 case PATROL_ROUTE_POOL: cPtr = 0x5511E4; - break; // 0 - 127 + break; // 0 - 127 case POINT_ROUTE_POOL: cPtr = 0x5511AF; - break; // 0 - 127 + break; // 0 - 127 case POINTER_DOUBLE_LINK_POOL: iPtr = 0x550F82; break; @@ -987,10 +1098,10 @@ void CPoolsSA::SetPoolCapacity(ePools pool, int iValue) break; } if (iPtr) - MemPut(iPtr, iValue); + MemPut(iPtr, iValue); if (cPtr) - MemPut(cPtr, iValue); + MemPut(cPtr, static_cast(iValue)); } int CPoolsSA::GetNumberOfUsedSpaces(ePools pool) @@ -1072,7 +1183,8 @@ int CPoolsSA::GetNumberOfUsedSpaces(ePools pool) int iOut = -2; if (*(DWORD*)dwThis != NULL) { - _asm + // clang-format off + __asm { mov ecx, dwThis mov ecx, [ecx] @@ -1080,6 +1192,7 @@ int CPoolsSA::GetNumberOfUsedSpaces(ePools pool) mov iOut, eax } + // clang-format on } return iOut; diff --git a/Client/game_sa/CPoolsSA.h b/Client/game_sa/CPoolsSA.h index 524b7035c58..98bb9fd6cbf 100644 --- a/Client/game_sa/CPoolsSA.h +++ b/Client/game_sa/CPoolsSA.h @@ -43,7 +43,7 @@ class CPoolsSA : public CPools SClientEntity* GetVehicle(DWORD* pGameInterface); SClientEntity* GetVehicle(size_t pos) { return &m_vehiclePool.arrayOfClientEntities[pos]; }; unsigned long GetVehicleCount() { return m_vehiclePool.ulCount; }; - void DeleteAllVehicles(); + void DeleteAllVehicles(); // Objects pool CObject* AddObject(CClientObject* pClientObject, DWORD dwModelID, bool bLowLod, bool bBreakingDisabled); @@ -70,7 +70,7 @@ class CPoolsSA : public CPools SClientEntity* GetPed(DWORD* pGameInterface); SClientEntity* GetPed(size_t pos) { return &m_pedPool.arrayOfClientEntities[pos]; }; CPed* GetPedFromRef(DWORD dwGameRef); - CPedSAInterface* GetPedInterface(DWORD dwGameRef); // game_sa specific + CPedSAInterface* GetPedInterface(DWORD dwGameRef); // game_sa specific unsigned long GetPedCount() { return m_pedPool.ulCount; } void DeleteAllPeds(); @@ -95,24 +95,24 @@ class CPoolsSA : public CPools void ResetPedPoolCount() { m_pedPool.ulCount = 0; } void InvalidateLocalPlayerClientEntity(); - CBuildingsPool& GetBuildingsPool() noexcept override { return m_BuildingsPool; }; - CDummyPool& GetDummyPool() noexcept { return m_DummyPool; }; - CTxdPool& GetTxdPool() noexcept { return m_TxdPool; }; + CBuildingsPool& GetBuildingsPool() noexcept override { return m_BuildingsPool; }; + CDummyPool& GetDummyPool() noexcept { return m_DummyPool; }; + CTxdPool& GetTxdPool() noexcept { return m_TxdPool; }; CPtrNodeSingleLinkPool& GetPtrNodeSingleLinkPool() noexcept override { return m_PtrNodeSingleLinkPool; }; private: // Pools - SPoolData m_vehiclePool; - SPoolData m_pedPool; - SPoolData m_objectPool; + SPoolData m_vehiclePool; + SPoolData m_pedPool; + SPoolData m_objectPool; - CPoolSAInterface** m_ppPedPoolInterface; - CPoolSAInterface** m_ppObjectPoolInterface; - CPoolSAInterface** m_ppVehiclePoolInterface; + CPoolSAInterface** m_ppPedPoolInterface; + CPoolSAInterface** m_ppObjectPoolInterface; + CPoolSAInterface** m_ppVehiclePoolInterface; - CBuildingsPoolSA m_BuildingsPool; - CDummyPoolSA m_DummyPool; - CTxdPoolSA m_TxdPool; + CBuildingsPoolSA m_BuildingsPool; + CDummyPoolSA m_DummyPool; + CTxdPoolSA m_TxdPool; CPtrNodeSingleLinkPoolSA m_PtrNodeSingleLinkPool; bool m_bGetVehicleEnabled; @@ -121,44 +121,44 @@ class CPoolsSA : public CPools #define FUNC_GetPed 0x54ff90 #define CLASS_CPool_Vehicle 0xB74494 -#define CLASS_CPool_Ped 0xB74490 -#define CLASS_CPool_Object 0xB7449C - -#define CLASS_CBuildingPool 0xb74498 -#define CLASS_CPedPool 0xb74490 -#define CLASS_CObjectPool 0xb7449c -#define CLASS_CDummyPool 0xb744a0 -#define CLASS_CVehiclePool 0xb74494 -#define CLASS_CColModelPool 0xb744a4 -#define CLASS_CTaskPool 0xb744a8 -#define CLASS_CEventPool 0xb744ac -#define CLASS_CTaskAllocatorPool 0xb744bc -#define CLASS_CPedIntelligencePool 0xb744c0 -#define CLASS_CPedAttractorPool 0xb744c4 -#define CLASS_CEntryInfoNodePool 0xb7448c -#define CLASS_CNodeRoutePool 0xb744b8 -#define CLASS_CPatrolRoutePool 0xb744b4 -#define CLASS_CPointRoutePool 0xb744b0 +#define CLASS_CPool_Ped 0xB74490 +#define CLASS_CPool_Object 0xB7449C + +#define CLASS_CBuildingPool 0xb74498 +#define CLASS_CPedPool 0xb74490 +#define CLASS_CObjectPool 0xb7449c +#define CLASS_CDummyPool 0xb744a0 +#define CLASS_CVehiclePool 0xb74494 +#define CLASS_CColModelPool 0xb744a4 +#define CLASS_CTaskPool 0xb744a8 +#define CLASS_CEventPool 0xb744ac +#define CLASS_CTaskAllocatorPool 0xb744bc +#define CLASS_CPedIntelligencePool 0xb744c0 +#define CLASS_CPedAttractorPool 0xb744c4 +#define CLASS_CEntryInfoNodePool 0xb7448c +#define CLASS_CNodeRoutePool 0xb744b8 +#define CLASS_CPatrolRoutePool 0xb744b4 +#define CLASS_CPointRoutePool 0xb744b0 #define CLASS_CPtrNodeDoubleLinkPool 0xB74488 #define CLASS_CPtrNodeSingleLinkPool 0xB74484 -#define FUNC_CBuildingPool_GetNoOfUsedSpaces 0x550620 -#define FUNC_CPedPool_GetNoOfUsedSpaces 0x5504A0 -#define FUNC_CObjectPool_GetNoOfUsedSpaces 0x54F6B0 -#define FUNC_CDummyPool_GetNoOfUsedSpaces 0x5507A0 -#define FUNC_CVehiclePool_GetNoOfUsedSpaces 0x42CCF0 -#define FUNC_CColModelPool_GetNoOfUsedSpaces 0x550870 -#define FUNC_CTaskPool_GetNoOfUsedSpaces 0x550940 -#define FUNC_CEventPool_GetNoOfUsedSpaces 0x550A10 -#define FUNC_CTaskAllocatorPool_GetNoOfUsedSpaces 0x550d50 -#define FUNC_CPedIntelligencePool_GetNoOfUsedSpaces 0x550E20 -#define FUNC_CPedAttractorPool_GetNoOfUsedSpaces 0x550ef0 -#define FUNC_CEntryInfoNodePool_GetNoOfUsedSpaces 0x5503d0 -#define FUNC_CNodeRoutePool_GetNoOfUsedSpaces 0x550c80 -#define FUNC_CPatrolRoutePool_GetNoOfUsedSpaces 0x550bb0 -#define FUNC_CPointRoutePool_GetNoOfUsedSpaces 0x550ae0 +#define FUNC_CBuildingPool_GetNoOfUsedSpaces 0x550620 +#define FUNC_CPedPool_GetNoOfUsedSpaces 0x5504A0 +#define FUNC_CObjectPool_GetNoOfUsedSpaces 0x54F6B0 +#define FUNC_CDummyPool_GetNoOfUsedSpaces 0x5507A0 +#define FUNC_CVehiclePool_GetNoOfUsedSpaces 0x42CCF0 +#define FUNC_CColModelPool_GetNoOfUsedSpaces 0x550870 +#define FUNC_CTaskPool_GetNoOfUsedSpaces 0x550940 +#define FUNC_CEventPool_GetNoOfUsedSpaces 0x550A10 +#define FUNC_CTaskAllocatorPool_GetNoOfUsedSpaces 0x550d50 +#define FUNC_CPedIntelligencePool_GetNoOfUsedSpaces 0x550E20 +#define FUNC_CPedAttractorPool_GetNoOfUsedSpaces 0x550ef0 +#define FUNC_CEntryInfoNodePool_GetNoOfUsedSpaces 0x5503d0 +#define FUNC_CNodeRoutePool_GetNoOfUsedSpaces 0x550c80 +#define FUNC_CPatrolRoutePool_GetNoOfUsedSpaces 0x550bb0 +#define FUNC_CPointRoutePool_GetNoOfUsedSpaces 0x550ae0 #define FUNC_CPtrNodeSingleLinkPool_GetNoOfUsedSpaces 0x550230 #define FUNC_CPtrNodeDoubleLinkPool_GetNoOfUsedSpaces 0x550300 #define FUNC_CTrain_CreateMissionTrain 0x6F7550 -#define VAR_TrainModelArray 0x8D44F8 +#define VAR_TrainModelArray 0x8D44F8 diff --git a/Client/game_sa/CProjectileInfoSA.cpp b/Client/game_sa/CProjectileInfoSA.cpp index ec5897b514a..50fd37005ce 100644 --- a/Client/game_sa/CProjectileInfoSA.cpp +++ b/Client/game_sa/CProjectileInfoSA.cpp @@ -49,23 +49,18 @@ void CProjectileInfoSA::RemoveProjectile(CProjectileInfo* pProjectileInfo, CProj if (bBlow) { DWORD dwFunc = FUNC_RemoveProjectile; - _asm - { - push projectileInterface - push projectileInfoInterface - call dwFunc - add esp, 8 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(projectileInfoInterface), decltype(projectileInterface)); + reinterpret_cast(dwFunc)(projectileInfoInterface, projectileInterface); + // clang-format on } else { DWORD dwFunc = FUNC_RemoveIfThisIsAProjectile; - _asm - { - push projectileInterface - call dwFunc - add esp, 4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(projectileInterface)); + reinterpret_cast(dwFunc)(projectileInterface); + // clang-format on } } } @@ -111,7 +106,8 @@ bool CProjectileInfoSA::AddProjectile(CEntity* creator, eWeaponType eWeapon, CVe targetVC = pTargetEntitySA->GetInterface(); } - _asm + // clang-format off + __asm { push eax @@ -130,6 +126,7 @@ bool CProjectileInfoSA::AddProjectile(CEntity* creator, eWeaponType eWeapon, CVe pop eax } + // clang-format on pGame->GetWorld()->IgnoreEntity(nullptr); return dwReturn != 0; } diff --git a/Client/game_sa/CProjectileInfoSA.h b/Client/game_sa/CProjectileInfoSA.h index 5bcb33c6290..17649c33bea 100644 --- a/Client/game_sa/CProjectileInfoSA.h +++ b/Client/game_sa/CProjectileInfoSA.h @@ -14,16 +14,16 @@ #include #include "CProjectileSA.h" -#define PROJECTILE_COUNT 32 -#define PROJECTILE_INFO_COUNT 32 +#define PROJECTILE_COUNT 32 +#define PROJECTILE_INFO_COUNT 32 -#define FUNC_RemoveAllProjectiles 0x7399B0 //##SA## -#define FUNC_RemoveProjectile 0x7388F0 //##SA## -#define FUNC_RemoveIfThisIsAProjectile 0x739A40 //##SA## -#define FUNC_AddProjectile 0x737C80 //##SA## +#define FUNC_RemoveAllProjectiles 0x7399B0 // ##SA## +#define FUNC_RemoveProjectile 0x7388F0 // ##SA## +#define FUNC_RemoveIfThisIsAProjectile 0x739A40 // ##SA## +#define FUNC_AddProjectile 0x737C80 // ##SA## -#define ARRAY_CProjectile 0xC89110 //##SA## -#define ARRAY_CProjectileInfo 0xC891A8 //##SA## +#define ARRAY_CProjectile 0xC89110 // ##SA## +#define ARRAY_CProjectileInfo 0xC891A8 // ##SA## // #pragma pack(push,1) class CProjectileInfoSAInterface diff --git a/Client/game_sa/CProjectileSA.cpp b/Client/game_sa/CProjectileSA.cpp index 939b87232b9..0625f4acb3c 100644 --- a/Client/game_sa/CProjectileSA.cpp +++ b/Client/game_sa/CProjectileSA.cpp @@ -43,19 +43,23 @@ CProjectileSA::~CProjectileSA() DWORD dwThis = (DWORD)this->GetInterface(); DWORD dwFunc = this->GetInterface()->vtbl->Remove; - _asm + // clang-format off + __asm { mov ecx, dwThis call dwFunc } + // clang-format on dwFunc = this->GetInterface()->vtbl->SCALAR_DELETING_DESTRUCTOR; // we use the vtbl so we can be type independent - _asm + // clang-format off + __asm { mov ecx, dwThis push 1 //delete too call dwFunc } + // clang-format on this->BeingDeleted = true; //((CPoolsSA *)pGame->GetPools())->RemoveObject((CObject *)(CObjectSA *)this); diff --git a/Client/game_sa/CProjectileSA.h b/Client/game_sa/CProjectileSA.h index 3a9d2caaf6f..4e46d38a2ee 100644 --- a/Client/game_sa/CProjectileSA.h +++ b/Client/game_sa/CProjectileSA.h @@ -14,7 +14,7 @@ #include #include "CObjectSA.h" -class CProjectileSAInterface : public CObjectSAInterface // entirely inherited from CObject +class CProjectileSAInterface : public CObjectSAInterface // entirely inherited from CObject { public: bool IsProjectableVTBL() const { return GetVTBL() == (void*)0x867030; }; @@ -30,7 +30,7 @@ class CProjectileSA : public virtual CProjectile, public virtual CObjectSA public: CProjectileSA(class CProjectileSAInterface* projectileInterface); ~CProjectileSA(); - void Destroy(bool bBlow = true); + void Destroy(bool bBlow = true); CProjectileSAInterface* GetProjectileInterface() const { return static_cast(m_pInterface); }; bool CalculateImpactPosition(CEntitySAInterface* pCollidedWith, CVector vecInputStart, CVector& vecInputEnd); diff --git a/Client/game_sa/CPtrNodeDoubleListSA.h b/Client/game_sa/CPtrNodeDoubleListSA.h index 93ac1ccd109..edc7279aea9 100644 --- a/Client/game_sa/CPtrNodeDoubleListSA.h +++ b/Client/game_sa/CPtrNodeDoubleListSA.h @@ -10,11 +10,11 @@ #pragma once -template +template class CPtrNodeDoubleLink { public: - T* pItem; + T* pItem; CPtrNodeDoubleLink* pNext; CPtrNodeDoubleLink* pPrev; }; diff --git a/Client/game_sa/CPtrNodeSingleLinkPoolSA.cpp b/Client/game_sa/CPtrNodeSingleLinkPoolSA.cpp index 42dfc5bdf1c..84cfcd2b8c3 100644 --- a/Client/game_sa/CPtrNodeSingleLinkPoolSA.cpp +++ b/Client/game_sa/CPtrNodeSingleLinkPoolSA.cpp @@ -20,15 +20,15 @@ CPtrNodeSingleLinkPoolSA::CPtrNodeSingleLinkPoolSA() m_customPool = new CPtrNodeSingleLinkPoolSA::pool_t(); } -constexpr std::uint32_t HOOKPOS_SingleLinkNodeConstructor = 0x552380; -constexpr std::size_t HOOKSIZE_SingleLinkNodeConstructor = 6; +constexpr std::uint32_t HOOKPOS_SingleLinkNodeConstructor = 0x552380; +constexpr std::size_t HOOKSIZE_SingleLinkNodeConstructor = 6; static CPtrNodeSingleLinkPoolSA::pool_item_t* __cdecl HOOK_SingleLinkNodeConstructor() { return CPtrNodeSingleLinkPoolSA::GetPoolInstance()->AllocateItem(); } -constexpr std::uint32_t HOOKPOS_SingleLinkNodeDestructor = 0x552390; -constexpr std::size_t HOOKSIZE_SingleLinkNodeDestructor = 6; +constexpr std::uint32_t HOOKPOS_SingleLinkNodeDestructor = 0x552390; +constexpr std::size_t HOOKSIZE_SingleLinkNodeDestructor = 6; static CPtrNodeSingleLinkPoolSA::pool_item_t* __cdecl HOOK_SingleLinkNodeDestructor(CPtrNodeSingleLinkPoolSA::pool_item_t* item) { CPtrNodeSingleLinkPoolSA::GetPoolInstance()->RemoveItem(item); @@ -37,23 +37,27 @@ static CPtrNodeSingleLinkPoolSA::pool_item_t* __cdecl HOOK_SingleLinkNodeDestruc } // Replace pool->RemoveItem here -constexpr std::uint32_t HOOKPOS_CPtrListSingleLink_Flush = 0x55243B; -constexpr std::size_t HOOKSIZE_CPtrListSingleLink_Flush = 6; -constexpr std::uint32_t CONTINUE_CPtrListSingleLink_Flush = 0x55245B; -static void _declspec(naked) HOOK_CPtrListSingleLink_Flush() +constexpr std::uint32_t HOOKPOS_CPtrListSingleLink_Flush = 0x55243B; +constexpr std::size_t HOOKSIZE_CPtrListSingleLink_Flush = 6; +constexpr std::uint32_t CONTINUE_CPtrListSingleLink_Flush = 0x55245B; +static void __declspec(naked) HOOK_CPtrListSingleLink_Flush() { - __asm { - mov edi, ecx ; save register + MTA_VERIFY_HOOK_LOCAL_SIZE; - ; CPtrNodeSingleLinkPoolSA::m_customPool->RemoveItem(eax) + // clang-format off + __asm + { + mov edi, ecx // save register - mov ecx, CPtrNodeSingleLinkPoolSA::m_customPool - push eax - call CPtrNodeSingleLinkPoolSA::pool_t::RemoveItem + // CPtrNodeSingleLinkPoolSA::m_customPool->RemoveItem(eax) + mov ecx, CPtrNodeSingleLinkPoolSA::m_customPool + push eax + call CPtrNodeSingleLinkPoolSA::pool_t::RemoveItem - mov ecx, edi ; restore - jmp CONTINUE_CPtrListSingleLink_Flush + mov ecx, edi // restore register + jmp CONTINUE_CPtrListSingleLink_Flush } + // clang-format on } void CPtrNodeSingleLinkPoolSA::StaticSetHooks() @@ -65,4 +69,3 @@ void CPtrNodeSingleLinkPoolSA::StaticSetHooks() // Skip the original pool initialization MemCpy((void*)0x550F26, "\xEB\x2D", 2); } - diff --git a/Client/game_sa/CPtrNodeSingleLinkPoolSA.h b/Client/game_sa/CPtrNodeSingleLinkPoolSA.h index 1043f704c76..0ee39783a09 100644 --- a/Client/game_sa/CPtrNodeSingleLinkPoolSA.h +++ b/Client/game_sa/CPtrNodeSingleLinkPoolSA.h @@ -10,7 +10,7 @@ *****************************************************************************/ #pragma once - + #include "CPoolSAInterface.h" #include "CDynamicPool.h" #include "CPtrNodeSingleListSA.h" @@ -30,8 +30,9 @@ class CPtrNodeSingleLinkPoolSA final : public CPtrNodeSingleLinkPool bool Resize(std::size_t newSize) override { return m_customPool->SetCapacity(newSize); }; void ResetCapacity() override { m_customPool->SetCapacity(MAX_POINTER_SINGLE_LINKS); }; - static auto* GetPoolInstance() { return m_customPool; } - static void StaticSetHooks(); + static auto* GetPoolInstance() { return m_customPool; } + static void StaticSetHooks(); + private: static pool_t* m_customPool; }; diff --git a/Client/game_sa/CQuadTreeNodeSA.h b/Client/game_sa/CQuadTreeNodeSA.h index 81d47c43e55..beefe0dc767 100644 --- a/Client/game_sa/CQuadTreeNodeSA.h +++ b/Client/game_sa/CQuadTreeNodeSA.h @@ -14,7 +14,7 @@ #include "CPtrNodeSingleListSA.h" #include "CRect.h" -template +template class CQuadTreeNodesSAInterface { public: @@ -22,13 +22,13 @@ class CQuadTreeNodesSAInterface char AddItem(T* item, CRect* boudingBox); private: - float m_fX; - float m_fY; - float m_fW; - float m_fH; + float m_fX; + float m_fY; + float m_fW; + float m_fH; CPtrNodeSingleListSAInterface m_pItemList; - CQuadTreeNodesSAInterface* m_childrens[4]; - uint32_t m_level; + CQuadTreeNodesSAInterface* m_childrens[4]; + uint32_t m_level; }; static_assert(sizeof(CQuadTreeNodesSAInterface) == 0x28, "Wrong CQuadTreeNodesSAInterface size"); diff --git a/Client/game_sa/CRadarSA.cpp b/Client/game_sa/CRadarSA.cpp index c9b4966c7b4..7a5b2f44bbf 100644 --- a/Client/game_sa/CRadarSA.cpp +++ b/Client/game_sa/CRadarSA.cpp @@ -51,11 +51,12 @@ CMarker* CRadarSA::GetFreeMarker() { Index++; } - if (Index >= MAX_MARKERS) + if (Index >= MAX_MARKERS) { return NULL; - else + } else { return Markers[Index]; } +} void CRadarSA::DrawAreaOnRadar(float fX1, float fY1, float fX2, float fY2, const SharedUtil::SColor color) { @@ -63,7 +64,8 @@ void CRadarSA::DrawAreaOnRadar(float fX1, float fY1, float fX2, float fY2, const unsigned long abgr = color.A << 24 | color.B << 16 | color.G << 8 | color.R; CRect myRect(fX1, fY2, fX2, fY1); DWORD dwFunc = FUNC_DrawAreaOnRadar; - _asm + // clang-format off + __asm { push eax @@ -77,4 +79,5 @@ void CRadarSA::DrawAreaOnRadar(float fX1, float fY1, float fX2, float fY2, const pop eax } + // clang-format on } diff --git a/Client/game_sa/CRadarSA.h b/Client/game_sa/CRadarSA.h index db1fdb1d9ec..d060b0b9152 100644 --- a/Client/game_sa/CRadarSA.h +++ b/Client/game_sa/CRadarSA.h @@ -14,11 +14,11 @@ #include #include "CMarkerSA.h" -#define ARRAY_CMarker 0xBA86F0 -#define MAX_MARKERS 175 +#define ARRAY_CMarker 0xBA86F0 +#define MAX_MARKERS 175 -#define FUNC_DrawAreaOnRadar 0x5853d0 -#define FUNC_SetCoordBlip 0x583820 +#define FUNC_DrawAreaOnRadar 0x5853d0 +#define FUNC_SetCoordBlip 0x583820 class CRadarSA : public CRadar { diff --git a/Client/game_sa/CRegisteredCoronaSA.cpp b/Client/game_sa/CRegisteredCoronaSA.cpp index de80f549a88..959114b26ce 100644 --- a/Client/game_sa/CRegisteredCoronaSA.cpp +++ b/Client/game_sa/CRegisteredCoronaSA.cpp @@ -124,7 +124,7 @@ void CRegisteredCoronaSA::Init(DWORD Identifier) internalInterface->FlareType = 0; internalInterface->ReflectionType = 0; internalInterface->JustCreated = 1; - internalInterface->RegisteredThisFrame = 1; // won't appear in-game without this + internalInterface->RegisteredThisFrame = 1; // won't appear in-game without this } void CRegisteredCoronaSA::Refresh() diff --git a/Client/game_sa/CRegisteredCoronaSA.h b/Client/game_sa/CRegisteredCoronaSA.h index 2c9ac27705e..f44a15863b5 100644 --- a/Client/game_sa/CRegisteredCoronaSA.h +++ b/Client/game_sa/CRegisteredCoronaSA.h @@ -16,35 +16,35 @@ class CEntitySAInterface; -#define ARRAY_CORONAS 0xC3E058 +#define ARRAY_CORONAS 0xC3E058 -class CRegisteredCoronaSAInterface // coronas are 104 bytes long, and theres 56 of them +class CRegisteredCoronaSAInterface // coronas are 104 bytes long, and theres 56 of them { public: - CVector Coordinates; // Where is it exactly. - DWORD Identifier; // Should be unique for each corona. Address or something (0 = empty) - RwTexture* pTex; // Pointer to the actual texture to be rendered - float Size; // How big is this fellow - float NormalAngle; // Is corona normal (if relevant) facing the camera? - float Range; // How far away is this guy still visible - float PullTowardsCam; // How far away is the z value pulled towards camera. - float HeightAboveGround; // Stired so that we don't have to do a ProcessVerticalLine every frame - // The following fields are used for trails behind coronas (glowy lights) - float FadeSpeed; // The speed the corona fades in and out ##SA## - BYTE Red, Green, Blue; // Rendering colour. - BYTE Intensity; // 255 = full - BYTE FadedIntensity; // Intensity that lags behind the given intenisty and fades out if the LOS is blocked - BYTE RegisteredThisFrame; // Has this guy been registered by game code this frame - BYTE FlareType; // What type of flare to render - BYTE ReflectionType; // What type of reflection during wet weather - BYTE LOSCheck : 1; // Do we check the LOS or do we render at the right Z value - BYTE OffScreen : 1; // Set by the rendering code to be used by the update code - BYTE JustCreated; // If this guy has been created this frame we won't delete it (It hasn't had the time to get its OffScreen cleared) ##SA - // removed from packed byte ## - BYTE NeonFade : 1; // Does the guy fade out when closer to cam - BYTE OnlyFromBelow : 1; // This corona is only visible if the camera is below it. ##SA## + CVector Coordinates; // Where is it exactly. + DWORD Identifier; // Should be unique for each corona. Address or something (0 = empty) + RwTexture* pTex; // Pointer to the actual texture to be rendered + float Size; // How big is this fellow + float NormalAngle; // Is corona normal (if relevant) facing the camera? + float Range; // How far away is this guy still visible + float PullTowardsCam; // How far away is the z value pulled towards camera. + float HeightAboveGround; // Stired so that we don't have to do a ProcessVerticalLine every frame + // The following fields are used for trails behind coronas (glowy lights) + float FadeSpeed; // The speed the corona fades in and out ##SA## + BYTE Red, Green, Blue; // Rendering colour. + BYTE Intensity; // 255 = full + BYTE FadedIntensity; // Intensity that lags behind the given intenisty and fades out if the LOS is blocked + BYTE RegisteredThisFrame; // Has this guy been registered by game code this frame + BYTE FlareType; // What type of flare to render + BYTE ReflectionType; // What type of reflection during wet weather + BYTE LOSCheck : 1; // Do we check the LOS or do we render at the right Z value + BYTE OffScreen : 1; // Set by the rendering code to be used by the update code + BYTE JustCreated; // If this guy has been created this frame we won't delete it (It hasn't had the time to get its OffScreen cleared) ##SA + // removed from packed byte ## + BYTE NeonFade : 1; // Does the guy fade out when closer to cam + BYTE OnlyFromBelow : 1; // This corona is only visible if the camera is below it. ##SA## BYTE bHasValidHeightAboveGround : 1; - BYTE WhiteCore : 1; // This corona rendered with a small white core. + BYTE WhiteCore : 1; // This corona rendered with a small white core. BYTE bIsAttachedToEntity : 1; CEntitySAInterface* pEntityAttachedTo; diff --git a/Client/game_sa/CRenderWareSA.ClothesReplacing.cpp b/Client/game_sa/CRenderWareSA.ClothesReplacing.cpp index 8d797a4c092..c67fa54815d 100644 --- a/Client/game_sa/CRenderWareSA.ClothesReplacing.cpp +++ b/Client/game_sa/CRenderWareSA.ClothesReplacing.cpp @@ -20,13 +20,13 @@ namespace ushort usNext; ushort usPrev; - ushort uiUnknown1; // Parent ? - uchar uiUnknown2; // 0x12 when loading, 0x02 when finished loading + ushort uiUnknown1; // Parent ? + uchar uiUnknown2; // 0x12 when loading, 0x02 when finished loading uchar ucImgId; int iBlockOffset; int iBlockCount; - uint uiLoadflag; // 0-not loaded 2-requested 3-loaded 1-processed + uint uiLoadflag; // 0-not loaded 2-requested 3-loaded 1-processed }; std::unordered_map ms_ReplacementClothesFileDataMap; @@ -59,7 +59,7 @@ namespace auto blockDiv = std::div(size, 2048); return (blockDiv.quot + (blockDiv.rem ? 1 : 0)); } -} // namespace +} // namespace //////////////////////////////////////////////////////////////// // @@ -73,11 +73,15 @@ void CRenderWareSA::ClothesAddReplacement(char* pFileData, size_t fileSize, usho if (!pFileData) return; + const size_t streamingSizeBlocks = GetSizeInBlocks(fileSize); + if (streamingSizeBlocks > 0xFFFF) + return; + if (pFileData != MapFindRef(ms_ReplacementClothesFileDataMap, usFileId)) { MapSet(ms_ReplacementClothesFileDataMap, usFileId, pFileData); MapSet(ms_OriginalStreamingSizesMap, usFileId, g_clothesDirectory->GetModelStreamingSize(usFileId)); - g_clothesDirectory->SetModelStreamingSize(usFileId, GetSizeInBlocks(fileSize)); + g_clothesDirectory->SetModelStreamingSize(usFileId, static_cast(streamingSizeBlocks)); clothesReplacementChanged = true; } @@ -110,8 +114,9 @@ void CRenderWareSA::ClothesRemoveReplacement(char* pFileData) iter = ms_ReplacementClothesFileDataMap.erase(iter); clothesReplacementChanged = true; } - else + else { ++iter; +} } } @@ -145,7 +150,10 @@ bool CRenderWareSA::ClothesAddFile(const char* fileData, std::size_t fileSize, c return false; DirectoryInfoSA entry{}; - entry.m_streamingSize = GetSizeInBlocks(fileSize); + const size_t streamingSizeBlocks = GetSizeInBlocks(fileSize); + if (streamingSizeBlocks > 0xFFFF) + return false; + entry.m_streamingSize = static_cast(streamingSizeBlocks); std::size_t nameSize = sizeof(entry.m_name) - 1; std::strncpy(entry.m_name, fileName, nameSize); @@ -172,6 +180,8 @@ bool CRenderWareSA::ClothesRemoveFile(char* fileData) if (!fileData) return false; + bool removed = false; + for (auto iter = ms_ClothesFileDataMap.begin(); iter != ms_ClothesFileDataMap.end();) { if (iter->second == fileData) @@ -181,10 +191,14 @@ bool CRenderWareSA::ClothesRemoveFile(char* fileData) iter = ms_ClothesFileDataMap.erase(iter); clothesReplacementChanged = true; + removed = true; } - else + else { ++iter; +} } + + return removed; } //////////////////////////////////////////////////////////////// @@ -194,7 +208,7 @@ bool CRenderWareSA::ClothesRemoveFile(char* fileData) // Check if clothe file exits // //////////////////////////////////////////////////////////////// -bool CRenderWareSA::HasClothesFile(const char* fileName) const noexcept +bool CRenderWareSA::HasClothesFile(const char* fileName) const { return fileName && MapFind(ms_ClothesFileDataMap, fileName); } @@ -217,14 +231,15 @@ __declspec(noinline) bool _cdecl OnCStreaming_RequestModel_Mid(int flags, SImgGT if (ms_ReplacementClothesFileDataMap.empty() && ms_ClothesFileDataMap.empty()) return false; - // Initialze lookup map if needed - static std::map blockOffsetToFileIdMap; - static std::map blockOffsetToFileNameMap; - if (blockOffsetToFileIdMap.empty()) + static std::map blockOffsetToFileIdMap; + std::map blockOffsetToFileNameMap; + + if (blockOffsetToFileIdMap.empty() || ms_ClothesFileDataMap.size() > 0) { // Check is player.img dir has been loaded by GTA SPlayerImgItemArray* pItemArray = (SPlayerImgItemArray*)0x00BC12C0; - std::uint32_t maxArraySize = 542 + ms_ClothesFileDataMap.size(); + std::uint32_t defaultArraySize = 542; + std::uint32_t maxArraySize = defaultArraySize + ms_ClothesFileDataMap.size(); if (!pItemArray->pItems || pItemArray->uiArraySize != maxArraySize) return false; @@ -232,7 +247,10 @@ __declspec(noinline) bool _cdecl OnCStreaming_RequestModel_Mid(int flags, SImgGT for (std::uint32_t i = 0; i < pItemArray->uiArraySize; i++) { SPlayerImgItem* pImgItem = &pItemArray->pItems[i]; - MapSet(blockOffsetToFileIdMap, pImgItem->uiBlockOffset, i); + + if (i < defaultArraySize) + MapSet(blockOffsetToFileIdMap, pImgItem->uiBlockOffset, i); + MapSet(blockOffsetToFileNameMap, pImgItem->uiBlockOffset, pImgItem->szName); } } @@ -254,8 +272,8 @@ __declspec(noinline) bool _cdecl OnCStreaming_RequestModel_Mid(int flags, SImgGT if (!replacementFileData) return false; - // If bLoadingBigModel is set, try to get it unset - #define VAR_CStreaming_bLoadingBigModel 0x08E4A58 + // If bLoadingBigModel is set, try to get it unset +#define VAR_CStreaming_bLoadingBigModel 0x08E4A58 BYTE& bLoadingBigModel = *(BYTE*)VAR_CStreaming_bLoadingBigModel; if (bLoadingBigModel) { @@ -279,13 +297,16 @@ __declspec(noinline) bool _cdecl OnCStreaming_RequestModel_Mid(int flags, SImgGT } // Hook info -#define HOOKPOS_CStreaming_RequestModel_Mid 0x040895A -#define HOOKSIZE_CStreaming_RequestModel_Mid 5 -DWORD RETURN_CStreaming_RequestModel_MidA = 0x0408960; -DWORD RETURN_CStreaming_RequestModel_MidB = 0x0408990; -void _declspec(naked) HOOK_CStreaming_RequestModel_Mid() +#define HOOKPOS_CStreaming_RequestModel_Mid 0x040895A +#define HOOKSIZE_CStreaming_RequestModel_Mid 5 +DWORD RETURN_CStreaming_RequestModel_MidA = 0x0408960; +DWORD RETURN_CStreaming_RequestModel_MidB = 0x0408990; +static void __declspec(naked) HOOK_CStreaming_RequestModel_Mid() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi @@ -301,12 +322,8 @@ void _declspec(naked) HOOK_CStreaming_RequestModel_Mid() push eax jmp RETURN_CStreaming_RequestModel_MidA - // Handle load here -skip: - popad - pushad - + skip: mov eax, 0 push eax mov eax, iReturnFileId @@ -319,6 +336,7 @@ void _declspec(naked) HOOK_CStreaming_RequestModel_Mid() popad jmp RETURN_CStreaming_RequestModel_MidB } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/game_sa/CRenderWareSA.ShaderMatching.cpp b/Client/game_sa/CRenderWareSA.ShaderMatching.cpp index e02023c99b5..c767d8bc1dc 100644 --- a/Client/game_sa/CRenderWareSA.ShaderMatching.cpp +++ b/Client/game_sa/CRenderWareSA.ShaderMatching.cpp @@ -7,11 +7,45 @@ *****************************************************************************/ #include "StdInc.h" +#include +#include #include #include "CRenderWareSA.ShaderMatching.h" uint CMatchChannel::ms_uiIdCounter = 1; +namespace +{ + ////////////////////////////////////////////////////////////////// + // + constexpr bool ENABLE_STALE_ENTITY_CLEANUP = true; + constexpr std::size_t NUM_STALE_ENTITY_CLEANUP_MAX_BATCH = 128; + constexpr std::size_t NUM_STALE_ENTITY_CLEANUP_MAX_QUEUE = 2048; + constexpr std::size_t NUM_STALE_ENTITY_CLEANUP_MAX_KEYS_PER_BATCH = 128; + + struct SStaleEntityCleanupBudget + { + long long llIntervalMs; + std::size_t uiBatchSize; + std::size_t uiProbeBudget; + long long llTimeBudgetUs; + }; + + static SStaleEntityCleanupBudget GetStaleEntityCleanupBudget(std::size_t uiTrackedEntities) + { + if (uiTrackedEntities >= 4096) + return {300, 96, 1024, 800}; + + if (uiTrackedEntities >= 1024) + return {700, 48, 512, 450}; + + if (uiTrackedEntities >= 256) + return {1400, 24, 192, 250}; + + return {2400, 12, 96, 120}; + } +} // namespace + ////////////////////////////////////////////////////////////////// // // CMatchChannelManager::AppendAdditiveMatch @@ -45,22 +79,28 @@ void CMatchChannelManager::AppendAdditiveMatch(CSHADERDUMMY* pShaderData, CClien ////////////////////////////////////////////////////////////////// void CMatchChannelManager::AppendSubtractiveMatch(CSHADERDUMMY* pShaderData, CClientEntityBase* pClientEntity, const SString& strTextureNameMatch) { - bool bAppendLayers = false; - // Don't bother if shader hasn't been seen before SShaderInfo* pShaderInfo = GetShaderInfo(pShaderData, false, 0, false, TYPE_MASK_NONE, 0, false); if (!pShaderInfo) return; - // Don't bother if there are no existing additive matches for this pair - if (!MapContains(m_ChannelUsageMap, CShaderAndEntityPair(pShaderInfo, pClientEntity, bAppendLayers))) - return; - - // Make channel unique before modifying match chain - CMatchChannel* pChannel = GetChannelOnlyUsedBy(pShaderInfo, pClientEntity, bAppendLayers); - pChannel->AppendSubtractiveMatch(strTextureNameMatch.ToLower()); - AddToOptimizeQueue(pChannel); - AddToRematchQueue(pChannel); + const bool bAppendLayersVariants[2] = {false, true}; + for (uint uiVariant = 0; uiVariant < 2; ++uiVariant) + { + const bool bAppendLayers = bAppendLayersVariants[uiVariant]; + + // Handle both append-layer variants so subtractive updates apply + // to whichever variant currently owns this pair. + // Skip variants that are not currently used by this pair + if (!MapContains(m_ChannelUsageMap, CShaderAndEntityPair(pShaderInfo, pClientEntity, bAppendLayers))) + continue; + + // Make channel unique before modifying match chain + CMatchChannel* pChannel = GetChannelOnlyUsedBy(pShaderInfo, pClientEntity, bAppendLayers); + pChannel->AppendSubtractiveMatch(strTextureNameMatch.ToLower()); + AddToOptimizeQueue(pChannel); + AddToRematchQueue(pChannel); + } } ////////////////////////////////////////////////////////////////// @@ -72,24 +112,42 @@ void CMatchChannelManager::AppendSubtractiveMatch(CSHADERDUMMY* pShaderData, CCl ////////////////////////////////////////////////////////////////// void CMatchChannelManager::InsertTexture(STexInfo* pTexInfo) { + if (!pTexInfo) + return; + // Find/create TexNameInfo STexNameInfo* pTexNameInfo = MapFindRef(m_AllTextureList, pTexInfo->strTextureName); if (!pTexNameInfo) { // Create TexNameInfo - MapSet(m_AllTextureList, pTexInfo->strTextureName, new STexNameInfo(pTexInfo->strTextureName)); - pTexNameInfo = MapFindRef(m_AllTextureList, pTexInfo->strTextureName); + STexNameInfo* pNewTexNameInfo = new STexNameInfo(pTexInfo->strTextureName); - // Insert into existing channels - for (CFastHashSet::iterator iter = m_CreatedChannelList.begin(); iter != m_CreatedChannelList.end(); ++iter) + try { - CMatchChannel* pChannel = *iter; - if (pChannel->m_MatchChain.IsAdditiveMatch(pTexNameInfo->strTextureName)) + MapSet(m_AllTextureList, pTexInfo->strTextureName, pNewTexNameInfo); + pTexNameInfo = MapFindRef(m_AllTextureList, pTexInfo->strTextureName); + + if (!pTexNameInfo) [[unlikely]] { - pChannel->AddTexture(pTexNameInfo); - MapInsert(pTexNameInfo->matchChannelList, pChannel); + delete pNewTexNameInfo; + return; + } + + // Insert into existing channels + for (CMatchChannel* pChannel : m_CreatedChannelList) + { + if (pChannel->m_MatchChain.IsAdditiveMatch(pTexNameInfo->strTextureName)) + { + pChannel->AddTexture(pTexNameInfo); + MapInsert(pTexNameInfo->matchChannelList, pChannel); + } } } + catch (...) + { + delete pNewTexNameInfo; + throw; + } } // Add association @@ -106,12 +164,19 @@ void CMatchChannelManager::InsertTexture(STexInfo* pTexInfo) ////////////////////////////////////////////////////////////////// void CMatchChannelManager::RemoveTexture(STexInfo* pTexInfo) { + if (!pTexInfo) + return; + STexNameInfo* pTexNameInfo = pTexInfo->pAssociatedTexNameInfo; - // Remove association - dassert(MapContains(pTexNameInfo->usedByTexInfoList, pTexInfo)); - MapRemove(pTexNameInfo->usedByTexInfoList, pTexInfo); - pTexInfo->pAssociatedTexNameInfo = NULL; + if (!pTexNameInfo) [[unlikely]] + return; + + if (MapContains(pTexNameInfo->usedByTexInfoList, pTexInfo)) [[likely]] + { + MapRemove(pTexNameInfo->usedByTexInfoList, pTexInfo); + pTexInfo->pAssociatedTexNameInfo = nullptr; + } } ////////////////////////////////////////////////////////////////// @@ -125,24 +190,25 @@ void CMatchChannelManager::FinalizeLayers(SShaderInfoLayers& shaderLayers) { // Sort layers by priority std::sort(shaderLayers.layerList.begin(), shaderLayers.layerList.end()); - uint uiNumLayers = shaderLayers.layerList.size(); + const std::size_t uiNumLayers = shaderLayers.layerList.size(); // Set output shaderLayers.output = SShaderItemLayers(); shaderLayers.output.layerList.resize(uiNumLayers); // Copy base - SShaderInfo* pShaderInfo = shaderLayers.pBase.pShaderInfo; - if (pShaderInfo) + if (const SShaderInfo* pBaseShaderInfo = shaderLayers.pBase.pShaderInfo) { - shaderLayers.output.pBase = pShaderInfo->pShaderData; - shaderLayers.output.bUsesVertexShader = pShaderInfo->bUsesVertexShader; + shaderLayers.output.pBase = pBaseShaderInfo->pShaderData; + shaderLayers.output.bUsesVertexShader = pBaseShaderInfo->bUsesVertexShader; } // Copy layers - for (uint i = 0; i < uiNumLayers; i++) + for (std::size_t i = 0; i < uiNumLayers; ++i) { - SShaderInfo* pShaderInfo = shaderLayers.layerList[i].pShaderInfo; + const SShaderInfo* pShaderInfo = shaderLayers.layerList[i].pShaderInfo; + if (!pShaderInfo) + continue; shaderLayers.output.layerList[i] = pShaderInfo->pShaderData; shaderLayers.output.bUsesVertexShader |= pShaderInfo->bUsesVertexShader; } @@ -164,31 +230,44 @@ STexShaderReplacement* CMatchChannelManager::UpdateTexShaderReplacement(STexName // If not done yet for this entity, needs to be done MapSet(pTexNameInfo->texEntityShaderMap, pClientEntity, STexShaderReplacement()); pTexShaderReplacement = MapFind(pTexNameInfo->texEntityShaderMap, pClientEntity); + + // Track which STexNameInfo entries reference this entity for fast cleanup + if (pClientEntity) + MapInsert(m_EntityToTexNameInfos[pClientEntity], pTexNameInfo); } - if (!pTexShaderReplacement->bSet) + if (!pTexShaderReplacement->bSet || !pTexShaderReplacement->bValid) { - // If not done yet for this entity, needs to be done - dassert(!pTexShaderReplacement->shaderLayers.pBase.pShaderInfo && pTexShaderReplacement->shaderLayers.layerList.empty()); + // If not calculated yet or invalidated, (re)build it + if (!pTexShaderReplacement->bValid) + { + // Clear invalidated data before rebuilding + pTexShaderReplacement->shaderLayers = SShaderInfoLayers(); + } + else + { + // Fresh entry - should be empty + dassert(!pTexShaderReplacement->shaderLayers.pBase.pShaderInfo && pTexShaderReplacement->shaderLayers.layerList.empty()); + } CalcShaderForTexAndEntity(pTexShaderReplacement->shaderLayers, pTexNameInfo, pClientEntity, iEntityType, false); pTexShaderReplacement->bSet = true; + pTexShaderReplacement->bValid = true; // texNoEntityShader need to be done also, so we can see what needs to be inherited from it + STexShaderReplacement& texNoEntityShader = pTexNameInfo->GetTexNoEntityShader(iEntityType); { - STexShaderReplacement& texNoEntityShader = pTexNameInfo->GetTexNoEntityShader(iEntityType); UpdateTexShaderReplacementNoEntity(pTexNameInfo, texNoEntityShader, iEntityType); // Handle base inheritance - if (pTexShaderReplacement->shaderLayers.pBase.pShaderInfo == NULL) + if (pTexShaderReplacement->shaderLayers.pBase.pShaderInfo == nullptr) { if (texNoEntityShader.shaderLayers.pBase.bMixEntityAndNonEntity) pTexShaderReplacement->shaderLayers.pBase = texNoEntityShader.shaderLayers.pBase; } // Handle layer inheritance - for (uint i = 0; i < texNoEntityShader.shaderLayers.layerList.size(); i++) + for (const SShaderInfoInstance& info : texNoEntityShader.shaderLayers.layerList) { - const SShaderInfoInstance& info = texNoEntityShader.shaderLayers.layerList[i]; if (info.bMixEntityAndNonEntity) pTexShaderReplacement->shaderLayers.layerList.push_back(info); } @@ -209,12 +288,22 @@ STexShaderReplacement* CMatchChannelManager::UpdateTexShaderReplacement(STexName ////////////////////////////////////////////////////////////////// void CMatchChannelManager::UpdateTexShaderReplacementNoEntity(STexNameInfo* pTexNameInfo, STexShaderReplacement& texNoEntityShader, int iEntityType) { - if (!texNoEntityShader.bSet) + if (!texNoEntityShader.bSet || !texNoEntityShader.bValid) { - // If not done yet, needs to be done - dassert(!texNoEntityShader.shaderLayers.pBase.pShaderInfo && texNoEntityShader.shaderLayers.layerList.empty()); - CalcShaderForTexAndEntity(texNoEntityShader.shaderLayers, pTexNameInfo, NULL, iEntityType, false); + // If not calculated yet or invalidated, (re)build it + if (!texNoEntityShader.bValid) + { + // Clear invalidated data before rebuilding + texNoEntityShader.shaderLayers = SShaderInfoLayers(); + } + else + { + // Fresh entry - should be empty + dassert(!texNoEntityShader.shaderLayers.pBase.pShaderInfo && texNoEntityShader.shaderLayers.layerList.empty()); + } + CalcShaderForTexAndEntity(texNoEntityShader.shaderLayers, pTexNameInfo, nullptr, iEntityType, false); texNoEntityShader.bSet = true; + texNoEntityShader.bValid = true; FinalizeLayers(texNoEntityShader.shaderLayers); } @@ -229,27 +318,35 @@ void CMatchChannelManager::UpdateTexShaderReplacementNoEntity(STexNameInfo* pTex ////////////////////////////////////////////////////////////////// SShaderInfoLayers* CMatchChannelManager::GetShaderForTexAndEntity(STexInfo* pTexInfo, CClientEntityBase* pClientEntity, int iEntityType) { + if (!pTexInfo) + return nullptr; + if (m_bChangesPending) FlushChanges(); STexNameInfo* pTexNameInfo = pTexInfo->pAssociatedTexNameInfo; + if (!pTexNameInfo) + return nullptr; + // Ignore unknown client entities - if (pClientEntity) + if (pClientEntity) { if (!MapContains(m_KnownClientEntities, pClientEntity)) - pClientEntity = NULL; + pClientEntity = nullptr; +} if (pClientEntity) { // Get entity info for this replace STexShaderReplacement* pTexShaderReplacement = MapFind(pTexNameInfo->texEntityShaderMap, pClientEntity); - if (!pTexShaderReplacement || !pTexShaderReplacement->bSet) + // Rebuild only if: doesn't exist, not yet calculated, or explicitly invalidated + if (!pTexShaderReplacement || !pTexShaderReplacement->bSet || !pTexShaderReplacement->bValid) { pTexShaderReplacement = UpdateTexShaderReplacement(pTexNameInfo, pClientEntity, iEntityType); } - #ifdef SHADER_DEBUG_CHECKS +#ifdef SHADER_DEBUG_CHECKS if (pTexNameInfo->iDebugCounter1++ > 400) { // Check cached shader is correct @@ -259,16 +356,15 @@ SShaderInfoLayers* CMatchChannelManager::GetShaderForTexAndEntity(STexInfo* pTex // Handle base inheritance STexShaderReplacement& texNoEntityShader = pTexNameInfo->GetTexNoEntityShader(iEntityType); - if (shaderLayersCheck1.pBase.pShaderInfo == NULL) + if (shaderLayersCheck1.pBase.pShaderInfo == nullptr) { if (texNoEntityShader.shaderLayers.pBase.bMixEntityAndNonEntity) shaderLayersCheck1.pBase = texNoEntityShader.shaderLayers.pBase; } // Handle layer inheritance - for (uint i = 0; i < texNoEntityShader.shaderLayers.layerList.size(); i++) + for (const SShaderInfoInstance& info : texNoEntityShader.shaderLayers.layerList) { - const SShaderInfoInstance& info = texNoEntityShader.shaderLayers.layerList[i]; if (info.bMixEntityAndNonEntity) shaderLayersCheck1.layerList.push_back(info); } @@ -276,7 +372,7 @@ SShaderInfoLayers* CMatchChannelManager::GetShaderForTexAndEntity(STexInfo* pTex FinalizeLayers(shaderLayersCheck1); assert(pTexShaderReplacement->shaderLayers == shaderLayersCheck1); } - #endif +#endif // Return layers for this entity return &pTexShaderReplacement->shaderLayers; @@ -285,22 +381,22 @@ SShaderInfoLayers* CMatchChannelManager::GetShaderForTexAndEntity(STexInfo* pTex { STexShaderReplacement& texNoEntityShader = pTexNameInfo->GetTexNoEntityShader(iEntityType); - if (!texNoEntityShader.bSet) + if (!texNoEntityShader.bSet || !texNoEntityShader.bValid) { UpdateTexShaderReplacementNoEntity(pTexNameInfo, texNoEntityShader, iEntityType); } - #ifdef SHADER_DEBUG_CHECKS +#ifdef SHADER_DEBUG_CHECKS if (pTexNameInfo->iDebugCounter2++ > 400) { // Check cached shader is correct pTexNameInfo->iDebugCounter2 = rand() % 100; SShaderInfoLayers shaderLayersCheck2; - CalcShaderForTexAndEntity(shaderLayersCheck2, pTexNameInfo, NULL, iEntityType, true); + CalcShaderForTexAndEntity(shaderLayersCheck2, pTexNameInfo, nullptr, iEntityType, true); FinalizeLayers(shaderLayersCheck2); assert(texNoEntityShader.shaderLayers == shaderLayersCheck2); } - #endif +#endif // Return layers for any entity return &texNoEntityShader.shaderLayers; @@ -321,9 +417,8 @@ void CMatchChannelManager::CalcShaderForTexAndEntity(SShaderInfoLayers& outShade const CFastHashSet& resultChannelList = pTexNameInfo->matchChannelList; // In each channel, get the best shader that has the correct entity - for (CFastHashSet::const_iterator iter = resultChannelList.begin(); iter != resultChannelList.end(); ++iter) + for (CMatchChannel* pChannel : resultChannelList) { - CMatchChannel* pChannel = *iter; pChannel->GetBestShaderForEntity(pClientEntity, iEntityType, outShaderLayers); } @@ -334,6 +429,428 @@ void CMatchChannelManager::CalcShaderForTexAndEntity(SShaderInfoLayers& outShade #endif } +////////////////////////////////////////////////////////////////// +// +// CMatchChannelManager::PulseStaleEntityCacheCleanup +// +// Rate-controlled periodic cleanup: +// 1. Remove all cache/index entries for entities no longer in m_KnownClientEntities +// 2. Prune invalidated (bValid=false) shader cache entries from active entities +// that haven't been rebuilt since the last cleanup interval +// +////////////////////////////////////////////////////////////////// +void CMatchChannelManager::PulseStaleEntityCacheCleanup() +{ + if (!ENABLE_STALE_ENTITY_CLEANUP) + return; + + const std::size_t uiTrackedEntities = m_EntityToTexNameInfos.size(); + if (uiTrackedEntities == 0 && m_StaleEntityChannelCleanupQueue.empty() && m_StaleEntityDeferredRetryKeys.empty()) + return; + + const std::size_t uiPendingDeferredWork = + m_StaleEntityChannelCleanupQueue.size() * NUM_STALE_ENTITY_CLEANUP_MAX_KEYS_PER_BATCH + m_StaleEntityDeferredRetryKeys.size(); + const std::size_t uiCleanupBudgetLoad = std::max(uiTrackedEntities, uiPendingDeferredWork); + const SStaleEntityCleanupBudget cleanupBudget = GetStaleEntityCleanupBudget(uiCleanupBudgetLoad); + const std::size_t uiTargetBatch = std::min(cleanupBudget.uiBatchSize, NUM_STALE_ENTITY_CLEANUP_MAX_BATCH); + + const long long llNow = GetTickCount64_(); + const bool bRunScan = (llNow >= m_llNextStaleEntityCleanupTime); + if (!bRunScan && m_StaleEntityChannelCleanupQueue.empty() && m_StaleEntityDeferredRetryKeys.empty()) + return; + + if (bRunScan) + { + m_llNextStaleEntityCleanupTime = llNow + cleanupBudget.llIntervalMs; + ++m_uiStaleEntityScanCycleCount; + } + + const std::size_t uiBucketCount = m_EntityToTexNameInfos.bucket_count(); + + std::array staleEntityList{}; + std::size_t uiStaleCount = 0; + std::array activeCacheCleanupList{}; + std::size_t uiActiveCount = 0; + const std::size_t uiDeferredChannelCleanupMaxPerPulse = (uiTargetBatch > 8) ? (uiTargetBatch / 2) : 4; + const long long llRetryTimeBudgetUs = std::max(40, cleanupBudget.llTimeBudgetUs / 2); + + const std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now(); + std::size_t uiProbes = 0; + std::size_t uiStartBucket = 0; + std::size_t uiCurrentBucket = 0; + bool bStopScan = false; + + if (uiBucketCount > 0) + uiStartBucket = m_uiStaleEntityCleanupCursorBucket % uiBucketCount; + + uiCurrentBucket = uiStartBucket; + + for (std::size_t uiBucketsVisited = 0; bRunScan && uiBucketsVisited < uiBucketCount && !bStopScan; ++uiBucketsVisited) + { + uiCurrentBucket = (uiStartBucket + uiBucketsVisited) % uiBucketCount; + for (std::unordered_map>::local_iterator iterEntity = m_EntityToTexNameInfos.begin(uiCurrentBucket); + iterEntity != m_EntityToTexNameInfos.end(uiCurrentBucket); ++iterEntity) + { + if (uiStaleCount >= uiTargetBatch) + { + bStopScan = true; + break; + } + + ++uiProbes; + if (uiProbes > cleanupBudget.uiProbeBudget) + { + bStopScan = true; + break; + } + + CClientEntityBase* pClientEntity = iterEntity->first; + if (!pClientEntity) + { + staleEntityList[uiStaleCount++] = pClientEntity; + continue; + } + + if (!MapContains(m_KnownClientEntities, pClientEntity)) { + staleEntityList[uiStaleCount++] = pClientEntity; + } else if (uiActiveCount < uiTargetBatch) { + activeCacheCleanupList[uiActiveCount++] = pClientEntity; +} + } + } + + if (bRunScan && uiBucketCount > 0) + m_uiStaleEntityCleanupCursorBucket = (uiCurrentBucket + 1) % uiBucketCount; + + for (std::size_t i = 0; i < uiStaleCount; ++i) + { + CClientEntityBase* pClientEntity = staleEntityList[i]; + std::unordered_map>::iterator iterTexNames = m_EntityToTexNameInfos.find(pClientEntity); + if (iterTexNames == m_EntityToTexNameInfos.end()) + continue; + + for (STexNameInfo* pTexNameInfo : iterTexNames->second) + { + if (pTexNameInfo) + MapRemove(pTexNameInfo->texEntityShaderMap, pClientEntity); + } + + m_EntityToTexNameInfos.erase(iterTexNames); + + // Queue channel and index cleanup to keep per-pulse work bounded. + std::unordered_map>::iterator iterEntityKeys = m_EntityToChannelKeys.find(pClientEntity); + if (iterEntityKeys != m_EntityToChannelKeys.end()) + { + const std::vector& sourceKeys = iterEntityKeys->second; + for (std::size_t k = 0; k < sourceKeys.size(); ++k) + { + CMatchChannel* pExpectedChannel = MapFindRef(m_ChannelUsageMap, sourceKeys[k]); + if (!pExpectedChannel) + continue; + + if (!TryPushDeferredKey(sourceKeys[k], pExpectedChannel)) + { + // Queue full - store remaining source keys for retry. + // The retry drain re-validates all keys, so unfiltered keys are safe. + std::vector& vecRetryKeys = m_StaleEntityDeferredRetryKeys[pClientEntity]; + vecRetryKeys.clear(); + vecRetryKeys.reserve(sourceKeys.size() - k); + for (std::size_t j = k; j < sourceKeys.size(); ++j) + { + if (sourceKeys[j].pClientEntity) + m_DeferredQueueEntityPresence.insert(sourceKeys[j].pClientEntity); + m_DeferredQueueShaderPresence.insert(sourceKeys[j].pShaderInfo); + vecRetryKeys.push_back(sourceKeys[j]); + } + break; + } + } + + m_EntityToChannelKeys.erase(iterEntityKeys); + } + } + + if (!m_StaleEntityDeferredRetryKeys.empty()) + { + std::size_t uiRetryEntitiesProcessed = 0; + while (uiRetryEntitiesProcessed < uiDeferredChannelCleanupMaxPerPulse && !m_StaleEntityDeferredRetryKeys.empty()) + { + if ((uiRetryEntitiesProcessed & 0x3) == 0) + { + const long long llElapsedUs = std::chrono::duration_cast(std::chrono::steady_clock::now() - startTime).count(); + if (llElapsedUs > llRetryTimeBudgetUs) + break; + } + + std::unordered_map>::iterator iterRetry = m_StaleEntityDeferredRetryKeys.begin(); + if (iterRetry == m_StaleEntityDeferredRetryKeys.end()) + break; + + CClientEntityBase* pClientEntity = iterRetry->first; + std::vector retryKeys = std::move(iterRetry->second); + m_StaleEntityDeferredRetryKeys.erase(iterRetry); + + if (retryKeys.empty()) + continue; + + if (retryKeys.size() > 1) + { + std::sort(retryKeys.begin(), retryKeys.end()); + retryKeys.erase(std::unique(retryKeys.begin(), retryKeys.end()), retryKeys.end()); + } + + bool bQueueSaturated = false; + for (std::size_t k = 0; k < retryKeys.size(); ++k) + { + const CShaderAndEntityPair& key = retryKeys[k]; + + if (key.pClientEntity && MapContains(m_KnownClientEntities, key.pClientEntity)) + { + std::unordered_map>::iterator itEnt = m_EntityToChannelKeys.find(key.pClientEntity); + if (itEnt != m_EntityToChannelKeys.end()) + { + bool bKeyStillIndexed = false; + for (const CShaderAndEntityPair& indexedKey : itEnt->second) + { + if (indexedKey.pShaderInfo == key.pShaderInfo && indexedKey.pClientEntity == key.pClientEntity && + indexedKey.bAppendLayers == key.bAppendLayers) + { + bKeyStillIndexed = true; + break; + } + } + + if (bKeyStillIndexed) + continue; + } + } + + CMatchChannel* pExpectedChannel = MapFindRef(m_ChannelUsageMap, key); + if (!pExpectedChannel) + continue; + + if (!TryPushDeferredKey(key, pExpectedChannel)) + { + // Queue full - return remaining keys to retry map. + std::vector& vecRetryKeys = m_StaleEntityDeferredRetryKeys[pClientEntity]; + vecRetryKeys.clear(); + vecRetryKeys.reserve(retryKeys.size() - k); + for (std::size_t j = k; j < retryKeys.size(); ++j) + { + if (retryKeys[j].pClientEntity) + m_DeferredQueueEntityPresence.insert(retryKeys[j].pClientEntity); + m_DeferredQueueShaderPresence.insert(retryKeys[j].pShaderInfo); + vecRetryKeys.push_back(retryKeys[j]); + } + bQueueSaturated = true; + break; + } + } + + if (bQueueSaturated) + break; + + ++uiRetryEntitiesProcessed; + } + } + + // Drain deferred channel cleanup with a per-pulse cap. + std::size_t uiDeferredCleaned = 0; + while (!m_StaleEntityChannelCleanupQueue.empty() && uiDeferredCleaned < uiDeferredChannelCleanupMaxPerPulse) + { + if ((uiDeferredCleaned & 0x3) == 0) + { + const long long llElapsedUs = std::chrono::duration_cast(std::chrono::steady_clock::now() - startTime).count(); + if (llElapsedUs > cleanupBudget.llTimeBudgetUs) + break; + } + + std::vector deferredChannelKeys = std::move(m_StaleEntityChannelCleanupQueue.front()); + m_StaleEntityChannelCleanupQueue.pop_front(); + + if (deferredChannelKeys.empty()) + continue; + + dassert(deferredChannelKeys.size() <= NUM_STALE_ENTITY_CLEANUP_MAX_KEYS_PER_BATCH); + + CleanupStaleEntityChannelRefs(deferredChannelKeys); + ++uiDeferredCleaned; + } + + // Reset presence sets after full drain; stale entries would cause unnecessary queue scans in Remove*. + if (m_StaleEntityChannelCleanupQueue.empty() && m_StaleEntityDeferredRetryKeys.empty()) + { + m_DeferredQueueEntityPresence.clear(); + m_DeferredQueueShaderPresence.clear(); + } + + // Prune invalidated (bValid=false) cache entries from active entities. + // By the time this runs (300ms+ after invalidation), entries still bValid=false + // are likely for entity+texture combos no longer being rendered. + // Run every 4th scan cycle; invalid entries are lazily rebuilt on render access. + if (bRunScan && (m_uiStaleEntityScanCycleCount & 0x3) == 0) + { + constexpr std::size_t ACTIVE_CLEANUP_MAX_REMOVALS_PER_ENTITY = 32; + constexpr std::size_t ACTIVE_CLEANUP_MAX_TOTAL_REMOVALS = 256; + std::size_t uiTotalActiveRemovals = 0; + for (std::size_t i = 0; i < uiActiveCount; ++i) + { + // Apply the same time cap used by scan work. + if ((i & 0x3) == 0 && i > 0) + { + const long long llElapsedUs = std::chrono::duration_cast(std::chrono::steady_clock::now() - startTime).count(); + if (llElapsedUs > cleanupBudget.llTimeBudgetUs) + break; + } + + CClientEntityBase* pClientEntity = activeCacheCleanupList[i]; + std::unordered_map>::iterator iterTexNames = m_EntityToTexNameInfos.find(pClientEntity); + if (iterTexNames == m_EntityToTexNameInfos.end()) + continue; + + CFastHashSet& texNameInfoSet = iterTexNames->second; + std::array toRemove{}; + std::size_t uiRemoveCount = 0; + + for (STexNameInfo* pTexNameInfo : texNameInfoSet) + { + if (uiTotalActiveRemovals + uiRemoveCount >= ACTIVE_CLEANUP_MAX_TOTAL_REMOVALS) + break; + + if (uiRemoveCount >= ACTIVE_CLEANUP_MAX_REMOVALS_PER_ENTITY) + break; + + if (!pTexNameInfo) + { + toRemove[uiRemoveCount++] = pTexNameInfo; + continue; + } + + STexShaderReplacement* pReplacement = MapFind(pTexNameInfo->texEntityShaderMap, pClientEntity); + if (pReplacement && !pReplacement->bValid) + { + MapRemove(pTexNameInfo->texEntityShaderMap, pClientEntity); + toRemove[uiRemoveCount++] = pTexNameInfo; + } + } + + for (std::size_t j = 0; j < uiRemoveCount; ++j) + MapRemove(texNameInfoSet, toRemove[j]); + + uiTotalActiveRemovals += uiRemoveCount; + + if (texNameInfoSet.empty()) + m_EntityToTexNameInfos.erase(iterTexNames); + + if (uiTotalActiveRemovals >= ACTIVE_CLEANUP_MAX_TOTAL_REMOVALS) + break; + } + } +} + +void CMatchChannelManager::CleanupStaleEntityChannelRefs(const std::vector& deferredChannelKeys) +{ + if (deferredChannelKeys.empty()) + return; + + CFastHashSet affectedChannels; + + for (const SDeferredChannelKey& deferredChannelKey : deferredChannelKeys) + { + const CShaderAndEntityPair& key = deferredChannelKey.key; + + if (key.pClientEntity && MapContains(m_KnownClientEntities, key.pClientEntity)) + { + std::unordered_map>::iterator itEnt = m_EntityToChannelKeys.find(key.pClientEntity); + if (itEnt != m_EntityToChannelKeys.end()) + { + bool bKeyStillIndexed = false; + for (const CShaderAndEntityPair& indexedKey : itEnt->second) + { + if (indexedKey.pShaderInfo == key.pShaderInfo && indexedKey.pClientEntity == key.pClientEntity && + indexedKey.bAppendLayers == key.bAppendLayers) + { + bKeyStillIndexed = true; + break; + } + } + + if (bKeyStillIndexed) + continue; + } + } + + std::map::iterator itUsage = m_ChannelUsageMap.find(key); + if (itUsage == m_ChannelUsageMap.end()) + continue; + + CMatchChannel* pChannel = itUsage->second; + if (!pChannel) + continue; + + if (pChannel != deferredChannelKey.pExpectedChannel) + continue; + + if (pChannel->m_uiId != deferredChannelKey.uiExpectedChannelId) + continue; + + pChannel->RemoveShaderAndEntity(key); + MapInsert(affectedChannels, pChannel); + + std::unordered_map>::iterator itShdr = m_ShaderToChannelKeys.find(key.pShaderInfo); + if (itShdr != m_ShaderToChannelKeys.end()) + { + std::vector& vec = itShdr->second; + for (std::size_t i = 0; i < vec.size(); ++i) + { + if (vec[i].pShaderInfo == key.pShaderInfo && vec[i].pClientEntity == key.pClientEntity && vec[i].bAppendLayers == key.bAppendLayers) + { + vec[i] = vec.back(); + vec.pop_back(); + break; + } + } + if (vec.empty()) + m_ShaderToChannelKeys.erase(itShdr); + } + + m_ChannelUsageMap.erase(itUsage); + } + + for (CMatchChannel* pChannel : affectedChannels) + { + if (!pChannel) + continue; + + for (STexNameInfo* pTexNameInfo : pChannel->m_MatchedTextureList) + { + if (pTexNameInfo) + pTexNameInfo->ResetReplacementResults(); + } + + if (pChannel->GetShaderAndEntityCount() == 0) + DeleteChannel(pChannel); + } +} + +bool CMatchChannelManager::TryPushDeferredKey(const CShaderAndEntityPair& key, CMatchChannel* pExpectedChannel) +{ + if (m_StaleEntityChannelCleanupQueue.empty() || m_StaleEntityChannelCleanupQueue.back().size() >= NUM_STALE_ENTITY_CLEANUP_MAX_KEYS_PER_BATCH) + { + if (m_StaleEntityChannelCleanupQueue.size() >= NUM_STALE_ENTITY_CLEANUP_MAX_QUEUE) + return false; + + m_StaleEntityChannelCleanupQueue.emplace_back(); + m_StaleEntityChannelCleanupQueue.back().reserve(NUM_STALE_ENTITY_CLEANUP_MAX_KEYS_PER_BATCH); + } + + if (key.pClientEntity) + m_DeferredQueueEntityPresence.insert(key.pClientEntity); + m_DeferredQueueShaderPresence.insert(key.pShaderInfo); + m_StaleEntityChannelCleanupQueue.back().emplace_back(key, pExpectedChannel); + return true; +} + ////////////////////////////////////////////////////////////////// // // CMatchChannelManager::RemoveClientEntityRefs @@ -343,36 +860,99 @@ void CMatchChannelManager::CalcShaderForTexAndEntity(SShaderInfoLayers& outShade ////////////////////////////////////////////////////////////////// void CMatchChannelManager::RemoveClientEntityRefs(CClientEntityBase* pClientEntity) { - assert(pClientEntity); + if (!pClientEntity) + return; // Ignore unknown client entities if (!MapContains(m_KnownClientEntities, pClientEntity)) return; + MapRemove(m_KnownClientEntities, pClientEntity); + m_StaleEntityDeferredRetryKeys.erase(pClientEntity); + + // Presence set is insert-only - absence guarantees no queue entries for this entity. + if (MapContains(m_DeferredQueueEntityPresence, pClientEntity)) + { + for (std::deque>::iterator itBatch = m_StaleEntityChannelCleanupQueue.begin(); + itBatch != m_StaleEntityChannelCleanupQueue.end();) + { + std::vector& batch = *itBatch; + for (std::size_t i = 0; i < batch.size();) + { + if (batch[i].key.pClientEntity == pClientEntity) + { + batch[i] = std::move(batch.back()); + batch.pop_back(); + } + else + { + ++i; + } + } + + if (batch.empty()) { + itBatch = m_StaleEntityChannelCleanupQueue.erase(itBatch); + } else { + ++itBatch; +} + } + m_DeferredQueueEntityPresence.erase(pClientEntity); + } + OutputDebug(SString("RemoveClientEntityRefs - Entity:%s", GetDebugTag(pClientEntity))); CFastHashSet affectedChannels; - for (std::map::iterator iter = m_ChannelUsageMap.begin(); iter != m_ChannelUsageMap.end();) + + // Use secondary index (entries-per-entity) instead of scanning all m_ChannelUsageMap entries + std::unordered_map>::iterator itEntity = m_EntityToChannelKeys.find(pClientEntity); + if (itEntity != m_EntityToChannelKeys.end()) { - if (pClientEntity == iter->first.pClientEntity) + for (const CShaderAndEntityPair& key : itEntity->second) { - CMatchChannel* pChannel = iter->second; - pChannel->RemoveShaderAndEntity(iter->first); - m_ChannelUsageMap.erase(iter++); - - MapInsert(affectedChannels, pChannel); + std::map::iterator itUsage = m_ChannelUsageMap.find(key); + if (itUsage != m_ChannelUsageMap.end()) + { + CMatchChannel* pChannel = itUsage->second; + if (pChannel) + { + pChannel->RemoveShaderAndEntity(key); + MapInsert(affectedChannels, pChannel); + } + // Maintain shader secondary index + std::unordered_map>::iterator itShdr = m_ShaderToChannelKeys.find(key.pShaderInfo); + if (itShdr != m_ShaderToChannelKeys.end()) + { + std::vector& vec = itShdr->second; + for (std::size_t i = 0; i < vec.size(); ++i) + { + if (vec[i].pShaderInfo == key.pShaderInfo && vec[i].pClientEntity == key.pClientEntity && vec[i].bAppendLayers == key.bAppendLayers) + { + vec[i] = vec.back(); + vec.pop_back(); + break; + } + } + if (vec.empty()) + m_ShaderToChannelKeys.erase(itShdr); + } + m_ChannelUsageMap.erase(itUsage); + } } - else - ++iter; + m_EntityToChannelKeys.erase(itEntity); } // Flag affected textures to re-calc shader results - for (CFastHashSet::iterator iter = affectedChannels.begin(); iter != affectedChannels.end(); ++iter) + for (CMatchChannel* pChannel : affectedChannels) { - CMatchChannel* pChannel = *iter; - for (CFastHashSet::iterator iter = pChannel->m_MatchedTextureList.begin(); iter != pChannel->m_MatchedTextureList.end(); ++iter) - (*iter)->ResetReplacementResults(); + if (!pChannel) + continue; + + for (STexNameInfo* pTexNameInfo : pChannel->m_MatchedTextureList) + { + if (pTexNameInfo) + pTexNameInfo->ResetReplacementResults(); + } // Also delete channel if is not refed anymore if (pChannel->GetShaderAndEntityCount() == 0) @@ -380,13 +960,18 @@ void CMatchChannelManager::RemoveClientEntityRefs(CClientEntityBase* pClientEnti // This could be optimized } - // Need to remove client entity entries that were used even though they had no matches - for (CFastHashMap::const_iterator iter = m_AllTextureList.begin(); iter != m_AllTextureList.end(); ++iter) + // Remove cached entity shader entries using reverse index instead of scanning all textures + std::unordered_map>::iterator itTexNames = m_EntityToTexNameInfos.find(pClientEntity); + if (itTexNames != m_EntityToTexNameInfos.end()) { - MapRemove(iter->second->texEntityShaderMap, pClientEntity); + for (STexNameInfo* pTexNameInfo : itTexNames->second) + { + MapRemove(pTexNameInfo->texEntityShaderMap, pClientEntity); + } + m_EntityToTexNameInfos.erase(itTexNames); } -#ifdef SHADER_DEBUG_CHECKS +#ifdef _CHECKS for (CFastHashSet::const_iterator iter = m_CreatedChannelList.begin(); iter != m_CreatedChannelList.end(); ++iter) { CMatchChannel* pChannel = *iter; @@ -414,27 +999,115 @@ void CMatchChannelManager::RemoveShaderRefs(CSHADERDUMMY* pShaderData) OutputDebug(SString("RemoveShaderRefs - Shader:%s", GetDebugTag(pShaderInfo))); - CFastHashSet affectedChannels; - for (std::map::iterator iter = m_ChannelUsageMap.begin(); iter != m_ChannelUsageMap.end();) + // Drop deferred and retry keys for this shader before removing live refs. + // Presence set is insert-only - absence guarantees no deferred entries for this shader. + if (MapContains(m_DeferredQueueShaderPresence, pShaderInfo)) { - if (pShaderInfo == iter->first.pShaderInfo) + for (std::unordered_map>::iterator itRetry = m_StaleEntityDeferredRetryKeys.begin(); + itRetry != m_StaleEntityDeferredRetryKeys.end();) { - CMatchChannel* pChannel = iter->second; - pChannel->RemoveShaderAndEntity(iter->first); - m_ChannelUsageMap.erase(iter++); + std::vector& retryKeys = itRetry->second; + for (std::size_t i = 0; i < retryKeys.size();) + { + if (retryKeys[i].pShaderInfo == pShaderInfo) + { + retryKeys[i] = std::move(retryKeys.back()); + retryKeys.pop_back(); + } + else + { + ++i; + } + } - MapInsert(affectedChannels, pChannel); + if (retryKeys.empty()) + itRetry = m_StaleEntityDeferredRetryKeys.erase(itRetry); + else + ++itRetry; } - else - ++iter; + + for (std::deque>::iterator itBatch = m_StaleEntityChannelCleanupQueue.begin(); + itBatch != m_StaleEntityChannelCleanupQueue.end();) + { + std::vector& batch = *itBatch; + for (std::size_t i = 0; i < batch.size();) + { + if (batch[i].key.pShaderInfo == pShaderInfo) + { + batch[i] = std::move(batch.back()); + batch.pop_back(); + } + else + { + ++i; + } + } + + if (batch.empty()) { + itBatch = m_StaleEntityChannelCleanupQueue.erase(itBatch); + } else { + ++itBatch; +} + } + + m_DeferredQueueShaderPresence.erase(pShaderInfo); + } + + CFastHashSet affectedChannels; + + // Use shader secondary index for lookup instead of full m_ChannelUsageMap scan + std::unordered_map>::iterator itShader = m_ShaderToChannelKeys.find(pShaderInfo); + if (itShader != m_ShaderToChannelKeys.end()) + { + for (const CShaderAndEntityPair& key : itShader->second) + { + std::map::iterator itUsage = m_ChannelUsageMap.find(key); + if (itUsage != m_ChannelUsageMap.end()) + { + CMatchChannel* pChannel = itUsage->second; + if (pChannel) + { + pChannel->RemoveShaderAndEntity(key); + MapInsert(affectedChannels, pChannel); + } + // Maintain entity secondary index + if (key.pClientEntity) + { + std::unordered_map>::iterator itEnt = m_EntityToChannelKeys.find(key.pClientEntity); + if (itEnt != m_EntityToChannelKeys.end()) + { + std::vector& vec = itEnt->second; + for (std::size_t i = 0; i < vec.size(); ++i) + { + if (vec[i].pShaderInfo == key.pShaderInfo && vec[i].pClientEntity == key.pClientEntity && vec[i].bAppendLayers == key.bAppendLayers) + { + vec[i] = vec.back(); + vec.pop_back(); + break; + } + } + if (vec.empty()) + m_EntityToChannelKeys.erase(itEnt); + } + } + m_ChannelUsageMap.erase(itUsage); + } + } + m_ShaderToChannelKeys.erase(itShader); } // Flag affected textures to re-calc shader matches for (CFastHashSet::iterator iter = affectedChannels.begin(); iter != affectedChannels.end(); ++iter) { CMatchChannel* pChannel = *iter; + if (!pChannel) + continue; + for (CFastHashSet::iterator iter = pChannel->m_MatchedTextureList.begin(); iter != pChannel->m_MatchedTextureList.end(); ++iter) - (*iter)->ResetReplacementResults(); + { + if (*iter) + (*iter)->ResetReplacementResults(); + } // Also delete channel if is not refed anymore if (pChannel->GetShaderAndEntityCount() == 0) @@ -442,7 +1115,7 @@ void CMatchChannelManager::RemoveShaderRefs(CSHADERDUMMY* pShaderData) // This could be optimized } -#ifdef SHADER_DEBUG_CHECKS +#ifdef _CHECKS // Check has been remove from textures for (CFastHashMap::const_iterator iter = m_AllTextureList.begin(); iter != m_AllTextureList.end(); ++iter) { @@ -569,17 +1242,16 @@ void CMatchChannelManager::RecalcEverything() } } - // Remove ClientEntitys with no matches - CFastHashSet removeList = m_KnownClientEntities; - for (std::map::iterator iter = m_ChannelUsageMap.begin(); iter != m_ChannelUsageMap.end(); ++iter) + // Remove ClientEntitys with no matches - use entity secondary index instead of scanning m_ChannelUsageMap + CFastHashSet removeList; + for (CClientEntityBase* pEntity : m_KnownClientEntities) { - if (iter->first.pClientEntity) - MapRemove(removeList, iter->first.pClientEntity); + if (m_EntityToChannelKeys.find(pEntity) == m_EntityToChannelKeys.end()) + MapInsert(removeList, pEntity); } for (CFastHashSet::iterator iter = removeList.begin(); iter != removeList.end(); ++iter) { - // This call could be optimized as the entity won't be present in some maps RemoveClientEntityRefs(*iter); } } @@ -599,27 +1271,25 @@ void CMatchChannelManager::ProcessRematchTexturesQueue() m_RematchQueue.clear(); // For each queued channel - for (CFastHashSet::iterator iter = rematchQueue.begin(); iter != rematchQueue.end(); ++iter) + for (CMatchChannel* pChannel : rematchQueue) { - CMatchChannel* pChannel = *iter; pChannel->m_bResetReplacements = true; OutputDebug(SString(" [ProcessRematchTexturesQueue] - Channel:%s", GetDebugTag(pChannel))); // Remove existing matches CFastHashSet matchedTextureList = pChannel->m_MatchedTextureList; - for (CFastHashSet::iterator iter = matchedTextureList.begin(); iter != matchedTextureList.end(); ++iter) + for (STexNameInfo* pTexNameInfo : matchedTextureList) { - STexNameInfo* pTexNameInfo = *iter; pChannel->RemoveTexture(pTexNameInfo); MapRemove(pTexNameInfo->matchChannelList, pChannel); - pTexNameInfo->ResetReplacementResults(); // Do this here as it won't get picked up in RecalcEverything now + pTexNameInfo->ResetReplacementResults(); } // Rematch against texture list - for (CFastHashMap::iterator iter = m_AllTextureList.begin(); iter != m_AllTextureList.end(); ++iter) + for (CFastHashMap::value_type& pair : m_AllTextureList) { - STexNameInfo* pTexNameInfo = iter->second; + STexNameInfo* pTexNameInfo = pair.second; if (pChannel->m_MatchChain.IsAdditiveMatch(pTexNameInfo->strTextureName)) { pChannel->AddTexture(pTexNameInfo); @@ -677,6 +1347,10 @@ void CMatchChannelManager::MergeChannelTo(CMatchChannel* pSource, CMatchChannel* { const CShaderAndEntityPair& key = *iter; RemoveUsage(key, pSource); + + if (key.pClientEntity && !MapContains(m_KnownClientEntities, key.pClientEntity)) + continue; + AddUsage(key, pTarget); } } @@ -747,9 +1421,58 @@ CMatchChannel* CMatchChannelManager::GetChannelOnlyUsedBy(SShaderInfo* pShaderIn void CMatchChannelManager::AddUsage(const CShaderAndEntityPair& key, CMatchChannel* pChannel) { OutputDebug(SString(" AddUsage - Channel:%s key:%s", GetDebugTag(pChannel), GetDebugTag(key))); - dassert(!MapContains(m_ChannelUsageMap, key)); + + CMatchChannel* pExistingChannel = MapFindRef(m_ChannelUsageMap, key); + if (pExistingChannel) + { + if (pExistingChannel == pChannel) + { + if (key.pClientEntity) + { + std::vector& vecEntityKeys = m_EntityToChannelKeys[key.pClientEntity]; + bool bHasEntityKey = false; + for (const CShaderAndEntityPair& existingKey : vecEntityKeys) + { + if (existingKey.pShaderInfo == key.pShaderInfo && existingKey.pClientEntity == key.pClientEntity && + existingKey.bAppendLayers == key.bAppendLayers) + { + bHasEntityKey = true; + break; + } + } + if (!bHasEntityKey) + vecEntityKeys.push_back(key); + } + + std::vector& vecShaderKeys = m_ShaderToChannelKeys[key.pShaderInfo]; + bool bHasShaderKey = false; + for (const CShaderAndEntityPair& existingKey : vecShaderKeys) + { + if (existingKey.pShaderInfo == key.pShaderInfo && existingKey.pClientEntity == key.pClientEntity && + existingKey.bAppendLayers == key.bAppendLayers) + { + bHasShaderKey = true; + break; + } + } + if (!bHasShaderKey) + vecShaderKeys.push_back(key); + + return; + } + + // Deferred cleanup can leave stale key ownership briefly. + // Reconcile here so each key stays bound to one channel. + RemoveUsage(key, pExistingChannel); + if (pExistingChannel->GetShaderAndEntityCount() == 0) + DeleteChannel(pExistingChannel); + } + pChannel->AddShaderAndEntity(key); MapSet(m_ChannelUsageMap, key, pChannel); + if (key.pClientEntity) + m_EntityToChannelKeys[key.pClientEntity].push_back(key); + m_ShaderToChannelKeys[key.pShaderInfo].push_back(key); pChannel->m_bResetReplacements = true; } @@ -766,6 +1489,43 @@ void CMatchChannelManager::RemoveUsage(const CShaderAndEntityPair& key, CMatchCh dassert(MapContains(m_ChannelUsageMap, key)); pChannel->RemoveShaderAndEntity(key); MapRemove(m_ChannelUsageMap, key); + if (key.pClientEntity) + { + std::unordered_map>::iterator it = m_EntityToChannelKeys.find(key.pClientEntity); + if (it != m_EntityToChannelKeys.end()) + { + std::vector& vec = it->second; + for (std::size_t i = 0; i < vec.size(); ++i) + { + if (vec[i].pShaderInfo == key.pShaderInfo && vec[i].pClientEntity == key.pClientEntity && vec[i].bAppendLayers == key.bAppendLayers) + { + vec[i] = vec.back(); + vec.pop_back(); + break; + } + } + if (vec.empty()) + m_EntityToChannelKeys.erase(it); + } + } + { + std::unordered_map>::iterator it = m_ShaderToChannelKeys.find(key.pShaderInfo); + if (it != m_ShaderToChannelKeys.end()) + { + std::vector& vec = it->second; + for (std::size_t i = 0; i < vec.size(); ++i) + { + if (vec[i].pShaderInfo == key.pShaderInfo && vec[i].pClientEntity == key.pClientEntity && vec[i].bAppendLayers == key.bAppendLayers) + { + vec[i] = vec.back(); + vec.pop_back(); + break; + } + } + if (vec.empty()) + m_ShaderToChannelKeys.erase(it); + } + } pChannel->m_bResetReplacements = true; } @@ -779,7 +1539,11 @@ void CMatchChannelManager::RemoveUsage(const CShaderAndEntityPair& key, CMatchCh CMatchChannel* CMatchChannelManager::GetChannel(const CShaderAndEntityPair& key) { CMatchChannel* pChannel = MapFindRef(m_ChannelUsageMap, key); - if (!pChannel) + if (pChannel) + { + AddUsage(key, pChannel); + } + else { pChannel = NewChannel(); AddUsage(key, pChannel); @@ -896,10 +1660,11 @@ void CMatchChannelManager::GetShaderReplacementStats(SShaderReplacementStats& ou const SMatchType& matchType = matchTypeList[i]; if (i) strResult += " "; - if (matchTypeList[i].bAdditive) + if (matchTypeList[i].bAdditive) { strResult += "+"; - else + } else { strResult += "-"; +} strResult += matchTypeList[i].strMatch; if (strResult.length() > 25) diff --git a/Client/game_sa/CRenderWareSA.ShaderMatching.h b/Client/game_sa/CRenderWareSA.ShaderMatching.h index 025cc118c47..f9b18467843 100644 --- a/Client/game_sa/CRenderWareSA.ShaderMatching.h +++ b/Client/game_sa/CRenderWareSA.ShaderMatching.h @@ -8,6 +8,8 @@ #pragma once +#include +#include #include "CRenderWareSA.ShaderSupport.h" #ifdef SHADER_DEBUG_OUTPUT @@ -24,7 +26,9 @@ SString GetDebugTagStr(CClientEntityBase* pClientEntity); SString GetDebugTagStr(SShaderInfo* pShaderInfo); SString GetDebugTagStr(CMatchChannel* pChannel); #else - #define OutputDebug(x) {} + #define OutputDebug(x) \ + { \ + } #endif // @@ -32,9 +36,17 @@ SString GetDebugTagStr(CMatchChannel* pChannel); // struct SMatchType { - SMatchType(const SString& strMatch, bool bAdditive) : strMatch(strMatch), bAdditive(bAdditive) {} + SMatchType(const SString& strMatch, bool bAdditive) + : strMatch(strMatch), + bAdditive(bAdditive), + bIsMatchAll(strMatch.length() == 1 && strMatch[0] == '*'), + bHasWildcards(strMatch.find_first_of("*?") != SString::npos) + { + } SString strMatch; bool bAdditive; + bool bIsMatchAll; + bool bHasWildcards; }; // @@ -49,8 +61,20 @@ struct SWildcardMatchChain { bool bIsMatch = false; for (std::vector::const_iterator iter = matchTypeList.begin(); iter != matchTypeList.end(); ++iter) - if (WildcardMatch(iter->strMatch, strTextureName)) + { + bool bMatches; + + // Fast paths for common patterns (equivalent to WildcardMatch but avoids per-char loop) + if (iter->bIsMatchAll) + bMatches = true; + else if (!iter->bHasWildcards) + bMatches = (iter->strMatch == strTextureName); + else + bMatches = WildcardMatch(iter->strMatch, strTextureName); + + if (bMatches) bIsMatch = iter->bAdditive; + } return bIsMatch; } @@ -94,7 +118,7 @@ struct SWildcardMatchChain return true; } - std::vector matchTypeList; // List of additive and subtractive wildcard match strings + std::vector matchTypeList; // List of additive and subtractive wildcard match strings }; //////////////////////////////////////////////////////////////// @@ -114,10 +138,19 @@ class CShaderAndEntityPair bool operator<(const CShaderAndEntityPair& other) const { - return pShaderInfo < other.pShaderInfo || (pShaderInfo == other.pShaderInfo && pClientEntity < other.pClientEntity); + if (pShaderInfo != other.pShaderInfo) + return pShaderInfo < other.pShaderInfo; + + if (pClientEntity != other.pClientEntity) + return pClientEntity < other.pClientEntity; + + return bAppendLayers < other.bAppendLayers; } - bool operator==(const CShaderAndEntityPair& other) const { return pShaderInfo == other.pShaderInfo && pClientEntity == other.pClientEntity; } + bool operator==(const CShaderAndEntityPair& other) const + { + return pShaderInfo == other.pShaderInfo && pClientEntity == other.pClientEntity && bAppendLayers == other.bAppendLayers; + } SShaderInfo* pShaderInfo; CClientEntityBase* pClientEntity; @@ -136,6 +169,12 @@ class CMatchChannel public: CMatchChannel() { + if (ms_uiIdCounter == 0) + { + dassert(0); + ms_uiIdCounter = 1; + } + m_bResetReplacements = false; m_uiId = ms_uiIdCounter++; } @@ -160,19 +199,19 @@ class CMatchChannel ////////////////////////////////////////////// void AddShaderAndEntity(const CShaderAndEntityPair& key) { - #ifdef SHADER_DEBUG_OUTPUT +#ifdef SHADER_DEBUG_OUTPUT if (!MapContains(m_ShaderAndEntityList, key)) OutputDebug(SString(" +Channel:%s adds (ShaderEntity:%s)", GetDebugTag(this), GetDebugTag(key))); - #endif +#endif MapInsert(m_ShaderAndEntityList, key); } void RemoveShaderAndEntity(const CShaderAndEntityPair& key) { - #ifdef SHADER_DEBUG_OUTPUT +#ifdef SHADER_DEBUG_OUTPUT if (MapContains(m_ShaderAndEntityList, key)) OutputDebug(SString(" -Channel:%s removes (ShaderEntity:%s)", GetDebugTag(this), GetDebugTag(key))); - #endif +#endif MapRemove(m_ShaderAndEntityList, key); } @@ -211,19 +250,19 @@ class CMatchChannel ////////////////////////////////////////////// void AddTexture(STexNameInfo* pTexNameInfo) { - #ifdef SHADER_DEBUG_OUTPUT +#ifdef SHADER_DEBUG_OUTPUT if (!MapContains(m_MatchedTextureList, pTexNameInfo)) OutputDebug(SString(" +Channel:%s adds Tex:%s", GetDebugTag(this), GetDebugTag(pTexNameInfo))); - #endif +#endif MapInsert(m_MatchedTextureList, pTexNameInfo); } void RemoveTexture(STexNameInfo* pTexNameInfo) { - #ifdef SHADER_DEBUG_OUTPUT +#ifdef SHADER_DEBUG_OUTPUT if (MapContains(m_MatchedTextureList, pTexNameInfo)) OutputDebug(SString(" -Channel:%s removes Tex:%s", GetDebugTag(this), GetDebugTag(pTexNameInfo))); - #endif +#endif MapRemove(m_MatchedTextureList, pTexNameInfo); } @@ -232,19 +271,19 @@ class CMatchChannel ////////////////////////////////////////////// void SetMatchChain(const SWildcardMatchChain& matchChain) { - #ifdef SHADER_DEBUG_OUTPUT +#ifdef SHADER_DEBUG_OUTPUT if (!(m_MatchChain == matchChain)) OutputDebug(SString(" Channel:%s SetMatchChain:%s", GetDebugTag(this), GetDebugTag(matchChain))); - #endif +#endif m_MatchChain = matchChain; } const SWildcardMatchChain& GetMatchChain() const { return m_MatchChain; } - SWildcardMatchChain m_MatchChain; // String matches this channel represents - CFastHashSet m_MatchedTextureList; // All textures whose name matches the match chain + SWildcardMatchChain m_MatchChain; // String matches this channel represents + CFastHashSet m_MatchedTextureList; // All textures whose name matches the match chain std::set m_ShaderAndEntityList; - bool m_bResetReplacements; // Flag to indicate texture replacements should be reset + bool m_bResetReplacements; // Flag to indicate texture replacements should be reset uint m_uiId; static uint ms_uiIdCounter; }; @@ -263,13 +302,28 @@ class CMatchChannelManager void InsertTexture(STexInfo* pTexInfo); void RemoveTexture(STexInfo* pTexInfo); SShaderInfoLayers* GetShaderForTexAndEntity(STexInfo* pTexInfo, CClientEntityBase* pClientEntity, int iEntityType); + void PulseStaleEntityCacheCleanup(); void RemoveClientEntityRefs(CClientEntityBase* pClientEntity); void RemoveShaderRefs(CSHADERDUMMY* pShaderData); void GetShaderReplacementStats(SShaderReplacementStats& outStats); protected: + struct SDeferredChannelKey + { + SDeferredChannelKey(const CShaderAndEntityPair& key, CMatchChannel* pExpectedChannel) + : key(key), pExpectedChannel(pExpectedChannel), uiExpectedChannelId(pExpectedChannel ? pExpectedChannel->m_uiId : 0) + { + } + + CShaderAndEntityPair key; + CMatchChannel* pExpectedChannel; // Pointer identity check only. Never deref. + uint uiExpectedChannelId; + }; + void CalcShaderForTexAndEntity(SShaderInfoLayers& outShaderLayers, STexNameInfo* pTexNameInfo, CClientEntityBase* pClientEntity, int iEntityType, bool bSilent); + void CleanupStaleEntityChannelRefs(const std::vector& deferredChannelKeys); + bool TryPushDeferredKey(const CShaderAndEntityPair& key, CMatchChannel* pExpectedChannel); void AddToOptimizeQueue(CMatchChannel* pChannel); void AddToRematchQueue(CMatchChannel* pChannel); void FlushChanges(); @@ -294,10 +348,26 @@ class CMatchChannelManager bool m_bChangesPending; std::map m_ChannelUsageMap; - CFastHashSet m_CreatedChannelList; - CFastHashSet m_OptimizeQueue; - CFastHashSet m_RematchQueue; - CFastHashMap m_AllTextureList; - CFastHashMap m_ShaderInfoMap; - CFastHashSet m_KnownClientEntities; + // Secondary index: entity > keys in m_ChannelUsageMap, for fast RemoveClientEntityRefs + std::unordered_map> m_EntityToChannelKeys; + // Secondary index: shader > keys in m_ChannelUsageMap, for fast RemoveShaderRefs + std::unordered_map> m_ShaderToChannelKeys; + // Secondary index: entity > STexNameInfo entries in texEntityShaderMap, for fast cleanup + std::unordered_map> m_EntityToTexNameInfos; + // Retry keys that didnt fit in the deferred queue. + std::unordered_map> m_StaleEntityDeferredRetryKeys; + // Which entities/shaders have any key currently in the deferred queue or retry map. + // Insert-only on push; bulk-cleared on full drain. Absent entry means no keys exist - Remove* skips the scan. + std::unordered_set m_DeferredQueueEntityPresence; + std::unordered_set m_DeferredQueueShaderPresence; + CFastHashSet m_CreatedChannelList; + CFastHashSet m_OptimizeQueue; + CFastHashSet m_RematchQueue; + CFastHashMap m_AllTextureList; + CFastHashMap m_ShaderInfoMap; + CFastHashSet m_KnownClientEntities; + std::deque> m_StaleEntityChannelCleanupQueue; + long long m_llNextStaleEntityCleanupTime = 0; + std::size_t m_uiStaleEntityCleanupCursorBucket = 0; + std::size_t m_uiStaleEntityScanCycleCount = 0; }; diff --git a/Client/game_sa/CRenderWareSA.ShaderSupport.cpp b/Client/game_sa/CRenderWareSA.ShaderSupport.cpp index b991550b4cc..1b5ac99ebac 100644 --- a/Client/game_sa/CRenderWareSA.ShaderSupport.cpp +++ b/Client/game_sa/CRenderWareSA.ShaderSupport.cpp @@ -19,13 +19,13 @@ extern CCoreInterface* g_pCore; extern CGameSA* pGame; -#define ADDR_CCustomCarPlateMgr_CreatePlateTexture_TextureSetName 0x06FDF40 -#define ADDR_CCustomRoadsignMgr_CreateRoadsignTexture_TextureSetName 0x06FED49 -#define ADDR_CClothesBuilder_ConstructTextures_Start 0x05A6040 -#define ADDR_CClothesBuilder_ConstructTextures_End 0x05A6520 -#define ADDR_CVehicle_DoHeadLightBeam_RenderPrimitive 0x06E13CD -#define ADDR_CHeli_SearchLightCone_RenderPrimitive 0x06C62AD -#define ADDR_CWaterCannon_Render_RenderPrimitive 0x072956B +#define ADDR_CCustomCarPlateMgr_CreatePlateTexture_TextureSetName 0x06FDF40 +#define ADDR_CCustomRoadsignMgr_CreateRoadsignTexture_TextureSetName 0x06FED49 +#define ADDR_CClothesBuilder_ConstructTextures_Start 0x05A6040 +#define ADDR_CClothesBuilder_ConstructTextures_End 0x05A6520 +#define ADDR_CVehicle_DoHeadLightBeam_RenderPrimitive 0x06E13CD +#define ADDR_CHeli_SearchLightCone_RenderPrimitive 0x06C62AD +#define ADDR_CWaterCannon_Render_RenderPrimitive 0x072956B enum { @@ -47,9 +47,9 @@ int CRenderWareSA::ms_iRenderingType = 0; //////////////////////////////////////////////////////////////// // Hooks for creating txd create and destroy events -#define HOOKPOS_CTxdStore_SetupTxdParent 0x731D55 +#define HOOKPOS_CTxdStore_SetupTxdParent 0x731D55 DWORD RETURN_CTxdStore_SetupTxdParent = 0x731D5B; -#define HOOKPOS_CTxdStore_RemoveTxd 0x731E90 +#define HOOKPOS_CTxdStore_RemoveTxd 0x731E90 DWORD RETURN_CTxdStore_RemoveTxd = 0x731E96; // @@ -57,51 +57,48 @@ DWORD RETURN_CTxdStore_RemoveTxd = 0x731E96; // struct STxdStreamEvent { + STxdStreamEvent() : bAdded(false), usTxdId(0) {} STxdStreamEvent(bool bAdded, ushort usTxdId) : bAdded(bAdded), usTxdId(usTxdId) {} - bool operator<(const STxdStreamEvent& other) const - { - return usTxdId < other.usTxdId || (usTxdId == other.usTxdId && bAdded == false && other.bAdded == true); - } - bool operator==(const STxdStreamEvent& other) const { return usTxdId == other.usTxdId && bAdded == other.bAdded; } - bool bAdded; ushort usTxdId; }; -static CMappedArray ms_txdStreamEventList; +// Keyed by usTxdId; only the last event per TXD per pulse is kept. +// This means an add followed by a remove in the same frame resolves to removed (and vice versa). +static std::unordered_map ms_txdStreamEventList; //////////////////////////////////////////////////////////////// // Txd created //////////////////////////////////////////////////////////////// __declspec(noinline) void _cdecl OnStreamingAddedTxd(DWORD dwTxdId) { - ushort usTxdId = (ushort)dwTxdId; - // Ensure there are no previous events for this txd - ms_txdStreamEventList.remove(STxdStreamEvent(false, usTxdId)); - ms_txdStreamEventList.remove(STxdStreamEvent(true, usTxdId)); - // Append 'added' - ms_txdStreamEventList.push_back(STxdStreamEvent(true, usTxdId)); + const ushort usTxdId = (ushort)dwTxdId; + ms_txdStreamEventList[usTxdId] = STxdStreamEvent(true, usTxdId); } // called from streaming on TXD create -void _declspec(naked) HOOK_CTxdStore_SetupTxdParent() +static void __declspec(naked) HOOK_CTxdStore_SetupTxdParent() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Hooked from 731D55 6 bytes // eax - txd id pushad - push eax - call OnStreamingAddedTxd - add esp, 4 + push eax + call OnStreamingAddedTxd + add esp, 4 popad // orig mov esi, ds:00C8800Ch jmp RETURN_CTxdStore_SetupTxdParent // 731D5B } + // clang-format on } //////////////////////////////////////////////////////////////// @@ -109,32 +106,32 @@ void _declspec(naked) HOOK_CTxdStore_SetupTxdParent() //////////////////////////////////////////////////////////////// __declspec(noinline) void _cdecl OnStreamingRemoveTxd(DWORD dwTxdId) { - ushort usTxdId = (ushort)dwTxdId - pGame->GetBaseIDforTXD(); - // Ensure there are no previous events for this txd - ms_txdStreamEventList.remove(STxdStreamEvent(true, usTxdId)); - ms_txdStreamEventList.remove(STxdStreamEvent(false, usTxdId)); - // Append 'removed' - ms_txdStreamEventList.push_back(STxdStreamEvent(false, usTxdId)); + const ushort usTxdId = (ushort)dwTxdId - pGame->GetBaseIDforTXD(); + ms_txdStreamEventList[usTxdId] = STxdStreamEvent(false, usTxdId); } // called from streaming on TXD destroy -void _declspec(naked) HOOK_CTxdStore_RemoveTxd() +static void __declspec(naked) HOOK_CTxdStore_RemoveTxd() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Hooked from 731E90 6 bytes // esi - txd id + 20000 pushad - push esi - call OnStreamingRemoveTxd - add esp, 4 + push esi + call OnStreamingRemoveTxd + add esp, 4 popad // orig mov ecx, ds:00C8800Ch jmp RETURN_CTxdStore_RemoveTxd // 731E96 } + // clang-format on } //////////////////////////////////////////////////////////////// @@ -164,6 +161,25 @@ void CRenderWareSA::InitTextureWatchHooks() // Process ms_txdStreamEventList // //////////////////////////////////////////////////////////////// + +// SEH-protected texture field access; returns false on access violation +static __declspec(noinline) bool TryReadTextureFields(RwTexture* texture, const char** ppName, CD3DDUMMY** ppD3DData) +{ + __try + { + *ppName = texture->name; + RwRaster* pRaster = texture->raster; + *ppD3DData = (pRaster != nullptr) ? static_cast(pRaster->renderResource) : nullptr; + return true; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + *ppName = nullptr; + *ppD3DData = nullptr; + return false; + } +} + void CRenderWareSA::PulseWorldTextureWatch() { UpdateModuleTickCount64(); @@ -172,9 +188,9 @@ void CRenderWareSA::PulseWorldTextureWatch() TIMING_CHECKPOINT("+TextureWatch"); // Go through ms_txdStreamEventList - for (std::vector::const_iterator iter = ms_txdStreamEventList.begin(); iter != ms_txdStreamEventList.end(); ++iter) + for (const auto& entry : ms_txdStreamEventList) { - const STxdStreamEvent& action = *iter; + const STxdStreamEvent& action = entry.second; if (action.bAdded) { // @@ -183,15 +199,22 @@ void CRenderWareSA::PulseWorldTextureWatch() // Get list of texture names and data to add - // Note: If txd has been unloaded since, textureList will be empty std::vector textureList; GetTxdTextures(textureList, action.usTxdId); for (std::vector::iterator iter = textureList.begin(); iter != textureList.end(); iter++) { - RwTexture* texture = *iter; - const char* szTextureName = texture->name; - CD3DDUMMY* pD3DData = texture->raster ? (CD3DDUMMY*)texture->raster->renderResource : NULL; + RwTexture* texture = *iter; + if (!texture) + continue; + + // Read texture fields with SEH protection instead of per-field IsReadablePointer syscalls. + // The TXD was just streamed in so its textures are normally valid; SEH catches rare corruption. + const char* szTextureName = nullptr; + CD3DDUMMY* pD3DData = nullptr; + if (!TryReadTextureFields(texture, &szTextureName, &pD3DData)) + continue; + if (!MapContains(m_SpecialTextures, texture)) StreamingAddedTexture(action.usTxdId, szTextureName, pD3DData); } @@ -207,6 +230,10 @@ void CRenderWareSA::PulseWorldTextureWatch() } ms_txdStreamEventList.clear(); + + m_pMatchChannelManager->PulseStaleEntityCacheCleanup(); + + ProcessPendingIsolatedModels(); TIMING_CHECKPOINT("-TextureWatch"); } @@ -215,11 +242,18 @@ void CRenderWareSA::PulseWorldTextureWatch() // CRenderWareSA::StreamingAddedTexture // // Called when a TXD is loaded. -// Create a texinfo for the texture +// Create a texinfo for the texture. +// Note: We register textures with their actual GTA internal name (e.g., "#emap"). +// The pattern matching in AppendAdditiveMatch/AppendSubtractiveMatch handles +// mapping external names in scripts (e.g. "remap*") to internal names. // //////////////////////////////////////////////////////////////// void CRenderWareSA::StreamingAddedTexture(ushort usTxdId, const SString& strTextureName, CD3DDUMMY* pD3DData) { + // Skip textures without valid D3D data or name - shader matching requires both + if (!pD3DData || strTextureName.empty()) + return; + STexInfo* pTexInfo = CreateTexInfo(usTxdId, strTextureName, pD3DData); OnTextureStreamIn(pTexInfo); } @@ -241,19 +275,68 @@ void CRenderWareSA::StreamingRemovedTxd(ushort usTxdId) for (ConstIterType iter = range.first; iter != range.second;) { STexInfo* pTexInfo = iter->second; - if (pTexInfo->texTag == usTxdId) + if (pTexInfo && pTexInfo->texTag == usTxdId) { OnTextureStreamOut(pTexInfo); + ConstIterType iterNext = iter; + ++iterNext; + m_TexInfoMap.erase(iter); DestroyTexInfo(pTexInfo); - m_TexInfoMap.erase(iter++); + iter = iterNext; } - else + else { ++iter; +} } TIMING_CHECKPOINT("-StreamingRemovedTxd"); } +//////////////////////////////////////////////////////////////// +// +// CRenderWareSA::RemoveStreamingTexture +// +// Remove a single texture that was added via StreamingAddedTexture. +// Finds the texture by matching TXD ID and D3D data pointer. +// +//////////////////////////////////////////////////////////////// +void CRenderWareSA::RemoveStreamingTexture(unsigned short usTxdId, CD3DDUMMY* pD3DData) +{ + if (!pD3DData) + return; + + typedef std::multimap::iterator IterType; + std::pair range = m_TexInfoMap.equal_range(usTxdId); + for (IterType iter = range.first; iter != range.second;) + { + STexInfo* pTexInfo = iter->second; + if (pTexInfo && pTexInfo->pD3DData == pD3DData) + { + OnTextureStreamOut(pTexInfo); + m_TexInfoMap.erase(iter); + DestroyTexInfo(pTexInfo); + return; // Only one entry per D3D data + } + else { + ++iter; +} + } +} + +//////////////////////////////////////////////////////////////// +// +// CRenderWareSA::IsTexInfoRegistered +// +// Check if a D3D data pointer is already registered in the shader system. +// +//////////////////////////////////////////////////////////////// +bool CRenderWareSA::IsTexInfoRegistered(CD3DDUMMY* pD3DData) const +{ + if (!pD3DData) + return false; + return MapContains(m_D3DDataTexInfoMap, pD3DData); +} + //////////////////////////////////////////////////////////////// // // CRenderWareSA::ScriptAddedTxd @@ -265,13 +348,28 @@ void CRenderWareSA::StreamingRemovedTxd(ushort usTxdId) void CRenderWareSA::ScriptAddedTxd(RwTexDictionary* pTxd) { TIMING_CHECKPOINT("+ScriptAddedTxd"); + + // Validate TXD pointer before iterating + if (!pTxd || !SharedUtil::IsReadablePointer(pTxd, sizeof(RwTexDictionary))) + { + TIMING_CHECKPOINT("-ScriptAddedTxd"); + return; + } + std::vector textureList; GetTxdTextures(textureList, pTxd); for (std::vector::iterator iter = textureList.begin(); iter != textureList.end(); iter++) { - RwTexture* texture = *iter; + RwTexture* texture = *iter; + if (!texture || !SharedUtil::IsReadablePointer(texture, sizeof(RwTexture))) + continue; + const char* szTextureName = texture->name; - CD3DDUMMY* pD3DData = texture->raster ? (CD3DDUMMY*)texture->raster->renderResource : NULL; + CD3DDUMMY* pD3DData = + (texture->raster && SharedUtil::IsReadablePointer(texture->raster, sizeof(RwRaster))) ? (CD3DDUMMY*)texture->raster->renderResource : NULL; + + if (!pD3DData || !szTextureName[0]) + continue; // Added texture STexInfo* pTexInfo = CreateTexInfo(texture, szTextureName, pD3DData); @@ -291,19 +389,30 @@ void CRenderWareSA::ScriptAddedTxd(RwTexDictionary* pTxd) void CRenderWareSA::ScriptRemovedTexture(RwTexture* pTex) { TIMING_CHECKPOINT("+ScriptRemovedTexture"); - // Find TexInfo for this script added texture - for (std::multimap::iterator iter = m_TexInfoMap.begin(); iter != m_TexInfoMap.end();) + + // Use reverse lookup instead of full m_TexInfoMap scan + auto it = m_ScriptTexInfoMap.find(pTex); + if (it != m_ScriptTexInfoMap.end()) { - STexInfo* pTexInfo = iter->second; - if (pTexInfo->texTag == pTex) + STexInfo* pTexInfo = it->second; + if (pTexInfo) { OnTextureStreamOut(pTexInfo); + // Erase from m_TexInfoMap by scanning the TXD ID bucket + typedef std::multimap::iterator IterType; + std::pair range = m_TexInfoMap.equal_range(pTexInfo->texTag.m_usTxdId); + for (IterType iter = range.first; iter != range.second; ++iter) + { + if (iter->second == pTexInfo) + { + m_TexInfoMap.erase(iter); + break; + } + } DestroyTexInfo(pTexInfo); - m_TexInfoMap.erase(iter++); } - else - ++iter; } + TIMING_CHECKPOINT("-ScriptRemovedTexture"); } @@ -316,12 +425,21 @@ void CRenderWareSA::ScriptRemovedTexture(RwTexture* pTex) //////////////////////////////////////////////////////////////// void CRenderWareSA::SpecialAddedTexture(RwTexture* texture, const char* szTextureName) { + if (!texture || !SharedUtil::IsReadablePointer(texture, sizeof(RwTexture))) + return; + if (!szTextureName) szTextureName = texture->name; + if (!szTextureName || !szTextureName[0]) + return; - OutputDebug(SString("Adding special texture %s", szTextureName)); + CD3DDUMMY* pD3DData = + (texture->raster && SharedUtil::IsReadablePointer(texture->raster, sizeof(RwRaster))) ? (CD3DDUMMY*)texture->raster->renderResource : NULL; - CD3DDUMMY* pD3DData = texture->raster ? (CD3DDUMMY*)texture->raster->renderResource : NULL; + if (!pD3DData) + return; + + OutputDebug(SString("Adding special texture %s", szTextureName)); // Added texture STexInfo* pTexInfo = CreateTexInfo(texture, szTextureName, pD3DData); @@ -346,19 +464,28 @@ void CRenderWareSA::SpecialRemovedTexture(RwTexture* pTex) MapRemove(m_SpecialTextures, pTex); - // Find TexInfo for this special texture - for (std::multimap::iterator iter = m_TexInfoMap.begin(); iter != m_TexInfoMap.end();) + // Use reverse lookup instead of full m_TexInfoMap scan + auto it = m_ScriptTexInfoMap.find(pTex); + if (it != m_ScriptTexInfoMap.end()) { - STexInfo* pTexInfo = iter->second; - if (pTexInfo->texTag == pTex) + STexInfo* pTexInfo = it->second; + if (pTexInfo) { OutputDebug(SString(" %s", *pTexInfo->strTextureName)); OnTextureStreamOut(pTexInfo); + // Erase from m_TexInfoMap by scanning the TXD ID bucket + typedef std::multimap::iterator IterType; + std::pair range = m_TexInfoMap.equal_range(pTexInfo->texTag.m_usTxdId); + for (IterType iter = range.first; iter != range.second; ++iter) + { + if (iter->second == pTexInfo) + { + m_TexInfoMap.erase(iter); + break; + } + } DestroyTexInfo(pTexInfo); - m_TexInfoMap.erase(iter++); } - else - ++iter; } } @@ -379,14 +506,70 @@ void CRenderWareSA::SpecialRemovedTexture(RwTexture* pTex) //////////////////////////////////////////////////////////////// STexInfo* CRenderWareSA::CreateTexInfo(const STexTag& texTag, const SString& strTextureName, CD3DDUMMY* pD3DData) { + const SString strTextureNameLower = strTextureName.ToLower(); + + // If this is a script/special texture, clean up any existing entry for the same RwTexture* + // to prevent orphaned STexInfo leaks (the old entry would be unreachable via m_ScriptTexInfoMap) + if (!texTag.m_bUsingTxdId && texTag.m_pTex && texTag.m_pTex != FAKE_RWTEXTURE_NO_TEXTURE) + { + auto itExisting = m_ScriptTexInfoMap.find(texTag.m_pTex); + if (itExisting != m_ScriptTexInfoMap.end()) + { + STexInfo* pOldTexInfo = itExisting->second; + if (pOldTexInfo) + { + const bool bSameTagType = (pOldTexInfo->texTag.m_bUsingTxdId == texTag.m_bUsingTxdId); + bool bSameTagValue = false; + if (bSameTagType) + { + if (texTag.m_bUsingTxdId) { + bSameTagValue = (pOldTexInfo->texTag.m_usTxdId == texTag.m_usTxdId); + } else { + bSameTagValue = (pOldTexInfo->texTag.m_pTex == texTag.m_pTex); +} + } + + if (bSameTagType && bSameTagValue && pOldTexInfo->pD3DData == pD3DData && pOldTexInfo->strTextureName == strTextureNameLower) + { + // Fast-return only if reverse lookup still points to this entry. + // Otherwise continue into recreate path to repair mapping. + STexInfo* pMappedTexInfo = MapFindRef(m_D3DDataTexInfoMap, pOldTexInfo->pD3DData); + if (pMappedTexInfo == pOldTexInfo && pOldTexInfo->bInTexInfoMap) + return pOldTexInfo; + } + + OnTextureStreamOut(pOldTexInfo); + // Erase from m_TexInfoMap by scanning the TXD ID bucket + typedef std::multimap::iterator IterType; + std::pair range = m_TexInfoMap.equal_range(pOldTexInfo->texTag.m_usTxdId); + for (IterType iter = range.first; iter != range.second; ++iter) + { + if (iter->second == pOldTexInfo) + { + pOldTexInfo->bInTexInfoMap = false; + m_TexInfoMap.erase(iter); + break; + } + } + DestroyTexInfo(pOldTexInfo); + } + } + } + // Create texinfo STexInfo* pTexInfo = new STexInfo(texTag, strTextureName, pD3DData); // Add to map MapInsert(m_TexInfoMap, pTexInfo->texTag.m_usTxdId, pTexInfo); + pTexInfo->bInTexInfoMap = true; // Add to D3DData lookup map MapSet(m_D3DDataTexInfoMap, pTexInfo->pD3DData, pTexInfo); + + // Add to script texture reverse lookup if tagged by a real RwTexture* + if (!texTag.m_bUsingTxdId && texTag.m_pTex && texTag.m_pTex != FAKE_RWTEXTURE_NO_TEXTURE) + m_ScriptTexInfoMap[texTag.m_pTex] = pTexInfo; + return pTexInfo; } @@ -399,9 +582,25 @@ STexInfo* CRenderWareSA::CreateTexInfo(const STexTag& texTag, const SString& str //////////////////////////////////////////////////////////////// void CRenderWareSA::DestroyTexInfo(STexInfo* pTexInfo) { - // Remove from D3DData lookup map - if (MapFindRef(m_D3DDataTexInfoMap, pTexInfo->pD3DData) == pTexInfo) + if (!pTexInfo) + return; + + pTexInfo->bInTexInfoMap = false; + + // Only remove if this specific STexInfo is the registered one + STexInfo* pCurrentEntry = MapFindRef(m_D3DDataTexInfoMap, pTexInfo->pD3DData); + if (pCurrentEntry == pTexInfo) + { MapRemove(m_D3DDataTexInfoMap, pTexInfo->pD3DData); + } + + // Remove from script texture reverse lookup + if (!pTexInfo->texTag.m_bUsingTxdId && pTexInfo->texTag.m_pTex && pTexInfo->texTag.m_pTex != FAKE_RWTEXTURE_NO_TEXTURE) + { + auto it = m_ScriptTexInfoMap.find(pTexInfo->texTag.m_pTex); + if (it != m_ScriptTexInfoMap.end() && it->second == pTexInfo) + m_ScriptTexInfoMap.erase(it); + } delete pTexInfo; } @@ -466,6 +665,10 @@ SShaderItemLayers* CRenderWareSA::GetAppliedShaderForD3DData(CD3DDUMMY* pD3DData void CRenderWareSA::AppendAdditiveMatch(CSHADERDUMMY* pShaderData, CClientEntityBase* pClientEntity, const char* szTextureNameMatch, float fShaderPriority, bool bShaderLayered, int iTypeMask, uint uiShaderCreateTime, bool bShaderUsesVertexShader, bool bAppendLayers) { + // NULL or empty pattern would cause issues + if (!szTextureNameMatch || !szTextureNameMatch[0]) + return; + TIMING_CHECKPOINT("+AppendAddMatch"); // Make previous versions usage of "CJ" work with new way @@ -473,8 +676,52 @@ void CRenderWareSA::AppendAdditiveMatch(CSHADERDUMMY* pShaderData, CClientEntity if (strTextureNameMatch.CompareI("cj")) strTextureNameMatch = "cj_ped_*"; + // Register the pattern as provided by script m_pMatchChannelManager->AppendAdditiveMatch(pShaderData, pClientEntity, strTextureNameMatch, fShaderPriority, bShaderLayered, iTypeMask, uiShaderCreateTime, bShaderUsesVertexShader, bAppendLayers); + + // Also register with internal texture name variant if pattern contains a known external name. + // This handles the case where script uses external names (e.g. "remap") but GTA internally + // renames textures (e.g., "#emap"). We register both patterns so the shader matches either. + // Handles: "remap", "remap*", "*remap*", "vehicleremap", etc. + SString strLower = strTextureNameMatch.ToLower(); + bool bHasRemap = strLower.Contains("remap"); + bool bHasWhite = strLower.Contains("white"); + + // Check for "remap" anywhere in the pattern (case-insensitive) + if (bHasRemap) + { + SString strInternalPattern = strTextureNameMatch.ReplaceI("remap", "#emap"); + // Only register if actually different (avoid duplicates) + if (strInternalPattern != strTextureNameMatch) + { + m_pMatchChannelManager->AppendAdditiveMatch(pShaderData, pClientEntity, strInternalPattern, fShaderPriority, bShaderLayered, iTypeMask, + uiShaderCreateTime, bShaderUsesVertexShader, bAppendLayers); + + // If pattern also contains "white", register the doubly-transformed variant + // e.g., "white_remap*" -> "@hite_#emap*" + if (bHasWhite) + { + SString strBothInternal = strInternalPattern.ReplaceI("white", "@hite"); + if (strBothInternal != strInternalPattern) + { + m_pMatchChannelManager->AppendAdditiveMatch(pShaderData, pClientEntity, strBothInternal, fShaderPriority, bShaderLayered, iTypeMask, + uiShaderCreateTime, bShaderUsesVertexShader, bAppendLayers); + } + } + } + } + // Check for "white" anywhere in the pattern (case-insensitive) + if (bHasWhite) + { + SString strInternalPattern = strTextureNameMatch.ReplaceI("white", "@hite"); + if (strInternalPattern != strTextureNameMatch) + { + m_pMatchChannelManager->AppendAdditiveMatch(pShaderData, pClientEntity, strInternalPattern, fShaderPriority, bShaderLayered, iTypeMask, + uiShaderCreateTime, bShaderUsesVertexShader, bAppendLayers); + } + } + TIMING_CHECKPOINT("-AppendAddMatch"); } @@ -487,6 +734,10 @@ void CRenderWareSA::AppendAdditiveMatch(CSHADERDUMMY* pShaderData, CClientEntity //////////////////////////////////////////////////////////////// void CRenderWareSA::AppendSubtractiveMatch(CSHADERDUMMY* pShaderData, CClientEntityBase* pClientEntity, const char* szTextureNameMatch) { + // NULL or empty pattern would cause problems + if (!szTextureNameMatch || !szTextureNameMatch[0]) + return; + TIMING_CHECKPOINT("+AppendSubMatch"); // Make previous versions usage of "CJ" work with new way @@ -494,7 +745,41 @@ void CRenderWareSA::AppendSubtractiveMatch(CSHADERDUMMY* pShaderData, CClientEnt if (strTextureNameMatch.CompareI("cj")) strTextureNameMatch = "cj_ped_*"; + // Register the pattern as provided by script m_pMatchChannelManager->AppendSubtractiveMatch(pShaderData, pClientEntity, strTextureNameMatch); + + // Also register with internal texture name variant (same logic as AppendAdditiveMatch) + SString strLower = strTextureNameMatch.ToLower(); + bool bHasRemap = strLower.Contains("remap"); + bool bHasWhite = strLower.Contains("white"); + + if (bHasRemap) + { + SString strInternalPattern = strTextureNameMatch.ReplaceI("remap", "#emap"); + if (strInternalPattern != strTextureNameMatch) + { + m_pMatchChannelManager->AppendSubtractiveMatch(pShaderData, pClientEntity, strInternalPattern); + + // If pattern also contains "white", register the doubly-transformed variant + if (bHasWhite) + { + SString strBothInternal = strInternalPattern.ReplaceI("white", "@hite"); + if (strBothInternal != strInternalPattern) + { + m_pMatchChannelManager->AppendSubtractiveMatch(pShaderData, pClientEntity, strBothInternal); + } + } + } + } + if (bHasWhite) + { + SString strInternalPattern = strTextureNameMatch.ReplaceI("white", "@hite"); + if (strInternalPattern != strTextureNameMatch) + { + m_pMatchChannelManager->AppendSubtractiveMatch(pShaderData, pClientEntity, strInternalPattern); + } + } + TIMING_CHECKPOINT("-AppendSubMatch"); } @@ -507,6 +792,9 @@ void CRenderWareSA::AppendSubtractiveMatch(CSHADERDUMMY* pShaderData, CClientEnt //////////////////////////////////////////////////////////////// void CRenderWareSA::OnTextureStreamIn(STexInfo* pTexInfo) { + if (!pTexInfo) + return; + // Insert into all channels that match the name m_pMatchChannelManager->InsertTexture(pTexInfo); } @@ -520,6 +808,9 @@ void CRenderWareSA::OnTextureStreamIn(STexInfo* pTexInfo) //////////////////////////////////////////////////////////////// void CRenderWareSA::OnTextureStreamOut(STexInfo* pTexInfo) { + if (!pTexInfo) + return; + m_pMatchChannelManager->RemoveTexture(pTexInfo); } @@ -647,19 +938,19 @@ void CRenderWareSA::SetGTAVertexShadersEnabled(bool bEnable) if (bEnable) { // Allow GTA vertex shaders (default) - MemPut(pSkinAtomic + 0, 0x8B); // mov eax, [edi+20h] + MemPut(pSkinAtomic + 0, 0x8B); // mov eax, [edi+20h] MemPut(pSkinAtomic + 1, 0x47); MemPut(pSkinAtomic + 2, 0x20); - MemPut(pSkinAtomic + 3, 0x85); // test eax, eax + MemPut(pSkinAtomic + 3, 0x85); // test eax, eax MemPut(pSkinAtomic + 4, 0xC0); } else { // Disallow GTA vertex shaders // This forces the current skin buffer to use software blending from now on - MemPut(pSkinAtomic + 0, 0x33); // xor eax, eax + MemPut(pSkinAtomic + 0, 0x33); // xor eax, eax MemPut(pSkinAtomic + 1, 0xC0); - MemPut(pSkinAtomic + 2, 0x89); // mov dword ptr [edi+20h], eax + MemPut(pSkinAtomic + 2, 0x89); // mov dword ptr [edi+20h], eax MemPut(pSkinAtomic + 3, 0x47); MemPut(pSkinAtomic + 4, 0x20); } @@ -675,24 +966,28 @@ void CRenderWareSA::SetGTAVertexShadersEnabled(bool bEnable) __declspec(noinline) void OnMY_RwTextureSetName(DWORD dwAddrCalledFrom, RwTexture* pTexture, const char* szName) { SString strReplacementName; - if (dwAddrCalledFrom == ADDR_CCustomCarPlateMgr_CreatePlateTexture_TextureSetName) + if (dwAddrCalledFrom == ADDR_CCustomCarPlateMgr_CreatePlateTexture_TextureSetName) { strReplacementName = "custom_car_plate"; - else if (dwAddrCalledFrom == ADDR_CCustomRoadsignMgr_CreateRoadsignTexture_TextureSetName) + } else if (dwAddrCalledFrom == ADDR_CCustomRoadsignMgr_CreateRoadsignTexture_TextureSetName) { strReplacementName = "custom_roadsign_text"; - else if (dwAddrCalledFrom > ADDR_CClothesBuilder_ConstructTextures_Start && dwAddrCalledFrom < ADDR_CClothesBuilder_ConstructTextures_End) + } else if (dwAddrCalledFrom > ADDR_CClothesBuilder_ConstructTextures_Start && dwAddrCalledFrom < ADDR_CClothesBuilder_ConstructTextures_End) { strReplacementName = SString("cj_ped_%s", szName); +} if (!strReplacementName.empty()) pGame->GetRenderWareSA()->SpecialAddedTexture(pTexture, strReplacementName); } // Hook info -#define HOOKPOS_RwTextureSetName 0x7F38A0 -#define HOOKSIZE_RwTextureSetName 9 -DWORD RETURN_RwTextureSetName = 0x7F38A9; -void _declspec(naked) HOOK_RwTextureSetName() +#define HOOKPOS_RwTextureSetName 0x7F38A0 +#define HOOKSIZE_RwTextureSetName 9 +DWORD RETURN_RwTextureSetName = 0x7F38A9; +static void __declspec(naked) HOOK_RwTextureSetName() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*2] @@ -706,6 +1001,7 @@ void _declspec(naked) HOOK_RwTextureSetName() mov ecx, ds:0x0C97B24 jmp RETURN_RwTextureSetName } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -721,12 +1017,15 @@ __declspec(noinline) void OnMY_RwTextureDestroy_Mid(RwTexture* pTexture) } // Hook info -#define HOOKPOS_RwTextureDestroy_Mid 0x07F3834 -#define HOOKSIZE_RwTextureDestroy_Mid 5 -DWORD RETURN_RwTextureDestroy_Mid = 0x07F3839; -void _declspec(naked) HOOK_RwTextureDestroy_Mid() +#define HOOKPOS_RwTextureDestroy_Mid 0x07F3834 +#define HOOKSIZE_RwTextureDestroy_Mid 5 +DWORD RETURN_RwTextureDestroy_Mid = 0x07F3839; +static void __declspec(naked) HOOK_RwTextureDestroy_Mid() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi @@ -737,6 +1036,7 @@ void _declspec(naked) HOOK_RwTextureDestroy_Mid() push 0x08E23CC jmp RETURN_RwTextureDestroy_Mid } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -751,7 +1051,7 @@ __declspec(noinline) void OnMY_RwIm3DRenderIndexedPrimitive_Pre(DWORD dwAddrCall if (dwAddrCalledFrom == ADDR_CVehicle_DoHeadLightBeam_RenderPrimitive || dwAddrCalledFrom == ADDR_CHeli_SearchLightCone_RenderPrimitive || dwAddrCalledFrom == ADDR_CWaterCannon_Render_RenderPrimitive) { - CRenderWareSA::ms_iRenderingType = RT_NONE; // Treat these items like world models + CRenderWareSA::ms_iRenderingType = RT_NONE; // Treat these items like world models } else { @@ -765,12 +1065,15 @@ __declspec(noinline) void OnMY_RwIm3DRenderIndexedPrimitive_Post(DWORD dwAddrCal } // Hook info -#define HOOKPOS_RwIm3DRenderIndexedPrimitive 0x07EF550 -#define HOOKSIZE_RwIm3DRenderIndexedPrimitive 5 -DWORD RETURN_RwIm3DRenderIndexedPrimitive = 0x07EF555; -void _declspec(naked) HOOK_RwIm3DRenderIndexedPrimitive() +#define HOOKPOS_RwIm3DRenderIndexedPrimitive 0x07EF550 +#define HOOKSIZE_RwIm3DRenderIndexedPrimitive 5 +DWORD RETURN_RwIm3DRenderIndexedPrimitive = 0x07EF555; +static void __declspec(naked) HOOK_RwIm3DRenderIndexedPrimitive() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*0] @@ -781,7 +1084,7 @@ void _declspec(naked) HOOK_RwIm3DRenderIndexedPrimitive() push [esp+4*3] push [esp+4*3] push [esp+4*3] - call inner + call inner add esp, 4*3 pushad @@ -790,10 +1093,12 @@ void _declspec(naked) HOOK_RwIm3DRenderIndexedPrimitive() add esp, 4*1 popad retn -inner: + + inner: mov eax, ds:0x0C9C078 jmp RETURN_RwIm3DRenderIndexedPrimitive } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -814,12 +1119,15 @@ __declspec(noinline) void OnMY_RwIm3DRenderPrimitive_Post(DWORD dwAddrCalledFrom } // Hook info -#define HOOKPOS_RwIm3DRenderPrimitive 0x07EF6B0 -#define HOOKSIZE_RwIm3DRenderPrimitive 6 -DWORD RETURN_RwIm3DRenderPrimitive = 0x07EF6B6; -void _declspec(naked) HOOK_RwIm3DRenderPrimitive() +#define HOOKPOS_RwIm3DRenderPrimitive 0x07EF6B0 +#define HOOKSIZE_RwIm3DRenderPrimitive 6 +DWORD RETURN_RwIm3DRenderPrimitive = 0x07EF6B6; +static void __declspec(naked) HOOK_RwIm3DRenderPrimitive() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*0] @@ -830,7 +1138,7 @@ void _declspec(naked) HOOK_RwIm3DRenderPrimitive() push [esp+4*3] push [esp+4*3] push [esp+4*3] - call inner + call inner add esp, 4*3 pushad @@ -839,10 +1147,12 @@ void _declspec(naked) HOOK_RwIm3DRenderPrimitive() add esp, 4*1 popad retn -inner: + + inner: mov ecx, ds:0x0C97B24 jmp RETURN_RwIm3DRenderPrimitive } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -863,12 +1173,15 @@ __declspec(noinline) void OnMY_RwIm2DRenderIndexedPrimitive_Post(DWORD dwAddrCal } // Hook info -#define HOOKPOS_RwIm2DRenderIndexedPrimitive 0x0734EA1 -#define HOOKSIZE_RwIm2DRenderIndexedPrimitive 5 -DWORD RETURN_RwIm2DRenderIndexedPrimitive = 0x0403927; -void _declspec(naked) HOOK_RwIm2DRenderIndexedPrimitive() +#define HOOKPOS_RwIm2DRenderIndexedPrimitive 0x0734EA1 +#define HOOKSIZE_RwIm2DRenderIndexedPrimitive 5 +DWORD RETURN_RwIm2DRenderIndexedPrimitive = 0x0403927; +static void __declspec(naked) HOOK_RwIm2DRenderIndexedPrimitive() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*0] @@ -881,7 +1194,7 @@ void _declspec(naked) HOOK_RwIm2DRenderIndexedPrimitive() push [esp+4*5] push [esp+4*5] push [esp+4*5] - call inner + call inner add esp, 4*5 pushad @@ -891,9 +1204,10 @@ void _declspec(naked) HOOK_RwIm2DRenderIndexedPrimitive() popad retn -inner: + inner: jmp RETURN_RwIm2DRenderIndexedPrimitive } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -914,12 +1228,15 @@ __declspec(noinline) void OnMY_RwIm2DRenderPrimitive_Post(DWORD dwAddrCalledFrom } // Hook info -#define HOOKPOS_RwIm2DRenderPrimitive 0x0734E90 -#define HOOKSIZE_RwIm2DRenderPrimitive 5 -DWORD RETURN_RwIm2DRenderPrimitive = 0x0734E95; -void _declspec(naked) HOOK_RwIm2DRenderPrimitive() +#define HOOKPOS_RwIm2DRenderPrimitive 0x0734E90 +#define HOOKSIZE_RwIm2DRenderPrimitive 5 +DWORD RETURN_RwIm2DRenderPrimitive = 0x0734E95; +static void __declspec(naked) HOOK_RwIm2DRenderPrimitive() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*0] @@ -930,7 +1247,7 @@ void _declspec(naked) HOOK_RwIm2DRenderPrimitive() push [esp+4*3] push [esp+4*3] push [esp+4*3] - call inner + call inner add esp, 4*3 pushad @@ -940,10 +1257,11 @@ void _declspec(naked) HOOK_RwIm2DRenderPrimitive() popad retn -inner: + inner: mov eax, ds:0x0C97B24 jmp RETURN_RwIm2DRenderPrimitive } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/game_sa/CRenderWareSA.ShaderSupport.h b/Client/game_sa/CRenderWareSA.ShaderSupport.h index dd2dfeb0761..2e94cb48a1e 100644 --- a/Client/game_sa/CRenderWareSA.ShaderSupport.h +++ b/Client/game_sa/CRenderWareSA.ShaderSupport.h @@ -20,12 +20,24 @@ #endif // Various dodgy pointer values -#define FAKE_D3DTEXTURE_EMPTY_KEY ( (CD3DDUMMY*)-1 ) -#define FAKE_D3DTEXTURE_DELETED_KEY ( (CD3DDUMMY*)-2 ) -#define FAKE_D3DTEXTURE_NO_TEXTURE ( (CD3DDUMMY*)-9 ) -#define FAKE_RWTEXTURE_NO_TEXTURE ( (RwTexture*)-10 ) +#define FAKE_D3DTEXTURE_EMPTY_KEY ((CD3DDUMMY*)-1) +#define FAKE_D3DTEXTURE_DELETED_KEY ((CD3DDUMMY*)-2) +#define FAKE_D3DTEXTURE_NO_TEXTURE ((CD3DDUMMY*)-9) +#define FAKE_RWTEXTURE_NO_TEXTURE ((RwTexture*)-10) #define FAKE_NAME_NO_TEXTURE "unnamed" +// CFastHashMap key funcs for CD3DDUMMY* - must be declared before CFastHashMap is used +// These override the default template keys (-3, -4) to use our values +inline CD3DDUMMY* GetEmptyMapKey(CD3DDUMMY**) +{ + return FAKE_D3DTEXTURE_EMPTY_KEY; +} + +inline CD3DDUMMY* GetDeletedMapKey(CD3DDUMMY**) +{ + return FAKE_D3DTEXTURE_DELETED_KEY; +} + class CMatchChannel; class CMatchChannelManager; struct STexNameInfo; @@ -35,17 +47,17 @@ struct STexNameInfo; // struct STexTag { - STexTag(ushort usTxdId) : m_bUsingTxdId(true), m_usTxdId(usTxdId), m_pTex(NULL) {} + STexTag(ushort usTxdId) : m_bUsingTxdId(true), m_usTxdId(usTxdId), m_pTex(nullptr) {} STexTag(RwTexture* pTex) : m_bUsingTxdId(false), m_usTxdId(0), m_pTex(pTex) {} - bool operator==(ushort usTxdId) const { return m_bUsingTxdId && usTxdId == m_usTxdId; } + [[nodiscard]] bool operator==(ushort usTxdId) const { return m_bUsingTxdId && usTxdId == m_usTxdId; } - bool operator==(RwTexture* pTex) const { return !m_bUsingTxdId && pTex == m_pTex; } + [[nodiscard]] bool operator==(RwTexture* pTex) const { return !m_bUsingTxdId && pTex == m_pTex; } const bool m_bUsingTxdId; - const ushort m_usTxdId; // Streamed textures are identified using the TXD id - const RwTexture* m_pTex; // Custom textures are identified using the RwTexture pointer + const ushort m_usTxdId; // Streamed textures are identified using the TXD id + const RwTexture* m_pTex; // Custom textures are identified using the RwTexture pointer }; struct SOrderValue @@ -53,12 +65,12 @@ struct SOrderValue SOrderValue(float fOrderPriority, uint uiShaderCreateTime) : fOrderPriority(fOrderPriority), uiShaderCreateTime(uiShaderCreateTime) {} // Less than means higher priority - bool operator<(const SOrderValue& other) const + [[nodiscard]] constexpr bool operator<(const SOrderValue& other) const { return fOrderPriority < other.fOrderPriority || (fOrderPriority == other.fOrderPriority && uiShaderCreateTime < other.uiShaderCreateTime); } - const float fOrderPriority; // Lower is higher priority + const float fOrderPriority; // Lower is higher priority const uint uiShaderCreateTime; }; @@ -89,18 +101,19 @@ struct SShaderInfo struct STexInfo { STexInfo(const STexTag& texTag, const SString& strTextureName, CD3DDUMMY* pD3DData) - : texTag(texTag), strTextureName(strTextureName.ToLower()), pD3DData(pD3DData), pAssociatedTexNameInfo(NULL) + : texTag(texTag), strTextureName(strTextureName.ToLower()), pD3DData(pD3DData), pAssociatedTexNameInfo(nullptr), bInTexInfoMap(false) { } STexTag texTag; - const SString strTextureName; // Always lower case + const SString strTextureName; // Always lower case CD3DDUMMY* const pD3DData; STexNameInfo* pAssociatedTexNameInfo; + bool bInTexInfoMap; }; struct SShaderInfoInstance { - SShaderInfoInstance() : pShaderInfo(NULL), bMixEntityAndNonEntity(false) {} + SShaderInfoInstance() : pShaderInfo(nullptr), bMixEntityAndNonEntity(false) {} SShaderInfoInstance(SShaderInfo* pShaderInfo, bool bMixEntityAndNonEntity) : pShaderInfo(pShaderInfo), bMixEntityAndNonEntity(bMixEntityAndNonEntity) {} @@ -108,23 +121,23 @@ struct SShaderInfoInstance bool bMixEntityAndNonEntity; #ifdef SHADER_DEBUG_CHECKS - bool operator==(const SShaderInfoInstance& other) const + [[nodiscard]] bool operator==(const SShaderInfoInstance& other) const { return pShaderInfo == other.pShaderInfo && bMixEntityAndNonEntity == other.bMixEntityAndNonEntity; } #endif - bool operator<(const SShaderInfoInstance& other) const { return pShaderInfo->orderValue < other.pShaderInfo->orderValue; } + [[nodiscard]] bool operator<(const SShaderInfoInstance& other) const { return pShaderInfo->orderValue < other.pShaderInfo->orderValue; } }; struct SShaderInfoLayers { SShaderInfoInstance pBase; std::vector layerList; - SShaderItemLayers output; // For renderer + SShaderItemLayers output; // For renderer #ifdef SHADER_DEBUG_CHECKS - bool operator==(const SShaderInfoLayers& other) const + [[nodiscard]] bool operator==(const SShaderInfoLayers& other) const { return pBase.pShaderInfo == other.pBase.pShaderInfo && pBase.bMixEntityAndNonEntity == other.pBase.bMixEntityAndNonEntity && layerList == other.layerList; @@ -137,8 +150,9 @@ struct SShaderInfoLayers // struct STexShaderReplacement { - STexShaderReplacement() : bSet(false) /*, pShaderInfo ( NULL )*/ {} + STexShaderReplacement() : bSet(false), bValid(true) {} bool bSet; + bool bValid; SShaderInfoLayers shaderLayers; }; @@ -157,24 +171,32 @@ struct STexNameInfo void ResetReplacementResults() { - for (uint i = 0; i < NUMELMS(texNoEntityShaders); i++) - texNoEntityShaders[i] = STexShaderReplacement(); - texEntityShaderMap.clear(); + // Mark invalid without clearing bSet - preserves data for safe renderer access + // Data will be rebuilt on next access when bValid=false is detected + for (STexShaderReplacement& shader : texNoEntityShaders) + { + shader.bValid = false; + } + for (CFastHashMap::value_type& pair : texEntityShaderMap) + { + pair.second.bValid = false; + } } STexShaderReplacement& GetTexNoEntityShader(int iEntityType) { - static char table[] = {-1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, 4}; - int idx = table[iEntityType]; + static constexpr char table[] = {-1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, 4}; + dassert(iEntityType >= 0 && iEntityType < static_cast(std::size(table))); + const int idx = table[iEntityType]; dassert(iEntityType >= TYPE_MASK_WORLD && iEntityType <= TYPE_MASK_OTHER && iEntityType == (1 << idx)); return texNoEntityShaders[idx]; } - const SString strTextureName; // Always lower case + const SString strTextureName; // Always lower case CFastHashSet usedByTexInfoList; CFastHashSet matchChannelList; - STexShaderReplacement texNoEntityShaders[5]; // 0 - world 1-ped 2-vehicle 3-object 4-other + STexShaderReplacement texNoEntityShaders[5]; // 0 - world 1-ped 2-vehicle 3-object 4-other CFastHashMap texEntityShaderMap; #ifdef SHADER_DEBUG_CHECKS diff --git a/Client/game_sa/CRenderWareSA.StreamingMemory.cpp b/Client/game_sa/CRenderWareSA.StreamingMemory.cpp new file mode 100644 index 00000000000..d7a6eaa6f17 --- /dev/null +++ b/Client/game_sa/CRenderWareSA.StreamingMemory.cpp @@ -0,0 +1,97 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CRenderWareSA.StreamingMemory.cpp + * PURPOSE: Streaming memory purging (MakeSpaceFor) to reduce OOM + * + *****************************************************************************/ + +#include "StdInc.h" +#include "CGameSA.h" +#include "CRenderWareSA.StreamingMemory.h" + +#include +#include +#include + +extern CGameSA* pGame; + +#define VAR_CStreaming_memoryAvailableKB 0x08A5A80 +#define VAR_CStreaming_memoryUsed 0x08E4CB4 + +namespace StreamingMemory +{ + + constexpr std::uint32_t kMinBytesToClean = 64U * 1024U; + constexpr std::uint32_t kMaxReasonableEstimate = 512U * 1024U * 1024U; // 512 MB + + void PrepareStreamingMemoryForSize(std::uint32_t estimatedBytes) + { + if (estimatedBytes < kMinBytesToClean) + return; + + if (!pGame) + return; + + auto* pStreaming = pGame->GetStreaming(); + if (!pStreaming) + return; + + std::uint32_t memoryLimitKB = 0; + __try + { + memoryLimitKB = *reinterpret_cast(VAR_CStreaming_memoryAvailableKB); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return; + } + if (memoryLimitKB == 0) + return; + + std::uint64_t memoryLimitBytes64 = static_cast(memoryLimitKB) * 1024ULL; + if (memoryLimitBytes64 > std::numeric_limits::max()) + memoryLimitBytes64 = std::numeric_limits::max(); + const std::uint32_t memoryLimitBytes = static_cast(memoryLimitBytes64); + + if (memoryLimitBytes <= 1) + return; + + std::uint32_t bytesToClean = std::min(estimatedBytes, kMaxReasonableEstimate); + if (bytesToClean >= memoryLimitBytes) + { + const std::uint32_t maxClean = static_cast((static_cast(memoryLimitBytes) * 3) / 4); + bytesToClean = std::min(maxClean, memoryLimitBytes - 1); + } + + if (bytesToClean == 0) + return; + + std::uint32_t memoryUsedBytes = 0; + __try + { + memoryUsedBytes = *reinterpret_cast(VAR_CStreaming_memoryUsed); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return; + } + if (memoryUsedBytes < memoryLimitBytes) + { + const std::uint32_t freeBytes = memoryLimitBytes - memoryUsedBytes; + if (freeBytes >= bytesToClean) + return; + } + + __try + { + pStreaming->MakeSpaceFor(bytesToClean); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return; + } + } + +} diff --git a/Client/game_sa/CRenderWareSA.StreamingMemory.h b/Client/game_sa/CRenderWareSA.StreamingMemory.h new file mode 100644 index 00000000000..d9ffb47f2d6 --- /dev/null +++ b/Client/game_sa/CRenderWareSA.StreamingMemory.h @@ -0,0 +1,17 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CRenderWareSA.StreamingMemory.h + * PURPOSE: Streaming memory purging (MakeSpaceFor) to reduce OOM + * + *****************************************************************************/ + +#pragma once + +#include + +namespace StreamingMemory +{ + void PrepareStreamingMemoryForSize(std::uint32_t estimatedBytes); +} diff --git a/Client/game_sa/CRenderWareSA.TextureReplacing.cpp b/Client/game_sa/CRenderWareSA.TextureReplacing.cpp index c6356288676..1f5b51299a1 100644 --- a/Client/game_sa/CRenderWareSA.TextureReplacing.cpp +++ b/Client/game_sa/CRenderWareSA.TextureReplacing.cpp @@ -6,281 +6,8987 @@ * *****************************************************************************/ +// TXD ref management rules (GTA:SA streaming can modify refs at any time): +// 1. Never release refs while textures are linked (causes 0xC0000374) +// 2. Add safety ref before orphaning to prevent race conditions +// 3. Re-link textures if race detected (prevents white textures) +// 4. Re-acquire ref before using TXD pointers after checks + +// The logic in CRenderWareSA.TextureReplacing.cpp is very peculiar and must be kept to work best (and most safely) with GTA's streaming system (Which we barely +// control). Changing something can have a domino effect, with effects not immediately obvious. The logic as present during the git blame date of this comment +// is a result of very painful trial and error. Future contributors need to be aware of the rules of engagement, and need to have researched relevant parts of +// the SA engine and RW. + #include "StdInc.h" #include "CGameSA.h" +#include "CRenderWareSA.h" +#include "CRenderWareSA.StreamingMemory.h" +#include "CTxdPoolSA.h" #include "gamesa_renderware.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include extern CGameSA* pGame; -// -// Info about the current state of a model's txd textures -// -class CModelTexturesInfo +#define FUNC_CTxdStore__SetTxdParent 0x7316E0 +#define FUNC_CTxdStore__GetTxdParent 0x731700 + +struct CModelTexturesInfo { -public: - std::vector originalTextures; - std::vector usedByReplacements; - ushort usTxdId; - RwTexDictionary* pTxd; + unsigned short usTxdId = 0; + RwTexDictionary* pTxd = nullptr; + std::unordered_set originalTextures; + std::unordered_map originalTexturesByName; + std::vector usedByReplacements; + bool bReapplyingTextures = false; + bool bHasLeakedTextures = false; + SString strDebugLabel; }; -std::map ms_ModelTexturesInfoMap; +static std::map ms_ModelTexturesInfoMap; +static uint32_t ms_uiTextureReplacingSession = 1; // Incremented at disconnect/reconnect boundaries -//////////////////////////////////////////////////////////////// -// -// CRenderWareSA::GetModelTexturesInfo -// -// Find/create texture info for a modelid -// -//////////////////////////////////////////////////////////////// -CModelTexturesInfo* CRenderWareSA::GetModelTexturesInfo(ushort usModelId) +namespace { - CModelInfoSA* pModelInfo = dynamic_cast(pGame->GetModelInfo(usModelId)); - if (!pModelInfo) - return NULL; + using TextureSwapMap = std::unordered_map; + using TextureNameSet = std::unordered_set; - ushort usTxdId = pModelInfo->GetTextureDictionaryID(); - - CModelTexturesInfo* pInfo = MapFind(ms_ModelTexturesInfoMap, usTxdId); - if (!pInfo) + // Content-hashed key avoids allocations. + // Stores the name lowercased so lookups match GTA:SA's own + // case-insensitive RwTexDictionaryFindNamedTexture (0x7F39F0). + struct SafeTextureName { - // Get txd - RwTexDictionary* pTxd = CTxdStore_GetTxd(usTxdId); + char m_name[RW_TEXTURE_NAME_LENGTH]; + std::size_t m_len; - if (!pTxd) + SafeTextureName(const char* str) { - pModelInfo->Request(BLOCKING, "CRenderWareSA::GetModelTexturesInfo"); - CTxdStore_AddRef(usTxdId); - ((void(__cdecl*)(unsigned short))FUNC_RemoveModel)(usModelId); - pTxd = CTxdStore_GetTxd(usTxdId); + if (str) + { + m_len = strnlen(str, RW_TEXTURE_NAME_LENGTH); + for (std::size_t i = 0; i < m_len; ++i) + m_name[i] = static_cast(std::tolower(static_cast(str[i]))); + if (m_len < RW_TEXTURE_NAME_LENGTH) + m_name[m_len] = '\0'; + } + else + { + m_len = 0; + m_name[0] = '\0'; + } } - else + + bool operator==(const SafeTextureName& other) const noexcept { return m_len == other.m_len && memcmp(m_name, other.m_name, m_len) == 0; } + }; + + struct SafeTextureNameHash + { + std::size_t operator()(const SafeTextureName& key) const noexcept { - CTxdStore_AddRef(usTxdId); - if (pModelInfo->GetModelType() == eModelInfoType::PED) + std::size_t h = 2166136261u; + for (std::size_t i = 0; i < key.m_len; ++i) { - // Mystery fix for #9336: (MTA sometimes fails at loading custom textures) - // Possibly forces the ped model to be reloaded in some way - ((void(__cdecl*)(unsigned short))FUNC_RemoveModel)(usModelId); + h ^= static_cast(key.m_name[i]); + h *= 16777619u; } + return h; } + }; - if (!pTxd) - return NULL; + using TxdTextureMap = std::unordered_map; + + // Lowercase a texture name for use as a map key, matching GTA:SA's + // case-insensitive texture lookup. + std::string LowercaseTextureName(const char* name, std::size_t len) + { + std::string result(name, len); + for (auto& c : result) + c = static_cast(std::tolower(static_cast(c))); + return result; + } + + struct ReplacementShaderKey + { + SReplacementTextures* pReplacement; + unsigned short usTxdId; + + bool operator==(const ReplacementShaderKey& rhs) const noexcept { return pReplacement == rhs.pReplacement && usTxdId == rhs.usTxdId; } + }; - // Add new info - MapSet(ms_ModelTexturesInfoMap, usTxdId, CModelTexturesInfo()); - pInfo = MapFind(ms_ModelTexturesInfoMap, usTxdId); - pInfo->usTxdId = usTxdId; - pInfo->pTxd = pTxd; + struct ReplacementShaderKeyHash + { + std::size_t operator()(const ReplacementShaderKey& key) const noexcept + { + return std::hash()(key.pReplacement) ^ (std::hash()(key.usTxdId) << 1); + } + }; + + using ShaderRegMap = std::unordered_map, ReplacementShaderKeyHash>; + ShaderRegMap g_ShaderRegs; + + // TXDs with leaked textures; retried at session boundary + std::unordered_set g_PendingLeakedTxdRefs; + + struct SIsolatedTxdInfo + { + unsigned short usTxdId = 0; + unsigned short usParentTxdId = 0; + bool bNeedsVehicleFallback = false; + }; + + struct SPendingReplacement + { + SReplacementTextures* pReplacement = nullptr; + unsigned int uiExpectedParentModelId = 0; + unsigned short usExpectedParentTxdId = 0; + unsigned char ucRetryCount = 0; + uint32_t uiWaitConditionSerial = 0; + uint32_t uiFirstQueueTick = 0; + uint32_t uiNextRetryTick = 0; + uint32_t uiSessionId = 0; + }; + + // NOTE: Overflow TXD slots [5000, 6316) share streaming IDs with COL/IPL/etc. + // We do NOT modify their streaming entries at all. The GetNextFileOnCd hook in + // CTxdPoolSA.cpp checks the TXD pool bytemap directly to satisfy DFF dependency + // checks, so no loadState manipulation is needed for overflow slots. + + // Per-model isolated TXD slots (higher pool usage than shared mode). + // Each entry holds an AddRef on its parent TXD to prevent streaming eviction. + std::unordered_map g_IsolatedTxdByModel; + std::unordered_map g_IsolatedModelByTxd; + std::unordered_set g_OrphanedIsolatedTxdSlots; + std::unordered_map g_PendingIsolatedModelTimes; + std::unordered_set g_PendingIsolatedModels; + std::unordered_map> g_PendingReplacementByModel; + std::unordered_set g_ActiveReplacements; + // TXD slots at safety-cap during cleanup; tracked for diagnostics + std::unordered_set g_PermanentlyLeakedTxdSlots; + // Textures (masters and leftover copies) that couldn't be destroyed inline; destroyed at StaticReset + std::unordered_set g_LeakedMasterTextures; + // D3D textures already released during StaticReset; used by SafeDestroyTextureWithRaster + // to detect shared rasters and prevent double-release across different texture structs. + std::unordered_set g_ReleasedD3DTextures; + // Rasters kept alive by orphaned copy textures during isolated TXD cleanup. + // Prevents master destruction from freeing rasters that orphaned copies still reference. + std::unordered_set g_OrphanedCopyRasters; + + // Script TXD slots that hold a parent pin ref (CTxdStore_AddRef on their parent). + // Tracked so the pin can be released when the slot is freed or reparented. + std::unordered_set g_ScriptTxdSlotsWithParentPin; + + // Cached global MTA raster set for PopulateOriginalTextures. + // Contains rasters from g_ActiveReplacements, g_LeakedMasterTextures, and g_OrphanedCopyRasters. + // Kept incrementally on additive changes (register, leak, orphan). + // Rebuilt from scratch on subtractive changes (unregister, raster null, erase) + // via the generation counter pair below. + std::unordered_set g_GlobalMtaRasterCache; + uint32_t g_uiGlobalMtaRasterGeneration = 0; + uint32_t g_uiGlobalMtaRasterCacheGeneration = 0; + + // Reverse map: TXD slot -> model IDs assigned to that slot. + // Rebuilt lazily when CModelInfoSA::ms_uiTxdAssignmentGeneration changes. + std::unordered_map> g_TxdToModelMap; + std::uint32_t g_uiTxdToModelMapGeneration = ~0u; // Forces rebuild on first access + + static void RebuildTxdToModelMap() + { + g_TxdToModelMap.clear(); - // Save original textures - GetTxdTextures(pInfo->originalTextures, pInfo->pTxd); + if (!pGame) + return; + + const unsigned int uiModelLimit = static_cast(pGame->GetBaseIDforCOL()); + for (unsigned int uiModelId = 0; uiModelId < uiModelLimit; ++uiModelId) + { + auto* pModelInfo = static_cast(pGame->GetModelInfo(uiModelId)); + if (!pModelInfo) + continue; + + const unsigned short usTxdId = pModelInfo->GetTextureDictionaryID(); + if (usTxdId == 0) + continue; + + g_TxdToModelMap[usTxdId].push_back(static_cast(uiModelId)); + } + + g_uiTxdToModelMapGeneration = CModelInfoSA::GetTxdAssignmentGeneration(); } - return pInfo; -} + static const std::vector& GetModelsForTxd(unsigned short usTxdId) + { + if (g_uiTxdToModelMapGeneration != CModelInfoSA::GetTxdAssignmentGeneration()) + RebuildTxdToModelMap(); -//////////////////////////////////////////////////////////////// -// -// CRenderWareSA::ModelInfoTXDLoadTextures -// -// Load textures from a TXD file -// -//////////////////////////////////////////////////////////////// -bool CRenderWareSA::ModelInfoTXDLoadTextures(SReplacementTextures* pReplacementTextures, const SString& strFilename, const SString& buffer, - bool bFilteringEnabled) -{ - // Are we already loaded? - if (!pReplacementTextures->textures.empty()) - return false; + static const std::vector empty; + auto it = g_TxdToModelMap.find(usTxdId); + return it != g_TxdToModelMap.end() ? it->second : empty; + } - // Try to load it - RwTexDictionary* pTxd = ReadTXD(strFilename, buffer); - if (pTxd) + static void InvalidateGlobalMtaRasterCache() { - // Get the list of textures into our own list - GetTxdTextures(pReplacementTextures->textures, pTxd); + ++g_uiGlobalMtaRasterGeneration; + } - for (uint i = 0; i < pReplacementTextures->textures.size(); i++) + static void* TryReleaseTextureD3D(RwTexture* pTex) + { + __try + { + RwRaster* pRaster = pTex ? pTex->raster : nullptr; + if (!pRaster) + return nullptr; + void* pD3D = pRaster->renderResource; + if (pD3D) + { + // Null the pointer first so a fault during Release() won't leave + // a stale D3D pointer that triggers a double-release later. + reinterpret_cast(pRaster->renderResource) = nullptr; + reinterpret_cast(pD3D)->Release(); + } + return pD3D; + } + __except (EXCEPTION_EXECUTE_HANDLER) { - pReplacementTextures->textures[i]->txd = NULL; - if (bFilteringEnabled) - pReplacementTextures->textures[i]->flags = 0x1102; // Enable filtering (otherwise textures are pixely) + return nullptr; } + } + + // Last-use timestamps for isolated TXDs; enables stale slot reclamation + std::unordered_map g_IsolatedTxdLastUseTime; + uint32_t g_uiLastStaleCleanupTime = 0; + + bool g_bInTxdReapply = false; - // Make the txd forget it has any textures and destroy it - pTxd->textures.root.next = &pTxd->textures.root; - pTxd->textures.root.prev = &pTxd->textures.root; - RwTexDictionaryDestroy(pTxd); - pTxd = NULL; + RwTexDictionary* g_pCachedVehicleTxd = nullptr; + RwListEntry* g_pCachedVehicleTxdListHead = nullptr; // textures.root.next at cache time; detects texture rebuild at same TXD address + RwListEntry* g_pCachedVehicleTxdListTail = nullptr; // textures.root.prev at cache time; detects changes at list tail + TxdTextureMap g_CachedVehicleTxdMap; + unsigned short g_usVehicleTxdSlotId = 0xFFFF; - // We succeeded if we got any textures - return pReplacementTextures->textures.size() > 0; + uint32_t g_uiLastPendingTxdProcessTime = 0; + uint32_t g_uiLastTxdPoolWarnTime = 0; + uint32_t g_uiLastPoolCountTime = 0; + uint32_t g_uiLastOrphanCleanupTime = 0; + uint32_t g_uiLastOrphanLogTime = 0; + uint32_t g_uiLastAdoptLogTime = 0; + uint32_t g_uiLastPoolDenyLogTime = 0; + uint32_t g_uiLastLeakCapacityLogTime = 0; + uint32_t g_uiLastIsolationFailLogTime = 0; + int g_iCachedPoolSize = 0; + int g_iCachedUsedSlots = 0; // Used slots in standard range [0, SA_TXD_POOL_CAPACITY) + bool g_bPoolCountDirty = true; + uint32_t g_uiIsolationDeniedSerial = 0; + bool g_bProcessingPendingReplacements = false; + bool g_bProcessingPendingIsolatedModels = false; + uint32_t g_uiPendingReplacementConditionSerial = 0; + uint32_t g_uiNextPendingRetryTick = 0; + const std::unordered_map>* g_pPendingReplacementSnapshot = nullptr; + + static uint32_t NextPendingReplacementConditionSerial() + { + ++g_uiPendingReplacementConditionSerial; + if (g_uiPendingReplacementConditionSerial == 0) + ++g_uiPendingReplacementConditionSerial; + + return g_uiPendingReplacementConditionSerial; } - return false; -} + static bool ClearPendingOnModelIfNoLiveEntry(unsigned short usModelId, const SPendingReplacement& pendingEntry) + { + if (!pendingEntry.pReplacement) + return false; -//////////////////////////////////////////////////////////////// -// -// CRenderWareSA::ModelInfoTXDAddTextures -// -// Adds texture into the TXD of a model. -// Returns true if model was affected. -// -//////////////////////////////////////////////////////////////// -bool CRenderWareSA::ModelInfoTXDAddTextures(SReplacementTextures* pReplacementTextures, ushort usModelId) -{ - // Already done for this modelid? - if (ListContains(pReplacementTextures->usedInModelIds, usModelId)) - return false; + auto itPendingReplacements = g_PendingReplacementByModel.find(usModelId); + if (itPendingReplacements != g_PendingReplacementByModel.end()) + { + for (const SPendingReplacement& liveEntry : itPendingReplacements->second) + { + if (liveEntry.pReplacement == pendingEntry.pReplacement && liveEntry.uiSessionId == pendingEntry.uiSessionId) + return false; + } + } - // Get valid textures info for this model - CModelTexturesInfo* pInfo = GetModelTexturesInfo(usModelId); - if (!pInfo) - return false; + pendingEntry.pReplacement->pendingOnModelIds.erase(usModelId); + return true; + } + + static void RemoveLivePendingEntries(unsigned short usModelId, const SPendingReplacement& pendingEntry) + { + if (!pendingEntry.pReplacement) + return; - // Remember which models this set has been applied to - pReplacementTextures->usedInModelIds.push_back(usModelId); + auto itPendingReplacements = g_PendingReplacementByModel.find(usModelId); + if (itPendingReplacements == g_PendingReplacementByModel.end()) + return; - // Already done for this txd? - if (ListContains(pReplacementTextures->usedInTxdIds, pInfo->usTxdId)) - return true; // Return true as model may need restreaming + std::vector& vecPending = itPendingReplacements->second; + vecPending.erase(std::remove_if(vecPending.begin(), vecPending.end(), + [&pendingEntry](const SPendingReplacement& e) + { + return e.pReplacement == pendingEntry.pReplacement && e.uiSessionId == pendingEntry.uiSessionId && + e.uiWaitConditionSerial == pendingEntry.uiWaitConditionSerial; + }), + vecPending.end()); - // - // Add section for this txd - // - pReplacementTextures->perTxdList.push_back(SReplacementTextures::SPerTxd()); - SReplacementTextures::SPerTxd& perTxdInfo = pReplacementTextures->perTxdList.back(); + if (vecPending.empty()) + g_PendingReplacementByModel.erase(itPendingReplacements); + } - perTxdInfo.usTxdId = pInfo->usTxdId; - perTxdInfo.bTexturesAreCopies = (pReplacementTextures->usedInTxdIds.size() > 0); + static void CompletePendingReplacement(unsigned short usModelId, const SPendingReplacement& pendingEntry) + { + if (!pendingEntry.pReplacement) + return; + + RemoveLivePendingEntries(usModelId, pendingEntry); + ClearPendingOnModelIfNoLiveEntry(usModelId, pendingEntry); + } - // Copy / clone textures - for (std::vector::iterator iter = pReplacementTextures->textures.begin(); iter != pReplacementTextures->textures.end(); iter++) + static const SPendingReplacement* FindPendingSnapshotEntry(unsigned short usModelId, const SReplacementTextures* pReplacement) { - RwTexture* pNewTexture = *iter; + if (!g_pPendingReplacementSnapshot || !pReplacement) + return nullptr; - // Use a copy if not first txd - if (perTxdInfo.bTexturesAreCopies) + if (pReplacement->pendingOnModelIds.find(usModelId) == pReplacement->pendingOnModelIds.end()) + return nullptr; + + auto itPendingReplacements = g_pPendingReplacementSnapshot->find(usModelId); + if (itPendingReplacements == g_pPendingReplacementSnapshot->end()) + return nullptr; + + for (const SPendingReplacement& snapshotEntry : itPendingReplacements->second) { - // Reuse the given texture's raster - RwTexture* pCopyTex = RwTextureCreate(pNewTexture->raster); + if (snapshotEntry.pReplacement == pReplacement && snapshotEntry.uiSessionId == ms_uiTextureReplacingSession) + return &snapshotEntry; + } - // Copy over additional properties - MemCpyFast(&pCopyTex->name, &pNewTexture->name, RW_TEXTURE_NAME_LENGTH); - MemCpyFast(&pCopyTex->mask, &pNewTexture->mask, RW_TEXTURE_NAME_LENGTH); - pCopyTex->flags = pNewTexture->flags; + return nullptr; + } - pNewTexture = pCopyTex; + bool BuildTxdTextureMapFast(RwTexDictionary* pTxd, TxdTextureMap& outMap); + static void AddVehicleTxdFallback(TxdTextureMap& outMap); + static bool ShouldUseVehicleTxdFallback(unsigned short usModelId); + static bool IsReadableTexture(RwTexture* pTexture); + static bool CollectModelMaterialTextureNames(TextureNameSet& names, unsigned short usModelId); + static void RebindLoadedModelToCurrentTxd(CModelInfoSA* pModelInfo, unsigned short usTxdId); + bool ReplaceTextureInModel(CModelInfoSA* pModelInfo, TextureSwapMap& swapMap); + static void RegisterReplacement(SReplacementTextures* pReplacement); + static void UnregisterReplacement(SReplacementTextures* pReplacement); + static bool IsReplacementActive(const SReplacementTextures* pReplacement); + static void TryApplyPendingReplacements(); + static bool WasIsolationDenied(uint32_t uiStartSerial); + static CStreamingInfo* GetStreamingInfoSafe(unsigned int uiStreamId); + static void SetStreamingInfoLoaded(unsigned short usTxdSlotId); + static void ResetStreamingInfo(unsigned short usTxdSlotId); + static void SetStreamingInfoLeaked(unsigned short usTxdSlotId); + static bool IsStreamingInfoSlot(unsigned short usTxdSlotId); + + constexpr std::size_t MAX_ORPHAN_TEXTURES = 8192; + constexpr std::size_t MAX_TEX_DICTIONARY_NAME_LENGTH = 24; + constexpr int TXD_POOL_USAGE_WARN_PERCENT = 80; + constexpr uint32_t TXD_POOL_USAGE_WARN_INTERVAL_MS = 5000; + constexpr uint32_t TXD_POOL_COUNT_INTERVAL_MS = 500; + constexpr uint32_t ORPHAN_CLEANUP_INTERVAL_MS = 250; + constexpr uint32_t LOG_THROTTLE_INTERVAL_MS = 2000; + constexpr int TXD_POOL_HARD_LIMIT_PERCENT = 95; + + // Pool pressure thresholds for stale slot reclamation + constexpr int TXD_POOL_PROACTIVE_CLEANUP_PERCENT = 70; + constexpr int TXD_POOL_MEDIUM_PRESSURE_PERCENT = 80; + constexpr int TXD_POOL_AGGRESSIVE_CLEANUP_PERCENT = 90; + constexpr uint32_t ISOLATION_STALE_TIMEOUT_MS = 15000; + constexpr uint32_t STALE_CLEANUP_INTERVAL_MS = 1000; + constexpr int TXD_POOL_RESERVED_SLOTS = 64; + constexpr int TXD_POOL_RESERVED_PERCENT = 10; + constexpr std::size_t MAX_LEAK_RETRY_COUNT = 1024; + constexpr std::size_t MAX_PENDING_REPLACEMENT_MODELS = 1024; + constexpr std::size_t MAX_PENDING_REPLACEMENTS_PER_MODEL = 16; + constexpr unsigned char MAX_PENDING_REPLACEMENT_RETRIES = 120; + constexpr unsigned char FIRST_SLOW_RETRY_COUNT = MAX_PENDING_REPLACEMENT_RETRIES + 1; + constexpr uint32_t PENDING_REPLACEMENT_MAX_AGE_MS = 300000; + constexpr uint32_t PENDING_REPLACEMENT_RETRY_INTERVAL_MS = 250; + constexpr std::size_t MAX_PENDING_REPLACEMENTS_PER_TICK = 64; + constexpr uint32_t PENDING_REPLACEMENT_SLOW_RETRY_INTERVAL_MS = 5000; + constexpr uint32_t PENDING_ISOLATION_TIMEOUT_MS = 15000; + constexpr std::size_t MAX_PENDING_ISOLATED_PER_TICK = 64; + constexpr std::size_t TEXTURE_NAME_VARIANT_COUNT = 3; + + // Per-TXD texture map cache to avoid repeated linked list iteration. + // Keyed by TXD slot ID; validated by TXD pointer, list head, and list tail + // (head/tail catch TXD rebuilds and texture adds/removes at either end). + struct SCachedTxdTextureMap + { + RwTexDictionary* pTxd = nullptr; // TXD pointer at cache time (detects reload/slot reuse) + RwListEntry* pListHead = nullptr; // textures.root.next at cache time (detects head change) + RwListEntry* pListTail = nullptr; // textures.root.prev at cache time (detects tail change) + TxdTextureMap textureMap; // Cached texture name > texture map + + bool IsValid(RwTexDictionary* pCurrentTxd) const noexcept + { + if (pTxd == nullptr || pTxd != pCurrentTxd) + return false; + + if (pListHead != pCurrentTxd->textures.root.next || pListTail != pCurrentTxd->textures.root.prev) + return false; + + if (pListHead && pListHead != &pCurrentTxd->textures.root) + { + RwTexture* pFirstTex = (RwTexture*)((char*)pListHead - offsetof(RwTexture, TXDList)); + auto it = textureMap.find(pFirstTex->name); + if (it == textureMap.end() || it->second != pFirstTex) + return false; + } + return true; } - perTxdInfo.usingTextures.push_back(pNewTexture); + }; + std::unordered_map g_TxdTextureMapCache; + + // Invalidate cache for specific TXD slot (call after texture add/remove) + static void InvalidateTxdTextureMapCache(unsigned short usTxdId) + { + g_TxdTextureMapCache.erase(usTxdId); } - // - // Add each texture to the target txd - // - for (std::vector::iterator iter = perTxdInfo.usingTextures.begin(); iter != perTxdInfo.usingTextures.end(); iter++) + // Clear all TXD texture map caches (call at session reset or bulk operations) + static void ClearTxdTextureMapCache() { - RwTexture* pNewTexture = *iter; + // Use swap idiom to ensure complete memory release on reconnect + // This forces deallocation of unordered_map buckets; .clear() might retain capacity. + // Safe: no TXD pool access, called early in StaticReset before heap-corrupting operations + decltype(g_TxdTextureMapCache) temp; + g_TxdTextureMapCache.swap(temp); + } - // If there is a name clash with an existing texture, replace it - RwTexture* pExistingTexture = RwTexDictionaryFindNamedTexture(pInfo->pTxd, pNewTexture->name); - if (pExistingTexture) + // Build or retrieve cached texture map and merge into output map. + // Use when building combined maps (parent + child + vehicle fallback) + static void MergeCachedTxdTextureMap(unsigned short usTxdId, RwTexDictionary* pTxd, TxdTextureMap& outMap) + { + if (!pTxd) + return; + + SCachedTxdTextureMap& entry = g_TxdTextureMapCache[usTxdId]; + + if (entry.IsValid(pTxd)) { - RwTexDictionaryRemoveTexture(pInfo->pTxd, pExistingTexture); + for (const auto& kv : entry.textureMap) + outMap[kv.first] = kv.second; + return; } - // Add the texture - dassert(!RwTexDictionaryContainsTexture(pInfo->pTxd, pNewTexture)); - RwTexDictionaryAddTexture(pInfo->pTxd, pNewTexture); + // Rebuild: reset cached metadata before populating + entry.pTxd = pTxd; + entry.pListHead = pTxd->textures.root.next; + entry.pListTail = pTxd->textures.root.prev; + // Use swap idiom to ensure complete memory release + // (avoids reconnect leaks; safer than .clear() on potentially corrupted maps) + TxdTextureMap temp; + entry.textureMap.swap(temp); + bool bComplete = BuildTxdTextureMapFast(pTxd, entry.textureMap); + + for (const auto& kv : entry.textureMap) + outMap[kv.first] = kv.second; + + // Don't keep a partial map in the cache.. next call will rebuild from scratch + if (!bComplete) + { + g_TxdTextureMapCache.erase(usTxdId); + AddReportLog(9401, SString("BuildTxdTextureMapFast: partial walk for TXD %u, cache entry discarded", usTxdId)); + } } - // Remember which txds this set has been applied to - pReplacementTextures->usedInTxdIds.push_back(pInfo->usTxdId); - dassert(!ListContains(pInfo->usedByReplacements, pReplacementTextures)); - pInfo->usedByReplacements.push_back(pReplacementTextures); - return true; + // Remove pReplacementTextures from all usedByReplacements vectors in the map. + // Uses usedInTxdIds for direct lookup. Debug builds verify no orphaned references exist. + void RemoveReplacementFromTracking(SReplacementTextures* pReplacementTextures) + { + if (!pReplacementTextures) + { + return; + } + + // Fast path: remove from entries tracked in usedInTxdIds (O(K) lookups where K = tracked TXDs) + for (unsigned short usTxdId : pReplacementTextures->usedInTxdIds) + { + auto it = ms_ModelTexturesInfoMap.find(usTxdId); + if (it != ms_ModelTexturesInfoMap.end()) + { + auto& usedBy = it->second.usedByReplacements; + if (!usedBy.empty()) + ListRemove(usedBy, pReplacementTextures); + } + } + + // Backstop: remove any orphaned references left behind when + // usedInTxdIds tracking fell out of sync with usedByReplacements. + for (auto& entry : ms_ModelTexturesInfoMap) + { + if (pReplacementTextures->usedInTxdIds.count(entry.first) != 0) + continue; + + auto& usedBy = entry.second.usedByReplacements; + if (!usedBy.empty()) + ListRemove(usedBy, pReplacementTextures); + } + +#ifdef MTA_DEBUG + // Debug-only: verify no references remain after the fast path and backstop scan. + for (const auto& entry : ms_ModelTexturesInfoMap) + { + const auto& usedBy = entry.second.usedByReplacements; + dassert(std::find(usedBy.begin(), usedBy.end(), pReplacementTextures) == usedBy.end()); + } +#endif + + if (!g_PendingReplacementByModel.empty()) + { + for (auto it = g_PendingReplacementByModel.begin(); it != g_PendingReplacementByModel.end();) + { + std::vector& vecPending = it->second; + vecPending.erase(std::remove_if(vecPending.begin(), vecPending.end(), [pReplacementTextures](const SPendingReplacement& entry) + { return entry.pReplacement == pReplacementTextures; }), + vecPending.end()); + if (vecPending.empty()) { + it = g_PendingReplacementByModel.erase(it); + } else { + ++it; } + } + } -//////////////////////////////////////////////////////////////// -// -// CRenderWareSA::ModelInfoTXDRemoveTextures -// -// Remove the textures from the txds that are using them. -// -//////////////////////////////////////////////////////////////// -void CRenderWareSA::ModelInfoTXDRemoveTextures(SReplacementTextures* pReplacementTextures) -{ - // For each using txd - for (uint i = 0; i < pReplacementTextures->perTxdList.size(); i++) + UnregisterReplacement(pReplacementTextures); + pReplacementTextures->pendingOnModelIds.clear(); + } + + std::vector& GetShaderRegList(SReplacementTextures* pReplacement, unsigned short usTxdId) { - SReplacementTextures::SPerTxd& perTxdInfo = pReplacementTextures->perTxdList[i]; + return g_ShaderRegs[ReplacementShaderKey{pReplacement, usTxdId}]; + } - // Get textures info - ushort usTxdId = perTxdInfo.usTxdId; - CModelTexturesInfo* pInfo = MapFind(ms_ModelTexturesInfoMap, usTxdId); + std::size_t GetShaderRegCount(const SReplacementTextures* pReplacement, unsigned short usTxdId) + { + auto it = g_ShaderRegs.find(ReplacementShaderKey{const_cast(pReplacement), usTxdId}); + return it == g_ShaderRegs.end() ? 0u : it->second.size(); + } - // Validate - dassert(MapFind(ms_ModelTexturesInfoMap, usTxdId)); - dassert(ListContains(pInfo->usedByReplacements, pReplacementTextures)); + template + void ForEachShaderReg(SReplacementTextures* pReplacement, unsigned short usTxdId, Fn&& fn) + { + auto it = g_ShaderRegs.find(ReplacementShaderKey{pReplacement, usTxdId}); + if (it == g_ShaderRegs.end()) + return; + for (CD3DDUMMY* pD3D : it->second) + fn(pD3D); + } + + void ClearShaderRegs(SReplacementTextures* pReplacement, unsigned short usTxdId) + { + g_ShaderRegs.erase(ReplacementShaderKey{pReplacement, usTxdId}); + } + + void RemoveShaderEntryByD3DData(unsigned short usTxdId, CD3DDUMMY* pD3DData); + void SafeOrphanTexture(RwTexture* pTexture, unsigned short usTxdIdHint = 0xFFFF); + + static void RemoveTxdFromReplacementTracking(unsigned short usTxdId) + { + std::map::iterator itInfo = ms_ModelTexturesInfoMap.find(usTxdId); + if (itInfo == ms_ModelTexturesInfoMap.end()) + return; - // Remove replacement textures - for (uint i = 0; i < perTxdInfo.usingTextures.size(); i++) + CModelTexturesInfo& info = itInfo->second; + std::vector vecUsedBy = info.usedByReplacements; + + for (SReplacementTextures* pReplacement : vecUsedBy) { - RwTexture* pOldTexture = perTxdInfo.usingTextures[i]; - RwTexDictionaryRemoveTexture(pInfo->pTxd, pOldTexture); - dassert(!RwTexDictionaryContainsTexture(pInfo->pTxd, pOldTexture)); - if (perTxdInfo.bTexturesAreCopies) + if (!pReplacement) + continue; + + ForEachShaderReg(pReplacement, usTxdId, [usTxdId](CD3DDUMMY* pD3D) { RemoveShaderEntryByD3DData(usTxdId, pD3D); }); + ClearShaderRegs(pReplacement, usTxdId); + + std::vector::iterator itPerTxd = + std::find_if(pReplacement->perTxdList.begin(), pReplacement->perTxdList.end(), + [usTxdId](const SReplacementTextures::SPerTxd& entry) { return entry.usTxdId == usTxdId; }); + + if (itPerTxd != pReplacement->perTxdList.end()) + { + itPerTxd->usingTextures.clear(); + itPerTxd->replacedOriginals.clear(); + pReplacement->perTxdList.erase(itPerTxd); + } + + pReplacement->usedInTxdIds.erase(usTxdId); + ListRemove(info.usedByReplacements, pReplacement); + } + + info.usedByReplacements.clear(); + info.originalTextures.clear(); + info.originalTexturesByName.clear(); + + // Balance the ref added by GetModelTexturesInfo + if (!info.bHasLeakedTextures && CTxdStore_GetNumRefs(usTxdId) > 0) + CRenderWareSA::DebugTxdRemoveRef(usTxdId, "RemoveTxdFromReplacementTracking"); + + ms_ModelTexturesInfoMap.erase(itInfo); + } + + static void RestoreModelTexturesToParent(CModelInfoSA* pModelInfo, unsigned short usModelId, unsigned short usOldTxdId, unsigned short usParentTxdId) + { + if (!pModelInfo) + return; + + if (!pModelInfo->GetRwObject()) + return; + + std::map::iterator itOldInfo = ms_ModelTexturesInfoMap.find(usOldTxdId); + if (itOldInfo == ms_ModelTexturesInfoMap.end()) + return; + + RwTexDictionary* pParentTxd = CTxdStore_GetTxd(usParentTxdId); + + // Request parent TXD to load if not already loaded - required for texture restoration. + // Without this, restoration fails when parent TXD is unloaded, leaving us with + // dangling texture pointers that later get their rasters nullified, causing "white textures" bug. + if (!pParentTxd && pGame && pGame->GetStreaming()) + { + const int iBaseIDforTXD = pGame->GetBaseIDforTXD(); + if (iBaseIDforTXD > 0) { - // Destroy the copy (but not the raster as that was not copied) - pOldTexture->raster = NULL; - RwTextureDestroy(pOldTexture); + const unsigned int uiTxdStreamId = usParentTxdId + static_cast(iBaseIDforTXD); + pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(true, "RestoreModelTexturesToParent-parentTxd"); + pParentTxd = CTxdStore_GetTxd(usParentTxdId); } } - // Ensure there are original named textures in the txd - for (uint i = 0; i < pInfo->originalTextures.size(); i++) + TxdTextureMap parentTxdMap; + if (pParentTxd) { - RwTexture* pOriginalTexture = pInfo->originalTextures[i]; - if (!RwTexDictionaryFindNamedTexture(pInfo->pTxd, pOriginalTexture->name)) - RwTexDictionaryAddTexture(pInfo->pTxd, pOriginalTexture); + MergeCachedTxdTextureMap(usParentTxdId, pParentTxd, parentTxdMap); + if (ShouldUseVehicleTxdFallback(usModelId)) + AddVehicleTxdFallback(parentTxdMap); } - // Remove refs - ListRemove(pInfo->usedByReplacements, pReplacementTextures); + for (SReplacementTextures* pReplacement : itOldInfo->second.usedByReplacements) + { + if (!pReplacement) + continue; - // If no refs left, check original state and then remove info - if (pInfo->usedByReplacements.empty()) + if (std::find(pReplacement->usedInModelIds.begin(), pReplacement->usedInModelIds.end(), usModelId) == pReplacement->usedInModelIds.end()) + continue; + + std::vector::iterator itPerTxd = + std::find_if(pReplacement->perTxdList.begin(), pReplacement->perTxdList.end(), + [usOldTxdId](const SReplacementTextures::SPerTxd& entry) { return entry.usTxdId == usOldTxdId; }); + + if (itPerTxd == pReplacement->perTxdList.end()) + continue; + + TextureSwapMap swapMap; + for (size_t idx = 0; idx < itPerTxd->usingTextures.size(); ++idx) + { + RwTexture* pReplacementTex = itPerTxd->usingTextures[idx]; + if (!pReplacementTex || !IsReadableTexture(pReplacementTex)) + continue; + + RwTexture* pOriginalTex = (idx < itPerTxd->replacedOriginals.size()) ? itPerTxd->replacedOriginals[idx] : nullptr; + if (!pOriginalTex && pParentTxd && strnlen(pReplacementTex->name, RW_TEXTURE_NAME_LENGTH) < RW_TEXTURE_NAME_LENGTH) + { + TxdTextureMap::iterator itParent = parentTxdMap.find(pReplacementTex->name); + if (itParent != parentTxdMap.end() && IsReadableTexture(itParent->second)) + pOriginalTex = itParent->second; + } + + if (pOriginalTex && IsReadableTexture(pOriginalTex)) + swapMap[pReplacementTex] = pOriginalTex; + } + + if (!swapMap.empty()) + ReplaceTextureInModel(pModelInfo, swapMap); + } + } + + static bool HasUsableTargetTxdMap(CModelInfoSA* pModelInfo, unsigned short usModelId, unsigned short usTargetTxdId) + { + if (!pGame || !pModelInfo) + return false; + + // Unloaded models can take the existing field-only path in SetTextureDictionaryID. + if (!pModelInfo->GetRwObject()) + return true; + + RwTexDictionary* pTargetTxd = CTxdStore_GetTxd(usTargetTxdId); + if (!pTargetTxd) + return false; + + TxdTextureMap targetTxdMap; + + constexpr std::size_t kMaxChainDepth = 16; + unsigned short chain[kMaxChainDepth]; + std::size_t chainLen = 0; + + CTxdPoolSA* pTxdPoolSA = static_cast(&pGame->GetPools()->GetTxdPool()); + for (unsigned short id = usTargetTxdId; pTxdPoolSA && chainLen < kMaxChainDepth;) { - // txd should now contain the same textures as 'originalTextures' - #ifdef MTA_DEBUG - std::vector currentTextures; - GetTxdTextures(currentTextures, pInfo->pTxd); - assert(currentTextures.size() == pInfo->originalTextures.size()); - for (uint i = 0; i < pInfo->originalTextures.size(); i++) + bool bCycle = false; + for (std::size_t j = 0; j < chainLen; ++j) { - RwTexture* pOriginalTexture = pInfo->originalTextures[i]; - assert(ListContains(currentTextures, pOriginalTexture)); - ListRemove(currentTextures, pOriginalTexture); + if (chain[j] == id) + { + bCycle = true; + break; + } } - assert(currentTextures.empty()); + if (bCycle) + break; - int32_t refsCount = CTxdStore_GetNumRefs(pInfo->usTxdId); - assert(refsCount > 0, "Should have at least one TXD reference here"); - #endif - // Remove info - CTxdStore_RemoveRef(pInfo->usTxdId); - MapRemove(ms_ModelTexturesInfoMap, usTxdId); + chain[chainLen++] = id; + + CTextureDictonarySAInterface* pSlot = pTxdPoolSA->GetTextureDictonarySlot(id); + if (!pSlot || pSlot->usParentIndex == static_cast(-1)) + break; + + id = pSlot->usParentIndex; + } + + bool bChainComplete = true; + for (std::size_t i = chainLen; i > 0; --i) + { + RwTexDictionary* pChainTxd = CTxdStore_GetTxd(chain[i - 1]); + if (pChainTxd) { + MergeCachedTxdTextureMap(chain[i - 1], pChainTxd, targetTxdMap); + } else { + bChainComplete = false; +} } + + if (ShouldUseVehicleTxdFallback(usModelId)) + AddVehicleTxdFallback(targetTxdMap); + + // Only accept a non-empty map when every ancestor in the chain + // was loaded. A partial chain can produce a map that looks valid + // but is missing textures from unloaded ancestors, which leads + // to white surfaces after rebind. + if (!targetTxdMap.empty() && bChainComplete) + return true; + + TextureNameSet modelTextureNames; + if (CollectModelMaterialTextureNames(modelTextureNames, usModelId) && modelTextureNames.empty()) + return true; + + return false; + } + + static size_t AddModelSwitchGuardRefs(CModelInfoSA* pModelInfo) + { + if (!pGame || !pModelInfo) + return 0; + + CBaseModelInfoSAInterface* pInterface = pModelInfo->GetInterface(); + if (!pInterface) + return 0; + + const unsigned short usCurrentTxdId = pModelInfo->GetTextureDictionaryID(); + if (pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(usCurrentTxdId)) + return 0; + + size_t nExtra = pInterface->usNumberOfRefs; + if (pInterface->pRwObject) + nExtra++; + + for (size_t i = 0; i < nExtra; i++) + CTxdStore_AddRef(usCurrentTxdId); + + return nExtra; } - // Destroy replacement textures - for (uint i = 0; i < pReplacementTextures->textures.size(); i++) + static void RemoveModelSwitchGuardRefs(unsigned short usTxdId, size_t nRefs) { - RwTexture* pOldTexture = pReplacementTextures->textures[i]; - DestroyTexture(pOldTexture); + if (!pGame || nRefs == 0) + return; + + if (pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(usTxdId)) + return; + + for (size_t i = 0; i < nRefs; i++) + CTxdStore_RemoveRef(usTxdId); + } + + static bool TrySwitchModelToTxd(CModelInfoSA* pModelInfo, unsigned short usModelId, unsigned short usTargetTxdId, bool bTargetMapAlreadyValidated = false) + { + if (!pModelInfo) + return false; + + if (pModelInfo->GetTextureDictionaryID() == usTargetTxdId) + return true; + + if (!bTargetMapAlreadyValidated && !HasUsableTargetTxdMap(pModelInfo, usModelId, usTargetTxdId)) + return false; + + const unsigned short usOriginalTxdId = pModelInfo->GetTextureDictionaryID(); + const size_t nGuardRefs = AddModelSwitchGuardRefs(pModelInfo); + + pModelInfo->SetTextureDictionaryID(usTargetTxdId); + + if (pModelInfo->GetTextureDictionaryID() == usTargetTxdId) + return true; + + if (pModelInfo->GetTextureDictionaryID() == usOriginalTxdId) + RemoveModelSwitchGuardRefs(usOriginalTxdId, nGuardRefs); + + return false; + } + + static bool TryRestoreAndSwitchModelToTxd(CModelInfoSA* pModelInfo, unsigned short usModelId, unsigned short usOldTxdId, unsigned short usTargetTxdId) + { + if (!pModelInfo) + return false; + + if (!HasUsableTargetTxdMap(pModelInfo, usModelId, usTargetTxdId)) + return false; + + RestoreModelTexturesToParent(pModelInfo, usModelId, usOldTxdId, usTargetTxdId); + return TrySwitchModelToTxd(pModelInfo, usModelId, usTargetTxdId, true); + } + + static void QueuePendingReplacement(unsigned short usModelId, SReplacementTextures* pReplacement, unsigned int uiExpectedParentModelId, + unsigned short usExpectedParentTxdId) + { + if (!pReplacement) + return; + + if (pReplacement->uiSessionId != ms_uiTextureReplacingSession) + return; + RegisterReplacement(pReplacement); + + std::unordered_map>::iterator itPendingReplacements = g_PendingReplacementByModel.find(usModelId); + if (itPendingReplacements == g_PendingReplacementByModel.end()) + { + if (g_PendingReplacementByModel.size() >= MAX_PENDING_REPLACEMENT_MODELS) + { + // Reclaim slots held by stale entries before rejecting the new one + const uint32_t uiEvictNow = GetTickCount32(); + for (auto itEvict = g_PendingReplacementByModel.begin(); itEvict != g_PendingReplacementByModel.end();) + { + auto& vec = itEvict->second; + vec.erase(std::remove_if(vec.begin(), vec.end(), + [uiEvictNow](const SPendingReplacement& e) + { + return e.uiSessionId != ms_uiTextureReplacingSession || !IsReplacementActive(e.pReplacement) || + (uiEvictNow - e.uiFirstQueueTick) > PENDING_REPLACEMENT_MAX_AGE_MS; + }), + vec.end()); + + if (vec.empty()) { + itEvict = g_PendingReplacementByModel.erase(itEvict); + } else { + ++itEvict; +} + } + + if (g_PendingReplacementByModel.size() >= MAX_PENDING_REPLACEMENT_MODELS) + { + AddReportLog(9401, SString("Pending replacement queue is full while deferring model %u", usModelId)); + return; + } + } + + itPendingReplacements = g_PendingReplacementByModel.emplace(usModelId, std::vector()).first; + } + + std::vector& vecPending = itPendingReplacements->second; + const uint32_t uiNow = GetTickCount32(); + + for (SPendingReplacement& entry : vecPending) + { + if (entry.pReplacement == pReplacement) + { + const bool bExpectedStateChanged = + entry.uiExpectedParentModelId != uiExpectedParentModelId || entry.usExpectedParentTxdId != usExpectedParentTxdId; + + entry.uiExpectedParentModelId = uiExpectedParentModelId; + entry.usExpectedParentTxdId = usExpectedParentTxdId; + + // Parent changed - new wait condition, so wipe timing and retry state. + if (bExpectedStateChanged) + { + entry.uiWaitConditionSerial = NextPendingReplacementConditionSerial(); + entry.uiFirstQueueTick = uiNow; + entry.ucRetryCount = 0; + entry.uiNextRetryTick = uiNow; + + if (g_uiNextPendingRetryTick == 0 || uiNow < g_uiNextPendingRetryTick) + g_uiNextPendingRetryTick = uiNow; + } + + pReplacement->pendingOnModelIds.insert(usModelId); + return; + } + } + + if (vecPending.size() >= MAX_PENDING_REPLACEMENTS_PER_MODEL) + { + // Reclaim stale entries for this model before rejecting + vecPending.erase(std::remove_if(vecPending.begin(), vecPending.end(), + [uiNow](const SPendingReplacement& e) + { + return e.uiSessionId != ms_uiTextureReplacingSession || !IsReplacementActive(e.pReplacement) || + (uiNow - e.uiFirstQueueTick) > PENDING_REPLACEMENT_MAX_AGE_MS; + }), + vecPending.end()); + + if (vecPending.size() >= MAX_PENDING_REPLACEMENTS_PER_MODEL) + { + AddReportLog(9401, SString("Pending replacement list is full for model %u", usModelId)); + return; + } + } + + SPendingReplacement entry; + entry.pReplacement = pReplacement; + entry.uiExpectedParentModelId = uiExpectedParentModelId; + entry.usExpectedParentTxdId = usExpectedParentTxdId; + entry.uiSessionId = ms_uiTextureReplacingSession; + + const auto* pSnapshotEntry = FindPendingSnapshotEntry(usModelId, pReplacement); + const bool bMatchesSnapshotWaitCondition = pSnapshotEntry && pSnapshotEntry->uiExpectedParentModelId == uiExpectedParentModelId && + pSnapshotEntry->usExpectedParentTxdId == usExpectedParentTxdId; + + if (bMatchesSnapshotWaitCondition) + { + entry.uiWaitConditionSerial = pSnapshotEntry->uiWaitConditionSerial; + entry.ucRetryCount = pSnapshotEntry->ucRetryCount; + entry.uiFirstQueueTick = pSnapshotEntry->uiFirstQueueTick; + entry.uiNextRetryTick = pSnapshotEntry->uiNextRetryTick; + } + else + { + entry.uiWaitConditionSerial = NextPendingReplacementConditionSerial(); + entry.ucRetryCount = 0; + entry.uiFirstQueueTick = uiNow; + entry.uiNextRetryTick = uiNow; + } + + pReplacement->pendingOnModelIds.insert(usModelId); + vecPending.push_back(entry); + + if (g_uiNextPendingRetryTick == 0 || entry.uiNextRetryTick < g_uiNextPendingRetryTick) + g_uiNextPendingRetryTick = entry.uiNextRetryTick; + } + + static void KeepPendingReplacement(unsigned short usModelId, const SPendingReplacement& pendingEntry) + { + if (!pendingEntry.pReplacement) + return; + + if (pendingEntry.uiSessionId != ms_uiTextureReplacingSession) + return; + + if (!IsReplacementActive(pendingEntry.pReplacement)) + return; + + std::vector& vecPending = g_PendingReplacementByModel[usModelId]; + for (SPendingReplacement& existingEntry : vecPending) + { + if (existingEntry.pReplacement == pendingEntry.pReplacement) + { + const bool bSameWaitCondition = existingEntry.uiWaitConditionSerial == pendingEntry.uiWaitConditionSerial; + + if (bSameWaitCondition) + { + if (pendingEntry.ucRetryCount > existingEntry.ucRetryCount) + existingEntry.ucRetryCount = pendingEntry.ucRetryCount; + + if (existingEntry.uiFirstQueueTick == 0 || pendingEntry.uiFirstQueueTick < existingEntry.uiFirstQueueTick) + existingEntry.uiFirstQueueTick = pendingEntry.uiFirstQueueTick; + + if (pendingEntry.uiNextRetryTick > existingEntry.uiNextRetryTick) + existingEntry.uiNextRetryTick = pendingEntry.uiNextRetryTick; + } + return; + } + } + + vecPending.push_back(pendingEntry); + } + + static void RequeuePendingReplacement(unsigned short usModelId, const SPendingReplacement& pendingEntry, bool bIncrementRetry) + { + if (!pendingEntry.pReplacement) + return; + + if (pendingEntry.uiSessionId != ms_uiTextureReplacingSession) + return; + + if (!IsReplacementActive(pendingEntry.pReplacement)) + return; + + SPendingReplacement pendingEntryCopy = pendingEntry; + if (bIncrementRetry && pendingEntryCopy.ucRetryCount < MAX_PENDING_REPLACEMENT_RETRIES) + ++pendingEntryCopy.ucRetryCount; + + pendingEntryCopy.uiNextRetryTick = GetTickCount32() + PENDING_REPLACEMENT_RETRY_INTERVAL_MS; + + std::vector& vecPending = g_PendingReplacementByModel[usModelId]; + + for (SPendingReplacement& existingEntry : vecPending) + { + if (existingEntry.pReplacement == pendingEntryCopy.pReplacement) + { + const bool bSameWaitCondition = existingEntry.uiWaitConditionSerial == pendingEntryCopy.uiWaitConditionSerial; + + if (bSameWaitCondition) + { + // Keep the higher retry count so escalation is never lost + if (pendingEntryCopy.ucRetryCount > existingEntry.ucRetryCount) + existingEntry.ucRetryCount = pendingEntryCopy.ucRetryCount; + } + // Enforce delayed retry so a fresh QueuePendingReplacement + // inside ModelInfoTXDAddTextures cant keep the entry eligible every frame. + if (pendingEntryCopy.uiNextRetryTick > existingEntry.uiNextRetryTick) + existingEntry.uiNextRetryTick = pendingEntryCopy.uiNextRetryTick; + return; + } + } + + vecPending.push_back(pendingEntryCopy); + } + + static void TryApplyPendingReplacements() + { + if (g_bProcessingPendingReplacements) + return; + + if (g_PendingReplacementByModel.empty()) + return; + + if (g_uiNextPendingRetryTick != 0 && static_cast(GetTickCount32() - g_uiNextPendingRetryTick) < 0) + return; + + CRenderWareSA* pRenderWareSA = pGame ? pGame->GetRenderWareSA() : nullptr; + if (!pRenderWareSA) + return; + + // Guard ensures flag is reset on any exit path + struct SProcessingGuard + { + bool& bFlag; + SProcessingGuard(bool& flag) : bFlag(flag) { bFlag = true; } + ~SProcessingGuard() { bFlag = false; } + } guard(g_bProcessingPendingReplacements); + + std::unordered_map> mapPendingSnapshot; + mapPendingSnapshot.swap(g_PendingReplacementByModel); + + struct SPendingSnapshotGuard + { + const std::unordered_map>*& pSnapshot; + SPendingSnapshotGuard(const std::unordered_map>*& pRef, + const std::unordered_map>* pValue) + : pSnapshot(pRef) + { + pSnapshot = pValue; + } + ~SPendingSnapshotGuard() { pSnapshot = nullptr; } + } snapshotGuard(g_pPendingReplacementSnapshot, &mapPendingSnapshot); + + std::size_t uiProcessedCount = 0; + bool bReachedLimit = false; + + for (auto itPending = mapPendingSnapshot.begin(); itPending != mapPendingSnapshot.end(); ++itPending) + { + const unsigned short usModelId = itPending->first; + const std::vector& vecPending = itPending->second; + const uint32_t uiNow = GetTickCount32(); + if (bReachedLimit) + { + for (const SPendingReplacement& entry : vecPending) + RequeuePendingReplacement(usModelId, entry, false); + continue; + } + + CModelInfoSA* pModelInfo = static_cast(pGame ? pGame->GetModelInfo(usModelId) : nullptr); + if (!pModelInfo) + { + for (const SPendingReplacement& entry : vecPending) + { + if (entry.pReplacement && entry.uiSessionId == ms_uiTextureReplacingSession && IsReplacementActive(entry.pReplacement)) + CompletePendingReplacement(usModelId, entry); + } + continue; + } + + const unsigned int uiCurrentParentModelId = pModelInfo->GetParentID(); + const bool bIsVanilla = (uiCurrentParentModelId == 0); + CModelInfoSA* pParentInfo = bIsVanilla ? nullptr : static_cast(pGame->GetModelInfo(uiCurrentParentModelId)); + const unsigned short usCurrentParentTxdId = pParentInfo ? pParentInfo->GetTextureDictionaryID() : 0; + const bool bModelLoaded = pModelInfo->IsLoaded(); + const unsigned int uiBaseTxdId = pGame->GetBaseIDforTXD(); + const unsigned int uiParentStreamId = static_cast(usCurrentParentTxdId) + uiBaseTxdId; + // Parent TXDs are always vanilla SA slots (< 5000), so streaming info is valid. + // Guard with SA_TXD_POOL_CAPACITY in case that invariant ever breaks. + CStreamingInfo* pParentStreamInfo = + (!bIsVanilla && usCurrentParentTxdId < CTxdPoolSA::SA_TXD_POOL_CAPACITY) ? GetStreamingInfoSafe(uiParentStreamId) : nullptr; + const bool bParentStreamingBusy = + !bIsVanilla && usCurrentParentTxdId != 0 && pParentStreamInfo && + (pParentStreamInfo->loadState == eModelLoadState::LOADSTATE_READING || pParentStreamInfo->loadState == eModelLoadState::LOADSTATE_FINISHING); + + for (const SPendingReplacement& entry : vecPending) + { + if (bReachedLimit) + { + RequeuePendingReplacement(usModelId, entry, false); + continue; + } + + if (!entry.pReplacement) + continue; + + if (!IsReplacementActive(entry.pReplacement)) + continue; + + if (entry.uiSessionId != ms_uiTextureReplacingSession) + continue; + + if (uiNow - entry.uiFirstQueueTick >= PENDING_REPLACEMENT_MAX_AGE_MS) + { + if (ClearPendingOnModelIfNoLiveEntry(usModelId, entry)) + AddReportLog(9401, SString("Dropping stale pending replacement for model %u", usModelId)); + continue; + } + + if (uiNow < entry.uiNextRetryTick) + { + KeepPendingReplacement(usModelId, entry); + continue; + } + + if ((entry.uiExpectedParentModelId != 0 && entry.uiExpectedParentModelId != uiCurrentParentModelId) || + (entry.usExpectedParentTxdId != 0 && entry.usExpectedParentTxdId != usCurrentParentTxdId)) + { + SPendingReplacement updated = entry; + updated.uiExpectedParentModelId = uiCurrentParentModelId; + updated.usExpectedParentTxdId = usCurrentParentTxdId; + updated.uiWaitConditionSerial = NextPendingReplacementConditionSerial(); + RequeuePendingReplacement(usModelId, updated, false); + continue; + } + + if (!bModelLoaded) + { + RequeuePendingReplacement(usModelId, entry, false); + continue; + } + + if (bParentStreamingBusy) + { + RequeuePendingReplacement(usModelId, entry, false); + continue; + } + + if (uiProcessedCount >= MAX_PENDING_REPLACEMENTS_PER_TICK) + { + bReachedLimit = true; + RequeuePendingReplacement(usModelId, entry, false); + continue; + } + + ++uiProcessedCount; + + const bool bApplied = pRenderWareSA->ModelInfoTXDAddTextures(entry.pReplacement, usModelId); + if (!bApplied) + { + if (entry.ucRetryCount >= MAX_PENDING_REPLACEMENT_RETRIES) + { + // Slow retry: keep trying with longer intervals until + // the age limit expires, instead of silently giving up. + SPendingReplacement slowRetry = entry; + slowRetry.uiNextRetryTick = GetTickCount32() + PENDING_REPLACEMENT_SLOW_RETRY_INTERVAL_MS; + + if (entry.ucRetryCount == MAX_PENDING_REPLACEMENT_RETRIES) + { + AddReportLog(9403, SString("TryApplyPendingReplacements: model %u entering slow retry after %u attempts", usModelId, + static_cast(entry.ucRetryCount))); + slowRetry.ucRetryCount = FIRST_SLOW_RETRY_COUNT; + } + + KeepPendingReplacement(usModelId, slowRetry); + } + else + { + RequeuePendingReplacement(usModelId, entry, true); + } + } + else + { + CompletePendingReplacement(usModelId, entry); + } + } + } + + // Update earliest eligible time so frames between retries skip the swap. + g_uiNextPendingRetryTick = UINT32_MAX; + for (const auto& pair : g_PendingReplacementByModel) + for (const auto& pendEntry : pair.second) + if (pendEntry.uiNextRetryTick < g_uiNextPendingRetryTick) + g_uiNextPendingRetryTick = pendEntry.uiNextRetryTick; + } + + static bool OrphanTxdTexturesBounded(RwTexDictionary* pTxd, bool bClearList) + { + if (!pTxd) + return false; + + std::vector vecTexturesToOrphan; + vecTexturesToOrphan.reserve(64); + + RwListEntry* const pRoot = &pTxd->textures.root; + RwListEntry* pNode = pRoot->next; + std::size_t uiCount = 0; + + while (pNode && pNode != pRoot && uiCount < MAX_ORPHAN_TEXTURES) + { + RwTexture* pTex = reinterpret_cast(reinterpret_cast(pNode) - offsetof(RwTexture, TXDList)); + if (pTex && pTex->txd == pTxd) + vecTexturesToOrphan.push_back(pTex); + + pNode = pNode->next; + ++uiCount; + } + + const bool bProcessedAll = (pNode == pRoot); + if (!bProcessedAll) + { + AddReportLog(9401, SString("OrphanTxdTexturesBounded: bailed after %u entries, TXD list too large or corrupt", (unsigned int)uiCount)); + return false; + } + + for (RwTexture* pTexture : vecTexturesToOrphan) + { + SafeOrphanTexture(pTexture); + } + + if (pRoot) + { + pRoot->next = pRoot; + pRoot->prev = pRoot; + } + + return true; + } + + static void MarkTxdPoolCountDirty() + { + g_bPoolCountDirty = true; + } + + static void AddPendingIsolatedModel(unsigned short usModelId) + { + g_PendingIsolatedModels.insert(usModelId); + g_PendingIsolatedModelTimes[usModelId] = GetTickCount32(); + + if (!g_bProcessingPendingIsolatedModels) + { + CRenderWareSA* pRenderWareSA = pGame ? pGame->GetRenderWareSA() : nullptr; + if (pRenderWareSA) + pRenderWareSA->ProcessPendingIsolatedModels(); + } + } + + static void ClearPendingIsolatedModel(unsigned short usModelId) + { + g_PendingIsolatedModels.erase(usModelId); + g_PendingIsolatedModelTimes.erase(usModelId); + } + + static void ClearPendingReplacementStateForModel(unsigned short usModelId) + { + std::unordered_map>::iterator itPendingReplacements = g_PendingReplacementByModel.find(usModelId); + if (itPendingReplacements == g_PendingReplacementByModel.end()) + return; + + for (const SPendingReplacement& pendingReplacement : itPendingReplacements->second) + { + SReplacementTextures* pPendingReplacement = pendingReplacement.pReplacement; + if (!pPendingReplacement) + continue; + + if (pendingReplacement.uiSessionId != ms_uiTextureReplacingSession) + continue; + + pPendingReplacement->pendingOnModelIds.erase(usModelId); + } + } + + static void RegisterReplacement(SReplacementTextures* pReplacement) + { + if (pReplacement) + { + if (g_ActiveReplacements.insert(pReplacement).second) + { + for (RwTexture* pTex : pReplacement->textures) + { + if (pTex && pTex->raster) + g_GlobalMtaRasterCache.insert(pTex->raster); + } + } + } + } + + static void UnregisterReplacement(SReplacementTextures* pReplacement) + { + if (pReplacement) + { + if (g_ActiveReplacements.erase(pReplacement) != 0) + InvalidateGlobalMtaRasterCache(); + } + } + + static bool IsReplacementActive(const SReplacementTextures* pReplacement) + { + if (!pReplacement) + return false; + + return g_ActiveReplacements.find(pReplacement) != g_ActiveReplacements.end(); + } + + static void TryApplyPendingReplacements(); + + static bool ShouldLog(uint32_t& uiLastLogTime) + { + const uint32_t uiNow = GetTickCount32(); + if (uiNow - uiLastLogTime < LOG_THROTTLE_INTERVAL_MS) + return false; + + uiLastLogTime = uiNow; + return true; + } + + static void MarkIsolationDenied() + { + ++g_uiIsolationDeniedSerial; + if (g_uiIsolationDeniedSerial == 0) + ++g_uiIsolationDeniedSerial; + } + + static bool WasIsolationDenied(uint32_t uiStartSerial) + { + return g_uiIsolationDeniedSerial != uiStartSerial; + } + + static bool TryGetIsolatedModelIdByTxd(unsigned short usTxdId, unsigned short& usModelId) + { + std::unordered_map::iterator itOwner = g_IsolatedModelByTxd.find(usTxdId); + if (itOwner != g_IsolatedModelByTxd.end()) + { + usModelId = itOwner->second; + return true; + } + + for (const auto& pair : g_IsolatedTxdByModel) + { + if (pair.second.usTxdId == usTxdId) + { + usModelId = pair.first; + g_IsolatedModelByTxd[usTxdId] = usModelId; + return true; + } + } + + return false; + } + + // Returns usage percentage of the standard-range slots (0 to SA_TXD_POOL_CAPACITY-1) + // that isolation can actually use. + static int GetTxdPoolUsagePercent() + { + if (g_iCachedUsedSlots < 0) + return 0; + + return (g_iCachedUsedSlots * 100) / CTxdPoolSA::SA_TXD_POOL_CAPACITY; + } + + static void UpdateIsolatedTxdLastUse(unsigned short usModelId) + { + g_IsolatedTxdLastUseTime[usModelId] = GetTickCount32(); + } + + static void ClearIsolatedTxdLastUse(unsigned short usModelId) + { + g_IsolatedTxdLastUseTime.erase(usModelId); + } + + // Mark an isolated slot for early stale reclamation by zeroing its last-use + // time. (now - 0) always exceeds any stale timeout, so the slot will be + // picked up on the next TryReclaimStaleIsolatedSlots pass. + // Called when all replacement tracking is removed from a TXD but the slot + // could not be freed (e.g. leaked texture refs prevent destruction). + static void MarkIsolatedSlotReadyForReclamation(unsigned short usTxdId) + { + auto itOwner = g_IsolatedModelByTxd.find(usTxdId); + if (itOwner == g_IsolatedModelByTxd.end()) + return; + + const unsigned short usModelId = itOwner->second; + if (g_IsolatedTxdByModel.count(usModelId) == 0) + return; + + g_IsolatedTxdLastUseTime[usModelId] = 0; + } + + // Reclaim isolated TXD slots unused for ISOLATION_STALE_TIMEOUT_MS under pool pressure + static void TryReclaimStaleIsolatedSlots() + { + if (!pGame) + return; + + const uint32_t uiNow = GetTickCount32(); + if (uiNow - g_uiLastStaleCleanupTime < STALE_CLEANUP_INTERVAL_MS) + return; + + g_uiLastStaleCleanupTime = uiNow; + + const int iUsagePercent = GetTxdPoolUsagePercent(); + if (iUsagePercent < TXD_POOL_PROACTIVE_CLEANUP_PERCENT) + return; // No pressure yet, skip proactive cleanup + + // Find isolated TXDs that haven't been used recently + std::vector vecStaleModels; + for (const auto& entry : g_IsolatedTxdByModel) + { + const unsigned short usModelId = entry.first; + const unsigned short usTxdId = entry.second.usTxdId; + + // Skip if already marked for orphan cleanup + if (g_OrphanedIsolatedTxdSlots.count(usTxdId) > 0) + continue; + + auto itLastUse = g_IsolatedTxdLastUseTime.find(usModelId); + if (itLastUse == g_IsolatedTxdLastUseTime.end()) + continue; // No tracking entry yet; protect new isolations + + // Stale timeout: shorter under higher pool pressure + uint32_t uiStaleTimeout = ISOLATION_STALE_TIMEOUT_MS; + if (iUsagePercent >= TXD_POOL_AGGRESSIVE_CLEANUP_PERCENT) + uiStaleTimeout = ISOLATION_STALE_TIMEOUT_MS / 3; + else if (iUsagePercent >= TXD_POOL_MEDIUM_PRESSURE_PERCENT) + uiStaleTimeout = ISOLATION_STALE_TIMEOUT_MS / 2; + + if (uiNow - itLastUse->second >= uiStaleTimeout) + vecStaleModels.push_back(usModelId); + } + + // Batch size: more aggressive cleanup under higher pressure + std::size_t uiMaxToProcess = 4; + if (iUsagePercent >= TXD_POOL_AGGRESSIVE_CLEANUP_PERCENT) { + uiMaxToProcess = 16; + } else if (iUsagePercent >= TXD_POOL_MEDIUM_PRESSURE_PERCENT) { + uiMaxToProcess = 8; +} + + auto* pTxdPoolSA = static_cast(&pGame->GetPools()->GetTxdPool()); + std::size_t uiProcessed = 0; + for (unsigned short usModelId : vecStaleModels) + { + if (uiProcessed >= uiMaxToProcess) + break; + + auto itIsolated = g_IsolatedTxdByModel.find(usModelId); + if (itIsolated == g_IsolatedTxdByModel.end()) + continue; + + const unsigned short usTxdId = itIsolated->second.usTxdId; + + // Verify staleness (model may have been used since we built vecStaleModels) + auto itLastUseRecheck = g_IsolatedTxdLastUseTime.find(usModelId); + if (itLastUseRecheck != g_IsolatedTxdLastUseTime.end()) + { + uint32_t uiStaleTimeoutRecheck = ISOLATION_STALE_TIMEOUT_MS; + if (iUsagePercent >= TXD_POOL_AGGRESSIVE_CLEANUP_PERCENT) + uiStaleTimeoutRecheck = ISOLATION_STALE_TIMEOUT_MS / 3; + else if (iUsagePercent >= TXD_POOL_MEDIUM_PRESSURE_PERCENT) + uiStaleTimeoutRecheck = ISOLATION_STALE_TIMEOUT_MS / 2; + + if (uiNow - itLastUseRecheck->second < uiStaleTimeoutRecheck) + continue; + } + + // Only mark for orphan cleanup if no external refs remain. + // With the MTA ownership pin the minimum expected ref count is 1. + { + const bool bPinned = pTxdPoolSA && pTxdPoolSA->IsSlotProtectedFromStreaming(usTxdId); + const int nPinRefs = bPinned ? 1 : 0; + if (CTxdStore_GetNumRefs(usTxdId) > nPinRefs) + continue; + } + + auto itInfo = ms_ModelTexturesInfoMap.find(usTxdId); + if (itInfo != ms_ModelTexturesInfoMap.end()) + { + if (itInfo->second.bReapplyingTextures || !itInfo->second.usedByReplacements.empty()) + continue; + } + + // Don't reclaim if replacements are queued but not yet applied + if (g_PendingReplacementByModel.count(usModelId) > 0) + continue; + + const unsigned short usParentTxdId = itIsolated->second.usParentTxdId; + + auto* pModelInfo = static_cast(pGame->GetModelInfo(usModelId)); + + // Parent TXD data may not be in memory (SA streamed it out). + // If the model has loaded geometry, we can't rebind textures + // without the parent data. But unloaded models hold zero TXD + // refs, so reassigning usTextureDictionary is a safe field-only + // change - SA will resolve textures when both are streamed in. + if (!CTxdStore_GetTxd(usParentTxdId)) + { + if (pTxdPoolSA->IsFreeTextureDictonarySlot(usParentTxdId)) + continue; // Parent slot freed entirely, can't reassign + + CBaseModelInfoSAInterface* pInterface = pModelInfo ? pModelInfo->GetInterface() : nullptr; + if (pInterface && pInterface->pRwObject) + continue; // Model has geometry, rebind needs parent data + } + + if (pModelInfo && pModelInfo->GetTextureDictionaryID() == usTxdId) + { + if (!TryRestoreAndSwitchModelToTxd(pModelInfo, usModelId, usTxdId, usParentTxdId)) + continue; + } + + // Clean tracking entry before orphaning to prevent stale lookups + ms_ModelTexturesInfoMap.erase(usTxdId); + + g_IsolatedModelByTxd.erase(usTxdId); + CTxdStore_RemoveRef(usParentTxdId); // Release parent pin + g_IsolatedTxdByModel.erase(itIsolated); + ClearPendingIsolatedModel(usModelId); + ClearPendingReplacementStateForModel(usModelId); + g_PendingReplacementByModel.erase(usModelId); + + g_OrphanedIsolatedTxdSlots.insert(usTxdId); + ClearIsolatedTxdLastUse(usModelId); + ++uiProcessed; + + if (ShouldLog(g_uiLastOrphanLogTime)) + { + AddReportLog(9402, SString("TryReclaimStaleIsolatedSlots: Reclaimed stale isolation for model %u (TXD %u -> parent %u, pool %d%%)", usModelId, + usTxdId, usParentTxdId, iUsagePercent)); + } + } + } + + // bForced: bypass interval check when under high pool pressure + static void TryCleanupOrphanedIsolatedSlots(bool bForced = false) + { + if (!pGame) + return; + + if (g_OrphanedIsolatedTxdSlots.empty()) + return; + + const uint32_t uiNow = GetTickCount32(); + + if (!bForced) + { + if (uiNow - g_uiLastOrphanCleanupTime < ORPHAN_CLEANUP_INTERVAL_MS) + return; + } + + g_uiLastOrphanCleanupTime = uiNow; + + CTxdPool* pTxdPool = &pGame->GetPools()->GetTxdPool(); + CTxdPoolSA* pTxdPoolSA = static_cast(pTxdPool); + if (!pTxdPoolSA) + return; + + std::vector vecSlotsToRemove; + vecSlotsToRemove.reserve(g_OrphanedIsolatedTxdSlots.size()); + + for (unsigned short usTxdId : g_OrphanedIsolatedTxdSlots) + { + // If the slot has an MTA ownership pin (from ProtectSlotFromStreaming / + // AddRef at creation), the minimum expected ref count is 1 - just the + // pin. For un-pinned legacy slots the threshold is 0. + const bool bPinned = pTxdPoolSA->IsSlotProtectedFromStreaming(usTxdId); + const short nPinRefs = bPinned ? 1 : 0; + if (CTxdStore_GetNumRefs(usTxdId) > nPinRefs) + continue; + + std::map::iterator itInfo = ms_ModelTexturesInfoMap.find(usTxdId); + if (itInfo != ms_ModelTexturesInfoMap.end()) + { + if (itInfo->second.bReapplyingTextures || !itInfo->second.usedByReplacements.empty()) + continue; + } + + unsigned short usModelId = 0; + if (TryGetIsolatedModelIdByTxd(usTxdId, usModelId)) + continue; + + RwTexDictionary* pTxd = CTxdStore_GetTxd(usTxdId); + if (pTxd) + { + const bool bOrphanedAll = OrphanTxdTexturesBounded(pTxd, true); + if (!bOrphanedAll) + continue; + } + + RemoveTxdFromReplacementTracking(usTxdId); + + if (IsStreamingInfoSlot(usTxdId)) + ResetStreamingInfo(usTxdId); + + CRenderWareSA* pRenderWareSA = pGame->GetRenderWareSA(); + if (pRenderWareSA) + pRenderWareSA->StreamingRemovedTxd(usTxdId); + + InvalidateTxdTextureMapCache(usTxdId); + + // Release the MTA ownership pin that kept SA's streaming from + // evicting this slot while textures were still tracked. The + // hook guard (g_StreamingProtectedTxdSlots) prevents the + // resulting ref-count-0 from triggering CStreaming::RemoveModel + // — only the explicit RemoveTextureDictonarySlot below will + // call SA's RemoveTxd. + if (bPinned) + CTxdStore_RemoveRef(usTxdId); + + pTxdPoolSA->RemoveTextureDictonarySlot(usTxdId); + g_IsolatedModelByTxd.erase(usTxdId); + for (auto itModel = g_IsolatedTxdByModel.begin(); itModel != g_IsolatedTxdByModel.end();) + { + if (itModel->second.usTxdId == usTxdId) + { + ClearPendingIsolatedModel(itModel->first); + ClearIsolatedTxdLastUse(itModel->first); + ClearPendingReplacementStateForModel(itModel->first); + g_PendingReplacementByModel.erase(itModel->first); + CTxdStore_RemoveRef(itModel->second.usParentTxdId); // Release parent pin + itModel = g_IsolatedTxdByModel.erase(itModel); + } + else + { + ++itModel; + } + } + MarkTxdPoolCountDirty(); + vecSlotsToRemove.push_back(usTxdId); + } + + for (unsigned short usTxdId : vecSlotsToRemove) + { + g_OrphanedIsolatedTxdSlots.erase(usTxdId); + } + } + + template + void ClearAllShaderRegs(Fn&& fn) + { + for (const auto& entry : g_ShaderRegs) + { + for (CD3DDUMMY* pD3D : entry.second) + { + fn(entry.first.usTxdId, pD3D); + } + } + g_ShaderRegs.clear(); + } + + SString BuildReplacementTag(const SReplacementTextures* pReplacement) + { + if (!pReplacement) + return ""; + + if (!pReplacement->strDebugName.empty() && !pReplacement->strDebugHash.empty()) + return SString("%s [%s]", pReplacement->strDebugName.c_str(), pReplacement->strDebugHash.c_str()); + + if (!pReplacement->strDebugName.empty()) + return pReplacement->strDebugName; + + if (!pReplacement->strDebugHash.empty()) + return pReplacement->strDebugHash; + + return ""; + } + + struct SScriptManagedTxdUsage + { + bool bHasOtherUsers = false; + bool bHasIncompatibleUsers = false; + std::vector otherUserModelIds; + }; + + static std::string CopyTextureNameForCompare(const char* szTextureName) + { + if (!szTextureName) + return std::string(); + + const std::size_t nameLen = strnlen(szTextureName, RW_TEXTURE_NAME_LENGTH); + if (nameLen >= RW_TEXTURE_NAME_LENGTH) + return std::string(); + + std::string strTextureName(szTextureName, nameLen); + std::transform(strTextureName.begin(), strTextureName.end(), strTextureName.begin(), + [](unsigned char ch) { return static_cast(std::tolower(ch)); }); + return strTextureName; + } + + static void AddTextureNameVariant(TextureNameSet& names, const char* szTextureName) + { + const std::string strTextureName = CopyTextureNameForCompare(szTextureName); + if (!strTextureName.empty()) + names.insert(strTextureName); + } + + static void CollectTextureNameVariants(TextureNameSet& names, const char* szTextureName) + { + AddTextureNameVariant(names, szTextureName); + + const std::string strTextureName = CopyTextureNameForCompare(szTextureName); + if (strTextureName.empty()) + return; + + AddTextureNameVariant(names, CRenderWareSA::GetInternalTextureName(strTextureName.c_str())); + AddTextureNameVariant(names, CRenderWareSA::GetExternalTextureName(strTextureName.c_str())); + } + + static bool CollectMaterialTextureNamesFromGeometry(TextureNameSet& names, RpGeometry* pGeometry) + { + if (!pGeometry || !pGeometry->materials.materials || pGeometry->materials.entries <= 0) + return true; + + constexpr int kMaxMaterials = 10000; + if (pGeometry->materials.entries > kMaxMaterials) + return false; + + for (int i = 0; i < pGeometry->materials.entries; ++i) + { + RpMaterial* pMaterial = pGeometry->materials.materials[i]; + if (!pMaterial || !pMaterial->texture) + continue; + + CollectTextureNameVariants(names, pMaterial->texture->name); + } + + return true; + } + + static RwObject* __cdecl CollectMaterialTextureNamesFromFrameObjectCB(RwObject* pObject, void* data) + { + if (pObject && pObject->type == RP_TYPE_ATOMIC) + { + RpAtomic* pAtomic = reinterpret_cast(pObject); + if (pAtomic->clump == nullptr && pAtomic->geometry) + { + auto* pNames = static_cast(data); + CollectMaterialTextureNamesFromGeometry(*pNames, pAtomic->geometry); + } + } + + return pObject; + } + + static bool CollectMaterialTextureNamesFromFrameHierarchy(TextureNameSet& names, RwFrame* pFrame, std::vector& visitedFrames, int depth = 0) + { + if (!pFrame) + return true; + + if (depth > 128) + return false; + + for (RwFrame* pVisited : visitedFrames) + { + if (pVisited == pFrame) + return true; + } + visitedFrames.push_back(pFrame); + + RwFrameForAllObjects(pFrame, reinterpret_cast(CollectMaterialTextureNamesFromFrameObjectCB), &names); + + if (!pFrame->child) + return true; + + RwFrame* pChild = pFrame->child; + int nChildren = 0; + while (pChild) + { + if (!CollectMaterialTextureNamesFromFrameHierarchy(names, pChild, visitedFrames, depth + 1)) + return false; + + pChild = pChild->next; + if (++nChildren > 1024) + return false; + } + + return true; + } + + static bool CollectModelMaterialTextureNames(TextureNameSet& names, unsigned short usModelId) + { + names.clear(); + + if (!pGame) + return false; + + auto* pModelInfo = static_cast(pGame->GetModelInfo(usModelId)); + if (!pModelInfo) + return false; + + RwObject* pRwObject = pModelInfo->GetRwObject(); + if (!pRwObject) + return false; + + const eModelInfoType modelType = pModelInfo->GetModelType(); + if (modelType == eModelInfoType::PED || modelType == eModelInfoType::WEAPON || modelType == eModelInfoType::VEHICLE || + modelType == eModelInfoType::CLUMP || (modelType == eModelInfoType::UNKNOWN && pRwObject->type == RP_TYPE_CLUMP)) + { + RpClump* pClump = reinterpret_cast(pRwObject); + std::vector atomicList; + CRenderWareSA::GetClumpAtomicList(pClump, atomicList); + + for (RpAtomic* pAtomic : atomicList) + { + if (!CollectMaterialTextureNamesFromGeometry(names, pAtomic ? pAtomic->geometry : nullptr)) + return false; + } + + if (RwFrame* pRootFrame = reinterpret_cast(pClump->object.parent)) + { + std::vector visitedFrames; + if (!CollectMaterialTextureNamesFromFrameHierarchy(names, pRootFrame, visitedFrames)) + return false; + } + + return true; + } + + if (modelType == eModelInfoType::ATOMIC || modelType == eModelInfoType::LOD_ATOMIC || modelType == eModelInfoType::TIME || + (modelType == eModelInfoType::UNKNOWN && pRwObject->type == RP_TYPE_ATOMIC)) + { + RpAtomic* pAtomic = reinterpret_cast(pRwObject); + return CollectMaterialTextureNamesFromGeometry(names, pAtomic ? pAtomic->geometry : nullptr); + } + + return false; + } + + static void CollectReplacementTextureNames(TextureNameSet& names, const SReplacementTextures* pReplacement) + { + names.clear(); + + if (!pReplacement) + return; + + for (RwTexture* pTexture : pReplacement->textures) + CollectTextureNameVariants(names, pTexture ? pTexture->name : nullptr); + } + + static void CollectPerTxdUsingTextureNames(TextureNameSet& names, const SReplacementTextures* pReplacement, unsigned short usTxdId) + { + names.clear(); + + if (!pReplacement) + return; + + auto itPerTxd = std::find_if(pReplacement->perTxdList.begin(), pReplacement->perTxdList.end(), + [usTxdId](const SReplacementTextures::SPerTxd& entry) { return entry.usTxdId == usTxdId; }); + if (itPerTxd == pReplacement->perTxdList.end()) + return; + + for (RwTexture* pTexture : itPerTxd->usingTextures) + CollectTextureNameVariants(names, pTexture ? pTexture->name : nullptr); + } + + static bool HasTextureNameIntersection(const TextureNameSet& leftNames, const TextureNameSet& rightNames) + { + if (leftNames.empty() || rightNames.empty()) + return false; + + const TextureNameSet* pSmallerSet = &leftNames; + const TextureNameSet* pLargerSet = &rightNames; + if (pSmallerSet->size() > pLargerSet->size()) + std::swap(pSmallerSet, pLargerSet); + + for (const std::string& strName : *pSmallerSet) + { + if (pLargerSet->count(strName) != 0) + return true; + } + + return false; + } + + static bool HasScriptManagedTxdConflict(const SReplacementTextures* pNewReplacement, unsigned short usModelId, unsigned short usTxdId, + unsigned short usParentTxdId, const SScriptManagedTxdUsage& scriptTxdUsage) + { + if (scriptTxdUsage.bHasIncompatibleUsers || !scriptTxdUsage.bHasOtherUsers) + return scriptTxdUsage.bHasIncompatibleUsers; + + TextureNameSet newTexNames; + TextureNameSet modelTexNames; + CollectReplacementTextureNames(newTexNames, pNewReplacement); + if (!CollectModelMaterialTextureNames(modelTexNames, usModelId)) + return true; + + auto itScriptTexInfo = ms_ModelTexturesInfoMap.find(usTxdId); + if (itScriptTexInfo == ms_ModelTexturesInfoMap.end()) + return false; + + for (unsigned short usOtherModelId : scriptTxdUsage.otherUserModelIds) + { + TextureNameSet otherMatNames; + if (!CollectModelMaterialTextureNames(otherMatNames, usOtherModelId)) + return true; + + if (HasTextureNameIntersection(newTexNames, otherMatNames)) + return true; + + for (SReplacementTextures* pExisting : itScriptTexInfo->second.usedByReplacements) + { + if (!pExisting || pExisting == pNewReplacement) + continue; + + bool bUsedByOther = false; + for (unsigned short usExistingModelId : pExisting->usedInModelIds) + { + if (usExistingModelId == usOtherModelId) + { + bUsedByOther = true; + break; + } + } + + if (!bUsedByOther) + continue; + + TextureNameSet otherTexNames; + CollectReplacementTextureNames(otherTexNames, pExisting); + if (HasTextureNameIntersection(otherTexNames, modelTexNames)) + return true; + } + } + + // Check replacements whose models no longer point at this TXD. + // The textures are still in the dictionary and will affect any + // model that reuses it. + for (SReplacementTextures* pExisting : itScriptTexInfo->second.usedByReplacements) + { + if (!pExisting || pExisting == pNewReplacement) + continue; + + bool bHasOtherModel = false; + bool bStillOnTxd = false; + for (unsigned short usExistingModelId : pExisting->usedInModelIds) + { + if (usExistingModelId == usModelId) + continue; + + bHasOtherModel = true; + + auto* pExistingModelInfo = static_cast(pGame->GetModelInfo(usExistingModelId)); + if (pExistingModelInfo && pExistingModelInfo->GetTextureDictionaryID() == usTxdId) + { + bStillOnTxd = true; + break; + } + } + + if (!bHasOtherModel || bStillOnTxd) + continue; + + TextureNameSet perTxdNames; + CollectPerTxdUsingTextureNames(perTxdNames, pExisting, usTxdId); + if (HasTextureNameIntersection(perTxdNames, modelTexNames)) + return true; + } + + return false; + } + + static SScriptManagedTxdUsage GetScriptManagedTxdUsage(unsigned short usModelId, unsigned short usTxdId, unsigned short usParentTxdId) + { + SScriptManagedTxdUsage usage; + + if (!pGame) + return usage; + + const std::vector& modelsOnTxd = GetModelsForTxd(usTxdId); + + for (unsigned short usOtherModelId : modelsOnTxd) + { + if (usOtherModelId == usModelId) + continue; + + auto* pOtherModelInfo = static_cast(pGame->GetModelInfo(usOtherModelId)); + if (!pOtherModelInfo) + continue; + + if (pOtherModelInfo->GetTextureDictionaryID() != usTxdId) + continue; + + usage.bHasOtherUsers = true; + + const unsigned int uiOtherParentModelId = pOtherModelInfo->GetParentID(); + if (uiOtherParentModelId == 0) + { + usage.bHasIncompatibleUsers = true; + usage.otherUserModelIds.clear(); + break; + } + + auto* pOtherParentInfo = static_cast(pGame->GetModelInfo(uiOtherParentModelId)); + const unsigned short usOtherParentTxdId = pOtherParentInfo ? pOtherParentInfo->GetTextureDictionaryID() : 0; + if (!pOtherParentInfo || usOtherParentTxdId != usParentTxdId) + { + usage.bHasIncompatibleUsers = true; + usage.otherUserModelIds.clear(); + break; + } + + usage.otherUserModelIds.push_back(usOtherModelId); + } + + return usage; + } + + static bool IsReadableTexture(RwTexture* pTexture) + { + if (!pTexture) + return false; + + if (!pTexture->raster) + return false; + + return true; + } + + static CStreamingInfo* GetStreamingInfoSafe(unsigned int uiStreamId) + { + if (!pGame) + return nullptr; + + const int iCountOfAllFileIds = pGame->GetCountOfAllFileIDs(); + if (iCountOfAllFileIds <= 0) + return nullptr; + + if (uiStreamId >= static_cast(iCountOfAllFileIds)) + return nullptr; + + CStreaming* pStreaming = pGame->GetStreaming(); + if (!pStreaming) + return nullptr; + + return pStreaming->GetStreamingInfo(uiStreamId); + } + + static void UnlinkStreamingInfoNeighbors(CStreamingInfo* pStreamInfo) + { + if (!pStreamInfo || !pGame) + return; + + if (pStreamInfo->loadState == eModelLoadState::LOADSTATE_NOT_LOADED) + return; + + CStreaming* pStreaming = pGame->GetStreaming(); + if (!pStreaming) + return; + + constexpr std::uint16_t kInvalidLink = static_cast(-1); + const std::uint16_t prev = pStreamInfo->prevId; + const std::uint16_t next = pStreamInfo->nextId; + + CStreamingInfo* pPrev = (prev != kInvalidLink) ? pStreaming->GetStreamingInfo(prev) : nullptr; + CStreamingInfo* pNext = (next != kInvalidLink) ? pStreaming->GetStreamingInfo(next) : nullptr; + + // If one side already points outside the streaming array, cut the + // reachable side instead of copying the bad link forward. + if (pPrev) + pPrev->nextId = (next == kInvalidLink || pNext) ? next : kInvalidLink; + if (pNext) + pNext->prevId = (prev == kInvalidLink || pPrev) ? prev : kInvalidLink; + } + + // Marks a TXD streaming entry as LOADED, zeroing disc-ref fields. + // Only applies to standard-range slots [0, 5000). Overflow slots [5000, 6316) + // have no dedicated streaming entry (they overlap COL/IPL), so we skip them. + // The GetNextFileOnCd hook in CTxdPoolSA handles DFF dependency checks for + // overflow TXDs by reading the pool directly. + static void SetStreamingInfoLoaded(unsigned short usTxdSlotId) + { + if (!pGame) + return; + + const int32_t baseTxdId = pGame->GetBaseIDforTXD(); + const std::uint32_t streamId = static_cast(usTxdSlotId) + static_cast(baseTxdId); + CStreamingInfo* pStreamInfo = GetStreamingInfoSafe(streamId); + if (!pStreamInfo) + return; + + if (usTxdSlotId < CTxdPoolSA::SA_TXD_POOL_CAPACITY) + { + // Unlink from SA's loaded-entry list before zeroing the link fields. + // Neighbors still reference this slot + UnlinkStreamingInfoNeighbors(pStreamInfo); + + pStreamInfo->prevId = static_cast(-1); + pStreamInfo->nextId = static_cast(-1); + pStreamInfo->nextInImg = static_cast(-1); + pStreamInfo->flg = 0; + pStreamInfo->archiveId = INVALID_ARCHIVE_ID; + pStreamInfo->offsetInBlocks = 0; + pStreamInfo->sizeInBlocks = 0; + pStreamInfo->loadState = eModelLoadState::LOADSTATE_LOADED; + } + // Overflow slots [5000, 6316): do NOT touch - streaming entry belongs to COL/IPL. + // The CTxdPoolSA ASM hooks always report LOADED for overflow slots. + } + + // Resets a TXD streaming entry when isolation is cleaned up. + // Standard-range slots: zeroes disc refs and sets NOT_LOADED. + // Overflow slots: no-op - we never modified their streaming entries. + static void ResetStreamingInfo(unsigned short usTxdSlotId) + { + if (!pGame) + return; + + const int32_t baseTxdId = pGame->GetBaseIDforTXD(); + const std::uint32_t streamId = static_cast(usTxdSlotId) + static_cast(baseTxdId); + CStreamingInfo* pStreamInfo = GetStreamingInfoSafe(streamId); + if (!pStreamInfo) + return; + + if (usTxdSlotId < CTxdPoolSA::SA_TXD_POOL_CAPACITY) + { + // Use CStreaming::RemoveModel to properly unlink from SA's + // streaming loaded doubly-linked list. Manually zeroing + // prevId/nextId corrupts the list because neighbours still + // point to this entry, causing crashes when SA walks it. + if (pStreamInfo->loadState != eModelLoadState::LOADSTATE_NOT_LOADED && pGame->GetStreaming()) + { + pGame->GetStreaming()->RemoveModel(streamId); + + // RemoveTxd (called internally by RemoveModel) doesn't + // reset parentIndex. Clear it so RemoveTextureDictonarySlot + // (which also calls RemoveTxd) won't double-decrement + // the parent's usUsagesCount. + auto* pTxdPool = static_cast(&pGame->GetPools()->GetTxdPool()); + if (auto* pEntry = pTxdPool->GetTextureDictonarySlot(usTxdSlotId)) + pEntry->usParentIndex = static_cast(-1); + } + + // Clear remaining informational fields not handled by RemoveModel + pStreamInfo->nextInImg = static_cast(-1); + pStreamInfo->flg = 0; + pStreamInfo->archiveId = INVALID_ARCHIVE_ID; + pStreamInfo->offsetInBlocks = 0; + pStreamInfo->sizeInBlocks = 0; + } + // Overflow slots: nothing to restore - we never modified their streaming entries. + } + + // Marks a leaked TXD slot's streaming entry as LOADED so SA doesn't try to re-stream. + // Standard-range: zeroes disc refs and sets LOADED. + // Overflow: no-op - the GetNextFileOnCd hook handles dependency checks directly. + static void SetStreamingInfoLeaked(unsigned short usTxdSlotId) + { + if (!pGame) + return; + + const int32_t baseTxdId = pGame->GetBaseIDforTXD(); + const std::uint32_t streamId = static_cast(usTxdSlotId) + static_cast(baseTxdId); + CStreamingInfo* pStreamInfo = GetStreamingInfoSafe(streamId); + if (!pStreamInfo) + return; + + if (usTxdSlotId < CTxdPoolSA::SA_TXD_POOL_CAPACITY) + { + // SA's streaming I/O completion can re-insert this entry into the + // loaded list after MTA set its link fields to -1. Unlink before + // zeroing the link fields, or neighbors retain dangling pointers + // to this slot and corrupt list traversal. + // Must NOT call RemoveModel: that triggers RemoveTxd which + // destroys the RW dictionary - but leaked slots still have + // live textures or external refs that must stay alive. + UnlinkStreamingInfoNeighbors(pStreamInfo); + pStreamInfo->prevId = static_cast(-1); + pStreamInfo->nextId = static_cast(-1); + pStreamInfo->nextInImg = static_cast(-1); + pStreamInfo->flg = 0; + pStreamInfo->archiveId = INVALID_ARCHIVE_ID; + pStreamInfo->offsetInBlocks = 0; + pStreamInfo->sizeInBlocks = 0; + pStreamInfo->loadState = eModelLoadState::LOADSTATE_LOADED; + } + // Overflow slots: do NOT touch - streaming entry belongs to COL/IPL. + } + + // Returns true if this TXD slot has a dedicated streaming entry in ms_aInfoForModel + // that MTA can safely read/write. Standard-range [0, 5000) have their own entries. + // Overflow [5000, 6316) overlap COL/IPL/etc - we must NOT treat them as ours. + // Slots >= 6316 have no entry at all. + static bool IsStreamingInfoSlot(unsigned short usTxdSlotId) + { + return usTxdSlotId < CTxdPoolSA::SA_TXD_POOL_CAPACITY; + } + + // Cancel any SA streaming operation for this TXD slot before MTA takes + // ownership. SA may have queued a load request whose pool allocation + // hasn't happened yet (pool slot is empty but streaming info is active). + // Without cancellation, ProcessLoadingChannel would later load SA's data + // into the slot MTA now owns, adding it to the loaded list behind MTA's + // back and corrupting the linked list on cleanup. + static void CancelPendingStreamingForSlot(unsigned short usTxdSlotId) + { + if (!pGame || !pGame->GetStreaming()) + return; + + if (!IsStreamingInfoSlot(usTxdSlotId)) + return; + + const int32_t baseTxdId = pGame->GetBaseIDforTXD(); + const std::uint32_t streamId = static_cast(usTxdSlotId) + static_cast(baseTxdId); + CStreamingInfo* pStreamInfo = GetStreamingInfoSafe(streamId); + if (!pStreamInfo) + return; + + // Only cancel pending states (Requested, Reading, Finishing). + // LOADED entries have pool data and RemoveModel would call RemoveTxd + // which crashes on empty pool slots. LOADED + empty pool is an + // inconsistent SA state that can't arise normally; the manual + // unlink in SetStreamingInfoLoaded handles those as a safety net. + if (pStreamInfo->loadState != eModelLoadState::LOADSTATE_NOT_LOADED && pStreamInfo->loadState != eModelLoadState::LOADSTATE_LOADED) + { + pGame->GetStreaming()->RemoveModel(streamId); + } + } + + std::unordered_set MakeTextureSet(const std::vector& textures) + { + return std::unordered_set(textures.begin(), textures.end()); + } + + std::unordered_map MakeRasterMap(const std::vector& textures) + { + std::unordered_map out; + out.reserve(textures.size()); + for (RwTexture* tex : textures) + { + if (!tex || !tex->raster) + continue; + auto it = out.find(tex->raster); + if (it == out.end()) + { + out.emplace(tex->raster, tex); + } + else if (!IsReadableTexture(it->second) && IsReadableTexture(tex)) + { + it->second = tex; + } + } + return out; + } + + RwTexture* FindReadableMasterForRaster(const std::unordered_map& masterRasterMap, const std::vector& masters, + RwRaster* raster) + { + if (!raster) + return nullptr; + + auto it = masterRasterMap.find(raster); + if (it != masterRasterMap.end() && IsReadableTexture(it->second)) + return it->second; + + for (RwTexture* tex : masters) + { + if (!tex || tex->raster != raster) + continue; + + return tex; + } + + return nullptr; + } + + // Capture all TXD textures for restoration, filtering out MTA-injected textures. + // Without filtering, MTA masters/copies still linked in the TXD get recorded as + // "originals," contaminating the baseline used by canProveNoLeaks comparisons. + void PopulateOriginalTextures(CModelTexturesInfo& info, RwTexDictionary* pTxd) + { + info.originalTextures.clear(); + info.originalTexturesByName.clear(); + + if (!pTxd) + return; + + std::vector allTextures; + CRenderWareSA::GetTxdTextures(allTextures, pTxd); + + // Build a set of rasters owned by known MTA textures for fast filtering. + // Both masters and copies share the same raster, so a raster-level check + // catches both without needing separate copy tracking. + // + // Additive changes (register, leak, orphan) insert into the cache directly. + // Subtractive changes (unregister, raster null, erase) bump the generation + // counter, triggering a full rebuild here on the next call. + if (g_uiGlobalMtaRasterCacheGeneration != g_uiGlobalMtaRasterGeneration) + { + g_GlobalMtaRasterCache.clear(); + + for (RwTexture* pMaster : g_LeakedMasterTextures) + { + if (pMaster && pMaster->raster) + g_GlobalMtaRasterCache.insert(pMaster->raster); + } + + for (const SReplacementTextures* pReplacement : g_ActiveReplacements) + { + if (!pReplacement) + continue; + for (RwTexture* pMasterTex : pReplacement->textures) + { + if (pMasterTex && pMasterTex->raster) + g_GlobalMtaRasterCache.insert(pMasterTex->raster); + } + } + + for (RwRaster* pKeptRaster : g_OrphanedCopyRasters) + g_GlobalMtaRasterCache.insert(pKeptRaster); + + g_uiGlobalMtaRasterCacheGeneration = g_uiGlobalMtaRasterGeneration; + } + + for (RwTexture* pTex : allTextures) + { + if (!IsReadableTexture(pTex)) + continue; + + // Reject textures whose raster belongs to an MTA master or copy + if (!g_GlobalMtaRasterCache.empty() && g_GlobalMtaRasterCache.count(pTex->raster) != 0) + continue; + + info.originalTextures.insert(pTex); + } + + // Build name map for lookup after replacements + for (RwTexture* pTex : info.originalTextures) + { + if (!IsReadableTexture(pTex)) + continue; + + const std::size_t nameLen = strnlen(pTex->name, RW_TEXTURE_NAME_LENGTH); + if (nameLen >= RW_TEXTURE_NAME_LENGTH) + continue; + + info.originalTexturesByName[LowercaseTextureName(pTex->name, nameLen)] = pTex; + } + } + + constexpr uint32_t MAX_VRAM_SIZE = 0x7FFFFFFF; + constexpr uint32_t MAX_TEXTURE_DIMENSION = 0x80000000; + + // Properly unlink texture from TXD to prevent list corruption + void SafeOrphanTexture(RwTexture* pTexture, unsigned short usTxdIdHint) + { + if (!pTexture) + return; + + RwTexDictionary* pCurrentTxd = pTexture->txd; + if (pCurrentTxd) + { + CRenderWareSA::RwTexDictionaryRemoveTexture(pCurrentTxd, pTexture); + + // Invalidate texture map cache since TXD contents changed + if (usTxdIdHint != 0xFFFF) { + InvalidateTxdTextureMapCache(usTxdIdHint); + } else { + ClearTxdTextureMapCache(); +} + + pTexture->TXDList.next = &pTexture->TXDList; + pTexture->TXDList.prev = &pTexture->TXDList; + pTexture->txd = nullptr; + } + else + { + RwListEntry* pNext = pTexture->TXDList.next; + RwListEntry* pPrev = pTexture->TXDList.prev; + + if (pNext && pPrev && pNext != &pTexture->TXDList && pPrev != &pTexture->TXDList && pNext->prev == &pTexture->TXDList && + pPrev->next == &pTexture->TXDList) + { + pPrev->next = pNext; + pNext->prev = pPrev; + } + + pTexture->TXDList.next = &pTexture->TXDList; + pTexture->TXDList.prev = &pTexture->TXDList; + } + } + + bool CanDestroyOrphanedTexture(RwTexture* pTexture); + + // Destroy copy texture (shares raster with master) - does NOT free raster + void SafeDestroyTexture(RwTexture* pTexture) + { + if (!pTexture) + return; + + if (!CanDestroyOrphanedTexture(pTexture)) + return; + + // If this is the final reference, RwTextureDestroy will attempt to free the raster. + // We only clear it if refs <= 1. If refs > 1, the struct won't be freed anyway, so clearing + // the raster just needlessly breaks any other materials still keeping this copy alive. + if (pTexture->refs <= 1) + { + reinterpret_cast(pTexture->raster) = nullptr; + } + + RwTextureDestroy(pTexture); + } + + // Destroy texture AND its raster safely. Releases D3D texture first, then frees structs. + void SafeDestroyTextureWithRaster(RwTexture* pTexture) + { + if (!pTexture) + return; + + if (!CanDestroyOrphanedTexture(pTexture)) + return; + + RwRaster* pRaster = pTexture->raster; + + // If raster is shared with an orphaned copy, don't release it + if (pRaster && g_OrphanedCopyRasters.count(pRaster)) + { + SafeDestroyTexture(pTexture); + return; + } + + if (pRaster) + { + // Release D3D texture before destroying to prevent double-free on shared rasters + void* pD3DRaw = pRaster->renderResource; + if (pD3DRaw) + { + if (g_ReleasedD3DTextures.find(pD3DRaw) == g_ReleasedD3DTextures.end()) + { + if (void* pReleased = TryReleaseTextureD3D(pTexture)) + g_ReleasedD3DTextures.insert(pReleased); + } + reinterpret_cast(pRaster->renderResource) = nullptr; + } + } + + RwTextureDestroy(pTexture); + } + + bool CanDestroyOrphanedTexture(RwTexture* pTexture) + { + if (!pTexture) + return false; + + if (pTexture->txd != nullptr) + return false; + + if (pTexture->TXDList.next != &pTexture->TXDList || pTexture->TXDList.prev != &pTexture->TXDList) + return false; + + constexpr int MAX_REFS = 10000; + if (pTexture->refs < 0 || pTexture->refs > MAX_REFS) + return false; + + return true; + } + + // Fast name->texture map builder. Returns true if the full list was walked, + // false if the walk bailed early (corrupt list, limit hit, null node). + // Callers that cache the result must not cache incomplete maps. + bool BuildTxdTextureMapFast(RwTexDictionary* pTxd, TxdTextureMap& outMap) + { + if (!pTxd) + return false; + + RwListEntry* const pRoot = &pTxd->textures.root; + RwListEntry* pNode = pRoot->next; + + if (pNode == nullptr || pNode == pRoot) + return true; + + if (outMap.empty()) + outMap.reserve(32); + + constexpr std::size_t kMaxTextures = 8192; + std::size_t count = 0; + + while (pNode != pRoot) + { + if (++count > kMaxTextures) + return false; + + RwTexture* pTex = reinterpret_cast(reinterpret_cast(pNode) - offsetof(RwTexture, TXDList)); + if (!pTex) + return false; + + if (strnlen(pTex->name, RW_TEXTURE_NAME_LENGTH) < RW_TEXTURE_NAME_LENGTH) + outMap[pTex->name] = pTex; + + pNode = pNode->next; + if (!pNode) + return false; + } + + return true; + } + + RwTexDictionary* GetVehicleTxd() + { + RwTexDictionary** pp = reinterpret_cast(0xB4E688); + if (!pp) + return nullptr; + RwTexDictionary* pTxd = *pp; + return pTxd; + } + + void AddVehicleTxdFallback(TxdTextureMap& outMap) + { + RwTexDictionary* pVehicleTxd = GetVehicleTxd(); + if (!pVehicleTxd) + return; + + // Check TXD pointer, texture list head and tail. + // Streaming can destroy and reload a TXD at the same address (pool/allocator reuse), + // which leaves the cache with dangling texture name pointers. + RwListEntry* pListHead = pVehicleTxd->textures.root.next; + RwListEntry* pListTail = pVehicleTxd->textures.root.prev; + RwTexture* pFirstTex = nullptr; + if (pListHead && pListHead != &pVehicleTxd->textures.root) + pFirstTex = (RwTexture*)((char*)pListHead - offsetof(RwTexture, TXDList)); + + bool bInvalidate = (pVehicleTxd != g_pCachedVehicleTxd || pListHead != g_pCachedVehicleTxdListHead || pListTail != g_pCachedVehicleTxdListTail); + + if (!bInvalidate && pFirstTex && !g_CachedVehicleTxdMap.empty()) + { + auto it = g_CachedVehicleTxdMap.find(pFirstTex->name); + if (it == g_CachedVehicleTxdMap.end() || it->second != pFirstTex) + { + bInvalidate = true; + } + } + + if (bInvalidate) + { + g_CachedVehicleTxdMap.clear(); + g_pCachedVehicleTxd = pVehicleTxd; + g_pCachedVehicleTxdListHead = pListHead; + g_pCachedVehicleTxdListTail = pListTail; + g_usVehicleTxdSlotId = 0xFFFF; + if (!BuildTxdTextureMapFast(pVehicleTxd, g_CachedVehicleTxdMap)) + { + // Incomplete build - use what we have but don't keep caching it + g_pCachedVehicleTxd = nullptr; + AddReportLog(9401, "BuildTxdTextureMapFast: partial walk for vehicle TXD, cache disabled"); + } + } + + for (const auto& entry : g_CachedVehicleTxdMap) + outMap.emplace(entry.first, entry.second); + } + + static bool EnsureTxdParentLink(unsigned short usChildTxdId, unsigned short usExpectedParentTxdId, bool* pbParentLinkWasRepaired = nullptr) + { + if (pbParentLinkWasRepaired) + *pbParentLinkWasRepaired = false; + + RwTexDictionary* pChildTxd = CTxdStore_GetTxd(usChildTxdId); + RwTexDictionary* pParentTxd = CTxdStore_GetTxd(usExpectedParentTxdId); + if (!pChildTxd || !pParentTxd) + return false; + + using SetTxdParent_t = void(__cdecl*)(RwTexDictionary*, RwTexDictionary*); + using GetTxdParent_t = RwTexDictionary*(__cdecl*)(RwTexDictionary*); + const SetTxdParent_t SetTxdParent = reinterpret_cast(FUNC_CTxdStore__SetTxdParent); + const GetTxdParent_t GetTxdParent = reinterpret_cast(FUNC_CTxdStore__GetTxdParent); + + if (GetTxdParent(pChildTxd) != pParentTxd) + { + SetTxdParent(pChildTxd, pParentTxd); + if (pbParentLinkWasRepaired) + *pbParentLinkWasRepaired = true; + } + + return GetTxdParent(pChildTxd) == pParentTxd; + } + + // Fast-path: Check if model uses vehicle.txd (vehicles, upgrade components, engineRequestModel clones) + // Returns true if the model's TXD or any parent in its chain includes vehicle.txd + bool TxdChainContainsVehicleTxd(unsigned short usStartTxdSlot) + { + if (!pGame) + return false; + + // Get vehicle.txd for parent chain comparison + RwTexDictionary* pVehicleTxd = GetVehicleTxd(); + if (!pVehicleTxd) + return false; + + // Validate cached vehicle TXD slot ID (TXD may have been reloaded) + if (g_usVehicleTxdSlotId != 0xFFFF) + { + if (CTxdStore_GetTxd(g_usVehicleTxdSlotId) != pVehicleTxd) + g_usVehicleTxdSlotId = 0xFFFF; + } + + // Find vehicle TXD slot by scanning the pool (only if not cached) + if (g_usVehicleTxdSlotId == 0xFFFF) + { + constexpr unsigned short kMaxTxdSlots = CTxdPoolSA::SA_TXD_POOL_CAPACITY; + for (unsigned short i = 0; i < kMaxTxdSlots; ++i) + { + if (CTxdStore_GetTxd(i) == pVehicleTxd) + { + g_usVehicleTxdSlotId = i; + break; + } + } + } + + if (g_usVehicleTxdSlotId == 0xFFFF) + return false; + + CTxdPool* pTxdPool = &pGame->GetPools()->GetTxdPool(); + CTxdPoolSA* pTxdPoolSA = static_cast(pTxdPool); + if (!pTxdPoolSA) + return false; + + constexpr unsigned short kInvalidSlot = 0xFFFF; + constexpr int kMaxDepth = 32; + + unsigned short usSlot = usStartTxdSlot; + for (int depth = 0; depth < kMaxDepth; ++depth) + { + if (usSlot == kInvalidSlot) + return false; + if (usSlot == g_usVehicleTxdSlotId) + return true; + + CTextureDictonarySAInterface* pSlot = pTxdPoolSA->GetTextureDictonarySlot(usSlot); + if (!pSlot) + return false; + + // Prevent infinite loops from cyclic parent chains + const unsigned short usParent = pSlot->usParentIndex; + if (usParent == kInvalidSlot || usParent == usSlot) + { + // If this is a known isolated TXD with a deferred parent link, + // look up the intended parent from our tracking and keep walking. + if (usParent == kInvalidSlot) + { + auto itOwner = g_IsolatedModelByTxd.find(usSlot); + if (itOwner != g_IsolatedModelByTxd.end()) + { + auto itInfo = g_IsolatedTxdByModel.find(itOwner->second); + if (itInfo != g_IsolatedTxdByModel.end() && itInfo->second.usParentTxdId != kInvalidSlot && itInfo->second.usParentTxdId != usSlot) + { + usSlot = itInfo->second.usParentTxdId; + continue; + } + } + } + return false; + } + + usSlot = usParent; + } + return false; + } + + // Fast-path: Check if model uses vehicle.txd (vehicles, upgrade components, engineRequestModel clones) + // Returns true if the model's TXD or any parent in its chain includes vehicle.txd + bool ShouldUseVehicleTxdFallback(unsigned short usModelId) + { + if (!pGame) + return false; + + auto* pModelInfo = static_cast(pGame->GetModelInfo(usModelId)); + if (!pModelInfo) + return false; + + // Vehicles and upgrade components always use vehicle.txd + if (pModelInfo->IsVehicle() || pModelInfo->IsUpgrade()) + return true; + + // Check the model's TXD and walk up parent chain + const unsigned short usModelTxdId = pModelInfo->GetTextureDictionaryID(); + if (TxdChainContainsVehicleTxd(usModelTxdId)) + return true; + + // Also check parent model for engineRequestModel clones + const unsigned int uiParentModelId = pModelInfo->GetParentID(); + if (uiParentModelId != 0) + { + if (auto* pParentModelInfo = static_cast(pGame->GetModelInfo(uiParentModelId))) + { + if (pParentModelInfo->IsVehicle() || pParentModelInfo->IsUpgrade()) + return true; + + const unsigned short usParentTxdId = pParentModelInfo->GetTextureDictionaryID(); + if (TxdChainContainsVehicleTxd(usParentTxdId)) + return true; + } + } + + return false; + } + + void CleanupStalePerTxd(SReplacementTextures::SPerTxd& perTxdInfo, RwTexDictionary* pDeadTxd, SReplacementTextures* pReplacementTextures, + const std::unordered_set* pMasterTextures, std::unordered_set& outCopiesToDestroy, + std::unordered_set& outOriginalsToDestroy, bool bSkipRasterNull = false) + { + const bool bDeadTxdValid = pDeadTxd != nullptr; + + std::unordered_set localMasterTextures; + if (!perTxdInfo.bTexturesAreCopies && pReplacementTextures && !pMasterTextures) + { + localMasterTextures = MakeTextureSet(pReplacementTextures->textures); + pMasterTextures = &localMasterTextures; + } + + bool bAnyRasterNulled = false; + for (RwTexture* pTexture : perTxdInfo.usingTextures) + { + if (!pTexture) + continue; + + bool bNeedsDestruction = false; + if (bDeadTxdValid && pTexture->txd == pDeadTxd) + { + SafeOrphanTexture(pTexture); + bNeedsDestruction = (pTexture->txd == nullptr); + } + else if (!bDeadTxdValid && pTexture->txd == nullptr) + { + SafeOrphanTexture(pTexture); + bNeedsDestruction = true; + } + + // Only null the raster if this is the final reference. If refs > 1, + // a material (like a shared LOD or missed chassis_vlo) is still using this texture. + if (bNeedsDestruction && !bSkipRasterNull && pTexture->refs <= 1) + { + if (pTexture->raster) + bAnyRasterNulled = true; + pTexture->raster = nullptr; + } + + if (bNeedsDestruction && CanDestroyOrphanedTexture(pTexture)) + { + bool bIsActuallyCopy = perTxdInfo.bTexturesAreCopies; + if (!bIsActuallyCopy && pReplacementTextures && pMasterTextures) + { + bIsActuallyCopy = pMasterTextures->find(pTexture) == pMasterTextures->end(); + if (bIsActuallyCopy && g_LeakedMasterTextures.count(pTexture)) + bIsActuallyCopy = false; + } + + if (bIsActuallyCopy) + outCopiesToDestroy.insert(pTexture); + } + } + if (bAnyRasterNulled) + InvalidateGlobalMtaRasterCache(); + perTxdInfo.usingTextures.clear(); + + for (RwTexture* pReplaced : perTxdInfo.replacedOriginals) + { + if (!pReplaced) + continue; + + bool bNeedsDestruction = false; + if (bDeadTxdValid && pReplaced->txd == pDeadTxd) + { + SafeOrphanTexture(pReplaced); + bNeedsDestruction = (pReplaced->txd == nullptr); + } + else if (!bDeadTxdValid && pReplaced->txd == nullptr) + { + SafeOrphanTexture(pReplaced); + bNeedsDestruction = true; + } + + if (bNeedsDestruction && !bSkipRasterNull && pReplaced->refs <= 1) + pReplaced->raster = nullptr; + + if (bNeedsDestruction && CanDestroyOrphanedTexture(pReplaced)) + outOriginalsToDestroy.insert(pReplaced); + } + perTxdInfo.replacedOriginals.clear(); + } + + struct STextureSwapLookup + { + const TextureSwapMap& m_swapMap; + TxdTextureMap m_nameSwapMap; + bool m_bNameMapBuilt = false; + + explicit STextureSwapLookup(const TextureSwapMap& swapMap) : m_swapMap(swapMap) {} + + void AddNameVariant(const char* szTextureName, RwTexture* pReplacement) + { + if (!szTextureName || !pReplacement) + return; + + if (strnlen(szTextureName, RW_TEXTURE_NAME_LENGTH) >= RW_TEXTURE_NAME_LENGTH) + return; + + auto itName = m_nameSwapMap.find(szTextureName); + if (itName == m_nameSwapMap.end()) + { + m_nameSwapMap.emplace(szTextureName, pReplacement); + } + else if (itName->second != pReplacement) + { + itName->second = nullptr; + } + } + + void AddTextureNameVariants(const char* szTextureName, RwTexture* pReplacement) + { + if (!szTextureName || !pReplacement) + return; + + if (strnlen(szTextureName, RW_TEXTURE_NAME_LENGTH) >= RW_TEXTURE_NAME_LENGTH) + return; + + AddNameVariant(szTextureName, pReplacement); + + const char* szInternalName = CRenderWareSA::GetInternalTextureName(szTextureName); + if (szInternalName && strcmp(szInternalName, szTextureName) != 0) + AddNameVariant(szInternalName, pReplacement); + + const char* szExternalName = CRenderWareSA::GetExternalTextureName(szTextureName); + if (szExternalName && strcmp(szExternalName, szTextureName) != 0) + AddNameVariant(szExternalName, pReplacement); + } + + RwTexture* FindReplacementByName(const char* szTextureName, RwTexture* pTexture) const + { + if (!szTextureName) + return nullptr; + + if (strnlen(szTextureName, RW_TEXTURE_NAME_LENGTH) >= RW_TEXTURE_NAME_LENGTH) + return nullptr; + + auto itName = m_nameSwapMap.find(szTextureName); + if (itName == m_nameSwapMap.end() || !itName->second || itName->second == pTexture) + return nullptr; + + return itName->second; + } + + RwTexture* FindReplacement(RwTexture* pTexture) + { + if (!pTexture) + return nullptr; + + auto it = m_swapMap.find(pTexture); + if (it != m_swapMap.end() && it->second) + return it->second; + + if (!m_bNameMapBuilt) + { + if (!m_swapMap.empty()) + m_nameSwapMap.reserve(m_swapMap.size() * TEXTURE_NAME_VARIANT_COUNT); + + for (const auto& entry : m_swapMap) + { + if (!entry.first || !entry.second) + continue; + + AddTextureNameVariants(entry.first->name, entry.second); + } + + m_bNameMapBuilt = true; + } + + if (m_nameSwapMap.empty()) + return nullptr; + + return FindReplacementByName(pTexture->name, pTexture); + } + }; + + void ReplaceTextureInGeometry(RpGeometry* pGeometry, STextureSwapLookup& swapLookup) + { + if (!pGeometry) + return; + + RpMaterials& materials = pGeometry->materials; + if (!materials.materials || materials.entries <= 0) + return; + + constexpr int MAX_MATERIALS = 10000; + int materialCount = materials.entries; + if (materialCount > MAX_MATERIALS) + return; + + for (int idx = 0; idx < materialCount; ++idx) + { + RpMaterial* pMaterial = materials.materials[idx]; + if (!pMaterial) + continue; + + RwTexture* pMatTex = pMaterial->texture; + if (!pMatTex) + continue; + + if (auto* pReplacement = swapLookup.FindReplacement(pMatTex)) + RpMaterialSetTexture(pMaterial, pReplacement); + } + } + + bool __cdecl ReplaceTextureInAtomicCB(RpAtomic* pAtomic, void* userData) + { + if (!pAtomic) + return true; + + auto* pSwapLookup = static_cast(userData); + if (!pSwapLookup) + return true; + + ReplaceTextureInGeometry(pAtomic->geometry, *pSwapLookup); + return true; + } + + RwObject* __cdecl ReplaceTextureInFrameObjectCB(RwObject* pObject, void* data) + { + if (pObject && pObject->type == RP_TYPE_ATOMIC) + { + RpAtomic* pAtomic = reinterpret_cast(pObject); + // Specifically target detached atomics like chassis_vlo that aren't in the clump list + if (pAtomic->clump == nullptr && pAtomic->geometry) + { + auto* pSwapLookup = static_cast(data); + ReplaceTextureInGeometry(pAtomic->geometry, *pSwapLookup); + } + } + return pObject; + } + + void ReplaceTextureInFrameHierarchy(RwFrame* pFrame, STextureSwapLookup& swapLookup, std::vector& visitedFrames, int depth = 0) + { + if (!pFrame) + return; + + if (depth > 128) + { + AddReportLog(9410, SString("ReplaceTextureInFrameHierarchy: depth cap reached (%d)", depth)); + return; + } + + for (RwFrame* pVisited : visitedFrames) + { + if (pVisited == pFrame) + return; + } + visitedFrames.push_back(pFrame); + + RwFrameForAllObjects(pFrame, reinterpret_cast(ReplaceTextureInFrameObjectCB), &swapLookup); + + if (pFrame->child) + { + RwFrame* pChild = pFrame->child; + int nChildren = 0; + while (pChild) + { + ReplaceTextureInFrameHierarchy(pChild, swapLookup, visitedFrames, depth + 1); + pChild = pChild->next; + if (++nChildren > 1024) + { + AddReportLog(9410, SString("ReplaceTextureInFrameHierarchy: child limit hit at depth %d", depth)); + break; + } + } + } + } + + bool ReplaceTextureInModel(CModelInfoSA* pModelInfo, TextureSwapMap& swapMap) + { + if (!pModelInfo || swapMap.empty()) + return false; + + RwObject* pRwObject = pModelInfo->GetRwObject(); + if (!pRwObject) + return false; + + STextureSwapLookup swapLookup(swapMap); + + const unsigned char rwType = pRwObject->type; + const eModelInfoType modelType = pModelInfo->GetModelType(); + + if (modelType == eModelInfoType::UNKNOWN) + { + if (rwType == RP_TYPE_ATOMIC) + { + auto* pAtomic = reinterpret_cast(pRwObject); + if (pAtomic && pAtomic->geometry) + ReplaceTextureInGeometry(pAtomic->geometry, swapLookup); + return true; + } + + if (rwType == RP_TYPE_CLUMP) + { + auto* pClump = reinterpret_cast(pRwObject); + if (pClump) + { + RpClumpForAllAtomics(pClump, ReplaceTextureInAtomicCB, &swapLookup); + if (RwFrame* pRootFrame = reinterpret_cast(pClump->object.parent)) + { + std::vector visitedFrames; + ReplaceTextureInFrameHierarchy(pRootFrame, swapLookup, visitedFrames); + } + } + return true; + } + + return false; + } + + switch (modelType) + { + case eModelInfoType::ATOMIC: + case eModelInfoType::TIME: + case eModelInfoType::LOD_ATOMIC: + { + if (rwType != RP_TYPE_ATOMIC) + return false; + + RpAtomic* pAtomic = reinterpret_cast(pRwObject); + if (pAtomic && pAtomic->geometry) + ReplaceTextureInGeometry(pAtomic->geometry, swapLookup); + return true; + } + + case eModelInfoType::WEAPON: + case eModelInfoType::CLUMP: + case eModelInfoType::VEHICLE: + case eModelInfoType::PED: + { + if (rwType != RP_TYPE_CLUMP) + return false; + + RpClump* pClump = reinterpret_cast(pRwObject); + if (pClump) + { + RpClumpForAllAtomics(pClump, ReplaceTextureInAtomicCB, &swapLookup); + if (RwFrame* pRootFrame = reinterpret_cast(pClump->object.parent)) + { + std::vector visitedFrames; + ReplaceTextureInFrameHierarchy(pRootFrame, swapLookup, visitedFrames); + } + } + return true; + } + + default: + return false; + } + } + + // Register texture for shader matching; return D3D pointer or nullptr + CD3DDUMMY* AddTextureToShaderSystem(unsigned short usTxdId, RwTexture* pTexture) + { + if (!pGame || !pTexture) + return nullptr; + + auto* pRenderWareSA = pGame->GetRenderWareSA(); + if (!pRenderWareSA) + return nullptr; + + const char* szTextureName = pTexture->name; + + if (!pTexture->raster) + return nullptr; + + CD3DDUMMY* pD3DData = static_cast(pTexture->raster->renderResource); + if (!pD3DData) + return nullptr; + + if (pRenderWareSA->IsTexInfoRegistered(pD3DData)) + return nullptr; + + pRenderWareSA->StreamingAddedTexture(usTxdId, szTextureName, pD3DData); + return pD3DData; + } + + void RemoveShaderEntryByD3DData(unsigned short usTxdId, CD3DDUMMY* pD3DData) + { + if (!pGame || !pD3DData) + return; + + auto* pRenderWareSA = pGame->GetRenderWareSA(); + if (!pRenderWareSA) + return; + + pRenderWareSA->RemoveStreamingTexture(usTxdId, pD3DData); + } + + // Create an isolated TXD for a custom model (engineRequestModel clone). + // Each model gets its own TXD slot to prevent texture mixing between clones. + bool EnsureIsolatedTxdForRequestedModel(unsigned short usModelId) + { + if (!pGame) + return false; + + auto* pModelInfo = static_cast(pGame->GetModelInfo(usModelId)); + if (!pModelInfo) + return false; + + const unsigned int uiParentModelId = pModelInfo->GetParentID(); + if (uiParentModelId == 0) + return false; + + auto* pParentInfo = static_cast(pGame->GetModelInfo(uiParentModelId)); + if (!pParentInfo) + return false; + + const unsigned short usParentTxdId = pParentInfo->GetTextureDictionaryID(); + const bool bParentTxdLoaded = (CTxdStore_GetTxd(usParentTxdId) != nullptr); + + CTxdPool* pTxdPool = &pGame->GetPools()->GetTxdPool(); + CTxdPoolSA* pTxdPoolSA = static_cast(pTxdPool); + if (!pTxdPoolSA) + return false; + + // Expand pool on first use if CGameSA::Initialize() hasn't run yet. + // Scripts may request model textures before game init completes. + pTxdPoolSA->InitialisePool(); + + bool bXferredToParent = false; + + auto itExisting = g_IsolatedTxdByModel.find(usModelId); + if (itExisting != g_IsolatedTxdByModel.end()) + { + if (itExisting->second.usParentTxdId == usParentTxdId) + { + const unsigned short existingTxdId = itExisting->second.usTxdId; + auto* slot = pTxdPoolSA->GetTextureDictonarySlot(existingTxdId); + if (slot && slot->rwTexDictonary && (slot->usParentIndex == usParentTxdId || slot->usParentIndex == static_cast(-1))) + { + // Complete deferred parent chain when the parent TXD is now loaded + if (slot->usParentIndex == static_cast(-1) && CTxdStore_GetTxd(usParentTxdId) != nullptr) + { + slot->usParentIndex = usParentTxdId; + CTxdStore_SetupTxdParent(existingTxdId); + ClearPendingIsolatedModel(usModelId); + } + + itExisting->second.bNeedsVehicleFallback = ShouldUseVehicleTxdFallback(usModelId); + g_IsolatedModelByTxd[existingTxdId] = usModelId; + bool bParentLinkWasRepaired = false; + const bool bParentLinkReady = + slot->usParentIndex != static_cast(-1) && EnsureTxdParentLink(existingTxdId, usParentTxdId, &bParentLinkWasRepaired); + + // Parent chain still incomplete - keep the model on its + // current TXD so it renders with original textures rather + // than white from an empty, unlinked child TXD. + if (!bParentLinkReady) + { + UpdateIsolatedTxdLastUse(usModelId); + if (!g_PendingIsolatedModels.count(usModelId)) + AddPendingIsolatedModel(usModelId); + return false; + } + + if (pModelInfo->GetTextureDictionaryID() != existingTxdId) + { + // Same ref-count shortfall as the vanilla allocation path: + // pre-add refs so the old TXD survives the transfer. + CBaseModelInfoSAInterface* pInterface = pModelInfo->GetInterface(); + if (pInterface) + { + size_t nExtra = pInterface->usNumberOfRefs; + if (pInterface->pRwObject) + nExtra++; + for (size_t i = 0; i < nExtra; i++) + CTxdStore_AddRef(pModelInfo->GetTextureDictionaryID()); + } + pModelInfo->SetTextureDictionaryID(existingTxdId); + } + else if (bParentLinkWasRepaired) { + RebindLoadedModelToCurrentTxd(pModelInfo, existingTxdId); +} + + UpdateIsolatedTxdLastUse(usModelId); + return true; + } + } + + const unsigned short oldTxdId = itExisting->second.usTxdId; + const unsigned short oldParentTxdId = itExisting->second.usParentTxdId; + + RestoreModelTexturesToParent(pModelInfo, usModelId, oldTxdId, oldParentTxdId); + + if (pModelInfo->GetTextureDictionaryID() == oldTxdId) + { + // Ensure parent TXD is loaded so SetTextureDictionaryID takes + // the full ref transfer path instead of a field-only change that + // would orphan any active entity refs on the old child TXD. + if (CTxdStore_GetTxd(oldParentTxdId) == nullptr && pGame && pGame->GetStreaming()) + { + const int iBaseIDforTXD = pGame->GetBaseIDforTXD(); + if (iBaseIDforTXD > 0) + { + const unsigned int uiTxdStreamId = oldParentTxdId + static_cast(iBaseIDforTXD); + pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(true, "EnsureIsolatedTxd-reiso"); + } + } + // Pre-add refs to the isolated child TXD so the transfer out of it + // doesn't underflow. SA's AddRef may have bumped usNumberOfRefs after + // isolation without adding TXD refs, creating the same shortfall as + // the allocation path. + if (!TrySwitchModelToTxd(pModelInfo, usModelId, oldParentTxdId)) + return false; + + if (oldParentTxdId == usParentTxdId) + bXferredToParent = true; + } + + auto* oldSlot = pTxdPoolSA->GetTextureDictonarySlot(oldTxdId); + if (oldSlot && oldSlot->rwTexDictonary && oldSlot->usParentIndex == oldParentTxdId) + { + auto* pRenderWareSA = pGame->GetRenderWareSA(); + if (pRenderWareSA) + pRenderWareSA->StreamingRemovedTxd(oldTxdId); + + // With the MTA ownership pin the minimum ref count is 1 (just + // the pin) instead of 0. Account for old un-pinned slots. + const bool bOldPinned = pTxdPoolSA->IsSlotProtectedFromStreaming(oldTxdId); + const short nPinRefs = bOldPinned ? 1 : 0; + + if (CTxdStore_GetNumRefs(oldTxdId) <= nPinRefs) + { + RwTexDictionary* pTxd = oldSlot->rwTexDictonary; + const bool bOrphanedAll = OrphanTxdTexturesBounded(pTxd, true); + if (!bOrphanedAll) + { + g_OrphanedIsolatedTxdSlots.insert(oldTxdId); + } + + if (bOrphanedAll) + { + if (IsStreamingInfoSlot(oldTxdId)) + ResetStreamingInfo(oldTxdId); + InvalidateTxdTextureMapCache(oldTxdId); + if (bOldPinned) + CTxdStore_RemoveRef(oldTxdId); + pTxdPoolSA->RemoveTextureDictonarySlot(oldTxdId); + MarkTxdPoolCountDirty(); + g_OrphanedIsolatedTxdSlots.erase(oldTxdId); + } + } + else + { + g_OrphanedIsolatedTxdSlots.insert(oldTxdId); + } + } + std::unordered_map::iterator itOwner = g_IsolatedModelByTxd.find(oldTxdId); + const bool bStillOwned = (itOwner != g_IsolatedModelByTxd.end() && itOwner->second == usModelId); + + // Only clean up tracking/orphan state if the slot hasn't been + // reused by another model since we last owned it. + if (bStillOwned) + { + RemoveTxdFromReplacementTracking(oldTxdId); + g_IsolatedModelByTxd.erase(itOwner); + } + + ClearIsolatedTxdLastUse(usModelId); + ClearPendingIsolatedModel(usModelId); + CTxdStore_RemoveRef(oldParentTxdId); // Release parent pin for old isolation entry + g_IsolatedTxdByModel.erase(itExisting); + } + + const unsigned short usCurrentTxdId = pModelInfo->GetTextureDictionaryID(); + if (usCurrentTxdId != 0 && usCurrentTxdId != usParentTxdId) + { + CTextureDictonarySAInterface* pCurrentSlot = pTxdPoolSA->GetTextureDictonarySlot(usCurrentTxdId); + if (pCurrentSlot && pCurrentSlot->rwTexDictonary && pCurrentSlot->usParentIndex == usParentTxdId) + { + std::unordered_map::iterator itOwner = g_IsolatedModelByTxd.find(usCurrentTxdId); + + // TXD ownership cases: + // 1. This model's slot > re-adopt + // 2. Another model's slot > restore to parent + // 3. Orphaned MTA slot > reclaim + // 4. Untracked game TXD > create new slot + + if (itOwner != g_IsolatedModelByTxd.end()) + { + if (itOwner->second == usModelId) + { + // Case 1: This model's slot - re-adopt + SIsolatedTxdInfo info; + info.usTxdId = usCurrentTxdId; + info.usParentTxdId = usParentTxdId; + info.bNeedsVehicleFallback = ShouldUseVehicleTxdFallback(usModelId); + + g_IsolatedTxdByModel[usModelId] = info; + g_IsolatedModelByTxd[usCurrentTxdId] = usModelId; + CTxdStore_AddRef(usParentTxdId); // Pin parent while child exists + + bool bParentLinkWasRepaired = false; + if (!EnsureTxdParentLink(usCurrentTxdId, usParentTxdId, &bParentLinkWasRepaired)) + { + UpdateIsolatedTxdLastUse(usModelId); + if (!g_PendingIsolatedModels.count(usModelId)) + AddPendingIsolatedModel(usModelId); + return false; + } + + if (bParentLinkWasRepaired) + RebindLoadedModelToCurrentTxd(pModelInfo, usCurrentTxdId); + + UpdateIsolatedTxdLastUse(usModelId); + return true; + } + + // Case 2: Another model's slot - restore to parent + if (pModelInfo->GetTextureDictionaryID() != usParentTxdId) + { + if (!TryRestoreAndSwitchModelToTxd(pModelInfo, usModelId, usCurrentTxdId, usParentTxdId)) + return false; + + bXferredToParent = true; + } + } + else if (g_OrphanedIsolatedTxdSlots.count(usCurrentTxdId) > 0) + { + // Case 3: Orphaned MTA isolated slot - safe to reclaim + g_OrphanedIsolatedTxdSlots.erase(usCurrentTxdId); + + SIsolatedTxdInfo info; + info.usTxdId = usCurrentTxdId; + info.usParentTxdId = usParentTxdId; + info.bNeedsVehicleFallback = ShouldUseVehicleTxdFallback(usModelId); + + g_IsolatedTxdByModel[usModelId] = info; + g_IsolatedModelByTxd[usCurrentTxdId] = usModelId; + CTxdStore_AddRef(usParentTxdId); // Pin parent while child exists + + bool bParentLinkWasRepaired = false; + if (!EnsureTxdParentLink(usCurrentTxdId, usParentTxdId, &bParentLinkWasRepaired)) + { + UpdateIsolatedTxdLastUse(usModelId); + if (!g_PendingIsolatedModels.count(usModelId)) + AddPendingIsolatedModel(usModelId); + return false; + } + + if (bParentLinkWasRepaired) + RebindLoadedModelToCurrentTxd(pModelInfo, usCurrentTxdId); + + UpdateIsolatedTxdLastUse(usModelId); + return true; + } + // Case 4: Untracked game TXD - create new slot without touching current assignment + } + } + + const uint32_t uiNow = GetTickCount32(); + int iPoolSize = pTxdPoolSA->GetPoolSize(); + + // Pressure metrics measure the standard range [0, SA_TXD_POOL_CAPACITY) + // where isolation prefers to allocate. Isolation can spill into the + // expanded range when this fills up, but pressure here still drives + // stale-slot reclamation to keep standard-range slots available. + constexpr int iIsolationPoolSize = CTxdPoolSA::SA_TXD_POOL_CAPACITY; + int iUsedSlots = 0; + int iFreeSlots = 0; + int iUsagePercent = 0; + int iReservedSlots = 0; + if (iPoolSize > 0) + { + iReservedSlots = TXD_POOL_RESERVED_SLOTS; + const int iPercentReserve = (iIsolationPoolSize * TXD_POOL_RESERVED_PERCENT) / 100; + if (iIsolationPoolSize < TXD_POOL_RESERVED_SLOTS) { + iReservedSlots = iPercentReserve; + } else if (iPercentReserve > iReservedSlots) { + iReservedSlots = iPercentReserve; +} + if (iReservedSlots < 0) + iReservedSlots = 0; + if (iReservedSlots > iIsolationPoolSize - 1) + iReservedSlots = iIsolationPoolSize - 1; + + bool bNeedRefresh = g_bPoolCountDirty || g_iCachedPoolSize != iPoolSize || (uiNow - g_uiLastPoolCountTime >= TXD_POOL_COUNT_INTERVAL_MS); + if (!bNeedRefresh) + { + int iCachedUsed = g_iCachedUsedSlots; + if (iCachedUsed < 0) + iCachedUsed = 0; + if (iCachedUsed > iIsolationPoolSize) + iCachedUsed = iIsolationPoolSize; + const int iCachedFree = iIsolationPoolSize - iCachedUsed; + const int iCachedUsagePercent = (iCachedUsed * 100) / iIsolationPoolSize; + if (iCachedUsagePercent >= TXD_POOL_HARD_LIMIT_PERCENT || iCachedFree <= iReservedSlots + 4) + bNeedRefresh = true; + } + + if (bNeedRefresh) + { + g_iCachedPoolSize = iPoolSize; + g_iCachedUsedSlots = pTxdPoolSA->GetUsedSlotCountInRange(static_cast(CTxdPoolSA::SA_TXD_POOL_CAPACITY)); + g_uiLastPoolCountTime = uiNow; + g_bPoolCountDirty = false; + } + + iUsedSlots = g_iCachedUsedSlots; + if (iUsedSlots < 0) + { + iPoolSize = 0; + } + else + { + if (iUsedSlots > iIsolationPoolSize) + iUsedSlots = iIsolationPoolSize; + iFreeSlots = iIsolationPoolSize - iUsedSlots; + iUsagePercent = (iUsedSlots * 100) / iIsolationPoolSize; + } + + const bool bPoolPressure = (iPoolSize != 0 && (iUsagePercent >= TXD_POOL_HARD_LIMIT_PERCENT || iFreeSlots <= iReservedSlots)); + if (bPoolPressure) + { + TryReclaimStaleIsolatedSlots(); + + if (!g_OrphanedIsolatedTxdSlots.empty()) + { + TryCleanupOrphanedIsolatedSlots(true); + g_iCachedUsedSlots = pTxdPoolSA->GetUsedSlotCountInRange(static_cast(CTxdPoolSA::SA_TXD_POOL_CAPACITY)); + g_uiLastPoolCountTime = uiNow; + g_bPoolCountDirty = false; + if (g_iCachedUsedSlots >= 0) + { + iUsedSlots = g_iCachedUsedSlots; + if (iUsedSlots > iIsolationPoolSize) + iUsedSlots = iIsolationPoolSize; + iFreeSlots = iIsolationPoolSize - iUsedSlots; + iUsagePercent = (iUsedSlots * 100) / iIsolationPoolSize; + } + else + { + iPoolSize = 0; + iUsedSlots = 0; + iFreeSlots = 0; + iUsagePercent = 0; + } + } + + const bool bPoolStillUnderPressure = (iPoolSize != 0 && (iUsagePercent >= TXD_POOL_HARD_LIMIT_PERCENT || iFreeSlots <= iReservedSlots)); + if (bPoolStillUnderPressure) + { + // Pool is under pressure but free slots may still exist. + // Log warning and continue to allocation attempt; real exhaustion + // is caught by GetFreeTextureDictonarySlotInRange() returning -1 below. + // Previously this was a hard denial, which led to "white textures bug" on + // total-conversion maps with many engineRequestModel objects (each + // needing an isolated TXD slot). + } + } + } + + if (iPoolSize == 0) + { + if (pTxdPoolSA->GetFreeTextureDictonarySlot() == static_cast(-1)) + { + if (!bParentTxdLoaded && pModelInfo->IsLoaded()) + pParentInfo->Request(NON_BLOCKING, "EnsureIsolatedTxdForRequestedModel-ParentTXD"); + + if (pModelInfo->GetTextureDictionaryID() != usParentTxdId) + { + if (!TryRestoreAndSwitchModelToTxd(pModelInfo, usModelId, usCurrentTxdId, usParentTxdId)) + { + MarkIsolationDenied(); + return false; + } + } + + MarkIsolationDenied(); + return false; + } + } + + if (uiNow - g_uiLastTxdPoolWarnTime >= TXD_POOL_USAGE_WARN_INTERVAL_MS) + { + g_uiLastTxdPoolWarnTime = uiNow; + } + + // Use blocking request to ensure parent TXD is loaded before child TXD allocation. + // Without this, ReadDFF may run with a NULL parent chain, causing white textures + bool bParentAvailable = bParentTxdLoaded; + if (!bParentAvailable) + { + pParentInfo->Request(BLOCKING, "EnsureIsolatedTxdForRequestedModel-ParentTXD"); + bParentAvailable = (CTxdStore_GetTxd(usParentTxdId) != nullptr); + } + + // If the model is on a different TXD than the target parent (e.g. when a + // previous isolated slot was just torn down because the parent changed), + // pre-add refs to the CURRENT TXD so the transfer out of it doesn't underflow. + // Track whether the transfer already happened so the downstream pre-AddRef on + // usParentTxdId only adds the 1 pin instead of the full N+1 (parent already + // has +N from the transfer; adding N+1 more would leave N phantom refs). + const unsigned short usModelTxdId = pModelInfo->GetTextureDictionaryID(); + if (usModelTxdId != usParentTxdId) + { + if (!TryRestoreAndSwitchModelToTxd(pModelInfo, usModelId, usModelTxdId, usParentTxdId)) + return false; + + bXferredToParent = true; + } + + // Prefer standard-range [0, 5000) for isolation slots - these have + // dedicated TXD streaming entries. Fall back to [5000, 6316) which + // has no dedicated entries, then to the expanded range [6316, 32768). + // For slots >= 5000 the ASM hooks always report LOADED to SA. + std::uint32_t uiNewTxdId = pTxdPoolSA->GetFreeTextureDictonarySlotInRange(static_cast(CTxdPoolSA::SA_TXD_POOL_CAPACITY)); + + if (uiNewTxdId == static_cast(-1)) + { + // Standard range exhausted. Try overflow range [5000, 6316). + uiNewTxdId = pTxdPoolSA->GetFreeTextureDictonarySlotInRange(static_cast(CTxdPoolSA::MAX_STREAMING_TXD_SLOT)); + } + + if (uiNewTxdId == static_cast(-1)) + { + // Both streaming-range tiers exhausted. Use expanded pool [6316+). + uiNewTxdId = pTxdPoolSA->GetFreeTextureDictonarySlotAbove(static_cast(CTxdPoolSA::MAX_STREAMING_TXD_SLOT)); + } + + if (uiNewTxdId == static_cast(-1)) + { + MarkIsolationDenied(); + return false; + } + + CancelPendingStreamingForSlot(static_cast(uiNewTxdId)); + + std::string txdName = SString("mta_iso_%u", usModelId); + if (txdName.size() > MAX_TEX_DICTIONARY_NAME_LENGTH) + txdName.resize(MAX_TEX_DICTIONARY_NAME_LENGTH); + + if (pTxdPoolSA->AllocateTextureDictonarySlot(uiNewTxdId, txdName) == static_cast(-1)) + { + MarkIsolationDenied(); + MarkTxdPoolCountDirty(); + return false; + } + + // Create an empty RenderWare texture dictionary to hold imported textures + RwTexDictionary* pChildTxd = RwTexDictionaryCreate(); + if (!pChildTxd) + { + pTxdPoolSA->RemoveTextureDictonarySlot(uiNewTxdId); + MarkTxdPoolCountDirty(); + return false; + } + + // Associate the TXD with the slot.Set usParentIndex only when the + // parent is available and SetupTxdParent will be called immediately, + // because SA's RemoveTxd internally decrements the parent's + // usUsagesCount via usParentIndex. When the parent is unavailable + // we defer setting usParentIndex until ProcessPendingIsolatedModels + // establishes the linkage, keeping the ref-count balanced. + const unsigned short usSlotParentIndex = bParentAvailable ? usParentTxdId : static_cast(-1); + if (!pTxdPoolSA->SetTextureDictonarySlot(uiNewTxdId, pChildTxd, usSlotParentIndex)) + { + RwTexDictionaryDestroy(pChildTxd); + pTxdPoolSA->RemoveTextureDictonarySlot(uiNewTxdId); + MarkTxdPoolCountDirty(); + return false; + } + + MarkTxdPoolCountDirty(); + + // Establish parent-child RW linkage if parent TXD is available + if (bParentAvailable) + CTxdStore_SetupTxdParent(uiNewTxdId); + + // Mark the streaming entry LOADSTATE_LOADED so SA's DFF dependency check + // in GetNextFileOnCd treats the TXD as loaded. Overflow slots have no + // dedicated streaming entry; the ASM hooks always report LOADED for those. + if (IsStreamingInfoSlot(static_cast(uiNewTxdId))) + { + SetStreamingInfoLoaded(static_cast(uiNewTxdId)); + } + + SIsolatedTxdInfo info; + info.usTxdId = static_cast(uiNewTxdId); + info.usParentTxdId = usParentTxdId; + info.bNeedsVehicleFallback = ShouldUseVehicleTxdFallback(usModelId); + + // SetTextureDictionaryID removes referencesCount refs from the old + // (parent) TXD, where referencesCount = usNumberOfRefs + loaded flag. + // SA's CBaseModelInfo::AddRef only bumps usNumberOfRefs without adding + // a TXD ref, so the parent may have fewer refs than the transfer + // expects. Pre-add enough to cover the transfer plus one pin ref. + // When bXferredToParent is true, the model was just moved to usParentTxdId + // above, so that TXD already has +N from the transfer; only the +1 pin is + // still needed here to avoid leaving N phantom refs on the parent. + { + size_t nParentRefsToAdd = 1; + if (bParentAvailable && !bXferredToParent) + { + CBaseModelInfoSAInterface* pInterface = pModelInfo->GetInterface(); + if (pInterface) + { + nParentRefsToAdd = pInterface->usNumberOfRefs; + if (pInterface->pRwObject) + nParentRefsToAdd++; + nParentRefsToAdd++; + } + } + for (size_t i = 0; i < nParentRefsToAdd; i++) + CTxdStore_AddRef(usParentTxdId); + } + + // Only assign the model to the child TXD when the parent chain is + // ready. Without a parent chain, texture lookups on the empty child + // TXD find nothing and the model renders white for every material + // whose texture name is not among the replacement set. + if (bParentAvailable) + pModelInfo->SetTextureDictionaryID(static_cast(uiNewTxdId)); + + g_IsolatedTxdByModel[usModelId] = info; + g_IsolatedModelByTxd[info.usTxdId] = usModelId; + + // Pin the child TXD itself so SA's streaming never reaches ref-count 0 + // while MTA still tracks its textures. Without this, model unloading + // via CBaseModelInfo::RemoveRef can drop the child TXD ref to 0 and + // CStreaming::RemoveModel -> CTxdStore::RemoveTxd destroys the RW dict + // and its textures before MTA's cleanup can orphan them - causing + // use-after-free / heap corruption. + CTxdStore_AddRef(uiNewTxdId); + pTxdPoolSA->ProtectSlotFromStreaming(static_cast(uiNewTxdId)); + + UpdateIsolatedTxdLastUse(usModelId); + + if (!bParentAvailable) + { + if (ShouldLog(g_uiLastIsolationFailLogTime)) + { + AddReportLog(9404, SString("EnsureIsolatedTxdForRequestedModel: deferred parent setup for model %u (parentTxd=%u, childTxd=%u)", usModelId, + info.usParentTxdId, static_cast(uiNewTxdId))); + } + AddPendingIsolatedModel(usModelId); + return false; + } + return true; + } + + // Allocate a private TXD slot for a vanilla model whose shared TXD already + // holds replacement textures from a different model. Unlike the clone path + // (EnsureIsolatedTxdForRequestedModel), vanilla models have no parent model, + // so the model's current TXD slot is treated as the parent. + bool AllocateIsolatedTxdForVanillaModel(unsigned short usModelId, unsigned short usParentTxdId) + { + if (!pGame) + return false; + + auto* pModelInfo = static_cast(pGame->GetModelInfo(usModelId)); + if (!pModelInfo) + return false; + + CTxdPoolSA* pTxdPoolSA = static_cast(&pGame->GetPools()->GetTxdPool()); + if (!pTxdPoolSA) + return false; + + pTxdPoolSA->InitialisePool(); + + bool bXferredToParent = false; + + // Already isolated - reuse if parent matches, otherwise clean up old entry + auto itExisting = g_IsolatedTxdByModel.find(usModelId); + if (itExisting != g_IsolatedTxdByModel.end()) + { + if (itExisting->second.usParentTxdId == usParentTxdId) + { + const unsigned short existingTxdId = itExisting->second.usTxdId; + auto* slot = pTxdPoolSA->GetTextureDictonarySlot(existingTxdId); + // Also accept usParentIndex==0xFFFF: the slot was created with the same parent + // but the parent TXD wasn't loaded yet, so parent-chain setup is still pending. + if (slot && slot->rwTexDictonary && (slot->usParentIndex == usParentTxdId || slot->usParentIndex == static_cast(-1))) + { + // If parent chain was deferred (0xFFFF) but the parent TXD is now available, + // complete the linkage so SA's texture walk resolves non-replaced textures. + if (slot->usParentIndex == static_cast(-1) && CTxdStore_GetTxd(usParentTxdId) != nullptr) + { + slot->usParentIndex = usParentTxdId; + CTxdStore_SetupTxdParent(existingTxdId); + ClearPendingIsolatedModel(usModelId); + } + + itExisting->second.bNeedsVehicleFallback = ShouldUseVehicleTxdFallback(usModelId); + g_IsolatedModelByTxd[existingTxdId] = usModelId; + bool bParentLinkWasRepaired = false; + const bool bParentLinkReady = + slot->usParentIndex != static_cast(-1) && EnsureTxdParentLink(existingTxdId, usParentTxdId, &bParentLinkWasRepaired); + + // If the parent chain is still incomplete, keep the model on + // its current TXD so it renders with original textures rather + // than white from an empty, unlinked child TXD. + if (!bParentLinkReady) + { + UpdateIsolatedTxdLastUse(usModelId); + if (!g_PendingIsolatedModels.count(usModelId)) + AddPendingIsolatedModel(usModelId); + return false; + } + + if (pModelInfo->GetTextureDictionaryID() != existingTxdId) + { + // Same ref-count shortfall as the new-allocation path: + // pre-add refs so the old TXD survives the transfer. + CBaseModelInfoSAInterface* pInterface = pModelInfo->GetInterface(); + if (pInterface) + { + size_t nExtra = pInterface->usNumberOfRefs; + if (pInterface->pRwObject) + nExtra++; + for (size_t i = 0; i < nExtra; i++) + CTxdStore_AddRef(pModelInfo->GetTextureDictionaryID()); + } + pModelInfo->SetTextureDictionaryID(existingTxdId); + } + else if (bParentLinkWasRepaired) { + RebindLoadedModelToCurrentTxd(pModelInfo, existingTxdId); +} + + UpdateIsolatedTxdLastUse(usModelId); + return true; + } + } + + // Parent changed or slot invalid - clean up old isolation before re-allocating + const unsigned short oldTxdId = itExisting->second.usTxdId; + const unsigned short oldParentTxdId = itExisting->second.usParentTxdId; + + RestoreModelTexturesToParent(pModelInfo, usModelId, oldTxdId, oldParentTxdId); + if (pModelInfo->GetTextureDictionaryID() == oldTxdId) + { + // Ensure parent TXD is loaded so SetTextureDictionaryID takes + // the full ref transfer path instead of a field-only change that + // would orphan any active entity refs on the old child TXD. + if (CTxdStore_GetTxd(oldParentTxdId) == nullptr && pGame && pGame->GetStreaming()) + { + const int iBaseIDforTXD = pGame->GetBaseIDforTXD(); + if (iBaseIDforTXD > 0) + { + const unsigned int uiTxdStreamId = oldParentTxdId + static_cast(iBaseIDforTXD); + pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(true, "AllocateIsolatedTxdForVanillaModel-reiso"); + } + } + // Pre-add refs to the isolated child TXD so the transfer out of it + // doesn't underflow. SA's AddRef may have bumped usNumberOfRefs after + // isolation without adding TXD refs, creating the same shortfall as + // the allocation path. + if (!TrySwitchModelToTxd(pModelInfo, usModelId, oldParentTxdId)) + return false; + + if (oldParentTxdId == usParentTxdId) + bXferredToParent = true; + } + + auto itOwner = g_IsolatedModelByTxd.find(oldTxdId); + const bool bStillOwned = (itOwner != g_IsolatedModelByTxd.end() && itOwner->second == usModelId); + + // Only clean up tracking/orphan state if the slot hasn't been + // reused by another model since we last owned it. + if (bStillOwned) + { + RemoveTxdFromReplacementTracking(oldTxdId); + g_IsolatedModelByTxd.erase(itOwner); + g_OrphanedIsolatedTxdSlots.insert(oldTxdId); + } + + ClearIsolatedTxdLastUse(usModelId); + ClearPendingIsolatedModel(usModelId); + CTxdStore_RemoveRef(oldParentTxdId); + g_IsolatedTxdByModel.erase(itExisting); + } + + // Reclaim stale and orphaned isolated slots before allocating. + // This keeps the pool clean and lets the allocation below reuse a + // freed slot instead of always usig a fresh one. + TryReclaimStaleIsolatedSlots(); + if (!g_OrphanedIsolatedTxdSlots.empty()) + { + TryCleanupOrphanedIsolatedSlots(true); + MarkTxdPoolCountDirty(); + } + + // Load the parent TXD with a blocking request so the parent chain is + // set up immediately. Deferred setup (usParentIndex=0xFFFF) leaves + // non-replaced textures unresolvable until ProcessPendingIsolatedModels + // completes the linkage, causing white surfaces on world objs. + bool bParentAvailable = (CTxdStore_GetTxd(usParentTxdId) != nullptr); + if (!bParentAvailable && pGame->GetStreaming()) + { + // Switching the model to the child TXD removes SA's streaming refs + // on the parent, so the parent won't load on its own. + const int iBaseIDforTXD = pGame->GetBaseIDforTXD(); + if (iBaseIDforTXD > 0) + { + const unsigned int uiTxdStreamId = usParentTxdId + static_cast(iBaseIDforTXD); + pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(true, "AllocateIsolatedTxdForVanillaModel-parentTxd"); + bParentAvailable = (CTxdStore_GetTxd(usParentTxdId) != nullptr); + } + } + + // Find a free TXD slot (same tier priority as clone isolation) + std::uint32_t uiNewTxdId = pTxdPoolSA->GetFreeTextureDictonarySlotInRange(static_cast(CTxdPoolSA::SA_TXD_POOL_CAPACITY)); + + if (uiNewTxdId == static_cast(-1)) + uiNewTxdId = pTxdPoolSA->GetFreeTextureDictonarySlotInRange(static_cast(CTxdPoolSA::MAX_STREAMING_TXD_SLOT)); + + if (uiNewTxdId == static_cast(-1)) + uiNewTxdId = pTxdPoolSA->GetFreeTextureDictonarySlotAbove(static_cast(CTxdPoolSA::MAX_STREAMING_TXD_SLOT)); + + if (uiNewTxdId == static_cast(-1)) + { + if (ShouldLog(g_uiLastPoolDenyLogTime)) + AddReportLog(9401, SString("AllocateIsolatedTxdForVanillaModel: No free TXD slot for model %u (parentTxd=%u)", usModelId, usParentTxdId)); + MarkIsolationDenied(); + return false; + } + + CancelPendingStreamingForSlot(static_cast(uiNewTxdId)); + + std::string txdName = SString("mta_iso_%u", usModelId); + if (txdName.size() > MAX_TEX_DICTIONARY_NAME_LENGTH) + txdName.resize(MAX_TEX_DICTIONARY_NAME_LENGTH); + + if (pTxdPoolSA->AllocateTextureDictonarySlot(uiNewTxdId, txdName) == static_cast(-1)) + { + MarkIsolationDenied(); + MarkTxdPoolCountDirty(); + return false; + } + + RwTexDictionary* pChildTxd = RwTexDictionaryCreate(); + if (!pChildTxd) + { + pTxdPoolSA->RemoveTextureDictonarySlot(uiNewTxdId); + MarkTxdPoolCountDirty(); + return false; + } + + const unsigned short usSlotParentIndex = bParentAvailable ? usParentTxdId : static_cast(-1); + if (!pTxdPoolSA->SetTextureDictonarySlot(uiNewTxdId, pChildTxd, usSlotParentIndex)) + { + RwTexDictionaryDestroy(pChildTxd); + pTxdPoolSA->RemoveTextureDictonarySlot(uiNewTxdId); + MarkTxdPoolCountDirty(); + return false; + } + + MarkTxdPoolCountDirty(); + + if (bParentAvailable) + CTxdStore_SetupTxdParent(uiNewTxdId); + + if (IsStreamingInfoSlot(static_cast(uiNewTxdId))) { + SetStreamingInfoLoaded(static_cast(uiNewTxdId)); + } else if (ShouldLog(g_uiLastPoolDenyLogTime)) { + AddReportLog(9405, SString("AllocateIsolatedTxdForVanillaModel: overflow slot %u for model %u (parentTxd=%u)", + static_cast(uiNewTxdId), usModelId, usParentTxdId)); +} + + SIsolatedTxdInfo info; + info.usTxdId = static_cast(uiNewTxdId); + info.usParentTxdId = usParentTxdId; + info.bNeedsVehicleFallback = ShouldUseVehicleTxdFallback(usModelId); + + // SetTextureDictionaryID removes referencesCount refs from the old + // (parent) TXD, where referencesCount = usNumberOfRefs + loaded flag. + // SA's CBaseModelInfo::AddRef only bumps usNumberOfRefs without adding + // a TXD ref, so the parent may have fewer refs than the transfer + // expects. Pre-add enough to cover the transfer plus one pin ref. + // When bXferredToParent is true the teardown already added +N to + // usParentTxdId; only the 1 pin is still needed. + { + size_t nParentRefsToAdd = 1; + if (bParentAvailable && !bXferredToParent) + { + CBaseModelInfoSAInterface* pInterface = pModelInfo->GetInterface(); + if (pInterface) + { + nParentRefsToAdd = pInterface->usNumberOfRefs; + if (pInterface->pRwObject) + nParentRefsToAdd++; + nParentRefsToAdd++; + } + } + for (size_t i = 0; i < nParentRefsToAdd; i++) + CTxdStore_AddRef(usParentTxdId); + } + + // Only assign the model to the child TXD when the parent chain is ready. + // Without a parent chain, texture lookups on the empty child TXD find + // nothing and the model renders white until the deferred setup completes. + if (bParentAvailable) + pModelInfo->SetTextureDictionaryID(static_cast(uiNewTxdId)); + + g_IsolatedTxdByModel[usModelId] = info; + g_IsolatedModelByTxd[info.usTxdId] = usModelId; + + // Pin child TXD so streaming cannot destroy it while MTA tracks its textures + CTxdStore_AddRef(uiNewTxdId); + pTxdPoolSA->ProtectSlotFromStreaming(static_cast(uiNewTxdId)); + + UpdateIsolatedTxdLastUse(usModelId); + + if (!bParentAvailable) + { + if (ShouldLog(g_uiLastIsolationFailLogTime)) + { + AddReportLog(9404, SString("AllocateIsolatedTxdForVanillaModel: deferred parent setup for model %u (parentTxd=%u, childTxd=%u)", usModelId, + usParentTxdId, static_cast(uiNewTxdId))); + } + AddPendingIsolatedModel(usModelId); + return false; + } + return true; + } + + // Rebind all materials of a single atomic to textures from the given combined texture map. + // Looks up each material's texture name (with internal name fallback) in the map and + // replaces the material's texture pointer if a match is found. + void RebindAtomicMaterialsFromMap(RpAtomic* pAtomic, const TxdTextureMap& txdTextureMap) + { + if (!pAtomic) + return; + + RpGeometry* pGeometry = pAtomic->geometry; + if (!pGeometry) + return; + + RpMaterials& materials = pGeometry->materials; + if (!materials.materials || materials.entries <= 0) + return; + + constexpr int kMaxMaterials = 10000; + const int materialCount = materials.entries; + if (materialCount > kMaxMaterials) + return; + + for (int idx = 0; idx < materialCount; ++idx) + { + RpMaterial* pMaterial = materials.materials[idx]; + if (!pMaterial) + continue; + + RwTexture* pOldTexture = pMaterial->texture; + if (!pOldTexture) + continue; + + const char* szTextureName = pOldTexture->name; + if (!szTextureName[0]) + continue; + + RwTexture* pCurrentTexture = nullptr; + if (strnlen(szTextureName, RW_TEXTURE_NAME_LENGTH) < RW_TEXTURE_NAME_LENGTH) + { + auto itFound = txdTextureMap.find(szTextureName); + if (itFound != txdTextureMap.end()) + pCurrentTexture = itFound->second; + + if (!pCurrentTexture) + { + const char* szInternalName = CRenderWareSA::GetInternalTextureName(szTextureName); + if (szInternalName && szInternalName != szTextureName && strnlen(szInternalName, RW_TEXTURE_NAME_LENGTH) < RW_TEXTURE_NAME_LENGTH) + { + auto itInternal = txdTextureMap.find(szInternalName); + if (itInternal != txdTextureMap.end()) + pCurrentTexture = itInternal->second; + } + } + } + + if (pCurrentTexture && pCurrentTexture != pOldTexture) + RpMaterialSetTexture(pMaterial, pCurrentTexture); + } + } +} + +namespace +{ + RwObject* __cdecl RebindTexturesInFrameObjectCB(RwObject* pObject, void* data) + { + if (pObject && pObject->type == RP_TYPE_ATOMIC) + { + RpAtomic* pAtomic = reinterpret_cast(pObject); + // Specifically target detached atomics that aren't in the clump list + if (pAtomic->clump == nullptr && pAtomic->geometry) + { + const auto* pTxdTextureMap = static_cast(data); + RebindAtomicMaterialsFromMap(pAtomic, *pTxdTextureMap); + } + } + return pObject; + } + + void RebindTexturesInFrameHierarchy(RwFrame* pFrame, const TxdTextureMap& txdTextureMap, std::vector& visitedFrames, int depth = 0) + { + if (!pFrame) + return; + + if (depth > 128) + { + AddReportLog(9410, SString("RebindTexturesInFrameHierarchy: depth cap reached (%d)", depth)); + return; + } + + for (RwFrame* pVisited : visitedFrames) + { + if (pVisited == pFrame) + return; + } + visitedFrames.push_back(pFrame); + + RwFrameForAllObjects(pFrame, reinterpret_cast(RebindTexturesInFrameObjectCB), const_cast(reinterpret_cast(&txdTextureMap))); + + if (pFrame->child) + { + RwFrame* pChild = pFrame->child; + int nChildren = 0; + while (pChild) + { + RebindTexturesInFrameHierarchy(pChild, txdTextureMap, visitedFrames, depth + 1); + pChild = pChild->next; + if (++nChildren > 1024) + { + AddReportLog(9410, SString("RebindTexturesInFrameHierarchy: child limit hit at depth %d", depth)); + break; + } + } + } + } + + void RebindLoadedModelToCurrentTxd(CModelInfoSA* pModelInfo, unsigned short usTxdId) + { + if (!pGame || !pModelInfo) + return; + + RwObject* pRwObject = pModelInfo->GetRwObject(); + if (!pRwObject) + return; + + RwTexDictionary* pTxd = CTxdStore_GetTxd(usTxdId); + if (!pTxd) + return; + + // Walk the full parent chain (child -> parent -> grandparent -> ...) with bounded depth and cycle protection, + // then merge root-to-child so child textures win on name conflict + constexpr std::size_t kMaxChainDepth = 16; + unsigned short chain[kMaxChainDepth]; + std::size_t chainLen = 0; + unsigned short usFirstParentId = static_cast(-1); + + CTxdPoolSA* pTxdPoolSA = static_cast(&pGame->GetPools()->GetTxdPool()); + for (unsigned short id = usTxdId; pTxdPoolSA && chainLen < kMaxChainDepth;) + { + bool bCycle = false; + for (std::size_t j = 0; j < chainLen; ++j) + { + if (chain[j] == id) + { + bCycle = true; + break; + } + } + if (bCycle) + break; + + chain[chainLen++] = id; + + CTextureDictonarySAInterface* pSlot = pTxdPoolSA->GetTextureDictonarySlot(id); + if (!pSlot || pSlot->usParentIndex == static_cast(-1)) + break; + + if (usFirstParentId == static_cast(-1)) + usFirstParentId = pSlot->usParentIndex; + + id = pSlot->usParentIndex; + } + + TxdTextureMap txdTextureMap; + bool bChainComplete = true; + for (std::size_t i = chainLen; i > 0; --i) + { + RwTexDictionary* pChainTxd = CTxdStore_GetTxd(chain[i - 1]); + if (pChainTxd) { + MergeCachedTxdTextureMap(chain[i - 1], pChainTxd, txdTextureMap); + } else { + bChainComplete = false; +} + } + + bool bNeedVehicleFallback = (usFirstParentId != static_cast(-1)) && TxdChainContainsVehicleTxd(usFirstParentId); + if (!bNeedVehicleFallback) + { + if (pModelInfo->IsVehicle() || pModelInfo->IsUpgrade()) { + bNeedVehicleFallback = true; + } else + { + const unsigned int uiParentId = pModelInfo->GetParentID(); + if (uiParentId != 0) + { + if (auto* pParentInfo = static_cast(pGame->GetModelInfo(uiParentId))) + { + if (pParentInfo->IsVehicle() || pParentInfo->IsUpgrade()) + bNeedVehicleFallback = true; + } + } + } + } + if (bNeedVehicleFallback) + AddVehicleTxdFallback(txdTextureMap); + + // Skip rebind when any ancestor in the chain was not loaded. + // A partial map would replace some textures but leave others + // as white until the missing ancestors stream in. + if (!bChainComplete) + { + if (ShouldLog(g_uiLastIsolationFailLogTime)) + { + AddReportLog(9402, SString("RebindLoadedModelToCurrentTxd: incomplete TXD chain for model %u TXD %u (chain length %u)", pModelInfo->GetModel(), + usTxdId, static_cast(chainLen))); + } + return; + } + + if (txdTextureMap.empty()) + { + if (ShouldLog(g_uiLastIsolationFailLogTime)) + { + AddReportLog(9402, SString("RebindLoadedModelToCurrentTxd: empty texture map for model %u TXD %u (chain length %u)", pModelInfo->GetModel(), + usTxdId, static_cast(chainLen))); + } + return; + } + + eModelInfoType modelType = pModelInfo->GetModelType(); + if (modelType == eModelInfoType::UNKNOWN) + { + if (pRwObject->type == RP_TYPE_ATOMIC) + modelType = eModelInfoType::ATOMIC; + else if (pRwObject->type == RP_TYPE_CLUMP) + modelType = eModelInfoType::CLUMP; + } + + switch (modelType) + { + case eModelInfoType::PED: + case eModelInfoType::WEAPON: + case eModelInfoType::VEHICLE: + case eModelInfoType::CLUMP: + { + RpClump* pClump = reinterpret_cast(pRwObject); + std::vector atomicList; + CRenderWareSA::GetClumpAtomicList(pClump, atomicList); + for (RpAtomic* pAtomic : atomicList) + RebindAtomicMaterialsFromMap(pAtomic, txdTextureMap); + + if (RwFrame* pRootFrame = reinterpret_cast(pClump->object.parent)) + { + std::vector visitedFrames; + RebindTexturesInFrameHierarchy(pRootFrame, txdTextureMap, visitedFrames); + } + break; + } + case eModelInfoType::ATOMIC: + case eModelInfoType::LOD_ATOMIC: + case eModelInfoType::TIME: + { + RebindAtomicMaterialsFromMap(reinterpret_cast(pRwObject), txdTextureMap); + break; + } + default: + break; + } + + // Rebinding materials resets them to the TXD chain's originals, overwriting + // any active replacement textures. Re-apply affected replacements right away + // so there's no visible frame gap where the model shows originals. + auto itTexInfo = ms_ModelTexturesInfoMap.find(usTxdId); + if (itTexInfo != ms_ModelTexturesInfoMap.end()) + { + const unsigned short usModelId = static_cast(pModelInfo->GetModel()); + for (SReplacementTextures* pReplacement : itTexInfo->second.usedByReplacements) + { + if (!pReplacement || !IsReplacementActive(pReplacement)) + continue; + if (std::find(pReplacement->usedInModelIds.begin(), pReplacement->usedInModelIds.end(), usModelId) == pReplacement->usedInModelIds.end()) + continue; + + auto itPerTxd = std::find_if(pReplacement->perTxdList.begin(), pReplacement->perTxdList.end(), + [usTxdId](const SReplacementTextures::SPerTxd& entry) { return entry.usTxdId == usTxdId; }); + if (itPerTxd == pReplacement->perTxdList.end()) + continue; + + TextureSwapMap reapplyMap; + for (RwTexture* pReplacementTex : itPerTxd->usingTextures) + { + if (!pReplacementTex || !pReplacementTex->name[0]) + continue; + if (strnlen(pReplacementTex->name, RW_TEXTURE_NAME_LENGTH) >= RW_TEXTURE_NAME_LENGTH) + continue; + auto itOriginal = txdTextureMap.find(pReplacementTex->name); + if (itOriginal != txdTextureMap.end() && itOriginal->second != pReplacementTex) + reapplyMap[itOriginal->second] = pReplacementTex; + } + + if (!reapplyMap.empty()) + ReplaceTextureInModel(pModelInfo, reapplyMap); + } + } + } +} + +// Process deferred parent TXD setup for per-model isolated TXDs +// Called periodically after streaming updates to finalize parent linkage once the parent TXD is loaded +void CRenderWareSA::ProcessPendingIsolatedModels(bool bBlockingParentLoad) +{ + if (!pGame) + return; + + if (g_bProcessingPendingIsolatedModels) + return; + + struct SPendingIsolatedProcessingGuard + { + bool& bFlag; + SPendingIsolatedProcessingGuard(bool& bInFlag) : bFlag(bInFlag) { bFlag = true; } + ~SPendingIsolatedProcessingGuard() { bFlag = false; } + }; + + SPendingIsolatedProcessingGuard guard(g_bProcessingPendingIsolatedModels); + + if (g_PendingIsolatedModels.empty()) + { + TryCleanupOrphanedIsolatedSlots(); + TryApplyPendingReplacements(); + if (g_OrphanedIsolatedTxdSlots.empty()) + return; + } + + uint32_t uiNow = GetTickCount32(); + + // Throttle cleanup-only work to 50ms intervals, but always process + // immediately when pending models exist - their parent linkage + // (usParentIndex) must be resolved before SA streams in the DFF. + if (g_PendingIsolatedModels.empty() && uiNow - g_uiLastPendingTxdProcessTime < 50) + return; + g_uiLastPendingTxdProcessTime = uiNow; + + CTxdPool* pTxdPool = &pGame->GetPools()->GetTxdPool(); + CTxdPoolSA* pTxdPoolSA = static_cast(pTxdPool); + if (!pTxdPoolSA) + return; + + std::vector vecPendingSnapshot; + vecPendingSnapshot.reserve(g_PendingIsolatedModels.size()); + for (unsigned short usModelId : g_PendingIsolatedModels) + vecPendingSnapshot.push_back(usModelId); + + std::size_t uiProcessedCount = 0; + for (unsigned short usModelId : vecPendingSnapshot) + { + if (uiProcessedCount >= MAX_PENDING_ISOLATED_PER_TICK) + break; + + ++uiProcessedCount; + auto itInfo = g_IsolatedTxdByModel.find(usModelId); + if (itInfo == g_IsolatedTxdByModel.end()) + { + ClearPendingIsolatedModel(usModelId); + continue; + } + + const unsigned short childTxdId = itInfo->second.usTxdId; + const unsigned short parentTxdId = itInfo->second.usParentTxdId; + + CModelInfoSA* pModelInfo = static_cast(pGame->GetModelInfo(usModelId)); + if (!pModelInfo) + { + ClearIsolatedTxdLastUse(usModelId); + ClearPendingIsolatedModel(usModelId); + CTxdStore_RemoveRef(parentTxdId); // Release parent pin + g_IsolatedTxdByModel.erase(itInfo); + std::unordered_map::iterator itOwner = g_IsolatedModelByTxd.find(childTxdId); + if (itOwner != g_IsolatedModelByTxd.end() && itOwner->second == usModelId) + g_IsolatedModelByTxd.erase(itOwner); + ClearPendingReplacementStateForModel(usModelId); + g_PendingReplacementByModel.erase(usModelId); + RemoveTxdFromReplacementTracking(childTxdId); + const bool bInserted = g_OrphanedIsolatedTxdSlots.insert(childTxdId).second; + if (bInserted && ShouldLog(g_uiLastOrphanLogTime)) + AddReportLog(9401, SString("ProcessPendingIsolatedModels: Orphaned isolated TXD %u (model removed)", childTxdId)); + continue; + } + + std::unordered_map::iterator itPendingTime = g_PendingIsolatedModelTimes.find(usModelId); + if (itPendingTime != g_PendingIsolatedModelTimes.end() && uiNow - itPendingTime->second > PENDING_ISOLATION_TIMEOUT_MS) + { + // Try to revert model TXD if parent is valid + if (pModelInfo->GetTextureDictionaryID() == childTxdId && CTxdStore_GetTxd(parentTxdId) != nullptr) + { + if (!TryRestoreAndSwitchModelToTxd(pModelInfo, usModelId, childTxdId, parentTxdId)) + { + itPendingTime->second = uiNow; + continue; + } + } + + // If model still using a fully set-up isolated TXD, don't orphan it yet. + // Deferred vanilla slots (GetParentID()==0 with usParentIndex==0xFFFF) never had a + // functioning parent chain; clear them regardless of whether the child TXD is live. + const auto* pTimeoutChildSlot = pTxdPoolSA->GetTextureDictonarySlot(childTxdId); + const bool bIsIncompleteVanillaSlot = + pModelInfo->GetParentID() == 0 && pTimeoutChildSlot && pTimeoutChildSlot->usParentIndex == static_cast(-1); + if (!bIsIncompleteVanillaSlot && pModelInfo->GetTextureDictionaryID() == childTxdId && CTxdStore_GetTxd(childTxdId) != nullptr) + continue; + + ClearIsolatedTxdLastUse(usModelId); + ClearPendingIsolatedModel(usModelId); + CTxdStore_RemoveRef(parentTxdId); // Release parent pin + g_IsolatedTxdByModel.erase(itInfo); + std::unordered_map::iterator itOwner = g_IsolatedModelByTxd.find(childTxdId); + if (itOwner != g_IsolatedModelByTxd.end() && itOwner->second == usModelId) + g_IsolatedModelByTxd.erase(itOwner); + ClearPendingReplacementStateForModel(usModelId); + g_PendingReplacementByModel.erase(usModelId); + RemoveTxdFromReplacementTracking(childTxdId); + const bool bInserted = g_OrphanedIsolatedTxdSlots.insert(childTxdId).second; + if (bInserted && ShouldLog(g_uiLastOrphanLogTime)) + AddReportLog(9401, SString("ProcessPendingIsolatedModels: Timed out, orphaned isolated TXD %u for model %u", childTxdId, usModelId)); + continue; + } + + const unsigned int uiCurrentParentId = pModelInfo->GetParentID(); + if (uiCurrentParentId == 0) + { + // GetParentID()==0: vanilla model owns its TXD directly (no clone parent). + // AllocateIsolatedTxdForVanillaModel stores usParentIndex=0xFFFF when the parent + // TXD is not yet loaded; detect that state and complete setup here once it arrives. + auto* pChildSlot = pTxdPoolSA->GetTextureDictonarySlot(childTxdId); + const bool bIsDeferredVanillaSetup = pChildSlot && pChildSlot->rwTexDictonary && pChildSlot->usParentIndex == static_cast(-1) && + (pModelInfo->GetTextureDictionaryID() == childTxdId || pModelInfo->GetTextureDictionaryID() == parentTxdId); + + if (bIsDeferredVanillaSetup) + { + // Unlike clone models there is no pCurrentParentInfo to nudge through; + // request the TXD streaming entry directly each tick so the streaming + // system doesn't de-prioritise it before it arrives. + RwTexDictionary* pParentTxd = CTxdStore_GetTxd(parentTxdId); + if (pParentTxd == nullptr) + { + if (pGame->GetStreaming()) + { + const int iBaseIDforTXD = pGame->GetBaseIDforTXD(); + if (iBaseIDforTXD > 0) + { + const unsigned int uiTxdStreamId = parentTxdId + static_cast(iBaseIDforTXD); + pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16); + + if (bBlockingParentLoad) + { + pGame->GetStreaming()->LoadAllRequestedModels(true, "ProcessPendingIsolatedModels"); + pParentTxd = CTxdStore_GetTxd(parentTxdId); + } + } + } + + if (pParentTxd == nullptr) + continue; + } + + // Complete parent-chain setup matching the clone-model deferred path: + // wire usParentIndex, merge textures, rebind materials, apply vehicle fallback. + g_IsolatedModelByTxd[childTxdId] = usModelId; + + pChildSlot->usParentIndex = parentTxdId; + CTxdStore_SetupTxdParent(childTxdId); + + if (pModelInfo->GetTextureDictionaryID() != childTxdId) + { + CBaseModelInfoSAInterface* pInterface = pModelInfo->GetInterface(); + if (pInterface) + { + size_t nExtra = pInterface->usNumberOfRefs; + if (pInterface->pRwObject) + nExtra++; + for (size_t i = 0; i < nExtra; i++) + CTxdStore_AddRef(pModelInfo->GetTextureDictionaryID()); + } + pModelInfo->SetTextureDictionaryID(childTxdId); + } + + // Walk the full TXD parent chain from childTxdId so all loaded + // ancestors contribute textures, not just the immediate parent. + TxdTextureMap txdTextureMap; + { + constexpr std::size_t kMaxChainDepth = 16; + unsigned short chainIds[kMaxChainDepth]; + std::size_t chainLen = 0; + + for (unsigned short id = childTxdId; chainLen < kMaxChainDepth;) + { + bool bCycle = false; + for (std::size_t j = 0; j < chainLen; ++j) + { + if (chainIds[j] == id) + { + bCycle = true; + break; + } + } + if (bCycle) + break; + + chainIds[chainLen++] = id; + + CTextureDictonarySAInterface* pChainSlot = pTxdPoolSA->GetTextureDictonarySlot(id); + if (!pChainSlot || pChainSlot->usParentIndex == static_cast(-1)) + break; + + id = pChainSlot->usParentIndex; + } + + // Root-to-child order so child textures override ancestors on name conflict. + for (std::size_t i = chainLen; i > 0; --i) + { + RwTexDictionary* pChainTxd = CTxdStore_GetTxd(chainIds[i - 1]); + if (pChainTxd) + MergeCachedTxdTextureMap(chainIds[i - 1], pChainTxd, txdTextureMap); + } + } + + bool bNeedVehicleFallback = TxdChainContainsVehicleTxd(parentTxdId); + if (!bNeedVehicleFallback && pModelInfo) + { + if (pModelInfo->IsVehicle() || pModelInfo->IsUpgrade()) + bNeedVehicleFallback = true; + } + + if (bNeedVehicleFallback) + AddVehicleTxdFallback(txdTextureMap); + + if (pModelInfo->IsAllocatedInArchive()) + { + RwObject* pRwObject = pModelInfo->GetRwObject(); + if (pRwObject) + { + eModelInfoType modelType = pModelInfo->GetModelType(); + if (modelType == eModelInfoType::UNKNOWN) + { + if (pRwObject->type == RP_TYPE_ATOMIC) + modelType = eModelInfoType::ATOMIC; + else if (pRwObject->type == RP_TYPE_CLUMP) + modelType = eModelInfoType::CLUMP; + } + + switch (modelType) + { + case eModelInfoType::PED: + case eModelInfoType::WEAPON: + case eModelInfoType::VEHICLE: + case eModelInfoType::CLUMP: + { + RpClump* pClump = reinterpret_cast(pRwObject); + std::vector atomicList; + CRenderWareSA::GetClumpAtomicList(pClump, atomicList); + for (RpAtomic* pAtomic : atomicList) + RebindAtomicMaterialsFromMap(pAtomic, txdTextureMap); + if (RwFrame* pRootFrame = reinterpret_cast(pClump->object.parent)) + { + std::vector visitedFrames; + RebindTexturesInFrameHierarchy(pRootFrame, txdTextureMap, visitedFrames); + } + break; + } + case eModelInfoType::ATOMIC: + case eModelInfoType::LOD_ATOMIC: + case eModelInfoType::TIME: + { + RebindAtomicMaterialsFromMap(reinterpret_cast(pRwObject), txdTextureMap); + break; + } + default: + break; + } + } + } + + UpdateIsolatedTxdLastUse(usModelId); + ClearPendingIsolatedModel(usModelId); + continue; + } + + // Not a deferred vanilla setup; stale entry, clear it. + // Try to revert model TXD if parent is valid + if (pModelInfo->GetTextureDictionaryID() == childTxdId && CTxdStore_GetTxd(parentTxdId) != nullptr) + { + if (!TryRestoreAndSwitchModelToTxd(pModelInfo, usModelId, childTxdId, parentTxdId)) + continue; + } + + // If model still using a valid isolated TXD, don't orphan it - wait for natural cleanup + if (pModelInfo->GetTextureDictionaryID() == childTxdId && CTxdStore_GetTxd(childTxdId) != nullptr) + continue; + + ClearIsolatedTxdLastUse(usModelId); + ClearPendingIsolatedModel(usModelId); + CTxdStore_RemoveRef(parentTxdId); // Release parent pin + g_IsolatedTxdByModel.erase(itInfo); + std::unordered_map::iterator itOwner = g_IsolatedModelByTxd.find(childTxdId); + if (itOwner != g_IsolatedModelByTxd.end() && itOwner->second == usModelId) + g_IsolatedModelByTxd.erase(itOwner); + ClearPendingReplacementStateForModel(usModelId); + g_PendingReplacementByModel.erase(usModelId); + RemoveTxdFromReplacementTracking(childTxdId); + const bool bInserted = g_OrphanedIsolatedTxdSlots.insert(childTxdId).second; + if (bInserted && ShouldLog(g_uiLastOrphanLogTime)) + AddReportLog(9401, SString("ProcessPendingIsolatedModels: Orphaned isolated TXD %u (parent cleared)", childTxdId)); + continue; + } + + CModelInfoSA* pCurrentParentInfo = static_cast(pGame->GetModelInfo(uiCurrentParentId)); + const unsigned short usCurrentParentTxdId = pCurrentParentInfo ? pCurrentParentInfo->GetTextureDictionaryID() : 0; + if (usCurrentParentTxdId == 0 || usCurrentParentTxdId != parentTxdId) + { + if (usCurrentParentTxdId != 0 && pModelInfo->GetTextureDictionaryID() == childTxdId) + { + if (!TryRestoreAndSwitchModelToTxd(pModelInfo, usModelId, childTxdId, usCurrentParentTxdId)) + continue; + } + + ClearIsolatedTxdLastUse(usModelId); + ClearPendingIsolatedModel(usModelId); + CTxdStore_RemoveRef(parentTxdId); // Release parent pin + g_IsolatedTxdByModel.erase(itInfo); + std::unordered_map::iterator itOwner = g_IsolatedModelByTxd.find(childTxdId); + if (itOwner != g_IsolatedModelByTxd.end() && itOwner->second == usModelId) + g_IsolatedModelByTxd.erase(itOwner); + ClearPendingReplacementStateForModel(usModelId); + g_PendingReplacementByModel.erase(usModelId); + RemoveTxdFromReplacementTracking(childTxdId); + const bool bInserted = g_OrphanedIsolatedTxdSlots.insert(childTxdId).second; + if (bInserted && ShouldLog(g_uiLastOrphanLogTime)) + AddReportLog(9401, SString("ProcessPendingIsolatedModels: Orphaned isolated TXD %u (parent changed)", childTxdId)); + + continue; + } + + RwTexDictionary* pParentTxd = CTxdStore_GetTxd(parentTxdId); + if (pParentTxd == nullptr) + { + if (pCurrentParentInfo && pModelInfo->IsLoaded()) + pCurrentParentInfo->Request(NON_BLOCKING, "ProcessPendingIsolatedModels-ParentTXD"); + + continue; + } + + g_IsolatedModelByTxd[childTxdId] = usModelId; + + CTextureDictonarySAInterface* pSlot = pTxdPoolSA->GetTextureDictonarySlot(childTxdId); + // Accept usParentIndex == 0xFFFF for pending slots where the parent + // was unavailable at creation time; we set it below before + // CTxdStore_SetupTxdParent establishes the RW linkage. + if (!pSlot || !pSlot->rwTexDictonary || (pSlot->usParentIndex != parentTxdId && pSlot->usParentIndex != static_cast(-1))) + { + // Try to revert model TXD if parent is valid + if (pModelInfo->GetTextureDictionaryID() == childTxdId && CTxdStore_GetTxd(parentTxdId) != nullptr) + { + if (!TryRestoreAndSwitchModelToTxd(pModelInfo, usModelId, childTxdId, parentTxdId)) + continue; + } + + // If model still using a valid isolated TXD, don't orphan it - wait for natural cleanup + if (pModelInfo->GetTextureDictionaryID() == childTxdId && CTxdStore_GetTxd(childTxdId) != nullptr) + continue; + + ClearIsolatedTxdLastUse(usModelId); + ClearPendingIsolatedModel(usModelId); + CTxdStore_RemoveRef(parentTxdId); // Release parent pin + g_IsolatedTxdByModel.erase(itInfo); + std::unordered_map::iterator itOwner = g_IsolatedModelByTxd.find(childTxdId); + if (itOwner != g_IsolatedModelByTxd.end() && itOwner->second == usModelId) + g_IsolatedModelByTxd.erase(itOwner); + ClearPendingReplacementStateForModel(usModelId); + g_PendingReplacementByModel.erase(usModelId); + RemoveTxdFromReplacementTracking(childTxdId); + const bool bInserted = g_OrphanedIsolatedTxdSlots.insert(childTxdId).second; + if (bInserted && ShouldLog(g_uiLastOrphanLogTime)) + AddReportLog(9401, SString("ProcessPendingIsolatedModels: Orphaned isolated TXD %u (slot invalid)", childTxdId)); + continue; + } + + // Set usParentIndex now so txdInitParent can read it to establish + // RW parent dict linkage and increment the parent's usUsagesCount. + // This was deferred at creation when the parent was not yet loaded. + pSlot->usParentIndex = parentTxdId; + CTxdStore_SetupTxdParent(childTxdId); + + if (pModelInfo->GetTextureDictionaryID() != childTxdId) + { + CBaseModelInfoSAInterface* pInterface = pModelInfo->GetInterface(); + if (pInterface) + { + size_t nExtra = pInterface->usNumberOfRefs; + if (pInterface->pRwObject) + nExtra++; + for (size_t i = 0; i < nExtra; i++) + CTxdStore_AddRef(pModelInfo->GetTextureDictionaryID()); + } + pModelInfo->SetTextureDictionaryID(childTxdId); + } + + // Walk the full TXD parent chain from childTxdId so all loaded + // ancestors contribute textures, not just the immediate parent. + TxdTextureMap txdTextureMap; + { + constexpr std::size_t kMaxChainDepth = 16; + unsigned short chainIds[kMaxChainDepth]; + std::size_t chainLen = 0; + + for (unsigned short id = childTxdId; chainLen < kMaxChainDepth;) + { + bool bCycle = false; + for (std::size_t j = 0; j < chainLen; ++j) + { + if (chainIds[j] == id) + { + bCycle = true; + break; + } + } + if (bCycle) + break; + + chainIds[chainLen++] = id; + + CTextureDictonarySAInterface* pChainSlot = pTxdPoolSA->GetTextureDictonarySlot(id); + if (!pChainSlot || pChainSlot->usParentIndex == static_cast(-1)) + break; + + id = pChainSlot->usParentIndex; + } + + // Root-to-child order so child textures override ancestors on name conflict. + for (std::size_t i = chainLen; i > 0; --i) + { + RwTexDictionary* pChainTxd = CTxdStore_GetTxd(chainIds[i - 1]); + if (pChainTxd) + MergeCachedTxdTextureMap(chainIds[i - 1], pChainTxd, txdTextureMap); + } + } + + bool bNeedVehicleFallback = TxdChainContainsVehicleTxd(parentTxdId); + if (!bNeedVehicleFallback && pModelInfo) + { + if (pModelInfo->IsVehicle() || pModelInfo->IsUpgrade()) + { + bNeedVehicleFallback = true; + } + else + { + unsigned int uiParentId = pModelInfo->GetParentID(); + if (uiParentId != 0) + { + if (auto* pParentInfo = static_cast(pGame->GetModelInfo(uiParentId))) + { + if (pParentInfo->IsVehicle() || pParentInfo->IsUpgrade()) + bNeedVehicleFallback = true; + } + } + } + } + + if (bNeedVehicleFallback) + AddVehicleTxdFallback(txdTextureMap); + + if (pModelInfo && pModelInfo->IsAllocatedInArchive()) + { + RwObject* pRwObject = pModelInfo->GetRwObject(); + if (pRwObject) + { + eModelInfoType modelType = pModelInfo->GetModelType(); + if (modelType == eModelInfoType::UNKNOWN) + { + if (pRwObject->type == RP_TYPE_ATOMIC) + modelType = eModelInfoType::ATOMIC; + else if (pRwObject->type == RP_TYPE_CLUMP) + modelType = eModelInfoType::CLUMP; + } + + switch (modelType) + { + case eModelInfoType::PED: + case eModelInfoType::WEAPON: + case eModelInfoType::VEHICLE: + case eModelInfoType::CLUMP: + { + RpClump* pClump = reinterpret_cast(pRwObject); + std::vector atomicList; + CRenderWareSA::GetClumpAtomicList(pClump, atomicList); + for (RpAtomic* pAtomic : atomicList) + RebindAtomicMaterialsFromMap(pAtomic, txdTextureMap); + if (RwFrame* pRootFrame = reinterpret_cast(pClump->object.parent)) + { + std::vector visitedFrames; + RebindTexturesInFrameHierarchy(pRootFrame, txdTextureMap, visitedFrames); + } + break; + } + case eModelInfoType::ATOMIC: + case eModelInfoType::LOD_ATOMIC: + case eModelInfoType::TIME: + { + RebindAtomicMaterialsFromMap(reinterpret_cast(pRwObject), txdTextureMap); + break; + } + default: + break; + } + } + } + + UpdateIsolatedTxdLastUse(usModelId); + ClearPendingIsolatedModel(usModelId); + } + + TryReclaimStaleIsolatedSlots(); + TryCleanupOrphanedIsolatedSlots(); + TryApplyPendingReplacements(); +} + +void CRenderWareSA::ProcessPendingIsolatedTxdParents(bool bBlockingParentLoad) +{ + ProcessPendingIsolatedModels(bBlockingParentLoad); +} + +// Find or create texture info for model +CModelTexturesInfo* CRenderWareSA::GetModelTexturesInfo(unsigned short usModelId, const char* callsiteTag) +{ + if (!pGame) + return nullptr; + + auto* pModelInfo = static_cast(pGame->GetModelInfo(usModelId)); + if (!pModelInfo) + return nullptr; + + const unsigned short usTxdId = pModelInfo->GetTextureDictionaryID(); + + // A freed pool slot means the model has a stale usTextureDictionary left over from a + // cleaned-up isolated TXD. Streaming requests on freed slots insert them into GTA's + // streaming linked list, and when RemoveLeastUsedModel walks that list it calls + // GetNumRefs on the freed slot > null-deref crash. + if (pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(usTxdId)) + return nullptr; + + auto it = ms_ModelTexturesInfoMap.find(usTxdId); + if (it != ms_ModelTexturesInfoMap.end()) + { + CModelTexturesInfo& info = it->second; + RwTexDictionary* pCurrentTxd = CTxdStore_GetTxd(usTxdId); + + if (info.bReapplyingTextures) + { + if (!pCurrentTxd) + { + info.bReapplyingTextures = false; + return nullptr; + } + return &info; + } + + const bool bIsStaleEntry = (info.pTxd != pCurrentTxd) || (!info.pTxd && !pCurrentTxd); + + if (bIsStaleEntry) + { + if (info.usedByReplacements.empty()) + { + if (pCurrentTxd) + { + // Leaked entries may have stale pTxd if the slot was freed/reallocated. + // Add ref only if TXD changed; matching pointer means our old ref is valid. + const bool bNeedNewRef = info.bHasLeakedTextures && (info.pTxd != pCurrentTxd); + if (bNeedNewRef) + CRenderWareSA::DebugTxdAddRef(usTxdId, "GetModelTexturesInfo-repopulate-leaked"); + info.pTxd = pCurrentTxd; + PopulateOriginalTextures(info, pCurrentTxd); + info.bHasLeakedTextures = false; + return &info; + } + info.pTxd = nullptr; + info.originalTextures.clear(); + info.originalTexturesByName.clear(); + return nullptr; + } + + unsigned int uiTxdStreamId = usTxdId + pGame->GetBaseIDforTXD(); + CStreamingInfo* pStreamInfoBusyCheck = IsStreamingInfoSlot(usTxdId) ? GetStreamingInfoSafe(uiTxdStreamId) : nullptr; + bool bBusy = IsStreamingInfoSlot(usTxdId) && pStreamInfoBusyCheck && + (pStreamInfoBusyCheck->loadState == eModelLoadState::LOADSTATE_READING || + pStreamInfoBusyCheck->loadState == eModelLoadState::LOADSTATE_FINISHING); + if (bBusy && !pCurrentTxd) + return nullptr; + + std::unordered_map modelInfoCache; + std::vector>> replacementsToReapply; + std::vector>> pendingGeometryLess; + std::vector originalUsed; + + // Computed before the collection loop; that loop erases from usedInModelIds, + // so checking afterward would give false even when a fallback is needed. + bool bNeedVehicleFallback = false; + for (SReplacementTextures* pReplacement : info.usedByReplacements) + { + if (!pReplacement) + continue; + + originalUsed.push_back(pReplacement); + std::vector modelIds; + std::vector geometryLessIds; + for (unsigned short modelId : pReplacement->usedInModelIds) + { + auto& pCachedModInfo = modelInfoCache[modelId]; + if (!pCachedModInfo) + pCachedModInfo = static_cast(pGame->GetModelInfo(modelId)); + if (!pCachedModInfo) + continue; + + if (pCachedModInfo->GetTextureDictionaryID() == usTxdId) + { + if (!bNeedVehicleFallback && ShouldUseVehicleTxdFallback(modelId)) + bNeedVehicleFallback = true; + + if (pCachedModInfo->GetRwObject()) + modelIds.push_back(modelId); + else + geometryLessIds.push_back(modelId); + } + } + if (!pReplacement->textures.empty() && !modelIds.empty()) + replacementsToReapply.emplace_back(pReplacement, std::move(modelIds)); + if (!pReplacement->textures.empty() && !geometryLessIds.empty()) + pendingGeometryLess.emplace_back(pReplacement, std::move(geometryLessIds)); + } + + for (auto& entry : replacementsToReapply) + { + for (unsigned short modelId : entry.second) + entry.first->usedInModelIds.erase(modelId); + } + + std::unordered_set texturesToKeep; + for (SReplacementTextures* pReplacement : info.usedByReplacements) + { + texturesToKeep.insert(pReplacement->textures.begin(), pReplacement->textures.end()); + + for (const auto& perTxd : pReplacement->perTxdList) + { + if (perTxd.usTxdId != usTxdId) + { + texturesToKeep.insert(perTxd.usingTextures.begin(), perTxd.usingTextures.end()); + texturesToKeep.insert(perTxd.replacedOriginals.begin(), perTxd.replacedOriginals.end()); + } + } + } + + TxdTextureMap freshTxdMap; + if (pCurrentTxd) + MergeCachedTxdTextureMap(usTxdId, pCurrentTxd, freshTxdMap); + + TxdTextureMap parentTxdMap; + auto& txdPool = pGame->GetPools()->GetTxdPool(); + if (auto* pTxdPoolSA = static_cast(&txdPool)) + { + if (auto* pTxdSlot = pTxdPoolSA->GetTextureDictonarySlot(usTxdId)) + { + unsigned short usParentTxdId = pTxdSlot->usParentIndex; + if (usParentTxdId != static_cast(-1)) + { + RwTexDictionary* pParentTxd = CTxdStore_GetTxd(usParentTxdId); + + // Load parent TXD (and TXD data when also unloaded) if models with geometry need texture restoration + if (!pParentTxd && pGame->GetStreaming()) + { + bool bAnyModelHasGeometry = false; + for (const auto& cacheEntry : modelInfoCache) + { + if (cacheEntry.second && cacheEntry.second->GetRwObject()) + { + bAnyModelHasGeometry = true; + break; + } + } + + if (bAnyModelHasGeometry) + { + const int iBaseIDforTXD = pGame->GetBaseIDforTXD(); + if (iBaseIDforTXD > 0) + { + const unsigned int uiTxdStreamId = usParentTxdId + static_cast(iBaseIDforTXD); + pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16); + + // When the TXD data also needs loading, + // request it now so both stream in one blocking wait + // instead of a second LoadAllRequestedModels after cleanup. + // Pending non-priority requests run on the next streaming update. + if (!pCurrentTxd && usTxdId < CTxdPoolSA::SA_TXD_POOL_CAPACITY) + { + const unsigned int uiTxdDataStreamId = usTxdId + static_cast(iBaseIDforTXD); + CStreamingInfo* pStreamInfo = GetStreamingInfoSafe(uiTxdDataStreamId); + const bool bBusyOrLoaded = pStreamInfo && (pStreamInfo->loadState == eModelLoadState::LOADSTATE_READING || + pStreamInfo->loadState == eModelLoadState::LOADSTATE_FINISHING || + pStreamInfo->loadState == eModelLoadState::LOADSTATE_LOADED); + if (!bBusyOrLoaded) + pGame->GetStreaming()->RequestModel(uiTxdDataStreamId, 0x16); + } + + pGame->GetStreaming()->LoadAllRequestedModels(true, "GetModelTexturesInfo-parentTxd"); + pParentTxd = CTxdStore_GetTxd(usParentTxdId); + } + } + } + + if (pParentTxd) + MergeCachedTxdTextureMap(usParentTxdId, pParentTxd, parentTxdMap); + } + } + } + + if (bNeedVehicleFallback) + AddVehicleTxdFallback(parentTxdMap); + + std::unordered_set copiesToDestroy; + std::unordered_set originalsToDestroy; + + for (SReplacementTextures* pReplacement : info.usedByReplacements) + { + auto itPerTxd = std::find_if(pReplacement->perTxdList.begin(), pReplacement->perTxdList.end(), + [usTxdId](const SReplacementTextures::SPerTxd& item) { return item.usTxdId == usTxdId; }); + + if (itPerTxd != pReplacement->perTxdList.end()) + { + if (!freshTxdMap.empty() || !parentTxdMap.empty()) + { + TextureSwapMap restoreMap; + for (RwTexture* pTex : itPerTxd->usingTextures) + { + if (!IsReadableTexture(pTex)) + continue; + if (strnlen(pTex->name, RW_TEXTURE_NAME_LENGTH) >= RW_TEXTURE_NAME_LENGTH) + continue; + + RwTexture* pFresh = nullptr; + auto itFresh = freshTxdMap.find(pTex->name); + if (itFresh != freshTxdMap.end() && IsReadableTexture(itFresh->second)) + pFresh = itFresh->second; + + if (!pFresh && !parentTxdMap.empty()) + { + auto itParent = parentTxdMap.find(pTex->name); + if (itParent != parentTxdMap.end() && IsReadableTexture(itParent->second)) + pFresh = itParent->second; + + if (!pFresh) + { + const char* szInternal = CRenderWareSA::GetInternalTextureName(pTex->name); + if (szInternal && strcmp(szInternal, pTex->name) != 0) + { + auto itInt = parentTxdMap.find(szInternal); + if (itInt != parentTxdMap.end() && IsReadableTexture(itInt->second)) + pFresh = itInt->second; + } + } + } + + if (pFresh) + restoreMap[pTex] = pFresh; + } + + if (!restoreMap.empty()) + { + for (unsigned short mid : pReplacement->usedInModelIds) + { + auto itMi = modelInfoCache.find(mid); + if (itMi != modelInfoCache.end() && itMi->second) + ReplaceTextureInModel(itMi->second, restoreMap); + } + } + } + + ForEachShaderReg(pReplacement, itPerTxd->usTxdId, + [txdId = itPerTxd->usTxdId](CD3DDUMMY* pD3D) { RemoveShaderEntryByD3DData(txdId, pD3D); }); + ClearShaderRegs(pReplacement, itPerTxd->usTxdId); + + CleanupStalePerTxd(*itPerTxd, info.pTxd, pReplacement, nullptr, copiesToDestroy, originalsToDestroy); + + pReplacement->perTxdList.erase(itPerTxd); + pReplacement->bHasRequestedSpace = false; + } + + pReplacement->usedInTxdIds.erase(usTxdId); + } + + // Destroy copies (nullify raster to prevent double-free of shared raster) + for (RwTexture* pTexture : copiesToDestroy) // Nullify raster to avoid double-free + { + if (!pTexture) + continue; + + if (texturesToKeep.find(pTexture) != texturesToKeep.end()) + continue; + + if (CanDestroyOrphanedTexture(pTexture)) + { + SafeDestroyTexture(pTexture); + } + } + + for (RwTexture* pTexture : originalsToDestroy) // Originals own their rasters + { + if (!pTexture) + continue; + + if (texturesToKeep.find(pTexture) != texturesToKeep.end()) + continue; + + if (CanDestroyOrphanedTexture(pTexture)) + { + RwTextureDestroy(pTexture); + } + } + info.usedByReplacements.clear(); + + auto restoreState = [usTxdId, &info, &originalUsed, &replacementsToReapply](bool bRestoreTxdTracking) + { + for (SReplacementTextures* pReplacement : originalUsed) + { + if (!pReplacement) + continue; + if (std::find(info.usedByReplacements.begin(), info.usedByReplacements.end(), pReplacement) == info.usedByReplacements.end()) + info.usedByReplacements.push_back(pReplacement); + if (bRestoreTxdTracking) + pReplacement->usedInTxdIds.insert(usTxdId); + } + for (auto& entry : replacementsToReapply) + { + SReplacementTextures* pReplacement = entry.first; + if (!pReplacement) + continue; + for (unsigned short modelId : entry.second) + pReplacement->usedInModelIds.insert(modelId); + } + }; + + if (pCurrentTxd) + { + info.pTxd = pCurrentTxd; + PopulateOriginalTextures(info, pCurrentTxd); + restoreState(true); + } + else if (usTxdId < CTxdPoolSA::SA_TXD_POOL_CAPACITY) + { + // Standard-range TXD: use SA streaming to load from disc. + unsigned int uiTxdStreamId = usTxdId + pGame->GetBaseIDforTXD(); + CStreamingInfo* pStreamInfo = GetStreamingInfoSafe(uiTxdStreamId); + + auto IsBusyStreaming = [](CStreamingInfo* pInfo) -> bool + { return pInfo && (pInfo->loadState == eModelLoadState::LOADSTATE_READING || pInfo->loadState == eModelLoadState::LOADSTATE_FINISHING); }; + + if (IsBusyStreaming(pStreamInfo)) + { + restoreState(true); + return nullptr; + } + + bool bLoaded = pStreamInfo && pStreamInfo->loadState == eModelLoadState::LOADSTATE_LOADED; + if (!bLoaded) + { + pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(false, "GetModelTexturesInfo-txd"); + } + + unsigned short uiNewTxdId = pModelInfo->GetTextureDictionaryID(); + + if (uiNewTxdId != usTxdId) // TXD slot reassigned + { + restoreState(false); + if (!info.bHasLeakedTextures && CTxdStore_GetNumRefs(usTxdId) > 0) { + CRenderWareSA::DebugTxdRemoveRef(usTxdId, "GetModelTexturesInfo-stale-id-changed"); + } else if (info.bHasLeakedTextures) + { + if (g_PendingLeakedTxdRefs.size() < MAX_LEAK_RETRY_COUNT) { + g_PendingLeakedTxdRefs.insert(usTxdId); + } else if (ShouldLog(g_uiLastLeakCapacityLogTime)) { + AddReportLog(9401, SString("g_PendingLeakedTxdRefs at capacity, TXD %u not tracked", usTxdId)); +} + } + MapRemove(ms_ModelTexturesInfoMap, usTxdId); + return nullptr; + } + + pCurrentTxd = CTxdStore_GetTxd(usTxdId); + + if (!pCurrentTxd) + { + pStreamInfo = GetStreamingInfoSafe(uiTxdStreamId); + if (IsBusyStreaming(pStreamInfo)) + { + restoreState(true); + return nullptr; + } + + if (!pStreamInfo || pStreamInfo->loadState != eModelLoadState::LOADSTATE_LOADED) + pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(true, "GetModelTexturesInfo-txd-block"); + pCurrentTxd = CTxdStore_GetTxd(usTxdId); + } + + if (pCurrentTxd) + { + info.pTxd = pCurrentTxd; + PopulateOriginalTextures(info, pCurrentTxd); + restoreState(true); + } + else + { + restoreState(false); + if (!info.bHasLeakedTextures && CTxdStore_GetNumRefs(usTxdId) > 0) { + CRenderWareSA::DebugTxdRemoveRef(usTxdId, "GetModelTexturesInfo-blocking-fail"); + } else if (info.bHasLeakedTextures) + { + if (g_PendingLeakedTxdRefs.size() < MAX_LEAK_RETRY_COUNT) { + g_PendingLeakedTxdRefs.insert(usTxdId); + } else if (ShouldLog(g_uiLastLeakCapacityLogTime)) { + AddReportLog(9401, SString("g_PendingLeakedTxdRefs at capacity, TXD %u not tracked", usTxdId)); +} + } + MapRemove(ms_ModelTexturesInfoMap, usTxdId); + return nullptr; + } + } + else + { + // Overflow TXDs have no streaming entry; refetch from pool + pCurrentTxd = CTxdStore_GetTxd(usTxdId); + if (pCurrentTxd) + { + info.pTxd = pCurrentTxd; + PopulateOriginalTextures(info, pCurrentTxd); + restoreState(true); + } + else + { + restoreState(false); + MapRemove(ms_ModelTexturesInfoMap, usTxdId); + return nullptr; + } + } + + if (pCurrentTxd && !replacementsToReapply.empty()) + { + info.bReapplyingTextures = true; + + CRenderWareSA::DebugTxdAddRef(usTxdId, "GetModelTexturesInfo-reapply-pin", true); + struct TxdRefGuard + { + unsigned short txdId; + ~TxdRefGuard() + { + if (pGame && pGame->GetRenderWareSA()) + CRenderWareSA::DebugTxdRemoveRef(txdId, "GetModelTexturesInfo-reapply-pin"); + } + } txdRefGuard{usTxdId}; + + auto* pRenderWareSA = pGame->GetRenderWareSA(); + if (pRenderWareSA) + { + const bool bPrevInReapply = g_bInTxdReapply; + g_bInTxdReapply = true; + + RwTexDictionary* txdAtStart = pCurrentTxd; + bool bTxdChangedMidReapply = false; + + for (auto& reapplyEntry : replacementsToReapply) + { + SReplacementTextures* pReplacement = reapplyEntry.first; + const std::vector& modelIds = reapplyEntry.second; + + bool bAppliedToFirstModel = false; + + if (!modelIds.empty()) + { + if (CTxdStore_GetTxd(usTxdId) != txdAtStart) + { + bTxdChangedMidReapply = true; + break; + } + + size_t uiAppliedIndex = modelIds.size(); + for (size_t i = 0; i < modelIds.size(); ++i) + { + if (CTxdStore_GetTxd(usTxdId) != txdAtStart) + { + bTxdChangedMidReapply = true; + break; + } + + unsigned short usTestModelId = modelIds[i]; + const uint32_t uiStartSerial = g_uiIsolationDeniedSerial; + const bool bApplied = pRenderWareSA->ModelInfoTXDAddTextures(pReplacement, usTestModelId); + if (bApplied) + { + uiAppliedIndex = i; + bAppliedToFirstModel = true; + break; + } + + if (WasIsolationDenied(uiStartSerial)) + break; + } + + if (bTxdChangedMidReapply) + break; + + if (bAppliedToFirstModel) + { + if (CTxdStore_GetTxd(usTxdId) != txdAtStart) + { + bTxdChangedMidReapply = true; + break; + } + + for (size_t i = 0; i < modelIds.size(); ++i) + { + if (i == uiAppliedIndex) + continue; + + unsigned short usModelId = modelIds[i]; + const uint32_t uiStartSerial = g_uiIsolationDeniedSerial; + pRenderWareSA->ModelInfoTXDAddTextures(pReplacement, usModelId); + if (WasIsolationDenied(uiStartSerial)) + break; + } + } + } + } + + // Queue un-applied replacements when a TXD change forced erly exit + if (bTxdChangedMidReapply) + { + for (auto& remaining : replacementsToReapply) + { + if (!remaining.first) + continue; + for (unsigned short usModelId : remaining.second) + QueuePendingReplacement(usModelId, remaining.first, 0, 0); + } + AddReportLog(9401, SString("GetModelTexturesInfo: TXD %u changed mid-reapply, queued remaining replacements", usTxdId)); + } + + g_bInTxdReapply = bPrevInReapply; + } + info.bReapplyingTextures = false; + } + + // Queue deferred texture application for models that had no geometry + // during stale reapply. Their perTxdList entries were cleaned above; + // TryApplyPendingReplacements will apply when streaming loads geometry. + if (!pendingGeometryLess.empty()) + { + for (auto& pendingEntry : pendingGeometryLess) + { + for (unsigned short usModelId : pendingEntry.second) + QueuePendingReplacement(usModelId, pendingEntry.first, 0, 0); + } + } + } + + // Handle leaked entries with empty originalTextures (cleared at StaticReset). + // Clear leak flag only after proving current TXD matches baseline (no leaked textures remain). + if (info.bHasLeakedTextures && info.usedByReplacements.empty()) + { + RwTexDictionary* pFinalTxd = info.pTxd; + + // With baseline snapshot: compare current TXD to prove cleanliness. + // Without snapshot: populate baseline for future tracking; flag clears when proven clean. + const bool bHasOriginalSnapshot = !info.originalTextures.empty(); + + if (bHasOriginalSnapshot) + { + // Prove no leaks: TXD textures must exactly match originalTextures. + auto canProveNoLeaks = [&]() -> bool + { + if (!pFinalTxd) + return false; + RwTexDictionary* pCurrentTxd = CTxdStore_GetTxd(info.usTxdId); + if (pCurrentTxd != pFinalTxd) + return false; + std::vector currentTextures; + GetTxdTextures(currentTextures, pFinalTxd); + if (currentTextures.empty()) + return false; + if (currentTextures.size() != info.originalTextures.size()) + return false; + for (RwTexture* pTex : currentTextures) + { + if (info.originalTextures.find(pTex) == info.originalTextures.end()) + return false; + } + + // If originalTextures was built while MTA textures were still linked + // in the TXD, the pointer check above gives a false positive. Cross-check + // against g_LeakedMasterTextures to catch masters or copies (shared raster) + // that shouldnt be in a clean TXD. + if (!g_LeakedMasterTextures.empty()) + { + for (RwTexture* pTex : currentTextures) + { + if (!pTex) + continue; + + if (g_LeakedMasterTextures.count(pTex) != 0) + return false; + + if (pTex->raster) + { + for (RwTexture* pMaster : g_LeakedMasterTextures) + { + if (pMaster && pMaster->raster == pTex->raster) + return false; + } + } + } + } + + return true; + }; + + if (canProveNoLeaks()) + { + info.bHasLeakedTextures = false; + } + } + else if (pFinalTxd) + { + // No baseline - populate from current TXD to enable replacement tracking. + // Leak flag clears next call when baseline matches TXD (no new leaks). + PopulateOriginalTextures(info, pFinalTxd); + } + } + + return &info; + } + + RwTexDictionary* pTxd = CTxdStore_GetTxd(usTxdId); + + // For total conversion maps: custom models via engineRequestModel inherit + // their parent's TXD ID but bypass normal streaming dependencies. If the parent model never + // spawns, its TXD won't be loaded via normal streaming. Load it on-demand here. + // Overflow TXDs (>= MAX_STREAMING_TXD_SLOT) have no streaming entry and + // cannot be loaded via RequestModel. Overflow isolation slots [5000, 6316) + // have entries but are MTA-created; if pTxd is null, streaming won't help. + if (!pTxd && usTxdId < CTxdPoolSA::SA_TXD_POOL_CAPACITY) + { + unsigned int uiTxdStreamId = usTxdId + pGame->GetBaseIDforTXD(); + CStreamingInfo* pStreamInfo = GetStreamingInfoSafe(uiTxdStreamId); + + auto IsBusyStreaming = [](CStreamingInfo* pInfo) -> bool + { return pInfo && (pInfo->loadState == eModelLoadState::LOADSTATE_READING || pInfo->loadState == eModelLoadState::LOADSTATE_FINISHING); }; + + if (IsBusyStreaming(pStreamInfo)) + return nullptr; + + bool bLoaded = pStreamInfo && pStreamInfo->loadState == eModelLoadState::LOADSTATE_LOADED; + if (!bLoaded) + { + pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(false, "GetModelTexturesInfo-txd"); + pTxd = CTxdStore_GetTxd(usTxdId); + } + + if (!pTxd) + { + pStreamInfo = GetStreamingInfoSafe(uiTxdStreamId); + if (IsBusyStreaming(pStreamInfo)) + return nullptr; + + if (!pStreamInfo || pStreamInfo->loadState != eModelLoadState::LOADSTATE_LOADED) + pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(true, "GetModelTexturesInfo-txd-block"); + pTxd = CTxdStore_GetTxd(usTxdId); + } + + if (pTxd) + CRenderWareSA::DebugTxdAddRef(usTxdId, "GetModelTexturesInfo-cache-miss"); + } + else if (pTxd) + { + CRenderWareSA::DebugTxdAddRef(usTxdId, "GetModelTexturesInfo-cache-hit"); + } + + if (!pTxd) + { + AddReportLog(9401, + SString("GetModelTexturesInfo: CTxdStore_GetTxd returned null for model %u txdId=%u (after TXD streaming request)", usModelId, usTxdId)); + return nullptr; + } + + auto itInserted = ms_ModelTexturesInfoMap.emplace(usTxdId, CModelTexturesInfo{}); + CModelTexturesInfo& newInfo = itInserted.first->second; + newInfo.usTxdId = usTxdId; + newInfo.pTxd = pTxd; + + PopulateOriginalTextures(newInfo, pTxd); + + return &newInfo; +} + +//////////////////////////////////////////////////////////////// +// +// CRenderWareSA::ModelInfoTXDLoadTextures +// +//////////////////////////////////////////////////////////////// +bool CRenderWareSA::ModelInfoTXDLoadTextures(SReplacementTextures* pReplacementTextures, const SString& strFilename, const SString& buffer, + bool bFilteringEnabled, SString* pOutError) +{ + if (!pReplacementTextures) + { + if (pOutError) + *pOutError = "[ModelInfoTXDLoadTextures] Internal error: Invalid replacement textures pointer"; + return false; + } + + // Reset tracking if crossed session boundary + if (pReplacementTextures->uiSessionId != ms_uiTextureReplacingSession) + { + RemoveReplacementFromTracking(pReplacementTextures); + pReplacementTextures->uiSessionId = ms_uiTextureReplacingSession; + pReplacementTextures->textures.clear(); + pReplacementTextures->perTxdList.clear(); + pReplacementTextures->usedInTxdIds.clear(); + pReplacementTextures->usedInModelIds.clear(); + pReplacementTextures->bHasRequestedSpace = false; + } + + if (!pReplacementTextures->textures.empty()) + { + if (pOutError) + *pOutError = "[ModelInfoTXDLoadTextures] Textures already loaded for this TXD element"; + return false; + } + + if (pReplacementTextures->strDebugName.empty()) + { + if (!strFilename.empty()) { + pReplacementTextures->strDebugName = strFilename; + } else { + pReplacementTextures->strDebugName = SString("", static_cast(buffer.size())); +} + } + + if (pReplacementTextures->strDebugHash.empty()) + { + constexpr std::size_t kMaxHashSample = 1024 * 1024; // Limit cost for huge buffers + if (!buffer.empty()) + { + std::size_t sample = std::min(buffer.size(), kMaxHashSample); + if (sample > 0) + pReplacementTextures->strDebugHash = GenerateSha256HexString(buffer.data(), static_cast(sample)).Left(16); + } + else if (!strFilename.empty()) + { + pReplacementTextures->strDebugHash = GenerateSha256HexStringFromFile(strFilename).Left(16); + } + } + + // Pre-allocate streaming memory before loading textures + // Use 1.5x size to account for VRAM alignment overhead + if (!buffer.empty()) + { + std::uint64_t estimatedVRAM = (static_cast(buffer.size()) * 3) / 2; + if (estimatedVRAM > UINT32_MAX) + estimatedVRAM = UINT32_MAX; + StreamingMemory::PrepareStreamingMemoryForSize(static_cast(estimatedVRAM)); + } + else if (!strFilename.empty()) + { + std::uint64_t fileSize = FileSize(strFilename); + if (fileSize > 0 && fileSize < UINT32_MAX) + { + std::uint64_t estimatedVRAM = (fileSize * 3) / 2; + if (estimatedVRAM > UINT32_MAX) + estimatedVRAM = UINT32_MAX; + StreamingMemory::PrepareStreamingMemoryForSize(static_cast(estimatedVRAM)); + } + } + + auto* pTxd = ReadTXD(strFilename, buffer); + if (!pTxd) + { + if (pOutError) + *pOutError = "[ModelInfoTXDLoadTextures:ReadTXD] Failed to parse TXD (file may be incomplete, corrupt, or inaccessible)"; + return false; + } + + GetTxdTextures(pReplacementTextures->textures, pTxd); + + for (RwTexture* pTexture : pReplacementTextures->textures) + { + if (!pTexture) + continue; + + pTexture->txd = nullptr; + pTexture->TXDList.next = &pTexture->TXDList; + pTexture->TXDList.prev = &pTexture->TXDList; + + if (bFilteringEnabled) + { + if ((pTexture->flags & 0xFF00) == 0) + pTexture->flags |= 0x1100; + + pTexture->flags = (pTexture->flags & ~0xFF) | 0x02; + } + } + + pTxd->textures.root.next = &pTxd->textures.root; // Detach textures before destroying TXD + pTxd->textures.root.prev = &pTxd->textures.root; + RwTexDictionaryDestroy(pTxd); + + if (pReplacementTextures->textures.empty()) + { + if (pOutError) + *pOutError = "[ModelInfoTXDLoadTextures] TXD parsed successfully but contains no valid textures"; + return false; + } + + return true; +} + +// Add textures to model's TXD (model must be loaded) +bool CRenderWareSA::ModelInfoTXDAddTextures(SReplacementTextures* pReplacementTextures, unsigned short usModelId) +{ + if (!pGame || !pReplacementTextures) + { + AddReportLog(9401, + SString("ModelInfoTXDAddTextures: Failed early - pGame=%p pReplacementTextures=%p model=%u", pGame, pReplacementTextures, usModelId)); + return false; + } + + RegisterReplacement(pReplacementTextures); + + // Check if model needs TXD isolation to prevent texture mixing + auto* pModelInfo = static_cast(pGame->GetModelInfo(usModelId)); + if (pModelInfo) + { + const unsigned int uiParentModelId = pModelInfo->GetParentID(); + if (uiParentModelId != 0) + { + auto* pParentInfo = static_cast(pGame->GetModelInfo(uiParentModelId)); + const unsigned short usParentTxdId = pParentInfo ? pParentInfo->GetTextureDictionaryID() : 0; + + // If the model uses a TXD assigned by script (engineSetModelTXDID / engineRequestTXD) + // that isn't tracked by isolation, import directly without allocating a pool slot + const unsigned short usModelCurrentTxdId = pModelInfo->GetTextureDictionaryID(); + const bool bScriptManagedTxd = usModelCurrentTxdId != 0 && usModelCurrentTxdId != usParentTxdId && g_IsolatedTxdByModel.count(usModelId) == 0; + + if (bScriptManagedTxd) + { + auto* pTxdPoolSA = static_cast(&pGame->GetPools()->GetTxdPool()); + auto* pScriptSlot = pTxdPoolSA ? pTxdPoolSA->GetTextureDictonarySlot(usModelCurrentTxdId) : nullptr; + + const SScriptManagedTxdUsage scriptTxdUsage = GetScriptManagedTxdUsage(usModelId, usModelCurrentTxdId, usParentTxdId); + const bool bSharedTxdConflict = + HasScriptManagedTxdConflict(pReplacementTextures, usModelId, usModelCurrentTxdId, usParentTxdId, scriptTxdUsage); + + if (bSharedTxdConflict) + { + // Isolate this model to its own TXD so its replacements don't + // overwrite another model's textures in the shared script TXD. + const bool bIsolatedOk = EnsureIsolatedTxdForRequestedModel(usModelId); + if (!bIsolatedOk) + { + QueuePendingReplacement(usModelId, pReplacementTextures, uiParentModelId, usParentTxdId); + return false; + } + // Model is now on a private TXD - fall through to add logic + } + else if (pScriptSlot && pScriptSlot->rwTexDictonary) + { + // Script TXDs from engineRequestTXD have no parent + // (usParentIndex == 0xFFFF), so SA's texture walk can't + // find non-replaced textures and materials go white. + // If the slot already has a compatible parent from earlier + // reuse, relink it instead of forcing isolation. + const unsigned short usSlotParentTxdId = pScriptSlot->usParentIndex; + using SetTxdParent_t = void(__cdecl*)(RwTexDictionary*, RwTexDictionary*); + using GetTxdParent_t = RwTexDictionary*(__cdecl*)(RwTexDictionary*); + + const SetTxdParent_t SetTxdParent = reinterpret_cast(FUNC_CTxdStore__SetTxdParent); + const GetTxdParent_t GetTxdParent = reinterpret_cast(FUNC_CTxdStore__GetTxdParent); + + bool bParentAvailable = CTxdStore_GetTxd(usParentTxdId) != nullptr; + RwTexDictionary* pParentTxd = bParentAvailable ? CTxdStore_GetTxd(usParentTxdId) : nullptr; + RwTexDictionary* pCurrentParent = GetTxdParent(pScriptSlot->rwTexDictonary); + + if (!bParentAvailable) + { + // Leave pool and RW parent state alone until the parent is + // loaded. Changing usParentIndex or clearing the RW parent + // now would break SA's texture walk for non-replaced textures. + if (pParentInfo) + pParentInfo->Request(NON_BLOCKING, "ModelInfoTXDAddTextures-scriptParent"); + + QueuePendingReplacement(usModelId, pReplacementTextures, uiParentModelId, usParentTxdId); + return false; + } + + if (usSlotParentTxdId != usParentTxdId) + { + // Release pin on old parent if one was set + if (g_ScriptTxdSlotsWithParentPin.count(usModelCurrentTxdId) && usSlotParentTxdId != static_cast(-1)) + { + if (CTxdStore_GetTxd(usSlotParentTxdId) != nullptr) + CTxdStore_RemoveRef(usSlotParentTxdId); + } + + // Pin new parent so SA streaming won't evict it + CTxdStore_AddRef(usParentTxdId); + g_ScriptTxdSlotsWithParentPin.insert(usModelCurrentTxdId); + + pScriptSlot->usParentIndex = usParentTxdId; + CTxdStore_SetupTxdParent(usModelCurrentTxdId); + RebindLoadedModelToCurrentTxd(pModelInfo, usModelCurrentTxdId); + } + else if (pCurrentParent != pParentTxd) + { + SetTxdParent(pScriptSlot->rwTexDictonary, pParentTxd); + RebindLoadedModelToCurrentTxd(pModelInfo, usModelCurrentTxdId); + } + } + } + else if (!g_bInTxdReapply) + { + // Normal path: try to create isolation + const uint32_t uiStartSerial = g_uiIsolationDeniedSerial; + const bool bIsolatedOk = EnsureIsolatedTxdForRequestedModel(usModelId); + if (!bIsolatedOk) + { + QueuePendingReplacement(usModelId, pReplacementTextures, uiParentModelId, usParentTxdId); + return false; + } + } + else + { + // Reapply path: check if isolation exists AND model is actually using it + std::unordered_map::iterator itIsolated = g_IsolatedTxdByModel.find(usModelId); + if (itIsolated == g_IsolatedTxdByModel.end()) + { + QueuePendingReplacement(usModelId, pReplacementTextures, uiParentModelId, usParentTxdId); + return false; + } + + std::unordered_map::iterator itOwner = g_IsolatedModelByTxd.find(itIsolated->second.usTxdId); + if (itOwner == g_IsolatedModelByTxd.end() || itOwner->second != usModelId) + { + const unsigned short usStaleIsolatedTxdId = itIsolated->second.usTxdId; + const unsigned short usStaleParentTxdId = itIsolated->second.usParentTxdId; + + if (pModelInfo->GetTextureDictionaryID() == usStaleIsolatedTxdId && CTxdStore_GetTxd(usStaleParentTxdId) != nullptr) + { + CBaseModelInfoSAInterface* pInterface = pModelInfo->GetInterface(); + if (pInterface) + { + size_t nExtra = pInterface->usNumberOfRefs; + if (pInterface->pRwObject) + nExtra++; + for (size_t i = 0; i < nExtra; i++) + CTxdStore_AddRef(usStaleIsolatedTxdId); + } + pModelInfo->SetTextureDictionaryID(usStaleParentTxdId); + } + + ClearIsolatedTxdLastUse(usModelId); + ClearPendingIsolatedModel(usModelId); + CTxdStore_RemoveRef(usStaleParentTxdId); + g_IsolatedTxdByModel.erase(itIsolated); + // Queue for deferred cleanup when no other model claims the slot, + // so TryCleanupOrphanedIsolatedSlots can release the MTA ownership pin. + if (itOwner == g_IsolatedModelByTxd.end()) + g_OrphanedIsolatedTxdSlots.insert(usStaleIsolatedTxdId); + QueuePendingReplacement(usModelId, pReplacementTextures, uiParentModelId, usParentTxdId); + return false; + } + + auto* pTxdPoolSA = static_cast(&pGame->GetPools()->GetTxdPool()); + auto* pChildSlot = pTxdPoolSA ? pTxdPoolSA->GetTextureDictonarySlot(itIsolated->second.usTxdId) : nullptr; + bool bParentLinkWasRepaired = false; + const bool bChildParentLinkReady = pChildSlot && pChildSlot->usParentIndex != static_cast(-1) && + EnsureTxdParentLink(itIsolated->second.usTxdId, itIsolated->second.usParentTxdId, &bParentLinkWasRepaired); + + // Verify model's current TXD matches the isolated TXD (catch stale entries) + const unsigned short usModelTxdId = pModelInfo->GetTextureDictionaryID(); + const bool bModelWasOnIsolatedTxd = (usModelTxdId == itIsolated->second.usTxdId); + if (usModelTxdId != itIsolated->second.usTxdId) + { + // Streaming may have reassigned the model back to its parent TXD. + // If the isolated slot is still valid, move the model back to it. + // Without this, clone/requested models can get stuck on the parent + // TXD during reapply and keep resolving non-replaced textures from + // the wrong dictionary. + if (CTxdStore_GetTxd(itIsolated->second.usTxdId) == nullptr) + { + QueuePendingReplacement(usModelId, pReplacementTextures, uiParentModelId, usParentTxdId); + return false; + } + + if (!bChildParentLinkReady) + { + UpdateIsolatedTxdLastUse(usModelId); + if (!g_PendingIsolatedModels.count(usModelId)) + AddPendingIsolatedModel(usModelId); + QueuePendingReplacement(usModelId, pReplacementTextures, uiParentModelId, usParentTxdId); + return false; + } + + { + CBaseModelInfoSAInterface* pInterface = pModelInfo->GetInterface(); + if (pInterface) + { + size_t nExtra = pInterface->usNumberOfRefs; + if (pInterface->pRwObject) + nExtra++; + for (size_t i = 0; i < nExtra; i++) + CTxdStore_AddRef(pModelInfo->GetTextureDictionaryID()); + } + } + pModelInfo->SetTextureDictionaryID(itIsolated->second.usTxdId); + UpdateIsolatedTxdLastUse(usModelId); + } + + if (CTxdStore_GetTxd(itIsolated->second.usTxdId) == nullptr) + { + QueuePendingReplacement(usModelId, pReplacementTextures, uiParentModelId, usParentTxdId); + return false; + } + + if (!bChildParentLinkReady) + { + UpdateIsolatedTxdLastUse(usModelId); + if (!g_PendingIsolatedModels.count(usModelId)) + AddPendingIsolatedModel(usModelId); + QueuePendingReplacement(usModelId, pReplacementTextures, uiParentModelId, usParentTxdId); + return false; + } + + if (bParentLinkWasRepaired && bModelWasOnIsolatedTxd) + RebindLoadedModelToCurrentTxd(pModelInfo, itIsolated->second.usTxdId); + + itIsolated->second.bNeedsVehicleFallback = ShouldUseVehicleTxdFallback(usModelId); + } + } + else if (!g_bInTxdReapply) + { + // Vanilla models get their own isolated TXD so replacement textures + // stay out of the shared parent slot. + const unsigned short usCurrentTxdId = pModelInfo->GetTextureDictionaryID(); + + // Check for an existing isolation entry for this model. + auto itPrevIsolated = g_IsolatedTxdByModel.find(usModelId); + if (itPrevIsolated != g_IsolatedTxdByModel.end() && usCurrentTxdId == itPrevIsolated->second.usTxdId) + { + // Model is already on its isolated TXD (e.g after resource restart + // where removal + restream ran but CleanupIsolatedTxdForModel did not). + // Validate the slot is still live and owned by this model; a recycled + // or disowned slot would cause textures to target the wrong TXD. + auto itOwner = g_IsolatedModelByTxd.find(usCurrentTxdId); + if (CTxdStore_GetTxd(usCurrentTxdId) != nullptr && itOwner != g_IsolatedModelByTxd.end() && itOwner->second == usModelId) + { + auto* pTxdPoolSA = static_cast(&pGame->GetPools()->GetTxdPool()); + auto* pChildSlot = pTxdPoolSA ? pTxdPoolSA->GetTextureDictonarySlot(usCurrentTxdId) : nullptr; + bool bParentLinkWasRepaired = false; + const bool bChildParentLinkReady = pChildSlot && pChildSlot->usParentIndex != static_cast(-1) && + EnsureTxdParentLink(usCurrentTxdId, itPrevIsolated->second.usParentTxdId, &bParentLinkWasRepaired); + + if (!bChildParentLinkReady) + { + UpdateIsolatedTxdLastUse(usModelId); + if (!g_PendingIsolatedModels.count(usModelId)) + AddPendingIsolatedModel(usModelId); + QueuePendingReplacement(usModelId, pReplacementTextures, 0, 0); + return false; + } + + if (bParentLinkWasRepaired) + RebindLoadedModelToCurrentTxd(pModelInfo, usCurrentTxdId); + + itPrevIsolated->second.bNeedsVehicleFallback = ShouldUseVehicleTxdFallback(usModelId); + UpdateIsolatedTxdLastUse(usModelId); + } + else + { + // Stale entry: slot was recycled or ownership changed. + // Clean up tracking, restore model to parent TXD so the + // pending retry re-runs isolation on the shared slot. + const unsigned short usParentTxdId = itPrevIsolated->second.usParentTxdId; + + if (itOwner != g_IsolatedModelByTxd.end() && itOwner->second == usModelId) + { + RemoveTxdFromReplacementTracking(usCurrentTxdId); + g_IsolatedModelByTxd.erase(itOwner); + } + + // Restore model to its parent TXD before releasing the pin, + // so the model doesn't remain pointed at a dead/disowned slot. + if (pModelInfo->GetTextureDictionaryID() == usCurrentTxdId) + { + if (!TryRestoreAndSwitchModelToTxd(pModelInfo, usModelId, usCurrentTxdId, usParentTxdId)) + { + QueuePendingReplacement(usModelId, pReplacementTextures, 0, 0); + return false; + } + } + + CTxdStore_RemoveRef(usParentTxdId); + ClearIsolatedTxdLastUse(usModelId); + ClearPendingIsolatedModel(usModelId); + g_IsolatedTxdByModel.erase(itPrevIsolated); + QueuePendingReplacement(usModelId, pReplacementTextures, 0, 0); + return false; + } + } + else if (itPrevIsolated != g_IsolatedTxdByModel.end() && itPrevIsolated->second.usParentTxdId == usCurrentTxdId) + { + // Model was restored to its parent TXD but the isolation entry persists. + // Re-isolate so replacement textures stay out of the shared slot. + if (!AllocateIsolatedTxdForVanillaModel(usModelId, usCurrentTxdId)) + { + // Allocation failed. Defer until a slot frees up. + AddReportLog(9401, SString("AllocateIsolatedTxdForVanillaModel failed for model %u (re-isolation), deferring", usModelId)); + QueuePendingReplacement(usModelId, pReplacementTextures, 0, 0); + return false; + } + } + else if (itPrevIsolated == g_IsolatedTxdByModel.end()) + { + // Keep vanilla replacements on a private TXD so later model + // loads and child TXDs dont pick them up from the shared slot. + if (!AllocateIsolatedTxdForVanillaModel(usModelId, usCurrentTxdId)) + { + AddReportLog(9401, SString("AllocateIsolatedTxdForVanillaModel failed for model %u, deferring", usModelId)); + QueuePendingReplacement(usModelId, pReplacementTextures, 0, 0); + return false; + } + } + else + { + // Parent TXD changed since last isolation - re-isolate with new parent. + if (!AllocateIsolatedTxdForVanillaModel(usModelId, usCurrentTxdId)) + { + // Prior isolation proves the TXD was shared. Defer to + // avoid shared injection on a multi-model TXD. + AddReportLog(9401, SString("AllocateIsolatedTxdForVanillaModel failed for model %u (parent changed), deferring", usModelId)); + QueuePendingReplacement(usModelId, pReplacementTextures, 0, 0); + return false; + } + } + } + else + { + // Reapply path for vanilla models: keep using the isolated slot if it still exists. + auto itIsolated = g_IsolatedTxdByModel.find(usModelId); + if (itIsolated != g_IsolatedTxdByModel.end()) + { + auto* pTxdPoolSA = static_cast(&pGame->GetPools()->GetTxdPool()); + auto* pChildSlot = pTxdPoolSA ? pTxdPoolSA->GetTextureDictonarySlot(itIsolated->second.usTxdId) : nullptr; + bool bParentLinkWasRepaired = false; + const bool bChildParentLinkReady = pChildSlot && pChildSlot->usParentIndex != static_cast(-1) && + EnsureTxdParentLink(itIsolated->second.usTxdId, itIsolated->second.usParentTxdId, &bParentLinkWasRepaired); + + const unsigned short usModelTxdId = pModelInfo->GetTextureDictionaryID(); + const bool bModelWasOnIsolatedTxd = (usModelTxdId == itIsolated->second.usTxdId); + if (usModelTxdId != itIsolated->second.usTxdId) + { + // Streaming may have reassigned the model back to the shared TXD. + // If the isolated slot is still valid, rebind the model to it. + if (CTxdStore_GetTxd(itIsolated->second.usTxdId) != nullptr) + { + // Verify the child slot has its parent chain linked before binding. + // Without a valid parent chain, SA's texture walk wont find + // non-replaced textures and the model renders partly white. + if (!bChildParentLinkReady) + { + UpdateIsolatedTxdLastUse(usModelId); + if (!g_PendingIsolatedModels.count(usModelId)) + AddPendingIsolatedModel(usModelId); + QueuePendingReplacement(usModelId, pReplacementTextures, 0, 0); + return false; + } + + { + CBaseModelInfoSAInterface* pInterface = pModelInfo->GetInterface(); + if (pInterface) + { + size_t nExtra = pInterface->usNumberOfRefs; + if (pInterface->pRwObject) + nExtra++; + for (size_t i = 0; i < nExtra; i++) + CTxdStore_AddRef(pModelInfo->GetTextureDictionaryID()); + } + } + pModelInfo->SetTextureDictionaryID(itIsolated->second.usTxdId); + UpdateIsolatedTxdLastUse(usModelId); + } + else + { + // Isolated slot was destroyed - release parent pin and remove stale entries. + // Do NOT fall through to shared-TXD import; that would re-create the + // texture mixup this isolation was meant to prevent. + const unsigned short usDestroyedTxdId = itIsolated->second.usTxdId; + CTxdStore_RemoveRef(itIsolated->second.usParentTxdId); + auto itOwner = g_IsolatedModelByTxd.find(usDestroyedTxdId); + if (itOwner != g_IsolatedModelByTxd.end() && itOwner->second == usModelId) + { + RemoveTxdFromReplacementTracking(usDestroyedTxdId); + g_IsolatedModelByTxd.erase(itOwner); + } + ClearIsolatedTxdLastUse(usModelId); + ClearPendingIsolatedModel(usModelId); + g_IsolatedTxdByModel.erase(itIsolated); + QueuePendingReplacement(usModelId, pReplacementTextures, 0, 0); + return false; + } + } + else if (CTxdStore_GetTxd(usModelTxdId) == nullptr) + { + // Isolated dict was destroyed while model still points to it. + // Restore the model to its parent TXD before releasing the pin so it doesnst remain pointed at the dead slot. + const unsigned short usParentTxdId = itIsolated->second.usParentTxdId; + auto itOwner = g_IsolatedModelByTxd.find(usModelTxdId); + if (itOwner != g_IsolatedModelByTxd.end() && itOwner->second == usModelId) + { + RemoveTxdFromReplacementTracking(usModelTxdId); + g_IsolatedModelByTxd.erase(itOwner); + } + if (pModelInfo->GetTextureDictionaryID() == usModelTxdId) + { + if (!TryRestoreAndSwitchModelToTxd(pModelInfo, usModelId, usModelTxdId, usParentTxdId)) + { + QueuePendingReplacement(usModelId, pReplacementTextures, 0, 0); + return false; + } + } + CTxdStore_RemoveRef(usParentTxdId); + ClearIsolatedTxdLastUse(usModelId); + ClearPendingIsolatedModel(usModelId); + g_IsolatedTxdByModel.erase(itIsolated); + QueuePendingReplacement(usModelId, pReplacementTextures, 0, 0); + return false; + } + else if (!bChildParentLinkReady) + { + UpdateIsolatedTxdLastUse(usModelId); + if (!g_PendingIsolatedModels.count(usModelId)) + AddPendingIsolatedModel(usModelId); + QueuePendingReplacement(usModelId, pReplacementTextures, 0, 0); + return false; + } + + if (bParentLinkWasRepaired && bModelWasOnIsolatedTxd) + RebindLoadedModelToCurrentTxd(pModelInfo, itIsolated->second.usTxdId); + + itIsolated->second.bNeedsVehicleFallback = ShouldUseVehicleTxdFallback(usModelId); + } + else + { + // Isolation entry was lost (cleanup ran between import and + // reapply). Defer so re-isolation can run on the next try. + QueuePendingReplacement(usModelId, pReplacementTextures, 0, 0); + return false; + } + } + } + + if (pReplacementTextures->uiSessionId != ms_uiTextureReplacingSession) + { + RemoveReplacementFromTracking(pReplacementTextures); + pReplacementTextures->uiSessionId = ms_uiTextureReplacingSession; + pReplacementTextures->textures.clear(); + pReplacementTextures->perTxdList.clear(); + pReplacementTextures->usedInTxdIds.clear(); + pReplacementTextures->usedInModelIds.clear(); + pReplacementTextures->bHasRequestedSpace = false; + } + + CModelTexturesInfo* pInfo = GetModelTexturesInfo(usModelId, "ModelInfoTXDAddTextures-first"); + if (!pInfo) + { + if (!pModelInfo) + { + AddReportLog(9401, SString("ModelInfoTXDAddTextures: No model info for model %u", usModelId)); + return false; + } + + pModelInfo->Request(BLOCKING, "CRenderWareSA::ModelInfoTXDAddTextures"); + + pInfo = GetModelTexturesInfo(usModelId, "ModelInfoTXDAddTextures-after-blocking"); + if (!pInfo) + { + AddReportLog(9401, SString("ModelInfoTXDAddTextures: GetModelTexturesInfo failed after blocking request for model %u (txdId=%u)", usModelId, + pModelInfo->GetTextureDictionaryID())); + return false; + } + } + + RwTexDictionary* pCurrentTxd = CTxdStore_GetTxd(pInfo->usTxdId); + RwTexDictionary* pOldTxd = pInfo->pTxd; + + bool bNeedTxdUpdate = false; + if (!pOldTxd) + { + if (!pCurrentTxd) + { + AddReportLog(9401, SString("ModelInfoTXDAddTextures: Both pOldTxd and pCurrentTxd are null for model %u txdId=%u", usModelId, pInfo->usTxdId)); + return false; + } + + bNeedTxdUpdate = true; + pOldTxd = nullptr; + } + else if (pOldTxd != pCurrentTxd) + { + bNeedTxdUpdate = true; + } + + bool bReplacementPresent = false; + bool bBuiltTxdTextureMap = false; + bool bProcessed = false; + TxdTextureMap txdTextureMap; + RwTexDictionary* pTxdToCheck = nullptr; + + if (pReplacementTextures->usedInTxdIds.find(pInfo->usTxdId) != pReplacementTextures->usedInTxdIds.end()) + { + auto itPerTxd = std::find_if(pReplacementTextures->perTxdList.begin(), pReplacementTextures->perTxdList.end(), + [pInfo](const SReplacementTextures::SPerTxd& entry) { return entry.usTxdId == pInfo->usTxdId; }); + + if (itPerTxd != pReplacementTextures->perTxdList.end()) + { + pTxdToCheck = pCurrentTxd ? pCurrentTxd : pInfo->pTxd; + + const std::unordered_set* pOriginalTextures = &pInfo->originalTextures; + std::unordered_set currentOriginalTextures; + if (bNeedTxdUpdate && pCurrentTxd) + { + CRenderWareSA::GetTxdTextures(currentOriginalTextures, pCurrentTxd); + pOriginalTextures = ¤tOriginalTextures; + } + + for (RwTexture* pTex : itPerTxd->usingTextures) + { + if (!IsReadableTexture(pTex)) + continue; + + if (strnlen(pTex->name, RW_TEXTURE_NAME_LENGTH) >= RW_TEXTURE_NAME_LENGTH) + continue; + + if (pTxdToCheck && pTex->txd == pTxdToCheck) + { + bReplacementPresent = true; + break; + } + + if (pTxdToCheck) + { + if (!bBuiltTxdTextureMap) + { + BuildTxdTextureMapFast(pTxdToCheck, txdTextureMap); + bBuiltTxdTextureMap = true; + } + + auto itFound = txdTextureMap.find(pTex->name); + RwTexture* pFound = (itFound != txdTextureMap.end()) ? itFound->second : nullptr; + if (pFound && pOriginalTextures->find(pFound) == pOriginalTextures->end()) + { + bReplacementPresent = true; + break; + } + } + + bProcessed = true; + } + } + else + { + bProcessed = true; + } + + if (bReplacementPresent) + { + if (bNeedTxdUpdate && pCurrentTxd) + pInfo->pTxd = pCurrentTxd; + + pReplacementTextures->usedInModelIds.insert(usModelId); + pReplacementTextures->pendingOnModelIds.erase(usModelId); + return true; + } + + if (itPerTxd != pReplacementTextures->perTxdList.end()) + { + ForEachShaderReg(pReplacementTextures, itPerTxd->usTxdId, + [usTxdId = itPerTxd->usTxdId](CD3DDUMMY* pD3D) { RemoveShaderEntryByD3DData(usTxdId, pD3D); }); + ClearShaderRegs(pReplacementTextures, itPerTxd->usTxdId); + + if (!bNeedTxdUpdate) + { + AddReportLog(9401, SString("ModelInfoTXDAddTextures: Stale replacement cleanup return false for model %u txdId=%u", usModelId, pInfo->usTxdId)); + pReplacementTextures->perTxdList.erase(itPerTxd); + pReplacementTextures->usedInTxdIds.erase(pInfo->usTxdId); + ListRemove(pInfo->usedByReplacements, pReplacementTextures); + return false; + } + + pReplacementTextures->usedInTxdIds.erase(pInfo->usTxdId); + ListRemove(pInfo->usedByReplacements, pReplacementTextures); + + TextureSwapMap swapMap; + swapMap.reserve(itPerTxd->usingTextures.size()); + const bool bCurrentTxdOk = pCurrentTxd != nullptr; + + const bool bCanReuseMap = bBuiltTxdTextureMap && pTxdToCheck == pCurrentTxd; + if (bCurrentTxdOk && !bCanReuseMap) + { + txdTextureMap.clear(); + BuildTxdTextureMapFast(pCurrentTxd, txdTextureMap); + } + TxdTextureMap& currentTxdTextureMap = txdTextureMap; + + TxdTextureMap parentTxdTextureMap; + if (bCurrentTxdOk) + { + auto& txdPoolAdd = pGame->GetPools()->GetTxdPool(); + if (auto* pTxdPoolAdd = static_cast(&txdPoolAdd)) + { + if (auto* pSlot = pTxdPoolAdd->GetTextureDictonarySlot(pInfo->usTxdId)) + { + unsigned short usParent = pSlot->usParentIndex; + if (usParent != static_cast(-1)) + { + RwTexDictionary* pParentTxd = CTxdStore_GetTxd(usParent); + + // Load parent TXD if models with geometry need texture restoration + if (!pParentTxd && pGame->GetStreaming()) + { + bool bNeedRestore = false; + for (unsigned short modelId : pReplacementTextures->usedInModelIds) + { + if (auto* pMi = static_cast(pGame->GetModelInfo(modelId))) + { + if (pMi->GetRwObject()) + { + bNeedRestore = true; + break; + } + } + } + + if (bNeedRestore) + { + const int iBaseIDforTXD = pGame->GetBaseIDforTXD(); + if (iBaseIDforTXD > 0) + { + const unsigned int uiTxdStreamId = usParent + static_cast(iBaseIDforTXD); + pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(true, "ModelInfoTXDAddTextures-parentTxd"); + pParentTxd = CTxdStore_GetTxd(usParent); + } + } + } + + if (pParentTxd) + BuildTxdTextureMapFast(pParentTxd, parentTxdTextureMap); + } + } + } + + if (ShouldUseVehicleTxdFallback(usModelId)) + AddVehicleTxdFallback(parentTxdTextureMap); + } + + for (std::size_t idx = 0; idx < itPerTxd->usingTextures.size(); ++idx) + { + RwTexture* pStaleReplacement = itPerTxd->usingTextures[idx]; + if (!pStaleReplacement) + continue; + + RwTexture* pFreshOriginal = nullptr; + if (bCurrentTxdOk && strnlen(pStaleReplacement->name, RW_TEXTURE_NAME_LENGTH) < RW_TEXTURE_NAME_LENGTH) + { + auto itFound = currentTxdTextureMap.find(pStaleReplacement->name); + pFreshOriginal = (itFound != currentTxdTextureMap.end()) ? itFound->second : nullptr; + + if (!pFreshOriginal && !parentTxdTextureMap.empty()) + { + auto itParent = parentTxdTextureMap.find(pStaleReplacement->name); + if (itParent != parentTxdTextureMap.end() && IsReadableTexture(itParent->second)) + pFreshOriginal = itParent->second; + + if (!pFreshOriginal) + { + const char* szInternal = CRenderWareSA::GetInternalTextureName(pStaleReplacement->name); + if (szInternal && strcmp(szInternal, pStaleReplacement->name) != 0) + { + auto itInt = parentTxdTextureMap.find(szInternal); + if (itInt != parentTxdTextureMap.end() && IsReadableTexture(itInt->second)) + pFreshOriginal = itInt->second; + } + } + } + } + + if (pFreshOriginal) + swapMap[pStaleReplacement] = pFreshOriginal; + } + + std::unordered_set texturesStillReferenced; + for (RwTexture* pTex : itPerTxd->usingTextures) + { + if (pTex && swapMap.find(pTex) == swapMap.end()) + texturesStillReferenced.insert(pTex); + } + + if (!swapMap.empty()) + { + std::unordered_set targetModels; + for (unsigned short modelId : pReplacementTextures->usedInModelIds) + { + CModelInfoSA* pModelInfo = static_cast(pGame->GetModelInfo(modelId)); + if (!pModelInfo || !pModelInfo->GetRwObject()) + continue; + targetModels.insert(pModelInfo); + } + + for (CModelInfoSA* pModelInfo : targetModels) + ReplaceTextureInModel(pModelInfo, swapMap); + } + + std::unordered_set copiesToDestroy; + std::unordered_set originalsToDestroy; + CleanupStalePerTxd(*itPerTxd, pOldTxd, pReplacementTextures, nullptr, copiesToDestroy, originalsToDestroy); + + for (RwTexture* pTexture : copiesToDestroy) + { + if (!pTexture) + continue; + + if (texturesStillReferenced.find(pTexture) != texturesStillReferenced.end()) + continue; + + if (CanDestroyOrphanedTexture(pTexture)) + { + SafeDestroyTexture(pTexture); + } + } + + for (RwTexture* pTexture : originalsToDestroy) + { + if (!pTexture) + continue; + + if (texturesStillReferenced.find(pTexture) != texturesStillReferenced.end()) + continue; + + if (CanDestroyOrphanedTexture(pTexture)) + RwTextureDestroy(pTexture); + } + + pReplacementTextures->perTxdList.erase(itPerTxd); + } + + if (bNeedTxdUpdate && pCurrentTxd) + { + pInfo->pTxd = pCurrentTxd; + if (pInfo->usedByReplacements.empty()) + PopulateOriginalTextures(*pInfo, pCurrentTxd); + } + } + + pReplacementTextures->perTxdList.emplace_back(); + SReplacementTextures::SPerTxd& perTxdInfo = pReplacementTextures->perTxdList.back(); + + perTxdInfo.usTxdId = pInfo->usTxdId; + perTxdInfo.bTexturesAreCopies = !pReplacementTextures->usedInTxdIds.empty(); + perTxdInfo.strDebugSource = BuildReplacementTag(pReplacementTextures); + perTxdInfo.strDebugHash = pReplacementTextures->strDebugHash; + + pInfo->strDebugLabel = perTxdInfo.strDebugSource; + + if (!perTxdInfo.bTexturesAreCopies && pGame->GetStreaming()) // Request VRAM space + { + if (!pReplacementTextures->bHasRequestedSpace) + { + uint32_t uiTotalSize = 0; + uint32_t uiTexturesWithValidRaster = 0; + for (RwTexture* pNewTexture : pReplacementTextures->textures) + { + if (pNewTexture && pNewTexture->raster) + { + if (pNewTexture->raster->width == 0 || pNewTexture->raster->height == 0) + continue; + + uiTexturesWithValidRaster++; + auto NextPow2 = [](uint32_t v) + { + uint32_t p = 1; + while (p < v && p < MAX_TEXTURE_DIMENSION) + p <<= 1; + return p; + }; + + uint64_t size = (uint64_t)NextPow2(pNewTexture->raster->width) * (uint64_t)NextPow2(pNewTexture->raster->height) * 4; + + if (pNewTexture->raster->numLevels > 1) + size += size / 3; + + if (size > MAX_VRAM_SIZE) + size = MAX_VRAM_SIZE; + + if ((uint64_t)uiTotalSize + size > MAX_VRAM_SIZE) + uiTotalSize = MAX_VRAM_SIZE; + else + uiTotalSize += (uint32_t)size; + } + } + + if (uiTexturesWithValidRaster > 0 && uiTotalSize == 0) + uiTotalSize = 1024 * 1024; + + if (uiTotalSize > 0) + { + pGame->GetStreaming()->MakeSpaceFor(uiTotalSize); + pReplacementTextures->bHasRequestedSpace = true; + } + } + } + + for (RwTexture* pNewTexture : pReplacementTextures->textures) + { + if (!IsReadableTexture(pNewTexture)) + continue; + + RwRaster* pRaster = pNewTexture->raster; + const bool bRasterOk = pRaster != nullptr; + + if (bRasterOk && (pRaster->width == 0 || pRaster->height == 0)) + continue; + + if (perTxdInfo.bTexturesAreCopies) + { + if (!bRasterOk) + continue; + + // Reuse the given texture's raster + RwTexture* pCopyTex = RwTextureCreate(pRaster); + if (!pCopyTex) + continue; + + pCopyTex->TXDList.next = &pCopyTex->TXDList; + pCopyTex->TXDList.prev = &pCopyTex->TXDList; + pCopyTex->txd = nullptr; + + strncpy(pCopyTex->name, pNewTexture->name, RW_TEXTURE_NAME_LENGTH - 1); + pCopyTex->name[RW_TEXTURE_NAME_LENGTH - 1] = '\0'; + strncpy(pCopyTex->mask, pNewTexture->mask, RW_TEXTURE_NAME_LENGTH - 1); + pCopyTex->mask[RW_TEXTURE_NAME_LENGTH - 1] = '\0'; + pCopyTex->flags = pNewTexture->flags; + + pNewTexture = pCopyTex; + } + perTxdInfo.usingTextures.push_back(pNewTexture); + } + + perTxdInfo.replacedOriginals.resize(perTxdInfo.usingTextures.size(), nullptr); + + const auto& masterTexturesVec = pReplacementTextures->textures; + const auto masterTexturesSet = MakeTextureSet(masterTexturesVec); + auto IsMasterTexture = [&masterTexturesSet](RwTexture* pTex) -> bool { return masterTexturesSet.count(pTex) != 0; }; + + RwTexDictionary* const pTargetTxd = pInfo->pTxd; + const bool bTargetTxdOk = pTargetTxd != nullptr; + TxdTextureMap targetTxdTextureMap; + BuildTxdTextureMapFast(pTargetTxd, targetTxdTextureMap); + + TxdTextureMap parentTxdTextureMapForAdd; + RwTexDictionary* pParentTxdForAdd = nullptr; + if (bTargetTxdOk) + { + auto& txdPoolForAdd = pGame->GetPools()->GetTxdPool(); + if (auto* pTxdPoolForAdd = static_cast(&txdPoolForAdd)) + { + if (auto* pSlotForAdd = pTxdPoolForAdd->GetTextureDictonarySlot(pInfo->usTxdId)) + { + unsigned short usParentForAdd = pSlotForAdd->usParentIndex; + if (usParentForAdd != static_cast(-1)) + { + pParentTxdForAdd = CTxdStore_GetTxd(usParentForAdd); + if (pParentTxdForAdd) + BuildTxdTextureMapFast(pParentTxdForAdd, parentTxdTextureMapForAdd); + } + } + } + + if (ShouldUseVehicleTxdFallback(usModelId)) + AddVehicleTxdFallback(parentTxdTextureMapForAdd); + } + + bool anyAdded = false; + for (std::size_t idx = 0; idx < perTxdInfo.usingTextures.size(); ++idx) + { + RwTexture* pNewTexture = perTxdInfo.usingTextures[idx]; + if (!pNewTexture) + continue; + + if (strnlen(pNewTexture->name, RW_TEXTURE_NAME_LENGTH) >= RW_TEXTURE_NAME_LENGTH) + continue; + + auto itExisting = targetTxdTextureMap.find(pNewTexture->name); + RwTexture* pExistingTexture = (itExisting != targetTxdTextureMap.end()) ? itExisting->second : nullptr; + bool bExistingFromParent = false; + + if (!pExistingTexture && !parentTxdTextureMapForAdd.empty()) + { + auto itParent = parentTxdTextureMapForAdd.find(pNewTexture->name); + if (itParent != parentTxdTextureMapForAdd.end() && IsReadableTexture(itParent->second)) + { + pExistingTexture = itParent->second; + bExistingFromParent = true; + } + } + + if (!pExistingTexture) // Try internal name (remap -> #emap) + { + const char* szInternalName = GetInternalTextureName(pNewTexture->name); + if (szInternalName && strcmp(szInternalName, pNewTexture->name) != 0) + { + auto itInternal = targetTxdTextureMap.find(szInternalName); + RwTexture* pInternalTexture = (itInternal != targetTxdTextureMap.end()) ? itInternal->second : nullptr; + + if (!pInternalTexture && !parentTxdTextureMapForAdd.empty()) + { + auto itParentInt = parentTxdTextureMapForAdd.find(szInternalName); + if (itParentInt != parentTxdTextureMapForAdd.end() && IsReadableTexture(itParentInt->second)) + { + pInternalTexture = itParentInt->second; + bExistingFromParent = true; + } + } + + if (pInternalTexture) + { + pExistingTexture = pInternalTexture; + + if (!perTxdInfo.bTexturesAreCopies) // Create copy to preserve master + { + if (pNewTexture->raster) + { + RwTexture* pCopyTex = RwTextureCreate(pNewTexture->raster); + if (pCopyTex) + { + pCopyTex->TXDList.next = &pCopyTex->TXDList; + pCopyTex->TXDList.prev = &pCopyTex->TXDList; + pCopyTex->txd = nullptr; + + strncpy(pCopyTex->name, szInternalName, RW_TEXTURE_NAME_LENGTH - 1); + pCopyTex->name[RW_TEXTURE_NAME_LENGTH - 1] = '\0'; + strncpy(pCopyTex->mask, pNewTexture->mask, RW_TEXTURE_NAME_LENGTH - 1); + pCopyTex->mask[RW_TEXTURE_NAME_LENGTH - 1] = '\0'; + pCopyTex->flags = pNewTexture->flags; + + pNewTexture = pCopyTex; + perTxdInfo.usingTextures[idx] = pCopyTex; + } + } + } + else + { + // Already a copy, safe to rename + strncpy(pNewTexture->name, szInternalName, RW_TEXTURE_NAME_LENGTH - 1); + pNewTexture->name[RW_TEXTURE_NAME_LENGTH - 1] = '\0'; + } + } + } + } + + SafeOrphanTexture(pNewTexture); + if (pNewTexture->txd != nullptr) + { + perTxdInfo.usingTextures[idx] = nullptr; + continue; + } + + bool bRemovedExisting = false; + if (pExistingTexture) + { + constexpr uint32_t rwTEXTUREADDRESSMASK = 0xFF00; + pNewTexture->flags = (pNewTexture->flags & ~rwTEXTUREADDRESSMASK) | (pExistingTexture->flags & rwTEXTUREADDRESSMASK); + + if (bTargetTxdOk && pExistingTexture->txd == pTargetTxd) + { + CRenderWareSA::RwTexDictionaryRemoveTexture(pTargetTxd, pExistingTexture); + bRemovedExisting = (pExistingTexture->txd == nullptr); + + if (bRemovedExisting && strnlen(pExistingTexture->name, RW_TEXTURE_NAME_LENGTH) < RW_TEXTURE_NAME_LENGTH) + targetTxdTextureMap.erase(pExistingTexture->name); + } + } + + if (pExistingTexture && bTargetTxdOk && pExistingTexture->txd == pTargetTxd && !bRemovedExisting) + { + bool bIsCopyTexture = perTxdInfo.bTexturesAreCopies || !IsMasterTexture(pNewTexture); + if (bIsCopyTexture && CanDestroyOrphanedTexture(pNewTexture)) + { + SafeDestroyTexture(pNewTexture); + } + + perTxdInfo.usingTextures[idx] = nullptr; + continue; + } + + RwTexture* pOriginalToRestore = nullptr; + if (pExistingTexture && (bRemovedExisting || bExistingFromParent)) + { + if (pInfo->originalTextures.find(pExistingTexture) != pInfo->originalTextures.end()) + { + pOriginalToRestore = pExistingTexture; + } + else if (bExistingFromParent && IsReadableTexture(pExistingTexture)) + { + pOriginalToRestore = pExistingTexture; + } + else + { + const std::size_t nameLen = strnlen(pExistingTexture->name, RW_TEXTURE_NAME_LENGTH); + if (nameLen < RW_TEXTURE_NAME_LENGTH) + { + auto itByName = pInfo->originalTexturesByName.find(LowercaseTextureName(pExistingTexture->name, nameLen)); + if (itByName != pInfo->originalTexturesByName.end() && itByName->second) + { + RwTexture* pFoundOriginal = itByName->second; + if (IsReadableTexture(pFoundOriginal)) + pOriginalToRestore = pFoundOriginal; + } + } + } + } + perTxdInfo.replacedOriginals[idx] = pOriginalToRestore; + + dassert(!RwTexDictionaryContainsTexture(pTargetTxd, pNewTexture)); + if (!bTargetTxdOk || !RwTexDictionaryAddTexture(pTargetTxd, pNewTexture)) + { + SString strError("RwTexDictionaryAddTexture failed for texture: %s in TXD %u", pNewTexture->name, pInfo->usTxdId); + WriteDebugEvent(strError); + AddReportLog(9401, strError); + + if (bRemovedExisting) + { + SafeOrphanTexture(pExistingTexture); + if (pExistingTexture->txd != nullptr || !bTargetTxdOk || !RwTexDictionaryAddTexture(pTargetTxd, pExistingTexture)) + { + WriteDebugEvent("Failed to restore original texture after add failure"); + + bool bIsOriginal = pInfo->originalTextures.find(pExistingTexture) != pInfo->originalTextures.end(); + + if (bIsOriginal) + perTxdInfo.replacedOriginals[idx] = pExistingTexture; // Keep for cleanup + } + else + { + perTxdInfo.replacedOriginals[idx] = nullptr; + if (strnlen(pExistingTexture->name, RW_TEXTURE_NAME_LENGTH) < RW_TEXTURE_NAME_LENGTH) + targetTxdTextureMap[pExistingTexture->name] = pExistingTexture; + } + } + + // Destroy copies to prevent leaks (never destroy masters) + bool bIsCopyTexture = perTxdInfo.bTexturesAreCopies || !IsMasterTexture(pNewTexture); + + if (bIsCopyTexture) + { + if (CanDestroyOrphanedTexture(pNewTexture)) + { + SafeDestroyTexture(pNewTexture); // Handles raster nullification safely + } + } + perTxdInfo.usingTextures[idx] = nullptr; + continue; + } + + if (strnlen(pNewTexture->name, RW_TEXTURE_NAME_LENGTH) < RW_TEXTURE_NAME_LENGTH) + { + targetTxdTextureMap.erase(pNewTexture->name); + targetTxdTextureMap[pNewTexture->name] = pNewTexture; + } + anyAdded = true; + } + + if (!anyAdded) + { + SString strDebug = SString( + "ModelInfoTXDAddTextures: No textures were added to TXD %d for model %d (pTargetTxd=%p bTargetTxdOk=%d usingTextures.size=%u textures.size=%u)", + pInfo->usTxdId, usModelId, pTargetTxd, bTargetTxdOk ? 1 : 0, (unsigned)perTxdInfo.usingTextures.size(), + (unsigned)pReplacementTextures->textures.size()); + WriteDebugEvent(strDebug); + AddReportLog(9401, strDebug); + + perTxdInfo.usingTextures.clear(); + perTxdInfo.replacedOriginals.clear(); + pReplacementTextures->perTxdList.pop_back(); + pReplacementTextures->bHasRequestedSpace = false; + + if (pInfo->usedByReplacements.empty() && !pInfo->bHasLeakedTextures) + { + pInfo->originalTextures.clear(); + pInfo->originalTexturesByName.clear(); + if (CTxdStore_GetNumRefs(pInfo->usTxdId) > 0) + CRenderWareSA::DebugTxdRemoveRef(pInfo->usTxdId, "ModelInfoTXDAddTextures-fail-cleanup"); + MapRemove(ms_ModelTexturesInfoMap, pInfo->usTxdId); + } + return false; + } + + pReplacementTextures->usedInTxdIds.insert(pInfo->usTxdId); + dassert(std::find(pInfo->usedByReplacements.begin(), pInfo->usedByReplacements.end(), pReplacementTextures) == pInfo->usedByReplacements.end()); + pInfo->usedByReplacements.push_back(pReplacementTextures); + + pReplacementTextures->usedInModelIds.insert(usModelId); + pReplacementTextures->pendingOnModelIds.erase(usModelId); + + TextureSwapMap parentSwapMap; + for (std::size_t idx = 0; idx < perTxdInfo.usingTextures.size(); ++idx) + { + RwTexture* pNewTexture = perTxdInfo.usingTextures[idx]; + RwTexture* pOriginal = (idx < perTxdInfo.replacedOriginals.size()) ? perTxdInfo.replacedOriginals[idx] : nullptr; + + if (pNewTexture && pNewTexture->txd == pInfo->pTxd) + { + CD3DDUMMY* pD3D = AddTextureToShaderSystem(pInfo->usTxdId, pNewTexture); + if (pD3D) + GetShaderRegList(pReplacementTextures, pInfo->usTxdId).push_back(pD3D); + + if (pOriginal && pOriginal != pNewTexture && pOriginal->txd != pInfo->pTxd) + parentSwapMap[pOriginal] = pNewTexture; + } + } + + if (!parentSwapMap.empty()) + { + if (auto* pModelInfoForSwap = static_cast(pGame->GetModelInfo(usModelId))) + ReplaceTextureInModel(pModelInfoForSwap, parentSwapMap); + } + + // When textures go into a shared TXD (model not isolated), all other + // models on the same slot see them through SA's texture walk. Track + // those models so the remove and reapply paths cover the full set. + if (g_IsolatedTxdByModel.count(usModelId) == 0) + { + const auto& sharedModels = GetModelsForTxd(pInfo->usTxdId); + for (unsigned short usSharedModelId : sharedModels) + { + if (usSharedModelId == usModelId) + continue; + if (pReplacementTextures->usedInModelIds.count(usSharedModelId)) + continue; + if (g_IsolatedTxdByModel.count(usSharedModelId)) + continue; + + pReplacementTextures->usedInModelIds.insert(usSharedModelId); + + if (!parentSwapMap.empty()) + { + if (auto* pSharedMI = static_cast(pGame->GetModelInfo(usSharedModelId))) + { + if (pSharedMI->GetRwObject()) + ReplaceTextureInModel(pSharedMI, parentSwapMap); + } + } + } + } + + if (g_IsolatedTxdByModel.count(usModelId) > 0) + UpdateIsolatedTxdLastUse(usModelId); + + // Invalidate cache for modified TXD + InvalidateTxdTextureMapCache(pInfo->usTxdId); + + return true; +} + +// Clean up isolated TXD slot for model (destroy copy textures, clear bookkeeping) +// bSkipStreamingLoads: When true, skip blocking streaming loads (use during session reset when streaming system may be unsafe) +void CRenderWareSA::CleanupIsolatedTxdForModel(unsigned short usModelId, bool bSkipStreamingLoads) +{ + if (!pGame) + return; + + ClearIsolatedTxdLastUse(usModelId); + + auto itModelInfo = g_IsolatedTxdByModel.find(usModelId); + if (itModelInfo == g_IsolatedTxdByModel.end()) + { + ClearPendingIsolatedModel(usModelId); + return; + } + + const unsigned short usParentTxdId = itModelInfo->second.usParentTxdId; + const unsigned short usIsolatedTxdId = itModelInfo->second.usTxdId; + const bool bNeedsVehicleFallback = itModelInfo->second.bNeedsVehicleFallback; + + // Check if model has loaded geometry that needs texture restoration. + // If not loaded, there's no geometry to restore textures for, so we can skip + // the parent TXD load and texture swap.. then, only bookkeeping cleanup is needed. + auto* pModelInfoForRestore = static_cast(pGame->GetModelInfo(usModelId)); + const bool bModelHasGeometry = pModelInfoForRestore && pModelInfoForRestore->GetRwObject(); + + RwTexDictionary* pParentTxd = CTxdStore_GetTxd(usParentTxdId); + + // Request parent TXD to load if not already loaded - required for texture restoration. + // Without this, restoration fails when parent TXD is unloaded, leaving model geometry + // with dangling texture pointers that later get their rasters nullified, causing white textures. + // Only needed when model has loaded geometry whose textures need restoring. + // Skip during session reset (bSkipStreamingLoads) when streaming system may be in shutdown state. + if (!pParentTxd && bModelHasGeometry && !bSkipStreamingLoads && pGame->GetStreaming()) + { + const int iBaseIDforTXD = pGame->GetBaseIDforTXD(); + if (iBaseIDforTXD > 0) + { + const unsigned int uiTxdStreamId = usParentTxdId + static_cast(iBaseIDforTXD); + pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(true, "CleanupIsolatedTxdForModel-parentTxd"); + pParentTxd = CTxdStore_GetTxd(usParentTxdId); + } + } + + // When parent TXD is unavailable and model has loaded geometry, material + // restoration can't run (swap map will be empty). Keep replacement texture + // rasters alive in that case so the model doesn't go white; the orphaned + // textures leak (refCount=1, unreachable) until process exit, matching the + // normal cleanup path where copies also leak with refCount=1. + const bool bSkipRasterNull = !pParentTxd && bModelHasGeometry; + + if (bSkipRasterNull && ShouldLog(g_uiLastIsolationFailLogTime)) + { + AddReportLog(9402, + SString("CleanupIsolatedTxdForModel: parent TXD %u unavailable for model %u with geometry, keeping rasters", usParentTxdId, usModelId)); + } + + TxdTextureMap parentTxdTextureMap; + if (pParentTxd) + MergeCachedTxdTextureMap(usParentTxdId, pParentTxd, parentTxdTextureMap); + + if (bNeedsVehicleFallback) + AddVehicleTxdFallback(parentTxdTextureMap); + + // Restore original textures in model geometry BEFORE removing from shared TXD. + // Without this, material->texture pointers become dangling when the shared TXD is destroyed. + // For isolated TXDs, replacedOriginals may be empty because the child TXD started empty. + // In that case, look up originals from the parent TXD by texture name. + auto itInfo = ms_ModelTexturesInfoMap.find(usIsolatedTxdId); + if (itInfo != ms_ModelTexturesInfoMap.end()) + { + CModelTexturesInfo& info = itInfo->second; + for (SReplacementTextures* pReplacement : info.usedByReplacements) + { + if (!pReplacement) + continue; + + auto itPerTxd = std::find_if(pReplacement->perTxdList.begin(), pReplacement->perTxdList.end(), + [usIsolatedTxdId](const SReplacementTextures::SPerTxd& entry) { return entry.usTxdId == usIsolatedTxdId; }); + + if (itPerTxd != pReplacement->perTxdList.end()) + { + TextureSwapMap swapMap; + for (size_t idx = 0; idx < itPerTxd->usingTextures.size(); ++idx) + { + RwTexture* pReplacementTex = itPerTxd->usingTextures[idx]; + if (!pReplacementTex || !IsReadableTexture(pReplacementTex)) + continue; + + // First try stored original (non-isolated TXDs or re-replacement scenarios) + RwTexture* pOriginalTex = (idx < itPerTxd->replacedOriginals.size()) ? itPerTxd->replacedOriginals[idx] : nullptr; + + if (!pOriginalTex && pParentTxd && strnlen(pReplacementTex->name, RW_TEXTURE_NAME_LENGTH) < RW_TEXTURE_NAME_LENGTH) + { + auto itParent = parentTxdTextureMap.find(pReplacementTex->name); + if (itParent != parentTxdTextureMap.end()) + pOriginalTex = itParent->second; + } + + if (pOriginalTex && IsReadableTexture(pOriginalTex)) + swapMap[pReplacementTex] = pOriginalTex; + } + + if (!swapMap.empty()) + { + if (auto* pModelInfo = static_cast(pGame->GetModelInfo(usModelId))) + ReplaceTextureInModel(pModelInfo, swapMap); + } + } + } + } + + // Hold a safety ref to keep the TXD alive during cleanup and orphaning. + // Without this, freed rasters get dereferenced during orphaning > heap corruption. + const bool bIsolatedSlotValid = CTxdStore_GetTxd(usIsolatedTxdId) != nullptr; + if (bIsolatedSlotValid) + CTxdStore_AddRef(usIsolatedTxdId); + + // Revert model TXD back to parent + if (auto* pModelInfo = static_cast(pGame->GetModelInfo(usModelId))) + { + if (pModelInfo->GetTextureDictionaryID() == usIsolatedTxdId) + { + // SetTextureDictionaryID removes usNumberOfRefs + (pRwObject ? 1 : 0) + // refs from the old TXD. If the model gained refs after its TXD assignment, + // the removal can exceed what was originally added, causing underflow. + // Adding the same count here lets SetTextureDictionaryID use them safely. + if (bIsolatedSlotValid) + { + CBaseModelInfoSAInterface* pInterface = pModelInfo->GetInterface(); + if (pInterface) + { + size_t nExtra = pInterface->usNumberOfRefs; + if (pInterface->pRwObject) + nExtra++; + for (size_t i = 0; i < nExtra; i++) + CTxdStore_AddRef(usIsolatedTxdId); + } + } + pModelInfo->SetTextureDictionaryID(usParentTxdId); + + // SetTextureDictionaryID handles ref transfer even when the target + // TXD data isn't loaded (null rwTexDictonary). But if it bailed + // (e.g. parent slot is freed and re-allocated as free), detect the + // skip and transfer refs manually so the isolated slot can be freed. + if (CTxdStore_GetTxd(usParentTxdId) == nullptr && !pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(usParentTxdId)) + { + CBaseModelInfoSAInterface* pInterface = pModelInfo->GetInterface(); + if (pInterface && pInterface->usTextureDictionary != usParentTxdId) + { + // SetTextureDictionaryID bailed without changing the field. + // Force the field and transfer refs manually. + pInterface->usTextureDictionary = usParentTxdId; + + size_t referencesCount = pInterface->usNumberOfRefs; + if (pInterface->pRwObject) + referencesCount++; + + // AddRef parent to match what SetTextureDictionaryID would have done. + // Safe even with null RW dict - operates on the pool entry's ref count. + for (size_t i = 0; i < referencesCount; i++) + CTxdStore_AddRef(usParentTxdId); + + // RemoveRef isolated to release the model's contribution. + // Guarded by bIsolatedSlotValid to match the safety ref pattern.. + // the safety ref keeps refs above 0 during this loop. + if (bIsolatedSlotValid) + { + for (size_t i = 0; i < referencesCount; i++) + CTxdStore_RemoveRef(usIsolatedTxdId); + } + } + } + + // If neither SetTextureDictionaryID nor the fallback above managed to restore + // the field (e.g. parent slot is freed), force-set it now so the model doesn't + // keep a stale reference to the about-to-be-freed isolated slot. + { + CBaseModelInfoSAInterface* pFinalCheck = pModelInfo->GetInterface(); + if (pFinalCheck && pFinalCheck->usTextureDictionary == usIsolatedTxdId) + pFinalCheck->usTextureDictionary = usParentTxdId; + } + } + } + + // Clear shader system entries for this TXD id + StreamingRemovedTxd(usIsolatedTxdId); + + itInfo = ms_ModelTexturesInfoMap.find(usIsolatedTxdId); + if (itInfo != ms_ModelTexturesInfoMap.end()) + { + CModelTexturesInfo& info = itInfo->second; + RwTexDictionary* pTxd = CTxdStore_GetTxd(usIsolatedTxdId); + const bool bTxdOk = pTxd != nullptr; + + const std::vector usedBy = info.usedByReplacements; + for (SReplacementTextures* pReplacement : usedBy) + { + if (!pReplacement) + continue; + + // Remove per-TXD shader regs and streaming texinfos + ForEachShaderReg(pReplacement, usIsolatedTxdId, [usIsolatedTxdId](CD3DDUMMY* pD3D) { RemoveShaderEntryByD3DData(usIsolatedTxdId, pD3D); }); + ClearShaderRegs(pReplacement, usIsolatedTxdId); + + auto itPerTxd = std::find_if(pReplacement->perTxdList.begin(), pReplacement->perTxdList.end(), + [usIsolatedTxdId](const SReplacementTextures::SPerTxd& entry) { return entry.usTxdId == usIsolatedTxdId; }); + + if (itPerTxd != pReplacement->perTxdList.end()) + { + bool bAnyRasterNulled = false; + for (RwTexture* pTex : itPerTxd->usingTextures) + { + if (!IsReadableTexture(pTex)) + continue; + + bool bWasInIsolatedTxd = (bTxdOk && pTex->txd == pTxd); + if (bWasInIsolatedTxd) + SafeOrphanTexture(pTex, usIsolatedTxdId); + + // Null raster for textures orphaned from this TXD, unless + // parent was unavailable and model has geometry (keep rasters + // to prevent white tex; follows the deferred-cleanup leak pattern). + if (bWasInIsolatedTxd && pTex->txd == nullptr) + { + if (!bSkipRasterNull) + { + if (pTex->raster) + bAnyRasterNulled = true; + pTex->raster = nullptr; + } + else if (pTex->raster) + { + // Only the first texture per raster keeps it alive; + // duplicates are nulled to prevent multiple frees + // when materials are destroyed by the engine. + if (!g_OrphanedCopyRasters.insert(pTex->raster).second) + pTex->raster = nullptr; + else + g_GlobalMtaRasterCache.insert(pTex->raster); + } + } + } + if (bAnyRasterNulled) + InvalidateGlobalMtaRasterCache(); + + itPerTxd->usingTextures.clear(); + itPerTxd->replacedOriginals.clear(); + pReplacement->perTxdList.erase(itPerTxd); + } + + pReplacement->usedInTxdIds.erase(usIsolatedTxdId); + ListRemove(info.usedByReplacements, pReplacement); + } + + info.usedByReplacements.clear(); + info.originalTextures.clear(); + info.originalTexturesByName.clear(); + + if (CTxdStore_GetNumRefs(usIsolatedTxdId) > 1) + CRenderWareSA::DebugTxdRemoveRef(usIsolatedTxdId, "CleanupIsolatedTxdForModel"); + + ms_ModelTexturesInfoMap.erase(itInfo); + } + + // Orphan remaining textures before releasing the safety ref. + // Empties the TXD so GTA's destructor won't try to destroy textures with bad rasters. + bool bOrphanedAll = true; + { + RwTexDictionary* pTxdForOrphan = CTxdStore_GetTxd(usIsolatedTxdId); + if (pTxdForOrphan) + bOrphanedAll = OrphanTxdTexturesBounded(pTxdForOrphan, true); + } + + // Release safety ref; may now allow TXD destruction + if (bIsolatedSlotValid) + CTxdStore_RemoveRef(usIsolatedTxdId); + + auto& txdPool = pGame->GetPools()->GetTxdPool(); + auto* pTxdPoolSA = static_cast(&txdPool); + if (pTxdPoolSA) + { + const bool bPinned = pTxdPoolSA->IsSlotProtectedFromStreaming(usIsolatedTxdId); + const int nPinRefs = bPinned ? 1 : 0; + + // Only remove the slot if the only remaining ref is the MTA pin (or none). + if (CTxdStore_GetNumRefs(usIsolatedTxdId) <= nPinRefs && bOrphanedAll) + { + // Release the MTA ownership pin right before slot removal. + // The hook guard (g_StreamingProtectedTxdSlots) prevents the + // resulting ref-count 0 from triggering CStreaming::RemoveModel; + // RemoveTextureDictonarySlot clears the guard afterwards. + if (bPinned) + CTxdStore_RemoveRef(usIsolatedTxdId); + + // Reset the streaming info for the isolated TXD back to unloaded state + // (or restore the original COL/IPL entry for overflow slots). + if (IsStreamingInfoSlot(usIsolatedTxdId)) + ResetStreamingInfo(usIsolatedTxdId); + + InvalidateTxdTextureMapCache(usIsolatedTxdId); + pTxdPoolSA->RemoveTextureDictonarySlot(usIsolatedTxdId); + MarkTxdPoolCountDirty(); + g_OrphanedIsolatedTxdSlots.erase(usIsolatedTxdId); + } + else + { + // External refs remain or not all textures could be orphaned. + // Keep the MTA pin active so the hook won't trigger + // CStreaming::RemoveModel while the slot is alive. + g_OrphanedIsolatedTxdSlots.insert(usIsolatedTxdId); + } + } + else + { + g_OrphanedIsolatedTxdSlots.insert(usIsolatedTxdId); + } + + ClearPendingIsolatedModel(usModelId); + CTxdStore_RemoveRef(usParentTxdId); // Release parent pin + g_IsolatedTxdByModel.erase(itModelInfo); + std::unordered_map::iterator itOwner = g_IsolatedModelByTxd.find(usIsolatedTxdId); + if (itOwner != g_IsolatedModelByTxd.end() && itOwner->second == usModelId) + g_IsolatedModelByTxd.erase(itOwner); + ClearPendingReplacementStateForModel(usModelId); + g_PendingReplacementByModel.erase(usModelId); +} + +//////////////////////////////////////////////////////////////// +// +// CRenderWareSA::CleanupReplacementsInTxdSlot +// +// Detach all replacement texture tracking from a TXD slot that is about +// to be destroyed (e.g. by RestoreTXD when engineRequestTXD is freed). +// Without this, CClientTXD destructors that run later would access the +// freed TXD via stale perTxdList entries, causing use-after-free. +// +//////////////////////////////////////////////////////////////// +void CRenderWareSA::CleanupReplacementsInTxdSlot(unsigned short usTxdSlotId) +{ + // Release parent pin early so it runs even when ms_ModelTexturesInfoMap + // has no entry (e.g. after RemoveTxdFromReplacementTracking cleared it). + if (g_ScriptTxdSlotsWithParentPin.erase(usTxdSlotId)) + { + auto* pTxdPoolSA = static_cast(&pGame->GetPools()->GetTxdPool()); + auto* pSlot = pTxdPoolSA ? pTxdPoolSA->GetTextureDictonarySlot(usTxdSlotId) : nullptr; + if (pSlot && pSlot->usParentIndex != static_cast(-1)) + { + if (CTxdStore_GetTxd(pSlot->usParentIndex) != nullptr) + CTxdStore_RemoveRef(pSlot->usParentIndex); + } + } + + auto itInfo = ms_ModelTexturesInfoMap.find(usTxdSlotId); + if (itInfo == ms_ModelTexturesInfoMap.end()) + { + InvalidateTxdTextureMapCache(usTxdSlotId); + return; + } + + CModelTexturesInfo& info = itInfo->second; + RwTexDictionary* pTxd = CTxdStore_GetTxd(usTxdSlotId); + const bool bTxdOk = pTxd != nullptr; + + const std::vector usedBy = info.usedByReplacements; + for (SReplacementTextures* pReplacement : usedBy) + { + if (!pReplacement) + continue; + + ForEachShaderReg(pReplacement, usTxdSlotId, [usTxdSlotId](CD3DDUMMY* pD3D) { RemoveShaderEntryByD3DData(usTxdSlotId, pD3D); }); + ClearShaderRegs(pReplacement, usTxdSlotId); + + auto itPerTxd = std::find_if(pReplacement->perTxdList.begin(), pReplacement->perTxdList.end(), + [usTxdSlotId](const SReplacementTextures::SPerTxd& entry) { return entry.usTxdId == usTxdSlotId; }); + + if (itPerTxd != pReplacement->perTxdList.end()) + { + // Build master set to distinguish masters from copies. + // When bTexturesAreCopies is false, usingTextures contains the + // actual master textures (placed directly into the TXD). Their + // rasters must be preserved for ModelInfoTXDRemoveTextures to + // properly free later. Only copy rasters are nulled since the + // master keeps the shared raster alive. + const std::unordered_set masterSet(pReplacement->textures.begin(), pReplacement->textures.end()); + + for (RwTexture* pTex : itPerTxd->usingTextures) + { + if (!IsReadableTexture(pTex)) + continue; + + // Remove texture from TXD linked list before slot destruction + if (bTxdOk && pTex->txd == pTxd) + SafeOrphanTexture(pTex, usTxdSlotId); + + // Null rasters only for copies. Copies share their raster with + // a master in pReplacement->textures; the master keeps it alive + // and ModelInfoTXDRemoveTextures will free it properly later. + // Nulling a master's raster would permanently leak the VRAM. + const bool bIsCopy = itPerTxd->bTexturesAreCopies || masterSet.find(pTex) == masterSet.end(); + if (bIsCopy && pTex->txd == nullptr) + { + pTex->raster = nullptr; + + // Destroy the copy struct now - the perTxdList entry is + // about to be erased, so ModelInfoTXDRemoveTextures will + // never see this copy. Without this the RwTexture struct + // leaks (raster was already nulled, no VRAM impact). + RwTextureDestroy(pTex); + } + } + + itPerTxd->usingTextures.clear(); + itPerTxd->replacedOriginals.clear(); + pReplacement->perTxdList.erase(itPerTxd); + } + + pReplacement->usedInTxdIds.erase(usTxdSlotId); + ListRemove(info.usedByReplacements, pReplacement); + } + + info.usedByReplacements.clear(); + + // Restore displaced originals back into the TXD so RwTexDictionaryDestroy + // frees them along with the dictionary. During ModelInfoTXDAddTextures, + // originals were removed from the TXD linked list and stored in + // replacedOriginals / info.originalTextures. Without restoring them, + // they'd leak (both struct and raster) since they're no longer in the + // TXD and nobody else tracks them. + if (bTxdOk) + { + TxdTextureMap txdTextureMap; + BuildTxdTextureMapFast(pTxd, txdTextureMap); + + for (RwTexture* pOriginal : info.originalTextures) + { + if (!IsReadableTexture(pOriginal)) + continue; + + // Already in the TXD - will be freed by RwTexDictionaryDestroy + if (pOriginal->txd == pTxd) + continue; + + if (strnlen(pOriginal->name, RW_TEXTURE_NAME_LENGTH) >= RW_TEXTURE_NAME_LENGTH) + continue; + + // Skip if a texture with this name is already in the TXD + if (txdTextureMap.find(pOriginal->name) != txdTextureMap.end()) + continue; + + // Ensure proper unlinking from any stale TXD list state + SafeOrphanTexture(pOriginal); + if (pOriginal->txd != nullptr) + continue; + + if (RwTexDictionaryAddTexture(pTxd, pOriginal)) + txdTextureMap[pOriginal->name] = pOriginal; + } + } + + info.originalTextures.clear(); + info.originalTexturesByName.clear(); + + ms_ModelTexturesInfoMap.erase(itInfo); + + // After restoring displaced originals above, the TXD now contains both + // non-displaced originals (never removed) and restored displaced originals. + // RwTexDictionaryDestroy in RemoveTextureDictonarySlot will free all of + // them properly. Do NOT call OrphanTxdTexturesBounded - orphaning them + // would leak their raster memory since nobody tracks them anymore. + + if (CTxdStore_GetNumRefs(usTxdSlotId) > 0) + CRenderWareSA::DebugTxdRemoveRef(usTxdSlotId, "CleanupReplacementsInTxdSlot"); + + InvalidateTxdTextureMapCache(usTxdSlotId); +} + +//////////////////////////////////////////////////////////////// +// +// CRenderWareSA::ModelInfoTXDDeferCleanup +// +// Remove tracking state without destroying textures. Used during shutdown +// when model data may be corrupted and full cleanup via +// ModelInfoTXDRemoveTextures would be unsafe. Immediate destruction risks +// double-freeing rasters shared between copy and master textures, or +// freeing rasters still referenced by in-flight clumps. +// Master textures are saved in g_LeakedMasterTextures so +// StaticResetModelTextureReplacing can destroy them safely after all +// elements are gone and shared-raster tracking is available. +// +//////////////////////////////////////////////////////////////// +void CRenderWareSA::ModelInfoTXDDeferCleanup(SReplacementTextures* pReplacementTextures) +{ + if (!pReplacementTextures) + { + return; + } + + // Save master textures for deferred destruction in StaticResetModelTextureReplacing. + // After this function returns, CClientTXD's destructor destroys pReplacementTextures + // and its textures vector drops the raw RwTexture* pointers. Without this, the + // master RwTexture structs and their rasters leak permanently. + // Masters are always orphaned (txd=nullptr, self-circular TXDList) - they were + // never added to any game TXD; only copies were. Their rasters are shared with + // copies still in TXDs; the destruction loop's mopupFreedRasters handles that. + for (RwTexture* pMaster : pReplacementTextures->textures) + { + if (pMaster && g_LeakedMasterTextures.insert(pMaster).second && pMaster->raster) + g_GlobalMtaRasterCache.insert(pMaster->raster); + } + + RemoveReplacementFromTracking(pReplacementTextures); +} + +//////////////////////////////////////////////////////////////// +// +// CRenderWareSA::ModelInfoTXDRemoveTextures +// +// Remove the textures from the txds that are using them. +// +//////////////////////////////////////////////////////////////// +void CRenderWareSA::ModelInfoTXDRemoveTextures(SReplacementTextures* pReplacementTextures) +{ + if (!pGame || !pReplacementTextures) + { + return; + } + + // Early exit if session changed - stale data is invalid + if (pReplacementTextures->uiSessionId != ms_uiTextureReplacingSession) + { + // Detach from any TXDs we previously registered with. + // This prevents leaving stale pointers in ms_ModelTexturesInfoMap when a TXD element is + // destroyed after a disconnect/reconnect boundary (session changed). + for (unsigned short txdId : pReplacementTextures->usedInTxdIds) + { + auto itInfo = ms_ModelTexturesInfoMap.find(txdId); + if (itInfo != ms_ModelTexturesInfoMap.end()) + { + ListRemove(itInfo->second.usedByReplacements, pReplacementTextures); + } + + // Drop any shader registrations we tracked for this replacement/txd pairing. + ForEachShaderReg(pReplacementTextures, txdId, [txdId](CD3DDUMMY* pD3D) { RemoveShaderEntryByD3DData(txdId, pD3D); }); + ClearShaderRegs(pReplacementTextures, txdId); + } + + RemoveReplacementFromTracking(pReplacementTextures); + + // Save master textures for deferred destruction, same as ModelInfoTXDDeferCleanup. + // Without this, masters leak permanently after session boundary. + for (RwTexture* pMaster : pReplacementTextures->textures) + { + if (pMaster && g_LeakedMasterTextures.insert(pMaster).second && pMaster->raster) + g_GlobalMtaRasterCache.insert(pMaster->raster); + } + + // Re-resolve loaded models to their current TXD so geometry materiale + // no longer reference stale replacement textures from the old session. + for (const unsigned short usModelId : pReplacementTextures->usedInModelIds) + { + auto* pModelInfo = static_cast(pGame->GetModelInfo(usModelId)); + if (!pModelInfo) + continue; + + const unsigned short usTxdId = pModelInfo->GetTextureDictionaryID(); + RebindLoadedModelToCurrentTxd(pModelInfo, usTxdId); + } + + pReplacementTextures->textures.clear(); + pReplacementTextures->perTxdList.clear(); + pReplacementTextures->usedInTxdIds.clear(); + // Keep usedInModelIds for the caller's restream pass, matching the normal cleanup path. + pReplacementTextures->bHasRequestedSpace = false; + return; + } + + const auto masterTextures = MakeTextureSet(pReplacementTextures->textures); + const auto masterRasterMap = MakeRasterMap(pReplacementTextures->textures); + + // Track destroyed textures across all perTxdInfo iterations to prevent double-free + std::unordered_set destroyedTextures; + std::unordered_set leakedTextures; // Still in TXD - must not destroy + std::unordered_set txdsWithLeakedTextures; + std::unordered_set processedTxdIds; + std::unordered_set cleanedTxdIds; + + auto markLeakedTxd = [&](unsigned short txdId, CModelTexturesInfo* pInfo) + { + txdsWithLeakedTextures.insert(txdId); + if (pInfo) + pInfo->bHasLeakedTextures = true; + }; + + for (SReplacementTextures::SPerTxd& perTxdInfo : pReplacementTextures->perTxdList) + { + unsigned short usTxdId = perTxdInfo.usTxdId; + processedTxdIds.insert(usTxdId); + + if (cleanedTxdIds.find(usTxdId) != cleanedTxdIds.end()) // Already cleaned + { + perTxdInfo.usingTextures.clear(); + perTxdInfo.replacedOriginals.clear(); + continue; + } + + CModelTexturesInfo* pInfo = MapFind(ms_ModelTexturesInfoMap, usTxdId); + + if (!pInfo) + { + ForEachShaderReg(pReplacementTextures, usTxdId, [usTxdId](CD3DDUMMY* pD3D) { RemoveShaderEntryByD3DData(usTxdId, pD3D); }); + ClearShaderRegs(pReplacementTextures, usTxdId); + + for (RwTexture* pTex : perTxdInfo.usingTextures) // Track leaked masters + { + if (!IsReadableTexture(pTex)) + continue; + + bool bIsCopy = perTxdInfo.bTexturesAreCopies || masterTextures.find(pTex) == masterTextures.end(); + + if (!bIsCopy) + { + leakedTextures.insert(pTex); + + continue; + } + + bool bMasterLeaked = false; + if (pTex->raster) + { + if (RwTexture* pMaster = FindReadableMasterForRaster(masterRasterMap, pReplacementTextures->textures, pTex->raster)) + { + leakedTextures.insert(pMaster); + bMasterLeaked = true; + } + } + + if (!bMasterLeaked) // Leak copy to keep raster valid for rendering + { + leakedTextures.insert(pTex); + + if (pTex->raster) + { + if (RwTexture* pMaster = FindReadableMasterForRaster(masterRasterMap, pReplacementTextures->textures, pTex->raster)) + leakedTextures.insert(pMaster); + } + } + } + + perTxdInfo.usingTextures.clear(); + perTxdInfo.replacedOriginals.clear(); + + pReplacementTextures->usedInTxdIds.erase(usTxdId); + cleanedTxdIds.insert(usTxdId); + continue; + } + + bool bKeepTxdAlive = false; + + dassert(MapFind(ms_ModelTexturesInfoMap, usTxdId)); + dassert(std::find(pInfo->usedByReplacements.begin(), pInfo->usedByReplacements.end(), pReplacementTextures) != pInfo->usedByReplacements.end()); + + RwTexDictionary* pCurrentTxd = CTxdStore_GetTxd(usTxdId); + const bool bCurrentTxdOk = pCurrentTxd != nullptr; + const bool bCachedTxdOk = pInfo->pTxd != nullptr; + bool bTxdIsValid = (pInfo->pTxd == pCurrentTxd) && bCachedTxdOk && bCurrentTxdOk; + + if (!bTxdIsValid && !pInfo->pTxd && bCurrentTxdOk) + { + pInfo->pTxd = pCurrentTxd; + bTxdIsValid = true; + } + + if (!bTxdIsValid) + { + bKeepTxdAlive = true; + markLeakedTxd(usTxdId, pInfo); + + ForEachShaderReg(pReplacementTextures, perTxdInfo.usTxdId, [usTxdId](CD3DDUMMY* pD3D) { RemoveShaderEntryByD3DData(usTxdId, pD3D); }); + ClearShaderRegs(pReplacementTextures, perTxdInfo.usTxdId); + + std::unordered_set copiesToDestroy; + std::unordered_set originalsToDestroy; + + CleanupStalePerTxd(perTxdInfo, pInfo->pTxd, pReplacementTextures, &masterTextures, copiesToDestroy, originalsToDestroy, + true /* bSkipRasterNull: textures are leaked, not destroyed — keep rasters for active materials */); + + for (RwTexture* pCopy : copiesToDestroy) // Leak to prevent crashes + { + if (!IsReadableTexture(pCopy)) + continue; + + bool bMasterLeaked = false; + if (pReplacementTextures && pCopy->raster) + { + if (RwTexture* pMaster = FindReadableMasterForRaster(masterRasterMap, pReplacementTextures->textures, pCopy->raster)) + { + leakedTextures.insert(pMaster); + bMasterLeaked = true; + } + } + + if (!bMasterLeaked) + { + leakedTextures.insert(pCopy); + + if (pReplacementTextures && pCopy->raster) + { + if (RwTexture* pMaster = FindReadableMasterForRaster(masterRasterMap, pReplacementTextures->textures, pCopy->raster)) + leakedTextures.insert(pMaster); + } + } + } + + if (!perTxdInfo.bTexturesAreCopies) // Track masters for final cleanup + { + for (RwTexture* pMaster : pReplacementTextures->textures) + { + if (IsReadableTexture(pMaster)) + { + leakedTextures.insert(pMaster); + } + } + } + + (void)originalsToDestroy; + + ListRemove(pInfo->usedByReplacements, pReplacementTextures); + pReplacementTextures->usedInTxdIds.erase(usTxdId); + + if (pInfo->usedByReplacements.empty()) + { + const bool bHasLeaks = bKeepTxdAlive || txdsWithLeakedTextures.count(usTxdId) > 0 || pInfo->bHasLeakedTextures; + pInfo->bHasLeakedTextures = pInfo->bHasLeakedTextures || bHasLeaks; + if (!bHasLeaks) + { + pInfo->originalTextures.clear(); + pInfo->originalTexturesByName.clear(); + if (CTxdStore_GetNumRefs(pInfo->usTxdId) > 0) + CRenderWareSA::DebugTxdRemoveRef(pInfo->usTxdId, "ModelInfoTXDRemoveTextures-stale-clean"); + MapRemove(ms_ModelTexturesInfoMap, usTxdId); + cleanedTxdIds.insert(usTxdId); + } + } + continue; + } + + if (!pInfo->pTxd) + { + bKeepTxdAlive = true; + markLeakedTxd(usTxdId, pInfo); + + ForEachShaderReg(pReplacementTextures, perTxdInfo.usTxdId, [usTxdId](CD3DDUMMY* pD3D) { RemoveShaderEntryByD3DData(usTxdId, pD3D); }); + ClearShaderRegs(pReplacementTextures, perTxdInfo.usTxdId); + + for (RwTexture* pTex : perTxdInfo.usingTextures) // Leak to avoid white textures + { + if (!IsReadableTexture(pTex)) + continue; + + bool bIsCopy = perTxdInfo.bTexturesAreCopies; + if (!bIsCopy && pReplacementTextures) + bIsCopy = (masterTextures.find(pTex) == masterTextures.end()); + + if (!bIsCopy) + { + leakedTextures.insert(pTex); + + continue; + } + + bool bMasterLeaked = false; + if (pReplacementTextures && pTex->raster) + { + if (RwTexture* pMaster = FindReadableMasterForRaster(masterRasterMap, pReplacementTextures->textures, pTex->raster)) + { + leakedTextures.insert(pMaster); + bMasterLeaked = true; + } + } + + if (!bMasterLeaked) // Leak copy to preserve raster + { + leakedTextures.insert(pTex); + + if (pReplacementTextures && pTex->raster) + { + if (RwTexture* pMaster = FindReadableMasterForRaster(masterRasterMap, pReplacementTextures->textures, pTex->raster)) + leakedTextures.insert(pMaster); + } + } + } + + perTxdInfo.usingTextures.clear(); + perTxdInfo.replacedOriginals.clear(); + + ListRemove(pInfo->usedByReplacements, pReplacementTextures); + pReplacementTextures->usedInTxdIds.erase(usTxdId); + + if (pInfo->usedByReplacements.empty()) + { + const bool bHasLeaks = bKeepTxdAlive || txdsWithLeakedTextures.count(usTxdId) > 0 || pInfo->bHasLeakedTextures; + pInfo->bHasLeakedTextures = pInfo->bHasLeakedTextures || bHasLeaks; + if (!bHasLeaks) + { + pInfo->originalTextures.clear(); + pInfo->originalTexturesByName.clear(); + if (CTxdStore_GetNumRefs(pInfo->usTxdId) > 0) + CRenderWareSA::DebugTxdRemoveRef(pInfo->usTxdId, "ModelInfoTXDRemoveTextures-stale-unreadable-clean"); + MapRemove(ms_ModelTexturesInfoMap, usTxdId); + cleanedTxdIds.insert(usTxdId); + } + } + continue; + } + + ForEachShaderReg(pReplacementTextures, perTxdInfo.usTxdId, [usTxdId](CD3DDUMMY* pD3D) { RemoveShaderEntryByD3DData(usTxdId, pD3D); }); + ClearShaderRegs(pReplacementTextures, perTxdInfo.usTxdId); + + TxdTextureMap txdTextureMap; // O(1) lookups during restoration + BuildTxdTextureMapFast(pInfo->pTxd, txdTextureMap); + + TxdTextureMap parentTxdTextureMap; + auto& txdPool = pGame->GetPools()->GetTxdPool(); + if (auto* pTxdPoolSA = static_cast(&txdPool)) + { + if (auto* pTxdSlot = pTxdPoolSA->GetTextureDictonarySlot(perTxdInfo.usTxdId)) + { + unsigned short usParent = pTxdSlot->usParentIndex; + if (usParent != static_cast(-1)) + { + RwTexDictionary* pParentTxd = CTxdStore_GetTxd(usParent); + + // Request parent TXD to load if not already loaded - required for texture restoration. + // Without this, restoration fails when parent TXD is unloaded, leaving model geometry + // with dangling texture pointers that cause white textures. + // Only load if at least one model using this replacement has geometry to restore. + if (!pParentTxd && pGame->GetStreaming()) + { + bool bNeedRestore = false; + for (unsigned short modelId : pReplacementTextures->usedInModelIds) + { + if (auto* pModelInfo = static_cast(pGame->GetModelInfo(modelId))) + { + if (pModelInfo->GetRwObject()) + { + bNeedRestore = true; + break; + } + } + } + + if (bNeedRestore) + { + const int iBaseIDforTXD = pGame->GetBaseIDforTXD(); + if (iBaseIDforTXD > 0) + { + const unsigned int uiTxdStreamId = usParent + static_cast(iBaseIDforTXD); + pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(true, "ModelInfoTXDRemoveTextures-parentTxd"); + pParentTxd = CTxdStore_GetTxd(usParent); + } + } + } + + if (pParentTxd) + BuildTxdTextureMapFast(pParentTxd, parentTxdTextureMap); + } + } + } + + for (unsigned short usedModelId : pReplacementTextures->usedInModelIds) + { + if (ShouldUseVehicleTxdFallback(usedModelId)) + { + AddVehicleTxdFallback(parentTxdTextureMap); + break; + } + } + + TextureSwapMap swapMap; + swapMap.reserve(perTxdInfo.usingTextures.size()); + + for (std::size_t idx = 0; idx < perTxdInfo.usingTextures.size(); ++idx) + { + RwTexture* pOldTexture = perTxdInfo.usingTextures[idx]; + if (!pOldTexture) + continue; + + RwTexture* pOriginalTexture = (idx < perTxdInfo.replacedOriginals.size()) ? perTxdInfo.replacedOriginals[idx] : nullptr; + + if (!pOriginalTexture && !parentTxdTextureMap.empty() && strnlen(pOldTexture->name, RW_TEXTURE_NAME_LENGTH) < RW_TEXTURE_NAME_LENGTH) + { + auto itParent = parentTxdTextureMap.find(pOldTexture->name); + if (itParent != parentTxdTextureMap.end() && IsReadableTexture(itParent->second)) + pOriginalTexture = itParent->second; + + if (!pOriginalTexture) + { + const char* szInternal = CRenderWareSA::GetInternalTextureName(pOldTexture->name); + if (szInternal && strcmp(szInternal, pOldTexture->name) != 0) + { + auto itInt = parentTxdTextureMap.find(szInternal); + if (itInt != parentTxdTextureMap.end() && IsReadableTexture(itInt->second)) + pOriginalTexture = itInt->second; + } + } + } + + if (pOriginalTexture) + swapMap[pOldTexture] = pOriginalTexture; + + if (pOriginalTexture && pInfo->pTxd && pOriginalTexture->txd != pInfo->pTxd) + { + if (strnlen(pOriginalTexture->name, RW_TEXTURE_NAME_LENGTH) >= RW_TEXTURE_NAME_LENGTH) + continue; + + SafeOrphanTexture(pOriginalTexture); + if (pOriginalTexture->txd != nullptr) + continue; + + auto itExisting = txdTextureMap.find(pOriginalTexture->name); + if (itExisting == txdTextureMap.end() || itExisting->second != pOriginalTexture) + { + if (!RwTexDictionaryAddTexture(pInfo->pTxd, pOriginalTexture)) + { + SString strError("RwTexDictionaryAddTexture failed restoring texture: %s in TXD %u", pOriginalTexture->name, pInfo->usTxdId); + WriteDebugEvent(strError); + AddReportLog(9401, strError); + } + else + { + txdTextureMap[pOriginalTexture->name] = pOriginalTexture; + } + } + } + } + + if (!swapMap.empty()) + { + std::vector targetModels; + std::unordered_set seenModels; + targetModels.reserve(pReplacementTextures->usedInModelIds.size()); + + for (unsigned short modelId : pReplacementTextures->usedInModelIds) + { + CModelInfoSA* pModelInfo = static_cast(pGame->GetModelInfo(modelId)); + if (!pModelInfo) + continue; + + if (!pModelInfo->GetRwObject()) + continue; + + if (seenModels.insert(pModelInfo).second) + targetModels.push_back(pModelInfo); + } + + for (CModelInfoSA* pModelInfo : targetModels) + { + // Note: targetModels only contains models that had GetRwObject() != null + // when added to the list above. While technically the object could be + // unloaded between loops, ReplaceTextureInModel handles null safely. + ReplaceTextureInModel(pModelInfo, swapMap); + } + } + + for (RwTexture* pOldTexture : perTxdInfo.usingTextures) + { + if (!pOldTexture) + continue; + + bool bWasSwapped = swapMap.find(pOldTexture) != swapMap.end(); + + if (!bWasSwapped && !IsReadableTexture(pOldTexture)) + continue; + + if (bWasSwapped && pInfo->pTxd && pOldTexture->txd == pInfo->pTxd) + CRenderWareSA::RwTexDictionaryRemoveTexture(pInfo->pTxd, pOldTexture); + + if (!bWasSwapped) // No original - must leak + { + bool bNameWasOriginal = false; + for (RwTexture* pOrig : pInfo->originalTextures) + { + if (!IsReadableTexture(pOrig)) + continue; + + if (strnlen(pOrig->name, RW_TEXTURE_NAME_LENGTH) >= RW_TEXTURE_NAME_LENGTH) + continue; + + if (strncmp(pOrig->name, pOldTexture->name, RW_TEXTURE_NAME_LENGTH) == 0) + { + bNameWasOriginal = true; + break; + } + } + + bKeepTxdAlive = true; + markLeakedTxd(usTxdId, pInfo); + + if (IsReadableTexture(pOldTexture)) + leakedTextures.insert(pOldTexture); + + bool bIsCopy = perTxdInfo.bTexturesAreCopies; // Also leak master sharing raster + if (!bIsCopy && pReplacementTextures && pOldTexture) + bIsCopy = (masterTextures.find(pOldTexture) == masterTextures.end()); + + bool bMasterLeaked = false; + if (bIsCopy && pReplacementTextures && pOldTexture && pOldTexture->raster) + { + if (RwTexture* pMaster = FindReadableMasterForRaster(masterRasterMap, pReplacementTextures->textures, pOldTexture->raster)) + { + leakedTextures.insert(pMaster); + bMasterLeaked = true; + } + } + + // Leak master or copy to keep raster valid for rendering + if (bIsCopy && !bMasterLeaked) + { + // Leak the copy to keep raster valid for rendering + leakedTextures.insert(pOldTexture); + + // Also leak any readable master sharing the raster + if (pReplacementTextures && pOldTexture->raster) + { + if (RwTexture* pMaster = FindReadableMasterForRaster(masterRasterMap, pReplacementTextures->textures, pOldTexture->raster)) + leakedTextures.insert(pMaster); + } + } + continue; + } + + dassert(!RwTexDictionaryContainsTexture(pInfo->pTxd, pOldTexture)); + + // Copy: bTexturesAreCopies or not in master list + bool bIsActuallyCopy = perTxdInfo.bTexturesAreCopies; + if (!bIsActuallyCopy && pReplacementTextures) + { + // If not in master list, it's a renamed copy + bIsActuallyCopy = (masterTextures.find(pOldTexture) == masterTextures.end()); + } + + // Only destroy orphaned copies (prevent double-free via destroyedTextures check) + if (bIsActuallyCopy && destroyedTextures.find(pOldTexture) == destroyedTextures.end() && CanDestroyOrphanedTexture(pOldTexture)) + { + destroyedTextures.insert(pOldTexture); + SafeDestroyTexture(pOldTexture); + } + } + + perTxdInfo.usingTextures.clear(); + + // Safety loop for edge cases (with new tracking, entries should be in originalTextures) + for (RwTexture* pReplacedTexture : perTxdInfo.replacedOriginals) + { + if (pReplacedTexture && destroyedTextures.find(pReplacedTexture) == destroyedTextures.end() && + pInfo->originalTextures.find(pReplacedTexture) == pInfo->originalTextures.end() && CanDestroyOrphanedTexture(pReplacedTexture)) + { + destroyedTextures.insert(pReplacedTexture); + + // If this entry shares a raster with a master texture, it's a copy that + // was incorrectly captured as a displaced original. Use SafeDestroyTexture + // to null the raster and prevent double-free when the master is destroyed. + bool bSharesRasterWithMaster = pReplacedTexture->raster && masterRasterMap.find(pReplacedTexture->raster) != masterRasterMap.end(); + + if (bSharesRasterWithMaster) + SafeDestroyTexture(pReplacedTexture); + else + RwTextureDestroy(pReplacedTexture); + if (g_LeakedMasterTextures.erase(pReplacedTexture) != 0) + InvalidateGlobalMtaRasterCache(); + } + } + + perTxdInfo.replacedOriginals.clear(); + + // Don't erase from originalTextures with freed pointers (heap corruption risk) + txdTextureMap.clear(); + if (pInfo->pTxd) + { + BuildTxdTextureMapFast(pInfo->pTxd, txdTextureMap); + } + else + { + bKeepTxdAlive = true; + markLeakedTxd(usTxdId, pInfo); + for (RwTexture* pOrig : pInfo->originalTextures) + { + if (IsReadableTexture(pOrig)) + { + leakedTextures.insert(pOrig); + } + } + ListRemove(pInfo->usedByReplacements, pReplacementTextures); + pReplacementTextures->usedInTxdIds.erase(usTxdId); + if (pInfo->usedByReplacements.empty()) + { + const bool bHasLeaks = bKeepTxdAlive || txdsWithLeakedTextures.count(usTxdId) > 0 || pInfo->bHasLeakedTextures; + pInfo->bHasLeakedTextures = pInfo->bHasLeakedTextures || bHasLeaks; + if (!bHasLeaks) + { + pInfo->originalTextures.clear(); + pInfo->originalTexturesByName.clear(); + if (CTxdStore_GetNumRefs(pInfo->usTxdId) > 0) + CRenderWareSA::DebugTxdRemoveRef(pInfo->usTxdId, "ModelInfoTXDRemoveTextures-restore-unreadable-clean"); + MapRemove(ms_ModelTexturesInfoMap, usTxdId); + cleanedTxdIds.insert(usTxdId); + } + } + continue; + } + + for (RwTexture* pOriginalTexture : pInfo->originalTextures) + { + // Skip null/invalid textures (can happen during shutdown) + if (!IsReadableTexture(pOriginalTexture)) + continue; + + if (pOriginalTexture->txd == pInfo->pTxd) + continue; + + // Validate texture name readable + if (strnlen(pOriginalTexture->name, RW_TEXTURE_NAME_LENGTH) >= RW_TEXTURE_NAME_LENGTH) + continue; // Invalid name - skip this texture + + // Already in TXD by name, skip + if (txdTextureMap.find(pOriginalTexture->name) != txdTextureMap.end()) + continue; + + SafeOrphanTexture(pOriginalTexture); + + // Orphan failed, don't add (double-link risk) + if (pOriginalTexture->txd != nullptr) + continue; + + // Avoid duplicates by name (O(1) hash map lookup) + if (txdTextureMap.find(pOriginalTexture->name) == txdTextureMap.end()) + { + if (!pInfo->pTxd || !RwTexDictionaryAddTexture(pInfo->pTxd, pOriginalTexture)) + { + SString strError("RwTexDictionaryAddTexture failed ensuring original texture: %s in TXD %u", pOriginalTexture->name, pInfo->usTxdId); + WriteDebugEvent(strError); + AddReportLog(9401, strError); + } + else + { + txdTextureMap[pOriginalTexture->name] = pOriginalTexture; + } + // Originals keep shader registration (never removed) + } + } + + ListRemove(pInfo->usedByReplacements, pReplacementTextures); + + if (pInfo->usedByReplacements.empty()) + { + // txd should now contain the same textures as 'originalTextures' +#ifdef MTA_DEBUG + std::vector currentTextures; + if (pInfo->pTxd) + GetTxdTextures(currentTextures, pInfo->pTxd); + + auto formatTextures = [](const auto& textures) -> std::string + { + std::ostringstream result; + size_t i = 0; + size_t count = textures.size(); + for (const auto* pTex : textures) + { + const bool isValid = pTex != nullptr; + const bool isLast = (i == count - 1); + + if (isValid) + result << pTex->name << "[0x" << std::hex << pTex << std::dec << "]"; + else + result << "INVALID[0x" << std::hex << pTex << std::dec << "]"; + + if (!isLast) + result << ", "; + ++i; + } + return result.str(); + }; + + // Allow size mismatch in case texture removal was skipped due to invalid pointers + if (currentTextures.size() != pInfo->originalTextures.size()) + { + std::ostringstream debugMsg; + debugMsg << "TXD " << pInfo->usTxdId << ": texture count mismatch (current=" << currentTextures.size() + << ", expected=" << pInfo->originalTextures.size() << ")\n"; + debugMsg << " Current textures: " << formatTextures(currentTextures); + debugMsg << "\n Expected textures: " << formatTextures(pInfo->originalTextures); + debugMsg << "\n"; + OutputDebugString(debugMsg.str().c_str()); + } + else + { + // First pass: validate all original textures are present + for (const auto* pOriginalTexture : pInfo->originalTextures) + { + if (!pOriginalTexture) + continue; + if (std::find(currentTextures.begin(), currentTextures.end(), pOriginalTexture) == currentTextures.end()) + { + const char* texName = pOriginalTexture ? pOriginalTexture->name : "INVALID"; + std::ostringstream oss; + oss << "Original texture not found in TXD " << pInfo->usTxdId << " - texture '" << texName << "' [0x" << std::hex << pOriginalTexture + << std::dec << "] was removed or replaced unexpectedly"; + const std::string assertMsg = oss.str(); + assert(false && assertMsg.c_str()); + } + } + + // Second pass: remove original textures from current list to find extras + for (auto* pOriginalTexture : pInfo->originalTextures) + { + if (pOriginalTexture) + ListRemove(currentTextures, pOriginalTexture); + } + + // Remaining textures indicate leak + if (!currentTextures.empty()) + { + std::ostringstream oss; + oss << "Extra textures remain in TXD " << pInfo->usTxdId + << " after removing all originals - indicates texture leak. Remaining: " << formatTextures(currentTextures); + const std::string assertMsg = oss.str(); + assert(false && assertMsg.c_str()); + } + } + + const auto refsCount = CTxdStore_GetNumRefs(pInfo->usTxdId); + if (refsCount <= 0 && !bKeepTxdAlive) + { + std::ostringstream oss; + oss << "TXD " << pInfo->usTxdId << " has invalid ref count " << refsCount << " - should be > 0 before cleanup"; + const std::string assertMsg = oss.str(); + assert(false && assertMsg.c_str()); + } +#endif + // Remove info + const bool bHasLeaks = bKeepTxdAlive || txdsWithLeakedTextures.count(usTxdId) > 0 || pInfo->bHasLeakedTextures; + pInfo->bHasLeakedTextures = pInfo->bHasLeakedTextures || bHasLeaks; + if (!bHasLeaks) + { + // Clear tracking; TXD owns textures + pInfo->originalTextures.clear(); + pInfo->originalTexturesByName.clear(); + + if (CTxdStore_GetNumRefs(pInfo->usTxdId) > 0) + CRenderWareSA::DebugTxdRemoveRef(pInfo->usTxdId, "ModelInfoTXDRemoveTextures-clean"); + MapRemove(ms_ModelTexturesInfoMap, usTxdId); + cleanedTxdIds.insert(usTxdId); + } + } + } + + // Leaked textures block master destruction (may still be linked in TXD list) + const bool bLeakedTextureStillLinked = !leakedTextures.empty(); + + // Persist per-TXD leak state for StaticReset + if (!txdsWithLeakedTextures.empty()) + { + for (unsigned short txdId : txdsWithLeakedTextures) + { + if (auto* pInfo = MapFind(ms_ModelTexturesInfoMap, txdId)) + pInfo->bHasLeakedTextures = true; + } + } + + // Clear leak flags only when TXD is proven back to original state + for (unsigned short txdId : processedTxdIds) + { + if (txdsWithLeakedTextures.count(txdId) != 0) + continue; + + auto* pInfo = MapFind(ms_ModelTexturesInfoMap, txdId); + if (!pInfo) + continue; + + if (!pInfo->usedByReplacements.empty()) + continue; + + // Fast-path: nothing to clear + if (!pInfo->bHasLeakedTextures) + continue; + + // Only clear if: + // 1) TXD pointer is valid and matches current CTxdStore pointer + // 2) Current TXD texture list matches originalTextures exactly (by pointer identity) + // This is the only safe proof that no leaked replacement textures remain linked. + const auto canProveNoLeaks = [&]() -> bool + { + if (!pInfo->pTxd) + return false; + + RwTexDictionary* pCurrentTxd = CTxdStore_GetTxd(pInfo->usTxdId); + if (pCurrentTxd != pInfo->pTxd) + return false; + + std::vector currentTextures; + GetTxdTextures(currentTextures, pInfo->pTxd); + + if (currentTextures.empty()) + return false; + + if (currentTextures.size() != pInfo->originalTextures.size()) + return false; + + for (RwTexture* pTex : currentTextures) + { + if (pInfo->originalTextures.find(pTex) == pInfo->originalTextures.end()) + return false; + } + + // Prevent PopulateOriginalTextures contamination: + // If originalTextures was snapshotted while MTA textures were still linked in the + // TXD, the pointer comparison above gives a false positive. Cross-check against + // g_LeakedMasterTextures to detect masters or copies (via shared raster) that + // should not be in a clean TXD. + if (!g_LeakedMasterTextures.empty()) + { + for (RwTexture* pTex : currentTextures) + { + if (!pTex) + continue; + + if (g_LeakedMasterTextures.count(pTex) != 0) + return false; + + if (pTex->raster) + { + for (RwTexture* pMaster : g_LeakedMasterTextures) + { + if (pMaster && pMaster->raster == pTex->raster) + return false; + } + } + } + } + + return true; + }; + + if (!canProveNoLeaks()) + continue; + + // Proven leak-free: clear flag and drop ref + pInfo->bHasLeakedTextures = false; + + if (CTxdStore_GetNumRefs(pInfo->usTxdId) > 0) + CRenderWareSA::DebugTxdRemoveRef(pInfo->usTxdId, "ModelInfoTXDRemoveTextures-no-leak-clean"); + MapRemove(ms_ModelTexturesInfoMap, txdId); + } + + // Destroy master textures (skip leaked to prevent dangling TXD list pointers) + // Also skip if perTxdList entries remain - copies may still reference masters' rasters + if (!bLeakedTextureStillLinked && pReplacementTextures->perTxdList.empty()) + { + bool bLeakedMastersMutated = false; + for (RwTexture* pTexture : pReplacementTextures->textures) + { + if (!pTexture) + continue; + + // Skip unreadable or already processed textures + if (destroyedTextures.find(pTexture) != destroyedTextures.end() || leakedTextures.find(pTexture) != leakedTextures.end()) + { + continue; + } + + // Destroy orphaned masters only (leak if txd still set) + if (!CanDestroyOrphanedTexture(pTexture)) + continue; + + // If an orphaned copy keeps this raster alive (bSkipRasterNull path), + // null the raster instead of freeing it. The copy's material destruction + // by the engine will free the raster when the model unloads. + if (pTexture->raster && g_OrphanedCopyRasters.count(pTexture->raster)) + SafeDestroyTexture(pTexture); + else + RwTextureDestroy(pTexture); + destroyedTextures.insert(pTexture); + bLeakedMastersMutated |= (g_LeakedMasterTextures.erase(pTexture) != 0); + } + if (bLeakedMastersMutated) + InvalidateGlobalMtaRasterCache(); + } + else + { + // Track masters that weren't destroyed for cleanup at StaticReset + for (RwTexture* pTexture : pReplacementTextures->textures) + { + if (pTexture && destroyedTextures.find(pTexture) == destroyedTextures.end()) + { + if (g_LeakedMasterTextures.insert(pTexture).second && pTexture->raster) + g_GlobalMtaRasterCache.insert(pTexture->raster); + } + } + } + + // TXD-only removals skip CleanupIsolatedTxdForModel since it only runs from + // CClientDFF::UnreplaceModel. Without this, usTextureDictionary stays pointing at + // the now-empty isolated slot and the pool entry is never released. + for (unsigned short usTxdId : cleanedTxdIds) + { + auto itOwner = g_IsolatedModelByTxd.find(usTxdId); + if (itOwner != g_IsolatedModelByTxd.end()) + CleanupIsolatedTxdForModel(itOwner->second); + } + + // For isolated slots whose replacements were all removed but the slot + // could not be freed (leaked texture refs or deferred state), + // mark for early stale reclamation so the next allocation or periodic + // cleanup pass reclaims the slot without waiting for the full timeout. + for (unsigned short usTxdId : processedTxdIds) + { + if (cleanedTxdIds.count(usTxdId) > 0) + continue; + + auto* pRemainingInfo = MapFind(ms_ModelTexturesInfoMap, usTxdId); + if (pRemainingInfo && pRemainingInfo->usedByReplacements.empty()) + MarkIsolatedSlotReadyForReclamation(usTxdId); + } + + // Invalidate caches for all TXDs that were modified + for (unsigned short usTxdId : processedTxdIds) + InvalidateTxdTextureMapCache(usTxdId); + + RemoveReplacementFromTracking(pReplacementTextures); + + // Reset all states except usedInModelIds which is needed by the caller for restreaming + pReplacementTextures->textures.clear(); + pReplacementTextures->perTxdList.clear(); + pReplacementTextures->usedInTxdIds.clear(); + // Note: usedInModelIds is NOT cleared here as CClientTXD destructor needs it for Restream() + pReplacementTextures->bHasRequestedSpace = false; +} + +//////////////////////////////////////////////////////////////// +// +// CRenderWareSA::StaticResetModelTextureReplacing +// Clears all texture replacement state. Keeps TXD refs if bHasLeakedTextures to prevent crashes. +//////////////////////////////////////////////////////////////// +void CRenderWareSA::StaticResetModelTextureReplacing() +{ + ++ms_uiTextureReplacingSession; + if (ms_uiTextureReplacingSession == 0) + ++ms_uiTextureReplacingSession; + + g_PendingIsolatedModels.clear(); + g_PendingIsolatedModelTimes.clear(); + + g_pCachedVehicleTxd = nullptr; + g_pCachedVehicleTxdListHead = nullptr; + g_pCachedVehicleTxdListTail = nullptr; + g_CachedVehicleTxdMap = TxdTextureMap{}; + g_usVehicleTxdSlotId = 0xFFFF; + ClearTxdTextureMapCache(); + g_uiLastPendingTxdProcessTime = 0; + g_uiLastTxdPoolWarnTime = 0; + g_uiLastPoolCountTime = 0; + g_iCachedPoolSize = 0; + g_iCachedUsedSlots = 0; + g_bPoolCountDirty = true; + g_uiIsolationDeniedSerial = 0; + g_bProcessingPendingReplacements = false; + g_bProcessingPendingIsolatedModels = false; + g_uiPendingReplacementConditionSerial = 0; + g_uiNextPendingRetryTick = 0; + g_pPendingReplacementSnapshot = nullptr; + const uint32_t uiNow = GetTickCount32(); + g_uiLastOrphanCleanupTime = uiNow; + g_uiLastOrphanLogTime = uiNow; + g_uiLastAdoptLogTime = uiNow; + g_uiLastPoolDenyLogTime = uiNow; + g_uiLastLeakCapacityLogTime = uiNow; + g_uiLastIsolationFailLogTime = uiNow; + + g_IsolatedTxdLastUseTime.clear(); + + g_uiLastStaleCleanupTime = uiNow; + + if (!g_PendingReplacementByModel.empty()) + g_PendingReplacementByModel.clear(); + + if (!g_ActiveReplacements.empty()) + g_ActiveReplacements.clear(); + + ClearAllShaderRegs([](unsigned short txdId, CD3DDUMMY* pD3D) { RemoveShaderEntryByD3DData(txdId, pD3D); }); + + if (!g_PermanentlyLeakedTxdSlots.empty()) + { + if (ShouldLog(g_uiLastOrphanLogTime)) + { + AddReportLog( + 9401, SString("StaticResetModelTextureReplacing: %u TXD slots remain leaked", static_cast(g_PermanentlyLeakedTxdSlots.size()))); + } + + // Queue previously-leaked slots for mop-up retry later in this function. + // External refs may have been released since the last session, allowing + // tryMopUpTxd to free them now. Without this, leaked slots accumulate + // permanently in the TXD pool, shrinking available capacity each session. + for (unsigned short txdId : g_PermanentlyLeakedTxdSlots) + { + if (g_PendingLeakedTxdRefs.size() < MAX_LEAK_RETRY_COUNT) + g_PendingLeakedTxdRefs.insert(txdId); + else if (ShouldLog(g_uiLastLeakCapacityLogTime)) + AddReportLog(9401, SString("g_PendingLeakedTxdRefs at capacity, TXD %u not tracked", txdId)); + } + + g_PermanentlyLeakedTxdSlots.clear(); + } + + if (!g_IsolatedTxdByModel.empty()) + { + std::vector modelIds; + modelIds.reserve(g_IsolatedTxdByModel.size()); + for (const auto& pair : g_IsolatedTxdByModel) + modelIds.push_back(pair.first); + + for (unsigned short modelId : modelIds) + CleanupIsolatedTxdForModel(modelId, true); // Skip streaming loads during session reset + } + + // Retry orphaned isolated TXD slots (should be empty after per-model cleanup). + // Remove or mark as leaked depending on remaining refs. + if (!g_OrphanedIsolatedTxdSlots.empty()) + { + if (pGame) + { + auto& txdPool = pGame->GetPools()->GetTxdPool(); + CTxdPoolSA* pTxdPoolSA = static_cast(&txdPool); + + TryCleanupOrphanedIsolatedSlots(); + TryApplyPendingReplacements(); + + if (pTxdPoolSA) + { + // Clear reverse lookup before processing orphans + g_IsolatedModelByTxd.clear(); + + for (auto it = g_OrphanedIsolatedTxdSlots.begin(); it != g_OrphanedIsolatedTxdSlots.end();) + { + const unsigned short txdId = *it; + + // If this TXD is still accessible, empty its texture list before dropping refs. + // This reduces the chance of crashing inside RW texture destruction on bad rasters. + bool bOrphanedAll = true; + if (RwTexDictionary* pTxd = CTxdStore_GetTxd(txdId)) + { + bOrphanedAll = OrphanTxdTexturesBounded(pTxd, true); + } + if (!bOrphanedAll) + { + if (IsStreamingInfoSlot(txdId)) + SetStreamingInfoLeaked(txdId); + if (g_PendingLeakedTxdRefs.size() < MAX_LEAK_RETRY_COUNT) { + g_PendingLeakedTxdRefs.insert(txdId); + } else if (ShouldLog(g_uiLastLeakCapacityLogTime)) { + AddReportLog(9401, SString("g_PendingLeakedTxdRefs at capacity, TXD %u not tracked", txdId)); +} + g_PermanentlyLeakedTxdSlots.insert(txdId); + it = g_OrphanedIsolatedTxdSlots.erase(it); + continue; + } + + const int iRefCount = CTxdStore_GetNumRefs(txdId); + if (iRefCount == 1) + { + const bool bOwnedByModel = (g_IsolatedModelByTxd.find(txdId) != g_IsolatedModelByTxd.end()); + std::map::iterator itInfo = ms_ModelTexturesInfoMap.find(txdId); + const bool bHasReplacement = + (itInfo != ms_ModelTexturesInfoMap.end() && (itInfo->second.bReapplyingTextures || !itInfo->second.usedByReplacements.empty())); + if (!bOwnedByModel && !bHasReplacement) + { + CTxdStore_RemoveRef(txdId); + } + } + + const int iCurrentRefCount = CTxdStore_GetNumRefs(txdId); + if (iCurrentRefCount > 0) + { + // Refs held by external systems - don't force-remove. + // Keep streaming entry LOADED so SA doesn't try to re-stream. + if (IsStreamingInfoSlot(txdId)) + SetStreamingInfoLeaked(txdId); + if (g_PendingLeakedTxdRefs.size() < MAX_LEAK_RETRY_COUNT) { + g_PendingLeakedTxdRefs.insert(txdId); + } else if (ShouldLog(g_uiLastLeakCapacityLogTime)) { + AddReportLog(9401, SString("g_PendingLeakedTxdRefs at capacity, TXD %u not tracked", txdId)); +} + g_PermanentlyLeakedTxdSlots.insert(txdId); + it = g_OrphanedIsolatedTxdSlots.erase(it); + continue; + } + + // Reset streaming info before removing the slot + if (IsStreamingInfoSlot(txdId)) + ResetStreamingInfo(txdId); + + // Orphan cleanup is removing the slot without going through per-model cleanup. + // Ensure shader support releases any texinfos tagged with this TXD id. + StreamingRemovedTxd(txdId); + + pTxdPoolSA->RemoveTextureDictonarySlot(txdId); + MarkTxdPoolCountDirty(); + it = g_OrphanedIsolatedTxdSlots.erase(it); + } + } + else + { + // TXD pool cast failed - can't clean up slots properly. + // Clear tracking to avoid stale state persisting across sessions. + AddReportLog(9401, "StaticResetModelTextureReplacing: TXD pool cast failed during orphan cleanup"); + g_OrphanedIsolatedTxdSlots.clear(); + } + } + else + { + // pGame is null - can't properly clean up streaming info or slots. + // Clear tracking to avoid stale state persisting across sessions + AddReportLog(9401, "StaticResetModelTextureReplacing: pGame is null during orphan cleanup"); + g_OrphanedIsolatedTxdSlots.clear(); + } + } + + // Pre-release D3D textures from leaked masters while raster pointers are still valid. + // Must happen before mopup because mopup may free shared raster structs. + // Validate texture struct to avoid crash on corrupted/freed memory. + g_ReleasedD3DTextures.clear(); + for (RwTexture* pMaster : g_LeakedMasterTextures) + { + if (!pMaster) + continue; + + // Validate texture struct is readable and sane before accessing raster + if (pMaster->txd != nullptr) + continue; // Not orphaned - skip to avoid corruption + if (pMaster->TXDList.next != &pMaster->TXDList || pMaster->TXDList.prev != &pMaster->TXDList) + continue; // Still linked - skip + if (pMaster->refs < 0 || pMaster->refs > 10000) + continue; // Corrupted refs field - skip + + // TryReleaseTextureD3D is idempotent (nulls renderResource after release), so no need + // to check g_ReleasedD3DTextures here. We populate the set for SafeDestroyTextureWithRaster. + if (void* pD3D = TryReleaseTextureD3D(pMaster)) + g_ReleasedD3DTextures.insert(pD3D); + } + + // Mop-up: orphan leaked TXDs to avoid stale refs + std::vector deferredLeakRetry(g_PendingLeakedTxdRefs.begin(), g_PendingLeakedTxdRefs.end()); + g_PendingLeakedTxdRefs.clear(); + + std::unordered_set mopupDestroyedTextures; // Avoid double-free with g_LeakedMasterTextures + std::unordered_set mopupFreedRasters; // Detect dangling raster pointers from shared rasters + + auto noteUncleaned = [&](unsigned short txdId) { g_PendingLeakedTxdRefs.insert(txdId); }; + + auto noteCleaned = [&](unsigned short txdId) { g_PendingLeakedTxdRefs.erase(txdId); }; + + auto enumerateTxdTexturesBounded = [](RwTexDictionary* pTxd, std::vector& outTextures) -> bool + { + outTextures.clear(); + + if (!pTxd) + return false; + + RwListEntry* const pRoot = &pTxd->textures.root; + RwListEntry* pNode = pRoot->next; + + if (pNode == nullptr) + return false; + + std::size_t count = 0; + + while (pNode && pNode != pRoot) + { + if (++count > MAX_ORPHAN_TEXTURES) + { + outTextures.clear(); + return false; + } + + RwTexture* pTex = reinterpret_cast(reinterpret_cast(pNode) - offsetof(RwTexture, TXDList)); + if (!pTex) + { + outTextures.clear(); + return false; + } + + outTextures.push_back(pTex); + pNode = pNode->next; + } + + return true; + }; + + auto tryMopUpTxd = [&](unsigned short txdId, CModelTexturesInfo* pInfo, bool isDeferred) + { + // Check if this slot has an MTA ownership pin. + CTxdPoolSA* pMopTxdPool = pGame ? static_cast(&pGame->GetPools()->GetTxdPool()) : nullptr; + const bool bPinned = pMopTxdPool && pMopTxdPool->IsSlotProtectedFromStreaming(txdId); + const int nPinRefs = bPinned ? 1 : 0; + + if (isDeferred) + { + if (ms_ModelTexturesInfoMap.find(txdId) != ms_ModelTexturesInfoMap.end()) + { + return; + } + + if (CTxdStore_GetNumRefs(txdId) > 1 + nPinRefs) + { + noteUncleaned(txdId); + return; + } + } + + RwTexDictionary* pTxd = CTxdStore_GetTxd(txdId); + const bool bTxdOk = pTxd != nullptr; + + if (!bTxdOk) + { + noteUncleaned(txdId); + return; + } + + // Only orphan if refs will hit 0 (accounting for MTA pin) + int currentRefs = CTxdStore_GetNumRefs(txdId); + if (currentRefs > 1 + nPinRefs) + { + noteUncleaned(txdId); + return; + } + + // Safety ref prevents race during orphan operation + CTxdStore_AddRef(txdId); + + // Enumerate and orphan textures (bounded traversal to avoid corruption hangs) + std::vector currentTextures; + const bool enumerationSucceeded = enumerateTxdTexturesBounded(pTxd, currentTextures); + + if (!enumerationSucceeded) + { + // Release safety ref, keep original ref + CTxdStore_RemoveRef(txdId); + noteUncleaned(txdId); + return; + } + + bool allOrphaned = true; + for (RwTexture* pTex : currentTextures) + { + SafeOrphanTexture(pTex, txdId); + + if (pTex && pTex->txd != nullptr) + { + allOrphaned = false; + } + } + + if (!allOrphaned) + { + int relinkedCount = 0; + for (RwTexture* pTex : currentTextures) + { + if (pTex && pTex->txd == nullptr) + { + // Nullify raster if already freed by previous mopup (shared raster scenario) + if (pTex->raster && mopupFreedRasters.find(pTex->raster) != mopupFreedRasters.end()) + reinterpret_cast(pTex->raster) = nullptr; + + if (RwTexDictionaryAddTexture(pTxd, pTex)) + ++relinkedCount; + } + } + CTxdStore_RemoveRef(txdId); + noteUncleaned(txdId); + return; + } + + int refsAfterOrphan = CTxdStore_GetNumRefs(txdId); + if (refsAfterOrphan > 2 + nPinRefs) + { + int relinkedCount = 0; + for (RwTexture* pTex : currentTextures) + { + if (pTex && pTex->txd == nullptr) + { + // Nullify raster if already freed by previous mopup (shared raster scenario) + if (pTex->raster && mopupFreedRasters.find(pTex->raster) != mopupFreedRasters.end()) + reinterpret_cast(pTex->raster) = nullptr; + + if (RwTexDictionaryAddTexture(pTxd, pTex)) + ++relinkedCount; + } + } + + CTxdStore_RemoveRef(txdId); + noteUncleaned(txdId); + return; + } + + // Release refs + if (pInfo) + pInfo->bHasLeakedTextures = false; + + // Release safety ref first + CTxdStore_RemoveRef(txdId); + + // Release our original ref + const char* tag = isDeferred ? "StaticResetModelTextureReplacing-mopup-deferred" : "StaticResetModelTextureReplacing-mopup"; + CRenderWareSA::DebugTxdRemoveRef(txdId, tag); + + // Release the MTA ownership pin. The hook guard still prevents + // CStreaming::RemoveModel while the slot is protected; we clear + // the protection flag immediately after the ref drop. + if (bPinned) + { + CTxdStore_RemoveRef(txdId); + if (pMopTxdPool) + pMopTxdPool->UnprotectSlotFromStreaming(txdId); + } + + int refsAfterDrop = CTxdStore_GetNumRefs(txdId); + if (refsAfterDrop == 0) + { + // Destroy orphaned textures with their rasters + for (RwTexture* pTex : currentTextures) + { + if (pTex && CanDestroyOrphanedTexture(pTex)) + { + mopupDestroyedTextures.insert(pTex); + RwRaster* pRaster = pTex->raster; + const bool bRasterAlreadyFreed = pRaster && (mopupFreedRasters.find(pRaster) != mopupFreedRasters.end()); + + if (bRasterAlreadyFreed) + { + SafeDestroyTexture(pTex); // Raster already freed, nullify pointer only + } + else + { + if (pRaster) + mopupFreedRasters.insert(pRaster); // Track before freeing for shared raster detection + SafeDestroyTextureWithRaster(pTex); + } + } + } + + CTxdStore_RemoveTxd(txdId); + } + else + { + // TXD has external refs - protect and defer + CTxdStore_AddRef(txdId); + + int relinkedCount = 0; + for (RwTexture* pTex : currentTextures) + { + if (pTex && pTex->txd == nullptr) + { + // Nullify raster if already freed by previous mopup (shared raster scenario) + if (pTex->raster && mopupFreedRasters.find(pTex->raster) != mopupFreedRasters.end()) + reinterpret_cast(pTex->raster) = nullptr; + + if (RwTexDictionaryAddTexture(pTxd, pTex)) + ++relinkedCount; + } + } + + if (pInfo) + pInfo->bHasLeakedTextures = true; + noteUncleaned(txdId); + return; + } + + noteCleaned(txdId); + }; + + // Restore original textures in shared (non-isolated) GTA TXDs. + // ModelInfoTXDDeferCleanup (used during delete-all) only removes tracking pointers + // but leaves replacement textures inside the TXD dictionaries and discards the originals. + // Without this restoration, replacement textures persist across server sessions: + // when the player reconnects, models restream from TXDs that still contain + // the previous server's replacement textures instead of the GTA originals. + // + // No rendering occurs between DeferCleanup and this point - both run within + // ~CClientGame's call stack on the main thread, so polluted TXDs are never + // sampled by the renderer. + std::size_t restoredTxdCount = 0; + std::size_t removedReplacementCount = 0; + std::size_t restoredOriginalCount = 0; + std::size_t skippedLeaked = 0; + std::size_t skippedActive = 0; + std::size_t skippedNoOriginals = 0; + std::size_t skippedNoTxd = 0; + std::size_t skippedMismatch = 0; + + for (auto& entry : ms_ModelTexturesInfoMap) + { + CModelTexturesInfo& info = entry.second; + if (info.bHasLeakedTextures) + { + // If the TXD is unchanged and originalTextures are intact, try to + // restore now - removing stale copies before masters' D3D is released. + RwTexDictionary* pLeakedTxd = CTxdStore_GetTxd(info.usTxdId); + + bool bCanRestore = pLeakedTxd && (!info.pTxd || info.pTxd == pLeakedTxd) && !info.originalTextures.empty() && info.usedByReplacements.empty(); + + if (bCanRestore) + { + // TXD unchanged - clear leaked flag and fall through to normal + // restoration, which removes stale copies and re-adds originals. + info.bHasLeakedTextures = false; + } + else if (!pLeakedTxd || (info.pTxd && info.pTxd != pLeakedTxd)) + { + // TXD unloaded or reloaded from disk - fresh data, no stale copies. + info.bHasLeakedTextures = false; + ++skippedNoTxd; + continue; + } + else + { + // Can't safely restore - leave for the mopup path below. + ++skippedLeaked; + continue; + } + } + + // Only restore if usedByReplacements is empty (DeferCleanup path) but originals exist. + // When usedByReplacements is non-empty, the normal removal path already handled it. + if (!info.usedByReplacements.empty()) + { + ++skippedActive; + continue; + } + if (info.originalTextures.empty()) + { + ++skippedNoOriginals; + continue; + } + + RwTexDictionary* pTxd = CTxdStore_GetTxd(info.usTxdId); + if (!pTxd) + { + // TXD was unloaded (e.g. streaming freed it during element cleanup). + // Safe to skip: when the TXD is reloaded from disk, it gets fresh + // original textures. GTA streaming doesn't run mid-destructor, so + // this path is a defensive guard rather than a common case. + ++skippedNoTxd; + continue; + } + + // Verify TXD pointer matches what we tracked - if GTA reloaded this TXD, + // originalTextures holds stale pointers and restoration would corrupt it + if (info.pTxd && info.pTxd != pTxd) + { + ++skippedMismatch; + continue; + } + + const std::size_t prevRemovedCount = removedReplacementCount; + const std::size_t prevRestoredCount = restoredOriginalCount; + + // Remove non-original (replacement) textures from the TXD + std::vector currentTextures; + GetTxdTextures(currentTextures, pTxd); + + for (RwTexture* pCurrent : currentTextures) + { + if (!IsReadableTexture(pCurrent)) + continue; + + if (info.originalTextures.find(pCurrent) != info.originalTextures.end()) + continue; // This is an original, keep it + + // This is a replacement texture left behind by DeferCleanup - remove it + // and make it a proper orphan (self-circular TXDList) so + // CanDestroyOrphanedTexture succeeds in the cleanup loop below. + SafeOrphanTexture(pCurrent, info.usTxdId); + ++removedReplacementCount; + + // Track for destruction at the end of StaticReset (g_LeakedMasterTextures loop). + // Without this, the orphaned RwTexture + raster + D3D texture leak permanently. + if (g_LeakedMasterTextures.insert(pCurrent).second && pCurrent->raster) + g_GlobalMtaRasterCache.insert(pCurrent->raster); + } + + // Re-add originals that were orphaned during ModelInfoTXDAddTextures + TxdTextureMap currentTxdMap; + BuildTxdTextureMapFast(pTxd, currentTxdMap); + + for (RwTexture* pOriginal : info.originalTextures) + { + if (!IsReadableTexture(pOriginal)) + continue; + + if (pOriginal->txd == pTxd) + continue; // Already in the TXD + + if (strnlen(pOriginal->name, RW_TEXTURE_NAME_LENGTH) >= RW_TEXTURE_NAME_LENGTH) + continue; + + // Skip if a texture with this name is already present + if (currentTxdMap.find(pOriginal->name) != currentTxdMap.end()) + continue; + + SafeOrphanTexture(pOriginal, info.usTxdId); + if (pOriginal->txd != nullptr) // Defensive: RwTexDictionaryRemoveTexture may fail on corrupt data + continue; + + if (RwTexDictionaryAddTexture(pTxd, pOriginal)) + { + currentTxdMap[pOriginal->name] = pOriginal; + ++restoredOriginalCount; + } + } + + // Only count and invalidate cache if we actually changed this TXD's contents + if (removedReplacementCount > prevRemovedCount || restoredOriginalCount > prevRestoredCount) + { + InvalidateTxdTextureMapCache(info.usTxdId); + ++restoredTxdCount; + } + } + + // Release the GetModelTexturesInfo ref for clean game-TXD entries. + // These refs were added by DebugTxdAddRef in GetModelTexturesInfo but never + // released by ModelInfoTXDDeferCleanup (which only removes replacement tracking) + // Must happen before the mopup loop below, as mopup may corrupt the heap, + // making later pool access unsafe (0xC0000374). + // Guard with GetNumRefs > 1 to avoid triggering CStreaming::RemoveModel + // (which is a heap operation) when earlier cleanup could have corrupted the heap. + for (auto& entry : ms_ModelTexturesInfoMap) + { + if (!entry.second.bHasLeakedTextures && CTxdStore_GetNumRefs(entry.first) > 1) + DebugTxdRemoveRef(entry.first, "StaticResetModelTextureReplacing-clean"); + } + + for (auto iter = ms_ModelTexturesInfoMap.begin(); iter != ms_ModelTexturesInfoMap.end();) + { + auto& info = iter->second; + if (!info.bHasLeakedTextures) + { + ++iter; + continue; + } + + tryMopUpTxd(info.usTxdId, &info, false); + + if (!info.bHasLeakedTextures) + { + iter = ms_ModelTexturesInfoMap.erase(iter); + } + else + { + ++iter; + } + } + + // Retry deferred TXDs kept alive across resets + for (unsigned short txdId : deferredLeakRetry) + { + tryMopUpTxd(txdId, nullptr, true); + } + + // Final cleanup pass - skip all GTA TXD pool operations for both branches. + // Earlier operations in this function (mopup, orphan cleanup, texture + // destruction) may corrupt the GTA heap without immediate detection. + // Any subsequent pool access - even on valid slots via CTxdStore_GetTxd - + // can trigger deferred heap corruption (0xC0000374). + // Clean entry refs were already released before the mopup loop above. + + for (auto iter = ms_ModelTexturesInfoMap.begin(); iter != ms_ModelTexturesInfoMap.end();) + { + CModelTexturesInfo& info = iter->second; + + if (!info.bHasLeakedTextures) + { + // Erase entry - ref already released before mopup + iter = ms_ModelTexturesInfoMap.erase(iter); + } + else + { + // Keep leaked entry but clear replacement linkage (script objects destroyed) + info.usedByReplacements.clear(); + info.originalTextures.clear(); + info.originalTexturesByName.clear(); + info.bReapplyingTextures = false; + ++iter; + } + } + + // Rasters kept alive by orphaned copies (bSkipRasterNull path) must not be freed + // when their master is destroyed. Treating them as "already freed" makes the loop + // below use SafeDestroyTexture (which only nulls the raster pointer) rather than + // RwTextureDestroy (which would free the raster the orphaned copy still references). + for (RwRaster* pKeptRaster : g_OrphanedCopyRasters) + mopupFreedRasters.insert(pKeptRaster); + g_OrphanedCopyRasters.clear(); + + // Destroy leaked master textures. Rasters may be dangling if mopup freed shared rasters. + if (!g_LeakedMasterTextures.empty()) + { + for (RwTexture* pDestroyed : mopupDestroyedTextures) + g_LeakedMasterTextures.erase(pDestroyed); + + for (RwTexture* pMaster : g_LeakedMasterTextures) + { + if (!pMaster) + { + continue; + } + + if (!IsReadableTexture(pMaster)) + { + continue; + } + + // Ensure texture is orphaned (not linked in any TXD) + if (pMaster->txd != nullptr) + { + SafeOrphanTexture(pMaster); + } + + if (CanDestroyOrphanedTexture(pMaster)) + { + RwRaster* pRaster = pMaster->raster; + const bool bRasterAlreadyFreed = pRaster && (mopupFreedRasters.find(pRaster) != mopupFreedRasters.end()); + + if (bRasterAlreadyFreed || pMaster->refs > 1) + { + // Raster already freed by another texture, or texture has external refs + // (e.g. materials still reference this copy). Null the raster to prevent + // dangling pointers. If both a master and its copy take this path, + // the raster leaks - better than crashing. + SafeDestroyTexture(pMaster); + } + else + { + if (pRaster) + mopupFreedRasters.insert(pRaster); // Track for shared raster detection + RwTextureDestroy(pMaster); // D3D prepped earlier, safe to free + } + } + } + + g_LeakedMasterTextures.clear(); + } + + g_GlobalMtaRasterCache.clear(); + InvalidateGlobalMtaRasterCache(); + + // Release parent TXD refs held for script TXDs before clearing the set. + // CleanupReplacementsInTxdSlot handles this during normal Lua cleanup, but + // script TXD entries that survive to session reset must be released here or + // the parent ref stays live across sessions. + if (!g_ScriptTxdSlotsWithParentPin.empty() && pGame) + { + auto* pTxdPoolSA = static_cast(&pGame->GetPools()->GetTxdPool()); + if (pTxdPoolSA) + { + for (unsigned short usTxdSlotId : g_ScriptTxdSlotsWithParentPin) + { + auto* pSlot = pTxdPoolSA->GetTextureDictonarySlot(usTxdSlotId); + if (pSlot && pSlot->usParentIndex != static_cast(-1)) + { + if (CTxdStore_GetTxd(pSlot->usParentIndex) != nullptr) + CTxdStore_RemoveRef(pSlot->usParentIndex); + } + } + } + } + g_ScriptTxdSlotsWithParentPin.clear(); + + g_TxdToModelMap.clear(); + g_uiTxdToModelMapGeneration = ~0u; + + g_ReleasedD3DTextures.clear(); +} + +//////////////////////////////////////////////////////////////// +// +// CRenderWareSA::StaticResetShaderSupport +// Cleans shader entries for MTA-managed TXD slots (>= SA pool capacity), +// preserves GTA base textures (slots 0 to SA_TXD_POOL_CAPACITY-1). +//////////////////////////////////////////////////////////////// +void CRenderWareSA::StaticResetShaderSupport() +{ + // Safety limit to prevent freeze on corrupted/huge maps + constexpr size_t MAX_CLEANUP_ITERATIONS = 50000; + if (m_TexInfoMap.size() > MAX_CLEANUP_ITERATIONS) + { + // Emergency path: >50k entries indicates corruption. Delete fast to prevent freeze. + for (auto& pair : m_TexInfoMap) + { + STexInfo* pTexInfo = pair.second; + if (pTexInfo) + { + OnTextureStreamOut(pTexInfo); + delete pTexInfo; + } + } + m_TexInfoMap.clear(); + m_D3DDataTexInfoMap.clear(); + m_ScriptTexInfoMap.clear(); + return; + } + + // Remove custom shader entries from m_TexInfoMap (preserves GTA base textures) + for (auto iter = m_TexInfoMap.begin(); iter != m_TexInfoMap.end();) + { + STexInfo* pTexInfo = iter->second; + + if (!pTexInfo) + { + iter = m_TexInfoMap.erase(iter); + continue; + } + + // Remove: custom TXD entries (overflow/MTA-managed slots) and script-loaded textures + // Keep: GTA base textures (slot < SA pool capacity) and FAKE_NO_TEXTURE singleton + const bool bIsCustomTxdEntry = pTexInfo->texTag.m_bUsingTxdId && pTexInfo->texTag.m_usTxdId >= CTxdPoolSA::SA_TXD_POOL_CAPACITY; + const bool bIsScriptTexture = !pTexInfo->texTag.m_bUsingTxdId && (pTexInfo->texTag.m_pTex != FAKE_RWTEXTURE_NO_TEXTURE); + const bool bShouldRemove = bIsCustomTxdEntry || bIsScriptTexture; + + if (bShouldRemove) + { + OnTextureStreamOut(pTexInfo); + DestroyTexInfo(pTexInfo); + iter = m_TexInfoMap.erase(iter); + } + else + { + ++iter; + } } - pReplacementTextures->textures.clear(); } diff --git a/Client/game_sa/CRenderWareSA.TxdRightSizing.cpp b/Client/game_sa/CRenderWareSA.TxdRightSizing.cpp index 4a131378a25..00878675793 100644 --- a/Client/game_sa/CRenderWareSA.TxdRightSizing.cpp +++ b/Client/game_sa/CRenderWareSA.TxdRightSizing.cpp @@ -30,23 +30,45 @@ extern CGameSA* pGame; ///////////////////////////////////////////////////////////////////////////// bool CRenderWareSA::RightSizeTxd(const SString& strInTxdFilename, const SString& strOutTxdFilename, uint uiSizeLimit) { - // - // Read txd from memory - // + constexpr std::size_t RW_CHUNK_HEADER_SIZE = 12; + constexpr std::uint32_t RW_CHUNK_TYPE_TXD = 0x16; + constexpr std::uint32_t MAX_SANE_CHUNK_SIZE = 512 * 1024 * 1024; + + SString headerData; + if (!FileLoad(std::nothrow, strInTxdFilename, headerData, RW_CHUNK_HEADER_SIZE)) + return false; + + if (headerData.size() < RW_CHUNK_HEADER_SIZE) + return false; + + std::uint32_t chunkType = 0; + std::uint32_t chunkSize = 0; + std::memcpy(&chunkType, headerData.data(), sizeof(chunkType)); + std::memcpy(&chunkSize, headerData.data() + 4, sizeof(chunkSize)); + + if (chunkType != RW_CHUNK_TYPE_TXD) + return false; + + if (chunkSize > MAX_SANE_CHUNK_SIZE) + return false; + + std::uint64_t fileSize = FileSize(strInTxdFilename); + if (fileSize < RW_CHUNK_HEADER_SIZE + chunkSize) + return false; + RwStream* pStream = RwStreamOpen(STREAM_TYPE_FILENAME, STREAM_MODE_READ, *strInTxdFilename); - if (pStream == NULL) + if (!pStream) return false; - // Find our txd chunk - if (RwStreamFindChunk(pStream, 0x16, NULL, NULL) == false) + if (!RwStreamFindChunk(pStream, RW_CHUNK_TYPE_TXD, nullptr, nullptr)) { - RwStreamClose(pStream, NULL); + RwStreamClose(pStream, nullptr); return false; } - // read the txd RwTexDictionary* pTxd = RwTexDictionaryGtaStreamRead(pStream); - RwStreamClose(pStream, NULL); + RwStreamClose(pStream, nullptr); + if (!pTxd) return false; @@ -69,15 +91,35 @@ bool CRenderWareSA::RightSizeTxd(const SString& strInTxdFilename, const SString& if (pNewRwTexture && pNewRwTexture != pTexture) { // Replace texture in txd if changed - RwTextureDestroy(pTexture); - RwTexDictionaryAddTexture(pTxd, pNewRwTexture); - bChanged = true; + // Remove old texture from TXD safely before destroying it + pGame->GetRenderWareSA()->RwTexDictionaryRemoveTexture(pTxd, pTexture); + if (pTexture->txd == nullptr) + { + RwTextureDestroy(pTexture); + // Initialize new texture's TXDList before adding + pNewRwTexture->TXDList.next = &pNewRwTexture->TXDList; + pNewRwTexture->TXDList.prev = &pNewRwTexture->TXDList; + pNewRwTexture->txd = nullptr; + RwTexDictionaryAddTexture(pTxd, pNewRwTexture); + bChanged = true; + } + else + { + // Unlink failed - discard new texture to avoid corruption + pNewRwTexture->TXDList.next = &pNewRwTexture->TXDList; + pNewRwTexture->TXDList.prev = &pNewRwTexture->TXDList; + pNewRwTexture->txd = nullptr; + RwTextureDestroy(pNewRwTexture); + } } else { - // Keep texture (Reinsert to preserve order for easier debugging) - RwTexDictionaryRemoveTexture(pTxd, pTexture); - RwTexDictionaryAddTexture(pTxd, pTexture); + // Reinsert to preserve order (only if texture still linked to this TXD) + if (pTexture && pTexture->txd == pTxd) + { + if (pGame->GetRenderWareSA()->RwTexDictionaryRemoveTexture(pTxd, pTexture)) + RwTexDictionaryAddTexture(pTxd, pTexture); + } } } @@ -171,12 +213,13 @@ RwTexture* CRenderWareSA::RightSizeTexture(RwTexture* pTexture, uint uiSizeLimit // Lock mip level 0 if required D3DLOCKED_RECT lockedRect = pD3DRaster->lockedRect; bool bNeedOwnLock = (pD3DRaster->lockedLevel != 0) || !pD3DRaster->lockedSurface; - if (bNeedOwnLock) + if (bNeedOwnLock) { if (FAILED(pD3DRaster->texture->LockRect(0, &lockedRect, NULL, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) { strError = "pD3DRaster->texture->LockRect failed"; return NULL; } +} // Try resize CBuffer newPixelBuffer; @@ -201,14 +244,13 @@ RwTexture* CRenderWareSA::RightSizeTexture(RwTexture* pTexture, uint uiSizeLimit header.TextureFormat.vAddressing = (pTexture->flags & 0xf000) >> 12; memcpy(header.TextureFormat.name, pTexture->name, 32); memcpy(header.TextureFormat.maskName, pTexture->mask, 32); - header.RasterFormat.rasterFormat = (pRaster->format & 0x0f) - << 8; // ( dxt1 = 0x00000100 or 0x00000200 / dxt3 = 0x00000300 ) | 0x00008000 mipmaps? + header.RasterFormat.rasterFormat = (pRaster->format & 0x0f) << 8; // ( dxt1 = 0x00000100 or 0x00000200 / dxt3 = 0x00000300 ) | 0x00008000 mipmaps? header.RasterFormat.d3dFormat = pD3DRaster->format; - header.RasterFormat.width = uiReqWidth; - header.RasterFormat.height = uiReqHeight; - header.RasterFormat.depth = pRaster->depth; + header.RasterFormat.width = static_cast(uiReqWidth); + header.RasterFormat.height = static_cast(uiReqHeight); + header.RasterFormat.depth = static_cast(pRaster->depth); header.RasterFormat.numLevels = 1; - header.RasterFormat.rasterType = pRaster->type; // dxt1 = 4 / dxt3 = 4 + header.RasterFormat.rasterType = pRaster->type; // dxt1 = 4 / dxt3 = 4 header.RasterFormat.alpha = bHasAlpha; header.RasterFormat.cubeTexture = bIsCubeTexture; header.RasterFormat.autoMipMaps = false; @@ -218,7 +260,7 @@ RwTexture* CRenderWareSA::RightSizeTexture(RwTexture* pTexture, uint uiSizeLimit CBuffer nativeData; CBufferWriteStream stream(nativeData); stream.Write(1); - stream.Write(0); // Size ignored + stream.Write(0); // Size ignored stream.Write(0x1803FFFF); stream.WriteBytes(&header, sizeof(header)); stream.Write(newPixelBuffer.GetSize()); diff --git a/Client/game_sa/CRenderWareSA.cpp b/Client/game_sa/CRenderWareSA.cpp index 44a83535144..8468355a650 100644 --- a/Client/game_sa/CRenderWareSA.cpp +++ b/Client/game_sa/CRenderWareSA.cpp @@ -12,6 +12,13 @@ *****************************************************************************/ #include "StdInc.h" +#include +#include +#include +#include +#include +#include +#include #include #include #define RWFUNC_IMPLEMENT @@ -21,22 +28,56 @@ #include "CGameSA.h" #include "CRenderWareSA.h" #include "CRenderWareSA.ShaderMatching.h" +#include "CTxdPoolSA.h" #include "gamesa_renderware.h" #include "gamesa_renderware.hpp" extern CCoreInterface* g_pCore; extern CGameSA* pGame; +// RenderWare binary chunk format constants (shared by ReadTXD, ReadDFF, +// LoadTxdSlotFromBuffer, etc.) +namespace +{ + constexpr std::size_t RW_CHUNK_HEADER_SIZE = 12; + constexpr std::uint32_t RW_CHUNK_TYPE_DFF = 0x10; + constexpr std::uint32_t RW_CHUNK_TYPE_TXD = 0x16; + constexpr std::uint32_t MAX_SANE_CHUNK_SIZE = 512 * 1024 * 1024; +} // namespace + +void CRenderWareSA::DebugTxdAddRef(unsigned short usTxdId, const char* /*tag*/, bool /*enableSafetyPin*/) +{ + if (!pGame || !pGame->GetRenderWareSA()) + return; + // Validate slot before AddRef to avoid crash on invalid/destroyed slots + if (CTxdStore_GetTxd(usTxdId) == nullptr) + return; + CTxdStore_AddRef(usTxdId); +} + +void CRenderWareSA::DebugTxdRemoveRef(unsigned short usTxdId, const char* /*tag*/) +{ + if (!pGame || !pGame->GetRenderWareSA()) + return; + // Validate slot before RemoveRef to avoid crash on invalid/destroyed slots + if (CTxdStore_GetTxd(usTxdId) == nullptr) + return; + CTxdStore_RemoveRef(usTxdId); +} + // RwFrameForAllObjects struct and callback used to replace dynamic vehicle parts struct SReplaceParts { - const char* szName; // name of the part you want to replace (e.g. 'door_lf' or 'door_rf') - unsigned char ucIndex; // index counter for internal usage (0 is the 'ok' part model, 1 is the 'dam' part model) - RpAtomicContainer* pReplacements; // replacement atomics - unsigned int uiReplacements; // number of replacements + const char* szName; // name of the part you want to replace (e.g. 'door_lf' or 'door_rf') + unsigned char ucIndex; // index counter for internal usage (0 is the 'ok' part model, 1 is the 'dam' part model) + RpAtomicContainer* pReplacements; // replacement atomics + unsigned int uiReplacements; // number of replacements }; static RwObject* ReplacePartsCB(RwObject* object, SReplaceParts* data) { + if (!object) [[unlikely]] + return object; + RpAtomic* Atomic = (RpAtomic*)object; char szAtomicName[16] = {0}; @@ -44,10 +85,11 @@ static RwObject* ReplacePartsCB(RwObject* object, SReplaceParts* data) for (unsigned int i = 0; i < data->uiReplacements; i++) { // get the correct atomic name based on the object # in our parent frame - if (data->ucIndex == 0) + if (data->ucIndex == 0) { snprintf(&szAtomicName[0], 16, "%s_ok", data->szName); - else + } else { snprintf(&szAtomicName[0], 16, "%s_dam", data->szName); +} // see if we have such an atomic in our replacement atomics array if (strncmp(&data->pReplacements[i].szName[0], &szAtomicName[0], 16) == 0) @@ -69,6 +111,9 @@ static RwObject* ReplacePartsCB(RwObject* object, SReplaceParts* data) // RpClumpForAllAtomics callback used to add atomics to a vehicle static bool AddAllAtomicsCB(RpAtomic* atomic, void* pClump) { + if (!atomic || !pClump) [[unlikely]] + return false; + RpClump* data = reinterpret_cast(pClump); RwFrame* pFrame = RpGetFrame(data); @@ -82,13 +127,16 @@ static bool AddAllAtomicsCB(RpAtomic* atomic, void* pClump) // RpClumpForAllAtomics struct and callback used to replace all wheels with a given wheel model struct SReplaceWheels { - const char* szName; // name of the new wheel model - RpClump* pClump; // the vehicle's clump - RpAtomicContainer* pReplacements; // replacement atomics - unsigned int uiReplacements; // number of replacements + const char* szName; // name of the new wheel model + RpClump* pClump; // the vehicle's clump + RpAtomicContainer* pReplacements; // replacement atomics + unsigned int uiReplacements; // number of replacements }; static bool ReplaceWheelsCB(RpAtomic* atomic, void* pData) { + if (!atomic || !pData) [[unlikely]] + return false; + SReplaceWheels* data = reinterpret_cast(pData); RwFrame* Frame = RpGetFrame(atomic); @@ -112,6 +160,7 @@ static bool ReplaceWheelsCB(RpAtomic* atomic, void* pData) // delete the current atomic RpClumpRemoveAtomic(data->pClump, atomic); + RpAtomicDestroy(atomic); // Destroy removed atomic to prevent leak } } } @@ -122,12 +171,15 @@ static bool ReplaceWheelsCB(RpAtomic* atomic, void* pData) // RpClumpForAllAtomics struct and callback used to replace all atomics for a vehicle struct SReplaceAll { - RpClump* pClump; // the vehicle's clump - RpAtomicContainer* pReplacements; // replacement atomics - unsigned int uiReplacements; // number of replacements + RpClump* pClump; // the vehicle's clump + RpAtomicContainer* pReplacements; // replacement atomics + unsigned int uiReplacements; // number of replacements }; static bool ReplaceAllCB(RpAtomic* atomic, void* pData) { + if (!atomic || !pData) [[unlikely]] + return false; + SReplaceAll* data = reinterpret_cast(pData); RwFrame* Frame = RpGetFrame(atomic); if (Frame == NULL) @@ -157,26 +209,34 @@ static bool ReplaceAllCB(RpAtomic* atomic, void* pData) // remove the current atomic RpClumpRemoveAtomic(data->pClump, atomic); + RpAtomicDestroy(atomic); // Destroy removed atomic to prevent leak } } return true; } -// RpClumpForAllAtomics struct and callback used to load the atomics from a specific clump into a container +// Load atomics from clump into container (caller manages lifetime) struct SLoadAtomics { - RpAtomicContainer* pReplacements; // replacement atomics - unsigned int uiReplacements; // number of replacements + RpAtomicContainer* pReplacements; // replacement atomics + unsigned int uiReplacements; // number of replacements }; static bool LoadAtomicsCB(RpAtomic* atomic, void* pData) { + if (!atomic || !pData) [[unlikely]] + return false; + SLoadAtomics* data = reinterpret_cast(pData); RwFrame* Frame = RpGetFrame(atomic); - // add the atomic to the container + if (!Frame) [[unlikely]] + return false; + + // Add atomic to container data->pReplacements[data->uiReplacements].atomic = atomic; strncpy(&data->pReplacements[data->uiReplacements].szName[0], &Frame->szName[0], 16); + data->pReplacements[data->uiReplacements].szName[16] = '\0'; // and increment the counter data->uiReplacements++; @@ -209,39 +269,89 @@ CRenderWareSA::~CRenderWareSA() // Reads and parses a TXD file specified by a path (szTXD) RwTexDictionary* CRenderWareSA::ReadTXD(const SString& strFilename, const SString& buffer) { - // open the stream - RwStream* streamTexture; - RwBuffer streamBuffer; - if (!buffer.empty()) + if (buffer.empty() && strFilename.empty()) + return nullptr; + + const bool bUsingBuffer = !buffer.empty(); + + std::uint32_t chunkType = 0; + std::uint32_t chunkSize = 0; + + if (!bUsingBuffer) { - streamBuffer.ptr = (void*)buffer.data(); - streamBuffer.size = buffer.size(); - streamTexture = RwStreamOpen(STREAM_TYPE_BUFFER, STREAM_MODE_READ, &streamBuffer); + SString headerData; + if (!FileLoad(std::nothrow, strFilename, headerData, RW_CHUNK_HEADER_SIZE)) + return nullptr; + + if (headerData.size() < RW_CHUNK_HEADER_SIZE) + return nullptr; + + std::memcpy(&chunkType, headerData.data(), sizeof(chunkType)); + std::memcpy(&chunkSize, headerData.data() + 4, sizeof(chunkSize)); + + if (chunkType != RW_CHUNK_TYPE_TXD) + return nullptr; + + if (chunkSize > MAX_SANE_CHUNK_SIZE) + return nullptr; + + std::uint64_t fileSize = FileSize(strFilename); + if (fileSize < RW_CHUNK_HEADER_SIZE + chunkSize) + return nullptr; } else - streamTexture = RwStreamOpen(STREAM_TYPE_FILENAME, STREAM_MODE_READ, *strFilename); + { + if (buffer.size() < RW_CHUNK_HEADER_SIZE) + return nullptr; + + std::memcpy(&chunkType, buffer.data(), sizeof(chunkType)); + std::memcpy(&chunkSize, buffer.data() + 4, sizeof(chunkSize)); - // check for errors - if (streamTexture == NULL) - return NULL; + if (chunkType != RW_CHUNK_TYPE_TXD) + return nullptr; - // TXD header id: 0x16 - // find our txd chunk (dff loads textures, so correct loading order is: txd, dff) - if (RwStreamFindChunk(streamTexture, 0x16, NULL, NULL) == false) + if (chunkSize > MAX_SANE_CHUNK_SIZE) + return nullptr; + + if (buffer.size() < RW_CHUNK_HEADER_SIZE + chunkSize) + return nullptr; + } + + RwStream* pStream = nullptr; + RwBuffer rwBuffer{}; + + if (bUsingBuffer) + { + rwBuffer.ptr = const_cast(buffer.data()); + + // Limit to actual chunk boundaries + // This buffer trim ensures RW's stream reader only sees actual TXD data, not trailing garbage + // from IMG sector alignment. Avoids some spurious "TXD parsed successfully but contains no valid textures" errors + rwBuffer.size = static_cast(RW_CHUNK_HEADER_SIZE + chunkSize); + pStream = RwStreamOpen(STREAM_TYPE_BUFFER, STREAM_MODE_READ, &rwBuffer); + } + else { - RwStreamClose(streamTexture, NULL); - return NULL; + pStream = RwStreamOpen(STREAM_TYPE_FILENAME, STREAM_MODE_READ, *strFilename); } - // read the texture dictionary from our model (txd) - RwTexDictionary* pTex = RwTexDictionaryGtaStreamRead(streamTexture); + if (!pStream) + return nullptr; - // close the stream - RwStreamClose(streamTexture, NULL); + if (!RwStreamFindChunk(pStream, RW_CHUNK_TYPE_TXD, nullptr, nullptr)) + { + RwStreamClose(pStream, nullptr); + return nullptr; + } - ScriptAddedTxd(pTex); + RwTexDictionary* pTxd = RwTexDictionaryGtaStreamRead(pStream); + RwStreamClose(pStream, nullptr); - return pTex; + if (!pTxd) + return nullptr; + + ScriptAddedTxd(pTxd); + return pTxd; } // Reads and parses a DFF file specified by a path (szDFF) into a CModelInfo identified by the object id (usModelID) @@ -249,69 +359,214 @@ RwTexDictionary* CRenderWareSA::ReadTXD(const SString& strFilename, const SStrin // Any custom TXD should be imported before this call RpClump* CRenderWareSA::ReadDFF(const SString& strFilename, const SString& buffer, unsigned short usModelID, bool bLoadEmbeddedCollisions) { - // Set correct TXD as materials are processed at the same time if (usModelID != 0) { - unsigned short usTxdId = ((CBaseModelInfoSAInterface**)ARRAY_ModelInfo)[usModelID]->usTextureDictionary; - SetTextureDict(usTxdId); + CBaseModelInfoSAInterface* pModelInfo = ((CBaseModelInfoSAInterface**)ARRAY_ModelInfo)[usModelID]; + if (pModelInfo) + { + unsigned short usTxdId = pModelInfo->usTextureDictionary; + SetTextureDict(usTxdId); + } + } + + const bool bUsingBuffer = !buffer.empty(); + + std::uint32_t chunkType = 0; + std::uint32_t chunkSize = 0; + + if (!bUsingBuffer) + { + if (strFilename.empty()) + return nullptr; + + SString headerData; + if (!FileLoad(std::nothrow, strFilename, headerData, RW_CHUNK_HEADER_SIZE)) + return nullptr; + + if (headerData.size() < RW_CHUNK_HEADER_SIZE) + return nullptr; + + std::memcpy(&chunkType, headerData.data(), sizeof(chunkType)); + std::memcpy(&chunkSize, headerData.data() + 4, sizeof(chunkSize)); + + if (chunkSize > MAX_SANE_CHUNK_SIZE) + return nullptr; + + std::uint64_t fileSize = FileSize(strFilename); + if (fileSize < RW_CHUNK_HEADER_SIZE + chunkSize) + return nullptr; + } + else + { + if (buffer.size() < RW_CHUNK_HEADER_SIZE) + return nullptr; + + std::memcpy(&chunkType, buffer.data(), sizeof(chunkType)); + std::memcpy(&chunkSize, buffer.data() + 4, sizeof(chunkSize)); + + if (chunkSize > MAX_SANE_CHUNK_SIZE) + return nullptr; + + if (buffer.size() < RW_CHUNK_HEADER_SIZE + chunkSize) + return nullptr; } - // open the stream - RwStream* streamModel; - RwBuffer streamBuffer; - if (!buffer.empty()) + RwStream* pStream = nullptr; + RwBuffer rwBuffer{}; + + if (bUsingBuffer) { - streamBuffer.ptr = (void*)buffer.data(); - streamBuffer.size = buffer.size(); - streamModel = RwStreamOpen(STREAM_TYPE_BUFFER, STREAM_MODE_READ, &streamBuffer); + rwBuffer.ptr = const_cast(buffer.data()); + + // Use the full buffer size - do NOT trim to (RW_CHUNK_HEADER_SIZE + chunkSize). + // RpClumpStreamRead uses count-based loop termination (numAtomics/numLights/numCameras from the + // struct header), not byte-based tracking against the outer chunk's declared size. Any trailing + // IMG sector padding is therefore harmless - RW stops reading once all declared sub-chunks are + // consumed. Trimming to chunkSize causes E_RW_ENDOFSTREAM (error 5) when inner sub-chunk totals + // slightly exceed the outer header's declared chunkSize, which happens with valid SA DFF files. + // SA's native CFileLoader_LoadAtomicFile also does not trim. + rwBuffer.size = static_cast(buffer.size()); + pStream = RwStreamOpen(STREAM_TYPE_BUFFER, STREAM_MODE_READ, &rwBuffer); } else - streamModel = RwStreamOpen(STREAM_TYPE_FILENAME, STREAM_MODE_READ, *strFilename); + { + pStream = RwStreamOpen(STREAM_TYPE_FILENAME, STREAM_MODE_READ, *strFilename); + } - // get the modelinfo array DWORD* pPool = (DWORD*)ARRAY_ModelInfo; - // check for errors - if (streamModel == NULL) - return NULL; + if (!pStream) + return nullptr; - // DFF header id: 0x10 - // find our dff chunk - if (RwStreamFindChunk(streamModel, 0x10, NULL, NULL) == false) + if (!RwStreamFindChunk(pStream, RW_CHUNK_TYPE_DFF, nullptr, nullptr)) { - RwStreamClose(streamModel, NULL); - return NULL; + RwStreamClose(pStream, nullptr); + return nullptr; } - // rockstar's collision hack: set the global particle emitter to the modelinfo pointer of this model if (bLoadEmbeddedCollisions) + { + // Vehicles have their collision loaded through the CollisionModel plugin, so we need to remove the current collision to prevent a memory leak. + // This needs to be done here before reading the stream data, because plugins are read in RpClumpStreamRead. + CModelInfo* modelInfo = pGame->GetModelInfo(usModelID); + if (modelInfo) + { + if (auto* modelInfoInterface = modelInfo->GetInterface()) + ((void(__thiscall*)(CBaseModelInfoSAInterface*))0x4C4C40)(modelInfoInterface); // CBaseModelInfo::DeleteCollisionModel + } + + // rockstar's collision hack + // It sets the pointer CCollisionPlugin::ms_currentModel to the model info of the given vehicle in order to correctly set up the vehicle’s + // collision during collision plugin reading (0x41B2BD). RpPrtStdGlobalDataSetStreamEmbedded((void*)pPool[usModelID]); + // Call CVehicleModelInfo::UseCommonVehicleTexDicationary + ((void(__cdecl*)())0x4C75A0)(); + } + + // Clear any stale RW error before reading, so post-failure RwErrorGet captures only fresh errors + { + RwError staleErr{}; + RwErrorGet(&staleErr); + } + // read the clump with all its extensions - RpClump* pClump = RpClumpStreamRead(streamModel); + RpClump* pClump = RpClumpStreamRead(pStream); + + if (!pClump) + { + int txdId = -1; + if (usModelID != 0) + { + auto* pInfo = ((CBaseModelInfoSAInterface**)ARRAY_ModelInfo)[usModelID]; + if (pInfo) + txdId = pInfo->usTextureDictionary; + } + + RwError rwError{}; + RwErrorGet(&rwError); + + std::uint32_t versionStamp = 0; + if (bUsingBuffer && buffer.size() >= RW_CHUNK_HEADER_SIZE) + std::memcpy(&versionStamp, buffer.data() + 8, sizeof(versionStamp)); + + // Also capture the stream position after the failed read + unsigned int streamPos = 0; + unsigned int streamSz = 0; + if (bUsingBuffer && pStream) + { + streamPos = pStream->data.position; + streamSz = pStream->data.size; + } + + AddReportLog(8630, SString("ReadDFF: RpClumpStreamRead null model=%d txd=%d buf=%d bufSz=%u chunkSz=%u ver=0x%X rwErr=%d/%d sPos=%u sSz=%u", usModelID, + txdId, bUsingBuffer ? 1 : 0, bUsingBuffer ? static_cast(buffer.size()) : 0u, chunkSize, versionStamp, + rwError.err1, rwError.err2, streamPos, streamSz)); + } - // reset collision hack if (bLoadEmbeddedCollisions) - RpPrtStdGlobalDataSetStreamEmbedded(NULL); + { + // reset collision hack + RpPrtStdGlobalDataSetStreamEmbedded(nullptr); + + // Call CVehicleModelInfo::StopUsingCommonVehicleTexDicationary + ((void(__cdecl*)())0x4C75C0)(); + } - // close the stream - RwStreamClose(streamModel, NULL); + RwStreamClose(pStream, nullptr); return pClump; } // // Returns list of atomics inside a clump +// Uses a visited set to detect cycles in corrupted linked lists // void CRenderWareSA::GetClumpAtomicList(RpClump* pClump, std::vector& outAtomicList) { - RpClumpForAllAtomics( - pClump, - [](RpAtomic* pAtomic, void* pData) { - reinterpret_cast*>(pData)->push_back(pAtomic); + // Track visited atomics to detect cycles from corrupted linked lists. + struct VisitedTracker + { + std::vector* pList; + std::unordered_set visited; + std::size_t iterations; + bool bStop; + std::size_t maxAtomics; + + VisitedTracker(std::vector* list, std::size_t maxCount) : pList(list), iterations(0), bStop(false), maxAtomics(maxCount) {} + }; + + auto ForAllAtomicsCB = [](RpAtomic* pAtomic, void* pData) -> bool + { + auto* t = reinterpret_cast(pData); + + if (t->bStop) + return false; // Stop iteration once we decided to bail + + if (++t->iterations > t->maxAtomics) + { + t->bStop = true; + return false; + } + + // Check if we've seen this atomic before (cycle detection) + if (t->visited.find(pAtomic) != t->visited.end()) + { + // Skip duplicates but keep iterating to avoid truncating legitshared atomics return true; - }, - &outAtomicList); + } + + t->visited.insert(pAtomic); + + if (pAtomic && SharedUtil::IsReadablePointer(pAtomic, sizeof(RpAtomic))) + t->pList->push_back(pAtomic); + + return true; + }; + + VisitedTracker tracker(&outAtomicList, 4096); + + RpClumpForAllAtomics(pClump, ForAllAtomicsCB, &tracker); } // @@ -344,9 +599,10 @@ bool CRenderWareSA::DoContainTheSameGeometry(RpClump* pClumpA, RpClump* pClumpB, MapInsert(geometryListA, atomicListA[i]->geometry); uint uiInBoth = 0; - for (uint i = 0; i < atomicListB.size(); i++) + for (uint i = 0; i < atomicListB.size(); i++) { if (MapContains(geometryListA, atomicListB[i]->geometry)) uiInBoth++; +} // If less than 50% match then assume it is not the same if (uiInBoth * 2 < atomicListB.size() || atomicListB.size() == 0) @@ -355,6 +611,278 @@ bool CRenderWareSA::DoContainTheSameGeometry(RpClump* pClumpA, RpClump* pClumpB, return true; } +// Helpers for rebinding model textures to a different TXD. +// When a model's TXD slot is changed, its loaded RwObject still holds pointers +// to textures from the old TXD. These helpers update material texture pointers +// to reference matching textures from the new TXD by name lookup. +namespace +{ + // Hash functor for texture name lookup (bounded to RW_TEXTURE_NAME_LENGTH). + // Case-insensitive to match GTA:SA's RwTexDictionaryFindNamedTexture (0x7F39F0). + struct TxdTextureNameHash + { + static constexpr std::size_t HASH_INIT = 2166136261u; + static constexpr std::size_t HASH_MULTIPLIER = 16777619u; + + std::size_t operator()(const char* s) const noexcept + { + if (!s) + return 0; + std::size_t h = HASH_INIT; + for (std::size_t i = 0; i < RW_TEXTURE_NAME_LENGTH && s[i]; ++i) + { + h ^= static_cast(std::tolower(static_cast(s[i]))); + h *= HASH_MULTIPLIER; + } + return h; + } + }; + + struct TxdTextureNameEq + { + bool operator()(const char* a, const char* b) const noexcept + { + if (a == b) + return true; + if (!a || !b) + return false; + return _strnicmp(a, b, RW_TEXTURE_NAME_LENGTH) == 0; + } + }; + + using TxdTextureMap = std::unordered_map; + + // Build name->texture map for a TXD slot, including textures from parent TXDs. + // Walks the parent chain via the pool-level usParentIndex (the TXD parent linkage in SA). + // Keys point directly into RwTexture::name buffers. + // Iterates from outermost parent to child, so child textures overwrite parent on name conflict. + TxdTextureMap BuildTxdTextureMap(unsigned short usTxdId) + { + TxdTextureMap result; + + RwTexDictionary* pTxd = CTxdStore_GetTxd(usTxdId); + if (!pTxd) + return result; + + // Get the TXD pool for parent index lookups. + // TXD parents are tracked via CTextureDictonarySAInterface::usParentIndex + // (not via RwObject::parent. which is unused for TXDs). + CTxdPoolSA* pTxdPoolSA = pGame ? static_cast(&pGame->GetPools()->GetTxdPool()) : nullptr; + + // Collect the TXD chain (child > parent > grandparent > ...) as pool IDs. + constexpr std::size_t kMaxChainDepth = 16; + unsigned short chain[kMaxChainDepth]; + std::size_t chainLen = 0; + + for (unsigned short id = usTxdId; chainLen < kMaxChainDepth;) + { + // Cyclic? stop if we revisit a TXD ID + bool bCycle = false; + for (std::size_t j = 0; j < chainLen; ++j) + { + if (chain[j] == id) + { + bCycle = true; + break; + } + } + if (bCycle) + break; + + chain[chainLen++] = id; + + // Walk to parent via pool-level usParentIndex + if (!pTxdPoolSA) + break; + + CTextureDictonarySAInterface* pSlot = pTxdPoolSA->GetTextureDictonarySlot(id); + if (!pSlot || pSlot->usParentIndex == static_cast(-1)) + break; + + id = pSlot->usParentIndex; + } + + // Iter from root (outermost parent) to child so child textures win on name conflict. + bool bChainComplete = true; + for (std::size_t i = chainLen; i > 0; --i) + { + RwTexDictionary* pChainTxd = CTxdStore_GetTxd(chain[i - 1]); + if (!pChainTxd) + { + bChainComplete = false; + continue; + } + + std::vector txdTextures; + CRenderWareSA::GetTxdTextures(txdTextures, pChainTxd); + + for (RwTexture* pTexture : txdTextures) + { + if (!pTexture) + continue; + + const char* name = pTexture->name; + if (strnlen(name, RW_TEXTURE_NAME_LENGTH) < RW_TEXTURE_NAME_LENGTH) + result[name] = pTexture; + } + } + + // A partial chain means some ancestors were not loaded, so the map + // is missing their textures. Return empty to prevent partial rebinds + // that leave unresolved textures white. + if (!bChainComplete) + result.clear(); + + return result; + } + + // Update each material's texture pointer to the matching texture from txdTextureMap. + // Falls back to internal name mapping if direct lookup fails. + void RebindAtomicMaterials(RpAtomic* pAtomic, const TxdTextureMap& txdTextureMap) + { + if (!pAtomic) + return; + + RpGeometry* pGeometry = pAtomic->geometry; + if (!pGeometry) + return; + + RpMaterials& materials = pGeometry->materials; + if (!materials.materials || materials.entries <= 0) + return; + + constexpr int MAX_REASONABLE_MATERIALS = 10000; + if (materials.entries > MAX_REASONABLE_MATERIALS) + return; + + for (int idx = 0; idx < materials.entries; ++idx) + { + RpMaterial* pMaterial = materials.materials[idx]; + if (!pMaterial) + continue; + + RwTexture* pOldTexture = pMaterial->texture; + if (!pOldTexture) + continue; + + const char* szTextureName = pOldTexture->name; + if (!szTextureName[0]) + continue; + + if (strnlen(szTextureName, RW_TEXTURE_NAME_LENGTH) >= RW_TEXTURE_NAME_LENGTH) + continue; + + RwTexture* pNewTexture = nullptr; + auto itFound = txdTextureMap.find(szTextureName); + if (itFound != txdTextureMap.end()) + pNewTexture = itFound->second; + + if (!pNewTexture) + { + const char* szInternalName = CRenderWareSA::GetInternalTextureName(szTextureName); + if (szInternalName && szInternalName != szTextureName) + { + if (strnlen(szInternalName, RW_TEXTURE_NAME_LENGTH) < RW_TEXTURE_NAME_LENGTH) + { + auto itInternal = txdTextureMap.find(szInternalName); + if (itInternal != txdTextureMap.end()) + pNewTexture = itInternal->second; + } + } + } + + if (pNewTexture && pNewTexture != pOldTexture) + RpMaterialSetTexture(pMaterial, pNewTexture); + } + } + + static RwObject* __cdecl RebindTexturesInFrameObjectCB(RwObject* pObject, void* pData) + { + if (pObject && pObject->type == RP_TYPE_ATOMIC) + { + auto* pAtomic = reinterpret_cast(pObject); + if (pAtomic->clump == nullptr && pAtomic->geometry) + { + auto* pTxdTextureMap = static_cast(pData); + RebindAtomicMaterials(pAtomic, *pTxdTextureMap); + } + } + + return pObject; + } + + static void RebindTexturesInFrameHierarchy(RwFrame* pFrame, const TxdTextureMap& mapTxdTextures, std::vector& vecVisitedFrames, int iDepth = 0) + { + if (!pFrame) + return; + + if (iDepth > 128) // cap recursion depth + return; + + for (RwFrame* pVisitedFrame : vecVisitedFrames) + { + if (pVisitedFrame == pFrame) + return; + } + vecVisitedFrames.push_back(pFrame); + + RwFrameForAllObjects(pFrame, RebindTexturesInFrameObjectCB, const_cast(&mapTxdTextures)); + + if (!pFrame->child) + return; + + RwFrame* pChild = pFrame->child; + int iChildCount = 0; + while (pChild) + { + RebindTexturesInFrameHierarchy(pChild, mapTxdTextures, vecVisitedFrames, iDepth + 1); + pChild = pChild->next; + if (++iChildCount > 1024) // guard against corrupt frame linked lists + return; + } + } +} + +void CRenderWareSA::RebindClumpTexturesToTxd(RpClump* pClump, unsigned short usTxdId) +{ + if (!pClump) + return; + + TxdTextureMap mapTxdTextures = BuildTxdTextureMap(usTxdId); + if (mapTxdTextures.empty()) + { + AddReportLog(9403, SString("RebindClumpTexturesToTxd: empty texture map for TXD %u", usTxdId)); + return; + } + + std::vector vecAtomics; + GetClumpAtomicList(pClump, vecAtomics); + + for (RpAtomic* pAtomic : vecAtomics) + RebindAtomicMaterials(pAtomic, mapTxdTextures); + + if (auto* pRootFrame = reinterpret_cast(pClump->object.parent)) + { + std::vector vecVisitedFrames; + RebindTexturesInFrameHierarchy(pRootFrame, mapTxdTextures, vecVisitedFrames); + } +} + +void CRenderWareSA::RebindAtomicTexturesToTxd(RpAtomic* pAtomic, unsigned short usTxdId) +{ + if (!pAtomic || !pAtomic->geometry) + return; + + TxdTextureMap txdTextureMap = BuildTxdTextureMap(usTxdId); + if (txdTextureMap.empty()) + { + AddReportLog(9403, SString("RebindAtomicTexturesToTxd: empty texture map for TXD %u", usTxdId)); + return; + } + + RebindAtomicMaterials(pAtomic, txdTextureMap); +} + // Replaces a vehicle/weapon/ped model bool CRenderWareSA::ReplaceModel(RpClump* pNew, unsigned short usModelID, DWORD dwSetClumpFunction) { @@ -368,10 +896,7 @@ bool CRenderWareSA::ReplaceModel(RpClump* pNew, unsigned short usModelID, DWORD RpClump* pOldClump = (RpClump*)pModelInfo->GetRwObject(); if (pOldClump != pNew && !DoContainTheSameGeometry(pNew, pOldClump, NULL)) { - if (pModelInfo->IsVehicle()) - { - pModelInfo->ResetSupportedUpgrades(); - } + const bool shouldResetUpgrades = (dwSetClumpFunction == FUNC_LoadVehicleModel); // Make new clump container for the model geometry // Clone twice as the geometry render order seems to be reversed each time it is cloned. @@ -384,7 +909,7 @@ bool CRenderWareSA::ReplaceModel(RpClump* pNew, unsigned short usModelID, DWORD if (dwSetClumpFunction == FUNC_LoadVehicleModel) { auto pVehicleModelInfoInterface = (CVehicleModelInfoSAInterface*)pModelInfo->GetInterface(); - if (pVehicleModelInfoInterface->pVisualInfo) + if (pVehicleModelInfoInterface && pVehicleModelInfoInterface->pVisualInfo) { auto pVisualInfo = pVehicleModelInfoInterface->pVisualInfo; CVehicleModelInfo_CVehicleStructure_Destructor(pVisualInfo); @@ -394,7 +919,60 @@ bool CRenderWareSA::ReplaceModel(RpClump* pNew, unsigned short usModelID, DWORD } CBaseModelInfoSAInterface* pModelInfoInterface = pModelInfo->GetInterface(); + if (!pModelInfoInterface) + { + RpClumpDestroy(pNewClone); + return false; + } CBaseModelInfo_SetClump(pModelInfoInterface, pNewClone); + + CBaseModelInfoSAInterface* pInterfaceAfterSet = pModelInfoInterface; + // Re-fetch interface pointer after SetClump (may relocate/change) + pModelInfoInterface = pModelInfo->GetInterface(); + + // Not happy + if (!pModelInfoInterface) + { + CBaseModelInfoSAInterface* fallback = nullptr; + auto* arrayEntry = ((CBaseModelInfoSAInterface**)ARRAY_ModelInfo)[usModelID]; + if (arrayEntry && SharedUtil::IsReadablePointer(arrayEntry, sizeof(*arrayEntry))) { + fallback = arrayEntry; + } else if (pInterfaceAfterSet && SharedUtil::IsReadablePointer(pInterfaceAfterSet, sizeof(*pInterfaceAfterSet))) { + fallback = pInterfaceAfterSet; +} + bool restored = false; + const bool oldClumpReadable = pOldClump && SharedUtil::IsReadablePointer(pOldClump, sizeof(*pOldClump)); + if (fallback && oldClumpReadable && SharedUtil::IsReadablePointer(fallback->VFTBL, sizeof(*fallback->VFTBL))) + { + fallback->pRwObject = &pOldClump->object; + CBaseModelInfo_SetClump(fallback, pOldClump); + restored = true; + } + AddReportLog(8627, SString("ReplaceModel: lost interface after SetClump, model:%d restored:%d", usModelID, restored ? 1 : 0)); + RpClumpDestroy(pNewClone); + return false; + } + + if (shouldResetUpgrades) + pModelInfo->ResetSupportedUpgrades(); + + // Fix for custom DFF without embedded collision: + // SetClump clears pColModel when DFF has no collision data, but vehicles need collision from .col pool. + // Solution: Remove + Request + Load to restore pool-managed collision from data/vehicles.col + if (dwSetClumpFunction == FUNC_LoadVehicleModel && !pModelInfoInterface->pColModel) + { + pGame->GetStreaming()->RemoveModel(usModelID); + pGame->GetStreaming()->RequestModel(usModelID, 0x16); + pGame->GetStreaming()->LoadAllRequestedModels(false, "CRenderWareSA::ReplaceVehicleModel"); + // Re-fetch interface pointer after model reload + pModelInfoInterface = pModelInfo->GetInterface(); + if (!pModelInfoInterface) + { + RpClumpDestroy(pOldClump); + return false; + } + } + RpClumpDestroy(pOldClump); } } @@ -408,6 +986,12 @@ bool CRenderWareSA::ReplaceVehicleModel(RpClump* pNew, unsigned short usModelID) return ReplaceModel(pNew, usModelID, FUNC_LoadVehicleModel); } +// Replaces a generic CClumpModelInfo model (multi-part objects like cranes, signs, etc.) +bool CRenderWareSA::ReplaceClumpModel(RpClump* pNew, unsigned short usModelID) +{ + return ReplaceModel(pNew, usModelID, FUNC_LoadClumpModel); +} + // Replaces a weapon model bool CRenderWareSA::ReplaceWeaponModel(RpClump* pNew, unsigned short usModelID) { @@ -428,45 +1012,123 @@ bool CRenderWareSA::ReplacePedModel(RpClump* pNew, unsigned short usModelID) return ReplaceModel(pNew, usModelID, FUNC_LoadPedModel); } -// Reads and parses a COL3 file +// Reads and parses a COL file (versions 1-4: COLL, COL2, COL3, COL4) CColModel* CRenderWareSA::ReadCOL(const SString& buffer) { - if (buffer.size() < sizeof(ColModelFileHeader) + 16) - return NULL; + // Validate minimum buffer size + if (buffer.size() < sizeof(ColModelFileHeader) + 16) [[unlikely]] + return nullptr; + + const auto& header = *reinterpret_cast(buffer.data()); + + // Validate version field contains valid COL magic number + // Version is 4-char fixed string (not null-terminated): "COLL", "COL2", "COL3", "COL4" + constexpr std::array, 4> validVersions = {{{'C', 'O', 'L', 'L'}, {'C', 'O', 'L', '2'}, {'C', 'O', 'L', '3'}, {'C', 'O', 'L', '4'}}}; - const ColModelFileHeader& header = *(ColModelFileHeader*)buffer.data(); + const bool isValidVersion = std::any_of(validVersions.begin(), validVersions.end(), + [&header](const auto& valid) { return std::equal(valid.begin(), valid.end(), header.version); }); - // Load the col model - if (header.version[0] == 'C' && header.version[1] == 'O' && header.version[2] == 'L') + if (!isValidVersion) [[unlikely]] { - unsigned char* pModelData = (unsigned char*)buffer.data() + sizeof(ColModelFileHeader); + // Explicitly limit to 4 characters + AddReportLog(8622, SString("ReadCOL: Invalid version '%c%c%c%c' - expected COLL, COL2, COL3, or COL4", header.version[0], header.version[1], + header.version[2], header.version[3])); + return nullptr; + } - // Create a new CColModel - CColModelSA* pColModel = new CColModelSA(); + // Ensure name field is null-terminated to prevent buffer overrun + const auto* nameEnd = static_cast(std::memchr(header.name, '\0', sizeof(header.name))); + if (!nameEnd) [[unlikely]] + { + AddReportLog(8623, "ReadCOL: Name field not null-terminated, may be truncated"); + return nullptr; + } - if (header.version[3] == 'L') - { - LoadCollisionModel(pModelData, pColModel->GetInterface(), NULL); - } - else if (header.version[3] == '2') - { - LoadCollisionModelVer2(pModelData, header.size - 0x18, pColModel->GetInterface(), NULL); - } - else if (header.version[3] == '3') + // Buffer is not modified by us, but GTA's functions expect non-const + auto* pModelData = const_cast(reinterpret_cast(buffer.data())) + sizeof(ColModelFileHeader); + + // Create a new CColModel + CColModelSA* pColModel = nullptr; + try + { + pColModel = new CColModelSA(); + } + catch (const std::exception& e) + { + AddReportLog(8625, SString("ReadCOL: Failed to construct col model for '%s': %s", header.name, e.what())); + return nullptr; + } + + if (!pColModel->IsValid() || !pColModel->GetInterface()) + { + AddReportLog(8626, SString("ReadCOL: Constructed invalid col model for '%s'", header.name)); + delete pColModel; + return nullptr; + } + + // Load appropriate collision version + switch (header.version[3]) + { + case 'L': + LoadCollisionModel(pModelData, pColModel->GetInterface(), nullptr); + break; + case '2': + LoadCollisionModelVer2(pModelData, header.size - 0x18, pColModel->GetInterface(), nullptr); + break; + case '3': + LoadCollisionModelVer3(pModelData, header.size - 0x18, pColModel->GetInterface(), nullptr); + break; + case '4': + // COL4 format has same structure as COL3 with one extra uint32 field in header + // Must use Ver4 loader for correct offset calculations + LoadCollisionModelVer4(pModelData, header.size - 0x18, pColModel->GetInterface(), nullptr); + break; + default: + // Should never reach here due to validation above + delete pColModel; + return nullptr; + } + + // Ensure shadow data consistency to prevent crash in GTA's stencil shadow rendering + // GTA accesses shadow vertices without NULL checks, causing crash if pointer is NULL but count is non-zero + // Also cap counts to catch corrupt data before CCollisionData::Copy amplifies it into an out-of-bounds read + auto* pInterface = pColModel->GetInterface(); + if (pInterface && pInterface->m_data) + { + auto* pData = pInterface->m_data; + + constexpr std::uint32_t MAX_SHADOW_VERTICES = 10000; + constexpr std::uint32_t MAX_SHADOW_TRIANGLES = 5000; + + // shadow counts indicate data exists but pointers are NULL, or counts are beyond any legitimate model + const bool shadowVertsCorrupt = + (pData->m_numShadowVertices > 0 && pData->m_shadowVertices == nullptr) || pData->m_numShadowVertices > MAX_SHADOW_VERTICES; + const bool shadowTrisCorrupt = + (pData->m_numShadowTriangles > 0 && pData->m_shadowTriangles == nullptr) || pData->m_numShadowTriangles > MAX_SHADOW_TRIANGLES; + + if (shadowVertsCorrupt || shadowTrisCorrupt) { - LoadCollisionModelVer3(pModelData, header.size - 0x18, pColModel->GetInterface(), NULL); + // Clear all shadow state to prevent GTA from attempting shadow rendering + pData->m_numShadowVertices = 0; + pData->m_numShadowTriangles = 0; + pData->m_shadowVertices = nullptr; + pData->m_shadowTriangles = nullptr; + pData->m_hasShadowInfo = 0; + pData->m_hasShadow = 0; + + AddReportLog(8624, SString("ReadCOL: Invalid shadow data in '%s' - shadow rendering disabled", header.name)); } - - // Return the collision model - return pColModel; } - return NULL; + return pColModel; } // Loads all atomics from a clump into a container struct and returns the number of atomics it loaded unsigned int CRenderWareSA::LoadAtomics(RpClump* pClump, RpAtomicContainer* pAtomics) { + if (!pClump || !pAtomics) [[unlikely]] + return 0; + // iterate through all atomics in the clump SLoadAtomics data = {0}; data.pReplacements = pAtomics; @@ -490,14 +1152,16 @@ bool AtomicsReplacer(RpAtomic* pAtomic, void* data) relatedModelInfo.bDeleteOldRwObject = true; CFileLoader_SetRelatedModelInfoCB(pAtomic, &relatedModelInfo); - // The above function adds a reference to the model's TXD by either - // calling CAtomicModelInfo::SetAtomic or CDamagableModelInfo::SetDamagedAtomic. Remove it again. - CTxdStore_RemoveRef(pData->usTxdID); + // The above function adds a reference to the model's TXD. Remove it again. + CRenderWareSA::DebugTxdRemoveRef(pData->usTxdID); return true; } bool CRenderWareSA::ReplaceAllAtomicsInModel(RpClump* pNew, unsigned short usModelID) { + if (!pNew) [[unlikely]] + return false; + CModelInfo* pModelInfo = pGame->GetModelInfo(usModelID); if (pModelInfo) @@ -508,10 +1172,21 @@ bool CRenderWareSA::ReplaceAllAtomicsInModel(RpClump* pNew, unsigned short usMod { // Clone the clump that's to be replaced (FUNC_AtomicsReplacer removes the atomics from the source clump) RpClump* pCopy = RpClumpClone(pNew); + if (!pCopy) [[unlikely]] + { + AddReportLog(8628, SString("ReplaceAllAtomicsInModel: RpClumpClone failed for model %d", usModelID)); + return false; + } // Replace the atomics - SAtomicsReplacer data; - data.usTxdID = ((CBaseModelInfoSAInterface**)ARRAY_ModelInfo)[usModelID]->usTextureDictionary; + SAtomicsReplacer data; + CBaseModelInfoSAInterface* pModelInfoInterface = pModelInfo->GetInterface(); + if (!pModelInfoInterface) + { + RpClumpDestroy(pCopy); + return false; + } + data.usTxdID = pModelInfoInterface->usTextureDictionary; data.pClump = pCopy; MemPutFast((DWORD*)DWORD_AtomicsReplacerModelID, usModelID); @@ -604,7 +1279,7 @@ void CRenderWareSA::ReplaceCollisions(CColModel* pCol, unsigned short usModelID) // TODO: It seems that on entering the game, when this function is executed, the modelinfo array for this // model is still zero, leading to a crash! - pModelInfoSA->IsLoaded(); + [[maybe_unused]] const bool modelLoaded = pModelInfoSA->IsLoaded(); } // Destroys a DFF instance @@ -614,6 +1289,111 @@ void CRenderWareSA::DestroyDFF(RpClump* pClump) RpClumpDestroy(pClump); } +// Parses TXD buffer data and injects the resulting RwTexDictionary directly +// into an allocated pool slot, bypassing the streaming system. +// Used for overflow TXD slots that have no corresponding streaming entry. +// +// Registers textures via StreamingAddedTexture (keyed by pool slot ID) so +// shader matching works. Cleanup is handled by RemoveTextureDictonarySlot +// which triggers StreamingRemovedTxd via the CTxdStore hook. +bool CRenderWareSA::LoadTxdSlotFromBuffer(std::uint32_t uiSlotId, const std::string& buffer) +{ + CTxdPoolSA* pTxdPool = pGame ? static_cast(&pGame->GetPools()->GetTxdPool()) : nullptr; + if (!pTxdPool) + return false; + + const int poolSize = pTxdPool->GetPoolSize(); + if (poolSize <= 0 || uiSlotId >= static_cast(poolSize)) + return false; + + // True means unallocated (slot not reserved via AllocateTextureDictonarySlot) + if (pTxdPool->IsFreeTextureDictonarySlot(uiSlotId)) + return false; + + // Only overflow slots (>= MAX_STREAMING_TXD_SLOT) are valid here. + // Standard slots [0, 5000) use SA's streaming system, and [5000, 6316) + // overlap with non-TXD streaming resources (COL/IPL/DAT/IFP). + if (uiSlotId < static_cast(CTxdPoolSA::MAX_STREAMING_TXD_SLOT)) + return false; + + CTextureDictonarySAInterface* pSlot = pTxdPool->GetTextureDictonarySlot(uiSlotId); + if (!pSlot) + return false; + + // Pre-validate the buffer before handing it to RenderWare + + if (buffer.size() < RW_CHUNK_HEADER_SIZE) + return false; + + std::uint32_t chunkType = 0; + std::uint32_t chunkSize = 0; + std::memcpy(&chunkType, buffer.data(), sizeof(chunkType)); + std::memcpy(&chunkSize, buffer.data() + 4, sizeof(chunkSize)); + + if (chunkType != RW_CHUNK_TYPE_TXD || chunkSize > MAX_SANE_CHUNK_SIZE) + return false; + + if (buffer.size() < RW_CHUNK_HEADER_SIZE + chunkSize) + return false; + + // Parse the TXD from buffer directly, bypassing ReadTXD/ScriptAddedTxd + RwBuffer rwBuffer{}; + // const_cast safe: STREAM_MODE_READ only reads from the buffer + rwBuffer.ptr = const_cast(buffer.data()); + rwBuffer.size = static_cast(RW_CHUNK_HEADER_SIZE + chunkSize); + + RwStream* pStream = RwStreamOpen(STREAM_TYPE_BUFFER, STREAM_MODE_READ, &rwBuffer); + if (!pStream) + return false; + + if (!RwStreamFindChunk(pStream, RW_CHUNK_TYPE_TXD, nullptr, nullptr)) + { + RwStreamClose(pStream, nullptr); + return false; + } + + RwTexDictionary* pTxd = RwTexDictionaryGtaStreamRead(pStream); + RwStreamClose(pStream, nullptr); + + if (!pTxd) + return false; + + if (pSlot->rwTexDictonary && pSlot->rwTexDictonary != pTxd) + { + // Refuse replacement if the old TXD still has active references + if (static_cast(pSlot->usUsagesCount) > 0) + { + RwTexDictionaryDestroy(pTxd); + return false; + } + + // Remove old shader TexInfo entries before destroying the TXD + StreamingRemovedTxd(static_cast(uiSlotId)); + + RwTexDictionaryDestroy(pSlot->rwTexDictonary); + } + + pSlot->rwTexDictonary = pTxd; + + // Register each texture for shader matching, keyed by pool slot ID + std::vector textureList; + GetTxdTextures(textureList, pTxd); + for (RwTexture* pTexture : textureList) + { + if (!pTexture || !SharedUtil::IsReadablePointer(pTexture, sizeof(RwTexture))) + continue; + + CD3DDUMMY* pD3DData = (pTexture->raster && SharedUtil::IsReadablePointer(pTexture->raster, sizeof(RwRaster))) + ? reinterpret_cast(pTexture->raster->renderResource) + : nullptr; + + if (pD3DData && pTexture->name[0] && !IsTexInfoRegistered(pD3DData)) + StreamingAddedTexture(static_cast(uiSlotId), pTexture->name, pD3DData); + } + + return true; +} + // Destroys a TXD instance void CRenderWareSA::DestroyTXD(RwTexDictionary* pTXD) { @@ -631,14 +1411,29 @@ void CRenderWareSA::DestroyTexture(RwTexture* pTex) } } -void CRenderWareSA::RwTexDictionaryRemoveTexture(RwTexDictionary* pTXD, RwTexture* pTex) +bool CRenderWareSA::RwTexDictionaryRemoveTexture(RwTexDictionary* pTXD, RwTexture* pTex) { + if (!pTex || !pTXD || !SharedUtil::IsReadablePointer(pTex, sizeof(RwTexture)) || !SharedUtil::IsReadablePointer(pTXD, sizeof(RwTexDictionary))) + return false; + if (pTex->txd != pTXD) - return; + return false; - pTex->TXDList.next->prev = pTex->TXDList.prev; - pTex->TXDList.prev->next = pTex->TXDList.next; - pTex->txd = NULL; + RwListEntry* pNext = pTex->TXDList.next; + RwListEntry* pPrev = pTex->TXDList.prev; + + if (!pNext || !pPrev || !SharedUtil::IsReadablePointer(pNext, sizeof(RwListEntry)) || !SharedUtil::IsReadablePointer(pPrev, sizeof(RwListEntry))) + return false; + + if (pNext->prev != &pTex->TXDList || pPrev->next != &pTex->TXDList) + return false; + + pPrev->next = pNext; + pNext->prev = pPrev; + pTex->TXDList.next = &pTex->TXDList; + pTex->TXDList.prev = &pTex->TXDList; + pTex->txd = nullptr; + return true; } short CRenderWareSA::CTxdStore_GetTxdRefcount(unsigned short usTxdID) @@ -648,6 +1443,9 @@ short CRenderWareSA::CTxdStore_GetTxdRefcount(unsigned short usTxdID) bool CRenderWareSA::RwTexDictionaryContainsTexture(RwTexDictionary* pTXD, RwTexture* pTex) { + if (!pTex || !pTXD || !SharedUtil::IsReadablePointer(pTex, sizeof(RwTexture)) || !SharedUtil::IsReadablePointer(pTXD, sizeof(RwTexDictionary))) + return false; + return pTex->txd == pTXD; } @@ -662,7 +1460,7 @@ bool CRenderWareSA::RwTexDictionaryContainsTexture(RwTexDictionary* pTXD, RwText // Player model adds (seemingly) unnecessary refs // (Will crash if anything is actually using the txd) // -// No idea what will happen if there is a custom txd replacement +// Handles custom txd replacements // //////////////////////////////////////////////////////////////// void CRenderWareSA::TxdForceUnload(ushort usTxdId, bool bDestroyTextures) @@ -671,31 +1469,155 @@ void CRenderWareSA::TxdForceUnload(ushort usTxdId, bool bDestroyTextures) if (!pTxd) return; - // We can abandon the textures instead of destroy. It might be safer, but will cause a memory leak + constexpr int kMaxTextureUnrefs = 10000; + constexpr int kMaxTxdUnrefs = 1000; + + // Optionally destroy textures first. Skipping is safer but leaks memory. if (bDestroyTextures) { - // Unref the textures + // Remove extra refs from each texture, then destroy when refs == 1 std::vector textureList; - pGame->GetRenderWareSA()->GetTxdTextures(textureList, pTxd); - for (std::vector::iterator iter = textureList.begin(); iter != textureList.end(); iter++) + GetTxdTextures(textureList, pTxd); + for (RwTexture* pTexture : textureList) { - RwTexture* pTexture = *iter; - while (pTexture->refs > 1) + if (!pTexture) + continue; + + if (pTexture->refs < 1) + continue; + + int textureUnrefCount = 0; + while (pTexture->refs > 1 && textureUnrefCount < kMaxTextureUnrefs) + { + RwTextureDestroy(pTexture); + ++textureUnrefCount; + } + + int remainingRefs = pTexture->refs; + if (textureUnrefCount >= kMaxTextureUnrefs && remainingRefs > 1) + { + AddReportLog(8625, SString("TxdForceUnload: Texture unref limit hit for TXD %d (refs remaining: %d)", usTxdId, remainingRefs)); + continue; + } + + if (remainingRefs == 1) RwTextureDestroy(pTexture); - RwTextureDestroy(pTexture); } } - // Need to have at least one ref for RemoveRef to work correctly + // Ensure at least one ref exists so RemoveRef can trigger cleanup if (CTxdStore_GetNumRefs(usTxdId) == 0) + CRenderWareSA::DebugTxdAddRef(usTxdId); + + int txdUnrefCount = 0; + while (CTxdStore_GetNumRefs(usTxdId) > 0 && txdUnrefCount < kMaxTxdUnrefs) + { + CRenderWareSA::DebugTxdRemoveRef(usTxdId); + ++txdUnrefCount; + } + + if (txdUnrefCount >= kMaxTxdUnrefs) + { + int remainingTxdRefs = CTxdStore_GetNumRefs(usTxdId); + if (remainingTxdRefs > 0) + { + AddReportLog(8626, SString("TxdForceUnload: TXD unref limit hit for TXD %d (refs remaining: %d)", usTxdId, remainingTxdRefs)); + } + } +} + +namespace +{ + struct TextureMapping + { + const char* externalPrefix; // e.g., "remap" + const char* internalPrefix; // e.g., "#emap" + size_t externalLength; // strlen(externalPrefix) + size_t internalLength; // strlen(internalPrefix) + }; + + // Static mappings for texture name transformations + // GTA:SA renames certain texture prefixes internally in CVehicleModelInfo::FindTextureCB + // This specifically handles vehicle paintjob textures. + // Note: This may false positive on non-vehicle textures with matching prefixes, + // but the fallback lookup pattern (try original first, then transformed) mitigates this. + constexpr std::array kTextureMappings = {{{"remap", "#emap", 5, 5}, {"white", "@hite", 5, 5}}}; + + // Thread-local buffers for transformed texture names (avoids allocation) + // Note: These are overwritten on each call - do not store the returned pointer + // for use after another call to these functions. + thread_local char s_szInternalNameBuffer[RW_TEXTURE_NAME_LENGTH + 1]; + thread_local char s_szExternalNameBuffer[RW_TEXTURE_NAME_LENGTH + 1]; +} + +//////////////////////////////////////////////////////////////// +// +// CRenderWareSA::GetInternalTextureName +// +// Maps external texture names to internal GTA:SA names. +// Handles prefix-based matches (e.g., "remap_body" -> "#emap_body"). +// Returns original name if no mapping exists. +// +// Note: Returns pointer to thread-local static buffer when transformation +// occurs. The returned string is only valid until the next call to this function +// on the same thread. Copy the result if you need to preserve it. +// +//////////////////////////////////////////////////////////////// +const char* CRenderWareSA::GetInternalTextureName(const char* szExternalName) +{ + if (!szExternalName || !szExternalName[0]) + return szExternalName; + + for (const auto& mapping : kTextureMappings) { - CTxdStore_AddRef(usTxdId); + // Check if the external name starts with this prefix (case-insensitive) + if (_strnicmp(szExternalName, mapping.externalPrefix, mapping.externalLength) == 0) + { + // Build internal name: internal prefix + rest of original name + const char* szSuffix = szExternalName + mapping.externalLength; + + // Build the transformed name (only snprintf is safe for it) + snprintf(s_szInternalNameBuffer, sizeof(s_szInternalNameBuffer), "%s%s", mapping.internalPrefix, szSuffix); + + return s_szInternalNameBuffer; + } } + return szExternalName; +} + +//////////////////////////////////////////////////////////////// +// +// CRenderWareSA::GetExternalTextureName +// +// Maps internal GTA:SA names to external texture names. +// Handles prefix-based matches (e.g., "#emap_body" -> "remap_body"). +// Returns original name if no mapping exists. +// +// Note: Returns pointer to thread-local static buffer when transformation +// occurs. The returned string is only valid until the next call to this function +// on the same thread. Copy the result if you need to preserve it. +// +//////////////////////////////////////////////////////////////// +const char* CRenderWareSA::GetExternalTextureName(const char* szInternalName) +{ + if (!szInternalName || !szInternalName[0]) + return szInternalName; - while (CTxdStore_GetNumRefs(usTxdId) > 0) + for (const auto& mapping : kTextureMappings) { - CTxdStore_RemoveRef(usTxdId); + // Check if the internal name starts with this prefix (case-insensitive) + if (_strnicmp(szInternalName, mapping.internalPrefix, mapping.internalLength) == 0) + { + // Build external name: external prefix + rest of original name + const char* szSuffix = szInternalName + mapping.internalLength; + + // Build the transformed name (only snprintf is safe for it) + snprintf(s_szExternalNameBuffer, sizeof(s_szExternalNameBuffer), "%s%s", mapping.externalPrefix, szSuffix); + + return s_szExternalNameBuffer; + } } + return szInternalName; } //////////////////////////////////////////////////////////////// @@ -758,14 +1680,26 @@ void CRenderWareSA::GetModelTextureNames(std::vector& outNameList, usho bLoadedModel = true; pGame->GetModelInfo(usModelId)->Request(BLOCKING, "CRenderWareSA::GetModelTextureNames"); pTXD = CTxdStore_GetTxd(usTxdId); + + // Revalidate TXD pointer after load - it may still be NULL or have been GC'd + if (!pTXD) + { + if (bLoadedModel) + ((void(__cdecl*)(unsigned short))FUNC_RemoveModel)(usModelId); + return; + } } std::vector textureList; GetTxdTextures(textureList, pTXD); - for (std::vector::iterator iter = textureList.begin(); iter != textureList.end(); iter++) + for (RwTexture* pTexture : textureList) { - outNameList.push_back((*iter)->name); + // Fix for #emap corruption: + // Some textures (like 'remap') are internally renamed to start with '#' (e.g. '#emap') by SA. + // This causes issues when scripts try to access them by their original name. + // We detect this case and return the expected name 'remap' instead. + outNameList.push_back(GetExternalTextureName(pTexture->name)); } if (bLoadedModel) @@ -799,21 +1733,35 @@ bool CRenderWareSA::GetModelTextures(std::vectorGetModelInfo(usModelId)->Request(BLOCKING, "CRenderWareSA::GetModelTextures"); pTXD = CTxdStore_GetTxd(usTxdId); + + // Revalidate TXD pointer after load - it may still be NULL or have been GC'd + if (!pTXD) + { + if (bLoadedModel) + ((void(__cdecl*)(unsigned short))FUNC_RemoveModel)(usModelId); + return false; + } } std::vector rwTextureList; GetTxdTextures(rwTextureList, pTXD); - // If any texture names specified in vTextureNames, we should only return these - bool bExcludeTextures = false; + // If texture list is empty after enumeration + if (rwTextureList.empty()) + { + if (bLoadedModel) + ((void(__cdecl*)(unsigned short))FUNC_RemoveModel)(usModelId); + return false; + } - if (vTextureNames.size() > 0) - bExcludeTextures = true; + // If any texture names specified in vTextureNames, we should only return these + const bool bExcludeTextures = !vTextureNames.empty(); for (RwTexture* pTexture : rwTextureList) { - SString strTextureName = pTexture->name; - bool bValidTexture = false; + SString strTextureName = GetExternalTextureName(pTexture->name); + + bool bValidTexture = false; if (bExcludeTextures) { @@ -830,6 +1778,9 @@ bool CRenderWareSA::GetModelTextures(std::vectorraster) + continue; + RwD3D9Raster* pD3DRaster = (RwD3D9Raster*)(&pTexture->raster->renderResource); CPixels texture; g_pCore->GetGraphics()->GetPixelsManager()->GetTexturePixels(pD3DRaster->texture, texture); @@ -861,6 +1812,9 @@ void CRenderWareSA::GetTxdTextures(std::vector& outTextureList, usho if (!pTXD) return; + if (!SharedUtil::IsReadablePointer(pTXD, sizeof(*pTXD))) + return; + GetTxdTextures(outTextureList, pTXD); } @@ -873,23 +1827,126 @@ void CRenderWareSA::GetTxdTextures(std::vector& outTextureList, usho //////////////////////////////////////////////////////////////// void CRenderWareSA::GetTxdTextures(std::vector& outTextureList, RwTexDictionary* pTXD) { - if (pTXD) + if (!pTXD) + return; + + // Validate TXD structure is readable (includes textures member) + if (!SharedUtil::IsReadablePointer(pTXD, sizeof(*pTXD))) + return; + + constexpr std::size_t kMaxReasonableTextures = 8192; + if (outTextureList.size() >= kMaxReasonableTextures) + { + LogEvent(852, "Texture enumeration aborted", "CRenderWareSA::GetTxdTextures", + SString("Texture list already contains %zu textures (limit: %zu)", outTextureList.size(), kMaxReasonableTextures), 5422); + return; + } + + if (outTextureList.empty()) + outTextureList.reserve(16); + + // Manual iteration avoids freezes on bad TXD lists. + RwListEntry* const pRoot = &pTXD->textures.root; + RwListEntry* pNode = pRoot->next; + + if (pNode == nullptr) + return; + + if (pNode == pRoot) + return; // Empty TXD + + std::size_t iterations = 0; + while (pNode != pRoot) { - RwTexDictionaryForAllTextures(pTXD, StaticGetTextureCB, &outTextureList); + if (++iterations > kMaxReasonableTextures) + { + LogEvent(852, "Texture enumeration aborted", "CRenderWareSA::GetTxdTextures", + SString("Texture list enumeration exceeded %zu iterations (possible TXD corruption/cycle)", kMaxReasonableTextures), 5422); + return; + } + + if (!SharedUtil::IsReadablePointer(pNode, sizeof(RwListEntry))) + return; + + RwTexture* pTexture = reinterpret_cast(reinterpret_cast(pNode) - offsetof(RwTexture, TXDList)); + if (!SharedUtil::IsReadablePointer(pTexture, sizeof(RwTexture))) + return; + + outTextureList.push_back(pTexture); + if (outTextureList.size() >= kMaxReasonableTextures) + return; + + if (!SharedUtil::IsReadablePointer(pNode->next, sizeof(RwListEntry))) + return; + + pNode = pNode->next; } } //////////////////////////////////////////////////////////////// // -// CRenderWareSA::StaticGetTextureCB +// CRenderWareSA::GetTxdTextures (unordered_set overload) // -// Callback used in GetTxdTextures +// Get textures from a TXD into unordered_set for O(1) contains // //////////////////////////////////////////////////////////////// -bool CRenderWareSA::StaticGetTextureCB(RwTexture* texture, std::vector* pTextureList) +void CRenderWareSA::GetTxdTextures(std::unordered_set& outTextureSet, RwTexDictionary* pTXD) { - pTextureList->push_back(texture); - return true; + if (!pTXD) + return; + + if (!SharedUtil::IsReadablePointer(pTXD, sizeof(*pTXD))) + return; + + constexpr std::size_t kMaxReasonableTextures = 8192; + if (outTextureSet.size() >= kMaxReasonableTextures) + { + LogEvent(852, "Texture enumeration aborted", "CRenderWareSA::GetTxdTextures", + SString("Texture set already contains %zu textures (limit: %zu)", outTextureSet.size(), kMaxReasonableTextures), 5422); + return; + } + + if (outTextureSet.empty()) + outTextureSet.reserve(16); + + // Manual iteration avoids freezes on bad TXD lists. + RwListEntry* const pRoot = &pTXD->textures.root; + RwListEntry* pNode = pRoot->next; + + if (pNode == nullptr) + return; + + if (pNode == pRoot) + return; // Empty TXD + + // The set size doesnt grow on duplicates; cap iterations separately. + std::size_t iterations = 0; + while (pNode != pRoot) + { + if (++iterations > kMaxReasonableTextures) + { + LogEvent(852, "Texture enumeration aborted", "CRenderWareSA::GetTxdTextures", + SString("Texture set enumeration exceeded %zu iterations (possible TXD corruption/cycle)", kMaxReasonableTextures), 5422); + return; + } + + if (!SharedUtil::IsReadablePointer(pNode, sizeof(RwListEntry))) + return; + + RwTexture* pTexture = reinterpret_cast(reinterpret_cast(pNode) - offsetof(RwTexture, TXDList)); + if (!SharedUtil::IsReadablePointer(pTexture, sizeof(RwTexture))) + return; + + if (outTextureSet.size() >= kMaxReasonableTextures) + return; + + outTextureSet.insert(pTexture); + + if (!SharedUtil::IsReadablePointer(pNode->next, sizeof(RwListEntry))) + return; + + pNode = pNode->next; + } } //////////////////////////////////////////////////////////////// @@ -909,18 +1966,8 @@ const char* CRenderWareSA::GetTextureName(CD3DDUMMY* pD3DData) return ""; } -// -// CFastHashMap functions -// -CD3DDUMMY* GetEmptyMapKey(CD3DDUMMY**) -{ - return FAKE_D3DTEXTURE_EMPTY_KEY; -} - -CD3DDUMMY* GetDeletedMapKey(CD3DDUMMY**) -{ - return FAKE_D3DTEXTURE_DELETED_KEY; -} +// Note: GetEmptyMapKey/GetDeletedMapKey for CD3DDUMMY* are now declared in CRenderWareSA.ShaderSupport.h +// to ensure they are visible before CFastHashMap template instantiatin RwFrame* CRenderWareSA::GetFrameFromName(RpClump* pRoot, SString strName) { diff --git a/Client/game_sa/CRenderWareSA.h b/Client/game_sa/CRenderWareSA.h index 1fc217ad967..093585a1a8e 100644 --- a/Client/game_sa/CRenderWareSA.h +++ b/Client/game_sa/CRenderWareSA.h @@ -14,9 +14,10 @@ #include #include "CModelInfoSA.h" #include "CRenderWareSA.ShaderSupport.h" +#include class CMatchChannelManager; -class CModelTexturesInfo; +struct CModelTexturesInfo; struct RpAtomic; struct SShaderReplacementStats; struct STexInfo; @@ -29,15 +30,21 @@ class CRenderWareSA : public CRenderWare CRenderWareSA(); ~CRenderWareSA(); void Initialize(); - bool ModelInfoTXDLoadTextures(SReplacementTextures* pReplacementTextures, const SString& strFilename, const SString& buffer, bool bFilteringEnabled); - bool ModelInfoTXDAddTextures(SReplacementTextures* pReplacementTextures, ushort usModelId); + bool ModelInfoTXDLoadTextures(SReplacementTextures* pReplacementTextures, const SString& strFilename, const SString& buffer, bool bFilteringEnabled, + SString* pOutError = nullptr) override; + bool ModelInfoTXDAddTextures(SReplacementTextures* pReplacementTextures, unsigned short usModelId); void ModelInfoTXDRemoveTextures(SReplacementTextures* pReplacementTextures); - void ClothesAddReplacement(char* pFileData, size_t fileSize, ushort usFileId); + void ModelInfoTXDDeferCleanup(SReplacementTextures* pReplacementTextures) override; + void CleanupIsolatedTxdForModel(unsigned short usModelId, bool bSkipStreamingLoads = false) override; + void CleanupReplacementsInTxdSlot(unsigned short usTxdSlotId) override; + void StaticResetModelTextureReplacing(); + void StaticResetShaderSupport(); + void ClothesAddReplacement(char* pFileData, size_t fileSize, unsigned short usFileId); void ClothesRemoveReplacement(char* pFileData); bool HasClothesReplacementChanged(); bool ClothesAddFile(const char* fileData, std::size_t fileSize, const char* fileName) override; bool ClothesRemoveFile(char* fileData) override; - bool HasClothesFile(const char* fileName) const noexcept override; + bool HasClothesFile(const char* fileName) const override; // Reads and parses a TXD file specified by a path (szTXD) RwTexDictionary* ReadTXD(const SString& strFilename, const SString& buffer); @@ -54,7 +61,10 @@ class CRenderWareSA : public CRenderWare // Destroys a texture void DestroyTexture(RwTexture* pTex); - // Reads and parses a COL3 file with an optional collision key name + // Parses TXD buffer data and injects it directly into an allocated pool slot + bool LoadTxdSlotFromBuffer(std::uint32_t uiSlotId, const std::string& buffer) override; + + // Reads and parses a COL file (versions 1-4: COLL, COL2, COL3, COL4) CColModel* ReadCOL(const SString& buffer); // Replaces a CColModel for a specific object identified by the object id (usModelID) @@ -81,7 +91,10 @@ class CRenderWareSA : public CRenderWare // Replaces a CClumpModelInfo (or CVehicleModelInfo, since its just for vehicles) clump with a new clump bool ReplaceVehicleModel(RpClump* pNew, unsigned short usModelID) override; - // Replaces a CClumpModelInfo clump with a new clump + // Replaces a generic CClumpModelInfo clump with a new clump + bool ReplaceClumpModel(RpClump* pNew, unsigned short usModelID) override; + + // Replaces a CWeaponModelInfo clump with a new clump bool ReplaceWeaponModel(RpClump* pNew, unsigned short usModelID) override; bool ReplacePedModel(RpClump* pNew, unsigned short usModelID) override; @@ -92,22 +105,26 @@ class CRenderWareSA : public CRenderWare // szName should be without the part suffix (e.g. 'door_lf' or 'door_rf', and not 'door_lf_dummy') bool ReplacePartModels(RpClump* pClump, RpAtomicContainer* pAtomics, unsigned int uiAtomics, const char* szName); - ushort GetTXDIDForModelID(ushort usModelID); - void PulseWorldTextureWatch(); - void GetModelTextureNames(std::vector& outNameList, ushort usModelID); - bool GetModelTextures(std::vector>& outTextureList, ushort usModelID, std::vector vTextureNames); - void GetTxdTextures(std::vector& outTextureList, ushort usTxdId); - static void GetTxdTextures(std::vector& outTextureList, RwTexDictionary* pTXD); - const char* GetTextureName(CD3DDUMMY* pD3DData); - void SetRenderingClientEntity(CClientEntityBase* pClientEntity, ushort usModelId, int iTypeMask); + unsigned short GetTXDIDForModelID(unsigned short usModelID); + void PulseWorldTextureWatch(); + // Compatibility wrapper; uses per-model pending processing. + void ProcessPendingIsolatedTxdParents(bool bBlockingParentLoad = false) override; + void ProcessPendingIsolatedModels(bool bBlockingParentLoad = false); + void GetModelTextureNames(std::vector& outNameList, unsigned short usModelID); + bool GetModelTextures(std::vector>& outTextureList, unsigned short usModelID, std::vector vTextureNames); + void GetTxdTextures(std::vector& outTextureList, unsigned short usTxdId); + static void GetTxdTextures(std::vector& outTextureList, RwTexDictionary* pTXD); + static void GetTxdTextures(std::unordered_set& outTextureSet, RwTexDictionary* pTXD); + const char* GetTextureName(CD3DDUMMY* pD3DData); + void SetRenderingClientEntity(CClientEntityBase* pClientEntity, unsigned short usModelId, int iTypeMask); SShaderItemLayers* GetAppliedShaderForD3DData(CD3DDUMMY* pD3DData); void AppendAdditiveMatch(CSHADERDUMMY* pShaderData, CClientEntityBase* pClientEntity, const char* strTextureNameMatch, float fShaderPriority, - bool bShaderLayered, int iTypeMask, uint uiShaderCreateTime, bool bShaderUsesVertexShader, bool bAppendLayers); + bool bShaderLayered, int iTypeMask, unsigned int uiShaderCreateTime, bool bShaderUsesVertexShader, bool bAppendLayers); void AppendSubtractiveMatch(CSHADERDUMMY* pShaderData, CClientEntityBase* pClientEntity, const char* strTextureNameMatch); void RemoveClientEntityRefs(CClientEntityBase* pClientEntity); void RemoveShaderRefs(CSHADERDUMMY* pShaderItem); - bool RightSizeTxd(const SString& strInTxdFilename, const SString& strOutTxdFilename, uint uiSizeLimit); - void TxdForceUnload(ushort usTxdId, bool bDestroyTextures); + bool RightSizeTxd(const SString& strInTxdFilename, const SString& strOutTxdFilename, unsigned int uiSizeLimit); + void TxdForceUnload(unsigned short usTxdId, bool bDestroyTextures); void CMatrixToRwMatrix(const CMatrix& mat, RwMatrix& rwOutMatrix); void RwMatrixToCMatrix(const RwMatrix& rwMatrix, CMatrix& matOut); @@ -119,23 +136,26 @@ class CRenderWareSA : public CRenderWare void RwMatrixSetScale(RwMatrix& rwInOutMatrix, const CVector& vecScale); // CRenderWareSA methods - RwTexture* RightSizeTexture(RwTexture* pTexture, uint uiSizeLimit, SString& strError); + RwTexture* RightSizeTexture(RwTexture* pTexture, unsigned int uiSizeLimit, SString& strError); void ResetStats(); void GetShaderReplacementStats(SShaderReplacementStats& outStats); - CModelTexturesInfo* GetModelTexturesInfo(ushort usModelId); + CModelTexturesInfo* GetModelTexturesInfo(unsigned short usModelId, const char* callsiteTag = "unknown"); RwFrame* GetFrameFromName(RpClump* pRoot, SString strName); static void StaticSetHooks(); static void StaticSetClothesReplacingHooks(); - static void RwTexDictionaryRemoveTexture(RwTexDictionary* pTXD, RwTexture* pTex); + static bool RwTexDictionaryRemoveTexture(RwTexDictionary* pTXD, RwTexture* pTex); static bool RwTexDictionaryContainsTexture(RwTexDictionary* pTXD, RwTexture* pTex); static short CTxdStore_GetTxdRefcount(unsigned short usTxdID); - static bool StaticGetTextureCB(RwTexture* texture, std::vector* pTextureList); + static void DebugTxdAddRef(unsigned short usTxdId, const char* tag = nullptr, bool enableSafetyPin = true); + static void DebugTxdRemoveRef(unsigned short usTxdId, const char* tag = nullptr); void InitTextureWatchHooks(); - void StreamingAddedTexture(ushort usTxdId, const SString& strTextureName, CD3DDUMMY* pD3DData); - void StreamingRemovedTxd(ushort usTxdId); + void StreamingAddedTexture(unsigned short usTxdId, const SString& strTextureName, CD3DDUMMY* pD3DData); + void StreamingRemovedTxd(unsigned short usTxdId); + void RemoveStreamingTexture(unsigned short usTxdId, CD3DDUMMY* pD3DData); + bool IsTexInfoRegistered(CD3DDUMMY* pD3DData) const; void ScriptAddedTxd(RwTexDictionary* pTxd); void ScriptRemovedTexture(RwTexture* pTex); void SpecialAddedTexture(RwTexture* texture, const char* szTextureName = NULL); @@ -146,6 +166,15 @@ class CRenderWareSA : public CRenderWare static void GetClumpAtomicList(RpClump* pClump, std::vector& outAtomicList); static bool DoContainTheSameGeometry(RpClump* pClumpA, RpClump* pClumpB, RpAtomic* pAtomicB); + // Rebind clump material textures to current TXD textures (fixes stale texture pointers after TXD reload) + void RebindClumpTexturesToTxd(RpClump* pClump, unsigned short usTxdId) override; + + // Rebind single atomic's material textures to current TXD textures + void RebindAtomicTexturesToTxd(RpAtomic* pAtomic, unsigned short usTxdId) override; + + static const char* GetInternalTextureName(const char* szExternalName); + static const char* GetExternalTextureName(const char* szInternalName); + void OnTextureStreamIn(STexInfo* pTexInfo); void OnTextureStreamOut(STexInfo* pTexInfo); void DisableGTAVertexShadersForAWhile(); @@ -153,18 +182,20 @@ class CRenderWareSA : public CRenderWare void SetGTAVertexShadersEnabled(bool bEnable); // Watched world textures - std::multimap m_TexInfoMap; - CFastHashMap m_D3DDataTexInfoMap; - CClientEntityBase* m_pRenderingClientEntity; - ushort m_usRenderingEntityModelId; - int m_iRenderingEntityType; - CMatchChannelManager* m_pMatchChannelManager; - int m_uiReplacementRequestCounter; - int m_uiReplacementMatchCounter; - int m_uiNumReplacementRequests; - int m_uiNumReplacementMatches; - CElapsedTime m_GTAVertexShadersDisabledTimer; - bool m_bGTAVertexShadersEnabled; - std::set m_SpecialTextures; - static int ms_iRenderingType; + std::multimap m_TexInfoMap; + CFastHashMap m_D3DDataTexInfoMap; + // Reverse lookup for script/special textures (keyed by RwTexture* tag) + std::unordered_map m_ScriptTexInfoMap; + CClientEntityBase* m_pRenderingClientEntity; + unsigned short m_usRenderingEntityModelId; + int m_iRenderingEntityType; + CMatchChannelManager* m_pMatchChannelManager; + int m_uiReplacementRequestCounter; + int m_uiReplacementMatchCounter; + int m_uiNumReplacementRequests; + int m_uiNumReplacementMatches; + CElapsedTime m_GTAVertexShadersDisabledTimer; + bool m_bGTAVertexShadersEnabled; + std::set m_SpecialTextures; + static int ms_iRenderingType; }; diff --git a/Client/game_sa/CRendererSA.cpp b/Client/game_sa/CRendererSA.cpp index e576e82729e..eed6fe73ffc 100644 --- a/Client/game_sa/CRendererSA.cpp +++ b/Client/game_sa/CRendererSA.cpp @@ -15,8 +15,8 @@ #include "CMatrix.h" #include "gamesa_renderware.h" -#define SetLightColoursForPedsCarsAndObjects(fMult) ((RpLight*(__cdecl*)(float))0x735D90)(fMult) -#define SetAmbientColours() ((RpLight*(__cdecl*)())0x735D30)() +#define SetLightColoursForPedsCarsAndObjects(fMult) ((RpLight * (__cdecl*)(float))0x735D90)(fMult) +#define SetAmbientColours() ((RpLight * (__cdecl*)())0x735D30)() CRendererSA::CRendererSA() { @@ -32,9 +32,25 @@ void CRendererSA::RenderModel(CModelInfo* pModelInfo, const CMatrix& matrix, flo if (!pModelInfoSAInterface) return; + // Prevent GC from freeing RwObject during rendering + pModelInfo->ModelAddRef(NON_BLOCKING, "CRendererSA::RenderModel"); + + // Revalidate interface after AddRef + pModelInfoSAInterface = pModelInfo->GetInterface(); + if (!pModelInfoSAInterface) + { + pModelInfo->RemoveRef(); + return; + } + + // Check and cache pRwObject RwObject* pRwObject = pModelInfoSAInterface->pRwObject; if (!pRwObject) + { + // Release reference before early return to prevent leak + pModelInfo->RemoveRef(); return; + } RwFrame* pFrame = RpGetFrame(pRwObject); @@ -45,20 +61,31 @@ void CRendererSA::RenderModel(CModelInfo* pModelInfo, const CMatrix& matrix, flo rwMatrix.pos = (RwV3d&)matrix.vPos; RwFrameTransform(pFrame, &rwMatrix, rwCOMBINEREPLACE); - // Setup ambient light multiplier - SetLightColoursForPedsCarsAndObjects(lighting); - - if (pRwObject->type == RP_TYPE_ATOMIC) + // Ensure reference released on exception + try { - RpAtomic* pRpAtomic = reinterpret_cast(pRwObject); - pRpAtomic->renderCallback(reinterpret_cast(pRwObject)); + // Setup ambient light multiplier + SetLightColoursForPedsCarsAndObjects(lighting); + + if (pRwObject->type == RP_TYPE_ATOMIC) + { + RpAtomic* pRpAtomic = reinterpret_cast(pRwObject); + pRpAtomic->renderCallback(reinterpret_cast(pRwObject)); + } + else + { + RpClump* pClump = reinterpret_cast(pRwObject); + RpClumpRender(pClump); + } + + // Restore ambient light + SetAmbientColours(); } - else + catch (...) { - RpClump* pClump = reinterpret_cast(pRwObject); - RpClumpRender(pClump); - } - - // Restore ambient light - SetAmbientColours(); + // Release reference on rendering exception + pModelInfo->RemoveRef(); + throw; + } // Release reference - allow GC + pModelInfo->RemoveRef(); } diff --git a/Client/game_sa/CRopesSA.cpp b/Client/game_sa/CRopesSA.cpp index e51bf9948d1..6ca6e2bd062 100644 --- a/Client/game_sa/CRopesSA.cpp +++ b/Client/game_sa/CRopesSA.cpp @@ -14,7 +14,7 @@ DWORD dwDurationAddress = 0x558D1El; -CRopesSAInterface (&CRopesSA::ms_aRopes)[8] = *(CRopesSAInterface(*)[8])0xB768B8; +CRopesSAInterface (&CRopesSA::ms_aRopes)[8] = *(CRopesSAInterface (*)[8])0xB768B8; int CRopesSA::CreateRopeForSwatPed(const CVector& vecPosition, DWORD dwDuration) { @@ -23,13 +23,10 @@ int CRopesSA::CreateRopeForSwatPed(const CVector& vecPosition, DWORD dwDuration) CVector* pvecPosition = const_cast(&vecPosition); // First Push @ 0x558D1D is the duration. MemPut((void*)(dwDurationAddress), dwDuration); - _asm - { - push pvecPosition - call dwFunc - add esp, 0x4 - mov iReturn, eax - } + // clang-format off + using func_t = decltype(iReturn) (__cdecl*)(decltype(pvecPosition)); +iReturn = reinterpret_cast(dwFunc)(pvecPosition); + // clang-format on // Set it back for SA in case we ever do some other implementation. MemPut((DWORD*)(dwDurationAddress), 4000); return iReturn; diff --git a/Client/game_sa/CRopesSA.h b/Client/game_sa/CRopesSA.h index ea6f3081233..2d038f9ba82 100644 --- a/Client/game_sa/CRopesSA.h +++ b/Client/game_sa/CRopesSA.h @@ -14,9 +14,9 @@ #include #include -#define ROPES_COUNT 8 +#define ROPES_COUNT 8 -#define FUNC_CRopes_CreateRopeForSwatPed 0x558d10 +#define FUNC_CRopes_CreateRopeForSwatPed 0x558d10 class CRopesSAInterface { diff --git a/Client/game_sa/CSettingsSA.cpp b/Client/game_sa/CSettingsSA.cpp index 24f29aa31fb..11514a07bc6 100644 --- a/Client/game_sa/CSettingsSA.cpp +++ b/Client/game_sa/CSettingsSA.cpp @@ -26,9 +26,9 @@ static const float MOUSE_SENSITIVITY_MIN = 0.000312f; static const float MOUSE_SENSITIVITY_DEFAULT = 0.0025f; static const float MOUSE_SENSITIVITY_MAX = MOUSE_SENSITIVITY_DEFAULT * 2 - MOUSE_SENSITIVITY_MIN; -#define VAR_CurVideoMode (*((uint*)(0x08D6220))) +#define VAR_CurVideoMode (*((uint*)(0x08D6220))) #define VAR_SavedVideoMode (*((uint*)(0x0BA6820))) -#define VAR_CurAdapter (*((uint*)(0x0C920F4))) +#define VAR_CurAdapter (*((uint*)(0x0C920F4))) #define HOOKPOS_GetFxQuality 0x49EA50 void HOOK_GetFxQuality(); @@ -53,7 +53,7 @@ CSettingsSA::CSettingsSA() HookInstall(HOOKPOS_StoreShadowForVehicle, (DWORD)HOOK_StoreShadowForVehicle, 9); m_iDesktopWidth = 0; m_iDesktopHeight = 0; - MemPut(0x6FF420, 0xC3); // Truncate CalculateAspectRatio + MemPut(0x6FF420, 0xC3); // Truncate CalculateAspectRatio MemPut(0x732926, &ms_fVehicleLODDistance); MemPut(0x732940, &ms_fTrainPlaneLODDistance); @@ -82,7 +82,7 @@ unsigned int CSettingsSA::GetNumVideoModes() VideoMode* CSettingsSA::GetVideoModeInfo(VideoMode* modeInfo, unsigned int modeIndex) { // RwEngineGetVideoModeInfo - return ((VideoMode*(__cdecl*)(VideoMode*, unsigned int))0x7F2CF0)(modeInfo, modeIndex); + return ((VideoMode * (__cdecl*)(VideoMode*, unsigned int))0x7F2CF0)(modeInfo, modeIndex); } unsigned int CSettingsSA::GetCurrentVideoMode() @@ -150,7 +150,10 @@ unsigned int CSettingsSA::GetUsertrackMode() void CSettingsSA::SetUsertrackMode(unsigned int uiMode) { - m_pInterface->ucUsertrackMode = uiMode; + if (uiMode > 2) + uiMode = 0; + + m_pInterface->ucUsertrackMode = static_cast(uiMode); } bool CSettingsSA::IsUsertrackAutoScan() @@ -194,7 +197,7 @@ float CSettingsSA::GetDrawDistance() void CSettingsSA::SetDrawDistance(float fDistance) { - MemPutFast(0x8CD800, fDistance); // CRenderer::ms_lodDistScale + MemPutFast(0x8CD800, fDistance); // CRenderer::ms_lodDistScale m_pInterface->fDrawDistance = fDistance; } @@ -217,13 +220,13 @@ unsigned int CSettingsSA::GetFXQuality() void CSettingsSA::SetFXQuality(unsigned int fxQualityId) { - MemPutFast(VAR_ucFxQuality, fxQualityId); + MemPutFast(VAR_ucFxQuality, static_cast(fxQualityId)); } float CSettingsSA::GetMouseSensitivity() { float fRawValue = *(float*)VAR_fMouseSensitivity; - return UnlerpClamped(MOUSE_SENSITIVITY_MIN, fRawValue, MOUSE_SENSITIVITY_MAX); // Remap to 0-1 + return UnlerpClamped(MOUSE_SENSITIVITY_MIN, fRawValue, MOUSE_SENSITIVITY_MAX); // Remap to 0-1 } void CSettingsSA::SetMouseSensitivity(float fSensitivity) @@ -243,12 +246,10 @@ void CSettingsSA::SetAntiAliasing(unsigned int uiAntiAliasing, bool bOnRestart) if (!bOnRestart) { DWORD dwFunc = FUNC_SetAntiAliasing; - _asm - { - push uiAntiAliasing - call dwFunc - add esp, 4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(uiAntiAliasing)); + reinterpret_cast(dwFunc)(uiAntiAliasing); + // clang-format on SetCurrentVideoMode(m_pInterface->dwVideoMode, false); } @@ -267,12 +268,10 @@ void CSettingsSA::SetMipMappingEnabled(bool bEnable) void CSettingsSA::Save() { - _asm - { - mov ecx, CLASS_CMenuManager - mov eax, FUNC_CMenuManager_Save - call eax - } + // clang-format off + using func_t = void (__thiscall*)(decltype(0xBA6748) ); + reinterpret_cast(0x57C660)(0xBA6748); + // clang-format on } bool CSettingsSA::IsVolumetricShadowsEnabled() const noexcept @@ -289,7 +288,6 @@ void CSettingsSA::SetVolumetricShadowsEnabled(bool bEnable) MemPut(0x5E682A + 1, bEnable); } - bool CSettingsSA::GetVolumetricShadowsEnabledByVideoSetting() const noexcept { bool volumetricShadow; @@ -331,7 +329,6 @@ bool CSettingsSA::ResetDynamicPedShadows() noexcept return true; } - // // Volumetric shadow hooks // @@ -350,11 +347,11 @@ __declspec(noinline) void _cdecl MaybeAlterFxQualityValue(DWORD dwAddrCalledFrom // These vehicles seem to have problems with volumetric shadows, so force blob shadows switch (usCallingForVehicleModel) { - case 460: // Skimmer - case 511: // Beagle - case 572: // Mower - case 590: // Box Freight - case 592: // Andromada + case 460: // Skimmer + case 511: // Beagle + case 572: // Mower + case 590: // Box Freight + case 592: // Andromada dwFxQualityValue = 0; } usCallingForVehicleModel = 0; @@ -362,15 +359,18 @@ __declspec(noinline) void _cdecl MaybeAlterFxQualityValue(DWORD dwAddrCalledFrom else // Handle all calls from CPed::PreRenderAfterTest if (dwAddrCalledFrom > 0x5E65A0 && dwAddrCalledFrom < 0x5E7680) - { - dwFxQualityValue = pGame->GetSettings()->IsDynamicPedShadowsEnabled() ? 2 : 0; - } + { + dwFxQualityValue = pGame->GetSettings()->IsDynamicPedShadowsEnabled() ? 2 : 0; + } } // Hooked from 0x49EA50 -void _declspec(naked) HOOK_GetFxQuality() +static void __declspec(naked) HOOK_GetFxQuality() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov eax, [ecx+054h] // Current FxQuality setting @@ -385,12 +385,16 @@ void _declspec(naked) HOOK_GetFxQuality() mov eax, dwFxQualityValue retn } + // clang-format on } // Hook to discover what vehicle will be calling GetFxQuality -void _declspec(naked) HOOK_StoreShadowForVehicle() +static void __declspec(naked) HOOK_StoreShadowForVehicle() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Hooked from 0x70BDA0 5 bytes mov eax, [esp+4] // Get vehicle @@ -402,6 +406,7 @@ void _declspec(naked) HOOK_StoreShadowForVehicle() call eax jmp RETURN_StoreShadowForVehicle } + // clang-format on } //////////////////////////////////////////////// @@ -439,7 +444,7 @@ void CSettingsSA::SetAspectRatio(eAspectRatio aspectRatio, bool bAdjustmentEnabl { fValue = 16 / 10.f; } - else // ASPECT_RATIO_16_9 + else // ASPECT_RATIO_16_9 { fValue = 16 / 9.f; } @@ -447,11 +452,12 @@ void CSettingsSA::SetAspectRatio(eAspectRatio aspectRatio, bool bAdjustmentEnabl MemPutFast(0xC3EFA4, fValue); // Adjust position and size of our HUD components - if (bAdjustmentEnabled) + if (bAdjustmentEnabled) { pGame->GetHud()->AdjustComponents(fValue); - else + } else { pGame->GetHud()->ResetComponentAdjustment(); } +} //////////////////////////////////////////////// // @@ -490,7 +496,7 @@ void CSettingsSA::SetRadarMode(eRadarMode hudMode) //////////////////////////////////////////////// float ms_fFOV = 70; float ms_fFOVCar = 70; -float ms_fFOVCarMax = 100; // at high vehicle velocity +float ms_fFOVCarMax = 100; // at high vehicle velocity bool ms_bFOVPlayerFromScript = false; bool ms_bFOVVehicleFromScript = false; @@ -661,10 +667,11 @@ void CSettingsSA::ResetPedsLODDistance(bool bForceDefault) bool bHighDetailPeds; g_pCore->GetCVars()->Get("high_detail_peds", bHighDetailPeds); - if (bHighDetailPeds) + if (bHighDetailPeds) { ms_fPedsLODDistance = MAX_PEDS_LOD_DISTANCE; - else + } else { ms_fPedsLODDistance = DEFAULT_PEDS_LOD_DISTANCE; +} ms_bMaxPedsLODDistanceFromScript = false; } @@ -964,14 +971,17 @@ __declspec(noinline) int OnMY_SelectDevice() } // Hook info -#define HOOKPOS_SelectDevice 0x0746219 +#define HOOKPOS_SelectDevice 0x0746219 #define HOOKSIZE_SelectDevice 6 -DWORD RETURN_SelectDeviceSingle = 0x0746273; -DWORD RETURN_SelectDeviceMultiHide = 0x074622C; -DWORD RETURN_SelectDeviceMultiShow = 0x0746227; -void _declspec(naked) HOOK_SelectDevice() +DWORD RETURN_SelectDeviceSingle = 0x0746273; +DWORD RETURN_SelectDeviceMultiHide = 0x074622C; +DWORD RETURN_SelectDeviceMultiShow = 0x0746227; +static void __declspec(naked) HOOK_SelectDevice() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad call OnMY_SelectDevice @@ -981,16 +991,17 @@ void _declspec(naked) HOOK_SelectDevice() jl single jz multishow - // multhide + // multhide mov eax, 1 jmp RETURN_SelectDeviceMultiHide -multishow: + multishow: jmp RETURN_SelectDeviceMultiShow -single: + single: jmp RETURN_SelectDeviceSingle } + // clang-format on } //////////////////////////////////////////////// diff --git a/Client/game_sa/CSettingsSA.h b/Client/game_sa/CSettingsSA.h index 8e1443d1171..a21369ee52d 100644 --- a/Client/game_sa/CSettingsSA.h +++ b/Client/game_sa/CSettingsSA.h @@ -15,67 +15,67 @@ #include -#define CLASS_CMenuManager 0xBA6748 +#define CLASS_CMenuManager 0xBA6748 -#define FUNC_CMenuManager_Save 0x57C660 +#define FUNC_CMenuManager_Save 0x57C660 -#define VAR_ucFxQuality 0xA9AE54 -#define VAR_fMouseSensitivity 0xB6EC1C -#define VAR_RadarMode 0xBA676C +#define VAR_ucFxQuality 0xA9AE54 +#define VAR_fMouseSensitivity 0xB6EC1C +#define VAR_RadarMode 0xBA676C -#define CLASS_CAudioEngine 0xB6BC90 +#define CLASS_CAudioEngine 0xB6BC90 #define FUNC_CAudioEngine_SetEffectsMasterVolume 0x506E10 -#define FUNC_CAudioEngine_SetMusicMasterVolume 0x506DE0 +#define FUNC_CAudioEngine_SetMusicMasterVolume 0x506DE0 -#define CLASS_CGamma 0xC92134 +#define CLASS_CGamma 0xC92134 #define FUNC_CGamma_SetGamma 0x747200 -#define FUNC_SetAntiAliasing 0x7F8A90 +#define FUNC_SetAntiAliasing 0x7F8A90 -#define DEFAULT_VEHICLE_LOD_DISTANCE ( 70.0f ) -#define DEFAULT_PEDS_LOD_DISTANCE ( 60.0f ) +#define DEFAULT_VEHICLE_LOD_DISTANCE (70.0f) +#define DEFAULT_PEDS_LOD_DISTANCE (60.0f) // Default train distance is 150, so make it relative to default vehicle distance -#define TRAIN_LOD_DISTANCE_MULTIPLIER ( 2.14f ) -#define MAX_VEHICLE_LOD_DISTANCE ( 500.0f ) -#define MAX_PEDS_LOD_DISTANCE ( 500.0f ) -#define DEFAULT_BLUR_LEVEL ( 36 ) +#define TRAIN_LOD_DISTANCE_MULTIPLIER (2.14f) +#define MAX_VEHICLE_LOD_DISTANCE (500.0f) +#define MAX_PEDS_LOD_DISTANCE (500.0f) +#define DEFAULT_BLUR_LEVEL (36) -struct CSettingsSAInterface // see code around 0x57CE9A for where these are +struct CSettingsSAInterface // see code around 0x57CE9A for where these are { BYTE pad1[4]; - float fStatsScrollSpeed; // 0x4 + float fStatsScrollSpeed; // 0x4 BYTE pad2[0x34]; DWORD dwBrightness; float fDrawDistance; - bool bSubtitles; // 0x44 + bool bSubtitles; // 0x44 bool pad3[5]; - bool bLegend; // 0x4A - bool bUseWideScreen; // 0x4B - bool bFrameLimiter; // 0x4C - bool bRadioAutotune; // 0x4D + bool bLegend; // 0x4A + bool bUseWideScreen; // 0x4B + bool bFrameLimiter; // 0x4C + bool bRadioAutotune; // 0x4D bool pad4; - BYTE ucSfxVolume; // 0x4F - BYTE ucRadioVolume; // 0x50 - bool bRadioEqualizer; // 0x51 - BYTE ucRadioStation; // 0x52 + BYTE ucSfxVolume; // 0x4F + BYTE ucRadioVolume; // 0x50 + bool bRadioEqualizer; // 0x51 + BYTE ucRadioStation; // 0x52 BYTE pad5[0x5D]; - BYTE ucUsertrackMode; // 0xB0 - bool bInvertPadX1; // 0xB1 - bool bInvertPadY1; // 0xB2 - bool bInvertPadX2; // 0xB3 - bool bInvertPadY2; // 0xB4 - bool bSwapPadAxis1; // 0xB5 - bool bSwapPadAxis2; // 0xB6 + BYTE ucUsertrackMode; // 0xB0 + bool bInvertPadX1; // 0xB1 + bool bInvertPadY1; // 0xB2 + bool bInvertPadX2; // 0xB3 + bool bInvertPadY2; // 0xB4 + bool bSwapPadAxis1; // 0xB5 + bool bSwapPadAxis2; // 0xB6 BYTE pad6[0xD]; - bool bMipMapping; // 0xC4 (setting appears to have no effect in gta 1.0) - bool bUsertrackAutoScan; // 0xC5 + bool bMipMapping; // 0xC4 (setting appears to have no effect in gta 1.0) + bool bUsertrackAutoScan; // 0xC5 BYTE pad7[0x2]; - DWORD dwAntiAliasing; // 0xC8 - DWORD dwFrontendAA; // 0xCC (anti-aliasing value in the single-player settings menu. Useless for MTA). - bool bUseKeyboardAndMouse; // 0xD0 + DWORD dwAntiAliasing; // 0xC8 + DWORD dwFrontendAA; // 0xCC (anti-aliasing value in the single-player settings menu. Useless for MTA). + bool bUseKeyboardAndMouse; // 0xD0 BYTE pad8[3]; - DWORD dwVideoMode; // 0xD4 - DWORD dwPrevVideoMode; // 0xD8 + DWORD dwVideoMode; // 0xD4 + DWORD dwPrevVideoMode; // 0xD8 }; class CSettingsSA : public CGameSettings @@ -141,7 +141,7 @@ class CSettingsSA : public CGameSettings bool IsVolumetricShadowsEnabled() const noexcept; bool GetVolumetricShadowsEnabledByVideoSetting() const noexcept; bool ResetVolumetricShadows() noexcept; - + void SetVolumetricShadowsEnabled(bool bEnable); void SetVolumetricShadowsSuspended(bool bSuspended); diff --git a/Client/game_sa/CStatsSA.cpp b/Client/game_sa/CStatsSA.cpp index ff18dfe7910..f7fd41e99c6 100644 --- a/Client/game_sa/CStatsSA.cpp +++ b/Client/game_sa/CStatsSA.cpp @@ -18,13 +18,15 @@ float CStatsSA::GetStatValue(unsigned short usIndex) float fReturn = 0.0f; DWORD dwStatIndex = usIndex; - _asm + // clang-format off + __asm { push dwStatIndex call dwFunc add esp, 4 fstp fReturn } + // clang-format on return fReturn; } @@ -33,13 +35,10 @@ void CStatsSA::ModifyStat(unsigned short usIndex, float fAmmount) DWORD dwFunc = FUNC_ModifyStat; DWORD dwStatIndex = usIndex; - _asm - { - push fAmmount - push dwStatIndex - call dwFunc - add esp, 8 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(dwStatIndex), decltype(fAmmount)); + reinterpret_cast(dwFunc)(dwStatIndex, fAmmount); + // clang-format on } void CStatsSA::SetStatValue(unsigned short usIndex, float fAmmount) @@ -47,13 +46,10 @@ void CStatsSA::SetStatValue(unsigned short usIndex, float fAmmount) DWORD dwFunc = FUNC_SetStatValue; DWORD dwStatIndex = usIndex; - _asm - { - push fAmmount - push dwStatIndex - call dwFunc - add esp, 8 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(dwStatIndex), decltype(fAmmount)); + reinterpret_cast(dwFunc)(dwStatIndex, fAmmount); + // clang-format on } unsigned short CStatsSA::GetSkillStatIndex(eWeaponType type) @@ -61,12 +57,9 @@ unsigned short CStatsSA::GetSkillStatIndex(eWeaponType type) int weaponType = (int)type; int iIndex; DWORD dwFunc = FUNC_CWeaponInfo_GetSkillStatIndex; - _asm - { - push weaponType - call dwFunc - add esp, 0x4 - mov iIndex, eax - } + // clang-format off + using func_t = decltype(iIndex) (__cdecl*)(decltype(weaponType)); +iIndex = reinterpret_cast(dwFunc)(weaponType); + // clang-format on return (unsigned short)iIndex; } diff --git a/Client/game_sa/CStatsSA.h b/Client/game_sa/CStatsSA.h index ea7e6d6a72a..37a393f91b6 100644 --- a/Client/game_sa/CStatsSA.h +++ b/Client/game_sa/CStatsSA.h @@ -13,10 +13,10 @@ #include -#define FUNC_GetStatValue 0x558E40 -#define FUNC_ModifyStat 0x55D090 -#define FUNC_SetStatValue 0x55A070 -#define FUNC_CWeaponInfo_GetSkillStatIndex 0x743CD0 +#define FUNC_GetStatValue 0x558E40 +#define FUNC_ModifyStat 0x55D090 +#define FUNC_SetStatValue 0x55A070 +#define FUNC_CWeaponInfo_GetSkillStatIndex 0x743CD0 class CStatsSA : public CStats { diff --git a/Client/game_sa/CStreamingGC.cpp b/Client/game_sa/CStreamingGC.cpp new file mode 100644 index 00000000000..72e801991f3 --- /dev/null +++ b/Client/game_sa/CStreamingGC.cpp @@ -0,0 +1,270 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CStreamingGC.cpp + * PURPOSE: Streaming Garbage Collector protection via guard + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include "CStreamingGC.h" +#include "CGameSA.h" +#include "CModelInfoSA.h" + +extern CGameSA* pGame; + +namespace +{ + using TProtectedModelMap = std::unordered_map; +} + +// Static member initialization +std::unordered_map CStreamingGC::ms_protectedModels; +std::mutex CStreamingGC::ms_mutex; +std::atomic_bool CStreamingGC::ms_bInitialized{false}; +std::atomic_bool CStreamingGC::ms_bShuttingDown{false}; +std::atomic_uint64_t CStreamingGC::ms_generation{1}; + +void CStreamingGC::Initialize() +{ + std::lock_guard lock(ms_mutex); + if (ms_bInitialized.load()) + return; + + ms_bShuttingDown.store(false); + + // CStreamingGC provides Guard-based protection using model reference counting + // Protected models have their reference count increased via ModelAddRef + + LogEvent(6645, "StreamingGC", "Initialize", "StreamingGC protection system initialized"); + ms_bInitialized.store(true); +} + +void CStreamingGC::Shutdown() +{ + if (!ms_bInitialized.load()) + return; + + TProtectedModelMap protectedModelsToRelease; + + { + std::lock_guard lock(ms_mutex); + + ms_bShuttingDown.store(true); + ms_generation.fetch_add(1); + protectedModelsToRelease.swap(ms_protectedModels); + ms_bInitialized.store(false); + } + + if (!pGame) + return; + + for (const auto& [modelId, refCount] : protectedModelsToRelease) + { + try + { + auto* pModelInfo = static_cast(pGame->GetModelInfo(modelId)); + if (pModelInfo) + pModelInfo->RemoveRef(); + } + catch (...) + { + // Continue releasing remaining references on exception + } + } +} + +bool CStreamingGC::ProtectModel(std::uint32_t modelId) +{ + return ProtectModelWithGeneration(modelId, nullptr); +} + +bool CStreamingGC::ProtectModelWithGeneration(std::uint32_t modelId, std::uint64_t* pGenerationOut) +{ + // Validate model ID is within valid range + if (modelId >= MODELINFO_MAX) [[unlikely]] + return false; + + std::lock_guard lock(ms_mutex); + + if (ms_bShuttingDown.load()) [[unlikely]] + return false; + + if (!ms_bInitialized.load()) + { + LogEvent(6645, "StreamingGC", "Initialize", "StreamingGC protection system initialized"); + ms_bInitialized.store(true); + } + + auto findResult = ms_protectedModels.find(modelId); + if (findResult != ms_protectedModels.end()) + { + ++(findResult->second); + if (pGenerationOut) + *pGenerationOut = ms_generation.load(); + return true; + } + + // Early return if no game instance + if (!pGame) [[unlikely]] + return false; + + auto* pModelInfo = static_cast(pGame->GetModelInfo(modelId)); + if (!pModelInfo) [[unlikely]] + return false; + + // Only track if model is loaded + // We do not attempt to load the model if it's not loaded to avoid deadlocks + // (ProtectModel holds a lock that OnRemoveModel also needs) + if (pModelInfo->IsLoaded()) [[likely]] + { + auto insertResult = ms_protectedModels.emplace(modelId, 1u); + if (!insertResult.second) + { + ++(insertResult.first->second); + return true; + } + + // Pin only models that are already loaded. Never trigger a streaming request here. + if (!pModelInfo->TryAddRefIfLoaded()) + { + ms_protectedModels.erase(modelId); + return false; + } + + if (pGenerationOut) + *pGenerationOut = ms_generation.load(); + + return true; + } + else + { +// Attempted to protect unloaded model +#if MTA_DEBUG + OutputDebugString(SString("CStreamingGC::ProtectModel: Ignored attempt to protect unloaded model %d", modelId)); +#endif + } + + return false; +} + +bool CStreamingGC::UnprotectModel(std::uint32_t modelId) +{ + return UnprotectModelForGeneration(modelId, ms_generation.load()); +} + +bool CStreamingGC::UnprotectModelForGeneration(std::uint32_t modelId, std::uint64_t generation) +{ + if (!ms_bInitialized.load()) [[unlikely]] + return false; + + // Validate model ID is within valid range + if (modelId >= MODELINFO_MAX) [[unlikely]] + return false; + + bool shouldReleaseRef = false; + + { + std::lock_guard lock(ms_mutex); + + if (generation != ms_generation.load()) + return false; + + // Only remove ref if currently protected + auto findResult = ms_protectedModels.find(modelId); + if (findResult == ms_protectedModels.end()) + return false; + + if (findResult->second > 1u) + { + --(findResult->second); + return true; + } + + ms_protectedModels.erase(findResult); + shouldReleaseRef = true; + } + + if (shouldReleaseRef) + { + // Decrease reference count to allow GC + if (pGame) [[likely]] + { + auto* pModelInfo = static_cast(pGame->GetModelInfo(modelId)); + if (pModelInfo) [[likely]] + pModelInfo->RemoveRef(); + } + + return true; + } + + return false; +} + +bool CStreamingGC::IsModelProtected(std::uint32_t modelId) +{ + if (!ms_bInitialized.load()) [[unlikely]] + return false; + + // Validate model ID is within valid range + if (modelId >= MODELINFO_MAX) [[unlikely]] + return false; + + std::lock_guard lock(ms_mutex); + return ms_protectedModels.find(modelId) != ms_protectedModels.end(); +} + +std::size_t CStreamingGC::GetProtectedCount() +{ + std::lock_guard lock(ms_mutex); + return ms_protectedModels.size(); +} + +void CStreamingGC::ClearAllProtections() +{ + TProtectedModelMap protectedModelsToRelease; + + { + std::lock_guard lock(ms_mutex); + ms_generation.fetch_add(1); + protectedModelsToRelease.swap(ms_protectedModels); + } + + // Release all references before clearing + if (pGame) + { + for (const auto& [modelId, refCount] : protectedModelsToRelease) + { + try + { + auto* pModelInfo = static_cast(pGame->GetModelInfo(modelId)); + if (pModelInfo) + pModelInfo->RemoveRef(); + } + catch (...) + { + // Continue releasing remaining references on exception + } + } + } +} + +//////////////////////////////////////////////////////////////// +// +// CStreamingGC::OnRemoveModel +// +// Called from the game model removal handler +// Returns true if removal should proceed, false to block +// +//////////////////////////////////////////////////////////////// +bool CStreamingGC::OnRemoveModel(std::uint32_t modelId) +{ + // Validate model ID is within valid range + if (modelId >= MODELINFO_MAX) [[unlikely]] + return true; // Allow removal of invalid model IDs + + return !IsModelProtected(modelId); +} diff --git a/Client/game_sa/CStreamingGC.h b/Client/game_sa/CStreamingGC.h new file mode 100644 index 00000000000..9e6552a085d --- /dev/null +++ b/Client/game_sa/CStreamingGC.h @@ -0,0 +1,99 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CStreamingGC.h + * PURPOSE: Streaming Garbage Collector protection + * USAGE: Provides temporary model protection during operations. + * Use Guard class for safety. RemoveModel hook installed via + * CStreamingRemoveModel interception in HookDestructors. + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include +#include +#include + +class CStreamingGC +{ +public: + // Marks the protection system ready for use. + // The remove-model hook is installed separately by the multiplayer layer. + static void Initialize(); + + // Stops accepting new protections and releases current ones. + // The remove-model hook remains installed elsewhere. + static void Shutdown(); + + // Check if model is protected. Returns true if model is protected from GC + static bool IsModelProtected(std::uint32_t modelId); + + // Get count of currently protected models + static std::size_t GetProtectedCount(); + + // Clear all protections - releases all references (Be careful) + static void ClearAllProtections(); + + // Hook callback for model removal - returns true to allow, false to block + static bool OnRemoveModel(std::uint32_t modelId); + + // Guard for automatic model protection + class Guard + { + public: + explicit Guard(std::uint32_t modelId) : m_modelId(modelId), m_generation(0) { m_bActive = ProtectModelWithGeneration(m_modelId, &m_generation); } + + ~Guard() noexcept + { + if (m_bActive) + static_cast(UnprotectModelForGeneration(m_modelId, m_generation)); + } + + // Prevent copying + Guard(const Guard&) = delete; + Guard& operator=(const Guard&) = delete; + + // Allow moving + Guard(Guard&& other) noexcept : m_modelId(other.m_modelId), m_bActive(other.m_bActive), m_generation(other.m_generation) + { + other.m_bActive = false; + other.m_generation = 0; + } + + Guard& operator=(Guard&& other) noexcept + { + if (this != &other) + { + if (m_bActive) + static_cast(UnprotectModelForGeneration(m_modelId, m_generation)); + + m_modelId = other.m_modelId; + m_bActive = other.m_bActive; + m_generation = other.m_generation; + other.m_bActive = false; + other.m_generation = 0; + } + return *this; + } + + private: + std::uint32_t m_modelId; + bool m_bActive; + std::uint64_t m_generation; + }; + +private: + static bool ProtectModel(std::uint32_t modelId); + [[nodiscard]] static bool UnprotectModel(std::uint32_t modelId); + static bool ProtectModelWithGeneration(std::uint32_t modelId, std::uint64_t* pGenerationOut); + static bool UnprotectModelForGeneration(std::uint32_t modelId, std::uint64_t generation); + static std::unordered_map ms_protectedModels; + static std::mutex ms_mutex; + static std::atomic_bool ms_bInitialized; + static std::atomic_bool ms_bShuttingDown; + static std::atomic_uint64_t ms_generation; +}; diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 8544bdda642..d321cb39fae 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -15,17 +15,242 @@ #include "CModelInfoSA.h" #include "Fileapi.h" #include "processthreadsapi.h" +#include "CGameSA.h" extern CCoreInterface* g_pCore; +extern CGameSA* pGame; // count: 26316 in unmodified game -CStreamingInfo (&CStreamingSA::ms_aInfoForModel)[26316] = *(CStreamingInfo(*)[26316])0x8E4CC0; +CStreamingInfo (&CStreamingSA::ms_aInfoForModel)[26316] = *(CStreamingInfo (*)[26316])0x8E4CC0; HANDLE* phStreamingThread = (HANDLE*)0x8E4008; uint32(&CStreamingSA::ms_streamingHalfOfBufferSizeBlocks) = *(uint32*)0x8E4CA8; void* (&CStreamingSA::ms_pStreamingBuffer)[2] = *(void* (*)[2])0x8E4CAC; namespace { + // Validates model info pointer by checking VFTBL is in valid GTA:SA code range. + // Uses SEH for crash protection when reading the VFTBL field, but avoids + // the expensive volatile read of VFTBL->Destructor by using address validation. + bool IsValidPtr(const void* ptr) noexcept + { + if (!ptr) + return false; + + __try + { + const auto* p = static_cast(ptr); + const DWORD vftbl = reinterpret_cast(p->VFTBL); + // VFTBL must be in valid GTA:SA code range - this implicitly validates + // the pointer since garbage/freed memory won't have valid VFTBL addresses + return SharedUtil::IsValidGtaSaPtr(vftbl); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + } + + // Reusable event handle pool for async CreateFile operations + namespace StreamingEventPool + { + constexpr auto SIZE = 8u; + static std::atomic slots[SIZE] = {}; + + inline HANDLE Acquire() + { + for (auto& slot : slots) + { + if (auto h = slot.exchange(nullptr)) + { + ResetEvent(h); + return h; + } + } + return CreateEventW(nullptr, TRUE, FALSE, nullptr); + } + + inline void Release(HANDLE h) + { + if (!h) + return; + + for (auto& slot : slots) + { + HANDLE expected = nullptr; + if (slot.compare_exchange_strong(expected, h)) + return; + } + CloseHandle(h); + } + } + + namespace AsyncStreamingFile + { + enum class State : int + { + Running = 0, + Completed = 1, + Abandoned = 2 + }; + constexpr DWORD TIMEOUT_MS = 5'000; + + struct Params + { + std::wstring fileName; + DWORD access = 0; + DWORD shareMode = 0; + DWORD disposition = 0; + DWORD flags = 0; + HANDLE result = INVALID_HANDLE_VALUE; + DWORD error = ERROR_SUCCESS; + HANDLE event = nullptr; + std::atomic state{0}; + }; + + constexpr auto POOL_SIZE = 8u; + static std::atomic pool[POOL_SIZE] = {}; + + inline Params* Acquire() + { + for (auto& slot : pool) + { + if (auto* p = slot.exchange(nullptr)) + { + p->state = 0; + p->result = INVALID_HANDLE_VALUE; + p->error = ERROR_SUCCESS; + p->event = nullptr; + p->fileName.clear(); + return p; + } + } + return new (std::nothrow) Params(); + } + + inline void Release(Params* p) + { + if (!p) + return; + + p->fileName.clear(); + + for (auto& slot : pool) + { + Params* expected = nullptr; + if (slot.compare_exchange_strong(expected, p)) + return; + } + delete p; + } + + static DWORD WINAPI PoolCallback(LPVOID arg) + { + auto* p = static_cast(arg); + + p->result = CreateFileW(p->fileName.c_str(), p->access, p->shareMode, nullptr, p->disposition, p->flags, nullptr); + p->error = GetLastError(); + + auto expected = static_cast(State::Running); + if (p->state.compare_exchange_strong(expected, static_cast(State::Completed))) + { + SetEvent(p->event); + } + else + { + StreamingEventPool::Release(p->event); + if (p->result != INVALID_HANDLE_VALUE) + CloseHandle(p->result); + Release(p); + } + return 0; + } + + inline HANDLE DirectCall(LPCWSTR name, DWORD access, DWORD share, DWORD disp, DWORD flags) + { + return CreateFileW(name, access, share, nullptr, disp, flags, nullptr); + } + } + + static HANDLE CreateFileWithTimeoutForStreaming(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes) + { + using namespace AsyncStreamingFile; + + if (!lpFileName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return INVALID_HANDLE_VALUE; + } + + auto* params = Acquire(); + if (!params) + { + AddReportLog(6216, "Streaming CreateFile timeout: alloc failed"); + return DirectCall(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes); + } + + try + { + params->fileName = lpFileName; + } + catch (...) + { + AddReportLog(6221, "Streaming CreateFile timeout: string copy failed"); + Release(params); + return DirectCall(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes); + } + + auto event = StreamingEventPool::Acquire(); + if (!event) + { + AddReportLog(6217, "Streaming CreateFile timeout: event failed"); + Release(params); + return DirectCall(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes); + } + + params->access = dwDesiredAccess; + params->shareMode = dwShareMode; + params->disposition = dwCreationDisposition; + params->flags = dwFlagsAndAttributes; + params->event = event; + + if (!QueueUserWorkItem(PoolCallback, params, WT_EXECUTELONGFUNCTION)) + { + AddReportLog(6219, "Streaming CreateFile timeout: queue failed"); + StreamingEventPool::Release(event); + Release(params); + return DirectCall(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes); + } + + if (WaitForSingleObject(event, TIMEOUT_MS) == WAIT_OBJECT_0) + { + StreamingEventPool::Release(event); + auto hResult = params->result; + auto dwError = params->error; + Release(params); + SetLastError(dwError); + return hResult; + } + + AddReportLog(6213, SString("Streaming CreateFile timed out after %ums: %s", TIMEOUT_MS, SharedUtil::ToUTF8(lpFileName).c_str())); + + auto expected = static_cast(State::Running); + if (params->state.compare_exchange_strong(expected, static_cast(State::Abandoned))) + { + SetLastError(ERROR_TIMEOUT); + } + else + { + StreamingEventPool::Release(event); + auto actualError = (params->result == INVALID_HANDLE_VALUE) ? params->error : ERROR_TIMEOUT; + if (params->result != INVALID_HANDLE_VALUE) + CloseHandle(params->result); + Release(params); + SetLastError(actualError); + } + return INVALID_HANDLE_VALUE; + } + // // Used in LoadAllRequestedModels to record state // @@ -38,10 +263,10 @@ namespace void Record() { - #define VAR_CStreaming_bLoadingBigModel 0x08E4A58 - #define VAR_CStreaming_numPriorityRequests 0x08E4BA0 - #define VAR_CStreaming_numModelsRequested 0x08E4CB8 - #define VAR_CStreaming_memoryUsed 0x08E4CB4 +#define VAR_CStreaming_bLoadingBigModel 0x08E4A58 +#define VAR_CStreaming_numPriorityRequests 0x08E4BA0 +#define VAR_CStreaming_numModelsRequested 0x08E4CB8 +#define VAR_CStreaming_memoryUsed 0x08E4CB4 bLoadingBigModel = *(BYTE*)VAR_CStreaming_bLoadingBigModel != 0; numPriorityRequests = *(DWORD*)VAR_CStreaming_numPriorityRequests; @@ -50,11 +275,11 @@ namespace } }; - constexpr size_t RESERVED_STREAMS_NUM = 10; // GTA3 + 9 SFX archives(FEET, GENRL, PAIN_A, SCRIPT, SPC_EA, SPC_FA, SPC_GA, SPC_NA, SPC_PA) + constexpr size_t RESERVED_STREAMS_NUM = 10; // GTA3 + 9 SFX archives(FEET, GENRL, PAIN_A, SCRIPT, SPC_EA, SPC_FA, SPC_GA, SPC_NA, SPC_PA) constexpr size_t MAX_STREAMS_NUM = 255; constexpr size_t MAX_IMAGES_NUM = MAX_STREAMS_NUM - RESERVED_STREAMS_NUM; - constexpr size_t MIN_IMAGES_NUM = 6; // GTA3(yes, it is presented twice), GTA_INT, CARREC, SCRIPT, CUTSCENE, PLAYER -} // namespace + constexpr size_t MIN_IMAGES_NUM = 6; // GTA3(yes, it is presented twice), GTA_INT, CARREC, SCRIPT, CUTSCENE, PLAYER +} // namespace bool IsUpgradeModelId(DWORD dwModelID) { @@ -67,16 +292,13 @@ CStreamingSA::CStreamingSA() SetArchivesNum(VAR_DefaultMaxArchives); // Copy the default data - HANDLE (&defaultStreamingHandlers)[32] = *(HANDLE(*)[32])0x8E4010; - SStreamName (&defaultStreamingNames)[32] = *(SStreamName(*)[32])0x8E4098; - CArchiveInfo (&defaultAchiveInfo)[8] = *(CArchiveInfo(*)[8])0x8E48D8; - - std::memcpy(m_StreamHandles.data(), defaultStreamingHandlers, - sizeof(HANDLE) * std::min(m_StreamHandles.size(), (size_t)VAR_DefaultStreamHandlersMaxCount)); - std::memcpy(m_StreamNames.data(), defaultStreamingNames, - sizeof(SStreamName) * std::min(m_StreamNames.size(), (size_t)VAR_DefaultStreamHandlersMaxCount)); - std::memcpy(m_Imgs.data(), defaultAchiveInfo, - sizeof(CArchiveInfo) * std::min(m_Imgs.size(), (size_t)VAR_DefaultMaxArchives)); + HANDLE(&defaultStreamingHandlers)[32] = *(HANDLE(*)[32])0x8E4010; + SStreamName(&defaultStreamingNames)[32] = *(SStreamName(*)[32])0x8E4098; + CArchiveInfo(&defaultAchiveInfo)[8] = *(CArchiveInfo(*)[8])0x8E48D8; + + std::memcpy(m_StreamHandles.data(), defaultStreamingHandlers, sizeof(HANDLE) * std::min(m_StreamHandles.size(), (size_t)VAR_DefaultStreamHandlersMaxCount)); + std::memcpy(m_StreamNames.data(), defaultStreamingNames, sizeof(SStreamName) * std::min(m_StreamNames.size(), (size_t)VAR_DefaultStreamHandlersMaxCount)); + std::memcpy(m_Imgs.data(), defaultAchiveInfo, sizeof(CArchiveInfo) * std::min(m_Imgs.size(), (size_t)VAR_DefaultMaxArchives)); } void CStreamingSA::SetArchivesNum(size_t imagesNum) @@ -98,7 +320,7 @@ void CStreamingSA::SetArchivesNum(size_t imagesNum) return; } - const auto pImgs = m_Imgs.data(); + const auto pImgs = m_Imgs.data(); const size_t uiImgsSize = sizeof(CArchiveInfo) * m_Imgs.size(); // CStreaming::AddImageToList @@ -184,24 +406,24 @@ void CStreamingSA::SetArchivesNum(size_t imagesNum) // _openStream DWORD dwExeCodePtr = (DWORD)0x01564A94; - MemPutFast((void*)(dwExeCodePtr), (WORD)0x048B); // mov eax, _streamHandles[esi*4] + MemPutFast((void*)(dwExeCodePtr), (WORD)0x048B); // mov eax, _streamHandles[esi*4] MemPutFast((void*)(dwExeCodePtr + 2), (BYTE)0xB5); MemPutFast((void*)(dwExeCodePtr + 3), (DWORD)pStreamHandles); MemPutFast((void*)(dwExeCodePtr + 7), (WORD)0xC085); MemPutFast((void*)(dwExeCodePtr + 9), (WORD)0x840F); - MemPutFast((void*)(dwExeCodePtr + 11), (DWORD)(0x01564B31 - (dwExeCodePtr+15))); + MemPutFast((void*)(dwExeCodePtr + 11), (DWORD)(0x01564B31 - (dwExeCodePtr + 15))); MemPutFast((void*)(dwExeCodePtr + 15), (BYTE)0x46); MemPutFast((void*)(dwExeCodePtr + 16), (WORD)0xFE81); - MemPutFast((void*)(dwExeCodePtr + 18), (DWORD)(handlesNum - 1)); // MAX_NUMBER_OF_STREAM_HANDLES + MemPutFast((void*)(dwExeCodePtr + 18), (DWORD)(handlesNum - 1)); // MAX_NUMBER_OF_STREAM_HANDLES MemPutFast((void*)(dwExeCodePtr + 22), (BYTE)0x7C); - MemPutFast((void*)(dwExeCodePtr + 23), (BYTE)(dwExeCodePtr - (dwExeCodePtr+24))); + MemPutFast((void*)(dwExeCodePtr + 23), (BYTE)(dwExeCodePtr - (dwExeCodePtr + 24))); MemPutFast((void*)(dwExeCodePtr + 24), (BYTE)0xE9); - MemPutFast((void*)(dwExeCodePtr + 25), (DWORD)(0x01564B31 - (dwExeCodePtr+29))); + MemPutFast((void*)(dwExeCodePtr + 25), (DWORD)(0x01564B31 - (dwExeCodePtr + 29))); // end of loop creation MemPutFast((void*)0x1564B74, (DWORD)pStreamHandles); @@ -223,34 +445,86 @@ void CStreamingSA::SetArchivesNum(size_t imagesNum) } } +static void UnlinkStreamingInfoNeighbors(CStreamingInfo* pStreamInfo, CStreamingSA* pStreaming) +{ + if (!pStreamInfo || !pStreaming) + return; + + if (pStreamInfo->loadState == eModelLoadState::LOADSTATE_NOT_LOADED) + return; + + constexpr unsigned short kInvalid = static_cast(-1); + const unsigned short prev = pStreamInfo->prevId; + const unsigned short next = pStreamInfo->nextId; + + CStreamingInfo* pPrev = (prev != kInvalid) ? pStreaming->GetStreamingInfo(prev) : nullptr; + CStreamingInfo* pNext = (next != kInvalid) ? pStreaming->GetStreamingInfo(next) : nullptr; + + // If one side already points outside the streaming array, cut the + // reachable side instead of copying the bad link forward. + if (pPrev) + pPrev->nextId = (next == kInvalid || pNext) ? next : kInvalid; + if (pNext) + pNext->prevId = (prev == kInvalid || pPrev) ? prev : kInvalid; +} + void CStreamingSA::RequestModel(DWORD dwModelID, DWORD dwFlags) { if (IsUpgradeModelId(dwModelID)) { DWORD dwFunc = FUNC_RequestVehicleUpgrade; - _asm - { - push dwFlags - push dwModelID - call dwFunc - add esp, 8 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(dwModelID), decltype(dwFlags)); + reinterpret_cast(dwFunc)(dwModelID, dwFlags); + // clang-format on } else { - DWORD dwFunction = FUNC_CStreaming__RequestModel; - _asm + // Overflow TXD slots (pool index >= 6316) produce streaming IDs >= 26316, + // which exceed ms_aInfoForModel[26316]. These slots are managed by MTA + // independently of SA's streaming system, so skip the request. + if (dwModelID >= static_cast(pGame->GetCountOfAllFileIDs())) + return; + + CBaseModelInfoSAInterface** ppModelInfo = reinterpret_cast(ARRAY_ModelInfo); + if (dwModelID < MODELINFO_DFF_MAX) { - push dwFlags - push dwModelID - call dwFunction - add esp, 8 + CBaseModelInfoSAInterface* pModelInfo = ppModelInfo[dwModelID]; + if (!IsValidPtr(pModelInfo)) + { + ppModelInfo[dwModelID] = nullptr; + + CStreamingInfo* pStreamInfo = GetStreamingInfo(dwModelID); + if (pStreamInfo) + { + // Unlink from SA's loaded-entry list before zeroing the link fields to avoid linked list corruptin + UnlinkStreamingInfoNeighbors(pStreamInfo, this); + pStreamInfo->prevId = static_cast(-1); + pStreamInfo->nextId = static_cast(-1); + pStreamInfo->nextInImg = static_cast(-1); + pStreamInfo->loadState = eModelLoadState::LOADSTATE_NOT_LOADED; + } + + return; + } } + + DWORD dwFunction = FUNC_CStreaming__RequestModel; + // clang-format off + using func_t = void (__cdecl*)(decltype(dwModelID), decltype(dwFlags)); + reinterpret_cast(dwFunction)(dwModelID, dwFlags); + // clang-format on } } void CStreamingSA::RemoveModel(std::uint32_t model) { + // Overflow TXD slots (pool index >= 6316) produce streaming IDs >= 26316, + // which exceed ms_aInfoForModel[26316]. These slots are managed by MTA + // independently of SA's streaming system, so skip the removal. + if (model >= static_cast(pGame->GetCountOfAllFileIDs())) + return; + using Signature = void(__cdecl*)(std::uint32_t); const auto function = reinterpret_cast(0x4089A0); function(model); @@ -262,12 +536,10 @@ void CStreamingSA::LoadAllRequestedModels(bool bOnlyPriorityModels, const char* DWORD dwFunction = FUNC_LoadAllRequestedModels; DWORD dwOnlyPriorityModels = bOnlyPriorityModels; - _asm - { - push dwOnlyPriorityModels - call dwFunction - add esp, 4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(dwOnlyPriorityModels)); + reinterpret_cast(dwFunction)(dwOnlyPriorityModels); + // clang-format on if (IS_TIMING_CHECKPOINTS()) { @@ -283,26 +555,25 @@ bool CStreamingSA::HasModelLoaded(DWORD dwModelID) { bool bReturn; DWORD dwFunc = FUNC_CStreaming__HasVehicleUpgradeLoaded; - _asm - { - push dwModelID - call dwFunc - add esp, 0x4 - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(dwModelID)); +bReturn = reinterpret_cast(dwFunc)(dwModelID); + // clang-format on return bReturn; } else { DWORD dwFunc = FUNC_CStreaming__HasModelLoaded; bool bReturn = 0; - _asm + // clang-format off + __asm { push dwModelID call dwFunc mov bReturn, al pop eax } + // clang-format on return bReturn; } @@ -311,14 +582,10 @@ bool CStreamingSA::HasModelLoaded(DWORD dwModelID) void CStreamingSA::RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel) { DWORD dwFunc = FUNC_CStreaming_RequestSpecialModel; - _asm - { - push channel - push szTexture - push model - call dwFunc - add esp, 0xC - } + // clang-format off + using func_t = void (__cdecl*)(decltype(model), decltype(szTexture), decltype(channel)); + reinterpret_cast(dwFunc)(model, szTexture, channel); + // clang-format on } void CStreamingSA::ReinitStreaming() @@ -333,6 +600,20 @@ void CStreamingSA::ReinitStreaming() void CStreamingSA::SetStreamingInfo(uint modelid, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg) { CStreamingInfo* pItemInfo = GetStreamingInfo(modelid); + if (!pItemInfo) + return; + + // We remove the existing RwObject because, after switching the archive, the streamer will load a new one. + // ReInit doesn't delete all RwObjects unless certain conditions are met. + // In this case, we must force-remove the RwObject from memory, because it is no longer used, + // and due to the archive change the streamer no longer detects it and therefore won't delete it. + // As a result, a memory leak occurs after every call to engineImageLinkDFF. + const auto baseTxdId = g_pCore->GetGame()->GetBaseIDforTXD(); + if (modelid < static_cast(baseTxdId)) + { + if (pItemInfo->loadState != eModelLoadState::LOADSTATE_NOT_LOADED) + RemoveModel(modelid); + } // Change nextInImg field for prev model for (CStreamingInfo& info : ms_aInfoForModel) @@ -351,11 +632,15 @@ void CStreamingSA::SetStreamingInfo(uint modelid, unsigned char usStreamID, uint pItemInfo->archiveId = usStreamID; pItemInfo->offsetInBlocks = uiOffset; pItemInfo->sizeInBlocks = usSize; - pItemInfo->nextInImg = uiNextInImg; + pItemInfo->nextInImg = static_cast(uiNextInImg); } CStreamingInfo* CStreamingSA::GetStreamingInfo(uint modelid) { + const uint maxStreamingID = pGame->GetCountOfAllFileIDs(); + if (modelid >= maxStreamingID) + return nullptr; + return &ms_aInfoForModel[modelid]; } @@ -400,10 +685,10 @@ unsigned char CStreamingSA::AddArchive(const wchar_t* szFilePath) if (ucStreamID == INVALID_STREAM_ID) return INVALID_ARCHIVE_ID; - // Create new stream handler + // Create new stream handler (uses timeout to avoid NtCreateFile hangs) const auto streamCreateFlags = *(DWORD*)0x8E3FE0; - HANDLE hFile = CreateFileW(szFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - streamCreateFlags | FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS, NULL); + HANDLE hFile = CreateFileWithTimeoutForStreaming(szFilePath, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, + streamCreateFlags | FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS); if (hFile == INVALID_HANDLE_VALUE) return INVALID_ARCHIVE_ID; @@ -431,54 +716,74 @@ void CStreamingSA::RemoveArchive(unsigned char ucArchiveID) bool CStreamingSA::SetStreamingBufferSize(uint32 numBlocks) { - numBlocks += numBlocks % 2; // Make sure number is even by "rounding" it upwards. [Otherwise it can't be split in half properly] - - // Check if the size is the same already + // Round up to even number so it can be split in half properly + numBlocks += numBlocks % 2; + + // Already the requested size if (numBlocks == ms_streamingHalfOfBufferSizeBlocks * 2) return true; if (ms_pStreamingBuffer[0] == nullptr || ms_pStreamingBuffer[1] == nullptr) return false; - // First of all, allocate the new buffer - // NOTE: Due to a bug in the `MallocAlign` code the function will just *crash* instead of returning nullptr on alloc. failure :D - typedef void*(__cdecl * Function_CMemoryMgr_MallocAlign)(uint32 uiCount, uint32 uiAlign); - void* pNewBuffer = ((Function_CMemoryMgr_MallocAlign)(0x72F4C0))(numBlocks * 2048, 2048); - if (!pNewBuffer) // ...so this code is useless for now + typedef void*(__cdecl * AllocFunc)(uint32, uint32); + typedef void(__cdecl * DeallocFunc)(void*); + + // Allocate new buffer first + void* pNewBuffer = ((AllocFunc)(0x72F4C0))(numBlocks * 2048, 2048); + if (!pNewBuffer) return false; int pointer = *(int*)0x8E3FFC; SGtaStream(&streaming)[5] = *(SGtaStream(*)[5])(pointer); - // Wait while streaming thread ends tasks - while (streaming[0].bInUse || streaming[1].bInUse); + void* const pOldBuffer = ms_pStreamingBuffer[0]; + + // Suspend streaming thread when idle to safely swap buffers + // Uses suspend-then-verify to avoid race between checking bInUse and suspending + constexpr int kMaxRetries = 10000; + for (int attempt = 0;; ++attempt) + { + if (attempt >= kMaxRetries) + { + ((DeallocFunc)(0x72F4F0))(pNewBuffer); + return false; + } + + if (SuspendThread(*phStreamingThread) == (DWORD)-1) + { + Sleep(1); + continue; + } + + if (!streaming[0].bInUse && !streaming[1].bInUse) + break; - // Suspend streaming thread [otherwise data might become corrupted] - SuspendThread(*phStreamingThread); + ResumeThread(*phStreamingThread); + Sleep(0); + } // Calculate new buffer pointers void* const pNewBuff0 = pNewBuffer; void* const pNewBuff1 = (void*)(reinterpret_cast(pNewBuffer) + 2048u * (numBlocks / 2)); - // Copy data from old buffer to new buffer + // Copy existing data to new buffer const auto copySizeBytes = std::min(ms_streamingHalfOfBufferSizeBlocks, numBlocks / 2) * 2048; MemCpyFast(pNewBuff0, ms_pStreamingBuffer[0], copySizeBytes); MemCpyFast(pNewBuff1, ms_pStreamingBuffer[1], copySizeBytes); - // Now, we can deallocate the old buffer safely - typedef void(__cdecl * Function_CMemoryMgr_FreeAlign)(void* pos); - ((Function_CMemoryMgr_FreeAlign)(0x72F4F0))(ms_pStreamingBuffer[0]); - - // Update the buffer size now + // Update buffer size and pointers ms_streamingHalfOfBufferSizeBlocks = numBlocks / 2; - // Update internal pointers too streaming[0].pBuffer = ms_pStreamingBuffer[0] = pNewBuff0; streaming[1].pBuffer = ms_pStreamingBuffer[1] = pNewBuff1; - // Now we can resume streaming + // Resume streaming thread before freeing old buffer ResumeThread(*phStreamingThread); + // Free old buffer after resume to avoid blocking GTA memory manager + ((DeallocFunc)(0x72F4F0))(pOldBuffer); + return true; } diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index a7a4598860a..00fe6727b3f 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -13,20 +13,20 @@ #include -#define VAR_DefaultStreamHandlersMaxCount 32 -#define VAR_DefaultMaxArchives 8 +#define VAR_DefaultStreamHandlersMaxCount 32 +#define VAR_DefaultMaxArchives 8 -#define FUNC_CStreaming__RequestModel 0x4087E0 -#define FUNC_LoadAllRequestedModels 0x40EA10 -#define FUNC_CStreaming__HasVehicleUpgradeLoaded 0x407820 -#define FUNC_CStreaming_RequestSpecialModel 0x409d10 -#define FUNC_CStreaming_LoadScene 0x40EB70 -#define FUNC_CStreaming_LoadSceneCollision 0x40ED80 +#define FUNC_CStreaming__RequestModel 0x4087E0 +#define FUNC_LoadAllRequestedModels 0x40EA10 +#define FUNC_CStreaming__HasVehicleUpgradeLoaded 0x407820 +#define FUNC_CStreaming_RequestSpecialModel 0x409d10 +#define FUNC_CStreaming_LoadScene 0x40EB70 +#define FUNC_CStreaming_LoadSceneCollision 0x40ED80 struct CArchiveInfo { char szName[40]; - BYTE bUnknow = 1; // Only in player.img is 0. Maybe, it is DWORD value + BYTE bUnknow = 1; // Only in player.img is 0. Maybe, it is DWORD value BYTE bUnused[3]; DWORD uiStreamHandleId{}; }; @@ -74,7 +74,7 @@ class CStreamingSA final : public CStreaming unsigned char AddArchive(const wchar_t* szFilePath); void RemoveArchive(unsigned char ucStreamHandler); bool SetStreamingBufferSize(uint32 uiSize); - uint32 GetStreamingBufferSize() { return ms_streamingHalfOfBufferSizeBlocks * 2048 * 2; }; // In bytes + uint32 GetStreamingBufferSize() { return ms_streamingHalfOfBufferSizeBlocks * 2048 * 2; }; // In bytes void MakeSpaceFor(std::uint32_t memoryToCleanInBytes) override; std::uint32_t GetMemoryUsed() const override; @@ -86,10 +86,10 @@ class CStreamingSA final : public CStreaming void AllocateArchive(); std::vector m_Imgs; - std::vector m_StreamHandles; - std::vector m_StreamNames; + std::vector m_StreamHandles; + std::vector m_StreamNames; static void* (&ms_pStreamingBuffer)[2]; static uint32(&ms_streamingHalfOfBufferSizeBlocks); - static CStreamingInfo (&ms_aInfoForModel)[26316]; // count: 26316 in unmodified game + static CStreamingInfo (&ms_aInfoForModel)[26316]; // count: 26316 in unmodified game }; diff --git a/Client/game_sa/CTaskManagementSystemSA.cpp b/Client/game_sa/CTaskManagementSystemSA.cpp index 4707c1ab179..8fe3abb3bb6 100644 --- a/Client/game_sa/CTaskManagementSystemSA.cpp +++ b/Client/game_sa/CTaskManagementSystemSA.cpp @@ -22,6 +22,7 @@ #include "TaskPhysicalResponseSA.h" #include "TaskSA.h" #include "TaskSecondarySA.h" +#include "TaskSimpleSwimSA.h" extern CGameSA* pGame; @@ -29,8 +30,6 @@ using namespace std; void HOOK_CTask_Operator_Delete(); -CTaskSAInterface* pTempTaskInterface = 0; - CTaskManagementSystemSA::CTaskManagementSystemSA() { // Install our hook used to delete our tasks when GTA does @@ -103,8 +102,21 @@ void CTaskManagementSystemSA::RemoveTask(CTaskSAInterface* pTaskInterface) CTaskSA* CTaskManagementSystemSA::GetTask(CTaskSAInterface* pTaskInterface) { // Return NULL if we got passed NULL - if (pTaskInterface == 0) - return NULL; + if (!pTaskInterface) + return nullptr; + + // Check vtable pointer to prevent crash from corrupted task objects + TaskVTBL* pVTBL = pTaskInterface->VTBL; + if (!pVTBL) + return nullptr; + + // Vtable should be in executable memory range (.text/.rdata sections) + // GTA SA base is around 0x400000-0x900000 range + constexpr DWORD GTA_BASE_MIN = 0x400000; + constexpr DWORD GTA_BASE_MAX = 0x900000; + DWORD dwVTableAddr = reinterpret_cast(pVTBL); + if (dwVTableAddr < GTA_BASE_MIN || dwVTableAddr > GTA_BASE_MAX) + return nullptr; // Find it in our list STaskListItem* pListItem; @@ -123,15 +135,13 @@ CTaskSA* CTaskManagementSystemSA::GetTask(CTaskSAInterface* pTaskInterface) // its not existed before, lets create the task // First, we create a temp task int iTaskType = 9999; - DWORD dwFunc = pTaskInterface->VTBL->GetTaskType; + DWORD dwFunc = pVTBL->GetTaskType; if (dwFunc && dwFunc != 0x82263A) { - _asm - { - mov ecx, pTaskInterface - call dwFunc - mov iTaskType, eax - } + // clang-format off + using func_t = decltype(iTaskType) (__thiscall*)(decltype(pTaskInterface) ); +iTaskType = reinterpret_cast(dwFunc)(pTaskInterface); + // clang-format on } // Create it and add it to our list @@ -183,6 +193,9 @@ CTaskSA* CTaskManagementSystemSA::CreateAppropriateTask(CTaskSAInterface* pTaskI case TASK_COMPLEX_SUNBATHE: pTaskSA = new CTaskComplexSunbatheSA; break; + case TASK_SIMPLE_SWIM: + pTaskSA = new CTaskSimpleSwimSA; + break; // Car accessories case TASK_SIMPLE_CAR_SET_PED_IN_AS_PASSENGER: @@ -257,26 +270,22 @@ CTaskSA* CTaskManagementSystemSA::CreateAppropriateTask(CTaskSAInterface* pTaskI } // HOOKS -__declspec(noinline) void OnMY_Task_Operator_Delete(CTaskSAInterface* pTaskInterface) +static void OnMY_Task_Operator_Delete(CTaskSAInterface* pTaskInterface) { - pGame->GetTaskManagementSystem()->RemoveTask(pTempTaskInterface); + pGame->GetTaskManagementSystem()->RemoveTask(pTaskInterface); } -void _declspec(naked) HOOK_CTask_Operator_Delete() +static void __declspec(naked) HOOK_CTask_Operator_Delete() { - _asm - { - mov eax, [esp+4] - mov pTempTaskInterface, eax + MTA_VERIFY_HOOK_LOCAL_SIZE; - pushad - } - - OnMY_Task_Operator_Delete(pTempTaskInterface); - - // Continue on our merry way.... - _asm + // clang-format off + __asm { + pushad + push [esp + 32 + 4] + call OnMY_Task_Operator_Delete + add esp, 4 popad mov eax, 0xB744A8 @@ -285,4 +294,5 @@ void _declspec(naked) HOOK_CTask_Operator_Delete() add eax, 6 jmp eax } + // clang-format on } diff --git a/Client/game_sa/CTaskManagementSystemSA.h b/Client/game_sa/CTaskManagementSystemSA.h index 98894375c42..d0777bd975a 100644 --- a/Client/game_sa/CTaskManagementSystemSA.h +++ b/Client/game_sa/CTaskManagementSystemSA.h @@ -14,7 +14,7 @@ class CTaskSA; class CTaskSAInterface; -#define FUNC_CTask_Operator_Delete 0x61A5B0 +#define FUNC_CTask_Operator_Delete 0x61A5B0 class CTaskManagementSystemSA { diff --git a/Client/game_sa/CTaskManagerSA.cpp b/Client/game_sa/CTaskManagerSA.cpp index afb0026a9b9..6aca049f343 100644 --- a/Client/game_sa/CTaskManagerSA.cpp +++ b/Client/game_sa/CTaskManagerSA.cpp @@ -26,7 +26,7 @@ CTaskManagerSA::CTaskManagerSA(CTaskManagerSAInterface* taskManagerInterface, CP void CTaskManagerSA::RemoveTask(const int iTaskPriority) { - if (iTaskPriority != TASK_PRIORITY_DEFAULT) // TASK_PRIORITY_DEFAULT removed = crash + if (iTaskPriority != TASK_PRIORITY_DEFAULT) // TASK_PRIORITY_DEFAULT removed = crash { SetTask(NULL, iTaskPriority); } @@ -40,7 +40,8 @@ void CTaskManagerSA::SetTask(CTaskSA* pTaskPrimary, const int iTaskPriority, con taskInterface = pTaskPrimary->GetInterface(); DWORD dwInterface = (DWORD)GetInterface(); - _asm + // clang-format off + __asm { xor eax, eax movzx eax, bForceNewTask @@ -50,6 +51,7 @@ void CTaskManagerSA::SetTask(CTaskSA* pTaskPrimary, const int iTaskPriority, con mov ecx, dwInterface call dwFunc } + // clang-format on } CTask* CTaskManagerSA::GetTask(const int iTaskPriority) @@ -63,19 +65,18 @@ CTask* CTaskManagerSA::GetActiveTask() DWORD dwFunc = FUNC_GetActiveTask; DWORD dwReturn = 0; DWORD dwThis = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThis - call dwFunc - mov dwReturn, eax - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(dwThis) ); +dwReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on CTaskSAInterface* pActiveTask = (CTaskSAInterface*)dwReturn; - if (dwReturn) + if (dwReturn) { return m_pTaskManagementSystem->GetTask((CTaskSAInterface*)dwReturn); - else + } else { return NULL; } +} CTask* CTaskManagerSA::GetSimplestActiveTask() { @@ -83,12 +84,10 @@ CTask* CTaskManagerSA::GetSimplestActiveTask() DWORD dwReturn = 0; DWORD dwThis = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThis - call dwFunc - mov dwReturn, eax - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(dwThis) ); +dwReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on if (dwReturn) return m_pTaskManagementSystem->GetTask((CTaskSAInterface*)dwReturn); else return NULL; @@ -99,13 +98,10 @@ CTask* CTaskManagerSA::GetSimplestTask(const int iPriority) DWORD dwFunc = FUNC_GetSimplestTask; DWORD dwReturn = 0; DWORD dwThis = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThis - push iPriority - call dwFunc - mov dwReturn, eax - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(dwThis), decltype(iPriority)); +dwReturn = reinterpret_cast(dwFunc)(dwThis, iPriority); + // clang-format on if (dwReturn) return m_pTaskManagementSystem->GetTask((CTaskSAInterface*)dwReturn); else return NULL; @@ -116,13 +112,10 @@ CTask* CTaskManagerSA::FindActiveTaskByType(const int iTaskType) DWORD dwFunc = FUNC_FindActiveTaskByType; DWORD dwReturn = 0; DWORD dwThis = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThis - push iTaskType - call dwFunc - mov dwReturn, eax - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(dwThis), decltype(iTaskType)); +dwReturn = reinterpret_cast(dwFunc)(dwThis, iTaskType); + // clang-format on if (dwReturn) return m_pTaskManagementSystem->GetTask((CTaskSAInterface*)dwReturn); else return NULL; @@ -133,14 +126,10 @@ CTask* CTaskManagerSA::FindTaskByType(const int iPriority, const int iTaskType) DWORD dwFunc = FUNC_FindTaskByType; DWORD dwReturn = 0; DWORD dwThis = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThis - push iTaskType - push iPriority - call dwFunc - mov dwReturn, eax - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(dwThis), decltype(iPriority), decltype(iTaskType)); +dwReturn = reinterpret_cast(dwFunc)(dwThis, iPriority, iTaskType); + // clang-format on if (dwReturn) return m_pTaskManagementSystem->GetTask((CTaskSAInterface*)dwReturn); else return NULL; @@ -170,13 +159,10 @@ void CTaskManagerSA::SetTaskSecondary(CTaskSA* pTaskSecondary, const int iType) if (pTaskSecondary) taskInterface = pTaskSecondary->GetInterface(); DWORD dwInterface = (DWORD)GetInterface(); - _asm - { - push iType - push taskInterface - mov ecx, dwInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwInterface), decltype(taskInterface), decltype(iType)); + reinterpret_cast(dwFunc)(dwInterface, taskInterface, iType); + // clang-format on } /** @@ -184,32 +170,31 @@ void CTaskManagerSA::SetTaskSecondary(CTaskSA* pTaskSecondary, const int iType) */ CTask* CTaskManagerSA::GetTaskSecondary(const int iType) { - if (iType < TASK_SECONDARY_MAX) + if (iType < TASK_SECONDARY_MAX) { return m_pTaskManagementSystem->GetTask(GetInterface()->m_tasksSecondary[iType]); - else + } else { return NULL; } +} bool CTaskManagerSA::HasTaskSecondary(const CTask* pTaskSecondary) { DWORD dwFunc = FUNC_HasTaskSecondary; bool bReturn = false; - _asm - { - push pTaskSecondary - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(pTaskSecondary)); +bReturn = reinterpret_cast(dwFunc)(pTaskSecondary); + // clang-format on return bReturn; } void CTaskManagerSA::ClearTaskEventResponse() { DWORD dwFunc = FUNC_ClearTaskEventResponse; - _asm - { - call dwFunc - } + // clang-format off + using func_t = void (__cdecl*)(); + reinterpret_cast(dwFunc)(); + // clang-format on } void CTaskManagerSA::Flush(const int iPriority) diff --git a/Client/game_sa/CTaskManagerSA.h b/Client/game_sa/CTaskManagerSA.h index 897e7ef7663..c22d99bac36 100644 --- a/Client/game_sa/CTaskManagerSA.h +++ b/Client/game_sa/CTaskManagerSA.h @@ -17,15 +17,15 @@ class CTaskSAInterface; class CTaskManagementSystemSA; class CTaskSA; -#define FUNC_SetTask 0x681AF0 -#define FUNC_GetActiveTask 0x681720 -#define FUNC_GetSimplestActiveTask 0x6819D0 -#define FUNC_GetSimplestTask 0x681A00 -#define FUNC_FindActiveTaskByType 0x681740 -#define FUNC_FindTaskByType 0x6817D0 -#define FUNC_SetTaskSecondary 0x681B60 -#define FUNC_ClearTaskEventResponse 0x681BD0 -#define FUNC_HasTaskSecondary 0x681820 +#define FUNC_SetTask 0x681AF0 +#define FUNC_GetActiveTask 0x681720 +#define FUNC_GetSimplestActiveTask 0x6819D0 +#define FUNC_GetSimplestTask 0x681A00 +#define FUNC_FindActiveTaskByType 0x681740 +#define FUNC_FindTaskByType 0x6817D0 +#define FUNC_SetTaskSecondary 0x681B60 +#define FUNC_ClearTaskEventResponse 0x681BD0 +#define FUNC_HasTaskSecondary 0x681820 // pointer for this at +1148+4? (see 0x568A20) class CTaskManagerSAInterface @@ -59,8 +59,8 @@ class CTaskManagerSA : public CTaskManager void RemoveTaskSecondary(const int iTaskPriority); bool RemoveTaskSecondary(const int taskPriority, const int taskType); void SetTaskSecondary(CTaskSA* pTaskSecondary, const int iType); - CTask* GetTaskSecondary(const int iType); // code it - bool HasTaskSecondary(const CTask* pTaskSecondary); // code it + CTask* GetTaskSecondary(const int iType); // code it + bool HasTaskSecondary(const CTask* pTaskSecondary); // code it void ClearTaskEventResponse(); void Flush(const int iPriority); }; diff --git a/Client/game_sa/CTasksSA.cpp b/Client/game_sa/CTasksSA.cpp index 9c080e58357..301f80b2e05 100644 --- a/Client/game_sa/CTasksSA.cpp +++ b/Client/game_sa/CTasksSA.cpp @@ -124,8 +124,8 @@ CTaskSimpleChoking* CTasksSA::CreateTaskSimpleChoking(CPed* pAttacker, bool bIsT return pTask; } -CTaskSimpleClimb* CTasksSA::CreateTaskSimpleClimb(CEntity* pClimbEnt, const CVector& vecTarget, float fHeading, unsigned char nSurfaceType, char nHeight, - const bool bForceClimb) +CTaskSimpleClimb* CTasksSA::CreateTaskSimpleClimb(CEntitySAInterface* pClimbEnt, const CVector& vecTarget, float fHeading, unsigned char nSurfaceType, + eClimbHeights nHeight, const bool bForceClimb) { CTaskSimpleClimbSA* pTask = NewTask(pClimbEnt, vecTarget, fHeading, nSurfaceType, nHeight, bForceClimb); m_pTaskManagementSystem->AddTask(pTask); @@ -160,6 +160,13 @@ CTaskSimpleRunNamedAnim* CTasksSA::CreateTaskSimpleRunNamedAnim(const char* pAni return pTask; } +CTaskComplexInWater* CTasksSA::CreateTaskComplexInWater() +{ + CTaskComplexInWaterSA* task = NewTask(); + m_pTaskManagementSystem->AddTask(task); + return task; +} + CTaskComplexDie* CTasksSA::CreateTaskComplexDie(const eWeaponType eMeansOfDeath, const AssocGroupId animGroup, const AnimationId anim, const float fBlendDelta, const float fAnimSpeed, const bool bBeingKilledByStealth, const bool bFallingToDeath, const int iFallToDeathDir, const bool bFallToDeathOverRailing) @@ -271,13 +278,16 @@ __declspec(noinline) void _cdecl OnCEventHandler_ComputeDamageResponse_Mid(CPedS } // Hook info -#define HOOKPOS_CEventHandler_ComputeDamageResponse_Mid 0x4C0593 -#define HOOKSIZE_CEventHandler_ComputeDamageResponse_Mid 5 -DWORD RETURN_CEventHandler_ComputeDamageResponse_Mid = 0x4C0598; -DWORD CTaskSimpleBeHit_constructor = FUNC_CTaskSimpleBeHit__Constructor; -void _declspec(naked) HOOK_CEventHandler_ComputeDamageResponse_Mid() +#define HOOKPOS_CEventHandler_ComputeDamageResponse_Mid 0x4C0593 +#define HOOKSIZE_CEventHandler_ComputeDamageResponse_Mid 5 +DWORD RETURN_CEventHandler_ComputeDamageResponse_Mid = 0x4C0598; +DWORD CTaskSimpleBeHit_constructor = FUNC_CTaskSimpleBeHit__Constructor; +static void __declspec(naked) HOOK_CEventHandler_ComputeDamageResponse_Mid() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*3] @@ -293,6 +303,7 @@ void _declspec(naked) HOOK_CEventHandler_ComputeDamageResponse_Mid() call CTaskSimpleBeHit_constructor jmp RETURN_CEventHandler_ComputeDamageResponse_Mid } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/game_sa/CTasksSA.h b/Client/game_sa/CTasksSA.h index 56a614f8c6b..65c0fd65dcf 100644 --- a/Client/game_sa/CTasksSA.h +++ b/Client/game_sa/CTasksSA.h @@ -42,6 +42,7 @@ class CTaskSimpleRunNamedAnim; class CTaskSimpleStealthKill; class CTaskSimpleTriggerLookAt; class CTaskSimpleUseGun; +class CTaskComplexInWater; class CTasksSA : public CTasks { @@ -70,8 +71,8 @@ class CTasksSA : public CTasks CTaskSimpleDuck* CreateTaskSimpleDuck(eDuckControlTypes nDuckControl, unsigned short nLengthOfDuck = 0, unsigned short nUseShotsWhizzingEvents = -1); CTaskSimpleChoking* CreateTaskSimpleChoking(CPed* pAttacker, bool bIsTearGas); - CTaskSimpleClimb* CreateTaskSimpleClimb(CEntity* pClimbEnt, const CVector& vecTarget, float fHeading, unsigned char nSurfaceType, char nHeight = CLIMB_GRAB, - const bool bForceClimb = false); + CTaskSimpleClimb* CreateTaskSimpleClimb(CEntitySAInterface* pClimbEnt, const CVector& vecTarget, float fHeading, unsigned char nSurfaceType, + eClimbHeights nHeight = CLIMB_GRAB, const bool bForceClimb = false); CTaskSimpleJetPack* CreateTaskSimpleJetpack(const CVector* pVecTargetPos = NULL, float fCruiseHeight = 10.0f, int nHoverTime = 0); CTaskSimpleRunAnim* CreateTaskSimpleRunAnim(const AssocGroupId animGroup, const AnimationId animID, const float fBlendDelta, const int iTaskType, @@ -80,6 +81,8 @@ class CTasksSA : public CTasks const int iTime = -1, const bool bDontInterrupt = false, const bool bRunInSequence = false, const bool bOffsetPed = false, const bool bHoldLastFrame = false); + CTaskComplexInWater* CreateTaskComplexInWater(); + CTaskComplexDie* CreateTaskComplexDie(const eWeaponType eMeansOfDeath = WEAPONTYPE_UNARMED, const AssocGroupId animGroup = 0 /*ANIM_STD_PED*/, const AnimationId anim = 0 /*ANIM_STD_KO_FRONT*/, const float fBlendDelta = 4.0f, const float fAnimSpeed = 0.0f, const bool bBeingKilledByStealth = false, const bool bFallingToDeath = false, const int iFallToDeathDir = 0, diff --git a/Client/game_sa/CTrainSA.h b/Client/game_sa/CTrainSA.h index daa367b2cf6..202cb8ce937 100644 --- a/Client/game_sa/CTrainSA.h +++ b/Client/game_sa/CTrainSA.h @@ -55,19 +55,19 @@ class CTrainSAInterface : public CVehicleSAInterface char _pad1[2]; public: - float m_fTrainSpeed; // 1.0 - train derails - float m_fTrainRailDistance; // Distance along rail starting from first rail node (determines train position when on rails) + float m_fTrainSpeed; // 1.0 - train derails + float m_fTrainRailDistance; // Distance along rail starting from first rail node (determines train position when on rails) float m_fDistanceToNextCarriage; - float m_fTrainGas; // gas pedal pressed: 255.0, moving forward: 0.0, moving back: -255.0 - float m_fTrainBrake; // 255.0 - braking + float m_fTrainGas; // gas pedal pressed: 255.0, moving forward: 0.0, moving back: -255.0 + float m_fTrainBrake; // 255.0 - braking union { struct { - unsigned short b01 : 1; // initialised with 1 - unsigned short bStoppedAtStation : 1; // Only the first created train on the chain gets this set to true, others get it set to false. + unsigned short b01 : 1; // initialised with 1 + unsigned short bStoppedAtStation : 1; // Only the first created train on the chain gets this set to true, others get it set to false. unsigned short bPassengersCanEnterAndLeave : 1; - unsigned short bIsTheChainEngine : 1; // front carriage + unsigned short bIsTheChainEngine : 1; // front carriage unsigned short bIsLastCarriage : 1; unsigned short bMissionTrain : 1; unsigned short bClockwiseDirection : 1; @@ -91,11 +91,11 @@ class CTrainSAInterface : public CVehicleSAInterface public: int m_nTimeWhenCreated; - short field_5C8; // initialized with 0, not referenced + short field_5C8; // initialized with 0, not referenced eTrainPassengersGenerationState m_nPassengersGenerationState; - unsigned char m_nNumPassengersToLeave : 4; // 0 to 4 - unsigned char m_nNumPassengersToEnter : 4; // 0 to 4 - CPedSAInterface* m_pTemporaryPassenger; // we tell peds to enter train and then delete them + unsigned char m_nNumPassengersToLeave : 4; // 0 to 4 + unsigned char m_nNumPassengersToEnter : 4; // 0 to 4 + CPedSAInterface* m_pTemporaryPassenger; // we tell peds to enter train and then delete them CTrainSAInterface* m_prevCarriage; CTrainSAInterface* m_nextCarriage; CDoorSAInterface m_aDoors[MAX_DOORS]; diff --git a/Client/game_sa/CTxdPoolSA.cpp b/Client/game_sa/CTxdPoolSA.cpp index 248f8258366..fa51c76fb92 100644 --- a/Client/game_sa/CTxdPoolSA.cpp +++ b/Client/game_sa/CTxdPoolSA.cpp @@ -11,12 +11,352 @@ #include "CTxdPoolSA.h" #include "CGameSA.h" #include "CKeyGenSA.h" +#include "CModelInfoSA.h" +#include "CStreamingSA.h" +#include "MemSA.h" +#include +#include +#include + +// Slots in this set are shielded from SA's streaming eviction. +// Hook_CTxdStore_RemoveRef will NOT call CStreaming::RemoveModel when a +// protected slot's ref count drops to zero, allowing MTA to orphan textures +// from the RwTexDictionary before it is destroyed. +static std::unordered_set g_StreamingProtectedTxdSlots; + +#define VAR_CTxdStore_ms_pTxdPool 0xC8800C +#define FUNC_CTxdStore__RemoveRef 0x731A30 +#define FUNC_CTxdStore__SetTxdParent 0x7316E0 +#define FUNC_CStreaming__requestTxd 0x407100 +#define FUNC_CTxdStore__RemoveSlot 0x731E90 + +// CMemoryMgr::MallocAlign / FreeAlign wrappers (hooked by MTA in +// CMultiplayerSA_FixMallocAlign.cpp > SafeMallocAlign / SafeFreeAlign). +// SafeMallocAlign uses MTA's CRT malloc with alignment metadata at ptr-4/ptr-8. +// SafeFreeAlign validates the metadata magic before freeing; if the magic is +// absent (e.g. memory from SA's CRT), it silently returns without freeing. +// +// We use these for Resize()'s replacement pool arrays. SA's original CPool +// constructor allocates via operator new (SA's static CRT), but MTA's hooked +// allocator provides controlled lifetime and avoids cross-CRT issues. +namespace CMemoryMgr +{ + inline void* MallocAlign(int size, int alignment = 4, int hint = 0) + { + using fn_t = void*(__cdecl*)(int, int, int); + return reinterpret_cast(0x72F4C0)(size, alignment, hint); + } + + inline void FreeAlign(void* ptr) + { + using fn_t = void(__cdecl*)(void*); + reinterpret_cast(0x72F4F0)(ptr); + } +} + +// GetNextFileOnCd TXD dependency check hook: +// At 0x408ECE, SA reads the TXD streaming entry loadState for DFF dependency: +// movzx edx, byte ptr [edx*4+0x946750] ; 8 bytes: 0F B6 14 95 50 67 94 00 +// For overflow TXD slots (txdIndex >= 5000), this reads COL/IPL streaming +// entries instead. For overflow slots, always report LOADED so SA never +// calls CStreaming::RequestModel with an out-of-range streaming ID. +#define HOOKPOS_GetNextFileOnCd_TxdCheck 0x408ECE +#define HOOKSIZE_GetNextFileOnCd_TxdCheck 8 +static const DWORD RETURN_GetNextFileOnCd_TxdCheck = 0x408ED6; + +// RequestModelStream TXD dependency check hook: +// At 0x40CD9F, SA reads the TXD streaming entry loadState before packing a +// DFF into a streaming request: +// mov al, byte ptr [ecx*4+0x8E4CD0] ; 7 bytes: 8A 04 8D D0 4C 8E 00 +// Same overflow problem as GetNextFileOnCd. For overflow TXD slots, always +// report LOADED so the DFF is not indefinitely deferred. +#define HOOKPOS_RequestModelStream_TxdCheck 0x40CD9F +#define HOOKSIZE_RequestModelStream_TxdCheck 7 +static const DWORD RETURN_RequestModelStream_TxdCheck = 0x40CDA6; + +// SetMissionDoesntRequireModel TXD cleanup hook: +// Prevents overlap/overflow TXD indices from being turned into out-of-bounds stream IDs. +#define HOOKPOS_SetMissionDoesntRequireModel_TxdCheck 0x409CFC +#define HOOKSIZE_SetMissionDoesntRequireModel_TxdCheck 10 +static const DWORD RETURN_SetMissionDoesntRequireModel_TxdCheck = 0x409CA0; + +// SetModelTxdIsDeletable hook: +// Prevents overlap/overflow TXD indices from being sent to SetModelIsDeletable. +#define HOOKPOS_SetModelTxdIsDeletable_TxdCheck 0x409C7B +#define HOOKSIZE_SetModelTxdIsDeletable_TxdCheck 10 +static const DWORD RETURN_SetModelTxdIsDeletable_TxdCheck = 0x409C85; + +// RemoveTxd parent cascade hook: +// Prevents overflow parent indices from causing out-of-bounds RemoveModel calls. +#define HOOKPOS_RemoveTxd_ParentCascade 0x731ED4 +#define HOOKSIZE_RemoveTxd_ParentCascade 8 extern CGameSA* pGame; +// Hook for GetNextFileOnCd's TXD dependency check (0x408ECE). +// Replaces: movzx edx, byte ptr [edx*4+0x946750] (8 bytes) +// At entry: eax = txdIndex (from movsx eax, [ecx+0Ah]) +// edx = txdIndex*5 (from lea edx, [eax+eax*4]) +// At exit: edx = loadState byte, execution continues at 0x408ED6 (cmp edx, 1) +// +// Post-hook, SA checks: cmp edx, 1 (LOADED) > jz loc_408F01 (IFP dep check); +// cmp edx, 3 (READING) > jz loc_408F01 (same); +// otherwise > fallthrough to RequestModel(txdIndex+20000). +// For standard TXDs (txdIndex < 5000): executes the original loadState read. +// For overflow TXDs (>= 5000 or negative from movsx): always reports LOADED (1). +// This prevents SA from falling through to its direct +// push edx; add eax, 4E20h; push eax; call CStreaming::RequestModel (0x4087E0) +// call, which is NOT guarded by Hook_CStreaming_requestTxd and would use +// an out-of-range streaming ID (>= 25000), corrupting COL/IPL streaming +// entries or writing out of bounds of ms_aInfoForModel[26316]. +// Only EDX is live after return; eax and ecx are preserved (never touched +// in the overflow path). +static void __declspec(naked) HOOK_GetNextFileOnCd_TxdCheck() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + // eax = txdIndex, edx = txdIndex*5 + test eax, eax + js overflow_loaded // Negative txdIndex from movsx of >= 32768 + cmp eax, 5000 // SA_TXD_POOL_CAPACITY + jge overflow_loaded + + // Standard path: execute original instruction + movzx edx, byte ptr [edx*4+0x946750] + jmp RETURN_GetNextFileOnCd_TxdCheck + + overflow_loaded: + // MTA manages overflow TXDs outside SA's streaming system. + // Reporting LOADED is always safe: + // - Slot occupied: TXD data is present, DFF renders correctly. + // - Slot empty: DFF may get white textures (recoverable), + // vs. NOT_LOADED which triggers the unguarded + // RequestModel call above (freeze/corruption). + mov edx, 1 // LOADSTATE_LOADED + jmp RETURN_GetNextFileOnCd_TxdCheck + } + // clang-format on +} + +// Hook for RequestModelStream's TXD dependency check (0x40CD9F). +// Replaces: mov al, byte ptr [ecx*4+0x8E4CD0] (7 bytes) +// At entry: eax = txdIndex+20000 (from movsx + add), ecx = (txdIndex+20000)*5 +// At exit: al = loadState byte, execution continues at 0x40CDA6 (cmp al, 1) +// +// Post-hook, SA checks: cmp al, 1 (LOADED) > jz proceed; +// cmp al, 3 (READING) > jz proceed; +// otherwise > jnz loc_40CEF8 (defer DFF). +// For standard TXDs (streaming ID < 25000): executes the original loadState read. +// For overflow TXDs (streaming ID >= 25000): always reports LOADED (1). +// Returning NOT_LOADED would prevent the DFF from ever being packed into +// a streaming request when its overflow TXD is managed by MTA. +// Only AL is live after return; ecx, edx, and eax upper bytes are dead. +static void __declspec(naked) HOOK_RequestModelStream_TxdCheck() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + // eax = txdIndex+20000, ecx = (txdIndex+20000)*5 + cmp eax, 25000 // 20000 + SA_TXD_POOL_CAPACITY + jge overflow_loaded + + // Standard path: execute original instruction + mov al, byte ptr [ecx*4+0x8E4CD0] + jmp RETURN_RequestModelStream_TxdCheck + + overflow_loaded: + mov al, 1 // LOADSTATE_LOADED + jmp RETURN_RequestModelStream_TxdCheck + } + // clang-format on +} + +// Hook for SetMissionDoesntRequireModel TXD check (0x409CFC) +// Replaces: movsx esi, word ptr [ecx+0Ah] +// add esi, 4E20h +// For overflow TXD slots, skipping the conversion prevents out of bounds +// RemoveModel calls for streaming IDs >= 25000. +static void __declspec(naked) HOOK_SetMissionDoesntRequireModel_TxdCheck() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + movsx esi, word ptr [ecx+0Ah] + + test esi, esi + js skip_txd + cmp esi, 5000 // SA_TXD_POOL_CAPACITY + jge skip_txd + + add esi, 20000 // 4E20h + jmp RETURN_SetMissionDoesntRequireModel_TxdCheck // 0x409CA0 + + skip_txd: + // Original loop tail exit from 0x409D08 + pop esi + retn + } + // clang-format on +} + +// Hook for SetModelTxdIsDeletable TXD check (0x409C7B) +// Replaces: movsx edx, word ptr [ecx+0Ah] +// add edx, 4E20h +// Same principle as SetMissionDoesntRequireModel. +static void __declspec(naked) HOOK_SetModelTxdIsDeletable_TxdCheck() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + movsx edx, word ptr [ecx+0Ah] + + test edx, edx + js skip_txd + cmp edx, 5000 // SA_TXD_POOL_CAPACITY + jge skip_txd + + add edx, 20000 // 4E20h + jmp RETURN_SetModelTxdIsDeletable_TxdCheck // 0x409C85 + + skip_txd: + // SetModelTxdIsDeletable is a void __cdecl function that does a tail JMP. + // We simply return, caller removes args. + retn + } + // clang-format on +} + +// Shared refcount-decrement path used by both the RemoveTxd parent +// cascade hook and the RemoveRef replacement. +static void __cdecl ProcessTxdRemoveRef(CPoolSAInterface* pool, int index) +{ + if (!pool) + return; + + if (index < 0 || index >= pool->m_nSize) + return; + + if (pool->m_byteMap[index].bEmpty) + return; + + auto* pEntry = &pool->m_pObjects[index]; + --pEntry->usUsagesCount; + + if (static_cast(pEntry->usUsagesCount) <= 0) + { + if (index < CTxdPoolSA::SA_TXD_POOL_CAPACITY && g_StreamingProtectedTxdSlots.count(static_cast(index)) == 0) + { + using RemoveModel_t = void(__cdecl*)(int); + reinterpret_cast(FUNC_RemoveModel)(index + pGame->GetBaseIDforTXD()); + } + } +} + +// Hook for CTxdStore::RemoveTxd parent cascade block (0x731ED4) +// Replaces: mov ax, [esi+6] +// cmp ax, 0FFFFh +static void __declspec(naked) HOOK_RemoveTxd_ParentCascade() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + movsx eax, word ptr [esi+6] // parentIndex + push eax // index + push ecx // pool + call ProcessTxdRemoveRef + add esp, 8 + + skip_parent_cascade: + mov dword ptr [esi], 0 + pop esi + retn + } + // clang-format on +} + +// Replaces CTxdStore::RemoveRef (0x731A30). +// The original calls CStreaming::RemoveModel(index + 20000) when the ref count +// drops to zero. For overflow pool slots (index >= 5000) that streaming ID +// falls outside ms_aInfoForModel. Skip CStreaming for overflow slots. +static void __cdecl Hook_CTxdStore_RemoveRef(int index) +{ + auto* pool = *reinterpret_cast**>(VAR_CTxdStore_ms_pTxdPool); + ProcessTxdRemoveRef(pool, index); +} + +// Replaces CStreaming::requestTxd (0x407100). +// The original converts a TXD pool index to a stream ID (index + 20000) and +// calls CStreaming::RequestModel. For standard-range slots (< 5000) forward +// to RequestModel. For overflow slots (>= 5000) the stream ID falls in +// COL/IPL/DAT/IFP territory, so skip - the GetNextFileOnCd and +// RequestModelStream hooks always report LOADED for overflow TXDs. +static void __cdecl Hook_CStreaming_requestTxd(int txdIndex, int flags) +{ + if (txdIndex >= 0 && txdIndex < CTxdPoolSA::SA_TXD_POOL_CAPACITY) + { + using RequestModel_t = void(__cdecl*)(int, int); + reinterpret_cast(FUNC_CStreaming__RequestModel)(txdIndex + pGame->GetBaseIDforTXD(), flags); + return; + } + + // Overflow slots (>= 5000): skip. GetNextFileOnCd and RequestModelStream + // hooks always report LOADED for overflow TXDs, so SA never tries to + // stream them. +} + CTxdPoolSA::CTxdPoolSA() { - m_ppTxdPoolInterface = (CPoolSAInterface**)0xC8800C; + m_ppTxdPoolInterface = (CPoolSAInterface**)VAR_CTxdStore_ms_pTxdPool; + InstallPoolHooks(); + + // Pool expansion deferred to InitialisePool() - called from + // CGameSA::Initialize() after SA's CTxdStore::Initialise has + // created the pool at 0xC8800C. +} + +void CTxdPoolSA::InitialisePool() +{ + if (!m_ppTxdPoolInterface || !*m_ppTxdPoolInterface) + return; + + const int currentSize = (*m_ppTxdPoolInterface)->m_nSize; + if (currentSize >= TXD_POOL_MAX_CAPACITY) + return; + + Resize(TXD_POOL_MAX_CAPACITY); +} + +void CTxdPoolSA::InstallPoolHooks() +{ + // First two instructions = 4 + 6 = 10 bytes + HookInstall(FUNC_CTxdStore__RemoveRef, reinterpret_cast(Hook_CTxdStore_RemoveRef), 10); + + // Small 2-instruction wrapper, 5-byte overwrite + HookInstall(FUNC_CStreaming__requestTxd, reinterpret_cast(Hook_CStreaming_requestTxd), 5); + + // GetNextFileOnCd TXD loadState hook: overflow slots always report + // LOADED to prevent SA from issuing RequestModel with invalid IDs. + HookInstall(HOOKPOS_GetNextFileOnCd_TxdCheck, reinterpret_cast(HOOK_GetNextFileOnCd_TxdCheck), HOOKSIZE_GetNextFileOnCd_TxdCheck); + + // RequestModelStream TXD dependency check when packing streaming requests. + HookInstall(HOOKPOS_RequestModelStream_TxdCheck, reinterpret_cast(HOOK_RequestModelStream_TxdCheck), HOOKSIZE_RequestModelStream_TxdCheck); + + // CStreaming::SetMissionDoesntRequireModel TXD cleanup hook + HookInstall(HOOKPOS_SetMissionDoesntRequireModel_TxdCheck, reinterpret_cast(HOOK_SetMissionDoesntRequireModel_TxdCheck), + HOOKSIZE_SetMissionDoesntRequireModel_TxdCheck); + + // CStreaming::SetModelTxdIsDeletable hook + HookInstall(HOOKPOS_SetModelTxdIsDeletable_TxdCheck, reinterpret_cast(HOOK_SetModelTxdIsDeletable_TxdCheck), + HOOKSIZE_SetModelTxdIsDeletable_TxdCheck); + + // CTxdStore::RemoveTxd parent cascade hook + HookInstall(HOOKPOS_RemoveTxd_ParentCascade, reinterpret_cast(HOOK_RemoveTxd_ParentCascade), HOOKSIZE_RemoveTxd_ParentCascade); } std::uint32_t CTxdPoolSA::AllocateTextureDictonarySlot(std::uint32_t uiSlotId, std::string& strTxdName) @@ -40,18 +380,355 @@ void CTxdPoolSA::RemoveTextureDictonarySlot(std::uint32_t uiTxdId) if (!(*m_ppTxdPoolInterface)->IsContains(uiTxdId)) return; - typedef std::uint32_t(__cdecl * Function_TxdReleaseSlot)(std::uint32_t uiTxdId); - ((Function_TxdReleaseSlot)(0x731E90))(uiTxdId); + // Clear streaming protection so any future re-use of this pool index + // starts unprotected. Must happen before RemoveTxd in case RemoveTxd's + // parent cascade triggers Hook_CTxdStore_RemoveRef on related slots. + g_StreamingProtectedTxdSlots.erase(static_cast(uiTxdId)); + + const DWORD dwStreamingId = uiTxdId + pGame->GetBaseIDforTXD(); + + // Standard-range TXD slots tracked by SA's streaming system must be + // removed via CStreaming::RemoveModel before the pool slot is freed. + // RemoveModel properly unlinks from the loaded doubly-linked list, + // sets loadState to NOT_LOADED, and calls RemoveTxd internally. + // Without this, the stale entry stays in the loaded list and causes + // a crash when RemoveLeastUsedModel later tries to access the freed slot. + if (uiTxdId < SA_TXD_POOL_CAPACITY && pGame->GetStreaming()) + { + CStreamingInfo* pStreamInfo = pGame->GetStreaming()->GetStreamingInfo(dwStreamingId); + if (pStreamInfo && pStreamInfo->loadState != eModelLoadState::LOADSTATE_NOT_LOADED) + { + pGame->GetStreaming()->RemoveModel(dwStreamingId); + + // RemoveTxd (called by RemoveModel) doesn't clear parentIndex. + // The direct RemoveTxd call below would re-process the parent + // chain, double-decrementing the parent's usUsagesCount. + CTextureDictonarySAInterface* pEntry = (*m_ppTxdPoolInterface)->GetObject(uiTxdId); + if (pEntry) + pEntry->usParentIndex = static_cast(-1); + } + } + + // Call RemoveTxd for dictionary cleanup. When RemoveModel already ran + // above, dictionary is NULL and parentIndex is -1, making this a no-op. + // For overflow slots or non-loaded standard slots, this performs the + // actual dictionary destruction and parent ref cascade. + // ShaderSupport hooks 0x731E90 and reads ESI as the streaming ID + // (pool index + 20000) for texture/shader tracking. + const DWORD dwFuncAddr = FUNC_CTxdStore__RemoveSlot; + // clang-format off + __asm + { + mov esi, dwStreamingId + push uiTxdId + call dwFuncAddr + add esp, 4 + } + // clang-format on + + // Clear stale parent references: any alive slot whose usParentIndex + // points to the slot being freed must be reset to 0xFFFF so SA's + // getTexDictionary doesnt read a free pool entry and crash. + // Also null the child's RW parent pointer so texture lookups + // don't follow a freed dictionary. + { + using SetTxdParent_t = void(__cdecl*)(RwTexDictionary*, RwTexDictionary*); + + auto* pool = *m_ppTxdPoolInterface; + const unsigned short parentVal = static_cast(uiTxdId); + for (int i = 0; i < pool->m_nSize; ++i) + { + if (!pool->m_byteMap[i].bEmpty && pool->m_pObjects[i].usParentIndex == parentVal) + { + pool->m_pObjects[i].usParentIndex = static_cast(-1); + + if (pool->m_pObjects[i].rwTexDictonary) + { + reinterpret_cast(FUNC_CTxdStore__SetTxdParent)(pool->m_pObjects[i].rwTexDictonary, nullptr); + } + } + } + } (*m_ppTxdPoolInterface)->Release(uiTxdId); + + // Lower the free-slot hints so the next search starts here + if (uiTxdId < m_uiFreeSlotHint) + m_uiFreeSlotHint = uiTxdId; + if (uiTxdId >= static_cast(MAX_STREAMING_TXD_SLOT) && uiTxdId < m_uiFreeSlotHintAbove) + m_uiFreeSlotHintAbove = uiTxdId; } bool CTxdPoolSA::IsFreeTextureDictonarySlot(std::uint32_t uiTxdId) { - return (*m_ppTxdPoolInterface)->IsEmpty(uiTxdId); + if (!m_ppTxdPoolInterface || !(*m_ppTxdPoolInterface)) + return false; + + // IsContains is bounds-checked; returns false for out-of-range indices. + return !(*m_ppTxdPoolInterface)->IsContains(static_cast(uiTxdId)); } -std::uint16_t CTxdPoolSA::GetFreeTextureDictonarySlot() +bool CTxdPoolSA::IsTxdLoaded(std::uint32_t uiTxdId) { + auto* pSlot = GetTextureDictonarySlot(uiTxdId); + return pSlot && pSlot->rwTexDictonary != nullptr; +} + +std::uint32_t CTxdPoolSA::GetFreeTextureDictonarySlot() +{ + if (!m_ppTxdPoolInterface || !(*m_ppTxdPoolInterface)) + return static_cast(-1); + return (*m_ppTxdPoolInterface)->GetFreeSlot(); } + +std::uint32_t CTxdPoolSA::GetFreeTextureDictonarySlotInRange(std::uint32_t maxExclusive) +{ + if (!m_ppTxdPoolInterface || !(*m_ppTxdPoolInterface)) + return static_cast(-1); + + auto* pool = *m_ppTxdPoolInterface; + if (!pool->m_byteMap || pool->m_nSize <= 0) + return static_cast(-1); + + const std::uint32_t limit = std::min(maxExclusive, static_cast(pool->m_nSize)); + + // Start from the hint to skip known-occupied lower slots + std::uint32_t start = (m_uiFreeSlotHint < limit) ? m_uiFreeSlotHint : 0; + for (std::uint32_t i = start; i < limit; ++i) + { + if (pool->m_byteMap[i].bEmpty) + { + m_uiFreeSlotHint = i + 1; + return i; + } + } + + // Hint was stale; scan the range below the hint + for (std::uint32_t i = 0; i < start; ++i) + { + if (pool->m_byteMap[i].bEmpty) + { + m_uiFreeSlotHint = i + 1; + return i; + } + } + + return static_cast(-1); +} + +std::uint32_t CTxdPoolSA::GetFreeTextureDictonarySlotAbove(std::uint32_t minInclusive) +{ + if (!m_ppTxdPoolInterface || !(*m_ppTxdPoolInterface)) + return static_cast(-1); + + auto* pool = *m_ppTxdPoolInterface; + + if (!pool->m_byteMap || pool->m_nSize <= static_cast(minInclusive)) + return static_cast(-1); + + const std::uint32_t poolSize = static_cast(pool->m_nSize); + + // Start from the hint to skip known-occupied lower slots + std::uint32_t start = (m_uiFreeSlotHintAbove >= minInclusive && m_uiFreeSlotHintAbove < poolSize) ? m_uiFreeSlotHintAbove : minInclusive; + for (std::uint32_t i = start; i < poolSize; ++i) + { + if (pool->m_byteMap[i].bEmpty) + { + m_uiFreeSlotHintAbove = i + 1; + return i; + } + } + + // Hint was stale; scan the range below the hint + for (std::uint32_t i = minInclusive; i < start; ++i) + { + if (pool->m_byteMap[i].bEmpty) + { + m_uiFreeSlotHintAbove = i + 1; + return i; + } + } + + return static_cast(-1); +} + +int CTxdPoolSA::GetUsedSlotCountInRange(std::uint32_t maxExclusive) const +{ + if (!m_ppTxdPoolInterface || !(*m_ppTxdPoolInterface)) + return -1; + + auto* pool = *m_ppTxdPoolInterface; + if (!pool->m_byteMap || pool->m_nSize <= 0) + return -1; + + const std::uint32_t limit = std::min(maxExclusive, static_cast(pool->m_nSize)); + int count = 0; + for (std::uint32_t i = 0; i < limit; ++i) + { + if (!pool->m_byteMap[i].bEmpty) + ++count; + } + + return count; +} + +int CTxdPoolSA::GetPoolSize() const noexcept +{ + if (!m_ppTxdPoolInterface || !(*m_ppTxdPoolInterface)) + return 0; + + return (*m_ppTxdPoolInterface)->m_nSize; +} + +int CTxdPoolSA::GetUsedSlotCount() const noexcept +{ + if (!m_ppTxdPoolInterface || !(*m_ppTxdPoolInterface)) + return -1; + + CPoolSAInterface* pPool = *m_ppTxdPoolInterface; + if (!pPool->m_byteMap || pPool->m_nSize <= 0) + return -1; + + int iUsedCount = 0; + for (int i = 0; i < pPool->m_nSize; ++i) + { + if (!pPool->m_byteMap[i].bEmpty) + ++iUsedCount; + } + + return iUsedCount; +} + +CTextureDictonarySAInterface* CTxdPoolSA::GetTextureDictonarySlot(std::uint32_t uiTxdId) noexcept +{ + if (!m_ppTxdPoolInterface || !(*m_ppTxdPoolInterface)) + return nullptr; + + if (!(*m_ppTxdPoolInterface)->IsContains(uiTxdId)) + return nullptr; + + return (*m_ppTxdPoolInterface)->GetObject(uiTxdId); +} + +bool CTxdPoolSA::SetTextureDictonarySlot(std::uint32_t uiTxdId, RwTexDictionary* pTxd, std::uint16_t usParentIndex) noexcept +{ + if (!m_ppTxdPoolInterface || !(*m_ppTxdPoolInterface)) + return false; + + CTextureDictonarySAInterface* pSlot = GetTextureDictonarySlot(uiTxdId); + if (!pSlot) + return false; + + pSlot->rwTexDictonary = pTxd; + pSlot->usParentIndex = usParentIndex; + return true; +} + +// Resizes the TXD pool, preserving existing slot data. +// Safe to call after SA creates the pool: SA stores TXD references +// as 16-bit indices and re-reads pool->m_pObjects on every access, +// so swapping the backing arrays doesn't invalidate anything as +// long as no pool-accessing code is on the call stack. +bool CTxdPoolSA::Resize(int newCapacity) +{ + if (!m_ppTxdPoolInterface || !(*m_ppTxdPoolInterface)) + { + AddReportLog(9401, "CTxdPoolSA::Resize: Pool pointer is NULL"); + return false; + } + + auto* pool = *m_ppTxdPoolInterface; + const int oldCapacity = pool->m_nSize; + + if (newCapacity <= oldCapacity) + { + AddReportLog(9401, SString("CTxdPoolSA::Resize: newCapacity(%d) <= oldCapacity(%d)", newCapacity, oldCapacity)); + return false; + } + + // SA reads CBaseModelInfo::usTextureDictionary with movsx (signed extend); + // indices >= 32768 become negative, crashing SA pool accesses. + constexpr int maxPoolIndex = 32767; + if (newCapacity > maxPoolIndex + 1) + newCapacity = maxPoolIndex + 1; + if (newCapacity <= oldCapacity) + { + AddReportLog(9401, SString("CTxdPoolSA::Resize: clamped newCapacity(%d) <= oldCapacity(%d)", newCapacity, oldCapacity)); + return false; + } + + // Allocate replacement arrays via CMemoryMgr::MallocAlign (hooked to + // SafeMallocAlign). SA's original CPool arrays were allocated with + // operator new (SA's static CRT), but we intentionally use MTA's hooked + // allocator for the replacement arrays. SafeFreeAlign below will detect + // the old SA-CRT arrays lack the metadata magic and silently skip freeing + // them (~65 KB one-time leak, negligible for a 32 KB-slot pool resize). + auto* newObjects = static_cast(CMemoryMgr::MallocAlign(newCapacity * sizeof(CTextureDictonarySAInterface))); + if (!newObjects) + { + AddReportLog(9401, SString("CTxdPoolSA::Resize: MallocAlign failed for objects (size=%d)", newCapacity * sizeof(CTextureDictonarySAInterface))); + return false; + } + + auto* newByteMap = static_cast(CMemoryMgr::MallocAlign(newCapacity * sizeof(tPoolObjectFlags))); + if (!newByteMap) + { + AddReportLog(9401, SString("CTxdPoolSA::Resize: MallocAlign failed for bytemap (size=%d)", newCapacity * sizeof(tPoolObjectFlags))); + CMemoryMgr::FreeAlign(newObjects); + return false; + } + + // Preserve all existing entries + std::memcpy(newObjects, pool->m_pObjects, oldCapacity * sizeof(CTextureDictonarySAInterface)); + std::memcpy(newByteMap, pool->m_byteMap, oldCapacity * sizeof(tPoolObjectFlags)); + + // Zero-init new slots to avoid stale pointers in empty entries + std::memset(&newObjects[oldCapacity], 0, static_cast(newCapacity - oldCapacity) * sizeof(CTextureDictonarySAInterface)); + + // Mark new slots as empty + for (int i = oldCapacity; i < newCapacity; ++i) + { + newByteMap[i].bEmpty = true; + newByteMap[i].nId = 0; + } + + // Swap arrays (pool is only accessed from the main thread) + auto* oldObjects = pool->m_pObjects; + auto* oldByteMap = pool->m_byteMap; + + pool->m_pObjects = newObjects; + pool->m_byteMap = newByteMap; + pool->m_nSize = newCapacity; + + // Prevent SA's CPool destructor from calling operator delete on our + // SafeMallocAlign'd arrays. MTA exits via TerminateProcess() so the + // destructor normally never runs, but this is a zero-cost safeguard. + pool->m_bOwnsAllocations = false; + + // Don't override m_nFirstFree - SA's value points within [0, 5000) + // where its standard TXD allocations belong. Overriding it to + // oldCapacity-1 would make SA's Allocate()/GetFreeSlot() skip the + // standard range and hand out slots in the overflow zone (>= 5000) + // where no streaming entries exist. + + CMemoryMgr::FreeAlign(oldObjects); + CMemoryMgr::FreeAlign(oldByteMap); + + return true; +} + +void CTxdPoolSA::ProtectSlotFromStreaming(unsigned short usSlotId) +{ + g_StreamingProtectedTxdSlots.insert(usSlotId); +} + +void CTxdPoolSA::UnprotectSlotFromStreaming(unsigned short usSlotId) +{ + g_StreamingProtectedTxdSlots.erase(usSlotId); +} + +bool CTxdPoolSA::IsSlotProtectedFromStreaming(unsigned short usSlotId) const +{ + return g_StreamingProtectedTxdSlots.count(usSlotId) > 0; +} diff --git a/Client/game_sa/CTxdPoolSA.h b/Client/game_sa/CTxdPoolSA.h index c1f0ed8eced..5d25e4d0853 100644 --- a/Client/game_sa/CTxdPoolSA.h +++ b/Client/game_sa/CTxdPoolSA.h @@ -17,15 +17,59 @@ class CTxdPoolSA final : public CTxdPool { public: + // Pool expansion limit: 5000 > 10000 > 20000 > 32768. + // Capped at 32768: SA reads CBaseModelInfo::usTextureDictionary with + // movsx, so indices >= 32768 become negative and crash SA functions. + static constexpr int TXD_POOL_MAX_CAPACITY = 32768; + CTxdPoolSA(); ~CTxdPoolSA() = default; - std::uint32_t AllocateTextureDictonarySlot(std::uint32_t uiSlotID, std::string& strTxdName); - void RemoveTextureDictonarySlot(std::uint32_t uiTxdId); - bool IsFreeTextureDictonarySlot(std::uint32_t uiTxdId); + std::uint32_t AllocateTextureDictonarySlot(std::uint32_t uiSlotID, std::string& strTxdName) override; + void RemoveTextureDictonarySlot(std::uint32_t uiTxdId) override; + bool IsFreeTextureDictonarySlot(std::uint32_t uiTxdId) override; + + std::uint32_t GetFreeTextureDictonarySlot() override; + std::uint32_t GetFreeTextureDictonarySlotInRange(std::uint32_t maxExclusive) override; + std::uint32_t GetFreeTextureDictonarySlotAbove(std::uint32_t minInclusive) override; + int GetUsedSlotCountInRange(std::uint32_t maxExclusive) const override; + bool IsTxdLoaded(std::uint32_t uiTxdId) override; + + int GetPoolSize() const noexcept; + int GetUsedSlotCount() const noexcept; + + // Expands pool to TXD_POOL_MAX_CAPACITY after SA's CTxdStore::Initialise + // has created the pool. The pool pointer at 0xC8800C is still NULL during + // CTxdPoolSA construction, so expansion is deferred to this call. + void InitialisePool(); + + // Grows pool to newCapacity, preserving existing slots. + // Returns false if newCapacity <= current or allocation fails. + bool Resize(int newCapacity); - std::uint16_t GetFreeTextureDictonarySlot(); + // Access/modification helpers for slots we create + CTextureDictonarySAInterface* GetTextureDictonarySlot(std::uint32_t uiTxdId) noexcept; + bool SetTextureDictonarySlot(std::uint32_t uiTxdId, RwTexDictionary* pTxd, std::uint16_t usParentIndex) noexcept; + + // Streaming protection: prevents Hook_CTxdStore_RemoveRef from calling + // CStreaming::RemoveModel when the ref count of a protected slot drops + // to zero. This keeps SA from destroying the RwTexDictionary of MTA- + // managed isolated TXD slots before MTA has orphaned their textures. + void ProtectSlotFromStreaming(unsigned short usSlotId); + void UnprotectSlotFromStreaming(unsigned short usSlotId); + bool IsSlotProtectedFromStreaming(unsigned short usSlotId) const; private: + void InstallPoolHooks(); + CPoolSAInterface** m_ppTxdPoolInterface; + + // Hint for GetFreeTextureDictonarySlotInRange: slots below this index + // are likely occupied. Advanced past each slot the function returns, + // lowered when a slot below the hint is freed. + std::uint32_t m_uiFreeSlotHint = 0; + + // Same hint for GetFreeTextureDictonarySlotAbove: slots below this + // index (within the above-range) are likely occupied. + std::uint32_t m_uiFreeSlotHintAbove = MAX_STREAMING_TXD_SLOT; }; diff --git a/Client/game_sa/CVehicleAudioSettingsEntrySA.h b/Client/game_sa/CVehicleAudioSettingsEntrySA.h index 319e1614617..24298d6e40a 100644 --- a/Client/game_sa/CVehicleAudioSettingsEntrySA.h +++ b/Client/game_sa/CVehicleAudioSettingsEntrySA.h @@ -18,48 +18,51 @@ struct tVehicleAudioSettings { VehicleSoundType m_eVehicleSoundType; - int16 m_nEngineOnSoundBankId; - int16 m_nEngineOffSoundBankId; - int8 m_nBassSetting; // 0 or 1 or 2 - float m_fBassEq; - float field_C; - int8 m_nHornToneSoundInBank; - float m_fHornHigh; - char m_nDoorSound; - char m_EngineUpgrade; - char m_nRadioID; - char m_nRadioType; - char m_nVehTypeForAudio; - float m_fHornVolumeDelta; + int16 m_nEngineOnSoundBankId; + int16 m_nEngineOffSoundBankId; + int8 m_nBassSetting; // 0 or 1 or 2 + float m_fBassEq; + float field_C; + int8 m_nHornToneSoundInBank; + float m_fHornHigh; + char m_nDoorSound; + char m_EngineUpgrade; + char m_nRadioID; + char m_nRadioType; + char m_nVehTypeForAudio; + float m_fHornVolumeDelta; }; static_assert(sizeof(tVehicleAudioSettings) == 0x24, "Invalid size for tVehicleAudioSettings"); class CVehicleAudioSettingsEntrySA final : public CVehicleAudioSettingsEntry { public: - CVehicleAudioSettingsEntrySA(): m_Settings{} {}; + CVehicleAudioSettingsEntrySA() : m_Settings{} {}; CVehicleAudioSettingsEntrySA(tVehicleAudioSettings* pSettings) { m_Settings = *pSettings; }; ~CVehicleAudioSettingsEntrySA() = default; const tVehicleAudioSettings& GetInterface() const noexcept { return m_Settings; }; void Assign(const tVehicleAudioSettings& settings) noexcept { m_Settings = settings; } - void Assign(const CVehicleAudioSettingsEntry& settings) noexcept { m_Settings = static_cast(settings).GetInterface(); }; + void Assign(const CVehicleAudioSettingsEntry& settings) noexcept + { + m_Settings = static_cast(settings).GetInterface(); + }; - VehicleSoundType GetSoundType() const noexcept override { return m_Settings.m_eVehicleSoundType; }; - short GetEngineOnSoundBankID() const noexcept override { return m_Settings.m_nEngineOnSoundBankId; }; - short GetEngineOffSoundBankID() const noexcept override { return m_Settings.m_nEngineOffSoundBankId; }; - char GetBassSetting() const noexcept override { return m_Settings.m_nBassSetting; }; - float GetBassEq() const noexcept override { return m_Settings.m_fBassEq; }; - float GetFieldC() const noexcept override { return m_Settings.field_C; }; - char GetHornTon() const noexcept override { return m_Settings.m_nHornToneSoundInBank; }; - float GetHornHign() const noexcept override { return m_Settings.m_fHornHigh; }; - char GetEngineUpgrade() const noexcept override { return m_Settings.m_EngineUpgrade; }; - char GetDoorSound() const noexcept override { return m_Settings.m_nDoorSound; }; - char GetRadioNum() const noexcept override { return m_Settings.m_nRadioID; }; - char GetRadioType() const noexcept override { return m_Settings.m_nRadioType; }; - char GetVehicleTypeForAudio() const noexcept override { return m_Settings.m_nVehTypeForAudio; }; - float GetHornVolumeDelta() const noexcept override { return m_Settings.m_fHornVolumeDelta; }; + VehicleSoundType GetSoundType() const noexcept override { return m_Settings.m_eVehicleSoundType; }; + short GetEngineOnSoundBankID() const noexcept override { return m_Settings.m_nEngineOnSoundBankId; }; + short GetEngineOffSoundBankID() const noexcept override { return m_Settings.m_nEngineOffSoundBankId; }; + char GetBassSetting() const noexcept override { return m_Settings.m_nBassSetting; }; + float GetBassEq() const noexcept override { return m_Settings.m_fBassEq; }; + float GetFieldC() const noexcept override { return m_Settings.field_C; }; + char GetHornTon() const noexcept override { return m_Settings.m_nHornToneSoundInBank; }; + float GetHornHign() const noexcept override { return m_Settings.m_fHornHigh; }; + char GetEngineUpgrade() const noexcept override { return m_Settings.m_EngineUpgrade; }; + char GetDoorSound() const noexcept override { return m_Settings.m_nDoorSound; }; + char GetRadioNum() const noexcept override { return m_Settings.m_nRadioID; }; + char GetRadioType() const noexcept override { return m_Settings.m_nRadioType; }; + char GetVehicleTypeForAudio() const noexcept override { return m_Settings.m_nVehTypeForAudio; }; + float GetHornVolumeDelta() const noexcept override { return m_Settings.m_fHornVolumeDelta; }; void SetSoundType(VehicleSoundType value) noexcept override { m_Settings.m_eVehicleSoundType = value; }; void SetEngineOnSoundBankID(short value) noexcept override { m_Settings.m_nEngineOnSoundBankId = value; }; diff --git a/Client/game_sa/CVehicleAudioSettingsManagerSA.cpp b/Client/game_sa/CVehicleAudioSettingsManagerSA.cpp index a47cdeed003..99eb0b99b10 100644 --- a/Client/game_sa/CVehicleAudioSettingsManagerSA.cpp +++ b/Client/game_sa/CVehicleAudioSettingsManagerSA.cpp @@ -14,7 +14,7 @@ #include const auto (&ORIGINAL_AUDIO_SETTINGS)[VEHICLES_COUNT] = *reinterpret_cast(0x860AF0); -tVehicleAudioSettings const * pNextVehicleAudioSettings = nullptr; +tVehicleAudioSettings const* pNextVehicleAudioSettings = nullptr; CVehicleAudioSettingsManagerSA::CVehicleAudioSettingsManagerSA() { @@ -23,7 +23,7 @@ CVehicleAudioSettingsManagerSA::CVehicleAudioSettingsManagerSA() std::unique_ptr CVehicleAudioSettingsManagerSA::CreateVehicleAudioSettingsData(uint32_t modelId) { - auto settings = std::make_unique(); + auto settings = std::make_unique(); const auto& fromSetting = GetVehicleModelAudioSettingsData(modelId); settings->Assign(fromSetting); return settings; @@ -58,7 +58,7 @@ void CVehicleAudioSettingsManagerSA::ResetAudioSettingsData() noexcept void CVehicleAudioSettingsManagerSA::StaticSetHooks() noexcept { - // Replace + // Replace // 8D 34 B5 F0 0A 86 00 ; lea esi, _VehicleAudioProperties.m_eVehicleSoundType[esi*4] // to // 8b 35 XX XX XX XX ; mov esi, [pNextVehicleAudioSettings] diff --git a/Client/game_sa/CVehicleAudioSettingsManagerSA.h b/Client/game_sa/CVehicleAudioSettingsManagerSA.h index ddd15140954..c7e2b936b48 100644 --- a/Client/game_sa/CVehicleAudioSettingsManagerSA.h +++ b/Client/game_sa/CVehicleAudioSettingsManagerSA.h @@ -24,7 +24,7 @@ class CVehicleAudioSettingsManagerSA final : public CVehicleAudioSettingsManager CVehicleAudioSettingsManagerSA(); std::unique_ptr CreateVehicleAudioSettingsData(uint32_t modelId) override; - CVehicleAudioSettingsEntry& GetVehicleModelAudioSettingsData(uint32_t modelId) noexcept override; + CVehicleAudioSettingsEntry& GetVehicleModelAudioSettingsData(uint32_t modelId) noexcept override; void ResetModelSettings(uint32_t modelId) noexcept override; void ResetAudioSettingsData() noexcept override; diff --git a/Client/game_sa/CVehicleSA.cpp b/Client/game_sa/CVehicleSA.cpp index f143c1784eb..512247c4fb6 100644 --- a/Client/game_sa/CVehicleSA.cpp +++ b/Client/game_sa/CVehicleSA.cpp @@ -11,11 +11,13 @@ #include "StdInc.h" #include +#include #include #include "CAutomobileSA.h" #include "CBikeSA.h" #include "CCameraSA.h" #include "CColModelSA.h" +#include "CColModelGuard.h" #include "CFxManagerSA.h" #include "CFxSystemSA.h" #include "CGameSA.h" @@ -29,35 +31,36 @@ #include "CWorldSA.h" #include "gamesa_renderware.h" #include "CFireManagerSA.h" +#include "enums/VehicleType.h" extern CCoreInterface* g_pCore; extern CGameSA* pGame; static BOOL m_bVehicleSunGlare = false; -_declspec(naked) void DoVehicleSunGlare(void* this_) -{ - _asm { - mov eax, FUNC_CVehicle_DoSunGlare - jmp eax - } -} -void _declspec(naked) HOOK_Vehicle_PreRender(void) +static void __declspec(naked) HOOK_Vehicle_PreRender() { - _asm { - mov ecx, m_bVehicleSunGlare - cmp ecx, 0 - jle noglare - mov ecx, esi - call DoVehicleSunGlare - noglare: - mov [esp+0D4h], edi - push 6ABD04h + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + mov ecx, m_bVehicleSunGlare + cmp ecx, 0 + jle noglare + mov ecx, esi + mov eax, FUNC_CVehicle_DoSunGlare + call eax + + noglare: + mov [esp+0D4h], edi + push 6ABD04h retn } + // clang-format on } -static float& fTimeStep = *(float*)(0xB7CB5C); +static float& fTimeStep = *(float*)(0xB7CB5C); static bool __fastcall CanProcessFlyingCarStuff(CAutomobileSAInterface* vehicleInterface) { SClientEntity* vehicle = pGame->GetPools()->GetVehicle((DWORD*)vehicleInterface); @@ -66,12 +69,12 @@ static bool __fastcall CanProcessFlyingCarStuff(CAutomobileSAInterface* vehicleI if (vehicle->pEntity->GetVehicleRotorState()) { - if (g_pCore->GetMultiplayer()->IsVehicleEngineAutoStartEnabled()) // keep default behavior + if (g_pCore->GetMultiplayer()->IsVehicleEngineAutoStartEnabled()) // keep default behavior return true; if (vehicle->pEntity->GetEntityStatus() != eEntityStatus::STATUS_PHYSICS && !vehicle->pEntity->IsBeingDriven()) { - vehicle->pEntity->SetEntityStatus(eEntityStatus::STATUS_PHYSICS); // this will make rotors spin without driver when engine is on + vehicle->pEntity->SetEntityStatus(eEntityStatus::STATUS_PHYSICS); // this will make rotors spin without driver when engine is on return false; } if (!vehicle->pEntity->IsEngineOn()) @@ -79,11 +82,11 @@ static bool __fastcall CanProcessFlyingCarStuff(CAutomobileSAInterface* vehicleI // Smoothly change rotors speed to 0 float speed = vehicle->pEntity->GetHeliRotorSpeed(); if (speed > 0) - vehicle->pEntity->SetHeliRotorSpeed(std::max(0.0f, speed - fTimeStep * 0.00055f)); // 0x6C4EB7 + vehicle->pEntity->SetHeliRotorSpeed(std::max(0.0f, speed - fTimeStep * 0.00055f)); // 0x6C4EB7 speed = vehicle->pEntity->GetPlaneRotorSpeed(); if (speed > 0) - vehicle->pEntity->SetPlaneRotorSpeed(std::max(0.0f, speed - fTimeStep * 0.003f)); // 0x6CC145 + vehicle->pEntity->SetPlaneRotorSpeed(std::max(0.0f, speed - fTimeStep * 0.003f)); // 0x6CC145 return false; } @@ -92,55 +95,82 @@ static bool __fastcall CanProcessFlyingCarStuff(CAutomobileSAInterface* vehicleI return false; } -static constexpr DWORD CONTINUE_CHeli_ProcessFlyingCarStuff = 0x6C4E82; -static constexpr DWORD RETURN_CHeli_ProcessFlyingCarStuff = 0x6C5404; -static void _declspec(naked) HOOK_CHeli_ProcessFlyingCarStuff() +static constexpr DWORD CONTINUE_CHeli_ProcessFlyingCarStuff = 0x6C4E82; +static constexpr DWORD RETURN_CHeli_ProcessFlyingCarStuff = 0x6C5404; +static void __declspec(naked) HOOK_CHeli_ProcessFlyingCarStuff() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - mov esi, ecx - mov al, [esi+36h] + mov esi, ecx + mov al, [esi+36h] pushad - call CanProcessFlyingCarStuff - test al, al - jz skip - + call CanProcessFlyingCarStuff + test al, al popad - jmp CONTINUE_CHeli_ProcessFlyingCarStuff + + jz skip + jmp CONTINUE_CHeli_ProcessFlyingCarStuff skip: - popad - jmp RETURN_CHeli_ProcessFlyingCarStuff + jmp RETURN_CHeli_ProcessFlyingCarStuff } + // clang-format on } -static constexpr DWORD CONTINUE_CPlane_ProcessFlyingCarStuff = 0x6CB7D7; -static constexpr DWORD RETURN_CPlane_ProcessFlyingCarStuff = 0x6CC482; -static void _declspec(naked) HOOK_CPlane_ProcessFlyingCarStuff() +static constexpr DWORD CONTINUE_CPlane_ProcessFlyingCarStuff = 0x6CB7D7; +static constexpr DWORD RETURN_CPlane_ProcessFlyingCarStuff = 0x6CC482; +static void __declspec(naked) HOOK_CPlane_ProcessFlyingCarStuff() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - push esi - mov esi, ecx - fnstsw ax + push esi + mov esi, ecx + fnstsw ax pushad - call CanProcessFlyingCarStuff - test al, al - jz skip - + call CanProcessFlyingCarStuff + test al, al popad - jmp CONTINUE_CPlane_ProcessFlyingCarStuff + + jz skip + jmp CONTINUE_CPlane_ProcessFlyingCarStuff skip: - popad - jmp RETURN_CPlane_ProcessFlyingCarStuff + jmp RETURN_CPlane_ProcessFlyingCarStuff } + // clang-format on } +#define NUM_FirstStreamEngineSlot 7 +#define NUM_LastStreamEngineSlot 16 +#define NUM_AllSoundIndices 0xFFFFFFFF +#define NUM_ResidentEngineSlot 40 +#define NUM_LocalVehicleAudioContext 0x0 +#define VAR_VehicleAudioContext 0x50230C + namespace { + void CancelVehicleAudioSlots(CAEVehicleAudioEntitySAInterface* pAudioInterface) + { + auto* pSoundManager = pGame ? pGame->GetAESoundManager() : nullptr; + if (!pAudioInterface || !pSoundManager) + return; + + if (pAudioInterface->m_wEngineBankSlotId >= NUM_FirstStreamEngineSlot && pAudioInterface->m_wEngineBankSlotId <= NUM_LastStreamEngineSlot) + pSoundManager->CancelSoundsInBankSlot(pAudioInterface->m_wEngineBankSlotId, NUM_AllSoundIndices); + + if (pAudioInterface->m_bPlayerDriver || pAudioInterface->m_bPlayerPassenger || + *reinterpret_cast(VAR_VehicleAudioContext) == NUM_LocalVehicleAudioContext) + pSoundManager->CancelSoundsInBankSlot(NUM_ResidentEngineSlot, NUM_AllSoundIndices); + } + bool ClumpDumpCB(RpAtomic* pAtomic, void* data) { CVehicleSA* pVehicleSA = (CVehicleSA*)data; @@ -175,7 +205,7 @@ namespace RwFrameDump(ret, pVehicleSA); } // don't re-add, check ret for validity, if it has an empty string at this point it isn't a variant or it's already added - if (pVehicleSA->IsComponentPresent(ret->szName) == false && ret->szName != "") + if (pVehicleSA->IsComponentPresent(ret->szName) == false && ret->szName[0] != '\0') { pVehicleSA->AddComponent(ret, true); } @@ -199,8 +229,46 @@ namespace } // Get all atomics for this frame (even if they are invisible) - void GetAllAtomicObjects(RwFrame* frame, std::vector& result) { RwFrameForAllObjects(frame, (void*)GetAllAtomicObjectCB, &result); } -} // namespace + void GetAllAtomicObjects(RwFrame* frame, std::vector& result) + { + RwFrameForAllObjects(frame, (void*)GetAllAtomicObjectCB, &result); + } + + int GetComponentIDFromName(const SString& name) + { + if (name == "bonnet_dummy") + return eDoors::BONNET; + else if (name == "boot_dummy") + return eDoors::BOOT; + else if (name == "door_lf_dummy") + return eDoors::FRONT_LEFT_DOOR; + else if (name == "door_rf_dummy") + return eDoors::FRONT_RIGHT_DOOR; + else if (name == "door_lb_dummy") + return eDoors::REAR_LEFT_DOOR; + else if (name == "door_rb_dummy") + return eDoors::REAR_RIGHT_DOOR; + else if (name == "bump_front_dummy") + return ePanels::FRONT_BUMPER; + else if (name == "bump_rear_dummy") + return ePanels::REAR_BUMPER; + else if (name == "windscreen_dummy") + return ePanels::WINDSCREEN_PANEL; + } + + VehicleComponentType GetComponentTypeFromName(const SString& name) + { + if (name == "bonnet_dummy" || name == "boot_dummy" || name == "door_lf_dummy" || name == "door_rf_dummy" || name == "door_lb_dummy" || + name == "door_rb_dummy") + return VehicleComponentType::DOOR; + else if (name == "bump_front_dummy" || name == "bump_rear_dummy" || name == "windscreen_dummy") + return VehicleComponentType::PANEL; + else if (name == "wheel_lb_dummy" || name == "wheel_rb_dummy" || name == "wheel_lf_dummy" || name == "wheel_rf_dummy") + return VehicleComponentType::WHEEL; + + return VehicleComponentType::NONE; + } +} // namespace void CVehicleSA::Init() { @@ -318,12 +386,11 @@ CVehicleSA::~CVehicleSA() } DWORD dwThis = (DWORD)m_pInterface; - DWORD dwFunc = 0x6D2460; // CVehicle::ExtinguishCarFire - _asm - { - mov ecx, dwThis - call dwFunc - } + DWORD dwFunc = 0x6D2460; // CVehicle::ExtinguishCarFire + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on CWorldSA* pWorld = (CWorldSA*)pGame->GetWorld(); pGame->GetProjectileInfo()->RemoveEntityReferences(this); @@ -342,12 +409,10 @@ void CVehicleSA::SetMoveSpeed(const CVector& vecMoveSpeed) noexcept DWORD dwFunc = FUNC_GetMoveSpeed; DWORD dwThis = (DWORD)GetInterface(); DWORD dwReturn = 0; - _asm - { - mov ecx, dwThis - call dwFunc - mov dwReturn, eax - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(dwThis) ); +dwReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on MemCpyFast((void*)dwReturn, &vecMoveSpeed, sizeof(CVector)); // INACCURATE. Use Get/SetTrainSpeed instead of Get/SetMoveSpeed. (Causes issue #4829). @@ -556,11 +621,10 @@ void CVehicleSA::SetDerailed(bool bDerailed) // Recalculate the on-rail distance from the start node (train position parameter, m_fTrainRailDistance) DWORD dwFunc = FUNC_CTrain_FindPositionOnTrackFromCoors; - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on // Reset the speed static_cast(GetVehicleInterface())->m_fTrainSpeed = 0.0f; @@ -598,11 +662,12 @@ void CVehicleSA::SetVehicleRotorState(bool state, bool stopRotor, bool isHeli) n if (state || !stopRotor) return; - if (isHeli) + if (isHeli) { SetHeliRotorSpeed(0.0f); - else + } else { SetPlaneRotorSpeed(0.0f); } +} void CVehicleSA::SetPlaneRotorSpeed(float fSpeed) { @@ -611,7 +676,7 @@ void CVehicleSA::SetPlaneRotorSpeed(float fSpeed) } bool CVehicleSA::SetVehicleWheelRotation(float fWheelRot1, float fWheelRot2, float fWheelRot3, float fWheelRot4) noexcept -{ +{ VehicleClass m_eVehicleType = static_cast(GetVehicleInterface()->m_vehicleSubClass); switch (m_eVehicleType) { @@ -641,7 +706,7 @@ bool CVehicleSA::SetVehicleWheelRotation(float fWheelRot1, float fWheelRot2, flo return false; } -float CVehicleSA::GetPlaneRotorSpeed() +float CVehicleSA::GetPlaneRotorSpeed() { auto pInterface = static_cast(GetInterface()); return pInterface->m_fPropSpeed; @@ -677,11 +742,10 @@ void CVehicleSA::SetRailTrack(BYTE ucTrackID) if (!IsDerailed()) { DWORD dwFunc = FUNC_CTrain_FindPositionOnTrackFromCoors; - _asm - { - mov ecx, pInterf - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(pInterf) ); + reinterpret_cast(dwFunc)(pInterf); + // clang-format on } } } @@ -701,11 +765,10 @@ void CVehicleSA::SetTrainPosition(float fPosition, bool bRecalcOnRailDistance) if (bRecalcOnRailDistance && !IsDerailed()) { DWORD dwFunc = FUNC_CTrain_FindPositionOnTrackFromCoors; - _asm - { - mov ecx, pInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(pInterface) ); + reinterpret_cast(dwFunc)(pInterface); + // clang-format on } } } @@ -768,12 +831,10 @@ void CVehicleSA::AddVehicleUpgrade(DWORD dwModelID) DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CVehicle_AddVehicleUpgrade; - _asm - { - mov ecx, dwThis - push dwModelID - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwModelID)); + reinterpret_cast(dwFunc)(dwThis, dwModelID); + // clang-format on } } @@ -782,12 +843,10 @@ void CVehicleSA::RemoveVehicleUpgrade(DWORD dwModelID) DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CVehicle_RemoveVehicleUpgrade; - _asm - { - mov ecx, dwThis - push dwModelID - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwModelID)); + reinterpret_cast(dwFunc)(dwThis, dwModelID); + // clang-format on // GTA SA only does this when CVehicle::ClearVehicleUpgradeFlags returns false. // In the case of hydraulics and nitro, this function does not return false and the upgrade is never removed from the array @@ -819,13 +878,10 @@ DWORD CVehicleSA::GetBaseVehicleType() DWORD dwFunc = FUNC_CVehicle_GetBaseVehicleType; DWORD dwReturn = 0; - _asm - { - mov ecx, dwThis - call dwFunc - mov dwReturn, eax - - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(dwThis) ); +dwReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on return dwReturn; } @@ -866,12 +922,10 @@ bool CVehicleSA::IsUpsideDown() DWORD dwFunc = FUNC_CVehicle_IsUpsideDown; bool bReturn = false; - _asm - { - mov ecx, dwThis - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThis) ); +bReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on return bReturn; } @@ -882,12 +936,10 @@ void CVehicleSA::SetEngineOn(bool bEngineOn) DWORD dwEngineOn = (DWORD)bEngineOn; DWORD dwFunc = FUNC_CVehicle_SetEngineOn; - _asm - { - mov ecx, dwThis - push dwEngineOn - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwEngineOn)); + reinterpret_cast(dwFunc)(dwThis, dwEngineOn); + // clang-format on } CPed* CVehicleSA::GetDriver() @@ -939,11 +991,10 @@ void CVehicleSA::PlaceBikeOnRoadProperly() DWORD dwFunc = FUNC_Bike_PlaceOnRoadProperly; DWORD dwBike = (DWORD)GetInterface(); - _asm - { - mov ecx, dwBike - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwBike) ); + reinterpret_cast(dwFunc)(dwBike); + // clang-format on } void CVehicleSA::PlaceAutomobileOnRoadProperly() @@ -951,11 +1002,10 @@ void CVehicleSA::PlaceAutomobileOnRoadProperly() DWORD dwFunc = FUNC_Automobile_PlaceOnRoadProperly; DWORD dwAutomobile = (DWORD)GetInterface(); - _asm - { - mov ecx, dwAutomobile - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwAutomobile) ); + reinterpret_cast(dwFunc)(dwAutomobile); + // clang-format on } void CVehicleSA::SetColor(SharedUtil::SColor color1, SharedUtil::SColor color2, SharedUtil::SColor color3, SharedUtil::SColor color4, int) @@ -970,14 +1020,14 @@ void CVehicleSA::SetColor(SharedUtil::SColor color1, SharedUtil::SColor color2, { m_RGBColorsFixed[i] = m_RGBColors[i]; const SharedUtil::SColor color = m_RGBColorsFixed[i]; - if (color == 0xFF00FF // 255, 0, 255 - || color == 0x00FFFF // 0, 0, 255 - || color == 0xFF00AF // 255, 0, 175 - || color == 0xFFAF00 // 255, 175, 0 - || color == 0xB9FF00 // 185, 255, 0 - || color == 0x00FFC8 // 0, 255, 200 - || color == 0xFF3C00 // 255, 60, 0 - || color == 0x3CFF00) // 60, 255, 0 + if (color == 0xFF00FF // 255, 0, 255 + || color == 0x00FFFF // 0, 0, 255 + || color == 0xFF00AF // 255, 0, 175 + || color == 0xFFAF00 // 255, 175, 0 + || color == 0xB9FF00 // 185, 255, 0 + || color == 0x00FFC8 // 0, 255, 200 + || color == 0xFF3C00 // 255, 60, 0 + || color == 0x3CFF00) // 60, 255, 0 m_RGBColorsFixed[i].ulARGB |= 0x010101; } } @@ -1008,7 +1058,8 @@ void CVehicleSA::GetTurretRotation(float* fHorizontal, float* fVertical) DWORD vehicleInterface = (DWORD)GetInterface(); float fHoriz = 0.0f; float fVert = 0.0f; - _asm + // clang-format off + __asm { mov eax, vehicleInterface add eax, 0x94C @@ -1018,6 +1069,7 @@ void CVehicleSA::GetTurretRotation(float* fHorizontal, float* fVertical) fld [eax] fstp fVert } + // clang-format on *fHorizontal = fHoriz; *fVertical = fVert; } @@ -1027,7 +1079,8 @@ void CVehicleSA::SetTurretRotation(float fHorizontal, float fVertical) //*(float *)(this->GetInterface() + 2380) = fHorizontal; //*(float *)(this->GetInterface() + 2384) = fVertical; DWORD vehicleInterface = (DWORD)GetInterface(); - _asm + // clang-format off + __asm { mov eax, vehicleInterface add eax, 0x94C @@ -1037,6 +1090,7 @@ void CVehicleSA::SetTurretRotation(float fHorizontal, float fVertical) fld fVertical fstp [eax] } + // clang-format on } bool CVehicleSA::IsSirenOrAlarmActive() @@ -1088,10 +1142,11 @@ void CVehicleSA::SetLandingGearDown(bool bLandingGearDown) } else { - if (fPosition != 1.0f) + if (fPosition != 1.0f) { fPosition *= -1.0f; - else + } else { fPosition = (fTimeStep * flt_871904) - 1.0f; +} } } } @@ -1111,11 +1166,12 @@ void CVehicleSA::SetLandingGearPosition(float fPosition) bool CVehicleSA::IsLandingGearDown() { DWORD dwThis = (DWORD)GetInterface(); - if (*(float*)(dwThis + 2508) <= 0.0f) + if (*(float*)(dwThis + 2508) <= 0.0f) { return true; - else + } else { return false; } +} void CVehicleSA::Fix() { @@ -1125,22 +1181,22 @@ void CVehicleSA::Fix() CModelInfo* pModelInfo = pGame->GetModelInfo(GetModelIndex()); if (pModelInfo) { - if (pModelInfo->IsCar() || pModelInfo->IsMonsterTruck() || pModelInfo->IsTrailer()) + if (pModelInfo->IsCar() || pModelInfo->IsMonsterTruck() || pModelInfo->IsTrailer()) { dwFunc = FUNC_CAutomobile__Fix; - else if (pModelInfo->IsPlane()) + } else if (pModelInfo->IsPlane()) { dwFunc = FUNC_CPlane__Fix; - else if (pModelInfo->IsHeli()) + } else if (pModelInfo->IsHeli()) { dwFunc = FUNC_CHeli__Fix; - else if (pModelInfo->IsBike()) + } else if (pModelInfo->IsBike()) { dwFunc = FUNC_CBike_Fix; +} if (dwFunc) { - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } } } @@ -1235,12 +1291,10 @@ void CVehicleSA::PickupEntityWithWinch(CEntity* pEntity) DWORD dwThis = (DWORD)GetInterface(); DWORD dwEntityInterface = (DWORD)pEntitySA->GetInterface(); - _asm - { - push dwEntityInterface - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwEntityInterface)); + reinterpret_cast(dwFunc)(dwThis, dwEntityInterface); + // clang-format on } } @@ -1249,11 +1303,10 @@ void CVehicleSA::ReleasePickedUpEntityWithWinch() DWORD dwFunc = FUNC_CVehicle_ReleasePickedUpEntityWithWinch; DWORD dwThis = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis) ); + reinterpret_cast(dwFunc)(dwThis); + // clang-format on } void CVehicleSA::SetRopeHeightForHeli(float fRopeHeight) @@ -1261,12 +1314,10 @@ void CVehicleSA::SetRopeHeightForHeli(float fRopeHeight) DWORD dwFunc = FUNC_CVehicle_SetRopeHeightForHeli; DWORD dwThis = (DWORD)GetInterface(); - _asm - { - push fRopeHeight - mov ecx, dwThis - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(fRopeHeight)); + reinterpret_cast(dwFunc)(dwThis, fRopeHeight); + // clang-format on } CPhysical* CVehicleSA::QueryPickedUpEntityWithWinch() @@ -1275,12 +1326,10 @@ CPhysical* CVehicleSA::QueryPickedUpEntityWithWinch() DWORD dwThis = (DWORD)GetInterface(); CPhysicalSAInterface* phys; - _asm - { - mov ecx, dwThis - call dwFunc - mov phys, eax - } + // clang-format off + using func_t = decltype(phys) (__thiscall*)(decltype(dwThis) ); +phys = reinterpret_cast(dwFunc)(dwThis); + // clang-format on if (phys) { @@ -1294,12 +1343,10 @@ void CVehicleSA::SetRemap(int iRemap) { DWORD dwFunc = FUNC_CVehicle__SetRemap; DWORD dwThis = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThis - push iRemap - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(iRemap)); + reinterpret_cast(dwFunc)(dwThis, iRemap); + // clang-format on } int CVehicleSA::GetRemapIndex() @@ -1307,12 +1354,10 @@ int CVehicleSA::GetRemapIndex() DWORD dwFunc = FUNC_CVehicle__GetRemapIndex; DWORD dwThis = (DWORD)GetInterface(); int iReturn = 0; - _asm - { - mov ecx, dwThis - call dwFunc - mov iReturn, eax - } + // clang-format off + using func_t = decltype(iReturn) (__thiscall*)(decltype(dwThis) ); +iReturn = reinterpret_cast(dwFunc)(dwThis); + // clang-format on return iReturn; } @@ -1320,12 +1365,10 @@ void CVehicleSA::SetRemapTexDictionary(int iRemapTextureDictionary) { DWORD dwFunc = FUNC_CVehicle__SetRemapTexDictionary; DWORD dwThis = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThis - push iRemapTextureDictionary - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(iRemapTextureDictionary)); + reinterpret_cast(dwFunc)(dwThis, iRemapTextureDictionary); + // clang-format on } bool CVehicleSA::IsSmokeTrailEnabled() @@ -1418,7 +1461,7 @@ void CVehicleSA::RecalculateHandling() pInt->dwHandlingFlags = uiHandlingFlags; pInt->m_fMass = m_pHandlingData->GetInterface()->fMass; - pInt->m_fTurnMass = m_pHandlingData->GetInterface()->fTurnMass; // * pGame->GetHandlingManager()->GetTurnMassMultiplier(); + pInt->m_fTurnMass = m_pHandlingData->GetInterface()->fTurnMass; // * pGame->GetHandlingManager()->GetTurnMassMultiplier(); pInt->m_vecCenterOfMass = m_pHandlingData->GetInterface()->vecCenterOfMass; pInt->m_fBuoyancyConstant = m_pHandlingData->GetInterface()->fUnknown2; /*if (m_pHandlingData->GetInterface()->fDragCoeff >= pGame->GetHandlingManager()->GetBasicDragCoeff()) @@ -1468,8 +1511,20 @@ bool CVehicleSA::IsWheelCollided(BYTE eWheelPosition) int CVehicleSA::GetWheelFrictionState(BYTE eWheelPosition) { - auto vehicle = static_cast(GetInterface()); - return vehicle->m_wheelFrictionState[eWheelPosition]; + switch (static_cast(GetVehicleInterface()->m_vehicleClass)) + { + case VehicleClass::BIKE: + case VehicleClass::BMX: + { + auto* bikeInterface = static_cast(GetVehicleInterface()); + return bikeInterface->m_aiWheelState[eWheelPosition]; + } + default: + { + auto* vehicleInterface = static_cast(GetVehicleInterface()); + return vehicleInterface->m_wheelFrictionState[eWheelPosition]; + } + } } void CVehicleSA::SetTaxiLightOn(bool bLightOn) @@ -1478,12 +1533,10 @@ void CVehicleSA::SetTaxiLightOn(bool bLightOn) DWORD dwState = (DWORD)bLightOn; DWORD dwFunc = FUNC_CAutomobile_SetTaxiLight; - _asm - { - mov ecx, dwThis - push dwState - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwState)); + reinterpret_cast(dwFunc)(dwThis, dwState); + // clang-format on } void GetMatrixForGravity(const CVector& vecGravity, CMatrix& mat) @@ -1548,7 +1601,7 @@ bool CVehicleSA::SpawnFlyingComponent(const eCarNodes& nodeIndex, const eCarComp if (nodeIndex == eCarNodes::NONE) return false; - DWORD nodesOffset = OFFSET_CAutomobile_Nodes; + DWORD nodesOffset = OFFSET_CAutomobile_Nodes; RwFrame* defaultBikeChassisFrame = nullptr; // CBike, CBmx, CBoat and CTrain don't inherit CAutomobile so let's do it manually! @@ -1739,13 +1792,10 @@ bool CVehicleSA::UpdateMovingCollision(float fAngle) bool bReturn; DWORD dwThis = (DWORD)GetInterface(); DWORD dwFunc = FUNC_CAutomobile__UpdateMovingCollision; - _asm - { - mov ecx, dwThis - push fAngle - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThis), decltype(fAngle)); +bReturn = reinterpret_cast(dwFunc)(dwThis, fAngle); + // clang-format on // Restore our driver vehicle->pDriver = pDriver; @@ -1755,10 +1805,14 @@ bool CVehicleSA::UpdateMovingCollision(float fAngle) void* CVehicleSA::GetPrivateSuspensionLines() { - if (m_pSuspensionLines == NULL) + if (m_pSuspensionLines == nullptr) { CModelInfo* pModelInfo = pGame->GetModelInfo(GetModelIndex()); - CColDataSA* pColData = pModelInfo->GetInterface()->pColModel->m_data; + if (!pModelInfo) + return nullptr; + + CBaseModelInfoSAInterface* pInterface = pModelInfo->GetInterface(); + CColDataSA* pColData = (pInterface && pInterface->pColModel) ? pInterface->pColModel->m_data : nullptr; if (pModelInfo->IsMonsterTruck()) { // Monster truck suspension data is 0x90 BYTES rather than 0x80 (some extra stuff I guess) @@ -1772,7 +1826,8 @@ void* CVehicleSA::GetPrivateSuspensionLines() else { // CAutomobile allocates wheels * 32 (0x20) - m_pSuspensionLines = new BYTE[pColData->m_numSuspensionLines * 0x20]; + const std::size_t numLines = pColData ? std::min(pColData->m_numSuspensionLines, MAX_SUSPENSION_LINES) : MAX_SUSPENSION_LINES; + m_pSuspensionLines = new BYTE[numLines * SUSPENSION_SIZE_STANDARD]; } } @@ -1782,43 +1837,82 @@ void* CVehicleSA::GetPrivateSuspensionLines() void CVehicleSA::CopyGlobalSuspensionLinesToPrivate() { CModelInfo* pModelInfo = pGame->GetModelInfo(GetModelIndex()); - CColDataSA* pColData = pModelInfo->GetInterface()->pColModel->m_data; + if (!pModelInfo) + return; + + // Protect collision model from streaming GC + CColModelGuard guard(static_cast(pModelInfo)); + if (!guard.IsValid()) + return; + + CColDataSA* pColData = guard.GetColData(); + if (!pColData || !pColData->m_suspensionLines) + return; + + void* pPrivateLines = GetPrivateSuspensionLines(); + if (!pPrivateLines) + return; + + // Determine copy size based on vehicle type + std::size_t copySize = 0; if (pModelInfo->IsMonsterTruck()) { - // Monster trucks are 0x90 bytes not 0x80 - if (pColData->m_suspensionLines) - memcpy(GetPrivateSuspensionLines(), pColData->m_suspensionLines, 0x90); + // Monster trucks: 0x90 bytes + copySize = SUSPENSION_SIZE_MONSTER_TRUCK; } else if (pModelInfo->IsBike()) { - // Bikes are 0x80 bytes not 0x40 - if (pColData->m_suspensionLines) - memcpy(GetPrivateSuspensionLines(), pColData->m_suspensionLines, 0x80); + // Bikes: 0x80 bytes (2 wheels with extra data) + copySize = SUSPENSION_SIZE_BIKE; } else { - // CAutomobile allocates wheels * 32 (0x20) - if (pColData->m_suspensionLines) - memcpy(GetPrivateSuspensionLines(), pColData->m_suspensionLines, pColData->m_numSuspensionLines * 0x20); + // CAutomobile: wheels * 0x20 bytes + const std::size_t numLines = std::min(pColData->m_numSuspensionLines, MAX_SUSPENSION_LINES); + copySize = numLines * SUSPENSION_SIZE_STANDARD; + } + + if (copySize > 0 && copySize <= MAX_SUSPENSION_LINES * SUSPENSION_SIZE_STANDARD) + { + memcpy(pPrivateLines, pColData->m_suspensionLines, copySize); } } void CVehicleSA::RecalculateSuspensionLines() { CHandlingEntry* pHandlingEntry = GetHandlingData(); + if (!pHandlingEntry) + return; + + const std::uint32_t dwModel = GetModelIndex(); - DWORD dwModel = GetModelIndex(); CModelInfo* pModelInfo = pGame->GetModelInfo(dwModel); - if (pModelInfo && pModelInfo->IsMonsterTruck() || pModelInfo->IsCar()) - { - // Trains (Their trailers do as well!) - if (pModelInfo->IsTrain() || dwModel == 571 || dwModel == 570 || dwModel == 569 || dwModel == 590) - return; + if (!pModelInfo || !pModelInfo->GetInterface()) + return; - GetVehicleInterface()->SetupSuspensionLines(); + // Only for vehicles with suspension lines + if (!(pModelInfo->IsMonsterTruck() || pModelInfo->IsCar())) + return; - CopyGlobalSuspensionLinesToPrivate(); - } + // Skip trains and their trailers (no suspension lines) + if (pModelInfo->IsTrain() || dwModel == static_cast(VehicleType::VT_FREIFLAT) || + dwModel == static_cast(VehicleType::VT_STREAKC) || dwModel == static_cast(VehicleType::VT_FREIBOX)) + return; + + // Protect collision model before accessing suspension data + CColModelGuard guard(static_cast(pModelInfo)); + if (!guard.IsValid()) + return; + + CVehicleSAInterface* pVehicleInterface = GetVehicleInterface(); + if (!pVehicleInterface) + return; + + // Safe to call now - collision is protected by guard + pVehicleInterface->SetupSuspensionLines(); + + // Copy to private storage while still protected + CopyGlobalSuspensionLinesToPrivate(); } void CVehicleSA::GiveVehicleSirens(unsigned char ucSirenType, unsigned char ucSirenCount) @@ -1925,15 +2019,10 @@ namespace if (matrixPadded) { DWORD dwFunc = FUNC_CMatrix__ConvertFromEulerAngles; - _asm - { - push iUnknown - push fZ - push fY - push fX - mov ecx, matrixPadded - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(matrixPadded), decltype(fX), decltype(fY), decltype(fZ), decltype(iUnknown)); + reinterpret_cast(dwFunc)(matrixPadded, fX, fY, fZ, iUnknown); + // clang-format on } } void _MatrixConvertToEulerAngles(CMatrix_Padded* matrixPadded, float& fX, float& fY, float& fZ) @@ -1942,18 +2031,13 @@ namespace if (matrixPadded) { DWORD dwFunc = FUNC_CMatrix__ConvertToEulerAngles; - _asm - { - push iUnknown - push fZ - push fY - push fX - mov ecx, matrixPadded - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(matrixPadded), decltype(fX), decltype(fY), decltype(fZ), decltype(iUnknown)); + reinterpret_cast(dwFunc)(matrixPadded, fX, fY, fZ, iUnknown); + // clang-format on } } -} // namespace +} // namespace SVehicleFrame* CVehicleSA::GetVehicleComponent(const SString& vehicleComponent) { @@ -2087,7 +2171,7 @@ void CVehicleSA::AddComponent(RwFrame* pFrame, bool bReadOnly) return; // if the frame already exists ignore it - if (IsComponentPresent(pFrame->szName) || pFrame->szName == "") + if (IsComponentPresent(pFrame->szName) || pFrame->szName[0] == '\0') return; SString strName = pFrame->szName; @@ -2160,30 +2244,60 @@ bool CVehicleSA::SetComponentVisible(const SString& vehicleComponent, bool bRequ // Count number currently visible uint uiNumAtomicsCurrentlyVisible = 0; - for (uint i = 0; i < atomicList.size(); i++) + for (uint i = 0; i < atomicList.size(); i++) { if (atomicList[i]->flags & 0x04) uiNumAtomicsCurrentlyVisible++; +} if (bRequestVisible && uiNumAtomicsCurrentlyVisible == 0) { - // Make atomic (undamaged version) visible. TODO - Check if damaged version should be made visible instead + bool isComponentDamaged = false; + bool isComponentFallenOff = false; + int componentID = GetComponentIDFromName(vehicleComponent); + auto damageManager = GetDamageManager(); + + switch (GetComponentTypeFromName(vehicleComponent)) + { + case VehicleComponentType::DOOR: + { + std::uint8_t doorStatus = damageManager->GetDoorStatus(static_cast(componentID)); + + isComponentDamaged = (doorStatus > 1); + isComponentFallenOff = (doorStatus == 4); + break; + } + case VehicleComponentType::PANEL: + { + std::uint8_t panelStatus = damageManager->GetPanelStatus(static_cast(componentID)); + + isComponentDamaged = (panelStatus > 0); + isComponentFallenOff = (panelStatus == 3); + break; + } + default: + break; + } + + // We don't want to show the component that fell off + if (isComponentFallenOff) + return false; + + // Make atomic visible. for (uint i = 0; i < atomicList.size(); i++) { RwObject* pAtomic = atomicList[i]; int AtomicId = pGame->GetVisibilityPlugins()->GetAtomicId(pAtomic); - if (!(AtomicId & ATOMIC_ID_FLAG_TWO_VERSIONS_DAMAGED)) - { - // Either only one version, or two versions and this is the undamaged one + if ((isComponentDamaged && (AtomicId & ATOMIC_ID_FLAG_TWO_VERSIONS_DAMAGED)) || + (!isComponentDamaged && (AtomicId & ATOMIC_ID_FLAG_TWO_VERSIONS_UNDAMAGED))) pAtomic->flags |= 0x04; - } } } else if (!bRequestVisible && uiNumAtomicsCurrentlyVisible > 0) { // Make all atomics invisible for (uint i = 0; i < atomicList.size(); i++) - atomicList[i]->flags &= ~0x05; // Mimic what GTA seems to do - Not sure what the bottom bit is for + atomicList[i]->flags &= ~0x05; // Mimic what GTA seems to do - Not sure what the bottom bit is for } return true; } @@ -2203,9 +2317,10 @@ bool CVehicleSA::GetComponentVisible(const SString& vehicleComponent, bool& bOut // Count number currently visible uint uiNumAtomicsCurrentlyVisible = 0; - for (uint i = 0; i < atomicList.size(); i++) + for (uint i = 0; i < atomicList.size(); i++) { if (atomicList[i]->flags & 0x04) uiNumAtomicsCurrentlyVisible++; +} // Set result bOutVisible = (uiNumAtomicsCurrentlyVisible > 0); @@ -2352,7 +2467,15 @@ bool CVehicleSA::SetPlateText(const SString& strText) CModelInfo* pModelInfo = pGame->GetModelInfo(GetModelIndex()); if (!pModelInfo) return false; - CVehicleModelInfoSAInterface* pVehicleModelInfo = (CVehicleModelInfoSAInterface*)pModelInfo->GetInterface(); + + auto* pVehicleModelInfo = static_cast(pModelInfo->GetInterface()); + if (!pVehicleModelInfo) + { + pModelInfo->Request(BLOCKING, "SetPlateText"); + pVehicleModelInfo = static_cast(pModelInfo->GetInterface()); + if (!pVehicleModelInfo) + return false; + } // Copy text strncpy(pVehicleModelInfo->plateText, *strText, 8); @@ -2372,13 +2495,10 @@ bool CVehicleSA::SetPlateText(const SString& strText) DWORD dwThis = (DWORD)m_pInterface; DWORD dwFunc = FUNC_CVehicle_CustomCarPlate_TextureCreate; bool bReturn = false; - _asm - { - mov ecx, dwThis - push pVehicleModelInfo - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThis), decltype(pVehicleModelInfo)); +bReturn = reinterpret_cast(dwFunc)(dwThis, pVehicleModelInfo); + // clang-format on return bReturn; } @@ -2401,25 +2521,29 @@ bool CVehicleSA::SetWindowOpenFlagState(unsigned char ucWindow, bool bState) } bool bReturn = false; - _asm - { - mov ecx, dwThis - push ucWindow - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThis), decltype(ucWindow)); +bReturn = reinterpret_cast(dwFunc)(dwThis, ucWindow); + // clang-format on return bReturn; } void CVehicleSA::ReinitAudio() { - auto* audioInterface = m_pVehicleAudioEntity->GetInterface(); + if (!m_pVehicleAudioEntity) + return; + + auto* pAudioInterface = m_pVehicleAudioEntity->GetInterface(); + if (!pAudioInterface) + return; + + CancelVehicleAudioSlots(pAudioInterface); - audioInterface->TerminateAudio(); - audioInterface->InitAudio(GetVehicleInterface()); + pAudioInterface->TerminateAudio(); + pAudioInterface->InitAudio(GetVehicleInterface()); CPed* pLocalPlayer = pGame->GetPedContext(); if (IsPassenger(pLocalPlayer) || GetDriver() == pLocalPlayer) - audioInterface->SoundJoin(); + pAudioInterface->SoundJoin(); } diff --git a/Client/game_sa/CVehicleSA.h b/Client/game_sa/CVehicleSA.h index ceaba79e499..c1246fcb096 100644 --- a/Client/game_sa/CVehicleSA.h +++ b/Client/game_sa/CVehicleSA.h @@ -27,40 +27,46 @@ class CFxSystemSAInterface; class CTrainSAInterface; -class CColModelSAInterface; +struct CColModelSAInterface; struct RwTexture; -#define SIZEOF_CHELI 2584 +#define SIZEOF_CHELI 2584 -#define FUNC_CCarCtrlCreateCarForScript 0x431f80 -#define FUNC_CVehicle_AddVehicleUpgrade 0x6E3290 -#define FUNC_CVehicle_RemoveVehicleUpgrade 0x6DF930 -#define FUNC_CVehicle_GetBaseVehicleType 0x411D50 -#define FUNC_CVehicle_IsUpsideDown 0x6D1D90 -#define FUNC_CVehicle_SetEngineOn 0x41BDD0 -#define FUNC_CVehicle_IsPassenger 0x6D1BD0 -#define FUNC_CTrain_FindPositionOnTrackFromCoors 0x6F6CC0 +// Suspension line sizes for different vehicle types +#define MAX_SUSPENSION_LINES 12 +#define SUSPENSION_SIZE_STANDARD 0x20 // Standard wheel: 32 bytes +#define SUSPENSION_SIZE_BIKE 0x80 // Bike: 128 bytes (2 wheels with extra data) +#define SUSPENSION_SIZE_MONSTER_TRUCK 0x90 // Monster truck: 144 bytes -#define FUNC_CVehicle_QueryPickedUpEntityWithWinch 0x6d3cf0 -#define FUNC_CVehicle_PickUpEntityWithWinch 0x6d3cd0 -#define FUNC_CVehicle_ReleasePickedUpEntityWithWinch 0x6d3cb0 -#define FUNC_CVehicle_SetRopeHeightForHeli 0x6d3d30 +#define FUNC_CCarCtrlCreateCarForScript 0x431f80 +#define FUNC_CVehicle_AddVehicleUpgrade 0x6E3290 +#define FUNC_CVehicle_RemoveVehicleUpgrade 0x6DF930 +#define FUNC_CVehicle_GetBaseVehicleType 0x411D50 +#define FUNC_CVehicle_IsUpsideDown 0x6D1D90 +#define FUNC_CVehicle_SetEngineOn 0x41BDD0 +#define FUNC_CVehicle_IsPassenger 0x6D1BD0 +#define FUNC_CTrain_FindPositionOnTrackFromCoors 0x6F6CC0 -#define FUNC_CVehicle__SetRemapTexDictionary 0x6D0BC0 -#define FUNC_CVehicle__GetRemapIndex 0x6D0B70 -#define FUNC_CVehicle__SetRemap 0x6D0C00 -#define FUNC_CVehicle_CustomCarPlate_TextureCreate 0x6D10E0 +#define FUNC_CVehicle_QueryPickedUpEntityWithWinch 0x6d3cf0 +#define FUNC_CVehicle_PickUpEntityWithWinch 0x6d3cd0 +#define FUNC_CVehicle_ReleasePickedUpEntityWithWinch 0x6d3cb0 +#define FUNC_CVehicle_SetRopeHeightForHeli 0x6d3d30 -#define FUNC_CVehicle_SetWindowOpenFlag 0x6D3080 -#define FUNC_CVehicle_ClearWindowOpenFlag 0x6D30B0 +#define FUNC_CVehicle__SetRemapTexDictionary 0x6D0BC0 +#define FUNC_CVehicle__GetRemapIndex 0x6D0B70 +#define FUNC_CVehicle__SetRemap 0x6D0C00 +#define FUNC_CVehicle_CustomCarPlate_TextureCreate 0x6D10E0 + +#define FUNC_CVehicle_SetWindowOpenFlag 0x6D3080 +#define FUNC_CVehicle_ClearWindowOpenFlag 0x6D30B0 // from CBike -#define FUNC_Bike_PlaceOnRoadProperly 0x6BEEB0 -#define FUNC_Automobile_PlaceOnRoadProperly 0x6AF420 -#define FUNC_CBike_Fix 0x6B7050 +#define FUNC_Bike_PlaceOnRoadProperly 0x6BEEB0 +#define FUNC_Automobile_PlaceOnRoadProperly 0x6AF420 +#define FUNC_CBike_Fix 0x6B7050 // from CPlane -#define FUNC_CPlane__Fix 0x6CABB0 +#define FUNC_CPlane__Fix 0x6CABB0 // from CAutomobile #define FUNC_CAutomobile__Fix 0x6A3440 @@ -68,35 +74,35 @@ struct RwTexture; #define FUNC_CAutomobile__UpdateMovingCollision 0x6a1460 // from CHeli -#define FUNC_CHeli__Fix 0x6C4530 +#define FUNC_CHeli__Fix 0x6C4530 // from CQuadBike -#define FUNC_CQuadBike__Fix 0x6CE2B0 +#define FUNC_CQuadBike__Fix 0x6CE2B0 -#define VARS_CarCounts 0x969094 // 5 values for each vehicle type +#define VARS_CarCounts 0x969094 // 5 values for each vehicle type -#define MAX_PASSENGERS 8 +#define MAX_PASSENGERS 8 -#define NUM_RAILTRACKS 4 -#define ARRAY_NumRailTrackNodes 0xC38014 // NUM_RAILTRACKS dwords -#define ARRAY_RailTrackNodePointers 0xC38024 // NUM_RAILTRACKS pointers to arrays of SRailNode +#define NUM_RAILTRACKS 4 +#define ARRAY_NumRailTrackNodes 0xC38014 // NUM_RAILTRACKS dwords +#define ARRAY_RailTrackNodePointers 0xC38024 // NUM_RAILTRACKS pointers to arrays of SRailNode -#define VAR_CVehicle_SpecialColModels 0xc1cc78 +#define VAR_CVehicle_SpecialColModels 0xc1cc78 #define FUNC_CAutomobile__GetDoorAngleOpenRatio 0x6A2270 #define FUNC_CTrain__GetDoorAngleOpenRatio 0x6F59C0 -#define HANDLING_NOS_Flag 0x00080000 -#define HANDLING_Hydraulics_Flag 0x00020000 +#define HANDLING_NOS_Flag 0x00080000 +#define HANDLING_Hydraulics_Flag 0x00020000 -#define VAR_CVehicle_Variation1 0x8A6458 -#define VAR_CVehicle_Variation2 0x8A6459 +#define VAR_CVehicle_Variation1 0x8A6458 +#define VAR_CVehicle_Variation2 0x8A6459 // for vehicle sun glare #define FUNC_CAutomobile_OnVehiclePreRender 0x6ABCFD #define FUNC_CVehicle_DoSunGlare 0x6DD6F0 -#define FUNC_CHeli_ProcessFlyingCarStuff 0x6C4E7D +#define FUNC_CHeli_ProcessFlyingCarStuff 0x6C4E7D #define FUNC_CPlane_ProcessFlyingCarStuff 0x6CB7D2 // CClumpModelInfo::GetFrameFromName @@ -107,91 +113,91 @@ struct RwTexture; // CBike::m_apModelNodes // CBoat::pBoatParts #define OFFSET_CAutomobile_Nodes 0x648 -#define OFFSET_CTrain_Nodes 0x668 -#define OFFSET_CBike_Nodes 0x5A0 -#define OFFSET_CBoat_Nodes 0x5B0 +#define OFFSET_CTrain_Nodes 0x668 +#define OFFSET_CBike_Nodes 0x5A0 +#define OFFSET_CBoat_Nodes 0x5B0 struct SRailNodeSA { - short sX; // x coordinate times 8 - short sY; // y coordinate times 8 - short sZ; // z coordinate times 8 - WORD sRailDistance; // on-rail distance times 3.33333334 + short sX; // x coordinate times 8 + short sY; // y coordinate times 8 + short sZ; // z coordinate times 8 + WORD sRailDistance; // on-rail distance times 3.33333334 WORD padding; }; struct CVehicleFlags { - unsigned char bIsLawEnforcer : 1; // Is this guy chasing the player at the moment - unsigned char bIsAmbulanceOnDuty : 1; // Ambulance trying to get to an accident - unsigned char bIsFireTruckOnDuty : 1; // Firetruck trying to get to a fire - unsigned char bIsLocked : 1; // Is this guy locked by the script (cannot be removed) - unsigned char bEngineOn : 1; // For sound purposes. Parked cars have their engines switched off (so do destroyed cars) - unsigned char bIsHandbrakeOn : 1; // How's the handbrake doing ? - unsigned char bLightsOn : 1; // Are the lights switched on ? - unsigned char bFreebies : 1; // Any freebies left in this vehicle ? - - unsigned char bIsVan : 1; // Is this vehicle a van (doors at back of vehicle) - unsigned char bIsBus : 1; // Is this vehicle a bus - unsigned char bIsBig : 1; // Is this vehicle a bus - unsigned char bLowVehicle : 1; // Need this for sporty type cars to use low getting-in/out anims - unsigned char bComedyControls : 1; // Will make the car hard to control (hopefully in a funny way) - unsigned char bWarnedPeds : 1; // Has scan and warn peds of danger been processed? - unsigned char bCraneMessageDone : 1; // A crane message has been printed for this car allready + unsigned char bIsLawEnforcer : 1; // Is this guy chasing the player at the moment + unsigned char bIsAmbulanceOnDuty : 1; // Ambulance trying to get to an accident + unsigned char bIsFireTruckOnDuty : 1; // Firetruck trying to get to a fire + unsigned char bIsLocked : 1; // Is this guy locked by the script (cannot be removed) + unsigned char bEngineOn : 1; // For sound purposes. Parked cars have their engines switched off (so do destroyed cars) + unsigned char bIsHandbrakeOn : 1; // How's the handbrake doing ? + unsigned char bLightsOn : 1; // Are the lights switched on ? + unsigned char bFreebies : 1; // Any freebies left in this vehicle ? + + unsigned char bIsVan : 1; // Is this vehicle a van (doors at back of vehicle) + unsigned char bIsBus : 1; // Is this vehicle a bus + unsigned char bIsBig : 1; // Is this vehicle a bus + unsigned char bLowVehicle : 1; // Need this for sporty type cars to use low getting-in/out anims + unsigned char bComedyControls : 1; // Will make the car hard to control (hopefully in a funny way) + unsigned char bWarnedPeds : 1; // Has scan and warn peds of danger been processed? + unsigned char bCraneMessageDone : 1; // A crane message has been printed for this car allready // unsigned char bExtendedRange: 1; // This vehicle needs to be a bit further away to get deleted - unsigned char bTakeLessDamage : 1; // This vehicle is stronger (takes about 1/4 of damage) - - unsigned char bIsDamaged : 1; // This vehicle has been damaged and is displaying all its components - unsigned char bHasBeenOwnedByPlayer : 1; // To work out whether stealing it is a crime - unsigned char bFadeOut : 1; // Fade vehicle out - unsigned char bIsBeingCarJacked : 1; // Fade vehicle out - unsigned char bCreateRoadBlockPeds : 1; // If this vehicle gets close enough we will create peds (coppers or gang members) round it - unsigned char bCanBeDamaged : 1; // Set to FALSE during cut scenes to avoid explosions + unsigned char bTakeLessDamage : 1; // This vehicle is stronger (takes about 1/4 of damage) + + unsigned char bIsDamaged : 1; // This vehicle has been damaged and is displaying all its components + unsigned char bHasBeenOwnedByPlayer : 1; // To work out whether stealing it is a crime + unsigned char bFadeOut : 1; // Fade vehicle out + unsigned char bIsBeingCarJacked : 1; // Fade vehicle out + unsigned char bCreateRoadBlockPeds : 1; // If this vehicle gets close enough we will create peds (coppers or gang members) round it + unsigned char bCanBeDamaged : 1; // Set to FALSE during cut scenes to avoid explosions // unsigned char bUsingSpecialColModel : 1; // Is player vehicle using special collision model, stored in player strucure - unsigned char bOccupantsHaveBeenGenerated : 1; // Is true if the occupants have already been generated. (Shouldn't happen again) - unsigned char bGunSwitchedOff : 1; // Level designers can use this to switch off guns on boats + unsigned char bOccupantsHaveBeenGenerated : 1; // Is true if the occupants have already been generated. (Shouldn't happen again) + unsigned char bGunSwitchedOff : 1; // Level designers can use this to switch off guns on boats - unsigned char bVehicleColProcessed : 1; // Has ProcessEntityCollision been processed for this car? - unsigned char bIsCarParkVehicle : 1; // Car has been created using the special CAR_PARK script command - unsigned char bHasAlreadyBeenRecorded : 1; // Used for replays + unsigned char bVehicleColProcessed : 1; // Has ProcessEntityCollision been processed for this car? + unsigned char bIsCarParkVehicle : 1; // Car has been created using the special CAR_PARK script command + unsigned char bHasAlreadyBeenRecorded : 1; // Used for replays unsigned char bPartOfConvoy : 1; - unsigned char bHeliMinimumTilt : 1; // This heli should have almost no tilt really - unsigned char bAudioChangingGear : 1; // sounds like vehicle is changing gear - unsigned char bIsDrowning : 1; // is vehicle occupants taking damage in water (i.e. vehicle is dead in water) - unsigned char bTyresDontBurst : 1; // If this is set the tyres are invincible + unsigned char bHeliMinimumTilt : 1; // This heli should have almost no tilt really + unsigned char bAudioChangingGear : 1; // sounds like vehicle is changing gear + unsigned char bIsDrowning : 1; // is vehicle occupants taking damage in water (i.e. vehicle is dead in water) + unsigned char bTyresDontBurst : 1; // If this is set the tyres are invincible - unsigned char bCreatedAsPoliceVehicle : 1; // True if this guy was created as a police vehicle (enforcer, policecar, miamivice car etc) - unsigned char bRestingOnPhysical : 1; // Dont go static cause car is sitting on a physical object that might get removed + unsigned char bCreatedAsPoliceVehicle : 1; // True if this guy was created as a police vehicle (enforcer, policecar, miamivice car etc) + unsigned char bRestingOnPhysical : 1; // Dont go static cause car is sitting on a physical object that might get removed unsigned char bParking : 1; unsigned char bCanPark : 1; - unsigned char bFireGun : 1; // Does the ai of this vehicle want to fire it's gun? - unsigned char bDriverLastFrame : 1; // Was there a driver present last frame ? - unsigned char bNeverUseSmallerRemovalRange : 1; // Some vehicles (like planes) we don't want to remove just behind the camera. - unsigned char bIsRCVehicle : 1; // Is this a remote controlled (small) vehicle. True whether the player or AI controls it. - - unsigned char bAlwaysSkidMarks : 1; // This vehicle leaves skidmarks regardless of the wheels' states. - unsigned char bEngineBroken : 1; // Engine doesn't work. Player can get in but the vehicle won't drive - unsigned char bVehicleCanBeTargetted : 1; // The ped driving this vehicle can be targetted, (for Torenos plane mission) - unsigned char bPartOfAttackWave : 1; // This car is used in an attack during a gang war - unsigned char bWinchCanPickMeUp : 1; // This car cannot be picked up by any ropes. - unsigned char bImpounded : 1; // Has this vehicle been in a police impounding garage - unsigned char bVehicleCanBeTargettedByHS : 1; // Heat seeking missiles will not target this vehicle. - unsigned char bSirenOrAlarm : 1; // Set to TRUE if siren or alarm active, else FALSE + unsigned char bFireGun : 1; // Does the ai of this vehicle want to fire it's gun? + unsigned char bDriverLastFrame : 1; // Was there a driver present last frame ? + unsigned char bNeverUseSmallerRemovalRange : 1; // Some vehicles (like planes) we don't want to remove just behind the camera. + unsigned char bIsRCVehicle : 1; // Is this a remote controlled (small) vehicle. True whether the player or AI controls it. + + unsigned char bAlwaysSkidMarks : 1; // This vehicle leaves skidmarks regardless of the wheels' states. + unsigned char bEngineBroken : 1; // Engine doesn't work. Player can get in but the vehicle won't drive + unsigned char bVehicleCanBeTargetted : 1; // The ped driving this vehicle can be targetted, (for Torenos plane mission) + unsigned char bPartOfAttackWave : 1; // This car is used in an attack during a gang war + unsigned char bWinchCanPickMeUp : 1; // This car cannot be picked up by any ropes. + unsigned char bImpounded : 1; // Has this vehicle been in a police impounding garage + unsigned char bVehicleCanBeTargettedByHS : 1; // Heat seeking missiles will not target this vehicle. + unsigned char bSirenOrAlarm : 1; // Set to TRUE if siren or alarm active, else FALSE unsigned char bHasGangLeaningOn : 1; - unsigned char bGangMembersForRoadBlock : 1; // Will generate gang members if NumPedsForRoadBlock > 0 - unsigned char bDoesProvideCover : 1; // If this is false this particular vehicle can not be used to take cover behind. - unsigned char bMadDriver : 1; // This vehicle is driving like a lunatic - unsigned char bUpgradedStereo : 1; // This vehicle has an upgraded stereo - unsigned char bConsideredByPlayer : 1; // This vehicle is considered by the player to enter - unsigned char bPetrolTankIsWeakPoint : 1; // If false shootong the petrol tank will NOT Blow up the car - unsigned char bDisableParticles : 1; // Disable particles from this car. Used in garage. - - unsigned char bHasBeenResprayed : 1; // Has been resprayed in a respray garage. Reset after it has been checked. - unsigned char bUseCarCheats : 1; // If this is true will set the car cheat stuff up in ProcessControl() - unsigned char bDontSetColourWhenRemapping : 1; // If the texture gets remapped we don't want to change the colour with it. - unsigned char bUsedForReplay : 1; // This car is controlled by replay and should be removed when replay is done. + unsigned char bGangMembersForRoadBlock : 1; // Will generate gang members if NumPedsForRoadBlock > 0 + unsigned char bDoesProvideCover : 1; // If this is false this particular vehicle can not be used to take cover behind. + unsigned char bMadDriver : 1; // This vehicle is driving like a lunatic + unsigned char bUpgradedStereo : 1; // This vehicle has an upgraded stereo + unsigned char bConsideredByPlayer : 1; // This vehicle is considered by the player to enter + unsigned char bPetrolTankIsWeakPoint : 1; // If false shootong the petrol tank will NOT Blow up the car + unsigned char bDisableParticles : 1; // Disable particles from this car. Used in garage. + + unsigned char bHasBeenResprayed : 1; // Has been resprayed in a respray garage. Reset after it has been checked. + unsigned char bUseCarCheats : 1; // If this is true will set the car cheat stuff up in ProcessControl() + unsigned char bDontSetColourWhenRemapping : 1; // If the texture gets remapped we don't want to change the colour with it. + unsigned char bUsedForReplay : 1; // This car is controlled by replay and should be removed when replay is done. }; struct CTransmissionGear @@ -204,15 +210,15 @@ struct CTransmissionGear struct CTransmission { CTransmissionGear gears[6]; - byte driveType; - byte engineType; - byte numOfGears; - byte pad; + uint8_t driveType; + uint8_t engineType; + uint8_t numOfGears; + uint8_t pad; DWORD handlingFlags; float engineAcceleration; float engineInertia; float maxGearVelocity; - byte pad2[4]; + uint8_t pad2[4]; float minGearVelocity; float curSpeed; }; @@ -222,7 +228,7 @@ class CAutoPilot BYTE pad[56]; }; -#define MAX_UPGRADES_ATTACHED 15 // perhaps? +#define MAX_UPGRADES_ATTACHED 15 // perhaps? class CVehicleSAInterface : public CPhysicalSAInterface { @@ -286,32 +292,30 @@ class CVehicleSAInterface : public CPhysicalSAInterface ((void(__thiscall*)(CVehicleSAInterface*, RwFrame*, std::uint32_t))0x6D2700)(this, component, state); } - bool IsPassenger(CPedSAInterface* ped) const { - return ((bool(__thiscall*)(CVehicleSAInterface const*, CPedSAInterface*))0x6D1BD0)(this, ped); - } + bool IsPassenger(CPedSAInterface* ped) const { return ((bool(__thiscall*)(CVehicleSAInterface const*, CPedSAInterface*))0x6D1BD0)(this, ped); } - CAEVehicleAudioEntitySAInterface m_VehicleAudioEntity; // 312 + CAEVehicleAudioEntitySAInterface m_VehicleAudioEntity; // 312 - tHandlingDataSA* pHandlingData; // +900 - tFlyingHandlingDataSA* pFlyingHandlingData; // +904 - DWORD dwHandlingFlags; // +908 + tHandlingDataSA* pHandlingData; // +900 + tFlyingHandlingDataSA* pFlyingHandlingData; // +904 + DWORD dwHandlingFlags; // +908 int pad52321[21]; - DWORD dwUnknown1201; // +996 - DWORD dwUnknown1202; // +1000 - unsigned int hFlagsLocal; // +1004 + DWORD dwUnknown1201; // +996 + DWORD dwUnknown1202; // +1000 + unsigned int hFlagsLocal; // +1004 - CAutoPilot AutoPilot; // +1008 - CVehicleFlags m_nVehicleFlags; // +1064? - unsigned int m_TimeOfCreation; // GetTimeInMilliseconds when this vehicle was created. + CAutoPilot AutoPilot; // +1008 + CVehicleFlags m_nVehicleFlags; // +1064? + unsigned int m_TimeOfCreation; // GetTimeInMilliseconds when this vehicle was created. unsigned char m_colour1, m_colour2, m_colour3, m_colour4; char m_comp1, m_comp2; - short m_upgrades[MAX_UPGRADES_ATTACHED]; // 1082 - float m_fWheelScale; // 1112 + short m_upgrades[MAX_UPGRADES_ATTACHED]; // 1082 + float m_fWheelScale; // 1112 - unsigned short CarAlarmState; // 1116 - unsigned short ForcedRandomSeed; // if this is non-zero the random wander gets deterministic + unsigned short CarAlarmState; // 1116 + unsigned short ForcedRandomSeed; // if this is non-zero the random wander gets deterministic CPedSAInterface* pDriver; CPedSAInterface* pPassengers[MAX_PASSENGERS]; @@ -321,38 +325,38 @@ class CVehicleSAInterface : public CPhysicalSAInterface unsigned char m_nGettingOutFlags; unsigned char m_nMaxPassengers; unsigned char m_windowsOpenFlags; - char m_nNitroBoosts; // +1162 + char m_nNitroBoosts; // +1162 // float m_fNitroTimer; // +2212 - unsigned char m_nSpecialColModel; - CEntity* pEntityWeAreOnForVisibilityCheck; - CFireSAInterface* m_pFire; + unsigned char m_nSpecialColModel; + CEntity* pEntityWeAreOnForVisibilityCheck; + CFireSAInterface* m_pFire; - float m_fSteerAngle; // +1172 - float m_f2ndSteerAngle; // used for steering 2nd set of wheels or elevators etc.. - float m_fGasPedal; // 0...1 // +1180 - float m_fBrakePedal; // 0...1 + float m_fSteerAngle; // +1172 + float m_f2ndSteerAngle; // used for steering 2nd set of wheels or elevators etc.. + float m_fGasPedal; // 0...1 // +1180 + float m_fBrakePedal; // 0...1 - unsigned char VehicleCreatedBy; // Contains information on whether this vehicle can be deleted - // or not. Probably only need this or IsLocked. + unsigned char VehicleCreatedBy; // Contains information on whether this vehicle can be deleted + // or not. Probably only need this or IsLocked. short ExtendedRemovalRange; - unsigned char BombOnBoard : 3; // 0 = None. 1 = Timed. 2 = On ignition, 3 = remotely set ? 4 = Timed Bomb has been activated. 5 = On ignition has - // been activated. - unsigned char OverrideLights : 2; // uses enum NO_CAR_LIGHT_OVERRIDE, FORCE_CAR_LIGHTS_OFF, FORCE_CAR_LIGHTS_ON - unsigned char WinchType : 2; // Does this vehicle use a winch? - unsigned char m_GunsCycleIndex : 2; // Cycle through alternate gun hardpoints on planes/helis - unsigned char m_OrdnanceCycleIndex : 2; // Cycle through alternate ordnance hardpoints on planes/helis + unsigned char BombOnBoard : 3; // 0 = None. 1 = Timed. 2 = On ignition, 3 = remotely set ? 4 = Timed Bomb has been activated. 5 = On ignition has + // been activated. + unsigned char OverrideLights : 2; // uses enum NO_CAR_LIGHT_OVERRIDE, FORCE_CAR_LIGHTS_OFF, FORCE_CAR_LIGHTS_ON + unsigned char WinchType : 2; // Does this vehicle use a winch? + unsigned char m_GunsCycleIndex : 2; // Cycle through alternate gun hardpoints on planes/helis + unsigned char m_OrdnanceCycleIndex : 2; // Cycle through alternate ordnance hardpoints on planes/helis - unsigned char nUsedForCover; // Has n number of cops hiding/attempting to hid behind it - unsigned char AmmoInClip; // Used to make the guns on boat do a reload. + unsigned char nUsedForCover; // Has n number of cops hiding/attempting to hid behind it + unsigned char AmmoInClip; // Used to make the guns on boat do a reload. unsigned char PacMansCollected; unsigned char PedsPositionForRoadBlock; unsigned char NumPedsForRoadBlock; // 1200 - float nBodyDirtLevel; // Dirt level of vehicle body texture: 0.0f=fully clean, 15.0f=maximum dirt visible, it may be altered at any time while - // vehicle's cycle of lige + float nBodyDirtLevel; // Dirt level of vehicle body texture: 0.0f=fully clean, 15.0f=maximum dirt visible, it may be altered at any time while + // vehicle's cycle of lige // values used by transmission unsigned char m_nCurrentGear; @@ -362,24 +366,24 @@ class CVehicleSAInterface : public CPhysicalSAInterface float m_fWheelSpinForAudio; // 1216 - float m_nHealth; // 1000.0f = full health. 0 -> explode + float m_nHealth; // 1000.0f = full health. 0 -> explode - CVehicleSAInterface* m_towingVehicle; // 1220 - CVehicleSAInterface* m_trailerVehicle; // 1224 + CVehicleSAInterface* m_towingVehicle; // 1220 + CVehicleSAInterface* m_trailerVehicle; // 1224 - CPedSAInterface* m_bombPlanter; // 1228 - uint32_t m_deleteAfterTime; // 1232 - uint32_t m_lastGunFireTime; // 1236 - uint32_t m_lastBlowUpTime; // 1240 - uint16_t m_policeChaseLeaveCarTimer; // 1244 - uint16_t m_delayedExplosionTimer; // 1246 - void* m_responsibleForDetonation; // 1248 - float m_frontGroundZ; // 1252 - float m_rearGroundZ; // 1256 + CPedSAInterface* m_bombPlanter; // 1228 + uint32_t m_deleteAfterTime; // 1232 + uint32_t m_lastGunFireTime; // 1236 + uint32_t m_lastBlowUpTime; // 1240 + uint16_t m_policeChaseLeaveCarTimer; // 1244 + uint16_t m_delayedExplosionTimer; // 1246 + void* m_responsibleForDetonation; // 1248 + float m_frontGroundZ; // 1252 + float m_rearGroundZ; // 1256 /*** BEGIN SECTION that was added by us ***/ - uint8_t _padding1262[8]; // 1260 - CVehicle* m_pVehicle; // 1268 + uint8_t _padding1262[8]; // 1260 + CVehicle* m_pVehicle; // 1268 /*** END SECTION that was added by us ***/ // 1272 @@ -407,7 +411,7 @@ class CVehicleSAInterface : public CPhysicalSAInterface // 1424 VehicleClass m_vehicleClass; - uint32_t m_vehicleSubClass; + uint32_t m_vehicleSubClass; int16_t m_peviousRemapTxd; int16_t m_remapTxd; @@ -450,6 +454,7 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA ~CVehicleSA(); CVehicleSAInterface* GetVehicleInterface() { return reinterpret_cast(GetInterface()); } + CVehicleSAInterface* GetVehicleInterface() const { return reinterpret_cast(m_pInterface); } void Init(); @@ -577,7 +582,7 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA bool GetVehicleRotorState() const noexcept override { return m_rotorState; } float GetPlaneRotorSpeed(); - unsigned long GetExplodeTime() { return *reinterpret_cast(reinterpret_cast(m_pInterface) + 1240); }; + unsigned long GetExplodeTime() { return *reinterpret_cast(reinterpret_cast(m_pInterface) + 1240); }; char GetNitroCount() { return GetVehicleInterface()->m_nNitroBoosts; } float GetNitroLevel(); @@ -639,9 +644,9 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA SharedUtil::SColor GetHeadLightColor() { return m_HeadLightColor; } void SetHeadLightColor(const SharedUtil::SColor color) { m_HeadLightColor = color; } - bool SpawnFlyingComponent(const eCarNodes& nodeIndex, const eCarComponentCollisionTypes& collisionType, std::int32_t removalTime = -1); - void SetWheelVisibility(eWheelPosition wheel, bool bVisible); - CVector GetWheelPosition(eWheelPosition wheel); + bool SpawnFlyingComponent(const eCarNodes& nodeIndex, const eCarComponentCollisionTypes& collisionType, std::int32_t removalTime = -1); + void SetWheelVisibility(eWheelPosition wheel, bool bVisible); + CVector GetWheelPosition(eWheelPosition wheel); bool IsHeliSearchLightVisible(); void SetHeliSearchLightVisible(bool bVisible); diff --git a/Client/game_sa/CVisibilityPluginsSA.cpp b/Client/game_sa/CVisibilityPluginsSA.cpp index 76aec6ae3d0..b569c99e937 100644 --- a/Client/game_sa/CVisibilityPluginsSA.cpp +++ b/Client/game_sa/CVisibilityPluginsSA.cpp @@ -17,13 +17,10 @@ void CVisibilityPluginsSA::SetClumpAlpha(RpClump* pClump, int iAlpha) { DWORD dwFunc = FUNC_CVisiblityPlugins_SetClumpAlpha; - _asm - { - push iAlpha - push pClump - call dwFunc - add esp, 0x8 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(pClump), decltype(iAlpha)); + reinterpret_cast(dwFunc)(pClump, iAlpha); + // clang-format on } // Some AtomicId bits are: @@ -44,13 +41,10 @@ int CVisibilityPluginsSA::GetAtomicId(RwObject* pAtomic) { DWORD dwFunc = FUNC_CVisibilityPlugins_GetAtomicId; int iResult = 0; - _asm - { - push pAtomic - call dwFunc - add esp, 0x4 - mov iResult, eax - } + // clang-format off + using func_t = decltype(iResult) (__cdecl*)(decltype(pAtomic)); +iResult = reinterpret_cast(dwFunc)(pAtomic); + // clang-format on return iResult; } diff --git a/Client/game_sa/CVisibilityPluginsSA.h b/Client/game_sa/CVisibilityPluginsSA.h index 5daf372ea77..a7cbf2d8c54 100644 --- a/Client/game_sa/CVisibilityPluginsSA.h +++ b/Client/game_sa/CVisibilityPluginsSA.h @@ -13,8 +13,8 @@ #include -#define FUNC_CVisiblityPlugins_SetClumpAlpha 0x732B00 -#define FUNC_CVisibilityPlugins_GetAtomicId 0x732370 +#define FUNC_CVisiblityPlugins_SetClumpAlpha 0x732B00 +#define FUNC_CVisibilityPlugins_GetAtomicId 0x732370 class CVisibilityPluginsSA : public CVisibilityPlugins { diff --git a/Client/game_sa/CWantedSA.cpp b/Client/game_sa/CWantedSA.cpp index 47ea8074740..0b8bb3a7d61 100644 --- a/Client/game_sa/CWantedSA.cpp +++ b/Client/game_sa/CWantedSA.cpp @@ -42,12 +42,10 @@ void CWantedSA::SetWantedLevel(DWORD dwWantedLevel) { DWORD dwThis = (DWORD)GetInterface(); DWORD dwFunc = FUNC_SetWantedLevel; - _asm - { - mov ecx, dwThis - push dwWantedLevel - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThis), decltype(dwWantedLevel)); + reinterpret_cast(dwFunc)(dwThis, dwWantedLevel); + // clang-format on } void CWantedSA::SetWantedLevelNoFlash(DWORD dwWantedLevel) { diff --git a/Client/game_sa/CWantedSA.h b/Client/game_sa/CWantedSA.h index b89376faeed..edf8c0875c1 100644 --- a/Client/game_sa/CWantedSA.h +++ b/Client/game_sa/CWantedSA.h @@ -17,17 +17,17 @@ class CPedSAInterface; -#define FUNC_SetMaximumWantedLevel 0x561E70 -#define FUNC_SetWantedLevel 0x562470 -#define FUNC_SetWantedLevelNoDrop 0x562570 +#define FUNC_SetMaximumWantedLevel 0x561E70 +#define FUNC_SetWantedLevel 0x562470 +#define FUNC_SetWantedLevelNoDrop 0x562570 -#define MAX_CRIMES_QD 16 -#define MAX_COPS_PURSUIT 10 +#define MAX_CRIMES_QD 16 +#define MAX_COPS_PURSUIT 10 class CCrimeBeingQd { public: - DWORD CrimeType; // was eCrimeType + DWORD CrimeType; // was eCrimeType long CrimeID; DWORD TimeOfQing; CVector Coors; @@ -43,18 +43,18 @@ class CWantedSAInterface DWORD m_LastTimeWantedDecreased; DWORD m_LastTimeWantedLevelChanged; DWORD m_TimeOfParole; - float m_fMultiplier; // New crimes have their wanted level contribution multiplied by this + float m_fMultiplier; // New crimes have their wanted level contribution multiplied by this BYTE m_nCopsInPursuit; BYTE m_nMaxCopsInPursuit; BYTE m_nMaxCopCarsInPursuit; BYTE m_nCopsBeatingSuspect; - WORD m_nChanceOnRoadBlock; // /127 for each new roadsegment - BYTE m_PoliceBackOff : 1; // If this is set the police will leave player alone (for cut-scenes) - BYTE m_PoliceBackOffGarage : 1; // If this is set the police will leave player alone (for garages) - BYTE m_EverybodyBackOff : 1; // If this is set then everybody (including police) will leave the player alone (for cut-scenes) - BYTE m_swatRequired : 1; // These three booleans are needed so that the - BYTE m_fbiRequired : 1; // streaming required vehicle stuff can be overrided + WORD m_nChanceOnRoadBlock; // /127 for each new roadsegment + BYTE m_PoliceBackOff : 1; // If this is set the police will leave player alone (for cut-scenes) + BYTE m_PoliceBackOffGarage : 1; // If this is set the police will leave player alone (for garages) + BYTE m_EverybodyBackOff : 1; // If this is set then everybody (including police) will leave the player alone (for cut-scenes) + BYTE m_swatRequired : 1; // These three booleans are needed so that the + BYTE m_fbiRequired : 1; // streaming required vehicle stuff can be overrided BYTE m_armyRequired : 1; DWORD current_chase_time; DWORD current_chase_time_counter; @@ -65,9 +65,9 @@ class CWantedSAInterface CCrimeBeingQd CrimesBeingQd[MAX_CRIMES_QD]; - CPedSAInterface* m_pCopsInPursuit[MAX_COPS_PURSUIT]; // was CCopPed + CPedSAInterface* m_pCopsInPursuit[MAX_COPS_PURSUIT]; // was CCopPed - DWORD m_PoliceScannerAudioEntity; // was CAEPoliceScannerAudioEntity + DWORD m_PoliceScannerAudioEntity; // was CAEPoliceScannerAudioEntity }; class CWantedSA : public CWanted @@ -89,5 +89,10 @@ class CWantedSA : public CWanted // Exported methods void SetWantedLevel(DWORD dwWantedLevel); void SetWantedLevelNoFlash(DWORD dwWantedLevel); - char GetWantedLevel() { return internalInterface->m_WantedLevel; }; + char GetWantedLevel() + { + const std::uint32_t wantedLevel = (internalInterface != nullptr) ? internalInterface->m_WantedLevel : 0u; + const std::uint32_t clampedLevel = (wantedLevel > 6u) ? 6u : wantedLevel; + return static_cast(clampedLevel); + }; }; diff --git a/Client/game_sa/CWaterManagerSA.cpp b/Client/game_sa/CWaterManagerSA.cpp index abc34cffbf4..4c372a2c4a9 100644 --- a/Client/game_sa/CWaterManagerSA.cpp +++ b/Client/game_sa/CWaterManagerSA.cpp @@ -23,9 +23,9 @@ extern int ms_iNumNonDefaultAndNonZeroVertices; using namespace std; -#define POLYENTRY_TYPE(entry) ( (entry)->m_wValue >> 14 ) -#define POLYENTRY_ID(entry) ( (entry)->m_wValue & 0x3FFF ) -#define MAKE_POLYENTRY(type, id) (WORD)( ((type) << 14) | (id) ) +#define POLYENTRY_TYPE(entry) ((entry)->m_wValue >> 14) +#define POLYENTRY_ID(entry) ((entry)->m_wValue & 0x3FFF) +#define MAKE_POLYENTRY(type, id) (WORD)(((type) << 14) | (id)) // These are code references in SA to the various data pools. We relocate these pools // to our own buffers to have more space, and thus have to update all references. @@ -256,10 +256,11 @@ bool CWaterZoneSA::RemovePoly(EWaterPolyType type, WORD wID) { if (pEntries[0].m_wValue == MAKE_POLYENTRY(type, wID) || pEntries[1].m_wValue == MAKE_POLYENTRY(type, wID)) { - if (pEntries[0].m_wValue == MAKE_POLYENTRY(type, wID)) + if (pEntries[0].m_wValue == MAKE_POLYENTRY(type, wID)) { m_pInterface->m_wValue = pEntries[1].m_wValue; - else + } else { m_pInterface->m_wValue = pEntries[0].m_wValue; +} CWaterPolyEntrySAInterface* pEntry = pEntries + 3; for (; pEntry < pEnd; pEntry++) @@ -361,21 +362,21 @@ void CWaterManagerSA::RelocatePools() } } - // - // Fix outside world water blocks disappearing when using long draw distances - // +// +// Fix outside world water blocks disappearing when using long draw distances +// - // GTA default is 70 blocks. We increase this to 512 which is 2^9 - #define OUTSIDE_WORLD_BLOCKS_BITS 9 +// GTA default is 70 blocks. We increase this to 512 which is 2^9 +#define OUTSIDE_WORLD_BLOCKS_BITS 9 static short ms_BlocksToBeRenderedOutsideWorldX[1 << OUTSIDE_WORLD_BLOCKS_BITS]; static short ms_BlocksToBeRenderedOutsideWorldY[1 << OUTSIDE_WORLD_BLOCKS_BITS]; - BYTE part1[] = {0xC1, 0xF8, OUTSIDE_WORLD_BLOCKS_BITS + 1, // sar eax,13 = 2^(10-1) = 512 - 0x7A, 0x19}; // jp part2 Effectively jump always + BYTE part1[] = {0xC1, 0xF8, OUTSIDE_WORLD_BLOCKS_BITS + 1, // sar eax,13 = 2^(10-1) = 512 + 0x7A, 0x19}; // jp part2 Effectively jump always - BYTE part2[] = {0x72, 0xFB, // jc exit Jump if at limit - 0xA1, 0xEC, 0x15, 0xC2, 0x00, // mov eax,NumBlocks Restore eax - 0x73, 0xDE}; // jnc dothing Effectively jump always + BYTE part2[] = {0x72, 0xFB, // jc exit Jump if at limit + 0xA1, 0xEC, 0x15, 0xC2, 0x00, // mov eax,NumBlocks Restore eax + 0x73, 0xDE}; // jnc dothing Effectively jump always MemCpy((void*)0x6E6CE9, part1, sizeof(part1)); MemCpy((void*)0x6E6D07, part2, sizeof(part2)); @@ -396,59 +397,74 @@ void CWaterManagerSA::RelocatePools() // pool; however in MTA, we can dynamically delete water polys, // creating gaps. These hooks make SA skip empty pool slots. -DWORD dwHook6E9E23continue = 0x6E9E29; -void __declspec(naked) Hook6E9E23() +DWORD dwHook6E9E23continue = 0x6E9E29; +static void __declspec(naked) Hook6E9E23() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { -check: - mov eax, dword ptr [edi] - test eax, eax - jnz cont - add edi, 0xA // sizeof(CWaterQuadSAInterface) - jmp check -cont: - movsx eax, word ptr [edi] - lea ebx, [eax+4*eax] - jmp dwHook6E9E23continue + check: + mov eax, dword ptr [edi] + test eax, eax + jnz cont + add edi, 0xA // sizeof(CWaterQuadSAInterface) + jmp check + + cont: + movsx eax, word ptr [edi] + lea ebx, [eax+4*eax] + jmp dwHook6E9E23continue } + // clang-format on } -DWORD dwHook6EFCD7continue = 0x6EFCDD; -DWORD dwHook6EFCD7skip = 0x6EFE5E; -void __declspec(naked) Hook6EFCD7() +DWORD dwHook6EFCD7continue = 0x6EFCDD; +DWORD dwHook6EFCD7skip = 0x6EFE5E; +static void __declspec(naked) Hook6EFCD7() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - mov eax, dword ptr [esi-4] - test eax, eax - jz check - jmp dwHook6EFCD7skip -check: - add esi, 0xA // sizeof(CWaterQuadSAInterface) - mov eax, dword ptr [esi-4] - test eax, eax - jz check - jmp dwHook6EFCD7continue + mov eax, dword ptr [esi-4] + test eax, eax + jz check + jmp dwHook6EFCD7skip + + check: + add esi, 0xA // sizeof(CWaterQuadSAInterface) + mov eax, dword ptr [esi-4] + test eax, eax + jz check + jmp dwHook6EFCD7continue } + // clang-format on } -DWORD dwHook6EFBD8continue = 0x6EFBDE; -void __declspec(naked) Hook6EFBD8() +DWORD dwHook6EFBD8continue = 0x6EFBDE; +static void __declspec(naked) Hook6EFBD8() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { -check: - mov eax, 0x6EFC27 - mov eax, dword ptr [eax] - mov eax, dword ptr [eax+8*esi] - test eax, eax - jnz cont - inc esi - jmp check -cont: + check: + mov eax, 0x6EFC27 + mov eax, dword ptr [eax] + mov eax, dword ptr [eax+8*esi] + test eax, eax + jnz cont + inc esi + jmp check + + cont: jmp dwHook6EFBD8continue } + // clang-format on } void CWaterManagerSA::InstallHooks() @@ -644,7 +660,7 @@ CWaterPoly* CWaterManagerSA::CreateQuad(const CVector& vecBL, const CVector& vec pInterface->m_wVertexIDs[0] = pV1->GetID(); pInterface->m_wVertexIDs[1] = pV2->GetID(); pInterface->m_wVertexIDs[2] = pV3->GetID(); - pInterface->m_wVertexIDs[3] = pV4->GetID(); // This is ok + pInterface->m_wVertexIDs[3] = pV4->GetID(); // This is ok pInterface->m_wFlags = WATER_VISIBLE; if (bShallow) pInterface->m_wFlags |= WATER_SHALLOW; @@ -959,10 +975,11 @@ void CWaterManagerSA::UndoChanges(void* pChangeSource) { while (!m_Changes.empty()) { - if (m_Changes.begin()->first) + if (m_Changes.begin()->first) { UndoChanges(m_Changes.begin()->first); - else - m_Changes.erase(m_Changes.begin()); + } else { + m +}_Changes.erase(m_Changes.begin()); } } else @@ -990,9 +1007,10 @@ void CWaterManagerSA::RebuildIndex() void CWaterManagerSA::ResetWorldWaterLevel() { - if (m_bInitializedVertices) + if (m_bInitializedVertices) { for (DWORD i = 0; i < NUM_DefWaterVertices; i++) m_Vertices[i].Reset(); +} SetOutsideWorldWaterLevel(DEFAULT_WATER_LEVEL); } diff --git a/Client/game_sa/CWaterManagerSA.h b/Client/game_sa/CWaterManagerSA.h index cf249e19e67..db189607c24 100644 --- a/Client/game_sa/CWaterManagerSA.h +++ b/Client/game_sa/CWaterManagerSA.h @@ -15,17 +15,18 @@ #include #include "CWaterSA.h" -#define DEFAULT_WATER_LEVEL 0.0f -#define DEFAULT_WAVE_LEVEL 0.0f - -#define FUNC_ReadWaterConfiguration 0x6EAE80 // () -#define FUNC_CreateWaterVertex 0x6E5A40 // (word x, word y, float z, float unknown, float height, word flow) -#define FUNC_CreateWaterQuad 0x6E7EF0 // (word x1, word y1, float z1, float unknown1, float height1, word flow1, word x2, ..., word x3, ..., word x4, ..., word flags) -#define FUNC_CreateWaterTriangle 0x6E7D40 // (word x1, word y1, float z1, float unknown1, float height1, word flow1, word x2, ..., word x3, ..., word flags) -#define FUNC_BuildWaterIndex 0x6E7B30 // () -#define FUNC_AddWaterPolyToZone 0x6E5750 // (zoneColumn, zoneRow, polyID, polyType) -#define FUNC_GetWaterLevel 0x6EB690 -#define FUNC_TestLineAgainstWater 0x6E61B0 +#define DEFAULT_WATER_LEVEL 0.0f +#define DEFAULT_WAVE_LEVEL 0.0f + +#define FUNC_ReadWaterConfiguration 0x6EAE80 // () +#define FUNC_CreateWaterVertex 0x6E5A40 // (word x, word y, float z, float unknown, float height, word flow) +#define FUNC_CreateWaterQuad \ + 0x6E7EF0 // (word x1, word y1, float z1, float unknown1, float height1, word flow1, word x2, ..., word x3, ..., word x4, ..., word flags) +#define FUNC_CreateWaterTriangle 0x6E7D40 // (word x1, word y1, float z1, float unknown1, float height1, word flow1, word x2, ..., word x3, ..., word flags) +#define FUNC_BuildWaterIndex 0x6E7B30 // () +#define FUNC_AddWaterPolyToZone 0x6E5750 // (zoneColumn, zoneRow, polyID, polyType) +#define FUNC_GetWaterLevel 0x6EB690 +#define FUNC_TestLineAgainstWater 0x6E61B0 typedef void(__cdecl* ReadWaterConfiguration_t)(); typedef WORD(__cdecl* CreateWaterVertex_t)(long lX, long lY, float fZ, float fUnknown, float fHeight, WORD wFlow); @@ -33,27 +34,27 @@ typedef void(__cdecl* BuildWaterIndex_t)(); typedef bool(__cdecl* TestLineAgainstWater_t)(float fStartX, float fStartY, float fStartZ, float fEndX, float fEndY, float fEndZ, CVector* pvecCollision); typedef bool(__cdecl* GetWaterLevel_t)(float fX, float fY, float fZ, float* pfLevel, bool bCheckWaves, CVector* pvecUnknown); -#define VAR_NumWaterVertices 0xC2288C -#define VAR_NumWaterQuads 0xC22888 -#define VAR_NumWaterTriangles 0xC22884 -#define VAR_NumWaterZonePolys 0xC215F0 -#define VAR_WaveLevel 0xC812E8 - -#define NUM_DefWaterVertices 0x3FD // Sizes of pools reserved in gta_sa.exe -#define NUM_DefWaterQuads 0x12D -#define NUM_DefWaterTriangles 0x6 -#define NUM_DefWaterZonePolys 0x2BC -#define NUM_NewWaterVertices 0x600 // Sizes of replacement pools in MTA -#define NUM_NewWaterQuads 0x200 -#define NUM_NewWaterTriangles 0x20 -#define NUM_NewWaterZonePolys 0x400 -#define NUM_WaterZones (12 * 12) - -#define ARRAY_WaterVertices 0xC22910 -#define ARRAY_WaterQuads 0xC21C90 -#define ARRAY_WaterTriangles 0xC22854 -#define ARRAY_WaterZones 0xC21B70 -#define ARRAY_WaterZonePolys 0xC215F8 +#define VAR_NumWaterVertices 0xC2288C +#define VAR_NumWaterQuads 0xC22888 +#define VAR_NumWaterTriangles 0xC22884 +#define VAR_NumWaterZonePolys 0xC215F0 +#define VAR_WaveLevel 0xC812E8 + +#define NUM_DefWaterVertices 0x3FD // Sizes of pools reserved in gta_sa.exe +#define NUM_DefWaterQuads 0x12D +#define NUM_DefWaterTriangles 0x6 +#define NUM_DefWaterZonePolys 0x2BC +#define NUM_NewWaterVertices 0x600 // Sizes of replacement pools in MTA +#define NUM_NewWaterQuads 0x200 +#define NUM_NewWaterTriangles 0x20 +#define NUM_NewWaterZonePolys 0x400 +#define NUM_WaterZones (12 * 12) + +#define ARRAY_WaterVertices 0xC22910 +#define ARRAY_WaterQuads 0xC21C90 +#define ARRAY_WaterTriangles 0xC22854 +#define ARRAY_WaterZones 0xC21B70 +#define ARRAY_WaterZonePolys 0xC215F8 // ------------------------------- // SA interfaces diff --git a/Client/game_sa/CWaterSA.cpp b/Client/game_sa/CWaterSA.cpp index c7435564b49..da3aaeea0ae 100644 --- a/Client/game_sa/CWaterSA.cpp +++ b/Client/game_sa/CWaterSA.cpp @@ -70,10 +70,11 @@ void CWaterVertexSA::OnChangeLevel(float fOldZ, float fNewZ) bool bIsDefaultOrZero = (fNewZ == m_fDefaultZ) || (fNewZ == 0); if (bWasDefaultOrZero != bIsDefaultOrZero) { - if (bWasDefaultOrZero) + if (bWasDefaultOrZero) { ms_iNumNonDefaultAndNonZeroVertices++; - else + } else { ms_iNumNonDefaultAndNonZeroVertices--; +} if (ms_iNumNonDefaultAndNonZeroVertices == 0 || ms_iNumNonDefaultAndNonZeroVertices == 1) g_pWaterManager->UpdateRenderOrderRequirement(); diff --git a/Client/game_sa/CWeaponInfoSA.h b/Client/game_sa/CWeaponInfoSA.h index 3bbb16ddfbe..d362132fbcd 100644 --- a/Client/game_sa/CWeaponInfoSA.h +++ b/Client/game_sa/CWeaponInfoSA.h @@ -17,8 +17,8 @@ class CEntitySAInterface; // Flame shot array for flamethrower flames and maybe molotovs -#define ARRAY_CFlameShotInfo 0xC89690 -#define MAX_FLAME_SHOT_INFOS 100 +#define ARRAY_CFlameShotInfo 0xC89690 +#define MAX_FLAME_SHOT_INFOS 100 #define FUNC_CWeaponInfo_GetWeaponReloadTime 0x743D70 class CFlameShotInfo @@ -36,18 +36,18 @@ class CFlameShotInfo }; static_assert(sizeof(CFlameShotInfo) == 0x2c, "Invalid size for CFlameShotInfo"); -class CWeaponInfoSAInterface // 112 byte long class +class CWeaponInfoSAInterface // 112 byte long class { public: - eFireType m_eFireType; // type - instant hit (e.g. pistol), projectile (e.g. rocket launcher), area effect (e.g. flame thrower) + eFireType m_eFireType; // type - instant hit (e.g. pistol), projectile (e.g. rocket launcher), area effect (e.g. flame thrower) - float m_fTargetRange; // max targeting range - float m_fWeaponRange; // absolute gun range / default melee attack range - int m_modelId; // modelinfo id - int m_modelId2; // second modelinfo id + float m_fTargetRange; // max targeting range + float m_fWeaponRange; // absolute gun range / default melee attack range + int m_modelId; // modelinfo id + int m_modelId2; // second modelinfo id eWeaponSlot m_nWeaponSlot; - int m_nFlags; // flags defining characteristics + int m_nFlags; // flags defining characteristics // instead of storing pointers directly to anims, use anim association groups // NOTE: this is used for stealth kill anims for melee weapons @@ -56,39 +56,39 @@ class CWeaponInfoSAInterface // 112 byte long class ////////////////////////////////// // Gun Data ///////////////////////////////// - short m_nAmmo; // ammo in one clip - short m_nDamage; // damage inflicted per hit - CVector m_vecFireOffset; // offset from weapon origin to projectile starting point + short m_nAmmo; // ammo in one clip + short m_nDamage; // damage inflicted per hit + CVector m_vecFireOffset; // offset from weapon origin to projectile starting point // skill settings - eWeaponSkill m_SkillLevel; // what's the skill level of this weapontype - int m_nReqStatLevel; // what stat level is required for this skill level - float m_fAccuracy; // modify accuracy of weapon - float m_fMoveSpeed; // how fast can move with weapon + eWeaponSkill m_SkillLevel; // what's the skill level of this weapontype + int m_nReqStatLevel; // what stat level is required for this skill level + float m_fAccuracy; // modify accuracy of weapon + float m_fMoveSpeed; // how fast can move with weapon // anim timings - float m_animLoopStart; // start of animation loop - float m_animLoopEnd; // end of animation loop - float m_animFireTime; // time in animation when weapon should be fired + float m_animLoopStart; // start of animation loop + float m_animLoopEnd; // end of animation loop + float m_animFireTime; // time in animation when weapon should be fired - float m_anim2LoopStart; // start of animation2 loop - float m_anim2LoopEnd; // end of animation2 loop - float m_anim2FireTime; // time in animation2 when weapon should be fired + float m_anim2LoopStart; // start of animation2 loop + float m_anim2LoopEnd; // end of animation2 loop + float m_anim2FireTime; // time in animation2 when weapon should be fired - float m_animBreakoutTime; // time after which player can break out of attack and run off + float m_animBreakoutTime; // time after which player can break out of attack and run off // projectile/area effect specific info - float m_fSpeed; // speed of projectile - float m_fRadius; // radius affected - float m_fLifeSpan; // time taken for shot to dissipate - float m_fSpread; // angle inside which shots are created + float m_fSpeed; // speed of projectile + float m_fRadius; // radius affected + float m_fLifeSpan; // time taken for shot to dissipate + float m_fSpread; // angle inside which shots are created - short m_nAimOffsetIndex; // index into array of aiming offsets + short m_nAimOffsetIndex; // index into array of aiming offsets ////////////////////////////////// // Melee Data ///////////////////////////////// - BYTE m_defaultCombo; // base combo for this melee weapon - BYTE m_nCombosAvailable; // how many further combos are available + BYTE m_defaultCombo; // base combo for this melee weapon + BYTE m_nCombosAvailable; // how many further combos are available int GetWeaponReloadTime() { return ((int(__thiscall*)(CWeaponInfoSAInterface*))FUNC_CWeaponInfo_GetWeaponReloadTime)(this); } }; @@ -106,10 +106,10 @@ class CWeaponInfoSA : public CWeaponInfo // DO NOT USE. void SetFlags(int iFlags) { m_pInterface->m_nFlags = iFlags; } // END - void SetFlag(DWORD flag) { m_pInterface->m_nFlags |= flag; } - void ClearFlag(DWORD flag) { m_pInterface->m_nFlags &= ~flag; } - bool IsFlagSet(DWORD flag) { return ((m_pInterface->m_nFlags & flag) > 0 ? true : false); } - short GetFlags() { return m_pInterface->m_nFlags; } + void SetFlag(DWORD flag) { m_pInterface->m_nFlags |= flag; } + void ClearFlag(DWORD flag) { m_pInterface->m_nFlags &= ~flag; } + bool IsFlagSet(DWORD flag) { return ((m_pInterface->m_nFlags & flag) > 0 ? true : false); } + int GetFlags() { return m_pInterface->m_nFlags; } eWeaponModel GetModel() { return (eWeaponModel)m_pInterface->m_modelId; } eWeaponModel GetModel2() { return (eWeaponModel)m_pInterface->m_modelId2; } diff --git a/Client/game_sa/CWeaponSA.cpp b/Client/game_sa/CWeaponSA.cpp index 3d09657c8c5..e19b53ee477 100644 --- a/Client/game_sa/CWeaponSA.cpp +++ b/Client/game_sa/CWeaponSA.cpp @@ -173,9 +173,9 @@ bool CWeaponSA::ProcessLineOfSight(const CVector& vecStart, const CVector& vecEn if (hit) { - if (collisionEntity) + if (collisionEntity) { *entity = collisionEntity->GetInterface(); - else + } else { if (buildingResult->bValid) *entity = buildingResult->pInterface; @@ -183,9 +183,10 @@ bool CWeaponSA::ProcessLineOfSight(const CVector& vecStart, const CVector& vecEn } // Call CWeapon::CheckForShootingVehicleOccupant - if (*entity && (*entity)->nType == ENTITY_TYPE_VEHICLE) + if (*entity && (*entity)->nType == ENTITY_TYPE_VEHICLE) { ((bool(__cdecl*)(CEntitySAInterface**, CColPointSAInterface*, eWeaponType, const CVector&, const CVector&))FUNC_CWeapon_CheckForShootingVehicleOccupant)(entity, (*colCollision)->GetInterface(), weaponType, vecStart, vecEnd); +} return hit; } diff --git a/Client/game_sa/CWeaponSA.h b/Client/game_sa/CWeaponSA.h index 9ef7124493a..5282981d411 100644 --- a/Client/game_sa/CWeaponSA.h +++ b/Client/game_sa/CWeaponSA.h @@ -23,9 +23,9 @@ class CWeaponSAInterface std::uint32_t m_ammoInClip{0}; std::uint32_t m_ammoTotal{0}; std::uint32_t m_timeToNextShootInMS{0}; - bool m_firstPersonEnabled{false}; // Unused - bool m_dontPlaceInHand{false}; // Used in case of goggles - FxSystem_c* m_fxSystem{nullptr}; // Fx system (flamethrower, spraycan, extinguisher) + bool m_firstPersonEnabled{false}; // Unused + bool m_dontPlaceInHand{false}; // Used in case of goggles + FxSystem_c* m_fxSystem{nullptr}; // Fx system (flamethrower, spraycan, extinguisher) void Shutdown() { ((void(__thiscall*)(CWeaponSAInterface*))0x73A380)(this); } void Initialize(eWeaponType weaponType, std::uint32_t ammo, CPedSAInterface* ped) diff --git a/Client/game_sa/CWeaponStatManagerSA.cpp b/Client/game_sa/CWeaponStatManagerSA.cpp index e976a61250f..a446dc46d69 100644 --- a/Client/game_sa/CWeaponStatManagerSA.cpp +++ b/Client/game_sa/CWeaponStatManagerSA.cpp @@ -128,15 +128,17 @@ CWeaponStat* CWeaponStatManagerSA::GetWeaponStatsFromSkillLevel(eWeaponType type { if (pPoor && pPro) { - if (fSkillLevel >= pPro->GetRequiredStatLevel()) + if (fSkillLevel >= pPro->GetRequiredStatLevel()) { return pPro; - else if (fSkillLevel >= pStd->GetRequiredStatLevel()) + } else if (fSkillLevel >= pStd->GetRequiredStatLevel()) { return pStd; - else + } else { return pPoor; +} } - else + else { return pStd; +} } return nullptr; } @@ -518,8 +520,8 @@ void CWeaponStatManagerSA::Init() OriginalNormalWeaponData[33].default_combo = 4; OriginalNormalWeaponData[33].combos_available = 1; // 34 - Sniper - OriginalNormalWeaponData[34].weapon_range = 300.0f; // Default is actually 100; - OriginalNormalWeaponData[34].target_range = 250.0f; // Default is actually 50; + OriginalNormalWeaponData[34].weapon_range = 300.0f; // Default is actually 100; + OriginalNormalWeaponData[34].target_range = 250.0f; // Default is actually 50; OriginalNormalWeaponData[34].accuracy = 1.0f; OriginalNormalWeaponData[34].damage = 125; OriginalNormalWeaponData[34].life_span = 0.0f; @@ -1757,8 +1759,9 @@ eWeaponSkill CWeaponStatManagerSA::GetWeaponSkillFromSkillLevel(eWeaponType type else return WEAPONSKILL_POOR; } - else - return WEAPONSKILL_STD; + else { + r +}eturn WEAPONSKILL_STD; } return WEAPONSKILL_STD; } diff --git a/Client/game_sa/CWeaponStatManagerSA.h b/Client/game_sa/CWeaponStatManagerSA.h index 8446598e2b1..c1b6344f706 100644 --- a/Client/game_sa/CWeaponStatManagerSA.h +++ b/Client/game_sa/CWeaponStatManagerSA.h @@ -15,24 +15,24 @@ #include "CWeaponStatSA.h" // Straight out of CGameSA.h -#define CLASSSIZE_WeaponInfo 112 // ##SA## -#define NUM_WeaponInfosStdSkill WEAPONTYPE_LAST_WEAPONTYPE -#define NUM_WeaponInfosOtherSkill 11 -#define NUM_WeaponInfosTotal (NUM_WeaponInfosStdSkill + (3*NUM_WeaponInfosOtherSkill)) // std, (poor, pro, special) +#define CLASSSIZE_WeaponInfo 112 // ##SA## +#define NUM_WeaponInfosStdSkill WEAPONTYPE_LAST_WEAPONTYPE +#define NUM_WeaponInfosOtherSkill 11 +#define NUM_WeaponInfosTotal (NUM_WeaponInfosStdSkill + (3 * NUM_WeaponInfosOtherSkill)) // std, (poor, pro, special) #define WEAPON_STAT_MAX 112 struct sWeaponInfo { - eFireType fire_type; // type - instant hit (e.g. pistol), projectile (e.g. rocket launcher), area effect (e.g. flame thrower) + eFireType fire_type; // type - instant hit (e.g. pistol), projectile (e.g. rocket launcher), area effect (e.g. flame thrower) - float target_range; // max targeting range - float weapon_range; // absolute gun range / default melee attack range - int model; // modelinfo id - int model2; // second modelinfo id + float target_range; // max targeting range + float weapon_range; // absolute gun range / default melee attack range + int model; // modelinfo id + int model2; // second modelinfo id eWeaponSlot weapon_slot; - int flags; // flags defining characteristics + int flags; // flags defining characteristics // instead of storing pointers directly to anims, use anim association groups // NOTE: this is used for stealth kill anims for melee weapons @@ -41,39 +41,39 @@ struct sWeaponInfo ////////////////////////////////// // Gun Data ///////////////////////////////// - short maximum_clip_ammo; // ammo in one clip - short damage; // damage inflicted per hit - CVector fire_offset; // offset from weapon origin to projectile starting point + short maximum_clip_ammo; // ammo in one clip + short damage; // damage inflicted per hit + CVector fire_offset; // offset from weapon origin to projectile starting point // skill settings - eWeaponSkill skill_level; // what's the skill level of this weapontype - int required_skill_level; // what stat level is required for this skill level - float accuracy; // modify accuracy of weapon - float move_speed; // how fast can move with weapon + eWeaponSkill skill_level; // what's the skill level of this weapontype + int required_skill_level; // what stat level is required for this skill level + float accuracy; // modify accuracy of weapon + float move_speed; // how fast can move with weapon // anim timings - float anim_loop_start; // start of animation loop - float anim_loop_stop; // end of animation loop - float anim_loop_bullet_fire; // time in animation when weapon should be fired + float anim_loop_start; // start of animation loop + float anim_loop_stop; // end of animation loop + float anim_loop_bullet_fire; // time in animation when weapon should be fired - float anim2_loop_start; // start of animation2 loop - float anim2_loop_stop; // end of animation2 loop - float anim2_loop_bullet_fire; // time in animation2 when weapon should be fired + float anim2_loop_start; // start of animation2 loop + float anim2_loop_stop; // end of animation2 loop + float anim2_loop_bullet_fire; // time in animation2 when weapon should be fired - float anim_breakout_time; // time after which player can break out of attack and run off + float anim_breakout_time; // time after which player can break out of attack and run off // projectile/area effect specific info - float firing_speed; // speed of projectile - float radius; // radius affected - float life_span; // time taken for shot to dissipate - float spread; // angle inside which shots are created + float firing_speed; // speed of projectile + float radius; // radius affected + float life_span; // time taken for shot to dissipate + float spread; // angle inside which shots are created - short aim_offset; // index into array of aiming offsets + short aim_offset; // index into array of aiming offsets ////////////////////////////////// // Melee Data ///////////////////////////////// - BYTE default_combo; // base combo for this melee weapon - BYTE combos_available; // how many further combos are available + BYTE default_combo; // base combo for this melee weapon + BYTE combos_available; // how many further combos are available }; class CWeaponStatManagerSA : public CWeaponStatManager diff --git a/Client/game_sa/CWeaponStatSA.h b/Client/game_sa/CWeaponStatSA.h index d89aeff1fd3..960e6671c19 100644 --- a/Client/game_sa/CWeaponStatSA.h +++ b/Client/game_sa/CWeaponStatSA.h @@ -15,7 +15,7 @@ class CWeaponStatSA : public CWeaponStat { public: - CWeaponStatSA(){}; + CWeaponStatSA() {}; CWeaponStatSA(eWeaponType weaponType, eWeaponSkill skillLevel); CWeaponStatSA(CWeaponInfoSA* pWeaponInfo, eWeaponType weaponType, eWeaponSkill skillLevel); ~CWeaponStatSA(); diff --git a/Client/game_sa/CWeatherSA.cpp b/Client/game_sa/CWeatherSA.cpp index 7ebc51469f9..270a0d5be80 100644 --- a/Client/game_sa/CWeatherSA.cpp +++ b/Client/game_sa/CWeatherSA.cpp @@ -16,23 +16,23 @@ static float WEATHER_FAKE_ACCUMULATOR; unsigned char CWeatherSA::Get() { - return *(unsigned char*)0xC81318; // CWeather::ForcedWeatherType + return *(unsigned char*)0xC81318; // CWeather::ForcedWeatherType } void CWeatherSA::Set(unsigned char primary, unsigned char secondary) { - MemPutFast(0xC81320, primary); // CWeather::OldWeatherType - MemPutFast(0xC8131C, secondary); // CWeather::NewWeatherType + MemPutFast(0xC81320, primary); // CWeather::OldWeatherType + MemPutFast(0xC8131C, secondary); // CWeather::NewWeatherType } void CWeatherSA::Release() { - MemPutFast(0xC81318, 0xFF); // CWeather::ForcedWeatherType + MemPutFast(0xC81318, 0xFF); // CWeather::ForcedWeatherType } float CWeatherSA::GetAmountOfRain() { - return *(float*)0xC81324; // CWeather::Rain + return *(float*)0xC81324; // CWeather::Rain } void CWeatherSA::SetAmountOfRain(float fAmount) @@ -44,12 +44,12 @@ void CWeatherSA::SetAmountOfRain(float fAmount) MemSet((void*)0x72BC72, 0x90, 5); // Set the amount of rain - MemPutFast(0xC81324, fAmount); // CWeather::Rain + MemPutFast(0xC81324, fAmount); // CWeather::Rain } void CWeatherSA::ResetAmountOfRain() { - BYTE originalMov[5] = {0xA3, 0x24, 0x13, 0xC8, 0x00}; // 0x72BC72 + BYTE originalMov[5] = {0xA3, 0x24, 0x13, 0xC8, 0x00}; // 0x72BC72 MemCpy((LPVOID)0x72BC72, &originalMov, 5); static constexpr DWORD originalAddr = 0x00C81324; diff --git a/Client/game_sa/CWorldSA.cpp b/Client/game_sa/CWorldSA.cpp index a3b379d0e27..8072ce3a7ef 100644 --- a/Client/game_sa/CWorldSA.cpp +++ b/Client/game_sa/CWorldSA.cpp @@ -10,6 +10,7 @@ *****************************************************************************/ #include "StdInc.h" +#include #include #include #include "CGameSA.h" @@ -77,58 +78,60 @@ bool CWorldSA::ResetSurfaceInfo(short sSurfaceID) return false; } -void HOOK_FallenPeds(); -void HOOK_FallenCars(); +DWORD CONTINUE_CWorld_FallenPeds = 0x00565CBA; +DWORD CONTINUE_CWorld_FallenCars = 0x00565E8A; -void CWorldSA::InstallHooks() +static bool IsUnderWorldWarpEnabled() { - HookInstall(0x565CB0, (DWORD)HOOK_FallenPeds, 5); - HookInstall(0x565E80, (DWORD)HOOK_FallenCars, 5); + return pGame && pGame->IsUnderWorldWarpEnabled(); } -DWORD CONTINUE_CWorld_FallenPeds = 0x00565CBA; -DWORD CONTINUE_CWorld_FallenCars = 0x00565E8A; - -void _declspec(naked) HOOK_FallenPeds() +static void __declspec(naked) HOOK_FallenPeds() { - if (pGame && pGame->IsUnderWorldWarpEnabled()) - { - _asm - { - sub esp, 2Ch - push ebx - mov ebx, ds:0B74490h - jmp CONTINUE_CWorld_FallenPeds - } - } - else + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - _asm - { - ret - } + call IsUnderWorldWarpEnabled + test al, al + jnz continueWithOriginalCode + ret + + continueWithOriginalCode: + sub esp, 2Ch + push ebx + mov ebx, ds:0B74490h + jmp CONTINUE_CWorld_FallenPeds } + // clang-format on } -void _declspec(naked) HOOK_FallenCars() +static void __declspec(naked) HOOK_FallenCars() { - if (pGame && pGame->IsUnderWorldWarpEnabled()) + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - _asm - { - sub esp, 2Ch - push ebx - mov ebx, ds:0B74494h - jmp CONTINUE_CWorld_FallenCars - } - } - else - { - _asm - { - ret - } + call IsUnderWorldWarpEnabled + test al, al + jnz continueWithOriginalCode + ret + + continueWithOriginalCode: + sub esp, 2Ch + push ebx + mov ebx, ds:0B74494h + jmp CONTINUE_CWorld_FallenCars } + // clang-format on +} + +void CWorldSA::InstallHooks() +{ + HookInstall(0x565CB0, (DWORD)HOOK_FallenPeds, 10); + HookInstall(0x565E80, (DWORD)HOOK_FallenCars, 10); } void CWorldSA::Add(CEntity* pEntity, eDebugCaller CallerId) @@ -145,12 +148,10 @@ void CWorldSA::Add(CEntity* pEntity, eDebugCaller CallerId) } DWORD dwEntity = (DWORD)pEntitySA->GetInterface(); DWORD dwFunction = FUNC_Add; - _asm - { - push dwEntity - call dwFunction - add esp, 4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(dwEntity)); + reinterpret_cast(dwFunction)(dwEntity); + // clang-format on } } @@ -162,12 +163,10 @@ void CWorldSA::Add(CEntitySAInterface* entityInterface, eDebugCaller CallerId) SString strMessage("Caller: %i ", CallerId); LogEvent(506, "CWorld::Add ( CEntitySAInterface * ) Crash", "", strMessage); } - _asm - { - push entityInterface - call dwFunction - add esp, 4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(entityInterface)); + reinterpret_cast(dwFunction)(entityInterface); + // clang-format on } void CWorldSA::Remove(CEntity* pEntity, eDebugCaller CallerId) @@ -184,12 +183,10 @@ void CWorldSA::Remove(CEntity* pEntity, eDebugCaller CallerId) } DWORD dwEntity = (DWORD)pInterface; DWORD dwFunction = FUNC_Remove; - _asm - { - push dwEntity - call dwFunction - add esp, 4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(dwEntity)); + reinterpret_cast(dwFunction)(dwEntity); + // clang-format on } } @@ -201,29 +198,20 @@ void CWorldSA::Remove(CEntitySAInterface* entityInterface, eDebugCaller CallerId LogEvent(507, "CWorld::Remove ( CEntitySAInterface * ) Crash", "", strMessage); } DWORD dwFunction = FUNC_Remove; - _asm - { - push entityInterface - call dwFunction - add esp, 4 - - /* mov ecx, entityInterface - mov esi, [ecx] - push 1 - call dword ptr [esi+8]*/ - } + // clang-format off + using func_t = void (__cdecl*)(decltype(entityInterface)); + reinterpret_cast(dwFunction)(entityInterface); + // clang-format on } void CWorldSA::RemoveReferencesToDeletedObject(CEntitySAInterface* entity) { DWORD dwFunc = FUNC_RemoveReferencesToDeletedObject; DWORD dwEntity = (DWORD)entity; - _asm - { - push dwEntity - call dwFunc - add esp, 4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(dwEntity)); + reinterpret_cast(dwFunc)(dwEntity); + // clang-format on } void ConvertMatrixToEulerAngles(const CMatrix_Padded& matrixPadded, float& fX, float& fY, float& fZ) @@ -239,18 +227,12 @@ void ConvertMatrixToEulerAngles(const CMatrix_Padded& matrixPadded, float& fX, f float* pfY = &fY; float* pfZ = &fZ; int iUnknown = 21; - _asm - { - push iUnknown - push pfZ - push pfY - push pfX - mov ecx, pMatrixPadded - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(pMatrixPadded), decltype(pfX), decltype(pfY), decltype(pfZ), decltype(iUnknown)); + reinterpret_cast(dwFunc)(pMatrixPadded, pfX, pfY, pfZ, iUnknown); + // clang-format on } - auto CWorldSA::ProcessLineAgainstMesh(CEntitySAInterface* targetEntity, CVector start, CVector end) -> SProcessLineOfSightMaterialInfoResult { assert(targetEntity); @@ -259,75 +241,82 @@ auto CWorldSA::ProcessLineAgainstMesh(CEntitySAInterface* targetEntity, CVector struct Context { - float minHitDistSq{}; //< [squared] hit distance from the line segment's origin - CVector originOS, endOS, dirOS; //< Line origin, end and dir [in object space] - CMatrix entMat, entInvMat; //< The hit entity's matrix, and it's inverse - RpTriangle* hitTri{}; //< The triangle hit - RpAtomic* hitAtomic{}; //< The atomic of the hit triangle's geometry - RpGeometry* hitGeo{}; //< The geometry of the hit triangle - CVector hitBary{}; //< Barycentric coordinates [on the hit triangle] of the hit - CVector hitPosOS{}; //< Hit position in object space - CEntitySAInterface* entity{}; //< The hit entity + float minHitDistSq{}; //< [squared] hit distance from the line segment's origin + CVector originOS, endOS, dirOS; //< Line origin, end and dir [in object space] + CMatrix entMat, entInvMat; //< The hit entity's matrix, and it's inverse + RpTriangle* hitTri{}; //< The triangle hit + RpAtomic* hitAtomic{}; //< The atomic of the hit triangle's geometry + RpGeometry* hitGeo{}; //< The geometry of the hit triangle + CVector hitBary{}; //< Barycentric coordinates [on the hit triangle] of the hit + CVector hitPosOS{}; //< Hit position in object space + CEntitySAInterface* entity{}; //< The hit entity } c = {}; c.entity = targetEntity; - if (!c.entity->m_pRwObject) { - return ret; // isValid will be false in this case + if (!c.entity->m_pRwObject) + { + return ret; // isValid will be false in this case } // Get matrix, and it's inverse - c.entity->matrix->ConvertToMatrix(c.entMat); + if (c.entity->matrix) { + c.entity->matrix->ConvertToMatrix(c.entMat); + } else + { + c.entMat.SetPosition(c.entity->m_transform.m_translate); + c.entMat.SetRotation(CVector{0.0f, 0.0f, c.entity->m_transform.m_heading}); + } c.entInvMat = c.entMat.Inverse(); // ...to transform the line origin and end into object space c.originOS = c.entInvMat.TransformVector(start); c.endOS = c.entInvMat.TransformVector(end); c.dirOS = c.endOS - c.originOS; - c.minHitDistSq = c.dirOS.LengthSquared(); // By setting it to this value we avoid collisions that would be detected after the line segment + c.minHitDistSq = c.dirOS.LengthSquared(); // By setting it to this value we avoid collisions that would be detected after the line segment // [but are still ont the ray] // Do raycast against the DFF to get hit position material UV and name // This is very slow // Perhaps we could parallelize it somehow? [OpenMP?] const auto ProcessOneAtomic = [](RpAtomic* a, void* data) - { - Context* const c = static_cast(data); - RwFrame* const f = RpAtomicGetFrame(a); + { + Context* const c = static_cast(data); + RwFrame* const f = RpAtomicGetFrame(a); - const auto GetFrameCMatrix = [](RwFrame* f) - { - CMatrix out; - pGame->GetRenderWare()->RwMatrixToCMatrix(*RwFrameGetMatrix(f), out); - return out; - }; + const auto GetFrameCMatrix = [](RwFrame* f) + { + CMatrix out; + pGame->GetRenderWare()->RwMatrixToCMatrix(*RwFrameGetMatrix(f), out); + return out; + }; - // Atomic not visible - if (!a->renderCallback || !(a->object.object.flags & 0x04 /*rpATOMICRENDER*/)) - { - return true; - } + // Atomic not visible + if (!a->renderCallback || !(a->object.object.flags & 0x04 /*rpATOMICRENDER*/)) + { + return true; + } - // Sometimes atomics have no geometry [I don't think that should be possible, but okay] - RpGeometry* const geo = a->geometry; - if (!geo) - { - return true; - } + // Sometimes atomics have no geometry [I don't think that should be possible, but okay] + RpGeometry* const geo = a->geometry; + if (!geo) + { + return true; + } - // Calculate transformation by traversing the hierarchy from the bottom (this frame) -> top (root frame) - CMatrix localToObjTransform{}; - for (RwFrame* i = f; i && i != i->root; i = RwFrameGetParent(i)) - { - localToObjTransform = GetFrameCMatrix(i) * localToObjTransform; - } - const CMatrix objToLocalTransform = localToObjTransform.Inverse(); + // Calculate transformation by traversing the hierarchy from the bottom (this frame) -> top (root frame) + CMatrix localToObjTransform{}; + for (RwFrame* i = f; i && i != i->root; i = RwFrameGetParent(i)) + { + localToObjTransform = GetFrameCMatrix(i) * localToObjTransform; + } + const CMatrix objToLocalTransform = localToObjTransform.Inverse(); - const auto ObjectToLocalSpace = [&](const CVector& in) { return objToLocalTransform.TransformVector(in); }; + const auto ObjectToLocalSpace = [&](const CVector& in) { return objToLocalTransform.TransformVector(in); }; - // Transform from object space, into local (the frame's) space - const CVector localOrigin = ObjectToLocalSpace(c->originOS); - const CVector localEnd = ObjectToLocalSpace(c->endOS); + // Transform from object space, into local (the frame's) space + const CVector localOrigin = ObjectToLocalSpace(c->originOS); + const CVector localEnd = ObjectToLocalSpace(c->endOS); #if 0 if (!CCollisionSA::TestLineSphere( @@ -337,42 +326,42 @@ auto CWorldSA::ProcessLineAgainstMesh(CEntitySAInterface* targetEntity, CVector return true; // Line segment doesn't touch bsp } #endif - const CVector localDir = localEnd - localOrigin; + const CVector localDir = localEnd - localOrigin; - const CVector* const verts = reinterpret_cast(geo->morph_target->verts); // It's fine, trust me bro - for (auto i = geo->triangles_size; i-- > 0;) - { - RpTriangle* const tri = &geo->triangles[i]; + const CVector* const verts = reinterpret_cast(geo->morph_target->verts); // It's fine, trust me bro + for (auto i = geo->triangles_size; i-- > 0;) + { + RpTriangle* const tri = &geo->triangles[i]; - // Process the line against the triangle - CVector hitBary, hitPos; - if (!localOrigin.IntersectsSegmentTriangle(localDir, verts[tri->verts[0]], verts[tri->verts[1]], verts[tri->verts[2]], &hitPos, &hitBary)) - { - continue; // No intersection at all - } + // Process the line against the triangle + CVector hitBary, hitPos; + if (!localOrigin.IntersectsSegmentTriangle(localDir, verts[tri->verts[0]], verts[tri->verts[1]], verts[tri->verts[2]], &hitPos, &hitBary)) + { + continue; // No intersection at all + } - // Intersection, check if it's closer than the previous one - const float hitDistSq = (hitPos - localOrigin).LengthSquared(); - if (c->minHitDistSq > hitDistSq) - { - c->minHitDistSq = hitDistSq; - c->hitGeo = geo; - c->hitAtomic = a; - c->hitTri = tri; - c->hitBary = hitBary; - c->hitPosOS = localToObjTransform.TransformVector(hitPos); // Transform back into object space - } + // Intersection, check if it's closer than the previous one + const float hitDistSq = (hitPos - localOrigin).LengthSquared(); + if (c->minHitDistSq > hitDistSq) + { + c->minHitDistSq = hitDistSq; + c->hitGeo = geo; + c->hitAtomic = a; + c->hitTri = tri; + c->hitBary = hitBary; + c->hitPosOS = localToObjTransform.TransformVector(hitPos); // Transform back into object space } + } - return true; - }; + return true; + }; if (c.entity->m_pRwObject->object.type == 2 /*rpCLUMP*/) { RpClumpForAllAtomics(c.entity->m_pRwObject, ProcessOneAtomic, &c); } else - { // Object is a single atomic, so process directly + { // Object is a single atomic, so process directly ProcessOneAtomic(reinterpret_cast(c.entity->m_pRwObject), &c); } @@ -381,22 +370,39 @@ auto CWorldSA::ProcessLineAgainstMesh(CEntitySAInterface* targetEntity, CVector // Now, calculate texture UV, etc based on the hit [if we've hit anything at all] // Since we have the barycentric coords of the hit, calculating it is easy ret.uv = {}; - for (int i = 0; i < 3; i++) - { - // UV set index - Usually models only use level 0 indices, so let's stick with that - const int uvSetIdx = 0; - // Vertex's UV position - RwTextureCoordinates* const vtxUV = &c.hitGeo->texcoords[uvSetIdx][c.hitTri->verts[i]]; + // Index of the UV set to use + const int uvSetIdx = 0; + + // Check if texcoords exist (some models only have colored mesh without textures) + if (c.hitGeo->texcoords[uvSetIdx]) + { + for (int i = 0; i < 3; i++) + { + // Vertex's UV position + RwTextureCoordinates* const vtxUV = &c.hitGeo->texcoords[uvSetIdx][c.hitTri->verts[i]]; - // Now, just interpolate - ret.uv += CVector2D{vtxUV->u, vtxUV->v} * c.hitBary[i]; + // Now, just interpolate + ret.uv += CVector2D{vtxUV->u, vtxUV->v} * c.hitBary[i]; + } + } + else + { + // No texture coords available, use barycentric coords as UV fallback + ret.uv = CVector2D{c.hitBary.fX, c.hitBary.fY}; } // Find out material texture name // For some reason this is sometimes null - RwTexture* const tex = c.hitGeo->materials.materials[c.hitTri->materialId]->texture; - ret.textureName = tex ? tex->name : nullptr; + if (c.hitGeo->materials.materials && c.hitGeo->materials.materials[c.hitTri->materialId]) + { + RwTexture* const tex = c.hitGeo->materials.materials[c.hitTri->materialId]->texture; + ret.textureName = tex ? tex->name : nullptr; + } + else + { + ret.textureName = nullptr; + } RwFrame* const hitFrame = RpAtomicGetFrame(c.hitAtomic); ret.frameName = hitFrame ? hitFrame->szName : nullptr; @@ -411,8 +417,8 @@ auto CWorldSA::ProcessLineAgainstMesh(CEntitySAInterface* targetEntity, CVector bool CWorldSA::ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd, CColPoint** colCollision, CEntity** CollisionEntity, const SLineOfSightFlags flags, SLineOfSightBuildingResult* pBuildingResult, SProcessLineOfSightMaterialInfoResult* outMatInfo) { - DWORD dwPadding[100]; // stops the function missbehaving and overwriting the return address - dwPadding[0] = 0; // prevent the warning and eventual compiler optimizations from removing it + DWORD dwPadding[100]; // stops the function missbehaving and overwriting the return address + dwPadding[0] = 0; // prevent the warning and eventual compiler optimizations from removing it CColPointSA* pColPointSA = new CColPointSA(); CColPointSAInterface* pColPointSAInterface = pColPointSA->GetInterface(); @@ -427,7 +433,8 @@ bool CWorldSA::ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd // bool bIgnoreSomeObjectsForCamera = false, bool bShootThroughStuff = false MemPutFast(VAR_CWorld_bIncludeCarTires, flags.bCheckCarTires); - _asm + // clang-format off + __asm { push flags.bShootThroughStuff push flags.bIgnoreSomeObjectsForCamera @@ -446,6 +453,7 @@ bool CWorldSA::ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd mov bReturn, al add esp, 0x30 } + // clang-format on MemPutFast(VAR_CWorld_bIncludeCarTires, 0); @@ -459,10 +467,11 @@ bool CWorldSA::ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd { pBuildingResult->bValid = true; pBuildingResult->usModelID = targetEntity->m_nModelIndex; - if (targetEntity->m_pLod) + if (targetEntity->m_pLod) { pBuildingResult->usLODModelID = targetEntity->m_pLod->m_nModelIndex; - else + } else { pBuildingResult->usLODModelID = 0; +} pBuildingResult->pInterface = targetEntity; pBuildingResult->vecPosition = targetEntity->m_transform.m_translate; @@ -477,10 +486,11 @@ bool CWorldSA::ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd { pBuildingResult->bValid = true; pBuildingResult->usModelID = targetEntity->m_nModelIndex; - if (targetEntity->m_pLod) + if (targetEntity->m_pLod) { pBuildingResult->usLODModelID = targetEntity->m_pLod->m_nModelIndex; - else + } else { pBuildingResult->usLODModelID = 0; +} pBuildingResult->pInterface = targetEntity; if (targetEntity->matrix) @@ -490,8 +500,9 @@ bool CWorldSA::ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd ConvertMatrixToEulerAngles(*targetEntity->matrix, vecRotation.fX, vecRotation.fY, vecRotation.fZ); vecRotation = -vecRotation; } - else + else { pBuildingResult->vecPosition = targetEntity->m_transform.m_translate; +} } } } @@ -520,24 +531,37 @@ bool CWorldSA::ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd } } - if (colCollision) + if (colCollision) { *colCollision = pColPointSA; - else + } else { pColPointSA->Destroy(); +} return bReturn; } -CEntity* CWorldSA::TestSphereAgainstWorld(const CVector& sphereCenter, float radius, CEntity* ignoredEntity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool cameraIgnore, STestSphereAgainstWorldResult& result) +CEntity* CWorldSA::TestSphereAgainstWorld(const CVector& sphereCenter, float radius, CEntity* ignoredEntity, bool checkBuildings, bool checkVehicles, + bool checkPeds, bool checkObjects, bool checkDummies, bool cameraIgnore, STestSphereAgainstWorldResult& result) { - auto entity = ((CEntitySAInterface*(__cdecl*)(CVector, float, CEntitySAInterface*, bool, bool, bool, bool, bool, bool))FUNC_CWorld_TestSphereAgainstWorld)(sphereCenter, radius, ignoredEntity ? ignoredEntity->GetInterface() : nullptr, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, cameraIgnore); + auto entity = ((CEntitySAInterface * (__cdecl*)(CVector, float, CEntitySAInterface*, bool, bool, bool, bool, bool, bool)) + FUNC_CWorld_TestSphereAgainstWorld)(sphereCenter, radius, ignoredEntity ? ignoredEntity->GetInterface() : nullptr, checkBuildings, + checkVehicles, checkPeds, checkObjects, checkDummies, cameraIgnore); if (!entity) return nullptr; - + result.collisionDetected = true; result.modelID = entity->m_nModelIndex; - result.entityPosition = entity->matrix->vPos; - ConvertMatrixToEulerAngles(*entity->matrix, result.entityRotation.fX, result.entityRotation.fY, result.entityRotation.fZ); + if (entity->matrix) + { + result.entityPosition = entity->matrix->vPos; + ConvertMatrixToEulerAngles(*entity->matrix, result.entityRotation.fX, result.entityRotation.fY, result.entityRotation.fZ); + } + else + { + result.entityPosition = entity->m_transform.m_translate; + result.entityRotation.fX = result.entityRotation.fY = 0.0f; + result.entityRotation.fZ = entity->m_transform.m_heading * (180.0f / std::numbers::pi_v); + } result.entityRotation = -result.entityRotation; result.lodID = entity->m_pLod ? entity->m_pLod->m_nModelIndex : 0; result.type = static_cast(entity->nType); @@ -562,7 +586,8 @@ float CWorldSA::FindGroundZFor3DPosition(CVector* vecPosition) float fX = vecPosition->fX; float fY = vecPosition->fY; float fZ = vecPosition->fZ; - _asm + // clang-format off + __asm { push 0 push 0 @@ -573,6 +598,7 @@ float CWorldSA::FindGroundZFor3DPosition(CVector* vecPosition) fstp fReturn add esp, 0x14 } + // clang-format on return fReturn; } @@ -590,7 +616,8 @@ bool CWorldSA::IsLineOfSightClear(const CVector* vecStart, const CVector* vecEnd // bool bCheckObjects = true, bool bCheckDummies = true, bool bSeeThroughStuff = false, // bool bIgnoreSomeObjectsForCamera = false - _asm + // clang-format off + __asm { push flags.bIgnoreSomeObjectsForCamera push flags.bSeeThroughStuff @@ -605,6 +632,7 @@ bool CWorldSA::IsLineOfSightClear(const CVector* vecStart, const CVector* vecEnd mov bReturn, al add esp, 0x24 } + // clang-format on return bReturn; } @@ -612,14 +640,10 @@ bool CWorldSA::HasCollisionBeenLoaded(CVector* vecPosition) { DWORD dwFunc = FUNC_HasCollisionBeenLoaded; bool bRet = false; - _asm - { - push 0 - push vecPosition - call dwFunc - mov bRet, al - add esp, 8 - } + // clang-format off + using func_t = decltype(bRet) (__cdecl*)(decltype(vecPosition), decltype(0)); +bRet = reinterpret_cast(dwFunc)(vecPosition, 0); + // clang-format on return bRet; } @@ -633,12 +657,10 @@ void CWorldSA::SetCurrentArea(DWORD dwArea) MemPutFast(VAR_currArea, dwArea); DWORD dwFunc = FUNC_RemoveBuildingsNotInArea; - _asm - { - push dwArea - call dwFunc - add esp, 4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(dwArea)); + reinterpret_cast(dwFunc)(dwArea); + // clang-format on } void CWorldSA::SetJetpackMaxHeight(float fHeight) @@ -675,36 +697,32 @@ void CWorldSA::SetOcclusionsEnabled(bool bEnabled) { if (!bEnabled) { - MemPut(FUNC_COcclusion_ProcessBeforeRendering, 0xC3); // retn + MemPut(FUNC_COcclusion_ProcessBeforeRendering, 0xC3); // retn MemPutFast(VAR_COcclusion_NumActiveOccluders, 0); - MemCpy((void*)CALL_CCullZones_FindTunnelAttributesForCoors, "\xB8\x80\x28\x00\x00", 5); // mov eax, 0x2880 + MemCpy((void*)CALL_CCullZones_FindTunnelAttributesForCoors, "\xB8\x80\x28\x00\x00", 5); // mov eax, 0x2880 } else { - MemPut(FUNC_COcclusion_ProcessBeforeRendering, 0x51); // Standard value - MemCpy((void*)CALL_CCullZones_FindTunnelAttributesForCoors, "\xE8\xDE\x82\x1D\x00", 5); // call 0x72D9F0 + MemPut(FUNC_COcclusion_ProcessBeforeRendering, 0x51); // Standard value + MemCpy((void*)CALL_CCullZones_FindTunnelAttributesForCoors, "\xE8\xDE\x82\x1D\x00", 5); // call 0x72D9F0 } } bool CWorldSA::GetOcclusionsEnabled() { - if (*(BYTE*)FUNC_COcclusion_ProcessBeforeRendering == 0x51) // Is standard value ? + if (*(BYTE*)FUNC_COcclusion_ProcessBeforeRendering == 0x51) // Is standard value ? return true; return false; } void CWorldSA::FindWorldPositionForRailTrackPosition(float fRailTrackPosition, int iTrackId, CVector* pOutVecPosition) { - DWORD dwFunc = FUNC_CWorld_FindPositionForTrackPosition; // __cdecl + DWORD dwFunc = FUNC_CWorld_FindPositionForTrackPosition; // __cdecl - _asm - { - push pOutVecPosition - push iTrackId - push fRailTrackPosition - call dwFunc - add esp, 3*4 - } + // clang-format off + using func_t = void (__cdecl*)(decltype(fRailTrackPosition), decltype(iTrackId), decltype(pOutVecPosition)); + reinterpret_cast(dwFunc)(fRailTrackPosition, iTrackId, pOutVecPosition); + // clang-format on } int CWorldSA::FindClosestRailTrackNode(const CVector& vecPosition, uchar& ucOutTrackId, float& fOutRailDistance) @@ -727,8 +745,10 @@ int CWorldSA::FindClosestRailTrackNode(const CVector& vecPosition, uchar& ucOutT { SRailNodeSA& railNode = aTrackNodes[ucTrackId][i]; - float fDistance = sqrt(pow(vecPosition.fZ - railNode.sZ * 0.125f, 2) + pow(vecPosition.fY - railNode.sY * 0.125f, 2) + - pow(vecPosition.fX - railNode.sX * 0.125f, 2)); + const float fDeltaZ = vecPosition.fZ - railNode.sZ * 0.125f; + const float fDeltaY = vecPosition.fY - railNode.sY * 0.125f; + const float fDeltaX = vecPosition.fX - railNode.sX * 0.125f; + const float fDistance = std::sqrt(fDeltaZ * fDeltaZ + fDeltaY * fDeltaY + fDeltaX * fDeltaX); if (fDistance < fMinDistance) { fMinDistance = fDistance; @@ -892,4 +912,4 @@ namespace 0x10, 0x10, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x04, 0x10, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x01, 0x10, 0x10, 0x00, 0x12, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x01, 0x90, 0x01, 0x00, 0x22, 0x00, 0x00}; static_assert(sizeof(CSurfaceType) == sizeof(aOriginalSurfaceInfo), "invalid size of aOriginalSurfaceInfo"); -} // namespace +} // namespace diff --git a/Client/game_sa/CWorldSA.h b/Client/game_sa/CWorldSA.h index 684cd311afc..6f6d6befd08 100644 --- a/Client/game_sa/CWorldSA.h +++ b/Client/game_sa/CWorldSA.h @@ -13,31 +13,31 @@ #include -#define FUNC_Add 0x563220 -#define FUNC_Remove 0x563280 -#define FUNC_ProcessLineOfSight 0x56BA00 -#define FUNC_FindGroundZFor3DCoord 0x5696C0 -#define FUNC_IsLineOfSightClear 0x56A490 -#define FUNC_HasCollisionBeenLoaded 0x410CE0 -#define FUNC_RemoveBuildingsNotInArea 0x4094B0 -#define FUNC_RemoveReferencesToDeletedObject 0x565510 -#define FUNC_COcclusion_ProcessBeforeRendering 0x7201C0 -#define VAR_COcclusion_NumActiveOccluders 0xC73CC0 -#define CALL_CCullZones_FindTunnelAttributesForCoors 0x55570D -#define FUNC_CWorld_FindPositionForTrackPosition 0x6F59E0 -#define FUNC_CWorld_TestSphereAgainstWorld 0x569E20 +#define FUNC_Add 0x563220 +#define FUNC_Remove 0x563280 +#define FUNC_ProcessLineOfSight 0x56BA00 +#define FUNC_FindGroundZFor3DCoord 0x5696C0 +#define FUNC_IsLineOfSightClear 0x56A490 +#define FUNC_HasCollisionBeenLoaded 0x410CE0 +#define FUNC_RemoveBuildingsNotInArea 0x4094B0 +#define FUNC_RemoveReferencesToDeletedObject 0x565510 +#define FUNC_COcclusion_ProcessBeforeRendering 0x7201C0 +#define VAR_COcclusion_NumActiveOccluders 0xC73CC0 +#define CALL_CCullZones_FindTunnelAttributesForCoors 0x55570D +#define FUNC_CWorld_FindPositionForTrackPosition 0x6F59E0 +#define FUNC_CWorld_TestSphereAgainstWorld 0x569E20 -#define VAR_IgnoredEntity 0xB7CD68 -#define VAR_currArea 0xB72914 -#define ARRAY_StreamSectors 0xB7D0B8 -#define NUM_StreamSectorRows 120 -#define NUM_StreamSectorCols 120 -#define ARRAY_StreamRepeatSectors 0xB992B8 -#define NUM_StreamRepeatSectorRows 16 -#define NUM_StreamRepeatSectorCols 16 -#define VAR_fJetpackMaxHeight 0x8703D8 -#define VTBL_CBUILDING 0x8585C8 -#define VAR_CWorld_bIncludeCarTires 0xB7CD70 +#define VAR_IgnoredEntity 0xB7CD68 +#define VAR_currArea 0xB72914 +#define ARRAY_StreamSectors 0xB7D0B8 +#define NUM_StreamSectorRows 120 +#define NUM_StreamSectorCols 120 +#define ARRAY_StreamRepeatSectors 0xB992B8 +#define NUM_StreamRepeatSectorRows 16 +#define NUM_StreamRepeatSectorCols 16 +#define VAR_fJetpackMaxHeight 0x8703D8 +#define VTBL_CBUILDING 0x8585C8 +#define VAR_CWorld_bIncludeCarTires 0xB7CD70 class CWorldSA : public CWorld { @@ -75,9 +75,10 @@ class CWorldSA : public CWorld void ResetAllSurfaceInfo() override; bool ResetSurfaceInfo(short sSurfaceID) override; - CEntity* TestSphereAgainstWorld(const CVector& sphereCenter, float radius, CEntity* ignoredEntity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool cameraIgnore, STestSphereAgainstWorldResult& result) override; + CEntity* TestSphereAgainstWorld(const CVector& sphereCenter, float radius, CEntity* ignoredEntity, bool checkBuildings, bool checkVehicles, bool checkPeds, + bool checkObjects, bool checkDummies, bool cameraIgnore, STestSphereAgainstWorldResult& result) override; private: - float m_fAircraftMaxHeight; - CSurfaceType* m_pSurfaceInfo; + float m_fAircraftMaxHeight; + CSurfaceType* m_pSurfaceInfo; }; diff --git a/Client/game_sa/HeapTrace.cpp b/Client/game_sa/HeapTrace.cpp index b7513725be6..8b9ce5bc4f0 100644 --- a/Client/game_sa/HeapTrace.cpp +++ b/Client/game_sa/HeapTrace.cpp @@ -13,7 +13,7 @@ #include "HeapTrace.h" #ifdef DETECT_LEAKS -#include + #include using namespace std; struct ALLOC_INFO diff --git a/Client/game_sa/HookSystem.h b/Client/game_sa/HookSystem.h index 3222c850291..5dfdc3aac79 100644 --- a/Client/game_sa/HookSystem.h +++ b/Client/game_sa/HookSystem.h @@ -11,7 +11,35 @@ #pragma once -#define MAX_JUMPCODE_SIZE 20 +#define MAX_JUMPCODE_SIZE 20 + +#include "gamesa_init.h" +#include + +#pragma warning(disable : 4102) // unreferenced label + +// This macro adds an unreferenced label to your '__declspec(naked)' hook functions, to +// point to the value of __LOCAL_SIZE, which will be examined by an external tool after +// compilation, and it must be zero. +// +// The Microsoft Visual C++ compiler (MSVC) expects you, the developer, to allocate space for +// local variables on the stack frame in custom prolog code. In the MSVC implementation of the +// C++17 language standard, the compiler started to use local space for certain statements, +// for which we will never support any sort of local space, in naked hook functions. +// https://learn.microsoft.com/en-us/cpp/cpp/considerations-for-writing-prolog-epilog-code +// https://developercommunity.visualstudio.com/t/stack-access-broken-in-naked-function/549628 +// +// IMPORTANT: We can't use static_assert because __LOCAL_SIZE is not a compile-time constant. +// If you're going to change this macro, then copy your changes to the copy in multiplayer_sa. +#define MTA_VERIFY_HOOK_LOCAL_SIZE \ + { \ + __asm { push eax } \ + ; \ + __asm { _localSize: mov eax, __LOCAL_SIZE } \ + ; \ + __asm { pop eax } \ + ; \ + } template void* FunctionPointerToVoidP(T func) @@ -24,6 +52,8 @@ void* FunctionPointerToVoidP(T func) return c.b; } +BYTE* CreateJump(DWORD dwFrom, DWORD dwTo, BYTE* ByteArray); + void HookInstallCall(DWORD dwInstallAddress, DWORD dwHookFunction); template @@ -42,11 +72,8 @@ bool HookInstall(DWORD dwInstallAddress, T dwHookHandler, int iJmpCodeSize = 5) } } -BYTE* CreateJump(DWORD dwFrom, DWORD dwTo, BYTE* ByteArray); - // Auto detect requirement of US/EU hook installation -#define EZHookInstall(type) \ - HookInstall(HOOKPOS_##type, (DWORD)HOOK_##type, HOOKSIZE_##type); +#define EZHookInstall(type) HookInstall(HOOKPOS_##type, (DWORD)HOOK_##type, HOOKSIZE_##type); // Structure for holding hook info struct SHookInfo @@ -60,7 +87,7 @@ struct SHookInfo uint uiSize; }; -#define MAKE_HOOK_INFO(type) SHookInfo ( HOOKPOS_##type, HOOK_##type, HOOKSIZE_##type ) +#define MAKE_HOOK_INFO(type) SHookInfo(HOOKPOS_##type, HOOK_##type, HOOKSIZE_##type) // Structure for holding poke info struct SPokeInfo diff --git a/Client/game_sa/MemSA.h b/Client/game_sa/MemSA.h index 7cb69371017..8f3edf443d6 100644 --- a/Client/game_sa/MemSA.h +++ b/Client/game_sa/MemSA.h @@ -13,27 +13,27 @@ namespace MemSA { - size_t msize(const void* p) + inline size_t msize(const void* p) { - using gta_msize = size_t (*__cdecl)(const void*); - return ((gta_msize)0x828C4A)(p); + using gta_msize = size_t (*)(const void*); + return reinterpret_cast(0x828C4A)(p); }; - void* malloc(size_t count) + inline void* malloc(size_t count) { - using gta_malloc = void* (*__cdecl)(size_t a1); - return ((gta_malloc)0x824257)(count); + using gta_malloc = void* (*)(size_t); + return reinterpret_cast(0x824257)(count); }; - template + template T* malloc_struct(size_t count) { return static_cast(MemSA::malloc(sizeof(T) * count)); } - void free(void* p) + inline void free(void* p) { - using gta_free = void (*__cdecl)(void* p); - return ((gta_free)0x82413F)(p); + using gta_free = void (*)(void*); + return reinterpret_cast(0x82413F)(p); }; } diff --git a/Client/game_sa/StdInc.h b/Client/game_sa/StdInc.h index d07dc2ec05d..21ae95fb78c 100644 --- a/Client/game_sa/StdInc.h +++ b/Client/game_sa/StdInc.h @@ -3,26 +3,31 @@ // illegal instruction size // The instruction did not have a form with the specified size. The smallest legal size was used. -#pragma warning (disable:4409) +#pragma warning(disable : 4409) // 'class1' : inherits 'class2::member' via dominance // Two or more members have the same name. The one in class2 is inherited because it is a base class for the other classes that contained this member. -#pragma warning (disable:4250) +#pragma warning(disable : 4250) #include -#define MTA_CLIENT -#define SHARED_UTIL_WITH_HASH_MAP -#define SHARED_UTIL_WITH_FAST_HASH_MAP -#include "SharedUtil.h" -#include "SharedUtil.MemAccess.h" -#include #include +#include #include #include #include #include +#include +#include #include +#include + +#define MTA_CLIENT +#define SHARED_UTIL_WITH_HASH_MAP +#define SHARED_UTIL_WITH_FAST_HASH_MAP +#define MTASA_EXPORT_SHARED_UTIL +#include "SharedUtil.h" +#include "SharedUtil.MemAccess.h" // Game includes #include "HookSystem.h" diff --git a/Client/game_sa/TaskAttackSA.cpp b/Client/game_sa/TaskAttackSA.cpp index 49c89b1ea74..6fa40279fb8 100644 --- a/Client/game_sa/TaskAttackSA.cpp +++ b/Client/game_sa/TaskAttackSA.cpp @@ -23,17 +23,10 @@ CTaskSimpleGangDriveBySA::CTaskSimpleGangDriveBySA(CEntity* pTargetEntity, const DWORD dwFunc = FUNC_CTaskSimpleGangDriveBy__Constructor; DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwTargetEntity = (pTargetEntity) ? (DWORD)pTargetEntity->GetInterface() : 0; - _asm - { - mov ecx, dwThisInterface - push bSeatRHS - push nDrivebyStyle - push FrequencyPercentage - push fAbortRange - push pVecTarget - push dwTargetEntity - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwTargetEntity), decltype(pVecTarget), decltype(fAbortRange), decltype(FrequencyPercentage), decltype(nDrivebyStyle), decltype(bSeatRHS)); + reinterpret_cast(dwFunc)(dwThisInterface, dwTargetEntity, pVecTarget, fAbortRange, FrequencyPercentage, nDrivebyStyle, bSeatRHS); + // clang-format on } CTaskSimpleUseGunSA::CTaskSimpleUseGunSA(CEntity* pTargetEntity, CVector vecTarget, char nCommand, short nBurstLength, unsigned char bAimImmediate) @@ -46,18 +39,10 @@ CTaskSimpleUseGunSA::CTaskSimpleUseGunSA(CEntity* pTargetEntity, CVector vecTarg DWORD dwTargetEntity = (pTargetEntity) ? (DWORD)pTargetEntity->GetInterface() : 0; float fTargetX = vecTarget.fX, fTargetY = vecTarget.fY, fTargetZ = vecTarget.fZ; DWORD dwBurstLength = nBurstLength; - _asm - { - mov ecx, dwThisInterface - push bAimImmediate - push dwBurstLength - push nCommand - push fTargetZ - push fTargetY - push fTargetX - push dwTargetEntity - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwTargetEntity), decltype(fTargetX), decltype(fTargetY), decltype(fTargetZ), decltype(nCommand), decltype(dwBurstLength), decltype(bAimImmediate)); + reinterpret_cast(dwFunc)(dwThisInterface, dwTargetEntity, fTargetX, fTargetY, fTargetZ, nCommand, dwBurstLength, bAimImmediate); + // clang-format on } bool CTaskSimpleUseGunSA::SetPedPosition(CPed* pPed) @@ -73,13 +58,10 @@ bool CTaskSimpleUseGunSA::SetPedPosition(CPed* pPed) BYTE currentWeaponSlot = dwPedInterface->bCurrentWeaponSlot; - _asm - { - mov ecx, dwThisInterface - push dwPedInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface)); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface); + // clang-format on return bReturn; } @@ -88,13 +70,10 @@ void CTaskSimpleUseGunSA::FireGun(CPed* pPed, bool bFlag) DWORD dwFunc = FUNC_CTaskSimpleUseGun_FireGun; DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwPedInterface = (DWORD)pPed->GetInterface(); - _asm - { - mov ecx, dwThisInterface - push bFlag - push dwPedInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface), decltype(bFlag)); + reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface, bFlag); + // clang-format on } bool CTaskSimpleUseGunSA::ControlGun(CPed* pPed, CEntity* pTargetEntity, char nCommand) @@ -104,15 +83,10 @@ bool CTaskSimpleUseGunSA::ControlGun(CPed* pPed, CEntity* pTargetEntity, char nC DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwPedInterface = (DWORD)pPed->GetInterface(); DWORD dwTargetEntity = (pTargetEntity) ? (DWORD)pTargetEntity->GetInterface() : 0; - _asm - { - mov ecx, dwThisInterface - push nCommand - push dwTargetEntity - push dwPedInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface), decltype(dwTargetEntity), decltype(nCommand)); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface, dwTargetEntity, nCommand); + // clang-format on return bReturn; } @@ -121,13 +95,10 @@ bool CTaskSimpleUseGunSA::ControlGunMove(CVector2D* pMoveVec) bool bReturn; DWORD dwFunc = FUNC_CTaskSimpleUseGun_ControlGunMove; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push pMoveVec - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface), decltype(pMoveVec)); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface, pMoveVec); + // clang-format on return bReturn; } @@ -139,18 +110,10 @@ void CTaskSimpleUseGunSA::Reset(CPed* pPed, CEntity* pTargetEntity, CVector vecT DWORD dwTargetEntity = (pTargetEntity) ? (DWORD)pTargetEntity->GetInterface() : 0; float fTargetX = vecTarget.fX, fTargetY = vecTarget.fY, fTargetZ = vecTarget.fZ; DWORD dwBurstLength = nBurstLength; - _asm - { - mov ecx, dwThisInterface - push dwBurstLength - push nCommand - push fTargetZ - push fTargetY - push fTargetX - push dwTargetEntity - push dwPedInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface), decltype(dwTargetEntity), decltype(fTargetX), decltype(fTargetY), decltype(fTargetZ), decltype(nCommand), decltype(dwBurstLength)); + reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface, dwTargetEntity, fTargetX, fTargetY, fTargetZ, nCommand, dwBurstLength); + // clang-format on } int CTaskSimpleUseGunSA::GetTaskType() @@ -158,12 +121,10 @@ int CTaskSimpleUseGunSA::GetTaskType() int iReturn; DWORD dwFunc = FUNC_CTaskSimpleUseGun_GetTaskType; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - call dwFunc - mov iReturn, eax - } + // clang-format off + using func_t = decltype(iReturn) (__thiscall*)(decltype(dwThisInterface) ); +iReturn = reinterpret_cast(dwFunc)(dwThisInterface); + // clang-format on return iReturn; } @@ -175,15 +136,10 @@ bool CTaskSimpleUseGunSA::MakeAbortable(CPed* pPed, int iPriority, CEvent const* DWORD dwFunc = FUNC_CTaskSimpleUseGun_MakeAbortable; DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwPedInterface = (DWORD)pPed->GetInterface(); - _asm - { - mov ecx, dwThisInterface - push pEvent - push iPriority - push dwPedInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface), decltype(iPriority), decltype(pEvent)); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface, iPriority, pEvent); + // clang-format on return bReturn; } @@ -193,13 +149,10 @@ bool CTaskSimpleUseGunSA::ProcessPed(CPed* pPed) DWORD dwFunc = FUNC_CTaskSimpleUseGun_ProcessPed; DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwPedInterface = (DWORD)pPed->GetInterface(); - _asm - { - mov ecx, dwThisInterface - push dwPedInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface)); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface); + // clang-format on return bReturn; } @@ -208,12 +161,10 @@ void CTaskSimpleUseGunSA::AbortIK(CPed* pPed) DWORD dwFunc = FUNC_CTaskSimpleUseGun_AbortIK; DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwPedInterface = (DWORD)pPed->GetInterface(); - _asm - { - mov ecx, dwThisInterface - push dwPedInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface)); + reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface); + // clang-format on } void CTaskSimpleUseGunSA::AimGun(CPed* pPed) @@ -221,12 +172,10 @@ void CTaskSimpleUseGunSA::AimGun(CPed* pPed) DWORD dwFunc = FUNC_CTaskSimpleUseGun_AimGun; DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwPedInterface = (DWORD)pPed->GetInterface(); - _asm - { - mov ecx, dwThisInterface - push dwPedInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface)); + reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface); + // clang-format on } void CTaskSimpleUseGunSA::ClearAnim(CPed* pPed) @@ -234,12 +183,10 @@ void CTaskSimpleUseGunSA::ClearAnim(CPed* pPed) DWORD dwFunc = FUNC_CTaskSimpleUseGun_ClearAnim; DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwPedInterface = (DWORD)pPed->GetInterface(); - _asm - { - mov ecx, dwThisInterface - push dwPedInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface)); + reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface); + // clang-format on } signed char CTaskSimpleUseGunSA::GetCurrentCommand() @@ -247,12 +194,10 @@ signed char CTaskSimpleUseGunSA::GetCurrentCommand() signed char bReturn; DWORD dwFunc = FUNC_CTaskSimpleUseGun_GetCurrentCommand; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface) ); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface); + // clang-format on return bReturn; } @@ -261,12 +206,10 @@ bool CTaskSimpleUseGunSA::GetDoneFiring() bool bReturn; DWORD dwFunc = FUNC_CTaskSimpleUseGun_GetDoneFiring; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface) ); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface); + // clang-format on return bReturn; } @@ -275,12 +218,10 @@ bool CTaskSimpleUseGunSA::GetIsFinished() bool bReturn; DWORD dwFunc = FUNC_CTaskSimpleUseGun_GetIsFinished; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface) ); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface); + // clang-format on return bReturn; } @@ -289,12 +230,10 @@ bool CTaskSimpleUseGunSA::IsLineOfSightBlocked() bool bReturn; DWORD dwFunc = FUNC_CTaskSimpleUseGun_IsLineOfSightBlocked; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface) ); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface); + // clang-format on return bReturn; } @@ -303,12 +242,10 @@ bool CTaskSimpleUseGunSA::GetIsFiring() bool bReturn; DWORD dwFunc = FUNC_CTaskSimpleUseGun_GetIsFiring; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface) ); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface); + // clang-format on return bReturn; } @@ -317,12 +254,10 @@ bool CTaskSimpleUseGunSA::GetIsReloading() bool bReturn; DWORD dwFunc = FUNC_CTaskSimpleUseGun_GetIsReloading; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface) ); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface); + // clang-format on return bReturn; } @@ -331,12 +266,10 @@ bool CTaskSimpleUseGunSA::GetSkipAim() bool bReturn; DWORD dwFunc = FUNC_CTaskSimpleUseGun_GetSkipAim; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface) ); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface); + // clang-format on return bReturn; } @@ -345,12 +278,10 @@ bool CTaskSimpleUseGunSA::PlayerPassiveControlGun() bool bReturn; DWORD dwFunc = FUNC_CTaskSimpleUseGun_PlayerPassiveControlGun; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface) ); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface); + // clang-format on return bReturn; } @@ -359,13 +290,10 @@ void CTaskSimpleUseGunSA::RemoveStanceAnims(CPed* pPed, float f) DWORD dwFunc = FUNC_CTaskSimpleUseGun_RemoveStanceAnims; DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwPedInterface = (DWORD)pPed->GetInterface(); - _asm - { - mov ecx, dwThisInterface - push f - push dwPedInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface), decltype(f)); + reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface, f); + // clang-format on } bool CTaskSimpleUseGunSA::RequirePistolWhip(CPed* pPed, CEntity* pTargetEntity) @@ -374,13 +302,10 @@ bool CTaskSimpleUseGunSA::RequirePistolWhip(CPed* pPed, CEntity* pTargetEntity) DWORD dwFunc = FUNC_CTaskSimpleUseGun_ControlGun; DWORD dwPedInterface = (DWORD)pPed->GetInterface(); DWORD dwTargetEntity = (pTargetEntity) ? (DWORD)pTargetEntity->GetInterface() : 0; - _asm - { - push dwTargetEntity - push dwPedInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__cdecl*)(decltype(dwPedInterface), decltype(dwTargetEntity)); +bReturn = reinterpret_cast(dwFunc)(dwPedInterface, dwTargetEntity); + // clang-format on return bReturn; } @@ -388,12 +313,10 @@ void CTaskSimpleUseGunSA::SetBurstLength(short a) { DWORD dwFunc = FUNC_CTaskSimpleUseGun_SetBurstLength; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push a - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(a)); + reinterpret_cast(dwFunc)(dwThisInterface, a); + // clang-format on } void CTaskSimpleUseGunSA::SetMoveAnim(CPed* pPed) @@ -401,12 +324,10 @@ void CTaskSimpleUseGunSA::SetMoveAnim(CPed* pPed) DWORD dwFunc = FUNC_CTaskSimpleUseGun_SetMoveAnim; DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwPedInterface = (DWORD)pPed->GetInterface(); - _asm - { - mov ecx, dwThisInterface - push dwPedInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface)); + reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface); + // clang-format on } void CTaskSimpleUseGunSA::StartAnim(class CPed* pPed) @@ -414,25 +335,20 @@ void CTaskSimpleUseGunSA::StartAnim(class CPed* pPed) DWORD dwFunc = FUNC_CTaskSimpleUseGun_StartAnim; DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwPedInterface = (DWORD)pPed->GetInterface(); - _asm - { - mov ecx, dwThisInterface - push dwPedInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface)); + reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface); + // clang-format on } void CTaskSimpleUseGunSA::StartCountDown(unsigned char a, bool b) { DWORD dwFunc = FUNC_CTaskSimpleUseGun_StartCountDown; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push b - push a - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(a), decltype(b)); + reinterpret_cast(dwFunc)(dwThisInterface, a, b); + // clang-format on } CTaskSimpleFightSA::CTaskSimpleFightSA(CEntity* pTargetEntity, int nCommand, unsigned int nIdlePeriod) @@ -443,12 +359,8 @@ CTaskSimpleFightSA::CTaskSimpleFightSA(CEntity* pTargetEntity, int nCommand, uns DWORD dwFunc = FUNC_CTaskSimpleFight__Constructor; DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwTargetEntity = (pTargetEntity) ? (DWORD)pTargetEntity->GetInterface() : 0; - _asm - { - mov ecx, dwThisInterface - push nIdlePeriod - push nCommand - push dwTargetEntity - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwTargetEntity), decltype(nCommand), decltype(nIdlePeriod)); + reinterpret_cast(dwFunc)(dwThisInterface, dwTargetEntity, nCommand, nIdlePeriod); + // clang-format on } diff --git a/Client/game_sa/TaskAttackSA.h b/Client/game_sa/TaskAttackSA.h index 8c9ea026cd4..9e6293e2f56 100644 --- a/Client/game_sa/TaskAttackSA.h +++ b/Client/game_sa/TaskAttackSA.h @@ -17,34 +17,34 @@ class CWeaponInfo; -#define FUNC_CTaskSimpleGangDriveBy__Constructor 0x6217d0 -#define FUNC_CTaskSimpleUseGun__Constructor 0x61de60 -#define FUNC_CTaskSimpleUseGun_ControlGun 0x61e040 -#define FUNC_CTaskSimpleUseGun_ControlGunMove 0x61e0c0 -#define FUNC_CTaskSimpleUseGun_Reset 0x624dc0 -#define FUNC_CTaskSimpleFight__Constructor 0x61c470 -#define FUNC_CTaskSimpleUseGun_SetPedPosition 0x624ED0 -#define FUNC_CTaskSimpleUseGun_FireGun 0x61EB10 -#define FUNC_CTaskSimpleUseGun_GetTaskType 0x61DF20 -#define FUNC_CTaskSimpleUseGun_MakeAbortable 0x624E30 -#define FUNC_CTaskSimpleUseGun_ProcessPed 0x62A380 -#define FUNC_CTaskSimpleUseGun_AbortIK 0x61DFA0 -#define FUNC_CTaskSimpleUseGun_AimGun 0x61ED10 -#define FUNC_CTaskSimpleUseGun_ClearAnim 0x61E190 -#define FUNC_CTaskSimpleUseGun_GetCurrentCommand 0x4ABE30 -#define FUNC_CTaskSimpleUseGun_GetDoneFiring 0x61C220 -#define FUNC_CTaskSimpleUseGun_GetIsFinished 0x61C240 -#define FUNC_CTaskSimpleUseGun_IsLineOfSightBlocked 0x61C250 -#define FUNC_CTaskSimpleUseGun_GetIsFiring 0x509950 -#define FUNC_CTaskSimpleUseGun_GetIsReloading 0x609340 -#define FUNC_CTaskSimpleUseGun_GetSkipAim 0x588840 -#define FUNC_CTaskSimpleUseGun_PlayerPassiveControlGun 0x61E0A0 -#define FUNC_CTaskSimpleUseGun_RemoveStanceAnims 0x61E8E0 -#define FUNC_CTaskSimpleUseGun_RequirePistolWhip 0x61E200 -#define FUNC_CTaskSimpleUseGun_SetBurstLength 0x61C210 -#define FUNC_CTaskSimpleUseGun_SetMoveAnim 0x61E3F0 -#define FUNC_CTaskSimpleUseGun_StartAnim 0x624F30 -#define FUNC_CTaskSimpleUseGun_StartCountDown 0x61E160 +#define FUNC_CTaskSimpleGangDriveBy__Constructor 0x6217d0 +#define FUNC_CTaskSimpleUseGun__Constructor 0x61de60 +#define FUNC_CTaskSimpleUseGun_ControlGun 0x61e040 +#define FUNC_CTaskSimpleUseGun_ControlGunMove 0x61e0c0 +#define FUNC_CTaskSimpleUseGun_Reset 0x624dc0 +#define FUNC_CTaskSimpleFight__Constructor 0x61c470 +#define FUNC_CTaskSimpleUseGun_SetPedPosition 0x624ED0 +#define FUNC_CTaskSimpleUseGun_FireGun 0x61EB10 +#define FUNC_CTaskSimpleUseGun_GetTaskType 0x61DF20 +#define FUNC_CTaskSimpleUseGun_MakeAbortable 0x624E30 +#define FUNC_CTaskSimpleUseGun_ProcessPed 0x62A380 +#define FUNC_CTaskSimpleUseGun_AbortIK 0x61DFA0 +#define FUNC_CTaskSimpleUseGun_AimGun 0x61ED10 +#define FUNC_CTaskSimpleUseGun_ClearAnim 0x61E190 +#define FUNC_CTaskSimpleUseGun_GetCurrentCommand 0x4ABE30 +#define FUNC_CTaskSimpleUseGun_GetDoneFiring 0x61C220 +#define FUNC_CTaskSimpleUseGun_GetIsFinished 0x61C240 +#define FUNC_CTaskSimpleUseGun_IsLineOfSightBlocked 0x61C250 +#define FUNC_CTaskSimpleUseGun_GetIsFiring 0x509950 +#define FUNC_CTaskSimpleUseGun_GetIsReloading 0x609340 +#define FUNC_CTaskSimpleUseGun_GetSkipAim 0x588840 +#define FUNC_CTaskSimpleUseGun_PlayerPassiveControlGun 0x61E0A0 +#define FUNC_CTaskSimpleUseGun_RemoveStanceAnims 0x61E8E0 +#define FUNC_CTaskSimpleUseGun_RequirePistolWhip 0x61E200 +#define FUNC_CTaskSimpleUseGun_SetBurstLength 0x61C210 +#define FUNC_CTaskSimpleUseGun_SetMoveAnim 0x61E3F0 +#define FUNC_CTaskSimpleUseGun_StartAnim 0x624F30 +#define FUNC_CTaskSimpleUseGun_StartCountDown 0x61E160 // temporary class CAnimBlendAssociation; @@ -68,9 +68,9 @@ class CTaskSimpleGangDriveBySAInterface : public CTaskSimpleSAInterface bool m_bFromScriptCommand; char m_nNextCommand; - char m_nLastCommand; // active command + char m_nLastCommand; // active command char m_nBurstShots; - char m_nDrivebyStyle; // what type of driveby are we doing + char m_nDrivebyStyle; // what type of driveby are we doing char m_nFrequencyPercentage; char m_nFakeShootDirn; short m_nAttackTimer; @@ -78,7 +78,7 @@ class CTaskSimpleGangDriveBySAInterface : public CTaskSimpleSAInterface unsigned int m_nLOSCheckTime; bool m_nLOSBlocked; - float m_fAbortRange; // range from target at which this task will be aborted + float m_fAbortRange; // range from target at which this task will be aborted AnimationId m_nRequiredAnim; AssocGroupId m_nRequiredAnimGroup; @@ -92,23 +92,23 @@ class CTaskSimpleGangDriveBySAInterface : public CTaskSimpleSAInterface class CTaskSimpleGangDriveBySA : public virtual CTaskSimpleSA, public virtual CTaskSimpleGangDriveBy { public: - CTaskSimpleGangDriveBySA(){}; + CTaskSimpleGangDriveBySA() {}; CTaskSimpleGangDriveBySA(CEntity* pTargetEntity, const CVector* pVecTarget, float fAbortRange, char FrequencyPercentage, char nDrivebyStyle, bool bSeatRHS); }; class CTaskSimpleUseGunSAInterface : public CTaskSimpleSAInterface { public: - unsigned char m_bIsFinished; // 0x08 + unsigned char m_bIsFinished; // 0x08 unsigned char m_bIsInControl; unsigned char m_bMoveControl; unsigned char m_bFiredGun; - unsigned char m_bBlockedLOS; // 0x0C + unsigned char m_bBlockedLOS; // 0x0C unsigned char m_nFireGunThisFrame; - unsigned char m_bSkipAim; // 0x0E + unsigned char m_bSkipAim; // 0x0E char m_nNextCommand; - char m_nLastCommand; // active command (2 or 3) == is firing + char m_nLastCommand; // active command (2 or 3) == is firing CVector2D m_vecMoveCommand; CEntity* m_pTargetEntity; @@ -116,8 +116,8 @@ class CTaskSimpleUseGunSAInterface : public CTaskSimpleSAInterface CAnimBlendAssociation* m_pAnim; - CWeaponInfo* m_pWeaponInfo; // 0x30 - short m_nBurstLength; // 0x34 + CWeaponInfo* m_pWeaponInfo; // 0x30 + short m_nBurstLength; // 0x34 short m_nBurstShots; unsigned char m_nCountDownFrames; @@ -130,7 +130,7 @@ class CTaskSimpleUseGunSAInterface : public CTaskSimpleSAInterface class CTaskSimpleUseGunSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleUseGun { public: - CTaskSimpleUseGunSA(){}; + CTaskSimpleUseGunSA() {}; CTaskSimpleUseGunSA(CEntity* pTargetEntity, CVector vecTarget, char nCommand, short nBurstLength = 1, unsigned char bAimImmediate = false); bool ControlGun(CPed* pPed, CEntity* pTargetEntity, char nCommand); @@ -188,6 +188,6 @@ class CTaskSimpleFightSAInterface : public CTaskSimpleSAInterface class CTaskSimpleFightSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleFight { public: - CTaskSimpleFightSA(){}; + CTaskSimpleFightSA() {}; CTaskSimpleFightSA(CEntity* pTargetEntity, int nCommand, unsigned int nIdlePeriod = 10000); }; diff --git a/Client/game_sa/TaskBasicSA.cpp b/Client/game_sa/TaskBasicSA.cpp index fbe6acd88ec..83052d3f51e 100644 --- a/Client/game_sa/TaskBasicSA.cpp +++ b/Client/game_sa/TaskBasicSA.cpp @@ -13,7 +13,6 @@ #include "TaskBasicSA.h" #include "CPedSA.h" - CTaskSimpleRunNamedAnimSAInterface* CTaskSimpleRunNamedAnimSA::GetAnimationInterface() noexcept { return reinterpret_cast(this->GetInterface()); @@ -42,12 +41,10 @@ CTaskComplexUseMobilePhoneSA::CTaskComplexUseMobilePhoneSA(const int iDuration) DWORD dwFunc = FUNC_CTaskComplexUseMobilePhone__Constructor; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push iDuration - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(iDuration)); + reinterpret_cast(dwFunc)(dwThisInterface, iDuration); + // clang-format on } CTaskSimpleRunAnimSA::CTaskSimpleRunAnimSA(const AssocGroupId animGroup, const AnimationId animID, const float fBlendDelta, const int iTaskType, @@ -60,17 +57,10 @@ CTaskSimpleRunAnimSA::CTaskSimpleRunAnimSA(const AssocGroupId animGroup, const A DWORD dwFunc = FUNC_CTaskSimpleRunAnim__Constructor; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push bHoldLastFrame - push pTaskName - push iTaskType - push fBlendDelta - push animID - push animGroup - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(animGroup), decltype(animID), decltype(fBlendDelta), decltype(iTaskType), decltype(pTaskName), decltype(bHoldLastFrame)); + reinterpret_cast(dwFunc)(dwThisInterface, animGroup, animID, fBlendDelta, iTaskType, pTaskName, bHoldLastFrame); + // clang-format on } CTaskSimpleRunNamedAnimSA::CTaskSimpleRunNamedAnimSA(const char* pAnimName, const char* pAnimGroupName, const int flags, const float fBlendDelta, @@ -84,20 +74,10 @@ CTaskSimpleRunNamedAnimSA::CTaskSimpleRunNamedAnimSA(const char* pAnimName, cons DWORD dwFunc = FUNC_CTaskSimpleRunNamedAnim__Constructor; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push bHoldLastFrame - push bOffsetPed - push bRunInSequence - push bDontInterrupt - push iTime - push fBlendDelta - push flags - push pAnimGroupName - push pAnimName - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(pAnimName), decltype(pAnimGroupName), decltype(flags), decltype(fBlendDelta), decltype(iTime), decltype(bDontInterrupt), decltype(bRunInSequence), decltype(bOffsetPed), decltype(bHoldLastFrame)); + reinterpret_cast(dwFunc)(dwThisInterface, pAnimName, pAnimGroupName, flags, fBlendDelta, iTime, bDontInterrupt, bRunInSequence, bOffsetPed, bHoldLastFrame); + // clang-format on } CTaskComplexDieSA::CTaskComplexDieSA(const eWeaponType eMeansOfDeath, const AssocGroupId animGroup, const AnimationId anim, const float fBlendDelta, @@ -111,20 +91,10 @@ CTaskComplexDieSA::CTaskComplexDieSA(const eWeaponType eMeansOfDeath, const Asso DWORD dwFunc = FUNC_CTaskComplexDie__Constructor; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push bFallToDeathOverRailing - push iFallToDeathDir - push bFallingToDeath - push bBeingKilledByStealth - push fAnimSpeed - push fBlendDelta - push anim - push animGroup - push eMeansOfDeath - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(eMeansOfDeath), decltype(animGroup), decltype(anim), decltype(fBlendDelta), decltype(fAnimSpeed), decltype(bBeingKilledByStealth), decltype(bFallingToDeath), decltype(iFallToDeathDir), decltype(bFallToDeathOverRailing)); + reinterpret_cast(dwFunc)(dwThisInterface, eMeansOfDeath, animGroup, anim, fBlendDelta, fAnimSpeed, bBeingKilledByStealth, bFallingToDeath, iFallToDeathDir, bFallToDeathOverRailing); + // clang-format on } CTaskSimpleStealthKillSA::CTaskSimpleStealthKillSA(bool bKiller, CPed* pPed, const AssocGroupId animGroup) @@ -137,14 +107,10 @@ CTaskSimpleStealthKillSA::CTaskSimpleStealthKillSA(bool bKiller, CPed* pPed, con DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwPedInterface = (DWORD)pPed->GetPedInterface(); - _asm - { - mov ecx, dwThisInterface - push animGroup - push dwPedInterface - push bKiller - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(bKiller), decltype(dwPedInterface), decltype(animGroup)); + reinterpret_cast(dwFunc)(dwThisInterface, bKiller, dwPedInterface, animGroup); + // clang-format on } CTaskSimpleDeadSA::CTaskSimpleDeadSA(unsigned int uiDeathTimeMS, bool bUnk2) @@ -155,13 +121,10 @@ CTaskSimpleDeadSA::CTaskSimpleDeadSA(unsigned int uiDeathTimeMS, bool bUnk2) DWORD dwFunc = FUNC_CTaskSimpleDead__Constructor; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push bUnk2 - push uiDeathTimeMS - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(uiDeathTimeMS), decltype(bUnk2)); + reinterpret_cast(dwFunc)(dwThisInterface, uiDeathTimeMS, bUnk2); + // clang-format on } CTaskSimpleBeHitSA::CTaskSimpleBeHitSA(CPed* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) @@ -173,15 +136,10 @@ CTaskSimpleBeHitSA::CTaskSimpleBeHitSA(CPed* pPedAttacker, ePedPieceTypes hitBod DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwPedInterface = (DWORD)pPedAttacker->GetPedInterface(); - _asm - { - mov ecx, dwThisInterface - push weaponId - push hitBodySide - push hitBodyPart - push dwPedInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface), decltype(hitBodyPart), decltype(hitBodySide), decltype(weaponId)); + reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface, hitBodyPart, hitBodySide, weaponId); + // clang-format on } CTaskComplexSunbatheSA::CTaskComplexSunbatheSA(CObject* pTowel, const bool bStartStanding) @@ -196,13 +154,10 @@ CTaskComplexSunbatheSA::CTaskComplexSunbatheSA(CObject* pTowel, const bool bStar if (pTowel) dwObjectInterface = (DWORD)pTowel->GetObjectInterface(); - _asm - { - mov ecx, dwThisInterface - push bStartStanding - push dwObjectInterface; - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwObjectInterface), decltype(bStartStanding)); + reinterpret_cast(dwFunc)(dwThisInterface, dwObjectInterface, bStartStanding); + // clang-format on } void CTaskComplexSunbatheSA::SetEndTime(DWORD dwTime) @@ -222,11 +177,10 @@ CTaskSimplePlayerOnFootSA::CTaskSimplePlayerOnFootSA() DWORD dwFunc = (DWORD)FUNC_CTASKSimplePlayerOnFoot__Constructor; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface) ); + reinterpret_cast(dwFunc)(dwThisInterface); + // clang-format on } //////////////////// @@ -240,9 +194,18 @@ CTaskComplexFacialSA::CTaskComplexFacialSA() DWORD dwFunc = (DWORD)FUNC_CTASKComplexFacial__Constructor; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface) ); + reinterpret_cast(dwFunc)(dwThisInterface); + // clang-format on +} + +CTaskComplexInWaterSA::CTaskComplexInWaterSA() +{ + CreateTaskInterface(sizeof(CTaskComplexInWaterSA)); + if (!IsValid()) + return; + + // Call the constructor + ((void(__thiscall*)(CTaskComplexInWaterSAInterface*))0x6350D0)(static_cast(GetInterface())); } diff --git a/Client/game_sa/TaskBasicSA.h b/Client/game_sa/TaskBasicSA.h index c62b3e1b755..a76660a6af8 100644 --- a/Client/game_sa/TaskBasicSA.h +++ b/Client/game_sa/TaskBasicSA.h @@ -19,17 +19,17 @@ class CVehicleSAInterface; class CObjectSAInterface; -#define FUNC_CTaskComplexUseMobilePhone__Constructor 0x6348A0 -#define FUNC_CTaskSimpleRunAnim__Constructor 0x61A900 -#define FUNC_CTaskSimpleRunNamedAnim__Constructor 0x61A990 -#define FUNC_CTaskComplexDie__Constructor 0x630040 -#define FUNC_CTaskSimpleStealthKill__Constructor 0x6225F0 -#define FUNC_CTaskSimpleDead__Constructor 0x630590 -#define FUNC_CTaskSimpleBeHit__Constructor 0x620780 -#define FUNC_CTaskComplexSunbathe__Constructor 0x631F80 -#define FUNC_CTASKSimplePlayerOnFoot__Constructor 0x685750 -#define FUNC_CTASKComplexFacial__Constructor 0x690D20 -#define VTBL_CTaskSimpleCarFallOut 0x86EFD0 +#define FUNC_CTaskComplexUseMobilePhone__Constructor 0x6348A0 +#define FUNC_CTaskSimpleRunAnim__Constructor 0x61A900 +#define FUNC_CTaskSimpleRunNamedAnim__Constructor 0x61A990 +#define FUNC_CTaskComplexDie__Constructor 0x630040 +#define FUNC_CTaskSimpleStealthKill__Constructor 0x6225F0 +#define FUNC_CTaskSimpleDead__Constructor 0x630590 +#define FUNC_CTaskSimpleBeHit__Constructor 0x620780 +#define FUNC_CTaskComplexSunbathe__Constructor 0x631F80 +#define FUNC_CTASKSimplePlayerOnFoot__Constructor 0x685750 +#define FUNC_CTASKComplexFacial__Constructor 0x690D20 +#define VTBL_CTaskSimpleCarFallOut 0x86EFD0 /////////////////////// // Use a mobile phone @@ -47,8 +47,8 @@ class CTaskComplexUseMobilePhoneSAInterface : public CTaskComplexSAInterface class CTaskComplexUseMobilePhoneSA : public virtual CTaskComplexSA, public virtual CTaskComplexUseMobilePhone { public: - CTaskComplexUseMobilePhoneSA(){}; - CTaskComplexUseMobilePhoneSA(const int iDuration); // Default is -1 + CTaskComplexUseMobilePhoneSA() {}; + CTaskComplexUseMobilePhoneSA(const int iDuration); // Default is -1 }; // temporary @@ -77,18 +77,18 @@ class CTaskSimpleAnimSAInterface : public CTaskSimpleSAInterface class CTaskSimpleAnimSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleAnim { public: - CTaskSimpleAnimSA(){}; + CTaskSimpleAnimSA() {}; }; class CTaskSimpleRunAnimSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleRunAnim { public: - CTaskSimpleRunAnimSA(){}; + CTaskSimpleRunAnimSA() {}; CTaskSimpleRunAnimSA(const AssocGroupId animGroup, const AnimationId animID, const float fBlendDelta, const int iTaskType, const char* pTaskName, const bool bHoldLastFrame = false); }; -#define ANIM_NAMELEN 24 +#define ANIM_NAMELEN 24 #define ANIMBLOCK_NAMELEN 16 class CTaskSimpleRunNamedAnimSAInterface : public CTaskSimpleAnimSAInterface @@ -109,7 +109,7 @@ class CTaskSimpleRunNamedAnimSAInterface : public CTaskSimpleAnimSAInterface class CTaskSimpleRunNamedAnimSA : public virtual CTaskSimpleAnimSA, public virtual CTaskSimpleRunNamedAnim { public: - CTaskSimpleRunNamedAnimSA(){}; + CTaskSimpleRunNamedAnimSA() {}; CTaskSimpleRunNamedAnimSA(const char* pAnimName, const char* pAnimGroupName, const int flags, const float fBlendDelta, const int iTime = -1, const bool bDontInterrupt = false, const bool bRunInSequence = false, const bool bOffsetPed = false, const bool bHoldLastFrame = false); @@ -129,7 +129,7 @@ class CTaskComplexDieSAInterface : public CTaskComplexSAInterface class CTaskComplexDieSA : public virtual CTaskComplexSA, public virtual CTaskComplexDie { public: - CTaskComplexDieSA(){}; + CTaskComplexDieSA() {}; CTaskComplexDieSA(const eWeaponType eMeansOfDeath /*=WEAPONTYPE_UNARMED*/, const AssocGroupId animGroup = 0 /*ANIM_STD_PED*/, const AnimationId anim = 0 /*ANIM_STD_KO_FRONT*/, const float fBlendDelta = 4.0f, const float fAnimSpeed = 0.0f, const bool bBeingKilledByStealth = false, const bool bFallingToDeath = false, const int iFallToDeathDir = 0, @@ -144,7 +144,7 @@ class CTaskSimpleStealthKillInterface : public CTaskSimpleSAInterface class CTaskSimpleStealthKillSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleStealthKill { public: - CTaskSimpleStealthKillSA(){}; + CTaskSimpleStealthKillSA() {}; CTaskSimpleStealthKillSA(bool bKiller, class CPed* pPed, const AssocGroupId animGroup); }; @@ -158,40 +158,40 @@ class CTaskSimpleDeadSAInterface : public CTaskSimpleSAInterface class CTaskSimpleDeadSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleDead { public: - CTaskSimpleDeadSA(){}; + CTaskSimpleDeadSA() {}; CTaskSimpleDeadSA(unsigned int uiDeathTimeMS, bool bUnk2); }; class CTaskSimpleBeHitSAInterface : public CTaskSimpleSAInterface { public: - CPed* pPedAttacker; // 0x08 - uchar a; // 0x0c - uchar b; // 0x0d - uchar c; // 0x0e - uchar d; // 0x0f - uint e; // 0x10 inited with 0x000000BF - uint f; // 0x14 inited with 0 - uint hitBodyPart; // 0x18 - uint weaponType; // 0x1C - uint hitBodySide; // 0x20 - uint g; // 0x24 inited with 0 + CPed* pPedAttacker; // 0x08 + uchar a; // 0x0c + uchar b; // 0x0d + uchar c; // 0x0e + uchar d; // 0x0f + uint e; // 0x10 inited with 0x000000BF + uint f; // 0x14 inited with 0 + uint hitBodyPart; // 0x18 + uint weaponType; // 0x1C + uint hitBodySide; // 0x20 + uint g; // 0x24 inited with 0 }; class CTaskSimpleBeHitSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleBeHit { public: - CTaskSimpleBeHitSA(){}; + CTaskSimpleBeHitSA() {}; CTaskSimpleBeHitSA(CPed* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId); }; class CTaskSimpleCarFallOutSAInterface : public CTaskSimpleSAInterface { public: - uint a; // 0x08 - uint b; // 0x0c - CVehicleSAInterface* pVehicle; // 0x10 - uint doorIndex; // 0x14 + uint a; // 0x08 + uint b; // 0x0c + CVehicleSAInterface* pVehicle; // 0x10 + uint doorIndex; // 0x14 }; class CAnimBlock; @@ -216,7 +216,7 @@ class CTaskComplexSunbatheSAInterface : public CTaskComplexSAInterface class CTaskComplexSunbatheSA : public virtual CTaskComplexSA, public virtual CTaskComplexSunbathe { public: - CTaskComplexSunbatheSA(){}; + CTaskComplexSunbatheSA() {}; CTaskComplexSunbatheSA(class CObject* pTowel, const bool bStartStanding); void SetEndTime(DWORD dwTime); @@ -251,3 +251,14 @@ class CTaskComplexFacialSA : public virtual CTaskComplexSA, public virtual CTask public: CTaskComplexFacialSA(); }; + +class CTaskComplexInWaterSAInterface : public CTaskComplexSAInterface +{ +public: +}; + +class CTaskComplexInWaterSA : public virtual CTaskComplexSA, public virtual CTaskComplexInWater +{ +public: + CTaskComplexInWaterSA(); +}; diff --git a/Client/game_sa/TaskCarAccessoriesSA.cpp b/Client/game_sa/TaskCarAccessoriesSA.cpp index cae3e7b68d6..b89f5467b89 100644 --- a/Client/game_sa/TaskCarAccessoriesSA.cpp +++ b/Client/game_sa/TaskCarAccessoriesSA.cpp @@ -30,13 +30,10 @@ CTaskSimpleCarSetPedInAsDriverSA::CTaskSimpleCarSetPedInAsDriverSA(CVehicle* pTa DWORD dwVehiclePtr = (DWORD)pTargetVehicleSA->GetInterface(); DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push pUtility - push dwVehiclePtr - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwVehiclePtr), decltype(pUtility)); + reinterpret_cast(dwFunc)(dwThisInterface, dwVehiclePtr, pUtility); + // clang-format on } } @@ -72,14 +69,10 @@ CTaskSimpleCarSetPedInAsPassengerSA::CTaskSimpleCarSetPedInAsPassengerSA(CVehicl DWORD dwFunc = FUNC_CTaskSimpleCarSetPedInAsPassenger__Constructor; DWORD dwVehiclePtr = (DWORD)pTargetVehicleSA->GetInterface(); DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push pUtility - push iTargetDoor - push dwVehiclePtr - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwVehiclePtr), decltype(iTargetDoor), decltype(pUtility)); + reinterpret_cast(dwFunc)(dwThisInterface, dwVehiclePtr, iTargetDoor, pUtility); + // clang-format on } } @@ -115,7 +108,8 @@ CTaskSimpleCarSetPedOutSA::CTaskSimpleCarSetPedOutSA(CVehicle* pTargetVehicle, i DWORD dwFunc = FUNC_CTaskSimpleCarSetPedOut__Constructor; DWORD dwVehiclePtr = (DWORD)pTargetVehicleSA->GetInterface(); DWORD dwThisInterface = (DWORD)GetInterface(); - _asm + // clang-format off + __asm { mov ecx, dwThisInterface xor eax, eax @@ -125,6 +119,7 @@ CTaskSimpleCarSetPedOutSA::CTaskSimpleCarSetPedOutSA(CVehicle* pTargetVehicle, i push dwVehiclePtr call dwFunc } + // clang-format on } } @@ -154,11 +149,8 @@ void CTaskSimpleCarSetPedOutSA::PositionPedOutOfCollision(CPed* ped, CVehicle* v DWORD dwFunc = FUNC_CTaskSimpleCarSetPedOut__PositionPedOutOfCollision; DWORD dwVehiclePtr = (DWORD)((CEntitySA*)vehicle)->GetInterface(); DWORD dwPedPtr = (DWORD)((CEntitySA*)ped)->GetInterface(); - _asm - { - push nDoor - push dwVehiclePtr - push dwPedPtr - call dwFunc - } + // clang-format off + using func_t = void (__cdecl*)(decltype(dwPedPtr), decltype(dwVehiclePtr), decltype(nDoor)); + reinterpret_cast(dwFunc)(dwPedPtr, dwVehiclePtr, nDoor); + // clang-format on } diff --git a/Client/game_sa/TaskCarAccessoriesSA.h b/Client/game_sa/TaskCarAccessoriesSA.h index 00cd1c96727..a02748e3e1a 100644 --- a/Client/game_sa/TaskCarAccessoriesSA.h +++ b/Client/game_sa/TaskCarAccessoriesSA.h @@ -20,11 +20,11 @@ class CAnimBlendAssociation; typedef DWORD CTaskUtilityLineUpPedWithCar; -#define FUNC_CTaskSimpleCarSetPedInAsDriver__Constructor 0x6470E0 -#define FUNC_CTaskSimpleCarSetPedInAsPassenger__Constructor 0x646FE0 -#define FUNC_CTaskSimpleCarSetPedOut__Constructor 0x6478B0 +#define FUNC_CTaskSimpleCarSetPedInAsDriver__Constructor 0x6470E0 +#define FUNC_CTaskSimpleCarSetPedInAsPassenger__Constructor 0x646FE0 +#define FUNC_CTaskSimpleCarSetPedOut__Constructor 0x6478B0 -#define FUNC_CTaskSimpleCarSetPedOut__PositionPedOutOfCollision 0x6479B0 +#define FUNC_CTaskSimpleCarSetPedOut__PositionPedOutOfCollision 0x6479B0 // ############################################################################## // ## Name: CTaskSimpleCarSetPedInAsDriver @@ -47,7 +47,7 @@ class CTaskSimpleCarSetPedInAsDriverSAInterface : public CTaskSimpleSAInterface class CTaskSimpleCarSetPedInAsDriverSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleCarSetPedInAsDriver { public: - CTaskSimpleCarSetPedInAsDriverSA(){}; + CTaskSimpleCarSetPedInAsDriverSA() {}; CTaskSimpleCarSetPedInAsDriverSA(CVehicle* pTargetVehicle, CTaskUtilityLineUpPedWithCar* pUtility); void SetIsWarpingPedIntoCar(); @@ -76,7 +76,7 @@ class CTaskSimpleCarSetPedInAsPassengerSAInterface : public CTaskSimpleSAInterfa class CTaskSimpleCarSetPedInAsPassengerSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleCarSetPedInAsPassenger { public: - CTaskSimpleCarSetPedInAsPassengerSA(){}; + CTaskSimpleCarSetPedInAsPassengerSA() {}; CTaskSimpleCarSetPedInAsPassengerSA(CVehicle* pTargetVehicle, int iTargetDoor, CTaskUtilityLineUpPedWithCar* pUtility); void SetIsWarpingPedIntoCar(); @@ -92,11 +92,11 @@ class CTaskSimpleCarSetPedInAsPassengerSA : public virtual CTaskSimpleSA, public class CTaskSimpleCarSetPedOutSAInterface : public CTaskSimpleSAInterface { public: - CVehicleSAInterface* m_pTargetVehicle; // 8 - int m_iTargetDoor; // 12 - bool m_bSwitchOffEngine; // 16 + CVehicleSAInterface* m_pTargetVehicle; // 8 + int m_iTargetDoor; // 12 + bool m_bSwitchOffEngine; // 16 bool m_bWarpingOutOfCar; - bool m_bFallingOutOfCar; // jumping or falling off car or bike + bool m_bFallingOutOfCar; // jumping or falling off car or bike bool m_bKnockedOffBike; unsigned char m_nDoorFlagsToClear; unsigned char m_nNumGettingInToClear; @@ -105,7 +105,7 @@ class CTaskSimpleCarSetPedOutSAInterface : public CTaskSimpleSAInterface class CTaskSimpleCarSetPedOutSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleCarSetPedOut { public: - CTaskSimpleCarSetPedOutSA(){}; + CTaskSimpleCarSetPedOutSA() {}; CTaskSimpleCarSetPedOutSA(CVehicle* pTargetVehicle, int iTargetDoor, bool bSwitchOffEngine = false); void SetIsWarpingPedOutOfCar(); diff --git a/Client/game_sa/TaskCarSA.cpp b/Client/game_sa/TaskCarSA.cpp index 93d10e34d68..e0a2a3bc028 100644 --- a/Client/game_sa/TaskCarSA.cpp +++ b/Client/game_sa/TaskCarSA.cpp @@ -43,12 +43,10 @@ CTaskComplexEnterCarAsDriverSA::CTaskComplexEnterCarAsDriverSA(CVehicle* pTarget DWORD dwVehiclePtr = (DWORD)pTargetVehicleSA->GetInterface(); DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push dwVehiclePtr - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwVehiclePtr)); + reinterpret_cast(dwFunc)(dwThisInterface, dwVehiclePtr); + // clang-format on } } @@ -71,7 +69,8 @@ CTaskComplexEnterCarAsPassengerSA::CTaskComplexEnterCarAsPassengerSA(CVehicle* p DWORD dwVehiclePtr = (DWORD)pTargetVehicleSA->GetInterface(); DWORD dwThisInterface = (DWORD)GetInterface(); - _asm + // clang-format off + __asm { push edx xor edx, edx @@ -83,6 +82,7 @@ CTaskComplexEnterCarAsPassengerSA::CTaskComplexEnterCarAsPassengerSA(CVehicle* p call dwFunc pop edx } + // clang-format on } } @@ -104,12 +104,10 @@ CTaskComplexEnterBoatAsDriverSA::CTaskComplexEnterBoatAsDriverSA(CVehicle* pTarg DWORD dwVehiclePtr = (DWORD)pTargetVehicleSA->GetInterface(); DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push dwVehiclePtr - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwVehiclePtr)); + reinterpret_cast(dwFunc)(dwThisInterface, dwVehiclePtr); + // clang-format on } } @@ -138,7 +136,8 @@ CTaskComplexLeaveCarSA::CTaskComplexLeaveCarSA(CVehicle* pTargetVehicle, const i if (iTargetDoor >= 0 && iTargetDoor <= 5) dwDoorIdx = s_iCarNodeIndexes[iTargetDoor]; - _asm + // clang-format off + __asm { mov ecx, dwThisInterface push ebx @@ -153,5 +152,6 @@ CTaskComplexLeaveCarSA::CTaskComplexLeaveCarSA(CVehicle* pTargetVehicle, const i call dwFunc pop ebx } + // clang-format on } } diff --git a/Client/game_sa/TaskCarSA.h b/Client/game_sa/TaskCarSA.h index d9752c6d371..c8ae39a1f1a 100644 --- a/Client/game_sa/TaskCarSA.h +++ b/Client/game_sa/TaskCarSA.h @@ -20,10 +20,10 @@ class CAnimBlendAssociation; typedef DWORD CTaskUtilityLineUpPedWithCar; typedef DWORD AnimationId; -#define FUNC_CTaskComplexEnterCarAsDriver__Constructor 0x6402F0 -#define FUNC_CTaskComplexEnterCarAsPassenger__Constructor 0x640340 -#define FUNC_CTaskComplexEnterBoatAsDriver__Constructor 0x63B5E0 -#define FUNC_CTaskComplexLeaveCar__Constructor 0x63B8C0 +#define FUNC_CTaskComplexEnterCarAsDriver__Constructor 0x6402F0 +#define FUNC_CTaskComplexEnterCarAsPassenger__Constructor 0x640340 +#define FUNC_CTaskComplexEnterBoatAsDriver__Constructor 0x63B5E0 +#define FUNC_CTaskComplexLeaveCar__Constructor 0x63B8C0 // ############################################################################## // ## Name: CTaskComplexEnterCar @@ -62,7 +62,7 @@ class CTaskComplexEnterCarSAInterface : public CTaskComplexSAInterface class CTaskComplexEnterCarSA : public virtual CTaskComplexSA { public: - CTaskComplexEnterCarSA(){}; + CTaskComplexEnterCarSA() {}; CTaskComplexEnterCarSA(CVehicle* pTargetVehicle, const bool bAsDriver, const bool bQuitAfterOpeningDoor, const bool bQuitAfterDraggingPedOut, const bool bCarryOnAfterFallingOff = false); @@ -97,7 +97,7 @@ class CTaskComplexEnterCarAsDriverSAInterface : public CTaskComplexEnterCarSAInt class CTaskComplexEnterCarAsDriverSA : public virtual CTaskComplexEnterCarSA, public virtual CTaskComplexEnterCarAsDriver { public: - CTaskComplexEnterCarAsDriverSA(){}; + CTaskComplexEnterCarAsDriverSA() {}; CTaskComplexEnterCarAsDriverSA(CVehicle* pTargetVehicle); // from CTaskComplexEnterCarSA @@ -119,7 +119,7 @@ class CTaskComplexEnterCarAsPassengerSAInterface : public CTaskComplexEnterCarSA class CTaskComplexEnterCarAsPassengerSA : public virtual CTaskComplexEnterCarSA, public virtual CTaskComplexEnterCarAsPassenger { public: - CTaskComplexEnterCarAsPassengerSA(){}; + CTaskComplexEnterCarAsPassengerSA() {}; CTaskComplexEnterCarAsPassengerSA(CVehicle* pTargetVehicle, const int iTargetSeat = 0, const bool bCarryOnAfterFallingOff = false); // from CTaskComplexEnterCarSA @@ -141,7 +141,7 @@ class CTaskComplexEnterBoatAsDriverSAInterface : public CTaskComplexSAInterface class CTaskComplexEnterBoatAsDriverSA : public virtual CTaskComplexSA, public virtual CTaskComplexEnterBoatAsDriver { public: - CTaskComplexEnterBoatAsDriverSA(){}; + CTaskComplexEnterBoatAsDriverSA() {}; CTaskComplexEnterBoatAsDriverSA(CVehicle* pTargetVehicle); }; @@ -174,7 +174,7 @@ class CTaskComplexLeaveCarSAInterface : public CTaskComplexSAInterface class CTaskComplexLeaveCarSA : public virtual CTaskComplexSA, public virtual CTaskComplexLeaveCar { public: - CTaskComplexLeaveCarSA(){}; + CTaskComplexLeaveCarSA() {}; CTaskComplexLeaveCarSA(CVehicle* pTargetVehicle, const int iTargetDoor = 0, const int iDelayTime = 0, const bool bSensibleLeaveCar = true, const bool bForceGetOut = false); diff --git a/Client/game_sa/TaskGoToSA.cpp b/Client/game_sa/TaskGoToSA.cpp index 4964295a976..8f5e79fbcd8 100644 --- a/Client/game_sa/TaskGoToSA.cpp +++ b/Client/game_sa/TaskGoToSA.cpp @@ -24,14 +24,12 @@ int CTaskComplexWanderSA::GetWanderType() DWORD dwFunc = ((TaskComplexWanderVTBL*)pTaskInterface->VTBL)->GetWanderType; int iReturn = NO_WANDER_TYPE; - if (dwFunc && dwFunc != 0x82263A) // some tasks have no wander type 0x82263A is purecal (assert?) + if (dwFunc && dwFunc != 0x82263A) // some tasks have no wander type 0x82263A is purecal (assert?) { - _asm - { - mov ecx, pTaskInterface - call dwFunc - mov iReturn, eax - } + // clang-format off + using func_t = decltype(iReturn) (__thiscall*)(decltype(pTaskInterface) ); +iReturn = reinterpret_cast(dwFunc)(pTaskInterface); + // clang-format on } return iReturn; } @@ -58,12 +56,8 @@ CTaskComplexWanderStandardSA::CTaskComplexWanderStandardSA(const int iMoveState, return; DWORD dwFunc = FUNC_CTaskComplexWanderStandard__Constructor; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push bWanderSensibly - push iDir - push iMoveState - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(iMoveState), decltype(iDir), decltype(bWanderSensibly)); + reinterpret_cast(dwFunc)(dwThisInterface, iMoveState, iDir, bWanderSensibly); + // clang-format on } diff --git a/Client/game_sa/TaskGoToSA.h b/Client/game_sa/TaskGoToSA.h index e10fa3bd611..b78157fed9a 100644 --- a/Client/game_sa/TaskGoToSA.h +++ b/Client/game_sa/TaskGoToSA.h @@ -19,10 +19,10 @@ class CAnimBlendAssociation; typedef DWORD CTaskUtilityLineUpPedWithCar; -#define FUNC_CTaskComplexWanderStandard__Constructor 0x48E4F0 -#define FUNC_CTaskComplexWanderStandard__Destructor 0x48E600 +#define FUNC_CTaskComplexWanderStandard__Constructor 0x48E4F0 +#define FUNC_CTaskComplexWanderStandard__Destructor 0x48E600 -#define FUNC_CTaskSimpleCarSetPedOut__PositionPedOutOfCollision 0x6479B0 +#define FUNC_CTaskSimpleCarSetPedOut__PositionPedOutOfCollision 0x6479B0 class TaskComplexWanderVTBL : public TaskComplexVTBL { @@ -62,7 +62,7 @@ class CTaskComplexWanderSAInterface : public CTaskComplexSAInterface class CTaskComplexWanderSA : public virtual CTaskComplexSA, public virtual CTaskComplexWander { public: - CTaskComplexWanderSA(){}; + CTaskComplexWanderSA() {}; CNodeAddress* GetNextNode(); CNodeAddress* GetLastNode(); @@ -86,6 +86,6 @@ class CTaskComplexWanderStandardSAInterface : public CTaskComplexWanderSAInterfa class CTaskComplexWanderStandardSA : public virtual CTaskComplexWanderSA, public virtual CTaskComplexWanderStandard { public: - CTaskComplexWanderStandardSA(){}; + CTaskComplexWanderStandardSA() {}; CTaskComplexWanderStandardSA(const int iMoveState, const unsigned char iDir, const bool bWanderSensibly = true); }; diff --git a/Client/game_sa/TaskIKSA.cpp b/Client/game_sa/TaskIKSA.cpp index a6e21b36930..7e13a04045f 100644 --- a/Client/game_sa/TaskIKSA.cpp +++ b/Client/game_sa/TaskIKSA.cpp @@ -31,25 +31,10 @@ CTaskSimpleIKChainSA::CTaskSimpleIKChainSA(char* idString, int effectorBoneTag, dwEntityInterface = (DWORD)pEntity->GetInterface(); float fEffectorX = effectorVec.fX, fEffectorY = effectorVec.fY, fEffectorZ = effectorVec.fZ; float fX = offsetPos.fX, fY = offsetPos.fY, fZ = offsetPos.fZ; - _asm - { - mov ecx, dwThisInterface - push blendTime - push time - push speed - push fZ - push fY - push fX - push offsetBoneTag - push dwEntityInterface - push pivotBoneTag - push fEffectorZ - push fEffectorY - push fEffectorX - push effectorBoneTag - push idString - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(idString), decltype(effectorBoneTag), decltype(fEffectorX), decltype(fEffectorY), decltype(fEffectorZ), decltype(pivotBoneTag), decltype(dwEntityInterface), decltype(offsetBoneTag), decltype(fX), decltype(fY), decltype(fZ), decltype(speed), decltype(time), decltype(blendTime)); + reinterpret_cast(dwFunc)(dwThisInterface, idString, effectorBoneTag, fEffectorX, fEffectorY, fEffectorZ, pivotBoneTag, dwEntityInterface, offsetBoneTag, fX, fY, fZ, speed, time, blendTime); + // clang-format on } CTaskSimpleIKLookAtSA::CTaskSimpleIKLookAtSA(char* idString, CEntity* pEntity, int time, int offsetBoneTag, CVector offsetPos, unsigned char useTorso, @@ -65,22 +50,10 @@ CTaskSimpleIKLookAtSA::CTaskSimpleIKLookAtSA(char* idString, CEntity* pEntity, i if (pEntity) dwEntityInterface = (DWORD)pEntity->GetInterface(); float fX = offsetPos.fX, fY = offsetPos.fY, fZ = offsetPos.fZ; - _asm - { - mov ecx, dwThisInterface - push m_priority - push blendTime - push speed - push useTorso - push fZ - push fY - push fX - push offsetBoneTag - push time - push dwEntityInterface - push idString - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(idString), decltype(dwEntityInterface), decltype(time), decltype(offsetBoneTag), decltype(fX), decltype(fY), decltype(fZ), decltype(useTorso), decltype(speed), decltype(blendTime), decltype(m_priority)); + reinterpret_cast(dwFunc)(dwThisInterface, idString, dwEntityInterface, time, offsetBoneTag, fX, fY, fZ, useTorso, speed, blendTime, m_priority); + // clang-format on } CTaskSimpleIKManagerSA::CTaskSimpleIKManagerSA() @@ -114,7 +87,7 @@ void CTaskSimpleIKManagerSA::RemoveIKChainTask(int slotID) { // Grab the task CTask* pTask = m_pTaskManagementSystem->GetTask(pInterface->m_pIKChainTasks[slotID]); - assert(pTask); // Leave this here temporarily for debugging (shouldn't ever be null) + assert(pTask); // Leave this here temporarily for debugging (shouldn't ever be null) pTask->Destroy(); pInterface->m_pIKChainTasks[slotID] = NULL; } @@ -138,7 +111,7 @@ CTaskSimpleIKChain* CTaskSimpleIKManagerSA::GetTaskAtSlot(int slotID) { // Grab the task CTask* pTask = m_pTaskManagementSystem->GetTask(pInterface->m_pIKChainTasks[slotID]); - assert(pTask); // Leave this here temporarily for debugging (shouldn't ever be null) + assert(pTask); // Leave this here temporarily for debugging (shouldn't ever be null) return dynamic_cast(pTask); } return NULL; @@ -157,19 +130,8 @@ CTaskSimpleTriggerLookAtSA::CTaskSimpleTriggerLookAtSA(CEntity* pEntity, int tim if (pEntity) dwEntityInterface = (DWORD)pEntity->GetInterface(); float fX = offsetPos.fX, fY = offsetPos.fY, fZ = offsetPos.fZ; - _asm - { - mov ecx, dwThisInterface - push priority - push blendTime - push speed - push useTorso - push fZ - push fY - push fX - push offsetBoneTag - push time - push dwEntityInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwEntityInterface), decltype(time), decltype(offsetBoneTag), decltype(fX), decltype(fY), decltype(fZ), decltype(useTorso), decltype(speed), decltype(blendTime), decltype(priority)); + reinterpret_cast(dwFunc)(dwThisInterface, dwEntityInterface, time, offsetBoneTag, fX, fY, fZ, useTorso, speed, blendTime, priority); + // clang-format on } diff --git a/Client/game_sa/TaskIKSA.h b/Client/game_sa/TaskIKSA.h index 7fd3efccc9e..eba305f32db 100644 --- a/Client/game_sa/TaskIKSA.h +++ b/Client/game_sa/TaskIKSA.h @@ -17,11 +17,11 @@ typedef DWORD IKChain_c; -#define FUNC_CTaskSimpleIKChain__Constructor 0x6339C0 -#define FUNC_CTaskSimpleIKLookAt__Constructor 0x633E00 -#define FUNC_CTaskSimpleIKManager__Constructor 0x6337F0 +#define FUNC_CTaskSimpleIKChain__Constructor 0x6339C0 +#define FUNC_CTaskSimpleIKLookAt__Constructor 0x633E00 +#define FUNC_CTaskSimpleIKManager__Constructor 0x6337F0 -#define FUNC_CTaskSimpleTriggerLookAt__Constructor 0x634440 +#define FUNC_CTaskSimpleTriggerLookAt__Constructor 0x634440 // ############################################################################## // ## Name: CTaskSimpleIKChain @@ -58,7 +58,7 @@ class CTaskSimpleIKChainSAInterface : public CTaskSimpleSAInterface class CTaskSimpleIKChainSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleIKChain { public: - CTaskSimpleIKChainSA(){}; + CTaskSimpleIKChainSA() {}; CTaskSimpleIKChainSA(char* idString, int effectorBoneTag, CVector effectorVec, int pivotBoneTag, CEntity* pEntity, int offsetBoneTag, CVector offsetPos, float speed, int time = 99999999, int blendTime = 1000); }; @@ -78,7 +78,7 @@ class CTaskSimpleIKLookAtSAInterface : public CTaskSimpleIKChainSAInterface class CTaskSimpleIKLookAtSA : public virtual CTaskSimpleIKChainSA, public virtual CTaskSimpleIKLookAt { public: - CTaskSimpleIKLookAtSA(){}; + CTaskSimpleIKLookAtSA() {}; CTaskSimpleIKLookAtSA(char* idString, CEntity* pEntity, int time, int offsetBoneTag, CVector offsetPos, unsigned char useTorso = false, float speed = 0.25f, int blendTime = 1000, int m_priority = 3); }; @@ -154,7 +154,7 @@ class CTaskSimpleTriggerLookAtSAInterface : public CTaskSimpleSAInterface class CTaskSimpleTriggerLookAtSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleTriggerLookAt { public: - CTaskSimpleTriggerLookAtSA(){}; + CTaskSimpleTriggerLookAtSA() {}; CTaskSimpleTriggerLookAtSA(CEntity* pEntity, int time, int offsetBoneTag, CVector offsetPos, unsigned char useTorso = false, float speed = 0.25f, int blendTime = 1000, int priority = 3); }; diff --git a/Client/game_sa/TaskJumpFallSA.cpp b/Client/game_sa/TaskJumpFallSA.cpp index d6f73eb529d..75ad328aa19 100644 --- a/Client/game_sa/TaskJumpFallSA.cpp +++ b/Client/game_sa/TaskJumpFallSA.cpp @@ -12,8 +12,8 @@ #include "StdInc.h" #include "TaskJumpFallSA.h" -CTaskSimpleClimbSA::CTaskSimpleClimbSA(CEntity* pClimbEnt, const CVector& vecTarget, float fHeading, unsigned char nSurfaceType, char nHeight, - const bool bForceClimb) +CTaskSimpleClimbSA::CTaskSimpleClimbSA(CEntitySAInterface* pClimbEnt, const CVector& vecTarget, float fHeading, unsigned char nSurfaceType, + eClimbHeights nHeight, const bool bForceClimb) { CreateTaskInterface(sizeof(CTaskSimpleClimbSAInterface)); if (!IsValid()) @@ -21,17 +21,10 @@ CTaskSimpleClimbSA::CTaskSimpleClimbSA(CEntity* pClimbEnt, const CVector& vecTar DWORD dwFunc = FUNC_CTaskSimpleClimb__Constructor; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push bForceClimb - push nHeight - push nSurfaceType - push fHeading - push vecTarget - push pClimbEnt - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(pClimbEnt), decltype(vecTarget), decltype(fHeading), decltype(nSurfaceType), decltype(nHeight), decltype(bForceClimb)); + reinterpret_cast(dwFunc)(dwThisInterface, pClimbEnt, vecTarget, fHeading, nSurfaceType, nHeight, bForceClimb); + // clang-format on } // ############################################################################## @@ -47,13 +40,8 @@ CTaskSimpleJetPackSA::CTaskSimpleJetPackSA(const CVector* pVecTargetPos, float f DWORD dwFunc = FUNC_CTaskSimpleJetPack__Constructor; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm - { - mov ecx, dwThisInterface - push 0 // pTargetEnt - ignored for simplicity's sake (we really don't need it) - push nHoverTime - push fCruiseHeight - push pVecTargetPos - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(pVecTargetPos), decltype(fCruiseHeight), decltype(nHoverTime), decltype(0)); + reinterpret_cast(dwFunc)(dwThisInterface, pVecTargetPos, fCruiseHeight, nHoverTime, 0); + // clang-format on } diff --git a/Client/game_sa/TaskJumpFallSA.h b/Client/game_sa/TaskJumpFallSA.h index 90ba3af976b..f2eab7c6fd1 100644 --- a/Client/game_sa/TaskJumpFallSA.h +++ b/Client/game_sa/TaskJumpFallSA.h @@ -20,24 +20,24 @@ class CAnimBlendAssociation; class FxSystem_c; -#define FUNC_CTaskSimpleClimb__Constructor 0x67A110 -#define FUNC_CTaskSimpleJetPack__Constructor 0x67B4E0 +#define FUNC_CTaskSimpleClimb__Constructor 0x67A110 +#define FUNC_CTaskSimpleJetPack__Constructor 0x67B4E0 class CTaskSimpleClimbSAInterface : public CTaskSimpleSAInterface { public: - bool m_bIsFinished; - bool m_bChangeAnimation; - bool m_bChangePosition; - bool m_bForceClimb; - bool m_bInvalidClimb; - char m_nHeightForAnim; - char m_nHeightForPos; - unsigned char m_nSurfaceType; - char m_nFallAfterVault; - float m_fHandholdHeading; - CVector m_vecHandholdPos; - CEntity* m_pClimbEnt; + bool m_bIsFinished; + bool m_bChangeAnimation; + bool m_bChangePosition; + bool m_bForceClimb; + bool m_bInvalidClimb; + eClimbHeights m_nHeightForAnim; + eClimbHeights m_nHeightForPos; + unsigned char m_nSurfaceType; + char m_nFallAfterVault; + float m_fHandholdHeading; + CVector m_vecHandholdPos; + CEntitySAInterface* m_pClimbEnt; short m_nGetToPosCounter; CAnimBlendAssociation* m_pAnim; @@ -46,9 +46,11 @@ class CTaskSimpleClimbSAInterface : public CTaskSimpleSAInterface class CTaskSimpleClimbSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleClimb { public: - CTaskSimpleClimbSA(){}; - CTaskSimpleClimbSA(CEntity* pClimbEnt, const CVector& vecTarget, float fHeading, unsigned char nSurfaceType, char nHeight = CLIMB_GRAB, + CTaskSimpleClimbSA() {}; + CTaskSimpleClimbSA(CEntitySAInterface* pClimbEnt, const CVector& vecTarget, float fHeading, unsigned char nSurfaceType, eClimbHeights nHeight = CLIMB_GRAB, const bool bForceClimb = false); + + eClimbHeights GetHeightForPos() const override { return static_cast(GetInterface())->m_nHeightForPos; } }; // ############################################################################## @@ -98,7 +100,7 @@ class CTaskSimpleJetPackSAInterface : public CTaskSimpleSAInterface class CTaskSimpleJetPackSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleJetPack { public: - CTaskSimpleJetPackSA(){}; + CTaskSimpleJetPackSA() {}; CTaskSimpleJetPackSA(const CVector* pVecTargetPos, float fCruiseHeight = 10.0f, int nHoverTime = 0); bool IsFinished() const override { return static_cast(GetInterface())->m_bIsFinished; } diff --git a/Client/game_sa/TaskPhysicalResponseSA.cpp b/Client/game_sa/TaskPhysicalResponseSA.cpp index 9e45bcde546..0380dd03d13 100644 --- a/Client/game_sa/TaskPhysicalResponseSA.cpp +++ b/Client/game_sa/TaskPhysicalResponseSA.cpp @@ -37,7 +37,8 @@ CTaskSimpleChokingSA::CTaskSimpleChokingSA(CPed* pAttacker, bool bIsTearGas) if (!IsValid()) return; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm + // clang-format off + __asm { mov ecx, dwThisInterface push ebx @@ -46,6 +47,7 @@ CTaskSimpleChokingSA::CTaskSimpleChokingSA(CPed* pAttacker, bool bIsTearGas) call dwFunc pop ebx } + // clang-format on } CPed* CTaskSimpleChokingSA::GetAttacker() @@ -99,12 +101,8 @@ void CTaskSimpleChokingSA::UpdateChoke(CPed* pPed, CPed* pAttacker, bool bIsTear // Call the func DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwFunc = FUNC_CTaskSimpleChoking__UpdateChoke; - _asm - { - mov ecx, dwThisInterface - push bIsTearGas - push pAttackerInterface - push pPedInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(pPedInterface), decltype(pAttackerInterface), decltype(bIsTearGas)); + reinterpret_cast(dwFunc)(dwThisInterface, pPedInterface, pAttackerInterface, bIsTearGas); + // clang-format on } diff --git a/Client/game_sa/TaskPhysicalResponseSA.h b/Client/game_sa/TaskPhysicalResponseSA.h index 1983be056a5..4b16fbab9c1 100644 --- a/Client/game_sa/TaskPhysicalResponseSA.h +++ b/Client/game_sa/TaskPhysicalResponseSA.h @@ -14,8 +14,8 @@ #include #include "TaskSA.h" -#define FUNC_CTaskSimpleChoking__Constructor 0x6202C0 -#define FUNC_CTaskSimpleChoking__UpdateChoke 0x620660 +#define FUNC_CTaskSimpleChoking__Constructor 0x6202C0 +#define FUNC_CTaskSimpleChoking__UpdateChoke 0x620660 class CTaskSimpleChokingSAInterface : public CTaskSimpleSAInterface { @@ -31,7 +31,7 @@ class CTaskSimpleChokingSAInterface : public CTaskSimpleSAInterface class CTaskSimpleChokingSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleChoking { public: - CTaskSimpleChokingSA(){}; + CTaskSimpleChokingSA() {}; CTaskSimpleChokingSA(CPed* pAttacker, bool bIsTearGas); CPed* GetAttacker(); diff --git a/Client/game_sa/TaskSA.cpp b/Client/game_sa/TaskSA.cpp index cf71e8f8888..c183e33c65b 100644 --- a/Client/game_sa/TaskSA.cpp +++ b/Client/game_sa/TaskSA.cpp @@ -46,13 +46,10 @@ void CTaskSA::CreateTaskInterface(size_t nSize) DWORD dwFunc = FUNC_CTask__Operator_New; DWORD dwReturn = 0; - _asm - { - push nSize - call dwFunc - add esp, 4 - mov dwReturn, eax - } + // clang-format off + using func_t = decltype(dwReturn) (__cdecl*)(decltype(nSize)); +dwReturn = reinterpret_cast(dwFunc)(nSize); + // clang-format on TaskInterface = (CTaskSAInterface*)dwReturn; Parent = 0; @@ -63,12 +60,10 @@ CTask* CTaskSA::Clone() DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwFunc = GetInterface()->VTBL->Clone; DWORD dwReturn = 0; - _asm - { - mov ecx, dwThisInterface - call dwFunc - mov dwReturn, eax - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(dwThisInterface) ); +dwReturn = reinterpret_cast(dwFunc)(dwThisInterface); + // clang-format on return (CTask*)dwReturn; } @@ -84,15 +79,19 @@ CTask* CTaskSA::GetSubTask() { static CTaskManagementSystemSA* s_pTaskManagementSystem = pGame->GetTaskManagementSystem(); - DWORD dwThisInterface = (DWORD)GetInterface(); - DWORD dwFunc = GetInterface()->VTBL->GetSubTask; + CTaskSAInterface* pTaskInterface = GetInterface(); + if (!pTaskInterface) + return nullptr; + + DWORD dwFunc = pTaskInterface->VTBL->GetSubTask; + if (!dwFunc || dwFunc == 0x82263A) + return nullptr; + DWORD dwReturn = 0; - _asm - { - mov ecx, dwThisInterface - call dwFunc - mov dwReturn, eax - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(pTaskInterface) ); +dwReturn = reinterpret_cast(dwFunc)(pTaskInterface); + // clang-format on return s_pTaskManagementSystem->GetTask((CTaskSAInterface*)dwReturn); } @@ -101,12 +100,10 @@ bool CTaskSA::IsSimpleTask() DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwFunc = GetInterface()->VTBL->IsSimpleTask; bool bReturn = 0; - _asm - { - mov ecx, dwThisInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface) ); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface); + // clang-format on return bReturn; } @@ -117,14 +114,12 @@ int CTaskSA::GetTaskType() DWORD dwFunc = pTaskInterface->VTBL->GetTaskType; int iReturn = 9999; - if (dwFunc && dwFunc != 0x82263A) // some functions have no task type 0x82263A is purecal (assert?) + if (dwFunc && dwFunc != 0x82263A) // some functions have no task type 0x82263A is purecal (assert?) { - _asm - { - mov ecx, pTaskInterface - call dwFunc - mov iReturn, eax - } + // clang-format off + using func_t = decltype(iReturn) (__thiscall*)(decltype(pTaskInterface) ); +iReturn = reinterpret_cast(dwFunc)(pTaskInterface); + // clang-format on } return iReturn; } @@ -138,12 +133,10 @@ void CTaskSA::StopTimer(const CEvent* pEvent) DWORD dwFunc = GetInterface()->VTBL->StopTimer; if (dwFunc != 0x82263A && dwFunc) { - _asm - { - mov ecx, dwThisInterface - push pEvent - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(pEvent)); + reinterpret_cast(dwFunc)(dwThisInterface, pEvent); + // clang-format on } } @@ -160,17 +153,12 @@ bool CTaskSA::MakeAbortable(CPed* pPed, const int iPriority, const CEvent* pEven DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwFunc = GetInterface()->VTBL->MakeAbortable; bool bReturn = 0; - if (dwFunc != 0x82263A && dwFunc) // 82263A = purecall + if (dwFunc != 0x82263A && dwFunc) // 82263A = purecall { - _asm - { - mov ecx, dwThisInterface - push pEvent - push iPriority - push dwPedInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface), decltype(iPriority), decltype(pEvent)); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface, iPriority, pEvent); + // clang-format on } return bReturn; } @@ -178,43 +166,45 @@ bool CTaskSA::MakeAbortable(CPed* pPed, const int iPriority, const CEvent* pEven const char* CTaskSA::GetTaskName() { int iTaskType = GetTaskType(); - if (iTaskType != NO_TASK_TYPE) - if (TaskNames[iTaskType].szName) + if (iTaskType != NO_TASK_TYPE) { + if (TaskNames[iTaskType].szName) { return TaskNames[iTaskType].szName; - else + } else { return ""; +} +} return sNoTaskName; } void CTaskSA::Destroy() { - if (m_bBeingDestroyed) // we want to make sure we don't delete this twice or we get crashes :) - return; // our hook in CTaskManagementSystem will try to delete this otherwise + if (m_bBeingDestroyed) // we want to make sure we don't delete this twice or we get crashes :) + return; // our hook in CTaskManagementSystem will try to delete this otherwise m_bBeingDestroyed = true; DWORD dwThisInterface = (DWORD)GetInterface(); DWORD dwFunc = GetInterface()->VTBL->DeletingDestructor; if (dwFunc) { - _asm - { - mov ecx, dwThisInterface - push 1 // delete the task too - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(1)); + reinterpret_cast(dwFunc)(dwThisInterface, 1); + // clang-format on } /*dwFunc = FUNC_CTask__Operator_Delete; DWORD thisInterface = (DWORD)GetInterface(); if ( thisInterface ) { - _asm + // clang-format off + __asm { push thisInterface call dwFunc add esp, 4 } + // clang-format on }*/ delete this; @@ -222,8 +212,8 @@ void CTaskSA::Destroy() void CTaskSA::DestroyJustThis() { - if (m_bBeingDestroyed) // we want to make sure we don't delete this twice or we get crashes :) - return; // our hook in CTaskManagementSystem will try to delete this otherwise + if (m_bBeingDestroyed) // we want to make sure we don't delete this twice or we get crashes :) + return; // our hook in CTaskManagementSystem will try to delete this otherwise m_bBeingDestroyed = true; delete this; @@ -255,13 +245,10 @@ bool CTaskSimpleSA::ProcessPed(CPed* pPed) bool bReturn = 0; if (dwFunc != 0x82263A && dwFunc) { - _asm - { - mov ecx, dwThisInterface - push dwPedInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface)); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface); + // clang-format on } return bReturn; } @@ -278,13 +265,10 @@ bool CTaskSimpleSA::SetPedPosition(CPed* pPed) bool bReturn = 0; if (dwFunc != 0x82263A && dwFunc) { - _asm - { - mov ecx, dwThisInterface - push dwPedInterface - call dwFunc - mov bReturn, al - } + // clang-format off + using func_t = decltype(bReturn) (__thiscall*)(decltype(dwThisInterface), decltype(dwPedInterface)); +bReturn = reinterpret_cast(dwFunc)(dwThisInterface, dwPedInterface); + // clang-format on } return bReturn; } @@ -313,12 +297,10 @@ void CTaskComplexSA::SetSubTask(CTask* pSubTask) DWORD dwFunc = ((TaskComplexVTBL*)GetInterface()->VTBL)->SetSubTask; if (dwFunc != 0x82263A && dwFunc) { - _asm - { - mov ecx, dwThisInterface - push dwTaskInterface - call dwFunc - } + // clang-format off + using func_t = void (__thiscall*)(decltype(dwThisInterface), decltype(dwTaskInterface)); + reinterpret_cast(dwFunc)(dwThisInterface, dwTaskInterface); + // clang-format on } } @@ -326,22 +308,22 @@ CTask* CTaskComplexSA::CreateNextSubTask(CPed* pPed) { CPedSA* pPedSA = dynamic_cast(pPed); if (!pPedSA) - return NULL; + return nullptr; + + CTaskSAInterface* pTaskInterface = GetInterface(); + if (!pTaskInterface) + return nullptr; + + DWORD dwFunc = ((TaskComplexVTBL*)pTaskInterface->VTBL)->CreateNextSubTask; + if (!dwFunc || dwFunc == 0x82263A) + return nullptr; DWORD dwPedInterface = (DWORD)pPedSA->GetInterface(); - DWORD dwThisInterface = (DWORD)GetInterface(); - DWORD dwFunc = ((TaskComplexVTBL*)GetInterface()->VTBL)->CreateNextSubTask; DWORD dwReturn = 0; - if (dwFunc != 0x82263A && dwFunc) - { - _asm - { - mov ecx, dwThisInterface - push dwPedInterface - call dwFunc - mov dwReturn, eax - } - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(pTaskInterface), decltype(dwPedInterface)); +dwReturn = reinterpret_cast(dwFunc)(pTaskInterface, dwPedInterface); + // clang-format on return pGame->GetTaskManagementSystem()->GetTask((CTaskSAInterface*)dwReturn); } @@ -349,22 +331,22 @@ CTask* CTaskComplexSA::CreateFirstSubTask(CPed* pPed) { CPedSA* pPedSA = dynamic_cast(pPed); if (!pPedSA) - return NULL; + return nullptr; + + CTaskSAInterface* pTaskInterface = GetInterface(); + if (!pTaskInterface) + return nullptr; + + DWORD dwFunc = ((TaskComplexVTBL*)pTaskInterface->VTBL)->CreateFirstSubTask; + if (!dwFunc || dwFunc == 0x82263A) + return nullptr; DWORD dwPedInterface = (DWORD)pPedSA->GetInterface(); - DWORD dwThisInterface = (DWORD)GetInterface(); - DWORD dwFunc = ((TaskComplexVTBL*)GetInterface()->VTBL)->CreateFirstSubTask; DWORD dwReturn = 0; - if (dwFunc != 0x82263A && dwFunc) - { - _asm - { - mov ecx, dwThisInterface - push dwPedInterface - call dwFunc - mov dwReturn, eax - } - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(pTaskInterface), decltype(dwPedInterface)); +dwReturn = reinterpret_cast(dwFunc)(pTaskInterface, dwPedInterface); + // clang-format on return pGame->GetTaskManagementSystem()->GetTask((CTaskSAInterface*)dwReturn); } @@ -372,21 +354,21 @@ CTask* CTaskComplexSA::ControlSubTask(CPed* pPed) { CPedSA* pPedSA = dynamic_cast(pPed); if (!pPedSA) - return NULL; + return nullptr; + + CTaskSAInterface* pTaskInterface = GetInterface(); + if (!pTaskInterface) + return nullptr; + + DWORD dwFunc = ((TaskComplexVTBL*)pTaskInterface->VTBL)->ControlSubTask; + if (!dwFunc || dwFunc == 0x82263A) + return nullptr; DWORD dwPedInterface = (DWORD)pPedSA->GetInterface(); - DWORD dwThisInterface = (DWORD)GetInterface(); - DWORD dwFunc = ((TaskComplexVTBL*)GetInterface()->VTBL)->ControlSubTask; DWORD dwReturn = 0; - if (dwFunc != 0x82263A && dwFunc) - { - _asm - { - mov ecx, dwThisInterface - push dwPedInterface - call dwFunc - mov dwReturn, eax - } - } + // clang-format off + using func_t = decltype(dwReturn) (__thiscall*)(decltype(pTaskInterface), decltype(dwPedInterface)); +dwReturn = reinterpret_cast(dwFunc)(pTaskInterface, dwPedInterface); + // clang-format on return pGame->GetTaskManagementSystem()->GetTask((CTaskSAInterface*)dwReturn); } diff --git a/Client/game_sa/TaskSA.h b/Client/game_sa/TaskSA.h index 60e0333f9d3..649dab12460 100644 --- a/Client/game_sa/TaskSA.h +++ b/Client/game_sa/TaskSA.h @@ -14,14 +14,14 @@ #include #include "TaskNamesSA.h" -#define FUNC_CTask__Operator_New 0x61A5A0 -#define FUNC_CTask__Operator_Delete 0x61A5B0 +#define FUNC_CTask__Operator_New 0x61A5A0 +#define FUNC_CTask__Operator_Delete 0x61A5B0 class CTaskTimer { public: - DWORD dwTimeStart; // ? - DWORD dwTimeEnd; // ? + DWORD dwTimeStart; // ? + DWORD dwTimeEnd; // ? bool bSet; bool bStopped; }; @@ -57,7 +57,7 @@ class TaskComplexVTBL : public TaskVTBL class CTaskSAInterface { public: - TaskVTBL* VTBL; // cast to either TaskSimpleVTBL or TaskComplexVTBL + TaskVTBL* VTBL; // cast to either TaskSimpleVTBL or TaskComplexVTBL CTaskSAInterface* m_pParent; }; @@ -66,7 +66,7 @@ class CTaskSA : public virtual CTask private: // our variable(s) CTaskSAInterface* TaskInterface; - CTaskSA* Parent; // if the task was setup through an external source, this isn't going to be correct + CTaskSA* Parent; // if the task was setup through an external source, this isn't going to be correct bool m_bBeingDestroyed; public: @@ -84,10 +84,10 @@ class CTaskSA : public virtual CTask const char* GetTaskName(); // our function(s) - void SetInterface(CTaskSAInterface* pInterface) { TaskInterface = pInterface; }; + void SetInterface(CTaskSAInterface* pInterface) { TaskInterface = pInterface; }; CTaskSAInterface* GetInterface() noexcept { return TaskInterface; } const CTaskSAInterface* GetInterface() const noexcept { return TaskInterface; } - bool IsValid() { return GetInterface() != NULL; } + bool IsValid() { return GetInterface() != NULL; } void CreateTaskInterface(size_t nSize); @@ -111,7 +111,7 @@ class CTaskSimpleSAInterface : public CTaskSAInterface class CTaskSimpleSA : public virtual CTaskSA, public virtual CTaskSimple { public: - CTaskSimpleSA(){}; + CTaskSimpleSA() {}; bool ProcessPed(CPed* pPed); bool SetPedPosition(CPed* pPed); @@ -126,7 +126,7 @@ class CTaskComplexSAInterface : public CTaskSAInterface class CTaskComplexSA : public virtual CTaskSA, public virtual CTaskComplex { public: - CTaskComplexSA(){}; + CTaskComplexSA() {}; void SetSubTask(CTask* pSubTask); CTask* CreateNextSubTask(CPed* pPed); diff --git a/Client/game_sa/TaskSecondarySA.cpp b/Client/game_sa/TaskSecondarySA.cpp index 31662c8e876..ae37b3a659a 100644 --- a/Client/game_sa/TaskSecondarySA.cpp +++ b/Client/game_sa/TaskSecondarySA.cpp @@ -24,7 +24,8 @@ CTaskSimpleDuckSA::CTaskSimpleDuckSA(eDuckControlTypes nDuckControl, unsigned sh if (!IsValid()) return; DWORD dwThisInterface = (DWORD)GetInterface(); - _asm + // clang-format off + __asm { mov ecx, dwThisInterface push ebx @@ -36,4 +37,5 @@ CTaskSimpleDuckSA::CTaskSimpleDuckSA(eDuckControlTypes nDuckControl, unsigned sh call dwFunc pop ebx } + // clang-format on } diff --git a/Client/game_sa/TaskSecondarySA.h b/Client/game_sa/TaskSecondarySA.h index 963386b0c96..1aa57b79b60 100644 --- a/Client/game_sa/TaskSecondarySA.h +++ b/Client/game_sa/TaskSecondarySA.h @@ -18,7 +18,7 @@ // typedef int CAnimBlendAssociation ; typedef DWORD IKChain_c; -#define FUNC_CTaskSimpleDuck__Constructor 0x691FC0 +#define FUNC_CTaskSimpleDuck__Constructor 0x691FC0 // ############################################################################## // ## Name: CTaskSimpleDuck @@ -31,13 +31,13 @@ class CTaskSimpleDuckSAInterface : public CTaskSimpleSAInterface unsigned int m_nStartTime; unsigned short m_nLengthOfDuck; short m_nShotWhizzingCounter; - int* m_pDuckAnim; // was CAnimBlendAssociation - int* m_pMoveAnim; // was CAnimBlendAssociation + int* m_pDuckAnim; // was CAnimBlendAssociation + int* m_pMoveAnim; // was CAnimBlendAssociation bool m_bIsFinished; bool m_bIsAborting; - bool m_bNeedToSetDuckFlag; // incase bIsDucking flag gets cleared elsewhere - so we know to stop duck task - bool m_bIsInControl; // if duck task is being controlled by another task then it requires continuous control + bool m_bNeedToSetDuckFlag; // incase bIsDucking flag gets cleared elsewhere - so we know to stop duck task + bool m_bIsInControl; // if duck task is being controlled by another task then it requires continuous control CVector2D m_vecMoveCommand; unsigned char m_nDuckControlType; @@ -48,6 +48,6 @@ class CTaskSimpleDuckSAInterface : public CTaskSimpleSAInterface class CTaskSimpleDuckSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleDuck { public: - CTaskSimpleDuckSA(){}; + CTaskSimpleDuckSA() {}; CTaskSimpleDuckSA(eDuckControlTypes nDuckControl, unsigned short nLengthOfDuck = 0, short nUseShotsWhizzingEvents = -1); }; diff --git a/Client/game_sa/TaskSimpleSwimSA.cpp b/Client/game_sa/TaskSimpleSwimSA.cpp new file mode 100644 index 00000000000..98e9e36600c --- /dev/null +++ b/Client/game_sa/TaskSimpleSwimSA.cpp @@ -0,0 +1,23 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include "TaskSimpleSwimSA.h" +#include "CPedSA.h" + +CTaskSimpleSwimSA::CTaskSimpleSwimSA(CPed* ped, CVector* pos) +{ + CreateTaskInterface(sizeof(CTaskSimpleSAInterface)); + if (!IsValid()) + return; + + // Call the constructor + ((void(__thiscall*)(CTaskSimpleSwimSAInterface*, CVector*, CPedSAInterface*))0x688930)(static_cast(GetInterface()), pos, + ped ? ped->GetPedInterface() : nullptr); +} diff --git a/Client/game_sa/TaskSimpleSwimSA.h b/Client/game_sa/TaskSimpleSwimSA.h new file mode 100644 index 00000000000..2faea864ffc --- /dev/null +++ b/Client/game_sa/TaskSimpleSwimSA.h @@ -0,0 +1,59 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include +#include "TaskSA.h" +#include +#include +#include + +class CPedSAInterface; +class CEntitySAInterface; + +class CTaskSimpleSwimSAInterface : public CTaskSimpleSAInterface +{ +public: + bool m_finishedBlending; + bool m_animBlockRefAdded; + swimState m_swimState; + int m_animID; + float m_animSpeed; + CVector m_pos; + CPedSAInterface* m_ped; + float m_rotationX; + float m_turningRotationY; + float m_upperTorsoRotationX; + float m_aimingRotation; + float m_stateChanger; + CEntitySAInterface* m_entity; + CVector m_climbPos; + float m_angle; + SurfaceTypes::Enum m_surfaceType; + std::uint8_t m_field4D[3]; + float m_randomMoveBlendRatio; + float m_swimStopTime; + std::uint32_t m_timeStep; + void* m_fxSystem; // FxSystem_cSAInterface* + bool m_triggerWaterSplash; + std::uint8_t m_field61[3]; +}; + +class CTaskSimpleSwimSA : public virtual CTaskSimpleSA, public virtual CTaskSimpleSwim +{ +public: + CTaskSimpleSwimSA() {}; + CTaskSimpleSwimSA(CPed* ped, CVector* pos); + + const CTaskSimpleSwimSAInterface* GetTaskInterface() const { return static_cast(GetInterface()); } + CTaskSimpleSwimSAInterface* GetTaskInterface() { return static_cast(GetInterface()); } + + swimState GetSwimState() const override { return GetTaskInterface()->m_swimState; } +}; diff --git a/Client/game_sa/gamesa_renderware.h b/Client/game_sa/gamesa_renderware.h index bd1cf14323d..9455a59da76 100644 --- a/Client/game_sa/gamesa_renderware.h +++ b/Client/game_sa/gamesa_renderware.h @@ -13,6 +13,7 @@ #pragma once #include +#include struct CColModelSAInterface; @@ -21,8 +22,8 @@ struct CColModelSAInterface; /*****************************************************************************/ /* RenderWare macros */ -#define RpGetFrame(__c) ((RwFrame*)(((RwObject *)(__c))->parent)) -#define RpSetFrame(__c,__f) ((((RwObject *)(__c))->parent) = (void *)(__f)) +#define RpGetFrame(__c) ((RwFrame*)(((RwObject*)(__c))->parent)) +#define RpSetFrame(__c, __f) ((((RwObject*)(__c))->parent) = (void*)(__f)) /* RenderWare function defines */ typedef RpAtomic*(__cdecl* RpAtomicCreate_t)(); @@ -67,6 +68,7 @@ typedef int(__cdecl* RpMaterialDestroy_t)(RpMaterial* mat); typedef RwTexDictionary*(__cdecl* RwTexDictionarySetCurrent_t)(RwTexDictionary* dict); typedef const RwTexDictionary*(__cdecl* RwTexDictionaryForAllTextures_t)(const RwTexDictionary* dict, void* callback, void* data); typedef RwTexture*(__cdecl* RwTexDictionaryAddTexture_t)(RwTexDictionary* dict, RwTexture* texture); +typedef RwTexture*(__cdecl* RwTexDictionaryRemoveTexture_t)(RwTexture* texture); typedef RwTexDictionary*(__cdecl* RwTexDictionaryGetCurrent_t)(); typedef RwTexture*(__cdecl* RwTexDictionaryFindNamedTexture_t)(RwTexDictionary* dict, const char* name); typedef void(__cdecl* RpPrtStdGlobalDataSetStreamEmbedded_t)(void* value); @@ -79,6 +81,7 @@ typedef RwV3d*(__cdecl* RwV3dTransformVector_t)(RwV3d* out, const RwV3d* in, con typedef void(__cdecl* _rwObjectHasFrameSetFrame_t)(void* object, RwFrame* frame); typedef RwCamera*(__cdecl* RwCameraClone_t)(RwCamera* camera); typedef RpClump*(__cdecl* RpClumpClone_t)(RpClump* clone); +typedef RwTexDictionary*(__cdecl* RwTexDictionaryCreate_t)(); typedef int(__cdecl* RwTexDictionaryDestroy_t)(RwTexDictionary* txd); typedef int(__cdecl* RwTextureDestroy_t)(RwTexture* texture); typedef int(__cdecl* RwStreamFindChunk_t)(RwStream* stream, unsigned int type, unsigned int* lengthOut, unsigned int* versionOut); @@ -111,9 +114,9 @@ typedef RtQuat*(__cdecl* RtQuatRotate_t)(RtQuat* quat, const RwV3d* axis, float /*****************************************************************************/ #ifdef RWFUNC_IMPLEMENT - #define RWFUNC(a,b) a = b; + #define RWFUNC(a, b) a = b; #else - #define RWFUNC(a,b) extern a; + #define RWFUNC(a, b) extern a; #endif // US Versions @@ -138,6 +141,7 @@ RWFUNC(RwTexDictionaryGetCurrent_t RwTexDictionaryGetCurrent, (RwTexDictionaryGe RWFUNC(RwTexDictionarySetCurrent_t RwTexDictionarySetCurrent, (RwTexDictionarySetCurrent_t)0xDEAD) RWFUNC(RwTexDictionaryForAllTextures_t RwTexDictionaryForAllTextures, (RwTexDictionaryForAllTextures_t)0xDEAD) RWFUNC(RwTexDictionaryAddTexture_t RwTexDictionaryAddTexture, (RwTexDictionaryAddTexture_t)0xDEAD) +RWFUNC(RwTexDictionaryRemoveTexture_t RwTexDictionaryRemoveTexture, (RwTexDictionaryRemoveTexture_t)0xDEAD) RWFUNC(RwTexDictionaryStreamWrite_t RwTexDictionaryStreamWrite, (RwTexDictionaryStreamWrite_t)0xDEAD) RWFUNC(rwD3D9NativeTextureRead_t rwD3D9NativeTextureRead, (rwD3D9NativeTextureRead_t)0xDEAD) RWFUNC(RpPrtStdGlobalDataSetStreamEmbedded_t RpPrtStdGlobalDataSetStreamEmbedded, (RpPrtStdGlobalDataSetStreamEmbedded_t)0xDEAD) @@ -183,6 +187,7 @@ RWFUNC(RpWorldAddLight_t RpWorldAddLight, (RpWorldAddLight_t)0xDEAD) RWFUNC(RpLightSetColor_t RpLightSetColor, (RpLightSetColor_t)0xDEAD) RWFUNC(RwCameraClone_t RwCameraClone, (RwCameraClone_t)0xDEAD) RWFUNC(RpClumpClone_t RpClumpClone, (RpClumpClone_t)0xDEAD) +RWFUNC(RwTexDictionaryCreate_t RwTexDictionaryCreate, (RwTexDictionaryCreate_t)0xDEAD) RWFUNC(RwTexDictionaryDestroy_t RwTexDictionaryDestroy, (RwTexDictionaryDestroy_t)0xDEAD) RWFUNC(RwTextureDestroy_t RwTextureDestroy, (RwTextureDestroy_t)0xDEAD) RWFUNC(RwRasterUnlock_t RwRasterUnlock, (RwRasterUnlock_t)0xDEAD) @@ -201,18 +206,21 @@ RWFUNC(RtQuatRotate_t RtQuatRotate, (RtQuatRotate_t)0xDEAD) /*****************************************************************************/ typedef bool(__cdecl* SetTextureDict_t)(unsigned short id); -typedef bool(__cdecl* LoadClumpFile_t)(RwStream* stream, unsigned int id); // (stream, model id) -typedef bool(__cdecl* LoadModel_t)(RwBuffer* filename, unsigned int id); // (memory chunk, model id) +typedef bool(__cdecl* LoadClumpFile_t)(RwStream* stream, unsigned int id); // (stream, model id) +typedef bool(__cdecl* LoadModel_t)(RwBuffer* filename, unsigned int id); // (memory chunk, model id) typedef void(__cdecl* LoadCollisionModel_t)(unsigned char*, CColModelSAInterface*, const char*); typedef void(__cdecl* LoadCollisionModelVer2_t)(unsigned char*, unsigned int, CColModelSAInterface*, const char*); typedef void(__cdecl* LoadCollisionModelVer3_t)(unsigned char*, unsigned int, CColModelSAInterface*, - const char*); // buf, bufsize, ccolmodel&, keyname + const char*); // buf, bufsize, ccolmodel&, keyname +typedef void(__cdecl* LoadCollisionModelVer4_t)(unsigned char*, unsigned int, CColModelSAInterface*, + const char*); // buf, bufsize, ccolmodel&, keyname typedef bool(__cdecl* CTxdStore_LoadTxd_t)(unsigned int id, RwStream* filename); typedef void(__cdecl* CTxdStore_RemoveTxd_t)(unsigned int id); typedef void(__cdecl* CTxdStore_RemoveRef_t)(unsigned int id); typedef void(__cdecl* CTxdStore_AddRef_t)(unsigned int id); typedef int(__cdecl* CTxdStore_GetNumRefs_t)(unsigned int id); typedef RwTexDictionary*(__cdecl* CTxdStore_GetTxd_t)(unsigned int id); +typedef void(__cdecl* CTxdStore_SetupTxdParent_t)(unsigned int id); typedef RwTexture*(__cdecl* CClothesBuilder_CopyTexture_t)(RwTexture* texture); RWFUNC(SetTextureDict_t SetTextureDict, (SetTextureDict_t)0xDEAD) @@ -221,12 +229,14 @@ RWFUNC(LoadModel_t LoadModel, (LoadModel_t)0xDEAD) RWFUNC(LoadCollisionModel_t LoadCollisionModel, (LoadCollisionModel_t)0xDEAD) RWFUNC(LoadCollisionModelVer2_t LoadCollisionModelVer2, (LoadCollisionModelVer2_t)0xDEAD) RWFUNC(LoadCollisionModelVer3_t LoadCollisionModelVer3, (LoadCollisionModelVer3_t)0xDEAD) +RWFUNC(LoadCollisionModelVer4_t LoadCollisionModelVer4, (LoadCollisionModelVer4_t)0xDEAD) RWFUNC(CTxdStore_LoadTxd_t CTxdStore_LoadTxd, (CTxdStore_LoadTxd_t)0xDEAD) RWFUNC(CTxdStore_GetTxd_t CTxdStore_GetTxd, (CTxdStore_GetTxd_t)0xDEAD) RWFUNC(CTxdStore_RemoveTxd_t CTxdStore_RemoveTxd, (CTxdStore_RemoveTxd_t)0xDEAD) RWFUNC(CTxdStore_RemoveRef_t CTxdStore_RemoveRef, (CTxdStore_RemoveRef_t)0xDEAD) RWFUNC(CTxdStore_AddRef_t CTxdStore_AddRef, (CTxdStore_AddRef_t)0xDEAD) RWFUNC(CTxdStore_GetNumRefs_t CTxdStore_GetNumRefs, (CTxdStore_GetNumRefs_t)0xDEAD) +RWFUNC(CTxdStore_SetupTxdParent_t CTxdStore_SetupTxdParent, (CTxdStore_SetupTxdParent_t)0xDEAD) RWFUNC(CClothesBuilder_CopyTexture_t CClothesBuilder_CopyTexture, (CClothesBuilder_CopyTexture_t)0xDEAD) /*****************************************************************************/ @@ -238,8 +248,8 @@ inline void RwFrameCopyMatrix(RwFrame* dst, RwFrame* src) { if (dst == NULL || src == NULL) return; - MemCpyFast(&dst->modelling, &src->modelling, sizeof(RwMatrix)); - MemCpyFast(&dst->ltm, &src->ltm, sizeof(RwMatrix)); + std::memcpy(&dst->modelling, &src->modelling, sizeof(RwMatrix)); + std::memcpy(&dst->ltm, &src->ltm, sizeof(RwMatrix)); } // Recursive RwFrame children searching function diff --git a/Client/game_sa/gamesa_renderware.hpp b/Client/game_sa/gamesa_renderware.hpp index 86da3e19583..dd6d5f442df 100644 --- a/Client/game_sa/gamesa_renderware.hpp +++ b/Client/game_sa/gamesa_renderware.hpp @@ -32,6 +32,7 @@ void InitRwFunctions() RwTexDictionarySetCurrent = (RwTexDictionarySetCurrent_t)0x007F3A70; RwTexDictionaryForAllTextures = (RwTexDictionaryForAllTextures_t)0x007F3730; RwTexDictionaryAddTexture = (RwTexDictionaryAddTexture_t)0x007F3980; + RwTexDictionaryRemoveTexture = (RwTexDictionaryRemoveTexture_t)0x007F39C0; RwTexDictionaryStreamWrite = (RwTexDictionaryStreamWrite_t)0x008049F0; rwD3D9NativeTextureRead = (rwD3D9NativeTextureRead_t)0x004CD820; RpPrtStdGlobalDataSetStreamEmbedded = (RpPrtStdGlobalDataSetStreamEmbedded_t)0x0041B350; @@ -77,6 +78,7 @@ void InitRwFunctions() RpLightSetColor = (RpLightSetColor_t)0x00751A90; RwCameraClone = (RwCameraClone_t)0x007EF3B0; RpClumpClone = (RpClumpClone_t)0x00749F70; + RwTexDictionaryCreate = (RwTexDictionaryCreate_t)0x007F3600; RwTexDictionaryDestroy = (RwTexDictionaryDestroy_t)0x007F36A0; RwTextureDestroy = (RwTextureDestroy_t)0x007F3820; RwRasterUnlock = (RwRasterUnlock_t)0x007FAEC0; @@ -89,18 +91,20 @@ void InitRwFunctions() RpHAnimIDGetIndex = (RpHAnimIDGetIndex_t)0x7C51A0; RpHAnimHierarchyGetMatrixArray = (RpHAnimHierarchyGetMatrixArray_t)0x7C5120; RtQuatRotate = (RtQuatRotate_t)0x7EB7C0; - + SetTextureDict = (SetTextureDict_t)0x007319C0; LoadClumpFile = (LoadClumpFile_t)0x005371F0; LoadModel = (LoadModel_t)0x0040C6B0; LoadCollisionModel = (LoadCollisionModel_t)0x00537580; LoadCollisionModelVer2 = (LoadCollisionModelVer2_t)0x00537EE0; LoadCollisionModelVer3 = (LoadCollisionModelVer3_t)0x00537CE0; + LoadCollisionModelVer4 = (LoadCollisionModelVer4_t)0x00537AE0; CTxdStore_LoadTxd = (CTxdStore_LoadTxd_t)0x00731DD0; CTxdStore_GetTxd = (CTxdStore_GetTxd_t)0x00408340; CTxdStore_RemoveTxd = (CTxdStore_RemoveTxd_t)0x00731E90; CTxdStore_RemoveRef = (CTxdStore_RemoveRef_t)0x00731A30; CTxdStore_AddRef = (CTxdStore_AddRef_t)0x00731A00; CTxdStore_GetNumRefs = (CTxdStore_GetNumRefs_t)0x00731AA0; + CTxdStore_SetupTxdParent = (CTxdStore_SetupTxdParent_t)0x00731D50; CClothesBuilder_CopyTexture = (CClothesBuilder_CopyTexture_t)0x005A5730; } diff --git a/Client/game_sa/premake5.lua b/Client/game_sa/premake5.lua index 588a4178cc8..7b99ef62974 100644 --- a/Client/game_sa/premake5.lua +++ b/Client/game_sa/premake5.lua @@ -3,10 +3,18 @@ project "Game SA" kind "SharedLib" targetname "game_sa" targetdir(buildpath("mta")) - - -- HACK(Jusonex): Temp fix for ebp not being set in naked functions - -- More information on this in multiplayer_sa's premake5.lua - cppdialect "C++14" + clangtidy "On" + + -- DO NOT REMOVE OR TURN THIS OPTION ON + -- By turning this feature off, our code will be compiled with '/Zi' instead of '/ZI'. + -- By enabling 'Edit and Continue' the compiler expects us to allocate enough stack space + -- using __LOCAL_SIZE to ensure enough local space within __declspec(naked) functions for + -- this feature. Our hook functions will never support this feature, because most of the + -- time our hook functions don't have proper epilog code and neither prolog code. + -- This is especially important for our post-build checking of __LOCAL_SIZE. + -- https://learn.microsoft.com/en-us/cpp/cpp/considerations-for-writing-prolog-epilog-code + -- https://learn.microsoft.com/en-us/cpp/build/reference/z7-zi-zi-debug-information-format + editandcontinue "Off" pchheader "StdInc.h" pchsource "StdInc.cpp" @@ -35,6 +43,10 @@ project "Game SA" "**.cpp" } + postbuildcommands { + "%[%{!wks.location}/../utils/hookcheck.exe] -dll:%[$(TargetPath)] -ignore:\\vendor\\" + } + filter "architecture:not x86" flags { "ExcludeFromBuild" } diff --git a/Client/gui/CGUIButton_Impl.cpp b/Client/gui/CGUIButton_Impl.cpp index 8abbc23204d..499fd48dcdc 100644 --- a/Client/gui/CGUIButton_Impl.cpp +++ b/Client/gui/CGUIButton_Impl.cpp @@ -15,7 +15,7 @@ CGUIButton_Impl::CGUIButton_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, const char* szCaption) { - m_pManager = pGUI; + SetManager(pGUI); // Get an unique identifier for CEGUI (gah, there's gotta be an another way) char szUnique[CGUI_CHAR_SIZE]; diff --git a/Client/gui/CGUIButton_Impl.h b/Client/gui/CGUIButton_Impl.h index e611af86fae..e215bf3f460 100644 --- a/Client/gui/CGUIButton_Impl.h +++ b/Client/gui/CGUIButton_Impl.h @@ -22,5 +22,5 @@ class CGUIButton_Impl : public CGUIButton, public CGUIElement_Impl eCGUIType GetType() { return CGUI_BUTTON; }; - #include "CGUIElement_Inc.h" +#include "CGUIElement_Inc.h" }; diff --git a/Client/gui/CGUICheckBox_Impl.cpp b/Client/gui/CGUICheckBox_Impl.cpp index db297e02538..319a8e32d43 100644 --- a/Client/gui/CGUICheckBox_Impl.cpp +++ b/Client/gui/CGUICheckBox_Impl.cpp @@ -15,7 +15,7 @@ CGUICheckBox_Impl::CGUICheckBox_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, const char* szCaption, bool bChecked) { - m_pManager = pGUI; + SetManager(pGUI); // Get an unique identifier for CEGUI (gah, there's gotta be an another way) char szUnique[CGUI_CHAR_SIZE]; diff --git a/Client/gui/CGUICheckBox_Impl.h b/Client/gui/CGUICheckBox_Impl.h index 3755f600788..7a926cedd98 100644 --- a/Client/gui/CGUICheckBox_Impl.h +++ b/Client/gui/CGUICheckBox_Impl.h @@ -25,5 +25,5 @@ class CGUICheckBox_Impl : public CGUICheckBox, public CGUIElement_Impl eCGUIType GetType() { return CGUI_CHECKBOX; }; - #include "CGUIElement_Inc.h" +#include "CGUIElement_Inc.h" }; diff --git a/Client/gui/CGUIComboBox_Impl.cpp b/Client/gui/CGUIComboBox_Impl.cpp index 94889c7646f..3289595a206 100644 --- a/Client/gui/CGUIComboBox_Impl.cpp +++ b/Client/gui/CGUIComboBox_Impl.cpp @@ -15,7 +15,7 @@ CGUIComboBox_Impl::CGUIComboBox_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, const char* szCaption) { - m_pManager = pGUI; + SetManager(pGUI); // Get an unique identifier for CEGUI (gah, there's gotta be an another way) char szUnique[CGUI_CHAR_SIZE]; @@ -83,7 +83,7 @@ bool CGUIComboBox_Impl::RemoveItem(int index) try { CEGUI::ListboxItem* pItem = reinterpret_cast(m_pWindow)->getListboxItemFromIndex(index); - if (pItem->isSelected()) // if this is currently selected, let's update the editbox. + if (pItem->isSelected()) // if this is currently selected, let's update the editbox. { m_pWindow->setText(storedCaption); } @@ -178,7 +178,7 @@ bool CGUIComboBox_Impl::SetItemText(int index, const char* szText) { CEGUI::ListboxItem* pItem = reinterpret_cast(m_pWindow)->getListboxItemFromIndex(index); pItem->setText(CGUI_Impl::GetUTFString(szText), NULL); - if (pItem->isSelected()) // if this is currently selected, let's update the editbox. + if (pItem->isSelected()) // if this is currently selected, let's update the editbox. { m_pWindow->setText(CGUI_Impl::GetUTFString(szText)); } diff --git a/Client/gui/CGUIComboBox_Impl.h b/Client/gui/CGUIComboBox_Impl.h index cd84a8e647b..9d4613f1537 100644 --- a/Client/gui/CGUIComboBox_Impl.h +++ b/Client/gui/CGUIComboBox_Impl.h @@ -44,7 +44,7 @@ class CGUIComboBox_Impl : public CGUIComboBox, public CGUIElement_Impl void ShowDropList(); void HideDropList(); - #include "CGUIElement_Inc.h" +#include "CGUIElement_Inc.h" protected: CFastHashMap m_Items; diff --git a/Client/gui/CGUIEdit_Impl.cpp b/Client/gui/CGUIEdit_Impl.cpp index ccea0156d56..3e179234bf6 100644 --- a/Client/gui/CGUIEdit_Impl.cpp +++ b/Client/gui/CGUIEdit_Impl.cpp @@ -15,7 +15,7 @@ CGUIEdit_Impl::CGUIEdit_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, const char* szEdit) { - m_pManager = pGUI; + SetManager(pGUI); // Get an unique identifier for CEGUI (gah, there's gotta be an another way) char szUnique[CGUI_CHAR_SIZE]; diff --git a/Client/gui/CGUIEdit_Impl.h b/Client/gui/CGUIEdit_Impl.h index 8edfbff1175..966324c51f0 100644 --- a/Client/gui/CGUIEdit_Impl.h +++ b/Client/gui/CGUIEdit_Impl.h @@ -47,7 +47,7 @@ class CGUIEdit_Impl : public CGUIEdit, public CGUIElement_Impl, public CGUITabLi eCGUIType GetType() { return CGUI_EDIT; }; - #include "CGUIElement_Inc.h" +#include "CGUIElement_Inc.h" protected: bool Event_OnTextChanged(const CEGUI::EventArgs& e); diff --git a/Client/gui/CGUIElement_Impl.cpp b/Client/gui/CGUIElement_Impl.cpp index 6dd92ece237..4e9fa9a6807 100644 --- a/Client/gui/CGUIElement_Impl.cpp +++ b/Client/gui/CGUIElement_Impl.cpp @@ -10,12 +10,13 @@ *****************************************************************************/ #include "StdInc.h" +#include "CGUI_Impl.h" // Define no-drawing zones, a.k.a. the inside borders in the FrameWindow of BlueLook in pixels // If something is drawn inside of these areas, the theme border is drawn on top of it -#define CGUI_NODRAW_LEFT 9.0f -#define CGUI_NODRAW_RIGHT 9.0f -#define CGUI_NODRAW_TOP 9.0f +#define CGUI_NODRAW_LEFT 9.0f +#define CGUI_NODRAW_RIGHT 9.0f +#define CGUI_NODRAW_TOP 9.0f #define CGUI_NODRAW_BOTTOM 9.0f CGUIElement_Impl::CGUIElement_Impl() @@ -24,20 +25,65 @@ CGUIElement_Impl::CGUIElement_Impl() m_pWindow = NULL; m_pParent = NULL; m_pManager = NULL; + m_redrawHandle = CGUI_Impl::kInvalidRedrawHandle; +} + +void CGUIElement_Impl::SetManager(CGUI_Impl* pManager) +{ + if (m_pManager == pManager) + return; + + if (m_pManager && m_redrawHandle != CGUI_Impl::kInvalidRedrawHandle) + { + m_pManager->ReleaseRedrawHandle(m_redrawHandle); + m_redrawHandle = CGUI_Impl::kInvalidRedrawHandle; + } + + m_pManager = pManager; + + if (m_pManager) + { + m_redrawHandle = m_pManager->RegisterRedrawHandle(this); + } +} + +void CGUIElement_Impl::UnregisterFromRedrawQueue() +{ + if (m_pManager && m_redrawHandle != CGUI_Impl::kInvalidRedrawHandle) + { + m_pManager->RemoveFromRedrawQueue(this); + } } void CGUIElement_Impl::DestroyElement() { - m_pManager->RemoveFromRedrawQueue(reinterpret_cast((m_pWindow)->getUserData())); + UnregisterFromRedrawQueue(); - // Clear pointer back to this - m_pWindow->setUserData(NULL); + if (m_pWindow) + { + // Clear pointer back to this + m_pWindow->setUserData(NULL); - // Destroy the control - m_pManager->GetWindowManager()->destroyWindow(m_pWindow); + if (m_pManager) + { + // Destroy the control + m_pManager->GetWindowManager()->destroyWindow(m_pWindow); + } + m_pWindow = NULL; + } // Destroy the properties list EmptyProperties(); + + if (m_pManager && m_redrawHandle != CGUI_Impl::kInvalidRedrawHandle) + { + m_pManager->ReleaseRedrawHandle(m_redrawHandle); + } + + m_redrawHandle = CGUI_Impl::kInvalidRedrawHandle; + m_pParent = NULL; + m_pData = NULL; + m_pManager = NULL; } void CGUIElement_Impl::SetVisible(bool bVisible) @@ -174,7 +220,7 @@ void CGUIElement_Impl::AutoSize(const char* Text, float fPaddingX, float fPaddin const CEGUI::Font* pFont = m_pWindow->getFont(); m_pWindow->setSize(CEGUI::Absolute, CEGUI::Size(pFont->getTextExtent(CGUI_Impl::GetUTFString(Text ? Text : GetText())) + fPaddingX, - pFont->getFontHeight() + fPaddingY)); // Add hack factor to height to allow for long characters such as 'g' or 'j' + pFont->getFontHeight() + fPaddingY)); // Add hack factor to height to allow for long characters such as 'g' or 'j' } void CGUIElement_Impl::SetMinimumSize(const CVector2D& vecSize) @@ -326,11 +372,6 @@ CGUIElement* CGUIElement_Impl::GetParent() return m_pParent; } -CEGUI::Window* CGUIElement_Impl::GetWindow() -{ - return m_pWindow; -} - void CGUIElement_Impl::CorrectEdges() { CEGUI::Point currentPoint = m_pWindow->getPosition(CEGUI::Absolute); diff --git a/Client/gui/CGUIElement_Impl.h b/Client/gui/CGUIElement_Impl.h index 5a7547b97cd..9f85a5be0f9 100644 --- a/Client/gui/CGUIElement_Impl.h +++ b/Client/gui/CGUIElement_Impl.h @@ -14,12 +14,13 @@ #include #include +#include namespace CEGUI { class Window; class EventArgs; -} // namespace CEGUI +} // namespace CEGUI class CGUI_Impl; class CGUIElement_Impl : public CGUIElement @@ -27,6 +28,8 @@ class CGUIElement_Impl : public CGUIElement public: CGUIElement_Impl(); + void SetManager(CGUI_Impl* pManager); + void SetVisible(bool bVisible); bool IsVisible(); @@ -90,7 +93,10 @@ class CGUIElement_Impl : public CGUIElement void SetParent(CGUIElement* pParent); CGUIElement* GetParent(); - CEGUI::Window* GetWindow(); + CEGUI::Window* GetWindow() const { return m_pWindow; } + CGUI_Impl* GetManager() const { return m_pManager; } + std::uint32_t GetRedrawHandle() const { return m_redrawHandle; } + void UnregisterFromRedrawQueue(); void ForceRedraw(); @@ -140,6 +146,8 @@ class CGUIElement_Impl : public CGUIElement CGUI_Impl* m_pManager; + std::uint32_t m_redrawHandle; + void* m_pData; std::list m_Properties; diff --git a/Client/gui/CGUIElement_Inc.h b/Client/gui/CGUIElement_Inc.h index 026b07d86f5..250fa22cfba 100644 --- a/Client/gui/CGUIElement_Inc.h +++ b/Client/gui/CGUIElement_Inc.h @@ -98,7 +98,7 @@ void SetHeight(float fY, bool bRelative = false) CGUIElement_Impl::SetHeight(fY, bRelative); }; -#ifndef EXCLUDE_SET_SIZE // WTF? TODO: Refactor this +#ifndef EXCLUDE_SET_SIZE // WTF? TODO: Refactor this void SetSize(const CVector2D& vecSize, bool bRelative = false) { CGUIElement_Impl::SetSize(vecSize, bRelative); diff --git a/Client/gui/CGUIFont_Impl.cpp b/Client/gui/CGUIFont_Impl.cpp index eaf02b2a0f0..7ab80996f40 100644 --- a/Client/gui/CGUIFont_Impl.cpp +++ b/Client/gui/CGUIFont_Impl.cpp @@ -88,7 +88,7 @@ void CGUIFont_Impl::SetNativeResolution(int iX, int iY) float CGUIFont_Impl::GetCharacterWidth(int iChar, float fScale) { char szBuf[2]; - szBuf[0] = iChar; + szBuf[0] = static_cast(iChar); szBuf[1] = 0; return m_pFont->getTextExtent(szBuf, fScale); @@ -96,8 +96,8 @@ float CGUIFont_Impl::GetCharacterWidth(int iChar, float fScale) float CGUIFont_Impl::GetFontHeight(float fScale) { - float fHeight = m_pFont->getFontHeight(fScale); // average height.. not the maximum height for long characters such as 'g' or 'j' - fHeight += 2.0f; // so hack it + float fHeight = m_pFont->getFontHeight(fScale); // average height.. not the maximum height for long characters such as 'g' or 'j' + fHeight += 2.0f; // so hack it return fHeight; } diff --git a/Client/gui/CGUIGridList_Impl.cpp b/Client/gui/CGUIGridList_Impl.cpp index b8c97911fe9..7145fbbcd99 100644 --- a/Client/gui/CGUIGridList_Impl.cpp +++ b/Client/gui/CGUIGridList_Impl.cpp @@ -11,20 +11,55 @@ #include "StdInc.h" -#define CGUIGRIDLIST_NAME "CGUI/MultiColumnList" -#define CGUIGRIDLISTNOFRAME_NAME "CGUI/MultiColumnList" //MultiColumnListNoFrame -#define CGUIGRIDLIST_SPACER " " +namespace +{ + constexpr const char kGridListName[] = "CGUI/MultiColumnList"; + constexpr const char kGridListNoFrameName[] = "CGUI/MultiColumnList"; // MultiColumnListNoFrame + constexpr const char kGridListSpacer[] = " "; + constexpr std::size_t kGridListSpacerLength = (sizeof(kGridListSpacer) / sizeof(char)) - 1; + constexpr std::size_t kGridListMaxTextLength = 256; + + constexpr CEGUI::ListHeaderSegment::SortDirection ToCeguiSortDirection(SortDirection direction) noexcept + { + switch (direction) + { + case SortDirections::Ascending: + return CEGUI::ListHeaderSegment::Ascending; + case SortDirections::Descending: + return CEGUI::ListHeaderSegment::Descending; + default: + return CEGUI::ListHeaderSegment::None; + } + } + + constexpr SortDirection FromCeguiSortDirection(CEGUI::ListHeaderSegment::SortDirection direction) noexcept + { + switch (direction) + { + case CEGUI::ListHeaderSegment::Ascending: + return SortDirections::Ascending; + case CEGUI::ListHeaderSegment::Descending: + return SortDirections::Descending; + default: + return SortDirections::None; + } + } + + inline unsigned int NormalizeSortColumn(unsigned int requestedColumn, unsigned int columnCount) noexcept + { + if (columnCount == 0) + return 0; + + if (requestedColumn == 0 || requestedColumn > columnCount) + return columnCount; -#define CGUIGRIDLIST_MAX_TEXT_LENGTH 256 + return requestedColumn; + } +} CGUIGridList_Impl::CGUIGridList_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, bool bFrame) { - m_pManager = pGUI; - - // Initialize - m_hUniqueHandle = 0; - m_iIndex = 0; - m_bIgnoreTextSpacer = false; + SetManager(pGUI); // Get an unique identifier for CEGUI (gah, there's gotta be an another way) char szUnique[CGUI_CHAR_SIZE]; @@ -32,9 +67,9 @@ CGUIGridList_Impl::CGUIGridList_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, bool // Create the window and set default settings if (bFrame) - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUIGRIDLIST_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(kGridListName, szUnique); else - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUIGRIDLISTNOFRAME_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(kGridListNoFrameName, szUnique); m_pWindow->setDestroyedByParent(false); m_pWindow->setRect(CEGUI::Relative, CEGUI::Rect(0.00f, 0.00f, 0.40f, 0.40f)); @@ -49,6 +84,7 @@ CGUIGridList_Impl::CGUIGridList_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, bool // Register our events m_pWindow->subscribeEvent(CEGUI::MultiColumnList::EventSortColumnChanged, CEGUI::Event::Subscriber(&CGUIGridList_Impl::Event_OnSortColumn, this)); + m_pWindow->subscribeEvent(CEGUI::MultiColumnList::EventSelectionChanged, CEGUI::Event::Subscriber(&CGUIGridList_Impl::Event_OnSelectionChanged, this)); AddEvents(); // If a parent is specified, add it to it's children list, if not, add it as a child to the pManager @@ -79,6 +115,44 @@ bool CGUIGridList_Impl::IsSortingEnabled() return reinterpret_cast(m_pWindow)->isUserSortControlEnabled(); } +void CGUIGridList_Impl::SetAutoSortSuppressed(bool bSuppressed) +{ + if (m_bAutoSortSuppressed == bSuppressed) + return; + + CEGUI::MultiColumnList* pList = reinterpret_cast(m_pWindow); + + if (bSuppressed) + { + m_bAutoSortSuppressed = true; + m_uiPendingSortColumn = static_cast(pList->getSortColumn() + 1); + m_PendingSortDirection = FromCeguiSortDirection(pList->getSortDirection()); + pList->setSortDirection(CEGUI::ListHeaderSegment::None); + UpdateSortIndicator(m_uiPendingSortColumn, m_PendingSortDirection); + return; + } + + m_bAutoSortSuppressed = false; + + const unsigned int columnCount = static_cast(pList->getColumnCount()); + if (columnCount == 0) + { + m_uiPendingSortColumn = 0; + m_PendingSortDirection = SortDirections::None; + return; + } + + const unsigned int column = NormalizeSortColumn(m_uiPendingSortColumn, columnCount); + UpdateSortIndicator(0, SortDirections::None); + pList->setSortColumn(GetColumnIndex(column)); + pList->setSortDirection(ToCeguiSortDirection(m_PendingSortDirection)); +} + +bool CGUIGridList_Impl::IsAutoSortSuppressed() const +{ + return m_bAutoSortSuppressed; +} + void CGUIGridList_Impl::RemoveColumn(unsigned int uiColumn) { try @@ -200,20 +274,25 @@ int CGUIGridList_Impl::AddRow(bool fast, std::vector >* int CGUIGridList_Impl::SetRowItemsText(int iRow, std::vector >* m_items) { - int iSortColumn = reinterpret_cast(m_pWindow)->getSortColumn() + 1; // MTA columns start at 1, CEGUI at 0 + const int sortColumn = reinterpret_cast(m_pWindow)->getSortColumn() + 1; // MTA columns start at 1, CEGUI at 0 + + int column = 1; + for (const auto& [text, isNumber] : *m_items) + { + if (column != sortColumn) + SetItemText(iRow, column, text.c_str(), isNumber, false, true); + ++column; + } - std::vector >::iterator it = m_items->begin(); - int col = 1; - for (it; it != m_items->end(); it++) + if (sortColumn > 0) { - // Loop through every item. We add each one unless it's the sorted by column, which we do last - if (col != iSortColumn) - SetItemText(iRow, col, it->first.c_str(), it->second, false, true); - col++; + const std::size_t sortIndex = static_cast(sortColumn - 1); + if (sortIndex < m_items->size()) + { + const auto& [text, isNumber] = m_items->at(sortIndex); + iRow = SetItemText(iRow, sortColumn, text.c_str(), isNumber, false, true); + } } - // Add our sort column text, if it was provided - if ((uint)iSortColumn <= m_items->size()) - iRow = SetItemText(iRow, iSortColumn, m_items->at(iSortColumn - 1).first.c_str(), m_items->at(iSortColumn - 1).second, false, true); return iRow; } @@ -267,10 +346,9 @@ void CGUIGridList_Impl::Clear() // reinterpret_cast < CEGUI::MultiColumnList* > ( m_pWindow ) -> setSortDirection( CEGUI::ListHeaderSegment::None ); reinterpret_cast(m_pWindow)->resetList(); - CFastHashMap::iterator it; - for (it = m_Items.begin(); it != m_Items.end(); it++) + for (auto& entry : m_Items) { - delete it->second; + delete entry.second; } m_Items.clear(); } @@ -319,16 +397,11 @@ const char* CGUIGridList_Impl::GetItemText(int iRow, int hColumn) { const char* szRet = pItem->getText().c_str(); - if (!m_bIgnoreTextSpacer) + if (!m_bIgnoreTextSpacer && GetColumnIndex(hColumn) == 0) { - unsigned char ucSpacerSize = (unsigned char)(strlen(CGUIGRIDLIST_SPACER)); - - if (GetColumnIndex(hColumn) == 0) - { - // Make sure there is a spacer to skip - if (strncmp(szRet, CGUIGRIDLIST_SPACER, strlen(CGUIGRIDLIST_SPACER)) == 0) - szRet += ucSpacerSize; - } + const unsigned char spacerSize = static_cast(kGridListSpacerLength); + if (strncmp(szRet, kGridListSpacer, spacerSize) == 0) + szRet += spacerSize; } return szRet; @@ -373,98 +446,49 @@ int CGUIGridList_Impl::SetItemText(int iRow, int hColumn, const char* szText, bo { try { - CEGUI::MultiColumnList* win = reinterpret_cast(m_pWindow); + CEGUI::MultiColumnList* list = reinterpret_cast(m_pWindow); + const int columnIndex = GetColumnIndex(hColumn); + CGUIListItem_Impl* pItem = reinterpret_cast(GetItem(iRow, hColumn)); - // Get the current item at that offset and set the text - CGUIListItem_Impl* pItem = reinterpret_cast(GetItem(iRow, hColumn)); - if (pItem) - { - if (bSection) - { - // Set section properties - pItem->SetFont("default-bold-small"); - pItem->SetDisabled(true); - pItem->SetText(szText, szSortText); - } - else - { - pItem->SetFont(win->getFont()->getName().c_str()); // Reset font to the font of the item's parent (the gridlist) - pItem->SetDisabled(false); - - if (GetColumnIndex(hColumn) == 0) - { - // Enable some spacing on regular items, if this is the first item - - char szBuf[CGUIGRIDLIST_MAX_TEXT_LENGTH]; - if (m_bIgnoreTextSpacer) - { - snprintf(szBuf, CGUIGRIDLIST_MAX_TEXT_LENGTH - 1, "%s", szText); - } - else - { - snprintf(szBuf, CGUIGRIDLIST_MAX_TEXT_LENGTH - 1, "%s%s", CGUIGRIDLIST_SPACER, szText); - } - - szBuf[CGUIGRIDLIST_MAX_TEXT_LENGTH - 1] = NULL; - - pItem->SetText(szBuf, szSortText); - } - else - { - pItem->SetText(szText, szSortText); - } - } - } - else + if (!pItem) { - // If it doesn't, create it and set it in the gridlist pItem = new CGUIListItem_Impl(szText, bNumber); - - if (szSortText) - pItem->SetText(szText, szSortText); - CEGUI::ListboxItem* pListboxItem = pItem->GetListItem(); - win->setItem(pListboxItem, CEGUI::MCLGridRef(iRow, GetColumnIndex(hColumn)), bFast); - - // Put our new item into the map + list->setItem(pListboxItem, CEGUI::MCLGridRef(iRow, columnIndex), bFast); m_Items[pItem->GetListItem()] = pItem; + } - if (bSection) + if (bSection) + { + pItem->SetFont("default-bold-small"); + pItem->SetDisabled(true); + pItem->SetText(szText, szSortText); + } + else + { + pItem->SetFont(list->getFont()->getName().c_str()); + pItem->SetDisabled(false); + + if (columnIndex == 0 && !m_bIgnoreTextSpacer) { - // Set section properties - pItem->SetFont("default-bold-small"); - pItem->SetDisabled(true); + char szBuf[kGridListMaxTextLength]; + snprintf(szBuf, kGridListMaxTextLength - 1, "%s%s", kGridListSpacer, szText); + szBuf[kGridListMaxTextLength - 1] = '\0'; + pItem->SetText(szBuf, szSortText); } - else if (GetColumnIndex(hColumn) == 0) + else { - // Enable some spacing on regular items, if this is the first item - char szBuf[CGUIGRIDLIST_MAX_TEXT_LENGTH]; - - if (m_bIgnoreTextSpacer) - { - snprintf(szBuf, CGUIGRIDLIST_MAX_TEXT_LENGTH - 1, "%s", szText); - } - else - { - snprintf(szBuf, CGUIGRIDLIST_MAX_TEXT_LENGTH - 1, "%s%s", CGUIGRIDLIST_SPACER, szText); - } - - szBuf[CGUIGRIDLIST_MAX_TEXT_LENGTH - 1] = NULL; - pItem->SetText(szBuf, szSortText); + pItem->SetText(szText, szSortText); } } - // If the list is sorted and we just changed an item in the sorting column, - // re-sort the list. - if (win->getSortDirection() != SortDirections::None && win->getSortColumn() == GetColumnIndex(hColumn)) + if (list->getSortDirection() != SortDirections::None && list->getSortColumn() == columnIndex) { - win->setSortColumn(win->getSortColumn()); + list->setSortColumn(list->getSortColumn()); return GetItemRowIndex(pItem); } - else - { - return iRow; - } + + return iRow; } catch (CEGUI::Exception) { @@ -535,22 +559,31 @@ bool CGUIGridList_Impl::IsColumnSegmentSizingEnabled(int hColumn) void CGUIGridList_Impl::SetItemImage(int iRow, int hColumn, CGUIStaticImage* pImage) { - // Get the current item at that offset - CGUIListItem* pItem = GetItem(iRow, hColumn); - if (pItem != NULL) + try { - pItem->SetImage(pImage); + CEGUI::MultiColumnList* pMultiColumnList = reinterpret_cast(m_pWindow); + if ((uint)iRow >= pMultiColumnList->getRowCount() || (uint)GetColumnIndex(hColumn) >= pMultiColumnList->getColumnCount()) + return; + + // Get the current item at that offset + CGUIListItem* pItem = GetItem(iRow, hColumn); + if (pItem != NULL) + { + pItem->SetImage(pImage); + } + else + { + // If it doesn't, create it and set it in the gridlist + CGUIListItem_Impl* pNewItem = new CGUIListItem_Impl("", CGUIListItem_Impl::ImageItem, (CGUIStaticImage_Impl*)pImage); + CEGUI::ListboxItem* pListboxItem = pNewItem->GetListItem(); + pMultiColumnList->setItem(pListboxItem, CEGUI::MCLGridRef(iRow, GetColumnIndex(hColumn)), true); + + // Put our new item in the map + m_Items[pNewItem->GetListItem()] = pNewItem; + } } - else - // if ( pImage ) + catch (CEGUI::Exception) { - // If it doesn't, create it and set it in the gridlist - CGUIListItem_Impl* pNewItem = new CGUIListItem_Impl("", CGUIListItem_Impl::ImageItem, (CGUIStaticImage_Impl*)pImage); - CEGUI::ListboxItem* pListboxItem = pNewItem->GetListItem(); - reinterpret_cast(m_pWindow)->setItem(pListboxItem, CEGUI::MCLGridRef(iRow, GetColumnIndex(hColumn)), true); - - // Put our new item in the map - m_Items[pNewItem->GetListItem()] = pNewItem; } } @@ -746,40 +779,36 @@ void CGUIGridList_Impl::SetSelectedItem(int iRow, int hColumn, bool bReset) void CGUIGridList_Impl::Sort(unsigned int uiColumn, SortDirection direction) { - reinterpret_cast(m_pWindow)->setSortColumn(GetColumnIndex(uiColumn)); + CEGUI::MultiColumnList* pList = reinterpret_cast(m_pWindow); + const unsigned int columnCount = static_cast(pList->getColumnCount()); + const unsigned int column = NormalizeSortColumn(uiColumn, columnCount); + if (column == 0) + return; - switch (direction) + if (m_bAutoSortSuppressed) { - case SortDirections::Ascending: - reinterpret_cast(m_pWindow)->setSortDirection(CEGUI::ListHeaderSegment::Ascending); - break; - case SortDirections::Descending: - reinterpret_cast(m_pWindow)->setSortDirection(CEGUI::ListHeaderSegment::Descending); - break; - default: - reinterpret_cast(m_pWindow)->setSortDirection(CEGUI::ListHeaderSegment::None); - break; + m_uiPendingSortColumn = column; + m_PendingSortDirection = direction; + UpdateSortIndicator(column, direction); + return; } + + pList->setSortColumn(GetColumnIndex(column)); + pList->setSortDirection(ToCeguiSortDirection(direction)); } void CGUIGridList_Impl::GetSort(unsigned int& uiColumn, SortDirection& direction) { - uiColumn = reinterpret_cast(m_pWindow)->getSortColumn() + 1; - - switch (reinterpret_cast(m_pWindow)->getSortDirection()) + if (m_bAutoSortSuppressed) { - case CEGUI::ListHeaderSegment::Ascending: - direction = SortDirections::Ascending; - break; - - case CEGUI::ListHeaderSegment::Descending: - direction = SortDirections::Descending; - break; - - default: - direction = SortDirections::None; - break; + uiColumn = m_uiPendingSortColumn; + direction = m_PendingSortDirection; + return; } + + CEGUI::MultiColumnList* pList = reinterpret_cast(m_pWindow); + uiColumn = pList->getSortColumn() + 1; + direction = FromCeguiSortDirection(pList->getSortDirection()); } void CGUIGridList_Impl::SetSortColumnHandler(GUI_CALLBACK Callback) @@ -787,6 +816,11 @@ void CGUIGridList_Impl::SetSortColumnHandler(GUI_CALLBACK Callback) m_OnSortColumn = Callback; } +void CGUIGridList_Impl::SetSelectionHandler(GUI_CALLBACK Callback) +{ + m_OnSelectionChanged = Callback; +} + bool CGUIGridList_Impl::Event_OnSortColumn(const CEGUI::EventArgs& e) { if (m_OnSortColumn) @@ -794,6 +828,35 @@ bool CGUIGridList_Impl::Event_OnSortColumn(const CEGUI::EventArgs& e) return true; } +bool CGUIGridList_Impl::Event_OnSelectionChanged(const CEGUI::EventArgs& e) +{ + if (m_OnSelectionChanged) + m_OnSelectionChanged(reinterpret_cast(this)); + return true; +} + +void CGUIGridList_Impl::UpdateSortIndicator(unsigned int uiColumn, SortDirection direction) +{ + try + { + CEGUI::MultiColumnList* pList = reinterpret_cast(m_pWindow); + const auto columnCount = static_cast(pList->getColumnCount()); + const int targetIndex = (uiColumn > 0) ? static_cast(uiColumn - 1) : -1; + + for (auto i = 0; i < columnCount; ++i) + { + auto segDirection = CEGUI::ListHeaderSegment::None; + if (i == targetIndex && direction != SortDirections::None) + segDirection = ToCeguiSortDirection(direction); + + pList->getHeaderSegmentForColumn(i).setSortDirection(segDirection); + } + } + catch (CEGUI::Exception) + { + } +} + unsigned int CGUIGridList_Impl::GetUniqueHandle() { return ++m_hUniqueHandle; @@ -801,10 +864,8 @@ unsigned int CGUIGridList_Impl::GetUniqueHandle() CGUIListItem_Impl* CGUIGridList_Impl::GetListItem(CEGUI::ListboxItem* pItem) { - CFastHashMap::iterator it; - it = m_Items.find(pItem); - if (it == m_Items.end()) - return NULL; + if (const auto it = m_Items.find(pItem); it != m_Items.end()) + return it->second; - return it->second; + return nullptr; } diff --git a/Client/gui/CGUIGridList_Impl.h b/Client/gui/CGUIGridList_Impl.h index 2185bb0b167..ec696a98ac3 100644 --- a/Client/gui/CGUIGridList_Impl.h +++ b/Client/gui/CGUIGridList_Impl.h @@ -48,11 +48,13 @@ class CGUIGridList_Impl : public CGUIGridList, public CGUIElement_Impl void SetItemColor(int iRow, int hColumn, unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue, unsigned char ucAlpha); bool GetItemColor(int iRow, int hColumn, unsigned char& ucRed, unsigned char& ucGreen, unsigned char& ucBlue, unsigned char& ucAlpha); - void SetHorizontalScrollBar(bool bEnabled); - void SetVerticalScrollBar(bool bEnabled); - void SetSortingEnabled(bool bEnabled); - bool IsSortingEnabled(); - void SetItemImage(int iRow, int hColumn, CGUIStaticImage* pImage); + void SetHorizontalScrollBar(bool bEnabled); + void SetVerticalScrollBar(bool bEnabled); + void SetSortingEnabled(bool bEnabled); + bool IsSortingEnabled(); + void SetAutoSortSuppressed(bool bSuppressed); + [[nodiscard]] bool IsAutoSortSuppressed() const; + void SetItemImage(int iRow, int hColumn, CGUIStaticImage* pImage); float GetHorizontalScrollPosition(); float GetVerticalScrollPosition(); @@ -80,24 +82,31 @@ class CGUIGridList_Impl : public CGUIGridList, public CGUIElement_Impl void SetSelectedItem(int iRow, int hColumn, bool bReset); void SetSortColumnHandler(GUI_CALLBACK Callback); + void SetSelectionHandler(GUI_CALLBACK Callback); void SetIgnoreTextSpacer(bool bIgnoreTextSpacer) { m_bIgnoreTextSpacer = bIgnoreTextSpacer; }; eCGUIType GetType() { return CGUI_GRIDLIST; }; - #include "CGUIElement_Inc.h" +#include "CGUIElement_Inc.h" private: bool Event_OnSortColumn(const CEGUI::EventArgs& e); + bool Event_OnSelectionChanged(const CEGUI::EventArgs& e); + void UpdateSortIndicator(unsigned int uiColumn, SortDirection direction); - int m_iIndex; + int m_iIndex = 0; unsigned int GetUniqueHandle(); CGUIListItem_Impl* GetListItem(CEGUI::ListboxItem* pItem); - unsigned int m_hUniqueHandle; + unsigned int m_hUniqueHandle = 0; CFastHashMap m_Items; - GUI_CALLBACK m_OnSortColumn; + GUI_CALLBACK m_OnSortColumn = nullptr; + GUI_CALLBACK m_OnSelectionChanged = nullptr; - bool m_bIgnoreTextSpacer; + bool m_bIgnoreTextSpacer = false; + bool m_bAutoSortSuppressed = false; + unsigned int m_uiPendingSortColumn = 1; + SortDirection m_PendingSortDirection = SortDirections::None; }; diff --git a/Client/gui/CGUILabel_Impl.cpp b/Client/gui/CGUILabel_Impl.cpp index 33a08fdfa2c..df81fa29a51 100644 --- a/Client/gui/CGUILabel_Impl.cpp +++ b/Client/gui/CGUILabel_Impl.cpp @@ -15,7 +15,7 @@ CGUILabel_Impl::CGUILabel_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, const char* szText) { - m_pManager = pGUI; + SetManager(pGUI); // Get an unique identifier for CEGUI (gah, there's gotta be an another way) char szUnique[CGUI_CHAR_SIZE]; diff --git a/Client/gui/CGUILabel_Impl.h b/Client/gui/CGUILabel_Impl.h index b4960c17b8f..c40eb598116 100644 --- a/Client/gui/CGUILabel_Impl.h +++ b/Client/gui/CGUILabel_Impl.h @@ -43,7 +43,7 @@ class CGUILabel_Impl : public CGUILabel, public CGUIElement_Impl eCGUIType GetType() { return CGUI_LABEL; }; - #define EXCLUDE_SET_TEXT - #include "CGUIElement_Inc.h" - #undef EXCLUDE_SET_TEXT +#define EXCLUDE_SET_TEXT +#include "CGUIElement_Inc.h" +#undef EXCLUDE_SET_TEXT }; diff --git a/Client/gui/CGUIMemo_Impl.cpp b/Client/gui/CGUIMemo_Impl.cpp index 31d9a55b6da..8839876735a 100644 --- a/Client/gui/CGUIMemo_Impl.cpp +++ b/Client/gui/CGUIMemo_Impl.cpp @@ -15,7 +15,7 @@ CGUIMemo_Impl::CGUIMemo_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, const char* szEdit) { - m_pManager = pGUI; + SetManager(pGUI); // Get an unique identifier for CEGUI char szUnique[CGUI_CHAR_SIZE]; diff --git a/Client/gui/CGUIMemo_Impl.h b/Client/gui/CGUIMemo_Impl.h index 650d495f2df..7ae3d421931 100644 --- a/Client/gui/CGUIMemo_Impl.h +++ b/Client/gui/CGUIMemo_Impl.h @@ -45,7 +45,7 @@ class CGUIMemo_Impl : public CGUIMemo, public CGUIElement_Impl, public CGUITabLi eCGUIType GetType() { return CGUI_MEMO; }; - #include "CGUIElement_Inc.h" +#include "CGUIElement_Inc.h" private: bool Event_TextChanged(const CEGUI::EventArgs& e); diff --git a/Client/gui/CGUIMessageBox_Impl.cpp b/Client/gui/CGUIMessageBox_Impl.cpp index 6e7c90a7694..ab74df595e5 100644 --- a/Client/gui/CGUIMessageBox_Impl.cpp +++ b/Client/gui/CGUIMessageBox_Impl.cpp @@ -12,15 +12,15 @@ #include "StdInc.h" #include "../core/CFilePathTranslator.h" -#define MESSAGEBOX_WIDTH 400.0f -#define MESSAGEBOX_HEIGHT 150.0f -#define MESSAGEBOX_SPACER 20 -#define MESSAGEBOX_ICON_SIZE 42 +#define MESSAGEBOX_WIDTH 400.0f +#define MESSAGEBOX_HEIGHT 150.0f +#define MESSAGEBOX_SPACER 20 +#define MESSAGEBOX_ICON_SIZE 42 CGUIMessageBox_Impl::CGUIMessageBox_Impl(CGUI_Impl* pGUI, const char* szTitle, const char* szCaption, unsigned int uiFlags) { // Initialize - m_bAutoDestroy = true; // TODO: If any buttons.. + m_bAutoDestroy = true; // TODO: If any buttons.. m_pIcon = NULL; m_pButton = NULL; m_pLabelCaption = NULL; @@ -32,7 +32,7 @@ CGUIMessageBox_Impl::CGUIMessageBox_Impl(CGUI_Impl* pGUI, const char* szTitle, c m_pWindow->SetCloseButtonEnabled(false); m_pWindow->SetSizingEnabled(false); m_pWindow->SetPosition(CVector2D(ScreenSize.fX * 0.5f - MESSAGEBOX_WIDTH * 0.5f, ScreenSize.fY * 0.5f - MESSAGEBOX_HEIGHT * 0.5f)); - m_pWindow->SetSize(CVector2D(MESSAGEBOX_WIDTH, MESSAGEBOX_HEIGHT)); // relative 0.35, 0.225 + m_pWindow->SetSize(CVector2D(MESSAGEBOX_WIDTH, MESSAGEBOX_HEIGHT)); // relative 0.35, 0.225 // Create the icon m_pIcon = pGUI->CreateStaticImage(m_pWindow); diff --git a/Client/gui/CGUIProgressBar_Impl.cpp b/Client/gui/CGUIProgressBar_Impl.cpp index 8eeb5bfd716..18ef26e45bc 100644 --- a/Client/gui/CGUIProgressBar_Impl.cpp +++ b/Client/gui/CGUIProgressBar_Impl.cpp @@ -15,7 +15,7 @@ CGUIProgressBar_Impl::CGUIProgressBar_Impl(CGUI_Impl* pGUI, CGUIElement* pParent) { - m_pManager = pGUI; + SetManager(pGUI); // Get an unique identifier for CEGUI (gah, there's gotta be an another way) char szUnique[CGUI_CHAR_SIZE]; diff --git a/Client/gui/CGUIProgressBar_Impl.h b/Client/gui/CGUIProgressBar_Impl.h index 38a041b5101..8d37c70d5cd 100644 --- a/Client/gui/CGUIProgressBar_Impl.h +++ b/Client/gui/CGUIProgressBar_Impl.h @@ -25,7 +25,7 @@ class CGUIProgressBar_Impl : public CGUIProgressBar, public CGUIElement_Impl eCGUIType GetType() { return CGUI_PROGRESSBAR; }; - #include "CGUIElement_Inc.h" +#include "CGUIElement_Inc.h" private: }; diff --git a/Client/gui/CGUIRadioButton_Impl.cpp b/Client/gui/CGUIRadioButton_Impl.cpp index ed0e7ff572a..e0639ae7f93 100644 --- a/Client/gui/CGUIRadioButton_Impl.cpp +++ b/Client/gui/CGUIRadioButton_Impl.cpp @@ -15,7 +15,7 @@ CGUIRadioButton_Impl::CGUIRadioButton_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, const char* szCaption) { - m_pManager = pGUI; + SetManager(pGUI); // Get an unique identifier for CEGUI (gah, there's gotta be an another way) char szUnique[CGUI_CHAR_SIZE]; diff --git a/Client/gui/CGUIRadioButton_Impl.h b/Client/gui/CGUIRadioButton_Impl.h index e9e189599f5..be22ac5cb0e 100644 --- a/Client/gui/CGUIRadioButton_Impl.h +++ b/Client/gui/CGUIRadioButton_Impl.h @@ -25,7 +25,7 @@ class CGUIRadioButton_Impl : public CGUIRadioButton, public CGUIElement_Impl eCGUIType GetType() { return CGUI_RADIOBUTTON; }; - #include "CGUIElement_Inc.h" +#include "CGUIElement_Inc.h" private: }; diff --git a/Client/gui/CGUIScrollBar_Impl.cpp b/Client/gui/CGUIScrollBar_Impl.cpp index 2df9f116d3c..c895a374149 100644 --- a/Client/gui/CGUIScrollBar_Impl.cpp +++ b/Client/gui/CGUIScrollBar_Impl.cpp @@ -11,12 +11,12 @@ #include "StdInc.h" -#define CGUISCROLLBAR_HORIZONTAL_NAME "CGUI/HorizontalScrollbar" -#define CGUISCROLLBAR_VERTICAL_NAME "CGUI/VerticalScrollbar" +#define CGUISCROLLBAR_HORIZONTAL_NAME "CGUI/HorizontalScrollbar" +#define CGUISCROLLBAR_VERTICAL_NAME "CGUI/VerticalScrollbar" CGUIScrollBar_Impl::CGUIScrollBar_Impl(CGUI_Impl* pGUI, bool bHorizontal, CGUIElement* pParent) { - m_pManager = pGUI; + SetManager(pGUI); // Get an unique identifier for CEGUI (gah, there's gotta be an another way) char szUnique[CGUI_CHAR_SIZE]; diff --git a/Client/gui/CGUIScrollBar_Impl.h b/Client/gui/CGUIScrollBar_Impl.h index a996595a888..8aa653b5fe7 100644 --- a/Client/gui/CGUIScrollBar_Impl.h +++ b/Client/gui/CGUIScrollBar_Impl.h @@ -27,7 +27,7 @@ class CGUIScrollBar_Impl : public CGUIScrollBar, public CGUIElement_Impl eCGUIType GetType() { return CGUI_SCROLLBAR; }; - #include "CGUIElement_Inc.h" +#include "CGUIElement_Inc.h" private: bool Event_OnScroll(const CEGUI::EventArgs& e); diff --git a/Client/gui/CGUIScrollPane_Impl.cpp b/Client/gui/CGUIScrollPane_Impl.cpp index ccf27681699..35677619101 100644 --- a/Client/gui/CGUIScrollPane_Impl.cpp +++ b/Client/gui/CGUIScrollPane_Impl.cpp @@ -15,7 +15,7 @@ CGUIScrollPane_Impl::CGUIScrollPane_Impl(CGUI_Impl* pGUI, CGUIElement* pParent) { - m_pManager = pGUI; + SetManager(pGUI); // Initialize m_pGUI = pGUI; diff --git a/Client/gui/CGUIScrollPane_Impl.h b/Client/gui/CGUIScrollPane_Impl.h index 1c2b036828b..91bc11c8c52 100644 --- a/Client/gui/CGUIScrollPane_Impl.h +++ b/Client/gui/CGUIScrollPane_Impl.h @@ -37,7 +37,7 @@ class CGUIScrollPane_Impl : public CGUIScrollPane, public CGUIElement_Impl, publ eCGUIType GetType() { return CGUI_SCROLLPANE; }; - #include "CGUIElement_Inc.h" +#include "CGUIElement_Inc.h" private: class CGUI_Impl* m_pGUI; diff --git a/Client/gui/CGUIStaticImage_Impl.cpp b/Client/gui/CGUIStaticImage_Impl.cpp index b96eeab2618..6d75bc8be04 100644 --- a/Client/gui/CGUIStaticImage_Impl.cpp +++ b/Client/gui/CGUIStaticImage_Impl.cpp @@ -20,7 +20,7 @@ CGUIStaticImage_Impl::CGUIStaticImage_Impl(CGUI_Impl* pGUI, CGUIElement* pParent m_pImageset = NULL; m_pImage = NULL; m_pGUI = pGUI; - m_pManager = pGUI; + SetManager(pGUI); m_pTexture = NULL; m_bCreatedTexture = false; diff --git a/Client/gui/CGUIStaticImage_Impl.h b/Client/gui/CGUIStaticImage_Impl.h index b01dcd8a9ef..7ebb54a1419 100644 --- a/Client/gui/CGUIStaticImage_Impl.h +++ b/Client/gui/CGUIStaticImage_Impl.h @@ -45,5 +45,5 @@ class CGUIStaticImage_Impl : public CGUIStaticImage, public CGUIElement_Impl, pu CEGUI::Imageset* m_pImageset; const CEGUI::Image* m_pImage; - #include "CGUIElement_Inc.h" +#include "CGUIElement_Inc.h" }; diff --git a/Client/gui/CGUITabList.h b/Client/gui/CGUITabList.h index dcbab3d4b90..9bb9a75da66 100644 --- a/Client/gui/CGUITabList.h +++ b/Client/gui/CGUITabList.h @@ -16,8 +16,8 @@ typedef std::list::const_iterator CGUITabIterator; class CGUITabList { public: - CGUITabList(){}; - ~CGUITabList(){}; + CGUITabList() {}; + ~CGUITabList() {}; void AddItem(CGUITabListItem* pItem) { m_Items.push_back(pItem); }; void RemoveItem(CGUITabListItem* pItem) { m_Items.remove(pItem); }; diff --git a/Client/gui/CGUITabPanel_Impl.cpp b/Client/gui/CGUITabPanel_Impl.cpp index 2bb986ae6d9..7d6c434709d 100644 --- a/Client/gui/CGUITabPanel_Impl.cpp +++ b/Client/gui/CGUITabPanel_Impl.cpp @@ -15,7 +15,7 @@ CGUITabPanel_Impl::CGUITabPanel_Impl(CGUI_Impl* pGUI, CGUIElement* pParent) { - m_pManager = pGUI; + SetManager(pGUI); // Initialize m_pGUI = pGUI; diff --git a/Client/gui/CGUITabPanel_Impl.h b/Client/gui/CGUITabPanel_Impl.h index a0b7b9f3229..b12c001ded6 100644 --- a/Client/gui/CGUITabPanel_Impl.h +++ b/Client/gui/CGUITabPanel_Impl.h @@ -42,7 +42,7 @@ class CGUITabPanel_Impl : public CGUITabPanel, public CGUIElement_Impl void SetSelectionHandler(GUI_CALLBACK Callback); - #include "CGUIElement_Inc.h" +#include "CGUIElement_Inc.h" private: class CGUI_Impl* m_pGUI; diff --git a/Client/gui/CGUITab_Impl.cpp b/Client/gui/CGUITab_Impl.cpp index aea47e47bad..fb5111ef399 100644 --- a/Client/gui/CGUITab_Impl.cpp +++ b/Client/gui/CGUITab_Impl.cpp @@ -13,7 +13,7 @@ CGUITab_Impl::CGUITab_Impl(CGUI_Impl* pGUI, CGUIElement_Impl* pParent, const char* szCaption) { - m_pManager = pGUI; + SetManager(pGUI); // Get an unique identifier for CEGUI char szUnique[CGUI_CHAR_SIZE]; diff --git a/Client/gui/CGUITab_Impl.h b/Client/gui/CGUITab_Impl.h index 507b6facbe1..fd30a87c56c 100644 --- a/Client/gui/CGUITab_Impl.h +++ b/Client/gui/CGUITab_Impl.h @@ -26,7 +26,7 @@ class CGUITab_Impl : public CGUITab, public CGUIElement_Impl, public CGUITabList #define SETVISIBLE_HACK #define SETENABLED_HACK - #include "CGUIElement_Inc.h" +#include "CGUIElement_Inc.h" #undef SETENABLED_HACK #undef SETVISIBLE_HACK diff --git a/Client/gui/CGUITexture_Impl.h b/Client/gui/CGUITexture_Impl.h index 23b2199467e..fb90bc8bcd5 100644 --- a/Client/gui/CGUITexture_Impl.h +++ b/Client/gui/CGUITexture_Impl.h @@ -17,7 +17,7 @@ namespace CEGUI { class Texture; class Renderer; -} // namespace CEGUI +} // namespace CEGUI class CGUITexture_Impl : public CGUITexture { diff --git a/Client/gui/CGUIWebBrowser_Impl.cpp b/Client/gui/CGUIWebBrowser_Impl.cpp index be5de4c979e..0de25b12306 100644 --- a/Client/gui/CGUIWebBrowser_Impl.cpp +++ b/Client/gui/CGUIWebBrowser_Impl.cpp @@ -18,7 +18,7 @@ CGUIWebBrowser_Impl::CGUIWebBrowser_Impl(CGUI_Impl* pGUI, CGUIElement* pParent) m_pImageset = nullptr; m_pImage = nullptr; m_pGUI = pGUI; - m_pManager = pGUI; + SetManager(pGUI); m_pWebView = nullptr; // Get an unique identifier for CEGUI @@ -108,7 +108,7 @@ void CGUIWebBrowser_Impl::LoadFromWebView(CWebViewInterface* pWebView) // Define an image and get its pointer m_pImageset->defineImage(szUnique, CEGUI::Point(0, 0), CEGUI::Size(pCEGUITexture->getWidth(), pCEGUITexture->getHeight()), CEGUI::Point(0, 0)); m_pImage = const_cast( - &m_pImageset->getImage(szUnique)); // const_cast here is a huge hack, but is okay here since all images generated here are unique + &m_pImageset->getImage(szUnique)); // const_cast here is a huge hack, but is okay here since all images generated here are unique // Set the image just loaded as the image to be drawn for the widget reinterpret_cast(m_pWindow)->setImage(m_pImage); diff --git a/Client/gui/CGUIWebBrowser_Impl.h b/Client/gui/CGUIWebBrowser_Impl.h index 99e2e69ebf3..7de13f501c6 100644 --- a/Client/gui/CGUIWebBrowser_Impl.h +++ b/Client/gui/CGUIWebBrowser_Impl.h @@ -60,9 +60,9 @@ class CGUIWebBrowser_Impl : public CGUIWebBrowser, public CGUIElement_Impl CWebViewInterface* m_pWebView; - #define EXCLUDE_SET_SIZE // WTF? TODO: Refactor this - #include "CGUIElement_Inc.h" - #undef EXCLUDE_SET_SIZE +#define EXCLUDE_SET_SIZE // WTF? TODO: Refactor this +#include "CGUIElement_Inc.h" +#undef EXCLUDE_SET_SIZE }; // The purpose of this class is to provide an externally managed DirectX texture @@ -75,12 +75,12 @@ class CGUIWebBrowserTexture : public CEGUI::DirectX9Texture virtual ushort getHeight() const override; // Override with empty function (--> eliminate the functinions from DirectX9Texture) - virtual void loadFromFile(const CEGUI::String& filename, const CEGUI::String& resourceGroup) override{}; - virtual void loadFromMemory(const void* buffPtr, uint buffWidth, uint buffHeight) override{}; + virtual void loadFromFile(const CEGUI::String& filename, const CEGUI::String& resourceGroup) override {}; + virtual void loadFromMemory(const void* buffPtr, uint buffWidth, uint buffHeight) override {}; virtual LPDIRECT3DTEXTURE9 getD3DTexture() const override; - virtual void preD3DReset(){}; - virtual void postD3DReset(){}; + virtual void preD3DReset() {}; + virtual void postD3DReset() {}; private: CWebViewInterface* m_pWebView; diff --git a/Client/gui/CGUIWindow_Impl.cpp b/Client/gui/CGUIWindow_Impl.cpp index 0247f1cf69c..bb6070beb5b 100644 --- a/Client/gui/CGUIWindow_Impl.cpp +++ b/Client/gui/CGUIWindow_Impl.cpp @@ -15,7 +15,7 @@ CGUIWindow_Impl::CGUIWindow_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, const char* szCaption, const SString& strLayoutFile) { - m_pManager = pGUI; + SetManager(pGUI); // Get an unique identifier for CEGUI char szUnique[CGUI_CHAR_SIZE]; diff --git a/Client/gui/CGUIWindow_Impl.h b/Client/gui/CGUIWindow_Impl.h index d7ec871be6e..881b83b5f7e 100644 --- a/Client/gui/CGUIWindow_Impl.h +++ b/Client/gui/CGUIWindow_Impl.h @@ -35,7 +35,7 @@ class CGUIWindow_Impl : public CGUIWindow, public CGUIElement_Impl, public CGUIT eCGUIType GetType() { return CGUI_WINDOW; }; - #include "CGUIElement_Inc.h" +#include "CGUIElement_Inc.h" protected: bool Event_OnCloseClick(const CEGUI::EventArgs& e); diff --git a/Client/gui/CGUI_Impl.cpp b/Client/gui/CGUI_Impl.cpp index 66ad708cd4e..b36c7e52750 100644 --- a/Client/gui/CGUI_Impl.cpp +++ b/Client/gui/CGUI_Impl.cpp @@ -10,45 +10,88 @@ *****************************************************************************/ #include "StdInc.h" +#include "GuiCleanup.h" #include "CEGUIExceptions.h" +#include +#include using std::list; -#define CGUI_MTA_DEFAULT_FONT "tahoma.ttf" // %WINDIR%/font/<...> -#define CGUI_MTA_DEFAULT_FONT_BOLD "tahomabd.ttf" // %WINDIR%/font/<...> -#define CGUI_MTA_CLEAR_FONT "verdana.ttf" // %WINDIR%/font/<...> - -#define CGUI_MTA_DEFAULT_REG "Tahoma (TrueType)" -#define CGUI_MTA_DEFAULT_REG_BOLD "Tahoma Bold (TrueType)" -#define CGUI_MTA_CLEAR_REG "Verdana (TrueType)" +void CGUI_Impl::DestroyElementRecursive(CGUIElement* pElement) +{ + if (!pElement) + return; -#define CGUI_MTA_SUBSTITUTE_FONT "cgui/unifont.ttf" // GTA/MTA/<...> -#define CGUI_MTA_SANS_FONT "cgui/sans.ttf" // GTA/MTA/<...> -#define CGUI_SA_HEADER_FONT "cgui/saheader.ttf" // GTA/MTA/<...> -#define CGUI_SA_GOTHIC_FONT "cgui/sagothic.ttf" // GTA/MTA/<...> -#define CGUI_SA_HEADER_SIZE 26 -#define CGUI_SA_GOTHIC_SIZE 47 -#define CGUI_MTA_SANS_FONT_SIZE 9 + if (auto* pImpl = dynamic_cast(pElement)) + { + CEGUI::Window* pWindow = pImpl->GetWindow(); + if (pWindow) + DestroyGuiWindowRecursive(pWindow); + else + delete pElement; + return; + } -CGUI_Impl::CGUI_Impl(IDirect3DDevice9* pDevice) : m_HasSchemeLoaded(false), m_fCurrentServerCursorAlpha(1.0f) -{ + delete pElement; +} + +#define CGUI_MTA_DEFAULT_FONT "tahoma.ttf" // %WINDIR%/font/<...> +#define CGUI_MTA_DEFAULT_FONT_BOLD "tahomabd.ttf" // %WINDIR%/font/<...> +#define CGUI_MTA_CLEAR_FONT "verdana.ttf" // %WINDIR%/font/<...> + +#define CGUI_MTA_DEFAULT_REG "Tahoma (TrueType)" +#define CGUI_MTA_DEFAULT_REG_BOLD "Tahoma Bold (TrueType)" +#define CGUI_MTA_CLEAR_REG "Verdana (TrueType)" + +#define CGUI_MTA_SUBSTITUTE_FONT "cgui/unifont.ttf" // GTA/MTA/<...> +#define CGUI_MTA_SANS_FONT "cgui/sans.ttf" // GTA/MTA/<...> +#define CGUI_SA_HEADER_FONT "cgui/saheader.ttf" // GTA/MTA/<...> +#define CGUI_SA_GOTHIC_FONT "cgui/sagothic.ttf" // GTA/MTA/<...> +#define CGUI_SA_HEADER_SIZE 26 +#define CGUI_SA_GOTHIC_SIZE 47 +#define CGUI_MTA_SANS_FONT_SIZE 9 + +CGUI_Impl::CGUI_Impl(IDirect3DDevice9* pDevice) + : m_HasSchemeLoaded(false), + m_fCurrentServerCursorAlpha(1.0f), + m_pDevice(pDevice), + m_pRenderer(nullptr), + m_pSystem(nullptr), + m_pFontManager(nullptr), + m_pImageSetManager(nullptr), + m_pSchemeManager(nullptr), + m_pWindowManager(nullptr), + m_pTop(nullptr), + m_pCursor(nullptr), + m_pDefaultFont(nullptr), + m_pSmallFont(nullptr), + m_pBoldFont(nullptr), + m_pClearFont(nullptr), + m_pSAHeaderFont(nullptr), + m_pSAGothicFont(nullptr), + m_pSansFont(nullptr), + m_pUniFont(nullptr), + m_nextRedrawHandle(1), + m_ulPreviousUnique(0), + m_eInputMode(INPUTMODE_NO_BINDS_ON_EDIT), + m_Channel(INPUT_CORE) +{ +#ifdef MTA_DEBUG + { + IUnknown* pProxyMarker = nullptr; + const HRESULT hr = pDevice ? pDevice->QueryInterface(CProxyDirect3DDevice9_GUID, reinterpret_cast(&pProxyMarker)) : E_POINTER; + if (SUCCEEDED(hr) && pProxyMarker) + { + pProxyMarker->Release(); + } + else + { + } + } +#endif m_RenderOkTimer.SetMaxIncrement(100); - // Init - m_pDevice = pDevice; - /* - m_pCharacterKeyHandler = NULL; - m_pKeyDownHandler = NULL; - m_pMouseClickHandler = NULL; - m_pMouseDoubleClickHandler = NULL; - m_pMouseWheelHandler = NULL; - m_pMouseMoveHandler = NULL; - m_pMouseEnterHandler = NULL; - m_pMouseLeaveHandler = NULL; - m_pMovedHandler = NULL; - m_pSizedHandler = NULL; - */ - m_Channel = INPUT_CORE; + // Callback arrays are default-initialized to empty state by their constructors // Create a GUI system and get the windowmanager m_pRenderer = new CEGUI::DirectX9Renderer(pDevice, 0); @@ -104,7 +147,29 @@ CGUI_Impl::CGUI_Impl(IDirect3DDevice9* pDevice) : m_HasSchemeLoaded(false), m_fC CGUI_Impl::~CGUI_Impl() { + // Clean up font objects to prevent memory leaks + delete m_pUniFont; + delete m_pDefaultFont; + delete m_pSmallFont; + delete m_pBoldFont; + delete m_pClearFont; + delete m_pSAHeaderFont; + delete m_pSAGothicFont; + delete m_pSansFont; + + // Clean up CEGUI system - this automatically deletes the renderer delete CEGUI::System::getSingletonPtr(); + // DO NOT delete m_pRenderer - it's already deleted by System destructor +} + +void CGUI_Impl::CreateRootWindow() +{ + if (!m_pWindowManager || !m_pSystem) + return; + + // Create dummy GUI root + m_pTop = reinterpret_cast(m_pWindowManager->createWindow("DefaultWindow", "guiroot")); + m_pSystem->setGUISheet(m_pTop); } void CGUI_Impl::SetSkin(const char* szName) @@ -125,12 +190,8 @@ void CGUI_Impl::SetSkin(const char* szName) CEGUI::System::getSingleton().setDefaultMouseCursor("CGUI-Images", "MouseArrow"); - // Destroy any windows we already have - CEGUI::WindowManager::getSingleton().destroyAllWindows(); - - // Create dummy GUI root - m_pTop = reinterpret_cast(m_pWindowManager->createWindow("DefaultWindow", "guiroot")); - m_pSystem->setGUISheet(m_pTop); + // Clean up CEGUI - this also re-creates the root window + Cleanup(); // Disable single click timeouts m_pSystem->setSingleClickTimeout(100000000.0f); @@ -192,10 +253,12 @@ void CGUI_Impl::Draw() // Redraw the changed elements if (!m_RedrawQueue.empty()) { - list::const_iterator iter = m_RedrawQueue.begin(); - for (; iter != m_RedrawQueue.end(); iter++) + for (const auto handle : m_RedrawQueue) { - (*iter)->ForceRedraw(); + if (CGUIElement* pElement = ResolveRedrawHandle(handle)) + { + pElement->ForceRedraw(); + } } m_RedrawQueue.clear(); } @@ -288,28 +351,31 @@ bool CGUI_Impl::GetGUIInputEnabled() break; case INPUTMODE_NO_BINDS_ON_EDIT: { - CEGUI::Window* pActiveWindow = m_pTop->getActiveChild(); - if (!pActiveWindow || pActiveWindow == m_pTop || !pActiveWindow->isVisible()) - { - return false; - } - if (pActiveWindow->getType() == "CGUI/Editbox") + if (m_pTop) { - CEGUI::Editbox* pEditBox = reinterpret_cast(pActiveWindow); - return (!pEditBox->isReadOnly() && pEditBox->hasInputFocus()); - } - else if (pActiveWindow->getType() == "CGUI/MultiLineEditbox") - { - CEGUI::MultiLineEditbox* pMultiLineEditBox = reinterpret_cast(pActiveWindow); - return (!pMultiLineEditBox->isReadOnly() && pMultiLineEditBox->hasInputFocus()); - } - else if (pActiveWindow->getType() == CGUIWEBBROWSER_NAME) - { - auto pElement = reinterpret_cast(pActiveWindow->getUserData()); - if (pElement->GetType() == CGUI_WEBBROWSER) + CEGUI::Window* pActiveWindow = m_pTop->getActiveChild(); + if (!pActiveWindow || pActiveWindow == m_pTop || !pActiveWindow->isVisible()) + { + return false; + } + if (pActiveWindow->getType() == "CGUI/Editbox") + { + CEGUI::Editbox* pEditBox = reinterpret_cast(pActiveWindow); + return (!pEditBox->isReadOnly() && pEditBox->hasInputFocus()); + } + else if (pActiveWindow->getType() == "CGUI/MultiLineEditbox") { - auto pWebBrowser = reinterpret_cast(pElement); - return pWebBrowser->HasInputFocus(); + CEGUI::MultiLineEditbox* pMultiLineEditBox = reinterpret_cast(pActiveWindow); + return (!pMultiLineEditBox->isReadOnly() && pMultiLineEditBox->hasInputFocus()); + } + else if (pActiveWindow->getType() == CGUIWEBBROWSER_NAME) + { + auto pElement = reinterpret_cast(pActiveWindow->getUserData()); + if (pElement->GetType() == CGUI_WEBBROWSER) + { + auto pWebBrowser = reinterpret_cast(pElement); + return pWebBrowser->HasInputFocus(); + } } } return false; @@ -332,13 +398,13 @@ eInputMode CGUI_Impl::GetGUIInputMode() CEGUI::String CGUI_Impl::GetUTFString(const char* szInput) { - CEGUI::String strUTF = (CEGUI::utf8*)szInput; // Convert into a CEGUI String + CEGUI::String strUTF = (CEGUI::utf8*)szInput; // Convert into a CEGUI String return strUTF; } CEGUI::String CGUI_Impl::GetUTFString(const std::string& strInput) { - CEGUI::String strUTF = (CEGUI::utf8*)strInput.c_str(); // Convert into a CEGUI String + CEGUI::String strUTF = (CEGUI::utf8*)strInput.c_str(); // Convert into a CEGUI String return strUTF; } @@ -541,6 +607,9 @@ eCursorType CGUI_Impl::GetCursorType() void CGUI_Impl::AddChild(CGUIElement_Impl* pChild) { + if (!m_pTop) + return; + m_pTop->addChildWindow(pChild->GetWindow()); } @@ -775,24 +844,22 @@ bool CGUI_Impl::Event_KeyDown(const CEGUI::EventArgs& Args) // If we got something to copy if (strTemp.length() > 0) { - // Convert it to Unicode - std::wstring strUTF = MbUTF8ToUTF16(strTemp.c_str()); - - // Open and empty the clipboard - OpenClipboard(NULL); - EmptyClipboard(); - - // Allocate the clipboard buffer and copy the data - HGLOBAL hBuf = GlobalAlloc(GMEM_DDESHARE, strUTF.length() * sizeof(wchar_t) + sizeof(wchar_t)); - wchar_t* buf = reinterpret_cast(GlobalLock(hBuf)); - wcscpy(buf, strUTF.c_str()); - GlobalUnlock(hBuf); - - // Copy the data into the clipboard - SetClipboardData(CF_UNICODETEXT, hBuf); + SString clipboardText; + try + { + clipboardText = UTF16ToMbUTF8(MbUTF8ToUTF16(strTemp.c_str())); + } + catch (const std::exception&) + { + clipboardText.clear(); + } + catch (...) + { + clipboardText.clear(); + } - // Close the clipboard - CloseClipboard(); + if (!clipboardText.empty()) + SharedUtil::SetClipboardText(clipboardText); } } @@ -807,158 +874,150 @@ bool CGUI_Impl::Event_KeyDown(const CEGUI::EventArgs& Args) CEGUI::Window* Wnd = reinterpret_cast(KeyboardArgs.window); if (Wnd->getType() == "CGUI/Editbox" || Wnd->getType() == "CGUI/MultiLineEditbox") { - // Open the clipboard - OpenClipboard(NULL); + SString clipboardUtf8 = SharedUtil::GetClipboardText(); + std::wstring strClipboardText; + try + { + strClipboardText = MbUTF8ToUTF16(clipboardUtf8); + } + catch (const std::exception&) + { + strClipboardText.clear(); + } + catch (...) + { + strClipboardText.clear(); + } - // Get the clipboard's data and lock it - HANDLE hClipData = GetClipboardData(CF_UNICODETEXT); - const wchar_t* ClipboardBuffer = nullptr; - if (hClipData) - ClipboardBuffer = static_cast(GlobalLock(hClipData)); + if (clipboardUtf8.empty() && strClipboardText.empty()) + break; - // Check to make sure we have valid data. - if (ClipboardBuffer) - { - size_t iSelectionStart, iSelectionLength, iMaxLength, iCaratIndex; - CEGUI::String strEditText; - bool bReplaceNewLines = true; - bool bIsBoxFull = false; + size_t iSelectionStart, iSelectionLength, iMaxLength, iCaratIndex; + CEGUI::String strEditText; + bool bReplaceNewLines = true; + bool bIsBoxFull = false; - if (Wnd->getType() == "CGUI/Editbox") + if (Wnd->getType() == "CGUI/Editbox") + { + // Turn our event window into an editbox + CEGUI::Editbox* WndEdit = reinterpret_cast(Wnd); + // Don't paste if we're read only + if (WndEdit->isReadOnly()) { - // Turn our event window into an editbox - CEGUI::Editbox* WndEdit = reinterpret_cast(Wnd); - // Don't paste if we're read only - if (WndEdit->isReadOnly()) - { - if (hClipData) - GlobalUnlock(hClipData); - CloseClipboard(); - return true; - } - strEditText = WndEdit->getText(); - iSelectionStart = WndEdit->getSelectionStartIndex(); - iSelectionLength = WndEdit->getSelectionLength(); - iMaxLength = WndEdit->getMaxTextLength(); - iCaratIndex = WndEdit->getCaratIndex(); + return true; } - else + strEditText = WndEdit->getText(); + iSelectionStart = WndEdit->getSelectionStartIndex(); + iSelectionLength = WndEdit->getSelectionLength(); + iMaxLength = WndEdit->getMaxTextLength(); + iCaratIndex = WndEdit->getCaratIndex(); + } + else + { + CEGUI::MultiLineEditbox* WndEdit = reinterpret_cast(Wnd); + // Don't paste if we're read only + if (WndEdit->isReadOnly()) { - CEGUI::MultiLineEditbox* WndEdit = reinterpret_cast(Wnd); - // Don't paste if we're read only - if (WndEdit->isReadOnly()) - { - if (hClipData) - GlobalUnlock(hClipData); - CloseClipboard(); - return true; - } - - strEditText = WndEdit->getText(); - iSelectionStart = WndEdit->getSelectionStartIndex(); - iSelectionLength = WndEdit->getSelectionLength(); - iMaxLength = WndEdit->getMaxTextLength(); - iCaratIndex = WndEdit->getCaratIndex(); - bReplaceNewLines = false; - - // Plus one character, because there is always an extra '\n' in - // MultiLineEditbox's text data and it causes MaxLength limit to - // be exceeded during pasting the text - iMaxLength += 1; + return true; } - std::wstring strClipboardText = ClipboardBuffer; - size_t iNewlineIndex; + strEditText = WndEdit->getText(); + iSelectionStart = WndEdit->getSelectionStartIndex(); + iSelectionLength = WndEdit->getSelectionLength(); + iMaxLength = WndEdit->getMaxTextLength(); + iCaratIndex = WndEdit->getCaratIndex(); + bReplaceNewLines = false; + + // Plus one character, because there is always an extra '\n' in + // MultiLineEditbox's text data and it causes MaxLength limit to + // be exceeded during pasting the text + iMaxLength += 1; + } + + size_t iNewlineIndex; - // Remove the newlines inserting spaces instead - if (bReplaceNewLines) + // Remove the newlines inserting spaces instead + if (bReplaceNewLines) + { + do { - do + iNewlineIndex = strClipboardText.find('\n'); + if (iNewlineIndex != SString::npos) { - iNewlineIndex = strClipboardText.find('\n'); - if (iNewlineIndex != SString::npos) + if (iNewlineIndex > 0 && strClipboardText[iNewlineIndex - 1] == '\r') { - if (iNewlineIndex > 0 && strClipboardText[iNewlineIndex - 1] == '\r') - { - // \r\n - strClipboardText[iNewlineIndex - 1] = ' '; - strClipboardText.replace(iNewlineIndex, strClipboardText.length() - iNewlineIndex, strClipboardText.c_str(), - iNewlineIndex + 1, strClipboardText.length() - iNewlineIndex - 1); - } - else - { - strClipboardText[iNewlineIndex] = ' '; - } + // \r\n + strClipboardText[iNewlineIndex - 1] = ' '; + strClipboardText.replace(iNewlineIndex, strClipboardText.length() - iNewlineIndex, strClipboardText.c_str(), + iNewlineIndex + 1, strClipboardText.length() - iNewlineIndex - 1); } - } while (iNewlineIndex != SString::npos); - } + else + { + strClipboardText[iNewlineIndex] = ' '; + } + } + } while (iNewlineIndex != SString::npos); + } - // Put the editbox's data into a string and insert the data if it has not reached it's maximum text length - std::wstring tmp = MbUTF8ToUTF16(strEditText.c_str()); - if ((strClipboardText.length() + tmp.length() - iSelectionLength) <= iMaxLength) + // Put the editbox's data into a string and insert the data if it has not reached it's maximum text length + std::wstring tmp = MbUTF8ToUTF16(strEditText.c_str()); + if ((strClipboardText.length() + tmp.length() - iSelectionLength) <= iMaxLength) + { + // Are there characters selected? + size_t sizeCaratIndex = 0; + if (iSelectionLength > 0) { - // Are there characters selected? - size_t sizeCaratIndex = 0; - if (iSelectionLength > 0) - { - // Replace what's selected with the pasted buffer and set the new carat index - tmp.replace(iSelectionStart, iSelectionLength, strClipboardText.c_str(), strClipboardText.length()); - sizeCaratIndex = iSelectionStart + strClipboardText.length(); - } - else - { - // If not, insert the clipboard buffer where we were and set the new carat index - tmp.insert(iSelectionStart, strClipboardText.c_str(), strClipboardText.length()); - sizeCaratIndex = iCaratIndex + strClipboardText.length(); - } + // Replace what's selected with the pasted buffer and set the new carat index + tmp.replace(iSelectionStart, iSelectionLength, strClipboardText.c_str(), strClipboardText.length()); + sizeCaratIndex = iSelectionStart + strClipboardText.length(); + } + else + { + // If not, insert the clipboard buffer where we were and set the new carat index + tmp.insert(iSelectionStart, strClipboardText.c_str(), strClipboardText.length()); + sizeCaratIndex = iCaratIndex + strClipboardText.length(); + } - // Set the new text and move the carat at the end of what we pasted - CEGUI::String strText((CEGUI::utf8*)UTF16ToMbUTF8(tmp).c_str()); - strEditText = strText; - iCaratIndex = sizeCaratIndex; + // Set the new text and move the carat at the end of what we pasted + CEGUI::String strText((CEGUI::utf8*)UTF16ToMbUTF8(tmp).c_str()); + strEditText = strText; + iCaratIndex = sizeCaratIndex; + } + else + { + bIsBoxFull = true; + } + if (bIsBoxFull) + { + // Fire an event if the editbox is full + if (Wnd->getType() == "CGUI/Editbox") + { + CEGUI::Editbox* WndEdit = reinterpret_cast(Wnd); + CEGUI::WindowEventArgs args(WndEdit); + WndEdit->fireEvent(CEGUI::Editbox::EventEditboxFull, args); } else { - bIsBoxFull = true; + CEGUI::MultiLineEditbox* WndEdit = reinterpret_cast(Wnd); + CEGUI::WindowEventArgs args(WndEdit); + WndEdit->fireEvent(CEGUI::Editbox::EventEditboxFull, args); } - if (bIsBoxFull) + } + else + { + if (Wnd->getType() == "CGUI/Editbox") { - // Fire an event if the editbox is full - if (Wnd->getType() == "CGUI/Editbox") - { - CEGUI::Editbox* WndEdit = reinterpret_cast(Wnd); - CEGUI::WindowEventArgs args(WndEdit); - WndEdit->fireEvent(CEGUI::Editbox::EventEditboxFull, args); - } - else - { - CEGUI::MultiLineEditbox* WndEdit = reinterpret_cast(Wnd); - CEGUI::WindowEventArgs args(WndEdit); - WndEdit->fireEvent(CEGUI::Editbox::EventEditboxFull, args); - } + CEGUI::Editbox* WndEdit = reinterpret_cast(Wnd); + WndEdit->setText(strEditText); + WndEdit->setCaratIndex(iCaratIndex); } else { - if (Wnd->getType() == "CGUI/Editbox") - { - CEGUI::Editbox* WndEdit = reinterpret_cast(Wnd); - WndEdit->setText(strEditText); - WndEdit->setCaratIndex(iCaratIndex); - } - else - { - CEGUI::MultiLineEditbox* WndEdit = reinterpret_cast(Wnd); - WndEdit->setText(strEditText); - WndEdit->setCaratIndex(iCaratIndex); - } + CEGUI::MultiLineEditbox* WndEdit = reinterpret_cast(Wnd); + WndEdit->setText(strEditText); + WndEdit->setCaratIndex(iCaratIndex); } } - - if (hClipData) - GlobalUnlock(hClipData); - - // Close the clipboard - CloseClipboard(); } } @@ -1124,12 +1183,15 @@ bool CGUI_Impl::Event_MouseButtonDown(const CEGUI::EventArgs& Args) pElement->Event_OnMouseButtonDown(); else { - // If there's no element, we're probably dealing with the root element - CEGUI::Window* pActiveWindow = m_pTop->getActiveChild(); - if (m_pTop == wnd && pActiveWindow) + if (m_pTop) { - // Deactivate active window to trigger onClientGUIBlur - pActiveWindow->deactivate(); + // If there's no element, we're probably dealing with the root element + CEGUI::Window* pActiveWindow = m_pTop->getActiveChild(); + if (m_pTop == wnd && pActiveWindow) + { + // Deactivate active window to trigger onClientGUIBlur + pActiveWindow->deactivate(); + } } } @@ -1366,11 +1428,17 @@ bool CGUI_Impl::Event_RedrawRequested(const CEGUI::EventArgs& Args) { const CEGUI::WindowEventArgs& e = reinterpret_cast(Args); - CGUIElement* pElement = reinterpret_cast((e.window)->getUserData()); + // Get the master window (walks up parent hierarchy for child widgets) + CEGUI::Window* pMasterWindow = GetMasterWindow(e.window); + + CGUIElement* pElement = reinterpret_cast(pMasterWindow->getUserData()); if (pElement) + { AddToRedrawQueue(pElement); - else - e.window->forceRedraw(); + } + + // Immediate redraw of event source for visual responsiveness + e.window->forceRedraw(); return true; } @@ -1423,34 +1491,80 @@ bool CGUI_Impl::Event_FocusLost(const CEGUI::EventArgs& Args) void CGUI_Impl::AddToRedrawQueue(CGUIElement* pWindow) { - // Manage the redraw queue, if we redraw the parent of the window passed, - // we should not add it to the redraw queue, and if the children are queued, - // remove them. - list::const_iterator iter = m_RedrawQueue.begin(); - for (; iter != m_RedrawQueue.end(); iter++) + auto* pImpl = dynamic_cast(pWindow); + if (!pImpl) + return; + + const std::uint32_t handle = pImpl->GetRedrawHandle(); + if (handle == kInvalidRedrawHandle) + return; + + if (m_RedrawRegistry.find(handle) == m_RedrawRegistry.end()) + return; + + // If parent is already queued, skip adding chidl + // (parent redraw will cover children) + if (CGUIElement* pParent = pWindow->GetParent()) { - if (pWindow->GetParent() == *iter) - { - return; - } - else if ((*iter)->GetParent() == pWindow) + if (auto* pParentImpl = dynamic_cast(pParent)) { - m_RedrawQueue.remove(*iter); - if (m_RedrawQueue.empty()) + const std::uint32_t parentHandle = pParentImpl->GetRedrawHandle(); + if (parentHandle != kInvalidRedrawHandle && m_RedrawQueue.count(parentHandle) > 0) return; - iter = m_RedrawQueue.begin(); - } - else if (*iter == pWindow) - { - return; } } - m_RedrawQueue.push_back(pWindow); + + // insertion with automatic deduplication + m_RedrawQueue.insert(handle); } void CGUI_Impl::RemoveFromRedrawQueue(CGUIElement* pWindow) { - m_RedrawQueue.remove(pWindow); + auto* pImpl = dynamic_cast(pWindow); + if (!pImpl) + return; + + const std::uint32_t handle = pImpl->GetRedrawHandle(); + if (handle == kInvalidRedrawHandle) + return; + + m_RedrawQueue.erase(handle); +} + +std::uint32_t CGUI_Impl::RegisterRedrawHandle(CGUIElement_Impl* pElement) +{ + if (!pElement) + return kInvalidRedrawHandle; + + std::uint32_t handle = kInvalidRedrawHandle; + do + { + handle = m_nextRedrawHandle++; + } while (handle == kInvalidRedrawHandle || m_RedrawRegistry.count(handle) != 0); + + m_RedrawRegistry[handle] = pElement; + return handle; +} + +void CGUI_Impl::ReleaseRedrawHandle(std::uint32_t handle) +{ + if (handle == kInvalidRedrawHandle) + return; + + m_RedrawRegistry.erase(handle); + m_RedrawQueue.erase(handle); +} + +CGUIElement* CGUI_Impl::ResolveRedrawHandle(std::uint32_t handle) const +{ + if (handle == kInvalidRedrawHandle) + return nullptr; + + auto iter = m_RedrawRegistry.find(handle); + if (iter == m_RedrawRegistry.end()) + return nullptr; + + return iter->second; } CGUIButton* CGUI_Impl::CreateButton(CGUIElement* pParent, const char* szCaption) @@ -1710,3 +1824,33 @@ CEGUI::Window* CGUI_Impl::GetMasterWindow(CEGUI::Window* wnd) } return wnd; } + +void CGUI_Impl::Cleanup() +{ + try + { + CleanDeadPool(); + + m_pTop = nullptr; + + if (m_pWindowManager) + m_pWindowManager->destroyAllWindows(); + + // Clear redraw structures that may reference old elements + m_RedrawQueue.clear(); + m_RedrawRegistry.clear(); + + // Recreate the root window (destroyed above via destroyAllWindows) + CreateRootWindow(); + } + catch (const std::exception& e) + { + WriteDebugEvent(SString("CGUI_Impl::Cleanup - Exception: %s", e.what())); + m_pTop = nullptr; + } + catch (...) + { + WriteDebugEvent("CGUI_Impl::Cleanup() failed with unknown exception"); + m_pTop = nullptr; + } +} diff --git a/Client/gui/CGUI_Impl.h b/Client/gui/CGUI_Impl.h index 6bd48fb7473..a8b8f07c6a9 100644 --- a/Client/gui/CGUI_Impl.h +++ b/Client/gui/CGUI_Impl.h @@ -15,6 +15,9 @@ class CGUI_Impl; #include #include +#include +#include +#include #include #define CGUI_CHAR_SIZE 6 @@ -55,11 +58,13 @@ namespace CEGUI class EventArgs; class GUISheet; typedef GUISheet DefaultWindow; -} // namespace CEGUI +} // namespace CEGUI class CGUI_Impl : public CGUI, public CGUITabList { public: + static constexpr std::uint32_t kInvalidRedrawHandle = 0; + CGUI_Impl(IDirect3DDevice9* pDevice); ~CGUI_Impl(); @@ -82,8 +87,7 @@ class CGUI_Impl : public CGUI, public CGUITabList eInputMode GetGUIInputMode(); static CEGUI::String GetUTFString(const char* szInput); static CEGUI::String GetUTFString(const std::string& strInput); - static CEGUI::String GetUTFString(const CEGUI::String& strInput); // Not defined - + static CEGUI::String GetUTFString(const CEGUI::String& strInput); // Not defined // CGUIMessageBox* CreateMessageBox(const char* szTitle, const char* szMessage, unsigned int uiFlags); @@ -276,10 +280,15 @@ class CGUI_Impl : public CGUI, public CGUITabList void RemoveFromRedrawQueue(CGUIElement* pWindow); void CleanDeadPool(); + void DestroyElementRecursive(CGUIElement* pElement); CGUIWindow* LoadLayout(CGUIElement* pParent, const SString& strFilename); bool LoadImageset(const SString& strFilename); + // Cleanup CEGUI active resources (dead pool) + void Cleanup(); + private: + friend class CGUIElement_Impl; CGUIButton* _CreateButton(CGUIElement_Impl* pParent = NULL, const char* szCaption = ""); CGUICheckBox* _CreateCheckBox(CGUIElement_Impl* pParent = NULL, const char* szCaption = "", bool bChecked = false); CGUIRadioButton* _CreateRadioButton(CGUIElement_Impl* pParent = NULL, const char* szCaption = ""); @@ -322,7 +331,13 @@ class CGUI_Impl : public CGUI, public CGUITabList CGUIFont_Impl* m_pSansFont; CGUIFont_Impl* m_pUniFont; - std::list m_RedrawQueue; + std::unordered_set m_RedrawQueue; + std::unordered_map m_RedrawRegistry; + std::uint32_t m_nextRedrawHandle; + + std::uint32_t RegisterRedrawHandle(CGUIElement_Impl* pElement); + void ReleaseRedrawHandle(std::uint32_t handle); + CGUIElement* ResolveRedrawHandle(std::uint32_t handle) const; unsigned long m_ulPreviousUnique; @@ -350,4 +365,6 @@ class CGUI_Impl : public CGUI, public CGUITabList bool m_HasSchemeLoaded; SString m_CurrentSchemeName; CElapsedTime m_RenderOkTimer; + + void CreateRootWindow(); }; diff --git a/Client/gui/GuiCleanup.h b/Client/gui/GuiCleanup.h new file mode 100644 index 00000000000..0a88fe4f393 --- /dev/null +++ b/Client/gui/GuiCleanup.h @@ -0,0 +1,38 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: gui/GuiCleanup.h + * PURPOSE: Shared helpers for recursive CEGUI teardown + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ +#pragma once + +#include +#include "CGUIElement_Impl.h" + +inline void DestroyGuiWindowRecursive(CEGUI::Window* pWindow) +{ + if (!pWindow) + return; + + const size_t childCount = pWindow->getChildCount(); + for (size_t idx = childCount; idx > 0; --idx) + { + if (CEGUI::Window* pChildWindow = pWindow->getChildAtIdx(static_cast(idx - 1))) + DestroyGuiWindowRecursive(pChildWindow); + } + + if (void* pUserData = pWindow->getUserData()) + { + CGUIElement* pElement = reinterpret_cast(pUserData); + if (CGUIElement_Impl* pImpl = dynamic_cast(pElement)) + { + pImpl->UnregisterFromRedrawQueue(); + } + pWindow->setUserData(nullptr); + delete pElement; + } +} diff --git a/Client/gui/premake5.lua b/Client/gui/premake5.lua index 9fa53ab4f61..1f6acdcf311 100644 --- a/Client/gui/premake5.lua +++ b/Client/gui/premake5.lua @@ -3,6 +3,7 @@ project "GUI" kind "SharedLib" targetname "cgui" targetdir(buildpath("mta")) + clangtidy "On" filter "system:windows" includedirs { "../../vendor/sparsehash/src/windows" } @@ -39,7 +40,7 @@ project "GUI" "*.h", "*.cpp" } - + filter "architecture:not x86" flags { "ExcludeFromBuild" } diff --git a/Client/launch/Main.cpp b/Client/launch/Main.cpp index 8a5f83f5622..71f2e22816d 100644 --- a/Client/launch/Main.cpp +++ b/Client/launch/Main.cpp @@ -3,7 +3,7 @@ * PROJECT: Multi Theft Auto v1.0 * LICENSE: See LICENSE in the top level directory * FILE: launch/Main.cpp - * PURPOSE: Unchanging .exe that doesn't change + * PURPOSE: Launcher * * Multi Theft Auto is available from https://www.multitheftauto.com/ * @@ -11,6 +11,23 @@ #include "StdInc.h" +// C++ STL +#include // std::array for safe command buffer +#include // std::bit_cast for safe function pointer conversion +#include // std::expected/std::unexpected for error handling +#include // std::format for string formatting +#include // std::ranges::copy/copy_n for safe copying +#include // std::span for memory view with bounds checking +#include // std::string_view for string parameters and constants +#include // std::is_trivially_copyable_v for compile-time checks +#include // std::forward for perfect forwarding + +// C STL +#include // std::strlen for C string length + +// Platform-specific headers +#include // GetModuleInformation, MODULEINFO + /* IMPORTANT @@ -22,74 +39,348 @@ (set flag.new_client_exe on the build server to generate new exe) */ -/////////////////////////////////////////////////////////////// -// -// WinMain -// -// -// -/////////////////////////////////////////////////////////////// -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +namespace mta::launcher { - if (!IsWindowsXPSP3OrGreater()) + enum class LoadResult : std::uint32_t { - BrowseToSolution("launch-xpsp3-check", ASK_GO_ONLINE, "This version of MTA requires Windows XP SP3 or later"); - return 1; - } + Success = 0, + PathError = 1, + LoadError = 2, + FunctionError = 3 + }; - // Group our processes and windows under a single taskbar button - SetCurrentProcessExplicitAppUserModelID(L"Multi Theft Auto"); + enum class DllLoadError : std::uint32_t + { + FileNotFound = 1, + InvalidPath = 2, + LoadFailed = 3 + }; + + // concepts for type safety + template + concept ValidBufferSize = N > 0 && N <= 65536; - // Load the loader.dll and continue the load #ifdef MTA_DEBUG - SString strLoaderDllFilename = "loader_d.dll"; + constexpr std::string_view LOADER_DLL = "loader_d.dll"; #else - SString strLoaderDllFilename = "loader.dll"; + constexpr std::string_view LOADER_DLL = "loader.dll"; #endif - SString strMTASAPath = PathJoin(GetLaunchPath(), "mta"); - SString strLoaderDllPathFilename = PathJoin(strMTASAPath, strLoaderDllFilename); + // RAII wrapper for preserving GetLastError + class [[nodiscard]] LastErrorPreserver + { + DWORD saved_error_; - // No Windows error box during first load attempt - DWORD dwPrevMode = SetErrorMode(SEM_FAILCRITICALERRORS); - HMODULE hModule = LoadLibraryW(FromUTF8(strLoaderDllPathFilename)); - DWORD dwLoadLibraryError = GetLastError(); - SetErrorMode(dwPrevMode); + public: + LastErrorPreserver() noexcept : saved_error_(GetLastError()) {} - if (!hModule) + ~LastErrorPreserver() noexcept { SetLastError(saved_error_); } + + LastErrorPreserver(const LastErrorPreserver&) = delete; + LastErrorPreserver& operator=(const LastErrorPreserver&) = delete; + LastErrorPreserver(LastErrorPreserver&&) = delete; + LastErrorPreserver& operator=(LastErrorPreserver&&) = delete; + }; + + // RAII scope_exit with perfect forwarding + template + struct [[nodiscard]] scope_exit { - // Retry using MTA current directory - SetCurrentDirectoryW(FromUTF8(strMTASAPath)); - hModule = LoadLibraryW(FromUTF8(strLoaderDllPathFilename)); - dwLoadLibraryError = GetLastError(); - if (hModule) + F f; + + explicit scope_exit(F&& func) noexcept : f(std::forward(func)) {} + + ~scope_exit() noexcept { f(); } + + scope_exit(const scope_exit&) = delete; + scope_exit& operator=(const scope_exit&) = delete; + scope_exit(scope_exit&&) = delete; + scope_exit& operator=(scope_exit&&) = delete; + }; + + template + constexpr auto make_scope_exit(F&& f) noexcept + { + return scope_exit{std::forward(f)}; + } + + // DLL directory guard with error preservation and optimized allocation + class [[nodiscard]] DllDirectoryGuard + { + std::wstring original_dir; + bool changed = false; + + public: + DllDirectoryGuard() + { + LastErrorPreserver error_guard; + DWORD len = GetDllDirectoryW(0, nullptr); + if (len > 0) + { + try + { + original_dir.resize_and_overwrite(len, + [](wchar_t* buf, std::size_t n) -> std::size_t + { + DWORD copied = GetDllDirectoryW(static_cast(n), buf); + return copied < n ? copied : 0; + }); + } + catch (...) + { + original_dir.resize(len); + if (GetDllDirectoryW(len, original_dir.data()) == 0) + original_dir.clear(); + } + } + } + + [[nodiscard]] bool SetDirectory(const wchar_t* path) noexcept + { + if (SetDllDirectoryW(path)) + { + changed = true; + return true; + } + return false; + } + + ~DllDirectoryGuard() noexcept { - AddReportLog(5712, SString("LoadLibrary '%s' succeeded on change to directory '%s'", *strLoaderDllFilename, *strMTASAPath)); + if (changed) + SetDllDirectoryW(original_dir.empty() ? nullptr : original_dir.c_str()); } + + DllDirectoryGuard(const DllDirectoryGuard&) = delete; + DllDirectoryGuard& operator=(const DllDirectoryGuard&) = delete; + DllDirectoryGuard(DllDirectoryGuard&&) = delete; + DllDirectoryGuard& operator=(DllDirectoryGuard&&) = delete; + }; + + // COM initialization with error handling + [[nodiscard]] std::expected InitializeCOM() noexcept + { + HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + if (FAILED(hr)) + return std::unexpected(hr); + return {}; } - int iReturnCode = 0; - if (hModule) + // Library loading with optimized string conversion + [[nodiscard]] std::expected LoadLibrarySafe(const SString& dll_path, std::string_view dll_name, const SString& mta_path) { - // Find and call DoWinMain - typedef int (*PFNDOWINMAIN)(HINSTANCE, HINSTANCE, LPSTR, int); - PFNDOWINMAIN pfnDoWinMain = static_cast(static_cast(GetProcAddress(hModule, "DoWinMain"))); - if (pfnDoWinMain) - iReturnCode = pfnDoWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); + WString dll_path_w = FromUTF8(dll_path); + if (dll_path_w.empty()) [[unlikely]] + return std::unexpected(DllLoadError::InvalidPath); + + if (HMODULE module = LoadLibraryW(dll_path_w.c_str())) + return module; + + DllDirectoryGuard dll_guard; + WString mta_path_w = FromUTF8(mta_path); + std::wstring dll_name_w; + try + { + dll_name_w.resize_and_overwrite(dll_name.size() * 2, + [&dll_name](wchar_t* buf, std::size_t n) -> std::size_t + { + SString temp{dll_name.data(), dll_name.size()}; + WString wide = FromUTF8(temp); + if (wide.empty()) + return 0; + std::size_t len = std::min(n, wide.length()); + std::ranges::copy_n(wide.c_str(), len, buf); + return len; + }); + } + catch (...) + { + SString temp{dll_name.data(), dll_name.size()}; + WString wide = FromUTF8(temp); + dll_name_w.assign(wide.begin(), wide.end()); + } + + if (mta_path_w.empty() || dll_name_w.empty()) [[unlikely]] + return std::unexpected(DllLoadError::InvalidPath); - FreeLibrary(hModule); + if (!dll_guard.SetDirectory(mta_path_w.c_str())) + return std::unexpected(DllLoadError::LoadFailed); + + std::wstring full_path_w = std::wstring(mta_path_w.c_str()) + L"\\" + dll_name_w; + if (HMODULE module = LoadLibraryW(full_path_w.c_str())) + return module; + + return std::unexpected(DllLoadError::LoadFailed); } - else + + // Function execution with bounds checking and secure conversion + [[nodiscard]] std::expected ExecuteDoWinMain(HMODULE module, HINSTANCE inst, HINSTANCE prev, LPSTR cmd, int show) { - iReturnCode = 1; - SString strError = GetSystemErrorMessage(dwLoadLibraryError); - SString strMessage("Failed to load: '%s'\n\n%s", *strLoaderDllPathFilename, *strError); - AddReportLog(5711, strMessage); - - // Error could be due to missing VC Redist. - // Online help page will have VC Redist download link. - BrowseToSolution("loader-dll-not-loadable", ASK_GO_ONLINE, strMessage); + using DoWinMainFunc = int (*)(HINSTANCE, HINSTANCE, LPSTR, int); + + if (!module) [[unlikely]] + return std::unexpected(LoadResult::FunctionError); + + FARPROC proc = GetProcAddress(module, "DoWinMain"); + if (!proc) [[unlikely]] + { + AddReportLog(5713, "Launcher Main: DoWinMain function not found"); + return std::unexpected(LoadResult::FunctionError); + } + + // Validate function pointer within module bounds + MODULEINFO info{}; + if (!GetModuleInformation(GetCurrentProcess(), module, &info, sizeof(info))) + return std::unexpected(LoadResult::FunctionError); + + std::span module_span{static_cast(info.lpBaseOfDll), info.SizeOfImage}; + auto func_ptr = reinterpret_cast(proc); + + if (func_ptr < module_span.data() || func_ptr >= (module_span.data() + module_span.size())) + { + AddReportLog(5713, "Launcher Main: Function pointer outside module bounds"); + return std::unexpected(LoadResult::FunctionError); + } + + // Command line handling + constexpr std::size_t MAX_CMD = 8192; + static_assert(ValidBufferSize); + + std::array safe_cmd{}; + if (cmd) + { + auto src_view = std::string_view{cmd, std::min(std::strlen(cmd), MAX_CMD - 1)}; + std::ranges::copy(src_view, safe_cmd.begin()); + } + + // Function pointer conversion with safety checks + static_assert(sizeof(FARPROC) == sizeof(DoWinMainFunc), "Function pointer size mismatch"); + static_assert(alignof(FARPROC) == alignof(DoWinMainFunc), "Function pointer alignment mismatch"); + static_assert(std::is_trivially_copyable_v, "FARPROC must be trivially copyable for bit_cast"); + static_assert(std::is_trivially_copyable_v, "DoWinMainFunc must be trivially copyable for bit_cast"); + + auto do_win_main = std::bit_cast(proc); + if (!do_win_main) [[unlikely]] + return std::unexpected(LoadResult::FunctionError); + + try + { + return do_win_main(inst, prev, safe_cmd.data(), show); + } + catch (...) + { + AddReportLog(5722, "Launcher Main: Exception in DoWinMain"); + return std::unexpected(LoadResult::FunctionError); + } + } + + // Path validation + [[nodiscard]] constexpr bool ValidatePathSafety(std::string_view path) noexcept + { + return path.find("..") == std::string_view::npos && path.find("//") == std::string_view::npos; + } + + // Path discovery with validation + [[nodiscard]] std::expected FindMtaPath(const SString& launch_path) + { + if (!ValidatePathSafety(launch_path)) [[unlikely]] + { + AddReportLog(5731, std::format("Launcher Main: Invalid launch path: '{}'", std::string_view{launch_path})); + return std::unexpected(LoadResult::PathError); + } + + SString mta_path = PathJoin(launch_path, "mta"); + if (!ValidatePathSafety(mta_path)) [[unlikely]] + return std::unexpected(LoadResult::PathError); + + if (DirectoryExists(mta_path)) + return mta_path; + + SString parent = PathJoin(launch_path, ".."); + if (!ValidatePathSafety(parent)) [[unlikely]] + return std::unexpected(LoadResult::PathError); + + SString alt = PathJoin(parent, "mta"); + + if (ValidatePathSafety(alt) && DirectoryExists(alt)) + return alt; + + AddReportLog(5730, std::format("Launcher Main: MTA directory not found from: '{}'", std::string_view{launch_path})); + return std::unexpected(LoadResult::PathError); + } +} // namespace mta::launcher + +int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) +{ + using namespace mta::launcher; + + // Configure silent error handling + _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); + + // COM initialization + auto com_result = InitializeCOM(); + if (!com_result) [[unlikely]] + { + AddReportLog(5737, std::format("Launcher Main: COM initialization failed (hr=0x{:08X})", static_cast(com_result.error()))); + } + + auto com_cleanup = make_scope_exit([]() noexcept { CoUninitialize(); }); + + // Set taskbar grouping + [[maybe_unused]] HRESULT hr = SetCurrentProcessExplicitAppUserModelID(L"Multi Theft Auto " MTA_STR(MTASA_VERSION_MAJOR) L"." MTA_STR(MTASA_VERSION_MINOR)); + + // Path discovery + SString launch_path = GetLaunchPath(); + auto mta_path_result = FindMtaPath(launch_path); + + if (!mta_path_result) [[unlikely]] + { + return std::to_underlying(mta_path_result.error()); + } + + SString mta_path = mta_path_result.value(); + SString dll_path = PathJoin(mta_path, SString{LOADER_DLL.data(), LOADER_DLL.size()}); + + AddReportLog(5725, SString("Launcher Main: Launch: '%s', MTA: '%s'", launch_path.c_str(), mta_path.c_str())); + + // DLL loading + auto module_result = LoadLibrarySafe(dll_path, LOADER_DLL, mta_path); + + if (!module_result) [[unlikely]] + { + DWORD error = GetLastError(); + SString msg = std::format("Launcher Main: Failed to load: '{}'\n\n{}", dll_path.data(), GetSystemErrorMessage(error).data()); + AddReportLog(5711, msg); + + // Pattern matching + switch (module_result.error()) + { + case DllLoadError::FileNotFound: + AddReportLog(5734, "Launcher Main: Build the 'Loader' project to create loader_d.dll"); + BrowseToSolution("loader-dll-missing", ASK_GO_ONLINE, msg); + break; + case DllLoadError::InvalidPath: + case DllLoadError::LoadFailed: + BrowseToSolution("loader-dll-not-loadable", ASK_GO_ONLINE, msg); + break; + } + + return std::to_underlying(LoadResult::LoadError); } - return iReturnCode; + HMODULE module = module_result.value(); + + // RAII module cleanup + auto module_cleanup = make_scope_exit( + [module]() noexcept + { + if (module) + FreeLibrary(module); + }); + + // Execution with concepts + auto exec_result = ExecuteDoWinMain(module, hInstance, hPrevInstance, lpCmdLine, nCmdShow); + + return exec_result.value_or(std::to_underlying(LoadResult::FunctionError)); } diff --git a/Client/launch/Multi Theft Auto.h b/Client/launch/Multi Theft Auto.h index 68c2c2ad284..8242869421a 100644 --- a/Client/launch/Multi Theft Auto.h +++ b/Client/launch/Multi Theft Auto.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// // Header File for : Multi Theft Auto -#define ID_ICON 101 +#define ID_ICON 101 ///////////////////////////////////////////////////////////////////////////// diff --git a/Client/launch/Multi Theft Auto.manifest b/Client/launch/Multi Theft Auto.manifest index 159fa06d34a..a08b225c85f 100644 --- a/Client/launch/Multi Theft Auto.manifest +++ b/Client/launch/Multi Theft Auto.manifest @@ -1,6 +1,6 @@ - + diff --git a/Client/launch/NEU/.gitattributes b/Client/launch/NEU/.gitattributes new file mode 100644 index 00000000000..2e92617703d --- /dev/null +++ b/Client/launch/NEU/.gitattributes @@ -0,0 +1 @@ +*.xml diff working-tree-encoding=UTF-16 eol=crlf diff --git a/Client/launch/NEU/Multi Theft Auto.gdf.xml b/Client/launch/NEU/Multi Theft Auto.gdf.xml index d1acb05b26e..7f8cfea319e 100644 Binary files a/Client/launch/NEU/Multi Theft Auto.gdf.xml and b/Client/launch/NEU/Multi Theft Auto.gdf.xml differ diff --git a/Client/launch/StdInc.h b/Client/launch/StdInc.h index b147834b152..5a28fb84f5d 100644 --- a/Client/launch/StdInc.h +++ b/Client/launch/StdInc.h @@ -1,13 +1,17 @@ - +#pragma once #define WIN32_LEAN_AND_MEAN -#include #define MTA_CLIENT -#include "SharedUtil.h" -#include "resource.h" +// Windows system headers +#include +#include +#include #include + +// C STL headers #include -#include "shellapi.h" -#include +// Project headers +#include "resource.h" +#include "SharedUtil.h" diff --git a/Client/launch/launch.rc b/Client/launch/launch.rc index 2135e9c704b..22b61b48efe 100644 --- a/Client/launch/launch.rc +++ b/Client/launch/launch.rc @@ -71,8 +71,8 @@ IDI_ICON1 ICON "resource\\mtaicon.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,6,0,0 - PRODUCTVERSION 1,6,0,0 + FILEVERSION 1,7,0,0 + PRODUCTVERSION 1,7,0,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -89,10 +89,10 @@ BEGIN BEGIN VALUE "CompanyName", "Multi Theft Auto" VALUE "FileDescription", "Multi Theft Auto Launcher" - VALUE "FileVersion", "1.6.0.0" - VALUE "LegalCopyright", "(C) 2003 - 2023 Multi Theft Auto" + VALUE "FileVersion", "1.7.0.0" + VALUE "LegalCopyright", "(C) 2003 - 2025 Multi Theft Auto" VALUE "ProductName", "MTA San Andreas" - VALUE "ProductVersion", "1.6.0.0" + VALUE "ProductVersion", "1.7.0.0" END END BLOCK "VarFileInfo" diff --git a/Client/launch/premake5.lua b/Client/launch/premake5.lua index 4a8fed34f6f..547e9995081 100644 --- a/Client/launch/premake5.lua +++ b/Client/launch/premake5.lua @@ -4,6 +4,7 @@ project "Client Launcher" targetname "Multi Theft Auto" targetdir(buildpath(".")) debugdir(buildpath(".")) + clangtidy "On" includedirs { "../../Shared/sdk", diff --git a/Client/launch/resource.h b/Client/launch/resource.h index fc507efb3f7..18e8c03853d 100644 --- a/Client/launch/resource.h +++ b/Client/launch/resource.h @@ -2,15 +2,15 @@ // Microsoft Visual C++ generated include file. // Used by launch.rc // -#define IDI_ICON1 110 +#define IDI_ICON1 110 // Next default values for new objects // #ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 115 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1010 -#define _APS_NEXT_SYMED_VALUE 101 -#endif + #ifndef APSTUDIO_READONLY_SYMBOLS + #define _APS_NEXT_RESOURCE_VALUE 115 + #define _APS_NEXT_COMMAND_VALUE 40001 + #define _APS_NEXT_CONTROL_VALUE 1010 + #define _APS_NEXT_SYMED_VALUE 101 + #endif #endif diff --git a/Client/loader-proxy/main.cpp b/Client/loader-proxy/main.cpp index 73d6b1b1f04..db8d3b0bd1b 100644 --- a/Client/loader-proxy/main.cpp +++ b/Client/loader-proxy/main.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +65,31 @@ HMODULE g_netc = nullptr; BOOL(WINAPI* Win32GetVersionExA)(LPOSVERSIONINFOA) = nullptr; +template +static T FarProcToFunctionPtr(FARPROC proc) +{ + T fn = nullptr; + static_assert(sizeof(fn) == sizeof(proc), "Unexpected function pointer size"); + if (proc) + std::memcpy(&fn, &proc, sizeof(fn)); + return fn; +} + +template +static FARPROC FunctionPtrToFarProc(T fn) +{ + FARPROC proc = nullptr; + static_assert(sizeof(proc) == sizeof(fn), "Unexpected function pointer size"); + std::memcpy(&proc, &fn, sizeof(proc)); + return proc; +} + +template +static T GetProcAddressAs(HMODULE module, const char* procName) +{ + return FarProcToFunctionPtr(module ? GetProcAddress(module, procName) : nullptr); +} + BOOL WINAPI DllMain(HINSTANCE dll, DWORD reason, LPVOID) { if (reason == DLL_PROCESS_ATTACH) @@ -103,15 +129,14 @@ BOOL OnLibraryAttach() ApplyDpiAwareness(); // Replace the first called imported procedure from the executable. - FARPROC procedure = SetImportProcAddress("kernel32.dll", "GetVersionExA", reinterpret_cast(MyGetVersionExA)); - + FARPROC procedure = SetImportProcAddress("kernel32.dll", "GetVersionExA", FunctionPtrToFarProc(&MyGetVersionExA)); if (!procedure) { DisplayErrorMessageBox(MakeLauncherError(L"Failed to redirect start procedure."), L"CL50"); return FALSE; } - Win32GetVersionExA = reinterpret_cast(procedure); + Win32GetVersionExA = FarProcToFunctionPtr(procedure); return TRUE; } @@ -121,9 +146,151 @@ VOID OnGameLaunch() std::error_code ec{}; + // Log current working directory + wchar_t inheritedCwd[32768]{}; + DWORD inheritedCwdLen = GetCurrentDirectoryW(32768, inheritedCwd); + + // CEF subprocess may have different working directory than parent process + // Try multiple methods to find the GTA directory: + // - Parse CEF command-line switch --mta-gta-path= + // - Read from gta_path.txt file written by parent process + // - Check MTA_GTA_PATH environment variable + // - Use current_path() as fallback + + // Parse CEF command-line switch + std::array gtaPathFromCmdLine{}; + DWORD cmdLinePathLen = 0; + std::array mtaBasePathFromCmdLine{}; + DWORD mtaBasePathLen = 0; + { + const LPWSTR cmdLine = GetCommandLineW(); + if (cmdLine) + { + // Parse for --mta-gta-path= + // CEF command-line format: --switch=value or --switch=\"value with spaces\" + constexpr std::wstring_view switchPrefix = L"--mta-gta-path="; + if (const wchar_t* switchPos = wcsstr(cmdLine, switchPrefix.data())) + { + const wchar_t* const pathStartBase = switchPos + switchPrefix.length(); + const wchar_t* pathStart = pathStartBase; + + // Skip opening quote if present + if (*pathStart == L'"') + pathStart++; + + // Find end of path (closing quote or space) + const wchar_t* pathEnd = pathStart; + const bool isQuoted = (pathStartBase[0] == L'"'); + + while (*pathEnd != L'\0') + { + if (isQuoted && *pathEnd == L'"') + { + break; // End of quoted path + } + else if (!isQuoted && *pathEnd == L' ') + { + break; // End of unquoted path + } + pathEnd++; + } + + const size_t pathLen = pathEnd - pathStart; + if (pathLen > 0 && pathLen < gtaPathFromCmdLine.size()) + { + wcsncpy_s(gtaPathFromCmdLine.data(), gtaPathFromCmdLine.size(), pathStart, pathLen); + cmdLinePathLen = static_cast(pathLen); + } + } + + // Parse for --mta-base-path= + constexpr std::wstring_view mtaSwitchPrefix = L"--mta-base-path="; + if (const wchar_t* mtaSwitchPos = wcsstr(cmdLine, mtaSwitchPrefix.data())) + { + const wchar_t* const mtaPathStartBase = mtaSwitchPos + mtaSwitchPrefix.length(); + const wchar_t* mtaPathStart = mtaPathStartBase; + + // Skip opening quote if present + if (*mtaPathStart == L'"') + mtaPathStart++; + + // Find end of path (closing quote or space) + const wchar_t* mtaPathEnd = mtaPathStart; + const bool mtaIsQuoted = (mtaPathStartBase[0] == L'"'); + + while (*mtaPathEnd != L'\0') + { + if (mtaIsQuoted && *mtaPathEnd == L'"') + { + break; + } + else if (!mtaIsQuoted && *mtaPathEnd == L' ') + { + break; + } + mtaPathEnd++; + } + + const size_t mtaPathLength = mtaPathEnd - mtaPathStart; + if (mtaPathLength > 0 && mtaPathLength < mtaBasePathFromCmdLine.size()) + { + wcsncpy_s(mtaBasePathFromCmdLine.data(), mtaBasePathFromCmdLine.size(), mtaPathStart, mtaPathLength); + mtaBasePathLen = static_cast(mtaPathLength); + } + } + } + } + + // Read from file + std::array gtaPathFromFile{}; + DWORD filePathLen = 0; + const fs::path gtaPathFile = fs::current_path(ec) / L".." / L".." / L"MTA" / L"CEF" / L"gta_path.txt"; + if (FILE* pFile = nullptr; _wfopen_s(&pFile, gtaPathFile.c_str(), L"r") == 0 && pFile) + { + std::array buffer{}; + const size_t bytesRead = fread(buffer.data(), 1, buffer.size() - 1, pFile); + fclose(pFile); + if (bytesRead > 0) + { + buffer[bytesRead] = '\0'; // Null-terminate + // Convert UTF-8 to wide char + if (MultiByteToWideChar(CP_UTF8, 0, buffer.data(), -1, gtaPathFromFile.data(), static_cast(gtaPathFromFile.size())) > 0) + { + filePathLen = static_cast(wcslen(gtaPathFromFile.data())); + } + } + } + + // Check environment variable + std::array gtaPathFromEnv{}; + const DWORD envLen = GetEnvironmentVariableW(L"MTA_GTA_PATH", gtaPathFromEnv.data(), static_cast(gtaPathFromEnv.size())); + + const fs::path gtaDirectory = [&]() -> fs::path + { + // CEF command-line switch + if (cmdLinePathLen > 0 && cmdLinePathLen < gtaPathFromCmdLine.size()) + { + return fs::path{gtaPathFromCmdLine.data()}; + } + // File-based communication + else if (filePathLen > 0 && filePathLen < gtaPathFromFile.size()) + { + return fs::path{gtaPathFromFile.data()}; + } + // Environment variable + else if (envLen > 0 && envLen < gtaPathFromEnv.size()) + { + return fs::path{gtaPathFromEnv.data()}; + } + // Current working directory + else + { + return fs::current_path(ec); + } + }(); + // MTA:SA launches GTA:SA process with the GTA:SA installation directory as the current directory. // We can't use the path to the current executable, because it's not in the game directory anymore. - const fs::path gtaDirectory = fs::current_path(ec); if (ec) { @@ -148,43 +315,59 @@ VOID OnGameLaunch() } } - // Abort if the current process is not the game executable. - const std::wstring processName = GetCurrentProcessPath().filename().wstring(); + // Detect if running as CEF subprocess by checking for --mta-base-path switch + // CEF subprocesses have this switch and skip validation checks + const bool bIsCefSubprocess = (mtaBasePathLen > 0); - if (!IEqual(GTA_EXE_NAME, processName)) + if (bIsCefSubprocess) { - std::wstring message = L"Executable has an incorrect name (" + processName + L")."; - DisplayErrorMessageBox(MakeLauncherError(message), L"CL52"); - return; + AddLaunchLog("Detected CEF subprocess mode - skipping process name validation"); } - // MTA:SA must be the parent launcher process in every case. - const fs::path launcherPath = GetParentProcessPath(); + // Abort if the current process is not the game executable + if (!bIsCefSubprocess) + { + const std::wstring processName = GetCurrentProcessPath().filename().wstring(); - if (launcherPath.empty()) + if (!IEqual(GTA_EXE_NAME, processName)) + { + std::wstring message = L"Executable has an incorrect name (" + processName + L")."; + DisplayErrorMessageBox(MakeLauncherError(message), L"CL52"); + return; + } + } + + // MTA must be the parent launcher process in every case + // For CEF subprocesses, skip parent process check + const fs::path launcherPath = bIsCefSubprocess ? fs::path{} : GetParentProcessPath(); + + if (!bIsCefSubprocess && launcherPath.empty()) { AddLaunchLog("Unable to determine launcher executable"); DisplayErrorMessageBox(MakeLauncherError(L"Unable to determine launcher executable."), L"CL53"); return; } - // Check if the name of the launcher process matches Multi Theft Auto. - const std::wstring launcherName = launcherPath.filename().wstring(); - - if (!IEqual(MTA_EXE_NAME, launcherName)) + // Check if the name of the launcher process matches Multi Theft Auto + if (!bIsCefSubprocess) { - if (IEqual(EXPLORER_EXE_NAME, launcherName)) + const std::wstring launcherName = launcherPath.filename().wstring(); + + if (!IEqual(MTA_EXE_NAME, launcherName)) { - DisplayErrorMessageBox(MakeLauncherError(L"Do not run this game from Windows Explorer."), L"CL54"); - return; - } + if (IEqual(EXPLORER_EXE_NAME, launcherName)) + { + DisplayErrorMessageBox(MakeLauncherError(L"Do not run this game from Windows Explorer."), L"CL54"); + return; + } - std::wstring message = L"Launcher executable has an incorrect name (" + launcherName + L")."; + std::wstring message = L"Launcher executable has an incorrect name (" + launcherName + L")."; - if (!DisplayWarningMessageBox(MakeLauncherError(message), L"CL54")) - { - ExitProcess(1); - return; + if (!DisplayWarningMessageBox(MakeLauncherError(message), L"CL54")) + { + ExitProcess(1); + return; + } } } @@ -200,7 +383,33 @@ VOID OnGameLaunch() } // Check if the MTA subdirectory exists. - const fs::path mtaRootDirectory = launcherPath.parent_path(); + // Use --mta-base-path from command-line if available, + // otherwise fall back to parent process path + const fs::path mtaRootDirectory = [&]() -> fs::path + { + if (bIsCefSubprocess && mtaBasePathLen > 0 && mtaBasePathLen < mtaBasePathFromCmdLine.size()) + { + AddLaunchLog("Using MTA base path from CEF command-line switch: %S", mtaBasePathFromCmdLine.data()); + return fs::path{mtaBasePathFromCmdLine.data()}; + } + else if (!bIsCefSubprocess && !launcherPath.empty()) + { + return launcherPath.parent_path(); + } + else + { + AddLaunchLog("ERROR: Unable to determine MTA base path"); + return fs::path{}; + } + }(); + + if (mtaRootDirectory.empty()) + { + AddLaunchLog("MTA root directory is empty - cannot continue"); + DisplayErrorMessageBox(MakeLauncherError(L"Unable to determine MTA installation directory."), L"CL55"); + return; + } + const fs::path mtaDirectory = mtaRootDirectory / "MTA"; if (!fs::is_directory(mtaDirectory, ec)) @@ -252,14 +461,14 @@ VOID OnGameLaunch() ApplyDirectoryInformation(g_netc, mtaRootDirectory.wstring(), gtaDirectory.wstring()); - void (*InitNetRev)(const char*, const char*, const char*) = reinterpret_cast(GetProcAddress(g_netc, "InitNetRev")); + void (*InitNetRev)(const char*, const char*, const char*) = GetProcAddressAs(g_netc, "InitNetRev"); if (InitNetRev) { InitNetRev(GetProductRegistryPath(), GetProductCommonDataDir(), GetProductVersion()); } - bool (*CheckService)(unsigned int) = reinterpret_cast(GetProcAddress(g_netc, "CheckService")); + bool (*CheckService)(unsigned int) = GetProcAddressAs(g_netc, "CheckService"); if (!CheckService) { @@ -300,7 +509,7 @@ VOID OnGameLaunch() ApplyDirectoryInformation(g_core, mtaRootDirectory.wstring(), gtaDirectory.wstring()); // Initialize and run the core. - int (*InitializeCore)() = reinterpret_cast(GetProcAddress(g_core, "InitializeCore")); + int (*InitializeCore)() = GetProcAddressAs(g_core, "InitializeCore"); if (!InitializeCore) { @@ -327,7 +536,7 @@ BOOL WINAPI MyGetVersionExA(LPOSVERSIONINFOA versionInfo) BOOL result = Win32GetVersionExA(versionInfo); // Restore the function pointer we've overriden to get here. - SetImportProcAddress("kernel32.dll", "GetVersionExA", reinterpret_cast(Win32GetVersionExA)); + SetImportProcAddress("kernel32.dll", "GetVersionExA", FunctionPtrToFarProc(Win32GetVersionExA)); // Run our startup code. OnGameLaunch(); @@ -598,9 +807,9 @@ auto GetSystemErrorMessage(DWORD errorCode) -> std::wstring void ApplyDpiAwareness() { // Minimum version: Windows 10, version 1607 - static BOOL(WINAPI * Win32SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT value) = ([] { + static BOOL(WINAPI * Win32SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT value) = ([]() -> decltype(Win32SetProcessDpiAwarenessContext) { HMODULE user32 = LoadLibraryW(L"user32"); - return user32 ? reinterpret_cast(GetProcAddress(user32, "SetProcessDpiAwarenessContext")) : nullptr; + return user32 ? GetProcAddressAs(user32, "SetProcessDpiAwarenessContext") : nullptr; })(); if (Win32SetProcessDpiAwarenessContext) @@ -610,9 +819,9 @@ void ApplyDpiAwareness() } // Minimum version: Windows 8.1 - static HRESULT(WINAPI * Win32SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS value) = ([] { + static HRESULT(WINAPI * Win32SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS value) = ([]() -> decltype(Win32SetProcessDpiAwareness) { HMODULE shcore = LoadLibraryW(L"shcore"); - return shcore ? reinterpret_cast(GetProcAddress(shcore, "SetProcessDpiAwareness")) : nullptr; + return shcore ? GetProcAddressAs(shcore, "SetProcessDpiAwareness") : nullptr; })(); if (Win32SetProcessDpiAwareness) @@ -634,7 +843,7 @@ void ApplyDpiAwareness() void ApplyDirectoryInformation(HMODULE library, const std::wstring& mtaDirectory, const std::wstring& gtaDirectory) { // Set the path to the Multi Theft Auto directory. - void (*SetMTADirectory)(const wchar_t*, size_t) = reinterpret_cast(GetProcAddress(library, "SetMTADirectory")); + void (*SetMTADirectory)(const wchar_t*, size_t) = GetProcAddressAs(library, "SetMTADirectory"); if (SetMTADirectory) { @@ -642,7 +851,7 @@ void ApplyDirectoryInformation(HMODULE library, const std::wstring& mtaDirectory } // Set the path to the GTA: San Andreas directory. - void (*SetGTADirectory)(const wchar_t*, size_t) = reinterpret_cast(GetProcAddress(library, "SetGTADirectory")); + void (*SetGTADirectory)(const wchar_t*, size_t) = GetProcAddressAs(library, "SetGTADirectory"); if (SetGTADirectory) { diff --git a/Client/loader-proxy/premake5.lua b/Client/loader-proxy/premake5.lua index 36ad798f54f..fc50913b392 100644 --- a/Client/loader-proxy/premake5.lua +++ b/Client/loader-proxy/premake5.lua @@ -3,7 +3,15 @@ project "Loader Proxy" kind "SharedLib" targetname "mtasa" targetdir(buildpath("mta")) - targetsuffix "" + clangtidy "On" + + filter "configurations:Debug" + targetsuffix "_d" + + filter "configurations:Release or configurations:Nightly" + targetsuffix "" + + filter {} vpaths { ["Headers/*"] = "**.h", @@ -22,9 +30,6 @@ project "Loader Proxy" "../../Shared/sdk", } - filter "system:windows" - linkoptions { "/SAFESEH:NO" } - filter "architecture:not x86" flags { "ExcludeFromBuild" } diff --git a/Client/loader/CInstallManager.cpp b/Client/loader/CInstallManager.cpp index 61226afdc6d..b10196f6e15 100644 --- a/Client/loader/CInstallManager.cpp +++ b/Client/loader/CInstallManager.cpp @@ -17,6 +17,11 @@ #include "FileGenerator.h" #include "FileSystem.h" #include "SharedUtil.Memory.h" +#include "../core/FastFailCrashHandler/WerCrashHandler.h" + +#include +#include +#include namespace fs = std::filesystem; @@ -30,6 +35,51 @@ namespace // ////////////////////////////////////////////////////////// + // Compares AppCompat entries as case-insensitive multisets (order-independent) + bool AreAppCompatEntriesEqual(const std::vector& a, const std::vector& b) + { + if (a.size() != b.size()) + return false; + + std::vector sortedA = a; + std::vector sortedB = b; + + auto caseInsensitiveLess = [](const WString& lhs, const WString& rhs) { return _wcsicmp(lhs.c_str(), rhs.c_str()) < 0; }; + std::sort(sortedA.begin(), sortedA.end(), caseInsensitiveLess); + std::sort(sortedB.begin(), sortedB.end(), caseInsensitiveLess); + + for (size_t i = 0; i < sortedA.size(); ++i) + { + if (_wcsicmp(sortedA[i].c_str(), sortedB[i].c_str()) != 0) + return false; + } + return true; + } + + // Case-insensitive remove + void AppCompatListRemove(std::vector& itemList, const WString& item) + { + auto it = itemList.begin(); + while (it != itemList.end()) + { + if (_wcsicmp(it->c_str(), item.c_str()) == 0) + it = itemList.erase(it); + else + ++it; + } + } + + // Case-insensitive add-unique + void AppCompatListAddUnique(std::vector& itemList, const WString& item) + { + for (const auto& existing : itemList) + { + if (_wcsicmp(existing.c_str(), item.c_str()) == 0) + return; + } + itemList.push_back(item); + } + // Ensure report log stuff has correct tags void UpdateSettingsForReportLog() { @@ -42,20 +92,32 @@ namespace } // Comms between 'Admin' and 'User' processes - void SendStringToUserProcess(const SString& strText) { SetApplicationSetting("admin2user_comms", strText); } + void SendStringToUserProcess(const SString& strText) + { + SetApplicationSetting("admin2user_comms", strText); + } - SString ReceiveStringFromAdminProcess() { return GetApplicationSetting("admin2user_comms"); } + SString ReceiveStringFromAdminProcess() + { + return GetApplicationSetting("admin2user_comms"); + } - bool IsBlockingUserProcess() { return GetApplicationSetting("admin2user_comms") == "user_waiting"; } + bool IsBlockingUserProcess() + { + return GetApplicationSetting("admin2user_comms") == "user_waiting"; + } - void SetIsBlockingUserProcess() { SetApplicationSetting("admin2user_comms", "user_waiting"); } + void SetIsBlockingUserProcess() + { + SetApplicationSetting("admin2user_comms", "user_waiting"); + } void ClearIsBlockingUserProcess() { if (IsBlockingUserProcess()) SetApplicationSetting("admin2user_comms", ""); } -} // namespace +} // namespace ////////////////////////////////////////////////////////// // @@ -82,128 +144,138 @@ CInstallManager* GetInstallManager() ////////////////////////////////////////////////////////// void CInstallManager::InitSequencer() { - #define CR "\n" - SString strSource = CR "initial: " // *** Starts here by default - CR " CALL CheckOnRestartCommand " ////// Start of 'update game' ////// - CR " IF LastResult != ok GOTO update_end: " // - CR " " // - CR " CALL MaybeSwitchToTempExe " // If update files comes with an .exe, switch to that for the install - CR " " // - CR "copy_files: " // - CR " CALL InstallFiles " // Try to install update files - CR " IF LastResult == ok GOTO update_end: " // - CR " " // - CR " CALL ChangeToAdmin " // If install failed, try as admin - CR " " // - CR "copy_files_admin: " // - CR " CALL InstallFiles " // Try to install update files - CR " IF LastResult == ok GOTO update_end_admin: " // - CR " " // - CR " CALL ShowCopyFailDialog " // If install failed as admin, show message box - CR " IF LastResult == retry GOTO copy_files_admin: " // - CR " " // - CR "update_end_admin: " // - CR " CALL ChangeFromAdmin " // - CR " " // - CR "update_end: " ////// End of 'update game' ////// - CR " CALL SwitchBackFromTempExe " // - CR " " // - CR "newlayout_check:" ////// Start of 'new layout check' ////// - CR " CALL ProcessLayoutChecks " // - CR " IF LastResult == ok GOTO newlayout_end: " // - CR " " // - CR " CALL ChangeToAdmin " // If changes failed, try as admin - CR " IF LastResult == ok GOTO newlayout_check: " // - CR " CALL Quit " // - CR " " // - CR "newlayout_end: " ////// End of 'new layout check' ////// - CR " " // - CR "langfile_check: " ////// Start of 'Lang file fix' ////// - CR " CALL ProcessLangFileChecks " // Make changes to comply with requirements - CR " IF LastResult == ok GOTO langfile_end: " // - CR " " // - CR " CALL ChangeToAdmin " // If changes failed, try as admin - CR " IF LastResult == ok GOTO langfile_check: " // - CR " CALL Quit " // - CR " " // - CR "langfile_end: " ////// End of 'Lang file fix' ////// - CR " " // - CR "prepare_launch_location:" ////// Start of 'prepare launch location' ////// - CR " CALL PrepareLaunchLocation " // - CR " IF LastResult == ok GOTO prepare_launch_location_end: " // - CR " " // - CR " CALL ChangeToAdmin " // If changes failed, try as admin - CR " IF LastResult == ok GOTO prepare_launch_location: " // - CR " CALL Quit " // - CR " " // - CR "prepare_launch_location_end:" ////// End of 'prepare launch location' ////// - CR " " // - CR "gta_patch_check:" ////// Start of 'gta patch check' ////// - CR " CALL ProcessGtaPatchCheck " // - CR " IF LastResult != ok GOTO do_quit: " // Switching to admin has zero impact - CR " " // - CR "gta_patch_check_end:" ////// End of 'gta patch check' ////// - CR " " // - CR "gta_dll_check:" ////// Start of 'gta dll check' ////// - CR " CALL ProcessGtaDllCheck " // - CR " IF LastResult == ok GOTO gta_dll_end: " // - CR " IF LastResult == quit GOTO do_quit: " // - CR " " // - CR " CALL ChangeToAdmin " // If changes failed, try as admin - CR " IF LastResult == ok GOTO gta_dll_check: " // - CR " CALL Quit " // - CR " " // - CR "gta_dll_end: " ////// End of 'gta dll check' ////// - CR " " // - CR "gta_version_check:" ////// Start of 'gta version check' ////// - CR " CALL ProcessGtaVersionCheck " // - CR " IF LastResult == ok GOTO gta_version_end: " // - CR " IF LastResult == quit GOTO do_quit: " // - CR " " // - CR " CALL ChangeToAdmin " // If changes failed, try as admin - CR " IF LastResult == ok GOTO gta_version_check: " // - CR " CALL Quit " // - CR " " // - CR "gta_version_end: " ////// End of 'gta version check' ////// - CR " " // - CR "service_check: " ////// Start of 'Service checks' ////// - CR " CALL ProcessServiceChecks " // Make changes to comply with service requirements - CR " IF LastResult == ok GOTO service_end: " // - CR " " // - CR " CALL ChangeToAdmin " // If changes failed, try as admin - CR " IF LastResult == ok GOTO service_check: " // - CR " CALL Quit " // - CR " " // - CR "service_end: " ////// End of 'Service checks' ////// - CR " " // - CR "appcompat_check: " ////// Start of 'AppCompat checks' ////// - CR " CALL ProcessAppCompatChecks " // Make changes to comply with appcompat requirements - CR " IF LastResult == ok GOTO appcompat_end: " // - CR " " // - CR " CALL ChangeToAdmin " // If changes failed, try as admin - CR " IF LastResult == ok GOTO appcompat_check: " // - CR " CALL Quit " // - CR " " // - CR "appcompat_end: " ////// End of 'AppCompat checks' ////// - CR " " // - CR " CALL ChangeFromAdmin " // - CR " CALL InstallNewsItems " // Install pending news - CR " GOTO launch: " // - CR " " // - CR "do_quit: " // Quit ensuring termination of both user & admin instance - CR " CALL ChangeFromAdmin " // - CR " CALL Quit " // - CR " " // - CR "crashed: " // *** Starts here when restarting after crash - CR " CALL ShowCrashFailDialog " // - CR " IF LastResult == ok GOTO initial: " // - CR " CALL Quit " // - CR " " // +#define CR "\n" + SString strSource = CR "initial: " // *** Starts here by default + CR " CALL CheckOnRestartCommand " ////// Start of 'update game' ////// + CR " IF LastResult != ok GOTO update_end: " // + CR " " // + CR " CALL MaybeSwitchToTempExe " // If update files comes with an .exe, switch to that for the install + CR " " // + CR "copy_files: " // + CR " CALL InstallFiles " // Try to install update files + CR " IF LastResult == ok GOTO update_end: " // + CR " " // + CR " CALL ChangeToAdmin " // If install failed, try as admin + CR " " // + CR "copy_files_admin: " // + CR " CALL InstallFiles " // Try to install update files + CR " IF LastResult == ok GOTO update_end_admin: " // + CR " " // + CR " CALL ShowCopyFailDialog " // If install failed as admin, show message box + CR " IF LastResult == retry GOTO copy_files_admin: " // + CR " " // + CR "update_end_admin: " // + CR " CALL ChangeFromAdmin " // + CR " " // + CR "update_end: " ////// End of 'update game' ////// + CR " CALL SwitchBackFromTempExe " // + CR " " // + CR "newlayout_check:" ////// Start of 'new layout check' ////// + CR " CALL ProcessLayoutChecks " // + CR " IF LastResult == ok GOTO newlayout_end: " // + CR " " // + CR " CALL ChangeToAdmin " // If changes failed, try as admin + CR " IF LastResult == ok GOTO newlayout_check: " // + CR " CALL Quit " // + CR " " // + CR "newlayout_end: " ////// End of 'new layout check' ////// + CR " " // + CR "langfile_check: " ////// Start of 'Lang file fix' ////// + CR " CALL ProcessLangFileChecks " // Make changes to comply with requirements + CR " IF LastResult == ok GOTO langfile_end: " // + CR " " // + CR " CALL ChangeToAdmin " // If changes failed, try as admin + CR " IF LastResult == ok GOTO langfile_check: " // + CR " CALL Quit " // + CR " " // + CR "langfile_end: " ////// End of 'Lang file fix' ////// + CR " " // + CR "prepare_launch_location:" ////// Start of 'prepare launch location' ////// + CR " CALL PrepareLaunchLocation " // + CR " IF LastResult == ok GOTO prepare_launch_location_end: " // + CR " " // + CR " CALL ChangeToAdmin " // If changes failed, try as admin + CR " IF LastResult == ok GOTO prepare_launch_location: " // + CR " CALL Quit " // + CR " " // + CR "prepare_launch_location_end:" ////// End of 'prepare launch location' ////// + CR " " // + CR "gta_patch_check:" ////// Start of 'gta patch check' ////// + CR " CALL ProcessGtaPatchCheck " // + CR " IF LastResult != ok GOTO do_quit: " // Switching to admin has zero impact + CR " " // + CR "gta_patch_check_end:" ////// End of 'gta patch check' ////// + CR " " // + CR "gta_dll_check:" ////// Start of 'gta dll check' ////// + CR " CALL ProcessGtaDllCheck " // + CR " IF LastResult == ok GOTO gta_dll_end: " // + CR " IF LastResult == quit GOTO do_quit: " // + CR " " // + CR " CALL ChangeToAdmin " // If changes failed, try as admin + CR " IF LastResult == ok GOTO gta_dll_check: " // + CR " CALL Quit " // + CR " " // + CR "gta_dll_end: " ////// End of 'gta dll check' ////// + CR " " // + CR "gta_version_check:" ////// Start of 'gta version check' ////// + CR " CALL ProcessGtaVersionCheck " // + CR " IF LastResult == ok GOTO gta_version_end: " // + CR " IF LastResult == quit GOTO do_quit: " // + CR " " // + CR " CALL ChangeToAdmin " // If changes failed, try as admin + CR " IF LastResult == ok GOTO gta_version_check: " // + CR " CALL Quit " // + CR " " // + CR "gta_version_end: " ////// End of 'gta version check' ////// + CR " " // + CR "service_check: " ////// Start of 'Service checks' ////// + CR " CALL ProcessServiceChecks " // Make changes to comply with service requirements + CR " IF LastResult == ok GOTO service_end: " // + CR " " // + CR " CALL ChangeToAdmin " // If changes failed, try as admin + CR " IF LastResult == ok GOTO service_check: " // + CR " CALL Quit " // + CR " " // + CR "service_end: " ////// End of 'Service checks' ////// + CR " " // + CR "appcompat_check: " ////// Start of 'AppCompat checks' ////// + CR " CALL ProcessAppCompatChecks " // Make changes to comply with appcompat requirements + CR " IF LastResult == ok GOTO appcompat_end: " // + CR " " // + CR " CALL ChangeToAdmin " // If changes failed, try as admin + CR " IF LastResult == ok GOTO appcompat_check: " // + CR " CALL Quit " // + CR " " // + CR "appcompat_end: " ////// End of 'AppCompat checks' ////// + CR " " // + CR " CALL ChangeFromAdmin " // + CR " CALL InstallNewsItems " // Install pending news + CR " CALL CheckForWerCrash " // Check for fail-fast crashes detected by WER + CR " IF LastResult == crashed GOTO crashed: " // WER crash detected -> show dialog + CR " GOTO launch: " // + CR " " // + CR "do_quit: " // Quit ensuring termination of both user & admin instance + CR " CALL ChangeFromAdmin " // + CR " CALL Quit " // + CR " " // + CR "crashed: " // *** Starts here when install_stage=crashed is passed + CR " CALL ShowCrashFailDialog " // Shows immediate crash dialog from fresh launcher process + CR " IF LastResult == ok GOTO initial: " // User clicked "Yes" to restart -> go to normal launch + CR " CALL Quit " // User clicked "No" -> exit launcher + // + // Flow when game crashes: + // 1. core.dll crash handler saves crash info to settings + // 2. core.dll launches "Multi Theft Auto.exe install_stage=crashed" (bypasses mutex) + // 3. New launcher lands HERE at "crashed:" label + // 4. Shows dialog with crash info from settings + // 5. User chooses restart or quit + CR " " // CR "launch: "; m_pSequencer = new CSequencerType(); m_pSequencer->SetSource(this, strSource); m_pSequencer->AddFunction("ShowCrashFailDialog", &CInstallManager::_ShowCrashFailDialog); + m_pSequencer->AddFunction("CheckForWerCrash", &CInstallManager::_CheckForWerCrash); m_pSequencer->AddFunction("CheckOnRestartCommand", &CInstallManager::_CheckOnRestartCommand); m_pSequencer->AddFunction("MaybeSwitchToTempExe", &CInstallManager::_MaybeSwitchToTempExe); m_pSequencer->AddFunction("SwitchBackFromTempExe", &CInstallManager::_SwitchBackFromTempExe); @@ -256,7 +328,7 @@ SString CInstallManager::Continue() { // Initial report line DWORD dwProcessId = GetCurrentProcessId(); - SString GotPathFrom = (m_pSequencer->GetVariable(INSTALL_LOCATION) == "far") ? "registry" : "module location"; + SString GotPathFrom = (m_pSequencer->GetVariable(INSTALL_LOCATION) == "far") ? "far-update resolver" : "module location"; AddReportLog(1041, SString("* Launch * pid:%d '%s' MTASAPath set from %s '%s'", dwProcessId, GetLaunchPathFilename().c_str(), GotPathFrom.c_str(), GetMTASAPath().c_str())); @@ -370,7 +442,7 @@ SString CInstallManager::_ChangeToAdmin() UpdateSettingsForReportLog(); RestoreSequencerFromSnapshot(ReceiveStringFromAdminProcess()); ClearIsBlockingUserProcess(); - return "ok"; // This will appear as the result for _ChangeFromAdmin + return "ok"; // This will appear as the result for _ChangeFromAdmin } CreateSingleInstanceMutex(); ClearIsBlockingUserProcess(); @@ -406,8 +478,19 @@ SString CInstallManager::_ChangeFromAdmin() // // ////////////////////////////////////////////////////////// +// ============================================================================ +// ShowCrashFailDialog - Display crash dialog in fresh launcher process +// ============================================================================ +// This function runs in a NEWLY LAUNCHED launcher instance, NOT the crashed game. +// The crashed core.dll saved crash info to application settings, and we read it here. +// +// Called when: Launcher starts with "install_stage=crashed" argument +// See: CCrashDumpWriter::RunErrorTool() which launches us +// ============================================================================ SString CInstallManager::_ShowCrashFailDialog() { + WriteDebugEvent("[7208] CInstallManager - _ShowCrashFailDialog called"); + // Crashed before gta game started ? if (WatchDogIsSectionOpen("L1")) WatchDogIncCounter("CR1"); @@ -423,6 +506,13 @@ SString CInstallManager::_ShowCrashFailDialog() SetApplicationSetting("diagnostics", "last-crash-reason", ""); SString strMessage = GetApplicationSetting("diagnostics", "last-crash-info"); + SetApplicationSetting("diagnostics", "last-crash-info", ""); + + const int exceptionCode = GetApplicationSettingInt("diagnostics", "last-crash-code"); + SetApplicationSetting("diagnostics", "last-crash-code", ""); + + const bool debuggerCapturePending = (GetApplicationSetting("diagnostics", "debugger-crash-capture") == "1"); + if (strReason == "direct3ddevice-reset") { strMessage += _("** The crash was caused by a graphics driver error **\n\n** Please update your graphics drivers **"); @@ -432,24 +522,487 @@ SString CInstallManager::_ShowCrashFailDialog() strMessage += strReason; } - const SString moduleName = GetApplicationSetting("diagnostics", "last-crash-module"); - const int exceptionCode = GetApplicationSettingInt("diagnostics", "last-crash-code"); - - if (exceptionCode == CUSTOM_EXCEPTION_CODE_OOM && moduleName.EndsWithI("\\kernelbase.dll")) + if (exceptionCode == CUSTOM_EXCEPTION_CODE_OOM) { strMessage += '\n'; strMessage += _("** Out of memory - this crash was caused by insufficient free or fragmented memory. **"); } + if (debuggerCapturePending) + { + strMessage += "\n\n"; + strMessage += _("** Enhanced crash capture will be attempted on next launch. **"); + } + strMessage = strMessage.Replace("\r", "").Replace("\n", "\r\n"); SString strResult = ShowCrashedDialog(g_hInstance, strMessage); HideCrashedDialog(); + // Show OOM-specific information message box after crash dialog closes + if (exceptionCode == CUSTOM_EXCEPTION_CODE_OOM) + { + ShowOOMMessageBox(g_hInstance); + } + CheckAndShowFileOpenFailureMessage(); + if (debuggerCapturePending) + { + AddReportLog(7205, "Crash dialog shown with debugger capture pending - proceeding to launch regardless of user choice"); + return "ok"; + } + return strResult; } +////////////////////////////////////////////////////////// +// +// CInstallManager::_CheckForWerCrash +// +// Check if a WER-generated crash dump exists from a fail-fast crash +// that bypassed our normal crash handler (e.g., stack buffer overrun). +// This detection runs here because PreLaunchWatchDogs() is called AFTER +// the sequencer runs, so we need to detect WER dumps inline. +// +////////////////////////////////////////////////////////// + +namespace +{ + constexpr DWORD EXCEPTION_STACK_BUFFER_OVERRUN = 0xC0000409; + constexpr DWORD EXCEPTION_HEAP_CORRUPTION = 0xC0000374; + + [[nodiscard]] bool IsFileRecentEnough(HANDLE hFile) noexcept + { + return WerCrash::IsFileRecentEnough(hFile); + } +} + +SString CInstallManager::_CheckForWerCrash() +{ + WriteDebugEvent("[7209] _CheckForWerCrash called"); + OutputDebugStringA("_CheckForWerCrash: Starting WER crash detection\n"); + + static bool bWerCrashAlreadyHandled = false; + if (bWerCrashAlreadyHandled) + { + OutputDebugStringA("_CheckForWerCrash: Already handled a WER crash this session, skipping\n"); + return "ok"; + } + + const SString existingReason = GetApplicationSetting("diagnostics", "last-crash-reason"); + const DWORD existingCode = static_cast(GetApplicationSettingInt("diagnostics", "last-crash-code")); + + if ((existingCode == EXCEPTION_STACK_BUFFER_OVERRUN || existingCode == EXCEPTION_HEAP_CORRUPTION) && !existingReason.empty()) + { + OutputDebugStringA(SString("_CheckForWerCrash: Already have crash info, code=0x%08X\n", existingCode)); + bWerCrashAlreadyHandled = true; + return "crashed"; + } + + const SString werDumpPath = CalcMTASAPath("mta\\dumps\\private"); + const SString lastShownDump = GetApplicationSetting("diagnostics", "last-wer-dump-shown"); + + OutputDebugStringA(SString("_CheckForWerCrash: Checking dump path: %s\n", werDumpPath.c_str())); + + auto dumpFiles = FindFiles(PathJoin(werDumpPath, "failfast_*.dmp"), true, false, true); + OutputDebugStringA(SString("_CheckForWerCrash: Found %zu fail-fast dump files\n", dumpFiles.size())); + + for (auto it = dumpFiles.rbegin(); it != dumpFiles.rend(); ++it) + { + const auto& dumpFile = *it; + + if (dumpFile == lastShownDump) + break; + + const SString fullPath = PathJoin(werDumpPath, dumpFile); + HANDLE hFile = CreateFileA(fullPath, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + + if (hFile == INVALID_HANDLE_VALUE) + break; + + const bool isRecent = IsFileRecentEnough(hFile); + CloseHandle(hFile); + + if (isRecent) + { + const auto regs = WerCrash::ExtractRegistersFromMinidump(fullPath); + const DWORD exceptionCode = regs.valid ? regs.exceptionCode : EXCEPTION_STACK_BUFFER_OVERRUN; + const char* exceptionName = (exceptionCode == EXCEPTION_STACK_BUFFER_OVERRUN) ? "Stack Buffer Overrun" + : (exceptionCode == EXCEPTION_HEAP_CORRUPTION) ? "Heap Corruption" + : "Security Exception"; + + SString moduleName = "unknown"; + DWORD moduleOffset = 0; + DWORD idaAddress = 0; + if (regs.valid) + { + const auto resolved = WerCrash::ResolveAddressFromMinidump(fullPath, regs.eip); + if (resolved.resolved) + { + moduleName = resolved.moduleName; + moduleOffset = resolved.rva; + idaAddress = resolved.idaAddress; + } + } + SString idaAddressStr; + if (idaAddress == 0) + idaAddressStr = "unknown"; + else + idaAddressStr = SString("0x%08X", idaAddress); + + SString renamedDumpPath; + if (regs.valid) + renamedDumpPath = WerCrash::RenameWerDumpToMtaFormat(fullPath, werDumpPath, moduleName, moduleOffset, exceptionCode, regs); + + const SString usedDumpPath = renamedDumpPath.empty() ? fullPath : renamedDumpPath; + + SString stackTrace; + if (regs.valid) + stackTrace = WerCrash::ExtractStackTraceFromMinidump(usedDumpPath, regs); + + SYSTEMTIME st{}; + GetLocalTime(&st); + + const auto strMTAVersionFull = SString("%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting("mta-version-ext").SplitRight(".", nullptr, -2)); + + const SString crashReason = SString( + "Security Exception - %s (0x%08X) detected.\n" + "Module: %s\n" + "Offset: 0x%08X\n" + "IDA Address: %s\n" + "This crash bypassed normal crash handling.\n" + "Crash dump: %s", + exceptionName, exceptionCode, moduleName.c_str(), moduleOffset, idaAddressStr.c_str(), ExtractFilename(usedDumpPath).c_str()); + + SString coreLogEntry; + coreLogEntry += SString("Version = %s\n", strMTAVersionFull.c_str()); + coreLogEntry += SString("Time = %04d-%02d-%02d %02d:%02d:%02d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + coreLogEntry += SString("Module = %s\n", moduleName.c_str()); + coreLogEntry += SString("Code = 0x%08X (%s)\n", exceptionCode, exceptionName); + coreLogEntry += SString("Offset = 0x%08X\n", moduleOffset); + coreLogEntry += SString("IDA-friendly Offset = %s\n\n", idaAddressStr.c_str()); + + if (regs.valid) + { + coreLogEntry += SString( + "EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESI=%08X\n" + "EDI=%08X EBP=%08X ESP=%08X EIP=%08X FLG=%08X\n" + "CS=%04X DS=%04X SS=%04X ES=%04X FS=%04X GS=%04X\n\n", + regs.eax, regs.ebx, regs.ecx, regs.edx, regs.esi, regs.edi, regs.ebp, regs.esp, regs.eip, regs.eflags, regs.cs, regs.ds, regs.ss, regs.es, + regs.fs, regs.gs); + } + + if (!stackTrace.empty()) + { + coreLogEntry += "Stack trace:\n"; + coreLogEntry += stackTrace; + coreLogEntry += "\n"; + } + + coreLogEntry += "Source: Debugger capture (fail-fast exception)\n"; + coreLogEntry += SString("Dump: %s\n", ExtractFilename(usedDumpPath).c_str()); + + SetApplicationSetting("diagnostics", "last-crash-reason", crashReason); + SetApplicationSetting("diagnostics", "last-crash-info", coreLogEntry); + SetApplicationSettingInt("diagnostics", "last-crash-code", exceptionCode); + SetApplicationSetting("diagnostics", "last-wer-dump-shown", dumpFile); + + if (!renamedDumpPath.empty()) + { + SetApplicationSetting("diagnostics", "last-dump-save", renamedDumpPath); + SetApplicationSetting("diagnostics", "last-dump-complete", "1"); + WriteDebugEvent(SString("Failfast crash dump queued for upload: %s", ExtractFilename(renamedDumpPath).c_str())); + } + + FILE* pFile = File::Fopen(CalcMTASAPath("mta\\core.log"), "a"); + if (pFile) + { + fprintf(pFile, "%s", "** -- Unhandled exception -- **\n\n"); + fprintf(pFile, "%s", coreLogEntry.c_str()); + fprintf(pFile, "%s", "** -- End of unhandled exception -- **\n\n\n"); + fclose(pFile); + } + + WerCrashInfo werInfoForMarking = QueryWerCrashInfo(); + if (!werInfoForMarking.reportId.empty()) + SetApplicationSetting("diagnostics", "last-wer-report-shown", werInfoForMarking.reportId); + + OutputDebugStringA(SString("_CheckForWerCrash: Found recent fail-fast dump: %s\n", dumpFile.c_str())); + bWerCrashAlreadyHandled = true; + return "crashed"; + } + break; + } + + const SString lastShownReport = GetApplicationSetting("diagnostics", "last-wer-report-shown"); + + WerCrashInfo werInfo = QueryWerCrashInfo(); + + if (!werInfo.found) + { + OutputDebugStringA("_CheckForWerCrash: No WER report in ReportArchive, checking for WER dump files directly\n"); + + auto werDumpFiles = FindFiles(PathJoin(werDumpPath, "gta_sa.exe.*.dmp"), true, false, true); + OutputDebugStringA(SString("_CheckForWerCrash: Found %zu gta_sa.exe.*.dmp files\n", werDumpFiles.size())); + + for (auto it = werDumpFiles.rbegin(); it != werDumpFiles.rend(); ++it) + { + const auto& dumpFile = *it; + + if (dumpFile == lastShownDump) + { + OutputDebugStringA(SString("_CheckForWerCrash: Already shown WER dump %s, skipping\n", dumpFile.c_str())); + break; + } + + const SString fullPath = PathJoin(werDumpPath, dumpFile); + HANDLE hFile = CreateFileA(fullPath, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + + if (hFile == INVALID_HANDLE_VALUE) + { + OutputDebugStringA(SString("_CheckForWerCrash: Cannot open %s (error %lu), stopping\n", dumpFile.c_str(), GetLastError())); + break; + } + + const bool isRecent = IsFileRecentEnough(hFile); + CloseHandle(hFile); + + if (isRecent) + { + OutputDebugStringA(SString("_CheckForWerCrash: Processing WER dump file directly: %s\n", dumpFile.c_str())); + + const auto regs = WerCrash::ExtractRegistersFromMinidump(fullPath); + const DWORD exceptionCode = regs.valid ? regs.exceptionCode : EXCEPTION_STACK_BUFFER_OVERRUN; + const char* exceptionName = (exceptionCode == EXCEPTION_STACK_BUFFER_OVERRUN) ? "Stack Buffer Overrun" + : (exceptionCode == EXCEPTION_HEAP_CORRUPTION) ? "Heap Corruption" + : "Security Exception"; + + SString moduleName = "unknown"; + DWORD moduleOffset = 0; + DWORD idaAddress = 0; + if (regs.valid) + { + const auto resolved = WerCrash::ResolveAddressFromMinidump(fullPath, regs.eip); + if (resolved.resolved) + { + moduleName = resolved.moduleName; + moduleOffset = resolved.rva; + idaAddress = resolved.idaAddress; + } + } + SString idaAddressStr; + if (idaAddress == 0) + idaAddressStr = "unknown"; + else + idaAddressStr = SString("0x%08X", idaAddress); + + SString renamedDumpPath; + if (regs.valid) + renamedDumpPath = WerCrash::RenameWerDumpToMtaFormat(fullPath, werDumpPath, moduleName, moduleOffset, exceptionCode, regs); + + const SString usedDumpPath = renamedDumpPath.empty() ? fullPath : renamedDumpPath; + + SString stackTrace; + if (regs.valid) + stackTrace = WerCrash::ExtractStackTraceFromMinidump(usedDumpPath, regs); + + SYSTEMTIME st{}; + GetLocalTime(&st); + + const auto strMTAVersionFull = SString("%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting("mta-version-ext").SplitRight(".", nullptr, -2)); + + const SString crashReason = SString( + "Security Exception - %s (0x%08X) detected.\n" + "Module: %s\n" + "Offset: 0x%08X\n" + "IDA Address: %s\n" + "This crash bypassed normal crash handling.\n" + "Crash dump: %s", + exceptionName, exceptionCode, moduleName.c_str(), moduleOffset, idaAddressStr.c_str(), ExtractFilename(usedDumpPath).c_str()); + + SString coreLogEntry; + coreLogEntry += SString("Version = %s\n", strMTAVersionFull.c_str()); + coreLogEntry += SString("Time = %04d-%02d-%02d %02d:%02d:%02d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + coreLogEntry += SString("Module = %s\n", moduleName.c_str()); + coreLogEntry += SString("Code = 0x%08X (%s)\n", exceptionCode, exceptionName); + coreLogEntry += SString("Offset = 0x%08X\n", moduleOffset); + coreLogEntry += SString("IDA-friendly Offset = %s\n\n", idaAddressStr.c_str()); + + if (regs.valid) + { + coreLogEntry += SString( + "EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESI=%08X\n" + "EDI=%08X EBP=%08X ESP=%08X EIP=%08X FLG=%08X\n" + "CS=%04X DS=%04X SS=%04X ES=%04X FS=%04X GS=%04X\n\n", + regs.eax, regs.ebx, regs.ecx, regs.edx, regs.esi, regs.edi, regs.ebp, regs.esp, regs.eip, regs.eflags, regs.cs, regs.ds, regs.ss, + regs.es, regs.fs, regs.gs); + } + + if (!stackTrace.empty()) + { + coreLogEntry += "Stack trace:\n"; + coreLogEntry += stackTrace; + coreLogEntry += "\n"; + } + + coreLogEntry += "Source: WER dump file (direct detection)\n"; + coreLogEntry += SString("Dump: %s\n", ExtractFilename(usedDumpPath).c_str()); + + SetApplicationSetting("diagnostics", "last-crash-reason", crashReason); + SetApplicationSetting("diagnostics", "last-crash-info", coreLogEntry); + SetApplicationSettingInt("diagnostics", "last-crash-code", exceptionCode); + SetApplicationSetting("diagnostics", "last-wer-dump-shown", dumpFile); + + if (!renamedDumpPath.empty()) + { + SetApplicationSetting("diagnostics", "last-dump-save", renamedDumpPath); + SetApplicationSetting("diagnostics", "last-dump-complete", "1"); + WriteDebugEvent(SString("WER dump (direct) queued for upload: %s", ExtractFilename(renamedDumpPath).c_str())); + } + + FILE* pFile = File::Fopen(CalcMTASAPath("mta\\core.log"), "a"); + if (pFile) + { + fprintf(pFile, "%s", "** -- Unhandled exception -- **\n\n"); + fprintf(pFile, "%s", coreLogEntry.c_str()); + fprintf(pFile, "%s", "** -- End of unhandled exception -- **\n\n\n"); + fclose(pFile); + } + + OutputDebugStringA(SString("_CheckForWerCrash: Detected WER dump directly: %s\n", dumpFile.c_str())); + bWerCrashAlreadyHandled = true; + return "crashed"; + } + break; + } + + OutputDebugStringA("_CheckForWerCrash: No recent WER crash found (neither ReportArchive nor direct dump)\n"); + return "ok"; + } + + if (!werInfo.reportId.empty() && werInfo.reportId == lastShownReport) + { + OutputDebugStringA(SString("_CheckForWerCrash: Already shown report %s, skipping\n", werInfo.reportId.c_str())); + return "ok"; + } + + const char* exceptionName = (werInfo.exceptionCode == EXCEPTION_STACK_BUFFER_OVERRUN) ? "Stack Buffer Overrun" + : (werInfo.exceptionCode == EXCEPTION_HEAP_CORRUPTION) ? "Heap Corruption" + : "Security Exception"; + + OutputDebugStringA(SString("_CheckForWerCrash: DETECTED! code=0x%08X module=%s offset=%s\n", werInfo.exceptionCode, werInfo.moduleName.c_str(), + werInfo.faultOffset.c_str())); + + DWORD offsetValue = 0; + SString offsetStr; + if (!werInfo.faultOffset.empty()) + { + offsetStr = werInfo.faultOffset; + offsetStr.Replace("0x", ""); + offsetStr.Replace("0X", ""); + offsetValue = static_cast(strtoull(offsetStr.c_str(), nullptr, 16)); + } + + SString offsetText; + if (offsetStr.empty()) + offsetText = "unknown"; + else + offsetText = SString("0x%s", offsetStr.c_str()); + + constexpr DWORD IDA_DEFAULT_DLL_BASE = 0x10000000; + const DWORD idaAddress = IDA_DEFAULT_DLL_BASE + offsetValue; + SString idaAddressStr; + if (offsetValue == 0) + idaAddressStr = "unknown"; + else + idaAddressStr = SString("0x%08X", idaAddress); + + const auto dumpResult = WerCrash::FindAndRenameWerDump(werDumpPath, werInfo.moduleName, offsetValue, werInfo.exceptionCode, std::nullopt); + if (!dumpResult.path.empty()) + { + SetApplicationSetting("diagnostics", "last-dump-save", dumpResult.path); + SetApplicationSetting("diagnostics", "last-dump-complete", "1"); + WriteDebugEvent(SString("WER crash dump queued for upload: %s", ExtractFilename(dumpResult.path).c_str())); + } + + if (!dumpResult.sourceFilename.empty()) + SetApplicationSetting("diagnostics", "last-wer-dump-shown", dumpResult.sourceFilename); + + const SString crashReason = dumpResult.path.empty() + ? SString( + "Security Exception - %s (0x%08X) detected.\n" + "Module: %s\n" + "Offset: %s\n" + "IDA Address: %s (assuming default DLL base 0x10000000)\n" + "This crash bypassed normal crash handling.", + exceptionName, werInfo.exceptionCode, werInfo.moduleName.empty() ? "unknown" : werInfo.moduleName.c_str(), + offsetText.c_str(), idaAddressStr.c_str()) + : SString( + "Security Exception - %s (0x%08X) detected.\n" + "Module: %s\n" + "Offset: %s\n" + "IDA Address: %s (assuming default DLL base 0x10000000)\n" + "Crash dump: %s", + exceptionName, werInfo.exceptionCode, werInfo.moduleName.empty() ? "unknown" : werInfo.moduleName.c_str(), + offsetText.c_str(), idaAddressStr.c_str(), ExtractFilename(dumpResult.path).c_str()); + + SYSTEMTIME st{}; + GetLocalTime(&st); + + const auto strMTAVersionFull = SString("%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting("mta-version-ext").SplitRight(".", nullptr, -2)); + + SString coreLogEntry; + coreLogEntry += SString("Version = %s\n", strMTAVersionFull.c_str()); + coreLogEntry += SString("Time = %04d-%02d-%02d %02d:%02d:%02d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + coreLogEntry += SString("Module = %s\n", werInfo.moduleName.empty() ? "unknown" : werInfo.moduleName.c_str()); + coreLogEntry += SString("Code = 0x%08X (%s)\n", werInfo.exceptionCode, exceptionName); + coreLogEntry += SString("Offset = %s\n", offsetText.c_str()); + coreLogEntry += SString("IDA Address = %s\n\n", idaAddressStr.c_str()); + + if (dumpResult.regs.valid) + { + coreLogEntry += SString( + "EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESI=%08X\n" + "EDI=%08X EBP=%08X ESP=%08X EIP=%08X FLG=%08X\n" + "CS=%04X DS=%04X SS=%04X ES=%04X FS=%04X GS=%04X\n\n", + dumpResult.regs.eax, dumpResult.regs.ebx, dumpResult.regs.ecx, dumpResult.regs.edx, dumpResult.regs.esi, dumpResult.regs.edi, dumpResult.regs.ebp, + dumpResult.regs.esp, dumpResult.regs.eip, dumpResult.regs.eflags, dumpResult.regs.cs, dumpResult.regs.ds, dumpResult.regs.ss, dumpResult.regs.es, + dumpResult.regs.fs, dumpResult.regs.gs); + } + + if (!dumpResult.stackTrace.empty()) + { + coreLogEntry += "Stack trace:\n"; + coreLogEntry += dumpResult.stackTrace; + coreLogEntry += "\n"; + } + + coreLogEntry += "Source: Windows Error Reporting (fail-fast exception)\n"; + if (!dumpResult.path.empty()) + coreLogEntry += SString("Dump: %s\n", ExtractFilename(dumpResult.path).c_str()); + + FILE* pFile = File::Fopen(CalcMTASAPath("mta\\core.log"), "a"); + if (pFile) + { + fprintf(pFile, "%s", "** -- Unhandled exception -- **\n\n"); + fprintf(pFile, "%s", coreLogEntry.c_str()); + fprintf(pFile, "%s", "** -- End of unhandled exception -- **\n\n\n"); + fclose(pFile); + } + + SetApplicationSetting("diagnostics", "last-crash-reason", crashReason); + SetApplicationSetting("diagnostics", "last-crash-info", coreLogEntry); + SetApplicationSettingInt("diagnostics", "last-crash-code", werInfo.exceptionCode); + + if (!werInfo.reportId.empty()) + { + SetApplicationSetting("diagnostics", "last-wer-report-shown", werInfo.reportId); + } + + bWerCrashAlreadyHandled = true; + return "crashed"; +} + ////////////////////////////////////////////////////////// // // CInstallManager::_CheckOnRestartCommand @@ -491,7 +1044,7 @@ SString CInstallManager::_MaybeSwitchToTempExe() { ReleaseSingleInstanceMutex(); if (ShellExecuteNonBlocking("open", GetLauncherPathFilename(), GetSequencerSnapshot())) - ExitProcess(0); // All done here + ExitProcess(0); // All done here CreateSingleInstanceMutex(); return "fail"; } @@ -512,10 +1065,22 @@ SString CInstallManager::_SwitchBackFromTempExe() { m_pSequencer->SetVariable(INSTALL_LOCATION, "near"); + SString strLauncherPathFilename = PathJoin(GetInstallPathForLauncher(), MTA_EXE_NAME); + if (!FileExists(strLauncherPathFilename)) + { + strLauncherPathFilename = PathJoin(GetMTASAPath(), MTA_EXE_NAME); + if (!FileExists(strLauncherPathFilename)) + { + AddReportLog(5055, SString("_SwitchBackFromTempExe: target launcher missing '%s'", strLauncherPathFilename.c_str())); + return "fail"; + } + } + ReleaseSingleInstanceMutex(); - if (ShellExecuteNonBlocking("open", GetLauncherPathFilename(), GetSequencerSnapshot())) - ExitProcess(0); // All done here + if (ShellExecuteNonBlocking("open", strLauncherPathFilename, GetSequencerSnapshot())) + ExitProcess(0); // All done here CreateSingleInstanceMutex(); + AddReportLog(5055, SString("_SwitchBackFromTempExe: failed to launch '%s'", strLauncherPathFilename.c_str())); return "fail"; } return "ok"; @@ -545,6 +1110,7 @@ SString CInstallManager::_InstallFiles() } else { + SetOnRestartCommand(""); UpdateMTAVersionApplicationSetting(); AddReportLog(2050, SString("_InstallFiles: ok %s", "")); return "ok"; @@ -602,31 +1168,6 @@ SString CInstallManager::_PrepareLaunchLocation() const fs::path mtaDir = GetMTARootDirectory() / "MTA"; const fs::path launchDir = GetGameLaunchDirectory(); -#if 0 - // NOTE(botder): We are not using this solution because creating directory junctions requires administrator privileges. - // Create GTA subdirectory junctions to our launch directory. - for (const char* directoryName : {"anim", "audio", "data", "models", "text"}) - { - // Delete shortcuts that may be confusing to the eye. - const fs::path shortcutPath = (launchDir / directoryName).replace_extension(".lnk"); - - if (std::error_code ec; fs::exists(shortcutPath, ec)) - { - if (!fs::remove(shortcutPath, ec)) - { - OutputDebugLine(*SString("Failed to remove shortcut for %s (%d, %s)", directoryName, ec.value(), ec.message().c_str())); - } - } - - if (std::error_code ec; !SetDirectoryJunction(gtaDir / directoryName, launchDir / directoryName, ec)) - { - OutputDebugLine(*SString("Failed to create junction for %s (%d, %s)", directoryName, ec.value(), ec.message().c_str())); - m_strAdminReason = _("Create GTA:SA junctions"); - return "fail"; - } - } -#endif - // Copy GTA dependencies to our launch directory. for (const char* fileName : {"eax.dll", "ogg.dll", "vorbis.dll", "vorbisFile.dll"}) { @@ -646,7 +1187,11 @@ SString CInstallManager::_PrepareLaunchLocation() } // Copy MTA dependencies to our launch directory. +#ifdef MTA_MAETRO + for (const char* fileName : {LOADER_PROXY_DLL_NAME, MAETRO32_DLL_NAME}) +#else for (const char* fileName : {LOADER_PROXY_DLL_NAME}) +#endif { const fs::path sourcePath = mtaDir / fileName; const fs::path targetPath = launchDir / fileName; @@ -666,13 +1211,13 @@ SString CInstallManager::_PrepareLaunchLocation() if (fs::is_regular_file(sourcePath, ec)) { SString strMessage(_("MTA:SA cannot launch because copying a file failed:")); - strMessage += "\n\n" + targetPath.u8string(); + strMessage += "\n\n" + UTF8FilePath(targetPath); BrowseToSolution("copy-files", ASK_GO_ONLINE, strMessage); } else { SString strMessage(_("MTA:SA cannot launch because an MTA:SA file is incorrect or missing:")); - strMessage += "\n\n" + sourcePath.u8string(); + strMessage += "\n\n" + UTF8FilePath(sourcePath); BrowseToSolution("mta-datafiles-missing", ASK_GO_ONLINE, strMessage); } @@ -703,16 +1248,18 @@ SString CInstallManager::_ProcessGtaPatchCheck() if (!FileGenerator::IsPatchBase(patchBasePath)) { + AddReportLog(5053, SString("_ProcessGtaPatchCheck: patch base invalid '%ls'", patchBasePath.wstring().c_str())); SString strMessage(_("MTA:SA cannot launch because a GTA:SA file is incorrect or missing:")); - strMessage += "\n\n" + patchBasePath.u8string(); + strMessage += "\n\n" + UTF8FilePath(patchBasePath); BrowseToSolution("gengta_pakfiles", ASK_GO_ONLINE, strMessage); return "quit"; } if (!FileGenerator::IsPatchDiff(patchDiffPath)) { + AddReportLog(5053, SString("_ProcessGtaPatchCheck: patch diff invalid '%ls'", patchDiffPath.wstring().c_str())); SString strMessage(_("MTA:SA cannot launch because an MTA:SA file is incorrect or missing:")); - strMessage += "\n\n" + patchDiffPath.u8string(); + strMessage += "\n\n" + UTF8FilePath(patchDiffPath); BrowseToSolution("mta-datafiles-missing", ASK_GO_ONLINE, strMessage); return "quit"; } @@ -782,7 +1329,7 @@ SString CInstallManager::_ProcessGtaDllCheck() if (isAdmin) { SString strMessage(_("MTA:SA cannot launch because a GTA:SA file is incorrect or missing:")); - strMessage += "\n\n" + dependecyPath.u8string(); + strMessage += "\n\n" + UTF8FilePath(dependecyPath); BrowseToSolution(SString("gendep_error&name=%s", dependency.fileName), ASK_GO_ONLINE, strMessage); return "quit"; } @@ -837,7 +1384,7 @@ SString CInstallManager::_ProcessGtaVersionCheck() if (isAdmin) { SString strMessage(_("MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:")); - strMessage += "\n\n" + gtaExePath.u8string(); + strMessage += "\n\n" + UTF8FilePath(gtaExePath); strMessage += "\n\n" + _("Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA."); @@ -862,7 +1409,7 @@ SString CInstallManager::_ProcessGtaVersionCheck() if (isAdmin) { SString strMessage(_("MTA:SA cannot launch because the GTA:SA executable is not loadable:")); - strMessage += "\n\n" + gtaExePath.u8string(); + strMessage += "\n\n" + UTF8FilePath(gtaExePath); BrowseToSolution(SString("gengta_error&code=%d", ec.value()), ASK_GO_ONLINE, strMessage); return "quit"; } @@ -885,7 +1432,7 @@ SString CInstallManager::_ProcessGtaVersionCheck() if (isAdmin) { SString strMessage(_("MTA:SA cannot launch because patching GTA:SA has failed:")); - strMessage += "\n\n" + gtaExePath.u8string(); + strMessage += "\n\n" + UTF8FilePath(gtaExePath); BrowseToSolution(SString("patchgta_error&code=%d", ec.value()), ASK_GO_ONLINE, strMessage); return "quit"; } @@ -932,7 +1479,7 @@ SString CInstallManager::_ProcessLayoutChecks() SString strMTADataPath = i ? GetMTADataPathCommon() : GetMTADataPath(); if (!DirectoryExists(strMTADataPath)) - ShowLayoutError("[Data directory not present]"); // Can't find directory + ShowLayoutError("[Data directory not present]"); // Can't find directory SString strTestFilePath = PathJoin(strMTADataPath, "testdir", "testfile.txt"); @@ -941,7 +1488,7 @@ SString CInstallManager::_ProcessLayoutChecks() SString strContent = "test"; if (!FileSave(strTestFilePath, strContent)) - ShowLayoutError("[Data directory not writable]"); // Can't save file + ShowLayoutError("[Data directory not writable]"); // Can't save file FileDelete(strTestFilePath); RemoveDirectory(ExtractPath(strTestFilePath)); @@ -951,7 +1498,7 @@ SString CInstallManager::_ProcessLayoutChecks() // Check reg key exists { if (GetRegistryValue("", "Last Install Location").empty()) - ShowLayoutError("[Registry key not present]"); // Can't find reg key + ShowLayoutError("[Registry key not present]"); // Can't find reg key } #endif @@ -963,7 +1510,7 @@ SString CInstallManager::_ProcessLayoutChecks() SetRegistryValue("testkeypath", "testname", strValue); SString strValueCheck = GetRegistryValue("testkeypath", "testname"); if (strValueCheck != strValue) - ShowLayoutError("[Registry key not writable]"); // Can't write reg key + ShowLayoutError("[Registry key not writable]"); // Can't write reg key RemoveRegistryKey("testkeypath"); } @@ -976,7 +1523,7 @@ SString CInstallManager::_ProcessLayoutChecks() SString strContent = "test"; if (!FileSave(strTestFilePath, strContent)) - ShowLayoutError("[Install directory not writable]"); // Can't save file + ShowLayoutError("[Install directory not writable]"); // Can't save file FileDelete(strTestFilePath); } @@ -1176,11 +1723,11 @@ SString CInstallManager::_ProcessServiceChecks() ////////////////////////////////////////////////////////// SString CInstallManager::_ProcessAppCompatChecks() { - BOOL bIsWOW64 = false; // 64bit OS + BOOL bIsWOW64 = false; // 64bit OS IsWow64Process(GetCurrentProcess(), &bIsWOW64); uint uiHKLMFlags = bIsWOW64 ? KEY_WOW64_64KEY : 0; WString strGTAExePathFilename = GetGameExecutablePath().wstring(); - WString strMTAExePathFilename = FromUTF8(GetLaunchPathFilename()); + WString strMTAExePathFilename = FromUTF8(PathJoin(GetInstallPathForLauncher(), MTA_EXE_NAME)); WString strCompatModeRegKey = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"; int bWin816BitColorOption = GetApplicationSettingInt("Win8Color16"); int bWin8MouseOption = GetApplicationSettingInt("Win8MouseFix"); @@ -1258,13 +1805,15 @@ SString CInstallManager::_ProcessAppCompatChecks() strValue.Split(" ", entryList); ListRemove(entryList, WString()); - // Apply removals + std::vector originalEntries = entryList; + + // Apply removals (case-insensitive) for (uint a = 0; a < removeList.size(); a++) - ListRemove(entryList, removeList[a]); + AppCompatListRemove(entryList, removeList[a]); - // Apply adds + // Apply adds (case-insensitive) for (uint a = 0; a < addList.size(); a++) - ListAddUnique(entryList, addList[a]); + AppCompatListAddUnique(entryList, addList[a]); // Clear list if only flags remain if (entryList.size() == 1 && entryList[0].size() < 3) @@ -1273,8 +1822,8 @@ SString CInstallManager::_ProcessAppCompatChecks() // Join to one value WString strNewValue = WString::Join(L" ", entryList); - // Save setting - if (strNewValue != strValue) + // Write only if entries actually changed + if (!AreAppCompatEntriesEqual(entryList, originalEntries)) if (!WriteCompatibilityEntries(items[i].strProgName, strCompatModeRegKey, items[i].hKeyRoot, items[i].uiFlags, strNewValue)) bTryAdmin = true; } @@ -1289,7 +1838,7 @@ SString CInstallManager::_ProcessAppCompatChecks() WriteDebugEvent(SString("GameUX ServiceLocation was '%s'", *ToUTF8(strUrlValue))); if (strUrlValue.ContainsI(L":")) { - strUrlValue = L"disabled"; // Can be anything not containing `:` + strUrlValue = L"disabled"; // Can be anything not containing `:` if (!WriteCompatibilityEntries(strUrlItem, strUrlKey, HKEY_CURRENT_USER, 0, strUrlValue)) bTryAdmin = true; } diff --git a/Client/loader/CInstallManager.h b/Client/loader/CInstallManager.h index 28ddd8d7c2e..9b80b0f7b31 100644 --- a/Client/loader/CInstallManager.h +++ b/Client/loader/CInstallManager.h @@ -13,9 +13,9 @@ #include "CSequencer.h" // Common command line keys -#define INSTALL_STAGE "install_stage" -#define INSTALL_LOCATION "install_loc" -#define HIDE_PROGRESS "hide_prog" +#define INSTALL_STAGE "install_stage" +#define INSTALL_LOCATION "install_loc" +#define HIDE_PROGRESS "hide_prog" typedef CBadLang CSequencerType; @@ -32,6 +32,7 @@ class CInstallManager protected: SString _ShowCrashFailDialog(); + SString _CheckForWerCrash(); SString _CheckOnRestartCommand(); SString _MaybeSwitchToTempExe(); SString _SwitchBackFromTempExe(); diff --git a/Client/loader/CSequencer.h b/Client/loader/CSequencer.h index d679a44ad57..5041cf0fbe2 100644 --- a/Client/loader/CSequencer.h +++ b/Client/loader/CSequencer.h @@ -166,9 +166,9 @@ class CBadLang SString strLabel = GetVariable("_pc_label"); int iOffset = GetVariableInt("_pc_offset"); m_uiCurrLine = m_LineList.size(); - for (uint i = 0; i < m_LineList.size(); i++) // Find label + for (uint i = 0; i < m_LineList.size(); i++) // Find label if (m_LineList[i].BeginsWith(strLabel)) - for (; i < m_LineList.size(); i++) // Find offset + for (; i < m_LineList.size(); i++) // Find offset if (IsLineValid(m_LineList[i]) && !iOffset--) { m_uiCurrLine = i; diff --git a/Client/loader/D3DStuff.cpp b/Client/loader/D3DStuff.cpp index 988a74d9024..ca4401a2e91 100644 --- a/Client/loader/D3DStuff.cpp +++ b/Client/loader/D3DStuff.cpp @@ -11,6 +11,9 @@ #include "D3DStuff.h" #include "Utils.h" #include "Dialogs.h" +#include "../sdk/core/CrashHandlerExports.h" + +#include #include #include @@ -57,7 +60,48 @@ namespace IDirect3D9* pD3D9 = NULL; IDirect3DDevice9* pD3DDevice9 = NULL; IDirect3DVertexDeclaration9* pD3DVertexDeclarations[20] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -} // namespace + + using EnableHandlersFn = BOOL(WINAPI*)(void); + std::atomic g_enableHandlersImpl{nullptr}; + std::atomic g_enableHandlersPending{false}; +} // namespace + +// Loader is built without core crash handler code; defer to the implementation once core.dll is loaded. +extern "C" BOOL BUGSUTIL_DLLINTERFACE __stdcall EnableAllHandlersAfterInitialization(void) noexcept +{ + if (EnableHandlersFn impl = g_enableHandlersImpl.load(std::memory_order_acquire)) + { + return impl(); + } + + g_enableHandlersPending.store(true, std::memory_order_release); + return TRUE; +} + +void LoaderResolveCrashHandlerExports(HMODULE coreModule) noexcept +{ + if (!coreModule) + return; + + auto resolved = reinterpret_cast(static_cast(GetProcAddress(coreModule, "EnableAllHandlersAfterInitialization"))); + + if (!resolved) + { + resolved = reinterpret_cast(static_cast(GetProcAddress(coreModule, "_EnableAllHandlersAfterInitialization@0"))); + } + + g_enableHandlersImpl.store(resolved, std::memory_order_release); + + if (!resolved) + { + WriteDebugEvent("Loader - Failed to resolve EnableAllHandlersAfterInitialization export"); + } + + if (resolved && g_enableHandlersPending.exchange(false, std::memory_order_acq_rel)) + { + resolved(); + } +} ////////////////////////////////////////////////////////// // @@ -94,8 +138,8 @@ bool NvOptimusDetect() bool bFoundOptimus = false; for (NvU32 i = 0; i < uiGpuCount; i++) { - NV_SYSTEM_TYPE SystemType = (NV_SYSTEM_TYPE)-1; // 1-Laptop 2-Desktop - NV_GPU_TYPE GpuType = (NV_GPU_TYPE)-1; // 1-Integrated 2-Discrete + NV_SYSTEM_TYPE SystemType = (NV_SYSTEM_TYPE)-1; // 1-Laptop 2-Desktop + NV_GPU_TYPE GpuType = (NV_GPU_TYPE)-1; // 1-Integrated 2-Discrete NvAPI_ShortString szName = "-"; NvAPI_GPU_GetSystemType(nvGPUHandle[i], &SystemType); @@ -210,6 +254,9 @@ void BeginD3DStuff() SetApplicationSettingInt("nvhacks", "optimus-export-enablement", 0); SetApplicationSettingInt("nvhacks", "optimus-force-windowed", 0); } + + // Crash handler enablement now occurs inside the game process once the + // Direct3D device is fully created (see CGraphics::OnDeviceCreate). } ////////////////////////////////////////////////////////// diff --git a/Client/loader/D3DStuff.h b/Client/loader/D3DStuff.h index ef3dadbae48..16cd19ddc3a 100644 --- a/Client/loader/D3DStuff.h +++ b/Client/loader/D3DStuff.h @@ -10,5 +10,8 @@ #pragma once +#include + void BeginD3DStuff(); void EndD3DStuff(); +void LoaderResolveCrashHandlerExports(HMODULE coreModule) noexcept; diff --git a/Client/loader/Dialogs.cpp b/Client/loader/Dialogs.cpp index 041a5c8d5dc..4bda6d12a39 100644 --- a/Client/loader/Dialogs.cpp +++ b/Client/loader/Dialogs.cpp @@ -8,23 +8,52 @@ * *****************************************************************************/ +#include "StdInc.h" #include "Dialogs.h" #include "resource.h" #include "Utils.h" #include "CInstallManager.h" #include "Main.h" #include +#include +#include +#include +#include + +// Define STN_CLICKED if not already defined +#ifndef STN_CLICKED + #define STN_CLICKED 0 +#endif -static bool bCancelPressed = false; -static bool bOkPressed = false; -static bool bOtherPressed = false; -static int iOtherCode = 0; -static HWND hwndProgressDialog = NULL; -static unsigned long ulProgressStartTime = 0; -static HWND hwndCrashedDialog = NULL; -static HWND hwndGraphicsDllDialog = NULL; -static HWND hwndOptimusDialog = NULL; -static HWND hwndNoAvDialog = NULL; +// Define IDC_SEND_DUMP_LABEL if not in resource.h yet +#ifndef IDC_SEND_DUMP_LABEL + #define IDC_SEND_DUMP_LABEL 1040 +#endif + +static std::atomic bCancelPressed{false}; +static std::atomic bOkPressed{false}; +static std::atomic bOtherPressed{false}; +static int iOtherCode = 0; +static HWND hwndProgressDialog = nullptr; +static unsigned long ulProgressStartTime = 0; +static HWND hwndCrashedDialog = nullptr; +static HWND hwndGraphicsDllDialog = nullptr; +static HWND hwndOptimusDialog = nullptr; +static HWND hwndNoAvDialog = nullptr; + +// Constants for crash dialog timeout +namespace +{ + inline constexpr DWORD MAX_WAIT_TIME = 30000; + static_assert(MAX_WAIT_TIME > 0 && MAX_WAIT_TIME <= 60000, "Timeout must be between 0 and 60 seconds"); + + inline constexpr std::string_view ERROR_MSG_PREFIX = "ShowCrashedDialog: CreateDialogW failed with error "; + inline constexpr std::string_view CRASH_MSG_DIALOG_FAIL = "MTA has crashed. (Failed to create crash dialog)"; + inline constexpr std::string_view CRASH_TITLE_FATAL = "MTA: San Andreas - Fatal Error"; + inline constexpr std::wstring_view DEFAULT_ERROR_MSG = L"An error occurred. No details available."; + inline constexpr size_t MAX_CRASH_MESSAGE_LENGTH = 65536; + static_assert(ERROR_MSG_PREFIX.size() <= INT_MAX, "ERROR_MSG_PREFIX too long for int cast"); +} /////////////////////////////////////////////////////////////////////////// // @@ -101,8 +130,8 @@ const SDialogItemInfo g_NoAvDialogItems[] = { _td("MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information.")}, - {IDC_NOAV_OPT_SKIP, 0, _td("I have already installed an anti-virus")}, - {IDC_NOAV_OPT_BOTNET, 0, + {IDC_NOAV_OPT_SKIP, 1, _td("I have already installed an anti-virus")}, + {IDC_NOAV_OPT_BOTNET, 1, _td("I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet.")}, {IDC_BUTTON_HELP, 0, dialogStringsHelp}, @@ -161,13 +190,67 @@ int CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { + case WM_CLOSE: + // Prevent dialog from closing via WM_CLOSE (Alt+F4, X button, parent termination, etc.) + // User must explicitly click a button. This prevents premature closure of crash dialog. + if (hwnd == hwndCrashedDialog) + { + // Block WM_CLOSE for crash dialog - require explicit user button press + return TRUE; + } + // Allow other dialogs to close normally + break; + + case WM_SYSCOMMAND: + // Block system menu commands that could hide or close the crash dialog + if (hwnd == hwndCrashedDialog) + { + if (wParam == SC_CLOSE || wParam == SC_MINIMIZE || wParam == SC_MAXIMIZE) + return TRUE; + } + break; + case WM_COMMAND: + // Validate message source + if (lParam != 0 && !IsWindow(reinterpret_cast(lParam))) + break; + switch (LOWORD(wParam)) { case IDCANCEL: + // For crash dialog, save checkbox state before exiting + if (hwnd == hwndCrashedDialog) + { + if (HWND hwndCheck = GetDlgItem(hwnd, IDC_SEND_DUMP_CHECK)) + { + LRESULT res = SendMessageA(hwndCheck, BM_GETCHECK, 0, 0); + try + { + SetApplicationSetting("diagnostics", "send-dumps", (res == BST_CHECKED) ? "yes" : "no"); + } + catch (...) + { + } + } + } bCancelPressed = true; return TRUE; case IDOK: + // For crash dialog, save checkbox state before exiting + if (hwnd == hwndCrashedDialog) + { + if (HWND hwndCheck = GetDlgItem(hwnd, IDC_SEND_DUMP_CHECK)) + { + LRESULT res = SendMessageA(hwndCheck, BM_GETCHECK, 0, 0); + try + { + SetApplicationSetting("diagnostics", "send-dumps", (res == BST_CHECKED) ? "yes" : "no"); + } + catch (...) + { + } + } + } bOkPressed = true; return TRUE; default: @@ -195,7 +278,7 @@ void ShowProgressDialog(HINSTANCE hInstance, const SString& strTitle, bool bAllo HideSplash(); bCancelPressed = false; hwndProgressDialog = CreateDialogW(hInstance, MAKEINTRESOURCEW(IDD_PROGRESS_DIALOG), 0, DialogProc); - dassert((GetWindowLong(hwndProgressDialog, GWL_STYLE) & WS_VISIBLE) == 0); // Should be Visible: False + dassert((GetWindowLong(hwndProgressDialog, GWL_STYLE) & WS_VISIBLE) == 0); // Should be Visible: False InitDialogStrings(hwndProgressDialog, g_ProgressDialogItems); SetWindowTextW(hwndProgressDialog, FromUTF8(strTitle)); ShowWindow(GetDlgItem(hwndProgressDialog, IDCANCEL), bAllowCancel ? SW_SHOW : SW_HIDE); @@ -275,65 +358,370 @@ void StopPseudoProgress() } } -/////////////////////////////////////////////////////////////// -// -// Crashed dialog -// -// -// -/////////////////////////////////////////////////////////////// -SString ShowCrashedDialog(HINSTANCE hInstance, const SString& strMessage) +// This function isn't overengineered, it needs to be extremely secure to avoid maliciously triggered crashes from escaping and doing bad things. +[[nodiscard]] SString ShowCrashedDialog(HINSTANCE hInstance, const SString& strMessage) { - if (!hwndCrashedDialog) + using namespace std::string_view_literals; + + if (auto validHandle = std::optional{hInstance ? hInstance : GetModuleHandle(nullptr)}; !validHandle || !*validHandle) [[unlikely]] { - SuspendSplash(); - bCancelPressed = false; - bOkPressed = false; - bOtherPressed = false; - iOtherCode = 0; - hwndCrashedDialog = CreateDialogW(hInstance, MAKEINTRESOURCEW(IDD_CRASHED_DIALOG), 0, DialogProc); - dassert((GetWindowLong(hwndCrashedDialog, GWL_STYLE) & WS_VISIBLE) == 0); // Should be Visible: False - InitDialogStrings(hwndCrashedDialog, g_CrashedDialogItems); - SetWindowTextW(GetDlgItem(hwndCrashedDialog, IDC_CRASH_INFO_EDIT), FromUTF8(strMessage)); - SendDlgItemMessage(hwndCrashedDialog, IDC_SEND_DUMP_CHECK, BM_SETCHECK, - GetApplicationSetting("diagnostics", "send-dumps") != "no" ? BST_CHECKED : BST_UNCHECKED, 0); + try + { + MessageBoxA(nullptr, "MTA has crashed."sv.data(), "MTA: San Andreas"sv.data(), MB_OK | MB_ICONERROR | MB_TOPMOST); + } + catch (...) + { + } + return "quit"; + } + else + { + hInstance = *validHandle; } - SetForegroundWindow(hwndCrashedDialog); - SetWindowPos(hwndCrashedDialog, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); - while (!bCancelPressed && !bOkPressed) + const auto strSanitizedMessage = [&message = std::as_const(strMessage)]() noexcept -> SString { - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) + try { - if (GetMessage(&msg, NULL, 0, 0)) + if constexpr (MAX_CRASH_MESSAGE_LENGTH > 0) { - TranslateMessage(&msg); - DispatchMessage(&msg); + const auto messageLength = std::clamp(std::size(message), size_t{0}, MAX_CRASH_MESSAGE_LENGTH); + if (std::size(message) > MAX_CRASH_MESSAGE_LENGTH) + return message.substr(0, messageLength); + else + return message; + } + else + { + return message; } } - Sleep(10); - } + catch (...) + { + return SString{}; + } + }(); - LRESULT res = SendMessageA(GetDlgItem(hwndCrashedDialog, IDC_SEND_DUMP_CHECK), BM_GETCHECK, 0, 0); - SetApplicationSetting("diagnostics", "send-dumps", res ? "yes" : "no"); + struct ReentranceGuard final + { + std::atomic& flag; + bool isValid{true}; - if (bCancelPressed) - return "quit"; + explicit ReentranceGuard(std::atomic& f) noexcept : flag(f), isValid(!flag.exchange(true, std::memory_order_acquire)) {} - ResumeSplash(); + ~ReentranceGuard() noexcept + { + if (isValid) [[likely]] + flag.store(false, std::memory_order_release); + } + + [[nodiscard]] explicit operator bool() const noexcept { return isValid; } + + ReentranceGuard(const ReentranceGuard&) = delete; + ReentranceGuard& operator=(const ReentranceGuard&) = delete; + ReentranceGuard(ReentranceGuard&&) = delete; + ReentranceGuard& operator=(ReentranceGuard&&) = delete; + }; + + static std::atomic bInShowCrashedDialog{false}; + + try + { + ReentranceGuard guard{bInShowCrashedDialog}; + + if (!guard) [[unlikely]] + { + try + { + MessageBoxA(nullptr, "MTA has crashed."sv.data(), "MTA: San Andreas"sv.data(), MB_OK | MB_ICONERROR | MB_TOPMOST | MB_SETFOREGROUND); + } + catch (...) + { + } + return "quit"; + } + + if ([[maybe_unused]] const auto displayResult = ChangeDisplaySettings(nullptr, 0); true) + { + constexpr auto displaySettingsDelay = 300; + Sleep(displaySettingsDelay); + } + + if (!hwndCrashedDialog) + { + try + { + SuspendSplash(); + } + catch (...) + { + } + + // Reset button states + bCancelPressed.store(false, std::memory_order_release); + bOkPressed.store(false, std::memory_order_release); + + hwndCrashedDialog = CreateDialogW(hInstance, MAKEINTRESOURCEW(IDD_CRASHED_DIALOG), nullptr, DialogProc); + + if (!hwndCrashedDialog) [[unlikely]] + { + [[nodiscard]] const auto logError = [lastError = static_cast(GetLastError())]() noexcept + { + try + { + constexpr auto errorCode = 9001; + AddReportLog(errorCode, SString("ShowCrashedDialog: CreateDialogW failed with error %u", lastError)); + } + catch (...) + { + } + }; + + [[nodiscard]] constexpr auto setDumpSetting = []() noexcept -> void + { + try + { + SetApplicationSetting("diagnostics"sv.data(), "send-dumps"sv.data(), "yes"sv.data()); + } + catch (...) + { + } + }; + + [[nodiscard]] constexpr auto cleanup = []() noexcept -> void + { + try + { + ResumeSplash(); + } + catch (...) + { + } + try + { + MessageBoxA(nullptr, CRASH_MSG_DIALOG_FAIL.data(), CRASH_TITLE_FATAL.data(), MB_OK | MB_ICONERROR | MB_TOPMOST); + } + catch (...) + { + } + }; + + std::invoke(logError); + std::invoke(setDumpSetting); + std::invoke(cleanup); + return "quit"; + } + try + { + InitDialogStrings(hwndCrashedDialog, g_CrashedDialogItems); + } + catch (...) + { + } + if (auto hwndCrashInfo = GetDlgItem(hwndCrashedDialog, IDC_CRASH_INFO_EDIT); hwndCrashInfo) + { + try + { + if (const bool isEmpty = std::empty(strSanitizedMessage); isEmpty) [[unlikely]] + { + SetWindowTextW(hwndCrashInfo, DEFAULT_ERROR_MSG.data()); + } + else + { + if (const auto wszMessage = FromUTF8(strSanitizedMessage); wszMessage && (wszMessage[0] != L'\0')) [[likely]] + { + SetWindowTextW(hwndCrashInfo, wszMessage); + } + else [[unlikely]] + { + SetWindowTextW(hwndCrashInfo, DEFAULT_ERROR_MSG.data()); + } + } + } + catch (...) + { + } + } + if (const auto hwndCheckbox = GetDlgItem(hwndCrashedDialog, IDC_SEND_DUMP_CHECK); hwndCheckbox) + { + try + { + const auto settingValue = std::invoke( + []() noexcept -> SString + { + try + { + return GetApplicationSetting("diagnostics"sv.data(), "send-dumps"sv.data()); + } + catch (...) + { + return "yes"; + } + }); + + const std::array checkStates = {BST_UNCHECKED, BST_CHECKED}; + const auto shouldCheck = !std::empty(settingValue) && settingValue != "no"sv.data(); + SendDlgItemMessage(hwndCrashedDialog, IDC_SEND_DUMP_CHECK, BM_SETCHECK, checkStates[shouldCheck], 0); + } + catch (...) + { + } + } + } + if (!hwndCrashedDialog) [[unlikely]] + { + try + { + SetApplicationSetting("diagnostics"sv.data(), "send-dumps"sv.data(), "yes"sv.data()); + } + catch (...) + { + } + return "quit"; + } + try + { + SetForegroundWindow(hwndCrashedDialog); + SetWindowPos(hwndCrashedDialog, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + } + catch (...) + { + } + + const auto dwStartTime = static_cast(GetTickCount32()); - // if ( bOkPressed ) - return "ok"; + [[nodiscard]] constexpr auto handleTimeout = []() noexcept -> void + { + try + { + SetApplicationSetting("diagnostics"sv.data(), "send-dumps"sv.data(), "yes"sv.data()); + } + catch (...) + { + } + }; + + [[nodiscard]] constexpr auto calculateElapsed = [](const DWORD current, const DWORD start) noexcept -> DWORD + { + if constexpr (sizeof(DWORD) == 4) + { + return (current >= start) ? (current - start) : (std::numeric_limits::max() - start + current + 1); + } + else + { + return current - start; + } + }; + + for (;;) + { + const auto [cancelPressed, okPressed] = std::pair{bCancelPressed.load(std::memory_order_acquire), bOkPressed.load(std::memory_order_acquire)}; + if (cancelPressed || okPressed) + break; + + if (const auto dwCurrentTime = static_cast(GetTickCount32()); calculateElapsed(dwCurrentTime, dwStartTime) > MAX_WAIT_TIME) [[unlikely]] + { + std::invoke(handleTimeout); + (void)bCancelPressed.exchange(true, std::memory_order_release); + break; + } + constexpr auto maxMessagesPerIteration = 100; + auto msg = MSG{}; + auto messageCount = decltype(maxMessagesPerIteration){0}; + + while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) + { + if (std::exchange(messageCount, messageCount + 1) >= maxMessagesPerIteration) [[unlikely]] + break; + + // Block WM_QUIT and other termination messages during crash dialog. + // The crash dialog MUST only close via explicit user button press (IDOK/IDCANCEL). + // External quit requests (from CallFunction:Quit, PostQuitMessage, etc.) are suppressed + // to prevent premature dialog closure before user can make a choice. + if (msg.message == WM_QUIT || msg.message == WM_CLOSE || msg.message == WM_DESTROY) [[unlikely]] + { + // Silently discard termination messages - do NOT set bCancelPressed + // This prevents external quit requests from closing the crash dialog + continue; + } + + if (msg.hwnd && !IsWindow(msg.hwnd)) [[unlikely]] + continue; + + try + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + catch (...) + { + } + } + if (!hwndCrashedDialog || !IsWindow(hwndCrashedDialog)) [[unlikely]] + { + (void)bCancelPressed.exchange(true, std::memory_order_release); + break; + } + + { + constexpr auto sleepDuration = 10; + try + { + Sleep(sleepDuration); + } + catch (...) + { + (void)bCancelPressed.exchange(true, std::memory_order_release); + break; + } + } + } + + const auto okWasPressed = bOkPressed.load(std::memory_order_acquire); + return okWasPressed ? "ok" : "quit"; + } + catch (...) + { + try + { + SetApplicationSetting("diagnostics"sv.data(), "send-dumps"sv.data(), "yes"sv.data()); + } + catch (...) + { + } + return "quit"; + } } void HideCrashedDialog() { if (hwndCrashedDialog) { - DestroyWindow(hwndCrashedDialog); - hwndCrashedDialog = NULL; + const HWND crashedDialog = hwndCrashedDialog; + hwndCrashedDialog = nullptr; + + if (crashedDialog && IsWindow(crashedDialog)) + DestroyWindow(crashedDialog); } + + ResumeSplash(); +} + +void ShowOOMMessageBox([[maybe_unused]] HINSTANCE hInstance) +{ + static constexpr const char* fallbackMessage = "The crash you experienced is due to memory abuse by servers. Contact server owner or MTA support."; + static constexpr const char* fallbackTitle = "MTA: San Andreas - Out of Memory Crash"; + + const char* message = + _("The crash you experienced is due to memory abuse by servers.\n\n" + "Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB " + "and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) " + "can make this happen, as well as lag your game.\n\n" + "Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information."); + + const char* title = _("MTA: San Andreas - Out of Memory Information"); + + MessageBoxA(NULL, message ? message : fallbackMessage, title ? title : fallbackTitle, MB_OK | MB_ICONINFORMATION | MB_TOPMOST | MB_SETFOREGROUND); } /////////////////////////////////////////////////////////////// @@ -367,7 +755,7 @@ void ShowGraphicsDllDialog(HINSTANCE hInstance, const std::vector(time(NULL) / 3600LL); @@ -616,12 +1004,16 @@ void ShowNoAvDialog(HINSTANCE hInstance, bool bEnableScaremongering) bOtherPressed = false; iOtherCode = IDC_BUTTON_HELP; hwndNoAvDialog = CreateDialogW(hInstance, MAKEINTRESOURCEW(IDD_NOAV_DIALOG), 0, DialogProc); - dassert((GetWindowLongW(hwndNoAvDialog, GWL_STYLE) & WS_VISIBLE) == 0); // Should be Visible: False + dassert((GetWindowLongW(hwndNoAvDialog, GWL_STYLE) & WS_VISIBLE) == 0); // Should be Visible: False InitDialogStrings(hwndNoAvDialog, g_NoAvDialogItems); - ShowWindow(GetDlgItem(hwndNoAvDialog, IDC_NOAV_OPT_SKIP), bEnableScaremongering ? SW_HIDE : SW_SHOW); - ShowWindow(GetDlgItem(hwndNoAvDialog, IDC_NOAV_OPT_BOTNET), bEnableScaremongering ? SW_SHOW : SW_HIDE); + const int textSourceItemId = bEnableScaremongering ? IDC_NOAV_OPT_BOTNET : IDC_NOAV_OPT_SKIP; + { + wchar_t text[256] = {}; + GetWindowTextW(GetDlgItem(hwndNoAvDialog, textSourceItemId), text, _countof(text)); + SetWindowTextW(GetDlgItem(hwndNoAvDialog, IDC_CHECK_NOT_AGAIN), text); + } } - ShowWindow(hwndNoAvDialog, SW_SHOW); // Show after all changes are complete + ShowWindow(hwndNoAvDialog, SW_SHOW); // Show after all changes are complete SetForegroundWindow(hwndNoAvDialog); SetWindowPos(hwndNoAvDialog, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); @@ -673,8 +1065,8 @@ void HideNoAvDialog() /////////////////////////////////////////////////////////////// void TestDialogs() { -#if 0 -#if 1 + #if 0 + #if 1 ShowProgressDialog( g_hInstance, _("Searching for Grand Theft Auto San Andreas"), true ); for ( uint i = 0 ; i < 100 ; i++ ) { @@ -718,40 +1110,40 @@ void TestDialogs() Sleep( 10 ); } HideProgressDialog(); -#endif + #endif -#if 1 + #if 1 ShowCrashedDialog( g_hInstance, "test2" ); HideCrashedDialog(); -#endif + #endif -#if 1 + #if 1 SetApplicationSetting("diagnostics", "d3d9-dll-last-hash", "123"); std::vector offenders{GraphicsLibrary{"dummy"}}; ShowGraphicsDllDialog(g_hInstance, offenders); HideGraphicsDllDialog(); -#endif + #endif -#if 1 + #if 1 ShowOptimusDialog( g_hInstance ); HideOptimusDialog(); -#endif + #endif -#if 1 + #if 1 // Friendly option SetApplicationSettingInt( "noav-last-asked-time", 1 ); SetApplicationSettingInt( "noav-user-says-skip", 0 ); ShowNoAvDialog( g_hInstance, true ); HideNoAvDialog(); -#endif + #endif -#if 1 + #if 1 // Scaremongering option option SetApplicationSettingInt( "noav-last-asked-time", 1 ); SetApplicationSettingInt( "noav-user-says-skip", 0 ); ShowNoAvDialog( g_hInstance, false ); HideNoAvDialog(); -#endif -#endif + #endif + #endif } #endif diff --git a/Client/loader/Dialogs.h b/Client/loader/Dialogs.h index ac89d1ed80c..3af8861b4a4 100644 --- a/Client/loader/Dialogs.h +++ b/Client/loader/Dialogs.h @@ -26,10 +26,11 @@ void StopPseudoProgress(); SString ShowCrashedDialog(HINSTANCE hInstance, const SString& strMessage); void HideCrashedDialog(); +void ShowOOMMessageBox(HINSTANCE hInstance); struct GraphicsLibrary { - SString stem; // filename without the final extension + SString stem; // filename without the final extension SString absoluteFilePath; SString md5Hash; SString appLastHash; diff --git a/Client/loader/FileSystem.cpp b/Client/loader/FileSystem.cpp index 405e99bee1d..bda0c05658e 100644 --- a/Client/loader/FileSystem.cpp +++ b/Client/loader/FileSystem.cpp @@ -316,12 +316,6 @@ bool AreFilesEqual(const fs::path& base, const fs::path& other, std::error_code& { ec.clear(); - if (fs::equivalent(base, other, ec)) - return true; - - if (ec) - return false; - HandleScope baseHandle{CreateFileW( /* FileName */ base.wstring().c_str(), /* DesiredAccess */ GENERIC_READ, @@ -354,23 +348,31 @@ bool AreFilesEqual(const fs::path& base, const fs::path& other, std::error_code& return false; } - LARGE_INTEGER baseSize{}; - LARGE_INTEGER otherSize{}; + BY_HANDLE_FILE_INFORMATION baseInfo{}; + BY_HANDLE_FILE_INFORMATION otherInfo{}; - if (!GetFileSizeEx(baseHandle.get(), &baseSize) || !GetFileSizeEx(otherHandle.get(), &otherSize)) + if (!GetFileInformationByHandle(baseHandle.get(), &baseInfo) || !GetFileInformationByHandle(otherHandle.get(), &otherInfo)) { ApplyLastSystemError(ec); return false; } - if (baseSize.QuadPart != otherSize.QuadPart) + // Check if the handles represent the same file in the file system. + if (baseInfo.dwVolumeSerialNumber == otherInfo.dwVolumeSerialNumber && baseInfo.nFileIndexHigh == otherInfo.nFileIndexHigh && + baseInfo.nFileIndexLow == otherInfo.nFileIndexLow) + { + return true; + } + + // Check if the file sizes differ. + if (!(baseInfo.nFileSizeHigh == otherInfo.nFileSizeHigh && baseInfo.nFileSizeLow == otherInfo.nFileSizeLow)) return false; std::array baseBuffer{}; std::array otherBuffer{}; const auto bytesToRead = static_cast(baseBuffer.size()); - LONGLONG remainingSize = baseSize.QuadPart; + LONGLONG remainingSize = (static_cast(baseInfo.nFileSizeHigh) << 32) | baseInfo.nFileSizeLow; while (remainingSize) { @@ -479,52 +481,3 @@ auto GetFileBufferHash(const std::vector& buffer) -> FileHash sha256_final(&ctx, hash.data()); return hash; } - -bool SetDirectoryJunction(const fs::path& from, const fs::path& to, std::error_code& ec) -{ - ec.clear(); - - // The source directory must exist. - if (!fs::is_directory(from, ec)) - return false; - - // Check if the target directory is already pointing to the source directory. - if (fs::is_symlink(to, ec)) - { - if (fs::equivalent(from, to, ec)) - return true; - - if (ec) - return false; - } - - // Remove the target file to replace it. - if (fs::exists(to, ec)) - { - fs::remove_all(to, ec); - } - - if (ec) - return false; - - // Create the parent directory for the symlink. - const fs::path toParentDirectory = to.parent_path(); - - if (!fs::exists(toParentDirectory, ec)) - { - if (ec || !fs::create_directories(toParentDirectory, ec)) - return false; - - if (!fs::is_directory(toParentDirectory, ec)) - return false; - } - - // Use the native function to create the symlink due to flag usage. - if (!CreateSymbolicLinkW(to.wstring().c_str(), from.wstring().c_str(), SYMBOLIC_LINK_FLAG_DIRECTORY | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)) - { - ApplyLastSystemError(ec); - return false; - } - - return true; -} diff --git a/Client/loader/GameExecutablePatcher.cpp b/Client/loader/GameExecutablePatcher.cpp index 3183fe7c6a5..46743ddc376 100644 --- a/Client/loader/GameExecutablePatcher.cpp +++ b/Client/loader/GameExecutablePatcher.cpp @@ -153,8 +153,8 @@ class WindowsAeroPatch final */ class LibraryRedirectionPatch final { - static constexpr auto LIBRARY_NAME_BEFORE = "WINMM.dll"; // Do not correct this value. It must be equal to the one in the original binary. - static constexpr auto LIBRARY_NAME_AFTER = LOADER_PROXY_DLL_NAME; // This must be equal to the library produced by 'Loader Proxy' project. + static constexpr auto LIBRARY_NAME_BEFORE = "WINMM.dll\x00\x02"; // Do not correct this value. It must be equal to the one in the original binary. + static constexpr auto LIBRARY_NAME_AFTER = LOADER_PROXY_DLL_NAME; // This must be equal to the library produced by 'Loader Proxy' project. static auto GetImportDescriptor(PatchableExecutable& pe) -> IMAGE_IMPORT_DESCRIPTOR* { @@ -195,7 +195,7 @@ class LibraryRedirectionPatch final if (stricmp(LIBRARY_NAME_AFTER, name)) continue; - strcpy(name, LIBRARY_NAME_BEFORE); + memcpy(name, LIBRARY_NAME_BEFORE, 11); return; } } @@ -278,8 +278,8 @@ class HighPerformanceGraphicsPatch final item.rvaName = EXPORT_DIRECTORY_VA + offset; auto value = reinterpret_cast(base + offset); - std::copy(item.name.data(), item.name.data() + item.name.size() + 1, value); // Plus one for null byte. - offset += item.name.size() + 1; // Length plus null byte. + std::copy(item.name.data(), item.name.data() + item.name.size() + 1, value); // Plus one for null byte. + offset += item.name.size() + 1; // Length plus null byte. } // Write export name RVAs. diff --git a/Client/loader/Install.Manifest.cpp b/Client/loader/Install.Manifest.cpp index 9f3e264d02f..d1fb986a227 100644 --- a/Client/loader/Install.Manifest.cpp +++ b/Client/loader/Install.Manifest.cpp @@ -63,7 +63,7 @@ static void ParseManifestVersion1(std::ifstream& manifest, std::vector_tmp_' + archiveFileName = archiveFileName.SubStr(1).SplitLeft("_tmp_", nullptr, -1); // Cut archive name out of '__tmp_' archivePath = MakeGenericPath(PathJoin(archiveDirectory, archiveFileName)); } @@ -585,6 +585,12 @@ static int RunInstall() const SString targetRoot = PathConform(GetMTASAPath()); + if (sourceRoot.CompareI(targetRoot)) + { + AddReportLog(5055, SString("RunInstall: Refusing to install from and to the same directory '%s'", sourceRoot.c_str())); + return 9; + } + if (!DirectoryExists(targetRoot)) { AddReportLog(5055, SString("RunInstall: MTA directory does not exist: '%s'", targetRoot.c_str())); @@ -604,6 +610,20 @@ static int RunInstall() if (archiveFiles.empty()) return 0; + // Check if server is installed, if not, skip server files during update + if (!DirectoryExists(CalcMTASAPath("server"))) + { + // Filter out server files + size_t originalCount = archiveFiles.size(); + archiveFiles.erase(std::remove_if(archiveFiles.begin(), archiveFiles.end(), [](const ManifestFile& file) + { return file.relativePath.compare(0, 7, "server/") == 0 || file.relativePath.compare(0, 7, "server\\") == 0; }), + archiveFiles.end()); + + size_t filteredCount = originalCount - archiveFiles.size(); + if (filteredCount > 0) + OutputDebugLine(SString("RunInstall: Skipped %zu server files (server not installed)", filteredCount)); + } + // Create a backup directory for disaster recovery. const SString backupRoot = CreateWritableDirectory(sourceRoot + "_bak_"); @@ -803,7 +823,8 @@ static int RunInstall() else OutputDebugLine(SString("RunInstall: Updated %zu files", files.size())); - const auto Rollback = [&]() { + const auto Rollback = [&]() + { if (size_t disasterCounter = RunRollback(files); disasterCounter > 0) { // Do not delete the backup directory if we need it for recovery. @@ -913,7 +934,11 @@ SString CheckOnRestartCommand() // if (strFile.empty() || !FileExists(strFile)) + { + AddReportLog(4047, SString("CheckOnRestartCommand: update archive missing '%s'", strFile.c_str())); + SetOnRestartCommand(""); return "FileMissing"; + } // Make temp path name and go there SString strArchivePath, strArchiveName; @@ -922,12 +947,18 @@ SString CheckOnRestartCommand() const SString sourceRoot = MakeUniquePath(strArchivePath + "\\_" + strArchiveName + "_tmp_"); if (!MkDir(sourceRoot)) + { + AddReportLog(4047, SString("CheckOnRestartCommand: failed to create temp dir '%s'", sourceRoot.c_str())); return "FileError1"; + } DirectoryDeleteScope deleteSourceRoot(sourceRoot); if (!SetCurrentDirectory(sourceRoot)) + { + AddReportLog(4047, SString("CheckOnRestartCommand: failed to enter temp dir '%s'", sourceRoot.c_str())); return "FileError2"; + } // Start progress bar if (!strParameters.Contains("hideprogress")) @@ -947,7 +978,10 @@ SString CheckOnRestartCommand() StopPseudoProgress(); if (!success) + { + AddReportLog(4047, SString("CheckOnRestartCommand: failed to extract or execute update '%s'", strFile.c_str())); return "FileError3"; + } deleteSourceRoot.Release(); @@ -961,6 +995,7 @@ SString CheckOnRestartCommand() else { AddReportLog(5052, SString("CheckOnRestartCommand: Unknown restart command %s", strOperation.c_str())); + SetOnRestartCommand(""); } } diff --git a/Client/loader/Main.cpp b/Client/loader/Main.cpp index adc5a93bae2..b17a70a6e93 100644 --- a/Client/loader/Main.cpp +++ b/Client/loader/Main.cpp @@ -15,10 +15,179 @@ #include "Dialogs.h" #include "Utils.h" #include "SharedUtil.Win32Utf8FileHooks.hpp" + #if defined(MTA_DEBUG) #include "SharedUtil.Tests.hpp" #endif + #include +#include +#include +#include + +#if __cplusplus >= 201703L + #define MAYBE_UNUSED [[maybe_unused]] +#else + #define MAYBE_UNUSED +#endif + +namespace +{ + // Error codes enum for better maintainability + enum ErrorCode : int + { + ERROR_NULL_INSTANCE = -1, + ERROR_NULL_INSTALL_MANAGER = -2, + ERROR_LAUNCH_EXCEPTION = -3, + ERROR_INSTALL_CONTINUE = -4 + }; + + // Command line constants + constexpr size_t MAX_CMD_LINE_LENGTH = 4096; + + // Report log IDs + constexpr int LOG_ID_END = 1044; + constexpr int LOG_ID_CONTINUE_EXCEPTION = 1045; + constexpr int LOG_ID_LAUNCH_EXCEPTION = 1046; + + // Compile-time checks + static_assert(MAX_CMD_LINE_LENGTH > 0, "Command line buffer size must be positive"); + static_assert(MAX_CMD_LINE_LENGTH <= 65536, "Command line buffer size seems unreasonably large"); + static_assert(sizeof(DWORD) >= sizeof(int), "DWORD must be at least as large as int"); + + class Utf8FileHooksGuard + { + private: + bool m_released = false; + + public: + Utf8FileHooksGuard() { AddUtf8FileHooks(); } + + ~Utf8FileHooksGuard() noexcept + { + if (!m_released) + { + RemoveUtf8FileHooks(); + } + } + + // Called when we want to keep hooks active (early return with error) + void release() noexcept { m_released = true; } + + // Called when we want to remove hooks early (on GetInstallManager failure) + void removeNow() noexcept + { + if (!m_released) + { + RemoveUtf8FileHooks(); + m_released = true; + } + } + + // Disable copy and move + Utf8FileHooksGuard(const Utf8FileHooksGuard&) = delete; + Utf8FileHooksGuard& operator=(const Utf8FileHooksGuard&) = delete; + Utf8FileHooksGuard(Utf8FileHooksGuard&&) = delete; + Utf8FileHooksGuard& operator=(Utf8FileHooksGuard&&) = delete; + }; + + inline void SafeCopyCommandLine(LPSTR lpCmdLine, char* safeCmdLine, size_t bufferSize) noexcept + { + // Preconditions (only in debug builds) + assert(safeCmdLine != nullptr && "Destination buffer must not be null"); + assert(bufferSize > 0 && "Buffer size must be positive"); + + if (!safeCmdLine || bufferSize == 0) + { + return; + } + + // If source is null, destination remains zero-initialized + if (!lpCmdLine) + { + return; + } + + const size_t maxCopyLen = bufferSize - 1; + const size_t cmdLineLen = strnlen(lpCmdLine, maxCopyLen); + + memcpy(safeCmdLine, lpCmdLine, cmdLineLen); + safeCmdLine[cmdLineLen] = '\0'; + } + + inline DWORD GetSafeProcessId() noexcept + { + try + { + return GetCurrentProcessId(); + } + catch (...) + { + return 0; + } + } + + CInstallManager* PerformEarlyInitialization(const char* safeCmdLine) + { + auto* pInstallManager = GetInstallManager(); + if (!pInstallManager) + { + return nullptr; + } + + // Let install manager figure out what MTASA path to use + // This must be called before ConfigureWerDumpPath which uses CalcMTASAPath + pInstallManager->SetMTASAPathSource(safeCmdLine); + + ConfigureWerDumpPath(); + + // Start logging.....now + BeginEventLog(); + + // Start localization if possible + InitLocalization(false); + + // Handle commands from the installer + HandleSpecialLaunchOptions(); + + // Check MTA is launched only once + HandleDuplicateLaunching(); + + return pInstallManager; + } + + SString ContinueUpdateProcedure(CInstallManager* pInstallManager) + { + if (!pInstallManager) + { + return SString(); + } + + try + { + return pInstallManager->Continue(); + } + catch (...) + { + AddReportLog(LOG_ID_CONTINUE_EXCEPTION, "Exception in InstallManager::Continue()"); + return SString(); + } + } + + // Launch the game with exception handling + int LaunchGameSafely(const SString& strCmdLine) + { + try + { + return LaunchGame(strCmdLine); + } + catch (...) + { + AddReportLog(LOG_ID_LAUNCH_EXCEPTION, "Exception in LaunchGame()"); + return static_cast(ERROR_LAUNCH_EXCEPTION); + } + } +} /////////////////////////////////////////////////////////////// // @@ -28,12 +197,38 @@ // 1. During install with /kdinstall command (as admin) // 2. During uninstall with /kduninstall command (as admin) // 3. By 'MTA San Andreas.exe' when temporary elevated privileges are required (as admin) -// 4. By 'MTA San Andreas.exe' during auto-update (in a temporary directory somewhere) (Which may then call it again as admin) +// 4. By 'MTA San Andreas.exe' during auto-update (in a temporary directory somewhere) +// (Which may then call it again as admin) // /////////////////////////////////////////////////////////////// -MTAEXPORT int DoWinMain(HINSTANCE hLauncherInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +MTAEXPORT int DoWinMain(HINSTANCE hLauncherInstance, MAYBE_UNUSED HINSTANCE hPrevInstance, LPSTR lpCmdLine, MAYBE_UNUSED int nCmdShow) { - AddUtf8FileHooks(); +// Silence unused parameter warnings for older compilers +#if __cplusplus < 201703L + (void)hPrevInstance; + (void)nCmdShow; +#endif + + // Check for null parameters before use + if (!hLauncherInstance) + { + return static_cast(ERROR_NULL_INSTANCE); + } + + char safeCmdLine[MAX_CMD_LINE_LENGTH] = {0}; + SafeCopyCommandLine(lpCmdLine, safeCmdLine, sizeof(safeCmdLine)); + + // Log the command line we're receiving + { + char debugBuf[512]; + _snprintf_s(debugBuf, sizeof(debugBuf), _TRUNCATE, + "========================================\nMain.cpp - Command line received: '%s'\n========================================\n", + safeCmdLine); + OutputDebugStringA(debugBuf); + } + + // RAII guard for UTF8 file hooks + Utf8FileHooksGuard utf8Guard; #if defined(MTA_DEBUG) SharedUtil_Tests(); @@ -43,23 +238,18 @@ MTAEXPORT int DoWinMain(HINSTANCE hLauncherInstance, HINSTANCE hPrevInstance, LP // Init // - // Let install manager figure out what MTASA path to use - GetInstallManager()->SetMTASAPathSource(lpCmdLine); - - // Start logging.....now - BeginEventLog(); + auto* pInstallManager = PerformEarlyInitialization(safeCmdLine); + if (!pInstallManager) + { + // Remove hooks when install manager fails + utf8Guard.removeNow(); + return static_cast(ERROR_NULL_INSTALL_MANAGER); + } - // Start localization if possible - InitLocalization(false); - - // Handle commands from the installer - HandleSpecialLaunchOptions(); - - // Check MTA is launched only once - HandleDuplicateLaunching(); + HINSTANCE hInstanceToUse = hLauncherInstance; // Show logo - ShowSplash(g_hInstance); + ShowSplash(hInstanceToUse); // Other init stuff ClearPendingBrowseToSolution(); @@ -67,16 +257,8 @@ MTAEXPORT int DoWinMain(HINSTANCE hLauncherInstance, HINSTANCE hPrevInstance, LP // Find GTA path to use ValidateGTAPath(); - // - // Update - // - // Continue any update procedure - SString strCmdLine = GetInstallManager()->Continue(); - - // - // Launch - // + SString strCmdLine = ContinueUpdateProcedure(pInstallManager); // Ensure localization is started InitLocalization(true); @@ -86,9 +268,11 @@ MTAEXPORT int DoWinMain(HINSTANCE hLauncherInstance, HINSTANCE hPrevInstance, LP // Stuff HandleCustomStartMessage(); - #if !defined(MTA_DEBUG) && MTASA_VERSION_TYPE != VERSION_TYPE_CUSTOM + +#if !defined(MTA_DEBUG) && MTASA_VERSION_TYPE != VERSION_TYPE_CUSTOM ForbodenProgramsMessage(); - #endif +#endif + CycleEventLog(); BsodDetectionPreLaunch(); MaybeShowCopySettingsDialog(); @@ -100,14 +284,17 @@ MTAEXPORT int DoWinMain(HINSTANCE hLauncherInstance, HINSTANCE hPrevInstance, LP CheckAntiVirusStatus(); // Ensure logo is showing - ShowSplash(g_hInstance); + ShowSplash(hInstanceToUse); // Check MTA files look good CheckDataFiles(); CheckLibVersions(); // Go for launch - int iReturnCode = LaunchGame(strCmdLine); + // Initialize return code with safe default + int iReturnCode = 0; + WriteDebugEvent(SString("[7207] Loader - About to call LaunchGameSafely, cmdLine='%s'", strCmdLine.c_str())); + iReturnCode = LaunchGameSafely(strCmdLine); PostRunWatchDogs(iReturnCode); @@ -120,8 +307,11 @@ MTAEXPORT int DoWinMain(HINSTANCE hLauncherInstance, HINSTANCE hPrevInstance, LP // Maybe show help if trouble was encountered ProcessPendingBrowseToSolution(); - AddReportLog(1044, SString("* End (0x%X)* pid:%d", iReturnCode, GetCurrentProcessId())); + // Get current process ID for logging + DWORD currentPid = GetSafeProcessId(); + + const DWORD exitCodeForLog = static_cast(static_cast(iReturnCode)); + AddReportLog(LOG_ID_END, SString("* End (0x%08X)* pid:%lu", exitCodeForLog, static_cast(currentPid))); - RemoveUtf8FileHooks(); return iReturnCode; } diff --git a/Client/loader/Main.h b/Client/loader/Main.h index a24661b3f52..56ad748234b 100644 --- a/Client/loader/Main.h +++ b/Client/loader/Main.h @@ -18,16 +18,24 @@ #define MTA_GUID "Global\\{4962AF5F-5D82-412D-9CCA-AB8BB9DBD353}" #define URI_CONNECT 1 #define MTA_EXE_NAME_RELEASE "Multi Theft Auto.exe" -#define LOADER_PROXY_DLL_NAME "mtasa.dll" #ifdef MTA_DEBUG - #define MTA_EXE_NAME "Multi Theft Auto_d.exe" - #define MTA_DLL_NAME "core_d.dll" - #define CHECK_DM_LUA_NAME "mods\\deathmatch\\lua5.1c_d.dll" - #define CHECK_DM_CLIENT_NAME "mods\\deathmatch\\Client_d.dll" + #define MTA_EXE_NAME "Multi Theft Auto_d.exe" + #define MTA_DLL_NAME "core_d.dll" + #define CHECK_DM_LUA_NAME "mods\\deathmatch\\lua5.1c_d.dll" + #define CHECK_DM_CLIENT_NAME "mods\\deathmatch\\Client_d.dll" + #define LOADER_PROXY_DLL_NAME "mtasa_d.dll" + #define MAETRO32_DLL_NAME "maetro32_d.dll" #else - #define MTA_EXE_NAME "Multi Theft Auto.exe" - #define MTA_DLL_NAME "core.dll" - #define CHECK_DM_LUA_NAME "mods\\deathmatch\\lua5.1c.dll" - #define CHECK_DM_CLIENT_NAME "mods\\deathmatch\\Client.dll" + #define MTA_EXE_NAME "Multi Theft Auto.exe" + #define MTA_DLL_NAME "core.dll" + #define CHECK_DM_LUA_NAME "mods\\deathmatch\\lua5.1c.dll" + #define CHECK_DM_CLIENT_NAME "mods\\deathmatch\\Client.dll" + #define LOADER_PROXY_DLL_NAME "mtasa.dll" + #define MAETRO32_DLL_NAME "maetro32.dll" +#endif + +#ifndef MTA_MAETRO + #undef MAETRO32_DLL_NAME + #define MAETRO32_DLL_NAME __COMPILE_ERROR_YOU_ARE_NOT_SUPPOSED_TO_USE_THIS__ #endif diff --git a/Client/loader/MainFunctions.cpp b/Client/loader/MainFunctions.cpp index 838853bcaaf..94f9ebc62f9 100644 --- a/Client/loader/MainFunctions.cpp +++ b/Client/loader/MainFunctions.cpp @@ -8,15 +8,422 @@ * *****************************************************************************/ +#include "Wine.h" #include "MainFunctions.h" #include "Main.h" #include "Utils.h" #include "Dialogs.h" #include "D3DStuff.h" +#include "../core/FastFailCrashHandler/WerCrashHandler.h" #include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#pragma comment(lib, "dbghelp.lib") +// Function must be at the start to fix odd compile error (Didn't happen locally but does in build server) +namespace +{ + bool ValidatePath(const SString& path) + { + // Placeholder + return true; + } +} + +[[nodiscard]] static bool IsCrashExitCode(DWORD exitCode) noexcept +{ + constexpr DWORD kLegacyCrashExitCode = 3; + + if (exitCode == kLegacyCrashExitCode) + return true; + + if (exitCode == EXIT_OK || exitCode == EXIT_ERROR || exitCode == STILL_ACTIVE) + return false; + + const DWORD kInformationalCrashCodes[] = { + 0x40000015u, // STATUS_FATAL_APP_EXIT + 0x40010004u, // DBG_TERMINATE_PROCESS + }; + + if (std::any_of(std::begin(kInformationalCrashCodes), std::end(kInformationalCrashCodes), [exitCode](DWORD code) { return exitCode == code; })) + { + return true; + } + + return (exitCode & 0x80000000u) != 0u; +} + +[[nodiscard]] static bool IsFailFastException(DWORD exceptionCode) noexcept +{ + return exceptionCode == 0xC0000409 || exceptionCode == 0xC0000374; +} + +[[nodiscard]] static bool IsHighIntegrityModule(const SString& moduleName) noexcept +{ + const char* szFileName = PathFindFileNameA(moduleName.c_str()); + return _stricmp(szFileName, "netc.dll") == 0 || _stricmp(szFileName, "core.dll") == 0 || _stricmp(szFileName, "client.dll") == 0; +} + +struct DebuggerCrashCapture +{ + DWORD exceptionCode = 0; + DWORD threadId = 0; + CONTEXT threadContext{}; + bool captured = false; + SString dumpPath; + ModuleCrashInfo moduleInfo; // Resolved at capture time while process is alive +}; + +static void WriteFailFastDump(HANDLE hProcess, DWORD processId, DWORD threadId, PEXCEPTION_RECORD pExceptionRecord, PCONTEXT pContext, + DebuggerCrashCapture& capture) +{ + SString dumpDir = CalcMTASAPath("mta\\dumps\\private"); + MakeSureDirExists(dumpDir + "/"); + + SYSTEMTIME st; + GetLocalTime(&st); + SString dumpFile = SString("failfast_%04d%02d%02d_%02d%02d%02d.dmp", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + SString dumpPath = PathJoin(dumpDir, dumpFile); + + HANDLE hFile = CreateFileA(dumpPath, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (hFile == INVALID_HANDLE_VALUE) + { + WriteDebugEvent(SString("Failed to create dump file: %s (error %lu)", dumpPath.c_str(), GetLastError())); + return; + } + + MINIDUMP_EXCEPTION_INFORMATION mei{}; + EXCEPTION_POINTERS ep{}; + ep.ExceptionRecord = pExceptionRecord; + ep.ContextRecord = pContext; + mei.ThreadId = threadId; + mei.ExceptionPointers = &ep; + mei.ClientPointers = FALSE; + + BOOL success = MiniDumpWriteDump(hProcess, processId, hFile, MiniDumpNormal, &mei, nullptr, nullptr); + CloseHandle(hFile); + + if (success) + { + capture.dumpPath = dumpPath; + WriteDebugEvent(SString("Fail-fast dump saved: %s", dumpPath.c_str())); + AddReportLog(3148, SString("Loader captured fail-fast dump: %s", dumpFile.c_str())); + } + else + { + DeleteFileA(dumpPath); + WriteDebugEvent(SString("MiniDumpWriteDump failed: %lu", GetLastError())); + } +} + +using FileTimeDuration = std::chrono::duration>; + +[[nodiscard]] static FileTimeDuration FileTimeToDuration(const FILETIME& value) noexcept +{ + const auto combined = (static_cast(value.dwHighDateTime) << 32) | value.dwLowDateTime; + return FileTimeDuration{static_cast(combined)}; +} + +using WerDumpResult = WerCrash::WerDumpResult; + +[[nodiscard]] static WerDumpResult FindAndRenameWerDump(const SString& moduleName, DWORD offset, DWORD exceptionCode, + const std::optional& processCreationTime) +{ + const SString dumpDir = CalcMTASAPath("mta\\dumps\\private"); + WerDumpResult result = WerCrash::FindAndRenameWerDump(dumpDir, moduleName, offset, exceptionCode, processCreationTime); + + if (!result.path.empty()) + { + SetApplicationSetting("diagnostics", "last-dump-save", result.path); + SetApplicationSetting("diagnostics", "last-dump-complete", "1"); + WriteDebugEvent(SString("WER crash dump queued for upload: %s", ExtractFilename(result.path).c_str())); + } + + if (!result.sourceFilename.empty()) + SetApplicationSetting("diagnostics", "last-wer-dump-shown", result.sourceFilename); + + return result; +} + +static DWORD RunDebuggerLoop(HANDLE hProcess, DWORD processId, DebuggerCrashCapture& capture) +{ + DEBUG_EVENT debugEvent{}; + DWORD continueStatus = DBG_CONTINUE; + DWORD exitCode = 0; + bool processExited = false; + + // Stuck detection + constexpr uint STARTUP_GRACE_TIMEOUTS = 20; + uint timeoutCount = 0; + bool startupStuckHandled = false; + bool quitStuckHandled = false; + + std::optional startupStuckDetector; + std::optional quitStuckDetector; + + while (!processExited) + { + if (!WaitForDebugEvent(&debugEvent, 1000)) + { + if (GetLastError() == ERROR_SEM_TIMEOUT) + { + ++timeoutCount; + + // Don't count timeouts while the device selection dialog is open + if (!startupStuckHandled && timeoutCount <= STARTUP_GRACE_TIMEOUTS && timeoutCount > 1 && IsDeviceSelectionDialogOpen(processId)) + --timeoutCount; + + // Startup stuck: check after grace period, once only + if (!startupStuckHandled && timeoutCount > STARTUP_GRACE_TIMEOUTS && WatchDogIsSectionOpen("L3")) + { + if (!startupStuckDetector) + startupStuckDetector.emplace(hProcess, 5000); + + if (startupStuckDetector->UpdateIsStuck()) + { + WriteDebugEvent("Detected stuck process at startup (one-shot debugger mode)"); + startupStuckHandled = true; + if (MessageBoxUTF8(0, _("GTA: San Andreas may not have launched correctly. Terminate it?"), _("Information") + _E("CL25"), + MB_YESNO | MB_ICONQUESTION | MB_TOPMOST) == IDYES) + { + TerminateProcess(hProcess, 1); + } + } + } + + // Quit stuck: Q0 is open (core shutting down) + if (!WatchDogIsSectionOpen("L3") && WatchDogIsSectionOpen("Q0")) + { + if (!quitStuckDetector) + quitStuckDetector.emplace(hProcess, 5000); + + if (!quitStuckHandled && quitStuckDetector->UpdateIsStuck()) + { + WriteDebugEvent("Detected stuck process at quit (one-shot debugger mode)"); + quitStuckHandled = true; +#ifndef MTA_DEBUG + TerminateProcess(hProcess, 1); +#endif + } + } + + continue; + } + break; + } + + continueStatus = DBG_CONTINUE; + + switch (debugEvent.dwDebugEventCode) + { + case EXCEPTION_DEBUG_EVENT: + { + DWORD exCode = debugEvent.u.Exception.ExceptionRecord.ExceptionCode; + + if (debugEvent.u.Exception.dwFirstChance) + { + if (IsFailFastException(exCode) && !capture.captured) + { + capture.exceptionCode = exCode; + capture.threadId = debugEvent.dwThreadId; + + HANDLE hThread = OpenThread(THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, debugEvent.dwThreadId); + if (hThread) + { + capture.threadContext.ContextFlags = CONTEXT_ALL; + if (GetThreadContext(hThread, &capture.threadContext)) + { + capture.captured = true; + + // Resolve crash address to module NOW while process is still alive + // This provides fallback if registry-based resolution fails + capture.moduleInfo = ResolveModuleCrashAddress(capture.threadContext.Eip, hProcess); + + // Do not collect a dump or store registers for high-integrity module crashes. + // These are deliberate security fastfails. + if (!IsHighIntegrityModule(capture.moduleInfo.moduleName)) + { + WriteFailFastDump(hProcess, processId, debugEvent.dwThreadId, &debugEvent.u.Exception.ExceptionRecord, + &capture.threadContext, capture); + } + else + { + capture.threadContext = {}; + } + + WriteDebugEvent( + SString("Captured fail-fast 0x%08X: EIP=0x%08X ESP=0x%08X", exCode, capture.threadContext.Eip, capture.threadContext.Esp)); + } + CloseHandle(hThread); + } + } + continueStatus = DBG_EXCEPTION_NOT_HANDLED; + } + else + { + continueStatus = DBG_EXCEPTION_NOT_HANDLED; + } + break; + } + + case EXIT_PROCESS_DEBUG_EVENT: + exitCode = debugEvent.u.ExitProcess.dwExitCode; + processExited = true; + break; + + case CREATE_PROCESS_DEBUG_EVENT: + if (debugEvent.u.CreateProcessInfo.hFile) + CloseHandle(debugEvent.u.CreateProcessInfo.hFile); + break; + + case LOAD_DLL_DEBUG_EVENT: + if (debugEvent.u.LoadDll.hFile) + CloseHandle(debugEvent.u.LoadDll.hFile); + break; + + default: + break; + } + + ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, continueStatus); + } + + return exitCode; +} + +enum class CrashArtifactState : unsigned char +{ + Missing, + Stale, + Fresh, +}; + +constexpr auto kCrashArtifactStaleTolerance = std::chrono::seconds(2); +static constexpr std::size_t kCrashArtifactCount = 3; + +[[nodiscard]] static constexpr const char* CrashArtifactStateToString(CrashArtifactState state) noexcept +{ + switch (state) + { + case CrashArtifactState::Fresh: + return "fresh"; + case CrashArtifactState::Stale: + return "stale"; + default: + return "missing"; + } +} + +[[nodiscard]] static CrashArtifactState InspectCrashArtifact(const SString& path, const std::optional& processCreationTime) noexcept +{ + WIN32_FILE_ATTRIBUTE_DATA attributes{}; + if (!GetFileAttributesExA(path.c_str(), GetFileExInfoStandard, &attributes)) + return CrashArtifactState::Missing; + + if (!processCreationTime.has_value()) + return CrashArtifactState::Fresh; + + if (const auto lastWrite = FileTimeToDuration(attributes.ftLastWriteTime); lastWrite + kCrashArtifactStaleTolerance < *processCreationTime) + return CrashArtifactState::Stale; + + return CrashArtifactState::Fresh; +} + +////////////////////////////////////////////////////////// +// +// CheckLibVersions +// +// Check lib versions are correct +// +////////////////////////////////////////////////////////// +void CheckLibVersions() +{ +#if MTASA_VERSION_TYPE >= VERSION_TYPE_UNTESTED + const char* moduleList[] = {"MTA\\loader.dll", + "MTA\\cgui.dll", + "MTA\\core.dll", + "MTA\\game_sa.dll", + "MTA\\multiplayer_sa.dll", + "MTA\\netc.dll", + "MTA\\xmll.dll", + "MTA\\game_sa.dll", + "MTA\\" LOADER_PROXY_DLL_NAME, + "mods\\deathmatch\\client.dll", + "mods\\deathmatch\\pcre3.dll"}; + + SString strReqFileVersion; + for (uint i = 0; i < NUMELMS(moduleList); i++) + { + SString strFilename = moduleList[i]; + // Skip _d suffix for LOADER_PROXY_DLL_NAME and netc.dll as they don't use _d + if (strFilename.find(LOADER_PROXY_DLL_NAME) == std::string::npos && strFilename.find("netc.dll") == std::string::npos) + { + #ifdef MTA_DEBUG + strFilename = ExtractBeforeExtension(strFilename) + "_d." + ExtractExtension(strFilename); + #endif + } + SString fullPath = CalcMTASAPath(strFilename); + if (!ValidatePath(fullPath)) + { + DisplayErrorMessageBox(SStringX(_("Invalid module path detected.\n") + SString("\n[%s]\n", *strFilename)), _E("CL49"), "invalid-module-path"); + ExitProcess(EXIT_ERROR); + } + + SLibVersionInfo fileInfo; + if (FileExists(fullPath)) + { + SString strFileVersion = "0.0.0.0"; + if (GetLibVersionInfo(fullPath, &fileInfo)) + { + // Validate version numbers + if (fileInfo.dwFileVersionMS > 0 && fileInfo.dwFileVersionMS < MAXDWORD && fileInfo.dwFileVersionLS > 0 && fileInfo.dwFileVersionLS < MAXDWORD) + { + strFileVersion = SString("%d.%d.%d.%d", fileInfo.dwFileVersionMS >> 16, fileInfo.dwFileVersionMS & 0xFFFF, fileInfo.dwFileVersionLS >> 16, + fileInfo.dwFileVersionLS & 0xFFFF); + } + } + + if (strReqFileVersion.empty()) + { + strReqFileVersion = strFileVersion; + } + else if (strReqFileVersion != strFileVersion) + { + DisplayErrorMessageBox(SStringX(_("File version mismatch error. Reinstall MTA:SA if you experience problems.\n") + + SString("\n[%s %s/%s]\n", *strFilename, *strFileVersion, *strReqFileVersion)), + _E("CL40"), "bad-file-version"); + break; + } + } + else + { + DisplayErrorMessageBox(SStringX(_("Some files are missing. Reinstall MTA:SA if you experience problems.\n") + SString("\n[%s]\n", *strFilename)), + _E("CL41"), "missing-file"); + break; + } + } +#endif + + // Check for Windows 'Safe Mode' + if (GetSystemMetrics(SM_CLEANBOOT) != 0) + { + DisplayErrorMessageBox(SStringX(_("MTA:SA is not compatible with Windows 'Safe Mode'.\n\nPlease restart your PC.\n")), _E("CL42"), "safe-mode"); + ExitProcess(EXIT_ERROR); + } +} + +// Enum declarations for WSC health DECLARE_ENUM(WSC_SECURITY_PROVIDER_HEALTH) IMPLEMENT_ENUM_BEGIN(WSC_SECURITY_PROVIDER_HEALTH) ADD_ENUM(WSC_SECURITY_PROVIDER_HEALTH_GOOD, "good") @@ -25,21 +432,22 @@ ADD_ENUM(WSC_SECURITY_PROVIDER_HEALTH_POOR, "poor") ADD_ENUM(WSC_SECURITY_PROVIDER_HEALTH_SNOOZE, "snooze") IMPLEMENT_ENUM_END("wsc_health") -class CLocalizationDummy : public CLocalizationInterface +// Simplified localization dummy class +class CLocalizationDummy final : public CLocalizationInterface { public: - virtual SString Translate(const SString& strMessage) { return strMessage; } - virtual SString TranslateWithContext(const SString& strContext, const SString& strMessage) { return strMessage; } - virtual SString TranslatePlural(const SString& strSingular, const SString& strPlural, int iNum) { return strPlural; } - virtual SString TranslatePluralWithContext(const SString& strContext, const SString& strSingular, const SString& strPlural, int iNum) { return strPlural; } - - virtual std::vector GetAvailableLocales() { return std::vector(); } - virtual bool IsLocalized() { return false; } - virtual SString GetLanguageDirectory(CLanguage* pLanguage = nullptr) { return ""; } - virtual SString GetLanguageCode() { return "en_US"; } - virtual SString GetLanguageName() { return "English"; } + SString Translate(const SString& strMessage) override { return strMessage; } + SString TranslateWithContext(const SString& strContext, const SString& strMessage) override { return strMessage; } + SString TranslatePlural(const SString& strSingular, const SString& strPlural, int iNum) override { return strPlural; } + SString TranslatePluralWithContext(const SString& strContext, const SString& strSingular, const SString& strPlural, int iNum) override { return strPlural; } + std::vector GetAvailableLocales() override { return {}; } + bool IsLocalized() override { return false; } + SString GetLanguageDirectory(CLanguage* pLanguage = nullptr) override { return ""; } + SString GetLanguageCode() override { return "en_US"; } + SString GetLanguageName() override { return "English"; } }; +// Global localization interface CLocalizationInterface* g_pLocalization = new CLocalizationDummy(); ////////////////////////////////////////////////////////// @@ -51,239 +459,139 @@ CLocalizationInterface* g_pLocalization = new CLocalizationDummy(); ////////////////////////////////////////////////////////// void InitLocalization(bool bShowErrors) { - static bool bDone = false; - if (bDone) + static bool bInitialized = false; + if (bInitialized) return; - // Check for and load core.dll for localization - // Use launch relative path so core.dll can get updated - SString strCoreDLL = PathJoin(GetLaunchPath(), "mta", MTA_DLL_NAME); + const SString strLaunchPath = GetLaunchPath(); + + // Check for core.dll + const SString strCoreDLL = PathJoin(strLaunchPath, "mta", MTA_DLL_NAME); if (!FileExists(strCoreDLL)) { if (!bShowErrors) return; - DisplayErrorMessageBox(("Load failed. Please ensure that " - "the file " MTA_DLL_NAME " is in the modules " - "directory within the MTA root directory."), - _E("CL23"), "core-missing"); // Core.dll missing - - return ExitProcess(EXIT_ERROR); + DisplayErrorMessageBox("Load failed. Please ensure that the file " MTA_DLL_NAME " is in the modules directory within the MTA root directory.", + _E("CL23"), "core-missing"); + ExitProcess(EXIT_ERROR); } - // Use registry setting of mta path for dlls, as they will not be present in update files + // Setup DLL search paths const SString strMTASAPath = GetMTASAPath(); SetDllDirectory(PathJoin(strMTASAPath, "mta")); - DWORD dwPrevMode = SetErrorMode(SEM_FAILCRITICALERRORS); - // See if xinput is loadable (core.dll dependency) - for (const SString& strModuleName : std::vector({"XInput9_1_0", "xinput1_3"})) + // See if xinput is loadable (XInput9_1_0.dll or xinput1_3.dll) + const DWORD dwPrevMode = SetErrorMode(SEM_FAILCRITICALERRORS); + const char* xinputModules[] = {"XInput9_1_0", "xinput1_3"}; + + for (uint i = 0; i < NUMELMS(xinputModules); ++i) { - HMODULE hXInputModule = LoadLibrary(strModuleName + ".dll"); + SString strDllName = SString("%s.dll", xinputModules[i]); + + HMODULE hXInputModule = LoadLibrary(strDllName); if (hXInputModule) { - FreeLibrary(hXInputModule); + FreeLibrary(hXInputModule); // Exists already - no need to copy } else { - // If xinput is not loadable, do hack to use dll supplied with MTA - SString strDest = PathJoin(strMTASAPath, "mta", strModuleName + ".dll"); + // Try to copy from our directory + const SString strDest = PathJoin(strMTASAPath, "mta", strDllName); if (!FileExists(strDest)) { - SString strSrc = PathJoin(strMTASAPath, "mta", strModuleName + "_mta.dll"); + SString strSrc = PathJoin(strMTASAPath, "mta", SString("%s_mta.dll", xinputModules[i])); if (!FileExists(strSrc)) { - // dll might only exist in launch directory during auto-update - strSrc = PathJoin(GetLaunchPath(), "mta", strModuleName + "_mta.dll"); + strSrc = PathJoin(strLaunchPath, "mta", SString("%s_mta.dll", xinputModules[i])); } FileCopy(strSrc, strDest); } } } - // Check if the core can be loaded - failure may mean d3dx9_40.dll etc is not installed - // Use LOAD_WITH_ALTERED_SEARCH_PATH so the strCoreDLL path is searched first for dependent dlls + // Load core.dll if (bShowErrors) SetErrorMode(dwPrevMode); HMODULE hCoreModule = LoadLibraryEx(strCoreDLL, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); SetErrorMode(dwPrevMode); - if (hCoreModule == NULL) + + if (!hCoreModule) { if (!bShowErrors) return; -#ifdef MTA_DEBUG - DisplayErrorMessageBox(("Loading core failed. Please ensure that \n" - "the latest DirectX is correctly installed and you executed win-install-data.bat"), - _E("CL24"), "core-not-loadable"); -#else - DisplayErrorMessageBox(("Loading core failed. Please ensure that \n" - "the latest DirectX is correctly installed."), - _E("CL24"), "core-not-loadable"); -#endif - return ExitProcess(EXIT_ERROR); + DisplayErrorMessageBox("Loading core failed. Please ensure that the latest DirectX is correctly installed.", _E("CL24"), "core-not-loadable"); + ExitProcess(EXIT_ERROR); } - // Grab our locale from the registry if possible, if not Windows + LoaderResolveCrashHandlerExports(hCoreModule); + + // Get locale SString strLocale = GetApplicationSetting("locale"); if (strLocale.empty()) { - setlocale(LC_ALL, ""); - char* szLocale = setlocale(LC_ALL, NULL); - strLocale = szLocale; - } + // Get system locale + char originalLocale[256] = {0}; + if (const char* locale = setlocale(LC_ALL, NULL)) + { + strncpy(originalLocale, locale, sizeof(originalLocale) - 1); + originalLocale[sizeof(originalLocale) - 1] = '\0'; + } - typedef CLocalizationInterface*(__cdecl * FUNC_CREATELOCALIZATIONFROMENVIRONMENT)(SString strLocale); - FUNC_CREATELOCALIZATIONFROMENVIRONMENT pFunc = (FUNC_CREATELOCALIZATIONFROMENVIRONMENT)GetProcAddress(hCoreModule, "L10n_CreateLocalization"); - CLocalizationInterface* pLocalization = pFunc(strLocale); - if (pLocalization == NULL) - { - if (!bShowErrors) - return; + setlocale(LC_ALL, ""); + if (const char* newLocale = setlocale(LC_ALL, NULL)) + { + strLocale = newLocale; + } - DisplayErrorMessageBox(("Loading localization failed. Please ensure that \n" - "the latest DirectX is correctly installed."), - _E("CL26"), "localization-not-loadable"); - FreeLibrary(hCoreModule); - return ExitProcess(EXIT_ERROR); + // Restore original locale + if (originalLocale[0]) + { + setlocale(LC_ALL, originalLocale); + } } - SAFE_DELETE(g_pLocalization); - g_pLocalization = pLocalization; - bDone = true; + // Create localization interface + typedef CLocalizationInterface*(__cdecl * CreateLocalizationFunc)(SString); + auto pFunc = reinterpret_cast(static_cast(GetProcAddress(hCoreModule, "L10n_CreateLocalization"))); -#ifdef MTA_DEBUG - TestDialogs(); -#endif -} - -////////////////////////////////////////////////////////// -// -// HandleSpecialLaunchOptions -// -// Check and handle commands (from the installer) -// -////////////////////////////////////////////////////////// -void HandleSpecialLaunchOptions() -{ - // Handle service install request from the installer - if (CommandLineContains("/kdinstall")) + if (!pFunc) { - UpdateMTAVersionApplicationSetting(true); - WatchDogReset(); - WatchDogBeginSection(WD_SECTION_POST_INSTALL); - if (CheckService(CHECK_SERVICE_POST_INSTALL)) - return ExitProcess(EXIT_OK); - return ExitProcess(EXIT_ERROR); - } - - // Handle service uninstall request from the installer - if (CommandLineContains("/kduninstall")) - { - UpdateMTAVersionApplicationSetting(true); - if (CheckService(CHECK_SERVICE_PRE_UNINSTALL)) - return ExitProcess(EXIT_OK); - return ExitProcess(EXIT_ERROR); + FreeLibrary(hCoreModule); + if (bShowErrors) + { + DisplayErrorMessageBox("Loading localization failed. Please ensure that MTA San Andreas 1.6\\MTA\\locale is accessible.", _E("CL26"), + "localization-not-loadable"); + } + return; } - // No run 4 sure check - if (CommandLineContains("/nolaunch")) + CLocalizationInterface* pLocalization = pFunc(strLocale); + if (!pLocalization) { - return ExitProcess(EXIT_OK); + FreeLibrary(hCoreModule); + if (bShowErrors) + { + DisplayErrorMessageBox("Loading localization failed. Please ensure that MTA San Andreas 1.6\\MTA\\locale is accessible.", _E("CL26"), + "localization-not-loadable"); + } + return; } -} -////////////////////////////////////////////////////////// -// -// HandleDuplicateLaunching -// -// Handle duplicate launching, or running from mtasa:// URI ? -// -////////////////////////////////////////////////////////// -void HandleDuplicateLaunching() -{ - LPSTR lpCmdLine = GetCommandLine(); + // Replace the dummy localization with the real one + SAFE_DELETE(g_pLocalization); + g_pLocalization = pLocalization; + // NOTE: hCoreModule is intentionally kept loaded as it contains the localization implementation + bInitialized = true; - int iRecheckTimeLimit = 2000; - while (!CreateSingleInstanceMutex()) - { - if (strcmp(lpCmdLine, "") != 0) - { - HWND hwMTAWindow = FindWindow(NULL, "MTA: San Andreas"); #ifdef MTA_DEBUG - if (hwMTAWindow == NULL) - hwMTAWindow = FindWindow(NULL, "MTA: San Andreas [DEBUG]"); + TestDialogs(); #endif - if (hwMTAWindow != NULL) - { - LPWSTR szCommandLine = GetCommandLineW(); - int numArgs; - LPWSTR* aCommandLineArgs = CommandLineToArgvW(szCommandLine, &numArgs); - for (int i = 1; i < numArgs; ++i) - { - if (WStringX(aCommandLineArgs[i]).BeginsWith(L"mtasa://")) - { - WString wideConnectInfo = aCommandLineArgs[i]; - SString strConnectInfo = ToUTF8(wideConnectInfo); - - COPYDATASTRUCT cdStruct; - cdStruct.cbData = strConnectInfo.length() + 1; - cdStruct.lpData = const_cast(strConnectInfo.c_str()); - cdStruct.dwData = URI_CONNECT; - - SendMessage(hwMTAWindow, WM_COPYDATA, NULL, (LPARAM)&cdStruct); - break; - } - } - } - else - { - if (iRecheckTimeLimit > 0) - { - // Sleep a little bit and check the mutex again - Sleep(500); - iRecheckTimeLimit -= 500; - continue; - } - SString strMessage; - strMessage += - _("Trouble restarting MTA:SA\n\n" - "If the problem persists, open Task Manager and\n" - "stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" - "Try to launch MTA:SA again?"); - if (MessageBoxUTF8(0, strMessage, _("Error") + _E("CL04"), MB_ICONWARNING | MB_YESNO | MB_TOPMOST) == - IDYES) // Trouble restarting MTA:SA - { - TerminateGTAIfRunning(); - TerminateOtherMTAIfRunning(); - ShellExecuteNonBlocking("open", PathJoin(GetMTASAPath(), MTA_EXE_NAME), lpCmdLine); - } - return ExitProcess(EXIT_ERROR); - } - } - else - { - if (!IsGTARunning() && !IsOtherMTARunning()) - { - MessageBoxUTF8(0, _("Another instance of MTA is already running.\n\nIf this problem persists, please restart your computer"), - _("Error") + _E("CL05"), MB_ICONERROR | MB_TOPMOST); - } - else if (MessageBoxUTF8(0, _("Another instance of MTA is already running.\n\nDo you want to terminate it?"), _("Error") + _E("CL06"), - MB_ICONQUESTION | MB_YESNO | MB_TOPMOST) == IDYES) - { - TerminateGTAIfRunning(); - TerminateOtherMTAIfRunning(); - ShellExecuteNonBlocking("open", PathJoin(GetMTASAPath(), MTA_EXE_NAME), lpCmdLine); - } - } - return ExitProcess(EXIT_ERROR); - } } ////////////////////////////////////////////////////////// // // HandleTrouble // -// -// ////////////////////////////////////////////////////////// void HandleTrouble() { @@ -304,8 +612,6 @@ void HandleTrouble() // // HandleResetSettings // -// -// ////////////////////////////////////////////////////////// void HandleResetSettings() { @@ -330,7 +636,7 @@ void HandleResetSettings() FileRename(strSettingsFilename, strSettingsFilenameBak); FileDelete(strSettingsFilename); - // Also reset NVidia Optimus "remember option" to allow them to choose again + // Also reset NVidia Optimus "remember option" SetApplicationSettingInt("nvhacks", "optimus-remember-option", 0); if (!FileExists(strSettingsFilename)) @@ -362,27 +668,28 @@ void HandleResetSettings() // // HandleNotUsedMainMenu // -// Called when a problem occured before the main menu was used by user -// If fullscreen, then maybe change fullscreen mode +// Changes to window mode if fullscreen and not used the main menu much // ////////////////////////////////////////////////////////// void HandleNotUsedMainMenu() { AddReportLog(9310, "Loader - HandleNotUsedMainMenu"); + + // Check current display mode in coreconfig.xml { - // Slighty hacky way of checking in-game settings SString strCoreConfigFilename = CalcMTASAPath(PathJoin("mta", "config", "coreconfig.xml")); SString strCoreConfig; FileLoad(strCoreConfigFilename, strCoreConfig); SString strWindowed = strCoreConfig.SplitRight("").Left(1); SString strFullscreenStyle = strCoreConfig.SplitRight("").Left(1); + if (strFullscreenStyle == "1") { AddReportLog(9315, "Loader - HandleNotUsedMainMenu - Already Borderless window"); } else if (!strWindowed.empty() && !strFullscreenStyle.empty()) { - if (strWindowed == "0" && strFullscreenStyle == "0") // 0=FULLSCREEN_STANDARD + if (strWindowed == "0" && strFullscreenStyle == "0") { // Inform user SString strMessage = _("Are you having problems running MTA:SA?.\n\nDo you want to change the following setting?"); @@ -391,16 +698,20 @@ void HandleNotUsedMainMenu() int iResponse = MessageBoxUTF8(NULL, strMessage, "MTA: San Andreas", MB_YESNO | MB_ICONQUESTION | MB_TOPMOST); if (iResponse == IDYES) { - // Very hacky way of changing in-game settings + // Change to borderless window mode strCoreConfig = strCoreConfig.Replace("0", "1"); FileSave(strCoreConfigFilename, strCoreConfig); AddReportLog(9311, "Loader - HandleNotUsedMainMenu - User change to Borderless window"); } else + { AddReportLog(9313, "Loader - HandleNotUsedMainMenu - User said no"); + } } else + { AddReportLog(9314, "Loader - HandleNotUsedMainMenu - Mode not fullscreen standard"); + } } else { @@ -411,7 +722,7 @@ void HandleNotUsedMainMenu() } } - // Check if problem processes are active + // Check for problem processes struct { std::vector matchTextList; @@ -419,24 +730,50 @@ void HandleNotUsedMainMenu() const char* szTrouble; } procItems[] = {{{"\\Evolve"}, "Evolve", "not-used-menu-evolve"}, {{"\\GbpSv.exe", "Diebold\\Warsaw"}, "GAS Tecnologia - G-Buster Browser Defense", "not-used-menu-gbpsv"}}; - for (uint i = 0; i < NUMELMS(procItems); i++) + + bool foundProblemProcess = false; + const size_t MAX_PROCESS_CHECKS = 100; + size_t processesChecked = 0; + + for (uint i = 0; i < NUMELMS(procItems) && !foundProblemProcess; i++) { - for (auto processId : MyEnumProcesses(true)) + auto processList = MyEnumProcesses(true); + + if (processList.size() > 1000) + { + WriteDebugEvent("Too many processes to check"); + break; + } + + for (auto processId : processList) { + if (++processesChecked > MAX_PROCESS_CHECKS) + { + WriteDebugEvent("Process check limit reached in HandleNotUsedMainMenu"); + break; + } + SString strProcessFilename = GetProcessPathFilename(processId); - for (auto strMatchText : procItems[i].matchTextList) + + // Validate process path + if (!strProcessFilename.empty() && strProcessFilename.length() < MAX_PATH) { - if (strProcessFilename.ContainsI(strMatchText)) + for (const auto& strMatchText : procItems[i].matchTextList) { - SString strMessage = _("Are you having problems running MTA:SA?.\n\nTry disabling the following products for GTA and MTA:"); - strMessage += "\n\n"; - strMessage += procItems[i].szProductName; - DisplayErrorMessageBox(strMessage, _E("CL43"), procItems[i].szTrouble); - goto done; + if (strProcessFilename.ContainsI(strMatchText)) + { + SString strMessage = _("Are you having problems running MTA:SA?.\n\nTry disabling the following products for GTA and MTA:"); + strMessage += "\n\n"; + strMessage += procItems[i].szProductName; + DisplayErrorMessageBox(strMessage, _E("CL43"), procItems[i].szTrouble); + foundProblemProcess = true; + break; + } } } + if (foundProblemProcess) + break; } - done:; } } @@ -444,8 +781,6 @@ void HandleNotUsedMainMenu() // // HandleCustomStartMessage // -// -// ////////////////////////////////////////////////////////// void HandleCustomStartMessage() { @@ -471,47 +806,140 @@ void HandleCustomStartMessage() DisplayErrorMessageBox(strStartMessage, _E("CL37"), strTrouble); } +////////////////////////////////////////////////////////// +// +// ConfigureWerDumpPath +// +// Configure Windows Error Reporting to save crash dumps to MTA's folder. +// This is critical for capturing fail-fast crashes (0xC0000409, 0xC0000374) +// that bypass normal exception handling. +// Called early in loader before core.dll is loaded. +// +////////////////////////////////////////////////////////// +void ConfigureWerDumpPath() +{ + using WerRegisterAppLocalDumpFn = HRESULT(WINAPI*)(PCWSTR); + + const SString strInstallPath = GetInstallPathForLauncher(); + if (strInstallPath.empty()) + return; + + // Build dump path: \MTA\dumps\private + std::wstring dumpPathW = FromUTF8(PathJoin(strInstallPath, "MTA", "dumps", "private")); + + SString mtaDumpPath = UTF16ToMbUTF8(dumpPathW); + if (mtaDumpPath.empty()) + return; + + MakeSureDirExists(mtaDumpPath + "/"); + + bool loaderConfigured = false; + + HMODULE hWer = LoadLibraryW(L"wer.dll"); + if (hWer) + { + WerRegisterAppLocalDumpFn pfnWerRegisterAppLocalDump = nullptr; + const auto procAddr = GetProcAddress(hWer, "WerRegisterAppLocalDump"); + static_assert(sizeof(pfnWerRegisterAppLocalDump) == sizeof(procAddr), "Unexpected function pointer size"); + if (procAddr) + std::memcpy(&pfnWerRegisterAppLocalDump, &procAddr, sizeof(pfnWerRegisterAppLocalDump)); + + if (pfnWerRegisterAppLocalDump) + { + loaderConfigured = SUCCEEDED(pfnWerRegisterAppLocalDump(dumpPathW.c_str())); + } + FreeLibrary(hWer); + } + + // WerRegisterAppLocalDump only affects current process and doesn't work for desktop apps anyway. + // Always use registry fallback for gta_sa.exe (child process), and for Multi Theft Auto.exe + // if WerRegisterAppLocalDump failed. + // Note: WER LocalDumps only reads from HKLM, not HKCU (per Microsoft documentation). + // Without admin privileges, we cannot update HKLM and stale entries from previous installs may persist. + const wchar_t* exeNames[] = {L"gta_sa.exe", loaderConfigured ? nullptr : L"Multi Theft Auto.exe"}; + + for (const wchar_t* exeName : exeNames) + { + if (!exeName) + continue; + + SString regSubPath = SString("SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\LocalDumps\\%S", exeName); + std::wstring regSubPathW = MbUTF8ToUTF16(regSubPath); + + HKEY hKey = nullptr; + // Use KEY_WOW64_64KEY to write to the 64-bit registry view. + // WER is a 64-bit system service that reads from the native 64-bit registry, + // not the WOW6432Node that 32-bit apps normally access. + LONG result = RegCreateKeyExW(HKEY_LOCAL_MACHINE, regSubPathW.c_str(), 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE | KEY_WOW64_64KEY, nullptr, + &hKey, nullptr); + if (result == ERROR_SUCCESS) + { + DWORD dumpType = 1; + RegSetValueExW(hKey, L"DumpType", 0, REG_DWORD, reinterpret_cast(&dumpType), sizeof(dumpType)); + + DWORD dumpCount = 10; + RegSetValueExW(hKey, L"DumpCount", 0, REG_DWORD, reinterpret_cast(&dumpCount), sizeof(dumpCount)); + + RegSetValueExW(hKey, L"DumpFolder", 0, REG_EXPAND_SZ, reinterpret_cast(dumpPathW.c_str()), + static_cast((dumpPathW.length() + 1) * sizeof(wchar_t))); + + RegCloseKey(hKey); + } + } +} + ////////////////////////////////////////////////////////// // // PreLaunchWatchDogs // +// Various checks to alert the user to problems which will make MTA not work correctly +// Some checks are cumulative triggers. i.e. they only trigger after a certain number of failures. +// +// Commands are often stored in the registry by the installer and client. +// +// "L0" is opened before the launch sequence and is closed if MTA shutsdown with no error +// "L1" is opened before the launch sequence and is closed if GTA is succesfully started +// "CR1" is a counter which is incremented if GTA was not started and MTA shutsdown with an error // +// "L2" is opened before the launch sequence and is closed if the GTA loading screen is shown +// "CR2" is a counter which is incremented at startup, if the previous run didn't make it to the loading screen +// +// "L3" is opened before the launch sequence and is closed if the GTA loading screen is shown, or a startup problem is handled elsewhere // ////////////////////////////////////////////////////////// void PreLaunchWatchDogs() { - assert(!CreateSingleInstanceMutex()); - - // - // "L0" is opened before the launch sequence and is closed if MTA shutsdown with no error - // "L1" is opened before the launch sequence and is closed if GTA is succesfully started - // "CR1" is a counter which is incremented if GTA was not started and MTA shutsdown with an error - // - // "L2" is opened before the launch sequence and is closed if the GTA loading screen is shown - // "CR2" is a counter which is incremented at startup, if the previous run didn't make it to the loading screen - // - // "L3" is opened before the launch sequence and is closed if the GTA loading screen is shown, or a startup problem is handled elsewhere - // + // Note: Single instance mutex is properly checked later in the launch sequence + // Creating it here just ensures we acquire it early, but we shouldn't assert + // because after a crash the mutex won't exist (OS releases it) + CreateSingleInstanceMutex(); // Check for unclean stop on previous run #ifndef MTA_DEBUG if (WatchDogIsSectionOpen("L0")) { - WatchDogSetUncleanStop(true); // Flag to maybe do things differently if MTA exit code on last run was not 0 + WatchDogSetUncleanStop(true); // Flag to maybe do things differently if MTA exit code on last run was not 0 CheckAndShowFileOpenFailureMessage(); } else #endif WatchDogSetUncleanStop(false); + // Check if crash dump file exists from the game SString strCrashFlagFilename = CalcMTASAPath("mta\\core.log.flag"); if (FileExists(strCrashFlagFilename)) { FileDelete(strCrashFlagFilename); - WatchDogSetLastRunCrash(true); // Flag to maybe do things differently if MTA crashed last run + WatchDogSetLastRunCrash(true); // Flag to maybe do things differently if MTA crashed last run } else + { WatchDogSetLastRunCrash(false); + } + + // Note: WER dump detection for fail-fast crashes (0xC0000409, 0xC0000374) is now + // handled in CInstallManager::_CheckForWerCrash() which runs during the sequencer, + // before this function is called. // Reset counter if gta game was run last time if (!WatchDogIsSectionOpen("L1")) @@ -527,11 +955,13 @@ void PreLaunchWatchDogs() // Check for possible gta_sa.set problems if (WatchDogIsSectionOpen("L2")) { - WatchDogIncCounter("CR2"); // Did not reach loading screen last time + WatchDogIncCounter("CR2"); WatchDogCompletedSection("L2"); } else + { WatchDogClearCounter("CR2"); + } // If didn't reach loading screen 5 times in a row, do something if (WatchDogGetCounter("CR2") >= 5) @@ -545,11 +975,12 @@ void PreLaunchWatchDogs() { int iChainLimit; if (WatchDogIsSectionOpen(WD_SECTION_POST_INSTALL)) - iChainLimit = 1; + iChainLimit = 1; // Low limit if just installed else if (GetApplicationSettingInt("times-connected") == 0) - iChainLimit = 2; + iChainLimit = 2; // Medium limit if have never connected in the past else - iChainLimit = 3; + iChainLimit = 3; // Normal limit + WatchDogCompletedSection(WD_SECTION_NOT_USED_MAIN_MENU); WatchDogIncCounter(WD_COUNTER_CRASH_CHAIN_BEFORE_USED_MAIN_MENU); if (WatchDogGetCounter(WD_COUNTER_CRASH_CHAIN_BEFORE_USED_MAIN_MENU) >= iChainLimit) @@ -559,13 +990,15 @@ void PreLaunchWatchDogs() } } else + { WatchDogClearCounter(WD_COUNTER_CRASH_CHAIN_BEFORE_USED_MAIN_MENU); + } // Clear down freeze on quit detection WatchDogCompletedSection("Q0"); - WatchDogBeginSection("L0"); // Gets closed if MTA exits with a return code of 0 - WatchDogBeginSection("L1"); // Gets closed when online game has started + WatchDogBeginSection("L0"); // Gets closed if MTA exits with a return code of 0 + WatchDogBeginSection("L1"); // Gets closed when GTA is launched SetApplicationSetting("diagnostics", "gta-fopen-fail", ""); SetApplicationSetting("diagnostics", "last-crash-reason", ""); SetApplicationSetting("diagnostics", "last-crash-module", ""); @@ -577,8 +1010,6 @@ void PreLaunchWatchDogs() // // PostRunWatchDogs // -// -// ////////////////////////////////////////////////////////// void PostRunWatchDogs(int iReturnCode) { @@ -610,11 +1041,189 @@ void HandleIfGTAIsAlreadyRunning() { MessageBoxUTF8(0, _("Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer."), _("Information") + _E("CL11"), MB_OK | MB_ICONERROR | MB_TOPMOST); - return ExitProcess(EXIT_ERROR); + ExitProcess(EXIT_ERROR); + } + } + else + { + ExitProcess(EXIT_OK); + } + } +} + +////////////////////////////////////////////////////////// +// +// HandleSpecialLaunchOptions +// +// Check and handle commands (from the installer) +// +////////////////////////////////////////////////////////// +void HandleSpecialLaunchOptions() +{ + // Handle service install request from the installer + if (CommandLineContains("/kdinstall")) + { + UpdateMTAVersionApplicationSetting(true); + WatchDogReset(); + WatchDogBeginSection(WD_SECTION_POST_INSTALL); + ExitProcess(CheckService(CHECK_SERVICE_POST_INSTALL) ? EXIT_OK : EXIT_ERROR); + } + + // Handle service uninstall request from the installer + if (CommandLineContains("/kduninstall")) + { + UpdateMTAVersionApplicationSetting(true); + ExitProcess(CheckService(CHECK_SERVICE_PRE_UNINSTALL) ? EXIT_OK : EXIT_ERROR); + } + + // No run 4 sure check + if (CommandLineContains("/nolaunch")) + { + ExitProcess(EXIT_OK); + } +} + +////////////////////////////////////////////////////////// +// +// HandleDuplicateLaunching +// +// Handle duplicate launching, or running from mtasa:// URI +// +////////////////////////////////////////////////////////// +void HandleDuplicateLaunching() +{ + LPSTR lpCmdLine = GetCommandLine(); + if (!lpCmdLine) + ExitProcess(EXIT_ERROR); + + // Validate command line length + const size_t cmdLineLen = strlen(lpCmdLine); + if (cmdLineLen >= 32768) + ExitProcess(EXIT_ERROR); // Max Windows command line length + + bool bIsCrashDialog = (cmdLineLen > 0 && strstr(lpCmdLine, "install_stage=crashed") != NULL); + bool bIsDetachedDialog = bIsCrashDialog; + + int recheckTime = 2000; // 2 seconds recheck time + + // We can only do certain things if MTA is already running + // Unless this is a crash dialog launch, which needs to run alongside the crashed instance + // + // Normal behavior: Loop here if mutex is held, try to pass command line to existing instance + // Crash dialog: Skip this entirely (bIsCrashDialog=true), proceed directly to showing dialog + while (!bIsDetachedDialog && !CreateSingleInstanceMutex()) + { + if (cmdLineLen > 0) + { + // Command line args present, so pass it on + HWND hwMTAWindow = FindWindow(NULL, "MTA: San Andreas"); +#ifdef MTA_DEBUG + if (!hwMTAWindow) + hwMTAWindow = FindWindow(NULL, "MTA: San Andreas [DEBUG]"); +#endif + + if (hwMTAWindow) + { + // Parse URI from command line + LPWSTR szCommandLine = GetCommandLineW(); + if (!szCommandLine) + continue; + + int numArgs = 0; + LPWSTR* aCommandLineArgs = CommandLineToArgvW(szCommandLine, &numArgs); + + if (aCommandLineArgs && numArgs > 0 && numArgs < 1000) + { + for (int i = 1; i < numArgs; ++i) + { + if (!aCommandLineArgs[i]) + continue; + + WString wideArg = aCommandLineArgs[i]; + if (wideArg.length() > 8 && wideArg.length() < 2048 && // Max MTA connect URI length + WStringX(wideArg).BeginsWith(L"mtasa://")) + { + SString strConnectInfo = ToUTF8(wideArg); + // Check for null bytes and validate content + if (strConnectInfo.find('\0') != SString::npos) + continue; + + // Additional validation for mtasa:// URI content + if (strConnectInfo.Contains("..") || strConnectInfo.Contains("\\\\")) + continue; + + COPYDATASTRUCT cdStruct = {URI_CONNECT, static_cast(strConnectInfo.length() + 1), const_cast(strConnectInfo.c_str())}; + + // Use SendMessageTimeout to prevent hanging + DWORD_PTR dwResult = 0; + SendMessageTimeout(hwMTAWindow, WM_COPYDATA, NULL, reinterpret_cast(&cdStruct), SMTO_ABORTIFHUNG | SMTO_BLOCK, 5000, + &dwResult); + break; + } + } + LocalFree(aCommandLineArgs); + } + ExitProcess(EXIT_ERROR); + } + else if (recheckTime > 0) + { + Sleep(500); + recheckTime -= 500; + continue; + } + else + { + const SString strMessage = + _("Trouble restarting MTA:SA\n\n" + "If the problem persists, open Task Manager and\n" + "stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" + "Try to launch MTA:SA again?"); + + if (MessageBoxUTF8(0, strMessage, _("Error") + _E("CL04"), MB_ICONWARNING | MB_YESNO | MB_TOPMOST) == IDYES) + { + TerminateGTAIfRunning(); + TerminateOtherMTAIfRunning(); + + const SString exePath = PathJoin(GetMTASAPath(), MTA_EXE_NAME); + if (FileExists(exePath)) + { + ShellExecuteNonBlocking("open", exePath, lpCmdLine); + } + } + ExitProcess(EXIT_ERROR); } } else - return ExitProcess(EXIT_OK); + { + // No command line args, so just bring to front + if (!IsGTARunning() && !IsOtherMTARunning()) + { + MessageBoxUTF8(0, + _("Another instance of MTA is already running.\n\n" + "If this problem persists, please restart your computer"), + _("Error") + _E("CL05"), MB_ICONERROR | MB_TOPMOST); + } + else if (MessageBoxUTF8(0, + _("Another instance of MTA is already running.\n\n" + "Do you want to terminate it?"), + _("Error") + _E("CL06"), MB_ICONQUESTION | MB_YESNO | MB_TOPMOST) == IDYES) + { + TerminateGTAIfRunning(); + TerminateOtherMTAIfRunning(); + + const SString exePath = PathJoin(GetMTASAPath(), MTA_EXE_NAME); + if (FileExists(exePath)) + { + ShellExecuteNonBlocking("open", exePath, lpCmdLine); + } + } + ExitProcess(EXIT_ERROR); + } + } + + if (bIsCrashDialog) + { + CreateSingleInstanceMutex(); } } @@ -622,35 +1231,38 @@ void HandleIfGTAIsAlreadyRunning() // // ValidateGTAPath // -// Check GTA path looks good +// Ensure we have a valid GTA path // ////////////////////////////////////////////////////////// void ValidateGTAPath() { // Get path to GTA - ePathResult iResult = DiscoverGTAPath(true); - if (iResult == GAME_PATH_MISSING) + const ePathResult result = DiscoverGTAPath(true); + + if (result == GAME_PATH_MISSING) { DisplayErrorMessageBox(_("Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas."), _E("CL12"), "reg-entries-missing"); - return ExitProcess(EXIT_ERROR); + ExitProcess(EXIT_ERROR); } - else if (iResult == GAME_PATH_UNICODE_CHARS) + else if (result == GAME_PATH_UNICODE_CHARS) { - DisplayErrorMessageBox( - _("The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas " - "installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas."), - _E("CL13")); - return ExitProcess(EXIT_ERROR); + DisplayErrorMessageBox(_("The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. " + "Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains " + "only standard ASCII characters and reinstall Multi Theft Auto: San Andreas."), + _E("CL13")); + ExitProcess(EXIT_ERROR); } const SString strGTAPath = GetGTAPath(); const SString strMTASAPath = GetMTASAPath(); + + // Check for semicolon in install path (causes problems) if (strGTAPath.Contains(";") || strMTASAPath.Contains(";")) { DisplayErrorMessageBox(_("The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" - " If you experience problems when running MTA:SA,\n" - " move your installation(s) to a path that does not contain a semicolon."), + "If you experience problems when running MTA:SA,\n" + "move your installation(s) to a path that does not contain a semicolon."), _E("CL15"), "path-semicolon"); } } @@ -664,108 +1276,159 @@ void ValidateGTAPath() ////////////////////////////////////////////////////////// void CheckAntiVirusStatus() { - // Get data from WMI - std::vector enabledList; - std::vector disabledList; + if (Wine::IsRunningOnWine()) + { + WriteDebugEvent("Skipping AV check under Wine"); + return; + } + + std::vector enabledList, disabledList; GetWMIAntiVirusStatus(enabledList, disabledList); - // Get status from WSC - WSC_SECURITY_PROVIDER_HEALTH health = (WSC_SECURITY_PROVIDER_HEALTH)-1; + if (enabledList.size() > 100) + enabledList.resize(100); + if (disabledList.size() > 100) + disabledList.resize(100); + + WSC_SECURITY_PROVIDER_HEALTH health = static_cast(-1); + + // Get windows defender status + static const auto WscGetHealth = []() -> decltype(&WscGetSecurityProviderHealth) { - using FunctionT = decltype(&WscGetSecurityProviderHealth); + if (HMODULE wscapi = LoadLibraryW(L"Wscapi.dll")) + { + return reinterpret_cast(reinterpret_cast(GetProcAddress(wscapi, "WscGetSecurityProviderHealth"))); + } + return nullptr; + }(); - static auto _WscGetSecurityProviderHealth = ([]() -> FunctionT { - if (HMODULE wscapi = LoadLibraryW(L"Wscapi.dll")) - { - return reinterpret_cast(static_cast(GetProcAddress(wscapi, "WscGetSecurityProviderHealth"))); - } + if (WscGetHealth) + { + WscGetHealth(WSC_SECURITY_PROVIDER_ANTIVIRUS, &health); + } - return nullptr; - })(); + SString strStatus; + strStatus.reserve(512); // Pre-allocate to prevent reallocation + strStatus += SString("AV health: %s (%d)", *EnumToString(health), static_cast(health)); - if (_WscGetSecurityProviderHealth) - _WscGetSecurityProviderHealth(WSC_SECURITY_PROVIDER_ANTIVIRUS, &health); + const size_t maxStatusItems = 10; + for (size_t i = 0; i < enabledList.size() && i < maxStatusItems; ++i) + { + if (strStatus.length() > 400) + break; // Prevent status string from growing too large + strStatus += SString(" [Ena%zu:%s]", i, *enabledList[i]); + } + for (size_t i = 0; i < disabledList.size() && i < maxStatusItems; ++i) + { + if (strStatus.length() > 400) + break; // Prevent status string from growing too large + strStatus += SString(" [Dis%zu:%s]", i, *disabledList[i]); } - // Dump results - SString strStatus("AV health: %s (%d)", *EnumToString(health), health); - for (uint i = 0; i < enabledList.size(); i++) - strStatus += SString(" [Ena%d:%s]", i, *enabledList[i]); - for (uint i = 0; i < disabledList.size(); i++) - strStatus += SString(" [Dis%d:%s]", i, *disabledList[i]); WriteDebugEvent(strStatus); - // Maybe show dialog if av not found if (enabledList.empty() && health != WSC_SECURITY_PROVIDER_HEALTH_GOOD) { - bool bEnableScaremongering = (health != WSC_SECURITY_PROVIDER_HEALTH_NOTMONITORED); + bool showWarning = (health != WSC_SECURITY_PROVIDER_HEALTH_NOTMONITORED); - if (bEnableScaremongering) + if (showWarning) { - const char* avProducts[] = { - "antivirus", "anti-virus", "Avast", "AVG", "Avira", "NOD32", "ESET", "F-Secure", - "Faronics", "Kaspersky", "McAfee", "Norton", "Symantec", "Panda", "Trend Micro", - }; + // Check for AV in loaded modules + static const char* avProducts[] = {"antivirus", "anti-virus", "Avast", "AVG", "Avira", "NOD32", "ESET", "F-Secure", + "Faronics", "Kaspersky", "McAfee", "Norton", "Symantec", "Panda", "Trend Micro"}; - // Check for anti-virus helper dlls before actual scaremongering - HMODULE aModules[1024]; - DWORD cbNeeded; - if (EnumProcessModules(GetCurrentProcess(), aModules, sizeof(aModules), &cbNeeded)) + // Check for AV in loaded modules + std::array modules; + DWORD cbNeeded; + + if (EnumProcessModules(GetCurrentProcess(), modules.data(), static_cast(sizeof(modules)), &cbNeeded)) { - DWORD cModules = cbNeeded / sizeof(HMODULE); - for (uint i = 0; i < cModules; i++) + DWORD moduleCount = cbNeeded / sizeof(HMODULE); + const DWORD maxModules = static_cast(modules.size()); + + if (cbNeeded > 0 && cbNeeded < MAXDWORD && (cbNeeded % sizeof(HMODULE)) == 0) { - if (aModules[i] != 0) + if (moduleCount > maxModules) + { + WriteDebugEvent(SString("Warning: Process has %lu modules but array can only hold %lu", moduleCount, maxModules)); + moduleCount = maxModules; + } + + for (DWORD i = 0; i < moduleCount && showWarning; ++i) { - WCHAR szModulePathFileName[1024] = L""; - GetModuleFileNameExW(GetCurrentProcess(), aModules[i], szModulePathFileName, NUMELMS(szModulePathFileName)); - SLibVersionInfo libVersionInfo; - GetLibVersionInfo(ToUTF8(szModulePathFileName), &libVersionInfo); + if (!modules[i]) + continue; + + WCHAR modulePath[MAX_PATH * 2] = L""; + DWORD pathLen = GetModuleFileNameExW(GetCurrentProcess(), modules[i], modulePath, NUMELMS(modulePath) - 1); - for (uint i = 0; i < NUMELMS(avProducts); i++) + // Ensure null-termination + if (pathLen > 0 && pathLen < NUMELMS(modulePath)) { - if (libVersionInfo.strCompanyName.ContainsI(avProducts[i]) || libVersionInfo.strProductName.ContainsI(avProducts[i])) + modulePath[pathLen] = L'\0'; + + SLibVersionInfo libInfo; + if (GetLibVersionInfo(ToUTF8(modulePath), &libInfo)) { - bEnableScaremongering = false; - WriteDebugEvent(SString("AV (module) maybe found %s [%d](%s,%s)", *WStringX(szModulePathFileName).ToAnsi(), i, - *libVersionInfo.strCompanyName, *libVersionInfo.strProductName)); + for (uint j = 0; j < NUMELMS(avProducts); ++j) + { + if (libInfo.strCompanyName.ContainsI(avProducts[j]) || libInfo.strProductName.ContainsI(avProducts[j])) + { + showWarning = false; + WriteDebugEvent(SString("AV (module) found: %s", *ToUTF8(modulePath))); + break; + } + } } } } } - - if (bEnableScaremongering) - WriteDebugEvent(SString("AV Searched %d dlls, but could not find av helper", cModules)); + else + { + WriteDebugEvent("Invalid module enumeration result"); + } } - if (bEnableScaremongering) + // Check for running processes for AV + if (showWarning) { - for (auto processId : MyEnumProcesses(true)) + auto processList = MyEnumProcesses(true); + + const size_t maxProcessesToCheck = 500; + size_t processesChecked = 0; + + for (auto processId : processList) { - SString strProcessPathFileName = GetProcessPathFilename(processId); - if (!strProcessPathFileName.empty()) + if (++processesChecked > maxProcessesToCheck) + { + WriteDebugEvent("Process check limit reached"); + break; + } + + SString processPath = GetProcessPathFilename(processId); + if (!processPath.empty() && ValidatePath(processPath)) { - SLibVersionInfo libVersionInfo; - if (GetLibVersionInfo(strProcessPathFileName, &libVersionInfo)) + SLibVersionInfo libInfo; + if (GetLibVersionInfo(processPath, &libInfo)) { - for (uint i = 0; i < NUMELMS(avProducts); i++) + for (uint i = 0; i < NUMELMS(avProducts); ++i) { - if (libVersionInfo.strCompanyName.ContainsI(avProducts[i]) || libVersionInfo.strProductName.ContainsI(avProducts[i])) + if (libInfo.strCompanyName.ContainsI(avProducts[i]) || libInfo.strProductName.ContainsI(avProducts[i])) { - bEnableScaremongering = false; - WriteDebugEvent(SString("AV (process) maybe found %s [%d](%s,%s)", *strProcessPathFileName, i, - *libVersionInfo.strCompanyName, *libVersionInfo.strProductName)); + showWarning = false; + WriteDebugEvent(SString("AV (process) found: %s", *processPath)); + break; } } } } + if (!showWarning) + break; } - if (bEnableScaremongering) - WriteDebugEvent("AV Searched processes, but could not find av helper"); } } - ShowNoAvDialog(g_hInstance, bEnableScaremongering); + ShowNoAvDialog(g_hInstance, showWarning); HideNoAvDialog(); } } @@ -782,160 +1445,279 @@ void CheckDataFiles() const SString strMTASAPath = GetMTASAPath(); const SString strGTAPath = GetGTAPath(); - const char* dataFilesFiles[] = {"MTA\\cgui\\images\\background_logo.png", - "MTA\\cgui\\images\\radarset\\up.png", - "MTA\\cgui\\images\\busy_spinner.png", - "MTA\\data\\gta_sa_diff.dat", - "MTA\\D3DX9_42.dll", - "MTA\\D3DCompiler_42.dll", - "MTA\\d3dcompiler_43.dll", - "MTA\\d3dcompiler_47.dll", - "MTA\\bass.dll", - "MTA\\bass_ac3.dll", - "MTA\\bassflac.dll", - "MTA\\bassmix.dll", - "MTA\\basswebm.dll", - "MTA\\bass_aac.dll", - "MTA\\bass_fx.dll", - "MTA\\bassmidi.dll", - "MTA\\bassopus.dll", - "MTA\\basswma.dll", - "MTA\\tags.dll", - "MTA\\sa.dat", - "MTA\\xinput1_3_mta.dll", - "MTA\\XInput9_1_0_mta.dll"}; - - for (uint i = 0; i < NUMELMS(dataFilesFiles); i++) - { - if (!FileExists(PathJoin(strMTASAPath, dataFilesFiles[i]))) + if (!ValidatePath(strMTASAPath) || !ValidatePath(strGTAPath)) + { + DisplayErrorMessageBox(_("Invalid installation paths detected."), _E("CL45"), "invalid-install-paths"); + ExitProcess(EXIT_ERROR); + } + + // No-op known incompatible/broken d3d9.dll versions from the launch directory + // By using file version we account for variants as well. The array is extendable, but primarily for D3D9.dll 6.3.9600.17415 (MTA top 5 crash) + { + struct SIncompatibleVersion + { + int iMajor; + int iMinor; + int iBuild; + int iRelease; + }; + + static const SIncompatibleVersion incompatibleVersions[] = { + // The below entry (D3D9.dll 6.3.9600.17415) always crashes the user @ 0x0001F4B3 (CreateSurfaceLH). + // Furthermore, it's not a graphical mod or functional. Some GTA:SA distributor just placed their own, outdated Win7 DLL in the folder. + {6, 3, 9600, 17415}, + // The below entry (D3D9.dll 0.3.1.3) is a fully incompatible, modified ENB version ("DirectX 2.0") that crashes the user @ 0002A733 + {0, 3, 1, 3}, + }; + + static bool bChecked = false; + if (!bChecked) + { + bChecked = true; + + // Check all 3 game roots + const std::vector directoriesToCheck = { + GetInstallPathForLauncher(), // MTA installation folder root + strGTAPath, // Real GTA:SA installation folder root. As chosen by DiscoverGTAPath() + PathJoin(GetMTADataPath(), "GTA San Andreas"), // Proxy-mirror that MTA uses for core GTA data files (C:\ProgramData\MTA San Andreas All\\GTA San Andreas) + }; + + for (const SString& directory : directoriesToCheck) + { + if (directory.empty()) + continue; + if (!ValidatePath(directory)) + continue; + + const SString strD3dModuleFilename = PathJoin(directory, "d3d9.dll"); + if (!ValidatePath(strD3dModuleFilename) || !FileExists(strD3dModuleFilename)) + continue; + + SharedUtil::SLibVersionInfo versionInfo = {}; + if (!SharedUtil::GetLibVersionInfo(strD3dModuleFilename, &versionInfo)) + continue; + + bool bIsIncompatible = false; + for (const SIncompatibleVersion& entry : incompatibleVersions) + { + if (versionInfo.GetFileVersionMajor() == entry.iMajor && versionInfo.GetFileVersionMinor() == entry.iMinor && + versionInfo.GetFileVersionBuild() == entry.iBuild && versionInfo.GetFileVersionRelease() == entry.iRelease) + { + bIsIncompatible = true; + break; + } + } + + if (!bIsIncompatible) + continue; + + const SString strBackupModuleFilename = PathJoin(directory, "d3d9.bak.incompatible"); + const WString wideSourcePath = FromUTF8(strD3dModuleFilename); + const WString wideBackupPath = FromUTF8(strBackupModuleFilename); + + if (FileExists(strBackupModuleFilename)) + { + SetFileAttributesW(wideBackupPath.c_str(), FILE_ATTRIBUTE_NORMAL); + DeleteFileW(wideBackupPath.c_str()); + } + + SetFileAttributesW(wideSourcePath.c_str(), FILE_ATTRIBUTE_NORMAL); + + bool bRenamed = MoveFileExW(wideSourcePath.c_str(), wideBackupPath.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) != 0; + if (!bRenamed) + { + if (!CopyFileW(wideSourcePath.c_str(), wideBackupPath.c_str(), FALSE)) + continue; + + SetFileAttributesW(wideBackupPath.c_str(), FILE_ATTRIBUTE_NORMAL); + + if (!DeleteFileW(wideSourcePath.c_str())) + continue; + + bRenamed = true; + } + + if (bRenamed) + { + SetFileAttributesW(wideBackupPath.c_str(), FILE_ATTRIBUTE_NORMAL); + } + } + } + } + + // Check for essential MTA files + static const char* dataFiles[] = {"MTA\\cgui\\images\\background_logo.png", + "MTA\\cgui\\images\\radarset\\up.png", + "MTA\\cgui\\images\\busy_spinner.png", + "MTA\\data\\gta_sa_diff.dat", + "MTA\\D3DX9_42.dll", + "MTA\\D3DCompiler_42.dll", + "MTA\\d3dcompiler_43.dll", + "MTA\\d3dcompiler_47.dll", + "MTA\\bass.dll", + "MTA\\bass_ac3.dll", + "MTA\\bassflac.dll", + "MTA\\bassmix.dll", + "MTA\\basswebm.dll", + "MTA\\bass_aac.dll", + "MTA\\bass_fx.dll", + "MTA\\bassmidi.dll", + "MTA\\bassopus.dll", + "MTA\\basswma.dll", + "MTA\\tags.dll", + "MTA\\sa.dat", + "MTA\\xinput1_3_mta.dll", + "MTA\\XInput9_1_0_mta.dll"}; + + for (uint i = 0; i < NUMELMS(dataFiles); ++i) + { + const SString filePath = PathJoin(strMTASAPath, dataFiles[i]); + if (!ValidatePath(filePath) || !FileExists(filePath)) { + AddReportLog(3211, SString("CheckDataFiles: missing required file '%s' (base='%s')", filePath.c_str(), strMTASAPath.c_str())); DisplayErrorMessageBox(_("Load failed. Please ensure that the latest data files have been installed correctly."), _E("CL16"), "mta-datafiles-missing"); - return ExitProcess(EXIT_ERROR); + ExitProcess(EXIT_ERROR); } } - // Check for client file + // Check for client deathmatch module if (!FileExists(PathJoin(strMTASAPath, CHECK_DM_CLIENT_NAME))) { DisplayErrorMessageBox(SString(_("Load failed. Please ensure that %s is installed correctly."), CHECK_DM_CLIENT_NAME), _E("CL18"), "client-missing"); - return ExitProcess(EXIT_ERROR); + ExitProcess(EXIT_ERROR); } - // Make sure the gta executable exists + // Check for GTA executable if (!FileExists(PathJoin(strGTAPath, GTA_EXE_NAME)) && !FileExists(PathJoin(strGTAPath, STEAM_GTA_EXE_NAME))) { DisplayErrorMessageBox(SString(_("Load failed. Could not find gta_sa.exe in %s."), strGTAPath.c_str()), _E("CL20"), "gta_sa-missing"); - return ExitProcess(EXIT_ERROR); + ExitProcess(EXIT_ERROR); } - // Make sure important dll's do not exist in the wrong place - const char* dllCheckList[] = {"xmll.dll", "cgui.dll", "netc.dll", "libcurl.dll", "pthread.dll"}; - for (int i = 0; i < NUMELMS(dllCheckList); i++) + // Check for conflicting files + static const char* dllConflicts[] = {"xmll.dll", "cgui.dll", "netc.dll", "libcurl.dll", "pthread.dll"}; + + for (uint i = 0; i < NUMELMS(dllConflicts); ++i) { - if (FileExists(PathJoin(strGTAPath, dllCheckList[i]))) + if (FileExists(PathJoin(strGTAPath, dllConflicts[i]))) { - DisplayErrorMessageBox(SString(_("Load failed. %s exists in the GTA directory. Please delete before continuing."), dllCheckList[i]), _E("CL21"), + DisplayErrorMessageBox(SString(_("Load failed. %s exists in the GTA directory. Please delete before continuing."), dllConflicts[i]), _E("CL21"), "file-clash"); - return ExitProcess(EXIT_ERROR); + ExitProcess(EXIT_ERROR); } } // Check main exe has the correct name - if (GetLaunchFilename().CompareI(MTA_EXE_NAME) == false) - { - SString strMessage(_("Main file has an incorrect name (%s)"), *GetLaunchFilename()); - int iResponse = MessageBoxUTF8(NULL, strMessage, _("Error") + _E("CL33"), MB_RETRYCANCEL | MB_ICONERROR | MB_TOPMOST); - ReleaseSingleInstanceMutex(); - if (iResponse == IDRETRY) - ShellExecuteNonBlocking("open", PathJoin(strMTASAPath, MTA_EXE_NAME)); - return ExitProcess(EXIT_ERROR); - } - - // Check for possible virus file changing activities - if (!VerifyEmbeddedSignature(PathJoin(strMTASAPath, MTA_EXE_NAME))) + const SString launchFilename = GetLaunchFilename(); + if (!launchFilename.CompareI(MTA_EXE_NAME)) { - SString strMessage(_("Main file is unsigned. Possible virus activity.\n\nSee online help if MTA does not work correctly.")); - #if MTASA_VERSION_BUILD > 0 && defined(MTA_DM_PUBLIC_CONNECTIONS) && !defined(MTA_DEBUG) - DisplayErrorMessageBox(strMessage, _E("CL29"), "maybe-virus1"); - #endif + const SString strMessage(_("Main file has an incorrect name (%s)"), *launchFilename); + if (MessageBoxUTF8(NULL, strMessage, _("Error") + _E("CL33"), MB_RETRYCANCEL | MB_ICONERROR | MB_TOPMOST) == IDRETRY) + { + ReleaseSingleInstanceMutex(); + const SString correctExePath = PathJoin(strMTASAPath, MTA_EXE_NAME); + if (FileExists(correctExePath)) + { + ShellExecuteNonBlocking("open", correctExePath); + } + } + ExitProcess(EXIT_ERROR); } - struct + // Check for possible virus activity (simple file hash check) + struct IntegrityCheck { - const char* expected; + const char* hash; const char* fileName; - } integrityCheckList[] = {{"DE5C08577EAA65309974F9860E303F53", "bass.dll"}, {"1D5A1AEF041255DEA49CD4780CAE4CCC", "bass_aac.dll"}, - {"8A1AC2AAD7F1691943635CA42F7F2940", "bass_ac3.dll"}, {"61C38C1FD091375F2A30EC631DF337E6", "bass_fx.dll"}, - {"F47DCE69DAFAA06A55A4BC1F07F80C8A", "bassflac.dll"}, {"49A603ED114982787FC0A301C0E93FDB", "bassmidi.dll"}, - {"064398B1A74B4EF35902F0C218142133", "bassmix.dll"}, {"9CFA31A873FF89C2CC491B9974FC5C65", "bassopus.dll"}, - {"B35714019BBFF0D0CEE0AFA2637A77A7", "basswebm.dll"}, {"1507C60C02E159B5FB247FEC6B209B09", "basswma.dll"}, - {"C6A44FC3CF2F5801561804272217B14D", "D3DX9_42.dll"}, {"D439E8EDD8C93D7ADE9C04BCFE9197C6", "sa.dat"}, - {"B33B21DB610116262D906305CE65C354", "D3DCompiler_42.dll"}, {"4B3932359373F11CBC542CC96D9A9285", "tags.dll"}, - {"0B3DD892007FB366D1F52F2247C046F5", "d3dcompiler_43.dll"}, {"D5D8C8561C6DDA7EF0D7D6ABB0D772F4", "xinput1_3_mta.dll"}, - {"2C0C596EE071B93CE15130BD5EE9CD31", "d3dcompiler_47.dll"}, {"F1CA5A1E77965777AC26A81EAF345A7A", "XInput9_1_0_mta.dll"}}; + }; + + static const IntegrityCheck integrityCheckList[] = { + {"DE5C08577EAA65309974F9860E303F53", "bass.dll"}, {"1D5A1AEF041255DEA49CD4780CAE4CCC", "bass_aac.dll"}, + {"8A1AC2AAD7F1691943635CA42F7F2940", "bass_ac3.dll"}, {"61C38C1FD091375F2A30EC631DF337E6", "bass_fx.dll"}, + {"F47DCE69DAFAA06A55A4BC1F07F80C8A", "bassflac.dll"}, {"49A603ED114982787FC0A301C0E93FDB", "bassmidi.dll"}, + {"064398B1A74B4EF35902F0C218142133", "bassmix.dll"}, {"9CFA31A873FF89C2CC491B9974FC5C65", "bassopus.dll"}, + {"B35714019BBFF0D0CEE0AFA2637A77A7", "basswebm.dll"}, {"1507C60C02E159B5FB247FEC6B209B09", "basswma.dll"}, + {"C6A44FC3CF2F5801561804272217B14D", "D3DX9_42.dll"}, {"D439E8EDD8C93D7ADE9C04BCFE9197C6", "sa.dat"}, + {"B33B21DB610116262D906305CE65C354", "D3DCompiler_42.dll"}, {"4B3932359373F11CBC542CC96D9A9285", "tags.dll"}, + {"0B3DD892007FB366D1F52F2247C046F5", "d3dcompiler_43.dll"}, {"D5D8C8561C6DDA7EF0D7D6ABB0D772F4", "xinput1_3_mta.dll"}, +#ifdef MTA_MAETRO + {"E1677EC0E21E27405E65E31419980348", "d3dcompiler_47.dll"}, +#else + {"2C0C596EE071B93CE15130BD5EE9CD31", "d3dcompiler_47.dll"}, +#endif + {"F1CA5A1E77965777AC26A81EAF345A7A", "XInput9_1_0_mta.dll"}}; - for (const auto& item : integrityCheckList) + for (uint i = 0; i < NUMELMS(integrityCheckList); ++i) { - SString filePath = PathJoin(strMTASAPath, "mta", item.fileName); - - if (!FileExists(filePath)) + const IntegrityCheck& check = integrityCheckList[i]; + const SString filePath = PathJoin(strMTASAPath, "mta", check.fileName); + if (!ValidatePath(filePath) || !FileExists(filePath)) { - SString message(_("Data file %s is missing. Possible virus activity.\n\nConsider reinstalling Multi Theft Auto for your security.\nSee online " - "help if MTA does not work correctly."), - item.fileName); - DisplayErrorMessageBox(message, _E("CL30"), "maybe-virus2"); + DisplayErrorMessageBox(SString(_("Data file %s is missing. Possible virus activity."), check.fileName), _E("CL30"), "maybe-virus2"); break; } - SString computed = CMD5Hasher::CalculateHexString(filePath); - - if (!computed.CompareI(item.expected)) + const SString computed = CMD5Hasher::CalculateHexString(filePath); + if (!computed.CompareI(check.hash)) { - SString message(_("Data file %s is modified. Possible virus activity.\n\nConsider reinstalling Multi Theft Auto for your security.\nSee online " - "help if MTA does not work correctly."), - item.fileName); - DisplayErrorMessageBox(message, _E("CL30"), "maybe-virus2"); + DisplayErrorMessageBox(SString(_("Data file %s is modified. Possible virus activity."), check.fileName), _E("CL30"), "maybe-virus2"); break; } } - // Check for asi files + // Check for ASI files + std::vector gtaAsiFiles = FindFiles(PathJoin(strGTAPath, "*.asi"), true, false); + std::vector mtaAsiFiles = FindFiles(PathJoin(strMTASAPath, "mta", "*.asi"), true, false); + + const size_t MAX_ASI_FILES = 100; + bool bFoundInGTADir = !gtaAsiFiles.empty() && gtaAsiFiles.size() < MAX_ASI_FILES; + bool bFoundInMTADir = !mtaAsiFiles.empty() && mtaAsiFiles.size() < MAX_ASI_FILES; + + if (bFoundInGTADir || bFoundInMTADir) { - bool bFoundInGTADir = !FindFiles(PathJoin(strGTAPath, "*.asi"), true, false).empty(); - bool bFoundInMTADir = !FindFiles(PathJoin(strMTASAPath, "mta", "*.asi"), true, false).empty(); - if (bFoundInGTADir || bFoundInMTADir) + if (bFoundInGTADir) { - DisplayErrorMessageBox(_(".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" - "Remove these .asi files if you experience problems with MTA:SA."), - _E("CL28"), "asi-files"); + for (size_t i = 0; i < gtaAsiFiles.size() && i < 10; ++i) + { + WriteDebugEvent(SString("Warning: ASI file detected in GTA dir: %s", *gtaAsiFiles[i])); + } } + + DisplayErrorMessageBox(_(".asi files are in the installation directory.\n\n" + "Remove these .asi files if you experience problems."), + _E("CL28"), "asi-files"); } // Check for graphics libraries in the GTA/MTA install directory { - // An array of pairs of: a registry prefix and a directory path - std::array, 2> directoriesToCheck = {{{"", strGTAPath}, {"mta-", PathJoin(strMTASAPath, "mta")}}}; + const std::pair directoriesToCheck[] = {{"", strGTAPath}, {"mta-", PathJoin(strMTASAPath, "mta")}}; std::vector offenders; for (const std::pair& directory : directoriesToCheck) { + if (!ValidatePath(directory.second)) + continue; + for (const char* libraryName : {"d3d9", "dxgi"}) { GraphicsLibrary library(libraryName); library.absoluteFilePath = PathJoin(directory.second, library.stem + ".dll"); + if (library.absoluteFilePath.length() > MAX_PATH) + continue; if (!FileExists(library.absoluteFilePath)) continue; library.appLastHash = SString("%s%s-dll-last-hash", directory.first, library.stem.c_str()); library.appDontRemind = SString("%s%s-dll-not-again", directory.first, library.stem.c_str()); + library.md5Hash = CMD5Hasher::CalculateHexString(library.absoluteFilePath); WriteDebugEvent(SString("Detected graphics library %s (md5: %s)", library.absoluteFilePath.c_str(), library.md5Hash.c_str())); bool isProblematic = true; - if (GetApplicationSetting("diagnostics", library.appLastHash) == library.md5Hash) { if (GetApplicationSetting("diagnostics", library.appDontRemind) == "yes") @@ -951,88 +1733,25 @@ void CheckDataFiles() } } - if (!offenders.empty()) + if (!offenders.empty() && offenders.size() < 10) { ShowGraphicsDllDialog(g_hInstance, offenders); HideGraphicsDllDialog(); } } - // Remove old log files saved in the wrong place - SString strMtaDir = PathJoin(strMTASAPath, "mta"); - if (strGTAPath.CompareI(strMtaDir) == false) - { - FileDelete(PathJoin(strGTAPath, "CEGUI.log")); - FileDelete(PathJoin(strGTAPath, "logfile.txt")); - FileDelete(PathJoin(strGTAPath, "shutdown.log")); - } -} - -////////////////////////////////////////////////////////// -// -// CheckLibVersions -// -// Ensure DLLs are the correct version -// -////////////////////////////////////////////////////////// -void CheckLibVersions() -{ -#if MTASA_VERSION_TYPE == VERSION_TYPE_RELEASE - - const char* moduleList[] = {"MTA\\loader.dll", - "MTA\\cgui.dll", - "MTA\\core.dll", - "MTA\\game_sa.dll", - "MTA\\multiplayer_sa.dll", - "MTA\\netc.dll", - "MTA\\xmll.dll", - "MTA\\game_sa.dll", - "MTA\\" LOADER_PROXY_DLL_NAME, - "mods\\deathmatch\\client.dll", - "mods\\deathmatch\\pcre3.dll"}; - SString strReqFileVersion; - for (uint i = 0; i < NUMELMS(moduleList); i++) + // Maybe remove some unwanted files + if (!strGTAPath.CompareI(PathJoin(strMTASAPath, "mta"))) { - SString strFilename = moduleList[i]; -#ifdef MTA_DEBUG - strFilename = ExtractBeforeExtension(strFilename) + "_d." + ExtractExtension(strFilename); -#endif - SLibVersionInfo fileInfo; - if (FileExists(CalcMTASAPath(strFilename))) + static const char* logFiles[] = {"CEGUI.log", "logfile.txt", "shutdown.log"}; + for (uint i = 0; i < NUMELMS(logFiles); ++i) { - SString strFileVersion = "0.0.0.0"; - if (GetLibVersionInfo(CalcMTASAPath(strFilename), &fileInfo)) - strFileVersion = SString("%d.%d.%d.%d", fileInfo.dwFileVersionMS >> 16, fileInfo.dwFileVersionMS & 0xFFFF, fileInfo.dwFileVersionLS >> 16, - fileInfo.dwFileVersionLS & 0xFFFF); - if (strReqFileVersion.empty()) - strReqFileVersion = strFileVersion; - else if (strReqFileVersion != strFileVersion) + const SString path = PathJoin(strGTAPath, logFiles[i]); + if (ValidatePath(path)) { - DisplayErrorMessageBox(SStringX(_("File version mismatch error." - " Reinstall MTA:SA if you experience problems.\n") + - SString("\n[%s %s/%s]\n", *strFilename, *strFileVersion, *strReqFileVersion)), - _E("CL40"), "bad-file-version"); - break; + FileDelete(path); } } - else - { - DisplayErrorMessageBox(SStringX(_("Some files are missing." - " Reinstall MTA:SA if you experience problems.\n") + - SString("\n[%s]\n", *strFilename)), - _E("CL41"), "missing-file"); - break; - } - } - -#endif - - if (GetSystemMetrics(SM_CLEANBOOT) != 0) - { - DisplayErrorMessageBox(SStringX(_("MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" - "Please restart your PC.\n")), - _E("CL42"), "safe-mode"); - return ExitProcess(EXIT_ERROR); } } @@ -1041,19 +1760,30 @@ void CheckLibVersions() // StartGtaProcess // // Start GTA as an independent process +// If bAsDebugger is true, launches with DEBUG_ONLY_THIS_PROCESS flag // ////////////////////////////////////////////////////////// BOOL StartGtaProcess(const SString& lpApplicationName, const SString& lpCommandLine, const SString& lpCurrentDirectory, - LPPROCESS_INFORMATION lpProcessInformation, DWORD& dwOutError, SString& strOutErrorContext) + LPPROCESS_INFORMATION lpProcessInformation, DWORD& dwOutError, SString& strOutErrorContext, bool bAsDebugger = false) { STARTUPINFOW startupInfo{}; startupInfo.cb = sizeof(startupInfo); - BOOL wasProcessCreated = CreateProcessW(*FromUTF8(lpApplicationName), FromUTF8(lpCommandLine).data(), nullptr, nullptr, FALSE, 0, nullptr, + + DWORD creationFlags = bAsDebugger ? DEBUG_ONLY_THIS_PROCESS : 0; + + BOOL wasProcessCreated = CreateProcessW(*FromUTF8(lpApplicationName), FromUTF8(lpCommandLine).data(), nullptr, nullptr, FALSE, creationFlags, nullptr, *FromUTF8(lpCurrentDirectory), &startupInfo, lpProcessInformation); if (wasProcessCreated) return true; + if (bAsDebugger) + { + dwOutError = GetLastError(); + strOutErrorContext = "CreateProcess-Debug"; + return false; + } + std::vector processIdListBefore = GetGTAProcessList(); if (!ShellExecuteNonBlocking("open", lpApplicationName, lpCommandLine, lpCurrentDirectory)) @@ -1110,16 +1840,24 @@ BOOL StartGtaProcess(const SString& lpApplicationName, const SString& lpCommandL ////////////////////////////////////////////////////////// int LaunchGame(SString strCmdLine) { + WriteDebugEvent(SString("[7206] Loader - LaunchGame entry, cmdLine='%s'", strCmdLine.c_str())); + CheckAndShowModelProblems(); CheckAndShowUpgradeProblems(); CheckAndShowImgProblems(); const SString strGTAPath = GetGTAPath(); const SString strMTASAPath = GetMTASAPath(); - SString strMtaDir = PathJoin(strMTASAPath, "mta"); - SString strGTAEXEPath = GetGameExecutablePath().u8string(); + const SString strGTAEXEPath = UTF8FilePath(GetGameExecutablePath()); + + if (!ValidatePath(strGTAPath) || !ValidatePath(strMTASAPath) || !ValidatePath(strGTAEXEPath)) + { + DisplayErrorMessageBox(_("Invalid game paths detected."), _E("CL44"), "invalid-paths"); + return 5; + } + + SetDllDirectory(PathJoin(strMTASAPath, "mta")); - SetDllDirectory(strMtaDir); if (!CheckService(CHECK_SERVICE_PRE_CREATE) && !IsUserAdmin()) { RelaunchAsAdmin(strCmdLine, _("Fix configuration issue")); @@ -1130,45 +1868,80 @@ int LaunchGame(SString strCmdLine) BeginD3DStuff(); LogSettings(); - WatchDogBeginSection("L2"); // Gets closed when loading screen is shown - WatchDogBeginSection("L3"); // Gets closed when loading screen is shown, or a startup problem is handled elsewhere - WatchDogBeginSection(WD_SECTION_NOT_USED_MAIN_MENU); // Gets closed when the main menu is used + WatchDogBeginSection("L2"); // Gets closed when loading screen is shown + WatchDogBeginSection("L3"); // Gets closed when loading screen is shown, or a startup problem is handled elsewhere + WatchDogBeginSection(WD_SECTION_NOT_USED_MAIN_MENU); // Gets closed when the main menu is used // Extract 'done-admin' flag from command line - bool bDoneAdmin = strCmdLine.Contains("/done-admin"); - strCmdLine = strCmdLine.Replace(" /done-admin", ""); + SString sanitizedCmdLine = strCmdLine; + const bool bDoneAdmin = sanitizedCmdLine.Contains("/done-admin"); + sanitizedCmdLine = sanitizedCmdLine.Replace(" /done-admin", ""); + + // Validate command line length + if (sanitizedCmdLine.length() > 2048) // Max MTA connect URI length + { + sanitizedCmdLine = sanitizedCmdLine.Left(2048); + } // Add server connection after update to command line - SString strPostUpdateConnect = GetPostUpdateConnect(); - if (!strPostUpdateConnect.empty() && strCmdLine.empty()) - strCmdLine = SString("mtasa://%s", *strPostUpdateConnect); + const SString strPostUpdateConnect = GetPostUpdateConnect(); + if (!strPostUpdateConnect.empty() && sanitizedCmdLine.empty() && strPostUpdateConnect.length() < 512) + { + sanitizedCmdLine = SString("mtasa://%s", *strPostUpdateConnect); + } - // - // Launch GTA - // - PROCESS_INFORMATION piLoadee = {0}; - DWORD dwError; - SString strErrorContext; - if (FALSE == StartGtaProcess(strGTAEXEPath, strCmdLine, strGTAPath, &piLoadee, dwError, strErrorContext)) + // Launch GTA using CreateProcess + // Note: Our Debugger mode (DEBUG_ONLY_THIS_PROCESS) can capture fail-fast crashes + // (like 0xC0000374, 0xC0000409, Subcode: 0x7 FAST_FAIL_FATAL_APP_EXIT, "abort" signal @ minkernel\crts\ucrt\src\appcrt\startup\abort.cpp) + // .. with full context, but it interferes with core.dll's normal crash handler. Only enable for diagnostics. + PROCESS_INFORMATION piLoadee = {}; + DWORD dwError = 0; + SString strErrorContext; + bool bLaunchedAsDebugger = false; + DebuggerCrashCapture debugCapture{}; + +#ifndef MTA_DEBUG + const SString debuggerFlagValue = GetApplicationSetting("diagnostics", "debugger-crash-capture"); + const bool bUseDebuggerMode = (debuggerFlagValue == "1"); + + WriteDebugEvent(SString("[7200] Loader - Debugger flag check: value='%s' useDebugger=%d", debuggerFlagValue.c_str(), bUseDebuggerMode ? 1 : 0)); + + if (bUseDebuggerMode) { - WriteDebugEvent(SString("Loader - Process not created[%d (%s)]: %s", dwError, *strErrorContext, *strGTAEXEPath)); + // Clear the one-shot flag before attempting launch, so a loader crash can't leave it stuck + SetApplicationSetting("diagnostics", "debugger-crash-capture", ""); - if (dwError == ERROR_ELEVATION_REQUIRED && !bDoneAdmin) + WriteDebugEvent("Loader - Debugger crash capture was requested (one-shot)"); + AddReportLog(7201, "Loader - Attempting debugger launch for fail-fast capture"); + + if (StartGtaProcess(strGTAEXEPath, sanitizedCmdLine, strGTAPath, &piLoadee, dwError, strErrorContext, true)) { - // Try to relaunch as admin if not done so already - RelaunchAsAdmin(strCmdLine + " /done-admin", _("Fix elevation required error")); - ExitProcess(EXIT_OK); + bLaunchedAsDebugger = true; + WriteDebugEvent("Loader - Launched as debugger for fail-fast crash detection (diagnostic mode)"); + AddReportLog(7202, "Loader - Debugger launch successful"); } else { - // Otherwise, show error message - SString strError = GetSystemErrorMessage(dwError) + " (" + strErrorContext + ")"; - DisplayErrorMessageBox(SString(_("Could not start Grand Theft Auto: San Andreas. " - "Please try restarting, or if the problem persists," - "contact MTA at www.multitheftauto.com. \n\n[%s]"), - *strError), - _E("CL22"), "createprocess-fail&err=" + strError); // Could not start GTA:SA - return 5; + WriteDebugEvent(SString("Loader - Debugger launch FAILED: %s error %d", strErrorContext.c_str(), dwError)); + AddReportLog(7203, SString("Loader - Debugger launch failed: %s error %d, falling back to normal launch", strErrorContext.c_str(), dwError)); + } + } +#endif + + if (!bLaunchedAsDebugger && !StartGtaProcess(strGTAEXEPath, sanitizedCmdLine, strGTAPath, &piLoadee, dwError, strErrorContext, false)) + { + // Handle process creation failure + SString strError = SString("Failed to launch GTA: San Andreas. [%s: %d]", *strErrorContext, dwError); + DisplayErrorMessageBox(strError, _E("CL50"), "gta-launch-failed"); + return 5; + } + + std::optional gtaCreationTime; + if (HANDLE processHandle = piLoadee.hProcess; processHandle && processHandle != INVALID_HANDLE_VALUE) + { + if (FILETIME ftCreate{}, ftExit{}, ftKernel{}, ftUser{}; GetProcessTimes(processHandle, &ftCreate, &ftExit, &ftKernel, &ftUser)) + { + gtaCreationTime = FileTimeToDuration(ftCreate); } } @@ -1178,78 +1951,97 @@ int LaunchGame(SString strCmdLine) // Clear previous on quit commands SetOnQuitCommand(""); - ShowSplash(g_hInstance); // Bring splash to the front + // Show splash screen + ShowSplash(g_hInstance); - if (piLoadee.hProcess) - { - WriteDebugEvent("Loader - Waiting for L3 to close"); + // Wait for game to launch + DWORD dwExitCode = static_cast(-1); + if (piLoadee.hProcess && piLoadee.hProcess != INVALID_HANDLE_VALUE) + { BsodDetectionOnGameBegin(); - // Show splash until game window is displayed (or max 20 seconds) - DWORD status; - for (uint i = 0; i < 20; i++) + + if (bLaunchedAsDebugger) { - status = WaitForSingleObject(piLoadee.hProcess, 1000); - if (status != WAIT_TIMEOUT) - break; + HideSplash(); + WriteDebugEvent("Loader - Running debugger loop for crash capture"); + dwExitCode = RunDebuggerLoop(piLoadee.hProcess, piLoadee.dwProcessId, debugCapture); - if (!WatchDogIsSectionOpen("L3")) // Gets closed when loading screen is shown + if (debugCapture.captured) { - WriteDebugEvent("Loader - L3 closed"); - break; + WriteDebugEvent(SString("Loader - Captured fail-fast crash 0x%08X", debugCapture.exceptionCode)); } - - // Keep showing splash if the device selection dialog is open - if (IsDeviceSelectionDialogOpen(piLoadee.dwProcessId)) + } + else + { + // Wait for game window + DWORD status = WAIT_TIMEOUT; + for (uint i = 0; i < 20 && status == WAIT_TIMEOUT; ++i) // Max 20 iterations { - i--; + status = WaitForSingleObject(piLoadee.hProcess, 1000); // 1 second timeout + + if (!WatchDogIsSectionOpen("L3")) // Gets closed when loading screen is shown + { + WriteDebugEvent("Loader - L3 closed"); + break; + } + + // Check for device selection dialog + if (IsDeviceSelectionDialogOpen(piLoadee.dwProcessId) && i > 0) + { + --i; // Don't count this iteration + Sleep(100); + } } - } - // Actually hide the splash - HideSplash(); + HideSplash(); - // If hasn't shown the loading screen and gta_sa.exe process memory usage is not changing, give user option to terminate - if (status == WAIT_TIMEOUT) - { - CStuckProcessDetector stuckProcessDetector(piLoadee.hProcess, 5000); - while (status == WAIT_TIMEOUT && WatchDogIsSectionOpen("L3")) // Gets closed when loading screen is shown + // Handle process if stuck at startup + if (status == WAIT_TIMEOUT) { - if (stuckProcessDetector.UpdateIsStuck()) + CStuckProcessDetector detector(piLoadee.hProcess, 5000); + while (status == WAIT_TIMEOUT && WatchDogIsSectionOpen("L3")) // Gets closed when loading screen is shown { - WriteDebugEvent("Detected stuck process at startup"); - if (MessageBoxUTF8(0, _("GTA: San Andreas may not have launched correctly. Do you want to terminate it?"), _("Information") + _E("CL25"), - MB_YESNO | MB_ICONQUESTION | MB_TOPMOST) == IDYES) + if (detector.UpdateIsStuck()) { - WriteDebugEvent("User selected process termination"); - TerminateProcess(piLoadee.hProcess, 1); + WriteDebugEvent("Detected stuck process at startup"); + if (MessageBoxUTF8(0, _("GTA: San Andreas may not have launched correctly. Terminate it?"), _("Information") + _E("CL25"), + MB_YESNO | MB_ICONQUESTION | MB_TOPMOST) == IDYES) + { + TerminateProcess(piLoadee.hProcess, 1); + } + break; } - break; + status = WaitForSingleObject(piLoadee.hProcess, 1000); // 1 second timeout } - status = WaitForSingleObject(piLoadee.hProcess, 1000); } - } - - // Wait for game to exit - WriteDebugEvent("Loader - Wait for game to exit"); - while (status == WAIT_TIMEOUT) - { - status = WaitForSingleObject(piLoadee.hProcess, 1500); - // If core is closing and gta_sa.exe process memory usage is not changing, terminate - CStuckProcessDetector stuckProcessDetector(piLoadee.hProcess, 5000); - while (status == WAIT_TIMEOUT && WatchDogIsSectionOpen("Q0")) // Gets closed when quit has completed + // Wait for game to exit + WriteDebugEvent("Loader - Wait for game to exit"); + while (status == WAIT_TIMEOUT) { - if (stuckProcessDetector.UpdateIsStuck()) + status = WaitForSingleObject(piLoadee.hProcess, 1500); + + // If core is closing and gta_sa.exe process memory usage is not changing, terminate + CStuckProcessDetector detector(piLoadee.hProcess, 5000); + while (status == WAIT_TIMEOUT && WatchDogIsSectionOpen("Q0")) // Gets closed when quit is detected as frozen { - WriteDebugEvent("Detected stuck process at quit"); - #ifndef MTA_DEBUG - TerminateProcess(piLoadee.hProcess, 1); - status = WAIT_FAILED; - break; - #endif + if (detector.UpdateIsStuck()) + { + WriteDebugEvent("Detected stuck process at quit"); +#ifndef MTA_DEBUG + TerminateProcess(piLoadee.hProcess, 1); + status = WAIT_FAILED; + break; +#endif + } + status = WaitForSingleObject(piLoadee.hProcess, 1000); } - status = WaitForSingleObject(piLoadee.hProcess, 1000); + } + + if (!GetExitCodeProcess(piLoadee.hProcess, &dwExitCode)) + { + dwExitCode = static_cast(-1); } } @@ -1258,25 +2050,272 @@ int LaunchGame(SString strCmdLine) AddReportLog(7104, "Loader - Finishing"); WriteDebugEvent("Loader - Finishing"); - EndD3DStuff(); - // Get its exit code - DWORD dwExitCode = -1; - GetExitCodeProcess(piLoadee.hProcess, &dwExitCode); + const DWORD rawExitCode = dwExitCode; - // Terminate to be sure - TerminateProcess(piLoadee.hProcess, 1); + if (IsCrashExitCode(rawExitCode)) + { + const std::array artifactPaths{CalcMTASAPath("mta\\core.log"), CalcMTASAPath("mta\\core.log.flag"), + CalcMTASAPath("mta\\core.dmp")}; - ////////////////////////////////////////////////////////// - // - // On exit - // - // Cleanup and exit. - CloseHandle(piLoadee.hProcess); - ReleaseSingleInstanceMutex(); + const auto artifactStates = [&] + { + std::array states{}; + std::transform(artifactPaths.cbegin(), artifactPaths.cend(), states.begin(), + [&](const SString& path) { return InspectCrashArtifact(path, gtaCreationTime); }); + return states; + }(); + + const auto artifactLabels = [&] + { + std::array labels{}; + std::transform(artifactStates.cbegin(), artifactStates.cend(), labels.begin(), + [](const CrashArtifactState state) { return CrashArtifactStateToString(state); }); + return labels; + }(); + + if (const bool allArtifactsFresh = + std::all_of(artifactStates.cbegin(), artifactStates.cend(), [](const CrashArtifactState state) { return state == CrashArtifactState::Fresh; }); + !allArtifactsFresh) + { + const auto [coreLogLabel, coreLogFlagLabel, coreDumpLabel] = artifactLabels; + bool isAcDefense = false; + + if (debugCapture.captured) + { + if (IsFailFastException(debugCapture.exceptionCode) && IsHighIntegrityModule(debugCapture.moduleInfo.moduleName)) + { + isAcDefense = true; + AddReportLog(7210, SString("Loader - AC integrity exit detected in debugger capture (module=%s code=0x%08X)", + debugCapture.moduleInfo.moduleName.c_str(), static_cast(debugCapture.exceptionCode))); + // Mark the failfast dump as handled so _CheckForWerCrash PATH 1 does not reprocess it on next launch + if (!debugCapture.dumpPath.empty()) + SetApplicationSetting("diagnostics", "last-wer-dump-shown", ExtractFilename(debugCapture.dumpPath)); + // Mark the WER archive report as handled so _CheckForWerCrash PATH 2 does not reprocess it. + // WER may still create an archive entry for a fail-fast even when our debugger is attached. + { + WerCrashInfo acWerInfo = QueryWerCrashInfo(debugCapture.exceptionCode); + if (acWerInfo.found && !acWerInfo.reportId.empty()) + SetApplicationSetting("diagnostics", "last-wer-report-shown", acWerInfo.reportId); + } + MessageBoxUTF8(nullptr, + "MTA: San Andreas has been terminated due to an integrity violation.\n\n" + "Make sure that no external program is modifying the game. Note that some unreliable " + "AV's (such as Bitdefender) are known to interfere in a way that can lead to this problem.", + "MTA: San Andreas", MB_OK | MB_ICONWARNING | MB_TOPMOST); + } + else + { + AddReportLog(3147, + SString("Loader observed crash exit 0x%08X (core.log=%s core.log.flag=%s core.dmp=%s " + "EIP=0x%08X ESP=0x%08X EBP=0x%08X EAX=0x%08X dump=%s)", + static_cast(rawExitCode), coreLogLabel, coreLogFlagLabel, coreDumpLabel, debugCapture.threadContext.Eip, + debugCapture.threadContext.Esp, debugCapture.threadContext.Ebp, debugCapture.threadContext.Eax, + debugCapture.dumpPath.empty() ? "none" : ExtractFilename(debugCapture.dumpPath).c_str())); + + // Use the pre-resolved module info from capture time (when process was alive) + // This ensures we have module info even for early crashes before registry storage + if (debugCapture.moduleInfo.resolved) + { + AddReportLog(3148, SString("Crash in %s: RVA=0x%08X IDA=0x%08X (base=0x%08X)", debugCapture.moduleInfo.moduleName.c_str(), + debugCapture.moduleInfo.rva, debugCapture.moduleInfo.idaAddress, debugCapture.moduleInfo.moduleBase)); + } + } + } + else + { + WerCrashInfo werInfo = QueryWerCrashInfo(rawExitCode); + + if (werInfo.found && IsFailFastException(werInfo.exceptionCode) && IsHighIntegrityModule(werInfo.moduleName)) + { + isAcDefense = true; + AddReportLog(7210, SString("Loader - AC integrity exit detected via WER (module=%s code=0x%08X)", werInfo.moduleName.c_str(), + static_cast(werInfo.exceptionCode))); + // Mark WER report as handled so _CheckForWerCrash does not reprocess it on next launch + if (!werInfo.reportId.empty()) + SetApplicationSetting("diagnostics", "last-wer-report-shown", werInfo.reportId); + MessageBoxUTF8(nullptr, + "MTA: San Andreas has been terminated due to an AC integrity violation.\n\n" + "Make sure that no external program is modifying the game. Note that some unreliable " + "AV's (such as Bitdefender) are known to interfere in a way that can lead to this problem.", + "MTA: San Andreas", MB_OK | MB_ICONWARNING | MB_TOPMOST); + } + else if (werInfo.found) + { + // WER faultOffset is already the RVA (offset within the module) + // We can directly compute IDA address: IDA_BASE + RVA + DWORD rva = 0; + SString offsetStr; + const bool hasValidOffset = !werInfo.faultOffset.empty(); + + if (hasValidOffset) + { + offsetStr = werInfo.faultOffset; + offsetStr.Replace("0x", ""); + offsetStr.Replace("0X", ""); + rva = static_cast(strtoull(offsetStr.c_str(), nullptr, 16)); + } + + SString offsetText; + if (offsetStr.empty()) + offsetText = "unknown"; + else + offsetText = SString("0x%s", offsetStr.c_str()); + + constexpr DWORD IDA_DEFAULT_DLL_BASE = 0x10000000; + const DWORD idaAddress = IDA_DEFAULT_DLL_BASE + rva; + SString idaAddressText; + if (hasValidOffset && rva != 0) + idaAddressText = SString("0x%08X", idaAddress); + else + idaAddressText = "unknown"; + + // Give WER time to finish writing the dump file (it can take a moment after process exit) + Sleep(1000); + + // Try to find and rename WER dump to MTA format (with retry) + WerDumpResult dumpResult; + for (int attempt = 0; attempt < 3 && dumpResult.path.empty(); ++attempt) + { + if (attempt > 0) + Sleep(500); + dumpResult = FindAndRenameWerDump(werInfo.moduleName, rva, werInfo.exceptionCode, gtaCreationTime); + } + const char* dumpLabel = dumpResult.path.empty() ? coreDumpLabel : "fresh"; + + // Set up crash info for dialog with register details + if (!dumpResult.path.empty()) + { + const char* exceptionName = (werInfo.exceptionCode == 0xC0000409) ? "Stack Buffer Overrun" + : (werInfo.exceptionCode == 0xC0000374) ? "Heap Corruption" + : "Security Exception"; + + SString crashReason = SString( + "Security Exception - %s (0x%08X) detected.\n" + "Module: %s\n" + "Offset: %s\n" + "IDA Address: %s (assuming default DLL base 0x10000000)\n" + "Crash dump: %s", + exceptionName, werInfo.exceptionCode, werInfo.moduleName.empty() ? "unknown" : werInfo.moduleName.c_str(), offsetText.c_str(), + idaAddressText.c_str(), ExtractFilename(dumpResult.path).c_str()); + + SetApplicationSetting("diagnostics", "last-crash-reason", crashReason); + SetApplicationSettingInt("diagnostics", "last-crash-code", werInfo.exceptionCode); + + // Mark this WER report as handled to prevent _CheckForWerCrash from reprocessing + if (!werInfo.reportId.empty()) + SetApplicationSetting("diagnostics", "last-wer-report-shown", werInfo.reportId); + + // Build core.log entry + SYSTEMTIME st{}; + GetLocalTime(&st); + const auto strMTAVersionFull = + SString("%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting("mta-version-ext").SplitRight(".", nullptr, -2)); + + SString coreLogEntry; + coreLogEntry += SString("Version = %s\n", strMTAVersionFull.c_str()); + coreLogEntry += SString("Time = %04d-%02d-%02d %02d:%02d:%02d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + coreLogEntry += SString("Module = %s\n", werInfo.moduleName.empty() ? "unknown" : werInfo.moduleName.c_str()); + coreLogEntry += SString("Code = 0x%08X (%s)\n", werInfo.exceptionCode, exceptionName); + coreLogEntry += SString("Offset = %s\n", offsetText.c_str()); + coreLogEntry += SString("IDA Address = %s\n\n", idaAddressText.c_str()); + + if (dumpResult.regs.valid) + { + coreLogEntry += SString( + "EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESI=%08X\n" + "EDI=%08X EBP=%08X ESP=%08X EIP=%08X FLG=%08X\n" + "CS=%04X DS=%04X SS=%04X ES=%04X FS=%04X GS=%04X\n\n", + dumpResult.regs.eax, dumpResult.regs.ebx, dumpResult.regs.ecx, dumpResult.regs.edx, dumpResult.regs.esi, dumpResult.regs.edi, + dumpResult.regs.ebp, dumpResult.regs.esp, dumpResult.regs.eip, dumpResult.regs.eflags, dumpResult.regs.cs, dumpResult.regs.ds, + dumpResult.regs.ss, dumpResult.regs.es, dumpResult.regs.fs, dumpResult.regs.gs); + } + + if (!dumpResult.stackTrace.empty()) + { + coreLogEntry += "Stack trace:\n"; + coreLogEntry += dumpResult.stackTrace; + coreLogEntry += "\n"; + } + + coreLogEntry += "Source: Windows Error Reporting (fail-fast exception)\n"; + coreLogEntry += SString("Dump: %s\n", ExtractFilename(dumpResult.path).c_str()); + + SetApplicationSetting("diagnostics", "last-crash-info", coreLogEntry); + + // Write to core.log + FILE* pFile = File::Fopen(CalcMTASAPath("mta\\core.log"), "a"); + if (pFile) + { + fprintf(pFile, "%s", "** -- Unhandled exception -- **\n\n"); + fprintf(pFile, "%s", coreLogEntry.c_str()); + fprintf(pFile, "%s", "** -- End of unhandled exception -- **\n\n\n"); + fclose(pFile); + } + } + + // Enhanced log with IDA-ready address (computed from WER offset) + if (hasValidOffset && rva != 0) + { + AddReportLog(3147, + SString("Loader observed crash exit 0x%08X (core.log=%s core.log.flag=%s core.dmp=%s module=%s offset=%s) " + "-> IDA=0x%08X", + static_cast(rawExitCode), coreLogLabel, coreLogFlagLabel, dumpLabel, + werInfo.moduleName.empty() ? "unknown" : werInfo.moduleName.c_str(), werInfo.faultOffset.c_str(), idaAddress)); + } + else + { + AddReportLog(3147, SString("Loader observed crash exit 0x%08X (core.log=%s core.log.flag=%s core.dmp=%s module=%s offset=%s)", + static_cast(rawExitCode), coreLogLabel, coreLogFlagLabel, dumpLabel, + werInfo.moduleName.empty() ? "unknown" : werInfo.moduleName.c_str(), + werInfo.faultOffset.empty() ? "unknown" : werInfo.faultOffset.c_str())); + } + } + else + { + AddReportLog(3147, SString("Loader observed crash exit 0x%08X (core.log=%s core.log.flag=%s core.dmp=%s)", + static_cast(rawExitCode), coreLogLabel, coreLogFlagLabel, coreDumpLabel)); + } + + if (!isAcDefense && IsFailFastException(rawExitCode)) + { + isAcDefense = true; + AddReportLog(7210, SString("Loader - AC integrity exit detected via exit code (code=0x%08X)", static_cast(rawExitCode))); + MessageBoxUTF8(nullptr, + "MTA: San Andreas has been terminated due to an integrity violation.\n\n" + "Make sure that no external program is modifying the game. Note that some unreliable " + "AV's (such as Bitdefender) are known to interfere in a way that can lead to this problem.", + "MTA: San Andreas", MB_OK | MB_ICONWARNING | MB_TOPMOST); + + SetApplicationSetting("diagnostics", "debugger-crash-capture", "1"); + WriteDebugEvent(SString("Loader - AC integrity exit via exit code, one-shot debugger flag SET (exit code 0x%08X)", rawExitCode)); + AddReportLog(7204, SString("Loader - One-shot debugger flag SET for next launch (exit code 0x%08X)", rawExitCode)); + } + } + } + } + + // Cleanup + if (piLoadee.hProcess && piLoadee.hProcess != INVALID_HANDLE_VALUE) + { + const bool terminateRequired = (dwExitCode == STILL_ACTIVE) || (dwExitCode == static_cast(-1)); + if (terminateRequired) + { + if (TerminateProcess(piLoadee.hProcess, EXIT_ERROR) != FALSE) + { + dwExitCode = EXIT_ERROR; + } + } + + if (piLoadee.hThread && piLoadee.hThread != INVALID_HANDLE_VALUE) + { + CloseHandle(piLoadee.hThread); + } + CloseHandle(piLoadee.hProcess); + } - // Success, maybe + ReleaseSingleInstanceMutex(); return dwExitCode; } @@ -1284,48 +2323,136 @@ int LaunchGame(SString strCmdLine) // // HandleOnQuitCommand // -// Parse and do something with OnQuitCommand from registry +// What to do when GTA exits // ////////////////////////////////////////////////////////// void HandleOnQuitCommand() { const SString strMTASAPath = GetMTASAPath(); + + if (!ValidatePath(strMTASAPath)) + { + CheckService(CHECK_SERVICE_POST_GAME); + return; + } + SetCurrentDirectory(strMTASAPath); SetDllDirectory(strMTASAPath); SString strOnQuitCommand = GetRegistryValue("", "OnQuitCommand"); + if (strOnQuitCommand.length() > 4096) + { + WriteDebugEvent("OnQuitCommand too long, ignoring"); + CheckService(CHECK_SERVICE_POST_GAME); + return; + } + std::vector vecParts; strOnQuitCommand.Split("\t", vecParts); - if (vecParts.size() > 4 && vecParts[0].length()) + + if (vecParts.size() < 5 || vecParts.size() > 100) { - SString strOperation = vecParts[0]; - SString strFile = vecParts[1]; - SString strParameters = vecParts[2]; - SString strDirectory = vecParts[3]; - SString strShowCmd = vecParts[4]; + CheckService(CHECK_SERVICE_POST_GAME); + return; + } - if (strOperation == "restart") + // Validate parts + for (const auto& part : vecParts) + { + if (part.length() > 1024) { - strOperation = "open"; - strFile = PathJoin(strMTASAPath, MTA_EXE_NAME); - CheckService(CHECK_SERVICE_RESTART_GAME); + WriteDebugEvent("OnQuitCommand has invalid parts"); + CheckService(CHECK_SERVICE_POST_GAME); + return; } - else - CheckService(CHECK_SERVICE_POST_GAME); // Stop service here if quit command is not 'restart' + } - LPCTSTR lpOperation = strOperation == "" ? NULL : strOperation.c_str(); - LPCTSTR lpFile = strFile.c_str(); - LPCTSTR lpParameters = strParameters == "" ? NULL : strParameters.c_str(); - LPCTSTR lpDirectory = strDirectory == "" ? NULL : strDirectory.c_str(); - INT nShowCmd = strShowCmd == "" ? SW_SHOWNORMAL : atoi(strShowCmd); + SString strOperation = vecParts[0]; + SString strFile = vecParts[1]; + SString strParameters = vecParts[2]; + SString strDirectory = vecParts[3]; + SString strShowCmd = vecParts[4]; - if (lpOperation && lpFile) + // Process operation type + if (strOperation == "restart") + { + strOperation = "open"; + strFile = PathJoin(strMTASAPath, MTA_EXE_NAME); + + if (!FileExists(strFile)) + { + WriteDebugEvent("MTA executable not found for restart"); + CheckService(CHECK_SERVICE_POST_GAME); + return; + } + CheckService(CHECK_SERVICE_RESTART_GAME); + } + else if (strOperation == "open" || strOperation.empty()) + { + if (strFile.Contains("..") || strFile.Contains("~/") || strFile.Contains("~\\")) + { + WriteDebugEvent("Suspicious file path in OnQuitCommand"); + CheckService(CHECK_SERVICE_POST_GAME); + return; + } + + // Check for executable extensions + if (strFile.EndsWithI(".exe") || strFile.EndsWithI(".bat") || strFile.EndsWithI(".cmd") || strFile.EndsWithI(".ps1")) { - // Maybe spawn an exe - ShellExecuteNonBlocking(lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd); + if (strFile.Contains(":") || strFile.BeginsWith("\\")) + { + if (!FileExists(strFile)) + { + WriteDebugEvent("Executable in OnQuitCommand not found"); + CheckService(CHECK_SERVICE_POST_GAME); + return; + } + + // Don't allow execution from Windows or System directories + const SString strFileLower = strFile.ToLower(); + if (strFileLower.Contains("\\windows\\") || strFileLower.Contains("\\system32\\") || strFileLower.Contains("\\syswow64\\") || + strFileLower.Contains("\\sysnative\\")) + { + WriteDebugEvent("Refusing to execute from system directory"); + CheckService(CHECK_SERVICE_POST_GAME); + return; + } + } } + CheckService(CHECK_SERVICE_POST_GAME); } else - CheckService(CHECK_SERVICE_POST_GAME); // Stop service here if quit command is empty + { + WriteDebugEvent(SString("Unknown operation: %s", *strOperation)); + CheckService(CHECK_SERVICE_POST_GAME); + return; + } + + // Sanitize parameters + if (strParameters.Contains("&") || strParameters.Contains("|") || strParameters.Contains(">") || strParameters.Contains("<") || + strParameters.Contains("&&") || strParameters.Contains("||")) + { + WriteDebugEvent("Suspicious parameters in OnQuitCommand, removing special chars"); + strParameters = strParameters.Replace("&", "").Replace("|", "").Replace(">", "").Replace("<", ""); + } + + // Validate ShowCmd + INT nShowCmd = SW_SHOWNORMAL; + if (!strShowCmd.empty()) + { + int tempShowCmd = atoi(strShowCmd); + if (tempShowCmd >= 0 && tempShowCmd <= 11) + { + nShowCmd = tempShowCmd; + } + } + + // Execute command + if (!strOperation.empty() && !strFile.empty()) + { + WriteDebugEvent(SString("Executing OnQuitCommand: op=%s, file=%s", *strOperation, *strFile)); + ShellExecuteNonBlocking(strOperation.empty() ? NULL : strOperation.c_str(), strFile.c_str(), strParameters.empty() ? NULL : strParameters.c_str(), + strDirectory.empty() ? NULL : strDirectory.c_str(), nShowCmd); + } } diff --git a/Client/loader/MainFunctions.h b/Client/loader/MainFunctions.h index e1fecc516a3..ae32f14aaf0 100644 --- a/Client/loader/MainFunctions.h +++ b/Client/loader/MainFunctions.h @@ -14,6 +14,11 @@ void InitLocalization(bool bShowErrors); void HandleSpecialLaunchOptions(); void HandleDuplicateLaunching(); void HandleCustomStartMessage(); +void HandleOnQuitCommand(); +void HandleTrouble(); +void HandleResetSettings(); +void HandleNotUsedMainMenu(); +void ConfigureWerDumpPath(); void PreLaunchWatchDogs(); void PostRunWatchDogs(int iReturnCode); void HandleIfGTAIsAlreadyRunning(); @@ -22,7 +27,6 @@ void CheckAntiVirusStatus(); void CheckDataFiles(); void CheckLibVersions(); int LaunchGame(SString strCmdLine); -void HandleOnQuitCommand(); -#define EXIT_OK (0) -#define EXIT_ERROR (1) +#define EXIT_OK (0) +#define EXIT_ERROR (1) diff --git a/Client/loader/SplashWindow.cpp b/Client/loader/SplashWindow.cpp index ab5e144dab0..fe6563c8c03 100644 --- a/Client/loader/SplashWindow.cpp +++ b/Client/loader/SplashWindow.cpp @@ -24,7 +24,7 @@ using hrc = std::chrono::high_resolution_clock; /////////////////////////////////////////////////////////////////////////// // // Splash window logic. -// +// /////////////////////////////////////////////////////////////////////////// class Splash final @@ -111,7 +111,7 @@ bool Splash::CreateSplashWindow(HINSTANCE instance) windowClass.style = 0; windowClass.hInstance = instance; windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.hIcon = LoadIconA(GetModuleHandle(nullptr), MAKEINTRESOURCE(110)); // IDI_ICON1 from Launcher + windowClass.hIcon = LoadIconA(GetModuleHandle(nullptr), MAKEINTRESOURCE(110)); // IDI_ICON1 from Launcher windowClass.lpszClassName = TEXT("SplashWindow"); if (!RegisterClass(&windowClass)) @@ -144,7 +144,7 @@ bool Splash::CreateSplashWindow(HINSTANCE instance) m_barX = {}; m_barY = ScaleToDpi(197, dpi); m_barWidth = m_width; - m_barHeight = ScaleToDpi(5, dpi) + 1; // We add 1 pixel because scaling can cause the bar to be too small. + m_barHeight = ScaleToDpi(5, dpi) + 1; // We add 1 pixel because scaling can cause the bar to be too small. m_windowClass = windowClass; m_window = window; @@ -179,55 +179,117 @@ bool Splash::CreateDeviceResources() if (!m_window) return false; + ReleaseDeviceResources(); + HBITMAP backgroundResource = LoadBitmap(m_windowClass.hInstance, MAKEINTRESOURCE(IDB_BITMAP1)); - HBITMAP barResource = LoadBitmap(m_windowClass.hInstance, MAKEINTRESOURCE(IDB_BITMAP2)); + if (backgroundResource == nullptr) + return false; - if (backgroundResource == nullptr || barResource == nullptr) + HBITMAP barResource = LoadBitmap(m_windowClass.hInstance, MAKEINTRESOURCE(IDB_BITMAP2)); + if (barResource == nullptr) + { + DeleteObject(backgroundResource); return false; + } HDC windowContext = GetDC(m_window); + if (windowContext == nullptr) + { + DeleteObject(barResource); + DeleteObject(backgroundResource); + return false; + } - // Background HDC sourceContext = CreateCompatibleDC(windowContext); - SelectObject(sourceContext, backgroundResource); + if (sourceContext == nullptr) { - HBITMAP backgroundBitmap = CreateCompatibleBitmap(windowContext, m_width, m_height); - HDC renderContext = CreateCompatibleDC(windowContext); - SelectObject(renderContext, backgroundBitmap); - - BITMAP source{}; - GetObject(backgroundResource, sizeof(source), &source); + ReleaseDC(m_window, windowContext); + DeleteObject(barResource); + DeleteObject(backgroundResource); + return false; + } - SetStretchBltMode(renderContext, HALFTONE); - StretchBlt(renderContext, 0, 0, m_width, m_height, sourceContext, 0, 0, source.bmWidth, source.bmHeight, SRCCOPY); + HBITMAP bgBitmap{}; + HDC bgContext{}; + HBITMAP barBitmap{}; + HDC barContext{}; + HRGN barRegion{}; + bool success = false; - m_bgBitmap = backgroundBitmap; - m_bgContext = renderContext; - } + BITMAP source{}; - // Loading bar - SelectObject(sourceContext, barResource); + do { - HBITMAP barBitmap = CreateCompatibleBitmap(windowContext, m_barWidth, m_barHeight); - HDC renderContext = CreateCompatibleDC(windowContext); - SelectObject(renderContext, barBitmap); + SelectObject(sourceContext, backgroundResource); - BITMAP source{}; - GetObject(barResource, sizeof(source), &source); + bgBitmap = CreateCompatibleBitmap(windowContext, m_width, m_height); + if (bgBitmap == nullptr) + break; - SetStretchBltMode(renderContext, HALFTONE); - StretchBlt(renderContext, 0, 0, m_barWidth, m_barHeight, sourceContext, 0, 0, source.bmWidth, source.bmHeight, SRCCOPY); + bgContext = CreateCompatibleDC(windowContext); + if (bgContext == nullptr) + break; - m_barBitmap = barBitmap; - m_barContext = renderContext; - m_barRegion = CreateRectRgn(0, m_barY, m_width, m_barY + m_barHeight); - } + SelectObject(bgContext, bgBitmap); + + if (!GetObject(backgroundResource, sizeof(source), &source)) + break; + + SetStretchBltMode(bgContext, HALFTONE); + if (!StretchBlt(bgContext, 0, 0, m_width, m_height, sourceContext, 0, 0, source.bmWidth, source.bmHeight, SRCCOPY)) + break; + + SelectObject(sourceContext, barResource); + + barBitmap = CreateCompatibleBitmap(windowContext, m_barWidth, m_barHeight); + if (barBitmap == nullptr) + break; + + barContext = CreateCompatibleDC(windowContext); + if (barContext == nullptr) + break; + + SelectObject(barContext, barBitmap); + + if (!GetObject(barResource, sizeof(source), &source)) + break; + + SetStretchBltMode(barContext, HALFTONE); + if (!StretchBlt(barContext, 0, 0, m_barWidth, m_barHeight, sourceContext, 0, 0, source.bmWidth, source.bmHeight, SRCCOPY)) + break; + + barRegion = CreateRectRgn(0, m_barY, m_width, m_barY + m_barHeight); + if (barRegion == nullptr) + break; + + success = true; + } while (false); DeleteDC(sourceContext); + ReleaseDC(m_window, windowContext); DeleteObject(barResource); DeleteObject(backgroundResource); - ReleaseDC(m_window, windowContext); + if (!success) + { + if (barRegion) + DeleteObject(barRegion); + if (barContext) + DeleteDC(barContext); + if (barBitmap) + DeleteObject(barBitmap); + if (bgContext) + DeleteDC(bgContext); + if (bgBitmap) + DeleteObject(bgBitmap); + return false; + } + + m_bgBitmap = bgBitmap; + m_bgContext = bgContext; + m_barBitmap = barBitmap; + m_barContext = barContext; + m_barRegion = barRegion; return true; } @@ -339,9 +401,10 @@ void Splash::UpdateLoadingBar() const long long numUpdates = elapsed / UPDATE_RATE_IN_MS; m_barLastUpdate += std::chrono::milliseconds(numUpdates * UPDATE_RATE_IN_MS); - m_barX += PIXELS_PER_UPDATE * numUpdates; - - if (m_barX >= m_width) + const long long delta = static_cast(PIXELS_PER_UPDATE) * numUpdates; + if (m_width > 0) + m_barX = static_cast((static_cast(m_barX) + delta) % m_width); + else m_barX = 0; // Only invalidate the loading bar region to avoid flickering. @@ -521,26 +584,6 @@ void SplashThread::PostRun() // /////////////////////////////////////////////////////////////////////////// -#ifdef MTA_DEBUG - -void ShowSplash(HINSTANCE instance) -{ -} - -void HideSplash() -{ -} - -void SuspendSplash() -{ -} - -void ResumeSplash() -{ -} - -#else - void ShowSplash(HINSTANCE instance) { if (g_splashThread.Exists()) @@ -569,8 +612,6 @@ void ResumeSplash() g_splash.Show(); } -#endif - /////////////////////////////////////////////////////////////////////////// // // Utility functions. diff --git a/Client/loader/Utils.cpp b/Client/loader/Utils.cpp index 7dae8ce439d..7249b03e081 100644 --- a/Client/loader/Utils.cpp +++ b/Client/loader/Utils.cpp @@ -14,6 +14,8 @@ #include "Dialogs.h" #include #include +#include +#include #include #include #include @@ -23,7 +25,7 @@ #include #include #include -#pragma comment (lib, "wintrust") +#pragma comment(lib, "wintrust") namespace fs = std::filesystem; @@ -86,7 +88,7 @@ WString devicePathToWin32Path(const WString& strDevicePath) while (*p++) ; - } while (!bFound && *p); // end of string + } while (!bFound && *p); // end of string } return pszFilename; } @@ -457,6 +459,146 @@ auto GetGameExecutablePath() -> std::filesystem::path return executable; } +namespace +{ + SString MakeCurrentVersionRegistryPath(const SString& strPath) + { + return PathJoin(GetProductRegistryPath(), GetMajorVersionString(), strPath).TrimEnd("\\"); + } + + bool IsTemporaryUpdateLaunchPath(const SString& strLaunchPath) + { + if (strLaunchPath.empty()) + return false; + + if (!strLaunchPath.ContainsI("\\upcache\\")) + return false; + + return ExtractFilename(strLaunchPath).ContainsI("_tmp_"); + } + + bool IsUsableMtasaInstallRoot(const SString& strPath) + { + if (strPath.empty()) + return false; + + return FileExists(PathJoin(strPath, "Multi Theft Auto.exe")) || FileExists(PathJoin(strPath, "Multi Theft Auto_d.exe")) || + FileExists(PathJoin(strPath, "mta", "core.dll")) || FileExists(PathJoin(strPath, "MTA", "core.dll")) || + FileExists(PathJoin(strPath, "mta", "core_d.dll")) || FileExists(PathJoin(strPath, "MTA", "core_d.dll")); + } + + bool HasDistinct64BitRegistryView() + { +#if defined(_WIN64) + return false; +#elif defined(KEY_WOW64_64KEY) + using IsWow64ProcessFn = BOOL(WINAPI*)(HANDLE, PBOOL); + + static IsWow64ProcessFn fnIsWow64Process = nullptr; + static bool bResolved = false; + + if (!bResolved) + { + bResolved = true; + + if (HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll"); hKernel32) + { + FARPROC procAddr = GetProcAddress(hKernel32, "IsWow64Process"); + if (procAddr) + { + static_assert(sizeof(fnIsWow64Process) == sizeof(procAddr), "Unexpected function pointer size"); + std::memcpy(&fnIsWow64Process, &procAddr, sizeof(fnIsWow64Process)); + } + } + } + + if (!fnIsWow64Process) + return false; + + BOOL bIsWow64 = FALSE; + return fnIsWow64Process(GetCurrentProcess(), &bIsWow64) && bIsWow64; +#else + return false; +#endif + } + + SString GetRegistryValue64(const SString& strPath, const SString& strName) + { + if (!HasDistinct64BitRegistryView()) + return GetRegistryValue(strPath, strName); + + const WString wstrSubKey = FromUTF8(MakeCurrentVersionRegistryPath(strPath)); + const WString wstrValueName = FromUTF8(strName); + + HKEY hKey = nullptr; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, wstrSubKey.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &hKey) != ERROR_SUCCESS || !hKey) + return ""; + + DWORD valueType = REG_SZ; + DWORD valueSize = 0; + LONG result = RegQueryValueExW(hKey, wstrValueName.c_str(), nullptr, &valueType, nullptr, &valueSize); + if (result != ERROR_SUCCESS || (valueType != REG_SZ && valueType != REG_EXPAND_SZ) || valueSize == 0) + { + RegCloseKey(hKey); + return ""; + } + + std::vector buffer((valueSize / sizeof(wchar_t)) + 1, L'\0'); + result = RegQueryValueExW(hKey, wstrValueName.c_str(), nullptr, &valueType, reinterpret_cast(buffer.data()), &valueSize); + RegCloseKey(hKey); + + if (result != ERROR_SUCCESS || (valueType != REG_SZ && valueType != REG_EXPAND_SZ)) + return ""; + + if (valueSize >= sizeof(wchar_t)) + buffer[(valueSize / sizeof(wchar_t)) - 1] = L'\0'; + else + buffer[0] = L'\0'; + + return ToUTF8(buffer.data()); + } + + void SetRegistryValue64(const SString& strPath, const SString& strName, const SString& strValue) + { + if (!HasDistinct64BitRegistryView()) + { + SetRegistryValue(strPath, strName, strValue); + return; + } + + const WString wstrSubKey = FromUTF8(MakeCurrentVersionRegistryPath(strPath)); + const WString wstrValueName = FromUTF8(strName); + const WString wstrValue = FromUTF8(strValue); + + HKEY hKey = nullptr; + if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, wstrSubKey.c_str(), 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS | KEY_WOW64_64KEY, nullptr, &hKey, + nullptr) != ERROR_SUCCESS || + !hKey) + return; + + RegSetValueExW(hKey, wstrValueName.c_str(), 0, REG_SZ, reinterpret_cast(wstrValue.c_str()), + static_cast((wstrValue.length() + 1) * sizeof(wchar_t))); + RegCloseKey(hKey); + } +} + +SString GetInstallPathForLauncher() +{ + const SString strLaunchPath = GetLaunchPath(); + if (!IsTemporaryUpdateLaunchPath(strLaunchPath)) + return strLaunchPath; + + const SString strSavedInstallPath = GetRegistryValue("", "Last Run Location"); + if (IsUsableMtasaInstallRoot(strSavedInstallPath) && !IsTemporaryUpdateLaunchPath(strSavedInstallPath)) + return strSavedInstallPath; + + const SString strSavedInstallPath64 = GetRegistryValue64("", "Last Run Location"); + if (IsUsableMtasaInstallRoot(strSavedInstallPath64) && !IsTemporaryUpdateLaunchPath(strSavedInstallPath64)) + return strSavedInstallPath64; + + return strLaunchPath; +} + void SetMTASAPathSource(bool bReadFromRegistry) { if (bReadFromRegistry) @@ -467,6 +609,16 @@ void SetMTASAPathSource(bool bReadFromRegistry) { // Get current module full path SString strLaunchPathFilename = GetLaunchPathFilename(); + SString strLaunchPath = GetLaunchPath(); + SString strInstallPath = GetInstallPathForLauncher(); + + if (!strInstallPath.CompareI(strLaunchPath)) + { + AddReportLog(1063, SString("SetMTASAPathSource: preserving install path '%s' for temp launcher '%s'", strInstallPath.c_str(), + strLaunchPathFilename.c_str())); + g_strMTASAPath = strInstallPath; + return; + } SString strHash = "-"; { @@ -481,14 +633,16 @@ void SetMTASAPathSource(bool bReadFromRegistry) } SetRegistryValue("", "Last Run Path", strLaunchPathFilename); + SetRegistryValue64("", "Last Run Path", strLaunchPathFilename); SetRegistryValue("", "Last Run Path Hash", strHash); + SetRegistryValue64("", "Last Run Path Hash", strHash); SetRegistryValue("", "Last Run Path Version", MTA_DM_ASE_VERSION); + SetRegistryValue64("", "Last Run Path Version", MTA_DM_ASE_VERSION); // Strip the module name out of the path. - SString strLaunchPath = GetLaunchPath(); - // Save to a temp registry key SetRegistryValue("", "Last Run Location", strLaunchPath); + SetRegistryValue64("", "Last Run Location", strLaunchPath); g_strMTASAPath = strLaunchPath; } } @@ -532,7 +686,8 @@ static const SString DoUserAssistedSearch() noexcept { SString result; - MessageBox(nullptr, _("Start Grand Theft Auto: San Andreas.\nEnsure the game is placed in the 'Program Files (x86)' folder."), _("Searching for GTA: San Andreas"), MB_OK | MB_ICONINFORMATION); + MessageBox(nullptr, _("Start Grand Theft Auto: San Andreas.\nEnsure the game is placed in the 'Program Files (x86)' folder."), + _("Searching for GTA: San Andreas"), MB_OK | MB_ICONINFORMATION); while (true) { @@ -545,7 +700,10 @@ static const SString DoUserAssistedSearch() noexcept return result; } - if (MessageBox(nullptr, _("Sorry, game not found.\nStart Grand Theft Auto: San Andreas and click retry.\nEnsure the game is placed in the 'Program Files (x86)' folder."), _("Searching for GTA: San Andreas"), MB_RETRYCANCEL | MB_ICONWARNING) == IDCANCEL) + if (MessageBox(nullptr, + _("Sorry, game not found.\nStart Grand Theft Auto: San Andreas and click retry.\nEnsure the game is placed in the 'Program Files (x86)' " + "folder."), + _("Searching for GTA: San Andreas"), MB_RETRYCANCEL | MB_ICONWARNING) == IDCANCEL) return result; } } @@ -565,11 +723,13 @@ ePathResult GetGamePath(SString& strOutResult, bool bFindIfMissing) // Try HKLM "SOFTWARE\\Multi Theft Auto: San Andreas All\\Common\\" pathList.push_back(GetCommonRegistryValue("", "GTA:SA Path")); + WriteDebugEvent(SString("GetGamePath: Registry returned '%s'", pathList[0].c_str())); + // Unicode character check on first one if (strlen(pathList[0].c_str())) { // Check for replacement characters (?), to see if there are any (unsupported) unicode characters - if (strchr(pathList[0].c_str(), '?') > 0) + if (strchr(pathList[0].c_str(), '?') != nullptr) return GAME_PATH_UNICODE_CHARS; } @@ -577,22 +737,39 @@ ePathResult GetGamePath(SString& strOutResult, bool bFindIfMissing) for (uint i = 0; i < pathList.size(); i++) { if (pathList[i].empty()) + { + WriteDebugEvent(SString("GetGamePath: pathList[%d] is empty", i)); + AddReportLog(3201, SString("GetGamePath: Registry GTA:SA Path is empty (index %d)", i)); continue; + } - if (FileExists(PathJoin(pathList[i], MTA_GTA_KNOWN_FILE_NAME))) + WriteDebugEvent(SString("GetGamePath: Checking '%s' for '%s'", pathList[i].c_str(), MTA_GTA_KNOWN_FILE_NAME)); + SString strCheckPath = PathJoin(pathList[i], MTA_GTA_KNOWN_FILE_NAME); + if (FileExists(strCheckPath)) { strOutResult = pathList[i]; // Update registry. SetCommonRegistryValue("", "GTA:SA Path", strOutResult); + WriteDebugEvent(SString("GetGamePath: Found GTA at '%s'", strOutResult.c_str())); return GAME_PATH_OK; } + else + { + AddReportLog(3202, SString("GetGamePath: File check failed - '%s' not found", strCheckPath.c_str())); + } } + WriteDebugEvent("GetGamePath: No valid GTA path found in registry"); + // Try to find? if (!bFindIfMissing) + { + AddReportLog(3203, "GetGamePath: No valid GTA path and bFindIfMissing=false"); return GAME_PATH_MISSING; + } // Ask user to browse for GTA + AddReportLog(3204, "GetGamePath: Prompting user to browse for GTA folder"); BROWSEINFOW bi = {0}; WString strMessage(_("Select your Grand Theft Auto: San Andreas Installation Directory")); bi.lpszTitle = strMessage; @@ -605,6 +782,7 @@ ePathResult GetGamePath(SString& strOutResult, bool bFindIfMissing) if (SHGetPathFromIDListW(pidl, szBuffer)) { strOutResult = ToUTF8(szBuffer); + AddReportLog(3205, SString("GetGamePath: User browsed to '%s'", strOutResult.c_str())); } // free memory used @@ -615,21 +793,31 @@ ePathResult GetGamePath(SString& strOutResult, bool bFindIfMissing) imalloc->Release(); } } + else + { + AddReportLog(3206, "GetGamePath: User cancelled browse dialog"); + } // Check browse result - if (!FileExists(PathJoin(strOutResult, MTA_GTA_KNOWN_FILE_NAME))) + SString strBrowseCheckPath = PathJoin(strOutResult, MTA_GTA_KNOWN_FILE_NAME); + if (!FileExists(strBrowseCheckPath)) { + AddReportLog(3207, SString("GetGamePath: Browse result invalid - '%s' not found, trying DoUserAssistedSearch", strBrowseCheckPath.c_str())); // If browse didn't help, try another method strOutResult = DoUserAssistedSearch(); - if (!FileExists(PathJoin(strOutResult, MTA_GTA_KNOWN_FILE_NAME))) + SString strSearchCheckPath = PathJoin(strOutResult, MTA_GTA_KNOWN_FILE_NAME); + if (!FileExists(strSearchCheckPath)) { + AddReportLog(3208, SString("GetGamePath: DoUserAssistedSearch failed - '%s' not found, giving up", strSearchCheckPath.c_str())); // If still not found, give up return GAME_PATH_MISSING; } + AddReportLog(3209, SString("GetGamePath: DoUserAssistedSearch succeeded - found '%s'", strOutResult.c_str())); } // File found. Update registry. + AddReportLog(3210, SString("GetGamePath: Success - GTA found at '%s'", strOutResult.c_str())); SetCommonRegistryValue("", "GTA:SA Path", strOutResult); return GAME_PATH_OK; } @@ -845,16 +1033,40 @@ void MakeRandomIndexList(int Size, std::vector& outList) // // GetOSVersion // -// Affected by compatibility mode +// Returns OS version info // /////////////////////////////////////////////////////////////// +static bool QueryRtlGetVersion(SOSVersionInfo& versionInfo) +{ + HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll"); + if (!hNtdll) + return false; + + FARPROC pProc = GetProcAddress(hNtdll, "RtlGetVersion"); + if (!pProc) + return false; + + using RtlGetVersionFn = LONG(WINAPI*)(PRTL_OSVERSIONINFOW); + RtlGetVersionFn pRtlGetVersion = nullptr; + static_assert(sizeof(pRtlGetVersion) == sizeof(pProc), "Unexpected function pointer size"); + std::memcpy(&pRtlGetVersion, &pProc, sizeof(pRtlGetVersion)); + + RTL_OSVERSIONINFOW osvi = {}; + osvi.dwOSVersionInfoSize = sizeof(osvi); + if (pRtlGetVersion(&osvi) != 0) + return false; + + versionInfo.dwMajor = osvi.dwMajorVersion; + versionInfo.dwMinor = osvi.dwMinorVersion; + versionInfo.dwBuild = osvi.dwBuildNumber; + return true; +} + SOSVersionInfo GetOSVersion() { - OSVERSIONINFO versionInfo; - memset(&versionInfo, 0, sizeof(versionInfo)); - versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); - GetVersionEx(&versionInfo); - return {versionInfo.dwMajorVersion, versionInfo.dwMinorVersion, versionInfo.dwBuildNumber}; + SOSVersionInfo versionInfo = {0}; + QueryRtlGetVersion(versionInfo); + return versionInfo; } /////////////////////////////////////////////////////////////// @@ -1044,8 +1256,48 @@ void UpdateMTAVersionApplicationSetting(bool bQuiet) usNetRel = static_cast(atoi(parts[5])); } + const auto LoadVersionModule = [&](const SString& strRootPath, DWORD& dwOutLastError) -> HMODULE + { + if (strRootPath.empty()) + return NULL; + + const SString strLibPath = PathJoin(strRootPath, "mta"); + const SString strLibPathFilename = PathJoin(strLibPath, strFilename); + if (!FileExists(strLibPathFilename)) + { + dwOutLastError = ERROR_FILE_NOT_FOUND; + return NULL; + } + + const SString strPrevCurDir = GetSystemCurrentDirectory(); + SetCurrentDirectory(strLibPath); + SetDllDirectory(strLibPath); + + HMODULE hLoadedModule = LoadLibrary(strLibPathFilename); + dwOutLastError = GetLastError(); + + SetCurrentDirectory(strPrevCurDir); + SetDllDirectory(strPrevCurDir); + return hLoadedModule; + }; + DWORD dwLastError = 0; - HMODULE hModule = GetLibraryHandle(strFilename, &dwLastError); + HMODULE hModule = NULL; + bool bFreeModule = false; + + const SString strInstallPath = GetInstallPathForLauncher(); + if (IsUsableMtasaInstallRoot(strInstallPath)) + { + hModule = LoadVersionModule(strInstallPath, dwLastError); + bFreeModule = hModule != NULL; + } + + if (!hModule) + { + hModule = LoadVersionModule(GetLaunchPath(), dwLastError); + bFreeModule = hModule != NULL; + } + if (hModule) { typedef void (*PFNINITNETREV)(const char*, const char*, const char*); @@ -1067,6 +1319,9 @@ void UpdateMTAVersionApplicationSetting(bool bQuiet) DisplayErrorMessageBox(strMessage, _E("CL38"), "module-not-loadable&name=" + ExtractBeforeExtension(strFilename)); } + if (bFreeModule) + FreeLibrary(hModule); + if (!bQuiet) SetApplicationSetting("mta-version-ext", SString("%d.%d.%d-%d.%05d.%c.%03d", MTASA_VERSION_MAJOR, MTASA_VERSION_MINOR, MTASA_VERSION_MAINTENANCE, MTASA_VERSION_TYPE, MTASA_VERSION_BUILD, usNetRev == 65535 ? '+' : usNetRev + '0', usNetRel)); @@ -1136,13 +1391,13 @@ bool Is32bitProcess(DWORD processID) if (bOk) { if (bIsWow64 == FALSE) - return false; // 64 bit O/S and process not running under WOW64, so it must be a 64 bit process + return false; // 64 bit O/S and process not running under WOW64, so it must be a 64 bit process return true; } } } - return false; // Can't determine. Guess it's 64 bit + return false; // Can't determine. Guess it's 64 bit } /////////////////////////////////////////////////////////////////////////// @@ -1302,10 +1557,13 @@ int GetFileAge(const SString& strPathFilename) /////////////////////////////////////////////////////////////////////////// void CleanDownloadCache() { - const uint uiMaxCleanTime = 5; // Limit clean time (seconds) - const uint uiCleanFileAge = 60 * 60 * 24 * 7; // Delete files older than this + const uint uiMaxCleanTime = 5; // Limit clean time (seconds) + const uint uiCleanFileAge = 60 * 60 * 24 * 7; // Delete files older than this + const uint uiTmpDirCleanAge = 60 * 60 * 24; // Delete stale extracted temp dirs older than this - const time_t tMaxEndTime = time(NULL) + uiMaxCleanTime; + const time_t tMaxEndTime = time(NULL) + uiMaxCleanTime; + const SString strLaunchPath = GetLaunchPath(); + const SString strCurrentDir = GetSystemCurrentDirectory(); // Search possible cache locations std::list cacheLocationList; @@ -1322,8 +1580,18 @@ void CleanDownloadCache() for (uint i = 0; i < fileList.size(); i++) { const SString strPathFilename = PathJoin(strCacheLocation, fileList[i]); + const bool bIsExtractedTempDir = DirectoryExists(strPathFilename) && ExtractFilename(strPathFilename).ContainsI("_tmp_"); + const uint uiRequiredAge = bIsExtractedTempDir ? uiTmpDirCleanAge : uiCleanFileAge; + + if (bIsExtractedTempDir) + { + if (strLaunchPath.CompareI(strPathFilename) || strCurrentDir.CompareI(strPathFilename) || strLaunchPath.BeginsWithI(strPathFilename + "\\") || + strCurrentDir.BeginsWithI(strPathFilename + "\\")) + continue; + } + // Check if over 7 days old - if (GetFileAge(strPathFilename) > uiCleanFileAge) + if (GetFileAge(strPathFilename) > uiRequiredAge) { // Delete as directory or file if (DirectoryExists(strPathFilename)) @@ -1385,7 +1653,7 @@ void DirectoryCopy(SString strSrcBase, SString strDestBase, bool bShowProgressDi bool bCheckFreeSpace = false; long long llFreeBytesAvailable = GetDiskFreeSpace(strDestBase); if (llFreeBytesAvailable != 0) - bCheckFreeSpace = (llFreeBytesAvailable < (iMinFreeSpaceMB + 10000) * 0x100000LL); // Only check if initial freespace is less than 10GB + bCheckFreeSpace = (llFreeBytesAvailable < (iMinFreeSpaceMB + 10000) * 0x100000LL); // Only check if initial freespace is less than 10GB if (bShowProgressDialog) ShowProgressDialog(g_hInstance, _("Copying files..."), true); @@ -1492,7 +1760,7 @@ void MaybeShowCopySettingsDialog() if (!FileExists(strPreviousConfig)) return; - HideSplash(); // Hide standard MTA splash + HideSplash(); // Hide standard MTA splash // Show dialog SString strMessage; @@ -2155,7 +2423,7 @@ bool IsNativeArm64Host() if (kernel32) { BOOL(WINAPI * IsWow64Process2_)(HANDLE, USHORT*, USHORT*) = nullptr; - IsWow64Process2_ = reinterpret_cast(GetProcAddress(kernel32, "IsWow64Process2")); + IsWow64Process2_ = reinterpret_cast(reinterpret_cast(GetProcAddress(kernel32, "IsWow64Process2"))); if (IsWow64Process2_) { @@ -2241,3 +2509,391 @@ int WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, PVOID pvNothing) g_hInstance = hModule; return TRUE; } + +////////////////////////////////////////////////////////// +// +// QueryWerCrashInfo +// +// Query Windows Error Reporting and Event Log for crash details. +// If targetExceptionCode is 0, any fail-fast exception is matched. +// +////////////////////////////////////////////////////////// +WerCrashInfo QueryWerCrashInfo(DWORD targetExceptionCode) +{ + constexpr DWORD EXCEPTION_STACK_BUFFER_OVERRUN = 0xC0000409; + constexpr DWORD EXCEPTION_HEAP_CORRUPTION = 0xC0000374; + constexpr ULONGLONG FILETIME_UNITS_PER_SECOND = 10000000ULL; + constexpr ULONGLONG MAX_CRASH_AGE_MINUTES = 15; + + WerCrashInfo result; + + // WER stores reports in two locations: + // 1. User profile: %LOCALAPPDATA%\Microsoft\Windows\WER\ReportArchive (no admin needed) + // 2. System-wide: C:\ProgramData\Microsoft\Windows\WER\ReportArchive (needs admin) + // Check user profile first as it's more likely to have reports without admin privileges + std::vector werArchivePaths; + + char localAppData[MAX_PATH]; + if (GetEnvironmentVariableA("LOCALAPPDATA", localAppData, MAX_PATH) > 0) + { + werArchivePaths.push_back(PathJoin(localAppData, "Microsoft\\Windows\\WER\\ReportArchive")); + } + werArchivePaths.push_back("C:\\ProgramData\\Microsoft\\Windows\\WER\\ReportArchive"); + + // Collect all report directories from both paths + std::vector> allReportDirs; // + for (const SString& werArchivePath : werArchivePaths) + { + SString searchPattern = PathJoin(werArchivePath, "AppCrash_gta_sa.exe_*"); + auto reportDirs = FindFiles(searchPattern, false, true, true); + for (const SString& dir : reportDirs) + { + allReportDirs.push_back({werArchivePath, dir}); + } + } + + if (allReportDirs.empty()) + return result; + + FILETIME ftNow; + GetSystemTimeAsFileTime(&ftNow); + ULARGE_INTEGER uliNow; + uliNow.LowPart = ftNow.dwLowDateTime; + uliNow.HighPart = ftNow.dwHighDateTime; + + for (auto it = allReportDirs.rbegin(); it != allReportDirs.rend(); ++it) + { + const SString& werArchivePath = it->first; + const SString& reportDir = it->second; + SString reportPath = PathJoin(werArchivePath, reportDir, "Report.wer"); + + HANDLE hFile = CreateFileA(reportPath, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + if (hFile == INVALID_HANDLE_VALUE) + continue; + + FILETIME ftCreate, ftAccess, ftWrite; + if (!GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite)) + { + CloseHandle(hFile); + continue; + } + + ULARGE_INTEGER uliWrite; + uliWrite.LowPart = ftWrite.dwLowDateTime; + uliWrite.HighPart = ftWrite.dwHighDateTime; + + const ULONGLONG maxAge = MAX_CRASH_AGE_MINUTES * 60 * FILETIME_UNITS_PER_SECOND; + if (uliNow.QuadPart < uliWrite.QuadPart || uliNow.QuadPart - uliWrite.QuadPart > maxAge) + { + CloseHandle(hFile); + continue; // Skip stale reports but check others from different paths + } + + wchar_t wbuffer[8192]{}; + DWORD bytesRead = 0; + SetFilePointer(hFile, 0, nullptr, FILE_BEGIN); + ReadFile(hFile, wbuffer, sizeof(wbuffer) - sizeof(wchar_t), &bytesRead, nullptr); + CloseHandle(hFile); + + std::wstring content(wbuffer, bytesRead / sizeof(wchar_t)); + + bool hasStackOverrun = content.find(L"c0000409") != std::wstring::npos || content.find(L"C0000409") != std::wstring::npos; + bool hasHeapCorruption = content.find(L"c0000374") != std::wstring::npos || content.find(L"C0000374") != std::wstring::npos; + + if (!hasStackOverrun && !hasHeapCorruption) + continue; + + DWORD foundCode = hasStackOverrun ? EXCEPTION_STACK_BUFFER_OVERRUN : EXCEPTION_HEAP_CORRUPTION; + + if (targetExceptionCode != 0 && foundCode != targetExceptionCode) + continue; + + auto parseField = [&content](const wchar_t* fieldName) -> SString + { + std::wstring searchKey = std::wstring(fieldName) + L".Value="; + size_t pos = content.find(searchKey); + if (pos == std::wstring::npos) + return ""; + pos += searchKey.length(); + size_t endPos = content.find_first_of(L"\r\n", pos); + if (endPos == std::wstring::npos) + return ""; + std::wstring value = content.substr(pos, endPos - pos); + return SString("%ls", value.c_str()); + }; + + SString appName = parseField(L"Sig[0]"); + SString werModule = parseField(L"Sig[3]"); + SString werOffset = parseField(L"Sig[6]"); + + SString evtModule, evtOffset; + HANDLE hEventLog = OpenEventLogW(nullptr, L"Application"); + if (hEventLog) + { + std::vector buffer(65536); + DWORD evtBytesRead = 0, minBytes = 0; + + if (ReadEventLogW(hEventLog, EVENTLOG_BACKWARDS_READ | EVENTLOG_SEQUENTIAL_READ, 0, buffer.data(), static_cast(buffer.size()), &evtBytesRead, + &minBytes)) + { + auto* record = reinterpret_cast(buffer.data()); + DWORD totalRead = 0; + + for (int i = 0; i < 10 && totalRead < evtBytesRead; ++i) + { + if (record->EventID == 1000) + { + auto* source = reinterpret_cast(reinterpret_cast(record) + sizeof(EVENTLOGRECORD)); + + if (wcscmp(source, L"Application Error") == 0) + { + constexpr LONGLONG UNIX_EPOCH_DIFF = 11644473600LL; + ULARGE_INTEGER eventTime; + eventTime.QuadPart = (static_cast(record->TimeGenerated) + UNIX_EPOCH_DIFF) * FILETIME_UNITS_PER_SECOND; + + ULONGLONG timeDiff = + (uliWrite.QuadPart > eventTime.QuadPart) ? (uliWrite.QuadPart - eventTime.QuadPart) : (eventTime.QuadPart - uliWrite.QuadPart); + + if (timeDiff < 2ULL * 60 * FILETIME_UNITS_PER_SECOND) + { + auto* strPtr = reinterpret_cast(reinterpret_cast(record) + record->StringOffset); + + std::vector eventStrings; + for (WORD s = 0; s < record->NumStrings && s < 10; ++s) + { + eventStrings.emplace_back(SString("%ls", strPtr)); + while (*strPtr) + ++strPtr; + ++strPtr; + } + + if (eventStrings.size() >= 8) + { + const SString& exCode = eventStrings[6]; + if (exCode.ContainsI("c0000409") || exCode.ContainsI("c0000374")) + { + evtModule = eventStrings[3]; + evtOffset = eventStrings[7]; + break; + } + } + } + } + } + totalRead += record->Length; + record = reinterpret_cast(reinterpret_cast(record) + record->Length); + } + } + CloseEventLog(hEventLog); + } + + result.moduleName = !evtModule.empty() ? evtModule : (!werModule.empty() ? werModule : appName); + result.faultOffset = !evtOffset.empty() ? evtOffset : werOffset; + result.reportId = reportDir; + result.exceptionCode = foundCode; + result.found = true; + return result; + } + + return result; +} + +////////////////////////////////////////////////////////// +// +// ResolveModuleCrashAddress +// +// Resolves a crash address to a known MTA module using stored module bases. +// Returns module name, RVA, and IDA-friendly address for debugging. +// +// The IDA address uses 0x10000000 as base (standard for DLLs in IDA). +// +////////////////////////////////////////////////////////// +ModuleCrashInfo ResolveModuleCrashAddress(DWORD crashAddress) +{ + ModuleCrashInfo result; + result.crashAddress = crashAddress; + + // Read stored module bases from registry (set by core.dll/Client.dll at startup) + int chunkCount = GetApplicationSettingInt("diagnostics", "module-bases-chunks"); + if (chunkCount <= 0) + chunkCount = 6; + if (chunkCount > 256) + chunkCount = 256; + + SString strModuleBases; + for (int i = 0; i < chunkCount; ++i) + { + SString key; + if (i == 0) + key = "module-bases"; + else + key.Format("module-bases-%d", i); + SString chunk = GetApplicationSetting("diagnostics", key); + if (chunk.empty()) + continue; + if (!strModuleBases.empty()) + strModuleBases += ";"; + strModuleBases += chunk; + } + + if (strModuleBases.empty()) + return result; + + // Parse format: "module1=base1,size1;module2=base2,size2;..." + // Each entry is "modulename=BASEADDR,SIZE" (hex without 0x prefix) + struct ModuleEntry + { + SString name; + DWORD base; + DWORD size; + }; + + std::vector modules; + std::vector entries; + strModuleBases.Split(";", entries, true); + + for (const SString& entry : entries) + { + std::vector parts; + entry.Split("=", parts); + if (parts.size() != 2) + continue; + + ModuleEntry mod; + mod.name = parts[0]; + + // Parse "base,size" or just "base" (legacy format with %p) + std::vector addrParts; + parts[1].Split(",", addrParts); + + if (addrParts.empty()) + continue; + + // Parse base address (handles both "0x..." from %p and raw hex) + SString addrStr = addrParts[0]; + addrStr.Replace("0x", ""); + addrStr.Replace("0X", ""); + mod.base = static_cast(strtoull(addrStr.c_str(), nullptr, 16)); + + // Parse size if available, otherwise estimate + if (addrParts.size() >= 2) + { + SString sizeStr = addrParts[1]; + sizeStr.Replace("0x", ""); + sizeStr.Replace("0X", ""); + mod.size = static_cast(strtoull(sizeStr.c_str(), nullptr, 16)); + } + else + { + mod.size = 0x400000; // Legacy fallback: 4MB estimate + } + + if (!mod.name.empty() && mod.base != 0 && mod.size != 0) + modules.push_back(mod); + } + + if (modules.empty()) + return result; + + // Find which module contains the crash address using actual sizes + for (const ModuleEntry& mod : modules) + { + // Check for overflow before computing end address + if (mod.size > 0xFFFFFFFF - mod.base) + continue; // Skip this module if end address would overflow + + DWORD moduleEnd = mod.base + mod.size; + + if (crashAddress >= mod.base && crashAddress < moduleEnd) + { + result.moduleName = mod.name; + result.moduleBase = mod.base; + result.rva = crashAddress - mod.base; + + // IDA default base varies: DLLs at 0x10000000, EXEs at 0x00400000 + const bool isExe = result.moduleName.EndsWithI(".exe"); + const DWORD idaBase = isExe ? 0x00400000 : 0x10000000; + result.idaAddress = idaBase + result.rva; + result.resolved = true; + return result; + } + } + + return result; +} + +////////////////////////////////////////////////////////// +// +// ResolveModuleCrashAddress (with process handle fallback) +// +// Tries registry-based resolution first. If that fails and a valid +// process handle is provided, enumerates modules from the target process +// directly. This handles early crashes before module bases are stored. +// +////////////////////////////////////////////////////////// +ModuleCrashInfo ResolveModuleCrashAddress(DWORD crashAddress, HANDLE hProcess) +{ + // First try registry-based resolution + ModuleCrashInfo result = ResolveModuleCrashAddress(crashAddress); + if (result.resolved) + return result; + + // Fallback: enumerate modules from the target process if handle is valid + if (!hProcess || hProcess == INVALID_HANDLE_VALUE) + return result; + + HMODULE hMods[512]; + DWORD cbNeeded = 0; + + if (!EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) + return result; + + DWORD moduleCount = cbNeeded / sizeof(HMODULE); + if (moduleCount > NUMELMS(hMods)) + moduleCount = NUMELMS(hMods); + + result.crashAddress = crashAddress; + + for (DWORD i = 0; i < moduleCount; ++i) + { + if (!hMods[i]) + continue; + + MODULEINFO modInfo = {}; + if (!GetModuleInformation(hProcess, hMods[i], &modInfo, sizeof(modInfo))) + continue; + + DWORD modBase = static_cast(reinterpret_cast(modInfo.lpBaseOfDll)); + + // Check for overflow before computing end address + if (modInfo.SizeOfImage > 0xFFFFFFFF - modBase) + continue; // Skip this module if end address would overflow + + DWORD modEnd = modBase + modInfo.SizeOfImage; + + if (crashAddress >= modBase && crashAddress < modEnd) + { + char szModName[MAX_PATH]; + if (GetModuleFileNameExA(hProcess, hMods[i], szModName, sizeof(szModName))) + { + const char* filename = strrchr(szModName, '\\'); + result.moduleName = filename ? filename + 1 : szModName; + } + else + { + result.moduleName = SString("module_%08X", modBase); + } + + result.moduleBase = modBase; + result.rva = crashAddress - modBase; + + const bool isExe = result.moduleName.EndsWithI(".exe"); + const DWORD idaBase = isExe ? 0x00400000 : 0x10000000; + result.idaAddress = idaBase + result.rva; + result.resolved = true; + return result; + } + } + + return result; +} diff --git a/Client/loader/Utils.h b/Client/loader/Utils.h index be0685a83cc..ba8b87ec5ec 100644 --- a/Client/loader/Utils.h +++ b/Client/loader/Utils.h @@ -74,10 +74,11 @@ std::vector GetGTAProcessList(); bool CommandLineContains(const SString& strText); void DisplayErrorMessageBox(const SString& strMessage, const SString& strErrorCode = "", const SString& strTroubleType = ""); -auto GetMTARootDirectory() -> std::filesystem::path; -auto GetGameBaseDirectory() -> std::filesystem::path; -auto GetGameLaunchDirectory() -> std::filesystem::path; -auto GetGameExecutablePath() -> std::filesystem::path; +auto GetMTARootDirectory() -> std::filesystem::path; +auto GetGameBaseDirectory() -> std::filesystem::path; +auto GetGameLaunchDirectory() -> std::filesystem::path; +auto GetGameExecutablePath() -> std::filesystem::path; +SString GetInstallPathForLauncher(); void SetMTASAPathSource(bool bReadFromRegistry); SString GetMTASAPath(); @@ -156,6 +157,39 @@ bool IsErrorCodeLoggable(const std::error_code& ec); */ bool IsNativeArm64Host(); +struct WerCrashInfo +{ + SString moduleName; + SString faultOffset; + SString reportId; + DWORD exceptionCode = 0; + bool found = false; +}; + +WerCrashInfo QueryWerCrashInfo(DWORD targetExceptionCode = 0); + +struct ModuleCrashInfo +{ + SString moduleName; + DWORD moduleBase = 0; + DWORD crashAddress = 0; + DWORD rva = 0; // Relative Virtual Address (crash - base) + DWORD idaAddress = 0; // IDA-friendly address (0x10000000 + rva for DLLs) + bool resolved = false; +}; + +// Resolves a crash address to a known MTA module using stored module bases. +// crashAddress: The absolute crash address from the crash report. +// return: ModuleCrashInfo with resolved module name, RVA, and IDA address if found. +ModuleCrashInfo ResolveModuleCrashAddress(DWORD crashAddress); + +// Resolves a crash address to a known MTA module with process handle fallback. +// If registry-based resolution fails, enumerates modules from the target process. +// crashAddress: The absolute crash address from the crash report. +// hProcess: Handle to the target process (for fallback enumeration). +// Returns ModuleCrashInfo with resolved module name, RVA, and IDA address if found. +ModuleCrashInfo ResolveModuleCrashAddress(DWORD crashAddress, HANDLE hProcess); + /** * @brief Queries the integer value of a specific value item from the registry. */ @@ -183,7 +217,7 @@ bool ReadFileValue(const SString& strFilename, T& value, uint uiOffset) template bool WriteFileValue(const SString& strFilename, const T& value, uint uiOffset) { - SetFileAttributes(strFilename, FILE_ATTRIBUTE_NORMAL); + SetFileAttributesW(FromUTF8(strFilename), FILE_ATTRIBUTE_NORMAL); std::fstream file(FromUTF8(strFilename), std::ios::in | std::ios::out | std::ios::binary); if (file) { @@ -229,7 +263,7 @@ class CStuckProcessDetector }; // For NtQuerySystemInformation -#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) +#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) #define SystemProcessImageNameInformation ((SYSTEM_INFORMATION_CLASS)88) typedef struct _SYSTEM_PROCESS_IMAGE_NAME_INFORMATION { diff --git a/Client/loader/loader.rc b/Client/loader/loader.rc index 7f3d4f1d8a2..8098855ade1 100644 --- a/Client/loader/loader.rc +++ b/Client/loader/loader.rc @@ -80,20 +80,20 @@ BEGIN LTEXT "",IDC_PROGRESS_STATIC,23,22,265,8 END -IDD_CRASHED_DIALOG DIALOGEX 0, 0, 385, 265 -STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_NOFAILCREATE | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +IDD_CRASHED_DIALOG DIALOGEX 0, 0, 500, 480 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "MTA: San Andreas has encountered a problem" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - DEFPUSHBUTTON "Yes",IDOK,134,244,50,14 - PUSHBUTTON "No",IDCANCEL,204,244,50,14 - CONTROL " Tick the check box to send this crash info to MTA devs using the 'internet'",IDC_SEND_DUMP_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,61,174,299,13 - CTEXT "Doing so will increase the chance of this crash being fixed.",IDC_SEND_DESC_STATIC,21,189,336,14 - GROUPBOX "",IDC_STATIC,15,161,348,51 - GROUPBOX "Crash information",IDC_CRASH_HEAD,7,7,371,146,BS_CENTER - CTEXT "Do you want to restart MTA: San Andreas ?",IDC_RESTART_QUESTION_STATIC,24,227,330,10 - EDITTEXT IDC_CRASH_INFO_EDIT,39,22,304,118,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "Yes",IDOK,187,459,50,14 + PUSHBUTTON "No",IDCANCEL,270,459,50,14 + CONTROL "Tick the check box to send this crash info to MTA devs using the 'internet'",IDC_SEND_DUMP_CHECK, + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | BS_CENTER | WS_TABSTOP,18,395,464,13 + CTEXT "Doing so will increase the chance of this crash being fixed.",IDC_SEND_DESC_STATIC,18,410,464,14 + GROUPBOX "",IDC_STATIC,12,382,476,46 + GROUPBOX "Crash information",IDC_CRASH_HEAD,7,7,486,368,BS_CENTER + CTEXT "Do you want to restart MTA: San Andreas ?",IDC_RESTART_QUESTION_STATIC,20,442,460,10 + EDITTEXT IDC_CRASH_INFO_EDIT,15,22,470,345,ES_MULTILINE | ES_READONLY | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL END IDD_D3DDLL_DIALOG DIALOGEX 0, 0, 373, 236 @@ -172,7 +172,7 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 378 TOPMARGIN, 7 - BOTTOMMARGIN, 258 + BOTTOMMARGIN, 493 END IDD_D3DDLL_DIALOG, DIALOG diff --git a/Client/loader/premake5.lua b/Client/loader/premake5.lua index 712d517ed2a..e1db452e78c 100644 --- a/Client/loader/premake5.lua +++ b/Client/loader/premake5.lua @@ -3,9 +3,10 @@ project "Loader" kind "SharedLib" targetname "loader" targetdir(buildpath("mta")) - - filter "system:windows" - linkoptions { "/SAFESEH:NO" } + disablewarnings { + "4996", -- use of symbol with __declspec(deprecated) + } + clangtidy "On" includedirs { "../../Shared/sdk", @@ -17,6 +18,7 @@ project "Loader" links { "unrar", "d3d9", "detours", "Imagehlp", + "DbgHelp", "Psapi", "../../vendor/nvapi/x86/nvapi.lib", "cryptopp", } @@ -35,7 +37,9 @@ project "Loader" files { "premake5.lua", "*.h", - "*.cpp" + "*.cpp", + "../core/FastFailCrashHandler/WerCrashHandler.h", + "../core/FastFailCrashHandler/WerCrashHandler.cpp" } filter "system:windows" diff --git a/Client/loader/resource.h b/Client/loader/resource.h index c39b39b6985..151e2c71ac5 100644 --- a/Client/loader/resource.h +++ b/Client/loader/resource.h @@ -2,53 +2,54 @@ // Microsoft Visual C++ generated include file. // Used by loader.rc // -#define IDB_BITMAP1 105 -#define IDB_BITMAP2 106 -#define IDD_PROGRESS_DIALOG 111 -#define IDD_CRASHED_DIALOG 114 -#define IDD_D3DDLL_DIALOG 115 -#define IDD_OPTIMUS_DIALOG 116 -#define IDD_NOAV_DIALOG 117 -#define IDC_PROGRESS_BAR 1001 -#define IDC_PROGRESS_STATIC 1002 -#define IDC_SEND_DUMP_CHECK 1004 -#define IDC_SEND_DESC_STATIC 1006 -#define IDC_RESTART_QUESTION_STATIC 1007 -#define IDC_CRASH_INFO_EDIT 1009 -#define IDC_EDIT_GRAPHICS_DLL_PATH 1011 -#define IDC_CHECK_NOT_AGAIN 1012 -#define IDC_BUTTON_SHOW_DIR 1013 -#define IDC_RADIO1 1014 -#define IDC_RADIO2 1015 -#define IDC_RADIO3 1016 -#define IDC_RADIO4 1017 -#define IDC_BUTTON_HELP 1022 -#define IDC_CHECK_FORCE_WINDOWED 1023 -#define IDC_STATIC_BODY1 1026 -#define IDC_NOAV_TEXT1 1026 -#define IDC_SPLASHBITMAP 1026 -#define IDC_STATIC_BODY2 1027 -#define IDC_NOAV_TEXT2 1027 -#define IDC_CRASH_HEAD 1028 -#define IDC_D3DDLL_TEXT1 1029 -#define IDC_D3DDLL_TEXT2 1030 -#define IDC_OPTIMUS_TEXT1 1031 -#define IDC_OPTIMUS_TEXT2 1032 -#define IDC_OPTIMUS_TEXT3 1033 -#define IDC_NOAV_OPT_BOTNET 1034 -#define IDC_NOAV_OPT_SKIP 1035 -#define IDC_APPLY_AUTOMATIC_CHANGES 1036 -#define IDC_NO_ACTION 1037 -#define IDC_CHECK_REMEMBER 1038 -#define IDC_OPTIMUS_TEXT4 1039 +#define IDB_BITMAP1 105 +#define IDB_BITMAP2 106 +#define IDD_PROGRESS_DIALOG 111 +#define IDD_CRASHED_DIALOG 114 +#define IDD_D3DDLL_DIALOG 115 +#define IDD_OPTIMUS_DIALOG 116 +#define IDD_NOAV_DIALOG 117 +#define IDC_PROGRESS_BAR 1001 +#define IDC_PROGRESS_STATIC 1002 +#define IDC_SEND_DUMP_CHECK 1004 +#define IDC_SEND_DESC_STATIC 1006 +#define IDC_RESTART_QUESTION_STATIC 1007 +#define IDC_CRASH_INFO_EDIT 1009 +#define IDC_EDIT_GRAPHICS_DLL_PATH 1011 +#define IDC_CHECK_NOT_AGAIN 1012 +#define IDC_BUTTON_SHOW_DIR 1013 +#define IDC_RADIO1 1014 +#define IDC_RADIO2 1015 +#define IDC_RADIO3 1016 +#define IDC_RADIO4 1017 +#define IDC_BUTTON_HELP 1022 +#define IDC_CHECK_FORCE_WINDOWED 1023 +#define IDC_STATIC_BODY1 1026 +#define IDC_NOAV_TEXT1 1026 +#define IDC_SPLASHBITMAP 1026 +#define IDC_STATIC_BODY2 1027 +#define IDC_NOAV_TEXT2 1027 +#define IDC_CRASH_HEAD 1028 +#define IDC_D3DDLL_TEXT1 1029 +#define IDC_D3DDLL_TEXT2 1030 +#define IDC_OPTIMUS_TEXT1 1031 +#define IDC_OPTIMUS_TEXT2 1032 +#define IDC_OPTIMUS_TEXT3 1033 +#define IDC_NOAV_OPT_BOTNET 1034 +#define IDC_NOAV_OPT_SKIP 1035 +#define IDC_APPLY_AUTOMATIC_CHANGES 1036 +#define IDC_NO_ACTION 1037 +#define IDC_CHECK_REMEMBER 1038 +#define IDC_OPTIMUS_TEXT4 1039 +#define IDC_SEND_DUMP_LABEL 1040 // Next default values for new objects // #ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 118 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1036 -#define _APS_NEXT_SYMED_VALUE 101 -#endif + #ifndef APSTUDIO_READONLY_SYMBOLS + #define _APS_NEXT_RESOURCE_VALUE 118 + #define _APS_NEXT_COMMAND_VALUE 40001 + #define _APS_NEXT_CONTROL_VALUE 1041 + #define _APS_NEXT_SYMED_VALUE 101 + #endif #endif diff --git a/Client/mods/deathmatch/CClient.cpp b/Client/mods/deathmatch/CClient.cpp index b293b757c22..44ff7e9cf60 100644 --- a/Client/mods/deathmatch/CClient.cpp +++ b/Client/mods/deathmatch/CClient.cpp @@ -20,6 +20,7 @@ CGame* g_pGame = NULL; CMultiplayer* g_pMultiplayer = NULL; CNet* g_pNet = NULL; CClientGame* g_pClientGame = NULL; +bool g_bClientShuttingDown = false; int CClient::ClientInitialize(const char* szArguments, CCoreInterface* pCore) { @@ -31,9 +32,11 @@ int CClient::ClientInitialize(const char* szArguments, CCoreInterface* pCore) #if defined(MTA_DM_EXPIRE_DAYS) // Make public client test builds expire + // Unused relic from 10+ years ago (as of 2025) but could still be used. Defined by net. if (GetDaysUntilExpire() < -1) { - MessageBox(NULL, _("This version has expired."), "MTA: San Andreas " MTA_DM_BUILDTAG_LONG + _E("CD64"), MB_OK | MB_ICONEXCLAMATION | MB_TOPMOST); + MessageBox(NULL, _("This version has expired."), (std::string("MTA: San Andreas ") + MTA_DM_BUILDTAG_LONG + _E("CD64")).c_str(), + MB_OK | MB_ICONEXCLAMATION | MB_TOPMOST); TerminateProcess(GetCurrentProcess(), 1); } #endif @@ -182,6 +185,9 @@ int CClient::ClientInitialize(const char* szArguments, CCoreInterface* pCore) void CClient::ClientShutdown() { + // Global shutdown flag + g_bClientShuttingDown = true; + // Unbind our radio controls g_pCore->GetKeyBinds()->RemoveControlFunction("radio_next", CClientGame::HandleRadioNext); g_pCore->GetKeyBinds()->RemoveControlFunction("radio_previous", CClientGame::HandleRadioPrevious); @@ -266,8 +272,6 @@ void CClient::RestreamModel(unsigned short usModel) bool CClient::HandleException(CExceptionInformation* pExceptionInformation) { -#ifndef MTA_DEBUG -#ifndef MTA_ALLOW_DEBUG // Let the clientgame write its dump, then make the core terminate our process if (g_pClientGame && pExceptionInformation) { @@ -275,14 +279,6 @@ bool CClient::HandleException(CExceptionInformation* pExceptionInformation) } return false; -#else - // We want to be able to debug using the debugger in debug-mode - return true; -#endif -#else - // We want to be able to debug using the debugger in debug-mode - return true; -#endif } void CClient::GetPlayerNames(std::vector& vPlayerNames) diff --git a/Client/mods/deathmatch/CClient.h b/Client/mods/deathmatch/CClient.h index af34d09e005..132cec1be14 100644 --- a/Client/mods/deathmatch/CClient.h +++ b/Client/mods/deathmatch/CClient.h @@ -13,6 +13,8 @@ #include +extern bool g_bClientShuttingDown; + class CClient : public CClientBase { public: diff --git a/Client/mods/deathmatch/CVoiceRecorder.cpp b/Client/mods/deathmatch/CVoiceRecorder.cpp index 4bb63ccca0f..cc90fc23bbd 100644 --- a/Client/mods/deathmatch/CVoiceRecorder.cpp +++ b/Client/mods/deathmatch/CVoiceRecorder.cpp @@ -56,7 +56,7 @@ void CVoiceRecorder::Init(bool bEnabled, unsigned int uiServerSampleRate, unsign { m_bEnabled = bEnabled; - if (!bEnabled) // If we aren't enabled, don't bother continuing + if (!bEnabled) // If we aren't enabled, don't bother continuing return; std::lock_guard lock(m_Mutex); @@ -101,7 +101,7 @@ void CVoiceRecorder::Init(bool bEnabled, unsigned int uiServerSampleRate, unsign if (iBitRate) speex_encoder_ctl(m_pSpeexEncoderState, SPEEX_SET_BITRATE, &iBitRate); - m_pOutgoingBuffer = (char*)malloc(m_uiBufferSizeBytes * FRAME_OUTGOING_BUFFER_COUNT); + m_pOutgoingBuffer = (unsigned char*)malloc(m_uiBufferSizeBytes * FRAME_OUTGOING_BUFFER_COUNT); m_uiOutgoingReadIndex = 0; m_uiOutgoingWriteIndex = 0; @@ -247,9 +247,9 @@ void CVoiceRecorder::DoPulse() { std::lock_guard lock(m_Mutex); - char* pInputBuffer; - char bufTempOutput[2048]; - unsigned int uiTotalBufferSize = m_uiBufferSizeBytes * FRAME_OUTGOING_BUFFER_COUNT; + unsigned char* pInputBuffer; + unsigned char audioBuffer[2048]{}; + unsigned int uiTotalBufferSize = m_uiBufferSizeBytes * FRAME_OUTGOING_BUFFER_COUNT; // Only send every 100 ms if (CClientTime::GetTime() - m_ulTimeOfLastSend > 100 && m_VoiceState != VOICESTATE_AWAITING_INPUT) @@ -280,8 +280,8 @@ void CVoiceRecorder::DoPulse() { unsigned t; for (t = 0; t < uiSpeexBlockSize; t++) - bufTempOutput[t] = m_pOutgoingBuffer[t % uiTotalBufferSize]; - pInputBuffer = bufTempOutput; + audioBuffer[t] = m_pOutgoingBuffer[t % uiTotalBufferSize]; + pInputBuffer = audioBuffer; } else pInputBuffer = m_pOutgoingBuffer + m_uiOutgoingReadIndex; @@ -296,9 +296,9 @@ void CVoiceRecorder::DoPulse() m_bIsSendingVoiceData = true; - unsigned int uiBytesWritten = speex_bits_write(&speexBits, bufTempOutput, 2048); + unsigned int audioBufferLength = speex_bits_write(&speexBits, reinterpret_cast(audioBuffer), 2048); - g_pClientGame->GetLocalPlayer()->GetVoice()->DecodeAndBuffer(bufTempOutput, uiBytesWritten); + g_pClientGame->GetLocalPlayer()->GetVoice()->DecodeAndBuffer(audioBuffer, audioBufferLength); NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); if (pBitStream) @@ -307,8 +307,8 @@ void CVoiceRecorder::DoPulse() if (pLocalPlayer) { - pBitStream->Write((unsigned short)uiBytesWritten); // size of buffer / voice data - pBitStream->Write((char*)bufTempOutput, uiBytesWritten); // voice data + pBitStream->Write((unsigned short)audioBufferLength); + pBitStream->Write(reinterpret_cast(audioBuffer), audioBufferLength); g_pNet->SendPacket(PACKET_ID_VOICE_DATA, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_UNRELIABLE_SEQUENCED, PACKET_ORDERING_VOICE); @@ -322,7 +322,7 @@ void CVoiceRecorder::DoPulse() } } - if (m_VoiceState == VOICESTATE_RECORDING_LAST_PACKET) // End of voice data (for events) + if (m_VoiceState == VOICESTATE_RECORDING_LAST_PACKET) // End of voice data (for events) { m_VoiceState = VOICESTATE_AWAITING_INPUT; diff --git a/Client/mods/deathmatch/CVoiceRecorder.h b/Client/mods/deathmatch/CVoiceRecorder.h index bde3d617349..acdb3242062 100644 --- a/Client/mods/deathmatch/CVoiceRecorder.h +++ b/Client/mods/deathmatch/CVoiceRecorder.h @@ -11,9 +11,9 @@ #pragma once -#define VOICE_BUFFER_LENGTH 200000 -#define VOICE_FREQUENCY 44100 -#define VOICE_SAMPLE_SIZE 2 +#define VOICE_BUFFER_LENGTH 200000 +#define VOICE_FREQUENCY 44100 +#define VOICE_SAMPLE_SIZE 2 #define FRAME_OUTGOING_BUFFER_COUNT 100 #define FRAME_INCOMING_BUFFER_COUNT 100 @@ -79,11 +79,11 @@ class CVoiceRecorder void* m_pSpeexEncoderState; SpeexPreprocessState* m_pSpeexPreprocState; - char* m_pOutgoingBuffer; - int m_iSpeexOutgoingFrameSampleCount; - unsigned int m_uiOutgoingReadIndex; - unsigned int m_uiOutgoingWriteIndex; - bool m_bIsSendingVoiceData; + unsigned char* m_pOutgoingBuffer; + int m_iSpeexOutgoingFrameSampleCount; + unsigned int m_uiOutgoingReadIndex; + unsigned int m_uiOutgoingWriteIndex; + bool m_bIsSendingVoiceData; unsigned long m_ulTimeOfLastSend; diff --git a/Client/mods/deathmatch/ClientCommands.cpp b/Client/mods/deathmatch/ClientCommands.cpp index e71b5a3a26e..5130f900626 100644 --- a/Client/mods/deathmatch/ClientCommands.cpp +++ b/Client/mods/deathmatch/ClientCommands.cpp @@ -18,14 +18,14 @@ using std::list; using std::vector; #ifdef MTA_DEBUG -#include -#include -#include -#include + #include + #include + #include + #include #endif // Hide the "conversion from 'unsigned long' to 'DWORD*' of greater size" warning -#pragma warning(disable:4312) +#pragma warning(disable : 4312) extern CClientGame* g_pClientGame; @@ -658,7 +658,7 @@ void DumpPlayer(CClientPlayer* pPlayer, FILE* pFile) for (uiIndex = 0; uiIndex < NUM_PLAYER_STATS; uiIndex++) { - fprintf(pFile, "Stat [%u] = %f\n", uiIndex, pPlayer->GetStat(uiIndex)); + fprintf(pFile, "Stat [%u] = %f\n", uiIndex, pPlayer->GetStat(static_cast(uiIndex))); } fprintf(pFile, "Streamed in: %u\n", pPlayer->IsStreamedIn()); @@ -771,7 +771,7 @@ void COMMAND_ServerInfo(const char* szCmdLine) g_pCore->GetConsole()->Print(*strSpacer); } -#if defined (MTA_DEBUG) || defined (MTA_BETA) +#if defined(MTA_DEBUG) || defined(MTA_BETA) void COMMAND_ShowSyncing(const char* szCmdLine) { @@ -828,18 +828,15 @@ void COMMAND_GiveWeapon(const char* szCmdLine) if (!(szCmdLine && szCmdLine[0])) return; - int nWeaponID = atoi(szCmdLine); - /* - * Check validity of the command line weapon id. - */ + const auto weaponId = static_cast(atoi(szCmdLine)); - if (!CClientPickupManager::IsValidWeaponID(nWeaponID)) + if (!CClientPickupManager::IsValidWeaponID(weaponId)) return; CClientPed* pPed = g_pClientGame->GetManager()->GetPlayerManager()->GetLocalPlayer(); if (pPed) { - CWeapon* pPlayerWeapon = pPed->GiveWeapon((eWeaponType)nWeaponID, 9999); + CWeapon* pPlayerWeapon = pPed->GiveWeapon((eWeaponType)weaponId, 9999); if (pPlayerWeapon) { pPlayerWeapon->SetAsCurrentWeapon(); diff --git a/Client/mods/deathmatch/StdInc.h b/Client/mods/deathmatch/StdInc.h index 9cbbb90f8bb..cc7fcf20860 100644 --- a/Client/mods/deathmatch/StdInc.h +++ b/Client/mods/deathmatch/StdInc.h @@ -4,6 +4,7 @@ #define MTA_CLIENT #define SHARED_UTIL_WITH_FAST_HASH_MAP #include "SharedUtil.h" +#include #include #include diff --git a/Client/mods/deathmatch/logic/CAntiCheat.cpp b/Client/mods/deathmatch/logic/CAntiCheat.cpp index dc2effaff60..935ce8f2333 100644 --- a/Client/mods/deathmatch/logic/CAntiCheat.cpp +++ b/Client/mods/deathmatch/logic/CAntiCheat.cpp @@ -100,9 +100,9 @@ SString CAntiCheat::GetInfo(const SString& acInfo, const SString& sdInfo) SString strAllowedFiles = "None"; SString strVerifyFiles = acInfo.SplitLeft(","); - SString strEnabledSD = sdInfo == "" ? "None" : sdInfo; + SString strEnabledSD = sdInfo == "" ? SStringX("None") : sdInfo; SString strDisabledAC = acInfo.SplitRight(","); - strDisabledAC = strDisabledAC == "" ? "None" : strDisabledAC; + strDisabledAC = strDisabledAC == "" ? SStringX("None") : strDisabledAC; int iVerifyFiles = atoi(strVerifyFiles); if (iVerifyFiles == 0) diff --git a/Client/mods/deathmatch/logic/CBassAudio.cpp b/Client/mods/deathmatch/logic/CBassAudio.cpp index 21111ad2243..37e2b343ac3 100644 --- a/Client/mods/deathmatch/logic/CBassAudio.cpp +++ b/Client/mods/deathmatch/logic/CBassAudio.cpp @@ -18,6 +18,9 @@ #include #include #include +#include +#include +#include void CALLBACK BPMCallback(int handle, float bpm, void* user); void CALLBACK BeatCallback(DWORD chan, double beatpos, void* user); @@ -30,38 +33,64 @@ namespace // Use ids instead of points for callback arguments, // as it's easier to identify an invalid id // - CCriticalSection ms_CallbackCS; + std::mutex ms_CallbackMutex; std::map ms_CallbackIdMap; uint ms_uiNextCallbackId = 1; + // Track failed audio file loads to prevent spam and performance hit + std::mutex ms_FailedFilesMutex; + std::unordered_map ms_FailedAudioFiles; + constexpr DWORD FAILED_LOAD_RETRY_DELAY = 10000; // 10 seconds before retrying a failed file + constexpr size_t MAX_FAILED_FILES_CACHE_SIZE = 1000; + + // Track active streaming threads to ensure they complete before DLL unload + std::atomic ms_iActiveStreamingThreads{0}; + std::atomic ms_bShuttingDown{false}; + std::mutex ms_StreamingThreadMutex; + std::condition_variable ms_StreamingThreadCV; + // Get callback id for this CBassAudio void* AddCallbackId(CBassAudio* pBassAudio) { - ms_CallbackCS.Lock(); - void* uiId = (void*)(++ms_uiNextCallbackId ? ms_uiNextCallbackId : ++ms_uiNextCallbackId); + std::lock_guard lock(ms_CallbackMutex); + void* uiId = (void*)(++ms_uiNextCallbackId ? ms_uiNextCallbackId : ++ms_uiNextCallbackId); MapSet(ms_CallbackIdMap, uiId, pBassAudio); - ms_CallbackCS.Unlock(); return uiId; } // Mark callback id as no longer valid void RemoveCallbackId(void* uiId) { - ms_CallbackCS.Lock(); + std::lock_guard lock(ms_CallbackMutex); MapRemove(ms_CallbackIdMap, uiId); - ms_CallbackCS.Unlock(); } - // Get pointer from id + // Get pointer from id (caller must hold lock) CBassAudio* LockCallbackId(void* uiId) { - ms_CallbackCS.Lock(); + ms_CallbackMutex.lock(); return MapFindRef(ms_CallbackIdMap, uiId); } // Finish with pointer - void UnlockCallbackId() { ms_CallbackCS.Unlock(); } -} // namespace + void UnlockCallbackId() + { + ms_CallbackMutex.unlock(); + } +} // namespace + +// Signal streaming threads that we're shutting down - they should exit ASAP after their blocking call returns +void SignalStreamingThreadsToStop() +{ + ms_bShuttingDown.store(true); +} + +// Wait for all active streaming threads to complete (called during shutdown after BASS is freed) +void WaitForAllStreamingThreads(unsigned int uiTimeoutMs) +{ + std::unique_lock lock(ms_StreamingThreadMutex); + ms_StreamingThreadCV.wait_for(lock, std::chrono::milliseconds(uiTimeoutMs), []() { return ms_iActiveStreamingThreads.load() == 0; }); +} CBassAudio::CBassAudio(bool bStream, const SString& strPath, bool bLoop, bool bThrottle, bool b3D) : m_bStream(bStream), m_strPath(strPath), m_bLoop(bLoop), m_bThrottle(bThrottle), m_b3D(b3D) @@ -134,7 +163,7 @@ bool CBassAudio::BeginLoadingMedia() // Calc the flags long lFlags = BASS_STREAM_AUTOFREE | BASS_SAMPLE_SOFTWARE; -#if 0 // Everything sounds better in ste-reo +#if 0 // Everything sounds better in ste-reo if ( m_b3D ) lFlags |= BASS_SAMPLE_MONO; #endif @@ -153,7 +182,16 @@ bool CBassAudio::BeginLoadingMedia() m_pVars = new SSoundThreadVariables(); m_pVars->strURL = m_strPath; m_pVars->lFlags = lFlags; - CreateThread(NULL, 0, reinterpret_cast(&CBassAudio::PlayStreamIntern), m_uiCallbackId, 0, NULL); + HANDLE hThread = CreateThread(NULL, 0, reinterpret_cast(&CBassAudio::PlayStreamIntern), m_uiCallbackId, 0, NULL); + if (!hThread) + { + g_pCore->GetConsole()->Printf("Could not create audio stream thread for %s", *m_strPath); + delete m_pVars; + m_pVars = nullptr; + return false; + } + + CloseHandle(hThread); m_bPendingPlay = true; OutputDebugLine("[Bass] stream connect started"); } @@ -162,6 +200,25 @@ bool CBassAudio::BeginLoadingMedia() // // For non streams, try to load the sound file // + // Check if this file has recently failed to load (file-based only, not buffers) + const DWORD dwCurrentTime = GetTickCount32(); + if (!m_pBuffer) + { + std::lock_guard lock(ms_FailedFilesMutex); + const auto it = ms_FailedAudioFiles.find(m_strPath); + if (it != ms_FailedAudioFiles.end()) + { + const DWORD dwTimeSinceFailure = dwCurrentTime - it->second; + if (dwTimeSinceFailure < FAILED_LOAD_RETRY_DELAY) + { + // File failed recently, don't spam it + return false; + } + // Enough time has passed, remove from failed list and try again + ms_FailedAudioFiles.erase(it); + } + } + // First x streams need to be decoders rather than "real" sounds but that's dependent on if we need streams or not so we need to adapt. /* We are the Borg. Lower your shields and surrender your ships. @@ -176,9 +233,28 @@ bool CBassAudio::BeginLoadingMedia() m_pSound = BASS_StreamCreateFile(false, FromUTF8(m_strPath), 0, 0, lCreateFlags | BASS_UNICODE); if (!m_pSound) m_pSound = BASS_MusicLoad(false, FromUTF8(m_strPath), 0, 0, BASS_MUSIC_RAMP | BASS_MUSIC_PRESCAN | BASS_STREAM_DECODE | BASS_UNICODE, - 0); // Try again + 0); // Try again if (!m_pSound && m_b3D) - m_pSound = ConvertFileToMono(m_strPath); // Last try if 3D + { + // Last try if 3D - check cache first to avoid spammed mono conversion attempts + bool bShouldTry = false; + { + std::lock_guard lock(ms_FailedFilesMutex); + const auto it = ms_FailedAudioFiles.find(m_strPath); + if (it == ms_FailedAudioFiles.end() || (dwCurrentTime - it->second) >= FAILED_LOAD_RETRY_DELAY) + { + bShouldTry = true; + // Mark as failed/in-progress immediately + // and to ensure failure is cached if ConvertFileToMono fails + ms_FailedAudioFiles[m_strPath] = dwCurrentTime; + } + } + + if (bShouldTry) + { + m_pSound = ConvertFileToMono(m_strPath); + } + } } else { @@ -190,11 +266,50 @@ bool CBassAudio::BeginLoadingMedia() // Failed to load ? if (!m_pSound) { - g_pCore->GetConsole()->Printf("BASS ERROR %d in LoadMedia path:%s 3d:%d loop:%d", BASS_ErrorGetCode(), *m_strPath, m_b3D, m_bLoop); + const int nErrorCode = BASS_ErrorGetCode(); + // Only cache file-not-found errors to prevent spam + if (!m_pBuffer && nErrorCode == BASS_ERROR_FILEOPEN) + { + std::lock_guard lock(ms_FailedFilesMutex); + if (ms_FailedAudioFiles.size() >= MAX_FAILED_FILES_CACHE_SIZE) + { + // Remove oldest entry + DWORD maxAge = 0; + auto itOldest = ms_FailedAudioFiles.begin(); + for (auto it = ms_FailedAudioFiles.begin(); it != ms_FailedAudioFiles.end(); ++it) + { + // Find oldest entry + DWORD age = dwCurrentTime - it->second; + if (age > maxAge) + { + maxAge = age; + itOldest = it; + } + } + ms_FailedAudioFiles.erase(itOldest); + } + ms_FailedAudioFiles[m_strPath] = dwCurrentTime; + } + g_pCore->GetConsole()->Printf("BASS ERROR %d in LoadMedia path:%s 3d:%d loop:%d", nErrorCode, *m_strPath, m_b3D, m_bLoop); return false; } - m_pSound = BASS_FX_ReverseCreate(m_pSound, 2.0f, BASS_STREAM_DECODE | BASS_FX_FREESOURCE | BASS_MUSIC_PRESCAN); + // Successfully loaded - remove from failed cache if it was there + if (!m_pBuffer) + { + std::lock_guard lock(ms_FailedFilesMutex); + ms_FailedAudioFiles.erase(m_strPath); + } + + HSTREAM pReversed = BASS_FX_ReverseCreate(m_pSound, 2.0f, BASS_STREAM_DECODE | BASS_FX_FREESOURCE | BASS_MUSIC_PRESCAN); + if (!pReversed) + { + g_pCore->GetConsole()->Printf("BASS ERROR %d in BASS_FX_ReverseCreate path:%s 3d:%d loop:%d", BASS_ErrorGetCode(), *m_strPath, m_b3D, m_bLoop); + BASS_StreamFree(m_pSound); + m_pSound = 0; + return false; + } + m_pSound = pReversed; BASS_ChannelSetAttribute(m_pSound, BASS_ATTRIB_REVERSE_DIR, BASS_FX_RVS_FORWARD); // Sucks. /*if ( BASS_FX_BPM_CallbackSet ( m_pSound, (BPMPROC*)&BPMCallback, 1, 0, 0, m_uiCallbackId ) == false ) @@ -208,12 +323,6 @@ bool CBassAudio::BeginLoadingMedia() g_pCore->GetConsole()->Printf("BASS ERROR %d in BASS_FX_BPM_BeatCallbackSet path:%s 3d:%d loop:%d", BASS_ErrorGetCode(), *m_strPath, m_b3D, m_bLoop); } - - if (!m_pSound) - { - g_pCore->GetConsole()->Printf("BASS ERROR %d in BASS_FX_ReverseCreate path:%s 3d:%d loop:%d", BASS_ErrorGetCode(), *m_strPath, m_b3D, m_bLoop); - return false; - } m_pSound = BASS_FX_TempoCreate(m_pSound, lFlags | BASS_FX_FREESOURCE); if (!m_pSound) { @@ -346,26 +455,83 @@ int CBassAudio::ErrorGetCode() // HSTREAM CBassAudio::ConvertFileToMono(const SString& strPath) { - HSTREAM decoder = - BASS_StreamCreateFile(false, FromUTF8(strPath), 0, 0, BASS_STREAM_DECODE | BASS_SAMPLE_MONO | BASS_UNICODE); // open file for decoding + HSTREAM decoder = BASS_StreamCreateFile(false, FromUTF8(strPath), 0, 0, BASS_STREAM_DECODE | BASS_SAMPLE_MONO | BASS_UNICODE); // open file for decoding if (!decoder) - return 0; // failed - DWORD length = static_cast(BASS_ChannelGetLength(decoder, BASS_POS_BYTE)); // get the length - void* data = malloc(length); // allocate buffer for decoded data + return 0; // failed + + QWORD lengthQW = BASS_ChannelGetLength(decoder, BASS_POS_BYTE); + if (lengthQW == static_cast(-1) || lengthQW == 0) + { + BASS_StreamFree(decoder); + return 0; // invalid length + } + + if (lengthQW > 0xFFFFFFFF) + { + BASS_StreamFree(decoder); + return 0; // file too large for mono conversion + } + + DWORD length = static_cast(lengthQW); // Safe cast after validation + void* data = malloc(length); // allocate buffer for decoded data + if (!data) + { + BASS_StreamFree(decoder); + return 0; // allocation failed + } + BASS_CHANNELINFO ci; - BASS_ChannelGetInfo(decoder, &ci); // get sample format - if (ci.chans > 1) // not mono, downmix... + if (!BASS_ChannelGetInfo(decoder, &ci)) // get sample format + { + free(data); + BASS_StreamFree(decoder); + return 0; // failed to get channel info + } + + if (ci.chans > 1) // not mono, downmix... + { + HSTREAM mixer = BASS_Mixer_StreamCreate(ci.freq, 1, BASS_STREAM_DECODE | BASS_MIXER_END); // create mono mixer + if (!mixer) + { + free(data); + BASS_StreamFree(decoder); + return 0; // mixer creation failed + } + if (!BASS_Mixer_StreamAddChannel(mixer, decoder, + BASS_MIXER_DOWNMIX | BASS_MIXER_NORAMPIN | BASS_STREAM_AUTOFREE)) // plug-in the decoder (auto-free with the mixer) + { + free(data); + BASS_StreamFree(mixer); + BASS_StreamFree(decoder); + return 0; // failed to add channel + } + decoder = mixer; // decode from the mixer + } + + DWORD decodedLength = BASS_ChannelGetData(decoder, data, length); // decode data + BASS_StreamFree(decoder); // free the decoder/mixer + + if (decodedLength == static_cast(-1)) + { + free(data); + return 0; // decode failed + } + + HSTREAM stream = BASS_StreamCreate(ci.freq, 1, BASS_STREAM_AUTOFREE, STREAMPROC_PUSH, NULL); // create stream + if (!stream) + { + free(data); + return 0; // stream creation failed + } + + if (!BASS_StreamPutData(stream, data, decodedLength)) // set the stream data { - HSTREAM mixer = BASS_Mixer_StreamCreate(ci.freq, 1, BASS_STREAM_DECODE | BASS_MIXER_END); // create mono mixer - BASS_Mixer_StreamAddChannel( - mixer, decoder, BASS_MIXER_DOWNMIX | BASS_MIXER_NORAMPIN | BASS_STREAM_AUTOFREE); // plug-in the decoder (auto-free with the mixer) - decoder = mixer; // decode from the mixer + free(data); + BASS_StreamFree(stream); + return 0; // failed to put data } - length = BASS_ChannelGetData(decoder, data, length); // decode data - BASS_StreamFree(decoder); // free the decoder/mixer - HSTREAM stream = BASS_StreamCreate(ci.freq, 1, BASS_STREAM_AUTOFREE, STREAMPROC_PUSH, NULL); // create stream - BASS_StreamPutData(stream, data, length); // set the stream data - free(data); // free the buffer + + free(data); // free the buffer return stream; } @@ -447,6 +613,19 @@ void CALLBACK BeatCallback(DWORD chan, double beatpos, void* user) DWORD CBassAudio::PlayStreamIntern(LPVOID argument) { + // Track this thread so DLL unload can wait for it. + // This needs be incremented at the very start and decremented at the very end + // to ensure the main thread waits for it before unloading the DLL. + ++ms_iActiveStreamingThreads; + + // Check if we're already shutting down + if (ms_bShuttingDown.load()) + { + --ms_iActiveStreamingThreads; + ms_StreamingThreadCV.notify_all(); + return 0; + } + CBassAudio* pBassAudio = LockCallbackId(argument); if (pBassAudio) { @@ -456,26 +635,43 @@ DWORD CBassAudio::PlayStreamIntern(LPVOID argument) pBassAudio->m_pVars->criticalSection.Unlock(); UnlockCallbackId(); - // This can take a while + // This can take a long time (30+ seconds on slow/failing connections). + // The main thread will wait for it with WaitForAllStreamingThreads(). HSTREAM pSound = BASS_StreamCreateURL(FromUTF8(strURL), 0, lFlags | BASS_UNICODE, NULL, NULL); - CBassAudio* pBassAudio = LockCallbackId(argument); - if (pBassAudio) - { - pBassAudio->m_pVars->criticalSection.Lock(); - pBassAudio->m_pVars->bStreamCreateResult = true; - pBassAudio->m_pVars->pSound = pSound; - pBassAudio->m_pVars->criticalSection.Unlock(); - } - else + // After BASS_StreamCreateURL returns, minimize work before decrementing counter. + // If shutting down, skip all processing and exit quickly - BASS is already freed + // So we shouldnt call any BASS functions or access game objects. + if (!ms_bShuttingDown.load()) { - // Deal with unwanted pSound unless we're disconnecting already - if (g_pClientGame != nullptr && !g_pClientGame->IsBeingDeleted()) - g_pClientGame->GetManager()->GetSoundManager()->QueueChannelStop(pSound); + CBassAudio* pBassAudio = LockCallbackId(argument); + if (pBassAudio) + { + pBassAudio->m_pVars->criticalSection.Lock(); + pBassAudio->m_pVars->bStreamCreateResult = true; + pBassAudio->m_pVars->pSound = pSound; + pBassAudio->m_pVars->criticalSection.Unlock(); + } + else if (pSound) + { + // Deal with unwanted pSound unless we're disconnecting already + if (g_pClientGame != nullptr && !g_pClientGame->IsBeingDeleted()) + g_pClientGame->GetManager()->GetSoundManager()->QueueChannelStop(pSound); + } + UnlockCallbackId(); } + // If shutting down: BASS is already freed, so pSound is invalid - just discard it. + // Do NOT call BASS_StreamFree or any BASS API here. + } + else + { + UnlockCallbackId(); } - UnlockCallbackId(); + // Signal that this thread is done - this allows WaitForAllStreamingThreads to return + --ms_iActiveStreamingThreads; + ms_StreamingThreadCV.notify_all(); + return 0; } @@ -516,12 +712,12 @@ void CBassAudio::CompleteStreamConnect(HSTREAM pSound) { for (; *szIcy; szIcy += strlen(szIcy) + 1) { - if (!strnicmp(szIcy, "icy-name:", 9)) // ICY / HTTP + if (!strnicmp(szIcy, "icy-name:", 9)) // ICY / HTTP { m_strStreamName = szIcy + 9; break; } - else if (!strnicmp(szIcy, "title=", 6)) // WMA + else if (!strnicmp(szIcy, "title=", 6)) // WMA { m_strStreamName = szIcy + 6; break; @@ -544,7 +740,7 @@ void CBassAudio::CompleteStreamConnect(HSTREAM pSound) } // set sync for stream titles - m_hSyncMeta = BASS_ChannelSetSync(pSound, BASS_SYNC_META, 0, &MetaSync, m_uiCallbackId); // Shoutcast + m_hSyncMeta = BASS_ChannelSetSync(pSound, BASS_SYNC_META, 0, &MetaSync, m_uiCallbackId); // Shoutcast // g_pCore->GetConsole()->Printf ( "BASS ERROR %d in BASS_SYNC_META", BASS_ErrorGetCode() ); // BASS_ChannelSetSync(pSound,BASS_SYNC_OGG_CHANGE,0,&MetaSync,this); // Icecast/OGG // g_pCore->GetConsole()->Printf ( "BASS ERROR %d in BASS_SYNC_OGG_CHANGE", BASS_ErrorGetCode() ); @@ -632,9 +828,12 @@ bool CBassAudio::SetPlayPosition(double dPosition) // Only relevant for non-streams, which are always ready if valid if (m_pSound) { + QWORD byteLength = BASS_ChannelGetLength(m_pSound, BASS_POS_BYTE); + if (byteLength == static_cast(-1) || byteLength == 0) + return false; + // Make sure position is in range QWORD bytePosition = BASS_ChannelSeconds2Bytes(m_pSound, dPosition); - QWORD byteLength = BASS_ChannelGetLength(m_pSound, BASS_POS_BYTE); return BASS_ChannelSetPosition(m_pSound, Clamp(0, bytePosition, byteLength - 1), BASS_POS_BYTE); } return false; @@ -880,6 +1079,21 @@ float CBassAudio::GetSoundBPM() { if (m_fBPM == 0.0f && !m_bStream) { + // Check failed cache before trying + const DWORD dwCurrentTime = GetTickCount32(); + { + std::lock_guard lock(ms_FailedFilesMutex); + const auto it = ms_FailedAudioFiles.find(m_strPath); + if (it != ms_FailedAudioFiles.end()) + { + const DWORD dwTimeSinceFailure = dwCurrentTime - it->second; + if (dwTimeSinceFailure < FAILED_LOAD_RETRY_DELAY) + { + return 0.0f; // File failed recently, don't retry + } + } + } + float fData = 0.0f; // open the same file as played but for bpm decoding detection @@ -898,6 +1112,11 @@ float CBassAudio::GetSoundBPM() if (BASS_ErrorGetCode() != BASS_OK) { + // Cache the failure to prevent repeated perf hits + { + std::lock_guard lock(ms_FailedFilesMutex); + ms_FailedAudioFiles[m_strPath] = dwCurrentTime; + } g_pCore->GetConsole()->Printf("BASS ERROR %d in BASS_FX_BPM_DecodeGet path:%s 3d:%d loop:%d", BASS_ErrorGetCode(), *m_strPath, m_b3D, m_bLoop); } else diff --git a/Client/mods/deathmatch/logic/CBassAudio.h b/Client/mods/deathmatch/logic/CBassAudio.h index 1c96a6d3308..b94f055d151 100644 --- a/Client/mods/deathmatch/logic/CBassAudio.h +++ b/Client/mods/deathmatch/logic/CBassAudio.h @@ -7,7 +7,7 @@ * *****************************************************************************/ -#define CUT_OFF 5.0f // Cut off point at which volume is regarded as 0 in the function e^-x +#define CUT_OFF 5.0f // Cut off point at which volume is regarded as 0 in the function e^-x enum eSoundEventType { @@ -159,3 +159,9 @@ class CBassAudio HSYNC m_hSyncFree; HSYNC m_hSyncMeta; }; + +// Signal streaming threads that shutdown is in progress - they should exit ASAP +void SignalStreamingThreadsToStop(); + +// Wait for streaming threads to complete. Call after BASS_Free() which aborts pending operations. +void WaitForAllStreamingThreads(unsigned int uiTimeoutMs = 3000); diff --git a/Client/mods/deathmatch/logic/CCallback.h b/Client/mods/deathmatch/logic/CCallback.h index 6f309b34b19..7a7dce47505 100644 --- a/Client/mods/deathmatch/logic/CCallback.h +++ b/Client/mods/deathmatch/logic/CCallback.h @@ -15,7 +15,7 @@ template class CCallbackInterface { public: - virtual ~CCallbackInterface(){}; + virtual ~CCallbackInterface() {}; virtual Ret operator()(Arguments) const = 0; }; @@ -42,7 +42,7 @@ class CCallbackMethod : public CCallbackInterface typedef Ret (T::*F)(Arguments); public: - CCallbackMethod(F pfnMethod, T* pClass) : m_pfnMethod(pfnMethod), m_pClass(pClass){}; + CCallbackMethod(F pfnMethod, T* pClass) : m_pfnMethod(pfnMethod), m_pClass(pClass) {}; virtual Ret operator()(Arguments Args) const { return (m_pClass->*m_pfnMethod)(Args); } diff --git a/Client/mods/deathmatch/logic/CClientBuilding.cpp b/Client/mods/deathmatch/logic/CClientBuilding.cpp index 354ecff8db2..bbff9a5685d 100644 --- a/Client/mods/deathmatch/logic/CClientBuilding.cpp +++ b/Client/mods/deathmatch/logic/CClientBuilding.cpp @@ -28,6 +28,7 @@ CClientBuilding::CClientBuilding(class CClientManager* pManager, ElementID ID, u SetTypeName("building"); m_pBuildingManager->AddToList(this); Create(); + UpdateSpatialData(); } CClientBuilding::~CClientBuilding() @@ -57,6 +58,7 @@ void CClientBuilding::SetPosition(const CVector& vecPosition) return; m_vPos = vecPosition; Recreate(); + UpdateSpatialData(); } void CClientBuilding::SetRotationRadians(const CVector& vecRadians) @@ -99,9 +101,13 @@ void CClientBuilding::SetModel(uint16_t model) { if (CClientBuildingManager::IsValidModel(model)) { - m_usModelId = model; - m_pModelInfo = g_pGame->GetModelInfo(model); - Recreate(); + if (model != m_usModelId) + { + Destroy(); + m_usModelId = model; + m_pModelInfo = g_pGame->GetModelInfo(model); + Create(); + } } } @@ -133,8 +139,8 @@ void CClientBuilding::Create() if (!m_pBuilding) return; - if (m_bDoubleSidedInit) - m_pBuilding->SetBackfaceCulled(!m_bDoubleSided); + if (m_bDoubleSidedInit) + m_pBuilding->SetBackfaceCulled(!m_bDoubleSided); if (!m_usesCollision) { @@ -191,3 +197,8 @@ bool CClientBuilding::SetLowLodBuilding(CClientBuilding* pLod) } return true; } + +float CClientBuilding::GetDistanceFromCentreOfMassToBaseOfModel() +{ + return m_pBuilding ? m_pBuilding->GetDistanceFromCentreOfMassToBaseOfModel() : 0.0f; +} diff --git a/Client/mods/deathmatch/logic/CClientBuilding.h b/Client/mods/deathmatch/logic/CClientBuilding.h index aa33cd50345..9e05c384a28 100644 --- a/Client/mods/deathmatch/logic/CClientBuilding.h +++ b/Client/mods/deathmatch/logic/CClientBuilding.h @@ -20,7 +20,7 @@ class CClientBuilding : public CClientEntity friend class CClientBuildingManager; public: - CClientBuilding(class CClientManager* pManager, ElementID ID, uint16_t usModelId, const CVector &pos, const CVector &rot, uint8_t interior); + CClientBuilding(class CClientManager* pManager, ElementID ID, uint16_t usModelId, const CVector& pos, const CVector& rot, uint8_t interior); ~CClientBuilding(); void Unlink(); @@ -50,15 +50,15 @@ class CClientBuilding : public CClientEntity bool IsValid() const noexcept { return m_pBuilding != nullptr; }; - CClientBuilding* GetLowLodBuilding() const noexcept { return m_pLowBuilding; }; - bool SetLowLodBuilding(CClientBuilding* pLod = nullptr); - bool IsLod() const noexcept { return m_pHighBuilding != nullptr; }; + bool SetLowLodBuilding(CClientBuilding* pLod = nullptr); + bool IsLod() const noexcept { return m_pHighBuilding != nullptr; }; + float GetDistanceFromCentreOfMassToBaseOfModel(); private: - CClientBuilding* GetHighLodBuilding() const { return m_pHighBuilding; }; - void SetHighLodBuilding(CClientBuilding* pHighBuilding = nullptr) { m_pHighBuilding = pHighBuilding; }; + CClientBuilding* GetHighLodBuilding() const { return m_pHighBuilding; }; + void SetHighLodBuilding(CClientBuilding* pHighBuilding = nullptr) { m_pHighBuilding = pHighBuilding; }; void Recreate() { diff --git a/Client/mods/deathmatch/logic/CClientBuildingManager.cpp b/Client/mods/deathmatch/logic/CClientBuildingManager.cpp index 627f432e094..9a0b735ab0b 100644 --- a/Client/mods/deathmatch/logic/CClientBuildingManager.cpp +++ b/Client/mods/deathmatch/logic/CClientBuildingManager.cpp @@ -10,7 +10,7 @@ #include "StdInc.h" -constexpr float WORLD_DISTANCE_FROM_CENTER = 3000.0f; +constexpr float WORLD_DISTANCE_FROM_CENTER = 3000.0f; constexpr size_t PRESERVED_POOL_SIZE = 2000; constexpr size_t RESIZE_POOL_STEP = 5000; @@ -62,8 +62,8 @@ bool CClientBuildingManager::IsValidModel(uint16_t modelId) if (modelId >= static_cast(g_pGame->GetBaseIDforTXD())) return false; - // Clothes and hands cause artefacts - if (384 <= modelId && modelId <= 397) + // Clothes and hands cause artefacts + if (384 <= modelId && modelId <= 397) return false; CModelInfo* pModelInfo = g_pGame->GetModelInfo(modelId); diff --git a/Client/mods/deathmatch/logic/CClientCamera.cpp b/Client/mods/deathmatch/logic/CClientCamera.cpp index d0403f643a1..fd417b35b60 100644 --- a/Client/mods/deathmatch/logic/CClientCamera.cpp +++ b/Client/mods/deathmatch/logic/CClientCamera.cpp @@ -10,9 +10,108 @@ #include #include +#include +#include +#include #define PI_2 6.283185307179586476925286766559f +// Camera FOV constants +constexpr const std::uintptr_t VAR_CurrentCameraFOV = 0x8D5038; // CCamera::CurrentFOV + +namespace +{ + constexpr float kPi = 3.1415926535897932384626433832795f; + constexpr float kMatrixTolerance = 1e-4f; + constexpr float kAngleTolerance = 1e-4f; + constexpr float kRollLookupStep = 15.0f; + constexpr std::size_t kRollLookupSize = static_cast(360.0f / kRollLookupStep); + + struct RollLookupEntry + { + float degrees; + float cosValue; + float sinValue; + }; + + const std::array kRollLookup = []() + { + std::array table = {}; + for (std::size_t i = 0; i < kRollLookupSize; ++i) + { + float degrees = static_cast(i) * kRollLookupStep; + float radians = ConvertDegreesToRadiansNoWrap(degrees); + table[i] = {degrees, std::cos(radians), std::sin(radians)}; + } + return table; + }(); + + inline float WrapDegrees(float angle) noexcept + { + angle -= 360.0f * std::floor((angle + 180.0f) / 360.0f); + if (angle <= -180.0f) + angle += 360.0f; + else if (angle > 180.0f) + angle -= 360.0f; + return angle; + } + + inline bool AlmostEqual(float lhs, float rhs, float epsilon = kMatrixTolerance) noexcept + { + return std::fabs(lhs - rhs) <= epsilon; + } + + inline bool VectorsClose(const CVector& a, const CVector& b, float epsilon = kMatrixTolerance) noexcept + { + return AlmostEqual(a.fX, b.fX, epsilon) && AlmostEqual(a.fY, b.fY, epsilon) && AlmostEqual(a.fZ, b.fZ, epsilon); + } + + inline bool MatricesClose(const CMatrix& a, const CMatrix& b, float epsilon = kMatrixTolerance) noexcept + { + return VectorsClose(a.vFront, b.vFront, epsilon) && VectorsClose(a.vUp, b.vUp, epsilon) && VectorsClose(a.vPos, b.vPos, epsilon); + } + + inline std::pair GetRollSinCos(float rollDegrees) noexcept + { + float normalized = WrapDegrees(rollDegrees); + float index = normalized / kRollLookupStep; + float rounded = std::round(index); + if (std::fabs(index - rounded) <= kAngleTolerance / kRollLookupStep) + { + int wrapped = static_cast(std::lround(rounded)) % static_cast(kRollLookupSize); + if (wrapped < 0) + wrapped += static_cast(kRollLookupSize); + std::size_t tableIndex = static_cast(wrapped); + const auto& entry = kRollLookup[tableIndex]; + return {entry.cosValue, entry.sinValue}; + } + + float radians = ConvertDegreesToRadiansNoWrap(normalized); + return {std::cos(radians), std::sin(radians)}; + } + + inline bool RequiresOrthonormalization(const CMatrix& matrix) noexcept + { + constexpr float lengthTarget = 1.0f; + const bool frontValid = AlmostEqual(matrix.vFront.LengthSquared(), lengthTarget, 1e-3f); + const bool upValid = AlmostEqual(matrix.vUp.LengthSquared(), lengthTarget, 1e-3f); + const bool orthogonal = AlmostEqual(matrix.vFront.DotProduct(&matrix.vUp), 0.0f, 1e-3f); + return !(frontValid && upValid && orthogonal); + } + + inline void EnsureOrthonormal(CMatrix& matrix) + { + if (RequiresOrthonormalization(matrix)) + matrix.OrthoNormalize(CMatrix::AXIS_FRONT, CMatrix::AXIS_UP); + } + + inline CMatrix& ScratchMatrix() noexcept + { + static thread_local CMatrix s_matrix; + return s_matrix; + } +} + CClientCamera::CClientCamera(CClientManager* pManager) : ClassInit(this), CClientEntity(INVALID_ELEMENT_ID) { CClientEntityRefManager::AddEntityRefs(ENTITY_REF_DEBUG(this, "CClientCamera"), &m_pFocusedPlayer, &m_pFocusedEntity, NULL); @@ -27,21 +126,27 @@ CClientCamera::CClientCamera(CClientManager* pManager) : ClassInit(this), CClien m_bInvalidated = false; m_bFixed = false; m_fRoll = 0.0f; - m_fFOV = 70.0f; + m_fFOV = DEFAULT_FOV; SetTypeName("camera"); - m_pCamera = g_pGame->GetCamera(); + m_pCamera = g_pGame ? g_pGame->GetCamera() : nullptr; // Hook handler for the fixed camera - g_pMultiplayer->SetProcessCamHandler(CClientCamera::StaticProcessFixedCamera); + if (g_pMultiplayer) + g_pMultiplayer->SetProcessCamHandler(CClientCamera::StaticProcessFixedCamera); m_FixedCameraMode = EFixedCameraMode::ROTATION; + m_hasCachedPulseMatrix = false; + m_hasCachedPulseEuler = false; + m_lastCenterOfWorldPos = CVector(); + m_lastCenterOfWorldRot = 0.0f; + m_hasCenterOfWorld = false; } CClientCamera::~CClientCamera() { // We need to be ingame - if (g_pGame->GetSystemState() == SystemState::GS_PLAYING_GAME) + if (g_pGame && g_pGame->GetSystemState() == SystemState::GS_PLAYING_GAME) { // Restore the camera to the local player SetFocusToLocalPlayerImpl(); @@ -51,15 +156,12 @@ CClientCamera::~CClientCamera() void CClientCamera::DoPulse() { + InvalidateCachedTransforms(); + // If we're fixed, force the target vector if (m_bFixed) { - // Make sure the world center/rotation is where the camera is - CVector vecRotation; - CMatrix matTemp; - GetMatrix(matTemp); - g_pMultiplayer->ConvertMatrixToEulerAngles(matTemp, vecRotation.fX, vecRotation.fY, vecRotation.fZ); - g_pMultiplayer->SetCenterOfWorld(NULL, &m_matFixedMatrix.vPos, 3.1415926535897932384626433832795f - vecRotation.fZ); + UpdateCenterOfWorldFromFixedMatrix(); } else { @@ -112,12 +214,16 @@ void CClientCamera::DoPulse() } // Set the new world center/rotation - g_pMultiplayer->SetCenterOfWorld(NULL, m_pFocusedGameEntity->GetPosition(), fRotation); + SetCenterOfWorldCached(m_pFocusedGameEntity->GetPosition(), fRotation); + } + else + { + SetCenterOfWorldCached(NULL, 0.0f); } } // Save this so position or rotation is preserved when changing to fixed mode - m_matFixedMatrix = GetGtaMatrix(); + m_matFixedMatrix = AcquirePulseMatrix(); } } @@ -126,7 +232,7 @@ bool CClientCamera::GetMatrix(CMatrix& Matrix) const if (m_bFixed) Matrix = m_matFixedMatrix; else - Matrix = GetGtaMatrix(); + Matrix = AcquirePulseMatrix(); return true; } @@ -137,9 +243,10 @@ bool CClientCamera::SetMatrix(const CMatrix& Matrix) ToggleCameraFixedMode(true); m_matFixedMatrix = Matrix; - m_matFixedMatrix.OrthoNormalize(CMatrix::AXIS_FRONT, CMatrix::AXIS_UP); + EnsureOrthonormal(m_matFixedMatrix); m_FixedCameraMode = EFixedCameraMode::MATRIX; - SetPosition(m_matFixedMatrix.vPos); // To update center of world + UpdateCenterOfWorldFromFixedMatrix(); + InvalidateCachedTransforms(); return true; } @@ -152,29 +259,39 @@ void CClientCamera::GetPosition(CVector& vecPosition) const void CClientCamera::SetPosition(const CVector& vecPosition) { + if (!std::isfinite(vecPosition.fX) || !std::isfinite(vecPosition.fY) || !std::isfinite(vecPosition.fZ)) + return; + // Switch to fixed mode if required if (!IsInFixedMode()) ToggleCameraFixedMode(true); - // Make sure that's where the world center is - CVector vecRotation; - CMatrix matTemp; - GetMatrix(matTemp); - g_pMultiplayer->ConvertMatrixToEulerAngles(matTemp, vecRotation.fX, vecRotation.fY, vecRotation.fZ); - g_pMultiplayer->SetCenterOfWorld(NULL, (CVector*)&vecPosition, 3.1415926535897932384626433832795f - vecRotation.fZ); - - // Store the position so it can be updated from our hook + // Update cached matrix position and world center lazily m_matFixedMatrix.vPos = vecPosition; + UpdateCenterOfWorldFromFixedMatrix(); + InvalidateCachedTransforms(); } void CClientCamera::GetRotationDegrees(CVector& vecRotation) const { - CMatrix matrix; - GetMatrix(matrix); + CVector eulerRadians(0.0f, 0.0f, 0.0f); + + if (m_bFixed) + { + if (g_pMultiplayer) + { + CMatrix matrix = m_matFixedMatrix; + EnsureOrthonormal(matrix); + g_pMultiplayer->ConvertMatrixToEulerAngles(matrix, eulerRadians.fX, eulerRadians.fY, eulerRadians.fZ); + } + } + else + { + const CMatrix& matrix = AcquirePulseMatrix(); + eulerRadians = AcquirePulseEuler(matrix); + } - matrix.OrthoNormalize(CMatrix::AXIS_FRONT, CMatrix::AXIS_UP); - g_pMultiplayer->ConvertMatrixToEulerAngles(matrix, vecRotation.fX, vecRotation.fY, vecRotation.fZ); - vecRotation = CVector(2 * PI, 2 * PI, 2 * PI) - vecRotation; + vecRotation = CVector(PI_2, PI_2, PI_2) - eulerRadians; ConvertRadiansToDegrees(vecRotation); // srsly, f knows, just pretend you never saw this line // vecRotation.fY = 360.0f - vecRotation.fY; // Removed as caused problems with: Camera.rotation = Camera.rotation @@ -182,11 +299,20 @@ void CClientCamera::GetRotationDegrees(CVector& vecRotation) const void CClientCamera::SetRotationRadians(const CVector& vecRotation) { + if (!std::isfinite(vecRotation.fX) || !std::isfinite(vecRotation.fY) || !std::isfinite(vecRotation.fZ)) + return; + + if (!m_pCamera) + return; + + if (!g_pMultiplayer) + return; + // Switch to fixed mode if required if (!IsInFixedMode()) ToggleCameraFixedMode(true); - CVector vecUseRotation = CVector(2 * PI, 2 * PI, 2 * PI) - vecRotation; + CVector vecUseRotation = CVector(PI_2, PI_2, PI_2) - vecRotation; m_FixedCameraMode = EFixedCameraMode::ROTATION; // Set rotational part of fixed matrix @@ -195,7 +321,9 @@ void CClientCamera::SetRotationRadians(const CVector& vecRotation) m_matFixedMatrix.vUp = newMatrix.vUp; m_matFixedMatrix.vFront = newMatrix.vFront; m_matFixedMatrix.vRight = newMatrix.vRight; - m_matFixedMatrix.OrthoNormalize(CMatrix::AXIS_FRONT, CMatrix::AXIS_UP); + EnsureOrthonormal(m_matFixedMatrix); + UpdateCenterOfWorldFromFixedMatrix(); + InvalidateCachedTransforms(); } void CClientCamera::GetFixedTarget(CVector& vecTarget, float* pfRoll) const @@ -219,13 +347,25 @@ void CClientCamera::GetFixedTarget(CVector& vecTarget, float* pfRoll) const void CClientCamera::SetFixedTarget(const CVector& vecPosition, float fRoll) { + if (!std::isfinite(vecPosition.fX) || !std::isfinite(vecPosition.fY) || !std::isfinite(vecPosition.fZ)) + return; + // Switch to fixed mode if required if (!IsInFixedMode()) ToggleCameraFixedMode(true); + float normalizedRoll = 0.0f; + if (std::isfinite(fRoll)) + { + constexpr float fullCircle = 360.0f; + normalizedRoll = std::remainder(fRoll, fullCircle); + if (normalizedRoll < 0.0f) + normalizedRoll += fullCircle; + } + // Store the target so it can be updated from our hook m_vecFixedTarget = vecPosition; - m_fRoll = fRoll; + m_fRoll = normalizedRoll; m_FixedCameraMode = EFixedCameraMode::TARGET; // Update fixed matrix @@ -249,17 +389,22 @@ void CClientCamera::SetFixedTarget(const CVector& vecPosition, float fRoll) vecUp.CrossProduct(&vecFront); vecUp.Normalize(); - // Apply roll if needed + // Apply roll if needed around the front axis if (m_fRoll != 0.0f) { - float fRoll = ConvertDegreesToRadiansNoWrap(m_fRoll); - vecUp = vecUp * cos(fRoll) - vecRight * sin(fRoll); + auto [cosRoll, sinRoll] = GetRollSinCos(m_fRoll); + const CVector originalUp = vecUp; + vecUp = originalUp * cosRoll - vecRight * sinRoll; + vecRight = originalUp * sinRoll + vecRight * cosRoll; } // Set rotational part of fixed matrix m_matFixedMatrix.vFront = vecFront; m_matFixedMatrix.vUp = vecUp; - m_matFixedMatrix.OrthoNormalize(CMatrix::AXIS_FRONT, CMatrix::AXIS_UP); + m_matFixedMatrix.vRight = vecRight; + EnsureOrthonormal(m_matFixedMatrix); + UpdateCenterOfWorldFromFixedMatrix(); + InvalidateCachedTransforms(); } // @@ -279,12 +424,17 @@ void CClientCamera::SetOrbitTarget(const CVector& vecPosition) vecTargetPosition.fZ += 0.6f; CVector vecDirection = vecPosition - vecTargetPosition; + if (vecDirection.Length() <= FLOAT_EPSILON) + return; vecDirection.Normalize(); float fAngleHorz = -atan2(vecDirection.fX, vecDirection.fY) - PI / 2; float fAngleVert = asin(vecDirection.fZ); CCam* pCam = m_pCamera->GetCam(m_pCamera->GetActiveCam()); + if (!pCam) + return; + pCam->SetDirection(fAngleHorz, fAngleVert); } } @@ -304,20 +454,33 @@ void CClientCamera::AttachTo(CElement* pElement) void CClientCamera::FadeIn(float fTime) { + if (!m_pCamera) + return; m_pCamera->Fade(fTime, FADE_IN); } void CClientCamera::FadeOut(float fTime, unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue) { + if (!m_pCamera) + return; m_pCamera->SetFadeColor(ucRed, ucGreen, ucBlue); m_pCamera->Fade(fTime, FADE_OUT); } void CClientCamera::SetFocus(CClientEntity* pEntity, eCamMode eMode, bool bSmoothTransition) { + if (!m_pCamera) + return; + // Should we attach to an entity, or set the camera to free? if (pEntity) { + if (pEntity->IsBeingDeleted()) + { + SetFocusToLocalPlayer(); + return; + } + eClientEntityType eType = pEntity->GetType(); // Remove stream reference from the previous target @@ -359,14 +522,24 @@ void CClientCamera::SetFocus(CClientEntity* pEntity, eCamMode eMode, bool bSmoot } m_fRoll = 0.0f; - m_fFOV = 70.0f; + m_fFOV = DEFAULT_FOV; + InvalidateCachedTransforms(); } void CClientCamera::SetFocus(CClientPlayer* pPlayer, eCamMode eMode, bool bSmoothTransition) { + if (!m_pCamera) + return; + // Should we attach to a player, or set the camera to free? if (pPlayer) { + if (pPlayer->IsBeingDeleted()) + { + SetFocus(reinterpret_cast(NULL), MODE_NONE, bSmoothTransition); + return; + } + // Attach the camera to the player vehicle if in a vehicle. To the player model otherwise CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); if (pVehicle) @@ -387,25 +560,40 @@ void CClientCamera::SetFocus(CClientPlayer* pPlayer, eCamMode eMode, bool bSmoot // Store the player we focused m_pFocusedPlayer = pPlayer; m_fRoll = 0.0f; - m_fFOV = 70.0f; + m_fFOV = DEFAULT_FOV; m_bFixed = false; + InvalidateCachedTransforms(); } void CClientCamera::SetFocus(CVector* vecTarget, bool bSmoothTransition) { - // Grab the camera - if (m_pCamera) - { - // Set the switch style - int iSwitchStyle = 2; - if (bSmoothTransition) - { - iSwitchStyle = 1; - } - // Do it - m_pCamera->TakeControl(vecTarget, iSwitchStyle); - m_bFixed = true; - } + if (!vecTarget) + return; + + CVector sanitizedTarget = *vecTarget; + + if (!std::isfinite(sanitizedTarget.fX) || !std::isfinite(sanitizedTarget.fY) || !std::isfinite(sanitizedTarget.fZ)) + return; + + if (!m_pCamera) + return; + + *vecTarget = sanitizedTarget; + + if (m_pFocusedEntity && m_pFocusedEntity->IsStreamingCompatibleClass()) + static_cast((CClientEntity*)m_pFocusedEntity)->RemoveStreamReference(); + m_pFocusedEntity = nullptr; + m_pFocusedGameEntity = nullptr; + m_pFocusedPlayer = nullptr; + m_bInvalidated = false; + + int iSwitchStyle = 2; + if (bSmoothTransition) + iSwitchStyle = 1; + + m_pCamera->TakeControl(vecTarget, iSwitchStyle); + m_bFixed = true; + InvalidateCachedTransforms(); } void CClientCamera::SetFocusToLocalPlayer() @@ -427,14 +615,19 @@ void CClientCamera::Reset() m_pFocusedGameEntity = NULL; m_bFixed = false; m_fRoll = 0.0f; - m_fFOV = 70.0f; + m_fFOV = DEFAULT_FOV; + SetCenterOfWorldCached(NULL, 0.0f); + InvalidateCachedTransforms(); } void CClientCamera::SetFocusToLocalPlayerImpl() { // Restore the camera + if (!m_pCamera) + return; m_pCamera->RestoreWithJumpCut(); - g_pMultiplayer->SetCenterOfWorld(NULL, NULL, NULL); + SetCenterOfWorldCached(NULL, 0.0f); + InvalidateCachedTransforms(); } void CClientCamera::UnreferenceEntity(CClientEntity* pEntity) @@ -488,31 +681,47 @@ void CClientCamera::RestoreEntity(CClientEntity* pEntity) void CClientCamera::SetCameraVehicleViewMode(eVehicleCamMode eMode) { + if (!m_pCamera) + return; m_pCamera->SetCameraVehicleViewMode(static_cast(eMode)); } void CClientCamera::SetCameraPedViewMode(ePedCamMode eMode) { + if (!m_pCamera) + return; m_pCamera->SetCameraPedViewMode(static_cast(eMode)); } eVehicleCamMode CClientCamera::GetCameraVehicleViewMode() { + if (!m_pCamera) + return eVehicleCamMode::BUMPER; return (eVehicleCamMode)m_pCamera->GetCameraVehicleViewMode(); } ePedCamMode CClientCamera::GetCameraPedViewMode() { + if (!m_pCamera) + return ePedCamMode::CLOSE; return (ePedCamMode)m_pCamera->GetCameraPedViewMode(); } void CClientCamera::SetCameraClip(bool bObjects, bool bVehicles) { + if (!m_pCamera) + return; m_pCamera->SetCameraClip(bObjects, bVehicles); } void CClientCamera::GetCameraClip(bool& bObjects, bool& bVehicles) { + if (!m_pCamera) + { + bObjects = true; + bVehicles = true; + return; + } m_pCamera->GetCameraClip(bObjects, bVehicles); } @@ -538,12 +747,14 @@ void CClientCamera::ToggleCameraFixedMode(bool bEnabled) } else { - g_pMultiplayer->SetCenterOfWorld(NULL, NULL, NULL); + SetCenterOfWorldCached(NULL, 0.0f); SetFocusToLocalPlayer(); m_fRoll = 0.0f; - m_fFOV = 70.0f; + m_fFOV = DEFAULT_FOV; } + + InvalidateCachedTransforms(); } void CClientCamera::SetTargetEntity(CClientEntity* pEntity) @@ -551,12 +762,25 @@ void CClientCamera::SetTargetEntity(CClientEntity* pEntity) if (m_bFixed) return; + if (!m_pCamera) + return; + CCam* const pCam = m_pCamera->GetCam(m_pCamera->GetActiveCam()); if (!pCam) return; - pCam->SetTargetEntity(pEntity->GetGameEntity()); + if (pEntity && pEntity->IsBeingDeleted()) + pEntity = nullptr; + + CEntity* pGameEntity = pEntity ? pEntity->GetGameEntity() : nullptr; + if (pEntity && !pGameEntity) + { + pEntity = nullptr; + pGameEntity = nullptr; + } + + pCam->SetTargetEntity(pGameEntity); } CClientEntity* CClientCamera::GetTargetEntity() @@ -564,12 +788,20 @@ CClientEntity* CClientCamera::GetTargetEntity() CClientEntity* pReturn = NULL; if (m_pCamera) { - CCam* pCam = m_pCamera->GetCam(m_pCamera->GetActiveCam()); + CCam* pCam = m_pCamera->GetCam(m_pCamera->GetActiveCam()); + if (!pCam) + return nullptr; + CEntity* pEntity = pCam->GetTargetEntity(); - if (pEntity) + if (pEntity && g_pGame) { CPools* pPools = g_pGame->GetPools(); - pReturn = pPools->GetClientEntity((DWORD*)pEntity->GetInterface()); + if (pPools) + { + CEntitySAInterface* pInterface = pEntity->GetInterface(); + if (pInterface) + pReturn = pPools->GetClientEntity(reinterpret_cast(pInterface)); + } } } return pReturn; @@ -577,7 +809,18 @@ CClientEntity* CClientCamera::GetTargetEntity() bool CClientCamera::StaticProcessFixedCamera(CCam* pCam) { - return g_pClientGame->GetManager()->GetCamera()->ProcessFixedCamera(pCam); + if (!pCam) + return false; + + if (!g_pClientGame) + return false; + + CClientManager* manager = g_pClientGame->GetManager(); + if (!manager) + return false; + + CClientCamera* camera = manager->GetCamera(); + return camera ? camera->ProcessFixedCamera(pCam) : false; } bool CClientCamera::ProcessFixedCamera(CCam* pCam) @@ -596,7 +839,8 @@ bool CClientCamera::ProcessFixedCamera(CCam* pCam) SetGtaMatrix(m_matFixedMatrix, pCam); // Set the zoom - pCam->SetFOV(m_fFOV); + float appliedFOV = std::isfinite(m_fFOV) ? m_fFOV : DEFAULT_FOV; + pCam->SetFOV(appliedFOV); return true; } @@ -606,14 +850,22 @@ bool CClientCamera::ProcessFixedCamera(CCam* pCam) // CMatrix CClientCamera::GetGtaMatrix() const { + if (!m_pCamera) + return CMatrix(); + + if (IsInCameraTransition()) + return GetInterpolatedCameraMatrix(); + CCam* pCam = m_pCamera->GetCam(m_pCamera->GetActiveCam()); + if (!pCam) + return CMatrix(); CMatrix matResult; m_pCamera->GetMatrix(&matResult); matResult.vFront = *pCam->GetFront(); matResult.vUp = *pCam->GetUp(); matResult.vPos = *pCam->GetSource(); - matResult.vRight = -matResult.vRight; // Camera has this the other way + matResult.vRight = -matResult.vRight; // Camera has this the other way matResult.OrthoNormalize(CMatrix::AXIS_FRONT, CMatrix::AXIS_UP); return matResult; } @@ -623,24 +875,144 @@ CMatrix CClientCamera::GetGtaMatrix() const // void CClientCamera::SetGtaMatrix(const CMatrix& matInNew, CCam* pCam) const { - if (!pCam) - pCam = m_pCamera->GetCam(m_pCamera->GetActiveCam()); + if (!m_pCamera) + return; + + auto isFiniteVector = [](const CVector& vec) { return std::isfinite(vec.fX) && std::isfinite(vec.fY) && std::isfinite(vec.fZ); }; + + if (!isFiniteVector(matInNew.vFront) || !isFiniteVector(matInNew.vUp) || !isFiniteVector(matInNew.vRight) || !isFiniteVector(matInNew.vPos)) + return; + + CCam* targetCam = pCam ? pCam : m_pCamera->GetCam(m_pCamera->GetActiveCam()); + if (!targetCam) + return; CMatrix matNew = matInNew; - matNew.OrthoNormalize(CMatrix::AXIS_FRONT, CMatrix::AXIS_UP); - matNew.vRight = -matNew.vRight; // Camera has this the other way + EnsureOrthonormal(matNew); + matNew.vRight = -matNew.vRight; // Camera has this the other way m_pCamera->SetMatrix(&matNew); - *pCam->GetUp() = matNew.vUp; - *pCam->GetFront() = matNew.vFront; - *pCam->GetSource() = matNew.vPos; + *targetCam->GetUp() = matNew.vUp; + *targetCam->GetFront() = matNew.vFront; + *targetCam->GetSource() = matNew.vPos; +} + +void CClientCamera::InvalidateCachedTransforms() const +{ + m_hasCachedPulseMatrix = false; + m_hasCachedPulseEuler = false; +} + +void CClientCamera::SetCenterOfWorldCached(const CVector* pPosition, float fRotationRadians) +{ + if (!g_pMultiplayer) + return; + + if (!pPosition) + { + if (m_hasCenterOfWorld) + { + g_pMultiplayer->SetCenterOfWorld(NULL, NULL, NULL); + m_hasCenterOfWorld = false; + m_lastCenterOfWorldPos = CVector(); + m_lastCenterOfWorldRot = 0.0f; + } + return; + } + + if (!std::isfinite(pPosition->fX) || !std::isfinite(pPosition->fY) || !std::isfinite(pPosition->fZ)) + return; + + const float rotation = std::isfinite(fRotationRadians) ? fRotationRadians : 0.0f; + + if (!m_hasCenterOfWorld || !VectorsClose(m_lastCenterOfWorldPos, *pPosition) || !AlmostEqual(m_lastCenterOfWorldRot, rotation, kAngleTolerance)) + { + m_lastCenterOfWorldPos = *pPosition; + m_lastCenterOfWorldRot = rotation; + g_pMultiplayer->SetCenterOfWorld(NULL, &m_lastCenterOfWorldPos, m_lastCenterOfWorldRot); + m_hasCenterOfWorld = true; + } +} + +void CClientCamera::UpdateCenterOfWorldFromFixedMatrix() +{ + if (!g_pMultiplayer) + return; + + if (!std::isfinite(m_matFixedMatrix.vPos.fX) || !std::isfinite(m_matFixedMatrix.vPos.fY) || !std::isfinite(m_matFixedMatrix.vPos.fZ)) + return; + + CMatrix normalized = m_matFixedMatrix; + EnsureOrthonormal(normalized); + + CVector eulerAngles; + g_pMultiplayer->ConvertMatrixToEulerAngles(normalized, eulerAngles.fX, eulerAngles.fY, eulerAngles.fZ); + + SetCenterOfWorldCached(&m_matFixedMatrix.vPos, kPi - eulerAngles.fZ); +} + +const CMatrix& CClientCamera::AcquirePulseMatrix() const +{ + if (!m_hasCachedPulseMatrix) + { + m_cachedPulseMatrix = GetGtaMatrix(); + m_hasCachedPulseMatrix = true; + } + return m_cachedPulseMatrix; +} + +const CVector& CClientCamera::AcquirePulseEuler(const CMatrix& matrix) const +{ + if (!m_hasCachedPulseEuler) + { + if (!g_pMultiplayer) + { + m_cachedPulseEuler = CVector(); + m_hasCachedPulseEuler = true; + return m_cachedPulseEuler; + } + CMatrix temp = matrix; + EnsureOrthonormal(temp); + g_pMultiplayer->ConvertMatrixToEulerAngles(temp, m_cachedPulseEuler.fX, m_cachedPulseEuler.fY, m_cachedPulseEuler.fZ); + m_hasCachedPulseEuler = true; + } + return m_cachedPulseEuler; } void CClientCamera::ShakeCamera(float radius, float x, float y, float z) noexcept { + if (!m_pCamera) + return; m_pCamera->ShakeCamera(radius, x, y, z); } void CClientCamera::ResetShakeCamera() noexcept { + if (!m_pCamera) + return; m_pCamera->ResetShakeCamera(); } + +bool CClientCamera::IsInCameraTransition() const +{ + return m_pCamera ? m_pCamera->IsInTransition() : false; +} + +CMatrix CClientCamera::GetInterpolatedCameraMatrix() const +{ + CMatrix matrix; + if (m_pCamera && m_pCamera->GetTransitionMatrix(matrix)) + return matrix; + + return CMatrix(); +} + +float CClientCamera::GetAccurateFOV() const +{ + if (!m_pCamera) + return DEFAULT_FOV; + + if (IsInCameraTransition()) + return m_pCamera->GetTransitionFOV(); + + return *(float*)VAR_CurrentCameraFOV; +} diff --git a/Client/mods/deathmatch/logic/CClientCamera.h b/Client/mods/deathmatch/logic/CClientCamera.h index c49246098cf..f217fd39ecf 100644 --- a/Client/mods/deathmatch/logic/CClientCamera.h +++ b/Client/mods/deathmatch/logic/CClientCamera.h @@ -12,6 +12,7 @@ #include #include +#include #include "CClientCommon.h" #include "CClientEntity.h" @@ -37,7 +38,7 @@ class CClientCamera final : public CClientEntity friend class CClientManager; public: - void Unlink(){}; + void Unlink() {}; void DoPulse(); eClientEntityType GetType() const { return CCLIENTCAMERA; }; @@ -51,9 +52,17 @@ class CClientCamera final : public CClientEntity void GetFixedTarget(CVector& vecTarget, float* pfRoll = NULL) const; void SetFixedTarget(const CVector& vecPosition, float fRoll = 0); float GetFOV() { return m_fFOV; } - void SetFOV(float fFOV) { m_fFOV = fFOV; } - void SetOrbitTarget(const CVector& vecPosition); - void AttachTo(CClientEntity* pElement); + void SetFOV(float fFOV) + { + if (!std::isfinite(fFOV) || fFOV <= 0.0f) + fFOV = DEFAULT_FOV; + else if (fFOV >= 180.0f) + fFOV = 179.0f; + + m_fFOV = fFOV; + } + void SetOrbitTarget(const CVector& vecPosition); + void AttachTo(CClientEntity* pElement); void FadeIn(float fTime); void FadeOut(float fTime, unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue); @@ -82,6 +91,10 @@ class CClientCamera final : public CClientEntity void UnreferencePlayer(CClientPlayer* pPlayer); + bool IsInCameraTransition() const; + CMatrix GetInterpolatedCameraMatrix() const; + float GetAccurateFOV() const; + private: CClientCamera(CClientManager* pManager); ~CClientCamera(); @@ -92,7 +105,12 @@ class CClientCamera final : public CClientEntity CMatrix GetGtaMatrix() const; void SetGtaMatrix(const CMatrix& matInNew, CCam* pCam = NULL) const; - void SetFocusToLocalPlayerImpl(); + void SetFocusToLocalPlayerImpl(); + void InvalidateCachedTransforms() const; + void SetCenterOfWorldCached(const CVector* pPosition, float fRotationRadians); + void UpdateCenterOfWorldFromFixedMatrix(); + const CMatrix& AcquirePulseMatrix() const; + const CVector& AcquirePulseEuler(const CMatrix& matrix) const; void UnreferenceEntity(CClientEntity* pEntity); void InvalidateEntity(CClientEntity* pEntity); @@ -112,5 +130,13 @@ class CClientCamera final : public CClientEntity float m_fFOV; CMatrix m_matFixedMatrix; + mutable CMatrix m_cachedPulseMatrix; + mutable CVector m_cachedPulseEuler; + mutable bool m_hasCachedPulseMatrix; + mutable bool m_hasCachedPulseEuler; + CVector m_lastCenterOfWorldPos; + float m_lastCenterOfWorldRot; + bool m_hasCenterOfWorld; + CCamera* m_pCamera; }; diff --git a/Client/mods/deathmatch/logic/CClientColCircle.cpp b/Client/mods/deathmatch/logic/CClientColCircle.cpp index 8641eaf12b5..4ddb65e901e 100644 --- a/Client/mods/deathmatch/logic/CClientColCircle.cpp +++ b/Client/mods/deathmatch/logic/CClientColCircle.cpp @@ -70,7 +70,7 @@ void CClientColCircle::DebugRender(const CVector& vecPosition, float fDrawRadius // Draw Slices { CVector vecMult(m_fRadius, m_fRadius, fHeight); - CVector vecAdd(vecOrigin.fX, vecOrigin.fY, vecBase.fZ + 4); // Extra bit so a slice is on the same Z coord as the camera + CVector vecAdd(vecOrigin.fX, vecOrigin.fY, vecBase.fZ + 4); // Extra bit so a slice is on the same Z coord as the camera for (uint s = iSkipEndSlices; s < uiNumSlices - iSkipEndSlices; s++) { diff --git a/Client/mods/deathmatch/logic/CClientColModel.cpp b/Client/mods/deathmatch/logic/CClientColModel.cpp index 294b65950fa..19c728cc88d 100644 --- a/Client/mods/deathmatch/logic/CClientColModel.cpp +++ b/Client/mods/deathmatch/logic/CClientColModel.cpp @@ -157,5 +157,16 @@ void CClientColModel::InternalRestore(unsigned short usModel) // Return true if data looks like COL file contents bool CClientColModel::IsCOLData(const SString& strData) { - return strData.length() > 32 && memcmp(strData, "COL", 3) == 0 && strData[7] == 0; + // COL file format: version[4] + size[4] + name[24] = minimum 32 bytes + // Version is 4-char string: "COLL", "COL2", "COL3", or "COL4" (not null-terminated) + if (strData.length() < 32) + return false; + + // Check if starts with "COL" magic number + if (memcmp(strData, "COL", 3) != 0) + return false; + + // Validate 4th character is valid version indicator + const char versionChar = strData[3]; + return versionChar == 'L' || versionChar == '2' || versionChar == '3' || versionChar == '4'; } diff --git a/Client/mods/deathmatch/logic/CClientColModel.h b/Client/mods/deathmatch/logic/CClientColModel.h index 081d5e44aae..01f98a278d8 100644 --- a/Client/mods/deathmatch/logic/CClientColModel.h +++ b/Client/mods/deathmatch/logic/CClientColModel.h @@ -36,9 +36,9 @@ class CClientColModel final : public CClientEntity static bool IsCOLData(const SString& strData); // Sorta a hack that these are required by CClientEntity... - void Unlink(){}; + void Unlink() {}; void GetPosition(CVector& vecPosition) const {}; - void SetPosition(const CVector& vecPosition){}; + void SetPosition(const CVector& vecPosition) {}; private: bool LoadFromFile(SString filePath); diff --git a/Client/mods/deathmatch/logic/CClientColPolygon.cpp b/Client/mods/deathmatch/logic/CClientColPolygon.cpp index afe63491184..59338f5cc64 100644 --- a/Client/mods/deathmatch/logic/CClientColPolygon.cpp +++ b/Client/mods/deathmatch/logic/CClientColPolygon.cpp @@ -195,7 +195,7 @@ void CClientColPolygon::DebugRender(const CVector& vecPosition, float fDrawRadiu for (uint s = iSkipEndSlices; s < uiNumSlices - iSkipEndSlices; s++) { float fZ = vecPosition.fZ - fDrawRadius + fDrawRadius * 2.0f * (s / (float)(uiNumSlices - 1)); - fZ += 4; // Extra bit so a slice is on the same Z coord as the camera + fZ += 4; // Extra bit so a slice is on the same Z coord as the camera if (m_fFloor <= fZ && fZ <= m_fCeil) { for (uint i = 0; i < uiNumPoints; i++) diff --git a/Client/mods/deathmatch/logic/CClientColRectangle.cpp b/Client/mods/deathmatch/logic/CClientColRectangle.cpp index 9aac4f72b2e..6daa0ea2b6d 100644 --- a/Client/mods/deathmatch/logic/CClientColRectangle.cpp +++ b/Client/mods/deathmatch/logic/CClientColRectangle.cpp @@ -67,7 +67,7 @@ void CClientColRectangle::DebugRender(const CVector& vecPosition, float fDrawRad static const CVector cornerPoints[] = {CVector(0, 0, 1), CVector(1, 0, 1), CVector(1, 1, 1), CVector(0, 1, 1)}; CVector vecMult = vecSize; - CVector vecAdd = vecBase + CVector(0, 0, 4); // Extra bit so a slice is on the same Z coord as the camera + CVector vecAdd = vecBase + CVector(0, 0, 4); // Extra bit so a slice is on the same Z coord as the camera for (uint s = iSkipEndSlicesZ; s < uiNumSlicesZ - iSkipEndSlicesZ; s++) { @@ -94,7 +94,7 @@ void CClientColRectangle::DebugRender(const CVector& vecPosition, float fDrawRad for (uint i = 0; i < NUMELMS(cornerPoints); i++) { if (!(i & 1)) - continue; // No end cap + continue; // No end cap const CVector& vecBegin = cornerPoints[i] * vecMult + vecAdd; const CVector& vecEnd = cornerPoints[(i + 1) % 4] * vecMult + vecAdd; pGraphics->DrawLine3DQueued(vecBegin, vecEnd, fLineWidth, color, eRenderStage::POST_FX); @@ -115,7 +115,7 @@ void CClientColRectangle::DebugRender(const CVector& vecPosition, float fDrawRad for (uint i = 0; i < NUMELMS(cornerPoints); i++) { if (!(i & 1)) - continue; // No end cap + continue; // No end cap const CVector& vecBegin = cornerPoints[i] * vecMult + vecAdd; const CVector& vecEnd = cornerPoints[(i + 1) % 4] * vecMult + vecAdd; pGraphics->DrawLine3DQueued(vecBegin, vecEnd, fLineWidth, color, eRenderStage::POST_FX); diff --git a/Client/mods/deathmatch/logic/CClientColTube.h b/Client/mods/deathmatch/logic/CClientColTube.h index ed6a345f3db..583b31eeef7 100644 --- a/Client/mods/deathmatch/logic/CClientColTube.h +++ b/Client/mods/deathmatch/logic/CClientColTube.h @@ -26,7 +26,7 @@ class CClientColTube final : public CClientColShape float GetRadius() { return m_fRadius; }; void SetRadius(float fRadius) { - m_fRadius = fRadius; + m_fRadius = (fRadius / 2.0f) + 0.15f; SizeChanged(); }; float GetHeight() { return m_fHeight; }; diff --git a/Client/mods/deathmatch/logic/CClientCommon.h b/Client/mods/deathmatch/logic/CClientCommon.h index a01416ac1d5..74b356f4b65 100644 --- a/Client/mods/deathmatch/logic/CClientCommon.h +++ b/Client/mods/deathmatch/logic/CClientCommon.h @@ -11,32 +11,32 @@ #pragma once // Defines the maximum amount of mimics (fake players) -#define MAX_MIMICS 50 +#define MAX_MIMICS 50 // Defines the maximum amount of real players -#define MAX_NET_PLAYERS_REAL 250 +#define MAX_NET_PLAYERS_REAL 250 // Defines the maximum amount of players inside the game (includes mimics) -#define MAX_NET_PLAYERS (MAX_NET_PLAYERS_REAL + MAX_MIMICS) +#define MAX_NET_PLAYERS (MAX_NET_PLAYERS_REAL + MAX_MIMICS) // Defines the min/max size for the player nick (who the hell came up with 22?) -#define MIN_PLAYER_NICK_LENGTH 1 -#define MAX_PLAYER_NICK_LENGTH 22 +#define MIN_PLAYER_NICK_LENGTH 1 +#define MAX_PLAYER_NICK_LENGTH 22 // Defines the min/max size for the player nametag (who the hell came up with 22?) -#define MIN_PLAYER_NAMETAG_LENGTH 1 -#define MAX_PLAYER_NAMETAG_LENGTH 64 +#define MIN_PLAYER_NAMETAG_LENGTH 1 +#define MAX_PLAYER_NAMETAG_LENGTH 64 -#define MAX_TEAM_NAME_LENGTH 255 +#define MAX_TEAM_NAME_LENGTH 255 // Defines the minimum fade time for a transfer -#define MIN_TRANSFER_TIME 1500 +#define MIN_TRANSFER_TIME 1500 // Defines the maximum size for a player name // #define MAX_PLAYER_NAME_LENGTH 32 // Defines the maximum size for a HTTP Download URL -#define MAX_HTTP_DOWNLOAD_URL 512 +#define MAX_HTTP_DOWNLOAD_URL 512 // Defines the maximum size for a HTTP Download URL (with file / directory information appended) #define MAX_HTTP_DOWNLOAD_URL_WITH_FILE 768 @@ -48,8 +48,8 @@ enum eHTTPDownloadType HTTP_DOWNLOAD_ENABLED_URL }; -#define CHATCOLOR_DEFAULT 235, 221, 178 -#define CHATCOLOR_INFO 255, 100, 100 +#define CHATCOLOR_DEFAULT 235, 221, 178 +#define CHATCOLOR_INFO 255, 100, 100 // Interfaces to Blue extern CCoreInterface* g_pCore; diff --git a/Client/mods/deathmatch/logic/CClientDFF.cpp b/Client/mods/deathmatch/logic/CClientDFF.cpp index 3de11df6bc2..326fdf10ee5 100644 --- a/Client/mods/deathmatch/logic/CClientDFF.cpp +++ b/Client/mods/deathmatch/logic/CClientDFF.cpp @@ -10,6 +10,9 @@ #include "StdInc.h" +std::vector CClientDFF::ms_DeferredModelRestores; +std::vector CClientDFF::ms_DeferredClumpDestroys; + CClientDFF::CClientDFF(CClientManager* pManager, ElementID ID) : ClassInit(this), CClientEntity(ID) { // Init @@ -27,6 +30,43 @@ CClientDFF::~CClientDFF() // Remove us from DFF manager list m_pDFFManager->RemoveFromList(this); + // During session shutdown (CClientManager being destroyed), element destruction + // order is arbitrary. Clear custom model pointers without restreaming or UnloadDFF + // to prevent RW data corruption or double-free. Resource stop uses the full + // restoration path below - CClientManager is still alive so cleanup is safe. + + if (m_pManager && m_pManager->IsBeingDeleted()) + { + for (auto usModel : m_Replaced) + { + CModelInfo* pModelInfo = g_pGame->GetModelInfo(usModel); + if (pModelInfo) + { + pModelInfo->ClearCustomModel(); + ms_DeferredModelRestores.push_back(usModel); + } + } + m_Replaced.clear(); + + // Save loaded template clumps for deferred destruction. UnloadDFF is + // skipped during DoDeleteAll because clump data may share geometry/ + // materials with game-owned model objects still being destroyed. + // FlushDeferredModelRestores destroys these after all entities and + // streamed models are gone. + for (auto& pair : m_LoadedClumpInfoMap) + { + if (pair.second.pClump) + ms_DeferredClumpDestroys.push_back(pair.second.pClump); + } + m_LoadedClumpInfoMap.clear(); + + // Remove clothes buffer references so OnCStreaming_RequestModel_Mid + // won't serve up our soon-to-be-freed m_RawDataBuffer pointer + g_pGame->GetRenderWare()->ClothesRemoveReplacement(m_RawDataBuffer.data()); + g_pGame->GetRenderWare()->ClothesRemoveFile(m_RawDataBuffer.data()); + return; + } + // Restore all our models RestoreModels(); @@ -47,10 +87,17 @@ RpClump* CClientDFF::GetLoadedClump(ushort usModelId) info.bTriedLoad = true; // Make sure previous model+collision is loaded - m_pManager->GetModelRequestManager()->RequestBlocking(usModelId, "CClientDFF::LoadDFF"); + if (!m_pManager->GetModelRequestManager()->RequestBlocking(usModelId, "CClientDFF::LoadDFF")) + AddReportLog(8631, SString("GetLoadedClump: RequestBlocking failed for model %d", usModelId)); + + // If engineImportTXD was called before the parent TXD was loaded, the model's + // TXD assignment and replacement textures were deferred. Now that RequestBlocking + // has loaded the model (and its TXD dependency), complete any pending setup so + // ReadDFF resolves textures from the correct child TXD. + g_pGame->GetRenderWare()->ProcessPendingIsolatedTxdParents(true); // Attempt loading it - if (!m_bIsRawData) // We have file + if (!m_bIsRawData) // We have file { if (g_pCore->GetNetwork()->CheckFile("dff", m_strDffFilename)) { @@ -58,7 +105,7 @@ RpClump* CClientDFF::GetLoadedClump(ushort usModelId) info.pClump = g_pGame->GetRenderWare()->ReadDFF(m_strDffFilename, SString(), usModelId, CClientVehicleManager::IsValidModel(usModelId)); } } - else // We have raw data + else // We have raw data { info.pClump = g_pGame->GetRenderWare()->ReadDFF(NULL, m_RawDataBuffer, usModelId, CClientVehicleManager::IsValidModel(usModelId)); @@ -93,7 +140,9 @@ void CClientDFF::UnloadDFF() { SLoadedClumpInfo& info = iter->second; if (info.pClump) + { g_pGame->GetRenderWare()->DestroyDFF(info.pClump); + } } m_LoadedClumpInfoMap.clear(); @@ -212,6 +261,11 @@ bool CClientDFF::DoReplaceModel(unsigned short usModel, bool bAlphaTransparency) } // No supported type or no loaded clump + if (!pClump) + AddReportLog(8632, SString("DoReplaceModel: GetLoadedClump returned null for model %d", usModel)); + else + AddReportLog(8633, SString("DoReplaceModel: No type match for model %d (loaded clump exists)", usModel)); + return false; } @@ -232,11 +286,12 @@ bool CClientDFF::HasReplaced(unsigned short usModel) return false; } -void CClientDFF::RestoreModel(unsigned short usModel) +bool CClientDFF::RestoreModel(unsigned short usModel) { // Restore the model and remove it from the list - InternalRestoreModel(usModel); + bool bRestored = InternalRestoreModel(usModel); m_Replaced.remove(usModel); + return bRestored; } void CClientDFF::RestoreModels() @@ -245,7 +300,7 @@ void CClientDFF::RestoreModels() std::list::iterator iter = m_Replaced.begin(); for (; iter != m_Replaced.end(); iter++) { - // Restore this model + // Restore this model (ignore return - bulk cleanup) InternalRestoreModel(*iter); } @@ -256,7 +311,7 @@ void CClientDFF::RestoreModels() m_Replaced.clear(); } -void CClientDFF::InternalRestoreModel(unsigned short usModel) +bool CClientDFF::InternalRestoreModel(unsigned short usModel) { // Is this a vehicle ID? if (CClientVehicleManager::IsValidModel(usModel)) @@ -266,7 +321,7 @@ void CClientDFF::InternalRestoreModel(unsigned short usModel) // eventually stream them back in with async loading. m_pManager->GetVehicleManager()->RestreamVehicles(usModel); } - // Is this an ped ID? + // Is this a ped ID? else if (CClientPlayerManager::IsValidModel(usModel)) { // Stream the ped of that model out so we have no @@ -295,18 +350,37 @@ void CClientDFF::InternalRestoreModel(unsigned short usModel) else if (CClientPlayerClothes::IsValidModel(usModel)) { g_pGame->GetRenderWare()->ClothesRemoveReplacement(m_RawDataBuffer.data()); - return; + return true; } else - return; + { + AddReportLog(9403, SString("InternalRestoreModel: Model %u not recognized as vehicle/ped/object/clothes", usModel), 10); + return false; + } - // Restore all the models we replaced. + // Restore model first - this releases texture replacement tracking refs CModelInfo* pModelInfo = g_pGame->GetModelInfo(usModel); + if (!pModelInfo) + { + AddReportLog(9405, SString("InternalRestoreModel: GetModelInfo returned null for model %u", usModel), 10); + return false; + } pModelInfo->ResetVehicleDummies(true); pModelInfo->ResetVehicleWheelSizes(); pModelInfo->RestoreOriginalModel(); pModelInfo->ResetAlphaTransparency(); + // Check if model was actually unloaded (immediate restore) + bool bModelUnloaded = !pModelInfo->IsLoaded(); + + // Only clean up isolated TXD if model has no refs (no entities using it) + // If refs remain, TXD cleanup is deferred to CClientModel::Deallocate + if (CRenderWare* pRenderWare = g_pGame->GetRenderWare()) + { + if (bModelUnloaded) + pRenderWare->CleanupIsolatedTxdForModel(usModel); + } + // 'Restream' upgrades after model replacement to propagate visual changes with immediate effect if (CClientObjectManager::IsValidModel(usModel) && CVehicleUpgrades::IsUpgrade(usModel)) m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel); @@ -323,6 +397,9 @@ void CClientDFF::InternalRestoreModel(unsigned short usModel) g_pGame->GetRenderWare()->DestroyDFF(pInfo->pClump); MapRemove(m_LoadedClumpInfoMap, usModel); } + + // Return true only if model was immediately restored (not deferred due to entities using it) + return bModelUnloaded; } bool CClientDFF::ReplaceClothes(ushort usModel) @@ -353,7 +430,11 @@ bool CClientDFF::ReplaceObjectModel(RpClump* pClump, ushort usModel, bool bAlpha CModelInfo* pModelInfo = g_pGame->GetModelInfo(usModel); if (!pModelInfo->SetCustomModel(pClump)) + { + AddReportLog(8635, SString("ReplaceObjectModel: SetCustomModel failed for model %d (loaded=%d, type=%d)", usModel, pModelInfo->IsLoaded() ? 1 : 0, + static_cast(pModelInfo->GetModelType()))); return false; + } pModelInfo->SetAlphaTransparencyEnabled(bAlphaTransparency); @@ -371,6 +452,8 @@ bool CClientDFF::ReplaceWeaponModel(RpClump* pClump, ushort usModel, bool bAlpha // or so. m_pManager->GetPedManager()->RestreamWeapon(usModel); m_pManager->GetPickupManager()->RestreamPickups(usModel); + m_pManager->GetObjectManager()->RestreamObjects(usModel); + g_pGame->GetModelInfo(usModel)->RestreamIPL(); // Grab the model info for that model and replace the model CModelInfo* pModelInfo = g_pGame->GetModelInfo(usModel); @@ -436,6 +519,36 @@ bool CClientDFF::ReplaceVehicleModel(RpClump* pClump, ushort usModel, bool bAlph return true; } +void CClientDFF::FlushDeferredModelRestores() +{ + if (ms_DeferredModelRestores.empty() && ms_DeferredClumpDestroys.empty()) + return; + + // After DoDeleteAll, all game entities are destroyed. Now it's safe to force-unload + // models that had custom DFF. Without this, it stays in + // GTA's streaming cache and carries over to the next server session. + for (unsigned short usModel : ms_DeferredModelRestores) + { + CModelInfo* pModelInfo = g_pGame->GetModelInfo(usModel); + if (pModelInfo && pModelInfo->IsLoaded()) + { + g_pGame->GetStreaming()->RemoveModel(usModel); + } + } + + ms_DeferredModelRestores.clear(); + + // Destroy template clumps that were kept alive during DoDeleteAll. + // Safe now: all game entities are gone and RemoveModel above unloaded + // the cloned DFF, so no shared references remain. + for (RpClump* pClump : ms_DeferredClumpDestroys) + { + if (pClump) + g_pGame->GetRenderWare()->DestroyDFF(pClump); + } + ms_DeferredClumpDestroys.clear(); +} + // Return true if data looks like DFF file contents bool CClientDFF::IsDFFData(const SString& strData) { diff --git a/Client/mods/deathmatch/logic/CClientDFF.h b/Client/mods/deathmatch/logic/CClientDFF.h index 22fc3ebef9f..eaebbb4a812 100644 --- a/Client/mods/deathmatch/logic/CClientDFF.h +++ b/Client/mods/deathmatch/logic/CClientDFF.h @@ -42,15 +42,20 @@ class CClientDFF final : public CClientEntity bool HasReplaced(unsigned short usModel); - void RestoreModel(unsigned short usModel); + bool RestoreModel(unsigned short usModel); void RestoreModels(); static bool IsDFFData(const SString& strData); + // After DoDeleteAll, unload models that had custom DFF replaced via ClearCustomModel. + // ClearCustomModel only nulls the clump pointer - the custom geometry stays loaded in + // GTA's streaming cache. This forces a re-stream from disk with original model data. + static void FlushDeferredModelRestores(); + // Sorta a hack that these are required by CClientEntity... - void Unlink(){}; + void Unlink() {}; void GetPosition(CVector& vecPosition) const {}; - void SetPosition(const CVector& vecPosition){}; + void SetPosition(const CVector& vecPosition) {}; private: bool LoadFromFile(SString filePath); @@ -58,7 +63,8 @@ class CClientDFF final : public CClientEntity bool DoReplaceModel(unsigned short usModel, bool bAlphaTransparency); void UnloadDFF(); - void InternalRestoreModel(unsigned short usModel); + + bool InternalRestoreModel(unsigned short usModel); bool ReplaceClothes(ushort usModel); bool ReplaceObjectModel(RpClump* pClump, ushort usModel, bool bAlphaTransparency); @@ -76,4 +82,7 @@ class CClientDFF final : public CClientEntity std::map m_LoadedClumpInfoMap; std::list m_Replaced; + + static std::vector ms_DeferredModelRestores; + static std::vector ms_DeferredClumpDestroys; }; diff --git a/Client/mods/deathmatch/logic/CClientDFFManager.cpp b/Client/mods/deathmatch/logic/CClientDFFManager.cpp index f466dd8407e..23bc52efe3a 100644 --- a/Client/mods/deathmatch/logic/CClientDFFManager.cpp +++ b/Client/mods/deathmatch/logic/CClientDFFManager.cpp @@ -89,11 +89,9 @@ bool CClientDFFManager::RestoreModel(unsigned short usModel) CClientDFF* pDFF = GetElementThatReplaced(usModel); if (pDFF) { - // Restore it - pDFF->RestoreModel(usModel); - - // Success - return true; + // Restore it and return whether it was immediately restored + // Returns false if model is still loaded (entities using it) + return pDFF->RestoreModel(usModel); } // Nothing to restore diff --git a/Client/mods/deathmatch/logic/CClientDisplayManager.cpp b/Client/mods/deathmatch/logic/CClientDisplayManager.cpp index 651b1d2efa1..357aabb8703 100644 --- a/Client/mods/deathmatch/logic/CClientDisplayManager.cpp +++ b/Client/mods/deathmatch/logic/CClientDisplayManager.cpp @@ -17,7 +17,7 @@ std::shared_ptr CClientDisplayManager::Get(unsigned long ulID) // Find the display with the given id auto iter = m_List.begin(); - for (; iter != m_List.end(); iter++) // Iterate weak_ptr list + for (; iter != m_List.end(); iter++) // Iterate weak_ptr list { if (const auto& display = (*iter).lock()) // Make sure the shared_ptr still exists { @@ -26,7 +26,6 @@ std::shared_ptr CClientDisplayManager::Get(unsigned long ulID) return display; } } - } return NULL; @@ -56,9 +55,9 @@ void CClientDisplayManager::DoPulse() // Clean up expired weak_ptr m_List.remove_if([](const std::weak_ptr& wp) { return wp.expired(); }); - for (; iter != m_List.end(); iter++) // Iterate weak_ptr list + for (; iter != m_List.end(); iter++) // Iterate weak_ptr list { - if (const auto& display = (*iter).lock()) // Make sure the shared_ptr still exists + if (const auto& display = (*iter).lock()) // Make sure the shared_ptr still exists { display->Render(); } diff --git a/Client/mods/deathmatch/logic/CClientDisplayManager.h b/Client/mods/deathmatch/logic/CClientDisplayManager.h index eac7e290842..9b87a15c327 100644 --- a/Client/mods/deathmatch/logic/CClientDisplayManager.h +++ b/Client/mods/deathmatch/logic/CClientDisplayManager.h @@ -31,7 +31,7 @@ class CClientDisplayManager void DoPulse(); - unsigned int Count() { return static_cast(m_List.size()); }; + unsigned int Count() { return static_cast(m_List.size()); }; std::shared_ptr Get(unsigned long ulID); void DrawText2D(const char* szCaption, const CVector& vecPosition, float fScale = 1.0f, RGBA rgbaColor = 0xFFFFFFFF); @@ -43,4 +43,3 @@ class CClientDisplayManager std::list> m_List; }; - diff --git a/Client/mods/deathmatch/logic/CClientEffectManager.cpp b/Client/mods/deathmatch/logic/CClientEffectManager.cpp index 0b5fbf92f5b..7eb18f5575f 100644 --- a/Client/mods/deathmatch/logic/CClientEffectManager.cpp +++ b/Client/mods/deathmatch/logic/CClientEffectManager.cpp @@ -37,7 +37,7 @@ CClientEffect* CClientEffectManager::Create(const SString& strEffectName, const CFxSystem* pFxSA = g_pGame->GetFxManager()->CreateFxSystem(strEffectName, vecPosition, NULL, true, bSoundEnable); if (pFxSA == NULL) - return NULL; // GTA was unable to create the effect (e.g. wrong effect name) + return NULL; // GTA was unable to create the effect (e.g. wrong effect name) CClientEffect* pFx = new CClientEffect(m_pManager, pFxSA, strEffectName, ID); m_Effects.push_back(pFx); @@ -86,7 +86,7 @@ void CClientEffectManager::SAEffectDestroyed(void* pFxSAInterface) g_pGame->GetFxManager()->OnFxSystemSAInterfaceDestroyed((CFxSystemSAInterface*)pFxSAInterface); if (pFx == NULL) - return; // We didn't create that effect + return; // We didn't create that effect pFx->SetFxSystem(NULL); g_pClientGame->GetElementDeleter()->Delete(pFx); diff --git a/Client/mods/deathmatch/logic/CClientEntity.cpp b/Client/mods/deathmatch/logic/CClientEntity.cpp index 849f218e25b..33b74e9b166 100644 --- a/Client/mods/deathmatch/logic/CClientEntity.cpp +++ b/Client/mods/deathmatch/logic/CClientEntity.cpp @@ -14,7 +14,7 @@ using std::list; extern CClientGame* g_pClientGame; -#pragma warning( disable : 4355 ) // warning C4355: 'this' : used in base member initializer list +#pragma warning(disable : 4355) // warning C4355: 'this' : used in base member initializer list CClientEntity::CClientEntity(ElementID ID) : ClassInit(this) { @@ -146,8 +146,7 @@ CClientEntity::~CClientEntity() } // Remove from spatial database - if (!g_pClientGame->IsBeingDeleted()) - GetClientSpatialDatabase()->RemoveEntity(this); + GetClientSpatialDatabase()->RemoveEntity(this); // Ensure not referenced in the disabled collisions list assert(!MapContains(g_pClientGame->m_AllDisabledCollisions, this)); @@ -279,12 +278,12 @@ void CClientEntity::SetID(ElementID ID) } } -CLuaArgument* CClientEntity::GetCustomData(const char* szName, bool bInheritData, bool* pbIsSynced) +CLuaArgument* CClientEntity::GetCustomData(const CStringName& name, bool bInheritData, bool* pbIsSynced) { - assert(szName); + assert(name); // Grab it and return a pointer to the variable - SCustomData* pData = m_pCustomData->Get(szName); + SCustomData* pData = m_pCustomData->Get(name); if (pData) { if (pbIsSynced) @@ -295,7 +294,7 @@ CLuaArgument* CClientEntity::GetCustomData(const char* szName, bool bInheritData // If none, try returning parent's custom data if (bInheritData && m_pParent) { - return m_pParent->GetCustomData(szName, true, pbIsSynced); + return m_pParent->GetCustomData(name, true, pbIsSynced); } // None available @@ -308,17 +307,17 @@ CLuaArguments* CClientEntity::GetAllCustomData(CLuaArguments* table) for (auto it = m_pCustomData->IterBegin(); it != m_pCustomData->IterEnd(); it++) { - table->PushString(it->first); // key - table->PushArgument(it->second.Variable); // value + table->PushString(it->first); // key + table->PushArgument(it->second.Variable); // value } return table; } -bool CClientEntity::GetCustomDataString(const char* szName, SString& strOut, bool bInheritData) +bool CClientEntity::GetCustomDataString(const CStringName& name, SString& strOut, bool bInheritData) { // Grab the custom data variable - CLuaArgument* pData = GetCustomData(szName, bInheritData); + CLuaArgument* pData = GetCustomData(name, bInheritData); if (pData) { // Write the content depending on what type it is @@ -350,10 +349,10 @@ bool CClientEntity::GetCustomDataString(const char* szName, SString& strOut, boo return false; } -bool CClientEntity::GetCustomDataInt(const char* szName, int& iOut, bool bInheritData) +bool CClientEntity::GetCustomDataInt(const CStringName& name, int& iOut, bool bInheritData) { // Grab the custom data variable - CLuaArgument* pData = GetCustomData(szName, bInheritData); + CLuaArgument* pData = GetCustomData(name, bInheritData); if (pData) { // Write the content depending on what type it is @@ -388,10 +387,10 @@ bool CClientEntity::GetCustomDataInt(const char* szName, int& iOut, bool bInheri return false; } -bool CClientEntity::GetCustomDataFloat(const char* szName, float& fOut, bool bInheritData) +bool CClientEntity::GetCustomDataFloat(const CStringName& name, float& fOut, bool bInheritData) { // Grab the custom data variable - CLuaArgument* pData = GetCustomData(szName, bInheritData); + CLuaArgument* pData = GetCustomData(name, bInheritData); if (pData) { // Write the content depending on what type it is @@ -415,10 +414,10 @@ bool CClientEntity::GetCustomDataFloat(const char* szName, float& fOut, bool bIn return false; } -bool CClientEntity::GetCustomDataBool(const char* szName, bool& bOut, bool bInheritData) +bool CClientEntity::GetCustomDataBool(const CStringName& name, bool& bOut, bool bInheritData) { // Grab the custom data variable - CLuaArgument* pData = GetCustomData(szName, bInheritData); + CLuaArgument* pData = GetCustomData(name, bInheritData); if (pData) { // Write the content depending on what type it is @@ -470,52 +469,52 @@ bool CClientEntity::GetCustomDataBool(const char* szName, bool& bOut, bool bInhe return false; } -void CClientEntity::SetCustomData(const char* szName, const CLuaArgument& Variable, bool bSynchronized) +void CClientEntity::SetCustomData(const CStringName& name, const CLuaArgument& Variable, bool bSynchronized) { - assert(szName); - if (strlen(szName) > MAX_CUSTOMDATA_NAME_LENGTH) + assert(name); + if (name->length() > MAX_CUSTOMDATA_NAME_LENGTH) { // Don't allow it to be set if the name is too long - CLogger::ErrorPrintf("Custom data name too long (%s)", *SStringX(szName).Left(MAX_CUSTOMDATA_NAME_LENGTH + 1)); + CLogger::ErrorPrintf("Custom data name too long (%s)", *SStringX(name.ToCString()).Left(MAX_CUSTOMDATA_NAME_LENGTH + 1)); return; } // Grab the old variable CLuaArgument oldVariable; - SCustomData* pData = m_pCustomData->Get(szName); + SCustomData* pData = m_pCustomData->Get(name); if (pData) { oldVariable = pData->Variable; } // Set the new data - m_pCustomData->Set(szName, Variable, bSynchronized); + m_pCustomData->Set(name, Variable, bSynchronized); // Trigger the onClientElementDataChange event on us CLuaArguments Arguments; - Arguments.PushString(szName); + Arguments.PushString(name); Arguments.PushArgument(oldVariable); Arguments.PushArgument(Variable); CallEvent("onClientElementDataChange", Arguments, true); } -void CClientEntity::DeleteCustomData(const char* szName) +void CClientEntity::DeleteCustomData(const CStringName& name) { // Grab the old variable - SCustomData* pData = m_pCustomData->Get(szName); + SCustomData* pData = m_pCustomData->Get(name); if (pData) { CLuaArgument oldVariable; oldVariable = pData->Variable; // Delete the custom data - m_pCustomData->Delete(szName); + m_pCustomData->Delete(name); // Trigger the onClientElementDataChange event on us CLuaArguments Arguments; - Arguments.PushString(szName); + Arguments.PushString(name); Arguments.PushArgument(oldVariable); - Arguments.PushArgument(CLuaArgument()); // Use nil as the new value to indicate the data has been removed + Arguments.PushArgument(CLuaArgument()); // Use nil as the new value to indicate the data has been removed CallEvent("onClientElementDataChange", Arguments, true); } } @@ -742,7 +741,7 @@ bool CClientEntity::AddEvent(CLuaMain* pLuaMain, const char* szName, const CLuaF return m_pEventManager->Add(pLuaMain, szName, iLuaFunction, bPropagated, eventPriority, fPriorityMod); } -bool CClientEntity::CallEvent(const char* szName, const CLuaArguments& Arguments, bool bCallOnChildren) +bool CClientEntity::CallEvent(const char* szName, const CLuaArguments& Arguments, bool bCallOnChildren, const char* minClientVersion) { if (!g_pClientGame->GetDebugHookManager()->OnPreEvent(szName, Arguments, this, NULL)) return false; @@ -755,12 +754,12 @@ bool CClientEntity::CallEvent(const char* szName, const CLuaArguments& Arguments pEvents->PreEventPulse(); // Call the event on our parents/us first - CallParentEvent(szName, Arguments, this); + CallParentEvent(szName, Arguments, this, minClientVersion); if (bCallOnChildren) { // Call it on all our children - CallEventNoParent(szName, Arguments, this); + CallEventNoParent(szName, Arguments, this, minClientVersion); } // Tell the event manager that we're done calling the event @@ -779,25 +778,26 @@ bool CClientEntity::CallEvent(const char* szName, const CLuaArguments& Arguments return (!pEvents->WasEventCancelled()); } -void CClientEntity::CallEventNoParent(const char* szName, const CLuaArguments& Arguments, CClientEntity* pSource) +void CClientEntity::CallEventNoParent(const char* szName, const CLuaArguments& Arguments, CClientEntity* pSource, const char* minClientVersion) { // Call it on us if this isn't the same class it was raised on // TODO not sure why the null check is necessary (eAi) if (pSource != this && m_pEventManager != NULL && m_pEventManager->HasEvents()) { - m_pEventManager->Call(szName, Arguments, pSource, this); + m_pEventManager->Call(szName, Arguments, pSource, this, minClientVersion); } // Call it on all our children if (!m_Children.empty()) { - for (CClientEntity* pEntity : *GetChildrenListSnapshot()) + CElementListSnapshotRef pChildrenSnapshot = GetChildrenListSnapshot(); + for (CClientEntity* pEntity : *pChildrenSnapshot) { if (!pEntity->IsBeingDeleted()) { if (!pEntity->m_pEventManager || pEntity->m_pEventManager->HasEvents() || !pEntity->m_Children.empty()) { - pEntity->CallEventNoParent(szName, Arguments, pSource); + pEntity->CallEventNoParent(szName, Arguments, pSource, minClientVersion); if (m_bBeingDeleted) break; } @@ -806,18 +806,18 @@ void CClientEntity::CallEventNoParent(const char* szName, const CLuaArguments& A } } -void CClientEntity::CallParentEvent(const char* szName, const CLuaArguments& Arguments, CClientEntity* pSource) +void CClientEntity::CallParentEvent(const char* szName, const CLuaArguments& Arguments, CClientEntity* pSource, const char* minClientVersion) { // Call the event on us if (m_pEventManager && m_pEventManager->HasEvents()) { - m_pEventManager->Call(szName, Arguments, pSource, this); + m_pEventManager->Call(szName, Arguments, pSource, this, minClientVersion); } // Call parent's handler if (m_pParent) { - m_pParent->CallParentEvent(szName, Arguments, pSource); + m_pParent->CallParentEvent(szName, Arguments, pSource, minClientVersion); } } @@ -1104,7 +1104,7 @@ bool CClientEntity::IsAttachedToElement(CClientEntity* pEntity, bool bRecursive) return true; if (!std::get(history.insert(pCurrent))) - break; // This should not be possible, but you never know + break; // This should not be possible, but you never know } return false; diff --git a/Client/mods/deathmatch/logic/CClientEntity.h b/Client/mods/deathmatch/logic/CClientEntity.h index 031c1418b8f..4ddd8baefb2 100644 --- a/Client/mods/deathmatch/logic/CClientEntity.h +++ b/Client/mods/deathmatch/logic/CClientEntity.h @@ -16,6 +16,7 @@ class CClientEntity; #include "CClientCommon.h" #include #include "logic/CClientEntityRefManager.h" +#include "CStringName.h" class CLuaFunctionRef; // Used to check fast version of getElementsByType @@ -23,20 +24,20 @@ class CLuaFunctionRef; class CClientManager; -#define IS_PED(entity) ((entity)->GetType()==CCLIENTPLAYER||(entity)->GetType()==CCLIENTPED) -#define IS_PLAYER(entity) ((entity)->GetType()==CCLIENTPLAYER) -#define IS_REMOTE_PLAYER(player) (IS_PLAYER(player)&&!(player)->IsLocalPlayer()) -#define IS_RADARMARKER(entity) ((entity)->GetType()==CCLIENTRADARMARKER) -#define IS_VEHICLE(entity) ((entity)->GetType()==CCLIENTVEHICLE) -#define IS_OBJECT(entity) ((entity)->GetType()==CCLIENTOBJECT) -#define IS_MARKER(entity) ((entity)->GetType()==CCLIENTMARKER) -#define IS_PICKUP(entity) ((entity)->GetType()==CCLIENTPICKUP) -#define IS_RADAR_AREA(entity) ((entity)->GetType()==CCLIENTRADARAREA) -#define IS_COLSHAPE(entity) ((entity)->GetType()==CCLIENTCOLSHAPE) -#define IS_PROJECTILE(entity) ((entity)->GetType()==CCLIENTPROJECTILE) -#define IS_GUI(entity) ((entity)->GetType()==CCLIENTGUI) -#define IS_IFP(entity) ((entity)->GetType()==CCLIENTIFP) -#define CHECK_CGUI(entity,type) (((CClientGUIElement*)entity)->GetCGUIElement()->GetType()==(type)) +#define IS_PED(entity) ((entity)->GetType() == CCLIENTPLAYER || (entity)->GetType() == CCLIENTPED) +#define IS_PLAYER(entity) ((entity)->GetType() == CCLIENTPLAYER) +#define IS_REMOTE_PLAYER(player) (IS_PLAYER(player) && !(player)->IsLocalPlayer()) +#define IS_RADARMARKER(entity) ((entity)->GetType() == CCLIENTRADARMARKER) +#define IS_VEHICLE(entity) ((entity)->GetType() == CCLIENTVEHICLE) +#define IS_OBJECT(entity) ((entity)->GetType() == CCLIENTOBJECT) +#define IS_MARKER(entity) ((entity)->GetType() == CCLIENTMARKER) +#define IS_PICKUP(entity) ((entity)->GetType() == CCLIENTPICKUP) +#define IS_RADAR_AREA(entity) ((entity)->GetType() == CCLIENTRADARAREA) +#define IS_COLSHAPE(entity) ((entity)->GetType() == CCLIENTCOLSHAPE) +#define IS_PROJECTILE(entity) ((entity)->GetType() == CCLIENTPROJECTILE) +#define IS_GUI(entity) ((entity)->GetType() == CCLIENTGUI) +#define IS_IFP(entity) ((entity)->GetType() == CCLIENTIFP) +#define CHECK_CGUI(entity, type) (((CClientGUIElement*)entity)->GetCGUIElement()->GetType() == (type)) enum eClientEntityType { @@ -57,7 +58,7 @@ enum eClientEntityType CCLIENTGUI, CCLIENTSPAWNPOINT_DEPRECATED, CCLIENTCOLSHAPE, - CCLIENTDUMMY, // anything user-defined + CCLIENTDUMMY, // anything user-defined SCRIPTFILE, CCLIENTDFF, CCLIENTCOL, @@ -201,14 +202,14 @@ class CClientEntity : public CClientEntityBase void SetID(ElementID ID); CCustomData* GetCustomDataPointer() { return m_pCustomData; } - CLuaArgument* GetCustomData(const char* szName, bool bInheritData, bool* pbIsSynced = nullptr); + CLuaArgument* GetCustomData(const CStringName& name, bool bInheritData, bool* pbIsSynced = nullptr); CLuaArguments* GetAllCustomData(CLuaArguments* table); - bool GetCustomDataString(const char* szKey, SString& strOut, bool bInheritData); - bool GetCustomDataFloat(const char* szKey, float& fOut, bool bInheritData); - bool GetCustomDataInt(const char* szKey, int& iOut, bool bInheritData); - bool GetCustomDataBool(const char* szKey, bool& bOut, bool bInheritData); - void SetCustomData(const char* szName, const CLuaArgument& Variable, bool bSynchronized = true); - void DeleteCustomData(const char* szName); + bool GetCustomDataString(const CStringName& name, SString& strOut, bool bInheritData); + bool GetCustomDataFloat(const CStringName& name, float& fOut, bool bInheritData); + bool GetCustomDataInt(const CStringName& name, int& iOut, bool bInheritData); + bool GetCustomDataBool(const CStringName& name, bool& bOut, bool bInheritData); + void SetCustomData(const CStringName& name, const CLuaArgument& Variable, bool bSynchronized = true); + void DeleteCustomData(const CStringName& name); virtual bool GetMatrix(CMatrix& matrix) const; virtual bool SetMatrix(const CMatrix& matrix); @@ -228,7 +229,7 @@ class CClientEntity : public CClientEntityBase virtual inline unsigned short GetDimension() { return m_usDimension; } virtual void SetDimension(unsigned short usDimension); - virtual void ModelRequestCallback(CModelInfo* pModelInfo){}; + virtual void ModelRequestCallback(CModelInfo* pModelInfo) {}; virtual bool IsOutOfBounds(); CModelInfo* GetModelInfo() { return m_pModelInfo; }; @@ -248,9 +249,9 @@ class CClientEntity : public CClientEntityBase bool AddEvent(CLuaMain* pLuaMain, const char* szName, const CLuaFunctionRef& iLuaFunction, bool bPropagated, EEventPriorityType eventPriority, float fPriorityMod); - bool CallEvent(const char* szName, const CLuaArguments& Arguments, bool bCallOnChildren); - void CallEventNoParent(const char* szName, const CLuaArguments& Arguments, CClientEntity* pSource); - void CallParentEvent(const char* szName, const CLuaArguments& Arguments, CClientEntity* pSource); + bool CallEvent(const char* szName, const CLuaArguments& Arguments, bool bCallOnChildren, const char* minClientVersion = nullptr); + void CallEventNoParent(const char* szName, const CLuaArguments& Arguments, CClientEntity* pSource, const char* minClientVersion = nullptr); + void CallParentEvent(const char* szName, const CLuaArguments& Arguments, CClientEntity* pSource, const char* minClientVersion = nullptr); bool DeleteEvent(CLuaMain* pLuaMain, const char* szName, const CLuaFunctionRef& iLuaFunction); void DeleteEvents(CLuaMain* pLuaMain, bool bRecursive); void DeleteAllEvents(); @@ -360,7 +361,7 @@ class CClientEntity : public CClientEntityBase CVector m_vecAttachedPosition; CVector m_vecAttachedRotation; std::vector m_AttachedEntities; - bool m_bDisallowAttaching; // Protect against attaching in destructor + bool m_bDisallowAttaching; // Protect against attaching in destructor bool m_bBeingDeleted; bool m_bSystemEntity; @@ -377,8 +378,8 @@ class CClientEntity : public CClientEntityBase bool m_bWorldIgnored; bool m_bCallPropagationEnabled; bool m_bDisallowCollisions; - bool m_canBeDestroyedByScript = true; // If true, destroyElement function will - // have no effect on this element + bool m_canBeDestroyedByScript = true; // If true, destroyElement function will + // have no effect on this element public: // Optimization for getElementsByType starting at root static void StartupEntitiesFromRoot(); diff --git a/Client/mods/deathmatch/logic/CClientEntityRefManager.h b/Client/mods/deathmatch/logic/CClientEntityRefManager.h index a12c5989362..5211c7b36c0 100644 --- a/Client/mods/deathmatch/logic/CClientEntityRefManager.h +++ b/Client/mods/deathmatch/logic/CClientEntityRefManager.h @@ -9,11 +9,9 @@ *****************************************************************************/ #ifdef MTA_DEBUG - #define ENTITY_REF_DEBUG( ptr, desc ) \ - SString ( "%08x %s", (int)ptr, desc ) + #define ENTITY_REF_DEBUG(ptr, desc) SString("%08x %s", (int)ptr, desc) #else - #define ENTITY_REF_DEBUG( ptr, desc ) \ - NULL + #define ENTITY_REF_DEBUG(ptr, desc) NULL #endif // diff --git a/Client/mods/deathmatch/logic/CClientExplosionManager.cpp b/Client/mods/deathmatch/logic/CClientExplosionManager.cpp index 583bbd62209..9ee6a90b001 100644 --- a/Client/mods/deathmatch/logic/CClientExplosionManager.cpp +++ b/Client/mods/deathmatch/logic/CClientExplosionManager.cpp @@ -39,6 +39,24 @@ bool CClientExplosionManager::Hook_StaticExplosionCreation(CEntity* pGameExplodi return g_pExplosionManager->Hook_ExplosionCreation(pGameExplodingEntity, pGameCreator, vecPosition, explosionType); } +eWeaponType CClientExplosionManager::GetWeaponTypeFromExplosionType(const eExplosionType explosionType) +{ + switch (explosionType) + { + case EXP_TYPE_GRENADE: + return WEAPONTYPE_GRENADE; + case EXP_TYPE_MOLOTOV: + return WEAPONTYPE_MOLOTOV; + case EXP_TYPE_ROCKET: + case EXP_TYPE_ROCKET_WEAK: + return WEAPONTYPE_ROCKET; + case EXP_TYPE_TANK_GRENADE: + return WEAPONTYPE_TANK_GRENADE; + default: + return WEAPONTYPE_EXPLOSION; + } +} + bool CClientExplosionManager::Hook_ExplosionCreation(CEntity* pGameExplodingEntity, CEntity* pGameCreator, const CVector& vecPosition, eExplosionType explosionType) { @@ -53,7 +71,23 @@ bool CClientExplosionManager::Hook_ExplosionCreation(CEntity* pGameExplodingEnti CClientEntity* const pResponsible = pPools->GetClientEntity(reinterpret_cast(pResponsibleGameEntity->GetInterface())); if (!pResponsible) - return false; + { + if (!pGameCreator) + return false; + + CClientPlayer* localPlayer = m_pManager->GetPlayerManager()->GetLocalPlayer(); + if (!localPlayer || localPlayer->GetGameEntity() != pGameCreator) + return false; + + eWeaponType explosionWeaponType = GetWeaponTypeFromExplosionType(explosionType); + + CLuaArguments arguments; + arguments.PushNumber(vecPosition.fX); + arguments.PushNumber(vecPosition.fY); + arguments.PushNumber(vecPosition.fZ); + arguments.PushNumber(explosionWeaponType); + return localPlayer->CallEvent("onClientExplosion", arguments, true); + } // Determine the used weapon eWeaponType explosionWeaponType = WEAPONTYPE_EXPLOSION; @@ -167,25 +201,22 @@ CExplosion* CClientExplosionManager::Create(eExplosionType explosionType, CVecto if (responsibleWeapon != WEAPONTYPE_UNARMED) m_LastWeaponType = responsibleWeapon; else + m_LastWeaponType = GetWeaponTypeFromExplosionType(explosionType); + + if (pCreator && pCreator->IsLocalEntity()) { - switch (explosionType) + bool allowExplosion = Hook_ExplosionCreation(nullptr, pGameCreator, vecPosition, explosionType); + if (!allowExplosion) + return nullptr; + } + else if (!pCreator) + { + CClientPlayer* localPlayer = m_pManager->GetPlayerManager()->GetLocalPlayer(); + if (localPlayer) { - case EXP_TYPE_GRENADE: - m_LastWeaponType = WEAPONTYPE_GRENADE; - break; - case EXP_TYPE_MOLOTOV: - m_LastWeaponType = WEAPONTYPE_MOLOTOV; - break; - case EXP_TYPE_ROCKET: - case EXP_TYPE_ROCKET_WEAK: - m_LastWeaponType = WEAPONTYPE_ROCKET; - break; - case EXP_TYPE_TANK_GRENADE: - m_LastWeaponType = WEAPONTYPE_TANK_GRENADE; - break; - default: - m_LastWeaponType = WEAPONTYPE_EXPLOSION; - break; + bool allowExplosion = Hook_ExplosionCreation(nullptr, localPlayer->GetGameEntity(), vecPosition, explosionType); + if (!allowExplosion) + return nullptr; } } diff --git a/Client/mods/deathmatch/logic/CClientExplosionManager.h b/Client/mods/deathmatch/logic/CClientExplosionManager.h index 0bfb37978f7..ea90478db95 100644 --- a/Client/mods/deathmatch/logic/CClientExplosionManager.h +++ b/Client/mods/deathmatch/logic/CClientExplosionManager.h @@ -35,4 +35,5 @@ class CClientExplosionManager private: CClientManager* m_pManager; + eWeaponType GetWeaponTypeFromExplosionType(const eExplosionType explosionType); }; diff --git a/Client/mods/deathmatch/logic/CClientGUIElement.h b/Client/mods/deathmatch/logic/CClientGUIElement.h index 51d58cf5aaf..a984ab59272 100644 --- a/Client/mods/deathmatch/logic/CClientGUIElement.h +++ b/Client/mods/deathmatch/logic/CClientGUIElement.h @@ -18,30 +18,30 @@ class CClientGUIElement; #define MAX_EVENT_NAME 256 -#define CGUI_GET_CCLIENTGUIELEMENT(x) static_cast < CClientGUIElement* > ( x->GetUserData () ) -#define CGUI_SET_CCLIENTGUIELEMENT(x,y) x->SetUserData ( reinterpret_cast < void* > ( y ) ) +#define CGUI_GET_CCLIENTGUIELEMENT(x) static_cast(x->GetUserData()) +#define CGUI_SET_CCLIENTGUIELEMENT(x, y) x->SetUserData(reinterpret_cast(y)) // use just for events, for all gui specific stuff use the funcs in the CGUI* classes // supports 2 events -#define IS_CGUIELEMENT_BUTTON(entity) ((entity)->GetCGUIType()==CGUI_BUTTON) -#define IS_CGUIELEMENT_CHECKBOX(entity) ((entity)->GetCGUIType()==CGUI_CHECKBOX) -#define IS_CGUIELEMENT_EDIT(entity) ((entity)->GetCGUIType()==CGUI_EDIT) -#define IS_CGUIELEMENT_GRIDLIST(entity) ((entity)->GetCGUIType()==CGUI_GRIDLIST) -#define IS_CGUIELEMENT_LABEL(entity) ((entity)->GetCGUIType()==CGUI_LABEL) -#define IS_CGUIELEMENT_MEMO(entity) ((entity)->GetCGUIType()==CGUI_MEMO) -#define IS_CGUIELEMENT_PROGRESSBAR(entity) ((entity)->GetCGUIType()==CGUI_PROGRESSBAR) -#define IS_CGUIELEMENT_SCROLLBAR(entity) ((entity)->GetCGUIType()==CGUI_SCROLLBAR) -#define IS_CGUIELEMENT_SCROLLPANE(entity) ((entity)->GetCGUIType()==CGUI_SCROLLPANE) -#define IS_CGUIELEMENT_RADIOBUTTON(entity) ((entity)->GetCGUIType()==CGUI_RADIOBUTTON) -#define IS_CGUIELEMENT_STATICIMAGE(entity) ((entity)->GetCGUIType()==CGUI_STATICIMAGE) -#define IS_CGUIELEMENT_TAB(entity) ((entity)->GetCGUIType()==CGUI_TAB) -#define IS_CGUIELEMENT_TABPANEL(entity) ((entity)->GetCGUIType()==CGUI_TABPANEL) -#define IS_CGUIELEMENT_COMBOBOX(entity) ((entity)->GetCGUIType()==CGUI_COMBOBOX) -#define IS_CGUIELEMENT_WINDOW(entity) ((entity)->GetCGUIType()==CGUI_WINDOW) - -#define IS_CGUIELEMENT_VALID_PARENT(entity) (IS_CGUIELEMENT_SCROLLPANE(entity) || IS_CGUIELEMENT_WINDOW(entity) || IS_CGUIELEMENT_TAB(entity) ) +#define IS_CGUIELEMENT_BUTTON(entity) ((entity)->GetCGUIType() == CGUI_BUTTON) +#define IS_CGUIELEMENT_CHECKBOX(entity) ((entity)->GetCGUIType() == CGUI_CHECKBOX) +#define IS_CGUIELEMENT_EDIT(entity) ((entity)->GetCGUIType() == CGUI_EDIT) +#define IS_CGUIELEMENT_GRIDLIST(entity) ((entity)->GetCGUIType() == CGUI_GRIDLIST) +#define IS_CGUIELEMENT_LABEL(entity) ((entity)->GetCGUIType() == CGUI_LABEL) +#define IS_CGUIELEMENT_MEMO(entity) ((entity)->GetCGUIType() == CGUI_MEMO) +#define IS_CGUIELEMENT_PROGRESSBAR(entity) ((entity)->GetCGUIType() == CGUI_PROGRESSBAR) +#define IS_CGUIELEMENT_SCROLLBAR(entity) ((entity)->GetCGUIType() == CGUI_SCROLLBAR) +#define IS_CGUIELEMENT_SCROLLPANE(entity) ((entity)->GetCGUIType() == CGUI_SCROLLPANE) +#define IS_CGUIELEMENT_RADIOBUTTON(entity) ((entity)->GetCGUIType() == CGUI_RADIOBUTTON) +#define IS_CGUIELEMENT_STATICIMAGE(entity) ((entity)->GetCGUIType() == CGUI_STATICIMAGE) +#define IS_CGUIELEMENT_TAB(entity) ((entity)->GetCGUIType() == CGUI_TAB) +#define IS_CGUIELEMENT_TABPANEL(entity) ((entity)->GetCGUIType() == CGUI_TABPANEL) +#define IS_CGUIELEMENT_COMBOBOX(entity) ((entity)->GetCGUIType() == CGUI_COMBOBOX) +#define IS_CGUIELEMENT_WINDOW(entity) ((entity)->GetCGUIType() == CGUI_WINDOW) + +#define IS_CGUIELEMENT_VALID_PARENT(entity) (IS_CGUIELEMENT_SCROLLPANE(entity) || IS_CGUIELEMENT_WINDOW(entity) || IS_CGUIELEMENT_TAB(entity)) class CClientGUIElement : public CClientEntity { @@ -66,7 +66,7 @@ class CClientGUIElement : public CClientEntity CLuaMain* GetVirtualMachine() { return m_pLuaMain; } // dummy overrides - void SetPosition(const CVector& vecDummy){}; + void SetPosition(const CVector& vecDummy) {}; void GetPosition(CVector& vecDummy) const {}; // cgui element access diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 9145708156c..6266149ea3f 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,7 @@ #include #include #include "CServerInfo.h" +#include "CClientPed.h" SString StringZeroPadout(const SString& strInput, uint uiPadoutSize) { @@ -73,6 +75,8 @@ CVector g_vecBulletFireEndPosition; #define DOUBLECLICK_TIMEOUT 330 #define DOUBLECLICK_MOVE_THRESHOLD 10.0f +#define MIN_CLIENT_REQ_ON_MOUSE_BUTTON_DOWN "1.7.0-7.26369" + static constexpr long long TIME_DISCORD_UPDATE_RATE = 15000; CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo()) @@ -80,6 +84,10 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo()) // Init the global var with ourself g_pClientGame = this; + g_pCore->UpdateWerCrashModuleBases(); + + CStaticFunctionDefinitions::PreInitialize(g_pCore, g_pGame, this, &m_Events); + // Packet handler m_pPacketHandler = new CPacketHandler(); @@ -102,10 +110,11 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo()) m_TargetedPlayerID = INVALID_ELEMENT_ID; m_pDamageEntity = NULL; m_DamagerID = INVALID_ELEMENT_ID; - m_ucDamageBodyPiece = 0xFF; - m_ucDamageWeapon = 0xFF; + m_ucDamageBodyPiece = BODYPART_INVALID; + m_ucDamageWeapon = WEAPONTYPE_INVALID; m_ulDamageTime = 0; m_bDamageSent = true; + m_serverProcessedDeath = false; m_bShowNetstat = false; m_bShowFPS = false; m_bHudAreaNameDisabled = false; @@ -113,13 +122,14 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo()) m_lMoney = 0; m_dwWanted = 0; m_timeLastDiscordStateUpdate = 0; - m_lastWeaponSlot = WEAPONSLOT_MAX; // last stored weapon slot, for weapon slot syncing to server (sets to invalid value) + m_lastWeaponSlot = WEAPONSLOT_MAX; // last stored weapon slot, for weapon slot syncing to server (sets to invalid value) ResetAmmoInClip(); m_bFocused = g_pCore->IsFocused(); m_bCursorEventsEnabled = false; m_bInitiallyFadedOut = true; + m_allowMultiCommandHandlers = MultiCommandHandlerPolicy::WARN; m_bIsPlayingBack = false; m_bFirstPlaybackFrame = false; @@ -376,10 +386,11 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo()) // Setup default states for Rich Presence g_vehicleTypePrefixes = { - _("Flying a UFO around"), _("Cruising around"), _("Riding the waves of"), - _("Riding the train in"), _("Flying around"), _("Flying around"), - _("Riding around"), _("Monster truckin' around"), _("Quaddin' around"), - _("Bunny hopping around"), _("Doing weird stuff in") + + _("Flying a UFO around"), _("Cruising around"), _("Riding the waves of"), _("Riding the train in"), + _("Flying around"), _("Flying around"), _("Riding around"), _("Monster truckin' around"), + _("Quaddin' around"), _("Bunny hopping around"), _("Doing weird stuff in") + }; g_playerTaskStates = { @@ -409,7 +420,7 @@ CClientGame::~CClientGame() m_bBeingDeleted = true; // Remove active projectile references to local player if (auto pLocalPlayer = g_pClientGame->GetLocalPlayer()) - g_pGame->GetProjectileInfo()->RemoveEntityReferences(pLocalPlayer->GetGameEntity()); + g_pGame->GetProjectileInfo()->RemoveEntityReferences(pLocalPlayer->GetGameEntity()); // Stop all explosions. Unfortunately this doesn't fix the crash // if a vehicle is destroyed while it explodes. @@ -465,6 +476,9 @@ CClientGame::~CClientGame() // Singular file download manager SAFE_DELETE(m_pSingularFileDownloadManager); + // Clear cached clothes from this session + g_pMultiplayer->FlushClothesCache(); + // NULL the message/net stuff g_pMultiplayer->SetPreContextSwitchHandler(NULL); g_pMultiplayer->SetPostContextSwitchHandler(NULL); @@ -544,8 +558,13 @@ CClientGame::~CClientGame() discord->UpdatePresence(); } + // Destruction order matters: destroy CClientTXD entities (via m_pManager) BEFORE + // StaticReset calls. TXD destructors need intact bookkeeping to clean up propery. + // Destroy our stuff - SAFE_DELETE(m_pManager); // Will trigger onClientResourceStop + CClientTXD::ClearPendingImports(); + SAFE_DELETE(m_pManager); // Will trigger onClientResourceStop + SAFE_DELETE(m_pNametags); SAFE_DELETE(m_pSyncDebug); SAFE_DELETE(m_pNetworkStats); @@ -566,6 +585,19 @@ CClientGame::~CClientGame() SAFE_DELETE(m_pRootEntity); + // Unload models that had custom DFF geometry cleared during DoDeleteAll. + // Must run after m_pRootEntity is gone and before StaticResetModelTextureReplacing. + CClientDFF::FlushDeferredModelRestores(); + + // Clear any remaining texture replacement/shader state after destroying entities. + // This ordering prevents global reset from running before late element destructors + // (e.g. CClientTXD) have a chance to clean up using RenderWare bookkeeping. + if (g_pGame && g_pGame->GetRenderWare()) + { + g_pGame->GetRenderWare()->StaticResetModelTextureReplacing(); + g_pGame->GetRenderWare()->StaticResetShaderSupport(); + } + SAFE_DELETE(m_pModelCacheManager); // SAFE_DELETE(m_pGameEntityXRefManager); SAFE_DELETE(m_pZoneNames); @@ -703,16 +735,10 @@ bool CClientGame::StartGame(const char* szNick, const char* szPassword, eServerT pBitStream->Write(strTemp.c_str(), MAX_PLAYER_NICK_LENGTH); pBitStream->Write(reinterpret_cast(Password.data), sizeof(MD5)); - // Append community information (Removed) + // Append community information (removed, but we keep this to retain protocol compat) std::string strUser; pBitStream->Write(strUser.c_str(), MAX_SERIAL_LENGTH); - // Send an empty string if server still has old Discord implementation (#2499) - if (g_pNet->CanServerBitStream(eBitStreamVersion::Discord_InitialImplementation) && !g_pNet->CanServerBitStream(eBitStreamVersion::Discord_Cleanup)) - { - pBitStream->WriteString(""); - } - // Send the packet as joindata g_pNet->SendPacket(PACKET_ID_PLAYER_JOINDATA, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); g_pNet->DeallocateNetBitStream(pBitStream); @@ -818,6 +844,8 @@ void CClientGame::DoPulsePreHUDRender(bool bDidUnminimize, bool bDidRecreateRend // Allow scripted dxSetRenderTarget for old scripts g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); + CClientTXD::ProcessPendingImports(); + // If appropriate, call onClientRestore if (bDidUnminimize) { @@ -937,8 +965,8 @@ void CClientGame::DoPulsePostFrame() // Draw network trouble message if required if (m_pNetAPI->IsNetworkTrouble()) { - int iPosX = uiWidth / 2; // Half way across - int iPosY = uiHeight * 45 / 100; // 45/100 down + int iPosX = uiWidth / 2; // Half way across + int iPosY = uiHeight * 45 / 100; // 45/100 down g_pCore->GetGraphics()->DrawString(iPosX, iPosY, iPosX, iPosY, COLOR_ARGB(255, 255, 0, 0), "*** NETWORK TROUBLE ***", 2.0f, 2.0f, DT_NOCLIP | DT_CENTER); } @@ -1030,12 +1058,12 @@ void CClientGame::DoPulsePostFrame() } auto taskManager = pLocalPlayer->GetTaskManager(); - auto task = taskManager->GetActiveTask(); + auto task = taskManager->GetActiveTask(); auto pVehicle = pLocalPlayer->GetOccupiedVehicle(); bool useZoneName = true; const eClientVehicleType vehicleType = (pVehicle) ? CClientVehicleManager::GetVehicleType(pVehicle->GetModel()) : CLIENTVEHICLE_NONE; - std::string discordState = (pVehicle) ? g_vehicleTypePrefixes.at(vehicleType).c_str() : _("Walking around "); + std::string discordState = (pVehicle) ? g_vehicleTypePrefixes.at(vehicleType) : _("Walking around "); if (task && task->IsValid()) { @@ -1051,7 +1079,7 @@ void CClientGame::DoPulsePostFrame() } // Check for non-matching sub/secondary tasks and remove them - for (auto it = taskStates.begin(); it != taskStates.end(); ) + for (auto it = taskStates.begin(); it != taskStates.end();) { const STaskState& taskState = (*it); @@ -1078,13 +1106,15 @@ void CClientGame::DoPulsePostFrame() const int stateCount = taskStates.size(); if (stateCount > 0) { - std::srand(GetTickCount64_()); - const int index = (std::rand() % stateCount); + const std::uint64_t tickCount = static_cast(GetTickCount64_()); + const unsigned int seed = static_cast(tickCount ^ (tickCount >> 32)); + std::srand(seed); + const int index = (std::rand() % stateCount); const auto& taskState = taskStates[index]; discordState = taskState.strState; useZoneName = taskState.bUseZone; - } + } if (useZoneName) { @@ -1122,8 +1152,7 @@ void CClientGame::DoPulses() { TIMING_CHECKPOINT("-CClientGame::DoPulsePostFrame"); - g_pCore->ApplyFrameRateLimit(); - + // TODO: (pxd) Useless, cleanup checkpoints on #4428 TIMING_CHECKPOINT("+CClientGame::DoPulses"); m_BuiltCollisionMapThisFrame = false; @@ -1389,7 +1418,7 @@ void CClientGame::DoPulses() { case RID_RSA_PUBLIC_KEY_MISMATCH: strError = _("Disconnected: unknown protocol error"); - strErrorCode = _E("CD10"); // encryption key mismatch + strErrorCode = _E("CD10"); // encryption key mismatch break; case RID_REMOTE_DISCONNECTION_NOTIFICATION: strError = _("Disconnected: disconnected remotely"); @@ -1455,16 +1484,25 @@ void CClientGame::DoPulses() m_pLocalPlayer->UpdateVehicleInOut(); UpdatePlayerTarget(); UpdatePlayerWeapons(); - UpdateTrailers(); // Test: Does it always work without this check? + UpdateTrailers(); // Test: Does it always work without this check? UpdateStunts(); // Clear last damager if more than 2 seconds old if (CClientTime::GetTime() - m_ulDamageTime > 2000) { m_DamagerID = INVALID_ELEMENT_ID; - m_ucDamageWeapon = 0xFF; - m_ucDamageBodyPiece = 0xFF; + m_ucDamageWeapon = WEAPONTYPE_INVALID; + m_ucDamageBodyPiece = BODYPART_INVALID; + } + // Check if we need to trigger death event + if (!m_pLocalPlayer->IsDeadOnNetwork() && m_pLocalPlayer->GetHealth() == 0.0f) + { + // Only call DoWastedCheck if server hasn't already processed this death + // This prevents duplicate events when server processes death via unified context system + if (!m_serverProcessedDeath) + { + DoWastedCheck(m_DamagerID, m_ucDamageWeapon, m_ucDamageBodyPiece); + } } - DoWastedCheck(m_DamagerID, m_ucDamageWeapon, m_ucDamageBodyPiece); } // Game hacks, restore certain variables @@ -1829,12 +1867,10 @@ void CClientGame::UpdatePlayerWeapons() SWeaponSlotSync slot; // Always send bit in case server is not in sync - if ((BitStream.Version() >= 0x44 && m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN) || BitStream.Version() >= 0x4D) { CWeapon* pLastWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); if (pLastWeapon && pLastWeapon->GetAmmoTotal() == 0 && - (m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN || - (BitStream.Version() >= 0x5A && (m_lastWeaponSlot == WEAPONSLOT_TYPE_HEAVY || m_lastWeaponSlot == WEAPONSLOT_TYPE_SPECIAL)))) + (m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN || m_lastWeaponSlot == WEAPONSLOT_TYPE_HEAVY || m_lastWeaponSlot == WEAPONSLOT_TYPE_SPECIAL)) BitStream.WriteBit(true); else BitStream.WriteBit(false); @@ -2009,7 +2045,7 @@ void CClientGame::UpdateFireKey() { if (pTargetPed->IsLocalEntity()) { - CStaticFunctionDefinitions::KillPed(*pTargetPed, m_pLocalPlayer, 4 /*WEAPONTYPE_KNIFE*/, 9 /*BODYPART_HEAD*/, true); + CStaticFunctionDefinitions::KillPed(*pTargetPed, m_pLocalPlayer, WEAPONTYPE_KNIFE, BODYPART_HEAD, true); return; } @@ -2204,16 +2240,16 @@ bool CClientGame::KeyStrokeHandler(const SString& strKey, bool bState, bool bIsC if (g_pCore->IsMenuVisible() || (g_pCore->GetConsole()->IsInputActive() && bIsConsoleInputKey) || (pFocusedBrowser && !pFocusedBrowser->IsLocal() && !isMouseKey)) - bIgnore = true; // Ignore this keydown and the matching keyup + bIgnore = true; // Ignore this keydown and the matching keyup else - MapInsert(m_AllowKeyUpMap, strKey); // Use this keydown and the matching keyup + MapInsert(m_AllowKeyUpMap, strKey); // Use this keydown and the matching keyup } else { if (!MapContains(m_AllowKeyUpMap, strKey)) - bIgnore = true; // Ignore this keyup + bIgnore = true; // Ignore this keyup else - MapRemove(m_AllowKeyUpMap, strKey); // Use this keyup + MapRemove(m_AllowKeyUpMap, strKey); // Use this keyup } if (!bIgnore) @@ -2638,6 +2674,10 @@ void CClientGame::AddBuiltInEvents() m_Events.AddEvent("onClientElementModelChange", "oldModel, newModel", nullptr, false); m_Events.AddEvent("onClientElementDimensionChange", "oldDimension, newDimension", nullptr, false); m_Events.AddEvent("onClientElementInteriorChange", "oldInterior, newInterior", nullptr, false); + m_Events.AddEvent("onClientElementAttach", "attachSource, attachOffsetX, attachOffsetY, attachOffsetZ, attachOffsetRX, attachOffsetRY, attachOffsetRZ", + nullptr, false); + m_Events.AddEvent("onClientElementDetach", "detachSource, detachWorldX, detachWorldY, detachWorldZ, detachWorldRX, detachWorldRY, detachWorldRZ", nullptr, + false); // Player events m_Events.AddEvent("onClientPlayerJoin", "", NULL, false); @@ -2654,6 +2694,7 @@ void CClientGame::AddBuiltInEvents() m_Events.AddEvent("onClientPlayerRadioSwitch", "", NULL, false); m_Events.AddEvent("onClientPlayerDamage", "attacker, weapon, bodypart", NULL, false); m_Events.AddEvent("onClientPlayerWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); + m_Events.AddEvent("onClientPlayerWeaponReload", "weapon, clip, ammo", nullptr, false); m_Events.AddEvent("onClientPlayerWasted", "ammo, killer, weapon, bodypart, isStealth, animGroup, animID", nullptr, false); m_Events.AddEvent("onClientPlayerChoke", "", NULL, false); m_Events.AddEvent("onClientPlayerVoiceStart", "", NULL, false); @@ -2672,6 +2713,7 @@ void CClientGame::AddBuiltInEvents() m_Events.AddEvent("onClientPedVehicleEnter", "vehicle, seat", NULL, false); m_Events.AddEvent("onClientPedVehicleExit", "vehicle, seat", NULL, false); m_Events.AddEvent("onClientPedWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); + m_Events.AddEvent("onClientPedWeaponReload", "weapon, clip, ammo", nullptr, false); m_Events.AddEvent("onClientPedWasted", "", NULL, false); m_Events.AddEvent("onClientPedChoke", "", NULL, false); m_Events.AddEvent("onClientPedHeliKilled", "heli", NULL, false); @@ -2743,10 +2785,13 @@ void CClientGame::AddBuiltInEvents() m_Events.AddEvent("onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false); // Marker events - m_Events.AddEvent("onClientMarkerHit", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientMarkerLeave", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientMarkerHit", "entity, matchingDimension", nullptr, false); + m_Events.AddEvent("onClientMarkerLeave", "entity, matchingDimension", nullptr, false); - // Marker events + m_Events.AddEvent("onClientPlayerMarkerHit", "marker, matchingDimension", nullptr, false); + m_Events.AddEvent("onClientPlayerMarkerLeave", "marker, matchingDimension", nullptr, false); + + // Pickup events m_Events.AddEvent("onClientPickupHit", "entity, matchingDimension", NULL, false); m_Events.AddEvent("onClientPickupLeave", "entity, matchingDimension", NULL, false); @@ -3067,7 +3112,7 @@ void CClientGame::UpdateMimics() } // Simulate lag (or not) - if (!m_bMimicLag || CClientTime::GetTime() >= m_ulLastMimicLag + 200) // TICK_RATE ) + if (!m_bMimicLag || CClientTime::GetTime() >= m_ulLastMimicLag + 200) // TICK_RATE ) { m_ulLastMimicLag = CClientTime::GetTime(); @@ -3217,19 +3262,19 @@ void CClientGame::UpdateMimics() CClientVehicle* pMimicVehicle = pMimic->GetOccupiedVehicle(); if (pVehicle) { - unsigned int uiModel; - CVector vecPosition, vecRotationDegrees; - CVector vecMoveSpeed, vecMoveSpeedMeters, vecTurnSpeed, vecVelocity; - float fHealth; + unsigned short modelId; + CVector vecPosition, vecRotationDegrees; + CVector vecMoveSpeed, vecMoveSpeedMeters, vecTurnSpeed, vecVelocity; + float fHealth; - uiModel = pVehicle->GetModel(); + modelId = pVehicle->GetModel(); pVehicle->GetPosition(vecPosition); pVehicle->GetRotationDegrees(vecRotationDegrees); pVehicle->GetMoveSpeed(vecMoveSpeed); pVehicle->GetTurnSpeed(vecTurnSpeed); fHealth = pVehicle->GetHealth(); - if (pMimicVehicle && pMimicVehicle->GetModel() != uiModel) + if (pMimicVehicle && pMimicVehicle->GetModel() != modelId) { delete pMimicVehicle; pMimicVehicle = NULL; @@ -3239,7 +3284,7 @@ void CClientGame::UpdateMimics() if (pMimicVehicle == NULL) { - pMimicVehicle = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, INVALID_ELEMENT_ID, uiModel, 0, 0); + pMimicVehicle = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, INVALID_ELEMENT_ID, modelId, 0, 0); pMimicVehicle->SetPosition(vecPosition); const SSlotStates& usUpgrades = pVehicle->GetUpgrades()->GetSlotStates(); @@ -3277,7 +3322,7 @@ void CClientGame::UpdateMimics() CClientVehicle* pMimicTrailer = NULL; while (pTrailer) { - uiModel = pTrailer->GetModel(); + modelId = pTrailer->GetModel(); pTrailer->GetPosition(vecPosition); pTrailer->GetRotationDegrees(vecRotationDegrees); pTrailer->GetMoveSpeed(vecMoveSpeed); @@ -3286,7 +3331,7 @@ void CClientGame::UpdateMimics() pMimicTrailer = DynamicCast(CElementIDs::GetElement(static_cast(450 + uiMimicIndex + uiTrailerLoop))); - if (pMimicTrailer && pMimicTrailer->GetModel() != uiModel) + if (pMimicTrailer && pMimicTrailer->GetModel() != modelId) { delete pMimicTrailer; pMimicTrailer = NULL; @@ -3295,7 +3340,7 @@ void CClientGame::UpdateMimics() if (!pMimicTrailer) { pMimicTrailer = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, - static_cast(450 + uiMimicIndex + uiTrailerLoop), uiModel, 0, 0); + static_cast(450 + uiMimicIndex + uiTrailerLoop), modelId, 0, 0); pMimicVehicle->SetTowedVehicle(pMimicTrailer); } @@ -3465,7 +3510,7 @@ void CClientGame::Event_OnIngame() // Reset anything from last game ResetMapInfo(); - g_pGame->GetWaterManager()->Reset(); // Deletes all custom water elements, ResetMapInfo only reverts changes to water level + g_pGame->GetWaterManager()->Reset(); // Deletes all custom water elements, ResetMapInfo only reverts changes to water level g_pGame->GetWaterManager()->SetWaterDrawnLast(true); m_pCamera->SetCameraClip(true, true); @@ -3554,9 +3599,9 @@ void CClientGame::StaticDeathHandler(CPed* pKilledPed, unsigned char ucDeathReas g_pClientGame->DeathHandler(pKilledPed, ucDeathReason, ucBodyPart); } -void CClientGame::StaticFireHandler(CFire* pFire) +bool CClientGame::StaticFireHandler(CEntitySAInterface* target, CEntitySAInterface* creator) { - g_pClientGame->FireHandler(pFire); + return g_pClientGame->FireHandler(target, creator); } void CClientGame::StaticRender3DStuffHandler() @@ -3629,6 +3674,9 @@ void CClientGame::StaticPostWorldProcessPedsAfterPreRenderHandler() void CClientGame::StaticPreFxRenderHandler() { + // RenderFadingInEntities is done at this point, so alpha entity list callbacks + // no longer reference CModelRenderer's queue elements. + g_pClientGame->GetModelRenderer()->NotifyFrameEnd(); g_pCore->OnPreFxRender(); } @@ -3725,6 +3773,11 @@ void CClientGame::StaticGameEntityRenderHandler(CEntitySAInterface* pGameEntity) CClientEntity* pClientEntity = pPools->GetClientEntity((DWORD*)pGameEntity); if (pClientEntity) { + if (pClientEntity->IsBeingDeleted()) + { + g_pGame->GetRenderWare()->SetRenderingClientEntity(nullptr, 0xFFFF, TYPE_MASK_WORLD); + return; + } int iTypeMask; ushort usModelId = 0xFFFF; switch (pClientEntity->GetType()) @@ -3752,7 +3805,7 @@ void CClientGame::StaticGameEntityRenderHandler(CEntitySAInterface* pGameEntity) } } - g_pGame->GetRenderWare()->SetRenderingClientEntity(NULL, 0xFFFF, TYPE_MASK_WORLD); + g_pGame->GetRenderWare()->SetRenderingClientEntity(nullptr, 0xFFFF, TYPE_MASK_WORLD); } void CClientGame::StaticTaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) @@ -3816,10 +3869,22 @@ bool CClientGame::BreakTowLinkHandler(CVehicle* pTowedVehicle) return true; } -void CClientGame::FireHandler(CFire* pFire) +bool CClientGame::FireHandler(CEntitySAInterface* target, CEntitySAInterface* creator) { - // Disable spreading fires - pFire->SetNumGenerationsAllowed(0); + CClientEntity* creatorClientEntity = g_pGame->GetPools()->GetClientEntity((DWORD*)creator); + CClientEntity* targetClientEntity = g_pGame->GetPools()->GetClientEntity((DWORD*)target); + + if (creatorClientEntity && targetClientEntity && IS_PLAYER(targetClientEntity) && IS_PLAYER(creatorClientEntity)) + { + CClientPlayer* targetPlayer = static_cast(targetClientEntity); + CClientPlayer* creatorPlayer = static_cast(creatorClientEntity); + + CClientTeam* targetPlayerTeam = targetPlayer->GetTeam(); + if (targetPlayerTeam && targetPlayer->IsOnMyTeam(creatorPlayer) && !targetPlayerTeam->GetFriendlyFire() && creatorPlayer != targetPlayer) + return false; + } + + return true; } void CClientGame::ProjectileInitiateHandler(CClientProjectile* pProjectile) @@ -4281,7 +4346,7 @@ bool CClientGame::DamageHandler(CPed* pDamagePed, CEventDamage* pEvent) CClientPlayer* pInflictingPlayer = DynamicCast(pInflictingEntity); if (pInflictingPlayer && !pInflictingPlayer->IsLocalPlayer()) { - bool bBulletSyncShot = (g_iDamageEventLimit != -1); // Called from discharge weapon + bool bBulletSyncShot = (g_iDamageEventLimit != -1); // Called from discharge weapon bool bBulletSyncWeapon = GetWeaponTypeUsesBulletSync(weaponUsed); if (bBulletSyncShot) @@ -4490,7 +4555,10 @@ bool CClientGame::ApplyPedDamageFromGame(eWeaponType weaponUsed, float fDamage, GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); // Check if we're dead - DoWastedCheck(damagerID, weaponUsed, hitZone, animGroup, animID); + if (!m_serverProcessedDeath) + { + DoWastedCheck(damagerID, weaponUsed, hitZone, animGroup, animID); + } } // Allow GTA to kill us if we've fell to our death @@ -4558,6 +4626,14 @@ void CClientGame::DeathHandler(CPed* pKilledPedSA, unsigned char ucDeathReason, if (!pKilledPed) return; + // For local player in vehicle explosions, set damage data for consistent client events + if (IS_PLAYER(pKilledPed) && pKilledPed->IsLocalPlayer() && ucDeathReason == WEAPONTYPE_EXPLOSION) + { + // Set explosion damage data so DoWastedCheck uses correct parameters + SetExplosionDamageData(); + return; // Local player death is handled by DoWastedCheck + } + // Not required for remote players. Local player is handled in DoPulses->DoWastedCheck if (IS_PLAYER(pKilledPed)) return; @@ -4578,7 +4654,8 @@ void CClientGame::DeathHandler(CPed* pKilledPedSA, unsigned char ucDeathReason, } bool CClientGame::VehicleCollisionHandler(CVehicleSAInterface*& pCollidingVehicle, CEntitySAInterface* pCollidedWith, int iModelIndex, float fDamageImpulseMag, - float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity, bool isProjectile) + float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity, + bool isProjectile) { if (pCollidingVehicle && pCollidedWith) { @@ -4593,7 +4670,8 @@ bool CClientGame::VehicleCollisionHandler(CVehicleSAInterface*& pCollidingVehicl } CClientVehicle* pClientVehicle = static_cast(pVehicleClientEntity); - CClientEntity* pCollidedWithClientEntity = !isProjectile ? pPools->GetClientEntity((DWORD*)pCollidedWith) : m_pManager->GetProjectileManager()->Get(pCollidedWith); + CClientEntity* pCollidedWithClientEntity = + !isProjectile ? pPools->GetClientEntity((DWORD*)pCollidedWith) : m_pManager->GetProjectileManager()->Get(pCollidedWith); CLuaArguments Arguments; if (pCollidedWithClientEntity) @@ -4625,34 +4703,31 @@ bool CClientGame::VehicleCollisionHandler(CVehicleSAInterface*& pCollidingVehicl // Make sure it created if (pBitStream) { - if (pBitStream->Version() >= 0x028) + // Sync Stuff + // if it's not a local vehicle + it collided with the local player + if (pVehicleClientEntity->IsLocalEntity() == false && pCollidedWithClientEntity == g_pClientGame->GetLocalPlayer()) { - // Sync Stuff - // if it's not a local vehicle + it collided with the local player - if (pVehicleClientEntity->IsLocalEntity() == false && pCollidedWithClientEntity == g_pClientGame->GetLocalPlayer()) + // is it below the anti spam threshold? + if (pClientVehicle->GetTimeSinceLastPush() >= MIN_PUSH_ANTISPAM_RATE) { - // is it below the anti spam threshold? - if (pClientVehicle->GetTimeSinceLastPush() >= MIN_PUSH_ANTISPAM_RATE) + // if there is no controlling player + if (!pClientVehicle->GetControllingPlayer()) { - // if there is no controlling player - if (!pClientVehicle->GetControllingPlayer()) + CDeathmatchVehicle* Vehicle = static_cast(pVehicleClientEntity); + // if We aren't already syncing the vehicle + if (GetUnoccupiedVehicleSync()->Exists(Vehicle) == false) { - CDeathmatchVehicle* Vehicle = static_cast(pVehicleClientEntity); - // if We aren't already syncing the vehicle - if (GetUnoccupiedVehicleSync()->Exists(Vehicle) == false) - { - // Write the vehicle ID - pBitStream->Write(pVehicleClientEntity->GetID()); - // Send! - g_pNet->SendPacket(PACKET_ID_VEHICLE_PUSH_SYNC, pBitStream, PACKET_PRIORITY_MEDIUM, - PACKET_RELIABILITY_UNRELIABLE_SEQUENCED); - // Reset our push time - pClientVehicle->ResetLastPushTime(); - } + // Write the vehicle ID + pBitStream->Write(pVehicleClientEntity->GetID()); + // Send! + g_pNet->SendPacket(PACKET_ID_VEHICLE_PUSH_SYNC, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_UNRELIABLE_SEQUENCED); + // Reset our push time + pClientVehicle->ResetLastPushTime(); } } } } + g_pNet->DeallocateNetBitStream(pBitStream); } return true; @@ -4911,20 +4986,36 @@ bool CClientGame::VehicleFellThroughMapHandler(CVehicleSAInterface* pVehicleInte return false; } -// Validate known objects +// Called when GTA:SA destroys an entity (e.g., during map streaming). +// Clear stale pool entries to prevent dangling pointer crashes in GetClientEntity/GetEntity. +// Note: This may leak the CObjectSA/CVehicleSA/CPedSA wrapper if MTA created it, but we cannot +// safely delete it here since the game entity is mid-destruction. The leak is acceptable +// as this is an abnormal code path (GTA destroying MTA-managed entities). void CClientGame::GameObjectDestructHandler(CEntitySAInterface* pObject) { - // m_pGameEntityXRefManager->OnGameEntityDestruct(pObject); + if (auto* pSlot = g_pGame->GetPools()->GetObject(reinterpret_cast(pObject))) + { + pSlot->pEntity = nullptr; + pSlot->pClientEntity = nullptr; + } } void CClientGame::GameVehicleDestructHandler(CEntitySAInterface* pVehicle) { - // m_pGameEntityXRefManager->OnGameEntityDestruct(pVehicle); + if (auto* pSlot = g_pGame->GetPools()->GetVehicle(reinterpret_cast(pVehicle))) + { + pSlot->pEntity = nullptr; + pSlot->pClientEntity = nullptr; + } } void CClientGame::GamePlayerDestructHandler(CEntitySAInterface* pPlayer) { - // m_pGameEntityXRefManager->OnGameEntityDestruct(pPlayer); + if (auto* pSlot = g_pGame->GetPools()->GetPed(reinterpret_cast(pPlayer))) + { + pSlot->pEntity = nullptr; + pSlot->pClientEntity = nullptr; + } } void CClientGame::GameProjectileDestructHandler(CEntitySAInterface* pProjectile) @@ -5030,7 +5121,7 @@ bool CClientGame::PreWeaponFire(CPlayerPed* pPlayerPed, bool bStopIfUsingBulletS if (pPlayer && !pPlayer->IsLocalPlayer()) { if (bStopIfUsingBulletSync && pPlayer->IsCurrentWeaponUsingBulletSync()) - return false; // Don't apply shot compensation & tell caller to not do bullet trace + return false; // Don't apply shot compensation & tell caller to not do bullet trace if (bShotCompensation) { @@ -5281,18 +5372,15 @@ void CClientGame::SendExplosionSync(const CVector& vecPosition, eExplosionType T // Because we use this packet to notify the server of blown vehicles, // we include a bit, whether the vehicle was blown without an explosion - if (pBitStream->Can(eBitStreamVersion::VehicleBlowStateSupport)) + if (pOrigin->GetType() == CCLIENTVEHICLE) { - if (pOrigin->GetType() == CCLIENTVEHICLE) - { - auto vehicle = reinterpret_cast(pOrigin); - pBitStream->WriteBit(1); - pBitStream->WriteBit(vehicleBlowState.value_or(vehicle->GetBlowState()) == VehicleBlowState::BLOWN); - } - else - { - pBitStream->WriteBit(0); - } + auto vehicle = reinterpret_cast(pOrigin); + pBitStream->WriteBit(1); + pBitStream->WriteBit(vehicleBlowState.value_or(vehicle->GetBlowState()) == VehicleBlowState::BLOWN); + } + else + { + pBitStream->WriteBit(0); } // Convert position @@ -5365,9 +5453,7 @@ void CClientGame::SendProjectileSync(CClientProjectile* pProjectile) pBitStream->Write(&weaponTypeSync); // Write the projectile's model - if (pBitStream->Version() >= 0x4F) - if (pBitStream->Version() >= 0x52 || pOriginSource) // Fix possible error for 0x51 server - pBitStream->Write(pProjectile->GetModel()); + pBitStream->Write(pProjectile->GetModel()); switch (weaponType) { @@ -5591,11 +5677,11 @@ void CClientGame::DoWastedCheck(ElementID damagerID, unsigned char ucWeapon, uns Arguments.PushElement(pKiller); else Arguments.PushBoolean(false); - if (ucWeapon != 0xFF) + if (ucWeapon != WEAPONTYPE_INVALID) Arguments.PushNumber(ucWeapon); else Arguments.PushBoolean(false); - if (ucBodyPiece != 0xFF) + if (ucBodyPiece != BODYPART_INVALID) Arguments.PushNumber(ucBodyPiece); else Arguments.PushBoolean(false); @@ -5639,8 +5725,9 @@ void CClientGame::DoWastedCheck(ElementID damagerID, unsigned char ucWeapon, uns if (discord && discord->IsDiscordRPCEnabled() && discord->IsDiscordCustomDetailsDisallowed()) { static const std::vector states{ - _("In a ditch"), _("En-route to hospital"), _("Meeting their maker"), - _("Regretting their decisions"), _("Wasted") + + _("In a ditch"), _("En-route to hospital"), _("Meeting their maker"), _("Regretting their decisions"), _("Wasted") + }; const std::string& state = states[rand() % states.size()]; @@ -5655,26 +5742,22 @@ bool CClientGame::OnKeyDown(CGUIKeyEventArgs Args) return true; } -bool CClientGame::OnMouseClick(CGUIMouseEventArgs Args) +void CClientGame::TriggerGUIClickEvent(CGUIMouseEventArgs Args, const char* szState, const char* minClientVersion) { if (!Args.pWindow) - return false; + return; const char* szButton = NULL; - const char* szState = NULL; switch (Args.button) { case CGUIMouse::LeftButton: szButton = "left"; - szState = "up"; break; case CGUIMouse::MiddleButton: szButton = "middle"; - szState = "up"; break; case CGUIMouse::RightButton: szButton = "right"; - szState = "up"; break; } @@ -5689,10 +5772,14 @@ bool CClientGame::OnMouseClick(CGUIMouseEventArgs Args) CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); if (GetGUIManager()->Exists(pGUIElement)) { - pGUIElement->CallEvent("onClientGUIClick", Arguments, true); + pGUIElement->CallEvent("onClientGUIClick", Arguments, true, minClientVersion); } } +} +bool CClientGame::OnMouseClick(CGUIMouseEventArgs Args) +{ + TriggerGUIClickEvent(Args, "up", nullptr); return true; } @@ -5758,18 +5845,21 @@ bool CClientGame::OnMouseButtonDown(CGUIMouseEventArgs Args) if (szButton) { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); if (GetGUIManager()->Exists(pGUIElement)) { + // Fire onClientGUIMouseDown for backward compatibility + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); pGUIElement->CallEvent("onClientGUIMouseDown", Arguments, true); } } + // Fire onClientGUIClick with state="down" + TriggerGUIClickEvent(Args, "down", MIN_CLIENT_REQ_ON_MOUSE_BUTTON_DOWN); + return true; } @@ -6257,10 +6347,7 @@ void CClientGame::TakePlayerScreenShot(uint uiSizeX, uint uiSizeY, const SString else pBitStream->Write((uchar)EPlayerScreenShotResult::MINIMIZED); pBitStream->Write(uiServerSentTime); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); + pBitStream->Write(pResource->GetNetID()); pBitStream->WriteString(strTag); g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); g_pNet->DeallocateNetBitStream(pBitStream); @@ -6325,13 +6412,9 @@ void CClientGame::GottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpen NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); pBitStream->Write((uchar)EPlayerScreenShotResult::ERROR_); pBitStream->Write(uiServerGrabTime); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); + pBitStream->Write(pResource->GetNetID()); pBitStream->WriteString(strTag); - if (pBitStream->Version() >= 0x053) - pBitStream->WriteString(strError); + pBitStream->WriteString(strError); g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); g_pNet->DeallocateNetBitStream(pBitStream); return; @@ -6355,8 +6438,8 @@ void CClientGame::GottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpen { NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - ushort usPartNumber = i; - ushort usBytesThisPart = std::min(uiBytesRemaining, uiBytesPerPart); + ushort usPartNumber = static_cast(i); + ushort usBytesThisPart = static_cast(std::min(uiBytesRemaining, uiBytesPerPart)); assert(usBytesThisPart != 0); pBitStream->Write((uchar)EPlayerScreenShotResult::SUCCESS); @@ -6371,10 +6454,7 @@ void CClientGame::GottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpen pBitStream->Write(uiServerGrabTime); pBitStream->Write(uiTotalByteSize); pBitStream->Write((ushort)uiNumParts); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); + pBitStream->Write(pResource->GetNetID()); pBitStream->WriteString(strTag); } @@ -6482,20 +6562,26 @@ bool CClientGame::WorldSoundHandler(const SWorldSoundEvent& event) // Audio events without a game entity could default to the root element, but the // best approach is to avoid spamming the event with the barely notable sounds (without a source). // Warning: Canceling sounds emitted by an audio entity (like vehicles do) will cause massive spam + CClientEntity* pEntity = nullptr; + if (event.pGameEntity) { - CPools* pPools = g_pGame->GetPools(); - CClientEntity* pEntity = pPools->GetClientEntity((DWORD*)event.pGameEntity); - if (pEntity) - { - CLuaArguments Arguments; - Arguments.PushNumber(event.uiGroup); - Arguments.PushNumber(event.uiIndex); - Arguments.PushNumber(event.vecPosition.fX); - Arguments.PushNumber(event.vecPosition.fY); - Arguments.PushNumber(event.vecPosition.fZ); - return pEntity->CallEvent("onClientWorldSound", Arguments, true); - } + CPools* pPools = g_pGame->GetPools(); + pEntity = pPools->GetClientEntity((DWORD*)event.pGameEntity); + } + + if (!pEntity) + pEntity = GetRootEntity(); + + if (pEntity) + { + CLuaArguments Arguments; + Arguments.PushNumber(event.uiGroup); + Arguments.PushNumber(event.uiIndex); + Arguments.PushNumber(event.vecPosition.fX); + Arguments.PushNumber(event.vecPosition.fY); + Arguments.PushNumber(event.vecPosition.fZ); + return pEntity->CallEvent("onClientWorldSound", Arguments, true); } return true; @@ -6549,11 +6635,24 @@ void CClientGame::OutputServerInfo() { SString strEnabledGlitches; - const char* szGlitchNames[] = {"Quick reload", "Fast fire", "Fast move", "Crouch bug", "Close damage", "Hit anim", "Fast sprint", - "Bad driveby hitboxes", "Quick stand", "Kickout of vehicle on model replace"}; - for (uint i = 0; i < NUM_GLITCHES; i++) + const char* szGlitchNames[] = { + + "Quick reload", + "Fast fire", + "Fast move", + "Crouch bug", + "Close damage", + "Hit anim", + "Fast sprint", + "Bad driveby hitboxes", + "Quick stand", + "Kickout of vehicle on model replace" + + }; + + for (unsigned char i = 0; i < NUM_GLITCHES; i++) { - if (IsGlitchEnabled(i)) + if (IsGlitchEnabled(static_cast(i))) { if (!strEnabledGlitches.empty()) strEnabledGlitches += ", "; @@ -6756,57 +6855,69 @@ bool CClientGame::TriggerBrowserRequestResultEvent(const std::unordered_setCallEvent("onClientBrowserWhitelistChange", Arguments, false); } -void CClientGame::RestreamModel(unsigned short usModel) +bool CClientGame::RestreamModel(std::uint16_t model) { // Is this a vehicle ID? - if (CClientVehicleManager::IsValidModel(usModel)) + if (CClientVehicleManager::IsValidModel(model)) { // Stream the vehicles of that model out so we have no // loaded when we do the restore. The streamer will // eventually stream them back in with async loading. - m_pManager->GetVehicleManager()->RestreamVehicles(usModel); - } + m_pManager->GetVehicleManager()->RestreamVehicles(model); + return true; + } // Is this an object ID? - else if (CClientObjectManager::IsValidModel(usModel)) + else if (CClientObjectManager::IsValidModel(model)) { - if (CClientPedManager::IsValidWeaponModel(usModel)) + if (CClientPedManager::IsValidWeaponModel(model)) { // Stream the weapon of that model out so we have no // loaded when we do the restore. The streamer will // eventually stream them back in with async loading. - m_pManager->GetPedManager()->RestreamWeapon(usModel); - m_pManager->GetPickupManager()->RestreamPickups(usModel); + m_pManager->GetPedManager()->RestreamWeapon(model); + m_pManager->GetPickupManager()->RestreamPickups(model); } // Stream the objects of that model out so we have no // loaded when we do the restore. The streamer will // eventually stream them back in with async loading. - m_pManager->GetObjectManager()->RestreamObjects(usModel); - g_pGame->GetModelInfo(usModel)->RestreamIPL(); + m_pManager->GetObjectManager()->RestreamObjects(model); + g_pGame->GetModelInfo(model)->RestreamIPL(); + + return true; } // Is this an ped ID? - else if (CClientPlayerManager::IsValidModel(usModel)) + else if (CClientPlayerManager::IsValidModel(model)) { // Stream the ped of that model out so we have no // loaded when we do the restore. The streamer will // eventually stream them back in with async loading. - m_pManager->GetPedManager()->RestreamPeds(usModel); - } - else + m_pManager->GetPedManager()->RestreamPeds(model); - // 'Restream' upgrades after model replacement to propagate visual changes with immediate effect - if (CClientObjectManager::IsValidModel(usModel) && CVehicleUpgrades::IsUpgrade(usModel)) - m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel); + return true; + } + // 'Restream' upgrades after model replacement to propagate visual changes with immediate effect + else if (CClientObjectManager::IsValidModel(model) && CVehicleUpgrades::IsUpgrade(model)) + { + m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(model); + return true; + } + return false; } void CClientGame::RestreamWorld() { + // If game is shutting down, do nothing for avoid crashes + if (g_bClientShuttingDown) + return; + unsigned int numberOfFileIDs = g_pGame->GetCountOfAllFileIDs(); for (unsigned int uiModelID = 0; uiModelID < numberOfFileIDs; uiModelID++) { - g_pClientGame->GetModelCacheManager()->OnRestreamModel(uiModelID); + g_pClientGame->GetModelCacheManager()->OnRestreamModel(static_cast(uiModelID)); } + m_pManager->GetObjectManager()->RestreamAllObjects(); m_pManager->GetVehicleManager()->RestreamAllVehicles(); m_pManager->GetPedManager()->RestreamAllPeds(); @@ -6816,6 +6927,55 @@ void CClientGame::RestreamWorld() g_pGame->GetStreaming()->ReinitStreaming(); } +void CClientGame::Restream(std::optional option) +{ + if (!option.has_value()) + option = RestreamOption::ALL; + + if (option == RestreamOption::ALL || option == RestreamOption::VEHICLES) + { + for (const auto& model : m_pManager->GetModelManager()->GetModelsByType(eClientModelType::VEHICLE)) + { + g_pClientGame->GetModelCacheManager()->OnRestreamModel(static_cast(model->GetModelID())); + } + + m_pManager->GetVehicleManager()->RestreamAllVehicles(); + } + + if (option == RestreamOption::ALL || option == RestreamOption::PEDS) + { + for (const auto& model : m_pManager->GetModelManager()->GetModelsByType(eClientModelType::PED)) + { + g_pClientGame->GetModelCacheManager()->OnRestreamModel(static_cast(model->GetModelID())); + } + + m_pManager->GetPedManager()->RestreamAllPeds(); + } + + if (option == RestreamOption::ALL || option == RestreamOption::OBJECTS) + { + static constexpr eClientModelType restreamTypes[] = {eClientModelType::OBJECT, eClientModelType::OBJECT_DAMAGEABLE, eClientModelType::TIMED_OBJECT, + eClientModelType::CLUMP}; + + for (eClientModelType type : restreamTypes) + { + for (const auto& model : m_pManager->GetModelManager()->GetModelsByType(type)) + { + g_pClientGame->GetModelCacheManager()->OnRestreamModel(static_cast(model->GetModelID())); + } + } + + m_pManager->GetObjectManager()->RestreamAllObjects(); + m_pManager->GetPickupManager()->RestreamAllPickups(); + } + + if (option == RestreamOption::ALL) + { + g_pGame->GetStreaming()->RemoveBigBuildings(); + g_pGame->GetStreaming()->ReinitStreaming(); + } +} + void CClientGame::ReinitMarkers() { g_pGame->Get3DMarkers()->ReinitMarkers(); @@ -6976,6 +7136,18 @@ void CClientGame::OnWindowFocusChange(bool state) return; m_bFocused = state; + if (m_pPlayerMap) + { + if (state) + { + g_pCore->GetGraphics()->MarkViewportRefreshPending(); + m_pPlayerMap->MarkViewportRefreshPending(); + } + else + { + m_pPlayerMap->ClearMovementFlags(); + } + } CLuaArguments Arguments; Arguments.PushBoolean(state); @@ -7148,3 +7320,20 @@ void CClientGame::AudioZoneRadioSwitchHandler(DWORD dwStationID) g_pGame->GetAudioEngine()->StartRadio(dwStationID); } } + +////////////////////////////////////////////////////////////////// +// +// CClientGame::TryGetCurrentWeapon +// +// Helper method to get current weapon type with error handling +// Returns actual weapon type or WEAPONTYPE_UNARMED as fallback +// +////////////////////////////////////////////////////////////////// +std::uint8_t CClientGame::TryGetCurrentWeapon(CClientPlayer* player) +{ + if (!player) + return WEAPONTYPE_UNARMED; + + eWeaponType weaponType = player->GetCurrentWeaponType(); + return (weaponType != WEAPONTYPE_INVALID) ? static_cast(weaponType) : WEAPONTYPE_UNARMED; +} diff --git a/Client/mods/deathmatch/logic/CClientGame.h b/Client/mods/deathmatch/logic/CClientGame.h index 97f1a39ba22..ce3f00c51e9 100644 --- a/Client/mods/deathmatch/logic/CClientGame.h +++ b/Client/mods/deathmatch/logic/CClientGame.h @@ -53,6 +53,7 @@ class CClientModelCacheManager; class CDebugHookManager; class CResourceFileDownloadManager; class CServerInfo; +class CFire; enum class eAnimID; struct SVehExtrapolateSettings @@ -129,7 +130,7 @@ class CClientGame SCRIPTFILE, WATER, WEAPON, - _DATABASE_CONNECTION, // server only + _DATABASE_CONNECTION, // server only TRAIN_TRACK, ROOT, UNKNOWN, @@ -192,6 +193,7 @@ class CClientGame QUIT_CONNECTION_DESYNC, QUIT_TIMEOUT, }; + enum { GLITCH_QUICKRELOAD, @@ -404,6 +406,46 @@ class CClientGame void SendPedWastedPacket(CClientPed* Ped, ElementID damagerID = INVALID_ELEMENT_ID, unsigned char ucWeapon = 0xFF, unsigned char ucBodyPiece = 0xFF, AssocGroupId animGroup = 0, AnimationId animID = 15); + void ClearDamageData() noexcept + { + m_DamagerID = INVALID_ELEMENT_ID; + m_ucDamageWeapon = WEAPONTYPE_INVALID; + m_ucDamageBodyPiece = BODYPART_INVALID; + m_ulDamageTime = 0; + m_serverProcessedDeath = true; + } + + void ResetDeathProcessingFlag() noexcept { m_serverProcessedDeath = false; } + + void SetScriptedDeathData() + { + auto* localPlayer = GetLocalPlayer(); + if (!localPlayer) + { + m_DamagerID = INVALID_ELEMENT_ID; + m_ucDamageWeapon = WEAPONTYPE_INVALID; + m_ucDamageBodyPiece = BODYPART_INVALID; + m_ulDamageTime = CClientTime::GetTime(); + m_serverProcessedDeath = false; + return; + } + + m_DamagerID = INVALID_ELEMENT_ID; + m_ucDamageWeapon = TryGetCurrentWeapon(localPlayer); + m_ucDamageBodyPiece = BODYPART_TORSO; + m_ulDamageTime = CClientTime::GetTime(); + m_serverProcessedDeath = false; + } + + void SetExplosionDamageData() noexcept + { + m_DamagerID = INVALID_ELEMENT_ID; + m_ucDamageWeapon = WEAPONTYPE_EXPLOSION; + m_ucDamageBodyPiece = BODYPART_TORSO; + m_ulDamageTime = CClientTime::GetTime(); + m_serverProcessedDeath = false; + } + CClientGUIElement* GetClickedGUIElement() { return m_pClickedGUIElement; } void SetClickedGUIElement(CClientGUIElement* pElement) { m_pClickedGUIElement = NULL; } @@ -464,12 +506,16 @@ class CClientGame bool IsHighFloatPrecision() const; bool TriggerBrowserRequestResultEvent(const std::unordered_set& newPages); - void RestreamModel(unsigned short usModel); + bool RestreamModel(std::uint16_t model); void RestreamWorld(); + void Restream(std::optional option); void ReinitMarkers(); void OnWindowFocusChange(bool state); + void SetAllowMultiCommandHandlers(MultiCommandHandlerPolicy policy) noexcept { m_allowMultiCommandHandlers = policy; } + MultiCommandHandlerPolicy GetAllowMultiCommandHandlers() const noexcept { return m_allowMultiCommandHandlers; } + private: // CGUI Callbacks bool OnKeyDown(CGUIKeyEventArgs Args); @@ -485,6 +531,7 @@ class CClientGame bool OnSize(CGUIElement* pElement); bool OnFocusGain(CGUIFocusEventArgs Args); bool OnFocusLoss(CGUIFocusEventArgs Args); + void TriggerGUIClickEvent(CGUIMouseEventArgs Args, const char* szState, const char* minClientVersion); // Network update functions void DoVehicleInKeyCheck(); @@ -522,7 +569,7 @@ class CClientGame static bool StaticDamageHandler(CPed* pDamagePed, CEventDamage* pEvent); static void StaticDeathHandler(CPed* pKilledPed, unsigned char ucDeathReason, unsigned char ucBodyPart); - static void StaticFireHandler(CFire* pFire); + static bool StaticFireHandler(CEntitySAInterface* target, CEntitySAInterface* creator); static bool StaticBreakTowLinkHandler(CVehicle* pTowedVehicle); static void StaticDrawRadarAreasHandler(); static void StaticRender3DStuffHandler(); @@ -573,7 +620,7 @@ class CClientGame bool DamageHandler(CPed* pDamagePed, CEventDamage* pEvent); void DeathHandler(CPed* pKilledPed, unsigned char ucDeathReason, unsigned char ucBodyPart); - void FireHandler(CFire* pFire); + bool FireHandler(CEntitySAInterface* target, CEntitySAInterface* creator); bool BreakTowLinkHandler(CVehicle* pTowedVehicle); void DrawRadarAreasHandler(); void Render3DStuffHandler(); @@ -592,7 +639,8 @@ class CClientGame RpClump* pClump); bool ProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface); bool VehicleCollisionHandler(CVehicleSAInterface*& pCollidingVehicle, CEntitySAInterface* pCollidedVehicle, int iModelIndex, float fDamageImpulseMag, - float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity, bool isProjectile); + float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity, + bool isProjectile); bool VehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, const CVector& vecDamagePos, uchar ucTyre); bool HeliKillHandler(CVehicleSAInterface* pHeli, CEntitySAInterface* pHitInterface); @@ -611,6 +659,9 @@ class CClientGame AnimationId DrivebyAnimationHandler(AnimationId animGroup, AssocGroupId animId); void AudioZoneRadioSwitchHandler(DWORD dwStationID); + // Helper method to get current weapon type with error handling + std::uint8_t TryGetCurrentWeapon(CClientPlayer* player); + static bool StaticProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); bool ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); @@ -628,7 +679,8 @@ class CClientGame bool VerifySADataFiles(int iEnableClientChecks = 0); void DebugElementRender(); - void SendExplosionSync(const CVector& vecPosition, eExplosionType Type, CClientEntity* pOrigin = nullptr, std::optional vehicleBlowState = std::nullopt); + void SendExplosionSync(const CVector& vecPosition, eExplosionType Type, CClientEntity* pOrigin = nullptr, + std::optional vehicleBlowState = std::nullopt); void SendFireSync(CFire* pFire); void SendProjectileSync(CClientProjectile* pProjectile); @@ -765,6 +817,7 @@ class CClientGame unsigned char m_ucDamageBodyPiece; unsigned long m_ulDamageTime; bool m_bDamageSent; + bool m_serverProcessedDeath{false}; // Flag to track server-processed deaths eWeaponSlot m_lastWeaponSlot; SFixedArray m_wasWeaponAmmoInClip; @@ -805,7 +858,7 @@ class CClientGame long long m_llLastTransgressionTime; SString m_strLastDiagnosticStatus; - bool m_bBeingDeleted; // To enable speedy disconnect + bool m_bBeingDeleted; // To enable speedy disconnect bool m_bWasMinimized; bool m_bFocused; @@ -871,7 +924,9 @@ class CClientGame AnimAssociations_type m_mapOfCustomAnimationAssociations; // Key is the task and value is the CClientPed* RunNamedAnimTask_type m_mapOfRunNamedAnimTasks; - + + MultiCommandHandlerPolicy m_allowMultiCommandHandlers; + long long m_timeLastDiscordStateUpdate; }; diff --git a/Client/mods/deathmatch/logic/CClientIFP.cpp b/Client/mods/deathmatch/logic/CClientIFP.cpp index d57003a1130..2862ba99d43 100644 --- a/Client/mods/deathmatch/logic/CClientIFP.cpp +++ b/Client/mods/deathmatch/logic/CClientIFP.cpp @@ -275,15 +275,25 @@ void CClientIFP::ReadSequenceVersion2(SSequenceHeaderV2& ObjectNode) bool CClientIFP::ReadSequenceKeyFrames(std::unique_ptr& pAnimationSequence, eFrameType iFrameType, const std::int32_t& cFrames) { + if (cFrames <= 0) + return false; + size_t iCompressedFrameSize = GetSizeOfCompressedFrame(iFrameType); - if (iCompressedFrameSize) + size_t iSourceFrameSize = GetSourceFrameDataSize(iFrameType); + if (iCompressedFrameSize == 0 || iSourceFrameSize == 0) + return false; + + BYTE* pKeyFrames = m_pAnimManager->AllocateKeyFramesMemory(iCompressedFrameSize * cFrames); + if (!pKeyFrames) { - BYTE* pKeyFrames = m_pAnimManager->AllocateKeyFramesMemory(iCompressedFrameSize * cFrames); - pAnimationSequence->SetKeyFrames(cFrames, IsKeyFramesTypeRoot(iFrameType), m_kbAllKeyFramesCompressed, pKeyFrames); - ReadKeyFramesAsCompressed(pAnimationSequence, iFrameType, cFrames); - return true; + // Advance stream past frame data to keep subsequent reads aligned + SkipBytes(static_cast(iSourceFrameSize * cFrames)); + return false; } - return false; + + pAnimationSequence->SetKeyFrames(cFrames, IsKeyFramesTypeRoot(iFrameType), m_kbAllKeyFramesCompressed, pKeyFrames); + ReadKeyFramesAsCompressed(pAnimationSequence, iFrameType, cFrames); + return true; } void CClientIFP::ReadHeaderVersion1(SInfo& Info) @@ -448,12 +458,40 @@ size_t CClientIFP::GetSizeOfCompressedFrame(eFrameType iFrameType) return 0; } +size_t CClientIFP::GetSourceFrameDataSize(eFrameType iFrameType) +{ + switch (iFrameType) + { + case eFrameType::KRTS: + { + return sizeof(SKrts); + } + case eFrameType::KRT0: + { + return sizeof(SKrt0); + } + case eFrameType::KR00: + { + return sizeof(SKr00); + } + case eFrameType::KR00_COMPRESSED: + { + return sizeof(SCompressed_KR00); + } + case eFrameType::KRT0_COMPRESSED: + { + return sizeof(SCompressed_KRT0); + } + } + return 0; +} + void CClientIFP::InitializeAnimationHierarchy(std::unique_ptr& pAnimationHierarchy, const SString& strAnimationName, const std::int32_t& iSequences) { pAnimationHierarchy->Initialize(); pAnimationHierarchy->SetName(strAnimationName); - pAnimationHierarchy->SetNumSequences(iSequences); + pAnimationHierarchy->SetNumSequences(static_cast(iSequences)); pAnimationHierarchy->SetAnimationBlockID(-1); pAnimationHierarchy->SetRunningCompressed(m_kbAllKeyFramesCompressed); } @@ -543,6 +581,9 @@ void CClientIFP::InsertAnimationDummySequence(std::unique_ptrAllocateKeyFramesMemory(FramesDataSizeInBytes); + if (!pKeyFrames) + return; + pAnimationSequence->SetKeyFrames(cKeyFrames, bHasTranslationValues, m_kbAllKeyFramesCompressed, pKeyFrames); CopyDummyKeyFrameByBoneID(pKeyFrames, dwBoneID); } @@ -551,7 +592,7 @@ void CClientIFP::CopyDummyKeyFrameByBoneID(BYTE* pKeyFrames, DWORD dwBoneID) { switch (dwBoneID) { - case eBoneType::NORMAL: // Normal or Root, both are same + case eBoneType::NORMAL: // Normal or Root, both are same { // This is a root frame. It contains translation as well, but it's compressed just like quaternion BYTE FrameData[16] = {0x1F, 0x00, 0x00, 0x00, 0x53, 0x0B, 0x4D, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00}; @@ -1102,7 +1143,7 @@ CAnimBlendHierarchySAInterface* CClientIFP::GetAnimationHierarchy(const SString& { const unsigned int uiAnimationNameHash = HashString(strAnimationName.ToLower()); auto it = std::find_if(m_pVecAnimations->begin(), m_pVecAnimations->end(), - [&uiAnimationNameHash](SAnimation const& Animation) { return Animation.uiNameHash == uiAnimationNameHash; }); + [&uiAnimationNameHash](SAnimation const& Animation) { return Animation.uiNameHash == uiAnimationNameHash; }); if (it != m_pVecAnimations->end()) { return it->pHierarchy->GetInterface(); diff --git a/Client/mods/deathmatch/logic/CClientIFP.h b/Client/mods/deathmatch/logic/CClientIFP.h index 5aaa98c4fda..e4e7111f2b8 100644 --- a/Client/mods/deathmatch/logic/CClientIFP.h +++ b/Client/mods/deathmatch/logic/CClientIFP.h @@ -13,6 +13,7 @@ #include "CClientEntity.h" #include "CFileReader.h" #include "CIFPAnimations.h" +#include class CAnimBlendSequence; @@ -150,7 +151,7 @@ class CClientIFP final : public CClientEntity, CFileReader char Name[24]; std::int32_t TotalObjects; std::int32_t FrameSize; - std::int32_t isCompressed; // The value is always 1 + std::int32_t isCompressed; // The value is always 1 }; struct SSequenceHeaderV2 @@ -164,7 +165,7 @@ class CClientIFP final : public CClientEntity, CFileReader enum eBoneType { UNKNOWN = -1, - NORMAL = 0, // Normal or Root, both are same + NORMAL = 0, // Normal or Root, both are same PELVIS = 1, SPINE = 2, SPINE1 = 3, @@ -215,7 +216,7 @@ class CClientIFP final : public CClientEntity, CFileReader // Sorta a hack that these are required by CClientEntity... void Unlink(); void GetPosition(CVector& vecPosition) const {}; - void SetPosition(const CVector& vecPosition){}; + void SetPosition(const CVector& vecPosition) {}; private: bool ReadIFPByVersion(); @@ -246,6 +247,11 @@ class CClientIFP final : public CClientEntity, CFileReader { BYTE* pKeyFrames = pAnimationSequence->GetKeyFrames(); size_t iSizeInBytes = sizeof(T) * iFrames; + if (!pKeyFrames) + { + SkipBytes(static_cast(iSizeInBytes)); + return; + } ReadBytes(pKeyFrames, iSizeInBytes); } @@ -266,6 +272,7 @@ class CClientIFP final : public CClientEntity, CFileReader eFrameType GetFrameTypeFromFourCC(const char* szFourCC); size_t GetSizeOfCompressedFrame(eFrameType FrameType); + size_t GetSourceFrameDataSize(eFrameType iFrameType); std::int32_t GetBoneIDFromName(const SString& strBoneName); SString GetCorrectBoneNameFromName(const SString& strBoneName); SString GetCorrectBoneNameFromID(const std::int32_t& iBoneID); diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 5abd8b07e66..bd366725db8 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -191,7 +191,13 @@ bool CClientIMG::StreamDisable() m_pImgManager->UpdateStreamerBufferSize(); - g_pClientGame->RestreamWorld(); + // During session shutdown (CClientManager being destroyed), element destruction + // order is arbitrary. Skip restreaming because earlier element cleanup may have + // already freed TXD pool slots, and ReinitStreaming would flush pending + // streaming channels that reference those freed parent slots. + if (!m_pManager || !m_pManager->IsBeingDeleted()) + g_pClientGame->RestreamWorld(); + return true; } @@ -205,12 +211,19 @@ bool CClientIMG::LinkModel(unsigned int uiModelID, size_t uiFileID) return false; CStreamingInfo* pCurrInfo = g_pGame->GetStreaming()->GetStreamingInfo(uiModelID); + if (!pCurrInfo) + return false; if (pCurrInfo->archiveId == m_ucArchiveID) - return true; // Already linked + return true; // Already linked m_restoreInfo.emplace_back(uiModelID, pCurrInfo->offsetInBlocks, pCurrInfo->sizeInBlocks, pCurrInfo->archiveId); + // Internally stream out the vehicle before calling CStreamingSA::RemoveModel + // otherwise a crash will occur if the player is inside a vehicle that gets unloaded by the streamer + if (CClientVehicleManager::IsValidModel(uiModelID)) + g_pClientGame->GetVehicleManager()->RestreamVehicles(static_cast(uiModelID)); + g_pGame->GetStreaming()->SetStreamingInfo(uiModelID, m_ucArchiveID, pFileInfo->uiOffset, pFileInfo->usSize); return true; diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index 2074e64fbc0..7408c3407cd 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -52,7 +52,7 @@ class CClientIMG : public CClientEntity void Unlink(); void GetPosition(CVector& vecPosition) const {}; - void SetPosition(const CVector& vecPosition){}; + void SetPosition(const CVector& vecPosition) {}; eClientEntityType GetType() const { return CCLIENTIMG; } unsigned char GetArchiveID() const { return m_ucArchiveID; } @@ -81,7 +81,7 @@ class CClientIMG : public CClientEntity fs::path m_filePath; unsigned char m_ucArchiveID; std::vector m_fileInfos; - size_t m_LargestFileSizeBlocks; // The size of the largest file [in streaming blocks/sectors] + size_t m_LargestFileSizeBlocks; // The size of the largest file [in streaming blocks/sectors] std::vector m_restoreInfo; }; diff --git a/Client/mods/deathmatch/logic/CClientIMGManager.cpp b/Client/mods/deathmatch/logic/CClientIMGManager.cpp index 6a8c6e7e6d8..7285a2be277 100644 --- a/Client/mods/deathmatch/logic/CClientIMGManager.cpp +++ b/Client/mods/deathmatch/logic/CClientIMGManager.cpp @@ -22,7 +22,7 @@ CClientIMGManager::CClientIMGManager(CClientManager* pManager) // TODO: In the default gta3.img the biggest file is 1260 sectors, so to be fail safe, we double it // ideally, we'd just take this value from the game, but there's no clean/easy way to do that [without loading the img archives] // so, for now, this is good enough - m_LargestFileSizeBlocks = m_GTALargestFileSizeBlocks = 1260 * 2; + m_LargestFileSizeBlocks = m_GTALargestFileSizeBlocks = 1260 * 2; } CClientIMGManager::~CClientIMGManager() @@ -77,13 +77,21 @@ bool CClientIMGManager::Exists(CClientIMG* pIMG) CClientIMG* CClientIMGManager::GetElementThatLinked(unsigned int uiModel) { - uchar ucArhiveID = g_pGame->GetStreaming()->GetStreamingInfo(uiModel)->archiveId; + auto* pStreamingInfo = g_pGame->GetStreaming()->GetStreamingInfo(uiModel); + if (!pStreamingInfo) + return nullptr; + + uchar ucArhiveID = pStreamingInfo->archiveId; return GetElementFromArchiveID(ucArhiveID); } bool CClientIMGManager::IsLinkableModel(unsigned int uiModel) { - return uiModel <= 26316; // StreamModelInfoSize + const int32_t count = g_pGame->GetCountOfAllFileIDs(); + if (count <= 0) + return false; + + return uiModel < static_cast(count); } bool CClientIMGManager::RestoreModel(unsigned int uiModel) diff --git a/Client/mods/deathmatch/logic/CClientIMGManager.h b/Client/mods/deathmatch/logic/CClientIMGManager.h index a16239e88b1..dd34beb01c3 100644 --- a/Client/mods/deathmatch/logic/CClientIMGManager.h +++ b/Client/mods/deathmatch/logic/CClientIMGManager.h @@ -37,11 +37,11 @@ class CClientIMGManager private: size_t CalculateLargestFile() const; - void AddToList(CClientIMG* pIMG) { m_List.push_back(pIMG); } - void RemoveFromList(CClientIMG* pIMG); + void AddToList(CClientIMG* pIMG) { m_List.push_back(pIMG); } + void RemoveFromList(CClientIMG* pIMG); std::list m_List; bool m_bRemoveFromList; uint32 m_GTALargestFileSizeBlocks; - uint32 m_LargestFileSizeBlocks; // Size of the largest file [in streaming blocks/sectors] in any of the loaded imgs + uint32 m_LargestFileSizeBlocks; // Size of the largest file [in streaming blocks/sectors] in any of the loaded imgs }; diff --git a/Client/mods/deathmatch/logic/CClientManager.cpp b/Client/mods/deathmatch/logic/CClientManager.cpp index e3a808555b4..bf79bf9ec93 100644 --- a/Client/mods/deathmatch/logic/CClientManager.cpp +++ b/Client/mods/deathmatch/logic/CClientManager.cpp @@ -201,7 +201,7 @@ void CClientManager::DoPulse(bool bDoStandardPulses, bool bDoVehicleManagerPulse are no longer a frame behind when attached to other entities. m_pMarkerManager->DoPulse (); */ m_pRadarAreaManager->DoPulse( - false); // DoPulse, but do not render (we render them from a hook to avoid render issues - the mask not blocking the edges) + false); // DoPulse, but do not render (we render them from a hook to avoid render issues - the mask not blocking the edges) } if (bDoVehicleManagerPulse) diff --git a/Client/mods/deathmatch/logic/CClientManager.h b/Client/mods/deathmatch/logic/CClientManager.h index 12aee3816cf..26f93f0015b 100644 --- a/Client/mods/deathmatch/logic/CClientManager.h +++ b/Client/mods/deathmatch/logic/CClientManager.h @@ -99,7 +99,10 @@ class CClientManager CClientIMGManager* GetIMGManager() { return m_pImgManager; } CClientBuildingManager* GetBuildingManager() const noexcept { return m_pBuildingManager; } - bool IsGameLoaded() { return g_pGame->GetSystemState() == SystemState::GS_PLAYING_GAME && !m_bGameUnloadedFlag && g_pCore->GetNetwork()->GetServerBitStreamVersion(); } + bool IsGameLoaded() + { + return g_pGame->GetSystemState() == SystemState::GS_PLAYING_GAME && !m_bGameUnloadedFlag && g_pCore->GetNetwork()->GetServerBitStreamVersion(); + } bool IsBeingDeleted() { return m_bBeingDeleted; } void SetGameUnloadedFlag() { m_bGameUnloadedFlag = true; } diff --git a/Client/mods/deathmatch/logic/CClientMarker.cpp b/Client/mods/deathmatch/logic/CClientMarker.cpp index 429f8168d9f..72c300dad04 100644 --- a/Client/mods/deathmatch/logic/CClientMarker.cpp +++ b/Client/mods/deathmatch/logic/CClientMarker.cpp @@ -13,7 +13,7 @@ extern CClientGame* g_pClientGame; #ifndef M_PI -#define M_PI 3.14159265358979323846 + #define M_PI 3.14159265358979323846 #endif unsigned int CClientMarker::m_uiStreamedInMarkers = 0; @@ -314,7 +314,15 @@ void CClientMarker::SetSize(float fSize) pShape->SetRadius(fSize); break; } + case COLSHAPE_TUBE: + { + CClientColTube* pShape = static_cast(m_pCollision); + pShape->SetRadius(fSize); + pShape->SetHeight(fSize <= 1.5 ? fSize + 1 : fSize); + break; + } } + m_pMarker->SetSize(fSize); } @@ -410,28 +418,44 @@ void CClientMarker::StreamOut() } } -void CClientMarker::Callback_OnCollision(CClientColShape& Shape, CClientEntity& Entity) +void CClientMarker::Callback_OnCollision(CClientColShape& shape, CClientEntity& entity) { - if (IS_PLAYER(&Entity)) - { - // Call the marker hit event - CLuaArguments Arguments; - Arguments.PushElement(&Entity); // player that hit it - Arguments.PushBoolean((GetDimension() == Entity.GetDimension())); // matching dimension? - CallEvent("onClientMarkerHit", Arguments, true); - } + if (GetInterior() != entity.GetInterior()) + return; + + // Call the marker hit event + CLuaArguments arguments; + arguments.PushElement(&entity); // Hit element + arguments.PushBoolean(GetDimension() == entity.GetDimension()); // Matching dimension? + CallEvent("onClientMarkerHit", arguments, true); + + if (!IS_PLAYER(&entity)) + return; + + CLuaArguments arguments2; + arguments2.PushElement(this); // marker + arguments2.PushBoolean(GetDimension() == entity.GetDimension()); // Matching dimension? + entity.CallEvent("onClientPlayerMarkerHit", arguments2, false); } -void CClientMarker::Callback_OnLeave(CClientColShape& Shape, CClientEntity& Entity) +void CClientMarker::Callback_OnLeave(CClientColShape& shape, CClientEntity& entity) { - if (IS_PLAYER(&Entity)) - { - // Call the marker hit event - CLuaArguments Arguments; - Arguments.PushElement(&Entity); // player that hit it - Arguments.PushBoolean((GetDimension() == Entity.GetDimension())); // matching dimension? - CallEvent("onClientMarkerLeave", Arguments, true); - } + if (GetInterior() != entity.GetInterior()) + return; + + // Call the marker leave event + CLuaArguments arguments; + arguments.PushElement(&entity); // Hit element + arguments.PushBoolean(GetDimension() == entity.GetDimension()); // Matching dimension? + CallEvent("onClientMarkerLeave", arguments, true); + + if (!IS_PLAYER(&entity)) + return; + + CLuaArguments arguments2; + arguments2.PushElement(this); // marker + arguments2.PushBoolean(GetDimension() == entity.GetDimension()); // Matching dimension? + entity.CallEvent("onPlayerMarkerLeave", arguments2, false); } void CClientMarker::CreateOfType(int iType) @@ -469,7 +493,8 @@ void CClientMarker::CreateOfType(int iType) CClient3DMarker* p3DMarker = new CClient3DMarker(this); p3DMarker->Set3DMarkerType(CClient3DMarker::TYPE_CYLINDER); m_pMarker = p3DMarker; - m_pCollision = new CClientColCircle(g_pClientGame->GetManager(), INVALID_ELEMENT_ID, vecOrigin, GetSize()); + + m_pCollision = new CClientColTube(g_pClientGame->GetManager(), INVALID_ELEMENT_ID, vecOrigin, GetSize(), GetSize()); m_pCollision->m_pOwningMarker = this; m_pCollision->SetHitCallback(this); break; diff --git a/Client/mods/deathmatch/logic/CClientModel.cpp b/Client/mods/deathmatch/logic/CClientModel.cpp index 906f77324c7..89228efd10d 100644 --- a/Client/mods/deathmatch/logic/CClientModel.cpp +++ b/Client/mods/deathmatch/logic/CClientModel.cpp @@ -20,35 +20,47 @@ CClientModel::CClientModel(CClientManager* pManager, int iModelID, eClientModelT CClientModel::~CClientModel(void) { + RestoreEntitiesUsingThisModel(); Deallocate(); } bool CClientModel::Allocate(ushort usParentID) { - m_bAllocatedByUs = true; - CModelInfo* pModelInfo = g_pGame->GetModelInfo(m_iModelID, true); + if (!pModelInfo) + return false; - // Allocate only on free IDs + // Model slot must be free if (pModelInfo->IsValid()) return false; - // Avoid hierarchy + // Parent must exist and have no parent (no hierarchy) CModelInfo* pParentModelInfo = g_pGame->GetModelInfo(usParentID, true); + if (!pParentModelInfo || !pParentModelInfo->IsValid()) + return false; if (pParentModelInfo->GetParentID()) return false; + bool allocated = false; switch (m_eModelType) { case eClientModelType::PED: - pModelInfo->MakePedModel("PSYCHO"); - return true; + { + // Parent ID 0 (CJ) bypasses TXD isolation in downstream logic + const unsigned short usEffectiveParent = usParentID ? usParentID : 7; + if (CClientPlayerManager::IsValidModel(usEffectiveParent)) + { + pModelInfo->MakePedModel(usEffectiveParent); + allocated = true; + } + break; + } case eClientModelType::OBJECT: if (g_pClientGame->GetObjectManager()->IsValidModel(usParentID)) { pModelInfo->MakeObjectModel(usParentID); - return true; + allocated = true; } break; case eClientModelType::OBJECT_DAMAGEABLE: @@ -58,7 +70,7 @@ bool CClientModel::Allocate(ushort usParentID) if (isValidModel && isDamagable) { pModelInfo->MakeObjectDamageableModel(usParentID); - return true; + allocated = true; } break; } @@ -66,27 +78,28 @@ bool CClientModel::Allocate(ushort usParentID) if (g_pClientGame->GetObjectManager()->IsValidModel(usParentID)) { pModelInfo->MakeClumpModel(usParentID); - return true; + allocated = true; } break; case eClientModelType::TIMED_OBJECT: if (g_pClientGame->GetObjectManager()->IsValidModel(usParentID)) { pModelInfo->MakeTimedObjectModel(usParentID); - return true; + allocated = true; } break; case eClientModelType::VEHICLE: if (g_pClientGame->GetVehicleManager()->IsValidModel(usParentID)) { pModelInfo->MakeVehicleAutomobile(usParentID); - return true; + allocated = true; } break; default: return false; } - return false; + m_bAllocatedByUs = allocated; + return allocated; } // You can call it only in destructor for DFF. @@ -99,19 +112,45 @@ bool CClientModel::Deallocate() CModelInfo* pModelInfo = g_pGame->GetModelInfo(m_iModelID, true); if (!pModelInfo || !pModelInfo->IsValid()) - return false; + { + // Model already gone - cleanup any orphaned TXD slot + if (m_eModelType != eClientModelType::TXD) + { + if (CRenderWare* pRenderWare = g_pGame->GetRenderWare()) + pRenderWare->CleanupIsolatedTxdForModel(static_cast(m_iModelID)); + } + m_bAllocatedByUs = false; + return true; + } if (m_eModelType != eClientModelType::TXD) { - // Remove model info + // Clean up TXD isolation BEFORE deallocating - cleanup needs valid model info + if (CRenderWare* pRenderWare = g_pGame->GetRenderWare()) + pRenderWare->CleanupIsolatedTxdForModel(static_cast(m_iModelID)); + pModelInfo->DeallocateModel(); + + // Log if model still has refs + if (pModelInfo->IsValid()) + AddReportLog(9406, SString("Deallocate: Model %d still valid after DeallocateModel (refs=%d)", m_iModelID, pModelInfo->GetRefCount()), 10); } + m_bAllocatedByUs = false; return true; } void CClientModel::RestoreEntitiesUsingThisModel() { + // TXD cleanup does not depend on GetModelInfo. Overflow TXDs (pool index >= 5000) + // map to model IDs in the COL/IPL range or beyond the ModelInfo array, so + // GetModelInfo would return wrong or null entries for them. + if (m_eModelType == eClientModelType::TXD) + { + RestoreTXD(); + return; + } + CModelInfo* pModelInfo = g_pGame->GetModelInfo(m_iModelID, true); if (!pModelInfo || !pModelInfo->IsValid()) return; @@ -126,9 +165,6 @@ void CClientModel::RestoreEntitiesUsingThisModel() case eClientModelType::VEHICLE: RestoreDFF(pModelInfo); return; - case eClientModelType::TXD: - RestoreTXD(pModelInfo); - return; default: return; } @@ -136,49 +172,79 @@ void CClientModel::RestoreEntitiesUsingThisModel() void CClientModel::RestoreDFF(CModelInfo* pModelInfo) { - auto callElementChangeEvent = [](auto &element, unsigned short usParentID, auto modelId) { + if (!g_pClientGame || !g_pClientGame->GetManager()) + return; + + // DFFManager is destroyed before ModelManager during CClientManager cleanup. + // If null, sub-managers are already torn down - skip restoration. + if (!g_pClientGame->GetManager()->GetDFFManager()) + return; + + const int modelId = m_iModelID; + const auto modelType = m_eModelType; + + auto callElementChangeEvent = [](auto& element, unsigned short usParentID, auto modelId) + { CLuaArguments Arguments; Arguments.PushNumber(modelId); Arguments.PushNumber(usParentID); element.CallEvent("onClientElementModelChange", Arguments, true); }; - auto unloadModelsAndCallEvents = [&](auto iterBegin, auto iterEnd, unsigned short usParentID, auto setElementModelLambda) { - for (auto iter = iterBegin; iter != iterEnd; iter++) + auto copyPtrs = [](auto begin, auto end) + { + using T = typename std::iterator_traits::value_type; + std::vector out; + for (auto it = begin; it != end; ++it) + out.push_back(*it); + return out; + }; + + auto unloadModelsAndCallEvents = + [modelId, callElementChangeEvent, copyPtrs](auto iterBegin, auto iterEnd, unsigned short usParentID, auto setElementModelLambda) + { + auto items = copyPtrs(iterBegin, iterEnd); + for (auto ptr : items) { - auto& element = **iter; + if (!ptr) + continue; + + auto& element = *ptr; - if (element.GetModel() != m_iModelID) + if (element.GetModel() != modelId) continue; if (element.IsStreamedIn()) element.StreamOutForABit(); setElementModelLambda(element); - - callElementChangeEvent(element, usParentID, m_iModelID); + callElementChangeEvent(element, usParentID, modelId); } }; - auto unloadModelsAndCallEventsNonStreamed = [&](auto iterBegin, auto iterEnd, unsigned short usParentID, auto setElementModelLambda) + auto unloadModelsAndCallEventsNonStreamed = + [modelId, callElementChangeEvent, copyPtrs](auto iterBegin, auto iterEnd, unsigned short usParentID, auto setElementModelLambda) { - for (auto iter = iterBegin; iter != iterEnd; iter++) + auto items = copyPtrs(iterBegin, iterEnd); + for (auto ptr : items) { - auto& element = **iter; + if (!ptr) + continue; + + auto& element = *ptr; - if (element.GetModel() != m_iModelID) + if (element.GetModel() != modelId) continue; setElementModelLambda(element); - callElementChangeEvent(element, usParentID, m_iModelID); + callElementChangeEvent(element, usParentID, modelId); } }; - switch (m_eModelType) + switch (modelType) { case eClientModelType::PED: { - // If some ped is using this ID, change him to CJ CClientPedManager* pPedManager = g_pClientGame->GetManager()->GetPedManager(); unloadModelsAndCallEvents(pPedManager->IterBegin(), pPedManager->IterEnd(), 0, [](auto& element) { element.SetModel(0); }); @@ -190,42 +256,42 @@ void CClientModel::RestoreDFF(CModelInfo* pModelInfo) case eClientModelType::TIMED_OBJECT: { const auto& objects = &g_pClientGame->GetManager()->GetObjectManager()->GetObjects(); - unsigned short usParentID = g_pGame->GetModelInfo(m_iModelID)->GetParentID(); + unsigned short usParentID = static_cast(pModelInfo->GetParentID()); - unloadModelsAndCallEvents(objects->begin(), objects->end(), usParentID, [=](auto& element) { element.SetModel(usParentID); }); + unloadModelsAndCallEvents(objects->begin(), objects->end(), usParentID, [usParentID](auto& element) { element.SetModel(usParentID); }); - // Restore pickups with custom model CClientPickupManager* pPickupManager = g_pClientGame->GetManager()->GetPickupManager(); - unloadModelsAndCallEvents(pPickupManager->IterBegin(), pPickupManager->IterEnd(), usParentID, [=](auto& element) { element.SetModel(usParentID); }); + unloadModelsAndCallEvents(pPickupManager->IterBegin(), pPickupManager->IterEnd(), usParentID, + [usParentID](auto& element) { element.SetModel(usParentID); }); - // Restore buildings CClientBuildingManager* pBuildingsManager = g_pClientGame->GetManager()->GetBuildingManager(); auto& buildingsList = pBuildingsManager->GetBuildings(); unloadModelsAndCallEventsNonStreamed(buildingsList.begin(), buildingsList.end(), usParentID, - [=](auto& element) { element.SetModel(usParentID); }); + [usParentID](auto& element) { element.SetModel(usParentID); }); - // Restore COL - g_pClientGame->GetManager()->GetColModelManager()->RestoreModel(m_iModelID); + g_pClientGame->GetManager()->GetColModelManager()->RestoreModel(static_cast(modelId)); break; } case eClientModelType::VEHICLE: { CClientVehicleManager* pVehicleManager = g_pClientGame->GetManager()->GetVehicleManager(); - unsigned short usParentID = g_pGame->GetModelInfo(m_iModelID)->GetParentID(); + unsigned short usParentID = static_cast(pModelInfo->GetParentID()); unloadModelsAndCallEvents(pVehicleManager->IterBegin(), pVehicleManager->IterEnd(), usParentID, - [=](auto& element) { element.SetModelBlocking(usParentID, 255, 255); }); + [usParentID](auto& element) { element.SetModelBlocking(usParentID, 255, 255); }); break; } } - // Restore DFF/TXD - g_pClientGame->GetManager()->GetDFFManager()->RestoreModel(m_iModelID); + g_pClientGame->GetManager()->GetDFFManager()->RestoreModel(static_cast(modelId)); } -bool CClientModel::AllocateTXD(std::string &strTxdName) +bool CClientModel::AllocateTXD(std::string& strTxdName) { + if (m_iModelID < MAX_MODEL_DFF_ID) + return false; + std::uint32_t uiSlotID = g_pGame->GetPools()->GetTxdPool().AllocateTextureDictonarySlot(m_iModelID - MAX_MODEL_DFF_ID, strTxdName); if (uiSlotID != -1) { @@ -235,18 +301,49 @@ bool CClientModel::AllocateTXD(std::string &strTxdName) return false; } -void CClientModel::RestoreTXD(CModelInfo* pModelInfo) +void CClientModel::RestoreTXD() { - uint uiTextureDictonarySlotID = pModelInfo->GetModel() - MAX_MODEL_DFF_ID; + if (m_iModelID < MAX_MODEL_DFF_ID) + return; + + const uint txdSlotId = static_cast(m_iModelID - MAX_MODEL_DFF_ID); + + // Slot may already have been freed (e.g. resource stopped then model destroyed) + if (g_pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(txdSlotId)) + return; - for (uint uiModelID = 0; uiModelID < MAX_MODEL_DFF_ID; uiModelID++) + // Reset any DFF models that reference this TXD slot back to the default + const uint limit = static_cast(g_pGame->GetBaseIDforCOL()); + for (uint modelId = 0; modelId < limit; modelId++) { - CModelInfo* pModelInfo = g_pGame->GetModelInfo(uiModelID, true); + CModelInfo* pIter = g_pGame->GetModelInfo(modelId, true); + if (!pIter) + continue; + + if (pIter->GetTextureDictionaryID() == txdSlotId) + { + pIter->ResetTextureDictionaryID(); - if (pModelInfo->GetTextureDictionaryID() == uiTextureDictonarySlotID) - pModelInfo->SetTextureDictionaryID(0); + // If still referencing this slot (no stored default, or the + // default's pool slot was freed), redirect to TXD 0 so + // streaming won't hit the freed slot later. + if (pIter->GetTextureDictionaryID() == txdSlotId) + pIter->SetTextureDictionaryID(0); + } } - g_pGame->GetPools()->GetTxdPool().RemoveTextureDictonarySlot(uiTextureDictonarySlotID); - g_pGame->GetStreaming()->SetStreamingInfo(pModelInfo->GetModel(), 0, 0, 0, -1); + // Detach any replacement texture tracking from this TXD slot before the slot + // is destroyed. Without this, CClientTXD destructors that run later (queued + // by DeleteRecursive) would access freed TXD data via stale perTxdList entries. + if (CRenderWare* pRenderWare = g_pGame->GetRenderWare()) + pRenderWare->CleanupReplacementsInTxdSlot(static_cast(txdSlotId)); + + g_pGame->GetPools()->GetTxdPool().RemoveTextureDictonarySlot(txdSlotId); + + // Only clear streaming info for TXDs within SA's streaming range. + // Overflow TXDs (pool index >= 5000) map to model IDs in the COL/IPL + // range or beyond the ModelInfo array and have no streaming entry. + const uint txdModelId = static_cast(m_iModelID); + if (txdModelId < static_cast(g_pGame->GetBaseIDforCOL())) + g_pGame->GetStreaming()->SetStreamingInfo(txdModelId, 0, 0, 0, -1); } diff --git a/Client/mods/deathmatch/logic/CClientModel.h b/Client/mods/deathmatch/logic/CClientModel.h index 759890e0e57..bd0ae1a60d3 100644 --- a/Client/mods/deathmatch/logic/CClientModel.h +++ b/Client/mods/deathmatch/logic/CClientModel.h @@ -47,7 +47,7 @@ class CClientModel final private: void RestoreDFF(CModelInfo* pModelInfo); - void RestoreTXD(CModelInfo* pModelInfo); + void RestoreTXD(); protected: CClientManager* m_pManager; @@ -55,5 +55,5 @@ class CClientModel final int m_iModelID; eClientModelType m_eModelType; bool m_bAllocatedByUs = false; - CResource* m_pParentResource = nullptr; // Resource that allocated model + CResource* m_pParentResource = nullptr; // Resource that allocated model }; diff --git a/Client/mods/deathmatch/logic/CClientModelCacheManager.cpp b/Client/mods/deathmatch/logic/CClientModelCacheManager.cpp index 48d69ab6322..d2889c18868 100644 --- a/Client/mods/deathmatch/logic/CClientModelCacheManager.cpp +++ b/Client/mods/deathmatch/logic/CClientModelCacheManager.cpp @@ -10,18 +10,18 @@ #include "StdInc.h" #include "../../../core/CModelCacheManager.h" -#define PED_STREAM_IN_DISTANCE (250) -#define VEHICLE_STREAM_IN_DISTANCE (250) -#define STREAMER_STREAM_OUT_EXTRA_DISTANCE (50) +#define PED_STREAM_IN_DISTANCE (250) +#define VEHICLE_STREAM_IN_DISTANCE (250) +#define STREAMER_STREAM_OUT_EXTRA_DISTANCE (50) -#define PED_MAX_STREAM_DISTANCE ( PED_STREAM_IN_DISTANCE + STREAMER_STREAM_OUT_EXTRA_DISTANCE ) -#define PED_MAX_STREAM_DISTANCE_SQ ( PED_MAX_STREAM_DISTANCE * PED_MAX_STREAM_DISTANCE ) +#define PED_MAX_STREAM_DISTANCE (PED_STREAM_IN_DISTANCE + STREAMER_STREAM_OUT_EXTRA_DISTANCE) +#define PED_MAX_STREAM_DISTANCE_SQ (PED_MAX_STREAM_DISTANCE * PED_MAX_STREAM_DISTANCE) -#define VEHICLE_MAX_STREAM_DISTANCE ( VEHICLE_STREAM_IN_DISTANCE + STREAMER_STREAM_OUT_EXTRA_DISTANCE ) -#define VEHICLE_MAX_STREAM_DISTANCE_SQ ( VEHICLE_MAX_STREAM_DISTANCE * VEHICLE_MAX_STREAM_DISTANCE ) +#define VEHICLE_MAX_STREAM_DISTANCE (VEHICLE_STREAM_IN_DISTANCE + STREAMER_STREAM_OUT_EXTRA_DISTANCE) +#define VEHICLE_MAX_STREAM_DISTANCE_SQ (VEHICLE_MAX_STREAM_DISTANCE * VEHICLE_MAX_STREAM_DISTANCE) -#define PED_MAX_VELOCITY (10) -#define VEHICLE_MAX_VELOCITY (10) +#define PED_MAX_VELOCITY (10) +#define VEHICLE_MAX_VELOCITY (10) /////////////////////////////////////////////////////////////// // @@ -38,7 +38,7 @@ class CClientModelCacheManagerImpl : public CClientModelCacheManager // CClientModelCacheManager interface virtual void DoPulse(); virtual void OnRestreamModel(ushort usModelId); - virtual void SetCustomLimits(std::optional numVehicles, std::optional numPeds); + virtual void SetCustomLimits(const size_t* numVehicles, const size_t* numPeds); // CClientModelCacheManagerImpl methods CClientModelCacheManagerImpl(); @@ -520,7 +520,7 @@ void CClientModelCacheManagerImpl::OnRestreamModel(ushort usModelId) m_pCoreModelCacheManager->OnRestreamModel(usModelId); } -void CClientModelCacheManagerImpl::SetCustomLimits(std::optional numVehicles, std::optional numPeds) +void CClientModelCacheManagerImpl::SetCustomLimits(const size_t* numVehicles, const size_t* numPeds) { m_pCoreModelCacheManager->SetCustomLimits(numVehicles, numPeds); } diff --git a/Client/mods/deathmatch/logic/CClientModelCacheManager.h b/Client/mods/deathmatch/logic/CClientModelCacheManager.h index e8e9aed6e06..0773806a460 100644 --- a/Client/mods/deathmatch/logic/CClientModelCacheManager.h +++ b/Client/mods/deathmatch/logic/CClientModelCacheManager.h @@ -15,7 +15,7 @@ class CClientModelCacheManager // CClientModelCacheManager interface virtual void DoPulse() = 0; virtual void OnRestreamModel(ushort usModelId) = 0; - virtual void SetCustomLimits(std::optional numVehicles, std::optional numPeds) = 0; + virtual void SetCustomLimits(const size_t* numVehicles, const size_t* numPeds) = 0; }; CClientModelCacheManager* NewClientModelCacheManager(); diff --git a/Client/mods/deathmatch/logic/CClientModelManager.cpp b/Client/mods/deathmatch/logic/CClientModelManager.cpp index 9b4ae7cc399..81a93f9141b 100644 --- a/Client/mods/deathmatch/logic/CClientModelManager.cpp +++ b/Client/mods/deathmatch/logic/CClientModelManager.cpp @@ -9,13 +9,9 @@ *****************************************************************************/ #include "StdInc.h" -CClientModelManager::CClientModelManager() : m_Models(std::make_unique[]>(g_pGame->GetBaseIDforCOL())) +CClientModelManager::CClientModelManager() : m_Models(std::make_unique[]>(MAX_MODEL_ID)) { - const unsigned int uiMaxModelID = g_pGame->GetBaseIDforCOL(); - for (unsigned int i = 0; i < uiMaxModelID; i++) - { - m_Models[i] = nullptr; - } + m_reserved.assign(MAX_MODEL_ID, 0); } CClientModelManager::~CClientModelManager(void) @@ -25,94 +21,206 @@ CClientModelManager::~CClientModelManager(void) void CClientModelManager::RemoveAll(void) { - const unsigned int uiMaxModelID = g_pGame->GetBaseIDforCOL(); - for (unsigned int i = 0; i < uiMaxModelID; i++) + const unsigned int uiMaxModelID = MAX_MODEL_ID; + + static std::atomic_bool inRemoveAll{false}; + if (inRemoveAll.exchange(true)) + return; + + struct RemoveAllGuard + { + std::atomic_bool& flag; + ~RemoveAllGuard() { flag = false; } + } guard{inRemoveAll}; + + std::vector> models; + { + std::lock_guard lock(m_idMutex); + models.reserve(m_modelCount); + for (unsigned int i = 0; i < uiMaxModelID; i++) + { + if (m_Models[i] != nullptr) + models.push_back(m_Models[i]); + } + } + + for (const auto& model : models) + Remove(model); + { - m_Models[i] = nullptr; + std::lock_guard lock(m_idMutex); + for (unsigned int i = 0; i < uiMaxModelID; i++) + m_Models[i] = nullptr; + m_modelCount = 0; + std::fill(m_reserved.begin(), m_reserved.end(), 0); } - m_modelCount = 0; + inRemoveAll = false; } void CClientModelManager::Add(const std::shared_ptr& pModel) { - if (m_Models[pModel->GetModelID()] != nullptr) + (void)TryAdd(pModel); +} + +bool CClientModelManager::TryAdd(const std::shared_ptr& pModel) +{ + int modelId = pModel->GetModelID(); + + if (modelId < 0 || modelId >= MAX_MODEL_ID) + return false; + + bool added = false; { - dassert(m_Models[pModel->GetModelID()].get() == pModel.get()); - return; + std::lock_guard lock(m_idMutex); + if (static_cast(modelId) < m_reserved.size()) + m_reserved[modelId] = 0; + + if (m_Models[modelId] != nullptr) + return false; + else + { + m_Models[modelId] = pModel; + m_modelCount++; + added = true; + } } - m_Models[pModel->GetModelID()] = pModel; - m_modelCount++; + + return added; } bool CClientModelManager::Remove(const std::shared_ptr& pModel) { int modelId = pModel->GetModelID(); - if (m_Models[modelId] != nullptr) + + if (modelId < 0 || modelId >= MAX_MODEL_ID) + return false; + + std::shared_ptr model; { - CResource* parentResource = m_Models[modelId]->GetParentResource(); - if (parentResource) - parentResource->GetResourceModelStreamer()->FullyReleaseModel(modelId); - m_Models[modelId]->RestoreEntitiesUsingThisModel(); + std::lock_guard lock(m_idMutex); + if (m_Models[modelId] == nullptr) + return false; + + model = m_Models[modelId]; m_Models[modelId] = nullptr; - m_modelCount--; - return true; + if (static_cast(modelId) < m_reserved.size()) + m_reserved[modelId] = 0; + if (m_modelCount > 0) + m_modelCount--; + } + + CResource* parentResource = model ? model->GetParentResource() : nullptr; + if (parentResource && modelId <= static_cast(std::numeric_limits::max())) + { + if (auto* streamer = parentResource->GetResourceModelStreamer()) + streamer->FullyReleaseModel(static_cast(modelId)); + } + if (model) + { + model->RestoreEntitiesUsingThisModel(); + model->Deallocate(); } - return false; + return true; } int CClientModelManager::GetFirstFreeModelID(void) { + std::lock_guard lock(m_idMutex); + const unsigned int uiMaxModelID = g_pGame->GetBaseIDforCOL(); - for (unsigned int i = 0; i < uiMaxModelID; i++) + const unsigned int uiMaxDffModelID = std::min(MAX_MODEL_DFF_ID, uiMaxModelID); + for (unsigned int i = 0; i < uiMaxDffModelID; i++) { CModelInfo* pModelInfo = g_pGame->GetModelInfo(i, true); - if (!pModelInfo->IsValid()) + if (m_Models[i] == nullptr && pModelInfo && !pModelInfo->IsValid()) { + if (i < m_reserved.size() && m_reserved[i] != 0) + continue; + if (i < m_reserved.size()) + m_reserved[i] = 1; return i; } } return INVALID_MODEL_ID; } +void CClientModelManager::ReleaseModelID(int iModelID) +{ + if (iModelID < 0) + return; + std::lock_guard lock(m_idMutex); + if (static_cast(iModelID) < m_reserved.size()) + m_reserved[iModelID] = 0; +} + int CClientModelManager::GetFreeTxdModelID() { - std::uint16_t usTxdId = g_pGame->GetPools()->GetTxdPool().GetFreeTextureDictonarySlot(); - if (usTxdId == -1) + // [0, 5000) have streaming entries (model IDs 20000-24999), so they + // support both engineLoadTXD/engineImportTXD and engineImageLinkTXD. + // [5000, 6316) maps to COL/IPL/DAT/IFP streaming IDs - not usable here. + // [6316+) are overflow slots with no streaming entries. They work with + // engineLoadTXD/engineImportTXD and engineImageLinkTXD (direct load). + auto& txdPool = g_pGame->GetPools()->GetTxdPool(); + + // Prefer the IMG-linkable range so all engineRequestTXD callers can + // freely use engineImageLinkTXD on the returned ID + std::uint32_t uiTxdId = txdPool.GetFreeTextureDictonarySlotInRange(CTxdPool::SA_TXD_POOL_CAPACITY); + + // Fall back to overflow range (no deferred streaming, but direct load works) + if (uiTxdId == static_cast(-1)) + uiTxdId = txdPool.GetFreeTextureDictonarySlotAbove(CTxdPool::MAX_STREAMING_TXD_SLOT); + + if (uiTxdId == static_cast(-1)) + return INVALID_MODEL_ID; + + // Pool index must fit within our model ID range [MAX_MODEL_DFF_ID, MAX_MODEL_TXD_ID) + if (uiTxdId >= static_cast(MAX_MODEL_TXD_ID - MAX_MODEL_DFF_ID)) return INVALID_MODEL_ID; - return MAX_MODEL_DFF_ID + usTxdId; + + return static_cast(MAX_MODEL_DFF_ID + uiTxdId); } -std::shared_ptr CClientModelManager::FindModelByID(int iModelID) +std::shared_ptr CClientModelManager::FindModelByID(int iModelID) { - int32_t iMaxModelId = g_pGame->GetBaseIDforCOL(); + if (iModelID < 0 || iModelID >= MAX_MODEL_ID) + return nullptr; - if (iModelID < iMaxModelId) - return m_Models[iModelID]; - - return nullptr; + std::lock_guard lock(m_idMutex); + return m_Models[iModelID]; } std::shared_ptr CClientModelManager::Request(CClientManager* pManager, int iModelID, eClientModelType eType) { - std::shared_ptr pModel = FindModelByID(iModelID); + std::lock_guard lock(m_idMutex); + + std::shared_ptr pModel = nullptr; + if (iModelID >= 0 && iModelID < MAX_MODEL_ID) + pModel = m_Models[iModelID]; + if (pModel == nullptr) { pModel = std::make_shared(pManager, iModelID, eType); + pModel->m_eModelType = eType; } - - pModel->m_eModelType = eType; return pModel; } std::vector> CClientModelManager::GetModelsByType(const eClientModelType type, const unsigned int minModelID) { std::vector> found; - found.reserve(m_modelCount); + { + std::lock_guard lock(m_idMutex); + found.reserve(m_modelCount); + } - const unsigned int uiMaxModelID = g_pGame->GetBaseIDforCOL(); + const unsigned int uiMaxModelID = MAX_MODEL_ID; for (unsigned int i = minModelID; i < uiMaxModelID; i++) { - const std::shared_ptr& model = m_Models[i]; + std::shared_ptr model; + { + std::lock_guard lock(m_idMutex); + model = m_Models[i]; + } if (model && model->GetModelType() == type) { found.push_back(model); @@ -123,10 +231,24 @@ std::vector> CClientModelManager::GetModelsByType( void CClientModelManager::DeallocateModelsAllocatedByResource(CResource* pResource) { - const unsigned int uiMaxModelID = g_pGame->GetBaseIDforCOL(); + const unsigned int uiMaxModelID = MAX_MODEL_ID; + + std::vector> models; + { + std::lock_guard lock(m_idMutex); + models.reserve(m_modelCount); + } for (unsigned int i = 0; i < uiMaxModelID; i++) { - if (m_Models[i] != nullptr && m_Models[i]->GetParentResource() == pResource) - Remove(m_Models[i]); + std::shared_ptr model; + { + std::lock_guard lock(m_idMutex); + model = m_Models[i]; + } + if (model != nullptr && model->GetParentResource() == pResource) + models.push_back(model); } + + for (const auto& model : models) + Remove(model); } diff --git a/Client/mods/deathmatch/logic/CClientModelManager.h b/Client/mods/deathmatch/logic/CClientModelManager.h index add0053a1e8..7fbb983d4cb 100644 --- a/Client/mods/deathmatch/logic/CClientModelManager.h +++ b/Client/mods/deathmatch/logic/CClientModelManager.h @@ -15,27 +15,31 @@ class CClientModelManager; #include #include #include +#include +#include #include "CClientModel.h" #define MAX_MODEL_DFF_ID 20000 -#define MAX_MODEL_TXD_ID 25000 -#define MAX_MODEL_ID 25000 +#define MAX_MODEL_TXD_ID 52768 +#define MAX_MODEL_ID 52768 class CClientModelManager { friend class CClientModel; public: - CClientModelManager::CClientModelManager(); + CClientModelManager(); ~CClientModelManager(void); void RemoveAll(void); void Add(const std::shared_ptr& pModel); + bool TryAdd(const std::shared_ptr& pModel); bool Remove(const std::shared_ptr& pModel); - int GetFirstFreeModelID(void); - int GetFreeTxdModelID(); + int GetFirstFreeModelID(void); + void ReleaseModelID(int iModelID); + int GetFreeTxdModelID(); std::shared_ptr FindModelByID(int iModelID); std::shared_ptr Request(CClientManager* pManager, int iModelID, eClientModelType eType); @@ -47,4 +51,6 @@ class CClientModelManager private: std::unique_ptr[]> m_Models; unsigned int m_modelCount = 0; + std::mutex m_idMutex; + std::vector m_reserved; }; diff --git a/Client/mods/deathmatch/logic/CClientObject.cpp b/Client/mods/deathmatch/logic/CClientObject.cpp index 8137a191a2e..210d5ed8a34 100644 --- a/Client/mods/deathmatch/logic/CClientObject.cpp +++ b/Client/mods/deathmatch/logic/CClientObject.cpp @@ -14,7 +14,7 @@ #define CCLIENTOBJECT_MAX 250 #ifndef M_PI -#define M_PI 3.14159265358979323846 + #define M_PI 3.14159265358979323846 #endif CClientObject::CClientObject(CClientManager* pManager, ElementID ID, unsigned short usModel, bool bLowLod) @@ -136,10 +136,8 @@ void CClientObject::GetRotationDegrees(CVector& vecRotation) const void CClientObject::GetRotationRadians(CVector& vecRotation) const { - if (m_pObject && m_pAttachedToEntity) // Temp fix for static objects-> + if (m_pObject) { - // We've been returning the rotation that got set last so far (::m_vecRotation).. - // but we need to get the real rotation for when the game moves the objects.. CMatrix matTemp; m_pObject->GetMatrix(&matTemp); vecRotation = matTemp.GetRotation(); @@ -526,9 +524,9 @@ void CClientObject::Create() // Apply our data to the object m_pObject->Teleport(m_vecPosition.fX, m_vecPosition.fY, m_vecPosition.fZ); m_pObject->SetOrientation(m_vecRotation.fX, m_vecRotation.fY, m_vecRotation.fZ); - #ifndef MTA_BUILDINGS +#ifndef MTA_BUILDINGS m_pObject->ProcessCollision(); - #endif +#endif m_pObject->SetupLighting(); m_pObject->SetFrozen(m_bIsFrozen); @@ -645,16 +643,28 @@ void CClientObject::StreamedInPulse() // Are we not frozen if (!m_bIsFrozen) { - // Grab our actual position (as GTA moves it too) - CVector vecPosition = *m_pObject->GetPosition(); - - // Has it moved without MTA knowing? - if (vecPosition != m_vecPosition) + // Model physics enabled? + if ((m_pModelInfo && m_pModelInfo->GetObjectPropertiesGroup() != -1) || !m_pModelInfo) { - m_vecPosition = vecPosition; + // Grab our actual position & rotation (as GTA moves it too) + CVector vecPosition = *m_pObject->GetPosition(); + + CVector vecRot; + GetRotationRadians(vecRot); - // Update our streaming position - UpdateStreamPosition(m_vecPosition); + // Has it moved without MTA knowing? + if (vecPosition != m_vecPosition) + { + m_vecPosition = vecPosition; + + // Update our streaming position + UpdateStreamPosition(m_vecPosition); + } + + if (vecRot != m_vecRotation) + { + m_vecRotation = vecRot; + } } } } diff --git a/Client/mods/deathmatch/logic/CClientObject.h b/Client/mods/deathmatch/logic/CClientObject.h index 03b37fbfbcc..dce385eb6a1 100644 --- a/Client/mods/deathmatch/logic/CClientObject.h +++ b/Client/mods/deathmatch/logic/CClientObject.h @@ -161,10 +161,10 @@ class CClientObject : public CClientStreamElement CVector m_vecMoveSpeed; CVector m_vecTurnSpeed; - const bool m_bIsLowLod; // true if this object is low LOD - CClientObject* m_pLowLodObject; // Pointer to low LOD version of this object - std::vector m_HighLodObjectList; // List of objects that use this object as a low LOD version - bool m_IsHiddenLowLod; // true if this object is low LOD and should not be drawn + const bool m_bIsLowLod; // true if this object is low LOD + CClientObject* m_pLowLodObject; // Pointer to low LOD version of this object + std::vector m_HighLodObjectList; // List of objects that use this object as a low LOD version + bool m_IsHiddenLowLod; // true if this object is low LOD and should not be drawn std::shared_ptr m_clientModel; public: diff --git a/Client/mods/deathmatch/logic/CClientObjectManager.cpp b/Client/mods/deathmatch/logic/CClientObjectManager.cpp index c59483b4db2..39f8e8d2120 100644 --- a/Client/mods/deathmatch/logic/CClientObjectManager.cpp +++ b/Client/mods/deathmatch/logic/CClientObjectManager.cpp @@ -91,6 +91,21 @@ CClientObject* CClientObjectManager::Get(ElementID ID) bool CClientObjectManager::IsValidModel(unsigned long ulObjectModel) { + CModelInfo* pModelInfo = g_pGame->GetModelInfo(ulObjectModel); + if (!pModelInfo || !pModelInfo->GetInterface()) + return false; + + // Custom models allocated via engineRequestModel have a parent ID + if (pModelInfo->GetParentID() != 0) + { + eModelInfoType eType = pModelInfo->GetModelType(); + // Custom object models must not be ped or vehicle types + if (eType == eModelInfoType::PED || eType == eModelInfoType::VEHICLE) + return false; + return (eType == eModelInfoType::CLUMP || eType == eModelInfoType::ATOMIC || eType == eModelInfoType::WEAPON || eType == eModelInfoType::TIME); + } + + // Standard GTA models must be in valid range if (ulObjectModel >= static_cast(g_pGame->GetBaseIDforTXD())) return false; @@ -102,10 +117,6 @@ bool CClientObjectManager::IsValidModel(unsigned long ulObjectModel) if (300 <= ulObjectModel && ulObjectModel <= 314) return false; - CModelInfo* pModelInfo = g_pGame->GetModelInfo(ulObjectModel); - if (!pModelInfo || !pModelInfo->GetInterface()) - return false; - if (!pModelInfo->IsAllocatedInArchive()) return false; @@ -272,8 +283,7 @@ bool CClientObjectManager::IsHardObjectLimitReached() "CClientObjectManager reached limit -" " ENTRY_INFO_NODES:%d/%d" " POINTER_DOUBLE_LINKS:%d/%d", - m_iEntryInfoNodeEntries, MAX_ENTRY_INFO_NODES_MTA, - m_iPointerNodeDoubleLinkEntries, MAX_POINTER_DOUBLE_LINKS_MTA); + m_iEntryInfoNodeEntries, MAX_ENTRY_INFO_NODES_MTA, m_iPointerNodeDoubleLinkEntries, MAX_POINTER_DOUBLE_LINKS_MTA); g_pCore->GetConsole()->Echo(strMessage); AddReportLog(7430, strMessage); } diff --git a/Client/mods/deathmatch/logic/CClientPacketRecorder.cpp b/Client/mods/deathmatch/logic/CClientPacketRecorder.cpp index 9c96b2b54cd..81a7de2aa21 100644 --- a/Client/mods/deathmatch/logic/CClientPacketRecorder.cpp +++ b/Client/mods/deathmatch/logic/CClientPacketRecorder.cpp @@ -368,7 +368,7 @@ void CClientPacketRecorder::DoPulse() } // Read out the packet id - unsigned char ucPacketID = fgetc(pFile); + unsigned char ucPacketID = static_cast(fgetc(pFile)); // Is it 0xFE (local player data) or 0xFF (local keys)? if (ucPacketID == 0xFE) @@ -396,7 +396,7 @@ void CClientPacketRecorder::DoPulse() // Write the filedata to the bitstream for (unsigned long i = 0; i < ulSize; i++) { - char c = fgetc(pFile); + char c = static_cast(fgetc(pFile)); pBitStream->Write(c); } @@ -412,7 +412,7 @@ void CClientPacketRecorder::DoPulse() // Remember the new offset and read out the time for the next packet m_ulCurrentOffset = ftell(pFile); fread(&m_lNextPacketTime, sizeof(long), 1, pFile); - m_ucNextPacketID = fgetc(pFile); + m_ucNextPacketID = static_cast(fgetc(pFile)); // g_pCore->GetConsole()->Printf("next time: %u\n",m_lNextPacketTime); // Reached end of file? diff --git a/Client/mods/deathmatch/logic/CClientPad.cpp b/Client/mods/deathmatch/logic/CClientPad.cpp index 223028a0c70..d87e0c8130f 100644 --- a/Client/mods/deathmatch/logic/CClientPad.cpp +++ b/Client/mods/deathmatch/logic/CClientPad.cpp @@ -227,7 +227,7 @@ void CClientPad::DoPulse(CClientPed* pPed) { if (!bInVehicle) { - cs.ButtonCircle = (m_fStates[0]) ? 255 : 0; // Fire + cs.ButtonCircle = (m_fStates[0]) ? 255 : 0; // Fire cs.LeftStickY = (short)(((m_fStates[3] && m_fStates[4]) || (!m_fStates[3] && !m_fStates[4])) ? 0 : (m_fStates[3]) ? m_fStates[3] * -128 @@ -237,27 +237,27 @@ void CClientPad::DoPulse(CClientPed* pPed) : (m_fStates[5]) ? m_fStates[5] * -128 : m_fStates[6] * 128); - cs.ButtonTriangle = (m_fStates[9]) ? 255 : 0; // Get in/out and alternative fighting styles + cs.ButtonTriangle = (m_fStates[9]) ? 255 : 0; // Get in/out and alternative fighting styles - cs.ButtonSquare = (m_fStates[11]) ? 255 : 0; // Jump + cs.ButtonSquare = (m_fStates[11]) ? 255 : 0; // Jump - cs.ButtonCross = (m_fStates[12]) ? 255 : 0; // Sprint + cs.ButtonCross = (m_fStates[12]) ? 255 : 0; // Sprint - cs.ShockButtonR = (m_fStates[13]) ? 255 : 0; // Look Behind + cs.ShockButtonR = (m_fStates[13]) ? 255 : 0; // Look Behind - cs.ShockButtonL = (m_fStates[14]) ? 255 : 0; // Crouch + cs.ShockButtonL = (m_fStates[14]) ? 255 : 0; // Crouch - cs.LeftShoulder1 = (m_fStates[15]) ? 255 : 0; // Action + cs.LeftShoulder1 = (m_fStates[15]) ? 255 : 0; // Action - cs.m_bPedWalk = (m_fStates[16]) ? 255 : 0; // Walk + cs.m_bPedWalk = (m_fStates[16]) ? 255 : 0; // Walk - cs.RightShoulder1 = (m_fStates[39]) ? 255 : 0; // Aim Weapon + cs.RightShoulder1 = (m_fStates[39]) ? 255 : 0; // Aim Weapon } else { - cs.ButtonCircle = (m_fStates[17]) ? 255 : 0; // Fire + cs.ButtonCircle = (m_fStates[17]) ? 255 : 0; // Fire - cs.LeftShoulder1 = (m_fStates[18]) ? 255 : 0; // Secondary Fire + cs.LeftShoulder1 = (m_fStates[18]) ? 255 : 0; // Secondary Fire cs.LeftStickX = (short)(((m_fStates[19] && m_fStates[20]) || (!m_fStates[19] && !m_fStates[20])) ? 0 : (m_fStates[19]) ? m_fStates[19] * -128 : m_fStates[20] * 128); @@ -266,17 +266,17 @@ void CClientPad::DoPulse(CClientPed* pPed) : (m_fStates[21]) ? m_fStates[21] * -128 : m_fStates[22] * 128); - cs.ButtonCross = (short)((m_fStates[23] * 255)); // Accelerate + cs.ButtonCross = (short)((m_fStates[23] * 255)); // Accelerate - cs.ButtonSquare = (short)((m_fStates[24] * 255)); // Reverse + cs.ButtonSquare = (short)((m_fStates[24] * 255)); // Reverse - cs.ShockButtonL = (m_fStates[28]) ? 255 : 0; // Horn + cs.ShockButtonL = (m_fStates[28]) ? 255 : 0; // Horn - cs.RightShoulder1 = (m_fStates[30]) ? 255 : 0; // Handbrake + cs.RightShoulder1 = (m_fStates[30]) ? 255 : 0; // Handbrake - cs.LeftShoulder2 = (m_fStates[31] || m_fStates[33]) ? 255 : 0; // Look Left + cs.LeftShoulder2 = (m_fStates[31] || m_fStates[33]) ? 255 : 0; // Look Left - cs.RightShoulder2 = (m_fStates[32] || m_fStates[33]) ? 255 : 0; // Look Right + cs.RightShoulder2 = (m_fStates[32] || m_fStates[33]) ? 255 : 0; // Look Right cs.RightStickX = (short)(((m_fStates[35] && m_fStates[36]) || (!m_fStates[35] && !m_fStates[36])) ? 0 : (m_fStates[35]) ? m_fStates[35] * 128 @@ -303,69 +303,69 @@ bool CClientPad::GetControlState(const char* szName, CControllerState& State, bo { case 0: return State.ButtonCircle == 255; - break; // fire + break; // fire case 1: return State.RightShoulder2 == 255; - break; // next wep + break; // next wep case 2: return State.LeftShoulder2 == 255; - break; // previous wep + break; // previous wep case 3: return State.LeftStickY == -128; - break; // forwards + break; // forwards case 4: return State.LeftStickY == 128; - break; // backwards + break; // backwards case 5: return State.LeftStickX == -128; - break; // left + break; // left case 6: return State.LeftStickX == 128; - break; // right + break; // right case 7: - return State.RightShoulder2 == 255; - break; // zoom in - case 8: return State.LeftShoulder2 == 255; - break; // zoom out + break; // zoom in + case 8: + return State.RightShoulder2 == 255; + break; // zoom out case 9: - return State.ButtonTriangle == 255; // enter_exit + return State.ButtonTriangle == 255; // enter_exit case 10: - return State.Select == 255; // change_cam + return State.Select == 255; // change_cam case 11: return State.ButtonSquare == 255; - break; // jump + break; // jump case 12: return State.ButtonCross == 255; - break; // sprint + break; // sprint case 13: return State.ShockButtonR == 255; - break; // look behind + break; // look behind case 14: return State.ShockButtonL == 255; - break; // crouch + break; // crouch case 15: return State.LeftShoulder1 == 255; - break; // action + break; // action case 16: return State.m_bPedWalk > 0; - break; // walk + break; // walk // vehicle keys case 39: return State.RightShoulder1 == 255; - break; // aim + break; // aim case 40: return State.DPadRight == 255; - break; // conv yes + break; // conv yes case 41: return State.DPadLeft == 255; - break; // conv no + break; // conv no case 42: return State.DPadUp == 255; - break; // group forward + break; // group forward case 43: return State.DPadDown == 255; - break; // group backward + break; // group backward default: break; } @@ -376,69 +376,69 @@ bool CClientPad::GetControlState(const char* szName, CControllerState& State, bo { case 17: return State.ButtonCircle == 255; - break; // fire + break; // fire case 18: return State.LeftShoulder1 == 255; - break; // secondary fire + break; // secondary fire case 19: return State.LeftStickX == -128; - break; // left + break; // left case 20: return State.LeftStickX == 128; - break; // right + break; // right case 21: return State.LeftStickY == -128; - break; // forward + break; // forward case 22: return State.LeftStickY == 128; - break; // backward + break; // backward case 23: return State.ButtonCross == 255; - break; // accel + break; // accel case 24: return State.ButtonSquare == 255; - break; // reverse + break; // reverse case 25: return State.DPadUp == 255; - break; // radio next + break; // radio next case 26: return State.DPadDown == 255; - break; // radio prev + break; // radio prev case 27: return State.m_bRadioTrackSkip == 255; - break; // track skip + break; // track skip case 28: return State.ShockButtonL == 255; - break; // horn + break; // horn case 29: return State.ShockButtonR == 255; - break; // sub-mission + break; // sub-mission case 30: return State.RightShoulder1 == 255; - break; // handbrake + break; // handbrake case 31: return State.LeftShoulder2 == 255; - break; // look left + break; // look left case 32: return State.RightShoulder2 == 255; - break; // look right + break; // look right case 33: - return State.LeftShoulder2 == 255 && State.RightShoulder2 == 255; // look behind + return State.LeftShoulder2 == 255 && State.RightShoulder2 == 255; // look behind case 34: return false; - break; // mouse look + break; // mouse look case 35: return State.RightStickX == 128; - break; // control left + break; // control left case 36: return State.RightStickX == -128; - break; // control right + break; // control right case 37: return State.RightStickY == 128; - break; // control down + break; // control down case 38: return State.RightStickY == -128; - break; // control up + break; // control up default: break; } @@ -483,46 +483,46 @@ bool CClientPad::GetAnalogControlState(const char* szName, CControllerState& cs, { case 0: fState = m_sScriptedStates[uiIndex] / -128.0f; - return true; // Left + return true; // Left case 1: fState = m_sScriptedStates[uiIndex] / 128.0f; - return true; // Right + return true; // Right case 2: fState = m_sScriptedStates[uiIndex] / -128.0f; - return true; // Up + return true; // Up case 3: fState = m_sScriptedStates[uiIndex] / 128.0f; - return true; // Down + return true; // Down case 4: fState = m_sScriptedStates[uiIndex] / -128.0f; - return true; // Left + return true; // Left case 5: fState = m_sScriptedStates[uiIndex] / 128.0f; - return true; // Right + return true; // Right case 6: fState = m_sScriptedStates[uiIndex] / -128.0f; - return true; // Up + return true; // Up case 7: fState = m_sScriptedStates[uiIndex] / 128.0f; - return true; // Down + return true; // Down case 8: fState = m_sScriptedStates[uiIndex] / 255.0f; - return true; // Accel + return true; // Accel case 9: fState = m_sScriptedStates[uiIndex] / 255.0f; - return true; // Reverse + return true; // Reverse case 10: fState = m_sScriptedStates[uiIndex] / -128.0f; - return true; // Special Left + return true; // Special Left case 11: fState = m_sScriptedStates[uiIndex] / 128.0f; - return true; // Special Right + return true; // Special Right case 12: fState = m_sScriptedStates[uiIndex] / -128.0f; - return true; // Special Up + return true; // Special Up case 13: fState = m_sScriptedStates[uiIndex] / 128.0f; - return true; // Special Down + return true; // Special Down default: return false; } @@ -533,16 +533,16 @@ bool CClientPad::GetAnalogControlState(const char* szName, CControllerState& cs, { case 0: fState = cs.LeftStickX < 0 ? cs.LeftStickX / -128.0f : 0; - return true; // Left + return true; // Left case 1: fState = cs.LeftStickX > 0 ? cs.LeftStickX / 128.0f : 0; - return true; // Right + return true; // Right case 2: fState = cs.LeftStickY < 0 ? cs.LeftStickY / -128.0f : 0; - return true; // Up + return true; // Up case 3: fState = cs.LeftStickY > 0 ? cs.LeftStickY / 128.0f : 0; - return true; // Down + return true; // Down default: fState = 0; return true; @@ -554,34 +554,34 @@ bool CClientPad::GetAnalogControlState(const char* szName, CControllerState& cs, { case 4: fState = cs.LeftStickX < 0 ? cs.LeftStickX / -128.0f : 0; - return true; // Left + return true; // Left case 5: fState = cs.LeftStickX > 0 ? cs.LeftStickX / 128.0f : 0; - return true; // Right + return true; // Right case 6: fState = cs.LeftStickY < 0 ? cs.LeftStickY / -128.0f : 0; - return true; // Up + return true; // Up case 7: fState = cs.LeftStickY > 0 ? cs.LeftStickY / 128.0f : 0; - return true; // Down + return true; // Down case 8: fState = cs.ButtonCross > 0 ? cs.ButtonCross / 255.0f : 0; - return true; // Accel + return true; // Accel case 9: fState = cs.ButtonSquare > 0 ? cs.ButtonSquare / 255.0f : 0; - return true; // Reverse + return true; // Reverse case 10: fState = cs.RightStickX < 0 ? cs.RightStickX / -128.0f : 0; - return true; // Special Left + return true; // Special Left case 11: fState = cs.RightStickX > 0 ? cs.RightStickX / 128.0f : 0; - return true; // Special Right + return true; // Special Right case 12: fState = cs.RightStickY < 0 ? cs.RightStickY / -128.0f : 0; - return true; // Special Up + return true; // Special Up case 13: fState = cs.RightStickY > 0 ? cs.RightStickY / 128.0f : 0; - return true; // Special Down + return true; // Special Down default: fState = 0; return true; @@ -606,81 +606,81 @@ bool CClientPad::SetAnalogControlState(const char* szName, float fState, bool bF m_sScriptedStates[1] = 0; m_bScriptedStatesNextFrameOverride[uiIndex] = bFrameForced; m_bScriptedStatesNextFrameOverride[1] = false; - return true; // Left + return true; // Left case 1: m_sScriptedStates[uiIndex] = (short)(fState * 128.0f); m_sScriptedStates[0] = 0; m_bScriptedStatesNextFrameOverride[uiIndex] = bFrameForced; m_bScriptedStatesNextFrameOverride[0] = false; - return true; // Right + return true; // Right case 2: m_sScriptedStates[uiIndex] = (short)(fState * -128.0f); m_sScriptedStates[3] = 0; m_bScriptedStatesNextFrameOverride[uiIndex] = bFrameForced; m_bScriptedStatesNextFrameOverride[3] = false; - return true; // Up + return true; // Up case 3: m_sScriptedStates[uiIndex] = (short)(fState * 128.0f); m_sScriptedStates[2] = 0; m_bScriptedStatesNextFrameOverride[uiIndex] = bFrameForced; m_bScriptedStatesNextFrameOverride[2] = false; - return true; // Down + return true; // Down case 4: m_sScriptedStates[uiIndex] = (short)(fState * -128.0f); m_sScriptedStates[5] = 0; m_bScriptedStatesNextFrameOverride[uiIndex] = bFrameForced; m_bScriptedStatesNextFrameOverride[5] = false; - return true; // Vehicle Left + return true; // Vehicle Left case 5: m_sScriptedStates[uiIndex] = (short)(fState * 128.0f); m_sScriptedStates[4] = 0; m_bScriptedStatesNextFrameOverride[uiIndex] = bFrameForced; m_bScriptedStatesNextFrameOverride[4] = false; - return true; // Vehicle Right + return true; // Vehicle Right case 6: m_sScriptedStates[uiIndex] = (short)(fState * -128.0f); m_sScriptedStates[7] = 0; m_bScriptedStatesNextFrameOverride[uiIndex] = bFrameForced; m_bScriptedStatesNextFrameOverride[7] = false; - return true; // Up + return true; // Up case 7: m_sScriptedStates[uiIndex] = (short)(fState * 128.0f); m_sScriptedStates[6] = 0; m_bScriptedStatesNextFrameOverride[uiIndex] = bFrameForced; m_bScriptedStatesNextFrameOverride[6] = false; - return true; // Down + return true; // Down case 8: m_sScriptedStates[uiIndex] = (short)(fState * 255.0f); m_bScriptedStatesNextFrameOverride[uiIndex] = bFrameForced; - return true; // Accel + return true; // Accel case 9: m_sScriptedStates[uiIndex] = (short)(fState * 255.0f); m_bScriptedStatesNextFrameOverride[uiIndex] = bFrameForced; - return true; // Reverse + return true; // Reverse case 10: m_sScriptedStates[uiIndex] = (short)(fState * -128.0f); m_sScriptedStates[11] = 0; m_bScriptedStatesNextFrameOverride[uiIndex] = bFrameForced; m_bScriptedStatesNextFrameOverride[11] = false; - return true; // Special Left + return true; // Special Left case 11: m_sScriptedStates[uiIndex] = (short)(fState * 128.0f); m_sScriptedStates[10] = 0; m_bScriptedStatesNextFrameOverride[uiIndex] = bFrameForced; m_bScriptedStatesNextFrameOverride[10] = false; - return true; // Special Right + return true; // Special Right case 12: m_sScriptedStates[uiIndex] = (short)(fState * -128.0f); m_sScriptedStates[13] = 0; m_bScriptedStatesNextFrameOverride[uiIndex] = bFrameForced; m_bScriptedStatesNextFrameOverride[13] = false; - return true; // Special Up + return true; // Special Up case 13: m_sScriptedStates[uiIndex] = (short)(fState * 128.0f); m_sScriptedStates[12] = 0; m_bScriptedStatesNextFrameOverride[uiIndex] = bFrameForced; m_bScriptedStatesNextFrameOverride[12] = false; - return true; // Special Down + return true; // Special Down default: return false; } @@ -704,37 +704,37 @@ void CClientPad::ProcessSetAnalogControlState(CControllerState& cs, bool bOnFoot { unsigned int uiIndex = 0; - ProcessControl(cs.LeftStickX, uiIndex); // Left + ProcessControl(cs.LeftStickX, uiIndex); // Left uiIndex++; - ProcessControl(cs.LeftStickX, uiIndex); // Right + ProcessControl(cs.LeftStickX, uiIndex); // Right uiIndex++; - ProcessControl(cs.LeftStickY, uiIndex); // Up + ProcessControl(cs.LeftStickY, uiIndex); // Up uiIndex++; - ProcessControl(cs.LeftStickY, uiIndex); // Down + ProcessControl(cs.LeftStickY, uiIndex); // Down } else { unsigned int uiIndex = 4; - ProcessControl(cs.LeftStickX, uiIndex); // Left + ProcessControl(cs.LeftStickX, uiIndex); // Left uiIndex++; - ProcessControl(cs.LeftStickX, uiIndex); // Right + ProcessControl(cs.LeftStickX, uiIndex); // Right uiIndex++; - ProcessControl(cs.LeftStickY, uiIndex); // Up + ProcessControl(cs.LeftStickY, uiIndex); // Up uiIndex++; - ProcessControl(cs.LeftStickY, uiIndex); // Down + ProcessControl(cs.LeftStickY, uiIndex); // Down uiIndex++; - ProcessControl(cs.ButtonCross, uiIndex); // Accel + ProcessControl(cs.ButtonCross, uiIndex); // Accel uiIndex++; - ProcessControl(cs.ButtonSquare, uiIndex); // Brake + ProcessControl(cs.ButtonSquare, uiIndex); // Brake uiIndex++; - ProcessControl(cs.RightStickX, uiIndex); // Special Left + ProcessControl(cs.RightStickX, uiIndex); // Special Left uiIndex++; - ProcessControl(cs.RightStickX, uiIndex); // Special Right + ProcessControl(cs.RightStickX, uiIndex); // Special Right uiIndex++; - ProcessControl(cs.RightStickY, uiIndex); // Special Up + ProcessControl(cs.RightStickY, uiIndex); // Special Up uiIndex++; - ProcessControl(cs.RightStickY, uiIndex); // Special Down + ProcessControl(cs.RightStickY, uiIndex); // Special Down } } @@ -802,7 +802,7 @@ void CClientPad::ProcessAllToggledControls(CControllerState& cs, bool bOnFoot) // Clear pad data for a disabled control. Returns true if control was actually disabled. bool CClientPad::ProcessToggledControl(const char* szName, CControllerState& cs, bool bOnFoot, bool bEnabled) { - if (bEnabled) // We don't need to disable anything if it the control is enabled. + if (bEnabled) // We don't need to disable anything if it the control is enabled. return false; unsigned int uiIndex; @@ -814,16 +814,16 @@ bool CClientPad::ProcessToggledControl(const char* szName, CControllerState& cs, { case 0: cs.LeftStickX = (cs.LeftStickX < 0) ? 0 : cs.LeftStickX; - return true; // Left + return true; // Left case 1: cs.LeftStickX = (cs.LeftStickX > 0) ? 0 : cs.LeftStickX; - return true; // Right + return true; // Right case 2: cs.LeftStickY = (cs.LeftStickY < 0) ? 0 : cs.LeftStickY; - return true; // Up + return true; // Up case 3: cs.LeftStickY = (cs.LeftStickY > 0) ? 0 : cs.LeftStickY; - return true; // Down + return true; // Down default: return false; } @@ -834,34 +834,34 @@ bool CClientPad::ProcessToggledControl(const char* szName, CControllerState& cs, { case 4: cs.LeftStickX = (cs.LeftStickX < 0) ? 0 : cs.LeftStickX; - return true; // Left + return true; // Left case 5: cs.LeftStickX = (cs.LeftStickX > 0) ? 0 : cs.LeftStickX; - return true; // Right + return true; // Right case 6: cs.LeftStickY = (cs.LeftStickY < 0) ? 0 : cs.LeftStickY; - return true; // Up + return true; // Up case 7: cs.LeftStickY = (cs.LeftStickY > 0) ? 0 : cs.LeftStickY; - return true; // Down + return true; // Down case 8: cs.ButtonCross = 0; - return true; // Accel + return true; // Accel case 9: cs.ButtonSquare = 0; - return true; // Reverse + return true; // Reverse case 10: cs.RightStickX = (cs.RightStickX < 0) ? 0 : cs.RightStickX; - return true; // Special Left + return true; // Special Left case 11: cs.RightStickX = (cs.RightStickX > 0) ? 0 : cs.RightStickX; - return true; // Special Right + return true; // Special Right case 12: cs.RightStickY = (cs.RightStickY < 0) ? 0 : cs.RightStickY; - return true; // Special Up + return true; // Special Up case 13: cs.RightStickY = (cs.RightStickY > 0) ? 0 : cs.RightStickY; - return true; // Special Down + return true; // Special Down default: return false; } diff --git a/Client/mods/deathmatch/logic/CClientPad.h b/Client/mods/deathmatch/logic/CClientPad.h index 348fe5a29be..af18331d077 100644 --- a/Client/mods/deathmatch/logic/CClientPad.h +++ b/Client/mods/deathmatch/logic/CClientPad.h @@ -10,7 +10,7 @@ #pragma once -#define MAX_GTA_CONTROLS 44 +#define MAX_GTA_CONTROLS 44 #define MAX_GTA_ANALOG_CONTROLS 14 class CClientPed; diff --git a/Client/mods/deathmatch/logic/CClientPed.cpp b/Client/mods/deathmatch/logic/CClientPed.cpp index a9ef955e6e3..058186bcc89 100644 --- a/Client/mods/deathmatch/logic/CClientPed.cpp +++ b/Client/mods/deathmatch/logic/CClientPed.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include "enums/VehicleType.h" using std::list; @@ -44,8 +45,8 @@ extern CClientGame* g_pClientGame; #define INVALID_VALUE 0xFFFFFFFF -#define PED_INTERPOLATION_WARP_THRESHOLD 5 // Minimal threshold -#define PED_INTERPOLATION_WARP_THRESHOLD_FOR_SPEED 5 // Units to increment the threshold per speed unit +#define PED_INTERPOLATION_WARP_THRESHOLD 5 // Minimal threshold +#define PED_INTERPOLATION_WARP_THRESHOLD_FOR_SPEED 5 // Units to increment the threshold per speed unit enum eAnimGroups { @@ -133,7 +134,7 @@ void CClientPed::Init(CClientManager* pManager, unsigned long ulModelID, bool bI m_armorLocked = false; m_ulLastOnScreenTime = 0; m_pLoadedModelInfo = NULL; - m_pOutOfVehicleWeaponSlot = WEAPONSLOT_MAX; // WEAPONSLOT_MAX = invalid + m_pOutOfVehicleWeaponSlot = WEAPONSLOT_MAX; // WEAPONSLOT_MAX = invalid m_bRadioOn = false; m_ucRadioChannel = 1; m_fBeginAimX = 0.0f; @@ -165,7 +166,7 @@ void CClientPed::Init(CClientManager* pManager, unsigned long ulModelID, bool bI m_fMoveSpeed = 0.0f; m_bCanBeKnockedOffBike = true; m_bBleeding = false; - RemoveAllWeapons(); // Set all our weapon values to unarmed + RemoveAllWeapons(); // Set all our weapon values to unarmed m_bHasJetPack = false; m_FightingStyle = STYLE_GRAB_KICK; m_MoveAnim = MOVE_DEFAULT; @@ -176,8 +177,8 @@ void CClientPed::Init(CClientManager* pManager, unsigned long ulModelID, bool bI m_ulLastTimeBeganAiming = 0; m_ulLastTimeEndedAiming = 0; m_ulLastTimeBeganCrouch = 0; - m_ulLastTimeBeganStand = 0; // Standing after crouching - m_ulLastTimeMovedWhileCrouched = 0; // Moved while crouching + m_ulLastTimeBeganStand = 0; // Standing after crouching + m_ulLastTimeMovedWhileCrouched = 0; // Moved while crouching m_bRecreatingModel = false; m_pCurrentContactEntity = NULL; m_bSunbathing = false; @@ -231,12 +232,17 @@ void CClientPed::Init(CClientManager* pManager, unsigned long ulModelID, bool bI m_MovementStateNames[MOVEMENTSTATE_JOG] = "jog"; m_MovementStateNames[MOVEMENTSTATE_SPRINT] = "sprint"; m_MovementStateNames[MOVEMENTSTATE_CROUCH] = "crouch"; - // These two are inactive for now m_MovementStateNames[MOVEMENTSTATE_CRAWL] = "crawl"; m_MovementStateNames[MOVEMENTSTATE_ROLL] = "roll"; m_MovementStateNames[MOVEMENTSTATE_JUMP] = "jump"; m_MovementStateNames[MOVEMENTSTATE_FALL] = "fall"; m_MovementStateNames[MOVEMENTSTATE_CLIMB] = "climb"; + m_MovementStateNames[MOVEMENTSTATE_SWIM] = "swim"; + m_MovementStateNames[MOVEMENTSTATE_WALK_TO_POINT] = "walk_to_point"; + m_MovementStateNames[MOVEMENTSTATE_ASCENT_JETPACK] = "ascent_jetpack"; + m_MovementStateNames[MOVEMENTSTATE_DESCENT_JETPACK] = "descent_jetpack"; + m_MovementStateNames[MOVEMENTSTATE_JETPACK] = "jetpack_flying"; + m_MovementStateNames[MOVEMENTSTATE_HANGING] = "hanging"; // Create the player model if (m_bIsLocalPlayer) @@ -273,7 +279,7 @@ void CClientPed::Init(CClientManager* pManager, unsigned long ulModelID, bool bI m_stats = m_remoteDataStorage->Stats(); // ### remember if you want to set Int flags, subtract STATS_OFFSET from the enum ID ### - SetStat(MAX_HEALTH, 569.0f); // Default max_health stat + SetStat(MAX_HEALTH, 569.0f); // Default max_health stat SetArmor(0.0f); } @@ -667,7 +673,7 @@ void CClientPed::SetRotationDegrees(const CVector& vecRotation) // HACK: set again the z rotation to work on ground SetCurrentRotation(vecTemp.fZ); if (!IS_PLAYER(this)) - SetCameraRotation(vecTemp.fZ); // This is incorrect and kept for backward compatibility + SetCameraRotation(vecTemp.fZ); // This is incorrect and kept for backward compatibility } void CClientPed::SetRotationRadians(const CVector& vecRotation) @@ -676,7 +682,7 @@ void CClientPed::SetRotationRadians(const CVector& vecRotation) CMatrix matTemp; GetMatrix(matTemp); g_pMultiplayer->ConvertEulerAnglesToMatrix(matTemp, vecRotation.fX, vecRotation.fY, - vecRotation.fZ); // This is incorrect and kept for backward compatibility + vecRotation.fZ); // This is incorrect and kept for backward compatibility SetMatrix(matTemp); } @@ -1503,7 +1509,7 @@ void CClientPed::WarpIntoVehicle(CClientVehicle* pVehicle, unsigned int uiSeat) else { // Passenger seat - unsigned char ucSeat = CClientVehicleManager::ConvertIndexToGameSeat(pVehicle->m_usModel, uiSeat); + unsigned char ucSeat = CClientVehicleManager::ConvertIndexToGameSeat(pVehicle->m_usModel, static_cast(uiSeat)); if (ucSeat != 0 && ucSeat != 0xFF) { if (m_pPlayerPed) @@ -1713,14 +1719,12 @@ void CClientPed::SetUsesCollision(bool bUsesCollision) float CClientPed::GetMaxHealth() { - // TODO: Verify this formula - // Grab his player health stat float fStat = GetStat(MAX_HEALTH); // Do a linear interpolation to get how much health this would allow - // Assumes: 100 health = 569 stat, 200 health = 1000 stat. - float fMaxHealth = 100.0f + (100.0f / 431.0f * (fStat - 569.0f)); + // Assumes: 100 health = 569 stat, 176 health = 1000 stat. + float fMaxHealth = fStat * 0.176f; // Return the max health. Make sure it can't be below 1 if (fMaxHealth < 1.0f) @@ -2008,14 +2012,8 @@ void CClientPed::SetFrozen(bool bFrozen) m_pTaskManager->RemoveTask(TASK_PRIORITY_PHYSICAL_RESPONSE); } - if (m_pPlayerPed) - { - m_pPlayerPed->GetMatrix(&m_matFrozen); - } - else - { - m_matFrozen = m_Matrix; - } + // Always use the client's cached matrix, it's already updated by SetCurrentRotation + m_matFrozen = m_Matrix; } } } @@ -2419,46 +2417,68 @@ eMovementState CClientPed::GetMovementState() GetControllerState(cs); // Get his current task(s) - const char* szComplexTaskName = GetTaskManager()->GetActiveTask()->GetTaskName(); - const char* szSimpleTaskName = GetTaskManager()->GetSimplestActiveTask()->GetTaskName(); + CTask* pActiveTask = GetTaskManager()->GetActiveTask(); + CTask* pSimplestTask = GetTaskManager()->GetSimplestActiveTask(); + if (!pActiveTask || !pSimplestTask) + return MOVEMENTSTATE_UNKNOWN; - // Is he climbing? - if (strcmp(szSimpleTaskName, "TASK_SIMPLE_CLIMB") == 0) - return MOVEMENTSTATE_CLIMB; + const char* szComplexTaskName = pActiveTask->GetTaskName(); + const char* szSimpleTaskName = pSimplestTask->GetTaskName(); - // Is he jumping? - else if (strcmp(szComplexTaskName, "TASK_COMPLEX_JUMP") == 0) + // Check tasks + if (strcmp(szSimpleTaskName, "TASK_SIMPLE_CLIMB") == 0) // Is he climbing? + { + CTaskSimpleClimb* climbingTask = dynamic_cast(GetTaskManager()->GetSimplestActiveTask()); + if (climbingTask && climbingTask->GetHeightForPos() == eClimbHeights::CLIMB_GRAB) + return MOVEMENTSTATE_HANGING; + + return MOVEMENTSTATE_CLIMB; + } + else if (strcmp(szComplexTaskName, "TASK_COMPLEX_JUMP") == 0) // Is he jumping? return MOVEMENTSTATE_JUMP; + else if (strcmp(szSimpleTaskName, "TASK_SIMPLE_GO_TO_POINT") == 0) // Entering vehicle (walking to the doors)? + return MOVEMENTSTATE_WALK_TO_POINT; + else if (strcmp(szSimpleTaskName, "TASK_SIMPLE_SWIM") == 0) // Is he swimming? + return MOVEMENTSTATE_SWIM; + else if (strcmp(szSimpleTaskName, "TASK_SIMPLE_JETPACK") == 0) // Is he flying? + { + if (cs.ButtonCross != 0) + return MOVEMENTSTATE_ASCENT_JETPACK; + else if (cs.ButtonSquare != 0) + return MOVEMENTSTATE_DESCENT_JETPACK; + else + return MOVEMENTSTATE_JETPACK; + } - // Is he falling? - else if (!IsOnGround() && !GetContactEntity()) + // Check movement state + if (!IsOnGround() && !GetContactEntity() && !m_pPlayerPed->IsStandingOnEntity() && !m_pPlayerPed->IsInWater() && + (strcmp(szSimpleTaskName, "TASK_SIMPLE_IN_AIR") == 0 || strcmp(szSimpleTaskName, "TASK_SIMPLE_FALL") == 0)) // Is he falling? return MOVEMENTSTATE_FALL; - // Grab his controller state - bool bWalkKey = false; - if (GetType() == CCLIENTPLAYER) - bWalkKey = CClientPad::GetControlState("walk", cs, true); - else - m_Pad.GetControlState("walk", bWalkKey); + // Sometimes it returns 'fall' or 'walk', so it's better to return false instead + if (IsEnteringVehicle() || IsLeavingVehicle()) + return MOVEMENTSTATE_UNKNOWN; - // Is he standing up? if (!IsDucked()) { - unsigned int iRunState = m_pPlayerPed->GetRunState(); + bool walking = false; + if (GetType() == CCLIENTPLAYER) + walking = CClientPad::GetControlState("walk", cs, true); + else + m_Pad.GetControlState("walk", walking); - // Is he moving the contoller at all? - if (iRunState == 1 && cs.LeftStickX == 0 && cs.LeftStickY == 0) - return MOVEMENTSTATE_STAND; - - // Is he either pressing the walk key, or has run state 1? - if (iRunState == 1 || bWalkKey && iRunState == 6) - return MOVEMENTSTATE_WALK; - else if (iRunState == 4) - return MOVEMENTSTATE_POWERWALK; - else if (iRunState == 6) - return MOVEMENTSTATE_JOG; - else if (iRunState == 7) - return MOVEMENTSTATE_SPRINT; + switch (m_pPlayerPed->GetMoveState()) + { + case PedMoveState::PEDMOVE_STILL: + return MOVEMENTSTATE_STAND; + case PedMoveState::PEDMOVE_WALK: + return (cs.LeftStickX == 0 && cs.LeftStickY == 0) ? MOVEMENTSTATE_STAND : MOVEMENTSTATE_WALK; + case PedMoveState::PEDMOVE_SPRINT: + return MOVEMENTSTATE_SPRINT; + case PedMoveState::PEDMOVE_RUN: + return walking ? MOVEMENTSTATE_WALK : MOVEMENTSTATE_JOG; // FileEX: It should be MOVEMENTSTATE_RUN, but we're keeping JOG for backward + // compatibility (PEDMOVE_JOG is unused in SA) + } } else { @@ -2466,9 +2486,10 @@ eMovementState CClientPed::GetMovementState() if (cs.LeftStickX == 0 && cs.LeftStickY == 0) return MOVEMENTSTATE_CROUCH; else - return MOVEMENTSTATE_CRAWL; + return (cs.LeftStickX != 0 && cs.RightShoulder1 != 0) ? MOVEMENTSTATE_ROLL : MOVEMENTSTATE_CRAWL; } } + return MOVEMENTSTATE_UNKNOWN; } @@ -2895,6 +2916,11 @@ void CClientPed::StreamedInPulse(bool bDoStandardPulses) } } + // Are we need to update anim speed & progress? + // We need to do it here because the anim starts on the next frame after calling RunNamedAnimation + if (m_pAnimationBlock && m_AnimationCache.progressWaitForStreamIn && IsAnimationInProgress()) + UpdateAnimationProgressAndSpeed(); + // Update our alpha unsigned char ucAlpha = m_ucAlpha; // Are we in a different interior to the camera? set our alpha to 0 @@ -3107,7 +3133,7 @@ void CClientPed::ApplyControllerStateFixes(CControllerState& Current) { // Disable double crouching (another anim cut) if (g_pClientGame->IsUsingAlternatePulseOrder()) - Current.ShockButtonL = 255; // Do this differently if we have changed the pulse order + Current.ShockButtonL = 255; // Do this differently if we have changed the pulse order else Current.ShockButtonL = 0; } @@ -3219,7 +3245,7 @@ void CClientPed::ApplyControllerStateFixes(CControllerState& Current) CTask* pTask = m_pTaskManager->GetSimplestActiveTask(); if ((pTask && pTask->GetTaskType() == TASK_SIMPLE_PLAYER_ON_FOOT) && (GetWeapon()->GetSlot() == WEAPONSLOT_TYPE_UNARMED) && (Current.RightShoulder1 != 0) && (Current.ButtonSquare != 0) && (Current.ButtonCross != 0)) - { // We are block jogging + { // We are block jogging if (Current.LeftStickY > 0) // We're pressing target+jump+sprint+backwards. Using the backwards key in this situation is prone to bugs, swap it with forwards Current.LeftStickY = -Current.LeftStickY; @@ -3302,6 +3328,12 @@ void CClientPed::ApplyControllerStateFixes(CControllerState& Current) float CClientPed::GetCurrentRotation() { + if (IsFrozen()) + { + CVector vecRotation = m_matFrozen.GetRotation(); + return vecRotation.fZ; + } + if (m_pPlayerPed) { return m_pPlayerPed->GetCurrentRotation(); @@ -3328,6 +3360,11 @@ void CClientPed::SetCurrentRotation(float fRotation, bool bIncludeTarget) if (bIncludeTarget) m_fTargetRotation = fRotation; } + + // Always update m_Matrix rotation so m_matFrozen gets correct value in SetFrozen + CVector vecRotation = m_Matrix.GetRotation(); + vecRotation.fZ = fRotation; + m_Matrix.SetRotation(vecRotation); } void CClientPed::SetTargetRotation(float fRotation) @@ -3685,8 +3722,8 @@ void CClientPed::_CreateModel() Kill(WEAPONTYPE_UNARMED, 0, false, true); } - // Are we still playing animation? - if ((m_AnimationCache.bLoop || m_AnimationCache.bFreezeLastFrame || m_AnimationCache.progressWaitForStreamIn) && m_pAnimationBlock) + // Are we still playing a animation? + if (m_pAnimationBlock && IsAnimationInProgress()) { if (m_bisCurrentAnimationCustom) { @@ -3963,8 +4000,8 @@ void CClientPed::_ChangeModel() } m_bDontChangeRadio = false; - // Are we still playing a looped animation? - if ((m_AnimationCache.bLoop || m_AnimationCache.bFreezeLastFrame || m_AnimationCache.progressWaitForStreamIn) && m_pAnimationBlock) + // Are we still playing a animation? + if (m_pAnimationBlock && IsAnimationInProgress()) { if (m_bisCurrentAnimationCustom) { @@ -4467,7 +4504,8 @@ void CClientPed::_GetIntoVehicle(CClientVehicle* pVehicle, unsigned int uiSeat, pTask = m_pTaskManager->GetTask(TASK_PRIORITY_EVENT_RESPONSE_NONTEMP); auto usVehicleModel = static_cast(pVehicle->GetModel()); if (((pTask && pTask->GetTaskType() == TASK_COMPLEX_IN_WATER) || pVehicle->IsOnWater()) && - (usVehicleModel == VehicleType::VT_SKIMMER || usVehicleModel == VehicleType::VT_SEASPAR || usVehicleModel == VehicleType::VT_LEVIATHN || usVehicleModel == VehicleType::VT_VORTEX)) + (usVehicleModel == VehicleType::VT_SKIMMER || usVehicleModel == VehicleType::VT_SEASPAR || usVehicleModel == VehicleType::VT_LEVIATHN || + usVehicleModel == VehicleType::VT_VORTEX)) { CVector vecDoorPos; unsigned int uiDoor; @@ -4514,7 +4552,7 @@ void CClientPed::_GetIntoVehicle(CClientVehicle* pVehicle, unsigned int uiSeat, } } - unsigned char ucSeat = CClientVehicleManager::ConvertIndexToGameSeat(pVehicle->m_usModel, uiSeat); + unsigned char ucSeat = CClientVehicleManager::ConvertIndexToGameSeat(pVehicle->m_usModel, static_cast(uiSeat)); if (ucSeat != 0 && ucSeat != 0xFF) { if (m_pPlayerPed) @@ -4649,12 +4687,20 @@ float CClientPed::GetDistanceFromGround() return (vecPosition.fZ - fGroundLevel); } -bool CClientPed::IsOnGround() +bool CClientPed::IsOnGround(bool checkVehicles) { CVector vecPosition; GetPosition(vecPosition); float fGroundLevel = static_cast(g_pGame->GetWorld()->FindGroundZFor3DPosition(&vecPosition)); - return (vecPosition.fZ > fGroundLevel && (vecPosition.fZ - fGroundLevel) <= 1.0f); + + if (DefinitelyLessThan(vecPosition.fZ, fGroundLevel)) + return false; + + bool isOnGround = DefinitelyLessThan((vecPosition.fZ - fGroundLevel), 1.0f, 1e-4f) || EssentiallyEqual((vecPosition.fZ - fGroundLevel), 1.0f, 1e-4f); + if (!isOnGround && checkVehicles && m_pPlayerPed) + return m_pPlayerPed->IsStandingOnEntity(); + + return isOnGround; } bool CClientPed::IsClimbing() @@ -4737,7 +4783,7 @@ bool CClientPed::GetShotData(CVector* pvecOrigin, CVector* pvecTarget, CVector* float fRotation = GetCurrentRotation(); // Grab the target range of the current weapon - float fSkill = 1000.0f; // GetStat ( g_pGame->GetStats ( )->GetSkillStatIndex ( pWeapon->GetType ( ) ) ); + float fSkill = 1000.0f; // GetStat ( g_pGame->GetStats ( )->GetSkillStatIndex ( pWeapon->GetType ( ) ) ); CWeaponStat* pCurrentWeaponInfo = g_pGame->GetWeaponStatManager()->GetWeaponStatsFromSkillLevel(pWeapon->GetType(), fSkill); float fRange = pCurrentWeaponInfo->GetWeaponRange(); @@ -4771,19 +4817,19 @@ bool CClientPed::GetShotData(CVector* pvecOrigin, CVector* pvecTarget, CVector* // Always use the gun muzzle as origin vecOrigin = vecGunMuzzle; - if (false && HasAkimboPointingUpwards()) // Upwards pointing akimbo's + if (false && HasAkimboPointingUpwards()) // Upwards pointing akimbo's { // Disabled temporarily until we actually get working akimbos vecTarget = vecOrigin; vecTarget.fZ += fRange; } - else if (Controller.RightShoulder1 == 255) // First-person weapons, crosshair active: sync the crosshair + else if (Controller.RightShoulder1 == 255) // First-person weapons, crosshair active: sync the crosshair { g_pGame->GetCamera()->Find3rdPersonCamTargetVector(fRange, &vecGunMuzzle, &vecOrigin, &vecTarget); // Apply shoot through walls fix vecOrigin = AdjustShotOriginForWalls(vecOrigin, vecTarget, 0.5f); } - else if (pVehicle) // Drive-by/vehicle weapons: camera origin as origin, performing collision tests + else if (pVehicle) // Drive-by/vehicle weapons: camera origin as origin, performing collision tests { CColPoint* pCollision; CMatrix mat; @@ -4818,7 +4864,7 @@ bool CClientPed::GetShotData(CVector* pvecOrigin, CVector* pvecTarget, CVector* } } } - else // Always use only the last reported shot data for remote players? + else // Always use only the last reported shot data for remote players? { vecOrigin = m_shotSyncData->m_vecShotOrigin; vecTarget = m_shotSyncData->m_vecShotTarget; @@ -4970,10 +5016,7 @@ void CClientPed::DestroySatchelCharges(bool bBlow, bool bDestroy) bool bCancelExplosion = !CallEvent("onClientExplosion", Arguments, true); if (!bCancelExplosion) - { m_pManager->GetExplosionManager()->Create(EXP_TYPE_GRENADE, vecPosition, this, true, -1.0f, false, WEAPONTYPE_REMOTE_SATCHEL_CHARGE); - g_pClientGame->SendExplosionSync(vecPosition, EXP_TYPE_GRENADE, this); - } } if (bDestroy) { @@ -5033,7 +5076,7 @@ bool CClientPed::IsLeavingVehicle() { switch (pTask->GetTaskType()) { - case TASK_COMPLEX_LEAVE_CAR: // We only use this task + case TASK_COMPLEX_LEAVE_CAR: // We only use this task case TASK_COMPLEX_LEAVE_CAR_AND_DIE: case TASK_COMPLEX_LEAVE_CAR_AND_FLEE: case TASK_COMPLEX_LEAVE_CAR_AND_WANDER: @@ -5731,7 +5774,23 @@ bool CClientPed::IsRunningAnimation() } return false; } - return (m_AnimationCache.bLoop && m_pAnimationBlock); + return (m_AnimationCache.bLoop || m_AnimationCache.bFreezeLastFrame) && m_pAnimationBlock; +} + +bool CClientPed::IsAnimationInProgress() +{ + bool constAnim = m_AnimationCache.bLoop || m_AnimationCache.bFreezeLastFrame; + + if (!m_pAnimationBlock) + return constAnim; + + float elapsedTime = static_cast(GetTimestamp() - m_AnimationCache.startTime) / 1000.0f; + + auto animBlendHierarchy = g_pGame->GetAnimManager()->GetAnimation(m_AnimationCache.strName.c_str(), m_pAnimationBlock); + if (!animBlendHierarchy) + return constAnim; + + return constAnim || elapsedTime < animBlendHierarchy->GetTotalTime(); } void CClientPed::RunNamedAnimation(std::unique_ptr& pBlock, const char* szAnimName, int iTime, int iBlend, bool bLoop, bool bUpdatePosition, @@ -5767,9 +5826,9 @@ void CClientPed::RunNamedAnimation(std::unique_ptr& pBlock, const ch Saml1er: Setting flags to 0x10 will tell GTA:SA that animation needs to be decompressed. If not, animation will either crash or do some weird things. */ - int flags = 0x10; // Stops jaw fucking up, some speaking flag maybe + int flags = 0x10; // Stops jaw fucking up, some speaking flag maybe if (bLoop) - flags |= 0x2; // flag that triggers the loop (Maccer) + flags |= 0x2; // flag that triggers the loop (Maccer) if (bUpdatePosition) { // 0x40 enables position updating on Y-coord, 0x80 on X. (Maccer) @@ -5786,7 +5845,7 @@ void CClientPed::RunNamedAnimation(std::unique_ptr& pBlock, const ch } if (!bFreezeLastFrame) - flags |= 0x08; // flag determines whether to freeze player when anim ends. Really annoying (Maccer) + flags |= 0x08; // flag determines whether to freeze player when anim ends. Really annoying (Maccer) float fBlendDelta = 1 / std::max((float)iBlend, 1.0f) * 1000; CTask* pTask = g_pGame->GetTasks()->CreateTaskSimpleRunNamedAnim(szAnimName, pBlock->GetName(), flags, fBlendDelta, iTime, !bInterruptable, bRunInSequence, bOffsetPed, bHoldLastFrame); @@ -5819,10 +5878,6 @@ void CClientPed::RunNamedAnimation(std::unique_ptr& pBlock, const ch m_AnimationCache.bUpdatePosition = bUpdatePosition; m_AnimationCache.bInterruptable = bInterruptable; m_AnimationCache.bFreezeLastFrame = bFreezeLastFrame; - m_AnimationCache.progress = 0.0f; - m_AnimationCache.speed = 1.0f; - m_AnimationCache.progressWaitForStreamIn = false; - m_AnimationCache.elapsedTime = 0.0f; } void CClientPed::KillAnimation() @@ -5861,39 +5916,46 @@ void CClientPed::RunAnimationFromCache() if (!m_pAnimationBlock) return; - bool needCalcProgress = m_AnimationCache.progressWaitForStreamIn; - float elapsedTime = m_AnimationCache.elapsedTime; - // Copy our name incase it gets deleted std::string animName = m_AnimationCache.strName; // Run our animation - RunNamedAnimation(m_pAnimationBlock, animName.c_str(), m_AnimationCache.iTime, m_AnimationCache.iBlend, m_AnimationCache.bLoop, m_AnimationCache.bUpdatePosition, m_AnimationCache.bInterruptable, m_AnimationCache.bFreezeLastFrame); + RunNamedAnimation(m_pAnimationBlock, animName.c_str(), m_AnimationCache.iTime, m_AnimationCache.iBlend, m_AnimationCache.bLoop, + m_AnimationCache.bUpdatePosition, m_AnimationCache.bInterruptable, m_AnimationCache.bFreezeLastFrame); + + // Set anim progress & speed + m_AnimationCache.progressWaitForStreamIn = true; +} - auto animAssoc = g_pGame->GetAnimManager()->RpAnimBlendClumpGetAssociation(GetClump(), animName.c_str()); +void CClientPed::UpdateAnimationProgressAndSpeed() +{ + if (!m_AnimationCache.progressWaitForStreamIn) + return; + + // Get current anim + auto animAssoc = g_pGame->GetAnimManager()->RpAnimBlendClumpGetAssociation(GetClump(), m_AnimationCache.strName.c_str()); if (!animAssoc) return; - // If the anim is synced from the server side, we need to calculate the progress - float progress = m_AnimationCache.progress; - if (needCalcProgress) - { - float animLength = animAssoc->GetLength(); + float animLength = animAssoc->GetLength(); + float progress = 0.0f; + float elapsedTime = static_cast(GetTimestamp() - m_AnimationCache.startTime) / 1000.0f; - if (m_AnimationCache.bFreezeLastFrame) // time and loop is ignored if freezeLastFrame is true - progress = (elapsedTime / animLength) * m_AnimationCache.speed; + if (m_AnimationCache.bFreezeLastFrame) // time and loop is ignored if freezeLastFrame is true + progress = (elapsedTime / animLength) * m_AnimationCache.speed; + else + { + if (m_AnimationCache.bLoop) + progress = std::fmod(elapsedTime * m_AnimationCache.speed, animLength) / animLength; else - { - if (m_AnimationCache.bLoop) - progress = std::fmod(elapsedTime * m_AnimationCache.speed, animLength) / animLength; - else - // For non-looped animations, limit duration to animLength if time exceeds it - progress = (elapsedTime / (m_AnimationCache.iTime <= animLength ? m_AnimationCache.iTime : animLength)) * m_AnimationCache.speed; - } + // For non-looped animations, limit duration to animLength if time exceeds it + progress = (elapsedTime / (m_AnimationCache.iTime <= animLength ? m_AnimationCache.iTime : animLength)) * m_AnimationCache.speed; } animAssoc->SetCurrentProgress(std::clamp(progress, 0.0f, 1.0f)); animAssoc->SetCurrentSpeed(m_AnimationCache.speed); + + m_AnimationCache.progressWaitForStreamIn = false; } void CClientPed::PostWeaponFire() @@ -6072,6 +6134,21 @@ bool CClientPed::ReloadWeapon() noexcept if (!CanReloadWeapon() || (task && task->GetTaskType() == TASK_SIMPLE_USE_GUN)) return false; + CLuaArguments args; + args.PushNumber(weapon->GetType()); + args.PushNumber(weapon->GetAmmoInClip()); + args.PushNumber(weapon->GetAmmoTotal()); + + bool result = false; + + if (IS_PLAYER(this)) + result = CallEvent("onClientPlayerWeaponReload", args, true); + else + result = CallEvent("onClientPedWeaponReload", args, true); + + if (!result) + return false; + weapon->SetState(WEAPONSTATE_RELOADING); return true; } @@ -6098,7 +6175,8 @@ bool CClientPed::ShouldBeStealthAiming() { // We need to be either crouched, walking or standing SBindableGTAControl* pWalkControl = pKeyBinds->GetBindableFromControl("walk"); - if (m_pPlayerPed->GetRunState() == 1 || m_pPlayerPed->GetRunState() == 4 || pWalkControl && pWalkControl->bState) + if (m_pPlayerPed->GetMoveState() == PedMoveState::PEDMOVE_STILL || m_pPlayerPed->GetMoveState() == PedMoveState::PEDMOVE_WALK || + pWalkControl && pWalkControl->bState) { // Do we have a target ped? CClientPed* pTargetPed = GetTargetedPed(); @@ -6462,46 +6540,27 @@ void CClientPed::UpdateStreamPosition(const CVector& vecInPosition) // Asks server for permission to start entering vehicle // ////////////////////////////////////////////////////////////////// -bool CClientPed::EnterVehicle(CClientVehicle* pVehicle, bool bPassenger) +bool CClientPed::EnterVehicle(CClientVehicle* pVehicle, bool bPassenger, std::optional optSeat) { // Are we local player or ped we are syncing if (!IsSyncing() && !IsLocalPlayer() && !IsLocalEntity()) - { - return false; - } - - // Are we a clientside ped - // TODO: Add support for clientside peds - if (IsLocalEntity()) - { - return false; - } - - // Check the server is compatible if we are a ped - if (!IsLocalPlayer() && !g_pNet->CanServerBitStream(eBitStreamVersion::PedEnterExit)) - { return false; - } // Are we already inside a vehicle if (GetOccupiedVehicle()) - { return false; - } // We dead or in water? if (IsDead()) - { return false; - } // Are we already sending an in/out request or not allowed to create a new in/out? - if (m_bNoNewVehicleTask // Are we permitted to even enter a vehicle? - || m_VehicleInOutID != INVALID_ELEMENT_ID // Make sure we're not already processing a vehicle enter (would refer to valid ID if we were) - || m_bIsGettingJacked // Make sure we're not currently getting carjacked && - || m_bIsGettingIntoVehicle // We can't enter a vehicle we're currently entering... - || m_bIsGettingOutOfVehicle // We can't enter a vehicle we're currently leaving... - || CClientTime::GetTime() < m_ulLastVehicleInOutTime + VEHICLE_INOUT_DELAY // We are trying to enter the vehicle to soon + if (m_bNoNewVehicleTask // Are we permitted to even enter a vehicle? + || m_VehicleInOutID != INVALID_ELEMENT_ID // Make sure we're not already processing a vehicle enter (would refer to valid ID if we were) + || m_bIsGettingJacked // Make sure we're not currently getting carjacked && + || m_bIsGettingIntoVehicle // We can't enter a vehicle we're currently entering... + || m_bIsGettingOutOfVehicle // We can't enter a vehicle we're currently leaving... + || CClientTime::GetTime() < m_ulLastVehicleInOutTime + VEHICLE_INOUT_DELAY // We are trying to enter the vehicle to soon ) { return false; @@ -6512,9 +6571,7 @@ bool CClientPed::EnterVehicle(CClientVehicle* pVehicle, bool bPassenger) // Streamed? if (!m_pPlayerPed) - { return false; - } unsigned int uiDoor = 0; // Do we want to enter a specific vehicle? @@ -6539,64 +6596,67 @@ bool CClientPed::EnterVehicle(CClientVehicle* pVehicle, bool bPassenger) // Dead vehicle? if (pVehicle->GetHealth() <= 0.0f) - { return false; - } + // Stop if the vehicle is not enterable if (!pVehicle->IsEnterable(IsLocalEntity())) - { - // Stop if the vehicle is not enterable return false; - } // Stop if the ped is swimming and the vehicle model cannot be entered from water (fixes #1990) auto vehicleModel = static_cast(pVehicle->GetModel()); - if (IsInWater() && !(vehicleModel == VehicleType::VT_SKIMMER || vehicleModel == VehicleType::VT_SEASPAR || vehicleModel == VehicleType::VT_LEVIATHN || vehicleModel == VehicleType::VT_VORTEX)) - { + if (IsInWater() && !(vehicleModel == VehicleType::VT_SKIMMER || vehicleModel == VehicleType::VT_SEASPAR || vehicleModel == VehicleType::VT_LEVIATHN || + vehicleModel == VehicleType::VT_VORTEX)) return false; - } // If the Jump task is playing and we are in water - I know right // Kill the task. CTask* pTask = GetCurrentPrimaryTask(); - if (pTask && pTask->GetTaskType() == TASK_COMPLEX_JUMP) // Kill jump task - breaks warp in entry and doesn't really matter + if (pTask && pTask->GetTaskType() == TASK_COMPLEX_JUMP) // Kill jump task - breaks warp in entry and doesn't really matter { - if (pVehicle->IsInWater() || - IsInWater()) // Make sure we are about to warp in (this bug only happens when someone jumps into water with a vehicle) - { - KillTask(3, true); // Kill jump task if we are about to warp in - } + if (pVehicle->IsInWater() || IsInWater()) // Make sure we are about to warp in (this bug only happens when someone jumps into water with a vehicle) + KillTask(3, true); // Kill jump task if we are about to warp in } // Make sure we don't have any other primary tasks running, otherwise our 'enter-vehicle' // task will replace it and fuck it up! if (GetCurrentPrimaryTask()) - { - // We already have a primary task, so stop. return false; - } - if (IsClimbing() // Make sure we're not currently climbing - || HasJetPack() // Make sure we don't have a jetpack - || IsUsingGun() // Make sure we're not using a gun (have the gun task active) - we stop it in UpdatePlayerTasks anyway - || IsRunningAnimation() // Make sure we aren't running an animation + if (IsClimbing() // Make sure we're not currently climbing + || HasJetPack() // Make sure we don't have a jetpack + || IsUsingGun() // Make sure we're not using a gun (have the gun task active) - we stop it in UpdatePlayerTasks anyway + || IsRunningAnimation() // Make sure we aren't running an animation ) { return false; } - unsigned int uiSeat = uiDoor; - if (bPassenger && uiDoor == 0) + // Determine seat - either explicitly specified or auto-determined from door/passenger flag + unsigned int uiSeat; + + if (optSeat.has_value()) { - // We're trying to enter as a passenger, yet our closest door - // is the driver's door. Force an enter for the passenger seat. - uiSeat = 1; + // Explicit seat specified + uiSeat = optSeat.value(); + if (!CClientVehicleManager::IsValidSeat(pVehicle->GetModel(), static_cast(uiSeat))) + return false; } - else if (!bPassenger) + else { - // We want to drive. Force our seat to the driver's seat. - uiSeat = 0; + // Legacy behavior - auto-determine seat from door/passenger flag + uiSeat = uiDoor; + if (bPassenger && uiDoor == 0) + { + // We're trying to enter as a passenger, yet our closest door + // is the driver's door. Force an enter for the passenger seat. + uiSeat = 1; + } + else if (!bPassenger) + { + // We want to drive. Force our seat to the driver's seat. + uiSeat = 0; + } } // If the vehicle's a boat, make sure we're standing on it (we need a dif task to enter boats properly) @@ -6605,12 +6665,16 @@ bool CClientPed::EnterVehicle(CClientVehicle* pVehicle, bool bPassenger) return false; } + // Validate camper seat to avoid multiple occupants && desyncronization + if (vehicleModel == VehicleType::VT_CAMPER && uiSeat > 0 && pVehicle->GetOccupant(uiSeat)) + return false; + // Call the onClientVehicleStartEnter event for the ped // Check if it is cancelled before sending packet CLuaArguments Arguments; - Arguments.PushElement(this); // player / ped - Arguments.PushNumber(uiSeat); // seat - Arguments.PushNumber(uiDoor); // door + Arguments.PushElement(this); // player / ped + Arguments.PushNumber(uiSeat); // seat + Arguments.PushNumber(uiDoor); // door if (!pVehicle->CallEvent("onClientVehicleStartEnter", Arguments, true)) { @@ -6626,11 +6690,11 @@ bool CClientPed::EnterVehicle(CClientVehicle* pVehicle, bool bPassenger) // Set the vehicle id we're about to enter m_VehicleInOutID = pVehicle->GetID(); - m_ucVehicleInOutSeat = uiSeat; + m_ucVehicleInOutSeat = static_cast(uiSeat); m_bIsJackingVehicle = false; // Make ped enter vehicle - GetIntoVehicle(pVehicle, uiSeat, uiDoor); + GetIntoVehicle(pVehicle, uiSeat, static_cast(uiDoor)); // Remember that this ped is working on entering a vehicle SetVehicleInOutState(VEHICLE_INOUT_GETTING_IN); @@ -6651,11 +6715,7 @@ bool CClientPed::EnterVehicle(CClientVehicle* pVehicle, bool bPassenger) return false; } - // Write the ped ID to it if server supports it - if (g_pNet->CanServerBitStream(eBitStreamVersion::PedEnterExit)) - { - pBitStream->Write(GetID()); - } + pBitStream->Write(GetID()); // Write the vehicle id to it and that we're requesting to get into it pBitStream->Write(pVehicle->GetID()); @@ -6698,13 +6758,6 @@ bool CClientPed::ExitVehicle() return false; } - // Are we a clientside ped - // TODO: Add support for clientside peds - if (IsLocalEntity()) - { - return false; - } - // Get our occupied vehicle CClientVehicle* pOccupiedVehicle = GetOccupiedVehicle(); if (!pOccupiedVehicle) @@ -6718,19 +6771,13 @@ bool CClientPed::ExitVehicle() return false; } - // Check the server is compatible if we are a ped - if (!IsLocalPlayer() && !g_pNet->CanServerBitStream(eBitStreamVersion::PedEnterExit)) - { - return false; - } - // Are we already sending an in/out request or not allowed to create a new in/out? - if (m_bNoNewVehicleTask // Are we permitted to even enter a vehicle? - || m_VehicleInOutID != INVALID_ELEMENT_ID // Make sure we're not already processing a vehicle enter (would refer to valid ID if we were) - || m_bIsGettingJacked // Make sure we're not currently getting carjacked && - || m_bIsGettingIntoVehicle // We can't enter a vehicle we're currently entering... - || m_bIsGettingOutOfVehicle // We can't enter a vehicle we're currently leaving... - || CClientTime::GetTime() < m_ulLastVehicleInOutTime + VEHICLE_INOUT_DELAY // We are trying to enter the vehicle to soon + if (m_bNoNewVehicleTask // Are we permitted to even enter a vehicle? + || m_VehicleInOutID != INVALID_ELEMENT_ID // Make sure we're not already processing a vehicle enter (would refer to valid ID if we were) + || m_bIsGettingJacked // Make sure we're not currently getting carjacked && + || m_bIsGettingIntoVehicle // We can't enter a vehicle we're currently entering... + || m_bIsGettingOutOfVehicle // We can't enter a vehicle we're currently leaving... + || CClientTime::GetTime() < m_ulLastVehicleInOutTime + VEHICLE_INOUT_DELAY // We are trying to enter the vehicle to soon ) { return false; @@ -6745,27 +6792,28 @@ bool CClientPed::ExitVehicle() return false; } - std::int8_t targetDoor = g_pGame->GetCarEnterExit()->ComputeTargetDoorToExit(m_pPlayerPed, pOccupiedVehicle->GetGameVehicle()); + const int rawDoor = g_pGame->GetCarEnterExit()->ComputeTargetDoorToExit(m_pPlayerPed, pOccupiedVehicle->GetGameVehicle()); + auto targetDoor = static_cast(rawDoor); // If it's a local entity, we can just exit the vehicle if (IsLocalEntity()) { // Set the vehicle id and the seat we're about to exit from m_VehicleInOutID = pOccupiedVehicle->GetID(); - m_ucVehicleInOutSeat = GetOccupiedVehicleSeat(); + m_ucVehicleInOutSeat = static_cast(GetOccupiedVehicleSeat()); // Call the onClientVehicleStartExit event for the ped // Check if it is cancelled before making the ped exit the vehicle CLuaArguments arguments; - arguments.PushElement(this); // player / ped - arguments.PushNumber(m_ucVehicleInOutSeat); // seat - arguments.PushNumber(0); // door + arguments.PushElement(this); // player / ped + arguments.PushNumber(m_ucVehicleInOutSeat); // seat + arguments.PushNumber(0); // door - if (!pOccupiedVehicle->CallEvent("onClientVehicleStartExit", arguments, true)) // Event has been cancelled + if (!pOccupiedVehicle->CallEvent("onClientVehicleStartExit", arguments, true)) // Event has been cancelled return false; // Make ped exit vehicle - GetOutOfVehicle(targetDoor); + GetOutOfVehicle(m_ucVehicleInOutSeat); // Remember that this ped is working on leaving a vehicle SetVehicleInOutState(VEHICLE_INOUT_GETTING_OUT); @@ -6784,11 +6832,7 @@ bool CClientPed::ExitVehicle() return false; } - // Write the ped ID to it if server supports it - if (g_pNet->CanServerBitStream(eBitStreamVersion::PedEnterExit)) - { - pBitStream->Write(GetID()); - } + pBitStream->Write(GetID()); // Write the vehicle id to it and that we're requesting to get out of it pBitStream->Write(pOccupiedVehicle->GetID()); @@ -6852,8 +6896,8 @@ void CClientPed::UpdateVehicleInOut() // Call the onClientVehicleEnter event for the ped // Check if it is cancelled before allowing the ped to enter the vehicle CLuaArguments arguments; - arguments.PushElement(this); // player / ped - arguments.PushNumber(m_ucVehicleInOutSeat); // seat + arguments.PushElement(this); // player / ped + arguments.PushNumber(m_ucVehicleInOutSeat); // seat if (!vehicle->CallEvent("onClientVehicleEnter", arguments, true)) { @@ -6878,12 +6922,13 @@ void CClientPed::UpdateVehicleInOut() // Call the onClientVehicleExit event for the ped CLuaArguments arguments; - arguments.PushElement(this); // player / ped - arguments.PushNumber(m_ucVehicleInOutSeat); // seat + arguments.PushElement(this); // player / ped + arguments.PushNumber(m_ucVehicleInOutSeat); // seat networkVehicle->CallEvent("onClientVehicleExit", arguments, true); m_bIsGettingOutOfVehicle = false; m_VehicleInOutID = INVALID_ELEMENT_ID; + RemoveFromVehicle(); SetVehicleInOutState(VEHICLE_INOUT_NONE); } @@ -6916,10 +6961,7 @@ void CClientPed::UpdateVehicleInOut() if (pBitStream) { // Write the ped ID to it - if (g_pNet->CanServerBitStream(eBitStreamVersion::PedEnterExit)) - { - pBitStream->Write(GetID()); - } + pBitStream->Write(GetID()); // Write the car id and the action id (enter complete) pBitStream->Write(m_VehicleInOutID); @@ -6969,10 +7011,7 @@ void CClientPed::UpdateVehicleInOut() if (pBitStream) { // Write the ped or player ID to it - if (g_pNet->CanServerBitStream(eBitStreamVersion::PedEnterExit)) - { - pBitStream->Write(GetID()); - } + pBitStream->Write(GetID()); // Write the car id and the action id (enter complete) pBitStream->Write(m_VehicleInOutID); @@ -7016,10 +7055,7 @@ void CClientPed::UpdateVehicleInOut() if (pBitStream) { // Write the ped or player ID to it - if (g_pNet->CanServerBitStream(eBitStreamVersion::PedEnterExit)) - { - pBitStream->Write(GetID()); - } + pBitStream->Write(GetID()); // Write the car id and the action id (enter complete) pBitStream->Write(m_VehicleInOutID); @@ -7131,10 +7167,7 @@ void CClientPed::UpdateVehicleInOut() return; // Write the ped or player ID to it - if (g_pNet->CanServerBitStream(eBitStreamVersion::PedEnterExit)) - { - pBitStream->Write(GetID()); - } + pBitStream->Write(GetID()); // Vehicle id pBitStream->Write(pOccupiedVehicle->GetID()); @@ -7186,3 +7219,65 @@ void CClientPed::SetSyncing(bool bIsSyncing) ResetVehicleInOut(); } } + +void CClientPed::RunClimbingTask() +{ + if (!m_pPlayerPed) + return; + + CVector climbPos; + float climbAngle; + int surfaceType; + + CEntitySAInterface* climbEntity = CTaskSimpleClimb::TestForClimb(m_pPlayerPed, climbPos, climbAngle, surfaceType, true); + + // If a ped is in the air, its rotation is inverted (see GetRotationDegressNew, GetRotationRadiansNew) + if (!IsOnGround() && !climbEntity) + { + CVector rot; + GetRotationDegrees(rot); + + rot.fZ += 180.0f; + SetRotationDegrees(rot); + + climbEntity = CTaskSimpleClimb::TestForClimb(m_pPlayerPed, climbPos, climbAngle, surfaceType, true); + } + + if (!climbEntity) + return; + + CTaskSimpleClimb* climbTask = g_pGame->GetTasks()->CreateTaskSimpleClimb(climbEntity, climbPos, climbAngle, static_cast(surfaceType), + eClimbHeights::CLIMB_GRAB, false); + if (!climbTask) + return; + + climbTask->SetAsPedTask(m_pPlayerPed, TASK_PRIORITY_PRIMARY, true); +} + +CTaskSimpleSwim* CClientPed::GetSwimmingTask() const +{ + if (!m_pPlayerPed) + return nullptr; + + CTask* simplestTask = const_cast(GetTaskManager())->GetSimplestActiveTask(); + if (!simplestTask || simplestTask->GetTaskType() != TASK_SIMPLE_SWIM) + return nullptr; + + auto* swimmingTask = dynamic_cast(simplestTask); + return swimmingTask; +} + +void CClientPed::RunSwimTask() const +{ + if (!m_pPlayerPed || GetSwimmingTask()) + return; + + CTaskComplexInWater* inWaterTask = g_pGame->GetTasks()->CreateTaskComplexInWater(); + if (!inWaterTask) + return; + + // Set physical flags (bTouchingWater, bSubmergedInWater) + m_pPlayerPed->SetInWaterFlags(true); + + inWaterTask->SetAsPedTask(m_pPlayerPed, TASK_PRIORITY_EVENT_RESPONSE_NONTEMP, true); +} diff --git a/Client/mods/deathmatch/logic/CClientPed.h b/Client/mods/deathmatch/logic/CClientPed.h index 6f2ba652fb4..8bab35d9849 100644 --- a/Client/mods/deathmatch/logic/CClientPed.h +++ b/Client/mods/deathmatch/logic/CClientPed.h @@ -35,6 +35,7 @@ class CClientPlayerClothes; class CClientProjectile; class CClientVehicle; class CTask; +class CTaskSimpleSwim; enum eDelayedSyncData { @@ -61,22 +62,29 @@ enum eBodyPart BODYPART_LEFT_LEG = 7, BODYPART_RIGHT_LEG = 8, BODYPART_HEAD = 9, + BODYPART_INVALID = 255, }; enum eMovementState { MOVEMENTSTATE_UNKNOWN, - MOVEMENTSTATE_STAND, // Standing still - MOVEMENTSTATE_WALK, // Walking - MOVEMENTSTATE_POWERWALK, // Walking quickly - MOVEMENTSTATE_JOG, // Jogging - MOVEMENTSTATE_SPRINT, // Sprinting - MOVEMENTSTATE_CROUCH, // Crouching still - MOVEMENTSTATE_CRAWL, // Crouch-moving - MOVEMENTSTATE_ROLL, // Crouch-rolling (Needs adding) - MOVEMENTSTATE_JUMP, // Jumping - MOVEMENTSTATE_FALL, // Falling - MOVEMENTSTATE_CLIMB // Climbing + MOVEMENTSTATE_STAND, // Standing still + MOVEMENTSTATE_WALK, // Walking + MOVEMENTSTATE_POWERWALK, // Walking quickly + MOVEMENTSTATE_JOG, // Jogging (Unused) + MOVEMENTSTATE_SPRINT, // Sprinting + MOVEMENTSTATE_CROUCH, // Crouching still + MOVEMENTSTATE_CRAWL, // Crouch-moving + MOVEMENTSTATE_ROLL, // Crouch-rolling + MOVEMENTSTATE_JUMP, // Jumping + MOVEMENTSTATE_FALL, // Falling + MOVEMENTSTATE_CLIMB, // Climbing + MOVEMENTSTATE_SWIM, // Swimming + MOVEMENTSTATE_WALK_TO_POINT, // Entering vehicle (walking to the door) + MOVEMENTSTATE_ASCENT_JETPACK, // Ascending with jetpack + MOVEMENTSTATE_DESCENT_JETPACK, // Descending with jetpack + MOVEMENTSTATE_JETPACK, // Jetpack flying + MOVEMENTSTATE_HANGING, // Hanging from the whall during climbing task }; enum eDeathAnims @@ -129,23 +137,23 @@ struct SReplacedAnimation struct SAnimationCache { - std::string strName; - int iTime{-1}; - bool bLoop{false}; - bool bUpdatePosition{false}; - bool bInterruptable{false}; - bool bFreezeLastFrame{true}; - int iBlend{250}; - float progress{0.0f}; - float speed{1.0f}; - bool progressWaitForStreamIn{false}; // for sync anim only - float elapsedTime{0.0f}; // for sync anim only + std::string strName; + int iTime{-1}; + bool bLoop{false}; + bool bUpdatePosition{false}; + bool bInterruptable{false}; + bool bFreezeLastFrame{true}; + int iBlend{250}; + float progress{0.0f}; + float speed{1.0f}; + bool progressWaitForStreamIn{false}; + std::int64_t startTime{0}; }; class CClientObject; // To hide the ugly "pointer truncation from DWORD* to unsigned long warning -#pragma warning(disable:4311) +#pragma warning(disable : 4311) class CClientPed : public CClientStreamElement, public CAntiCheatModule { @@ -236,12 +244,12 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule bool GetCanBeKnockedOffBike(); void SetCanBeKnockedOffBike(bool bCanBeKnockedOffBike); - bool IsInVehicle() const noexcept { return GetOccupiedVehicle() != NULL; }; + bool IsInVehicle() const noexcept { return GetOccupiedVehicle() != NULL; }; CClientVehicle* GetOccupiedVehicle() noexcept { return m_pOccupiedVehicle; }; const CClientVehicle* GetOccupiedVehicle() const noexcept { return m_pOccupiedVehicle; }; - unsigned int GetOccupiedVehicleSeat() const noexcept { return m_uiOccupiedVehicleSeat; }; + unsigned int GetOccupiedVehicleSeat() const noexcept { return m_uiOccupiedVehicleSeat; }; CClientVehicle* GetOccupyingVehicle() noexcept { return m_pOccupyingVehicle; }; const CClientVehicle* GetOccupyingVehicle() const noexcept { return m_pOccupyingVehicle; }; @@ -374,7 +382,7 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule void SetInWater(bool bIsInWater) { m_bIsInWater = bIsInWater; }; bool IsInWater(); - bool IsOnGround(); + bool IsOnGround(bool checkVehicles = false); bool IsClimbing(); bool IsRadioOn() const noexcept { return m_bRadioOn; }; @@ -402,7 +410,7 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule std::list::iterator ProjectilesEnd() { return m_Projectiles.end(); } unsigned int CountProjectiles(eWeaponType weaponType = WEAPONTYPE_UNARMED); - std::list& GetProjectiles() noexcept { return m_Projectiles; } + std::list& GetProjectiles() noexcept { return m_Projectiles; } const std::list& GetProjectiles() const noexcept { return m_Projectiles; } void RemoveAllProjectiles(); @@ -426,21 +434,21 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule unsigned char GetAlpha() const noexcept { return m_ucAlpha; } void SetAlpha(unsigned char ucAlpha); - bool HasTargetPosition() const noexcept { return m_interp.pos.ulFinishTime != 0; } - CClientEntity* GetTargetOriginSource() noexcept { return m_interp.pTargetOriginSource; } + bool HasTargetPosition() const noexcept { return m_interp.pos.ulFinishTime != 0; } + CClientEntity* GetTargetOriginSource() noexcept { return m_interp.pTargetOriginSource; } const CClientEntity* GetTargetOriginSource() const noexcept { return m_interp.pTargetOriginSource; } - void GetTargetPosition(CVector& vecPosition); - void SetTargetPosition(const CVector& vecPosition, unsigned long ulDelay, CClientEntity* pTargetOriginSource = NULL); - void RemoveTargetPosition(); - void UpdateTargetPosition(); - void UpdateUnderFloorFix(const CVector& vecTargetPosition, const CVector& vecOrigin); + void GetTargetPosition(CVector& vecPosition); + void SetTargetPosition(const CVector& vecPosition, unsigned long ulDelay, CClientEntity* pTargetOriginSource = NULL); + void RemoveTargetPosition(); + void UpdateTargetPosition(); + void UpdateUnderFloorFix(const CVector& vecTargetPosition, const CVector& vecOrigin); CClientEntity* GetTargetedEntity(); CClientPed* GetTargetedPed(); CClientEntity* GetCurrentContactEntity() noexcept { return m_pCurrentContactEntity; } const CClientEntity* GetCurrentContactEntity() const noexcept { return m_pCurrentContactEntity; } - void SetCurrentContactEntity(CClientEntity* pEntity) noexcept { m_pCurrentContactEntity = pEntity; } + void SetCurrentContactEntity(CClientEntity* pEntity) noexcept { m_pCurrentContactEntity = pEntity; } bool IsSunbathing(); void SetSunbathing(bool bSunbathing, bool bStartStanding = true); @@ -456,6 +464,10 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule bool GetRunningAnimationName(SString& strBlockName, SString& strAnimName); bool IsRunningAnimation(); + + // It checks whether the animation is still playing based on time, not on task execution. + bool IsAnimationInProgress(); + void RunNamedAnimation(std::unique_ptr& pBlock, const char* szAnimName, int iTime = -1, int iBlend = 250, bool bLoop = true, bool bUpdatePosition = true, bool bInterruptable = false, bool bFreezeLastFrame = true, bool bRunInSequence = false, bool bOffsetPed = false, bool bHoldLastFrame = false); @@ -463,6 +475,7 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule std::unique_ptr GetAnimationBlock(); const SAnimationCache& GetAnimationCache() const noexcept { return m_AnimationCache; } void RunAnimationFromCache(); + void UpdateAnimationProgressAndSpeed(); bool IsUsingGun(); @@ -512,20 +525,16 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule void DereferenceCustomAnimationBlock() { m_pCustomAnimationIFP = nullptr; } std::shared_ptr GetCustomAnimationIFP() const noexcept { return m_pCustomAnimationIFP; } - bool IsCustomAnimationPlaying() noexcept - { - return (m_bRequestedAnimation || m_AnimationCache.bLoop) - && m_pAnimationBlock && m_bisCurrentAnimationCustom; - } + bool IsCustomAnimationPlaying() noexcept { return (m_bRequestedAnimation || m_AnimationCache.bLoop) && m_pAnimationBlock && m_bisCurrentAnimationCustom; } void SetCustomAnimationUntriggerable() noexcept { m_bRequestedAnimation = false; m_AnimationCache.bLoop = false; } - bool IsNextAnimationCustom() const noexcept { return m_bisNextAnimationCustom; } - void SetNextAnimationCustom(const std::shared_ptr& pIFP, const SString& strAnimationName); - void SetCurrentAnimationCustom(bool bCustom) noexcept { m_bisCurrentAnimationCustom = bCustom; } - bool IsCurrentAnimationCustom() const noexcept { return m_bisCurrentAnimationCustom; } + bool IsNextAnimationCustom() const noexcept { return m_bisNextAnimationCustom; } + void SetNextAnimationCustom(const std::shared_ptr& pIFP, const SString& strAnimationName); + void SetCurrentAnimationCustom(bool bCustom) noexcept { m_bisCurrentAnimationCustom = bCustom; } + bool IsCurrentAnimationCustom() const noexcept { return m_bisCurrentAnimationCustom; } CIFPAnimations* GetIFPAnimationsPointer() noexcept { return m_pIFPAnimations; } const CIFPAnimations* GetIFPAnimationsPointer() const noexcept { return m_pIFPAnimations; } @@ -552,6 +561,11 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule void SetHasSyncedAnim(bool synced) noexcept { m_hasSyncedAnim = synced; } bool HasSyncedAnim() const noexcept { return m_hasSyncedAnim; } + void RunClimbingTask(); + + CTaskSimpleSwim* GetSwimmingTask() const; + void RunSwimTask() const; + protected: // This constructor is for peds managed by a player. These are unknown to the ped manager. CClientPed(CClientManager* pManager, unsigned long ulModelID, ElementID ID, bool bIsLocalPlayer); @@ -591,7 +605,7 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule public: void _GetIntoVehicle(CClientVehicle* pVehicle, unsigned int uiSeat, unsigned char ucDoor); // Used to control and sync entering/exiting - bool EnterVehicle(CClientVehicle* pVehicle, bool bPassenger); + bool EnterVehicle(CClientVehicle* pVehicle, bool bPassenger, std::optional optSeat = std::nullopt); bool ExitVehicle(); void ResetVehicleInOut(); void UpdateVehicleInOut(); @@ -634,8 +648,8 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule CStatsData* m_stats; CControllerState* m_currentControllerState; CControllerState* m_lastControllerState; - CControllerState m_rawControllerState; // copy of lastControllerState before CClientPed::ApplyControllerStateFixes is applied (modifies states to - // prevent stuff like rapid input glitch) + CControllerState m_rawControllerState; // copy of lastControllerState before CClientPed::ApplyControllerStateFixes is applied (modifies states to + // prevent stuff like rapid input glitch) CRemoteDataStorage* m_remoteDataStorage; unsigned long m_ulLastTimeFired; unsigned long m_ulLastTimeBeganAiming; @@ -675,7 +689,7 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule CClientEntityPtr m_pTargetedEntity; std::list m_SyncBuffer; bool m_bDucked; - bool m_bWasDucked; // For knowing when to register standing up + bool m_bWasDucked; // For knowing when to register standing up bool m_bIsChoking; bool m_bWearingGoggles; bool m_bVisible; @@ -779,16 +793,16 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule bool m_bWarpInToVehicleRequired = false; // Enter/exit variables - unsigned long m_ulLastVehicleInOutTime; // Last tick where we sent an enter/exit request - bool m_bIsGettingOutOfVehicle; // Indicates we are exiting a vehicle - bool m_bIsGettingIntoVehicle; // Indicates we are entering a vehicle - bool m_bIsJackingVehicle; // Indicates we are jacking a vehicle - bool m_bIsGettingJacked; // Indicates we are getting jacked - ElementID m_VehicleInOutID; // ElementID of vehicle received from server - unsigned char m_ucVehicleInOutSeat; // Seat ID we are entering/exiting received from server - bool m_bNoNewVehicleTask; // When set, we are not allowed to initiate a new enter/exit task because we are waiting for server reply - ElementID m_NoNewVehicleTaskReasonID; // ElementID of the vehicle that we are waiting on - CClientPed* m_pGettingJackedBy; // The ped that is jacking us + unsigned long m_ulLastVehicleInOutTime; // Last tick where we sent an enter/exit request + bool m_bIsGettingOutOfVehicle; // Indicates we are exiting a vehicle + bool m_bIsGettingIntoVehicle; // Indicates we are entering a vehicle + bool m_bIsJackingVehicle; // Indicates we are jacking a vehicle + bool m_bIsGettingJacked; // Indicates we are getting jacked + ElementID m_VehicleInOutID; // ElementID of vehicle received from server + unsigned char m_ucVehicleInOutSeat; // Seat ID we are entering/exiting received from server + bool m_bNoNewVehicleTask; // When set, we are not allowed to initiate a new enter/exit task because we are waiting for server reply + ElementID m_NoNewVehicleTaskReasonID; // ElementID of the vehicle that we are waiting on + CClientPed* m_pGettingJackedBy; // The ped that is jacking us std::shared_ptr m_clientModel; diff --git a/Client/mods/deathmatch/logic/CClientPedManager.cpp b/Client/mods/deathmatch/logic/CClientPedManager.cpp index 878b002a6d9..2f1c5fd5f7a 100644 --- a/Client/mods/deathmatch/logic/CClientPedManager.cpp +++ b/Client/mods/deathmatch/logic/CClientPedManager.cpp @@ -39,13 +39,10 @@ void CClientPedManager::DeleteAll() void CClientPedManager::DoPulse(bool bDoStandardPulses) { - CClientPed* pPed = NULL; // Loop through our streamed-in peds - vector List = m_StreamedIn; - vector::iterator iter = List.begin(); - for (; iter != List.end(); ++iter) + for (uint i = 0; i < m_StreamedIn.size(); i++) { - pPed = *iter; + CClientPed* pPed = m_StreamedIn[i]; // We should have a game ped here assert(pPed->GetGamePlayer()); pPed->StreamedInPulse(bDoStandardPulses); @@ -263,58 +260,58 @@ bool CClientPedManager::IsValidWeaponModel(DWORD dwModel) switch (dwModel) { case 0: - case 321: // Regular_Dildo - case 322: // Vibrator - case 323: // White_Dildo - // 324 // Vibrator_unused - case 325: // Flowers - case 326: // Cane - // 327 - // 328 - // 329 - // 330 - case 331: // Brass_Knuckles - // 332 - case 333: // Golf_Club - case 334: // Night_Strick - case 335: // Knife - case 336: // Baseball_Bat - case 337: // Shovel - case 338: // Pool_Cue - case 339: // Katana - // 340 - case 341: // Chainsaw - case 342: // Grenade - case 343: // Tear_Gas - case 344: // Molotov_Cocktail - // 345 // Missile - case 346: // Pistol - case 347: // Silenced_Pistol - case 348: // Desert_Eagle - case 349: // Shotgun - case 350: // Sawn-Off_Shotgun - case 351: // Combat_Shotgun - case 352: // Uzi - case 353: // MP5 - // 354 // Hydra_Flare - case 355: // AK47 - case 356: // M4 - case 357: // Country_Rifle - case 358: // Sniper_Rifle - case 359: // Rocket_Launcher - case 360: // Heat_Seeking_Rocket_Launcher - case 361: // Flamethrower - case 362: // Minigun - case 363: // Satchel_Charge - case 364: // Detonator - case 365: // Spray_Can - case 366: // Fire_Extinguisher - case 367: // Camera - case 368: // Night_Vision_Goggles - case 369: // Infra-Red_Goggles + case 321: // Regular_Dildo + case 322: // Vibrator + case 323: // White_Dildo + // 324 // Vibrator_unused + case 325: // Flowers + case 326: // Cane + // 327 + // 328 + // 329 + // 330 + case 331: // Brass_Knuckles + // 332 + case 333: // Golf_Club + case 334: // Night_Strick + case 335: // Knife + case 336: // Baseball_Bat + case 337: // Shovel + case 338: // Pool_Cue + case 339: // Katana + // 340 + case 341: // Chainsaw + case 342: // Grenade + case 343: // Tear_Gas + case 344: // Molotov_Cocktail + // 345 // Missile + case 346: // Pistol + case 347: // Silenced_Pistol + case 348: // Desert_Eagle + case 349: // Shotgun + case 350: // Sawn-Off_Shotgun + case 351: // Combat_Shotgun + case 352: // Uzi + case 353: // MP5 + // 354 // Hydra_Flare + case 355: // AK47 + case 356: // M4 + case 357: // Country_Rifle + case 358: // Sniper_Rifle + case 359: // Rocket_Launcher + case 360: // Heat_Seeking_Rocket_Launcher + case 361: // Flamethrower + case 362: // Minigun + case 363: // Satchel_Charge + case 364: // Detonator + case 365: // Spray_Can + case 366: // Fire_Extinguisher + case 367: // Camera + case 368: // Night_Vision_Goggles + case 369: // Infra-Red_Goggles // 370 // Jet_Pack - case 371: // Parachute - case 372: // Tec-9 + case 371: // Parachute + case 372: // Tec-9 { return true; } diff --git a/Client/mods/deathmatch/logic/CClientPerfStat.LibMemory.cpp b/Client/mods/deathmatch/logic/CClientPerfStat.LibMemory.cpp index 161898daee9..c42416d740b 100644 --- a/Client/mods/deathmatch/logic/CClientPerfStat.LibMemory.cpp +++ b/Client/mods/deathmatch/logic/CClientPerfStat.LibMemory.cpp @@ -42,7 +42,7 @@ namespace CDynamicLibrary* pLibrary; PFNGETALLOCSTATS pfnGetAllocStats; }; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -219,14 +219,14 @@ void CClientPerfStatLibMemoryImpl::GetLibMemoryStats(CClientPerfStatResult* pRes CLibraryInfo info; bool bModDir = libs[i].bModDir; info.strName = libs[i].szName; - #if MTA_DEBUG +#if MTA_DEBUG info.strName += "_d"; - #endif - #ifdef WIN32 +#endif +#ifdef WIN32 info.strName += ".dll"; - #else +#else info.strName += ".so"; - #endif +#endif info.pLibrary = new CDynamicLibrary(); SString strPathFilename; diff --git a/Client/mods/deathmatch/logic/CClientPerfStat.LuaMemory.cpp b/Client/mods/deathmatch/logic/CClientPerfStat.LuaMemory.cpp index e4f387e13de..f2a2d1b6849 100644 --- a/Client/mods/deathmatch/logic/CClientPerfStat.LuaMemory.cpp +++ b/Client/mods/deathmatch/logic/CClientPerfStat.LuaMemory.cpp @@ -36,7 +36,7 @@ namespace public: CLuaMainMemoryMap LuaMainMemoryMap; }; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -296,16 +296,16 @@ void CClientPerfStatLuaMemoryImpl::GetLuaMemoryStats(CClientPerfStatResult* pRes int ScreenSourceCount = g_pClientGame->GetManager()->GetRenderElementManager()->GetScreenSourceCount(); int WebBrowserCount = g_pClientGame->GetManager()->GetRenderElementManager()->GetWebBrowserCount(); int VectorGraphicCount = g_pClientGame->GetManager()->GetRenderElementManager()->GetVectorGraphicCount(); - TextItemCount = std::max(TextItemCount - 4, 0); // Remove count for radar items - row[c++] = !TextItemCount ? "-" : SString("%d", TextItemCount); - row[c++] = !DxFontCount ? "-" : SString("%d", DxFontCount); - row[c++] = !GuiFontCount ? "-" : SString("%d", GuiFontCount); - row[c++] = !TextureCount ? "-" : SString("%d", TextureCount); - row[c++] = !ShaderCount ? "-" : SString("%d", ShaderCount); - row[c++] = !RenderTargetCount ? "-" : SString("%d", RenderTargetCount); - row[c++] = !ScreenSourceCount ? "-" : SString("%d", ScreenSourceCount); - row[c++] = !WebBrowserCount ? "-" : SString("%d", WebBrowserCount); - row[c++] = !VectorGraphicCount ? "-" : SString("%d", VectorGraphicCount); + TextItemCount = std::max(TextItemCount - 4, 0); // Remove count for radar items + row[c++] = !TextItemCount ? SStringX("-") : SString("%d", TextItemCount); + row[c++] = !DxFontCount ? SStringX("-") : SString("%d", DxFontCount); + row[c++] = !GuiFontCount ? SStringX("-") : SString("%d", GuiFontCount); + row[c++] = !TextureCount ? SStringX("-") : SString("%d", TextureCount); + row[c++] = !ShaderCount ? SStringX("-") : SString("%d", ShaderCount); + row[c++] = !RenderTargetCount ? SStringX("-") : SString("%d", RenderTargetCount); + row[c++] = !ScreenSourceCount ? SStringX("-") : SString("%d", ScreenSourceCount); + row[c++] = !WebBrowserCount ? SStringX("-") : SString("%d", WebBrowserCount); + row[c++] = !VectorGraphicCount ? SStringX("-") : SString("%d", VectorGraphicCount); } // For each VM @@ -333,9 +333,9 @@ void CClientPerfStatLuaMemoryImpl::GetLuaMemoryStats(CClientPerfStatResult* pRes row[c++] = SString("%d KB", LuaMainMemory.Current); row[c++] = SString("%d KB", LuaMainMemory.Max); - row[c++] = !LuaMainMemory.OpenXMLFiles ? "-" : SString("%d", LuaMainMemory.OpenXMLFiles); - row[c++] = !LuaMainMemory.Refs ? "-" : SString("%d", LuaMainMemory.Refs); - row[c++] = !LuaMainMemory.TimerCount ? "-" : SString("%d", LuaMainMemory.TimerCount); - row[c++] = !LuaMainMemory.ElementCount ? "-" : SString("%d", LuaMainMemory.ElementCount); + row[c++] = !LuaMainMemory.OpenXMLFiles ? SStringX("-") : SString("%d", LuaMainMemory.OpenXMLFiles); + row[c++] = !LuaMainMemory.Refs ? SStringX("-") : SString("%d", LuaMainMemory.Refs); + row[c++] = !LuaMainMemory.TimerCount ? SStringX("-") : SString("%d", LuaMainMemory.TimerCount); + row[c++] = !LuaMainMemory.ElementCount ? SStringX("-") : SString("%d", LuaMainMemory.ElementCount); } } diff --git a/Client/mods/deathmatch/logic/CClientPerfStat.LuaTiming.cpp b/Client/mods/deathmatch/logic/CClientPerfStat.LuaTiming.cpp index e228345e391..122f1da96df 100644 --- a/Client/mods/deathmatch/logic/CClientPerfStat.LuaTiming.cpp +++ b/Client/mods/deathmatch/logic/CClientPerfStat.LuaTiming.cpp @@ -31,8 +31,8 @@ namespace struct CTimingPair { - CTiming acc; // Accumulator for current period - CTiming prev; // Result for previous period + CTiming acc; // Accumulator for current period + CTiming prev; // Result for previous period void Pulse(CTimingPair* above) { @@ -46,10 +46,10 @@ namespace class CTimingBlock { public: - CTimingPair s5; // 5 second period - CTimingPair s60; // 60 - CTimingPair m5; // 300 - CTimingPair m60; // 3600 + CTimingPair s5; // 5 second period + CTimingPair s60; // 60 + CTimingPair m5; // 300 + CTimingPair m60; // 3600 void Pulse1s(int flags) { @@ -100,7 +100,7 @@ namespace } } }; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -269,13 +269,13 @@ void CClientPerfStatLuaTimingImpl::DoPulse() int flags = 0; m_SecondCounter++; - if (m_SecondCounter % 5 == 0) // 1 second + if (m_SecondCounter % 5 == 0) // 1 second flags |= 1; - if (m_SecondCounter % 60 == 0) // 60 seconds + if (m_SecondCounter % 60 == 0) // 60 seconds flags |= 2; - if (m_SecondCounter % (60 * 5) == 0) // 5 mins + if (m_SecondCounter % (60 * 5) == 0) // 5 mins flags |= 4; - if (m_SecondCounter % (60 * 60) == 0) // 60 mins + if (m_SecondCounter % (60 * 60) == 0) // 60 mins flags |= 8; AllLuaTiming.Pulse1s(flags); @@ -430,9 +430,9 @@ void CClientPerfStatLuaTimingImpl::OutputTimingBlock(CClientPerfStatResult* pRes double total_p = total_s / double(threshList[i]) * 100; - row[c++] = total_p > 0.005 ? SString("%2.2f%%", total_p) : "-"; - row[c++] = total_s > 0.0005 ? SString("%2.3f", total_s) : "-"; - row[c++] = p->prev.calls > 0 ? SString("%d", p->prev.calls) : ""; + row[c++] = total_p > 0.005 ? SString("%2.2f%%", total_p) : SStringX("-"); + row[c++] = total_s > 0.0005 ? SString("%2.3f", total_s) : SStringX("-"); + row[c++] = p->prev.calls > 0 ? SString("%d", p->prev.calls) : SStringX(""); row[c++] = avg_s > 0.0005 ? SString("%2.3f", avg_s).c_str() : bSubBlock ? "-" : ""; row[c++] = max_s > 0.0005 ? SString("%2.3f", max_s).c_str() : bSubBlock ? "-" : ""; } diff --git a/Client/mods/deathmatch/logic/CClientPerfStat.PacketUsage.cpp b/Client/mods/deathmatch/logic/CClientPerfStat.PacketUsage.cpp index 677f4542814..b557a822a78 100644 --- a/Client/mods/deathmatch/logic/CClientPerfStat.PacketUsage.cpp +++ b/Client/mods/deathmatch/logic/CClientPerfStat.PacketUsage.cpp @@ -247,7 +247,7 @@ void CClientPerfStatPacketUsageImpl::GetStats(CClientPerfStatResult* pResult, co row[c++] = SString("%d", (statInDelta.iCount + 4) / 5); row[c++] = SString("%d", (statInDelta.iTotalBytes + 4) / 5); row[c++] = SString("%2.2f%%", - statInDelta.totalTime / 50000.f); // Number of microseconds in sample period ( 5sec * 1000000 ) into percent ( * 100 ) + statInDelta.totalTime / 50000.f); // Number of microseconds in sample period ( 5sec * 1000000 ) into percent ( * 100 ) } else { diff --git a/Client/mods/deathmatch/logic/CClientPickup.cpp b/Client/mods/deathmatch/logic/CClientPickup.cpp index dd9e9525ca5..9211b2cc987 100644 --- a/Client/mods/deathmatch/logic/CClientPickup.cpp +++ b/Client/mods/deathmatch/logic/CClientPickup.cpp @@ -84,7 +84,7 @@ void CClientPickup::SetPosition(const CVector& vecPosition) void CClientPickup::SetModel(unsigned short usModel) { - // Different from our current id? + // Different from our current model? if (m_usModel != usModel) { // Set the model and recreate the pickup @@ -114,7 +114,13 @@ void CClientPickup::SetVisible(bool bVisible) if (IsStreamedIn()) { if (bVisible) - Create(); + { + // Attempt to create - revert visibility if failed + if (!Create()) + { + m_bVisible = false; + } + } else Destroy(); } @@ -122,41 +128,68 @@ void CClientPickup::SetVisible(bool bVisible) void CClientPickup::StreamIn(bool bInstantly) { - // Create it - Create(); + // Invisible pickups don't need a game object - just notify streamer + if (!m_bVisible) + { + NotifyCreate(); + return; + } - // Notify the streamer we've created it - NotifyCreate(); + // Create the pickup and notify the streamer of the result + if (Create()) + { + NotifyCreate(); + } + else + { + NotifyUnableToCreate(); + } } void CClientPickup::StreamOut() { - // Destroy it + // Destroy the pickup Destroy(); } -void CClientPickup::Create() +bool CClientPickup::Create() { if (!m_pPickup && m_bVisible) { + // Grab the attributes from the MTA interface for this pickup + unsigned char ucAreaCode = GetInterior(); + unsigned short usDimension = GetDimension(); + // Create the pickup m_pPickup = g_pGame->GetPickups()->CreatePickup(&m_vecPosition, m_usModel, PickupType::PICKUP_ONCE); - m_pObject = NULL; + m_pObject = nullptr; if (m_pPickup) { - // Grab the attributes from the MTA interface for this pickup - unsigned char ucAreaCode = GetInterior(); - unsigned short usDimension = GetDimension(); - - // Make sure we have an object + // Make sure we have an object - request one if needed if (!m_pPickup->GetObject()) - m_pPickup->GiveUsAPickUpObject(); + { + if (!m_pPickup->GiveUsAPickUpObject()) + { + // Failed to create object - clean up and fail + m_pPickup->Remove(); + m_pPickup = nullptr; + return false; + } + } // Store our pickup's object m_pObject = m_pPickup->GetObject(); - // Create our collision - m_pCollision = new CClientColSphere(g_pClientGame->GetManager(), NULL, m_vecPosition, 1.0f); + // Validate the object was stored correctly + if (!m_pObject) + { + m_pPickup->Remove(); + m_pPickup = nullptr; + return false; + } + + // Create our collision sphere + m_pCollision = new CClientColSphere(g_pClientGame->GetManager(), ElementID(INVALID_ELEMENT_ID), m_vecPosition, 1.0f); m_pCollision->m_pOwningPickup = this; m_pCollision->SetHitCallback(this); m_pCollision->SetCanBeDestroyedByScript(false); @@ -170,54 +203,59 @@ void CClientPickup::Create() // Reattach to an entity + any entities attached to this ReattachEntities(); + return true; } } + return false; } void CClientPickup::Destroy() { + // Delete the collision sphere if (m_pCollision) { delete m_pCollision; - m_pCollision = NULL; + m_pCollision = nullptr; } + // Delete the pickup if (m_pPickup) { - // Delete the pickup + // Clear object reference before Remove() to prevent dangling pointer + m_pObject = nullptr; m_pPickup->Remove(); - m_pPickup = NULL; - m_pObject = NULL; + m_pPickup = nullptr; // Decrement pickup counter --m_pPickupManager->m_uiPickupCount; } } -void CClientPickup::ReCreate() +bool CClientPickup::ReCreate() { // If we had a pickup, destroy and recreate it if (m_pPickup) { Destroy(); - Create(); + return Create(); } + return false; } void CClientPickup::Callback_OnCollision(CClientColShape& Shape, CClientEntity& Entity) { if (IS_PLAYER(&Entity)) { - bool bMatchingDimensions = (GetDimension() == Entity.GetDimension()); // Matching dimensions? + bool bMatchingDimensions = (GetDimension() == Entity.GetDimension()); // Matching dimensions? // Call the pickup hit event (source = pickup that was hit) CLuaArguments Arguments; - Arguments.PushElement(&Entity); // The element that hit the pickup + Arguments.PushElement(&Entity); // The element that hit the pickup Arguments.PushBoolean(bMatchingDimensions); CallEvent("onClientPickupHit", Arguments, true); // Call the player pickup hit (source = player that hit the pickup) CLuaArguments Arguments2; - Arguments2.PushElement(this); // The pickup that was hit + Arguments2.PushElement(this); // The pickup that was hit Arguments2.PushBoolean(bMatchingDimensions); Entity.CallEvent("onClientPlayerPickupHit", Arguments2, true); } @@ -227,18 +265,31 @@ void CClientPickup::Callback_OnLeave(CClientColShape& Shape, CClientEntity& Enti { if (IS_PLAYER(&Entity)) { - bool bMatchingDimensions = (GetDimension() == Entity.GetDimension()); // Matching dimensions? + bool bMatchingDimensions = (GetDimension() == Entity.GetDimension()); // Matching dimensions? // Call the pickup leave event (source = the pickup that was left) CLuaArguments Arguments; - Arguments.PushElement(&Entity); // The element that left the pickup + Arguments.PushElement(&Entity); // The element that left the pickup Arguments.PushBoolean(bMatchingDimensions); CallEvent("onClientPickupLeave", Arguments, true); // Call the player pickup leave event (source = the player that left the pickup) CLuaArguments Arguments2; - Arguments2.PushElement(this); // The pickup that was left (this) + Arguments2.PushElement(this); // The pickup that was left (this) Arguments2.PushBoolean(bMatchingDimensions); Entity.CallEvent("onClientPlayerPickupLeave", Arguments2, true); } } + +void CClientPickup::NotifyUnableToCreate() +{ + // Clean up any collision sphere we may have created + if (m_pCollision) + { + delete m_pCollision; + m_pCollision = nullptr; + } + + // Notify the streamer we were unable to create the pickup + CClientStreamElement::NotifyUnableToCreate(); +} diff --git a/Client/mods/deathmatch/logic/CClientPickup.h b/Client/mods/deathmatch/logic/CClientPickup.h index 556ea1d72c9..8553e7a642f 100644 --- a/Client/mods/deathmatch/logic/CClientPickup.h +++ b/Client/mods/deathmatch/logic/CClientPickup.h @@ -124,9 +124,10 @@ class CClientPickup final : public CClientStreamElement, private CClientColCallb void StreamOut(); private: - void Create(); + void NotifyUnableToCreate(); + bool Create(); void Destroy(); - void ReCreate(); + bool ReCreate(); CClientPickupManager* m_pPickupManager; diff --git a/Client/mods/deathmatch/logic/CClientPickupManager.cpp b/Client/mods/deathmatch/logic/CClientPickupManager.cpp index 0e96acbe5ae..6cc7b07c3ca 100644 --- a/Client/mods/deathmatch/logic/CClientPickupManager.cpp +++ b/Client/mods/deathmatch/logic/CClientPickupManager.cpp @@ -14,11 +14,11 @@ using std::list; static const SFixedArray g_usWeaponModels = {{ - 0, 331, 333, 334, 335, 336, 337, 338, 339, 341, // 9 - 321, 322, 323, 0, 325, 326, 342, 343, 344, 0, // 19 - 0, 0, 346, 347, 348, 349, 350, 351, 352, 353, // 29 - 355, 356, 372, 357, 358, 359, 360, 361, 362, 363, // 39 - 364, 365, 366, 367, 368, 369, 371 // 46 + 0, 331, 333, 334, 335, 336, 337, 338, 339, 341, // 9 + 321, 322, 323, 324, 325, 326, 342, 343, 344, 0, // 19 + 0, 0, 346, 347, 348, 349, 350, 351, 352, 353, // 29 + 355, 356, 372, 357, 358, 359, 360, 361, 362, 363, // 39 + 364, 365, 366, 367, 368, 369, 371 // 46 }}; unsigned int CClientPickupManager::m_uiPickupCount = 0; @@ -51,6 +51,13 @@ CClientPickup* CClientPickupManager::Get(ElementID ID) void CClientPickupManager::DeleteAll() { + // Disable pickup processing during mass deletion to prevent crashes + bool wasDisabled = m_bPickupProcessingDisabled; + if (!wasDisabled) + { + SetPickupProcessingDisabled(true); + } + // Delete each pickup m_bDontRemoveFromList = true; list::const_iterator iter = m_List.begin(); @@ -63,6 +70,12 @@ void CClientPickupManager::DeleteAll() // Clear the list m_List.clear(); + + // Restore previous processing state + if (!wasDisabled) + { + SetPickupProcessingDisabled(false); + } } bool CClientPickupManager::Exists(CClientPickup* pPickup) @@ -92,13 +105,13 @@ bool CClientPickupManager::IsValidPickupID(unsigned short usPickupID) bool CClientPickupManager::IsValidWeaponID(unsigned short usWeaponID) { - return (usWeaponID > 0 && usWeaponID != 13 && usWeaponID != 19 && usWeaponID != 20 && usWeaponID != 21 && usWeaponID <= 46); + return (usWeaponID > 0 && usWeaponID != 19 && usWeaponID != 20 && usWeaponID != 21 && usWeaponID <= 46); } bool CClientPickupManager::IsPickupLimitReached() { - // Max 600 pickups - return (m_uiPickupCount >= 64); + // GTA:SA supports max 620 pickups + return (m_uiPickupCount >= 620); } unsigned short CClientPickupManager::GetWeaponModel(unsigned int uiWeaponID) diff --git a/Client/mods/deathmatch/logic/CClientPlayer.cpp b/Client/mods/deathmatch/logic/CClientPlayer.cpp index 4669e2ef715..2b8e6c5ecea 100644 --- a/Client/mods/deathmatch/logic/CClientPlayer.cpp +++ b/Client/mods/deathmatch/logic/CClientPlayer.cpp @@ -66,7 +66,7 @@ CClientPlayer::CClientPlayer(CClientManager* pManager, ElementID ID, bool bIsLoc m_remoteDataStorage->SetProcessPlayerWeapon(true); // Enable voice playback for remote players - if (g_pClientGame->GetVoiceRecorder()->IsEnabled()) // If voice is enabled + if (g_pClientGame->GetVoiceRecorder()->IsEnabled()) // If voice is enabled m_voice = new CClientPlayerVoice(this, g_pClientGame->GetVoiceRecorder()); } @@ -269,7 +269,6 @@ void CClientPlayer::DischargeWeapon(eWeaponType weaponType, const CVector& vecSt if (weaponType != GetCurrentWeaponType()) { GiveWeapon(weaponType, 99, true); - AddReportLog(5432, SString("DischargeWeapon adding missing weapon %d (%s)", weaponType, GetNick()), 30); } // Check weapon matches and is enabled for bullet sync diff --git a/Client/mods/deathmatch/logic/CClientPlayer.h b/Client/mods/deathmatch/logic/CClientPlayer.h index bef1f264976..57cd754dd0d 100644 --- a/Client/mods/deathmatch/logic/CClientPlayer.h +++ b/Client/mods/deathmatch/logic/CClientPlayer.h @@ -112,7 +112,7 @@ class CClientPlayer final : public CClientPed void SetIsInNetworkInterruption(bool bInNetworkInterruption); std::uint8_t GetPlayerScriptDebugLevel() const noexcept { return m_scriptDebugLevel; } - void SetPlayerScriptDebugLevel(std::uint8_t level) noexcept { m_scriptDebugLevel = level; } + void SetPlayerScriptDebugLevel(std::uint8_t level) noexcept { m_scriptDebugLevel = level; } CVector m_vecPrevBulletSyncStart; CVector m_vecPrevBulletSyncEnd; @@ -139,7 +139,7 @@ class CClientPlayer final : public CClientPed unsigned long m_ulTick; bool m_bDoExtrapolatingAim; - std::uint8_t m_scriptDebugLevel{}; + std::uint8_t m_scriptDebugLevel{}; bool m_bForce; CVector m_vecForcedMoveSpeed; diff --git a/Client/mods/deathmatch/logic/CClientPlayerClothes.cpp b/Client/mods/deathmatch/logic/CClientPlayerClothes.cpp index 789eab812d8..8ec23087ca2 100644 --- a/Client/mods/deathmatch/logic/CClientPlayerClothes.cpp +++ b/Client/mods/deathmatch/logic/CClientPlayerClothes.cpp @@ -15,171 +15,304 @@ static const SPlayerClothingType g_clothesNames[PLAYER_CLOTHING_SLOTS] = { {"Right Lower Arm"}, {"Back Top"}, {"Left Chest"}, {"Right Chest"}, {"Stomach"}, {"Lower Back"}, {"Extra1"}, {"Extra2"}, {"Extra3"}, {"Extra4"}, {"Suit"}}; -SFixedArray, PLAYER_CLOTHING_SLOTS> CClientPlayerClothes::m_DefaultClothes -{ - //Torso Clothing - std::vector { - {"player_torso", "torso"}, {"vestblack", "vest"}, {"vest", "vest"}, {"tshirt2horiz", "tshirt2"}, {"tshirtwhite", "tshirt"}, - {"tshirtilovels", "tshirt"}, {"tshirtblunts", "tshirt"}, {"shirtbplaid", "shirtb"}, {"shirtbcheck", "shirtb"}, - {"field", "field"}, {"tshirterisyell", "tshirt"}, {"tshirterisorn", "tshirt"}, {"trackytop2eris", "trackytop1"}, - {"bbjackrim", "bbjack"}, {"bballjackrstar", "bbjack"}, {"baskballdrib", "baskball"}, {"baskballrim", "baskball"}, - {"sixtyniners", "tshirt"}, {"bandits", "baseball"}, {"tshirtprored", "tshirt"}, {"tshirtproblk", "tshirt"}, - {"trackytop1pro", "trackytop1"}, {"hockeytop", "sweat"}, {"bbjersey", "sleevt"}, {"shellsuit", "trackytop1"}, - {"tshirtheatwht", "tshirt"}, {"tshirtbobomonk", "tshirt"}, {"tshirtbobored", "tshirt"}, {"tshirtbase5", "tshirt"}, - {"tshirtsuburb", "tshirt"}, {"hoodyamerc", "hoodya"}, {"hoodyabase5", "hoodya"}, {"hoodyarockstar", "hoodya"}, - {"wcoatblue", "wcoat"}, {"coach", "coach"}, {"coachsemi", "coach"}, {"sweatrstar", "sweat"}, {"hoodyAblue", "hoodyA"}, - {"hoodyAblack", "hoodyA"}, {"hoodyAgreen", "hoodyA"}, {"sleevtbrown", "sleevt"}, {"shirtablue", "shirta"}, {"shirtayellow", "shirta"}, - {"shirtagrey", "shirta"}, {"shirtbgang", "shirtb"}, {"tshirtzipcrm", "tshirt"}, {"tshirtzipgry", "tshirt"}, {"denimfade", "denim"}, - {"bowling", "hawaii"}, {"hoodjackbeige", "hoodjack"}, {"baskballloc", "baskball"}, {"tshirtlocgrey", "tshirt"}, - {"tshirtmaddgrey", "tshirt"}, {"tshirtmaddgrn", "tshirt"}, {"suit1grey", "suit1"}, {"suit1blk", "suit1"}, {"leather", "leather"}, - {"painter", "painter"}, {"hawaiiwht", "hawaii"}, {"hawaiired", "hawaii"}, {"sportjack", "trackytop1"}, {"suit1red", "suit1"}, - {"suit1blue", "suit1"}, {"suit1yellow", "suit1"}, {"suit2grn", "suit2"}, {"tuxedo", "suit2"}, {"suit1gang", "suit1"}, {"letter", "sleevt"} - }, - - //Hair Clothing - std::vector { - {"player_face", "head"}, {"hairblond", "head"}, {"hairred", "head"}, {"hairblue", "head"}, {"hairgreen", "head"}, {"hairpink", "head"}, - {"bald", "head"}, {"baldbeard", "head"}, {"baldtash", "head"}, {"baldgoatee", "head"}, {"highfade", "head"}, {"highafro", "highafro"}, - {"wedge", "wedge"}, {"slope", "slope"}, {"jhericurl", "jheri"}, {"cornrows", "cornrows"}, {"cornrowsb", "cornrows"}, {"tramline", "tramline"}, - {"groovecut", "groovecut"}, {"mohawk", "mohawk"}, {"mohawkblond", "mohawk"}, {"mohawkpink", "mohawk"}, - {"mohawkbeard", "mohawk"}, {"afro", "afro"}, {"afrotash", "afro"}, {"afrobeard", "afro"}, {"afroblond", "afro"}, {"flattop", "flattop"}, - {"elvishair", "elvishair"}, {"beard", "head"}, {"tash", "head"}, {"goatee", "head"}, {"afrogoatee", "afro"} - }, - - //Legs Clothing - std::vector { - {"player_legs", "legs"}, {"worktrcamogrn", "worktr"}, {"worktrcamogry", "worktr"}, {"worktrgrey", "worktr"}, - {"worktrkhaki", "worktr"}, {"tracktr", "tracktr"}, {"tracktreris", "tracktr"}, {"jeansdenim", "jeans"}, - {"legsblack", "legs"}, {"legsheart", "legs"}, {"biegetr", "chinosb"}, {"tracktrpro", "tracktr"}, - {"tracktrwhstr", "tracktr"}, {"tracktrblue", "tracktr"}, {"tracktrgang", "tracktr"}, {"bbshortwht", "boxingshort"}, - {"boxshort", "boxingshort"}, {"bbshortred", "boxingshort"}, {"shellsuittr", "tracktr"}, {"shortsgrey", "shorts"}, - {"shortskhaki", "shorts"}, {"chongergrey", "chonger"}, {"chongergang", "chonger"}, {"chongerred", "chonger"}, - {"chongerblue", "chonger"}, {"shortsgang", "shorts"}, {"denimsgang", "jeans"}, {"denimsred", "jeans"}, - {"chinosbiege", "chinosb"}, {"chinoskhaki", "chinosb"}, {"cutoffchinos", "shorts"}, {"cutoffchinosblue", "shorts"}, - {"chinosblack", "chinosb"}, {"chinosblue", "chinosb"}, {"leathertr", "leathertr"}, {"leathertrchaps", "leathertr"}, - {"suit1trgrey", "suit1tr"}, {"suit1trblk", "suit1tr"}, {"cutoffdenims", "shorts"}, {"suit1trred", "suit1tr"}, - {"suit1trblue", "suit1tr"}, {"suit1tryellow", "suit1tr"}, {"suit1trgreen", "suit1tr"}, {"suit1trblk2", "suit1tr"}, - {"suit1trgang", "suit1tr"} - }, - - //Shoes Clothing - std::vector { - {"foot", "feet"}, {"cowboyboot2", "biker"}, {"bask2semi", "bask1"}, {"bask1eris", "bask1"}, {"sneakerbincgang", "sneaker"}, {"sneakerbincblu", "sneaker"}, - {"sneakerbincblk", "sneaker"}, {"sandal", "flipflop"}, {"sandalsock", "flipflop"}, {"flipflop", "flipflop"}, {"hitop", "bask1"}, {"convproblk", "conv"}, - {"convproblu", "conv"}, {"convprogrn", "conv"}, {"sneakerprored", "sneaker"}, {"sneakerproblu", "sneaker"}, {"sneakerprowht", "sneaker"}, - {"bask1prowht", "bask1"}, {"bask1problk", "bask1"}, {"boxingshoe", "biker"}, {"convheatblk", "conv"}, {"convheatred", "conv"}, {"convheatorn", "conv"}, - {"sneakerheatwht", "sneaker"}, {"sneakerheatgry", "sneaker"}, {"sneakerheatblk", "sneaker"}, {"bask2heatwht", "bask1"}, {"bask2heatband", "bask1"}, - {"timbergrey", "bask1"}, {"timberred", "bask1"}, {"timberfawn", "bask1"}, {"timberhike", "bask1"}, {"cowboyboot", "biker"}, {"biker", "biker"}, - {"snakeskin", "biker"}, {"shoedressblk", "shoe"}, {"shoedressbrn", "shoe"}, {"shoespatz", "shoe"} - }, - - //Left Upper Arm Clothing - std::vector { - {"4weed", "4WEED"}, {"4rip", "4RIP"}, {"4spider", "4SPIDER"} - }, - - //Left Lower Arm Clothing - std::vector { - {"5gun", "5GUN"}, {"5cross", "5CROSS"}, {"5cross2", "5CROSS2"}, - {"5cross3", "5CROSS3"} - }, - - //Right Upper Arm Clothing - std::vector { - {"6aztec", "6AZTEC"}, {"6crown", "6CROWN"}, {"6clown", "6CLOWN"}, - {"6africa", "6AFRICA"} - }, - - //Right LowerA rm Clothing - std::vector { - {"7cross", "7CROSS"}, {"7cross2", "7CROSS2"}, {"7cross3", "7CROSS3"}, - {"7mary", "7MARY"} - }, - - //Back Top Clothing - std::vector { - {"8sa", "8SA"}, {"8sa2", "8SA2"}, {"8sa3", "8SA3"}, - {"8westside", "8WESTSD"}, {"8santos", "8SANTOS"}, - {"8poker", "8POKER"}, {"8gun", "8GUN"} - }, - - //Left Chest Clothing - std::vector { - {"9crown", "9CROWN"}, {"9gun", "9GUN"}, {"9gun2", "9GUN2"}, - {"9homeboy", "9HOMBY"}, {"9bullet", "9BULLT"}, - {"9rasta", "9RASTA"} - }, - - //Right Chest Clothing - std::vector { - {"10ls", "10LS"}, {"10ls2", "10LS2"}, {"10ls3", "10LS3"}, - {"10ls4", "10LS4"}, {"10ls5", "10LS5"}, {"10og", "10OG"}, - {"10weed", "10WEED"} - }, - - //Stomach Clothing - std::vector { - {"11grove", "11GROVE"}, {"11grove2", "11GROV2"}, {"11grove3", "11GROV3"}, {"11dice", "11DICE"}, - {"11dice2", "11DICE2"}, {"11jail", "11JAIL"}, {"11godsgift", "11GGIFT"} - }, - - //Lower Back Clothing - std::vector { - {"12angels", "12ANGEL"}, {"12mayabird", "12MAYBR"}, {"12dagger", "12DAGER"}, - {"12bandit", "12BNDIT"}, {"12cross7", "12CROSS"}, {"12mayaface", "12MYFAC"}, - }, - - //Extra1 Clothing - std::vector { - {"dogtag", "neck"}, {"neckafrica", "neck"}, {"stopwatch", "neck"}, {"necksaints", "neck"}, {"neckhash", "neck"}, {"necksilver", "neck2"}, - {"neckgold", "neck2"}, {"neckropes", "neck2"}, {"neckropeg", "neck2"}, {"neckls", "neck"}, {"neckdollar", "neck"}, {"neckcross", "neck"} - }, - - //Extra2 Clothing - std::vector { - {"watchpink", "watch"}, {"watchyellow", "watch"}, {"watchpro", "watch"}, {"watchpro2", "watch"}, {"watchsub1", "watch"}, - {"watchsub2", "watch"}, {"watchzip1", "watch"}, {"watchzip2", "watch"}, {"watchgno", "watch"}, {"watchgno2", "watch"}, - {"watchcro", "watch"}, {"watchcro2", "watch"} +SFixedArray, PLAYER_CLOTHING_SLOTS> CClientPlayerClothes::m_DefaultClothes{ + // Torso Clothing + std::vector{{"player_torso", "torso"}, + {"vestblack", "vest"}, + {"vest", "vest"}, + {"tshirt2horiz", "tshirt2"}, + {"tshirtwhite", "tshirt"}, + {"tshirtilovels", "tshirt"}, + {"tshirtblunts", "tshirt"}, + {"shirtbplaid", "shirtb"}, + {"shirtbcheck", "shirtb"}, + {"field", "field"}, + {"tshirterisyell", "tshirt"}, + {"tshirterisorn", "tshirt"}, + {"trackytop2eris", "trackytop1"}, + {"bbjackrim", "bbjack"}, + {"bballjackrstar", "bbjack"}, + {"baskballdrib", "baskball"}, + {"baskballrim", "baskball"}, + {"sixtyniners", "tshirt"}, + {"bandits", "baseball"}, + {"tshirtprored", "tshirt"}, + {"tshirtproblk", "tshirt"}, + {"trackytop1pro", "trackytop1"}, + {"hockeytop", "sweat"}, + {"bbjersey", "sleevt"}, + {"shellsuit", "trackytop1"}, + {"tshirtheatwht", "tshirt"}, + {"tshirtbobomonk", "tshirt"}, + {"tshirtbobored", "tshirt"}, + {"tshirtbase5", "tshirt"}, + {"tshirtsuburb", "tshirt"}, + {"hoodyamerc", "hoodya"}, + {"hoodyabase5", "hoodya"}, + {"hoodyarockstar", "hoodya"}, + {"wcoatblue", "wcoat"}, + {"coach", "coach"}, + {"coachsemi", "coach"}, + {"sweatrstar", "sweat"}, + {"hoodyAblue", "hoodyA"}, + {"hoodyAblack", "hoodyA"}, + {"hoodyAgreen", "hoodyA"}, + {"sleevtbrown", "sleevt"}, + {"shirtablue", "shirta"}, + {"shirtayellow", "shirta"}, + {"shirtagrey", "shirta"}, + {"shirtbgang", "shirtb"}, + {"tshirtzipcrm", "tshirt"}, + {"tshirtzipgry", "tshirt"}, + {"denimfade", "denim"}, + {"bowling", "hawaii"}, + {"hoodjackbeige", "hoodjack"}, + {"baskballloc", "baskball"}, + {"tshirtlocgrey", "tshirt"}, + {"tshirtmaddgrey", "tshirt"}, + {"tshirtmaddgrn", "tshirt"}, + {"suit1grey", "suit1"}, + {"suit1blk", "suit1"}, + {"leather", "leather"}, + {"painter", "painter"}, + {"hawaiiwht", "hawaii"}, + {"hawaiired", "hawaii"}, + {"sportjack", "trackytop1"}, + {"suit1red", "suit1"}, + {"suit1blue", "suit1"}, + {"suit1yellow", "suit1"}, + {"suit2grn", "suit2"}, + {"tuxedo", "suit2"}, + {"suit1gang", "suit1"}, + {"letter", "sleevt"}}, + + // Hair Clothing + std::vector{ + {"player_face", "head"}, {"hairblond", "head"}, {"hairred", "head"}, {"hairblue", "head"}, {"hairgreen", "head"}, + {"hairpink", "head"}, {"bald", "head"}, {"baldbeard", "head"}, {"baldtash", "head"}, {"baldgoatee", "head"}, + {"highfade", "head"}, {"highafro", "highafro"}, {"wedge", "wedge"}, {"slope", "slope"}, {"jhericurl", "jheri"}, + {"cornrows", "cornrows"}, {"cornrowsb", "cornrows"}, {"tramline", "tramline"}, {"groovecut", "groovecut"}, {"mohawk", "mohawk"}, + {"mohawkblond", "mohawk"}, {"mohawkpink", "mohawk"}, {"mohawkbeard", "mohawk"}, {"afro", "afro"}, {"afrotash", "afro"}, + {"afrobeard", "afro"}, {"afroblond", "afro"}, {"flattop", "flattop"}, {"elvishair", "elvishair"}, {"beard", "head"}, + {"tash", "head"}, {"goatee", "head"}, {"afrogoatee", "afro"}}, + + // Legs Clothing + std::vector{ + {"player_legs", "legs"}, {"worktrcamogrn", "worktr"}, {"worktrcamogry", "worktr"}, {"worktrgrey", "worktr"}, {"worktrkhaki", "worktr"}, + {"tracktr", "tracktr"}, {"tracktreris", "tracktr"}, {"jeansdenim", "jeans"}, {"legsblack", "legs"}, {"legsheart", "legs"}, + {"biegetr", "chinosb"}, {"tracktrpro", "tracktr"}, {"tracktrwhstr", "tracktr"}, {"tracktrblue", "tracktr"}, {"tracktrgang", "tracktr"}, + {"bbshortwht", "boxingshort"}, {"boxshort", "boxingshort"}, {"bbshortred", "boxingshort"}, {"shellsuittr", "tracktr"}, {"shortsgrey", "shorts"}, + {"shortskhaki", "shorts"}, {"chongergrey", "chonger"}, {"chongergang", "chonger"}, {"chongerred", "chonger"}, {"chongerblue", "chonger"}, + {"shortsgang", "shorts"}, {"denimsgang", "jeans"}, {"denimsred", "jeans"}, {"chinosbiege", "chinosb"}, {"chinoskhaki", "chinosb"}, + {"cutoffchinos", "shorts"}, {"cutoffchinosblue", "shorts"}, {"chinosblack", "chinosb"}, {"chinosblue", "chinosb"}, {"leathertr", "leathertr"}, + {"leathertrchaps", "leathertr"}, {"suit1trgrey", "suit1tr"}, {"suit1trblk", "suit1tr"}, {"cutoffdenims", "shorts"}, {"suit1trred", "suit1tr"}, + {"suit1trblue", "suit1tr"}, {"suit1tryellow", "suit1tr"}, {"suit1trgreen", "suit1tr"}, {"suit1trblk2", "suit1tr"}, {"suit1trgang", "suit1tr"}}, + + // Shoes Clothing + std::vector{{"foot", "feet"}, + {"cowboyboot2", "biker"}, + {"bask2semi", "bask1"}, + {"bask1eris", "bask1"}, + {"sneakerbincgang", "sneaker"}, + {"sneakerbincblu", "sneaker"}, + {"sneakerbincblk", "sneaker"}, + {"sandal", "flipflop"}, + {"sandalsock", "flipflop"}, + {"flipflop", "flipflop"}, + {"hitop", "bask1"}, + {"convproblk", "conv"}, + {"convproblu", "conv"}, + {"convprogrn", "conv"}, + {"sneakerprored", "sneaker"}, + {"sneakerproblu", "sneaker"}, + {"sneakerprowht", "sneaker"}, + {"bask1prowht", "bask1"}, + {"bask1problk", "bask1"}, + {"boxingshoe", "biker"}, + {"convheatblk", "conv"}, + {"convheatred", "conv"}, + {"convheatorn", "conv"}, + {"sneakerheatwht", "sneaker"}, + {"sneakerheatgry", "sneaker"}, + {"sneakerheatblk", "sneaker"}, + {"bask2heatwht", "bask1"}, + {"bask2heatband", "bask1"}, + {"timbergrey", "bask1"}, + {"timberred", "bask1"}, + {"timberfawn", "bask1"}, + {"timberhike", "bask1"}, + {"cowboyboot", "biker"}, + {"biker", "biker"}, + {"snakeskin", "biker"}, + {"shoedressblk", "shoe"}, + {"shoedressbrn", "shoe"}, + {"shoespatz", "shoe"}}, + + // Left Upper Arm Clothing + std::vector{{"4weed", "4WEED"}, {"4rip", "4RIP"}, {"4spider", "4SPIDER"}}, + + // Left Lower Arm Clothing + std::vector{{"5gun", "5GUN"}, {"5cross", "5CROSS"}, {"5cross2", "5CROSS2"}, {"5cross3", "5CROSS3"}}, + + // Right Upper Arm Clothing + std::vector{{"6aztec", "6AZTEC"}, {"6crown", "6CROWN"}, {"6clown", "6CLOWN"}, {"6africa", "6AFRICA"}}, + + // Right LowerA rm Clothing + std::vector{{"7cross", "7CROSS"}, {"7cross2", "7CROSS2"}, {"7cross3", "7CROSS3"}, {"7mary", "7MARY"}}, + + // Back Top Clothing + std::vector{ + {"8sa", "8SA"}, {"8sa2", "8SA2"}, {"8sa3", "8SA3"}, {"8westside", "8WESTSD"}, {"8santos", "8SANTOS"}, {"8poker", "8POKER"}, {"8gun", "8GUN"}}, + + // Left Chest Clothing + std::vector{ + {"9crown", "9CROWN"}, {"9gun", "9GUN"}, {"9gun2", "9GUN2"}, {"9homeboy", "9HOMBY"}, {"9bullet", "9BULLT"}, {"9rasta", "9RASTA"}}, + + // Right Chest Clothing + std::vector{ + {"10ls", "10LS"}, {"10ls2", "10LS2"}, {"10ls3", "10LS3"}, {"10ls4", "10LS4"}, {"10ls5", "10LS5"}, {"10og", "10OG"}, {"10weed", "10WEED"}}, + + // Stomach Clothing + std::vector{{"11grove", "11GROVE"}, + {"11grove2", "11GROV2"}, + {"11grove3", "11GROV3"}, + {"11dice", "11DICE"}, + {"11dice2", "11DICE2"}, + {"11jail", "11JAIL"}, + {"11godsgift", "11GGIFT"}}, + + // Lower Back Clothing + std::vector{ + {"12angels", "12ANGEL"}, + {"12mayabird", "12MAYBR"}, + {"12dagger", "12DAGER"}, + {"12bandit", "12BNDIT"}, + {"12cross7", "12CROSS"}, + {"12mayaface", "12MYFAC"}, }, - //Extra3 Clothing - std::vector { - {"groucho", "grouchos"}, {"zorro", "zorromask"}, {"eyepatch", "eyepatch"}, - {"glasses01", "glasses01"}, {"glasses04", "glasses04"}, {"bandred3", "bandmask"}, - {"bandblue3", "bandmask"}, {"bandgang3", "bandmask"}, {"bandblack3", "bandmask"}, - {"glasses01dark", "glasses01"}, {"glasses04dark", "glasses04"}, {"glasses03", "glasses03"}, - {"glasses03red", "glasses03"}, {"glasses03blue", "glasses03"}, {"glasses03dark", "glasses03"}, - {"glasses05dark", "glasses03"}, {"glasses05", "glasses03"} - }, - - //Extra4 Clothing - std::vector { - {"bandred", "bandana"}, {"bandblue", "bandana"}, {"bandgang", "bandana"}, {"bandblack", "bandana"}, {"bandred2", "bandknots"}, - {"bandblue2", "bandknots"}, {"bandblack2", "bandknots"}, {"bandgang2", "bandknots"}, {"capknitgrn", "capknit"}, {"captruck", "captruck"}, - {"cowboy", "cowboy"}, {"hattiger", "cowboy"}, {"helmet", "helmet"}, {"moto", "moto"}, {"boxingcap", "boxingcap"}, {"hockey", "hockeymask"}, {"capgang", "cap"}, - {"capgangback", "capback"}, {"capgangside", "capside"}, {"capgangover", "capovereye"}, {"capgangup", "caprimup"}, {"bikerhelmet", "bikerhelmet"}, - {"capred", "cap"}, {"capredback", "capback"}, {"capredside", "capside"}, {"capredover", "capovereye"}, {"capredup", "caprimup"}, {"capblue", "cap"}, - {"capblueback", "capback"}, {"capblueside", "capside"}, {"capblueover", "capovereye"}, {"capblueup", "caprimup"}, {"skullyblk", "skullycap"}, - {"skullygrn", "skullycap"}, {"hatmancblk", "hatmanc"}, {"hatmancplaid", "hatmanc"}, {"capzip", "cap"}, {"capzipback", "capback"}, {"capzipside", "capside"}, - {"capzipover", "capovereye"}, {"capzipup", "caprimup"}, {"beretred", "beret"}, {"beretblk", "beret"}, {"capblk", "cap"}, {"capblkback", "capback"}, - {"capblkside", "capside"}, {"capblkover", "capovereye"}, {"capblkup", "caprimup"}, {"trilbydrk", "trilby"}, {"trilbylght", "trilby"}, - {"bowler", "bowler"}, {"bowlerred", "bowler"}, {"bowlerblue", "bowler"}, {"bowleryellow", "bowler"}, {"boater", "boater"}, {"bowlergang", "bowler"}, - {"boaterblk", "boater"} - }, + // Extra1 Clothing + std::vector{{"dogtag", "neck"}, + {"neckafrica", "neck"}, + {"stopwatch", "neck"}, + {"necksaints", "neck"}, + {"neckhash", "neck"}, + {"necksilver", "neck2"}, + {"neckgold", "neck2"}, + {"neckropes", "neck2"}, + {"neckropeg", "neck2"}, + {"neckls", "neck"}, + {"neckdollar", "neck"}, + {"neckcross", "neck"}}, + + // Extra2 Clothing + std::vector{{"watchpink", "watch"}, + {"watchyellow", "watch"}, + {"watchpro", "watch"}, + {"watchpro2", "watch"}, + {"watchsub1", "watch"}, + {"watchsub2", "watch"}, + {"watchzip1", "watch"}, + {"watchzip2", "watch"}, + {"watchgno", "watch"}, + {"watchgno2", "watch"}, + {"watchcro", "watch"}, + {"watchcro2", "watch"}}, + + // Extra3 Clothing + std::vector{{"groucho", "grouchos"}, + {"zorro", "zorromask"}, + {"eyepatch", "eyepatch"}, + {"glasses01", "glasses01"}, + {"glasses04", "glasses04"}, + {"bandred3", "bandmask"}, + {"bandblue3", "bandmask"}, + {"bandgang3", "bandmask"}, + {"bandblack3", "bandmask"}, + {"glasses01dark", "glasses01"}, + {"glasses04dark", "glasses04"}, + {"glasses03", "glasses03"}, + {"glasses03red", "glasses03"}, + {"glasses03blue", "glasses03"}, + {"glasses03dark", "glasses03"}, + {"glasses05dark", "glasses03"}, + {"glasses05", "glasses03"}}, + + // Extra4 Clothing + std::vector{{"bandred", "bandana"}, + {"bandblue", "bandana"}, + {"bandgang", "bandana"}, + {"bandblack", "bandana"}, + {"bandred2", "bandknots"}, + {"bandblue2", "bandknots"}, + {"bandblack2", "bandknots"}, + {"bandgang2", "bandknots"}, + {"capknitgrn", "capknit"}, + {"captruck", "captruck"}, + {"cowboy", "cowboy"}, + {"hattiger", "cowboy"}, + {"helmet", "helmet"}, + {"moto", "moto"}, + {"boxingcap", "boxingcap"}, + {"hockey", "hockeymask"}, + {"capgang", "cap"}, + {"capgangback", "capback"}, + {"capgangside", "capside"}, + {"capgangover", "capovereye"}, + {"capgangup", "caprimup"}, + {"bikerhelmet", "bikerhelmet"}, + {"capred", "cap"}, + {"capredback", "capback"}, + {"capredside", "capside"}, + {"capredover", "capovereye"}, + {"capredup", "caprimup"}, + {"capblue", "cap"}, + {"capblueback", "capback"}, + {"capblueside", "capside"}, + {"capblueover", "capovereye"}, + {"capblueup", "caprimup"}, + {"skullyblk", "skullycap"}, + {"skullygrn", "skullycap"}, + {"hatmancblk", "hatmanc"}, + {"hatmancplaid", "hatmanc"}, + {"capzip", "cap"}, + {"capzipback", "capback"}, + {"capzipside", "capside"}, + {"capzipover", "capovereye"}, + {"capzipup", "caprimup"}, + {"beretred", "beret"}, + {"beretblk", "beret"}, + {"capblk", "cap"}, + {"capblkback", "capback"}, + {"capblkside", "capside"}, + {"capblkover", "capovereye"}, + {"capblkup", "caprimup"}, + {"trilbydrk", "trilby"}, + {"trilbylght", "trilby"}, + {"bowler", "bowler"}, + {"bowlerred", "bowler"}, + {"bowlerblue", "bowler"}, + {"bowleryellow", "bowler"}, + {"boater", "boater"}, + {"bowlergang", "bowler"}, + {"boaterblk", "boater"}}, // Suit Clothing - std::vector { - {"gimpleg", "gimpleg"}, {"valet", "valet"}, {"countrytr", "countrytr"}, {"croupier", "valet"}, - {"policetr", "policetr"}, {"balaclava", "balaclava"}, {"pimptr", "pimptr"}, - {"garageleg", "garagetr"}, {"medictr", "medictr"} - } -}; + std::vector{{"gimpleg", "gimpleg"}, + {"valet", "valet"}, + {"countrytr", "countrytr"}, + {"croupier", "valet"}, + {"policetr", "policetr"}, + {"balaclava", "balaclava"}, + {"pimptr", "pimptr"}, + {"garageleg", "garagetr"}, + {"medictr", "medictr"}}}; // This represents GTA's 1 clothing block -SFixedArray CClientPlayerClothes::m_GlobalClothes; -SFixedArray, PLAYER_CLOTHING_SLOTS> CClientPlayerClothes::m_NewClothes; -bool CClientPlayerClothes::m_bStaticInit = true; -bool CClientPlayerClothes::m_bHasClothesChanged = false; +SFixedArray CClientPlayerClothes::m_GlobalClothes; +SFixedArray, PLAYER_CLOTHING_SLOTS> CClientPlayerClothes::m_NewClothes; +bool CClientPlayerClothes::m_bStaticInit = true; +bool CClientPlayerClothes::m_bHasClothesChanged = false; CClientPlayerClothes::CClientPlayerClothes(CClientPed* pPlayerModel) { @@ -329,7 +462,7 @@ bool CClientPlayerClothes::HasEmptyClothing(unsigned char ucType) bool CClientPlayerClothes::IsEmptyClothing(const SPlayerClothing* pClothing, unsigned char ucType) { - if (!pClothing || ucType > 3) + if (!pClothing || ucType > 3) return false; const std::vector pGroup = GetClothingGroup(ucType); @@ -414,9 +547,8 @@ bool CClientPlayerClothes::AddClothingModel(const char* texture, const char* mod auto& clothes = m_NewClothes[clothingType]; - if (std::any_of(clothes.begin(), clothes.end(), [&](const SPlayerClothing& clothing) { - return !stricmp(texture, clothing.texture.c_str()) && !stricmp(model, clothing.model.c_str()); - })) + if (std::any_of(clothes.begin(), clothes.end(), [&](const SPlayerClothing& clothing) + { return !stricmp(texture, clothing.texture.c_str()) && !stricmp(model, clothing.model.c_str()); })) { return false; } @@ -437,9 +569,8 @@ bool CClientPlayerClothes::RemoveClothingModel(const char* texture, const char* auto& clothes = m_NewClothes[clothingType]; - auto it = std::find_if(clothes.begin(), clothes.end(),[&](const SPlayerClothing& clothing) { - return !stricmp(texture, clothing.texture.c_str()) && !stricmp(model, clothing.model.c_str()); - }); + auto it = std::find_if(clothes.begin(), clothes.end(), [&](const SPlayerClothing& clothing) + { return !stricmp(texture, clothing.texture.c_str()) && !stricmp(model, clothing.model.c_str()); }); if (it == clothes.end()) return false; @@ -462,49 +593,49 @@ void CClientPlayerClothes::RefreshClothes() { for (std::uint8_t clothingType = 0; clothingType < PLAYER_CLOTHING_SLOTS; clothingType++) { - auto& clothes = m_NewClothes[clothingType]; + auto& clothes = m_NewClothes[clothingType]; - if (clothes.empty() && !m_bHasClothesChanged) - continue; + if (clothes.empty() && !m_bHasClothesChanged) + continue; - bool hasInvalidClothing = false; - const SPlayerClothing* pCurrent = m_Clothes[clothingType]; + bool hasInvalidClothing = false; + const SPlayerClothing* pCurrent = m_Clothes[clothingType]; - if (!m_bHasClothesChanged) - { - for (auto clothing = clothes.begin(); clothing != clothes.end();) - { - std::string fileTXD = clothing->texture + ".txd"; - std::string fileDFF = clothing->model + ".dff"; + if (!m_bHasClothesChanged) + { + for (auto clothing = clothes.begin(); clothing != clothes.end();) + { + std::string fileTXD = clothing->texture + ".txd"; + std::string fileDFF = clothing->model + ".dff"; - if (!g_pGame->GetRenderWare()->HasClothesFile(fileTXD.c_str()) || !g_pGame->GetRenderWare()->HasClothesFile(fileDFF.c_str())) - { - if (pCurrent && (pCurrent->texture == clothing->texture || pCurrent->model == clothing->model)) - { + if (!g_pGame->GetRenderWare()->HasClothesFile(fileTXD.c_str()) || !g_pGame->GetRenderWare()->HasClothesFile(fileDFF.c_str())) + { + if (pCurrent && (pCurrent->texture == clothing->texture || pCurrent->model == clothing->model)) + { hasInvalidClothing = true; - } - - clothing = clothes.erase(clothing); - } - else - ++clothing; - } - } - - if (pCurrent && !hasInvalidClothing && m_bHasClothesChanged) - { - const SPlayerClothing* pClothing = GetClothing(pCurrent->texture.c_str(), pCurrent->model.c_str(), clothingType); - - if (!pClothing) - { - hasInvalidClothing = true; - } - } - - if (hasInvalidClothing) - { - RemoveClothes(clothingType, true); - } + } + + clothing = clothes.erase(clothing); + } + else + ++clothing; + } + } + + if (pCurrent && !hasInvalidClothing && m_bHasClothesChanged) + { + const SPlayerClothing* pClothing = GetClothing(pCurrent->texture.c_str(), pCurrent->model.c_str(), clothingType); + + if (!pClothing) + { + hasInvalidClothing = true; + } + } + + if (hasInvalidClothing) + { + RemoveClothes(clothingType, true); + } } m_bHasClothesChanged = false; diff --git a/Client/mods/deathmatch/logic/CClientPlayerClothes.h b/Client/mods/deathmatch/logic/CClientPlayerClothes.h index f01e3433fba..0f8e8e8ce6f 100644 --- a/Client/mods/deathmatch/logic/CClientPlayerClothes.h +++ b/Client/mods/deathmatch/logic/CClientPlayerClothes.h @@ -12,25 +12,25 @@ class CClientPlayerClothes; #pragma once -#define PLAYER_CLOTHING_SLOTS 18 -#define TORSO_CLOTHING_MAX 68 -#define HAIR_CLOTHING_MAX 33 -#define LEGS_CLOTHING_MAX 45 -#define SHOES_CLOTHING_MAX 38 -#define LEFT_UPPER_ARM_CLOTHING_MAX 3 -#define LEFT_LOWER_ARM_CLOTHING_MAX 4 +#define PLAYER_CLOTHING_SLOTS 18 +#define TORSO_CLOTHING_MAX 68 +#define HAIR_CLOTHING_MAX 33 +#define LEGS_CLOTHING_MAX 45 +#define SHOES_CLOTHING_MAX 38 +#define LEFT_UPPER_ARM_CLOTHING_MAX 3 +#define LEFT_LOWER_ARM_CLOTHING_MAX 4 #define RIGHT_UPPER_ARM_CLOTHING_MAX 4 #define RIGHT_LOWER_ARM_CLOTHING_MAX 4 -#define BACK_TOP_CLOTHING_MAX 7 -#define LEFT_CHEST_CLOTHING_MAX 6 -#define RIGHT_CHEST_CLOTHING_MAX 7 -#define STOMACH_CLOTHING_MAX 7 -#define LOWER_BACK_CLOTHING_MAX 6 -#define EXTRA1_CLOTHING_MAX 12 -#define EXTRA2_CLOTHING_MAX 12 -#define EXTRA3_CLOTHING_MAX 17 -#define EXTRA4_CLOTHING_MAX 57 -#define SUIT_CLOTHING_MAX 9 +#define BACK_TOP_CLOTHING_MAX 7 +#define LEFT_CHEST_CLOTHING_MAX 6 +#define RIGHT_CHEST_CLOTHING_MAX 7 +#define STOMACH_CLOTHING_MAX 7 +#define LOWER_BACK_CLOTHING_MAX 6 +#define EXTRA1_CLOTHING_MAX 12 +#define EXTRA2_CLOTHING_MAX 12 +#define EXTRA3_CLOTHING_MAX 17 +#define EXTRA4_CLOTHING_MAX 57 +#define SUIT_CLOTHING_MAX 9 class CClientPed; @@ -67,11 +67,11 @@ class CClientPlayerClothes static bool IsEmptyClothing(const SPlayerClothing* pClothing, unsigned char ucType); static const char* GetClothingName(unsigned char ucType); - static std::vector GetClothingGroup(unsigned char ucType); - static bool IsValidModel(unsigned short usModel); - static bool HasClothesChanged(); - static bool AddClothingModel(const char* texture, const char* model, unsigned char clothingType); - static bool RemoveClothingModel(const char* texture, const char* model, unsigned char clothingType); + static std::vector GetClothingGroup(unsigned char ucType); + static bool IsValidModel(unsigned short usModel); + static bool HasClothesChanged(); + static bool AddClothingModel(const char* texture, const char* model, unsigned char clothingType); + static bool RemoveClothingModel(const char* texture, const char* model, unsigned char clothingType); private: static const SPlayerClothing* GetClothing(const char* szTexture, const char* szModel, unsigned char ucType); diff --git a/Client/mods/deathmatch/logic/CClientPlayerManager.cpp b/Client/mods/deathmatch/logic/CClientPlayerManager.cpp index f7e74f1cd36..84ec18407cb 100644 --- a/Client/mods/deathmatch/logic/CClientPlayerManager.cpp +++ b/Client/mods/deathmatch/logic/CClientPlayerManager.cpp @@ -178,12 +178,19 @@ bool CClientPlayerManager::IsPlayerLimitReached() bool CClientPlayerManager::IsValidModel(unsigned long ulModel) { - if (ulModel < static_cast(g_pGame->GetBaseIDforTXD())) - { - CModelInfo* pModelInfo = g_pGame->GetModelInfo(ulModel); - return pModelInfo && pModelInfo->IsPlayerModel(); - } - return false; + CModelInfo* pModelInfo = g_pGame->GetModelInfo(ulModel); + if (!pModelInfo || !pModelInfo->GetInterface()) + return false; + + // Custom models allocated via engineRequestModel have a parent ID + if (pModelInfo->GetParentID() != 0) + return pModelInfo->GetModelType() == eModelInfoType::PED; + + // Standard GTA models must be in valid range + if (ulModel >= static_cast(g_pGame->GetBaseIDforTXD())) + return false; + + return pModelInfo->IsPlayerModel(); } void CClientPlayerManager::ResetAll() diff --git a/Client/mods/deathmatch/logic/CClientPlayerVoice.cpp b/Client/mods/deathmatch/logic/CClientPlayerVoice.cpp index 295a53237d7..f4241200c5b 100644 --- a/Client/mods/deathmatch/logic/CClientPlayerVoice.cpp +++ b/Client/mods/deathmatch/logic/CClientPlayerVoice.cpp @@ -118,8 +118,11 @@ void CClientPlayerVoice::DoPulse() } } -void CClientPlayerVoice::DecodeAndBuffer(char* pBuffer, unsigned int bytesWritten) +void CClientPlayerVoice::DecodeAndBuffer(const unsigned char* voiceBuffer, unsigned int voiceBufferLength) { + if (!voiceBuffer || !voiceBufferLength || voiceBufferLength > 2048) + return; + m_Mutex.lock(); if (!m_bVoiceActive) @@ -143,7 +146,7 @@ void CClientPlayerVoice::DecodeAndBuffer(char* pBuffer, unsigned int bytesWritte SpeexBits speexBits; speex_bits_init(&speexBits); - speex_bits_read_from(&speexBits, (char*)(pBuffer), bytesWritten); + speex_bits_read_from(&speexBits, reinterpret_cast(voiceBuffer), voiceBufferLength); speex_decode_int(m_pSpeexDecoderState, &speexBits, (spx_int16_t*)pTempBuffer); speex_bits_destroy(&speexBits); @@ -443,14 +446,14 @@ void CClientPlayerVoice::SetPaused(bool bPaused) { // call onClientPlayerVoicePause CLuaArguments Arguments; - Arguments.PushString("paused"); // Reason + Arguments.PushString("paused"); // Reason m_pPlayer->CallEvent("onClientPlayerVoicePause", Arguments, false); } else { // call onClientPlayerVoiceResumed CLuaArguments Arguments; - Arguments.PushString("resumed"); // Reason + Arguments.PushString("resumed"); // Reason m_pPlayer->CallEvent("onClientPlayerVoiceResumed", Arguments, false); } } diff --git a/Client/mods/deathmatch/logic/CClientPlayerVoice.h b/Client/mods/deathmatch/logic/CClientPlayerVoice.h index 8ce78bd5aaa..092958b27ad 100644 --- a/Client/mods/deathmatch/logic/CClientPlayerVoice.h +++ b/Client/mods/deathmatch/logic/CClientPlayerVoice.h @@ -28,13 +28,13 @@ class CClientPlayerVoice ZERO_ON_NEW CClientPlayerVoice(CClientPlayer* pPlayer, CVoiceRecorder* pVoiceRecorder); ~CClientPlayerVoice(); - void DecodeAndBuffer(char* pBuffer, unsigned int bytesWritten); + void DecodeAndBuffer(const unsigned char* voiceBuffer, unsigned int voiceBufferLength); void DoPulse(); bool m_bVoiceActive; std::list m_EventQueue; - std::mutex m_Mutex; // Only for m_EventQueue and m_bVoiceActive + std::mutex m_Mutex; // Only for m_EventQueue and m_bVoiceActive void GetTempoValues(float& fSampleRate, float& fTempo, float& fPitch, bool& bReverse) { diff --git a/Client/mods/deathmatch/logic/CClientRadarArea.cpp b/Client/mods/deathmatch/logic/CClientRadarArea.cpp index 903ccc49927..0c958ab1947 100644 --- a/Client/mods/deathmatch/logic/CClientRadarArea.cpp +++ b/Client/mods/deathmatch/logic/CClientRadarArea.cpp @@ -48,7 +48,7 @@ void CClientRadarArea::DoPulse() void CClientRadarArea::DoPulse(bool bRender) { - #define RADAR_FLASH_CYCLETIME 1000 +#define RADAR_FLASH_CYCLETIME 1000 // Suppose to show? if (m_bStreamedIn) diff --git a/Client/mods/deathmatch/logic/CClientRadarMarkerManager.cpp b/Client/mods/deathmatch/logic/CClientRadarMarkerManager.cpp index d7273e96a01..e7f00c96cf0 100644 --- a/Client/mods/deathmatch/logic/CClientRadarMarkerManager.cpp +++ b/Client/mods/deathmatch/logic/CClientRadarMarkerManager.cpp @@ -120,4 +120,4 @@ void CClientRadarMarkerManager::OrderMarkers() bool CClientRadarMarkerManager::CompareOrderingIndex(CClientRadarMarker* p1, CClientRadarMarker* p2) { return p1->GetOrdering() < p2->GetOrdering(); -} \ No newline at end of file +} diff --git a/Client/mods/deathmatch/logic/CClientSearchLight.cpp b/Client/mods/deathmatch/logic/CClientSearchLight.cpp index a6d6c714936..deece435bb1 100644 --- a/Client/mods/deathmatch/logic/CClientSearchLight.cpp +++ b/Client/mods/deathmatch/logic/CClientSearchLight.cpp @@ -33,5 +33,5 @@ void CClientSearchLight::Render() DoAttaching(); if (IsStreamedIn()) - g_pGame->GetPointLights()->RenderHeliLight(m_StartPosition, m_EndPosition, m_StartRadius, m_EndRadius, m_bRenderSpot); + g_pGame->GetPointLights()->RenderHeliLight(m_StartPosition, m_EndPosition, m_StartRadius, m_EndRadius, m_bRenderSpot, m_color); } diff --git a/Client/mods/deathmatch/logic/CClientSearchLight.h b/Client/mods/deathmatch/logic/CClientSearchLight.h index 1550aacc750..54c7043eea5 100644 --- a/Client/mods/deathmatch/logic/CClientSearchLight.h +++ b/Client/mods/deathmatch/logic/CClientSearchLight.h @@ -25,7 +25,7 @@ class CClientSearchLight final : public CClientStreamElement eClientEntityType GetType() const { return CCLIENTSEARCHLIGHT; } // CClientEntity methods - virtual void GetPosition(CVector& vecPosition) const override { vecPosition = m_StartPosition; } // required for streaming + virtual void GetPosition(CVector& vecPosition) const override { vecPosition = m_StartPosition; } // required for streaming virtual void SetPosition(const CVector& vecPosition) override {} // CClientStreamElement methods @@ -53,6 +53,9 @@ class CClientSearchLight final : public CClientStreamElement bool GetRenderSpot() const { return m_bRenderSpot; } void SetRenderSpot(bool renderSpot) { m_bRenderSpot = renderSpot; } + SColor GetColor() const noexcept { return m_color; } + void SetColor(const SColor& color) noexcept { m_color = color; } + protected: void Render(); @@ -63,4 +66,5 @@ class CClientSearchLight final : public CClientStreamElement float m_StartRadius; float m_EndRadius; bool m_bRenderSpot; + SColor m_color{SColorRGBA(200, 200, 255, 0)}; }; diff --git a/Client/mods/deathmatch/logic/CClientSound.cpp b/Client/mods/deathmatch/logic/CClientSound.cpp index 052071a97a9..2e3c3174be0 100644 --- a/Client/mods/deathmatch/logic/CClientSound.cpp +++ b/Client/mods/deathmatch/logic/CClientSound.cpp @@ -9,6 +9,8 @@ #include #include "CBassAudio.h" +#include +#include CClientSound::CClientSound(CClientManager* pManager, ElementID ID) : ClassInit(this), CClientEntity(ID) { @@ -25,8 +27,9 @@ CClientSound::CClientSound(CClientManager* pManager, ElementID ID) : ClassInit(t m_fPlaybackSpeed = 1.0f; m_bPan = true; m_fPan = 0.0f; + m_bThrottle = false; - m_pBuffer = nullptr; + m_uiBufferLength = 0; m_uiFrameNumberCreated = g_pClientGame->GetFrameCount(); } @@ -35,8 +38,37 @@ CClientSound::~CClientSound() Destroy(); m_pSoundManager->RemoveFromList(this); - delete m_pBuffer; - m_pBuffer = NULL; + ReleaseBuffer(); +} + +void CClientSound::ReleaseBuffer() +{ + if (!m_Buffer) + return; + + m_Buffer.reset(); + m_uiBufferLength = 0; +} + +// Pull an existing audio buffer so it's owned by the sound; pass the matching deleter so we can release it safely later. +void CClientSound::AdoptBuffer(void* pMemory, unsigned int uiLength, AudioBufferDeleter deleter) +{ + if (!pMemory || uiLength == 0) + { + ReleaseBuffer(); + return; + } + + // Always release the old buffer before adopting a new one, even if the pointer is the same + // This prevents deleter mismatch issues (e.g., mixing new[]/delete[] with malloc/free) + if (m_Buffer) + { + ReleaseBuffer(); + } + + m_Buffer = BufferPtr(pMemory, std::move(deleter)); + m_uiBufferLength = uiLength; + m_strPath.clear(); } //////////////////////////////////////////////////////////// @@ -112,16 +144,20 @@ bool CClientSound::Create() return false; // Initial state - if (!m_pBuffer) + if (!m_Buffer) m_pAudio = new CBassAudio(m_bStream, m_strPath, m_bLoop, m_bThrottle, m_b3D); else - m_pAudio = new CBassAudio(m_pBuffer, m_uiBufferLength, m_bLoop, m_b3D); + m_pAudio = new CBassAudio(m_Buffer.get(), m_uiBufferLength, m_bLoop, m_b3D); m_bDoneCreate = true; // Load file/start connect if (!m_pAudio->BeginLoadingMedia()) + { + m_pAudio->Destroy(); + m_pAudio = nullptr; return false; + } // Get and save length m_dLength = m_pAudio->GetLength(); @@ -230,10 +266,13 @@ bool CClientSound::Play(const SString& strPath, bool bLoop) { assert(m_strPath.empty()); + ReleaseBuffer(); + m_bStream = false; m_b3D = false; m_strPath = strPath; m_bLoop = bLoop; + m_bThrottle = false; m_bPan = false; // Instant distance-stream in @@ -246,9 +285,9 @@ bool CClientSound::Play(void* pMemory, unsigned int uiLength, bool bLoop) m_bStream = false; m_b3D = false; - m_pBuffer = pMemory; - m_uiBufferLength = uiLength; + AdoptBuffer(pMemory, uiLength, AudioBufferDeleter::ForNewArray()); m_bLoop = bLoop; + m_bThrottle = false; m_bPan = false; // Instant distance-stream in @@ -259,10 +298,13 @@ bool CClientSound::Play3D(const SString& strPath, bool bLoop) { assert(m_strPath.empty()); + ReleaseBuffer(); + m_bStream = false; m_b3D = true; m_strPath = strPath; m_bLoop = bLoop; + m_bThrottle = false; BeginSimulationOfPlayPosition(); @@ -273,9 +315,9 @@ bool CClientSound::Play3D(void* pMemory, unsigned int uiLength, bool bLoop) { m_bStream = false; m_b3D = true; - m_pBuffer = pMemory; - m_uiBufferLength = uiLength; + AdoptBuffer(pMemory, uiLength, AudioBufferDeleter::ForNewArray()); m_bLoop = bLoop; + m_bThrottle = false; BeginSimulationOfPlayPosition(); @@ -286,6 +328,8 @@ void CClientSound::PlayStream(const SString& strURL, bool bLoop, bool bThrottle, { assert(m_strPath.empty()); + ReleaseBuffer(); + m_bStream = true; m_b3D = b3D; m_strPath = strURL; @@ -344,7 +388,7 @@ double CClientSound::GetLength(bool bAvoidLoad) { // Not loaded by this entity yet -#if 0 // TODO +#if 0 // TODO if ( bAvoidLoad ) { // Caller wants to avoid loading the file to find out the length, @@ -464,14 +508,14 @@ void CClientSound::SetPaused(bool bPaused) { // call onClientSoundStopped CLuaArguments Arguments; - Arguments.PushString("paused"); // Reason + Arguments.PushString("paused"); // Reason this->CallEvent("onClientSoundStopped", Arguments, false); } else { // call onClientSoundStarted CLuaArguments Arguments; - Arguments.PushString("resumed"); // Reason + Arguments.PushString("resumed"); // Reason this->CallEvent("onClientSoundStarted", Arguments, false); } } @@ -712,7 +756,7 @@ void CClientSound::Process3D(const CVector& vecPlayerPosition, const CVector& ve if (Create()) { CLuaArguments Arguments; - Arguments.PushString("enabled"); // Reason + Arguments.PushString("enabled"); // Reason CallEvent("onClientSoundStarted", Arguments, false); } } @@ -722,7 +766,7 @@ void CClientSound::Process3D(const CVector& vecPlayerPosition, const CVector& ve { Destroy(); CLuaArguments Arguments; - Arguments.PushString("disabled"); // Reason + Arguments.PushString("disabled"); // Reason CallEvent("onClientSoundStopped", Arguments, false); } } diff --git a/Client/mods/deathmatch/logic/CClientSound.h b/Client/mods/deathmatch/logic/CClientSound.h index e3d082deb0b..db7843a850c 100644 --- a/Client/mods/deathmatch/logic/CClientSound.h +++ b/Client/mods/deathmatch/logic/CClientSound.h @@ -13,6 +13,9 @@ class CBassAudio; #pragma once +#include +#include +#include #include "CClientSoundManager.h" #include "CClientEntity.h" #include "CSimulatedPlayPosition.h" @@ -86,7 +89,7 @@ class CClientSound final : public CClientEntity bool SetFxEffectParameters(uint uiFxEffect, void* params); bool GetFxEffectParameters(uint uiFxEffect, void* params); - void Unlink(){}; + void Unlink() {}; bool IsSoundStopped() { return m_pAudio == NULL; } bool IsFinished(); @@ -104,6 +107,37 @@ class CClientSound final : public CClientEntity void Destroy(); private: + struct AudioBufferDeleter + { + using DeleterFn = void (*)(void*) noexcept; + + AudioBufferDeleter() noexcept = default; + explicit AudioBufferDeleter(DeleterFn fn) noexcept { Set(fn); } + + void operator()(void* ptr) const noexcept + { + if (ptr) + m_Deleter(ptr); + } + + void Set(DeleterFn fn) noexcept { m_Deleter = fn ? fn : &DeleteArrayImpl; } + + static AudioBufferDeleter ForNewArray() noexcept { return AudioBufferDeleter(&DeleteArrayImpl); } + static AudioBufferDeleter ForMalloc() noexcept { return AudioBufferDeleter(&FreeImpl); } + static AudioBufferDeleter ForExternalReference() noexcept { return AudioBufferDeleter(&NoopImpl); } + + private: + static void DeleteArrayImpl(void* ptr) noexcept { delete[] static_cast(ptr); } + static void FreeImpl(void* ptr) noexcept { std::free(ptr); } + static void NoopImpl(void*) noexcept {} + + DeleterFn m_Deleter = &DeleteArrayImpl; + }; + using BufferPtr = std::unique_ptr; + + void ReleaseBuffer(); + void AdoptBuffer(void* pMemory, unsigned int uiLength, AudioBufferDeleter deleter = {}); + CClientSoundManager* m_pSoundManager; CSimulatedPlayPosition m_SimulatedPlayPosition; CBassAudio* m_pAudio; @@ -114,7 +148,7 @@ class CClientSound final : public CClientEntity SString m_strPath; bool m_bLoop; bool m_bThrottle; - void* m_pBuffer; + BufferPtr m_Buffer; unsigned int m_uiBufferLength; // Info diff --git a/Client/mods/deathmatch/logic/CClientSoundManager.cpp b/Client/mods/deathmatch/logic/CClientSoundManager.cpp index 65f0e52b563..3f8c42d8a0c 100644 --- a/Client/mods/deathmatch/logic/CClientSoundManager.cpp +++ b/Client/mods/deathmatch/logic/CClientSoundManager.cpp @@ -42,7 +42,8 @@ CClientSoundManager::CClientSoundManager(CClientManager* pClientManager) g_pCore->GetConsole()->Printf("BASS ERROR %d in PluginLoad WEBM", BASS_ErrorGetCode()); BASS_SetConfig(BASS_CONFIG_NET_PREBUF, 0); - BASS_SetConfig(BASS_CONFIG_NET_PLAYLIST, 1); // Allow playlists + BASS_SetConfig(BASS_CONFIG_NET_PLAYLIST, 1); // Allow playlists + BASS_SetConfig(BASS_CONFIG_NET_TIMEOUT, 15000); m_strUserAgent = SString("MTA:SA Server %s - See http://mtasa.com/agent/", g_pNet->GetConnectedServer(true)); BASS_SetConfigPtr(BASS_CONFIG_NET_AGENT, (void*)*m_strUserAgent); @@ -69,8 +70,18 @@ CClientSoundManager::CClientSoundManager(CClientManager* pClientManager) CClientSoundManager::~CClientSoundManager() { ProcessStopQueues(true); + + // Signal stream threads to exit as soon as their blocking call returns + SignalStreamingThreadsToStop(); + + // Stopping and freeing BASS should lead any pending BASS_StreamCreateURL to abort/return. + // This makes threads exit quickly BASS_Stop(); BASS_Free(); + + // Now wait for threads to finish - they should exit almost immediately since BASS was freed. + // Use a short timeout since the blocking call should have been interrupted. + WaitForAllStreamingThreads(3000); } void CClientSoundManager::DoPulse() @@ -112,7 +123,7 @@ void CClientSoundManager::DoPulse() { // call onClientSoundStopped CLuaArguments Arguments; - Arguments.PushString("finished"); // Reason + Arguments.PushString("finished"); // Reason pSound->CallEvent("onClientSoundStopped", Arguments, false); g_pClientGame->GetElementDeleter()->Delete(pSound); } @@ -141,6 +152,7 @@ CClientSound* CClientSoundManager::PlaySound2D(const SString& strSound, bool bIs memcpy(pMemory, strSound.data(), size); if (pSound->Play((void*)pMemory, size, bLoop)) return pSound; + // Note: pMemory is already owned by pSound via AdoptBuffer, don't delete it here } else if (pSound->Play(strSound, bLoop)) return pSound; @@ -180,6 +192,7 @@ CClientSound* CClientSoundManager::PlaySound3D(const SString& strSound, bool bIs pSound->SetPosition(vecPosition); return pSound; } + // Note: pMemory is already owned by pSound via AdoptBuffer, don't delete it here } else if (pSound->Play3D(strSound, bLoop)) { @@ -431,7 +444,7 @@ void CClientSoundManager::ProcessStopQueues(bool bFlush) { if (iter->second.Get() > 100 || bFlush) { - delete iter->first; // This will cause BASS_ChannelStop + delete iter->first; // This will cause BASS_ChannelStop m_AudioStopQueue.erase(iter++); } else diff --git a/Client/mods/deathmatch/logic/CClientSpatialDatabase.cpp b/Client/mods/deathmatch/logic/CClientSpatialDatabase.cpp index 1babdac2769..844725fdce3 100644 --- a/Client/mods/deathmatch/logic/CClientSpatialDatabase.cpp +++ b/Client/mods/deathmatch/logic/CClientSpatialDatabase.cpp @@ -209,7 +209,7 @@ bool CClientSpatialDatabaseImpl::IsValidSphere(const CSphere& sphere) return false; // Check radius within limits - if (sphere.fRadius < -12000 || sphere.fRadius > 12000) // radius = sqrt(worldlimits*worldlimits + worldlimits*worldlimits) + if (sphere.fRadius < -12000 || sphere.fRadius > 12000) // radius = sqrt(worldlimits*worldlimits + worldlimits*worldlimits) return false; // Check position within limits diff --git a/Client/mods/deathmatch/logic/CClientSpatialDatabase.h b/Client/mods/deathmatch/logic/CClientSpatialDatabase.h index 053e3af2c26..60171ba5b10 100644 --- a/Client/mods/deathmatch/logic/CClientSpatialDatabase.h +++ b/Client/mods/deathmatch/logic/CClientSpatialDatabase.h @@ -13,7 +13,7 @@ class CClientEntity; #pragma once // Bounding sphere z position for 2d objects -#define SPATIAL_2D_Z 0 +#define SPATIAL_2D_Z 0 // Result of a Query class CClientEntityResult : public std::vector diff --git a/Client/mods/deathmatch/logic/CClientStreamElement.cpp b/Client/mods/deathmatch/logic/CClientStreamElement.cpp index b883eb0ec7e..6082703cf98 100644 --- a/Client/mods/deathmatch/logic/CClientStreamElement.cpp +++ b/Client/mods/deathmatch/logic/CClientStreamElement.cpp @@ -20,6 +20,7 @@ CClientStreamElement::CClientStreamElement(CClientStreamer* pStreamer, ElementID m_fExpDistance = 0.0f; m_bStreamedIn = false; m_bAttemptingToStreamIn = false; + m_lastStreamOutTime = 0u; m_usStreamReferences = 0; m_usStreamReferencesScript = 0; m_pStreamer->AddElement(this); @@ -67,6 +68,7 @@ void CClientStreamElement::InternalStreamOut() { StreamOut(); m_bStreamedIn = false; + m_lastStreamOutTime = static_cast(CClientTime::GetTime()); // Stream out attached elements CClientObject* thisObject = DynamicCast(this); diff --git a/Client/mods/deathmatch/logic/CClientStreamElement.h b/Client/mods/deathmatch/logic/CClientStreamElement.h index eb3ae101d17..c32a5c7d6bc 100644 --- a/Client/mods/deathmatch/logic/CClientStreamElement.h +++ b/Client/mods/deathmatch/logic/CClientStreamElement.h @@ -11,6 +11,7 @@ #pragma once #include "CClientEntity.h" +#include class CClientStreamer; class CClientStreamSector; class CClientStreamSectorRow; @@ -39,6 +40,7 @@ class CClientStreamElement : public CClientEntity void RemoveStreamReference(bool bScript = false); unsigned short GetStreamReferences(bool bScript = false); unsigned long GetTotalStreamReferences() { return m_usStreamReferences + m_usStreamReferencesScript; } + std::uint32_t GetLastStreamOutTime() const { return m_lastStreamOutTime; } void StreamOutForABit(); void SetDimension(unsigned short usDimension) override; float GetExpDistance() { return m_fExpDistance; } @@ -53,7 +55,7 @@ class CClientStreamElement : public CClientEntity void SetStreamRow(CClientStreamSectorRow* pRow) { m_pStreamRow = pRow; } void SetStreamSector(CClientStreamSector* pSector) { m_pStreamSector = pSector; } void SetExpDistance(float fDistance) { m_fExpDistance = fDistance; } - + CClientStreamSectorRow* m_pStreamRow; CClientStreamSector* m_pStreamSector; CVector m_vecStreamPosition; @@ -61,9 +63,10 @@ class CClientStreamElement : public CClientEntity unsigned short m_usStreamReferences, m_usStreamReferencesScript; protected: - CClientStreamer* m_pStreamer; - bool m_bStreamedIn; - bool m_bAttemptingToStreamIn; + CClientStreamer* m_pStreamer; + bool m_bStreamedIn; + bool m_bAttemptingToStreamIn; + std::uint32_t m_lastStreamOutTime; public: float m_fCachedRadius; diff --git a/Client/mods/deathmatch/logic/CClientStreamSector.cpp b/Client/mods/deathmatch/logic/CClientStreamSector.cpp index 39a2f38c7b1..0da28517ebf 100644 --- a/Client/mods/deathmatch/logic/CClientStreamSector.cpp +++ b/Client/mods/deathmatch/logic/CClientStreamSector.cpp @@ -137,24 +137,32 @@ void CClientStreamSector::CompareSurroundings(CClientStreamSector* pSector, list } } -void CClientStreamSector::AddElements(list* pList) +void CClientStreamSector::AddElements(list* pList, std::unordered_set* pSet) { list::iterator iter = m_Elements.begin(); for (; iter != m_Elements.end(); iter++) { - // Don't add if already in the list - if (ListContains(*pList, *iter)) + // Don't add if already in the list (O(1) if set provided) + if (pSet) + { + if (pSet->count(*iter)) + continue; + pSet->insert(*iter); + } + else if (ListContains(*pList, *iter)) continue; pList->push_back(*iter); } } -void CClientStreamSector::RemoveElements(list* pList) +void CClientStreamSector::RemoveElements(list* pList, std::unordered_set* pSet) { list::iterator iter = m_Elements.begin(); for (; iter != m_Elements.end(); iter++) { pList->remove(*iter); + if (pSet) + pSet->erase(*iter); } -} \ No newline at end of file +} diff --git a/Client/mods/deathmatch/logic/CClientStreamSector.h b/Client/mods/deathmatch/logic/CClientStreamSector.h index 10bd3db2f3a..2e0706c3b0c 100644 --- a/Client/mods/deathmatch/logic/CClientStreamSector.h +++ b/Client/mods/deathmatch/logic/CClientStreamSector.h @@ -11,6 +11,7 @@ #pragma once #include +#include #include "CClientCommon.h" class CClientStreamer; @@ -38,8 +39,8 @@ class CClientStreamSector std::list::iterator Begin() { return m_Elements.begin(); } std::list::iterator End() { return m_Elements.end(); } - void AddElements(std::list* pList); - void RemoveElements(std::list* pList); + void AddElements(std::list* pList, std::unordered_set* pSet = nullptr); + void RemoveElements(std::list* pList, std::unordered_set* pSet = nullptr); unsigned int CountElements() { return m_Elements.size(); } CClientStreamSectorRow* GetRow() { return m_pRow; } diff --git a/Client/mods/deathmatch/logic/CClientStreamSectorRow.cpp b/Client/mods/deathmatch/logic/CClientStreamSectorRow.cpp index bf74f0debc8..31c92de1e46 100644 --- a/Client/mods/deathmatch/logic/CClientStreamSectorRow.cpp +++ b/Client/mods/deathmatch/logic/CClientStreamSectorRow.cpp @@ -133,4 +133,4 @@ void CClientStreamSectorRow::ConnectSector(CClientStreamSector* pSector) pSector->m_pTop->m_pBottom = pSector; if (pSector->m_pBottom) pSector->m_pBottom->m_pTop = pSector; -} \ No newline at end of file +} diff --git a/Client/mods/deathmatch/logic/CClientStreamSectorRow.h b/Client/mods/deathmatch/logic/CClientStreamSectorRow.h index 0fa26750fa4..024f44906a3 100644 --- a/Client/mods/deathmatch/logic/CClientStreamSectorRow.h +++ b/Client/mods/deathmatch/logic/CClientStreamSectorRow.h @@ -10,7 +10,7 @@ #pragma once -#define WORLD_SIZE 6000.0f // was 3000.0f +#define WORLD_SIZE 6000.0f // was 3000.0f #include "CClientCommon.h" #include diff --git a/Client/mods/deathmatch/logic/CClientStreamer.cpp b/Client/mods/deathmatch/logic/CClientStreamer.cpp index e0aff6d3527..12460430ad8 100644 --- a/Client/mods/deathmatch/logic/CClientStreamer.cpp +++ b/Client/mods/deathmatch/logic/CClientStreamer.cpp @@ -9,6 +9,7 @@ *****************************************************************************/ #include "StdInc.h" +#include using std::list; void* CClientStreamer::pAddingElement = NULL; @@ -26,7 +27,10 @@ CClientStreamer::CClientStreamer(StreamerLimitReachedFunction* pLimitReachedFunc m_pLimitReachedFunc = pLimitReachedFunc; // Create our main world sectors covering the mainland - CreateSectors(&m_WorldRows, CVector2D(m_fSectorSize, m_fRowSize), CVector2D(-WORLD_SIZE, -WORLD_SIZE), CVector2D(WORLD_SIZE, WORLD_SIZE)); + CVector2D size(m_fSectorSize, m_fRowSize); + CVector2D bottomLeft(-WORLD_SIZE, -WORLD_SIZE); + CVector2D topRight(WORLD_SIZE, WORLD_SIZE); + CreateSectors(&m_WorldRows, size, bottomLeft, topRight); // Find our row and sector m_pRow = FindOrCreateRow(m_vecPosition); @@ -45,43 +49,52 @@ CClientStreamer::~CClientStreamer() m_WorldRows.clear(); // Clear our extra rows - iter = m_ExtraRows.begin(); - for (; iter != m_ExtraRows.end(); iter++) + for (auto& [key, pRow] : m_ExtraRows) { - delete *iter; + delete pRow; } m_ExtraRows.clear(); } -void CClientStreamer::CreateSectors(list* pList, CVector2D& vecSize, CVector2D& vecBottomLeft, CVector2D& vecTopRight) +void CClientStreamer::CreateSectors(std::list* pList, CVector2D& vecSize, CVector2D& vecBottomLeft, CVector2D& vecTopRight) { // Creates our sectors within rows, filling up our rectangle, connecting each sector and row CClientStreamSector * pCurrent = NULL, *pPrevious = NULL, *pPreviousRowSector = NULL; CClientStreamSectorRow *pCurrentRow = NULL, *pPreviousRow = NULL; float fX = vecBottomLeft.fX, fY = vecBottomLeft.fY; + while (fY < vecTopRight.fY) { pCurrentRow = new CClientStreamSectorRow(fY, fY + vecSize.fY, m_fSectorSize, m_fRowSize); - pList->push_back(pCurrentRow); pCurrentRow->m_pBottom = pPreviousRow; + pList->push_back(pCurrentRow); + if (pPreviousRow) pPreviousRow->m_pTop = pCurrentRow; + while (fX < vecTopRight.fX) { + CVector2D bottomLeft(fX, fY); + CVector2D topRight(fX + vecSize.fX, fY + vecSize.fY); + pPrevious = pCurrent; - pCurrent = new CClientStreamSector(pCurrentRow, CVector2D(fX, fY), CVector2D(fX + vecSize.fX, fY + vecSize.fY)); + pCurrent = new CClientStreamSector(pCurrentRow, bottomLeft, topRight); pCurrentRow->Add(pCurrent); pCurrent->m_pLeft = pPrevious; + if (pPrevious) pPrevious->m_pRight = pCurrent; + if (pPreviousRowSector) { pCurrent->m_pBottom = pPreviousRowSector; pPreviousRowSector->m_pTop = pCurrent; pPreviousRowSector = pPreviousRowSector->m_pRight; } + fX += vecSize.fX; } + pPrevious = NULL; pCurrent = NULL; pPreviousRow = pCurrentRow; @@ -231,24 +244,21 @@ CClientStreamSectorRow* CClientStreamer::FindOrCreateRow(CVector& vecPosition, C } } - // Search through our extra rows - iter = m_ExtraRows.begin(); - for (; iter != m_ExtraRows.end(); iter++) - { - pRow = *iter; - if (pRow->DoesContain(vecPosition)) - { - return pRow; - } - } - // We need a new row, align it with the others + // Search through our extra rows using map lookup float fBottom = float((int)(vecPosition.fY / m_fRowSize)) * m_fRowSize; if (vecPosition.fY < 0.0f) fBottom -= m_fRowSize; + int iRowIndex = (int)(fBottom / m_fRowSize); + + auto it = m_ExtraRows.find(iRowIndex); + if (it != m_ExtraRows.end()) + return it->second; + + // We need a new row, align it with the others pRow = new CClientStreamSectorRow(fBottom, fBottom + m_fRowSize, m_fSectorSize, m_fRowSize); ConnectRow(pRow); pRow->SetExtra(true); - m_ExtraRows.push_back(pRow); + m_ExtraRows[iRowIndex] = pRow; return pRow; } @@ -266,16 +276,16 @@ CClientStreamSectorRow* CClientStreamer::FindRow(float fY) } } - // Search through our extra rows - iter = m_ExtraRows.begin(); - for (; iter != m_ExtraRows.end(); iter++) - { - pRow = *iter; - if (pRow->DoesContain(fY)) - { - return pRow; - } - } + // Search through our extra rows using map lookup + float fBottom = float((int)(fY / m_fRowSize)) * m_fRowSize; + if (fY < 0.0f) + fBottom -= m_fRowSize; + int iRowIndex = (int)(fBottom / m_fRowSize); + + auto it = m_ExtraRows.find(iRowIndex); + if (it != m_ExtraRows.end()) + return it->second; + return NULL; } @@ -320,6 +330,7 @@ void CClientStreamer::RemoveElement(CClientStreamElement* pElement) { OnElementEnterSector(pElement, NULL); m_ActiveElements.remove(pElement); + m_ActiveElementSet.erase(pElement); m_ToStreamOut.remove(pElement); } @@ -342,27 +353,14 @@ void CClientStreamer::AddToSortedList(list* pList, CClien float fDistance = pElement->GetDistanceToBoundingBoxSquared(m_vecPosition); pElement->SetExpDistance(fDistance); - // Don't add if already in the list - if (ListContains(*pList, pElement)) + // Don't add if already in the list (O(1) check) + if (m_ActiveElementSet.count(pElement)) return; - // Search through our list. Add it behind the first item further away than this - CClientStreamElement* pTemp = NULL; - list::iterator iter = pList->begin(); - for (; iter != pList->end(); iter++) - { - pTemp = *iter; + // Track in the set + m_ActiveElementSet.insert(pElement); - // Is it further than the one we add? - if (pTemp->GetDistanceToBoundingBoxSquared(m_vecPosition) > fDistance) - { - // Add it before here - pList->insert(iter, pElement); - return; - } - } - - // We have no elements in the list, add it at the beginning + // Append unsorted - DoPulse sorts the list every frame via m_ActiveElements.sort() pList->push_back(pElement); } @@ -373,19 +371,17 @@ bool CClientStreamer::CompareExpDistance(CClientStreamElement* p1, CClientStream bool CClientStreamer::IsActiveElement(CClientStreamElement* pElement) { - list::iterator iter = m_ActiveElements.begin(); - for (; iter != m_ActiveElements.end(); iter++) - { - if (*iter == pElement) - { - return true; - } - } - return false; + return m_ActiveElementSet.count(pElement) > 0; } void CClientStreamer::Restream(bool bMovedFar) { + // Avoid swap ping-pong when two candidates are almost the same distance. + // Distances are squared, so compare against squared hysteresis too. + constexpr float swapHysteresisDistanceSq = 10.0f * 10.0f; + constexpr std::uint32_t minStreamInDelayAfterOutMs = 1200u; + const std::uint32_t currentTime = static_cast(CClientTime::GetTime()); + // Limit distance stream in/out rate // Vehicles might have to ignore this to reduce blocking loads elsewhere. int iMaxOut = 6; @@ -535,11 +531,15 @@ void CClientStreamer::Restream(bool bMovedFar) continue; } + // Prevent rapid in/out thrashing of the same element. + if (!bMovedFar && (currentTime - pElement->GetLastStreamOutTime()) < minStreamInDelayAfterOutMs) + continue; + // Not room to stream in more elements? if (bReachedLimit) { // Add to the list that might be streamed in during the final phase - if ((int)ClosestStreamedOutList.size() < iMaxIn) // (only add if there is a chance it will be used) + if ((int)ClosestStreamedOutList.size() < iMaxIn) // (only add if there is a chance it will be used) ClosestStreamedOutList.push_back(pElement); } else @@ -582,7 +582,7 @@ void CClientStreamer::Restream(bool bMovedFar) // See if ClosestStreamedOut is nearer than FurthestStreamedIn CClientStreamElement* pFurthestStreamedIn = FurthestStreamedInList[iFurthestStreamedInIndex]; CClientStreamElement* pClosestStreamedOut = ClosestStreamedOutList[uiClosestStreamedOutIndex]; - if (pClosestStreamedOut->GetExpDistance() >= pFurthestStreamedIn->GetExpDistance()) + if ((pClosestStreamedOut->GetExpDistance() + swapHysteresisDistanceSq) >= pFurthestStreamedIn->GetExpDistance()) break; // Stream out FurthestStreamedIn candidate if possible @@ -593,11 +593,14 @@ void CClientStreamer::Restream(bool bMovedFar) iMaxOut--; } m_ToStreamOut.remove(pFurthestStreamedIn); - iFurthestStreamedInIndex--; // Always advance to the next candidate + iFurthestStreamedInIndex--; // Always advance to the next candidate // Stream in ClosestStreamedOut candidate if possible if (!ReachedLimit()) { + if (!bMovedFar && (currentTime - pClosestStreamedOut->GetLastStreamOutTime()) < minStreamInDelayAfterOutMs) + continue; + // Stream in the new element. No need to do it instantly unless moved from far away. pClosestStreamedOut->InternalStreamIn(bMovedFar); iMaxIn--; @@ -637,7 +640,7 @@ void CClientStreamer::OnEnterSector(CClientStreamSector* pSector) m_ToStreamOut.push_back(pElement); } } - pTempSector->RemoveElements(&m_ActiveElements); + pTempSector->RemoveElements(&m_ActiveElements, &m_ActiveElementSet); pTempSector->SetActivated(false); } } @@ -653,7 +656,7 @@ void CClientStreamer::OnEnterSector(CClientStreamSector* pSector) pTempSector = *iter; if (!pTempSector->IsActivated()) { - pTempSector->AddElements(&m_ActiveElements); + pTempSector->AddElements(&m_ActiveElements, &m_ActiveElementSet); pTempSector->SetActivated(true); } } @@ -695,7 +698,7 @@ void CClientStreamer::OnElementEnterSector(CClientStreamElement* pElement, CClie // Should we activate this sector? if (pSector->IsExtra() && (m_pSector->IsMySurroundingSector(pSector) || m_pSector == pSector)) { - pSector->AddElements(&m_ActiveElements); + pSector->AddElements(&m_ActiveElements, &m_ActiveElementSet); pSector->SetActivated(true); } // If we're in a deactivated sector and streamed in, stream us out diff --git a/Client/mods/deathmatch/logic/CClientStreamer.h b/Client/mods/deathmatch/logic/CClientStreamer.h index 9e81fedbdfe..752b057d224 100644 --- a/Client/mods/deathmatch/logic/CClientStreamer.h +++ b/Client/mods/deathmatch/logic/CClientStreamer.h @@ -12,6 +12,8 @@ #include "CClientCommon.h" #include +#include +#include class CClientStreamSector; class CClientStreamSectorRow; class CClientStreamElement; @@ -35,7 +37,7 @@ class CClientStreamer std::list::iterator ActiveElementsBegin() { return m_ActiveElements.begin(); } std::list::iterator ActiveElementsEnd() { return m_ActiveElements.end(); } - std::uint16_t GetDimension() const noexcept { return m_usDimension; } + std::uint16_t GetDimension() const noexcept { return m_usDimension; } private: void CreateSectors(std::list* pList, CVector2D& vecSize, CVector2D& vecBottomLeft, CVector2D& vecTopRight); @@ -61,19 +63,20 @@ class CClientStreamer void OnElementForceStreamOut(CClientStreamElement* pElement); void OnElementDimension(CClientStreamElement* pElement); - const float m_fSectorSize; - const float m_fRowSize; - float m_fMaxDistanceExp; - float m_fMaxDistanceThreshold; - StreamerLimitReachedFunction* m_pLimitReachedFunc; - std::list m_WorldRows; - std::list m_ExtraRows; - CClientStreamSectorRow* m_pRow; - CClientStreamSector* m_pSector; - CVector m_vecPosition; - unsigned short m_usDimension; - std::list m_ActiveElements; - std::list m_ToStreamOut; + const float m_fSectorSize; + const float m_fRowSize; + float m_fMaxDistanceExp; + float m_fMaxDistanceThreshold; + StreamerLimitReachedFunction* m_pLimitReachedFunc; + std::list m_WorldRows; + std::unordered_map m_ExtraRows; + CClientStreamSectorRow* m_pRow; + CClientStreamSector* m_pSector; + CVector m_vecPosition; + unsigned short m_usDimension; + std::list m_ActiveElements; + std::unordered_set m_ActiveElementSet; + std::list m_ToStreamOut; static void* pAddingElement; }; diff --git a/Client/mods/deathmatch/logic/CClientTXD.cpp b/Client/mods/deathmatch/logic/CClientTXD.cpp index b619586c917..a989b1910f4 100644 --- a/Client/mods/deathmatch/logic/CClientTXD.cpp +++ b/Client/mods/deathmatch/logic/CClientTXD.cpp @@ -10,6 +10,69 @@ #include +struct SPendingTxdImport +{ + CClientTXD* pTXD = nullptr; + unsigned short usModelId = 0; + uint32_t uiQueuedTick = 0; + uint8_t ucRetryCount = 0; +}; + +struct SPendingRenderWareImport +{ + CClientTXD* pTXD = nullptr; + unsigned short usModelId = 0; +}; + +static std::vector s_PendingTxdImports; +static std::vector s_PendingRenderWareImports; +static uint32_t s_uiLastPendingImportProcessTime = 0; +static uint32_t s_uiLastPendingImportDropLogTime = 0; + +constexpr std::size_t MAX_PENDING_RENDER_WARE_IMPORTS = 4096; + +static bool IsDeviceLossImportQueued(const CClientTXD* pTXD, unsigned short usModelID) +{ + for (const SPendingTxdImport& pendingTxdImport : s_PendingTxdImports) + { + if (pendingTxdImport.pTXD == pTXD && pendingTxdImport.usModelId == usModelID) + return true; + } + + return false; +} + +static bool IsRenderWareImportQueued(const CClientTXD* pTXD, unsigned short usModelID) +{ + for (const SPendingRenderWareImport& pendingRenderWareImport : s_PendingRenderWareImports) + { + if (pendingRenderWareImport.pTXD == pTXD && pendingRenderWareImport.usModelId == usModelID) + return true; + } + + return false; +} + +static void PrunePendingRenderWareImports() +{ + for (auto it = s_PendingRenderWareImports.begin(); it != s_PendingRenderWareImports.end();) + { + if (!it->pTXD || it->pTXD->IsBeingDeleted()) + { + it = s_PendingRenderWareImports.erase(it); + continue; + } + + if (!it->pTXD->HasPendingRenderWareImport(it->usModelId)) + { + it = s_PendingRenderWareImports.erase(it); + continue; + } + + ++it; + } +} + CClientTXD::CClientTXD(class CClientManager* pManager, ElementID ID) : ClassInit(this), CClientEntity(ID) { // Init @@ -19,13 +82,40 @@ CClientTXD::CClientTXD(class CClientManager* pManager, ElementID ID) : ClassInit CClientTXD::~CClientTXD() { - // Remove us from all the models + RemovePendingImports(); + + if (!g_pGame || !g_pGame->GetRenderWare()) + { + // RenderWare already destroyed (SA is unpredictable) + return; + } + + // During session shutdown (CClientManager being destroyed), element destruction + // order is arbitrary. Skip full cleanup which would access RW data that other + // elements' destructors may have already freed. Resource stop uses the full path + // below - CClientManager is still alive so full cleanup is safe. + if (m_pManager && m_pManager->IsBeingDeleted()) + { + g_pGame->GetRenderWare()->ModelInfoTXDDeferCleanup(&m_ReplacementTextures); + + // Remove clothes buffer references so OnCStreaming_RequestModel_Mid + // won't serve up our soon-to-be-freed m_FileData pointer + g_pGame->GetRenderWare()->ClothesRemoveReplacement(m_FileData.data()); + g_pGame->GetRenderWare()->ClothesRemoveFile(m_FileData.data()); + return; + } + g_pGame->GetRenderWare()->ModelInfoTXDRemoveTextures(&m_ReplacementTextures); - // Restream affected models - for (uint i = 0; i < m_ReplacementTextures.usedInModelIds.size(); i++) + // Restream all models that used our replacement textures. Don't filter by current + // TXD ID - if CClientDFF was destroyed before us, CleanupIsolatedTxdForModel may + // have moved the model back to its parent TXD, making the old TXD ID stale. + for (unsigned short modelId : m_ReplacementTextures.usedInModelIds) { - Restream(m_ReplacementTextures.usedInModelIds[i]); + CModelInfo* pModelInfo = g_pGame->GetModelInfo(modelId, true); + if (!pModelInfo || !pModelInfo->IsValid()) + continue; + Restream(modelId); } // Remove us from all the clothes replacement doo dah @@ -55,11 +145,19 @@ bool CClientTXD::Load(bool isRaw, SString input, bool enableFiltering) bool CClientTXD::AddClothingTexture(const std::string& modelName) { + m_strLastError.clear(); + if (modelName.empty()) + { + m_strLastError = "Model name is empty"; return false; + } if (m_FileData.empty() && m_bIsRawData) + { + m_strLastError = "Raw data buffer unavailable (texture was first used for non-clothes model)"; return false; + } if (m_FileData.empty()) { @@ -67,18 +165,70 @@ bool CClientTXD::AddClothingTexture(const std::string& modelName) if (!GetFilenameToUse(strUseFilename)) return false; if (!FileLoad(std::nothrow, strUseFilename, m_FileData)) + { + m_strLastError = SString("Failed to read file: %s", ExtractFilename(strUseFilename).c_str()); return false; + } + } + + if (!g_pGame->GetRenderWare()->ClothesAddFile(m_FileData.data(), m_FileData.size(), modelName.c_str())) + { + m_strLastError = SString("Failed to add clothing texture: %s", modelName.c_str()); + return false; } - return g_pGame->GetRenderWare()->ClothesAddFile(m_FileData.data(), m_FileData.size(), modelName.c_str()); + return true; } bool CClientTXD::Import(unsigned short usModelID) { + return ImportInternal(usModelID, true); +} + +bool CClientTXD::IsDeviceLost() const +{ + IDirect3DDevice9* pDevice = g_pCore ? g_pCore->GetGraphics()->GetDevice() : nullptr; + if (!pDevice) + return true; + + const HRESULT hr = pDevice->TestCooperativeLevel(); + return hr != D3D_OK; +} + +bool CClientTXD::HasPendingRenderWareImport(unsigned short usModelID) const +{ + std::unordered_set::const_iterator itPendingOnModel = m_ReplacementTextures.pendingOnModelIds.find(usModelID); + return itPendingOnModel != m_ReplacementTextures.pendingOnModelIds.end(); +} + +void CClientTXD::RemovePendingImports() +{ + if (!s_PendingTxdImports.empty()) + { + s_PendingTxdImports.erase( + std::remove_if(s_PendingTxdImports.begin(), s_PendingTxdImports.end(), [this](const SPendingTxdImport& entry) { return entry.pTXD == this; }), + s_PendingTxdImports.end()); + } + + if (!s_PendingRenderWareImports.empty()) + { + s_PendingRenderWareImports.erase(std::remove_if(s_PendingRenderWareImports.begin(), s_PendingRenderWareImports.end(), + [this](const SPendingRenderWareImport& entry) { return entry.pTXD == this; }), + s_PendingRenderWareImports.end()); + } +} + +bool CClientTXD::ImportInternal(unsigned short usModelID, bool bAllowQueue) +{ + m_strLastError.clear(); + if (usModelID >= CLOTHES_TEX_ID_FIRST && usModelID <= CLOTHES_TEX_ID_LAST) { if (m_FileData.empty() && m_bIsRawData) - return false; // Raw data has been freed already because texture was first used as non-clothes + { + m_strLastError = "Raw data buffer unavailable (texture was first used for non-clothes model)"; + return false; + } // If using for clothes only, unload 'replacing model textures' stuff to save memory if (!m_ReplacementTextures.textures.empty() && m_ReplacementTextures.usedInModelIds.empty()) @@ -92,10 +242,17 @@ bool CClientTXD::Import(unsigned short usModelID) SString strUseFilename; if (!GetFilenameToUse(strUseFilename)) + { + if (m_strLastError.empty()) + m_strLastError = SString("Cannot access file: %s", ExtractFilename(m_strFilename).c_str()); return false; + } if (!FileLoad(std::nothrow, strUseFilename, m_FileData)) + { + m_strLastError = SString("Failed to read file: %s", ExtractFilename(strUseFilename).c_str()); return false; + } } m_bUsingFileDataForClothes = true; // Note: ClothesAddReplacement uses the pointer from m_FileData, so don't touch m_FileData until matching ClothesRemove call @@ -111,16 +268,28 @@ bool CClientTXD::Import(unsigned short usModelID) { SString strUseFilename; if (!GetFilenameToUse(strUseFilename)) + { + if (m_strLastError.empty()) + m_strLastError = SString("Cannot access file for model %d: %s", usModelID, ExtractFilename(m_strFilename).c_str()); return false; - g_pGame->GetRenderWare()->ModelInfoTXDLoadTextures(&m_ReplacementTextures, strUseFilename, SString(), m_bFilteringEnabled); - if (m_ReplacementTextures.textures.empty()) + } + + if (!g_pGame->GetRenderWare()->ModelInfoTXDLoadTextures(&m_ReplacementTextures, strUseFilename, SString(), m_bFilteringEnabled, + &m_strLastError)) + { + if (m_strLastError.empty()) + m_strLastError = SString("Failed to load textures for model %d: %s", usModelID, ExtractFilename(strUseFilename).c_str()); return false; + } } else { - g_pGame->GetRenderWare()->ModelInfoTXDLoadTextures(&m_ReplacementTextures, NULL, m_FileData, m_bFilteringEnabled); - if (m_ReplacementTextures.textures.empty()) + if (!g_pGame->GetRenderWare()->ModelInfoTXDLoadTextures(&m_ReplacementTextures, SString(), m_FileData, m_bFilteringEnabled, &m_strLastError)) + { + if (m_strLastError.empty()) + m_strLastError = SString("Failed to load textures for model %d from buffer", usModelID); return false; + } } } @@ -131,17 +300,192 @@ bool CClientTXD::Import(unsigned short usModelID) SString().swap(m_FileData); } - // Have we got textures and haven't already imported into this model? if (g_pGame->GetRenderWare()->ModelInfoTXDAddTextures(&m_ReplacementTextures, usModelID)) { Restream(usModelID); return true; } + + const bool bRenderWareImportPending = HasPendingRenderWareImport(usModelID); + const bool bRenderWareImportQueued = IsRenderWareImportQueued(this, usModelID); + if (bAllowQueue && (bRenderWareImportPending || bRenderWareImportQueued)) + { + if (!bRenderWareImportQueued) + { + PrunePendingRenderWareImports(); + + if (s_PendingRenderWareImports.size() >= MAX_PENDING_RENDER_WARE_IMPORTS) + { + m_strLastError = SString("RenderWare deferred import queue is full for model %d", usModelID); + return false; + } + + SPendingRenderWareImport pendingRenderWareImport; + pendingRenderWareImport.pTXD = this; + pendingRenderWareImport.usModelId = usModelID; + s_PendingRenderWareImports.push_back(pendingRenderWareImport); + } + return true; + } + + if (bAllowQueue && IsDeviceLost()) + { + const std::size_t kMaxPendingImports = 2048; + const uint32_t uiNow = GetTickCount32(); + + if (IsDeviceLossImportQueued(this, usModelID)) + return true; + + if (s_PendingTxdImports.size() >= kMaxPendingImports) + { + const SPendingTxdImport& droppedTxdImport = s_PendingTxdImports.front(); + AddReportLog(9401, SString("Dropping device-loss TXD retry for model %u because the queue is full", droppedTxdImport.usModelId)); + s_PendingTxdImports.erase(s_PendingTxdImports.begin()); + if (uiNow - s_uiLastPendingImportDropLogTime >= 1000) + s_uiLastPendingImportDropLogTime = uiNow; + } + + SPendingTxdImport pendingTxdImport; + pendingTxdImport.pTXD = this; + pendingTxdImport.usModelId = usModelID; + pendingTxdImport.uiQueuedTick = uiNow; + pendingTxdImport.ucRetryCount = 0; + s_PendingTxdImports.push_back(pendingTxdImport); + return true; + } + + if (m_strLastError.empty()) + m_strLastError = SString("Failed to apply textures to model %d (texture import failed or was deferred)", usModelID); } return false; } +void CClientTXD::ProcessPendingImports() +{ + if (s_PendingTxdImports.empty() && s_PendingRenderWareImports.empty()) + return; + + const uint32_t uiNow = GetTickCount32(); + if (uiNow - s_uiLastPendingImportProcessTime < 250) + return; + + s_uiLastPendingImportProcessTime = uiNow; + + IDirect3DDevice9* pDevice = g_pCore ? g_pCore->GetGraphics()->GetDevice() : nullptr; + if (!pDevice) + return; + + const HRESULT hr = pDevice->TestCooperativeLevel(); + if (hr != D3D_OK) + { + // Device loss is a wait state, not a failed import attempt. + // Keep queued entries fresh so they are retried after recovery + // instead of aging out while no retry can run. + for (SPendingTxdImport& pendingTxdImport : s_PendingTxdImports) + pendingTxdImport.uiQueuedTick = uiNow; + return; + } + + const uint32_t kTimeoutMs = 30000; + const uint8_t kMaxRetries = 10; + + for (auto it = s_PendingTxdImports.begin(); it != s_PendingTxdImports.end();) + { + SPendingTxdImport& pendingTxdImport = *it; + if (!pendingTxdImport.pTXD || pendingTxdImport.pTXD->IsBeingDeleted()) + { + it = s_PendingTxdImports.erase(it); + continue; + } + + if (uiNow - pendingTxdImport.uiQueuedTick > kTimeoutMs || pendingTxdImport.ucRetryCount >= kMaxRetries) + { + AddReportLog(9401, SString("Dropping device-loss TXD retry for model %u after %u retries", pendingTxdImport.usModelId, + static_cast(pendingTxdImport.ucRetryCount))); + if (uiNow - s_uiLastPendingImportDropLogTime >= 1000) + s_uiLastPendingImportDropLogTime = uiNow; + it = s_PendingTxdImports.erase(it); + continue; + } + + if (pendingTxdImport.pTXD->ImportInternal(pendingTxdImport.usModelId, false)) + { + it = s_PendingTxdImports.erase(it); + continue; + } + + if (pendingTxdImport.pTXD->HasPendingRenderWareImport(pendingTxdImport.usModelId)) + { + if (!IsRenderWareImportQueued(pendingTxdImport.pTXD, pendingTxdImport.usModelId)) + { + PrunePendingRenderWareImports(); + + if (s_PendingRenderWareImports.size() >= MAX_PENDING_RENDER_WARE_IMPORTS) + { + ++it; + continue; + } + + SPendingRenderWareImport pendingRenderWareImport; + pendingRenderWareImport.pTXD = pendingTxdImport.pTXD; + pendingRenderWareImport.usModelId = pendingTxdImport.usModelId; + s_PendingRenderWareImports.push_back(pendingRenderWareImport); + } + + it = s_PendingTxdImports.erase(it); + continue; + } + + ++pendingTxdImport.ucRetryCount; + ++it; + } + + for (auto it = s_PendingRenderWareImports.begin(); it != s_PendingRenderWareImports.end();) + { + SPendingRenderWareImport& pendingRenderWareImport = *it; + if (!pendingRenderWareImport.pTXD || pendingRenderWareImport.pTXD->IsBeingDeleted()) + { + it = s_PendingRenderWareImports.erase(it); + continue; + } + + if (pendingRenderWareImport.pTXD->HasPendingRenderWareImport(pendingRenderWareImport.usModelId)) + { + ++it; + continue; + } + + if (pendingRenderWareImport.pTXD->ImportInternal(pendingRenderWareImport.usModelId, false)) + { + it = s_PendingRenderWareImports.erase(it); + continue; + } + + if (pendingRenderWareImport.pTXD->HasPendingRenderWareImport(pendingRenderWareImport.usModelId)) + { + ++it; + continue; + } + + SString strError = pendingRenderWareImport.pTXD->GetLastError(); + if (strError.empty()) + strError = SString("Deferred texture import failed for model %u", pendingRenderWareImport.usModelId); + + AddReportLog(9401, SString("Deferred TXD import failed for model %u: %s", pendingRenderWareImport.usModelId, strError.c_str())); + + it = s_PendingRenderWareImports.erase(it); + } +} + +void CClientTXD::ClearPendingImports() +{ + s_PendingTxdImports.clear(); + s_PendingRenderWareImports.clear(); + s_uiLastPendingImportProcessTime = 0; + s_uiLastPendingImportDropLogTime = 0; +} + bool CClientTXD::IsImportableModel(unsigned short usModelID) { // Currently we work on vehicles and objects @@ -152,23 +496,41 @@ bool CClientTXD::IsImportableModel(unsigned short usModelID) bool CClientTXD::LoadFromFile(SString filePath) { m_strFilename = std::move(filePath); + m_strLastError.clear(); SString strUseFilename; if (!GetFilenameToUse(strUseFilename)) + { + if (m_strLastError.empty()) + m_strLastError = SString("Invalid or inaccessible file: %s", ExtractFilename(m_strFilename).c_str()); return false; + } + + const bool ok = g_pGame->GetRenderWare()->ModelInfoTXDLoadTextures(&m_ReplacementTextures, strUseFilename, SString(), m_bFilteringEnabled, &m_strLastError); + if (!ok && m_strLastError.empty()) + m_strLastError = SString("Failed to load TXD: %s", ExtractFilename(m_strFilename).c_str()); - return g_pGame->GetRenderWare()->ModelInfoTXDLoadTextures(&m_ReplacementTextures, strUseFilename, SString(), m_bFilteringEnabled); + return ok; } bool CClientTXD::LoadFromBuffer(SString buffer) { + m_strLastError.clear(); + if (!g_pCore->GetNetwork()->CheckFile("txd", "", buffer.data(), buffer.size())) + { + m_strLastError = SString("TXD data rejected as invalid (%u bytes)", static_cast(buffer.size())); return false; + } m_FileData = std::move(buffer); - return g_pGame->GetRenderWare()->ModelInfoTXDLoadTextures(&m_ReplacementTextures, NULL, m_FileData, m_bFilteringEnabled); + const bool ok = g_pGame->GetRenderWare()->ModelInfoTXDLoadTextures(&m_ReplacementTextures, SString(), m_FileData, m_bFilteringEnabled, &m_strLastError); + if (!ok && m_strLastError.empty()) + m_strLastError = SString("Failed to load TXD from buffer (%u bytes)", static_cast(m_FileData.size())); + + return ok; } void CClientTXD::Restream(unsigned short usModelID) @@ -193,18 +555,143 @@ void CClientTXD::Restream(unsigned short usModelID) } } -// Return filename to use, or false if not valid bool CClientTXD::GetFilenameToUse(SString& strOutFilename) { - g_pClientGame->GetResourceManager()->ValidateResourceFile(m_strFilename, nullptr, 0); + if (!FileExists(m_strFilename)) + { + m_strLastError = SString("File not found: %s", ExtractFilename(m_strFilename).c_str()); + return false; + } + + CDownloadableResource* pResFile = nullptr; + bool bChecksumAlreadyValidated = false; + + static const CChecksum zeroChecksum; + + CChecksum serverChecksum; + bool bServerHasChecksum = false; + long long cachedFileSize = -1; + + if (g_pClientGame) + { + if (auto* pResMgr = g_pClientGame->GetResourceManager()) + { + SString strLookup = PathConform(m_strFilename).ToLower(); + pResFile = pResMgr->GetDownloadableResourceFile(strLookup); + + if (pResFile) + { + serverChecksum = pResFile->GetServerChecksum(); + bServerHasChecksum = (serverChecksum != zeroChecksum); + } + } + } + + if (pResFile && pResFile->IsAutoDownload() && !pResFile->IsDownloaded()) + { + const long long expectedSize = static_cast(pResFile->GetDownloadSize()); + + if (expectedSize > 0) + { + cachedFileSize = static_cast(FileSize(m_strFilename)); + if (cachedFileSize < 0) + { + m_strLastError = SString("Cannot read file: %s (download may be in progress)", ExtractFilename(m_strFilename).c_str()); + return false; + } + if (cachedFileSize != expectedSize) + { + m_strLastError = + SString("Download incomplete: %s (got %lld of %lld bytes)", ExtractFilename(m_strFilename).c_str(), cachedFileSize, expectedSize); + return false; + } + } + + if (bServerHasChecksum) + { + const CChecksum clientChecksum = CChecksum::GenerateChecksumFromFileUnsafe(m_strFilename); + if (clientChecksum == zeroChecksum) + { + m_strLastError = SString("Download incomplete: %s (checksum unavailable)", ExtractFilename(m_strFilename).c_str()); + return false; + } + + if (clientChecksum == serverChecksum) + { + pResFile->SetDownloaded(); + bChecksumAlreadyValidated = true; + } + else + { + m_strLastError = SString("Download incomplete: %s (checksum mismatch during transfer)", ExtractFilename(m_strFilename).c_str()); + return false; + } + } + else + { + m_strLastError = SString("Download incomplete: %s (awaiting server verification)", ExtractFilename(m_strFilename).c_str()); + return false; + } + } + + if (g_pClientGame && g_pClientGame->GetResourceManager()) + g_pClientGame->GetResourceManager()->ValidateResourceFile(m_strFilename, nullptr, 0); + + // Validate downloaded resources + if (pResFile) + { + const long long expectedSize = static_cast(pResFile->GetDownloadSize()); + + // Cache file size for reuse (also used in RightSizeTxd logging) + if (cachedFileSize < 0) + cachedFileSize = static_cast(FileSize(m_strFilename)); + + if (cachedFileSize < 0) + { + m_strLastError = SString("Cannot read file: %s", ExtractFilename(m_strFilename).c_str()); + return false; + } + + if (expectedSize > 0 && cachedFileSize != expectedSize) + { + m_strLastError = SString("Size mismatch: %s (expected %lld, got %lld bytes)", ExtractFilename(m_strFilename).c_str(), expectedSize, cachedFileSize); + return false; + } + + // Only validate checksum if server provided it AND we haven't already validated it + // (serverChecksum and bServerHasChecksum already cached above) + + if (bServerHasChecksum && !bChecksumAlreadyValidated) + { + const CChecksum clientChecksum = CChecksum::GenerateChecksumFromFileUnsafe(m_strFilename); + + if (clientChecksum == zeroChecksum) + { + m_strLastError = SString("Cannot verify file: %s (checksum computation failed)", ExtractFilename(m_strFilename).c_str()); + return false; + } + + if (clientChecksum != serverChecksum) + { + char szMd5Got[33]; + CMD5Hasher::ConvertToHex(clientChecksum.md5, szMd5Got); + m_strLastError = SString("Checksum mismatch: %s (file hash: %.8s...)", ExtractFilename(m_strFilename).c_str(), szMd5Got); + return false; + } + } + } + if (!g_pCore->GetNetwork()->CheckFile("txd", m_strFilename)) + { + m_strLastError = SString("File rejected as invalid: %s", ExtractFilename(m_strFilename).c_str()); return false; + } // Default: use original data strOutFilename = m_strFilename; // Should we try to reduce the size of this txd? - if (g_pCore->GetRightSizeTxdEnabled()) + if (g_pCore->GetRightSizeTxdEnabled() && g_pGame && g_pGame->GetRenderWare()) { // See if previously shrunk result exists SString strLargeSha256 = GenerateSha256HexStringFromFile(m_strFilename); @@ -243,8 +730,10 @@ bool CClientTXD::GetFilenameToUse(SString& strOutFilename) strOutFilename = strShrunkFilename; FileAppend(strShrunkFilename, SStringX("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12)); FileAppend(strShrunkFilename, GenerateSha256HexStringFromFile(strShrunkFilename)); - AddReportLog(9400, SString("RightSized %s(%s) from %d KB => %d KB", *ExtractFilename(m_strFilename), *strLargeSha256.Left(8), - (uint)FileSize(m_strFilename) / 1024, (uint)FileSize(strShrunkFilename) / 1024)); + // Use cached file size if available, otherwise compute it + const long long originalSizeKB = (cachedFileSize >= 0 ? cachedFileSize : FileSize(m_strFilename)) / 1024; + AddReportLog(9400, SString("RightSized %s(%s) from %d KB => %d KB", *ExtractFilename(m_strFilename), *strLargeSha256.Left(8), (uint)originalSizeKB, + (uint)(FileSize(strShrunkFilename) / 1024))); } else { diff --git a/Client/mods/deathmatch/logic/CClientTXD.h b/Client/mods/deathmatch/logic/CClientTXD.h index 7b9be10dbff..8f7c4439a55 100644 --- a/Client/mods/deathmatch/logic/CClientTXD.h +++ b/Client/mods/deathmatch/logic/CClientTXD.h @@ -21,18 +21,26 @@ class CClientTXD final : public CClientEntity CClientTXD(class CClientManager* pManager, ElementID ID); ~CClientTXD(); - void Unlink(){}; + void Unlink() {}; void GetPosition(CVector& vecPosition) const {}; - void SetPosition(const CVector& vecPosition){}; + void SetPosition(const CVector& vecPosition) {}; eClientEntityType GetType() const { return CCLIENTTXD; } bool Load(bool isRaw, SString input, bool enableFiltering); bool AddClothingTexture(const std::string& modelName); bool Import(unsigned short usModelID); + static void ProcessPendingImports(); + static void ClearPendingImports(); static bool IsImportableModel(unsigned short usModelID); static bool IsTXDData(const SString& strData); + const SString& GetLastError() const { return m_strLastError; } + bool HasPendingRenderWareImport(unsigned short usModelID) const; private: + bool ImportInternal(unsigned short usModelID, bool bAllowQueue); + bool IsDeviceLost() const; + void RemovePendingImports(); + bool LoadFromFile(SString filePath); bool LoadFromBuffer(SString buffer); @@ -40,6 +48,7 @@ class CClientTXD final : public CClientEntity bool GetFilenameToUse(SString& strOutFilename); SString m_strFilename; + SString m_strLastError; bool m_bFilteringEnabled; bool m_bIsRawData; bool m_bUsingFileDataForClothes; diff --git a/Client/mods/deathmatch/logic/CClientTask.cpp b/Client/mods/deathmatch/logic/CClientTask.cpp index 58193f2e130..3dec9c9ae07 100644 --- a/Client/mods/deathmatch/logic/CClientTask.cpp +++ b/Client/mods/deathmatch/logic/CClientTask.cpp @@ -21,8 +21,8 @@ using std::list; unsigned long CClientTask::m_ulLastUniqueIdentifier = 0; // Temporary until we start using ids -#define VERIFY_PLAYER(player) (m_pManager->GetPlayerManager ()->Exists(player)&&!player->IsBeingDeleted()) -#define VERIFY_VEHICLE(vehicle) (m_pManager->GetVehicleManager ()->Exists(vehicle)&&!vehicle->IsBeingDeleted()) +#define VERIFY_PLAYER(player) (m_pManager->GetPlayerManager()->Exists(player) && !player->IsBeingDeleted()) +#define VERIFY_VEHICLE(vehicle) (m_pManager->GetVehicleManager()->Exists(vehicle) && !vehicle->IsBeingDeleted()) CClientTask::CClientTask(CClientManager* pManager) { @@ -617,8 +617,8 @@ CTask* CClientTask::CreateTask(bool& bTaskPrimary, int& iTaskPriority) iTaskPriority = TASK_PRIORITY_PRIMARY; // Create the task - return g_pGame->GetTasks()->CreateTaskSimpleClimb(NULL, vecTarget, fHeading, static_cast(fSurfaceType), static_cast(fClimbStage), - bForceClimb); + return g_pGame->GetTasks()->CreateTaskSimpleClimb(NULL, vecTarget, fHeading, static_cast(fSurfaceType), + static_cast(fClimbStage), bForceClimb); } // Choking task? diff --git a/Client/mods/deathmatch/logic/CClientTeam.h b/Client/mods/deathmatch/logic/CClientTeam.h index 11e5dc71e15..6b1d51f4ed8 100644 --- a/Client/mods/deathmatch/logic/CClientTeam.h +++ b/Client/mods/deathmatch/logic/CClientTeam.h @@ -41,9 +41,9 @@ class CClientTeam final : public CClientEntity bool GetFriendlyFire() { return m_bFriendlyFire; } void SetFriendlyFire(bool bFriendlyFire) { m_bFriendlyFire = bFriendlyFire; } - void AddPlayer(CClientPlayer* pPlayer, bool bChangePlayer = false); - void RemovePlayer(CClientPlayer* pPlayer, bool bChangePlayer = false); - void RemoveAll(); + void AddPlayer(CClientPlayer* pPlayer, bool bChangePlayer = false); + void RemovePlayer(CClientPlayer* pPlayer, bool bChangePlayer = false); + void RemoveAll(); std::vector GetPlayers() const; bool Exists(CClientPlayer* pPlayer); diff --git a/Client/mods/deathmatch/logic/CClientVectorGraphic.cpp b/Client/mods/deathmatch/logic/CClientVectorGraphic.cpp index 2e3dcb675e5..bd3e35ce96e 100644 --- a/Client/mods/deathmatch/logic/CClientVectorGraphic.cpp +++ b/Client/mods/deathmatch/logic/CClientVectorGraphic.cpp @@ -10,6 +10,196 @@ #include "StdInc.h" #include "CClientVectorGraphic.h" #include +#include +#include +#include + +namespace +{ + constexpr size_t MAX_DATA_URI_SIZE = 10 * 1024 * 1024; + constexpr size_t MAX_LOG_MESSAGES = 10; + + CXMLAttribute* FindAttributeI(CXMLNode* node, const char* name) + { + if (!node) + return nullptr; + + SString targetName = SStringX(name).ToLower(); + for (auto iter = node->GetAttributes().ListBegin(); iter != node->GetAttributes().ListEnd(); ++iter) + { + if (SString((*iter)->GetName()).CompareI(targetName)) + return *iter; + } + return nullptr; + } + + bool IsHrefAllowed(const std::string& href) + { + if (href.empty()) + return true; + + if (href[0] == '#') + return true; + + SString hrefStr(href); + if (hrefStr.BeginsWithI("data:")) + { + if (hrefStr.BeginsWithI("data:image/svg")) + return false; + + if (!hrefStr.BeginsWithI("data:image/")) + return false; + + return href.size() <= MAX_DATA_URI_SIZE; + } + + return false; + } + + bool StyleContainsExternalReference(const std::string& styleValue) + { + SString styleLower = SString(styleValue).ToLower(); + return styleLower.find("url(") != std::string::npos || styleLower.find("@import") != std::string::npos; + } + + bool AttributeContainsExternalUrl(const std::string& value) + { + SString valueLower = SString(value).ToLower(); + + size_t urlPos = valueLower.find("url("); + if (urlPos == std::string::npos) + return false; + + size_t start = urlPos + 4; + + while (start < valueLower.length() && (valueLower[start] == ' ' || valueLower[start] == '"' || valueLower[start] == '\'')) + start++; + + if (start >= valueLower.length()) + return false; + + SString urlContent = valueLower.substr(start); + + if (urlContent.empty()) + return false; + + if (urlContent[0] == '#') + return false; + + if (urlContent.BeginsWithI("data:image/") && !urlContent.BeginsWithI("data:image/svg")) + return false; + + return true; + } + + bool IsEventAttribute(const std::string& attrName) + { + return SString(attrName).BeginsWithI("on"); + } + + void AddLogMessage(std::vector& info, const SString& message) + { + if (info.size() < MAX_LOG_MESSAGES) + info.push_back(message); + else if (info.size() == MAX_LOG_MESSAGES) + info.push_back("... additional warnings suppressed"); + } + + bool ProcessSVGNode(CXMLNode* node, int depth, std::vector& info) + { + if (!node) + return false; + + if (depth > 100) + { + AddLogMessage(info, "SVG parsing limit exceeded"); + return true; + } + + SString tagName = node->GetTagName(); + SString tagNameLower = tagName.ToLower(); + + constexpr const char* blockedElements[] = {"script", "foreignobject", "handler"}; + for (const char* blocked : blockedElements) + { + if (tagNameLower == blocked) + { + AddLogMessage(info, SString("SVG element <%s> is not supported", tagName.c_str())); + return true; + } + } + + const char* hrefAttrs[] = {"href", "xlink:href"}; + for (const char* attrName : hrefAttrs) + { + CXMLAttribute* attr = FindAttributeI(node, attrName); + if (attr && !IsHrefAllowed(attr->GetValue())) + { + AddLogMessage(info, SString("SVG element <%s> contains unsupported content", tagName.c_str())); + return true; + } + } + + std::vector attrsToRemove; + for (auto iter = node->GetAttributes().ListBegin(); iter != node->GetAttributes().ListEnd(); ++iter) + { + std::string attrName = (*iter)->GetName(); + std::string attrValue = (*iter)->GetValue(); + + if (IsEventAttribute(attrName)) + { + attrsToRemove.push_back(attrName); + AddLogMessage(info, SString("SVG attribute '%s' on <%s> is not supported", attrName.c_str(), tagName.c_str())); + } + else if (AttributeContainsExternalUrl(attrValue)) + { + attrsToRemove.push_back(attrName); + AddLogMessage(info, SString("SVG attribute '%s' on <%s> contains unsupported content", attrName.c_str(), tagName.c_str())); + } + } + + for (const std::string& attrName : attrsToRemove) + node->GetAttributes().Delete(attrName.c_str()); + + CXMLAttribute* xmlBaseAttr = FindAttributeI(node, "xml:base"); + if (xmlBaseAttr) + { + node->GetAttributes().Delete(xmlBaseAttr->GetName().c_str()); + AddLogMessage(info, SString("SVG attribute 'xml:base' on <%s> is not supported", tagName.c_str())); + } + + CXMLAttribute* styleAttr = FindAttributeI(node, "style"); + if (styleAttr) + { + SString styleLower = SString(styleAttr->GetValue()).ToLower(); + if (styleLower.find("@import") != std::string::npos) + { + node->GetAttributes().Delete(styleAttr->GetName().c_str()); + AddLogMessage(info, SString("SVG 'style' attribute on <%s> contains unsupported content", tagName.c_str())); + } + } + + std::vector toRemove; + for (unsigned int i = 0; i < node->GetSubNodeCount(); i++) + { + CXMLNode* child = node->GetSubNode(i); + if (ProcessSVGNode(child, depth + 1, info)) + toRemove.push_back(child); + } + + for (CXMLNode* child : toRemove) + node->DeleteSubNode(child); + + return false; + } + + bool ProcessSVGDocument(CXMLNode* root, std::vector& info) + { + if (!root) + return false; + return ProcessSVGNode(root, 0, info); + } +} CClientVectorGraphic::CClientVectorGraphic(CClientManager* pManager, ElementID ID, CVectorGraphicItem* pVectorGraphicItem) : ClassInit(this), CClientTexture(pManager, ID, pVectorGraphicItem) @@ -48,11 +238,27 @@ bool CClientVectorGraphic::SetDocument(CXMLNode* node) if (!node || !node->IsValid()) return false; + std::vector info; + if (ProcessSVGDocument(node, info)) + { + g_pClientGame->GetScriptDebugging()->LogWarning(nullptr, "SVG load failed: document contains unsupported content"); + return false; + } + + for (const SString& msg : info) + g_pClientGame->GetScriptDebugging()->LogInformation(nullptr, "%s", msg.c_str()); + + std::string strSvgData = node->ToString(); + if (m_pXMLString && m_pXMLString->node != node) m_pXMLString = nullptr; m_pXMLDocument = node; - m_pSVGDocument = lunasvg::Document::loadFromData(node->ToString()); + m_pSVGDocument = lunasvg::Document::loadFromData(strSvgData); + + // Check if LunaSVG successfully parsed the document + if (!m_pSVGDocument) + return false; m_pVectorGraphicDisplay->Update(); @@ -84,7 +290,7 @@ void CClientVectorGraphic::OnUpdate() if (std::holds_alternative(m_updateCallbackRef)) { auto& func = std::get(m_updateCallbackRef); - auto state = func.GetLuaVM(); + auto state = func.GetLuaVM(); if (VERIFY_FUNCTION(func) && state != NULL) { diff --git a/Client/mods/deathmatch/logic/CClientVectorGraphicDisplay.cpp b/Client/mods/deathmatch/logic/CClientVectorGraphicDisplay.cpp index 05936b79131..dc564e56de8 100644 --- a/Client/mods/deathmatch/logic/CClientVectorGraphicDisplay.cpp +++ b/Client/mods/deathmatch/logic/CClientVectorGraphicDisplay.cpp @@ -13,8 +13,20 @@ using namespace lunasvg; -CClientVectorGraphicDisplay::CClientVectorGraphicDisplay(CClientVectorGraphic* pVectorGraphic, int ID) - : CClientDisplay(ID) +static bool SafeSvgRender(Document* doc, Bitmap& bitmap, const Matrix& matrix) +{ + __try + { + doc->render(bitmap, matrix); + return true; + } + __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) + { + return false; + } +} + +CClientVectorGraphicDisplay::CClientVectorGraphicDisplay(CClientVectorGraphic* pVectorGraphic, int ID) : CClientDisplay(ID) { m_pVectorGraphic = pVectorGraphic; m_bVisible = true; @@ -51,10 +63,10 @@ void CClientVectorGraphicDisplay::UnpremultiplyBitmap(Bitmap& bitmap) auto stride = bitmap.stride(); auto rowData = bitmap.data(); - for (std::uint32_t y = 0; y < height; y++) + for (decltype(height) y = 0; y < height; y++) { auto data = rowData; - for (std::uint32_t x = 0; x < width; x++) + for (decltype(width) x = 0; x < width; x++) { auto& b = data[0]; auto& g = data[1]; @@ -92,8 +104,27 @@ void CClientVectorGraphicDisplay::UpdateTexture() if (!surface) return; - // SVG has a predefined width and height. We need transform it to the requested size - const Matrix transformationMatrix(pVectorGraphicItem->m_uiSizeX / svgDocument->width(), 0, 0, pVectorGraphicItem->m_uiSizeY / svgDocument->height(), 0, 0); + // Validate render item dimensions + if (pVectorGraphicItem->m_uiSizeX == 0 || pVectorGraphicItem->m_uiSizeY == 0) + return; + + // Validate SVG document dimensions (reject zero, negative, NaN, Inf) + float svgWidth = svgDocument->width(); + float svgHeight = svgDocument->height(); + if (svgWidth <= 0 || svgHeight <= 0 || !std::isfinite(svgWidth) || !std::isfinite(svgHeight)) + return; + + // Reject documents whose content bounding box is degenerate. + // Catches fully-empty or NaN-dimension documents before they reach the renderer. + Box bbox = svgDocument->boundingBox(); + if (bbox.w <= 0 || bbox.h <= 0 || !std::isfinite(bbox.w) || !std::isfinite(bbox.h) || !std::isfinite(bbox.x) || !std::isfinite(bbox.y)) + return; + + // SVG has a predefined width and height. We need to transform it to the requested size + float scaleX = pVectorGraphicItem->m_uiSizeX / svgWidth; + float scaleY = pVectorGraphicItem->m_uiSizeY / svgHeight; + + const Matrix transformationMatrix(scaleX, 0, 0, scaleY, 0, 0); // Lock surface D3DLOCKED_RECT LockedRect; @@ -104,7 +135,15 @@ void CClientVectorGraphicDisplay::UpdateTexture() Bitmap bitmap{surfaceData, (int32_t)pVectorGraphicItem->m_uiSizeX, (int32_t)pVectorGraphicItem->m_uiSizeY, stride}; bitmap.clear(0); - svgDocument->render(bitmap, transformationMatrix); + + if (!SafeSvgRender(svgDocument, bitmap, transformationMatrix)) + { + // SVG triggered an access violation during rendering (malformed content) + surface->UnlockRect(); + m_bHasUpdated = false; + return; + } + UnpremultiplyBitmap(bitmap); // Unlock surface diff --git a/Client/mods/deathmatch/logic/CClientVehicle.cpp b/Client/mods/deathmatch/logic/CClientVehicle.cpp index b08b867b6ea..2c12c80fadb 100644 --- a/Client/mods/deathmatch/logic/CClientVehicle.cpp +++ b/Client/mods/deathmatch/logic/CClientVehicle.cpp @@ -21,19 +21,39 @@ #include #include #include +#include +#include using std::list; extern CClientGame* g_pClientGame; std::set ms_AttachedVehiclesToIgnore; +namespace +{ + bool HasPendingAudioSettingsChange(CVehicle* pVehicle, const CVehicleAudioSettingsEntry& settings) + { + auto* pVehicleSA = dynamic_cast(pVehicle); + if (!pVehicleSA) + return true; + + auto* pVehicleAudioEntity = pVehicleSA->GetVehicleAudioEntity(); + auto* pAudioInterface = pVehicleAudioEntity ? pVehicleAudioEntity->GetInterface() : nullptr; + if (!pAudioInterface) + return true; + + const auto& desiredSettings = static_cast(settings).GetInterface(); + return std::memcmp(&pAudioInterface->m_nSettings, &desiredSettings, sizeof(desiredSettings)) != 0; + } +} + // To hide the ugly "pointer truncation from DWORD* to unsigned long warning -#pragma warning(disable:4311) +#pragma warning(disable : 4311) // Maximum distance between current position and target position (for interpolation) // before we disable interpolation and warp to the position instead -#define VEHICLE_INTERPOLATION_WARP_THRESHOLD 15 -#define VEHICLE_INTERPOLATION_WARP_THRESHOLD_FOR_SPEED 10 +#define VEHICLE_INTERPOLATION_WARP_THRESHOLD 15 +#define VEHICLE_INTERPOLATION_WARP_THRESHOLD_FOR_SPEED 10 CClientVehicle::CClientVehicle(CClientManager* pManager, ElementID ID, unsigned short usModel, unsigned char ucVariation, unsigned char ucVariation2) : ClassInit(this), CClientStreamElement(pManager->GetVehicleStreamer(), ID) @@ -57,9 +77,9 @@ CClientVehicle::CClientVehicle(CClientManager* pManager, ElementID ID, unsigned m_pModelInfo = g_pGame->GetModelInfo(usModel); // Apply handling - std::uint16_t usHandlingModelID = m_usModel; + std::uint32_t usHandlingModelID = m_usModel; if (m_usModel < 400 || m_usModel > 611) - usHandlingModelID = m_pModelInfo->GetParentID(); + usHandlingModelID = static_cast(m_pModelInfo->GetParentID()); m_pOriginalHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(usHandlingModelID); m_HandlingEntry = g_pGame->GetHandlingManager()->CreateHandlingData(); @@ -814,13 +834,13 @@ void CClientVehicle::Fix() GetInitialDoorStates(ucDoorStates); bool flyingComponents = m_pVehicleManager->IsSpawnFlyingComponentEnabled(); - for (int i = 0; i < MAX_DOORS; i++) + for (unsigned char i = 0; i < MAX_DOORS; i++) SetDoorStatus(i, ucDoorStates[i], flyingComponents); - for (int i = 0; i < MAX_PANELS; i++) + for (unsigned char i = 0; i < MAX_PANELS; i++) SetPanelStatus(i, 0, flyingComponents); - for (int i = 0; i < MAX_LIGHTS; i++) + for (unsigned char i = 0; i < MAX_LIGHTS; i++) SetLightStatus(i, 0); - for (int i = 0; i < MAX_WHEELS; i++) + for (unsigned char i = 0; i < MAX_WHEELS; i++) SetWheelStatus(i, 0); // These components get a funny rotation when calling Fix() (unknown reason) @@ -1057,9 +1077,9 @@ void CClientVehicle::SetModelBlocking(unsigned short usModel, unsigned char ucVa // Reset handling to fit the vehicle if (IsLocalEntity() || !(usModel < 400 || usModel > 611)) { - std::uint16_t usHandlingModelID = usModel; + std::uint32_t usHandlingModelID = usModel; if (usHandlingModelID < 400 || usHandlingModelID > 611) - usHandlingModelID = m_pModelInfo->GetParentID(); + usHandlingModelID = static_cast(m_pModelInfo->GetParentID()); m_pOriginalHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(usHandlingModelID); m_HandlingEntry->Assign(m_pOriginalHandlingEntry); @@ -1127,7 +1147,6 @@ void CClientVehicle::SetVariant(unsigned char ucVariant, unsigned char ucVariant m_ComponentVisibilityBackup[pair.first] = pair.second.m_bVisible; // Clear component data to regenerate it on next create m_ComponentData.clear(); - ReCreate(); } @@ -1476,8 +1495,9 @@ void CClientVehicle::SetWheelStatus(unsigned char ucWheel, unsigned char ucStatu m_pVehicle->GetDamageManager()->SetWheelStatus((eWheelPosition)(ucWheel), ucGTAStatus); // Update the wheel's visibility - m_pVehicle->SetWheelVisibility((eWheelPosition)ucWheel, ucStatus != DT_WHEEL_MISSING && - (m_ComponentData.empty() || m_ComponentData[GetComponentNameForWheel(ucWheel)].m_bVisible)); + m_pVehicle->SetWheelVisibility( + (eWheelPosition)ucWheel, + ucStatus != DT_WHEEL_MISSING && (m_ComponentData.empty() || m_ComponentData[GetComponentNameForWheel(ucWheel)].m_bVisible)); } else if (m_eVehicleType == CLIENTVEHICLE_BIKE && ucWheel < 2) m_pVehicle->SetBikeWheelStatus(ucWheel, ucGTAStatus); @@ -2310,7 +2330,7 @@ void CClientVehicle::StreamedInPulse() // Check if we need to update the train position (because of streaming) CVector vecPosition; - float fCarriageDistance = 20.0f; // approximately || Todo: Find proper distance + float fCarriageDistance = 20.0f; // approximately || Todo: Find proper distance if (GetTrainDirection()) fCarriageDistance = -fCarriageDistance; @@ -2473,8 +2493,8 @@ bool CClientVehicle::DoCheckHasLandingGear() { auto model = static_cast(m_usModel); - return (model == VehicleType::VT_ANDROM || model == VehicleType::VT_AT400 || model == VehicleType::VT_NEVADA || model == VehicleType::VT_RUSTLER || model == VehicleType::VT_SHAMAL || model == VehicleType::VT_HYDRA || - model == VehicleType::VT_STUNT); + return (model == VehicleType::VT_ANDROM || model == VehicleType::VT_AT400 || model == VehicleType::VT_NEVADA || model == VehicleType::VT_RUSTLER || + model == VehicleType::VT_SHAMAL || model == VehicleType::VT_HYDRA || model == VehicleType::VT_STUNT); } void CClientVehicle::Create() @@ -2482,9 +2502,9 @@ void CClientVehicle::Create() // If the vehicle doesn't exist if (!m_pVehicle) { - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG g_pCore->GetConsole()->Printf("CClientVehicle::Create %d", GetModel()); - #endif +#endif // Check again that the limit isn't reached. We are required to do so because // we load async. The streamer isn't always aware of our limits. @@ -2636,7 +2656,6 @@ void CClientVehicle::Create() m_pVehicle->SetOverrideLights(m_ucOverrideLights); m_pVehicle->SetRemap(static_cast(m_ucPaintjob)); m_pVehicle->SetBodyDirtLevel(m_fDirtLevel); - m_pVehicle->SetEngineOn(m_bEngineOn); m_pVehicle->SetAreaCode(m_ucInterior); m_pVehicle->SetSmokeTrailEnabled(m_bSmokeTrail); m_pVehicle->SetGravity(&m_vecGravity); @@ -2682,13 +2701,15 @@ void CClientVehicle::Create() m_pVehicle->SetTurretRotation(m_fTurretHorizontal, m_fTurretVertical); } - for (int i = 0; i < MAX_WHEELS; i++) + for (unsigned char i = 0; i < MAX_WHEELS; i++) SetWheelStatus(i, m_ucWheelStates[i], true); // Eventually warp driver back in if (m_pDriver) m_pDriver->WarpIntoVehicle(this, 0); + m_pVehicle->SetEngineOn(m_bEngineOn); + // Warp the passengers back in for (unsigned int i = 0; i < 8; i++) { @@ -2788,11 +2809,13 @@ void CClientVehicle::Create() switch (m_eVehicleType) { case CLIENTVEHICLE_BOAT: - dynamic_cast(m_pVehicle)->SetBoatHandlingData(m_BoatHandlingEntry.get()); + if (auto* pBoat = dynamic_cast(m_pVehicle)) + pBoat->SetBoatHandlingData(m_BoatHandlingEntry.get()); break; case CLIENTVEHICLE_BIKE: case CLIENTVEHICLE_BMX: - dynamic_cast(m_pVehicle)->SetBikeHandlingData(m_BikeHandlingEntry.get()); + if (auto* pBike = dynamic_cast(m_pVehicle)) + pBike->SetBikeHandlingData(m_BikeHandlingEntry.get()); break; } @@ -2880,7 +2903,7 @@ void CClientVehicle::Create() } m_ComponentVisibilityBackup.clear(); } - + // Grab our component data std::map::iterator iter = m_ComponentData.begin(); // Loop through our component data @@ -2954,9 +2977,9 @@ void CClientVehicle::Destroy() // If the vehicle exists if (m_pVehicle) { - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG g_pCore->GetConsole()->Printf("CClientVehicle::Destroy %d", GetModel()); - #endif +#endif // Invalidate m_pManager->InvalidateEntity(this); @@ -2979,11 +3002,23 @@ void CClientVehicle::Destroy() switch (m_eVehicleType) { case CLIENTVEHICLE_BOAT: - m_BoatHandlingEntry->Assign(dynamic_cast(m_pVehicle)->GetBoatHandlingData()); + if (auto* pBoat = dynamic_cast(m_pVehicle)) + { + if (!m_BoatHandlingEntry) + m_BoatHandlingEntry = g_pGame->GetHandlingManager()->CreateBoatHandlingData(); + + m_BoatHandlingEntry->Assign(pBoat->GetBoatHandlingData()); + } break; case CLIENTVEHICLE_BIKE: case CLIENTVEHICLE_BMX: - m_BikeHandlingEntry->Assign(dynamic_cast(m_pVehicle)->GetBikeHandlingData()); + if (auto* pBike = dynamic_cast(m_pVehicle)) + { + if (!m_BikeHandlingEntry) + m_BikeHandlingEntry = g_pGame->GetHandlingManager()->CreateBikeHandlingData(); + + m_BikeHandlingEntry->Assign(pBike->GetBikeHandlingData()); + } break; default: break; @@ -3000,14 +3035,14 @@ void CClientVehicle::Destroy() // Grab the damage model CDamageManager* pDamageManager = m_pVehicle->GetDamageManager(); - for (int i = 0; i < MAX_DOORS; i++) + for (unsigned char i = 0; i < MAX_DOORS; i++) m_ucDoorStates[i] = pDamageManager->GetDoorStatus(static_cast(i)); - for (int i = 0; i < MAX_PANELS; i++) + for (unsigned char i = 0; i < MAX_PANELS; i++) m_ucPanelStates[i] = pDamageManager->GetPanelStatus(static_cast(i)); - for (int i = 0; i < MAX_LIGHTS; i++) + for (unsigned char i = 0; i < MAX_LIGHTS; i++) m_ucLightStates[i] = pDamageManager->GetLightStatus(static_cast(i)); } - for (int i = 0; i < MAX_WHEELS; i++) + for (unsigned char i = 0; i < MAX_WHEELS; i++) m_ucWheelStates[i] = GetWheelStatus(i); // Remove the driver from the vehicle @@ -3090,6 +3125,12 @@ void CClientVehicle::Destroy() g_pGame->GetPools()->RemoveVehicle(m_pVehicle); m_pVehicle = NULL; + // Clear our component data, but backup the visibility states so we can restore them on next create + m_ComponentVisibilityBackup.clear(); + for (const auto& pair : m_ComponentData) + m_ComponentVisibilityBackup[pair.first] = pair.second.m_bVisible; + m_ComponentData.clear(); + // Remove reference to its model m_pModelInfo->RemoveRef(); @@ -3325,7 +3366,7 @@ bool CClientVehicle::InternalSetTowLink(CClientVehicle* pTrailer) // SA can attach the trailer now pGameVehicle->SetTowLink(m_pVehicle); - pTrailer->PlaceProperlyOnGround(); // Probably not needed + pTrailer->PlaceProperlyOnGround(); // Probably not needed return true; } @@ -3337,7 +3378,7 @@ bool CClientVehicle::IsTowableBy(CClientVehicle* towingVehicle) bool CClientVehicle::SetWinchType(eWinchType winchType) { - if (static_cast(GetModel()) == VehicleType::VT_LEVIATHN) // Leviathan + if (static_cast(GetModel()) == VehicleType::VT_LEVIATHN) // Leviathan { if (m_pVehicle) { @@ -3463,7 +3504,7 @@ unsigned char CClientVehicle::GetPaintjob() if (m_pVehicle) { int iRemap = m_pVehicle->GetRemapIndex(); - return (iRemap == -1) ? 3 : iRemap; + return (iRemap == -1) ? m_ucPaintjob : iRemap; } return m_ucPaintjob; @@ -3551,23 +3592,56 @@ float CClientVehicle::GetDistanceFromGround() bool CClientVehicle::IsOnGround() { - if (m_pModelInfo) + if (!m_pVehicle) + return m_bIsOnGround; + + int type = m_pVehicle->GetBaseVehicleType(); // 0 = Automobile, 9 = Bike, 10 = BMX + if ((type == 0 && dynamic_cast(m_pVehicle)->IsAnyWheelTouchingGround()) || + ((type == 9 || type == 10) && dynamic_cast(m_pVehicle)->IsAnyWheelTouchingGround())) { - CBoundingBox* pBoundingBox = m_pModelInfo->GetBoundingBox(); - if (pBoundingBox) - { - CVector vecMin = pBoundingBox->vecBoundMin; - CVector vecPosition; - GetPosition(vecPosition); - vecMin += vecPosition; - float fGroundLevel = static_cast(g_pGame->GetWorld()->FindGroundZFor3DPosition(&vecPosition)); + return true; + } - /* Is the lowest point of the bounding box lower than 0.5 above the floor, - or is the lowest point of the bounding box higher than 0.3 below the floor */ - return ((fGroundLevel > vecMin.fZ && (fGroundLevel - vecMin.fZ) < 0.5f) || (vecMin.fZ > fGroundLevel && (vecMin.fZ - fGroundLevel) < 0.3f)); - } + CVector vehPos; + GetPosition(vehPos); + float groundZ = g_pGame->GetWorld()->FindGroundZFor3DPosition(&vehPos); + + // Is vehicle under the ground? + if (DefinitelyLessThan(vehPos.fZ, groundZ, 1e-4f)) + return false; + + if (!m_pModelInfo) + return m_bIsOnGround; + + CBoundingBox* bbox = m_pModelInfo->GetBoundingBox(); + if (!bbox) + return m_bIsOnGround; + + const CVector& min = bbox->vecBoundMin; + const CVector& max = bbox->vecBoundMax; + + // Is vehicle too high above the ground? + float halfHeight = (max.fZ - min.fZ) * 0.5f; + if (DefinitelyGreaterThan(vehPos.fZ - halfHeight, groundZ + halfHeight + 0.3f, 1e-4f)) + return false; + + // OBB check + CMatrix mat; + GetMatrix(mat); + + CVector localPoints[8] = {CVector(min.fX, min.fY, min.fZ), CVector(min.fX, min.fY, max.fZ), CVector(min.fX, max.fY, min.fZ), + CVector(min.fX, max.fY, max.fZ), CVector(max.fX, min.fY, min.fZ), CVector(max.fX, min.fY, max.fZ), + CVector(max.fX, max.fY, min.fZ), CVector(max.fX, max.fY, max.fZ)}; + + float lowestZ = FLT_MAX; + for (const auto& lp : localPoints) + { + float z = mat.TransformVector(lp).fZ; + if (z < lowestZ) + lowestZ = z; } - return m_bIsOnGround; + + return DefinitelyLessThan((lowestZ - groundZ), 0.3f, 1e-4f) || EssentiallyEqual((lowestZ - groundZ), 0.3f, 1e-4f); } void CClientVehicle::LockSteering(bool bLock) @@ -3929,18 +4003,17 @@ bool CClientVehicle::IsEnterable(bool localEntity) { if (!m_pVehicle) return false; - + // Server vehicle? if (IsLocalEntity() != localEntity) return false; - + if (GetHealth() <= 0.0f) return false; - - return !IsInWater() || (GetVehicleType() == CLIENTVEHICLE_BOAT - || m_usModel == 447 /* sea sparrow */ - || m_usModel == 417 /* levithan */ - || m_usModel == 460 /* skimmer */); + + return !IsInWater() || (GetVehicleType() == CLIENTVEHICLE_BOAT || m_usModel == 447 /* sea sparrow */ + || m_usModel == 417 /* levithan */ + || m_usModel == 460 /* skimmer */); } bool CClientVehicle::HasRadio() @@ -4017,11 +4090,15 @@ void CClientVehicle::SetHeadLightColor(const SColor color) // #if OCCUPY_DEBUG_INFO - #define INFO(x) g_pCore->GetConsole ()->Printf x - #define WARN(x) g_pCore->GetConsole ()->Printf x + #define INFO(x) g_pCore->GetConsole()->Printf x + #define WARN(x) g_pCore->GetConsole()->Printf x #else - #define INFO(x) {} - #define WARN(x) {} + #define INFO(x) \ + { \ + } + #define WARN(x) \ + { \ + } #endif std::string GetPlayerName(CClientPed* pClientPed) @@ -4303,7 +4380,8 @@ void CClientVehicle::ApplyHandling() m_pVehicle->RecalculateHandling(); if (m_eVehicleType == CLIENTVEHICLE_BMX || m_eVehicleType == CLIENTVEHICLE_BIKE) - dynamic_cast(m_pVehicle)->RecalculateBikeHandling(); + if (auto* pBike = dynamic_cast(m_pVehicle)) + pBike->RecalculateBikeHandling(); } CHandlingEntry* CClientVehicle::GetHandlingData() @@ -4391,9 +4469,9 @@ void CClientVehicle::HandleWaitingForGroundToLoad() { // If not near any MTA objects, then don't bother waiting SetFrozenWaitingForGroundToLoad(false, true); - #ifdef ASYNC_LOADING_DEBUG_OUTPUTA +#ifdef ASYNC_LOADING_DEBUG_OUTPUTA OutputDebugLine("[AsyncLoading] FreezeUntilCollisionLoaded - Early stop"); - #endif +#endif return; } @@ -4417,29 +4495,29 @@ void CClientVehicle::HandleWaitingForGroundToLoad() bool bASync = g_pGame->IsASyncLoadingEnabled(); bool bMTAObjLimit = pObjectManager->IsObjectLimitReached(); bool bHasModel = GetModelInfo() != NULL; - #ifndef ASYNC_LOADING_DEBUG_OUTPUTA +#ifndef ASYNC_LOADING_DEBUG_OUTPUTA bool bMTALoaded = pObjectManager->ObjectsAroundPointLoaded(vecPosition, fUseRadius, m_usDimension); - #else +#else SString strAround; bool bMTALoaded = pObjectManager->ObjectsAroundPointLoaded(vecPosition, fUseRadius, m_usDimension, &strAround); - #endif +#endif - #ifdef ASYNC_LOADING_DEBUG_OUTPUTA +#ifdef ASYNC_LOADING_DEBUG_OUTPUTA SString status = SString( "%2.2f,%2.2f,%2.2f bASync:%d bHasModel:%d bMTALoaded:%d bMTAObjLimit:%d m_fGroundCheckTolerance:%2.2f m_fObjectsAroundTolerance:%2.2f " "fUseRadius:%2.1f", vecPosition.fX, vecPosition.fY, vecPosition.fZ, bASync, bHasModel, bMTALoaded, bMTAObjLimit, m_fGroundCheckTolerance, m_fObjectsAroundTolerance, fUseRadius); - #endif +#endif // See if ground is ready if ((!bHasModel || !bMTALoaded) && m_fObjectsAroundTolerance < 1.f) { m_fGroundCheckTolerance = 0.f; m_fObjectsAroundTolerance = std::min(1.f, m_fObjectsAroundTolerance + 0.01f); - #ifdef ASYNC_LOADING_DEBUG_OUTPUTA +#ifdef ASYNC_LOADING_DEBUG_OUTPUTA status += (" FreezeUntilCollisionLoaded - wait"); - #endif +#endif } else { @@ -4452,16 +4530,16 @@ void CClientVehicle::HandleWaitingForGroundToLoad() if (fUseDist > -0.2f && fUseDist < 1.5f) SetFrozenWaitingForGroundToLoad(false, true); - #ifdef ASYNC_LOADING_DEBUG_OUTPUTA +#ifdef ASYNC_LOADING_DEBUG_OUTPUTA status += (SString(" GetDistanceFromGround: fDist:%2.2f fUseDist:%2.2f", fDist, fUseDist)); - #endif +#endif // Stop waiting after 3 frames, if the object limit has not been reached. (bASync should always be false here) if (m_fGroundCheckTolerance > 0.03f /*&& !bMTAObjLimit*/ && !bASync) SetFrozenWaitingForGroundToLoad(false, true); } - #ifdef ASYNC_LOADING_DEBUG_OUTPUTA +#ifdef ASYNC_LOADING_DEBUG_OUTPUTA OutputDebugLine(SStringX("[AsyncLoading] ") + status); g_pCore->GetGraphics()->DrawString(10, 220, -1, 1, status); @@ -4469,7 +4547,7 @@ void CClientVehicle::HandleWaitingForGroundToLoad() strAround.Split("\n", lineList); for (unsigned int i = 0; i < lineList.size(); i++) g_pCore->GetGraphics()->DrawString(10, 230 + i * 10, -1, 1, lineList[i]); - #endif +#endif } bool CClientVehicle::GiveVehicleSirens(unsigned char ucSirenType, unsigned char ucSirenCount) @@ -4969,7 +5047,6 @@ CVehicleAudioSettingsEntry& CClientVehicle::GetOrCreateAudioSettings() return *m_pSoundSettingsEntry.get(); } - bool CClientVehicle::GetDummyPosition(VehicleDummies dummy, CVector& position) const { if (dummy >= VehicleDummies::LIGHT_FRONT_MAIN && dummy < VehicleDummies::VEHICLE_DUMMY_COUNT) @@ -5124,15 +5201,15 @@ bool CClientVehicle::SpawnFlyingComponent(const eCarNodes& nodeID, const eCarCom return m_pVehicle->SpawnFlyingComponent(nodeID, collisionType, removalTime); } - + CVector CClientVehicle::GetEntryPoint(std::uint32_t entryPointIndex) { static const uint32_t lookup[4] = {10, 8, 11, 9}; assert(entryPointIndex < 4); const std::uint32_t saDoorIndex = lookup[entryPointIndex]; - CVector entryPoint; - CVehicle* gameVehicle = GetGameVehicle(); + CVector entryPoint; + CVehicle* gameVehicle = GetGameVehicle(); g_pGame->GetCarEnterExit()->GetPositionToOpenCarDoor(entryPoint, gameVehicle, saDoorIndex); @@ -5144,7 +5221,11 @@ void CClientVehicle::ApplyAudioSettings() if (!m_pVehicle) return; - g_pGame->GetVehicleAudioSettingsManager()->SetNextSettings(&GetAudioSettings()); + const auto& audioSettings = GetAudioSettings(); + if (!HasPendingAudioSettingsChange(m_pVehicle, audioSettings)) + return; + + g_pGame->GetVehicleAudioSettingsManager()->SetNextSettings(&audioSettings); m_pVehicle->ReinitAudio(); } @@ -5153,4 +5234,3 @@ void CClientVehicle::ResetAudioSettings() m_pSoundSettingsEntry = nullptr; ApplyAudioSettings(); } - diff --git a/Client/mods/deathmatch/logic/CClientVehicle.h b/Client/mods/deathmatch/logic/CClientVehicle.h index 05c2601cf6a..2c3c75e89c2 100644 --- a/Client/mods/deathmatch/logic/CClientVehicle.h +++ b/Client/mods/deathmatch/logic/CClientVehicle.h @@ -50,7 +50,7 @@ enum eClientVehicleType CLIENTVEHICLE_TRAILER }; -static constexpr int NUM_VEHICLE_TYPES = 11; +static constexpr int NUM_VEHICLE_TYPES = 11; enum eDelayedSyncVehicleData { @@ -136,12 +136,12 @@ struct SVehicleComponentData m_bVisible = true; } SString m_strParentName; - CVector m_vecComponentPosition; // Parent relative - CVector m_vecComponentRotation; // Parent relative radians - CVector m_vecComponentScale; // Parent relative - CVector m_vecOriginalComponentPosition; // Parent relative - CVector m_vecOriginalComponentRotation; // Parent relative radians - CVector m_vecOriginalComponentScale; // Parent relative + CVector m_vecComponentPosition; // Parent relative + CVector m_vecComponentRotation; // Parent relative radians + CVector m_vecComponentScale; // Parent relative + CVector m_vecOriginalComponentPosition; // Parent relative + CVector m_vecOriginalComponentRotation; // Parent relative radians + CVector m_vecOriginalComponentScale; // Parent relative bool m_bPositionChanged; bool m_bRotationChanged; bool m_bScaleChanged; @@ -156,10 +156,10 @@ class CClientVehicle : public CClientStreamElement friend class CClientCamera; friend class CClientPed; friend class CClientVehicleManager; - friend class CClientGame; // TEMP HACK + friend class CClientGame; // TEMP HACK -protected: // Use CDeathmatchVehicle constructor for now. Will get removed later when this class is - // cleaned up. +protected: // Use CDeathmatchVehicle constructor for now. Will get removed later when this class is + // cleaned up. CClientVehicle(CClientManager* pManager, ElementID ID, unsigned short usModel, unsigned char ucVariation, unsigned char ucVariation2); public: @@ -287,7 +287,7 @@ class CClientVehicle : public CClientStreamElement int GetWheelFrictionState(unsigned char ucWheel); unsigned char GetPanelStatus(unsigned char ucPanel); unsigned char GetLightStatus(unsigned char ucLight); - SString GetComponentNameForWheel(unsigned char ucWheel) const noexcept; + SString GetComponentNameForWheel(unsigned char ucWheel) const noexcept; bool AreLightsOn(); @@ -429,7 +429,6 @@ class CClientVehicle : public CClientStreamElement void ResetInterpolation(); void Interpolate(); - void UpdateKeysync(); void GetInitialDoorStates(SFixedArray& ucOutDoorStates); @@ -540,7 +539,7 @@ class CClientVehicle : public CClientStreamElement void SetWheelScale(float fWheelScale); void ResetWheelScale(); - bool OnVehicleFallThroughMap(); + bool OnVehicleFallThroughMap(); const CVehicleAudioSettingsEntry& GetAudioSettings() const noexcept; CVehicleAudioSettingsEntry& GetOrCreateAudioSettings(); @@ -620,60 +619,60 @@ class CClientVehicle : public CClientStreamElement SFixedArray ulStartTime; SFixedArray ulTargetTime; } m_doorInterp; - bool m_bSwingingDoorsAllowed; - bool m_bDoorsLocked; - bool m_bDoorsUndamageable; - bool m_bCanShootPetrolTank; - bool m_bCanBeTargettedByHeatSeekingMissiles; - bool m_bCanBeDamaged; - bool m_bScriptCanBeDamaged; - bool m_bSyncUnoccupiedDamage; - bool m_bTyresCanBurst; - SFixedArray m_ucDoorStates; - SFixedArray m_ucWheelStates; - SFixedArray m_ucPanelStates; - SFixedArray m_ucLightStates; - bool m_bJustBlewUp; - eEntityStatus m_NormalStatus; - bool m_bColorSaved; - CVehicleColor m_Color; - bool m_bIsFrozen; - bool m_bScriptFrozen; - bool m_bFrozenWaitingForGroundToLoad; - float m_fGroundCheckTolerance; - float m_fObjectsAroundTolerance; - CVector m_vecWaitingForGroundSavedMoveSpeed; - CVector m_vecWaitingForGroundSavedTurnSpeed; - CMatrix m_matFrozen; - CVehicleUpgrades* m_pUpgrades; - unsigned char m_ucOverrideLights; - CClientVehiclePtr m_pTowedVehicle; - CClientVehiclePtr m_pTowedByVehicle; - eWinchType m_eWinchType; - CClientEntityPtr m_pPickedUpWinchEntity; - SString m_strRegPlate; - unsigned char m_ucPaintjob; - float m_fDirtLevel; - bool m_bSmokeTrail; - unsigned char m_ucAlpha; - bool m_bAlphaChanged; - double m_dLastRotationTime; - bool m_blowAfterStreamIn; - bool m_bIsOnGround; - bool m_bHeliSearchLightVisible; - float m_fHeliRotorSpeed; - float m_fPlaneRotorSpeed; - const CHandlingEntry* m_pOriginalHandlingEntry = nullptr; - std::unique_ptr m_HandlingEntry = nullptr; - const CFlyingHandlingEntry* m_pOriginalFlyingHandlingEntry = nullptr; - std::unique_ptr m_FlyingHandlingEntry = nullptr; - const CBoatHandlingEntry* m_pOriginalBoatHandlingEntry = nullptr; - std::unique_ptr m_BoatHandlingEntry = nullptr; - const CBikeHandlingEntry* m_pOriginalBikeHandlingEntry = nullptr; - std::unique_ptr m_BikeHandlingEntry = nullptr; - float m_fNitroLevel; - char m_cNitroCount; - float m_fWheelScale; + bool m_bSwingingDoorsAllowed; + bool m_bDoorsLocked; + bool m_bDoorsUndamageable; + bool m_bCanShootPetrolTank; + bool m_bCanBeTargettedByHeatSeekingMissiles; + bool m_bCanBeDamaged; + bool m_bScriptCanBeDamaged; + bool m_bSyncUnoccupiedDamage; + bool m_bTyresCanBurst; + SFixedArray m_ucDoorStates; + SFixedArray m_ucWheelStates; + SFixedArray m_ucPanelStates; + SFixedArray m_ucLightStates; + bool m_bJustBlewUp; + eEntityStatus m_NormalStatus; + bool m_bColorSaved; + CVehicleColor m_Color; + bool m_bIsFrozen; + bool m_bScriptFrozen; + bool m_bFrozenWaitingForGroundToLoad; + float m_fGroundCheckTolerance; + float m_fObjectsAroundTolerance; + CVector m_vecWaitingForGroundSavedMoveSpeed; + CVector m_vecWaitingForGroundSavedTurnSpeed; + CMatrix m_matFrozen; + CVehicleUpgrades* m_pUpgrades; + unsigned char m_ucOverrideLights; + CClientVehiclePtr m_pTowedVehicle; + CClientVehiclePtr m_pTowedByVehicle; + eWinchType m_eWinchType; + CClientEntityPtr m_pPickedUpWinchEntity; + SString m_strRegPlate; + unsigned char m_ucPaintjob; + float m_fDirtLevel; + bool m_bSmokeTrail; + unsigned char m_ucAlpha; + bool m_bAlphaChanged; + double m_dLastRotationTime; + bool m_blowAfterStreamIn; + bool m_bIsOnGround; + bool m_bHeliSearchLightVisible; + float m_fHeliRotorSpeed; + float m_fPlaneRotorSpeed; + const CHandlingEntry* m_pOriginalHandlingEntry = nullptr; + std::unique_ptr m_HandlingEntry = nullptr; + const CFlyingHandlingEntry* m_pOriginalFlyingHandlingEntry = nullptr; + std::unique_ptr m_FlyingHandlingEntry = nullptr; + const CBoatHandlingEntry* m_pOriginalBoatHandlingEntry = nullptr; + std::unique_ptr m_BoatHandlingEntry = nullptr; + const CBikeHandlingEntry* m_pOriginalBikeHandlingEntry = nullptr; + std::unique_ptr m_BikeHandlingEntry = nullptr; + float m_fNitroLevel; + char m_cNitroCount; + float m_fWheelScale; std::unique_ptr m_pSoundSettingsEntry; bool m_bChainEngine; @@ -700,7 +699,7 @@ class CClientVehicle : public CClientStreamElement float fLastAlpha; unsigned long ulStartTime; unsigned long ulFinishTime; - } pos; + } pos{}; struct { @@ -712,8 +711,8 @@ class CClientVehicle : public CClientStreamElement float fLastAlpha; unsigned long ulStartTime; unsigned long ulFinishTime; - } rot; - } m_interp; + } rot{}; + } m_interp{}; unsigned long m_ulIllegalTowBreakTime; @@ -755,9 +754,9 @@ class CClientVehicle : public CClientStreamElement SSirenInfo m_tSirenBeaconInfo; std::map m_ComponentData; // Store visibility state when the component map is regenerated - std::map m_ComponentVisibilityBackup; - bool m_bAsyncLoadingDisabled; + std::map m_ComponentVisibilityBackup; + bool m_bAsyncLoadingDisabled; std::array(VehicleDummies::VEHICLE_DUMMY_COUNT)> m_dummyPositions; - bool m_copyDummyPositions = true; + bool m_copyDummyPositions = true; }; diff --git a/Client/mods/deathmatch/logic/CClientVehicleManager.cpp b/Client/mods/deathmatch/logic/CClientVehicleManager.cpp index f1d32978c6b..01342e60700 100644 --- a/Client/mods/deathmatch/logic/CClientVehicleManager.cpp +++ b/Client/mods/deathmatch/logic/CClientVehicleManager.cpp @@ -16,40 +16,40 @@ using std::list; using std::vector; // List over all vehicles with their passenger max counts -const SFixedArray g_ucMaxPassengers = {3, 1, 1, 1, 3, 3, 0, 1, 1, 3, 1, 1, 1, 3, 1, 1, // 400->415 - 3, 1, 3, 1, 3, 3, 1, 1, 1, 0, 3, 3, 3, 1, 0, 8, // 416->431 - 0, 1, 1, 255, 1, 8, 3, 1, 3, 0, 1, 1, 1, 3, 0, 1, // 432->447 - 0, 1, 255, 1, 0, 0, 0, 1, 1, 1, 3, 3, 1, 1, 1, // 448->462 - 1, 1, 1, 3, 3, 1, 1, 3, 1, 0, 0, 1, 1, 0, 1, 1, // 463->478 - 3, 1, 0, 3, 1, 0, 0, 0, 3, 1, 1, 3, 1, 3, 0, 1, // 479->494 - 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 0, 0, // 495->510 - 1, 0, 0, 1, 1, 3, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, // 511->526 - 1, 1, 3, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 3, 1, // 527->541 - 1, 1, 1, 1, 3, 3, 1, 1, 3, 3, 1, 0, 1, 1, 1, 1, // 542->557 - 1, 1, 3, 3, 1, 1, 0, 1, 3, 3, 0, 255, 1, 0, 0, // 558->572 - 1, 0, 1, 1, 1, 1, 3, 3, 1, 3, 0, 255, 3, 1, 1, 1, // 573->588 - 1, 255, 255, 1, 1, 1, 0, 3, 3, 3, 1, 1, 1, 1, 1, // 589->604 - 3, 1, 255, 255, 255, 3, 255, 255}; // 605->611 +const SFixedArray g_ucMaxPassengers = {3, 1, 1, 1, 3, 3, 0, 1, 1, 3, 1, 1, 1, 3, 1, 1, // 400->415 + 3, 1, 3, 1, 3, 3, 1, 1, 1, 0, 3, 3, 3, 1, 0, 8, // 416->431 + 0, 1, 1, 255, 1, 8, 3, 1, 3, 0, 1, 1, 1, 3, 0, 1, // 432->447 + 0, 1, 255, 1, 0, 0, 0, 1, 1, 1, 3, 3, 1, 1, 1, // 448->462 + 1, 1, 1, 3, 3, 1, 1, 3, 1, 0, 0, 1, 1, 0, 1, 1, // 463->478 + 3, 1, 0, 3, 3, 0, 0, 0, 3, 1, 1, 3, 1, 3, 0, 1, // 479->494 + 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 0, 0, // 495->510 + 1, 0, 0, 1, 1, 3, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, // 511->526 + 1, 1, 3, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 3, 1, // 527->541 + 1, 1, 1, 1, 3, 3, 1, 1, 3, 3, 1, 0, 1, 1, 1, 1, // 542->557 + 1, 1, 3, 3, 1, 1, 0, 1, 3, 3, 0, 255, 1, 0, 0, // 558->572 + 1, 0, 1, 1, 1, 1, 3, 3, 1, 3, 0, 255, 3, 1, 1, 1, // 573->588 + 1, 255, 255, 1, 1, 1, 0, 3, 3, 3, 1, 1, 1, 1, 1, // 589->604 + 3, 1, 255, 255, 255, 3, 255, 255}; // 605->611 // List over all vehicles with their special attributes -#define VEHICLE_HAS_TURRENT 0x001UL //1 -#define VEHICLE_HAS_SIRENS 0x002UL //2 -#define VEHICLE_HAS_LANDING_GEARS 0x004UL //4 -#define VEHICLE_HAS_ADJUSTABLE_PROPERTY 0x008UL //8 -#define VEHICLE_HAS_SMOKE_TRAIL 0x010UL //16 -#define VEHICLE_HAS_TAXI_LIGHTS 0x020UL //32 -#define VEHICLE_HAS_SEARCH_LIGHT 0x040UL //64 +#define VEHICLE_HAS_TURRENT 0x001UL // 1 +#define VEHICLE_HAS_SIRENS 0x002UL // 2 +#define VEHICLE_HAS_LANDING_GEARS 0x004UL // 4 +#define VEHICLE_HAS_ADJUSTABLE_PROPERTY 0x008UL // 8 +#define VEHICLE_HAS_SMOKE_TRAIL 0x010UL // 16 +#define VEHICLE_HAS_TAXI_LIGHTS 0x020UL // 32 +#define VEHICLE_HAS_SEARCH_LIGHT 0x040UL // 64 // Generated by MTA10\utils\gentable\gentable_vehattr.cpp static const SFixedArray g_ulVehicleAttributes = { - 0, 0, 0, 0, 0, 0, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 32, 0, 0, 2, 0, // 400-424 - 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, // 425-449 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 450-474 - 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 64, 0, 0, // 475-499 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 4, 12, 0, 0, 2, 8, // 500-524 - 8, 0, 0, 2, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, // 525-549 - 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 550-574 - 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 2, 2, 2, 2, // 575-599 + 0, 0, 0, 0, 0, 0, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 32, 0, 0, 2, 0, // 400-424 + 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, // 425-449 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 450-474 + 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 64, 0, 0, // 475-499 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 4, 12, 0, 0, 2, 8, // 500-524 + 8, 0, 0, 2, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, // 525-549 + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 550-574 + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 2, 2, 2, 2, // 575-599 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static SFixedArray g_ucVariants; @@ -425,7 +425,14 @@ bool CClientVehicleManager::IsTrainModel(unsigned long ulModel) bool CClientVehicleManager::IsValidModel(unsigned long ulModel) { CModelInfo* pModelInfo = g_pGame->GetModelInfo(ulModel); - return pModelInfo && pModelInfo->IsVehicle(); + if (!pModelInfo || !pModelInfo->GetInterface()) + return false; + + // Custom models allocated via engineRequestModel have a parent ID + if (pModelInfo->GetParentID() != 0) + return pModelInfo->GetModelType() == eModelInfoType::VEHICLE; + + return pModelInfo->IsVehicle(); } bool CClientVehicleManager::IsStandardModel(unsigned long ulModel) @@ -486,6 +493,24 @@ unsigned char CClientVehicleManager::GetMaxPassengerCount(unsigned long ulModel) return 0xFF; } +bool CClientVehicleManager::IsValidSeat(unsigned long ulModel, unsigned char ucSeat) +{ + // Camper only has 3 seats (0-2) + if (static_cast(ulModel) == VehicleType::VT_CAMPER && ucSeat > 2) + return false; + + // Get the maximum passenger count for the vehicle + unsigned char ucMaxPassengers = GetMaxPassengerCount(ulModel); + if (ucSeat > ucMaxPassengers) + return false; + + // Vehicles with unknown passenger count (255) can only have driver in seat 0 + if (ucSeat > 0 && ucMaxPassengers == 255) + return false; + + return true; +} + void CClientVehicleManager::GetRandomVariation(unsigned short usModel, unsigned char& ucVariant, unsigned char& ucVariant2) { RandomizeRandomSeed(); diff --git a/Client/mods/deathmatch/logic/CClientVehicleManager.h b/Client/mods/deathmatch/logic/CClientVehicleManager.h index c9d14d848d4..cd4c1b4ad49 100644 --- a/Client/mods/deathmatch/logic/CClientVehicleManager.h +++ b/Client/mods/deathmatch/logic/CClientVehicleManager.h @@ -50,6 +50,7 @@ class CClientVehicleManager static bool HasDamageModel(unsigned long ulModel); static bool HasDamageModel(enum eClientVehicleType Type); static bool HasDoors(unsigned long ulModel); + static bool IsValidSeat(unsigned long ulModel, unsigned char ucSeat); bool Exists(CClientVehicle* pVehicle); diff --git a/Client/mods/deathmatch/logic/CClientWater.h b/Client/mods/deathmatch/logic/CClientWater.h index 13277eef8ff..452613bf764 100644 --- a/Client/mods/deathmatch/logic/CClientWater.h +++ b/Client/mods/deathmatch/logic/CClientWater.h @@ -39,9 +39,9 @@ class CClientWater final : public CClientEntity private: CWaterPoly* m_pPoly; CClientWaterManager* m_pWaterManager; - bool m_bTriangle; // Is this water a triangle or a quad type? - bool m_bShallow; // Shallow water? - std::vector m_Vertices; // List of vertices for this water + bool m_bTriangle; // Is this water a triangle or a quad type? + bool m_bShallow; // Shallow water? + std::vector m_Vertices; // List of vertices for this water friend class CClientWaterManager; }; diff --git a/Client/mods/deathmatch/logic/CClientWeapon.cpp b/Client/mods/deathmatch/logic/CClientWeapon.cpp index 14f8e6338f3..37f47a842d7 100644 --- a/Client/mods/deathmatch/logic/CClientWeapon.cpp +++ b/Client/mods/deathmatch/logic/CClientWeapon.cpp @@ -309,10 +309,10 @@ void CClientWeapon::Fire(bool bServerFire) #ifdef SHOTGUN_TEST CVector vecFireOffset = *m_pWeaponInfo->GetFireOffset(); CMatrix matTemp = CMatrix(vecFireOffset) * matOrigin; -#ifdef MARKER_DEBUG + #ifdef MARKER_DEBUG // Process m_pMarker->SetPosition(matOrigin.GetPosition()); -#endif + #endif CVector vecTemp2; GetRotationDegrees(vecTemp2); vecTemp2.fZ -= 84.6f; @@ -419,18 +419,18 @@ void CClientWeapon::FireInstantHit(CVector vecOrigin, CVector vecTarget, bool bS CClientEntity* pClientEntity = pColEntity ? pPools->GetClientEntity((DWORD*)pColEntity->GetInterface()) : nullptr; CLuaArguments Arguments; if (pClientEntity) - Arguments.PushElement(pClientEntity); // entity that got hit + Arguments.PushElement(pClientEntity); // entity that got hit else - Arguments.PushNil(); // Probably a building. - Arguments.PushNumber(pColPoint->GetPosition().fX); // pos x - Arguments.PushNumber(pColPoint->GetPosition().fY); // pos y - Arguments.PushNumber(pColPoint->GetPosition().fZ); // pos z - Arguments.PushNumber(pColPoint->GetNormal().fX); // Normal x - Arguments.PushNumber(pColPoint->GetNormal().fY); // Normal y - Arguments.PushNumber(pColPoint->GetNormal().fZ); // Normal z - Arguments.PushNumber(pColPoint->GetSurfaceTypeB()); // Surface type "B" - Arguments.PushNumber(pColPoint->GetLightingForTimeOfDay()); // Lighting - Arguments.PushNumber(pColPoint->GetPieceTypeB()); // Piece + Arguments.PushNil(); // Probably a building. + Arguments.PushNumber(pColPoint->GetPosition().fX); // pos x + Arguments.PushNumber(pColPoint->GetPosition().fY); // pos y + Arguments.PushNumber(pColPoint->GetPosition().fZ); // pos z + Arguments.PushNumber(pColPoint->GetNormal().fX); // Normal x + Arguments.PushNumber(pColPoint->GetNormal().fY); // Normal y + Arguments.PushNumber(pColPoint->GetNormal().fZ); // Normal z + Arguments.PushNumber(pColPoint->GetSurfaceTypeB()); // Surface type "B" + Arguments.PushNumber(pColPoint->GetLightingForTimeOfDay()); // Lighting + Arguments.PushNumber(pColPoint->GetPieceTypeB()); // Piece if (!CallEvent("onClientWeaponFire", Arguments, true)) { if (pColPoint) diff --git a/Client/mods/deathmatch/logic/CClientWeapon.h b/Client/mods/deathmatch/logic/CClientWeapon.h index 00c400810d0..bc1dae9e4ce 100644 --- a/Client/mods/deathmatch/logic/CClientWeapon.h +++ b/Client/mods/deathmatch/logic/CClientWeapon.h @@ -124,7 +124,7 @@ class CClientWeapon final : public CClientObject eBone m_targetBone; int m_itargetWheel; SWeaponConfiguration m_weaponConfig; - CClientPlayerPtr m_pOwner; // For lag compensation + CClientPlayerPtr m_pOwner; // For lag compensation int m_nAmmoTotal; int m_nAmmoInClip; eWeaponState m_PreviousState; @@ -132,5 +132,5 @@ class CClientWeapon final : public CClientObject CElapsedTime m_reloadTimer; unsigned char m_ucCounter; int m_iWeaponFireRate; - CVector m_vecFireRotationNoTarget; // Rotation adjustment when firing directly forward + CVector m_vecFireRotationNoTarget; // Rotation adjustment when firing directly forward }; diff --git a/Client/mods/deathmatch/logic/CClientWebBrowser.cpp b/Client/mods/deathmatch/logic/CClientWebBrowser.cpp index 5284382d96a..c56adf8df46 100644 --- a/Client/mods/deathmatch/logic/CClientWebBrowser.cpp +++ b/Client/mods/deathmatch/logic/CClientWebBrowser.cpp @@ -16,10 +16,19 @@ CClientWebBrowser::CClientWebBrowser(CClientManager* pManager, ElementID ID, CWe { m_pResource = nullptr; m_pManager = pManager; + m_pWebView = nullptr; SetTypeName("webbrowser"); // Create the web view - m_pWebView = g_pCore->GetWebCore()->CreateWebView(pWebBrowserItem->m_uiSizeX, pWebBrowserItem->m_uiSizeY, bLocal, pWebBrowserItem, bTransparent); + const auto pWebCore = g_pCore->GetWebCore(); + if (!pWebCore) + { + return; + } + m_pWebView = pWebCore->CreateWebView(pWebBrowserItem->m_uiSizeX, pWebBrowserItem->m_uiSizeY, bLocal, pWebBrowserItem, bTransparent); + + if (!m_pWebView) + return; // Set events interface m_pWebView->SetWebBrowserEvents(this); @@ -30,11 +39,26 @@ CClientWebBrowser::CClientWebBrowser(CClientManager* pManager, ElementID ID, CWe CClientWebBrowser::~CClientWebBrowser() { - g_pCore->GetWebCore()->DestroyWebView(m_pWebView); - m_pWebView = nullptr; + // Mark as being destroyed to prevent event callbacks from executing + m_bBeingDestroyed = true; + + if (m_pWebView) + m_pWebView->ClearWebBrowserEvents(this); - // Unlink from tree + // Unlink from tree first to prevent event callbacks from reaching Unlink(); + + // Clear AJAX callback map to release any held references + m_mapAjaxCallback.clear(); + + if (m_pWebView) + { + // Use GetWebCoreUnchecked() to ensure cleanup even if initialization failed + const auto pWebCore = g_pCore->GetWebCoreUnchecked(); + if (pWebCore) + pWebCore->DestroyWebView(m_pWebView); + m_pWebView = nullptr; + } } void CClientWebBrowser::Unlink() @@ -48,36 +72,42 @@ void CClientWebBrowser::Unlink() bool CClientWebBrowser::IsLoading() { - return m_pWebView->IsLoading(); + return m_pWebView ? m_pWebView->IsLoading() : false; } bool CClientWebBrowser::LoadURL(const SString& strURL, bool bFilterEnabled, const SString& strPostData, bool bURLEncoded) { - return m_pWebView->LoadURL(strURL, bFilterEnabled, strPostData, bURLEncoded); + return m_pWebView ? m_pWebView->LoadURL(strURL, bFilterEnabled, strPostData, bURLEncoded) : false; } const SString& CClientWebBrowser::GetTitle() { - return m_pWebView->GetTitle(); + static SString empty; + return m_pWebView ? m_pWebView->GetTitle() : empty; } SString CClientWebBrowser::GetURL() { - return m_pWebView->GetURL(); + return m_pWebView ? m_pWebView->GetURL() : SString(); } void CClientWebBrowser::SetRenderingPaused(bool bPaused) { - m_pWebView->SetRenderingPaused(bPaused); + if (m_pWebView) + m_pWebView->SetRenderingPaused(bPaused); } void CClientWebBrowser::Focus() { - m_pWebView->Focus(); + if (m_pWebView) + m_pWebView->Focus(); } bool CClientWebBrowser::ExecuteJavascript(const SString& strJavascriptCode) { + if (!m_pWebView) + return false; + // Don't allow javascript code execution on remote websites if (!m_pWebView->IsLocal()) return false; @@ -88,82 +118,89 @@ bool CClientWebBrowser::ExecuteJavascript(const SString& strJavascriptCode) bool CClientWebBrowser::SetProperty(const SString& strKey, const SString& strValue) { - return m_pWebView->SetProperty(strKey, strValue); + return m_pWebView ? m_pWebView->SetProperty(strKey, strValue) : false; } bool CClientWebBrowser::GetProperty(const SString& strKey, SString& outValue) { - return m_pWebView->GetProperty(strKey, outValue); + return m_pWebView ? m_pWebView->GetProperty(strKey, outValue) : false; } void CClientWebBrowser::InjectMouseMove(int iPosX, int iPosY) { - m_pWebView->InjectMouseMove(iPosX, iPosY); + if (m_pWebView) + m_pWebView->InjectMouseMove(iPosX, iPosY); } void CClientWebBrowser::InjectMouseDown(eWebBrowserMouseButton mouseButton, int count) { - m_pWebView->InjectMouseDown(mouseButton, count); + if (m_pWebView) + m_pWebView->InjectMouseDown(mouseButton, count); } void CClientWebBrowser::InjectMouseUp(eWebBrowserMouseButton mouseButton) { - m_pWebView->InjectMouseUp(mouseButton); + if (m_pWebView) + m_pWebView->InjectMouseUp(mouseButton); } void CClientWebBrowser::InjectMouseWheel(int iScrollVert, int iScrollHorz) { - m_pWebView->InjectMouseWheel(iScrollVert, iScrollHorz); + if (m_pWebView) + m_pWebView->InjectMouseWheel(iScrollVert, iScrollHorz); } bool CClientWebBrowser::IsLocal() { - return m_pWebView->IsLocal(); + return m_pWebView ? m_pWebView->IsLocal() : false; } float CClientWebBrowser::GetAudioVolume() { - return m_pWebView->GetAudioVolume(); + return m_pWebView ? m_pWebView->GetAudioVolume() : 0.0f; } bool CClientWebBrowser::SetAudioVolume(float fVolume) { - return m_pWebView->SetAudioVolume(fVolume); + return m_pWebView ? m_pWebView->SetAudioVolume(fVolume) : false; } void CClientWebBrowser::GetSourceCode(const std::function& callback) { - return m_pWebView->GetSourceCode(callback); + if (m_pWebView) + m_pWebView->GetSourceCode(callback); } void CClientWebBrowser::Resize(const CVector2D& size) { - m_pWebView->Resize(size); + if (m_pWebView) + m_pWebView->Resize(size); } bool CClientWebBrowser::CanGoBack() { - return m_pWebView->CanGoBack(); + return m_pWebView ? m_pWebView->CanGoBack() : false; } bool CClientWebBrowser::CanGoForward() { - return m_pWebView->CanGoForward(); + return m_pWebView ? m_pWebView->CanGoForward() : false; } bool CClientWebBrowser::GoBack() { - return m_pWebView->GoBack(); + return m_pWebView ? m_pWebView->GoBack() : false; } bool CClientWebBrowser::GoForward() { - return m_pWebView->GoForward(); + return m_pWebView ? m_pWebView->GoForward() : false; } void CClientWebBrowser::Refresh(bool bIgnoreCache) { - m_pWebView->Refresh(bIgnoreCache); + if (m_pWebView) + m_pWebView->Refresh(bIgnoreCache); } //////////////////////////////////////////////////////////////////////////// @@ -173,12 +210,18 @@ void CClientWebBrowser::Refresh(bool bIgnoreCache) //////////////////////////////////////////////////////////////////////////// void CClientWebBrowser::Events_OnCreated() { + if (m_bBeingDestroyed) + return; + CLuaArguments Arguments; CallEvent("onClientBrowserCreated", Arguments, false); } void CClientWebBrowser::Events_OnLoadingStart(const SString& strURL, bool bMainFrame) { + if (m_bBeingDestroyed) + return; + CLuaArguments Arguments; Arguments.PushString(strURL); Arguments.PushBoolean(bMainFrame); @@ -187,6 +230,9 @@ void CClientWebBrowser::Events_OnLoadingStart(const SString& strURL, bool bMainF void CClientWebBrowser::Events_OnDocumentReady(const SString& strURL) { + if (m_bBeingDestroyed) + return; + CLuaArguments Arguments; Arguments.PushString(strURL); CallEvent("onClientBrowserDocumentReady", Arguments, false); @@ -194,6 +240,9 @@ void CClientWebBrowser::Events_OnDocumentReady(const SString& strURL) void CClientWebBrowser::Events_OnLoadingFailed(const SString& strURL, int errorCode, const SString& errorDescription) { + if (m_bBeingDestroyed) + return; + CLuaArguments Arguments; Arguments.PushString(strURL); Arguments.PushNumber(errorCode); @@ -203,6 +252,9 @@ void CClientWebBrowser::Events_OnLoadingFailed(const SString& strURL, int errorC void CClientWebBrowser::Events_OnNavigate(const SString& strURL, bool bIsBlocked, bool bIsMainFrame) { + if (m_bBeingDestroyed) + return; + CLuaArguments Arguments; Arguments.PushString(strURL); Arguments.PushBoolean(bIsBlocked); @@ -212,6 +264,9 @@ void CClientWebBrowser::Events_OnNavigate(const SString& strURL, bool bIsBlocked void CClientWebBrowser::Events_OnPopup(const SString& strTargetURL, const SString& strOpenerURL) { + if (m_bBeingDestroyed) + return; + CLuaArguments Arguments; Arguments.PushString(strTargetURL); Arguments.PushString(strOpenerURL); @@ -220,6 +275,9 @@ void CClientWebBrowser::Events_OnPopup(const SString& strTargetURL, const SStrin void CClientWebBrowser::Events_OnChangeCursor(unsigned char ucCursor) { + if (m_bBeingDestroyed) + return; + CLuaArguments Arguments; Arguments.PushNumber(ucCursor); CallEvent("onClientBrowserCursorChange", Arguments, false); @@ -239,6 +297,9 @@ void CClientWebBrowser::Events_OnTriggerEvent(const SString& strEventName, const void CClientWebBrowser::Events_OnTooltip(const SString& strTooltip) { + if (m_bBeingDestroyed) + return; + CLuaArguments Arguments; Arguments.PushString(strTooltip); CallEvent("onClientBrowserTooltip", Arguments, false); @@ -246,6 +307,9 @@ void CClientWebBrowser::Events_OnTooltip(const SString& strTooltip) void CClientWebBrowser::Events_OnInputFocusChanged(bool bGainedFocus) { + if (m_bBeingDestroyed) + return; + CLuaArguments Arguments; Arguments.PushBoolean(bGainedFocus); CallEvent("onClientBrowserInputFocusChanged", Arguments, false); @@ -253,11 +317,14 @@ void CClientWebBrowser::Events_OnInputFocusChanged(bool bGainedFocus) bool CClientWebBrowser::Events_OnResourcePathCheck(SString& strURL) { + if (m_bBeingDestroyed) + return false; + // If no resource is set, we are allowed to use the requested file if (!m_pResource) return true; - CResource* pTempResource = m_pResource; // Make a copy to ignore a changed resource + CResource* pTempResource = m_pResource; // Make a copy to ignore a changed resource if (CResourceManager::ParseResourcePathInput(strURL, pTempResource, &strURL)) return true; @@ -267,6 +334,9 @@ bool CClientWebBrowser::Events_OnResourcePathCheck(SString& strURL) bool CClientWebBrowser::Events_OnResourceFileCheck(const SString& strPath, CBuffer& outFileData) { + if (m_bBeingDestroyed) + return false; + // If no resource is set, we do not require to verify the file if (!m_pResource) return true; @@ -283,6 +353,9 @@ bool CClientWebBrowser::Events_OnResourceFileCheck(const SString& strPath, CBuff void CClientWebBrowser::Events_OnResourceBlocked(const SString& strURL, const SString& strDomain, unsigned char reason) { + if (m_bBeingDestroyed) + return; + CLuaArguments Arguments; Arguments.PushString(strURL); Arguments.PushString(strDomain); @@ -292,6 +365,12 @@ void CClientWebBrowser::Events_OnResourceBlocked(const SString& strURL, const SS void CClientWebBrowser::Events_OnAjaxRequest(CAjaxResourceHandlerInterface* pHandler, const SString& strURL) { + if (m_bBeingDestroyed) + { + pHandler->SetResponse(""); + return; + } + auto callbackMapEntry = m_mapAjaxCallback.find(strURL); if (callbackMapEntry == m_mapAjaxCallback.end()) @@ -300,13 +379,16 @@ void CClientWebBrowser::Events_OnAjaxRequest(CAjaxResourceHandlerInterface* pHan return; } - auto callback = callbackMapEntry->second; - SString result = callback(pHandler->GetGetData(), pHandler->GetPostData()); - pHandler->SetResponse(result); + auto& callback = callbackMapEntry->second; + std::string result = callback(pHandler->GetGetData(), pHandler->GetPostData()); + pHandler->SetResponse(std::move(result)); } void CClientWebBrowser::Events_OnConsoleMessage(const std::string& message, const std::string& source, int line, std::int16_t level) { + if (m_bBeingDestroyed) + return; + CLuaArguments arguments; arguments.PushString(message); arguments.PushString(source); @@ -317,6 +399,9 @@ void CClientWebBrowser::Events_OnConsoleMessage(const std::string& message, cons bool CClientWebBrowser::AddAjaxHandler(const SString& strURL, ajax_callback_t& handler) { + if (!m_pWebView) + return false; + if (!m_pWebView->RegisterAjaxHandler(strURL)) return false; @@ -326,6 +411,9 @@ bool CClientWebBrowser::AddAjaxHandler(const SString& strURL, ajax_callback_t& h bool CClientWebBrowser::RemoveAjaxHandler(const SString& strURL) { + if (!m_pWebView) + return false; + if (!m_pWebView->UnregisterAjaxHandler(strURL)) return false; @@ -334,21 +422,30 @@ bool CClientWebBrowser::RemoveAjaxHandler(const SString& strURL) bool CClientWebBrowser::ToggleDevTools(bool visible) { - return m_pWebView->ToggleDevTools(visible); + return m_pWebView ? m_pWebView->ToggleDevTools(visible) : false; } CClientGUIWebBrowser::CClientGUIWebBrowser(bool isLocal, bool isTransparent, uint width, uint height, CClientManager* pManager, CLuaMain* pLuaMain, CGUIElement* pCGUIElement, ElementID ID) - : CClientGUIElement(pManager, pLuaMain, pCGUIElement, ID) + : CClientGUIElement(pManager, pLuaMain, pCGUIElement, ID), m_pBrowser(nullptr) { m_pManager = pManager; - m_pBrowser = g_pClientGame->GetManager()->GetRenderElementManager()->CreateWebBrowser(width, height, isLocal, isTransparent); - if (m_pBrowser) + if (!g_pClientGame || !pLuaMain) + return; + + CClientWebBrowser* pBrowser = g_pClientGame->GetManager()->GetRenderElementManager()->CreateWebBrowser(width, height, isLocal, isTransparent); + + if (pBrowser) { - m_pBrowser->SetParent(this); // m_pBrowser gets deleted automatically by the element tree logic + // Store immediately so destructor can always find it + m_pBrowser = pBrowser; + + // Set our owner resource BEFORE transferring ownership to element tree + pBrowser->SetResource(pLuaMain->GetResource()); - // Set our owner resource - m_pBrowser->SetResource(pLuaMain->GetResource()); + // Transfer ownership to element tree by setting parent + // After this call, the element tree is responsible for cleanup + pBrowser->SetParent(this); } } diff --git a/Client/mods/deathmatch/logic/CClientWebBrowser.h b/Client/mods/deathmatch/logic/CClientWebBrowser.h index 9838d2a5330..2cdb5999d3e 100644 --- a/Client/mods/deathmatch/logic/CClientWebBrowser.h +++ b/Client/mods/deathmatch/logic/CClientWebBrowser.h @@ -31,7 +31,7 @@ class CClientWebBrowser : public CClientTexture, public CWebBrowserEventsInterfa const SString& GetTitle(); SString GetURL(); void SetRenderingPaused(bool bPaused); - const bool GetRenderingPaused() const { return m_pWebView->GetRenderingPaused(); } + const bool GetRenderingPaused() const { return m_pWebView ? m_pWebView->GetRenderingPaused() : false; } void Focus(); bool ExecuteJavascript(const SString& strJavascriptCode); @@ -56,7 +56,7 @@ class CClientWebBrowser : public CClientTexture, public CWebBrowserEventsInterfa void Resize(const CVector2D& size); - using ajax_callback_t = const std::function& vecGet, std::vector& vecPost)>; + using ajax_callback_t = const std::function& vecGet, std::vector& vecPost)>; bool AddAjaxHandler(const SString& strURL, ajax_callback_t& handler); bool RemoveAjaxHandler(const SString& strURL); @@ -90,6 +90,7 @@ class CClientWebBrowser : public CClientTexture, public CWebBrowserEventsInterfa CWebViewInterface* m_pWebView; CResource* m_pResource; std::map m_mapAjaxCallback; + bool m_bBeingDestroyed = false; }; class CClientGUIWebBrowser : public CClientGUIElement @@ -101,5 +102,5 @@ class CClientGUIWebBrowser : public CClientGUIElement CClientWebBrowser* GetBrowser() { return m_pBrowser; } private: - CClientWebBrowser* m_pBrowser; + CClientWebBrowser* m_pBrowser = nullptr; }; diff --git a/Client/mods/deathmatch/logic/CCustomData.cpp b/Client/mods/deathmatch/logic/CCustomData.cpp index 8f441030783..355ab5f0973 100644 --- a/Client/mods/deathmatch/logic/CCustomData.cpp +++ b/Client/mods/deathmatch/logic/CCustomData.cpp @@ -14,30 +14,30 @@ void CCustomData::Copy(CCustomData* pCustomData) { - std::map::const_iterator iter = pCustomData->IterBegin(); + auto iter = pCustomData->IterBegin(); for (; iter != pCustomData->IterEnd(); iter++) { - Set(iter->first.c_str(), iter->second.Variable); + Set(iter->first, iter->second.Variable); } } -SCustomData* CCustomData::Get(const char* szName) +SCustomData* CCustomData::Get(const CStringName& name) { - assert(szName); + assert(name); - std::map::iterator it = m_Data.find(szName); + auto it = m_Data.find(name); if (it != m_Data.end()) return &it->second; return NULL; } -void CCustomData::Set(const char* szName, const CLuaArgument& Variable, bool bSynchronized) +void CCustomData::Set(const CStringName& name, const CLuaArgument& Variable, bool bSynchronized) { - assert(szName); + assert(name); // Grab the item with the given name - SCustomData* pData = Get(szName); + SCustomData* pData = Get(name); if (pData) { // Update existing @@ -50,14 +50,14 @@ void CCustomData::Set(const char* szName, const CLuaArgument& Variable, bool bSy SCustomData newData; newData.Variable = Variable; newData.bSynchronized = bSynchronized; - m_Data[szName] = newData; + m_Data[name] = newData; } } -bool CCustomData::Delete(const char* szName) +bool CCustomData::Delete(const CStringName& name) { // Find the item and delete it - std::map::iterator it = m_Data.find(szName); + auto it = m_Data.find(name); if (it != m_Data.end()) { m_Data.erase(it); diff --git a/Client/mods/deathmatch/logic/CCustomData.h b/Client/mods/deathmatch/logic/CCustomData.h index 01e5eb81cdb..6219750266b 100644 --- a/Client/mods/deathmatch/logic/CCustomData.h +++ b/Client/mods/deathmatch/logic/CCustomData.h @@ -11,6 +11,7 @@ #pragma once #include "lua/CLuaArgument.h" +#include "CStringName.h" #define MAX_CUSTOMDATA_NAME_LENGTH 128 @@ -25,14 +26,14 @@ class CCustomData public: void Copy(CCustomData* pCustomData); - SCustomData* Get(const char* szName); - void Set(const char* szName, const CLuaArgument& Variable, bool bSynchronized = true); + SCustomData* Get(const CStringName& name); + void Set(const CStringName& name, const CLuaArgument& Variable, bool bSynchronized = true); - bool Delete(const char* szName); + bool Delete(const CStringName& name); - std::map::const_iterator IterBegin() { return m_Data.begin(); } - std::map::const_iterator IterEnd() { return m_Data.end(); } + std::unordered_map::const_iterator IterBegin() { return m_Data.begin(); } + std::unordered_map::const_iterator IterEnd() { return m_Data.end(); } private: - std::map m_Data; + std::unordered_map m_Data; }; diff --git a/Client/mods/deathmatch/logic/CDeathmatchObject.cpp b/Client/mods/deathmatch/logic/CDeathmatchObject.cpp index 36f2dd81497..cd950285a85 100644 --- a/Client/mods/deathmatch/logic/CDeathmatchObject.cpp +++ b/Client/mods/deathmatch/logic/CDeathmatchObject.cpp @@ -102,8 +102,8 @@ void CDeathmatchObject::UpdateMovement() if (!bStillRunning) { - _StopMovement(false); // We don't unregister ourselves here since CDeathmatchObject::UpdateMovement is called from an iteration in - // CMovingObjectsManager::DoPulse + _StopMovement(false); // We don't unregister ourselves here since CDeathmatchObject::UpdateMovement is called from an iteration in + // CMovingObjectsManager::DoPulse // and we are automatically removed from the list after CDeathmatchObject::UpdateMovement if we are finished } } diff --git a/Client/mods/deathmatch/logic/CDeathmatchVehicle.cpp b/Client/mods/deathmatch/logic/CDeathmatchVehicle.cpp index ccccfbf123e..31ac68753b5 100644 --- a/Client/mods/deathmatch/logic/CDeathmatchVehicle.cpp +++ b/Client/mods/deathmatch/logic/CDeathmatchVehicle.cpp @@ -46,7 +46,7 @@ bool CDeathmatchVehicle::SyncDamageModel() bool bChanges = false; // Copy current door states to the sync structure and mark those that changed - for (unsigned int i = 0; i < MAX_DOORS; ++i) + for (unsigned char i = 0; i < MAX_DOORS; ++i) { damage.data.ucDoorStates[i] = GetDoorStatus(i); if (damage.data.ucDoorStates[i] != m_ucLastDoorStates[i]) @@ -58,7 +58,7 @@ bool CDeathmatchVehicle::SyncDamageModel() damage.data.bDoorStatesChanged[i] = false; } // Copy current wheel states to the sync structure and mark those that changed - for (unsigned int i = 0; i < MAX_WHEELS; ++i) + for (unsigned char i = 0; i < MAX_WHEELS; ++i) { damage.data.ucWheelStates[i] = GetWheelStatus(i); if (damage.data.ucWheelStates[i] != m_ucLastWheelStates[i]) @@ -70,7 +70,7 @@ bool CDeathmatchVehicle::SyncDamageModel() damage.data.bWheelStatesChanged[i] = false; } // Copy current panel states to the sync structure and mark those that changed - for (unsigned int i = 0; i < MAX_PANELS; ++i) + for (unsigned char i = 0; i < MAX_PANELS; ++i) { damage.data.ucPanelStates[i] = GetPanelStatus(i); if (damage.data.ucPanelStates[i] != m_ucLastPanelStates[i]) @@ -82,7 +82,7 @@ bool CDeathmatchVehicle::SyncDamageModel() damage.data.bPanelStatesChanged[i] = false; } // Copy current light states to the sync structure and mark those that changed - for (unsigned int i = 0; i < MAX_LIGHTS; ++i) + for (unsigned char i = 0; i < MAX_LIGHTS; ++i) { damage.data.ucLightStates[i] = GetLightStatus(i); if (damage.data.ucLightStates[i] != m_ucLastLightStates[i]) @@ -124,12 +124,12 @@ bool CDeathmatchVehicle::SyncDamageModel() void CDeathmatchVehicle::ResetDamageModelSync() { - for (int i = 0; i < MAX_DOORS; i++) + for (unsigned char i = 0; i < MAX_DOORS; i++) m_ucLastDoorStates[i] = GetDoorStatus(i); - for (int i = 0; i < MAX_WHEELS; i++) + for (unsigned char i = 0; i < MAX_WHEELS; i++) m_ucLastWheelStates[i] = GetWheelStatus(i); - for (int i = 0; i < MAX_PANELS; i++) + for (unsigned char i = 0; i < MAX_PANELS; i++) m_ucLastPanelStates[i] = GetPanelStatus(i); - for (int i = 0; i < MAX_LIGHTS; i++) + for (unsigned char i = 0; i < MAX_LIGHTS; i++) m_ucLastLightStates[i] = GetLightStatus(i); } diff --git a/Client/mods/deathmatch/logic/CDownloadableResource.cpp b/Client/mods/deathmatch/logic/CDownloadableResource.cpp index a070a066f7e..db04323bd9f 100644 --- a/Client/mods/deathmatch/logic/CDownloadableResource.cpp +++ b/Client/mods/deathmatch/logic/CDownloadableResource.cpp @@ -11,6 +11,24 @@ #include +static bool s_bChecksumBatchActive = false; +static int64_t s_checksumBatchAccumMs = 0; + +void CDownloadableResource::BeginChecksumBatch() +{ + if (!s_bChecksumBatchActive) + { + s_bChecksumBatchActive = true; + s_checksumBatchAccumMs = 0; + } +} + +void CDownloadableResource::EndChecksumBatch() +{ + s_bChecksumBatchActive = false; + s_checksumBatchAccumMs = 0; +} + CDownloadableResource::CDownloadableResource(CResource* pResource, eResourceType resourceType, const char* szName, const char* szNameShort, uint uiDownloadSize, CChecksum serverChecksum, bool bAutoDownload) { @@ -25,6 +43,7 @@ CDownloadableResource::CDownloadableResource(CResource* pResource, eResourceType m_uiDownloadSize = uiDownloadSize; m_uiHttpServerIndex = 0; m_bModifedByScript = false; + m_bClientChecksumVerified = false; GenerateClientChecksum(); g_pClientGame->GetResourceManager()->OnAddResourceFile(this); @@ -38,24 +57,47 @@ CDownloadableResource::~CDownloadableResource() bool CDownloadableResource::DoesClientAndServerChecksumMatch() { - return (m_LastClientChecksum == m_ServerChecksum); + return !m_bClientChecksumVerified || (m_LastClientChecksum == m_ServerChecksum); } CChecksum CDownloadableResource::GenerateClientChecksum() { + constexpr int64_t BATCH_BUDGET_MS = 5000; + + if (s_bChecksumBatchActive && s_checksumBatchAccumMs >= BATCH_BUDGET_MS) + { + m_LastClientChecksum = CChecksum(); + m_bClientChecksumVerified = false; + return m_LastClientChecksum; + } + + long long startMs = GetTickCount64_(); m_LastClientChecksum = CChecksum::GenerateChecksumFromFileUnsafe(m_strName); + m_bClientChecksumVerified = true; + + if (s_bChecksumBatchActive) + s_checksumBatchAccumMs += GetTickCount64_() - startMs; + return m_LastClientChecksum; } CChecksum CDownloadableResource::GenerateClientChecksum(CBuffer& outFileData) { - // If LoadFromFile fails, a default initialized checksum is returned (just like GenerateClientChecksum() behaves) if (outFileData.LoadFromFile(m_strName)) m_LastClientChecksum = CChecksum::GenerateChecksumFromBuffer(outFileData.GetData(), outFileData.GetSize()); + else + m_LastClientChecksum = CChecksum(); + + m_bClientChecksumVerified = true; return m_LastClientChecksum; } +CChecksum CDownloadableResource::GetLastClientChecksum() +{ + return m_LastClientChecksum; +} + CChecksum CDownloadableResource::GetServerChecksum() { return m_ServerChecksum; diff --git a/Client/mods/deathmatch/logic/CDownloadableResource.h b/Client/mods/deathmatch/logic/CDownloadableResource.h index f4fe9ee9633..f0482340a45 100644 --- a/Client/mods/deathmatch/logic/CDownloadableResource.h +++ b/Client/mods/deathmatch/logic/CDownloadableResource.h @@ -13,9 +13,9 @@ #ifndef _WINDOWS_ -#define WIN32_LEAN_AND_MEAN // Exclude all uncommon functions from windows.h to reduce build time by 100ms + #define WIN32_LEAN_AND_MEAN // Exclude all uncommon functions from windows.h to reduce build time by 100ms -#include + #include #endif #include @@ -40,6 +40,9 @@ class CDownloadableResource CChecksum serverChecksum, bool bAutoDownload); virtual ~CDownloadableResource(); + static void BeginChecksumBatch(); + static void EndChecksumBatch(); + bool DoesClientAndServerChecksumMatch(); eResourceType GetResourceType() { return m_resourceType; }; @@ -53,7 +56,14 @@ class CDownloadableResource CChecksum GenerateClientChecksum(); CChecksum GenerateClientChecksum(CBuffer& outFileData); + CChecksum GetLastClientChecksum(); CChecksum GetServerChecksum(); + bool HasVerifiedClientChecksum() { return m_bClientChecksumVerified; }; + void SetLastClientChecksum(CChecksum checksum) + { + m_LastClientChecksum = checksum; + m_bClientChecksumVerified = true; + } bool IsAutoDownload() { return m_bAutoDownload; }; void SetDownloaded() { m_bDownloaded = true; }; @@ -74,9 +84,10 @@ class CDownloadableResource CChecksum m_ServerChecksum; bool m_bAutoDownload; - bool m_bInDownloadQueue; // File in auto download queue - bool m_bDownloaded; // File has been downloaded and is ready to use + bool m_bInDownloadQueue; // File in auto download queue + bool m_bDownloaded; // File has been downloaded and is ready to use uint m_uiDownloadSize; uint m_uiHttpServerIndex; bool m_bModifedByScript; + bool m_bClientChecksumVerified; }; diff --git a/Client/mods/deathmatch/logic/CDynamicLibrary.cpp b/Client/mods/deathmatch/logic/CDynamicLibrary.cpp index b3d13162822..0f6d6b72c4f 100644 --- a/Client/mods/deathmatch/logic/CDynamicLibrary.cpp +++ b/Client/mods/deathmatch/logic/CDynamicLibrary.cpp @@ -29,10 +29,10 @@ bool CDynamicLibrary::Load(const char* szFilename) // Unload the previous library Unload(); - // Load the new library - #ifdef WIN32 +// Load the new library +#ifdef WIN32 m_hModule = LoadLibrary(szFilename); - #else +#else m_hModule = dlopen(szFilename, RTLD_NOW); // Output error if needed @@ -40,7 +40,7 @@ bool CDynamicLibrary::Load(const char* szFilename) { Print("%s\n", dlerror()); } - #endif +#endif // Return whether we succeeded or not return m_hModule != 0; @@ -51,11 +51,11 @@ void CDynamicLibrary::Unload() // Got a module? if (m_hModule != 0) { - #ifdef WIN32 +#ifdef WIN32 FreeLibrary(m_hModule); - #else +#else dlclose(m_hModule); - #endif +#endif // Zero out our library as it's no longer valid m_hModule = 0; @@ -72,9 +72,9 @@ void* CDynamicLibrary::GetProcedureAddress(const char* szProcName) // Got a module? if (m_hModule != 0) { - #ifdef WIN32 +#ifdef WIN32 return GetProcAddress(m_hModule, szProcName); - #else +#else char* szError = NULL; dlerror(); @@ -85,7 +85,7 @@ void* CDynamicLibrary::GetProcedureAddress(const char* szProcName) } return pFunc; - #endif +#endif } return NULL; diff --git a/Client/mods/deathmatch/logic/CDynamicLibrary.h b/Client/mods/deathmatch/logic/CDynamicLibrary.h index 55daf8e2d14..f070cac8201 100644 --- a/Client/mods/deathmatch/logic/CDynamicLibrary.h +++ b/Client/mods/deathmatch/logic/CDynamicLibrary.h @@ -12,7 +12,7 @@ #pragma once #ifdef WIN32 -#include + #include #endif class CDynamicLibrary @@ -28,9 +28,9 @@ class CDynamicLibrary void* GetProcedureAddress(const char* szProcName); private: - #ifdef WIN32 +#ifdef WIN32 HMODULE m_hModule; - #else +#else void* m_hModule; - #endif +#endif }; diff --git a/Client/mods/deathmatch/logic/CElementGroup.cpp b/Client/mods/deathmatch/logic/CElementGroup.cpp index 2cf2aaeb2d3..50b86523e4e 100644 --- a/Client/mods/deathmatch/logic/CElementGroup.cpp +++ b/Client/mods/deathmatch/logic/CElementGroup.cpp @@ -49,4 +49,4 @@ void CElementGroup::Remove(class CClientEntity* element) unsigned int CElementGroup::GetCount() { return m_elements.size(); -} \ No newline at end of file +} diff --git a/Client/mods/deathmatch/logic/CIFPEngine.cpp b/Client/mods/deathmatch/logic/CIFPEngine.cpp index 1dea9d0df22..2a5f0a04d53 100644 --- a/Client/mods/deathmatch/logic/CIFPEngine.cpp +++ b/Client/mods/deathmatch/logic/CIFPEngine.cpp @@ -50,8 +50,15 @@ bool CIFPEngine::EngineReplaceAnimation(CClientEntity* pEntity, const SString& s std::shared_ptr pCustomIFP = g_pClientGame->GetIFPPointerFromMap(u32BlockNameHash); if (pInternalBlock && pCustomIFP) { - // Try to load the block, if it's not loaded already - pInternalBlock->Request(BLOCKING, true); + if (!pInternalBlock->IsLoaded()) + { + // Request non-blocking load to avoid freezes from synchronous I/O (e.g. during resource cleanup). + // Only request if no existing refs, to avoid inflating ref count on repeated calls. + if (pInternalBlock->GetRefs() == 0) + pInternalBlock->Request(NON_BLOCKING); + + return false; + } auto pInternalAnimHierarchy = g_pGame->GetAnimManager()->GetAnimation(strInternalAnimName, pInternalBlock); CAnimBlendHierarchySAInterface* pCustomAnimHierarchyInterface = pCustomIFP->GetAnimationHierarchy(strCustomAnimName); diff --git a/Client/mods/deathmatch/logic/CLogger.cpp b/Client/mods/deathmatch/logic/CLogger.cpp index 930fde4e1a0..bfdbe42a6a9 100644 --- a/Client/mods/deathmatch/logic/CLogger.cpp +++ b/Client/mods/deathmatch/logic/CLogger.cpp @@ -47,7 +47,7 @@ void CLogger::LogPrintfNoStamp(const char* szFormat, ...) HandleLogPrint(false, "", szBuffer, true, true); } -#if 0 // Currently unused +#if 0 // Currently unused void CLogger::LogPrintNoStamp ( const char* szText ) { // Send to the console and logfile @@ -68,7 +68,7 @@ void CLogger::ErrorPrintf(const char* szFormat, ...) HandleLogPrint(true, "ERROR: ", szBuffer, true, true); } -#if 0 // Currently unused +#if 0 // Currently unused void CLogger::DebugPrintf ( const char* szFormat, ... ) { #ifdef MTA_DEBUG diff --git a/Client/mods/deathmatch/logic/CMapEventManager.cpp b/Client/mods/deathmatch/logic/CMapEventManager.cpp index 27042ffa1cb..fd8a47af26d 100644 --- a/Client/mods/deathmatch/logic/CMapEventManager.cpp +++ b/Client/mods/deathmatch/logic/CMapEventManager.cpp @@ -120,7 +120,8 @@ void CMapEventManager::DeleteAll() m_bHasEvents = !m_EventsMap.empty(); } -bool CMapEventManager::Call(const char* szName, const CLuaArguments& Arguments, class CClientEntity* pSource, class CClientEntity* pThis) +bool CMapEventManager::Call(const char* szName, const CLuaArguments& Arguments, class CClientEntity* pSource, class CClientEntity* pThis, + const char* minClientVersion) { // Check if no events if (!m_bHasEvents) @@ -144,6 +145,7 @@ bool CMapEventManager::Call(const char* szName, const CLuaArguments& Arguments, // Copy the results into a array in case m_EventsMap is modified during the call std::vector matchingEvents; + matchingEvents.reserve(8); for (EventsIter iter = itPair.first; iter != itPair.second; ++iter) matchingEvents.push_back(iter->second); @@ -161,13 +163,20 @@ bool CMapEventManager::Call(const char* szName, const CLuaArguments& Arguments, if (pSource == pThis || pMapEvent->IsPropagated()) { // Grab the current VM - lua_State* pState = pMapEvent->GetVM()->GetVM(); + CLuaMain* luaMain = pMapEvent->GetVM(); + lua_State* pState = luaMain->GetVM(); - LUA_CHECKSTACK(pState, 1); // Ensure some room + if (minClientVersion != nullptr) + { + if (luaMain->GetResource()->GetMinClientReq() < minClientVersion) + continue; + } - #if MTA_DEBUG + LUA_CHECKSTACK(pState, 1); // Ensure some room + +#if MTA_DEBUG int luaStackPointer = lua_gettop(pState); - #endif +#endif TIMEUS startTime = GetTimeUs(); @@ -182,7 +191,7 @@ bool CMapEventManager::Call(const char* szName, const CLuaArguments& Arguments, // Record event for the crash dump writer static bool bEnabled = (g_pCore->GetDiagnosticDebug() == EDiagnosticDebug::LUA_TRACE_0000); if (bEnabled) - g_pCore->LogEvent(0, "Lua Event", pMapEvent->GetVM()->GetScriptName(), szName); + g_pCore->LogEvent(0, "Lua Event", luaMain->GetScriptName(), szName); if (!g_pClientGame->GetDebugHookManager()->OnPreEventFunction(szName, Arguments, pSource, nullptr, pMapEvent)) continue; @@ -222,7 +231,7 @@ bool CMapEventManager::Call(const char* szName, const CLuaArguments& Arguments, lua_pushresource(pState, pSourceResource); lua_setglobal(pState, "sourceResource"); - lua_pushelement(pState, pSourceResource->GetResourceDynamicEntity()); + lua_pushelement(pState, pSourceResource->GetResourceEntity()); lua_setglobal(pState, "sourceResourceRoot"); } else @@ -259,9 +268,9 @@ bool CMapEventManager::Call(const char* szName, const CLuaArguments& Arguments, OldEventName.Push(pState); lua_setglobal(pState, "eventName"); - #if MTA_DEBUG +#if MTA_DEBUG assert(lua_gettop(pState) == luaStackPointer); - #endif +#endif // Aspect ratio adjustment bodges if (pMapEvent->ShouldAllowAspectRatioAdjustment()) @@ -274,9 +283,9 @@ bool CMapEventManager::Call(const char* szName, const CLuaArguments& Arguments, if (deltaTimeUs > 3000) if (IS_TIMING_CHECKPOINTS()) - strStatus += SString(" (%s %d ms)", pMapEvent->GetVM()->GetScriptName(), deltaTimeUs / 1000); + strStatus += SString(" (%s %d ms)", luaMain->GetScriptName(), deltaTimeUs / 1000); - CClientPerfStatLuaTiming::GetSingleton()->UpdateLuaTiming(pMapEvent->GetVM(), szName, deltaTimeUs); + CClientPerfStatLuaTiming::GetSingleton()->UpdateLuaTiming(luaMain, szName, deltaTimeUs); } } } @@ -400,4 +409,4 @@ void CMapEventManager::GetHandles(CLuaMain* pLuaMain, const char* szName, lua_St } } } -} \ No newline at end of file +} diff --git a/Client/mods/deathmatch/logic/CMapEventManager.h b/Client/mods/deathmatch/logic/CMapEventManager.h index e6500fefdd3..99d61483154 100644 --- a/Client/mods/deathmatch/logic/CMapEventManager.h +++ b/Client/mods/deathmatch/logic/CMapEventManager.h @@ -28,7 +28,8 @@ class CMapEventManager bool HasEvents() const { return m_bHasEvents; } void GetHandles(CLuaMain* pLuaMain, const char* szName, lua_State* luaVM); - bool Call(const char* szName, const CLuaArguments& Arguments, class CClientEntity* pSource, class CClientEntity* pThis); + bool Call(const char* szName, const CLuaArguments& Arguments, class CClientEntity* pSource, class CClientEntity* pThis, + const char* minClientVersion = nullptr); private: void TakeOutTheTrash(); diff --git a/Client/mods/deathmatch/logic/CModelNames.cpp b/Client/mods/deathmatch/logic/CModelNames.cpp index 35ff4224eda..d090f3c981f 100644 --- a/Client/mods/deathmatch/logic/CModelNames.cpp +++ b/Client/mods/deathmatch/logic/CModelNames.cpp @@ -4808,7 +4808,7 @@ struct 333, "Golf_Club", 334, - "Night_Strick", // typo here retained for BC + "Night_Strick", // typo here retained for BC 334, "Night_Stick", 335, @@ -29324,7 +29324,7 @@ uint32 CModelNames::ResolveModelID(const SString& strModelName) { uint32 usModelID = atoi(strModelName.SubStr(3)); if (usModelID) - return g_pGame->GetBaseIDforTXD() + usModelID; // Encode global txd as model id 20000+ + return g_pGame->GetBaseIDforTXD() + usModelID; // Encode global txd as model id 20000+ } // Now search for the name @@ -29362,12 +29362,12 @@ void CModelNames::InitializeMaps() } // Include vehicle names as well - for (uint i = 400; i <= 610; i++) + for (uint32_t i = 400; i <= 610; i++) { - ushort usID = i; + uint32_t modelId = i; const char* szName = CVehicleNames::GetVehicleName(i); - MapSet(ms_ModelIDNameMap, usID, szName); - MapSet(ms_NameModelIDMap, SStringX(szName).ToLower(), usID); + MapSet(ms_ModelIDNameMap, modelId, szName); + MapSet(ms_NameModelIDMap, SStringX(szName).ToLower(), modelId); } assert(NUMELMS(playerClothesModel) == CLOTHES_MODEL_ID_LAST - CLOTHES_MODEL_ID_FIRST + 1); diff --git a/Client/mods/deathmatch/logic/CModelNames.h b/Client/mods/deathmatch/logic/CModelNames.h index ffc21e18d55..75a28b668ef 100644 --- a/Client/mods/deathmatch/logic/CModelNames.h +++ b/Client/mods/deathmatch/logic/CModelNames.h @@ -8,11 +8,11 @@ * *****************************************************************************/ -#define CLOTHES_MODEL_ID_FIRST 30000 -#define CLOTHES_MODEL_ID_LAST 30151 -#define CLOTHES_TEX_ID_FIRST 30152 -#define CLOTHES_TEX_ID_LAST 30541 -#define INVALID_MODEL_ID 32000 +#define CLOTHES_MODEL_ID_FIRST 30000 +#define CLOTHES_MODEL_ID_LAST 30151 +#define CLOTHES_TEX_ID_FIRST 30152 +#define CLOTHES_TEX_ID_LAST 30541 +#define INVALID_MODEL_ID 32000 class CModelNames { diff --git a/Client/mods/deathmatch/logic/CModelRenderer.cpp b/Client/mods/deathmatch/logic/CModelRenderer.cpp index 8983197e75e..fb91d75a0aa 100644 --- a/Client/mods/deathmatch/logic/CModelRenderer.cpp +++ b/Client/mods/deathmatch/logic/CModelRenderer.cpp @@ -18,6 +18,11 @@ bool CModelRenderer::EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix, if (g_pCore->IsWindowMinimized()) return false; + // Reject enqueues while the alpha entity list holds pointers into m_Queue. + // An emplace_back could reallocate the vector, dangling those pointers. + if (m_bAlphaRefsActive) + return false; + if (pModelInfo && pModelInfo->IsLoaded()) { m_Queue.emplace_back(pModelInfo, matrix, lighting); @@ -37,18 +42,20 @@ void CModelRenderer::Update() // Insert transparent entities into a sorted list if (modelDesc.pModelInfo->GetIdeFlag(eModelIdeFlag::DRAW_LAST)) { - const CVector& vecCameraPosition = *(CVector*)0xB76870; // CRenderer::ms_vecCameraPosition - const float fDistance = (modelDesc.matrix.GetPosition() - vecCameraPosition).Length(); + const CVector& vecCameraPosition = *(CVector*)0xB76870; // CRenderer::ms_vecCameraPosition + const float fDistance = (modelDesc.matrix.GetPosition() - vecCameraPosition).Length(); pVisibilityPlugins->InsertEntityIntoEntityList(&modelDesc, fDistance, RenderEntity); } } + + m_bAlphaRefsActive = true; } void CModelRenderer::Render() { CRenderer* pRenderer = g_pGame->GetRenderer(); - assert(pRenderer); + assert(pRenderer); // Draw opaque entities for (auto& modelDesc : m_Queue) @@ -57,11 +64,30 @@ void CModelRenderer::Render() pRenderer->RenderModel(modelDesc.pModelInfo, modelDesc.matrix, modelDesc.lighting); } + // m_Queue must NOT be cleared here: GTA's RenderFadingInEntities runs later + // in the same frame and calls RenderEntity with pointers into m_Queue elements + // that were inserted by Update() into the alpha entity list. +} + +void CModelRenderer::NotifyFrameEnd() +{ m_Queue.clear(); + m_bAlphaRefsActive = false; } void CModelRenderer::RenderEntity(SModelToRender* modelDesc, float distance) { + // GTA's alpha entity list stores raw pointers from InsertEntityIntoEntityList. + // Verify modelDesc actually points into our queue before dereferencing it, + // in case heap corruption overwrote the entity field in a list node. + CModelRenderer* pModelRenderer = g_pClientGame->GetModelRenderer(); + if (!pModelRenderer || pModelRenderer->m_Queue.empty()) + return; + + const SModelToRender* pQueueData = pModelRenderer->m_Queue.data(); + if (modelDesc < pQueueData || modelDesc >= pQueueData + pModelRenderer->m_Queue.size()) + return; + if (!modelDesc->pModelInfo->IsLoaded()) return; diff --git a/Client/mods/deathmatch/logic/CModelRenderer.h b/Client/mods/deathmatch/logic/CModelRenderer.h index 8272fcf34ce..99faa93c62b 100644 --- a/Client/mods/deathmatch/logic/CModelRenderer.h +++ b/Client/mods/deathmatch/logic/CModelRenderer.h @@ -17,15 +17,10 @@ class CModelRenderer final struct SModelToRender final { CModelInfo* pModelInfo; - CMatrix matrix; - float lighting; - - SModelToRender(CModelInfo* pModelInfo, const CMatrix& matrix, float lighting = 0.0f) : - pModelInfo(pModelInfo), - matrix(matrix), - lighting(lighting) - { - } + CMatrix matrix; + float lighting; + + SModelToRender(CModelInfo* pModelInfo, const CMatrix& matrix, float lighting = 0.0f) : pModelInfo(pModelInfo), matrix(matrix), lighting(lighting) {} }; bool EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix, float lighting); @@ -34,9 +29,13 @@ class CModelRenderer final void Render(); - static void RenderEntity(SModelToRender* entity, float distance); + // Must be called after GTA's RenderFadingInEntities completes to release + // the queue memory that the alpha entity list's callbacks reference. + void NotifyFrameEnd(); -private: + static void RenderEntity(SModelToRender* entity, float distance); +private: std::vector m_Queue; + bool m_bAlphaRefsActive = false; }; diff --git a/Client/mods/deathmatch/logic/CNametags.cpp b/Client/mods/deathmatch/logic/CNametags.cpp index d3c68300aaf..9927b6253a1 100644 --- a/Client/mods/deathmatch/logic/CNametags.cpp +++ b/Client/mods/deathmatch/logic/CNametags.cpp @@ -14,17 +14,17 @@ using std::list; -#define MELEE_VISIBLE_RANGE 60.0f -#define AIM_VISIBLE_RANGE 300.0f -#define SNIPER_AIM_VISIBLE_RANGE 300.0f -#define WEAPON_RANGE_FACTOR 3.0f -#define NAMETAG_BEGIN_FADE_TIME 0 -#define NAMETAG_END_FADE_TIME 700 -#define NAMETAG_FONT_SIZE 0.8f -#define MAX_ALPHA 180.0f // max value is 255 - -#define DEFAULT_VIEW_RANGE 45.0f -#define DEFAULT_VIEW_RANGE_EXP ((DEFAULT_VIEW_RANGE)*(DEFAULT_VIEW_RANGE)) +#define MELEE_VISIBLE_RANGE 60.0f +#define AIM_VISIBLE_RANGE 300.0f +#define SNIPER_AIM_VISIBLE_RANGE 300.0f +#define WEAPON_RANGE_FACTOR 3.0f +#define NAMETAG_BEGIN_FADE_TIME 0 +#define NAMETAG_END_FADE_TIME 700 +#define NAMETAG_FONT_SIZE 0.8f +#define MAX_ALPHA 180.0f // max value is 255 + +#define DEFAULT_VIEW_RANGE 45.0f +#define DEFAULT_VIEW_RANGE_EXP ((DEFAULT_VIEW_RANGE) * (DEFAULT_VIEW_RANGE)) const bool bRenderOwn = false; @@ -310,11 +310,11 @@ void CNametags::DrawTagForPlayer(CClientPlayer* pPlayer, unsigned char ucAlpha) float fRemovedWidth = fWidth - (fHealth / 512.0f * fWidth); float fTopArmorOffset = fTopOffset + fHeight - 0.01f * fResWidth; float fMaxArmor = 100.0f; - float fArmorAlpha = (fArmor / fMaxArmor) * (ucAlpha / 255.0f); // 0->1 + float fArmorAlpha = (fArmor / fMaxArmor) * (ucAlpha / 255.0f); // 0->1 unsigned char ucArmorAlpha = (unsigned char)(255.0f * fArmorAlpha); - #define ARMOR_BORDER_COLOR COLOR_ABGR(ucArmorAlpha,167,177,179) +#define ARMOR_BORDER_COLOR COLOR_ABGR(ucArmorAlpha, 167, 177, 179) // Base rectangle CVector vecTopLeftBase(vecScreenPosition.fX - fWidth * 0.5f, vecScreenPosition.fY + fTopOffset, 0); diff --git a/Client/mods/deathmatch/logic/CNetAPI.cpp b/Client/mods/deathmatch/logic/CNetAPI.cpp index c547b810bb6..74320154034 100644 --- a/Client/mods/deathmatch/logic/CNetAPI.cpp +++ b/Client/mods/deathmatch/logic/CNetAPI.cpp @@ -128,37 +128,29 @@ bool CNetAPI::ProcessPacket(unsigned char bytePacketID, NetBitStreamInterface& B case PACKET_ID_PLAYER_BULLETSYNC: { - // Read out the player ID - ElementID PlayerID; - if (BitStream.Read(PlayerID)) - { - // Grab the player - CClientPlayer* pPlayer = m_pPlayerManager->Get(PlayerID); - if (pPlayer) - { - // Read out the bulletsync data - ReadBulletsync(pPlayer, BitStream); - } - } + ElementID id; + if (!BitStream.Read(id)) + return true; + + auto* player = m_pPlayerManager->Get(id); + if (!player) + return true; + ReadBulletsync(player, BitStream); return true; } case PACKET_ID_WEAPON_BULLETSYNC: { - // Read out the player ID - ElementID PlayerID; - if (BitStream.Read(PlayerID)) - { - // Grab the player - CClientPlayer* pPlayer = m_pPlayerManager->Get(PlayerID); - if (pPlayer) - { - // Read out the bulletsync data - ReadWeaponBulletsync(pPlayer, BitStream); - } - } + ElementID id; + if (!BitStream.Read(id)) + return true; + auto* player = m_pPlayerManager->Get(id); + if (!player) + return true; + + ReadWeaponBulletsync(player, BitStream); return true; } @@ -303,7 +295,7 @@ void CNetAPI::DoPulse() // Grab the local player CClientPlayer* pPlayer = m_pPlayerManager->GetLocalPlayer(); - if (pPlayer && !pPlayer->IsDeadOnNetwork()) + if (pPlayer) { unsigned long ulCurrentTime = CClientTime::GetTime(); @@ -472,8 +464,8 @@ bool CNetAPI::IsSmallKeySyncNeeded(CClientPed* pPlayerModel) return true; // Movement direction buttons change ? - short LeftStickXDelta = abs(ControllerState.LeftStickX - LastControllerState.LeftStickX); - short LeftStickYDelta = abs(ControllerState.LeftStickY - LastControllerState.LeftStickY); + auto LeftStickXDelta = static_cast(abs(ControllerState.LeftStickX - LastControllerState.LeftStickX)); + auto LeftStickYDelta = static_cast(abs(ControllerState.LeftStickY - LastControllerState.LeftStickY)); if (LeftStickXDelta > 32 || LeftStickYDelta > 32) { // If movement within -127 to -1 or 1 to 127, then apply analog update limits @@ -673,7 +665,7 @@ void CNetAPI::ReadKeysync(CClientPlayer* pPlayer, NetBitStreamInterface& BitStre // Eventually read vehicle specific keysync data ReadSmallVehicleSpecific(pVehicle, BitStream, pVehicle->GetModel()); - if (pVehicle->GetUpgrades()->HasUpgrade(1087)) // Hydraulics? + if (pVehicle->GetUpgrades()->HasUpgrade(1087)) // Hydraulics? { short sRightStickX, sRightStickY; BitStream.Read(sRightStickX); @@ -798,7 +790,7 @@ void CNetAPI::WriteKeysync(CClientPed* pPlayerModel, NetBitStreamInterface& BitS CVehicleUpgrades* pUpgrades = pVehicle->GetUpgrades(); if (pUpgrades) { - if (pUpgrades->HasUpgrade(1087)) // Hydraulics? + if (pUpgrades->HasUpgrade(1087)) // Hydraulics? { BitStream.Write(ControllerState.RightStickX); BitStream.Write(ControllerState.RightStickY); @@ -989,6 +981,13 @@ void CNetAPI::ReadPlayerPuresync(CClientPlayer* pPlayer, NetBitStreamInterface& pPlayer->SetOnFire(flags.data.bIsOnFire); pPlayer->SetStealthAiming(flags.data.bStealthAiming); + if (flags.data.hangingDuringClimb && pPlayer->GetMovementState() != eMovementState::MOVEMENTSTATE_HANGING && + pPlayer->GetMovementState() != eMovementState::MOVEMENTSTATE_CLIMB) + pPlayer->RunClimbingTask(); + + if (flags.data.bIsInWater && !pPlayer->IsInWater()) + pPlayer->RunSwimTask(); + // Remember now as the last puresync time pPlayer->SetLastPuresyncTime(CClientTime::GetTime()); pPlayer->SetLastPuresyncPosition(position.data.vecPosition); @@ -1054,16 +1053,16 @@ void WriteCameraOrientation(const CVector& vecPositionBase, NetBitStreamInterfac uint uiNumBits; float fRange; } bitCountTable[4] = { - {3, 4.0f}, // 3 bits is +-4 12 bits total - {5, 16.0f}, // 5 bits is +-16 18 bits total - {9, 256.0f}, // 9 bits is +-256 30 bits total - {14, 8192.0f}, // 14 bits is +-8192 45 bits total + {3, 4.0f}, // 3 bits is +-4 12 bits total + {5, 16.0f}, // 5 bits is +-16 18 bits total + {9, 256.0f}, // 9 bits is +-256 30 bits total + {14, 8192.0f}, // 14 bits is +-8192 45 bits total }; char idx; for (idx = 0; idx < 3; idx++) { if (bitCountTable[idx].fRange > fUseMaxValue) - break; // We have enough bits now + break; // We have enough bits now } const uint uiNumBits = bitCountTable[idx].uiNumBits; const float fRange = bitCountTable[idx].fRange; @@ -1118,11 +1117,18 @@ void CNetAPI::WritePlayerPuresync(CClientPlayer* pPlayerModel, NetBitStreamInter flags.data.bHasAWeapon = (pPlayerWeapon != NULL); flags.data.bSyncingVelocity = (!flags.data.bIsOnGround || (pPlayerModel->GetPlayerSyncCount() % 4) == 0); flags.data.bStealthAiming = (pPlayerModel->IsStealthAiming() == true); + flags.data.isReloadingWeapon = (pPlayerModel->IsReloadingWeapon() == true); + flags.data.animInterrupted = pPlayerModel->HasSyncedAnim() && (!pPlayerModel->IsRunningAnimation() || pPlayerModel->m_animationOverridedByClient); + flags.data.hangingDuringClimb = pPlayerModel->GetMovementState() == eMovementState::MOVEMENTSTATE_HANGING; - if (BitStream.Can(eBitStreamVersion::IsPedReloadingWeapon)) - flags.data2.isReloadingWeapon = (pPlayerModel->IsReloadingWeapon() == true); + // The animation has been overwritten or interrupted by the client + if (flags.data.animInterrupted) + { + pPlayerModel->SetHasSyncedAnim(false); + pPlayerModel->m_animationOverridedByClient = false; + } - if (pPlayerWeapon->GetSlot() > 15) + if (flags.data.bHasAWeapon && pPlayerWeapon->GetSlot() > 15) flags.data.bHasAWeapon = false; BitStream.Write(&flags); @@ -1289,9 +1295,7 @@ void CNetAPI::ReadVehiclePuresync(CClientPlayer* pPlayer, CClientVehicle* pVehic // differs from the local one (#8800) int iModelID = pVehicle->GetModel(); int iRemoteModelID = iModelID; - - if (BitStream.Version() >= 0x05F) - BitStream.Read(iRemoteModelID); + BitStream.Read(iRemoteModelID); eClientVehicleType remoteVehicleType = CClientVehicleManager::GetVehicleType(iRemoteModelID); eClientVehicleType vehicleType = pVehicle->GetVehicleType(); @@ -1480,7 +1484,7 @@ void CNetAPI::ReadVehiclePuresync(CClientPlayer* pPlayer, CClientVehicle* pVehic } // Read out the weapon ammo - SWeaponAmmoSync ammo(ucCurrentWeapon, BitStream.Version() >= 0x44, true); + SWeaponAmmoSync ammo(ucCurrentWeapon, true, true); BitStream.Read(&ammo); unsigned short usWeaponAmmo = ammo.data.usAmmoInClip; @@ -1489,7 +1493,7 @@ void CNetAPI::ReadVehiclePuresync(CClientPlayer* pPlayer, CClientVehicle* pVehic CWeapon* pPlayerWeapon = pPlayer->GiveWeapon(static_cast(ucCurrentWeapon), usWeaponAmmo, true); if (pPlayerWeapon) { - pPlayerWeapon->SetAmmoTotal(BitStream.Version() >= 0x44 ? ammo.data.usTotalAmmo : 9999); + pPlayerWeapon->SetAmmoTotal(ammo.data.usTotalAmmo); pPlayerWeapon->SetAmmoInClip(usWeaponAmmo); } } @@ -1545,8 +1549,7 @@ void CNetAPI::ReadVehiclePuresync(CClientPlayer* pPlayer, CClientVehicle* pVehic pPlayer->SetControllerState(ControllerState); - if (BitStream.Can(eBitStreamVersion::SetElementOnFire)) - pVehicle->SetOnFire(BitStream.ReadBit()); + pVehicle->SetOnFire(BitStream.ReadBit()); // Remember now as the last puresync time CVector vecPosition; @@ -1574,8 +1577,7 @@ void CNetAPI::WriteVehiclePuresync(CClientPed* pPlayerModel, CClientVehicle* pVe iModelID = pVehicle->GetModelInfo()->GetParentID(); // Write the clientside model - if (BitStream.Version() >= 0x05F) - BitStream.Write(iModelID); + BitStream.Write(iModelID); // Grab the vehicle position CVector vecPosition; @@ -1667,38 +1669,6 @@ void CNetAPI::WriteVehiclePuresync(CClientPed* pPlayerModel, CClientVehicle* pVe BitStream.WriteBit(false); } - // Update Damage Info if changed - if (BitStream.Version() >= 0x047) - { - if (!g_pClientGame->GetDamageSent()) - { - g_pClientGame->SetDamageSent(true); - - ElementID DamagerID = g_pClientGame->GetDamagerID(); - if (DamagerID != RESERVED_ELEMENT_ID) - { - BitStream.WriteBit(true); - BitStream.Write(DamagerID); - - SWeaponTypeSync weaponType; - weaponType.data.ucWeaponType = g_pClientGame->GetDamageWeapon(); - BitStream.Write(&weaponType); - - SBodypartSync bodypart; - bodypart.data.uiBodypart = g_pClientGame->GetDamageBodyPiece(); - BitStream.Write(&bodypart); - } - else - { - BitStream.WriteBit(false); - } - } - else - { - BitStream.WriteBit(false); - } - } - // Player health sync (scaled from 0.0f-200.0f to 0-255 to save three bytes). // Scale goes up to 200.0f because having max stats gives you the double of health. SPlayerHealthSync health; @@ -1741,7 +1711,7 @@ void CNetAPI::WriteVehiclePuresync(CClientPed* pPlayerModel, CClientVehicle* pVe if (flags.data.bIsDoingGangDriveby && CWeaponNames::DoesSlotHaveAmmo(uiSlot)) { // Write the ammo states - SWeaponAmmoSync ammo(pPlayerWeapon->GetType(), BitStream.Version() >= 0x44, true); + SWeaponAmmoSync ammo(pPlayerWeapon->GetType(), true, true); ammo.data.usAmmoInClip = static_cast(pPlayerWeapon->GetAmmoInClip()); ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); BitStream.Write(&ammo); @@ -1773,8 +1743,7 @@ void CNetAPI::WriteVehiclePuresync(CClientPed* pPlayerModel, CClientVehicle* pVe BitStream.WriteBit(ControllerState.RightShoulder2 != 0); } - if (BitStream.Can(eBitStreamVersion::SetElementOnFire)) - BitStream.WriteBit(pVehicle->IsOnFire()); + BitStream.WriteBit(pVehicle->IsOnFire()); // Write the sent position to the interpolator AddInterpolation(vecPosition); @@ -1786,19 +1755,19 @@ bool CNetAPI::ReadSmallKeysync(CControllerState& ControllerState, NetBitStreamIn if (!BitStream.Read(&keys)) return false; - // Put the result into the controllerstate - ControllerState.LeftShoulder1 = 255 * keys.data.bLeftShoulder1; - ControllerState.RightShoulder1 = 255 * keys.data.bRightShoulder1; short sButtonSquare = 255 * keys.data.bButtonSquare; short sButtonCross = 255 * keys.data.bButtonCross; - if (BitStream.Can(eBitStreamVersion::AnalogControlSync_AccelBrakeReverse)) { if (keys.data.ucButtonSquare != 0) - sButtonSquare = (short)keys.data.ucButtonSquare; // override controller state with analog data if present + sButtonSquare = (short)keys.data.ucButtonSquare; // override controller state with analog data if present if (keys.data.ucButtonCross != 0) - sButtonCross = (short)keys.data.ucButtonCross; // override controller state with analog data if present + sButtonCross = (short)keys.data.ucButtonCross; // override controller state with analog data if present } + + // Put the result into the controllerstate + ControllerState.LeftShoulder1 = 255 * keys.data.bLeftShoulder1; + ControllerState.RightShoulder1 = 255 * keys.data.bRightShoulder1; ControllerState.ButtonSquare = sButtonSquare; ControllerState.ButtonCross = sButtonCross; ControllerState.ButtonCircle = 255 * keys.data.bButtonCircle; @@ -1813,16 +1782,16 @@ bool CNetAPI::ReadSmallKeysync(CControllerState& ControllerState, NetBitStreamIn void CNetAPI::WriteSmallKeysync(const CControllerState& ControllerState, NetBitStreamInterface& BitStream) { SSmallKeysyncSync keys; - keys.data.bLeftShoulder1 = (ControllerState.LeftShoulder1 != 0); // Action / Secondary-Fire - keys.data.bRightShoulder1 = (ControllerState.RightShoulder1 != 0); // Aim-Weapon / Handbrake - keys.data.bButtonSquare = (ControllerState.ButtonSquare != 0); // Jump / Reverse - keys.data.bButtonCross = (ControllerState.ButtonCross != 0); // Sprint / Accelerate - keys.data.bButtonCircle = (ControllerState.ButtonCircle != 0); // Fire // Fire - keys.data.bButtonTriangle = (ControllerState.ButtonTriangle != 0); // Enter/Exit/Special-Attack / Enter/exit - keys.data.bShockButtonL = (ControllerState.ShockButtonL != 0); // Crouch / Horn - keys.data.bPedWalk = (ControllerState.m_bPedWalk != 0); // Walk / - - keys.data.ucButtonSquare = (unsigned char)ControllerState.ButtonSquare; // Jump / Reverse - keys.data.ucButtonCross = (unsigned char)ControllerState.ButtonCross; // Sprint / Accelerate + keys.data.bLeftShoulder1 = (ControllerState.LeftShoulder1 != 0); // Action / Secondary-Fire + keys.data.bRightShoulder1 = (ControllerState.RightShoulder1 != 0); // Aim-Weapon / Handbrake + keys.data.bButtonSquare = (ControllerState.ButtonSquare != 0); // Jump / Reverse + keys.data.bButtonCross = (ControllerState.ButtonCross != 0); // Sprint / Accelerate + keys.data.bButtonCircle = (ControllerState.ButtonCircle != 0); // Fire // Fire + keys.data.bButtonTriangle = (ControllerState.ButtonTriangle != 0); // Enter/Exit/Special-Attack / Enter/exit + keys.data.bShockButtonL = (ControllerState.ShockButtonL != 0); // Crouch / Horn + keys.data.bPedWalk = (ControllerState.m_bPedWalk != 0); // Walk / - + keys.data.ucButtonSquare = (unsigned char)ControllerState.ButtonSquare; // Jump / Reverse + keys.data.ucButtonCross = (unsigned char)ControllerState.ButtonCross; // Sprint / Accelerate keys.data.sLeftStickX = ControllerState.LeftStickX; keys.data.sLeftStickY = ControllerState.LeftStickY; @@ -1837,19 +1806,19 @@ bool CNetAPI::ReadFullKeysync(CControllerState& ControllerState, NetBitStreamInt if (!BitStream.Read(&keys)) return false; - // Put the result into the controllerstate - ControllerState.LeftShoulder1 = 255 * keys.data.bLeftShoulder1; - ControllerState.RightShoulder1 = 255 * keys.data.bRightShoulder1; short sButtonSquare = 255 * keys.data.bButtonSquare; short sButtonCross = 255 * keys.data.bButtonCross; - if (BitStream.Can(eBitStreamVersion::AnalogControlSync_AccelBrakeReverse)) { if (keys.data.ucButtonSquare != 0) - sButtonSquare = (short)keys.data.ucButtonSquare; // override controller state with analog data if present + sButtonSquare = (short)keys.data.ucButtonSquare; // override controller state with analog data if present if (keys.data.ucButtonCross != 0) - sButtonCross = (short)keys.data.ucButtonCross; // override controller state with analog data if present + sButtonCross = (short)keys.data.ucButtonCross; // override controller state with analog data if present } + + // Put the result into the controllerstate + ControllerState.LeftShoulder1 = 255 * keys.data.bLeftShoulder1; + ControllerState.RightShoulder1 = 255 * keys.data.bRightShoulder1; ControllerState.ButtonSquare = sButtonSquare; ControllerState.ButtonCross = sButtonCross; ControllerState.ButtonCircle = 255 * keys.data.bButtonCircle; @@ -1988,8 +1957,7 @@ void CNetAPI::WriteCameraSync(NetBitStreamInterface& BitStream) { CClientCamera* pCamera = m_pManager->GetCamera(); - if (BitStream.Version() >= 0x05E) - BitStream.Write(pCamera->GetSyncTimeContext()); + BitStream.Write(pCamera->GetSyncTimeContext()); // Are we in fixed mode? bool bFixed = pCamera->IsInFixedMode(); @@ -2239,178 +2207,141 @@ void CNetAPI::ReadVehicleResync(CClientVehicle* pVehicle, NetBitStreamInterface& void CNetAPI::ReadVehiclePartsState(CClientVehicle* pVehicle, NetBitStreamInterface& BitStream) { - if (BitStream.Version() < 0x5D) - return; - SVehicleDamageSyncMethodeB damage; BitStream.Read(&damage); bool flyingComponents = m_pVehicleManager->IsSpawnFlyingComponentEnabled(); if (damage.data.bSyncDoors) - for (unsigned int i = 0; i < MAX_DOORS; ++i) + for (unsigned char i = 0; i < MAX_DOORS; ++i) pVehicle->SetDoorStatus(i, damage.data.doors.data.ucStates[i], flyingComponents); if (damage.data.bSyncWheels) - for (unsigned int i = 0; i < MAX_WHEELS; ++i) + for (unsigned char i = 0; i < MAX_WHEELS; ++i) pVehicle->SetWheelStatus(i, damage.data.wheels.data.ucStates[i]); if (damage.data.bSyncPanels) - for (unsigned int i = 0; i < MAX_PANELS; ++i) + for (unsigned char i = 0; i < MAX_PANELS; ++i) pVehicle->SetPanelStatus(i, damage.data.panels.data.ucStates[i], flyingComponents); if (damage.data.bSyncLights) - for (unsigned int i = 0; i < MAX_LIGHTS; ++i) + for (unsigned char i = 0; i < MAX_LIGHTS; ++i) pVehicle->SetLightStatus(i, damage.data.lights.data.ucStates[i]); static_cast(pVehicle)->ResetDamageModelSync(); } -// -// Read bulletsync packet for a remote player -// -void CNetAPI::ReadBulletsync(CClientPlayer* pPlayer, NetBitStreamInterface& BitStream) +void CNetAPI::ReadBulletsync(CClientPlayer* player, NetBitStreamInterface& stream) { - // Read the bulletsync data - uchar ucWeapon = 0; - if (!BitStream.Read(ucWeapon) || !CClientWeaponManager::HasWeaponBulletSync(ucWeapon)) + std::uint8_t weapon = 0; + if (!stream.Read(weapon) || !CClientWeaponManager::HasWeaponBulletSync(weapon)) return; - eWeaponType weaponType = (eWeaponType)ucWeapon; + const auto type = static_cast(weapon); - CVector vecStart, vecEnd; - if (!BitStream.Read((char*)&vecStart, sizeof(CVector)) || !BitStream.Read((char*)&vecEnd, sizeof(CVector))) + CVector start; + CVector end; + if (!stream.Read(reinterpret_cast(&start), sizeof(CVector)) || !stream.Read(reinterpret_cast(&end), sizeof(CVector)) || !start.IsValid() || + !end.IsValid()) return; - if (!vecStart.IsValid() || !vecEnd.IsValid()) + std::uint8_t order = 0; + if (!stream.Read(order)) return; - uchar ucOrderCounter = 0; - if (!BitStream.Read(ucOrderCounter)) - return; + float damage = 0.0f; + std::uint8_t zone = 0; + CClientPlayer* damaged = nullptr; - float fDamage = 0; - uchar ucHitZone = 0; - CClientPlayer* pDamagedPlayer = NULL; - if (BitStream.ReadBit()) + if (stream.ReadBit()) { - ElementID DamagedPlayerID = INVALID_ELEMENT_ID; - if (!BitStream.Read(fDamage) || !BitStream.Read(ucHitZone) || !BitStream.Read(DamagedPlayerID)) + ElementID id = INVALID_ELEMENT_ID; + if (!stream.Read(damage) || !stream.Read(zone) || !stream.Read(id)) return; - pDamagedPlayer = DynamicCast(CElementIDs::GetElement(DamagedPlayerID)); + damaged = DynamicCast(CElementIDs::GetElement(id)); } - // Duplicate bullet check - { - bool bIsDuplicate = false; + bool duplicate = false; - // Check if duplicate by comparing with previously sent vectors - if (vecStart == pPlayer->m_vecPrevBulletSyncStart && vecEnd == pPlayer->m_vecPrevBulletSyncEnd) - { - bIsDuplicate = true; - } - pPlayer->m_vecPrevBulletSyncStart = vecStart; - pPlayer->m_vecPrevBulletSyncEnd = vecEnd; + if (start == player->m_vecPrevBulletSyncStart && end == player->m_vecPrevBulletSyncEnd) + duplicate = true; - // Verify if duplicate by comparing order counter - char cDif = ucOrderCounter - pPlayer->m_ucPrevBulletSyncOrderCounter; - if (cDif > 0) - bIsDuplicate = false; + player->m_vecPrevBulletSyncStart = start; + player->m_vecPrevBulletSyncEnd = end; - pPlayer->m_ucPrevBulletSyncOrderCounter = ucOrderCounter; + if (static_cast(order - player->m_ucPrevBulletSyncOrderCounter) > 0) + duplicate = false; - if (bIsDuplicate) - return; - } + player->m_ucPrevBulletSyncOrderCounter = order; + + if (duplicate) + return; - pPlayer->DischargeWeapon(weaponType, vecStart, vecEnd, fDamage, ucHitZone, pDamagedPlayer); + player->DischargeWeapon(type, start, end, damage, zone, damaged); } -// -// Read bulletsync packet for a remote player -// -void CNetAPI::ReadWeaponBulletsync(CClientPlayer* pPlayer, NetBitStreamInterface& BitStream) +void CNetAPI::ReadWeaponBulletsync(CClientPlayer* player, NetBitStreamInterface& stream) { - // Read the bulletsync data - ElementID elementID; - if (!BitStream.Read(elementID)) + ElementID id; + if (!stream.Read(id)) return; - CClientWeapon* pWeapon = DynamicCast(CElementIDs::GetElement(elementID)); - if (!pWeapon || !CClientWeaponManager::HasWeaponBulletSync(pWeapon->GetWeaponType())) + auto* weapon = DynamicCast(CElementIDs::GetElement(id)); + if (!weapon || !CClientWeaponManager::HasWeaponBulletSync(weapon->GetWeaponType())) return; - CVector vecStart, vecEnd; - if (!BitStream.Read((char*)&vecStart, sizeof(CVector)) || !BitStream.Read((char*)&vecEnd, sizeof(CVector))) + CVector start; + CVector end; + if (!stream.Read(reinterpret_cast(&start), sizeof(CVector)) || !stream.Read(reinterpret_cast(&end), sizeof(CVector)) || !start.IsValid() || + !end.IsValid()) return; - if (!vecStart.IsValid() || !vecEnd.IsValid()) + uint8_t order = 0; + if (!stream.Read(order)) return; - uchar ucOrderCounter = 0; - if (!BitStream.Read(ucOrderCounter)) - return; - - pWeapon->FireInstantHit(vecStart, vecEnd, false, true); + weapon->FireInstantHit(start, end, false, true); } -// -// Send bulletsync fire button press packet to remote players -// -void CNetAPI::SendBulletSyncFire(eWeaponType weaponType, const CVector& vecStart, const CVector& vecEnd, float fDamage, uchar ucHitZone, - CClientPlayer* pRemoteDamagedPlayer) +void CNetAPI::SendBulletSyncFire(eWeaponType weapon, const CVector& start, const CVector& end, float damage, std::uint8_t zone, CClientPlayer* damaged) { - // Send a bulletsync packet - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - - // Write the bulletsync data - pBitStream->Write((char)weaponType); + auto* stream = g_pNet->AllocateNetBitStream(); - pBitStream->Write((const char*)&vecStart, sizeof(CVector)); - pBitStream->Write((const char*)&vecEnd, sizeof(CVector)); + stream->Write(static_cast(weapon)); + stream->Write(reinterpret_cast(&start), sizeof(CVector)); + stream->Write(reinterpret_cast(&end), sizeof(CVector)); + stream->Write(m_ucBulletSyncOrderCounter++); - pBitStream->Write(m_ucBulletSyncOrderCounter++); - - if (fDamage > 0 && pRemoteDamagedPlayer) + if (damage > 0.0f && damaged) { - pBitStream->WriteBit(true); - pBitStream->Write(fDamage); - pBitStream->Write(ucHitZone); - pBitStream->Write(pRemoteDamagedPlayer->GetID()); + stream->WriteBit(true); + stream->Write(damage); + stream->Write(zone); + stream->Write(damaged->GetID()); } else { - pBitStream->WriteBit(false); + stream->WriteBit(false); } - // Send the packet - g_pNet->SendPacket(PACKET_ID_PLAYER_BULLETSYNC, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_RELIABLE); - g_pNet->DeallocateNetBitStream(pBitStream); + g_pNet->SendPacket(PACKET_ID_PLAYER_BULLETSYNC, stream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_RELIABLE); + g_pNet->DeallocateNetBitStream(stream); } -// -// Send bulletsync fire button press packet to remote players -// -void CNetAPI::SendBulletSyncCustomWeaponFire(CClientWeapon* pWeapon, const CVector& vecStart, const CVector& vecEnd) +void CNetAPI::SendBulletSyncCustomWeaponFire(CClientWeapon* weapon, const CVector& start, const CVector& end) { - // Ignore old bullet sync stuff - if (pWeapon->IsLocalEntity()) + if (weapon->IsLocalEntity()) return; - // Send a bulletsync packet - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - - // Write the bulletsync data - pBitStream->Write(pWeapon->GetID()); - - pBitStream->Write((const char*)&vecStart, sizeof(CVector)); - pBitStream->Write((const char*)&vecEnd, sizeof(CVector)); + auto* stream = g_pNet->AllocateNetBitStream(); - pBitStream->Write(m_ucCustomWeaponBulletSyncOrderCounter++); + stream->Write(weapon->GetID()); + stream->Write(reinterpret_cast(&start), sizeof(CVector)); + stream->Write(reinterpret_cast(&end), sizeof(CVector)); + stream->Write(m_ucCustomWeaponBulletSyncOrderCounter++); - // Send the packet - g_pNet->SendPacket(PACKET_ID_WEAPON_BULLETSYNC, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_RELIABLE); - g_pNet->DeallocateNetBitStream(pBitStream); + g_pNet->SendPacket(PACKET_ID_WEAPON_BULLETSYNC, stream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_RELIABLE); + g_pNet->DeallocateNetBitStream(stream); } // diff --git a/Client/mods/deathmatch/logic/CNetAPI.h b/Client/mods/deathmatch/logic/CNetAPI.h index 2d4a9f401fa..d3ed4cec57c 100644 --- a/Client/mods/deathmatch/logic/CNetAPI.h +++ b/Client/mods/deathmatch/logic/CNetAPI.h @@ -21,9 +21,9 @@ class CNetAPI; #include "CTickRateSettings.h" // SYNC SETTINGS -#define TICK_RATE ( g_TickRateSettings.iPureSync ) -#define CAM_SYNC_RATE ( g_TickRateSettings.iCamSync ) -#define TICK_RATE_AIM ( std::min ( TICK_RATE, g_TickRateSettings.iKeySyncRotation ) ) // Keysync or puresync update the aim, so use the shortest interval +#define TICK_RATE (g_TickRateSettings.iPureSync) +#define CAM_SYNC_RATE (g_TickRateSettings.iCamSync) +#define TICK_RATE_AIM (std::min(TICK_RATE, g_TickRateSettings.iKeySyncRotation)) // Keysync or puresync update the aim, so use the shortest interval enum eServerRPCFunctions { @@ -49,9 +49,8 @@ class CNetAPI void AddInterpolation(const CVector& vecPosition); bool GetInterpolation(CVector& vecPosition, unsigned short usLatency); - void SendBulletSyncFire(eWeaponType weaponType, const CVector& vecStart, const CVector& vecEnd, float fDamage, uchar ucHitZone, - CClientPlayer* pRemoteDamagedPlayer); - void SendBulletSyncCustomWeaponFire(CClientWeapon* pWeapon, const CVector& vecStart, const CVector& vecEnd); + void SendBulletSyncFire(eWeaponType weapon, const CVector& start, const CVector& end, float damage, std::uint8_t zone, CClientPlayer* damaged); + void SendBulletSyncCustomWeaponFire(CClientWeapon* weapon, const CVector& start, const CVector& end); bool IsNetworkTrouble() { return m_bIsNetworkTrouble; } static bool IsWeaponIDAkimbo(unsigned char ucWeaponID); @@ -64,8 +63,8 @@ class CNetAPI void ReadKeysync(CClientPlayer* pPlayer, NetBitStreamInterface& BitStream); void WriteKeysync(CClientPed* pPed, NetBitStreamInterface& BitStream); - void ReadBulletsync(CClientPlayer* pPlayer, NetBitStreamInterface& BitStream); - void ReadWeaponBulletsync(CClientPlayer* pWeapon, NetBitStreamInterface& BitStream); + void ReadBulletsync(CClientPlayer* player, NetBitStreamInterface& stream); + void ReadWeaponBulletsync(CClientPlayer* player, NetBitStreamInterface& stream); void ReadPlayerPuresync(CClientPlayer* pPlayer, NetBitStreamInterface& BitStream); void WritePlayerPuresync(CClientPlayer* pPed, NetBitStreamInterface& BitStream); diff --git a/Client/mods/deathmatch/logic/CObjectSync.cpp b/Client/mods/deathmatch/logic/CObjectSync.cpp index 4cd196f7e14..f580376cddb 100644 --- a/Client/mods/deathmatch/logic/CObjectSync.cpp +++ b/Client/mods/deathmatch/logic/CObjectSync.cpp @@ -16,7 +16,7 @@ using std::list; -#define OBJECT_SYNC_RATE ( g_TickRateSettings.iObjectSync ) + #define OBJECT_SYNC_RATE (g_TickRateSettings.iObjectSync) CObjectSync::CObjectSync(CClientObjectManager* pObjectManager) { @@ -97,10 +97,10 @@ void CObjectSync::Packet_ObjectStartSync(NetBitStreamInterface& BitStream) SRotationRadiansSync rotation; if (BitStream.Read(&position) && BitStream.Read(&rotation)) { - // Disabled due to problem when attached in the editor - issue #5886 - #if 0 + // Disabled due to problem when attached in the editor - issue #5886 + #if 0 pObject->SetOrientation ( position.data.vecPosition, rotation.data.vecRotation ); - #endif + #endif } // No velocity due to issue #3522 @@ -267,4 +267,4 @@ void CObjectSync::WriteObjectInformation(NetBitStreamInterface* pBitStream, CDea } } -#endif \ No newline at end of file +#endif diff --git a/Client/mods/deathmatch/logic/CPacketHandler.cpp b/Client/mods/deathmatch/logic/CPacketHandler.cpp index f62e9955b4a..a3608654820 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.cpp +++ b/Client/mods/deathmatch/logic/CPacketHandler.cpp @@ -309,6 +309,10 @@ void CPacketHandler::Packet_ServerConnected(NetBitStreamInterface& bitStream) if (g_pGame->GetSystemState() == SystemState::GS_FRONTEND) { g_pGame->StartGame(); + + // Fix area name showing for a second when joining to server for first time + // HUD_AREA_NAME will be made visible later in the process when the camera fades in (CCameraRPCs::FadeCamera) + g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false); } } @@ -400,11 +404,8 @@ void CPacketHandler::Packet_ServerJoined(NetBitStreamInterface& bitStream) g_pClientGame->InitVoice(bVoiceEnabled, (unsigned int)sampleRate, quality, iBitrate); // Get fakelag command enabled - if (bitStream.Can(eBitStreamVersion::FakeLagCommand)) - { - if (bitStream.ReadBit()) - g_pCore->SetFakeLagCommandEnabled(true); - } + if (bitStream.ReadBit()) + g_pCore->SetFakeLagCommandEnabled(true); // Limit number of http request if required by the server int iHTTPMaxConnectionsPerClient = 4; @@ -467,22 +468,24 @@ void CPacketHandler::Packet_ServerJoined(NetBitStreamInterface& bitStream) g_pCore->UpdateRecentlyPlayed(); - if (g_pNet->CanServerBitStream((eBitStreamVersion::CPlayerJoinCompletePacket_ServerName))) + // Update focus state after joining + // m_bFocused is set in the CClientGame constructor - immediately after clicking "join." + // This means that if the window loses focus while joining the game, the game still believes it has focus, + // and isMTAWindowFocused returns true even when the user is doing anything outside the MTA window. + g_pClientGame->m_bFocused = g_pCore->IsFocused(); + + auto discord = g_pCore->GetDiscord(); + if (discord && discord->IsDiscordRPCEnabled()) { - auto discord = g_pCore->GetDiscord(); - if (discord && discord->IsDiscordRPCEnabled()) - { - std::string serverName; - bitStream.ReadString(serverName); + std::string serverName; + bitStream.ReadString(serverName); - if (serverName.length() > 0) - { - g_pCore->SetLastConnectedServerName(serverName); - discord->SetPresenceDetails(serverName.c_str(), false); - } + if (serverName.length() > 0) + { + g_pCore->SetLastConnectedServerName(serverName); + discord->SetPresenceDetails(serverName.c_str(), false); } } - } void CPacketHandler::Packet_ServerDisconnected(NetBitStreamInterface& bitStream) @@ -598,7 +601,7 @@ void CPacketHandler::Packet_ServerDisconnected(NetBitStreamInterface& bitStream) break; case ePlayerDisconnectType::CUSTOM: strReason = "%s"; - strErrorCode = _E("CD48"); // Custom disconnect reason + strErrorCode = _E("CD48"); // Custom disconnect reason bExpectExtraString = true; break; case ePlayerDisconnectType::SHUTDOWN: @@ -820,15 +823,12 @@ void CPacketHandler::Packet_PlayerList(NetBitStreamInterface& bitStream) // Read version info ushort usBitStreamVersion = 0; uint uiBuildNumber = 0; - if (bitStream.Version() >= 0x34) - { - bitStream.Read(usBitStreamVersion); - bitStream.Read(uiBuildNumber); - } + bitStream.Read(usBitStreamVersion); + bitStream.Read(uiBuildNumber); // Player flags bool bIsDead = bitStream.ReadBit(); - bool bIsSpawned = bitStream.ReadBit(); // Indicates extra info in packet. Always true for newer server builds. + bool bIsSpawned = bitStream.ReadBit(); // Indicates extra info in packet. Always true for newer server builds. bool bInVehicle = bitStream.ReadBit(); bool bHasJetPack = bitStream.ReadBit(); bool bNametagShowing = bitStream.ReadBit(); @@ -853,8 +853,7 @@ void CPacketHandler::Packet_PlayerList(NetBitStreamInterface& bitStream) // Move anim uchar ucMoveAnim = MOVE_DEFAULT; - if (bitStream.Version() > 0x4B) - bitStream.Read(ucMoveAnim); + bitStream.Read(ucMoveAnim); // Read out the spawndata if he has spawned unsigned short usPlayerModelID; @@ -867,7 +866,7 @@ void CPacketHandler::Packet_PlayerList(NetBitStreamInterface& bitStream) unsigned char ucFightingStyle = 0; SEntityAlphaSync alpha; unsigned char ucInterior = 0; - if (bIsSpawned) // Always true for newer server builds. + if (bIsSpawned) // Always true for newer server builds. { // Read out the player model id bitStream.ReadCompressed(usPlayerModelID); @@ -908,7 +907,7 @@ void CPacketHandler::Packet_PlayerList(NetBitStreamInterface& bitStream) return; } } - else // On foot? + else // On foot? { // Set the vehicle id to 0 to indicate we're on foot ID = INVALID_ELEMENT_ID; @@ -971,7 +970,7 @@ void CPacketHandler::Packet_PlayerList(NetBitStreamInterface& bitStream) pPlayer->SetTeam(pTeam, true); // If the player has spawned - if (bIsSpawned) // Always true for newer server builds. + if (bIsSpawned) // Always true for newer server builds. { // Give him the correct skin pPlayer->SetModel(usPlayerModelID); @@ -985,7 +984,7 @@ void CPacketHandler::Packet_PlayerList(NetBitStreamInterface& bitStream) pPlayer->ResetInterpolation(); pPlayer->SetHasJetPack(bHasJetPack); } - else // In a vehicle + else // In a vehicle { // Grab the vehicle and warp him into it CClientVehicle* pVehicle = g_pClientGame->m_pVehicleManager->Get(ID); @@ -1011,6 +1010,38 @@ void CPacketHandler::Packet_PlayerList(NetBitStreamInterface& bitStream) pPlayer->GiveWeapon(static_cast(weaponType.data.ucWeaponType), 1); } } + + // Animation + if (bitStream.ReadBit()) + { + std::string blockName, animName; + int time, blendTime; + bool looped, updatePosition, interruptable, freezeLastFrame, taskRestore; + float speed; + double startTime; + + // Read data + bitStream.ReadString(blockName); + bitStream.ReadString(animName); + bitStream.Read(time); + bitStream.ReadBit(looped); + bitStream.ReadBit(updatePosition); + bitStream.ReadBit(interruptable); + bitStream.ReadBit(freezeLastFrame); + bitStream.Read(blendTime); + bitStream.ReadBit(taskRestore); + bitStream.Read(startTime); + bitStream.Read(speed); + + // Run anim + CStaticFunctionDefinitions::SetPedAnimation(*pPlayer, blockName, animName.c_str(), time, blendTime, looped, updatePosition, interruptable, + freezeLastFrame); + pPlayer->m_AnimationCache.startTime = static_cast(startTime); + pPlayer->m_AnimationCache.speed = speed; + pPlayer->m_AnimationCache.progress = 0.0f; + + pPlayer->SetHasSyncedAnim(true); + } } // Set move anim even if not spawned @@ -1065,7 +1096,7 @@ void CPacketHandler::Packet_PlayerSpawn(NetBitStreamInterface& bitStream) // Flags unsigned char ucFlags; - bitStream.Read(ucFlags); // Unused + bitStream.Read(ucFlags); // Unused // Position vector CVector vecPosition; @@ -1117,6 +1148,12 @@ void CPacketHandler::Packet_PlayerSpawn(NetBitStreamInterface& bitStream) // He's no longer dead pPlayer->SetDeadOnNetwork(false); + // Reset death processing flag for new life + if (pPlayer->IsLocalPlayer()) + { + g_pClientGame->ResetDeathProcessingFlag(); + } + // Reset weapons pPlayer->RemoveAllWeapons(); @@ -1196,6 +1233,13 @@ void CPacketHandler::Packet_PlayerWasted(NetBitStreamInterface& bitStream) // Update our sync-time context pPed->SetSyncTimeContext(ucTimeContext); + // Clear stale damage data if this is the local player + // This prevents DoWastedCheck from firing with stale data when server processes death + if (pPed->IsLocalPlayer()) + { + g_pClientGame->ClearDamageData(); + } + // To at least here needs to be done on the local player to avoid desync // Caz: Issue 8148 - Desync when calling spawnPlayer from an event handler remotely triggered from within onClientPlayerWasted @@ -1208,7 +1252,7 @@ void CPacketHandler::Packet_PlayerWasted(NetBitStreamInterface& bitStream) pKillerPed->StealthKill(pPed); } // Kill our ped in the correct way - pPed->Kill((eWeaponType)weapon.data.ucWeaponType, bodyPart.data.uiBodypart, bStealth, false, animGroup, animID); + pPed->Kill((eWeaponType)weapon.data.ucWeaponType, static_cast(bodyPart.data.uiBodypart), bStealth, false, animGroup, animID); // Local player triggers himself when sending the death packet to the server, this one will be delayed by network delay so disable it unless it's // sent by the server. if we were not already dead on the network trigger it anyway because this is also called by KillPed server side and that will @@ -1374,24 +1418,14 @@ void CPacketHandler::Packet_ChatEcho(NetBitStreamInterface& bitStream) int iNumberOfBytesUsed; unsigned char ucMessageType; - if (bitStream.Can(eBitStreamVersion::OnClientChatMessage_PlayerSource)) - { - ElementID ClientID; - bitStream.Read(ClientID); - pClient = (ClientID != INVALID_ELEMENT_ID) ? CElementIDs::GetElement(ClientID) : nullptr; - iNumberOfBytesUsed = bitStream.GetNumberOfBytesUsed() - 6; - } - else - { - iNumberOfBytesUsed = bitStream.GetNumberOfBytesUsed() - 4; - } + ElementID ClientID; + bitStream.Read(ClientID); + pClient = (ClientID != INVALID_ELEMENT_ID) ? CElementIDs::GetElement(ClientID) : nullptr; + iNumberOfBytesUsed = bitStream.GetNumberOfBytesUsed() - 6; - if (bitStream.Can(eBitStreamVersion::OnClientChatMessage_MessageType)) - { - // Get the message type and push the argument - bitStream.Read(ucMessageType); - iNumberOfBytesUsed -= 1; - } + // Get the message type and push the argument + bitStream.Read(ucMessageType); + iNumberOfBytesUsed -= 1; // Valid length? if (iNumberOfBytesUsed >= MIN_CHATECHO_LENGTH) @@ -1401,8 +1435,9 @@ void CPacketHandler::Packet_ChatEcho(NetBitStreamInterface& bitStream) bitStream.Read(szMessage, iNumberOfBytesUsed); szMessage[iNumberOfBytesUsed] = 0; // actual limits enforced on the remote client, this is the maximum a string can be to be printed. - if (MbUTF8ToUTF16(szMessage).size() <= - MAX_CHATECHO_LENGTH + 6) // Extra 6 characters to fix #7125 (Teamsay + long name + long message = too long message) + SString textToProcess = bColorCoded ? RemoveColorCodes(szMessage) : szMessage; + if (MbUTF8ToUTF16(textToProcess).size() <= + MAX_CHATECHO_LENGTH + 6) // Extra 6 characters to fix #7125 (Teamsay + long name + long message = too long message) { // Strip it for bad characters StripControlCodes(szMessage, ' '); @@ -1417,11 +1452,7 @@ void CPacketHandler::Packet_ChatEcho(NetBitStreamInterface& bitStream) Arguments.PushNumber(ucRed); Arguments.PushNumber(ucGreen); Arguments.PushNumber(ucBlue); - - if (bitStream.Can(eBitStreamVersion::OnClientChatMessage_MessageType)) - { - Arguments.PushNumber(ucMessageType); - } + Arguments.PushNumber(ucMessageType); if (pEntity->CallEvent("onClientChatMessage", Arguments, pEntity != pRootEntity)) { @@ -1630,22 +1661,22 @@ void CPacketHandler::Packet_VehicleDamageSync(NetBitStreamInterface& bitStream) { bool flyingComponents = g_pClientGame->IsWorldSpecialProperty(WorldSpecialProperty::FLYINGCOMPONENTS); - for (unsigned int i = 0; i < MAX_DOORS; ++i) + for (unsigned char i = 0; i < MAX_DOORS; ++i) { if (damage.data.bDoorStatesChanged[i]) pVehicle->SetDoorStatus(i, damage.data.ucDoorStates[i], flyingComponents); } - for (unsigned int i = 0; i < MAX_WHEELS; ++i) + for (unsigned char i = 0; i < MAX_WHEELS; ++i) { if (damage.data.bWheelStatesChanged[i]) pVehicle->SetWheelStatus(i, damage.data.ucWheelStates[i]); } - for (unsigned int i = 0; i < MAX_PANELS; ++i) + for (unsigned char i = 0; i < MAX_PANELS; ++i) { if (damage.data.bPanelStatesChanged[i]) pVehicle->SetPanelStatus(i, damage.data.ucPanelStates[i], flyingComponents); } - for (unsigned int i = 0; i < MAX_LIGHTS; ++i) + for (unsigned char i = 0; i < MAX_LIGHTS; ++i) { if (damage.data.bLightStatesChanged[i]) pVehicle->SetLightStatus(i, damage.data.ucLightStates[i]); @@ -1701,9 +1732,9 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) #ifdef MTA_DEBUG if (pPed->IsLocalPlayer() || pPed->IsSyncing()) { - char* actions[] = {"request_in_confirmed", "notify_in_return", "notify_in_abort_return", "request_out_confirmed", - "notify_out_return", "notify_out_abort_return", "notify_fell_off_return", "request_jack_confirmed", - "notify_jack_return", "attempt_failed"}; + const char* actions[] = {"request_in_confirmed", "notify_in_return", "notify_in_abort_return", "request_out_confirmed", + "notify_out_return", "notify_out_abort_return", "notify_fell_off_return", "request_jack_confirmed", + "notify_jack_return", "attempt_failed"}; g_pCore->GetConsole()->Printf("* Packet_InOut: %s", actions[ucAction]); } #endif @@ -1731,9 +1762,9 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) { // Call the onClientVehicleStartEnter event for remote players and peds we dont sync CLuaArguments Arguments; - Arguments.PushElement(pPed); // player / ped - Arguments.PushNumber(ucSeat); // seat - Arguments.PushNumber(ucDoor); // Door + Arguments.PushElement(pPed); // player / ped + Arguments.PushNumber(ucSeat); // seat + Arguments.PushNumber(ucDoor); // Door pVehicle->CallEvent("onClientVehicleStartEnter", Arguments, true); } @@ -1768,8 +1799,8 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) // Call the onClientPlayerEnterVehicle/onClientPedEnterVehicle event CLuaArguments Arguments; - Arguments.PushElement(pVehicle); // vehicle - Arguments.PushNumber(ucSeat); // seat + Arguments.PushElement(pVehicle); // vehicle + Arguments.PushNumber(ucSeat); // seat if (IS_PLAYER(pPed)) pPed->CallEvent("onClientPlayerVehicleEnter", Arguments, true); else @@ -1777,8 +1808,8 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) // Call the onClientVehicleEnter event CLuaArguments Arguments2; - Arguments2.PushElement(pPed); // player / ped - Arguments2.PushNumber(ucSeat); // seat + Arguments2.PushElement(pPed); // player / ped + Arguments2.PushNumber(ucSeat); // seat pVehicle->CallEvent("onClientVehicleEnter", Arguments2, true); break; } @@ -1804,25 +1835,27 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) CClientPed* pJacked = pVehicle->GetOccupant(ucSeat); // If it's the local player or syncing ped getting jacked, reset some stuff - if (pJacked) { - if (pJacked->IsLocalPlayer() || pJacked->IsSyncing()) { + if (pJacked) + { + if (pJacked->IsLocalPlayer() || pJacked->IsSyncing()) + { pJacked->ResetVehicleInOut(); } - else { + else + { // Desynced? Outside but supposed to be in // For local player or synced peds this is taken care of in CClientPed::UpdateVehicleInOut() - if (pJacked->GetOccupiedVehicle() && !pJacked->GetRealOccupiedVehicle()) { + if (pJacked->GetOccupiedVehicle() && !pJacked->GetRealOccupiedVehicle()) + { // Warp him back in pJacked->WarpIntoVehicle(pJacked->GetOccupiedVehicle(), pJacked->GetOccupiedVehicleSeat()); // For bikes and cars where jacked through passenger door, warp the passenger back in if desynced - if (ucSeat == 0) { + if (ucSeat == 0) + { CClientPed* pPassenger = pJacked->GetOccupiedVehicle()->GetOccupant(1); // Is the passenger a remote player or ped and is he physically outside but supposed to be in - if (pPassenger && - !pPassenger->IsLocalPlayer() && - !pPassenger->IsSyncing() && - pPassenger->GetOccupiedVehicle() && + if (pPassenger && !pPassenger->IsLocalPlayer() && !pPassenger->IsSyncing() && pPassenger->GetOccupiedVehicle() && !pPassenger->GetRealOccupiedVehicle()) { pPassenger->WarpIntoVehicle(pPassenger->GetOccupiedVehicle(), pPassenger->GetOccupiedVehicleSeat()); @@ -1866,9 +1899,9 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) pPed->SetVehicleInOutState(VEHICLE_INOUT_GETTING_OUT); CLuaArguments Arguments; - Arguments.PushElement(pPed); // player / ped - Arguments.PushNumber(ucSeat); // seat - Arguments.PushNumber(ucDoor); // door being used + Arguments.PushElement(pPed); // player / ped + Arguments.PushNumber(ucSeat); // seat + Arguments.PushNumber(ucDoor); // door being used pVehicle->CallEvent("onClientVehicleStartExit", Arguments, true); break; } @@ -1891,9 +1924,9 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) // Call the onClientPlayerExitVehicle/onClientPedExitVehicle event CLuaArguments Arguments; - Arguments.PushElement(pVehicle); // vehicle - Arguments.PushNumber(ucSeat); // seat - Arguments.PushBoolean(false); // jacker + Arguments.PushElement(pVehicle); // vehicle + Arguments.PushNumber(ucSeat); // seat + Arguments.PushBoolean(false); // jacker if (IS_PLAYER(pPed)) pPed->CallEvent("onClientPlayerVehicleExit", Arguments, true); else @@ -1901,9 +1934,9 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) // Call the onClientVehicleExit event CLuaArguments Arguments2; - Arguments2.PushElement(pPed); // player / ped - Arguments2.PushNumber(ucSeat); // seat - Arguments2.PushBoolean(false); // jacker + Arguments2.PushElement(pPed); // player / ped + Arguments2.PushNumber(ucSeat); // seat + Arguments2.PushBoolean(false); // jacker pVehicle->CallEvent("onClientVehicleExit", Arguments2, true); break; } @@ -1938,9 +1971,9 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) pVehicle->RemoveTargetPosition(); CLuaArguments Arguments; - Arguments.PushElement(pVehicle); // vehicle - Arguments.PushNumber(ucSeat); // seat - Arguments.PushBoolean(false); // jacker + Arguments.PushElement(pVehicle); // vehicle + Arguments.PushNumber(ucSeat); // seat + Arguments.PushBoolean(false); // jacker if (IS_PLAYER(pPed)) pPed->CallEvent("onClientPlayerVehicleExit", Arguments, true); else @@ -1948,9 +1981,9 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) // Call the onClientVehicleExit event CLuaArguments Arguments2; - Arguments2.PushElement(pPed); // player / ped - Arguments2.PushNumber(ucSeat); // seat - Arguments2.PushBoolean(false); // jacker + Arguments2.PushElement(pPed); // player / ped + Arguments2.PushNumber(ucSeat); // seat + Arguments2.PushBoolean(false); // jacker pVehicle->CallEvent("onClientVehicleExit", Arguments2, true); break; } @@ -1975,9 +2008,9 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) // Call the onClientVehicleStartEnter event for remote players and peds we don't sync // Local player / Syncing player triggers it himself before sending packet in CClientPed CLuaArguments Arguments; - Arguments.PushElement(pPed); // player / ped - Arguments.PushNumber(ucSeat); // seat - Arguments.PushNumber(ucDoor); // Door + Arguments.PushElement(pPed); // player / ped + Arguments.PushNumber(ucSeat); // seat + Arguments.PushNumber(ucDoor); // Door pVehicle->CallEvent("onClientVehicleStartEnter", Arguments, true); } @@ -2001,9 +2034,9 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) pPed->SetVehicleInOutState(VEHICLE_INOUT_JACKING); CLuaArguments Arguments2; - Arguments2.PushElement(pJacked); // player / ped - Arguments2.PushNumber(ucSeat); // seat - Arguments2.PushNumber(ucDoor); // door + Arguments2.PushElement(pJacked); // player / ped + Arguments2.PushNumber(ucSeat); // seat + Arguments2.PushNumber(ucDoor); // door pVehicle->CallEvent("onClientVehicleStartExit", Arguments2, true); break; } @@ -2068,27 +2101,27 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) // Call the onClientVehicleStartEnter event CLuaArguments Arguments; - Arguments.PushElement(pInsidePed); // player / ped - Arguments.PushNumber(ucSeat); // seat + Arguments.PushElement(pInsidePed); // player / ped + Arguments.PushNumber(ucSeat); // seat pVehicle->CallEvent("onClientVehicleEnter", Arguments, true); CLuaArguments Arguments2; - Arguments2.PushElement(pOutsidePed); // player / ped - Arguments2.PushNumber(ucSeat); // seat + Arguments2.PushElement(pOutsidePed); // player / ped + Arguments2.PushNumber(ucSeat); // seat pVehicle->CallEvent("onClientVehicleExit", Arguments2, true); CLuaArguments Arguments3; - Arguments3.PushElement(pVehicle); // vehicle - Arguments3.PushNumber(ucSeat); // seat - Arguments3.PushElement(pInsidePed); // jacker + Arguments3.PushElement(pVehicle); // vehicle + Arguments3.PushNumber(ucSeat); // seat + Arguments3.PushElement(pInsidePed); // jacker if (IS_PLAYER(pOutsidePed)) pOutsidePed->CallEvent("onClientPlayerVehicleExit", Arguments3, true); else pOutsidePed->CallEvent("onClientPedVehicleExit", Arguments3, true); CLuaArguments Arguments4; - Arguments4.PushElement(pVehicle); // vehicle - Arguments4.PushNumber(ucSeat); // seat + Arguments4.PushElement(pVehicle); // vehicle + Arguments4.PushNumber(ucSeat); // seat if (IS_PLAYER(pInsidePed)) pInsidePed->CallEvent("onClientPlayerVehicleEnter", Arguments4, true); else @@ -2170,9 +2203,9 @@ void CPacketHandler::Packet_VehicleTrailer(NetBitStreamInterface& bitStream) pTrailer->SetRotationDegrees(rotation.data.vecRotation); pTrailer->SetTurnSpeed(turn.data.vecVelocity); - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG g_pCore->GetConsole()->Printf("Packet_VehicleTrailer: attaching trailer %d to vehicle %d", TrailerID, ID); - #endif +#endif pVehicle->SetTowedVehicle(pTrailer); // Call the onClientTrailerAttach @@ -2182,9 +2215,9 @@ void CPacketHandler::Packet_VehicleTrailer(NetBitStreamInterface& bitStream) } else { - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG g_pCore->GetConsole()->Printf("Packet_VehicleTrailer: detaching trailer %d from vehicle %d", TrailerID, ID); - #endif +#endif pVehicle->SetTowedVehicle(NULL); // Call the onClientTrailerDetach @@ -2195,12 +2228,12 @@ void CPacketHandler::Packet_VehicleTrailer(NetBitStreamInterface& bitStream) } else { - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG if (!pVehicle) g_pCore->GetConsole()->Printf("Packet_VehicleTrailer: vehicle (id %d) not found", ID); if (!pTrailer) g_pCore->GetConsole()->Printf("Packet_VehicleTrailer: trailer (id %d) not found", TrailerID); - #endif +#endif } } } @@ -2327,13 +2360,10 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) { bitStream.Read(fNonSeaLevel); } - if (bitStream.Can(eBitStreamVersion::SetWaterLevel_ChangeOutsideWorldLevel)) + bitStream.ReadBit(bHasOutsideLevel); + if (bHasOutsideLevel) { - bitStream.ReadBit(bHasOutsideLevel); - if (bHasOutsideLevel) - { - bitStream.Read(fOutsideLevel); - } + bitStream.Read(fOutsideLevel); } // Reset world water level to GTA default g_pClientGame->GetManager()->GetWaterManager()->ResetWorldWaterLevel(); @@ -2346,9 +2376,9 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) // Apply world sea level (to world sea level water only) g_pClientGame->GetManager()->GetWaterManager()->SetWorldWaterLevel(fSeaLevel, nullptr, false, true, false); - unsigned short usFPSLimit = 36; - bitStream.ReadCompressed(usFPSLimit); - g_pCore->RecalculateFrameRateLimit(usFPSLimit); + std::uint16_t fps = 36; // Default to 36 + bitStream.ReadCompressed(fps); + CStaticFunctionDefinitions::SetServerFPSLimit(fps); // Read out the garage door states CGarages* pGarages = g_pCore->GetGame()->GetGarages(); @@ -2374,15 +2404,15 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_FASTMOVE, funBugs.data.bFastMove); g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_CROUCHBUG, funBugs.data.bCrouchBug); g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_CLOSEDAMAGE, funBugs.data.bCloseRangeDamage); - g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_HITANIM, funBugs.data2.bHitAnim); - g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_FASTSPRINT, funBugs.data3.bFastSprint); - g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_BADDRIVEBYHITBOX, funBugs.data4.bBadDrivebyHitboxes); - g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_QUICKSTAND, funBugs.data5.bQuickStand); - g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_VEHICLE_RAPID_STOP, funBugs.data6.vehicleRapidStop); + g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_HITANIM, funBugs.data.bHitAnim); + g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_FASTSPRINT, funBugs.data.bFastSprint); + g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_BADDRIVEBYHITBOX, funBugs.data.bBadDrivebyHitboxes); + g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_QUICKSTAND, funBugs.data.bQuickStand); + g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_VEHICLE_RAPID_STOP, funBugs.data.vehicleRapidStop); SWorldSpecialPropertiesStateSync wsProps; - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperties)) - bitStream.Read(&wsProps); + if (!bitStream.Read(&wsProps)) + return; g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::HOVERCARS, wsProps.data.hovercars); g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::AIRCARS, wsProps.data.aircars); @@ -2396,14 +2426,14 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::CORONAZTEST, wsProps.data.coronaztest); g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::WATERCREATURES, wsProps.data.watercreatures); g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::BURNFLIPPEDCARS, wsProps.data.burnflippedcars); - g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::FIREBALLDESTRUCT, wsProps.data2.fireballdestruct); - g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::ROADSIGNSTEXT, wsProps.data3.roadsignstext); - g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::EXTENDEDWATERCANNONS, wsProps.data4.extendedwatercannons); - g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::TUNNELWEATHERBLEND, wsProps.data5.tunnelweatherblend); - g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::IGNOREFIRESTATE, wsProps.data6.ignoreFireState); - g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::FLYINGCOMPONENTS, wsProps.data7.flyingcomponents); - g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::VEHICLEBURNEXPLOSIONS, wsProps.data8.vehicleburnexplosions); - g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::VEHICLE_ENGINE_AUTOSTART, wsProps.data9.vehicleEngineAutoStart); + g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::FIREBALLDESTRUCT, wsProps.data.fireballdestruct); + g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::ROADSIGNSTEXT, wsProps.data.roadsignstext); + g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::EXTENDEDWATERCANNONS, wsProps.data.extendedwatercannons); + g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::TUNNELWEATHERBLEND, wsProps.data.tunnelweatherblend); + g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::IGNOREFIRESTATE, wsProps.data.ignoreFireState); + g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::FLYINGCOMPONENTS, wsProps.data.flyingcomponents); + g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::VEHICLEBURNEXPLOSIONS, wsProps.data.vehicleburnexplosions); + g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::VEHICLE_ENGINE_AUTOSTART, wsProps.data.vehicleEngineAutoStart); float fJetpackMaxHeight = 100; if (!bitStream.Read(fJetpackMaxHeight)) @@ -2452,17 +2482,14 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) // Moon size bool bOverrideMoonSize = false; int iMoonSize = 3; - if (bitStream.Version() >= 0x40) + if (!bitStream.ReadBit(bOverrideMoonSize)) + return; + if (bOverrideMoonSize) { - if (!bitStream.ReadBit(bOverrideMoonSize)) + if (!bitStream.Read(iMoonSize)) return; - if (bOverrideMoonSize) - { - if (!bitStream.Read(iMoonSize)) - return; - g_pMultiplayer->SetMoonSize(iMoonSize); - } + g_pMultiplayer->SetMoonSize(iMoonSize); } // Sun size @@ -2540,27 +2567,22 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) // Aircraft max velocity float fAircraftMaxVelocity = 1.5f; - if (bitStream.Version() >= 0x3E) - { - if (!bitStream.Read(fAircraftMaxVelocity)) - return; + if (!bitStream.Read(fAircraftMaxVelocity)) + return; - g_pGame->GetWorld()->SetAircraftMaxVelocity(fAircraftMaxVelocity); - } + g_pGame->GetWorld()->SetAircraftMaxVelocity(fAircraftMaxVelocity); g_pGame->SetJetpackWeaponEnabled(WEAPONTYPE_TEC9, true); g_pGame->SetJetpackWeaponEnabled(WEAPONTYPE_MICRO_UZI, true); g_pGame->SetJetpackWeaponEnabled(WEAPONTYPE_PISTOL, true); - if (bitStream.Version() >= 0x30) + for (int i = WEAPONTYPE_BRASSKNUCKLE; i < WEAPONTYPE_PISTOL; i++) { - for (int i = WEAPONTYPE_BRASSKNUCKLE; i < WEAPONTYPE_PISTOL; i++) - { - bool bEnabled; - bitStream.ReadBit(bEnabled); - g_pGame->SetJetpackWeaponEnabled((eWeaponType)i, bEnabled); - } + bool bEnabled; + bitStream.ReadBit(bEnabled); + g_pGame->SetJetpackWeaponEnabled((eWeaponType)i, bEnabled); } + for (int i = WEAPONTYPE_PISTOL; i <= WEAPONTYPE_EXTINGUISHER; i++) { bool bReadWeaponInfo = true; @@ -2588,13 +2610,12 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) pWeaponInfo->SetAnimBreakoutTime(weaponProperty.data.anim_breakout_time); } - if (bitStream.Version() >= 0x30) - { - bool bEnabled; - bitStream.ReadBit(bEnabled); - g_pGame->SetJetpackWeaponEnabled((eWeaponType)weaponProperty.data.weaponType, bEnabled); - } + + bool bEnabled; + bitStream.ReadBit(bEnabled); + g_pGame->SetJetpackWeaponEnabled((eWeaponType)weaponProperty.data.weaponType, bEnabled); } + for (int i = WEAPONTYPE_PISTOL; i <= WEAPONTYPE_TEC9; i++) { bool bReadWeaponInfo = true; @@ -2625,21 +2646,17 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) pWeaponInfo->SetAnimBreakoutTime(weaponProperty.data.anim_breakout_time); } } - if (bitStream.Version() >= 0x36) - { - bool bEnabled; - bitStream.ReadBit(bEnabled); - g_pGame->SetJetpackWeaponEnabled((eWeaponType)weaponProperty.data.weaponType, bEnabled); - } + + bool bEnabled; + bitStream.ReadBit(bEnabled); + g_pGame->SetJetpackWeaponEnabled((eWeaponType)weaponProperty.data.weaponType, bEnabled); } - if (bitStream.Version() >= 0x30) + + for (int i = WEAPONTYPE_CAMERA; i <= WEAPONTYPE_PARACHUTE; i++) { - for (int i = WEAPONTYPE_CAMERA; i <= WEAPONTYPE_PARACHUTE; i++) - { - bool bEnabled; - bitStream.ReadBit(bEnabled); - g_pGame->SetJetpackWeaponEnabled((eWeaponType)i, bEnabled); - } + bool bEnabled; + bitStream.ReadBit(bEnabled); + g_pGame->SetJetpackWeaponEnabled((eWeaponType)i, bEnabled); } unsigned short usModel = 0; @@ -2652,16 +2669,12 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) bitStream.Read(fX); bitStream.Read(fY); bitStream.Read(fZ); - if (bitStream.Version() >= 0x039) - { - bitStream.Read(cInterior); - } + bitStream.Read(cInterior); g_pGame->GetBuildingRemoval()->RemoveBuilding(usModel, fRadius, fX, fY, fZ, cInterior); } bool bOcclusionsEnabled = true; - if (bitStream.Version() >= 0x25) - bitStream.ReadBit(bOcclusionsEnabled); + bitStream.ReadBit(bOcclusionsEnabled); g_pGame->GetWorld()->SetOcclusionsEnabled(bOcclusionsEnabled); } @@ -2696,8 +2709,8 @@ void CPacketHandler::Packet_PlayerNetworkStatus(NetBitStreamInterface& bitStream if (bitStream.Read(ucType) && bitStream.Read(uiTicks)) { CLuaArguments Arguments; - Arguments.PushNumber(ucType); // 0-interruption began 1-interruption end - Arguments.PushNumber(uiTicks); // Ticks since interruption start + Arguments.PushNumber(ucType); // 0-interruption began 1-interruption end + Arguments.PushNumber(uiTicks); // Ticks since interruption start CClientPlayer* pLocalPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); if (pLocalPlayer) { @@ -2713,104 +2726,104 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) if (g_pClientGame) g_pClientGame->NotifyBigPacketProgress(0, 0); - // This packet contains a list over entities to add to the world. - // There's a byte seperating the entities saying what type it is (vehicle spawn,object,weapon pickup) - - // Common: - // ElementID (2) - entity id - // unsigned char (1) - entity type id - // ElementID (2) - parent entity id - // unsigned char (1) - entity interior - // unsigned short (2) - entity dimension - // ElementID (2) - attached to entity id - // bool (1) - collisions enabled - // ??? (?) - custom data - - // Objects: - // CVector (12) - position - // CVector (12) - rotation - // unsigned short (2) - object model id - // unsigned char (1) - alpha - // CVector (12) - scale - // bool (1) - static - // SObjectHealthSync (?) - health - // bool (1) - is break - // bool (1) - respawnable - - // Pickups: - // CVector (12) - position - // unsigned char (1) - type - // bool - visible? - // unsigned char (1) - weapon type (if type is weapon) - - // Vehicles: - // CMatrix (48) - matrix - // unsigned char (1) - vehicle id - // float (4) - health - // unsigned char (1) - blow state (if supported) - // unsigned char (1) - color 1 - // unsigned char (1) - color 2 - // unsigned char (1) - color 3 - // unsigned char (1) - color 4 - // unsigned char (1) - paintjob - // float (4) - turret position x (if applies) - // float (4) - turret position y (if applies) - // unsigned short (2) - adjustable property (if applies) - // SDoorAngleSync (?) - Door #0 angle ratio. - // SDoorAngleSync (?) - Door #1 angle ratio. - // SDoorAngleSync (?) - Door #2 angle ratio. - // SDoorAngleSync (?) - Door #3 angle ratio. - // SDoorAngleSync (?) - Door #4 angle ratio. - // SDoorAngleSync (?) - Door #5 angle ratio. - // bool - landing gear down? (if applies) - // bool - sirenes on? (if applies) - // unsigned char (1) - no. of upgrades - // unsigned char (1++) - list of upgrades - // unsigned char (1) - reg-plate length - // char[] (?) - reg-plate - // unsigned char (1) - light override - // bool - can shoot petrol tank - // bool - engine on - // bool - locked - // bool - doors damageable - - // Blips: - // bool - attached to an entity? - // -- following if attached: - // unsigned char (1) - attached entity type - // unsigned char/short (1/2) - attached entity id (char if player, otherwize short) - // -- following if not attached: - // CVector (12) - position - // -- end - // unsigned char (1) - icon - // -- if icon is 0 - // unsigned char (1) - size - // unsigned long (4) - color - - // Radar areas: - // CVector2D (8) - position - // CVector2D (8) - size - // unsigned long (4) - color - // bool - flashing? - - // Path Nodes: - // CVector (12) - position - // CVector (12) - rotation - // int (4) - time - // unsigned char (1) - style - // ElementID (2) - next-node id - - // World meshes - // unsigned short (2) - name length - // char[] (?) - name - // CVector (12) - position - // CVector (12) - rotation - - // Teams - // unsigned short (2) - name length - // char[] (?) - name - // unsigned char[3] (3) - cols - // unsigned char (1) - friendly-fire + // This packet contains a list over entities to add to the world. + // There's a byte seperating the entities saying what type it is (vehicle spawn,object,weapon pickup) + + // Common: + // ElementID (2) - entity id + // unsigned char (1) - entity type id + // ElementID (2) - parent entity id + // unsigned char (1) - entity interior + // unsigned short (2) - entity dimension + // ElementID (2) - attached to entity id + // bool (1) - collisions enabled + // ??? (?) - custom data + + // Objects: + // CVector (12) - position + // CVector (12) - rotation + // unsigned short (2) - object model id + // unsigned char (1) - alpha + // CVector (12) - scale + // bool (1) - static + // SObjectHealthSync (?) - health + // bool (1) - is break + // bool (1) - respawnable + + // Pickups: + // CVector (12) - position + // unsigned char (1) - type + // bool - visible? + // unsigned char (1) - weapon type (if type is weapon) + + // Vehicles: + // CMatrix (48) - matrix + // unsigned char (1) - vehicle id + // float (4) - health + // unsigned char (1) - blow state (if supported) + // unsigned char (1) - color 1 + // unsigned char (1) - color 2 + // unsigned char (1) - color 3 + // unsigned char (1) - color 4 + // unsigned char (1) - paintjob + // float (4) - turret position x (if applies) + // float (4) - turret position y (if applies) + // unsigned short (2) - adjustable property (if applies) + // SDoorAngleSync (?) - Door #0 angle ratio. + // SDoorAngleSync (?) - Door #1 angle ratio. + // SDoorAngleSync (?) - Door #2 angle ratio. + // SDoorAngleSync (?) - Door #3 angle ratio. + // SDoorAngleSync (?) - Door #4 angle ratio. + // SDoorAngleSync (?) - Door #5 angle ratio. + // bool - landing gear down? (if applies) + // bool - sirenes on? (if applies) + // unsigned char (1) - no. of upgrades + // unsigned char (1++) - list of upgrades + // unsigned char (1) - reg-plate length + // char[] (?) - reg-plate + // unsigned char (1) - light override + // bool - can shoot petrol tank + // bool - engine on + // bool - locked + // bool - doors damageable + + // Blips: + // bool - attached to an entity? + // -- following if attached: + // unsigned char (1) - attached entity type + // unsigned char/short (1/2) - attached entity id (char if player, otherwize short) + // -- following if not attached: + // CVector (12) - position + // -- end + // unsigned char (1) - icon + // -- if icon is 0 + // unsigned char (1) - size + // unsigned long (4) - color + + // Radar areas: + // CVector2D (8) - position + // CVector2D (8) - size + // unsigned long (4) - color + // bool - flashing? + + // Path Nodes: + // CVector (12) - position + // CVector (12) - rotation + // int (4) - time + // unsigned char (1) - style + // ElementID (2) - next-node id + + // World meshes + // unsigned short (2) - name length + // char[] (?) - name + // CVector (12) - position + // CVector (12) - rotation + + // Teams + // unsigned short (2) - name length + // char[] (?) - name + // unsigned char[3] (3) - cols + // unsigned char (1) - friendly-fire #if MTA_DEBUG retry: @@ -2864,11 +2877,7 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) // Check element collisions enabled ( for use later on ) bitStream.ReadBit(bCollisonsEnabled); - - if (bitStream.Version() >= 0x56) - bitStream.ReadBit(bCallPropagationEnabled); - else - bCallPropagationEnabled = true; + bitStream.ReadBit(bCallPropagationEnabled); // Read custom data CCustomData* pCustomData = new CCustomData; @@ -2890,11 +2899,11 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) CLuaArgument Argument; Argument.ReadFromBitStream(bitStream); - pCustomData->Set(strName, Argument); + pCustomData->Set(CStringName{strName}, Argument); } else { - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG char buf[256] = {0}; bitStream.Read(buf, ucNameLength); // Raise a special assert, as we have to try and figure out this error. @@ -2902,7 +2911,7 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) // Replay the problem for debugging bitStream.ResetReadPointer(); goto retry; - #endif +#endif delete pCustomData; pCustomData = NULL; @@ -2913,11 +2922,11 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) } else { - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG // Jax: had this with a colshape (ucNameLength=109,us=0,usNumData=4) // Raise a special assert, as we have to try and figure out this error. assert(0); - #endif +#endif delete pCustomData; pCustomData = NULL; @@ -3032,15 +3041,12 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) return; } - if (bitStream.ReadBit()) - pObject->SetDoubleSided(true); + pObject->SetDoubleSided(bitStream.ReadBit()); - if (bitStream.Can(eBitStreamVersion::CEntityAddPacket_ObjectBreakable)) - pObject->SetBreakable(bitStream.ReadBit()); + pObject->SetBreakable(bitStream.ReadBit()); - if (bitStream.Can(eBitStreamVersion::DimensionOmnipresence)) - if (bitStream.ReadBit()) - pObject->SetVisibleInAllDimensions(true); + if (bitStream.ReadBit()) + pObject->SetVisibleInAllDimensions(true); bool bIsMoving; if (bitStream.ReadBit(bIsMoving) && bIsMoving) @@ -3058,33 +3064,24 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) } CVector vecScale; - if (bitStream.Version() >= 0x41) + bool bIsUniform; + bitStream.ReadBit(bIsUniform); + if (bIsUniform) { - bool bIsUniform; - bitStream.ReadBit(bIsUniform); - if (bIsUniform) - { - bool bIsUnitSize; - bitStream.ReadBit(bIsUnitSize); - if (!bIsUnitSize) - bitStream.Read(vecScale.fX); - else - vecScale.fX = 1.0f; - vecScale.fY = vecScale.fX; - vecScale.fZ = vecScale.fX; - } - else - { + bool bIsUnitSize; + bitStream.ReadBit(bIsUnitSize); + if (!bIsUnitSize) bitStream.Read(vecScale.fX); - bitStream.Read(vecScale.fY); - bitStream.Read(vecScale.fZ); - } + else + vecScale.fX = 1.0f; + vecScale.fY = vecScale.fX; + vecScale.fZ = vecScale.fX; } else { bitStream.Read(vecScale.fX); - vecScale.fY = vecScale.fX; - vecScale.fZ = vecScale.fX; + bitStream.Read(vecScale.fY); + bitStream.Read(vecScale.fZ); } pObject->SetScale(vecScale); @@ -3096,21 +3093,17 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) if (bitStream.Read(&health)) pObject->SetHealth(health.data.fValue); - if (bitStream.Can(eBitStreamVersion::BreakObject_Serverside)) - { - if (bitStream.ReadBit()) - pObject->Break(); - } + if (bitStream.ReadBit()) + pObject->Break(); - if (bitStream.Can(eBitStreamVersion::RespawnObject_Serverside)) - pObject->SetRespawnEnabled(bitStream.ReadBit()); + pObject->SetRespawnEnabled(bitStream.ReadBit()); pObject->SetCollisionEnabled(bCollisonsEnabled); if (ucEntityTypeID == CClientGame::WEAPON) { CClientWeapon* pWeapon = (CClientWeapon*)pObject; unsigned char ucTargetType = eTargetType::TARGET_TYPE_FIXED; - bitStream.ReadBits(&ucTargetType, 3); // 3 bits = 4 possible values. + bitStream.ReadBits(&ucTargetType, 3); // 3 bits = 4 possible values. switch (ucTargetType) { case TARGET_TYPE_FIXED: @@ -3129,13 +3122,13 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) { if (IS_PED(pTarget)) { - bitStream.Read(ucSubTarget); // Send the entire unsigned char as there are a lot of bones. + bitStream.Read(ucSubTarget); // Send the entire unsigned char as there are a lot of bones. } else if (IS_VEHICLE(pTarget)) { bitStream.ReadBits(&ucSubTarget, 4); } - pWeapon->SetWeaponTarget(pTarget, ucSubTarget); // 4 bits = 8 possible values. + pWeapon->SetWeaponTarget(pTarget, ucSubTarget); // 4 bits = 8 possible values. } break; } @@ -3153,7 +3146,7 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) { float fAccuracy, fTargetRange, fWeaponRange; unsigned short usDamagePerHit; - bitStream.ReadBits(&usDamagePerHit, 12); // 12 bits = 2048 values... plenty. + bitStream.ReadBits(&usDamagePerHit, 12); // 12 bits = 2048 values... plenty. bitStream.Read(fAccuracy); bitStream.Read(fTargetRange); bitStream.Read(fWeaponRange); @@ -3180,7 +3173,7 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) unsigned short usAmmo, usClipAmmo; unsigned char ucWeaponState; - bitStream.ReadBits(&ucWeaponState, 4); // 4 bits = 8 possible values for weapon state + bitStream.ReadBits(&ucWeaponState, 4); // 4 bits = 8 possible values for weapon state bitStream.Read(usAmmo); bitStream.Read(usClipAmmo); pWeapon->SetClipAmmo(usClipAmmo); @@ -3222,11 +3215,6 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) // Create the pickup with the given position and model CClientPickup* pPickup = new CClientPickup(g_pClientGame->m_pManager, EntityID, usModel, position.data.vecPosition); pEntity = pPickup; - if (!pPickup) - { - RaiseEntityAddError(64); - return; - } pPickup->m_ucType = pickupType.data.ucType; switch (pickupType.data.ucType) @@ -3283,18 +3271,10 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) SRotationDegreesSync rotationDegrees(false); bitStream.Read(&rotationDegrees); - // Read out the vehicle value as a char, then convert - unsigned char ucModel = 0xFF; - bitStream.Read(ucModel); - - // The server appears to subtract 400 from the vehicle id before - // sending it to us, as to allow the value to fit into an unsigned - // char. - // - // Too bad this was never documented. - // - // --slush - unsigned short usModel = ucModel + 400; + // Read out the vehicle model + std::uint16_t usModel = 0xFFFF; + bitStream.Read(usModel); + if (!CClientVehicleManager::IsValidModel(usModel)) { RaiseEntityAddError(39); @@ -3313,29 +3293,20 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) VehicleBlowState blowState = VehicleBlowState::INTACT; unsigned char rawBlowState = 0; - if (bitStream.Can(eBitStreamVersion::VehicleBlowStateSupport)) + if (!bitStream.ReadBits(&rawBlowState, 2)) { - if (!bitStream.ReadBits(&rawBlowState, 2)) - { - RaiseEntityAddError(75); - return; - } - - switch (rawBlowState) - { - case 1: - blowState = VehicleBlowState::AWAITING_EXPLOSION_SYNC; - break; - case 2: - blowState = VehicleBlowState::BLOWN; - break; - } + RaiseEntityAddError(75); + return; } - else if (health.data.fValue <= 0.0f) + + switch (rawBlowState) { - // Blow state is not supported by the server and we are required to blow the vehicle - // if the health is equal to or below zero - blowState = VehicleBlowState::AWAITING_EXPLOSION_SYNC; + case 1: + blowState = VehicleBlowState::AWAITING_EXPLOSION_SYNC; + break; + case 2: + blowState = VehicleBlowState::BLOWN; + break; } // Read out the color @@ -3399,13 +3370,13 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) bool flyingComponents = g_pClientGame->IsWorldSpecialProperty(WorldSpecialProperty::FLYINGCOMPONENTS); // Setup our damage model - for (int i = 0; i < MAX_DOORS; i++) + for (unsigned char i = 0; i < MAX_DOORS; i++) pVehicle->SetDoorStatus(i, damage.data.ucDoorStates[i], flyingComponents); - for (int i = 0; i < MAX_WHEELS; i++) + for (unsigned char i = 0; i < MAX_WHEELS; i++) pVehicle->SetWheelStatus(i, damage.data.ucWheelStates[i]); - for (int i = 0; i < MAX_PANELS; i++) + for (unsigned char i = 0; i < MAX_PANELS; i++) pVehicle->SetPanelStatus(i, damage.data.ucPanelStates[i], flyingComponents); - for (int i = 0; i < MAX_LIGHTS; i++) + for (unsigned char i = 0; i < MAX_LIGHTS; i++) pVehicle->SetLightStatus(i, damage.data.ucLightStates[i]); pVehicle->ResetDamageModelSync(); @@ -3588,35 +3559,34 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) // pEntry->SetTailLight ( (CHandlingEntry::eLightType)handling.data.ucTailLight ); // pEntry->SetAnimGroup ( handling.data.ucAnimGroup ); } - if (bitStream.Version() >= 0x02A) + + unsigned char ucSirenCount = 0; + unsigned char ucSirenType = 0; + bool bSync = false; + bitStream.ReadBit(bSync); + if (bSync) { - unsigned char ucSirenCount = 0; - unsigned char ucSirenType = 0; - bool bSync = false; - bitStream.ReadBit(bSync); - if (bSync) - { - bitStream.Read(ucSirenCount); - bitStream.Read(ucSirenType); + bitStream.Read(ucSirenCount); + bitStream.Read(ucSirenType); - pVehicle->GiveVehicleSirens(ucSirenType, ucSirenCount); - for (int i = 0; i < ucSirenCount; i++) - { - SVehicleSirenSync sirenData; - bitStream.Read(&sirenData); - pVehicle->SetVehicleSirenPosition(i, sirenData.data.m_vecSirenPositions); - pVehicle->SetVehicleSirenColour(i, sirenData.data.m_colSirenColour); - pVehicle->SetVehicleSirenMinimumAlpha(i, sirenData.data.m_dwSirenMinAlpha); - pVehicle->SetVehicleFlags(sirenData.data.m_b360Flag, sirenData.data.m_bUseRandomiser, sirenData.data.m_bDoLOSCheck, - sirenData.data.m_bEnableSilent); - } - } - // If the vehicle has sirens, set the siren state - if (CClientVehicleManager::HasSirens(usModel) || pVehicle->DoesVehicleHaveSirens()) + pVehicle->GiveVehicleSirens(ucSirenType, ucSirenCount); + for (unsigned char i = 0; i < ucSirenCount; i++) { - pVehicle->SetSirenOrAlarmActive(bSirenesActive); + SVehicleSirenSync sirenData; + bitStream.Read(&sirenData); + pVehicle->SetVehicleSirenPosition(i, sirenData.data.m_vecSirenPositions); + pVehicle->SetVehicleSirenColour(i, sirenData.data.m_colSirenColour); + pVehicle->SetVehicleSirenMinimumAlpha(i, sirenData.data.m_dwSirenMinAlpha); + pVehicle->SetVehicleFlags(sirenData.data.m_b360Flag, sirenData.data.m_bUseRandomiser, sirenData.data.m_bDoLOSCheck, + sirenData.data.m_bEnableSilent); } } + // If the vehicle has sirens, set the siren state + if (CClientVehicleManager::HasSirens(usModel) || pVehicle->DoesVehicleHaveSirens()) + { + pVehicle->SetSirenOrAlarmActive(bSirenesActive); + } + pVehicle->ApplyHandling(); // Set the matrix @@ -3670,7 +3640,7 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) pCheckpoint->SetIcon(CClientCheckpoint::ICON_ARROW); } - if (ucType == CClientGame::MARKER_CHECKPOINT && bitStream.Can(eBitStreamVersion::SetMarkerTargetArrowProperties)) + if (ucType == CClientGame::MARKER_CHECKPOINT) { SColor color; float size; @@ -3686,8 +3656,7 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) } // Read out alpha limit flag - if (bitStream.Can(eBitStreamVersion::Marker_IgnoreAlphaLimits)) - pMarker->SetIgnoreAlphaLimits(bitStream.ReadBit()); + pMarker->SetIgnoreAlphaLimits(bitStream.ReadBit()); pMarker->SetColor(color); } @@ -3925,8 +3894,7 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) // Move anim uchar ucMoveAnim = MOVE_DEFAULT; - if (bitStream.Version() > 0x4B) - bitStream.Read(ucMoveAnim); + bitStream.Read(ucMoveAnim); pPed->SetMoveAnim((eMoveAnim)ucMoveAnim); // clothes @@ -3962,79 +3930,73 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) } // weapons - if (bitStream.Version() >= 0x61) - { - unsigned char slot; - bitStream.Read(slot); + unsigned char slot; + bitStream.Read(slot); - while (slot != 0xFF) - { - // Read info from bitstream - unsigned char ucType; - bitStream.Read(ucType); + while (slot != 0xFF) + { + // Read info from bitstream + unsigned char ucType; + bitStream.Read(ucType); - unsigned short usTotalAmmo; - bitStream.Read(usTotalAmmo); + unsigned short usTotalAmmo; + bitStream.Read(usTotalAmmo); - // ammoInClip is not implemented generally - // unsigned short usAmmoInClip; - // bitStream.Read ( usAmmoInClip ); + // ammoInClip is not implemented generally + // unsigned short usAmmoInClip; + // bitStream.Read ( usAmmoInClip ); - // Apply read info - CWeapon* pWeapon = pPed->GiveWeapon((eWeaponType)ucType, usTotalAmmo); - pPed->m_usWeaponAmmo[slot] = usTotalAmmo; - if (pWeapon) - { - // pWeapon->SetAmmoInClip ( usAmmoInClip ); - pWeapon->SetAmmoTotal(usTotalAmmo); - } - - // Get next slot - bitStream.Read(slot); + // Apply read info + CWeapon* pWeapon = pPed->GiveWeapon((eWeaponType)ucType, usTotalAmmo); + pPed->m_usWeaponAmmo[slot] = usTotalAmmo; + if (pWeapon) + { + // pWeapon->SetAmmoInClip ( usAmmoInClip ); + pWeapon->SetAmmoTotal(usTotalAmmo); } - // Read and set current slot - unsigned char ucCurrentSlot; - bitStream.Read(ucCurrentSlot); - pPed->SetCurrentWeaponSlot((eWeaponSlot)ucCurrentSlot); + // Get next slot + bitStream.Read(slot); } + // Read and set current slot + unsigned char ucCurrentSlot; + bitStream.Read(ucCurrentSlot); + pPed->SetCurrentWeaponSlot((eWeaponSlot)ucCurrentSlot); + // Collisions pPed->SetUsesCollision(bCollisonsEnabled); // Animation - if (bitStream.Can(eBitStreamVersion::AnimationsSync)) + if (bitStream.ReadBit()) { - // Contains animation data? - if (bitStream.ReadBit()) - { - std::string blockName, animName; - int time, blendTime; - bool looped, updatePosition, interruptable, freezeLastFrame, taskRestore; - float elapsedTime, speed; - - // Read data - bitStream.ReadString(blockName); - bitStream.ReadString(animName); - bitStream.Read(time); - bitStream.ReadBit(looped); - bitStream.ReadBit(updatePosition); - bitStream.ReadBit(interruptable); - bitStream.ReadBit(freezeLastFrame); - bitStream.Read(blendTime); - bitStream.ReadBit(taskRestore); - bitStream.Read(elapsedTime); - bitStream.Read(speed); - - // Run anim - CStaticFunctionDefinitions::SetPedAnimation(*pPed, blockName, animName.c_str(), time, blendTime, looped, updatePosition, interruptable, freezeLastFrame); - pPed->m_AnimationCache.progressWaitForStreamIn = true; - pPed->m_AnimationCache.elapsedTime = elapsedTime; - - CStaticFunctionDefinitions::SetPedAnimationSpeed(*pPed, animName, speed); - - pPed->SetHasSyncedAnim(true); - } + std::string blockName, animName; + int time, blendTime; + bool looped, updatePosition, interruptable, freezeLastFrame, taskRestore; + float speed; + double startTime; + + // Read data + bitStream.ReadString(blockName); + bitStream.ReadString(animName); + bitStream.Read(time); + bitStream.ReadBit(looped); + bitStream.ReadBit(updatePosition); + bitStream.ReadBit(interruptable); + bitStream.ReadBit(freezeLastFrame); + bitStream.Read(blendTime); + bitStream.ReadBit(taskRestore); + bitStream.Read(startTime); + bitStream.Read(speed); + + // Run anim + CStaticFunctionDefinitions::SetPedAnimation(*pPed, blockName, animName.c_str(), time, blendTime, looped, updatePosition, interruptable, + freezeLastFrame); + pPed->m_AnimationCache.startTime = static_cast(startTime); + pPed->m_AnimationCache.speed = speed; + pPed->m_AnimationCache.progress = 0.0f; + + pPed->SetHasSyncedAnim(true); } break; @@ -4065,7 +4027,7 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) { CResource* pResource = g_pClientGame->m_pResourceManager->GetResource(szName); if (pResource) - pResource->SetResourceEntity(pDummy); // problem with resource starting without this entity + pResource->SetResourceEntity(pDummy); // problem with resource starting without this entity } } @@ -4151,7 +4113,6 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) pPolygon->AddPoint(vertex.data.vecPosition); } pEntity = pShape = pPolygon; - if (bitStream.Can(eBitStreamVersion::SetColPolygonHeight)) { float fFloor, fCeil; if (bitStream.Read(fFloor) && bitStream.Read(fCeil)) @@ -4199,8 +4160,7 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) } bool bShallow = false; - if (bitStream.Can(eBitStreamVersion::Water_bShallow_ServerSide)) - bitStream.ReadBit(bShallow); + bitStream.ReadBit(bShallow); CClientWater* pWater = NULL; if (ucNumVertices == 3) @@ -4235,7 +4195,8 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) modelId = 1700; bitStream.Read(LowLodObjectID); - CClientBuilding* pBuilding = new CClientBuilding(g_pClientGame->m_pManager, EntityID, modelId, position.data.vecPosition, rotationRadians.data.vecRotation, ucInterior); + CClientBuilding* pBuilding = new CClientBuilding(g_pClientGame->m_pManager, EntityID, modelId, position.data.vecPosition, + rotationRadians.data.vecRotation, ucInterior); pBuilding->SetUsesCollision(bCollisonsEnabled); break; @@ -4436,8 +4397,12 @@ void CPacketHandler::Packet_PickupHideShow(NetBitStreamInterface& bitStream) CClientPickup* pPickup = g_pClientGame->m_pPickupManager->Get(PickupID); if (pPickup) { + // Only update model if it changed (avoids unnecessary recreate) + if (pPickup->GetModel() != usPickupModel) + { + pPickup->SetModel(usPickupModel); + } // Show/hide it - pPickup->SetModel(usPickupModel); pPickup->SetVisible(bShow); } } @@ -4568,7 +4533,7 @@ void CPacketHandler::Packet_TextItem(NetBitStreamInterface& bitStream) // Does the text not already exist? Create it std::shared_ptr textDisplay = nullptr; - std::shared_ptr display = g_pClientGame->m_pDisplayManager->Get(ulID); + std::shared_ptr display = g_pClientGame->m_pDisplayManager->Get(ulID); if (display && display->GetType() == DISPLAY_TEXT) { @@ -4621,7 +4586,7 @@ void CPacketHandler::Packet_ExplosionSync(NetBitStreamInterface& bitStream) bool isVehicleResponsible = false; bool blowVehicleWithoutExplosion = false; - if (bHasOrigin && bitStream.Can(eBitStreamVersion::VehicleBlowStateSupport)) + if (bHasOrigin) { if (!bitStream.ReadBit(isVehicleResponsible)) return; @@ -4755,7 +4720,7 @@ void CPacketHandler::Packet_ExplosionSync(NetBitStreamInterface& bitStream) // Call onClientVehicleExplode CLuaArguments arguments; - arguments.PushBoolean(!bCancelExplosion); // withExplosion + arguments.PushBoolean(!bCancelExplosion); // withExplosion vehicle->CallEvent("onClientVehicleExplode", arguments, true); if (!bCancelExplosion) @@ -4843,15 +4808,8 @@ void CPacketHandler::Packet_ProjectileSync(NetBitStreamInterface& bitStream) // Read the model unsigned short usModel = 0; - if (bitStream.Version() >= 0x4F) - { - if (bitStream.Version() >= 0x52 || bHasCreator) // Fix possible error from 0x51 server - if (!bitStream.Read(usModel)) - return; - } - - if (bitStream.Version() < 0x52) - usModel = 0; // Fix possible error from 0x51 server + if (!bitStream.Read(usModel)) + return; // Crash fix - usModel is not valid for some clients // either because number is incorrect due to some mismatch in bitstream versions @@ -5053,27 +5011,33 @@ void CPacketHandler::Packet_LuaEvent(NetBitStreamInterface& bitStream) szName[usNameLength] = 0; // Read out the arguments aswell - CLuaArguments Arguments(bitStream); - - // Grab the event. Does it exist and is it remotely triggerable? - SEvent* pEvent = g_pClientGame->m_Events.Get(szName); - if (pEvent) + CLuaArguments Arguments; + if (!Arguments.ReadFromBitStream(bitStream)) { - if (pEvent->bAllowRemoteTrigger) + g_pClientGame->m_pScriptDebugging->LogError(nullptr, "Server triggered clientside event %s with invalid argument data", szName); + } + else + { + // Grab the event. Does it exist and is it remotely triggerable? + SEvent* pEvent = g_pClientGame->m_Events.Get(szName); + if (pEvent) { - // Grab the element we trigger it on - CClientEntity* pEntity = CElementIDs::GetElement(EntityID); - if (pEntity) + if (pEvent->bAllowRemoteTrigger) { - pEntity->CallEvent(szName, Arguments, true); + // Grab the element we trigger it on + CClientEntity* pEntity = CElementIDs::GetElement(EntityID); + if (pEntity) + { + pEntity->CallEvent(szName, Arguments, true); + } } + else + g_pClientGame->m_pScriptDebugging->LogError( + nullptr, "Server triggered clientside event %s, but event is not marked as remotely triggerable", szName); } else - g_pClientGame->m_pScriptDebugging->LogError(NULL, "Server triggered clientside event %s, but event is not marked as remotely triggerable", - szName); + g_pClientGame->m_pScriptDebugging->LogError(nullptr, "Server triggered clientside event %s, but event is not added clientside", szName); } - else - g_pClientGame->m_pScriptDebugging->LogError(NULL, "Server triggered clientside event %s, but event is not added clientside", szName); } // Delete event name again @@ -5090,8 +5054,9 @@ void CPacketHandler::Packet_ResourceStart(NetBitStreamInterface& bitStream) uiTotalSizeProcessed = 0; /* - * unsigned char (1) - resource name size + * unsigned char (1) - resource name size * unsigned char (x) - resource name + * unsigned int (4) - start counter * unsigned short (2) - resource id * unsigned short (2) - resource entity id * unsigned short (2) - resource dynamic entity id @@ -5146,6 +5111,10 @@ void CPacketHandler::Packet_ResourceStart(NetBitStreamInterface& bitStream) return; } + // Start counter + unsigned int startCounter{}; + bitStream.Read(startCounter); + // Resource ID unsigned short usResourceID; bitStream.Read(usResourceID); @@ -5156,28 +5125,18 @@ void CPacketHandler::Packet_ResourceStart(NetBitStreamInterface& bitStream) bitStream.Read(ResourceDynamicEntityID); // Read the amount of 'no client cache' scripts - if (bitStream.Version() >= 0x26) - bitStream.Read(usNoClientCacheScriptCount); + bitStream.Read(usNoClientCacheScriptCount); // Read the declared min client version for this resource CMtaVersion strMinServerReq, strMinClientReq; - if (bitStream.Version() >= 0x32) - { - bitStream.ReadString(strMinServerReq); - bitStream.ReadString(strMinClientReq); - } + bitStream.ReadString(strMinServerReq); + bitStream.ReadString(strMinClientReq); bool bEnableOOP = false; - if (bitStream.Version() >= 0x45) - { - bitStream.ReadBit(bEnableOOP); - } + bitStream.ReadBit(bEnableOOP); int iDownloadPriorityGroup = 0; - if (bitStream.Version() >= 0x62) - { - bitStream.Read(iDownloadPriorityGroup); - } + bitStream.Read(iDownloadPriorityGroup); // Get the resource entity CClientEntity* pResourceEntity = CElementIDs::GetElement(ResourceEntityID); @@ -5197,8 +5156,11 @@ void CPacketHandler::Packet_ResourceStart(NetBitStreamInterface& bitStream) strMinClientReq, bEnableOOP); if (pResource) { + CDownloadableResource::BeginChecksumBatch(); + pResource->SetRemainingNoClientCacheScripts(usNoClientCacheScriptCount); pResource->SetDownloadPriorityGroup(iDownloadPriorityGroup); + pResource->SetStartCounter(startCounter); // Resource Chunk Type (F = Resource File, E = Exported Function) unsigned char ucChunkType; @@ -5217,7 +5179,7 @@ void CPacketHandler::Packet_ResourceStart(NetBitStreamInterface& bitStream) { switch (ucChunkType) { - case 'E': // Exported Function + case 'E': // Exported Function if (bitStream.Read(ucChunkSize)) { szChunkData = new char[ucChunkSize + 1]; @@ -5231,7 +5193,7 @@ void CPacketHandler::Packet_ResourceStart(NetBitStreamInterface& bitStream) } break; - case 'F': // Resource File + case 'F': // Resource File if (bitStream.Read(ucChunkSize)) { szChunkData = new char[ucChunkSize + 1]; @@ -5360,6 +5322,8 @@ void CPacketHandler::Packet_ResourceStart(NetBitStreamInterface& bitStream) // Are there any resources to being downloaded? if (!g_pClientGame->GetResourceFileDownloadManager()->IsTransferringInitialFiles()) { + CDownloadableResource::EndChecksumBatch(); + // Load the resource now if (pResource->CanBeLoaded()) { @@ -5374,6 +5338,7 @@ void CPacketHandler::Packet_ResourceStart(NetBitStreamInterface& bitStream) if (bFatalError) { + CDownloadableResource::EndChecksumBatch(); g_pClientGame->m_pResourceManager->Remove(pResource); RaiseFatalError(2081); } @@ -5402,8 +5367,7 @@ void CPacketHandler::Packet_ResourceClientScripts(NetBitStreamInterface& bitStre for (unsigned int i = 0; i < usScriptCount; ++i) { SString strFilename = "(unknown)"; - if (bitStream.Version() >= 0x50) - bitStream.ReadString(strFilename); + bitStream.ReadString(strFilename); // Read the script compressed chunk unsigned int len; @@ -5481,24 +5445,26 @@ void CPacketHandler::Packet_DestroySatchels(NetBitStreamInterface& bitStream) void CPacketHandler::Packet_VoiceData(NetBitStreamInterface& bitStream) { - unsigned short usPacketSize; + unsigned short voiceBufferLength; ElementID PlayerID; + if (bitStream.Read(PlayerID)) { CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->Get(PlayerID); - if (pPlayer && bitStream.Read(usPacketSize)) + + if (pPlayer && bitStream.Read(voiceBufferLength) && voiceBufferLength <= 2048) { - char* pBuf = new char[usPacketSize]; + const auto voiceBuffer = new unsigned char[voiceBufferLength]; - if (bitStream.Read(pBuf, usPacketSize)) + if (bitStream.Read(reinterpret_cast(voiceBuffer), voiceBufferLength)) { if (pPlayer->GetVoice()) { - pPlayer->GetVoice()->DecodeAndBuffer(pBuf, usPacketSize); + pPlayer->GetVoice()->DecodeAndBuffer(voiceBuffer, voiceBufferLength); } } - delete[] pBuf; + delete[] voiceBuffer; } } } @@ -5533,39 +5499,36 @@ void CPacketHandler::Packet_SyncSettings(NetBitStreamInterface& bitStream) g_pClientGame->SetWeaponTypesUsingBulletSync(weaponTypesUsingBulletSync); } - if (bitStream.Version() >= 0x35) + uchar ucEnabled; + short sBaseMs, sScalePercent, sMaxMs; + bitStream.Read(ucEnabled); + bitStream.Read(sBaseMs); + bitStream.Read(sScalePercent); + if (bitStream.Read(sMaxMs)) { - uchar ucEnabled; - short sBaseMs, sScalePercent, sMaxMs; - bitStream.Read(ucEnabled); - bitStream.Read(sBaseMs); - bitStream.Read(sScalePercent); - if (bitStream.Read(sMaxMs)) - { - SVehExtrapolateSettings vehExtrapolateSettings; - vehExtrapolateSettings.bEnabled = ucEnabled != 0; - vehExtrapolateSettings.iBaseMs = sBaseMs; - vehExtrapolateSettings.iScalePercent = sScalePercent; - vehExtrapolateSettings.iMaxMs = sMaxMs; - g_pClientGame->SetVehExtrapolateSettings(vehExtrapolateSettings); - } + SVehExtrapolateSettings vehExtrapolateSettings; + vehExtrapolateSettings.bEnabled = ucEnabled != 0; + vehExtrapolateSettings.iBaseMs = sBaseMs; + vehExtrapolateSettings.iScalePercent = sScalePercent; + vehExtrapolateSettings.iMaxMs = sMaxMs; + g_pClientGame->SetVehExtrapolateSettings(vehExtrapolateSettings); } uchar ucUseAltPulseOrder = 0; - if (bitStream.Version() >= 0x3D) - bitStream.Read(ucUseAltPulseOrder); + bitStream.Read(ucUseAltPulseOrder); uchar ucAllowFastSprintFix = 0; - if (bitStream.Version() >= 0x58) - bitStream.Read(ucAllowFastSprintFix); + bitStream.Read(ucAllowFastSprintFix); uchar ucAllowBadDrivebyHitboxesFix = 0; - if (bitStream.Version() >= 0x59) - bitStream.Read(ucAllowBadDrivebyHitboxesFix); + bitStream.Read(ucAllowBadDrivebyHitboxesFix); uchar ucAllowShotgunDamageFix = 0; - if (bitStream.Can(eBitStreamVersion::ShotgunDamageFix)) - bitStream.Read(ucAllowShotgunDamageFix); + bitStream.Read(ucAllowShotgunDamageFix); + + uchar allowMultiCommandHandlers = 1; + bitStream.Read(allowMultiCommandHandlers); + g_pClientGame->SetAllowMultiCommandHandlers(static_cast(allowMultiCommandHandlers)); SMiscGameSettings miscGameSettings; miscGameSettings.bUseAltPulseOrder = (ucUseAltPulseOrder != 0); @@ -5734,11 +5697,7 @@ SString CPacketHandler::EntityAddDebugRead(NetBitStreamInterface& bitStream) // Check element collisions enabled ( for use later on ) bitStream.ReadBit(bCollisonsEnabled); - - if (bitStream.Version() >= 0x56) - bitStream.ReadBit(bCallPropagationEnabled); - else - bCallPropagationEnabled = true; + bitStream.ReadBit(bCallPropagationEnabled); // Read custom data // CCustomData* pCustomData = new CCustomData; diff --git a/Client/mods/deathmatch/logic/CPedSync.cpp b/Client/mods/deathmatch/logic/CPedSync.cpp index 59f2a81f6ca..8e8bc8dd84f 100644 --- a/Client/mods/deathmatch/logic/CPedSync.cpp +++ b/Client/mods/deathmatch/logic/CPedSync.cpp @@ -15,7 +15,7 @@ using std::list; extern CClientGame* g_pClientGame; -#define PED_SYNC_RATE ( g_TickRateSettings.iPedSync ) +#define PED_SYNC_RATE (g_TickRateSettings.iPedSync) CPedSync::CPedSync(CClientPedManager* pPedManager) { @@ -124,14 +124,10 @@ void CPedSync::Packet_PedStartSync(NetBitStreamInterface& BitStream) float fHealth, fArmor; BitStream.Read(fHealth); BitStream.Read(fArmor); - - if (BitStream.Can(eBitStreamVersion::PedSync_CameraRotation)) - { - float cameraRotation{}; - BitStream.Read(cameraRotation); - pPed->SetCameraRotation(cameraRotation); - } + float cameraRotation{}; + BitStream.Read(cameraRotation); + pPed->SetCameraRotation(cameraRotation); // Set data pPed->SetPosition(vecPosition); @@ -188,55 +184,32 @@ void CPedSync::Packet_PedSync(NetBitStreamInterface& BitStream) BitStream.Read(ucFlags); std::uint8_t flags2{}; - if (BitStream.Can(eBitStreamVersion::PedSync_CameraRotation)) - BitStream.Read(flags2); + BitStream.Read(flags2); - CVector vecPosition{ CVector::NoInit{} }, vecMoveSpeed{ CVector::NoInit{} }; + CVector vecPosition{CVector::NoInit{}}, vecMoveSpeed{CVector::NoInit{}}; float fRotation, fHealth, fArmor; bool bOnFire; bool bIsInWater; float cameraRotation; - if (BitStream.Can(eBitStreamVersion::PedSync_Revision)) - { - // Read out the position - SPositionSync position(false); - if (ucFlags & 0x01) - BitStream.Read(&position); - - // And rotation - SPedRotationSync rotation; - if (ucFlags & 0x02) - BitStream.Read(&rotation); - - // And the move speed - SVelocitySync velocity; - if (ucFlags & 0x04) - BitStream.Read(&velocity); + // Read out the position + SPositionSync position(false); + if (ucFlags & 0x01) + BitStream.Read(&position); - vecPosition = position.data.vecPosition; - fRotation = rotation.data.fRotation; - vecMoveSpeed = velocity.data.vecVelocity; - } - else - { - if (ucFlags & 0x01) - { - BitStream.Read(vecPosition.fX); - BitStream.Read(vecPosition.fY); - BitStream.Read(vecPosition.fZ); - } + // And rotation + SPedRotationSync rotation; + if (ucFlags & 0x02) + BitStream.Read(&rotation); - if (ucFlags & 0x02) - BitStream.Read(fRotation); + // And the move speed + SVelocitySync velocity; + if (ucFlags & 0x04) + BitStream.Read(&velocity); - if (ucFlags & 0x04) - { - BitStream.Read(vecMoveSpeed.fX); - BitStream.Read(vecMoveSpeed.fY); - BitStream.Read(vecMoveSpeed.fZ); - } - } + vecPosition = position.data.vecPosition; + fRotation = rotation.data.fRotation; + vecMoveSpeed = velocity.data.vecVelocity; // And health with armour if (ucFlags & 0x08) @@ -252,11 +225,11 @@ void CPedSync::Packet_PedSync(NetBitStreamInterface& BitStream) } // And the burning state - if (BitStream.Version() >= 0x04E && ucFlags & 0x20) + if (ucFlags & 0x20) BitStream.ReadBit(bOnFire); // And the in water state - if (BitStream.Version() >= 0x55 && ucFlags & 0x40) + if (ucFlags & 0x40) BitStream.ReadBit(bIsInWater); // Grab the ped. Only update the sync if this packet is from the same context. @@ -275,9 +248,9 @@ void CPedSync::Packet_PedSync(NetBitStreamInterface& BitStream) pPed->LockArmor(fArmor); if (flags2 & 0x01) pPed->SetTargetRotation(PED_SYNC_RATE, std::nullopt, cameraRotation); - if (BitStream.Version() >= 0x04E && ucFlags & 0x20) + if (ucFlags & 0x20) pPed->SetOnFire(bOnFire); - if (BitStream.Version() >= 0x55 && ucFlags & 0x40) + if (ucFlags & 0x40) pPed->SetInWater(bIsInWater); } } @@ -329,13 +302,13 @@ void CPedSync::WritePedInformation(NetBitStreamInterface* pBitStream, CClientPed ucFlags |= 0x20; if (pPed->IsInWater() != pPed->m_LastSyncedData->bIsInWater) ucFlags |= 0x40; - if (pPed->IsReloadingWeapon() != pPed->m_LastSyncedData->isReloadingWeapon && pBitStream->Can(eBitStreamVersion::IsPedReloadingWeapon)) + if (pPed->IsReloadingWeapon() != pPed->m_LastSyncedData->isReloadingWeapon) ucFlags |= 0x60; if (pPed->HasSyncedAnim() && (!pPed->IsRunningAnimation() || pPed->m_animationOverridedByClient)) ucFlags |= 0x80; std::uint8_t flags2{}; - if (!IsNearlyEqual(pPed->GetCameraRotation(), pPed->m_LastSyncedData->cameraRotation) && pBitStream->Can(eBitStreamVersion::PedSync_CameraRotation)) + if (!IsNearlyEqual(pPed->GetCameraRotation(), pPed->m_LastSyncedData->cameraRotation)) flags2 |= 0x01; // Do we really have to sync this ped? @@ -352,38 +325,23 @@ void CPedSync::WritePedInformation(NetBitStreamInterface* pBitStream, CClientPed pBitStream->Write(ucFlags); // Write flags 2 - if (pBitStream->Can(eBitStreamVersion::PedSync_CameraRotation)) - pBitStream->Write(flags2); + pBitStream->Write(flags2); // Write position if needed if (ucFlags & 0x01) { - if (pBitStream->Can(eBitStreamVersion::PedSync_Revision)) - { - SPositionSync position(false); - position.data.vecPosition = vecPosition; - pBitStream->Write(&position); - } - else - { - pBitStream->Write(vecPosition.fX); - pBitStream->Write(vecPosition.fY); - pBitStream->Write(vecPosition.fZ); - } + SPositionSync position(false); + position.data.vecPosition = vecPosition; + pBitStream->Write(&position); pPed->m_LastSyncedData->vPosition = vecPosition; } if (ucFlags & 0x02) { - if (pBitStream->Can(eBitStreamVersion::PedSync_Revision)) - { - SPedRotationSync rotation; - rotation.data.fRotation = pPed->GetCurrentRotation(); - pBitStream->Write(&rotation); - } - else - pBitStream->Write(pPed->GetCurrentRotation()); + SPedRotationSync rotation; + rotation.data.fRotation = pPed->GetCurrentRotation(); + pBitStream->Write(&rotation); pPed->m_LastSyncedData->fRotation = pPed->GetCurrentRotation(); } @@ -391,17 +349,8 @@ void CPedSync::WritePedInformation(NetBitStreamInterface* pBitStream, CClientPed // Write velocity if (ucFlags & 0x04) { - if (pBitStream->Can(eBitStreamVersion::PedSync_Revision)) - { - SVelocitySync velocity; - pBitStream->Write(&velocity); - } - else - { - pBitStream->Write(vecVelocity.fX); - pBitStream->Write(vecVelocity.fY); - pBitStream->Write(vecVelocity.fZ); - } + SVelocitySync velocity; + pBitStream->Write(&velocity); pPed->m_LastSyncedData->vVelocity = vecVelocity; } @@ -427,19 +376,19 @@ void CPedSync::WritePedInformation(NetBitStreamInterface* pBitStream, CClientPed pPed->m_LastSyncedData->cameraRotation = camRotation.data.fRotation; } - if (ucFlags & 0x20 && pBitStream->Version() >= 0x04E) + if (ucFlags & 0x20) { pBitStream->WriteBit(pPed->IsOnFire()); pPed->m_LastSyncedData->bOnFire = pPed->IsOnFire(); } - if (ucFlags & 0x40 && pBitStream->Version() >= 0x55) + if (ucFlags & 0x40) { pBitStream->WriteBit(pPed->IsInWater()); pPed->m_LastSyncedData->bIsInWater = pPed->IsInWater(); } - if (ucFlags & 0x60 && pBitStream->Can(eBitStreamVersion::IsPedReloadingWeapon)) + if (ucFlags & 0x60) { bool isReloadingWeapon = pPed->IsReloadingWeapon(); @@ -448,7 +397,7 @@ void CPedSync::WritePedInformation(NetBitStreamInterface* pBitStream, CClientPed } // The animation has been overwritten or interrupted by the client - if (ucFlags & 0x80 && pBitStream->Can(eBitStreamVersion::AnimationsSync)) + if (ucFlags & 0x80) { pPed->SetHasSyncedAnim(false); pPed->m_animationOverridedByClient = false; diff --git a/Client/mods/deathmatch/logic/CPlayerMap.cpp b/Client/mods/deathmatch/logic/CPlayerMap.cpp index fe089cd23b0..6ee8468c1fb 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.cpp +++ b/Client/mods/deathmatch/logic/CPlayerMap.cpp @@ -77,12 +77,11 @@ CPlayerMap::CPlayerMap(CClientManager* pManager) {colorWhiteTransparent, 0.92f, 1.5f, ""}, {colorWhite, 0.95f, 1.0f, SString(_("Change mode: %s"), *GetBoundKeyName("radar_attach"))}, - {colorWhite, 0.05f, 1.0f, SString(_("Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s"), - *GetBoundKeyName("radar_zoom_in"), *GetBoundKeyName("radar_zoom_out"), *GetBoundKeyName("radar_move_north"), - *GetBoundKeyName("radar_move_east"), *GetBoundKeyName("radar_move_south"), *GetBoundKeyName("radar_move_west"), - *GetBoundKeyName("radar_opacity_down"), *GetBoundKeyName("radar_opacity_up"))}, - {colorWhite, 0.07f, 1.0f, SString(_("Toggle map: %s Toggle help text: %s"), - *GetBoundKeyName("radar"), *GetBoundKeyName("radar_help"))}, + {colorWhite, 0.05f, 1.0f, + SString(_("Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s"), *GetBoundKeyName("radar_zoom_in"), *GetBoundKeyName("radar_zoom_out"), + *GetBoundKeyName("radar_move_north"), *GetBoundKeyName("radar_move_east"), *GetBoundKeyName("radar_move_south"), + *GetBoundKeyName("radar_move_west"), *GetBoundKeyName("radar_opacity_down"), *GetBoundKeyName("radar_opacity_up"))}, + {colorWhite, 0.07f, 1.0f, SString(_("Toggle map: %s Toggle help text: %s"), *GetBoundKeyName("radar"), *GetBoundKeyName("radar_help"))}, }; for (uint i = 0; i < NUMELMS(messageList); i++) @@ -173,6 +172,16 @@ void CPlayerMap::CreateAllTextures() void CPlayerMap::DoPulse() { + const uint uiViewportWidth = g_pCore->GetGraphics()->GetViewportWidth(); + const uint uiViewportHeight = g_pCore->GetGraphics()->GetViewportHeight(); + if (uiViewportWidth > 0 && uiViewportHeight > 0 && (m_bPendingViewportRefresh || m_uiWidth != uiViewportWidth || m_uiHeight != uiViewportHeight)) + { + m_uiWidth = uiViewportWidth; + m_uiHeight = uiViewportHeight; + SetupMapVariables(); + m_bPendingViewportRefresh = false; + } + // If our map image exists if (IsPlayerMapShowing()) { @@ -210,6 +219,19 @@ void CPlayerMap::DoPulse() } } +void CPlayerMap::MarkViewportRefreshPending() +{ + m_bPendingViewportRefresh = true; +} + +void CPlayerMap::ClearMovementFlags() +{ + m_bIsMovingNorth = false; + m_bIsMovingSouth = false; + m_bIsMovingEast = false; + m_bIsMovingWest = false; +} + // // Precreate all the textures for the player map markers // @@ -267,11 +289,11 @@ CTextureItem* CPlayerMap::GetMarkerTexture(CClientRadarMarker* pMarker, float fL pMarker->GetPosition(vecMarker); if (fLocalZ > vecMarker.fZ + 4.0f) - uiListIndex = MARKER_DOWN_TRIANGLE_INDEX; // We're higher than this marker, so draw the arrow pointing down + uiListIndex = MARKER_DOWN_TRIANGLE_INDEX; // We're higher than this marker, so draw the arrow pointing down else if (fLocalZ < vecMarker.fZ - 4.0f) - uiListIndex = MARKER_UP_TRIANGLE_INDEX; // We're lower than this entity, so draw the arrow pointing up + uiListIndex = MARKER_UP_TRIANGLE_INDEX; // We're lower than this entity, so draw the arrow pointing up else - uiListIndex = MARKER_SQUARE_INDEX; // We're at the same level so draw a square + uiListIndex = MARKER_SQUARE_INDEX; // We're at the same level so draw a square fScale /= 4; } @@ -288,10 +310,57 @@ CTextureItem* CPlayerMap::GetMarkerTexture(CClientRadarMarker* pMarker, float fL void CPlayerMap::DoRender() { bool isMapShowing = IsPlayerMapShowing(); + if (isMapShowing) + { + g_pCore->GetGraphics()->RefreshViewportIfNeeded(); + if (!g_pCore->GetGraphics()->GetRenderItemManager()->IsUsingDefaultRenderTarget()) + { + g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); + } + g_pCore->GetGraphics()->ApplyMTARenderViewportIfNeeded(); + const uint uiViewportWidth = g_pCore->GetGraphics()->GetViewportWidth(); + const uint uiViewportHeight = g_pCore->GetGraphics()->GetViewportHeight(); + if (uiViewportWidth > 0 && uiViewportHeight > 0 && (m_bPendingViewportRefresh || m_uiWidth != uiViewportWidth || m_uiHeight != uiViewportHeight)) + { + m_uiWidth = uiViewportWidth; + m_uiHeight = uiViewportHeight; + SetupMapVariables(); + m_bPendingViewportRefresh = false; + } + } // Render if showing and textures are all loaded if (isMapShowing && !m_failedToLoadTextures) { + IDirect3DDevice9* pDevice = g_pCore->GetGraphics()->GetDevice(); + D3DVIEWPORT9 prevViewport = {}; + RECT prevScissor = {}; + DWORD prevScissorEnable = FALSE; + bool restoreViewport = false; + bool restoreScissor = false; + + if (pDevice && m_uiWidth > 0 && m_uiHeight > 0) + { + if (SUCCEEDED(pDevice->GetViewport(&prevViewport))) + restoreViewport = true; + if (SUCCEEDED(pDevice->GetScissorRect(&prevScissor))) + restoreScissor = true; + pDevice->GetRenderState(D3DRS_SCISSORTESTENABLE, &prevScissorEnable); + + D3DVIEWPORT9 viewport = {}; + viewport.X = 0; + viewport.Y = 0; + viewport.Width = m_uiWidth; + viewport.Height = m_uiHeight; + viewport.MinZ = 0.0f; + viewport.MaxZ = 1.0f; + pDevice->SetViewport(&viewport); + + RECT fullRect = {0, 0, static_cast(m_uiWidth), static_cast(m_uiHeight)}; + pDevice->SetScissorRect(&fullRect); + pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); + } + // Get the alpha value from the settings int mapAlpha; g_pCore->GetCVars()->Get("mapalpha", mapAlpha); @@ -383,6 +452,15 @@ void CPlayerMap::DoRender() } g_pCore->GetGraphics()->DrawTexture(m_playerMarkerTexture, vecLocalPos.fX, vecLocalPos.fY, 1.0, 1.0, vecLocalRot.fZ, 0.5f, 0.5f); + + if (pDevice) + { + if (restoreViewport) + pDevice->SetViewport(&prevViewport); + if (restoreScissor) + pDevice->SetScissorRect(&prevScissor); + pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, prevScissorEnable); + } } // Update visibility of help text @@ -718,7 +796,8 @@ void CPlayerMap::SetAttachedToLocalPlayer(bool bIsAttachedToLocal) bool CPlayerMap::IsPlayerMapShowing() { - return ((m_bIsPlayerMapEnabled || m_bForcedState) && m_mapImageTexture && m_playerMarkerTexture && (!g_pCore->GetConsole()->IsVisible() && !g_pCore->IsMenuVisible())); + return ((m_bIsPlayerMapEnabled || m_bForcedState) && m_mapImageTexture && m_playerMarkerTexture && + (!g_pCore->GetConsole()->IsVisible() && !g_pCore->IsMenuVisible())); } bool CPlayerMap::GetBoundingBox(CVector& vecMin, CVector& vecMax) diff --git a/Client/mods/deathmatch/logic/CPlayerMap.h b/Client/mods/deathmatch/logic/CPlayerMap.h index d03f40892e0..f88076310ab 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.h +++ b/Client/mods/deathmatch/logic/CPlayerMap.h @@ -36,6 +36,8 @@ class CPlayerMap bool GetBoundingBox(CVector& vecMin, CVector& vecMax); void ToggleHelpText(); + void MarkViewportRefreshPending(); + void ClearMovementFlags(); protected: void InternalSetPlayerMapEnabled(bool bEnabled); @@ -117,7 +119,7 @@ class CPlayerMap unsigned long m_ulUpdateTime; std::vector> m_HelpTextList; - bool m_bHideHelpText; + bool m_bHideHelpText; bool m_bHudVisible; bool m_bChatVisible; @@ -125,4 +127,5 @@ class CPlayerMap bool m_bRadarVisible; bool m_bDebugVisible; bool m_bTextVisible; + bool m_bPendingViewportRefresh = false; }; diff --git a/Client/mods/deathmatch/logic/CRegisteredCommands.cpp b/Client/mods/deathmatch/logic/CRegisteredCommands.cpp index 4faa169071e..5119e5e2245 100644 --- a/Client/mods/deathmatch/logic/CRegisteredCommands.cpp +++ b/Client/mods/deathmatch/logic/CRegisteredCommands.cpp @@ -9,6 +9,7 @@ *****************************************************************************/ #include "StdInc.h" +#include "CClientGame.h" using std::list; @@ -27,6 +28,27 @@ bool CRegisteredCommands::AddCommand(CLuaMain* pLuaMain, const char* szKey, cons assert(pLuaMain); assert(szKey); + if (CommandExists(szKey, nullptr)) + { + const MultiCommandHandlerPolicy allowMultiHandlers = g_pClientGame->GetAllowMultiCommandHandlers(); + + switch (allowMultiHandlers) + { + case MultiCommandHandlerPolicy::BLOCK: + g_pClientGame->GetScriptDebugging()->LogError( + pLuaMain->GetVM(), "addCommandHandler: Duplicate command registration blocked for '%s' (multiple handlers disabled)", szKey); + return false; + + case MultiCommandHandlerPolicy::WARN: + g_pClientGame->GetScriptDebugging()->LogWarning(pLuaMain->GetVM(), "addCommandHandler: Attempt to register duplicate command '%s'", szKey); + break; + + case MultiCommandHandlerPolicy::ALLOW: + default: + break; + } + } + // Check if we already have this key and handler SCommand* pCommand = GetCommand(szKey, pLuaMain); if (pCommand) @@ -126,7 +148,7 @@ bool CRegisteredCommands::CommandExists(const char* szKey, CLuaMain* pLuaMain) { assert(szKey); - return GetCommand(szKey, pLuaMain) != NULL; + return GetCommand(szKey, pLuaMain) != nullptr; } bool CRegisteredCommands::ProcessCommand(const char* szKey, const char* szArguments) @@ -183,7 +205,7 @@ CRegisteredCommands::SCommand* CRegisteredCommands::GetCommand(const char* szKey } // Doesn't exist - return NULL; + return nullptr; } void CRegisteredCommands::CallCommandHandler(CLuaMain* pLuaMain, const CLuaFunctionRef& iLuaFunction, const char* szKey, const char* szArguments) @@ -204,7 +226,7 @@ void CRegisteredCommands::CallCommandHandler(CLuaMain* pLuaMain, const CLuaFunct while (arg) { Arguments.PushString(arg); - arg = strtok(NULL, " "); + arg = strtok(nullptr, " "); } delete[] szTempArguments; } diff --git a/Client/mods/deathmatch/logic/CRegisteredCommands.h b/Client/mods/deathmatch/logic/CRegisteredCommands.h index 5583e8d1d16..612f1d75da9 100644 --- a/Client/mods/deathmatch/logic/CRegisteredCommands.h +++ b/Client/mods/deathmatch/logic/CRegisteredCommands.h @@ -10,12 +10,20 @@ #pragma once +#include #include #include -#define MAX_REGISTERED_COMMAND_LENGTH 64 +#define MAX_REGISTERED_COMMAND_LENGTH 64 #define MAX_REGISTERED_COMMANDHANDLER_LENGTH 64 +enum class MultiCommandHandlerPolicy : std::uint8_t +{ + BLOCK = 0, + WARN = 1, + ALLOW = 2 +}; + class CRegisteredCommands { struct SCommand diff --git a/Client/mods/deathmatch/logic/CRemoteCalls.cpp b/Client/mods/deathmatch/logic/CRemoteCalls.cpp index ec07e2db199..e105a91910a 100644 --- a/Client/mods/deathmatch/logic/CRemoteCalls.cpp +++ b/Client/mods/deathmatch/logic/CRemoteCalls.cpp @@ -17,7 +17,7 @@ CRemoteCalls::CRemoteCalls() CRemoteCalls::~CRemoteCalls() { - for (auto pRemoteCall : m_calls) + for (auto* pRemoteCall : m_calls) { delete pRemoteCall; } @@ -38,7 +38,7 @@ CRemoteCall* CRemoteCalls::Call(const char* szURL, CLuaArguments* fetchArguments void CRemoteCalls::OnLuaMainDestroy(CLuaMain* lua) { - for (auto pRemoteCall : m_calls) + for (auto* pRemoteCall : m_calls) { if (pRemoteCall->GetVM() == lua) { @@ -146,12 +146,23 @@ void CRemoteCall::MakeCall() { m_iStartTime = GetTickCount64_(); - // GetDomainFromURL requires protocol://, but curl does not (defaults to http) - SString strDomain = g_pCore->GetWebCore()->GetDomainFromURL(m_strURL); - if (strDomain.empty()) - strDomain = g_pCore->GetWebCore()->GetDomainFromURL("https://" + m_strURL); - // Bypass net module IP check if we are allowed to access the URL - bool bAnyHost = (g_pCore->GetWebCore()->GetDomainState(strDomain) == eURLState::WEBPAGE_ALLOWED); + const auto pWebCore = g_pCore->GetWebCore(); + bool bAnyHost = false; + + if (pWebCore) + { + // GetDomainFromURL requires protocol:// + const SString strDomain = [&]() + { + SString domain = pWebCore->GetDomainFromURL(m_strURL); + if (domain.empty()) + domain = pWebCore->GetDomainFromURL("https://" + m_strURL); + return domain; + }(); + // Bypass net module IP check if allowed to access the URL + bAnyHost = (pWebCore->GetDomainState(strDomain) == eURLState::WEBPAGE_ALLOWED); + } + m_downloadMode = g_pClientGame->GetRemoteCalls()->GetDownloadModeForQueueName(m_strQueueName, bAnyHost); CNetHTTPDownloadManagerInterface* pDownloadManager = g_pNet->GetHTTPDownloadManager(m_downloadMode); pDownloadManager->QueueFile(m_strURL, NULL, this, DownloadFinishedCallback, m_options); diff --git a/Client/mods/deathmatch/logic/CResource.cpp b/Client/mods/deathmatch/logic/CResource.cpp index 663b6208a77..7a94259a682 100644 --- a/Client/mods/deathmatch/logic/CResource.cpp +++ b/Client/mods/deathmatch/logic/CResource.cpp @@ -14,6 +14,8 @@ #include "profiler/SharedUtil.Profiler.h" #include "CServerIdManager.h" +#include + using namespace std; extern CClientGame* g_pClientGame; @@ -39,7 +41,7 @@ CResource::CResource(unsigned short usNetID, const char* szResourceName, CClient m_pLuaManager = g_pClientGame->GetLuaManager(); m_pRootEntity = g_pClientGame->GetRootEntity(); - m_pDefaultElementGroup = new CElementGroup(); // for use by scripts + m_pDefaultElementGroup = new CElementGroup(); // for use by scripts m_pResourceEntity = pResourceEntity; m_pResourceDynamicEntity = pResourceDynamicEntity; @@ -114,7 +116,23 @@ CResource::~CResource() // Remove all keybinds on this VM g_pClientGame->GetScriptKeyBinds()->RemoveAllKeys(m_pLuaVM); - g_pCore->GetKeyBinds()->SetAllCommandsActive(m_strResourceName, false); + + // Remove all resource-specific command bindings while preserving user bindings + CKeyBindsInterface* pKeyBinds = g_pCore->GetKeyBinds(); + pKeyBinds->SetAllCommandsActive(m_strResourceName, false); + + // Additional cleanup: remove any remaining resource bindings that weren't caught by SetAllCommandsActive + for (auto& bind : *pKeyBinds) + { + if (bind->type == KeyBindType::COMMAND) + { + auto commandBind = static_cast(bind.get()); + if (commandBind->context == BindingContext::RESOURCE && commandBind->resource == m_strResourceName) + { + pKeyBinds->Remove(commandBind); + } + } + } // Destroy the txd root so all dff elements are deleted except those moved out g_pClientGame->GetElementDeleter()->DeleteRecursive(m_pResourceTXDRoot); @@ -220,9 +238,50 @@ bool CResource::CallExportedFunction(const SString& name, CLuaArguments& args, C return false; } +bool CResource::VerifyPendingClientChecksums() +{ + bool bQueuedDownload = false; + + const auto queueDownloadForMismatch = [&bQueuedDownload](CDownloadableResource* pDownloadableResource) + { + if (!pDownloadableResource->IsAutoDownload() || pDownloadableResource->IsWaitingForDownload() || pDownloadableResource->HasVerifiedClientChecksum()) + return; + + const CChecksum clientChecksum = pDownloadableResource->GenerateClientChecksum(); + if (clientChecksum == pDownloadableResource->GetServerChecksum()) + return; + + const SString strName = pDownloadableResource->GetName(); + FileDelete(strName); + if (FileExists(strName)) + { + SString strMessage("Unable to delete old file %s", *ConformResourcePath(strName)); + g_pClientGame->TellServerSomethingImportant(1009, strMessage); + } + + MakeSureDirExists(strName); + g_pClientGame->GetResourceFileDownloadManager()->AddPendingFileDownload(pDownloadableResource); + bQueuedDownload = true; + }; + + for (CResourceConfigItem* pConfigFile : m_ConfigFiles) + queueDownloadForMismatch(pConfigFile); + + for (CResourceFile* pResourceFile : m_ResourceFiles) + queueDownloadForMismatch(pResourceFile); + + return bQueuedDownload; +} + bool CResource::CanBeLoaded() { - return !IsActive() && !IsWaitingForInitialDownloads(); + if (IsActive() || IsWaitingForInitialDownloads()) + return false; + + if (VerifyPendingClientChecksums()) + return false; + + return !IsWaitingForInitialDownloads(); } bool CResource::IsWaitingForInitialDownloads() @@ -258,7 +317,7 @@ void CResource::Load() m_pResourceTXDRoot->SetParent(m_pResourceEntity); } - CLogger::LogPrintf("> Starting resource '%s'", *m_strResourceName); + CLogger::LogPrintf("> Starting resource '%s'\n", *m_strResourceName); // Flag resource files as readable for (std::list::iterator iter = m_ConfigFiles.begin(); iter != m_ConfigFiles.end(); ++iter) @@ -299,25 +358,31 @@ void CResource::Load() { // Load the file std::vector buffer; - FileLoad(pResourceFile->GetName(), buffer); - const char* pBufferData = buffer.empty() ? nullptr : &buffer.at(0); + const bool bLoaded = FileLoad(pResourceFile->GetName(), buffer); + const char* pBufferData = buffer.empty() ? nullptr : &buffer.at(0); DECLARE_PROFILER_SECTION(OnPreLoadScript) // Check the contents - if (CChecksum::GenerateChecksumFromBuffer(pBufferData, buffer.size()) == pResourceFile->GetServerChecksum()) + if (bLoaded) { - m_pLuaVM->LoadScriptFromBuffer(pBufferData, buffer.size(), pResourceFile->GetName()); + const CChecksum checksum = CChecksum::GenerateChecksumFromBuffer(pBufferData, buffer.size()); + pResourceFile->SetLastClientChecksum(checksum); + + if (checksum == pResourceFile->GetServerChecksum()) + m_pLuaVM->LoadScriptFromBuffer(pBufferData, buffer.size(), pResourceFile->GetName()); + else + HandleDownloadedFileTrouble(pResourceFile, true); } else { + pResourceFile->SetLastClientChecksum(CChecksum()); HandleDownloadedFileTrouble(pResourceFile, true); } DECLARE_PROFILER_SECTION(OnPostLoadScript) } else if (pResourceFile->IsAutoDownload()) { - // Check the file contents - if (CChecksum::GenerateChecksumFromFileUnsafe(pResourceFile->GetName()) != pResourceFile->GetServerChecksum()) + if (!pResourceFile->DoesClientAndServerChecksumMatch()) { HandleDownloadedFileTrouble(pResourceFile, false); } @@ -339,14 +404,10 @@ void CResource::Load() NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); if (pBitStream) { - if (pBitStream->Can(eBitStreamVersion::OnPlayerResourceStart)) - { - // Write resource net ID - pBitStream->Write(GetNetID()); - - g_pNet->SendPacket(PACKET_ID_PLAYER_RESOURCE_START, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - } - + // Write resource net ID + pBitStream->Write(GetNetID()); + pBitStream->Write(GetStartCounter()); + g_pNet->SendPacket(PACKET_ID_PLAYER_RESOURCE_START, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); g_pNet->DeallocateNetBitStream(pBitStream); } } @@ -370,7 +431,16 @@ void CResource::Stop() { discord->ResetDiscordData(); discord->SetPresenceState(_("In-game"), false); - discord->SetPresenceStartTimestamp(time(nullptr)); + const time_t now = time(nullptr); + unsigned long startTimestamp = 0; + if (now > 0) + { + const auto maxValue = std::numeric_limits::max(); + const auto nowUnsigned = static_cast(now); + startTimestamp = (nowUnsigned > maxValue) ? maxValue : static_cast(now); + } + + discord->SetPresenceStartTimestamp(startTimestamp); discord->UpdatePresence(); } } @@ -414,11 +484,11 @@ void CResource::ShowCursor(bool bShow, bool bToggleControls) // Update our showing cursor state m_bShowingCursor = bShow; - - // Show cursor if more than 0 resources wanting the cursor on - g_pCore->ForceCursorVisible(m_iShowingCursor > 0, bToggleControls); - g_pClientGame->SetCursorEventsEnabled(m_iShowingCursor > 0); } + + // Always update cursor and controls state regardless of cursor visibility change + g_pCore->ForceCursorVisible(m_iShowingCursor > 0, bToggleControls); + g_pClientGame->SetCursorEventsEnabled(m_iShowingCursor > 0); } SString CResource::GetResourceDirectoryPath(eAccessType accessType, const SString& strMetaPath) @@ -502,20 +572,23 @@ void CResource::AddToElementGroup(CClientEntity* pElement) // void CResource::HandleDownloadedFileTrouble(CResourceFile* pResourceFile, bool bScript) { - auto checksumResult = CChecksum::GenerateChecksumFromFile(pResourceFile->GetName()); - SString errorMessage; - if (std::holds_alternative(checksumResult)) - errorMessage = std::get(checksumResult); + + CChecksum clientChecksum = pResourceFile->GetLastClientChecksum(); + if (!pResourceFile->HasVerifiedClientChecksum()) + { + errorMessage = "Client checksum was not verified before load"; + } + else if (clientChecksum == CChecksum()) + { + errorMessage = SString("File not readable: %s", pResourceFile->GetName()); + } else { - CChecksum checksum = std::get(checksumResult); - - // Compose message - uint uiGotFileSize = (uint)FileSize(pResourceFile->GetName()); - SString strGotMd5 = ConvertDataToHexString(checksum.md5.data, sizeof(MD5)); + SString strGotMd5 = ConvertDataToHexString(clientChecksum.md5.data, sizeof(MD5)); SString strWantedMd5 = ConvertDataToHexString(pResourceFile->GetServerChecksum().md5.data, sizeof(MD5)); - errorMessage = SString("Got size:%d MD5:%s, wanted MD5:%s", uiGotFileSize, *strGotMd5, *strWantedMd5); + errorMessage = + SString("Got CRC:%08lX MD5:%s, wanted CRC:%08lX MD5:%s", clientChecksum.ulCRC, *strGotMd5, pResourceFile->GetServerChecksum().ulCRC, *strWantedMd5); } SString strFilename = ExtractFilename(PathConform(pResourceFile->GetShortName())); diff --git a/Client/mods/deathmatch/logic/CResource.h b/Client/mods/deathmatch/logic/CResource.h index 5c1ef2af273..7f129c19211 100644 --- a/Client/mods/deathmatch/logic/CResource.h +++ b/Client/mods/deathmatch/logic/CResource.h @@ -19,8 +19,8 @@ #include "CElementGroup.h" #include -#define MAX_RESOURCE_NAME_LENGTH 255 -#define MAX_FUNCTION_NAME_LENGTH 50 +#define MAX_RESOURCE_NAME_LENGTH 255 +#define MAX_FUNCTION_NAME_LENGTH 50 struct SNoClientCacheScript { @@ -110,9 +110,13 @@ class CResource int GetDownloadPriorityGroup() { return m_iDownloadPriorityGroup; } void SetDownloadPriorityGroup(int iDownloadPriorityGroup) { m_iDownloadPriorityGroup = iDownloadPriorityGroup; } + void SetStartCounter(unsigned int startCounter) { m_startCounter = startCounter; } + unsigned int GetStartCounter() const noexcept { return m_startCounter; } + private: unsigned short m_usNetID; uint m_uiScriptID; + unsigned int m_startCounter{}; SString m_strResourceName; CLuaMain* m_pLuaVM; CLuaManager* m_pLuaManager; @@ -120,8 +124,8 @@ class CResource bool m_bActive; bool m_bStarting; bool m_bStopping; - class CClientEntity* m_pResourceEntity; // no idea what this is used for anymore - class CClientEntity* m_pResourceDynamicEntity; // parent of elements created by the resource + class CClientEntity* m_pResourceEntity; // no idea what this is used for anymore + class CClientEntity* m_pResourceDynamicEntity; // parent of elements created by the resource class CClientEntity* m_pResourceCOLRoot; class CClientEntity* m_pResourceDFFEntity; class CClientEntity* m_pResourceGUIEntity; @@ -139,15 +143,17 @@ class CResource static int m_iShowingCursor; bool m_bShowingCursor; - SString m_strResourceDirectoryPath; // stores the path to /mods/deathmatch/resources/resource_name - SString m_strResourcePrivateDirectoryPath; // stores the path to /mods/deathmatch/priv/server-id/resource_name - SString m_strResourcePrivateDirectoryPathOld; // stores the path to /mods/deathmatch/priv/old-server-id/resource_name + SString m_strResourceDirectoryPath; // stores the path to /mods/deathmatch/resources/resource_name + SString m_strResourcePrivateDirectoryPath; // stores the path to /mods/deathmatch/priv/server-id/resource_name + SString m_strResourcePrivateDirectoryPathOld; // stores the path to /mods/deathmatch/priv/old-server-id/resource_name std::list m_ResourceFiles; std::list m_ConfigFiles; CFastHashSet m_exportedFunctions; - CElementGroup* m_pDefaultElementGroup; // stores elements created by scripts in this resource + CElementGroup* m_pDefaultElementGroup; // stores elements created by scripts in this resource std::list m_NoClientCacheScriptList; CResourceModelStreamer m_modelStreamer{}; + + bool VerifyPendingClientChecksums(); }; diff --git a/Client/mods/deathmatch/logic/CResourceConfigItem.cpp b/Client/mods/deathmatch/logic/CResourceConfigItem.cpp index d68bd1a53b0..22de1f3fd6f 100644 --- a/Client/mods/deathmatch/logic/CResourceConfigItem.cpp +++ b/Client/mods/deathmatch/logic/CResourceConfigItem.cpp @@ -91,4 +91,4 @@ bool CResourceConfigItem::Stop() } return true; -} \ No newline at end of file +} diff --git a/Client/mods/deathmatch/logic/CResourceConfigItem.h b/Client/mods/deathmatch/logic/CResourceConfigItem.h index 1d9dcbc22d5..c53ea708163 100644 --- a/Client/mods/deathmatch/logic/CResourceConfigItem.h +++ b/Client/mods/deathmatch/logic/CResourceConfigItem.h @@ -16,7 +16,7 @@ #include #ifndef MAX_PATH -#define MAX_PATH 260 + #define MAX_PATH 260 #endif class CResourceConfigItem : public CDownloadableResource diff --git a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp index f10ef66ed2f..1bf97bb22ad 100644 --- a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp +++ b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp @@ -142,7 +142,7 @@ void CResourceFileDownloadManager::DoPulse() AddReportLog(7106, SString("Game - HTTPError (%s)", *m_strLastHTTPError)); g_pCore->GetModManager()->RequestUnload(); - g_pCore->ShowMessageBox(_("Error") + _E("CD20"), *m_strLastHTTPError, MB_BUTTON_OK | MB_ICON_ERROR); // HTTP Error + g_pCore->ShowMessageBox(_("Error") + _E("CD20"), *m_strLastHTTPError, MB_BUTTON_OK | MB_ICON_ERROR); // HTTP Error m_bIsTransferingFiles = false; return; } @@ -309,7 +309,8 @@ void CResourceFileDownloadManager::DownloadFinished(const SHttpDownloadResult& r if (result.bSuccess) { - CChecksum checksum = CChecksum::GenerateChecksumFromFileUnsafe(pResourceFile->GetName()); + CDownloadableResource::EndChecksumBatch(); + CChecksum checksum = pResourceFile->GenerateClientChecksum(); if (checksum != pResourceFile->GetServerChecksum()) { // Checksum failed - Try download on next server diff --git a/Client/mods/deathmatch/logic/CResourceManager.cpp b/Client/mods/deathmatch/logic/CResourceManager.cpp index 9d0b55d3e08..c485dcfea92 100644 --- a/Client/mods/deathmatch/logic/CResourceManager.cpp +++ b/Client/mods/deathmatch/logic/CResourceManager.cpp @@ -10,6 +10,7 @@ *****************************************************************************/ #include "StdInc.h" +#include "CChecksum.h" using std::list; @@ -19,6 +20,8 @@ CResourceManager::CResourceManager() CResourceManager::~CResourceManager() { + CChecksum::ClearChecksumCache(); + while (!m_resources.empty()) { CResource* pResource = m_resources.back(); @@ -57,7 +60,7 @@ CResource* CResourceManager::GetResourceFromNetID(unsigned short usNetID) { if ((*iter)->GetNetID() == usNetID) { - assert(0); // Should be in map + assert(0); // Should be in map return (*iter); } } @@ -99,15 +102,26 @@ CResource* CResourceManager::GetResource(const char* szResourceName) void CResourceManager::OnDownloadGroupFinished() { + CDownloadableResource::EndChecksumBatch(); + // Try to load newly ready resources for (std::list::const_iterator iter = m_resources.begin(); iter != m_resources.end(); ++iter) { CResource* pResource = *iter; if (!pResource->IsActive()) { - // Stop as soon as we hit a resource which hasn't downloaded yet (as per previous behaviour) + if (!pResource->CanBeLoaded()) + { + // Stop as soon as we hit a resource which hasn't downloaded yet (as per previous behaviour) + if (pResource->IsWaitingForInitialDownloads()) + break; + + continue; + } + if (pResource->IsWaitingForInitialDownloads()) break; + pResource->Load(); } } @@ -241,8 +255,6 @@ void CResourceManager::OnFileModifedByScript(const SString& strInFilename, const if (pResourceFile && !pResourceFile->IsModifedByScript()) { pResourceFile->SetModifedByScript(true); - SString strMessage("Resource file modifed by script (%s): %s ", *strReason, *ConformResourcePath(strInFilename)); - AddReportLog(7059, strMessage + g_pNet->GetConnectedServer(true), 10); } } @@ -272,8 +284,9 @@ void CResourceManager::ValidateResourceFile(const SString& strInFilename, const CMD5Hasher::ConvertToHex(checksum.md5, szMd5); char szMd5Wanted[33]; CMD5Hasher::ConvertToHex(pResourceFile->GetServerChecksum().md5, szMd5Wanted); - SString strMessage("%s [Expected Size:%d MD5:%s][Got Size:%d MD5:%s] ", *ConformResourcePath(strInFilename), pResourceFile->GetDownloadSize(), - szMd5Wanted, (int)FileSize(strInFilename), szMd5); + const int iGotSize = buffer ? static_cast(bufferSize) : static_cast(FileSize(strInFilename)); + SString strMessage("%s [Expected Size:%d CRC:%08lX MD5:%s][Got Size:%d CRC:%08lX MD5:%s] ", *ConformResourcePath(strInFilename), + pResourceFile->GetDownloadSize(), pResourceFile->GetServerChecksum().ulCRC, szMd5Wanted, iGotSize, checksum.ulCRC, szMd5); if (pResourceFile->IsDownloaded()) { strMessage = "Resource file unexpected change: " + strMessage; diff --git a/Client/mods/deathmatch/logic/CResourceManager.h b/Client/mods/deathmatch/logic/CResourceManager.h index d79bff256d7..39a1b4601d4 100644 --- a/Client/mods/deathmatch/logic/CResourceManager.h +++ b/Client/mods/deathmatch/logic/CResourceManager.h @@ -39,6 +39,9 @@ class CResourceManager CResource* GetResourceFromLuaState(struct lua_State* luaVM); SString GetResourceName(struct lua_State* luaVM); + std::list::const_iterator IterBegin() { return m_resources.begin(); }; + std::list::const_iterator IterEnd() { return m_resources.end(); }; + bool RemoveResource(unsigned short usID); void Remove(CResource* pResource); bool Exists(CResource* pResource); @@ -54,7 +57,8 @@ class CResourceManager void ValidateResourceFile(const SString& strFilename, const char* buffer, size_t bufferSize); CDownloadableResource* GetDownloadableResourceFile(const SString& strFilename) { return MapFindRef(m_ResourceFileMap, strFilename); } - static bool ParseResourcePathInput(std::string strInput, CResource*& pResource, std::string* pStrPath, std::string* pStrMetaPath = nullptr, bool bPassSize = false); + static bool ParseResourcePathInput(std::string strInput, CResource*& pResource, std::string* pStrPath, std::string* pStrMetaPath = nullptr, + bool bPassSize = false); private: CMappedList m_resources; diff --git a/Client/mods/deathmatch/logic/CResourceModelStreamer.cpp b/Client/mods/deathmatch/logic/CResourceModelStreamer.cpp index c6c2eb30d1d..4b309634c4f 100644 --- a/Client/mods/deathmatch/logic/CResourceModelStreamer.cpp +++ b/Client/mods/deathmatch/logic/CResourceModelStreamer.cpp @@ -28,21 +28,16 @@ bool CResourceModelStreamer::RequestModel(std::uint16_t modelId, bool addRef, bo if (refsCount == 1) { model->ModelAddRef(blocking ? EModelRequestType::BLOCKING : EModelRequestType::NON_BLOCKING, "CResourceModelStreamer::RequestModel With reference"); - return true; } - return false; + return true; } else { if (model->IsLoaded()) - { - return false; - } - else - { - model->Request(blocking ? EModelRequestType::BLOCKING : EModelRequestType::NON_BLOCKING, "CResourceModelStreamer::RequestModel With out reference"); return true; - } + + model->Request(blocking ? EModelRequestType::BLOCKING : EModelRequestType::NON_BLOCKING, "CResourceModelStreamer::RequestModel With out reference"); + return true; } } @@ -92,7 +87,7 @@ bool CResourceModelStreamer::ReleaseModel(std::uint16_t modelId, bool removeRef) void CResourceModelStreamer::ReleaseAll() { - for (const auto &modelRefs : m_requestedModels) + for (const auto& modelRefs : m_requestedModels) { if (modelRefs.second > 0) { @@ -121,6 +116,9 @@ void CResourceModelStreamer::FullyReleaseModel(std::uint16_t modelId) if (!model) return; - model->RemoveRef(); + // Pass true to also decrement GTA's usNumberOfRefs which was incremented + // by ModelAddRef() when the model was first requested. Without this, + // DeallocateModel() will be blocked due to orphaned GTA-side refs. + model->RemoveRef(true); } } diff --git a/Client/mods/deathmatch/logic/CScriptDebugging.cpp b/Client/mods/deathmatch/logic/CScriptDebugging.cpp index 4af67b15244..854b1651b3c 100644 --- a/Client/mods/deathmatch/logic/CScriptDebugging.cpp +++ b/Client/mods/deathmatch/logic/CScriptDebugging.cpp @@ -16,9 +16,9 @@ CScriptDebugging::CScriptDebugging(CLuaManager* pLuaManager) { m_pLuaManager = pLuaManager; m_uiLogFileLevel = 0; - m_pLogFile = NULL; + m_pLogFile = nullptr; m_bTriggeringMessageEvent = false; - m_flushTimerHandle = NULL; + m_flushTimerHandle = nullptr; } CScriptDebugging::~CScriptDebugging() @@ -33,13 +33,13 @@ CScriptDebugging::~CScriptDebugging() fprintf(m_pLogFile, "INFO: Logging to this file ended\n"); // if we have a flush timer - if (m_flushTimerHandle != NULL) + if (m_flushTimerHandle) { // delete our flush timer - DeleteTimerQueueTimer(NULL, m_flushTimerHandle, INVALID_HANDLE_VALUE); // INVALID_HANDLE_VALUE = wait for running callbacks to finish + DeleteTimerQueueTimer(nullptr, m_flushTimerHandle, INVALID_HANDLE_VALUE); // INVALID_HANDLE_VALUE = wait for running callbacks to finish } fclose(m_pLogFile); - m_pLogFile = NULL; + m_pLogFile = nullptr; } } @@ -52,7 +52,7 @@ void CScriptDebugging::LogBadLevel(lua_State* luaVM, unsigned int uiRequiredLeve void CALLBACK TimerProc(void* lpParametar, BOOLEAN TimerOrWaitFired) { // Got a logfile? - if (CScriptDebugging::m_pLogFile != NULL) + if (CScriptDebugging::m_pLogFile) { // flush our log file fflush((FILE*)CScriptDebugging::m_pLogFile); @@ -68,13 +68,13 @@ bool CScriptDebugging::SetLogfile(const char* szFilename, unsigned int uiLevel) { fprintf(m_pLogFile, "INFO: Logging to this file ended\n"); // if we have a flush timer - if (m_flushTimerHandle != NULL) + if (m_flushTimerHandle) { // delete our flush timer - DeleteTimerQueueTimer(NULL, m_flushTimerHandle, INVALID_HANDLE_VALUE); // INVALID_HANDLE_VALUE = wait for running callbacks to finish + DeleteTimerQueueTimer(nullptr, m_flushTimerHandle, INVALID_HANDLE_VALUE); // INVALID_HANDLE_VALUE = wait for running callbacks to finish } fclose(m_pLogFile); - m_pLogFile = NULL; + m_pLogFile = nullptr; } // Apply log size limit @@ -102,15 +102,14 @@ bool CScriptDebugging::SetLogfile(const char* szFilename, unsigned int uiLevel) // round 37.5 to 38 because we can't have half a message // 8 * 256 bytes = 6004B // round 6004 up to the nearest divisible by 1024 = 6144 - // we have our buffer size. - setvbuf(pFile, NULL, _IOFBF, 6144); + setvbuf(pFile, nullptr, _IOFBF, 6144); // Set the new pointer and level and return true m_uiLogFileLevel = uiLevel; m_pLogFile = pFile; // Create a timer - ::CreateTimerQueueTimer(&m_flushTimerHandle, NULL, TimerProc, NULL, 50, 50, WT_EXECUTEINTIMERTHREAD); + ::CreateTimerQueueTimer(&m_flushTimerHandle, nullptr, TimerProc, nullptr, 50, 50, WT_EXECUTEINTIMERTHREAD); return true; } @@ -123,17 +122,27 @@ void CScriptDebugging::UpdateLogOutput() while (m_DuplicateLineFilter.PopOutputLine(line)) { // Log it to the file if enough level - bool sufficientDebugLevel = CheckForSufficientDebugLevel(m_uiLogFileLevel, line.uiMinimumDebugLevel); + bool sufficientDebugLevel = + CheckForSufficientDebugLevel(static_cast(m_uiLogFileLevel), static_cast(line.uiMinimumDebugLevel)); if (sufficientDebugLevel) { PrintLog(line.strText); } - #ifdef MTA_DEBUG + +#ifdef MTA_DEBUG if (!g_pCore->IsDebugVisible()) return; - #endif - g_pCore->DebugEchoColor(line.strText, line.ucRed, line.ucGreen, line.ucBlue); +#endif + + std::uint8_t clientDebugLevel = 0; + auto* localPlayer = g_pClientGame->GetPlayerManager()->GetLocalPlayer(); + if (localPlayer) + clientDebugLevel = localPlayer->GetPlayerScriptDebugLevel(); + + bool shouldDisplayInConsole = CheckForSufficientDebugLevel(clientDebugLevel, static_cast(line.uiMinimumDebugLevel)); + if (shouldDisplayInConsole) + g_pCore->DebugEchoColor(line.strText, line.ucRed, line.ucGreen, line.ucBlue); } } diff --git a/Client/mods/deathmatch/logic/CScriptDebugging.h b/Client/mods/deathmatch/logic/CScriptDebugging.h index 48b41b606ac..961e9e41d8c 100644 --- a/Client/mods/deathmatch/logic/CScriptDebugging.h +++ b/Client/mods/deathmatch/logic/CScriptDebugging.h @@ -68,8 +68,8 @@ class CScriptDebugging SString ComposeErrorMessage(const char* szPrePend, const SLuaDebugInfo& luaDebugInfo, const char* szMessage); void LogString(const char* szPrePend, const SLuaDebugInfo& luaDebugInfo, const char* szMessage, unsigned int uiMinimumDebugLevel, unsigned char ucRed = 255, unsigned char ucGreen = 255, unsigned char ucBlue = 255); - bool CheckForSufficientDebugLevel(std::uint8_t playerDebugLevel, std::uint8_t messageDebugLevel) const noexcept; void PrintLog(const char* szText); + bool CheckForSufficientDebugLevel(std::uint8_t playerDebugLevel, std::uint8_t messageDebugLevel) const noexcept; public: static FILE* m_pLogFile; diff --git a/Client/mods/deathmatch/logic/CScriptFile.h b/Client/mods/deathmatch/logic/CScriptFile.h index b3bea766985..b962816394e 100644 --- a/Client/mods/deathmatch/logic/CScriptFile.h +++ b/Client/mods/deathmatch/logic/CScriptFile.h @@ -32,11 +32,11 @@ class CScriptFile final : public CClientEntity // Functions required for linking void GetPosition(CVector& vecPosition) const {}; - void SetPosition(const CVector& vecPosition){}; + void SetPosition(const CVector& vecPosition) {}; // Functions required by CClientEntity eClientEntityType GetType() const { return SCRIPTFILE; }; - void Unlink(){}; + void Unlink() {}; // Load and unload routines bool Load(CResource* pResourceForFilePath, eMode Mode); @@ -53,7 +53,7 @@ class CScriptFile final : public CClientEntity /** * @brief Returns a pointer to CResourceFile if the script file points to one. * @return A pointer to CResourceFile on success, null otherwise - */ + */ CResourceFile* GetResourceFile() const; // Only call functions below this if you're sure that the file is loaded. @@ -79,8 +79,8 @@ class CScriptFile final : public CClientEntity void DoResourceFileCheck(); CBinaryFileInterface* m_pFile; - SString m_strFilename; // Resource relative - SString m_strAbsPath; // Absolute + SString m_strFilename; // Resource relative + SString m_strAbsPath; // Absolute unsigned long m_ulMaxSize; bool m_bDoneResourceFileCheck; unsigned int m_uiScriptId; diff --git a/Client/mods/deathmatch/logic/CServerIdManager.cpp b/Client/mods/deathmatch/logic/CServerIdManager.cpp index b28ea8a5dc3..a442bfccd8c 100644 --- a/Client/mods/deathmatch/logic/CServerIdManager.cpp +++ b/Client/mods/deathmatch/logic/CServerIdManager.cpp @@ -13,20 +13,20 @@ #include "StdInc.h" #include "CServerIdManager.h" -#define MTA_SERVERID_LOOKUP_DIR "priv" -#define MTA_SERVERID_LOOKUP_XML "priv/server-ids.xml" +#define MTA_SERVERID_LOOKUP_DIR "priv" +#define MTA_SERVERID_LOOKUP_XML "priv/server-ids.xml" namespace { struct CServerIdKey { - SString strId; // Server id + SString strId; // Server id bool operator<(const CServerIdKey& other) const { return strId < other.strId; } }; struct CServerIdInfo { - SString strDir; // Server private directory + SString strDir; // Server private directory }; // Variables used for saving the file on a separate thread @@ -40,7 +40,7 @@ namespace strText.Split("_", &strMain, &strCount); return SString("%s_%d", *strMain, atoi(strCount) + 1); } -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -63,7 +63,7 @@ class CServerIdManagerImpl : public CServerIdManager void SaveServerIdMap(bool bWait = false); const CServerIdInfo& GetServerIdInfo(const SString& strServerId); bool LoadServerIdMap(); - static DWORD StaticThreadProc(LPVOID lpdwThreadParam); + static DWORD WINAPI StaticThreadProc(LPVOID lpdwThreadParam); static void StaticSaveServerIdMap(); bool m_bListChanged; @@ -188,7 +188,7 @@ void CServerIdManagerImpl::SaveServerIdMap(bool bWait) ms_ServerIdMap = m_ServerIdMap; // Start save thread - HANDLE hThread = CreateThread(NULL, 0, reinterpret_cast(CServerIdManagerImpl::StaticThreadProc), NULL, CREATE_SUSPENDED, NULL); + HANDLE hThread = CreateThread(NULL, 0, &CServerIdManagerImpl::StaticThreadProc, NULL, CREATE_SUSPENDED, NULL); if (!hThread) { g_pCore->GetConsole()->Printf("Could not create server-ids save thread."); @@ -197,7 +197,13 @@ void CServerIdManagerImpl::SaveServerIdMap(bool bWait) { ms_bIsSaving = true; SetThreadPriority(hThread, THREAD_PRIORITY_LOWEST); - ResumeThread(hThread); + if (ResumeThread(hThread) == static_cast(-1)) + { + g_pCore->GetConsole()->Printf("Could not start server-ids save thread."); + ms_bIsSaving = false; + } + + CloseHandle(hThread); } // Wait for save to complete if required @@ -212,7 +218,7 @@ void CServerIdManagerImpl::SaveServerIdMap(bool bWait) // SaveServerIdMap thread // /////////////////////////////////////////////////////////////// -DWORD CServerIdManagerImpl::StaticThreadProc(LPVOID lpdwThreadParam) +DWORD WINAPI CServerIdManagerImpl::StaticThreadProc(LPVOID lpdwThreadParam) { StaticSaveServerIdMap(); ms_bIsSaving = false; @@ -266,7 +272,7 @@ SString CServerIdManagerImpl::GetConnectionPrivateDirectory(bool bPreviousVer) // If ServerId is invalid, use the temp dir if (strServerId.length() < 10) - return bPreviousVer ? "" : m_strTempErrorDir; + return bPreviousVer ? SStringX("") : m_strTempErrorDir; // Otherwise fetch the server unique dir const CServerIdInfo& info = GetServerIdInfo(strServerId); diff --git a/Client/mods/deathmatch/logic/CServerInfo.h b/Client/mods/deathmatch/logic/CServerInfo.h index 80813d8bb18..81310fffba2 100644 --- a/Client/mods/deathmatch/logic/CServerInfo.h +++ b/Client/mods/deathmatch/logic/CServerInfo.h @@ -12,9 +12,9 @@ enum EServerInfoSyncFlag : uint8 { - SERVER_INFO_FLAG_ALL = 0xFF, // 0b11111111 - SERVER_INFO_FLAG_MAX_PLAYERS = 1, // 0b00000001 - SERVER_INFO_FLAG_RESERVED = 1 << 1 // 0b00000010 and so on + SERVER_INFO_FLAG_ALL = 0xFF, // 0b11111111 + SERVER_INFO_FLAG_MAX_PLAYERS = 1, // 0b00000001 + SERVER_INFO_FLAG_RESERVED = 1 << 1 // 0b00000010 and so on }; class CServerInfo diff --git a/Client/mods/deathmatch/logic/CSingularFileDownload.cpp b/Client/mods/deathmatch/logic/CSingularFileDownload.cpp index bb606d0be52..31c3f0fa12b 100644 --- a/Client/mods/deathmatch/logic/CSingularFileDownload.cpp +++ b/Client/mods/deathmatch/logic/CSingularFileDownload.cpp @@ -65,15 +65,15 @@ void CSingularFileDownload::CallFinished(bool bSuccess) { // Call the onClientbFileDownloadComplete event CLuaArguments Arguments; - Arguments.PushString(GetShortName()); // file name - Arguments.PushBoolean(bSuccess); // Completed successfully? + Arguments.PushString(GetShortName()); // file name + Arguments.PushBoolean(bSuccess); // Completed successfully? if (m_pRequestResource) { - Arguments.PushResource(m_pRequestResource); // Resource that called downloadFile + Arguments.PushResource(m_pRequestResource); // Resource that called downloadFile } else { - Arguments.PushBoolean(false); // or false + Arguments.PushBoolean(false); // or false } m_pResource->GetResourceEntity()->CallEvent("onClientFileDownloadComplete", Arguments, false); diff --git a/Client/mods/deathmatch/logic/CSingularFileDownload.h b/Client/mods/deathmatch/logic/CSingularFileDownload.h index b3686c14d85..1bfd4d5dd18 100644 --- a/Client/mods/deathmatch/logic/CSingularFileDownload.h +++ b/Client/mods/deathmatch/logic/CSingularFileDownload.h @@ -13,9 +13,9 @@ #ifndef _WINDOWS_ -#define WIN32_LEAN_AND_MEAN // Exclude all uncommon functions from windows.h to reduce build time by 100ms + #define WIN32_LEAN_AND_MEAN // Exclude all uncommon functions from windows.h to reduce build time by 100ms -#include + #include #endif #include diff --git a/Client/mods/deathmatch/logic/CSingularFileDownloadManager.cpp b/Client/mods/deathmatch/logic/CSingularFileDownloadManager.cpp index 97be6ba0dd2..2f88040d36c 100644 --- a/Client/mods/deathmatch/logic/CSingularFileDownloadManager.cpp +++ b/Client/mods/deathmatch/logic/CSingularFileDownloadManager.cpp @@ -59,4 +59,4 @@ bool CSingularFileDownloadManager::AllComplete() return false; } return true; -} \ No newline at end of file +} diff --git a/Client/mods/deathmatch/logic/CSingularFileDownloadManager.h b/Client/mods/deathmatch/logic/CSingularFileDownloadManager.h index 9b861b5dce8..a49ff55281c 100644 --- a/Client/mods/deathmatch/logic/CSingularFileDownloadManager.h +++ b/Client/mods/deathmatch/logic/CSingularFileDownloadManager.h @@ -13,9 +13,9 @@ #ifndef _WINDOWS_ -#define WIN32_LEAN_AND_MEAN // Exclude all uncommon functions from windows.h to reduce build time by 100ms + #define WIN32_LEAN_AND_MEAN // Exclude all uncommon functions from windows.h to reduce build time by 100ms -#include + #include #endif #include diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 905a2c43cfb..e104e137404 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -27,10 +27,13 @@ #include #include #include +#include #include #include #include #include +#include +#include using std::list; @@ -101,6 +104,14 @@ CStaticFunctionDefinitions::~CStaticFunctionDefinitions() { } +void CStaticFunctionDefinitions::PreInitialize(CCoreInterface* pCore, CGame* pGame, CClientGame* pClientGame, CEvents* pEvents) +{ + m_pCore = pCore; + m_pGame = pGame; + m_pClientGame = pClientGame; + m_pEvents = pEvents; +} + bool CStaticFunctionDefinitions::AddEvent(CLuaMain& LuaMain, const char* szName, bool bAllowRemoteTrigger) { assert(szName); @@ -260,43 +271,37 @@ bool CStaticFunctionDefinitions::ClearChatBox() bool CStaticFunctionDefinitions::OutputChatBox(const char* szText, unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue, bool bColorCoded) { - if (strlen(szText) <= MAX_OUTPUTCHATBOX_LENGTH) - { - CLuaArguments Arguments; - Arguments.PushString(szText); - Arguments.PushNumber(ucRed); - Arguments.PushNumber(ucGreen); - Arguments.PushNumber(ucBlue); + // Early null-safety checks to prevent crashes when called before initialization + if (!m_pCore || !g_pClientGame || !szText || szText[0] == '\0') + return false; - bool bCancelled = !g_pClientGame->GetRootEntity()->CallEvent("onClientChatMessage", Arguments, false); - if (!bCancelled) - { - m_pCore->ChatPrintfColor("%s", bColorCoded, ucRed, ucGreen, ucBlue, szText); - return true; - } + // Calculate length without color codes when bColorCoded is true for accurate visible text length + SString textToProcess = bColorCoded ? RemoveColorCodes(szText) : SStringX(szText); + + // Reject messages that exceed the maximum length + if (textToProcess.length() > MAX_OUTPUTCHATBOX_LENGTH) + return false; + + // Fire the onClientChatMessage event + CLuaArguments Arguments; + Arguments.PushString(szText); + Arguments.PushNumber(ucRed); + Arguments.PushNumber(ucGreen); + Arguments.PushNumber(ucBlue); + + bool bCancelled = !g_pClientGame->GetRootEntity()->CallEvent("onClientChatMessage", Arguments, false); + if (!bCancelled) + { + m_pCore->ChatPrintfColor("%s", bColorCoded, ucRed, ucGreen, ucBlue, szText); + return true; } + return false; } bool CStaticFunctionDefinitions::SetClipboard(SString& strText) { - std::wstring strUTF = MbUTF8ToUTF16(strText); - - // Open and empty the clipboard - OpenClipboard(NULL); - EmptyClipboard(); - - // Allocate the clipboard buffer and copy the data - HGLOBAL hBuf = GlobalAlloc(GMEM_DDESHARE, strUTF.length() * sizeof(wchar_t) + sizeof(wchar_t)); - wchar_t* buf = reinterpret_cast(GlobalLock(hBuf)); - wcscpy(buf, strUTF.c_str()); - GlobalUnlock(hBuf); - - // Copy the data into the clipboard - SetClipboardData(CF_UNICODETEXT, hBuf); - - // Close the clipboard - CloseClipboard(); + SharedUtil::SetClipboardText(strText); return true; } @@ -571,7 +576,6 @@ bool CStaticFunctionDefinitions::GetElementBoundingBox(CClientEntity& Entity, CV pModelInfo = g_pGame->GetModelInfo(building.GetModel()); break; } - } if (pModelInfo) @@ -668,6 +672,11 @@ bool CStaticFunctionDefinitions::GetElementDistanceFromCentreOfMassToBaseOfModel fDistance = static_cast(Entity).GetDistanceFromCentreOfMassToBaseOfModel(); return true; } + case CCLIENTBUILDING: + { + fDistance = static_cast(Entity).GetDistanceFromCentreOfMassToBaseOfModel(); + return true; + } } return false; @@ -1019,13 +1028,13 @@ bool CStaticFunctionDefinitions::SetElementID(CClientEntity& Entity, const char* return false; } -bool CStaticFunctionDefinitions::SetElementData(CClientEntity& Entity, const char* szName, CLuaArgument& Variable, bool bSynchronize) +bool CStaticFunctionDefinitions::SetElementData(CClientEntity& Entity, CStringName name, CLuaArgument& Variable, bool bSynchronize) { - assert(szName); - assert(strlen(szName) <= MAX_CUSTOMDATA_NAME_LENGTH); + assert(name); + assert(name->length() <= MAX_CUSTOMDATA_NAME_LENGTH); bool bIsSynced; - CLuaArgument* pCurrentVariable = Entity.GetCustomData(szName, false, &bIsSynced); + CLuaArgument* pCurrentVariable = Entity.GetCustomData(name, false, &bIsSynced); if (!pCurrentVariable || Variable != *pCurrentVariable || bIsSynced != bSynchronize) { if (bSynchronize && !Entity.IsLocalEntity()) @@ -1033,9 +1042,9 @@ bool CStaticFunctionDefinitions::SetElementData(CClientEntity& Entity, const cha NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); // Write element ID, name length and the name. Also write the variable. pBitStream->Write(Entity.GetID()); - unsigned short usNameLength = static_cast(strlen(szName)); + unsigned short usNameLength = static_cast(name->length()); pBitStream->WriteCompressed(usNameLength); - pBitStream->Write(szName, usNameLength); + pBitStream->Write(name.ToCString(), usNameLength); Variable.WriteToBitStream(*pBitStream); // Send the packet and deallocate @@ -1044,14 +1053,14 @@ bool CStaticFunctionDefinitions::SetElementData(CClientEntity& Entity, const cha } // Set its custom data - Entity.SetCustomData(szName, Variable, bSynchronize); + Entity.SetCustomData(name, Variable, bSynchronize); return true; } return false; } -bool CStaticFunctionDefinitions::RemoveElementData(CClientEntity& Entity, const char* szName) +bool CStaticFunctionDefinitions::RemoveElementData(CClientEntity& Entity, CStringName name) { // TODO return false; @@ -1274,7 +1283,7 @@ bool CStaticFunctionDefinitions::SetElementParent(CClientEntity& Entity, CClient const char* szTypeName = pTemp->GetTypeName(); if (szTypeName && strcmp(szTypeName, "map") == 0) { - bValidParent = true; // parents must be a map + bValidParent = true; // parents must be a map break; } @@ -1371,18 +1380,30 @@ bool CStaticFunctionDefinitions::AttachElements(CClientEntity& Entity, CClientEn RUN_CHILDREN(AttachElements(**iter, AttachedToEntity, vecPosition, vecRotation)) // Can these elements be attached? - if (Entity.IsAttachToable() && AttachedToEntity.IsAttachable() && !AttachedToEntity.IsAttachedToElement(&Entity) && - Entity.GetDimension() == AttachedToEntity.GetDimension()) + if (!Entity.IsAttachToable() || !AttachedToEntity.IsAttachable() || AttachedToEntity.IsAttachedToElement(&Entity) || + Entity.GetDimension() != AttachedToEntity.GetDimension()) { - ConvertDegreesToRadians(vecRotation); + return false; + } - Entity.SetAttachedOffsets(vecPosition, vecRotation); - Entity.AttachTo(&AttachedToEntity); + CLuaArguments Arguments; + Arguments.PushElement(&AttachedToEntity); + Arguments.PushNumber(vecPosition.fX); + Arguments.PushNumber(vecPosition.fY); + Arguments.PushNumber(vecPosition.fZ); + Arguments.PushNumber(vecRotation.fX); + Arguments.PushNumber(vecRotation.fY); + Arguments.PushNumber(vecRotation.fZ); + + if (!Entity.CallEvent("onClientElementAttach", Arguments, true)) + return false; - return true; - } + ConvertDegreesToRadians(vecRotation); - return false; + Entity.SetAttachedOffsets(vecPosition, vecRotation); + Entity.AttachTo(&AttachedToEntity); + + return true; } bool CStaticFunctionDefinitions::DetachElements(CClientEntity& Entity, CClientEntity* pAttachedToEntity) @@ -1390,16 +1411,33 @@ bool CStaticFunctionDefinitions::DetachElements(CClientEntity& Entity, CClientEn RUN_CHILDREN(DetachElements(**iter, pAttachedToEntity)) CClientEntity* pActualAttachedToEntity = Entity.GetAttachedTo(); - if (pActualAttachedToEntity) + if (!pActualAttachedToEntity || (pAttachedToEntity && pActualAttachedToEntity != pAttachedToEntity)) { - if (pAttachedToEntity == NULL || pActualAttachedToEntity == pAttachedToEntity) - { - Entity.AttachTo(NULL); - return true; - } + return false; } - return false; + CVector vecPosition; + CVector vecRotation; + + Entity.GetPosition(vecPosition); + Entity.GetRotationDegrees(vecRotation); + + CLuaArguments Arguments; + Arguments.PushElement(pActualAttachedToEntity); + Arguments.PushNumber(vecPosition.fX); + Arguments.PushNumber(vecPosition.fY); + Arguments.PushNumber(vecPosition.fZ); + Arguments.PushNumber(vecRotation.fX); + Arguments.PushNumber(vecRotation.fY); + Arguments.PushNumber(vecRotation.fZ); + + if (!Entity.CallEvent("onClientElementDetach", Arguments, true)) + { + return false; + } + + Entity.AttachTo(NULL); + return true; } bool CStaticFunctionDefinitions::SetElementAttachedOffsets(CClientEntity& Entity, CVector& vecPosition, CVector& vecRotation) @@ -1464,6 +1502,13 @@ bool CStaticFunctionDefinitions::SetElementHealth(CClientEntity& Entity, float f // Grab the model CClientPed& Ped = static_cast(Entity); + // If setting health to 0 for local player, clear stale damage data + // and set proper scripted death parameters for DoWastedCheck + if (fHealth == 0.0f && Ped.IsLocalPlayer() && Ped.GetHealth() > 0.0f) + { + g_pClientGame->SetScriptedDeathData(); + } + // Set the new health Ped.SetHealth(Clamp(0.0f, fHealth, Ped.GetMaxHealth())); return true; @@ -1492,7 +1537,8 @@ bool CStaticFunctionDefinitions::SetElementModel(CClientEntity& Entity, unsigned { RUN_CHILDREN(SetElementModel(**iter, usModel)) - auto callOnChangeEvent = [](auto &element, uint16_t usCurrentModel, uint16_t usModel) { + auto callOnChangeEvent = [](auto& element, uint16_t usCurrentModel, uint16_t usModel) + { CLuaArguments Arguments; Arguments.PushNumber(usCurrentModel); Arguments.PushNumber(usModel); @@ -1712,7 +1758,7 @@ bool CStaticFunctionDefinitions::GetPedClothes(CClientPed& Ped, unsigned char uc return false; } -bool CStaticFunctionDefinitions::GetPedControlState(CClientPed& const ped, const std::string control, bool& state) noexcept +bool CStaticFunctionDefinitions::GetPedControlState(CClientPed& ped, const std::string& control, bool& state) noexcept { if (&ped == GetLocalPlayer()) return GetControlState(control.c_str(), state); @@ -1758,7 +1804,7 @@ bool CStaticFunctionDefinitions::GetPedAnalogControlState(CClientPed& Ped, const unsigned int uiIndex; if (bRawInput) - cs = Ped.m_rawControllerState; // use the raw controller values without MTA glitch fixes modifying our raw inputs + cs = Ped.m_rawControllerState; // use the raw controller values without MTA glitch fixes modifying our raw inputs else Ped.GetControllerState(cs); @@ -2247,6 +2293,8 @@ bool CStaticFunctionDefinitions::SetPedAnimation(CClientEntity& Entity, const SS } } } + + Ped.m_AnimationCache.startTime = GetTimestamp(); } else { @@ -2365,13 +2413,15 @@ bool CStaticFunctionDefinitions::RemovePedClothes(CClientEntity& Entity, unsigne return false; } -bool CStaticFunctionDefinitions::SetPedControlState(CClientPed& const ped, const std::string control, const bool state) noexcept +bool CStaticFunctionDefinitions::SetPedControlState(CClientPed& ped, const std::string& control, bool state) noexcept { if (&ped == GetLocalPlayer()) return SetControlState(control.c_str(), state); if (ped.m_Pad.SetControlState(control.c_str(), state)) return true; + + return false; } bool CStaticFunctionDefinitions::SetPedDoingGangDriveby(CClientEntity& Entity, bool bGangDriveby) @@ -2502,7 +2552,7 @@ bool CStaticFunctionDefinitions::SetPedAimTarget(CClientEntity& Entity, CVector& // Ped rotation CVector vecRot; Ped.GetRotationRadians(vecRot); - float fRotZ = -vecRot.fZ; // Counter-clockwise + float fRotZ = -vecRot.fZ; // Counter-clockwise fRotZ = (fRotZ > PI) ? fRotZ - PI * 2 : fRotZ; // Rotation difference @@ -2643,7 +2693,8 @@ bool CStaticFunctionDefinitions::GetTypeIndexFromClothes(const char* szTexture, { std::vector pPlayerClothing = CClientPlayerClothes::GetClothingGroup(ucType); - if (!pPlayerClothing.empty()) { + if (!pPlayerClothing.empty()) + { for (unsigned char ucIter = 0; ucIter < pPlayerClothing.size(); ucIter++) { if ((szTexture == NULL || strcmp(szTexture, pPlayerClothing[ucIter]->texture.c_str()) == 0) && @@ -2869,7 +2920,7 @@ bool CStaticFunctionDefinitions::BlowVehicle(CClientEntity& Entity, std::optiona if (!IS_VEHICLE(&Entity)) return false; - CClientVehicle& vehicle = static_cast(Entity); + CClientVehicle& vehicle = static_cast(Entity); VehicleBlowFlags blow; blow.withExplosion = withExplosion.value_or(true); @@ -2883,8 +2934,8 @@ bool CStaticFunctionDefinitions::BlowVehicle(CClientEntity& Entity, std::optiona CVector position; vehicle.GetPosition(position); - const auto type = vehicle.GetType(); - const auto state = (blow.withExplosion ? VehicleBlowState::AWAITING_EXPLOSION_SYNC : VehicleBlowState::BLOWN); + const auto type = vehicle.GetType(); + const auto state = (blow.withExplosion ? VehicleBlowState::AWAITING_EXPLOSION_SYNC : VehicleBlowState::BLOWN); eExplosionType explosion; switch (type) @@ -2924,7 +2975,7 @@ bool CStaticFunctionDefinitions::GetVehicleHeadLightColor(CClientVehicle& Vehicl bool CStaticFunctionDefinitions::GetVehicleCurrentGear(CClientVehicle& Vehicle, unsigned short& currentGear) { - currentGear = Vehicle.GetCurrentGear(); + currentGear = static_cast(Vehicle.GetCurrentGear()); return true; } @@ -3219,7 +3270,8 @@ bool CStaticFunctionDefinitions::SetVehicleLightState(CClientEntity& Entity, uns return false; } -bool CStaticFunctionDefinitions::SetVehiclePanelState(CClientEntity& Entity, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent, bool breakGlass) +bool CStaticFunctionDefinitions::SetVehiclePanelState(CClientEntity& Entity, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent, + bool breakGlass) { RUN_CHILDREN(SetVehiclePanelState(**iter, ucPanel, ucState, spawnFlyingComponent, breakGlass)) @@ -4791,12 +4843,13 @@ bool CStaticFunctionDefinitions::SetBlipVisibleDistance(CClientEntity& Entity, u return false; } -CClientMarker* CStaticFunctionDefinitions::CreateMarker(CResource& Resource, const CVector& vecPosition, const char* szType, float fSize, const SColor color, bool ignoreAlphaLimits) +CClientMarker* CStaticFunctionDefinitions::CreateMarker(CResource& Resource, const CVector& vecPosition, const char* szType, float fSize, const SColor color, + bool ignoreAlphaLimits) { assert(szType); // Grab the type id - unsigned char ucType = CClientMarker::StringToType(szType); + unsigned char ucType = static_cast(CClientMarker::StringToType(szType)); if (ucType != CClientMarker::MARKER_INVALID) { // Create the marker @@ -4841,7 +4894,7 @@ bool CStaticFunctionDefinitions::SetMarkerType(CClientEntity& Entity, const char RUN_CHILDREN(SetMarkerType(**iter, szType)) // Grab the new type ID - unsigned char ucType = CClientMarker::StringToType(szType); + unsigned char ucType = static_cast(CClientMarker::StringToType(szType)); if (ucType != CClientMarker::MARKER_INVALID) { // Is this a marker? @@ -4954,7 +5007,7 @@ bool CStaticFunctionDefinitions::SetMarkerTargetArrowProperties(CClientEntity& E if (!IS_MARKER(&Entity)) return false; - CClientMarker& marker = static_cast(Entity); + CClientMarker& marker = static_cast(Entity); CClientCheckpoint* checkpoint = marker.GetCheckpoint(); if (!checkpoint) return false; @@ -4968,14 +5021,45 @@ bool CStaticFunctionDefinitions::SetMarkerTargetArrowProperties(CClientEntity& E bool CStaticFunctionDefinitions::GetCameraMatrix(CVector& vecPosition, CVector& vecLookAt, float& fRoll, float& fFOV) { + if (!m_pCamera) + return false; + m_pCamera->GetPosition(vecPosition); m_pCamera->GetFixedTarget(vecLookAt, &fRoll); - fFOV = m_pCamera->GetFOV(); + + fFOV = m_pCamera->GetAccurateFOV(); + + if (fRoll == 0.0f) + { + // Calculate roll from camera matrix when not directly available + CMatrix matrix; + m_pCamera->GetMatrix(matrix); + + CVector worldUp(0.0f, 0.0f, 1.0f); + CVector cameraUp = matrix.vUp; + CVector cameraRight = matrix.vRight; + + // Project camera up vector onto plane perpendicular to camera front + CVector projectedUp = cameraUp - matrix.vFront * cameraUp.DotProduct(&matrix.vFront); + if (projectedUp.Length() <= FLOAT_EPSILON) + return true; + + projectedUp.Normalize(); + + float cosRoll = worldUp.DotProduct(&projectedUp); + float sinRoll = cameraRight.DotProduct(&worldUp); + + fRoll = std::atan2(sinRoll, cosRoll) * (180.0f / std::numbers::pi_v); + } + return true; } CClientEntity* CStaticFunctionDefinitions::GetCameraTarget() { + if (!m_pCamera) + return nullptr; + if (!m_pCamera->IsInFixedMode()) return m_pCamera->GetTargetEntity(); return NULL; @@ -4983,12 +5067,22 @@ CClientEntity* CStaticFunctionDefinitions::GetCameraTarget() bool CStaticFunctionDefinitions::GetCameraInterior(unsigned char& ucInterior) { - ucInterior = static_cast(g_pGame->GetWorld()->GetCurrentArea()); + if (!g_pGame) + return false; + + auto world = g_pGame->GetWorld(); + if (!world) + return false; + + ucInterior = static_cast(world->GetCurrentArea()); return true; } bool CStaticFunctionDefinitions::SetCameraMatrix(const CVector& vecPosition, CVector* pvecLookAt, float fRoll, float fFOV) { + if (!m_pCamera) + return false; + if (!m_pCamera->IsInFixedMode()) { m_pCamera->ToggleCameraFixedMode(true); @@ -5004,13 +5098,23 @@ bool CStaticFunctionDefinitions::SetCameraMatrix(const CVector& vecPosition, CVe m_pCamera->GetFixedTarget(vecPrevLookAt); m_pCamera->SetFixedTarget(vecPrevLookAt, fRoll); } + + if (!std::isfinite(fFOV) || fFOV <= 0.0f) + fFOV = 70.0f; + else if (fFOV >= 180.0f) + fFOV = 179.0f; + m_pCamera->SetFOV(fFOV); return true; } bool CStaticFunctionDefinitions::SetCameraTarget(CClientEntity* pEntity) { - assert(pEntity); + if (!m_pCamera || !pEntity) + return false; + + if (pEntity->IsBeingDeleted()) + return false; switch (pEntity->GetType()) { @@ -5049,30 +5153,45 @@ bool CStaticFunctionDefinitions::SetCameraTarget(CClientEntity* pEntity) bool CStaticFunctionDefinitions::SetCameraTarget(const CVector& vecTarget) { + if (!m_pCamera) + return false; + m_pCamera->SetOrbitTarget(vecTarget); return true; } bool CStaticFunctionDefinitions::SetCameraInterior(unsigned char ucInterior) { - g_pGame->GetWorld()->SetCurrentArea(ucInterior); + if (!g_pGame) + return false; + + auto world = g_pGame->GetWorld(); + if (!world) + return false; + + world->SetCurrentArea(ucInterior); return true; } bool CStaticFunctionDefinitions::FadeCamera(bool bFadeIn, float fFadeTime, unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue) { CClientCamera* pCamera = m_pManager->GetCamera(); + if (!pCamera || !g_pClientGame) + return false; + g_pClientGame->SetInitiallyFadedOut(false); if (bFadeIn) { pCamera->FadeIn(fFadeTime); - g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, !g_pClientGame->GetHudAreaNameDisabled()); + if (g_pGame && g_pGame->GetHud()) + g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, !g_pClientGame->GetHudAreaNameDisabled()); } else { pCamera->FadeOut(fFadeTime, ucRed, ucGreen, ucBlue); - g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false); + if (g_pGame && g_pGame->GetHud()) + g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false); } return true; @@ -5148,7 +5267,7 @@ bool CStaticFunctionDefinitions::SetCursorAlpha(float fAlpha) } bool CStaticFunctionDefinitions::GUIGetInputEnabled() -{ // can't inline because statics are defined in .cpp not .h +{ // can't inline because statics are defined in .cpp not .h return m_pGUI->GetGUIInputEnabled(); } @@ -6366,7 +6485,8 @@ void CStaticFunctionDefinitions::GUILabelSetColor(CClientEntity& Entity, int iR, if (IS_CGUIELEMENT_LABEL(&GUIElement)) { // Set the label color - static_cast(GUIElement.GetCGUIElement())->SetTextColor(iR, iG, iB); + static_cast(GUIElement.GetCGUIElement()) + ->SetTextColor(static_cast(iR), static_cast(iG), static_cast(iB)); } } } @@ -6645,6 +6765,11 @@ bool CStaticFunctionDefinitions::GetGarageSize(unsigned char ucGarageID, float& if (pGarage) { pGarage->GetSize(fHeight, fWidth, fDepth); + + CVector vecPosition; + pGarage->GetPosition(vecPosition); + fHeight -= vecPosition.fZ; + return true; } @@ -6972,20 +7097,19 @@ bool CStaticFunctionDefinitions::SetMoonSize(int iSize) return false; } -bool CStaticFunctionDefinitions::SetFPSLimit(int iLimit) +void CStaticFunctionDefinitions::SetClientFPSLimit(std::uint16_t fps) { - if (iLimit == 0 || (iLimit >= 25 && iLimit <= std::numeric_limits::max())) - { - g_pCore->SetClientScriptFrameRateLimit(iLimit); - return true; - } - return false; + g_pCore->GetFPSLimiter()->SetClientEnforcedFPS(fps); } -bool CStaticFunctionDefinitions::GetFPSLimit(int& iLimit) +void CStaticFunctionDefinitions::GetFPSLimit(std::uint16_t& fps) noexcept { - iLimit = g_pCore->GetFrameRateLimit(); - return true; + fps = g_pCore->GetFPSLimiter()->GetFPSTarget(); +} + +void CStaticFunctionDefinitions::SetServerFPSLimit(std::uint16_t fps) +{ + g_pCore->GetFPSLimiter()->SetServerEnforcedFPS(fps); } bool CStaticFunctionDefinitions::BindKey(const char* szKey, const char* szHitState, CLuaMain* pLuaMain, const CLuaFunctionRef& iLuaFunction, @@ -7129,7 +7253,6 @@ bool CStaticFunctionDefinitions::UnbindKey(const char* szKey, const char* szHitS CKeyBindsInterface* pKeyBinds = g_pCore->GetKeyBinds(); bool bKey = pKeyBinds->IsKey(szKey); - CCommandBind* pBind; if (bKey) { @@ -7147,27 +7270,16 @@ bool CStaticFunctionDefinitions::UnbindKey(const char* szKey, const char* szHitS } } - pBind = g_pCore->GetKeyBinds()->GetBindFromCommand(szCommandName, NULL, false, szKey, bCheckHitState, bHitState); - + // Use context-aware removal to only remove resource bindings if ((!stricmp(szHitState, "down") || !stricmp(szHitState, "both")) && - pKeyBinds->SetCommandActive(szKey, szCommandName, bHitState, NULL, szResource, false, true, true)) + pKeyBinds->RemoveCommandFromContext(szKey, szCommandName, BindingContext::RESOURCE, bCheckHitState, bHitState, NULL, szResource)) { - pKeyBinds->SetAllCommandsActive(szResource, false, szCommandName, bHitState, NULL, true, szKey); - - if (pBind) - pKeyBinds->Remove(pBind); - bSuccess = true; } bHitState = false; if ((!stricmp(szHitState, "up") || !stricmp(szHitState, "both")) && - pKeyBinds->SetCommandActive(szKey, szCommandName, bHitState, NULL, szResource, false, true, true)) + pKeyBinds->RemoveCommandFromContext(szKey, szCommandName, BindingContext::RESOURCE, bCheckHitState, bHitState, NULL, szResource)) { - pKeyBinds->SetAllCommandsActive(szResource, false, szCommandName, bHitState, NULL, true, szKey); - - if (pBind) - pKeyBinds->Remove(pBind); - bSuccess = true; } } @@ -7214,7 +7326,7 @@ bool CStaticFunctionDefinitions::GetAnalogControlState(const char* szControl, fl bool bOnFoot = (!pLocalPlayer->GetRealOccupiedVehicle()); if (bRawInput) - cs = pLocalPlayer->m_rawControllerState; // use the raw controller values without MTA glitch fixes modifying our raw inputs + cs = pLocalPlayer->m_rawControllerState; // use the raw controller values without MTA glitch fixes modifying our raw inputs else pLocalPlayer->GetControllerState(cs); @@ -7975,7 +8087,9 @@ bool CStaticFunctionDefinitions::FxAddFootSplash(CVector& vecPosition) return true; } -bool CStaticFunctionDefinitions::FxCreateParticle(FxParticleSystems eFxParticle, CVector& vecPosition, CVector& vecDirection, float fR, float fG, float fB, float fA, bool bRandomizeColors, std::uint32_t iCount, float fBrightness, float fSize, bool bRandomizeSizes, float fLife) +bool CStaticFunctionDefinitions::FxCreateParticle(FxParticleSystems eFxParticle, CVector& vecPosition, CVector& vecDirection, float fR, float fG, float fB, + float fA, bool bRandomizeColors, std::uint32_t iCount, float fBrightness, float fSize, bool bRandomizeSizes, + float fLife) { g_pGame->GetFx()->AddParticle(eFxParticle, vecPosition, vecDirection, fR, fG, fB, fA, bRandomizeColors, iCount, fBrightness, fSize, bRandomizeSizes, fLife); return true; @@ -8010,7 +8124,7 @@ bool CStaticFunctionDefinitions::StopSound(CClientSound& Sound) { // call onClientSoundStopped CLuaArguments Arguments; - Arguments.PushString("destroyed"); // Reason + Arguments.PushString("destroyed"); // Reason Sound.CallEvent("onClientSoundStopped", Arguments, false); g_pClientGame->GetElementDeleter()->Delete(&Sound); return true; @@ -8546,7 +8660,7 @@ bool CStaticFunctionDefinitions::SetEntryHandling(CHandlingEntry* pEntry, Handli if (ucValue >= 0 && ucValue <= 29) { if (ucValue != 3 && ucValue != 8 && ucValue != 17 && ucValue != 23) - return true; // Pretend it worked to avoid script warnings + return true; // Pretend it worked to avoid script warnings pEntry->SetAnimGroup(ucValue); return true; @@ -9245,7 +9359,7 @@ bool CStaticFunctionDefinitions::GetEntryHandling(CHandlingEntry* pEntry, Handli case HandlingProperty::HANDLING_SEATOFFSETDISTANCE: fValue = pEntry->GetSeatOffsetDistance(); break; - case HandlingProperty::HANDLING_ABS: // bool + case HandlingProperty::HANDLING_ABS: // bool fValue = (float)(pEntry->GetABS() ? 1 : 0); break; default: @@ -9261,7 +9375,7 @@ bool CStaticFunctionDefinitions::GetEntryHandling(CHandlingEntry* pEntry, Handli { switch (eProperty) { - case HandlingProperty::HANDLING_PERCENTSUBMERGED: // unsigned int + case HandlingProperty::HANDLING_PERCENTSUBMERGED: // unsigned int uiValue = pEntry->GetPercentSubmerged(); break; case HandlingProperty::HANDLING_MONETARY: @@ -9856,6 +9970,9 @@ bool CStaticFunctionDefinitions::WarpPedIntoVehicle(CClientPed* pPed, CClientVeh if (pPed->IsLocalEntity() != pVehicle->IsLocalEntity()) return false; + if (!CClientVehicleManager::IsValidSeat(pVehicle->GetModel(), static_cast(uiSeat))) + return false; + if (pPed->IsLocalEntity()) { // @@ -9866,14 +9983,6 @@ bool CStaticFunctionDefinitions::WarpPedIntoVehicle(CClientPed* pPed, CClientVeh if (pPed->IsDead() || pVehicle->GetHealth() <= 0.0f) return false; - // Valid seat id for that vehicle? - uchar ucMaxPassengers = CClientVehicleManager::GetMaxPassengerCount(pVehicle->GetModel()); - if (uiSeat > ucMaxPassengers) - return false; - - if (uiSeat > 0 && ucMaxPassengers == 255) - return false; - // Toss the previous player out of it if neccessary if (CClientPed* pPreviousOccupant = pVehicle->GetOccupant(uiSeat)) RemovePedFromVehicle(pPreviousOccupant); @@ -9907,8 +10016,8 @@ bool CStaticFunctionDefinitions::WarpPedIntoVehicle(CClientPed* pPed, CClientVeh // Call the onClientPlayerEnterVehicle event CLuaArguments Arguments; - Arguments.PushElement(pVehicle); // vehicle - Arguments.PushNumber(uiSeat); // seat + Arguments.PushElement(pVehicle); // vehicle + Arguments.PushNumber(uiSeat); // seat if (IS_PLAYER(pPed)) pPed->CallEvent("onClientPlayerVehicleEnter", Arguments, true); else @@ -9916,8 +10025,8 @@ bool CStaticFunctionDefinitions::WarpPedIntoVehicle(CClientPed* pPed, CClientVeh // Call the onClientVehicleEnter event CLuaArguments Arguments2; - Arguments2.PushElement(pPed); // player / ped - Arguments2.PushNumber(uiSeat); // seat + Arguments2.PushElement(pPed); // player / ped + Arguments2.PushNumber(uiSeat); // seat pVehicle->CallEvent("onClientVehicleEnter", Arguments2, true); return true; @@ -9928,7 +10037,7 @@ bool CStaticFunctionDefinitions::RemovePedFromVehicle(CClientPed* pPed) // Get the ped / player's occupied vehicle data before pulling it out CClientVehicle* pVehicle = pPed->GetOccupiedVehicle(); unsigned int uiSeat = pPed->GetOccupiedVehicleSeat(); - bool bCancellingWhileEntering = pPed->IsEnteringVehicle(); // Special case here that could cause network trouble. + bool bCancellingWhileEntering = pPed->IsEnteringVehicle(); // Special case here that could cause network trouble. // Occupied vehicle can be NULL here while entering (Walking up to a vehicle in preparation to getting in/opening the doors) if (pVehicle || bCancellingWhileEntering) @@ -9941,8 +10050,8 @@ bool CStaticFunctionDefinitions::RemovePedFromVehicle(CClientPed* pPed) if (pVehicle == NULL) pVehicle = pPed->GetOccupyingVehicle(); - if (pVehicle == NULL) // Every time I've tested this the occupying Vehicle has been correct, but if it doesn't exist let's not try and - // call an event on it! + if (pVehicle == NULL) // Every time I've tested this the occupying Vehicle has been correct, but if it doesn't exist let's not try and + // call an event on it! return false; } @@ -9960,9 +10069,9 @@ bool CStaticFunctionDefinitions::RemovePedFromVehicle(CClientPed* pPed) // Call onClientPlayerVehicleExit CLuaArguments Arguments; - Arguments.PushElement(pVehicle); // vehicle - Arguments.PushNumber(uiSeat); // seat - Arguments.PushBoolean(false); // jacker + Arguments.PushElement(pVehicle); // vehicle + Arguments.PushNumber(uiSeat); // seat + Arguments.PushBoolean(false); // jacker if (IS_PLAYER(pPed)) pPed->CallEvent("onClientPlayerVehicleExit", Arguments, true); else @@ -9970,8 +10079,8 @@ bool CStaticFunctionDefinitions::RemovePedFromVehicle(CClientPed* pPed) // Call onClientVehicleExit CLuaArguments Arguments2; - Arguments2.PushElement(pPed); // player / ped - Arguments2.PushNumber(uiSeat); // seat + Arguments2.PushElement(pPed); // player / ped + Arguments2.PushNumber(uiSeat); // seat pVehicle->CallEvent("onClientVehicleExit", Arguments2, true); return true; } diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h index ba779ad2ba0..0c20cbe9d6b 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -27,6 +27,8 @@ class CStaticFunctionDefinitions CClientManager* pManager); ~CStaticFunctionDefinitions(); + static void PreInitialize(CCoreInterface* pCore, CGame* pGame, CClientGame* pClientGame, CEvents* pEvents); + static bool AddEvent(CLuaMain& LuaMain, const char* szName, bool bAllowRemoteTrigger); static bool AddEventHandler(CLuaMain& LuaMain, const char* szName, CClientEntity& Entity, const CLuaFunctionRef& iLuaFunction, bool bPropagated, EEventPriorityType eventPriority, float fPriorityMod); @@ -85,8 +87,8 @@ class CStaticFunctionDefinitions static CClientDummy* CreateElement(CResource& Resource, const char* szTypeName, const char* szID); static bool DestroyElement(CClientEntity& Entity); static bool SetElementID(CClientEntity& Entity, const char* szID); - static bool SetElementData(CClientEntity& Entity, const char* szName, CLuaArgument& Variable, bool bSynchronize); - static bool RemoveElementData(CClientEntity& Entity, const char* szName); + static bool SetElementData(CClientEntity& Entity, CStringName name, CLuaArgument& Variable, bool bSynchronize); + static bool RemoveElementData(CClientEntity& Entity, CStringName name); static bool SetElementMatrix(CClientEntity& Entity, const CMatrix& matrix); static bool SetElementPosition(CClientEntity& Entity, const CVector& vecPosition, bool bWarp = true); static bool SetElementRotation(CClientEntity& Entity, const CVector& vecRotation, eEulerRotationOrder rotationOrder, bool bNewWay); @@ -141,7 +143,7 @@ class CStaticFunctionDefinitions static bool IsPedDoingTask(CClientPed& Ped, const char* szTaskName, bool& bIsDoingTask); static bool GetPedBonePosition(CClientPed& Ped, eBone bone, CVector& vecPosition); static bool GetPedClothes(CClientPed& Ped, unsigned char ucType, SString& strOutTexture, SString& strOutModel); - static bool GetPedControlState(CClientPed& const ped, const std::string control, bool& state) noexcept; + static bool GetPedControlState(CClientPed& ped, const std::string& control, bool& state) noexcept; static bool GetPedAnalogControlState(CClientPed& Ped, const char* szControl, float& fState, bool bRawInput); static bool IsPedDoingGangDriveby(CClientPed& Ped, bool& bDoingGangDriveby); static bool GetPedFightingStyle(CClientPed& Ped, unsigned char& ucStyle); @@ -172,13 +174,13 @@ class CStaticFunctionDefinitions static bool SetPedAnimation(CClientEntity& Entity, const SString& strBlockName, const char* szAnimName, int iTime, int iBlend, bool bLoop, bool bUpdatePosition, bool bInterruptable, bool bFreezeLastFrame); - static bool SetPedAnimationProgress(CClientEntity& Entity, const SString& strAnimName, float fProgress); - static bool SetPedAnimationSpeed(CClientEntity& Entity, const SString& strAnimName, float fSpeed); + static bool SetPedAnimationProgress(CClientEntity& Entity, const SString& strAnimName, float fProgress); + static bool SetPedAnimationSpeed(CClientEntity& Entity, const SString& strAnimName, float fSpeed); static bool SetPedMoveAnim(CClientEntity& Entity, unsigned int iMoveAnim); static bool AddPedClothes(CClientEntity& Entity, const char* szTexture, const char* szModel, unsigned char ucType); static bool RemovePedClothes(CClientEntity& Entity, unsigned char ucType); - static bool SetPedControlState(CClientPed& const ped, const std::string control, const bool state) noexcept; + static bool SetPedControlState(CClientPed& ped, const std::string& control, bool state) noexcept; static bool SetPedAnalogControlState(CClientEntity& Entity, const char* szControl, float fState); static bool SetPedDoingGangDriveby(CClientEntity& Entity, bool bGangDriveby); static bool SetPedFightingStyle(CClientEntity& Entity, unsigned char ucStyle); @@ -247,7 +249,8 @@ class CStaticFunctionDefinitions static bool SetVehicleDoorState(CClientEntity& Entity, unsigned char ucDoor, unsigned char ucState, bool spawnFlyingComponent); static bool SetVehicleWheelStates(CClientEntity& Entity, int iFrontLeft, int iRearLeft = -1, int iFrontRight = -1, int iRearRight = -1); static bool SetVehicleLightState(CClientEntity& Entity, unsigned char ucLight, unsigned char ucState); - static bool SetVehiclePanelState(CClientEntity& Entity, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent = true, bool breakGlass = false); + static bool SetVehiclePanelState(CClientEntity& Entity, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent = true, + bool breakGlass = false); static bool SetVehicleOverrideLights(CClientEntity& Entity, unsigned char ucLights); static bool AttachTrailerToVehicle(CClientVehicle& Vehicle, CClientVehicle& Trailer, const CVector& vecRotationOffsetDegrees); static bool DetachTrailerFromVehicle(CClientVehicle& Vehicle, CClientVehicle* pTrailer = NULL); @@ -372,7 +375,8 @@ class CStaticFunctionDefinitions static bool SetBlipVisibleDistance(CClientEntity& Entity, unsigned short usVisibleDistance); // Marker create/destroy funcs - static CClientMarker* CreateMarker(CResource& Resource, const CVector& vecPosition, const char* szType, float fSize, const SColor color, bool ignoreAlphaLimits); + static CClientMarker* CreateMarker(CResource& Resource, const CVector& vecPosition, const char* szType, float fSize, const SColor color, + bool ignoreAlphaLimits); // Marker get funcs static bool GetMarkerTarget(CClientMarker& Marker, CVector& vecTarget); @@ -540,7 +544,12 @@ class CStaticFunctionDefinitions }; static inline void GUIGridListSetItemColor(CClientGUIElement& GUIElement, int iRow, int iColumn, int iRed, int iGreen, int iBlue, int iAlpha) { - static_cast(GUIElement.GetCGUIElement())->SetItemColor(iRow, iColumn, iRed, iGreen, iBlue, iAlpha); + const unsigned char ucRed = static_cast(Clamp(0, iRed, 255)); + const unsigned char ucGreen = static_cast(Clamp(0, iGreen, 255)); + const unsigned char ucBlue = static_cast(Clamp(0, iBlue, 255)); + const unsigned char ucAlpha = static_cast(Clamp(0, iAlpha, 255)); + + static_cast(GUIElement.GetCGUIElement())->SetItemColor(iRow, iColumn, ucRed, ucGreen, ucBlue, ucAlpha); }; static void GUIGridListSetHorizontalScrollPosition(CClientEntity& Element, float fPosition); static void GUIGridListSetVerticalScrollPosition(CClientEntity& Element, float fPosition); @@ -637,8 +646,11 @@ class CStaticFunctionDefinitions static bool SetBirdsEnabled(bool bEnabled); static bool GetBirdsEnabled(); static bool SetMoonSize(int iSize); - static bool SetFPSLimit(int iLimit); - static bool GetFPSLimit(int& iLimit); + + // FPS Limiter + static void GetFPSLimit(std::uint16_t& fps) noexcept; + static void SetClientFPSLimit(std::uint16_t fps); + static void SetServerFPSLimit(std::uint16_t fps); static bool ResetAllSurfaceInfo(); static bool ResetSurfaceInfo(short sSurfaceID); @@ -736,7 +748,8 @@ class CStaticFunctionDefinitions static bool FxAddWaterSplash(CVector& vecPosition); static bool FxAddBulletSplash(CVector& vecPosition); static bool FxAddFootSplash(CVector& vecPosition); - static bool FxCreateParticle(FxParticleSystems eFxParticle, CVector& vecPosition, CVector& vecDirection, float fR, float fG, float fB, float fA, bool bRandomizeColors, std::uint32_t iCount, float fBrightness, float fSize, bool bRandomizeSizes, float fLife); + static bool FxCreateParticle(FxParticleSystems eFxParticle, CVector& vecPosition, CVector& vecDirection, float fR, float fG, float fB, float fA, + bool bRandomizeColors, std::uint32_t iCount, float fBrightness, float fSize, bool bRandomizeSizes, float fLife); static CClientEffect* CreateEffect(CResource& Resource, const SString& strFxName, const CVector& vecPosition, bool bSoundEnable); // Sound funcs @@ -791,28 +804,28 @@ class CStaticFunctionDefinitions // Handling funcs static HandlingProperty GetVehicleHandlingEnum(std::string strProperty); - static bool GetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, float& fValue); - static bool GetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, CVector& vecValue); - static bool GetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, std::string& strValue); - static bool GetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, unsigned int& uiValue); - static bool GetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, unsigned char& ucValue); - static bool GetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, float& fValue); - static bool GetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, CVector& vecValue); - static bool GetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, std::string& strValue); - static bool GetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, unsigned int& uiValue); - static bool GetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, unsigned char& ucValue); - static bool ResetVehicleHandling(CClientVehicle* pVehicle); - static bool ResetVehicleHandlingProperty(CClientVehicle* pVehicle, HandlingProperty eProperty); - static bool SetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, float fValue); - static bool SetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, CVector vecValue); - static bool SetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, std::string strValue); - static bool SetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, unsigned int uiValue); - static bool SetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, unsigned char ucValue); - static bool SetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, float fValue); - static bool SetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, CVector vecValue); - static bool SetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, std::string strValue); - static bool SetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, unsigned int uiValue); - static bool SetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, unsigned char ucValue); + static bool GetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, float& fValue); + static bool GetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, CVector& vecValue); + static bool GetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, std::string& strValue); + static bool GetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, unsigned int& uiValue); + static bool GetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, unsigned char& ucValue); + static bool GetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, float& fValue); + static bool GetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, CVector& vecValue); + static bool GetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, std::string& strValue); + static bool GetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, unsigned int& uiValue); + static bool GetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, unsigned char& ucValue); + static bool ResetVehicleHandling(CClientVehicle* pVehicle); + static bool ResetVehicleHandlingProperty(CClientVehicle* pVehicle, HandlingProperty eProperty); + static bool SetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, float fValue); + static bool SetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, CVector vecValue); + static bool SetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, std::string strValue); + static bool SetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, unsigned int uiValue); + static bool SetVehicleHandling(CClientVehicle* pVehicle, HandlingProperty eProperty, unsigned char ucValue); + static bool SetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, float fValue); + static bool SetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, CVector vecValue); + static bool SetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, std::string strValue); + static bool SetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, unsigned int uiValue); + static bool SetEntryHandling(CHandlingEntry* pEntry, HandlingProperty eProperty, unsigned char ucValue); // Version funcs static unsigned long GetVersion(); diff --git a/Client/mods/deathmatch/logic/CSyncDebug.cpp b/Client/mods/deathmatch/logic/CSyncDebug.cpp index f3d63fb2091..c4ff77a0280 100644 --- a/Client/mods/deathmatch/logic/CSyncDebug.cpp +++ b/Client/mods/deathmatch/logic/CSyncDebug.cpp @@ -27,8 +27,8 @@ CSyncDebug::CSyncDebug(CClientManager* pManager) m_ulLastUpdateTime = CClientTime::GetTime(); m_uiLastPacketsSent = m_uiPacketsSent = stats.packetsSent; m_uiLastPacketsReceived = m_uiPacketsReceived = stats.packetsReceived; - m_uiLastBitsReceived = m_uiBitsReceived = (uint)stats.bytesReceived * 8; // stats.runningTotal [ NS_ACTUAL_BYTES_RECEIVED ] * 8; - m_uiLastBitsSent = m_uiBitsSent = (uint)stats.bytesSent * 8; // stats.runningTotal [ NS_ACTUAL_BYTES_SENT ] * 8; + m_uiLastBitsReceived = m_uiBitsReceived = (uint)stats.bytesReceived * 8; // stats.runningTotal [ NS_ACTUAL_BYTES_RECEIVED ] * 8; + m_uiLastBitsSent = m_uiBitsSent = (uint)stats.bytesSent * 8; // stats.runningTotal [ NS_ACTUAL_BYTES_SENT ] * 8; m_usFakeLagVariance = 0; m_usFakeLagPing = 0; diff --git a/Client/mods/deathmatch/logic/CSyncDebug.h b/Client/mods/deathmatch/logic/CSyncDebug.h index 5d7a6921e40..41a823ccf22 100644 --- a/Client/mods/deathmatch/logic/CSyncDebug.h +++ b/Client/mods/deathmatch/logic/CSyncDebug.h @@ -30,14 +30,14 @@ class CSyncDebug void OnPulse(); #else - CSyncDebug(CClientManager* pManager){}; + CSyncDebug(CClientManager* pManager) {}; - void Unreference(CClientPlayer& Player){}; + void Unreference(CClientPlayer& Player) {}; - void Attach(CClientPlayer& Player){}; - void Detach(){}; + void Attach(CClientPlayer& Player) {}; + void Detach() {}; - void OnPulse(){}; + void OnPulse() {}; #endif diff --git a/Client/mods/deathmatch/logic/CTransferBox.cpp b/Client/mods/deathmatch/logic/CTransferBox.cpp index 340832bdeee..546fbbcb3bf 100644 --- a/Client/mods/deathmatch/logic/CTransferBox.cpp +++ b/Client/mods/deathmatch/logic/CTransferBox.cpp @@ -56,7 +56,7 @@ void CTransferBox::CreateTransferWindow() m_window->SetCloseButtonEnabled(false); m_window->SetSizingEnabled(false); m_window->SetPosition(CVector2D(screenSize.fX * 0.5f - fTransferBoxWidth * 0.5f, screenSize.fY * 0.85f - TRANSFERBOX_HEIGHT * 0.5f)); - m_window->SetSize(CVector2D(fTransferBoxWidth, TRANSFERBOX_HEIGHT)); // relative 0.35, 0.225 + m_window->SetSize(CVector2D(fTransferBoxWidth, TRANSFERBOX_HEIGHT)); // relative 0.35, 0.225 m_progressBar.reset(m_GUI->CreateProgressBar(m_window.get())); m_progressBar->SetPosition(CVector2D(0, TRANSFERBOX_YSTART)); diff --git a/Client/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp b/Client/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp index 7e4d647c7f7..b4dbe67ea88 100644 --- a/Client/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp +++ b/Client/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp @@ -16,7 +16,7 @@ using std::list; extern CClientGame* g_pClientGame; -#define UNOCCUPIED_VEHICLE_SYNC_RATE ( g_TickRateSettings.iUnoccupiedVehicle ) +#define UNOCCUPIED_VEHICLE_SYNC_RATE (g_TickRateSettings.iUnoccupiedVehicle) CUnoccupiedVehicleSync::CUnoccupiedVehicleSync(CClientVehicleManager* pVehicleManager) { diff --git a/Client/mods/deathmatch/logic/CUnoccupiedVehicleSync.h b/Client/mods/deathmatch/logic/CUnoccupiedVehicleSync.h index 749ff5c9ea4..cf4d338bf3d 100644 --- a/Client/mods/deathmatch/logic/CUnoccupiedVehicleSync.h +++ b/Client/mods/deathmatch/logic/CUnoccupiedVehicleSync.h @@ -13,7 +13,7 @@ #include #include "CDeathmatchVehicle.h" -#define MIN_ROTATION_DIFF 0.1 +#define MIN_ROTATION_DIFF 0.1 class CUnoccupiedVehicleSync { public: diff --git a/Client/mods/deathmatch/logic/CVehicleNames.cpp b/Client/mods/deathmatch/logic/CVehicleNames.cpp index 32bcc3e7e6f..5de6553d859 100644 --- a/Client/mods/deathmatch/logic/CVehicleNames.cpp +++ b/Client/mods/deathmatch/logic/CVehicleNames.cpp @@ -17,7 +17,7 @@ const char* const szVehicleNameEmpty = ""; struct SVehicleName { const char* szName; - const char* szName_replaced; // Compatability + const char* szName_replaced; // Compatability }; static const SFixedArray VehicleNames = {{{"Landstalker"}, @@ -122,8 +122,8 @@ static const SFixedArray VehicleNames = {{{"Landstalker"}, {"Benson"}, {"Mesa"}, {"RC Goblin"}, - {"Hotring Racer 3"}, {"Hotring Racer 2"}, + {"Hotring Racer 3"}, {"Bloodring Banger"}, {"Rancher Lure"}, {"Super GT"}, @@ -225,7 +225,7 @@ static const SFixedArray VehicleNames = {{{"Landstalker"}, {"Alpha"}, {"Phoenix"}, {"Glendale Damaged"}, - {"Sadler", "Sadler Damaged"}, + {"Sadler Damaged", "Sadler"}, {"Baggage Trailer (covered)"}, {"Baggage Trailer (Uncovered)"}, {"Trailer (Stairs)"}, diff --git a/Client/mods/deathmatch/logic/CVehicleUpgrades.cpp b/Client/mods/deathmatch/logic/CVehicleUpgrades.cpp index da592b41ef1..2b7709cbb19 100644 --- a/Client/mods/deathmatch/logic/CVehicleUpgrades.cpp +++ b/Client/mods/deathmatch/logic/CVehicleUpgrades.cpp @@ -64,6 +64,11 @@ bool CVehicleUpgrades::IsUpgradeCompatible(unsigned short usUpgrade) return false; unsigned short usModel = m_pVehicle->GetModel(); + auto* modelInfo = g_pGame->GetModelInfo(usModel); + + if (modelInfo && modelInfo->GetParentID() != 0) + usModel = static_cast(modelInfo->GetParentID()); + // Wheels should be compatible with any vehicle which have wheels, except // bike/bmx (they're buggy). Vortex is technically a car, but it has no // wheels. @@ -79,6 +84,13 @@ bool CVehicleUpgrades::IsUpgradeCompatible(unsigned short usUpgrade) if (us == VEHICLEUPGRADE_NITRO_5X || us == VEHICLEUPGRADE_NITRO_2X || us == VEHICLEUPGRADE_NITRO_10X || us == VEHICLEUPGRADE_HYDRAULICS) return true; + if (us == 1000 || us == 1001 || us == 1002 || us == 1003 || us == 1014 || /* spoiler */ + us == 1015 || us == 1016 || us == 1023 || us == 1049 || us == 1050 || us == 1058 || us == 1060 || us == 1138 || us == 1139 || us == 1146 || + us == 1147 || us == 1158 || us == 1162 || us == 1163 || us == 1164) + { + return true; + } + bool bReturn = false; switch (usModel) { @@ -86,7 +98,7 @@ bool CVehicleUpgrades::IsUpgradeCompatible(unsigned short usUpgrade) bReturn = (us == 1020 || us == 1021 || us == 1019 || us == 1018 || us == 1013 || us == 1024 || us == 1008 || us == 1009 || us == 1010); break; case 401: - bReturn = (us == 1005 || us == 1004 || us == 1142 || us == 1143 || us == 1144 || us == 114 || us == 1020 || us == 1019 || us == 1013 || + bReturn = (us == 1005 || us == 1004 || us == 1142 || us == 1143 || us == 1144 || us == 1145 || us == 1020 || us == 1019 || us == 1013 || us == 1008 || us == 1009 || us == 1010 || us == 1006 || us == 1001 || us == 1003 || us == 1017 || us == 1007); break; case 402: @@ -362,7 +374,10 @@ bool CVehicleUpgrades::IsUpgradeCompatible(unsigned short usUpgrade) if (GetSlotFromUpgrade(us, ucSlot) && (bReturn || ucSlot == 2)) { // Get our model supported upgrades - SVehicleSupportedUpgrades supportedUpgrades = m_pVehicle->GetModelInfo()->GetVehicleSupportedUpgrades(); + auto* info = g_pGame->GetModelInfo(usModel); + modelInfo = info ? info : m_pVehicle->GetModelInfo(); + SVehicleSupportedUpgrades supportedUpgrades = modelInfo->GetVehicleSupportedUpgrades(); + // Initialisation happens when we load the clump which is done when we require a specific model rather than in bulk if (supportedUpgrades.m_bInitialised == true) { @@ -463,17 +478,17 @@ bool CVehicleUpgrades::GetSlotFromUpgrade(unsigned short us, unsigned char& ucSl ucSlot = 3; return true; } - if (us == 1115 || us == 1116) // front bullbars + if (us == 1115 || us == 1116) // front bullbars { ucSlot = 4; return true; } - if (us == 1109 || us == 1110) // rear bullbars + if (us == 1109 || us == 1110) // rear bullbars { ucSlot = 5; return true; } - if (us == 1013 || us == 1024) // lamps + if (us == 1013 || us == 1024) // lamps { ucSlot = 6; return true; @@ -485,17 +500,17 @@ bool CVehicleUpgrades::GetSlotFromUpgrade(unsigned short us, unsigned char& ucSl ucSlot = 7; return true; } - if (us == 1008 || us == 1009 || us == 1010) // nitro + if (us == 1008 || us == 1009 || us == 1010) // nitro { ucSlot = 8; return true; } - if (us == 1087) // hydraulics + if (us == 1087) // hydraulics { ucSlot = 9; return true; } - if (us == 1086) // stereo + if (us == 1086) // stereo { ucSlot = 10; return true; diff --git a/Client/mods/deathmatch/logic/CWeaponNames.cpp b/Client/mods/deathmatch/logic/CWeaponNames.cpp index 0905f3901ff..daf688b9c5d 100644 --- a/Client/mods/deathmatch/logic/CWeaponNames.cpp +++ b/Client/mods/deathmatch/logic/CWeaponNames.cpp @@ -9,6 +9,7 @@ *****************************************************************************/ #include +#include "SharedUtil.Misc.h" using namespace std; @@ -33,10 +34,10 @@ static const SWeaponName _WeaponNames[] = {{"Fist"}, {"Poolstick"}, {"Katana"}, {"Chainsaw"}, + {"Purple Dildo"}, {"Dildo"}, - {"Dildo"}, - {"Vibrator"}, {"Vibrator"}, + {"Silver Vibrator"}, {"Flower"}, {"Cane"}, {"Grenade"}, @@ -97,11 +98,11 @@ unsigned char CWeaponNames::GetWeaponID(const char* szName) return 0xFF; // Look for it in our table - for (unsigned int i = 0; i < NUMELMS(WeaponNames); i++) + for (unsigned char i = 0; i < NUMELMS(WeaponNames); i++) { if (stricmp(szName, WeaponNames[i].szName) == 0) { - return i; + return static_cast(i); } } diff --git a/Client/mods/deathmatch/logic/Config.h b/Client/mods/deathmatch/logic/Config.h index a5348e0c40b..83cdb7c77df 100644 --- a/Client/mods/deathmatch/logic/Config.h +++ b/Client/mods/deathmatch/logic/Config.h @@ -41,7 +41,7 @@ class CVaPassNext CVaPassNext(va_list& args) { try - { // to avoid access violation + { // to avoid access violation memcpy(&svapassnext, args, sizeof(svapassnext)); } catch (...) @@ -62,7 +62,7 @@ class CVaPassNext // Min and max number of characters in chat echos #define MIN_CHATECHO_LENGTH 1 -#define MAX_CHATECHO_LENGTH (MAX_CHAT_LENGTH + MAX_PLAYER_NICK_LENGTH + 2) // +2 is for ": " between player nick and the message +#define MAX_CHATECHO_LENGTH (MAX_CHAT_LENGTH + MAX_PLAYER_NICK_LENGTH + 2) // +2 is for ": " between player nick and the message // Min and max number of characters in outputChatBox from the server #define MIN_OUTPUTCHATBOX_LENGTH 1 @@ -102,7 +102,7 @@ class CVaPassNext #define MAX_MAPNAME_LENGTH 255 // Timeouts -#define NET_CONNECT_TIMEOUT 30000 +#define NET_CONNECT_TIMEOUT 30000 #define CLIENT_VERIFICATION_TIMEOUT 10000 // Vehicle in-out delay (to prevent messed up like 1765/1956/1880 diff --git a/Client/mods/deathmatch/logic/lua/CLuaArgument.cpp b/Client/mods/deathmatch/logic/lua/CLuaArgument.cpp index 7ed7b463c38..819e0854f83 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaArgument.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaArgument.cpp @@ -11,15 +11,15 @@ #include "StdInc.h" #include "net/SyncStructures.h" -#define ARGUMENT_TYPE_INT 9 -#define ARGUMENT_TYPE_FLOAT 10 +#define ARGUMENT_TYPE_INT 9 +#define ARGUMENT_TYPE_FLOAT 10 #ifndef VERIFY_ENTITY -#define VERIFY_ENTITY(entity) (CStaticFunctionDefinitions::GetRootElement()->IsMyChild(entity,true)&&!entity->IsBeingDeleted()) + #define VERIFY_ENTITY(entity) (CStaticFunctionDefinitions::GetRootElement()->IsMyChild(entity, true) && !entity->IsBeingDeleted()) #endif #ifndef VERIFY_RESOURCE -#define VERIFY_RESOURCE(resource) (g_pClientGame->GetResourceManager()->Exists(resource)) + #define VERIFY_RESOURCE(resource) (g_pClientGame->GetResourceManager()->Exists(resource)) #endif extern CClientGame* g_pClientGame; @@ -27,7 +27,7 @@ extern CClientGame* g_pClientGame; using namespace std; // Prevent the warning issued when doing unsigned short -> void* -#pragma warning(disable:4312) +#pragma warning(disable : 4312) CLuaArgument::CLuaArgument() { @@ -35,6 +35,7 @@ CLuaArgument::CLuaArgument() m_iIndex = -1; m_pTableData = NULL; m_pUserData = NULL; + m_bWeakTableRef = false; } CLuaArgument::CLuaArgument(const CLuaArgument& Argument, CFastHashMap* pKnownTables) @@ -46,7 +47,10 @@ CLuaArgument::CLuaArgument(const CLuaArgument& Argument, CFastHashMap* pKnownTables) { + m_iType = LUA_TNIL; m_pTableData = NULL; + m_pUserData = NULL; + m_bWeakTableRef = false; ReadFromBitStream(bitStream, pKnownTables); } @@ -334,6 +338,13 @@ void CLuaArgument::ReadString(const std::string_view& string) m_strString = std::string{string}; } +void CLuaArgument::ReadString(const CStringName& string) +{ + m_iType = LUA_TSTRING; + DeleteTableData(); + m_strString = string.ToString(); +} + void CLuaArgument::ReadString(const char* string) { m_iType = LUA_TSTRING; @@ -387,65 +398,71 @@ CClientEntity* CLuaArgument::GetElement() const void CLuaArgument::Push(lua_State* luaVM, CFastHashMap* pKnownTables) const { - // WARNING: - // Stuff using this function is kinda unsafe, we expect - // it to successfully push something, when it actually may not, - // corrupting the Lua stack - if (m_iType != LUA_TNONE) + // Make sure the stack has enough room + LUA_CHECKSTACK(luaVM, 1); + + // Push it depending on the type + switch (m_iType) { - // Make sure the stack has enough room - LUA_CHECKSTACK(luaVM, 1); + case LUA_TNIL: + { + lua_pushnil(luaVM); + break; + } - // Push it depending on the type - switch (m_iType) + case LUA_TBOOLEAN: { - case LUA_TNIL: - { - lua_pushnil(luaVM); - break; - } + lua_pushboolean(luaVM, m_bBoolean); + break; + } - case LUA_TBOOLEAN: - { - lua_pushboolean(luaVM, m_bBoolean); - break; - } + case LUA_TUSERDATA: + case LUA_TLIGHTUSERDATA: + { + lua_pushuserdata(luaVM, m_pUserData); + break; + } - case LUA_TUSERDATA: - case LUA_TLIGHTUSERDATA: - { - lua_pushuserdata(luaVM, m_pUserData); - break; - } + case LUA_TNUMBER: + { + lua_pushnumber(luaVM, m_Number); + break; + } - case LUA_TNUMBER: + case LUA_TTABLE: + { + if (!m_pTableData) { - lua_pushnumber(luaVM, m_Number); + lua_pushnil(luaVM); break; } - case LUA_TTABLE: + int* pTableId; + if (pKnownTables && (pTableId = MapFind(*pKnownTables, m_pTableData))) { - int* pTableId; - if (pKnownTables && (pTableId = MapFind(*pKnownTables, m_pTableData))) - { - lua_getfield(luaVM, LUA_REGISTRYINDEX, "cache"); - lua_pushnumber(luaVM, *pTableId); - lua_gettable(luaVM, -2); - lua_remove(luaVM, -2); - } - else - { - m_pTableData->PushAsTable(luaVM, pKnownTables); - } - break; + lua_getfield(luaVM, LUA_REGISTRYINDEX, "cache"); + lua_pushnumber(luaVM, *pTableId); + lua_gettable(luaVM, -2); + lua_remove(luaVM, -2); } - - case LUA_TSTRING: + else { - lua_pushlstring(luaVM, m_strString.c_str(), m_strString.length()); - break; + m_pTableData->PushAsTable(luaVM, pKnownTables); } + break; + } + + case LUA_TSTRING: + { + lua_pushlstring(luaVM, m_strString.c_str(), m_strString.length()); + break; + } + + default: + { + // Unexpected type, keep the stack balanced for callers + lua_pushnil(luaVM); + break; } } } @@ -454,148 +471,160 @@ void CLuaArgument::Push(lua_State* luaVM, CFastHashMap* pKn bool CLuaArgument::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables) { DeleteTableData(); + m_iType = LUA_TNIL; SLuaTypeSync type; // Read out the type - if (bitStream.Read(&type)) + if (!bitStream.Read(&type)) + return false; + + // Depending on what type... + switch (type.data.ucType) { - // Depending on what type... - switch (type.data.ucType) + // Nil type + case LUA_TNIL: { - // Nil type - case LUA_TNIL: - { - m_iType = LUA_TNIL; - break; - } + m_iType = LUA_TNIL; + break; + } - // Boolean type - case LUA_TBOOLEAN: - { - bool bValue; - if (bitStream.ReadBit(bValue)) - ReadBool(bValue); - break; - } + // Boolean type + case LUA_TBOOLEAN: + { + bool bValue; + if (bitStream.ReadBit(bValue)) + ReadBool(bValue); + break; + } - // Number type - case LUA_TNUMBER: + // Number type + case LUA_TNUMBER: + { + if (bitStream.ReadBit()) { + // Should be in high precision mode + dassert(g_pClientGame->IsHighFloatPrecision()); if (bitStream.ReadBit()) { - // Should be in high precision mode - dassert(g_pClientGame->IsHighFloatPrecision()); - if (bitStream.ReadBit()) - { - double dNum; - if (bitStream.Read(dNum)) - ReadNumber(dNum); - } - else - { - float fNum; - if (bitStream.Read(fNum)) - ReadNumber(RoundFromFloatSource(fNum)); - } + double dNum; + if (bitStream.Read(dNum)) + ReadNumber(dNum); } else { - int iNum; - if (bitStream.ReadCompressed(iNum)) - ReadNumber(iNum); + float fNum; + if (bitStream.Read(fNum)) + ReadNumber(RoundFromFloatSource(fNum)); } - break; } + else + { + int iNum; + if (bitStream.ReadCompressed(iNum)) + ReadNumber(iNum); + } + break; + } - // Table type - case LUA_TTABLE: + // Table type + case LUA_TTABLE: + { + m_pTableData = new CLuaArguments(); + if (!m_pTableData->ReadFromBitStream(bitStream, pKnownTables)) { - m_pTableData = new CLuaArguments(bitStream, pKnownTables); - m_bWeakTableRef = false; - m_iType = LUA_TTABLE; - m_pTableData->ValidateTableKeys(); - break; + DeleteTableData(); + return false; } + m_bWeakTableRef = false; + m_iType = LUA_TTABLE; + m_pTableData->ValidateTableKeys(); + break; + } - // Table reference (self-referencing tables) - case LUA_TTABLEREF: + // Table reference (self-referencing tables) + case LUA_TTABLEREF: + { + unsigned long ulTableRef; + if (bitStream.ReadCompressed(ulTableRef)) { - unsigned long ulTableRef; - if (bitStream.ReadCompressed(ulTableRef)) + if (pKnownTables && ulTableRef < pKnownTables->size()) { - if (pKnownTables && ulTableRef < pKnownTables->size()) - { - m_pTableData = pKnownTables->at(ulTableRef); - m_bWeakTableRef = true; - m_iType = LUA_TTABLE; - } + m_pTableData = pKnownTables->at(ulTableRef); + m_bWeakTableRef = true; + m_iType = LUA_TTABLE; } - break; } + break; + } - // String type - case LUA_TSTRING: + // String type + case LUA_TSTRING: + { + // Read out the string length + unsigned short usLength; + if (bitStream.ReadCompressed(usLength) && usLength) { - // Read out the string length - unsigned short usLength; - if (bitStream.ReadCompressed(usLength) && usLength) - { - // Allocate a buffer and read the string into it - char* szValue = new char[usLength + 1]; - if (bitStream.Read(szValue, usLength)) - { - // Put it into us - ReadString(std::string(szValue, usLength)); - } + if (!bitStream.CanReadNumberOfBytes(usLength)) + return false; - // Delete the buffer - delete[] szValue; + // Allocate a buffer and read the string into it + char* szValue = new char[usLength + 1]; + if (bitStream.Read(szValue, usLength)) + { + // Put it into us + ReadString(std::string(szValue, usLength)); } - else - ReadString(""); - break; + // Delete the buffer + delete[] szValue; } + else + ReadString(""); - // Long string type - case LUA_TSTRING_LONG: + break; + } + + // Long string type + case LUA_TSTRING_LONG: + { + // Read out the string length + uint uiLength; + if (bitStream.ReadCompressed(uiLength) && uiLength) { - // Read out the string length - uint uiLength; - if (bitStream.ReadCompressed(uiLength) && uiLength) - { - bitStream.AlignReadToByteBoundary(); + if (!bitStream.CanReadNumberOfBytes(uiLength)) + return false; - // Allocate a buffer and read the string into it - char* szValue = new char[uiLength + 1]; - assert(szValue); - if (bitStream.Read(szValue, uiLength)) - { - // Put it into us - ReadString(std::string(szValue, uiLength)); - } + bitStream.AlignReadToByteBoundary(); - // Delete the buffer - delete[] szValue; + // Allocate a buffer and read the string into it + char* szValue = new char[uiLength + 1]; + assert(szValue); + if (bitStream.Read(szValue, uiLength)) + { + // Put it into us + ReadString(std::string(szValue, uiLength)); } - else - ReadString(""); - break; + // Delete the buffer + delete[] szValue; } + else + ReadString(""); - // Element type - case LUA_TLIGHTUSERDATA: - case LUA_TUSERDATA: + break; + } + + // Element type + case LUA_TLIGHTUSERDATA: + case LUA_TUSERDATA: + { + // Read out the elemnt ID + ElementID ElementID; + if (bitStream.Read(ElementID)) { - // Read out the elemnt ID - ElementID ElementID; - if (bitStream.Read(ElementID)) - { - ReadElementID(ElementID); - } - break; + ReadElementID(ElementID); } + break; } } return true; @@ -880,9 +909,9 @@ json_object* CLuaArgument::WriteToJSONObject(bool bSerialize, CFastHashMapGetScriptDebugging()->LogError(NULL, "Couldn't convert userdata argument to JSON, elements not allowed for this function."); - else if (!bSerialize) // eg toJSON() with invalid element + else if (!bSerialize) // eg toJSON() with invalid element g_pClientGame->GetScriptDebugging()->LogError( NULL, "Couldn't convert userdata argument to JSON, only valid resources can be included for this function."); else @@ -1031,7 +1060,7 @@ bool CLuaArgument::ReadFromJSONObject(json_object* object, std::vectorGetResourceManager()->GetResource(strString.c_str() + 3); if (resource) @@ -1063,7 +1092,7 @@ bool CLuaArgument::ReadFromJSONObject(json_object* object, std::vector(atol(strString.c_str() + 3)); if (pKnownTables && ulTableID < pKnownTables->size()) diff --git a/Client/mods/deathmatch/logic/lua/CLuaArgument.h b/Client/mods/deathmatch/logic/lua/CLuaArgument.h index 3cb5b451904..c861cb57a80 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaArgument.h +++ b/Client/mods/deathmatch/logic/lua/CLuaArgument.h @@ -12,16 +12,17 @@ extern "C" { - #include "lua.h" +#include "lua.h" } #include #include #include "json.h" +#include "CStringName.h" class CClientEntity; class CLuaArguments; -#define LUA_TTABLEREF 9 +#define LUA_TTABLEREF 9 #define LUA_TSTRING_LONG 10 class CLuaArgument @@ -42,6 +43,7 @@ class CLuaArgument void ReadNumber(double dNumber); void ReadString(const std::string& string); void ReadString(const std::string_view& string); + void ReadString(const CStringName& string); void ReadString(const char* string); void ReadElement(CClientEntity* pElement); void ReadScriptID(uint uiScriptID); diff --git a/Client/mods/deathmatch/logic/lua/CLuaArguments.cpp b/Client/mods/deathmatch/logic/lua/CLuaArguments.cpp index 6b4de4ec33d..911eef27d94 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaArguments.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaArguments.cpp @@ -15,14 +15,15 @@ using namespace std; #ifndef VERIFY_ENTITY -#define VERIFY_ENTITY(entity) (CStaticFunctionDefinitions::GetRootElement()->IsMyChild(entity,true)&&!entity->IsBeingDeleted()) + #define VERIFY_ENTITY(entity) (CStaticFunctionDefinitions::GetRootElement()->IsMyChild(entity, true) && !entity->IsBeingDeleted()) #endif extern CClientGame* g_pClientGame; CLuaArguments::CLuaArguments(NetBitStreamInterface& bitStream, std::vector* pKnownTables) { - ReadFromBitStream(bitStream, pKnownTables); + if (!ReadFromBitStream(bitStream, pKnownTables)) + DeleteArguments(); } CLuaArguments::CLuaArguments(const CLuaArguments& Arguments, CFastHashMap* pKnownTables) @@ -114,10 +115,10 @@ void CLuaArguments::ReadTable(lua_State* luaVM, int iIndexBegin, CFastHashMap::const_iterator iter = m_Arguments.begin(); for (; iter != m_Arguments.end() && (iter + 1) != m_Arguments.end(); iter++) { - (*iter)->Push(luaVM, pKnownTables); // index + (*iter)->Push(luaVM, pKnownTables); // index iter++; - (*iter)->Push(luaVM, pKnownTables); // value + (*iter)->Push(luaVM, pKnownTables); // value lua_settable(luaVM, -3); } @@ -225,7 +226,7 @@ bool CLuaArguments::Call(CLuaMain* pLuaMain, const CLuaFunctionRef& iLuaFunction while (lua_gettop(luaVM) - luaStackPointer > 0) lua_pop(luaVM, 1); - return false; // the function call failed + return false; // the function call failed } else { @@ -289,7 +290,7 @@ bool CLuaArguments::CallGlobal(CLuaMain* pLuaMain, const char* szFunction, CLuaA while (lua_gettop(luaVM) - luaStackPointer > 0) lua_pop(luaVM, 1); - return false; // the function call failed + return false; // the function call failed } else { @@ -351,6 +352,14 @@ CLuaArgument* CLuaArguments::PushString(const std::string_view& string) return arg; } +CLuaArgument* CLuaArguments::PushString(const CStringName& string) +{ + CLuaArgument* arg = new CLuaArgument(); + arg->ReadString(string); + m_Arguments.push_back(arg); + return arg; +} + CLuaArgument* CLuaArguments::PushString(const char* string) { CLuaArgument* arg = new CLuaArgument(); @@ -463,10 +472,26 @@ bool CLuaArguments::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vec unsigned int uiNumArgs; if (bitStream.ReadCompressed(uiNumArgs)) { + // Each argument needs at least 4 bits (SLuaTypeSync), reject obviously corrupt counts + int unreadBits = bitStream.GetNumberOfUnreadBits(); + if (unreadBits < 0 || uiNumArgs > static_cast(unreadBits) / 4) + { + if (bKnownTablesCreated) + delete pKnownTables; + return false; + } + pKnownTables->push_back(this); for (unsigned int ui = 0; ui < uiNumArgs; ++ui) { - CLuaArgument* pArgument = new CLuaArgument(bitStream, pKnownTables); + CLuaArgument* pArgument = new CLuaArgument(); + if (!pArgument->ReadFromBitStream(bitStream, pKnownTables)) + { + delete pArgument; + if (bKnownTablesCreated) + delete pKnownTables; + return false; + } m_Arguments.push_back(pArgument); } } @@ -512,7 +537,7 @@ bool CLuaArguments::WriteToJSONString(std::string& strJSON, bool bSerialize, int if (my_array) { strJSON = json_object_to_json_string_ext(my_array, flags); - json_object_put(my_array); // dereference - causes a crash, is actually commented out in the example too + json_object_put(my_array); // dereference - causes a crash, is actually commented out in the example too return true; } return false; @@ -547,49 +572,53 @@ json_object* CLuaArguments::WriteTableToJSONObject(bool bSerialize, CFastHashMap bKnownTablesCreated = true; } - pKnownTables->insert(std::make_pair(this, pKnownTables->size())); + pKnownTables->insert({this, pKnownTables->size()}); - bool bIsArray = true; - unsigned int iArrayPos = 1; // lua arrays are 1 based - vector::const_iterator iter = m_Arguments.begin(); + bool bIsArray = true; + std::vector> vecSortedArguments; // lua arrays are not necessarily sorted + std::vector::const_iterator iter = m_Arguments.begin(); for (; iter != m_Arguments.end(); iter += 2) { CLuaArgument* pArgument = *iter; if (pArgument->GetType() == LUA_TNUMBER) { - double num = pArgument->GetNumber(); - unsigned int iNum = static_cast(num); - if (num == iNum) - { - if (iArrayPos != iNum) // check if the value matches its index in the table - { - bIsArray = false; - break; - } - } - else - { - bIsArray = false; - break; - } + double const num = pArgument->GetNumber(); + auto const iNum = static_cast(num); + + vecSortedArguments.push_back({iNum, *(iter + 1)}); } else { bIsArray = false; break; } - iArrayPos++; } - if (bIsArray) + if (bIsArray && !vecSortedArguments.empty()) // the table could possibly be an array { - json_object* my_array = json_object_new_array(); - vector::const_iterator iter = m_Arguments.begin(); - for (; iter != m_Arguments.end(); iter++) + // sort the table based on the keys (already handled correctly by std::pair) + std::sort(vecSortedArguments.begin(), vecSortedArguments.end()); + + // only the first and last element are checked, everything else is correct by default because the vector was sorted + // the last key should match the size of vecSortedArguments to ensure there are no gaps in this array-like table + auto const iFirstKey = vecSortedArguments.front().first; + auto const iLastKey = vecSortedArguments.back().first; + + auto const iFirstArrayPos = 1U; // lua arrays are 1 based + auto const iLastArrayPos = static_cast(vecSortedArguments.size()); + + if (iFirstKey != iFirstArrayPos || iLastKey != iLastArrayPos) { - iter++; // skip the key values - CLuaArgument* pArgument = *iter; - json_object* object = pArgument->WriteToJSONObject(bSerialize, pKnownTables); + bIsArray = false; + } + } + + if (bIsArray) // the table is definitely an array + { + json_object* my_array = json_object_new_array(); + for (auto const& [iKey, pArgument] : vecSortedArguments) + { + json_object* object = pArgument->WriteToJSONObject(bSerialize, pKnownTables); if (object) { json_object_array_add(my_array, object); @@ -612,11 +641,11 @@ json_object* CLuaArguments::WriteTableToJSONObject(bool bSerialize, CFastHashMap char szKey[255]; szKey[0] = '\0'; CLuaArgument* pArgument = *iter; - if (!pArgument->WriteToString(szKey, 255)) // index + if (!pArgument->WriteToString(szKey, 255)) // index break; iter++; pArgument = *iter; - json_object* object = pArgument->WriteToJSONObject(bSerialize, pKnownTables); // value + json_object* object = pArgument->WriteToJSONObject(bSerialize, pKnownTables); // value if (object) { @@ -660,11 +689,11 @@ bool CLuaArguments::ReadFromJSONString(const char* szJSON) json_object* arrayObject = json_object_array_get_idx(object, i); CLuaArgument* pArgument = new CLuaArgument(); bSuccess = pArgument->ReadFromJSONObject(arrayObject, &knownTables); - m_Arguments.push_back(pArgument); // then the value + m_Arguments.push_back(pArgument); // then the value if (!bSuccess) break; } - json_object_put(object); // dereference + json_object_put(object); // dereference return bSuccess; } else if (json_object_get_type(object) == json_type_object) @@ -672,12 +701,12 @@ bool CLuaArguments::ReadFromJSONString(const char* szJSON) std::vector knownTables; CLuaArgument* pArgument = new CLuaArgument(); bool bSuccess = pArgument->ReadFromJSONObject(object, &knownTables); - m_Arguments.push_back(pArgument); // value + m_Arguments.push_back(pArgument); // value json_object_put(object); return bSuccess; } - json_object_put(object); // dereference + json_object_put(object); // dereference } // else // g_pClientGame->GetScriptDebugging()->LogError ( "Could not parse invalid JSON object."); @@ -706,9 +735,9 @@ bool CLuaArguments::ReadFromJSONObject(json_object* object, std::vectorReadString(key); - m_Arguments.push_back(pArgument); // push the key first + m_Arguments.push_back(pArgument); // push the key first pArgument = new CLuaArgument(); - bSuccess = pArgument->ReadFromJSONObject(val, pKnownTables); // then the value + bSuccess = pArgument->ReadFromJSONObject(val, pKnownTables); // then the value m_Arguments.push_back(pArgument); if (!bSuccess) break; @@ -744,12 +773,12 @@ bool CLuaArguments::ReadFromJSONArray(json_object* object, std::vectorReadNumber(i + 1); // push the key + pArgument->ReadNumber(i + 1); // push the key m_Arguments.push_back(pArgument); pArgument = new CLuaArgument(); bSuccess = pArgument->ReadFromJSONObject(arrayObject, pKnownTables); - m_Arguments.push_back(pArgument); // then the valoue + m_Arguments.push_back(pArgument); // then the valoue if (!bSuccess) break; } diff --git a/Client/mods/deathmatch/logic/lua/CLuaArguments.h b/Client/mods/deathmatch/logic/lua/CLuaArguments.h index 45ec796cbba..c6a7df10b9f 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaArguments.h +++ b/Client/mods/deathmatch/logic/lua/CLuaArguments.h @@ -12,7 +12,7 @@ extern "C" { - #include "lua.h" +#include "lua.h" } #include @@ -57,6 +57,7 @@ class CLuaArguments CLuaArgument* PushNumber(double dNumber); CLuaArgument* PushString(const std::string& string); CLuaArgument* PushString(const std::string_view& string); + CLuaArgument* PushString(const CStringName& string); CLuaArgument* PushString(const char* string); CLuaArgument* PushElement(CClientEntity* pElement); CLuaArgument* PushArgument(const CLuaArgument& argument); diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Event.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Event.cpp index 183abe241d2..7bdbc0e2aad 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Event.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Event.cpp @@ -71,7 +71,7 @@ int CLuaFunctionDefs::AddEventHandler(lua_State* luaVM) } if (!StringToEnum(strPriority, eventPriority)) - argStream.SetTypeError(GetEnumTypeName(eventPriority), 5); // priority is argument #5 + argStream.SetTypeError(GetEnumTypeName(eventPriority), 5); // priority is argument #5 } if (!argStream.HasErrors()) diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Input.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Input.cpp index 00256a1f72a..2dc8e42bcb7 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Input.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Input.cpp @@ -210,7 +210,7 @@ int CLuaFunctionDefs::UnbindKey(lua_State* luaVM) CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); if (pLuaMain) { - if (argStream.NextIsString(1)) // Check if has command + if (argStream.NextIsString(1)) // Check if has command { // bool unbindKey ( string key, string keyState, string command ) SString strResource = pLuaMain->GetResource()->GetName(); @@ -304,7 +304,7 @@ int CLuaFunctionDefs::SetAnalogControlState(lua_State* luaVM) // bool setAnalogControlState ( string controlName [, float state][, bFrameForced] ) SString strControlState = ""; float fState = 0.0f; - bool bForceOverrideNextFrame = false; // if user input effect should be forcefully overriden for the next frame + bool bForceOverrideNextFrame = false; // if user input effect should be forcefully overriden for the next frame CScriptArgReader argStream(luaVM); argStream.ReadString(strControlState); diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Util.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Util.cpp index 978fb139e8d..1bdcfeb7c40 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Util.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Util.cpp @@ -12,7 +12,7 @@ int CLuaFunctionDefs::GetValidPedModels(lua_State* luaVM) { - bool includeCustom; + bool includeCustom; CScriptArgReader argStream(luaVM); argStream.ReadBool(includeCustom, true); @@ -235,16 +235,16 @@ int CLuaFunctionDefs::GetKeyboardLayout(lua_State* luaVM) { switch (readingLayoutValue) { - case 0: // Left to right (English) + case 0: // Left to right (English) readingLayout = "ltr"; break; - case 1: // Right to left (Arabic, Hebrew) + case 1: // Right to left (Arabic, Hebrew, and Persian) readingLayout = "rtl"; break; - case 2: // Vertical top to bottom with columns to the left and also left to right (Japanese) + case 2: // Vertical top to bottom with columns to the left and also left to right (Japanese) readingLayout = "ttb-rtl-ltr"; break; - case 3: // Vertical top to bottom with columns proceeding to the right (Mongolian) + case 3: // Vertical top to bottom with columns proceeding to the right (Mongolian) readingLayout = "ttb-ltr"; break; default: @@ -293,7 +293,7 @@ int CLuaFunctionDefs::GetPerformanceStats(lua_State* luaVM) for (int c = 0; c < Result.ColumnCount(); c++) { const SString& name = Result.ColumnName(c); - lua_pushnumber(luaVM, c + 1); // row index number (starting at 1, not 0) + lua_pushnumber(luaVM, c + 1); // row index number (starting at 1, not 0) lua_pushlstring(luaVM, name.c_str(), name.length()); lua_settable(luaVM, -3); } @@ -301,10 +301,10 @@ int CLuaFunctionDefs::GetPerformanceStats(lua_State* luaVM) lua_newtable(luaVM); for (int r = 0; r < Result.RowCount(); r++) { - lua_newtable(luaVM); // new table - lua_pushnumber(luaVM, r + 1); // row index number (starting at 1, not 0) - lua_pushvalue(luaVM, -2); // value - lua_settable(luaVM, -4); // refer to the top level table + lua_newtable(luaVM); // new table + lua_pushnumber(luaVM, r + 1); // row index number (starting at 1, not 0) + lua_pushvalue(luaVM, -2); // value + lua_settable(luaVM, -4); // refer to the top level table for (int c = 0; c < Result.ColumnCount(); c++) { @@ -313,7 +313,7 @@ int CLuaFunctionDefs::GetPerformanceStats(lua_State* luaVM) lua_pushlstring(luaVM, cell.c_str(), cell.length()); lua_settable(luaVM, -3); } - lua_pop(luaVM, 1); // pop the inner table + lua_pop(luaVM, 1); // pop the inner table } return 2; } diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Voice.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Voice.cpp index 04a84ee5897..0ab5003465a 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Voice.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Voice.cpp @@ -15,4 +15,4 @@ int CLuaFunctionDefs::IsVoiceEnabled(lua_State* luaVM) { lua_pushboolean(luaVM, g_pClientGame->GetVoiceRecorder()->IsEnabled()); return 1; -} \ No newline at end of file +} diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.h b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.h index a6592f9df04..d2476b716e4 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.h @@ -18,7 +18,7 @@ class CLuaFunctionDefinitions; class CRegisteredCommands; -#define LUA_DECLARE(x) static int x ( lua_State * luaVM ); +#define LUA_DECLARE(x) static int x(lua_State* luaVM); class CLuaFunctionDefs { diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp index 1a538347626..7ae83f8bfbb 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -104,6 +104,9 @@ ADD_ENUM(HUD_MONEY, "money") ADD_ENUM(HUD_VEHICLE_NAME, "vehicle_name") ADD_ENUM(HUD_AREA_NAME, "area_name") ADD_ENUM(HUD_RADAR, "radar") +ADD_ENUM(HUD_RADAR_MAP, "radar_map") +ADD_ENUM(HUD_RADAR_BLIPS, "radar_blips") +ADD_ENUM(HUD_RADAR_ALTIMETER, "radar_altimeter") ADD_ENUM(HUD_CLOCK, "clock") ADD_ENUM(HUD_RADIO, "radio") ADD_ENUM(HUD_WANTED, "wanted") @@ -247,13 +250,13 @@ ADD_ENUM(WeaponProperty::WEAPON_WEAPON_RANGE, "weapon_range") ADD_ENUM(WeaponProperty::WEAPON_TARGET_RANGE, "target_range") ADD_ENUM(WeaponProperty::WEAPON_ACCURACY, "accuracy") ADD_ENUM(WeaponProperty::WEAPON_DAMAGE, "damage") -ADD_ENUM(WeaponProperty::WEAPON_LIFE_SPAN, "life_span") // Disabled for release -ADD_ENUM(WeaponProperty::WEAPON_FIRING_SPEED, "firing_speed") // Disabled for release -ADD_ENUM(WeaponProperty::WEAPON_SPREAD, "spread") // Disabled for release +ADD_ENUM(WeaponProperty::WEAPON_LIFE_SPAN, "life_span") // Disabled for release +ADD_ENUM(WeaponProperty::WEAPON_FIRING_SPEED, "firing_speed") // Disabled for release +ADD_ENUM(WeaponProperty::WEAPON_SPREAD, "spread") // Disabled for release ADD_ENUM(WeaponProperty::WEAPON_MAX_CLIP_AMMO, "maximum_clip_ammo") ADD_ENUM(WeaponProperty::WEAPON_MOVE_SPEED, "move_speed") ADD_ENUM(WeaponProperty::WEAPON_FLAGS, "flags") -ADD_ENUM(WeaponProperty::WEAPON_ANIM_GROUP, "anim_group") // Disabled for release +ADD_ENUM(WeaponProperty::WEAPON_ANIM_GROUP, "anim_group") // Disabled for release ADD_ENUM(WeaponProperty::WEAPON_ANIM_LOOP_START, "anim_loop_start") ADD_ENUM(WeaponProperty::WEAPON_ANIM_LOOP_STOP, "anim_loop_stop") @@ -317,7 +320,7 @@ IMPLEMENT_ENUM_BEGIN(ERenderFormat) ADD_ENUM(RFORMAT_UNKNOWN, "unknown") ADD_ENUM(RFORMAT_ARGB, "argb") ADD_ENUM(RFORMAT_XRGB, "xrgb") -ADD_ENUM(RFORMAT_RGB, "rgb") +ADD_ENUM(RFORMAT_RGB, "rgb") ADD_ENUM(RFORMAT_DXT1, "dxt1") ADD_ENUM(RFORMAT_DXT2, "dxt2") ADD_ENUM(RFORMAT_DXT3, "dxt3") @@ -488,11 +491,11 @@ IMPLEMENT_ENUM_BEGIN(eFontQuality) ADD_ENUM(FONT_QUALITY_DEFAULT, "default") ADD_ENUM(FONT_QUALITY_DRAFT, "draft") ADD_ENUM(FONT_QUALITY_PROOF, "proof") -#if( WINVER >= 0x0400 ) +#if (WINVER >= 0x0400) ADD_ENUM(FONT_QUALITY_NONANTIALIASED, "nonantialiased") ADD_ENUM(FONT_QUALITY_ANTIALIASED, "antialiased") #endif -#if( _WIN32_WINNT >= _WIN32_WINNT_WINXP ) +#if (_WIN32_WINNT >= _WIN32_WINNT_WINXP) ADD_ENUM(FONT_QUALITY_CLEARTYPE, "cleartype") ADD_ENUM(FONT_QUALITY_CLEARTYPE_NATURAL, "cleartype_natural") #endif @@ -570,17 +573,17 @@ ADD_ENUM(JSONPRETTY_TABS, "tabs") IMPLEMENT_ENUM_END("json-pretty-type") IMPLEMENT_ENUM_BEGIN(eCursorType) -ADD_ENUM(CURSORTYPE_NONE, "none") // cursor has no image -ADD_ENUM(CURSORTYPE_DEFAULT, "arrow") // default cursor -ADD_ENUM(CURSORTYPE_SIZING_NS, "sizing_ns") // N-S (up-down) sizing cursor -ADD_ENUM(CURSORTYPE_SIZING_EW, "sizing_ew") // E-W (left-right) sizing cursor -ADD_ENUM(CURSORTYPE_SIZING_NWSE, "sizing_nwse") // NW-SE diagonal sizing cursor -ADD_ENUM(CURSORTYPE_SIZING_NESW, "sizing_nesw") // NE-SW diagonal sizing cursor -ADD_ENUM(CURSORTYPE_SIZING_ESWE, "sizing_eswe") // ES-WE horizontal sizing cursor -ADD_ENUM(CURSORTYPE_MOVE, "move") // move cursor -ADD_ENUM(CURSORTYPE_DRAG, "container_drag") // drag container cursor (note: not in use) -ADD_ENUM(CURSORTYPE_SEG_MOVING, "segment_moving") // segment moving cursor (note: not in use) -ADD_ENUM(CURSORTYPE_SEG_SIZING, "segment_sizing") // segment sizing cursor (note: not in use) +ADD_ENUM(CURSORTYPE_NONE, "none") // cursor has no image +ADD_ENUM(CURSORTYPE_DEFAULT, "arrow") // default cursor +ADD_ENUM(CURSORTYPE_SIZING_NS, "sizing_ns") // N-S (up-down) sizing cursor +ADD_ENUM(CURSORTYPE_SIZING_EW, "sizing_ew") // E-W (left-right) sizing cursor +ADD_ENUM(CURSORTYPE_SIZING_NWSE, "sizing_nwse") // NW-SE diagonal sizing cursor +ADD_ENUM(CURSORTYPE_SIZING_NESW, "sizing_nesw") // NE-SW diagonal sizing cursor +ADD_ENUM(CURSORTYPE_SIZING_ESWE, "sizing_eswe") // ES-WE horizontal sizing cursor +ADD_ENUM(CURSORTYPE_MOVE, "move") // move cursor +ADD_ENUM(CURSORTYPE_DRAG, "container_drag") // drag container cursor (note: not in use) +ADD_ENUM(CURSORTYPE_SEG_MOVING, "segment_moving") // segment moving cursor (note: not in use) +ADD_ENUM(CURSORTYPE_SEG_SIZING, "segment_sizing") // segment sizing cursor (note: not in use) IMPLEMENT_ENUM_END("cursor-type") IMPLEMENT_ENUM_BEGIN(eWheelPosition) @@ -943,6 +946,12 @@ ADD_ENUM(PreloadAreaOption::COLLISIONS, "collisions") ADD_ENUM(PreloadAreaOption::ALL, "all") IMPLEMENT_ENUM_CLASS_END("preload-area-option") +IMPLEMENT_ENUM_CLASS_BEGIN(RestreamOption) +ADD_ENUM(RestreamOption::ALL, "world") +ADD_ENUM(RestreamOption::VEHICLES, "vehicles") +ADD_ENUM(RestreamOption::PEDS, "peds") +ADD_ENUM(RestreamOption::OBJECTS, "objects") +IMPLEMENT_ENUM_CLASS_END("restream-option") IMPLEMENT_ENUM_CLASS_BEGIN(taskType) ADD_ENUM(taskType::PRIMARY_TASK, "primary") @@ -959,7 +968,6 @@ ADD_ENUM(ENTITY_TYPE_DUMMY, "dummy") ADD_ENUM(ENTITY_TYPE_NOTINPOOLS, "unknown") IMPLEMENT_ENUM_END("entity-type") - IMPLEMENT_ENUM_CLASS_BEGIN(VehicleAudioSettingProperty) ADD_ENUM(VehicleAudioSettingProperty::DOOR_SOUND, "door-sound") ADD_ENUM(VehicleAudioSettingProperty::ENGINE_OFF_SOUND_BANK_ID, "engine-off-soundbank-id") @@ -977,6 +985,12 @@ ADD_ENUM(VehicleAudioSettingProperty::ENGINE_UPGRADE, "engine-upgrade") ADD_ENUM(VehicleAudioSettingProperty::VEHICLE_TYPE_FOR_AUDIO, "vehicle-type-for-audio") IMPLEMENT_ENUM_CLASS_END("vehicle-audio-setting") +IMPLEMENT_ENUM_CLASS_BEGIN(PostFXType) +ADD_ENUM(PostFXType::GAMMA, "gamma") +ADD_ENUM(PostFXType::BRIGHTNESS, "brightness") +ADD_ENUM(PostFXType::CONTRAST, "contrast") +ADD_ENUM(PostFXType::SATURATION, "saturation") +IMPLEMENT_ENUM_CLASS_END("postfx-type") // // CResource from userdata @@ -1081,15 +1095,15 @@ SString GetUserDataClassName(void* ptr, lua_State* luaVM, bool bFindElementType) return GetClassTypeName(pClientElement); } - if (auto* pVar = UserDataCast((CResource*)ptr, luaVM)) // Try resource + if (auto* pVar = UserDataCast((CResource*)ptr, luaVM)) // Try resource return GetClassTypeName(pVar); - if (auto* pVar = UserDataCast((CXMLNode*)ptr, luaVM)) // Try xml node + if (auto* pVar = UserDataCast((CXMLNode*)ptr, luaVM)) // Try xml node return GetClassTypeName(pVar); - if (auto* pVar = UserDataCast((CLuaTimer*)ptr, luaVM)) // Try timer + if (auto* pVar = UserDataCast((CLuaTimer*)ptr, luaVM)) // Try timer return GetClassTypeName(pVar); - if (auto* pVar = UserDataCast((CLuaVector2D*)ptr, luaVM)) // Try 2D Vector + if (auto* pVar = UserDataCast((CLuaVector2D*)ptr, luaVM)) // Try 2D Vector return GetClassTypeName(pVar); - if (auto* pVar = UserDataCast((CLuaVector3D*)ptr, luaVM)) // Try 3D Vector + if (auto* pVar = UserDataCast((CLuaVector3D*)ptr, luaVM)) // Try 3D Vector return GetClassTypeName(pVar); if (auto* pVar = UserDataCast((CLuaVector4D*)ptr, luaVM)) return GetClassTypeName(pVar); @@ -1272,10 +1286,10 @@ bool MinClientReqCheck(CScriptArgReader& argStream, const char* szVersionReq, co { if (pResource->GetMinClientReq() < szVersionReq) { - #if MTASA_VERSION_TYPE == VERSION_TYPE_RELEASE +#if MTASA_VERSION_TYPE >= VERSION_TYPE_UNTESTED if (szReason) argStream.SetVersionWarning(szVersionReq, "client", szReason); - #endif +#endif return false; } } @@ -1296,16 +1310,14 @@ void MinClientReqCheck(lua_State* luaVM, const char* szVersionReq, const char* s CResource* pResource = pLuaMain->GetResource(); if (!pResource) return; - + if (pResource->GetMinClientReq() < szVersionReq) { - #if MTASA_VERSION_TYPE == VERSION_TYPE_RELEASE - SString err(" section in the meta.xml is incorrect or missing (expected at least client %s because %s)", - szVersionReq, szReason); +#if MTASA_VERSION_TYPE >= VERSION_TYPE_UNTESTED + SString err(" section in the meta.xml is incorrect or missing (expected at least client %s because %s)", szVersionReq, szReason); throw std::invalid_argument(err); - #endif +#endif } - } // @@ -1371,7 +1383,7 @@ uint GetWeaponPropertyFlagBit(WeaponProperty weaponProperty) return 0; // Check 20 bits from first to last - //dassert(WEAPON_FLAG_LAST + 1 - WEAPON_FLAG_FIRST == 20); + // dassert(WEAPON_FLAG_LAST + 1 - WEAPON_FLAG_FIRST == 20); uint uiFlagIndex = ((std::size_t)weaponProperty - (std::size_t)WeaponProperty::WEAPON_FLAG_FIRST); uint uiFlagBit = 1 << uiFlagIndex; diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h index da35c0d1cc2..bae91981974 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h @@ -25,6 +25,7 @@ #include "enums/SoundEffectParams.h" #include "enums/SoundEffectType.h" #include "enums/ObjectGroupPhysicalProperties.h" +#include "enums/PostFXType.h" enum eLuaType { @@ -98,9 +99,11 @@ DECLARE_ENUM(ePools); DECLARE_ENUM_CLASS(WorldProperty); DECLARE_ENUM_CLASS(eModelLoadState); DECLARE_ENUM_CLASS(PreloadAreaOption); +DECLARE_ENUM_CLASS(RestreamOption); DECLARE_ENUM_CLASS(taskType); DECLARE_ENUM(eEntityType); DECLARE_ENUM_CLASS(VehicleAudioSettingProperty); +DECLARE_ENUM_CLASS(PostFXType); class CRemoteCall; diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionRef.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionRef.cpp index 52b4fc3678d..65fa553727e 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionRef.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionRef.cpp @@ -10,7 +10,7 @@ *****************************************************************************/ #include "StdInc.h" -#pragma warning( disable : 4355 ) // warning C4355: 'this' : used in base member initializer list +#pragma warning(disable : 4355) // warning C4355: 'this' : used in base member initializer list CIntrusiveList CLuaFunctionRef::ms_AllRefList(&CLuaFunctionRef::m_ListNode); diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionRef.h b/Client/mods/deathmatch/logic/lua/CLuaFunctionRef.h index 9ab5e862d8d..1fe0fc39f03 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionRef.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionRef.h @@ -11,9 +11,9 @@ #pragma once -#define LUA_REFNIL (-1) -#define VERIFY_FUNCTION(func) ( (func).ToInt () != LUA_REFNIL ) -#define IS_REFNIL(func) ( (func).ToInt () == LUA_REFNIL ) +#define LUA_REFNIL (-1) +#define VERIFY_FUNCTION(func) ((func).ToInt() != LUA_REFNIL) +#define IS_REFNIL(func) ((func).ToInt() == LUA_REFNIL) class CLuaFunctionRef { diff --git a/Client/mods/deathmatch/logic/lua/CLuaMain.cpp b/Client/mods/deathmatch/logic/lua/CLuaMain.cpp index 4db16040937..91f26561267 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaMain.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaMain.cpp @@ -21,7 +21,7 @@ static CLuaManager* m_pLuaManager; SString CLuaMain::ms_strExpectedUndumpHash; #define HOOK_INSTRUCTION_COUNT 1000000 -#define HOOK_MAXIMUM_TIME 5000 +#define HOOK_MAXIMUM_TIME 5000 #include "luascripts/coroutine_debug.lua.h" #include "luascripts/exports.lua.h" @@ -111,7 +111,7 @@ void CLuaMain::InitClasses(lua_State* luaVM) CLuaEngineDefs::AddClass(luaVM); CLuaEffectDefs::AddClass(luaVM); CLuaGUIDefs::AddClass(luaVM); - CLuaBrowserDefs::AddClass(luaVM); // browser must be after drawing/gui, since it extends DxTexture/GUIElement + CLuaBrowserDefs::AddClass(luaVM); // browser must be after drawing/gui, since it extends DxTexture/GUIElement CLuaMarkerDefs::AddClass(luaVM); CLuaObjectDefs::AddClass(luaVM); CLuaPedDefs::AddClass(luaVM); @@ -495,14 +495,14 @@ const SString& CLuaMain::GetFunctionTag(int iLuaFunction) strText = SString("@func_%d NULL", iLuaFunction); } - #ifdef CHECK_FUNCTION_TAG +#ifdef CHECK_FUNCTION_TAG if (pTag) { // Check tag remains unchanged assert(strText == *pTag); return *pTag; } - #endif +#endif MapSet(m_FunctionTagMap, iLuaFunction, strText); pTag = MapFind(m_FunctionTagMap, iLuaFunction); diff --git a/Client/mods/deathmatch/logic/lua/CLuaMain.h b/Client/mods/deathmatch/logic/lua/CLuaMain.h index 259fce07bab..f5400c93c2f 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaMain.h +++ b/Client/mods/deathmatch/logic/lua/CLuaMain.h @@ -33,7 +33,7 @@ struct CRefInfo int iFunction; }; -class CLuaMain //: public CClient +class CLuaMain //: public CClient { public: ZERO_ON_NEW @@ -90,7 +90,7 @@ class CLuaMain //: public CClient lua_State* m_luaVM; CLuaTimerManager* m_pLuaTimerManager; - bool m_bBeingDeleted; // prevent it being deleted twice + bool m_bBeingDeleted; // prevent it being deleted twice CElapsedTime m_FunctionEnterTimer; diff --git a/Client/mods/deathmatch/logic/lua/CLuaManager.cpp b/Client/mods/deathmatch/logic/lua/CLuaManager.cpp index 89dadab3325..e97f802e612 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaManager.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaManager.cpp @@ -13,6 +13,7 @@ #include "../luadefs/CLuaFireDefs.h" #include "../luadefs/CLuaClientDefs.h" #include "../luadefs/CLuaVectorGraphicDefs.h" +#include "../luadefs/CLuaPostfxDefs.h" using std::list; @@ -28,10 +29,10 @@ CLuaManager::CLuaManager(CClientGame* pClientGame) m_pGUIManager = pClientGame->GetGUIManager(); m_pRegisteredCommands = pClientGame->GetRegisteredCommands(); - // Ensure lua was compiled with apichecks - #ifdef NDEBUG - #error "NDEBUG should not be defined" - #endif +// Ensure lua was compiled with apichecks +#ifdef NDEBUG + #error "NDEBUG should not be defined" +#endif assert(luaX_is_apicheck_enabled()); // Load the C functions @@ -142,7 +143,7 @@ CLuaMain* CLuaManager::GetVirtualMachine(lua_State* luaVM) { if (luaVM == (*iter)->GetVirtualMachine()) { - dassert(0); // Why not in map? + dassert(0); // Why not in map? return *iter; } } @@ -283,4 +284,5 @@ void CLuaManager::LoadCFunctions() CLuaClientDefs::LoadFunctions(); CLuaDiscordDefs::LoadFunctions(); CLuaBuildingDefs::LoadFunctions(); + CLuaPostfxDefs::LoadFunctions(); } diff --git a/Client/mods/deathmatch/logic/lua/CLuaTimerManager.cpp b/Client/mods/deathmatch/logic/lua/CLuaTimerManager.cpp index c6e961b3ba8..5006fbae246 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaTimerManager.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaTimerManager.cpp @@ -120,7 +120,6 @@ void CLuaTimerManager::SetTimerPaused(CLuaTimer* timer, bool paused) ListRemove(m_ProcessQueue, timer); } - void CLuaTimerManager::ResetTimer(CLuaTimer* pLuaTimer) { assert(pLuaTimer); @@ -157,5 +156,5 @@ CLuaTimer* CLuaTimerManager::AddTimer(const CLuaFunctionRef& iLuaFunction, CTick return pLuaTimer; } - return false; + return nullptr; } diff --git a/Client/mods/deathmatch/logic/lua/LuaCommon.cpp b/Client/mods/deathmatch/logic/lua/LuaCommon.cpp index 5fc9d75eed8..45392327811 100644 --- a/Client/mods/deathmatch/logic/lua/LuaCommon.cpp +++ b/Client/mods/deathmatch/logic/lua/LuaCommon.cpp @@ -16,7 +16,7 @@ // End of temporary // Prevent the warning issued when doing unsigned short -> void* -#pragma warning(disable:4312) +#pragma warning(disable : 4312) CClientEntity* lua_toelement(lua_State* luaVM, int iArgument) { @@ -161,7 +161,7 @@ void lua_pushobject(lua_State* luaVM, const char* szClass, void* pObject, bool b // Assign the class metatable lua_getclass(luaVM, szClass); - lua_setmetatable(luaVM, -2); // element + lua_setmetatable(luaVM, -2); // element } void lua_pushvector(lua_State* luaVM, const CVector4D& vector) @@ -253,31 +253,31 @@ void lua_newclass(lua_State* luaVM) void lua_getclass(lua_State* luaVM, const char* szName) { - lua_pushstring(luaVM, "mt"); // "mt" - lua_rawget(luaVM, LUA_REGISTRYINDEX); // mt + lua_pushstring(luaVM, "mt"); // "mt" + lua_rawget(luaVM, LUA_REGISTRYINDEX); // mt assert(lua_istable(luaVM, -1)); - lua_pushstring(luaVM, szName); // mt, class name - lua_rawget(luaVM, -2); // mt, class + lua_pushstring(luaVM, szName); // mt, class name + lua_rawget(luaVM, -2); // mt, class - lua_remove(luaVM, -2); // class + lua_remove(luaVM, -2); // class } void lua_registerclass(lua_State* luaVM, const char* szName, const char* szParent) { if (szParent != NULL) { - lua_pushstring(luaVM, "mt"); // class table, "mt" - lua_rawget(luaVM, LUA_REGISTRYINDEX); // class table, mt table - lua_getfield(luaVM, -1, szParent); // class table, mt table, parent table + lua_pushstring(luaVM, "mt"); // class table, "mt" + lua_rawget(luaVM, LUA_REGISTRYINDEX); // class table, mt table + lua_getfield(luaVM, -1, szParent); // class table, mt table, parent table // Error if we can't find the parent class to extend from assert(lua_istable(luaVM, -1)); - lua_setfield(luaVM, -3, "__parent"); // class table, mt table + lua_setfield(luaVM, -3, "__parent"); // class table, mt table - lua_pop(luaVM, 1); // class table + lua_pop(luaVM, 1); // class table } lua_pushstring(luaVM, "mt"); diff --git a/Client/mods/deathmatch/logic/lua/LuaCommon.h b/Client/mods/deathmatch/logic/lua/LuaCommon.h index 0dfd8194053..71a90a6157d 100644 --- a/Client/mods/deathmatch/logic/lua/LuaCommon.h +++ b/Client/mods/deathmatch/logic/lua/LuaCommon.h @@ -13,14 +13,14 @@ extern "C" { - #include "lua.h" - #include "lualib.h" - #include "lauxlib.h" +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" } CLuaFunctionRef luaM_toref(lua_State* luaVM, int iArgument); -#define TO_ELEMENTID(x) ((ElementID) reinterpret_cast < unsigned long > (x) ) +#define TO_ELEMENTID(x) ((ElementID) reinterpret_cast(x)) // Predeclarations of our classes class CClientColModel; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp index 6684e6e697d..97986aac0ca 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp @@ -186,7 +186,7 @@ int CLuaAudioDefs::PlaySound(lua_State* luaVM) { // call onClientSoundStarted CLuaArguments Arguments; - Arguments.PushString("play"); // Reason + Arguments.PushString("play"); // Reason pSound->CallEvent("onClientSoundStarted", Arguments, false); lua_pushelement(luaVM, pSound); @@ -246,7 +246,7 @@ int CLuaAudioDefs::PlaySound3D(lua_State* luaVM) { // call onClientSoundStarted CLuaArguments Arguments; - Arguments.PushString("play"); // Reason + Arguments.PushString("play"); // Reason pSound->CallEvent("onClientSoundStarted", Arguments, false); lua_pushelement(luaVM, pSound); @@ -1407,12 +1407,12 @@ struct SPlayerVoiceWrapper bool SetFxEffectParameters(std::uint32_t uiFxEffect, void* params) { - CClientPlayerVoice* pVoice = pPlayer->GetVoice(); + CClientPlayerVoice* pVoice = pPlayer->GetVoice(); return pVoice ? pVoice->SetFxEffectParameters(uiFxEffect, params) : false; } bool GetFxEffectParameters(std::uint32_t uiFxEffect, void* params) { - CClientPlayerVoice* pVoice = pPlayer->GetVoice(); + CClientPlayerVoice* pVoice = pPlayer->GetVoice(); return pVoice ? pVoice->GetFxEffectParameters(uiFxEffect, params) : false; } }; @@ -1420,14 +1420,15 @@ struct SPlayerVoiceWrapper int CLuaAudioDefs::SetSoundEffectParameter(lua_State* luaVM) { // bool setSoundEffectParameter ( sound/player sound, string effectName, string effectParameter, var effectParameterValue ) - CClientSound* pSound{}; + CClientSound* pSound{}; SPlayerVoiceWrapper playerVoice; - SoundEffectType eEffectType; + SoundEffectType eEffectType; - CScriptArgReader argStream(luaVM); + CScriptArgReader argStream(luaVM); // Call `SetFxEffectParameters` and log errors if any - const auto SetParamWithErrorLog = [luaVM, &eEffectType](auto* pSound, auto effectParam, auto& params) { + const auto SetParamWithErrorLog = [luaVM, &eEffectType](auto* pSound, auto effectParam, auto& params) + { // Try setting parameter if (pSound->SetFxEffectParameters((uint)eEffectType, ¶ms)) { @@ -1451,7 +1452,8 @@ int CLuaAudioDefs::SetSoundEffectParameter(lua_State* luaVM) return 1; }; - const auto ProcessSoundParams = [&eEffectType, luaVM, &argStream, &SetParamWithErrorLog](auto* pSound) { + const auto ProcessSoundParams = [&eEffectType, luaVM, &argStream, &SetParamWithErrorLog](auto* pSound) + { if (!pSound->IsFxEffectEnabled((std::uint32_t)eEffectType)) return luaL_error(luaVM, "Effect's parameters can't be set unless it's enabled"); @@ -1864,7 +1866,7 @@ int CLuaAudioDefs::SetSoundEffectParameter(lua_State* luaVM) lua_pushboolean(luaVM, false); return 1; }; - + if (argStream.NextIsUserDataOfType()) argStream.ReadUserData(pSound); else if (argStream.NextIsUserDataOfType()) @@ -1896,13 +1898,14 @@ int CLuaAudioDefs::SetSoundEffectParameter(lua_State* luaVM) int CLuaAudioDefs::GetSoundEffectParameters(lua_State* luaVM) { // table getSoundEffectParameters ( sound/player sound, string effectName ) - CClientSound* pSound{}; + CClientSound* pSound{}; SPlayerVoiceWrapper playerVoice; - SoundEffectType eEffectType; + SoundEffectType eEffectType; CScriptArgReader argStream(luaVM); - const auto ProcessSoundParams = [luaVM, &eEffectType](auto* pSound) { + const auto ProcessSoundParams = [luaVM, &eEffectType](auto* pSound) + { if (!pSound->IsFxEffectEnabled((std::uint32_t)eEffectType)) return luaL_error(luaVM, "Effect's parameters can't be set unless it's enabled"); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaBlipDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaBlipDefs.cpp index 68d21cfb32c..f30c489b129 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaBlipDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaBlipDefs.cpp @@ -14,14 +14,18 @@ static constexpr std::uint8_t MAX_BLIP_SIZE = 25; -std::variant CLuaBlipDefs::CreateBlip(lua_State* luaVM, const CVector vecPosition, std::optional icon, std::optional size, std::optional r, std::optional g, std::optional b, std::optional a, std::optional ordering, std::optional visibleDistance) +std::variant CLuaBlipDefs::CreateBlip(lua_State* luaVM, const CVector vecPosition, std::optional icon, + std::optional size, std::optional r, std::optional g, + std::optional b, std::optional a, + std::optional ordering, std::optional visibleDistance) { if (icon.has_value() && !CClientRadarMarkerManager::IsValidIcon(icon.value())) throw std::invalid_argument("Invalid icon"); if (size.has_value() && size.value() > MAX_BLIP_SIZE) { - m_pScriptDebugging->LogWarning(luaVM, SString("Blip size beyond %i is no longer supported (got %i). It will be clamped between 0 and %i.", MAX_BLIP_SIZE, size.value(), MAX_BLIP_SIZE)); + m_pScriptDebugging->LogWarning(luaVM, SString("Blip size beyond %i is no longer supported (got %i). It will be clamped between 0 and %i.", + MAX_BLIP_SIZE, size.value(), MAX_BLIP_SIZE)); size = MAX_BLIP_SIZE; } @@ -39,14 +43,19 @@ std::variant CLuaBlipDefs::CreateBlip(lua_State* luaV return radarMarker; } -std::variant CLuaBlipDefs::CreateBlipAttachedTo(lua_State* luaVM, CClientEntity* entity, std::optional icon, std::optional size, std::optional r, std::optional g, std::optional b, std::optional a, std::optional ordering, std::optional visibleDistance) +std::variant CLuaBlipDefs::CreateBlipAttachedTo(lua_State* luaVM, CClientEntity* entity, std::optional icon, + std::optional size, std::optional r, + std::optional g, std::optional b, + std::optional a, std::optional ordering, + std::optional visibleDistance) { if (icon.has_value() && !CClientRadarMarkerManager::IsValidIcon(icon.value())) throw std::invalid_argument("Invalid icon"); if (size.has_value() && size.value() > MAX_BLIP_SIZE) { - m_pScriptDebugging->LogWarning(luaVM, SString("Blip size beyond %i is no longer supported (got %i). It will be clamped between 0 and %i.", MAX_BLIP_SIZE, size.value(), MAX_BLIP_SIZE)); + m_pScriptDebugging->LogWarning(luaVM, SString("Blip size beyond %i is no longer supported (got %i). It will be clamped between 0 and %i.", + MAX_BLIP_SIZE, size.value(), MAX_BLIP_SIZE)); size = MAX_BLIP_SIZE; } @@ -57,7 +66,7 @@ std::variant CLuaBlipDefs::CreateBlipAttachedTo(lua_S if (!radarMarker) return false; - + if (CElementGroup* elementGroup = resource.GetElementGroup()) elementGroup->Add(radarMarker); @@ -102,7 +111,8 @@ bool CLuaBlipDefs::SetBlipSize(lua_State* luaVM, CClientRadarMarker* radarMarker { if (size > MAX_BLIP_SIZE) { - m_pScriptDebugging->LogWarning(luaVM, SString("Blip size beyond %i is no longer supported (got %i). It will be clamped between 0 and %i.", MAX_BLIP_SIZE, size, MAX_BLIP_SIZE)); + m_pScriptDebugging->LogWarning( + luaVM, SString("Blip size beyond %i is no longer supported (got %i). It will be clamped between 0 and %i.", MAX_BLIP_SIZE, size, MAX_BLIP_SIZE)); size = MAX_BLIP_SIZE; } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaBlipDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaBlipDefs.h index b6e4bea7873..fffd02abdb6 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaBlipDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaBlipDefs.h @@ -20,8 +20,15 @@ class CLuaBlipDefs : public CLuaDefs private: // Create functions - static std::variant CreateBlip(lua_State* luaVM, const CVector vecPosition, std::optional icon, std::optional size, std::optional r, std::optional g, std::optional b, std::optional a, std::optional ordering, std::optional visibleDistance); - static std::variant CreateBlipAttachedTo(lua_State* luaVM, CClientEntity* entity, std::optional icon, std::optional size, std::optional r, std::optional g, std::optional b, std::optional a, std::optional ordering, std::optional visibleDistance); + static std::variant CreateBlip(lua_State* luaVM, const CVector vecPosition, std::optional icon, + std::optional size, std::optional r, std::optional g, + std::optional b, std::optional a, + std::optional ordering, std::optional visibleDistance); + static std::variant CreateBlipAttachedTo(lua_State* luaVM, CClientEntity* entity, std::optional icon, + std::optional size, std::optional r, + std::optional g, std::optional b, + std::optional a, std::optional ordering, + std::optional visibleDistance); // Get functions static auto GetBlipIcon(CClientRadarMarker* radarMarker) noexcept; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaBrowserDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaBrowserDefs.cpp index 2285d986155..b08a1c3c9c0 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaBrowserDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaBrowserDefs.cpp @@ -141,7 +141,14 @@ int CLuaBrowserDefs::CreateBrowser(lua_State* luaVM) if (argStream.HasErrors()) return luaL_error(luaVM, argStream.GetFullErrorMessage()); - if (!bIsLocal && !g_pCore->GetWebCore()->GetRemotePagesEnabled()) + const auto pWebCore = g_pCore->GetWebCore(); + if (!pWebCore) + { + lua_pushboolean(luaVM, false); + return 1; + } + + if (!bIsLocal && !pWebCore->GetRemotePagesEnabled()) { lua_pushboolean(luaVM, false); return 1; @@ -186,7 +193,7 @@ int CLuaBrowserDefs::RequestBrowserDomains(lua_State* luaVM) if (!argStream.HasErrors()) { // Remove empty and invalid URLs - std::regex invalidSynmbolsRegex("[^A-Za-z0-9\-._~!#$&'()*+,;=:@\/?%]"); + std::regex invalidSynmbolsRegex("[^A-Za-z0-9._~!#$&'()*+,;=:@/?%-]"); pages.erase(std::remove_if(pages.begin(), pages.end(), [&invalidSynmbolsRegex](const auto& url) { return url.empty() || std::regex_search(url, invalidSynmbolsRegex); }), @@ -194,9 +201,18 @@ int CLuaBrowserDefs::RequestBrowserDomains(lua_State* luaVM) // Convert to domains if we got a list of URLs if (bIsURL) - std::transform(pages.begin(), pages.end(), pages.begin(), [](const auto& url) { return g_pCore->GetWebCore()->GetDomainFromURL(url); }); + { + auto pWebCore = g_pCore->GetWebCore(); + if (!pWebCore) + { + lua_pushboolean(luaVM, false); + return 1; + } + std::transform(pages.begin(), pages.end(), pages.begin(), [pWebCore](const auto& url) { return pWebCore->GetDomainFromURL(url); }); + } - WebRequestCallback callback = [=](bool bAllow, const std::unordered_set& domains) { + WebRequestCallback callback = [=](bool bAllow, const std::unordered_set& domains) + { // Test if luaVM is still available if (m_pLuaManager->IsLuaVMValid(luaVM) && VERIFY_FUNCTION(callbackFunction)) { @@ -219,7 +235,13 @@ int CLuaBrowserDefs::RequestBrowserDomains(lua_State* luaVM) } }; - g_pCore->GetWebCore()->RequestPages(pages, VERIFY_FUNCTION(callbackFunction) ? &callback : nullptr); + auto pWebCore = g_pCore->GetWebCore(); + if (!pWebCore) + { + lua_pushboolean(luaVM, false); + return 1; + } + pWebCore->RequestPages(pages, VERIFY_FUNCTION(callbackFunction) ? &callback : nullptr); lua_pushboolean(luaVM, true); return 1; } @@ -515,7 +537,8 @@ int CLuaBrowserDefs::SetBrowserVolume(lua_State* luaVM) if (argStream.NextIsNumber()) { argStream.ReadNumber(fVolume); - lua_pushboolean(luaVM, g_pCore->GetWebCore()->SetGlobalAudioVolume(fVolume)); + auto pWebCore = g_pCore->GetWebCore(); + lua_pushboolean(luaVM, pWebCore ? pWebCore->SetGlobalAudioVolume(fVolume) : false); return 1; } @@ -546,12 +569,19 @@ int CLuaBrowserDefs::IsBrowserDomainBlocked(lua_State* luaVM) if (!argStream.HasErrors()) { + auto pWebCore = g_pCore->GetWebCore(); + if (!pWebCore) + { + lua_pushnil(luaVM); + return 1; + } + if (bIsURL) - strURL = g_pCore->GetWebCore()->GetDomainFromURL(strURL); + strURL = pWebCore->GetDomainFromURL(strURL); if (!strURL.empty()) { - lua_pushboolean(luaVM, g_pCore->GetWebCore()->GetDomainState(strURL) != eURLState::WEBPAGE_ALLOWED); + lua_pushboolean(luaVM, pWebCore->GetDomainState(strURL) != eURLState::WEBPAGE_ALLOWED); return 1; } } @@ -570,7 +600,9 @@ int CLuaBrowserDefs::FocusBrowser(lua_State* luaVM) CScriptArgReader argStream(luaVM); if (argStream.NextIsNil() || argStream.NextIsNone()) { - g_pCore->GetWebCore()->SetFocusedWebView(NULL); + auto pWebCore = g_pCore->GetWebCore(); + if (pWebCore) + pWebCore->SetFocusedWebView(NULL); lua_pushboolean(luaVM, true); return 1; } @@ -600,7 +632,8 @@ int CLuaBrowserDefs::IsBrowserFocused(lua_State* luaVM) if (!argStream.HasErrors()) { - CWebViewInterface* pWebView = g_pCore->GetWebCore()->GetFocusedWebView(); + auto pWebCore = g_pCore->GetWebCore(); + CWebViewInterface* pWebView = pWebCore ? pWebCore->GetFocusedWebView() : nullptr; lua_pushboolean(luaVM, pWebBrowser->GetWebView() == pWebView); return 1; } @@ -667,14 +700,16 @@ int CLuaBrowserDefs::GetBrowserProperty(lua_State* luaVM) int CLuaBrowserDefs::GetBrowserSettings(lua_State* luaVM) { // table getBrowserSettings () + auto pWebCore = g_pCore->GetWebCore(); + lua_createtable(luaVM, 0, 3); lua_pushstring(luaVM, "RemoteEnabled"); - lua_pushboolean(luaVM, g_pCore->GetWebCore()->GetRemotePagesEnabled()); + lua_pushboolean(luaVM, pWebCore ? pWebCore->GetRemotePagesEnabled() : false); lua_settable(luaVM, -3); lua_pushstring(luaVM, "RemoteJavascript"); - lua_pushboolean(luaVM, g_pCore->GetWebCore()->GetRemoteJavascriptEnabled()); + lua_pushboolean(luaVM, pWebCore ? pWebCore->GetRemoteJavascriptEnabled() : false); lua_settable(luaVM, -3); lua_pushstring(luaVM, "PluginsEnabled"); @@ -700,21 +735,23 @@ int CLuaBrowserDefs::GetBrowserSource(lua_State* luaVM) CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); if (pLuaMain && VERIFY_FUNCTION(callbackFunction)) { - pWebBrowser->GetSourceCode([callbackFunction, pLuaMain, pWebBrowser](const std::string& code) { - /* - This function should not be called when the resource is about to stop as - stopping the resource destroys the browser element and thus cancels the - CefStringVisitor callback class (see CWebView::GetSourceCode::MyStringVisitor) - */ - if (VERIFY_FUNCTION(callbackFunction)) + pWebBrowser->GetSourceCode( + [callbackFunction, pLuaMain, pWebBrowser](const std::string& code) { - CLuaArguments arguments; - // TODO: Use SCharStringRef/direct string access instead of copying strings around - arguments.PushString(code); - arguments.PushElement(pWebBrowser); - arguments.Call(pLuaMain, callbackFunction); - } - }); + /* + This function should not be called when the resource is about to stop as + stopping the resource destroys the browser element and thus cancels the + CefStringVisitor callback class (see CWebView::GetSourceCode::MyStringVisitor) + */ + if (VERIFY_FUNCTION(callbackFunction)) + { + CLuaArguments arguments; + // TODO: Use SCharStringRef/direct string access instead of copying strings around + arguments.PushString(code); + arguments.PushElement(pWebBrowser); + arguments.Call(pLuaMain, callbackFunction); + } + }); lua_pushboolean(luaVM, true); return 1; @@ -739,7 +776,8 @@ int CLuaBrowserDefs::ToggleBrowserDevTools(lua_State* luaVM) if (!argStream.HasErrors()) { - if (g_pCore->GetWebCore()->IsTestModeEnabled()) + auto pWebCore = g_pCore->GetWebCore(); + if (pWebCore && pWebCore->IsTestModeEnabled()) { lua_pushboolean(luaVM, pWebBrowser->ToggleDevTools(visible)); return 1; @@ -916,7 +954,8 @@ int CLuaBrowserDefs::GUICreateBrowser(lua_State* luaVM) if (!argStream.HasErrors()) { - if (!bIsLocal && !g_pCore->GetWebCore()->GetRemotePagesEnabled()) + auto pWebCore = g_pCore->GetWebCore(); + if (!bIsLocal && (!pWebCore || !pWebCore->GetRemotePagesEnabled())) { lua_pushboolean(luaVM, false); return 1; @@ -947,7 +986,7 @@ int CLuaBrowserDefs::GUICreateBrowser(lua_State* luaVM) return 1; } -int CLuaBrowserDefs::GUIGetBrowser(lua_State* luaVM) // Or rather guiGetBrowserBrowser? +int CLuaBrowserDefs::GUIGetBrowser(lua_State* luaVM) // Or rather guiGetBrowserBrowser? { // webbrowser guiGetBrowser ( gui-webbrowser browser ) CClientGUIElement* pGUIElement; @@ -1005,45 +1044,47 @@ int CLuaBrowserDefs::SetBrowserAjaxHandler(lua_State* luaVM) CResourceManager* pResourceManager = m_pResourceManager; auto netId = pResource->GetNetID(); - bool bResult = pWebBrowser->AddAjaxHandler(strURL, [=](std::vector& vecGet, std::vector& vecPost) -> const SString { - // Make sure the resource is still running - if (!pResourceManager->Exists(pResource) || pResource->GetNetID() != netId) - { - return ""; - } + bool bResult = pWebBrowser->AddAjaxHandler(strURL, + [=](std::vector& vecGet, std::vector& vecPost) -> const std::string + { + // Make sure the resource is still running + if (!pResourceManager->Exists(pResource) || pResource->GetNetID() != netId) + { + return ""; + } - // Make sure the function is valid - if (VERIFY_FUNCTION(callbackFunction)) - { - CLuaArguments arguments; - CLuaArguments getArguments; - CLuaArguments postArguments; + // Make sure the function is valid + if (VERIFY_FUNCTION(callbackFunction)) + { + CLuaArguments arguments; + CLuaArguments getArguments; + CLuaArguments postArguments; - for (auto&& param : vecGet) - getArguments.PushString(param); + for (auto&& param : vecGet) + getArguments.PushString(param); - for (auto&& param : vecPost) - postArguments.PushString(param); + for (auto&& param : vecPost) + postArguments.PushString(param); - arguments.PushTable(&getArguments); - arguments.PushTable(&postArguments); + arguments.PushTable(&getArguments); + arguments.PushTable(&postArguments); - CLuaArguments result; + CLuaArguments result; - arguments.Call(pLuaMain, callbackFunction, &result); + arguments.Call(pLuaMain, callbackFunction, &result); - if (result.IsEmpty()) - return ""; + if (result.IsEmpty()) + return ""; - CLuaArgument* returnedValue = *result.begin(); - if (returnedValue->GetType() == LUA_TSTRING) - return returnedValue->GetString(); - else - return ""; - } - else - return ""; - }); + CLuaArgument* returnedValue = *result.begin(); + if (returnedValue->GetType() == LUA_TSTRING) + return std::string(returnedValue->GetString()); + else + return ""; + } + else + return ""; + }); lua_pushboolean(luaVM, bResult); return 1; @@ -1059,5 +1100,6 @@ int CLuaBrowserDefs::SetBrowserAjaxHandler(lua_State* luaVM) bool CLuaBrowserDefs::IsBrowserGPUEnabled() noexcept { - return g_pCore->GetWebCore()->GetGPUEnabled(); + auto pWebCore = g_pCore->GetWebCore(); + return pWebCore ? pWebCore->GetGPUEnabled() : false; } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp index 067fe6e7693..732b821cbea 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp @@ -33,14 +33,15 @@ void CLuaBuildingDefs::AddClass(lua_State* luaVM) lua_registerclass(luaVM, "Building", "Element"); } -CClientBuilding* CLuaBuildingDefs::CreateBuilding(lua_State* const luaVM, std::uint16_t modelId, CVector pos, std::optional rot, std::optional interior) +CClientBuilding* CLuaBuildingDefs::CreateBuilding(lua_State* const luaVM, std::uint16_t modelId, CVector pos, std::optional rot, + std::optional interior) { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); // Get the resource we belong to CResource* pResource = pLuaMain->GetResource(); if (!pResource) - return false; + return nullptr; if (!CClientBuildingManager::IsValidModel(modelId)) throw std::invalid_argument("Invalid building model id"); @@ -53,7 +54,7 @@ CClientBuilding* CLuaBuildingDefs::CreateBuilding(lua_State* const luaVM, std::u else rot.emplace(CVector(0, 0, 0)); - CClientBuilding* pBuilding = new CClientBuilding(m_pManager, INVALID_ELEMENT_ID, modelId, pos, rot.value() , interior.value_or(0)); + CClientBuilding* pBuilding = new CClientBuilding(m_pManager, INVALID_ELEMENT_ID, modelId, pos, rot.value(), interior.value_or(0)); CClientEntity* pRoot = pResource->GetResourceDynamicEntity(); pBuilding->SetParent(pRoot); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h index 1a723488024..28b950ac761 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h @@ -19,7 +19,8 @@ class CLuaBuildingDefs : public CLuaDefs static void AddClass(lua_State* luaVM); // Buiding create funcs - static CClientBuilding* CreateBuilding(lua_State* const luaVM, std::uint16_t modelId, CVector pos, std::optional rot, std::optional interior); + static CClientBuilding* CreateBuilding(lua_State* const luaVM, std::uint16_t modelId, CVector pos, std::optional rot, + std::optional interior); static void RemoveAllGameBuildings(); static void RestoreGameBuildings(); }; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.cpp index 9c8cb6cd830..8a64fe4f997 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.cpp @@ -481,7 +481,7 @@ bool CLuaCameraDefs::SetCameraDrunkLevel(short drunkLevel) throw std::invalid_argument("Invalid range (0-255)"); CPlayerInfo* pPlayerInfo = g_pGame->GetPlayerInfo(); - pPlayerInfo->SetCamDrunkLevel(drunkLevel); + pPlayerInfo->SetCamDrunkLevel(static_cast(drunkLevel)); return true; } @@ -560,7 +560,7 @@ bool CLuaCameraDefs::ShakeCamera(float radius, std::optional x, std::opti if (!x || !y || !z) { const auto* player = CStaticFunctionDefinitions::GetLocalPlayer(); - CVector out; + CVector out; player->GetPosition(out); x = out.fX; y = out.fY; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaClassDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaClassDefs.cpp index 9efb8a88523..3b74e2474ed 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaClassDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaClassDefs.cpp @@ -14,75 +14,75 @@ // Don't whine bout my gotos, lua api is a bitch, i had to! int CLuaClassDefs::Index(lua_State* luaVM) { - lua_pushvalue(luaVM, lua_upvalueindex(1)); // ud, k, mt + lua_pushvalue(luaVM, lua_upvalueindex(1)); // ud, k, mt // First we look for a function - lua_pushstring(luaVM, "__class"); // ud, k, mt, "__class" - lua_rawget(luaVM, -2); // ud, k, mt, __class table + lua_pushstring(luaVM, "__class"); // ud, k, mt, "__class" + lua_rawget(luaVM, -2); // ud, k, mt, __class table if (!lua_istable(luaVM, -1)) { - lua_pop(luaVM, 1); // ud, k, mt + lua_pop(luaVM, 1); // ud, k, mt goto searchparent; } - lua_pushvalue(luaVM, 2); // ud, k, mt, __class table, k - lua_rawget(luaVM, -2); // ud, k, mt, __class table, function - lua_remove(luaVM, -2); // ud, k, mt, function + lua_pushvalue(luaVM, 2); // ud, k, mt, __class table, k + lua_rawget(luaVM, -2); // ud, k, mt, __class table, function + lua_remove(luaVM, -2); // ud, k, mt, function if (lua_isfunction(luaVM, -1)) - { // Found the function, clean up and return - lua_remove(luaVM, -2); // ud, k, function + { // Found the function, clean up and return + lua_remove(luaVM, -2); // ud, k, function return 1; } - lua_pop(luaVM, 1); // ud, k, mt + lua_pop(luaVM, 1); // ud, k, mt // Function not found, look for property - lua_pushstring(luaVM, "__get"); // ud, k, mt, "__get" - lua_rawget(luaVM, -2); // ud, k, mt, __get table + lua_pushstring(luaVM, "__get"); // ud, k, mt, "__get" + lua_rawget(luaVM, -2); // ud, k, mt, __get table if (!lua_istable(luaVM, -1)) { - lua_pop(luaVM, 1); // ud, k, mt + lua_pop(luaVM, 1); // ud, k, mt goto searchparent; } - lua_pushvalue(luaVM, 2); // ud, k, mt, __get table, k - lua_rawget(luaVM, -2); // ud, k, mt, __get table, function - lua_remove(luaVM, -2); // ud, k, mt, function + lua_pushvalue(luaVM, 2); // ud, k, mt, __get table, k + lua_rawget(luaVM, -2); // ud, k, mt, __get table, function + lua_remove(luaVM, -2); // ud, k, mt, function if (lua_isfunction(luaVM, -1)) - { // Found the property, - lua_remove(luaVM, -2); // ud, k, function + { // Found the property, + lua_remove(luaVM, -2); // ud, k, function - lua_pushvalue(luaVM, 1); // ud, k, function, ud - lua_call(luaVM, 1, 1); // ud, k, result + lua_pushvalue(luaVM, 1); // ud, k, function, ud + lua_call(luaVM, 1, 1); // ud, k, result return 1; } - lua_pop(luaVM, 1); // ud, k, mt + lua_pop(luaVM, 1); // ud, k, mt searchparent: - lua_pushstring(luaVM, "__parent"); // ud, k, mt, "__parent" - lua_rawget(luaVM, -2); // ud, k, mt, __parent table + lua_pushstring(luaVM, "__parent"); // ud, k, mt, "__parent" + lua_rawget(luaVM, -2); // ud, k, mt, __parent table if (lua_istable(luaVM, -1)) { - lua_pushstring(luaVM, "__index"); // ud, k, mt, __parent table, "__index" - lua_rawget(luaVM, -2); // ud, k, mt, __parent table, function + lua_pushstring(luaVM, "__index"); // ud, k, mt, __parent table, "__index" + lua_rawget(luaVM, -2); // ud, k, mt, __parent table, function if (lua_isfunction(luaVM, -1)) { - lua_pushvalue(luaVM, 1); // ud, k, mt, __parent table, function, ud - lua_pushvalue(luaVM, 2); // ud, k, mt, __parent table, function, ud, k + lua_pushvalue(luaVM, 1); // ud, k, mt, __parent table, function, ud + lua_pushvalue(luaVM, 2); // ud, k, mt, __parent table, function, ud, k - lua_call(luaVM, 2, 1); // ud, k, mt, __parent table, result + lua_call(luaVM, 2, 1); // ud, k, mt, __parent table, result - lua_replace(luaVM, -3); // ud, k, result, __parent table - lua_pop(luaVM, 1); // ud, k, result + lua_replace(luaVM, -3); // ud, k, result, __parent table + lua_pop(luaVM, 1); // ud, k, result return 1; } - lua_pop(luaVM, 1); // ud, k, mt, __parent table + lua_pop(luaVM, 1); // ud, k, mt, __parent table } - lua_pop(luaVM, 2); // ud, k + lua_pop(luaVM, 2); // ud, k lua_pushnil(luaVM); return 1; @@ -90,113 +90,113 @@ int CLuaClassDefs::Index(lua_State* luaVM) int CLuaClassDefs::NewIndex(lua_State* luaVM) { - lua_pushvalue(luaVM, lua_upvalueindex(1)); // ud, k, v, mt + lua_pushvalue(luaVM, lua_upvalueindex(1)); // ud, k, v, mt - lua_pushstring(luaVM, "__set"); // ud, k, v, mt, "__set" - lua_rawget(luaVM, -2); // ud, k, v, mt, __set table + lua_pushstring(luaVM, "__set"); // ud, k, v, mt, "__set" + lua_rawget(luaVM, -2); // ud, k, v, mt, __set table if (!lua_istable(luaVM, -1)) { - lua_pop(luaVM, 1); // ud, k, v, mt + lua_pop(luaVM, 1); // ud, k, v, mt goto searchparent; } - lua_pushvalue(luaVM, 2); // ud, k, v, mt, __set table, k - lua_rawget(luaVM, -2); // ud, k, v, mt, __set table, function - lua_remove(luaVM, -2); // ud, k, v, mt, function + lua_pushvalue(luaVM, 2); // ud, k, v, mt, __set table, k + lua_rawget(luaVM, -2); // ud, k, v, mt, __set table, function + lua_remove(luaVM, -2); // ud, k, v, mt, function if (lua_isfunction(luaVM, -1)) - { // Found the property - lua_pushvalue(luaVM, 1); // ud, k, v, mt, function, ud - lua_pushvalue(luaVM, 3); // ud, k, v, mt, function, ud, v + { // Found the property + lua_pushvalue(luaVM, 1); // ud, k, v, mt, function, ud + lua_pushvalue(luaVM, 3); // ud, k, v, mt, function, ud, v - lua_call(luaVM, 2, 0); // ud, k, v, mt + lua_call(luaVM, 2, 0); // ud, k, v, mt - lua_pop(luaVM, 1); // ud, k, v + lua_pop(luaVM, 1); // ud, k, v return 0; } - lua_pop(luaVM, 1); // ud, k, v, mt + lua_pop(luaVM, 1); // ud, k, v, mt searchparent: - lua_pushstring(luaVM, "__parent"); // ud, k, v, mt, "__parent" - lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table + lua_pushstring(luaVM, "__parent"); // ud, k, v, mt, "__parent" + lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table if (lua_istable(luaVM, -1)) { - lua_pushstring(luaVM, "__newindex"); // ud, k, v, mt, __parent table, "__newindex" - lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table, function + lua_pushstring(luaVM, "__newindex"); // ud, k, v, mt, __parent table, "__newindex" + lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table, function if (lua_isfunction(luaVM, -1)) { - lua_pushvalue(luaVM, 1); // ud, k, v, mt, __parent table, function, ud - lua_pushvalue(luaVM, 2); // ud, k, v, mt, __parent table, function, ud, k - lua_pushvalue(luaVM, 3); // ud, k, v, mt, __parent table, function, ud, k, v + lua_pushvalue(luaVM, 1); // ud, k, v, mt, __parent table, function, ud + lua_pushvalue(luaVM, 2); // ud, k, v, mt, __parent table, function, ud, k + lua_pushvalue(luaVM, 3); // ud, k, v, mt, __parent table, function, ud, k, v - lua_call(luaVM, 3, 0); // ud, k, v, mt, __parent table + lua_call(luaVM, 3, 0); // ud, k, v, mt, __parent table - lua_pop(luaVM, 2); // ud, k, v + lua_pop(luaVM, 2); // ud, k, v return 0; } - lua_pop(luaVM, 1); // ud, k, v, mt, __parent table + lua_pop(luaVM, 1); // ud, k, v, mt, __parent table } - lua_pop(luaVM, 2); // ud, k, v + lua_pop(luaVM, 2); // ud, k, v return 0; } int CLuaClassDefs::StaticNewIndex(lua_State* luaVM) { - lua_pushvalue(luaVM, lua_upvalueindex(1)); // ud, k, v, mt + lua_pushvalue(luaVM, lua_upvalueindex(1)); // ud, k, v, mt - lua_pushstring(luaVM, "__set"); // ud, k, v, mt, "__set" - lua_rawget(luaVM, -2); // ud, k, v, mt, __set table + lua_pushstring(luaVM, "__set"); // ud, k, v, mt, "__set" + lua_rawget(luaVM, -2); // ud, k, v, mt, __set table if (!lua_istable(luaVM, -1)) { - lua_pop(luaVM, 1); // ud, k, v, mt + lua_pop(luaVM, 1); // ud, k, v, mt goto searchparent; } - lua_pushvalue(luaVM, 2); // ud, k, v, mt, __set table, k - lua_rawget(luaVM, -2); // ud, k, v, mt, __set table, function - lua_remove(luaVM, -2); // ud, k, v, mt, function + lua_pushvalue(luaVM, 2); // ud, k, v, mt, __set table, k + lua_rawget(luaVM, -2); // ud, k, v, mt, __set table, function + lua_remove(luaVM, -2); // ud, k, v, mt, function if (lua_isfunction(luaVM, -1)) - { // Found the property - lua_pushvalue(luaVM, 3); // ud, k, v, mt, function, v + { // Found the property + lua_pushvalue(luaVM, 3); // ud, k, v, mt, function, v - lua_call(luaVM, 1, 0); // ud, k, v, mt + lua_call(luaVM, 1, 0); // ud, k, v, mt - lua_pop(luaVM, 1); // ud, k, v + lua_pop(luaVM, 1); // ud, k, v return 0; } - lua_pop(luaVM, 1); // ud, k, v, mt + lua_pop(luaVM, 1); // ud, k, v, mt searchparent: - lua_pushstring(luaVM, "__parent"); // ud, k, v, mt, "__parent" - lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table + lua_pushstring(luaVM, "__parent"); // ud, k, v, mt, "__parent" + lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table if (lua_istable(luaVM, -1)) { - lua_pushstring(luaVM, "__newindex"); // ud, k, v, mt, __parent table, "__newindex" - lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table, function + lua_pushstring(luaVM, "__newindex"); // ud, k, v, mt, __parent table, "__newindex" + lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table, function if (lua_isfunction(luaVM, -1)) { - lua_pushvalue(luaVM, 1); // ud, k, v, mt, __parent table, function, ud - lua_pushvalue(luaVM, 2); // ud, k, v, mt, __parent table, function, ud, k - lua_pushvalue(luaVM, 3); // ud, k, v, mt, __parent table, function, ud, k, v + lua_pushvalue(luaVM, 1); // ud, k, v, mt, __parent table, function, ud + lua_pushvalue(luaVM, 2); // ud, k, v, mt, __parent table, function, ud, k + lua_pushvalue(luaVM, 3); // ud, k, v, mt, __parent table, function, ud, k, v - lua_call(luaVM, 3, 0); // ud, k, v, mt, __parent table + lua_call(luaVM, 3, 0); // ud, k, v, mt, __parent table - lua_pop(luaVM, 2); // ud, k, v + lua_pop(luaVM, 2); // ud, k, v return 0; } - lua_pop(luaVM, 1); // ud, k, v, mt, __parent table + lua_pop(luaVM, 1); // ud, k, v, mt, __parent table } - lua_pop(luaVM, 2); // ud, k, v + lua_pop(luaVM, 2); // ud, k, v return 0; } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaClassDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaClassDefs.h index 2f20191aab8..78f09d3ccb9 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaClassDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaClassDefs.h @@ -13,9 +13,9 @@ extern "C" { - #include "lua.h" - #include "lualib.h" - #include "lauxlib.h" +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" } class CLuaClassDefs : public CLuaDefs diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaDefs.h index 3f3c18386f4..bc2c6c2f275 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDefs.h @@ -9,9 +9,12 @@ *****************************************************************************/ #pragma once -#define LUA_DECLARE(x) static int x ( lua_State * luaVM ); + +#define LUA_DECLARE(x) static int x(lua_State* luaVM); #define LUA_DECLARE_OOP(x) LUA_DECLARE(x) LUA_DECLARE(OOP_##x) +#include "lua/CLuaFunctionParser.h" + class CClientColManager; class CClientColModelManager; class CClientDFFManager; @@ -74,7 +77,7 @@ class CLuaDefs template static inline int ArgumentParserWarn(lua_State* L) { - return CLuaFunctionParser()(L, m_pScriptDebugging); + return CLuaFunctionParser>()(L, m_pScriptDebugging); } // Special case for overloads @@ -84,8 +87,8 @@ class CLuaDefs { // Pad functions to have the same number of parameters by // filling both up to the larger number of parameters with dummy_type arguments - using PaddedFunctionA = pad_func_with_func; - using PaddedFunctionB = pad_func_with_func; + using PaddedFunctionA = pad_func_with_func, remove_noexcept_fn_v>; + using PaddedFunctionB = pad_func_with_func, remove_noexcept_fn_v>; // Combine functions using Overload = CLuaOverloadParser; @@ -96,7 +99,7 @@ class CLuaDefs template static inline int ArgumentParser(lua_State* L) { - return CLuaFunctionParser()(L, m_pScriptDebugging); + return CLuaFunctionParser>()(L, m_pScriptDebugging); } // Special case for overloads @@ -106,8 +109,8 @@ class CLuaDefs { // Pad functions to have the same number of parameters by // filling both up to the larger number of parameters with dummy_type arguments - using PaddedFunctionA = pad_func_with_func; - using PaddedFunctionB = pad_func_with_func; + using PaddedFunctionA = pad_func_with_func, remove_noexcept_fn_v>; + using PaddedFunctionB = pad_func_with_func, remove_noexcept_fn_v>; // Combine functions using Overload = CLuaOverloadParser; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDiscordDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaDiscordDefs.cpp index 7e36e1147d2..6cbe6fd5cf2 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDiscordDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDiscordDefs.cpp @@ -10,6 +10,8 @@ #include "StdInc.h" #include +#include + void CLuaDiscordDefs::LoadFunctions() { // Backwards compatibility functions @@ -24,7 +26,7 @@ void CLuaDiscordDefs::LoadFunctions() {"setDiscordRichPresenceEndTime", ArgumentParser}, {"setDiscordRichPresencePartySize", ArgumentParser}, {"resetDiscordRichPresenceData", ArgumentParser}, - {"isDiscordRichPresenceConnected", ArgumentParser }, + {"isDiscordRichPresenceConnected", ArgumentParser}, {"getDiscordRichPresenceUserID", ArgumentParser}, }; @@ -48,8 +50,8 @@ void CLuaDiscordDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "setPartySize", "setDiscordRichPresencePartySize"); lua_classfunction(luaVM, "isConnected", "isDiscordRichPresenceConnected"); - //lua_classfunction(luaVM, "setAppID", "setDiscordRichPresenceAppID"); - //lua_classfunction(luaVM, "setAppID", "setDiscordRichPresenceAppID"); + // lua_classfunction(luaVM, "setAppID", "setDiscordRichPresenceAppID"); + // lua_classfunction(luaVM, "setAppID", "setDiscordRichPresenceAppID"); lua_registerclass(luaVM, "DiscordRPC"); } @@ -100,7 +102,7 @@ bool CLuaDiscordDefs::SetAppID(lua_State* luaVM, std::string strAppID) auto discord = g_pCore->GetDiscord(); - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); const char* resourceName = ""; if (pLuaMain) { @@ -138,10 +140,24 @@ bool CLuaDiscordDefs::SetDetails(std::string strDetails) bool CLuaDiscordDefs::SetStartTime(unsigned long ulTime) { - unsigned long ulSecondsSinceEpoch = time(nullptr) + ulTime; + unsigned long ulSecondsSinceEpoch = 0; + if (ulTime != 0) + { + const time_t now = time(nullptr); + if (now <= 0) + return false; + + const auto maxValue = std::numeric_limits::max(); + const auto nowUnsigned = static_cast(now); + if (nowUnsigned > maxValue) + return false; - if (ulTime == 0) - ulSecondsSinceEpoch = 0; + const unsigned long nowUl = static_cast(nowUnsigned); + if (maxValue - nowUl < ulTime) + return false; + + ulSecondsSinceEpoch = nowUl + ulTime; + } auto discord = g_pCore->GetDiscord(); @@ -157,10 +173,24 @@ bool CLuaDiscordDefs::SetStartTime(unsigned long ulTime) bool CLuaDiscordDefs::SetEndTime(unsigned long ulTime) { - unsigned long ulSecondsSinceEpoch = time(nullptr) + ulTime; + unsigned long ulSecondsSinceEpoch = 0; + if (ulTime != 0) + { + const time_t now = time(nullptr); + if (now <= 0) + return false; + + const auto maxValue = std::numeric_limits::max(); + const auto nowUnsigned = static_cast(now); + if (nowUnsigned > maxValue) + return false; - if (ulTime == 0) - ulSecondsSinceEpoch = 0; + const unsigned long nowUl = static_cast(nowUnsigned); + if (maxValue - nowUl < ulTime) + return false; + + ulSecondsSinceEpoch = nowUl + ulTime; + } auto discord = g_pCore->GetDiscord(); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDiscordDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaDiscordDefs.h index 6fa724f2417..efd1fce687f 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDiscordDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDiscordDefs.h @@ -17,18 +17,17 @@ class CLuaDiscordDefs : public CLuaDefs static void AddClass(lua_State* luaVM); private: - static bool ResetData(); - static bool SetState(std::string strState); - static bool SetAppID(lua_State* luaVM, std::string strAppID); - static bool SetDetails(std::string strDetails); - static bool SetAsset(std::string szAsset, std::string szAssetText, bool bIsLarge = false); - static bool SetButtons(unsigned short int iIndex, std::string szName, std::string szUrl); - static bool SetLargeAsset(std::string szAsset, std::string szAssetText); - static bool SetSmallAsset(std::string szAsset, std::string szAssetText); - static bool SetStartTime(unsigned long ulTime); - static bool SetEndTime(unsigned long ulTime); - static bool SetPartySize(int iMin, int iMax); - static bool IsDiscordRPCConnected(); + static bool ResetData(); + static bool SetState(std::string strState); + static bool SetAppID(lua_State* luaVM, std::string strAppID); + static bool SetDetails(std::string strDetails); + static bool SetAsset(std::string szAsset, std::string szAssetText, bool bIsLarge = false); + static bool SetButtons(unsigned short int iIndex, std::string szName, std::string szUrl); + static bool SetLargeAsset(std::string szAsset, std::string szAssetText); + static bool SetSmallAsset(std::string szAsset, std::string szAssetText); + static bool SetStartTime(unsigned long ulTime); + static bool SetEndTime(unsigned long ulTime); + static bool SetPartySize(int iMin, int iMax); + static bool IsDiscordRPCConnected(); static std::string GetDiscordUserID(); }; - diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp index 7422dfdf67a..fa652401e78 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp @@ -189,10 +189,10 @@ int CLuaDrawingDefs::DxDrawLine(lua_State* luaVM) int CLuaDrawingDefs::DxDrawLine3D(lua_State* luaVM) { // bool dxDrawLine3D ( float startX, float startY, float startZ, float endX, float endY, float endZ, int color[, int width, bool postGUI ] ) - CVector vecBegin; - CVector vecEnd; - SColor color; - float fWidth; + CVector vecBegin; + CVector vecEnd; + SColor color; + float fWidth; eRenderStage renderStage{eRenderStage::POST_FX}; CScriptArgReader argStream(luaVM); @@ -232,7 +232,7 @@ int CLuaDrawingDefs::DxDrawMaterialLine3D(lua_State* luaVM) SColor color; CVector vecFaceToward; bool bUseFaceToward = false; - eRenderStage renderStage{eRenderStage::POST_FX}; + eRenderStage renderStage{eRenderStage::POST_FX}; CScriptArgReader argStream(luaVM); argStream.ReadVector3D(vecBegin); @@ -282,7 +282,7 @@ int CLuaDrawingDefs::DxDrawMaterialSectionLine3D(lua_State* luaVM) SColor color; CVector vecFaceToward; bool bUseFaceToward = false; - eRenderStage renderStage{eRenderStage::POST_FX}; + eRenderStage renderStage{eRenderStage::POST_FX}; CScriptArgReader argStream(luaVM); argStream.ReadVector3D(vecBegin); @@ -598,7 +598,7 @@ int CLuaDrawingDefs::DxDrawPrimitive3D(lua_State* luaVM) // bool DxDrawPrimitive3D (string primitiveType, bool postGUI, table vertice1, ...) D3DPRIMITIVETYPE ePrimitiveType; auto pVecVertices = new std::vector(); - eRenderStage renderStage{eRenderStage::POST_FX}; + eRenderStage renderStage{eRenderStage::POST_FX}; CScriptArgReader argStream(luaVM); argStream.ReadEnumString(ePrimitiveType); if (argStream.NextIsBool()) @@ -651,7 +651,7 @@ int CLuaDrawingDefs::DxDrawMaterialPrimitive3D(lua_State* luaVM) D3DPRIMITIVETYPE ePrimitiveType; auto pVecVertices = new std::vector(); CClientMaterial* pMaterialElement; - eRenderStage renderStage{eRenderStage::POST_FX}; + eRenderStage renderStage{eRenderStage::POST_FX}; CScriptArgReader argStream(luaVM); argStream.ReadEnumString(ePrimitiveType); @@ -1050,15 +1050,24 @@ int CLuaDrawingDefs::DxCreateTexture(lua_State* luaVM) // Make it a child of the resource's file root ** CHECK Should parent be pFileResource, and element added to pParentResource's // ElementGroup? ** pTexture->SetParent(pParentResource->GetResourceDynamicEntity()); + lua_pushelement(luaVM, pTexture); + return 1; + } + else + { + m_pScriptDebugging->LogCustom( + luaVM, + SString("[DxCreateTexture] Failed to create texture from file '%s' (may be corrupt, unsupported format, or out of memory)", + strFilePath.c_str())); + lua_pushnil(luaVM); + return 1; } - lua_pushelement(luaVM, pTexture); - return 1; } else - argStream.SetCustomError(strFilePath, "File not found"); + argStream.SetCustomError(strFilePath, "[DxCreateTexture] File not found"); } else - argStream.SetCustomError(strFilePath, "Bad file path"); + argStream.SetCustomError(strFilePath, "[DxCreateTexture] Bad file path"); } else if (pixels.GetSize()) { @@ -1068,9 +1077,15 @@ int CLuaDrawingDefs::DxCreateTexture(lua_State* luaVM) if (pTexture) { pTexture->SetParent(pParentResource->GetResourceDynamicEntity()); + lua_pushelement(luaVM, pTexture); + return 1; + } + else + { + m_pScriptDebugging->LogCustom(luaVM, "[DxCreateTexture:Pixels] Failed to create texture from pixel data (invalid format or out of memory)"); + lua_pushnil(luaVM); + return 1; } - lua_pushelement(luaVM, pTexture); - return 1; } else { @@ -1080,9 +1095,16 @@ int CLuaDrawingDefs::DxCreateTexture(lua_State* luaVM) if (pTexture) { pTexture->SetParent(pParentResource->GetResourceDynamicEntity()); + lua_pushelement(luaVM, pTexture); + return 1; + } + else + { + m_pScriptDebugging->LogCustom( + luaVM, SString("[DxCreateTexture:Blank] Failed to create blank texture %dx%d (invalid dimensions or out of memory)", width, height)); + lua_pushnil(luaVM); + return 1; } - lua_pushelement(luaVM, pTexture); - return 1; } } } @@ -1196,7 +1218,7 @@ int CLuaDrawingDefs::DxCreateShader(lua_State* luaVM) // Replace any path in the error message with our own one SString strRootPathWithoutResource = strRootPath.Left(strRootPath.TrimEnd("\\").length() - SStringX(pFileResource->GetName()).length()); strStatus = strStatus.ReplaceI(strRootPathWithoutResource, ""); - argStream.SetCustomError(bIsRawData ? "raw data" : strFile, strStatus); + argStream.SetCustomError(bIsRawData ? SStringX("raw data") : strFile, strStatus); m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); lua_pushboolean(luaVM, false); return 1; @@ -1206,9 +1228,9 @@ int CLuaDrawingDefs::DxCreateRenderTarget(lua_State* luaVM) { // element dxCreateRenderTarget( int sizeX, int sizeY [, int withAlphaChannel = false ] ) // element dxCreateRenderTarget( int sizeX, int sizeY, SurfaceFormat surfaceFormat ) - CVector2D vecSize; - bool bWithAlphaChannel = false; - bool bHasSurfaceFormat = false; + CVector2D vecSize; + bool bWithAlphaChannel = false; + bool bHasSurfaceFormat = false; _D3DFORMAT surfaceFormat; CScriptArgReader argStream(luaVM); @@ -1403,11 +1425,11 @@ int CLuaDrawingDefs::DxSetShaderValue(lua_State* luaVM) float fBuffer[16]{}; uint i = 0; - lua_pushnil(luaVM); // Loop through our table, beginning at the first key + lua_pushnil(luaVM); // Loop through our table, beginning at the first key while (lua_next(luaVM, argStream.m_iIndex) != 0 && i < NUMELMS(fBuffer)) { - fBuffer[i++] = static_cast(lua_tonumber(luaVM, -1)); // Ignore the index at -2, and just read the value - lua_pop(luaVM, 1); // Remove the item and keep the key for the next iteration + fBuffer[i++] = static_cast(lua_tonumber(luaVM, -1)); // Ignore the index at -2, and just read the value + lua_pop(luaVM, 1); // Remove the item and keep the key for the next iteration } bool bResult = pShader->GetShaderItem()->SetValue(strName, fBuffer, i); lua_pushboolean(luaVM, bResult); @@ -1756,27 +1778,29 @@ int CLuaDrawingDefs::DxGetStatus(lua_State* luaVM) lua_settable(luaVM, -3); lua::Push(luaVM, "SettingDebugMode"); - lua::Push(luaVM, [] { - switch (g_pCore->GetDiagnosticDebug()) - { - case EDiagnosticDebug::GRAPHICS_6734: - return "#6734 Graphics"; - case EDiagnosticDebug::D3D_6732: - return "#6732 D3D"; - case EDiagnosticDebug::LOG_TIMING_0000: - return "#0000 Log timing"; - case EDiagnosticDebug::JOYSTICK_0000: - return "#0000 Joystick"; - case EDiagnosticDebug::LUA_TRACE_0000: - return "#0000 Lua trace"; - case EDiagnosticDebug::RESIZE_ALWAYS_0000: - return "#0000 Resize always"; - case EDiagnosticDebug::RESIZE_NEVER_0000: - return "#0000 Resize never"; - default: - return "Default"; - } - }()); + lua::Push(luaVM, + [] + { + switch (g_pCore->GetDiagnosticDebug()) + { + case EDiagnosticDebug::GRAPHICS_6734: + return "#6734 Graphics"; + case EDiagnosticDebug::D3D_6732: + return "#6732 D3D"; + case EDiagnosticDebug::LOG_TIMING_0000: + return "#0000 Log timing"; + case EDiagnosticDebug::JOYSTICK_0000: + return "#0000 Joystick"; + case EDiagnosticDebug::LUA_TRACE_0000: + return "#0000 Lua trace"; + case EDiagnosticDebug::RESIZE_ALWAYS_0000: + return "#0000 Resize always"; + case EDiagnosticDebug::RESIZE_NEVER_0000: + return "#0000 Resize never"; + default: + return "Default"; + } + }()); lua_settable(luaVM, -3); return 1; @@ -1791,7 +1815,8 @@ int CLuaDrawingDefs::DxGetStatus(lua_State* luaVM) int CLuaDrawingDefs::DxGetTexturePixels(lua_State* luaVM) { - // string dxGetTexturePixels( [ int surfaceIndex, ] element texture [, string pixelsFormat = "plain" [, string textureFormat = "argb"] [, bool mipmaps = true]] + // string dxGetTexturePixels( [ int surfaceIndex, ] element texture [, string pixelsFormat = "plain" [, string textureFormat = "argb"] [, bool mipmaps = + // true]] // [, int x, int y, int width, int height ] ) CClientTexture* pTexture; CVector2D vecPosition; @@ -2123,7 +2148,8 @@ bool CLuaDrawingDefs::DxDrawWiredSphere(lua_State* const luaVM, const CVector po return true; } -bool CLuaDrawingDefs::DxDrawModel3D(std::uint32_t modelID, CVector position, CVector rotation, const std::optional scale, const std::optional lighting) +bool CLuaDrawingDefs::DxDrawModel3D(std::uint32_t modelID, CVector position, CVector rotation, const std::optional scale, + const std::optional lighting) { CModelInfo* pModelInfo = g_pGame->GetModelInfo(modelID); if (!pModelInfo) @@ -2137,6 +2163,6 @@ bool CLuaDrawingDefs::DxDrawModel3D(std::uint32_t modelID, CVector position, CVe ConvertDegreesToRadians(rotation); - return g_pClientGame->GetModelRenderer()->EnqueueModel(pModelInfo, - CMatrix{position, rotation, scale.value_or(CVector{1.0f, 1.0f, 1.0f})}, lighting.value_or(0.0f)); + return g_pClientGame->GetModelRenderer()->EnqueueModel(pModelInfo, CMatrix{position, rotation, scale.value_or(CVector{1.0f, 1.0f, 1.0f})}, + lighting.value_or(0.0f)); } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h index 89278accd11..0a0a7917d48 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h @@ -82,7 +82,8 @@ class CLuaDrawingDefs : public CLuaDefs static bool DxDrawWiredSphere(lua_State* const luaVM, const CVector position, const float radius, const std::optional color, const std::optional lineWidth, const std::optional iterations); - static bool DxDrawModel3D(std::uint32_t modelID, CVector position, CVector rotation, const std::optional scale, const std::optional lighting); + static bool DxDrawModel3D(std::uint32_t modelID, CVector position, CVector rotation, const std::optional scale, + const std::optional lighting); private: static void AddDxMaterialClass(lua_State* luaVM); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEffectDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEffectDefs.cpp index 2112aaf4394..5aa04aca2e2 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEffectDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEffectDefs.cpp @@ -643,7 +643,11 @@ int CLuaEffectDefs::SetEffectDensity(lua_State* luaVM) return 1; } -bool CLuaEffectDefs::FxCreateParticle(FxParticleSystems eParticleSystem, CVector vecPosition, CVector vecDirection, float fR, float fG, float fB, float fA, std::optional bRandomizeColors, std::optional iCount, std::optional fBrightness, std::optional fSize, std::optional bRandomizeSizes, std::optional fLife) +bool CLuaEffectDefs::FxCreateParticle(FxParticleSystems eParticleSystem, CVector vecPosition, CVector vecDirection, float fR, float fG, float fB, float fA, + std::optional bRandomizeColors, std::optional iCount, std::optional fBrightness, + std::optional fSize, std::optional bRandomizeSizes, std::optional fLife) { - return CStaticFunctionDefinitions::FxCreateParticle(eParticleSystem, vecPosition, vecDirection, fR/255, fG/255, fB/255, fA/255, bRandomizeColors.value_or(false), iCount.value_or(1), fBrightness.value_or(1.0f), fSize.value_or(0.3f), bRandomizeSizes.value_or(false), fLife.value_or(1.0f)); + return CStaticFunctionDefinitions::FxCreateParticle(eParticleSystem, vecPosition, vecDirection, fR / 255, fG / 255, fB / 255, fA / 255, + bRandomizeColors.value_or(false), iCount.value_or(1), fBrightness.value_or(1.0f), fSize.value_or(0.3f), + bRandomizeSizes.value_or(false), fLife.value_or(1.0f)); } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEffectDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEffectDefs.h index d45107069cb..fa33a6c434d 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEffectDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEffectDefs.h @@ -38,5 +38,7 @@ class CLuaEffectDefs : public CLuaDefs LUA_DECLARE(SetEffectDensity); LUA_DECLARE(GetEffectDensity); - static bool FxCreateParticle(FxParticleSystems eParticleSystem, CVector vecPosition, CVector vecDirection, float fR, float fG, float fB, float fA, std::optional bRandomizeColors, std::optional iCount, std::optional fBrightness, std::optional fSize, std::optional bRandomizeSizes, std::optional fLife); + static bool FxCreateParticle(FxParticleSystems eParticleSystem, CVector vecPosition, CVector vecDirection, float fR, float fG, float fB, float fA, + std::optional bRandomizeColors, std::optional iCount, std::optional fBrightness, + std::optional fSize, std::optional bRandomizeSizes, std::optional fLife); }; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp index 0c23f9ef818..2fe3401fc7c 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp @@ -14,8 +14,6 @@ #include using std::list; -#define MIN_CLIENT_REQ_LOD_FOR_BUILDING "1.6.0-9.22470" - void CLuaElementDefs::LoadFunctions() { constexpr static const std::pair functions[]{ @@ -980,7 +978,11 @@ CClientEntityResult CLuaElementDefs::GetElementsWithinRange(CVector pos, float r if (interior || dimension || typeHash) { result.erase(std::remove_if(result.begin(), result.end(), - [&, radiusSq = radius * radius](CElement* pElement) { + [&, radiusSq = radius * radius](CElement* pElement) + { + if (pElement->IsBeingDeleted()) + return true; + if (typeHash && typeHash != pElement->GetTypeHash()) return true; @@ -996,7 +998,7 @@ CClientEntityResult CLuaElementDefs::GetElementsWithinRange(CVector pos, float r if ((elementPos - pos).LengthSquared() > radiusSq) return true; - return pElement->IsBeingDeleted(); + return false; }), result.end()); } @@ -1791,7 +1793,7 @@ int CLuaElementDefs::SetElementData(lua_State* luaVM) key = key->substr(0, MAX_CUSTOMDATA_NAME_LENGTH); } - if (CStaticFunctionDefinitions::SetElementData(*pEntity, key.ToCString(), value, bSynchronize)) + if (CStaticFunctionDefinitions::SetElementData(*pEntity, key, value, bSynchronize)) { lua_pushboolean(luaVM, true); return 1; @@ -1830,7 +1832,7 @@ int CLuaElementDefs::RemoveElementData(lua_State* luaVM) key = key->substr(0, MAX_CUSTOMDATA_NAME_LENGTH); } - if (CStaticFunctionDefinitions::RemoveElementData(*pEntity, key.ToCString())) + if (CStaticFunctionDefinitions::RemoveElementData(*pEntity, key)) { lua_pushboolean(luaVM, true); return 1; @@ -2102,7 +2104,7 @@ int CLuaElementDefs::SetElementInterior(lua_State* luaVM) } // Set the interior - if (CStaticFunctionDefinitions::SetElementInterior(*pEntity, uiInterior, bSetPosition, vecPosition)) + if (CStaticFunctionDefinitions::SetElementInterior(*pEntity, static_cast(uiInterior), bSetPosition, vecPosition)) { lua_pushboolean(luaVM, true); return 1; @@ -2513,10 +2515,6 @@ int CLuaElementDefs::GetLowLodElement(lua_State* luaVM) bool CLuaElementDefs::SetLowLodElement(lua_State* luaVM, CClientEntity* pEntity, std::optional pLowLodEntity) { // bool setLowLODElement ( element theElement [, element lowLowElement ] ) - - if (pEntity->GetType() == CCLIENTBUILDING) - MinClientReqCheck(luaVM, MIN_CLIENT_REQ_LOD_FOR_BUILDING, "target is building"); - return CStaticFunctionDefinitions::SetLowLodElement(*pEntity, pLowLodEntity.value_or(nullptr)); } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 3de38bbf76a..ce01b71ffcd 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -20,8 +20,13 @@ //! Set the CModelCacheManager limits //! By passing `nil`/no value the original values are restored -void EngineStreamingSetModelCacheLimits(std::optional numVehicles, std::optional numPeds) { - g_pClientGame->GetModelCacheManager()->SetCustomLimits(numVehicles, numPeds); +void EngineStreamingSetModelCacheLimits(std::optional numVehicles, std::optional numPeds) +{ + size_t vehicleValue = numVehicles.value_or(0); + size_t pedValue = numPeds.value_or(0); + const size_t* pVehicles = numVehicles.has_value() ? &vehicleValue : nullptr; + const size_t* pPeds = numPeds.has_value() ? &pedValue : nullptr; + g_pClientGame->GetModelCacheManager()->SetCustomLimits(pVehicles, pPeds); } void EngineStreamingFreeUpMemory(std::uint32_t bytes) @@ -36,39 +41,49 @@ std::uint32_t EngineStreamingGetUsedMemory() } // Set the streaming memory size to a custom value -void EngineStreamingSetMemorySize(size_t sizeBytes) { - if (sizeBytes == 0) { +void EngineStreamingSetMemorySize(size_t sizeBytes) +{ + if (sizeBytes == 0) + { throw std::invalid_argument{"Memory size must be > 0"}; } g_pCore->SetCustomStreamingMemory(sizeBytes); } // Restore memory size to cvar -void EngineStreamingRestoreMemorySize() { +void EngineStreamingRestoreMemorySize() +{ g_pCore->SetCustomStreamingMemory(0); } // Get the streaming memory size [In bytes] - This is the limit, not the amount currently used! [See `EngineStreamingGetUsedMemory`] -size_t EngineStreamingGetMemorySize() { +size_t EngineStreamingGetMemorySize() +{ return g_pCore->GetStreamingMemory(); } // Set streaming buffer size -bool EngineStreamingSetBufferSize(size_t sizeBytes) { +bool EngineStreamingSetBufferSize(size_t sizeBytes) +{ const auto sizeBlocks = sizeBytes / 2048; - if (sizeBlocks > g_pClientGame->GetManager()->GetIMGManager()->GetLargestFileSizeBlocks()) { // Can't allow it to be less than the largest file + if (sizeBlocks > g_pClientGame->GetManager()->GetIMGManager()->GetLargestFileSizeBlocks()) + { // Can't allow it to be less than the largest file return g_pGame->GetStreaming()->SetStreamingBufferSize(sizeBlocks); - } else { + } + else + { return false; } } -void EngineStreamingRestoreBufferSize() { +void EngineStreamingRestoreBufferSize() +{ g_pGame->GetStreaming()->SetStreamingBufferSize(g_pClientGame->GetManager()->GetIMGManager()->GetLargestFileSizeBlocks()); } // Get current streaming buffer size -size_t EngineStreamingGetBufferSize() { +size_t EngineStreamingGetBufferSize() +{ return g_pGame->GetStreaming()->GetStreamingBufferSize(); } @@ -150,7 +165,9 @@ void CLuaEngineDefs::LoadFunctions() {"engineGetPoolUsedCapacity", ArgumentParser}, {"engineSetPoolCapacity", ArgumentParser}, {"enginePreloadWorldArea", ArgumentParser}, - + {"engineRestreamModel", ArgumentParser}, + {"engineRestream", ArgumentParser}, + // CLuaCFunctions::AddFunction ( "engineReplaceMatchingAtomics", EngineReplaceMatchingAtomics ); // CLuaCFunctions::AddFunction ( "engineReplaceWheelAtomics", EngineReplaceWheelAtomics ); // CLuaCFunctions::AddFunction ( "enginePositionAtomic", EnginePositionAtomic ); @@ -329,12 +346,12 @@ int CLuaEngineDefs::EngineLoadCOL(lua_State* luaVM) { // Delete it again. We failed delete pCol; - argStream.SetCustomError(bIsRawData ? "raw data" : input, "Error loading COL"); + argStream.SetCustomError(bIsRawData ? SStringX("raw data") : input, "Error loading COL"); } } else { - argStream.SetCustomError(bIsRawData ? "raw data" : input, "Bad file path"); + argStream.SetCustomError(bIsRawData ? SStringX("raw data") : input, "Bad file path"); } } } @@ -401,12 +418,12 @@ int CLuaEngineDefs::EngineLoadDFF(lua_State* luaVM) { // Delete it again delete pDFF; - argStream.SetCustomError(bIsRawData ? "raw data" : input, "Error loading DFF"); + argStream.SetCustomError(bIsRawData ? SStringX("raw data") : input, "Error loading DFF"); } } else { - argStream.SetCustomError(bIsRawData ? "raw data" : input, "Bad file path"); + argStream.SetCustomError(bIsRawData ? SStringX("raw data") : input, "Bad file path"); } } } @@ -427,7 +444,7 @@ int CLuaEngineDefs::EngineLoadTXD(lua_State* luaVM) bool bFilteringEnabled = true; CScriptArgReader argStream(luaVM); argStream.ReadString(input); - if (argStream.NextIsBool()) // Some scripts have a number here (in error) + if (argStream.NextIsBool()) // Some scripts have a number here (in error) argStream.ReadBool(bFilteringEnabled, true); if (!argStream.HasErrors()) @@ -455,8 +472,15 @@ int CLuaEngineDefs::EngineLoadTXD(lua_State* luaVM) if (bIsRawData || CResourceManager::ParseResourcePathInput(input, pResource, &filePath)) { - // Grab the resource root entity + // TXD must have parent to ensure cleanup before global reset CClientEntity* pRoot = pResource->GetResourceTXDRoot(); + if (!pRoot) + { + argStream.SetCustomError(bIsRawData ? SString("raw data", 8) : SString(input), "Resource TXD root not available"); + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + lua_pushboolean(luaVM, false); + return 1; + } // Create a TXD element CClientTXD* pTXD = new CClientTXD(m_pManager, INVALID_ELEMENT_ID); @@ -473,13 +497,18 @@ int CLuaEngineDefs::EngineLoadTXD(lua_State* luaVM) } else { + // Get specific error from CClientTXD if available + SString strError = pTXD->GetLastError(); + if (strError.empty()) + strError = "Error loading TXD"; + // Delete it again delete pTXD; - argStream.SetCustomError(bIsRawData ? "raw data" : input, "Error loading TXD"); + argStream.SetCustomError(bIsRawData ? SStringX("raw data") : input, strError); } } else - argStream.SetCustomError(bIsRawData ? "raw data" : input, "Bad file path"); + argStream.SetCustomError(bIsRawData ? SStringX("raw data") : input, "Bad file path"); } } } @@ -540,12 +569,12 @@ int CLuaEngineDefs::EngineLoadIFP(lua_State* luaVM) } else { - argStream.SetCustomError(bIsRawData ? "raw data" : input, "Error loading IFP"); + argStream.SetCustomError(bIsRawData ? SStringX("raw data") : input, "Error loading IFP"); } } else { - argStream.SetCustomError(bIsRawData ? "raw data" : input, "Bad file path"); + argStream.SetCustomError(bIsRawData ? SStringX("raw data") : input, "Bad file path"); } } } @@ -600,9 +629,9 @@ int CLuaEngineDefs::EngineRestoreCOL(lua_State* luaVM) if (!argStream.HasErrors()) { - unsigned short usModelID = CModelNames::ResolveModelID(strModelName); + uint32_t modelId = CModelNames::ResolveModelID(strModelName); - if (m_pColModelManager->RestoreModel(usModelID)) + if (m_pColModelManager->RestoreModel(static_cast(modelId))) { // Success lua_pushboolean(luaVM, true); @@ -628,23 +657,34 @@ int CLuaEngineDefs::EngineImportTXD(lua_State* luaVM) if (!argStream.HasErrors()) { // Valid importable model? - ushort usModelID = CModelNames::ResolveModelID(strModelName); - if (usModelID == INVALID_MODEL_ID) - usModelID = CModelNames::ResolveClothesTexID(strModelName); - if (CClientTXD::IsImportableModel(usModelID)) + uint32_t modelId = CModelNames::ResolveModelID(strModelName); + + if (modelId == INVALID_MODEL_ID) + modelId = CModelNames::ResolveClothesTexID(strModelName); + + if (CClientTXD::IsImportableModel(static_cast(modelId))) { // Try to import - if (pTXD->Import(usModelID)) + if (pTXD->Import(static_cast(modelId))) { // Success lua_pushboolean(luaVM, true); return 1; } + else + { + // Get specific error from CClientTXD if available + SString strError = pTXD->GetLastError(); + if (strError.empty()) + strError = "Failed to import TXD"; + argStream.SetCustomError(strModelName, strError); + } } else m_pScriptDebugging->LogBadPointer(luaVM, "number", 2); } - else + + if (argStream.HasErrors()) m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); // Failed @@ -658,7 +698,12 @@ bool CLuaEngineDefs::EngineAddClothingTXD(CClientTXD* pTXD, std::string strModel throw std::invalid_argument(SString("Invalid file name specified (%*s)", (int)strModelName.length(), strModelName.data())); if (!pTXD->AddClothingTexture(strModelName)) - throw std::invalid_argument(SString("Texture already added (%*s)", (int)strModelName.length(), strModelName.data())); + { + SString strError = pTXD->GetLastError(); + if (strError.empty()) + strError = SString("Failed to add clothing texture (%*s)", (int)strModelName.length(), strModelName.data()); + throw std::invalid_argument(strError); + } return true; } @@ -670,7 +715,7 @@ CClientIMG* CLuaEngineDefs::EngineLoadIMG(lua_State* const luaVM, std::string st // Get the resource we belong to CResource* pResource = pLuaMain->GetResource(); if (!pResource) - return false; + return nullptr; std::string strFullPath; @@ -745,7 +790,7 @@ std::string CLuaEngineDefs::EngineImageGetFile(CClientIMG* pIMG, std::variantGetFile(ResolveIMGFileID(pIMG, file), buffer)) // Get file might throw + if (!pIMG->GetFile(ResolveIMGFileID(pIMG, file), buffer)) // Get file might throw throw std::invalid_argument("Failed to read file. Probably EOF reached, make sure the archieve isn't corrupted."); return buffer; @@ -758,7 +803,7 @@ bool CLuaEngineDefs::EngineImageLinkDFF(CClientIMG* pIMG, std::variantGetFile(ResolveIMGFileID(pIMG, file), buffer)) + if (!pIMG->GetFile(fileID, buffer)) throw std::invalid_argument("Failed to read file. Probably EOF reached, make sure the archieve isn't corrupted."); if (!g_pCore->GetNetwork()->CheckFile("dff", "", buffer.data(), buffer.size())) @@ -769,18 +814,32 @@ bool CLuaEngineDefs::EngineImageLinkDFF(CClientIMG* pIMG, std::variant file, uint uiTxdID) { - if (uiTxdID >= 5000) - throw std::invalid_argument(SString("Expected txdid in range 0 - 4999, got %d", uiTxdID)); - size_t fileID = ResolveIMGFileID(pIMG, file); std::string buffer; - if (!pIMG->GetFile(ResolveIMGFileID(pIMG, file), buffer)) + if (!pIMG->GetFile(fileID, buffer)) throw std::invalid_argument("Failed to read file. Probably EOF reached, make sure the archieve isn't corrupted."); if (!g_pCore->GetNetwork()->CheckFile("txd", "", buffer.data(), buffer.size())) throw std::invalid_argument("Failed to link file. Make sure the archieve isn't corrupted."); - return pIMG->LinkModel(20000 + uiTxdID, fileID); + // Standard TXD slots [0, SA_TXD_POOL_CAPACITY) have dedicated streaming + // entries (model IDs 20000-24999) and can use deferred IMG streaming + if (uiTxdID < static_cast(CTxdPool::SA_TXD_POOL_CAPACITY)) + return pIMG->LinkModel(20000 + uiTxdID, fileID); + + // Slots [SA_TXD_POOL_CAPACITY, MAX_STREAMING_TXD_SLOT) have streaming IDs + // that overlap with non-TXD resources (COL/IPL/DAT/IFP). engineRequestTXD + // never allocates from this range. + if (uiTxdID < static_cast(CTxdPool::MAX_STREAMING_TXD_SLOT)) + throw std::invalid_argument(SString("Invalid TXD slot ID %u (reserved range)", uiTxdID)); + + // Overflow TXD slots (>= MAX_STREAMING_TXD_SLOT, from engineRequestTXD + // fallback) have no streaming entry, so we parse and load the TXD data + // directly into the pool slot. + if (!g_pGame->GetRenderWare()->LoadTxdSlotFromBuffer(uiTxdID, buffer)) + throw std::invalid_argument(SString("Failed to load TXD data into slot %u", uiTxdID)); + + return true; } bool CLuaEngineDefs::EngineRestoreDFFImage(uint uiModelID) @@ -796,8 +855,10 @@ bool CLuaEngineDefs::EngineRestoreDFFImage(uint uiModelID) bool CLuaEngineDefs::EngineRestoreTXDImage(uint uiModelID) { - if (uiModelID >= 5000) - throw std::invalid_argument("Expected TXD ID in range [0-4999] at argument 1"); + // Only standard TXD slots [0, SA_TXD_POOL_CAPACITY) can have streaming + // IMG links to restore. Higher slots don't have TXD streaming entries. + if (uiModelID >= static_cast(CTxdPool::SA_TXD_POOL_CAPACITY)) + return false; if (CClientIMGManager::IsLinkableModel(uiModelID)) return m_pImgManager->RestoreModel(20000 + uiModelID); @@ -818,22 +879,29 @@ int CLuaEngineDefs::EngineReplaceModel(lua_State* luaVM) if (!argStream.HasErrors()) { - ushort usModelID = CModelNames::ResolveModelID(strModelName); - if (usModelID != INVALID_MODEL_ID) + const auto modelId = static_cast(CModelNames::ResolveModelID(strModelName)); + + if (modelId != INVALID_MODEL_ID) { // Fixes vehicle dff leak problem with engineReplaceModel - m_pDFFManager->RestoreModel(usModelID); - if (pDFF->ReplaceModel(usModelID, bAlphaTransparency)) + m_pDFFManager->RestoreModel(modelId); + + if (pDFF->ReplaceModel(modelId, bAlphaTransparency)) { lua_pushboolean(luaVM, true); return 1; } else - argStream.SetCustomError(SString("Model ID %d replace failed", usModelID)); + { + argStream.SetCustomError(SString("Model ID %u replace failed", modelId)); + } } else + { argStream.SetCustomError("Expected valid model ID or name at argument 2"); + } } + if (argStream.HasErrors()) m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); @@ -855,7 +923,7 @@ bool CLuaEngineDefs::EngineAddClothingModel(CClientDFF* pDFF, std::string strMod int CLuaEngineDefs::EngineRestoreModel(lua_State* luaVM) { // Grab the model ID - unsigned short usModelID = CModelNames::ResolveModelID(lua_tostring(luaVM, 1)); + const auto usModelID = static_cast(CModelNames::ResolveModelID(lua_tostring(luaVM, 1))); // Valid client DFF and model? if (CClientDFFManager::IsReplacableModel(usModelID)) @@ -893,52 +961,83 @@ int CLuaEngineDefs::EngineRequestModel(lua_State* luaVM) { if (!argStream.HasErrors()) { - int iModelID = m_pManager->GetModelManager()->GetFirstFreeModelID(); - if (iModelID != INVALID_MODEL_ID) { - std::shared_ptr pModel = m_pManager->GetModelManager()->Request(m_pManager, iModelID, eModelType); - m_pManager->GetModelManager()->Add(pModel); + auto modelManager = m_pManager->GetModelManager(); - ushort usParentID = -1; + int iModelID = modelManager->GetFirstFreeModelID(); + if (iModelID != INVALID_MODEL_ID) + { + int iParentID = -1; if (argStream.NextIsNumber()) - argStream.ReadNumber(usParentID); + argStream.ReadNumber(iParentID); else { + constexpr int defaultPedParentId = 7; + constexpr int defaultTimedObjectParentId = 4715; + constexpr int defaultClumpParentId = 3425; + constexpr int defaultObjectParentId = 1337; + constexpr int defaultDamageableObjectParentId = 994; + switch (eModelType) { case eClientModelType::PED: - usParentID = 7; // male01 + iParentID = defaultPedParentId; break; case eClientModelType::TIMED_OBJECT: - usParentID = 4715; // LTSLAsky1_LAn2 + iParentID = defaultTimedObjectParentId; break; case eClientModelType::CLUMP: - usParentID = 3425; // nt_windmill (windmill) + iParentID = defaultClumpParentId; break; case eClientModelType::OBJECT: - usParentID = 1337; // BinNt07_LA (trash can) + iParentID = defaultObjectParentId; break; case eClientModelType::OBJECT_DAMAGEABLE: - usParentID = 994; // lhouse_barrier2 + iParentID = defaultDamageableObjectParentId; break; case eClientModelType::VEHICLE: - usParentID = static_cast(VehicleType::VT_LANDSTAL); + iParentID = static_cast(VehicleType::VT_LANDSTAL); break; default: break; } } - if (pModel->Allocate(usParentID)) + if (iParentID < 0 || iParentID >= MAX_MODEL_DFF_ID) { - pModel->SetParentResource(pResource); - - lua_pushinteger(luaVM, iModelID); - return 1; + argStream.SetCustomError("Expected valid original model ID at argument 2"); + modelManager->ReleaseModelID(iModelID); + } + else + { + std::shared_ptr pModel = modelManager->Request(m_pManager, iModelID, eModelType); + if (!pModel) + { + modelManager->ReleaseModelID(iModelID); + argStream.SetCustomError("Failed to create model"); + } + else + { + pModel->SetParentResource(pResource); + + if (!modelManager->TryAdd(pModel)) + { + modelManager->ReleaseModelID(iModelID); + argStream.SetCustomError("Model ID already in use"); + } + else + { + if (pModel->Allocate(static_cast(iParentID))) + { + lua_pushinteger(luaVM, iModelID); + return 1; + } + + modelManager->Remove(pModel); + argStream.SetCustomError("Allocation failed"); + } + } } - - m_pManager->GetModelManager()->Remove(pModel); - argStream.SetCustomError("Expected valid original model ID at argument 2"); } } } @@ -1055,11 +1154,11 @@ int CLuaEngineDefs::EngineGetModelLODDistance(lua_State* luaVM) if (!argStream.HasErrors()) { - ushort usModelID = CModelNames::ResolveModelID(strModelId); + uint32_t modelId = CModelNames::ResolveModelID(strModelId); // Ensure we have a good model (GitHub #446) - if (usModelID < g_pGame->GetBaseIDforTXD()) + if (modelId < g_pGame->GetBaseIDforTXD()) { - CModelInfo* pModelInfo = g_pGame->GetModelInfo(usModelID); + CModelInfo* pModelInfo = g_pGame->GetModelInfo(modelId); if (pModelInfo) { lua_pushnumber(luaVM, pModelInfo->GetLODDistance()); @@ -1068,7 +1167,7 @@ int CLuaEngineDefs::EngineGetModelLODDistance(lua_State* luaVM) } else argStream.SetCustomError( - SString("Expected a valid model name or ID in range [0-%d] at argument 1, got \"%s\"", g_pGame->GetBaseIDforTXD(), *strModelId)); + SString("Expected a valid model name or ID in range [0-%u] at argument 1, got \"%s\"", g_pGame->GetBaseIDforTXD(), *strModelId)); } if (argStream.HasErrors()) m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); @@ -1091,11 +1190,11 @@ int CLuaEngineDefs::EngineSetModelLODDistance(lua_State* luaVM) if (!argStream.HasErrors()) { - ushort usModelID = CModelNames::ResolveModelID(strModelId); + uint32_t modelId = CModelNames::ResolveModelID(strModelId); // Ensure we have a good model (GitHub #446) - if (usModelID < g_pGame->GetBaseIDforTXD()) + if (modelId < g_pGame->GetBaseIDforTXD()) { - CModelInfo* pModelInfo = g_pGame->GetModelInfo(usModelID); + CModelInfo* pModelInfo = g_pGame->GetModelInfo(modelId); if (pModelInfo && fDistance > 0.0f) { pModelInfo->SetLODDistance(fDistance, extendedLod); @@ -1105,7 +1204,7 @@ int CLuaEngineDefs::EngineSetModelLODDistance(lua_State* luaVM) } else argStream.SetCustomError( - SString("Expected a valid model name or ID in range [0-%d] at argument 1, got \"%s\"", g_pGame->GetBaseIDforTXD() - 1, *strModelId)); + SString("Expected a valid model name or ID in range [0-%u] at argument 1, got \"%s\"", g_pGame->GetBaseIDforTXD() - 1, *strModelId)); } if (argStream.HasErrors()) m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); @@ -1123,8 +1222,8 @@ int CLuaEngineDefs::EngineResetModelLODDistance(lua_State* luaVM) if (argStream.HasErrors()) return luaL_error(luaVM, argStream.GetFullErrorMessage()); - unsigned short usModelID = CModelNames::ResolveModelID(strModel); - CModelInfo* pModelInfo = g_pGame->GetModelInfo(usModelID); + uint32_t modelId = CModelNames::ResolveModelID(strModel); + CModelInfo* pModelInfo = g_pGame->GetModelInfo(modelId); if (pModelInfo) { float fCurrentDistance = pModelInfo->GetLODDistance(); @@ -1324,9 +1423,12 @@ int CLuaEngineDefs::EngineRemoveShaderFromWorldTexture(lua_State* luaVM) uint CLuaEngineDefs::EngineGetModelTXDID(uint uiModelID) { - CModelInfo* pModelInfo = g_pGame->GetModelInfo(uiModelID); + const int32_t baseTxdId = g_pGame->GetBaseIDforTXD(); + if (baseTxdId <= 0 || uiModelID >= static_cast(baseTxdId)) + throw std::invalid_argument("Expected a valid model ID at argument 1"); - if (uiModelID >= g_pGame->GetBaseIDforTXD() || !pModelInfo) + CModelInfo* pModelInfo = g_pGame->GetModelInfo(uiModelID); + if (!pModelInfo) throw std::invalid_argument("Expected a valid model ID at argument 1"); return pModelInfo->GetTextureDictionaryID(); @@ -1334,22 +1436,86 @@ uint CLuaEngineDefs::EngineGetModelTXDID(uint uiModelID) bool CLuaEngineDefs::EngineSetModelTXDID(uint uiModelID, unsigned short usTxdId) { - CModelInfo* pModelInfo = g_pGame->GetModelInfo(uiModelID); + static uint32_t uiLastPendingTargetLogTime = 0; + static uint uiLastPendingTargetModelId = 0; + static unsigned short usLastPendingTargetTxdId = 0xFFFF; // 0xFFFF = no previous TXD recorded - if (uiModelID >= g_pGame->GetBaseIDforTXD() || !pModelInfo) + const int32_t baseTxdId = g_pGame->GetBaseIDforTXD(); + if (baseTxdId <= 0 || uiModelID >= static_cast(baseTxdId)) throw std::invalid_argument("Expected a valid model ID at argument 1"); + CModelInfo* pModelInfo = g_pGame->GetModelInfo(uiModelID); + if (!pModelInfo) + throw std::invalid_argument("Expected a valid model ID at argument 1"); + + // TXD pool indices range from 0 to (MAX_MODEL_TXD_ID - MAX_MODEL_DFF_ID - 1), + // covering both standard SA slots and overflow slots. + const unsigned short usMaxTxdSlots = static_cast(MAX_MODEL_TXD_ID - MAX_MODEL_DFF_ID); + if (usTxdId >= usMaxTxdSlots) + throw std::invalid_argument("Expected a valid TXD ID at argument 2"); + + // Clean up any existing isolation entry before changing the model's TXD. + // This applies to clone and vanilla models; the cleanup is a no-op when + // theh model has no isolated TXD. + if (CRenderWare* pRenderWare = g_pGame->GetRenderWare()) + pRenderWare->CleanupIsolatedTxdForModel(static_cast(uiModelID)); + + const bool bModelLoaded = pModelInfo->IsLoaded(); + const bool bTargetSlotAllocated = !g_pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(usTxdId); + const bool bTargetTxdLoaded = g_pGame->GetPools()->GetTxdPool().IsTxdLoaded(usTxdId); + if (bModelLoaded && bTargetSlotAllocated && !bTargetTxdLoaded) + { + const unsigned short usCurrentTxdId = pModelInfo->GetTextureDictionaryID(); + const unsigned int uiParentModelId = pModelInfo->GetParentID(); + unsigned short usParentTxdId = 0xFFFF; // 0xFFFF = none + + if (uiParentModelId != 0) + { + if (CModelInfo* pParentModelInfo = g_pGame->GetModelInfo(uiParentModelId)) + usParentTxdId = pParentModelInfo->GetTextureDictionaryID(); + } + + const char* szTargetBand = "standard"; + if (usTxdId >= static_cast(CTxdPool::MAX_STREAMING_TXD_SLOT)) + szTargetBand = "overflow"; + else if (usTxdId >= static_cast(CTxdPool::SA_TXD_POOL_CAPACITY)) + szTargetBand = "overlap-reserved"; + + const uint32_t uiNow = GetTickCount32(); + const bool bSameModelAndTxdPair = (uiLastPendingTargetModelId == uiModelID && usLastPendingTargetTxdId == usTxdId); + // 1000 ms - log at most once per second for the same model/TXD pair + if (!bSameModelAndTxdPair || uiNow - uiLastPendingTargetLogTime >= 1000) + { + uiLastPendingTargetLogTime = uiNow; + uiLastPendingTargetModelId = uiModelID; + usLastPendingTargetTxdId = usTxdId; + + AddReportLog( + 9401, SString("EngineSetModelTXDID: model %u assigned to TXD slot %u (%s band) with no RwTexDictionary; curTxd=%u parentModel=%u parentTxd=%u", + uiModelID, usTxdId, szTargetBand, usCurrentTxdId, uiParentModelId, usParentTxdId)); + } + } + pModelInfo->SetTextureDictionaryID(usTxdId); return true; } bool CLuaEngineDefs::EngineResetModelTXDID(uint uiModelID) { - CModelInfo* pModelInfo = g_pGame->GetModelInfo(uiModelID); + const int32_t baseTxdId = g_pGame->GetBaseIDforTXD(); + if (baseTxdId <= 0 || uiModelID >= static_cast(baseTxdId)) + throw std::invalid_argument("Expected a valid model ID at argument 1"); - if (uiModelID >= g_pGame->GetBaseIDforTXD() || !pModelInfo) + CModelInfo* pModelInfo = g_pGame->GetModelInfo(uiModelID); + if (!pModelInfo) throw std::invalid_argument("Expected a valid model ID at argument 1"); + // Clean up any existing isolation entry before resetting the model TXD. + // This applies to clone and vanilla models; the cleanup is a no-op when + // the model has no isolated TXD. + if (CRenderWare* pRenderWare = g_pGame->GetRenderWare()) + pRenderWare->CleanupIsolatedTxdForModel(static_cast(uiModelID)); + pModelInfo->ResetTextureDictionaryID(); return true; } @@ -1417,11 +1583,11 @@ int CLuaEngineDefs::EngineGetModelTextureNames(lua_State* luaVM) if (!argStream.HasErrors()) { - ushort usModelID = CModelNames::ResolveModelID(strModelName); - if (usModelID != INVALID_MODEL_ID) + uint32_t modelId = CModelNames::ResolveModelID(strModelName); + if (modelId != INVALID_MODEL_ID) { std::vector nameList; - g_pGame->GetRenderWare()->GetModelTextureNames(nameList, usModelID); + g_pGame->GetRenderWare()->GetModelTextureNames(nameList, static_cast(modelId)); lua_newtable(luaVM); for (uint i = 0; i < nameList.size(); i++) @@ -1454,11 +1620,11 @@ int CLuaEngineDefs::EngineGetVisibleTextureNames(lua_State* luaVM) if (!argStream.HasErrors()) { - ushort usModelID = CModelNames::ResolveModelID(strModelName); - if (usModelID != INVALID_MODEL_ID || strModelName == "") + uint32_t modelId = CModelNames::ResolveModelID(strModelName); + if (modelId != INVALID_MODEL_ID || strModelName == "") { std::vector nameList; - g_pCore->GetGraphics()->GetRenderItemManager()->GetVisibleTextureNames(nameList, strTextureNameMatch, usModelID); + g_pCore->GetGraphics()->GetRenderItemManager()->GetVisibleTextureNames(nameList, strTextureNameMatch, static_cast(modelId)); lua_newtable(luaVM); for (uint i = 0; i < nameList.size(); i++) @@ -1481,8 +1647,8 @@ int CLuaEngineDefs::EngineGetVisibleTextureNames(lua_State* luaVM) bool CLuaEngineDefs::EngineSetModelVisibleTime(std::string strModelId, char cHourOn, char cHourOff) { - ushort usModelID = CModelNames::ResolveModelID(strModelId); - CModelInfo* pModelInfo = g_pGame->GetModelInfo(usModelID); + uint32_t modelId = CModelNames::ResolveModelID(strModelId); + CModelInfo* pModelInfo = g_pGame->GetModelInfo(modelId); if (pModelInfo) { if (cHourOn >= 0 && cHourOn <= 24 && cHourOff >= 0 && cHourOff <= 24) @@ -1495,8 +1661,8 @@ bool CLuaEngineDefs::EngineSetModelVisibleTime(std::string strModelId, char cHou std::variant> CLuaEngineDefs::EngineGetModelVisibleTime(std::string strModelId) { - ushort usModelID = CModelNames::ResolveModelID(strModelId); - CModelInfo* pModelInfo = g_pGame->GetModelInfo(usModelID); + uint32_t modelId = CModelNames::ResolveModelID(strModelId); + CModelInfo* pModelInfo = g_pGame->GetModelInfo(modelId); if (pModelInfo) { char cHourOn, cHourOff; @@ -1504,7 +1670,7 @@ std::variant> CLuaEngineDefs::EngineGetModelVi { return std::tuple(cHourOn, cHourOff); } - else // Model is incompatible, don't let confuse user. + else // Model is incompatible, don't let confuse user. { return std::tuple(0, 24); } @@ -1532,9 +1698,9 @@ int CLuaEngineDefs::EngineGetModelTextures(lua_State* luaVM) else if (argStream.NextIsTable()) argStream.ReadStringTable(vTextureNames); - ushort usModelID = CModelNames::ResolveModelID(strModelName); + uint32_t modelId = CModelNames::ResolveModelID(strModelName); - if (usModelID == INVALID_MODEL_ID || !g_pGame->GetRenderWare()->GetModelTextures(textureList, usModelID, vTextureNames)) + if (modelId == INVALID_MODEL_ID || !g_pGame->GetRenderWare()->GetModelTextures(textureList, static_cast(modelId), vTextureNames)) { argStream.SetCustomError("Invalid model ID"); lua_pushboolean(luaVM, false); @@ -1718,7 +1884,7 @@ int CLuaEngineDefs::EngineSetSurfaceProperties(lua_State* luaVM) argStream.ReadNumber(uiTyreGrip); if (!argStream.HasErrors() && uiTyreGrip >= 0 && uiTyreGrip <= 255) { - pSurface->m_tyreGrip = uiTyreGrip; + pSurface->m_tyreGrip = static_cast(uiTyreGrip); lua_pushboolean(luaVM, true); return 1; } @@ -1730,7 +1896,7 @@ int CLuaEngineDefs::EngineSetSurfaceProperties(lua_State* luaVM) argStream.ReadNumber(uiWetGrip); if (!argStream.HasErrors() && uiWetGrip >= 0 && uiWetGrip <= 255) { - pSurface->m_wetGrip = uiWetGrip; + pSurface->m_wetGrip = static_cast(uiWetGrip); lua_pushboolean(luaVM, true); return 1; } @@ -1967,26 +2133,26 @@ int CLuaEngineDefs::EngineResetSurfaceProperties(lua_State* luaVM) int CLuaEngineDefs::EngineGetModelPhysicalPropertiesGroup(lua_State* luaVM) { // int engineGetModelPhysicalPropertiesGroup ( int modelID ) - int iModelID; + unsigned int modelId; CScriptArgReader argStream(luaVM); - argStream.ReadNumber(iModelID); + argStream.ReadNumber(modelId); if (!argStream.HasErrors()) { - if (iModelID < 0 || iModelID >= g_pGame->GetBaseIDforTXD()) + if (modelId >= g_pGame->GetBaseIDforTXD()) { - argStream.SetCustomError(SString("Expected model ID in range [0-%d] at argument 1", g_pGame->GetBaseIDforTXD() - 1)); + argStream.SetCustomError(SString("Expected model ID in range [0-%u] at argument 1", g_pGame->GetBaseIDforTXD() - 1)); return luaL_error(luaVM, argStream.GetFullErrorMessage()); } - auto pModelInfo = g_pGame->GetModelInfo(iModelID); - if (pModelInfo) + if (auto pModelInfo = g_pGame->GetModelInfo(modelId); pModelInfo != nullptr) { uint16_t groupId = pModelInfo->GetObjectPropertiesGroup(); lua_pushnumber(luaVM, groupId == 0xFFFF ? -1 : groupId); return 1; } + argStream.SetCustomError("Expected valid model ID at argument 1"); } @@ -1996,18 +2162,18 @@ int CLuaEngineDefs::EngineGetModelPhysicalPropertiesGroup(lua_State* luaVM) int CLuaEngineDefs::EngineSetModelPhysicalPropertiesGroup(lua_State* luaVM) { // bool engineSetModelPhysicalPropertiesGroup ( int modelID, int newGroup ) - int iModelID; - int iNewGroup; + uint32_t modelId; + int iNewGroup; CScriptArgReader argStream(luaVM); - argStream.ReadNumber(iModelID); + argStream.ReadNumber(modelId); argStream.ReadNumber(iNewGroup); if (!argStream.HasErrors()) { - if (iModelID < 0 || iModelID > g_pGame->GetBaseIDforTXD() - 1) + if (modelId > g_pGame->GetBaseIDforTXD() - 1) { - argStream.SetCustomError(SString("Expected model ID in range [0-%d] at argument 1", g_pGame->GetBaseIDforTXD() - 1)); + argStream.SetCustomError(SString("Expected model ID in range [0-%u] at argument 1", g_pGame->GetBaseIDforTXD() - 1)); return luaL_error(luaVM, argStream.GetFullErrorMessage()); } @@ -2017,13 +2183,13 @@ int CLuaEngineDefs::EngineSetModelPhysicalPropertiesGroup(lua_State* luaVM) return luaL_error(luaVM, argStream.GetFullErrorMessage()); } - auto pModelInfo = g_pGame->GetModelInfo(iModelID); - if (pModelInfo) + if (auto pModelInfo = g_pGame->GetModelInfo(modelId); pModelInfo != nullptr) { - pModelInfo->SetObjectPropertiesGroup(iNewGroup); + pModelInfo->SetObjectPropertiesGroup(static_cast(iNewGroup)); lua_pushboolean(luaVM, true); return 1; } + argStream.SetCustomError("Expected valid model ID at argument 1"); } @@ -2033,26 +2199,26 @@ int CLuaEngineDefs::EngineSetModelPhysicalPropertiesGroup(lua_State* luaVM) int CLuaEngineDefs::EngineRestoreModelPhysicalPropertiesGroup(lua_State* luaVM) { // bool engineRestoreModelPhysicalPropertiesGroup ( int modelID ) - int iModelID; + uint32_t modelId; CScriptArgReader argStream(luaVM); - argStream.ReadNumber(iModelID); + argStream.ReadNumber(modelId); if (!argStream.HasErrors()) { - if (iModelID < 0 || iModelID > g_pGame->GetBaseIDforTXD() - 1) + if (modelId > g_pGame->GetBaseIDforTXD() - 1) { - argStream.SetCustomError(SString("Expected model ID in range [0-%d] at argument 1", g_pGame->GetBaseIDforTXD() - 1)); + argStream.SetCustomError(SString("Expected model ID in range [0-%u] at argument 1", g_pGame->GetBaseIDforTXD() - 1)); return luaL_error(luaVM, argStream.GetFullErrorMessage()); } - auto pModelInfo = g_pGame->GetModelInfo(iModelID); - if (pModelInfo) + if (auto pModelInfo = g_pGame->GetModelInfo(modelId); pModelInfo != nullptr) { pModelInfo->RestoreObjectPropertiesGroup(); lua_pushboolean(luaVM, true); return 1; } + argStream.SetCustomError("Expected valid model ID at argument 1"); } @@ -2066,9 +2232,12 @@ std::unordered_mapSetElasticity(fValue); }}, {ObjectGroupPhysicalProperties::Modifiable::BUOYANCY, [](CObjectGroupPhysicalProperties* pGroup, float fValue) { pGroup->SetBuoyancy(fValue); }}, {ObjectGroupPhysicalProperties::Modifiable::UPROOTLIMIT, [](CObjectGroupPhysicalProperties* pGroup, float fValue) { pGroup->SetUprootLimit(fValue); }}, - {ObjectGroupPhysicalProperties::Modifiable::COLDAMAGEMULTIPLIER, [](CObjectGroupPhysicalProperties* pGroup, float fValue) { pGroup->SetCollisionDamageMultiplier(fValue); }}, - {ObjectGroupPhysicalProperties::Modifiable::SMASHMULTIPLIER, [](CObjectGroupPhysicalProperties* pGroup, float fValue) { pGroup->SetSmashMultiplier(fValue); }}, - {ObjectGroupPhysicalProperties::Modifiable::BREAKVELOCITYRAND, [](CObjectGroupPhysicalProperties* pGroup, float fValue) { pGroup->SetBreakVelocityRandomness(fValue); }}, + {ObjectGroupPhysicalProperties::Modifiable::COLDAMAGEMULTIPLIER, + [](CObjectGroupPhysicalProperties* pGroup, float fValue) { pGroup->SetCollisionDamageMultiplier(fValue); }}, + {ObjectGroupPhysicalProperties::Modifiable::SMASHMULTIPLIER, + [](CObjectGroupPhysicalProperties* pGroup, float fValue) { pGroup->SetSmashMultiplier(fValue); }}, + {ObjectGroupPhysicalProperties::Modifiable::BREAKVELOCITYRAND, + [](CObjectGroupPhysicalProperties* pGroup, float fValue) { pGroup->SetBreakVelocityRandomness(fValue); }}, }; std::unordered_map> g_GroupPropertiesSettersBool{ {ObjectGroupPhysicalProperties::Modifiable::CAMERAAVOID, [](CObjectGroupPhysicalProperties* pGroup, bool bValue) { pGroup->SetCameraAvoidObject(bValue); }}, @@ -2077,13 +2246,14 @@ std::unordered_map> g_GroupPropertiesSettersVector{ {ObjectGroupPhysicalProperties::Modifiable::FXOFFSET, [](CObjectGroupPhysicalProperties* pGroup, CVector vecValue) { pGroup->SetFxOffset(vecValue); }}, - {ObjectGroupPhysicalProperties::Modifiable::BREAKVELOCITY, [](CObjectGroupPhysicalProperties* pGroup, CVector vecValue) { pGroup->SetBreakVelocity(vecValue); }}, + {ObjectGroupPhysicalProperties::Modifiable::BREAKVELOCITY, + [](CObjectGroupPhysicalProperties* pGroup, CVector vecValue) { pGroup->SetBreakVelocity(vecValue); }}, }; int CLuaEngineDefs::EngineSetObjectGroupPhysicalProperty(lua_State* luaVM) { // bool engineSetObjectGroupPhysicalProperty ( int groupID, string property, ...) - int iGivenGroup; + int iGivenGroup; ObjectGroupPhysicalProperties::Modifiable eProperty; CScriptArgReader argStream(luaVM); @@ -2099,7 +2269,7 @@ int CLuaEngineDefs::EngineSetObjectGroupPhysicalProperty(lua_State* luaVM) return luaL_error(luaVM, argStream.GetFullErrorMessage()); } - auto pGroup = g_pGame->GetObjectGroupPhysicalProperties(iGivenGroup); + auto pGroup = g_pGame->GetObjectGroupPhysicalProperties(static_cast(iGivenGroup)); if (!pGroup) { argStream.SetCustomError("Expected valid group ID at argument 1"); @@ -2250,7 +2420,8 @@ std::unordered_mapGetElasticity(); }}, {ObjectGroupPhysicalProperties::Modifiable::BUOYANCY, [](CObjectGroupPhysicalProperties* pGroup) { return pGroup->GetBuoyancy(); }}, {ObjectGroupPhysicalProperties::Modifiable::UPROOTLIMIT, [](CObjectGroupPhysicalProperties* pGroup) { return pGroup->GetUprootLimit(); }}, - {ObjectGroupPhysicalProperties::Modifiable::COLDAMAGEMULTIPLIER, [](CObjectGroupPhysicalProperties* pGroup) { return pGroup->GetCollisionDamageMultiplier(); }}, + {ObjectGroupPhysicalProperties::Modifiable::COLDAMAGEMULTIPLIER, + [](CObjectGroupPhysicalProperties* pGroup) { return pGroup->GetCollisionDamageMultiplier(); }}, {ObjectGroupPhysicalProperties::Modifiable::SMASHMULTIPLIER, [](CObjectGroupPhysicalProperties* pGroup) { return pGroup->GetSmashMultiplier(); }}, {ObjectGroupPhysicalProperties::Modifiable::BREAKVELOCITYRAND, [](CObjectGroupPhysicalProperties* pGroup) { return pGroup->GetBreakVelocityRandomness(); }}, }; @@ -2266,7 +2437,7 @@ std::unordered_mapGetObjectGroupPhysicalProperties(iGivenGroup); + auto pGroup = g_pGame->GetObjectGroupPhysicalProperties(static_cast(iGivenGroup)); if (!pGroup) { argStream.SetCustomError("Expected valid group ID at argument 1"); @@ -2383,7 +2554,7 @@ int CLuaEngineDefs::EngineRestoreObjectGroupPhysicalProperties(lua_State* luaVM) return luaL_error(luaVM, argStream.GetFullErrorMessage()); } - auto pGroup = g_pGame->GetObjectGroupPhysicalProperties(iGivenGroup); + auto pGroup = g_pGame->GetObjectGroupPhysicalProperties(static_cast(iGivenGroup)); if (!pGroup) { argStream.SetCustomError("Expected valid group ID at argument 1"); @@ -2427,7 +2598,7 @@ bool CLuaEngineDefs::EngineSetModelFlags(uint uiModelID, uint uiFlags, std::opti if (bIdeFlags.value_or(false)) pModelInfo->SetIdeFlags(uiFlags); else - pModelInfo->SetFlags(uiFlags); + pModelInfo->SetFlags(static_cast(uiFlags)); return true; } @@ -2470,7 +2641,7 @@ bool CLuaEngineDefs::EngineRestreamWorld() return true; } -uint CLuaEngineDefs::EngineRequestTXD(lua_State* const luaVM, std::string strTxdName) +std::variant CLuaEngineDefs::EngineRequestTXD(lua_State* const luaVM, std::string strTxdName) { if (strTxdName.size() > 24) throw std::invalid_argument("TXD name length shoudn't be more than 24 characters"); @@ -2479,19 +2650,33 @@ uint CLuaEngineDefs::EngineRequestTXD(lua_State* const luaVM, std::string strTxd if (iModelID == INVALID_MODEL_ID) return false; - std::shared_ptr pModel = m_pManager->GetModelManager()->Request(m_pManager, iModelID, eClientModelType::TXD); + auto modelManager = m_pManager->GetModelManager(); + std::shared_ptr pModel = modelManager->Request(m_pManager, iModelID, eClientModelType::TXD); + + if (!pModel) + return false; - pModel->AllocateTXD(strTxdName); pModel->SetParentResource(m_pLuaManager->GetVirtualMachine(luaVM)->GetResource()); - m_pManager->GetModelManager()->Add(pModel); - return iModelID - MAX_MODEL_DFF_ID; + if (!modelManager->TryAdd(pModel)) + return false; + + if (!pModel->AllocateTXD(strTxdName)) + { + modelManager->Remove(pModel); + return false; + } + + return static_cast(iModelID - MAX_MODEL_DFF_ID); } bool CLuaEngineDefs::EngineFreeTXD(uint txdID) { - std::shared_ptr pModel = m_pManager->GetModelManager()->FindModelByID(MAX_MODEL_DFF_ID + txdID); - return pModel && pModel->Deallocate(); + auto modelManager = m_pManager->GetModelManager(); + std::shared_ptr pModel = modelManager->FindModelByID(MAX_MODEL_DFF_ID + txdID); + + // Use the manager removal path so RestoreTXD runs and the TXD slot is actually freed. + return pModel && modelManager->Remove(pModel); } size_t CLuaEngineDefs::EngineGetPoolCapacity(ePools pool) @@ -2579,7 +2764,11 @@ eModelLoadState CLuaEngineDefs::EngineStreamingGetModelLoadState(std::uint16_t m if (modelId >= g_pGame->GetCountOfAllFileIDs()) throw std::invalid_argument("Expected a valid model ID at argument 1"); - return g_pGame->GetStreaming()->GetStreamingInfo(modelId)->loadState; + auto* pStreamingInfo = g_pGame->GetStreaming()->GetStreamingInfo(modelId); + if (!pStreamingInfo) + return eModelLoadState::LOADSTATE_NOT_LOADED; + + return pStreamingInfo->loadState; } void CLuaEngineDefs::EnginePreloadWorldArea(CVector position, std::optional option) @@ -2593,3 +2782,13 @@ void CLuaEngineDefs::EnginePreloadWorldArea(CVector position, std::optionalGetStreaming()->LoadSceneCollision(&position); } + +bool CLuaEngineDefs::EngineRestreamModel(std::uint16_t modelId) +{ + return g_pClientGame->RestreamModel(modelId); +} + +void CLuaEngineDefs::EngineRestream(std::optional option) +{ + g_pClientGame->Restream(option); +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index 48fa2706a41..628e067e107 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -74,7 +74,7 @@ class CLuaEngineDefs : public CLuaDefs static bool EngineRemoveImage(CClientIMG* pImg); static uint EngineImageGetFilesCount(CClientIMG* pImg); static bool EngineImageLinkDFF(CClientIMG* pImg, std::variant file, uint uiModelID); - static bool EngineImageLinkTXD(CClientIMG* pImg, std::variant file, uint uiModelID); + static bool EngineImageLinkTXD(CClientIMG* pImg, std::variant file, uint uiTxdID); static bool EngineRestoreDFFImage(uint uiModelID); static bool EngineRestoreTXDImage(uint uiModelID); static std::vector EngineImageGetFileList(CClientIMG* pImg); @@ -88,14 +88,16 @@ class CLuaEngineDefs : public CLuaDefs static size_t EngineGetPoolUsedCapacity(ePools pool); static bool EngineSetPoolCapacity(lua_State* luaVM, ePools pool, size_t newSize); - static uint EngineRequestTXD(lua_State* const luaVM, std::string strTxdName); - static bool EngineFreeTXD(uint txdID); + static std::variant EngineRequestTXD(lua_State* const luaVM, std::string strTxdName); + static bool EngineFreeTXD(uint txdID); static bool EngineStreamingRequestModel(lua_State* const luaVM, std::uint16_t modelId, std::optional addReference, std::optional blocking); static bool EngineStreamingReleaseModel(lua_State* const luaVM, std::uint16_t modelId, std::optional removeReference); static eModelLoadState EngineStreamingGetModelLoadState(std::uint16_t modelId); static void EnginePreloadWorldArea(CVector position, std::optional option); + static bool EngineRestreamModel(std::uint16_t modelId); + static void EngineRestream(std::optional option); private: static void AddEngineColClass(lua_State* luaVM); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp index 6a564c5a778..5471c8e6089 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp @@ -2424,7 +2424,7 @@ int CLuaGUIDefs::GUIGridListInsertRowAfter(lua_State* luaVM) else { // Vector containing our string arguments. We add a bool to store whether it was originally a number. - std::vector > m_items; + std::vector> m_items; for (CLuaArgument* pArgument : Arguments) { SString strItemText; @@ -2569,7 +2569,7 @@ int CLuaGUIDefs::GUIGridListGetSelectedItem(lua_State* luaVM) int iRow = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemRow(); int iColumn = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemColumn(); lua_pushnumber(luaVM, iRow); - lua_pushnumber(luaVM, iColumn + 1); // columns start at 1 + lua_pushnumber(luaVM, iColumn + 1); // columns start at 1 return 2; } else diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.cpp index 1f921eaa333..70ece841563 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.cpp @@ -182,8 +182,9 @@ int CLuaMarkerDefs::GetMarkerColor(lua_State* luaVM) lua_pushnumber(luaVM, static_cast(color.G)); lua_pushnumber(luaVM, static_cast(color.B)); - if (!pMarker->AreAlphaLimitsIgnored() && (pMarker->GetMarkerType() == CClientMarker::MARKER_CHECKPOINT || pMarker->GetMarkerType() == CClientMarker::MARKER_ARROW)) - lua_pushnumber(luaVM, 255); // fake alpha + if (!pMarker->AreAlphaLimitsIgnored() && + (pMarker->GetMarkerType() == CClientMarker::MARKER_CHECKPOINT || pMarker->GetMarkerType() == CClientMarker::MARKER_ARROW)) + lua_pushnumber(luaVM, 255); // fake alpha else lua_pushnumber(luaVM, static_cast(color.A)); @@ -260,7 +261,7 @@ int CLuaMarkerDefs::GetMarkerIcon(lua_State* luaVM) if (pCheckpoint) { SString strMarkerIcon; - CClientCheckpoint::IconToString(pCheckpoint->GetIcon(), strMarkerIcon); + CClientCheckpoint::IconToString(static_cast(pCheckpoint->GetIcon()), strMarkerIcon); lua_pushstring(luaVM, strMarkerIcon); return 1; } @@ -427,7 +428,8 @@ bool CLuaMarkerDefs::IsCoronaReflectionEnabled(CClientMarker* pMarker) return pCorona->IsReflectionEnabled(); } -bool CLuaMarkerDefs::SetMarkerTargetArrowProperties(CClientMarker* marker, std::optional r, std::optional g, std::optional b, std::optional a, std::optional size) +bool CLuaMarkerDefs::SetMarkerTargetArrowProperties(CClientMarker* marker, std::optional r, std::optional g, + std::optional b, std::optional a, std::optional size) { SColor color; color.R = r.value_or(255); @@ -438,7 +440,8 @@ bool CLuaMarkerDefs::SetMarkerTargetArrowProperties(CClientMarker* marker, std:: return CStaticFunctionDefinitions::SetMarkerTargetArrowProperties(*marker, color, size.value_or(marker->GetSize() * 0.625f)); } -std::variant, bool> CLuaMarkerDefs::GetMarkerTargetArrowProperties(CClientMarker* marker) noexcept +std::variant, bool> CLuaMarkerDefs::GetMarkerTargetArrowProperties( + CClientMarker* marker) noexcept { CClientCheckpoint* checkpoint = marker->GetCheckpoint(); if (!checkpoint) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.h index d32aadfb03d..b48dedeea7a 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.h @@ -37,6 +37,8 @@ class CLuaMarkerDefs : public CLuaDefs static bool SetCoronaReflectionEnabled(CClientMarker* pMarker, bool bEnabled); static bool IsCoronaReflectionEnabled(CClientMarker* pMarker); - static bool SetMarkerTargetArrowProperties(CClientMarker* marker, std::optional r, std::optional g, std::optional b, std::optional a, std::optional size); - static std::variant, bool> GetMarkerTargetArrowProperties(CClientMarker* marker) noexcept; + static bool SetMarkerTargetArrowProperties(CClientMarker* marker, std::optional r, std::optional g, + std::optional b, std::optional a, std::optional size); + static std::variant, bool> GetMarkerTargetArrowProperties( + CClientMarker* marker) noexcept; }; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp index 35e05386335..714d2a9eec2 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp @@ -252,7 +252,7 @@ int CLuaObjectDefs::GetObjectProperties(lua_State* luaVM) int CLuaObjectDefs::GetObjectProperty(lua_State* luaVM) { // float, float, float getObjectProperty ( object theObject, string property ) - CClientObject* pObject; + CClientObject* pObject; ObjectProperty eProp; CScriptArgReader argStream(luaVM); @@ -610,7 +610,7 @@ int CLuaObjectDefs::SetObjectMass(lua_State* luaVM) int CLuaObjectDefs::SetObjectProperty(lua_State* luaVM) { // bool setObjectProperty ( object theObject, string property, ... ) - CClientEntity* pEntity; + CClientEntity* pEntity; ObjectProperty eProp; CScriptArgReader argStream(luaVM); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp index 9d1dab664de..450214d624f 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp @@ -18,7 +18,7 @@ #include "CLuaPedDefs.h" #define MIN_CLIENT_REQ_REMOVEPEDFROMVEHICLE_CLIENTSIDE "1.3.0-9.04482" -#define MIN_CLIENT_REQ_WARPPEDINTOVEHICLE_CLIENTSIDE "1.3.0-9.04482" +#define MIN_CLIENT_REQ_WARPPEDINTOVEHICLE_CLIENTSIDE "1.3.0-9.04482" void CLuaPedDefs::LoadFunctions() { @@ -75,7 +75,7 @@ void CLuaPedDefs::LoadFunctions() {"getPedAnimation", GetPedAnimation}, {"getPedAnimationProgress", ArgumentParser}, {"getPedAnimationSpeed", ArgumentParser}, - {"getPedAnimationLength", ArgumentParser}, + {"getPedAnimationLength", ArgumentParser}, {"getPedWalkingStyle", GetPedMoveAnim}, {"getPedControlState", ArgumentParserWarn}, {"getPedAnalogControlState", GetPedAnalogControlState}, @@ -141,7 +141,7 @@ void CLuaPedDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "canBeKnockedOffBike", "canPedBeKnockedOffBike"); lua_classfunction(luaVM, "doesHaveJetPack", "doesPedHaveJetPack"); - lua_classfunction(luaVM, "isWearingJetpack", "isPedWearingJetpack"); // introduced in 1.5.5-9.13846 + lua_classfunction(luaVM, "isWearingJetpack", "isPedWearingJetpack"); // introduced in 1.5.5-9.13846 lua_classfunction(luaVM, "getAmmoInClip", "getPedAmmoInClip"); lua_classfunction(luaVM, "getAnalogControlState", "getPedAnalogControlState"); lua_classfunction(luaVM, "getAnimation", "getPedAnimation"); @@ -218,7 +218,7 @@ void CLuaPedDefs::AddClass(lua_State* luaVM) lua_classvariable(luaVM, "vehicleSeat", NULL, "getPedOccupiedVehicleSeat"); lua_classvariable(luaVM, "canBeKnockedOffBike", "setPedCanBeKnockedOffBike", "canPedBeKnockedOffBike"); lua_classvariable(luaVM, "hasJetPack", NULL, "doesPedHaveJetPack"); - lua_classvariable(luaVM, "jetpack", NULL, "isPedWearingJetpack"); // introduced in 1.5.5-9.13846 + lua_classvariable(luaVM, "jetpack", NULL, "isPedWearingJetpack"); // introduced in 1.5.5-9.13846 lua_classvariable(luaVM, "armor", "setPedArmor", "getPedArmor"); lua_classvariable(luaVM, "fightingStyle", "setPedFightingStyle", "getPedFightingStyle"); lua_classvariable(luaVM, "cameraRotation", "setPedCameraRotation", "getPedCameraRotation"); @@ -914,13 +914,15 @@ int CLuaPedDefs::IsPedOnGround(lua_State* luaVM) { // Verify the argument CClientPed* pPed = NULL; + bool checkVehicles = false; CScriptArgReader argStream(luaVM); argStream.ReadUserData(pPed); + argStream.ReadBool(checkVehicles, false); if (!argStream.HasErrors()) { // Find out whether he's on the ground or not and return it - bool bOnGround = pPed->IsOnGround(); + bool bOnGround = pPed->IsOnGround(checkVehicles); lua_pushboolean(luaVM, bOnGround); return 1; } @@ -1001,7 +1003,7 @@ std::variant> CLuaPedDefs::GetElement throw std::invalid_argument("Invalid bone: " + std::to_string(bone)); CEntity* entity = ped->GetGameEntity(); - CVector position; + CVector position; if (!entity || !entity->GetBonePosition(static_cast(bone), position)) return false; @@ -1018,7 +1020,7 @@ std::variant> CLuaPedDefs::GetElement float yaw = 0.0f; float pitch = 0.0f; float roll = 0.0f; - + if (!entity || !entity->GetBoneRotation(static_cast(bone), yaw, pitch, roll)) return false; @@ -1132,7 +1134,7 @@ bool CLuaPedDefs::UpdateElementRpHAnim(CClientPed* ped) if (clump) { - ((void(__cdecl*)(RpClump*))0x5DF560)(clump); // CPed::ShoulderBoneRotation + ((void(__cdecl*)(RpClump*))0x5DF560)(clump); // CPed::ShoulderBoneRotation } return true; @@ -1260,7 +1262,7 @@ bool CLuaPedDefs::IsPedReloadingWeapon(CClientPed* const ped) noexcept { return ped->IsReloadingWeapon(); } - + int CLuaPedDefs::GetPedClothes(lua_State* luaVM) { // Verify the argument @@ -1311,7 +1313,7 @@ bool CLuaPedDefs::GetPedControlState(std::variant firs } bool state; - + if (!CStaticFunctionDefinitions::GetPedControlState(*ped, control, state)) return false; @@ -1802,6 +1804,13 @@ int CLuaPedDefs::IsPedDead(lua_State* luaVM) { // Grab his dead state and return it bool bDead = pPed->IsDead() || pPed->IsDying(); + + // Check player is already dead on network (#4147) + if (auto pPlayer = dynamic_cast(pPed)) + { + bDead = bDead || pPlayer->IsDeadOnNetwork(); + } + lua_pushboolean(luaVM, bDead); return 1; } @@ -1929,7 +1938,7 @@ bool CLuaPedDefs::SetPedFightingStyle(CClientEntity* const entity, const unsigne if (style < 4 || style > 16) throw std::invalid_argument("Style can only be between 4 and 16"); - return CStaticFunctionDefinitions::SetPedFightingStyle(*entity, style); + return CStaticFunctionDefinitions::SetPedFightingStyle(*entity, static_cast(style)); } int CLuaPedDefs::SetPedLookAt(lua_State* luaVM) @@ -2233,9 +2242,9 @@ int CLuaPedDefs::SetPedAnimation(lua_State* luaVM) CScriptArgReader argStream(luaVM); argStream.ReadUserData(pEntity); if (argStream.NextIsBool()) - argStream.ReadBool(bDummy); // Wiki used setPedAnimation(source,false) as an example + argStream.ReadBool(bDummy); // Wiki used setPedAnimation(source,false) as an example else if (argStream.NextIsNil()) - argStream.m_iIndex++; // Wiki docs said blockName could be nil + argStream.m_iIndex++; // Wiki docs said blockName could be nil else argStream.ReadString(strBlockName, ""); argStream.ReadString(strAnimName, ""); @@ -2509,11 +2518,29 @@ int CLuaPedDefs::DetonateSatchels(lua_State* luaVM) return 1; } -bool CLuaPedDefs::SetPedEnterVehicle(CClientPed* pPed, std::optional pOptVehicle, std::optional bOptPassenger) +bool CLuaPedDefs::SetPedEnterVehicle(CClientPed* pPed, std::optional pOptVehicle, + std::optional> seatOrPassenger) { - CClientVehicle* pVehicle = pOptVehicle.value_or(nullptr); - bool bPassenger = bOptPassenger.value_or(false); - return pPed->EnterVehicle(pVehicle, bPassenger); + CClientVehicle* pVehicle = pOptVehicle.value_or(nullptr); + bool bPassenger = false; + std::optional optSeat; + + // Parse third argument: either a bool (passenger flag) or int (seat number) + if (seatOrPassenger.has_value()) + { + if (std::holds_alternative(seatOrPassenger.value())) + { + // Third argument is bool - treat as passenger flag + bPassenger = std::get(seatOrPassenger.value()); + } + else if (std::holds_alternative(seatOrPassenger.value())) + { + // Third argument is int - treat as seat number + optSeat = std::get(seatOrPassenger.value()); + } + } + + return pPed->EnterVehicle(pVehicle, bPassenger, optSeat); } bool CLuaPedDefs::SetPedExitVehicle(CClientPed* pPed) @@ -2521,7 +2548,7 @@ bool CLuaPedDefs::SetPedExitVehicle(CClientPed* pPed) return pPed->ExitVehicle(); } -bool CLuaPedDefs::killPedTask(CClientPed* ped, taskType taskType, std::uint8_t taskNumber, std::optional gracefully) +bool CLuaPedDefs::killPedTask(CClientPed* ped, taskType taskType, std::uint8_t taskNumber, std::optional gracefully) { switch (taskType) { @@ -2533,7 +2560,7 @@ bool CLuaPedDefs::killPedTask(CClientPed* ped, taskType taskType, std::uint8_t t if (taskNumber >= TASK_PRIORITY_MAX) throw LuaFunctionError("Invalid task slot number"); - return ped->KillTask(taskNumber, gracefully.value_or(true)); + return ped->KillTask(taskNumber, gracefully.value_or(true)); } case taskType::SECONDARY_TASK: { @@ -2543,7 +2570,7 @@ bool CLuaPedDefs::killPedTask(CClientPed* ped, taskType taskType, std::uint8_t t return ped->KillTaskSecondary(taskNumber, gracefully.value_or(true)); } default: - return false; + return false; } } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.h index 20ec1aa5909..8f9e386bf8d 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.h @@ -51,8 +51,8 @@ class CLuaPedDefs : public CLuaDefs LUA_DECLARE(GetPedRotation); LUA_DECLARE(CanPedBeKnockedOffBike); - static std::variant> GetElementBonePosition(CClientPed* ped, const std::uint16_t bone); - static std::variant> GetElementBoneRotation(CClientPed* ped, const std::uint16_t bone); + static std::variant> GetElementBonePosition(CClientPed* ped, const std::uint16_t bone); + static std::variant> GetElementBoneRotation(CClientPed* ped, const std::uint16_t bone); static std::variant> GetElementBoneQuaternion(CClientPed* ped, const std::uint16_t bone); static std::variant, 4>> GetElementBoneMatrix(CClientPed* ped, const std::uint16_t bone); @@ -96,8 +96,7 @@ class CLuaPedDefs : public CLuaDefs static bool IsPedReloadingWeapon(CClientPed* const ped) noexcept; LUA_DECLARE(AddPedClothes); LUA_DECLARE(RemovePedClothes); - static bool SetPedControlState(std::variant first, std::variant second, - std::optional maybeState); + static bool SetPedControlState(std::variant first, std::variant second, std::optional maybeState); LUA_DECLARE(SetPedAnalogControlState); LUA_DECLARE(SetPedDoingGangDriveby); static bool SetPedFightingStyle(CClientEntity* const entity, const unsigned int style); @@ -112,11 +111,12 @@ class CLuaPedDefs : public CLuaDefs LUA_DECLARE(RemovePedFromVehicle); LUA_DECLARE(SetPedOxygenLevel); LUA_DECLARE(SetPedStat); - static bool SetPedEnterVehicle(CClientPed* pPed, std::optional pOptVehicle, std::optional bOptPassenger); + static bool SetPedEnterVehicle(CClientPed* pPed, std::optional pOptVehicle, + std::optional> seatOrPassenger); static bool SetPedExitVehicle(CClientPed* pPed); static bool IsPedBleeding(CClientPed* ped); static bool SetPedBleeding(CClientPed* ped, bool bleeding); - + static bool killPedTask(CClientPed* ped, taskType taskType, std::uint8_t taskNumber, std::optional gracefully); static void PlayPedVoiceLine(CClientPed* ped, int speechId, std::optional probability); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp index 5ae695f0f87..e6f8a8d9e57 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp @@ -492,7 +492,8 @@ int CLuaPlayerDefs::SetPlayerNametagColor(lua_State* luaVM) if (!argStream.HasErrors()) { - if (CStaticFunctionDefinitions::SetPlayerNametagColor(*pPlayer, false, iR, iG, iB)) + if (CStaticFunctionDefinitions::SetPlayerNametagColor(*pPlayer, false, static_cast(iR), static_cast(iG), + static_cast(iB))) { lua_pushboolean(luaVM, true); return 1; @@ -651,9 +652,11 @@ bool CLuaPlayerDefs::IsPlayerCrosshairVisible() return g_pGame->GetHud()->IsCrosshairVisible(); } -bool CLuaPlayerDefs::SetPlayerHudComponentProperty(eHudComponent component, eHudComponentProperty property, std::variant value) +bool CLuaPlayerDefs::SetPlayerHudComponentProperty(eHudComponent component, eHudComponentProperty property, + std::variant value) { - if (component == HUD_ALL || component == HUD_CROSSHAIR || component == HUD_VITAL_STATS || component == HUD_HELP_TEXT || component == HUD_RADAR) + if (component == HUD_ALL || component == HUD_CROSSHAIR || component == HUD_VITAL_STATS || component == HUD_HELP_TEXT || component == HUD_RADAR || + component == HUD_RADAR_MAP || component == HUD_RADAR_BLIPS || component == HUD_RADAR_ALTIMETER) return false; CHud* hud = g_pGame->GetHud(); @@ -885,7 +888,7 @@ bool CLuaPlayerDefs::ResetPlayerHudComponentProperty(eHudComponent component, eH } case eHudComponentProperty::BLINKING_HP_VALUE: { - if (!component != HUD_HEALTH) + if (component != HUD_HEALTH) return false; hud->SetHealthBarBlinkingValue(10.0f); @@ -937,9 +940,10 @@ bool CLuaPlayerDefs::ResetPlayerHudComponentProperty(eHudComponent component, eH } return false; -} +} -std::variant, CLuaMultiReturn> CLuaPlayerDefs::GetPlayerHudComponentProperty(eHudComponent component, eHudComponentProperty property) +std::variant, CLuaMultiReturn> +CLuaPlayerDefs::GetPlayerHudComponentProperty(eHudComponent component, eHudComponentProperty property) { if (component == HUD_ALL || component == HUD_CROSSHAIR || component == HUD_VITAL_STATS || component == HUD_HELP_TEXT || component == HUD_RADAR) return false; @@ -950,12 +954,12 @@ std::variant, CLuaMultiR { case eHudComponentProperty::POSITION: { - CVector2D& pos = hud->GetComponentPosition(component); + CVector2D pos = hud->GetComponentPosition(component); return CLuaMultiReturn{pos.fX, pos.fY}; } case eHudComponentProperty::SIZE: { - CVector2D& size = hud->GetComponentSize(component); + CVector2D size = hud->GetComponentSize(component); return CLuaMultiReturn{size.fX, size.fY}; } case eHudComponentProperty::FILL_COLOR: @@ -963,7 +967,7 @@ std::variant, CLuaMultiR if (!hud->IsComponentBar(component) && !hud->IsComponentText(component) && component != HUD_WEAPON) return false; - SColor& color = hud->GetComponentColor(component); + SColor color = hud->GetComponentColor(component); return CLuaMultiReturn{color.R, color.G, color.B, color.A}; } case eHudComponentProperty::FILL_COLOR_SECONDARY: @@ -971,7 +975,7 @@ std::variant, CLuaMultiR if (component != HUD_RADIO && component != HUD_MONEY && component != HUD_WANTED && component != HUD_WEAPON) return false; - SColor& color = hud->GetComponentSecondaryColor(component); + SColor color = hud->GetComponentSecondaryColor(component); return CLuaMultiReturn{color.R, color.G, color.B, color.A}; } case eHudComponentProperty::DROP_COLOR: @@ -979,7 +983,7 @@ std::variant, CLuaMultiR if (!hud->IsComponentText(component)) return false; - SColor& color = hud->GetComponentFontDropColor(component); + SColor color = hud->GetComponentFontDropColor(component); return CLuaMultiReturn{color.R, color.G, color.B, color.A}; } case eHudComponentProperty::DRAW_BLACK_BORDER: @@ -1039,10 +1043,12 @@ std::variant, CLuaMultiR return hud->GetComponentFontProportional(component); } case eHudComponentProperty::CUSTOM_ALPHA: + { return hud->GetComponentUseCustomAlpha(component); + } case eHudComponentProperty::TEXT_SIZE: { - CVector2D& size = hud->GetComponentTextSize(component); + CVector2D size = hud->GetComponentTextSize(component); return CLuaMultiReturn{size.fX, size.fY}; } } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h index 1bc08998a47..a051291bf28 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h @@ -31,7 +31,8 @@ class CLuaPlayerDefs : public CLuaDefs LUA_DECLARE(GetPlayerWantedLevel); static std::uint8_t GetPlayerScriptDebugLevel() noexcept; static bool IsPlayerCrosshairVisible(); - static std::variant, CLuaMultiReturn> GetPlayerHudComponentProperty(eHudComponent component, eHudComponentProperty property); + static std::variant, CLuaMultiReturn> + GetPlayerHudComponentProperty(eHudComponent component, eHudComponentProperty property); // Player set LUA_DECLARE(ShowPlayerHudComponent); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPointLightDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaPointLightDefs.h index 6d0811d0d68..066d0f58a8a 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPointLightDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPointLightDefs.h @@ -26,4 +26,4 @@ class CLuaPointLightDefs : public CLuaDefs LUA_DECLARE(SetLightRadius); LUA_DECLARE(SetLightColor); LUA_DECLARE(SetLightDirection); -}; \ No newline at end of file +}; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPostfxDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaPostfxDefs.cpp new file mode 100644 index 00000000000..3dc6728b9c0 --- /dev/null +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPostfxDefs.cpp @@ -0,0 +1,70 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/luadefs/CLuaPostfxDefs.cpp + * PURPOSE: Lua definitions class + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include "CLuaPostfxDefs.h" +#include + +void CLuaPostfxDefs::LoadFunctions() +{ + constexpr static const std::pair functions[]{ + {"getPostFXValue", ArgumentParser}, + {"getPostFXMode", ArgumentParser}, + {"isPostFXEnabled", ArgumentParser}, + }; + + // Add functions + for (const auto& [name, func] : functions) + CLuaCFunctions::AddFunction(name, func); +} + +float CLuaPostfxDefs::GetPostFXValue(PostFXType type) +{ + switch (type) + { + case PostFXType::GAMMA: + return g_pCore->GetCVars()->GetValue("borderless_gamma_power", 0.0f); + case PostFXType::BRIGHTNESS: + return g_pCore->GetCVars()->GetValue("borderless_brightness_scale", 0.0f); + case PostFXType::CONTRAST: + return g_pCore->GetCVars()->GetValue("borderless_contrast_scale", 0.0f); + case PostFXType::SATURATION: + return g_pCore->GetCVars()->GetValue("borderless_saturation_scale", 0.0f); + + default: + throw std::invalid_argument("Invalid PostFX type"); + } +} + +int CLuaPostfxDefs::GetPostFXMode() +{ + return g_pCore->GetCVars()->GetValue("borderless_apply_fullscreen", false) ? 1 + : g_pCore->GetCVars()->GetValue("borderless_apply_windowed", false) ? 2 + : 0; +} + +bool CLuaPostfxDefs::IsPostFXEnabled(PostFXType type) +{ + switch (type) + { + case PostFXType::GAMMA: + return g_pCore->GetCVars()->GetValue("borderless_gamma_enabled", false); + case PostFXType::BRIGHTNESS: + return g_pCore->GetCVars()->GetValue("borderless_brightness_enabled", false); + case PostFXType::CONTRAST: + return g_pCore->GetCVars()->GetValue("borderless_brightness_enabled", false); + case PostFXType::SATURATION: + return g_pCore->GetCVars()->GetValue("borderless_saturation_enabled", false); + + default: + throw std::invalid_argument("Invalid PostFX type"); + } +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPostfxDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaPostfxDefs.h new file mode 100644 index 00000000000..832e0f60401 --- /dev/null +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPostfxDefs.h @@ -0,0 +1,23 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/luadefs/CLuaPostfxDefs.h + * PURPOSE: Lua definitions class + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "luadefs/CLuaDefs.h" + +class CLuaPostfxDefs : public CLuaDefs +{ +public: + static void LoadFunctions(); + +private: + static float GetPostFXValue(PostFXType type); + static int GetPostFXMode(); + static bool IsPostFXEnabled(PostFXType type); +}; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp index 265c6383b1f..bbde4f6d6d6 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp @@ -26,6 +26,7 @@ void CLuaResourceDefs::LoadFunctions() {"getResourceGUIElement", GetResourceGUIElement}, {"getResourceDynamicElementRoot", GetResourceDynamicElementRoot}, {"getResourceExportedFunctions", GetResourceExportedFunctions}, + {"getResources", ArgumentParser}, {"getResourceState", GetResourceState}, {"loadstring", LoadString}, {"load", Load}, @@ -89,7 +90,7 @@ int CLuaResourceDefs::Call(lua_State* luaVM) args.ReadArguments(luaVM, 3); CLuaArguments returns; - LUA_CHECKSTACK(targetLuaVM, 1); // Ensure some room + LUA_CHECKSTACK(targetLuaVM, 1); // Ensure some room // Lets grab the original hidden variables so we can restore them later lua_getglobal(targetLuaVM, "sourceResource"); @@ -411,6 +412,11 @@ int CLuaResourceDefs::GetResourceState(lua_State* luaVM) return 1; } +std::vector CLuaResourceDefs::GetResources() +{ + return {m_pResourceManager->IterBegin(), m_pResourceManager->IterEnd()}; +} + int CLuaResourceDefs::LoadString(lua_State* luaVM) { // func,err loadstring( string text[, string name] ) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h index 38d3bc8ac61..663e2969e86 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h @@ -27,6 +27,7 @@ class CLuaResourceDefs : public CLuaDefs LUA_DECLARE(GetResourceDynamicElementRoot); LUA_DECLARE(GetResourceExportedFunctions); LUA_DECLARE(GetResourceState); + static std::vector GetResources(); LUA_DECLARE(LoadString); LUA_DECLARE(Load); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaSearchLightDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaSearchLightDefs.cpp index 89c2380d412..0ec6f63e8a1 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaSearchLightDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaSearchLightDefs.cpp @@ -20,11 +20,13 @@ void CLuaSearchLightDefs::LoadFunctions() {"getSearchLightEndPosition", GetSearchLightEndPosition}, {"getSearchLightStartRadius", GetSearchLightStartRadius}, {"getSearchLightEndRadius", GetSearchLightEndRadius}, + {"getSearchLightColor", ArgumentParser}, {"setSearchLightStartPosition", SetSearchLightStartPosition}, {"setSearchLightEndPosition", SetSearchLightEndPosition}, {"setSearchLightStartRadius", SetSearchLightStartRadius}, {"setSearchLightEndRadius", SetSearchLightEndRadius}, + {"setSearchLightColor", ArgumentParser}, }; // Add functions @@ -312,3 +314,14 @@ int CLuaSearchLightDefs::OOP_GetSearchLightEndPosition(lua_State* luaVM) lua_pushboolean(luaVM, false); return 1; } + +CLuaMultiReturn CLuaSearchLightDefs::GetSearchLightColor(CClientSearchLight* searchLight) +{ + SColor color = searchLight->GetColor(); + return CLuaMultiReturn{color.R, color.G, color.B, color.A}; +} + +void CLuaSearchLightDefs::SetSearchLightColor(CClientSearchLight* searchLight, SColor color) +{ + searchLight->SetColor(color); +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaSearchLightDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaSearchLightDefs.h index 3eed77904e8..2baab4032bc 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaSearchLightDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaSearchLightDefs.h @@ -29,4 +29,7 @@ class CLuaSearchLightDefs : public CLuaDefs LUA_DECLARE(SetSearchLightEndPosition); LUA_DECLARE(SetSearchLightStartRadius); LUA_DECLARE(SetSearchLightEndRadius); + + static CLuaMultiReturn GetSearchLightColor(CClientSearchLight* searchLight); + static void SetSearchLightColor(CClientSearchLight* searchLight, SColor color); }; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaTeamDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaTeamDefs.cpp index 28944179b9d..7e8450a681f 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaTeamDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaTeamDefs.cpp @@ -13,13 +13,9 @@ void CLuaTeamDefs::LoadFunctions() { constexpr static const std::pair functions[]{ - {"getTeamFromName", ArgumentParserWarn}, - {"getTeamName", ArgumentParserWarn}, - {"getTeamColor", ArgumentParserWarn}, - {"getTeamFriendlyFire", ArgumentParserWarn}, - {"getPlayersInTeam", ArgumentParserWarn}, - {"countPlayersInTeam", ArgumentParserWarn} - }; + {"getTeamFromName", ArgumentParserWarn}, {"getTeamName", ArgumentParserWarn}, + {"getTeamColor", ArgumentParserWarn}, {"getTeamFriendlyFire", ArgumentParserWarn}, + {"getPlayersInTeam", ArgumentParserWarn}, {"countPlayersInTeam", ArgumentParserWarn}}; // Add functions for (const auto& [name, func] : functions) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaTeamDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaTeamDefs.h index e3de95df131..46cdc9969ce 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaTeamDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaTeamDefs.h @@ -18,10 +18,10 @@ class CLuaTeamDefs : public CLuaDefs static void AddClass(lua_State* luaVM); private: - static std::variant GetTeamFromName(const std::string name) noexcept; - static std::string GetTeamName(CClientTeam* team); + static std::variant GetTeamFromName(const std::string name) noexcept; + static std::string GetTeamName(CClientTeam* team); static CLuaMultiReturn GetTeamColor(CClientTeam* team) noexcept; - static bool GetTeamFriendlyFire(CClientTeam* team) noexcept; - static std::vector GetPlayersInTeam(CClientTeam* team); - static std::uint32_t CountPlayersInTeam(CClientTeam* team) noexcept; + static bool GetTeamFriendlyFire(CClientTeam* team) noexcept; + static std::vector GetPlayersInTeam(CClientTeam* team); + static std::uint32_t CountPlayersInTeam(CClientTeam* team) noexcept; }; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp index 0d022164fa5..4de67d4c1a5 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp @@ -15,9 +15,14 @@ void CLuaTimerDefs::LoadFunctions() { constexpr static const std::pair functions[]{ - {"setTimer", SetTimer}, {"killTimer", KillTimer}, {"resetTimer", ResetTimer}, - {"setTimerPaused", ArgumentParser},{"isTimerPaused", ArgumentParser}, - {"getTimers", GetTimers}, {"isTimer", IsTimer}, {"getTimerDetails", GetTimerDetails}, + {"setTimer", SetTimer}, + {"killTimer", KillTimer}, + {"resetTimer", ResetTimer}, + {"setTimerPaused", ArgumentParser}, + {"isTimerPaused", ArgumentParser}, + {"getTimers", GetTimers}, + {"isTimer", IsTimer}, + {"getTimerDetails", GetTimerDetails}, }; // Add functions diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaVectorGraphicDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaVectorGraphicDefs.cpp index eba1e21d0ce..a22252c4b02 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaVectorGraphicDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaVectorGraphicDefs.cpp @@ -110,7 +110,7 @@ bool CLuaVectorGraphicDefs::SetSize(CClientVectorGraphic* vectorGraphic, CVector int intSizeX = static_cast(size.fX); int intSizeY = static_cast(size.fY); - vectorGraphicItem->Resize(CVector2D(intSizeX, intSizeY)); + vectorGraphicItem->Resize(CVector2D(static_cast(intSizeX), static_cast(intSizeY))); vectorGraphic->GetDisplay()->Update(); return true; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp index 80bbccfa219..d45bdf2b908 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp @@ -18,6 +18,8 @@ #include "enums/HandlingProperty.h" +#include + void CLuaVehicleDefs::LoadFunctions() { constexpr static const std::pair functions[]{ @@ -64,7 +66,6 @@ void CLuaVehicleDefs::LoadFunctions() {"isTrainDerailable", IsTrainDerailable}, {"getTrainDirection", GetTrainDirection}, {"getTrainSpeed", GetTrainSpeed}, - //{"getTrainTrack", ArgumentParser}, {"getTrainPosition", GetTrainPosition}, {"isTrainChainEngine", IsTrainChainEngine}, {"getVehicleGravity", GetVehicleGravity}, @@ -136,7 +137,6 @@ void CLuaVehicleDefs::LoadFunctions() {"setTrainDerailable", SetTrainDerailable}, {"setTrainDirection", SetTrainDirection}, {"setTrainSpeed", SetTrainSpeed}, - //{"setTrainTrack", ArgumentParser}, {"setTrainPosition", SetTrainPosition}, {"setVehicleTaxiLightOn", SetVehicleTaxiLightOn}, {"setVehicleGravity", SetVehicleGravity}, @@ -177,6 +177,13 @@ void CLuaVehicleDefs::LoadFunctions() // Add functions for (const auto& [name, func] : functions) CLuaCFunctions::AddFunction(name, func); + + // Add train track related functions + if (CLuaShared::CustomTrainTracks) + { + CLuaCFunctions::AddFunction("getTrainTrack", ArgumentParser); + CLuaCFunctions::AddFunction("setTrainTrack", ArgumentParser); + } } void CLuaVehicleDefs::AddClass(lua_State* luaVM) @@ -206,7 +213,8 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "getNitroLevel", "getVehicleNitroLevel"); lua_classfunction(luaVM, "getDirection", "getTrainDirection"); lua_classfunction(luaVM, "getTrainSpeed", "getTrainSpeed"); - // lua_classfunction(luaVM, "getTrack", "getTrainTrack"); + if (CLuaShared::CustomTrainTracks) + lua_classfunction(luaVM, "getTrainTrack", "getTrainTrack"); lua_classfunction(luaVM, "getTrainPosition", "getTrainPosition"); lua_classfunction(luaVM, "getName", "getVehicleName"); lua_classfunction(luaVM, "getVehicleType", "getVehicleType"); @@ -295,7 +303,8 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "setNitroLevel", "setVehicleNitroLevel"); lua_classfunction(luaVM, "setDirection", "setTrainDirection"); lua_classfunction(luaVM, "setTrainSpeed", "setTrainSpeed"); - // lua_classfunction(luaVM, "setTrack", "setTrainTrack"); + if (CLuaShared::CustomTrainTracks) + lua_classfunction(luaVM, "setTrainTrack", "setTrainTrack"); lua_classfunction(luaVM, "setTrainPosition", "setTrainPosition"); lua_classfunction(luaVM, "setDerailable", "setTrainDerailable"); lua_classfunction(luaVM, "setDerailed", "setTrainDerailed"); @@ -360,7 +369,8 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classvariable(luaVM, "towedByVehicle", NULL, "getVehicleTowedByVehicle"); lua_classvariable(luaVM, "direction", "setTrainDirection", "getTrainDirection"); lua_classvariable(luaVM, "trainSpeed", "setTrainSpeed", "getTrainSpeed"); - // lua_classvariable(luaVM, "track", "setTrainTrack", "getTrainTrack"); + if (CLuaShared::CustomTrainTracks) + lua_classvariable(luaVM, "trainTrack", "setTrainTrack", "getTrainTrack"); lua_classvariable(luaVM, "trainPosition", "setTrainPosition", "getTrainPosition"); lua_classvariable(luaVM, "derailable", "setTrainDerailable", "isTrainDerailable"); lua_classvariable(luaVM, "derailed", "setTrainDerailed", "isTrainDerailed"); @@ -399,7 +409,7 @@ int CLuaVehicleDefs::GetVehicleType(lua_State* luaVM) if (!argStream.HasErrors()) { - lua_pushstring(luaVM, CVehicleNames::GetVehicleTypeName(ucModel)); // Range check will be done by GetVehicleTypeName + lua_pushstring(luaVM, CVehicleNames::GetVehicleTypeName(ucModel)); // Range check will be done by GetVehicleTypeName return 1; } else @@ -910,10 +920,10 @@ int CLuaVehicleDefs::GetVehicleUpgradeSlotName(lua_State* luaVM) int CLuaVehicleDefs::GetVehicleCompatibleUpgrades(lua_State* luaVM) { CClientVehicle* pVehicle = NULL; - unsigned char ucSlot = 0xFF; + unsigned int uiSlot = 0xFF; CScriptArgReader argStream(luaVM); argStream.ReadUserData(pVehicle); - argStream.ReadIfNextIsNumber(ucSlot, 0xFF); + argStream.ReadIfNextIsNumber(uiSlot, 0xFF); if (!argStream.HasErrors()) { @@ -928,13 +938,13 @@ int CLuaVehicleDefs::GetVehicleCompatibleUpgrades(lua_State* luaVM) { if (pUpgrades->IsUpgradeCompatible(usUpgrade)) { - if (ucSlot != 0xFF) + if (uiSlot != 0xFF) { unsigned char ucUpgradeSlot; if (!pUpgrades->GetSlotFromUpgrade(usUpgrade, ucUpgradeSlot)) continue; - if (ucUpgradeSlot != ucSlot) + if (ucUpgradeSlot != static_cast(uiSlot)) continue; } @@ -2569,8 +2579,8 @@ int CLuaVehicleDefs::SetVehicleHandling(lua_State* luaVM) } break; } - case HandlingProperty::HANDLING_PERCENTSUBMERGED: // unsigned int - // case HANDLING_MONETARY: + case HandlingProperty::HANDLING_PERCENTSUBMERGED: // unsigned int + // case HANDLING_MONETARY: case HandlingProperty::HANDLING_HANDLINGFLAGS: case HandlingProperty::HANDLING_MODELFLAGS: { @@ -2691,7 +2701,7 @@ int CLuaVehicleDefs::GetVehicleHandling(lua_State* luaVM) SString strProperty; argStream.ReadString(strProperty); - bool bResult = true; + bool bResult = true; HandlingProperty eProperty = g_pGame->GetHandlingManager()->GetPropertyEnumFromName(strProperty); if (eProperty != HandlingProperty::HANDLING_MAX) { @@ -2787,7 +2797,7 @@ int CLuaVehicleDefs::GetVehicleHandling(lua_State* luaVM) lua_pushstring(luaVM, "rwd"); else if (eDriveType == CHandlingEntry::FOURWHEEL) lua_pushstring(luaVM, "awd"); - else // What the ... (yeah, security) + else // What the ... (yeah, security) lua_pushnil(luaVM); lua_setfield(luaVM, -2, "driveType"); CHandlingEntry::eEngineType eEngineType = entry->GetCarEngineType(); @@ -2943,7 +2953,7 @@ int CLuaVehicleDefs::GetOriginalHandling(lua_State* luaVM) lua_pushstring(luaVM, "rwd"); else if (eDriveType == CHandlingEntry::FOURWHEEL) lua_pushstring(luaVM, "awd"); - else // What the ... (yeah, security) + else // What the ... (yeah, security) lua_pushnil(luaVM); lua_setfield(luaVM, -2, "driveType"); CHandlingEntry::eEngineType eEngineType = entry->GetCarEngineType(); @@ -3075,37 +3085,37 @@ int CLuaVehicleDefs::GetVehicleSirenParams(lua_State* luaVM) argStream.ReadUserData(pVehicle); if (!argStream.HasErrors()) { - tSirenInfo = pVehicle->m_tSirenBeaconInfo; // Grab the siren structure data + tSirenInfo = pVehicle->m_tSirenBeaconInfo; // Grab the siren structure data lua_newtable(luaVM); lua_pushstring(luaVM, "SirenCount"); lua_pushnumber(luaVM, tSirenInfo.m_ucSirenCount); - lua_settable(luaVM, -3); // End of SirenCount Property + lua_settable(luaVM, -3); // End of SirenCount Property lua_pushstring(luaVM, "SirenType"); lua_pushnumber(luaVM, tSirenInfo.m_ucSirenType); - lua_settable(luaVM, -3); // End of SirenType Property + lua_settable(luaVM, -3); // End of SirenType Property lua_pushstring(luaVM, "Flags"); lua_newtable(luaVM); lua_pushstring(luaVM, "360"); lua_pushboolean(luaVM, tSirenInfo.m_b360Flag); - lua_settable(luaVM, -3); // End of 360 Property + lua_settable(luaVM, -3); // End of 360 Property lua_pushstring(luaVM, "DoLOSCheck"); lua_pushboolean(luaVM, tSirenInfo.m_bDoLOSCheck); - lua_settable(luaVM, -3); // End of DoLOSCheck Property + lua_settable(luaVM, -3); // End of DoLOSCheck Property lua_pushstring(luaVM, "UseRandomiser"); lua_pushboolean(luaVM, tSirenInfo.m_bUseRandomiser); - lua_settable(luaVM, -3); // End of UseRandomiser Property + lua_settable(luaVM, -3); // End of UseRandomiser Property lua_pushstring(luaVM, "Silent"); lua_pushboolean(luaVM, tSirenInfo.m_bSirenSilent); - lua_settable(luaVM, -3); // End of Silent Property + lua_settable(luaVM, -3); // End of Silent Property - lua_settable(luaVM, -3); // End of table + lua_settable(luaVM, -3); // End of table return 1; } @@ -3126,7 +3136,7 @@ int CLuaVehicleDefs::GetVehicleSirens(lua_State* luaVM) argStream.ReadUserData(pVehicle); if (!argStream.HasErrors()) { - tSirenInfo = pVehicle->m_tSirenBeaconInfo; // Grab the siren structure data + tSirenInfo = pVehicle->m_tSirenBeaconInfo; // Grab the siren structure data lua_newtable(luaVM); for (int i = 0; i < tSirenInfo.m_ucSirenCount; i++) @@ -3136,37 +3146,37 @@ int CLuaVehicleDefs::GetVehicleSirens(lua_State* luaVM) lua_pushstring(luaVM, "Min_Alpha"); lua_pushnumber(luaVM, tSirenInfo.m_tSirenInfo[i].m_dwMinSirenAlpha); - lua_settable(luaVM, -3); // End of Min_Alpha property + lua_settable(luaVM, -3); // End of Min_Alpha property lua_pushstring(luaVM, "Red"); lua_pushnumber(luaVM, tSirenInfo.m_tSirenInfo[i].m_RGBBeaconColour.R); - lua_settable(luaVM, -3); // End of Red property + lua_settable(luaVM, -3); // End of Red property lua_pushstring(luaVM, "Green"); lua_pushnumber(luaVM, tSirenInfo.m_tSirenInfo[i].m_RGBBeaconColour.G); - lua_settable(luaVM, -3); // End of Green property + lua_settable(luaVM, -3); // End of Green property lua_pushstring(luaVM, "Blue"); lua_pushnumber(luaVM, tSirenInfo.m_tSirenInfo[i].m_RGBBeaconColour.B); - lua_settable(luaVM, -3); // End of Blue property + lua_settable(luaVM, -3); // End of Blue property lua_pushstring(luaVM, "Alpha"); lua_pushnumber(luaVM, tSirenInfo.m_tSirenInfo[i].m_RGBBeaconColour.A); - lua_settable(luaVM, -3); // End of Alpha property + lua_settable(luaVM, -3); // End of Alpha property lua_pushstring(luaVM, "x"); lua_pushnumber(luaVM, tSirenInfo.m_tSirenInfo[i].m_vecSirenPositions.fX); - lua_settable(luaVM, -3); // End of X property + lua_settable(luaVM, -3); // End of X property lua_pushstring(luaVM, "y"); lua_pushnumber(luaVM, tSirenInfo.m_tSirenInfo[i].m_vecSirenPositions.fY); - lua_settable(luaVM, -3); // End of Y property + lua_settable(luaVM, -3); // End of Y property lua_pushstring(luaVM, "z"); lua_pushnumber(luaVM, tSirenInfo.m_tSirenInfo[i].m_vecSirenPositions.fZ); - lua_settable(luaVM, -3); // End of Z property + lua_settable(luaVM, -3); // End of Z property - lua_settable(luaVM, -3); // End of Table + lua_settable(luaVM, -3); // End of Table } return 1; @@ -3663,7 +3673,7 @@ int CLuaVehicleDefs::GetVehicleComponents(lua_State* luaVM) { lua_pushstring(luaVM, (*iter).first); lua_pushboolean(luaVM, (*iter).second.m_bVisible); - lua_settable(luaVM, -3); // End of Table + lua_settable(luaVM, -3); // End of Table } return 1; } @@ -3977,9 +3987,9 @@ int CLuaVehicleDefs::IsVehicleWindowOpen(lua_State* luaVM) int CLuaVehicleDefs::SetVehicleModelDummyPosition(lua_State* luaVM) { // bool setVehicleModelDummyPosition ( int modelID, vehicle-dummy dummy, float x, float y, float z ) - unsigned short usModel; + unsigned short usModel; VehicleDummies eDummy; - CVector vecPosition; + CVector vecPosition; CScriptArgReader argStream(luaVM); argStream.ReadNumber(usModel); @@ -4004,7 +4014,7 @@ int CLuaVehicleDefs::SetVehicleModelDummyPosition(lua_State* luaVM) int CLuaVehicleDefs::GetVehicleModelDummyPosition(lua_State* luaVM) { // float, float, float getVehicleModelDummyPosition ( int modelID, vehicle-dummy dummy ) - unsigned short usModel; + unsigned short usModel; VehicleDummies eDummy; CScriptArgReader argStream(luaVM); @@ -4033,7 +4043,7 @@ int CLuaVehicleDefs::GetVehicleModelDummyPosition(lua_State* luaVM) int CLuaVehicleDefs::OOP_GetVehicleModelDummyPosition(lua_State* luaVM) { // float, float, float getVehicleModelDummyPosition ( int modelID, vehicle-dummy dummy ) - unsigned short usModel; + unsigned short usModel; VehicleDummies eDummy; CScriptArgReader argStream(luaVM); @@ -4205,17 +4215,21 @@ bool CLuaVehicleDefs::SetVehicleModelWheelSize(const unsigned short usModel, con int CLuaVehicleDefs::GetVehicleWheelFrictionState(CClientVehicle* pVehicle, unsigned char wheel) { - if (wheel < 0 || wheel > 3) + if (wheel >= MAX_WHEELS) throw std::invalid_argument("Invalid wheel number"); - if (CClientVehicleManager::GetVehicleType(pVehicle->GetModel()) != CLIENTVEHICLE_CAR) - throw std::invalid_argument("Invalid vehicle type"); + auto vehicleType = pVehicle->GetVehicleType(); + + if (vehicleType == CLIENTVEHICLE_CAR || vehicleType == CLIENTVEHICLE_MONSTERTRUCK || vehicleType == CLIENTVEHICLE_QUADBIKE || + vehicleType == CLIENTVEHICLE_BIKE || vehicleType == CLIENTVEHICLE_BMX || vehicleType == CLIENTVEHICLE_TRAILER) + { + return pVehicle->GetWheelFrictionState(wheel); + } - return pVehicle->GetWheelFrictionState(wheel); + throw std::invalid_argument("Invalid vehicle type"); } -std::variant> CLuaVehicleDefs::GetVehicleModelDummyDefaultPosition(unsigned short vehicleModel, - VehicleDummies dummy) +std::variant> CLuaVehicleDefs::GetVehicleModelDummyDefaultPosition(unsigned short vehicleModel, VehicleDummies dummy) { CVector position; @@ -4432,69 +4446,132 @@ bool CLuaVehicleDefs::SetVehicleModelAudioSetting(const uint32_t uiModel, const { if (!CClientVehicleManager::IsStandardModel(uiModel)) throw std::invalid_argument("Cannot change audio setting for allocated vechiles"); - + + const auto toInt = [](float value) -> int + { + const int iValue = static_cast(value); + if (static_cast(iValue) != value) + throw std::invalid_argument("Expected an integer value"); + + return iValue; + }; + + const auto toChar = [&toInt](float value) -> char + { + const int iValue = toInt(value); + if (iValue < std::numeric_limits::min() || iValue > std::numeric_limits::max()) + throw std::invalid_argument("Value out of range"); + + return static_cast(iValue); + }; + CVehicleAudioSettingsEntry& pModelSettings = g_pGame->GetVehicleAudioSettingsManager()->GetVehicleModelAudioSettingsData(uiModel); switch (eProperty) { case VehicleAudioSettingProperty::DOOR_SOUND: - pModelSettings.SetDoorSound(varValue); + { + pModelSettings.SetDoorSound(toChar(varValue)); break; + } case VehicleAudioSettingProperty::ENGINE_OFF_SOUND_BANK_ID: { // Using SPC_ sound banks other than SPC_EA causes a crash - if (varValue > 410) + const int iValue = toInt(varValue); + if (iValue < 0 || iValue > 410) throw std::invalid_argument("Invalid engine-off-sound-bank-id value"); - pModelSettings.SetEngineOffSoundBankID(varValue); + pModelSettings.SetEngineOffSoundBankID(static_cast(iValue)); break; } case VehicleAudioSettingProperty::ENGINE_ON_SOUND_BANK_ID: { // Using SPC_ sound banks other than SPC_EA causes a crash - if (varValue > 410) + const int iValue = toInt(varValue); + if (iValue < 0 || iValue > 410) throw std::invalid_argument("Invalid engine-on-sound-bank-id value"); - pModelSettings.SetEngineOnSoundBankID(varValue); + pModelSettings.SetEngineOnSoundBankID(static_cast(iValue)); break; } case VehicleAudioSettingProperty::HORN_HIGH: + { pModelSettings.SetHornHign(varValue); break; + } case VehicleAudioSettingProperty::HORN_TON: - pModelSettings.SetHornTon(varValue); + { + pModelSettings.SetHornTon(toChar(varValue)); break; + } case VehicleAudioSettingProperty::HORN_VOLUME_DELTA: + { pModelSettings.SetHornVolumeDelta(varValue); break; + } case VehicleAudioSettingProperty::RADIO_NUM: - pModelSettings.SetRadioNum(varValue); + { + pModelSettings.SetRadioNum(toChar(varValue)); break; + } case VehicleAudioSettingProperty::RADIO_TYPE: - pModelSettings.SetRadioType(varValue); + { + pModelSettings.SetRadioType(toChar(varValue)); break; + } case VehicleAudioSettingProperty::SOUND_TYPE: - pModelSettings.SetSoundType((VehicleSoundType)(int)(varValue)); + { + const int iValue = toInt(varValue); + if (!((iValue >= 0 && iValue <= 5) || (iValue >= 8 && iValue <= 10))) + throw std::invalid_argument("Invalid sound-type value"); + + pModelSettings.SetSoundType(static_cast(iValue)); break; + } case VehicleAudioSettingProperty::BASS_SETTING: - pModelSettings.SetBassSetting(varValue); + { + const int iValue = toInt(varValue); + if (iValue < 0 || iValue > 2) + throw std::invalid_argument("Invalid bass-setting value"); + + pModelSettings.SetBassSetting(static_cast(iValue)); break; + } case VehicleAudioSettingProperty::BASS_EQ: + { pModelSettings.SetBassEq(varValue); break; + } case VehicleAudioSettingProperty::FIELD_C: + { pModelSettings.SetFieldC(varValue); break; + } case VehicleAudioSettingProperty::ENGINE_UPGRADE: - pModelSettings.SetEngineUpgrade(varValue); + { + pModelSettings.SetEngineUpgrade(toChar(varValue)); break; + } case VehicleAudioSettingProperty::VEHICLE_TYPE_FOR_AUDIO: - pModelSettings.SetVehicleTypeForAudio(varValue); + { + pModelSettings.SetVehicleTypeForAudio(toChar(varValue)); break; + } default: return false; } + auto iter = g_pClientGame->GetVehicleManager()->IterBegin(); + auto end = g_pClientGame->GetVehicleManager()->IterEnd(); + for (; iter != end; ++iter) + { + CClientVehicle* pVehicle = *iter; + if (pVehicle && pVehicle->GetModel() == uiModel) + { + pVehicle->ApplyAudioSettings(); + } + } + return true; } @@ -4503,69 +4580,123 @@ bool CLuaVehicleDefs::ResetVehicleModelAudioSettings(const uint32_t uiModel) if (!CClientVehicleManager::IsStandardModel(uiModel)) throw std::invalid_argument("Cannot change audio setting for allocated vechiles"); - g_pGame->GetVehicleAudioSettingsManager()->ResetModelSettings(uiModel); + g_pGame->GetVehicleAudioSettingsManager()->ResetModelSettings(uiModel); + + return true; } bool CLuaVehicleDefs::SetVehicleAudioSetting(CClientVehicle* pVehicle, const VehicleAudioSettingProperty eProperty, float varValue) { CVehicleAudioSettingsEntry& pModelSettings = pVehicle->GetOrCreateAudioSettings(); + const auto toInt = [](float value) -> int + { + const int iValue = static_cast(value); + if (static_cast(iValue) != value) + throw std::invalid_argument("Expected an integer value"); + + return iValue; + }; + + const auto toChar = [&toInt](float value) -> char + { + const int iValue = toInt(value); + if (iValue < std::numeric_limits::min() || iValue > std::numeric_limits::max()) + throw std::invalid_argument("Value out of range"); + + return static_cast(iValue); + }; + switch (eProperty) { case VehicleAudioSettingProperty::DOOR_SOUND: - pModelSettings.SetDoorSound(varValue); + { + pModelSettings.SetDoorSound(toChar(varValue)); break; + } case VehicleAudioSettingProperty::ENGINE_OFF_SOUND_BANK_ID: { // Using SPC_ sound banks other than SPC_EA causes a crash - if (varValue > 410) + const int iValue = toInt(varValue); + if (iValue < 0 || iValue > 410) throw std::invalid_argument("Invalid engine-off-sound-bank-id value"); - pModelSettings.SetEngineOffSoundBankID(varValue); + pModelSettings.SetEngineOffSoundBankID(static_cast(iValue)); break; } case VehicleAudioSettingProperty::ENGINE_ON_SOUND_BANK_ID: { // Using SPC_ sound banks other than SPC_EA causes a crash - if (varValue > 410) + const int iValue = toInt(varValue); + if (iValue < 0 || iValue > 410) throw std::invalid_argument("Invalid engine-on-sound-bank-id value"); - pModelSettings.SetEngineOnSoundBankID(varValue); + pModelSettings.SetEngineOnSoundBankID(static_cast(iValue)); break; } case VehicleAudioSettingProperty::HORN_HIGH: + { pModelSettings.SetHornHign(varValue); break; + } case VehicleAudioSettingProperty::HORN_TON: - pModelSettings.SetHornTon(varValue); + { + pModelSettings.SetHornTon(toChar(varValue)); break; + } case VehicleAudioSettingProperty::HORN_VOLUME_DELTA: + { pModelSettings.SetHornVolumeDelta(varValue); break; + } case VehicleAudioSettingProperty::RADIO_NUM: - pModelSettings.SetRadioNum(varValue); + { + pModelSettings.SetRadioNum(toChar(varValue)); break; + } case VehicleAudioSettingProperty::RADIO_TYPE: - pModelSettings.SetRadioType(varValue); + { + pModelSettings.SetRadioType(toChar(varValue)); break; + } case VehicleAudioSettingProperty::SOUND_TYPE: - pModelSettings.SetSoundType((VehicleSoundType)(int)(varValue)); + { + const int iValue = toInt(varValue); + if (!((iValue >= 0 && iValue <= 5) || (iValue >= 8 && iValue <= 10))) + throw std::invalid_argument("Invalid sound-type value"); + + pModelSettings.SetSoundType(static_cast(iValue)); break; + } case VehicleAudioSettingProperty::BASS_SETTING: - pModelSettings.SetBassSetting(varValue); + { + const int iValue = toInt(varValue); + if (iValue < 0 || iValue > 2) + throw std::invalid_argument("Invalid bass-setting value"); + + pModelSettings.SetBassSetting(static_cast(iValue)); break; + } case VehicleAudioSettingProperty::BASS_EQ: + { pModelSettings.SetBassEq(varValue); break; + } case VehicleAudioSettingProperty::FIELD_C: + { pModelSettings.SetFieldC(varValue); break; + } case VehicleAudioSettingProperty::ENGINE_UPGRADE: - pModelSettings.SetEngineUpgrade(varValue); + { + pModelSettings.SetEngineUpgrade(toChar(varValue)); break; + } case VehicleAudioSettingProperty::VEHICLE_TYPE_FOR_AUDIO: - pModelSettings.SetVehicleTypeForAudio(varValue); + { + pModelSettings.SetVehicleTypeForAudio(toChar(varValue)); break; + } default: return false; } @@ -4600,19 +4731,19 @@ std::unordered_map CLuaVehicleDefs::GetVehicleModelAudioSett std::unordered_map output; - output["sound-type"] = (int)pEntry.GetSoundType(); - output["engine-on-soundbank-id"] = pEntry.GetEngineOnSoundBankID(); - output["engine-off-soundbank-id"] = pEntry.GetEngineOffSoundBankID(); - output["bass-setting"] = pEntry.GetBassSetting(); + output["sound-type"] = static_cast(static_cast(pEntry.GetSoundType())); + output["engine-on-soundbank-id"] = static_cast(pEntry.GetEngineOnSoundBankID()); + output["engine-off-soundbank-id"] = static_cast(pEntry.GetEngineOffSoundBankID()); + output["bass-setting"] = static_cast(pEntry.GetBassSetting()); output["bass-eq"] = pEntry.GetBassEq(); output["field-c"] = pEntry.GetFieldC(); - output["horn-ton"] = pEntry.GetHornTon(); + output["horn-ton"] = static_cast(pEntry.GetHornTon()); output["horn-high"] = pEntry.GetHornHign(); - output["engine-upgrade"] = pEntry.GetEngineUpgrade(); - output["door-sound"] = pEntry.GetDoorSound(); - output["radio-num"] = pEntry.GetRadioNum(); - output["radio-type"] = pEntry.GetRadioType(); - output["vehicle-type-for-audio"] = pEntry.GetVehicleTypeForAudio(); + output["engine-upgrade"] = static_cast(pEntry.GetEngineUpgrade()); + output["door-sound"] = static_cast(pEntry.GetDoorSound()); + output["radio-num"] = static_cast(pEntry.GetRadioNum()); + output["radio-type"] = static_cast(pEntry.GetRadioType()); + output["vehicle-type-for-audio"] = static_cast(pEntry.GetVehicleTypeForAudio()); output["horn-volume-delta"] = pEntry.GetHornVolumeDelta(); return output; @@ -4624,21 +4755,20 @@ std::unordered_map CLuaVehicleDefs::GetVehicleAudioSettings( std::unordered_map output; - output["sound-type"] = (int)pEntry.GetSoundType(); - output["engine-on-soundbank-id"] = pEntry.GetEngineOnSoundBankID(); - output["engine-off-soundbank-id"] = pEntry.GetEngineOffSoundBankID(); - output["bass-setting"] = pEntry.GetBassSetting(); + output["sound-type"] = static_cast(static_cast(pEntry.GetSoundType())); + output["engine-on-soundbank-id"] = static_cast(pEntry.GetEngineOnSoundBankID()); + output["engine-off-soundbank-id"] = static_cast(pEntry.GetEngineOffSoundBankID()); + output["bass-setting"] = static_cast(pEntry.GetBassSetting()); output["bass-eq"] = pEntry.GetBassEq(); output["field-c"] = pEntry.GetFieldC(); - output["horn-ton"] = pEntry.GetHornTon(); + output["horn-ton"] = static_cast(pEntry.GetHornTon()); output["horn-high"] = pEntry.GetHornHign(); - output["engine-upgrade"] = pEntry.GetEngineUpgrade(); - output["door-sound"] = pEntry.GetDoorSound(); - output["radio-num"] = pEntry.GetRadioNum(); - output["radio-type"] = pEntry.GetRadioType(); - output["vehicle-type-for-audio"] = pEntry.GetVehicleTypeForAudio(); + output["engine-upgrade"] = static_cast(pEntry.GetEngineUpgrade()); + output["door-sound"] = static_cast(pEntry.GetDoorSound()); + output["radio-num"] = static_cast(pEntry.GetRadioNum()); + output["radio-type"] = static_cast(pEntry.GetRadioType()); + output["vehicle-type-for-audio"] = static_cast(pEntry.GetVehicleTypeForAudio()); output["horn-volume-delta"] = pEntry.GetHornVolumeDelta(); return output; } - diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h index d2139619184..945efed4c47 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h @@ -154,8 +154,8 @@ class CLuaVehicleDefs : public CLuaDefs static std::variant OOP_GetVehicleDummyPosition(CClientVehicle* vehicle, VehicleDummies dummy); static bool ResetVehicleDummyPositions(CClientVehicle* vehicle); - static std::variant, 4>> GetVehicleEntryPoints(CClientVehicle* vehicle); - static std::variant> OOP_GetVehicleEntryPoints(CClientVehicle* vehicle); + static std::variant, 4>> GetVehicleEntryPoints(CClientVehicle* vehicle); + static std::variant> OOP_GetVehicleEntryPoints(CClientVehicle* vehicle); LUA_DECLARE(SetVehicleModelExhaustFumesPosition); LUA_DECLARE_OOP(GetVehicleModelExhaustFumesPosition); @@ -163,7 +163,7 @@ class CLuaVehicleDefs : public CLuaDefs static bool SetVehicleVariant(CClientVehicle* pVehicle, std::optional optVariant1, std::optional optVariant2); static float GetVehicleWheelScale(CClientVehicle* const pVehicle); static bool SetVehicleWheelScale(CClientVehicle* const pVehicle, const float fWheelScale); - static std::variant> GetVehicleModelWheelSize(const unsigned short usModel, + static std::variant> GetVehicleModelWheelSize(const unsigned short usModel, const std::optional eWheelGroup); static bool SetVehicleModelWheelSize(const unsigned short usModel, const ResizableVehicleWheelGroup eWheelGroup, const float fWheelSize); static int GetVehicleWheelFrictionState(CClientVehicle* pVehicle, unsigned char wheel); @@ -171,9 +171,10 @@ class CLuaVehicleDefs : public CLuaDefs static bool SetVehicleRotorState(CClientVehicle* const vehicle, bool state, std::optional stopRotor) noexcept; static bool GetVehicleRotorState(CClientVehicle* const vehicle) noexcept; - static bool AddVehicleSirens(CClientVehicle* vehicle, std::uint8_t sirenType, std::uint8_t sirenCount, std::optional enable360, std::optional enableLOSCheck, std::optional enableRandomiser, std::optional enableSilent) noexcept; + static bool AddVehicleSirens(CClientVehicle* vehicle, std::uint8_t sirenType, std::uint8_t sirenCount, std::optional enable360, + std::optional enableLOSCheck, std::optional enableRandomiser, std::optional enableSilent) noexcept; static bool RemoveVehicleSirens(CClientVehicle* vehicle) noexcept; - + static bool SetVehicleModelAudioSetting(const uint32_t uiModel, const VehicleAudioSettingProperty eProperty, float varValue); static bool ResetVehicleModelAudioSettings(const uint32_t uiModel); static bool SetVehicleAudioSetting(CClientVehicle* pVehicle, const VehicleAudioSettingProperty eProperty, float varValue); @@ -195,7 +196,8 @@ class CLuaVehicleDefs : public CLuaDefs LUA_DECLARE(GetVehicleComponentVisible); LUA_DECLARE(GetVehicleComponents); - static bool SpawnVehicleFlyingComponent(CClientVehicle* const vehicle, std::uint8_t nodeIndex, std::optional componentCollisionType, std::optional removalTime); + static bool SpawnVehicleFlyingComponent(CClientVehicle* const vehicle, std::uint8_t nodeIndex, std::optional componentCollisionType, + std::optional removalTime); static bool SetSmokeTrailEnabled(CClientVehicle* vehicle, bool state); static bool IsSmokeTrailEnabled(CClientVehicle* vehicle) noexcept; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWaterDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaWaterDefs.cpp index f8a6890497d..e048f060b49 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWaterDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWaterDefs.cpp @@ -41,7 +41,7 @@ void CLuaWaterDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "create", "createWater"); lua_classfunction(luaVM, "testLineAgainst", "testLineAgainstWater"); - lua_classfunction(luaVM, "isDrawnLast", "isWaterDrawnLast"); // Drawn last property affects all water instances + lua_classfunction(luaVM, "isDrawnLast", "isWaterDrawnLast"); // Drawn last property affects all water instances lua_classfunction(luaVM, "setDrawnLast", "setWaterDrawnLast"); // Static variables (not implemented yet!) @@ -80,7 +80,7 @@ int CLuaWaterDefs::CreateWater(lua_State* luaVM) argStream.ReadVector3D(v1); argStream.ReadVector3D(v2); argStream.ReadVector3D(v3); - bool bIsQuad = argStream.NextCouldBeNumber(2); // Check for existence of v4.fZ + bool bIsQuad = argStream.NextCouldBeNumber(2); // Check for existence of v4.fZ if (bIsQuad) { argStream.ReadVector3D(v4); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWeaponDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaWeaponDefs.cpp index 39cb8eff19c..3384e50b4ad 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWeaponDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWeaponDefs.cpp @@ -12,7 +12,7 @@ #include "StdInc.h" #include "game/CWeaponStatManager.h" -#define MIN_CLIENT_REQ_WEAPON_PROPERTY_FLAG "1.3.5-9.06139" +#define MIN_CLIENT_REQ_WEAPON_PROPERTY_FLAG "1.3.5-9.06139" void CLuaWeaponDefs::LoadFunctions() { @@ -41,8 +41,7 @@ void CLuaWeaponDefs::LoadFunctions() {"setWeaponAmmo", SetWeaponAmmo}, {"setWeaponClipAmmo", SetWeaponClipAmmo}, {"setWeaponRenderEnabled", ArgumentParser}, - {"isWeaponRenderEnabled", ArgumentParser} - }; + {"isWeaponRenderEnabled", ArgumentParser}}; // Add functions for (const auto& [name, func] : functions) @@ -209,7 +208,7 @@ int CLuaWeaponDefs::FireWeapon(lua_State* luaVM) int CLuaWeaponDefs::SetWeaponProperty(lua_State* luaVM) { CClientWeapon* pWeapon; - WeaponProperty weaponProperty; + WeaponProperty weaponProperty; CScriptArgReader argStream(luaVM); argStream.ReadUserData(pWeapon); argStream.ReadEnumString(weaponProperty); @@ -694,7 +693,10 @@ int CLuaWeaponDefs::SetWeaponClipAmmo(lua_State* luaVM) return 1; } -std::variant> CLuaWeaponDefs::GetWeaponProperty(lua_State* luaVM, std::variant weapon, std::variant weaponSkill, WeaponProperty property) +std::variant> CLuaWeaponDefs::GetWeaponProperty(lua_State* luaVM, + std::variant weapon, + std::variant weaponSkill, + WeaponProperty property) { eWeaponSkill skill = WEAPONSKILL_POOR; if (std::holds_alternative(weaponSkill)) @@ -708,7 +710,7 @@ std::variant> CLuaWeaponDef // custom weapon if (std::holds_alternative(weapon)) { - auto* weaponPtr = std::get(weapon); + auto* weaponPtr = std::get(weapon); CWeaponStat* weaponStats = weaponPtr->GetWeaponStat(); if (!weaponPtr || !weaponStats) return false; @@ -840,7 +842,10 @@ std::variant> CLuaWeaponDef return false; } -std::variant> CLuaWeaponDefs::GetOriginalWeaponProperty(lua_State* luaVM, std::variant weapon, std::variant weaponSkill, WeaponProperty property) +std::variant> CLuaWeaponDefs::GetOriginalWeaponProperty(lua_State* luaVM, + std::variant weapon, + std::variant weaponSkill, + WeaponProperty property) { eWeaponType weaponType = eWeaponType::WEAPONTYPE_INVALID; if (std::holds_alternative(weapon)) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWeaponDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaWeaponDefs.h index d61b1a88bbf..93338c895a2 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWeaponDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWeaponDefs.h @@ -25,8 +25,14 @@ class CLuaWeaponDefs : public CLuaDefs LUA_DECLARE(CreateWeapon); LUA_DECLARE(FireWeapon); LUA_DECLARE(SetWeaponProperty); - static std::variant> GetWeaponProperty(lua_State* luaVM, std::variant weapon, std::variant weaponSkill, WeaponProperty property); - static std::variant> GetOriginalWeaponProperty(lua_State* luaVM, std::variant weapon, std::variant weaponSkill, WeaponProperty property); + static std::variant> GetWeaponProperty(lua_State* luaVM, + std::variant weapon, + std::variant weaponSkill, + WeaponProperty property); + static std::variant> GetOriginalWeaponProperty(lua_State* luaVM, + std::variant weapon, + std::variant weaponSkill, + WeaponProperty property); LUA_DECLARE(SetWeaponState); LUA_DECLARE(GetWeaponState); LUA_DECLARE(SetWeaponTarget); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp index 8240385f1dc..87e8a23a6c0 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp @@ -17,139 +17,139 @@ void CLuaWorldDefs::LoadFunctions() { - constexpr static const std::pair functions[]{// World get functions - {"getTime", GetTime}, - {"getColorFilter", ArgumentParser}, - {"getRoofPosition", GetRoofPosition}, - {"getGroundPosition", GetGroundPosition}, - {"processLineAgainstMesh", ArgumentParser}, - {"processLineOfSight", ProcessLineOfSight}, - {"getWorldFromScreenPosition", GetWorldFromScreenPosition}, - {"getScreenFromWorldPosition", GetScreenFromWorldPosition}, - {"getWeather", GetWeather}, - {"getZoneName", GetZoneName}, - {"getGravity", GetGravity}, - {"getGameSpeed", GetGameSpeed}, - {"getMinuteDuration", GetMinuteDuration}, - {"getWaveHeight", GetWaveHeight}, - {"getGaragePosition", GetGaragePosition}, - {"getGarageSize", GetGarageSize}, - {"getGarageBoundingBox", GetGarageBoundingBox}, - {"getBlurLevel", GetBlurLevel}, - {"getTrafficLightState", GetTrafficLightState}, - {"getSkyGradient", GetSkyGradient}, - {"getHeatHaze", GetHeatHaze}, - {"getJetpackMaxHeight", GetJetpackMaxHeight}, - {"getWindVelocity", GetWindVelocity}, - {"getInteriorSoundsEnabled", GetInteriorSoundsEnabled}, - {"getInteriorFurnitureEnabled", GetInteriorFurnitureEnabled}, - {"getFarClipDistance", GetFarClipDistance}, - {"getNearClipDistance", GetNearClipDistance}, - {"getVehiclesLODDistance", GetVehiclesLODDistance}, - {"getPedsLODDistance", GetPedsLODDistance}, - {"getFogDistance", GetFogDistance}, - {"getSunColor", GetSunColor}, - {"getSunSize", GetSunSize}, - {"getAircraftMaxHeight", GetAircraftMaxHeight}, - {"getAircraftMaxVelocity", GetAircraftMaxVelocity}, - {"getOcclusionsEnabled", GetOcclusionsEnabled}, - {"getCloudsEnabled", GetCloudsEnabled}, - {"getRainLevel", GetRainLevel}, - {"getMoonSize", GetMoonSize}, - {"getFPSLimit", GetFPSLimit}, - {"getBirdsEnabled", GetBirdsEnabled}, - {"getCoronaReflectionsEnabled", ArgumentParser}, - {"getWorldProperty", ArgumentParser}, - - // World set funcs - {"setTime", SetTime}, - {"setColorFilter", ArgumentParser}, - {"setGrainMultiplier", ArgumentParser}, - {"setGrainLevel", ArgumentParser}, - {"setSkyGradient", SetSkyGradient}, - {"setHeatHaze", SetHeatHaze}, - {"setWeather", SetWeather}, - {"setWeatherBlended", SetWeatherBlended}, - {"setGravity", SetGravity}, - {"setGameSpeed", SetGameSpeed}, - {"setWaveHeight", SetWaveHeight}, - {"setMinuteDuration", SetMinuteDuration}, - {"setGarageOpen", SetGarageOpen}, - {"setWorldSpecialPropertyEnabled", ArgumentParser}, - {"setBlurLevel", SetBlurLevel}, - {"setJetpackMaxHeight", SetJetpackMaxHeight}, - {"setCloudsEnabled", SetCloudsEnabled}, - {"setTrafficLightState", SetTrafficLightState}, - {"setTrafficLightsLocked", SetTrafficLightsLocked}, - {"setWindVelocity", SetWindVelocity}, - {"setInteriorSoundsEnabled", SetInteriorSoundsEnabled}, - {"setInteriorFurnitureEnabled", SetInteriorFurnitureEnabled}, - {"setRainLevel", SetRainLevel}, - {"setFarClipDistance", SetFarClipDistance}, - {"setNearClipDistance", SetNearClipDistance}, - {"setVehiclesLODDistance", SetVehiclesLODDistance}, - {"setPedsLODDistance", SetPedsLODDistance}, - {"setFogDistance", SetFogDistance}, - {"setSunColor", SetSunColor}, - {"setSunSize", SetSunSize}, - {"setAircraftMaxHeight", SetAircraftMaxHeight}, - {"setAircraftMaxVelocity", SetAircraftMaxVelocity}, - {"setOcclusionsEnabled", SetOcclusionsEnabled}, - {"setBirdsEnabled", SetBirdsEnabled}, - {"setPedTargetingMarkerEnabled", SetPedTargetingMarkerEnabled}, - {"setMoonSize", SetMoonSize}, - {"setFPSLimit", SetFPSLimit}, - {"setCoronaReflectionsEnabled", ArgumentParser}, - {"setWorldProperty", ArgumentParser}, - - // World remove/restore functions - {"removeWorldModel", RemoveWorldBuilding}, - {"restoreAllWorldModels", RestoreWorldBuildings}, - {"restoreWorldModel", RestoreWorldBuilding}, - {"removeGameWorld", ArgumentParser}, - {"restoreGameWorld", ArgumentParser}, - - {"setTimeFrozen", ArgumentParser}, - {"setVolumetricShadowsEnabled", ArgumentParser}, - {"setDynamicPedShadowsEnabled", ArgumentParser}, - - - // World create funcs - {"createSWATRope", CreateSWATRope}, - {"createExplosion", CreateExplosion}, - - // World reset funcs - {"resetColorFilter", ArgumentParser}, - {"resetCoronaReflectionsEnabled", ArgumentParser}, - {"resetSkyGradient", ResetSkyGradient}, - {"resetHeatHaze", ResetHeatHaze}, - {"resetWindVelocity", ResetWindVelocity}, - {"resetRainLevel", ResetRainLevel}, - {"resetFarClipDistance", ResetFarClipDistance}, - {"resetNearClipDistance", ResetNearClipDistance}, - {"resetVehiclesLODDistance", ResetVehiclesLODDistance}, - {"resetPedsLODDistance", ResetPedsLODDistance}, - {"resetFogDistance", ResetFogDistance}, - {"resetSunColor", ResetSunColor}, - {"resetSunSize", ResetSunSize}, - {"resetMoonSize", ResetMoonSize}, - {"resetBlurLevel", ResetBlurLevel}, - {"resetWorldProperty", ArgumentParserWarn}, - {"resetTimeFrozen", ArgumentParser}, - {"resetVolumetricShadows", ArgumentParser}, - {"resetWorldProperties", ArgumentParser}, - {"resetDynamicPedShadows", ArgumentParser}, - - // World check funcs - {"areTrafficLightsLocked", AreTrafficLightsLocked}, - {"isPedTargetingMarkerEnabled", IsPedTargetingMarkerEnabled}, - {"isLineOfSightClear", IsLineOfSightClear}, - {"isWorldSpecialPropertyEnabled", ArgumentParserWarn}, - {"isGarageOpen", IsGarageOpen}, - {"isTimeFrozen", ArgumentParser}, - {"isVolumetricShadowsEnabled", ArgumentParser}, - {"isDynamicPedShadowsEnabled", ArgumentParser}, - {"testSphereAgainstWorld", ArgumentParser}}; + constexpr static const std::pair functions[]{ + // World get functions + {"getTime", GetTime}, + {"getColorFilter", ArgumentParser}, + {"getRoofPosition", GetRoofPosition}, + {"getGroundPosition", GetGroundPosition}, + {"processLineAgainstMesh", ArgumentParser}, + {"processLineOfSight", ProcessLineOfSight}, + {"getWorldFromScreenPosition", GetWorldFromScreenPosition}, + {"getScreenFromWorldPosition", GetScreenFromWorldPosition}, + {"getWeather", GetWeather}, + {"getZoneName", GetZoneName}, + {"getGravity", GetGravity}, + {"getGameSpeed", GetGameSpeed}, + {"getMinuteDuration", GetMinuteDuration}, + {"getWaveHeight", GetWaveHeight}, + {"getGaragePosition", GetGaragePosition}, + {"getGarageSize", GetGarageSize}, + {"getGarageBoundingBox", GetGarageBoundingBox}, + {"getBlurLevel", GetBlurLevel}, + {"getTrafficLightState", GetTrafficLightState}, + {"getSkyGradient", GetSkyGradient}, + {"getHeatHaze", GetHeatHaze}, + {"getJetpackMaxHeight", GetJetpackMaxHeight}, + {"getWindVelocity", GetWindVelocity}, + {"getInteriorSoundsEnabled", GetInteriorSoundsEnabled}, + {"getInteriorFurnitureEnabled", GetInteriorFurnitureEnabled}, + {"getFarClipDistance", GetFarClipDistance}, + {"getNearClipDistance", GetNearClipDistance}, + {"getVehiclesLODDistance", GetVehiclesLODDistance}, + {"getPedsLODDistance", GetPedsLODDistance}, + {"getFogDistance", GetFogDistance}, + {"getSunColor", GetSunColor}, + {"getSunSize", GetSunSize}, + {"getAircraftMaxHeight", GetAircraftMaxHeight}, + {"getAircraftMaxVelocity", GetAircraftMaxVelocity}, + {"getOcclusionsEnabled", GetOcclusionsEnabled}, + {"getCloudsEnabled", GetCloudsEnabled}, + {"getRainLevel", GetRainLevel}, + {"getMoonSize", GetMoonSize}, + {"getFPSLimit", GetFPSLimit}, + {"getBirdsEnabled", GetBirdsEnabled}, + {"getCoronaReflectionsEnabled", ArgumentParser}, + {"getWorldProperty", ArgumentParser}, + + // World set funcs + {"setTime", SetTime}, + {"setColorFilter", ArgumentParser}, + {"setGrainMultiplier", ArgumentParser}, + {"setGrainLevel", ArgumentParser}, + {"setSkyGradient", SetSkyGradient}, + {"setHeatHaze", SetHeatHaze}, + {"setWeather", SetWeather}, + {"setWeatherBlended", SetWeatherBlended}, + {"setGravity", SetGravity}, + {"setGameSpeed", SetGameSpeed}, + {"setWaveHeight", SetWaveHeight}, + {"setMinuteDuration", SetMinuteDuration}, + {"setGarageOpen", SetGarageOpen}, + {"setWorldSpecialPropertyEnabled", ArgumentParser}, + {"setBlurLevel", SetBlurLevel}, + {"setJetpackMaxHeight", SetJetpackMaxHeight}, + {"setCloudsEnabled", SetCloudsEnabled}, + {"setTrafficLightState", SetTrafficLightState}, + {"setTrafficLightsLocked", SetTrafficLightsLocked}, + {"setWindVelocity", SetWindVelocity}, + {"setInteriorSoundsEnabled", SetInteriorSoundsEnabled}, + {"setInteriorFurnitureEnabled", SetInteriorFurnitureEnabled}, + {"setRainLevel", SetRainLevel}, + {"setFarClipDistance", SetFarClipDistance}, + {"setNearClipDistance", SetNearClipDistance}, + {"setVehiclesLODDistance", SetVehiclesLODDistance}, + {"setPedsLODDistance", SetPedsLODDistance}, + {"setFogDistance", SetFogDistance}, + {"setSunColor", SetSunColor}, + {"setSunSize", SetSunSize}, + {"setAircraftMaxHeight", SetAircraftMaxHeight}, + {"setAircraftMaxVelocity", SetAircraftMaxVelocity}, + {"setOcclusionsEnabled", SetOcclusionsEnabled}, + {"setBirdsEnabled", SetBirdsEnabled}, + {"setPedTargetingMarkerEnabled", SetPedTargetingMarkerEnabled}, + {"setMoonSize", SetMoonSize}, + {"setFPSLimit", SetFPSLimit}, + {"setCoronaReflectionsEnabled", ArgumentParser}, + {"setWorldProperty", ArgumentParser}, + + // World remove/restore functions + {"removeWorldModel", RemoveWorldBuilding}, + {"restoreAllWorldModels", RestoreWorldBuildings}, + {"restoreWorldModel", RestoreWorldBuilding}, + {"removeGameWorld", ArgumentParser}, + {"restoreGameWorld", ArgumentParser}, + + {"setTimeFrozen", ArgumentParser}, + {"setVolumetricShadowsEnabled", ArgumentParser}, + {"setDynamicPedShadowsEnabled", ArgumentParser}, + + // World create funcs + {"createSWATRope", CreateSWATRope}, + {"createExplosion", CreateExplosion}, + + // World reset funcs + {"resetColorFilter", ArgumentParser}, + {"resetCoronaReflectionsEnabled", ArgumentParser}, + {"resetSkyGradient", ResetSkyGradient}, + {"resetHeatHaze", ResetHeatHaze}, + {"resetWindVelocity", ResetWindVelocity}, + {"resetRainLevel", ResetRainLevel}, + {"resetFarClipDistance", ResetFarClipDistance}, + {"resetNearClipDistance", ResetNearClipDistance}, + {"resetVehiclesLODDistance", ResetVehiclesLODDistance}, + {"resetPedsLODDistance", ResetPedsLODDistance}, + {"resetFogDistance", ResetFogDistance}, + {"resetSunColor", ResetSunColor}, + {"resetSunSize", ResetSunSize}, + {"resetMoonSize", ResetMoonSize}, + {"resetBlurLevel", ResetBlurLevel}, + {"resetWorldProperty", ArgumentParserWarn}, + {"resetTimeFrozen", ArgumentParser}, + {"resetVolumetricShadows", ArgumentParser}, + {"resetWorldProperties", ArgumentParser}, + {"resetDynamicPedShadows", ArgumentParser}, + + // World check funcs + {"areTrafficLightsLocked", AreTrafficLightsLocked}, + {"isPedTargetingMarkerEnabled", IsPedTargetingMarkerEnabled}, + {"isLineOfSightClear", IsLineOfSightClear}, + {"isWorldSpecialPropertyEnabled", ArgumentParserWarn}, + {"isGarageOpen", IsGarageOpen}, + {"isTimeFrozen", ArgumentParser}, + {"isVolumetricShadowsEnabled", ArgumentParser}, + {"isDynamicPedShadowsEnabled", ArgumentParser}, + {"testSphereAgainstWorld", ArgumentParser}}; // Add functions for (const auto& [name, func] : functions) @@ -174,7 +174,7 @@ int CLuaWorldDefs::CreateExplosion(lua_State* luaVM) if (!argStream.HasErrors()) { - if (CStaticFunctionDefinitions::CreateExplosion(vecPosition, iType, bMakeSound, fCamShake, bDamaging)) + if (CStaticFunctionDefinitions::CreateExplosion(vecPosition, static_cast(iType), bMakeSound, fCamShake, bDamaging)) { lua_pushboolean(luaVM, true); return 1; @@ -252,16 +252,21 @@ int CLuaWorldDefs::GetRoofPosition(lua_State* luaVM) return 1; } -std::variant> CLuaWorldDefs::ProcessLineAgainstMesh(CClientEntity* e, CVector start, CVector end) { +std::variant> CLuaWorldDefs::ProcessLineAgainstMesh(CClientEntity* e, + CVector start, + CVector end) +{ const auto ge = e->GetGameEntity(); - if (!ge) { + if (!ge) + { // Element likely not streamed in, and such // Can't process it. This isn't an error per-se, thus we won't raise anything and treat this as a no-hit scenario - return { false }; + return {false}; } const SProcessLineOfSightMaterialInfoResult matInfo{g_pGame->GetWorld()->ProcessLineAgainstMesh(ge->GetInterface(), start, end)}; - if (!matInfo.valid) { - return { false }; // No hit + if (!matInfo.valid) + { + return {false}; // No hit } return CLuaMultiReturn{ true, @@ -332,7 +337,7 @@ int CLuaWorldDefs::ProcessLineOfSight(lua_State* L) // Get the collision position vecColPosition = pColPoint->GetPosition(); vecColNormal = pColPoint->GetNormal(); - iMaterial = pColPoint->GetSurfaceTypeB(); // From test, only B function return relevant data + iMaterial = pColPoint->GetSurfaceTypeB(); // From test, only B function return relevant data fLighting = pColPoint->GetLightingForTimeOfDay(); iPiece = pColPoint->GetPieceTypeB(); @@ -360,7 +365,7 @@ int CLuaWorldDefs::ProcessLineOfSight(lua_State* L) lua_pushnumber(L, fLighting); lua_pushinteger(L, iPiece); - if (bIncludeBuildingInfo && buildingResult.bValid) // 8 args + if (bIncludeBuildingInfo && buildingResult.bValid) // 8 args { lua_pushnumber(L, buildingResult.usModelID); @@ -373,13 +378,17 @@ int CLuaWorldDefs::ProcessLineOfSight(lua_State* L) lua_pushnumber(L, ConvertRadiansToDegrees(buildingResult.vecRotation.fZ)); lua_pushnumber(L, buildingResult.usLODModelID); - } else { - for (auto i = 1 + 3 + 3 + 1; i-- > 0;) { + } + else + { + for (auto i = 1 + 3 + 3 + 1; i-- > 0;) + { lua_pushnil(L); } } - if (bIncludeExtraMateriaInfo && matInfo.valid) { // 7 args + if (bIncludeExtraMateriaInfo && matInfo.valid) + { // 7 args lua::Push(L, matInfo.uv.fX); lua::Push(L, matInfo.uv.fY); @@ -389,8 +398,11 @@ int CLuaWorldDefs::ProcessLineOfSight(lua_State* L) lua::Push(L, matInfo.hitPos.fX); lua::Push(L, matInfo.hitPos.fY); lua::Push(L, matInfo.hitPos.fZ); - } else { - for (auto i = 2 + 1 + 1 + 3; i-- > 0;) { + } + else + { + for (auto i = 2 + 1 + 1 + 3; i-- > 0;) + { lua_pushnil(L); } } @@ -622,7 +634,7 @@ int CLuaWorldDefs::IsGarageOpen(lua_State* luaVM) { bool bIsOpen; - if (CStaticFunctionDefinitions::IsGarageOpen(iGarageID, bIsOpen)) + if (CStaticFunctionDefinitions::IsGarageOpen(static_cast(iGarageID), bIsOpen)) { lua_pushboolean(luaVM, bIsOpen); return 1; @@ -647,7 +659,7 @@ int CLuaWorldDefs::GetGaragePosition(lua_State* luaVM) { CVector vecPosition; - if (CStaticFunctionDefinitions::GetGaragePosition(iGarageID, vecPosition)) + if (CStaticFunctionDefinitions::GetGaragePosition(static_cast(iGarageID), vecPosition)) { lua_pushnumber(luaVM, vecPosition.fX); lua_pushnumber(luaVM, vecPosition.fY); @@ -676,11 +688,11 @@ int CLuaWorldDefs::GetGarageSize(lua_State* luaVM) float fWidth; float fHeight; - if (CStaticFunctionDefinitions::GetGarageSize(iGarageID, fHeight, fWidth, fDepth)) + if (CStaticFunctionDefinitions::GetGarageSize(static_cast(iGarageID), fHeight, fWidth, fDepth)) { - lua_pushnumber(luaVM, fHeight); lua_pushnumber(luaVM, fWidth); lua_pushnumber(luaVM, fDepth); + lua_pushnumber(luaVM, fHeight); return 3; } } @@ -706,7 +718,7 @@ int CLuaWorldDefs::GetGarageBoundingBox(lua_State* luaVM) float fFront; float fBack; - if (CStaticFunctionDefinitions::GetGarageBoundingBox(iGarageID, fLeft, fRight, fFront, fBack)) + if (CStaticFunctionDefinitions::GetGarageBoundingBox(static_cast(iGarageID), fLeft, fRight, fFront, fBack)) { lua_pushnumber(luaVM, fLeft); lua_pushnumber(luaVM, fRight); @@ -1069,7 +1081,7 @@ int CLuaWorldDefs::SetGarageOpen(lua_State* luaVM) if (!argStream.HasErrors()) { - if (CStaticFunctionDefinitions::SetGarageOpen(iGarageID, bOpen)) + if (CStaticFunctionDefinitions::SetGarageOpen(static_cast(iGarageID), bOpen)) { lua_pushboolean(luaVM, true); return 1; @@ -1126,7 +1138,8 @@ int CLuaWorldDefs::RemoveWorldBuilding(lua_State* luaVM) if (pResource) { uint uiAmount; - CStaticFunctionDefinitions::RemoveWorldBuilding(iModelToRemove, fRadius, vecPosition.fX, vecPosition.fY, vecPosition.fZ, cInterior, uiAmount); + CStaticFunctionDefinitions::RemoveWorldBuilding(static_cast(iModelToRemove), fRadius, vecPosition.fX, vecPosition.fY, + vecPosition.fZ, cInterior, uiAmount); lua_pushboolean(luaVM, true); lua_pushnumber(luaVM, uiAmount); @@ -1182,7 +1195,8 @@ int CLuaWorldDefs::RestoreWorldBuilding(lua_State* luaVM) if (pResource) { uint uiAmount; - CStaticFunctionDefinitions::RestoreWorldBuilding(iModelToRestore, fRadius, vecPosition.fX, vecPosition.fY, vecPosition.fZ, cInterior, uiAmount); + CStaticFunctionDefinitions::RestoreWorldBuilding(static_cast(iModelToRestore), fRadius, vecPosition.fX, vecPosition.fY, + vecPosition.fZ, cInterior, uiAmount); lua_pushboolean(luaVM, true); lua_pushnumber(luaVM, uiAmount); @@ -1276,9 +1290,6 @@ bool CLuaWorldDefs::SetWorldSpecialPropertyEnabled(const WorldSpecialProperty pr if (!m_pClientGame->SetWorldSpecialProperty(property, enabled)) return false; - if (!g_pNet->CanServerBitStream(eBitStreamVersion::WorldSpecialPropertyEvent)) - return true; - if (auto stream = g_pNet->AllocateNetBitStream()) { stream->WriteString(EnumToString(property)); @@ -1360,7 +1371,7 @@ int CLuaWorldDefs::SetTrafficLightState(lua_State* luaVM) if (!argStream.HasErrors()) { - if (CStaticFunctionDefinitions::SetTrafficLightState(iState)) + if (CStaticFunctionDefinitions::SetTrafficLightState(static_cast(iState))) { lua_pushboolean(luaVM, true); return 1; @@ -1855,7 +1866,8 @@ int CLuaWorldDefs::SetSunColor(lua_State* luaVM) if (!argStream.HasErrors()) { - g_pMultiplayer->SetSunColor(iCoreRed, iCoreGreen, iCoreBlue, iCoronaRed, iCoronaGreen, iCoronaBlue); + g_pMultiplayer->SetSunColor(static_cast(iCoreRed), static_cast(iCoreGreen), static_cast(iCoreBlue), + static_cast(iCoronaRed), static_cast(iCoronaGreen), static_cast(iCoronaBlue)); } else m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); @@ -2003,21 +2015,19 @@ int CLuaWorldDefs::ResetMoonSize(lua_State* luaVM) int CLuaWorldDefs::SetFPSLimit(lua_State* luaVM) { // bool setFPSLimit ( int fpsLimit ) - int iLimit; + std::uint16_t fps; - CScriptArgReader argStream(luaVM); - argStream.ReadNumber(iLimit); + CScriptArgReader argReader(luaVM); + argReader.ReadNumber(fps); - if (!argStream.HasErrors()) + if (!argReader.HasErrors()) { - if (CStaticFunctionDefinitions::SetFPSLimit(iLimit)) - { - lua_pushboolean(luaVM, true); - return 1; - } + CStaticFunctionDefinitions::SetClientFPSLimit(fps); + lua_pushboolean(luaVM, true); + return 1; } else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + m_pScriptDebugging->LogCustom(luaVM, argReader.GetFullErrorMessage()); lua_pushboolean(luaVM, false); return 1; @@ -2025,14 +2035,12 @@ int CLuaWorldDefs::SetFPSLimit(lua_State* luaVM) int CLuaWorldDefs::GetFPSLimit(lua_State* luaVM) { - int iLimit; - if (CStaticFunctionDefinitions::GetFPSLimit(iLimit)) - { - lua_pushnumber(luaVM, iLimit); - return 1; - } + // int getFPSLimit () + std::uint16_t fps; - lua_pushboolean(luaVM, false); + CStaticFunctionDefinitions::GetFPSLimit(fps); + + lua_pushnumber(luaVM, fps); return 1; } @@ -2057,8 +2065,7 @@ CLuaMultiReturn CLuaWorl SColor uColor1 = 0; g_pMultiplayer->GetColorFilter(uColor0.ulARGB, uColor1.ulARGB, isOriginal); return { - uColor0.R, uColor0.G, uColor0.B, uColor0.A, - uColor1.R, uColor1.G, uColor1.B, uColor1.A, + uColor0.R, uColor0.G, uColor0.B, uColor0.A, uColor1.R, uColor1.G, uColor1.B, uColor1.A, }; } @@ -2168,6 +2175,15 @@ bool CLuaWorldDefs::SetWorldProperty(WorldProperty property, float arg1, std::op { if (arg2.has_value() && arg3.has_value()) { + const auto toInt16ColorComponent = [](float value) -> int16 + { + const int iValue = Round(value); + if (iValue < 0 || iValue > 255) + throw std::invalid_argument("Expected a valid colour component (0-255)"); + + return static_cast(iValue); + }; + switch (property) { case WorldProperty::AMBIENT_COLOR: @@ -2177,9 +2193,10 @@ bool CLuaWorldDefs::SetWorldProperty(WorldProperty property, float arg1, std::op case WorldProperty::DIRECTIONAL_COLOR: return g_pMultiplayer->SetDirectionalColor(arg1 / 255, arg2.value() / 255, arg3.value() / 255); case WorldProperty::LOW_CLOUDS_COLOR: - return g_pMultiplayer->SetLowCloudsColor((int16)arg1, (int16)arg2.value(), (int16)arg3.value()); + return g_pMultiplayer->SetLowCloudsColor(toInt16ColorComponent(arg1), toInt16ColorComponent(arg2.value()), toInt16ColorComponent(arg3.value())); case WorldProperty::BOTTOM_CLOUDS_COLOR: - return g_pMultiplayer->SetBottomCloudsColor((int16)arg1, (int16)arg2.value(), (int16)arg3.value()); + return g_pMultiplayer->SetBottomCloudsColor(toInt16ColorComponent(arg1), toInt16ColorComponent(arg2.value()), + toInt16ColorComponent(arg3.value())); } return false; } @@ -2190,9 +2207,9 @@ bool CLuaWorldDefs::SetWorldProperty(WorldProperty property, float arg1, std::op case WorldProperty::SPRITE_BRIGHTNESS: return g_pMultiplayer->SetSpriteBrightness(arg1); case WorldProperty::POLE_SHADOW_STRENGTH: - return g_pMultiplayer->SetPoleShadowStrength(arg1); + return g_pMultiplayer->SetPoleShadowStrength(static_cast(arg1)); case WorldProperty::SHADOW_STRENGTH: - return g_pMultiplayer->SetShadowStrength(arg1); + return g_pMultiplayer->SetShadowStrength(static_cast(arg1)); case WorldProperty::SHADOWS_OFFSET: return g_pMultiplayer->SetShadowsOffset(arg1); case WorldProperty::LIGHTS_ON_GROUND: @@ -2323,9 +2340,11 @@ bool CLuaWorldDefs::ResetVolumetricShadows() noexcept return g_pGame->GetSettings()->ResetVolumetricShadows(); } -void CLuaWorldDefs::ResetWorldProperties(std::optional resetSpecialWorldProperties, std::optional resetWorldProperties, std::optional resetWeatherProperties, std::optional resetLODs, std::optional resetSounds) noexcept +void CLuaWorldDefs::ResetWorldProperties(std::optional resetSpecialWorldProperties, std::optional resetWorldProperties, + std::optional resetWeatherProperties, std::optional resetLODs, std::optional resetSounds) noexcept { - g_pClientGame->ResetWorldProperties(ResetWorldPropsInfo{resetSpecialWorldProperties.value_or(true), resetWorldProperties.value_or(true), resetWeatherProperties.value_or(true), resetLODs.value_or(true), resetSounds.value_or(true)}); + g_pClientGame->ResetWorldProperties(ResetWorldPropsInfo{resetSpecialWorldProperties.value_or(true), resetWorldProperties.value_or(true), + resetWeatherProperties.value_or(true), resetLODs.value_or(true), resetSounds.value_or(true)}); } bool CLuaWorldDefs::SetDynamicPedShadowsEnabled(bool enable) @@ -2344,14 +2363,28 @@ bool CLuaWorldDefs::ResetDynamicPedShadows() noexcept return g_pGame->GetSettings()->ResetDynamicPedShadows(); } -CLuaMultiReturn CLuaWorldDefs::TestSphereAgainstWorld(CVector sphereCenter, float radius, std::optional ignoredEntity, std::optional checkBuildings, std::optional checkVehicles, std::optional checkPeds, std::optional checkObjects, std::optional checkDummies, std::optional cameraIgnore) +CLuaMultiReturn CLuaWorldDefs::TestSphereAgainstWorld( + CVector sphereCenter, float radius, std::optional ignoredEntity, std::optional checkBuildings, std::optional checkVehicles, + std::optional checkPeds, std::optional checkObjects, std::optional checkDummies, std::optional cameraIgnore) { STestSphereAgainstWorldResult result; - CClientEntity* collidedEntity = nullptr; + CClientEntity* collidedEntity = nullptr; - CEntity* entity = g_pGame->GetWorld()->TestSphereAgainstWorld(sphereCenter, radius, ignoredEntity.has_value() ? ignoredEntity.value()->GetGameEntity() : nullptr, checkBuildings.value_or(true), checkVehicles.value_or(true), checkPeds.value_or(true), checkObjects.value_or(true), checkDummies.value_or(true), cameraIgnore.value_or(false), result); + CEntity* entity = g_pGame->GetWorld()->TestSphereAgainstWorld( + sphereCenter, radius, ignoredEntity.has_value() ? ignoredEntity.value()->GetGameEntity() : nullptr, checkBuildings.value_or(true), + checkVehicles.value_or(true), checkPeds.value_or(true), checkObjects.value_or(true), checkDummies.value_or(true), cameraIgnore.value_or(false), result); if (entity) collidedEntity = reinterpret_cast(entity->GetStoredPointer()); - return {result.collisionDetected, collidedEntity, result.modelID, result.entityPosition.fX, result.entityPosition.fY, result.entityPosition.fZ, ConvertRadiansToDegrees(result.entityRotation.fX), ConvertRadiansToDegrees(result.entityRotation.fY), ConvertRadiansToDegrees(result.entityRotation.fZ), result.lodID, result.type}; + return {result.collisionDetected, + collidedEntity, + result.modelID, + result.entityPosition.fX, + result.entityPosition.fY, + result.entityPosition.fZ, + ConvertRadiansToDegrees(result.entityRotation.fX), + ConvertRadiansToDegrees(result.entityRotation.fY), + ConvertRadiansToDegrees(result.entityRotation.fZ), + result.lodID, + result.type}; } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h index 5668ca6dd48..5ad83bdeae0 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h @@ -15,11 +15,12 @@ class CLuaWorldDefs : public CLuaDefs public: static void LoadFunctions(); - LUA_DECLARE(GetTime); LUA_DECLARE(GetGroundPosition); LUA_DECLARE(GetRoofPosition); - static std::variant> ProcessLineAgainstMesh(CClientEntity* e, CVector start, CVector end); + static std::variant> ProcessLineAgainstMesh(CClientEntity* e, + CVector start, + CVector end); LUA_DECLARE(ProcessLineOfSight); LUA_DECLARE(IsLineOfSightClear); LUA_DECLARE(GetWorldFromScreenPosition); @@ -115,9 +116,9 @@ class CLuaWorldDefs : public CLuaDefs LUA_DECLARE(CreateExplosion); - static bool ResetColorFilter(); - static bool SetColorFilter(uchar ucPass0Red, uchar ucPass0Green, uchar ucPass0Blue, uchar ucPass0Alpha, - uchar ucPass1Red, uchar ucPass1Green, uchar ucPass1Blue, uchar ucPass1Alpha); + static bool ResetColorFilter(); + static bool SetColorFilter(uchar ucPass0Red, uchar ucPass0Green, uchar ucPass0Blue, uchar ucPass0Alpha, uchar ucPass1Red, uchar ucPass1Green, + uchar ucPass1Blue, uchar ucPass1Alpha); static CLuaMultiReturn GetColorFilter(bool isOriginal = false); static bool SetGrainMultiplier(eGrainMultiplierType type, float fMultiplier); @@ -134,18 +135,21 @@ class CLuaWorldDefs : public CLuaDefs static bool SetTimeFrozen(bool value) noexcept; static bool IsTimeFrozen() noexcept; static bool ResetTimeFrozen() noexcept; - + static bool SetVolumetricShadowsEnabled(bool enable) noexcept; static bool IsVolumetricShadowsEnabled() noexcept; static bool ResetVolumetricShadows() noexcept; - - static void ResetWorldProperties(std::optional resetSpecialWorldProperties, std::optional resetWorldProperties, std::optional resetWeatherProperties, std::optional resetLODs, std::optional resetSounds) noexcept; + + static void ResetWorldProperties(std::optional resetSpecialWorldProperties, std::optional resetWorldProperties, + std::optional resetWeatherProperties, std::optional resetLODs, std::optional resetSounds) noexcept; static bool SetDynamicPedShadowsEnabled(bool enable); static bool IsDynamicPedShadowsEnabled() noexcept; static bool ResetDynamicPedShadows() noexcept; - static CLuaMultiReturn TestSphereAgainstWorld(CVector sphereCenter, float radius, std::optional ignoredEntity, std::optional checkBuildings, std::optional checkVehicles, std::optional checkPeds, std::optional checkObjects, std::optional checkDummies, std::optional cameraIgnore); + static CLuaMultiReturn TestSphereAgainstWorld( + CVector sphereCenter, float radius, std::optional ignoredEntity, std::optional checkBuildings, std::optional checkVehicles, + std::optional checkPeds, std::optional checkObjects, std::optional checkDummies, std::optional cameraIgnore); static void RemoveGameWorld(); static void RestoreGameWorld(); diff --git a/Client/mods/deathmatch/logic/rpc/CBlipRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CBlipRPCs.cpp index c684724e4fa..a59111ebe90 100644 --- a/Client/mods/deathmatch/logic/rpc/CBlipRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CBlipRPCs.cpp @@ -110,4 +110,4 @@ void CBlipRPCs::SetBlipVisibleDistance(CClientEntity* pSource, NetBitStreamInter pMarker->SetVisibleDistance(visibleDistance); } } -} \ No newline at end of file +} diff --git a/Client/mods/deathmatch/logic/rpc/CCameraRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CCameraRPCs.cpp index 88d9f133429..488e9921899 100644 --- a/Client/mods/deathmatch/logic/rpc/CCameraRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CCameraRPCs.cpp @@ -10,6 +10,7 @@ *****************************************************************************/ #include +#include #include "CCameraRPCs.h" void CCameraRPCs::LoadFunctions() @@ -22,82 +23,133 @@ void CCameraRPCs::LoadFunctions() void CCameraRPCs::SetCameraMatrix(NetBitStreamInterface& bitStream) { - if (bitStream.Version() >= 0x5E) - { - uchar ucTimeContext; - if (bitStream.Read(ucTimeContext)) - m_pCamera->SetSyncTimeContext(ucTimeContext); - } + uchar ucTimeContext; + if (!bitStream.Read(ucTimeContext)) + return; + + if (m_pCamera) + m_pCamera->SetSyncTimeContext(ucTimeContext); CVector vecPosition, vecLookAt; float fRoll = 0.0f; float fFOV = 70.0f; - if (bitStream.Read(vecPosition.fX) && bitStream.Read(vecPosition.fY) && bitStream.Read(vecPosition.fZ) && bitStream.Read(vecLookAt.fX) && - bitStream.Read(vecLookAt.fY) && bitStream.Read(vecLookAt.fZ)) + + if (!bitStream.Read(vecPosition.fX) || !bitStream.Read(vecPosition.fY) || !bitStream.Read(vecPosition.fZ) || !bitStream.Read(vecLookAt.fX) || + !bitStream.Read(vecLookAt.fY) || !bitStream.Read(vecLookAt.fZ)) { - bitStream.Read(fRoll); - bitStream.Read(fFOV); + return; // Invalid data + } - if (!m_pCamera->IsInFixedMode()) - m_pCamera->ToggleCameraFixedMode(true); + const unsigned int unreadBits = bitStream.GetNumberOfUnreadBits(); + if (unreadBits >= 64) + { + if (!bitStream.Read(fRoll) || !bitStream.Read(fFOV)) + return; + } + else if (unreadBits >= 32) + { + if (!bitStream.Read(fRoll)) + return; + } - // Put the camera there - m_pCamera->SetPosition(vecPosition); - m_pCamera->SetFixedTarget(vecLookAt, fRoll); - m_pCamera->SetFOV(fFOV); + // Validate float values to prevent potential issues + if (!std::isfinite(fRoll) || !std::isfinite(fFOV) || !std::isfinite(vecPosition.fX) || !std::isfinite(vecPosition.fY) || !std::isfinite(vecPosition.fZ) || + !std::isfinite(vecLookAt.fX) || !std::isfinite(vecLookAt.fY) || !std::isfinite(vecLookAt.fZ)) + { + return; // Invalid float values (NaN, infinity, etc.) } + + if (fFOV <= 0.0f) + fFOV = 70.0f; + else if (fFOV >= 180.0f) + fFOV = 179.0f; + + if (!std::isfinite(fRoll)) + fRoll = 0.0f; + else + { + constexpr float fullCircle = 360.0f; + fRoll = std::remainder(fRoll, fullCircle); + if (fRoll < 0.0f) + fRoll += fullCircle; + } + + // Validate camera pointer before use + if (!m_pCamera) + return; + + if (!m_pCamera->IsInFixedMode()) + m_pCamera->ToggleCameraFixedMode(true); + + // Put the camera there + m_pCamera->SetPosition(vecPosition); + m_pCamera->SetFixedTarget(vecLookAt, fRoll); + m_pCamera->SetFOV(fFOV); } void CCameraRPCs::SetCameraTarget(NetBitStreamInterface& bitStream) { - if (bitStream.Version() >= 0x5E) - { - uchar ucTimeContext; - if (bitStream.Read(ucTimeContext)) - m_pCamera->SetSyncTimeContext(ucTimeContext); - } + uchar ucTimeContext; + if (!bitStream.Read(ucTimeContext)) + return; + + if (m_pCamera) + m_pCamera->SetSyncTimeContext(ucTimeContext); ElementID targetID; - if (bitStream.Read(targetID)) + if (!bitStream.Read(targetID)) + return; + + // Validate camera pointer + if (!m_pCamera) + return; + + CClientEntity* pEntity = CElementIDs::GetElement(targetID); + if (!pEntity) + return; + + // Check if entity is being deleted - critical memory safety check + if (pEntity->IsBeingDeleted()) + return; + + switch (pEntity->GetType()) { - CClientEntity* pEntity = CElementIDs::GetElement(targetID); - if (pEntity) + case CCLIENTPLAYER: { - switch (pEntity->GetType()) + CClientPlayer* pPlayer = static_cast(pEntity); + if (pPlayer->IsLocalPlayer()) + { + // Return the focus to the local player + m_pCamera->SetFocusToLocalPlayer(); + } + else { - case CCLIENTPLAYER: - { - CClientPlayer* pPlayer = static_cast(pEntity); - if (pPlayer->IsLocalPlayer()) - { - // Return the focus to the local player - m_pCamera->SetFocusToLocalPlayer(); - } - else - { - // Put the focus on that player - m_pCamera->SetFocus(pPlayer, MODE_CAM_ON_A_STRING, false); - } - break; - } - case CCLIENTPED: - case CCLIENTVEHICLE: - { - m_pCamera->SetFocus(pEntity, MODE_CAM_ON_A_STRING, false); - break; - } - default: - return; + // Put the focus on that player + m_pCamera->SetFocus(pPlayer, MODE_CAM_ON_A_STRING, false); } + break; } + case CCLIENTPED: + case CCLIENTVEHICLE: + { + m_pCamera->SetFocus(pEntity, MODE_CAM_ON_A_STRING, false); + break; + } + default: + // Invalid entity type for camera target + return; } } void CCameraRPCs::SetCameraInterior(NetBitStreamInterface& bitStream) { - // Read out the camera mode + // Read out the camera interior unsigned char ucInterior; - if (bitStream.Read(ucInterior)) + if (!bitStream.Read(ucInterior)) + return; + + // Validate game pointer before use + if (g_pGame && g_pGame->GetWorld()) { g_pGame->GetWorld()->SetCurrentArea(ucInterior); } @@ -107,26 +159,41 @@ void CCameraRPCs::FadeCamera(NetBitStreamInterface& bitStream) { unsigned char ucFadeIn; float fFadeTime = 1.0f; - if (bitStream.Read(ucFadeIn) && bitStream.Read(fFadeTime)) + + if (!bitStream.Read(ucFadeIn) || !bitStream.Read(fFadeTime)) + return; + + // Validate pointers before use + if (!m_pCamera || !g_pClientGame) + return; + + g_pClientGame->SetInitiallyFadedOut(false); + + if (ucFadeIn) { - g_pClientGame->SetInitiallyFadedOut(false); + m_pCamera->FadeIn(fFadeTime); - if (ucFadeIn) + // Validate game and HUD pointers + if (g_pGame && g_pGame->GetHud()) { - m_pCamera->FadeIn(fFadeTime); g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, !g_pClientGame->GetHudAreaNameDisabled()); } - else - { - unsigned char ucRed = 0; - unsigned char ucGreen = 0; - unsigned char ucBlue = 0; + } + else + { + unsigned char ucRed = 0; + unsigned char ucGreen = 0; + unsigned char ucBlue = 0; - if (bitStream.Read(ucRed) && bitStream.Read(ucGreen) && bitStream.Read(ucBlue)) - { - m_pCamera->FadeOut(fFadeTime, ucRed, ucGreen, ucBlue); - g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false); - } + if (!bitStream.Read(ucRed) || !bitStream.Read(ucGreen) || !bitStream.Read(ucBlue)) + return; + + m_pCamera->FadeOut(fFadeTime, ucRed, ucGreen, ucBlue); + + // Validate game and HUD pointers + if (g_pGame && g_pGame->GetHud()) + { + g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false); } } } diff --git a/Client/mods/deathmatch/logic/rpc/CElementRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CElementRPCs.cpp index dfd790cdd0e..224c0c01b5b 100644 --- a/Client/mods/deathmatch/logic/rpc/CElementRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CElementRPCs.cpp @@ -96,7 +96,7 @@ void CElementRPCs::SetElementData(CClientEntity* pSource, NetBitStreamInterface& CLuaArgument Argument; if (bitStream.ReadStringCharacters(strName, usNameLength) && Argument.ReadFromBitStream(bitStream)) { - pSource->SetCustomData(strName, Argument); + pSource->SetCustomData(CStringName{strName}, Argument); } } } @@ -105,7 +105,7 @@ void CElementRPCs::RemoveElementData(CClientEntity* pSource, NetBitStreamInterfa { // Read out the name length unsigned short usNameLength; - bool bRecursive; // Unused + bool bRecursive; // Unused if (bitStream.ReadCompressed(usNameLength)) { SString strName; @@ -114,7 +114,7 @@ void CElementRPCs::RemoveElementData(CClientEntity* pSource, NetBitStreamInterfa if (bitStream.ReadStringCharacters(strName, usNameLength) && bitStream.ReadBit(bRecursive)) { // Remove that name - pSource->DeleteCustomData(strName); + pSource->DeleteCustomData(CStringName{strName}); } } } @@ -313,32 +313,90 @@ void CElementRPCs::SetElementDimension(CClientEntity* pSource, NetBitStreamInter void CElementRPCs::AttachElements(CClientEntity* pSource, NetBitStreamInterface& bitStream) { ElementID usAttachedToID; - CVector vecPosition, vecRotation; - if (bitStream.Read(usAttachedToID) && bitStream.Read(vecPosition.fX) && bitStream.Read(vecPosition.fY) && bitStream.Read(vecPosition.fZ) && - bitStream.Read(vecRotation.fX) && bitStream.Read(vecRotation.fY) && bitStream.Read(vecRotation.fZ)) + + CVector vecPosition; + CVector vecRotation; + + if (!(bitStream.Read(usAttachedToID) && bitStream.Read(vecPosition.fX) && bitStream.Read(vecPosition.fY) && bitStream.Read(vecPosition.fZ) && + bitStream.Read(vecRotation.fX) && bitStream.Read(vecRotation.fY) && bitStream.Read(vecRotation.fZ))) { - CClientEntity* pAttachedToEntity = CElementIDs::GetElement(usAttachedToID); - if (pAttachedToEntity) - { - pSource->SetAttachedOffsets(vecPosition, vecRotation); - pSource->AttachTo(pAttachedToEntity); - } + return; + } + + CClientEntity* pAttachedToEntity = CElementIDs::GetElement(usAttachedToID); + if (!pAttachedToEntity) + { + return; } + + ConvertRadiansToDegrees(vecRotation); + + CLuaArguments Arguments; + Arguments.PushElement(pAttachedToEntity); + Arguments.PushNumber(vecPosition.fX); + Arguments.PushNumber(vecPosition.fY); + Arguments.PushNumber(vecPosition.fZ); + Arguments.PushNumber(vecRotation.fX); + Arguments.PushNumber(vecRotation.fY); + Arguments.PushNumber(vecRotation.fZ); + + if (!pSource->CallEvent("onClientElementAttach", Arguments, true)) + { + return; + } + + ConvertDegreesToRadians(vecRotation); + + pSource->SetAttachedOffsets(vecPosition, vecRotation); + pSource->AttachTo(pAttachedToEntity); } void CElementRPCs::DetachElements(CClientEntity* pSource, NetBitStreamInterface& bitStream) { unsigned char ucTimeContext; - if (bitStream.Read(ucTimeContext)) + if (!bitStream.Read(ucTimeContext)) { - pSource->SetSyncTimeContext(ucTimeContext); - pSource->AttachTo(NULL); + return; + } - CVector vecPosition; - if (bitStream.Read(vecPosition.fX) && bitStream.Read(vecPosition.fY) && bitStream.Read(vecPosition.fZ)) - { - pSource->SetPosition(vecPosition); - } + ElementID usAttachedToID; + CClientEntity* pAttachedToEntity = CElementIDs::GetElement(usAttachedToID); + + CVector vecPosition; + CVector vecRotation; + + bitStream.Read(vecPosition.fX); + bitStream.Read(vecPosition.fY); + bitStream.Read(vecPosition.fZ); + bitStream.Read(vecRotation.fX); + bitStream.Read(vecRotation.fY); + bitStream.Read(vecRotation.fZ); + + CLuaArguments Arguments; + Arguments.PushElement(pAttachedToEntity); + Arguments.PushNumber(vecPosition.fX); + Arguments.PushNumber(vecPosition.fY); + Arguments.PushNumber(vecPosition.fZ); + Arguments.PushNumber(vecRotation.fX); + Arguments.PushNumber(vecRotation.fY); + Arguments.PushNumber(vecRotation.fZ); + + if (!pSource->CallEvent("onClientElementDetach", Arguments, true)) + { + return; + } + + pSource->SetSyncTimeContext(ucTimeContext); + pSource->AttachTo(NULL); + + if (vecPosition.fX != 0.0f || vecPosition.fY != 0.0f || vecPosition.fZ != 0.0f) + { + pSource->SetPosition(vecPosition); + } + + if (vecRotation.fX != 0.0f || vecRotation.fY != 0.0f || vecRotation.fZ != 0.0f) + { + pSource->SetRotationDegrees(vecRotation); } } @@ -408,7 +466,15 @@ void CElementRPCs::SetElementHealth(CClientEntity* pSource, NetBitStreamInterfac if (pPed->IsHealthLocked()) pPed->LockHealth(fHealth); else + { pPed->SetHealth(fHealth); + // If server sets health to 0 for local player, mark as server-processed death + // to prevent DoWastedCheck from firing with stale local damage data + if (fHealth == 0.0f && pPed->IsLocalPlayer()) + { + g_pClientGame->ClearDamageData(); + } + } break; } diff --git a/Client/mods/deathmatch/logic/rpc/CHandlingRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CHandlingRPCs.cpp index 138048e9db3..2efa967b0da 100644 --- a/Client/mods/deathmatch/logic/rpc/CHandlingRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CHandlingRPCs.cpp @@ -364,10 +364,12 @@ void CHandlingRPCs::RestoreVehicleHandlingProperty(CClientEntity* pSource, NetBi CClientVehicle& Vehicle = static_cast(*pSource); CHandlingEntry* pHandlingEntry = Vehicle.GetHandlingData(); const CHandlingEntry* pOriginalEntry = Vehicle.GetOriginalHandlingData(); + CModelInfo* pModelInfo = Vehicle.GetModelInfo(); HandlingProperty property = static_cast(ucProperty); + const bool bSupportsSuspension = pModelInfo && (pModelInfo->IsCar() || pModelInfo->IsMonsterTruck()); if (property >= HandlingProperty::HANDLING_SUSPENSION_FORCELEVEL && property <= HandlingProperty::HANDLING_SUSPENSION_ANTIDIVEMULTIPLIER && - (Vehicle.GetModelInfo()->IsCar() || Vehicle.GetModelInfo()->IsMonsterTruck())) + !bSupportsSuspension) { return; } diff --git a/Client/mods/deathmatch/logic/rpc/CInputRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CInputRPCs.cpp index 4b0dcebb500..52d48493ab1 100644 --- a/Client/mods/deathmatch/logic/rpc/CInputRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CInputRPCs.cpp @@ -126,6 +126,7 @@ void CInputRPCs::UnbindKey(NetBitStreamInterface& bitStream) const SBindableKey* pKey = pKeyBinds->GetBindableFromKey(szKey); if (pKey) { + // Only remove server-side function bindings, preserve user command bindings pKeyBinds->RemoveFunction(szKey, CClientGame::StaticProcessServerKeyBind, true, bState); } else @@ -133,6 +134,7 @@ void CInputRPCs::UnbindKey(NetBitStreamInterface& bitStream) SBindableGTAControl* pControl = pKeyBinds->GetBindableFromControl(szKey); if (pControl) { + // Only remove server-side control function bindings, preserve user command bindings pKeyBinds->RemoveControlFunction(szKey, CClientGame::StaticProcessServerControlBind, true, bState); } } diff --git a/Client/mods/deathmatch/logic/rpc/CObjectRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CObjectRPCs.cpp index a4093f3cf53..15ff752b6a3 100644 --- a/Client/mods/deathmatch/logic/rpc/CObjectRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CObjectRPCs.cpp @@ -95,11 +95,8 @@ void CObjectRPCs::SetObjectScale(CClientEntity* pSource, NetBitStreamInterface& bitStream.Read(vecScale.fX); vecScale.fY = vecScale.fX; vecScale.fZ = vecScale.fX; - if (bitStream.Version() >= 0x40) - { - bitStream.Read(vecScale.fY); - bitStream.Read(vecScale.fZ); - } + bitStream.Read(vecScale.fY); + bitStream.Read(vecScale.fZ); pObject->SetScale(vecScale); } } @@ -132,7 +129,7 @@ void CObjectRPCs::SetObjectBreakable(CClientEntity* pSource, NetBitStreamInterfa void CObjectRPCs::BreakObject(CClientEntity* pSource, NetBitStreamInterface& bitStream) { - auto* pObject = static_cast(m_pObjectManager->Get(pSource->GetID())); + auto* pObject = static_cast(m_pObjectManager->Get(pSource->GetID())); if (pObject) pObject->Break(); diff --git a/Client/mods/deathmatch/logic/rpc/CPedRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CPedRPCs.cpp index f01e91f09db..00ab607e11e 100644 --- a/Client/mods/deathmatch/logic/rpc/CPedRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CPedRPCs.cpp @@ -260,14 +260,11 @@ void CPedRPCs::SetPedAnimation(CClientEntity* pSource, NetBitStreamInterface& bi if (bitStream.ReadString(animName) && bitStream.Read(iTime) && bitStream.ReadBit(bLoop) && bitStream.ReadBit(bUpdatePosition) && bitStream.ReadBit(bInterruptable) && bitStream.ReadBit(bFreezeLastFrame)) { - if (bitStream.Can(eBitStreamVersion::SetPedAnimation_Blend)) + bitStream.Read(iBlend); + bitStream.ReadBit(bTaskToBeRestoredOnAnimEnd); + if (!pPed->IsDucked()) { - bitStream.Read(iBlend); - bitStream.ReadBit(bTaskToBeRestoredOnAnimEnd); - if (!pPed->IsDucked()) - { - bTaskToBeRestoredOnAnimEnd = false; - } + bTaskToBeRestoredOnAnimEnd = false; } std::unique_ptr pBlock = g_pGame->GetAnimManager()->GetAnimationBlock(blockName.c_str()); @@ -276,6 +273,12 @@ void CPedRPCs::SetPedAnimation(CClientEntity* pSource, NetBitStreamInterface& bi pPed->RunNamedAnimation(pBlock, animName.c_str(), iTime, iBlend, bLoop, bUpdatePosition, bInterruptable, bFreezeLastFrame); pPed->SetTaskToBeRestoredOnAnimEnd(bTaskToBeRestoredOnAnimEnd); pPed->SetTaskTypeToBeRestoredOnAnimEnd((eTaskType)TASK_SIMPLE_DUCK); + + pPed->m_AnimationCache.startTime = GetTimestamp(); + pPed->m_AnimationCache.speed = 1.0f; + pPed->m_AnimationCache.progress = 0.0f; + + pPed->SetHasSyncedAnim(true); } } } @@ -307,6 +310,7 @@ void CPedRPCs::SetPedAnimationProgress(CClientEntity* pSource, NetBitStreamInter if (pAnimAssociation) { pAnimAssociation->SetCurrentProgress(fProgress); + pPed->m_AnimationCache.progress = fProgress; } } } @@ -334,6 +338,7 @@ void CPedRPCs::SetPedAnimationSpeed(CClientEntity* pSource, NetBitStreamInterfac if (pAnimAssociation) { pAnimAssociation->SetCurrentSpeed(fSpeed); + pPed->m_AnimationCache.speed = fSpeed; } } } diff --git a/Client/mods/deathmatch/logic/rpc/CPickupRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CPickupRPCs.cpp index 88611e4d3ab..c303c6043c9 100644 --- a/Client/mods/deathmatch/logic/rpc/CPickupRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CPickupRPCs.cpp @@ -69,7 +69,6 @@ void CPickupRPCs::SetPickupType(CClientEntity* pSource, NetBitStreamInterface& b { pPickup->SetModel(usModel); pPickup->m_ucType = ucType; - pPickup->SetModel(usModel); } } } @@ -90,4 +89,4 @@ void CPickupRPCs::SetPickupVisible(CClientEntity* pSource, NetBitStreamInterface pPickup->SetVisible(ucVisible != 0); } } -} \ No newline at end of file +} diff --git a/Client/mods/deathmatch/logic/rpc/CPlayerRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CPlayerRPCs.cpp index 7a4243bc0d7..8c0423ac157 100644 --- a/Client/mods/deathmatch/logic/rpc/CPlayerRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CPlayerRPCs.cpp @@ -151,18 +151,10 @@ void CPlayerRPCs::TakePlayerScreenShot(NetBitStreamInterface& bitStream) bitStream.Read(ucQuality); bitStream.Read(uiMaxBandwidth); bitStream.Read(usMaxPacketSize); - if (bitStream.Version() >= 0x53) - { - ushort usResourceNetId; - bitStream.Read(usResourceNetId); - pResource = g_pClientGame->GetResourceManager()->GetResourceFromNetID(usResourceNetId); - } - else - { - SString strResourceName; - bitStream.ReadString(strResourceName); - pResource = g_pClientGame->GetResourceManager()->GetResource(strResourceName); - } + + ushort usResourceNetId; + bitStream.Read(usResourceNetId); + pResource = g_pClientGame->GetResourceManager()->GetResourceFromNetID(usResourceNetId); if (!bitStream.Read(uiServerSentTime)) return; diff --git a/Client/mods/deathmatch/logic/rpc/CRPCFunctions.h b/Client/mods/deathmatch/logic/rpc/CRPCFunctions.h index 81fd123b0a6..4b3f44c3384 100644 --- a/Client/mods/deathmatch/logic/rpc/CRPCFunctions.h +++ b/Client/mods/deathmatch/logic/rpc/CRPCFunctions.h @@ -13,8 +13,8 @@ class CRPCFunctions; -#define DECLARE_RPC(a) static void a ( class NetBitStreamInterface& bitStream ); -#define DECLARE_ELEMENT_RPC(a) static void a ( CClientEntity* pSourceEntity, NetBitStreamInterface& bitStream ); +#define DECLARE_RPC(a) static void a(class NetBitStreamInterface& bitStream); +#define DECLARE_ELEMENT_RPC(a) static void a(CClientEntity* pSourceEntity, NetBitStreamInterface& bitStream); class CRPCFunctions { @@ -65,8 +65,8 @@ class CRPCFunctions static class CClientGame* m_pClientGame; protected: - // Include the RPC functions enum - #include "net/rpc_enums.h" +// Include the RPC functions enum +#include "net/rpc_enums.h" static SFixedArray m_RPCHandlers; static SFixedArray m_ElementRPCHandlers; diff --git a/Client/mods/deathmatch/logic/rpc/CRadarRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CRadarRPCs.cpp index 288ac1977ed..ce6a8f3903c 100644 --- a/Client/mods/deathmatch/logic/rpc/CRadarRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CRadarRPCs.cpp @@ -72,4 +72,4 @@ void CRadarRPCs::SetRadarAreaFlashing(CClientEntity* pSource, NetBitStreamInterf pArea->SetFlashing(bFlashing); } } -} \ No newline at end of file +} diff --git a/Client/mods/deathmatch/logic/rpc/CTeamRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CTeamRPCs.cpp index 60d27ce0744..5eb1d7b4253 100644 --- a/Client/mods/deathmatch/logic/rpc/CTeamRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CTeamRPCs.cpp @@ -56,4 +56,4 @@ void CTeamRPCs::SetTeamFriendlyFire(CClientEntity* pSource, NetBitStreamInterfac pTeam->SetFriendlyFire(bFriendlyFire); } } -} \ No newline at end of file +} diff --git a/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp index 037f9d92d59..d78b978b928 100644 --- a/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp @@ -85,7 +85,7 @@ void CVehicleRPCs::BlowVehicle(CClientEntity* pSource, NetBitStreamInterface& bi if (bitStream.Read(syncTimeContext)) { - if (bitStream.Can(eBitStreamVersion::VehicleBlowStateSupport) && !bitStream.ReadBit(withExplosion)) + if (!bitStream.ReadBit(withExplosion)) { return; } @@ -312,24 +312,21 @@ void CVehicleRPCs::SetVehicleDamageState(CClientEntity* pSource, NetBitStreamInt { switch (ucObject) { - case 0: // Door + case 0: // Door { unsigned char ucDoor, ucState; if (bitStream.Read(ucDoor) && bitStream.Read(ucState)) { bool spawnFlyingComponent = true; - if (bitStream.Can(eBitStreamVersion::SetVehicleDoorState_SpawnFlyingComponent)) - { - if (!bitStream.ReadBit(spawnFlyingComponent)) - break; - } + if (!bitStream.ReadBit(spawnFlyingComponent)) + break; pVehicle->SetDoorStatus(ucDoor, ucState, spawnFlyingComponent); } break; } - case 1: // Wheel + case 1: // Wheel { unsigned char ucWheel, ucState; if (bitStream.Read(ucWheel) && bitStream.Read(ucState)) @@ -338,7 +335,7 @@ void CVehicleRPCs::SetVehicleDamageState(CClientEntity* pSource, NetBitStreamInt } break; } - case 2: // Light + case 2: // Light { unsigned char ucLight, ucState; if (bitStream.Read(ucLight) && bitStream.Read(ucState)) @@ -347,18 +344,15 @@ void CVehicleRPCs::SetVehicleDamageState(CClientEntity* pSource, NetBitStreamInt } break; } - case 3: // Panel + case 3: // Panel { unsigned char ucPanel, ucState; if (bitStream.Read(ucPanel) && bitStream.Read(ucState)) { bool spawnFlyingComponent = true; bool breakGlass = false; - if (bitStream.Can(eBitStreamVersion::SetVehiclePanelState_SpawnFlyingComponent)) - { - bitStream.ReadBit(spawnFlyingComponent); - bitStream.ReadBit(breakGlass); - } + bitStream.ReadBit(spawnFlyingComponent); + bitStream.ReadBit(breakGlass); pVehicle->SetPanelStatus(ucPanel, ucState, spawnFlyingComponent, breakGlass); } @@ -456,7 +450,7 @@ void CVehicleRPCs::SetVehicleWheelStates(CClientEntity* pSource, NetBitStreamInt CClientVehicle* pVehicle = m_pVehicleManager->Get(pSource->GetID()); if (pVehicle) { - for (int i = 0; i < MAX_WHEELS; i++) + for (unsigned char i = 0; i < MAX_WHEELS; i++) pVehicle->SetWheelStatus(i, ucWheelStates[i], false); } } @@ -683,12 +677,12 @@ void CVehicleRPCs::SetVehicleNitroActivated(CClientEntity* pSourceEntity, NetBit CClientVehicle* vehicle = m_pVehicleManager->Get(pSourceEntity->GetID()); if (!vehicle) - return; + return; if (!vehicle->IsNitroInstalled()) return; - // If nitro level < 0, nitro is activated. (until nitro level reaches -1, at that point it will become 0 and increase instead of decrease) + // If nitro level < 0, nitro is activated. (until nitro level reaches -1, at that point it will become 0 and increase instead of decrease) if ((vehicle->GetNitroLevel() < 0.0f) == state) return; @@ -698,4 +692,3 @@ void CVehicleRPCs::SetVehicleNitroActivated(CClientEntity* pSourceEntity, NetBit else vehicle->SetNitroLevel(vehicle->GetNitroLevel() + 1.0001f); } - diff --git a/Client/mods/deathmatch/logic/rpc/CWaterRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CWaterRPCs.cpp index 71800ad371d..91ad0026ee1 100644 --- a/Client/mods/deathmatch/logic/rpc/CWaterRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CWaterRPCs.cpp @@ -32,11 +32,8 @@ void CWaterRPCs::SetWorldWaterLevel(NetBitStreamInterface& bitStream) if (bitStream.Read(fLevel) && bitStream.ReadBit(bIncludeWorldNonSeaLevel)) { - if (bitStream.Can(eBitStreamVersion::SetWaterLevel_ChangeOutsideWorldLevel)) - { - bitStream.ReadBit(bIncludeWorldSeaLevel); - bitStream.ReadBit(bIncludeOutsideWorldLevel); - } + bitStream.ReadBit(bIncludeWorldSeaLevel); + bitStream.ReadBit(bIncludeOutsideWorldLevel); m_pWaterManager->SetWorldWaterLevel(fLevel, nullptr, bIncludeWorldNonSeaLevel, bIncludeWorldSeaLevel, bIncludeOutsideWorldLevel); } } diff --git a/Client/mods/deathmatch/logic/rpc/CWorldRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CWorldRPCs.cpp index 79a1952570f..38a15493fad 100644 --- a/Client/mods/deathmatch/logic/rpc/CWorldRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CWorldRPCs.cpp @@ -212,9 +212,9 @@ void CWorldRPCs::ResetMapInfo(NetBitStreamInterface& bitStream) void CWorldRPCs::SetFPSLimit(NetBitStreamInterface& bitStream) { - short sFPSLimit; - bitStream.Read(sFPSLimit); - g_pCore->RecalculateFrameRateLimit(sFPSLimit); + std::uint16_t fps; + bitStream.Read(fps); + CStaticFunctionDefinitions::SetServerFPSLimit(fps); } void CWorldRPCs::SetGarageOpen(NetBitStreamInterface& bitStream) @@ -368,12 +368,9 @@ void CWorldRPCs::SetAircraftMaxVelocity(NetBitStreamInterface& bitStream) { float fVelocity; - if (bitStream.Version() >= 0x3E) + if (bitStream.Read(fVelocity)) { - if (bitStream.Read(fVelocity)) - { - g_pGame->GetWorld()->SetAircraftMaxVelocity(fVelocity); - } + g_pGame->GetWorld()->SetAircraftMaxVelocity(fVelocity); } } @@ -525,14 +522,7 @@ void CWorldRPCs::SetWeaponProperty(NetBitStreamInterface& bitStream) case WeaponProperty::WEAPON_FLAGS: { int iData = 0; - if (bitStream.Version() < 0x57) - { - bitStream.Read(sData); - iData = sData; - } - else - bitStream.Read(iData); - + bitStream.Read(iData); pWeaponInfo->ToggleFlagBits(iData); break; } @@ -579,12 +569,8 @@ void CWorldRPCs::RemoveWorldModel(NetBitStreamInterface& bitStream) unsigned short usModel = 0; float fRadius = 0.0f, fX = 0.0f, fY = 0.0f, fZ = 0.0f; char cInterior = -1; - if (bitStream.Read(usModel) && bitStream.Read(fRadius) && bitStream.Read(fX) && bitStream.Read(fY) && bitStream.Read(fZ)) + if (bitStream.Read(usModel) && bitStream.Read(fRadius) && bitStream.Read(fX) && bitStream.Read(fY) && bitStream.Read(fZ) && bitStream.Read(cInterior)) { - if (bitStream.Version() >= 0x039) - { - bitStream.Read(cInterior); - } g_pGame->GetBuildingRemoval()->RemoveBuilding(usModel, fRadius, fX, fY, fZ, cInterior); } } @@ -594,12 +580,8 @@ void CWorldRPCs::RestoreWorldModel(NetBitStreamInterface& bitStream) unsigned short usModel = 0; float fRadius = 0.0f, fX = 0.0f, fY = 0.0f, fZ = 0.0f; char cInterior = -1; - if (bitStream.Read(usModel) && bitStream.Read(fRadius) && bitStream.Read(fX) && bitStream.Read(fY) && bitStream.Read(fZ)) + if (bitStream.Read(usModel) && bitStream.Read(fRadius) && bitStream.Read(fX) && bitStream.Read(fY) && bitStream.Read(fZ) && bitStream.Read(cInterior)) { - if (bitStream.Version() >= 0x039) - { - bitStream.Read(cInterior); - } g_pGame->GetBuildingRemoval()->RestoreBuilding(usModel, fRadius, fX, fY, fZ, cInterior); } } @@ -619,12 +601,8 @@ void CWorldRPCs::SetSyncIntervals(NetBitStreamInterface& bitStream) bitStream.Read(g_TickRateSettings.iObjectSync); bitStream.Read(g_TickRateSettings.iKeySyncRotation); bitStream.Read(g_TickRateSettings.iKeySyncAnalogMove); - - if (bitStream.Can(eBitStreamVersion::FixSyncerDistance)) - { - bitStream.Read(g_TickRateSettings.iPedSyncerDistance); - bitStream.Read(g_TickRateSettings.iUnoccupiedVehicleSyncerDistance); - } + bitStream.Read(g_TickRateSettings.iPedSyncerDistance); + bitStream.Read(g_TickRateSettings.iUnoccupiedVehicleSyncerDistance); } void CWorldRPCs::SetMoonSize(NetBitStreamInterface& bitStream) diff --git a/Client/mods/deathmatch/premake5.lua b/Client/mods/deathmatch/premake5.lua index 07013f8d8df..752ddbd54a3 100644 --- a/Client/mods/deathmatch/premake5.lua +++ b/Client/mods/deathmatch/premake5.lua @@ -3,6 +3,7 @@ project "Client Deathmatch" kind "SharedLib" targetname "client" targetdir(buildpath("mods/deathmatch")) + clangtidy "On" pchheader "StdInc.h" pchsource "StdInc.cpp" @@ -32,6 +33,7 @@ project "Client Deathmatch" ".", "./logic", "../../sdk/", + "../../", "../../../vendor/pthreads/include", "../../../vendor/bochs", "../../../vendor/bass", diff --git a/Client/multiplayer_sa/CLimitsSA.cpp b/Client/multiplayer_sa/CLimitsSA.cpp index bc4cb0d9a22..d95a79be868 100644 --- a/Client/multiplayer_sa/CLimitsSA.cpp +++ b/Client/multiplayer_sa/CLimitsSA.cpp @@ -19,8 +19,8 @@ #include "StdInc.h" -#define INTEGER_AT(addr) *(int *)(addr) -#define FLOAT_AT(addr) *(float *)(addr) +#define INTEGER_AT(addr) *(int*)(addr) +#define FLOAT_AT(addr) *(float*)(addr) int CLimitsSA::GetIPLFiles() const { diff --git a/Client/multiplayer_sa/CMultiplayerSA.cpp b/Client/multiplayer_sa/CMultiplayerSA.cpp index 2389110fbf9..a190b1a5f09 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA.cpp @@ -17,11 +17,18 @@ #include #include +typedef RwRaster*(__cdecl* RwRasterUnlock_t)(RwRaster* raster); +typedef RwRaster*(__cdecl* RwRasterLock_t)(RwRaster* raster, unsigned char level, int lockmode); +extern RwRasterUnlock_t RwRasterUnlock; +extern RwRasterLock_t RwRasterLock; + class CEventDamageSAInterface; extern CCoreInterface* g_pCore; extern CMultiplayerSA* pMultiplayer; +void ProcessDeferredStreamingMemoryRelief(); + using namespace std; char* CMultiplayerSA::ms_PlayerImgCachePtr = NULL; @@ -36,6 +43,8 @@ extern CGame* pGameInterface; #define HOOKPOS_CRunningScript_Process 0x469F00 #define HOOKPOS_CExplosion_AddExplosion 0x736A50 #define HOOKPOS_CCustomRoadsignMgr__RenderRoadsignAtomic 0x6FF35B +#define HOOKPOS_CEntity__CreateEffects_RoadsignAtomic 0x53388C +#define HOOKPOS_RoadsignGenerateTextRaster 0x6FEB70 #define HOOKPOS_Trailer_BreakTowLink 0x6E0027 #define HOOKPOS_CRadar__DrawRadarGangOverlay 0x586650 #define HOOKPOS_CTaskComplexJump__CreateSubTask 0x67DABE @@ -48,19 +57,24 @@ extern CGame* pGameInterface; #define HOOKPOS_ComputeDamageResponse_StartChoking 0x4C05B9 #define HOOKPOS_CAutomobile__ProcessSwingingDoor 0x6A9DAF -#define FUNC_CStreaming_Update 0x40E670 -#define FUNC_CAudioEngine__DisplayRadioStationName 0x507030 -#define FUNC_CHud_Draw 0x58FAE0 -#define FUNC_CPlayerInfoBase 0xB7CD98 +#define FUNC_CStreaming_Update 0x40E670 +#define FUNC_CAudioEngine__DisplayRadioStationName 0x507030 +#define FUNC_CHud_Draw 0x58FAE0 +#define FUNC_CPlayerInfoBase 0xB7CD98 +#define FUNC_RoadsignGetLineAndRow 0x6FE260 -#define ADDR_CursorHiding 0x7481CD -#define ADDR_GotFocus 0x748054 +#define VAR_RoadsignRasterLockedData 0xC3EF88 -#define HOOKPOS_FxManager_CreateFxSystem 0x4A9BE0 -#define HOOKPOS_FxManager_DestroyFxSystem 0x4A9810 +#define ADDR_CursorHiding 0x7481CD +#define ADDR_GotFocus 0x748054 -DWORD RETURN_FxManager_CreateFxSystem = 0x4A9BE8; -DWORD RETURN_FxManager_DestroyFxSystem = 0x4A9817; +#define HOOKPOS_FxManager_CreateFxSystem 0x4A9BE0 +#define HOOKPOS_FxManager_DestroyFxSystem 0x4A9810 + +DWORD RETURN_FxManager_CreateFxSystem = 0x4A9BE8; +DWORD RETURN_FxManager_DestroyFxSystem = 0x4A9817; +static constexpr std::uintptr_t RETURN_CEntity__CreateEffects_RoadsignAtomic = 0x533891; +static constexpr std::uintptr_t RETURN_CEntity__CreateEffects_RoadsignSkip = 0x5337E7; #define HOOKPOS_CCam_ProcessFixed 0x51D470 #define HOOKPOS_CTaskSimplePlayerOnFoot_ProcessPlayerWeapon 0x6859a0 @@ -70,234 +84,227 @@ DWORD RETURN_CCam_ProcessFixed = 0x51D475; DWORD RETURN_CTaskSimplePlayerOnFoot_ProcessPlayerWeapon = 0x6859A7; DWORD RETURN_CPed_IsPlayer = 0x5DF8F6; -#define VAR_CollisionStreamRead_ModelInfo 0x9689E0 -#define HOOKPOS_CollisionStreamRead 0x41B1D0 +#define VAR_CollisionStreamRead_ModelInfo 0x9689E0 +#define HOOKPOS_CollisionStreamRead 0x41B1D0 DWORD RETURN_CollisionStreamRead = 0x41B1D6; -#define CALL_Render3DStuff 0x53EABF -#define FUNC_Render3DStuff 0x53DF40 +#define CALL_Render3DStuff 0x53EABF +#define FUNC_Render3DStuff 0x53DF40 -#define CALL_CRenderer_Render 0x53EA12 -#define FUNC_CRenderer_Render 0x727140 +#define CALL_CRenderer_Render 0x53EA12 +#define FUNC_CRenderer_Render 0x727140 -#define CALL_CTrafficLights_GetPrimaryLightState 0x49DB5F -#define CALL_CTrafficLights_GetSecondaryLightState 0x49DB6D -#define HOOKPOS_CTrafficLights_DisplayActualLight 0x49E1D9 +#define CALL_CTrafficLights_GetPrimaryLightState 0x49DB5F +#define CALL_CTrafficLights_GetSecondaryLightState 0x49DB6D +#define HOOKPOS_CTrafficLights_DisplayActualLight 0x49E1D9 DWORD RETURN_CTrafficLights_DisplayActualLight = 0x49E1FF; -#define HOOKPOS_CGame_Process 0x53C095 +#define HOOKPOS_CGame_Process 0x53C095 DWORD RETURN_CGame_Process = 0x53C09F; -#define HOOKPOS_Idle 0x53E981 +#define HOOKPOS_Idle 0x53E981 DWORD RETURN_Idle = 0x53E98B; DWORD FUNC_CEntity_Render = 0x534310; -#define HOOKPOS_VehicleCamStart 0x5245ED +#define HOOKPOS_VehicleCamStart 0x5245ED DWORD RETURN_VehicleCamStart_success = 0x5245F3; DWORD RETURN_VehicleCamStart_failure = 0x525E43; -#define HOOKPOS_VehicleCamTargetZTweak 0x524A68 +#define HOOKPOS_VehicleCamTargetZTweak 0x524A68 DWORD RETURN_VehicleCamTargetZTweak = 0x524AA4; -#define HOOKPOS_VehicleCamLookDir1 0x524DF1 +#define HOOKPOS_VehicleCamLookDir1 0x524DF1 DWORD RETURN_VehicleCamLookDir1 = 0x524DF6; -#define HOOKPOS_VehicleCamLookDir2 0x525B0E +#define HOOKPOS_VehicleCamLookDir2 0x525B0E DWORD RETURN_VehicleCamLookDir2 = 0x525B73; -#define HOOKPOS_VehicleCamHistory 0x525C56 +#define HOOKPOS_VehicleCamHistory 0x525C56 DWORD RETURN_VehicleCamHistory = 0x525D4A; -#define HOOKPOS_VehicleCamColDetect 0x525D8D +#define HOOKPOS_VehicleCamColDetect 0x525D8D DWORD RETURN_VehicleCamColDetect = 0x525D92; -#define CALL_VehicleCamUp 0x525E1F -#define HOOKPOS_VehicleCamEnd 0x525E3C +#define CALL_VehicleCamUp 0x525E1F +#define HOOKPOS_VehicleCamEnd 0x525E3C DWORD RETURN_VehicleCamEnd = 0x525E42; -#define HOOKPOS_VehicleLookBehind 0x5207E3 +#define HOOKPOS_VehicleLookBehind 0x5207E3 DWORD RETURN_VehicleLookBehind = 0x520891; -#define CALL_VehicleLookBehindUp 0x520E2A -#define HOOKPOS_VehicleLookAside 0x520F70 +#define CALL_VehicleLookBehindUp 0x520E2A +#define HOOKPOS_VehicleLookAside 0x520F70 DWORD RETURN_VehicleLookAside = 0x520FDC; -#define CALL_VehicleLookAsideUp 0x5211E0 +#define CALL_VehicleLookAsideUp 0x5211E0 -#define HOOKPOS_OccupiedVehicleBurnCheck 0x570C84 +#define HOOKPOS_OccupiedVehicleBurnCheck 0x570C84 DWORD RETURN_OccupiedVehicleBurnCheck = 0x570C8A; -#define HOOKPOS_UnoccupiedVehicleBurnCheck 0x6A76DC +#define HOOKPOS_UnoccupiedVehicleBurnCheck 0x6A76DC DWORD RETURN_UnoccupiedVehicleBurnCheck = 0x6A76E4; -#define HOOKPOS_ApplyCarBlowHop 0x6B3816 +#define HOOKPOS_ApplyCarBlowHop 0x6B3816 DWORD RETURN_ApplyCarBlowHop = 0x6B3831; -#define HOOKPOS_CVehicle_ApplyBoatWaterResistance 0x6D2771 +#define HOOKPOS_CVehicle_ApplyBoatWaterResistance 0x6D2771 DWORD RETURN_CVehicle_ApplyBoatWaterResistance = 0x6D2777; -#define HOOKPOS_CPhysical_ApplyGravity 0x543081 +#define HOOKPOS_CPhysical_ApplyGravity 0x543081 DWORD RETURN_CPhysical_ApplyGravity = 0x543093; -#define HOOKPOS_CWorld_SetWorldOnFire 0x56B983 +#define HOOKPOS_CWorld_SetWorldOnFire 0x56B983 DWORD RETURN_CWorld_SetWorldOnFire = 0x56B989; -#define HOOKPOS_CTaskSimplePlayerOnFire_ProcessPed 0x6336DA +#define HOOKPOS_CTaskSimplePlayerOnFire_ProcessPed 0x6336DA DWORD RETURN_CTaskSimplePlayerOnFire_ProcessPed = 0x6336E0; -#define HOOKPOS_CFire_ProcessFire 0x53AC1A +#define HOOKPOS_CFire_ProcessFire 0x53AC1A DWORD RETURN_CFire_ProcessFire = 0x53AC1F; -#define HOOKPOS_CExplosion_Update 0x7377D3 +#define HOOKPOS_CExplosion_Update 0x7377D3 DWORD RETURN_CExplosion_Update = 0x7377D8; -#define HOOKPOS_CWeapon_FireAreaEffect 0x73EBFE +#define HOOKPOS_CWeapon_FireAreaEffect 0x73EBFE DWORD RETURN_CWeapon_FireAreaEffect = 0x73EC03; -#define CALL_RenderScene_Plants 0x53E103 -#define HOOKPOS_RenderScene_end 0x53E159 -#define HOOKPOS_CPlantMgr_Render 0x5DBC4C +#define CALL_RenderScene_Plants 0x53E103 +#define HOOKPOS_RenderScene_end 0x53E159 +#define HOOKPOS_CPlantMgr_Render 0x5DBC4C DWORD RETURN_CPlantMgr_Render_success = 0x5DBC52; -DWORD RETURN_CPlantMgr_Render_fail = 0x5DBDAA; -#define HOOKPOS_CEventHandler_ComputeKnockOffBikeResponse 0x4BA06F +#define HOOKPOS_CEventHandler_ComputeKnockOffBikeResponse 0x4BA06F DWORD RETURN_CEventHandler_ComputeKnockOffBikeResponse = 0x4BA076; -#define HOOKPOS_CAnimBlendAssociation_SetCurrentTime 0x4CEA80 -#define HOOKPOS_RpAnimBlendClumpUpdateAnimations 0x4D34F0 -#define HOOKPOS_CAnimBlendAssoc_destructor 0x4CECF0 -#define HOOKPOS_CAnimBlendAssocGroupCopyAnimation 0x4CE130 -#define HOOKPOS_CAnimManager_AddAnimation 0x4d3aa0 -#define HOOKPOS_CAnimManager_AddAnimationAndSync 0x4D3B30 -#define HOOKPOS_CAnimManager_BlendAnimation_Hierarchy 0x4D453E +#define HOOKPOS_CAnimBlendAssocGroupCopyAnimation 0x4CE130 -#define HOOKPOS_CPed_GetWeaponSkill 0x5e3b60 +#define HOOKPOS_CPed_GetWeaponSkill 0x5e3b60 DWORD RETURN_CPed_GetWeaponSkill = 0x5E3B68; -#define HOOKPOS_CPed_AddGogglesModel 0x5E3ACB +#define HOOKPOS_CPed_AddGogglesModel 0x5E3ACB DWORD RETURN_CPed_AddGogglesModel = 0x5E3AD4; -#define FUNC_CWorld_Remove 0x563280 -#define FUNC_CTagManager_ShutdownForRestart 0x49CC60 +#define FUNC_CWorld_Remove 0x563280 +#define FUNC_CTagManager_ShutdownForRestart 0x49CC60 unsigned int* VAR_NumTags = (unsigned int*)0xA9AD70; DWORD** VAR_TagInfoArray = (DWORD**)0xA9A8C0; -#define HOOKPOS_CPhysical_ProcessCollisionSectorList 0x54BB93 +#define HOOKPOS_CPhysical_ProcessCollisionSectorList 0x54BB93 DWORD RETURN_CPhysical_ProcessCollisionSectorList = 0x54BB9A; -#define HOOKPOS_CheckAnimMatrix 0x7C5A5C +#define HOOKPOS_CheckAnimMatrix 0x7C5A5C DWORD RETURN_CheckAnimMatrix = 0x7C5A61; -#define HOOKPOS_VehColCB 0x04C838D +#define HOOKPOS_VehColCB 0x04C838D DWORD RETURN_VehColCB = 0x04C83AA; -#define HOOKPOS_VehCol 0x06D6603 +#define HOOKPOS_VehCol 0x06D6603 DWORD RETURN_VehCol = 0x06D660C; #define HOOKPOS_Transmission_CalculateDriveAcceleration 0x6D05E0 DWORD RETURN_Transmission_CalculateDriveAcceleration = 0x6D05E6; // Handling fix - driveType is per model -#define HOOKPOS_CHandlingData_isNotRWD 0x6A048C +#define HOOKPOS_CHandlingData_isNotRWD 0x6A048C DWORD RETURN_CHandlingData_isNotRWD = 0x6A0493; -#define HOOKPOS_CHandlingData_isNotFWD 0x6A04BC +#define HOOKPOS_CHandlingData_isNotFWD 0x6A04BC DWORD RETURN_CHandlingData_isNotFWD = 0x6A04C3; // end of handling fix -#define CALL_CAutomobile_ProcessEntityCollision 0x6AD053 -#define CALL_CMonsterTruck_ProcessEntityCollision 0x6C8B9E +#define CALL_CAutomobile_ProcessEntityCollision 0x6AD053 +#define CALL_CMonsterTruck_ProcessEntityCollision 0x6C8B9E DWORD RETURN_ProcessEntityCollision = 0x4185C0; -#define HOOKPOS_PreFxRender 0x049E650 +#define HOOKPOS_PreFxRender 0x049E650 DWORD RETURN_PreFxRender = 0x0404D1E; -#define HOOKPOS_PostColorFilterRender 0x705099 +#define HOOKPOS_PostColorFilterRender 0x705099 DWORD RETURN_PostColorFilterRender = 0x70509E; -#define HOOKPOS_PreHUDRender 0x053EAD8 +#define HOOKPOS_PreHUDRender 0x053EAD8 DWORD RETURN_PreHUDRender = 0x053EADD; -#define HOOKPOS_LoadIPLInstance 0x4061E8 +#define HOOKPOS_LoadIPLInstance 0x4061E8 DWORD CALL_LoadIPLInstance = 0x538090; DWORD RETURN_LoadIPLInstance = 0x04061ED; -#define HOOKPOS_CWorld_LOD_SETUP 0x406224 -#define HOOKPOS_CWorld_LOD_SETUP2 0x406326 +#define HOOKPOS_CWorld_LOD_SETUP 0x406224 +#define HOOKPOS_CWorld_LOD_SETUP2 0x406326 DWORD CALL_CWorld_LODSETUP = 0x404C90; -#define HOOKPOS_CBuilding_DTR 0x404180 +#define HOOKPOS_CBuilding_DTR 0x404180 DWORD JMP_CBuilding_DTR = 0x535E90; -#define HOOKPOS_CDummy_DTR 0x532566 +#define HOOKPOS_CDummy_DTR 0x532566 DWORD JMP_CDummy_DTR = 0x535E90; -#define HOOKPOS_CObject_DTR 0x59F680 +#define HOOKPOS_CObject_DTR 0x59F680 DWORD JMP_CObject_DTR = 0x59F686; -#define HOOKPOS_AddBuildingInstancesToWorld_CWorldAdd 0x5B5348 +#define HOOKPOS_AddBuildingInstancesToWorld_CWorldAdd 0x5B5348 DWORD JMP_CWorld_Add_AddBuildingInstancesToWorld_CALL_CWorldAdd = 0x563220; DWORD RETURN_AddBuildingInstancesToWorld_CWorldAdd = 0x5B534D; -#define HOOKPOS_CWorld_Remove_CPopulation_ConvertToDummyObject 0x6146F8 +#define HOOKPOS_CWorld_Remove_CPopulation_ConvertToDummyObject 0x6146F8 -#define HOOKPOS_CWorld_ADD_CPopulation_ConvertToRealObject 0x6145C7 +#define HOOKPOS_CWorld_ADD_CPopulation_ConvertToRealObject 0x6145C7 DWORD JMP_CWorld_Add_CPopulation_ConvertToRealObject_Retn = 0x6145CC; DWORD JMP_CWorld_Add_CPopulation_ConvertToRealObject_CallCWorldAdd = 0x563220; -#define HOOKPOS_ConvertToObject_CPopulationManageDummy 0x616091 +#define HOOKPOS_ConvertToObject_CPopulationManageDummy 0x616091 DWORD CALL_Convert_To_Real_Object_CPopulation_ManageDummy = 0x614580; DWORD JMP_RETN_Called_CPopulation_ManageDummy = 0x616097; DWORD JMP_RETN_Cancel_CPopulation_ManageDummy = 0x616098; -#define HOOKPOS_CWorld_ADD_CPopulation_ConvertToDummyObject 0x61470C +#define HOOKPOS_CWorld_ADD_CPopulation_ConvertToDummyObject 0x61470C DWORD CALL_CWorld_Add_CPopulation_ConvertToDummyObject = 0x563220; DWORD JMP_RETN_Called_CPopulation_ConvertToDummyObject = 0x614712; DWORD JMP_RETN_Cancelled_CPopulation_ConvertToDummyObject = 0x614715; -#define HOOKPOS_CEntity_IsOnScreen_FixObjectsScale 0x534575 +#define HOOKPOS_CEntity_IsOnScreen_FixObjectsScale 0x534575 DWORD JMP_CEntity_IsOnScreen_FixObjectsScale = 0x53457C; -#define HOOKPOS_CClothes_RebuildPlayer 0x5A82C0 +#define HOOKPOS_CClothes_RebuildPlayer 0x5A82C0 DWORD RETURN_CClothes_RebuildPlayera = 0x5A82C8; DWORD RETURN_CClothes_RebuildPlayerb = 0x5A837F; -#define HOOKPOS_CProjectileInfo_FindPlayerPed 0x739321 -#define HOOKPOS_CProjectileInfo_FindPlayerVehicle 0x739570 +#define HOOKPOS_CProjectileInfo_FindPlayerPed 0x739321 +#define HOOKPOS_CProjectileInfo_FindPlayerVehicle 0x739570 -#define HOOKPOS_CHeli_ProcessHeliKill 0x6DB201 +#define HOOKPOS_CHeli_ProcessHeliKill 0x6DB201 DWORD RETURN_CHeli_ProcessHeliKill_RETN_Cancel = 0x6DB9E0; DWORD RETURN_CHeli_ProcessHeliKill_RETN_Cont_Zero = 0x6DB207; DWORD RETURN_CHeli_ProcessHeliKill_6DB437h = 0x6DB437; -#define HOOKPOS_CObject_ProcessBreak 0x5A0F0F +#define HOOKPOS_CObject_ProcessBreak 0x5A0F0F DWORD RETURN_CObject_ProcessBreak = 0x5A0F14; -#define HOOKPOS_CObject_ProcessDamage 0x5A0E0D +#define HOOKPOS_CObject_ProcessDamage 0x5A0E0D DWORD RETURN_CObject_ProcessDamage = 0x5A0E13; DWORD RETURN_CObject_ProcessDamage_Cancel = 0x5A1241; -#define HOOKPOS_CObject_ProcessCollision 0x548DC7 +#define HOOKPOS_CObject_ProcessCollision 0x548DC7 DWORD RETURN_CObject_ProcessCollision = 0x548DD1; DWORD JMP_DynamicObject_Cond_Zero = 0x548E98; -#define HOOKPOS_CGlass_WindowRespondsToCollision 0x71BC40 +#define HOOKPOS_CGlass_WindowRespondsToCollision 0x71BC40 DWORD RETURN_CGlass_WindowRespondsToCollision = 0x71BC48; -#define HOOKPOS_CGlass__BreakGlassPhysically 0x71D14B +#define HOOKPOS_CGlass__BreakGlassPhysically 0x71D14B DWORD RETURN_CGlass__BreakGlassPhysically = 0x71D150; -#define HOOKPOS_CGlass_WindowRespondsToExplosion 0x71C255 -DWORD RETURN_CGlass_WindowRespondsToExplosion = 0x71C25A; +#define HOOKPOS_CGlass_WindowRespondsToExplosion 0x71C255 +DWORD RETURN_CGlass_WindowRespondsToExplosion = 0x71C25A; constexpr const DWORD CALL_FROM_CGlass_WindowRespondsToExplosion = 0x71C28E; constexpr const DWORD CALL_FROM_CGlass_WasGlassHitByBullet = 0x71C192; constexpr const DWORD CALL_FROM_CPhysical_ApplyCollision = 0x548F39; constexpr const DWORD CALL_FROM_CPhysical_ApplyCollision_2 = 0x5490AE; constexpr const DWORD CALL_FROM_CPhysical_ApplySoftCollision = 0x54A816; -#define HOOKPOS_FxManager_c__DestroyFxSystem 0x4A989A +#define HOOKPOS_FxManager_c__DestroyFxSystem 0x4A989A -#define HOOKPOS_CTaskSimplyGangDriveBy__ProcessPed 0x62D5A7 +#define HOOKPOS_CTaskSimplyGangDriveBy__ProcessPed 0x62D5A7 DWORD RETURN_CTaskSimplyGangDriveBy__ProcessPed = 0x62D5AC; #define HOOKPOS_CAERadioTrackManager__ChooseMusicTrackIndex 0x4EA296 DWORD RETURN_CAERadioTrackManager__ChooseMusicTrackIndex = 0x4EA2A0; DWORD RETURN_CAERadioTrackManager__ChooseMusicTrackIndex_Regenerate = 0x04EA286; -#define HOOKPOS_CAEVEhicleAudioEntity__ProcessDummyHeli 0x4FE9B9 +#define HOOKPOS_CAEVEhicleAudioEntity__ProcessDummyHeli 0x4FE9B9 DWORD RETURN_CAEVEhicleAudioEntity__ProcessDummyHeli = 0x4FEDFB; DWORD dwFUNC_CAEVehicleAudioEntity__ProcessAIHeli = FUNC_CAEVehicleAudioEntity__ProcessAIHeli; -#define HOOKPOS_CAEVEhicleAudioEntity__ProcessDummyProp 0x4FD96D +#define HOOKPOS_CAEVEhicleAudioEntity__ProcessDummyProp 0x4FD96D DWORD RETURN_CAEVEhicleAudioEntity__ProcessDummyProp = 0x4FDFAB; DWORD dwFUNC_CAEVehicleAudioEntity__ProcessAIProp = FUNC_CAEVehicleAudioEntity__ProcessAIProp; -#define HOOKPOS_CTaskSimpleSwim_ProcessSwimmingResistance 0x68A4EF +#define HOOKPOS_CTaskSimpleSwim_ProcessSwimmingResistance 0x68A4EF DWORD RETURN_CTaskSimpleSwim_ProcessSwimmingResistance = 0x68A50E; const DWORD HOOKPOS_Idle_CWorld_ProcessPedsAfterPreRender = 0x53EA03; const DWORD RETURN_Idle_CWorld_ProcessPedsAfterPreRender = 0x53EA08; -#define HOOKPOS_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_StartRadio 0x4D7198 -#define HOOKPOS_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_StopRadio 0x4D71E7 +#define HOOKPOS_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_StartRadio 0x4D7198 +#define HOOKPOS_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_StopRadio 0x4D71E7 #define HOOKPOS_CAutomobile__dmgDrawCarCollidingParticles 0x6A6FF0 @@ -325,13 +332,13 @@ bool bTrafficLightsBlocked = false; bool bInteriorSoundsEnabled = true; bool bInteriorFurnitureStates[5] = {true, true, true, true, true}; -bool bUsingCustomSkyGradient = false; -BYTE ucSkyGradientTopR = 0; -BYTE ucSkyGradientTopG = 0; -BYTE ucSkyGradientTopB = 0; -BYTE ucSkyGradientBottomR = 0; -BYTE ucSkyGradientBottomG = 0; -BYTE ucSkyGradientBottomB = 0; +bool bUsingCustomSkyGradient = false; +BYTE ucSkyGradientTopR = 0; +BYTE ucSkyGradientTopG = 0; +BYTE ucSkyGradientTopB = 0; +BYTE ucSkyGradientBottomR = 0; +BYTE ucSkyGradientBottomG = 0; +BYTE ucSkyGradientBottomB = 0; bool bUsingCustomAmbientColor = false; float fAmbientColorR = 0.0F; @@ -370,22 +377,22 @@ extern bool bWeaponFire; float fDuckingHealthThreshold; static const std::array shadowAddr{ - 0x6FAD5D, // CRegisteredCorona::Update - 0x7041DB, // CPostEffects::Fog - 0x7085A9, // CShadows::RenderStaticShadows - 0x709B2F, // CShadows::CastShadowEntityXY - 0x709B8E, // CShadows::CastShadowEntityXY - 0x709BC7, // CShadows::CastShadowEntityXY - 0x709BF6, // CShadows::CastShadowEntityXY - 0x709C93, // CShadows::CastShadowEntityXY - 0x709E9E, // IntersectEntityRenderTriangleCB - 0x709EBC, // IntersectEntityRenderTriangleCB - 0x709ED7, // IntersectEntityRenderTriangleCB - 0x70B221, // CShadows::RenderStoredShadows - 0x70B373, // CShadows::RenderStoredShadows - 0x70B4D1, // CShadows::RenderStoredShadows - 0x70B635, // CShadows::RenderStoredShadows - 0x73A48F // CWeapon::AddGunshell + 0x6FAD5D, // CRegisteredCorona::Update + 0x7041DB, // CPostEffects::Fog + 0x7085A9, // CShadows::RenderStaticShadows + 0x709B2F, // CShadows::CastShadowEntityXY + 0x709B8E, // CShadows::CastShadowEntityXY + 0x709BC7, // CShadows::CastShadowEntityXY + 0x709BF6, // CShadows::CastShadowEntityXY + 0x709C93, // CShadows::CastShadowEntityXY + 0x709E9E, // IntersectEntityRenderTriangleCB + 0x709EBC, // IntersectEntityRenderTriangleCB + 0x709ED7, // IntersectEntityRenderTriangleCB + 0x70B221, // CShadows::RenderStoredShadows + 0x70B373, // CShadows::RenderStoredShadows + 0x70B4D1, // CShadows::RenderStoredShadows + 0x70B635, // CShadows::RenderStoredShadows + 0x73A48F // CWeapon::AddGunshell }; PreContextSwitchHandler* m_pPreContextSwitchHandler = NULL; @@ -421,7 +428,7 @@ DrivebyAnimationHandler* m_pDrivebyAnimationHandler = NULL; AudioZoneRadioSwitchHandler* m_pAudioZoneRadioSwitchHandler = NULL; CEntitySAInterface* dwSavedPlayerPointer = 0; -CEntitySAInterface* activeEntityForStreaming = 0; // the entity that the streaming system considers active +CEntitySAInterface* activeEntityForStreaming = 0; // the entity that the streaming system considers active void HOOK_FindPlayerCoors(); void HOOK_FindPlayerCentreOfWorld(); @@ -431,6 +438,8 @@ void HOOK_CHud_Draw_Caller(); void HOOK_CRunningScript_Process(); void HOOK_CExplosion_AddExplosion(); void HOOK_CCustomRoadsignMgr__RenderRoadsignAtomic(); +void HOOK_CEntity__CreateEffects_RoadsignAtomic(); +void HOOK_RoadsignGenerateTextRaster(); void HOOK_Trailer_BreakTowLink(); void HOOK_CRadar__DrawRadarGangOverlay(); void HOOK_CTaskComplexJump__CreateSubTask(); @@ -473,18 +482,11 @@ void HOOK_RenderScene_Plants(); void HOOK_RenderScene_end(); void HOOK_CPlantMgr_Render(); void HOOK_CEventHandler_ComputeKnockOffBikeResponse(); -void HOOK_CAnimBlendAssociation_SetCurrentTime(); -void HOOK_RpAnimBlendClumpUpdateAnimations(); -void HOOK_CAnimBlendAssoc_destructor(); -void HOOK_CAnimManager_AddAnimation(); -void HOOK_CAnimManager_AddAnimationAndSync(); -void HOOK_CAnimManager_BlendAnimation_Hierarchy(); void HOOK_CPed_GetWeaponSkill(); void HOOK_CPed_AddGogglesModel(); void HOOK_CPhysical_ProcessCollisionSectorList(); void HOOK_CrashFix_Misc1(); void HOOK_CrashFix_Misc2(); -void HOOK_CrashFix_Misc3(); void HOOK_CrashFix_Misc4(); void HOOK_CrashFix_Misc5(); void HOOK_CrashFix_Misc6(); @@ -596,7 +598,7 @@ CMultiplayerSA::CMultiplayerSA() m_pProjectileStopHandler = NULL; MemSetFast(&localStatsData, 0, sizeof(CStatsData)); - localStatsData.StatTypesFloat[24] = 569.0f; // Max Health + localStatsData.StatTypesFloat[24] = 569.0f; // Max Health m_fAircraftMaxHeight = 800.0f; @@ -610,6 +612,13 @@ CMultiplayerSA::CMultiplayerSA() m_dwLastStaticAnimID = eAnimID::ANIM_ID_WALK; } +CMultiplayerSA::~CMultiplayerSA() +{ + // Cleanup hooks that require explicit resource deallocation + // This is to prevent resource leaks + CleanupHooks_HookDestructors(); +} + void CMultiplayerSA::InitHooks() { InitKeysyncHooks(); @@ -642,6 +651,8 @@ void CMultiplayerSA::InitHooks() HookInstall(HOOKPOS_CRunningScript_Process, (DWORD)HOOK_CRunningScript_Process, 6); HookInstall(HOOKPOS_CExplosion_AddExplosion, (DWORD)HOOK_CExplosion_AddExplosion, 6); HookInstall(HOOKPOS_CCustomRoadsignMgr__RenderRoadsignAtomic, (DWORD)HOOK_CCustomRoadsignMgr__RenderRoadsignAtomic, 6); + HookInstall(HOOKPOS_CEntity__CreateEffects_RoadsignAtomic, (DWORD)HOOK_CEntity__CreateEffects_RoadsignAtomic, 5); + HookInstall(HOOKPOS_RoadsignGenerateTextRaster, (DWORD)HOOK_RoadsignGenerateTextRaster, 5); HookInstall(HOOKPOS_Trailer_BreakTowLink, (DWORD)HOOK_Trailer_BreakTowLink, 6); HookInstall(HOOKPOS_CRadar__DrawRadarGangOverlay, (DWORD)HOOK_CRadar__DrawRadarGangOverlay, 6); HookInstall(HOOKPOS_CTaskComplexJump__CreateSubTask, (DWORD)HOOK_CTaskComplexJump__CreateSubTask, 6); @@ -679,15 +690,11 @@ void CMultiplayerSA::InitHooks() HookInstall(HOOKPOS_CGame_Process, (DWORD)HOOK_CGame_Process, 10); HookInstall(HOOKPOS_Idle, (DWORD)HOOK_Idle, 10); HookInstall(HOOKPOS_CEventHandler_ComputeKnockOffBikeResponse, (DWORD)HOOK_CEventHandler_ComputeKnockOffBikeResponse, 7); - HookInstall(HOOKPOS_CAnimBlendAssociation_SetCurrentTime, (DWORD)HOOK_CAnimBlendAssociation_SetCurrentTime, 8); - HookInstall(HOOKPOS_RpAnimBlendClumpUpdateAnimations, (DWORD)HOOK_RpAnimBlendClumpUpdateAnimations, 8); - HookInstall(HOOKPOS_CAnimBlendAssoc_destructor, (DWORD)HOOK_CAnimBlendAssoc_destructor, 6); HookInstall(HOOKPOS_CPed_GetWeaponSkill, (DWORD)HOOK_CPed_GetWeaponSkill, 8); HookInstall(HOOKPOS_CPed_AddGogglesModel, (DWORD)HOOK_CPed_AddGogglesModel, 6); HookInstall(HOOKPOS_CPhysical_ProcessCollisionSectorList, (DWORD)HOOK_CPhysical_ProcessCollisionSectorList, 7); HookInstall(HOOKPOS_CheckAnimMatrix, (DWORD)HOOK_CheckAnimMatrix, 5); - HookInstall(HOOKPOS_VehColCB, (DWORD)HOOK_VehColCB, 29); HookInstall(HOOKPOS_VehCol, (DWORD)HOOK_VehCol, 9); HookInstall(HOOKPOS_PreFxRender, (DWORD)HOOK_PreFxRender, 5); @@ -750,7 +757,7 @@ void CMultiplayerSA::InitHooks() HookInstall(HOOKPOS_CObject_ProcessCollision, (DWORD)HOOK_CObject_ProcessCollision, 10); HookInstall(HOOKPOS_CGlass_WindowRespondsToCollision, (DWORD)HOOK_CGlass_WindowRespondsToCollision, 8); HookInstall(HOOKPOS_CGlass__BreakGlassPhysically, (DWORD)HOOK_CGlass__BreakGlassPhysically, 5); - + // Post-destruction hook for FxSystems HookInstall(HOOKPOS_FxManager_c__DestroyFxSystem, (DWORD)HOOK_FxManager_c__DestroyFxSystem, 5); @@ -771,10 +778,6 @@ void CMultiplayerSA::InitHooks() HookInstall(HOOKPOS_CTaskSimpleSwim_ProcessSwimmingResistance, (DWORD)HOOK_CTaskSimpleSwim_ProcessSwimmingResistance, 6); HookInstall(HOOKPOS_Idle_CWorld_ProcessPedsAfterPreRender, (DWORD)HOOK_Idle_CWorld_ProcessPedsAfterPreRender, 5); - HookInstall(HOOKPOS_CAnimManager_AddAnimation, (DWORD)HOOK_CAnimManager_AddAnimation, 10); - HookInstall(HOOKPOS_CAnimManager_AddAnimationAndSync, (DWORD)HOOK_CAnimManager_AddAnimationAndSync, 10); - HookInstall(HOOKPOS_CAnimManager_BlendAnimation_Hierarchy, (DWORD)HOOK_CAnimManager_BlendAnimation_Hierarchy, 5); - HookInstall(HOOKPOS_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_StartRadio, (DWORD)HOOK_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_StartRadio, 5); HookInstall(HOOKPOS_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_StopRadio, @@ -852,6 +855,12 @@ void CMultiplayerSA::InitHooks() // MemSet ( (void*)0x408A1B, 0x90, 5 ); + // CTxdStore::GetNumRefs freed-slot error path does xor eax,eax then movsx eax,[eax+4] + // which is a null-deref (reads address 0x4). In SA its dead code, but MTA can reach it + // when a stale streaming entry references a freed TXD pool slot. NOP the movsx so + // freed slots return 0 refs instead of crashing. + MemSet((void*)0x731AB5, 0x90, 4); + // Hack to make the choke task use 0 time left remaining when he starts t // just stand there looking. So he won't do that. MemPut(0x620607, 0x33); @@ -979,11 +988,11 @@ void CMultiplayerSA::InitHooks() MemSet((LPVOID)0x6B5B17, 0x90, 6); // Increase VehicleStruct pool size - MemPut(0x5B8342 + 0, 0x33); // xor eax, eax + MemPut(0x5B8342 + 0, 0x33); // xor eax, eax MemPut(0x5B8342 + 1, 0xC0); - MemPut(0x5B8342 + 2, 0xB0); // mov al, 0xFF + MemPut(0x5B8342 + 2, 0xB0); // mov al, 0xFF MemPut(0x5B8342 + 3, 0xFF); - MemPut(0x5B8342 + 4, 0x8B); // mov edi, eax + MemPut(0x5B8342 + 4, 0x8B); // mov edi, eax MemPut(0x5B8342 + 5, 0xF8); /* @@ -1042,8 +1051,8 @@ void CMultiplayerSA::InitHooks() MemPut(0x44C39A + 4, 0x00); MemPut(0x44C39A + 5, 0x00); - // Avoid garage doors closing when you change your model - MemSet((LPVOID)0x4486F7, 0x90, 4); + // Disable CGarages::PlayerArrestedOrDied to stop the game from automatically closing/opening garages + MemSet((void*)0x442303, 0x90, 5); // Disable CStats::IncrementStat (returns at start of function) MemPut(0x55C180, 0xC3); @@ -1105,7 +1114,7 @@ void CMultiplayerSA::InitHooks() // Prevent TRAINS spawning with PEDs MemPut(0x6F7865, 0xEB); MemPut(0x6F8E7B, 0xE9); - MemPut(0x6F8E7C, 0x109); // jmp to 0x6F8F89 + MemPut(0x6F8E7C, 0x109); // jmp to 0x6F8F89 MemPut(0x6F8E80, 0x90); // DISABLE PLANES @@ -1312,8 +1321,8 @@ void CMultiplayerSA::InitHooks() MemPut(0x748B0E, 5); // Skip copyright screen - MemSet((void*)0x748C2B, 0x90, 5); // call CLoadingScreen::DoPCTitleFadeIn - MemSet((void*)0x748C9A, 0x90, 5); // call CLoadingScreen::DoPCTitleFadeOut + MemSet((void*)0x748C2B, 0x90, 5); // call CLoadingScreen::DoPCTitleFadeIn + MemSet((void*)0x748C9A, 0x90, 5); // call CLoadingScreen::DoPCTitleFadeOut // Force triggering of the damage event for players on fire MemSet((void*)0x633695, 0x90, 6); @@ -1390,7 +1399,7 @@ void CMultiplayerSA::InitHooks() // Disable the loading screen tune. MemSet((void*)0x748CF6, 0x90, 5); - + // Do not render the loading screen. MemSet((void*)0x590D7C, 0x90, 5); MemSet((void*)0x590DB3, 0x90, 5); @@ -1514,8 +1523,8 @@ void CMultiplayerSA::InitHooks() MemSetFast((void*)0x60D861, 0x90, 14); // Allow water cannon to hit objects and players visually - MemSet((void*)0x72925D, 0x1, 1); // objects - MemSet((void*)0x729263, 0x1, 1); // players + MemSet((void*)0x72925D, 0x1, 1); // objects + MemSet((void*)0x729263, 0x1, 1); // players // Allow crouching with 1HP MemPut((void*)0x6943AD, &fDuckingHealthThreshold); @@ -1576,12 +1585,33 @@ void CMultiplayerSA::InitHooks() // Allow alpha change for helicopter rotor (#523) MemSet((void*)0x6C444B, 0x90, 6); MemSet((void*)0x6C4453, 0x90, 0x68); - + + // Allow model ID 432 (Rhino) to render headlight cones and coronas + MemSet((void*)0x6A2EAB, 0x90, 6); + MemSet((void*)0x6ABC81, 0x90, 6); + + // Disable Z position changes in the matrix in the C3dMarkers::PlaceMarker (#4000, #536) + // To prevent arrow-type markers from snapping to the ground + MemCpy((void*)0x725844, "\xDD\xD8\x90", 3); + MemCpy((void*)0x725619, "\xDD\xD8\x90", 3); + MemCpy((void*)0x72565A, "\xDD\xD8\x90", 3); + MemCpy((void*)0x7259B0, "\xDD\xD8\x90", 3); + MemSet((void*)0x7258B8, 0x90, 6); + + // Disable spreading fires (Moved from multiplayer_shotsync) + MemCpy((void*)0x53A23F, "\x33\xC0\x90\x90\x90", 5); + MemCpy((void*)0x53A00A, "\x33\xC0\x90\x90\x90", 5); + + // Fix objects with alpha below 141 are invisible (#425) + MemPut(0x553AD9, 0); + MemPut(0x732C2F, 0); + InitHooks_CrashFixHacks(); InitHooks_DeviceSelection(); // Init our 1.3 hooks. Init_13(); + InitHooks_CustomAnimations(); InitHooks_LicensePlate(); InitHooks_Direct3D(); InitHooks_FixLineOfSightArgs(); @@ -1693,14 +1723,14 @@ void CMultiplayerSA::DisablePadHandler(bool bDisabled) void CMultiplayerSA::GetHeatHaze(SHeatHazeSettings& settings) { - settings.ucIntensity = *(int*)0x8D50E8; - settings.ucRandomShift = *(int*)0xC402C0; - settings.usSpeedMin = *(int*)0x8D50EC; - settings.usSpeedMax = *(int*)0x8D50F0; - settings.sScanSizeX = *(int*)0xC40304; - settings.sScanSizeY = *(int*)0xC40308; - settings.usRenderSizeX = *(int*)0xC4030C; - settings.usRenderSizeY = *(int*)0xC40310; + settings.ucIntensity = *(uchar*)0x8D50E8; + settings.ucRandomShift = *(uchar*)0xC402C0; + settings.usSpeedMin = *(ushort*)0x8D50EC; + settings.usSpeedMax = *(ushort*)0x8D50F0; + settings.sScanSizeX = *(short*)0xC40304; + settings.sScanSizeY = *(short*)0xC40308; + settings.usRenderSizeX = *(ushort*)0xC4030C; + settings.usRenderSizeY = *(ushort*)0xC40310; settings.bInsideBuilding = *(bool*)0xC402BA; } @@ -1708,8 +1738,8 @@ void CMultiplayerSA::ResetColorFilter() { if (*(BYTE*)0x7036EC == 0xB8) { - static BYTE DefaultBytes[5] = {0xC1, 0xE0, 0x08, 0x0B, 0xC1}; // shl eax, 8 - // or eax, ecx + static BYTE DefaultBytes[5] = {0xC1, 0xE0, 0x08, 0x0B, 0xC1}; // shl eax, 8 + // or eax, ecx MemCpy((void*)0x7036EC, DefaultBytes, sizeof(DefaultBytes)); MemCpy((void*)0x70373D, DefaultBytes, sizeof(DefaultBytes)); } @@ -1722,14 +1752,14 @@ void CMultiplayerSA::SetColorFilter(DWORD dwPass0Color, DWORD dwPass1Color) // Update a pass0 color if needed if (!bEnabled || *(DWORD*)0x7036ED != dwPass0Color) { - MemPut(0x7036EC, 0xB8); // mov eax + MemPut(0x7036EC, 0xB8); // mov eax MemPut(0x7036ED, dwPass0Color); } // Update a pass1 color if needed if (!bEnabled || *(DWORD*)0x70373E != dwPass1Color) { - MemPut(0x70373D, 0xB8); // mov eax + MemPut(0x70373D, 0xB8); // mov eax MemPut(0x70373E, dwPass1Color); } } @@ -1738,7 +1768,8 @@ void CMultiplayerSA::GetColorFilter(DWORD& dwPass0Color, DWORD& dwPass1Color, bo { // GTASA PC has 2 color filters, one of them is static color filter, and another one is blended by time cycle bool bUseTimeCycle = *(BYTE*)0x7036EC == 0xC1; - if (bUseTimeCycle || isOriginal){ //If we are using color filter from time cycle or we specified color filter from time cycle + if (bUseTimeCycle || isOriginal) + { // If we are using color filter from time cycle or we specified color filter from time cycle SColorRGBA pass0SColor(*(float*)0xB7C518, *(float*)0xB7C51C, *(float*)0xB7C520, *(float*)0xB7C524); SColorRGBA pass1SColor(*(float*)0xB7C528, *(float*)0xB7C52C, *(float*)0xB7C530, *(float*)0xB7C534); dwPass0Color = pass0SColor.ulARGB; @@ -1771,17 +1802,17 @@ void DoSetHeatHazePokes(const SHeatHazeSettings& settings, int iHourStart, int i MemPutFast(0xC402BA, settings.bInsideBuilding); if (bAllowAutoTypeChange) - MemPut(0x701455, 0x83); // sub + MemPut(0x701455, 0x83); // sub else - MemPut(0x701455, 0xC3); // retn + MemPut(0x701455, 0xC3); // retn } void CMultiplayerSA::SetHeatHaze(const SHeatHazeSettings& settings) { if (settings.ucIntensity != 0) - DoSetHeatHazePokes(settings, 0, 24, 1.0f, 1.0f, false); // 24 hrs + DoSetHeatHazePokes(settings, 0, 24, 1.0f, 1.0f, false); // 24 hrs else - DoSetHeatHazePokes(settings, 38, 39, 1.0f, 1.0f, false); // 0 hrs + DoSetHeatHazePokes(settings, 38, 39, 1.0f, 1.0f, false); // 0 hrs m_bHeatHazeCustomized = true; ApplyHeatHazeEnabled(); @@ -1800,7 +1831,7 @@ void CMultiplayerSA::ResetHeatHaze() settings.usRenderSizeY = 0x55; settings.bInsideBuilding = false; - DoSetHeatHazePokes(settings, 10, 19, 0.05f, 1.0f, true); // defaults + DoSetHeatHazePokes(settings, 10, 19, 0.05f, 1.0f, true); // defaults m_bHeatHazeCustomized = false; ApplyHeatHazeEnabled(); @@ -2218,7 +2249,7 @@ void CMultiplayerSA::ResetSky() void CMultiplayerSA::SetMoonSize(int iSize) { - MemPutFast(0x8D4B60, iSize); + MemPutFast(0x8D4B60, static_cast(iSize)); } int CMultiplayerSA::GetMoonSize() @@ -2797,9 +2828,12 @@ void CMultiplayerSA::SetCenterOfWorld(CEntity* entity, CVector* vecPosition, FLO } } -void _declspec(naked) HOOK_FindPlayerCoors() +static void __declspec(naked) HOOK_FindPlayerCoors() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Only set our world of center if we have a center of world set push eax @@ -2831,20 +2865,25 @@ void _declspec(naked) HOOK_FindPlayerCoors() add ecx, 6 jmp ecx } + // clang-format on } -void _declspec(naked) HOOK_CStreaming_Update_Caller() +static void __declspec(naked) HOOK_CStreaming_Update_Caller() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + /* 0053BF09 8BF8 MOV EDI,EAX 0053BF0B E8 6027EDFF CALL gta_sa.0040E670 */ - _asm + // clang-format off + __asm { // Store all registers pushad } + // clang-format on // We're now in the streaming update bInStreamingUpdate = true; @@ -2853,7 +2892,8 @@ void _declspec(naked) HOOK_CStreaming_Update_Caller() if (activeEntityForStreaming) { // Do something... - _asm + // clang-format off + __asm { mov edi, FUNC_CPlayerInfoBase mov ebx, [edi] @@ -2861,9 +2901,11 @@ void _declspec(naked) HOOK_CStreaming_Update_Caller() mov ebx, activeEntityForStreaming mov [edi], ebx } + // clang-format on } - _asm + // clang-format off + __asm { mov edi, eax @@ -2871,22 +2913,26 @@ void _declspec(naked) HOOK_CStreaming_Update_Caller() mov eax, FUNC_CStreaming_Update call eax } + // clang-format on // We have an entity for streaming? if (activeEntityForStreaming) { - _asm + // clang-format off + __asm { // ... mov edi, FUNC_CPlayerInfoBase mov ebx, dwSavedPlayerPointer mov [edi], ebx } + // clang-format on } // We're no longer in streaming update bInStreamingUpdate = false; - _asm + // clang-format off + __asm { // Restore registers popad @@ -2896,35 +2942,43 @@ void _declspec(naked) HOOK_CStreaming_Update_Caller() add eax, 7 jmp eax } + // clang-format on } -void _declspec(naked) HOOK_CHud_Draw_Caller() +static void __declspec(naked) HOOK_CHud_Draw_Caller() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + /* 0053E4FA . E8 318BFCFF CALL gta_sa_u.00507030 0053E4FF . E8 DC150500 CALL gta_sa_u.0058FAE0 */ - _asm + // clang-format off + __asm { pushad mov edx, FUNC_CAudioEngine__DisplayRadioStationName call edx } + // clang-format on if (!bSetCenterOfWorld) { - _asm + // clang-format off + __asm { mov edx, FUNC_CHud_Draw call edx } + // clang-format on } else { /*if ( activeEntityForStreaming ) { - _asm + // clang-format off + __asm { mov edi, FUNC_CPlayerInfoBase mov ebx, [edi] @@ -2932,29 +2986,35 @@ void _declspec(naked) HOOK_CHud_Draw_Caller() mov ebx, activeEntityForStreaming mov [edi], ebx } + // clang-format on }*/ if (!bHideRadar) { - _asm + // clang-format off + __asm { mov edx, 0x58A330 call edx } + // clang-format on } /*if ( activeEntityForStreaming ) { - _asm + // clang-format off + __asm { mov edi, FUNC_CPlayerInfoBase mov ebx, dwSavedPlayerPointer mov [edi], ebx } + // clang-format on }*/ } - _asm + // clang-format off + __asm { popad @@ -2962,16 +3022,20 @@ void _declspec(naked) HOOK_CHud_Draw_Caller() add eax, 10 jmp eax } + // clang-format on } -void _declspec(naked) HOOK_FindPlayerCentreOfWorld() +static void __declspec(naked) HOOK_FindPlayerCentreOfWorld() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + /* 0056E250 /$ 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] 0056E254 |. 85C0 TEST EAX,EAX */ - _asm + // clang-format off + __asm { mov al, bSetCenterOfWorld test al, al @@ -2989,16 +3053,20 @@ void _declspec(naked) HOOK_FindPlayerCentreOfWorld() lea eax, vecCenterOfWorld retn } + // clang-format on } -void _declspec(naked) HOOK_FindPlayerHeading() +static void __declspec(naked) HOOK_FindPlayerHeading() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + /* 0056E450 /$ 8B4C24 04 MOV ECX,DWORD PTR SS:[ESP+4] 0056E454 |. 8BD1 MOV EDX,ECX */ - _asm + // clang-format off + __asm { // Jump if bSetCenterOfWorld is true push eax @@ -3020,12 +3088,16 @@ void _declspec(naked) HOOK_FindPlayerHeading() fld fFalseHeading retn } + // clang-format on } // this hook adds a null check to prevent the game crashing when objects are placed really high up (issue 517) -void _declspec(naked) HOOK_CCustomRoadsignMgr__RenderRoadsignAtomic() +static void __declspec(naked) HOOK_CCustomRoadsignMgr__RenderRoadsignAtomic() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { cmp esi, 0 jz no_render @@ -3040,6 +3112,131 @@ void _declspec(naked) HOOK_CCustomRoadsignMgr__RenderRoadsignAtomic() mov edx, 0x6FF40B jmp edx } + // clang-format on +} + +// Mirror the existing roadsign render guard in the create path. +// CreateEffects stores the loop index and model info on the stack, so restore them +// before continuing with the switch loop when roadsign atomic creation fails. +void _declspec(naked) HOOK_CEntity__CreateEffects_RoadsignAtomic() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + mov ebx, eax + test ebx, ebx + jz no_atomic + + mov edi, [ebx+4] + mov edx, RETURN_CEntity__CreateEffects_RoadsignAtomic + jmp edx + + no_atomic: + mov dword ptr [esi+2Ch], 0 + mov edi, [esp+40h] + mov ebx, [esp+44h] + add esp, 24h + mov edx, RETURN_CEntity__CreateEffects_RoadsignSkip + jmp edx + } + // clang-format on +} + +static void CallRoadsignGetLineAndRow(char cLetter, int* pCol, int* pRow) noexcept +{ + // SA passes the character in AL for this helper. + __asm + { + mov al, cLetter + push pRow + push pCol + mov edx, FUNC_RoadsignGetLineAndRow + call edx + add esp, 8 + } +} + +[[nodiscard]] static bool RoadsignGenerateTextRaster_Fixed(const char* szRoadName, int iNumLetters, RwRaster* pCharsetRaster, RwRaster* pSignRaster) noexcept +{ + constexpr int SIGN_CHAR_WIDTH = 8; + constexpr int SIGN_CHAR_HEIGHT = 16; + constexpr int SIGN_PIXEL_BYTES = 4; + constexpr int CHARSET_COLS_PER_ROW = 64; + constexpr int LOCKMODE_WRITE_NOFETCH = 5; + + struct SRoadsignRasterView + { + void* pParent; + std::uint8_t* pPixels; + std::uint8_t* pPalette; + int iWidth; + int iHeight; + int iDepth; + int iStride; + }; + + auto* pSignLock = reinterpret_cast(RwRasterLock(pSignRaster, 0, LOCKMODE_WRITE_NOFETCH)); + if (!pSignLock) + return false; + + bool bSuccess = false; + do + { + auto*& pCharsetLockRef = *reinterpret_cast(VAR_RoadsignRasterLockedData); + if (!pCharsetLockRef) + pCharsetLockRef = reinterpret_cast(RwRasterLock(pCharsetRaster, 0, RASTER_LOCK_READ)); + + auto* pCharsetLock = pCharsetLockRef; + if (!pCharsetLock) + break; + + const int iCharsetStride = reinterpret_cast(pCharsetRaster)->iStride; + if (!iCharsetStride) + break; + + const int iSignStride = reinterpret_cast(pSignRaster)->iStride; + if (!iSignStride) + break; + + for (int iLetter = 0; iLetter < iNumLetters; ++iLetter) + { + int iCol = 1; + int iRow = 1; + CallRoadsignGetLineAndRow(szRoadName[iLetter], &iCol, &iRow); + + auto* pCharsetPixels = pCharsetLock + SIGN_CHAR_WIDTH * SIGN_PIXEL_BYTES * (iCol + iRow * CHARSET_COLS_PER_ROW); + auto* pSignPixels = pSignLock + iLetter * SIGN_CHAR_WIDTH * SIGN_PIXEL_BYTES; + + for (int iRasterRow = 0; iRasterRow < SIGN_CHAR_HEIGHT; ++iRasterRow) + { + std::memcpy(pSignPixels, pCharsetPixels, SIGN_CHAR_WIDTH * SIGN_PIXEL_BYTES); + pCharsetPixels += iCharsetStride; + pSignPixels += iSignStride; + } + } + + bSuccess = true; + } while (false); + + RwRasterUnlock(pSignRaster); + return bSuccess; +} + +static bool __cdecl HOOK_RoadsignGenerateTextRaster_Impl(char* szRoadName, int iNumLetters, RwRaster* pCharsetRaster, int, RwRaster* pSignRaster) noexcept +{ + return RoadsignGenerateTextRaster_Fixed(szRoadName, iNumLetters, pCharsetRaster, pSignRaster); +} + +void _declspec(naked) HOOK_RoadsignGenerateTextRaster() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + jmp HOOK_RoadsignGenerateTextRaster_Impl + } + // clang-format on } bool CallBreakTowLinkHandler(CVehicleSAInterface* vehicle) @@ -3053,54 +3250,70 @@ bool CallBreakTowLinkHandler(CVehicleSAInterface* vehicle) return true; } -void _declspec(naked) HOOK_CRadar__DrawRadarGangOverlay() +static void __declspec(naked) HOOK_CRadar__DrawRadarGangOverlay() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on if (m_pDrawRadarAreasHandler) m_pDrawRadarAreasHandler(); - _asm + // clang-format off + __asm { popad retn } + // clang-format on } CVehicleSAInterface* towingVehicle; -void _declspec(naked) HOOK_Trailer_BreakTowLink() +static void __declspec(naked) HOOK_Trailer_BreakTowLink() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov towingVehicle, ecx pushad } + // clang-format on if (CallBreakTowLinkHandler(towingVehicle)) { - _asm + // clang-format off + __asm { popad call dword ptr [edx+0xF8] } + // clang-format on } else { - _asm + // clang-format off + __asm { popad } + // clang-format on } - _asm + // clang-format off + __asm { mov ecx, HOOKPOS_Trailer_BreakTowLink add ecx, 6 jmp ecx } + // clang-format on } eExplosionType explosionType; @@ -3129,9 +3342,12 @@ bool CallExplosionHandler() return m_pExplosionHandler(pExplodingEntity, pExplosionCreator, vecExplosionLocation, explosionType); } -void _declspec(naked) HOOK_CExplosion_AddExplosion() +static void __declspec(naked) HOOK_CExplosion_AddExplosion() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Check if explosions are disabled. push eax @@ -3178,25 +3394,31 @@ void _declspec(naked) HOOK_CExplosion_AddExplosion() // Store registers for calling this handler pushad } + // clang-format on // Call the explosion handler if (!CallExplosionHandler()) { - _asm + // clang-format off + __asm { popad retn // if they return false from the handler, they don't want the explosion to show } + // clang-format on } else { - _asm + // clang-format off + __asm { popad } + // clang-format on } - _asm + // clang-format off + __asm { noexplosionhandler: @@ -3211,6 +3433,7 @@ void _declspec(naked) HOOK_CExplosion_AddExplosion() add edx, 6 jmp edx } + // clang-format on } CEntitySAInterface* entity; @@ -3238,9 +3461,12 @@ bool processGrab() } // 0x67DABE -void _declspec(naked) HOOK_CTaskComplexJump__CreateSubTask() +static void __declspec(naked) HOOK_CTaskComplexJump__CreateSubTask() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov pedPosition, eax mov eax, [esi+28] @@ -3251,24 +3477,29 @@ void _declspec(naked) HOOK_CTaskComplexJump__CreateSubTask() mov eax, pedPosition pushad } + // clang-format on if (processGrab()) { - _asm + // clang-format off + __asm { popad mov eax, 0x67DAD6 jmp eax } + // clang-format on } else { - _asm + // clang-format off + __asm { popad mov eax, 0x67DAD1 jmp eax } + // clang-format on } } @@ -3276,9 +3507,12 @@ char* szCreateFxSystem_ExplosionType = 0; DWORD* pCreateFxSystem_Matrix = 0; DWORD* pNewCreateFxSystem_Matrix = 0; -void _declspec(naked) HOOK_FxManager_CreateFxSystem() +static void __declspec(naked) HOOK_FxManager_CreateFxSystem() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Store the explosion type mov eax, [esp+4] @@ -3291,6 +3525,7 @@ void _declspec(naked) HOOK_FxManager_CreateFxSystem() // Store all the registers on the stack pushad } + // clang-format on // If we got a matrix and it is an explosion type? if (pCreateFxSystem_Matrix != 0 && strncmp(szCreateFxSystem_ExplosionType, "explosion", 9) == 0) @@ -3308,7 +3543,8 @@ void _declspec(naked) HOOK_FxManager_CreateFxSystem() pNewCreateFxSystem_Matrix = pCreateFxSystem_Matrix; } - _asm + // clang-format off + __asm { // Restore the registers popad @@ -3324,14 +3560,18 @@ void _declspec(naked) HOOK_FxManager_CreateFxSystem() // Jump back to the rest of the function we hooked jmp RETURN_FxManager_CreateFxSystem } + // clang-format on } DWORD dwDestroyFxSystem_Pointer = 0; DWORD* pDestroyFxSystem_Matrix = 0; -void _declspec(naked) HOOK_FxManager_DestroyFxSystem() +static void __declspec(naked) HOOK_FxManager_DestroyFxSystem() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Grab the FxSystem that's being destroyed mov eax, [esp+4] @@ -3340,6 +3580,7 @@ void _declspec(naked) HOOK_FxManager_DestroyFxSystem() // Store all the registers on the stack pushad } + // clang-format on // Grab the matrix pointer in it pDestroyFxSystem_Matrix = *((DWORD**)(dwDestroyFxSystem_Pointer + 12)); @@ -3347,7 +3588,8 @@ void _declspec(naked) HOOK_FxManager_DestroyFxSystem() // Delete it if it's in our list RemoveFxSystemPointer(pDestroyFxSystem_Matrix); - _asm + // clang-format off + __asm { // Restore the registers popad @@ -3361,6 +3603,7 @@ void _declspec(naked) HOOK_FxManager_DestroyFxSystem() // Jump back to the rest of the function we hooked jmp RETURN_FxManager_DestroyFxSystem } + // clang-format on } bool CCam_ProcessFixed(class CCamSAInterface* pCamInterface) @@ -3376,23 +3619,30 @@ bool CCam_ProcessFixed(class CCamSAInterface* pCamInterface) CCamSAInterface* CCam_ProcessFixed_pCam; -void _declspec(naked) HOOK_CCam_ProcessFixed() +static void __declspec(naked) HOOK_CCam_ProcessFixed() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov CCam_ProcessFixed_pCam, ecx } + // clang-format on if (CCam_ProcessFixed(CCam_ProcessFixed_pCam)) { - _asm + // clang-format off + __asm { ret 10h } + // clang-format on } else { - _asm + // clang-format off + __asm { mov ecx, CCam_ProcessFixed_pCam sub esp, 28h @@ -3400,23 +3650,30 @@ void _declspec(naked) HOOK_CCam_ProcessFixed() push ebp jmp RETURN_CCam_ProcessFixed } + // clang-format on } } -void _declspec(naked) HOOK_Render3DStuff() +static void __declspec(naked) HOOK_Render3DStuff() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on if (m_pRender3DStuffHandler) m_pRender3DStuffHandler(); - _asm + // clang-format off + __asm { popad mov eax, FUNC_Render3DStuff jmp eax } + // clang-format on } CPedSAInterface* pProcessPlayerWeaponPed = NULL; @@ -3441,36 +3698,44 @@ bool ProcessPlayerWeapon() return false; } -void _declspec(naked) HOOK_CTaskSimplePlayerOnFoot_ProcessPlayerWeapon() +static void __declspec(naked) HOOK_CTaskSimplePlayerOnFoot_ProcessPlayerWeapon() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + /* 006859A0 push 0FFFFFFFFh 006859A2 push 846BCEh 006859A7 mov eax,dword ptr fs:[00000000h] */ - _asm + // clang-format off + __asm { mov eax, [esp+4] mov pProcessPlayerWeaponPed, eax pushad } + // clang-format on if (ProcessPlayerWeapon()) { - _asm + // clang-format off + __asm { popad push 0FFFFFFFFh push 846BCEh jmp RETURN_CTaskSimplePlayerOnFoot_ProcessPlayerWeapon } + // clang-format on } else { - _asm + // clang-format off + __asm { popad ret 4 } + // clang-format on } } @@ -3480,34 +3745,42 @@ bool IsPlayer() return true; } -void _declspec(naked) HOOK_CPed_IsPlayer() +static void __declspec(naked) HOOK_CPed_IsPlayer() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + /* 005DF8F0 mov eax,dword ptr [ecx+598h] 005DF8F6 test eax,eax */ - _asm + // clang-format off + __asm { mov pIsPlayerPed, ecx pushad } + // clang-format on if (IsPlayer()) { - _asm + // clang-format off + __asm { popad mov eax,dword ptr [ecx+598h] jmp RETURN_CPed_IsPlayer } + // clang-format on } else { - _asm + // clang-format off + __asm { popad xor al, al ret } + // clang-format on } } @@ -3519,11 +3792,12 @@ void CRunningScript_Process() pCamera->SetFadeColor(0, 0, 0); pCamera->Fade(0.0f, FADE_OUT); - DWORD dwFunc = 0x409D10; // RequestSpecialModel + DWORD dwFunc = 0x409D10; // RequestSpecialModel char szModelName[64]; strcpy(szModelName, "player"); - _asm + // clang-format off + __asm { push 26 lea eax, szModelName @@ -3532,45 +3806,55 @@ void CRunningScript_Process() call dwFunc add esp, 12 } + // clang-format on - dwFunc = 0x40EA10; // load all requested models - _asm + dwFunc = 0x40EA10; // load all requested models + // clang-format off + __asm { push 1 call dwFunc add esp, 4 } + // clang-format on - dwFunc = 0x60D790; // setup player ped - _asm + dwFunc = 0x60D790; // setup player ped + // clang-format off + __asm { push 0 call dwFunc add esp, 4 } + // clang-format on /*dwFunc = 0x05E47E0; // set created by - _asm + // clang-format off + __asm { mov edi, 0xB7CD98 mov ecx, [edi] push 2 call dwFunc } + // clang-format on dwFunc = 0x609520; // deactivate player ped - _asm + // clang-format off + __asm { push 0 call dwFunc add esp, 4 } + // clang-format on */ - dwFunc = 0x420B80; // set position + dwFunc = 0x420B80; // set position fX = 2488.562f; fY = -1666.864f; fZ = 12.8757f; - _asm + // clang-format off + __asm { mov edi, 0xB7CD98 push fZ @@ -3579,32 +3863,40 @@ void CRunningScript_Process() mov ecx, [edi] call dwFunc } + // clang-format on /* dwFunc = 0x609540; // reactivate player ped - _asm + // clang-format off + __asm { push 0 call dwFunc add esp, 4 } + // clang-format on dwFunc = 0x61A5A0; // CTask::operator new - _asm + // clang-format off + __asm { push 28 call dwFunc add esp, 4 } + // clang-format on dwFunc = 0x685750; // CTaskSimplePlayerOnFoot::CTaskSimplePlayerOnFoot - _asm + // clang-format off + __asm { mov ecx, eax call dwFunc } + // clang-format on dwFunc = 0x681AF0; // set task - _asm + // clang-format off + __asm { mov edi, 0xB7CD98 mov edi, [edi] @@ -3615,33 +3907,43 @@ void CRunningScript_Process() push eax call dwFunc } + // clang-format on */ bHasProcessedScript = true; } } -void _declspec(naked) HOOK_CRunningScript_Process() +static void __declspec(naked) HOOK_CRunningScript_Process() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on CRunningScript_Process(); - _asm + // clang-format off + __asm { popad retn } + // clang-format on } -static CVehicleSAInterface* pDerailingTrain = NULL; -void _declspec(naked) HOOK_CTrain_ProcessControl_Derail() +static CVehicleSAInterface* pDerailingTrain = NULL; +static void __declspec(naked) HOOK_CTrain_ProcessControl_Derail() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // If the train wouldn't derail, don't modify anything - _asm + // clang-format off + __asm { jnp train_would_derail mov eax, 0x6F8F89 @@ -3650,26 +3952,31 @@ void _declspec(naked) HOOK_CTrain_ProcessControl_Derail() pushad mov pDerailingTrain, esi } + // clang-format on // At this point we know that GTA wants to derail the train if (pDerailingTrain->m_pVehicle->IsDerailable()) { // Go back to the derailment code - _asm + // clang-format off + __asm { popad mov eax, 0x6F8DC0 jmp eax } + // clang-format on } else { - _asm + // clang-format off + __asm { popad mov eax, 0x6F8F89 jmp eax } + // clang-format on } } @@ -3694,12 +4001,14 @@ static void SetEntityAlphaHooked(DWORD dwEntity, DWORD dwCallback, DWORD dwAlpha // Call SetRwObjectAlpha DWORD dwFunc = FUNC_SetRwObjectAlpha; - _asm + // clang-format off + __asm { mov ecx, dwEntity push dwAlpha call dwFunc } + // clang-format on // Restore the GTA callbacks MemPutFast(0x5332A2, (DWORD)(0x533280)); @@ -3764,43 +4073,55 @@ static void SetVehicleAlpha() bEntityHasAlpha = false; } -static DWORD dwCVehicle_SetupRender_ret = 0x6D6517; -void _declspec(naked) HOOK_CVehicle_SetupRender() +static DWORD dwCVehicle_SetupRender_ret = 0x6D6517; +static void __declspec(naked) HOOK_CVehicle_SetupRender() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov dwAlphaEntity, esi pushad } + // clang-format on SetVehicleAlpha(); - _asm + // clang-format off + __asm { popad add esp, 0x8 test eax, eax jmp dwCVehicle_SetupRender_ret } + // clang-format on } -static DWORD dwCVehicle_ResetAfterRender_ret = 0x6D0E43; -void _declspec(naked) HOOK_CVehicle_ResetAfterRender() +static DWORD dwCVehicle_ResetAfterRender_ret = 0x6D0E43; +static void __declspec(naked) HOOK_CVehicle_ResetAfterRender() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on RestoreAlphaValues(); - _asm + // clang-format off + __asm { popad add esp, 0x0C test eax, eax jmp dwCVehicle_ResetAfterRender_ret } + // clang-format on } /** @@ -3831,72 +4152,42 @@ static void SetObjectAlpha() } } -DWORD dwCObjectRenderRet = 0; -void _declspec(naked) HOOK_CObject_PostRender() +static void CObjectRenderWithTiming(CObjectSAInterface* object) { - _asm + dwAlphaEntity = reinterpret_cast(object); + + SetObjectAlpha(); + TIMING_CHECKPOINT("+ObjRndr"); { - pushad + if (bObjectIsAGangTag) + { + void(__cdecl * CTagManager__RenderTagForPC)(RpAtomic*) = reinterpret_cast(0x49CE40); + CTagManager__RenderTagForPC(reinterpret_cast(object->m_pRwObject)); + } + else + { + void(__fastcall * CObject__Render)(CObjectSAInterface*) = reinterpret_cast(0x534310); + CObject__Render(object); + } } - TIMING_CHECKPOINT("-ObjRndr"); RestoreAlphaValues(); - - _asm - { - popad - mov edx, dwCObjectRenderRet - jmp edx - } } // Note: This hook is also called for world objects (light poles, wooden fences, etc). -void _declspec(naked) HOOK_CObject_Render() +static void __declspec(naked) HOOK_CObject_Render() { - _asm - { - mov dwAlphaEntity, ecx - pushad - } + MTA_VERIFY_HOOK_LOCAL_SIZE; - TIMING_CHECKPOINT("+ObjRndr"); - SetObjectAlpha(); - - _asm - { - popad - mov edx, [esp] - mov dwCObjectRenderRet, edx - mov edx, HOOK_CObject_PostRender - mov [esp], edx - pushad - } - - if (bObjectIsAGangTag) goto render_a_tag; - - _asm - { - popad - jmp FUNC_CEntity_Render - } - -render_a_tag: - _asm + // clang-format off + __asm { - popad - // We simulate here the header of the CEntity::Render function - // but then go straight to CTagManager::RenderTagForPC. - push ecx - push esi - mov eax, [esi+0x18] - test eax, eax - jz no_clump - mov eax, 0x534331 - jmp eax - no_clump: - mov eax, 0x5343EB - jmp eax + push ecx + call CObjectRenderWithTiming + add esp, 4 + retn } + // clang-format on } void _cdecl DoEndWorldColorsPokes() @@ -3951,26 +4242,33 @@ void _cdecl DoEndWorldColorsPokes() } // Note: This hook is called at the end of the function that sets the world colours (sky gradient, water colour, etc). -void _declspec(naked) HOOK_EndWorldColors() +static void __declspec(naked) HOOK_EndWorldColors() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { call DoEndWorldColorsPokes ret } + // clang-format on } // This hook modifies the code in CWorld::ProcessVerticalLineSectorList to // force it to also check the world objects, so we can get a reliable ground // position on custom object maps. This will make getGroundPosition, jetpacks // and molotovs to work. -static DWORD dwObjectsChecked = 0; -static DWORD dwProcessVerticalKeepLooping = 0x5632D1; -static DWORD dwProcessVerticalEndLooping = 0x56335F; -static DWORD dwGlobalListOfObjects = 0xB9ACCC; -void _declspec(naked) HOOK_CWorld_ProcessVerticalLineSectorList() +static DWORD dwObjectsChecked = 0; +static DWORD dwProcessVerticalKeepLooping = 0x5632D1; +static DWORD dwProcessVerticalEndLooping = 0x56335F; +static DWORD dwGlobalListOfObjects = 0xB9ACCC; +static void __declspec(naked) HOOK_CWorld_ProcessVerticalLineSectorList() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { test ebp, ebp jz end_of_entities_list @@ -3991,37 +4289,48 @@ void _declspec(naked) HOOK_CWorld_ProcessVerticalLineSectorList() mov dwObjectsChecked, 0 jmp dwProcessVerticalEndLooping } + // clang-format on } // Hook to detect when a player is choking -static DWORD dwChokingChoke = 0x4C05C1; -static DWORD dwChokingDontchoke = 0x4C0620; -static unsigned char ucChokingWeaponType = 0; -void _declspec(naked) HOOK_ComputeDamageResponse_StartChoking() +static DWORD dwChokingChoke = 0x4C05C1; +static DWORD dwChokingDontchoke = 0x4C0620; +static unsigned char ucChokingWeaponType = 0; +static void __declspec(naked) HOOK_ComputeDamageResponse_StartChoking() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - pushad - mov al, [esp+0x8C] + // Get weapon type before pushad to avoid stack offset corruption + mov al, [esp+0x8] mov ucChokingWeaponType, al - } - if (m_pChokingHandler && m_pChokingHandler(ucChokingWeaponType) == false) goto dont_choke; + pushad - _asm - { + mov ebx, [m_pChokingHandler] + test ebx, ebx + jz continueWithOriginalCode + + // Push weapon type as parameter + movzx eax, ucChokingWeaponType + push eax + call ebx + add esp, 4 + test al, al + + jnz continueWithOriginalCode + popad + jmp dwChokingDontchoke + + continueWithOriginalCode: popad mov ecx, [edi] mov eax, [ecx+0x47C] jmp dwChokingChoke } - -dont_choke: - _asm - { - popad - jmp dwChokingDontchoke - } + // clang-format on } void CMultiplayerSA::DisableEnterExitVehicleKey(bool bDisabled) @@ -4203,7 +4512,8 @@ void CMultiplayerSA::ConvertEulerAnglesToMatrix(CMatrix& Matrix, float fX, float CMatrix_Padded* pMatrixPadded = &matrixPadded; DWORD dwFunc = FUNC_CMatrix__ConvertFromEulerAngles; int iUnknown = 21; - _asm + // clang-format off + __asm { push iUnknown push fZ @@ -4212,6 +4522,7 @@ void CMultiplayerSA::ConvertEulerAnglesToMatrix(CMatrix& Matrix, float fX, float mov ecx, pMatrixPadded call dwFunc } + // clang-format on // Convert the result matrix to the CMatrix we know matrixPadded.ConvertToMatrix(Matrix); @@ -4230,7 +4541,8 @@ void CMultiplayerSA::ConvertMatrixToEulerAngles(const CMatrix& Matrix, float& fX float* pfY = &fY; float* pfZ = &fZ; int iUnknown = 21; - _asm + // clang-format off + __asm { push iUnknown push pfZ @@ -4239,6 +4551,7 @@ void CMultiplayerSA::ConvertMatrixToEulerAngles(const CMatrix& Matrix, float& fX mov ecx, pMatrixPadded call dwFunc } + // clang-format on } void CMultiplayerSA::RebuildMultiplayerPlayer(CPed* player) @@ -4336,104 +4649,134 @@ void CMultiplayerSA::SetDebugVars(float f1, float f2, float f3) { } -void _declspec(naked) HOOK_CollisionStreamRead() +static void __declspec(naked) HOOK_CollisionStreamRead() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + if (*(DWORD*)VAR_CollisionStreamRead_ModelInfo) { - _asm + // clang-format off + __asm { mov eax, dword ptr fs:[0] jmp RETURN_CollisionStreamRead } + // clang-format on } else { - _asm + // clang-format off + __asm { ret } + // clang-format on } } -unsigned char ucDesignatedLightState = 0; -void _declspec(naked) HOOK_CTrafficLights_GetPrimaryLightState() +unsigned char ucDesignatedLightState = 0; +static void __declspec(naked) HOOK_CTrafficLights_GetPrimaryLightState() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on if (ucTrafficLightState == 0 || ucTrafficLightState == 5 || ucTrafficLightState == 8) { - ucDesignatedLightState = 0; // Green + ucDesignatedLightState = 0; // Green } else if (ucTrafficLightState == 1 || ucTrafficLightState == 6 || ucTrafficLightState == 7) { - ucDesignatedLightState = 1; // Amber + ucDesignatedLightState = 1; // Amber } else if (ucTrafficLightState == 9) { - ucDesignatedLightState = 4; // Off + ucDesignatedLightState = 4; // Off } - else ucDesignatedLightState = 2; // Red + else ucDesignatedLightState = 2; // Red - _asm + // clang-format off + __asm { popad mov al, ucDesignatedLightState retn } + // clang-format on } -void _declspec(naked) HOOK_CTrafficLights_GetSecondaryLightState() +static void __declspec(naked) HOOK_CTrafficLights_GetSecondaryLightState() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on if (ucTrafficLightState == 3 || ucTrafficLightState == 5 || ucTrafficLightState == 7) { - ucDesignatedLightState = 0; // Green + ucDesignatedLightState = 0; // Green } else if (ucTrafficLightState == 4 || ucTrafficLightState == 6 || ucTrafficLightState == 8) { - ucDesignatedLightState = 1; // Amber + ucDesignatedLightState = 1; // Amber } else if (ucTrafficLightState == 9) { - ucDesignatedLightState = 4; // Off + ucDesignatedLightState = 4; // Off } - else ucDesignatedLightState = 2; // Red + else ucDesignatedLightState = 2; // Red - _asm + // clang-format off + __asm { popad mov al, ucDesignatedLightState retn } + // clang-format on } -void _declspec(naked) HOOK_CTrafficLights_DisplayActualLight() +static void __declspec(naked) HOOK_CTrafficLights_DisplayActualLight() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on if (ucTrafficLightState == 2) { ucDesignatedLightState = 0; } - else if (ucTrafficLightState == 9) { ucDesignatedLightState = 1; } - else { ucDesignatedLightState = 2; } + else if (ucTrafficLightState == 9) + { + ucDesignatedLightState = 1; + } + else + { + ucDesignatedLightState = 2; + } - _asm + // clang-format off + __asm { popad movzx eax, ucDesignatedLightState jmp RETURN_CTrafficLights_DisplayActualLight } + // clang-format on } static CVehicleSAInterface* pHandlingDriveTypeVeh = NULL; @@ -4455,9 +4798,12 @@ void CheckVehicleMaxGear() } } -void _declspec(naked) HOOK_Transmission_CalculateDriveAcceleration() +static void __declspec(naked) HOOK_Transmission_CalculateDriveAcceleration() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push eax mov pCurTransmission, ecx @@ -4466,52 +4812,67 @@ void _declspec(naked) HOOK_Transmission_CalculateDriveAcceleration() pop eax pushad } + // clang-format on CheckVehicleMaxGear(); - _asm + // clang-format off + __asm { popad mov eax, [esp+0x10] mov edx, [eax] jmp RETURN_Transmission_CalculateDriveAcceleration } + // clang-format on } -void _declspec(naked) HOOK_isVehDriveTypeNotRWD() +static void __declspec(naked) HOOK_isVehDriveTypeNotRWD() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // Get the Vehicle interface from esi - _asm + // clang-format off + __asm { mov pHandlingDriveTypeVeh, esi } + // clang-format on GetVehicleDriveType(); // push our drive type into bl :) - _asm + // clang-format off + __asm { mov bl, ucDriveType jmp RETURN_CHandlingData_isNotRWD } + // clang-format on } -void _declspec(naked) HOOK_isVehDriveTypeNotFWD() +static void __declspec(naked) HOOK_isVehDriveTypeNotFWD() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // Get the Vehicle SA interface from esi - _asm + // clang-format off + __asm { mov pHandlingDriveTypeVeh, esi } + // clang-format on GetVehicleDriveType(); // push our drive type into bl :) - _asm + // clang-format off + __asm { mov bl, ucDriveType jmp RETURN_CHandlingData_isNotFWD } + // clang-format on } unsigned char CMultiplayerSA::GetTrafficLightState() @@ -4567,13 +4928,15 @@ void CMultiplayerSA::AllowCreatedObjectsInVerticalLineTest(bool bOn) void _cdecl CPhysical_ApplyGravity(DWORD dwThis) { DWORD dwType; - _asm + // clang-format off + __asm { mov ecx, dwThis mov eax, 0x46A2C0 // CEntity::GetType call eax mov dwType, eax } + // clang-format on float fTimeStep = *(float*)0xB7CB5C; float fGravity = *(float*)0x863984; @@ -4598,27 +4961,35 @@ void _cdecl CPhysical_ApplyGravity(DWORD dwThis) } } -const float kfTimeStepOrg = 5.0f / 3.0f; -void _declspec(naked) HOOK_CVehicle_ApplyBoatWaterResistance() +const float kfTimeStepOrg = 5.0f / 3.0f; +static void __declspec(naked) HOOK_CVehicle_ApplyBoatWaterResistance() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { fmul ds : 0x871DDC // Original constant used in code fmul ds : 0xB7CB5C // Multiply by current timestep fdiv kfTimeStepOrg // Divide by desired timestep, used at 30fps jmp RETURN_CVehicle_ApplyBoatWaterResistance } + // clang-format on } -void _declspec(naked) HOOK_CPhysical_ApplyGravity() +static void __declspec(naked) HOOK_CPhysical_ApplyGravity() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push esi call CPhysical_ApplyGravity add esp, 4 jmp RETURN_CPhysical_ApplyGravity } + // clang-format on } // --------------------------------------------------- @@ -4690,9 +5061,12 @@ bool _cdecl VehicleCamStart(DWORD dwCam, DWORD pVehicleInterface) return true; } -void _declspec(naked) HOOK_VehicleCamStart() +static void __declspec(naked) HOOK_VehicleCamStart() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push edi push esi @@ -4708,6 +5082,7 @@ void _declspec(naked) HOOK_VehicleCamStart() add esp, 4 jmp RETURN_VehicleCamStart_failure } + // clang-format on } // --------------------------------------------------- @@ -4718,9 +5093,12 @@ void _cdecl VehicleCamTargetZTweak(CVector* pvecCamTarget, float fTargetZTweak) *pvecCamTarget += gravcam_matGravity.vUp * fTargetZTweak; } -void _declspec(naked) HOOK_VehicleCamTargetZTweak() +static void __declspec(naked) HOOK_VehicleCamTargetZTweak() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { fstp st @@ -4743,6 +5121,7 @@ void _declspec(naked) HOOK_VehicleCamTargetZTweak() cmp eax, 1 jmp RETURN_VehicleCamTargetZTweak } + // clang-format on } // --------------------------------------------------- @@ -4755,9 +5134,12 @@ void _cdecl VehicleCamLookDir1(DWORD dwCam, DWORD pVehicleInterface) *pvecLookDir = gravcam_matInvertGravity * (*pvecLookDir); } -void _declspec(naked) HOOK_VehicleCamLookDir1() +static void __declspec(naked) HOOK_VehicleCamLookDir1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov eax, 0x59C910 // CVector::Normalise call eax @@ -4769,6 +5151,7 @@ void _declspec(naked) HOOK_VehicleCamLookDir1() jmp RETURN_VehicleCamLookDir1 } + // clang-format on } // --------------------------------------------------- @@ -4788,9 +5171,12 @@ bool _cdecl VehicleCamLookDir2(DWORD dwCam) return true; } -void _declspec(naked) HOOK_VehicleCamLookDir2() +static void __declspec(naked) HOOK_VehicleCamLookDir2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push esi call VehicleCamLookDir2 @@ -4801,6 +5187,7 @@ void _declspec(naked) HOOK_VehicleCamLookDir2() push 4 jmp RETURN_VehicleCamLookDir2 } + // clang-format on } // --------------------------------------------------- @@ -4814,9 +5201,12 @@ void _cdecl VehicleCamHistory(DWORD dwCam, CVector* pvecTarget, float fTargetThe ((CVector*)(dwCam + 0x1D8))[1] = *pvecTarget - vecDir * fZoom; } -void _declspec(naked) HOOK_VehicleCamHistory() +static void __declspec(naked) HOOK_VehicleCamHistory() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push [esp+0x0+0x7C] // zoom push [esp+0x4+0x2C] // radius @@ -4830,6 +5220,7 @@ void _declspec(naked) HOOK_VehicleCamHistory() mov eax, [esp+0x24] jmp RETURN_VehicleCamHistory } + // clang-format on } // --------------------------------------------------- @@ -4847,9 +5238,12 @@ void _cdecl VehicleCamUp(DWORD dwCam) pvecUp->Normalize(); } -void _declspec(naked) HOOK_VehicleCamUp() +static void __declspec(naked) HOOK_VehicleCamUp() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov edx, ecx mov ecx, [ecx+0x21C] // CCam::pTargetEntity @@ -4869,6 +5263,7 @@ void _declspec(naked) HOOK_VehicleCamUp() add esp, 4 ret } + // clang-format on } // --------------------------------------------------- @@ -4885,9 +5280,12 @@ void _cdecl VehicleCamEnd(DWORD pVehicleInterface) pVehicle->SetMoveSpeed(gravcam_vecVehicleVelocity); } -void _declspec(naked) HOOK_VehicleCamEnd() +static void __declspec(naked) HOOK_VehicleCamEnd() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov ds:[0xB6F020], edx @@ -4897,6 +5295,7 @@ void _declspec(naked) HOOK_VehicleCamEnd() jmp RETURN_VehicleCamEnd } + // clang-format on } // --------------------------------------------------- @@ -4908,9 +5307,12 @@ void _cdecl VehicleLookBehind(DWORD dwCam, CVector* pvecEntityPos, float fDistan MemPutFast(dwCam + 0x19C, *pvecEntityPos + (gravcam_matVehicleTransform.vFront + gravcam_matGravity.vUp * 0.2f) * fDistance); } -void _declspec(naked) HOOK_VehicleLookBehind() +static void __declspec(naked) HOOK_VehicleLookBehind() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push [esp+0x14] lea eax, [esp+4+0x1C] @@ -4932,6 +5334,7 @@ void _declspec(naked) HOOK_VehicleLookBehind() mov eax, ebx // pEntity jmp RETURN_VehicleLookBehind } + // clang-format on } // --------------------------------------------------- @@ -4943,9 +5346,12 @@ void _cdecl VehicleLookAside(DWORD dwCam, CVector* pvecEntityPos, float fDirecti MemPutFast(dwCam + 0x19C, *pvecEntityPos + (-gravcam_matVehicleTransform.vRight * fDirectionFactor + gravcam_matGravity.vUp * 0.2f) * fDistance); } -void _declspec(naked) HOOK_VehicleLookAside() +static void __declspec(naked) HOOK_VehicleLookAside() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push [esp+0x14] push [esp+4+0x1C] @@ -4959,6 +5365,7 @@ void _declspec(naked) HOOK_VehicleLookAside() mov ecx, [esi+0x21C] jmp RETURN_VehicleLookAside } + // clang-format on } // --------------------------------------------------- @@ -4981,20 +5388,27 @@ float _cdecl VehicleBurnCheck(DWORD pVehicleInterface) return matVehicle.vUp.DotProduct(&vecGravity); } -void _declspec(naked) HOOK_OccupiedVehicleBurnCheck() +static void __declspec(naked) HOOK_OccupiedVehicleBurnCheck() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push eax call VehicleBurnCheck add esp, 4 jmp RETURN_OccupiedVehicleBurnCheck } + // clang-format on } -void _declspec(naked) HOOK_UnoccupiedVehicleBurnCheck() +static void __declspec(naked) HOOK_UnoccupiedVehicleBurnCheck() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov word ptr [esp+0x78], cx @@ -5003,6 +5417,7 @@ void _declspec(naked) HOOK_UnoccupiedVehicleBurnCheck() add esp, 4 jmp RETURN_UnoccupiedVehicleBurnCheck } + // clang-format on } // --------------------------------------------------- @@ -5023,9 +5438,12 @@ void _cdecl ApplyVehicleBlowHop(DWORD pVehicleInterface) pVehicle->SetMoveSpeed(vecVelocity); } -void _declspec(naked) HOOK_ApplyCarBlowHop() +static void __declspec(naked) HOOK_ApplyCarBlowHop() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push esi call ApplyVehicleBlowHop @@ -5038,39 +5456,46 @@ void _declspec(naked) HOOK_ApplyCarBlowHop() mov [esi+0x36], dl jmp RETURN_ApplyCarBlowHop } + // clang-format on } // --------------------------------------------------- -DWORD CALL_CWorld_Process = 0x5684a0; -void _declspec(naked) HOOK_CGame_Process() +static void Pre_CGame_Process() { - _asm - { - pushad - } - TIMING_CHECKPOINT("+CWorld_Process"); + if (m_pPreWorldProcessHandler) m_pPreWorldProcessHandler(); +} + +static void Post_CGame_Process() +{ + if (m_pPostWorldProcessHandler) + m_pPostWorldProcessHandler(); + + TIMING_CHECKPOINT("-CWorld_Process"); +} + +DWORD CALL_CWorld_Process = 0x5684a0; +static void __declspec(naked) HOOK_CGame_Process() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; - _asm + // clang-format off + __asm { + pushad + call Pre_CGame_Process popad call CALL_CWorld_Process mov ecx, 0B72978h pushad - } - - if (m_pPostWorldProcessHandler) m_pPostWorldProcessHandler(); - - TIMING_CHECKPOINT("-CWorld_Process"); - - _asm - { + call Post_CGame_Process popad jmp RETURN_CGame_Process; } + // clang-format on } void __cdecl HandleIdle() @@ -5080,92 +5505,125 @@ void __cdecl HandleIdle() { bAnimGroupArrayAddressLogged = true; DWORD dwAnimGroupArrayAddress = 0xb4ea34; - LogEvent(567, "aAnimAssocGroups", "CAnimManager::ms_aAnimAssocGroups Address", - SString("CAnimManager::ms_aAnimAssocGroups = %#.8x", *(DWORD*)dwAnimGroupArrayAddress), 567); } + + ProcessDeferredStreamingMemoryRelief(); + m_pIdleHandler(); } -DWORD CALL_CGame_Process = 0x53BEE0; -void _declspec(naked) HOOK_Idle() +static void CGameProcessWithTiming() { TIMING_CHECKPOINT("+CGame_Process"); - _asm { - call CALL_CGame_Process - pushad + void(__cdecl * CGame__Process)() = reinterpret_cast(0x53BEE0); + CGame__Process(); } - TIMING_CHECKPOINT("-CGame_Process"); +} +static void IdleWithTiming() +{ TIMING_CHECKPOINT("+Idle"); - if (m_pIdleHandler) - HandleIdle(); + { + if (m_pIdleHandler) + HandleIdle(); + } TIMING_CHECKPOINT("-Idle"); +} + +DWORD CALL_CGame_Process = 0x53BEE0; +static void __declspec(naked) HOOK_Idle() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; - _asm + // clang-format off + __asm { + pushad + call CGameProcessWithTiming + call IdleWithTiming popad + mov ecx, 0B6BC90h jmp RETURN_Idle } + // clang-format on } // Hooked from 0049E650 5 bytes -void _declspec(naked) HOOK_PreFxRender() +static void __declspec(naked) HOOK_PreFxRender() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov eax,[esp+32+4*2] cmp eax,0 jne skip } + // clang-format on if (m_pPreFxRenderHandler) m_pPreFxRenderHandler(); - _asm + // clang-format off + __asm { skip: popad jmp RETURN_PreFxRender // 00404D1E } + // clang-format on } // Hooked from 00705099 5 bytes -void _declspec(naked) HOOK_PostColorFilterRender() +static void __declspec(naked) HOOK_PostColorFilterRender() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on if (m_pPostColorFilterRenderHandler) m_pPostColorFilterRenderHandler(); - _asm + // clang-format off + __asm { popad mov al, ds:0C402BAh jmp RETURN_PostColorFilterRender // 0070509E } + // clang-format on } // Hooked from 0053EAD8 5 bytes -void _declspec(naked) HOOK_PreHUDRender() +static void __declspec(naked) HOOK_PreHUDRender() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on if (m_pPreHudRenderHandler) m_pPreHudRenderHandler(); - _asm + // clang-format off + __asm { popad mov eax, ds:0B6F0B8h jmp RETURN_PreHUDRender // 0053EADD } + // clang-format on } // --------------------------------------------------- @@ -5181,25 +5639,25 @@ void vehicle_lights_init() #else -#define HOOKPOS_CVehicle_DoVehicleLights 0x6e1a60 + #define HOOKPOS_CVehicle_DoVehicleLights 0x6e1a60 DWORD RETURN_CVehicle_DoVehicleLights = 0x6e1a68; -#define HOOKPOS_CVehicle_DoHeadLightBeam_1 0x6E0E20 + #define HOOKPOS_CVehicle_DoHeadLightBeam_1 0x6E0E20 DWORD RETURN_CVehicle_DoHeadLightBeam_1 = 0x6E0E26; -#define HOOKPOS_CVehicle_DoHeadLightBeam_2 0x6E13A4 + #define HOOKPOS_CVehicle_DoHeadLightBeam_2 0x6E13A4 DWORD RETURN_CVehicle_DoHeadLightBeam_2 = 0x6E13AE; -#define HOOKPOS_CVehicle_DoHeadLightEffect_1 0x6E0D01 + #define HOOKPOS_CVehicle_DoHeadLightEffect_1 0x6E0D01 DWORD RETURN_CVehicle_DoHeadLightEffect_1 = 0x6E0D09; -#define HOOKPOS_CVehicle_DoHeadLightEffect_2 0x6E0DF7 + #define HOOKPOS_CVehicle_DoHeadLightEffect_2 0x6E0DF7 DWORD RETURN_CVehicle_DoHeadLightEffect_2 = 0x6E0DFF; -#define HOOKPOS_CVehicle_DoHeadLightReflectionTwin 0x6E170F + #define HOOKPOS_CVehicle_DoHeadLightReflectionTwin 0x6E170F DWORD RETURN_CVehicle_DoHeadLightReflectionTwin = 0x6E1717; -#define HOOKPOS_CVehicle_DoHeadLightReflectionSingle 0x6E15E2 + #define HOOKPOS_CVehicle_DoHeadLightReflectionSingle 0x6E15E2 DWORD RETURN_CVehicle_DoHeadLightReflectionSingle = 0x6E15EA; void HOOK_CVehicle_DoVehicleLights(); @@ -5227,16 +5685,34 @@ void vehicle_lights_init() MemPut(0x6E1D4F, 2); } -CVehicleSAInterface* pLightsVehicleInterface = NULL; -void _declspec(naked) HOOK_CVehicle_DoVehicleLights() +CVehicleSAInterface* pLightsVehicleInterface = NULL; +static void __declspec(naked) HOOK_CVehicle_DoVehicleLights() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov pLightsVehicleInterface, ecx mov al,byte ptr ds:[00C1CC18h] sub esp,3Ch jmp RETURN_CVehicle_DoVehicleLights } + // clang-format on +} + +static unsigned long ClampFloatToByteULong(float value) +{ + if (!(value > 0.0f)) + return 0; + if (value >= 255.0f) + return 255; + return static_cast(value + 0.5f); +} + +static unsigned char ULongToByte(unsigned long value) +{ + return static_cast(value & 0xFFu); } unsigned long ulHeadLightR = 0, ulHeadLightG = 0, ulHeadLightB = 0; @@ -5251,20 +5727,24 @@ void CVehicle_GetHeadLightColor(CVehicleSAInterface* pInterface, float } // Scale our color values to the defaults ..looks dodgy but its needed! - ulHeadLightR = (unsigned char)std::min(255.f, color.R * (1 / 255.0f) * fR); - ulHeadLightG = (unsigned char)std::min(255.f, color.G * (1 / 255.0f) * fG); - ulHeadLightB = (unsigned char)std::min(255.f, color.B * (1 / 255.0f) * fB); + ulHeadLightR = ClampFloatToByteULong(color.R * (1.0f / 255.0f) * fR); + ulHeadLightG = ClampFloatToByteULong(color.G * (1.0f / 255.0f) * fG); + ulHeadLightB = ClampFloatToByteULong(color.B * (1.0f / 255.0f) * fB); } -CVehicleSAInterface* pHeadLightBeamVehicleInterface = NULL; -void _declspec(naked) HOOK_CVehicle_DoHeadLightBeam_1() +CVehicleSAInterface* pHeadLightBeamVehicleInterface = NULL; +static void __declspec(naked) HOOK_CVehicle_DoHeadLightBeam_1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov pHeadLightBeamVehicleInterface, ecx sub esp, 94h jmp RETURN_CVehicle_DoHeadLightBeam_1 } + // clang-format on } RwVertex* pHeadLightVerts = NULL; @@ -5277,13 +5757,16 @@ void CVehicle_DoHeadLightBeam() for (unsigned int i = 0; i < uiHeadLightNumVerts; i++) { unsigned char alpha = COLOR_ARGB_A(pHeadLightVerts[i].color); - pHeadLightVerts[i].color = COLOR_ARGB(alpha, (unsigned char)ulHeadLightR, (unsigned char)ulHeadLightG, (unsigned char)ulHeadLightB); + pHeadLightVerts[i].color = COLOR_ARGB(alpha, ULongToByte(ulHeadLightR), ULongToByte(ulHeadLightG), ULongToByte(ulHeadLightB)); } } -void _declspec(naked) HOOK_CVehicle_DoHeadLightBeam_2() +static void __declspec(naked) HOOK_CVehicle_DoHeadLightBeam_2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov eax, [esp] mov pHeadLightVerts, eax @@ -5291,28 +5774,36 @@ void _declspec(naked) HOOK_CVehicle_DoHeadLightBeam_2() mov uiHeadLightNumVerts, eax pushad } + // clang-format on CVehicle_DoHeadLightBeam(); - _asm + // clang-format off + __asm { popad mov dword ptr ds:[0C4B950h],5 jmp RETURN_CVehicle_DoHeadLightBeam_2 } + // clang-format on } -DWORD dwCCoronas_RegisterCorona = 0x6FC580; -void _declspec(naked) HOOK_CVehicle_DoHeadLightEffect_1() +DWORD dwCCoronas_RegisterCorona = 0x6FC580; +static void __declspec(naked) HOOK_CVehicle_DoHeadLightEffect_1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on CVehicle_GetHeadLightColor(pLightsVehicleInterface, 160.0f, 160.0f, 140.0f); - _asm + // clang-format off + __asm { popad mov eax, ulHeadLightR @@ -5328,18 +5819,24 @@ void _declspec(naked) HOOK_CVehicle_DoHeadLightEffect_1() add esp,54h jmp RETURN_CVehicle_DoHeadLightEffect_1 } + // clang-format on } -void _declspec(naked) HOOK_CVehicle_DoHeadLightEffect_2() +static void __declspec(naked) HOOK_CVehicle_DoHeadLightEffect_2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on CVehicle_GetHeadLightColor(pLightsVehicleInterface, 160.0f, 160.0f, 140.0f); - _asm + // clang-format off + __asm { popad mov eax, ulHeadLightR @@ -5355,19 +5852,25 @@ void _declspec(naked) HOOK_CVehicle_DoHeadLightEffect_2() add esp, 54h jmp RETURN_CVehicle_DoHeadLightEffect_2 } + // clang-format on } -DWORD dwCShadows_StoreCarLightShadow = 0x70C500; -void _declspec(naked) HOOK_CVehicle_DoHeadLightReflectionTwin() +DWORD dwCShadows_StoreCarLightShadow = 0x70C500; +static void __declspec(naked) HOOK_CVehicle_DoHeadLightReflectionTwin() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on CVehicle_GetHeadLightColor(pLightsVehicleInterface, 45.0f, 45.0f, 45.0f); - _asm + // clang-format off + __asm { popad mov eax, ulHeadLightR @@ -5381,18 +5884,24 @@ void _declspec(naked) HOOK_CVehicle_DoHeadLightReflectionTwin() add esp, 4Ch jmp RETURN_CVehicle_DoHeadLightReflectionTwin } + // clang-format on } -void _declspec(naked) HOOK_CVehicle_DoHeadLightReflectionSingle() +static void __declspec(naked) HOOK_CVehicle_DoHeadLightReflectionSingle() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on CVehicle_GetHeadLightColor(pLightsVehicleInterface, 45.0f, 45.0f, 45.0f); - _asm + // clang-format off + __asm { popad mov eax, ulHeadLightR @@ -5406,6 +5915,7 @@ void _declspec(naked) HOOK_CVehicle_DoHeadLightReflectionSingle() add esp, 30h jmp RETURN_CVehicle_DoHeadLightReflectionSingle } + // clang-format on } #endif // ENABLE_VEHICLE_HEADLIGHT_COLOR @@ -5414,22 +5924,29 @@ void _declspec(naked) HOOK_CVehicle_DoHeadLightReflectionSingle() // Report fire damage, with correct inflictor entity -void _declspec(naked) HOOK_CWorld_SetWorldOnFire() +static void __declspec(naked) HOOK_CWorld_SetWorldOnFire() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // Actually pass the pCreatorEntity parameter that this function receives to CFireManager::StartFire // (instead of a null pointer) - _asm + // clang-format off + __asm { push 7000 push [esp+0x18+0x14] jmp RETURN_CWorld_SetWorldOnFire } + // clang-format on } -void _declspec(naked) HOOK_CTaskSimplePlayerOnFire_ProcessPed() +static void __declspec(naked) HOOK_CTaskSimplePlayerOnFire_ProcessPed() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // Actually pass the fire's pCreatorEntity to the damage event (instead of a null pointer) - _asm + // clang-format off + __asm { push 3 push 0x25 @@ -5439,12 +5956,16 @@ void _declspec(naked) HOOK_CTaskSimplePlayerOnFire_ProcessPed() push eax jmp RETURN_CTaskSimplePlayerOnFire_ProcessPed } + // clang-format on } -void _declspec(naked) HOOK_CFire_ProcessFire() +static void __declspec(naked) HOOK_CFire_ProcessFire() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // Set the new fire's creator to the original fire's creator - _asm + // clang-format off + __asm { mov eax, 0x53A450 // CCreepingFire::TryToStartFireAtCoors call eax @@ -5455,12 +5976,16 @@ void _declspec(naked) HOOK_CFire_ProcessFire() fail: jmp RETURN_CFire_ProcessFire } + // clang-format on } -void _declspec(naked) HOOK_CExplosion_Update() +static void __declspec(naked) HOOK_CExplosion_Update() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // Set the new fire's creator to the explosion's creator - _asm + // clang-format off + __asm { mov eax, 0x53A450 // CCreepingFire::TryToStartFireAtCoors call eax @@ -5471,12 +5996,16 @@ void _declspec(naked) HOOK_CExplosion_Update() fail: jmp RETURN_CExplosion_Update } + // clang-format on } -void _declspec(naked) HOOK_CWeapon_FireAreaEffect() +static void __declspec(naked) HOOK_CWeapon_FireAreaEffect() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // Set the new fire's creator to the weapon's owner - _asm + // clang-format off + __asm { mov eax, 0x53A450 // CCreepingFire::TryToStartFireAtCoors call eax @@ -5487,6 +6016,7 @@ void _declspec(naked) HOOK_CWeapon_FireAreaEffect() fail: jmp RETURN_CWeapon_FireAreaEffect } + // clang-format on } // --------------------------------------------------- @@ -5574,9 +6104,12 @@ void CPlantMgr_Render_Post() // and water is not drawn in front of above-water plants (eg if you're looking at a // lake through some high grass). -void _declspec(naked) HOOK_RenderScene_Plants() +static void __declspec(naked) HOOK_RenderScene_Plants() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad call CPlantMgr_Render_Pre @@ -5594,11 +6127,15 @@ void _declspec(naked) HOOK_RenderScene_Plants() popad ret } + // clang-format on } -void _declspec(naked) HOOK_RenderScene_end() +static void __declspec(naked) HOOK_RenderScene_end() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad call CPlantMgr_Render_Pre @@ -5620,6 +6157,7 @@ void _declspec(naked) HOOK_RenderScene_end() mov eax, 0x7113B0 jmp eax } + // clang-format on } bool _cdecl IsPlantBelowWater(float fPlantZ, float fWaterZ) @@ -5627,10 +6165,13 @@ bool _cdecl IsPlantBelowWater(float fPlantZ, float fWaterZ) return fPlantZ + 2.0f < fWaterZ; } -void _declspec(naked) HOOK_CPlantMgr_Render() +static void __declspec(naked) HOOK_CPlantMgr_Render() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // (bCamBelowWater, bRenderingBeforeWater) - _asm + // clang-format off + __asm { sub esp, 4 mov eax, esp @@ -5666,10 +6207,8 @@ void _declspec(naked) HOOK_CPlantMgr_Render() mov edx, edi fld ds:[0x8D12C0] jmp RETURN_CPlantMgr_Render_success - -fail: - jmp RETURN_CPlantMgr_Render_fail } + // clang-format on } /* This hook called from CEventHandler::ComputeKnockOffBikeResponse makes sure the @@ -5696,10 +6235,13 @@ void CEventHandler_ComputeKnockOffBikeResponse() pEvent->Destroy(); } -DWORD dw_CEventDamage_AffectsPed = 0x4b35a0; -void _declspec(naked) HOOK_CEventHandler_ComputeKnockOffBikeResponse() +DWORD dw_CEventDamage_AffectsPed = 0x4b35a0; +static void __declspec(naked) HOOK_CEventHandler_ComputeKnockOffBikeResponse() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov pBikeDamageInterface, ecx mov pBikePedInterface, edx @@ -5708,14 +6250,17 @@ void _declspec(naked) HOOK_CEventHandler_ComputeKnockOffBikeResponse() pushad } + // clang-format on CEventHandler_ComputeKnockOffBikeResponse(); - _asm + // clang-format off + __asm { popad call dw_CEventDamage_AffectsPed jmp RETURN_CEventHandler_ComputeKnockOffBikeResponse } + // clang-format on } CPedSAInterface* weaponSkillPed; @@ -5759,28 +6304,35 @@ bool CPed_GetWeaponSkill() return false; } -void _declspec(naked) HOOK_CPed_GetWeaponSkill() +static void __declspec(naked) HOOK_CPed_GetWeaponSkill() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov weaponSkillPed, ecx mov eax, [esp+4] mov weaponSkillWeapon, eax pushad } + // clang-format on if (CPed_GetWeaponSkill()) { - _asm + // clang-format off + __asm { popad mov al, weaponSkill retn 4 } + // clang-format on } else { - _asm + // clang-format off + __asm { popad push esi @@ -5788,6 +6340,7 @@ void _declspec(naked) HOOK_CPed_GetWeaponSkill() cmp esi, 16h jmp RETURN_CPed_GetWeaponSkill } + // clang-format on } } @@ -5800,9 +6353,12 @@ bool _cdecl CPed_AddGogglesModelCheck(void* pPedInterface) return pPed == pGameInterface->GetPools()->GetPedFromRef(1); } -void _declspec(naked) HOOK_CPed_AddGogglesModel() +static void __declspec(naked) HOOK_CPed_AddGogglesModel() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push esi call CPed_AddGogglesModelCheck @@ -5817,6 +6373,7 @@ void _declspec(naked) HOOK_CPed_AddGogglesModel() skip: jmp RETURN_CPed_AddGogglesModel } + // clang-format on } void CMultiplayerSA::DeleteAndDisableGangTags() @@ -5834,20 +6391,24 @@ void CMultiplayerSA::DeleteAndDisableGangTags() DWORD* pTagInterface = VAR_TagInfoArray[i << 1]; if (pTagInterface) { - _asm + // clang-format off + __asm { push pTagInterface call dwFunc add esp, 4 } + // clang-format on } } dwFunc = FUNC_CTagManager_ShutdownForRestart; - _asm + // clang-format off + __asm { call dwFunc } + // clang-format on // Disallow spraying gang tags // Nop the whole CTagManager::IsTag function and replace its body with: @@ -5896,29 +6457,36 @@ bool CPhysical_ProcessCollisionSectorList() return true; } -void _declspec(naked) HOOK_CPhysical_ProcessCollisionSectorList() +static void __declspec(naked) HOOK_CPhysical_ProcessCollisionSectorList() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov pCollisionPhysicalThis, esi mov pCollisionPhysical, edi pushad } + // clang-format on // Carry on with collision? (sets the CElement->bUsesCollision flag check) if (CPhysical_ProcessCollisionSectorList()) { - _asm + // clang-format off + __asm { popad mov ecx, [eax+4] test byte ptr [edi+1Ch], 1 jmp RETURN_CPhysical_ProcessCollisionSectorList } + // clang-format on } else { - _asm + // clang-format off + __asm { popad mov ecx, [eax+4] @@ -5927,6 +6495,7 @@ void _declspec(naked) HOOK_CPhysical_ProcessCollisionSectorList() mov edi, pCollisionPhysical jmp RETURN_CPhysical_ProcessCollisionSectorList } + // clang-format on } } @@ -5934,53 +6503,87 @@ void _declspec(naked) HOOK_CPhysical_ProcessCollisionSectorList() // Hack fix for now is to validate each matrix before it is used void _cdecl CheckMatrix(float* pMatrix) { - // Peek at IEEE 754 float data to quickly check if any element is outside range of -2 to 2 or is NaN - int* p = (int*)pMatrix; - int RotBits = p[0] | p[1] | p[2] | p[4] | p[5] | p[6] | p[8] | p[9] | p[10]; + if (!pMatrix) + return; - int PosBits = p[12] | p[13] | p[14]; + // Proper alignment for x86 performance + if (reinterpret_cast(pMatrix) % alignof(float) != 0) + return; + + union FloatIntUnion + { + float f; + uint32_t i; + }; - // If rotational part is outside -2 to 2 range, then flag fix + // Fast bit manipulation for performance + uint32_t* p = reinterpret_cast(pMatrix); + uint32_t RotBits = p[0] | p[1] | p[2] | p[4] | p[5] | p[6] | p[8] | p[9] | p[10]; + uint32_t PosBits = p[12] | p[13] | p[14]; + + // Range check bool bFix = (RotBits & 0x40000000) != 0; - // If positional part is outside -2 to 2 range, then do further check for -10 to 10 range - if (PosBits & 0x40000000) + // Position validation + if (!bFix && (PosBits & 0x40000000)) { - for (uint i = 12; i < 15; i++) + for (uint32_t i = 12; i < 15; i++) { float f = pMatrix[i]; - if (f < -10 || f > 10 || std::isnan(f)) + if (f < -10.0f || f > 10.0f || std::isnan(f)) + { bFix = true; + break; + } + } + } + + // Additional NaN/Infinity check only if needed + if (!bFix) + { + // Only check the elements that matter for animation matrices + uint32_t indices[] = {0, 1, 2, 4, 5, 6, 8, 9, 10}; + for (uint32_t i = 0; i < 9; i++) + { + float f = pMatrix[indices[i]]; + if (std::isnan(f) || std::isinf(f)) + { + bFix = true; + break; + } } } - // Fix if required if (bFix) { + // Use 0.0f scale to disable corrupted animations float scale = 0.0f; pMatrix[0] = scale; - pMatrix[1] = 0; - pMatrix[2] = 0; - - pMatrix[4] = 0; + pMatrix[1] = 0.0f; + pMatrix[2] = 0.0f; + pMatrix[4] = 0.0f; pMatrix[5] = scale; - pMatrix[6] = 0; + pMatrix[6] = 0.0f; + pMatrix[8] = 0.0f; + pMatrix[9] = 0.0f; + pMatrix[10] = scale; // This one was missing for a long time (pre-Sept 2025) + pMatrix[12] = 0.0f; + pMatrix[13] = 0.0f; + pMatrix[14] = 1.0f; - pMatrix[7] = 0; - pMatrix[8] = 0; - pMatrix[10] = scale; - - pMatrix[12] = 0; - pMatrix[13] = 0; - pMatrix[14] = 1; + // For x86 cache efficiency + std::atomic_thread_fence(std::memory_order_release); } } // hooked at 7C5A5C 5 bytes -void _declspec(naked) HOOK_CheckAnimMatrix() +static void __declspec(naked) HOOK_CheckAnimMatrix() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Replaced code lea ecx, [esp+054h] @@ -5996,6 +6599,7 @@ void _declspec(naked) HOOK_CheckAnimMatrix() push eax jmp RETURN_CheckAnimMatrix // 7C5A61 } + // clang-format on } static SColor vehColors[4]; @@ -6010,9 +6614,12 @@ void _cdecl SaveVehColors(DWORD dwThis) } } -void _declspec(naked) HOOK_VehCol() +static void __declspec(naked) HOOK_VehCol() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Get vehColors for this vehicle pushad @@ -6032,11 +6639,15 @@ void _declspec(naked) HOOK_VehCol() jmp RETURN_VehCol // 006D660C } + // clang-format on } -void _declspec(naked) HOOK_VehColCB() +static void __declspec(naked) HOOK_VehColCB() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Hooked from 004C838D 29 bytes @@ -6052,6 +6663,7 @@ void _declspec(naked) HOOK_VehColCB() jmp RETURN_VehColCB // 004C83AA } + // clang-format on } // Check if this vehicle is allowed to process swinging doors. @@ -6068,30 +6680,38 @@ static bool AllowSwingingDoors() return false; } -void _declspec(naked) HOOK_CAutomobile__ProcessSwingingDoor() +static void __declspec(naked) HOOK_CAutomobile__ProcessSwingingDoor() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov dwSwingingDoorAutomobile, esi mov ecx, [esi+eax*4+0x648] pushad } + // clang-format on if (AllowSwingingDoors()) { - _asm + // clang-format off + __asm { popad jmp dwSwingingRet1 } + // clang-format on } else { - _asm + // clang-format off + __asm { popad jmp dwSwingingRet2 } + // clang-format on } } @@ -6099,14 +6719,39 @@ void* SetModelSuspensionLinesToVehiclePrivate(CVehicleSAInterface* pVehicleIntf) { // Set the per-model suspension line data of the vehicle's model to the per-vehicle // suspension line data so that collision processing will use that instead. - CVehicle* pVehicle = pVehicleIntf->m_pVehicle; + CVehicle* pVehicle = pVehicleIntf->m_pVehicle; + if (!pVehicle) + return nullptr; + CModelInfo* pModelInfo = pGameInterface->GetModelInfo(pVehicle->GetModelIndex()); - return pModelInfo->SetVehicleSuspensionData(pVehicle->GetPrivateSuspensionLines()); + if (!pModelInfo) + return nullptr; + + void* pOriginalSuspensionLines = pModelInfo->GetVehicleSuspensionData(); + if (!pOriginalSuspensionLines) + return nullptr; + + void* pPrivateSuspensionLines = pVehicle->GetPrivateSuspensionLines(); + if (!pPrivateSuspensionLines) + return nullptr; + + pModelInfo->SetVehicleSuspensionData(pPrivateSuspensionLines); + return pOriginalSuspensionLines; } void SetModelSuspensionLines(CVehicleSAInterface* pVehicleIntf, void* pSuspensionLines) { - CModelInfo* pModelInfo = pGameInterface->GetModelInfo(pVehicleIntf->m_pVehicle->GetModelIndex()); + if (!pVehicleIntf || !pSuspensionLines) + return; + + CVehicle* pVehicle = pVehicleIntf->m_pVehicle; + if (!pVehicle) + return; + + CModelInfo* pModelInfo = pGameInterface->GetModelInfo(pVehicle->GetModelIndex()); + if (!pModelInfo) + return; + pModelInfo->SetVehicleSuspensionData(pSuspensionLines); } // Some variables. @@ -6124,7 +6769,7 @@ bool CheckHasSuspensionChanged() return false; CModelInfo* pModelInfo = pGameInterface->GetModelInfo(pVehicle->GetModelIndex()); - if (pModelInfo && (pModelInfo->IsCar() || pModelInfo->IsMonsterTruck())) + if (pModelInfo && pModelInfo->GetInterface() && (pModelInfo->IsCar() || pModelInfo->IsMonsterTruck())) return true; else return false; @@ -6132,20 +6777,26 @@ bool CheckHasSuspensionChanged() else return false; } -void _declspec(naked) HOOK_ProcessVehicleCollision() + +static void __declspec(naked) HOOK_ProcessVehicleCollision() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov pSuspensionInterface, esi pushad } + // clang-format on if (CheckHasSuspensionChanged()) { // When the vehicle's collision is about to be processed, set its per-vehicle // suspension lines as the per-model suspension lines, and restore the per-model lines // afterwards - _asm + // clang-format off + __asm { popad push esi @@ -6178,15 +6829,18 @@ void _declspec(naked) HOOK_ProcessVehicleCollision() pop eax ret } + // clang-format on } else { // Skip our code in this case because they haven't changed anything so it'l just cause problems. - _asm + // clang-format off + __asm { popad jmp dwSuspensionChangedJump } + // clang-format on } } @@ -6213,7 +6867,7 @@ bool CheckRemovedModelNoSet() if (pBuildingRemoval) { // Is the model in question even removed? - if (pBuildingRemoval->IsModelRemoved(pEntityWorldAdd->m_nModelIndex)) + if (pBuildingRemoval->IsModelRemoved(static_cast(pEntityWorldAdd->m_nModelIndex))) { // is the replaced model in the spherical radius of any building removal if (pGameInterface->GetBuildingRemoval()->IsRemovedModelInRadius(pEntityWorldAdd)) @@ -6238,23 +6892,29 @@ bool CheckRemovedModel() // Binary // Hook 1 -void _declspec(naked) HOOK_LoadIPLInstance() +static void __declspec(naked) HOOK_LoadIPLInstance() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pEntityWorldAdd, ecx } + // clang-format on if (pEntityWorldAdd) { CheckRemovedModel(); } - _asm + // clang-format off + __asm { popad jmp CALL_LoadIPLInstance jmp RETURN_LoadIPLInstance } + // clang-format on } static bool bTest = false; // Binary @@ -6273,7 +6933,7 @@ void HideEntitySomehow() (pInterface->nType == ENTITY_TYPE_BUILDING || pInterface->nType == ENTITY_TYPE_DUMMY)) { // Add the LOD to the list - pBuildingRemoval->AddBinaryBuilding(pInterface); + pBuildingRemoval->AddBinaryBuilding(pInterface, pInterface->m_iplIndex); // Remove the model from the world pGameInterface->GetWorld()->Remove(pInterface, BuildingRemoval); // Get next LOD ( LOD's can have LOD's so we keep checking pInterface ) @@ -6297,19 +6957,25 @@ void HideEntitySomehow() } // Binary // Hook 2 -void _declspec(naked) HOOK_CWorld_LOD_SETUP() +static void __declspec(naked) HOOK_CWorld_LOD_SETUP() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pLODInterface, esi } + // clang-format on HideEntitySomehow(); - _asm + // clang-format off + __asm { popad jmp CALL_CWorld_LODSETUP } + // clang-format on } CEntitySAInterface* pBuildingAdd = NULL; @@ -6323,19 +6989,25 @@ void StorePointerToBuilding() // Called when a data entity is added to the world (this happens once when the game loads so we just dump those in a list and we can sift through when someone // tries to remove.) -void _declspec(naked) Hook_AddBuildingInstancesToWorld() +static void __declspec(naked) Hook_AddBuildingInstancesToWorld() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pBuildingAdd, edx } + // clang-format on StorePointerToBuilding(); - _asm + // clang-format off + __asm { popad jmp JMP_CWorld_Add_AddBuildingInstancesToWorld_CALL_CWorldAdd } + // clang-format on } bool CheckForRemoval() @@ -6355,21 +7027,27 @@ bool CheckForRemoval() } // Call to CWorld::Add in CPopulation::ConvertToRealObject we just use this to get a list of pointers to valid objects for instant removal -void _declspec(naked) Hook_CWorld_ADD_CPopulation_ConvertToRealObject() +static void __declspec(naked) Hook_CWorld_ADD_CPopulation_ConvertToRealObject() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pBuildingAdd, esi mov pLODInterface, esi } + // clang-format on StorePointerToBuilding(); - _asm + // clang-format off + __asm { popad jmp JMP_CWorld_Add_CPopulation_ConvertToRealObject_CallCWorldAdd jmp JMP_CWorld_Add_CPopulation_ConvertToRealObject_Retn } + // clang-format on } void RemoveObjectIfNeeded() @@ -6380,13 +7058,13 @@ void RemoveObjectIfNeeded() { if (!pBuildingAdd->IsPlaceableVTBL()) { - pBuildingRemoval->AddDataBuilding(pBuildingAdd); + pBuildingRemoval->AddDataBuilding(pBuildingAdd, pBuildingAdd->m_iplIndex); pGameInterface->GetWorld()->Remove(pBuildingAdd, BuildingRemoval3); } if (!pLODInterface->IsPlaceableVTBL()) { - pBuildingRemoval->AddDataBuilding(pLODInterface); + pBuildingRemoval->AddDataBuilding(pLODInterface, pLODInterface->m_iplIndex); pGameInterface->GetWorld()->Remove(pLODInterface, BuildingRemoval4); } } @@ -6394,15 +7072,20 @@ void RemoveObjectIfNeeded() } // on stream in -> create and remove it from the world just after so we can restore easily -void _declspec(naked) HOOK_ConvertToObject_CPopulationManageDummy() +static void __declspec(naked) HOOK_ConvertToObject_CPopulationManageDummy() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pBuildingAdd, edx mov pLODInterface, edx } - _asm + // clang-format on + // clang-format off + __asm { popad push edx @@ -6410,13 +7093,15 @@ void _declspec(naked) HOOK_ConvertToObject_CPopulationManageDummy() pop ecx mov pLODInterface, ecx pushad - } + } // clang-format on RemoveObjectIfNeeded(); - _asm + // clang-format off + __asm { popad jmp JMP_RETN_Cancel_CPopulation_ManageDummy } + // clang-format on } CEntitySAInterface* pBuildingRemove = NULL; @@ -6428,18 +7113,8 @@ void RemovePointerToBuilding() } } -DWORD dwCWorldRemove = 0x563280; -// Call to CWorld::Remove in CPopulation::ConvertToDummyObject this is called just before deleting a CObject so we remove the CObject while we are there and -// remove the new dummy if we need to do so before returning -void _declspec(naked) HOOK_CWorld_Remove_CPopulation_ConvertToDummyObject() +static void RemovePointerToBuildingWithTiming() { - _asm - { - pushad - mov pBuildingRemove, esi - mov pBuildingAdd, edi - mov pLODInterface, edi - } TIMING_CHECKPOINT("+RemovePointerToBuilding"); RemovePointerToBuilding(); StorePointerToBuilding(); @@ -6450,12 +7125,30 @@ void _declspec(naked) HOOK_CWorld_Remove_CPopulation_ConvertToDummyObject() RemoveObjectIfNeeded(); TIMING_CHECKPOINT("-RemovePointerToBuilding"); - _asm +} + +DWORD dwCWorldRemove = 0x563280; +// Call to CWorld::Remove in CPopulation::ConvertToDummyObject this is called just before deleting a CObject so we remove the CObject while we are there and +// remove the new dummy if we need to do so before returning +static void __declspec(naked) HOOK_CWorld_Remove_CPopulation_ConvertToDummyObject() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { + pushad + mov pBuildingRemove, esi + mov pBuildingAdd, edi + mov pLODInterface, edi + call RemovePointerToBuildingWithTiming popad - jmp dwCWorldRemove + + jmp dwCWorldRemove } + // clang-format on } + // if it's replaced get rid of it void RemoveDummyIfReplaced() { @@ -6464,99 +7157,121 @@ void RemoveDummyIfReplaced() { if (!pBuildingAdd->IsPlaceableVTBL()) { - pBuildingRemoval->AddDataBuilding(pBuildingAdd); + pBuildingRemoval->AddDataBuilding(pBuildingAdd, pBuildingAdd->m_iplIndex); pGameInterface->GetWorld()->Remove(pBuildingAdd, BuildingRemoval5); } } } +static bool CheckForRemovalWithTiming() +{ + TIMING_CHECKPOINT("+CheckForRemoval"); + StorePointerToBuilding(); + bool result = CheckForRemoval(); + TIMING_CHECKPOINT("-CheckForRemoval"); + return result; +} + // Function that handles dummy -> object so we can cancel this process if need be -void _declspec(naked) HOOK_CWorld_Add_CPopulation_ConvertToDummyObject() +static void __declspec(naked) HOOK_CWorld_Add_CPopulation_ConvertToDummyObject() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad - mov pLODInterface, edi - mov pBuildingAdd, edi - } + mov pLODInterface, edi + mov pBuildingAdd, edi - TIMING_CHECKPOINT("+CheckForRemoval"); - StorePointerToBuilding(); - if (CheckForRemoval()) - { - TIMING_CHECKPOINT("-CheckForRemoval"); - _asm - { - popad - jmp JMP_RETN_Cancelled_CPopulation_ConvertToDummyObject - } - } - else - { - TIMING_CHECKPOINT("-CheckForRemoval"); - _asm - { - popad - push edi - call CALL_CWorld_Add_CPopulation_ConvertToDummyObject - jmp JMP_RETN_Called_CPopulation_ConvertToDummyObject - } + call CheckForRemovalWithTiming + test al, al + popad + jz continueWithOriginalCode + jmp JMP_RETN_Cancelled_CPopulation_ConvertToDummyObject + + continueWithOriginalCode: + push edi + call CALL_CWorld_Add_CPopulation_ConvertToDummyObject + jmp JMP_RETN_Called_CPopulation_ConvertToDummyObject } + // clang-format on } // Destructors to catch element deletion so we can delete their entries -void _declspec(naked) Hook_CBuilding_DTR() +static void __declspec(naked) Hook_CBuilding_DTR() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pBuildingRemove, ecx } + // clang-format on RemovePointerToBuilding(); - _asm + // clang-format off + __asm { popad jmp JMP_CBuilding_DTR } + // clang-format on } -void _declspec(naked) Hook_CDummy_DTR() +static void __declspec(naked) Hook_CDummy_DTR() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pBuildingRemove, ecx } + // clang-format on RemovePointerToBuilding(); - _asm + // clang-format off + __asm { popad jmp JMP_CDummy_DTR } + // clang-format on } -DWORD dwObjectVtbl = 0x866F60; -void _declspec(naked) Hook_CObject_DTR() +DWORD dwObjectVtbl = 0x866F60; +static void __declspec(naked) Hook_CObject_DTR() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pBuildingRemove, esi } + // clang-format on RemovePointerToBuilding(); - _asm + // clang-format off + __asm { popad mov dword ptr [esi], offset dwObjectVtbl jmp JMP_CObject_DTR } + // clang-format on } -static DWORD dwEntityVtbl; -static DWORD dwMultResult; -void _declspec(naked) HOOK_CEntity_IsOnScreen_FixObjectScale() +static DWORD dwEntityVtbl; +static DWORD dwMultResult; +static void __declspec(naked) HOOK_CEntity_IsOnScreen_FixObjectScale() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push 0xB6FA74 @@ -6564,18 +7279,22 @@ void _declspec(naked) HOOK_CEntity_IsOnScreen_FixObjectScale() mov eax, [esi] mov dwEntityVtbl, eax } + // clang-format on if (dwEntityVtbl == 0x866F60) goto IsOnScreen_IsObject; - _asm + // clang-format off + __asm { popad mov esi, ecx jmp JMP_CEntity_IsOnScreen_FixObjectsScale } + // clang-format on -IsOnScreen_IsObject: - _asm + IsOnScreen_IsObject : + // clang-format off + __asm { popad fld [eax+0x24] @@ -6585,14 +7304,18 @@ void _declspec(naked) HOOK_CEntity_IsOnScreen_FixObjectScale() mov esi, dwMultResult jmp JMP_CEntity_IsOnScreen_FixObjectsScale } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// // Only allow rebuild player on CJ - Stops other models getting corrupted (spider CJ) // hooked at 5A82C0 8 bytes -void _declspec(naked) HOOK_CClothes_RebuildPlayer() +static void __declspec(naked) HOOK_CClothes_RebuildPlayer() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push esi mov esi, [esp+8] @@ -6607,19 +7330,24 @@ void _declspec(naked) HOOK_CClothes_RebuildPlayer() cont: jmp RETURN_CClothes_RebuildPlayerb // 005A837F } + // clang-format on } -void _declspec(naked) HOOK_CProjectileInfo_Update_FindLocalPlayer_FindLocalPlayerVehicle() +static void __declspec(naked) HOOK_CProjectileInfo_Update_FindLocalPlayer_FindLocalPlayerVehicle() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // 00739559 E8 B2 4C E3 FF call FindPlayerPed < HOOK > // 00739570 E8 5B 4B E3 FF call FindPlayerVehicle < HOOK > // Checks if the creator is the local player ped or the creator is the local player peds vehicle else decreases the velocity substantially. // We are forcing it to think the creator is not the local player ped or his vehicle for this specific check - _asm + // clang-format off + __asm { xor eax, eax retn } + // clang-format on } void CMultiplayerSA::SetAutomaticVehicleStartupOnPedEnter(bool bSet) @@ -6648,8 +7376,8 @@ void CMultiplayerSA::SetVehicleEngineAutoStartEnabled(bool enabled) } else { - MemSet((void*)0x64BC03, 0x90, 5); // prevent vehicle engine from turning on (driver enter) - MemCpy((void*)0x6C4EA9, "\xE9\x15\x03\x00", 4); // prevent aircraft engine from turning off (driver exit) + MemSet((void*)0x64BC03, 0x90, 5); // prevent vehicle engine from turning on (driver enter) + MemCpy((void*)0x6C4EA9, "\xE9\x15\x03\x00", 4); // prevent aircraft engine from turning off (driver exit) } } @@ -6668,8 +7396,10 @@ bool CallHeliKillEvent() return true; } -void _declspec(naked) HOOK_CHeli_ProcessHeliKill() +static void __declspec(naked) HOOK_CHeli_ProcessHeliKill() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // 006DB201 0F 85 30 02 00 00 jnz loc_6DB437 < HOOK > // 006DB207 8B 47 14 mov eax, [edi+14h] < RETURN CONTINUE > // 006DB9E0 8B 44 24 6C mov eax, [esp+1C8h+var_15C] < RETURN CANCEL > @@ -6677,27 +7407,32 @@ void _declspec(naked) HOOK_CHeli_ProcessHeliKill() // We hook just after the check if he's touched the blade as before that it's just got the results of if he's near enough the heli to hit the blades // esi = Heli // edi = ped - _asm + // clang-format off + __asm { pushfd pushad mov pHeliKiller, esi mov pHitByHeli, edi } + // clang-format on // Call our event if (CallHeliKillEvent() == false) { - _asm + // clang-format off + __asm { popad popfd // Go to the end of the while loop and let it start again jmp RETURN_CHeli_ProcessHeliKill_RETN_Cancel } + // clang-format on } else { - _asm + // clang-format off + __asm { popad popfd @@ -6708,6 +7443,7 @@ void _declspec(naked) HOOK_CHeli_ProcessHeliKill() lp1: jmp RETURN_CHeli_ProcessHeliKill_6DB437h } + // clang-format on } } @@ -6728,41 +7464,49 @@ bool TriggerObjectDamageEvent() return true; } -void _declspec(naked) HOOK_CObject_ProcessDamage() +static void __declspec(naked) HOOK_CObject_ProcessDamage() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // .text:005A0DF7 mov ecx, [esi+160h] // .text:005A0DFD fld [esp+0D4h+arg_0] // .text:005A0E04 fmul dword ptr [ecx+18h] // .text:005A0E07 fsubr dword ptr [esi+154h] // .text:005A0E0D fst dword ptr [esi+154h] - _asm + // clang-format off + __asm { pushad mov pDamagedObject, esi mov pObjectAttacker, edi fst dword ptr fNewObjectHealth } + // clang-format on if (TriggerObjectDamageEvent()) { bObjectDamaged = true; - _asm + // clang-format off + __asm { popad fst dword ptr [esi+154h] jmp RETURN_CObject_ProcessDamage } + // clang-format on } else { bObjectDamaged = false; - _asm + // clang-format off + __asm { popad ffree st(0) fdecstp jmp RETURN_CObject_ProcessDamage_Cancel } + // clang-format on } } @@ -6776,12 +7520,16 @@ bool TriggerObjectBreakEvent() return true; } -void _declspec(naked) HOOK_CObject_ProcessBreak() +static void __declspec(naked) HOOK_CObject_ProcessBreak() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on ucColDamageEffect = *(unsigned char*)((DWORD)pDamagedObject + 324); if (ucColDamageEffect != NULL) @@ -6791,28 +7539,35 @@ void _declspec(naked) HOOK_CObject_ProcessBreak() if (!TriggerObjectBreakEvent()) { bObjectDamaged = false; - _asm + // clang-format off + __asm { popad jmp RETURN_CObject_ProcessDamage_Cancel } + // clang-format on } } } - _asm + // clang-format off + __asm { popad cmp eax, 0C9h jmp RETURN_CObject_ProcessBreak } + // clang-format on } -void _declspec(naked) HOOK_CObject_ProcessCollision() +static void __declspec(naked) HOOK_CObject_ProcessCollision() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + if (bObjectDamaged) { - _asm + // clang-format off + __asm { test byte ptr [esi+1Ch], 1 jnz checkfordynamic @@ -6821,35 +7576,44 @@ void _declspec(naked) HOOK_CObject_ProcessCollision() checkfordynamic: jmp JMP_DynamicObject_Cond_Zero } + // clang-format on } else { - _asm + // clang-format off + __asm { jmp RETURN_CObject_ProcessCollision } + // clang-format on } } -DWORD WindowRespondsToCollision_CalledFrom = 0; -void _declspec(naked) HOOK_CGlass_WindowRespondsToCollision() +DWORD WindowRespondsToCollision_CalledFrom = 0; +static void __declspec(naked) HOOK_CGlass_WindowRespondsToCollision() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push eax mov eax, [esp + 4] mov WindowRespondsToCollision_CalledFrom, eax pop eax } + // clang-format on pObjectAttacker = nullptr; if (WindowRespondsToCollision_CalledFrom != CALL_FROM_CGlass_WindowRespondsToExplosion) { - _asm + // clang-format off + __asm { mov pDamagedObject, esi } + // clang-format on } // Get attacker for the glass break @@ -6857,67 +7621,82 @@ void _declspec(naked) HOOK_CGlass_WindowRespondsToCollision() WindowRespondsToCollision_CalledFrom == CALL_FROM_CPhysical_ApplyCollision_2 || WindowRespondsToCollision_CalledFrom == CALL_FROM_CPhysical_ApplySoftCollision) { - _asm + // clang-format off + __asm { mov pObjectAttacker, edi } + // clang-format on } if (WindowRespondsToCollision_CalledFrom == CALL_FROM_CGlass_WasGlassHitByBullet) { - _asm + // clang-format off + __asm { mov pObjectAttacker, ebx // WasGlassHitByBullet called from CWeapon::DoBulletImpact } + // clang-format on - if (!pObjectAttacker || (pObjectAttacker && !pObjectAttacker->m_pRwObject)) // WasGlassHitByBullet called from CBulletInfo::Update + if (!pObjectAttacker || (pObjectAttacker && !pObjectAttacker->m_pRwObject)) // WasGlassHitByBullet called from CBulletInfo::Update { - _asm + // clang-format off + __asm { push ecx mov ecx, [edi] mov pObjectAttacker, ecx pop ecx } + // clang-format on } } if (WindowRespondsToCollision_CalledFrom == CALL_FROM_CGlass_WindowRespondsToExplosion) { - _asm + // clang-format off + __asm { mov pDamagedObject, edx mov pObjectAttacker, ebp } + // clang-format on } - if (pObjectAttacker && !pObjectAttacker->m_pRwObject) // Still wrong? + if (pObjectAttacker && !pObjectAttacker->m_pRwObject) // Still wrong? pObjectAttacker = nullptr; if (TriggerObjectBreakEvent()) { - _asm + // clang-format off + __asm { sub esp, 68h push esi mov esi, [esp+6Ch+4] jmp RETURN_CGlass_WindowRespondsToCollision } + // clang-format on } else { - _asm + // clang-format off + __asm { retn } + // clang-format on } } // Called when glass object is being broken by ped melee attack -DWORD dummy_404350 = 0x404350; -void _declspec(naked) HOOK_CGlass__BreakGlassPhysically() +DWORD dummy_404350 = 0x404350; +static void __declspec(naked) HOOK_CGlass__BreakGlassPhysically() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov pDamagedObject, esi push ecx @@ -6925,20 +7704,24 @@ void _declspec(naked) HOOK_CGlass__BreakGlassPhysically() mov pObjectAttacker, ecx pop ecx } + // clang-format on if (TriggerObjectBreakEvent()) { - _asm + // clang-format off + __asm { // restore replaced part push dummy_404350 // jump outside of the hook jmp RETURN_CGlass__BreakGlassPhysically } + // clang-format on } else { - _asm + // clang-format off + __asm { pop edi pop esi @@ -6947,6 +7730,7 @@ void _declspec(naked) HOOK_CGlass__BreakGlassPhysically() add esp, 0BCh retn } + // clang-format on } } @@ -6959,17 +7743,22 @@ void FxManager_c__DestroyFxSystem() } } -void _declspec(naked) HOOK_FxManager_c__DestroyFxSystem() +static void __declspec(naked) HOOK_FxManager_c__DestroyFxSystem() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov pFxSystemToBeDestroyed, edi pushad } + // clang-format on FxManager_c__DestroyFxSystem(); - _asm + // clang-format off + __asm { popad @@ -6980,6 +7769,7 @@ void _declspec(naked) HOOK_FxManager_c__DestroyFxSystem() pop ecx retn 4 } + // clang-format on } DWORD pProcessedGangDriveBySimpleTask; @@ -6992,17 +7782,22 @@ void CTaskSimpleGangDriveBy__ProcessPed() *pRequiredAnim = m_pDrivebyAnimationHandler(*pRequiredAnim, requiredAnimGroup); } -DWORD RETURN_CTaskSimpleGangDriveBy_ProcessPed_Cancel = 0x62D5C1; -void _declspec(naked) HOOK_CTaskSimpleGangDriveBy__ProcessPed() +DWORD RETURN_CTaskSimpleGangDriveBy_ProcessPed_Cancel = 0x62D5C1; +static void __declspec(naked) HOOK_CTaskSimpleGangDriveBy__ProcessPed() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // esi contains 'this' - _asm + // clang-format off + __asm { mov pProcessedGangDriveBySimpleTask, esi pushad } + // clang-format on CTaskSimpleGangDriveBy__ProcessPed(); - _asm + // clang-format off + __asm { popad // Replaced code @@ -7014,6 +7809,7 @@ void _declspec(naked) HOOK_CTaskSimpleGangDriveBy__ProcessPed() GangDriveBy_ProcessPed_Cancel: jmp RETURN_CTaskSimpleGangDriveBy_ProcessPed_Cancel } + // clang-format on } eRadioStationID dwStationID = UNKNOWN; @@ -7021,17 +7817,17 @@ BYTE bTrackID = 0; DWORD dwNumberOfTracks = 0; const DWORD pTrackNumbers[] = { - 0x2, // radio off, somewhere 2 is subtracted from this so that's why it's 2 - 0xB, // playback fm - 0xF, // k-rose - 0xF, // k-dst - 0xE, // bounce fm - 0x10, // sf-ur - 0xE, // rls - 0xD, // radio x - 0xD, // csr - 0xE, // k-jah - 0xC, // master sounds + 0x2, // radio off, somewhere 2 is subtracted from this so that's why it's 2 + 0xB, // playback fm + 0xF, // k-rose + 0xF, // k-dst + 0xE, // bounce fm + 0x10, // sf-ur + 0xE, // rls + 0xD, // radio x + 0xD, // csr + 0xE, // k-jah + 0xC, // master sounds 0x1F, }; @@ -7185,23 +7981,28 @@ bool ChooseMusicTrackIndex_SteamFix() These are as a result of the fact that steam updated gta-sa.exe and gta_sa.exe is our old exe which contains the arrays the game had originally for audio files All the files related to the deleted audio are zeroed and decompress to 5kb 0 length files which includes intros and outros. */ -void _declspec(naked) HOOK_CAERadioTrackManager__ChooseMusicTrackIndex() +static void __declspec(naked) HOOK_CAERadioTrackManager__ChooseMusicTrackIndex() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // esi is our station id // al has the random number picked (music id the game wants to play) - _asm + // clang-format off + __asm { add esp, 8 // fix the stack from the function call above as we overrote this instruction pushad // save our registers mov dwStationID, esi // save esi, we need the station ID above mov bTrackID, al // save our track ID which we need to figure out if we can play it. } + // clang-format on // returns true if this is a restricted song if (ChooseMusicTrackIndex_SteamFix()) { - _asm + // clang-format off + __asm { // pop the stack popad @@ -7210,9 +8011,11 @@ void _declspec(naked) HOOK_CAERadioTrackManager__ChooseMusicTrackIndex() // as such generating a new ID is better than trying to fix it (this is how the game naturally works anyway) jmp RETURN_CAERadioTrackManager__ChooseMusicTrackIndex_Regenerate } + // clang-format on } // looks good, carry on - _asm + // clang-format off + __asm { // pop the stack popad @@ -7221,12 +8024,16 @@ void _declspec(naked) HOOK_CAERadioTrackManager__ChooseMusicTrackIndex() // jump back to normal processing jmp RETURN_CAERadioTrackManager__ChooseMusicTrackIndex } + // clang-format on } // Use AI heli rotor sound if player sound bank is not loaded -void _declspec(naked) HOOK_CAEVehicleAudioEntity__ProcessDummyHeli() +static void __declspec(naked) HOOK_CAEVehicleAudioEntity__ProcessDummyHeli() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // push our argument push [esp+8Ch+4] @@ -7236,12 +8043,16 @@ void _declspec(naked) HOOK_CAEVehicleAudioEntity__ProcessDummyHeli() // go back jmp RETURN_CAEVEhicleAudioEntity__ProcessDummyHeli } + // clang-format on } // Use AI plane propeller sound if player sound bank is not loaded -void _declspec(naked) HOOK_CAEVehicleAudioEntity__ProcessDummyProp() +static void __declspec(naked) HOOK_CAEVehicleAudioEntity__ProcessDummyProp() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // push our argument push [esp+98h+4] @@ -7251,12 +8062,16 @@ void _declspec(naked) HOOK_CAEVehicleAudioEntity__ProcessDummyProp() // go back jmp RETURN_CAEVEhicleAudioEntity__ProcessDummyProp } + // clang-format on } -const float kfTimeStepOriginal = 1.66f; -void _declspec(naked) HOOK_CTaskSimpleSwim_ProcessSwimmingResistance() +const float kfTimeStepOriginal = 1.66f; +static void __declspec(naked) HOOK_CTaskSimpleSwim_ProcessSwimmingResistance() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { fsub st, st(1) @@ -7284,6 +8099,7 @@ void _declspec(naked) HOOK_CTaskSimpleSwim_ProcessSwimmingResistance() jmp RETURN_CTaskSimpleSwim_ProcessSwimmingResistance } + // clang-format on } void PostCWorld_ProcessPedsAfterPreRender() @@ -7314,15 +8130,19 @@ void PostCWorld_ProcessPedsAfterPreRender() } } -const DWORD CWorld_ProcessPedsAfterPreRender = 0x563430; -void _declspec(naked) HOOK_Idle_CWorld_ProcessPedsAfterPreRender() +const DWORD CWorld_ProcessPedsAfterPreRender = 0x563430; +static void __declspec(naked) HOOK_Idle_CWorld_ProcessPedsAfterPreRender() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off __asm { call CWorld_ProcessPedsAfterPreRender call PostCWorld_ProcessPedsAfterPreRender jmp RETURN_Idle_CWorld_ProcessPedsAfterPreRender } + // clang-format on } DWORD dwLastRequestedStation = -1; @@ -7339,9 +8159,12 @@ void CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_ChangeStation(DWORD } // Start radio after entering audio zone -void _declspec(naked) HOOK_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_StartRadio() +static void __declspec(naked) HOOK_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_StartRadio() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push [esi+3] call CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_ChangeStation @@ -7353,12 +8176,16 @@ void _declspec(naked) HOOK_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume add esp, 36 retn } + // clang-format on } // Stop radio after leaving audio zone -void _declspec(naked) HOOK_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_StopRadio() +static void __declspec(naked) HOOK_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_StopRadio() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push 0 call CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_ChangeStation @@ -7370,6 +8197,7 @@ void _declspec(naked) HOOK_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume add esp, 36 retn } + // clang-format on } static void AddVehicleColoredDebris(CAutomobileSAInterface* pVehicleInterface, CVector& vecPosition, int count) @@ -7381,18 +8209,34 @@ static void AddVehicleColoredDebris(CAutomobileSAInterface* pVehicleInterface, C SColor colors[4]; pVehicle->GetColor(&colors[0], &colors[1], &colors[2], &colors[3], false); - RwColor color = {colors[0].R * pVehicleInterface->m_fLighting, colors[0].G * pVehicleInterface->m_fLighting, - colors[0].B * pVehicleInterface->m_fLighting, 0xFF}; + const float fLighting = pVehicleInterface->m_fLighting; + const auto ClampFloatToByte = [](float value) -> unsigned char + { + if (value <= 0.0f) + return 0; + if (value >= 255.0f) + return 255; + return static_cast(value); + }; + + RwColor color; + color.r = ClampFloatToByte(static_cast(colors[0].R) * fLighting); + color.g = ClampFloatToByte(static_cast(colors[0].G) * fLighting); + color.b = ClampFloatToByte(static_cast(colors[0].B) * fLighting); + color.a = 0xFF; // Fx_c::AddDebris ((void(__thiscall*)(int, CVector&, RwColor&, float, int))0x49F750)(CLASS_CFx, vecPosition, color, 0.06f, count / 100 + 1); } } -const DWORD RETURN_CAutomobile__dmgDrawCarCollidingParticles = 0x6A7081; -void _declspec(naked) HOOK_CAutomobile__dmgDrawCarCollidingParticles() +const DWORD RETURN_CAutomobile__dmgDrawCarCollidingParticles = 0x6A7081; +static void __declspec(naked) HOOK_CAutomobile__dmgDrawCarCollidingParticles() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { lea eax, [esp + 0x1C] push ebp // count @@ -7403,6 +8247,7 @@ void _declspec(naked) HOOK_CAutomobile__dmgDrawCarCollidingParticles() jmp RETURN_CAutomobile__dmgDrawCarCollidingParticles } + // clang-format on } // Reimplement camera photo creation @@ -7412,10 +8257,13 @@ static void TakePhotograph() g_pCore->InitiateScreenShot(true); } -const DWORD RETURN_CWeapon__TakePhotograph = 0x73C273; -void _declspec(naked) HOOK_CWeapon__TakePhotograph() +const DWORD RETURN_CWeapon__TakePhotograph = 0x73C273; +static void __declspec(naked) HOOK_CWeapon__TakePhotograph() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Restore instructions replaced by hook add esp, 8 @@ -7426,6 +8274,7 @@ void _declspec(naked) HOOK_CWeapon__TakePhotograph() // Go back jmp RETURN_CWeapon__TakePhotograph } + // clang-format on } // Disable camera collisions for projectiles and detached vehicle parts @@ -7437,27 +8286,30 @@ bool CanEntityCollideWithCamera(CEntitySAInterface* pEntity) switch (pEntity->m_nModelIndex) { // projectiles - case 342: // grenade - case 343: // teargas - case 344: // molotov - case 363: // satchel + case 342: // grenade + case 343: // teargas + case 344: // molotov + case 363: // satchel // vehicle parts - case 374: // car_door - case 375: // car_bumper - case 376: // car_panel - case 377: // car_bonnet - case 378: // car_boot - case 379: // car_wheel + case 374: // car_door + case 375: // car_bumper + case 376: // car_panel + case 377: // car_bonnet + case 378: // car_boot + case 379: // car_wheel return false; } return true; } -void _declspec(naked) HOOK_CCollision__CheckCameraCollisionObjects() +static void __declspec(naked) HOOK_CCollision__CheckCameraCollisionObjects() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Restore instructions replaced by hook jz out2 @@ -7481,4 +8333,5 @@ void _declspec(naked) HOOK_CCollision__CheckCameraCollisionObjects() out1: jmp RETURN_CCollision__CheckCameraCollisionObjects out2: jmp RETURN_CCollision__CheckCameraCollisionObjects_2 } + // clang-format on } diff --git a/Client/multiplayer_sa/CMultiplayerSA.h b/Client/multiplayer_sa/CMultiplayerSA.h index 75206d82114..77e95b4191a 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -19,8 +19,8 @@ #include "CRemoteDataSA.h" class CRemoteDataSA; -#define DEFAULT_NEAR_CLIP_DISTANCE ( 0.3f ) -#define DEFAULT_SHADOWS_OFFSET ( 0.013f ) // GTA default = 0.06f +#define DEFAULT_NEAR_CLIP_DISTANCE (0.3f) +#define DEFAULT_SHADOWS_OFFSET (0.013f) // GTA default = 0.06f enum eRadioStationID { @@ -51,14 +51,17 @@ class CMultiplayerSA : public CMultiplayer ZERO_ON_NEW CMultiplayerSA(); + ~CMultiplayerSA(); void InitHooks(); void InitHooks_CrashFixHacks(); void Init_13(); void InitHooks_13(); void InitMemoryCopies_13(); + void InitHooks_CustomAnimations(); void InitHooks_ClothesSpeedUp(); void InitHooks_FixBadAnimId(); void InitHooks_HookDestructors(); + void CleanupHooks_HookDestructors(); void InitHooks_RwResources(); void InitHooks_ClothesCache(); void InitHooks_Files(); @@ -76,6 +79,7 @@ class CMultiplayerSA : public CMultiplayer void InitHooks_Direct3D(); void InitHooks_FixLineOfSightArgs(); void InitHooks_Streaming(); + void InitHooks_FixMallocAlign(); void InitHooks_FrameRateFixes(); void InitHooks_ProjectileCollisionFix(); void InitHooks_ObjectStreamerOptimization(); @@ -200,17 +204,17 @@ class CMultiplayerSA : public CMultiplayer int GetMoonSize(); void ResetMoonSize(); - void GetAmbientColor(float& red, float& green, float& blue) const; - bool SetAmbientColor(float red, float green, float blue); - bool ResetAmbientColor(); + void GetAmbientColor(float& red, float& green, float& blue) const; + bool SetAmbientColor(float red, float green, float blue); + bool ResetAmbientColor(); - void GetAmbientObjectColor(float& red, float& green, float& blue) const; - bool SetAmbientObjectColor(float red, float green, float blue); - bool ResetAmbientObjectColor(); + void GetAmbientObjectColor(float& red, float& green, float& blue) const; + bool SetAmbientObjectColor(float red, float green, float blue); + bool ResetAmbientObjectColor(); - void GetDirectionalColor(float& red, float& green, float& blue) const; - bool SetDirectionalColor(float red, float green, float blue); - bool ResetDirectionalColor(); + void GetDirectionalColor(float& red, float& green, float& blue) const; + bool SetDirectionalColor(float red, float green, float blue); + bool ResetDirectionalColor(); float GetSpriteSize() const; bool SetSpriteSize(float size); @@ -236,13 +240,13 @@ class CMultiplayerSA : public CMultiplayer bool SetLightsOnGroundBrightness(float brightness); bool ResetLightsOnGroundBrightness(); - void GetLowCloudsColor(int16& red, int16& green, int16& blue) const; - bool SetLowCloudsColor(int16 red, int16 green, int16 blue); - bool ResetLowCloudsColor(); + void GetLowCloudsColor(int16& red, int16& green, int16& blue) const; + bool SetLowCloudsColor(int16 red, int16 green, int16 blue); + bool ResetLowCloudsColor(); - void GetBottomCloudsColor(int16& red, int16& green, int16& blue) const; - bool SetBottomCloudsColor(int16 red, int16 green, int16 blue); - bool ResetBottomCloudsColor(); + void GetBottomCloudsColor(int16& red, int16& green, int16& blue) const; + bool SetBottomCloudsColor(int16 red, int16 green, int16 blue); + bool ResetBottomCloudsColor(); float GetCloudsAlpha1() const; bool SetCloudsAlpha1(float alpha); diff --git a/Client/multiplayer_sa/CMultiplayerSA_1.3.cpp b/Client/multiplayer_sa/CMultiplayerSA_1.3.cpp index 48035ffc105..ec474ec7ecc 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_1.3.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_1.3.cpp @@ -2,7 +2,7 @@ * * PROJECT: Multi Theft Auto v1.0 * LICENSE: See LICENSE in the top level directory - * FILE: multiplayer_sa/CMultiplayerSA.cpp + * FILE: multiplayer_sa/CMultiplayerSA_1.3.cpp * PURPOSE: Multiplayer module class 1.3 * * Multi Theft Auto is available from https://www.multitheftauto.com/ @@ -14,133 +14,135 @@ extern CCoreInterface* g_pCore; -#define FUNC_CPed__RenderTargetMarker 0x60BA80 +#define FUNC_CPed__RenderTargetMarker 0x60BA80 WaterCannonHitHandler* m_pWaterCannonHitHandler = NULL; VehicleFellThroughMapHandler* m_pVehicleFellThroughMapHandler = NULL; -#define HOOKPOS_CEventHitByWaterCannon 0x729899 +#define HOOKPOS_CEventHitByWaterCannon 0x729899 DWORD RETURN_CWaterCannon_PushPeds_RETN = 0x7298A7; DWORD CALL_CEventHitByWaterCannon = 0x4B1290; DWORD RETURN_CWaterCannon_PushPeds_RETN_Cancel = 0x729AEB; void HOOK_CEventHitByWaterCannon(); -#define HOOKPOS_CVehicle_ProcessStuff_TestSirenTypeSingle 0x6AB366 +#define HOOKPOS_CVehicle_ProcessStuff_TestSirenTypeSingle 0x6AB366 DWORD RETN_CVehicle_ProcessStuff_TestSirenTypeSingle = 0x6AB36D; -#define HOOKPOS_CVehicle_ProcessStuff_SetSirenPositionSingle 0x6ABC51 +#define HOOKPOS_CVehicle_ProcessStuff_SetSirenPositionSingle 0x6ABC51 DWORD RETN_CVehicle_ProcessStuff_PostPushSirenPositionSingle = 0x6ABC64; -#define HOOKPOS_CVehicle_ProcessStuff_TestSirenTypeDual 0x6AB382 +#define HOOKPOS_CVehicle_ProcessStuff_TestSirenTypeDual 0x6AB382 DWORD RETN_CVehicle_ProcessStuff_TestSirenTypeDual = 0x6AB389; -#define HOOKPOS_CVehicle_ProcessStuff_PostPushSirenPosition1 0x6ABA47 +#define HOOKPOS_CVehicle_ProcessStuff_PostPushSirenPosition1 0x6ABA47 DWORD RETN_CVehicle_ProcessStuff_PostPushSirenPositionDual1 = 0x6ABA5E; -#define HOOKPOS_CVehicle_ProcessStuff_PostPushSirenPosition2 0x6AB9F7 +#define HOOKPOS_CVehicle_ProcessStuff_PostPushSirenPosition2 0x6AB9F7 DWORD RETN_CVehicle_ProcessStuff_PostPushSirenPositionDual2 = 0x6ABA07; -#define HOOKPOS_CMotorBike_ProcessStuff_PushSirenPositionBlue 0x6BD4C3 +#define HOOKPOS_CMotorBike_ProcessStuff_PushSirenPositionBlue 0x6BD4C3 DWORD RETN_CMotorBike_ProcessStuff_PushSirenPositionDualBlue = 0x6BD4DB; -#define HOOKPOS_CMotorBike_ProcessStuff_PushSirenPositionRed 0x6BD516 +#define HOOKPOS_CMotorBike_ProcessStuff_PushSirenPositionRed 0x6BD516 DWORD RETN_CMotorBike_ProcessStuff_PushSirenPositionDualRed = 0x6BD52C; -#define HOOKPOS_CMotorbike_ProcessStuff_TestVehicleModel 0x6BD40F +#define HOOKPOS_CMotorbike_ProcessStuff_TestVehicleModel 0x6BD40F DWORD RETN_CMotorbike_ProcessStuff_TestVehicleModel = 0x6BD415; -#define HOOKPOS_CVehicle_DoesVehicleUseSiren 0x6D8470 +#define HOOKPOS_CVehicle_DoesVehicleUseSiren 0x6D8470 DWORD RETN_CVehicleDoesVehicleUseSirenRetn = 0x6D8497; -#define HOOKPOS_CVehicle_ProcessStuff_TestCameraPosition 0x6ABC17 +#define HOOKPOS_CVehicle_ProcessStuff_TestCameraPosition 0x6ABC17 DWORD RETN_CVehicle_ProcessStuff_TestCameraPosition = 0x6ABC1C; DWORD RETN_CVehicle_ProcessStuff_TestCameraPosition2 = 0x6ABC1E; -#define HOOKPOS_CVehicleAudio_ProcessSirenSound1 0x501FC2 +#define HOOKPOS_CVehicleAudio_ProcessSirenSound1 0x501FC2 DWORD RETN_CVehicleAudio_ProcessSirenSound1 = 0x501FC7; -#define HOOKPOS_CVehicleAudio_ProcessSirenSound2 0x502067 +#define HOOKPOS_CVehicleAudio_ProcessSirenSound2 0x502067 DWORD RETN_CVehicleAudio_ProcessSirenSound2 = 0x50206C; -#define HOOKPOS_CVehicleAudio_ProcessSirenSound3 0x5021AE +#define HOOKPOS_CVehicleAudio_ProcessSirenSound3 0x5021AE DWORD RETN_CVehicleAudio_ProcessSirenSound3 = 0x5021B3; -#define HOOKPOS_CVehicleAudio_ProcessSirenSound 0x4F62BB +#define HOOKPOS_CVehicleAudio_ProcessSirenSound 0x4F62BB DWORD RETN_CVehicleAudio_GetVehicleSirenType = 0x4F62C1; -#define HOOKPOS_CVehicle_ProcessStuff_PushRGBPointLights 0x6AB7A5 +#define HOOKPOS_CVehicle_ProcessStuff_PushRGBPointLights 0x6AB7A5 DWORD RETN_CVehicle_ProcessStuff_PushRGBPointLights = 0x6AB7D5; -#define HOOKPOS_CVehicle_ProcessStuff_StartPointLightCode 0x6AB722 +#define HOOKPOS_CVehicle_ProcessStuff_StartPointLightCode 0x6AB722 DWORD RETN_CVehicle_ProcessStuff_StartPointLightCode = 0x6AB729; DWORD RETN_CVehicle_ProcessStuff_IgnorePointLightCode = 0x6AB823; -#define HOOKPOS_CTaskSimpleJetpack_ProcessInput 0x67E7F1 +#define HOOKPOS_CTaskSimpleJetpack_ProcessInput 0x67E7F1 DWORD RETN_CTaskSimpleJetpack_ProcessInputEnable = 0x67E812; DWORD RETN_CTaskSimpleJetpack_ProcessInputDisabled = 0x67E821; -#define HOOKPOS_CTaskSimplePlayerOnFoot_ProcessWeaponFire 0x685ABA +#define HOOKPOS_CTaskSimplePlayerOnFoot_ProcessWeaponFire 0x685ABA DWORD RETN_CTaskSimplePlayerOnFoot_ProcessWeaponFire = 0x685ABF; DWORD RETN_CTaskSimplePlayerOnFoot_ProcessWeaponFire_Call = 0x540670; -#define HOOKPOS_CWorld_RemoveFallenPeds 0x565D0D +#define HOOKPOS_CWorld_RemoveFallenPeds 0x565D0D DWORD RETURN_CWorld_RemoveFallenPeds_Cont = 0x565D13; DWORD RETURN_CWorld_RemoveFallenPeds_Cancel = 0x565E6F; -#define HOOKPOS_CWorld_RemoveFallenCars 0x565F52 +#define HOOKPOS_CWorld_RemoveFallenCars 0x565F52 DWORD RETURN_CWorld_RemoveFallenCars_Cont = 0x565F59; DWORD RETURN_CWorld_RemoveFallenCars_Cancel = 0x56609B; -#define HOOKPOS_CVehicleModelInterface_SetClump 0x4C9606 +#define HOOKPOS_CVehicleModelInterface_SetClump 0x4C9606 DWORD RETURN_CVehicleModelInterface_SetClump = 0x4C9611; -#define HOOKPOS_CBoat_ApplyDamage 0x6F1C32 +#define HOOKPOS_CBoat_ApplyDamage 0x6F1C32 DWORD RETURN_CBoat_ApplyDamage = 0x6F1C3E; -#define HOOKPOS_CProjectile_FixTearGasCrash 0x4C0403 +#define HOOKPOS_CProjectile_FixTearGasCrash 0x4C0403 DWORD RETURN_CProjectile_FixTearGasCrash_Fix = 0x4C05B9; DWORD RETURN_CProjectile_FixTearGasCrash_Cont = 0x4C0409; -#define HOOKPOS_CVehicle_ProcessTyreSmoke_Initial 0x6DE8A2 -#define HOOKPOS_CVehicle_ProcessTyreSmoke_Burnouts 0x6DF197 -#define HOOKPOS_CVehicle_ProcessTyreSmoke_Braking 0x6DECED -#define HOOKPOS_CVehicle_ProcessTyreSmoke_HookAddress 0x6DF308 +#define HOOKPOS_CVehicle_ProcessTyreSmoke_Initial 0x6DE8A2 +#define HOOKPOS_CVehicle_ProcessTyreSmoke_Burnouts 0x6DF197 +#define HOOKPOS_CVehicle_ProcessTyreSmoke_Braking 0x6DECED +#define HOOKPOS_CVehicle_ProcessTyreSmoke_HookAddress 0x6DF308 -#define HOOKPOS_CProjectile_FixExplosionLocation 0x738A77 +#define HOOKPOS_CProjectile_FixExplosionLocation 0x738A77 DWORD RETURN_CProjectile_FixExplosionLocation = 0x738A86; #define HOOKPOS_CPed_RemoveWeaponWhenEnteringVehicle 0x5E6370 DWORD RETURN_CPed_RemoveWeaponWhenEnteringVehicle = 0x5E6379; -void HOOK_CVehicle_ProcessStuff_TestSirenTypeSingle(); -void HOOK_CVehicle_ProcessStuff_PostPushSirenPositionSingle(); -void HOOK_CVehicle_ProcessStuff_TestSirenTypeDual(); -void HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualRed(); -void HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualBlue(); -void HOOK_CVehicle_DoesVehicleUseSiren(); -void HOOK_CVehicle_ProcessStuff_TestCameraPosition(); -void HOOK_CVehicleAudio_ProcessSirenSound(); -void HOOK_CVehicleAudio_ProcessSirenSound1(); -void HOOK_CVehicleAudio_ProcessSirenSound2(); -void HOOK_CVehicleAudio_ProcessSirenSound3(); -void HOOK_CMotorBike_ProcessStuff_PushSirenPositionBlue(); -void HOOK_CMotorBike_ProcessStuff_PushSirenPositionRed(); -void HOOK_CMotorBike_ProcessStuff_PushSirenPosition2(); -void HOOK_CMotorbike_ProcessStuff_TestVehicleModel(); -void HOOK_CVehicle_ProcessStuff_PushRGBPointLights(); -void HOOK_CVehicle_ProcessStuff_StartPointLightCode(); -void HOOK_CTaskSimpleJetpack_ProcessInput(); -void HOOK_CTaskSimplePlayerOnFoot_ProcessWeaponFire(); -void HOOK_CTaskSimpleJetpack_ProcessInputFixFPS2(); -void HOOK_CWorld_RemoveFallenPeds(); -void HOOK_CWorld_RemoveFallenCars(); -void HOOK_CVehicleModelInterface_SetClump(); -void HOOK_CBoat_ApplyDamage(); -void HOOK_CProjectile_FixTearGasCrash(); -void HOOK_CProjectile_FixExplosionLocation(); -void HOOK_CPed_RemoveWeaponWhenEnteringVehicle(); +void HOOK_CVehicle_ProcessStuff_TestSirenTypeSingle(); +void HOOK_CVehicle_ProcessStuff_PostPushSirenPositionSingle(); +void HOOK_CVehicle_ProcessStuff_TestSirenTypeDual(); +void HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualRed(); +void HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualBlue(); +void HOOK_CVehicle_DoesVehicleUseSiren(); +void HOOK_CVehicle_ProcessStuff_TestCameraPosition(); +void HOOK_CVehicleAudio_ProcessSirenSound(); +void HOOK_CVehicleAudio_ProcessSirenSound1(); +void HOOK_CVehicleAudio_ProcessSirenSound2(); +void HOOK_CVehicleAudio_ProcessSirenSound3(); +void HOOK_CMotorBike_ProcessStuff_PushSirenPositionBlue(); +void HOOK_CMotorBike_ProcessStuff_PushSirenPositionRed(); +void HOOK_CMotorBike_ProcessStuff_PushSirenPosition2(); +void HOOK_CMotorbike_ProcessStuff_TestVehicleModel(); +void HOOK_CVehicle_ProcessStuff_PushRGBPointLights(); +void HOOK_CVehicle_ProcessStuff_StartPointLightCode(); +void HOOK_CTaskSimpleJetpack_ProcessInput(); +void HOOK_CTaskSimplePlayerOnFoot_ProcessWeaponFire(); +void HOOK_CTaskSimpleJetpack_ProcessInputFixFPS2(); +void HOOK_CWorld_RemoveFallenPeds(); +void HOOK_CWorld_RemoveFallenCars(); +void HOOK_CVehicleModelInterface_SetClump(); +void HOOK_CBoat_ApplyDamage(); +void HOOK_CProjectile_FixTearGasCrash(); +void HOOK_CProjectile_FixExplosionLocation(); +void HOOK_CPed_RemoveWeaponWhenEnteringVehicle(); +void* __cdecl HOOK_CMemoryMgr_MallocAlign(int size, int alignment, int nHint); +void __cdecl HOOK_CMemoryMgr_FreeAlign(void* ptr); void CMultiplayerSA::Init_13() { @@ -155,18 +157,18 @@ void CMultiplayerSA::InitHooks_13() // Siren hooks HookInstall(HOOKPOS_CVehicle_ProcessStuff_TestSirenTypeSingle, (DWORD)HOOK_CVehicle_ProcessStuff_TestSirenTypeSingle, - 7); // Test siren type is single for a jump + 7); // Test siren type is single for a jump HookInstall(HOOKPOS_CVehicle_ProcessStuff_SetSirenPositionSingle, (DWORD)HOOK_CVehicle_ProcessStuff_PostPushSirenPositionSingle, - 19); // mov before Push for the siren position (overhook so we can get RGBA) + 19); // mov before Push for the siren position (overhook so we can get RGBA) HookInstall(HOOKPOS_CVehicle_ProcessStuff_TestSirenTypeDual, (DWORD)HOOK_CVehicle_ProcessStuff_TestSirenTypeDual, - 7); // test siren type is dual for a jump + 7); // test siren type is dual for a jump HookInstall(HOOKPOS_CVehicle_ProcessStuff_PostPushSirenPosition1, (DWORD)HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualRed, - 15); // mov before push for the siren position (overhook so we can get RGBA) + 15); // mov before push for the siren position (overhook so we can get RGBA) HookInstall(HOOKPOS_CVehicle_ProcessStuff_PostPushSirenPosition2, (DWORD)HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualBlue, - 15); // mov before push for the siren position (overhook so we can get RGBA) - HookInstall(HOOKPOS_CVehicle_DoesVehicleUseSiren, (DWORD)HOOK_CVehicle_DoesVehicleUseSiren, 5); // Does vehicle have a siren + 15); // mov before push for the siren position (overhook so we can get RGBA) + HookInstall(HOOKPOS_CVehicle_DoesVehicleUseSiren, (DWORD)HOOK_CVehicle_DoesVehicleUseSiren, 5); // Does vehicle have a siren HookInstall(HOOKPOS_CVehicle_ProcessStuff_TestCameraPosition, (DWORD)HOOK_CVehicle_ProcessStuff_TestCameraPosition, - 5); // Fix for single sirens being 360 degrees + 5); // Fix for single sirens being 360 degrees // Breaks Rear wheel rendering leave for now // HookInstall ( HOOKPOS_CMotorBike_ProcessStuff_PushSirenPositionBlue, (DWORD)HOOK_CMotorBike_ProcessStuff_PushSirenPositionBlue, 15 ); // mov before the // push for the sien position (overhook so we can get RGBA) HookInstall ( HOOKPOS_CMotorBike_ProcessStuff_PushSirenPositionRed, @@ -213,6 +215,7 @@ void CMultiplayerSA::InitHooks_13() InitHooks_VehicleDummies(); InitHooks_Vehicles(); InitHooks_Rendering(); + InitHooks_FixMallocAlign(); } void CMultiplayerSA::InitMemoryCopies_13() @@ -225,7 +228,7 @@ void CMultiplayerSA::InitMemoryCopies_13() MemPut(0x040892A, 0x53); MemPut(0x040892B, 0x90); - MemPut(0x04341C0, 0xC3); // Skip CCarCtrl::GenerateRandomCars + MemPut(0x04341C0, 0xC3); // Skip CCarCtrl::GenerateRandomCars // Prevent garages deleting vehicles MemPut(0x0449C50, 0xC3); @@ -331,9 +334,13 @@ void GetVehicleSirenType() dwSirenType2 = 5; } } -void _declspec(naked) HOOK_CVehicle_ProcessStuff_TestSirenTypeSingle() + +static void __declspec(naked) HOOK_CVehicle_ProcessStuff_TestSirenTypeSingle() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad // Grab our original siren type @@ -343,9 +350,11 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_TestSirenTypeSingle() // Grab our siren vehicle mov pVehicleWithTheSiren, esi } + // clang-format on // Call our Get siren type function which edits dwSirenType to our desired type GetVehicleSirenType(); - _asm + // clang-format off + __asm { popad // put our new siren type into edx or old one for default/no sirens @@ -353,6 +362,7 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_TestSirenTypeSingle() // Jump back to the original code JMP RETN_CVehicle_ProcessStuff_TestSirenTypeSingle } + // clang-format on } void SetupSirenColour(CVehicle* pVehicle) @@ -562,9 +572,12 @@ bool ProcessVehicleSirenPosition() return false; } -void _declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionSingle() +static void __declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionSingle() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Get our siren position into edx lea edx, [esp+64h] @@ -574,11 +587,13 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionSingle() // Put edx into our position variable mov vecRelativeSirenPosition, edx } + // clang-format on bPointLights = false; // Call our main siren Process function if (ProcessVehicleSirenPosition()) { - _asm + // clang-format off + __asm { popad // push our siren position @@ -594,10 +609,12 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionSingle() // return back to SA JMP RETN_CVehicle_ProcessStuff_PostPushSirenPositionSingle } + // clang-format on } else { - _asm + // clang-format off + __asm { popad // push our siren position @@ -609,6 +626,7 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionSingle() // return back to SA JMP RETN_CVehicle_ProcessStuff_PostPushSirenPositionSingle } + // clang-format on } } @@ -626,9 +644,13 @@ void TestSirenTypeDualDefaultFix() GetVehicleSirenType(); } } -void _declspec(naked) HOOK_CVehicle_ProcessStuff_TestSirenTypeDual() + +static void __declspec(naked) HOOK_CVehicle_ProcessStuff_TestSirenTypeDual() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Grab our default siren type into edi movzx edi, byte ptr ds:[edi+06ACDACh] @@ -638,9 +660,11 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_TestSirenTypeDual() // Store our post hook default siren type mov dwSirenTypePostHook, edi } + // clang-format on // Do our test and edit dwSirenType2 appropriately TestSirenTypeDualDefaultFix(); - _asm + // clang-format off + __asm { popad // Move dwSirenType into edi @@ -648,11 +672,15 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_TestSirenTypeDual() // Return back to SA JMP RETN_CVehicle_ProcessStuff_TestSirenTypeDual } + // clang-format on } -void _declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualRed() +static void __declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualRed() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Grab our siren position vector lea eax, [esp+130h] @@ -666,12 +694,14 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualRed() mov dwGreen, edx mov dwBlue, ecx } + // clang-format on bPointLights = false; // Call our main process siren function if (ProcessVehicleSirenPosition()) { - _asm + // clang-format off + __asm { popad // Push our position @@ -688,10 +718,12 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualRed() // Return control JMP RETN_CVehicle_ProcessStuff_PostPushSirenPositionDual1 } + // clang-format on } else { - _asm + // clang-format off + __asm { popad // Push our position @@ -708,12 +740,16 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualRed() // Return control JMP RETN_CVehicle_ProcessStuff_PostPushSirenPositionDual1 } + // clang-format on } } -void _declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualBlue() +static void __declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualBlue() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Grab our siren position vector lea eax, [esp+130h] @@ -726,12 +762,14 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualBlue() mov dwGreen, edx mov dwBlue, ecx } + // clang-format on bPointLights = false; // Call our main process siren function if (ProcessVehicleSirenPosition()) { - _asm + // clang-format off + __asm { popad // Push our position @@ -748,10 +786,12 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualBlue() // Return control JMP RETN_CVehicle_ProcessStuff_PostPushSirenPositionDual2 } + // clang-format on } else { - _asm + // clang-format off + __asm { popad // Push our position @@ -768,6 +808,7 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_PostPushSirenPositionDualBlue() // Return control JMP RETN_CVehicle_ProcessStuff_PostPushSirenPositionDual2 } + // clang-format on } } @@ -789,18 +830,23 @@ bool TestVehicleForSiren() return true; } -void _declspec(naked) HOOK_CVehicle_DoesVehicleUseSiren() +static void __declspec(naked) HOOK_CVehicle_DoesVehicleUseSiren() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad // Grab our vehicle interface mov pVehicleWithTheSiren, ecx } + // clang-format on // Test our vehicle for sirens if (TestVehicleForSiren()) { - _asm + // clang-format off + __asm { popad // Move 1 into AL (true) @@ -808,10 +854,12 @@ void _declspec(naked) HOOK_CVehicle_DoesVehicleUseSiren() // Return jmp RETN_CVehicleDoesVehicleUseSirenRetn } + // clang-format on } else { - _asm + // clang-format off + __asm { popad // xor AL (false) @@ -819,6 +867,7 @@ void _declspec(naked) HOOK_CVehicle_DoesVehicleUseSiren() // Return jmp RETN_CVehicleDoesVehicleUseSirenRetn } + // clang-format on } } bool SirenCheckCameraPosition() @@ -841,28 +890,36 @@ bool SirenCheckCameraPosition() // Only visible from the front return false; } -void _declspec(naked) HOOK_CVehicle_ProcessStuff_TestCameraPosition() + +static void __declspec(naked) HOOK_CVehicle_ProcessStuff_TestCameraPosition() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad // Grab our vehicle mov pVehicleWithTheSiren, esi } + // clang-format on // Check if we disable or enable the 360 effect if (SirenCheckCameraPosition()) { - _asm + // clang-format off + __asm { popad // 360 effect // Carry on jmp RETN_CVehicle_ProcessStuff_TestCameraPosition } + // clang-format on } else { - _asm + // clang-format off + __asm { popad // 180 effect @@ -872,6 +929,7 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_TestCameraPosition() // Carry on jmp RETN_CVehicle_ProcessStuff_TestCameraPosition2 } + // clang-format on } } bool DisableVehicleSiren() @@ -887,83 +945,115 @@ bool DisableVehicleSiren() } return false; } -void _declspec(naked) HOOK_CVehicleAudio_ProcessSirenSound() + +static void __declspec(naked) HOOK_CVehicleAudio_ProcessSirenSound() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on if (DisableVehicleSiren()) { - _asm + // clang-format off + __asm { popad mov dl, 0 jmp RETN_CVehicleAudio_GetVehicleSirenType } + // clang-format on } else { - _asm + // clang-format off + __asm { popad mov dl, [ecx+42Dh] jmp RETN_CVehicleAudio_GetVehicleSirenType } + // clang-format on } } -DWORD CALL_CVehicleAudio_ProcessCarHorn = 0x5002C0; -void _declspec(naked) HOOK_CVehicleAudio_ProcessSirenSound1() +DWORD CALL_CVehicleAudio_ProcessCarHorn = 0x5002C0; +static void __declspec(naked) HOOK_CVehicleAudio_ProcessSirenSound1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov pVehicleWithTheSiren, edi pushad } + // clang-format on - _asm + // clang-format off + __asm { popad call CALL_CVehicleAudio_ProcessCarHorn jmp RETN_CVehicleAudio_ProcessSirenSound1 } + // clang-format on } -void _declspec(naked) HOOK_CVehicleAudio_ProcessSirenSound2() + +static void __declspec(naked) HOOK_CVehicleAudio_ProcessSirenSound2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov pVehicleWithTheSiren, edi pushad } + // clang-format on - _asm + // clang-format off + __asm { popad call CALL_CVehicleAudio_ProcessCarHorn jmp RETN_CVehicleAudio_ProcessSirenSound2 } + // clang-format on } -void _declspec(naked) HOOK_CVehicleAudio_ProcessSirenSound3() + +static void __declspec(naked) HOOK_CVehicleAudio_ProcessSirenSound3() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov pVehicleWithTheSiren, edi pushad } + // clang-format on - _asm + // clang-format off + __asm { popad call CALL_CVehicleAudio_ProcessCarHorn jmp RETN_CVehicleAudio_ProcessSirenSound3 } + // clang-format on } DWORD RETN_CMotorbike_ProcessStuff_PostPushSirenPositionDual1 = 0x6BD4DB; -void _declspec(naked) HOOK_CMotorBike_ProcessStuff_PushSirenPositionBlue() +static void __declspec(naked) HOOK_CMotorBike_ProcessStuff_PushSirenPositionBlue() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Grab our siren position vector lea eax,[esp+0ECh] @@ -973,12 +1063,14 @@ void _declspec(naked) HOOK_CMotorBike_ProcessStuff_PushSirenPositionBlue() // move our position vector pointer into our position variable mov vecRelativeSirenPosition, eax } + // clang-format on bPointLights = false; // Call our main process siren function if (ProcessVehicleSirenPosition()) { - _asm + // clang-format off + __asm { popad // Push our position @@ -995,10 +1087,12 @@ void _declspec(naked) HOOK_CMotorBike_ProcessStuff_PushSirenPositionBlue() // Return control JMP RETN_CMotorbike_ProcessStuff_PostPushSirenPositionDual1 } + // clang-format on } else { - _asm + // clang-format off + __asm { popad // Push our position @@ -1012,12 +1106,16 @@ void _declspec(naked) HOOK_CMotorBike_ProcessStuff_PushSirenPositionBlue() // Return control JMP RETN_CMotorbike_ProcessStuff_PostPushSirenPositionDual1 } + // clang-format on } } -void _declspec(naked) HOOK_CMotorBike_ProcessStuff_PushSirenPositionRed() +static void __declspec(naked) HOOK_CMotorBike_ProcessStuff_PushSirenPositionRed() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad // Grab our vehicle interface @@ -1025,12 +1123,14 @@ void _declspec(naked) HOOK_CMotorBike_ProcessStuff_PushSirenPositionRed() // move our position vector pointer into our position variable mov vecRelativeSirenPosition, edx } + // clang-format on bPointLights = false; // Call our main process siren function if (ProcessVehicleSirenPosition()) { - _asm + // clang-format off + __asm { popad // Push our position @@ -1049,10 +1149,12 @@ void _declspec(naked) HOOK_CMotorBike_ProcessStuff_PushSirenPositionRed() // Return control JMP RETN_CMotorBike_ProcessStuff_PushSirenPositionDualRed } + // clang-format on } else { - _asm + // clang-format off + __asm { popad // Push our position @@ -1067,47 +1169,59 @@ void _declspec(naked) HOOK_CMotorBike_ProcessStuff_PushSirenPositionRed() // Return control JMP RETN_CMotorBike_ProcessStuff_PushSirenPositionDualRed } + // clang-format on } } -DWORD RETN_CMotorbike_ProcessStuff_TestVehicleModel2 = 0x6BD41B; -void _declspec(naked) HOOK_CMotorbike_ProcessStuff_TestVehicleModel() +DWORD RETN_CMotorbike_ProcessStuff_TestVehicleModel2 = 0x6BD41B; +static void __declspec(naked) HOOK_CMotorbike_ProcessStuff_TestVehicleModel() { - _asm + // clang-format off + __asm { pushad mov pVehicleWithTheSiren, esi } + // clang-format on if (TestVehicleForSiren()) { - _asm + // clang-format off + __asm { popad cmp word ptr [esi+22h], 20Bh jmp RETN_CMotorbike_ProcessStuff_TestVehicleModel2 } + // clang-format on } else { - _asm + // clang-format off + __asm { popad cmp word ptr [esi+22h], 20Bh jmp RETN_CMotorbike_ProcessStuff_TestVehicleModel } + // clang-format on } } -DWORD dwValue = 0x858B4C; -void _declspec(naked) HOOK_CVehicle_ProcessStuff_PushRGBPointLights() +DWORD dwValue = 0x858B4C; +static void __declspec(naked) HOOK_CVehicle_ProcessStuff_PushRGBPointLights() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov esi, pVehicleWithTheSiren } + // clang-format on bPointLights = true; if (ProcessVehicleSirenPosition()) { - _asm + // clang-format off + __asm { popad mov edx, dwBlue @@ -1127,10 +1241,12 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_PushRGBPointLights() fild dword ptr [esp+30h] JMP RETN_CVehicle_ProcessStuff_PushRGBPointLights } + // clang-format on } else { - _asm + // clang-format off + __asm { popad fild dword ptr [esp+30h] @@ -1146,19 +1262,25 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_PushRGBPointLights() fild dword ptr [esp+30h] JMP RETN_CVehicle_ProcessStuff_PushRGBPointLights } + // clang-format on } } -void _declspec(naked) HOOK_CVehicle_ProcessStuff_StartPointLightCode() +static void __declspec(naked) HOOK_CVehicle_ProcessStuff_StartPointLightCode() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pVehicleWithTheSiren, esi } + // clang-format on if (DoesVehicleHaveSiren()) { - _asm + // clang-format off + __asm { popad fld dword ptr [eax+28h] @@ -1166,16 +1288,19 @@ void _declspec(naked) HOOK_CVehicle_ProcessStuff_StartPointLightCode() fadd st, st jmp RETN_CVehicle_ProcessStuff_StartPointLightCode } + // clang-format on } else { - _asm + // clang-format off + __asm { popad movzx eax, byte ptr [esp+88h] mov [esp+50h], eax jmp RETN_CVehicle_ProcessStuff_IgnorePointLightCode } + // clang-format on } } // Water Cannon Stuff @@ -1198,9 +1323,12 @@ bool TriggerTheEvent() return false; } -void _declspec(naked) HOOK_CEventHitByWaterCannon() +static void __declspec(naked) HOOK_CEventHitByWaterCannon() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad // EDX = CWaterCannon @@ -1210,18 +1338,22 @@ void _declspec(naked) HOOK_CEventHitByWaterCannon() mov pPedHitByWaterCannonInterface, esi mov pVehicleWithTheCannonMounted, eax } + // clang-format on if (TriggerTheEvent()) { - _asm + // clang-format off + __asm { popad // Cancel. jmp RETURN_CWaterCannon_PushPeds_RETN_Cancel } + // clang-format on } else { - _asm + // clang-format off + __asm { popad // Replaced code @@ -1233,6 +1365,7 @@ void _declspec(naked) HOOK_CEventHitByWaterCannon() // Go back to execution jmp RETURN_CWaterCannon_PushPeds_RETN } + // clang-format on } } CPedSAInterface* pPedUsingJetpack; @@ -1246,12 +1379,14 @@ bool IsUsingJetPack() { DWORD CPedIntelligence_FindJetpackTask = 0x601110; DWORD dwReturn = 0; - _asm + // clang-format off + __asm { mov ecx, dwJetpackPedIntelligence call CPedIntelligence_FindJetpackTask mov dwReturn, eax } + // clang-format on return dwReturn > 0; } } @@ -1273,55 +1408,71 @@ bool AllowJetPack() return false; } -void _declspec(naked) HOOK_CTaskSimpleJetpack_ProcessInput() +static void __declspec(naked) HOOK_CTaskSimpleJetpack_ProcessInput() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov pPedUsingJetpack, edi pushad } + // clang-format on if (AllowJetPack()) { - _asm + // clang-format off + __asm { popad jmp RETN_CTaskSimpleJetpack_ProcessInputEnable } + // clang-format on } else { - _asm + // clang-format off + __asm { popad jmp RETN_CTaskSimpleJetpack_ProcessInputDisabled } + // clang-format on } } -void _declspec(naked) HOOK_CTaskSimplePlayerOnFoot_ProcessWeaponFire() +static void __declspec(naked) HOOK_CTaskSimplePlayerOnFoot_ProcessWeaponFire() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pPedUsingJetpack, esi } + // clang-format on if (AllowJetPack()) { - _asm + // clang-format off + __asm { popad xor al, al jmp RETN_CTaskSimplePlayerOnFoot_ProcessWeaponFire } + // clang-format on } else { - _asm + // clang-format off + __asm { popad call RETN_CTaskSimplePlayerOnFoot_ProcessWeaponFire_Call jmp RETN_CTaskSimplePlayerOnFoot_ProcessWeaponFire } + // clang-format on } } @@ -1339,31 +1490,39 @@ bool CWorld_Remove_FallenPedsCheck() return false; } -void _declspec(naked) HOOK_CWorld_RemoveFallenPeds() +static void __declspec(naked) HOOK_CWorld_RemoveFallenPeds() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // If it's going to skip the code anyway just do it otherwise check if he's in a vehicle as the vehicle will be respawned anyway and he will be warped with // it. - _asm + // clang-format off + __asm { test ah, 5 jp [RemoveFallenPeds_Cancel] pushad mov pFallingPedInterface, esi } + // clang-format on if (CWorld_Remove_FallenPedsCheck()) { - _asm + // clang-format off + __asm { popad RemoveFallenPeds_Cancel: jmp RETURN_CWorld_RemoveFallenPeds_Cancel } + // clang-format on } - _asm + // clang-format off + __asm { popad jmp RETURN_CWorld_RemoveFallenPeds_Cont } + // clang-format on } void CMultiplayerSA::SetVehicleFellThroughMapHandler(VehicleFellThroughMapHandler* pHandler) @@ -1387,23 +1546,30 @@ bool CWorld_Remove_FallenVehiclesCheck() DWORD HOOK_CWorld_RemoveFallenCars_Cont1 = 0x565F57; -void _declspec(naked) HOOK_CWorld_RemoveFallenCars() +static void __declspec(naked) HOOK_CWorld_RemoveFallenCars() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // If the vehicle fell through the map give it another try to respawn. - _asm + // clang-format off + __asm { pushad mov pFallingVehicleInterface, esi } + // clang-format on if (CWorld_Remove_FallenVehiclesCheck()) { - _asm + // clang-format off + __asm { popad jmp RETURN_CWorld_RemoveFallenCars_Cancel } + // clang-format on } - _asm + // clang-format off + __asm { popad mov eax, [esi + 14h] @@ -1414,6 +1580,7 @@ void _declspec(naked) HOOK_CWorld_RemoveFallenCars() RemoveFallenCars_Cancel: jmp HOOK_CWorld_RemoveFallenCars_Cont1 } + // clang-format on } void CMultiplayerSA::SetPedTargetingMarkerEnabled(bool bEnable) @@ -1453,20 +1620,25 @@ void CVehicleModelInterface_SetClump() } } -void _declspec(naked) HOOK_CVehicleModelInterface_SetClump() +static void __declspec(naked) HOOK_CVehicleModelInterface_SetClump() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // Grab our currently loading clump // Get our Handling ID because that's all that's in the interface - _asm + // clang-format off + __asm { pushad mov pLoadingClump, eax mov pLoadingModelInfo, esi } + // clang-format on // Init our supported upgrades structure for this model info CVehicleModelInterface_SetClump(); // Perform overwrite sequence and jump back - _asm + // clang-format off + __asm { popad push eax @@ -1474,11 +1646,15 @@ void _declspec(naked) HOOK_CVehicleModelInterface_SetClump() mov dword ptr [esp+14h], 0FFFFFFFFh jmp RETURN_CVehicleModelInterface_SetClump } + // clang-format on } -void _declspec(naked) HOOK_CBoat_ApplyDamage() +static void __declspec(naked) HOOK_CBoat_ApplyDamage() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push eax // Check if vehicleFlags->bCanBeDamaged is set @@ -1487,19 +1663,25 @@ void _declspec(naked) HOOK_CBoat_ApplyDamage() jz boatCanBeDamaged fst dword ptr [esi+4C0h] } + // clang-format on -boatCanBeDamaged: - _asm + boatCanBeDamaged : + // clang-format off + __asm { pop eax jmp RETURN_CBoat_ApplyDamage } + // clang-format on } // fixes a crash where a vehicle is the source of a tear gas projectile. -void _declspec(naked) HOOK_CProjectile_FixTearGasCrash() +static void __declspec(naked) HOOK_CProjectile_FixTearGasCrash() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { cmp ebp, 0h je cont @@ -1512,6 +1694,7 @@ void _declspec(naked) HOOK_CProjectile_FixTearGasCrash() // dundundundundun // dundundundundun } + // clang-format on } void CMultiplayerSA::SetBoatWaterSplashEnabled(bool bEnabled) @@ -1561,24 +1744,31 @@ bool IsPlayerPedLocal() } // makes sure remote player tyre smoke isn't processed when tyre smoke is in the "off" position -void _declspec(naked) HOOK_CMultiplayerSA_ToggleTyreSmoke() +static void __declspec(naked) HOOK_CMultiplayerSA_ToggleTyreSmoke() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pTyreSmokePed, ecx } + // clang-format on if (!IsPlayerPedLocal()) { - _asm + // clang-format off + __asm { popad jmp dwReturnIgnorePed } + // clang-format on } - _asm + // clang-format off + __asm { popad test eax, 20000h @@ -1588,6 +1778,7 @@ void _declspec(naked) HOOK_CMultiplayerSA_ToggleTyreSmoke() ToggleTyreSmoke_Cancel: jmp dwReturnIgnorePed } + // clang-format on } void CMultiplayerSA::SetTyreSmokeEnabled(bool bEnabled) @@ -1654,15 +1845,20 @@ void UpdateExplosionLocation() } } -void _declspec(naked) HOOK_CProjectile_FixExplosionLocation() +static void __declspec(naked) HOOK_CProjectile_FixExplosionLocation() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov pExplosionEntity, esi pushad } + // clang-format on UpdateExplosionLocation(); - _asm + // clang-format off + __asm { popad mov eax, [esi+14h] @@ -1674,12 +1870,16 @@ void _declspec(naked) HOOK_CProjectile_FixExplosionLocation() lea eax, [esi+4] jmp RETURN_CProjectile_FixExplosionLocation } + // clang-format on } -DWORD CPed_RemoveWeaponWhenEnteringVehicle_CalledFrom = 0; -void _declspec(naked) HOOK_CPed_RemoveWeaponWhenEnteringVehicle() +DWORD CPed_RemoveWeaponWhenEnteringVehicle_CalledFrom = 0; +static void __declspec(naked) HOOK_CPed_RemoveWeaponWhenEnteringVehicle() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push eax mov eax, [esp+4] @@ -1690,27 +1890,34 @@ void _declspec(naked) HOOK_CPed_RemoveWeaponWhenEnteringVehicle() mov esi, ecx mov eax, [esi+480h] } + // clang-format on // Called from CTaskSimpleJetPack::ProcessPed if (CPed_RemoveWeaponWhenEnteringVehicle_CalledFrom == 0x68025F) { - _asm + // clang-format off + __asm { mov pPedUsingJetpack, esi } + // clang-format on if (AllowJetPack()) { - _asm + // clang-format off + __asm { pop esi retn 4 } + // clang-format on } } - _asm + // clang-format off + __asm { jmp RETURN_CPed_RemoveWeaponWhenEnteringVehicle } + // clang-format on } diff --git a/Client/multiplayer_sa/CMultiplayerSA_ClothesCache.cpp b/Client/multiplayer_sa/CMultiplayerSA_ClothesCache.cpp index 3b5dd798ad3..c7d242f0530 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_ClothesCache.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_ClothesCache.cpp @@ -14,7 +14,7 @@ #include "..\game_sa\gamesa_renderware.h" #include "..\game_sa\gamesa_renderware.hpp" -#define CLOTHES_REF_TEST 1 // Debug clothes geometry refs +#define CLOTHES_REF_TEST 1 // Debug clothes geometry refs //////////////////////////////////////////////// // @@ -28,7 +28,7 @@ class CPedClothesDesc public: union { - DWORD things1[10]; // models + DWORD things1[10]; // models struct { DWORD torso; @@ -45,7 +45,7 @@ class CPedClothesDesc union { - DWORD things2[18]; // +0x28 textures? + DWORD things2[18]; // +0x28 textures? struct { DWORD Torso; @@ -69,8 +69,8 @@ class CPedClothesDesc }; }; - float fFatAmount; // +0x70 - float fMuscleAmount; // +0x74 + float fFatAmount; // +0x70 + float fMuscleAmount; // +0x74 bool operator==(const CPedClothesDesc& other) const { @@ -117,6 +117,24 @@ class CClumpStore SClothesCacheStats m_Stats; int m_iCacheRevision; + /////////////////////////////////////// + // + // Get geometry from clump's first atomic if structure is valid + // + /////////////////////////////////////// + RpGeometry* GetClumpGeometry(RpClump* pClump) const + { + if (!pClump || !pClump->atomics.root.next) + return nullptr; + if (pClump->atomics.root.next == &pClump->atomics.root) + return nullptr; + + // Subtract 8 RwListEntry elements (64 bytes) to get from inClumpLink to RpAtomic base + RpAtomic* pAtomic = reinterpret_cast(pClump->atomics.root.next - 0x8); + + return pAtomic->geometry; + } + /////////////////////////////////////// // // Constructor @@ -133,15 +151,28 @@ class CClumpStore ////////////////////////////////////////////////////////////// // // Check if any clumps have become unused outside of the cache + // Also removes orphaned entries (null pClump) // ////////////////////////////////////////////////////////////// uint GetNumCached() { - uint uiNumCached = 0; - for (std::vector::iterator iter = savedClumpList.begin(); iter != savedClumpList.end(); ++iter) + uint uiNumCached = 0; + std::vector orphanedIndices; + + for (std::size_t i = 0; i < savedClumpList.size(); ++i) { - SSavedClumpInfo& info = *iter; - RpGeometry* pGeometry = ((RpAtomic*)((info.pClump->atomics.root.next) - 0x8))->geometry; + SSavedClumpInfo& info = savedClumpList[i]; + + if (!info.pClump) + { + orphanedIndices.push_back(i); + continue; + } + + RpGeometry* pGeometry = GetClumpGeometry(info.pClump); + if (!pGeometry) + continue; // Skip but don't remove - geometry may be temp unavailable + #ifdef CLOTHES_REF_TEST if (pGeometry->refs < 21) { @@ -164,6 +195,13 @@ class CClumpStore info.bUnused = false; } + // Remove orphaned entries (null pClump) in reverse order + for (auto it = orphanedIndices.rbegin(); it != orphanedIndices.rend(); ++it) + { + savedClumpList.erase(savedClumpList.begin() + static_cast(*it)); + m_Stats.uiNumRemoved++; + } + m_Stats.uiNumTotal = savedClumpList.size(); m_Stats.uiNumUnused = uiNumCached; return uiNumCached; @@ -185,14 +223,17 @@ class CClumpStore RemoveOldestUnused(); RpClump* pClumpCopy = RpClumpClone(pClump); + if (!pClumpCopy) + return; - SSavedClumpInfo info; - info.pClump = pClumpCopy; #ifdef CLOTHES_REF_TEST - RpGeometry* pGeometry = ((RpAtomic*)((info.pClump->atomics.root.next) - 0x8))->geometry; - pGeometry->refs += 20; + RpGeometry* pGeometry = GetClumpGeometry(pClumpCopy); + if (pGeometry) + pGeometry->refs += 20; #endif + SSavedClumpInfo info; + info.pClump = pClumpCopy; info.clothedDesc = *pClothesDesc; info.bUnused = false; info.iCacheRevision = m_iCacheRevision; @@ -226,42 +267,47 @@ class CClumpStore /////////////////////////////////////// bool RemoveOldestUnused() { - uint uiBestAge = -1; - std::vector::iterator uiBestIndex; + uint uiBestAge = static_cast(-1); + std::size_t bestIndex = savedClumpList.size(); CTickCount timeNow = CTickCount::Now(); - for (std::vector::iterator iter = savedClumpList.begin(); iter != savedClumpList.end(); ++iter) + for (std::size_t i = 0; i < savedClumpList.size(); ++i) { - const SSavedClumpInfo& info = *iter; + const SSavedClumpInfo& info = savedClumpList[i]; if (info.bUnused) { uint uiAge = (timeNow - info.timeUnused).ToInt(); if (uiAge > m_uiMinCacheTime) { - if (uiAge > uiBestAge || uiBestAge == -1) + const bool isFirstCandidate = (bestIndex == savedClumpList.size()); + if (isFirstCandidate || uiAge > uiBestAge) { uiBestAge = uiAge; - uiBestIndex = iter; + bestIndex = i; } } } } - if (uiBestAge == -1) + if (bestIndex == savedClumpList.size()) return false; - const SSavedClumpInfo& info = *uiBestIndex; + const SSavedClumpInfo& info = savedClumpList[bestIndex]; + + if (!info.bUnused) + return false; #ifdef CLOTHES_REF_TEST - RpGeometry* pGeometry = ((RpAtomic*)((info.pClump->atomics.root.next) - 0x8))->geometry; - pGeometry->refs -= 20; + RpGeometry* pGeometry = GetClumpGeometry(info.pClump); + if (pGeometry && pGeometry->refs >= 20) + pGeometry->refs -= 20; #endif - RpClumpDestroy(info.pClump); - assert(info.bUnused); + if (info.pClump) + RpClumpDestroy(info.pClump); m_Stats.uiNumTotal--; m_Stats.uiNumUnused--; m_Stats.uiNumRemoved++; - savedClumpList.erase(uiBestIndex); + savedClumpList.erase(savedClumpList.begin() + static_cast(bestIndex)); return true; } @@ -273,14 +319,16 @@ class CClumpStore /////////////////////////////////////// RpClump* FindMatchAndUse(CPedClothesDesc* pClothesDesc) { - for (std::vector::iterator iter = savedClumpList.begin(); iter != savedClumpList.end(); ++iter) + for (SSavedClumpInfo& info : savedClumpList) { - SSavedClumpInfo& info = *iter; if (info.iCacheRevision != m_iCacheRevision) - continue; // Don't match if it was generated with different custom clothes textures + continue; // Don't match if it was generated with different custom clothes textures if (info.clothedDesc == *pClothesDesc) { + if (!GetClumpGeometry(info.pClump)) + continue; // Skip if geometry unavailable + if (info.bUnused) { info.bUnused = false; @@ -295,6 +343,34 @@ class CClumpStore m_Stats.uiCacheMiss++; return NULL; } + + void ClearOldRevisions() + { + m_iCacheRevision++; + + for (auto& info : savedClumpList) + { + if (info.iCacheRevision == m_iCacheRevision) + continue; + +#ifdef CLOTHES_REF_TEST + if (auto pGeometry = GetClumpGeometry(info.pClump)) + if (pGeometry->refs >= 20) + pGeometry->refs -= 20; +#endif + if (info.pClump) + RpClumpDestroy(info.pClump); + + m_Stats.uiNumTotal--; + if (info.bUnused) + m_Stats.uiNumUnused--; + m_Stats.uiNumRemoved++; + } + + savedClumpList.erase(std::remove_if(savedClumpList.begin(), savedClumpList.end(), + [this](const SSavedClumpInfo& info) { return info.iCacheRevision != m_iCacheRevision; }), + savedClumpList.end()); + } }; CClumpStore ms_clumpStore; @@ -308,7 +384,7 @@ CClumpStore ms_clumpStore; //////////////////////////////////////////////// void CMultiplayerSA::FlushClothesCache() { - ms_clumpStore.m_iCacheRevision++; + ms_clumpStore.ClearOldRevisions(); } //////////////////////////////////////////////// @@ -340,12 +416,15 @@ void _cdecl OnCClothesBuilderCreateSkinnedClumpPost(RpClump* pRpClumpResult, RpC } // Hook info -#define HOOKPOS_CClothesBuilderCreateSkinnedClump 0x5A69D0 -#define HOOKSIZE_CClothesBuilderCreateSkinnedClump 6 -DWORD RETURN_CClothesBuilderCreateSkinnedClump = 0x5A69D6; -void _declspec(naked) HOOK_CClothesBuilderCreateSkinnedClump() +#define HOOKPOS_CClothesBuilderCreateSkinnedClump 0x5A69D0 +#define HOOKSIZE_CClothesBuilderCreateSkinnedClump 6 +DWORD RETURN_CClothesBuilderCreateSkinnedClump = 0x5A69D6; +static void __declspec(naked) HOOK_CClothesBuilderCreateSkinnedClump() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*5] @@ -388,6 +467,7 @@ void _declspec(naked) HOOK_CClothesBuilderCreateSkinnedClump() sub esp, 0D4h jmp RETURN_CClothesBuilderCreateSkinnedClump } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_ClothesMemFix.cpp b/Client/multiplayer_sa/CMultiplayerSA_ClothesMemFix.cpp index 05231b96bb2..0b087525ad9 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_ClothesMemFix.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_ClothesMemFix.cpp @@ -11,8 +11,10 @@ #include "StdInc.h" -#define FUNC_CPedModelInfo_DeleteRwObject 0x04C6C50 -#define FUNC_CPedModelInfo_SetClump 0x04C7340 +#define FUNC_CPedModelInfo_DeleteRwObject 0x04C6C50 +#define FUNC_CPedModelInfo_SetClump 0x04C7340 +#define FUNC_CClumpModelInfo_SetClump 0x04C4F70 +DWORD ADDR_CPedModelInfo_SetClump_AfterHook = 0x04C7349; ////////////////////////////////////////////////////////////////////////////////////////// // @@ -23,23 +25,27 @@ void CPedModelInfo_DeleteRwObject(CBaseModelInfoSAInterface* pModelInfo) { DWORD dwFunction = FUNC_CPedModelInfo_DeleteRwObject; CBaseModelInfoSAInterface* pInterface = pModelInfo; - _asm + // clang-format off + __asm { mov ecx, pInterface call dwFunction } + // clang-format on } -void CPedModelInfo_SetClump(CBaseModelInfoSAInterface* pModelInfo, RwObject* pSavedRwObject) +void CClumpModelInfo_SetClump(CBaseModelInfoSAInterface* pModelInfo, RwObject* pRwClump) { - DWORD dwFunction = FUNC_CPedModelInfo_SetClump; + DWORD dwFunction = FUNC_CClumpModelInfo_SetClump; CBaseModelInfoSAInterface* pInterface = pModelInfo; - _asm + // clang-format off + __asm { - push pSavedRwObject + push pRwClump mov ecx, pInterface call dwFunction } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -50,20 +56,24 @@ void CPedModelInfo_SetClump(CBaseModelInfoSAInterface* pModelInfo, RwObject* pSa RwObject* pSavedModel0RwObject = NULL; void OnMy_CClothesDeleteRwObject() { - assert(!pSavedModel0RwObject); + if (pSavedModel0RwObject) + return; + ushort usModelID = 0; CBaseModelInfoSAInterface* pModelInfo = ((CBaseModelInfoSAInterface**)ARRAY_ModelInfo)[usModelID]; - // Save RwObject of model 0 pSavedModel0RwObject = pModelInfo->pRwObject; } // Hook info -#define HOOKPOS_CClothesDeleteRwObject 0x5A8243 -#define HOOKSIZE_CClothesDeleteRwObject 5 -DWORD RETURN_CClothesDeleteRwObject = 0x5A8248; -void _declspec(naked) HOOK_CClothesDeleteRwObject() +#define HOOKPOS_CClothesDeleteRwObject 0x5A8243 +#define HOOKSIZE_CClothesDeleteRwObject 5 +DWORD RETURN_CClothesDeleteRwObject = 0x5A8248; +static void __declspec(naked) HOOK_CClothesDeleteRwObject() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad call OnMy_CClothesDeleteRwObject @@ -75,6 +85,7 @@ void _declspec(naked) HOOK_CClothesDeleteRwObject() //call dword ptr [edx+20h] //; 004C6C50 ; void CPedModelInfo::DeleteRwObject() jmp RETURN_CClothesDeleteRwObject } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -84,23 +95,40 @@ void _declspec(naked) HOOK_CClothesDeleteRwObject() ////////////////////////////////////////////////////////////////////////////////////////// void OnMy_PostCPedDress() { + if (!pSavedModel0RwObject) + return; + ushort usModelID = 0; CBaseModelInfoSAInterface* pModelInfo = ((CBaseModelInfoSAInterface**)ARRAY_ModelInfo)[usModelID]; - if (pSavedModel0RwObject) + if (!pModelInfo) { - CPedModelInfo_DeleteRwObject(pModelInfo); - CPedModelInfo_SetClump(pModelInfo, pSavedModel0RwObject); - pSavedModel0RwObject = NULL; + pSavedModel0RwObject = nullptr; + return; } + + RwObject* pCurrentRwObject = pModelInfo->pRwObject; + RwObject* pObjectToRestore = pSavedModel0RwObject; + pSavedModel0RwObject = nullptr; + + if (pCurrentRwObject == pObjectToRestore) + return; + + if (pCurrentRwObject) + CPedModelInfo_DeleteRwObject(pModelInfo); + + pModelInfo->pRwObject = pObjectToRestore; } // Hook info -#define HOOKPOS_PostCPedDress 0x5A835C -#define HOOKSIZE_PostCPedDress 5 -DWORD RETURN_PostCPedDress = 0x5A8361; -void _declspec(naked) HOOK_PostCPedDress() +#define HOOKPOS_PostCPedDress 0x5A835C +#define HOOKSIZE_PostCPedDress 5 +DWORD RETURN_PostCPedDress = 0x5A8361; +static void __declspec(naked) HOOK_PostCPedDress() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad call OnMy_PostCPedDress @@ -112,6 +140,7 @@ void _declspec(naked) HOOK_PostCPedDress() push eax jmp RETURN_PostCPedDress } + // clang-format on } //////////////////////////////////////////////// @@ -168,7 +197,6 @@ void CMultiplayerSA::EnableHooks_ClothesMemFix(bool bEnable) { const SHookInfo& hookInfo = hookInfoList[i]; BYTE temp[10]; - assert(sizeof(temp) >= hookInfo.uiSize); stream.ReadBytes(temp, hookInfo.uiSize); MemCpy((void*)hookInfo.dwAddress, temp, hookInfo.uiSize); } diff --git a/Client/multiplayer_sa/CMultiplayerSA_ClothesSpeedUp.cpp b/Client/multiplayer_sa/CMultiplayerSA_ClothesSpeedUp.cpp index 2bee56ea6bb..feb68fa5400 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_ClothesSpeedUp.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_ClothesSpeedUp.cpp @@ -69,18 +69,21 @@ namespace ushort usNext; ushort usPrev; - ushort uiUnknown1; // Parent ? - uchar uiUnknown2; // 0x12 when loading, 0x02 when finished loading + ushort uiUnknown1; // Parent ? + uchar uiUnknown2; // 0x12 when loading, 0x02 when finished loading uchar ucImgId; int iBlockOffset; int iBlockCount; - uint uiLoadflag; // 0-not loaded 2-requested 3-loaded 1-processed + uint uiLoadflag; // 0-not loaded 2-requested 3-loaded 1-processed }; int iReturnFileId; char* pReturnBuffer; -} // namespace + int iLastCacheFileId = -1; +} // namespace + +void OnCrashAverted(uint uiId); //////////////////////////////////////////////////////////////////////////////////////////////// // @@ -94,19 +97,24 @@ bool _cdecl OnCallCStreamingInfoAddToList(int flags, SImgGTAItemInfo* pImgGTAInf if (pImgGTAInfo->ucImgId == 5) { - // If bLoadingBigModel is set, try to get it unset - #define VAR_CStreaming_bLoadingBigModel 0x08E4A58 + int iFileId = ((char*)pImgGTAInfo - (char*)CStreaming__ms_aInfoForModel) / 20; + + // Track which file we're attempting to cache-load, so ShouldSkipLoadRequestedModels + // can verify its loadState before deciding to skip + iLastCacheFileId = iFileId; + +// If bLoadingBigModel is set, try to get it unset +#define VAR_CStreaming_bLoadingBigModel 0x08E4A58 BYTE& bLoadingBigModel = *(BYTE*)VAR_CStreaming_bLoadingBigModel; if (bLoadingBigModel) { pGameInterface->GetStreaming()->LoadAllRequestedModels(true); if (bLoadingBigModel) pGameInterface->GetStreaming()->LoadAllRequestedModels(false); - assert(!bLoadingBigModel); + if (bLoadingBigModel) + return false; } - int iFileId = ((char*)pImgGTAInfo - (char*)CStreaming__ms_aInfoForModel) / 20; - iReturnFileId = iFileId; pReturnBuffer = CMultiplayerSA::ms_PlayerImgCachePtr + pImgGTAInfo->iBlockOffset * 2048; @@ -123,13 +131,16 @@ bool _cdecl OnCallCStreamingInfoAddToList(int flags, SImgGTAItemInfo* pImgGTAInf } // Hook info -#define HOOKPOS_CallCStreamingInfoAddToList 0x408962 -#define HOOKSIZE_CallCStreamingInfoAddToList 5 -DWORD RETURN_CallCStreamingInfoAddToListA = 0x408967; -DWORD RETURN_CallCStreamingInfoAddToListB = 0x408990; -void _declspec(naked) HOOK_CallCStreamingInfoAddToList() +#define HOOKPOS_CallCStreamingInfoAddToList 0x408962 +#define HOOKSIZE_CallCStreamingInfoAddToList 5 +DWORD RETURN_CallCStreamingInfoAddToListA = 0x408967; +DWORD RETURN_CallCStreamingInfoAddToListB = 0x408990; +static void __declspec(naked) HOOK_CallCStreamingInfoAddToList() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push ecx @@ -159,10 +170,15 @@ void _declspec(naked) HOOK_CallCStreamingInfoAddToList() call FUNC_CStreamingConvertBufferToObject add esp, 4*3 + // On failure, ConvertBufferToObject internally calls RemoveModel + RequestModel + // to re-queue. Don't touch loadState here -- let its internal cleanup handle state + // correctly. ShouldSkipLoadRequestedModels verifies loadState before skipping. + popad add esp, 4*1 jmp RETURN_CallCStreamingInfoAddToListB } + // clang-format on } //////////////////////////////////////////////////////////////////////////////////////////////// @@ -177,19 +193,32 @@ bool _cdecl ShouldSkipLoadRequestedModels(DWORD calledFrom) // CClothesBuilder::LoadAndPutOnClothes 5A5F70 - 5A6039 // CClothesBuilder::ConstructTextures 5A6040 - 5A6520 if (calledFrom > 0x5A55A0 && calledFrom < 0x5A6520) - return true; + { + // Only skip if a file was actually served from cache and is in processed state (loadState 1). + // If no file was cache-loaded (iLastCacheFileId < 0) or the cache load failed, + // let the standard LoadRequestedModels run as fallback. + if (iLastCacheFileId >= 0) + { + auto* pInfo = reinterpret_cast(reinterpret_cast(CStreaming__ms_aInfoForModel) + iLastCacheFileId * 20); + if (pInfo->uiLoadflag == 1) + return true; + } + } return false; } // Hook info -#define HOOKPOS_CStreamingLoadRequestedModels 0x15670A0 -#define HOOKSIZE_CStreamingLoadRequestedModels 5 -DWORD RETURN_CStreamingLoadRequestedModels = 0x15670A5; -DWORD RETURN_CStreamingLoadRequestedModelsB = 0x156711B; -void _declspec(naked) HOOK_CStreamingLoadRequestedModels() +#define HOOKPOS_CStreamingLoadRequestedModels 0x15670A0 +#define HOOKSIZE_CStreamingLoadRequestedModels 5 +DWORD RETURN_CStreamingLoadRequestedModels = 0x15670A5; +DWORD RETURN_CStreamingLoadRequestedModelsB = 0x156711B; +static void __declspec(naked) HOOK_CStreamingLoadRequestedModels() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*0] @@ -208,6 +237,7 @@ void _declspec(naked) HOOK_CStreamingLoadRequestedModels() popad jmp RETURN_CStreamingLoadRequestedModelsB } + // clang-format on } // @@ -229,14 +259,17 @@ bool IsPlayerImgDirLoaded() // Hook info #define HOOKSIZE_LoadingPlayerImgDir 5 -#define HOOKPOS_LoadingPlayerImgDir 0x5A69E3 // 005A69D6 -> CClothesBuilder::CreateSkinnedClump -> playerImgEntries -static constexpr std::uintptr_t RETURN_LoadingPlayerImgDirA = 0x5A69E8; // push 00000226 { 550 } -static constexpr std::uintptr_t RETURN_LoadingPlayerImgDirB = 0x5A6A06; // return of CreateSkinnedClump function +#define HOOKPOS_LoadingPlayerImgDir 0x5A69E3 // 005A69D6 -> CClothesBuilder::CreateSkinnedClump -> playerImgEntries +static constexpr std::uintptr_t RETURN_LoadingPlayerImgDirA = 0x5A69E8; // push 00000226 { 550 } +static constexpr std::uintptr_t RETURN_LoadingPlayerImgDirB = 0x5A6A06; // return of CreateSkinnedClump function -void _declspec(naked) HOOK_LoadingPlayerImgDir() +static void __declspec(naked) HOOK_LoadingPlayerImgDir() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // hook from 005A69E3 5 bytes - _asm + // clang-format off + __asm { pushad call IsPlayerImgDirLoaded @@ -254,6 +287,7 @@ void _declspec(naked) HOOK_LoadingPlayerImgDir() popad jmp RETURN_LoadingPlayerImgDirB } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -263,22 +297,74 @@ void _declspec(naked) HOOK_LoadingPlayerImgDir() ////////////////////////////////////////////////////////////////////////////////////////// bool SetClothingDirectorySize(int directorySize) { - DirectoryInfoSA* clothesDirectory = new DirectoryInfoSA[directorySize]; + if (directorySize <= 0 || directorySize > 0xFFFF) + return false; + + const std::uint16_t usDirectorySize = static_cast(directorySize); + DirectoryInfoSA* clothesDirectory = new DirectoryInfoSA[static_cast(directorySize)]; if (!clothesDirectory) return false; // CClothesBuilder::LoadCdDirectory(void) - MemPut(0x5A4190 + 1, reinterpret_cast(clothesDirectory)); // push offset _playerImgEntries; headers - MemPut(0x5A4195 + 1, directorySize); // push 550 ; count - MemPut(0x5A69E8 + 1, directorySize); // push 550 ; count + MemPut(0x5A4190 + 1, reinterpret_cast(clothesDirectory)); // push offset _playerImgEntries; headers + MemPut(0x5A4195 + 1, usDirectorySize); // push 550 ; count + MemPut(0x5A69E8 + 1, usDirectorySize); // push 550 ; count g_playerImgEntries = reinterpret_cast(clothesDirectory); - g_playerImgSize = directorySize; + g_playerImgSize = usDirectorySize; return true; } +//////////////////////////////////////////////////////////////////////////////////////////////// +// +// CClothesBuilder::CopyTexture null-check hook +// SA CopyTexture at 0x5A5730 derefs the texture parameter without a null +// check. With MTA's fast clothes caching, a cache load failure can leave a TXD dictionary +// invalid. Misc33's hook on RwTexDictionaryFindNamedTexture converts the resulting invalid- +// dictionary crash into a NULL return, which then reaches CopyTexture as a NULL parameter. +// This hook catches that NULL, reports CrashAverted(43), and returns NULL. +// Note: callers of CopyTexture do not null-check the return value, so a crash may still +// occur at a different address. The primary prevention is the loadState verification in +// ShouldSkipLoadRequestedModels; this hook is a last-resort diagnostic. +// +// Original bytes at 0x5A5730 (5 bytes): +// 8B 44 24 04 mov eax, [esp+4] ; get texture param +// 53 push ebx ; save ebx +// (then 8B 18 mov ebx, [eax] ; CRASH when eax=NULL) +// +#define HOOKPOS_CClothesBuilder_CopyTexture 0x5A5730 +#define HOOKSIZE_CClothesBuilder_CopyTexture 5 +static constexpr DWORD RETURN_CClothesBuilder_CopyTexture = 0x5A5735; + +static void _declspec(naked) HOOK_CClothesBuilder_CopyTexture() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + mov eax, [esp+4] // texture parameter + test eax, eax + jz copytex_null + + // Replicate overwritten instructions and continue + push ebx + jmp RETURN_CClothesBuilder_CopyTexture + + copytex_null: + pushad + push 43 + call OnCrashAverted + add esp, 4 + popad + xor eax, eax // return NULL + ret + } + // clang-format on +} + ////////////////////////////////////////////////////////////////////////////////////////// // // Setup hooks for ClothesSpeedUp @@ -291,4 +377,5 @@ void CMultiplayerSA::InitHooks_ClothesSpeedUp() EZHookInstall(CStreamingLoadRequestedModels); EZHookInstall(LoadingPlayerImgDir); EZHookInstall(CallCStreamingInfoAddToList); + EZHookInstall(CClothesBuilder_CopyTexture); } diff --git a/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp b/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp index 4ddeb382593..4af196856a4 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp @@ -17,21 +17,26 @@ #include "../game_sa/TaskBasicSA.h" #include "../game_sa/CFxSystemBPSA.h" #include "../game_sa/CFxSystemSA.h" +#include "../game_sa/CColModelSA.h" +#include "../game_sa/CTxdPoolSA.h" extern CCoreInterface* g_pCore; -void CPlayerPed__ProcessControl_Abort(); - // // Support for crash stats // void OnCrashAverted(uint uiId); void OnEnterCrashZone(uint uiId); -void _declspec(naked) CrashAverted() +void OnRequestDeferredStreamingMemoryRelief(); + +static void __declspec(naked) CrashAverted() { - _asm - { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { pushfd pushad push [esp+4+32+4*1] @@ -40,27 +45,176 @@ void _declspec(naked) CrashAverted() popad popfd retn 4 + } + // clang-format on +} + +static bool HasReadAccess(DWORD dwProtect) noexcept +{ + if (dwProtect & PAGE_GUARD) + return false; + + dwProtect &= 0xFF; + + if (dwProtect == PAGE_NOACCESS) + return false; + + return dwProtect == PAGE_READONLY || dwProtect == PAGE_READWRITE || dwProtect == PAGE_WRITECOPY || dwProtect == PAGE_EXECUTE || + dwProtect == PAGE_EXECUTE_READ || dwProtect == PAGE_EXECUTE_READWRITE || dwProtect == PAGE_EXECUTE_WRITECOPY; +} + +static bool HasWriteAccess(DWORD dwProtect) noexcept +{ + if (dwProtect & PAGE_GUARD) + return false; + + dwProtect &= 0xFF; + + return dwProtect == PAGE_READWRITE || dwProtect == PAGE_WRITECOPY || dwProtect == PAGE_EXECUTE_READWRITE || dwProtect == PAGE_EXECUTE_WRITECOPY; +} + +static constexpr std::size_t REGION_CACHE_SIZE = 8; +static constexpr std::uintptr_t NUM_LOWMEM_THRESHOLD = 0x10000; + +#define NUM_LOWMEM_THRESHOLD_ASM 0x10000 + +struct CachedRegion +{ + std::uintptr_t start{}; + std::uintptr_t end{}; + DWORD state{}; + DWORD protect{}; +}; + +static bool QueryRegionCached(std::uintptr_t address, DWORD& outState, DWORD& outProtect, std::uintptr_t& outEnd) noexcept +{ + static thread_local CachedRegion s_cache[REGION_CACHE_SIZE]{}; + static thread_local std::size_t s_nextSlot{}; + + for (const auto& entry : s_cache) + { + if (entry.start != 0 && address >= entry.start && address <= entry.end) + { + outState = entry.state; + outProtect = entry.protect; + outEnd = entry.end; + return true; + } + } + + MEMORY_BASIC_INFORMATION mbi{}; + if (VirtualQuery(reinterpret_cast(address), &mbi, sizeof(mbi)) != sizeof(mbi)) + return false; + + const auto regionSize = static_cast(mbi.RegionSize); + if (regionSize == 0) + return false; + + auto& slot = s_cache[s_nextSlot]; + s_nextSlot = (s_nextSlot + 1) % REGION_CACHE_SIZE; + + slot.start = reinterpret_cast(mbi.BaseAddress); + slot.state = mbi.State; + slot.protect = mbi.Protect; + + const auto endPlusOne = slot.start + regionSize; + slot.end = (endPlusOne <= slot.start) ? static_cast(-1) : (endPlusOne - 1); + + outState = slot.state; + outProtect = slot.protect; + outEnd = slot.end; + return true; +} + +static bool IsReadablePtr(const void* ptr, std::size_t size) noexcept +{ + if (ptr == nullptr || size == 0) + return false; + + const auto start = reinterpret_cast(ptr); + if (start < NUM_LOWMEM_THRESHOLD) + return false; + + const auto end = start + size - 1; + if (end < start) + return false; + + auto cur = start; + for (;;) + { + DWORD state{}, protect{}; + std::uintptr_t regionEnd{}; + if (!QueryRegionCached(cur, state, protect, regionEnd)) + return false; + + if (state != MEM_COMMIT || !HasReadAccess(protect)) + return false; + + if (regionEnd >= end) + return true; + + if (regionEnd < cur || regionEnd == static_cast(-1)) + return false; + + cur = regionEnd + 1; + } +} + +static bool IsWritablePtr(void* ptr, std::size_t size) noexcept +{ + if (ptr == nullptr || size == 0) + return false; + + const auto start = reinterpret_cast(ptr); + if (start < NUM_LOWMEM_THRESHOLD) + return false; + + const auto end = start + size - 1; + if (end < start) + return false; + + auto cur = start; + for (;;) + { + DWORD state{}, protect{}; + std::uintptr_t regionEnd{}; + if (!QueryRegionCached(cur, state, protect, regionEnd)) + return false; + + if (state != MEM_COMMIT || !HasWriteAccess(protect)) + return false; + + if (regionEnd >= end) + return true; + + if (regionEnd < cur || regionEnd == static_cast(-1)) + return false; + + cur = regionEnd + 1; } } //////////////////////////////////////////////////////////////////////// // CCustomCarEnvMapPipeline::CustomPipeRenderCB -// +// // Null mesh material pointer //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc1 0x5D9A6E -#define HOOKSIZE_CrashFix_Misc1 6 -DWORD RETURN_CrashFix_Misc1 = 0x5D9A74; -void _declspec(naked) HOOK_CrashFix_Misc1() +#define HOOKPOS_CrashFix_Misc1 0x5D9A6E +#define HOOKSIZE_CrashFix_Misc1 6 +DWORD RETURN_CrashFix_Misc1 = 0x5D9A74; +static void __declspec(naked) HOOK_CrashFix_Misc1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov eax,dword ptr [esp+18h] test eax,eax je cont mov eax,dword ptr ds:[008D12CCh] - mov ecx,dword ptr [eax+esi] // If [eax+esi] (mesh->material) is 0, it causes a crash + mov ecx,dword ptr [eax+esi] // If [eax+esi] (mesh->material) is 0, it causes a crash test ecx,ecx jne cont push 1 @@ -69,33 +223,37 @@ void _declspec(naked) HOOK_CrashFix_Misc1() cont: jmp RETURN_CrashFix_Misc1 } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CAutomobile::ProcessControl -// +// // Null CColModel pointer or corrupted m_pColData //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc2 0x6B18B0 -#define HOOKSIZE_CrashFix_Misc2 9 -DWORD RETURN_CrashFix_Misc2 = 0x6B18B9; -DWORD RETURN_CrashFix_Misc2B = 0x6B3775; -void _declspec(naked) HOOK_CrashFix_Misc2() +#define HOOKPOS_CrashFix_Misc2 0x6B18B0 +#define HOOKSIZE_CrashFix_Misc2 9 +DWORD RETURN_CrashFix_Misc2 = 0x6B18B9; +DWORD RETURN_CrashFix_Misc2B = 0x6B3775; +static void __declspec(naked) HOOK_CrashFix_Misc2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { test eax,eax - je cont // Skip much code if eax is zero (vehicle has no colmodel) + je cont // Skip much code if eax is zero (vehicle has no colmodel) mov eax,dword ptr [eax+2Ch] test eax,eax - je cont // Skip much code if eax is zero (colmodel has no coldata) + je cont // Skip much code if eax is zero (colmodel has no coldata) mov ebx,dword ptr [eax+10h] test ebx,ebx - je cont // Skip much code if ebx is zero (coldata has no suspension lines) + je cont // Skip much code if ebx is zero (coldata has no suspension lines) mov cl,byte ptr [esi+429h] jmp RETURN_CrashFix_Misc2 @@ -104,47 +262,27 @@ void _declspec(naked) HOOK_CrashFix_Misc2() call CrashAverted jmp RETURN_CrashFix_Misc2B } -} - -//////////////////////////////////////////////////////////////////////// -// CTaskSimpleCarOpenDoorFromOutside::ComputeAnimID -// -// Invalid m_veh pointer -//////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc3 0x645FD9 -#define HOOKSIZE_CrashFix_Misc3 6 -DWORD RETURN_CrashFix_Misc3 = 0x645FDF; -void _declspec(naked) HOOK_CrashFix_Misc3() -{ - _asm - { - test ecx,ecx - je cont // Skip much code if ecx is zero (invalid m_veh in CTaskSimpleCarOpenDoorFromOutside) - - mov edx,dword ptr [ecx+384h] - jmp RETURN_CrashFix_Misc3 - cont: - push 3 - call CrashAverted - jmp CPlayerPed__ProcessControl_Abort - } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CAESoundManager::Service -// +// // Division by 0 //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc4 0x4F02D2 -#define HOOKSIZE_CrashFix_Misc4 5 -DWORD RETURN_CrashFix_Misc4 = 0x4F02D7; -DWORD RETURN_CrashFix_Misc4B = 0x4F0B07; -void _declspec(naked) HOOK_CrashFix_Misc4() +#define HOOKPOS_CrashFix_Misc4 0x4F02D2 +#define HOOKSIZE_CrashFix_Misc4 5 +DWORD RETURN_CrashFix_Misc4 = 0x4F02D7; +DWORD RETURN_CrashFix_Misc4B = 0x4F0B07; +static void __declspec(naked) HOOK_CrashFix_Misc4() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { test ecx,ecx - je cont // Skip much code if ecx is zero (avoid divide by zero in soundmanager::service) + je cont // Skip much code if ecx is zero (avoid divide by zero in soundmanager::service) cdq idiv ecx @@ -155,25 +293,28 @@ void _declspec(naked) HOOK_CrashFix_Misc4() call CrashAverted jmp RETURN_CrashFix_Misc4B } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CPed::SetPedPositionInCar -// +// // Null pointer m_pVehicleStruct in the CVehicleModelInfo structure //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc5 0x5DF949 -#define HOOKSIZE_CrashFix_Misc5 7 -DWORD RETURN_CrashFix_Misc5 = 0x5DF950; -DWORD RETURN_CrashFix_Misc5B = 0x5DFCC4; -void _declspec(naked) HOOK_CrashFix_Misc5() +#define HOOKPOS_CrashFix_Misc5 0x5DF949 +#define HOOKSIZE_CrashFix_Misc5 7 +DWORD RETURN_CrashFix_Misc5 = 0x5DF950; +DWORD RETURN_CrashFix_Misc5B = 0x5DFCC4; +static void __declspec(naked) HOOK_CrashFix_Misc5() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + __asm { mov edi, dword ptr[ARRAY_ModelInfo] mov edi, dword ptr [ecx*4+edi] mov edi, dword ptr [edi+5Ch] test edi, edi - je cont // Skip much code if edi is zero + je cont // Skip much code if edi is zero mov edi, dword ptr[ARRAY_ModelInfo] mov edi, dword ptr [ecx*4+edi] @@ -193,16 +334,19 @@ void _declspec(naked) HOOK_CrashFix_Misc5() // // Null pointer to object in the BlendNodeArrays array of the AnimBlendUpdateData structure //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc6 0x4D1750 -#define HOOKSIZE_CrashFix_Misc6 5 -DWORD RETURN_CrashFix_Misc6 = 0x4D1755; -DWORD RETURN_CrashFix_Misc6B = 0x4D1A44; -void _declspec(naked) HOOK_CrashFix_Misc6() +#define HOOKPOS_CrashFix_Misc6 0x4D1750 +#define HOOKSIZE_CrashFix_Misc6 5 +DWORD RETURN_CrashFix_Misc6 = 0x4D1755; +DWORD RETURN_CrashFix_Misc6B = 0x4D1A44; +static void __declspec(naked) HOOK_CrashFix_Misc6() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { test ecx, ecx - je cont // Skip much code if ecx is zero (ped has no anim something) + je cont // Skip much code if ecx is zero (ped has no anim something) mov eax, dword ptr [ecx+10h] test eax, eax @@ -212,6 +356,7 @@ void _declspec(naked) HOOK_CrashFix_Misc6() call CrashAverted jmp RETURN_CrashFix_Misc6B } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -221,16 +366,19 @@ void _declspec(naked) HOOK_CrashFix_Misc6() // // Null colModel pointer //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc7 0x417BF8 -#define HOOKSIZE_CrashFix_Misc7 5 -DWORD RETURN_CrashFix_Misc7 = 0x417BFD; -DWORD RETURN_CrashFix_Misc7B = 0x417BFF; -void _declspec(naked) HOOK_CrashFix_Misc7() +#define HOOKPOS_CrashFix_Misc7 0x417BF8 +#define HOOKSIZE_CrashFix_Misc7 5 +DWORD RETURN_CrashFix_Misc7 = 0x417BFD; +DWORD RETURN_CrashFix_Misc7B = 0x417BFF; +static void __declspec(naked) HOOK_CrashFix_Misc7() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { test ecx, ecx - je cont // Skip much code if ecx is zero (no colmodel) + je cont // Skip much code if ecx is zero (no colmodel) mov esi, dword ptr [ecx+2Ch] test esi, esi @@ -240,6 +388,7 @@ void _declspec(naked) HOOK_CrashFix_Misc7() call CrashAverted jmp RETURN_CrashFix_Misc7B } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -249,16 +398,19 @@ void _declspec(naked) HOOK_CrashFix_Misc7() // // Null pointer atomic->geometry in the RpAtomic //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc8 0x73485D -#define HOOKSIZE_CrashFix_Misc8 5 -DWORD RETURN_CrashFix_Misc8 = 0x734862; -DWORD RETURN_CrashFix_Misc8B = 0x734871; -void _declspec(naked) HOOK_CrashFix_Misc8() +#define HOOKPOS_CrashFix_Misc8 0x73485D +#define HOOKSIZE_CrashFix_Misc8 5 +DWORD RETURN_CrashFix_Misc8 = 0x734862; +DWORD RETURN_CrashFix_Misc8B = 0x734871; +static void __declspec(naked) HOOK_CrashFix_Misc8() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { test ecx, ecx - je cont // Skip much code if ecx is zero (no 2d effect plugin) + je cont // Skip much code if ecx is zero (no 2d effect plugin) mov ecx, dword ptr [edx+ecx] test ecx, ecx @@ -268,6 +420,7 @@ void _declspec(naked) HOOK_CrashFix_Misc8() call CrashAverted jmp RETURN_CrashFix_Misc8B } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -277,16 +430,19 @@ void _declspec(naked) HOOK_CrashFix_Misc8() // // Null pointer projectile of type CObject* in the array CProjectileInfo::ms_apProjectile //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc9 0x738B64 -#define HOOKSIZE_CrashFix_Misc9 6 -DWORD RETURN_CrashFix_Misc9 = 0x738B6A; -DWORD RETURN_CrashFix_Misc9B = 0x73983A; -void _declspec(naked) HOOK_CrashFix_Misc9() +#define HOOKPOS_CrashFix_Misc9 0x738B64 +#define HOOKSIZE_CrashFix_Misc9 6 +DWORD RETURN_CrashFix_Misc9 = 0x738B6A; +DWORD RETURN_CrashFix_Misc9B = 0x73983A; +static void __declspec(naked) HOOK_CrashFix_Misc9() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { test esi, esi - je cont // Skip much code if esi is zero (invalid projectile) + je cont // Skip much code if esi is zero (invalid projectile) mov eax, dword ptr [esi+40h] test ah, 1 @@ -296,6 +452,7 @@ void _declspec(naked) HOOK_CrashFix_Misc9() call CrashAverted jmp RETURN_CrashFix_Misc9B } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -305,16 +462,19 @@ void _declspec(naked) HOOK_CrashFix_Misc9() // // Invalid pointer to a vector //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc10 0x5334FE -#define HOOKSIZE_CrashFix_Misc10 6 -DWORD RETURN_CrashFix_Misc10 = 0x533504; -DWORD RETURN_CrashFix_Misc10B = 0x533539; -void _declspec(naked) HOOK_CrashFix_Misc10() +#define HOOKPOS_CrashFix_Misc10 0x5334FE +#define HOOKSIZE_CrashFix_Misc10 6 +DWORD RETURN_CrashFix_Misc10 = 0x533504; +DWORD RETURN_CrashFix_Misc10B = 0x533539; +static void __declspec(naked) HOOK_CrashFix_Misc10() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { cmp ecx, 0x80 - jb cont // Skip much code if ecx is small (invalid vector pointer) + jb cont // Skip much code if ecx is small (invalid vector pointer) mov edx, dword ptr [ecx] mov dword ptr [esp], edx @@ -328,6 +488,7 @@ void _declspec(naked) HOOK_CrashFix_Misc10() mov dword ptr [ecx+8],0 jmp RETURN_CrashFix_Misc10B } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -337,16 +498,19 @@ void _declspec(naked) HOOK_CrashFix_Misc10() // // The crash likely occurs due to invalid data passed as the second argument //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc11 0x4D2C62 -#define HOOKSIZE_CrashFix_Misc11 5 -DWORD RETURN_CrashFix_Misc11 = 0x4D2C67; -DWORD RETURN_CrashFix_Misc11B = 0x4D2E03; -void _declspec(naked) HOOK_CrashFix_Misc11() +#define HOOKPOS_CrashFix_Misc11 0x4D2C62 +#define HOOKSIZE_CrashFix_Misc11 5 +DWORD RETURN_CrashFix_Misc11 = 0x4D2C67; +DWORD RETURN_CrashFix_Misc11B = 0x4D2E03; +static void __declspec(naked) HOOK_CrashFix_Misc11() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { test ecx, ecx - je cont // Skip much code if ecx is zero (invalid anim somthing) + je cont // Skip much code if ecx is zero (invalid anim somthing) mov eax, dword ptr [ecx+10h] test eax, eax @@ -356,6 +520,7 @@ void _declspec(naked) HOOK_CrashFix_Misc11() call CrashAverted jmp RETURN_CrashFix_Misc11B } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -365,16 +530,19 @@ void _declspec(naked) HOOK_CrashFix_Misc11() // // Null pointer of type CAnimBlendHierarchy passed to the function //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc12 0x4D41C5 -#define HOOKSIZE_CrashFix_Misc12 5 -DWORD RETURN_CrashFix_Misc12 = 0x4D41CA; -DWORD RETURN_CrashFix_Misc12B = 0x4D4222; -void _declspec(naked) HOOK_CrashFix_Misc12() +#define HOOKPOS_CrashFix_Misc12 0x4D41C5 +#define HOOKSIZE_CrashFix_Misc12 5 +DWORD RETURN_CrashFix_Misc12 = 0x4D41CA; +DWORD RETURN_CrashFix_Misc12B = 0x4D4222; +static void __declspec(naked) HOOK_CrashFix_Misc12() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { test edi, edi - je cont // Skip much code if edi is zero (invalid anim somthing) + je cont // Skip much code if edi is zero (invalid anim somthing) mov al, byte ptr [edi+0Bh] test al, al @@ -384,6 +552,7 @@ void _declspec(naked) HOOK_CrashFix_Misc12() call CrashAverted jmp RETURN_CrashFix_Misc12B } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -391,16 +560,19 @@ void _declspec(naked) HOOK_CrashFix_Misc12() // // Invalid animation (Null pointer returned by CAnimBlendAssocGroup::GetAnimation) //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc13 0x4D464E -#define HOOKSIZE_CrashFix_Misc13 6 -DWORD RETURN_CrashFix_Misc13 = 0x4D4654; -DWORD RETURN_CrashFix_Misc13B = 0x4D4764; -void _declspec(naked) HOOK_CrashFix_Misc13() +#define HOOKPOS_CrashFix_Misc13 0x4D464E +#define HOOKSIZE_CrashFix_Misc13 6 +DWORD RETURN_CrashFix_Misc13 = 0x4D4654; +DWORD RETURN_CrashFix_Misc13B = 0x4D4764; +static void __declspec(naked) HOOK_CrashFix_Misc13() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { cmp eax, 0x2480 - jb cont // Skip much code if eax is less than 0x480 (invalid anim) + jb cont // Skip much code if eax is less than 0x480 (invalid anim) mov al, byte ptr [eax+0Ah] shr al, 5 @@ -410,23 +582,27 @@ void _declspec(naked) HOOK_CrashFix_Misc13() call CrashAverted jmp RETURN_CrashFix_Misc13B } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CAEFrontendAudioEntity::AddAudioEvent -// +// // Invalid pointer to the array CAEAudioEntity::m_pAudioEventVolumes //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc14 0x4DD4B5 -#define HOOKSIZE_CrashFix_Misc14 6 -DWORD RETURN_CrashFix_Misc14 = 0x4DD4BB; -void _declspec(naked) HOOK_CrashFix_Misc14() +#define HOOKPOS_CrashFix_Misc14 0x4DD4B5 +#define HOOKSIZE_CrashFix_Misc14 6 +DWORD RETURN_CrashFix_Misc14 = 0x4DD4BB; +static void __declspec(naked) HOOK_CrashFix_Misc14() { - _asm - { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { mov eax, dword ptr ds:[0BD00F8h] cmp eax, 0 - je cont // Skip much code if eax is zero ( Audio event volumes table not initialized ) + je cont // Skip much code if eax is zero ( Audio event volumes table not initialized ) sub esp, 0D4h jmp RETURN_CrashFix_Misc14 @@ -435,17 +611,34 @@ void _declspec(naked) HOOK_CrashFix_Misc14() call CrashAverted add esp, 12 retn 12 - } + } + // clang-format on } //////////////////////////////////////////////////////////////////////// void _cdecl DoWait(HANDLE hHandle) { - DWORD dwWait = 4000; + static DWORD s_consecutiveTimeouts = 0; + static DWORD s_lastCallTick = 0; + + DWORD now = SharedUtil::GetTickCount32(); + + // Reset counter after a quiet period - a 10+ second gap means + // we moved on to a different streaming operation + if (s_lastCallTick != 0 && (now - s_lastCallTick) > 10000) + s_consecutiveTimeouts = 0; + s_lastCallTick = now; + + // After a consecutive timeout, use a short wait so + // LoadAllRequestedModels doesn't accumulate multi-second freezes + // when the same I/O issue keeps re-ocurring + DWORD dwWait = (s_consecutiveTimeouts >= 1) ? 100 : 4000; + DWORD dwResult = WaitForSingleObject(hHandle, dwWait); if (dwResult == WAIT_TIMEOUT) { - AddReportLog(6211, SString("WaitForSingleObject timed out with %08x and %dms", hHandle, dwWait)); + s_consecutiveTimeouts++; + AddReportLog(6211, SString("WaitForSingleObject timed out with %08x and %dms (consecutive: %u)", hHandle, dwWait, s_consecutiveTimeouts)); // This thread lock bug in GTA will have to be fixed one day. // Until then, a 5 second freeze should be long enough for the loading thread to have finished it's job. #if 0 @@ -457,17 +650,29 @@ void _cdecl DoWait(HANDLE hHandle) ") , _CRT_WIDE(__FILE__), __LINE__); #endif - dwResult = WaitForSingleObject(hHandle, 1000); + if (dwWait >= 4000) + { + dwResult = WaitForSingleObject(hHandle, 1000); + if (dwResult != WAIT_TIMEOUT) + s_consecutiveTimeouts = 0; // Completed during retry, not persistent + } + } + else + { + s_consecutiveTimeouts = 0; } } // hook info -#define HOOKPOS_FreezeFix_Misc15 0x156CDAE -#define HOOKSIZE_FreezeFix_Misc15 6 -DWORD RETURN_FreezeFix_Misc15 = 0x156CDB4; -void _declspec(naked) HOOK_FreezeFix_Misc15() +#define HOOKPOS_FreezeFix_Misc15 0x156CDAE +#define HOOKSIZE_FreezeFix_Misc15 6 +DWORD RETURN_FreezeFix_Misc15 = 0x156CDB4; +static void __declspec(naked) HOOK_FreezeFix_Misc15() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pop eax pop edx @@ -480,6 +685,7 @@ void _declspec(naked) HOOK_FreezeFix_Misc15() popad jmp RETURN_FreezeFix_Misc15 } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -487,17 +693,20 @@ void _declspec(naked) HOOK_FreezeFix_Misc15() // // RpAnimBlendClumpGetFirstAssociation returns null pointer //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc16 0x5E5815 -#define HOOKSIZE_CrashFix_Misc16 6 -DWORD RETURN_CrashFix_Misc16 = 0x5E581B; -void _declspec(naked) HOOK_CrashFix_Misc16() +#define HOOKPOS_CrashFix_Misc16 0x5E5815 +#define HOOKSIZE_CrashFix_Misc16 6 +DWORD RETURN_CrashFix_Misc16 = 0x5E581B; +static void __declspec(naked) HOOK_CrashFix_Misc16() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { cmp eax, 0 - je cont // Skip much code if eax is zero ( RpAnimBlendClumpGetFirstAssociation returns NULL ) + je cont // Skip much code if eax is zero ( RpAnimBlendClumpGetFirstAssociation returns NULL ) - // continue standard path + // continue standard path movsx ecx, word ptr [eax+2Ch] xor edi, edi jmp RETURN_CrashFix_Misc16 @@ -508,6 +717,7 @@ void _declspec(naked) HOOK_CrashFix_Misc16() add esp, 96 retn } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -515,18 +725,21 @@ void _declspec(naked) HOOK_CrashFix_Misc16() // // Null pointer for the objectList (0x90) field of the RwFrame structure //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc17 0x7F120E -#define HOOKSIZE_CrashFix_Misc17 6 -DWORD RETURN_CrashFix_Misc17 = 0x7F1214; -DWORD RETURN_CrashFix_Misc17B = 0x7F1236; -void _declspec(naked) HOOK_CrashFix_Misc17() +#define HOOKPOS_CrashFix_Misc17 0x7F120E +#define HOOKSIZE_CrashFix_Misc17 6 +DWORD RETURN_CrashFix_Misc17 = 0x7F1214; +DWORD RETURN_CrashFix_Misc17B = 0x7F1236; +static void __declspec(naked) HOOK_CrashFix_Misc17() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { cmp eax, 0 - je cont // Skip much code if eax is zero + je cont // Skip much code if eax is zero - // continue standard path + // continue standard path mov eax, [eax+90h] jmp RETURN_CrashFix_Misc17 @@ -535,6 +748,7 @@ void _declspec(naked) HOOK_CrashFix_Misc17() call CrashAverted jmp RETURN_CrashFix_Misc17B } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -542,17 +756,20 @@ void _declspec(naked) HOOK_CrashFix_Misc17() // // Null pointer frame returned by CClumpModelInfo::GetFrameFromId //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc18 0x4C7DAD -#define HOOKSIZE_CrashFix_Misc18 7 -DWORD RETURN_CrashFix_Misc18 = 0x4C7DB4; -void _declspec(naked) HOOK_CrashFix_Misc18() +#define HOOKPOS_CrashFix_Misc18 0x4C7DAD +#define HOOKSIZE_CrashFix_Misc18 7 +DWORD RETURN_CrashFix_Misc18 = 0x4C7DB4; +static void __declspec(naked) HOOK_CrashFix_Misc18() { - _asm - { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { cmp ebp, 0 - je cont // Skip much code if ebp is zero + je cont // Skip much code if ebp is zero - // continue standard path + // continue standard path mov edx,dword ptr [ebp+40h] mov eax,dword ptr [esp+10h] jmp RETURN_CrashFix_Misc18 @@ -568,7 +785,8 @@ void _declspec(naked) HOOK_CrashFix_Misc18() mov dword ptr [eax+8],edx pop ebp ret 0Ch - } + } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -576,18 +794,21 @@ void _declspec(naked) HOOK_CrashFix_Misc18() // // The pointer passed as the first argument of type RwFrame to the function is null //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc19 0x7F0BF7 -#define HOOKSIZE_CrashFix_Misc19 6 -DWORD RETURN_CrashFix_Misc19 = 0x7F0BFD; -DWORD RETURN_CrashFix_Misc19B = 0x7F0C20; -void _declspec(naked) HOOK_CrashFix_Misc19() +#define HOOKPOS_CrashFix_Misc19 0x7F0BF7 +#define HOOKSIZE_CrashFix_Misc19 6 +DWORD RETURN_CrashFix_Misc19 = 0x7F0BFD; +DWORD RETURN_CrashFix_Misc19B = 0x7F0C20; +static void __declspec(naked) HOOK_CrashFix_Misc19() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { cmp esi, 0 - je cont // Skip much code if esi is zero + je cont // Skip much code if esi is zero - // continue standard path + // continue standard path mov eax, [esi+98h] jmp RETURN_CrashFix_Misc19 @@ -598,24 +819,28 @@ void _declspec(naked) HOOK_CrashFix_Misc19() test edx,edx jmp RETURN_CrashFix_Misc19B } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CPlaceable::RemoveMatrix -// +// // "this" is invalid //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc20 0x54F3B0 -#define HOOKSIZE_CrashFix_Misc20 6 -DWORD RETURN_CrashFix_Misc20 = 0x54F3B6; -void _declspec(naked) HOOK_CrashFix_Misc20() +#define HOOKPOS_CrashFix_Misc20 0x54F3B0 +#define HOOKSIZE_CrashFix_Misc20 6 +DWORD RETURN_CrashFix_Misc20 = 0x54F3B6; +static void __declspec(naked) HOOK_CrashFix_Misc20() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { cmp ecx, 0 - je cont // Skip much code if ecx is zero + je cont // Skip much code if ecx is zero - // continue standard path + // continue standard path sub esp, 10h mov eax, [ecx+14h] jmp RETURN_CrashFix_Misc20 @@ -625,11 +850,12 @@ void _declspec(naked) HOOK_CrashFix_Misc20() call CrashAverted retn } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CTaskSimpleCarFallOut::FinishAnimFallOutCB -// +// // Handle CTaskSimpleCarFallOut::FinishAnimFallOutCB having wrong data //////////////////////////////////////////////////////////////////////// bool IsTaskSimpleCarFallOutValid(CAnimBlendAssociationSAInterface* pAnimBlendAssociation, CTaskSimpleCarFallOutSAInterface* pTask) @@ -656,12 +882,15 @@ bool IsTaskSimpleCarFallOutValid(CAnimBlendAssociationSAInterface* pAnimBlendAss return true; } -#define HOOKPOS_CrashFix_Misc21 0x648EE0 -#define HOOKSIZE_CrashFix_Misc21 7 -DWORD RETURN_CrashFix_Misc21 = 0x648EE7; -void _declspec(naked) HOOK_CrashFix_Misc21() +#define HOOKPOS_CrashFix_Misc21 0x648EE0 +#define HOOKSIZE_CrashFix_Misc21 7 +DWORD RETURN_CrashFix_Misc21 = 0x648EE7; +static void __declspec(naked) HOOK_CrashFix_Misc21() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*2] @@ -670,9 +899,9 @@ void _declspec(naked) HOOK_CrashFix_Misc21() add esp, 4*2 cmp al,0 popad - je cont // Skip much code if CTaskSimpleCarFallOut is not valid + je cont // Skip much code if CTaskSimpleCarFallOut is not valid - // continue standard path + // continue standard path mov eax, [esp+8] mov ecx, [eax+10h] jmp RETURN_CrashFix_Misc21 @@ -682,6 +911,7 @@ void _declspec(naked) HOOK_CrashFix_Misc21() call CrashAverted retn } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -689,19 +919,22 @@ void _declspec(naked) HOOK_CrashFix_Misc21() // // this->m_clumpAssoc.m_pNodeArray[v5] is invalid //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc22 0x4CEF08 -#define HOOKSIZE_CrashFix_Misc22 6 -DWORD RETURN_CrashFix_Misc22 = 0x4CEF25; -void _declspec(naked) HOOK_CrashFix_Misc22() +#define HOOKPOS_CrashFix_Misc22 0x4CEF08 +#define HOOKSIZE_CrashFix_Misc22 6 +DWORD RETURN_CrashFix_Misc22 = 0x4CEF25; +static void __declspec(naked) HOOK_CrashFix_Misc22() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov edx,dword ptr [edi+0Ch] cmp edx, 0x480 - jb altcode // Fill output with zeros if edx is low + jb altcode // Fill output with zeros if edx is low - // do standard code + // do standard code lp1: mov edx,dword ptr [edi+0Ch] mov edx,dword ptr [edx+eax*4] @@ -716,7 +949,7 @@ void _declspec(naked) HOOK_CrashFix_Misc22() jl lp1 jmp RETURN_CrashFix_Misc22 - // do alternate code + // do alternate code altcode: push 22 call CrashAverted @@ -731,6 +964,7 @@ void _declspec(naked) HOOK_CrashFix_Misc22() jl altcode jmp RETURN_CrashFix_Misc22 } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -738,19 +972,22 @@ void _declspec(naked) HOOK_CrashFix_Misc22() // // Door index is out of range //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc23 0x6E3D10 -#define HOOKSIZE_CrashFix_Misc23 7 -DWORD RETURN_CrashFix_Misc23 = 0x6E3D17; -void _declspec(naked) HOOK_CrashFix_Misc23() +#define HOOKPOS_CrashFix_Misc23 0x6E3D10 +#define HOOKSIZE_CrashFix_Misc23 7 +DWORD RETURN_CrashFix_Misc23 = 0x6E3D17; +static void __declspec(naked) HOOK_CrashFix_Misc23() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Ensure door index is reasonable mov edx, [esp+8] cmp edx,16 jb ok - // zero if out of range + // zero if out of range mov edx,0 mov [esp+8], edx push 23 @@ -762,24 +999,28 @@ void _declspec(naked) HOOK_CrashFix_Misc23() lea eax, [edx+edx*2] jmp RETURN_CrashFix_Misc23 } + // clang-format on } //////////////////////////////////////////////////////////////////////// // RwFrameForAllChildren -// +// // The first argument of type RwFrame received is invalid //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc24 0x7F0DC8 -#define HOOKSIZE_CrashFix_Misc24 6 -DWORD RETURN_CrashFix_Misc24 = 0x7F0DCE; -void _declspec(naked) HOOK_CrashFix_Misc24() +#define HOOKPOS_CrashFix_Misc24 0x7F0DC8 +#define HOOKSIZE_CrashFix_Misc24 6 +DWORD RETURN_CrashFix_Misc24 = 0x7F0DCE; +static void __declspec(naked) HOOK_CrashFix_Misc24() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { cmp ebp, 0x480 - jb cont // Skip code if ebp is low + jb cont // Skip code if ebp is low - // continue standard path + // continue standard path mov eax, [ebp+98h] jmp RETURN_CrashFix_Misc24 @@ -790,193 +1031,1395 @@ void _declspec(naked) HOOK_CrashFix_Misc24() mov eax, 0 jmp RETURN_CrashFix_Misc24 } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CTaskSimpleCarOpenDoorFromOutside::FinishAnimCarOpenDoorFromOutsideCB +// +// Null vehicle pointer +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc25 0x646026 +#define HOOKSIZE_CrashFix_Misc25 5 +DWORD RETURN_CrashFix_Misc25 = 0x64602B; +static void __declspec(naked) HOOK_CrashFix_Misc25() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + // Check for zero pointer to vehicle + mov eax, [esi+0x10] + cmp eax, 0 + jz fix + + // Continue standard path + lea eax,[esp+10h] + push eax + jmp RETURN_CrashFix_Misc25 + + fix: + push 25 + call CrashAverted + // Do special thing + pop esi + pop ecx + retn + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CShotInfo::Update +// +// _creator->m_pIntelligence is invalid +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc26 0x739FA0 +#define HOOKSIZE_CrashFix_Misc26 6 +DWORD RETURN_CrashFix_Misc26 = 0x739FA6; +static void __declspec(naked) HOOK_CrashFix_Misc26() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + // Check for incorrect pointer + cmp ebx, 130h + jz fix + + // Continue standard path + mov edi,dword ptr [ebx+ebp*4] + dec ebp + test edi,edi + jmp RETURN_CrashFix_Misc26 + + fix: + push 26 + call CrashAverted + // Do special thing + mov edi, 0 + dec ebp + test edi,edi + jmp RETURN_CrashFix_Misc26 + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CTaskComplexDieInCar::ControlSubTask +// +// ped or ped->m_pVehicle is null pointer +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc27 0x6377FB +#define HOOKSIZE_CrashFix_Misc27 7 +DWORD RETURN_CrashFix_Misc27 = 0x637802; +static void __declspec(naked) HOOK_CrashFix_Misc27() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + // Execute replaced code + cmp byte ptr [edi+484h], 2 + je cont + + // Check if veh pointer is zero + mov ecx, [edi+58Ch] + test ecx, ecx + jne cont + push 27 + call CrashAverted + +cont: + // Continue standard path + jmp RETURN_CrashFix_Misc27 + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CObject::ProcessGarageDoorBehaviour +// +// Null this->m_pDummyObject pointer +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc28 0x44A4FD +#define HOOKSIZE_CrashFix_Misc28 6 +DWORD RETURN_CrashFix_Misc28 = 0x44A503; +DWORD RETURN_CrashFix_Misc28B = 0x44A650; +static void __declspec(naked) HOOK_CrashFix_Misc28() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + // Execute replaced code + mov eax, [esi+170h] + + // Check if dummy pointer is zero + test eax, eax + jne cont + + push 28 + call CrashAverted + // Skip much code + jmp RETURN_CrashFix_Misc28B + +cont: + // Continue standard path + jmp RETURN_CrashFix_Misc28 + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CAEMP3BankLoader::IsSoundBankLoaded +// +// The value of the argument BankSlotId is invalid +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc29 0x4E022C +#define HOOKSIZE_CrashFix_Misc29 5 +DWORD RETURN_CrashFix_Misc29 = 0x4E0231; +DWORD RETURN_CrashFix_Misc29B = 0x4E0227; +static void __declspec(naked) HOOK_CrashFix_Misc29() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + // Execute replaced code + movsx eax,word ptr [esp+8] + + // Check for out-of-range BankSlotId + test eax, eax + js cont + cmp ax, word ptr [ecx+0Ch] + jae cont + + // Continue standard path + jmp RETURN_CrashFix_Misc29 + +cont: + push 29 + call CrashAverted + // Skip much code + jmp RETURN_CrashFix_Misc29B + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CAEMP3BankLoader::GetSoundBuffer +// +// The value of the argument bankSlotInfoId is out of range +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc43 0x4E028C +#define HOOKSIZE_CrashFix_Misc43 5 +DWORD RETURN_CrashFix_Misc43 = 0x4E0291; +void _declspec(naked) HOOK_CrashFix_Misc43() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + // Validate bankSlotInfoId range + movsx eax, word ptr [esp+8] + + test eax, eax + js bail + cmp ax, word ptr [ecx+0Ch] + jae bail + + // Execute replaced code + push ebx + mov ebx, [ecx] + push ebp + push esi + // Continue standard path + jmp RETURN_CrashFix_Misc43 + +bail: + push 43 + call CrashAverted + // Return null buffer + xor eax, eax + retn 10h + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CAEMP3BankLoader::GetSoundBuffer +// +// Reject impossible sound-count, sound-id, or bank-id metadata +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc45 0x4E02E8 +#define HOOKSIZE_CrashFix_Misc45 5 +DWORD RETURN_CrashFix_Misc45 = 0x4E02ED; +DWORD RETURN_CrashFix_Misc45B = 0x4E036C; +void _declspec(naked) HOOK_CrashFix_Misc45() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + // Reject impossible sound-count metadata + cmp dx, 0FFFFh + je check_bank + test dx, dx + jle bail45 + cmp dx, 190h + jg bail45 + +check_bank: + // Reject values that would later index outside the 400-entry sound header table + cmp di, 190h + jae bail45 + + // Reject slot metadata whose bank id points outside the lookup table + mov ax, [ebx+esi+10h] + cmp ax, word ptr [ecx+0Eh] + jae bail45 + + // Execute replaced code + cmp di, 190h + jmp RETURN_CrashFix_Misc45 + +bail45: + push 45 + call CrashAverted + jmp RETURN_CrashFix_Misc45B + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CAEMP3BankLoader::GetSoundBuffer +// +// Computed sound size or offset exceeds the slot buffer capacity, +// caused by stale or inconsistent slot metadata after a slot reload +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc44 0x4E0347 +#define HOOKSIZE_CrashFix_Misc44 7 +DWORD RETURN_CrashFix_Misc44 = 0x4E034E; +void _declspec(naked) HOOK_CrashFix_Misc44() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + // At this point size was written to *a4. + // ecx = this, ebx = m_pBankSlotsInfos, esi = bankSlotInfoId * 4820, + // edi = bankSlotInfoId * 4820 + 12 * soundId + + // Read the computed size + mov edx, [esp+1Ch] + mov eax, [edx] + + // Verify sound_offset + size fits within the slot buffer + add eax, [edi+ebx+14h] + jc bail44 + cmp eax, [ebx+esi+4] + ja bail44 + + // Execute replaced code + mov edx, [ecx] + mov ax, [edi+edx+1Ch] + jmp RETURN_CrashFix_Misc44 + +bail44: + push 44 + call CrashAverted + pop edi + pop esi + pop ebp + xor eax, eax + pop ebx + retn 10h + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CAEMP3BankLoader::Service (PENDING_LOAD_ONE_SOUND) +// +// BankNumBytes from the stream header may exceed the buffer limit for +// the rep movsd at 0x4DFE92. Clamp it so the copy stays within bounds. +// Only bail when OffsetBytes is at or past the buffer end. +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc47 0x4DFE7D +#define HOOKSIZE_CrashFix_Misc47 5 +DWORD RETURN_CrashFix_Misc47 = 0x4DFE82; +DWORD RETURN_CrashFix_Misc47B = 0x4DFFED; +void _declspec(naked) HOOK_CrashFix_Misc47() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + // Execute replaced code + mov edx, [ebx-1Ah] // edx = req.SlotInfo + mov edi, [edx] // edi = SlotInfo->OffsetBytes + + // Safe limit = m_BufferSize - OffsetBytes; bail if no room at all + mov eax, [ebp+18h] // eax = m_BufferSize + sub eax, edi // eax = space left in m_Buffer + jbe bail47 // OffsetBytes >= m_BufferSize + + // Reduce safe limit to SlotInfo->NumBytes if that is smaller + mov ecx, [edx+4] // ecx = SlotInfo->NumBytes + cmp eax, ecx + jb skip47 // space_left is the tighter bound + mov eax, ecx // NumBytes is the tighter bound +skip47: + + // Clamp BankNumBytes to the safe limit if needed + mov ecx, [ebx-12h] // ecx = req.BankNumBytes + cmp ecx, eax + jbe ok47 // already within range + + mov [ebx-12h], eax // req.BankNumBytes = safe limit + push 47 + call CrashAverted + +ok47: + jmp RETURN_CrashFix_Misc47 + +bail47: + push 47 + call CrashAverted + jmp RETURN_CrashFix_Misc47B + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CAEMP3BankLoader::Service (PENDING_READ, whole-bank path) +// +// Same buffer overflow risk as Misc47, but on the whole-bank memcpy +// at 0x4DFF90. Clamp BankNumBytes so the copy stays within bounds. +// Only bail when OffsetBytes is at or past the buffer end. +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc48 0x4DFF78 +#define HOOKSIZE_CrashFix_Misc48 5 +DWORD RETURN_CrashFix_Misc48 = 0x4DFF7D; +DWORD RETURN_CrashFix_Misc48B = 0x4DFFED; +void _declspec(naked) HOOK_CrashFix_Misc48() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + // Execute replaced code + mov edx, [ebx-1Ah] // edx = req.SlotInfo + mov edi, [edx] // edi = SlotInfo->OffsetBytes + + // Safe limit = m_BufferSize - OffsetBytes; bail if no room at all + mov eax, [ebp+18h] // eax = m_BufferSize + sub eax, edi // eax = space left in m_Buffer + jbe bail48 // OffsetBytes >= m_BufferSize + + // Reduce safe limit to SlotInfo->NumBytes if that is smaller + mov ecx, [edx+4] // ecx = SlotInfo->NumBytes + cmp eax, ecx + jb skip48 // space_left is the tighter bound + mov eax, ecx // NumBytes is the tighter bound +skip48: + + // Clamp BankNumBytes to the safe limit if needed + mov ecx, [ebx-12h] // ecx = req.BankNumBytes + cmp ecx, eax + jbe ok48 // already within range + + mov [ebx-12h], eax // req.BankNumBytes = safe limit + push 48 + call CrashAverted + +ok48: + jmp RETURN_CrashFix_Misc48 + +bail48: + push 48 + call CrashAverted + jmp RETURN_CrashFix_Misc48B + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CAEMP3BankLoader::Service (PENDING_READ, single-sound path) +// +// BankNumBytes from the stream header can be negative or larger than +// the slot holds. Clamp to SlotInfo->NumBytes so the second read still +// runs and the bank slot gets populated. Bail only when the bank index +// is out of range, which would write past the end of the slot array +// when the second read completes. +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc49 0x4E0094 +#define HOOKSIZE_CrashFix_Misc49 5 +DWORD RETURN_CrashFix_Misc49 = 0x4E0099; +DWORD RETURN_CrashFix_Misc49B = 0x4DFFED; +void _declspec(naked) HOOK_CrashFix_Misc49() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + // Execute replaced subtraction; EAX must be unchanged for the return site at 0x4E0099 + sub ecx, [eax] // ecx = nextOrEnd - Sounds[SoundID].BankOffsetBytes + + // Bail on out-of-range Bank: it is used as an array index for slot writes + movsx edx, word ptr [ebx-2] // edx = req.Bank + test edx, edx + js bail49 + cmp dx, [ebp+0Eh] // Bank >= m_BankLkupCnt? + jae bail49 + + // Clamp BankNumBytes to SlotInfo->NumBytes + mov edx, [ebx-1Ah] // edx = req.SlotInfo + mov edi, [edx+4] // edi = SlotInfo->NumBytes + test ecx, ecx // negative result (underflow)? + js clamp49 + cmp ecx, edi // BankNumBytes > NumBytes? + jbe ok49 + +clamp49: + mov ecx, edi + push 49 + call CrashAverted + +ok49: + mov [ebx-12h], ecx // req.BankNumBytes = ecx + jmp RETURN_CrashFix_Misc49 + +bail49: + push 49 + call CrashAverted + jmp RETURN_CrashFix_Misc49B + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CAnimBlendAssociation::SetFinishCallback +// +// "this" is invalid +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc30 0x4CEBE8 +#define HOOKSIZE_CrashFix_Misc30 7 +#define HOOKCHECK_CrashFix_Misc30 0xC7 +DWORD RETURN_CrashFix_Misc30 = 0x4CEBEF; +DWORD RETURN_CrashFix_Misc30B = 0x4CEBF5; +static void __declspec(naked) HOOK_CrashFix_Misc30() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + // Check for incorrect pointer + cmp ecx, 0 + jz cont + + // Execute replaced code + mov dword ptr [ecx+30h], 1 + // Continue standard path + jmp RETURN_CrashFix_Misc30 + +cont: + push 30 + call CrashAverted + // Skip much code + jmp RETURN_CrashFix_Misc30B + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CAnimBlendAssociation::SetCurrentTime +// +// "this" is invalid +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc32 0x4CEA80 +#define HOOKSIZE_CrashFix_Misc32 8 +DWORD RETURN_CrashFix_Misc32 = 0x4CEA88; + +static void __declspec(naked) HOOK_CrashFix_Misc32() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + test ecx, ecx + jz cont + + // Check hierarchy pointer (offset 0x14) + // We can use eax as scratch because it gets overwritten by the first replaced instruction anyway + mov eax, [ecx+14h] + test eax, eax + jz cont + + // Execute replaced code + mov eax, [esp+4] + fld dword ptr [esp+4] + jmp RETURN_CrashFix_Misc32 + + cont: + push 32 + call CrashAverted + retn 4 + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CVehicleModelInfo::FindTextureCB (0x4C7510) +// SA's inlined strcpy to 32-byte buffer overruns if name >= 31 chars > 0xC0000409 +// Reimplement it using safe string handling +// +// Hook interaction: This calls RwTexDictionaryFindNamedTexture (0x7F39F0) which has +// Misc33 hook. Direct calls causes re-entry and stack corruption. +// Solution: CallOriginalRwTexDictionaryFindNamedTexture replicates Misc33's overwritten +// bytes (mov eax,[esp+4]; push ebx) and jumps to 0x7F39F5 to work around the hook. +//////////////////////////////////////////////////////////////////////// +typedef RwTexture*(__cdecl* RwTexDictionaryFindNamedTexture_t)(RwTexDictionary* dict, const char* name); +typedef RwTexDictionary*(__cdecl* RwTexDictionaryGetCurrent_t)(); + +static RwTexDictionaryGetCurrent_t pfnRwTexDictionaryGetCurrentForMisc39 = (RwTexDictionaryGetCurrent_t)0x7F3A90; + +// Trampoline to call the ORIGINAL RwTexDictionaryFindNamedTexture at 0x7F39F0, +// thereby working around HOOK_CrashFix_Misc33. +// Replicates the 5 overwritten bytes (mov eax,[esp+4]; push ebx) then jumps to 0x7F39F5. +static constexpr DWORD AddrFindNamedTexture_Continue = 0x7F39F5; +static void _declspec(naked) TrampolineRwTexDictionaryFindNamedTexture() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + mov eax, [esp+4] + push ebx + jmp AddrFindNamedTexture_Continue + } + // clang-format on +} + +static constexpr std::size_t TextureNameSize = 32; +static constexpr char RemapPrefix[] = "remap"; + +typedef RwTexDictionary*(__cdecl* CTxdStore_GetTxd_t)(unsigned int id); +typedef int(__cdecl* CTxdStore_GetParentTxdSlot_t)(int index); + +// Cached dict-to-slot mapping to avoid repeated pool scans +static RwTexDictionary* s_cachedTxdPtr = nullptr; +static int s_cachedSlotIndex = -1; + +// Reads the runtime TXD pool size from SA's pool struct at 0xC8800C. +// Returns 0 if the pool hasn't been created yet. +static int GetRuntimeTxdPoolSize() noexcept +{ + auto* pPool = *reinterpret_cast**>(0xC8800C); + if (!pPool) + return 0; + return pPool->m_nSize; +} + +// Finds the pool slot index for a given RwTexDictionary pointer by scanning +// non-empty slots within the pool bounds. Uses a one-entry cache to skip +// the scan when the same dictionary is looked up again. +static int FindTxdSlotForDict(RwTexDictionary* pDict) noexcept +{ + if (!pDict) + return -1; + + // Check cached result first + if (s_cachedTxdPtr == pDict && s_cachedSlotIndex >= 0) + { + // Check the slot still holds this dictionary + auto* pPool = *reinterpret_cast**>(0xC8800C); + if (pPool && pPool->m_byteMap && pPool->m_pObjects && s_cachedSlotIndex < pPool->m_nSize && !pPool->m_byteMap[s_cachedSlotIndex].bEmpty && + pPool->m_pObjects[s_cachedSlotIndex].rwTexDictonary == pDict) + { + return s_cachedSlotIndex; + } + s_cachedTxdPtr = nullptr; + s_cachedSlotIndex = -1; + } + + auto* pPool = *reinterpret_cast**>(0xC8800C); + if (!pPool || pPool->m_nSize <= 0 || !pPool->m_byteMap || !pPool->m_pObjects) + return -1; + + const int scanLimit = (pPool->m_nSize < CTxdPoolSA::TXD_POOL_MAX_CAPACITY) ? pPool->m_nSize : CTxdPoolSA::TXD_POOL_MAX_CAPACITY; + for (int i = 0; i < scanLimit; ++i) + { + if (pPool->m_byteMap[i].bEmpty) + continue; + if (pPool->m_pObjects[i].rwTexDictonary == pDict) + { + s_cachedTxdPtr = pDict; + s_cachedSlotIndex = i; + return i; + } + } + return -1; +} + +static RwTexture* __cdecl OnMY_FindTextureCB(const char* name) +{ + if (name == nullptr) + return nullptr; + + const auto RwTexDictionaryFindNamedTexture = + reinterpret_cast(reinterpret_cast(TrampolineRwTexDictionaryFindNamedTexture)); + const auto RwTexDictionaryGetCurrent = pfnRwTexDictionaryGetCurrentForMisc39; + const auto CTxdStore_GetTxd = reinterpret_cast(0x00408340); + const auto CTxdStore_GetParentTxdSlot = reinterpret_cast(0x00408370); + + RwTexDictionary* vehicleTxd = *reinterpret_cast(0x00B4E688); + if (vehicleTxd != nullptr) + { + RwTexture* tex = RwTexDictionaryFindNamedTexture(vehicleTxd, name); + if (tex != nullptr) + { + return tex; + } + } + + RwTexDictionary* currentTxd = RwTexDictionaryGetCurrent(); + if (currentTxd == nullptr) + return nullptr; + + RwTexture* tex = nullptr; + const bool bIsRemap = (std::strncmp(name, RemapPrefix, sizeof(RemapPrefix) - 1) == 0); + + constexpr int kMaxDepth = 32; + int depth = 0; + int slotIndex = -1; + bool slotLookedUp = false; + + char remapName[TextureNameSize]; + if (bIsRemap) + { + const std::size_t nameLen = strnlen(name, TextureNameSize); + if (nameLen >= TextureNameSize) + { + OnCrashAverted(39); + return nullptr; + } + std::memcpy(remapName, name, nameLen + 1); + remapName[0] = '#'; + } + + RwTexDictionary* txd = currentTxd; + while (txd != nullptr && depth < kMaxDepth) + { + tex = RwTexDictionaryFindNamedTexture(txd, name); + if (tex != nullptr) + break; + + if (bIsRemap) + { + tex = RwTexDictionaryFindNamedTexture(txd, remapName); + if (tex != nullptr) + break; + } + + if (!slotLookedUp) + { + slotLookedUp = true; + slotIndex = FindTxdSlotForDict(currentTxd); + } + + if (slotIndex < 0) + break; + + int parentSlot = CTxdStore_GetParentTxdSlot(slotIndex); + if (parentSlot < 0 || parentSlot == slotIndex) + break; + + // Check parentSlot is within pool bounds + const int poolSize = GetRuntimeTxdPoolSize(); + if (parentSlot >= poolSize) + break; + + slotIndex = parentSlot; + txd = CTxdStore_GetTxd(static_cast(parentSlot)); + ++depth; + } + + if (depth >= kMaxDepth) + AddReportLog(8540, SString("FindTextureCB: parent chain depth cap reached for '%s'", name)); + + if (tex != nullptr && bIsRemap) + { + if (IsWritablePtr(tex, sizeof(RwTexture))) + { + tex->name[0] = '#'; + } + } + + return tex; +} + +#define HOOKPOS_CrashFix_Misc39 0x4C7510 +#define HOOKSIZE_CrashFix_Misc39 5 +static void __declspec(naked) HOOK_CrashFix_Misc39() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + push [esp+4] + call OnMY_FindTextureCB + add esp, 4 + ret + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// RwTexDictionaryFindNamedTexture (0x7F39F0) +// +// Crash occur when dict pointer is NULL or invalid (not a valid RwTexDictionary). +// This can happen with corrupted texture dictionary chains or during streaming issues. +// +// Validates the dict pointer before calling the SA function +// +// Overwrites the first 5 bytes at 0x7F39F0: +// Original: 8B 44 24 04 53 (mov eax,[esp+4]; push ebx) +// Replaced: E9 xx xx xx xx (jmp HOOK_CrashFix_Misc33) +// +// HOOK_CrashFix_Misc39 (FindTextureCB replacement) needs to call this function +// but has to dodge this hook (risk of re-entry and stack corruption) +// See CallOriginalRwTexDictionaryFindNamedTexture in the Misc39 code for the +// trampoline that replicates the overwritten bytes and jumps to 0x7F39F5. +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc33 0x7F39F0 +#define HOOKSIZE_CrashFix_Misc33 5 +DWORD RETURN_CrashFix_Misc33 = 0x7F39F5; + +typedef RwTexDictionary*(__cdecl* PFN_RwTexDictionaryGetCurrent)(); +PFN_RwTexDictionaryGetCurrent pfnRwTexDictionaryGetCurrent = (PFN_RwTexDictionaryGetCurrent)0x7F3A90; + +// Helper to execute the original func's overwritten prologue and continue. +// Used by HOOK_CrashFix_Misc33 when validation passes. +static void __declspec(naked) CallOriginalFindNamedTexture() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + // Replicate overwritten bytes at 0x7F39F0 + mov eax, [esp+4] // Original: mov eax, [esp+dict] + push ebx // Original: push ebx + jmp RETURN_CrashFix_Misc33 // Continue at 0x7F39F5: add eax, 8 + } + // clang-format on +} + +static void __declspec(naked) HOOK_CrashFix_Misc33() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + // Get first argument (dict) + mov ecx, [esp+4] + + // Grab name parameter for later reuse + mov edx, [esp+8] + + // Name must be valid + test edx, edx + jz invalid_texture + + // Check for NULL dict + test ecx, ecx + jz invalid_texture + + // Check for valid pointer + cmp ecx, 0x10000 + jb invalid_texture + + // Check if it's a dictionary (RwObject type 6 at offset 0) + cmp byte ptr [ecx], 6 + jne use_current_dict + + // Validate dict->texturesInDict.next (offset 8) + mov eax, [ecx+8] + test eax, eax + jz invalid_texture + + // All validation passed - execute original function + jmp CallOriginalFindNamedTexture + + use_current_dict: + // Dict exists but is not type 6, try to recover using current dictionary + // Save name in edx across the call + push edx + call pfnRwTexDictionaryGetCurrent + pop edx + test eax, eax + jz invalid_texture + + // Replace the invalid dict argument on stack with current one + mov [esp+4], eax + // Continue with corrected dict + jmp CallOriginalFindNamedTexture + + invalid_texture: + push 33 + call CrashAverted + xor eax, eax // Return null (texture not found) + retn // cdecl + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// CCustomCarEnvMapPipeline::CustomPipeRenderCB - EnvWave path +// +// NULL env map plugin data pointer (EBP) causes crash in CalculateEnvMap +// Crash when rendering a car environment map (Accessing [esi+2]) +// This occurs when a material has MF_HAS_SHINE_WAVE flag set +// but the env map plugin data slot is NULL. +// +// Hook at 0x5D9CB2 replaces: jz loc_5D9E0D (original flag check) +// +// Original code flow at loc_5D9CAC: +// 0x5D9CAC: mov al, [esp+4Ch+var_39] ; load EnvWave flag +// 0x5D9CB0: test al, al +// 0x5D9CB2: jz loc_5D9E0D ; skip if flag not set <-- HOOKED +// 0x5D9CB8: mov eax, ds:_RwEngineInstance (EnvWave processing begins) +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc34 0x5D9CB2 +#define HOOKSIZE_CrashFix_Misc34 6 +DWORD RETURN_CrashFix_Misc34 = 0x5D9CB8; +DWORD RETURN_CrashFix_Misc34_Skip = 0x5D9E0D; // Skip to end of EnvWave block +static void __declspec(naked) HOOK_CrashFix_Misc34() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + // Replicate original flag check: ZF was set by previous "test al, al" + // If ZF is set (al == 0, flag not set), skip EnvWave (original behavior) + // Note: JMP does not modify flags, so ZF from "test al, al" is preserved + jz skip_envwave_normal + + // Flag is set - check if EBP (env map plugin data) is valid + // EBP was loaded at loc_5D9A00: mov ebp, [ecx+esi] (material plugin slot) + // Check if EBP points to a valid address (catches NULL and low invalid addresses) + cmp ebp, 0x10000 + jb skip_envwave_crash + + // EBP is valid, continue with EnvWave processing + // Return to 0x5D9CB8: mov eax, ds:_RwEngineInstance + jmp RETURN_CrashFix_Misc34 + + skip_envwave_normal: + // Normal skip - flag was not set (original behavior) + jmp RETURN_CrashFix_Misc34_Skip + + skip_envwave_crash: + // Crash averted - flag was set but EBP was NULL or invalid + push 34 + call CrashAverted + jmp RETURN_CrashFix_Misc34_Skip + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// RwTexDictionaryForAllTextures +// +// Invalid list entry pointer (crash at 0x7F374A: mov esi, [eax]) +// (https://pastebin.com/hFduf1JB) +// WARNING: No pushad/popad with C++ calls (corrupts /GS cookie > 0xC0000409) +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc35 0x7F374A +#define HOOKSIZE_CrashFix_Misc35 5 +#define HOOKCHECK_CrashFix_Misc35 0x8B +DWORD RETURN_CrashFix_Misc35 = 0x7F374F; +DWORD RETURN_CrashFix_Misc35_Abort = 0x7F3760; + +static void __declspec(naked) HOOK_CrashFix_Misc35() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + cmp eax, NUM_LOWMEM_THRESHOLD_ASM + jb abort_35 + + push eax + push ecx + push edx + push 4 + push eax + call IsReadablePtr + add esp, 8 + test al, al + pop edx + pop ecx + pop eax + jz abort_35 + + mov esi, [eax] + add eax, 0FFFFFFF8h + jmp RETURN_CrashFix_Misc35 + + abort_35: + push 35 + call CrashAverted + jmp RETURN_CrashFix_Misc35_Abort + } + // clang-format on +} + +/////////////////////////////////////////////////////////////////////////////// +// RwTexDictionaryFindNamedTexture - Invalid/corrupted texture name pointer +// Crash: 0x7F3A17 (mov cl,[esi]), see https://pastebin.com/buBbyWRx and https://pastebin.com/1wTeTwu2 +// Flow: validate ebx > compute ecx=ebx+8 > range-check > IsReadablePtr(ecx) +// Bad ptrs: 0xFF1B1B1B (high), 0x4E505444 (unmapped ASCII) +// WARNING: No pushad/popad with C++ calls (corrupts /GS cookie > 0xC0000409) +// Use push eax/ecx/edx + pushfd instead (16 bytes vs 32) +/////////////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc36 0x7F3A09 +#define HOOKSIZE_CrashFix_Misc36 6 +#define HOOKCHECK_CrashFix_Misc36 0x8D +DWORD RETURN_CrashFix_Misc36 = 0x7F3A0F; +DWORD RETURN_CrashFix_Misc36_Abort = 0x7F3A5C; + +static void __declspec(naked) HOOK_CrashFix_Misc36() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + cmp ebx, NUM_LOWMEM_THRESHOLD_ASM + jb abort_36 + + // Replicate original code + lea eax, [ebx-8] + lea ecx, [eax+10h] + + cmp ecx, NUM_LOWMEM_THRESHOLD_ASM + jb abort_36 + + push eax + push ecx + push edx + push 1 + push ecx + call IsReadablePtr + add esp, 8 + test al, al + pop edx + pop ecx + pop eax + jz abort_36 + + // Continue to original code at test ecx, ecx + jmp RETURN_CrashFix_Misc36 + + abort_36: + push 36 + call CrashAverted + jmp RETURN_CrashFix_Misc36_Abort + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// RwTexDictionaryAddTexture +// +// Invalid list head pointer (crash at 0x7F39B3: mov [esi+4], edx) +// (https://pastebin.com/pkWwsSih) +// WARNING: No pushad/popad with C++ calls (corrupts /GS cookie > 0xC0000409) +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc37 0x7F39B3 +#define HOOKSIZE_CrashFix_Misc37 5 +#define HOOKCHECK_CrashFix_Misc37 0x89 +DWORD RETURN_CrashFix_Misc37 = 0x7F39B8; + +static void __declspec(naked) HOOK_CrashFix_Misc37() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + cmp esi, NUM_LOWMEM_THRESHOLD_ASM + jb bad + + push eax + push ecx + push edx + push 8 + push esi + call IsWritablePtr + add esp, 8 + test al, al + pop edx + pop ecx + pop eax + jz bad + + cmp esi, ecx + jz ok + + cmp dword ptr [esi+4], ecx + jz ok + + bad: + push 37 + call CrashAverted + jmp RETURN_CrashFix_Misc37 + + ok: + mov [edx], esi + mov [esi+4], edx + mov [ecx], edx + jmp RETURN_CrashFix_Misc37 + } + // clang-format on +} + +//////////////////////////////////////////////////////////////////////// +// __rpD3D9SkinGeometryReinstance +// +// NULL pointer (out of video mem crash at 0x003C91CC: mov ebx, [esi]) +// Hook at loc_7C91C0 validates [eax] +// On NULL, skip to loc_7C91DA (after the call block) to continue the loop. +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc38 0x7C91C0 +#define HOOKSIZE_CrashFix_Misc38 6 +#define HOOKCHECK_CrashFix_Misc38 0x8B +DWORD RETURN_CrashFix_Misc38 = 0x7C91C6; +DWORD RETURN_CrashFix_Misc38_Skip = 0x7C91DA; // loc_7C91DA: after call block, safe loop continuation + +constexpr std::uint32_t NUM_VRAM_RELIEF_THROTTLE_MS = 500; + +static void OnVideoMemoryExhausted() +{ + static DWORD s_dwLastReliefTick = 0; + const DWORD dwNow = GetTickCount32(); + + if (dwNow - s_dwLastReliefTick < NUM_VRAM_RELIEF_THROTTLE_MS) + return; + + s_dwLastReliefTick = dwNow; + OnRequestDeferredStreamingMemoryRelief(); } -//////////////////////////////////////////////////////////////////////// -// CTaskSimpleCarOpenDoorFromOutside::FinishAnimCarOpenDoorFromOutsideCB -// -// Null vehicle pointer -//////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc25 0x646026 -#define HOOKSIZE_CrashFix_Misc25 5 -DWORD RETURN_CrashFix_Misc25 = 0x64602B; -void _declspec(naked) HOOK_CrashFix_Misc25() +// No pushad/popad with C++ calls (corrupts /GS cookie > 0xC0000409) +static void __declspec(naked) HOOK_CrashFix_Misc38() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - // Check for zero pointer to vehicle - mov eax, [esi+0x10] - cmp eax, 0 - jz fix + mov esi, [eax] + test esi, esi + jnz ok - // Continue standard path - lea eax,[esp+10h] + // Save only volatile registers before call push eax - jmp RETURN_CrashFix_Misc25 + push ecx + push edx + call OnVideoMemoryExhausted + pop edx + pop ecx + pop eax - fix: - push 25 + push 38 call CrashAverted - // Do special thing - pop esi - pop ecx - retn + jmp RETURN_CrashFix_Misc38_Skip + + ok: + lea ecx, [esp+ecx*4+18h] + jmp RETURN_CrashFix_Misc38 } + // clang-format on } //////////////////////////////////////////////////////////////////////// -// CShotInfo::Update -// -// _creator->m_pIntelligence is invalid +// __rpD3D9VertexDeclarationInstV3d +// +// Same class of issue as CrashFix_Misc38 (skin geometry path), usually due to out of video mem. +// This condition indicates out of video mem, but we'll alleviate it by calling OnVideoMemoryExhausted following the avert. +// NULL locked vertex buffer crash (VB Lock failure unchecked by RW). +// RW's D3D9AtomicDefaultInstanceCallback passes a NULL lockedVertexBuffer +// to this function when IDirect3DVertexBuffer9::Lock() fails and the +// HRESULT is discarded. The function writes vertex data to the NULL +// pointer, causing an crash at 0x00352BA7 (0x752BA7) (case 2, first store). +// +// __cdecl: [esp+4]=type, [esp+8]=mem, [esp+C]=src, [esp+10]=numVerts, [esp+14]=stride +// Returns D3D9VertexTypeSize[type] in EAX on all paths. //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc26 0x739FA0 -#define HOOKSIZE_CrashFix_Misc26 6 -DWORD RETURN_CrashFix_Misc26 = 0x739FA6; -void _declspec(naked) HOOK_CrashFix_Misc26() +#define HOOKPOS_CrashFix_VBInstV3dNull 0x752AD0 +#define HOOKSIZE_CrashFix_VBInstV3dNull 7 +#define HOOKCHECK_CrashFix_VBInstV3dNull 0x51 +DWORD RETURN_CrashFix_VBInstV3dNull = 0x752AD7; +DWORD ARRAY_D3D9VertexTypeSize = 0x874EF8; + +static void _declspec(naked) HOOK_CrashFix_VBInstV3dNull() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - // Check for incorrect pointer - cmp ebx, 130h - jz fix + mov eax, [esp+8] // eax = mem (locked VB pointer) + test eax, eax + jz bail_out - // Continue standard path - mov edi,dword ptr [ebx+ebp*4] - dec ebp - test edi,edi - jmp RETURN_CrashFix_Misc26 + // Replicate overwritten prologue (7 bytes: push ecx; push ebx; push ebp; mov ebp,[esp+0Ch]) + push ecx + push ebx + push ebp + mov ebp, [esp+10h] // type (was [esp+0C] before 3 pushes, +4 each = +0Ch+4 = 10h) + jmp RETURN_CrashFix_VBInstV3dNull - fix: - push 26 + bail_out: + push eax + push ecx + push edx + call OnVideoMemoryExhausted + pop edx + pop ecx + pop eax + + push 40 call CrashAverted - // Do special thing - mov edi, 0 - dec ebp - test edi,edi - jmp RETURN_CrashFix_Misc26 + + // Return D3D9VertexTypeSize[type] to satisfy caller's contract + mov ecx, [esp+4] // ecx = type + mov eax, ARRAY_D3D9VertexTypeSize // eax = array base address + mov eax, [eax + ecx*4] // eax = D3D9VertexTypeSize[type] + ret } + // clang-format on } //////////////////////////////////////////////////////////////////////// -// CTaskComplexDieInCar::ControlSubTask -// -// ped or ped->m_pVehicle is null pointer +// __rpD3D9VertexDeclarationInstV3dMorph +// +// Same NULL locked VB crash as above __rpD3D9VertexDeclarationInstV3d, but in the morph interpolation path. +// Called from D3D9AtomicDefaultInstanceCallback when geometry has morph +// targets. mem (2nd arg) receives lockedVertexBuffer[] which can be NULL. +// This condition indicates out of video mem, but we'll alleviate it by calling OnVideoMemoryExhausted following the avert. +// +// __cdecl: [esp+4]=type, [esp+8]=mem, [esp+C]=src1, [esp+10]=src2, +// [esp+14]=scale(float), [esp+18]=numVerts, [esp+1C]=stride +// Returns D3D9VertexTypeSize[type] in EAX. //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc27 0x6377FB -#define HOOKSIZE_CrashFix_Misc27 7 -DWORD RETURN_CrashFix_Misc27 = 0x637802; -void _declspec(naked) HOOK_CrashFix_Misc27() +#define HOOKPOS_CrashFix_VBInstV3dMorphNull 0x753B60 +#define HOOKSIZE_CrashFix_VBInstV3dMorphNull 5 +#define HOOKCHECK_CrashFix_VBInstV3dMorphNull 0x51 +DWORD RETURN_CrashFix_VBInstV3dMorphNull = 0x753B65; + +static void _declspec(naked) HOOK_CrashFix_VBInstV3dMorphNull() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - // Execute replaced code - cmp byte ptr [edi+484h], 2 - je cont + mov eax, [esp+8] // eax = mem (locked VB pointer) + test eax, eax + jz bail_out_morph - // Check if veh pointer is zero - mov ecx, [edi+58Ch] - test ecx, ecx - jne cont - push 27 + // Replicate overwritten prologue (5 bytes: push ecx; mov eax,[esp+4+arg_0]) + push ecx + mov eax, [esp+8] // type (was [esp+4+4] = [esp+8] after push ecx) + jmp RETURN_CrashFix_VBInstV3dMorphNull + + bail_out_morph: + push eax + push ecx + push edx + call OnVideoMemoryExhausted + pop edx + pop ecx + pop eax + + push 41 call CrashAverted -cont: - // Continue standard path - jmp RETURN_CrashFix_Misc27 + // Return D3D9VertexTypeSize[type] + mov ecx, [esp+4] // ecx = type + mov eax, ARRAY_D3D9VertexTypeSize // eax = array base address + mov eax, [eax + ecx*4] // eax = D3D9VertexTypeSize[type] + ret } + // clang-format on } //////////////////////////////////////////////////////////////////////// -// CObject::ProcessGarageDoorBehaviour +// __rpD3D9VertexDeclarationInstWeights // -// Null this->m_pDummyObject pointer +// Same NULL locked VB crash as InstV3d/InstV3dMorph, but in the skin +// weights instancing path. Called only from __rpD3D9SkinGeometryReinstance +// when rendering skinned meshes (peds, deformable vehicles). +// This condition indicates out of video mem, but we'll alleviate it by calling OnVideoMemoryExhausted following the avert. +// The caller adds a vertex byte offset to the locked pointer, so mem +// is typically a small non-zero value (e.g 0x20) rather than exact NULL. +// Any address below 0x10000 (Windows null guard page) is invalid. +// +// __cdecl: [esp+4]=type, [esp+8]=mem, [esp+C]=src, [esp+10]=numVerts, [esp+14]=stride +// Returns D3D9VertexTypeSize[type] in EAX. //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc28 0x44A4FD -#define HOOKSIZE_CrashFix_Misc28 6 -DWORD RETURN_CrashFix_Misc28 = 0x44A503; -DWORD RETURN_CrashFix_Misc28B = 0x44A650; -void _declspec(naked) HOOK_CrashFix_Misc28() +#define HOOKPOS_CrashFix_VBInstWeightsNull 0x752320 +#define HOOKSIZE_CrashFix_VBInstWeightsNull 7 +#define HOOKCHECK_CrashFix_VBInstWeightsNull 0x8B +DWORD RETURN_CrashFix_VBInstWeightsNull = 0x752327; + +static void _declspec(naked) HOOK_CrashFix_VBInstWeightsNull() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - // Execute replaced code - mov eax, [esi+170h] + cmp dword ptr [esp+8], 10000h // mem below 64KB null guard page? + jb bail_out_weights - // Check if dummy pointer is zero - test eax, eax - jne cont + // Replicate overwritten prologue (7 bytes: mov eax,[esp+4]; sub esp,10h) + mov eax, [esp+4] // type + sub esp, 10h + jmp RETURN_CrashFix_VBInstWeightsNull - push 28 + bail_out_weights: + push eax + push ecx + push edx + call OnVideoMemoryExhausted + pop edx + pop ecx + pop eax + + push 42 call CrashAverted - // Skip much code - jmp RETURN_CrashFix_Misc28B -cont: - // Continue standard path - jmp RETURN_CrashFix_Misc28 + // Return D3D9VertexTypeSize[type] + mov ecx, [esp+4] // ecx = type + mov eax, ARRAY_D3D9VertexTypeSize // eax = array base address + mov eax, [eax + ecx*4] // eax = D3D9VertexTypeSize[type] + ret } + // clang-format on } //////////////////////////////////////////////////////////////////////// -// CAEMP3BankLoader::IsSoundBankLoaded +// __rpD3D9VertexDeclarationInstIndicesRemap // -// The value of the argument BankSlotId is invalid +// Same NULL locked VB crash as InstV3d/InstV3dMorph and InstWeights, +// but in the bone index remap path. Called only from __rpD3D9SkinGeometryReinstance +// when rendering skinned meshes (peds, deformable vehicles). +// This condition indicates out of video mem, but we'll alleviate it by calling OnVideoMemoryExhausted following the avert. +// The caller adds a vertex element byte offset to the locked pointer, so mem +// is typically a small non-zero value (e.g 0x28) rather than exact NULL. +// Any address below 0x10000 (Windows null guard page) is invalid. +// +// __cdecl: [esp+4]=type, [esp+8]=mem, [esp+C]=src, [esp+10]=remap, [esp+14]=numVerts, [esp+18]=stride +// Returns D3D9VertexTypeSize[type] in EAX. //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc29 0x4E022C -#define HOOKSIZE_CrashFix_Misc29 5 -DWORD RETURN_CrashFix_Misc29 = 0x4E0231; -DWORD RETURN_CrashFix_Misc29B = 0x4E0227; -void _declspec(naked) HOOK_CrashFix_Misc29() +#define HOOKPOS_CrashFix_VBInstIndicesRemapNull 0x754C80 +#define HOOKSIZE_CrashFix_VBInstIndicesRemapNull 8 +#define HOOKCHECK_CrashFix_VBInstIndicesRemapNull 0x8B +DWORD RETURN_CrashFix_VBInstIndicesRemapNull = 0x754C88; + +static void _declspec(naked) HOOK_CrashFix_VBInstIndicesRemapNull() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm { - // Execute replaced code - movsx eax,word ptr [esp+8] + cmp dword ptr [esp+8], 10000h // mem below 64KB null guard page? + jb bail_out_remap - // Check word being -1 - cmp al, 0xffff - jz cont + // Replicate overwritten prologue (8 bytes: mov edx,[esp+4]; mov eax,[esp+0Ch]) + mov edx, [esp+4] // type + mov eax, [esp+0Ch] // src + jmp RETURN_CrashFix_VBInstIndicesRemapNull - // Continue standard path - jmp RETURN_CrashFix_Misc29 + bail_out_remap: + push eax + push ecx + push edx + call OnVideoMemoryExhausted + pop edx + pop ecx + pop eax -cont: - push 29 + push 53 call CrashAverted - // Skip much code - jmp RETURN_CrashFix_Misc29B + + // Return D3D9VertexTypeSize[type] + mov ecx, [esp+4] // ecx = type + mov eax, ARRAY_D3D9VertexTypeSize // eax = array base address + mov eax, [eax + ecx*4] // eax = D3D9VertexTypeSize[type] + ret } + // clang-format on } //////////////////////////////////////////////////////////////////////// -// CAnimBlendAssociation::SetFinishCallback -// -// "this" is invalid +// _RwD3D9DynamicVertexBufferCreate +// +// NULL VB pointer crash when reusing a DynamicVertexBuffer list entry +// whose prior CreateVertexBuffer call failed (out of video mem). +// The entry has in_use=0, pVB=NULL, size=old_size. When the function +// finds this entry with a non-matching size, it tries to Release() the +// old VB through a NULL pointer (crash at 0x003F5A3A / 0x7F5A3A: mov ecx,[eax]). +// This condition indicates out of video mem, but we'll alleviate it by calling OnVideoMemoryExhausted following the avert. +// +// Hook at 0x7F5A36 replaces: mov eax,[esi+8]; push eax; mov ecx,[eax] +// On NULL, skip the Release() block and continue to VB reallocation. //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CrashFix_Misc30 0x4CEBE8 -#define HOOKSIZE_CrashFix_Misc30 7 -#define HOOKCHECK_CrashFix_Misc30 0xC7 -DWORD RETURN_CrashFix_Misc30 = 0x4CEBEF; -DWORD RETURN_CrashFix_Misc30B = 0x4CEBF5; -void _declspec(naked) HOOK_CrashFix_Misc30() +#define HOOKPOS_CrashFix_DynVBCreateNull 0x7F5A36 +#define HOOKSIZE_CrashFix_DynVBCreateNull 6 +#define HOOKCHECK_CrashFix_DynVBCreateNull 0x8B +DWORD RETURN_CrashFix_DynVBCreateNull = 0x7F5A3C; +DWORD RETURN_CrashFix_DynVBCreateNull_Skip = 0x7F5A8F; + +static void _declspec(naked) HOOK_CrashFix_DynVBCreateNull() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm { - // Check for incorrect pointer - cmp ecx, 0 - jz cont + mov eax, [esi+8] // load VB pointer from list entry + test eax, eax + jz bail_out_dynvb - // Execute replaced code - mov dword ptr [ecx+30h], 1 - // Continue standard path - jmp RETURN_CrashFix_Misc30 + // Replicate overwritten bytes (push eax; mov ecx,[eax]) + push eax + mov ecx, [eax] + jmp RETURN_CrashFix_DynVBCreateNull -cont: - push 30 + bail_out_dynvb: + push eax + push ecx + push edx + call OnVideoMemoryExhausted + pop edx + pop ecx + pop eax + + push 46 call CrashAverted - // Skip much code - jmp RETURN_CrashFix_Misc30B + jmp RETURN_CrashFix_DynVBCreateNull_Skip } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -990,10 +2433,10 @@ RwFrame* OnMY_CClumpModelInfo_GetFrameFromId_Post(RwFrame* pFrameResult, DWORD _ return pFrameResult; // Don't check frame if call can legitimately return NULL - if (calledFrom == 0x6D308F // CVehicle::SetWindowOpenFlag - || calledFrom == 0x6D30BF // CVehicle::ClearWindowOpenFlag - || calledFrom == 0x4C7DDE // CVehicleModelInfo::GetOriginalCompPosition - || calledFrom == 0x4C96BD) // CVehicleModelInfo::CreateInstance + if (calledFrom == 0x6D308F // CVehicle::SetWindowOpenFlag + || calledFrom == 0x6D30BF // CVehicle::ClearWindowOpenFlag + || calledFrom == 0x4C7DDE // CVehicleModelInfo::GetOriginalCompPosition + || calledFrom == 0x4C96BD) // CVehicleModelInfo::CreateInstance return NULL; // Ignore external calls @@ -1007,14 +2450,14 @@ RwFrame* OnMY_CClumpModelInfo_GetFrameFromId_Post(RwFrame* pFrameResult, DWORD _ int iModelId = 0; DWORD pVehicle = NULL; - if (calledFrom == 0x6D3847) // CVehicle::AddReplacementUpgrade + if (calledFrom == 0x6D3847) // CVehicle::AddReplacementUpgrade pVehicle = _ebx; - else if (calledFrom == 0x6DFA61 // CVehicle::AddUpgrade - || calledFrom == 0x6D3A62) // CVehicle::GetReplacementUpgrade + else if (calledFrom == 0x6DFA61 // CVehicle::AddUpgrade + || calledFrom == 0x6D3A62) // CVehicle::GetReplacementUpgrade pVehicle = _edi; - else if (calledFrom == 0x06AC740 // CAutomobile::PreRender (Forklift) - || calledFrom == 0x6D39F3 // CVehicle::RemoveReplacementUpgrade - || calledFrom == 0x6D3A32) // CVehicle::RemoveReplacementUpgrade2 + else if (calledFrom == 0x06AC740 // CAutomobile::PreRender (Forklift) + || calledFrom == 0x6D39F3 // CVehicle::RemoveReplacementUpgrade + || calledFrom == 0x6D3A32) // CVehicle::RemoveReplacementUpgrade2 pVehicle = _esi; if (pVehicle > 0x1000) @@ -1025,8 +2468,9 @@ RwFrame* OnMY_CClumpModelInfo_GetFrameFromId_Post(RwFrame* pFrameResult, DWORD _ { RwFrame* pNewFrameResult = NULL; uint uiNewId = id + (i / 2) * ((i & 1) ? -1 : 1); - DWORD dwFunc = 0x4C53C0; // CClumpModelInfo::GetFrameFromId - _asm + DWORD dwFunc = 0x4C53C0; // CClumpModelInfo::GetFrameFromId + // clang-format off + __asm { push uiNewId push pClump @@ -1034,6 +2478,7 @@ RwFrame* OnMY_CClumpModelInfo_GetFrameFromId_Post(RwFrame* pFrameResult, DWORD _ add esp, 8 mov pNewFrameResult,eax } + // clang-format on if (pNewFrameResult) { @@ -1053,12 +2498,15 @@ RwFrame* OnMY_CClumpModelInfo_GetFrameFromId_Post(RwFrame* pFrameResult, DWORD _ } // Hook info -#define HOOKPOS_CClumpModelInfo_GetFrameFromId 0x4C53C0 -#define HOOKSIZE_CClumpModelInfo_GetFrameFromId 7 -DWORD RETURN_CClumpModelInfo_GetFrameFromId = 0x4C53C7; -void _declspec(naked) HOOK_CClumpModelInfo_GetFrameFromId() +#define HOOKPOS_CClumpModelInfo_GetFrameFromId 0x4C53C0 +#define HOOKSIZE_CClumpModelInfo_GetFrameFromId 7 +DWORD RETURN_CClumpModelInfo_GetFrameFromId = 0x4C53C7; +static void __declspec(naked) HOOK_CClumpModelInfo_GetFrameFromId() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push [esp+4*2] push [esp+4*2] @@ -1085,6 +2533,7 @@ void _declspec(naked) HOOK_CClumpModelInfo_GetFrameFromId() mov eax,dword ptr [esp+10h] jmp RETURN_CClumpModelInfo_GetFrameFromId } + // clang-format on } CStreamingInfo* GetStreamingInfo(uint id) @@ -1118,10 +2567,18 @@ void OnMY_CEntity_GetBoundRect(CEntitySAInterface* pEntity) { // Crash will occur at offset 00134134 CStreamingInfo* pStreamingInfo = pGameInterface->GetStreaming()->GetStreamingInfo(usModelId); - SString strDetails("refs:%d txd:%d RwObj:%08x bOwn:%d flg:%d off:%d size:%d loadState:%d", pModelInfo->usNumberOfRefs, - pModelInfo->usTextureDictionary, pModelInfo->pRwObject, pModelInfo->bDoWeOwnTheColModel, pStreamingInfo->flg, - pStreamingInfo->offsetInBlocks, pStreamingInfo->sizeInBlocks, pStreamingInfo->loadState); - LogEvent(815, "Model collision missing", "CEntity_GetBoundRect", SString("No collision for model:%d %s", usModelId, *strDetails), 5415); + if (pStreamingInfo) + { + SString strDetails("refs:%d txd:%d RwObj:%08x bOwn:%d flg:%d off:%d size:%d loadState:%d", pModelInfo->usNumberOfRefs, + pModelInfo->usTextureDictionary, pModelInfo->pRwObject, pModelInfo->bDoWeOwnTheColModel, pStreamingInfo->flg, + pStreamingInfo->offsetInBlocks, pStreamingInfo->sizeInBlocks, pStreamingInfo->loadState); + LogEvent(815, "Model collision missing", "CEntity_GetBoundRect", SString("No collision for model:%d %s", usModelId, *strDetails), 5415); + } + else + { + LogEvent(815, "Model collision missing", "CEntity_GetBoundRect", SString("No collision for model:%d (invalid streaming info)", usModelId), + 5415); + } CArgMap argMap; argMap.Set("id", usModelId); argMap.Set("reason", "collision"); @@ -1131,13 +2588,16 @@ void OnMY_CEntity_GetBoundRect(CEntitySAInterface* pEntity) } // Hook info -#define HOOKPOS_CEntity_GetBoundRect 0x534131 -#define HOOKSIZE_CEntity_GetBoundRect 5 -#define HOOKCHECK_CEntity_GetBoundRect 0x8B -DWORD RETURN_CEntity_GetBoundRect = 0x534136; -void _declspec(naked) HOOK_CEntity_GetBoundRect() +#define HOOKPOS_CEntity_GetBoundRect 0x534131 +#define HOOKSIZE_CEntity_GetBoundRect 5 +#define HOOKCHECK_CEntity_GetBoundRect 0x8B +DWORD RETURN_CEntity_GetBoundRect = 0x534136; +static void __declspec(naked) HOOK_CEntity_GetBoundRect() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi @@ -1145,11 +2605,12 @@ void _declspec(naked) HOOK_CEntity_GetBoundRect() add esp, 4*1 popad - // Continue replaced code + // Continue replaced code mov eax, [ecx+14h] mov edx, [eax] jmp RETURN_CEntity_GetBoundRect } + // clang-format on } ////////////////////////////////////////////////////////////////////////// @@ -1172,13 +2633,16 @@ void OnMY_CVehicle_AddUpgrade_Post() } // Hook info -#define HOOKPOS_CVehicle_AddUpgrade 0x6DFA20 -#define HOOKSIZE_CVehicle_AddUpgrade 6 -#define HOOKCHECK_CVehicle_AddUpgrade 0x51 -DWORD RETURN_CVehicle_AddUpgrade = 0x6DFA26; -void _declspec(naked) HOOK_CVehicle_AddUpgrade() +#define HOOKPOS_CVehicle_AddUpgrade 0x6DFA20 +#define HOOKSIZE_CVehicle_AddUpgrade 6 +#define HOOKCHECK_CVehicle_AddUpgrade 0x51 +DWORD RETURN_CVehicle_AddUpgrade = 0x6DFA26; +static void __declspec(naked) HOOK_CVehicle_AddUpgrade() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*2] @@ -1202,66 +2666,75 @@ void _declspec(naked) HOOK_CVehicle_AddUpgrade() mov ebx, [esp+16] jmp RETURN_CVehicle_AddUpgrade } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CObject::~CObject, CObject::ProcessTrainCrossingBehavior -// +// // Train crossings: Detach barrier from post (to be able to create objects 1373 and 1374 separately) //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CObject_Destructor_TrainCrossing_Check 0x59F7A8 -#define HOOKPOS_CObject_ProcessTrainCrossingBehavior1 0x5A0C34 -#define HOOKPOS_CObject_ProcessTrainCrossingBehavior2 0x5A0C54 -#define RETURN_CObject_Destructor_TrainCrossing_Check 0x59F7AD -#define RETURN_CObject_Destructor_TrainCrossing_Invalid 0x59F811 -#define RETURN_CObject_ProcessTrainCrossingBehavior1_Check 0x5A0C39 -#define RETURN_CObject_ProcessTrainCrossingBehavior2_Check 0x5A0C59 +#define HOOKPOS_CObject_Destructor_TrainCrossing_Check 0x59F7A8 +#define HOOKPOS_CObject_ProcessTrainCrossingBehavior1 0x5A0C34 +#define HOOKPOS_CObject_ProcessTrainCrossingBehavior2 0x5A0C54 +#define RETURN_CObject_Destructor_TrainCrossing_Check 0x59F7AD +#define RETURN_CObject_Destructor_TrainCrossing_Invalid 0x59F811 +#define RETURN_CObject_ProcessTrainCrossingBehavior1_Check 0x5A0C39 +#define RETURN_CObject_ProcessTrainCrossingBehavior2_Check 0x5A0C59 #define RETURN_CObject_ProcessTrainCrossingBehavior_Invalid 0x5A0CBD DWORD TrainCrossingFix_ReturnAddress, TrainCrossingFix_InvalidReturnAddress; template -void _declspec(naked) HOOK_TrainCrossingBarrierCrashFix() +static void __declspec(naked) HOOK_TrainCrossingBarrierCrashFix() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // We cannot use template parameters directly in inline assembly; the following instructions don't modify registers TrainCrossingFix_ReturnAddress = ReturnAddress; TrainCrossingFix_InvalidReturnAddress = InvalidReturnAddress; - _asm + // clang-format off + __asm { - test eax, eax // Check if pLinkedBarrierPost exists - jz jmp_invalid // Skip the barrier stuff - mov ecx, [eax+14h] // Execute replaced code + test eax, eax // Check if pLinkedBarrierPost exists + jz jmp_invalid // Skip the barrier stuff + mov ecx, [eax+14h] // Execute replaced code test ecx, ecx jmp TrainCrossingFix_ReturnAddress jmp_invalid: jmp TrainCrossingFix_InvalidReturnAddress } + // clang-format on } //////////////////////////////////////////////////////////////////////// // Interior_c::Init -// +// // GTA doesn't reset the furniture object counter, so do it manually everytime before GTA furnishes an interior (Interior_c::Init) //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_ResetFurnitureObjectCounter 0x593BF0 +#define HOOKPOS_ResetFurnitureObjectCounter 0x593BF0 #define HOOKSIZE_ResetFurnitureObjectCounter 6 -DWORD RETURN_ResetFurnitureObjectCounter = 0x593BF6; -void _declspec(naked) HOOK_ResetFurnitureObjectCounter() +DWORD RETURN_ResetFurnitureObjectCounter = 0x593BF6; +static void __declspec(naked) HOOK_ResetFurnitureObjectCounter() { - *(int*)0xBB3A18 = 0; // InteriorManager_c::ms_objectCounter + MTA_VERIFY_HOOK_LOCAL_SIZE; + + *(int*)0xBB3A18 = 0; // InteriorManager_c::ms_objectCounter - _asm + // clang-format off + __asm { // original instruction mov eax, fs:[0] jmp RETURN_ResetFurnitureObjectCounter } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CVolumetricShadowMgr_Render -// +// // Custom models can cause problems for volumetric shadows. // Record when volumetric shadows are being rendered so we can disable them if a crash occurs. //////////////////////////////////////////////////////////////////////// @@ -1276,13 +2749,16 @@ void OnMY_CVolumetricShadowMgr_Render_Post() } // Hook info -#define HOOKPOS_CVolumetricShadowMgr_Render 0x7113B0 -#define HOOKSIZE_CVolumetricShadowMgr_Render 8 -#define HOOKCHECK_CVolumetricShadowMgr_Render 0x83 -DWORD RETURN_CVolumetricShadowMgr_Render = 0x7113B8; -void _declspec(naked) HOOK_CVolumetricShadowMgr_Render() +#define HOOKPOS_CVolumetricShadowMgr_Render 0x7113B0 +#define HOOKSIZE_CVolumetricShadowMgr_Render 8 +#define HOOKCHECK_CVolumetricShadowMgr_Render 0x83 +DWORD RETURN_CVolumetricShadowMgr_Render = 0x7113B8; +static void __declspec(naked) HOOK_CVolumetricShadowMgr_Render() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad call OnMY_CVolumetricShadowMgr_Render_Pre @@ -1296,16 +2772,17 @@ void _declspec(naked) HOOK_CVolumetricShadowMgr_Render() retn inner: - // Replaced code + // Replaced code sub esp, 18h mov ecx, 0A9AE00h jmp RETURN_CVolumetricShadowMgr_Render } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CVolumetricShadowMgr_Update -// +// // Custom models can cause problems for volumetric shadows. // Record when volumetric shadows are being updated so we can disable them if a crash occurs. //////////////////////////////////////////////////////////////////////// @@ -1320,13 +2797,16 @@ void OnMY_CVolumetricShadowMgr_Update_Post() } // Hook info -#define HOOKPOS_CVolumetricShadowMgr_Update 0x711D90 -#define HOOKSIZE_CVolumetricShadowMgr_Update 5 -#define HOOKCHECK_CVolumetricShadowMgr_Update 0xB9 -DWORD RETURN_CVolumetricShadowMgr_Update = 0x711D95; -void _declspec(naked) HOOK_CVolumetricShadowMgr_Update() +#define HOOKPOS_CVolumetricShadowMgr_Update 0x711D90 +#define HOOKSIZE_CVolumetricShadowMgr_Update 5 +#define HOOKCHECK_CVolumetricShadowMgr_Update 0xB9 +DWORD RETURN_CVolumetricShadowMgr_Update = 0x711D95; +static void __declspec(naked) HOOK_CVolumetricShadowMgr_Update() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad call OnMY_CVolumetricShadowMgr_Update_Pre @@ -1342,21 +2822,23 @@ void _declspec(naked) HOOK_CVolumetricShadowMgr_Update() retn inner: - // Replaced code + // Replaced code mov ecx, 0A9AE00h jmp RETURN_CVolumetricShadowMgr_Update } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CAnimManager::CreateAnimAssocGroups -// +// // CModelInfo::ms_modelInfoPtrs at the given index is a null pointer //////////////////////////////////////////////////////////////////////// void OnMY_CAnimManager_CreateAnimAssocGroups(uint uiModelId) { - CModelInfo* pModelInfo = pGameInterface->GetModelInfo(uiModelId); - if (pModelInfo->GetInterface()->pRwObject == NULL) + CModelInfo* pModelInfo = pGameInterface->GetModelInfo(uiModelId); + CBaseModelInfoSAInterface* pInterface = pModelInfo ? pModelInfo->GetInterface() : nullptr; + if (!pInterface || pInterface->pRwObject == nullptr) { // Crash will occur at offset 00349b7b LogEvent(816, "Model not loaded", "CAnimManager_CreateAnimAssocGroups", SString("No RwObject for model:%d", uiModelId), 5416); @@ -1368,13 +2850,16 @@ void OnMY_CAnimManager_CreateAnimAssocGroups(uint uiModelId) } // Hook info -#define HOOKPOS_CAnimManager_CreateAnimAssocGroups 0x4D3D52 -#define HOOKSIZE_CAnimManager_CreateAnimAssocGroups 5 -#define HOOKCHECK_CAnimManager_CreateAnimAssocGroups 0x8B -DWORD RETURN_CAnimManager_CreateAnimAssocGroups = 0x4D3D59; -void _declspec(naked) HOOK_CAnimManager_CreateAnimAssocGroups() +#define HOOKPOS_CAnimManager_CreateAnimAssocGroups 0x4D3D52 +#define HOOKSIZE_CAnimManager_CreateAnimAssocGroups 5 +#define HOOKCHECK_CAnimManager_CreateAnimAssocGroups 0x8B +DWORD RETURN_CAnimManager_CreateAnimAssocGroups = 0x4D3D59; +static void __declspec(naked) HOOK_CAnimManager_CreateAnimAssocGroups() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push eax @@ -1382,7 +2867,7 @@ void _declspec(naked) HOOK_CAnimManager_CreateAnimAssocGroups() add esp, 4*1 popad - // Replaced code + // Replaced code push ecx mov ecx, dword ptr[ARRAY_ModelInfo] mov eax, dword ptr[ecx + eax*4] @@ -1390,6 +2875,7 @@ void _declspec(naked) HOOK_CAnimManager_CreateAnimAssocGroups() jmp RETURN_CAnimManager_CreateAnimAssocGroups } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -1398,8 +2884,8 @@ void _declspec(naked) HOOK_CAnimManager_CreateAnimAssocGroups() // Accessing a temporally not existing vehicle // (seems to happen when the driver is slower being thrown out than the jacker enters the vehicle) //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CTaskComplexCarSlowBeDraggedOut_CreateFirstSubTask 0x6485AC -#define HOOKSIZE_CTaskComplexCarSlowBeDraggedOut_CreateFirstSubTask 6 +#define HOOKPOS_CTaskComplexCarSlowBeDraggedOut_CreateFirstSubTask 0x6485AC +#define HOOKSIZE_CTaskComplexCarSlowBeDraggedOut_CreateFirstSubTask 6 DWORD RETURN_CTaskComplexCarSlowBeDraggedOut_CreateFirstSubTask = 0x6485B2; DWORD RETURN_CTaskComplexCarSlowBeDraggedOut_CreateFirstSubTask_Invalid = 0x6485E1; void OnMY_CTaskComplexCarSlowBeDraggedOut_CreateFirstSubTask() @@ -1407,9 +2893,12 @@ void OnMY_CTaskComplexCarSlowBeDraggedOut_CreateFirstSubTask() LogEvent(817, "CTaskComplexCarSlowBeDraggedOut", "", "CTaskComplexCarSlowBeDraggedOut race condition"); } -void _declspec(naked) HOOK_CTaskComplexCarSlowBeDraggedOut_CreateFirstSubTask() +static void __declspec(naked) HOOK_CTaskComplexCarSlowBeDraggedOut_CreateFirstSubTask() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { test eax, eax jz invalid_vehicle @@ -1423,11 +2912,12 @@ void _declspec(naked) HOOK_CTaskComplexCarSlowBeDraggedOut_CreateFirstSubTask() popad jmp RETURN_CTaskComplexCarSlowBeDraggedOut_CreateFirstSubTask_Invalid } + // clang-format on } //////////////////////////////////////////////////////////////////////// // OnMY_printf -// +// // GTA outputs stuff via printf which we can use to help diagnose problems //////////////////////////////////////////////////////////////////////// void _cdecl OnMY_printf(DWORD dwCalledFrom, const char* szMessage) @@ -1460,13 +2950,16 @@ void _cdecl OnMY_printf(DWORD dwCalledFrom, const char* szMessage) } // hook info -#define HOOKPOS_printf 0x821982 -#define HOOKSIZE_printf 7 -#define HOOKCHECK_printf 0x6A -DWORD RETURN_printf = 0x821989; -void _declspec(naked) HOOK_printf() +#define HOOKPOS_printf 0x821982 +#define HOOKSIZE_printf 7 +#define HOOKCHECK_printf 0x6A +DWORD RETURN_printf = 0x821989; +static void __declspec(naked) HOOK_printf() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*1] @@ -1475,29 +2968,33 @@ void _declspec(naked) HOOK_printf() add esp, 4*2 popad - // Replaced code + // Replaced code push 10h push 887DC0h jmp RETURN_printf } + // clang-format on } //////////////////////////////////////////////////////////////////////// // RwMatrixMultiply -// +// // The third received argument of type RwMatrixTag* is a null pointer //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_RwMatrixMultiply 0x7F18B0 -#define HOOKSIZE_RwMatrixMultiply 6 -#define HOOKCHECK_RwMatrixMultiply 0x8B -DWORD RETURN_RwMatrixMultiply = 0x7F18B6; -void _declspec(naked) HOOK_RwMatrixMultiply() +#define HOOKPOS_RwMatrixMultiply 0x7F18B0 +#define HOOKSIZE_RwMatrixMultiply 6 +#define HOOKCHECK_RwMatrixMultiply 0x8B +DWORD RETURN_RwMatrixMultiply = 0x7F18B6; +static void __declspec(naked) HOOK_RwMatrixMultiply() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov eax, [esp+0Ch] cmp eax, 0x480 - jb cont // Skip code if eax is low + jb cont // Skip code if eax is low mov ecx, dword ptr ds:[0C979BCh] jmp RETURN_RwMatrixMultiply @@ -1507,31 +3004,47 @@ void _declspec(naked) HOOK_RwMatrixMultiply() call CrashAverted retn } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CAnimBlendNode::GetCurrentTranslation -// +// // Invalid endKeyFrameIndex //////////////////////////////////////////////////////////////////////// void OnMY_CAnimBlendNode_GetCurrentTranslation(CAnimBlendNodeSAInterface* pInterface) { - // Crash will occur at offset 0xCFCD6 + if (!pInterface) + return; + + // Crash will occur at offset 0x000CFCD6 OnCrashAverted(32); CAnimBlendAssociationSAInterface* pAnimAssoc = pInterface->pAnimBlendAssociation; - CAnimBlendSequenceSAInterface* pAnimSequence = pInterface->pAnimSequence; - CAnimBlendHierarchySAInterface* pAnimHierarchy = pAnimAssoc->pAnimHierarchy; + if (!pAnimAssoc) + return; + + CAnimBlendSequenceSAInterface* pAnimSequence = pInterface->pAnimSequence; + if (!pAnimSequence) + return; + + CAnimBlendHierarchySAInterface* pAnimHierarchy = pAnimAssoc->pAnimHierarchy; + if (!pAnimHierarchy) + return; + + bool bSequenceExistsInHierarchy = false; - bool bSequenceExistsInHierarchy = false; - CAnimBlendSequenceSAInterface* pAnimHierSequence = pAnimHierarchy->pSequences; - for (int i = 0; i < pAnimHierarchy->usNumSequences; i++) + if (pAnimHierarchy->pSequences && pAnimHierarchy->usNumSequences > 0 && pAnimHierarchy->usNumSequences < 1000) { - if (pAnimHierSequence == pAnimSequence) + CAnimBlendSequenceSAInterface* pAnimHierSequence = pAnimHierarchy->pSequences; + for (int i = 0; i < pAnimHierarchy->usNumSequences; i++) { - bSequenceExistsInHierarchy = true; - break; + if (pAnimHierSequence == pAnimSequence) + { + bSequenceExistsInHierarchy = true; + break; + } + pAnimHierSequence++; } - pAnimHierSequence++; } LogEvent(588, "GetCurrentTranslation", "Incorrect endKeyFrameIndex", @@ -1544,41 +3057,42 @@ void OnMY_CAnimBlendNode_GetCurrentTranslation(CAnimBlendNodeSAInterface* pInter } // Hook info -#define HOOKPOS_CAnimBlendNode_GetCurrentTranslation 0x4CFCB5 -#define HOOKSIZE_CAnimBlendNode_GetCurrentTranslation 6 -DWORD RETURN_CAnimBlendNode_GetCurrentTranslation = 0x4CFCBB; -void _declspec(naked) HOOK_CAnimBlendNode_GetCurrentTranslation() +#define HOOKPOS_CAnimBlendNode_GetCurrentTranslation 0x4CFCB5 +#define HOOKSIZE_CAnimBlendNode_GetCurrentTranslation 6 +DWORD RETURN_CAnimBlendNode_GetCurrentTranslation = 0x4CFCBB; +static void __declspec(naked) HOOK_CAnimBlendNode_GetCurrentTranslation() { - _asm - { - // if end key frame index is greater than 10,000 then return + MTA_VERIFY_HOOK_LOCAL_SIZE; + + __asm + {// if end key frame index is greater than 10,000 then return cmp eax, 0x2710 jg altcode + // Normal path - execute original code push ebx mov bl, [edx + 4] shr bl, 1 jmp RETURN_CAnimBlendNode_GetCurrentTranslation - // do alternate code - altcode : + // Crash prevention path + altcode: + // Save registers before logging pushad - push ebp // this + push ebp // Pass 'this' pointer call OnMY_CAnimBlendNode_GetCurrentTranslation - add esp, 4 * 1 + add esp, 4 popad - pop edi - pop esi - pop ebp - add esp, 18h + // Return safely without executing original buggy code + // The function expects 8 bytes of parameters retn 8 - } + } } //////////////////////////////////////////////////////////////////////// // CStreaming::AreAnimsUsedByRequestedModels -// +// // GTA streamer will use this function to decide if IFP blocks should be unloaded or not. // We will return true to disable unloading. //////////////////////////////////////////////////////////////////////// @@ -1600,22 +3114,26 @@ bool __cdecl OnMY_CStreaming_AreAnimsUsedByRequestedModels(int modelID) } // Hook info -#define HOOKPOS_CStreaming_AreAnimsUsedByRequestedModels 0x407AD5 -#define HOOKSIZE_CStreaming_AreAnimsUsedByRequestedModels 7 -void _declspec(naked) HOOK_CStreaming_AreAnimsUsedByRequestedModels() +#define HOOKPOS_CStreaming_AreAnimsUsedByRequestedModels 0x407AD5 +#define HOOKSIZE_CStreaming_AreAnimsUsedByRequestedModels 7 +static void __declspec(naked) HOOK_CStreaming_AreAnimsUsedByRequestedModels() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push [esp + 4] call OnMY_CStreaming_AreAnimsUsedByRequestedModels add esp, 0x4 retn } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CTrain::ProcessControl -// +// // This hook overwrites the logic to wrap the train's rail distance, because in the // original game code this could cause an infinite loop // @@ -1623,8 +3141,8 @@ void _declspec(naked) HOOK_CStreaming_AreAnimsUsedByRequestedModels() // >>> 0x6F8F89 | D9 86 A8 05 00 00 | fld dword ptr [esi + 5A8h] // 0x6F8F8F | D8 1D 50 8B 85 00 | fcomp ds: __real @00000000 //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CTrain__ProcessControl 0x6F8F89 -#define HOOKSIZE_CTrain__ProcessControl 6 +#define HOOKPOS_CTrain__ProcessControl 0x6F8F89 +#define HOOKSIZE_CTrain__ProcessControl 6 static DWORD CONTINUE_CTrain__ProcessControl = 0x6F8FE5; // 0xC37FEC; float RailTrackLength[NUM_TRACKS] @@ -1667,9 +3185,12 @@ static void _cdecl WrapTrainRailDistance(CTrainSAInterface* train) train->m_fTrainRailDistance = railDistance; } -static void _declspec(naked) HOOK_CTrain__ProcessControl() +static void __declspec(naked) HOOK_CTrain__ProcessControl() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi // CVehicleSAInterface* @@ -1678,11 +3199,12 @@ static void _declspec(naked) HOOK_CTrain__ProcessControl() popad jmp CONTINUE_CTrain__ProcessControl } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CTaskComplexCarSlowBeDraggedOutAndStandUp::CreateFirstSubTask -// +// // This hook adds a null-pointer check for eax, which stores the ped's current vehicle. // Returning a null-pointer from this function will prevent the animation from being played. // @@ -1690,8 +3212,8 @@ static void _declspec(naked) HOOK_CTrain__ProcessControl() // >>> 0x648AAF | 8B 80 84 03 00 00 | mov eax, [eax + 384h] // 0x648AB5 | 0F B6 80 DE 00 00 00 | movzx eax, byte ptr [eax + 0DEh] //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CTaskComplexCarSlowBeDraggedOutAndStandUp__CreateFirstSubTask 0x648AAF -#define HOOKSIZE_CTaskComplexCarSlowBeDraggedOutAndStandUp__CreateFirstSubTask 6 +#define HOOKPOS_CTaskComplexCarSlowBeDraggedOutAndStandUp__CreateFirstSubTask 0x648AAF +#define HOOKSIZE_CTaskComplexCarSlowBeDraggedOutAndStandUp__CreateFirstSubTask 6 static DWORD CONTINUE_CTaskComplexCarSlowBeDraggedOutAndStandUp__CreateFirstSubTask = 0x648AB5; static void _cdecl LOG_CTaskComplexCarSlowBeDraggedOutAndStandUp__CreateFirstSubTask() @@ -1699,10 +3221,13 @@ static void _cdecl LOG_CTaskComplexCarSlowBeDraggedOutAndStandUp__CreateFirstSub LogEvent(819, "CTaskComplexCarSlowBeDraggedOutAndStandUp::CreateFirstSubTask", "eax is null", ""); } -static void _declspec(naked) HOOK_CTaskComplexCarSlowBeDraggedOutAndStandUp__CreateFirstSubTask() +static void __declspec(naked) HOOK_CTaskComplexCarSlowBeDraggedOutAndStandUp__CreateFirstSubTask() { - _asm - { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { test eax, eax jz returnZeroTaskLocation mov eax, [eax + 384h] @@ -1715,12 +3240,13 @@ static void _declspec(naked) HOOK_CTaskComplexCarSlowBeDraggedOutAndStandUp__Cre pop edi pop esi retn 4 - } + } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CVehicleModelInfo::LoadVehicleColours -// +// // A modified data/carcols.dat can have entries with invalid model names and these cause // CModelInfo::GetModelInfo to return a null pointer, but the original code doesn't verify // the return value and tries to use the null pointer. This hook adds a null pointer check @@ -1735,14 +3261,17 @@ static void _cdecl LOG_CVehicleModelInfo__LoadVehicleColours(int location, const // >>> 0x5B6B20 | 8B F0 | mov esi, eax // 0x5B6B22 | 8D 47 FF | lea eax, [edi - 1] // 0x5B6B25 | 99 | cdq -#define HOOKPOS_CVehicleModelInfo__LoadVehicleColours_1 0x5B6B20 -#define HOOKSIZE_CVehicleModelInfo__LoadVehicleColours_1 5 +#define HOOKPOS_CVehicleModelInfo__LoadVehicleColours_1 0x5B6B20 +#define HOOKSIZE_CVehicleModelInfo__LoadVehicleColours_1 5 static DWORD CONTINUE_CVehicleModelInfo__LoadVehicleColours_1 = 0x5B6B25; static DWORD SKIP_CVehicleModelInfo__LoadVehicleColours_1 = 0x5B6D04; -static void _declspec(naked) HOOK_CVehicleModelInfo__LoadVehicleColours_1() +static void __declspec(naked) HOOK_CVehicleModelInfo__LoadVehicleColours_1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { test eax, eax jnz continueLoadingColorLineLocation @@ -1763,20 +3292,24 @@ static void _declspec(naked) HOOK_CVehicleModelInfo__LoadVehicleColours_1() lea eax, [edi - 1] jmp CONTINUE_CVehicleModelInfo__LoadVehicleColours_1 } + // clang-format on } // 0x5B6CA5 | E8 96 EC F0 FF | call CModelInfo::GetModelInfo // >>> 0x5B6CAA | 8B F0 | mov esi, eax // 0x5B6CAC | 8D 47 FF | lea eax, [edi - 1] // 0x5B6CAF | 99 | cdq -#define HOOKPOS_CVehicleModelInfo__LoadVehicleColours_2 0x5B6CAA -#define HOOKSIZE_CVehicleModelInfo__LoadVehicleColours_2 5 +#define HOOKPOS_CVehicleModelInfo__LoadVehicleColours_2 0x5B6CAA +#define HOOKSIZE_CVehicleModelInfo__LoadVehicleColours_2 5 static DWORD CONTINUE_CVehicleModelInfo__LoadVehicleColours_2 = 0x5B6CAF; static DWORD SKIP_CVehicleModelInfo__LoadVehicleColours_2 = 0x5B6D04; -static void _declspec(naked) HOOK_CVehicleModelInfo__LoadVehicleColours_2() +static void __declspec(naked) HOOK_CVehicleModelInfo__LoadVehicleColours_2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { test eax, eax jnz continueLoadingColorLineLocation @@ -1797,11 +3330,12 @@ static void _declspec(naked) HOOK_CVehicleModelInfo__LoadVehicleColours_2() lea eax, [edi - 1] jmp CONTINUE_CVehicleModelInfo__LoadVehicleColours_2 } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CPlaceName::Process -// +// // Prevent the original game code from accessing the ped's vehicle, when it's a null pointer // and the ped flag bInVehicle is set by setting the ped flag to zero. // @@ -1809,29 +3343,33 @@ static void _declspec(naked) HOOK_CVehicleModelInfo__LoadVehicleColours_2() // >>> 0x571F39 | 8B 88 6C 04 00 00 | mov ecx, [eax + 46Ch] // 0x571F3F | F6 C5 01 | test ch, 1 //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CPlaceName__Process 0x571F39 -#define HOOKSIZE_CPlaceName__Process 6 +#define HOOKPOS_CPlaceName__Process 0x571F39 +#define HOOKSIZE_CPlaceName__Process 6 static DWORD CONTINUE_CPlaceName__Process = 0x571F3F; -static void _declspec(naked) HOOK_CPlaceName__Process() +static void __declspec(naked) HOOK_CPlaceName__Process() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov ecx, [eax + 46Ch] - test ch, 1 // if (ped->pedFlags.bInVehicle + test ch, 1 // if (ped->pedFlags.bInVehicle jz continueAfterFixLocation - mov ebx, [eax + 58Ch] // && !ped->m_pVehicle) + mov ebx, [eax + 58Ch] // && !ped->m_pVehicle) test ebx, ebx jnz continueAfterFixLocation and ch, 0FEh - mov dword ptr [eax + 46Ch], ecx // ped->pedFlags.bInVehicle = 0 + mov dword ptr [eax + 46Ch], ecx // ped->pedFlags.bInVehicle = 0 continueAfterFixLocation: popad mov ecx, [eax + 46Ch] jmp CONTINUE_CPlaceName__Process } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -1854,18 +3392,22 @@ static void LOG_CWorld__FindObjectsKindaCollidingSectorList(unsigned int modelId } } -#define HOOKPOS_CWorld__FindObjectsKindaCollidingSectorList 0x56508C +#define HOOKPOS_CWorld__FindObjectsKindaCollidingSectorList 0x56508C #define HOOKSIZE_CWorld__FindObjectsKindaCollidingSectorList 0xA -static const unsigned int RETURN_CWorld__FindObjectsKindaCollidingSectorList = 0x565096; -static const unsigned int RETURN_CWorld__FindObjectsKindaCollidingSectorList_SKIP = 0x5650C3; -static void _declspec(naked) HOOK_CWorld__FindObjectsKindaCollidingSectorList() +static const unsigned int RETURN_CWorld__FindObjectsKindaCollidingSectorList = 0x565096; +static const unsigned int RETURN_CWorld__FindObjectsKindaCollidingSectorList_SKIP = 0x5650C3; +static void __declspec(naked) HOOK_CWorld__FindObjectsKindaCollidingSectorList() { - _asm { - mov eax, [edx*4+0xA9B0C8] // CModelInfo::ms_modelInfoPtrs + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + mov eax, [edx*4+0xA9B0C8] // CModelInfo::ms_modelInfoPtrs test eax, eax jz skip - mov ecx, [eax+0x14] // m_pColModel + mov ecx, [eax+0x14] // m_pColModel test ecx, ecx jz skip @@ -1880,11 +3422,12 @@ static void _declspec(naked) HOOK_CWorld__FindObjectsKindaCollidingSectorList() jmp RETURN_CWorld__FindObjectsKindaCollidingSectorList_SKIP } + // clang-format on } //////////////////////////////////////////////////////////////////////// // RpClumpForAllAtomics -// +// // Adds a nullptr check for the clump object pointer. // // >>> 0x749B70 | 8B 44 24 04 | mov eax, [esp+arg_0] @@ -1892,15 +3435,18 @@ static void _declspec(naked) HOOK_CWorld__FindObjectsKindaCollidingSectorList() // >>> 0x749B75 | 55 | push ebp // 0x749B76 | 56 | push esi //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_RpClumpForAllAtomics 0x749B70 -#define HOOKSIZE_RpClumpForAllAtomics 6 +#define HOOKPOS_RpClumpForAllAtomics 0x749B70 +#define HOOKSIZE_RpClumpForAllAtomics 6 static DWORD CONTINUE_RpClumpForAllAtomics = 0x749B76; -static void _declspec(naked) HOOK_RpClumpForAllAtomics() +static void __declspec(naked) HOOK_RpClumpForAllAtomics() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - mov eax, [esp+4] // RpClump* clump + mov eax, [esp+4] // RpClump* clump test eax, eax jnz continueAfterFixLocation retn @@ -1910,23 +3456,27 @@ static void _declspec(naked) HOOK_RpClumpForAllAtomics() push ebp jmp CONTINUE_RpClumpForAllAtomics } + // clang-format on } //////////////////////////////////////////////////////////////////////// // RpAnimBlendClumpGetFirstAssociation -// +// // Adds a nullptr check for the clump object pointer. // // >>> 0x4D6A70 | 8B 0D 78 F8 B5 00 | mov ecx, ds:_ClumpOffset // 0x4D6A76 | 8B 44 24 04 | mov eax, [esp+4] //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_RpAnimBlendClumpGetFirstAssociation 0x4D6A70 -#define HOOKSIZE_RpAnimBlendClumpGetFirstAssociation 6 +#define HOOKPOS_RpAnimBlendClumpGetFirstAssociation 0x4D6A70 +#define HOOKSIZE_RpAnimBlendClumpGetFirstAssociation 6 static DWORD CONTINUE_RpAnimBlendClumpGetFirstAssociation = 0x4D6A76; -static void _declspec(naked) HOOK_RpAnimBlendClumpGetFirstAssociation() +static void __declspec(naked) HOOK_RpAnimBlendClumpGetFirstAssociation() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov eax, [esp+4] // RpClump* clump test eax, eax @@ -1937,24 +3487,28 @@ static void _declspec(naked) HOOK_RpAnimBlendClumpGetFirstAssociation() mov ecx, ds:[0xB5F878] jmp CONTINUE_RpAnimBlendClumpGetFirstAssociation } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CAnimManager::BlendAnimation -// +// // Adds a nullptr check for the clump object pointer. // // >>> 0x4D4610 | 83 EC 14 | sub esp, 14h // >>> 0x4D4613 | 8B 4C 24 18 | mov ecx, [esp+18h] // 0x4D4617 | 8B 15 34 EA B4 00 | mov edx, CAnimManager::ms_aAnimAssocGroups //////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CAnimManager__BlendAnimation 0x4D4610 -#define HOOKSIZE_CAnimManager__BlendAnimation 7 +#define HOOKPOS_CAnimManager__BlendAnimation 0x4D4610 +#define HOOKSIZE_CAnimManager__BlendAnimation 7 static DWORD CONTINUE_CAnimManager__BlendAnimation = 0x4D4617; -static void _declspec(naked) HOOK_CAnimManager__BlendAnimation() +static void __declspec(naked) HOOK_CAnimManager__BlendAnimation() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov eax, [esp+4] // RpClump* clump test eax, eax @@ -1966,6 +3520,7 @@ static void _declspec(naked) HOOK_CAnimManager__BlendAnimation() mov ecx, [esp+18h] jmp CONTINUE_CAnimManager__BlendAnimation } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -2015,10 +3570,13 @@ static void _cdecl POST_PROCESS_FxSystemBP_c__Load(CFxSystemBPSAInterface* bluep } } -static void _declspec(naked) HOOK_FxSystemBP_c__Load() +static void __declspec(naked) HOOK_FxSystemBP_c__Load() { - _asm - { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { pushad push ebp call POST_PROCESS_FxSystemBP_c__Load @@ -2028,10 +3586,11 @@ static void _declspec(naked) HOOK_FxSystemBP_c__Load() pop ebp xor al, al pop ebx - // mov large fs:0, ecx + // mov large fs:0, ecx add esp, 5E8h retn 0Ch - } + } + // clang-format on } //////////////////////////////////////////////////////////////////////// @@ -2047,10 +3606,13 @@ static void _declspec(naked) HOOK_FxSystemBP_c__Load() #define HOOKPOS_FxPrim_c__Enable 0x4A9F50 #define HOOKSIZE_FxPrim_c__Enable 10 -static void _declspec(naked) HOOK_FxPrim_c__Enable() +static void __declspec(naked) HOOK_FxPrim_c__Enable() { - _asm - { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { test ecx, ecx jz returnFromFunction mov al, [esp+4] @@ -2058,25 +3620,29 @@ static void _declspec(naked) HOOK_FxPrim_c__Enable() returnFromFunction: retn 4 - } + } + // clang-format on } //////////////////////////////////////////////////////////////////////// // CFire::ProcessFire -// +// // GitHub #1757 (https://github.com/multitheftauto/mtasa-blue/issues/1757) -// +// // Null pointer to the attachedTo field in the CFire structure //////////////////////////////////////////////////////////////////////// #define HOOKPOS_CFire_ProcessFire 0x53A6FC #define HOOKSIZE_CFire_ProcessFire 9 -static constexpr DWORD CONTINUE_CFire_ProcessFire = 0x53A705; -static constexpr DWORD SKIP_CFire_ProcessFire = 0x53A69C; -static void _declspec(naked) HOOK_CFire_ProcessFire() +static constexpr DWORD CONTINUE_CFire_ProcessFire = 0x53A705; +static constexpr DWORD SKIP_CFire_ProcessFire = 0x53A69C; +static void __declspec(naked) HOOK_CFire_ProcessFire() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - test byte ptr [esi], 1 // If the "active" flag has been set to 0, we skip processing attached entities + test byte ptr [esi], 1 // If the "active" flag has been set to 0, we skip processing attached entities jz skip mov ecx, [esi+10h] @@ -2087,6 +3653,127 @@ static void _declspec(naked) HOOK_CFire_ProcessFire() mov ecx, esi jmp SKIP_CFire_ProcessFire } + // clang-format on +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// CColModel::MakeMultipleAlloc - Validate collision data before converting +// single-allocation to multi-allocation format via CCollisionData::Copy. +// +// Corrupt collision data (e.g. from PC_Scratch buffer overflow) can produce +// bogus shadow vertex/triangle counts, causing Copy to read past allocations. +// +////////////////////////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CColModel_MakeMultipleAlloc 0x40F740 +#define HOOKSIZE_CColModel_MakeMultipleAlloc 5 +static void __fastcall HOOK_CColModel_MakeMultipleAlloc(CColModelSAInterface* pColModel, void*) +{ + if (CColDataSA* pData = pColModel->m_data) + { + constexpr std::uint32_t MAX_SHADOW_TRIANGLES = 5000; + constexpr std::uint32_t MAX_SHADOW_VERTICES = 10000; + + const bool shadowCorrupt = pData->m_numShadowTriangles > MAX_SHADOW_TRIANGLES || pData->m_numShadowVertices > MAX_SHADOW_VERTICES || + (pData->m_numShadowVertices > 0 && !pData->m_shadowVertices) || + (pData->m_numShadowTriangles > 0 && !pData->m_shadowTriangles); + + if (shadowCorrupt) + { + pData->m_numShadowTriangles = 0; + pData->m_numShadowVertices = 0; + pData->m_shadowVertices = nullptr; + pData->m_shadowTriangles = nullptr; + pData->m_hasShadowInfo = 0; + pData->m_hasShadow = 0; + + OnCrashAverted(9801); + } + } + + // Call the original MakeMultipleAlloc + using MakeMultipleAlloc_t = void(__thiscall*)(CColModelSAInterface*); + reinterpret_cast(0x1564A10)(pColModel); +} + +//////////////////////////////////////////////////////////////////////// +// AreTexturesUsedByRequestedModels +// +// Null ms_modelInfoPtrs[modelId] during requested-list and channel iteration +//////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CrashFix_Misc50 0x156650D +#define HOOKSIZE_CrashFix_Misc50 7 +DWORD RETURN_CrashFix_Misc50 = 0x1566514; +DWORD RETURN_CrashFix_Misc50B = 0x1566552; +void _declspec(naked) HOOK_CrashFix_Misc50() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + test edx, edx + js skip + mov ecx, dword ptr [edx*4 + 0A9B0C8h] + test ecx, ecx + jnz cont + skip: + push 50 + call CrashAverted + jmp RETURN_CrashFix_Misc50B + cont: + jmp RETURN_CrashFix_Misc50 + } + // clang-format on +} + +#define HOOKPOS_CrashFix_Misc51 0x156658A +#define HOOKSIZE_CrashFix_Misc51 7 +DWORD RETURN_CrashFix_Misc51 = 0x1566591; +DWORD RETURN_CrashFix_Misc51B = 0x15665BB; +void _declspec(naked) HOOK_CrashFix_Misc51() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + test eax, eax + js skip + mov edx, dword ptr [eax*4 + 0A9B0C8h] + test edx, edx + jnz cont + skip: + push 51 + call CrashAverted + jmp RETURN_CrashFix_Misc51B + cont: + jmp RETURN_CrashFix_Misc51 + } + // clang-format on +} + +#define HOOKPOS_CrashFix_Misc52 0x15665C9 +#define HOOKSIZE_CrashFix_Misc52 7 +DWORD RETURN_CrashFix_Misc52 = 0x15665D0; +DWORD RETURN_CrashFix_Misc52B = 0x1566600; +void _declspec(naked) HOOK_CrashFix_Misc52() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + test eax, eax + js skip + mov ecx, dword ptr [eax*4 + 0A9B0C8h] + test ecx, ecx + jnz cont + skip: + push 52 + call CrashAverted + jmp RETURN_CrashFix_Misc52B + cont: + jmp RETURN_CrashFix_Misc52 + } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -2098,7 +3785,6 @@ void CMultiplayerSA::InitHooks_CrashFixHacks() { EZHookInstall(CrashFix_Misc1); EZHookInstall(CrashFix_Misc2); - // EZHookInstall ( CrashFix_Misc3 ); EZHookInstall(CrashFix_Misc4); EZHookInstall(CrashFix_Misc5); EZHookInstall(CrashFix_Misc6); @@ -2125,7 +3811,25 @@ void CMultiplayerSA::InitHooks_CrashFixHacks() EZHookInstall(CrashFix_Misc27); EZHookInstall(CrashFix_Misc28); EZHookInstall(CrashFix_Misc29); + EZHookInstall(CrashFix_Misc43); + EZHookInstall(CrashFix_Misc45); + EZHookInstall(CrashFix_Misc44); + EZHookInstall(CrashFix_Misc47); + EZHookInstall(CrashFix_Misc48); + EZHookInstall(CrashFix_Misc49); EZHookInstallChecked(CrashFix_Misc30); + EZHookInstall(CrashFix_Misc32); + EZHookInstall(CrashFix_Misc33); + EZHookInstall(CrashFix_Misc34); + EZHookInstallChecked(CrashFix_Misc35); + EZHookInstallChecked(CrashFix_Misc36); + EZHookInstallChecked(CrashFix_Misc37); + EZHookInstallChecked(CrashFix_Misc38); + EZHookInstallChecked(CrashFix_VBInstV3dNull); + EZHookInstallChecked(CrashFix_VBInstV3dMorphNull); + EZHookInstallChecked(CrashFix_VBInstWeightsNull); + EZHookInstallChecked(CrashFix_DynVBCreateNull); + EZHookInstall(CrashFix_Misc39); EZHookInstall(CClumpModelInfo_GetFrameFromId); EZHookInstallChecked(CEntity_GetBoundRect); EZHookInstallChecked(CVehicle_AddUpgrade); @@ -2151,6 +3855,12 @@ void CMultiplayerSA::InitHooks_CrashFixHacks() EZHookInstall(FxPrim_c__Enable); EZHookInstall(CFire_ProcessFire); + EZHookInstall(CColModel_MakeMultipleAlloc); + + EZHookInstall(CrashFix_Misc50); + EZHookInstall(CrashFix_Misc51); + EZHookInstall(CrashFix_Misc52); + // Install train crossing crashfix (the temporary variable is required for the template logic) void (*temp)() = HOOK_TrainCrossingBarrierCrashFix; HookInstall(HOOKPOS_CObject_Destructor_TrainCrossing_Check, (DWORD)temp, 5); diff --git a/Client/multiplayer_sa/CMultiplayerSA_CustomAnimations.cpp b/Client/multiplayer_sa/CMultiplayerSA_CustomAnimations.cpp index 50a95324592..55f3c52a017 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_CustomAnimations.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_CustomAnimations.cpp @@ -73,54 +73,72 @@ CAnimBlendAssocGroupSAInterface* getAnimAssocGroupInterface(eAnimGroup animGroup return &pAnimGroupArray[(int)animGroup]; } -void _declspec(naked) HOOK_CAnimBlendAssociation_SetCurrentTime() +#define HOOKPOS_CAnimBlendAssociation_SetCurrentTime 0x4CEA80 +static void __declspec(naked) HOOK_CAnimBlendAssociation_SetCurrentTime() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on if (bDisableCallsToCAnimBlendNode) { - _asm + // clang-format off + __asm { popad retn 4 } + // clang-format on } - _asm + // clang-format off + __asm { popad mov eax, [esp+4] fld [esp+4] jmp RETURN_CAnimBlendAssociation_SetCurrentTime_NORMALFLOW } + // clang-format on } -void _declspec(naked) HOOK_RpAnimBlendClumpUpdateAnimations() +#define HOOKPOS_RpAnimBlendClumpUpdateAnimations 0x4D34F0 +static void __declspec(naked) HOOK_RpAnimBlendClumpUpdateAnimations() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on if (bDisableCallsToCAnimBlendNode) { - _asm + // clang-format off + __asm { popad retn } + // clang-format on } - _asm + // clang-format off + __asm { popad sub esp, 3Ch mov eax, ds:[0B5F878h] jmp RETURN_RpAnimBlendClumpUpdateAnimations_NORMALFLOW } + // clang-format on } CAnimBlendAssociationSAInterface* __cdecl CAnimBlendAssocGroup_CopyAnimation(RpClump* pClump, eAnimGroup u32AnimGroupID, eAnimID animID) @@ -142,9 +160,13 @@ CAnimBlendAssociationSAInterface* __cdecl CAnimBlendAssocGroup_CopyAnimation(RpC return pAnimAssociationInterface; } -void _declspec(naked) HOOK_CAnimManager_AddAnimation() +#define HOOKPOS_CAnimManager_AddAnimation 0x4d3aa0 +static void __declspec(naked) HOOK_CAnimManager_AddAnimation() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { lea edx, [esp + 8] // animationGroupID address lea eax, [esp + 12] // animationID address @@ -154,10 +176,12 @@ void _declspec(naked) HOOK_CAnimManager_AddAnimation() add esp, 8 pushad } + // clang-format on if (m_pAddAnimationHandler) { - _asm + // clang-format off + __asm { popad mov ecx, [esp + 4] // animationClump @@ -173,20 +197,27 @@ void _declspec(naked) HOOK_CAnimManager_AddAnimation() jmp RETURN_CAnimManager_AddAnimation } + // clang-format on } - _asm + // clang-format off + __asm { popad mov eax, dword ptr[esp + 0Ch] mov edx, dword ptr ds : [0B4EA34h] jmp RETURN_CAnimManager_AddAnimation_NORMAL_FLOW } + // clang-format on } -void _declspec(naked) HOOK_CAnimManager_AddAnimationAndSync() +#define HOOKPOS_CAnimManager_AddAnimationAndSync 0x4D3B30 +static void __declspec(naked) HOOK_CAnimManager_AddAnimationAndSync() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { lea edx, [esp + 12] // animationGroup address lea eax, [esp + 16] // animationID address @@ -196,10 +227,12 @@ void _declspec(naked) HOOK_CAnimManager_AddAnimationAndSync() add esp, 8 pushad } + // clang-format on if (m_pAddAnimationAndSyncHandler) { - _asm + // clang-format off + __asm { popad mov ecx, [esp + 4] // animationClump @@ -214,9 +247,11 @@ void _declspec(naked) HOOK_CAnimManager_AddAnimationAndSync() push edi jmp RETURN_CAnimManager_AddAnimationAndSync } + // clang-format on } - _asm + // clang-format off + __asm { popad @@ -224,18 +259,25 @@ void _declspec(naked) HOOK_CAnimManager_AddAnimationAndSync() mov edx, dword ptr ds : [0B4EA34h] jmp RETURN_CAnimManager_AddAnimationAndSync_NORMAL_FLOW } + // clang-format on } -void _declspec(naked) HOOK_CAnimManager_BlendAnimation_Hierarchy() +#define HOOKPOS_CAnimManager_BlendAnimation_Hierarchy 0x4D453E +static void __declspec(naked) HOOK_CAnimManager_BlendAnimation_Hierarchy() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on if (m_pBlendAnimationHierarchyHandler) { - _asm + // clang-format off + __asm { popad push eax // pAnimAssociation @@ -277,9 +319,11 @@ void _declspec(naked) HOOK_CAnimManager_BlendAnimation_Hierarchy() pushad jmp NORMAL_FLOW_BlendAnimation_Hierarchy } + // clang-format on } - _asm + // clang-format off + __asm { NORMAL_FLOW_BlendAnimation_Hierarchy: popad @@ -300,4 +344,21 @@ void _declspec(naked) HOOK_CAnimManager_BlendAnimation_Hierarchy() call FUNC_UncompressAnimation jmp RETURN_CAnimManager_BlendAnimation_Hierarchy } + // clang-format on +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// CMultiplayerSA::InitHooks_CustomAnimations +// +// Setup hooks +// +////////////////////////////////////////////////////////////////////////////////////////// +void CMultiplayerSA::InitHooks_CustomAnimations() +{ + HookInstall(HOOKPOS_CAnimBlendAssociation_SetCurrentTime, (DWORD)HOOK_CAnimBlendAssociation_SetCurrentTime, 8); + HookInstall(HOOKPOS_RpAnimBlendClumpUpdateAnimations, (DWORD)HOOK_RpAnimBlendClumpUpdateAnimations, 8); + HookInstall(HOOKPOS_CAnimManager_AddAnimation, (DWORD)HOOK_CAnimManager_AddAnimation, 10); + HookInstall(HOOKPOS_CAnimManager_AddAnimationAndSync, (DWORD)HOOK_CAnimManager_AddAnimationAndSync, 10); + HookInstall(HOOKPOS_CAnimManager_BlendAnimation_Hierarchy, (DWORD)HOOK_CAnimManager_BlendAnimation_Hierarchy, 5); } diff --git a/Client/multiplayer_sa/CMultiplayerSA_DeviceSelection.cpp b/Client/multiplayer_sa/CMultiplayerSA_DeviceSelection.cpp index 883cf24cecd..3d82fb9a354 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_DeviceSelection.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_DeviceSelection.cpp @@ -9,6 +9,8 @@ *****************************************************************************/ #include "StdInc.h" + +#include #define FUNC_rwDeviceSystemRequest 0x7F2AB0 #define FUNC_DialogFunc 0x745E50 #define FUNC_RwEngineGetSubSystemInfo 0x7F2C30 @@ -26,9 +28,28 @@ std::unordered_map GetFriendlyMonitorNamesForDevicePat if (!user32Lib) return monitorNames; - auto* getDisplayConfigBufferSizes = (decltype(GetDisplayConfigBufferSizes)*)GetProcAddress(user32Lib, "GetDisplayConfigBufferSizes"); - auto* queryDisplayConfig = (decltype(QueryDisplayConfig)*)GetProcAddress(user32Lib, "QueryDisplayConfig"); - auto* displayConfigGetDeviceInfo = (decltype(DisplayConfigGetDeviceInfo)*)GetProcAddress(user32Lib, "DisplayConfigGetDeviceInfo"); + using GetDisplayConfigBufferSizesFn = decltype(&GetDisplayConfigBufferSizes); + using QueryDisplayConfigFn = decltype(&QueryDisplayConfig); + using DisplayConfigGetDeviceInfoFn = decltype(&DisplayConfigGetDeviceInfo); + + GetDisplayConfigBufferSizesFn getDisplayConfigBufferSizes = nullptr; + QueryDisplayConfigFn queryDisplayConfig = nullptr; + DisplayConfigGetDeviceInfoFn displayConfigGetDeviceInfo = nullptr; + + const auto procGetDisplayConfigBufferSizes = GetProcAddress(user32Lib, "GetDisplayConfigBufferSizes"); + const auto procQueryDisplayConfig = GetProcAddress(user32Lib, "QueryDisplayConfig"); + const auto procDisplayConfigGetDeviceInfo = GetProcAddress(user32Lib, "DisplayConfigGetDeviceInfo"); + + static_assert(sizeof(getDisplayConfigBufferSizes) == sizeof(procGetDisplayConfigBufferSizes), "Unexpected function pointer size"); + static_assert(sizeof(queryDisplayConfig) == sizeof(procQueryDisplayConfig), "Unexpected function pointer size"); + static_assert(sizeof(displayConfigGetDeviceInfo) == sizeof(procDisplayConfigGetDeviceInfo), "Unexpected function pointer size"); + + if (procGetDisplayConfigBufferSizes) + std::memcpy(&getDisplayConfigBufferSizes, &procGetDisplayConfigBufferSizes, sizeof(getDisplayConfigBufferSizes)); + if (procQueryDisplayConfig) + std::memcpy(&queryDisplayConfig, &procQueryDisplayConfig, sizeof(queryDisplayConfig)); + if (procDisplayConfigGetDeviceInfo) + std::memcpy(&displayConfigGetDeviceInfo, &procDisplayConfigGetDeviceInfo, sizeof(displayConfigGetDeviceInfo)); if (!getDisplayConfigBufferSizes || !queryDisplayConfig || !displayConfigGetDeviceInfo) { FreeLibrary(user32Lib); @@ -65,14 +86,14 @@ std::unordered_map GetFriendlyMonitorNamesForDevicePat targetName.header.id = paths[i].targetInfo.id; targetName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; targetName.header.size = sizeof(targetName); - const LONG targetNameResult = DisplayConfigGetDeviceInfo(&targetName.header); + const LONG targetNameResult = displayConfigGetDeviceInfo(&targetName.header); DISPLAYCONFIG_SOURCE_DEVICE_NAME sourceName = {}; sourceName.header.adapterId = paths[i].sourceInfo.adapterId; sourceName.header.id = paths[i].sourceInfo.id; sourceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; sourceName.header.size = sizeof(sourceName); - const LONG sourceNameResult = DisplayConfigGetDeviceInfo(&sourceName.header); + const LONG sourceNameResult = displayConfigGetDeviceInfo(&sourceName.header); if (targetNameResult == ERROR_SUCCESS && sourceNameResult == ERROR_SUCCESS && targetName.monitorFriendlyDeviceName[0] != '\0') { char gdiDeviceName[std::size(sourceName.viewGdiDeviceName)]; @@ -94,7 +115,7 @@ struct RwSubSystemInfo char name[80]; }; -using rwDeviceSystemRequest = RwSubSystemInfo*(__cdecl*)(RwDevice* device, std::int32_t requestId, RwSubSystemInfo* pOut, void* pInOut, std::int32_t numIn); +using rwDeviceSystemRequest = RwSubSystemInfo*(__cdecl*)(RwDevice * device, std::int32_t requestId, RwSubSystemInfo* pOut, void* pInOut, std::int32_t numIn); static RwSubSystemInfo* RwEngineGetSubSystemInfo_Hooked(RwSubSystemInfo* subSystemInfo, std::int32_t subSystemIndex) { auto* rwGlobals = *(RwGlobals**)CLASS_RwGlobals; diff --git a/Client/multiplayer_sa/CMultiplayerSA_Direct3D.cpp b/Client/multiplayer_sa/CMultiplayerSA_Direct3D.cpp index e610f21509e..32d7fe35f94 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Direct3D.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Direct3D.cpp @@ -20,7 +20,8 @@ namespace DWORD ms_BehaviorFlags = 0; D3DPRESENT_PARAMETERS* ms_pPresentationParameters = NULL; IDirect3DDevice9** ms_ppReturnedDeviceInterface = NULL; -} // namespace + bool ms_hasDeviceArgs = false; +} // namespace DWORD RESTORE_Addr_PreCreateDevice; DWORD RESTORE_Size_PreCreateDevice; @@ -36,51 +37,77 @@ BYTE RESTORE_Bytes_PreCreateDevice[6]; void _cdecl OnPreCreateDevice(IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD* BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface) { - // Unpatch - MemCpy((PVOID)RESTORE_Addr_PreCreateDevice, RESTORE_Bytes_PreCreateDevice, RESTORE_Size_PreCreateDevice); - - // g_pCore->OnPreCreateDevice( pDirect3D, Adapter, DeviceType, hFocusWindow, *BehaviorFlags, pPresentationParameters ); - ms_pDirect3D = pDirect3D; - ms_Adapter = Adapter; - ms_DeviceType = DeviceType; - ms_hFocusWindow = hFocusWindow; - ms_BehaviorFlags = *BehaviorFlags; - ms_pPresentationParameters = pPresentationParameters; - ms_ppReturnedDeviceInterface = ppReturnedDeviceInterface; + // Safely unpatch with validation + if (RESTORE_Addr_PreCreateDevice && RESTORE_Size_PreCreateDevice > 0 && RESTORE_Size_PreCreateDevice <= sizeof(RESTORE_Bytes_PreCreateDevice)) + { + MemCpy((PVOID)RESTORE_Addr_PreCreateDevice, RESTORE_Bytes_PreCreateDevice, RESTORE_Size_PreCreateDevice); + } + + // Validate critical parameters before dereferencing + if (BehaviorFlags && pPresentationParameters && ppReturnedDeviceInterface) + { + ms_pDirect3D = pDirect3D; + ms_Adapter = Adapter; + ms_DeviceType = DeviceType; + ms_hFocusWindow = hFocusWindow; + ms_BehaviorFlags = *BehaviorFlags; + ms_pPresentationParameters = pPresentationParameters; + ms_ppReturnedDeviceInterface = ppReturnedDeviceInterface; + ms_hasDeviceArgs = true; + } + else + { + ms_hasDeviceArgs = false; + SString message; + message = "OnPreCreateDevice: missing device arguments for alt startup path"; + AddReportLog(8740, message); + } } // Hook info -#define HOOKPOS_PreCreateDevice 0x007F675B -#define HOOKSIZE_PreCreateDevice 6 -DWORD RETURN_PreCreateDevice = 0x07F6781; -void _declspec(naked) HOOK_PreCreateDevice() +#define HOOKPOS_PreCreateDevice 0x007F675B +#define HOOKSIZE_PreCreateDevice 6 +DWORD RETURN_PreCreateDevice = 0x07F6781; +static void __declspec(naked) HOOK_PreCreateDevice() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - // Run replaced code - mov ecx,dword ptr ds:[0C97C20h] - push 0C97C28h - push 0C9C040h - push eax - mov eax,dword ptr ds:[00C97C1Ch] + // Run replaced code - these pushes create the original function parameters + mov ecx,dword ptr ds:[0C97C20h] // pDirect3D + push 0C97C28h // ppReturnedDeviceInterface + push 0C9C040h // pPresentationParameters + push eax // BehaviorFlags (original eax) + mov eax,dword ptr ds:[00C97C1Ch] mov edx, [ecx] - push eax + push eax // hFocusWindow mov eax,dword ptr ds:[008E2428h] - push eax + push eax // DeviceType - mov eax, ds:0x0C97C24 // __RwD3DAdapterIndex - push eax - push ecx + mov eax, ds:0x0C97C24 // __RwD3DAdapterIndex + push eax // Adapter + push ecx // pDirect3D - pushad - push [esp+32+4*6] - push [esp+32+4*6] - lea eax,[esp+32+4*6] // Turn BehaviorFlags into a pointer so we can modify it + // Now we have 7 parameters on stack (28 bytes) + // Stack layout at ESP: [pDirect3D][Adapter][DeviceType][hFocusWindow][BehaviorFlags][pPresentationParameters][ppReturnedDeviceInterface] + + pushad // Save all registers (32 bytes), ESP now at ESP-32 + + // Pass parameters to OnPreCreateDevice + // After pushad, params start at ESP+32. Each push decreases ESP by 4, + // so [esp+32+4*6] effectively walks backward through the params: + // 1st access: ESP+56 = ppReturnedDeviceInterface, then ESP -= 4 + // 2nd access: ESP+56 = pPresentationParameters (was at ESP+52), etc. + push [esp+32+4*6] // ppReturnedDeviceInterface + push [esp+32+4*6] // pPresentationParameters + lea eax,[esp+32+4*6] // BehaviorFlags as pointer push eax - push [esp+32+4*6] - push [esp+32+4*6] - push [esp+32+4*6] - push [esp+32+4*6] + push [esp+32+4*6] // hFocusWindow + push [esp+32+4*6] // DeviceType + push [esp+32+4*6] // Adapter + push [esp+32+4*6] // pDirect3D call OnPreCreateDevice add esp, 4*7 popad @@ -88,6 +115,7 @@ void _declspec(naked) HOOK_PreCreateDevice() // Continue jmp RETURN_PreCreateDevice } + // clang-format on } //////////////////////////////////////////////////////////////// @@ -99,18 +127,55 @@ void _declspec(naked) HOOK_PreCreateDevice() //////////////////////////////////////////////////////////////// HRESULT _cdecl OnPostCreateDevice(HRESULT hResult) { - return g_pCore->OnPostCreateDevice(hResult, ms_pDirect3D, ms_Adapter, ms_DeviceType, ms_hFocusWindow, ms_BehaviorFlags, ms_pPresentationParameters, - ms_ppReturnedDeviceInterface); + if (!g_pCore) + { + ms_hasDeviceArgs = false; + return hResult; + } + + if (!ms_hasDeviceArgs) + { + SString message; + message = "OnPostCreateDevice: device arguments were not captured; skipping alt startup logic"; + AddReportLog(8741, message); + return hResult; + } + + if (!SharedUtil::IsReadablePointer(ms_ppReturnedDeviceInterface, sizeof(*ms_ppReturnedDeviceInterface))) + { + SString message; + message.Format("OnPostCreateDevice: invalid device pointer reference %p", ms_ppReturnedDeviceInterface); + AddReportLog(8742, message); + ms_hasDeviceArgs = false; + return hResult; + } + + if (!SharedUtil::IsReadablePointer(ms_pPresentationParameters, sizeof(*ms_pPresentationParameters))) + { + SString message; + message.Format("OnPostCreateDevice: invalid presentation parameters pointer %p", ms_pPresentationParameters); + AddReportLog(8743, message); + ms_hasDeviceArgs = false; + return hResult; + } + + HRESULT result = g_pCore->OnPostCreateDevice(hResult, ms_pDirect3D, ms_Adapter, ms_DeviceType, ms_hFocusWindow, ms_BehaviorFlags, + ms_pPresentationParameters, ms_ppReturnedDeviceInterface); + ms_hasDeviceArgs = false; + return result; } // Hook info -#define HOOKPOS_PostCreateDevice 0x07F6784 -#define HOOKSIZE_PostCreateDevice 6 -DWORD RETURN_PostCreateDevice = 0x07F678A; -DWORD RETURN_PostCreateDeviceB = 0x07F6799; -void _declspec(naked) HOOK_PostCreateDevice() +#define HOOKPOS_PostCreateDevice 0x07F6784 +#define HOOKSIZE_PostCreateDevice 6 +DWORD RETURN_PostCreateDevice = 0x07F678A; +DWORD RETURN_PostCreateDeviceB = 0x07F6799; +static void __declspec(naked) HOOK_PostCreateDevice() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Replaced code pushad @@ -130,6 +195,7 @@ void _declspec(naked) HOOK_PostCreateDevice() ok: jmp RETURN_PostCreateDeviceB } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_Explosions.cpp b/Client/multiplayer_sa/CMultiplayerSA_Explosions.cpp index 4e0dbeae747..9ec1fe801cd 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Explosions.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Explosions.cpp @@ -19,9 +19,12 @@ #define HOOKPOS_CWorld_TriggerExplosion 0x56B82E #define HOOKSIZE_CWorld_TriggerExplosion 8 static constexpr std::uintptr_t RETURN_CWorld_TriggerExplosion = 0x56B836; -static void _declspec(naked) HOOK_CWorld_TriggerExplosion() +static void __declspec(naked) HOOK_CWorld_TriggerExplosion() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov [esp+1Ch-8h], eax mov [esp+1Ch-10h], ecx @@ -36,15 +39,19 @@ static void _declspec(naked) HOOK_CWorld_TriggerExplosion() cmp esi, eax jmp RETURN_CWorld_TriggerExplosion } + // clang-format on } #define HOOKPOS_CWorld_TriggerExplosionSectorList 0x5677F4 #define HOOKSIZE_CWorld_TriggerExplosionSectorList 7 static constexpr std::uintptr_t RETURN_CWorld_TriggerExplosionSectorList = 0x5677FB; static constexpr std::uintptr_t SKIP_CWorld_TriggerExplosionSectorList = 0x568473; -static void _declspec(naked) HOOK_CWorld_TriggerExplosionSectorList() +static void __declspec(naked) HOOK_CWorld_TriggerExplosionSectorList() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // check entity->m_nScanCode == CWorld::ms_nCurrentScanCode mov ecx, dword ptr ds:[0xB7CD78] @@ -62,6 +69,7 @@ static void _declspec(naked) HOOK_CWorld_TriggerExplosionSectorList() skip: jmp SKIP_CWorld_TriggerExplosionSectorList } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_Files.cpp b/Client/multiplayer_sa/CMultiplayerSA_Files.cpp index 19184f3fc6b..9ecb6476d5e 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Files.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Files.cpp @@ -39,18 +39,20 @@ void OnMY_Rtl_fopen_Post(FILE* fh, DWORD calledFrom, const char* szFilename, con return; } - AddReportLog(5321, SString("Rtl_fopen failed: called from:%08x mode:%s name:%s", calledFrom, szMode, *strFilename)); SetApplicationSetting("diagnostics", "gta-fopen-fail", strFilename); } } // Hook info -#define HOOKPOS_Rtl_fopen 0x8232D8 -#define HOOKSIZE_Rtl_fopen 6 -DWORD RETURN_Rtl_fopen = 0x8232DE; -void _declspec(naked) HOOK_Rtl_fopen() +#define HOOKPOS_Rtl_fopen 0x8232D8 +#define HOOKSIZE_Rtl_fopen 6 +DWORD RETURN_Rtl_fopen = 0x8232DE; +static void __declspec(naked) HOOK_Rtl_fopen() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push [esp+4*3] push [esp+4*3] @@ -73,6 +75,7 @@ void _declspec(naked) HOOK_Rtl_fopen() push [esp+0x0c] jmp RETURN_Rtl_fopen } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -89,12 +92,15 @@ void OnMY_Rtl_fclose(DWORD calledFrom, FILE* fh) } // Hook info -#define HOOKPOS_Rtl_fclose 0x82318B -#define HOOKSIZE_Rtl_fclose 6 -DWORD RETURN_Rtl_fclose = 0x823192; -void _declspec(naked) HOOK_Rtl_fclose() +#define HOOKPOS_Rtl_fclose 0x82318B +#define HOOKSIZE_Rtl_fclose 6 +DWORD RETURN_Rtl_fclose = 0x823192; +static void __declspec(naked) HOOK_Rtl_fclose() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*1] @@ -107,6 +113,7 @@ void _declspec(naked) HOOK_Rtl_fclose() push 0x887EC8 jmp RETURN_Rtl_fclose } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_FixBadAnimId.cpp b/Client/multiplayer_sa/CMultiplayerSA_FixBadAnimId.cpp index d780a8d8d3d..2659691761c 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_FixBadAnimId.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_FixBadAnimId.cpp @@ -92,12 +92,15 @@ void _cdecl OnGetAnimHierarchyFromSkinClump(RpClump* pRpClump, void* pRpHAnimHie } } -#define HOOKPOS_GetAnimHierarchyFromSkinClump 0x734A5D -#define HOOKSIZE_GetAnimHierarchyFromSkinClump 7 -DWORD RETURN_GetAnimHierarchyFromSkinClump = 0x734A64; -void _declspec(naked) HOOK_GetAnimHierarchyFromSkinClump() +#define HOOKPOS_GetAnimHierarchyFromSkinClump 0x734A5D +#define HOOKSIZE_GetAnimHierarchyFromSkinClump 7 +DWORD RETURN_GetAnimHierarchyFromSkinClump = 0x734A64; +static void __declspec(naked) HOOK_GetAnimHierarchyFromSkinClump() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push[esp + 32 + 0x0C] // RpHAnimHierarchy* (return value) @@ -110,6 +113,7 @@ void _declspec(naked) HOOK_GetAnimHierarchyFromSkinClump() add esp, 10h jmp RETURN_GetAnimHierarchyFromSkinClump } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_FixLineOfSightArgs.cpp b/Client/multiplayer_sa/CMultiplayerSA_FixLineOfSightArgs.cpp index 2567c666824..cbb1a98b20c 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_FixLineOfSightArgs.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_FixLineOfSightArgs.cpp @@ -33,7 +33,7 @@ namespace vecEnd = vecStart + CVector(0, 0, 0.01f); } } -} // namespace +} // namespace //////////////////////////////////////////////////////////////// // @@ -48,12 +48,15 @@ void _cdecl OnCWorld_ProcessLineOfSight(CVector* pvecStart, CVector* pvecEnd) } // Hook info -#define HOOKPOS_CWorld_ProcessLineOfSight 0x56BA00 -#define HOOKSIZE_CWorld_ProcessLineOfSight 12 -DWORD RETURN_CWorld_ProcessLineOfSight = 0x56BA0C; -void _declspec(naked) HOOK_CWorld_ProcessLineOfSight() +#define HOOKPOS_CWorld_ProcessLineOfSight 0x56BA00 +#define HOOKSIZE_CWorld_ProcessLineOfSight 12 +DWORD RETURN_CWorld_ProcessLineOfSight = 0x56BA0C; +static void __declspec(naked) HOOK_CWorld_ProcessLineOfSight() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*2] @@ -66,6 +69,7 @@ void _declspec(naked) HOOK_CWorld_ProcessLineOfSight() cmp word ptr ds:[0B7CD78h], 0FFFFh jmp RETURN_CWorld_ProcessLineOfSight } + // clang-format on } //////////////////////////////////////////////////////////////// @@ -81,12 +85,15 @@ void _cdecl OnCWorld_GetIsLineOfSightClear(CVector* pvecStart, CVector* pvecEnd) } // Hook info -#define HOOKPOS_CWorld_GetIsLineOfSightClear 0x56A490 -#define HOOKSIZE_CWorld_GetIsLineOfSightClear 12 -DWORD RETURN_CWorld_GetIsLineOfSightClear = 0x56A49C; -void _declspec(naked) HOOK_CWorld_GetIsLineOfSightClear() +#define HOOKPOS_CWorld_GetIsLineOfSightClear 0x56A490 +#define HOOKSIZE_CWorld_GetIsLineOfSightClear 12 +DWORD RETURN_CWorld_GetIsLineOfSightClear = 0x56A49C; +static void __declspec(naked) HOOK_CWorld_GetIsLineOfSightClear() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*2] @@ -99,6 +106,7 @@ void _declspec(naked) HOOK_CWorld_GetIsLineOfSightClear() cmp word ptr ds:[0B7CD78h], 0FFFFh jmp RETURN_CWorld_GetIsLineOfSightClear } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_FixMallocAlign.cpp b/Client/multiplayer_sa/CMultiplayerSA_FixMallocAlign.cpp new file mode 100644 index 00000000000..69a3cdd3bfe --- /dev/null +++ b/Client/multiplayer_sa/CMultiplayerSA_FixMallocAlign.cpp @@ -0,0 +1,439 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: multiplayer_sa/CMultiplayerSA_FixMallocAlign.cpp + * PURPOSE: Reimplement GTA:SA CMemoryMgr with performance and stability fixes + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include + +namespace mta::memory +{ + constexpr std::size_t VIRTUALALLOC_THRESHOLD = 1024 * 1024; + constexpr std::uint32_t VIRTUALALLOC_PADDING = 64; + constexpr std::size_t MAX_ALIGNMENT = 8192; + constexpr std::uint32_t NULL_PAGE_BOUNDARY = 0x10000; + constexpr std::uint32_t MAX_ADDRESS_SPACE = 0xFFFFFFFF; + constexpr std::uint32_t POINTER_SIZE = 4; + constexpr std::uint32_t POINTER_METADATA_OVERHEAD = POINTER_SIZE * 2; + constexpr std::uint32_t METADATA_MAGIC = 0x4D544100; // 'MTA\0' + constexpr std::uint32_t METADATA_MAGIC_MASK = 0xFFFFFFFE; + constexpr std::uint32_t METADATA_FLAG_VIRTUALALLOC = 0x1; + + constexpr bool is_valid_alignment(std::size_t alignment) noexcept + { + return alignment != 0 && (alignment & (alignment - 1)) == 0; + } + + void* SafeMallocAlignVirtual(std::size_t size, std::size_t alignment) noexcept; + + // Aligned malloc - stores pointer at result-4 and metadata at result-8 + [[nodiscard]] void* SafeMallocAlign(std::size_t size, std::size_t alignment) noexcept + { + // Check alignment + if (alignment == 0) + { + errno = EINVAL; + return nullptr; + } + + if (size == 0) + { + size = 1; + } + + if (!is_valid_alignment(alignment) || alignment > MAX_ALIGNMENT) + { + errno = EINVAL; + return nullptr; + } + + // Fast path for small allocations + if (alignment <= 16 && size <= 512) + { + const std::uint32_t size_u32 = static_cast(size); + const std::uint32_t align_u32 = static_cast(alignment); + + // Prevent intermediate overflow + if (align_u32 > UINT32_MAX - POINTER_METADATA_OVERHEAD) + { + errno = ENOMEM; + return nullptr; + } + const std::uint32_t alignment_overhead = align_u32 + POINTER_METADATA_OVERHEAD; + + if (size_u32 > UINT32_MAX - alignment_overhead) + { + errno = ENOMEM; + return nullptr; + } + const std::uint32_t total_size = size_u32 + alignment_overhead; + + void* raw_memory = malloc(total_size); + if (!raw_memory) + { + errno = ENOMEM; + return nullptr; + } + + const std::uint32_t raw_addr = reinterpret_cast(raw_memory); + + if (raw_addr > MAX_ADDRESS_SPACE - POINTER_METADATA_OVERHEAD - align_u32 + 1) + { + free(raw_memory); + errno = ENOMEM; + return nullptr; + } + + const std::uint32_t aligned_addr = (raw_addr + POINTER_METADATA_OVERHEAD + align_u32 - 1) & ~(align_u32 - 1); + + if (aligned_addr < raw_addr + POINTER_METADATA_OVERHEAD || aligned_addr + size_u32 > raw_addr + total_size || + aligned_addr + size_u32 < aligned_addr) + { + free(raw_memory); + errno = EINVAL; + return nullptr; + } + + void* result = reinterpret_cast(aligned_addr); + + // Validate store location + void** store_location = reinterpret_cast(aligned_addr - POINTER_SIZE); + std::uint32_t* metadata_location = reinterpret_cast(aligned_addr - POINTER_METADATA_OVERHEAD); + const std::uint32_t store_addr = reinterpret_cast(store_location); + const std::uint32_t metadata_addr = reinterpret_cast(metadata_location); + + if (store_addr < raw_addr || store_addr > raw_addr + total_size - POINTER_SIZE || metadata_addr < raw_addr || + metadata_addr > raw_addr + total_size - POINTER_SIZE) + { + free(raw_memory); + errno = EFAULT; + return nullptr; + } + + *store_location = raw_memory; + *metadata_location = METADATA_MAGIC; + + return result; + } + + // Use VirtualAlloc for large sizes + if (size > VIRTUALALLOC_THRESHOLD) + { + return SafeMallocAlignVirtual(size, alignment); + } + + if (size > 0xFFFFFFFF || alignment > 0xFFFFFFFF) + { + errno = ENOMEM; + return nullptr; + } + + const std::uint32_t size_u32 = static_cast(size); + const std::uint32_t align_u32 = static_cast(alignment); + + // Prevent intermediate overflow + if (align_u32 > UINT32_MAX - POINTER_METADATA_OVERHEAD) + { + errno = ENOMEM; + return nullptr; + } + const std::uint32_t alignment_overhead = align_u32 + POINTER_METADATA_OVERHEAD; + + if (size_u32 > UINT32_MAX - alignment_overhead) + { + errno = ENOMEM; + return nullptr; + } + const std::uint32_t total_size = size_u32 + alignment_overhead; + + void* raw_memory = malloc(total_size); + if (!raw_memory) + { + errno = ENOMEM; + return nullptr; + } + + const std::uint32_t raw_addr = reinterpret_cast(raw_memory); + + if (raw_addr > MAX_ADDRESS_SPACE - POINTER_METADATA_OVERHEAD - align_u32 + 1) + { + free(raw_memory); + errno = ENOMEM; + return nullptr; + } + + const std::uint32_t aligned_addr = (raw_addr + POINTER_METADATA_OVERHEAD + align_u32 - 1) & ~(align_u32 - 1); + + if (aligned_addr < raw_addr + POINTER_METADATA_OVERHEAD || aligned_addr + size_u32 > raw_addr + total_size || aligned_addr + size_u32 < aligned_addr) + { + free(raw_memory); + errno = EINVAL; + return nullptr; + } + + void* result = reinterpret_cast(aligned_addr); + + void** store_location = reinterpret_cast(aligned_addr - POINTER_SIZE); + std::uint32_t* metadata_location = reinterpret_cast(aligned_addr - POINTER_METADATA_OVERHEAD); + const std::uint32_t store_addr = reinterpret_cast(store_location); + const std::uint32_t metadata_addr = reinterpret_cast(metadata_location); + + if (store_addr < raw_addr || store_addr > raw_addr + total_size - POINTER_SIZE || metadata_addr < raw_addr || + metadata_addr > raw_addr + total_size - POINTER_SIZE) + { + free(raw_memory); + errno = EFAULT; + return nullptr; + } + + *store_location = raw_memory; + *metadata_location = METADATA_MAGIC; + + return result; + } + + // VirtualAlloc path + [[nodiscard]] void* SafeMallocAlignVirtual(std::size_t size, std::size_t alignment) noexcept + { + // Check params + if (alignment == 0 || !is_valid_alignment(alignment) || alignment > MAX_ALIGNMENT) + { + errno = EINVAL; + return nullptr; + } + + if (size == 0) + { + size = 1; + } + + if (size > 0xFFFFFFFF || alignment > 0xFFFFFFFF) + { + errno = ENOMEM; + return nullptr; + } + + const std::uint32_t size_u32 = static_cast(size); + const std::uint32_t align_u32 = static_cast(alignment); + const std::uint32_t padding = (align_u32 <= 64) ? 32 : VIRTUALALLOC_PADDING; + + if (align_u32 > UINT32_MAX - POINTER_METADATA_OVERHEAD) + { + errno = ENOMEM; + return nullptr; + } + const std::uint32_t alignment_overhead = align_u32 + POINTER_METADATA_OVERHEAD; + + if (alignment_overhead > UINT32_MAX - padding) + { + errno = ENOMEM; + return nullptr; + } + if (size_u32 > UINT32_MAX - alignment_overhead - padding) + { + errno = ENOMEM; + return nullptr; + } + + const DWORD total_size = size_u32 + alignment_overhead + padding; + + void* raw_ptr = VirtualAlloc(nullptr, static_cast(total_size), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (!raw_ptr) + { + errno = ENOMEM; + return nullptr; + } + + const std::uint32_t raw_addr = reinterpret_cast(raw_ptr); + + if (raw_addr > MAX_ADDRESS_SPACE - POINTER_METADATA_OVERHEAD - align_u32 + 1) + { + BOOL vfree_result = VirtualFree(raw_ptr, 0, MEM_RELEASE); + (void)vfree_result; + errno = ENOMEM; + return nullptr; + } + + const std::uint32_t aligned_addr = (raw_addr + POINTER_METADATA_OVERHEAD + align_u32 - 1) & ~(align_u32 - 1); + + if (aligned_addr < raw_addr + POINTER_METADATA_OVERHEAD || aligned_addr + size_u32 > raw_addr + total_size || aligned_addr + size_u32 < aligned_addr) + { + BOOL vfree_result = VirtualFree(raw_ptr, 0, MEM_RELEASE); + (void)vfree_result; + errno = EINVAL; + return nullptr; + } + + void* result = reinterpret_cast(aligned_addr); + + // Validate store location + void** store_location = reinterpret_cast(aligned_addr - POINTER_SIZE); + std::uint32_t* metadata_location = reinterpret_cast(aligned_addr - POINTER_METADATA_OVERHEAD); + const std::uint32_t store_addr = reinterpret_cast(store_location); + const std::uint32_t metadata_addr = reinterpret_cast(metadata_location); + + if (store_addr < raw_addr || store_addr > raw_addr + total_size - POINTER_SIZE || metadata_addr < raw_addr || + metadata_addr > raw_addr + total_size - POINTER_SIZE) + { + BOOL vfree_result = VirtualFree(raw_ptr, 0, MEM_RELEASE); + (void)vfree_result; + errno = EFAULT; + return nullptr; + } + + *store_location = raw_ptr; + *metadata_location = METADATA_MAGIC | METADATA_FLAG_VIRTUALALLOC; + + return result; + } + + // Free aligned memory + void SafeFreeAlign(void* ptr) noexcept + { + if (!ptr) + return; + + const std::uint32_t ptr_addr = reinterpret_cast(ptr); + + if (ptr_addr < NULL_PAGE_BOUNDARY) + { + return; + } + + if (ptr_addr < POINTER_METADATA_OVERHEAD) + { + return; + } + + void** read_location = reinterpret_cast(ptr_addr - POINTER_SIZE); + std::uint32_t* metadata_location = reinterpret_cast(ptr_addr - POINTER_METADATA_OVERHEAD); + + // Validate memory readable + MEMORY_BASIC_INFORMATION mbi_read; + SIZE_T mbi_read_result = VirtualQuery(read_location, &mbi_read, sizeof(mbi_read)); + + if (mbi_read_result != sizeof(mbi_read) || mbi_read.State != MEM_COMMIT || mbi_read.Protect == PAGE_NOACCESS || mbi_read.Protect == PAGE_GUARD) + { + return; + } + + const std::uint32_t metadata_addr = reinterpret_cast(metadata_location); + const std::uint32_t base_addr = reinterpret_cast(mbi_read.BaseAddress); + + if (mbi_read.RegionSize == 0 || mbi_read.RegionSize > static_cast(MAX_ADDRESS_SPACE)) + { + return; + } + + const std::uint32_t region_size_u32 = static_cast(mbi_read.RegionSize); + + if (base_addr > MAX_ADDRESS_SPACE - region_size_u32) + { + return; + } + + const std::uint32_t region_end = base_addr + region_size_u32; + + if (region_size_u32 < POINTER_SIZE || metadata_addr < base_addr || metadata_addr > region_end - POINTER_SIZE) + { + return; + } + + void* original_ptr = *read_location; + const std::uint32_t metadata = *metadata_location; + + if ((metadata & METADATA_MAGIC_MASK) != METADATA_MAGIC) + { + return; + } + + if (!original_ptr) + { + return; + } + + const std::uint32_t original_addr = reinterpret_cast(original_ptr); + + if (original_addr >= ptr_addr) + { + return; // Impossible for our allocator + } + + const std::uint32_t distance = ptr_addr - original_addr; + if (distance > MAX_ALIGNMENT + POINTER_METADATA_OVERHEAD) + { + return; // Beyond maximum possible alignment + } + + if (original_addr > ptr_addr - POINTER_SIZE) + { + return; // Violates our storage pattern + } + + if (original_addr >= 0xFFFF0000 || original_addr < NULL_PAGE_BOUNDARY) + { + return; + } + + if ((metadata & METADATA_FLAG_VIRTUALALLOC) != 0) + { + BOOL vfree_result = VirtualFree(original_ptr, 0, MEM_RELEASE); + (void)vfree_result; + return; + } + + free(original_ptr); + } +} // namespace mta::memory + +// Hook constants +#define HOOKPOS_CMemoryMgr_MallocAlign 0x72F4C0 +#define HOOKSIZE_CMemoryMgr_MallocAlign 5 + +#define HOOKPOS_CMemoryMgr_FreeAlign 0x72F4F0 +#define HOOKSIZE_CMemoryMgr_FreeAlign 5 + +// Hook functions + +void* __cdecl HOOK_CMemoryMgr_MallocAlign(int size, int alignment, int nHint) +{ + if (size <= 0 || alignment <= 0) + { + std::size_t safe_size = (size <= 0) ? 1 : static_cast(size); + std::size_t safe_align = (alignment <= 0) ? 4 : static_cast(alignment); + return mta::memory::SafeMallocAlign(safe_size, safe_align); + } + + // Only check maximum (minimum handled above) + if (alignment > static_cast(mta::memory::MAX_ALIGNMENT)) + { + errno = EINVAL; + return nullptr; + } + + if (size > static_cast(0x7FFFFFFF) || alignment > static_cast(0x7FFFFFFF)) + { + errno = EINVAL; + return nullptr; + } + + (void)nHint; + return mta::memory::SafeMallocAlign(static_cast(size), static_cast(alignment)); +} + +void __cdecl HOOK_CMemoryMgr_FreeAlign(void* ptr) +{ + mta::memory::SafeFreeAlign(ptr); +} + +void CMultiplayerSA::InitHooks_FixMallocAlign() +{ + HookInstall(HOOKPOS_CMemoryMgr_MallocAlign, reinterpret_cast(HOOK_CMemoryMgr_MallocAlign), HOOKSIZE_CMemoryMgr_MallocAlign); + HookInstall(HOOKPOS_CMemoryMgr_FreeAlign, reinterpret_cast(HOOK_CMemoryMgr_FreeAlign), HOOKSIZE_CMemoryMgr_FreeAlign); +} diff --git a/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp b/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp index 620d9ba2eaa..f71793cb26b 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp @@ -16,12 +16,16 @@ static unsigned int nLastFrameTime = 0; constexpr float kOriginalTimeStep = 50.0f / 30.0f; // Fixes player movement issue while aiming and walking on high FPS. -#define HOOKPOS_CTaskSimpleUseGun__SetMoveAnim 0x61E4F2 +#define HOOKPOS_CTaskSimpleUseGun__SetMoveAnim 0x61E4F2 #define HOOKSIZE_CTaskSimpleUseGun__SetMoveAnim 0x6 -const unsigned int RETURN_CTaskSimpleUseGun__SetMoveAnim = 0x61E4F8; -void _declspec(naked) HOOK_CTaskSimpleUseGun__SetMoveAnim() +const unsigned int RETURN_CTaskSimpleUseGun__SetMoveAnim = 0x61E4F8; +static void __declspec(naked) HOOK_CTaskSimpleUseGun__SetMoveAnim() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { fld ds:[0xB7CB5C] // CTimer::ms_fTimeStep fdiv kOriginalTimeStep // 1.666f fmul ds:[0x858B1C] // 0.1f @@ -31,15 +35,20 @@ void _declspec(naked) HOOK_CTaskSimpleUseGun__SetMoveAnim() fstp st(0) jmp RETURN_CTaskSimpleUseGun__SetMoveAnim } + // clang-format on } // Fixes excessively fast camera shaking with setCameraShakeLevel on high FPS. -#define HOOKPOS_CCamera__Process 0x52C723 +#define HOOKPOS_CCamera__Process 0x52C723 #define HOOKSIZE_CCamera__Process 0x12 -static const unsigned int RETURN_CCamera__Process = 0x52C735; -static void _declspec(naked) HOOK_CCamera__Process() +static const unsigned int RETURN_CCamera__Process = 0x52C735; +static void __declspec(naked) HOOK_CCamera__Process() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { fld ds:[0x858C80] // 5.0f fmul ds:[0xB7CB5C] // CTimer::ms_fTimeStep fdiv kOriginalTimeStep // 1.666f @@ -47,15 +56,20 @@ static void _declspec(naked) HOOK_CCamera__Process() fstp ds:[0xB6EC30] jmp RETURN_CCamera__Process } + // clang-format on } // Fixes helicopters accelerating excessively during takeoff at high FPS. -#define HOOKPOS_CHeli__ProcessFlyingCarStuff 0x6C4F13 +#define HOOKPOS_CHeli__ProcessFlyingCarStuff 0x6C4F13 #define HOOKSIZE_CHeli__ProcessFlyingCarStuff 0x2A -static const unsigned int RETURN_CHeli__ProcessFlyingCarStuff = 0x6C4F3D; -static void _declspec(naked) HOOK_CHeli__ProcessFlyingCarStuff() +static const unsigned int RETURN_CHeli__ProcessFlyingCarStuff = 0x6C4F3D; +static void __declspec(naked) HOOK_CHeli__ProcessFlyingCarStuff() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { mov ax, [esi+0x22] cmp ax, 465 jz is_rc_heli @@ -74,15 +88,20 @@ static void _declspec(naked) HOOK_CHeli__ProcessFlyingCarStuff() fadd [esi+0x84C] jmp RETURN_CHeli__ProcessFlyingCarStuff } + // clang-format on } // Fixes excessively fast movement of fog on high FPS. -#define HOOKPOS_CClouds__MovingFog_Update 0x716BA6 +#define HOOKPOS_CClouds__MovingFog_Update 0x716BA6 #define HOOKSIZE_CClouds__MovingFog_Update 0x16 -static const unsigned int RETURN_CClouds__MovingFog_Update = 0x716BBC; -static void _declspec(naked) HOOK_CClouds__MovingFog_Update() +static const unsigned int RETURN_CClouds__MovingFog_Update = 0x716BBC; +static void __declspec(naked) HOOK_CClouds__MovingFog_Update() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { fmul [edi*4+0xC6E394] // CClouds::ms_mf.fSpeedFactor fmul ds:[0xB7CB5C] // CTimer::ms_fTimeStep fdiv kOriginalTimeStep // 1.666f @@ -94,15 +113,20 @@ static void _declspec(naked) HOOK_CClouds__MovingFog_Update() fdiv kOriginalTimeStep // 1.666f jmp RETURN_CClouds__MovingFog_Update } + // clang-format on } // Fixes glass shards spinning and moving at excessive speeds on high FPS. -#define HOOKPOS_CFallingGlassPane__Update_A 0x71AABF +#define HOOKPOS_CFallingGlassPane__Update_A 0x71AABF #define HOOKSIZE_CFallingGlassPane__Update_A 0x6 -static const unsigned int RETURN_CFallingGlassPane__Update_A = 0x71AAC5; -static void _declspec(naked) HOOK_CFallingGlassPane__Update_A() +static const unsigned int RETURN_CFallingGlassPane__Update_A = 0x71AAC5; +static void __declspec(naked) HOOK_CFallingGlassPane__Update_A() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { fld [esp+0x28] fmul ds:[0xB7CB5C] // CTimer::ms_fTimeStep fdiv kOriginalTimeStep // 1.666f @@ -117,15 +141,20 @@ static void _declspec(naked) HOOK_CFallingGlassPane__Update_A() fadd [esi] jmp RETURN_CFallingGlassPane__Update_A } + // clang-format on } // Fixes glass shards spinning and moving at excessive speeds on high FPS. -#define HOOKPOS_CFallingGlassPane__Update_B 0x71AAEA +#define HOOKPOS_CFallingGlassPane__Update_B 0x71AAEA #define HOOKSIZE_CFallingGlassPane__Update_B 0x6 -static const unsigned int RETURN_CFallingGlassPane__Update_B = 0x71AAF0; -static void _declspec(naked) HOOK_CFallingGlassPane__Update_B() +static const unsigned int RETURN_CFallingGlassPane__Update_B = 0x71AAF0; +static void __declspec(naked) HOOK_CFallingGlassPane__Update_B() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { fld [eax] fmul ds:[0xB7CB5C] // CTimer::ms_fTimeStep fdiv kOriginalTimeStep // 1.666f @@ -142,15 +171,20 @@ static void _declspec(naked) HOOK_CFallingGlassPane__Update_B() mov [esp+0x2C], ecx jmp RETURN_CFallingGlassPane__Update_B } + // clang-format on } // Fixes glass shards spinning and moving at excessive speeds on high FPS. -#define HOOKPOS_CFallingGlassPane__Update_C 0x71AB29 +#define HOOKPOS_CFallingGlassPane__Update_C 0x71AB29 #define HOOKSIZE_CFallingGlassPane__Update_C 0x6 -static const unsigned int RETURN_CFallingGlassPane__Update_C = 0x71AB2F; -static void _declspec(naked) HOOK_CFallingGlassPane__Update_C() +static const unsigned int RETURN_CFallingGlassPane__Update_C = 0x71AB2F; +static void __declspec(naked) HOOK_CFallingGlassPane__Update_C() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { fld [eax] fmul ds:[0xB7CB5C] // CTimer::ms_fTimeStep fdiv kOriginalTimeStep // 1.666f @@ -167,14 +201,19 @@ static void _declspec(naked) HOOK_CFallingGlassPane__Update_C() mov [esp+0x38], edx jmp RETURN_CFallingGlassPane__Update_C } + // clang-format on } // Ensure that CTimer::CurrentFrame is updated only every 33+ milliseconds. -#define HOOKPOS_CTimer__Update 0x561C5D +#define HOOKPOS_CTimer__Update 0x561C5D #define HOOKSIZE_CTimer__Update 0xE -static void _declspec(naked) HOOK_CTimer__Update() +static void __declspec(naked) HOOK_CTimer__Update() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { add esp, 0x4 mov bWouldBeNewFrame, 0 @@ -194,15 +233,20 @@ static void _declspec(naked) HOOK_CTimer__Update() add esp, 0xC ret } + // clang-format on } // Fixes premature despawning of broken breakable objects on high FPS. -#define HOOKPOS_BreakObject_c__Update 0x59E420 +#define HOOKPOS_BreakObject_c__Update 0x59E420 #define HOOKSIZE_BreakObject_c__Update 0xB -static const unsigned int RETURN_BreakObject_c__Update = 0x59E42B; -static void _declspec(naked) HOOK_BreakObject_c__Update() +static const unsigned int RETURN_BreakObject_c__Update = 0x59E42B; +static void __declspec(naked) HOOK_BreakObject_c__Update() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx edx, bWouldBeNewFrame test edx, edx jz skip @@ -215,16 +259,21 @@ static void _declspec(naked) HOOK_BreakObject_c__Update() skip: jmp RETURN_BreakObject_c__Update } + // clang-format on } // Fixes limited reach of the water cannon on high FPS. #define HOOKPOS_CWaterCannon__Update_OncePerFrame 0x72A29B #define HOOKSIZE_CWaterCannon__Update_OncePerFrame 0x5 -static const unsigned int RETURN_CWaterCannon__Update_OncePerFrame = 0x72A2A0; -static const unsigned int RETURN_CWaterCannon__Update_OncePerFrame_SKIP = 0x72A2BB; -static void _declspec(naked) HOOK_CWaterCannon__Update_OncePerFrame() +static const unsigned int RETURN_CWaterCannon__Update_OncePerFrame = 0x72A2A0; +static const unsigned int RETURN_CWaterCannon__Update_OncePerFrame_SKIP = 0x72A2BB; +static void __declspec(naked) HOOK_CWaterCannon__Update_OncePerFrame() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx eax, bWouldBeNewFrame test eax, eax jz skip @@ -236,16 +285,21 @@ static void _declspec(naked) HOOK_CWaterCannon__Update_OncePerFrame() skip: jmp RETURN_CWaterCannon__Update_OncePerFrame_SKIP } + // clang-format on } // Fixes money animation issues on high FPS. -#define HOOKPOS_CPlayerInfo__Process 0x5700F5 +#define HOOKPOS_CPlayerInfo__Process 0x5700F5 #define HOOKSIZE_CPlayerInfo__Process 0x6 -static const unsigned int RETURN_CPlayerInfo__Process = 0x5700FB; -static const unsigned int RETURN_CPlayerInfo__Process_SKIP = 0x57015B; -static void _declspec(naked) HOOK_CPlayerInfo__Process() +static const unsigned int RETURN_CPlayerInfo__Process = 0x5700FB; +static const unsigned int RETURN_CPlayerInfo__Process_SKIP = 0x57015B; +static void __declspec(naked) HOOK_CPlayerInfo__Process() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx edx, bWouldBeNewFrame test edx, edx jz skip @@ -256,16 +310,21 @@ static void _declspec(naked) HOOK_CPlayerInfo__Process() skip: jmp RETURN_CPlayerInfo__Process_SKIP } + // clang-format on } // Fixes excessive effects spawning from rocket launchers on high FPS. -#define HOOKPOS_CProjectileInfo__Update 0x738C63 +#define HOOKPOS_CProjectileInfo__Update 0x738C63 #define HOOKSIZE_CProjectileInfo__Update 0x5 -static const unsigned int RETURN_CProjectileInfo__Update = 0x738C68; -static const unsigned int RETURN_CProjectileInfo__Update_SKIP = 0x738F22; -static void _declspec(naked) HOOK_CProjectileInfo__Update() +static const unsigned int RETURN_CProjectileInfo__Update = 0x738C68; +static const unsigned int RETURN_CProjectileInfo__Update_SKIP = 0x738F22; +static void __declspec(naked) HOOK_CProjectileInfo__Update() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx edx, bWouldBeNewFrame test edx, edx jz skip @@ -277,15 +336,20 @@ static void _declspec(naked) HOOK_CProjectileInfo__Update() skip: jmp RETURN_CProjectileInfo__Update_SKIP } + // clang-format on } // Fixes excessive surface effects spawning from wheels on high FPS. -#define HOOKPOS_CVehicle__AddWheelDirtAndWater 0x6D2D50 +#define HOOKPOS_CVehicle__AddWheelDirtAndWater 0x6D2D50 #define HOOKSIZE_CVehicle__AddWheelDirtAndWater 0x6 -static const unsigned int RETURN_CVehicle__AddWheelDirtAndWater = 0x6D2D56; -static void _declspec(naked) HOOK_CVehicle__AddWheelDirtAndWater() +static const unsigned int RETURN_CVehicle__AddWheelDirtAndWater = 0x6D2D56; +static void __declspec(naked) HOOK_CVehicle__AddWheelDirtAndWater() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx edx, bWouldBeNewFrame test edx, edx jz skip @@ -298,16 +362,21 @@ static void _declspec(naked) HOOK_CVehicle__AddWheelDirtAndWater() xor eax, eax retn 0x10 } + // clang-format on } // Fixes excessive smoke trail particle spawning from stuntplanes and cropdusters on high FPS. -#define HOOKPOS_CPlane__PreRender 0x6CA937 +#define HOOKPOS_CPlane__PreRender 0x6CA937 #define HOOKSIZE_CPlane__PreRender 0x6 -static const unsigned int RETURN_CPlane__PreRender = 0x6CA93D; -static const unsigned int RETURN_CPlane__PreRender_SKIP = 0x6CAA93; -static void _declspec(naked) HOOK_CPlane__PreRender() +static const unsigned int RETURN_CPlane__PreRender = 0x6CA93D; +static const unsigned int RETURN_CPlane__PreRender_SKIP = 0x6CAA93; +static void __declspec(naked) HOOK_CPlane__PreRender() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx eax, bWouldBeNewFrame test eax, eax jz skip @@ -318,16 +387,21 @@ static void _declspec(naked) HOOK_CPlane__PreRender() skip: jmp RETURN_CPlane__PreRender_SKIP } + // clang-format on } // Fixes increased frequency of water cannon pushing peds on high FPS. -#define HOOKPOS_CWaterCannon__Update_OncePerFrame_PushPedFix 0x72A37B +#define HOOKPOS_CWaterCannon__Update_OncePerFrame_PushPedFix 0x72A37B #define HOOKSIZE_CWaterCannon__Update_OncePerFrame_PushPedFix 0x6 -static const unsigned int RETURN_CWaterCannon__Update_OncePerFrame_PushPedFix = 0x72A381; -static const unsigned int RETURN_CWaterCannon__Update_OncePerFrame_PushPedFix_SKIP = 0x72A38E; -static void _declspec(naked) HOOK_CWaterCannon__Update_OncePerFrame_PushPedFix() +static const unsigned int RETURN_CWaterCannon__Update_OncePerFrame_PushPedFix = 0x72A381; +static const unsigned int RETURN_CWaterCannon__Update_OncePerFrame_PushPedFix_SKIP = 0x72A38E; +static void __declspec(naked) HOOK_CWaterCannon__Update_OncePerFrame_PushPedFix() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx edx, bWouldBeNewFrame test edx, edx jz skip @@ -338,16 +412,21 @@ static void _declspec(naked) HOOK_CWaterCannon__Update_OncePerFrame_PushPedFix() skip: jmp RETURN_CWaterCannon__Update_OncePerFrame_PushPedFix_SKIP } + // clang-format on } // Fixes excessive particle spawning from water cannons on high FPS. -#define HOOKPOS_CWaterCannon__Render_FxFix 0x729437 +#define HOOKPOS_CWaterCannon__Render_FxFix 0x729437 #define HOOKSIZE_CWaterCannon__Render_FxFix 0x5 -static const unsigned int RETURN_CWaterCannon__Render_FxFix = 0x729440; -static const unsigned int RETURN_CWaterCannon__Render_FxFix_SKIP = 0x7294EE; -static void _declspec(naked) HOOK_CWaterCannon__Render_FxFix() +static const unsigned int RETURN_CWaterCannon__Render_FxFix = 0x729440; +static const unsigned int RETURN_CWaterCannon__Render_FxFix_SKIP = 0x7294EE; +static void __declspec(naked) HOOK_CWaterCannon__Render_FxFix() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx edx, bWouldBeNewFrame test edx, edx jz skip @@ -356,16 +435,21 @@ static void _declspec(naked) HOOK_CWaterCannon__Render_FxFix() skip: jmp RETURN_CWaterCannon__Render_FxFix_SKIP } + // clang-format on } // Fixes excessive particle spawning with setPedHeadless on high FPS. -#define HOOKPOS_CPed__PreRenderAfterTest 0x5E7181 +#define HOOKPOS_CPed__PreRenderAfterTest 0x5E7181 #define HOOKSIZE_CPed__PreRenderAfterTest 0x6 -static const unsigned int RETURN_CPed__PreRenderAfterTest = 0x5E7187; -static const unsigned int RETURN_CPed__PreRenderAfterTest_SKIP = 0x5E722D; -static void _declspec(naked) HOOK_CPed__PreRenderAfterTest() +static const unsigned int RETURN_CPed__PreRenderAfterTest = 0x5E7187; +static const unsigned int RETURN_CPed__PreRenderAfterTest_SKIP = 0x5E722D; +static void __declspec(naked) HOOK_CPed__PreRenderAfterTest() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx eax, bWouldBeNewFrame test eax, eax jz skip @@ -376,15 +460,20 @@ static void _declspec(naked) HOOK_CPed__PreRenderAfterTest() skip: jmp RETURN_CPed__PreRenderAfterTest_SKIP } + // clang-format on } // Fixes excessive particle spawning from boats on high FPS. -#define HOOKPOS_cBuoyancy__AddSplashParticles 0x6C34E0 +#define HOOKPOS_cBuoyancy__AddSplashParticles 0x6C34E0 #define HOOKSIZE_cBuoyancy__AddSplashParticles 0x6 -static const unsigned int RETURN_cBuoyancy__AddSplashParticles = 0x6C34E6; -static void _declspec(naked) HOOK_cBuoyancy__AddSplashParticles() +static const unsigned int RETURN_cBuoyancy__AddSplashParticles = 0x6C34E6; +static void __declspec(naked) HOOK_cBuoyancy__AddSplashParticles() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx eax, bWouldBeNewFrame test eax, eax jz skip @@ -395,15 +484,20 @@ static void _declspec(naked) HOOK_cBuoyancy__AddSplashParticles() skip: retn 0x2C } + // clang-format on } // Fixes excessive weather particle spawning on high FPS. -#define HOOKPOS_CWeather__AddRain 0x72AAA8 +#define HOOKPOS_CWeather__AddRain 0x72AAA8 #define HOOKSIZE_CWeather__AddRain 0x6 -static const unsigned int RETURN_CWeather__AddRain = 0x72AAAE; -static void _declspec(naked) HOOK_CWeather__AddRain() +static const unsigned int RETURN_CWeather__AddRain = 0x72AAAE; +static void __declspec(naked) HOOK_CWeather__AddRain() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx eax, bWouldBeNewFrame test eax, eax jz skip @@ -416,16 +510,21 @@ static void _declspec(naked) HOOK_CWeather__AddRain() add esp, 0x84 ret } + // clang-format on } // Fixes excessive damage particle spawning from airplanes on high FPS. -#define HOOKPOS_CPlane__ProcessFlyingCarStuff 0x6CBE4B +#define HOOKPOS_CPlane__ProcessFlyingCarStuff 0x6CBE4B #define HOOKSIZE_CPlane__ProcessFlyingCarStuff 0x6 -static const unsigned int RETURN_CPlane__ProcessFlyingCarStuff = 0x6CBE51; -static const unsigned int RETURN_CPlane__ProcessFlyingCarStuff_SKIP = 0x6CC0D9; -static void _declspec(naked) HOOK_CPlane__ProcessFlyingCarStuff() +static const unsigned int RETURN_CPlane__ProcessFlyingCarStuff = 0x6CBE51; +static const unsigned int RETURN_CPlane__ProcessFlyingCarStuff_SKIP = 0x6CC0D9; +static void __declspec(naked) HOOK_CPlane__ProcessFlyingCarStuff() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx eax, bWouldBeNewFrame test eax, eax jz skip @@ -436,16 +535,21 @@ static void _declspec(naked) HOOK_CPlane__ProcessFlyingCarStuff() skip: jmp RETURN_CPlane__ProcessFlyingCarStuff_SKIP } + // clang-format on } // Fixes excessive spawning of sand and water particles from vehicles on high FPS. -#define HOOKPOS_CAutomobile__UpdateWheelMatrix 0x6AA78A +#define HOOKPOS_CAutomobile__UpdateWheelMatrix 0x6AA78A #define HOOKSIZE_CAutomobile__UpdateWheelMatrix 0x5 -static const unsigned int RETURN_CAutomobile__UpdateWheelMatrix = 0x6AA78F; -static const unsigned int RETURN_CAutomobile__UpdateWheelMatrix_SKIP = 0x6AAAD0; -static void _declspec(naked) HOOK_CAutomobile__UpdateWheelMatrix() +static const unsigned int RETURN_CAutomobile__UpdateWheelMatrix = 0x6AA78F; +static const unsigned int RETURN_CAutomobile__UpdateWheelMatrix_SKIP = 0x6AAAD0; +static void __declspec(naked) HOOK_CAutomobile__UpdateWheelMatrix() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx eax, bWouldBeNewFrame test eax, eax jz skip @@ -456,15 +560,20 @@ static void _declspec(naked) HOOK_CAutomobile__UpdateWheelMatrix() skip: jmp RETURN_CAutomobile__UpdateWheelMatrix_SKIP } + // clang-format on } // Fixes excessive particle spawning from boats on high FPS. -#define HOOKPOS_CVehicle__DoBoatSplashes 0x6DD130 +#define HOOKPOS_CVehicle__DoBoatSplashes 0x6DD130 #define HOOKSIZE_CVehicle__DoBoatSplashes 0x6 -static const unsigned int RETURN_CVehicle__DoBoatSplashes = 0x6DD136; -static void _declspec(naked) HOOK_CVehicle__DoBoatSplashes() +static const unsigned int RETURN_CVehicle__DoBoatSplashes = 0x6DD136; +static void __declspec(naked) HOOK_CVehicle__DoBoatSplashes() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx eax, bWouldBeNewFrame test eax, eax jz skip @@ -475,15 +584,20 @@ static void _declspec(naked) HOOK_CVehicle__DoBoatSplashes() skip: retn 4 } + // clang-format on } // Fixes excessive rain particle spawning on vehicles on high FPS. -#define HOOKPOS_CVehicle__AddWaterSplashParticles 0x6DDF60 +#define HOOKPOS_CVehicle__AddWaterSplashParticles 0x6DDF60 #define HOOKSIZE_CVehicle__AddWaterSplashParticles 0x6 -static const unsigned int RETURN_CVehicle__AddWaterSplashParticles = 0x6DDF66; -static void _declspec(naked) HOOK_CVehicle__AddWaterSplashParticles() +static const unsigned int RETURN_CVehicle__AddWaterSplashParticles = 0x6DDF66; +static void __declspec(naked) HOOK_CVehicle__AddWaterSplashParticles() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx eax, bWouldBeNewFrame test eax, eax jz skip @@ -494,16 +608,21 @@ static void _declspec(naked) HOOK_CVehicle__AddWaterSplashParticles() skip: ret } + // clang-format on } // Fixes excessive particle spawning from airplanes when damaged on high FPS. -#define HOOKPOS_CPlane__ProcessControl 0x6C939A +#define HOOKPOS_CPlane__ProcessControl 0x6C939A #define HOOKSIZE_CPlane__ProcessControl 0x5 -static const unsigned int RETURN_CPlane__ProcessControl = 0x6C939F; -static const unsigned int RETURN_CPlane__ProcessControl_SKIP = 0x6C9463; -static void _declspec(naked) HOOK_CPlane__ProcessControl() +static const unsigned int RETURN_CPlane__ProcessControl = 0x6C939F; +static const unsigned int RETURN_CPlane__ProcessControl_SKIP = 0x6C9463; +static void __declspec(naked) HOOK_CPlane__ProcessControl() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx edx, bWouldBeNewFrame test edx, edx jz skip @@ -515,15 +634,20 @@ static void _declspec(naked) HOOK_CPlane__ProcessControl() skip: jmp RETURN_CPlane__ProcessControl_SKIP } + // clang-format on } // Fixes excessive exhaust particle spawning from vehicles on high FPS. -#define HOOKPOS_CVehicle__AddExhaustParticles 0x6DE240 +#define HOOKPOS_CVehicle__AddExhaustParticles 0x6DE240 #define HOOKSIZE_CVehicle__AddExhaustParticles 0x6 -static const unsigned int RETURN_CVehicle__AddExhaustParticles = 0x6DE246; -static void _declspec(naked) HOOK_CVehicle__AddExhaustParticles() +static const unsigned int RETURN_CVehicle__AddExhaustParticles = 0x6DE246; +static void __declspec(naked) HOOK_CVehicle__AddExhaustParticles() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx edx, bWouldBeNewFrame test edx, edx jz skip @@ -534,16 +658,21 @@ static void _declspec(naked) HOOK_CVehicle__AddExhaustParticles() skip: ret } + // clang-format on } // Fixes excessive particle spawning while swimming on high FPS. -#define HOOKPOS_CTaskSimpleSwim__ProcessEffects 0x68AD3B +#define HOOKPOS_CTaskSimpleSwim__ProcessEffects 0x68AD3B #define HOOKSIZE_CTaskSimpleSwim__ProcessEffects 0x6 -static const unsigned int RETURN_CTaskSimpleSwim__ProcessEffects = 0x68AD41; -static const unsigned int RETURN_CTaskSimpleSwim__ProcessEffects_SKIP = 0x68AFDB; -static void _declspec(naked) HOOK_CTaskSimpleSwim__ProcessEffects() +static const unsigned int RETURN_CTaskSimpleSwim__ProcessEffects = 0x68AD41; +static const unsigned int RETURN_CTaskSimpleSwim__ProcessEffects_SKIP = 0x68AFDB; +static void __declspec(naked) HOOK_CTaskSimpleSwim__ProcessEffects() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx eax, bWouldBeNewFrame test eax, eax jz skip @@ -555,16 +684,21 @@ static void _declspec(naked) HOOK_CTaskSimpleSwim__ProcessEffects() skip: jmp RETURN_CTaskSimpleSwim__ProcessEffects_SKIP } + // clang-format on } // Fixes excessive particle spawning while swimming on high FPS. -#define HOOKPOS_CTaskSimpleSwim__ProcessEffectsBubbleFix 0x68AC31 +#define HOOKPOS_CTaskSimpleSwim__ProcessEffectsBubbleFix 0x68AC31 #define HOOKSIZE_CTaskSimpleSwim__ProcessEffectsBubbleFix 0x7 -static const unsigned int RETURN_CTaskSimpleSwim__ProcessEffectsBubbleFix = 0x68AC38; -static const unsigned int RETURN_CTaskSimpleSwim__ProcessEffectsBubbleFix_SKIP = 0x68AD36; -static void _declspec(naked) HOOK_CTaskSimpleSwim__ProcessEffectsBubbleFix() +static const unsigned int RETURN_CTaskSimpleSwim__ProcessEffectsBubbleFix = 0x68AC38; +static const unsigned int RETURN_CTaskSimpleSwim__ProcessEffectsBubbleFix_SKIP = 0x68AD36; +static void __declspec(naked) HOOK_CTaskSimpleSwim__ProcessEffectsBubbleFix() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { movzx eax, bWouldBeNewFrame test eax, eax jz skip @@ -576,15 +710,19 @@ static void _declspec(naked) HOOK_CTaskSimpleSwim__ProcessEffectsBubbleFix() skip: jmp RETURN_CTaskSimpleSwim__ProcessEffectsBubbleFix_SKIP } + // clang-format on } // Fixes invisible weapon particles (extinguisher, spraycan, flamethrower) at high FPS -#define HOOKPOS_CWeapon_Update 0x73DC3D +#define HOOKPOS_CWeapon_Update 0x73DC3D #define HOOKSIZE_CWeapon_Update 5 static constexpr std::uintptr_t RETURN_CWeapon_Update = 0x073DC42; -static void __declspec(naked) HOOK_CWeapon_Update() +static void __declspec(naked) HOOK_CWeapon_Update() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Temp fix for camera cmp [esi], 0x2B // CWeapon::m_eWeaponType @@ -617,14 +755,19 @@ static void __declspec(naked) HOOK_CWeapon_Update() mov eax, ds:[0xB7CB84] jmp RETURN_CWeapon_Update } + // clang-format on } #define HOOKPOS_CPhysical__ApplyAirResistance 0x544D29 #define HOOKSIZE_CPhysical__ApplyAirResistance 5 -static const unsigned int RETURN_CPhysical__ApplyAirResistance = 0x544D4D; -static void _declspec(naked) HOOK_CPhysical__ApplyAirResistance() +static const unsigned int RETURN_CPhysical__ApplyAirResistance = 0x544D4D; +static void __declspec(naked) HOOK_CPhysical__ApplyAirResistance() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { fld ds:[0x862CD0] // 0.99000001f fld ds:[0xB7CB5C] // CTimer::ms_fTimeStep fdiv kOriginalTimeStep // 1.666f @@ -643,18 +786,24 @@ static void _declspec(naked) HOOK_CPhysical__ApplyAirResistance() fstp [esi+0x58] jmp RETURN_CPhysical__ApplyAirResistance } + // clang-format on } template -static void _declspec(naked) HOOK_VehicleRapidStopFix() +static void __declspec(naked) HOOK_VehicleRapidStopFix() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + static unsigned int RETURN_VehicleRapidStopFix = returnAddress; - _asm { + // clang-format off + __asm + { fld ds:[0xC2B9CC] // mod_HandlingManager.m_fWheelFriction fmul ds:[0xB7CB5C] // CTimer::ms_fTimeStep fdiv kOriginalTimeStep // 1.666f jmp RETURN_VehicleRapidStopFix } + // clang-format on } void CMultiplayerSA::SetRapidVehicleStopFixEnabled(bool enabled) @@ -708,6 +857,12 @@ void CMultiplayerSA::InitHooks_FrameRateFixes() // CVehicle::ProcessBoatControl MemPut(0x6DC23F, &kOriginalTimeStep); + // Fixes climbing over certain objects killing player on high FPS or low game speed. + // GitHub Issue #602 + MemPut(0x6811E9, &kOriginalTimeStep); + MemPut(0x68128A, &kOriginalTimeStep); + MemPut(0x68131B, &kOriginalTimeStep); + // CTimer::m_FrameCounter fixes EZHookInstall(CTimer__Update); diff --git a/Client/multiplayer_sa/CMultiplayerSA_HookDestructors.cpp b/Client/multiplayer_sa/CMultiplayerSA_HookDestructors.cpp index c243db790f0..895729dcd3c 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_HookDestructors.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_HookDestructors.cpp @@ -3,26 +3,36 @@ * PROJECT: Multi Theft Auto v1.0 * LICENSE: See LICENSE in the top level directory * FILE: multiplayer_sa/CMultiplayerSA_HookDestructors.cpp - * PORPOISE: + * PURPOSE: Game destructor hooks and entity lifecycle tracking * * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ #include "StdInc.h" +#include +#include + +extern CGame* pGameInterface; namespace { - CAnimBlendAssocDestructorHandler* m_pCAnimBlendAssocDestructorHandler = nullptr; - GameObjectDestructHandler* pGameObjectDestructHandler = NULL; - GameVehicleDestructHandler* pGameVehicleDestructHandler = NULL; - GamePlayerDestructHandler* pGamePlayerDestructHandler = NULL; - GameProjectileDestructHandler* pGameProjectileDestructHandler = NULL; - GameModelRemoveHandler* pGameModelRemoveHandler = NULL; - GameRunNamedAnimDestructorHandler* pRunNamedAnimDestructorHandler = nullptr; + // Handler pointers for game destructors + CAnimBlendAssocDestructorHandler* m_pCAnimBlendAssocDestructorHandler = nullptr; + GameObjectDestructHandler* pGameObjectDestructHandler = nullptr; + GameVehicleDestructHandler* pGameVehicleDestructHandler = nullptr; + GamePlayerDestructHandler* pGamePlayerDestructHandler = nullptr; + GameProjectileDestructHandler* pGameProjectileDestructHandler = nullptr; + std::atomic pGameModelRemoveHandler{nullptr}; + GameRunNamedAnimDestructorHandler* pRunNamedAnimDestructorHandler = nullptr; + + // Reentrancy protection for CStreamingRemoveModel + static std::atomic g_bStreamingRemoveModelInProgress{false}; + static std::atomic_flag g_streamingRemoveModelLock{}; - #define FUNC_CPtrListSingleLink_Remove 0x0533610 - #define FUNC_CPtrListDoubleLink_Remove 0x05336B0 +#define FUNC_CPtrListSingleLink_Remove 0x0533610 +#define FUNC_CPtrListDoubleLink_Remove 0x05336B0 +#define FUNC_CPhysical_RemoveFromMovingList 0x542860 struct SStreamSectorEntrySingle { @@ -45,20 +55,16 @@ namespace }; CFastHashMap ms_EntitySAInterfaceExtraInfoMap; + std::mutex ms_EntityMapMutex; // Protects ms_EntitySAInterfaceExtraInfoMap - bool HasEntitySAInterfaceExtraInfo(CEntitySAInterface* pEntitySAInterface) { return MapContains(ms_EntitySAInterfaceExtraInfoMap, pEntitySAInterface); } - - SEntitySAInterfaceExtraInfo& GetEntitySAInterfaceExtraInfo(CEntitySAInterface* pEntitySAInterface) + void RemoveEntitySAInterfaceExtraInfo(CEntitySAInterface* pEntitySAInterface) { - return MapGet(ms_EntitySAInterfaceExtraInfoMap, pEntitySAInterface); - } - - void RemoveEntitySAInterfaceExtraInfo(CEntitySAInterface* pEntitySAInterface) { MapRemove(ms_EntitySAInterfaceExtraInfoMap, pEntitySAInterface); } - - // + const std::lock_guard lock(ms_EntityMapMutex); + MapRemove(ms_EntitySAInterfaceExtraInfoMap, pEntitySAInterface); + } // // CPtrListSingleLink contains item // - bool CPtrListSingleLink_Contains(SStreamSectorEntrySingle* pStreamEntry, CEntitySAInterface* pCheckEntity) + [[nodiscard]] bool CPtrListSingleLink_Contains(SStreamSectorEntrySingle* pStreamEntry, CEntitySAInterface* pCheckEntity) noexcept { for (; pStreamEntry; pStreamEntry = pStreamEntry->pNext) if (pStreamEntry->pEntity == pCheckEntity) @@ -72,18 +78,22 @@ namespace void CPtrListSingleLink_Remove(SStreamSectorEntrySingle** ppStreamEntryList, CEntitySAInterface* pCheckEntity) { DWORD dwFunc = FUNC_CPtrListSingleLink_Remove; - _asm + // clang-format off + __asm { + pushfd // Preserve flags (including Direction Flag) mov ecx, ppStreamEntryList push pCheckEntity call dwFunc + popfd // Restore flags } + // clang-format on } // // CPtrListDoubleLink contains item // - bool CPtrListDoubleLink_Contains(SStreamSectorEntryDouble* pStreamEntry, CEntitySAInterface* pCheckEntity) + [[nodiscard]] bool CPtrListDoubleLink_Contains(SStreamSectorEntryDouble* pStreamEntry, CEntitySAInterface* pCheckEntity) noexcept { for (; pStreamEntry; pStreamEntry = pStreamEntry->pNext) if (pStreamEntry->pEntity == pCheckEntity) @@ -97,48 +107,68 @@ namespace void CPtrListDoubleLink_Remove(SStreamSectorEntryDouble** ppStreamEntryList, CEntitySAInterface* pCheckEntity) { DWORD dwFunc = FUNC_CPtrListDoubleLink_Remove; - _asm + // clang-format off + __asm { + pushfd // Preserve flags (including Direction Flag) mov ecx, ppStreamEntryList push pCheckEntity call dwFunc + popfd // Restore flags } + // clang-format on } // // Ensure entity is removed from previously added stream sectors + // NOTE: Called from naked asm hooks - MUST be noexcept to prevent stack corruption // - void RemoveEntityFromStreamSectors(CEntitySAInterface* pEntity, bool bRemoveExtraInfo) + void OnCEntityRemoveFromStreamSectorLists(CEntitySAInterface* pEntity) noexcept { - SEntitySAInterfaceExtraInfo* pInfo = MapFind(ms_EntitySAInterfaceExtraInfoMap, pEntity); - if (!pInfo) - return; - SEntitySAInterfaceExtraInfo& info = *pInfo; - - // Check single link sectors - for (uint i = 0; i < info.AddedSectorSingleList.size(); i++) + try { - if (CPtrListSingleLink_Contains(*info.AddedSectorSingleList[i], pEntity)) + // Copy sector lists while holding lock to prevent dangling pointers + std::vector sectorSingleList; + std::vector sectorDoubleList; + { - CPtrListSingleLink_Remove(info.AddedSectorSingleList[i], pEntity); + const std::lock_guard lock(ms_EntityMapMutex); // Can throw std::system_error + auto* const pInfo = MapFind(ms_EntitySAInterfaceExtraInfoMap, pEntity); + + if (!pInfo) [[unlikely]] + return; + + // Remove map entry FIRST, before moving vectors, to prevent leak if move throws. + // Use std::move for exception safety (move hardly throws). + sectorSingleList = std::move(pInfo->AddedSectorSingleList); // Usually noexcept + sectorDoubleList = std::move(pInfo->AddedSectorDoubleList); // Usually noexcept + + // Now safe to remove - entry has been emptied + MapRemove(ms_EntitySAInterfaceExtraInfoMap, pEntity); } - } - info.AddedSectorSingleList.clear(); - // Check double link sectors - for (uint i = 0; i < info.AddedSectorDoubleList.size(); i++) - { - if (CPtrListDoubleLink_Contains(*info.AddedSectorDoubleList[i], pEntity)) + // Remove from single link sectors (lock released - safe to call game functions) + for (auto* pSectorList : sectorSingleList) { - CPtrListDoubleLink_Remove(info.AddedSectorDoubleList[i], pEntity); + if (CPtrListSingleLink_Contains(*pSectorList, pEntity)) [[likely]] + CPtrListSingleLink_Remove(pSectorList, pEntity); } - } - info.AddedSectorDoubleList.clear(); - if (bRemoveExtraInfo) - RemoveEntitySAInterfaceExtraInfo(pEntity); + // Remove from double link sectors + for (auto* pSectorList : sectorDoubleList) + { + if (CPtrListDoubleLink_Contains(*pSectorList, pEntity)) [[likely]] + CPtrListDoubleLink_Remove(pSectorList, pEntity); + } + } + catch (...) + { + // Called from naked asm hooks - MUST NOT throw or stack is corrupted + // If mutex.lock() or move fails, entity may remain in sector lists (leak in GTA's tracking) + // This is acceptable as entity destructor will eventually clean up + } } -} // namespace +} // namespace //////////////////////////////////////////////////////////////////////////////////////////////// // @@ -150,402 +180,744 @@ void __cdecl CAnimBlendAssoc_destructor(CAnimBlendAssociationSAInterface* pThis) } } -DWORD RETURN_CAnimBlendAssoc_destructor = 0x4CECF6; -void _declspec(naked) HOOK_CAnimBlendAssoc_destructor() +#define HOOKPOS_CAnimBlendAssoc_destructor 0x4CECF0 +static DWORD RETURN_CAnimBlendAssoc_destructor = 0x4CECF6; +static void __declspec(naked) HOOK_CAnimBlendAssoc_destructor() { - _asm - { - push ecx + MTA_VERIFY_HOOK_LOCAL_SIZE; - push ecx + // clang-format off + __asm + { + // Cache this pointer from ECX before pushad + mov eax, ecx + + // Preserve registers and flags + pushad + pushfd + + // Call handler (__cdecl convention) + push eax call CAnimBlendAssoc_destructor - add esp, 0x4 - - pop ecx + add esp, 4 + + // Restore registers and flags + popfd + popad + // Replay original prologue (6 bytes overwritten) push esi mov esi, ecx mov eax, [esi + 10h] jmp RETURN_CAnimBlendAssoc_destructor } + // clang-format on } void _cdecl OnCObjectDestructor(DWORD calledFrom, CObjectSAInterface* pObject) { - // Tell client to check for things going away + if (!pObject) + return; + if (pGameObjectDestructHandler) pGameObjectDestructHandler(pObject); } // Hook info -#define HOOKPOS_CObjectDestructor 0x59F667 -#define HOOKSIZE_CObjectDestructor 6 -DWORD RETURN_CObjectDestructor = 0x59F66D; -void _declspec(naked) HOOK_CObjectDestructor() +#define HOOKPOS_CObjectDestructor 0x59F660 +#define HOOKSIZE_CObjectDestructor 7 +DWORD RETURN_CObjectDestructor = 0x59F667; +static void __declspec(naked) HOOK_CObjectDestructor() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { + // Cache parameters before pushad + mov eax, ecx + mov edx, [esp] + + // Preserve registers and flags pushad - push ecx - push [esp+32+4*1+4*2] + pushfd + + // Call handler (__cdecl convention) + push eax + push edx call OnCObjectDestructor add esp, 4*2 + + // Restore registers and flags + popfd popad - mov eax,dword ptr fs:[00000000h] + // Replay original prologue (7 bytes overwritten) + // SEH frame setup + push 0FFFFFFFFh + push 0x83D228 jmp RETURN_CObjectDestructor } + // clang-format on } -//////////////////////////////////////////////////////////////////////////////////////////////// -// void _cdecl OnVehicleDestructor(DWORD calledFrom, CVehicleSAInterface* pVehicle) { - // Tell client to check for things going away + if (!pVehicle) + return; + if (pGameVehicleDestructHandler) pGameVehicleDestructHandler(pVehicle); } // Hook info -#define HOOKPOS_CVehicleDestructor 0x6E2B40 -#define HOOKSIZE_CVehicleDestructor 7 -DWORD RETURN_CVehicleDestructor = 0x401355; -void _declspec(naked) HOOK_CVehicleDestructor() +#define HOOKPOS_CVehicleDestructor 0x6E2B40 +#define HOOKSIZE_CVehicleDestructor 7 +DWORD RETURN_CVehicleDestructor = + 0x6E2B47; // Avoid SA's anti-disasm obfuscation at 0x401355 (which had been the return address for years), jump directly to real destructor body +static void __declspec(naked) HOOK_CVehicleDestructor() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { + mov eax, ecx + mov edx, [esp] + pushad - push ecx - push [esp+32+4*1] + pushfd + + push eax + push edx call OnVehicleDestructor add esp, 4*2 + + popfd popad - push 0FFFFFFFFh + // Original code at 0x6E2B40: push 0xFFFFFFFF; jmp 0x401355 (obfuscation chunk) + // The obfuscation at 0x401355 pushes TWO values before jumping to 0x6E2B47: + // 1. A garbage value (result of mov+add+xchg) + // 2. The original 0xFFFFFFFF + // We must replicate this stack layout to maintain compatibility + push 0 // Garbage value placeholder (obfusscation result doesn't matter) + push 0FFFFFFFFh // SEH marker jmp RETURN_CVehicleDestructor } + // clang-format on } -//////////////////////////////////////////////////////////////////////////////////////////////// -// void _cdecl OnCPlayerPedDestructor(DWORD calledFrom, CPedSAInterface* pPlayerPed) { - // Tell client to check for things going away + if (!pPlayerPed) + return; + if (pGamePlayerDestructHandler) pGamePlayerDestructHandler(pPlayerPed); } // Hook info -#define HOOKPOS_CPlayerPedDestructor 0x6093B7 -#define HOOKSIZE_CPlayerPedDestructor 6 -DWORD RETURN_CPlayerPedDestructor = 0x6093BD; -void _declspec(naked) HOOK_CPlayerPedDestructor() +#define HOOKPOS_CPlayerPedDestructor 0x6093B0 +#define HOOKSIZE_CPlayerPedDestructor 7 +DWORD RETURN_CPlayerPedDestructor = 0x6093B7; +static void __declspec(naked) HOOK_CPlayerPedDestructor() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { + mov eax, ecx + mov edx, [esp] + pushad - push ecx - push [esp+32+4*1+4*2] + pushfd + + push eax + push edx call OnCPlayerPedDestructor add esp, 4*2 + + popfd popad - mov eax,dword ptr fs:[00000000h] + push 0FFFFFFFFh + push 0x83EC18 jmp RETURN_CPlayerPedDestructor } + // clang-format on } //////////////////////////////////////////////////////////////////////////////////////////////// // void _cdecl OnCProjectileDestructor(DWORD calledFrom, CEntitySAInterface* pProjectile) { - // Tell client to check for things going away + if (!pProjectile) + return; + if (pGameProjectileDestructHandler) pGameProjectileDestructHandler(pProjectile); } // Hook info -#define HOOKPOS_CProjectileDestructor 0x5A40E0 -#define HOOKSIZE_CProjectileDestructor 6 -DWORD RETURN_CProjectileDestructor = 0x5A40E6; -void _declspec(naked) HOOK_CProjectileDestructor() +#define HOOKPOS_CProjectileDestructor 0x5A40E0 +#define HOOKSIZE_CProjectileDestructor 6 +DWORD RETURN_CProjectileDestructor = 0x5A40E6; +static void __declspec(naked) HOOK_CProjectileDestructor() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { + mov eax, ecx + mov edx, [esp] + pushad - push ecx - push [esp+32+4*1] + pushfd + + push eax + push edx call OnCProjectileDestructor add esp, 4*2 + + popfd popad mov dword ptr [ecx], 867030h jmp RETURN_CProjectileDestructor } + // clang-format on } //////////////////////////////////////////////////////////////////////////////////////////////// // -void _cdecl OnCPhysicalDestructor(DWORD calledFrom, CPhysicalSAInterface* pEntity) +void _cdecl OnCPhysicalDestructor(DWORD calledFrom, CPhysicalSAInterface* pEntity) noexcept { - // This should be null + if (!pEntity) + return; + if (pEntity->m_pMovingList) { - AddReportLog(8640, SString("Removing CPhysical type %d from moving list", pEntity->nType)); + // Log the removal (SString can throw, so wrap in try/catch) + try + { + AddReportLog(8640, SString("Removing CPhysical type %d from moving list", pEntity->nType)); + } + catch (...) + { + // Called from naked asm hook - MUST NOT throw or stack is corrupted + // If SString alloc fails, skip logging but continue cleanup + } + + // Always perform the actual removal, even if logging failed DWORD dwFunc = FUNC_CPhysical_RemoveFromMovingList; - _asm + // clang-format off + __asm { mov ecx, pEntity call dwFunc } + // clang-format on } } // Hook info -#define HOOKPOS_CPhysicalDestructor 0x0542457 -#define HOOKSIZE_CPhysicalDestructor 6 -DWORD RETURN_CPhysicalDestructor = 0x054245D; -void _declspec(naked) HOOK_CPhysicalDestructor() +#define HOOKPOS_CPhysicalDestructor 0x542450 +#define HOOKSIZE_CPhysicalDestructor 7 +DWORD RETURN_CPhysicalDestructor = 0x542457; +static void __declspec(naked) HOOK_CPhysicalDestructor() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { + mov eax, ecx + mov edx, [esp] + pushad - push ecx - push [esp+32+4*1+8] + pushfd + + push eax + push edx call OnCPhysicalDestructor add esp, 4*2 + + popfd popad - mov eax,dword ptr fs:[00000000h] + push 0FFFFFFFFh + push 0x83C996 jmp RETURN_CPhysicalDestructor } + // clang-format on } //////////////////////////////////////////////////////////////////////////////////////////////// // void _cdecl OnCEntityDestructor(DWORD calledFrom, CEntitySAInterface* pEntity) { - RemoveEntityFromStreamSectors(pEntity, true); + if (!pEntity) + return; + + OnCEntityRemoveFromStreamSectorLists(pEntity); } // Hook info -#define HOOKPOS_CEntityDestructor 0x535E97 -#define HOOKSIZE_CEntityDestructor 6 -DWORD RETURN_CEntityDestructor = 0x535E9D; -void _declspec(naked) HOOK_CEntityDestructor() +#define HOOKPOS_CEntityDestructor 0x535E97 +#define HOOKSIZE_CEntityDestructor 6 +DWORD RETURN_CEntityDestructor = 0x535E9D; +static void __declspec(naked) HOOK_CEntityDestructor() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { + mov eax, ecx + mov edx, [esp] + pushad - push ecx - push [esp+32+4*1] + pushfd + + push eax + push edx call OnCEntityDestructor add esp, 4*2 + + popfd popad mov eax, dword ptr fs:[00000000h] jmp RETURN_CEntityDestructor } + // clang-format on } -//////////////////////////////////////////////////////////////////////////////////////////////// -// -void cdecl OnCEntityAddMid1(SStreamSectorEntrySingle** ppStreamEntryList, CEntitySAInterface* pEntitySAInterface) +void cdecl OnCEntityAddMid1(SStreamSectorEntrySingle** ppStreamEntryList, CEntitySAInterface* pEntitySAInterface) noexcept { - // ARRAY_LodSectors - SEntitySAInterfaceExtraInfo& info = GetEntitySAInterfaceExtraInfo(pEntitySAInterface); - info.AddedSectorSingleList.push_back(ppStreamEntryList); + if (!ppStreamEntryList || !pEntitySAInterface) [[unlikely]] + return; + + try + { + const std::lock_guard lock(ms_EntityMapMutex); + + // Find or create entry - use find() first to prevent empty entry leak if push_back throws + auto it = ms_EntitySAInterfaceExtraInfoMap.find(pEntitySAInterface); + if (it != ms_EntitySAInterfaceExtraInfoMap.end()) + { + // Entry exists - directly push_back (may throw, but no leak) + it->second.AddedSectorSingleList.push_back(ppStreamEntryList); + } + else + { + // Entry doesn't exist - create with initial value to avoid empty entry leak + SEntitySAInterfaceExtraInfo info; + info.AddedSectorSingleList.push_back(ppStreamEntryList); // May throw - info is local, no leak + ms_EntitySAInterfaceExtraInfoMap[pEntitySAInterface] = std::move(info); // Move assignment (noexcept) + } + } + catch (...) + { + // Called from naked asm hook - MUST NOT throw or stack is corrupted + // Silently ignore allocation failures (no memory leak - exception-safe) + } } // Hook info -#define HOOKPOS_CEntityAddMid1 0x5348FB -#define HOOKSIZE_CEntityAddMid1 5 -#define HOOKCHECK_CEntityAddMid1 0xE8 -DWORD RETURN_CEntityAddMid1 = 0x534900; -void _declspec(naked) HOOK_CEntityAddMid1() +#define HOOKPOS_CEntityAddMid1 0x5348FB +#define HOOKSIZE_CEntityAddMid1 5 +#define HOOKCHECK_CEntityAddMid1 0xE8 +DWORD RETURN_CEntityAddMid1 = 0x534900; +static void __declspec(naked) HOOK_CEntityAddMid1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { + // At hook entry: ECX = list pointer (thiscall this), [esp] = entity pointer (pushed arg) + mov eax, [esp] // Entity pointer from stack arg + mov edx, ecx // List pointer from ECX + pushad - push [esp+32+4*0] - push ecx + pushfd + + // cdecl: push args right-to-left, so arg2 first, arg1 second + // Handler: OnCEntityAddMid1(list, entity) + push eax // arg2: entity + push edx // arg1: list call OnCEntityAddMid1 add esp, 4*2 + + popfd popad - mov eax, 0x5335E0 // CPtrListSingleLink::Add + mov eax, 0x5335E0 call eax jmp RETURN_CEntityAddMid1 } + // clang-format on } //////////////////////////////////////////////////////////////////////////////////////////////// // -void cdecl OnCEntityAddMid2(SStreamSectorEntrySingle** ppStreamEntryList, CEntitySAInterface* pEntitySAInterface) +void cdecl OnCEntityAddMid2(SStreamSectorEntrySingle** ppStreamEntryList, CEntitySAInterface* pEntitySAInterface) noexcept { - // ARRAY_BuildingSectors - SEntitySAInterfaceExtraInfo& info = GetEntitySAInterfaceExtraInfo(pEntitySAInterface); - info.AddedSectorSingleList.push_back(ppStreamEntryList); + if (!ppStreamEntryList || !pEntitySAInterface) [[unlikely]] + return; + + try + { + const std::lock_guard lock(ms_EntityMapMutex); + + // Find or create entry - use find() first to prevent empty entry leak if push_back throws + auto it = ms_EntitySAInterfaceExtraInfoMap.find(pEntitySAInterface); + if (it != ms_EntitySAInterfaceExtraInfoMap.end()) + { + // Entry exists - directly push_back (may throw, but no leak) + it->second.AddedSectorSingleList.push_back(ppStreamEntryList); + } + else + { + // Entry doesn't exist - create with initial value to avoid empty entry leak + SEntitySAInterfaceExtraInfo info; + info.AddedSectorSingleList.push_back(ppStreamEntryList); // May throw - info is local, no leak + ms_EntitySAInterfaceExtraInfoMap[pEntitySAInterface] = std::move(info); // Move assignment (noexcept) + } + } + catch (...) + { + // Called from naked asm hook - MUST NOT throw or stack is corrupted + // Silently ignore allocation failures (no memory leak - exception-safe) + } } // Hook info -#define HOOKPOS_CEntityAddMid2 0x534A10 -#define HOOKSIZE_CEntityAddMid2 5 -#define HOOKCHECK_CEntityAddMid2 0xE8 -DWORD RETURN_CEntityAddMid2 = 0x534A15; -void _declspec(naked) HOOK_CEntityAddMid2() +#define HOOKPOS_CEntityAddMid2 0x534A10 +#define HOOKSIZE_CEntityAddMid2 5 +#define HOOKCHECK_CEntityAddMid2 0xE8 +DWORD RETURN_CEntityAddMid2 = 0x534A15; +static void __declspec(naked) HOOK_CEntityAddMid2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { + // At hook entry: ECX = list pointer (thiscall this), [esp] = entity pointer (pushed arg) + mov eax, [esp] // Entity pointer from stack arg + mov edx, ecx // List pointer from ECX + pushad - push [esp+32+4*0] - push ecx + pushfd + + // cdecl: push args right-to-left, so arg2 first, arg1 second + // Handler: OnCEntityAddMid2(list, entity) + push eax // arg2: entity + push edx // arg1: list call OnCEntityAddMid2 add esp, 4*2 + + popfd popad - mov eax, 0x5335E0 // CPtrListSingleLink::Add + mov eax, 0x5335E0 call eax jmp RETURN_CEntityAddMid2 } + // clang-format on } //////////////////////////////////////////////////////////////////////////////////////////////// // -void cdecl OnCEntityAddMid3(SStreamSectorEntryDouble** ppStreamEntryList, CEntitySAInterface* pEntitySAInterface) +void cdecl OnCEntityAddMid3(SStreamSectorEntryDouble** ppStreamEntryList, CEntitySAInterface* pEntitySAInterface) noexcept { - // ARRAY_VehicleSectors - // ARRAY_PedSectors - // ARRAY_ObjectSectors - // ARRAY_DummySectors - SEntitySAInterfaceExtraInfo& info = GetEntitySAInterfaceExtraInfo(pEntitySAInterface); - info.AddedSectorDoubleList.push_back(ppStreamEntryList); + if (!ppStreamEntryList || !pEntitySAInterface) [[unlikely]] + return; + + try + { + const std::lock_guard lock(ms_EntityMapMutex); + + // Find or create entry - use find() first to prevent empty entry leak if push_back throws + auto it = ms_EntitySAInterfaceExtraInfoMap.find(pEntitySAInterface); + if (it != ms_EntitySAInterfaceExtraInfoMap.end()) + { + // Entry exists - directly push_back (may throw, but no leak) + it->second.AddedSectorDoubleList.push_back(ppStreamEntryList); + } + else + { + // Entry doesn't exist - create with initial value to avoid empty entry leak + SEntitySAInterfaceExtraInfo info; + info.AddedSectorDoubleList.push_back(ppStreamEntryList); // May throw - info is local, no leak + ms_EntitySAInterfaceExtraInfoMap[pEntitySAInterface] = std::move(info); // Move assignment (noexcept) + } + } + catch (...) + { + // Called from naked asm hook - MUST NOT throw or stack is corrupted + // Silently ignore allocation failures (no memory leak - exception-safe) + } } // Hook info -#define HOOKPOS_CEntityAddMid3 0x534AA2 -#define HOOKSIZE_CEntityAddMid3 5 -#define HOOKCHECK_CEntityAddMid3 0xE8 -DWORD RETURN_CEntityAddMid3 = 0x534AA7; -void _declspec(naked) HOOK_CEntityAddMid3() +#define HOOKPOS_CEntityAddMid3 0x534AA2 +#define HOOKSIZE_CEntityAddMid3 5 +#define HOOKCHECK_CEntityAddMid3 0xE8 +DWORD RETURN_CEntityAddMid3 = 0x534AA7; +static void __declspec(naked) HOOK_CEntityAddMid3() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { + // At hook entry: ECX = list pointer (thiscall this), [esp] = entity pointer (pushed arg) + mov eax, [esp] // Entity pointer from stack arg + mov edx, ecx // List pointer from ECX + pushad - push [esp+32+4*0] - push ecx + pushfd + + // cdecl: push args right-to-left, so arg2 first, arg1 second + // Handler: OnCEntityAddMid3(list, entity) + push eax // arg2: entity + push edx // arg1: list call OnCEntityAddMid3 add esp, 4*2 + + popfd popad - mov eax, 0x533670 // CPtrListDoubleLink::Add + mov eax, 0x533670 call eax jmp RETURN_CEntityAddMid3 } + // clang-format on } //////////////////////////////////////////////////////////////////////////////////////////////// // void cdecl OnCEntityRemovePost(CEntitySAInterface* pEntity) { - RemoveEntityFromStreamSectors(pEntity, false); + if (!pEntity) + return; + + OnCEntityRemoveFromStreamSectorLists(pEntity); } // Hook info -#define HOOKPOS_CEntityRemove 0x534AE0 -#define HOOKSIZE_CEntityRemove 5 -#define HOOKCHECK_CEntityRemove 0x83 -DWORD RETURN_CEntityRemove = 0x534AE5; -void _declspec(naked) HOOK_CEntityRemove() +#define HOOKPOS_CEntityRemove 0x534AE0 +#define HOOKSIZE_CEntityRemove 5 +#define HOOKCHECK_CEntityRemove 0x83 +DWORD RETURN_CEntityRemove = 0x534AE5; +static void __declspec(naked) HOOK_CEntityRemove() { - _asm - { - push [esp+4*1] - call inner - add esp, 4*1 + MTA_VERIFY_HOOK_LOCAL_SIZE; + // clang-format off + __asm + { + // Save original ESI (callee-saved) + push esi + + // Get entity pointer from ECX (it's __thiscall!) + mov esi, ecx // Entity is in ECX, not on stack! + + // Inner function expects entity in ECX (not on stack!) + mov ecx, esi // Ensure ECX has entity + call inner + + // Call post-removal handler pushad - push [esp+32+4*1] + pushfd + push esi // Push cached entity call OnCEntityRemovePost add esp, 4*1 + popfd popad - retn + + // Restore original ESI + pop esi + ret inner: - // Original code + // Original code (expects entity in ECX) sub esp, 30h push ebx push ebp jmp RETURN_CEntityRemove } + // clang-format on } -//////////////////////////////////////////////////////////////////////////////////////////////// -// -void _cdecl OnCStreamingRemoveModel(DWORD calledFrom, ushort usModelId) +static void CallGameModelRemoveHandlerSafe(GameModelRemoveHandler* handler, ushort modelId) { - // Tell client to check for things going away - if (pGameModelRemoveHandler) - pGameModelRemoveHandler(usModelId); + __try + { + handler(modelId); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + } +} + +bool _cdecl OnCStreamingRemoveModel(DWORD calledFrom, int modelId) noexcept +{ + if (pGameInterface) + { + StreamingRemoveModelCallback pCallback = pGameInterface->GetStreamingRemoveModelCallback(); + if (pCallback && !pCallback(static_cast(modelId))) + return false; + } + + if (g_bStreamingRemoveModelInProgress.exchange(true, std::memory_order_acquire)) + return true; + + bool bLockAcquired = false; + bool bTimeout = false; + int attemptCount = 0; + + // Acquire spinlock with timeout + constexpr int MAX_SPIN_ATTEMPTS = 50000; // ~50ms on most CPU's + int spinCount = 0; + + while (g_streamingRemoveModelLock.test_and_set(std::memory_order_acquire)) + { + if (++spinCount > MAX_SPIN_ATTEMPTS) + { + bTimeout = true; + attemptCount = spinCount; + break; + } + SwitchToThread(); + } + + if (!bTimeout) + { + bLockAcquired = true; + + // Call handler with exception protection + auto* const handler = pGameModelRemoveHandler.load(std::memory_order_acquire); + if (handler) [[likely]] + { + CallGameModelRemoveHandlerSafe(handler, static_cast(modelId)); + } + + // Release spinlock + g_streamingRemoveModelLock.clear(std::memory_order_release); + } + + // Always release reentrancy flag + g_bStreamingRemoveModelInProgress.store(false, std::memory_order_release); + + // Log timeout (SString can throw, so wrap in try/catch) + if (bTimeout) + { + try + { + AddReportLog(8641, SString("Failed to acquire CStreamingRemoveModel lock after %d attempts (modelId=%d)", attemptCount, modelId)); + } + catch (...) + { + // Called from naked asm hook - MUST NOT throw or stack is corrupted + // If SString allocation fails, skip logging (reentrancy flag already released above) + } + } + + return true; } // Hook info -#define HOOKPOS_CStreamingRemoveModel 0x4089A0 -#define HOOKSIZE_CStreamingRemoveModel 5 -DWORD RETURN_CStreamingRemoveModel = 0x4089A5; -void _declspec(naked) HOOK_CStreamingRemoveModel() +#define HOOKPOS_CStreamingRemoveModel 0x4089A0 +#define HOOKSIZE_CStreamingRemoveModel 6 +DWORD RETURN_CStreamingRemoveModel = 0x4089A6; +static void __declspec(naked) HOOK_CStreamingRemoveModel() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { + mov eax, [esp+4] + mov edx, [esp] + pushad - push [esp+32+4*1] - push [esp+32+4*1] + pushfd + + push eax + push edx call OnCStreamingRemoveModel add esp, 4*2 + mov [esp+32], eax + popfd popad + test al, al + jz skipRemoval push esi mov esi, [esp+8] + push edi jmp RETURN_CStreamingRemoveModel + +skipRemoval: + ret } + // clang-format on } //////////////////////////////////////////////////////////////////////////////////////////////// // void _cdecl OnCTaskSimpleRunNamedAnimDestructor(class CTaskSimpleRunNamedAnimSAInterface* pTask) { + if (!pTask) + return; + if (pRunNamedAnimDestructorHandler) pRunNamedAnimDestructorHandler(pTask); } // Hook info -#define HOOKPOS_CTaskSimpleRunNamedAnimDestructor 0x61BEF0 -#define HOOKSIZE_CTaskSimpleRunNamedAnimDestructor 8 -DWORD RETURN_CTaskSimpleRunNamedAnim = 0x61BEF8; -void _declspec(naked) HOOK_CTaskSimpleRunNamedAnimDestructor() +#define HOOKPOS_CTaskSimpleRunNamedAnimDestructor 0x61BEF0 +#define HOOKSIZE_CTaskSimpleRunNamedAnimDestructor 8 +DWORD RETURN_CTaskSimpleRunNamedAnim = 0x61BEF8; +static void __declspec(naked) HOOK_CTaskSimpleRunNamedAnimDestructor() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { + mov eax, ecx + pushad - push ecx + pushfd + + push eax call OnCTaskSimpleRunNamedAnimDestructor - add esp, 4 * 1 + add esp, 4 + + popfd popad push esi mov esi, ecx - // call the non-virtual destructor - // CTaskSimpleRunNamedAnim::~CTaskSimpleRunNamedAnim() mov eax, 0x61BF10 call eax jmp RETURN_CTaskSimpleRunNamedAnim } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// // -// Set handlers +// Handler setters // ////////////////////////////////////////////////////////////////////////////////////////// void CMultiplayerSA::SetCAnimBlendAssocDestructorHandler(CAnimBlendAssocDestructorHandler* pHandler) @@ -575,7 +947,7 @@ void CMultiplayerSA::SetGameProjectileDestructHandler(GameProjectileDestructHand void CMultiplayerSA::SetGameModelRemoveHandler(GameModelRemoveHandler* pHandler) { - pGameModelRemoveHandler = pHandler; + pGameModelRemoveHandler.store(pHandler, std::memory_order_release); } void CMultiplayerSA::SetGameRunNamedAnimDestructorHandler(GameRunNamedAnimDestructorHandler* pHandler) @@ -585,11 +957,12 @@ void CMultiplayerSA::SetGameRunNamedAnimDestructorHandler(GameRunNamedAnimDestru ////////////////////////////////////////////////////////////////////////////////////////// // -// Setup hooks for HookDestructors +// Setup hooks // ////////////////////////////////////////////////////////////////////////////////////////// void CMultiplayerSA::InitHooks_HookDestructors() { + HookInstall(HOOKPOS_CAnimBlendAssoc_destructor, (DWORD)HOOK_CAnimBlendAssoc_destructor, 6); EZHookInstall(CTaskSimpleRunNamedAnimDestructor); EZHookInstall(CObjectDestructor); EZHookInstall(CVehicleDestructor); @@ -603,3 +976,24 @@ void CMultiplayerSA::InitHooks_HookDestructors() EZHookInstall(CEntityAddMid3); EZHookInstall(CEntityRemove); } + +////////////////////////////////////////////////////////////////////////////////////////// +// +// Cleanup hooks +// +////////////////////////////////////////////////////////////////////////////////////////// +void CMultiplayerSA::CleanupHooks_HookDestructors() +{ + m_pCAnimBlendAssocDestructorHandler = nullptr; + pGameObjectDestructHandler = nullptr; + pGameVehicleDestructHandler = nullptr; + pGamePlayerDestructHandler = nullptr; + pGameProjectileDestructHandler = nullptr; + pGameModelRemoveHandler.store(nullptr, std::memory_order_release); + pRunNamedAnimDestructorHandler = nullptr; + + { + const std::lock_guard lock(ms_EntityMapMutex); + ms_EntitySAInterfaceExtraInfoMap.clear(); + } +} diff --git a/Client/multiplayer_sa/CMultiplayerSA_LicensePlate.cpp b/Client/multiplayer_sa/CMultiplayerSA_LicensePlate.cpp index ae587ec195a..4c62bde3215 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_LicensePlate.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_LicensePlate.cpp @@ -22,7 +22,7 @@ namespace std::vector ms_SavedTextureList; CVehicleModelInfoSAInterface* ms_pProcessingVehicleModelInfo = NULL; RwTexture* ms_pLastGeneratedPlateText = NULL; -} // namespace +} // namespace ////////////////////////////////////////////////////////////////////////////////////////// // @@ -58,12 +58,15 @@ void OnMY_CAutomobile_CustomCarPlate_BeforeRenderingStart(CVehicleSAInterface* p } // Hook info -#define HOOKPOS_CAutomobile_CustomCarPlate_BeforeRenderingStart 0x006A2F00 -#define HOOKSIZE_CAutomobile_CustomCarPlate_BeforeRenderingStart 7 -DWORD RETURN_CAutomobile_CustomCarPlate_BeforeRenderingStart = 0x006A2F07; -void _declspec(naked) HOOK_CAutomobile_CustomCarPlate_BeforeRenderingStart() +#define HOOKPOS_CAutomobile_CustomCarPlate_BeforeRenderingStart 0x006A2F00 +#define HOOKSIZE_CAutomobile_CustomCarPlate_BeforeRenderingStart 7 +DWORD RETURN_CAutomobile_CustomCarPlate_BeforeRenderingStart = 0x006A2F07; +static void __declspec(naked) HOOK_CAutomobile_CustomCarPlate_BeforeRenderingStart() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*1] @@ -76,6 +79,7 @@ void _declspec(naked) HOOK_CAutomobile_CustomCarPlate_BeforeRenderingStart() mov eax, [eax+24h] jmp RETURN_CAutomobile_CustomCarPlate_BeforeRenderingStart } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -113,12 +117,15 @@ void OnMY_CAutomobile_CustomCarPlate_AfterRenderingStop(CVehicleModelInfoSAInter } // Hook info -#define HOOKPOS_CAutomobile_CustomCarPlate_AfterRenderingStop 0x006A2F30 -#define HOOKSIZE_CAutomobile_CustomCarPlate_AfterRenderingStop 7 -DWORD RETURN_CAutomobile_CustomCarPlate_AfterRenderingStop = 0x006A2F37; -void _declspec(naked) HOOK_CAutomobile_CustomCarPlate_AfterRenderingStop() +#define HOOKPOS_CAutomobile_CustomCarPlate_AfterRenderingStop 0x006A2F30 +#define HOOKSIZE_CAutomobile_CustomCarPlate_AfterRenderingStop 7 +DWORD RETURN_CAutomobile_CustomCarPlate_AfterRenderingStop = 0x006A2F37; +static void __declspec(naked) HOOK_CAutomobile_CustomCarPlate_AfterRenderingStop() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*1] @@ -130,6 +137,7 @@ void _declspec(naked) HOOK_CAutomobile_CustomCarPlate_AfterRenderingStop() mov eax, [eax+24h] jmp RETURN_CAutomobile_CustomCarPlate_AfterRenderingStop } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -149,12 +157,15 @@ void OnMY_CCustomCarPlateMgr_SetupMaterialPlateTexture(struct RpMaterial* a, cha } // Hook info -#define HOOKPOS_CCustomCarPlateMgr_SetupMaterialPlateTexture 0x006FE020 -#define HOOKSIZE_CCustomCarPlateMgr_SetupMaterialPlateTexture 5 -DWORD RETURN_CCustomCarPlateMgr_SetupMaterialPlateTexture = 0x006FE025; -void _declspec(naked) HOOK_CCustomCarPlateMgr_SetupMaterialPlateTexture() +#define HOOKPOS_CCustomCarPlateMgr_SetupMaterialPlateTexture 0x006FE020 +#define HOOKSIZE_CCustomCarPlateMgr_SetupMaterialPlateTexture 5 +DWORD RETURN_CCustomCarPlateMgr_SetupMaterialPlateTexture = 0x006FE025; +static void __declspec(naked) HOOK_CCustomCarPlateMgr_SetupMaterialPlateTexture() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*2] @@ -168,6 +179,7 @@ void _declspec(naked) HOOK_CCustomCarPlateMgr_SetupMaterialPlateTexture() mov edi, [esp+8] jmp RETURN_CCustomCarPlateMgr_SetupMaterialPlateTexture } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -193,12 +205,15 @@ void OnMY_CVehicleModelInfo_SetCarCustomPlate_Post() } // Hook info -#define HOOKPOS_CVehicleModelInfo_SetCarCustomPlate 0x004C9450 -#define HOOKSIZE_CVehicleModelInfo_SetCarCustomPlate 6 -DWORD RETURN_CVehicleModelInfo_SetCarCustomPlate = 0x004C9456; -void _declspec(naked) HOOK_CVehicleModelInfo_SetCarCustomPlate() +#define HOOKPOS_CVehicleModelInfo_SetCarCustomPlate 0x004C9450 +#define HOOKSIZE_CVehicleModelInfo_SetCarCustomPlate 6 +DWORD RETURN_CVehicleModelInfo_SetCarCustomPlate = 0x004C9456; +static void __declspec(naked) HOOK_CVehicleModelInfo_SetCarCustomPlate() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push ecx @@ -219,6 +234,7 @@ void _declspec(naked) HOOK_CVehicleModelInfo_SetCarCustomPlate() mov esi, ecx jmp RETURN_CVehicleModelInfo_SetCarCustomPlate } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -229,12 +245,15 @@ void _declspec(naked) HOOK_CVehicleModelInfo_SetCarCustomPlate() // Prevent GTA from generating a new texture for each occurrence of 'carplate' in a model // ////////////////////////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CCustomCarPlateMgr_CreatePlateTexture 0x006FDEA0 -#define HOOKSIZE_CCustomCarPlateMgr_CreatePlateTexture 5 -DWORD RETURN_CCustomCarPlateMgr_CreatePlateTexture = 0x006FDEA5; -void _declspec(naked) HOOK_CCustomCarPlateMgr_CreatePlateTexture() +#define HOOKPOS_CCustomCarPlateMgr_CreatePlateTexture 0x006FDEA0 +#define HOOKSIZE_CCustomCarPlateMgr_CreatePlateTexture 5 +DWORD RETURN_CCustomCarPlateMgr_CreatePlateTexture = 0x006FDEA5; +static void __declspec(naked) HOOK_CCustomCarPlateMgr_CreatePlateTexture() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Skip our code if not processing a VehicleModelInfo cmp ms_pProcessingVehicleModelInfo, 0 @@ -261,6 +280,7 @@ void _declspec(naked) HOOK_CCustomCarPlateMgr_CreatePlateTexture() mov bl, [esp+0x0c] jmp RETURN_CCustomCarPlateMgr_CreatePlateTexture } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_ObjectCollision.cpp b/Client/multiplayer_sa/CMultiplayerSA_ObjectCollision.cpp index aed8fa28690..232305d3905 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_ObjectCollision.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_ObjectCollision.cpp @@ -42,13 +42,16 @@ static void ColStoreRemoveRef(CObjectSAInterface* gameObject) // >>> 0x59F8D1 | 0D 00 00 01 00 | or eax, 10000h // >>> 0x59F8D6 | 89 86 40 01 00 00 | mov [esi+140h], eax // 0x59F8DC | 0F BF 4E 22 | movsx ecx, word ptr [esi+22h] -#define HOOKPOS_CObject_Init 0x59F8BE -#define HOOKSIZE_CObject_Init 30 +#define HOOKPOS_CObject_Init 0x59F8BE +#define HOOKSIZE_CObject_Init 30 static const DWORD CONTINUE_CObject_Init = 0x59F8DC; -static void _declspec(naked) HOOK_CObject_Init() +static void __declspec(naked) HOOK_CObject_Init() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi // CObjectSAInterface* @@ -63,6 +66,7 @@ static void _declspec(naked) HOOK_CObject_Init() jmp CONTINUE_CObject_Init } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -81,13 +85,16 @@ static void _declspec(naked) HOOK_CObject_Init() // >>> 0x59F701 | E8 CA 10 E7 FF | call CColStore::RemoveRef(int) // >>> 0x59F706 | 83 C4 04 | add esp, 4 // 0x59F709 | 8B 3D 9C 44 B7 00 | mov edi, ds:CPools::ms_pObjectPool -#define HOOKPOS_CObject_Destructor 0x59F6EE -#define HOOKSIZE_CObject_Destructor 27 +#define HOOKPOS_CObject_Destructor 0x59F6EE +#define HOOKSIZE_CObject_Destructor 27 static const DWORD CONTINUE_CObject_Destructor = 0x59F709; -static void _declspec(naked) HOOK_CObject_Destructor() +static void __declspec(naked) HOOK_CObject_Destructor() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi // CObjectSAInterface* @@ -96,6 +103,7 @@ static void _declspec(naked) HOOK_CObject_Destructor() popad jmp CONTINUE_CObject_Destructor } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_ObjectLODSystem.cpp b/Client/multiplayer_sa/CMultiplayerSA_ObjectLODSystem.cpp index a4a9521fc22..e3e94d7e694 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_ObjectLODSystem.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_ObjectLODSystem.cpp @@ -18,12 +18,18 @@ //////////////////////////////////////////////// namespace { - // #define ARRAY_ModelInfo 0xA9B0C8 - #define LOW_LOD_DRAW_DISTANCE_SCALE 5 +// #define ARRAY_ModelInfo 0xA9B0C8 +#define LOW_LOD_DRAW_DISTANCE_SCALE 5 - void SetGlobalDrawDistanceScale(float fValue) { MemPut(0x858FD8, 300.f * fValue); } + void SetGlobalDrawDistanceScale(float fValue) + { + MemPut(0x858FD8, 300.f * fValue); + } - float GetDrawDistanceSetting() { return *(float*)0xB6F118; } + float GetDrawDistanceSetting() + { + return *(float*)0xB6F118; + } float CalculateLowLodFadeAlpha(CBaseModelInfoSAInterface* pModelInfo, float fDist) { @@ -40,25 +46,39 @@ namespace float fLodDistanceUnscaled; CBaseModelInfoSAInterface* pModelInfo; } saved = {false, 0.f, NULL}; -} // namespace + + DWORD preResult = 0; + DWORD entityCheckValid = 0; +} // namespace //////////////////////////////////////////////// // // CRenderer_SetupEntityVisibility // //////////////////////////////////////////////// -void OnMY_CRenderer_SetupEntityVisibility_Pre(CEntitySAInterface* pEntity, float& fValue) +// Returns -1 to proceed with the original function, or >= 0 to skip it (value used as result) +int OnMY_CRenderer_SetupEntityVisibility_Pre(CEntitySAInterface* pEntity, float& fValue) { + // Guard against entities whose model info has been deallocated + auto* pModelInfo = ((CBaseModelInfoSAInterface**)ARRAY_ModelInfo)[pEntity->m_nModelIndex]; + if (!pModelInfo) + { + saved.bValid = false; + return 0xFF; // Skip: caller's switch-default ignores the entity + } + if (pEntity->IsLowLodEntity()) { SetGlobalDrawDistanceScale(LOW_LOD_DRAW_DISTANCE_SCALE * 2); - saved.pModelInfo = ((CBaseModelInfoSAInterface**)ARRAY_ModelInfo)[pEntity->m_nModelIndex]; - saved.fLodDistanceUnscaled = saved.pModelInfo->fLodDistanceUnscaled; - saved.pModelInfo->fLodDistanceUnscaled *= LOW_LOD_DRAW_DISTANCE_SCALE / GetDrawDistanceSetting(); + saved.pModelInfo = pModelInfo; + saved.fLodDistanceUnscaled = pModelInfo->fLodDistanceUnscaled; + pModelInfo->fLodDistanceUnscaled *= LOW_LOD_DRAW_DISTANCE_SCALE / GetDrawDistanceSetting(); saved.bValid = true; } else saved.bValid = false; + + return -1; // Proceed with the original function } void OnMY_CRenderer_SetupEntityVisibility_Post(int result, CEntitySAInterface* pEntity, float& fDist) @@ -84,12 +104,15 @@ void OnMY_CRenderer_SetupEntityVisibility_Post(int result, CEntitySAInterface* p } // Hook info -#define HOOKPOS_CRenderer_SetupEntityVisibility 0x554230 -#define HOOKSIZE_CRenderer_SetupEntityVisibility 8 -DWORD RETURN_CRenderer_SetupEntityVisibility = 0x554238; -void _declspec(naked) HOOK_CRenderer_SetupEntityVisibility() +#define HOOKPOS_CRenderer_SetupEntityVisibility 0x554230 +#define HOOKSIZE_CRenderer_SetupEntityVisibility 8 +DWORD RETURN_CRenderer_SetupEntityVisibility = 0x554238; +static void __declspec(naked) HOOK_CRenderer_SetupEntityVisibility() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { //////////////////// pushad @@ -97,7 +120,11 @@ void _declspec(naked) HOOK_CRenderer_SetupEntityVisibility() push [esp+32+4*2] call OnMY_CRenderer_SetupEntityVisibility_Pre add esp, 4*2 + mov preResult, eax popad + mov eax, preResult + cmp eax, 0FFFFFFFFh + jne skip_original // Pre signaled skip - eax already holds the result //////////////////// push [esp+4*2] @@ -106,6 +133,7 @@ void _declspec(naked) HOOK_CRenderer_SetupEntityVisibility() add esp, 4*2 //////////////////// +skip_original: pushad push [esp+32+4*2] push [esp+32+4*2] @@ -122,6 +150,7 @@ void _declspec(naked) HOOK_CRenderer_SetupEntityVisibility() mov esi,dword ptr [esp+1Ch] jmp RETURN_CRenderer_SetupEntityVisibility // 0x554238 } + // clang-format on } //////////////////////////////////////////////// @@ -143,13 +172,16 @@ void OnMY_CWorldScan_ScanWorld_Pre(CVector2D* pVec, int iValue, void(__cdecl* fu } // Hook info -#define HOOKPOS_CWorldScan_ScanWorld 0x55555E -#define HOOKSIZE_CWorldScan_ScanWorld 5 -DWORD RETURN_CWorldScan_ScanWorlda = 0x555563; -DWORD RETURN_CWorldScan_ScanWorldb = 0x72CAE0; -void _declspec(naked) HOOK_CWorldScan_ScanWorld() +#define HOOKPOS_CWorldScan_ScanWorld 0x55555E +#define HOOKSIZE_CWorldScan_ScanWorld 5 +DWORD RETURN_CWorldScan_ScanWorlda = 0x555563; +DWORD RETURN_CWorldScan_ScanWorldb = 0x72CAE0; +static void __declspec(naked) HOOK_CWorldScan_ScanWorld() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { call second jmp RETURN_CWorldScan_ScanWorlda // 555563 @@ -165,6 +197,117 @@ void _declspec(naked) HOOK_CWorldScan_ScanWorld() jmp RETURN_CWorldScan_ScanWorldb // 72CAE0 } + // clang-format on +} + +//////////////////////////////////////////////// +// +// CRenderer_ScanSectorList_EntityCheck +// +// Validates entity pointer before accessing its scan code field. +// The LOD system's 10x expanded scan area can visit sectors containing +// dangling entity pointers (freed but not unlinked from sector lists). +// +//////////////////////////////////////////////// +bool IsEntityAccessible(CEntitySAInterface* pEntity) +{ + if (!pEntity) + return false; + + // GTA SA pool header layout: [B* m_pObjects][BYTE* m_byteMap][int m_nSize] + // tPoolObjectFlags: bEmpty is bit 7 (MSB) of each byte. Zero MSB = occupied. + struct RawPool + { + BYTE* m_pObjects; + BYTE* m_byteMap; + int m_nSize; + }; + + // CRenderer_ScanSectorList visits sector lists that can contain entities from + // all five gameplay pools: buildings, dummies, objects, peds, and vehicles. + // Strides: sizeof(CBuildingSAInterface)=56, sizeof(CEntitySAInterface)=56, + // PoolAllocStride::value=412, + // PoolAllocStride::value=1988, + // PoolAllocStride::value=2584. + static const struct + { + DWORD ppPool; + DWORD stride; + } pools[] = { + {0xb74498, 56}, // *CLASS_CBuildingPool + {0xb744a0, 56}, // *CLASS_CDummyPool + {0xb7449c, 412}, // *CLASS_CObjectPool + {0xb74490, 1988}, // *CLASS_CPedPool + {0xb74494, 2584}, // *CLASS_CVehiclePool + }; + + const BYTE* ent = reinterpret_cast(pEntity); + + for (int i = 0; i < 5; ++i) + { + const RawPool* pPool = *reinterpret_cast(pools[i].ppPool); + if (!pPool || !pPool->m_pObjects || pPool->m_nSize <= 0) + continue; + + if (ent < pPool->m_pObjects) + continue; + + const DWORD stride = pools[i].stride; + const DWORD diff = static_cast(ent - pPool->m_pObjects); + if (diff % stride != 0) + continue; + + const DWORD index = diff / stride; + if (index >= static_cast(pPool->m_nSize)) + continue; + + if ((pPool->m_byteMap[index] & 0x80) == 0) // bEmpty clear (bit 7 = 0) = slot occupied + return true; + } + + return false; +} + +// Hook info +#define HOOKPOS_CRenderer_ScanSectorList_EntityCheck 0x554910 +#define HOOKSIZE_CRenderer_ScanSectorList_EntityCheck 8 +DWORD RETURN_CRenderer_ScanSectorList_EntityCheck = 0x554918; +DWORD LOOPBOTTOM_CRenderer_ScanSectorList_EntityCheck = 0x554AD5; +static void _declspec(naked) HOOK_CRenderer_ScanSectorList_EntityCheck() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + check_entity: + test edi, edi + jz list_done + + mov esi, [edi] // entity = node->data + + pushad + push esi + call IsEntityAccessible + add esp, 4 + mov entityCheckValid, eax + popad + + cmp entityCheckValid, 0 + je skip_entity + + // Valid entity: replicate original 'mov ax, word ptr [CWorld::ms_nCurrentScanCode]' + mov ax, word ptr ds:[0xB7CD78] + jmp RETURN_CRenderer_ScanSectorList_EntityCheck // -> 0x554918 + + skip_entity: + mov edi, [edi+4] // advance to next node + jmp check_entity // retry with next entity + + list_done: + jmp LOOPBOTTOM_CRenderer_ScanSectorList_EntityCheck // -> 0x554AD5 (def_554948: test edi,edi; jnz) + } + // clang-format on } //////////////////////////////////////////////// @@ -185,12 +328,15 @@ int OnMY_CVisibilityPlugins_CalculateFadingAtomicAlpha_Pre(CBaseModelInfoSAInter } // Hook info -#define HOOKPOS_CVisibilityPlugins_CalculateFadingAtomicAlpha 0x732500 -#define HOOKSIZE_CVisibilityPlugins_CalculateFadingAtomicAlpha 5 -DWORD RETURN_CVisibilityPlugins_CalculateFadingAtomicAlpha = 0x732505; -void _declspec(naked) HOOK_CVisibilityPlugins_CalculateFadingAtomicAlpha() +#define HOOKPOS_CVisibilityPlugins_CalculateFadingAtomicAlpha 0x732500 +#define HOOKSIZE_CVisibilityPlugins_CalculateFadingAtomicAlpha 5 +DWORD RETURN_CVisibilityPlugins_CalculateFadingAtomicAlpha = 0x732505; +static void __declspec(naked) HOOK_CVisibilityPlugins_CalculateFadingAtomicAlpha() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*3] @@ -220,6 +366,7 @@ void _declspec(naked) HOOK_CVisibilityPlugins_CalculateFadingAtomicAlpha() mov ecx, [esp+8] jmp RETURN_CVisibilityPlugins_CalculateFadingAtomicAlpha } + // clang-format on } //////////////////////////////////////////////// @@ -239,7 +386,7 @@ void CMultiplayerSA::SetLODSystemEnabled(bool bEnable) // Memory saved here static CBuffer savedMem; SHookInfo hookInfoList[] = {MAKE_HOOK_INFO(CRenderer_SetupEntityVisibility), MAKE_HOOK_INFO(CWorldScan_ScanWorld), - MAKE_HOOK_INFO(CVisibilityPlugins_CalculateFadingAtomicAlpha)}; + MAKE_HOOK_INFO(CRenderer_ScanSectorList_EntityCheck), MAKE_HOOK_INFO(CVisibilityPlugins_CalculateFadingAtomicAlpha)}; // Enable or not? if (bEnable) diff --git a/Client/multiplayer_sa/CMultiplayerSA_ObjectStreamerOptimization.cpp b/Client/multiplayer_sa/CMultiplayerSA_ObjectStreamerOptimization.cpp index 976eefb98b2..cde18d68ab2 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_ObjectStreamerOptimization.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_ObjectStreamerOptimization.cpp @@ -13,86 +13,116 @@ static unsigned int CEntryInfoNodePool_UsedSpaces = 0; static unsigned int CPtrNodeDoubleLinkPool_UsedSpaces = 0; -#define HOOKPOS_CEntryInfoNodePool__New 0x536D6E +#define HOOKPOS_CEntryInfoNodePool__New 0x536D6E #define HOOKSIZE_CEntryInfoNodePool__New 0x5 -static void _declspec(naked) HOOK_CEntryInfoNodePool__New() +static void __declspec(naked) HOOK_CEntryInfoNodePool__New() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { inc CEntryInfoNodePool_UsedSpaces lea eax, [ecx+eax*4] pop esi ret } + // clang-format on } -#define HOOKPOS_CEntryInfoNode__operator_delete 0x536DF1 +#define HOOKPOS_CEntryInfoNode__operator_delete 0x536DF1 #define HOOKSIZE_CEntryInfoNode__operator_delete 0x6 -static const unsigned int RETURN_CEntryInfoNode__operator_delete = 0x536DF7; -static void _declspec(naked) HOOK_CEntryInfoNode__operator_delete() +static const unsigned int RETURN_CEntryInfoNode__operator_delete = 0x536DF7; +static void __declspec(naked) HOOK_CEntryInfoNode__operator_delete() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { dec CEntryInfoNodePool_UsedSpaces lea eax, [ecx+edx] or byte ptr [eax], 0x80 jmp RETURN_CEntryInfoNode__operator_delete } + // clang-format on } -#define HOOKPOS_CEntryInfoList__Flush 0x536E6C +#define HOOKPOS_CEntryInfoList__Flush 0x536E6C #define HOOKSIZE_CEntryInfoList__Flush 0x5 -static const unsigned int RETURN_CEntryInfoList__Flush = 0x536E71; -static void _declspec(naked) HOOK_CEntryInfoList__Flush() +static const unsigned int RETURN_CEntryInfoList__Flush = 0x536E71; +static void __declspec(naked) HOOK_CEntryInfoList__Flush() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { dec CEntryInfoNodePool_UsedSpaces or bl, 0x80 mov [eax], bl jmp RETURN_CEntryInfoList__Flush } + // clang-format on } -#define HOOKPOS_CPtrNodeDoubleLinkPool__New 0x55233E +#define HOOKPOS_CPtrNodeDoubleLinkPool__New 0x55233E #define HOOKSIZE_CPtrNodeDoubleLinkPool__New 0x6 -static void _declspec(naked) HOOK_CPtrNodeDoubleLinkPool__New() +static void __declspec(naked) HOOK_CPtrNodeDoubleLinkPool__New() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { inc CPtrNodeDoubleLinkPool_UsedSpaces lea eax, [ecx+eax*4] pop esi ret } + // clang-format on } -#define HOOKPOS_CPtrNodeDoubleLink__operator_delete 0x5523F0 +#define HOOKPOS_CPtrNodeDoubleLink__operator_delete 0x5523F0 #define HOOKSIZE_CPtrNodeDoubleLink__operator_delete 0x6 -static const unsigned int RETURN_CPtrNodeDoubleLink__operator_delete = 0x5523F6; -static void _declspec(naked) HOOK_CPtrNodeDoubleLink__operator_delete() +static const unsigned int RETURN_CPtrNodeDoubleLink__operator_delete = 0x5523F6; +static void __declspec(naked) HOOK_CPtrNodeDoubleLink__operator_delete() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { dec CPtrNodeDoubleLinkPool_UsedSpaces lea eax, [ecx+edx] or byte ptr [eax], 0x80 jmp RETURN_CPtrNodeDoubleLink__operator_delete } + // clang-format on } -#define HOOKPOS_CPtrListDoubleLink__Flush 0x5524CB +#define HOOKPOS_CPtrListDoubleLink__Flush 0x5524CB #define HOOKSIZE_CPtrListDoubleLink__Flush 0x5 -static const unsigned int RETURN_CPtrListDoubleLink__Flush = 0x5524D0; -static void _declspec(naked) HOOK_CPtrListDoubleLink__Flush() +static const unsigned int RETURN_CPtrListDoubleLink__Flush = 0x5524D0; +static void __declspec(naked) HOOK_CPtrListDoubleLink__Flush() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { dec CPtrNodeDoubleLinkPool_UsedSpaces or bl, 0x80 mov [eax], bl jmp RETURN_CPtrListDoubleLink__Flush } + // clang-format on } void CMultiplayerSA::InitHooks_ObjectStreamerOptimization() diff --git a/Client/multiplayer_sa/CMultiplayerSA_Peds.cpp b/Client/multiplayer_sa/CMultiplayerSA_Peds.cpp index 3ff2a669498..8e022e6eda7 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Peds.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Peds.cpp @@ -29,13 +29,16 @@ static void __cdecl DoFootLanded(CPedSAInterface* pPedSAInterface, short footId, pPedStepHandler(pPedSAInterface, footId == LANDED_PED_LEFT_FOOT ? true : false); } -#define HOOKPOS_CPed_DoFootLanded 0x5E5380 -#define HOOKSIZE_CPed_DoFootLanded 6 +#define HOOKPOS_CPed_DoFootLanded 0x5E5380 +#define HOOKSIZE_CPed_DoFootLanded 6 static const DWORD CONTINUE_CPed_DoFootLanded = 0x5E5386; -void _declspec(naked) HOOK_CPed_DoFootLanded() +static void __declspec(naked) HOOK_CPed_DoFootLanded() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp + 32 + 4] @@ -51,6 +54,7 @@ void _declspec(naked) HOOK_CPed_DoFootLanded() mov esi, ecx jmp CONTINUE_CPed_DoFootLanded } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_Postprocess.cpp b/Client/multiplayer_sa/CMultiplayerSA_Postprocess.cpp index cf1214437a1..2ffcde55a67 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Postprocess.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Postprocess.cpp @@ -10,74 +10,74 @@ #include "StdInc.h" -#define HOOKPOS_GrainEffect_NightModifier 0x704EE8 +#define HOOKPOS_GrainEffect_NightModifier 0x704EE8 #define HOOKPOS_GrainEffect_InfraredModifier 0x704F59 -#define HOOKPOS_GrainEffect_RainModifier 0x705078 -#define HOOKPOS_GrainEffect_OverlayModifier 0x705091 +#define HOOKPOS_GrainEffect_RainModifier 0x705078 +#define HOOKPOS_GrainEffect_OverlayModifier 0x705091 namespace GrainEffect { + static BYTE ucGrainEnabled = FALSE; + static DWORD dwGrainStrength = 1; -static BYTE ucGrainEnabled = FALSE; -static DWORD dwGrainStrength = 1; - -struct MasterModifier -{ - static float fMultiplier; + static BYTE ScaleLevel(BYTE ucLevel, float fMultiplier) + { + const float scaled = static_cast(ucLevel) * fMultiplier; + if (scaled <= 0.0f) + return 0; + if (scaled >= 255.0f) + return 255; + return static_cast(scaled); + } - static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate) + static int ApplyGrainEffect(BYTE ucLevel, BYTE ucUpdate) { - return ((int(__cdecl*)(char, char))0x7037C0)(ucLevel * fMultiplier, ucUpdate); + using GrainApplyEffectFn = int(__cdecl*)(BYTE, BYTE); + const auto pfnApplyEffect = reinterpret_cast(0x7037C0); + return pfnApplyEffect(ucLevel, ucUpdate); } -}; -struct InfraredModifier -{ - static float fMultiplier; + struct MasterModifier + { + static float fMultiplier; + + static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate) { return ApplyGrainEffect(ScaleLevel(ucLevel, fMultiplier), ucUpdate); } + }; - static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate) + struct InfraredModifier { - return MasterModifier::ApplyEffect(ucLevel * fMultiplier, ucUpdate); - } -}; + static float fMultiplier; -struct NightModifier -{ - static float fMultiplier; + static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate) { return MasterModifier::ApplyEffect(ScaleLevel(ucLevel, fMultiplier), ucUpdate); } + }; - static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate) + struct NightModifier { - return MasterModifier::ApplyEffect(ucLevel * fMultiplier, ucUpdate); - } -}; + static float fMultiplier; -struct RainModifier -{ - static float fMultiplier; + static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate) { return MasterModifier::ApplyEffect(ScaleLevel(ucLevel, fMultiplier), ucUpdate); } + }; - static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate) + struct RainModifier { - return MasterModifier::ApplyEffect(ucLevel * fMultiplier, ucUpdate); - } -}; + static float fMultiplier; -struct OverlayModifier -{ - static float fMultiplier; + static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate) { return MasterModifier::ApplyEffect(ScaleLevel(ucLevel, fMultiplier), ucUpdate); } + }; - static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate) + struct OverlayModifier { - return MasterModifier::ApplyEffect(ucLevel * fMultiplier, ucUpdate); - } -}; + static float fMultiplier; -float MasterModifier::fMultiplier = 1.0f; -float InfraredModifier::fMultiplier = 1.0f; -float NightModifier::fMultiplier = 1.0f; -float RainModifier::fMultiplier = 1.0f; -float OverlayModifier::fMultiplier = 1.0f; + static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate) { return MasterModifier::ApplyEffect(ScaleLevel(ucLevel, fMultiplier), ucUpdate); } + }; -} + float MasterModifier::fMultiplier = 1.0f; + float InfraredModifier::fMultiplier = 1.0f; + float NightModifier::fMultiplier = 1.0f; + float RainModifier::fMultiplier = 1.0f; + float OverlayModifier::fMultiplier = 1.0f; +} // namespace GrainEffect void CMultiplayerSA::SetGrainMultiplier(eGrainMultiplierType type, float fMultiplier) { @@ -87,26 +87,27 @@ void CMultiplayerSA::SetGrainMultiplier(eGrainMultiplierType type, float fMultip switch (type) { - case eGrainMultiplierType::MASTER: - MasterModifier::fMultiplier = fMultiplier; - break; - case eGrainMultiplierType::INFRARED: - InfraredModifier::fMultiplier = fMultiplier; - break; - case eGrainMultiplierType::NIGHT: - NightModifier::fMultiplier = fMultiplier; - break; - case eGrainMultiplierType::RAIN: - RainModifier::fMultiplier = fMultiplier; - break; - case eGrainMultiplierType::OVERLAY: - OverlayModifier::fMultiplier = fMultiplier; - break; - case eGrainMultiplierType::ALL: - MasterModifier::fMultiplier = InfraredModifier::fMultiplier = NightModifier::fMultiplier = RainModifier::fMultiplier = OverlayModifier::fMultiplier = fMultiplier; - break; - default: - break; + case eGrainMultiplierType::MASTER: + MasterModifier::fMultiplier = fMultiplier; + break; + case eGrainMultiplierType::INFRARED: + InfraredModifier::fMultiplier = fMultiplier; + break; + case eGrainMultiplierType::NIGHT: + NightModifier::fMultiplier = fMultiplier; + break; + case eGrainMultiplierType::RAIN: + RainModifier::fMultiplier = fMultiplier; + break; + case eGrainMultiplierType::OVERLAY: + OverlayModifier::fMultiplier = fMultiplier; + break; + case eGrainMultiplierType::ALL: + MasterModifier::fMultiplier = InfraredModifier::fMultiplier = NightModifier::fMultiplier = RainModifier::fMultiplier = + OverlayModifier::fMultiplier = fMultiplier; + break; + default: + break; } } @@ -119,7 +120,7 @@ void CMultiplayerSA::SetGrainLevel(BYTE ucLevel) GrainEffect::dwGrainStrength = static_cast(ucLevel); if (bEnable == bOverridden) - return; + return; if (bEnable) { @@ -136,14 +137,8 @@ void CMultiplayerSA::SetGrainLevel(BYTE ucLevel) void CMultiplayerSA::SetNightVisionEnabled(bool bEnabled, bool bNoiseEnabled) { - if (bEnabled) - { - MemPutFast(0xC402B8, 1); - } - else - { - MemPutFast(0xC402B8, 0); - } + MemPutFast(0xC402B8, bEnabled ? 1 : 0); // bool CPostEffects::m_bNightVision + if (bNoiseEnabled) { HookInstallCall(0x704EE8, (DWORD)GrainEffect::NightModifier::ApplyEffect); @@ -156,14 +151,8 @@ void CMultiplayerSA::SetNightVisionEnabled(bool bEnabled, bool bNoiseEnabled) void CMultiplayerSA::SetThermalVisionEnabled(bool bEnabled, bool bNoiseEnabled) { - if (bEnabled) - { - MemPutFast(0xC402B9, 1); - } - else - { - MemPutFast(0xC402B9, 0); - } + MemPutFast(0xC402B9, bEnabled ? 1 : 0); // bool CPostEffects::m_bInfraredVision + if (bNoiseEnabled) { HookInstallCall(0x704F59, (DWORD)GrainEffect::InfraredModifier::ApplyEffect); @@ -176,12 +165,12 @@ void CMultiplayerSA::SetThermalVisionEnabled(bool bEnabled, bool bNoiseEnabled) bool CMultiplayerSA::IsNightVisionEnabled() { - return (*(BYTE*)0xC402B8 == 1); + return (*(BYTE*)0xC402B8 == 1); // bool CPostEffects::m_bNightVision } bool CMultiplayerSA::IsThermalVisionEnabled() { - return (*(BYTE*)0xC402B9 == 1); + return (*(BYTE*)0xC402B9 == 1); // bool CPostEffects::m_bInfraredVision } void CMultiplayerSA::InitHooks_Postprocess() diff --git a/Client/multiplayer_sa/CMultiplayerSA_ProjectileCollisionFix.cpp b/Client/multiplayer_sa/CMultiplayerSA_ProjectileCollisionFix.cpp index a9021221b6d..187269d5302 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_ProjectileCollisionFix.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_ProjectileCollisionFix.cpp @@ -32,26 +32,35 @@ static void InitializeGrenadeColModel() &colModelGrenade.m_data->m_spheres[0], colModelGrenade.m_sphere.m_radius * 0.75f, colModelGrenade.m_sphere.m_center, 56, 0, 255); } -#define HOOKPOS_CTempColModels__Initialise 0x5BB87D +#define HOOKPOS_CTempColModels__Initialise 0x5BB87D #define HOOKSIZE_CTempColModels__Initialise 0x6 -static const unsigned int RETURN_CTempColModels__Initialise = 0x5BB883; -static void _declspec(naked) HOOK_CTempColModels__Initialise() +static const unsigned int RETURN_CTempColModels__Initialise = 0x5BB883; +static void __declspec(naked) HOOK_CTempColModels__Initialise() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { mov ds:[0x968FE4], edx call InitializeGrenadeColModel jmp RETURN_CTempColModels__Initialise } + // clang-format on } -#define HOOKPOS_CFileLoader__LoadWeaponObject 0x5B401E +#define HOOKPOS_CFileLoader__LoadWeaponObject 0x5B401E #define HOOKSIZE_CFileLoader__LoadWeaponObject 0x5 -static const unsigned int RETURN_CFileLoader__LoadWeaponObject = 0x5B4023; -static void _declspec(naked) HOOK_CFileLoader__LoadWeaponObject() +static const unsigned int RETURN_CFileLoader__LoadWeaponObject = 0x5B4023; +static void __declspec(naked) HOOK_CFileLoader__LoadWeaponObject() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { mov eax, [esp+0x8] cmp eax, 342 je grenade @@ -69,6 +78,7 @@ static void _declspec(naked) HOOK_CFileLoader__LoadWeaponObject() push offset colModelGrenade jmp RETURN_CFileLoader__LoadWeaponObject } + // clang-format on } void CMultiplayerSA::InitHooks_ProjectileCollisionFix() diff --git a/Client/multiplayer_sa/CMultiplayerSA_Rendering.cpp b/Client/multiplayer_sa/CMultiplayerSA_Rendering.cpp index 4b014a57ace..e539576c726 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Rendering.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Rendering.cpp @@ -9,14 +9,14 @@ *****************************************************************************/ #include "StdInc.h" -extern CCoreInterface* g_pCore; -GameEntityRenderHandler* pGameEntityRenderHandler = nullptr; -PreRenderSkyHandler* pPreRenderSkyHandlerHandler = nullptr; -RenderHeliLightHandler* pRenderHeliLightHandler = nullptr; -RenderEverythingBarRoadsHandler* pRenderEverythingBarRoadsHandler = nullptr; +extern CCoreInterface* g_pCore; +GameEntityRenderHandler* pGameEntityRenderHandler = nullptr; +PreRenderSkyHandler* pPreRenderSkyHandlerHandler = nullptr; +RenderHeliLightHandler* pRenderHeliLightHandler = nullptr; +RenderEverythingBarRoadsHandler* pRenderEverythingBarRoadsHandler = nullptr; -#define VAR_CCullZones_NumMirrorAttributeZones 0x0C87AC4 // int -#define VAR_CMirrors_d3dRestored 0x0C7C729 // uchar +#define VAR_CCullZones_NumMirrorAttributeZones 0x0C87AC4 // int +#define VAR_CMirrors_d3dRestored 0x0C7C729 // uchar namespace { @@ -24,7 +24,7 @@ namespace CEntitySAInterface* ms_RenderingOneNonRoad = NULL; bool ms_bIsMinimizedAndNotConnected = false; int ms_iSavedNumMirrorZones = 0; -} // namespace +} // namespace ////////////////////////////////////////////////////////////////////////////////////////// // @@ -44,13 +44,16 @@ void OnMY_CallIdle_Post(RwGeometry* pGeometry, DWORD calledFrom) } // Hook info -#define HOOKPOS_CallIdle 0x53ECBD -#define HOOKSIZE_CallIdle 5 -DWORD RETURN_CallIdle = 0x53ECC2; -DWORD DO_CallIdle = 0x53E920; -void _declspec(naked) HOOK_CallIdle() +#define HOOKPOS_CallIdle 0x53ECBD +#define HOOKSIZE_CallIdle 5 +DWORD RETURN_CallIdle = 0x53ECC2; +DWORD DO_CallIdle = 0x53E920; +static void __declspec(naked) HOOK_CallIdle() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad call OnMY_CallIdle_Pre @@ -66,6 +69,7 @@ void _declspec(naked) HOOK_CallIdle() jmp RETURN_CallIdle } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -106,17 +110,20 @@ void OnMY_CEntity_Render_Post() if (ms_Rendering) { ms_Rendering = NULL; - CallGameEntityRenderHandler(ms_RenderingOneNonRoad); // restore value set in RenderOneNonRoad + CallGameEntityRenderHandler(ms_RenderingOneNonRoad); // restore value set in RenderOneNonRoad } } // Hook info -#define HOOKPOS_CEntity_Render 0x534310 -#define HOOKSIZE_CEntity_Render 6 -DWORD RETURN_CEntity_Render = 0x534317; -void _declspec(naked) HOOK_CEntity_Render() +#define HOOKPOS_CEntity_Render 0x534310 +#define HOOKSIZE_CEntity_Render 6 +DWORD RETURN_CEntity_Render = 0x534317; +static void __declspec(naked) HOOK_CEntity_Render() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push ecx @@ -138,6 +145,7 @@ void _declspec(naked) HOOK_CEntity_Render() mov eax,dword ptr [esi+18h] jmp RETURN_CEntity_Render } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -164,12 +172,15 @@ void OnMY_CEntity_RenderOneNonRoad_Post(CEntitySAInterface* pEntity) } // Hook info -#define HOOKPOS_CEntity_RenderOneNonRoad 0x553260 -#define HOOKSIZE_CEntity_RenderOneNonRoad 5 -DWORD RETURN_CEntity_RenderOneNonRoad = 0x553265; -void _declspec(naked) HOOK_CEntity_RenderOneNonRoad() +#define HOOKPOS_CEntity_RenderOneNonRoad 0x553260 +#define HOOKSIZE_CEntity_RenderOneNonRoad 5 +DWORD RETURN_CEntity_RenderOneNonRoad = 0x553265; +static void __declspec(naked) HOOK_CEntity_RenderOneNonRoad() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*1] @@ -196,6 +207,7 @@ void _declspec(naked) HOOK_CEntity_RenderOneNonRoad() mov esi, [esp+08h] jmp RETURN_CEntity_RenderOneNonRoad } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -211,12 +223,15 @@ void OnMY_CVisibilityPlugins_RenderWeaponPedsForPC_Mid(CPedSAInterface* pEntity) } // Hook info -#define HOOKPOS_CVisibilityPlugins_RenderWeaponPedsForPC_Mid 0x733080 -#define HOOKSIZE_CVisibilityPlugins_RenderWeaponPedsForPC_Mid 6 -DWORD RETURN_CVisibilityPlugins_RenderWeaponPedsForPC_Mid = 0x733086; -void _declspec(naked) HOOK_CVisibilityPlugins_RenderWeaponPedsForPC_Mid() +#define HOOKPOS_CVisibilityPlugins_RenderWeaponPedsForPC_Mid 0x733080 +#define HOOKSIZE_CVisibilityPlugins_RenderWeaponPedsForPC_Mid 6 +DWORD RETURN_CVisibilityPlugins_RenderWeaponPedsForPC_Mid = 0x733086; +static void __declspec(naked) HOOK_CVisibilityPlugins_RenderWeaponPedsForPC_Mid() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push ebx @@ -228,6 +243,7 @@ void _declspec(naked) HOOK_CVisibilityPlugins_RenderWeaponPedsForPC_Mid() mov ecx,dword ptr [ebx+4F4h] jmp RETURN_CVisibilityPlugins_RenderWeaponPedsForPC_Mid } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -243,11 +259,14 @@ void OnMY_CVisibilityPlugins_RenderWeaponPedsForPC_End() } // Hook info -#define HOOKPOS_CVisibilityPlugins_RenderWeaponPedsForPC_End 0x73314D -#define HOOKSIZE_CVisibilityPlugins_RenderWeaponPedsForPC_End 5 -void _declspec(naked) HOOK_CVisibilityPlugins_RenderWeaponPedsForPC_End() +#define HOOKPOS_CVisibilityPlugins_RenderWeaponPedsForPC_End 0x73314D +#define HOOKSIZE_CVisibilityPlugins_RenderWeaponPedsForPC_End 5 +static void __declspec(naked) HOOK_CVisibilityPlugins_RenderWeaponPedsForPC_End() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad call OnMY_CVisibilityPlugins_RenderWeaponPedsForPC_End @@ -258,6 +277,7 @@ void _declspec(naked) HOOK_CVisibilityPlugins_RenderWeaponPedsForPC_End() add esp,0Ch ret } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -268,12 +288,15 @@ void _declspec(naked) HOOK_CVisibilityPlugins_RenderWeaponPedsForPC_End() // ////////////////////////////////////////////////////////////////////////////////////////// // Hook info -#define HOOKPOS_Check_NoOfVisibleLods 0x5534F9 -#define HOOKSIZE_Check_NoOfVisibleLods 6 -DWORD RETURN_Check_NoOfVisibleLods = 0x5534FF; -void _declspec(naked) HOOK_Check_NoOfVisibleLods() +#define HOOKPOS_Check_NoOfVisibleLods 0x5534F9 +#define HOOKSIZE_Check_NoOfVisibleLods 6 +DWORD RETURN_Check_NoOfVisibleLods = 0x5534FF; +static void __declspec(naked) HOOK_Check_NoOfVisibleLods() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { cmp eax, 999 // Array limit is 1000 jge limit @@ -282,6 +305,7 @@ void _declspec(naked) HOOK_Check_NoOfVisibleLods() mov dword ptr ds:[00B76840h],eax // NoOfVisibleLods jmp RETURN_Check_NoOfVisibleLods } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -292,12 +316,15 @@ void _declspec(naked) HOOK_Check_NoOfVisibleLods() // ////////////////////////////////////////////////////////////////////////////////////////// // Hook info -#define HOOKPOS_Check_NoOfVisibleEntities 0x55352D -#define HOOKSIZE_Check_NoOfVisibleEntities 6 -DWORD RETURN_Check_NoOfVisibleEntities = 0x553533; -void _declspec(naked) HOOK_Check_NoOfVisibleEntities() +#define HOOKPOS_Check_NoOfVisibleEntities 0x55352D +#define HOOKSIZE_Check_NoOfVisibleEntities 6 +DWORD RETURN_Check_NoOfVisibleEntities = 0x553533; +static void __declspec(naked) HOOK_Check_NoOfVisibleEntities() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { cmp eax, 999 // Array limit is 1000 jge limit @@ -306,6 +333,7 @@ void _declspec(naked) HOOK_Check_NoOfVisibleEntities() mov dword ptr ds:[00B76844h],eax // NoOfVisibleEntities jmp RETURN_Check_NoOfVisibleEntities } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -320,12 +348,15 @@ void OnMY_WinLoop() } // Hook info -#define HOOKPOS_WinLoop 0x748A93 -#define HOOKSIZE_WinLoop 5 -DWORD RETURN_WinLoop = 0x748A98; -void _declspec(naked) HOOK_WinLoop() +#define HOOKPOS_WinLoop 0x748A93 +#define HOOKSIZE_WinLoop 5 +DWORD RETURN_WinLoop = 0x748A98; +static void __declspec(naked) HOOK_WinLoop() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad call OnMY_WinLoop @@ -334,6 +365,7 @@ void _declspec(naked) HOOK_WinLoop() mov eax, ds:0x0C8D4C0 jmp RETURN_WinLoop } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -343,24 +375,91 @@ void _declspec(naked) HOOK_WinLoop() // Just before GTA calculates frame time deltas // ////////////////////////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CTimer_Update 0x561B10 -#define HOOKSIZE_CTimer_Update 6 -static const DWORD CONTINUE_CTimer_Update = 0x561B16; -static void _declspec(naked) HOOK_CTimer_Update() +#define HOOKPOS_CTimer_Update 0x561B10 +#define HOOKSIZE_CTimer_Update 6 +static const DWORD CONTINUE_CTimer_Update = 0x561B16; +static void __declspec(naked) HOOK_CTimer_Update() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on g_pCore->OnGameTimerUpdate(); - _asm + // clang-format off + __asm { popad - mov ecx,dword ptr ds:[0B7CB28h] + // Original code: mov ecx, ds:_timerFunction + // GTA has its own NULL check at 0x561B19, so we just execute the original instruction + mov ecx, dword ptr ds:[0B7CB28h] jmp CONTINUE_CTimer_Update } + // clang-format on +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// CTimer::Suspend / CTimer::Resume +// +// Prevent crashes if _timerFunction is NULL during init +// +////////////////////////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CTimer_Suspend 0x5619E9 +#define HOOKSIZE_CTimer_Suspend 6 +static const DWORD CONTINUE_CTimer_Suspend = 0x5619EF; +static void _declspec(naked) HOOK_CTimer_Suspend() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + _asm + { + // Check if _timerFunction is NULL + mov eax, dword ptr ds:[0B7CB28h] + test eax, eax + jz skip_suspend + + // Original code: call [_timerFunction] + call eax + jmp CONTINUE_CTimer_Suspend + + skip_suspend: + // If NULL, return zero timestamp (EAX:EDX = 0) to avoid corrupting pause time + xor eax, eax + xor edx, edx + jmp CONTINUE_CTimer_Suspend + } +} + +#define HOOKPOS_CTimer_Resume 0x561A11 +#define HOOKSIZE_CTimer_Resume 6 +static const DWORD CONTINUE_CTimer_Resume = 0x561A17; +static void _declspec(naked) HOOK_CTimer_Resume() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + _asm + { + // Check if _timerFunction is NULL + mov eax, dword ptr ds:[0B7CB28h] + test eax, eax + jz skip_resume + + // Original code: call [_timerFunction] + call eax + jmp CONTINUE_CTimer_Resume + + skip_resume: + // If NULL, return zero timestamp (EAX:EDX = 0) to avoid corrupting resume time calculations + xor eax, eax + xor edx, edx + jmp CONTINUE_CTimer_Resume + } } ////////////////////////////////////////////////////////////////////////////////////////// @@ -397,13 +496,16 @@ bool OnMY_psGrabScreen_ShouldUseRect() } // Hook info -#define HOOKPOS_psGrabScreen 0x7452FC -#define HOOKSIZE_psGrabScreen 5 -DWORD RETURN_psGrabScreen_YesChange = 0x745311; -DWORD RETURN_psGrabScreen_NoChange = 0x745336; -void _declspec(naked) HOOK_psGrabScreen() +#define HOOKPOS_psGrabScreen 0x7452FC +#define HOOKSIZE_psGrabScreen 5 +DWORD RETURN_psGrabScreen_YesChange = 0x745311; +DWORD RETURN_psGrabScreen_NoChange = 0x745336; +static void __declspec(naked) HOOK_psGrabScreen() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad call OnMY_psGrabScreen_ShouldUseRect @@ -425,6 +527,7 @@ void _declspec(naked) HOOK_psGrabScreen() jmp RETURN_psGrabScreen_YesChange } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -441,13 +544,16 @@ void OnMY_CClouds_RenderSkyPolys() } // Hook info -#define HOOKCHECK_CClouds_RenderSkyPolys 0xA1 -#define HOOKPOS_CClouds_RenderSkyPolys 0x714650 -#define HOOKSIZE_CClouds_RenderSkyPolys 5 -DWORD RETURN_CClouds_RenderSkyPolys = 0x714655; -void _declspec(naked) HOOK_CClouds_RenderSkyPolys() +#define HOOKCHECK_CClouds_RenderSkyPolys 0xA1 +#define HOOKPOS_CClouds_RenderSkyPolys 0x714650 +#define HOOKSIZE_CClouds_RenderSkyPolys 5 +DWORD RETURN_CClouds_RenderSkyPolys = 0x714655; +static void __declspec(naked) HOOK_CClouds_RenderSkyPolys() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad call OnMY_CClouds_RenderSkyPolys @@ -456,6 +562,7 @@ void _declspec(naked) HOOK_CClouds_RenderSkyPolys() mov eax, ds:0x0B6F03C jmp RETURN_CClouds_RenderSkyPolys } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -496,13 +603,16 @@ float OnMY_RwCameraSetNearClipPlane(DWORD dwCalledFrom, void* pUnknown, float fD } // Hook info -#define HOOKCHECK_RwCameraSetNearClipPlane 0xD9 -#define HOOKPOS_RwCameraSetNearClipPlane 0x7EE1D0 -#define HOOKSIZE_RwCameraSetNearClipPlane 5 -DWORD RETURN_RwCameraSetNearClipPlane = 0x7EE1D5; -void _declspec(naked) HOOK_RwCameraSetNearClipPlane() +#define HOOKCHECK_RwCameraSetNearClipPlane 0xD9 +#define HOOKPOS_RwCameraSetNearClipPlane 0x7EE1D0 +#define HOOKSIZE_RwCameraSetNearClipPlane 5 +DWORD RETURN_RwCameraSetNearClipPlane = 0x7EE1D5; +static void __declspec(naked) HOOK_RwCameraSetNearClipPlane() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*2] @@ -517,6 +627,7 @@ void _declspec(naked) HOOK_RwCameraSetNearClipPlane() push esi jmp RETURN_RwCameraSetNearClipPlane } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -528,25 +639,31 @@ void _declspec(naked) HOOK_RwCameraSetNearClipPlane() // ////////////////////////////////////////////////////////////////////////////////////////// // Hook info -#define HOOKPOS_RenderEffects_HeliLight 0x53E1B9 -#define HOOKSIZE_RenderEffects_HeliLight 5 -DWORD RETURN_RenderEffects_HeliLight = 0x53E1BE; -void _declspec(naked) HOOK_RenderEffects_HeliLight() +#define HOOKPOS_RenderEffects_HeliLight 0x53E1B9 +#define HOOKSIZE_RenderEffects_HeliLight 5 +DWORD RETURN_RenderEffects_HeliLight = 0x53E1BE; +static void __declspec(naked) HOOK_RenderEffects_HeliLight() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on // Call render handler if (pRenderHeliLightHandler) pRenderHeliLightHandler(); - _asm + // clang-format off + __asm { popad mov eax, ds:[0xC1C96C] jmp RETURN_RenderEffects_HeliLight } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -650,34 +767,29 @@ bool IsMatrixValid(RwMatrix* pMatrix) constexpr float maxValue = 100000.0; constexpr float minValue = -100000.0; - return - pMatrix->at.x >= minValue && pMatrix->at.x <= maxValue - && pMatrix->at.y >= minValue && pMatrix->at.y <= maxValue - && pMatrix->at.z >= minValue && pMatrix->at.y <= maxValue + return pMatrix->at.x >= minValue && pMatrix->at.x <= maxValue && pMatrix->at.y >= minValue && pMatrix->at.y <= maxValue && pMatrix->at.z >= minValue && + pMatrix->at.y <= maxValue - && pMatrix->right.x >= minValue && pMatrix->right.x <= maxValue - && pMatrix->right.y >= minValue && pMatrix->right.y <= maxValue - && pMatrix->right.z >= minValue && pMatrix->right.y <= maxValue + && pMatrix->right.x >= minValue && pMatrix->right.x <= maxValue && pMatrix->right.y >= minValue && pMatrix->right.y <= maxValue && + pMatrix->right.z >= minValue && pMatrix->right.y <= maxValue - && pMatrix->up.x >= minValue && pMatrix->up.x <= maxValue - && pMatrix->up.y >= minValue && pMatrix->up.y <= maxValue - && pMatrix->up.z >= minValue && pMatrix->up.y <= maxValue + && pMatrix->up.x >= minValue && pMatrix->up.x <= maxValue && pMatrix->up.y >= minValue && pMatrix->up.y <= maxValue && pMatrix->up.z >= minValue && + pMatrix->up.y <= maxValue - && pMatrix->pos.x >= minValue && pMatrix->pos.x <= maxValue - && pMatrix->pos.y >= minValue && pMatrix->pos.y <= maxValue - && pMatrix->pos.z >= minValue && pMatrix->pos.y <= maxValue; + && pMatrix->pos.x >= minValue && pMatrix->pos.x <= maxValue && pMatrix->pos.y >= minValue && pMatrix->pos.y <= maxValue && + pMatrix->pos.z >= minValue && pMatrix->pos.y <= maxValue; } bool AreMatricesOfRpAtomicValid(RpAtomic* pAtomic) { - uint32 atomicSkinOffset = *(uint32*)0xC978A4; + uint32 atomicSkinOffset = *(uint32*)0xC978A4; RpHAnimHierarchy* pSkinPluginData = *(RpHAnimHierarchy**)((char*)pAtomic + atomicSkinOffset); if (!pSkinPluginData) return true; unsigned __int32 count = pSkinPluginData->numNodes; - RwMatrix* pMatrixArray = pSkinPluginData->pMatrixArray; + RwMatrix* pMatrixArray = pSkinPluginData->pMatrixArray; for (unsigned int i = 0; i < count; i++) { @@ -688,11 +800,14 @@ bool AreMatricesOfRpAtomicValid(RpAtomic* pAtomic) return true; } -#define HOOKPOS_CVisibilityPlugins_RenderPedCB 0x7335B0 -#define HOOKSIZE_CVisibilityPlugins_RenderPedCB 5 -void _declspec(naked) HOOK_CVisibilityPlugins_RenderPedCB() +#define HOOKPOS_CVisibilityPlugins_RenderPedCB 0x7335B0 +#define HOOKSIZE_CVisibilityPlugins_RenderPedCB 5 +static void __declspec(naked) HOOK_CVisibilityPlugins_RenderPedCB() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push esi; push edi; @@ -713,30 +828,36 @@ void _declspec(naked) HOOK_CVisibilityPlugins_RenderPedCB() pop esi; retn; } + // clang-format on } // Hook info -#define HOOKPOS_CRenderer_EverythingBarRoads 0x553C78 -#define HOOKSIZE_CRenderer_EverythingBarRoads 5 -DWORD RETURN_CRenderer_EverythingBarRoads = 0x553C7D; -DWORD DO_CRenderer_EverythingBarRoads = 0x7EE180; -void _declspec(naked) HOOK_CRenderer_EverythingBarRoads() +#define HOOKPOS_CRenderer_EverythingBarRoads 0x553C78 +#define HOOKSIZE_CRenderer_EverythingBarRoads 5 +DWORD RETURN_CRenderer_EverythingBarRoads = 0x553C7D; +DWORD DO_CRenderer_EverythingBarRoads = 0x7EE180; +static void __declspec(naked) HOOK_CRenderer_EverythingBarRoads() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on - if (pRenderEverythingBarRoadsHandler) - pRenderEverythingBarRoadsHandler(); + if (pRenderEverythingBarRoadsHandler) pRenderEverythingBarRoadsHandler(); - _asm + // clang-format off + __asm { popad call DO_CRenderer_EverythingBarRoads jmp RETURN_CRenderer_EverythingBarRoads } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -758,6 +879,8 @@ void CMultiplayerSA::InitHooks_Rendering() EZHookInstall(Check_NoOfVisibleEntities); EZHookInstall(WinLoop); EZHookInstall(CTimer_Update); + EZHookInstall(CTimer_Suspend); + EZHookInstall(CTimer_Resume); EZHookInstall(psGrabScreen); EZHookInstallChecked(CClouds_RenderSkyPolys); EZHookInstallChecked(RwCameraSetNearClipPlane); diff --git a/Client/multiplayer_sa/CMultiplayerSA_RwResources.cpp b/Client/multiplayer_sa/CMultiplayerSA_RwResources.cpp index 8a04cce91df..d29e894fb91 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_RwResources.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_RwResources.cpp @@ -10,10 +10,15 @@ *****************************************************************************/ #include "StdInc.h" +#include namespace { SRwResourceStats ms_Stats; + + constexpr std::size_t kTextureRefsReadableSize = offsetof(RwTexture, refs) + sizeof(int); + constexpr std::size_t kGeometryRefsReadableSize = offsetof(RwGeometry, refs) + sizeof(short); + } ////////////////////////////////////////////////////////////////////////////////////////// @@ -27,16 +32,22 @@ void OnMY_RwTextureCreate_Pre(DWORD calledFrom) void OnMY_RwTextureCreate_Post(RwTexture* pTexture, DWORD calledFrom) { + if (!pTexture) + return; + ms_Stats.uiTextures++; } // Hook info -#define HOOKPOS_RwTextureCreate 0x7F37C0 -#define HOOKSIZE_RwTextureCreate 5 -DWORD RETURN_RwTextureCreate = 0x7F37C5; -void _declspec(naked) HOOK_RwTextureCreate() +#define HOOKPOS_RwTextureCreate 0x7F37C0 +#define HOOKSIZE_RwTextureCreate 5 +DWORD RETURN_RwTextureCreate = 0x7F37C5; +static void __declspec(naked) HOOK_RwTextureCreate() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*0] @@ -61,6 +72,7 @@ void _declspec(naked) HOOK_RwTextureCreate() mov eax,dword ptr ds:[00C97B24h] jmp RETURN_RwTextureCreate } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -70,17 +82,30 @@ void _declspec(naked) HOOK_RwTextureCreate() ////////////////////////////////////////////////////////////////////////////////////////// void OnMY_RwTextureDestroy(RwTexture* pTexture, DWORD calledFrom) { - if (pTexture->refs == 1) + if (!pTexture) + return; + + if (SharedUtil::IsReadablePointer(pTexture, kTextureRefsReadableSize)) + { + if (pTexture->refs == 1 && ms_Stats.uiTextures > 0) + ms_Stats.uiTextures--; + return; + } + + if (ms_Stats.uiTextures > 0) ms_Stats.uiTextures--; } // Hook info -#define HOOKPOS_RwTextureDestroy 0x7F3820 -#define HOOKSIZE_RwTextureDestroy 5 -DWORD RETURN_RwTextureDestroy = 0x7F3825; -void _declspec(naked) HOOK_RwTextureDestroy() +#define HOOKPOS_RwTextureDestroy 0x7F3820 +#define HOOKSIZE_RwTextureDestroy 5 +DWORD RETURN_RwTextureDestroy = 0x7F3825; +static void __declspec(naked) HOOK_RwTextureDestroy() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push esi mov esi,dword ptr [esp+8] @@ -93,6 +118,7 @@ void _declspec(naked) HOOK_RwTextureDestroy() jmp RETURN_RwTextureDestroy } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -106,12 +132,15 @@ void OnMY_RwRasterCreate(DWORD calledFrom) } // Hook info -#define HOOKPOS_RwRasterCreate 0x7FB230 -#define HOOKSIZE_RwRasterCreate 5 -DWORD RETURN_RwRasterCreate = 0x7FB235; -void _declspec(naked) HOOK_RwRasterCreate() +#define HOOKPOS_RwRasterCreate 0x7FB230 +#define HOOKSIZE_RwRasterCreate 5 +DWORD RETURN_RwRasterCreate = 0x7FB235; +static void __declspec(naked) HOOK_RwRasterCreate() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov eax,dword ptr ds:[00C97B24h] @@ -123,6 +152,7 @@ void _declspec(naked) HOOK_RwRasterCreate() jmp RETURN_RwRasterCreate } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -136,12 +166,15 @@ void OnMY_RwRasterDestroy(DWORD calledFrom) } // Hook info -#define HOOKPOS_RwRasterDestroy 0x7FB020 -#define HOOKSIZE_RwRasterDestroy 5 -DWORD RETURN_RwRasterDestroy = 0x7FB025; -void _declspec(naked) HOOK_RwRasterDestroy() +#define HOOKPOS_RwRasterDestroy 0x7FB020 +#define HOOKSIZE_RwRasterDestroy 5 +DWORD RETURN_RwRasterDestroy = 0x7FB025; +static void __declspec(naked) HOOK_RwRasterDestroy() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push esi mov esi,dword ptr [esp+8] @@ -153,6 +186,7 @@ void _declspec(naked) HOOK_RwRasterDestroy() jmp RETURN_RwRasterDestroy } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -166,16 +200,22 @@ void OnMY_RwGeometryCreate_Pre(DWORD calledFrom) void OnMY_RwGeometryCreate_Post(RwGeometry* pGeometry, DWORD calledFrom) { + if (!pGeometry) + return; + ms_Stats.uiGeometries++; } // Hook info -#define HOOKPOS_RwGeometryCreate 0x74CA90 -#define HOOKSIZE_RwGeometryCreate 7 -DWORD RETURN_RwGeometryCreate = 0x74CA97; -void _declspec(naked) HOOK_RwGeometryCreate() +#define HOOKPOS_RwGeometryCreate 0x74CA90 +#define HOOKSIZE_RwGeometryCreate 7 +DWORD RETURN_RwGeometryCreate = 0x74CA97; +static void __declspec(naked) HOOK_RwGeometryCreate() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*0] @@ -203,6 +243,7 @@ void _declspec(naked) HOOK_RwGeometryCreate() sub esp, 8 jmp RETURN_RwGeometryCreate } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -212,17 +253,30 @@ void _declspec(naked) HOOK_RwGeometryCreate() ////////////////////////////////////////////////////////////////////////////////////////// void OnMY_RwGeometryDestroy(DWORD calledFrom, RwGeometry* pGeometry) { - if (pGeometry->refs == 1) + if (!pGeometry) + return; + + if (SharedUtil::IsReadablePointer(pGeometry, kGeometryRefsReadableSize)) + { + if (pGeometry->refs == 1 && ms_Stats.uiGeometries > 0) + ms_Stats.uiGeometries--; + return; + } + + if (ms_Stats.uiGeometries > 0) ms_Stats.uiGeometries--; } // Hook info -#define HOOKPOS_RwGeometryDestroy 0x74CCC0 -#define HOOKSIZE_RwGeometryDestroy 5 -DWORD RETURN_RwGeometryDestroy = 0x74CCC5; -void _declspec(naked) HOOK_RwGeometryDestroy() +#define HOOKPOS_RwGeometryDestroy 0x74CCC0 +#define HOOKSIZE_RwGeometryDestroy 5 +DWORD RETURN_RwGeometryDestroy = 0x74CCC5; +static void __declspec(naked) HOOK_RwGeometryDestroy() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*1] @@ -235,6 +289,7 @@ void _declspec(naked) HOOK_RwGeometryDestroy() mov esi,dword ptr [esp+8] jmp RETURN_RwGeometryDestroy } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_Streaming.cpp b/Client/multiplayer_sa/CMultiplayerSA_Streaming.cpp index 88d1a93c956..9468cabc34c 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Streaming.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Streaming.cpp @@ -10,10 +10,17 @@ #include "StdInc.h" -void OnModelLoaded(unsigned int uiModelID) +void OnModelLoaded(uint32_t uiModelID) { - if (uiModelID < pGameInterface->GetBaseIDforTXD()) - pGameInterface->GetModelInfo(uiModelID)->MakeCustomModel(); + const int32_t baseTxdId = pGameInterface->GetBaseIDforTXD(); + if (baseTxdId <= 0) + return; + + if (uiModelID < static_cast(baseTxdId)) + { + if (auto* pModelInfo = pGameInterface->GetModelInfo(uiModelID)) + pModelInfo->MakeCustomModel(); + } } ////////////////////////////////////////////////////////////////////////////////////////// @@ -26,9 +33,13 @@ void OnModelLoaded(unsigned int uiModelID) #define HOOKPOS_CStreaming__ConvertBufferToObject 0x40CB88 #define HOOKSIZE_CStreaming__ConvertBufferToObject 9 -static void _declspec(naked) HOOK_CStreaming__ConvertBufferToObject() +static void __declspec(naked) HOOK_CStreaming__ConvertBufferToObject() { - _asm { + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { push esi call OnModelLoaded pop esi @@ -41,6 +52,103 @@ static void _declspec(naked) HOOK_CStreaming__ConvertBufferToObject() add esp, 20h retn } + // clang-format on +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// CStreaming::RetryLoadFile - spin loop timeout +// +// GTA:SA's RetryLoadFile (0x4076B7) has an unbounded while(1) spin loop that +// polls CdStreamGetStatus with no sleep or timeout. If the streaming channel +// stays in an error state (ms_channelError != -1), the loop freezes the game. +// +// This hook intercepts the loop-back decision at 0x40776B (the cmp+jnz that +// checks ms_channelError and jumps back to the loop head) and enforces a +// timeout. On timeout, ms_channelError is forced to -1 so the function exits +// through its normal "error cleared" path. +// +////////////////////////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CStreaming__RetryLoadFileTimeout 0x40776B +#define HOOKSIZE_CStreaming__RetryLoadFileTimeout 9 // cmp (7 bytes) + jnz (2 bytes) +static DWORD RETURN_CStreaming__RetryLoadFileTimeout_Exit = 0x407774; // pop edi; pop esi; jmp CLoadingScreen::Continue +static DWORD RETURN_CStreaming__RetryLoadFileTimeout_LoopBack = 0x4076F4; // Loop head (mov eax, ms_channel[esi].LoadStatus) + +static DWORD s_retryLoopStartTick = 0; +static DWORD s_retryLoopLastCallTick = 0; +static DWORD s_retryTimeoutCount = 0; +static DWORD s_lastTimeoutTick = 0; + +static bool ShouldTimeoutRetryLoop() +{ + constexpr DWORD FIRST_TIMEOUT_MS = 5000; + constexpr DWORD COOLDOWN_MS = 30000; + DWORD now = SharedUtil::GetTickCount32(); + + // After a quiet period with no timeouts, treat the next error as fresh + if (s_lastTimeoutTick != 0 && (now - s_lastTimeoutTick) > COOLDOWN_MS) + { + s_retryTimeoutCount = 0; + s_lastTimeoutTick = 0; + } + + // Detect new invocation: within the spin loop, consecutive calls are + // microseconds apart. A gap over 100ms means this is a fresh RetryLoadFile + // call, so reset the timer. This also handles the case where a previous + // invocation exited via loc_4077A5 without going through our hook. + if (s_retryLoopStartTick == 0 || (now - s_retryLoopLastCallTick) > 100) + s_retryLoopStartTick = now; + + s_retryLoopLastCallTick = now; + + // After the first timeout, outer callers (LoadAllRequestedModels and + // CModelInfoSA::Request) can re-enter RetryLoadFile on the same + // persistent I/O error. Exit immediately on re-entry to avoid + // accumulating multi-minute freezes across nested retry loops. + DWORD timeoutMs = (s_retryTimeoutCount > 0) ? 0 : FIRST_TIMEOUT_MS; + + DWORD elapsed = now - s_retryLoopStartTick; + if (elapsed >= timeoutMs) + { + s_retryLoopStartTick = 0; + s_retryTimeoutCount++; + s_lastTimeoutTick = now; + *(int*)0x8E4B90 = -1; // CStreaming::ms_channelError = -1 (force clear) + AddReportLog(8650, SString("RetryLoadFile spin loop timed out after %ums (count: %u)", elapsed, s_retryTimeoutCount)); + return true; + } + + return false; +} + +static void _declspec(naked) HOOK_CStreaming__RetryLoadFileTimeout() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + pushad + call ShouldTimeoutRetryLoop + test al, al + jnz timeout + + popad + + // Original code: cmp ms_channelError, -1; jnz loc_4076F4 + cmp dword ptr ds:[0x8E4B90], 0FFFFFFFFh + jnz loopback + + jmp RETURN_CStreaming__RetryLoadFileTimeout_Exit + + loopback: + jmp RETURN_CStreaming__RetryLoadFileTimeout_LoopBack + + timeout: + popad + jmp RETURN_CStreaming__RetryLoadFileTimeout_Exit + } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -53,4 +161,5 @@ static void _declspec(naked) HOOK_CStreaming__ConvertBufferToObject() void CMultiplayerSA::InitHooks_Streaming() { EZHookInstall(CStreaming__ConvertBufferToObject); + EZHookInstall(CStreaming__RetryLoadFileTimeout); } diff --git a/Client/multiplayer_sa/CMultiplayerSA_Tasks.cpp b/Client/multiplayer_sa/CMultiplayerSA_Tasks.cpp index 69cce9ab046..1af1cc09cf4 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Tasks.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Tasks.cpp @@ -26,9 +26,12 @@ static bool __IsIgnoreFireStateEnabled() #define HOOKSIZE_CTaskSimplePlayerOnFoot__MakeAbortable 6 static constexpr std::uintptr_t RETURN_CTaskSimplePlayerOnFoot__MakeAbortable = 0x68585F; static constexpr std::uintptr_t SKIP_CTaskSimplePlayerOnFoot__MakeAbortable = 0x685855; -static void _declspec(naked) HOOK_CTaskSimplePlayerOnFoot__MakeAbortable() +static void __declspec(naked) HOOK_CTaskSimplePlayerOnFoot__MakeAbortable() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // return false and keep task alive call dword ptr [eax+8] @@ -56,6 +59,7 @@ static void _declspec(naked) HOOK_CTaskSimplePlayerOnFoot__MakeAbortable() skip: jmp SKIP_CTaskSimplePlayerOnFoot__MakeAbortable } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_VehicleCollision.cpp b/Client/multiplayer_sa/CMultiplayerSA_VehicleCollision.cpp index 30de5308fe4..0a5b2fbf08b 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_VehicleCollision.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_VehicleCollision.cpp @@ -56,21 +56,26 @@ void TriggerVehicleCollisionEvent() // CAutomobile, CPlane, CHeli, CMonsterTruck, CQuadBike, CTrailer // ////////////////////////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CAutomobile_ProcessControl_VehicleDamage 0x6B1F3B -#define HOOKSIZE_CAutomobile_ProcessControl_VehicleDamage 6 +#define HOOKPOS_CAutomobile_ProcessControl_VehicleDamage 0x6B1F3B +#define HOOKSIZE_CAutomobile_ProcessControl_VehicleDamage 6 static const DWORD CONTINUE_CAutomobile_ProcessControl_VehicleDamage = 0x6B1F41; -static void _declspec(naked) HOOK_CAutomobile_ProcessControl_VehicleDamage() +static void __declspec(naked) HOOK_CAutomobile_ProcessControl_VehicleDamage() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pCollisionVehicle, ecx } + // clang-format on TriggerVehicleCollisionEvent(); - _asm + // clang-format off + __asm { popad mov ecx, pCollisionVehicle @@ -79,6 +84,7 @@ static void _declspec(naked) HOOK_CAutomobile_ProcessControl_VehicleDamage() call dword ptr[eax + 0E0h] jmp CONTINUE_CAutomobile_ProcessControl_VehicleDamage } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -89,21 +95,26 @@ static void _declspec(naked) HOOK_CAutomobile_ProcessControl_VehicleDamage() // CBike, CBmx // ////////////////////////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CBike_ProcessControl_VehicleDamage 0x6B9AA5 -#define HOOKSIZE_CBike_ProcessControl_VehicleDamage 6 +#define HOOKPOS_CBike_ProcessControl_VehicleDamage 0x6B9AA5 +#define HOOKSIZE_CBike_ProcessControl_VehicleDamage 6 static const DWORD CONTINUE_CBike_ProcessControl_VehicleDamage = 0x6B9AAB; -static void _declspec(naked) HOOK_CBike_ProcessControl_VehicleDamage() +static void __declspec(naked) HOOK_CBike_ProcessControl_VehicleDamage() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pCollisionVehicle, ecx } + // clang-format on TriggerVehicleCollisionEvent(); - _asm + // clang-format off + __asm { popad mov ecx, pCollisionVehicle @@ -112,6 +123,7 @@ static void _declspec(naked) HOOK_CBike_ProcessControl_VehicleDamage() call dword ptr[eax + 0E0h] jmp CONTINUE_CBike_ProcessControl_VehicleDamage } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -122,22 +134,27 @@ static void _declspec(naked) HOOK_CBike_ProcessControl_VehicleDamage() // CBoat // ////////////////////////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CBoat_ProcessControl_VehicleDamage 0x6F1864 -#define HOOKSIZE_CBoat_ProcessControl_VehicleDamage 5 +#define HOOKPOS_CBoat_ProcessControl_VehicleDamage 0x6F1864 +#define HOOKSIZE_CBoat_ProcessControl_VehicleDamage 5 static const DWORD CONTINUE_CBoat_ProcessControl_VehicleDamage = 0x6F1869; static const DWORD FUNC_CVehicle_ProcessCarAlarm = 0x6D21F0; -static void _declspec(naked) HOOK_CBoat_ProcessControl_VehicleDamage() +static void __declspec(naked) HOOK_CBoat_ProcessControl_VehicleDamage() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pCollisionVehicle, ecx } + // clang-format on TriggerVehicleCollisionEvent(); - _asm + // clang-format off + __asm { popad mov ecx, pCollisionVehicle @@ -145,6 +162,7 @@ static void _declspec(naked) HOOK_CBoat_ProcessControl_VehicleDamage() call FUNC_CVehicle_ProcessCarAlarm jmp CONTINUE_CBoat_ProcessControl_VehicleDamage } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -155,27 +173,33 @@ static void _declspec(naked) HOOK_CBoat_ProcessControl_VehicleDamage() // CTrain // ////////////////////////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CTrain_ProcessControl_VehicleDamage 0x6F86BB -#define HOOKSIZE_CTrain_ProcessControl_VehicleDamage 5 +#define HOOKPOS_CTrain_ProcessControl_VehicleDamage 0x6F86BB +#define HOOKSIZE_CTrain_ProcessControl_VehicleDamage 5 static const DWORD CONTINUE_CTrain_ProcessControl_VehicleDamage = 0x6F86C0; -static void _declspec(naked) HOOK_CTrain_ProcessControl_VehicleDamage() +static void __declspec(naked) HOOK_CTrain_ProcessControl_VehicleDamage() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov pCollisionVehicle, esi } + // clang-format on TriggerVehicleCollisionEvent(); - _asm + // clang-format off + __asm { popad mov esi, pCollisionVehicle mov al, ds:[0BA6728h] jmp CONTINUE_CTrain_ProcessControl_VehicleDamage } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_VehicleDamage.cpp b/Client/multiplayer_sa/CMultiplayerSA_VehicleDamage.cpp index 9d154a0fdbd..8c801c7de1d 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_VehicleDamage.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_VehicleDamage.cpp @@ -24,7 +24,7 @@ namespace CVector ms_SavedDamagedPos; VehicleDamageHandler* m_pVehicleDamageHandler = NULL; -} // namespace +} // namespace ////////////////////////////////////////////////////////////////////////////////////////// // @@ -58,14 +58,17 @@ bool OnMY_CVehicle_BurstTyre(CVehicleSAInterface* pVehicle, uchar ucTyre) } // Hook info -#define HOOKPOS_CAutomobile_BurstTyre 0x06A331C -#define HOOKSIZE_CAutomobile_BurstTyre 5 -#define HOOKCHECK_CAutomobile_BurstTyre 0x6A -DWORD RETURN_CAutomobile_BurstTyre_A = 0x06A3321; -DWORD RETURN_CAutomobile_BurstTyre_B = 0x06A3425; -void _declspec(naked) HOOK_CAutomobile_BurstTyre() +#define HOOKPOS_CAutomobile_BurstTyre 0x06A331C +#define HOOKSIZE_CAutomobile_BurstTyre 5 +#define HOOKCHECK_CAutomobile_BurstTyre 0x6A +DWORD RETURN_CAutomobile_BurstTyre_A = 0x06A3321; +DWORD RETURN_CAutomobile_BurstTyre_B = 0x06A3425; +static void __declspec(naked) HOOK_CAutomobile_BurstTyre() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push edi @@ -86,6 +89,7 @@ void _declspec(naked) HOOK_CAutomobile_BurstTyre() mov ecx, ebx jmp RETURN_CAutomobile_BurstTyre_A } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -95,14 +99,17 @@ void _declspec(naked) HOOK_CAutomobile_BurstTyre() // ////////////////////////////////////////////////////////////////////////////////////////// // Hook info -#define HOOKPOS_CBike_BurstTyre 0x06BEB94 -#define HOOKSIZE_CBike_BurstTyre 10 -#define HOOKCHECK_CBike_BurstTyre 0x6A -DWORD RETURN_CBike_BurstTyre_A = 0x06BEB9E; -DWORD RETURN_CBike_BurstTyre_B = 0x06BECA5; -void _declspec(naked) HOOK_CBike_BurstTyre() +#define HOOKPOS_CBike_BurstTyre 0x06BEB94 +#define HOOKSIZE_CBike_BurstTyre 10 +#define HOOKCHECK_CBike_BurstTyre 0x6A +DWORD RETURN_CBike_BurstTyre_A = 0x06BEB9E; +DWORD RETURN_CBike_BurstTyre_B = 0x06BECA5; +static void __declspec(naked) HOOK_CBike_BurstTyre() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad movzx eax, bl @@ -124,6 +131,7 @@ void _declspec(naked) HOOK_CBike_BurstTyre() lea ecx, [esi+138h] jmp RETURN_CBike_BurstTyre_A } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -145,13 +153,16 @@ bool OnMY_CVehicle_InflictDamage(CVehicleSAInterface* pVehicle, CEntitySAInterfa } // Hook info -#define HOOKPOS_CVehicle_InflictDamage 0x06D7C90 -#define HOOKSIZE_CVehicle_InflictDamage 5 -#define HOOKCHECK_CVehicle_InflictDamage 0x6A -DWORD RETURN_CVehicle_InflictDamage = 0x0404CDC; -void _declspec(naked) HOOK_CVehicle_InflictDamage() +#define HOOKPOS_CVehicle_InflictDamage 0x06D7C90 +#define HOOKSIZE_CVehicle_InflictDamage 5 +#define HOOKCHECK_CVehicle_InflictDamage 0x6A +DWORD RETURN_CVehicle_InflictDamage = 0x0404CDC; +static void __declspec(naked) HOOK_CVehicle_InflictDamage() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*6] @@ -175,6 +186,7 @@ void _declspec(naked) HOOK_CVehicle_InflictDamage() push 0FFFFFFFFh jmp RETURN_CVehicle_InflictDamage } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -199,13 +211,16 @@ void OnMY_CVehicle_VehicleDamage1(CVehicleSAInterface* pVehicle, float f, ushort } // Hook info -#define HOOKPOS_CAutomobile_VehicleDamage1 0x06A7650 -#define HOOKSIZE_CAutomobile_VehicleDamage1 7 -#define HOOKCHECK_CAutomobile_VehicleDamage1 0x6A -DWORD RETURN_CAutomobile_VehicleDamage1 = 0x06A7657; -void _declspec(naked) HOOK_CAutomobile_VehicleDamage1() +#define HOOKPOS_CAutomobile_VehicleDamage1 0x06A7650 +#define HOOKSIZE_CAutomobile_VehicleDamage1 7 +#define HOOKCHECK_CAutomobile_VehicleDamage1 0x6A +DWORD RETURN_CAutomobile_VehicleDamage1 = 0x06A7657; +static void __declspec(naked) HOOK_CAutomobile_VehicleDamage1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*6] @@ -224,6 +239,7 @@ void _declspec(naked) HOOK_CAutomobile_VehicleDamage1() push [0x847FD8] jmp RETURN_CAutomobile_VehicleDamage1 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -258,13 +274,16 @@ float OnMY_CVehicle_VehicleDamage2(CVehicleSAInterface* pVehicle, float fDamage) } // Hook info -#define HOOKPOS_CAutomobile_VehicleDamage2 0x06A8325 -#define HOOKSIZE_CAutomobile_VehicleDamage2 6 -#define HOOKCHECK_CAutomobile_VehicleDamage2 0xD8 -DWORD RETURN_CAutomobile_VehicleDamage2 = 0x06A832B; -void _declspec(naked) HOOK_CAutomobile_VehicleDamage2() +#define HOOKPOS_CAutomobile_VehicleDamage2 0x06A8325 +#define HOOKSIZE_CAutomobile_VehicleDamage2 6 +#define HOOKCHECK_CAutomobile_VehicleDamage2 0xD8 +DWORD RETURN_CAutomobile_VehicleDamage2 = 0x06A832B; +static void __declspec(naked) HOOK_CAutomobile_VehicleDamage2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad fstp [esp-4] // Pop loss @@ -279,6 +298,7 @@ void _declspec(naked) HOOK_CAutomobile_VehicleDamage2() fsubr dword ptr [esi+4C0h] jmp RETURN_CAutomobile_VehicleDamage2 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -289,13 +309,16 @@ void _declspec(naked) HOOK_CAutomobile_VehicleDamage2() // ////////////////////////////////////////////////////////////////////////////////////////// // Hook info -#define HOOKPOS_CPlane_VehicleDamage1 0x06CC4B0 -#define HOOKSIZE_CPlane_VehicleDamage1 8 -#define HOOKCHECK_CPlane_VehicleDamage1 0x83 -DWORD RETURN_CPlane_VehicleDamage1 = 0x06CC4B8; -void _declspec(naked) HOOK_CPlane_VehicleDamage1() +#define HOOKPOS_CPlane_VehicleDamage1 0x06CC4B0 +#define HOOKSIZE_CPlane_VehicleDamage1 8 +#define HOOKCHECK_CPlane_VehicleDamage1 0x83 +DWORD RETURN_CPlane_VehicleDamage1 = 0x06CC4B8; +static void __declspec(naked) HOOK_CPlane_VehicleDamage1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*6] @@ -314,6 +337,7 @@ void _declspec(naked) HOOK_CPlane_VehicleDamage1() mov eax, dword ptr ds:[0x08D33E4] jmp RETURN_CPlane_VehicleDamage1 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -324,13 +348,16 @@ void _declspec(naked) HOOK_CPlane_VehicleDamage1() // ////////////////////////////////////////////////////////////////////////////////////////// // Hook info -#define HOOKPOS_CPlane_VehicleDamage2 0x06CC6C8 -#define HOOKSIZE_CPlane_VehicleDamage2 6 -#define HOOKCHECK_CPlane_VehicleDamage2 0xD8 -DWORD RETURN_CPlane_VehicleDamage2 = 0x06CC6CE; -void _declspec(naked) HOOK_CPlane_VehicleDamage2() +#define HOOKPOS_CPlane_VehicleDamage2 0x06CC6C8 +#define HOOKSIZE_CPlane_VehicleDamage2 6 +#define HOOKCHECK_CPlane_VehicleDamage2 0xD8 +DWORD RETURN_CPlane_VehicleDamage2 = 0x06CC6CE; +static void __declspec(naked) HOOK_CPlane_VehicleDamage2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad fstp [esp-4] // Pop loss @@ -345,6 +372,7 @@ void _declspec(naked) HOOK_CPlane_VehicleDamage2() fsubr dword ptr [esi+4C0h] jmp RETURN_CPlane_VehicleDamage2 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -355,13 +383,16 @@ void _declspec(naked) HOOK_CPlane_VehicleDamage2() // ////////////////////////////////////////////////////////////////////////////////////////// // Hook info -#define HOOKPOS_CBike_VehicleDamage1 0x06B8EC0 -#define HOOKSIZE_CBike_VehicleDamage1 5 -#define HOOKCHECK_CBike_VehicleDamage1 0x51 -DWORD RETURN_CBike_VehicleDamage1 = 0x06B8EC5; -void _declspec(naked) HOOK_CBike_VehicleDamage1() +#define HOOKPOS_CBike_VehicleDamage1 0x06B8EC0 +#define HOOKSIZE_CBike_VehicleDamage1 5 +#define HOOKCHECK_CBike_VehicleDamage1 0x51 +DWORD RETURN_CBike_VehicleDamage1 = 0x06B8EC5; +static void __declspec(naked) HOOK_CBike_VehicleDamage1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*6] @@ -380,6 +411,7 @@ void _declspec(naked) HOOK_CBike_VehicleDamage1() fld [esp+8] jmp RETURN_CBike_VehicleDamage1 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -390,13 +422,16 @@ void _declspec(naked) HOOK_CBike_VehicleDamage1() // ////////////////////////////////////////////////////////////////////////////////////////// // Hook info -#define HOOKPOS_CBike_VehicleDamage2 0x06B91C2 -#define HOOKSIZE_CBike_VehicleDamage2 6 -#define HOOKCHECK_CBike_VehicleDamage2 0xD8 -DWORD RETURN_CBike_VehicleDamage2 = 0x06B91C8; -void _declspec(naked) HOOK_CBike_VehicleDamage2() +#define HOOKPOS_CBike_VehicleDamage2 0x06B91C2 +#define HOOKSIZE_CBike_VehicleDamage2 6 +#define HOOKCHECK_CBike_VehicleDamage2 0xD8 +DWORD RETURN_CBike_VehicleDamage2 = 0x06B91C8; +static void __declspec(naked) HOOK_CBike_VehicleDamage2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad fstp [esp-4] // Pop loss @@ -411,6 +446,7 @@ void _declspec(naked) HOOK_CBike_VehicleDamage2() fsubr dword ptr [esi+4C0h] jmp RETURN_CBike_VehicleDamage2 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_VehicleDummies.cpp b/Client/multiplayer_sa/CMultiplayerSA_VehicleDummies.cpp index 316e80d4f9d..08d1219f390 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_VehicleDummies.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_VehicleDummies.cpp @@ -45,13 +45,15 @@ static void __cdecl UpdateVehicleDummiesPositionArray(CVehicleSAInterface* vehic // >>> 0x6DE325 | 89 54 24 70 | mov [esp+0D4h+var_64.x], edx // >>> 0x6DE329 | 89 54 24 48 | mov [esp+0D4h+var_8C], edx // 0x6DE32D | E8 BE D9 EB FF | call CMatrix::CMatrix(CMatrix const &) -#define HOOKPOS_CVehicle_AddExhaustParticles_1 0x6DE2F1 -#define HOOKSIZE_CVehicle_AddExhaustParticles_1 59 +#define HOOKPOS_CVehicle_AddExhaustParticles_1 0x6DE2F1 +#define HOOKSIZE_CVehicle_AddExhaustParticles_1 59 static const DWORD CONTINUE_CVehicle_AddExhaustParticles_1 = 0x6DE32D; static void __cdecl ApplyExhaustParticlesPosition(CVehicleSAInterface* vehicleInterface, CVector* mainPosition, CVector* secondaryPosition) { - UpdateVehicleDummiesPositionArray(vehicleInterface); + // NOTE: Caller (HOOK_CVehicle_AddExhaustParticles_1) already called UpdateVehicleDummiesPositionArray + // and verified vehicleDummiesPositionArray is non-null before calling us. Don't call it again + // as the pool state could change between calls, causing nullptr deref or wrong positions. if (vehicleDummiesPositionArray != nullptr) { @@ -94,29 +96,71 @@ static void __cdecl ApplyExhaustParticlesPosition(CVehicleSAInterface* vehicleIn } } -static void _declspec(naked) HOOK_CVehicle_AddExhaustParticles_1() +static void __declspec(naked) HOOK_CVehicle_AddExhaustParticles_1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad - lea eax, [esp+5Ch] - lea ebx, [esp+84h] - push eax // CVector* - push ebx // CVector* push esi // CVehicleSAInterface* + call UpdateVehicleDummiesPositionArray + add esp, 4 + + mov eax, vehicleDummiesPositionArray + test eax, eax + jz useOriginalCode + + // Check if exhaust dummy position is uninitialized (all zeros) + // EXHAUST is at index 6, offset = 6 * sizeof(CVector) = 6 * 12 = 0x48 + mov ecx, [eax+48h] // EXHAUST.X + or ecx, [eax+4Ch] // EXHAUST.Y + or ecx, [eax+50h] // EXHAUST.Z + jz useOriginalCode // If all zero, use model defaults + + // vehicle with custom dummies - apply custom positions to stack + // ApplyExhaustParticlesPosition writes all position components correctly + // Parameters: (vehicleInterface, mainPosition, secondaryPosition) + // cdecl: push right-to-left, so eax=secondary (3rd), ebx=main (2nd), esi=vehicle (1st) + lea eax, [esp+5Ch] // secondaryPosition at original_esp+0x3C + lea ebx, [esp+84h] // mainPosition at original_esp+0x64 + push eax + push ebx + push esi call ApplyExhaustParticlesPosition add esp, 12 popad - mov edx, vehicleDummiesPositionArray + // ApplyExhaustParticlesPosition already wrote all X,Y,Z to mainPos and secondaryPos. + // Now replicate remaining original instructions that don't involve position data: + // push ebx, lea ecx for matrix constructor arg, then jump to continuation + push ebx + lea ecx, [esp+80h] + jmp CONTINUE_CVehicle_AddExhaustParticles_1 + + useOriginalCode: + // Vehicle not in MTA pool or has uninitialized dummies - run SA code + popad + mov edx, [edi+5Ch] add edx, 48h + mov eax, [edx] + mov [esp+64h], eax + mov ecx, [edx+4] + fld dword ptr [esp+64h] + mov [esp+68h], ecx mov edx, [edx+8] + fmul dword ptr ds:[0858C1Ch] + mov [esp+40h], ecx + mov [esp+3Ch], eax push ebx - lea ecx, [esp+0D4h-54h] - mov [esp+0D4h-64h], edx - mov [esp+0D4h-8Ch], edx + lea ecx, [esp+80h] + fstp dword ptr [esp+40h] + mov [esp+70h], edx + mov [esp+48h], edx jmp CONTINUE_CVehicle_AddExhaustParticles_1 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -130,19 +174,29 @@ static void _declspec(naked) HOOK_CVehicle_AddExhaustParticles_1() // >>> 0x6DE39E | 8B 57 5C | mov edx, [edi+5Ch] // >>> 0x6DE3A1 | 81 C2 84 00 00 00 | add edx, 84h // 0x6DE3A7 | 8B 02 | mov eax, [edx] -#define HOOKPOS_CVehicle_AddExhaustParticles_2 0x6DE39E -#define HOOKSIZE_CVehicle_AddExhaustParticles_2 9 +#define HOOKPOS_CVehicle_AddExhaustParticles_2 0x6DE39E +#define HOOKSIZE_CVehicle_AddExhaustParticles_2 9 static const DWORD CONTINUE_CVehicle_AddExhaustParticles_2 = 0x6DE3A7; -static void _declspec(naked) HOOK_CVehicle_AddExhaustParticles_2() +static void __declspec(naked) HOOK_CVehicle_AddExhaustParticles_2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov eax, vehicleDummiesPositionArray test eax, eax jz continueWithOriginalCode + // Check if exhaust secondary dummy position is uninitialized (all zeros) + // EXHAUST_SECONDARY is at offset 0x84 + mov ecx, [eax+84h] // EXHAUST_SECONDARY.X + or ecx, [eax+88h] // EXHAUST_SECONDARY.Y + or ecx, [eax+8Ch] // EXHAUST_SECONDARY.Z + jz continueWithOriginalCode + popad mov edx, vehicleDummiesPositionArray add edx, 84h @@ -154,6 +208,7 @@ static void _declspec(naked) HOOK_CVehicle_AddExhaustParticles_2() add edx, 84h jmp CONTINUE_CVehicle_AddExhaustParticles_2 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -167,13 +222,16 @@ static void _declspec(naked) HOOK_CVehicle_AddExhaustParticles_2() // >>> 0x6D2B09 | 8B 49 5C | mov ecx, [ecx+5Ch] // >>> 0x6D2B0C | 83 C1 54 | add ecx, 54h // 0x6D2B0F | 84 D2 | test dl, dl -#define HOOKPOS_CVehicle_AddDamagedVehicleParticles 0x6D2B09 -#define HOOKSIZE_CVehicle_AddDamagedVehicleParticles 6 +#define HOOKPOS_CVehicle_AddDamagedVehicleParticles 0x6D2B09 +#define HOOKSIZE_CVehicle_AddDamagedVehicleParticles 6 static const DWORD CONTINUE_CVehicle_AddDamagedVehicleParticles = 0x6D2B0F; -static void _declspec(naked) HOOK_CVehicle_AddDamagedVehicleParticles() +static void __declspec(naked) HOOK_CVehicle_AddDamagedVehicleParticles() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi // CVehicleSAInterface* @@ -184,6 +242,12 @@ static void _declspec(naked) HOOK_CVehicle_AddDamagedVehicleParticles() test eax, eax jz continueWithOriginalCode + // Check if ENGINE dummy (offset 0x54) is uninitialized (all zeros) + mov edx, [eax+54h] // ENGINE.X + or edx, [eax+58h] // ENGINE.Y + or edx, [eax+5Ch] // ENGINE.Z + jz continueWithOriginalCode + popad mov ecx, vehicleDummiesPositionArray add ecx, 54h @@ -191,10 +255,11 @@ static void _declspec(naked) HOOK_CVehicle_AddDamagedVehicleParticles() continueWithOriginalCode: popad - mov ecx, [edi+5Ch] + mov ecx, [ecx+5Ch] add ecx, 54h jmp CONTINUE_CVehicle_AddDamagedVehicleParticles } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -208,13 +273,16 @@ static void _declspec(naked) HOOK_CVehicle_AddDamagedVehicleParticles() // >>> 0x53A714 | 8B 40 5C | mov eax, [eax+5Ch] // >>> 0x53A717 | 8B 10 | mov edx, [eax] // 0x53A719 | 89 54 24 18 | mov [esp+3Ch+var_24.x], edx -#define HOOKPOS_CFire_ProcessFire 0x53A714 -#define HOOKSIZE_CFire_ProcessFire 5 +#define HOOKPOS_CFire_ProcessFire 0x53A714 +#define HOOKSIZE_CFire_ProcessFire 5 static const DWORD CONTINUE_CFire_ProcessFire = 0x53A719; -static void _declspec(naked) HOOK_CFire_ProcessFire() +static void __declspec(naked) HOOK_CFire_ProcessFire() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push ecx // CVehicleSAInterface* @@ -225,6 +293,12 @@ static void _declspec(naked) HOOK_CFire_ProcessFire() test eax, eax jz continueWithOriginalCode + // Check if dummy at offset 0 is uninitialized (all zeros) + mov edx, [eax] // Dummy.X + or edx, [eax+4] // Dummy.Y + or edx, [eax+8] // Dummy.Z + jz continueWithOriginalCode + popad mov eax, vehicleDummiesPositionArray mov edx, [eax] @@ -236,6 +310,7 @@ static void _declspec(naked) HOOK_CFire_ProcessFire() mov edx, [eax] jmp CONTINUE_CFire_ProcessFire } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -249,13 +324,16 @@ static void _declspec(naked) HOOK_CFire_ProcessFire() // >>> 0x6A3BE2 | 8B 48 5C | mov ecx, [eax+5Ch] // >>> 0x6A3BE5 | 83 C1 48 | add ecx, 48h // 0x6A3BE8 | 8B 11 | mov edx, [ecx] -#define HOOKPOS_CAutomobile_DoNitroEffect_1 0x6A3BE2 -#define HOOKSIZE_CAutomobile_DoNitroEffect_1 6 +#define HOOKPOS_CAutomobile_DoNitroEffect_1 0x6A3BE2 +#define HOOKSIZE_CAutomobile_DoNitroEffect_1 6 static const DWORD CONTINUE_CAutomobile_DoNitroEffect_1 = 0x6A3BE8; -static void _declspec(naked) HOOK_CAutomobile_DoNitroEffect_1() +static void __declspec(naked) HOOK_CAutomobile_DoNitroEffect_1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi // CVehicleSAInterface* @@ -266,6 +344,12 @@ static void _declspec(naked) HOOK_CAutomobile_DoNitroEffect_1() test eax, eax jz continueWithOriginalCode + // Check if EXHAUST dummy (offset 0x48) is uninitialized (all zeros) + mov edx, [eax+48h] // EXHAUST.X + or edx, [eax+4Ch] // EXHAUST.Y + or edx, [eax+50h] // EXHAUST.Z + jz continueWithOriginalCode + popad mov ecx, vehicleDummiesPositionArray add ecx, 48h @@ -277,6 +361,7 @@ static void _declspec(naked) HOOK_CAutomobile_DoNitroEffect_1() add ecx, 48h jmp CONTINUE_CAutomobile_DoNitroEffect_1 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -298,8 +383,8 @@ static void _declspec(naked) HOOK_CAutomobile_DoNitroEffect_1() // >>> 0x6A3C89 | D9 5C 24 20 | fstp [esp+38h+secondaryNitroPos.x] // >>> 0x6A3C8D | 89 54 24 24 | mov [esp+38h+secondaryNitroPos.y], edx // 0x6A3C91 | 74 4B | jz short loc_6A3CDE -#define HOOKPOS_CAutomobile_DoNitroEffect_2 0x6A3C68 -#define HOOKSIZE_CAutomobile_DoNitroEffect_2 41 +#define HOOKPOS_CAutomobile_DoNitroEffect_2 0x6A3C68 +#define HOOKSIZE_CAutomobile_DoNitroEffect_2 41 static const DWORD CONTINUE_CAutomobile_DoNitroEffect_2 = 0x6A3C91; static void __cdecl ApplySecondaryExhaustNitroPosition(CVehicleSAInterface* vehicleInterface, CVector* secondaryExhaustPosition) @@ -308,25 +393,34 @@ static void __cdecl ApplySecondaryExhaustNitroPosition(CVehicleSAInterface* vehi if (vehicleDummiesPositionArray != nullptr) { - *secondaryExhaustPosition = vehicleDummiesPositionArray[(std::size_t)VehicleDummies::EXHAUST_SECONDARY]; - - if (secondaryExhaustPosition->fX == 0.0 && secondaryExhaustPosition->fY == 0.0 && secondaryExhaustPosition->fZ == 0.0) + // Check if EXHAUST_SECONDARY is initialized (non-zero) + CVector& exhaustSecondary = vehicleDummiesPositionArray[(std::size_t)VehicleDummies::EXHAUST_SECONDARY]; + if (exhaustSecondary.fX != 0.0f || exhaustSecondary.fY != 0.0f || exhaustSecondary.fZ != 0.0f) { - *secondaryExhaustPosition = vehicleDummiesPositionArray[(std::size_t)VehicleDummies::EXHAUST]; - secondaryExhaustPosition->fX *= -1.0f; + *secondaryExhaustPosition = exhaustSecondary; + } + else + { + // EXHAUST_SECONDARY is uninitialized, try EXHAUST with negated X + CVector& exhaust = vehicleDummiesPositionArray[(std::size_t)VehicleDummies::EXHAUST]; + if (exhaust.fX != 0.0f || exhaust.fY != 0.0f || exhaust.fZ != 0.0f) + { + *secondaryExhaustPosition = exhaust; + secondaryExhaustPosition->fX *= -1.0f; + } + // If both are zero, leave secondaryExhaustPosition unchanged (use original GTA value on stack) } } - else - { - secondaryExhaustPosition->fX = 0.0f; - secondaryExhaustPosition->fY = 0.0f; - secondaryExhaustPosition->fZ = 0.0f; - } + // If vehicleDummiesPositionArray is nullptr, leave secondaryExhaustPosition unchanged + // (use original GTA value that's already on the stack) } -static void _declspec(naked) HOOK_CAutomobile_DoNitroEffect_2() +static void __declspec(naked) HOOK_CAutomobile_DoNitroEffect_2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad lea eax, [esp+40h] @@ -339,6 +433,7 @@ static void _declspec(naked) HOOK_CAutomobile_DoNitroEffect_2() test [esi+40h], edi jmp CONTINUE_CAutomobile_DoNitroEffect_2 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -355,13 +450,16 @@ static void _declspec(naked) HOOK_CAutomobile_DoNitroEffect_2() // >>> 0x6E1F3C | 8B 40 5C | mov eax, [eax+5Ch] // >>> 0x6E1F3F | 83 C0 18 | add eax, 18h // 0x6E1F42 | 8B 08 | mov ecx, [eax] -#define HOOKPOS_CVehicle_DoVehicleLights_1 0x6E1F3C -#define HOOKSIZE_CVehicle_DoVehicleLights_1 6 +#define HOOKPOS_CVehicle_DoVehicleLights_1 0x6E1F3C +#define HOOKSIZE_CVehicle_DoVehicleLights_1 6 static const DWORD CONTINUE_CVehicle_DoVehicleLights_1 = 0x6E1F42; -static void _declspec(naked) HOOK_CVehicle_DoVehicleLights_1() +static void __declspec(naked) HOOK_CVehicle_DoVehicleLights_1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi // CVehicleSAInterface* @@ -372,6 +470,12 @@ static void _declspec(naked) HOOK_CVehicle_DoVehicleLights_1() test eax, eax jz continueWithOriginalCode + // Check if LIGHT_FRONT_SECONDARY (offset 0x18) is uninitialized + mov edx, [eax+18h] + or edx, [eax+1Ch] + or edx, [eax+20h] + jz continueWithOriginalCode + popad mov eax, vehicleDummiesPositionArray add eax, 18h @@ -383,19 +487,23 @@ static void _declspec(naked) HOOK_CVehicle_DoVehicleLights_1() add eax, 18h jmp CONTINUE_CVehicle_DoVehicleLights_1 } + // clang-format on } // 0x6E22C6 | 8B 04 85 C8 B0 A9 00 | mov eax, CModelInfo::ms_modelInfoPtrs // >>> 0x6E22CD | 8B 48 5C | mov ecx, [eax+5Ch] // >>> 0x6E22D0 | 83 C1 18 | add ecx, 18h // 0x6E22D3 | 8B 11 | mov edx, [ecx] -#define HOOKPOS_CVehicle_DoVehicleLights_2 0x6E22CD -#define HOOKSIZE_CVehicle_DoVehicleLights_2 6 +#define HOOKPOS_CVehicle_DoVehicleLights_2 0x6E22CD +#define HOOKSIZE_CVehicle_DoVehicleLights_2 6 static const DWORD CONTINUE_CVehicle_DoVehicleLights_2 = 0x6E22D3; -static void _declspec(naked) HOOK_CVehicle_DoVehicleLights_2() +static void __declspec(naked) HOOK_CVehicle_DoVehicleLights_2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi // CVehicleSAInterface* @@ -406,6 +514,12 @@ static void _declspec(naked) HOOK_CVehicle_DoVehicleLights_2() test eax, eax jz continueWithOriginalCode + // Check if LIGHT_FRONT_SECONDARY (offset 0x18) is uninitialized + mov edx, [eax+18h] + or edx, [eax+1Ch] + or edx, [eax+20h] + jz continueWithOriginalCode + popad mov ecx, vehicleDummiesPositionArray add ecx, 18h @@ -417,6 +531,7 @@ static void _declspec(naked) HOOK_CVehicle_DoVehicleLights_2() add ecx, 18h jmp CONTINUE_CVehicle_DoVehicleLights_2 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -430,13 +545,16 @@ static void _declspec(naked) HOOK_CVehicle_DoVehicleLights_2() // >>> 0x6A717F | 8B 40 5C | mov eax, [eax+5Ch] // >>> 0x6A7182 | 83 C0 54 | add eax, 54h // 0x6A7185 | 8B 08 | mov ecx, [eax] -#define HOOKPOS_CAutomobile_ProcessCarOnFireAndExplode 0x6A717F -#define HOOKSIZE_CAutomobile_ProcessCarOnFireAndExplode 6 +#define HOOKPOS_CAutomobile_ProcessCarOnFireAndExplode 0x6A717F +#define HOOKSIZE_CAutomobile_ProcessCarOnFireAndExplode 6 static const DWORD CONTINUE_CAutomobile_ProcessCarOnFireAndExplode = 0x6A7185; -static void _declspec(naked) HOOK_CAutomobile_ProcessCarOnFireAndExplode() +static void __declspec(naked) HOOK_CAutomobile_ProcessCarOnFireAndExplode() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi // CVehicleSAInterface* @@ -447,6 +565,12 @@ static void _declspec(naked) HOOK_CAutomobile_ProcessCarOnFireAndExplode() test eax, eax jz continueWithOriginalCode + // Check if ENGINE dummy (offset 0x54) is uninitialized + mov edx, [eax+54h] + or edx, [eax+58h] + or edx, [eax+5Ch] + jz continueWithOriginalCode + popad mov eax, vehicleDummiesPositionArray add eax, 54h @@ -458,6 +582,7 @@ static void _declspec(naked) HOOK_CAutomobile_ProcessCarOnFireAndExplode() add eax, 54h jmp CONTINUE_CAutomobile_ProcessCarOnFireAndExplode } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -471,13 +596,16 @@ static void _declspec(naked) HOOK_CAutomobile_ProcessCarOnFireAndExplode() // >>> 0x6B8053 | 8B 40 5C | mov eax, [eax+92] // >>> 0x6B8056 | 83 C0 78 | add eax, 78h // 0x6B8059 | 8B 10 | mov edx, [eax] -#define HOOKPOS_CBike_FixHandsToBars 0x6B8053 -#define HOOKSIZE_CBike_FixHandsToBars 6 +#define HOOKPOS_CBike_FixHandsToBars 0x6B8053 +#define HOOKSIZE_CBike_FixHandsToBars 6 static const DWORD CONTINUE_CBike_FixHandsToBars = 0x6B8059; -static void _declspec(naked) HOOK_CBike_FixHandsToBars() +static void __declspec(naked) HOOK_CBike_FixHandsToBars() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push ebx // CVehicleSAInterface* @@ -488,6 +616,12 @@ static void _declspec(naked) HOOK_CBike_FixHandsToBars() test eax, eax jz continueWithOriginalCode + // Check if HAND_REST dummy (offset 0x78) is uninitialized + mov edx, [eax+78h] + or edx, [eax+7Ch] + or edx, [eax+80h] + jz continueWithOriginalCode + popad mov eax, vehicleDummiesPositionArray add eax, 78h @@ -499,6 +633,7 @@ static void _declspec(naked) HOOK_CBike_FixHandsToBars() add eax, 78h jmp CONTINUE_CBike_FixHandsToBars } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -512,13 +647,16 @@ static void _declspec(naked) HOOK_CBike_FixHandsToBars() // >>> 0x5DF98B | 83 7F 3C 05 | cmp dword ptr [edi+3Ch], 5 // >>> 0x5DF98F | 8B 7F 5C | mov edi, [edi+5Ch] // 0x5DF992 | 74 03 | jz short loc_5DF997 -#define HOOKPOS_CPed_SetPedPositionInCar_1 0x5DF98B -#define HOOKSIZE_CPed_SetPedPositionInCar_1 7 +#define HOOKPOS_CPed_SetPedPositionInCar_1 0x5DF98B +#define HOOKSIZE_CPed_SetPedPositionInCar_1 7 static const DWORD CONTINUE_CPed_SetPedPositionInCar_1 = 0x5DF992; -static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_1() +static void __declspec(naked) HOOK_CPed_SetPedPositionInCar_1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov eax, [esi+58Ch] @@ -530,6 +668,12 @@ static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_1() test eax, eax jz continueWithOriginalCode + // Check if SEAT_FRONT dummy (offset 0x30) is uninitialized + mov edx, [eax+30h] + or edx, [eax+34h] + or edx, [eax+38h] + jz continueWithOriginalCode + popad cmp dword ptr [edi+3Ch], 5 mov edi, vehicleDummiesPositionArray @@ -541,6 +685,7 @@ static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_1() mov edi, [edi+5Ch] jmp CONTINUE_CPed_SetPedPositionInCar_1 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -554,13 +699,16 @@ static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_1() // >>> 0x5DFA56 | 8B 47 5C | mov eax, [edi+5Ch] // >>> 0x5DFA59 | 83 C0 3C | add eax, 3Ch // 0x5DFA5C | 8B 10 | mov edx, [eax] -#define HOOKPOS_CPed_SetPedPositionInCar_2 0x5DFA56 -#define HOOKSIZE_CPed_SetPedPositionInCar_2 6 +#define HOOKPOS_CPed_SetPedPositionInCar_2 0x5DFA56 +#define HOOKSIZE_CPed_SetPedPositionInCar_2 6 static const DWORD CONTINUE_CPed_SetPedPositionInCar_2 = 0x5DFA5C; -static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_2() +static void __declspec(naked) HOOK_CPed_SetPedPositionInCar_2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov eax, [esi+58Ch] @@ -572,6 +720,12 @@ static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_2() test eax, eax jz continueWithOriginalCode + // Check if SEAT_REAR dummy (offset 0x3C) is uninitialized + mov edx, [eax+3Ch] + or edx, [eax+40h] + or edx, [eax+44h] + jz continueWithOriginalCode + popad mov eax, vehicleDummiesPositionArray add eax, 3Ch @@ -583,6 +737,7 @@ static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_2() add eax, 3Ch jmp CONTINUE_CPed_SetPedPositionInCar_2 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -596,13 +751,16 @@ static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_2() // >>> 0x5DFA04 | 83 7F 3C 05 | cmp dword ptr [edi+3Ch], 5 // >>> 0x5DFA08 | 8B 7F 5C | mov edi, [edi+5Ch] // 0x5DFA0B | 74 03 | jz short loc_5DFA10 -#define HOOKPOS_CPed_SetPedPositionInCar_3 0x5DFA04 -#define HOOKSIZE_CPed_SetPedPositionInCar_3 7 +#define HOOKPOS_CPed_SetPedPositionInCar_3 0x5DFA04 +#define HOOKSIZE_CPed_SetPedPositionInCar_3 7 static const DWORD CONTINUE_CPed_SetPedPositionInCar_3 = 0x5DFA0B; -static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_3() +static void __declspec(naked) HOOK_CPed_SetPedPositionInCar_3() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov eax, [esi+58Ch] @@ -614,6 +772,12 @@ static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_3() test eax, eax jz continueWithOriginalCode + // Check if SEAT_FRONT dummy (offset 0x30) is uninitialized + mov edx, [eax+30h] + or edx, [eax+34h] + or edx, [eax+38h] + jz continueWithOriginalCode + popad cmp dword ptr [edi+3Ch], 5 mov edi, vehicleDummiesPositionArray @@ -625,6 +789,7 @@ static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_3() mov edi, [edi+5Ch] jmp CONTINUE_CPed_SetPedPositionInCar_3 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -638,13 +803,16 @@ static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_3() // >>> 0x5DFA80 | 8B 57 5C | mov edx, [edi+5Ch] // >>> 0x5DFA83 | 83 C2 3C | add edx, 3Ch // 0x5DFA86 | 8B 02 | mov eax, [edx] -#define HOOKPOS_CPed_SetPedPositionInCar_4 0x5DFA80 -#define HOOKSIZE_CPed_SetPedPositionInCar_4 6 +#define HOOKPOS_CPed_SetPedPositionInCar_4 0x5DFA80 +#define HOOKSIZE_CPed_SetPedPositionInCar_4 6 static const DWORD CONTINUE_CPed_SetPedPositionInCar_4 = 0x5DFA86; -static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_4() +static void __declspec(naked) HOOK_CPed_SetPedPositionInCar_4() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov eax, [esi+58Ch] @@ -656,6 +824,12 @@ static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_4() test eax, eax jz continueWithOriginalCode + // Check if SEAT_REAR dummy (offset 0x3C) is uninitialized + mov edx, [eax+3Ch] + or edx, [eax+40h] + or edx, [eax+44h] + jz continueWithOriginalCode + popad mov edx, vehicleDummiesPositionArray add edx, 3Ch @@ -667,6 +841,7 @@ static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_4() add edx, 3Ch jmp CONTINUE_CPed_SetPedPositionInCar_4 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -680,13 +855,16 @@ static void _declspec(naked) HOOK_CPed_SetPedPositionInCar_4() // >>> 0x6E0A69 | 8B 50 5C | mov edx, [eax+5Ch] // >>> 0x6E0A6C | 8D 0C 5B | lea ecx, [ebx+ebx*2] // 0x6E0A6F | 8D 04 CA | lea eax, [edx+ecx*8] -#define HOOKPOS_CVehicle_DoHeadLightEffect 0x6E0A69 -#define HOOKSIZE_CVehicle_DoHeadLightEffect 6 +#define HOOKPOS_CVehicle_DoHeadLightEffect 0x6E0A69 +#define HOOKSIZE_CVehicle_DoHeadLightEffect 6 static const DWORD CONTINUE_CVehicle_DoHeadLightEffect = 0x6E0A6F; -static void _declspec(naked) HOOK_CVehicle_DoHeadLightEffect() +static void __declspec(naked) HOOK_CVehicle_DoHeadLightEffect() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push ecx // CVehicleSAInterface* @@ -697,6 +875,12 @@ static void _declspec(naked) HOOK_CVehicle_DoHeadLightEffect() test eax, eax jz continueWithOriginalCode + // Check if LIGHT_FRONT_MAIN dummy (offset 0x00) is uninitialized + mov edx, [eax] + or edx, [eax+4] + or edx, [eax+8] + jz continueWithOriginalCode + popad mov edx, vehicleDummiesPositionArray lea ecx, [ebx+ebx*2] @@ -708,6 +892,7 @@ static void _declspec(naked) HOOK_CVehicle_DoHeadLightEffect() lea ecx, [ebx+ebx*2] jmp CONTINUE_CVehicle_DoHeadLightEffect } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -722,13 +907,16 @@ static void _declspec(naked) HOOK_CVehicle_DoHeadLightEffect() // >>> 0x6E17C3 | 53 | push ebx // >>> 0x6E17C4 | 8B 5C 24 34 | mov ebx, [esp+4+30h] // 0x6E17C8 | 83 FB 01 | cmp ebx, 1 -#define HOOKPOS_CVehicle_DoTailLightEffect 0x6E17C0 -#define HOOKSIZE_CVehicle_DoTailLightEffect 8 +#define HOOKPOS_CVehicle_DoTailLightEffect 0x6E17C0 +#define HOOKSIZE_CVehicle_DoTailLightEffect 8 static const DWORD CONTINUE_CVehicle_DoTailLightEffect = 0x6E17C8; -static void _declspec(naked) HOOK_CVehicle_DoTailLightEffect() +static void __declspec(naked) HOOK_CVehicle_DoTailLightEffect() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi // CVehicleSAInterface* @@ -739,6 +927,12 @@ static void _declspec(naked) HOOK_CVehicle_DoTailLightEffect() test eax, eax jz continueWithOriginalCode + // Check if LIGHT_REAR_MAIN dummy (offset 0x0C) is uninitialized + mov edx, [eax+0Ch] + or edx, [eax+10h] + or edx, [eax+14h] + jz continueWithOriginalCode + popad mov edx, vehicleDummiesPositionArray push ebx @@ -752,6 +946,7 @@ static void _declspec(naked) HOOK_CVehicle_DoTailLightEffect() mov ebx, [esp+4+30h] jmp CONTINUE_CVehicle_DoTailLightEffect } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -765,13 +960,16 @@ static void _declspec(naked) HOOK_CVehicle_DoTailLightEffect() // >>> 0x6E1452 | 8B 50 5C | mov edx, [eax+5Ch] // >>> 0x6E1455 | 8B 02 | mov eax, [edx] // 0x6E1457 | 89 44 24 18 | mov [esp+24h+var_C], eax -#define HOOKPOS_CVehicle_DoHeadLightReflectionSingle 0x6E1452 -#define HOOKSIZE_CVehicle_DoHeadLightReflectionSingle 5 +#define HOOKPOS_CVehicle_DoHeadLightReflectionSingle 0x6E1452 +#define HOOKSIZE_CVehicle_DoHeadLightReflectionSingle 5 static const DWORD CONTINUE_CVehicle_DoHeadLightReflectionSingle = 0x6E1457; -static void _declspec(naked) HOOK_CVehicle_DoHeadLightReflectionSingle() +static void __declspec(naked) HOOK_CVehicle_DoHeadLightReflectionSingle() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push ecx // CVehicleSAInterface* @@ -782,6 +980,12 @@ static void _declspec(naked) HOOK_CVehicle_DoHeadLightReflectionSingle() test eax, eax jz continueWithOriginalCode + // Check if LIGHT_FRONT_MAIN dummy (offset 0x00) is uninitialized + mov edx, [eax] + or edx, [eax+4] + or edx, [eax+8] + jz continueWithOriginalCode + popad mov edx, vehicleDummiesPositionArray mov eax, [edx] @@ -793,6 +997,7 @@ static void _declspec(naked) HOOK_CVehicle_DoHeadLightReflectionSingle() mov eax, [edx] jmp CONTINUE_CVehicle_DoHeadLightReflectionSingle } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -806,13 +1011,16 @@ static void _declspec(naked) HOOK_CVehicle_DoHeadLightReflectionSingle() // >>> 0x6E160E | 8B 50 5C | mov edx, [eax+5Ch] // >>> 0x6E1611 | 8B 02 | mov eax, [edx] // 0x6E1613 | 89 44 24 10 | mov [esp+1Ch+var_C], eax -#define HOOKPOS_CVehicle_DoHeadLightReflectionTwin 0x6E160E -#define HOOKSIZE_CVehicle_DoHeadLightReflectionTwin 5 +#define HOOKPOS_CVehicle_DoHeadLightReflectionTwin 0x6E160E +#define HOOKSIZE_CVehicle_DoHeadLightReflectionTwin 5 static const DWORD CONTINUE_CVehicle_DoHeadLightReflectionTwin = 0x6E1613; -static void _declspec(naked) HOOK_CVehicle_DoHeadLightReflectionTwin() +static void __declspec(naked) HOOK_CVehicle_DoHeadLightReflectionTwin() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push ecx // CVehicleSAInterface* @@ -823,6 +1031,12 @@ static void _declspec(naked) HOOK_CVehicle_DoHeadLightReflectionTwin() test eax, eax jz continueWithOriginalCode + // Check if LIGHT_FRONT_MAIN dummy (offset 0x00) is uninitialized + mov edx, [eax] + or edx, [eax+4] + or edx, [eax+8] + jz continueWithOriginalCode + popad mov edx, vehicleDummiesPositionArray mov eax, [edx] @@ -834,6 +1048,7 @@ static void _declspec(naked) HOOK_CVehicle_DoHeadLightReflectionTwin() mov eax, [edx] jmp CONTINUE_CVehicle_DoHeadLightReflectionTwin } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -848,13 +1063,16 @@ static void _declspec(naked) HOOK_CVehicle_DoHeadLightReflectionTwin() // >>> 0x6D429A | 8B 04 8D C8 B0 A9 00 | mov eax, CModelInfo::ms_modelInfoPtrs // >>> 0x6D42A1 | 8B 40 5C | mov eax, [eax+5Ch] // 0x6D42A4 | 05 9C 00 00 00 | add eax, 9Ch -#define HOOKPOS_CVehicle_GetPlaneGunsPosition 0x6D4297 -#define HOOKSIZE_CVehicle_GetPlaneGunsPosition 13 +#define HOOKPOS_CVehicle_GetPlaneGunsPosition 0x6D4297 +#define HOOKSIZE_CVehicle_GetPlaneGunsPosition 13 static const DWORD CONTINUE_CVehicle_GetPlaneGunsPosition = 0x6D42A4; -static void _declspec(naked) HOOK_CVehicle_GetPlaneGunsPosition() +static void __declspec(naked) HOOK_CVehicle_GetPlaneGunsPosition() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push ecx // CVehicleSAInterface* @@ -867,7 +1085,6 @@ static void _declspec(naked) HOOK_CVehicle_GetPlaneGunsPosition() popad movsx ecx, dx - mov eax, CModelInfo__ms_modelInfoPtrs mov eax, vehicleDummiesPositionArray jmp CONTINUE_CVehicle_GetPlaneGunsPosition @@ -875,9 +1092,11 @@ static void _declspec(naked) HOOK_CVehicle_GetPlaneGunsPosition() popad movsx ecx, dx mov eax, CModelInfo__ms_modelInfoPtrs + mov eax, [eax+ecx*4] mov eax, [eax+5Ch] jmp CONTINUE_CVehicle_GetPlaneGunsPosition } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -891,13 +1110,16 @@ static void _declspec(naked) HOOK_CVehicle_GetPlaneGunsPosition() // >>> 0x6D46F0 | 8B 40 5C | mov eax, [eax+5Ch] // >>> 0x6D46F3 | 05 9C 00 00 00 | add eax, 9Ch // 0x6D46F8 | 8B 08 | mov ecx, [eax] -#define HOOKPOS_CVehicle_GetPlaneOrdnancePosition 0x6D46F0 -#define HOOKSIZE_CVehicle_GetPlaneOrdnancePosition 8 +#define HOOKPOS_CVehicle_GetPlaneOrdnancePosition 0x6D46F0 +#define HOOKSIZE_CVehicle_GetPlaneOrdnancePosition 8 static const DWORD CONTINUE_CVehicle_GetPlaneOrdnancePosition = 0x6D46F8; -static void _declspec(naked) HOOK_CVehicle_GetPlaneOrdnancePosition() +static void __declspec(naked) HOOK_CVehicle_GetPlaneOrdnancePosition() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push ecx // CVehicleSAInterface* @@ -919,6 +1141,7 @@ static void _declspec(naked) HOOK_CVehicle_GetPlaneOrdnancePosition() add eax, 9Ch jmp CONTINUE_CVehicle_GetPlaneOrdnancePosition } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -932,13 +1155,16 @@ static void _declspec(naked) HOOK_CVehicle_GetPlaneOrdnancePosition() // >>> 0x6D5438 | 83 78 3C 05 | cmp dword ptr [eax+3Ch], 5 // >>> 0x6D543C | 8B 40 5C | mov eax, [eax+5Ch] // 0x6D543F | 74 03 | jz short loc_6D5444 -#define HOOKPOS_CVehicle_CanBeDriven 0x6D5438 -#define HOOKSIZE_CVehicle_CanBeDriven 7 +#define HOOKPOS_CVehicle_CanBeDriven 0x6D5438 +#define HOOKSIZE_CVehicle_CanBeDriven 7 static const DWORD CONTINUE_CVehicle_CanBeDriven = 0x6D543F; -static void _declspec(naked) HOOK_CVehicle_CanBeDriven() +static void __declspec(naked) HOOK_CVehicle_CanBeDriven() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push ecx // CVehicleSAInterface* @@ -949,6 +1175,12 @@ static void _declspec(naked) HOOK_CVehicle_CanBeDriven() test eax, eax jz continueWithOriginalCode + // Check if SEAT_FRONT dummy (offset 0x30) is uninitialized + mov edx, [eax+30h] + or edx, [eax+34h] + or edx, [eax+38h] + jz continueWithOriginalCode + popad cmp dword ptr [eax+3Ch], 5 mov eax, vehicleDummiesPositionArray @@ -960,6 +1192,7 @@ static void _declspec(naked) HOOK_CVehicle_CanBeDriven() mov eax, [eax+5Ch] jmp CONTINUE_CVehicle_CanBeDriven } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -973,13 +1206,16 @@ static void _declspec(naked) HOOK_CVehicle_CanBeDriven() // >>> 0x6C971B | 8B 4D 5C | mov ecx, [ebp+5Ch] // >>> 0x6C971E | 81 C1 84 00 00 00 | add ecx, 84h // 0x6C9724 | 8B 11 | mov edx, [ecx] -#define HOOKPOS_CPlane_PreRender_1 0x6C971B -#define HOOKSIZE_CPlane_PreRender_1 9 +#define HOOKPOS_CPlane_PreRender_1 0x6C971B +#define HOOKSIZE_CPlane_PreRender_1 9 static const DWORD CONTINUE_CPlane_PreRender_1 = 0x6C9724; -static void _declspec(naked) HOOK_CPlane_PreRender_1() +static void __declspec(naked) HOOK_CPlane_PreRender_1() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi // CVehicleSAInterface* @@ -990,6 +1226,12 @@ static void _declspec(naked) HOOK_CPlane_PreRender_1() test eax, eax jz continueWithOriginalCode + // Check if dummy at offset 0x84 (EXHAUST_SECONDARY) is uninitialized + mov edx, [eax+84h] + or edx, [eax+88h] + or edx, [eax+8Ch] + jz continueWithOriginalCode + popad mov ecx, vehicleDummiesPositionArray add ecx, 84h @@ -1001,6 +1243,7 @@ static void _declspec(naked) HOOK_CPlane_PreRender_1() add ecx, 84h jmp CONTINUE_CPlane_PreRender_1 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1014,13 +1257,16 @@ static void _declspec(naked) HOOK_CPlane_PreRender_1() // >>> 0x6C98C9 | 8B 45 5C | mov eax, [ebp+5Ch] // >>> 0x6C98CC | 83 C0 6C | add eax, 6Ch // 0x6C98CF | 8B 08 | mov ecx, [eax] -#define HOOKPOS_CPlane_PreRender_2 0x6C98C9 -#define HOOKSIZE_CPlane_PreRender_2 6 +#define HOOKPOS_CPlane_PreRender_2 0x6C98C9 +#define HOOKSIZE_CPlane_PreRender_2 6 static const DWORD CONTINUE_CPlane_PreRender_2 = 0x6C98CF; -static void _declspec(naked) HOOK_CPlane_PreRender_2() +static void __declspec(naked) HOOK_CPlane_PreRender_2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi // CVehicleSAInterface* @@ -1031,6 +1277,12 @@ static void _declspec(naked) HOOK_CPlane_PreRender_2() test eax, eax jz continueWithOriginalCode + // Check if dummy at offset 0x6C (TRAILER_ATTACH) is uninitialized + mov edx, [eax+6Ch] + or edx, [eax+70h] + or edx, [eax+74h] + jz continueWithOriginalCode + popad mov eax, vehicleDummiesPositionArray add eax, 6Ch @@ -1042,6 +1294,7 @@ static void _declspec(naked) HOOK_CPlane_PreRender_2() add eax, 6Ch jmp CONTINUE_CPlane_PreRender_2 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1055,13 +1308,16 @@ static void _declspec(naked) HOOK_CPlane_PreRender_2() // >>> 0x6C9B56 | 8B 45 5C | mov eax, [ebp+5Ch] // >>> 0x6C9B59 | 83 C0 78 | add eax, 78h // 0x6C9B5C | 8B 08 | mov ecx, [eax] -#define HOOKPOS_CPlane_PreRender_3 0x6C9B56 -#define HOOKSIZE_CPlane_PreRender_3 6 +#define HOOKPOS_CPlane_PreRender_3 0x6C9B56 +#define HOOKSIZE_CPlane_PreRender_3 6 static const DWORD CONTINUE_CPlane_PreRender_3 = 0x6C9B5C; -static void _declspec(naked) HOOK_CPlane_PreRender_3() +static void __declspec(naked) HOOK_CPlane_PreRender_3() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push esi // CVehicleSAInterface* @@ -1072,6 +1328,12 @@ static void _declspec(naked) HOOK_CPlane_PreRender_3() test eax, eax jz continueWithOriginalCode + // Check if dummy at offset 0x78 (HAND_REST) is uninitialized + mov edx, [eax+78h] + or edx, [eax+7Ch] + or edx, [eax+80h] + jz continueWithOriginalCode + popad mov eax, vehicleDummiesPositionArray add eax, 78h @@ -1083,6 +1345,7 @@ static void _declspec(naked) HOOK_CPlane_PreRender_3() add eax, 78h jmp CONTINUE_CPlane_PreRender_3 } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1096,13 +1359,16 @@ static void _declspec(naked) HOOK_CPlane_PreRender_3() // >>> 0x6E0E34 | 8B 49 5C | mov ecx, [ecx+5Ch] // >>> 0x6E0E37 | 8B 84 24 9C 00 00 00 | mov eax, [esp+98h+arg_0] // 0x6E0E3E | 83 F8 01 | cmp eax, 1 -#define HOOKPOS_CVehicle_DoHeadLightBeam 0x6E0E34 -#define HOOKSIZE_CVehicle_DoHeadLightBeam 10 +#define HOOKPOS_CVehicle_DoHeadLightBeam 0x6E0E34 +#define HOOKSIZE_CVehicle_DoHeadLightBeam 10 static const DWORD CONTINUE_CVehicle_DoHeadLightBeam = 0x6E0E3E; -static void _declspec(naked) HOOK_CVehicle_DoHeadLightBeam() +static void __declspec(naked) HOOK_CVehicle_DoHeadLightBeam() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push edi // CVehicleSAInterface* @@ -1113,6 +1379,12 @@ static void _declspec(naked) HOOK_CVehicle_DoHeadLightBeam() test eax, eax jz continueWithOriginalCode + // Check if LIGHT_FRONT_MAIN dummy (offset 0x00) is uninitialized + mov edx, [eax] + or edx, [eax+4] + or edx, [eax+8] + jz continueWithOriginalCode + popad mov ecx, vehicleDummiesPositionArray mov eax, [esp+98h+4h] @@ -1124,6 +1396,7 @@ static void _declspec(naked) HOOK_CVehicle_DoHeadLightBeam() mov eax, [esp+98h+4h] jmp CONTINUE_CVehicle_DoHeadLightBeam } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_VehicleLights.cpp b/Client/multiplayer_sa/CMultiplayerSA_VehicleLights.cpp index 52cb5b626a1..4a371de5160 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_VehicleLights.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_VehicleLights.cpp @@ -14,7 +14,7 @@ namespace { // Used to save state between CVehicle_DoTailLightEffect_Mid and CVehicle_DoTailLightEffect_Mid2 uint bCameraFacingCorona = false; -} // namespace +} // namespace ////////////////////////////////////////////////////////////////////////////////////////// // @@ -25,13 +25,16 @@ namespace // ////////////////////////////////////////////////////////////////////////////////////////// // Hook info -#define HOOKPOS_CVehicle_DoTailLightEffect_Mid 0x006E18E5 -#define HOOKSIZE_CVehicle_DoTailLightEffect_Mid 6 -#define HOOKCHECK_CVehicle_DoTailLightEffect_Mid 0x0F -DWORD RETURN_CVehicle_DoTailLightEffect_Mid = 0x006E18EB; -void _declspec(naked) HOOK_CVehicle_DoTailLightEffect_Mid() +#define HOOKPOS_CVehicle_DoTailLightEffect_Mid 0x006E18E5 +#define HOOKSIZE_CVehicle_DoTailLightEffect_Mid 6 +#define HOOKCHECK_CVehicle_DoTailLightEffect_Mid 0x0F +DWORD RETURN_CVehicle_DoTailLightEffect_Mid = 0x006E18EB; +static void __declspec(naked) HOOK_CVehicle_DoTailLightEffect_Mid() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Save result of comparing camera and corona direction mov eax, 0 @@ -42,6 +45,7 @@ void _declspec(naked) HOOK_CVehicle_DoTailLightEffect_Mid() mov bCameraFacingCorona, eax jmp RETURN_CVehicle_DoTailLightEffect_Mid } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -52,14 +56,17 @@ void _declspec(naked) HOOK_CVehicle_DoTailLightEffect_Mid() // ////////////////////////////////////////////////////////////////////////////////////////// // Hook info -#define HOOKPOS_CVehicle_DoTailLightEffect_Mid2 0x006E19E6 -#define HOOKSIZE_CVehicle_DoTailLightEffect_Mid2 10 -#define HOOKCHECK_CVehicle_DoTailLightEffect_Mid2 0x8B -DWORD RETURN_CVehicle_DoTailLightEffect_Mid2 = 0x006E19F0; -DWORD RETURN_CVehicle_DoTailLightEffect_Mid2_NoCorona = 0x006E1A32; -void _declspec(naked) HOOK_CVehicle_DoTailLightEffect_Mid2() +#define HOOKPOS_CVehicle_DoTailLightEffect_Mid2 0x006E19E6 +#define HOOKSIZE_CVehicle_DoTailLightEffect_Mid2 10 +#define HOOKCHECK_CVehicle_DoTailLightEffect_Mid2 0x8B +DWORD RETURN_CVehicle_DoTailLightEffect_Mid2 = 0x006E19F0; +DWORD RETURN_CVehicle_DoTailLightEffect_Mid2_NoCorona = 0x006E1A32; +static void __declspec(naked) HOOK_CVehicle_DoTailLightEffect_Mid2() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { movzx eax, byte ptr [esp+0Fh] test al, al @@ -78,6 +85,7 @@ void _declspec(naked) HOOK_CVehicle_DoTailLightEffect_Mid2() sub esp, 54h jmp RETURN_CVehicle_DoTailLightEffect_Mid2_NoCorona } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_VehicleWeapons.cpp b/Client/multiplayer_sa/CMultiplayerSA_VehicleWeapons.cpp index e6c7afec211..543b2e12034 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_VehicleWeapons.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_VehicleWeapons.cpp @@ -40,8 +40,8 @@ static void TriggerVehicleWeaponHitEvent(EVehicleWeaponType weaponType, CVehicle // 0x729324 | 0F 84 1C 02 00 00 | jz 0x729546 // >>> 0x72932A | 68 CD CC 4C 3E | push 3E4CCCCDh // 0x72932F | 68 00 00 80 3F | push 3F800000h -#define HOOKPOS_CWaterCannon__Render 0x72932A -#define HOOKSIZE_CWaterCannon__Render 5 +#define HOOKPOS_CWaterCannon__Render 0x72932A +#define HOOKSIZE_CWaterCannon__Render 5 static DWORD CONTINUE_CWaterCannon__Render = 0x72932F; static void HandleWaterCannonHit(CVehicleSAInterface* pGameVehicle, CColPointSAInterface* pColPoint, CEntitySAInterface** ppHitGameEntity) @@ -55,9 +55,12 @@ static void HandleWaterCannonHit(CVehicleSAInterface* pGameVehicle, CColPointSAI TriggerVehicleWeaponHitEvent(EVehicleWeaponType::WATER_CANNON, pGameVehicle, pHitGameEntity, pColPoint->Position, iModel, pColPoint->ucSurfaceTypeB); } -static void _declspec(naked) HOOK_CWaterCannon__Render() +static void __declspec(naked) HOOK_CWaterCannon__Render() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov eax, [ebx] // CVehicleSAInterface* CWaterCannon::m_pVehicle @@ -72,6 +75,7 @@ static void _declspec(naked) HOOK_CWaterCannon__Render() push 3E4CCCCDh jmp CONTINUE_CWaterCannon__Render } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp b/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp index dc9eaa887c9..610f9a55f9d 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp @@ -31,13 +31,16 @@ static bool __fastcall AreVehicleDoorsUndamageable(CVehicleSAInterface* vehicle) // 0x6C2321 | 56 | push esi // 0x6C2322 | 0F B6 74 24 0C | movzx esi, [esp + doorId] // 0x6C2327 | 85 F6 | test esi, esi -#define HOOKPOS_CDamageManager__ProgressDoorDamage 0x6C2320 -#define HOOKSIZE_CDamageManager__ProgressDoorDamage 7 +#define HOOKPOS_CDamageManager__ProgressDoorDamage 0x6C2320 +#define HOOKSIZE_CDamageManager__ProgressDoorDamage 7 static DWORD CONTINUE_CDamageManager__ProgressDoorDamage = 0x6C2327; -static void _declspec(naked) HOOK_CDamageManager__ProgressDoorDamage() +static void __declspec(naked) HOOK_CDamageManager__ProgressDoorDamage() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad mov ecx, [esp + 08h] // CAutomobileSAInterface* @@ -56,6 +59,7 @@ static void _declspec(naked) HOOK_CDamageManager__ProgressDoorDamage() movzx esi, [esp + 0Ch] jmp CONTINUE_CDamageManager__ProgressDoorDamage } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/multiplayer_sa/CMultiplayerSA_Weapons.cpp b/Client/multiplayer_sa/CMultiplayerSA_Weapons.cpp index 45174f4f692..4fb0d36b872 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Weapons.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Weapons.cpp @@ -51,12 +51,15 @@ void OnMY_CWeapon_GenerateDamageEvent(DWORD calledFrom, CPedSAInterface* pPed, C } // Hook info -#define HOOKPOS_CWeapon_GenerateDamageEvent 0x73A530 -#define HOOKSIZE_CWeapon_GenerateDamageEvent 7 -DWORD RETURN_CWeapon_GenerateDamageEvent = 0x73A537; -void _declspec(naked) HOOK_CWeapon_GenerateDamageEvent() +#define HOOKPOS_CWeapon_GenerateDamageEvent 0x73A530 +#define HOOKSIZE_CWeapon_GenerateDamageEvent 7 +DWORD RETURN_CWeapon_GenerateDamageEvent = 0x73A537; +static void __declspec(naked) HOOK_CWeapon_GenerateDamageEvent() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push [esp+32+4*6] @@ -74,6 +77,7 @@ void _declspec(naked) HOOK_CWeapon_GenerateDamageEvent() push 848E10h jmp RETURN_CWeapon_GenerateDamageEvent } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -85,8 +89,8 @@ void _declspec(naked) HOOK_CWeapon_GenerateDamageEvent() ////////////////////////////////////////////////////////////////////////////////////////// // Hook info -#define HOOKPOS_CShotInfo_Update 0x739E60 -#define HOOKSIZE_CShotInfo_Update 6 +#define HOOKPOS_CShotInfo_Update 0x739E60 +#define HOOKSIZE_CShotInfo_Update 6 DWORD RETURN_CShotInfo_Update = 0x739E66; // Clear all shotinfos @@ -100,12 +104,13 @@ void ResetShotInfoArray() memcpy(pInfo + i, pInfo, sizeof(CFlameShotInfo)); } -#pragma warning( push ) -#pragma warning( disable : 4731 ) // warning C4731: 'Call_CShotInfo_Update' : frame pointer register 'ebp' modified by inline assembly code +#pragma warning(push) +#pragma warning(disable : 4731) // warning C4731: 'Call_CShotInfo_Update' : frame pointer register 'ebp' modified by inline assembly code void Call_CShotInfo_Update() { - _asm + // clang-format off + __asm { call inner jmp done @@ -116,9 +121,10 @@ void Call_CShotInfo_Update() jmp RETURN_CShotInfo_Update done: } + // clang-format on } -#pragma warning( pop ) +#pragma warning(pop) // Our code for when CShotInfo_Update is called void OnMY_CShotInfo_Update() @@ -142,15 +148,19 @@ void OnMY_CShotInfo_Update() } // The hook goes here -void _declspec(naked) HOOK_CShotInfo_Update() +static void __declspec(naked) HOOK_CShotInfo_Update() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad call OnMY_CShotInfo_Update popad retn } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -171,21 +181,24 @@ int OnMY_Fx_AddBulletImpact(int iType) if (iType == 2 || iType == 4) { if (ms_LastFxTimer.Get() > 500) - ms_LastFxTimer.Reset(); // Allow once every 500ms + ms_LastFxTimer.Reset(); // Allow once every 500ms else - iType = 1; // Otherwise replace with spark + iType = 1; // Otherwise replace with spark } return iType; } // Hook info -#define HOOKPOS_Fx_AddBulletImpact 0x049F3E8 -#define HOOKSIZE_Fx_AddBulletImpact 5 +#define HOOKPOS_Fx_AddBulletImpact 0x049F3E8 +#define HOOKSIZE_Fx_AddBulletImpact 5 DWORD RETURN_Fx_AddBulletImpact = 0x049F3ED; -void _declspec(naked) HOOK_Fx_AddBulletImpact() +static void __declspec(naked) HOOK_Fx_AddBulletImpact() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad push eax @@ -198,21 +211,25 @@ void _declspec(naked) HOOK_Fx_AddBulletImpact() mov eax, ds:0x0B6F03C jmp RETURN_Fx_AddBulletImpact } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// // // CVisibilityPlugins::RenderWeaponPedsForPC -// +// // Fix for the bright objects after weapon change sometimes -// +// ////////////////////////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CVisibilityPlugins_RenderWeaponPedsForPC 0x733123 +#define HOOKPOS_CVisibilityPlugins_RenderWeaponPedsForPC 0x733123 #define HOOKSIZE_CVisibilityPlugins_RenderWeaponPedsForPC 5 -static constexpr DWORD CONTINUE_CVisibilityPlugins_RenderWeaponPedsForPC = 0x733128; -static void _declspec(naked) HOOK_CVisibilityPlugins_RenderWeaponPedsForPC() +static constexpr DWORD CONTINUE_CVisibilityPlugins_RenderWeaponPedsForPC = 0x733128; +static void __declspec(naked) HOOK_CVisibilityPlugins_RenderWeaponPedsForPC() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov eax, 5DF4E0h call eax // call CPed::ResetGunFlashAlpha @@ -225,6 +242,50 @@ static void _declspec(naked) HOOK_CVisibilityPlugins_RenderWeaponPedsForPC() jmp CONTINUE_CVisibilityPlugins_RenderWeaponPedsForPC } + // clang-format on +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// CWaterLevel::TestLineAgainstWater +// +// Limit the values to world bounds, because the water level does not exceed it. +// +////////////////////////////////////////////////////////////////////////////////////////// +static void CLAMP_CWaterLevel_TestLineAgainstWater(float values[6]) +{ + for (int i = 0; i < 6; ++i) + values[i] = Clamp(-3000.0f, values[i], 3000.0f); +} + +#define HOOKPOS_CWaterLevel_TestLineAgainstWater 0x6E61B0 +#define HOOKSIZE_CWaterLevel_TestLineAgainstWater 10 +static constexpr DWORD CONTINUE_CWaterLevel_TestLineAgainstWater = 0x6E61BA; +static void _declspec(naked) HOOK_CWaterLevel_TestLineAgainstWater() +{ + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm + { + // [esp+4] from.x + // [esp+8] from.y + // [esp+12] from.z + // [esp+16] to.x + // [esp+20] to.y + // [esp+24] to.z + pushad + lea eax, [esp+32+4] + push eax + call CLAMP_CWaterLevel_TestLineAgainstWater + add esp, 4 + popad + + fld [esp+0Ch] + sub esp, 88h + jmp CONTINUE_CWaterLevel_TestLineAgainstWater + } + // clang-format on } ////////////////////////////////////////////////////////////////////////////////////////// @@ -240,4 +301,5 @@ void CMultiplayerSA::InitHooks_Weapons() EZHookInstall(CShotInfo_Update); EZHookInstall(Fx_AddBulletImpact); EZHookInstall(CVisibilityPlugins_RenderWeaponPedsForPC); + EZHookInstall(CWaterLevel_TestLineAgainstWater); } diff --git a/Client/multiplayer_sa/StdInc.h b/Client/multiplayer_sa/StdInc.h index 9396212e417..546a69176a7 100644 --- a/Client/multiplayer_sa/StdInc.h +++ b/Client/multiplayer_sa/StdInc.h @@ -1,12 +1,13 @@ // Pragmas -#pragma warning (disable:4250) +#pragma warning(disable : 4250) #include #define MTA_CLIENT #define SHARED_UTIL_WITH_HASH_MAP #define SHARED_UTIL_WITH_FAST_HASH_MAP #define SHARED_UTIL_WITH_SYS_INFO +#define MTASA_EXPORT_SHARED_UTIL #include "SharedUtil.h" #include "SharedUtil.MemAccess.h" #include diff --git a/Client/multiplayer_sa/multiplayer_hooksystem.h b/Client/multiplayer_sa/multiplayer_hooksystem.h index fb6e0df3634..16e4106d93d 100644 --- a/Client/multiplayer_sa/multiplayer_hooksystem.h +++ b/Client/multiplayer_sa/multiplayer_hooksystem.h @@ -13,19 +13,35 @@ #pragma once +#pragma warning(disable : 4102) // unreferenced label + +// This macro adds an unreferenced label to your '__declspec(naked)' hook functions, to +// point to the value of __LOCAL_SIZE, which will be examined by an external tool after +// compilation, and it must be zero. +// +// NOTE: This was copied from game_sa. Check the comment there for more details. +#define MTA_VERIFY_HOOK_LOCAL_SIZE \ + { \ + __asm { push eax } \ + ; \ + __asm { _localSize: mov eax, __LOCAL_SIZE } \ + ; \ + __asm { pop eax } \ + ; \ + } + VOID HookInstallMethod(DWORD dwInstallAddress, DWORD dwHookFunction); VOID HookInstallCall(DWORD dwInstallAddress, DWORD dwHookFunction); BOOL HookInstall(DWORD dwInstallAddress, DWORD dwHookHandler, int iJmpCodeSize); BYTE* CreateJump(DWORD dwFrom, DWORD dwTo, BYTE* ByteArray); VOID HookCheckOriginalByte(DWORD dwInstallAddress, uchar ucExpectedValue); -#define EZHookInstall(type) \ - HookInstall( HOOKPOS_##type, (DWORD)HOOK_##type, HOOKSIZE_##type ); +#define EZHookInstall(type) HookInstall(HOOKPOS_##type, (DWORD)HOOK_##type, HOOKSIZE_##type); // Check original byte before hooking #define EZHookInstallChecked(type) \ - HookCheckOriginalByte( HOOKPOS_##type, HOOKCHECK_##type ); \ - EZHookInstall( type ); + HookCheckOriginalByte(HOOKPOS_##type, HOOKCHECK_##type); \ + EZHookInstall(type); #define EZHookInstallRestore(type) \ __if_exists(RESTORE_Bytes_##type) \ @@ -35,7 +51,7 @@ VOID HookCheckOriginalByte(DWORD dwInstallAddress, uchar ucExpectedValue); assert(sizeof(RESTORE_Bytes_##type) >= RESTORE_Size_##type); \ MemCpyFast(RESTORE_Bytes_##type, (PVOID)RESTORE_Addr_##type, RESTORE_Size_##type); \ } \ - EZHookInstall( type ); + EZHookInstall(type); // Structure for holding hook info struct SHookInfo @@ -49,7 +65,7 @@ struct SHookInfo uint uiSize; }; -#define MAKE_HOOK_INFO(type) SHookInfo ( HOOKPOS_##type, HOOK_##type, HOOKSIZE_##type ) +#define MAKE_HOOK_INFO(type) SHookInfo(HOOKPOS_##type, HOOK_##type, HOOKSIZE_##type) // Structure for holding poke info struct SPokeInfo diff --git a/Client/multiplayer_sa/multiplayer_keysync.cpp b/Client/multiplayer_sa/multiplayer_keysync.cpp index 29da80d19b4..d0642824f9b 100644 --- a/Client/multiplayer_sa/multiplayer_keysync.cpp +++ b/Client/multiplayer_sa/multiplayer_keysync.cpp @@ -15,8 +15,8 @@ extern CMultiplayerSA* pMultiplayer; -DWORD dwCurrentPlayerPed = 0; // stores the player ped temporarily during hooks -DWORD dwCurrentVehicle = 0; // stores the current vehicle during the hooks +DWORD dwCurrentPlayerPed = 0; // stores the player ped temporarily during hooks +DWORD dwCurrentVehicle = 0; // stores the current vehicle during the hooks DWORD dwParameter = 0; @@ -37,6 +37,42 @@ extern float fLocalPlayerGravity; extern PreContextSwitchHandler* m_pPreContextSwitchHandler; extern PostContextSwitchHandler* m_pPostContextSwitchHandler; +#define NUM_FirstStreamEngineSlot 7 +#define NUM_LastStreamEngineSlot 16 +#define NUM_LocalVehicleAudioContext 0x0 +#define NUM_RemoteVehicleAudioContext 0x1 +#define VAR_VehicleAudioContext 0x50230C + +namespace +{ + bool HasValidVehicleAudioContext(const CAEVehicleAudioEntitySAInterface* pAudioInterface) noexcept + { + if (!pAudioInterface) + return false; + + if (pAudioInterface->m_wEngineBankSlotId >= NUM_FirstStreamEngineSlot && pAudioInterface->m_wEngineBankSlotId <= NUM_LastStreamEngineSlot) + return true; + + return pAudioInterface->m_wEngineAccelerateSoundBankId >= 0 || pAudioInterface->m_wEngineDecelerateSoundBankId >= 0; + } + + void SetVehicleAudioContext(CVehicleSA* pVehicleSA, BYTE ucContext) + { + if (ucContext == NUM_LocalVehicleAudioContext && pVehicleSA) + { + auto* pVehicleAudioEntity = pVehicleSA->GetVehicleAudioEntity(); + auto* pAudioInterface = pVehicleAudioEntity ? pVehicleAudioEntity->GetInterface() : nullptr; + if (!HasValidVehicleAudioContext(pAudioInterface)) + return; + } + + if (*reinterpret_cast(VAR_VehicleAudioContext) == ucContext) + return; + + MemPutFast(VAR_VehicleAudioContext, ucContext); + } +} + VOID InitKeysyncHooks() { // OutputDebugString("InitKeysyncHooks"); @@ -148,7 +184,7 @@ void PostContextSwitch() // Prevent the game making remote players vehicle's audio behave like locals (and deleting // radio etc when they are removed) - issue #95 - MemPutFast(0x50230C, 0x1); + SetVehicleAudioContext(nullptr, NUM_RemoteVehicleAudioContext); bRadioHackInstalled = FALSE; } @@ -201,7 +237,7 @@ VOID ReturnContextToLocalPlayer() bNotInLocalContext = false; - CPed* pLocalPlayerPed = pGameInterface->GetPools()->GetPedFromRef((DWORD)1); // the player + CPed* pLocalPlayerPed = pGameInterface->GetPools()->GetPedFromRef((DWORD)1); // the player CPedSA* pLocalPlayerPedSA = dynamic_cast(pLocalPlayerPed); if (pLocalPlayerPedSA) { @@ -222,7 +258,7 @@ VOID ReturnContextToLocalPlayer() // Store any changes to the local-players stats? if (!bLocalStatsStatic) { - assert(0); // bLocalStatsStatic is always true + assert(0); // bLocalStatsStatic is always true MemCpyFast(&localStatsData.StatTypesFloat, (void*)0xb79380, sizeof(float) * MAX_FLOAT_STATS); MemCpyFast(&localStatsData.StatTypesInt, (void*)0xb79000, sizeof(int) * MAX_INT_STATS); MemCpyFast(&localStatsData.StatReactionValue, (void*)0xb78f10, sizeof(float) * MAX_REACTION_STATS); @@ -245,7 +281,7 @@ void SwitchContext(CPed* thePed) if (thePed && !bNotInLocalContext) { // Grab the local ped and the local pad - CPed* pLocalPlayerPed = pGameInterface->GetPools()->GetPedFromRef((DWORD)1); // the player + CPed* pLocalPlayerPed = pGameInterface->GetPools()->GetPedFromRef((DWORD)1); // the player CPad* pLocalPad = pGameInterface->GetPad(); CPadSAInterface* pLocalPadInterface = ((CPadSA*)pLocalPad)->GetInterface(); @@ -253,7 +289,7 @@ void SwitchContext(CPed* thePed) if (thePed != pLocalPlayerPed) { // Store the local pad - pLocalPad->Store(); // store a copy of the local pad internally + pLocalPad->Store(); // store a copy of the local pad internally // Grab the remote data storage for the player we're context switching to CPlayerPed* thePlayerPed = dynamic_cast(thePed); @@ -301,8 +337,7 @@ void SwitchContext(CPed* thePed) pGameInterface->SetGravity(data->m_fGravity); // Disable mouselook for remote players (so the mouse doesn't affect them) - // Only disable mouselook if they're not holding a 1st-person weapon - // And if they're not under-water + // Disable mouselook if they're not holding a 1st-person weapon bool bDisableMouseLook = true; if (pWeapon) { @@ -312,6 +347,16 @@ void SwitchContext(CPed* thePed) bDisableMouseLook = false; } } + + // Disable mouse look if they're not in a fight task and not aiming (strafing) + // Fix GitHub Issue #395 + if (thePed->GetCurrentWeaponSlot() == eWeaponSlot::WEAPONSLOT_TYPE_UNARMED && data->m_pad.NewState.RightShoulder1 != 0 && + thePed->GetPedIntelligence()->GetFightTask()) + bDisableMouseLook = false; + + // Disable mouse look if they're not underwater (Ped vertical rotation when diving) + // TODO - After merge PR #4401 + bMouseLookEnabled = *(bool*)0xB6EC2E; if (bDisableMouseLook) *(bool*)0xB6EC2E = false; @@ -442,7 +487,7 @@ void SwitchContext(CVehicle* pVehicle) { // Prevent the game making remote players vehicle's audio behave like locals (and deleting // radio etc when they are removed) - issue #95 - MemPutFast(0x50230C, 0x0); + SetVehicleAudioContext(pVehicleSA, NUM_LocalVehicleAudioContext); // For tanks, to prevent our mouse movement affecting remote tanks // 006AEA25 0F85 60010000 JNZ gta_sa.006AEB8B @@ -501,10 +546,13 @@ struct CSavedRegs }; static CSavedRegs PlayerPed__ProcessControl_Saved; -VOID _declspec(naked) HOOK_CPlayerPed__ProcessControl() +static void __declspec(naked) HOOK_CPlayerPed__ProcessControl() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // Assumes no reentrancy - _asm + // clang-format off + __asm { mov dwCurrentPlayerPed, ecx @@ -519,29 +567,37 @@ VOID _declspec(naked) HOOK_CPlayerPed__ProcessControl() mov PlayerPed__ProcessControl_Saved.edi, edi pushad } + // clang-format on SwitchContext((CPedSAInterface*)dwCurrentPlayerPed); - _asm + // clang-format off + __asm { popad mov edx, FUNC_CPlayerPed__ProcessControl call edx pushad } + // clang-format on ReturnContextToLocalPlayer(); - _asm + // clang-format off + __asm { popad retn } + // clang-format on } -void _declspec(naked) CPlayerPed__ProcessControl_Abort() +static void __declspec(naked) CPlayerPed__ProcessControl_Abort() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // restore stuff mov eax, PlayerPed__ProcessControl_Saved.eax @@ -554,302 +610,385 @@ void _declspec(naked) CPlayerPed__ProcessControl_Abort() mov edi, PlayerPed__ProcessControl_Saved.edi pushad } + // clang-format on ReturnContextToLocalPlayer(); - _asm + // clang-format off + __asm { popad retn } + // clang-format on } //-------------------------------------------------------------------------------------------- -VOID _declspec(naked) HOOK_CAutomobile__ProcessControl() +static void __declspec(naked) HOOK_CAutomobile__ProcessControl() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov dwCurrentVehicle, ecx pushad } + // clang-format on SwitchContext((CVehicleSAInterface*)dwCurrentVehicle); - _asm + // clang-format off + __asm { popad mov edx, FUNC_CAutomobile__ProcessControl call edx pushad } + // clang-format on ReturnContextToLocalPlayer(); - _asm + // clang-format off + __asm { popad retn } + // clang-format on } //-------------------------------------------------------------------------------------------- -VOID _declspec(naked) HOOK_CMonsterTruck__ProcessControl() +static void __declspec(naked) HOOK_CMonsterTruck__ProcessControl() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov dwCurrentVehicle, ecx pushad } + // clang-format on SwitchContext((CVehicleSAInterface*)dwCurrentVehicle); - _asm + // clang-format off + __asm { popad mov edx, FUNC_CMonsterTruck__ProcessControl call edx pushad } + // clang-format on ReturnContextToLocalPlayer(); - _asm + // clang-format off + __asm { popad retn } + // clang-format on } //-------------------------------------------------------------------------------------------- -VOID _declspec(naked) HOOK_CTrailer__ProcessControl() +static void __declspec(naked) HOOK_CTrailer__ProcessControl() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov dwCurrentVehicle, ecx pushad } + // clang-format on SwitchContext((CVehicleSAInterface*)dwCurrentVehicle); - _asm + // clang-format off + __asm { popad mov edx, FUNC_CTrailer__ProcessControl call edx pushad } + // clang-format on ReturnContextToLocalPlayer(); - _asm + // clang-format off + __asm { popad retn } + // clang-format on } //-------------------------------------------------------------------------------------------- -VOID _declspec(naked) HOOK_CQuadBike__ProcessControl() +static void __declspec(naked) HOOK_CQuadBike__ProcessControl() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov dwCurrentVehicle, ecx pushad } + // clang-format on SwitchContext((CVehicleSAInterface*)dwCurrentVehicle); - _asm + // clang-format off + __asm { popad mov edx, FUNC_CQuadBike__ProcessControl call edx pushad } + // clang-format on ReturnContextToLocalPlayer(); - _asm + // clang-format off + __asm { popad retn } + // clang-format on } //-------------------------------------------------------------------------------------------- -VOID _declspec(naked) HOOK_CPlane__ProcessControl() +static void __declspec(naked) HOOK_CPlane__ProcessControl() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov dwCurrentVehicle, ecx pushad } + // clang-format on SwitchContext((CVehicleSAInterface*)dwCurrentVehicle); - _asm + // clang-format off + __asm { popad mov edx, FUNC_CPlane__ProcessControl call edx pushad } + // clang-format on ReturnContextToLocalPlayer(); - _asm + // clang-format off + __asm { popad retn } + // clang-format on } //-------------------------------------------------------------------------------------------- -VOID _declspec(naked) HOOK_CBmx__ProcessControl() +static void __declspec(naked) HOOK_CBmx__ProcessControl() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov dwCurrentVehicle, ecx pushad } + // clang-format on SwitchContext((CVehicleSAInterface*)dwCurrentVehicle); - _asm + // clang-format off + __asm { popad mov edx, FUNC_CBmx__ProcessControl call edx pushad } + // clang-format on ReturnContextToLocalPlayer(); - _asm + // clang-format off + __asm { popad retn } + // clang-format on } //-------------------------------------------------------------------------------------------- -VOID _declspec(naked) HOOK_CTrain__ProcessControl() +static void __declspec(naked) HOOK_CTrain__ProcessControl() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov dwCurrentVehicle, ecx pushad } + // clang-format on SwitchContext((CVehicleSAInterface*)dwCurrentVehicle); - _asm + // clang-format off + __asm { popad mov edx, FUNC_CTrain__ProcessControl call edx pushad } + // clang-format on ReturnContextToLocalPlayer(); - _asm + // clang-format off + __asm { popad retn } + // clang-format on } //-------------------------------------------------------------------------------------------- -VOID _declspec(naked) HOOK_CBoat__ProcessControl() +static void __declspec(naked) HOOK_CBoat__ProcessControl() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov dwCurrentVehicle, ecx pushad } + // clang-format on SwitchContext((CVehicleSAInterface*)dwCurrentVehicle); - _asm + // clang-format off + __asm { popad mov edx, FUNC_CBoat__ProcessControl call edx pushad } + // clang-format on ReturnContextToLocalPlayer(); - _asm + // clang-format off + __asm { popad retn } + // clang-format on } //-------------------------------------------------------------------------------------------- -VOID _declspec(naked) HOOK_CBike__ProcessControl() +static void __declspec(naked) HOOK_CBike__ProcessControl() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov dwCurrentVehicle, ecx pushad } + // clang-format on SwitchContext((CVehicleSAInterface*)dwCurrentVehicle); - _asm + // clang-format off + __asm { popad mov edx, FUNC_CBike__ProcessControl call edx pushad } + // clang-format on ReturnContextToLocalPlayer(); - _asm + // clang-format off + __asm { popad retn } + // clang-format on } //-------------------------------------------------------------------------------------------- -VOID _declspec(naked) HOOK_CHeli__ProcessControl() +static void __declspec(naked) HOOK_CHeli__ProcessControl() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov dwCurrentVehicle, ecx pushad } + // clang-format on SwitchContext((CVehicleSAInterface*)dwCurrentVehicle); - _asm + // clang-format off + __asm { popad mov edx, FUNC_CHeli__ProcessControl call edx pushad } + // clang-format on ReturnContextToLocalPlayer(); - _asm + // clang-format off + __asm { popad retn } + // clang-format on } diff --git a/Client/multiplayer_sa/multiplayer_keysync.h b/Client/multiplayer_sa/multiplayer_keysync.h index ec0e13e7194..d95f0e2c092 100644 --- a/Client/multiplayer_sa/multiplayer_keysync.h +++ b/Client/multiplayer_sa/multiplayer_keysync.h @@ -37,44 +37,44 @@ VOID HOOK_CBike__ProcessControl(); VOID HOOK_CHeli__ProcessControl(); // gta's stuff -#define VAR_Keystates 0x7DBCB0 +#define VAR_Keystates 0x7DBCB0 -#define FUNC_CPlayerPed__ProcessControl 0x60EA90 -#define VTBL_CPlayerPed__ProcessControl 0x86D190 +#define FUNC_CPlayerPed__ProcessControl 0x60EA90 +#define VTBL_CPlayerPed__ProcessControl 0x86D190 -#define FUNC_CAutomobile__ProcessControl 0x6B1880 -#define VTBL_CAutomobile__ProcessControl 0x871148 +#define FUNC_CAutomobile__ProcessControl 0x6B1880 +#define VTBL_CAutomobile__ProcessControl 0x871148 -#define FUNC_CMonsterTruck__ProcessControl 0x6C8250 -#define VTBL_CMonsterTruck__ProcessControl 0x871800 +#define FUNC_CMonsterTruck__ProcessControl 0x6C8250 +#define VTBL_CMonsterTruck__ProcessControl 0x871800 -#define FUNC_CTrailer__ProcessControl 0x6CED20 -#define VTBL_CTrailer__ProcessControl 0x871C50 +#define FUNC_CTrailer__ProcessControl 0x6CED20 +#define VTBL_CTrailer__ProcessControl 0x871C50 -#define FUNC_CQuadBike__ProcessControl 0x6CDCC0 -#define VTBL_CQuadBike__ProcessControl 0x871B10 +#define FUNC_CQuadBike__ProcessControl 0x6CDCC0 +#define VTBL_CQuadBike__ProcessControl 0x871B10 -#define FUNC_CPlane__ProcessControl 0x6C9260 -#define VTBL_CPlane__ProcessControl 0x871970 +#define FUNC_CPlane__ProcessControl 0x6C9260 +#define VTBL_CPlane__ProcessControl 0x871970 -#define FUNC_CBmx__ProcessControl 0x6BFA30 -#define VTBL_CBmx__ProcessControl 0x871550 +#define FUNC_CBmx__ProcessControl 0x6BFA30 +#define VTBL_CBmx__ProcessControl 0x871550 -#define FUNC_CTrain__ProcessControl 0x6F86A0 -#define VTBL_CTrain__ProcessControl 0x872398 +#define FUNC_CTrain__ProcessControl 0x6F86A0 +#define VTBL_CTrain__ProcessControl 0x872398 -#define FUNC_CBoat__ProcessControl 0x6F1770 -#define VTBL_CBoat__ProcessControl 0x8721C8 +#define FUNC_CBoat__ProcessControl 0x6F1770 +#define VTBL_CBoat__ProcessControl 0x8721C8 -#define FUNC_CBike__ProcessControl 0x6B9250 -#define VTBL_CBike__ProcessControl 0x871388 +#define FUNC_CBike__ProcessControl 0x6B9250 +#define VTBL_CBike__ProcessControl 0x871388 -#define FUNC_CHeli__ProcessControl 0x6C7050 -#define VTBL_CHeli__ProcessControl 0x8716A8 +#define FUNC_CHeli__ProcessControl 0x6C7050 +#define VTBL_CHeli__ProcessControl 0x8716A8 // #define FUNC_CVehicle__ProcessUnknown 0x593030 // #define VTBL_CVehicle__ProcessUnknown 0x69ADB0 -#define CODE_SetTargetRotation 0x535851 +#define CODE_SetTargetRotation 0x535851 -#define VAR_CameraRotation 0xB6F178 +#define VAR_CameraRotation 0xB6F178 diff --git a/Client/multiplayer_sa/multiplayer_shotsync.cpp b/Client/multiplayer_sa/multiplayer_shotsync.cpp index a3cf39f8dae..306e36c8c28 100644 --- a/Client/multiplayer_sa/multiplayer_shotsync.cpp +++ b/Client/multiplayer_sa/multiplayer_shotsync.cpp @@ -21,7 +21,7 @@ extern CMultiplayerSA* pMultiplayer; std::list ShotSyncData; -CShotSyncData LocalShotSyncData; +CShotSyncData LocalShotSyncData; float* fDirectionX; float* fDirectionY; @@ -79,7 +79,7 @@ DWORD RETURN_CProjectile__CProjectile = 0x4037B3; CPools* m_pools = 0; -#define VAR_CWorld_IncludeCarTyres 0xb7cd70 // Used for CWorld_ProcessLineOfSight +#define VAR_CWorld_IncludeCarTyres 0xb7cd70 // Used for CWorld_ProcessLineOfSight void InitFireInstantHit_MidHooks(); void InitFireSniper_MidHooks(); @@ -95,7 +95,6 @@ VOID InitShotsyncHooks() HookInstall(HOOKPOS_CEventDamage__AffectsPed, (DWORD)HOOK_CEventDamage__AffectsPed, 6); HookInstall(HOOKPOS_CEventVehicleExplosion__AffectsPed, (DWORD)HOOK_CEventVehicleExplosion__AffectsPed, 5); HookInstall(HOOKPOS_CFireManager__StartFire, (DWORD)HOOK_CFireManager__StartFire, 6); - HookInstall(HOOKPOS_CFireManager__StartFire_, (DWORD)HOOK_CFireManager__StartFire_, 6); HookInstall(HOOKPOS_CProjectileInfo__AddProjectile, (DWORD)HOOK_CProjectileInfo__AddProjectile, 7); HookInstall(HOOKPOS_CProjectile__CProjectile, (DWORD)HOOK_CProjectile__CProjectile, 7); HookInstall(HOOKPOS_IKChainManager_PointArm, (DWORD)HOOK_IKChainManager_PointArm, 7); @@ -308,7 +307,7 @@ static void Event_BulletImpact() m_pBulletImpactHandler(pInitiator, pVictim, pBulletImpactStartPosition, pBulletImpactEndPosition); } } - vecSavedBulletImpactEndPosition = *pBulletImpactEndPosition; // Saved for vehicle damage event parameters + vecSavedBulletImpactEndPosition = *pBulletImpactEndPosition; // Saved for vehicle damage event parameters } } @@ -319,10 +318,13 @@ CVector* pTempVec; bool* pSkipAim; CRemoteDataStorageSA* pTempRemote; -VOID _declspec(naked) HOOK_CTaskSimpleUsegun_ProcessPed() +static void __declspec(naked) HOOK_CTaskSimpleUsegun_ProcessPed() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // We can use EAX - _asm + // clang-format off + __asm { // Store the ped pointer for our later hook (SkipAim) mov eax, [esp+4] @@ -337,6 +339,7 @@ VOID _declspec(naked) HOOK_CTaskSimpleUsegun_ProcessPed() add edx, 8 jmp edx } + // clang-format on } static CPed* GetTargetingPed() @@ -345,12 +348,15 @@ static CPed* GetTargetingPed() return pClientEntity ? pClientEntity->pEntity : nullptr; } -VOID _declspec(naked) HOOK_SkipAim() +static void __declspec(naked) HOOK_SkipAim() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // We can use ECX // Return to 0x62AEED for normal aiming // Return to 0x62A565 for arms up. Should probably set [esi+0Eh] to 1 too. - _asm + // clang-format off + __asm { // Store the pointer to the skipaim argument mov ecx, esi @@ -360,6 +366,7 @@ VOID _declspec(naked) HOOK_SkipAim() // Store all the registers pushad } + // clang-format on pATargetingPed = GetTargetingPed(); if (pATargetingPed) @@ -374,7 +381,7 @@ VOID _declspec(naked) HOOK_SkipAim() { // Grab his remote storage pTempRemote = CRemoteDataSA::GetRemoteDataStorage( - pAPed); // TODO: Can be optimized further by using the PlayerPed class. Not sure how to convert CPed to CPlayerPed + pAPed); // TODO: Can be optimized further by using the PlayerPed class. Not sure how to convert CPed to CPlayerPed if (pTempRemote) { if (pTempRemote->ProcessPlayerWeapon()) @@ -391,7 +398,8 @@ VOID _declspec(naked) HOOK_SkipAim() // Return to the correct place wheter we put our arms up or not if (*pSkipAim) { - _asm + // clang-format off + __asm { // Restore all registers popad @@ -400,10 +408,12 @@ VOID _declspec(naked) HOOK_SkipAim() mov ecx, 0x62A565 jmp ecx } + // clang-format on } else { - _asm + // clang-format off + __asm { // Restore all registers popad @@ -412,15 +422,19 @@ VOID _declspec(naked) HOOK_SkipAim() mov ecx, 0x62AEED jmp ecx } + // clang-format on } } float* pTargetVector; -VOID _declspec(naked) HOOK_IKChainManager_PointArm() +static void __declspec(naked) HOOK_IKChainManager_PointArm() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // We can use edx - _asm + // clang-format off + __asm { // Grab the ped whose aiming the gun and the pointer to the vector we aim at mov edx, [esp+24] @@ -431,6 +445,7 @@ VOID _declspec(naked) HOOK_IKChainManager_PointArm() // Store all the registers on the stack pushad } + // clang-format on pATargetingPed = GetTargetingPed(); if (pATargetingPed) @@ -447,7 +462,7 @@ VOID _declspec(naked) HOOK_IKChainManager_PointArm() { // Grab his remote storage pTempRemote = CRemoteDataSA::GetRemoteDataStorage( - pAPed); // TODO: Can be optimized further by using the PlayerPed class. Not sure how to convert CPed to CPlayerPed + pAPed); // TODO: Can be optimized further by using the PlayerPed class. Not sure how to convert CPed to CPlayerPed if (pTempRemote) { if (pTempRemote->ProcessPlayerWeapon()) @@ -461,7 +476,8 @@ VOID _declspec(naked) HOOK_IKChainManager_PointArm() } } - _asm + // clang-format off + __asm { // Restore all the registers from the stack popad @@ -475,12 +491,16 @@ VOID _declspec(naked) HOOK_IKChainManager_PointArm() add edx, 7 jmp edx } + // clang-format on } -VOID _declspec(naked) HOOK_IKChainManager_LookAt() +static void __declspec(naked) HOOK_IKChainManager_LookAt() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // We can use eax - _asm + // clang-format off + __asm { // Grab the player ped and the vector pointer from the stack mov eax, [esp+24] @@ -491,6 +511,7 @@ VOID _declspec(naked) HOOK_IKChainManager_LookAt() // Store all the registers on the stack pushad } + // clang-format on // Jax: this gets called on vehicle collision and pTargetVector is null if (pTargetVector) @@ -510,7 +531,7 @@ VOID _declspec(naked) HOOK_IKChainManager_LookAt() { // Grab his remote storage pTempRemote = CRemoteDataSA::GetRemoteDataStorage( - pAPed); // TODO: Can be optimized further by using the PlayerPed class. Not sure how to convert CPed to CPlayerPed + pAPed); // TODO: Can be optimized further by using the PlayerPed class. Not sure how to convert CPed to CPlayerPed if (pTempRemote) { if (pTempRemote->ProcessPlayerWeapon()) @@ -525,7 +546,8 @@ VOID _declspec(naked) HOOK_IKChainManager_LookAt() } } - _asm + // clang-format off + __asm { // Restore all the registers from the stack popad @@ -539,11 +561,15 @@ VOID _declspec(naked) HOOK_IKChainManager_LookAt() add edx, 7 jmp edx } + // clang-format on } -VOID _declspec(naked) HOOK_CWeapon__Fire() +static void __declspec(naked) HOOK_CWeapon__Fire() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { push ebx mov ebx, esp @@ -559,6 +585,7 @@ VOID _declspec(naked) HOOK_CWeapon__Fire() pushad } + // clang-format on // Weapon inaccuracy and animations problems may be fixed by blanking out the CWeapon variables nTimer and beyond. @@ -566,15 +593,18 @@ VOID _declspec(naked) HOOK_CWeapon__Fire() if (!WriteTargetDataForPed(pShootingPed, vecTargetPosition, vecOrigin)) { // Don't fire shot - _asm + // clang-format off + __asm { popad mov al, 1 retn 18h } + // clang-format on } - _asm + // clang-format off + __asm { popad @@ -583,25 +613,33 @@ VOID _declspec(naked) HOOK_CWeapon__Fire() push esi push edi } + // clang-format on - _asm + // clang-format off + __asm { mov esi, HOOKPOS_CWeapon__Fire add esi, 6 jmp esi } + // clang-format on } -VOID _declspec(naked) HOOK_CWeapon__PostFire() +static void __declspec(naked) HOOK_CWeapon__PostFire() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on Event_PostFire(); - _asm + // clang-format off + __asm { popad @@ -611,30 +649,40 @@ VOID _declspec(naked) HOOK_CWeapon__PostFire() add esp, 3Ch ret 18h } + // clang-format on } -VOID _declspec(naked) HOOK_CWeapon__PostFire2() // handles the FALSE exit point at 0x074241E +static void __declspec(naked) HOOK_CWeapon__PostFire2() // handles the FALSE exit point at 0x074241E { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad } + // clang-format on Event_PostFire(); - _asm + // clang-format off + __asm { popad add esp, 3Ch ret 18h } + // clang-format on } -static const DWORD CWeapon_DoBulletImpact_RET = 0x73B557; -void _declspec(naked) HOOK_CWeapon_DoBulletImpact() +static const DWORD CWeapon_DoBulletImpact_RET = 0x73B557; +static void __declspec(naked) HOOK_CWeapon_DoBulletImpact() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov eax, [esp+4] mov pBulletImpactInitiator, eax @@ -646,33 +694,41 @@ void _declspec(naked) HOOK_CWeapon_DoBulletImpact() mov pBulletImpactEndPosition, eax pushad } + // clang-format on Event_BulletImpact(); - _asm + // clang-format off + __asm { popad push 0xFFFFFFFF push 0x00848E50 jmp CWeapon_DoBulletImpact_RET } + // clang-format on } -VOID _declspec(naked) HOOK_CTaskSimpleGangDriveBy__PlayerTarget() +static void __declspec(naked) HOOK_CTaskSimpleGangDriveBy__PlayerTarget() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // Replacement code - _asm + // clang-format off + __asm { mov cTempGunDirection, al mov pPedInterfaceTemp, edi pushad } + // clang-format on // either store or change the data WriteGunDirectionDataForPed(pPedInterfaceTemp, 0, 0, &cTempGunDirection); // cTempGunDirection may be modified by the function, so write it back - _asm + // clang-format off + __asm { popad movsx eax, cTempGunDirection @@ -683,11 +739,15 @@ VOID _declspec(naked) HOOK_CTaskSimpleGangDriveBy__PlayerTarget() jmp edx } + // clang-format on } -VOID _declspec(naked) HOOK_CPedIK__PointGunInDirection() +static void __declspec(naked) HOOK_CPedIK__PointGunInDirection() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov pPedIKInterface, ecx mov edx, esp @@ -697,12 +757,14 @@ VOID _declspec(naked) HOOK_CPedIK__PointGunInDirection() mov fDirectionY, edx pushad } + // clang-format on // either store or change the data WriteGunDirectionDataForPed((CPedSAInterface*)((DWORD)pPedIKInterface - 1292), fDirectionX, fDirectionY, 0); // replacement code - _asm + // clang-format off + __asm { popad sub esp, 0x10 @@ -715,28 +777,34 @@ VOID _declspec(naked) HOOK_CPedIK__PointGunInDirection() add edx, 7 jmp edx } + // clang-format on } // This hook prevents remote players always hitting local players if both players are targeting with sniper. // This was because it then used the FireSniper mode rather than FireInstantHit so it appeared that the local // player was shooting himself! -void _declspec(naked) HOOK_CWeapon__Fire_Sniper() +static void __declspec(naked) HOOK_CWeapon__Fire_Sniper() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + /* 007424A6 8B4424 14 MOV EAX,DWORD PTR SS:[ESP+14] 007424AA 85C0 TEST EAX,EAX */ - _asm + // clang-format off + __asm { mov pPedInterfaceTemp, edi pushad } + // clang-format on if (IsLocalPlayer(pPedInterfaceTemp)) { // use sniper (local players) - _asm + // clang-format off + __asm { popad mov ecx, HOOKPOS_CWeapon__Fire_Sniper @@ -747,16 +815,19 @@ void _declspec(naked) HOOK_CWeapon__Fire_Sniper() jmp ecx } + // clang-format on } else { // use instanthit (remote players) - _asm + // clang-format off + __asm { popad mov ecx, HOOKRET_CWeapon__Fire_Sniper jmp ecx } + // clang-format on } } @@ -771,6 +842,11 @@ bool ProcessDamageEvent(CEventDamageSAInterface* event, CPedSAInterface* affects if (pPed) { + // The damage handler runs Lua events that may call CPed::Teleport + // (via setElementPosition), which nulls m_pCollidedEntity. Save and + // restore it so ScanForCollisionEvents can use it after this hook. + CEntitySAInterface* pSavedCollidedEntity = affectsPed->m_pCollidedEntity; + // This creates a CEventDamageSA for us CEventDamage* pEvent = pGameInterface->GetEventList()->GetEventDamage(event); pEvent->SetDamageReason(g_GenerateDamageEventReason); @@ -778,6 +854,9 @@ bool ProcessDamageEvent(CEventDamageSAInterface* event, CPedSAInterface* affects bool bReturn = m_pDamageHandler(pPed, pEvent); // Destroy the CEventDamageSA (so we dont get a leak) pEvent->Destroy(); + + affectsPed->m_pCollidedEntity = pSavedCollidedEntity; + // Finally, return return bReturn; } @@ -785,17 +864,20 @@ bool ProcessDamageEvent(CEventDamageSAInterface* event, CPedSAInterface* affects return true; } -CPedSAInterface* affectsPed = 0; -CEventDamageSAInterface* event = 0; -void _declspec(naked) HOOK_CEventDamage__AffectsPed() +CPedSAInterface* affectsPed = 0; +CEventDamageSAInterface* event = 0; +static void __declspec(naked) HOOK_CEventDamage__AffectsPed() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + /* 004B35A0 83EC 0C SUB ESP,0C 004B35A3 56 PUSH ESI 004B35A4 8BF1 MOV ESI,ECX */ - _asm + // clang-format off + __asm { push esi @@ -807,11 +889,13 @@ void _declspec(naked) HOOK_CEventDamage__AffectsPed() pushad } + // clang-format on if (ProcessDamageEvent(event, affectsPed)) { // they want the damage to happen! - _asm + // clang-format off + __asm { popad @@ -823,110 +907,62 @@ void _declspec(naked) HOOK_CEventDamage__AffectsPed() add ecx, 6 jmp ecx } + // clang-format on } else { // they want the player to escape unscathed - _asm + // clang-format off + __asm { popad xor eax, eax retn 4 // return from the function } - } -} - -void ProcessStartFire(CFireSAInterface* fire) -{ - if (m_pFireHandler) - { - DWORD dwID = ((DWORD)fire - 0xB71F80 /* CLASS_CFireManager */) / 40; - CFire* pFire = pGameInterface->GetFireManager()->GetFire(dwID); - if (pFire) - { - m_pFireHandler(pFire); - } - } -} - -CFireSAInterface* tempFire; -DWORD dwStoredReturn; - -// CFire* StartFire(CVector vecLocation, float fFireSize=DEFAULT_FIRE_PARTICLE_SIZE, bool8 bExtinguishEnabled=TRUE, CEntity* pStartedFireEntity = NULL, UInt32 -// ArgBurnTime = FIRE_AVERAGE_BURNTIME, Int8 NumGenerationsAllowed = 100, Bool8 bReportFire = true); -void _declspec(naked) HOOK_CFireManager__StartFire() -{ - // replacement code - _asm - { - mov edx, [esp] - mov dwStoredReturn, edx - mov edx, returnHere - mov [esp], edx - - push ecx - push ebp - mov ebp, [esp+0x10] - - mov edx, HOOKPOS_CFireManager__StartFire - add edx, 6 - jmp edx - - returnHere: - mov tempFire, eax - - pushad - } - - ProcessStartFire(tempFire); - - _asm - { - popad - - mov eax, tempFire - mov edx, dwStoredReturn - jmp edx + // clang-format on } } // CFire* StartFire(CEntity *pBurningEntity, CEntity *pStartedFireEntity, float fFireSize=DEFAULT_FIRE_PARTICLE_SIZE, bool8 bExtinguishEnabled=TRUE, UInt32 // ArgBurnTime = FIRE_AVERAGE_BURNTIME, Int8 NumGenerationsAllowed = 100); -void _declspec(naked) HOOK_CFireManager__StartFire_() +static constexpr std::uintptr_t SKIP_CFireManager_StartFire = 0x53A0C5; +static constexpr std::uintptr_t RETURN_CFireManager_StartFire = 0x53A056; + +static void __declspec(naked) HOOK_CFireManager__StartFire() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { - // replacement code - mov edx, [esp] - mov dwStoredReturn, edx - mov edx, returnHere - mov [esp], edx + push esi + push edi + mov edi, [esp+0Ch] - push esi - push edi - mov edi, [esp+0xC] + mov eax, m_pFireHandler + test eax, eax + jz startFire - // - mov edx, HOOKPOS_CFireManager__StartFire_ - add edx, 6 - jmp edx + push ecx - returnHere: - mov tempFire, eax + push [esp+14h] + push edi + call m_pFireHandler + add esp, 8 - pushad - } + pop ecx - ProcessStartFire(tempFire); + test al, al + jz abortCreatingFire - _asm - { - popad + startFire: + jmp RETURN_CFireManager_StartFire - mov eax, tempFire - jmp dwStoredReturn + abortCreatingFire: + jmp SKIP_CFireManager_StartFire } + // clang-format on } static CEntity* GetProjectileOwner(CPools* pPools) @@ -1025,9 +1061,12 @@ void ProcessProjectile() // CProjectileInfo::AddProjectile(class CEntity * owner,enum eWeaponType weapon type // ,class CVector origin?,float 0?,class CVector * direction,class CEntity * target) -void _declspec(naked) HOOK_CProjectileInfo__AddProjectile() +static void __declspec(naked) HOOK_CProjectileInfo__AddProjectile() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov edx, [esp+4] mov pProjectileOwner, edx @@ -1049,45 +1088,56 @@ void _declspec(naked) HOOK_CProjectileInfo__AddProjectile() pushad } + // clang-format on if (ProcessProjectileAdd()) - { // projectile should be created - _asm + { // projectile should be created + // clang-format off + __asm { popad push 0xFFFFFFFF mov edx, RETURN_CProjectile__AddProjectile jmp edx } + // clang-format on } else { - _asm + // clang-format off + __asm { popad xor al, al retn } + // clang-format on } } -void _declspec(naked) HOOK_CProjectile__CProjectile() +static void __declspec(naked) HOOK_CProjectile__CProjectile() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { mov dwProjectileInfoIndex, ebx // it happens to be in here, luckily mov pProjectile, ecx pushad } + // clang-format on ProcessProjectile(); - _asm + // clang-format off + __asm { popad push 0xFFFFFFFF mov edx, RETURN_CProjectile__CProjectile jmp edx } + // clang-format on } static void CheckInVehicleDamage() @@ -1106,7 +1156,8 @@ static void CheckInVehicleDamage() eWeaponType weaponType = pWeapon->GetType(); DWORD dwFunc = FUNC_CWeapon_CheckForShootingVehicleOccupant; - _asm + // clang-format off + __asm { push pInstantHitStart push pInstantHitEnd @@ -1116,6 +1167,7 @@ static void CheckInVehicleDamage() call dwFunc add esp, 0x14 } + // clang-format on } } } @@ -1163,12 +1215,15 @@ void OnMy_CWeapon_FireInstantHit_Mid(CEntitySAInterface* pEntity, CVector* pvecN } // Hook info -#define HOOKPOS_CWeapon_FireInstantHit_Mid 0x740B89 -#define HOOKSIZE_CWeapon_FireInstantHit_Mid 5 -DWORD RETURN_CWeapon_FireInstantHit_Mid = 0x740B8E; -void _declspec(naked) HOOK_CWeapon_FireInstantHit_Mid() +#define HOOKPOS_CWeapon_FireInstantHit_Mid 0x740B89 +#define HOOKSIZE_CWeapon_FireInstantHit_Mid 5 +DWORD RETURN_CWeapon_FireInstantHit_Mid = 0x740B8E; +static void __declspec(naked) HOOK_CWeapon_FireInstantHit_Mid() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { pushad @@ -1199,6 +1254,7 @@ void _declspec(naked) HOOK_CWeapon_FireInstantHit_Mid() push eax jmp RETURN_CWeapon_FireInstantHit_Mid } + // clang-format on } // Hook install @@ -1244,12 +1300,15 @@ void OnMy_CWeapon_FireSniper_Mid(CEntitySAInterface* pEntity, CVector* pvecEndHi } // Hook info -#define HOOKPOS_CWeapon_FireSniper_Mid 0x73AE31 -#define HOOKSIZE_CWeapon_FireSniper_Mid 5 -DWORD RETURN_CWeapon_FireSniper_Mid = 0x73AE39; -void _declspec(naked) HOOK_CWeapon_FireSniper_Mid() +#define HOOKPOS_CWeapon_FireSniper_Mid 0x73AE31 +#define HOOKSIZE_CWeapon_FireSniper_Mid 5 +DWORD RETURN_CWeapon_FireSniper_Mid = 0x73AE39; +static void __declspec(naked) HOOK_CWeapon_FireSniper_Mid() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Do original code fstp dword ptr [esp+4Ch] @@ -1284,6 +1343,7 @@ void _declspec(naked) HOOK_CWeapon_FireSniper_Mid() // Continue jmp RETURN_CWeapon_FireSniper_Mid } + // clang-format on } // Hook install @@ -1330,10 +1390,12 @@ void _cdecl DoFireInstantHitPokes() MemPutFast(VAR_CWorld_IncludeCarTyres, 1); } -DWORD dwFunc_CWeapon_FireInstantHit_ret = 0x740B6E; -DWORD dwFunc_CWorld_ProcessLineOfSight = 0x56BA00; -void _declspec(naked) HOOK_CWeapon_FireInstantHit() +DWORD dwFunc_CWeapon_FireInstantHit_ret = 0x740B6E; +DWORD dwFunc_CWorld_ProcessLineOfSight = 0x56BA00; +static void __declspec(naked) HOOK_CWeapon_FireInstantHit() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + /* CWeapon::FireInstantHit->CWorld::ProcessLineOfSight 00740B42 push 1 00740B44 push 0 @@ -1353,7 +1415,8 @@ void _declspec(naked) HOOK_CWeapon_FireInstantHit() 00740B68 push eax 00740B69 call 0056BA00 */ - _asm + // clang-format off + __asm { push 1 push 0 @@ -1377,29 +1440,35 @@ void _declspec(naked) HOOK_CWeapon_FireInstantHit() push eax pushad } + // clang-format on // Make sure we include car tyres in our ProcessLineOfSight check - _asm + // clang-format off + __asm { call DoFireInstantHitPokes - } + } // clang-format on HandleRemoteInstantHit(); - _asm + // clang-format off + __asm { popad call dwFunc_CWorld_ProcessLineOfSight pushad } + // clang-format on CheckInVehicleDamage(); - _asm + // clang-format off + __asm { popad jmp dwFunc_CWeapon_FireInstantHit_ret } + // clang-format on } bool FireInstantHit_CameraMode() @@ -1417,12 +1486,14 @@ bool FireInstantHit_CameraMode() return false; } -DWORD dwFunc_CWeapon_FireInstantHit_CameraMode_ret = 0x7403C7; -DWORD dwAddr_FireInstantHit_CameraMode = 0x740389; -DWORD dwAddr_FireInstantHit_CameraMode_2 = 0x740373; -short sFireInstantHit_CameraMode_camMode = 0; -void _declspec(naked) HOOK_CWeapon_FireInstantHit_CameraMode() +DWORD dwFunc_CWeapon_FireInstantHit_CameraMode_ret = 0x7403C7; +DWORD dwAddr_FireInstantHit_CameraMode = 0x740389; +DWORD dwAddr_FireInstantHit_CameraMode_2 = 0x740373; +short sFireInstantHit_CameraMode_camMode = 0; +static void __declspec(naked) HOOK_CWeapon_FireInstantHit_CameraMode() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + /* CWeapon::FireInstantHit->'CameraMode switch' 0074036D cmp ax,35h (53) ** 00740371 je 00740389 ** @@ -1433,37 +1504,45 @@ void _declspec(naked) HOOK_CWeapon_FireInstantHit_CameraMode() 0074037F cmp ax,31h (39) 00740383 jne 007407C1 */ - _asm + // clang-format off + __asm { mov sFireInstantHit_CameraMode_camMode, ax pushad } + // clang-format on if (FireInstantHit_CameraMode()) { - _asm + // clang-format off + __asm { popad jmp dwAddr_FireInstantHit_CameraMode } + // clang-format on } else { if (sFireInstantHit_CameraMode_camMode == 0x35) { - _asm + // clang-format off + __asm { popad jmp dwAddr_FireInstantHit_CameraMode } + // clang-format on } else { - _asm + // clang-format off + __asm { popad jmp dwAddr_FireInstantHit_CameraMode_2 } + // clang-format on } } } @@ -1489,10 +1568,12 @@ bool FireInstantHit_IsPlayer() return false; } -DWORD RETURN_CWeapon_FireInstantHit_IsPlayer = 0x740353; -DWORD FUNC_CPlayer_IsPed = 0x5DF8F0; -void _declspec(naked) HOOK_CWeapon_FireInstantHit_IsPlayer() +DWORD RETURN_CWeapon_FireInstantHit_IsPlayer = 0x740353; +DWORD FUNC_CPlayer_IsPed = 0x5DF8F0; +static void __declspec(naked) HOOK_CWeapon_FireInstantHit_IsPlayer() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + /* 0074034C call 005DF8F0 00740351 test al,al @@ -1508,43 +1589,52 @@ void _declspec(naked) HOOK_CWeapon_FireInstantHit_IsPlayer() 00740E6B test al,al 00740E6D je 00740E7E */ - _asm + // clang-format off + __asm { mov pFireInstantHit_IsPlayerPed, ecx pushad } + // clang-format on if (!FireInstantHit_IsPlayer()) { - _asm + // clang-format off + __asm { popad xor al, al test al, al jmp RETURN_CWeapon_FireInstantHit_IsPlayer } + // clang-format on } else { - _asm + // clang-format off + __asm { popad call FUNC_CPlayer_IsPed test al,al jmp RETURN_CWeapon_FireInstantHit_IsPlayer } + // clang-format on } } #if false -VOID _declspec(naked) HOOK_CCamera__Find3rdPersonCamTargetVector() +static void __declspec(naked) HOOK_CCamera__Find3rdPersonCamTargetVector() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + /* 0046FB36 |. 5D POP EBP 0046FB37 |. 5E POP ESI 0046FB38 |. 5B POP EBX 0046FB39 \. C2 1800 RETN 18 */ - _asm + // clang-format off + __asm { mov ebp, esp add ebp, 0x14 @@ -1558,6 +1648,7 @@ VOID _declspec(naked) HOOK_CCamera__Find3rdPersonCamTargetVector() pushad } + // clang-format on if(IsNotInLocalContext() && GetContextSwitchPedID()) { @@ -1604,7 +1695,8 @@ VOID _declspec(naked) HOOK_CCamera__Find3rdPersonCamTargetVector() OutputDebugString(szDebug);*/ } - _asm + // clang-format off + __asm { popad @@ -1613,10 +1705,13 @@ VOID _declspec(naked) HOOK_CCamera__Find3rdPersonCamTargetVector() pop ebx retn 0x18 } + // clang-format on } -VOID _declspec(naked) HOOK_CWeapon__FireShotgun() +static void __declspec(naked) HOOK_CWeapon__FireShotgun() { + MTA_VERIFY_HOOK_LOCAL_SIZE; + // this is used to store and replace the CrossProduct /* 005CDA99 . 50 PUSH EAX @@ -1628,14 +1723,17 @@ VOID _declspec(naked) HOOK_CWeapon__FireShotgun() 005CDAAA . 83C4 0C ADD ESP,0C */ - _asm + // clang-format off + __asm { pushad } + // clang-format on if(IsNotInLocalContext() && GetContextSwitchPedID()) { - _asm + // clang-format off + __asm { popad @@ -1646,6 +1744,7 @@ VOID _declspec(naked) HOOK_CWeapon__FireShotgun() pushad } + // clang-format on sprintf(szDebug, "Switched Cross Products to %f %f %f (0x%X)", RemotePlayerCrossProducts[GetContextSwitchPedID()].fX, RemotePlayerCrossProducts[GetContextSwitchPedID()].fY, @@ -1656,7 +1755,8 @@ VOID _declspec(naked) HOOK_CWeapon__FireShotgun() } else { - _asm + // clang-format off + __asm { popad @@ -1672,6 +1772,7 @@ VOID _declspec(naked) HOOK_CWeapon__FireShotgun() pushad } + // clang-format on MemCpy (&LocalPlayerCrossProduct, vecCrossProduct, sizeof(CVector)); sprintf(szDebug, "SHOTGUN: Saved Local Cross Product %f %f %f", @@ -1681,7 +1782,8 @@ VOID _declspec(naked) HOOK_CWeapon__FireShotgun() OutputDebugString(szDebug); } - _asm + // clang-format off + __asm { popad @@ -1689,6 +1791,7 @@ VOID _declspec(naked) HOOK_CWeapon__FireShotgun() add edx, 20 jmp edx } + // clang-format on } #endif @@ -1703,13 +1806,18 @@ void CEventVehicleExplosion_NotifyDeathmatch() CPed* pPed = pPedClientEntity ? pPedClientEntity->pEntity : nullptr; if (pPed) - m_pDeathHandler(pPed, 63, 3); + { + m_pDeathHandler(pPed, WEAPONTYPE_EXPLOSION, 3); + } } } -void _declspec(naked) HOOK_CEventVehicleExplosion__AffectsPed() +static void __declspec(naked) HOOK_CEventVehicleExplosion__AffectsPed() { - _asm + MTA_VERIFY_HOOK_LOCAL_SIZE; + + // clang-format off + __asm { // Save the ped mov CEventVehicleExplosion_pPed, edi @@ -1728,15 +1836,18 @@ void _declspec(naked) HOOK_CEventVehicleExplosion__AffectsPed() pushad } + // clang-format on // Notify Deathmatch about the death CEventVehicleExplosion_NotifyDeathmatch(); - _asm + // clang-format off + __asm { popad return_from: retn 4 } + // clang-format on } diff --git a/Client/multiplayer_sa/multiplayer_shotsync.h b/Client/multiplayer_sa/multiplayer_shotsync.h index 35fa3a57a92..7ea90b17609 100644 --- a/Client/multiplayer_sa/multiplayer_shotsync.h +++ b/Client/multiplayer_sa/multiplayer_shotsync.h @@ -18,27 +18,26 @@ // #include "../game_sa/CPedIKSA.h" -#define HOOKPOS_CWeapon__Fire 0x742300 -#define HOOKPOS_CWeapon__PostFire 0x742A02 // if the function returns true -#define HOOKPOS_CWeapon__PostFire2 0x742423 // if the function returns false -#define HOOKPOS_CPedIK__PointGunInDirection 0x5FDC00 -#define HOOKPOS_CTaskSimpleGangDriveBy__PlayerTarget 0x621A57 -#define HOOKPOS_CWeapon__Fire_Sniper 0x7424A6 -#define HOOKRET_CWeapon__Fire_Sniper 0x7424D7 -#define HOOKPOS_CEventDamage__AffectsPed 0x4B35A0 -#define HOOKPOS_CEventVehicleExplosion__AffectsPed 0x4B0E58 -#define HOOKPOS_CFireManager__StartFire 0x539F00 -#define HOOKPOS_CFireManager__StartFire_ 0x53A050 -#define HOOKPOS_CProjectileInfo__AddProjectile 0x737C80 -#define HOOKPOS_CProjectile__CProjectile 0x5A4030 -#define HOOKPOS_IKChainManager_PointArm 0x618B66 -#define HOOKPOS_IKChainManager_LookAt 0x618970 -#define HOOKPOS_IKChainManager_SkipAim 0x62AEE7 -#define HOOKPOS_CTaskSimpleUsegun_ProcessPed 0x62A380 -#define HOOKPOS_CWeapon_FireInstantHit 0x740B42 -#define HOOKPOS_CWeapon_FireInstantHit_CameraMode 0x74036D -#define HOOKPOS_CWeapon_FireInstantHit_IsPlayer 0x74034C -#define HOOKPOS_CWeapon_DoBulletImpact 0x73B550 +#define HOOKPOS_CWeapon__Fire 0x742300 +#define HOOKPOS_CWeapon__PostFire 0x742A02 // if the function returns true +#define HOOKPOS_CWeapon__PostFire2 0x742423 // if the function returns false +#define HOOKPOS_CPedIK__PointGunInDirection 0x5FDC00 +#define HOOKPOS_CTaskSimpleGangDriveBy__PlayerTarget 0x621A57 +#define HOOKPOS_CWeapon__Fire_Sniper 0x7424A6 +#define HOOKRET_CWeapon__Fire_Sniper 0x7424D7 +#define HOOKPOS_CEventDamage__AffectsPed 0x4B35A0 +#define HOOKPOS_CEventVehicleExplosion__AffectsPed 0x4B0E58 +#define HOOKPOS_CFireManager__StartFire 0x53A050 +#define HOOKPOS_CProjectileInfo__AddProjectile 0x737C80 +#define HOOKPOS_CProjectile__CProjectile 0x5A4030 +#define HOOKPOS_IKChainManager_PointArm 0x618B66 +#define HOOKPOS_IKChainManager_LookAt 0x618970 +#define HOOKPOS_IKChainManager_SkipAim 0x62AEE7 +#define HOOKPOS_CTaskSimpleUsegun_ProcessPed 0x62A380 +#define HOOKPOS_CWeapon_FireInstantHit 0x740B42 +#define HOOKPOS_CWeapon_FireInstantHit_CameraMode 0x74036D +#define HOOKPOS_CWeapon_FireInstantHit_IsPlayer 0x74034C +#define HOOKPOS_CWeapon_DoBulletImpact 0x73B550 // our stuff VOID InitShotsyncHooks(); diff --git a/Client/multiplayer_sa/multiplayersa_init.cpp b/Client/multiplayer_sa/multiplayersa_init.cpp index 015b041d71a..68ae32947a3 100644 --- a/Client/multiplayer_sa/multiplayersa_init.cpp +++ b/Client/multiplayer_sa/multiplayersa_init.cpp @@ -90,3 +90,31 @@ void CallGameEntityRenderHandler(CEntitySAInterface* pEntity) if (pGameEntityRenderHandler) pGameEntityRenderHandler(pEntity); } + +void OnRequestStreamingMemoryRelief(std::uint32_t bytesNeeded) +{ + if (!pGameInterface) + return; + + auto* pStreaming = pGameInterface->GetStreaming(); + if (!pStreaming) + return; + + pStreaming->MakeSpaceFor(bytesNeeded); +} + +static volatile bool s_bStreamingReliefRequested = false; + +void OnRequestDeferredStreamingMemoryRelief() +{ + s_bStreamingReliefRequested = true; +} + +void ProcessDeferredStreamingMemoryRelief() +{ + if (!s_bStreamingReliefRequested) + return; + + s_bStreamingReliefRequested = false; + OnRequestStreamingMemoryRelief(4 * 1024 * 1024); +} diff --git a/Client/multiplayer_sa/multiplayersa_init.h b/Client/multiplayer_sa/multiplayersa_init.h index 36361960ccf..60574460c52 100644 --- a/Client/multiplayer_sa/multiplayersa_init.h +++ b/Client/multiplayer_sa/multiplayersa_init.h @@ -16,6 +16,7 @@ #include "Common.h" #include +#include #include "../game_sa/CGameSA.h" #include "multiplayer_keysync.h" diff --git a/Client/multiplayer_sa/premake5.lua b/Client/multiplayer_sa/premake5.lua index 1d2386c9a58..6c86dfd7bc8 100644 --- a/Client/multiplayer_sa/premake5.lua +++ b/Client/multiplayer_sa/premake5.lua @@ -3,14 +3,11 @@ project "Multiplayer SA" kind "SharedLib" targetname "multiplayer_sa" targetdir(buildpath("mta")) + clangtidy "On" - -- HACK(Jusonex): Temp fix for ebp not being set in naked functions - -- VS2019 changed the evaluation order as required by the C++17 standard - -- which broke all functions marked with _declspec(naked) that call C++ code - -- Falling back to the old, C++14 implementing fixes this - -- See https://developercommunity.visualstudio.com/content/problem/549628/stack-access-broken-in-naked-function.html - -- We're not aware of any workaround to avoid rewriting multiplayer_sa - cppdialect "C++14" + -- DO NOT REMOVE OR TURN THIS OPTION ON + -- See details in game_sa/premake5.lua + editandcontinue "Off" filter "system:windows" includedirs { "../../vendor/sparsehash/src/windows" } @@ -37,32 +34,12 @@ project "Multiplayer SA" "*.cpp" } + postbuildcommands { + "%[%{!wks.location}/../utils/hookcheck.exe] -dll:%[$(TargetPath)] -ignore:\\vendor\\" + } + filter "architecture:not x86" flags { "ExcludeFromBuild" } filter "system:not windows" flags { "ExcludeFromBuild" } - - filter { "configurations:Release or configurations:Nightly", - "files:CMultiplayerSA.cpp" .. " or " .. - "files:CMultiplayerSA_1.3.cpp" .. " or " .. - "files:CMultiplayerSA_ClothesCache.cpp" .. " or " .. - "files:CMultiplayerSA_ClothesMemFix.cpp" .. " or " .. - "files:CMultiplayerSA_ClothesSpeedUp.cpp" .. " or " .. - "files:CMultiplayerSA_CrashFixHacks.cpp" .. " or " .. - "files:CMultiplayerSA_Direct3D.cpp" .. " or " .. - "files:CMultiplayerSA_Files.cpp" .. " or " .. - "files:CMultiplayerSA_FixBadAnimId.cpp" .. " or " .. - "files:CMultiplayerSA_FixLineOfSightArgs.cpp" .. " or " .. - "files:CMultiplayerSA_HookDestructors.cpp" .. " or " .. - "files:CMultiplayerSA_LicensePlate.cpp" .. " or " .. - "files:CMultiplayerSA_ObjectLODSystem.cpp" .. " or " .. - "files:CMultiplayerSA_Rendering.cpp" .. " or " .. - "files:CMultiplayerSA_RwResources.cpp" .. " or " .. - "files:CMultiplayerSA_VehicleDamage.cpp" .. " or " .. - "files:CMultiplayerSA_VehicleLights.cpp" .. " or " .. - "files:CMultiplayerSA_Weapons.cpp" .. " or " .. - "files:CPopulationSA.cpp" .. " or " .. - "files:multiplayer_keysync.cpp" .. " or " .. - "files:multiplayer_shotsync.cpp" } - buildoptions { "/Ob1" } -- Expand only functions marked as inline diff --git a/Client/sdk/Wine.h b/Client/sdk/Wine.h new file mode 100644 index 00000000000..f03f7860f78 --- /dev/null +++ b/Client/sdk/Wine.h @@ -0,0 +1,33 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * PURPOSE: Wine/Proton detection utility + * + * Multi Theft Auto is available from https://multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include + +namespace Wine +{ + ///////////////////////////////////////////////////////// + // + // IsRunningOnWine + // + // Detect if we are running under Wine/Proton + // + ///////////////////////////////////////////////////////// + inline bool IsRunningOnWine() + { + HMODULE hNtdll = GetModuleHandleA("ntdll.dll"); + if (!hNtdll) + return false; + + FARPROC wineVersion = GetProcAddress(hNtdll, "wine_get_version"); + return wineVersion != nullptr; + } +} diff --git a/Client/sdk/core/CAjaxResourceHandlerInterface.h b/Client/sdk/core/CAjaxResourceHandlerInterface.h index aa2d0c48955..aae8e1665f8 100644 --- a/Client/sdk/core/CAjaxResourceHandlerInterface.h +++ b/Client/sdk/core/CAjaxResourceHandlerInterface.h @@ -10,10 +10,13 @@ *****************************************************************************/ #pragma once +#include +#include + class CAjaxResourceHandlerInterface { public: - virtual std::vector& GetGetData() = 0; - virtual std::vector& GetPostData() = 0; - virtual void SetResponse(const SString& data) = 0; + virtual std::vector& GetGetData() = 0; + virtual std::vector& GetPostData() = 0; + virtual void SetResponse(std::string data) = 0; }; diff --git a/Client/sdk/core/CCVarsInterface.h b/Client/sdk/core/CCVarsInterface.h index 7d61d9f6de4..497538edf41 100644 --- a/Client/sdk/core/CCVarsInterface.h +++ b/Client/sdk/core/CCVarsInterface.h @@ -35,7 +35,7 @@ class CCVarsInterface // Get without needing caller temp variable template - T GetValue(const std::string& strVariable, const T& defaultValue = 0) + T GetValue(const std::string& strVariable, const T& defaultValue = {}) { T value = defaultValue; Get(strVariable, value); diff --git a/Client/sdk/core/CChatInterface.h b/Client/sdk/core/CChatInterface.h index dd929a3d1d1..71d6435c989 100644 --- a/Client/sdk/core/CChatInterface.h +++ b/Client/sdk/core/CChatInterface.h @@ -57,7 +57,7 @@ namespace Chat BOTTOM = 2 }; } - } // namespace Position + } // namespace Position namespace Text { @@ -69,8 +69,8 @@ namespace Chat RIGHT = 1 }; } - } // namespace Text -} // namespace Chat + } // namespace Text +} // namespace Chat typedef Chat::Font::eFont eChatFont; typedef Chat::ColorType::eType eChatColorType; diff --git a/Client/sdk/core/CClientBase.h b/Client/sdk/core/CClientBase.h index c4ac679ec8c..bbd8307e086 100644 --- a/Client/sdk/core/CClientBase.h +++ b/Client/sdk/core/CClientBase.h @@ -24,7 +24,7 @@ class CClientBase virtual void PreHUDRenderExecutionHandler(bool bDidUnminimize, bool bDidRecreateRenderTargets) = 0; virtual void PostFrameExecutionHandler() = 0; virtual void IdleHandler() = 0; - virtual void RestreamModel(unsigned short usModel) = 0; + virtual void RestreamModel(std::uint16_t model) = 0; virtual bool WebsiteRequestResultHandler(const std::unordered_set& newPages) = 0; diff --git a/Client/sdk/core/CClientCommands.h b/Client/sdk/core/CClientCommands.h index bc9f1689b18..90ff3b55687 100644 --- a/Client/sdk/core/CClientCommands.h +++ b/Client/sdk/core/CClientCommands.h @@ -18,4 +18,4 @@ namespace mtasa using namespace std::string_view_literals; static inline auto CMD_ALWAYS_SHOW_TRANSFERBOX = "cvar_always_show_transferbox"sv; -} // namespace mtasa +} // namespace mtasa diff --git a/Client/sdk/core/CCommandsInterface.h b/Client/sdk/core/CCommandsInterface.h index 950a1bc1dc8..c90d15a2595 100644 --- a/Client/sdk/core/CCommandsInterface.h +++ b/Client/sdk/core/CCommandsInterface.h @@ -18,8 +18,8 @@ typedef bool (*pfnExecuteCommandHandler)(const char*, const char*, bool, bool, b typedef void (*PFNCOMMAND)(const char*); -#define MAX_COMMAND_NAME_LENGTH 128 -#define MAX_COMMAND_DESCRIPTION_LENGTH 128 +#define MAX_COMMAND_NAME_LENGTH 128 +#define MAX_COMMAND_DESCRIPTION_LENGTH 128 typedef struct tagCOMMANDENTRY { diff --git a/Client/sdk/core/CCoreInterface.h b/Client/sdk/core/CCoreInterface.h index bfc30328271..07f3848e61c 100644 --- a/Client/sdk/core/CCoreInterface.h +++ b/Client/sdk/core/CCoreInterface.h @@ -24,6 +24,7 @@ #include "CTrayIconInterface.h" #include "CChatInterface.h" #include "CDiscordInterface.h" +#include "FPSLimiterInterface.h" #include "xml/CXML.h" #include @@ -41,7 +42,7 @@ enum eCoreVersion }; #ifndef WITH_TIMING_CHECKPOINTS - #define WITH_TIMING_CHECKPOINTS 1 // Comment this line to remove timing checkpoint code + #define WITH_TIMING_CHECKPOINTS 1 // Comment this line to remove timing checkpoint code #endif #if WITH_TIMING_CHECKPOINTS @@ -79,8 +80,10 @@ class CCoreInterface virtual CCVarsInterface* GetCVars() = 0; virtual CLocalizationInterface* GetLocalization() = 0; virtual CWebCoreInterface* GetWebCore() = 0; + virtual CWebCoreInterface* GetWebCoreUnchecked() = 0; // For cleanup in destructors only - bypasses initialization check virtual CTrayIconInterface* GetTrayIcon() = 0; virtual std::shared_ptr GetDiscord() = 0; + virtual FPSLimiter::FPSLimiterInterface* GetFPSLimiter() const noexcept = 0; // Temporary functions for r1 virtual void DebugEcho(const char* szText) = 0; @@ -143,18 +146,13 @@ class CCoreInterface virtual bool IsOptionalUpdateInfoRequired(const char* szHost) = 0; virtual void InitiateDataFilesFix() = 0; - virtual uint GetFrameRateLimit() = 0; - virtual void RecalculateFrameRateLimit(uint uiServerFrameRateLimit = -1, bool bLogToConsole = true) = 0; - virtual void ApplyFrameRateLimit(uint uiOverrideRate = -1) = 0; - virtual void EnsureFrameRateLimitApplied() = 0; - virtual void SetClientScriptFrameRateLimit(uint uiClientScriptFrameRateLimit) = 0; - virtual void OnPreFxRender() = 0; virtual void OnPreHUDRender() = 0; virtual uint GetMinStreamingMemory() = 0; virtual uint GetMaxStreamingMemory() = 0; virtual void OnCrashAverted(uint uiId) = 0; virtual void OnEnterCrashZone(uint uiId) = 0; + virtual void UpdateWerCrashModuleBases() = 0; virtual void LogEvent(uint uiDebugId, const char* szType, const char* szContext, const char* szBody, uint uiAddReportLogId = 0) = 0; virtual bool GetDebugIdEnabled(uint uiDebugId) = 0; virtual EDiagnosticDebugType GetDiagnosticDebug() = 0; diff --git a/Client/sdk/core/CGraphicsInterface.h b/Client/sdk/core/CGraphicsInterface.h index 50c4cdf5b1f..6a7edd5ec5c 100644 --- a/Client/sdk/core/CGraphicsInterface.h +++ b/Client/sdk/core/CGraphicsInterface.h @@ -70,12 +70,12 @@ enum eFontQuality FONT_QUALITY_DRAFT = DRAFT_QUALITY, FONT_QUALITY_PROOF = PROOF_QUALITY, -#if( WINVER >= 0x0400 ) +#if (WINVER >= 0x0400) FONT_QUALITY_NONANTIALIASED = NONANTIALIASED_QUALITY, FONT_QUALITY_ANTIALIASED = ANTIALIASED_QUALITY, #endif -#if( _WIN32_WINNT >= _WIN32_WINNT_WINXP ) +#if (_WIN32_WINNT >= _WIN32_WINNT_WINXP) FONT_QUALITY_CLEARTYPE = CLEARTYPE_QUALITY, FONT_QUALITY_CLEARTYPE_NATURAL = CLEARTYPE_NATURAL_QUALITY, #endif @@ -88,10 +88,10 @@ namespace EBlendMode enum EBlendModeType { NONE, - BLEND, // Alpha blend - ADD, // Color add (used for making composite textures with a premultiplied source) - MODULATE_ADD, // Modulate color with alpha then add (used for making composite textures with a non-premultiplied source) - OVERWRITE, // Blat everything + BLEND, // Alpha blend + ADD, // Color add (used for making composite textures with a premultiplied source) + MODULATE_ADD, // Modulate color with alpha then add (used for making composite textures with a non-premultiplied source) + OVERWRITE, // Blat everything }; } using EBlendMode::EBlendModeType; @@ -152,11 +152,13 @@ class CGraphicsInterface // Queued up drawing virtual void DrawLineQueued(float fX1, float fY1, float fX2, float fY2, float fWidth, unsigned long ulColor, bool bPostGUI) = 0; - virtual void DrawLine3DQueued(const CVector& vecBegin, const CVector& vecEnd, float fWidth, unsigned long ulColor, eRenderStage stage = eRenderStage::PRE_FX) = 0; + virtual void DrawLine3DQueued(const CVector& vecBegin, const CVector& vecEnd, float fWidth, unsigned long ulColor, + eRenderStage stage = eRenderStage::PRE_FX) = 0; virtual void DrawMaterialLine3DQueued(const CVector& vecBegin, const CVector& vecEnd, float fWidth, unsigned long ulColor, CMaterialItem* pMaterial, float fU = 0, float fV = 0, float fSizeU = 1, float fSizeV = 1, bool bRelativeUV = true, bool bFlipUV = false, - bool bUseFaceToward = false, const CVector& vecFaceToward = CVector(), eRenderStage renderStage = eRenderStage::POST_FX) = 0; + bool bUseFaceToward = false, const CVector& vecFaceToward = CVector(), + eRenderStage renderStage = eRenderStage::POST_FX) = 0; virtual void DrawRectQueued(float fX, float fY, float fWidth, float fHeight, unsigned long ulColor, bool bPostGUI, bool bSubPixelPositioning = false) = 0; @@ -193,6 +195,9 @@ class CGraphicsInterface virtual void LeavingMTARenderZone() = 0; virtual void MaybeEnteringMTARenderZone() = 0; virtual void MaybeLeavingMTARenderZone() = 0; + virtual void MarkViewportRefreshPending() = 0; + virtual void RefreshViewportIfNeeded() = 0; + virtual void ApplyMTARenderViewportIfNeeded() = 0; // Texture data manipulation virtual bool ResizeTextureData(const void* pData, uint uiDataPitch, uint uiWidth, uint uiHeight, uint d3dFormat, uint uiNewWidth, uint uiNewHeight, diff --git a/Client/sdk/core/CKeyBindsInterface.h b/Client/sdk/core/CKeyBindsInterface.h index badabc59162..b6cb07671cf 100644 --- a/Client/sdk/core/CKeyBindsInterface.h +++ b/Client/sdk/core/CKeyBindsInterface.h @@ -64,10 +64,10 @@ struct SBindableGTAControl enum class KeyBindType { UNDEFINED, - COMMAND, // bind key function args - GTA_CONTROL, // bind key gta_control - FUNCTION, // script bind key to function - CONTROL_FUNCTION, // script bind gta_control to function (pressing control, calls function) + COMMAND, // bind key function args + GTA_CONTROL, // bind key gta_control + FUNCTION, // script bind key to function + CONTROL_FUNCTION, // script bind gta_control to function (pressing control, calls function) }; class CKeyBind @@ -91,7 +91,14 @@ class CKeyBindWithState : public CKeyBind public: bool state{false}; - bool triggerState{false}; // true == "down", false == "up" + bool triggerState{false}; // true == "down", false == "up" +}; + +enum class BindingContext +{ + USER, // Created by user via /bind command + RESOURCE, // Created by resource via bindKey + SYSTEM // Created by system/default }; class CCommandBind : public CKeyBindWithState @@ -100,12 +107,14 @@ class CCommandBind : public CKeyBindWithState CCommandBind() : CKeyBindWithState(KeyBindType::COMMAND) {} public: - std::string command; - std::string arguments; - std::string resource; - std::string originalScriptKey; // Original key set by script - bool wasCreatedByScript{false}; - bool isReplacingScriptKey{false}; // true if script set key is not being used + std::string command; + std::string arguments; + std::string resource; + std::string originalScriptKey; // Original key set by script + std::string sourceResource; // Resource that created this binding + bool wasCreatedByScript{false}; + bool isReplacingScriptKey{false}; // true if script set key is not being used + BindingContext context{BindingContext::USER}; // Context of this binding }; class CKeyFunctionBind : public CKeyBindWithState @@ -174,6 +183,14 @@ class CKeyBindsInterface virtual void UserRemoveCommandBoundKey(CCommandBind* pBind) = 0; virtual CCommandBind* FindMatchingUpBind(CCommandBind* pBind) = 0; + // Context-aware binding methods + virtual bool CommandExistsInContext(const char* key, const char* command, BindingContext context, bool checkState = false, bool state = true, + const char* arguments = NULL, const char* resource = NULL) = 0; + virtual bool RemoveCommandFromContext(const char* key, const char* command, BindingContext context, bool checkState = false, bool state = true, + const char* arguments = NULL, const char* resource = NULL) = 0; + virtual bool HasAnyBindingForKey(const char* key, bool checkState = false, bool state = true) = 0; + virtual bool HasBindingInContext(const char* key, BindingContext context, bool checkState = false, bool state = true) = 0; + // Control-bind funcs virtual bool AddGTAControl(const char* szKey, const char* szControl) = 0; virtual bool AddGTAControl(const SBindableKey* pKey, SBindableGTAControl* pControl) = 0; diff --git a/Client/sdk/core/CLocalizationInterface.h b/Client/sdk/core/CLocalizationInterface.h index e5d877f999c..4c4eeee4701 100644 --- a/Client/sdk/core/CLocalizationInterface.h +++ b/Client/sdk/core/CLocalizationInterface.h @@ -12,14 +12,14 @@ #pragma once #ifdef _ -#undef _ + #undef _ #endif -#define _ g_pLocalization->Translate -#define _tc g_pLocalization->TranslateWithContext -#define _tn g_pLocalization->TranslatePlural -#define _tcn g_pLocalization->TranslatePluralWithContext -#define _td // Dummy translation tag for compile-time use only. Translation templates are generated by this, but no source code interaction +#define _ g_pLocalization->Translate +#define _tc g_pLocalization->TranslateWithContext +#define _tn g_pLocalization->TranslatePlural +#define _tcn g_pLocalization->TranslatePluralWithContext +#define _td // Dummy translation tag for compile-time use only. Translation templates are generated by this, but no source code interaction class CLanguage; diff --git a/Client/sdk/core/CRenderItemManagerInterface.h b/Client/sdk/core/CRenderItemManagerInterface.h index 4f25fb4e311..d2ed814103d 100644 --- a/Client/sdk/core/CRenderItemManagerInterface.h +++ b/Client/sdk/core/CRenderItemManagerInterface.h @@ -9,6 +9,8 @@ * *****************************************************************************/ +#pragma once + #include #include @@ -41,14 +43,14 @@ class CWebViewInterface; class CEffectTemplate; class CVectorGraphicItem; -#define RDEFAULT ((uint)-1) +#define RDEFAULT ((uint) - 1) enum ERenderFormat { RFORMAT_UNKNOWN, - RFORMAT_ARGB = 21, // D3DFMT_A8R8G8B8 - RFORMAT_XRGB = 22, // D3DFMT_X8R8G8B8 - RFORMAT_RGB = 23, // D3DFMT_R5G6B5 + RFORMAT_ARGB = 21, // D3DFMT_A8R8G8B8 + RFORMAT_XRGB = 22, // D3DFMT_X8R8G8B8 + RFORMAT_RGB = 23, // D3DFMT_R5G6B5 RFORMAT_DXT1 = '1TXD', RFORMAT_DXT2 = '2TXD', RFORMAT_DXT3 = '3TXD', @@ -159,8 +161,8 @@ class CRenderItemManagerInterface ETextureType textureType = TTYPE_TEXTURE, uint uiVolumeDepth = 1) = 0; virtual CShaderItem* CreateShader(const SString& strFile, const SString& strRootPath, bool bIsRawData, SString& strOutStatus, float fPriority, float fMaxDistance, bool bLayered, bool bDebug, int iTypeMask, const EffectMacroList& macros) = 0; - virtual CRenderTargetItem* CreateRenderTarget(uint uiSizeX, uint uiSizeY, bool bHasSurfaceFormat, bool bWithAlphaChannel, - int surfaceFormat, bool bForce = false) = 0; + virtual CRenderTargetItem* CreateRenderTarget(uint uiSizeX, uint uiSizeY, bool bHasSurfaceFormat, bool bWithAlphaChannel, int surfaceFormat, + bool bForce = false) = 0; virtual CScreenSourceItem* CreateScreenSource(uint uiSizeX, uint uiSizeY) = 0; virtual CWebBrowserItem* CreateWebBrowser(uint uiSizeX, uint uiSizeY) = 0; virtual CVectorGraphicItem* CreateVectorGraphic(uint uiSizeX, uint uiSizeY) = 0; @@ -185,7 +187,8 @@ class CRenderItemManagerInterface virtual ERenderFormat GetDepthBufferFormat() = 0; virtual void SaveReadableDepthBuffer() = 0; virtual void FlushNonAARenderTarget() = 0; - virtual void HandleStretchRect(IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestSurface, CONST RECT* pDestRect, + virtual bool IsUsingDefaultRenderTarget() = 0; + virtual HRESULT HandleStretchRect(IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestSurface, CONST RECT* pDestRect, int Filter) = 0; }; @@ -332,7 +335,7 @@ class CEffectWrap : public CRenderItem virtual void OnLostDevice(); virtual void OnResetDevice(); HRESULT Begin(UINT* pPasses, DWORD Flags, bool bWorldRender = true); - HRESULT End(); + HRESULT End(bool bDeviceOperational = true); bool ApplyCommonHandles(); bool ApplyMappedHandles(); @@ -480,18 +483,21 @@ class CFileTextureItem : public CTextureItem class CVectorGraphicItem : public CTextureItem { DECLARE_CLASS(CVectorGraphicItem, CTextureItem) - CVectorGraphicItem() : ClassInit(this) {} + CVectorGraphicItem() : ClassInit(this), m_uiLastEnsureAttempt(0), m_uiEnsureDelayMs(0) {} virtual void PostConstruct(CRenderItemManager* pRenderItemManager, uint width, uint height); virtual void PreDestruct(); virtual bool IsValid(); virtual void OnLostDevice(); virtual void OnResetDevice(); + bool TryEnsureValid(); void CreateUnderlyingData(); void ReleaseUnderlyingData(); void UpdateTexture(); virtual void Resize(const CVector2D& size); IDirect3DSurface9* m_pD3DRenderTargetSurface; + uint m_uiLastEnsureAttempt; + uint m_uiEnsureDelayMs; }; //////////////////////////////////////////////////////////////// @@ -502,13 +508,14 @@ class CVectorGraphicItem : public CTextureItem class CRenderTargetItem : public CTextureItem { DECLARE_CLASS(CRenderTargetItem, CTextureItem) - CRenderTargetItem() : ClassInit(this) {} - virtual void PostConstruct(CRenderItemManager* pManager, uint uiSizeX, uint uiSizeY, bool bHasSurfaceFormat, bool bWithAlphaChannel, - int surfaceFormat, bool bIncludeInMemoryStats); + CRenderTargetItem() : ClassInit(this), m_uiLastEnsureAttempt(0), m_uiEnsureDelayMs(0) {} + virtual void PostConstruct(CRenderItemManager* pManager, uint uiSizeX, uint uiSizeY, bool bHasSurfaceFormat, bool bWithAlphaChannel, int surfaceFormat, + bool bIncludeInMemoryStats); virtual void PreDestruct(); virtual bool IsValid(); virtual void OnLostDevice(); virtual void OnResetDevice(); + bool TryEnsureValid(); void CreateUnderlyingData(); void ReleaseUnderlyingData(); bool ReadPixels(CBuffer& outBuffer, SString& strOutError); @@ -519,6 +526,8 @@ class CRenderTargetItem : public CTextureItem IDirect3DSurface9* m_pD3DRenderTargetSurface; IDirect3DSurface9* m_pD3DZStencilSurface; IDirect3DSurface9* m_pD3DReadSurface; + uint m_uiLastEnsureAttempt; + uint m_uiEnsureDelayMs; }; //////////////////////////////////////////////////////////////// @@ -529,17 +538,20 @@ class CRenderTargetItem : public CTextureItem class CScreenSourceItem : public CTextureItem { DECLARE_CLASS(CScreenSourceItem, CTextureItem) - CScreenSourceItem() : ClassInit(this) {} + CScreenSourceItem() : ClassInit(this), m_uiLastEnsureAttempt(0), m_uiEnsureDelayMs(0) {} virtual void PostConstruct(CRenderItemManager* pRenderItemManager, uint uiSizeX, uint uiSizeY); virtual void PreDestruct(); virtual bool IsValid(); virtual void OnLostDevice(); virtual void OnResetDevice(); + bool TryEnsureValid(); void CreateUnderlyingData(); void ReleaseUnderlyingData(); IDirect3DSurface9* m_pD3DRenderTargetSurface; uint m_uiRevision; + uint m_uiLastEnsureAttempt; + uint m_uiEnsureDelayMs; }; //////////////////////////////////////////////////////////////// diff --git a/Client/sdk/core/CWebCoreInterface.h b/Client/sdk/core/CWebCoreInterface.h index 6b956907563..4797c7362d4 100644 --- a/Client/sdk/core/CWebCoreInterface.h +++ b/Client/sdk/core/CWebCoreInterface.h @@ -50,6 +50,7 @@ class CWebCoreInterface public: virtual ~CWebCoreInterface() {} virtual bool Initialise(bool gpuEnabled) = 0; + virtual bool IsInitialised() const noexcept = 0; virtual CWebViewInterface* CreateWebView(unsigned int uiWidth, unsigned int uiHeight, bool bIsLocal, CWebBrowserItem* pWebBrowserRenderItem, bool bTransparent) = 0; @@ -85,6 +86,8 @@ class CWebCoreInterface virtual void OnPreScreenshot() = 0; virtual void OnPostScreenshot() = 0; + virtual void OnFPSLimitChange(std::uint16_t fps) = 0; + virtual bool SetGlobalAudioVolume(float fVolume) = 0; virtual void WriteCustomList(const SString& strListName, const std::vector& customList, bool bReset = true) = 0; diff --git a/Client/sdk/core/CWebViewInterface.h b/Client/sdk/core/CWebViewInterface.h index aadc90ecc36..66371ac03b8 100644 --- a/Client/sdk/core/CWebViewInterface.h +++ b/Client/sdk/core/CWebViewInterface.h @@ -8,6 +8,11 @@ * *****************************************************************************/ #pragma once + +#include +#include +#include + #include "CWebCoreInterface.h" class CWebBrowserEventsInterface; @@ -17,6 +22,7 @@ class CWebViewInterface public: virtual void Initialise() = 0; virtual void SetWebBrowserEvents(CWebBrowserEventsInterface* pInterface) = 0; + virtual void ClearWebBrowserEvents(CWebBrowserEventsInterface* pInterface) = 0; virtual bool LoadURL(const SString& strURL, bool bFilterEnabled = true, const SString& strPostData = SString(), bool bURLEncoded = true) = 0; virtual bool IsLoading() = 0; virtual void SetBeingDestroyed(bool state) = 0; @@ -51,7 +57,7 @@ class CWebViewInterface virtual CVector2D GetSize() = 0; // Ajax Handlers - using ajax_callback_t = const std::function& vecGet, std::vector& vecPost)>; + using ajax_callback_t = const std::function& vecGet, std::vector& vecPost)>; virtual bool RegisterAjaxHandler(const SString& strURL) = 0; virtual bool UnregisterAjaxHandler(const SString& strURL) = 0; diff --git a/Client/sdk/core/CrashHandlerExports.h b/Client/sdk/core/CrashHandlerExports.h new file mode 100644 index 00000000000..72e6366a433 --- /dev/null +++ b/Client/sdk/core/CrashHandlerExports.h @@ -0,0 +1,46 @@ +/* + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Client/sdk/core/CrashHandlerExports.h + * PURPOSE: Crash handler exports + */ + +#pragma once + +#include + +#if !defined(BUGSUTIL_DLLINTERFACE) + #if defined(BUGSUTIL_EXPORTS) + #define BUGSUTIL_DLLINTERFACE __declspec(dllexport) + #else + #define BUGSUTIL_DLLINTERFACE + #endif +#endif + +#ifdef __cplusplus + #define MTA_CH_NOEXCEPT noexcept + #define MTA_CH_NODISCARD [[nodiscard]] +extern "C" +{ +#else + #define MTA_CH_NOEXCEPT + #define MTA_CH_NODISCARD +#endif + + MTA_CH_NODISCARD BOOL BUGSUTIL_DLLINTERFACE __stdcall EnableAllHandlersAfterInitialization(void) MTA_CH_NOEXCEPT; + +#ifdef __cplusplus + MTA_CH_NODISCARD BOOL BUGSUTIL_DLLINTERFACE __stdcall StartWatchdogThread(DWORD mainThreadId, DWORD timeoutSeconds = 20) MTA_CH_NOEXCEPT; +#else +MTA_CH_NODISCARD BOOL BUGSUTIL_DLLINTERFACE __stdcall StartWatchdogThread(DWORD mainThreadId, DWORD timeoutSeconds) MTA_CH_NOEXCEPT; +#endif + + void BUGSUTIL_DLLINTERFACE __stdcall StopWatchdogThread(void) MTA_CH_NOEXCEPT; + void BUGSUTIL_DLLINTERFACE __stdcall UpdateWatchdogHeartbeat(void) MTA_CH_NOEXCEPT; + +#ifdef __cplusplus +} +#endif + +#undef MTA_CH_NOEXCEPT +#undef MTA_CH_NODISCARD diff --git a/Client/sdk/core/D3DProxyDeviceGuids.h b/Client/sdk/core/D3DProxyDeviceGuids.h new file mode 100644 index 00000000000..f1da387dfa2 --- /dev/null +++ b/Client/sdk/core/D3DProxyDeviceGuids.h @@ -0,0 +1,21 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: sdk/core/D3DProxyDeviceGuids.h + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include + +// GUID for identifying CProxyDirect3DDevice9 instances via QueryInterface +// {B4C5C640-B3F2-4888-9D30-D41A59CC72F0} +DEFINE_GUID(CProxyDirect3DDevice9_GUID, 0xb4c5c640, 0xb3f2, 0x4888, 0x9d, 0x30, 0xd4, 0x1a, 0x59, 0xcc, 0x72, 0xf0); + +// Reset DEFINE_GUID to extern-declaration mode so subsequent GUIDs +// in other headers do not get storage allocated here. +#undef INITGUID +#include diff --git a/Client/sdk/core/FPSLimiterInterface.h b/Client/sdk/core/FPSLimiterInterface.h new file mode 100644 index 00000000000..5c8994e018f --- /dev/null +++ b/Client/sdk/core/FPSLimiterInterface.h @@ -0,0 +1,50 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: sdk/core/FPSLimiterInterface.h + * PURPOSE: Frame rate limiter interface + * + * Provides methods to manage and enforce frame rates in the + * application. + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +namespace FPSLimiter +{ + // Enum for enforcement types (replaces constexpr constants for better type safety) + enum class EnforcerType : std::uint8_t + { + None = 0, // No frame rate limit enforced (unlimited FPS) + VSync = 1, // Frame rate limited by display refresh rate + UserDefined = 2, // Frame rate limited by the user via settings menu or console variable + Client = 3, // Frame rate limited by the client script + Server = 4 // Frame rate limited by the server script + }; + DECLARE_ENUM(EnforcerType); + + class FPSLimiterInterface + { + public: + virtual ~FPSLimiterInterface() {} + + public: + virtual void Reset() = 0; // Reset all frame rate limits to default (unlimited) + + virtual std::uint16_t GetFPSTarget() const noexcept = 0; // Get the current active frame rate limit (0 = no limit) + virtual EnforcerType GetEnforcer() const noexcept = 0; // Get who is enforcing the current frame rate limit (as uint8_t from EnforcerType) + + virtual void SetServerEnforcedFPS(std::uint16_t fps) = 0; // Set the server-enforced frame rate limit (0 = no limit) + virtual void SetClientEnforcedFPS(std::uint16_t fps) = 0; // Set the client-enforced frame rate limit (0 = no limit) + virtual void SetUserDefinedFPS(std::uint16_t fps) = 0; // Set the user-defined frame rate limit (0 = no limit) + virtual void SetDisplayVSync(bool enabled) = 0; // Set the display refresh rate to cap FPS (0 = no cap) + + virtual void OnFPSLimitChange() = 0; // Event handler called when the active frame rate limit changes + virtual void OnFrameStart() = 0; // Event handler called at the start of each frame + virtual void OnFrameEnd() = 0; // Event handler called at the end of each frame + }; +} // namespace FPSLimiter diff --git a/Client/sdk/game/C3DMarker.h b/Client/sdk/game/C3DMarker.h index 151184eaf0d..43ffdd2c32d 100644 --- a/Client/sdk/game/C3DMarker.h +++ b/Client/sdk/game/C3DMarker.h @@ -23,13 +23,13 @@ struct RpClump; class C3DMarker { public: - virtual ~C3DMarker(){}; + virtual ~C3DMarker() {}; virtual void GetMatrix(CMatrix* pMatrix) = 0; virtual void SetMatrix(CMatrix* pMatrix) = 0; virtual void SetPosition(CVector* vecPosition) = 0; virtual CVector* GetPosition() = 0; - virtual DWORD GetType() = 0; // need enum? + virtual DWORD GetType() = 0; // need enum? virtual bool IsActive() = 0; virtual DWORD GetIdentifier() = 0; virtual SharedUtil::SColor GetColor() = 0; diff --git a/Client/sdk/game/CAEVehicleAudioEntity.h b/Client/sdk/game/CAEVehicleAudioEntity.h index 14549e4763e..1904b0d7166 100644 --- a/Client/sdk/game/CAEVehicleAudioEntity.h +++ b/Client/sdk/game/CAEVehicleAudioEntity.h @@ -19,10 +19,10 @@ enum eVehicleAudioType VEHICLE_AUDIO_BOAT, VEHICLE_AUDIO_HELI, VEHICLE_AUDIO_PLANE, - VEHICLE_AUDIO_SEAPLANE, // unused? + VEHICLE_AUDIO_SEAPLANE, // unused? VEHICLE_AUDIO_TRAIN = 8, - VEHICLE_AUDIO_SPECIAL, // RC vehicles, vortex, caddy, few trailers + VEHICLE_AUDIO_SPECIAL, // RC vehicles, vortex, caddy, few trailers VEHICLE_AUDIO_SILENT }; diff --git a/Client/sdk/game/CAnimBlendAssocGroup.h b/Client/sdk/game/CAnimBlendAssocGroup.h index ab679af5773..dc9873751d6 100644 --- a/Client/sdk/game/CAnimBlendAssocGroup.h +++ b/Client/sdk/game/CAnimBlendAssocGroup.h @@ -387,9 +387,9 @@ enum class eAnimID : int ANIM_ID_BIKE_DRIVEBYRHS = 203, ANIM_ID_BIKE_DRIVEBYFT = 204, ANIM_ID_BIKE_PASSENGER = 205, - ANIM_ID_BIKE_BUNNYHOP = 206, // bicycle anim - ANIM_ID_BIKE_PEDAL = 207, // bicycle anim - ANIM_ID_BIKE_SPRINT = 208, // bicycle anim + ANIM_ID_BIKE_BUNNYHOP = 206, // bicycle anim + ANIM_ID_BIKE_PEDAL = 207, // bicycle anim + ANIM_ID_BIKE_SPRINT = 208, // bicycle anim ANIM_ID_FIGHT_1 = 214, ANIM_ID_FIGHT_2 = 215, ANIM_ID_FIGHT_3 = 216, diff --git a/Client/sdk/game/CAnimManager.h b/Client/sdk/game/CAnimManager.h index 31e4c88e00e..2b1a9c1a944 100644 --- a/Client/sdk/game/CAnimManager.h +++ b/Client/sdk/game/CAnimManager.h @@ -15,7 +15,7 @@ // Get correct values #define MAX_ANIM_GROUPS 200 -#define MAX_ANIMATIONS 500 +#define MAX_ANIMATIONS 500 #define MAX_ANIM_BLOCKS 200 typedef unsigned long AssocGroupId; @@ -128,7 +128,7 @@ class CAnimManager virtual void DeleteCustomAnimHierarchyInterface(CAnimBlendHierarchySAInterface* pInterface) = 0; virtual void DeleteCustomAnimSequenceInterface(CAnimBlendSequenceSAInterface* pInterface) = 0; - virtual bool isGateWayAnimationHierarchy(CAnimBlendHierarchySAInterface* pInterface) = 0; + virtual bool isGateWayAnimationHierarchy(CAnimBlendHierarchySAInterface* pInterface) = 0; virtual const char* GetGateWayBlockName() const = 0; virtual const char* GetGateWayAnimationName() const = 0; diff --git a/Client/sdk/game/CAudioEngine.h b/Client/sdk/game/CAudioEngine.h index 7e34c646fc8..e91bea204b1 100644 --- a/Client/sdk/game/CAudioEngine.h +++ b/Client/sdk/game/CAudioEngine.h @@ -54,7 +54,7 @@ class CAudioEngine public: virtual void PlayFrontEndSound(DWORD dwSound) = 0; virtual void PlayBeatTrack(short iTrack) = 0; - virtual void SetEffectsMasterVolume(BYTE bVolume) = 0; // 64 = max volume + virtual void SetEffectsMasterVolume(BYTE bVolume) = 0; // 64 = max volume virtual void SetMusicMasterVolume(BYTE bVolume) = 0; virtual void ClearMissionAudio(int slot = 1) = 0; virtual void PreloadMissionAudio(unsigned short usAudioEvent, int slot = 1) = 0; diff --git a/Client/sdk/game/CAutomobile.h b/Client/sdk/game/CAutomobile.h index eeef7a92911..1361a0e137f 100644 --- a/Client/sdk/game/CAutomobile.h +++ b/Client/sdk/game/CAutomobile.h @@ -1,6 +1,6 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: sdk/game/CAutomobile.h * PURPOSE: Automobile vehicle entity interface @@ -20,5 +20,7 @@ class CDoor; class CAutomobile : public virtual CVehicle { public: - virtual ~CAutomobile(){}; + virtual ~CAutomobile() {}; + + virtual bool IsAnyWheelTouchingGround() const = 0; }; diff --git a/Client/sdk/game/CBike.h b/Client/sdk/game/CBike.h index 5750fa55031..44cfdcbef46 100644 --- a/Client/sdk/game/CBike.h +++ b/Client/sdk/game/CBike.h @@ -1,6 +1,6 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: sdk/game/CBike.h * PURPOSE: Bike vehicle entity interface @@ -18,9 +18,10 @@ class CBikeHandlingEntry; class CBike : public virtual CVehicle { public: - virtual ~CBike(){}; + virtual ~CBike() {}; virtual CBikeHandlingEntry* GetBikeHandlingData() = 0; virtual void SetBikeHandlingData(CBikeHandlingEntry* pHandling) = 0; virtual void RecalculateBikeHandling() = 0; + virtual bool IsAnyWheelTouchingGround() const = 0; }; diff --git a/Client/sdk/game/CBikeHandlingEntry.h b/Client/sdk/game/CBikeHandlingEntry.h index 543e718ef22..4d1ff2dfa9f 100644 --- a/Client/sdk/game/CBikeHandlingEntry.h +++ b/Client/sdk/game/CBikeHandlingEntry.h @@ -15,7 +15,7 @@ class CBikeHandlingEntry { public: // Destructor - virtual ~CBikeHandlingEntry(){}; + virtual ~CBikeHandlingEntry() {}; // Use this to copy data from an another handling class to this virtual void Assign(const CBikeHandlingEntry* pData) = 0; diff --git a/Client/sdk/game/CBmx.h b/Client/sdk/game/CBmx.h index 5f649c3dc21..04d6ed892c0 100644 --- a/Client/sdk/game/CBmx.h +++ b/Client/sdk/game/CBmx.h @@ -16,5 +16,5 @@ class CBmx : public virtual CBike { public: - virtual ~CBmx(){}; + virtual ~CBmx() {}; }; diff --git a/Client/sdk/game/CBoat.h b/Client/sdk/game/CBoat.h index 2275be6404a..826658dcde9 100644 --- a/Client/sdk/game/CBoat.h +++ b/Client/sdk/game/CBoat.h @@ -18,7 +18,7 @@ class CBoatHandlingEntry; class CBoat : public virtual CVehicle { public: - virtual ~CBoat(){}; + virtual ~CBoat() {}; virtual CBoatHandlingEntry* GetBoatHandlingData() = 0; virtual void SetBoatHandlingData(CBoatHandlingEntry* pHandling) = 0; diff --git a/Client/sdk/game/CBoatHandlingEntry.h b/Client/sdk/game/CBoatHandlingEntry.h index b7583d595ff..8f0fce87aec 100644 --- a/Client/sdk/game/CBoatHandlingEntry.h +++ b/Client/sdk/game/CBoatHandlingEntry.h @@ -15,7 +15,7 @@ class CBoatHandlingEntry { public: // Destructor - virtual ~CBoatHandlingEntry(){}; + virtual ~CBoatHandlingEntry() {}; // Use this to copy data from an another handling class to this virtual void Assign(const CBoatHandlingEntry* pData) = 0; diff --git a/Client/sdk/game/CBuilding.h b/Client/sdk/game/CBuilding.h index 8969df3daab..a7e2627eb3e 100644 --- a/Client/sdk/game/CBuilding.h +++ b/Client/sdk/game/CBuilding.h @@ -18,7 +18,7 @@ class CBuildingSAInterface; class CBuilding : public virtual CEntity { public: - virtual ~CBuilding(){}; + virtual ~CBuilding() {}; virtual CBuildingSAInterface* GetBuildingInterface() = 0; virtual void SetLod(CBuilding* pLod) = 0; diff --git a/Client/sdk/game/CBuildingRemoval.h b/Client/sdk/game/CBuildingRemoval.h index 655996f99b3..2e4ef4d2774 100644 --- a/Client/sdk/game/CBuildingRemoval.h +++ b/Client/sdk/game/CBuildingRemoval.h @@ -18,12 +18,18 @@ class CEntitySAInterface; class CVector; class CVector4D; +struct SRemovedEntity +{ + CEntitySAInterface* m_pInterface; + BYTE m_iplIndex; // cached at tracking time; used by OnRemoveIpl to skip entries from other IPLs +}; + struct SBuildingRemoval { SBuildingRemoval() { - m_pBinaryRemoveList = new std::list; - m_pDataRemoveList = new std::list; + m_pBinaryRemoveList = new std::list; + m_pDataRemoveList = new std::list; m_usModel = 0; m_vecPos = CVector(0, 0, 0); m_fRadius = 0.0f; @@ -36,23 +42,15 @@ struct SBuildingRemoval delete m_pDataRemoveList; } - void AddBinaryBuilding(CEntitySAInterface* pInterface) - { - // Add to list of binary buildings for this removal - m_pBinaryRemoveList->push_back(pInterface); - } - void AddDataBuilding(CEntitySAInterface* pInterface) - { - // Add to list of data buildings for this removal - m_pDataRemoveList->push_back(pInterface); - } + void AddBinaryBuilding(CEntitySAInterface* pInterface, BYTE iplIndex) { m_pBinaryRemoveList->push_back({pInterface, iplIndex}); } + void AddDataBuilding(CEntitySAInterface* pInterface, BYTE iplIndex) { m_pDataRemoveList->push_back({pInterface, iplIndex}); } - unsigned short m_usModel; - CVector m_vecPos; - float m_fRadius; - char m_cInterior; - std::list* m_pBinaryRemoveList; - std::list* m_pDataRemoveList; + unsigned short m_usModel; + CVector m_vecPos; + float m_fRadius; + char m_cInterior; + std::list* m_pBinaryRemoveList; + std::list* m_pDataRemoveList; }; struct sDataBuildingRemovalItem @@ -61,11 +59,13 @@ struct sDataBuildingRemovalItem { m_pInterface = pInterface; m_iCount = 0; + m_iplIndex = 0; // set in AddDataBuilding(); CEntitySAInterface is forward-decl here } void AddCount() { m_iCount++; } void RemoveCount() { m_iCount--; } CEntitySAInterface* m_pInterface; int m_iCount; + BYTE m_iplIndex; // cached at tracking time; used by OnRemoveIpl to skip entries from other IPLs }; struct sBuildingRemovalItem @@ -74,11 +74,13 @@ struct sBuildingRemovalItem { m_pInterface = pInterface; m_iCount = 0; + m_iplIndex = 0; // set in AddBinaryBuilding(); CEntitySAInterface is forward-decl here } void AddCount() { m_iCount++; } void RemoveCount() { m_iCount--; } CEntitySAInterface* m_pInterface; int m_iCount; + BYTE m_iplIndex; // cached at tracking time; used by OnRemoveIpl to skip entries from other IPLs }; struct SIPLInst @@ -120,5 +122,4 @@ class CBuildingRemoval virtual bool IsObjectRemoved(CEntitySAInterface* pInterface) = 0; virtual bool IsDataModelRemoved(uint16_t usModelID) = 0; virtual bool IsEntityRemoved(CEntitySAInterface* pInterface) = 0; - }; diff --git a/Client/sdk/game/CBuildingsPool.h b/Client/sdk/game/CBuildingsPool.h index 85ad4b87391..ea5a99f2690 100644 --- a/Client/sdk/game/CBuildingsPool.h +++ b/Client/sdk/game/CBuildingsPool.h @@ -20,7 +20,6 @@ class CBuildingSA; class CBuildingsPool { public: - // Buildings pool virtual CBuilding* AddBuilding(class CClientBuilding*, std::uint16_t modelId, CVector* vPos, CVector* vRot, std::uint8_t interior) = 0; virtual void RemoveBuilding(CBuilding* pObject) = 0; diff --git a/Client/sdk/game/CCamera.h b/Client/sdk/game/CCamera.h index e91c3ac8479..b0f6eef1863 100644 --- a/Client/sdk/game/CCamera.h +++ b/Client/sdk/game/CCamera.h @@ -17,75 +17,78 @@ class CMatrix; class CCam; struct RwMatrix; +// Camera constants +constexpr const float DEFAULT_FOV = 70.0f; + enum eCamMode { MODE_NONE = 0, - MODE_TOPDOWN, //=1, - MODE_GTACLASSIC, // =2, - MODE_BEHINDCAR, //=3, - MODE_FOLLOWPED, //=4, - MODE_AIMING, //=5, - MODE_DEBUG, //=6, - MODE_SNIPER, //=7, - MODE_ROCKETLAUNCHER, //=8, - MODE_MODELVIEW, //=9, - MODE_BILL, //=10, - MODE_SYPHON, //=11, - MODE_CIRCLE, //=12, - MODE_CHEESYZOOM, //=13, - MODE_WHEELCAM, //=14, - MODE_FIXED, //=15, - MODE_1STPERSON, //=16, - MODE_FLYBY, //=17, - MODE_CAM_ON_A_STRING, //=18, - MODE_REACTION, //=19, - MODE_FOLLOW_PED_WITH_BIND, //=20, - MODE_CHRIS, // 21 - MODE_BEHINDBOAT, //=22, - MODE_PLAYER_FALLEN_WATER, //=23, - MODE_CAM_ON_TRAIN_ROOF, //=24, - MODE_CAM_RUNNING_SIDE_TRAIN, //=25, - MODE_BLOOD_ON_THE_TRACKS, //=26, - MODE_IM_THE_PASSENGER_WOOWOO, //=27, - MODE_SYPHON_CRIM_IN_FRONT, // =28, - MODE_PED_DEAD_BABY, //=29, - MODE_PILLOWS_PAPS, //=30, - MODE_LOOK_AT_CARS, //=31, - MODE_ARRESTCAM_ONE, //=32, - MODE_ARRESTCAM_TWO, //=33, - MODE_M16_1STPERSON, //=34, - MODE_SPECIAL_FIXED_FOR_SYPHON, //=35, - MODE_FIGHT_CAM, //=36, - MODE_TOP_DOWN_PED, //=37, - MODE_LIGHTHOUSE, //=38 + MODE_TOPDOWN, //=1, + MODE_GTACLASSIC, // =2, + MODE_BEHINDCAR, //=3, + MODE_FOLLOWPED, //=4, + MODE_AIMING, //=5, + MODE_DEBUG, //=6, + MODE_SNIPER, //=7, + MODE_ROCKETLAUNCHER, //=8, + MODE_MODELVIEW, //=9, + MODE_BILL, //=10, + MODE_SYPHON, //=11, + MODE_CIRCLE, //=12, + MODE_CHEESYZOOM, //=13, + MODE_WHEELCAM, //=14, + MODE_FIXED, //=15, + MODE_1STPERSON, //=16, + MODE_FLYBY, //=17, + MODE_CAM_ON_A_STRING, //=18, + MODE_REACTION, //=19, + MODE_FOLLOW_PED_WITH_BIND, //=20, + MODE_CHRIS, // 21 + MODE_BEHINDBOAT, //=22, + MODE_PLAYER_FALLEN_WATER, //=23, + MODE_CAM_ON_TRAIN_ROOF, //=24, + MODE_CAM_RUNNING_SIDE_TRAIN, //=25, + MODE_BLOOD_ON_THE_TRACKS, //=26, + MODE_IM_THE_PASSENGER_WOOWOO, //=27, + MODE_SYPHON_CRIM_IN_FRONT, // =28, + MODE_PED_DEAD_BABY, //=29, + MODE_PILLOWS_PAPS, //=30, + MODE_LOOK_AT_CARS, //=31, + MODE_ARRESTCAM_ONE, //=32, + MODE_ARRESTCAM_TWO, //=33, + MODE_M16_1STPERSON, //=34, + MODE_SPECIAL_FIXED_FOR_SYPHON, //=35, + MODE_FIGHT_CAM, //=36, + MODE_TOP_DOWN_PED, //=37, + MODE_LIGHTHOUSE, //=38 /// all 1rst person run ablout run about modes now - MODE_SNIPER_RUNABOUT, //=39, - MODE_ROCKETLAUNCHER_RUNABOUT, //=40, - MODE_1STPERSON_RUNABOUT, //=41, - MODE_M16_1STPERSON_RUNABOUT, //=42, - MODE_FIGHT_CAM_RUNABOUT, //=43, - MODE_EDITOR, //=44, - MODE_HELICANNON_1STPERSON, //= 45 - MODE_CAMERA, // 46 - MODE_ATTACHCAM, // 47 + MODE_SNIPER_RUNABOUT, //=39, + MODE_ROCKETLAUNCHER_RUNABOUT, //=40, + MODE_1STPERSON_RUNABOUT, //=41, + MODE_M16_1STPERSON_RUNABOUT, //=42, + MODE_FIGHT_CAM_RUNABOUT, //=43, + MODE_EDITOR, //=44, + MODE_HELICANNON_1STPERSON, //= 45 + MODE_CAMERA, // 46 + MODE_ATTACHCAM, // 47 MODE_TWOPLAYER, MODE_TWOPLAYER_IN_CAR_AND_SHOOTING, - MODE_TWOPLAYER_SEPARATE_CARS, // 50 + MODE_TWOPLAYER_SEPARATE_CARS, // 50 MODE_ROCKETLAUNCHER_HS, MODE_ROCKETLAUNCHER_RUNABOUT_HS, MODE_AIMWEAPON, MODE_TWOPLAYER_SEPARATE_CARS_TOPDOWN, - MODE_AIMWEAPON_FROMCAR, // 55 + MODE_AIMWEAPON_FROMCAR, // 55 MODE_DW_HELI_CHASE, MODE_DW_CAM_MAN, MODE_DW_BIRDY, MODE_DW_PLANE_SPOTTER, - MODE_DW_DOG_FIGHT, // 60 + MODE_DW_DOG_FIGHT, // 60 MODE_DW_FISH, MODE_DW_PLANECAM1, MODE_DW_PLANECAM2, MODE_DW_PLANECAM3, - MODE_AIMWEAPON_ATTACHED // 65 + MODE_AIMWEAPON_ATTACHED // 65 }; enum class eVehicleCamMode @@ -147,5 +150,8 @@ class CCamera virtual void ShakeCamera(float radius, float x, float y, float z) noexcept = 0; virtual void ResetShakeCamera() noexcept = 0; - virtual std::uint8_t GetTransitionState() = 0; + virtual std::uint8_t GetTransitionState() const = 0; + virtual bool IsInTransition() const = 0; + virtual float GetTransitionFOV() const = 0; + virtual bool GetTransitionMatrix(CMatrix& matrix) const = 0; }; diff --git a/Client/sdk/game/CCheckpoint.h b/Client/sdk/game/CCheckpoint.h index b5a7f8de777..c298c30f181 100644 --- a/Client/sdk/game/CCheckpoint.h +++ b/Client/sdk/game/CCheckpoint.h @@ -21,9 +21,9 @@ class CVector; enum { - CHECKPOINT_TUBE, // a long tube with arrow as direction - CHECKPOINT_ENDTUBE, // finish flag long tube checkpoint - CHECKPOINT_EMPTYTUBE, // just a long tube checkpoint + CHECKPOINT_TUBE, // a long tube with arrow as direction + CHECKPOINT_ENDTUBE, // finish flag long tube checkpoint + CHECKPOINT_EMPTYTUBE, // just a long tube checkpoint CHECKPOINT_TORUS, CHECKPOINT_TORUS_NOFADE, CHECKPOINT_TORUSROT, @@ -40,7 +40,7 @@ class CCheckpoint virtual CVector* GetPosition() = 0; virtual void SetPointDirection(CVector* vecPointDirection) = 0; virtual CVector* GetPointDirection() = 0; - virtual DWORD GetType() = 0; // need enum? + virtual DWORD GetType() = 0; // need enum? virtual bool IsActive() = 0; virtual DWORD GetIdentifier() = 0; virtual SharedUtil::SColor GetColor() = 0; diff --git a/Client/sdk/game/CColPoint.h b/Client/sdk/game/CColPoint.h index 26cac7c4da4..c4e1337e7bf 100644 --- a/Client/sdk/game/CColPoint.h +++ b/Client/sdk/game/CColPoint.h @@ -214,15 +214,15 @@ C_ASSERT(sizeof(EColSurface) == 1); // Collision stored lighting struct CColLighting { - uchar day : 4; // 0-15 - uchar night : 4; // 0-15 + uchar day : 4; // 0-15 + uchar night : 4; // 0-15 }; C_ASSERT(sizeof(CColLighting) == 1); class CColPoint { public: - virtual ~CColPoint(){}; + virtual ~CColPoint() {}; virtual CColPointSAInterface* GetInterface() = 0; virtual const CVector& GetPosition() = 0; diff --git a/Client/sdk/game/CCollision.h b/Client/sdk/game/CCollision.h index e286c4c82f1..544392566a3 100644 --- a/Client/sdk/game/CCollision.h +++ b/Client/sdk/game/CCollision.h @@ -14,7 +14,8 @@ struct CColLineSA; struct CColSphereSA; -class CCollision { +class CCollision +{ public: virtual bool TestLineSphere(const CColLineSA& line, const CColSphereSA& sphere) const = 0; }; diff --git a/Client/sdk/game/CControllerConfigManager.h b/Client/sdk/game/CControllerConfigManager.h index 05ac4b139a4..91b280f3b23 100644 --- a/Client/sdk/game/CControllerConfigManager.h +++ b/Client/sdk/game/CControllerConfigManager.h @@ -22,9 +22,9 @@ #define GTA_KEY_MXB2 7 #define GTA_KEY_SPACE 32 #define GTA_KEY_COMMA 44 -#define GTA_KEY_MINUS 45 /* - on main keyboard */ -#define GTA_KEY_PERIOD 46 /* . on main keyboard */ -#define GTA_KEY_SLASH 47 /* / on main keyboard */ +#define GTA_KEY_MINUS 45 /* - on main keyboard */ +#define GTA_KEY_PERIOD 46 /* . on main keyboard */ +#define GTA_KEY_SLASH 47 /* / on main keyboard */ #define GTA_KEY_0 48 #define GTA_KEY_1 49 #define GTA_KEY_2 50 @@ -68,7 +68,7 @@ #define GTA_KEY_LBRACKET 91 #define GTA_KEY_BACKSLASH 92 #define GTA_KEY_RBRACKET 93 -#define GTA_KEY_GRAVE 96 /* accent grave */ +#define GTA_KEY_GRAVE 96 /* accent grave */ #define GTA_KEY_F1 1001 #define GTA_KEY_F2 1002 #define GTA_KEY_F3 1003 @@ -81,21 +81,21 @@ #define GTA_KEY_F10 1010 #define GTA_KEY_F11 1011 #define GTA_KEY_F12 1012 -#define GTA_KEY_INSERT 1013 /* Insert on arrow keypad */ -#define GTA_KEY_DELETE 1014 /* Delete on arrow keypad */ -#define GTA_KEY_HOME 1015 /* Home on arrow keypad */ -#define GTA_KEY_END 1016 /* End on arrow keypad */ -#define GTA_KEY_PGUP 1017 /* PgUp on arrow keypad */ -#define GTA_KEY_PGDN 1018 /* PgDn on arrow keypad */ -#define GTA_KEY_UP 1019 /* UpArrow on arrow keypad */ -#define GTA_KEY_DOWN 1020 /* DownArrow on arrow keypad */ -#define GTA_KEY_LEFT 1021 /* LeftArrow on arrow keypad */ -#define GTA_KEY_RIGHT 1022 /* RightArrow on arrow keypad */ -#define GTA_KEY_DIVIDE 1023 /* / on numeric keypad */ -#define GTA_KEY_MULTIPLY 1024 /* * on numeric keypad */ -#define GTA_KEY_ADD 1025 /* + on numeric keypad */ -#define GTA_KEY_SUBTRACT 1026 /* - on numeric keypad */ -#define GTA_KEY_DECIMAL 1027 /* . on numeric keypad */ +#define GTA_KEY_INSERT 1013 /* Insert on arrow keypad */ +#define GTA_KEY_DELETE 1014 /* Delete on arrow keypad */ +#define GTA_KEY_HOME 1015 /* Home on arrow keypad */ +#define GTA_KEY_END 1016 /* End on arrow keypad */ +#define GTA_KEY_PGUP 1017 /* PgUp on arrow keypad */ +#define GTA_KEY_PGDN 1018 /* PgDn on arrow keypad */ +#define GTA_KEY_UP 1019 /* UpArrow on arrow keypad */ +#define GTA_KEY_DOWN 1020 /* DownArrow on arrow keypad */ +#define GTA_KEY_LEFT 1021 /* LeftArrow on arrow keypad */ +#define GTA_KEY_RIGHT 1022 /* RightArrow on arrow keypad */ +#define GTA_KEY_DIVIDE 1023 /* / on numeric keypad */ +#define GTA_KEY_MULTIPLY 1024 /* * on numeric keypad */ +#define GTA_KEY_ADD 1025 /* + on numeric keypad */ +#define GTA_KEY_SUBTRACT 1026 /* - on numeric keypad */ +#define GTA_KEY_DECIMAL 1027 /* . on numeric keypad */ #define GTA_KEY_NUMPAD1 1028 #define GTA_KEY_NUMPAD2 1029 #define GTA_KEY_NUMPAD3 1030 @@ -107,21 +107,21 @@ #define GTA_KEY_NUMPAD8 1036 #define GTA_KEY_NUMPAD9 1037 #define GTA_KEY_NUMPAD0 1038 -#define GTA_KEY_NUMPADENTER 1039 /* Enter on numeric keypad */ -#define GTA_KEY_SCROLL 1040 /* Scroll Lock */ -#define GTA_KEY_PAUSE 1041 /* Pause */ -#define GTA_KEY_BACK 1042 /* backspace */ +#define GTA_KEY_NUMPADENTER 1039 /* Enter on numeric keypad */ +#define GTA_KEY_SCROLL 1040 /* Scroll Lock */ +#define GTA_KEY_PAUSE 1041 /* Pause */ +#define GTA_KEY_BACK 1042 /* backspace */ #define GTA_KEY_TAB 1043 -#define GTA_KEY_CAPSLOCK 1044 /* Caps Lock */ -#define GTA_KEY_RETURN 1045 /* Enter on main keyboard */ +#define GTA_KEY_CAPSLOCK 1044 /* Caps Lock */ +#define GTA_KEY_RETURN 1045 /* Enter on main keyboard */ #define GTA_KEY_LSHIFT 1046 #define GTA_KEY_RSHIFT 1047 #define GTA_KEY_LCONTROL 1049 #define GTA_KEY_RCONTROL 1050 -#define GTA_KEY_LMENU 1051 /* left Alt */ -#define GTA_KEY_RMENU 1052 /* right Alt */ -#define GTA_KEY_LWIN 1053 /* Left Windows key */ -#define GTA_KEY_RWIN 1054 /* Right Windows key */ +#define GTA_KEY_LMENU 1051 /* left Alt */ +#define GTA_KEY_RMENU 1052 /* right Alt */ +#define GTA_KEY_LWIN 1053 /* Left Windows key */ +#define GTA_KEY_RWIN 1054 /* Right Windows key */ #define NO_KEY_DEFINED 1056 /* @@ -206,4 +206,5 @@ class CControllerConfigManager virtual void SetVerticalAimSensitivity(float fSensitivity) = 0; virtual float GetVerticalAimSensitivityRawValue() = 0; virtual void SetVerticalAimSensitivityRawValue(float fRawValue) = 0; + virtual void SetVerticalAimSensitivitySameAsHorizontal(bool enable) = 0; }; diff --git a/Client/sdk/game/CCoronas.h b/Client/sdk/game/CCoronas.h index f87ef55bf6f..6a184176bcd 100644 --- a/Client/sdk/game/CCoronas.h +++ b/Client/sdk/game/CCoronas.h @@ -16,8 +16,8 @@ class CRegisteredCorona; class CVector; // these are the IDs that are used internally for coronas -#define CORONA_SUN 1 -#define CORONA_MOON 2 +#define CORONA_SUN 1 +#define CORONA_MOON 2 class CCoronas { diff --git a/Client/sdk/game/CDamageManager.h b/Client/sdk/game/CDamageManager.h index 326ebaeba6e..46442eda878 100644 --- a/Client/sdk/game/CDamageManager.h +++ b/Client/sdk/game/CDamageManager.h @@ -12,12 +12,12 @@ #pragma once // Not sure if R* used these -#define DT_ENGINE_OK (0) -#define DT_ENGINE_RADIATOR_BURST (100) -#define DT_ENGINE_ENGINE_OVERHEAT (150) -#define DT_ENGINE_ENGINE_PIPES_BURST (200) -#define DT_ENGINE_ON_FIRE (225) -#define DT_ENGINE_FUCKED (250) +#define DT_ENGINE_OK (0) +#define DT_ENGINE_RADIATOR_BURST (100) +#define DT_ENGINE_ENGINE_OVERHEAT (150) +#define DT_ENGINE_ENGINE_PIPES_BURST (200) +#define DT_ENGINE_ON_FIRE (225) +#define DT_ENGINE_FUCKED (250) /* const unsigned char DT_ENG_INOPERABLE = 0x01; @@ -97,11 +97,11 @@ enum ePanels FRONT_RIGHT_PANEL, REAR_LEFT_PANEL, REAR_RIGHT_PANEL, - WINDSCREEN_PANEL, // needs to be in same order as in component.h + WINDSCREEN_PANEL, // needs to be in same order as in component.h FRONT_BUMPER, REAR_BUMPER, - MAX_PANELS // MUST BE 8 OR LESS + MAX_PANELS // MUST BE 8 OR LESS }; enum eLights @@ -118,7 +118,7 @@ enum eLights REAR_LEFT_INDICATOR, REAR_RIGHT_INDICATOR,*/ - MAX_LIGHTS // MUST BE 16 OR LESS + MAX_LIGHTS // MUST BE 16 OR LESS }; enum class eCarNodes @@ -182,7 +182,7 @@ class CDamageManager virtual void SetLightStatus(BYTE bLight, BYTE bLightStatus) = 0; virtual void SetLightStatus(unsigned char ucStatus) = 0; virtual BYTE GetAeroplaneCompStatus(BYTE CompID) = 0; - virtual void SetAeroplaneCompStatus(BYTE CompID, BYTE Status) = 0; // component ids begin at 12 - probably + virtual void SetAeroplaneCompStatus(BYTE CompID, BYTE Status) = 0; // component ids begin at 12 - probably virtual void FuckCarCompletely(bool bKeepWheels) = 0; }; diff --git a/Client/sdk/game/CDoor.h b/Client/sdk/game/CDoor.h index 56e7b29dbcf..2da58f89a31 100644 --- a/Client/sdk/game/CDoor.h +++ b/Client/sdk/game/CDoor.h @@ -15,9 +15,9 @@ class CDoor { public: - virtual float GetAngleOpenRatio() = 0; - virtual bool IsClosed() = 0; - virtual bool IsFullyOpen() = 0; - virtual void Open(float fRatio) = 0; + virtual float GetAngleOpenRatio() = 0; + virtual bool IsClosed() = 0; + virtual bool IsFullyOpen() = 0; + virtual void Open(float fRatio) = 0; virtual DoorState GetDoorState() = 0; }; diff --git a/Client/sdk/game/CEntity.h b/Client/sdk/game/CEntity.h index 264c5bb14d5..8f370fc6a76 100644 --- a/Client/sdk/game/CEntity.h +++ b/Client/sdk/game/CEntity.h @@ -46,14 +46,14 @@ enum eEntityStatus STATUS_PLANE, STATUS_REMOTE_CONTROLLED, STATUS_PLAYER_DISABLED, - STATUS_TRAILER, // ToDo: Check this. I can't reproduce that this is set for trailers - STATUS_SIMPLE_TRAILER // Same here + STATUS_TRAILER, // ToDo: Check this. I can't reproduce that this is set for trailers + STATUS_SIMPLE_TRAILER // Same here }; class CEntity { public: - virtual ~CEntity(){}; + virtual ~CEntity() {}; // virtual VOID SetModelAlpha ( int iAlpha )=0; virtual class CEntitySAInterface* GetInterface() = 0; diff --git a/Client/sdk/game/CFlyingHandlingEntry.h b/Client/sdk/game/CFlyingHandlingEntry.h index e329e19a747..dbd73fbc3e8 100644 --- a/Client/sdk/game/CFlyingHandlingEntry.h +++ b/Client/sdk/game/CFlyingHandlingEntry.h @@ -15,7 +15,7 @@ class CFlyingHandlingEntry { public: // Destructor - virtual ~CFlyingHandlingEntry(){}; + virtual ~CFlyingHandlingEntry() {}; // Use this to copy data from an another handling class to this virtual void Assign(const CFlyingHandlingEntry* pData) = 0; diff --git a/Client/sdk/game/CFx.h b/Client/sdk/game/CFx.h index d575f28b835..f71bfdf1ae1 100644 --- a/Client/sdk/game/CFx.h +++ b/Client/sdk/game/CFx.h @@ -35,5 +35,6 @@ class CFx virtual void TriggerWaterSplash(CVector& vecPosition) = 0; virtual void TriggerBulletSplash(CVector& vecPosition) = 0; virtual void TriggerFootSplash(CVector& vecPosition) = 0; - virtual void AddParticle(FxParticleSystems eFxParticle, const CVector& vecPosition, const CVector& vecDirection, float fR, float fG, float fB, float fA, bool bRandomizeColors, std::uint32_t iCount, float fBrightness, float fSize, bool bRandomizeSizes, float fLife) = 0; + virtual void AddParticle(FxParticleSystems eFxParticle, const CVector& vecPosition, const CVector& vecDirection, float fR, float fG, float fB, float fA, + bool bRandomizeColors, std::uint32_t iCount, float fBrightness, float fSize, bool bRandomizeSizes, float fLife) = 0; }; diff --git a/Client/sdk/game/CGame.h b/Client/sdk/game/CGame.h index baa6103e100..974ff8e94eb 100644 --- a/Client/sdk/game/CGame.h +++ b/Client/sdk/game/CGame.h @@ -74,6 +74,8 @@ class CVehicleAudioSettingsManager; enum eEntityType; enum ePedPieceTypes; +using StreamingRemoveModelCallback = bool (*)(unsigned int modelId); + typedef bool(PreWeaponFireHandler)(class CPlayerPed* pPlayer, bool bStopIfUsingBulletSync); typedef void(PostWeaponFireHandler)(); typedef void(TaskSimpleBeHitHandler)(class CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId); @@ -159,18 +161,18 @@ class __declspec(novtable) CGame virtual CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD) = 0; virtual CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false) = 0; - virtual DWORD GetSystemTime() = 0; - virtual int GetSystemFrameCounter() const = 0; - virtual bool IsAtMenu() = 0; - virtual void StartGame() = 0; - virtual void SetSystemState(SystemState State) = 0; - virtual SystemState GetSystemState() = 0; - virtual void Pause(bool bPaused) = 0; - virtual void SetTimeScale(float fTimeScale) = 0; - virtual float GetFPS() = 0; - virtual float GetTimeStep() = 0; - virtual float GetOldTimeStep() = 0; - virtual float GetTimeScale() = 0; + virtual DWORD GetSystemTime() = 0; + virtual int GetSystemFrameCounter() const = 0; + virtual bool IsAtMenu() = 0; + virtual void StartGame() = 0; + virtual void SetSystemState(SystemState State) = 0; + virtual SystemState GetSystemState() = 0; + virtual void Pause(bool bPaused) = 0; + virtual void SetTimeScale(float fTimeScale) = 0; + virtual float GetFPS() = 0; + virtual float GetTimeStep() = 0; + virtual float GetOldTimeStep() = 0; + virtual float GetTimeScale() = 0; virtual void Initialize() = 0; virtual void Reset() = 0; @@ -271,21 +273,22 @@ class __declspec(novtable) CGame virtual void SetPostWeaponFireHandler(PostWeaponFireHandler* pPostWeaponFireHandler) = 0; virtual void SetTaskSimpleBeHitHandler(TaskSimpleBeHitHandler* pTaskSimpleBeHitHandler) = 0; + virtual StreamingRemoveModelCallback GetStreamingRemoveModelCallback() const noexcept = 0; + virtual CObjectGroupPhysicalProperties* GetObjectGroupPhysicalProperties(unsigned char ucObjectGroup) = 0; - virtual int32_t GetBaseIDforDFF() = 0; - virtual int32_t GetBaseIDforTXD() = 0; - virtual int32_t GetBaseIDforCOL() = 0; - virtual int32_t GetBaseIDforIPL() = 0; - virtual int32_t GetBaseIDforDAT() = 0; - virtual int32_t GetBaseIDforIFP() = 0; - virtual int32_t GetBaseIDforRRR() = 0; - virtual int32_t GetBaseIDforSCM() = 0; - virtual int32_t GetCountOfAllFileIDs() = 0; + virtual uint32_t GetBaseIDforDFF() = 0; + virtual uint32_t GetBaseIDforTXD() = 0; + virtual uint32_t GetBaseIDforCOL() = 0; + virtual uint32_t GetBaseIDforIPL() = 0; + virtual uint32_t GetBaseIDforDAT() = 0; + virtual uint32_t GetBaseIDforIFP() = 0; + virtual uint32_t GetBaseIDforRRR() = 0; + virtual uint32_t GetBaseIDforSCM() = 0; + virtual uint32_t GetCountOfAllFileIDs() = 0; virtual void RemoveGameWorld() = 0; virtual void RestoreGameWorld() = 0; virtual bool SetBuildingPoolSize(size_t size) = 0; - }; diff --git a/Client/sdk/game/CHandlingEntry.h b/Client/sdk/game/CHandlingEntry.h index f40eeb433aa..4e3667642a1 100644 --- a/Client/sdk/game/CHandlingEntry.h +++ b/Client/sdk/game/CHandlingEntry.h @@ -16,52 +16,52 @@ class CVector; // ### MODELFLAGS ### // 1st digit -#define MODELFLAGS_IS_VAN 0x00000001 -#define MODELFLAGS_IS_BUS 0x00000002 -#define MODELFLAGS_IS_LOW 0x00000004 -#define MODELFLAGS_IS_BIG 0x00000008 +#define MODELFLAGS_IS_VAN 0x00000001 +#define MODELFLAGS_IS_BUS 0x00000002 +#define MODELFLAGS_IS_LOW 0x00000004 +#define MODELFLAGS_IS_BIG 0x00000008 // 2nd digit -#define MODELFLAGS_REVERSE_BONNET 0x00000010 -#define MODELFLAGS_HANGING_BOOT 0x00000020 -#define MODELFLAGS_TAILGATE_BOOT 0x00000040 -#define MODELFLAGS_NOSWING_BOOT 0x00000080 +#define MODELFLAGS_REVERSE_BONNET 0x00000010 +#define MODELFLAGS_HANGING_BOOT 0x00000020 +#define MODELFLAGS_TAILGATE_BOOT 0x00000040 +#define MODELFLAGS_NOSWING_BOOT 0x00000080 // 3rd digit -#define MODELFLAGS_NO_DOORS 0x00000100 -#define MODELFLAGS_TANDEM_SEATS 0x00000200 -#define MODELFLAGS_SIT_IN_BOAT 0x00000400 -#define MODELFLAGS_CONVERTIBLE 0x00000800 +#define MODELFLAGS_NO_DOORS 0x00000100 +#define MODELFLAGS_TANDEM_SEATS 0x00000200 +#define MODELFLAGS_SIT_IN_BOAT 0x00000400 +#define MODELFLAGS_CONVERTIBLE 0x00000800 // 4th digit -#define MODELFLAGS_NO_EXHAUST 0x00001000 -#define MODELFLAGS_DOUBLE_EXHAUST 0x00002000 -#define MODELFLAGS_NO1FPS_LOOK_BEHIND 0x00004000 -#define MODELFLAGS_FORCE_DOOR_CHECK 0x00008000 +#define MODELFLAGS_NO_EXHAUST 0x00001000 +#define MODELFLAGS_DOUBLE_EXHAUST 0x00002000 +#define MODELFLAGS_NO1FPS_LOOK_BEHIND 0x00004000 +#define MODELFLAGS_FORCE_DOOR_CHECK 0x00008000 // 5th digit -#define MODELFLAGS_AXLE_F_NOTILT 0x00010000 -#define MODELFLAGS_AXLE_F_SOLID 0x00020000 -#define MODELFLAGS_AXLE_F_MCPHERSON 0x00040000 -#define MODELFLAGS_AXLE_F_REVERSE 0x00080000 +#define MODELFLAGS_AXLE_F_NOTILT 0x00010000 +#define MODELFLAGS_AXLE_F_SOLID 0x00020000 +#define MODELFLAGS_AXLE_F_MCPHERSON 0x00040000 +#define MODELFLAGS_AXLE_F_REVERSE 0x00080000 // 6th digit -#define MODELFLAGS_AXLE_R_NOTILT 0x00100000 -#define MODELFLAGS_AXLE_R_SOLID 0x00200000 -#define MODELFLAGS_AXLE_R_MCPHERSON 0x00400000 -#define MODELFLAGS_AXLE_R_REVERSE 0x00800000 +#define MODELFLAGS_AXLE_R_NOTILT 0x00100000 +#define MODELFLAGS_AXLE_R_SOLID 0x00200000 +#define MODELFLAGS_AXLE_R_MCPHERSON 0x00400000 +#define MODELFLAGS_AXLE_R_REVERSE 0x00800000 // 7th digit -#define MODELFLAGS_IS_BIKE 0x01000000 -#define MODELFLAGS_IS_HELI 0x02000000 -#define MODELFLAGS_IS_PLANE 0x04000000 -#define MODELFLAGS_IS_BOAT 0x08000000 +#define MODELFLAGS_IS_BIKE 0x01000000 +#define MODELFLAGS_IS_HELI 0x02000000 +#define MODELFLAGS_IS_PLANE 0x04000000 +#define MODELFLAGS_IS_BOAT 0x08000000 // 8th digit -#define MODELFLAGS_BOUNCE_PANELS 0x10000000 -#define MODELFLAGS_DOUBLE_RWHEELS 0x20000000 -#define MODELFLAGS_FORCE_GROUND_CLEARANCE 0x40000000 -#define MODELFLAGS_IS_HATCHBACK 0x80000000 +#define MODELFLAGS_BOUNCE_PANELS 0x10000000 +#define MODELFLAGS_DOUBLE_RWHEELS 0x20000000 +#define MODELFLAGS_FORCE_GROUND_CLEARANCE 0x40000000 +#define MODELFLAGS_IS_HATCHBACK 0x80000000 class CHandlingEntry { @@ -89,7 +89,7 @@ class CHandlingEntry }; // Destructor - virtual ~CHandlingEntry(){}; + virtual ~CHandlingEntry() {}; // Use this to copy data from an another handling class to this virtual void Assign(const CHandlingEntry* pEntry) noexcept = 0; diff --git a/Client/sdk/game/CHeli.h b/Client/sdk/game/CHeli.h index 89f8b5c73b8..cac8e2dca33 100644 --- a/Client/sdk/game/CHeli.h +++ b/Client/sdk/game/CHeli.h @@ -15,5 +15,5 @@ class CHeli : public virtual CAutomobile { public: - virtual ~CHeli(){}; + virtual ~CHeli() {}; }; diff --git a/Client/sdk/game/CHud.h b/Client/sdk/game/CHud.h index 8b3e2e37fd4..da95656daf9 100644 --- a/Client/sdk/game/CHud.h +++ b/Client/sdk/game/CHud.h @@ -31,6 +31,9 @@ enum eHudComponent HUD_ALL, HUD_VITAL_STATS, HUD_HELP_TEXT, + HUD_RADAR_MAP, + HUD_RADAR_BLIPS, + HUD_RADAR_ALTIMETER, }; enum class eHudComponentProperty @@ -110,16 +113,16 @@ class CHud virtual void ResetComponentFontAlignment(const eHudComponent& component) noexcept = 0; virtual void ResetComponentFontProportional(const eHudComponent& component) noexcept = 0; - virtual CVector2D GetComponentPosition(const eHudComponent& component) const noexcept = 0; - virtual CVector2D GetComponentSize(const eHudComponent& component) const noexcept = 0; + virtual CVector2D GetComponentPosition(const eHudComponent& component) const noexcept = 0; + virtual CVector2D GetComponentSize(const eHudComponent& component) const noexcept = 0; - virtual SColor GetComponentColor(const eHudComponent& component) const noexcept = 0; - virtual SColor GetComponentSecondaryColor(const eHudComponent& component) const noexcept = 0; - virtual SColor GetComponentFontDropColor(const eHudComponent& component) const = 0; + virtual SColor GetComponentColor(const eHudComponent& component) const noexcept = 0; + virtual SColor GetComponentSecondaryColor(const eHudComponent& component) const noexcept = 0; + virtual SColor GetComponentFontDropColor(const eHudComponent& component) const = 0; - virtual bool GetComponentDrawBlackBorder(const eHudComponent& component) const noexcept = 0; - virtual bool GetComponentDrawPercentage(const eHudComponent& component) const noexcept = 0; - virtual float GetHealthBarBlinkingValue(const eHudComponent& component) const noexcept = 0; + virtual bool GetComponentDrawBlackBorder(const eHudComponent& component) const noexcept = 0; + virtual bool GetComponentDrawPercentage(const eHudComponent& component) const noexcept = 0; + virtual float GetHealthBarBlinkingValue(const eHudComponent& component) const noexcept = 0; virtual float GetComponentFontOutline(const eHudComponent& component) const = 0; virtual float GetComponentFontShadow(const eHudComponent& component) const = 0; @@ -127,7 +130,7 @@ class CHud virtual eFontAlignment GetComponentFontAlignment(const eHudComponent& component) const = 0; virtual bool GetComponentFontProportional(const eHudComponent& component) const = 0; - virtual bool GetComponentUseCustomAlpha(const eHudComponent& component) const noexcept = 0; + virtual bool GetComponentUseCustomAlpha(const eHudComponent& component) const noexcept = 0; - virtual CVector2D GetComponentTextSize(const eHudComponent& component) const = 0; + virtual CVector2D GetComponentTextSize(const eHudComponent& component) const = 0; }; diff --git a/Client/sdk/game/CMarker.h b/Client/sdk/game/CMarker.h index 7ab48725655..f968d3a9a8d 100644 --- a/Client/sdk/game/CMarker.h +++ b/Client/sdk/game/CMarker.h @@ -22,8 +22,8 @@ class CPed; class CVector; class CVehicle; -#define MARKER_SCALE_SMALL 1 -#define MARKER_SCALE_NORMAL 2 +#define MARKER_SCALE_SMALL 1 +#define MARKER_SCALE_NORMAL 2 class CMarker { diff --git a/Client/sdk/game/CModelInfo.h b/Client/sdk/game/CModelInfo.h index 3c111013f3d..19019b31deb 100644 --- a/Client/sdk/game/CModelInfo.h +++ b/Client/sdk/game/CModelInfo.h @@ -11,6 +11,7 @@ #pragma once #include +#include #include #include "CAnimBlock.h" #include "enums/VehicleDummies.h" @@ -39,7 +40,7 @@ enum class eModelIdeFlag IS_ROAD, DRAW_LAST, ADDITIVE, - IGNORE_LIGHTING, // Used with animated objects + IGNORE_LIGHTING, // Used with animated objects NO_ZBUFFER_WRITE, DONT_RECEIVE_SHADOWS, IS_GLASS_TYPE_1, @@ -169,6 +170,9 @@ class CModelInfo virtual bool GetIdeFlag(eModelIdeFlag eFlag) = 0; virtual void SetIdeFlag(eModelIdeFlag eFlag, bool bState) = 0; virtual CBoundingBox* GetBoundingBox() = 0; + virtual bool IsCollisionLoaded() const noexcept = 0; + virtual bool IsRwObjectLoaded() const noexcept = 0; + virtual void WaitForModelFullyLoaded(std::chrono::milliseconds timeout) = 0; virtual bool IsValid() = 0; virtual bool IsAllocatedInArchive() const noexcept = 0; virtual unsigned short GetTextureDictionaryID() = 0; @@ -236,7 +240,8 @@ class CModelInfo // Call this to make sure the custom vehicle models are being used after a load. virtual void MakeCustomModel() = 0; virtual RwObject* GetRwObject() = 0; - virtual void MakePedModel(char* szTexture) = 0; + virtual void MakePedModel(const char* szTexture) = 0; + virtual void MakePedModel(unsigned short usParentID) = 0; virtual void MakeObjectModel(unsigned short usBaseID) = 0; virtual void MakeObjectDamageableModel(std::uint16_t baseID) = 0; virtual void MakeVehicleAutomobile(unsigned short usBaseID) = 0; @@ -254,6 +259,11 @@ class CModelInfo virtual bool IsTowableBy(CModelInfo* towingModel) = 0; virtual unsigned int GetParentID() = 0; + virtual void SetParentID(unsigned int id) = 0; virtual bool IsDynamic() = 0; virtual bool IsDamageableAtomic() = 0; + + // Clear m_pCustomClump without touching GTA streaming or RW objects. + // Used during shutdown when RW operations are unsafe. + virtual void ClearCustomModel() = 0; }; diff --git a/Client/sdk/game/CMonsterTruck.h b/Client/sdk/game/CMonsterTruck.h index f1d6f740af3..3107615ae8d 100644 --- a/Client/sdk/game/CMonsterTruck.h +++ b/Client/sdk/game/CMonsterTruck.h @@ -16,5 +16,5 @@ class CMonsterTruck : public virtual CAutomobile { public: - virtual ~CMonsterTruck(){}; + virtual ~CMonsterTruck() {}; }; diff --git a/Client/sdk/game/CObject.h b/Client/sdk/game/CObject.h index 1d65e4fc77f..0f8c75c2830 100644 --- a/Client/sdk/game/CObject.h +++ b/Client/sdk/game/CObject.h @@ -20,7 +20,7 @@ class CVehicle; class CObject : public virtual CPhysical { public: - virtual ~CObject(){}; + virtual ~CObject() {}; virtual CObjectSAInterface* GetObjectInterface() = 0; @@ -41,5 +41,4 @@ class CObject : public virtual CPhysical virtual void SetScale(float fX, float fY, float fZ) = 0; virtual CVector* GetScale() = 0; virtual void ResetScale() = 0; - }; diff --git a/Client/sdk/game/CObjectGroupPhysicalProperties.h b/Client/sdk/game/CObjectGroupPhysicalProperties.h index f350f531a07..9cbb6b934f2 100644 --- a/Client/sdk/game/CObjectGroupPhysicalProperties.h +++ b/Client/sdk/game/CObjectGroupPhysicalProperties.h @@ -22,42 +22,42 @@ class CObjectGroupPhysicalProperties virtual unsigned char GetGroup() const = 0; virtual void RestoreDefault() = 0; - virtual void SetMass(float fMass) = 0; - virtual float GetMass() const = 0; - virtual void SetTurnMass(float fTurnMass) = 0; - virtual float GetTurnMass() const = 0; - virtual void SetAirResistance(float fAirResistance) = 0; - virtual float GetAirResistance() const = 0; - virtual void SetElasticity(float fElasticity) = 0; - virtual float GetElasticity() const = 0; - virtual void SetBuoyancy(float fBuoyancy) = 0; - virtual float GetBuoyancy() const = 0; - virtual void SetUprootLimit(float fUprootLimit) = 0; - virtual float GetUprootLimit() const = 0; - virtual void SetCollisionDamageMultiplier(float fColMult) = 0; - virtual float GetCollisionDamageMultiplier() const = 0; - virtual void SetCollisionDamageEffect(ObjectGroupPhysicalProperties::DamageEffect eDamageEffect) = 0; - virtual ObjectGroupPhysicalProperties::DamageEffect GetCollisionDamageEffect() const = 0; - virtual void SetCollisionSpecialResponseCase(ObjectGroupPhysicalProperties::CollisionResponse eResponseCase) = 0; + virtual void SetMass(float fMass) = 0; + virtual float GetMass() const = 0; + virtual void SetTurnMass(float fTurnMass) = 0; + virtual float GetTurnMass() const = 0; + virtual void SetAirResistance(float fAirResistance) = 0; + virtual float GetAirResistance() const = 0; + virtual void SetElasticity(float fElasticity) = 0; + virtual float GetElasticity() const = 0; + virtual void SetBuoyancy(float fBuoyancy) = 0; + virtual float GetBuoyancy() const = 0; + virtual void SetUprootLimit(float fUprootLimit) = 0; + virtual float GetUprootLimit() const = 0; + virtual void SetCollisionDamageMultiplier(float fColMult) = 0; + virtual float GetCollisionDamageMultiplier() const = 0; + virtual void SetCollisionDamageEffect(ObjectGroupPhysicalProperties::DamageEffect eDamageEffect) = 0; + virtual ObjectGroupPhysicalProperties::DamageEffect GetCollisionDamageEffect() const = 0; + virtual void SetCollisionSpecialResponseCase(ObjectGroupPhysicalProperties::CollisionResponse eResponseCase) = 0; virtual ObjectGroupPhysicalProperties::CollisionResponse GetCollisionSpecialResponseCase() const = 0; - virtual void SetCameraAvoidObject(bool bAvoid) = 0; - virtual bool GetCameraAvoidObject() const = 0; - virtual void SetCausesExplosion(bool bExplodes) = 0; - virtual bool GetCausesExplosion() const = 0; - virtual void SetFxType(ObjectGroupPhysicalProperties::FxType eFxType) = 0; + virtual void SetCameraAvoidObject(bool bAvoid) = 0; + virtual bool GetCameraAvoidObject() const = 0; + virtual void SetCausesExplosion(bool bExplodes) = 0; + virtual bool GetCausesExplosion() const = 0; + virtual void SetFxType(ObjectGroupPhysicalProperties::FxType eFxType) = 0; virtual ObjectGroupPhysicalProperties::FxType GetFxType() const = 0; - virtual void SetFxOffset(CVector vecOffset) = 0; - virtual CVector GetFxOffset() const = 0; - virtual bool SetFxParticleSystem(CFxSystemBPSAInterface* pBlueprint) = 0; - virtual void RemoveFxParticleSystem() = 0; - virtual void SetSmashMultiplier(float fMult) = 0; - virtual float GetSmashMultiplier() const = 0; - virtual void SetBreakVelocity(CVector vecVelocity) = 0; - virtual CVector GetBreakVelocity() const = 0; - virtual void SetBreakVelocityRandomness(float fRand) = 0; - virtual float GetBreakVelocityRandomness() const = 0; - virtual void SetBreakMode(ObjectGroupPhysicalProperties::BreakMode eBreakMode) = 0; + virtual void SetFxOffset(CVector vecOffset) = 0; + virtual CVector GetFxOffset() const = 0; + virtual bool SetFxParticleSystem(CFxSystemBPSAInterface* pBlueprint) = 0; + virtual void RemoveFxParticleSystem() = 0; + virtual void SetSmashMultiplier(float fMult) = 0; + virtual float GetSmashMultiplier() const = 0; + virtual void SetBreakVelocity(CVector vecVelocity) = 0; + virtual CVector GetBreakVelocity() const = 0; + virtual void SetBreakVelocityRandomness(float fRand) = 0; + virtual float GetBreakVelocityRandomness() const = 0; + virtual void SetBreakMode(ObjectGroupPhysicalProperties::BreakMode eBreakMode) = 0; virtual ObjectGroupPhysicalProperties::BreakMode GetBreakMode() const = 0; - virtual void SetSparksOnImpact(bool bSparks) = 0; - virtual bool GetSparksOnImpact() const = 0; + virtual void SetSparksOnImpact(bool bSparks) = 0; + virtual bool GetSparksOnImpact() const = 0; }; diff --git a/Client/sdk/game/CPad.h b/Client/sdk/game/CPad.h index 448311252f1..d1727dfbf1d 100644 --- a/Client/sdk/game/CPad.h +++ b/Client/sdk/game/CPad.h @@ -15,31 +15,31 @@ class CControllerState { public: - signed short LeftStickX; // move/steer left (-128?)/right (+128) - signed short LeftStickY; // move back(+128)/forwards(-128?) - signed short RightStickX; // numpad 6(+128)/numpad 4(-128?) + signed short LeftStickX; // move/steer left (-128?)/right (+128) + signed short LeftStickY; // move back(+128)/forwards(-128?) + signed short RightStickX; // numpad 6(+128)/numpad 4(-128?) signed short RightStickY; signed short LeftShoulder1; signed short LeftShoulder2; - signed short RightShoulder1; // target / hand brake + signed short RightShoulder1; // target / hand brake signed short RightShoulder2; - signed short DPadUp; // radio change up - signed short DPadDown; // radio change down + signed short DPadUp; // radio change up + signed short DPadDown; // radio change down signed short DPadLeft; signed short DPadRight; signed short Start; signed short Select; - signed short ButtonSquare; // jump / reverse - signed short ButtonTriangle; // get in/out - signed short ButtonCross; // sprint / accelerate - signed short ButtonCircle; // fire + signed short ButtonSquare; // jump / reverse + signed short ButtonTriangle; // get in/out + signed short ButtonCross; // sprint / accelerate + signed short ButtonCircle; // fire signed short ShockButtonL; - signed short ShockButtonR; // look behind + signed short ShockButtonR; // look behind signed short m_bChatIndicated; signed short m_bPedWalk; diff --git a/Client/sdk/game/CPed.h b/Client/sdk/game/CPed.h index 6ffd9aaf6b7..1d90ba466c8 100644 --- a/Client/sdk/game/CPed.h +++ b/Client/sdk/game/CPed.h @@ -14,6 +14,7 @@ #include "CWeaponInfo.h" #include "CPedSound.h" #include "enums/PedState.h" +#include "enums/PedMoveState.h" // To avoid VS intellisense highlight errors #include @@ -178,7 +179,10 @@ struct SSatchelsData CVector* vecAttachedOffsets; CVector* vecAttachedRotation; - SSatchelsData(CProjectileSAInterface* proj, CVector* offset, CVector* rotation) : pProjectileInterface(proj), vecAttachedOffsets(offset), vecAttachedRotation(rotation) {} + SSatchelsData(CProjectileSAInterface* proj, CVector* offset, CVector* rotation) + : pProjectileInterface(proj), vecAttachedOffsets(offset), vecAttachedRotation(rotation) + { + } }; inline bool IsValidMoveAnim(std::uint32_t iMoveAnim) noexcept @@ -189,7 +193,7 @@ inline bool IsValidMoveAnim(std::uint32_t iMoveAnim) noexcept class CPed : public virtual CPhysical { public: - virtual ~CPed(){}; + virtual ~CPed() {}; virtual class CPedSAInterface* GetPedInterface() noexcept = 0; @@ -253,8 +257,9 @@ class CPed : public virtual CPhysical virtual void SetFightingStyle(eFightingStyle style, std::uint8_t styleExtra) = 0; virtual CEntity* GetContactEntity() const = 0; + virtual bool IsStandingOnEntity() const = 0; - virtual int GetRunState() const = 0; + virtual PedMoveState::Enum GetMoveState() const = 0; virtual bool GetCanBeShotInVehicle() const = 0; virtual bool GetTestForShotInVehicle() const = 0; @@ -263,7 +268,7 @@ class CPed : public virtual CPhysical virtual void SetTestForShotInVehicle(bool test) = 0; virtual std::uint8_t GetOccupiedSeat() const noexcept = 0; - virtual void SetOccupiedSeat(std::uint8_t seat) noexcept = 0; + virtual void SetOccupiedSeat(std::uint8_t seat) noexcept = 0; virtual void RemoveBodyPart(std::uint8_t boneID, std::uint8_t direction) = 0; @@ -300,9 +305,11 @@ class CPed : public virtual CPhysical virtual std::unique_ptr GetPedIK() = 0; virtual CEntitySAInterface* GetTargetedObject() const = 0; - virtual PedState GetPedState() const = 0; + virtual PedState GetPedState() const = 0; - virtual void GetAttachedSatchels(std::vector &satchelsList) const = 0; + virtual void GetAttachedSatchels(std::vector& satchelsList) const = 0; virtual void Say(const ePedSpeechContext& speechId, float probability) = 0; + + virtual void SetInWaterFlags(bool inWater) = 0; }; diff --git a/Client/sdk/game/CPedIntelligence.h b/Client/sdk/game/CPedIntelligence.h index 7118b0c639b..a1ff8d71f54 100644 --- a/Client/sdk/game/CPedIntelligence.h +++ b/Client/sdk/game/CPedIntelligence.h @@ -15,12 +15,14 @@ class CPed; class CTaskSAInterface; class CTaskManager; class CTaskSimpleUseGun; +class CTaskSimpleFight; class CPedIntelligence { public: - virtual CTaskManager* GetTaskManager() = 0; - virtual bool TestForStealthKill(CPed* pPed, bool bUnk) = 0; - virtual CTaskSAInterface* SetTaskDuckSecondary(unsigned short nLengthOfDuck) = 0; + virtual CTaskManager* GetTaskManager() = 0; + virtual bool TestForStealthKill(CPed* pPed, bool bUnk) = 0; + virtual CTaskSAInterface* SetTaskDuckSecondary(unsigned short nLengthOfDuck) = 0; virtual CTaskSimpleUseGun* GetTaskUseGun() = 0; + virtual CTaskSimpleFight* GetFightTask() = 0; }; diff --git a/Client/sdk/game/CPhysical.h b/Client/sdk/game/CPhysical.h index 3f04fa257b9..d395d5aebe1 100644 --- a/Client/sdk/game/CPhysical.h +++ b/Client/sdk/game/CPhysical.h @@ -16,7 +16,7 @@ class CPhysical : public virtual CEntity { public: - virtual ~CPhysical(){}; + virtual ~CPhysical() {}; virtual CVector* GetMoveSpeed(CVector* vecMoveSpeed) = 0; virtual CVector* GetTurnSpeed(CVector* vecTurnSpeed) = 0; diff --git a/Client/sdk/game/CPickup.h b/Client/sdk/game/CPickup.h index f737ae39cf3..3f7b31b199c 100644 --- a/Client/sdk/game/CPickup.h +++ b/Client/sdk/game/CPickup.h @@ -25,22 +25,22 @@ class CPickup virtual CVector* GetPosition(CVector* vecPosition) = 0; virtual PickupType GetType() = 0; - virtual void SetType(PickupType type) = 0; - virtual float GetCurrentValue() = 0; - virtual void SetCurrentValue(float fCurrentValue) = 0; - virtual void SetRegenerationTime(DWORD dwTime) = 0; - virtual void SetMoneyPerDay(WORD wMoneyPerDay) = 0; - virtual WORD GetMoneyPerDay() = 0; - virtual WORD GetModel() = 0; - virtual void SetModel(WORD wModelIndex) = 0; // do not export + virtual void SetType(PickupType type) = 0; + virtual float GetCurrentValue() = 0; + virtual void SetCurrentValue(float fCurrentValue) = 0; + virtual void SetRegenerationTime(DWORD dwTime) = 0; + virtual void SetMoneyPerDay(WORD wMoneyPerDay) = 0; + virtual WORD GetMoneyPerDay() = 0; + virtual WORD GetModel() = 0; + virtual void SetModel(WORD wModelIndex) = 0; // do not export virtual PickupState GetState() = 0; - virtual void SetState(PickupState bState) = 0; - virtual BYTE GetAmmo() = 0; - virtual void SetAmmo(BYTE bAmmo) = 0; - virtual long GetMonetaryValue() = 0; - virtual void SetMonetaryValue(long lMonetaryValue) = 0; - virtual BYTE IsNearby() = 0; - virtual void Remove() = 0; - virtual void GiveUsAPickUpObject(int ForcedObjectIndex = -1) = 0; - virtual void GetRidOfObjects() = 0; + virtual void SetState(PickupState bState) = 0; + virtual BYTE GetAmmo() = 0; + virtual void SetAmmo(BYTE bAmmo) = 0; + virtual long GetMonetaryValue() = 0; + virtual void SetMonetaryValue(long lMonetaryValue) = 0; + virtual BYTE IsNearby() = 0; + virtual void Remove() = 0; + virtual bool GiveUsAPickUpObject(int ForcedObjectIndex = -1) = 0; + virtual void GetRidOfObjects() = 0; }; diff --git a/Client/sdk/game/CPickups.h b/Client/sdk/game/CPickups.h index 6a15f97b914..631b2511997 100644 --- a/Client/sdk/game/CPickups.h +++ b/Client/sdk/game/CPickups.h @@ -19,7 +19,7 @@ class CVector; class CPickups { public: - virtual CPickup* CreatePickup(CVector* position, DWORD ModelIndex, PickupType Type = PickupType::PICKUP_ONCE, DWORD dwMonetaryValue = 0, DWORD dwMoneyPerDay = 0, - BYTE bPingOutOfPlayer = 0) = 0; + virtual CPickup* CreatePickup(CVector* position, DWORD ModelIndex, PickupType Type = PickupType::PICKUP_ONCE, DWORD dwMonetaryValue = 0, + DWORD dwMoneyPerDay = 0, BYTE bPingOutOfPlayer = 0) = 0; virtual void DisablePickupProcessing(bool bDisabled) = 0; }; diff --git a/Client/sdk/game/CPlane.h b/Client/sdk/game/CPlane.h index 22b0e56fc39..461cdd0cf0d 100644 --- a/Client/sdk/game/CPlane.h +++ b/Client/sdk/game/CPlane.h @@ -16,5 +16,5 @@ class CPlane : public virtual CAutomobile { public: - virtual ~CPlane(){}; + virtual ~CPlane() {}; }; diff --git a/Client/sdk/game/CPlayerInfo.h b/Client/sdk/game/CPlayerInfo.h index 328f0a27d38..8314d0e30ea 100644 --- a/Client/sdk/game/CPlayerInfo.h +++ b/Client/sdk/game/CPlayerInfo.h @@ -31,13 +31,13 @@ class CPlayerInfo virtual byte GetCamDrunkLevel() = 0; virtual void SetCamDrunkLevel(byte level) = 0; - virtual DWORD GetCarTwoWheelCounter() = 0; - virtual float GetCarTwoWheelDist() = 0; - virtual DWORD GetCarLess3WheelCounter() = 0; - virtual DWORD GetBikeRearWheelCounter() = 0; - virtual float GetBikeRearWheelDist() = 0; - virtual DWORD GetBikeFrontWheelCounter() = 0; - virtual float GetBikeFrontWheelDist() = 0; + virtual DWORD GetCarTwoWheelCounter() = 0; + virtual float GetCarTwoWheelDist() = 0; + virtual DWORD GetCarLess3WheelCounter() = 0; + virtual DWORD GetBikeRearWheelCounter() = 0; + virtual float GetBikeRearWheelDist() = 0; + virtual DWORD GetBikeFrontWheelCounter() = 0; + virtual float GetBikeFrontWheelDist() = 0; virtual std::uint8_t GetMaxHealth() const = 0; virtual std::uint8_t GetMaxArmor() const = 0; }; diff --git a/Client/sdk/game/CPlayerPed.h b/Client/sdk/game/CPlayerPed.h index 9eba8102dc7..bfa4873e562 100644 --- a/Client/sdk/game/CPlayerPed.h +++ b/Client/sdk/game/CPlayerPed.h @@ -18,7 +18,7 @@ class CWanted; class CPlayerPed : public virtual CPed { public: - virtual ~CPlayerPed(){}; + virtual ~CPlayerPed() {}; virtual CWanted* GetWanted() = 0; diff --git a/Client/sdk/game/CPointLights.h b/Client/sdk/game/CPointLights.h index a564c125e51..171324a3662 100644 --- a/Client/sdk/game/CPointLights.h +++ b/Client/sdk/game/CPointLights.h @@ -29,5 +29,6 @@ class CPointLights virtual void PreRenderHeliLights() = 0; virtual void PostRenderHeliLights() = 0; - virtual void RenderHeliLight(const CVector& vecStart, const CVector& vecEnd, float startRadius, float endRadius, bool renderSpot) = 0; + virtual void RenderHeliLight(const CVector& vecStart, const CVector& vecEnd, float startRadius, float endRadius, bool renderSpot, + const SharedUtil::SColor& color) = 0; }; diff --git a/Client/sdk/game/CPools.h b/Client/sdk/game/CPools.h index 7c209ed6c4b..55d6bacb242 100644 --- a/Client/sdk/game/CPools.h +++ b/Client/sdk/game/CPools.h @@ -87,7 +87,7 @@ class CPools virtual CPed* AddPed(class CClientPed* pClientPed, DWORD* pGameInterface) = 0; virtual void RemovePed(CPed* pPed, bool bDelete = true) = 0; - virtual SClientEntity* GetPed(DWORD* pGameInterface) = 0; // not sure we really want this here + virtual SClientEntity* GetPed(DWORD* pGameInterface) = 0; // not sure we really want this here virtual SClientEntity* GetPed(size_t pos) = 0; virtual CPed* GetPedFromRef(DWORD dwGameRef) = 0; virtual unsigned long GetPedCount() = 0; @@ -109,8 +109,8 @@ class CPools virtual void ResetPedPoolCount() = 0; virtual void InvalidateLocalPlayerClientEntity() = 0; - virtual CBuildingsPool& GetBuildingsPool() noexcept = 0; - virtual CDummyPool& GetDummyPool() noexcept = 0; - virtual CTxdPool& GetTxdPool() noexcept = 0; + virtual CBuildingsPool& GetBuildingsPool() noexcept = 0; + virtual CDummyPool& GetDummyPool() noexcept = 0; + virtual CTxdPool& GetTxdPool() noexcept = 0; virtual CPtrNodeSingleLinkPool& GetPtrNodeSingleLinkPool() noexcept = 0; }; diff --git a/Client/sdk/game/CProjectile.h b/Client/sdk/game/CProjectile.h index d6f9faa7c9f..799ea6a5284 100644 --- a/Client/sdk/game/CProjectile.h +++ b/Client/sdk/game/CProjectile.h @@ -18,7 +18,7 @@ class CProjectileInfo; class CProjectile : public virtual CObject { public: - virtual ~CProjectile(){}; + virtual ~CProjectile() {}; virtual void Destroy(bool bBlow) = 0; virtual void SetProjectileInfo(CProjectileInfo* pProjectileInfo) = 0; diff --git a/Client/sdk/game/CProjectileInfo.h b/Client/sdk/game/CProjectileInfo.h index 70cdc7fb2b8..aeb3d564bfc 100644 --- a/Client/sdk/game/CProjectileInfo.h +++ b/Client/sdk/game/CProjectileInfo.h @@ -20,8 +20,8 @@ class CProjectileInfo { public: virtual bool AddProjectile(CEntity* creator, eWeaponType eWeapon, CVector vecOrigin, float fForce, CVector* target, CEntity* targetEntity) = 0; - virtual CProjectile* GetProjectile(void* projectilePointer) = 0; // hack, don't use please - virtual CProjectileInfo* GetProjectileInfo(void* projectileInfoInterface) = 0; // don't use + virtual CProjectile* GetProjectile(void* projectilePointer) = 0; // hack, don't use please + virtual CProjectileInfo* GetProjectileInfo(void* projectileInfoInterface) = 0; // don't use virtual void RemoveProjectile(CProjectileInfo* pProjectileInfo, CProjectile* pProjectile, bool bBlow = true) = 0; virtual CProjectileInfo* GetProjectileInfo(DWORD Index) = 0; virtual void RemoveEntityReferences(CEntity* entity) = 0; diff --git a/Client/sdk/game/CQuadBike.h b/Client/sdk/game/CQuadBike.h index 50af912b879..4ed8836e663 100644 --- a/Client/sdk/game/CQuadBike.h +++ b/Client/sdk/game/CQuadBike.h @@ -16,5 +16,5 @@ class CQuadBike : public virtual CAutomobile { public: - virtual ~CQuadBike(){}; + virtual ~CQuadBike() {}; }; diff --git a/Client/sdk/game/CRenderWare.h b/Client/sdk/game/CRenderWare.h index c7314dabc74..58702a08ca8 100644 --- a/Client/sdk/game/CRenderWare.h +++ b/Client/sdk/game/CRenderWare.h @@ -11,7 +11,11 @@ #pragma once +#include #include +#include +#include +#include class CClientEntityBase; class CD3DDUMMY; @@ -20,12 +24,14 @@ class CPixels; class CShaderItem; class SString; class CColModel; +class CVector; struct RpAtomicContainer; struct RwFrame; struct RwMatrix; struct RwTexDictionary; struct RwTexture; struct RpClump; +struct RpAtomic; typedef CShaderItem CSHADERDUMMY; @@ -35,14 +41,23 @@ struct SReplacementTextures struct SPerTxd { std::vector usingTextures; - ushort usTxdId; + std::vector replacedOriginals; + unsigned short usTxdId; bool bTexturesAreCopies; + SString strDebugSource; // filename/resource for diagnostics + SString strDebugHash; // Short hash of source data for deduping logs }; - std::vector textures; // List of textures we want to inject into TXD's - std::vector perTxdList; // TXD's which have been modified - std::vector usedInTxdIds; - std::vector usedInModelIds; + std::vector textures; // List of textures we want to inject into TXD's + std::vector perTxdList; // TXD's which have been modified + std::unordered_set usedInTxdIds; // contains/erase for streaming hot path + std::unordered_set usedInModelIds; // All consuming models (explicit + shared TXD passive) + std::unordered_set pendingOnModelIds; // Models waiting for a later apply + uint32_t uiSessionId = 0; // Texture-replacing session generation (used to ignore stale cross-session cleanup) + SString strDebugName; // Source path or description for logging + SString strDebugHash; // Short hash of the loaded TXD bytes + SString strDebugResource; // Resource name, if known + bool bHasRequestedSpace = false; }; // Shader layers to render @@ -67,21 +82,23 @@ enum EEntityTypeMask typedef void (*PFN_WATCH_CALLBACK)(CSHADERDUMMY* pContext, CD3DDUMMY* pD3DDataNew, CD3DDUMMY* pD3DDataOld); -#define MAX_ATOMICS_PER_CLUMP 128 +#define MAX_ATOMICS_PER_CLUMP 128 class CRenderWare { public: - virtual bool ModelInfoTXDLoadTextures(SReplacementTextures* pReplacementTextures, const SString& strFilename, const SString& buffer, - bool bFilteringEnabled) = 0; - virtual bool ModelInfoTXDAddTextures(SReplacementTextures* pReplacementTextures, ushort usModelId) = 0; - virtual void ModelInfoTXDRemoveTextures(SReplacementTextures* pReplacementTextures) = 0; - virtual void ClothesAddReplacement(char* pFileData, size_t fileSize, ushort usFileId) = 0; - virtual void ClothesRemoveReplacement(char* pFileData) = 0; - virtual bool HasClothesReplacementChanged() = 0; - virtual bool ClothesAddFile(const char* fileData, std::size_t fileSize, const char* fileName) = 0; - virtual bool ClothesRemoveFile(char* fileData) = 0; - virtual bool HasClothesFile(const char* fileName) const noexcept = 0; + virtual bool ModelInfoTXDLoadTextures(SReplacementTextures* pReplacementTextures, const SString& strFilename, const SString& buffer, bool bFilteringEnabled, + SString* pOutError = nullptr) = 0; + virtual bool ModelInfoTXDAddTextures(SReplacementTextures* pReplacementTextures, unsigned short usModelId) = 0; + virtual void ModelInfoTXDRemoveTextures(SReplacementTextures* pReplacementTextures) = 0; + virtual void StaticResetModelTextureReplacing() = 0; + virtual void StaticResetShaderSupport() = 0; + virtual void ClothesAddReplacement(char* pFileData, size_t fileSize, unsigned short usFileId) = 0; + virtual void ClothesRemoveReplacement(char* pFileData) = 0; + virtual bool HasClothesReplacementChanged() = 0; + virtual bool ClothesAddFile(const char* fileData, std::size_t fileSize, const char* fileName) = 0; + virtual bool ClothesRemoveFile(char* fileData) = 0; + virtual bool HasClothesFile(const char* fileName) const = 0; virtual RwTexDictionary* ReadTXD(const SString& strFilename, const SString& buffer) = 0; virtual RpClump* ReadDFF(const SString& strFilename, const SString& buffer, unsigned short usModelID, bool bLoadEmbeddedCollisions) = 0; virtual CColModel* ReadCOL(const SString& buffer) = 0; @@ -96,25 +113,27 @@ class CRenderWare virtual void RepositionAtomic(RpClump* pDst, RpClump* pSrc, const char* szName) = 0; virtual void AddAllAtomics(RpClump* pDst, RpClump* pSrc) = 0; virtual bool ReplaceVehicleModel(RpClump* pNew, unsigned short usModelID) = 0; + virtual bool ReplaceClumpModel(RpClump* pNew, unsigned short usModelID) = 0; virtual bool ReplaceWeaponModel(RpClump* pNew, unsigned short usModelID) = 0; virtual bool ReplacePedModel(RpClump* pNew, unsigned short usModelID) = 0; virtual bool ReplacePartModels(RpClump* pClump, RpAtomicContainer* pAtomics, unsigned int uiAtomics, const char* szName) = 0; virtual void PulseWorldTextureWatch() = 0; - virtual void GetModelTextureNames(std::vector& outNameList, ushort usModelID) = 0; - virtual bool GetModelTextures(std::vector>& outTextureList, ushort usModelID, std::vector vTextureNames) = 0; - virtual const char* GetTextureName(CD3DDUMMY* pD3DData) = 0; - virtual ushort GetTXDIDForModelID(ushort usModelID) = 0; + virtual void GetModelTextureNames(std::vector& outNameList, unsigned short usModelID) = 0; + virtual bool GetModelTextures(std::vector>& outTextureList, unsigned short usModelID, + std::vector vTextureNames) = 0; + virtual const char* GetTextureName(CD3DDUMMY* pD3DData) = 0; + virtual unsigned short GetTXDIDForModelID(unsigned short usModelID) = 0; - virtual void SetRenderingClientEntity(CClientEntityBase* pClientEntity, ushort usModelId, int iTypeMask) = 0; + virtual void SetRenderingClientEntity(CClientEntityBase* pClientEntity, unsigned short usModelId, int iTypeMask) = 0; virtual SShaderItemLayers* GetAppliedShaderForD3DData(CD3DDUMMY* pD3DData) = 0; virtual void AppendAdditiveMatch(CSHADERDUMMY* pShaderData, CClientEntityBase* pClientEntity, const char* strTextureNameMatch, float fShaderPriority, - bool bShaderLayered, int iTypeMask, uint uiShaderCreateTime, bool bShaderUsesVertexShader, bool bAppendLayers) = 0; + bool bShaderLayered, int iTypeMask, unsigned int uiShaderCreateTime, bool bShaderUsesVertexShader, bool bAppendLayers) = 0; virtual void AppendSubtractiveMatch(CSHADERDUMMY* pShaderData, CClientEntityBase* pClientEntity, const char* strTextureNameMatch) = 0; virtual void RemoveClientEntityRefs(CClientEntityBase* pClientEntity) = 0; virtual void RemoveShaderRefs(CSHADERDUMMY* pShaderItem) = 0; virtual RwFrame* GetFrameFromName(RpClump* pRoot, SString strName) = 0; - virtual bool RightSizeTxd(const SString& strInTxdFilename, const SString& strOutTxdFilename, uint uiSizeLimit) = 0; - virtual void TxdForceUnload(ushort usTxdId, bool bDestroyTextures) = 0; + virtual bool RightSizeTxd(const SString& strInTxdFilename, const SString& strOutTxdFilename, unsigned int uiSizeLimit) = 0; + virtual void TxdForceUnload(unsigned short usTxdId, bool bDestroyTextures) = 0; virtual void CMatrixToRwMatrix(const CMatrix& mat, RwMatrix& rwOutMatrix) = 0; virtual void RwMatrixToCMatrix(const RwMatrix& rwMatrix, CMatrix& matOut) = 0; @@ -124,4 +143,32 @@ class CRenderWare virtual void RwMatrixSetPosition(RwMatrix& rwInOutMatrix, const CVector& vecPosition) = 0; virtual void RwMatrixGetScale(const RwMatrix& rwMatrix, CVector& vecOutScale) = 0; virtual void RwMatrixSetScale(RwMatrix& rwInOutMatrix, const CVector& vecScale) = 0; + + // New methods MUST be added at the end to preserve vtable order. + virtual void RebindClumpTexturesToTxd(RpClump* pClump, unsigned short usTxdId) = 0; + + // Cleanup TXD slots created to isolate engineRequestModel clones. + // bSkipStreamingLoads: When true, skip blocking streaming loads (use during session reset when streaming system may be unsafe) + virtual void CleanupIsolatedTxdForModel(unsigned short usModelId, bool bSkipStreamingLoads = false) = 0; + + // Rebind single atomic's material textures to current TXD textures + virtual void RebindAtomicTexturesToTxd(RpAtomic* pAtomic, unsigned short usTxdId) = 0; + + // Remove tracking state without destroying textures; used during shutdown. + virtual void ModelInfoTXDDeferCleanup(SReplacementTextures* pReplacementTextures) = 0; + + // Parses TXD buffer data and injects it directly into an allocated pool slot + virtual bool LoadTxdSlotFromBuffer(std::uint32_t uiSlotId, const std::string& buffer) = 0; + + // Clean up replacement texture tracking for a TXD slot that is about to be destroyed. + // Detaches all SReplacementTextures from this slot, orphans copy textures, and removes + // the ms_ModelTexturesInfoMap entry so later CClientTXD cleanup won't access freed data. + virtual void CleanupReplacementsInTxdSlot(unsigned short usTxdSlotId) = 0; + + // Complete any deferred isolated-TXD parent setup and apply queued replacement textures. + // Must be called after a blocking model load when the model may have pending TXD work, + // so that ReadDFF resolves textures from the correct (child) TXD instead of vanilla. + // When bBlockingParentLoad is true, parent TXDs that are not yet streamed in are loaded + // synchronously so the setup can complete in a single call. + virtual void ProcessPendingIsolatedTxdParents(bool bBlockingParentLoad = false) = 0; }; diff --git a/Client/sdk/game/CSettings.h b/Client/sdk/game/CSettings.h index 624b166fb56..1d4ee3a99a1 100644 --- a/Client/sdk/game/CSettings.h +++ b/Client/sdk/game/CSettings.h @@ -12,10 +12,10 @@ #pragma once #if (!defined(RWFORCEENUMSIZEINT)) -#define RWFORCEENUMSIZEINT ((int)((~((unsigned int)0))>>1)) + #define RWFORCEENUMSIZEINT ((int)((~((unsigned int)0)) >> 1)) #endif /* (!defined(RWFORCEENUMSIZEINT)) */ -enum VideoModeFlag // RwVideoModeFlag +enum VideoModeFlag // RwVideoModeFlag { rwVIDEOMODEEXCLUSIVE = 0x0001, /** #define INVALID_ARCHIVE_ID 0xFF -#define INVALID_STREAM_ID 0xFF +#define INVALID_STREAM_ID 0xFF enum class eModelLoadState : std::uint32_t { @@ -44,15 +44,23 @@ enum class PreloadAreaOption ALL }; +enum class RestreamOption +{ + ALL = 0, + VEHICLES, + PEDS, + OBJECTS +}; + struct CStreamingInfo { - uint16_t prevId = (uint16_t)-1; - uint16_t nextId = (uint16_t)-1; - uint16_t nextInImg = (uint16_t)-1; - uint8_t flg = 0u; - uint8_t archiveId = 0u; - uint32_t offsetInBlocks = 0u; - uint32_t sizeInBlocks = 0u; + uint16_t prevId = (uint16_t)-1; + uint16_t nextId = (uint16_t)-1; + uint16_t nextInImg = (uint16_t)-1; + uint8_t flg = 0u; + uint8_t archiveId = 0u; + uint32_t offsetInBlocks = 0u; + uint32_t sizeInBlocks = 0u; eModelLoadState loadState = eModelLoadState::LOADSTATE_NOT_LOADED; }; static_assert(sizeof(CStreamingInfo) == 0x14, "Invalid size for CStreamingInfo"); @@ -67,7 +75,7 @@ class CStreaming virtual void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel) = 0; virtual CStreamingInfo* GetStreamingInfo(uint32 id) = 0; virtual void ReinitStreaming() = 0; - virtual unsigned char AddArchive(const wchar_t *szFilePath) = 0; + virtual unsigned char AddArchive(const wchar_t* szFilePath) = 0; virtual void RemoveArchive(unsigned char ucArchiveID) = 0; virtual void SetStreamingInfo(unsigned int id, unsigned char usStreamID, unsigned int uiOffset, unsigned short usSize, unsigned int uiNextInImg = -1) = 0; virtual bool SetStreamingBufferSize(uint32 uiSize) = 0; diff --git a/Client/sdk/game/CTaskManager.h b/Client/sdk/game/CTaskManager.h index 69fba5b8d2d..d2b25a0232c 100644 --- a/Client/sdk/game/CTaskManager.h +++ b/Client/sdk/game/CTaskManager.h @@ -25,8 +25,8 @@ enum enum eSecondaryTaskType { - TASK_SECONDARY_ATTACK = 0, // want duck to be after attack - TASK_SECONDARY_DUCK, // because attack controls ducking movement + TASK_SECONDARY_ATTACK = 0, // want duck to be after attack + TASK_SECONDARY_DUCK, // because attack controls ducking movement TASK_SECONDARY_SAY, TASK_SECONDARY_FACIAL_COMPLEX, TASK_SECONDARY_PARTIAL_ANIM, @@ -47,7 +47,6 @@ enum taskType SECONDARY_TASK }; - class CTaskManager { public: diff --git a/Client/sdk/game/CTasks.h b/Client/sdk/game/CTasks.h index d55d4f5dbb1..4211b838519 100644 --- a/Client/sdk/game/CTasks.h +++ b/Client/sdk/game/CTasks.h @@ -46,13 +46,14 @@ class CTaskSimpleRunNamedAnim; class CTaskSimpleStealthKill; class CTaskSimpleTriggerLookAt; class CTaskSimpleUseGun; +class CTaskComplexInWater; class CVector; class CVehicle; typedef unsigned long AssocGroupId; typedef unsigned long AnimationId; -enum eClimbHeights +enum eClimbHeights : std::int8_t { CLIMB_NOT_READY = 0, CLIMB_GRAB, @@ -86,8 +87,8 @@ class CTasks unsigned short nUseShotsWhizzingEvents = -1) = 0; virtual CTaskSimpleChoking* CreateTaskSimpleChoking(CPed* pAttacker, bool bIsTearGas) = 0; - virtual CTaskSimpleClimb* CreateTaskSimpleClimb(CEntity* pClimbEnt, const CVector& vecTarget, float fHeading, unsigned char nSurfaceType, - char nHeight = CLIMB_GRAB, const bool bForceClimb = false) = 0; + virtual CTaskSimpleClimb* CreateTaskSimpleClimb(CEntitySAInterface* pClimbEnt, const CVector& vecTarget, float fHeading, unsigned char nSurfaceType, + eClimbHeights nHeight = CLIMB_GRAB, const bool bForceClimb = false) = 0; virtual CTaskSimpleJetPack* CreateTaskSimpleJetpack(const CVector* pVecTargetPos = NULL, float fCruiseHeight = 10.0f, int nHoverTime = 0) = 0; virtual CTaskSimpleRunAnim* CreateTaskSimpleRunAnim(const AssocGroupId animGroup, const AnimationId animID, const float fBlendDelta, const int iTaskType, @@ -96,6 +97,8 @@ class CTasks const int iTime = -1, const bool bDontInterrupt = false, const bool bRunInSequence = false, const bool bOffsetPed = false, const bool bHoldLastFrame = false) = 0; + virtual CTaskComplexInWater* CreateTaskComplexInWater() = 0; + virtual CTaskComplexDie* CreateTaskComplexDie(const eWeaponType eMeansOfDeath = WEAPONTYPE_UNARMED, const AssocGroupId animGroup = 0 /*ANIM_STD_PED*/, const AnimationId anim = 0 /*ANIM_STD_KO_FRONT*/, const float fBlendDelta = 4.0f, const float fAnimSpeed = 0.0f, const bool bBeingKilledByStealth = false, const bool bFallingToDeath = false, diff --git a/Client/sdk/game/CTrailer.h b/Client/sdk/game/CTrailer.h index e3ebb499b0d..905e76ec13f 100644 --- a/Client/sdk/game/CTrailer.h +++ b/Client/sdk/game/CTrailer.h @@ -16,5 +16,5 @@ class CTrailer : public virtual CVehicle { public: - virtual ~CTrailer(){}; + virtual ~CTrailer() {}; }; diff --git a/Client/sdk/game/CTrain.h b/Client/sdk/game/CTrain.h index 4dd13aeb73b..91c604d4438 100644 --- a/Client/sdk/game/CTrain.h +++ b/Client/sdk/game/CTrain.h @@ -15,5 +15,5 @@ class CTrain : public virtual CVehicle { public: - virtual ~CTrain(){}; + virtual ~CTrain() {}; }; diff --git a/Client/sdk/game/CTxdPool.h b/Client/sdk/game/CTxdPool.h index 1e4ff3493ba..432700b50ea 100644 --- a/Client/sdk/game/CTxdPool.h +++ b/Client/sdk/game/CTxdPool.h @@ -14,9 +14,31 @@ class CTxdPool { public: + // SA's original TXD pool size (not the expanded capacity - see TXD_POOL_MAX_CAPACITY). + // Only slots [0, 5000) have dedicated TXD streaming entries (model IDs 20000-24999). + // Slots >= 5000 map to COL/IPL/DAT/IFP streaming ID's and cannot be used for IMG linking. + static constexpr int SA_TXD_POOL_CAPACITY = 5000; + + // Maximum TXD slot index whose streaming ID (index + 20000) fits within + // SA's ms_aInfoForModel[26316]. Isolation TXDs prefer [0, 6316) but + // spill above when that fills up. + static constexpr int MAX_STREAMING_TXD_SLOT = 6316; + virtual std::uint32_t AllocateTextureDictonarySlot(std::uint32_t uiSlotID, std::string& strTxdName) = 0; virtual void RemoveTextureDictonarySlot(std::uint32_t uiTxdID) = 0; virtual bool IsFreeTextureDictonarySlot(std::uint32_t uiTxdID) = 0; - virtual std::uint16_t GetFreeTextureDictonarySlot() = 0; + virtual std::uint32_t GetFreeTextureDictonarySlot() = 0; + + // Returns the first free slot in [0, maxExclusive). + virtual std::uint32_t GetFreeTextureDictonarySlotInRange(std::uint32_t maxExclusive) = 0; + + // Returns the first free slot in [minInclusive, poolSize), or -1 if none. + virtual std::uint32_t GetFreeTextureDictonarySlotAbove(std::uint32_t minInclusive) = 0; + + // Returns the number of occupied slots in [0, maxExclusive). + virtual int GetUsedSlotCountInRange(std::uint32_t maxExclusive) const = 0; + + // Returns true if the slot is allocated and its RwTexDictionary is in memory. + virtual bool IsTxdLoaded(std::uint32_t uiTxdId) = 0; }; diff --git a/Client/sdk/game/CVehicle.h b/Client/sdk/game/CVehicle.h index ce4b337d541..778dbf8a37d 100644 --- a/Client/sdk/game/CVehicle.h +++ b/Client/sdk/game/CVehicle.h @@ -54,9 +54,9 @@ enum eDoorLock : int32_t }; #define SIREN_TYPE_FIRST 1 -#define SIREN_TYPE_LAST 6 -#define SIREN_ID_MAX 7 -#define SIREN_COUNT_MAX 8 +#define SIREN_TYPE_LAST 6 +#define SIREN_ID_MAX 7 +#define SIREN_COUNT_MAX 8 struct SSirenBeaconInfo { @@ -88,13 +88,22 @@ struct SVehicleFrame RwFrame* pFrame; bool bReadOnly; - std::vector frameList; // Frames from root to parent + std::vector frameList; // Frames from root to parent +}; + +enum class VehicleComponentType +{ + NONE = -1, + + DOOR, + PANEL, + WHEEL, }; class CVehicle : public virtual CPhysical { public: - virtual ~CVehicle(){}; + virtual ~CVehicle() {}; virtual bool AddProjectile(eWeaponType eWeapon, CVector vecOrigin, float fForce, CVector* target, CEntity* targetEntity) = 0; @@ -269,9 +278,9 @@ class CVehicle : public virtual CPhysical virtual SColor GetHeadLightColor() = 0; virtual void SetHeadLightColor(const SColor color) = 0; - virtual bool SpawnFlyingComponent(const eCarNodes& nodeIndex, const eCarComponentCollisionTypes& collisionType, std::int32_t removalTime = -1) = 0; - virtual void SetWheelVisibility(eWheelPosition wheel, bool bVisible) = 0; - virtual CVector GetWheelPosition(eWheelPosition wheel) = 0; + virtual bool SpawnFlyingComponent(const eCarNodes& nodeIndex, const eCarComponentCollisionTypes& collisionType, std::int32_t removalTime = -1) = 0; + virtual void SetWheelVisibility(eWheelPosition wheel, bool bVisible) = 0; + virtual CVector GetWheelPosition(eWheelPosition wheel) = 0; virtual bool IsHeliSearchLightVisible() = 0; virtual void SetHeliSearchLightVisible(bool bVisible) = 0; diff --git a/Client/sdk/game/CVehicleAudioSettingsEntry.h b/Client/sdk/game/CVehicleAudioSettingsEntry.h index f16a3c37217..fc980cf5761 100644 --- a/Client/sdk/game/CVehicleAudioSettingsEntry.h +++ b/Client/sdk/game/CVehicleAudioSettingsEntry.h @@ -17,23 +17,23 @@ class CVehicleAudioSettingsEntry { public: // Destructor - virtual ~CVehicleAudioSettingsEntry(){} + virtual ~CVehicleAudioSettingsEntry() {} // Get - virtual VehicleSoundType GetSoundType() const noexcept = 0; - virtual short GetEngineOnSoundBankID() const noexcept = 0; - virtual short GetEngineOffSoundBankID() const noexcept = 0; - virtual char GetBassSetting() const noexcept = 0; - virtual float GetBassEq() const noexcept = 0; - virtual float GetFieldC() const noexcept = 0; - virtual char GetHornTon() const noexcept = 0; - virtual float GetHornHign() const noexcept = 0; - virtual char GetEngineUpgrade() const noexcept = 0; - virtual char GetDoorSound() const noexcept = 0; - virtual char GetRadioNum() const noexcept = 0; - virtual char GetRadioType() const noexcept = 0; - virtual char GetVehicleTypeForAudio() const noexcept = 0; - virtual float GetHornVolumeDelta() const noexcept = 0; + virtual VehicleSoundType GetSoundType() const noexcept = 0; + virtual short GetEngineOnSoundBankID() const noexcept = 0; + virtual short GetEngineOffSoundBankID() const noexcept = 0; + virtual char GetBassSetting() const noexcept = 0; + virtual float GetBassEq() const noexcept = 0; + virtual float GetFieldC() const noexcept = 0; + virtual char GetHornTon() const noexcept = 0; + virtual float GetHornHign() const noexcept = 0; + virtual char GetEngineUpgrade() const noexcept = 0; + virtual char GetDoorSound() const noexcept = 0; + virtual char GetRadioNum() const noexcept = 0; + virtual char GetRadioType() const noexcept = 0; + virtual char GetVehicleTypeForAudio() const noexcept = 0; + virtual float GetHornVolumeDelta() const noexcept = 0; // Set virtual void SetSoundType(VehicleSoundType value) noexcept = 0; diff --git a/Client/sdk/game/CVehicleAudioSettingsManager.h b/Client/sdk/game/CVehicleAudioSettingsManager.h index a34864cb99e..7a77ef2591b 100644 --- a/Client/sdk/game/CVehicleAudioSettingsManager.h +++ b/Client/sdk/game/CVehicleAudioSettingsManager.h @@ -18,7 +18,7 @@ class CVehicleAudioSettingsManager public: virtual std::unique_ptr CreateVehicleAudioSettingsData(uint32_t modelId) = 0; virtual CVehicleAudioSettingsEntry& GetVehicleModelAudioSettingsData(uint32_t modelId) noexcept = 0; - + virtual void ResetModelSettings(uint32_t modelId) noexcept = 0; virtual void ResetAudioSettingsData() noexcept = 0; virtual void SetNextSettings(CVehicleAudioSettingsEntry const* pSettings) noexcept = 0; diff --git a/Client/sdk/game/CVisibilityPlugins.h b/Client/sdk/game/CVisibilityPlugins.h index 3d857dd5f75..55765d64548 100644 --- a/Client/sdk/game/CVisibilityPlugins.h +++ b/Client/sdk/game/CVisibilityPlugins.h @@ -11,8 +11,8 @@ #pragma once -#define ATOMIC_ID_FLAG_TWO_VERSIONS_UNDAMAGED 1 -#define ATOMIC_ID_FLAG_TWO_VERSIONS_DAMAGED 2 +#define ATOMIC_ID_FLAG_TWO_VERSIONS_UNDAMAGED 1 +#define ATOMIC_ID_FLAG_TWO_VERSIONS_DAMAGED 2 struct RpClump; struct RwObject; diff --git a/Client/sdk/game/CWaterManager.h b/Client/sdk/game/CWaterManager.h index 05eee46507b..e399743d0fa 100644 --- a/Client/sdk/game/CWaterManager.h +++ b/Client/sdk/game/CWaterManager.h @@ -35,6 +35,6 @@ class CWaterManager virtual bool TestLineAgainstWater(const CVector& vecStart, const CVector& vecEnd, CVector* vecCollision) = 0; virtual void UndoChanges(void* pChangeSource = NULL) = 0; - virtual void RebuildIndex() = 0; // Call this after moving a polygon's vertices - virtual void Reset() = 0; // Reset all water to SA default + virtual void RebuildIndex() = 0; // Call this after moving a polygon's vertices + virtual void Reset() = 0; // Reset all water to SA default }; diff --git a/Client/sdk/game/CWeaponInfo.h b/Client/sdk/game/CWeaponInfo.h index 5ad4760cb6b..ac03689eff3 100644 --- a/Client/sdk/game/CWeaponInfo.h +++ b/Client/sdk/game/CWeaponInfo.h @@ -20,7 +20,7 @@ enum eWeaponSkill : std::uint8_t WEAPONSKILL_POOR = 0, WEAPONSKILL_STD, WEAPONSKILL_PRO, - WEAPONSKILL_SPECIAL, // for cops using pistols differently for example + WEAPONSKILL_SPECIAL, // for cops using pistols differently for example WEAPONSKILL_MAX_NUMBER }; @@ -42,15 +42,15 @@ enum eWeaponSlot WEAPONSLOT_TYPE_MELEE, WEAPONSLOT_TYPE_HANDGUN, WEAPONSLOT_TYPE_SHOTGUN, - WEAPONSLOT_TYPE_SMG, // 4 + WEAPONSLOT_TYPE_SMG, // 4 WEAPONSLOT_TYPE_MG, WEAPONSLOT_TYPE_RIFLE, WEAPONSLOT_TYPE_HEAVY, WEAPONSLOT_TYPE_THROWN, - WEAPONSLOT_TYPE_SPECIAL, // 9 - WEAPONSLOT_TYPE_GIFT, // 10 - WEAPONSLOT_TYPE_PARACHUTE, // 11 - WEAPONSLOT_TYPE_DETONATOR, // 12 + WEAPONSLOT_TYPE_SPECIAL, // 9 + WEAPONSLOT_TYPE_GIFT, // 10 + WEAPONSLOT_TYPE_PARACHUTE, // 11 + WEAPONSLOT_TYPE_DETONATOR, // 12 WEAPONSLOT_MAX }; @@ -81,7 +81,7 @@ enum eWeaponType WEAPONTYPE_CHAINSAW, // gifts - WEAPONTYPE_DILDO1, // 10 + WEAPONTYPE_DILDO1, // 10 WEAPONTYPE_DILDO2, WEAPONTYPE_VIBE1, WEAPONTYPE_VIBE2, @@ -92,31 +92,31 @@ enum eWeaponType WEAPONTYPE_TEARGAS, WEAPONTYPE_MOLOTOV, WEAPONTYPE_ROCKET, - WEAPONTYPE_ROCKET_HS, // 20 + WEAPONTYPE_ROCKET_HS, // 20 WEAPONTYPE_FREEFALL_BOMB, // FIRST SKILL WEAPON - WEAPONTYPE_PISTOL, // handguns + WEAPONTYPE_PISTOL, // handguns WEAPONTYPE_PISTOL_SILENCED, WEAPONTYPE_DESERT_EAGLE, - WEAPONTYPE_SHOTGUN, // shotguns - WEAPONTYPE_SAWNOFF_SHOTGUN, // one handed + WEAPONTYPE_SHOTGUN, // shotguns + WEAPONTYPE_SAWNOFF_SHOTGUN, // one handed WEAPONTYPE_SPAS12_SHOTGUN, - WEAPONTYPE_MICRO_UZI, // submachine guns + WEAPONTYPE_MICRO_UZI, // submachine guns WEAPONTYPE_MP5, - WEAPONTYPE_AK47, // 30 // machine guns + WEAPONTYPE_AK47, // 30 // machine guns WEAPONTYPE_M4, - WEAPONTYPE_TEC9, // this uses stat from the micro_uzi + WEAPONTYPE_TEC9, // this uses stat from the micro_uzi // END SKILL WEAPONS - WEAPONTYPE_COUNTRYRIFLE, // rifles + WEAPONTYPE_COUNTRYRIFLE, // rifles WEAPONTYPE_SNIPERRIFLE, - WEAPONTYPE_ROCKETLAUNCHER, // specials + WEAPONTYPE_ROCKETLAUNCHER, // specials WEAPONTYPE_ROCKETLAUNCHER_HS, WEAPONTYPE_FLAMETHROWER, WEAPONTYPE_MINIGUN, WEAPONTYPE_REMOTE_SATCHEL_CHARGE, - WEAPONTYPE_DETONATOR, // 40 // plastic explosive + WEAPONTYPE_DETONATOR, // 40 // plastic explosive WEAPONTYPE_SPRAYCAN, WEAPONTYPE_EXTINGUISHER, WEAPONTYPE_CAMERA, @@ -128,12 +128,12 @@ enum eWeaponType WEAPONTYPE_ARMOUR, // these are possible ways to die WEAPONTYPE_RAMMEDBYCAR, - WEAPONTYPE_RUNOVERBYCAR, // 50 + WEAPONTYPE_RUNOVERBYCAR, // 50 WEAPONTYPE_EXPLOSION, WEAPONTYPE_UZI_DRIVEBY, WEAPONTYPE_DROWNING, WEAPONTYPE_FALL, - WEAPONTYPE_UNIDENTIFIED, // Used for damage being done + WEAPONTYPE_UNIDENTIFIED, // Used for damage being done WEAPONTYPE_ANYMELEE, WEAPONTYPE_ANYWEAPON, WEAPONTYPE_FLARE, @@ -245,11 +245,11 @@ class CWeaponInfo virtual float GetRequiredStatLevel() = 0; virtual void SetRequiredStatLevel(float fStatLevel) = 0; - virtual void SetFlags(int flags) = 0; - virtual void SetFlag(DWORD flag) = 0; - virtual void ClearFlag(DWORD flag) = 0; - virtual bool IsFlagSet(DWORD flag) = 0; - virtual short GetFlags() = 0; + virtual void SetFlags(int flags) = 0; + virtual void SetFlag(DWORD flag) = 0; + virtual void ClearFlag(DWORD flag) = 0; + virtual bool IsFlagSet(DWORD flag) = 0; + virtual int GetFlags() = 0; virtual DWORD GetAnimGroup() = 0; virtual void SetAnimGroup(DWORD dwAnimGroup) = 0; diff --git a/Client/sdk/game/CWorld.h b/Client/sdk/game/CWorld.h index cb86712ade8..7fb82345ce0 100644 --- a/Client/sdk/game/CWorld.h +++ b/Client/sdk/game/CWorld.h @@ -39,7 +39,7 @@ struct SLineOfSightFlags bool bCheckDummies; bool bSeeThroughStuff; bool bIgnoreSomeObjectsForCamera; - bool bShootThroughStuff; // not used for IsLineOfSightClear + bool bShootThroughStuff; // not used for IsLineOfSightClear bool bCheckCarTires; }; @@ -54,22 +54,23 @@ struct SLineOfSightBuildingResult CEntitySAInterface* pInterface; }; -struct SProcessLineOfSightMaterialInfoResult { - CVector2D uv; //< On-texture UV coordinates of the intersection point - const char* textureName; //< GTA texture name - const char* frameName; //< The name of the frame the hit geometry belongs to - CVector hitPos; //< Precise hit position on the clump [World space] - bool valid{}; //< Data found in this struct is only valid if this is `true`! +struct SProcessLineOfSightMaterialInfoResult +{ + CVector2D uv; //< On-texture UV coordinates of the intersection point + const char* textureName; //< GTA texture name + const char* frameName; //< The name of the frame the hit geometry belongs to + CVector hitPos; //< Precise hit position on the clump [World space] + bool valid{}; //< Data found in this struct is only valid if this is `true`! }; struct STestSphereAgainstWorldResult { - bool collisionDetected{false}; - std::uint32_t modelID{0}; - CVector entityPosition{}; - CVector entityRotation{}; - std::uint32_t lodID{0}; - eEntityType type{ENTITY_TYPE_NOTHING}; + bool collisionDetected{false}; + std::uint32_t modelID{0}; + CVector entityPosition{}; + CVector entityRotation{}; + std::uint32_t lodID{0}; + eEntityType type{ENTITY_TYPE_NOTHING}; }; enum eDebugCaller @@ -181,58 +182,58 @@ class SurfaceInfo_c { public: uint8_t m_tyreGrip; - uint8_t m_wetGrip; // 2 - uint16_t pad; // 4 + uint8_t m_wetGrip; // 2 + uint16_t pad; // 4 union { - struct // size 8 + struct // size 8 { uint32_t flags[2]; }; - struct // size = 51 + struct // size = 51 { - uint32_t m_adhesionGroup : 3; // 1 - 3 - uint32_t m_skidmarkType : 2; // 4 - 5 - uint32_t m_frictionEffect : 3; // 6 - 8 - uint32_t m_bulletFx : 3; // 9 - 11 - uint32_t m_softLanding : 1; // 12 - uint32_t m_seeThrough : 1; // 13 - uint32_t m_shootThrough : 1; // 14 - uint32_t m_sand : 1; // 15 + uint32_t m_adhesionGroup : 3; // 1 - 3 + uint32_t m_skidmarkType : 2; // 4 - 5 + uint32_t m_frictionEffect : 3; // 6 - 8 + uint32_t m_bulletFx : 3; // 9 - 11 + uint32_t m_softLanding : 1; // 12 + uint32_t m_seeThrough : 1; // 13 + uint32_t m_shootThrough : 1; // 14 + uint32_t m_sand : 1; // 15 uint32_t m_water : 1; - uint32_t m_shallowWater : 1; // unknown effect + uint32_t m_shallowWater : 1; // unknown effect uint32_t m_beach : 1; uint32_t m_steepSlope : 1; - uint32_t m_glass : 1; // 20 + uint32_t m_glass : 1; // 20 uint32_t m_stairs : 1; uint32_t m_skateable : 1; uint32_t m_pavement : 1; - uint32_t m_roughness : 2; // 24 - 25 - uint32_t m_flammability : 2; // 26 - 27 - uint32_t m_createsSparks : 1; // 28 - uint32_t m_cantSprintOn : 1; // 29 + uint32_t m_roughness : 2; // 24 - 25 + uint32_t m_flammability : 2; // 26 - 27 + uint32_t m_createsSparks : 1; // 28 + uint32_t m_cantSprintOn : 1; // 29 uint32_t m_leavesFootsteps : 1; uint32_t m_producesFootDust : 1; - uint32_t m_makesCarDirty : 1; // 32 + uint32_t m_makesCarDirty : 1; // 32 - uint32_t m_makesCarClean : 1; // 1 + uint32_t m_makesCarClean : 1; // 1 uint32_t m_createsWheelGrass : 1; uint32_t m_createsWheelGravel : 1; uint32_t m_createsWheelMud : 1; - uint32_t m_createsWheelDust : 1; // 5 - uint32_t m_createsWheelSand : 1; // no effect - uint32_t m_createsWheelSpray : 1; // crash - uint32_t m_createsPlants : 1; // 8 + uint32_t m_createsWheelDust : 1; // 5 + uint32_t m_createsWheelSand : 1; // no effect + uint32_t m_createsWheelSpray : 1; // crash + uint32_t m_createsPlants : 1; // 8 uint32_t m_createsObjects : 1; - uint32_t m_canClimb : 1; // 10 - uint32_t m_audioConcrete : 1; // 11 + uint32_t m_canClimb : 1; // 10 + uint32_t m_audioConcrete : 1; // 11 uint32_t m_audioGrass : 1; - uint32_t m_audioSand : 1; // 13 + uint32_t m_audioSand : 1; // 13 uint32_t m_audioGravel : 1; uint32_t m_audioWood : 1; uint32_t m_audioWater : 1; uint32_t m_audioMetal : 1; - uint32_t m_audioLongGrass : 1; // 18 + uint32_t m_audioLongGrass : 1; // 18 uint32_t m_audioTile : 1; }; }; @@ -264,7 +265,8 @@ class CWorld virtual void Remove(CEntitySAInterface* entityInterface, eDebugCaller CallerId) = 0; virtual auto ProcessLineAgainstMesh(CEntitySAInterface* e, CVector start, CVector end) -> SProcessLineOfSightMaterialInfoResult = 0; virtual bool ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd, CColPoint** colCollision, CEntity** CollisionEntity, - const SLineOfSightFlags flags = SLineOfSightFlags(), SLineOfSightBuildingResult* pBuildingResult = NULL, SProcessLineOfSightMaterialInfoResult* outMatInfo = {}) = 0; + const SLineOfSightFlags flags = SLineOfSightFlags(), SLineOfSightBuildingResult* pBuildingResult = NULL, + SProcessLineOfSightMaterialInfoResult* outMatInfo = {}) = 0; virtual void IgnoreEntity(CEntity* entity) = 0; virtual float FindGroundZFor3DPosition(CVector* vecPosition) = 0; virtual float FindRoofZFor3DCoord(CVector* pvecPosition, bool* pbOutResult) = 0; @@ -288,5 +290,6 @@ class CWorld virtual void ResetAllSurfaceInfo() = 0; virtual bool ResetSurfaceInfo(short sSurfaceID) = 0; - virtual CEntity* TestSphereAgainstWorld(const CVector& sphereCenter, float radius, CEntity* ignoredEntity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool cameraIgnore, STestSphereAgainstWorldResult& result) = 0; + virtual CEntity* TestSphereAgainstWorld(const CVector& sphereCenter, float radius, CEntity* ignoredEntity, bool checkBuildings, bool checkVehicles, + bool checkPeds, bool checkObjects, bool checkDummies, bool cameraIgnore, STestSphereAgainstWorldResult& result) = 0; }; diff --git a/Client/sdk/game/Common.h b/Client/sdk/game/Common.h index 80810a7d24d..fa3597f9b88 100644 --- a/Client/sdk/game/Common.h +++ b/Client/sdk/game/Common.h @@ -13,42 +13,42 @@ #include // Limits for MTA -#define MAX_VEHICLES_MTA 64 // Real limit is 110 -#define MAX_PEDS_MTA 110 // Real limit is 140 -#define MAX_OBJECTS_MTA 1000 // Real limit is 1200 -#define MAX_ENTRY_INFO_NODES_MTA 72000 // Real limit is 72600 ( MAX_OBJECTS_MTA * 72 ) [Large col models are the cause of high usage] -#define MAX_POINTER_SINGLE_LINKS_MTA 85000 // Real limit is 90000 [Large col models are the cause of high usage] -#define MAX_POINTER_DOUBLE_LINKS_MTA 74000 // Real limit is 74800 ( MAX_OBJECTS_MTA * 72 + 2000 ) +#define MAX_VEHICLES_MTA 64 // Real limit is 110 +#define MAX_PEDS_MTA 110 // Real limit is 140 +#define MAX_OBJECTS_MTA 1000 // Real limit is 1200 +#define MAX_ENTRY_INFO_NODES_MTA 72000 // Real limit is 72600 ( MAX_OBJECTS_MTA * 72 ) [Large col models are the cause of high usage] +#define MAX_POINTER_SINGLE_LINKS_MTA 85000 // Real limit is 90000 [Large col models are the cause of high usage] +#define MAX_POINTER_DOUBLE_LINKS_MTA 74000 // Real limit is 74800 ( MAX_OBJECTS_MTA * 72 + 2000 ) // Real limits for GTA -#define MAX_VEHICLES ( MAX_VEHICLES_MTA + 46 ) // 110 -#define MAX_PEDS ( MAX_PEDS_MTA + 30 ) // 140 -#define MAX_OBJECTS ( MAX_OBJECTS_MTA + 200 ) // 1200 -#define MAX_BUILDINGS 13000 -#define MAX_DUMMIES 2500 -#define MAX_ENTRY_INFO_NODES ( MAX_ENTRY_INFO_NODES_MTA + 600 ) // 72600 -#define MAX_POINTER_SINGLE_LINKS ( MAX_POINTER_SINGLE_LINKS_MTA + 5000 ) // 90000 May be changed in runtime -#define MAX_POINTER_DOUBLE_LINKS ( MAX_POINTER_DOUBLE_LINKS_MTA + 800 ) // 74800 -#define MAX_RWOBJECT_INSTANCES 2500 +#define MAX_VEHICLES (MAX_VEHICLES_MTA + 46) // 110 +#define MAX_PEDS (MAX_PEDS_MTA + 30) // 140 +#define MAX_OBJECTS (MAX_OBJECTS_MTA + 200) // 1200 +#define MAX_BUILDINGS 13000 +#define MAX_DUMMIES 2500 +#define MAX_ENTRY_INFO_NODES (MAX_ENTRY_INFO_NODES_MTA + 600) // 72600 +#define MAX_POINTER_SINGLE_LINKS (MAX_POINTER_SINGLE_LINKS_MTA + 5000) // 90000 May be changed in runtime +#define MAX_POINTER_DOUBLE_LINKS (MAX_POINTER_DOUBLE_LINKS_MTA + 800) // 74800 +#define MAX_RWOBJECT_INSTANCES 2500 /** * Flags used to define weapon characteristics */ // aiming options -#define WEAPONTYPE_CANAIM (0x000001) // can auto target to aim -#define WEAPONTYPE_CANAIMWITHARM (0x000002) // only needs arm to aim -#define WEAPONTYPE_FIRSTPERSON (0x000004) // uses 1st person aim -#define WEAPONTYPE_CANFREEAIM (0x000008) // can only use free aiming +#define WEAPONTYPE_CANAIM (0x000001) // can auto target to aim +#define WEAPONTYPE_CANAIMWITHARM (0x000002) // only needs arm to aim +#define WEAPONTYPE_FIRSTPERSON (0x000004) // uses 1st person aim +#define WEAPONTYPE_CANFREEAIM (0x000008) // can only use free aiming // movement options -#define WEAPONTYPE_MOVEAIM (0x000010) // can move and aim at same time -#define WEAPONTYPE_MOVEFIRE (0x000020) // can move and fire at same time +#define WEAPONTYPE_MOVEAIM (0x000010) // can move and aim at same time +#define WEAPONTYPE_MOVEFIRE (0x000020) // can move and fire at same time // basic characteristics -#define WEAPONTYPE_THROW (0x000100) // is a throwing weapon -#define WEAPONTYPE_HEAVY (0x000200) // heavy weapon - can't jump -#define WEAPONTYPE_CONTINUOUS_FIRE (0x000400) // fires every frame within loop (ie paint spray) -#define WEAPONTYPE_TWIN_PISTOLS (0x000800) // can use 2x guns at same time +#define WEAPONTYPE_THROW (0x000100) // is a throwing weapon +#define WEAPONTYPE_HEAVY (0x000200) // heavy weapon - can't jump +#define WEAPONTYPE_CONTINUOUS_FIRE (0x000400) // fires every frame within loop (ie paint spray) +#define WEAPONTYPE_TWIN_PISTOLS (0x000800) // can use 2x guns at same time // these are gun anim options #define WEAPONTYPE_ANIM_RELOAD (0x001000) // weapon has reload anims @@ -57,8 +57,8 @@ #define WEAPONTYPE_LONG_RELOAD_TIME (0x008000) // force a longer reload time! // these are area effect/shot options -#define WEAPONTYPE_SLOWS_DOWN (0x010000) // -#define WEAPONTYPE_RANDOM_SPEED (0x020000) // +#define WEAPONTYPE_SLOWS_DOWN (0x010000) // +#define WEAPONTYPE_RANDOM_SPEED (0x020000) // #define WEAPONTYPE_FORCE_FINISH_ANIM (0x040000) // force the anim to finish player after aim/fire rather than blending out -#define WEAPONTYPE_EXPANDS (0x080000) // -#define WEAPONTYPE_CHAINGUN WEAPONTYPE_MINIGUN +#define WEAPONTYPE_EXPANDS (0x080000) // +#define WEAPONTYPE_CHAINGUN WEAPONTYPE_MINIGUN diff --git a/Client/sdk/game/RenderWare.h b/Client/sdk/game/RenderWare.h index d43099d0cc2..c0a4257b059 100644 --- a/Client/sdk/game/RenderWare.h +++ b/Client/sdk/game/RenderWare.h @@ -22,10 +22,10 @@ #define RWFORCEENUMSIZEINT ((std::int32_t)((~((std::uint32_t)0)) >> 1)) #endif #define RWPLUGINOFFSET(_type, _base, _offset) ((_type*)((std::uint8_t*)(_base) + (_offset))) -#define RW_STRUCT_ALIGN ((int)((~((unsigned int)0))>>1)) -#define RW_TEXTURE_NAME_LENGTH 32 -#define RW_FRAME_NAME_LENGTH 23 -#define RW_MAX_TEXTURE_COORDS 8 +#define RW_STRUCT_ALIGN ((int)((~((unsigned int)0)) >> 1)) +#define RW_TEXTURE_NAME_LENGTH 32 +#define RW_FRAME_NAME_LENGTH 23 +#define RW_MAX_TEXTURE_COORDS 8 /* Type IDs */ @@ -59,11 +59,11 @@ typedef RpClump* (*RpClumpCallback)(RpClump* clump, void* data); // RenderWare primitive types struct RwV2d -{ // 8-byte +{ // 8-byte float x, y; }; struct RwV3d -{ // 12-byte +{ // 12-byte float x, y, z; }; struct RwPlane @@ -207,7 +207,7 @@ struct RwObject unsigned char subtype; unsigned char flags; unsigned char privateFlags; - void* parent; // should be RwFrame with RpClump + void* parent; // should be RwFrame with RpClump }; struct RwVertex { @@ -226,18 +226,18 @@ struct RwList }; struct RwFrame { - RwObject object; // 0 - void * pad1, *pad2; // 8 - RwMatrix modelling; // 16 - RwMatrix ltm; // 32 - RwList objects; // 48 - struct RwFrame* child; // 56 - struct RwFrame* next; // 60 - struct RwFrame* root; // 64 + RwObject object; // 0 + void * pad1, *pad2; // 8 + RwMatrix modelling; // 16 + RwMatrix ltm; // 32 + RwList objects; // 48 + struct RwFrame* child; // 56 + struct RwFrame* next; // 60 + struct RwFrame* root; // 64 // Rockstar Frame extension (0x253F2FE) (24 bytes) - unsigned char pluginData[8]; // padding - char szName[RW_FRAME_NAME_LENGTH + 1]; // name (as stored in the frame extension) + unsigned char pluginData[8]; // padding + char szName[RW_FRAME_NAME_LENGTH + 1]; // name (as stored in the frame extension) }; struct RwTexDictionary { @@ -261,11 +261,11 @@ struct RwTextureCoordinates }; struct RwRaster { - RwRaster* parent; // 0 - unsigned char* pixels; // 4 - unsigned char* palette; // 8 - int width, height, depth; // 12, 16 / 0x10, 20 - int numLevels; // 24 / 0x18 + RwRaster* parent; // 0 + unsigned char* pixels; // 4 + unsigned char* palette; // 8 + int width, height, depth; // 12, 16 / 0x10, 20 + int numLevels; // 24 / 0x18 short u, v; unsigned char type; unsigned char flags; @@ -273,7 +273,7 @@ struct RwRaster unsigned char format; unsigned char* origPixels; int origWidth, origHeight, origDepth; - void* renderResource; // RwD3D9Raster continues from here + void* renderResource; // RwD3D9Raster continues from here }; struct RwColorFloat { @@ -372,7 +372,7 @@ struct RpLight unsigned short unknown2; }; struct RpClump -{ // RenderWare (plugin) Clump (used by GTA) +{ // RenderWare (plugin) Clump (used by GTA) RwObject object; RwList atomics; RwList lights; @@ -407,9 +407,9 @@ struct RpTriangle struct RpMorphTarget { RpGeometry* parentGeom; - RwSphere boundingSphere; - RwV3d* verts; - RwV3d* normals; + RwSphere boundingSphere; + RwV3d* verts; + RwV3d* normals; }; struct RpGeometry { @@ -432,31 +432,34 @@ struct RpGeometry RpMorphTarget* morph_target; }; -inline auto rwObjectGetParent(RwObject* o) { +inline auto rwObjectGetParent(RwObject* o) +{ return (RwObject*)o->parent; } -inline auto RpAtomicGetFrame(RpAtomic* atomic) { +inline auto RpAtomicGetFrame(RpAtomic* atomic) +{ return (RwFrame*)atomic->object.object.parent; } -inline auto RwFrameGetParent(RwFrame* f) { +inline auto RwFrameGetParent(RwFrame* f) +{ return (RwFrame*)rwObjectGetParent((RwObject*)f); } -inline RwMatrix* RwFrameGetMatrix(RwFrame* f) { +inline RwMatrix* RwFrameGetMatrix(RwFrame* f) +{ return &f->modelling; } -inline void _rpAtomicResyncInterpolatedSphere(RpAtomic* atomic) { +inline void _rpAtomicResyncInterpolatedSphere(RpAtomic* atomic) +{ reinterpret_cast(0x7491F0)(atomic); } /* NB "RpAtomicGetBoundingSphere(atomic++)" will break it */ -#define RpAtomicGetBoundingSphere(_atomic) \ - ((((_atomic)->interpolator.flags & rpINTERPOLATORDIRTYSPHERE)? \ - _rpAtomicResyncInterpolatedSphere(_atomic), 0: 0), \ - &((_atomic)->boundingSphere)) +#define RpAtomicGetBoundingSphere(_atomic) \ + ((((_atomic)->interpolator.flags & rpINTERPOLATORDIRTYSPHERE) ? _rpAtomicResyncInterpolatedSphere(_atomic), 0 : 0), &((_atomic)->boundingSphere)) /*****************************************************************************/ /** RenderWare I/O **/ @@ -554,13 +557,13 @@ struct RwDevice typedef bool (*RwStandardFunc)(void*, void*, std::int32_t); struct RwGlobals { - void* curCamera; - void* curWorld; - std::uint16_t renderFrame; - std::uint16_t lightFrame; - std::uint16_t pad[2]; - RwDevice dOpenDevice; - RwStandardFunc stdFunc[29]; + void* curCamera; + void* curWorld; + std::uint16_t renderFrame; + std::uint16_t lightFrame; + std::uint16_t pad[2]; + RwDevice dOpenDevice; + RwStandardFunc stdFunc[29]; // RwLinkList dirtyFrameList; // RwFileFunctions fileFuncs; // RwStringFunctions stringFuncs; @@ -571,4 +574,4 @@ struct RwGlobals // RwEngineStatus engineStatus; // RwUInt32 resArenaInitSize; }; -//static_assert(sizeof(RwGlobals) == 0x158, "Incorrect class size: RwGlobals"); +// static_assert(sizeof(RwGlobals) == 0x158, "Incorrect class size: RwGlobals"); diff --git a/Client/sdk/game/RenderWareD3D.h b/Client/sdk/game/RenderWareD3D.h index e39a4038651..77fbca332b2 100644 --- a/Client/sdk/game/RenderWareD3D.h +++ b/Client/sdk/game/RenderWareD3D.h @@ -11,6 +11,10 @@ * *****************************************************************************/ +#pragma once + +#include + // From SA::Render struct RwD3D9Raster { diff --git a/Client/sdk/game/Task.h b/Client/sdk/game/Task.h index f233a7e68ef..ae5dd16b24a 100644 --- a/Client/sdk/game/Task.h +++ b/Client/sdk/game/Task.h @@ -17,27 +17,27 @@ class CEvent; class CPed; class CTaskSAInterface; -#define NO_TASK_TYPE 9999 +#define NO_TASK_TYPE 9999 class CTask { public: - virtual ~CTask(){}; + virtual ~CTask() {}; - virtual CTask* Clone() = 0; - virtual void SetParent(CTask* pParent) = 0; - virtual CTask* GetParent() = 0; - virtual CTask* GetSubTask() = 0; - virtual bool IsSimpleTask() = 0; - virtual int GetTaskType() = 0; // returns NO_TASK_TYPE if no task type exists - virtual void StopTimer(const CEvent* pEvent) = 0; - virtual bool MakeAbortable(CPed* pPed, const int iPriority, const CEvent* pEvent) = 0; - virtual const char* GetTaskName() = 0; - virtual class CTaskSAInterface* GetInterface() noexcept = 0; + virtual CTask* Clone() = 0; + virtual void SetParent(CTask* pParent) = 0; + virtual CTask* GetParent() = 0; + virtual CTask* GetSubTask() = 0; + virtual bool IsSimpleTask() = 0; + virtual int GetTaskType() = 0; // returns NO_TASK_TYPE if no task type exists + virtual void StopTimer(const CEvent* pEvent) = 0; + virtual bool MakeAbortable(CPed* pPed, const int iPriority, const CEvent* pEvent) = 0; + virtual const char* GetTaskName() = 0; + virtual class CTaskSAInterface* GetInterface() noexcept = 0; virtual const class CTaskSAInterface* GetInterface() const noexcept = 0; - virtual bool IsValid() = 0; - virtual void SetAsPedTask(CPed* pPed, const int iTaskPriority, const bool bForceNewTask = false) = 0; - virtual void SetAsSecondaryPedTask(CPed* pPed, const int iType) = 0; + virtual bool IsValid() = 0; + virtual void SetAsPedTask(CPed* pPed, const int iTaskPriority, const bool bForceNewTask = false) = 0; + virtual void SetAsSecondaryPedTask(CPed* pPed, const int iType) = 0; virtual void Destroy() = 0; virtual void DestroyJustThis() = 0; @@ -46,7 +46,7 @@ class CTask class CTaskSimple : public virtual CTask { public: - virtual ~CTaskSimple(){}; + virtual ~CTaskSimple() {}; virtual bool ProcessPed(CPed* pPed) = 0; virtual bool SetPedPosition(CPed* pPed) = 0; @@ -55,7 +55,7 @@ class CTaskSimple : public virtual CTask class CTaskComplex : public virtual CTask { public: - virtual ~CTaskComplex(){}; + virtual ~CTaskComplex() {}; virtual void SetSubTask(CTask* pSubTask) = 0; virtual CTask* CreateNextSubTask(CPed* pPed) = 0; diff --git a/Client/sdk/game/TaskAttack.h b/Client/sdk/game/TaskAttack.h index 5f1741e60fa..59d7a13a785 100644 --- a/Client/sdk/game/TaskAttack.h +++ b/Client/sdk/game/TaskAttack.h @@ -19,7 +19,7 @@ class CVector; class CTaskSimpleGangDriveBy : public virtual CTaskSimple { public: - virtual ~CTaskSimpleGangDriveBy(){}; + virtual ~CTaskSimpleGangDriveBy() {}; }; enum eGunCommand @@ -39,7 +39,7 @@ class CVector2D; class CTaskSimpleUseGun : public virtual CTaskSimple { public: - virtual ~CTaskSimpleUseGun(){}; + virtual ~CTaskSimpleUseGun() {}; virtual bool ControlGun(CPed* pPed, CEntity* pTargetEntity, char nCommand) = 0; virtual bool ControlGunMove(CVector2D* pMoveVec) = 0; @@ -51,5 +51,5 @@ class CTaskSimpleUseGun : public virtual CTaskSimple class CTaskSimpleFight : public virtual CTaskSimple { public: - virtual ~CTaskSimpleFight(){}; + virtual ~CTaskSimpleFight() {}; }; diff --git a/Client/sdk/game/TaskBasic.h b/Client/sdk/game/TaskBasic.h index bd88b855d95..e3f0df8ddfb 100644 --- a/Client/sdk/game/TaskBasic.h +++ b/Client/sdk/game/TaskBasic.h @@ -16,19 +16,19 @@ class CTaskComplexUseMobilePhone : public virtual CTaskComplex { public: - virtual ~CTaskComplexUseMobilePhone(){}; + virtual ~CTaskComplexUseMobilePhone() {}; }; class CTaskSimpleAnim : public virtual CTaskSimple { public: - virtual ~CTaskSimpleAnim(){}; + virtual ~CTaskSimpleAnim() {}; }; class CTaskSimpleRunAnim : public virtual CTaskSimpleAnim { public: - virtual ~CTaskSimpleRunAnim(){}; + virtual ~CTaskSimpleRunAnim() {}; }; class CTaskSimpleRunNamedAnim : public virtual CTaskSimpleAnim @@ -41,25 +41,25 @@ class CTaskSimpleRunNamedAnim : public virtual CTaskSimpleAnim class CTaskComplexDie : public virtual CTaskComplex { public: - virtual ~CTaskComplexDie(){}; + virtual ~CTaskComplexDie() {}; }; class CTaskSimpleStealthKill : public virtual CTaskSimple { public: - virtual ~CTaskSimpleStealthKill(){}; + virtual ~CTaskSimpleStealthKill() {}; }; class CTaskSimpleDead : public virtual CTaskSimple { public: - virtual ~CTaskSimpleDead(){}; + virtual ~CTaskSimpleDead() {}; }; class CTaskSimpleBeHit : public virtual CTaskSimple { public: - virtual ~CTaskSimpleBeHit(){}; + virtual ~CTaskSimpleBeHit() {}; }; enum eSunbatherType @@ -74,7 +74,7 @@ enum eSunbatherType class CTaskComplexSunbathe : public virtual CTaskComplex { public: - virtual ~CTaskComplexSunbathe(){}; + virtual ~CTaskComplexSunbathe() {}; virtual void SetEndTime(DWORD dwTime) = 0; }; @@ -84,7 +84,7 @@ class CTaskComplexSunbathe : public virtual CTaskComplex class CTaskSimplePlayerOnFoot : public virtual CTaskSimple { public: - virtual ~CTaskSimplePlayerOnFoot(){}; + virtual ~CTaskSimplePlayerOnFoot() {}; }; //////////////////// @@ -93,5 +93,11 @@ class CTaskSimplePlayerOnFoot : public virtual CTaskSimple class CTaskComplexFacial : public virtual CTaskComplex { public: - virtual ~CTaskComplexFacial(){}; + virtual ~CTaskComplexFacial() {}; +}; + +class CTaskComplexInWater : public virtual CTaskComplex +{ +public: + virtual ~CTaskComplexInWater() {}; }; diff --git a/Client/sdk/game/TaskCar.h b/Client/sdk/game/TaskCar.h index 171ddda1588..e1a607c30aa 100644 --- a/Client/sdk/game/TaskCar.h +++ b/Client/sdk/game/TaskCar.h @@ -24,7 +24,7 @@ enum class CTaskComplexEnterCar : public virtual CTaskComplex { public: - virtual ~CTaskComplexEnterCar(){}; + virtual ~CTaskComplexEnterCar() {}; virtual int GetTargetDoor() = 0; virtual void SetTargetDoor(int iDoor) = 0; @@ -34,25 +34,25 @@ class CTaskComplexEnterCar : public virtual CTaskComplex class CTaskComplexEnterCarAsDriver : public virtual CTaskComplexEnterCar { public: - virtual ~CTaskComplexEnterCarAsDriver(){}; + virtual ~CTaskComplexEnterCarAsDriver() {}; }; class CTaskComplexEnterCarAsPassenger : public virtual CTaskComplexEnterCar { public: - virtual ~CTaskComplexEnterCarAsPassenger(){}; + virtual ~CTaskComplexEnterCarAsPassenger() {}; }; class CTaskComplexEnterBoatAsDriver : public virtual CTaskComplex { public: - virtual ~CTaskComplexEnterBoatAsDriver(){}; + virtual ~CTaskComplexEnterBoatAsDriver() {}; }; class CTaskComplexLeaveCar : public virtual CTaskComplex { public: - virtual ~CTaskComplexLeaveCar(){}; + virtual ~CTaskComplexLeaveCar() {}; virtual int GetTargetDoor() = 0; }; diff --git a/Client/sdk/game/TaskCarAccessories.h b/Client/sdk/game/TaskCarAccessories.h index 4e849947677..6a6d422391d 100644 --- a/Client/sdk/game/TaskCarAccessories.h +++ b/Client/sdk/game/TaskCarAccessories.h @@ -18,7 +18,7 @@ class CVehicle; class CTaskSimpleCarSetPedInAsDriver : public virtual CTaskSimple { public: - virtual ~CTaskSimpleCarSetPedInAsDriver(){}; + virtual ~CTaskSimpleCarSetPedInAsDriver() {}; virtual void SetIsWarpingPedIntoCar() = 0; virtual void SetDoorFlagsToClear(const unsigned char nDoorFlagsToClear) = 0; @@ -28,7 +28,7 @@ class CTaskSimpleCarSetPedInAsDriver : public virtual CTaskSimple class CTaskSimpleCarSetPedOut : public virtual CTaskSimple { public: - virtual ~CTaskSimpleCarSetPedOut(){}; + virtual ~CTaskSimpleCarSetPedOut() {}; virtual void SetIsWarpingPedOutOfCar() = 0; virtual void SetKnockedOffBike() = 0; @@ -40,7 +40,7 @@ class CTaskSimpleCarSetPedOut : public virtual CTaskSimple class CTaskSimpleCarSetPedInAsPassenger : public virtual CTaskSimple { public: - virtual ~CTaskSimpleCarSetPedInAsPassenger(){}; + virtual ~CTaskSimpleCarSetPedInAsPassenger() {}; virtual void SetIsWarpingPedIntoCar() = 0; virtual void SetDoorFlagsToClear(const unsigned char nDoorFlagsToClear) = 0; diff --git a/Client/sdk/game/TaskGoTo.h b/Client/sdk/game/TaskGoTo.h index dbf283a2086..0f96fe9eff3 100644 --- a/Client/sdk/game/TaskGoTo.h +++ b/Client/sdk/game/TaskGoTo.h @@ -34,12 +34,12 @@ enum WANDER_TYPE_PROSTITUTE }; -#define NO_WANDER_TYPE 9999 +#define NO_WANDER_TYPE 9999 class CTaskComplexWander : public virtual CTaskComplex { public: - virtual ~CTaskComplexWander(){}; + virtual ~CTaskComplexWander() {}; virtual CNodeAddress* GetNextNode() = 0; virtual CNodeAddress* GetLastNode() = 0; @@ -50,5 +50,5 @@ class CTaskComplexWander : public virtual CTaskComplex class CTaskComplexWanderStandard : public virtual CTaskComplexWander { public: - virtual ~CTaskComplexWanderStandard(){}; + virtual ~CTaskComplexWanderStandard() {}; }; diff --git a/Client/sdk/game/TaskIK.h b/Client/sdk/game/TaskIK.h index c1530200025..51a4cc0fb71 100644 --- a/Client/sdk/game/TaskIK.h +++ b/Client/sdk/game/TaskIK.h @@ -13,24 +13,24 @@ #include "Task.h" -#define NUM_IK_CHAIN_SLOTS 5 //(28 - sizeof(CTaskSimple)) / 4 +#define NUM_IK_CHAIN_SLOTS 5 //(28 - sizeof(CTaskSimple)) / 4 class CTaskSimpleIKChain : public virtual CTaskSimple { public: - virtual ~CTaskSimpleIKChain(){}; + virtual ~CTaskSimpleIKChain() {}; }; class CTaskSimpleIKLookAt : public virtual CTaskSimpleIKChain { public: - virtual ~CTaskSimpleIKLookAt(){}; + virtual ~CTaskSimpleIKLookAt() {}; }; class CTaskSimpleIKManager : public virtual CTaskSimple { public: - virtual ~CTaskSimpleIKManager(){}; + virtual ~CTaskSimpleIKManager() {}; virtual int AddIKChainTask(CTaskSimpleIKChain* pIKChainTask, int slotID = -1) = 0; virtual void RemoveIKChainTask(int slotID) = 0; @@ -42,5 +42,5 @@ class CTaskSimpleIKManager : public virtual CTaskSimple class CTaskSimpleTriggerLookAt : public virtual CTaskSimple { public: - virtual ~CTaskSimpleTriggerLookAt(){}; + virtual ~CTaskSimpleTriggerLookAt() {}; }; diff --git a/Client/sdk/game/TaskJumpFall.h b/Client/sdk/game/TaskJumpFall.h index 2b91068f197..596739c9453 100644 --- a/Client/sdk/game/TaskJumpFall.h +++ b/Client/sdk/game/TaskJumpFall.h @@ -12,17 +12,32 @@ #pragma once #include "Task.h" +#include "CPed.h" + +enum eClimbHeights : std::int8_t; class CTaskSimpleClimb : public virtual CTaskSimple { public: - virtual ~CTaskSimpleClimb(){}; + virtual ~CTaskSimpleClimb() {}; + + virtual eClimbHeights GetHeightForPos() const = 0; + + static class CEntitySAInterface* TestForClimb(CPed* ped, CVector& climbPos, float& climbAngle, int& surfaceType, bool launch) + { + if (!ped) + return nullptr; + + // CTaskSimpleClimb::TestForClimb + return ((class CEntitySAInterface * (__cdecl*)(class CPedSAInterface*, CVector*, float*, int*, bool))0x6803A0)(ped->GetPedInterface(), &climbPos, + &climbAngle, &surfaceType, launch); + } }; class CTaskSimpleJetPack : public virtual CTaskSimple { public: - virtual ~CTaskSimpleJetPack(){}; + virtual ~CTaskSimpleJetPack() {}; virtual bool IsFinished() const = 0; }; diff --git a/Client/sdk/game/TaskPhysicalResponse.h b/Client/sdk/game/TaskPhysicalResponse.h index 552d8e14502..d6b4af2ab57 100644 --- a/Client/sdk/game/TaskPhysicalResponse.h +++ b/Client/sdk/game/TaskPhysicalResponse.h @@ -16,7 +16,7 @@ class CTaskSimpleChoking : public virtual CTaskSimple { public: - virtual ~CTaskSimpleChoking(){}; + virtual ~CTaskSimpleChoking() {}; virtual CPed* GetAttacker() = 0; virtual unsigned int GetTimeRemaining() = 0; diff --git a/Client/sdk/game/TaskSecondary.h b/Client/sdk/game/TaskSecondary.h index 14f5c993748..b40d22d827a 100644 --- a/Client/sdk/game/TaskSecondary.h +++ b/Client/sdk/game/TaskSecondary.h @@ -15,15 +15,15 @@ enum eDuckControlTypes { - DUCK_STANDALONE = 0, // duck anim removed when task removed - DUCK_STANDALONE_WEAPON_CROUCH, // duck anim removed when task removed - DUCK_TASK_CONTROLLED, // duck directly linked to a controlling task - DUCK_ANIM_CONTROLLED, // duck linked to duck anim (make duck partial?) + DUCK_STANDALONE = 0, // duck anim removed when task removed + DUCK_STANDALONE_WEAPON_CROUCH, // duck anim removed when task removed + DUCK_TASK_CONTROLLED, // duck directly linked to a controlling task + DUCK_ANIM_CONTROLLED, // duck linked to duck anim (make duck partial?) DUCK_SCRIPT_CONTROLLED, }; class CTaskSimpleDuck : public virtual CTaskSimple { public: - virtual ~CTaskSimpleDuck(){}; + virtual ~CTaskSimpleDuck() {}; }; diff --git a/Client/sdk/game/TaskSimpleSwim.h b/Client/sdk/game/TaskSimpleSwim.h new file mode 100644 index 00000000000..11dd2d6354b --- /dev/null +++ b/Client/sdk/game/TaskSimpleSwim.h @@ -0,0 +1,30 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: sdk/game/TaskSimpleSwim.h + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once +#include "Task.h" + +enum swimState : std::uint16_t +{ + SWIM_TREAD = 0, + SWIM_SPRINT, + SWIM_SPRINTING, + SWIM_DIVE_UNDERWATER, + SWIM_UNDERWATER_SPRINTING, + SWIM_BACK_TO_SURFACE, +}; + +class CTaskSimpleSwim : public virtual CTaskSimple +{ +public: + virtual ~CTaskSimpleSwim() {}; + + virtual swimState GetSwimState() const = 0; +}; diff --git a/Client/sdk/game/TaskTypes.h b/Client/sdk/game/TaskTypes.h index 289d368bf7f..5a511b8e535 100644 --- a/Client/sdk/game/TaskTypes.h +++ b/Client/sdk/game/TaskTypes.h @@ -144,9 +144,9 @@ enum eTaskType TASK_COMPLEX_FACIAL, TASK_SIMPLE_AFFECT_SECONDARY_BEHAVIOUR, TASK_SIMPLE_HOLD_ENTITY, - TASK_SIMPLE_PICKUP_ENTITY, // these three aren't really secondary tasks - TASK_SIMPLE_PUTDOWN_ENTITY, // but they exist around the secondary hold entity - TASK_COMPLEX_GO_PICKUP_ENTITY, // task at the start and finish + TASK_SIMPLE_PICKUP_ENTITY, // these three aren't really secondary tasks + TASK_SIMPLE_PUTDOWN_ENTITY, // but they exist around the secondary hold entity + TASK_COMPLEX_GO_PICKUP_ENTITY, // task at the start and finish TASK_SIMPLE_DUCK_WHILE_SHOTS_WHIZZING, // SCRIPT_DECISION @@ -415,8 +415,8 @@ enum eTaskType TASK_SIMPLE_GANG_DRIVEBY, // SCRIPT_DECISION - TASK_COMPLEX_KILL_PED_ON_FOOT_TIMED, // SCRIPT_DECISION - TASK_COMPLEX_KILL_PED_ON_FOOT_STAND_STILL, // SCRIPT_DECISION + TASK_COMPLEX_KILL_PED_ON_FOOT_TIMED, // SCRIPT_DECISION + TASK_COMPLEX_KILL_PED_ON_FOOT_STAND_STILL, // SCRIPT_DECISION TASK_UNUSED2, TASK_KILL_PED_ON_FOOT_WHILE_DUCKING, // SCRIPT_DECISION diff --git a/Client/sdk/gui/CGUI.h b/Client/sdk/gui/CGUI.h index e552c0d7885..184a22511b2 100644 --- a/Client/sdk/gui/CGUI.h +++ b/Client/sdk/gui/CGUI.h @@ -38,14 +38,14 @@ class CGUI; #include "CGUITypes.h" // Path defines for CGUI -#define CGUI_ICON_MESSAGEBOX_INFO "cgui\\images\\info.png" -#define CGUI_ICON_MESSAGEBOX_QUESTION "cgui\\images\\question.png" -#define CGUI_ICON_MESSAGEBOX_WARNING "cgui\\images\\warning.png" -#define CGUI_ICON_MESSAGEBOX_ERROR "cgui\\images\\error.png" -#define CGUI_ICON_SERVER_PASSWORD "cgui\\images\\locked.png" -#define CGUI_GetMaxTextExtent(...) GetMaxTextExtent(__VA_ARGS__, SString()) +#define CGUI_ICON_MESSAGEBOX_INFO "cgui\\images\\info.png" +#define CGUI_ICON_MESSAGEBOX_QUESTION "cgui\\images\\question.png" +#define CGUI_ICON_MESSAGEBOX_WARNING "cgui\\images\\warning.png" +#define CGUI_ICON_MESSAGEBOX_ERROR "cgui\\images\\error.png" +#define CGUI_ICON_SERVER_PASSWORD "cgui\\images\\locked.png" +#define CGUI_GetMaxTextExtent(...) GetMaxTextExtent(__VA_ARGS__, SString()) -#define CHECK_CHANNEL(channel) assert ( (channel) >= 0 && (channel) < INPUT_CHANNEL_COUNT ) +#define CHECK_CHANNEL(channel) assert((channel) >= 0 && (channel) < INPUT_CHANNEL_COUNT) class CGUI { @@ -166,7 +166,10 @@ class CGUI virtual void ClearSystemKeys() = 0; virtual void CleanDeadPool() = 0; + virtual void DestroyElementRecursive(CGUIElement* pElement) = 0; virtual CGUIWindow* LoadLayout(CGUIElement* pParent, const SString& strFilename) = 0; virtual bool LoadImageset(const SString& strFilename) = 0; + + virtual void Cleanup() = 0; }; diff --git a/Client/sdk/gui/CGUIButton.h b/Client/sdk/gui/CGUIButton.h index 620619741d8..f3b80b93293 100644 --- a/Client/sdk/gui/CGUIButton.h +++ b/Client/sdk/gui/CGUIButton.h @@ -17,5 +17,5 @@ class CGUIButton : public CGUIElement { public: - virtual ~CGUIButton(){}; + virtual ~CGUIButton() {}; }; diff --git a/Client/sdk/gui/CGUICallback.h b/Client/sdk/gui/CGUICallback.h index e7342dcd77b..45f44cca348 100644 --- a/Client/sdk/gui/CGUICallback.h +++ b/Client/sdk/gui/CGUICallback.h @@ -14,10 +14,10 @@ class CGUIElement; // Define callbacks -#define GUI_CALLBACK CGUICallback < bool, CGUIElement * > -#define GUI_CALLBACK_KEY CGUICallback < bool, CGUIKeyEventArgs > -#define GUI_CALLBACK_MOUSE CGUICallback < bool, CGUIMouseEventArgs > -#define GUI_CALLBACK_FOCUS CGUICallback < bool, CGUIFocusEventArgs > +#define GUI_CALLBACK CGUICallback +#define GUI_CALLBACK_KEY CGUICallback +#define GUI_CALLBACK_MOUSE CGUICallback +#define GUI_CALLBACK_FOCUS CGUICallback // Represents any callback template @@ -98,5 +98,5 @@ class CGUICallback operator bool() const { return *(DWORD*)m_Callback != NULL; } protected: - char m_Callback[4 + 4 + 20]; // vtable + pObj + pMemFn + char m_Callback[4 + 4 + 20]; // vtable + pObj + pMemFn }; diff --git a/Client/sdk/gui/CGUICheckBox.h b/Client/sdk/gui/CGUICheckBox.h index b800e712b87..5f4950f9ae6 100644 --- a/Client/sdk/gui/CGUICheckBox.h +++ b/Client/sdk/gui/CGUICheckBox.h @@ -17,7 +17,7 @@ class CGUICheckBox : public CGUIElement { public: - virtual ~CGUICheckBox(){}; + virtual ~CGUICheckBox() {}; virtual void SetSelected(bool bSelected) = 0; virtual bool GetSelected() = 0; diff --git a/Client/sdk/gui/CGUIComboBox.h b/Client/sdk/gui/CGUIComboBox.h index ae8c54f2b34..253d4803892 100644 --- a/Client/sdk/gui/CGUIComboBox.h +++ b/Client/sdk/gui/CGUIComboBox.h @@ -17,7 +17,7 @@ class CGUIComboBox : public CGUIElement { public: - virtual ~CGUIComboBox(){}; + virtual ~CGUIComboBox() {}; virtual void SetReadOnly(bool bRead) = 0; virtual CGUIListItem* AddItem(const char* szText) = 0; diff --git a/Client/sdk/gui/CGUIEdit.h b/Client/sdk/gui/CGUIEdit.h index 3126be3acc6..836cbcf4bd5 100644 --- a/Client/sdk/gui/CGUIEdit.h +++ b/Client/sdk/gui/CGUIEdit.h @@ -17,7 +17,7 @@ class CGUIEdit : public CGUIElement { public: - virtual ~CGUIEdit(){}; + virtual ~CGUIEdit() {}; virtual void SetReadOnly(bool bReadOnly) = 0; virtual bool IsReadOnly() = 0; diff --git a/Client/sdk/gui/CGUIElement.h b/Client/sdk/gui/CGUIElement.h index f6e93103be8..309a2f47360 100644 --- a/Client/sdk/gui/CGUIElement.h +++ b/Client/sdk/gui/CGUIElement.h @@ -47,7 +47,7 @@ enum eCGUIType class CGUIElement { public: - virtual ~CGUIElement(){}; + virtual ~CGUIElement() {}; virtual void SetVisible(bool bVisible) = 0; virtual bool IsVisible() = 0; diff --git a/Client/sdk/gui/CGUIFont.h b/Client/sdk/gui/CGUIFont.h index 27b52fc2155..76b946a6d74 100644 --- a/Client/sdk/gui/CGUIFont.h +++ b/Client/sdk/gui/CGUIFont.h @@ -16,7 +16,7 @@ class CGUIFont { public: - virtual ~CGUIFont(){}; + virtual ~CGUIFont() {}; virtual void SetAntiAliasingEnabled(bool bAntialiased) = 0; virtual bool IsAntiAliasingEnabled() = 0; diff --git a/Client/sdk/gui/CGUIGridList.h b/Client/sdk/gui/CGUIGridList.h index b3fa40eb06d..8d3ad38f088 100644 --- a/Client/sdk/gui/CGUIGridList.h +++ b/Client/sdk/gui/CGUIGridList.h @@ -50,7 +50,7 @@ using SortDirections::SortDirection; class CGUIGridList : public CGUIElement { public: - virtual ~CGUIGridList(){}; + virtual ~CGUIGridList() {}; virtual unsigned int AddColumn(const char* szTitle, float fWidth) = 0; virtual void RemoveColumn(unsigned int uiColumn) = 0; @@ -82,6 +82,8 @@ class CGUIGridList : public CGUIElement virtual void SetVerticalScrollBar(bool bEnabled) = 0; virtual void SetSortingEnabled(bool bEnabled) = 0; virtual bool IsSortingEnabled() = 0; + virtual void SetAutoSortSuppressed(bool bSuppressed) = 0; + virtual bool IsAutoSortSuppressed() const = 0; virtual void SetItemImage(int iRow, int hColumn, CGUIStaticImage* pImage) = 0; virtual float GetHorizontalScrollPosition() = 0; @@ -110,6 +112,7 @@ class CGUIGridList : public CGUIElement virtual void SetSelectedItem(int iRow, int hColumn, bool bReset) = 0; virtual void SetSortColumnHandler(GUI_CALLBACK Callback) = 0; + virtual void SetSelectionHandler(GUI_CALLBACK Callback) = 0; virtual void SetIgnoreTextSpacer(bool bIgnoreTextSpacer) = 0; }; diff --git a/Client/sdk/gui/CGUILabel.h b/Client/sdk/gui/CGUILabel.h index 0bbefd93a24..cebc2d4eec8 100644 --- a/Client/sdk/gui/CGUILabel.h +++ b/Client/sdk/gui/CGUILabel.h @@ -16,7 +16,7 @@ class CGUILabel : public CGUIElement { public: - virtual ~CGUILabel(){}; + virtual ~CGUILabel() {}; virtual void SetText(const char* Text) = 0; diff --git a/Client/sdk/gui/CGUIListItem.h b/Client/sdk/gui/CGUIListItem.h index 5c0d34af163..74abe4c167b 100644 --- a/Client/sdk/gui/CGUIListItem.h +++ b/Client/sdk/gui/CGUIListItem.h @@ -17,7 +17,7 @@ class CGUIListItem { public: - virtual ~CGUIListItem(){}; + virtual ~CGUIListItem() {}; virtual std::string GetText() const = 0; virtual void SetText(const char* pszText, const char* pszSortText = NULL) = 0; diff --git a/Client/sdk/gui/CGUIMemo.h b/Client/sdk/gui/CGUIMemo.h index 8a42249d73a..a8160b33f1c 100644 --- a/Client/sdk/gui/CGUIMemo.h +++ b/Client/sdk/gui/CGUIMemo.h @@ -17,7 +17,7 @@ class CGUIMemo : public CGUIElement { public: - virtual ~CGUIMemo(){}; + virtual ~CGUIMemo() {}; virtual void SetReadOnly(bool bReadOnly) = 0; virtual bool IsReadOnly() = 0; diff --git a/Client/sdk/gui/CGUIMessageBox.h b/Client/sdk/gui/CGUIMessageBox.h index 31639266c06..8178303afa5 100644 --- a/Client/sdk/gui/CGUIMessageBox.h +++ b/Client/sdk/gui/CGUIMessageBox.h @@ -18,7 +18,7 @@ class CGUIMessageBox { public: - virtual ~CGUIMessageBox(){}; + virtual ~CGUIMessageBox() {}; virtual void SetAutoDestroy(bool bAutoDestroy) = 0; virtual bool GetAutoDestroy() = 0; diff --git a/Client/sdk/gui/CGUIProgressBar.h b/Client/sdk/gui/CGUIProgressBar.h index b100a58a309..abea94bf50f 100644 --- a/Client/sdk/gui/CGUIProgressBar.h +++ b/Client/sdk/gui/CGUIProgressBar.h @@ -17,7 +17,7 @@ class CGUIProgressBar : public CGUIElement { public: - virtual ~CGUIProgressBar(){}; + virtual ~CGUIProgressBar() {}; virtual void SetProgress(float fProgress) = 0; virtual float GetProgress() = 0; diff --git a/Client/sdk/gui/CGUIRadioButton.h b/Client/sdk/gui/CGUIRadioButton.h index 3d29bfe555e..b0a34c813ad 100644 --- a/Client/sdk/gui/CGUIRadioButton.h +++ b/Client/sdk/gui/CGUIRadioButton.h @@ -17,7 +17,7 @@ class CGUIRadioButton : public CGUIElement { public: - virtual ~CGUIRadioButton(){}; + virtual ~CGUIRadioButton() {}; virtual void SetSelected(bool bSelected) = 0; virtual bool GetSelected() = 0; diff --git a/Client/sdk/gui/CGUIScrollBar.h b/Client/sdk/gui/CGUIScrollBar.h index 67dcc752334..92740157344 100644 --- a/Client/sdk/gui/CGUIScrollBar.h +++ b/Client/sdk/gui/CGUIScrollBar.h @@ -17,7 +17,7 @@ class CGUIScrollBar : public CGUIElement { public: - virtual ~CGUIScrollBar(){}; + virtual ~CGUIScrollBar() {}; virtual void SetOnScrollHandler(const GUI_CALLBACK& Callback) = 0; diff --git a/Client/sdk/gui/CGUIScrollPane.h b/Client/sdk/gui/CGUIScrollPane.h index 1947d826b92..3a898d9fdc9 100644 --- a/Client/sdk/gui/CGUIScrollPane.h +++ b/Client/sdk/gui/CGUIScrollPane.h @@ -16,7 +16,7 @@ class CGUIScrollPane : public CGUIElement { public: - virtual ~CGUIScrollPane(){}; + virtual ~CGUIScrollPane() {}; virtual void SetHorizontalScrollBar(bool bEnabled) = 0; virtual void SetVerticalScrollBar(bool bEnabled) = 0; diff --git a/Client/sdk/gui/CGUIStaticImage.h b/Client/sdk/gui/CGUIStaticImage.h index 0ec5734d146..8f9c8052c90 100644 --- a/Client/sdk/gui/CGUIStaticImage.h +++ b/Client/sdk/gui/CGUIStaticImage.h @@ -17,7 +17,7 @@ class CGUIStaticImage : public CGUIElement { public: - virtual ~CGUIStaticImage(){}; + virtual ~CGUIStaticImage() {}; virtual bool LoadFromFile(const char* szFilename) = 0; virtual bool LoadFromTexture(CGUITexture* pTexture) = 0; diff --git a/Client/sdk/gui/CGUITab.h b/Client/sdk/gui/CGUITab.h index 2ec0b6f616c..2b5e4685fad 100644 --- a/Client/sdk/gui/CGUITab.h +++ b/Client/sdk/gui/CGUITab.h @@ -16,7 +16,7 @@ class CGUITab : public CGUIElement { public: - virtual ~CGUITab(){}; + virtual ~CGUITab() {}; virtual void SetCaption(const char* szCaption) = 0; }; diff --git a/Client/sdk/gui/CGUITabPanel.h b/Client/sdk/gui/CGUITabPanel.h index a178e19c49a..4b875027ab6 100644 --- a/Client/sdk/gui/CGUITabPanel.h +++ b/Client/sdk/gui/CGUITabPanel.h @@ -17,7 +17,7 @@ class CGUITabPanel : public CGUIElement { public: - virtual ~CGUITabPanel(){}; + virtual ~CGUITabPanel() {}; virtual CGUITab* CreateTab(const char* szCaption) = 0; virtual void DeleteTab(CGUITab* pTab) = 0; diff --git a/Client/sdk/gui/CGUITexture.h b/Client/sdk/gui/CGUITexture.h index e613da25d03..adb9ef2665f 100644 --- a/Client/sdk/gui/CGUITexture.h +++ b/Client/sdk/gui/CGUITexture.h @@ -18,7 +18,7 @@ struct IDirect3DTexture9; class CGUITexture { public: - virtual ~CGUITexture(){}; + virtual ~CGUITexture() {}; virtual bool LoadFromFile(const char* szFilename) = 0; virtual void LoadFromMemory(const void* pBuffer, unsigned int uiWidth, unsigned int uiHeight) = 0; diff --git a/Client/sdk/gui/CGUITypes.h b/Client/sdk/gui/CGUITypes.h index 3a43cfc9dd5..2bb2f46c1a8 100644 --- a/Client/sdk/gui/CGUITypes.h +++ b/Client/sdk/gui/CGUITypes.h @@ -17,7 +17,7 @@ #include #ifndef NULL -#define NULL 0 + #define NULL 0 #endif typedef int CGUIHandle; @@ -40,7 +40,7 @@ enum CGUIMouseInput CGUI_MI_MOUSEWHEEL }; -enum CGUIMouseButton // Synchronized with CEGUI::MouseButton in ceguiinputevent.h +enum CGUIMouseButton // Synchronized with CEGUI::MouseButton in ceguiinputevent.h { LeftButton, RightButton, @@ -100,8 +100,8 @@ struct CGUIMouse MiddleButton, X1Button, X2Button, - MouseButtonCount, // #include - // DOESNT WORK FOR 64-BIT APPS ! +// DOESNT WORK FOR 64-BIT APPS ! - #pragma warning ( disable:4311 ) - #pragma warning ( disable:4312 ) + #pragma warning(disable : 4311) + #pragma warning(disable : 4312) extern bool g_bBoundsChecker; extern DWORD* g_Table; diff --git a/Client/sdk/multiplayer/CMultiplayer.h b/Client/sdk/multiplayer/CMultiplayer.h index af3ae03f207..5926e578a89 100644 --- a/Client/sdk/multiplayer/CMultiplayer.h +++ b/Client/sdk/multiplayer/CMultiplayer.h @@ -85,7 +85,7 @@ typedef void(BulletImpactHandler)(class CPed* pInitiator, class CEntity* pVictim typedef void(BulletFireHandler)(class CPed* pInitiator, const CVector* pvecStartPosition, const CVector* pvecEndPosition); typedef bool(DamageHandler)(class CPed* pDamagePed, class CEventDamage* pEvent); typedef void(DeathHandler)(class CPed* pKilledPed, unsigned char ucDeathReason, unsigned char ucBodyPart); -typedef void(FireHandler)(class CFire* pFire); +typedef bool(FireHandler)(class CEntitySAInterface* target, class CEntitySAInterface* creator); typedef bool(ProjectileStopHandler)(class CEntity* owner, enum eWeaponType weaponType, class CVector* origin, float fForce, class CVector* target, class CEntity* targetEntity); typedef void(ProjectileHandler)(class CEntity* owner, class CProjectile* projectile, class CProjectileInfo* projectileInfo, enum eWeaponType weaponType, @@ -105,8 +105,8 @@ typedef void(PreFxRenderHandler)(); typedef void(PostColorFilterRenderHandler)(); typedef void(PreHudRenderHandler)(); typedef void(RenderEverythingBarRoadsHandler)(); -typedef CAnimBlendAssociationSAInterface*(AddAnimationHandler)(RpClump* pClump, AssocGroupId animGroup, AnimationId animID); -typedef CAnimBlendAssociationSAInterface*(AddAnimationAndSyncHandler)(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, +typedef CAnimBlendAssociationSAInterface*(AddAnimationHandler)(RpClump * pClump, AssocGroupId animGroup, AnimationId animID); +typedef CAnimBlendAssociationSAInterface*(AddAnimationAndSyncHandler)(RpClump * pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, AssocGroupId animGroup, AnimationId animID); typedef void(CAnimBlendAssocDestructorHandler)(CAnimBlendAssociationSAInterface* pThis); typedef bool(AssocGroupCopyAnimationHandler)(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, @@ -311,17 +311,17 @@ class CMultiplayer virtual int GetMoonSize() = 0; virtual void ResetMoonSize() = 0; - virtual void GetAmbientColor(float& red, float& green, float& blue) const = 0; - virtual bool SetAmbientColor(float red, float green, float blue) = 0; - virtual bool ResetAmbientColor() = 0; + virtual void GetAmbientColor(float& red, float& green, float& blue) const = 0; + virtual bool SetAmbientColor(float red, float green, float blue) = 0; + virtual bool ResetAmbientColor() = 0; - virtual void GetAmbientObjectColor(float& red, float& green, float& blue) const = 0; - virtual bool SetAmbientObjectColor(float red, float green, float blue) = 0; - virtual bool ResetAmbientObjectColor() = 0; + virtual void GetAmbientObjectColor(float& red, float& green, float& blue) const = 0; + virtual bool SetAmbientObjectColor(float red, float green, float blue) = 0; + virtual bool ResetAmbientObjectColor() = 0; - virtual void GetDirectionalColor(float& red, float& green, float& blue) const = 0; - virtual bool SetDirectionalColor(float red, float green, float blue) = 0; - virtual bool ResetDirectionalColor() = 0; + virtual void GetDirectionalColor(float& red, float& green, float& blue) const = 0; + virtual bool SetDirectionalColor(float red, float green, float blue) = 0; + virtual bool ResetDirectionalColor() = 0; virtual float GetSpriteSize() const = 0; virtual bool SetSpriteSize(float size) = 0; @@ -347,13 +347,13 @@ class CMultiplayer virtual bool SetLightsOnGroundBrightness(float brightness) = 0; virtual bool ResetLightsOnGroundBrightness() = 0; - virtual void GetLowCloudsColor(int16& red, int16& green, int16& blue) const = 0; - virtual bool SetLowCloudsColor(int16 red, int16 green, int16 blue) = 0; - virtual bool ResetLowCloudsColor() = 0; + virtual void GetLowCloudsColor(int16& red, int16& green, int16& blue) const = 0; + virtual bool SetLowCloudsColor(int16 red, int16 green, int16 blue) = 0; + virtual bool ResetLowCloudsColor() = 0; - virtual void GetBottomCloudsColor(int16& red, int16& green, int16& blue) const = 0; - virtual bool SetBottomCloudsColor(int16 red, int16 green, int16 blue) = 0; - virtual bool ResetBottomCloudsColor() = 0; + virtual void GetBottomCloudsColor(int16& red, int16& green, int16& blue) const = 0; + virtual bool SetBottomCloudsColor(int16 red, int16 green, int16 blue) = 0; + virtual bool ResetBottomCloudsColor() = 0; virtual float GetCloudsAlpha1() const = 0; virtual bool SetCloudsAlpha1(float alpha) = 0; diff --git a/Client/sdk/net/CNet.h b/Client/sdk/net/CNet.h index f64ec279032..2ff09c3a062 100644 --- a/Client/sdk/net/CNet.h +++ b/Client/sdk/net/CNet.h @@ -16,7 +16,7 @@ #include "net/bitstream.h" #include "net/CNetHTTPDownloadManagerInterface.h" -#define MAX_CALL_REMOTE_QUEUES 100 +#define MAX_CALL_REMOTE_QUEUES 100 namespace EDownloadMode { @@ -26,7 +26,7 @@ namespace EDownloadMode CORE_ASE_LIST, CORE_UPDATER, WEBBROWSER_LISTS, - CORE_LAST, // Download modes after this one will be reset on server disconnect + CORE_LAST, // Download modes after this one will be reset on server disconnect RESOURCE_INITIAL_FILES_INTERNAL, RESOURCE_INITIAL_FILES_EXTERNAL, RESOURCE_SINGULAR_FILES, diff --git a/Client/sdk/net/net_common.h b/Client/sdk/net/net_common.h index adfe6cd3347..20540740cf8 100644 --- a/Client/sdk/net/net_common.h +++ b/Client/sdk/net/net_common.h @@ -12,18 +12,18 @@ #pragma once #ifdef WIN32 -#include + #include #endif #include "net/bitstream.h" #include "net/packetenums.h" -#define CNET_DOWNLOAD_INVALID 65535 +#define CNET_DOWNLOAD_INVALID 65535 -#define NET_CLIENT_PORT 0 // 0 will allow it to automatically choose a port, otherwise, use the value specific -#define NET_DISCONNECT_DELAY 30 +#define NET_CLIENT_PORT 0 // 0 will allow it to automatically choose a port, otherwise, use the value specific +#define NET_DISCONNECT_DELAY 30 -#define NET_INVALID_PACKET_ID 255 +#define NET_INVALID_PACKET_ID 255 typedef bool (*PPACKETHANDLER)(unsigned char, NetBitStreamInterface&); @@ -37,11 +37,11 @@ enum NetPacketPriority enum NetPacketReliability { - PACKET_RELIABILITY_UNRELIABLE = 0, // Can arrive out of order + PACKET_RELIABILITY_UNRELIABLE = 0, // Can arrive out of order PACKET_RELIABILITY_UNRELIABLE_SEQUENCED, - PACKET_RELIABILITY_RELIABLE, // Can arrive out of order + PACKET_RELIABILITY_RELIABLE, // Can arrive out of order PACKET_RELIABILITY_RELIABLE_ORDERED, - PACKET_RELIABILITY_RELIABLE_SEQUENCED // Can drop packets + PACKET_RELIABILITY_RELIABLE_SEQUENCED // Can drop packets }; // Copy of raknet statistics diff --git a/Client/sdk/premake5.lua b/Client/sdk/premake5.lua index a027cb877fb..5ff315c2ea4 100644 --- a/Client/sdk/premake5.lua +++ b/Client/sdk/premake5.lua @@ -2,6 +2,7 @@ project "Client SDK" language "C++" kind "StaticLib" targetname "sdk" + clangtidy "On" vpaths { ["Headers/*"] = { "**.h", "**.hpp" }, diff --git a/Client/sdk/utils/XFont.h b/Client/sdk/utils/XFont.h index 7c5f62cad1e..8ed4438330f 100644 --- a/Client/sdk/utils/XFont.h +++ b/Client/sdk/utils/XFont.h @@ -32,7 +32,7 @@ #include #ifndef XFONT_H -#define XFONT_H + #define XFONT_H typedef struct _tagFONT_PROPERTIES { @@ -73,17 +73,17 @@ typedef struct _tagTT_OFFSET_TABLE typedef struct _tagTT_TABLE_DIRECTORY { - char szTag[4]; // table name - ULONG uCheckSum; // Check sum - ULONG uOffset; // Offset from beginning of file - ULONG uLength; // length of the table in bytes + char szTag[4]; // table name + ULONG uCheckSum; // Check sum + ULONG uOffset; // Offset from beginning of file + ULONG uLength; // length of the table in bytes } TT_TABLE_DIRECTORY; typedef struct _tagTT_NAME_TABLE_HEADER { - USHORT uFSelector; // format selector. Always 0 - USHORT uNRCount; // Name Records count - USHORT uStorageOffset; // Offset for strings storage, from start of the table + USHORT uFSelector; // format selector. Always 0 + USHORT uNRCount; // Name Records count + USHORT uStorageOffset; // Offset for strings storage, from start of the table } TT_NAME_TABLE_HEADER; typedef struct _tagTT_NAME_RECORD @@ -93,11 +93,11 @@ typedef struct _tagTT_NAME_RECORD USHORT uLanguageID; USHORT uNameID; USHORT uStringLength; - USHORT uStringOffset; // from start of storage area + USHORT uStringOffset; // from start of storage area } TT_NAME_RECORD; -#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x)) -#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x))) + #define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x)) + #define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x))) BOOL GetFontProperties(LPCTSTR lpszFilePath, FONT_PROPERTIES* lpFontPropsX) { @@ -108,14 +108,14 @@ BOOL GetFontProperties(LPCTSTR lpszFilePath, FONT_PROPERTIES* lpFontPropsX) HANDLE hFile = INVALID_HANDLE_VALUE; hFile = ::CreateFile(lpszFilePath, - GENERIC_READ, // | GENERIC_WRITE, + GENERIC_READ, // | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (hFile == INVALID_HANDLE_VALUE) { // Windows 8 fix hFile = ::CreateFile(lpszFilePath, - GENERIC_READ, // | GENERIC_WRITE, + GENERIC_READ, // | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); } @@ -141,7 +141,7 @@ BOOL GetFontProperties(LPCTSTR lpszFilePath, FONT_PROPERTIES* lpFontPropsX) // Create a file mapping object that is the current size of the file HANDLE hMappedFile = NULL; hMappedFile = ::CreateFileMapping(hFile, NULL, - PAGE_READONLY, // PAGE_READWRITE, + PAGE_READONLY, // PAGE_READWRITE, 0, dwFileSize, NULL); if (hMappedFile == NULL) @@ -151,11 +151,11 @@ BOOL GetFontProperties(LPCTSTR lpszFilePath, FONT_PROPERTIES* lpFontPropsX) return FALSE; } - LPBYTE lpMapAddress = (LPBYTE)::MapViewOfFile(hMappedFile, // handle to file-mapping object - FILE_MAP_READ, // FILE_MAP_WRITE, // access mode - 0, // high-order DWORD of offset - 0, // low-order DWORD of offset - 0); // number of bytes to map + LPBYTE lpMapAddress = (LPBYTE)::MapViewOfFile(hMappedFile, // handle to file-mapping object + FILE_MAP_READ, // FILE_MAP_WRITE, // access mode + 0, // high-order DWORD of offset + 0, // low-order DWORD of offset + 0); // number of bytes to map if (lpMapAddress == NULL) { @@ -239,7 +239,7 @@ BOOL GetFontProperties(LPCTSTR lpszFilePath, FONT_PROPERTIES* lpFontPropsX) if (ttRecord.uNameID == 1 || ttRecord.uNameID == 0 || ttRecord.uNameID == 4 || ttRecord.uNameID == 7) { - int nPos = index; // f.GetPosition(); + int nPos = index; // f.GetPosition(); index = tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset; @@ -321,4 +321,4 @@ BOOL GetFontProperties(LPCTSTR lpszFilePath, FONT_PROPERTIES* lpFontPropsX) return bRetVal; } -#endif //XFONT_H +#endif // XFONT_H diff --git a/Client/utils/ide2models/Main.h b/Client/utils/ide2models/Main.h index db3f22ae4d9..1fbb0e41b7c 100644 --- a/Client/utils/ide2models/Main.h +++ b/Client/utils/ide2models/Main.h @@ -12,7 +12,6 @@ #pragma once #include -using namespace std; int main(int iArgumentCount, char* szArgs[]); int Convert(FILE* pInput, FILE* pOutput); diff --git a/Client/utils/map2xml/Main.h b/Client/utils/map2xml/Main.h index d5c347034ed..bdfcd78c42e 100644 --- a/Client/utils/map2xml/Main.h +++ b/Client/utils/map2xml/Main.h @@ -13,7 +13,6 @@ #include "CConfig.h" #include -using namespace std; int main(int iArgumentCount, char* szArgs[]); int Convert(CConfig* pInput, FILE* pOutput); diff --git a/MAETRO.md b/MAETRO.md new file mode 100644 index 00000000000..48d2075dcc5 --- /dev/null +++ b/MAETRO.md @@ -0,0 +1,17 @@ +# maetro releases + +Maetro is a special build of Multi Theft Auto for Windows 7, Windows 8, and Windows 8.1. + +The name is a portmaneteau of [Windows Aero](https://en.wikipedia.org/wiki/Windows_Aero) and [Windows Metro](https://en.wikipedia.org/wiki/Windows_Metro). + +## Differences between the regular MTA release and the maetro release + +- maetro uses an older version of CEF, as Chrome [doesn't support](https://support.google.com/chrome/thread/185534985/sunsetting-support-for-windows-7-8-1-in-early-2023?hl=en) Windows 7, Windows 8, and Windows 8.1. +- maetro uses a different version of `d3dcompiler_47.dll`, stored [as `d3dcompiler_47.maetro.dll`](https://github.com/qaisjp/mtasa-blue/commits/master/Shared/data/MTA%20San%20Andreas/MTA/d3dcompiler_47.maetro.dll). +- various [other minor customisations](https://github.com/search?q=repo%3Amultitheftauto%2Fmtasa-blue%20MTA_MAETRO&type=code) to make sure the build continues to succeed + +## Building + +- maetro is built from the `master` branch with the `MTA_MAETRO=true` environment variable. +- Build maetro locally by running `$env:MTA_MAETRO='true'; .\win-create-projects.bat; \$env:MTA_MAETRO=$null` in PowerShell. +- GitHub Actions doesn't currently build maetro. diff --git a/README.md b/README.md index 2934cf64139..e8abb8d3816 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,9 @@ Our project's code repository can be found on the [multitheftauto/mtasa-blue](ht #### Windows Prerequisites -- [Visual Studio 2022](https://visualstudio.microsoft.com/vs/) with: +- [Visual Studio 2026](https://visualstudio.microsoft.com/vs/) with: - Desktop development with C++ - - Optional component *C++ MFC for latest v143 build tools (x86 & x64)* + - Optional component *C++ MFC for latest v145 build tools (x86 & x64)* or if that's missing *C++ MFC for x64/x86 (Latest MSVC)* - [Microsoft DirectX SDK](https://wiki.multitheftauto.com/wiki/Compiling_MTASA#Microsoft_DirectX_SDK) - [Git for Windows](https://git-scm.com/download/win) (Optional) @@ -126,4 +126,4 @@ Execute `win-create-projects.bat` Unless otherwise specified, all source code hosted on this repository is licensed under the GPLv3 license. See the [LICENSE](./LICENSE) file for more details. -Grand Theft Auto and all related trademarks are © Rockstar North 1997–2025. +Grand Theft Auto and all related trademarks are © Rockstar North 1997–2026. diff --git a/Server/core/CCrashHandler.cpp b/Server/core/CCrashHandler.cpp index 6578e10c328..d69e51442d4 100644 --- a/Server/core/CCrashHandler.cpp +++ b/Server/core/CCrashHandler.cpp @@ -46,14 +46,19 @@ static SString ms_strDumpPathFilename; static SString ms_strDumpPath; #ifdef WIN32 -#include -#include -#include + #include + #include + #include + #include + #include typedef BOOL(WINAPI* MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); +static HMODULE ms_hDbgHelp = NULL; +static MINIDUMPWRITEDUMP ms_pMiniDumpWriteDump = nullptr; + #endif void CCrashHandler::Init(const SString& strInServerPath) @@ -63,10 +68,36 @@ void CCrashHandler::Init(const SString& strInServerPath) strServerPath = GetSystemCurrentDirectory(); ms_strDumpPath = PathJoin(strServerPath, SERVER_DUMP_PATH); - // Set a global filter - #ifdef WIN32 +// Set a global filter +#ifdef WIN32 + // Load dbghelp.dll now while the loader lock is not held. During a crash + // the loader lock may already be owned, so calling LoadLibrary at that + // point would deadlock. + { + char szDbgHelpPath[MAX_PATH]; + if (GetModuleFileNameA(NULL, szDbgHelpPath, MAX_PATH)) + { + char* pSlash = _tcsrchr(szDbgHelpPath, '\\'); + if (pSlash) + { + _tcscpy(pSlash + 1, "DBGHELP.DLL"); + ms_hDbgHelp = LoadLibrary(szDbgHelpPath); + } + } + if (!ms_hDbgHelp) + ms_hDbgHelp = LoadLibrary("DBGHELP.DLL"); + + if (ms_hDbgHelp) + { + const auto procAddr = GetProcAddress(ms_hDbgHelp, "MiniDumpWriteDump"); + static_assert(sizeof(ms_pMiniDumpWriteDump) == sizeof(procAddr), "Unexpected function pointer size"); + if (procAddr) + std::memcpy(&ms_pMiniDumpWriteDump, &procAddr, sizeof(ms_pMiniDumpWriteDump)); + } + } + SetCrashHandlerFilter(HandleExceptionGlobal); - #else +#else // Prepare initial dumpfile name time_t pTime = time(NULL); @@ -75,17 +106,21 @@ void CCrashHandler::Init(const SString& strInServerPath) ms_strDumpPathFilename = PathJoin(ms_strDumpPath, strFilename); MakeSureDirExists(ms_strDumpPathFilename); - #ifdef WITH_BACKTRACE_ONLY + #ifdef WITH_BACKTRACE_ONLY signal(SIGSEGV, HandleExceptionGlobal); - #else - #ifdef __APPLE__ + signal(SIGFPE, HandleExceptionGlobal); + signal(SIGBUS, HandleExceptionGlobal); + signal(SIGILL, HandleExceptionGlobal); + signal(SIGABRT, HandleExceptionGlobal); + #else + #ifdef __APPLE__ static google_breakpad::ExceptionHandler eh(ms_strDumpPath, NULL, DumpCallback, NULL, true, NULL); - #else - google_breakpad::MinidumpDescriptor descriptor(ms_strDumpPath); + #else + google_breakpad::MinidumpDescriptor descriptor(ms_strDumpPath); static google_breakpad::ExceptionHandler eh(descriptor, NULL, DumpCallback, NULL, true, -1); - #endif #endif #endif +#endif } #ifndef WIN32 @@ -112,11 +147,14 @@ inline __attribute__((always_inline)) static void SaveBacktraceSummary() sContent += SString("Caught %d addresses ...\n\n", iAmount); sContent += "Backtrace:\n"; - for (int i = 0; i < iAmount; i++) + if (symbols) { - if (symbols[i]) + for (int i = 0; i < iAmount; i++) { - sContent += SString("#%d - %s\n", i, symbols[i]); + if (symbols[i]) + { + sContent += SString("#%d - %s\n", i, symbols[i]); + } } } sContent += std::string(80, '-') + "\n"; @@ -142,28 +180,37 @@ inline __attribute__((always_inline)) static void SaveBacktraceSummary() } } -// Linux/Mac crash callback when using google-breakpad -#ifdef __APPLE__ + // Linux/Mac crash callback when using google-breakpad + #ifdef __APPLE__ bool DumpCallback(const char* dump_dir, const char* minidump_id, void* context, bool succeeded) { auto path = PathJoin(dump_dir, SString("%s.dmp", minidump_id)); -#else + #else bool DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) { auto path = descriptor.path(); -#endif - // Set inital dump file name (Safeish) - File::Rename(path, ms_strDumpPathFilename); + #endif - // Set final dump file name (Not so safe) - time_t pTime = time(NULL); - struct tm* tm = localtime(&pTime); - SString strFilename("server_%s_%04d%02d%02d_%02d%02d.dmp", MTA_DM_BUILDTAG_LONG, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min); - SString strFinalDumpPathFilename = PathJoin(ms_strDumpPath, strFilename); - File::Rename(ms_strDumpPathFilename, strFinalDumpPathFilename); + SString strFinalDumpPathFilename; + + if (succeeded) + { + // Set inital dump file name (Safeish) + File::Rename(path, ms_strDumpPathFilename); + + // Set final dump file name (Not so safe) + time_t pTime = time(NULL); + struct tm* tm = localtime(&pTime); + SString strFilename("server_%s_%04d%02d%02d_%02d%02d.dmp", MTA_DM_BUILDTAG_LONG, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, + tm->tm_min); + strFinalDumpPathFilename = PathJoin(ms_strDumpPath, strFilename); + File::Rename(ms_strDumpPathFilename, strFinalDumpPathFilename); + } SaveBacktraceSummary(); - FileSave(PathJoin(ms_strDumpPath, "server_pending_upload_filename"), strFinalDumpPathFilename); + + if (succeeded) + FileSave(PathJoin(ms_strDumpPath, "server_pending_upload_filename"), strFinalDumpPathFilename); // Return false to indicate exception has not been handled (and allow core dump?) return false; @@ -180,7 +227,12 @@ void CCrashHandler::HandleExceptionGlobal(int iSig) long WINAPI CCrashHandler::HandleExceptionGlobal(_EXCEPTION_POINTERS* pException) { // Create the exception information class - CExceptionInformation_Impl* pExceptionInformation = new CExceptionInformation_Impl; + CExceptionInformation_Impl* pExceptionInformation = new (std::nothrow) CExceptionInformation_Impl; + if (!pExceptionInformation) + { + TerminateProcess(GetCurrentProcess(), 1); + return EXCEPTION_CONTINUE_SEARCH; + } pExceptionInformation->Set(pException->ExceptionRecord->ExceptionCode, pException); // Write the dump @@ -190,79 +242,62 @@ long WINAPI CCrashHandler::HandleExceptionGlobal(_EXCEPTION_POINTERS* pException return EXCEPTION_CONTINUE_SEARCH; } -void CCrashHandler::DumpMiniDump(_EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation) +// Call MiniDumpWriteDump under SEH. The dump writer can crash if the process +// heap is corrupt; catching that crash here lets the handler clean up its +// file handles and exit the process cleanly. +static bool TryWriteDump(MINIDUMPWRITEDUMP pDump, HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE dumpType, _MINIDUMP_EXCEPTION_INFORMATION* pExInfo) { - // Try to load the DLL in our directory - HMODULE hDll = NULL; - char szDbgHelpPath[MAX_PATH]; - if (GetModuleFileNameA(NULL, szDbgHelpPath, MAX_PATH)) + #ifdef _MSC_VER + BOOL bResult = FALSE; + __try { - char* pSlash = _tcsrchr(szDbgHelpPath, '\\'); - if (pSlash) - { - _tcscpy(pSlash + 1, "DBGHELP.DLL"); - hDll = LoadLibrary(szDbgHelpPath); - } + bResult = pDump(hProcess, dwPid, hFile, dumpType, pExInfo, NULL, NULL); } - - // If we couldn't load the one in our dir, load any version available - if (!hDll) + __except (EXCEPTION_EXECUTE_HANDLER) { - hDll = LoadLibrary("DBGHELP.DLL"); + return false; } + return bResult != FALSE; + #else + BOOL bResult = pDump(hProcess, dwPid, hFile, dumpType, pExInfo, NULL, NULL); + return bResult != FALSE; + #endif +} - // We could load a dll? - if (hDll) - { - // Grab the MiniDumpWriteDump proc address - MINIDUMPWRITEDUMP pDump = reinterpret_cast(GetProcAddress(hDll, "MiniDumpWriteDump")); - if (pDump) - { - // Grab the current time - // Ask windows for the system time. - SYSTEMTIME SystemTime; - GetLocalTime(&SystemTime); - - // Create the dump directory - CreateDirectory(ms_strDumpPath, 0); - CreateDirectory(PathJoin(ms_strDumpPath, "private"), 0); - - SString strModuleName = pExceptionInformation->GetModuleBaseName(); - strModuleName = strModuleName.ReplaceI(".dll", "").Replace(".exe", "").Replace("_", "").Replace(".", "").Replace("-", ""); - if (strModuleName.length() == 0) - strModuleName = "unknown"; - - #ifdef _WIN64 - strModuleName += "64"; - #endif - - SString strFilename("server_%s_%s_%08x_%x_%04d%02d%02d_%02d%02d.dmp", MTA_DM_BUILDTAG_LONG, strModuleName.c_str(), - pExceptionInformation->GetAddressModuleOffset(), pExceptionInformation->GetCode() & 0xffff, SystemTime.wYear, SystemTime.wMonth, - SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute); - - SString strFinalDumpPathFilename = PathJoin(ms_strDumpPath, "private", strFilename); +void CCrashHandler::DumpMiniDump(_EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation) +{ + MINIDUMPWRITEDUMP pDump = ms_pMiniDumpWriteDump; - // Create the file - HANDLE hFile = CreateFile(strFinalDumpPathFilename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile != INVALID_HANDLE_VALUE) - { - // Create an exception information struct - _MINIDUMP_EXCEPTION_INFORMATION ExInfo; - ExInfo.ThreadId = GetCurrentThreadId(); - ExInfo.ExceptionPointers = pException; - ExInfo.ClientPointers = FALSE; + if (pDump) + { + // Grab the current time + // Ask windows for the system time. + SYSTEMTIME SystemTime; + GetLocalTime(&SystemTime); + + // Create the dump directory + CreateDirectory(ms_strDumpPath, 0); + CreateDirectory(PathJoin(ms_strDumpPath, "private"), 0); + + SString strModuleName = pExceptionInformation->GetModuleBaseName(); + strModuleName = strModuleName.ReplaceI(".dll", "").Replace(".exe", "").Replace("_", "").Replace(".", "").Replace("-", ""); + if (strModuleName.length() == 0) + strModuleName = "unknown"; + + #ifdef _WIN64 + strModuleName += "64"; + #endif - // Write the dump - pDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, (MINIDUMP_TYPE)(MiniDumpNormal | MiniDumpWithIndirectlyReferencedMemory), &ExInfo, - NULL, NULL); + SString strFilename("server_%s_%s_%08x_%x_%04d%02d%02d_%02d%02d.dmp", MTA_DM_BUILDTAG_LONG, strModuleName.c_str(), + pExceptionInformation->GetAddressModuleOffset(), pExceptionInformation->GetCode() & 0xffff, SystemTime.wYear, SystemTime.wMonth, + SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute); - // Close the dumpfile - CloseHandle(hFile); + SString strFinalDumpPathFilename = PathJoin(ms_strDumpPath, "private", strFilename); - FileSave(PathJoin(ms_strDumpPath, "server_pending_upload_filename"), strFinalDumpPathFilename); - } - - // Write a log with the generic exception information + // Write the log before attempting the dump. If MiniDumpWriteDump crashes + // below (which happens when the process heap is corrupt), the log is + // already on disk and still captures the original exception info. + { FILE* pFile = File::Fopen(PathJoin(ms_strDumpPath, "server_pending_upload.log"), "a+"); if (pFile) { @@ -277,15 +312,38 @@ void CCrashHandler::DumpMiniDump(_EXCEPTION_POINTERS* pException, CExceptionInfo SString strInfo; strInfo += SString("Version = %s\n", strMTAVersionFull.c_str()); - strInfo += SString("Time = %s", ctime(&timeTemp)); - strInfo += SString("Module = %s\n", pExceptionInformation->GetModulePathName()); + char szTimeBuf[64]; + struct tm tmLocal; + localtime_s(&tmLocal, &timeTemp); + strftime(szTimeBuf, sizeof(szTimeBuf), "%c\n", &tmLocal); + strInfo += SString("Time = %s", szTimeBuf); + + const char* szModulePath = pExceptionInformation->GetModulePathName(); + strInfo += SString("Module = %s\n", szModulePath ? szModulePath : ""); // Write the basic exception information strInfo += SString("Code = 0x%08X\n", pExceptionInformation->GetCode()); strInfo += SString("Offset = 0x%08X\n\n", pExceptionInformation->GetAddressModuleOffset()); // Write the register info + #ifdef WIN_x64 + strInfo += SString( + "RAX=%016llX RBX=%016llX RCX=%016llX\n" + "RDX=%016llX RSI=%016llX RDI=%016llX\n" + "RBP=%016llX RSP=%016llX RIP=%016llX\n" + "R8 =%016llX R9 =%016llX R10=%016llX\n" + "R11=%016llX R12=%016llX R13=%016llX\n" + "R14=%016llX R15=%016llX FLG=%08X\n" + "CS=%04X DS=%04X SS=%04X ES=%04X " + "FS=%04X GS=%04X\n\n", + pExceptionInformation->GetRAX(), pExceptionInformation->GetRBX(), pExceptionInformation->GetRCX(), pExceptionInformation->GetRDX(), + pExceptionInformation->GetRSI(), pExceptionInformation->GetRDI(), pExceptionInformation->GetRBP(), pExceptionInformation->GetRSP(), + pExceptionInformation->GetRIP(), pExceptionInformation->GetR8(), pExceptionInformation->GetR9(), pExceptionInformation->GetR10(), + pExceptionInformation->GetR11(), pExceptionInformation->GetR12(), pExceptionInformation->GetR13(), pExceptionInformation->GetR14(), + pExceptionInformation->GetR15(), pExceptionInformation->GetEFlags(), pExceptionInformation->GetCS(), pExceptionInformation->GetDS(), + pExceptionInformation->GetSS(), pExceptionInformation->GetES(), pExceptionInformation->GetFS(), pExceptionInformation->GetGS()); + #else strInfo += SString( "EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESI=%08X\n" "EDI=%08X EBP=%08X ESP=%08X EIP=%08X FLG=%08X\n" @@ -295,19 +353,44 @@ void CCrashHandler::DumpMiniDump(_EXCEPTION_POINTERS* pException, CExceptionInfo pExceptionInformation->GetESI(), pExceptionInformation->GetEDI(), pExceptionInformation->GetEBP(), pExceptionInformation->GetESP(), pExceptionInformation->GetEIP(), pExceptionInformation->GetEFlags(), pExceptionInformation->GetCS(), pExceptionInformation->GetDS(), pExceptionInformation->GetSS(), pExceptionInformation->GetES(), pExceptionInformation->GetFS(), pExceptionInformation->GetGS()); + #endif fprintf(pFile, "%s", strInfo.c_str()); // End of unhandled exception fprintf(pFile, "%s", "** -- End of unhandled exception -- **\n\n\n"); + // Flush before close. fflush writes directly to the OS (no heap + // alloc), so it succeeds even if the heap is corrupt. fclose + // may fault when freeing internal buffers in that case. + fflush(pFile); + // Close the file fclose(pFile); } } - // Free the DLL again - FreeLibrary(hDll); + // Create the file + HANDLE hFile = CreateFile(strFinalDumpPathFilename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + _MINIDUMP_EXCEPTION_INFORMATION ExInfo; + ExInfo.ThreadId = GetCurrentThreadId(); + ExInfo.ExceptionPointers = pException; + ExInfo.ClientPointers = FALSE; + + // MiniDumpWriteDump can crash if the process heap is corrupt at the time + // of the fault. TryWriteDump catches the secondary exception so this + // handler can finish cleanly. + const bool bDumpWritten = TryWriteDump(pDump, GetCurrentProcess(), GetCurrentProcessId(), hFile, + (MINIDUMP_TYPE)(MiniDumpNormal | MiniDumpWithIndirectlyReferencedMemory), &ExInfo); + + // Close the dumpfile + CloseHandle(hFile); + + if (bDumpWritten) + FileSave(PathJoin(ms_strDumpPath, "server_pending_upload_filename"), strFinalDumpPathFilename); + } } } diff --git a/Server/core/CCrashHandler.h b/Server/core/CCrashHandler.h index 0c3878b6e02..7fdd3c31f6d 100644 --- a/Server/core/CCrashHandler.h +++ b/Server/core/CCrashHandler.h @@ -27,16 +27,16 @@ class CCrashHandler static void Init(const SString& strServerPath); private: - #ifdef WIN32 +#ifdef WIN32 static long WINAPI HandleExceptionGlobal(_EXCEPTION_POINTERS* pException); static void DumpMiniDump(_EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation); static void RunErrorTool(); - #else +#else static void HandleExceptionGlobal(int iSig); - #endif +#endif }; diff --git a/Server/core/CCrashHandlerAPI.cpp b/Server/core/CCrashHandlerAPI.cpp index 989d0b00689..0be4b11eb59 100644 --- a/Server/core/CCrashHandlerAPI.cpp +++ b/Server/core/CCrashHandlerAPI.cpp @@ -25,11 +25,13 @@ CONDITIONAL COMPILATION : #include "StdInc.h" #include "CCrashHandlerAPI.h" + +#include #ifdef WIN32 -#ifdef _M_IX86 - #include -#endif + #ifdef _M_IX86 + #include + #endif /*////////////////////////////////////////////////////////////////////// File Scope Global Variables @@ -46,13 +48,13 @@ static LPTOP_LEVEL_EXCEPTION_FILTER g_pfnOrigFilt = NULL; // The exception handler LONG __stdcall CrashHandlerExceptionFilter(EXCEPTION_POINTERS* pExPtrs); -/*////////////////////////////////////////////////////////////////////// - Destructor Class -//////////////////////////////////////////////////////////////////////*/ -// See the note in MEMDUMPVALIDATOR.CPP about automatic classes. -// Turn off warning : initializers put in library initialization area -#pragma warning (disable : 4073) -#pragma init_seg(lib) + /*////////////////////////////////////////////////////////////////////// + Destructor Class + //////////////////////////////////////////////////////////////////////*/ + // See the note in MEMDUMPVALIDATOR.CPP about automatic classes. + // Turn off warning : initializers put in library initialization area + #pragma warning(disable : 4073) + #pragma init_seg(lib) class CleanUpCrashHandler { public: @@ -89,9 +91,24 @@ BOOL __stdcall SetCrashHandlerFilter(PFNCHFILTFN pFn) } else { - if (TRUE == IsBadCodePtr((FARPROC)pFn)) { - return (FALSE); + const void* address = nullptr; + static_assert(sizeof(address) == sizeof(pFn), "Unexpected function pointer size"); + std::memcpy(&address, &pFn, sizeof(address)); + + MEMORY_BASIC_INFORMATION mbi{}; + if (VirtualQuery(address, &mbi, sizeof(mbi)) != sizeof(mbi)) + return (FALSE); + if (mbi.State != MEM_COMMIT) + return (FALSE); + if ((mbi.Protect & PAGE_GUARD) || (mbi.Protect & PAGE_NOACCESS)) + return (FALSE); + + const DWORD protect = (mbi.Protect & 0xFF); + const bool isExecutable = + protect == PAGE_EXECUTE || protect == PAGE_EXECUTE_READ || protect == PAGE_EXECUTE_READWRITE || protect == PAGE_EXECUTE_WRITECOPY; + if (!isExecutable) + return (FALSE); } g_pfnCallBack = pFn; @@ -102,11 +119,12 @@ BOOL __stdcall SetCrashHandlerFilter(PFNCHFILTFN pFn) { g_pfnOrigFilt = SetUnhandledExceptionFilter(CrashHandlerExceptionFilter); -#ifdef _M_IX86 + #ifdef _M_IX86 // Stop the OS from turning off our handler // Ref: https://www.codeproject.com/Articles/154686/SetUnhandledExceptionFilter-and-the-C-C-Runtime-Li LPTOP_LEVEL_EXCEPTION_FILTER(WINAPI * RedirectedSetUnhandledExceptionFilter) - (LPTOP_LEVEL_EXCEPTION_FILTER) = [](LPTOP_LEVEL_EXCEPTION_FILTER /*ExceptionInfo*/) -> LPTOP_LEVEL_EXCEPTION_FILTER { + (LPTOP_LEVEL_EXCEPTION_FILTER) = [](LPTOP_LEVEL_EXCEPTION_FILTER /*ExceptionInfo*/) -> LPTOP_LEVEL_EXCEPTION_FILTER + { // When the CRT calls SetUnhandledExceptionFilter with NULL parameter // our handler will not get removed. return 0; @@ -115,7 +133,7 @@ BOOL __stdcall SetCrashHandlerFilter(PFNCHFILTFN pFn) "invalid type of RedirectedSetUnhandledExceptionFilter"); DetourLibraryFunction("kernel32.dll", "SetUnhandledExceptionFilter", RedirectedSetUnhandledExceptionFilter); -#endif + #endif } } return (TRUE); @@ -162,7 +180,7 @@ LONG __stdcall CrashHandlerExceptionFilter(EXCEPTION_POINTERS* pExPtrs) // it got unloaded. If some other function loaded // back into the same address, however, there isn't much // I can do. - if (FALSE == IsBadCodePtr((FARPROC)g_pfnCallBack)) + if (FALSE == IsBadCodePtr(reinterpret_cast(reinterpret_cast(g_pfnCallBack)))) { lRet = g_pfnCallBack(pExPtrs); } diff --git a/Server/core/CCrashHandlerAPI.h b/Server/core/CCrashHandlerAPI.h index c3f06e859aa..0013b541d40 100644 --- a/Server/core/CCrashHandlerAPI.h +++ b/Server/core/CCrashHandlerAPI.h @@ -21,16 +21,16 @@ Copyright (c) 1997-2000 John Robbins -- All rights reserved. #ifdef WIN32 -#ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN -#endif -#include -#define BUGSUTIL_DLLINTERFACE + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + #include + #define BUGSUTIL_DLLINTERFACE -#ifdef __cplusplus + #ifdef __cplusplus extern "C" { -#endif //__cplusplus + #endif //__cplusplus /*////////////////////////////////////////////////////////////////////// Type Definitions @@ -59,8 +59,8 @@ extern "C" ----------------------------------------------------------------------*/ BOOL BUGSUTIL_DLLINTERFACE __stdcall SetCrashHandlerFilter(PFNCHFILTFN pFn); -#ifdef __cplusplus + #ifdef __cplusplus } -#endif //__cplusplus + #endif //__cplusplus #endif diff --git a/Server/core/CDynamicLibrary.cpp b/Server/core/CDynamicLibrary.cpp index 344f8f0041d..5478b539779 100644 --- a/Server/core/CDynamicLibrary.cpp +++ b/Server/core/CDynamicLibrary.cpp @@ -56,8 +56,8 @@ bool CDynamicLibrary::Load(const char* szFilename) #endif - // Load the new library - #ifdef WIN32 +// Load the new library +#ifdef WIN32 m_hModule = LoadLibraryEx(szFilename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); // Failed? @@ -76,7 +76,7 @@ bool CDynamicLibrary::Load(const char* szFilename) // Free the error message buffer LocalFree(lpMsgBuf); } - #else +#else m_hModule = dlopen(szFilename, RTLD_NOW); // Output error if needed @@ -88,7 +88,7 @@ bool CDynamicLibrary::Load(const char* szFilename) else Print("Loading %s failed\n", szFilename); } - #endif +#endif // Check for version mismatch if (!CheckMtaVersion(ExtractFilename(szFilename))) @@ -105,11 +105,11 @@ void CDynamicLibrary::Unload() // Got a module? if (m_hModule != 0) { - #ifdef WIN32 +#ifdef WIN32 FreeLibrary(m_hModule); - #else +#else dlclose(m_hModule); - #endif +#endif // Zero out our library as it's no longer valid m_hModule = 0; @@ -126,20 +126,20 @@ FuncPtr_t CDynamicLibrary::GetProcedureAddress(const char* szProcName) // Got a module? if (m_hModule != 0) { - #ifdef WIN32 - return (FuncPtr_t)GetProcAddress(m_hModule, szProcName); - #else +#ifdef WIN32 + return GetProcAddress(m_hModule, szProcName); +#else char* szError = NULL; dlerror(); - FuncPtr_t pFunc = (FuncPtr_t)dlsym(m_hModule, szProcName); + auto pFunc = reinterpret_cast(dlsym(m_hModule, szProcName)); if ((szError = dlerror()) != NULL) { return NULL; } return pFunc; - #endif +#endif } return NULL; @@ -149,7 +149,7 @@ bool CDynamicLibrary::CheckMtaVersion(const char* szLibName) { #if MTASA_VERSION_TYPE >= VERSION_TYPE_UNSTABLE // define MTASA_SKIP_VERSION_CHECKS in "Shared/build_overrides.h" to skip version checks -#ifndef MTASA_SKIP_VERSION_CHECKS + #ifndef MTASA_SKIP_VERSION_CHECKS if (m_hModule == 0) return false; @@ -179,7 +179,7 @@ bool CDynamicLibrary::CheckMtaVersion(const char* szLibName) return false; } -#endif + #endif #endif return true; } diff --git a/Server/core/CDynamicLibrary.h b/Server/core/CDynamicLibrary.h index ab65575adb7..20033c23d6d 100644 --- a/Server/core/CDynamicLibrary.h +++ b/Server/core/CDynamicLibrary.h @@ -12,10 +12,14 @@ #pragma once #ifdef WIN32 -#include + #include #endif +#ifdef WIN32 +using FuncPtr_t = FARPROC; +#else typedef void (*FuncPtr_t)(); +#endif class CDynamicLibrary { @@ -31,9 +35,9 @@ class CDynamicLibrary bool CheckMtaVersion(const char* szLibName); private: - #ifdef WIN32 +#ifdef WIN32 HMODULE m_hModule; - #else +#else void* m_hModule; - #endif +#endif }; diff --git a/Server/core/CExceptionInformation_Impl.cpp b/Server/core/CExceptionInformation_Impl.cpp index 00b12acd4c8..e3d6d6c6534 100644 --- a/Server/core/CExceptionInformation_Impl.cpp +++ b/Server/core/CExceptionInformation_Impl.cpp @@ -12,6 +12,9 @@ #include "StdInc.h" #include "CExceptionInformation_Impl.h" +#include +#include + #define MAX_MODULE_PATH 512 CExceptionInformation_Impl::CExceptionInformation_Impl() @@ -37,12 +40,31 @@ CExceptionInformation_Impl::CExceptionInformation_Impl() m_ulGS = 0; m_ulSS = 0; m_ulEFlags = 0; +#ifdef WIN_x64 + m_ullRAX = 0; + m_ullRBX = 0; + m_ullRCX = 0; + m_ullRDX = 0; + m_ullRSI = 0; + m_ullRDI = 0; + m_ullRBP = 0; + m_ullRSP = 0; + m_ullRIP = 0; + m_ullR8 = 0; + m_ullR9 = 0; + m_ullR10 = 0; + m_ullR11 = 0; + m_ullR12 = 0; + m_ullR13 = 0; + m_ullR14 = 0; + m_ullR15 = 0; +#endif } CExceptionInformation_Impl::~CExceptionInformation_Impl() { if (m_szModulePathName) - delete m_szModulePathName; + delete[] m_szModulePathName; } void CExceptionInformation_Impl::Set(unsigned int iCode, _EXCEPTION_POINTERS* pException) @@ -66,14 +88,43 @@ void CExceptionInformation_Impl::Set(unsigned int iCode, _EXCEPTION_POINTERS* pE m_ulGS = pException->ContextRecord->SegGs; m_ulSS = pException->ContextRecord->SegSs; m_ulEFlags = pException->ContextRecord->EFlags; +#elif defined(WIN_x64) + m_ullRAX = pException->ContextRecord->Rax; + m_ullRBX = pException->ContextRecord->Rbx; + m_ullRCX = pException->ContextRecord->Rcx; + m_ullRDX = pException->ContextRecord->Rdx; + m_ullRSI = pException->ContextRecord->Rsi; + m_ullRDI = pException->ContextRecord->Rdi; + m_ullRBP = pException->ContextRecord->Rbp; + m_ullRSP = pException->ContextRecord->Rsp; + m_ullRIP = pException->ContextRecord->Rip; + m_ullR8 = pException->ContextRecord->R8; + m_ullR9 = pException->ContextRecord->R9; + m_ullR10 = pException->ContextRecord->R10; + m_ullR11 = pException->ContextRecord->R11; + m_ullR12 = pException->ContextRecord->R12; + m_ullR13 = pException->ContextRecord->R13; + m_ullR14 = pException->ContextRecord->R14; + m_ullR15 = pException->ContextRecord->R15; + m_ulCS = pException->ContextRecord->SegCs; + m_ulDS = pException->ContextRecord->SegDs; + m_ulES = pException->ContextRecord->SegEs; + m_ulFS = pException->ContextRecord->SegFs; + m_ulGS = pException->ContextRecord->SegGs; + m_ulSS = pException->ContextRecord->SegSs; + m_ulEFlags = pException->ContextRecord->EFlags; #endif void* pModuleBaseAddress = NULL; - m_szModulePathName = new char[MAX_MODULE_PATH]; - GetModule(m_szModulePathName, MAX_MODULE_PATH, &pModuleBaseAddress); - m_szModuleBaseName = strrchr(m_szModulePathName, '\\'); - m_szModuleBaseName = m_szModuleBaseName ? m_szModuleBaseName + 1 : m_szModulePathName; - m_uiAddressModuleOffset = static_cast(GetAddress()) - static_cast(pModuleBaseAddress); + m_szModulePathName = new (std::nothrow) char[MAX_MODULE_PATH]; + if (m_szModulePathName) + { + GetModule(m_szModulePathName, MAX_MODULE_PATH, &pModuleBaseAddress); + m_szModuleBaseName = strrchr(m_szModulePathName, '\\'); + m_szModuleBaseName = m_szModuleBaseName ? m_szModuleBaseName + 1 : m_szModulePathName; + } + if (pModuleBaseAddress) + m_uiAddressModuleOffset = static_cast(GetAddress()) - static_cast(pModuleBaseAddress); } /** @@ -113,7 +164,13 @@ bool CExceptionInformation_Impl::GetModule(char* szOutputBuffer, int nOutputName * See if we're able to use GetModuleHandleExA. According to Microsoft, * this API is only available on Windows XP and Vista. */ - _pfnGetModuleHandleExA pfnGetModuleHandleExA = (_pfnGetModuleHandleExA)GetProcAddress(hKern32, "GetModuleHandleExA"); + _pfnGetModuleHandleExA pfnGetModuleHandleExA = NULL; + { + const auto procAddr = GetProcAddress(hKern32, "GetModuleHandleExA"); + static_assert(sizeof(pfnGetModuleHandleExA) == sizeof(procAddr), "Unexpected function pointer size"); + if (procAddr) + std::memcpy(&pfnGetModuleHandleExA, &procAddr, sizeof(pfnGetModuleHandleExA)); + } /* * TODO: Possibly use our own code to do this for other systems. diff --git a/Server/core/CExceptionInformation_Impl.h b/Server/core/CExceptionInformation_Impl.h index f4ff0863318..e5108def521 100644 --- a/Server/core/CExceptionInformation_Impl.h +++ b/Server/core/CExceptionInformation_Impl.h @@ -18,7 +18,7 @@ class CExceptionInformation_Impl : public CExceptionInformation { public: CExceptionInformation_Impl(); - ~CExceptionInformation_Impl(); // {}; + ~CExceptionInformation_Impl(); // {}; unsigned int GetCode() { return m_uiCode; }; void* GetAddress() { return m_pAddress; }; @@ -44,6 +44,26 @@ class CExceptionInformation_Impl : public CExceptionInformation unsigned long GetSS() { return m_ulSS; }; unsigned long GetEFlags() { return m_ulEFlags; }; +#ifdef WIN_x64 + unsigned long long GetRAX() { return m_ullRAX; }; + unsigned long long GetRBX() { return m_ullRBX; }; + unsigned long long GetRCX() { return m_ullRCX; }; + unsigned long long GetRDX() { return m_ullRDX; }; + unsigned long long GetRSI() { return m_ullRSI; }; + unsigned long long GetRDI() { return m_ullRDI; }; + unsigned long long GetRBP() { return m_ullRBP; }; + unsigned long long GetRSP() { return m_ullRSP; }; + unsigned long long GetRIP() { return m_ullRIP; }; + unsigned long long GetR8() { return m_ullR8; }; + unsigned long long GetR9() { return m_ullR9; }; + unsigned long long GetR10() { return m_ullR10; }; + unsigned long long GetR11() { return m_ullR11; }; + unsigned long long GetR12() { return m_ullR12; }; + unsigned long long GetR13() { return m_ullR13; }; + unsigned long long GetR14() { return m_ullR14; }; + unsigned long long GetR15() { return m_ullR15; }; +#endif + void Set(unsigned int iCode, _EXCEPTION_POINTERS* pException); private: @@ -68,4 +88,23 @@ class CExceptionInformation_Impl : public CExceptionInformation unsigned long m_ulGS; unsigned long m_ulSS; unsigned long m_ulEFlags; +#ifdef WIN_x64 + unsigned long long m_ullRAX; + unsigned long long m_ullRBX; + unsigned long long m_ullRCX; + unsigned long long m_ullRDX; + unsigned long long m_ullRSI; + unsigned long long m_ullRDI; + unsigned long long m_ullRBP; + unsigned long long m_ullRSP; + unsigned long long m_ullRIP; + unsigned long long m_ullR8; + unsigned long long m_ullR9; + unsigned long long m_ullR10; + unsigned long long m_ullR11; + unsigned long long m_ullR12; + unsigned long long m_ullR13; + unsigned long long m_ullR14; + unsigned long long m_ullR15; +#endif }; diff --git a/Server/core/CModManagerImpl.cpp b/Server/core/CModManagerImpl.cpp index 3628d9f1b7a..cf31c060a26 100644 --- a/Server/core/CModManagerImpl.cpp +++ b/Server/core/CModManagerImpl.cpp @@ -74,7 +74,10 @@ bool CModManagerImpl::Load(const char* szModName, int iArgumentCount, char* szAr } // Grab the initialization procedure - InitServer* pfnInitServer = (InitServer*)(m_Library.GetProcedureAddress("InitServer")); + InitServer* pfnInitServer = nullptr; + const auto procAddr = m_Library.GetProcedureAddress("InitServer"); + static_assert(sizeof(pfnInitServer) == sizeof(procAddr), "Unexpected function pointer size"); + std::memcpy(&pfnInitServer, &procAddr, sizeof(pfnInitServer)); if (!pfnInitServer) { // Unload the library diff --git a/Server/core/CModManagerImpl.h b/Server/core/CModManagerImpl.h index 272cef87a3d..1dfaedcb9ab 100644 --- a/Server/core/CModManagerImpl.h +++ b/Server/core/CModManagerImpl.h @@ -62,6 +62,6 @@ class CModManagerImpl : public CModManager CServerBase* m_pBase; CDynamicLibrary m_Library; - SString m_strServerPath; // Root path - SString m_strModPath; // root/mods/deathmatch + SString m_strServerPath; // Root path + SString m_strModPath; // root/mods/deathmatch }; diff --git a/Server/core/CServerImpl.cpp b/Server/core/CServerImpl.cpp index 0f11cc1cd75..b868d455e02 100644 --- a/Server/core/CServerImpl.cpp +++ b/Server/core/CServerImpl.cpp @@ -48,7 +48,7 @@ bool IsCursesActive() return m_wndInput != NULL; } #else -bool g_isChildProcess = false; +bool g_isChildProcess = false; HANDLE g_readyEvent = nullptr; #endif @@ -58,13 +58,13 @@ CServerImpl::CServerImpl(CThreadCommandQueue* pThreadCommandQueue) CServerImpl::CServerImpl() #endif { - #ifdef WIN32 +#ifdef WIN32 m_pThreadCommandQueue = pThreadCommandQueue; m_hConsole = NULL; - #else +#else m_wndMenu = NULL; m_wndInput = NULL; - #endif +#endif // Init m_pNetwork = NULL; @@ -331,7 +331,12 @@ int CServerImpl::Run(int iArgumentCount, char* szArguments[]) { // Network module compatibility check typedef unsigned long (*PFNCHECKCOMPATIBILITY)(unsigned long, unsigned long*); - PFNCHECKCOMPATIBILITY pfnCheckCompatibility = reinterpret_cast(m_NetworkLibrary.GetProcedureAddress("CheckCompatibility")); + PFNCHECKCOMPATIBILITY pfnCheckCompatibility = nullptr; + { + const auto procAddr = m_NetworkLibrary.GetProcedureAddress("CheckCompatibility"); + static_assert(sizeof(pfnCheckCompatibility) == sizeof(procAddr), "Unexpected function pointer size"); + std::memcpy(&pfnCheckCompatibility, &procAddr, sizeof(pfnCheckCompatibility)); + } if (!pfnCheckCompatibility || !pfnCheckCompatibility(MTA_DM_SERVER_NET_MODULE_VERSION, (unsigned long*)MTASA_VERSION_TYPE)) { // net.dll doesn't like our version number @@ -351,9 +356,25 @@ int CServerImpl::Run(int iArgumentCount, char* szArguments[]) if (m_XMLLibrary.Load(PathJoin(m_strServerPath, SERVER_BIN_PATH, szXMLLibName))) { - auto pfnInitNetServerInterface = (InitNetServerInterface)(m_NetworkLibrary.GetProcedureAddress("InitNetServerInterface")); - auto pfnReleaseNetServerInterface = (ReleaseNetServerInterface)(m_NetworkLibrary.GetProcedureAddress("ReleaseNetServerInterface")); - auto pfnInitXMLInterface = (InitXMLInterface)(m_XMLLibrary.GetProcedureAddress("InitXMLInterface")); + InitNetServerInterface pfnInitNetServerInterface = nullptr; + ReleaseNetServerInterface pfnReleaseNetServerInterface = nullptr; + InitXMLInterface pfnInitXMLInterface = nullptr; + + { + const auto procAddr = m_NetworkLibrary.GetProcedureAddress("InitNetServerInterface"); + static_assert(sizeof(pfnInitNetServerInterface) == sizeof(procAddr), "Unexpected function pointer size"); + std::memcpy(&pfnInitNetServerInterface, &procAddr, sizeof(pfnInitNetServerInterface)); + } + { + const auto procAddr = m_NetworkLibrary.GetProcedureAddress("ReleaseNetServerInterface"); + static_assert(sizeof(pfnReleaseNetServerInterface) == sizeof(procAddr), "Unexpected function pointer size"); + std::memcpy(&pfnReleaseNetServerInterface, &procAddr, sizeof(pfnReleaseNetServerInterface)); + } + { + const auto procAddr = m_XMLLibrary.GetProcedureAddress("InitXMLInterface"); + static_assert(sizeof(pfnInitXMLInterface) == sizeof(procAddr), "Unexpected function pointer size"); + std::memcpy(&pfnInitXMLInterface, &procAddr, sizeof(pfnInitXMLInterface)); + } if (pfnInitNetServerInterface && pfnInitXMLInterface) { @@ -364,7 +385,7 @@ int CServerImpl::Run(int iArgumentCount, char* szArguments[]) if (m_pNetwork && m_pXML) { // Make the modmanager load our mod - if (m_pModManager->Load("deathmatch", iArgumentCount, szArguments)) // Hardcoded for now + if (m_pModManager->Load("deathmatch", iArgumentCount, szArguments)) // Hardcoded for now { // Enter our mainloop MainLoop(); @@ -446,7 +467,7 @@ int CServerImpl::Run(int iArgumentCount, char* szArguments[]) void CServerImpl::MainLoop() { #ifdef WIN32 - timeBeginPeriod(1); // Change sleep resolution to 1ms + timeBeginPeriod(1); // Change sleep resolution to 1ms #endif // Loop until a termination is requested @@ -474,10 +495,10 @@ void CServerImpl::MainLoop() // Handle the interpreter input HandleInput(); - // Handle input from the secondary thread - #ifdef WIN32 +// Handle input from the secondary thread +#ifdef WIN32 m_pThreadCommandQueue->Process(m_bRequestedQuit, m_pModManager); - #endif +#endif // Pulse the modmanager m_pModManager->DoPulse(); @@ -498,7 +519,7 @@ void CServerImpl::MainLoop() } #ifdef WIN32 - timeEndPeriod(1); // Restore previous sleep resolution + timeEndPeriod(1); // Restore previous sleep resolution #endif // Unload the current mod @@ -553,7 +574,7 @@ void CServerImpl::ApplyFrameRateLimit(uint uiUseRate) const double dTargetTimeToUse = 1000.0 / uiUseRate; // Time now - double dTimeMs = CTickCount::Now().ToDouble(); // GetTickCount32 (); + double dTimeMs = CTickCount::Now().ToDouble(); // GetTickCount32 (); // Get delta time in ms since last frame double dTimeUsed = dTimeMs - m_dLastTimeMs; @@ -767,7 +788,7 @@ void CServerImpl::HandleInput() switch (iStdIn) { - case '\n': // Newlines and carriage returns + case '\n': // Newlines and carriage returns case '\r': #ifdef WIN32 // Echo a newline @@ -828,12 +849,12 @@ void CServerImpl::HandleInput() m_uiSelectedCommandHistoryEntry = 0; break; - case KEY_BACKSPACE: // Backspace + case KEY_BACKSPACE: // Backspace case 0x7F: if (m_uiInputCount == 0) break; - // Insert a blank space + backspace + // Insert a blank space + backspace #ifdef WIN32 Printf("%c %c", 0x08, 0x08); #else @@ -844,7 +865,7 @@ void CServerImpl::HandleInput() m_szInputBuffer[m_uiInputCount] = 0; break; -#ifdef WIN32 // WIN32: we have to use a prefix code, this routine opens an extra switch +#ifdef WIN32 // WIN32: we have to use a prefix code, this routine opens an extra switch case KEY_EXTENDED: // Color the text if (!g_bSilent && HasConsole()) @@ -897,7 +918,7 @@ void CServerImpl::HandleInput() break; } - case KEY_UP: // Up-arrow cursor + case KEY_UP: // Up-arrow cursor { // If there's nothing to select, break here if (m_vecCommandHistory.size() <= 1 || m_uiSelectedCommandHistoryEntry == 1) @@ -915,7 +936,7 @@ void CServerImpl::HandleInput() break; } - case KEY_DOWN: // Down-arrow cursor + case KEY_DOWN: // Down-arrow cursor { // If there's nothing to select, break here if (m_vecCommandHistory.size() <= 1 || m_uiSelectedCommandHistoryEntry == 0) @@ -926,13 +947,13 @@ void CServerImpl::HandleInput() break; } -#ifdef WIN32 // WIN32: Close the switch again +#ifdef WIN32 // WIN32: Close the switch again } // Restore the color if (!g_bSilent && HasConsole()) SetConsoleTextAttribute(m_hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - break; // KEY_EXTENDED + break; // KEY_EXTENDED #endif default: diff --git a/Server/core/CServerImpl.h b/Server/core/CServerImpl.h index f5fd12d25ac..f7917b5fd5e 100644 --- a/Server/core/CServerImpl.h +++ b/Server/core/CServerImpl.h @@ -37,11 +37,11 @@ constexpr SHORT SCREEN_BUFFER_SIZE = 256; class CServerImpl : public CServerInterface { public: - #ifdef WIN32 +#ifdef WIN32 CServerImpl(CThreadCommandQueue* pThreadCommandQueue); - #else +#else CServerImpl(); - #endif +#endif ~CServerImpl(); diff --git a/Server/core/CThreadCommandQueue.cpp b/Server/core/CThreadCommandQueue.cpp index 873a1c5c574..4a20e7e4499 100644 --- a/Server/core/CThreadCommandQueue.cpp +++ b/Server/core/CThreadCommandQueue.cpp @@ -11,8 +11,8 @@ #include "StdInc.h" #ifdef WIN32 -#include "CThreadCommandQueue.h" -#include "CModManagerImpl.h" + #include "CThreadCommandQueue.h" + #include "CModManagerImpl.h" using std::string; diff --git a/Server/core/CThreadCommandQueue.h b/Server/core/CThreadCommandQueue.h index 8b43c931aea..c33078dd93d 100644 --- a/Server/core/CThreadCommandQueue.h +++ b/Server/core/CThreadCommandQueue.h @@ -13,8 +13,8 @@ #ifdef WIN32 -#include -#include + #include + #include class CThreadCommandQueue { diff --git a/Server/core/ErrorCodes.h b/Server/core/ErrorCodes.h index 4b30901b89a..1d1731fd8f3 100644 --- a/Server/core/ErrorCodes.h +++ b/Server/core/ErrorCodes.h @@ -11,8 +11,8 @@ #pragma once -#define ERROR_NO_ERROR 0 -#define ERROR_NO_NETWORK_LIBRARY 1 +#define ERROR_NO_ERROR 0 +#define ERROR_NO_NETWORK_LIBRARY 1 #define ERROR_NETWORK_LIBRARY_FAILED 2 -#define ERROR_LOADING_MOD 3 -#define ERROR_OTHER 4 +#define ERROR_LOADING_MOD 3 +#define ERROR_OTHER 4 diff --git a/Server/core/Server.cpp b/Server/core/Server.cpp index 952e432c30c..93cc2ae59ab 100644 --- a/Server/core/Server.cpp +++ b/Server/core/Server.cpp @@ -35,26 +35,26 @@ MTAEXPORT int Run(int iArgumentCount, char* szArguments[]) } } - #ifdef WIN32 +#ifdef WIN32 // Disable critical error message boxes SetErrorMode(SEM_FAILCRITICALERRORS); - #endif +#endif - #ifdef WIN_x86 +#ifdef WIN_x86 // Apply file hooks if not already done by the client bool bSkipFileHooks = false; for (int i = 1; i < iArgumentCount; i++) bSkipFileHooks |= SStringX(szArguments[i]).Contains("--clientfeedback"); if (!bSkipFileHooks) AddUtf8FileHooks(); - #endif +#endif - // Create the server - #ifdef WIN32 + // Create the server +#ifdef WIN32 CServerImpl Server(&g_CommandQueue); - #else +#else CServerImpl Server; - #endif +#endif // Run the main func int iReturn; @@ -63,10 +63,10 @@ MTAEXPORT int Run(int iArgumentCount, char* szArguments[]) iReturn = Server.Run(iArgumentCount, szArguments); } while (iReturn == SERVER_RESET_RETURN); - // Done - #ifdef WIN_x86 +// Done +#ifdef WIN_x86 RemoveUtf8FileHooks(); - #endif +#endif // Overwrite the exit code, if we are stopping gracefully without errors if (iReturn == ERROR_NO_ERROR) diff --git a/Server/core/StdInc.h b/Server/core/StdInc.h index 070a739d35a..cd370fa42ea 100644 --- a/Server/core/StdInc.h +++ b/Server/core/StdInc.h @@ -55,6 +55,6 @@ #endif #ifndef Sleep - #define Sleep(duration) usleep((duration)*1000) + #define Sleep(duration) usleep((duration) * 1000) #endif #endif diff --git a/Server/core/premake5.lua b/Server/core/premake5.lua index c7b5c552d96..0ee132f0fd7 100644 --- a/Server/core/premake5.lua +++ b/Server/core/premake5.lua @@ -3,10 +3,10 @@ project "Core" kind "SharedLib" targetname "core" targetdir(buildpath("server")) + clangtidy "On" filter "system:windows" includedirs { "../../vendor/sparsehash/current/src/windows" } - linkoptions { "/SAFESEH:NO" } filter {} includedirs { diff --git a/Server/dbconmy/CDatabaseConnectionMySql.cpp b/Server/dbconmy/CDatabaseConnectionMySql.cpp index be29caf8179..de9e6b998ea 100644 --- a/Server/dbconmy/CDatabaseConnectionMySql.cpp +++ b/Server/dbconmy/CDatabaseConnectionMySql.cpp @@ -110,7 +110,7 @@ CDatabaseConnectionMySql::CDatabaseConnectionMySql(CDatabaseType* pManager, cons m_handle = mysql_init(NULL); if (m_handle) { - bool reconnect = m_bAutomaticReconnect; + bool reconnect = m_bAutomaticReconnect; uint const ssl_mode = m_bUseSSL ? SSL_MODE_REQUIRED : SSL_MODE_DISABLED; mysql_options(m_handle, MYSQL_OPT_RECONNECT, &reconnect); mysql_options(m_handle, MYSQL_OPT_SSL_MODE, &ssl_mode); diff --git a/Server/dbconmy/premake5.lua b/Server/dbconmy/premake5.lua index 0e7761c8dd5..026155de5bb 100644 --- a/Server/dbconmy/premake5.lua +++ b/Server/dbconmy/premake5.lua @@ -3,6 +3,7 @@ project "Dbconmy" kind "SharedLib" targetname "dbconmy" targetdir(buildpath("server/mods/deathmatch")) + clangtidy "On" filter "system:windows" includedirs { @@ -35,36 +36,42 @@ project "Dbconmy" filter "system:linux" includedirs { "/usr/include/mysql" } + libdirs { + -- RHEL/Fedora distributions put MySQL client libraries of their mysql-devel + -- package under a subdirectory not picked up by Premake's default library + -- search path + os.findlib("mysqlclient", { + "/usr/lib/mysql", + "/usr/lib64/mysql", + }) + } links { "rt" } filter "system:macosx" + -- brew install mysql-client libidn2 includedirs { os.findheader("mysql.h", { "/usr/local/opt/mysql/include/mysql", "/opt/homebrew/include/mysql", - "/opt/osxcross/macports/pkgs/opt/local/include/mysql8/mysql", + "/opt/homebrew/opt/mysql-client/include/mysql", }) } libdirs { os.findlib("libmysqlclient.a", { "/usr/local/opt/mysql/lib", "/opt/homebrew/lib", - "/opt/osxcross/macports/pkgs/opt/local/lib/mysql8/mysql", + "/opt/homebrew/opt/mysql-client/lib", }) } if GLIBC_COMPAT then filter { "system:linux" } buildoptions { "-pthread" } - linkoptions { "-l:libmysqlclient.a", "-pthread", "-lssl", "-lcrypto" } - links { "z", "dl", "m" } + linkoptions { "-pthread" } + links { "z", "dl", "m", "mysqlclient", "zstd", "ssl", "crypto", "resolv" } else filter "system:not windows" links { "mysqlclient" } - filter {"system:linux", "platforms:x86"} - libdirs { "/usr/lib32/mysql" } - filter {"system:linux", "platforms:x64"} - libdirs { "/usr/lib64/mysql" } end filter { "system:windows", "platforms:x64" } diff --git a/Server/launcher/CDynamicLibrary.cpp b/Server/launcher/CDynamicLibrary.cpp index a75d0919206..9e45a3b8ee3 100644 --- a/Server/launcher/CDynamicLibrary.cpp +++ b/Server/launcher/CDynamicLibrary.cpp @@ -32,10 +32,10 @@ bool CDynamicLibrary::Load(const char* szFilename) // Unload the previous library Unload(); - // Load the new library - #ifdef WIN32 +// Load the new library +#ifdef WIN32 m_hModule = LoadLibrary(szFilename); - #else +#else m_hModule = dlopen(szFilename, RTLD_NOW); // Output error if needed @@ -43,7 +43,7 @@ bool CDynamicLibrary::Load(const char* szFilename) { printf("%s\n", dlerror()); } - #endif +#endif // Return whether we succeeded or not return m_hModule != 0; @@ -54,11 +54,11 @@ void CDynamicLibrary::Unload() // Got a module? if (m_hModule != 0) { - #ifdef WIN32 +#ifdef WIN32 FreeLibrary(m_hModule); - #else +#else dlclose(m_hModule); - #endif +#endif // Zero out our library as it's no longer valid m_hModule = 0; @@ -75,9 +75,9 @@ void* CDynamicLibrary::GetProcedureAddress(const char* szProcName) // Got a module? if (m_hModule != 0) { - #ifdef WIN32 +#ifdef WIN32 return GetProcAddress(m_hModule, szProcName); - #else +#else char* szError = NULL; dlerror(); @@ -88,7 +88,7 @@ void* CDynamicLibrary::GetProcedureAddress(const char* szProcName) } return pFunc; - #endif +#endif } return NULL; diff --git a/Server/launcher/CDynamicLibrary.h b/Server/launcher/CDynamicLibrary.h index 32530629712..7549ec0e89a 100644 --- a/Server/launcher/CDynamicLibrary.h +++ b/Server/launcher/CDynamicLibrary.h @@ -12,9 +12,9 @@ #pragma once #ifdef WIN32 -#include + #include #else -#include + #include #endif class CDynamicLibrary @@ -30,9 +30,9 @@ class CDynamicLibrary void* GetProcedureAddress(const char* szProcName); private: - #ifdef WIN32 +#ifdef WIN32 HMODULE m_hModule; - #else +#else void* m_hModule; - #endif +#endif }; diff --git a/Server/launcher/Main.cpp b/Server/launcher/Main.cpp index 6ce037ec733..15695a286ea 100644 --- a/Server/launcher/Main.cpp +++ b/Server/launcher/Main.cpp @@ -113,14 +113,14 @@ int main(int argc, char* argv[]) FILE* fh = File::Fopen(LIB_CORE, "r"); if (!fh) { - #ifdef WIN32 +#ifdef WIN32 wchar_t szBuffer[64000]; GetModuleFileNameW(NULL, szBuffer, 64000); PathRemoveFileSpecW(szBuffer); SetCurrentDirectoryW(szBuffer); - #else +#else chdir(strLaunchDirectory); - #endif +#endif } else fclose(fh); @@ -131,7 +131,10 @@ int main(int argc, char* argv[]) { // Grab the entrypoint typedef int(Main_t)(int, char*[]); - Main_t* pfnEntryPoint = reinterpret_cast((long long)(Core.GetProcedureAddress("Run"))); + Main_t* pfnEntryPoint = nullptr; + const auto procAddr = Core.GetProcedureAddress("Run"); + static_assert(sizeof(pfnEntryPoint) == sizeof(procAddr), "Unexpected function pointer size"); + std::memcpy(&pfnEntryPoint, &procAddr, sizeof(pfnEntryPoint)); if (pfnEntryPoint) { // Call it and return what it returns diff --git a/Server/launcher/premake5.lua b/Server/launcher/premake5.lua index 3482a3c92b1..fa831edf667 100644 --- a/Server/launcher/premake5.lua +++ b/Server/launcher/premake5.lua @@ -3,6 +3,7 @@ project "Launcher" kind "ConsoleApp" targetdir(buildpath("server")) targetname "mta-server" + clangtidy "On" includedirs { "../../Shared/sdk", diff --git a/Server/launcher/resource.h b/Server/launcher/resource.h index a2ed40b8252..f3df8e2c143 100644 --- a/Server/launcher/resource.h +++ b/Server/launcher/resource.h @@ -2,15 +2,15 @@ // Microsoft Visual C++ generated include file. // Used by Server - Launcher.rc // -#define IDI_ICON1 110 +#define IDI_ICON1 110 // Next default values for new objects // #ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif + #ifndef APSTUDIO_READONLY_SYMBOLS + #define _APS_NEXT_RESOURCE_VALUE 101 + #define _APS_NEXT_COMMAND_VALUE 40001 + #define _APS_NEXT_CONTROL_VALUE 1001 + #define _APS_NEXT_SYMED_VALUE 101 + #endif #endif diff --git a/Server/mods/deathmatch/CServer.cpp b/Server/mods/deathmatch/CServer.cpp index 3db2a2d7f86..9f88916f45e 100644 --- a/Server/mods/deathmatch/CServer.cpp +++ b/Server/mods/deathmatch/CServer.cpp @@ -43,9 +43,9 @@ void CServer::ServerInitialize(CServerInterface* pServerInterface) g_pServerInterface = pServerInterface; g_pNetServer = pServerInterface->GetNetwork(); g_pRealNetServer = g_pNetServer; - #if defined(MTA_DEBUG) +#if defined(MTA_DEBUG) SharedUtil_Tests(); - #endif +#endif } bool CServer::ServerStartup(int iArgumentCount, char* szArguments[]) diff --git a/Server/mods/deathmatch/Config.h b/Server/mods/deathmatch/Config.h index 5a368934fc3..d857a680489 100644 --- a/Server/mods/deathmatch/Config.h +++ b/Server/mods/deathmatch/Config.h @@ -39,7 +39,7 @@ // Min and max number of characters in chat echos #define MIN_CHATECHO_LENGTH 1 -#define MAX_CHATECHO_LENGTH (MAX_CHAT_LENGTH + MAX_PLAYER_NICK_LENGTH + 2) // +2 is for ": " between player nick and the message +#define MAX_CHATECHO_LENGTH (MAX_CHAT_LENGTH + MAX_PLAYER_NICK_LENGTH + 2) // +2 is for ": " between player nick and the message // Min and max number of characters in outputChatBox from the server #define MIN_OUTPUTCHATBOX_LENGTH 1 @@ -89,41 +89,41 @@ #define GAME_TYPE_STRING "MTA:SA" // Banlist filename -#define FILENAME_BANLIST "banlist.xml" +#define FILENAME_BANLIST "banlist.xml" // Settings filename -#define FILENAME_SETTINGS "settings.xml" +#define FILENAME_SETTINGS "settings.xml" // Settings root-node -#define ROOTNODE_SETTINGS "settings" +#define ROOTNODE_SETTINGS "settings" // Settings prefixes and delimiters -#define SETTINGS_PREFIX_PRIVATE '@' // Private prefix -#define SETTINGS_PREFIX_PROTECTED '#' // Protected prefix -#define SETTINGS_PREFIX_PUBLIC '*' // Public prefix -#define SETTINGS_NO_PREFIX CSettings::Private // Access type when no prefix is used -#define SETTINGS_DELIMITER '.' // Delimiter +#define SETTINGS_PREFIX_PRIVATE '@' // Private prefix +#define SETTINGS_PREFIX_PROTECTED '#' // Protected prefix +#define SETTINGS_PREFIX_PUBLIC '*' // Public prefix +#define SETTINGS_NO_PREFIX CSettings::Private // Access type when no prefix is used +#define SETTINGS_DELIMITER '.' // Delimiter // Maximum length for names and values in settings registry -#define MAX_SETTINGS_LENGTH 256 +#define MAX_SETTINGS_LENGTH 256 // Maximum resource length -#define MAX_RESOURCE_LENGTH 64 +#define MAX_RESOURCE_LENGTH 64 // SQL variable placeholder (replaces with actual variable content) -#define SQL_VARIABLE_PLACEHOLDER '?' +#define SQL_VARIABLE_PLACEHOLDER '?' // Server FPS limit (in milliseconds) -#define FPS_LIMIT 16 +#define FPS_LIMIT 16 // Max garages -#define MAX_GARAGES 50 +#define MAX_GARAGES 50 // MTA master server query URL (Inputs: game port, ase port, http port, version, extra, serverip) #define QUERY_URL_MTA_MASTER_SERVER "https://master.multitheftauto.com/ase/add.php?g=%GAME%&a=%ASE%&h=%HTTP%&v=%VER%&x=%EXTRA%&ip=%IP%" // MTA port tester URL -#define PORT_TESTER_URL "https://nightly.multitheftauto.com/ports/" +#define PORT_TESTER_URL "https://nightly.multitheftauto.com/ports/" // MTA minclientversion auto update and others -#define HQCOMMS_URL "https://updatesa.multitheftauto.com/sa/server/hqcomms/" +#define HQCOMMS_URL "https://updatesa.multitheftauto.com/sa/server/hqcomms/" diff --git a/Server/mods/deathmatch/Server.cpp b/Server/mods/deathmatch/Server.cpp index 771c8e43671..246136bebce 100644 --- a/Server/mods/deathmatch/Server.cpp +++ b/Server/mods/deathmatch/Server.cpp @@ -42,7 +42,7 @@ MTAEXPORT void ReleaseServer(void) } } -#ifdef WIN32 /* Win32 DllMain entry */ +#ifdef WIN32 /* Win32 DllMain entry */ int WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, PVOID pvNothing) { diff --git a/Server/mods/deathmatch/StdInc.h b/Server/mods/deathmatch/StdInc.h index e326d53aa62..3f06363f4c5 100644 --- a/Server/mods/deathmatch/StdInc.h +++ b/Server/mods/deathmatch/StdInc.h @@ -27,6 +27,7 @@ #include "MTAPlatform.h" #ifdef WIN32 + #define _WINSOCK_DEPRECATED_NO_WARNINGS // // Windows // diff --git a/Server/mods/deathmatch/logic/ASE.cpp b/Server/mods/deathmatch/logic/ASE.cpp index 204e51a86d8..12d6b426532 100644 --- a/Server/mods/deathmatch/logic/ASE.cpp +++ b/Server/mods/deathmatch/logic/ASE.cpp @@ -16,15 +16,20 @@ #include "CPlayerManager.h" #include "CMainConfig.h" +#ifdef WIN32 + #include +#else + #include +#endif extern "C" { - #include "ASEQuerySDK.h" +#include "ASEQuerySDK.h" } ASE* ASE::_instance = NULL; ASE::ASE(CMainConfig* pMainConfig, CPlayerManager* pPlayerManager, unsigned short usPort, const SString& strServerIPList /*, bool bLan*/) - : m_QueryDosProtect(5, 6000, 7000) // Max of 5 queries per 6 seconds, then 7 second ignore + : m_QueryDosProtect(5, 6000, 7000) // Max of 5 queries per 6 seconds, then 7 second ignore { _instance = this; m_tStartTime = time(NULL); @@ -36,15 +41,15 @@ ASE::ASE(CMainConfig* pMainConfig, CPlayerManager* pPlayerManager, unsigned shor m_uiFullLastPlayerCount = 0; m_llFullLastTime = 0; - m_lFullMinInterval = 10 * 1000; // Update full query cache after 10 seconds + m_lFullMinInterval = 10 * 1000; // Update full query cache after 10 seconds m_uiLightLastPlayerCount = 0; m_llLightLastTime = 0; - m_lLightMinInterval = 10 * 1000; // Update light query cache after 10 seconds + m_lLightMinInterval = 10 * 1000; // Update light query cache after 10 seconds m_uiXfireLightLastPlayerCount = 0; m_llXfireLightLastTime = 0; - m_lXfireLightMinInterval = 10 * 1000; // Update XFire light query cache after 10 seconds + m_lXfireLightMinInterval = 10 * 1000; // Update XFire light query cache after 10 seconds m_ulMasterServerQueryCount = 0; m_uiNumQueriesTotal = 0; @@ -101,7 +106,15 @@ bool ASE::SetPortEnabled(bool bInternetEnabled, bool bLanEnabled) sockAddr.sin_family = AF_INET; sockAddr.sin_port = htons(m_usPort); if (!strIP.empty()) - sockAddr.sin_addr.s_addr = inet_addr(strIP); + { +#ifdef WIN32 + if (InetPtonA(AF_INET, strIP.c_str(), &sockAddr.sin_addr) != 1) + return false; +#else + if (inet_pton(AF_INET, strIP.c_str(), &sockAddr.sin_addr) != 1) + return false; +#endif + } else sockAddr.sin_addr.s_addr = INADDR_ANY; @@ -123,13 +136,13 @@ bool ASE::SetPortEnabled(bool bInternetEnabled, bool bLanEnabled) return false; } - // Set it to non blocking, so we dont have to wait for a packet - #ifdef WIN32 +// Set it to non blocking, so we dont have to wait for a packet +#ifdef WIN32 unsigned long ulNonBlock = 1; ioctlsocket(newSocket, FIONBIO, &ulNonBlock); - #else +#else fcntl(newSocket, F_SETFL, fcntl(newSocket, F_GETFL) | O_NONBLOCK); - #endif +#endif m_SocketList.push_back(newSocket); } @@ -152,7 +165,7 @@ void ASE::DoPulse() m_llCurrentTime = GetTickCount64_(); m_uiCurrentPlayerCount = m_pPlayerManager->Count(); - char szBuffer[100]; // Extra bytes for future use + char szBuffer[100]; // Extra bytes for future use for (uint s = 0; s < m_SocketList.size(); s++) { @@ -168,36 +181,47 @@ void ASE::DoPulse() m_uiNumQueriesTotal++; if (m_QueryDosProtect.GetTotalFloodingCount() < 100) - if (m_QueryDosProtect.AddConnect(inet_ntoa(SockAddr.sin_addr))) + { + char szAddr[INET_ADDRSTRLEN] = {}; +#ifdef WIN32 + if (!InetNtopA(AF_INET, &SockAddr.sin_addr, szAddr, sizeof(szAddr))) + continue; +#else + if (!inet_ntop(AF_INET, &SockAddr.sin_addr, szAddr, sizeof(szAddr))) continue; +#endif + + if (m_QueryDosProtect.AddConnect(szAddr)) + continue; + } const std::string* strReply = NULL; switch (szBuffer[0]) { case 's': - { // ASE protocol query + { // ASE protocol query m_ulMasterServerQueryCount++; strReply = QueryFullCached(); break; } case 'b': - { // Our own lighter query for ingame browser + { // Our own lighter query for ingame browser strReply = QueryLightCached(); break; } case 'r': - { // Our own lighter query for ingame browser - Release version only + { // Our own lighter query for ingame browser - Release version only strReply = QueryLightCached(); break; } case 'x': - { // Our own lighter query for xfire updates + { // Our own lighter query for xfire updates strReply = QueryXfireLightCached(); break; } case 'v': - { // MTA Version (For further possibilities to quick ping, in case we do multiply master servers) + { // MTA Version (For further possibilities to quick ping, in case we do multiply master servers) strReply = &m_strMtaAseVersion; break; } @@ -288,12 +312,12 @@ std::string ASE::QueryFull() // the flags that tell what data we carry per player ( apparently we need all set cause of GM atm ) unsigned char ucFlags = 0; - ucFlags |= 0x01; // nick - ucFlags |= 0x02; // team - ucFlags |= 0x04; // skin - ucFlags |= 0x08; // score - ucFlags |= 0x10; // ping - ucFlags |= 0x20; // time + ucFlags |= 0x01; // nick + ucFlags |= 0x02; // team + ucFlags |= 0x04; // skin + ucFlags |= 0x08; // score + ucFlags |= 0x10; // ping + ucFlags |= 0x20; // time char szTemp[256] = {'\0'}; CPlayer* pPlayer = NULL; diff --git a/Server/mods/deathmatch/logic/ASE.h b/Server/mods/deathmatch/logic/ASE.h index e6e0f041f81..556632ecec7 100644 --- a/Server/mods/deathmatch/logic/ASE.h +++ b/Server/mods/deathmatch/logic/ASE.h @@ -33,11 +33,11 @@ typedef int SOCKET; #include #include -#define MAX_ASE_GAME_TYPE_LENGTH 200 -#define MAX_ASE_MAP_NAME_LENGTH 200 -#define MAX_RULE_KEY_LENGTH 200 -#define MAX_RULE_VALUE_LENGTH 200 -#define MAX_ANNOUNCE_VALUE_LENGTH 200 +#define MAX_ASE_GAME_TYPE_LENGTH 200 +#define MAX_ASE_MAP_NAME_LENGTH 200 +#define MAX_RULE_KEY_LENGTH 200 +#define MAX_RULE_VALUE_LENGTH 200 +#define MAX_ANNOUNCE_VALUE_LENGTH 200 class CASERule; class CMainConfig; diff --git a/Server/mods/deathmatch/logic/CAccessControlListGroup.h b/Server/mods/deathmatch/logic/CAccessControlListGroup.h index 93997196726..e97776c3465 100644 --- a/Server/mods/deathmatch/logic/CAccessControlListGroup.h +++ b/Server/mods/deathmatch/logic/CAccessControlListGroup.h @@ -34,7 +34,7 @@ class CAccessControlListGroupObject m_eObjectType = eObjectType; } - virtual ~CAccessControlListGroupObject(){}; + virtual ~CAccessControlListGroupObject() {}; static SString GenerateKey(const char* szName, EObjectType eObjectType) { return SString("%s_%d", szName, (unsigned int)eObjectType); } diff --git a/Server/mods/deathmatch/logic/CAccessControlListRight.cpp b/Server/mods/deathmatch/logic/CAccessControlListRight.cpp index ea66e76ccb8..31d18f457ee 100644 --- a/Server/mods/deathmatch/logic/CAccessControlListRight.cpp +++ b/Server/mods/deathmatch/logic/CAccessControlListRight.cpp @@ -92,6 +92,6 @@ SString CAccessControlListRight::GetAttributeValue(const SString& strAttributeNa else { SString* pResult = MapFind(m_ExtraAttributeMap, strAttributeName); - return pResult ? *pResult : ""; + return pResult ? *pResult : SStringX(""); } } diff --git a/Server/mods/deathmatch/logic/CAccount.cpp b/Server/mods/deathmatch/logic/CAccount.cpp index e2e82f6ce8a..40b32ebf6ac 100644 --- a/Server/mods/deathmatch/logic/CAccount.cpp +++ b/Server/mods/deathmatch/logic/CAccount.cpp @@ -34,7 +34,7 @@ CAccount::CAccount(CAccountManager* pManager, EAccountType accountType, const st m_pManager->AddToList(this); if (m_Password.SetPassword(strPassword)) - m_pManager->MarkAsChanged(this); // Save if password upgraded + m_pManager->MarkAsChanged(this); // Save if password upgraded } CAccount::~CAccount() @@ -143,7 +143,7 @@ std::shared_ptr CAccount::GetData(const std::string& strKey) break; default: - dassert(0); // It never should hit this, if so, something corrupted + dassert(0); // It never should hit this, if so, something corrupted break; } } @@ -263,9 +263,12 @@ bool CAccount::IsValidSerial(const std::string& serial) const noexcept { const std::regex serialPattern("^[A-Fa-f0-9]{32}$"); - try{ + try + { return std::regex_match(serial, serialPattern); - } catch (...) { + } + catch (...) + { return false; } } diff --git a/Server/mods/deathmatch/logic/CAccount.h b/Server/mods/deathmatch/logic/CAccount.h index 24490e6b548..49892d11659 100644 --- a/Server/mods/deathmatch/logic/CAccount.h +++ b/Server/mods/deathmatch/logic/CAccount.h @@ -27,10 +27,10 @@ class CAccountPassword enum EAccountPasswordType { - NONE, // "" (empty string) possibly means 'not a password' + NONE, // "" (empty string) possibly means 'not a password' PLAINTEXT, - MD5, // pass stored as sha256(md5)+salt+type, stored as "1" - SHA256 // pass stored as sha256(plaintext)+salt+type, stored as "0" + MD5, // pass stored as sha256(md5)+salt+type, stored as "1" + SHA256 // pass stored as sha256(plaintext)+salt+type, stored as "0" }; protected: @@ -39,7 +39,7 @@ class CAccountPassword SString m_strSha256; SString m_strSalt; - SString m_strType; // can be "1", "0" or "" as shown in EAccountPasswordType + SString m_strType; // can be "1", "0" or "" as shown in EAccountPasswordType }; enum class EAccountType diff --git a/Server/mods/deathmatch/logic/CAccountManager.cpp b/Server/mods/deathmatch/logic/CAccountManager.cpp index cb64bce6962..3f3d39a3f0e 100644 --- a/Server/mods/deathmatch/logic/CAccountManager.cpp +++ b/Server/mods/deathmatch/logic/CAccountManager.cpp @@ -21,7 +21,7 @@ #include "CMapManager.h" CAccountManager::CAccountManager(const SString& strDbPathFilename) - : m_AccountProtect(6, 30000, 60000 * 1) // Max of 6 attempts per 30 seconds, then 1 minute ignore + : m_AccountProtect(6, 30000, 60000 * 1) // Max of 6 attempts per 30 seconds, then 1 minute ignore { m_llLastTimeSaved = GetTickCount64_(); m_bChangedSinceSaved = false; @@ -591,7 +591,7 @@ bool CAccountManager::LogIn(CClient* pClient, CClient* pEchoClient, const std::s CLuaArguments Arguments; Arguments.PushAccount(pCurrentAccount); Arguments.PushAccount(pAccount); - Arguments.PushBoolean(false); // was bAutoLogin + Arguments.PushBoolean(false); // was bAutoLogin if (!pPlayer->CallEvent("onPlayerLogin", Arguments)) { // DENIED! @@ -723,7 +723,7 @@ std::shared_ptr CAccountManager::GetAccountData(CAccount* pAccount break; default: - dassert(0); // It never should hit this, if so, something corrupted + dassert(0); // It never should hit this, if so, something corrupted break; } } @@ -777,14 +777,14 @@ bool CAccountManager::CopyAccountData(CAccount* pFromAccount, CAccount* pToAccou // list to store pFromAccount data to std::map copiedData; - if (!pFromAccount->IsRegistered()) // is not registered account, retrieve data from memory + if (!pFromAccount->IsRegistered()) // is not registered account, retrieve data from memory { for (const auto& iter : *pFromAccount) { MapSet(copiedData, iter.second.GetKey(), CAccountData(iter.second.GetKey(), iter.second.GetStrValue(), iter.second.GetType())); } } - else // is registered account, retrieve from database + else // is registered account, retrieve from database { SString strKey; SString strValue; @@ -813,17 +813,17 @@ bool CAccountManager::CopyAccountData(CAccount* pFromAccount, CAccount* pToAccou } } - if (copiedData.size() > 0) // got anything to copy? + if (copiedData.size() > 0) // got anything to copy? { std::map::iterator iter = copiedData.begin(); for (; iter != copiedData.end(); iter++) { - if (!pToAccount->IsRegistered()) // store to memory + if (!pToAccount->IsRegistered()) // store to memory { pToAccount->SetData(iter->second.GetKey(), iter->second.GetStrValue(), iter->second.GetType()); } - else // store to database + else // store to database { CRegistryResult subResult; @@ -1011,7 +1011,7 @@ CAccount* CAccountManager::AddConsoleAccount(const SString& strName) CAccount* CAccountManager::AddPlayerAccount(const SString& strName, const SString& strPassword, int iUserID, const SString& strIP, const SString& strSerial, const SString& strHttpPassAppend) { - CAccount* pAccount = new CAccount(this, EAccountType::Player, strName, strPassword, iUserID, strIP, strSerial, strHttpPassAppend); + CAccount* pAccount = new CAccount(this, EAccountType::Player, strName, strPassword, iUserID, strIP, strSerial, strHttpPassAppend); CLuaArguments Arguments; Arguments.PushAccount(pAccount); g_pGame->GetMapManager()->GetRootElement()->CallEvent("onAccountCreate", Arguments); @@ -1146,7 +1146,7 @@ bool CAccountManager::IsAuthorizedSerialRequired(CAccount* pAccount) bool CAccountManager::IsHttpLoginAllowed(CAccount* pAccount, const SString& strIp) { return !g_pGame->GetConfig()->GetAuthSerialHttpEnabled() || g_pGame->GetConfig()->IsAuthSerialHttpIpException(strIp) || - !IsAuthorizedSerialRequired(pAccount) || pAccount->IsIpAuthorized(strIp); + !IsAuthorizedSerialRequired(pAccount) || pAccount->IsIpAuthorized(strIp); } // diff --git a/Server/mods/deathmatch/logic/CAccountManager.h b/Server/mods/deathmatch/logic/CAccountManager.h index c3a0b72f281..bb9e7a89d01 100644 --- a/Server/mods/deathmatch/logic/CAccountManager.h +++ b/Server/mods/deathmatch/logic/CAccountManager.h @@ -21,10 +21,10 @@ class CDatabaseManager; typedef uint SDbConnectionId; -#define GUEST_ACCOUNT_NAME "guest" -#define HTTP_GUEST_ACCOUNT_NAME "http_guest" -#define CONSOLE_ACCOUNT_NAME "Console" -#define CONSOLE_NICK_NAME "Console" +#define GUEST_ACCOUNT_NAME "guest" +#define HTTP_GUEST_ACCOUNT_NAME "http_guest" +#define CONSOLE_ACCOUNT_NAME "Console" +#define CONSOLE_NICK_NAME "Console" // // CFastList with additional name->account mapping diff --git a/Server/mods/deathmatch/logic/CAccountPassword.cpp b/Server/mods/deathmatch/logic/CAccountPassword.cpp index c9b96e1cb42..01c166974ca 100644 --- a/Server/mods/deathmatch/logic/CAccountPassword.cpp +++ b/Server/mods/deathmatch/logic/CAccountPassword.cpp @@ -132,7 +132,6 @@ SString CAccountPassword::GenerateSalt() { char randomData[16]; g_pNetServer->GenerateRandomData(randomData, sizeof(randomData)); - randomData[8] = rand(); SString strSalt = ConvertDataToHexString(randomData, sizeof(randomData)); diff --git a/Server/mods/deathmatch/logic/CBan.h b/Server/mods/deathmatch/logic/CBan.h index 68ab44cbc73..624425ebf56 100644 --- a/Server/mods/deathmatch/logic/CBan.h +++ b/Server/mods/deathmatch/logic/CBan.h @@ -70,13 +70,6 @@ class CBan m_strSerial = strSerial; }; - const std::string& GetAccount() { return m_strAccount; }; - void SetAccount(const std::string& strAccount) - { - CBanManager::SetBansModified(); - m_strAccount = strAccount; - }; - time_t GetBanTimeRemaining(); SString GetDurationDesc(); SString GetReasonText() const; @@ -90,7 +83,6 @@ class CBan std::string m_strBanner; std::string m_strReason; std::string m_strSerial; - std::string m_strAccount; time_t m_tTimeOfBan; time_t m_tTimeOfUnban; uint m_uiScriptID; diff --git a/Server/mods/deathmatch/logic/CBanManager.cpp b/Server/mods/deathmatch/logic/CBanManager.cpp index de53eb5092e..6a6a760285e 100644 --- a/Server/mods/deathmatch/logic/CBanManager.cpp +++ b/Server/mods/deathmatch/logic/CBanManager.cpp @@ -141,34 +141,6 @@ CBan* CBanManager::AddSerialBan(const SString& strSerial, CClient* pBanner, cons return NULL; } -CBan* CBanManager::AddAccountBan(CPlayer* pPlayer, CClient* pBanner, const SString& strReason, time_t tTimeOfUnban) -{ - if (pPlayer) - { - if (!pPlayer->GetSerialUser().empty() && !IsAccountBanned(pPlayer->GetSerialUser().c_str())) - { - CBan* pBan = AddBan(pBanner->GetNick(), strReason, tTimeOfUnban); - pBan->SetNick(pPlayer->GetNick()); - pBan->SetAccount(pPlayer->GetSerialUser()); - return pBan; - } - } - - return NULL; -} - -CBan* CBanManager::AddAccountBan(const SString& strAccount, CClient* pBanner, const SString& strReason, time_t tTimeOfUnban) -{ - if (!IsAccountBanned(strAccount.c_str())) - { - CBan* pBan = AddBan(pBanner->GetNick(), strReason, tTimeOfUnban); - pBan->SetSerial(strAccount); - return pBan; - } - - return NULL; -} - CBan* CBanManager::AddBan(const SString& strBanner, const SString& strReason, time_t tTimeOfUnban) { // Create the ban and assign its values @@ -223,34 +195,6 @@ bool CBanManager::IsSerialBanned(const char* szSerial) return false; } -bool CBanManager::IsAccountBanned(const char* szAccount) -{ - list::const_iterator iter = m_BanManager.begin(); - for (; iter != m_BanManager.end(); iter++) - { - if ((*iter)->GetAccount() == szAccount) - { - return true; - } - } - - return false; -} - -CBan* CBanManager::GetBanFromAccount(const char* szAccount) -{ - list::const_iterator iter = m_BanManager.begin(); - for (; iter != m_BanManager.end(); iter++) - { - if ((*iter)->GetAccount() == szAccount) - { - return (*iter); - } - } - - return NULL; -} - void CBanManager::RemoveBan(CBan* pBan) { if (m_BanManager.Contains(pBan)) @@ -280,7 +224,7 @@ CBan* CBanManager::GetBanFromIP(const char* szIP) if (a == b) { if (a == 0) - return *iter; // Full match + return *iter; // Full match } else { @@ -294,7 +238,7 @@ CBan* CBanManager::GetBanFromIP(const char* szIP) } else if (strIP == szIP) { - return *iter; // Full match + return *iter; // Full match } } return pBanWildcardMatch; @@ -388,15 +332,14 @@ bool CBanManager::LoadBanList() { if (pNode->GetTagName().compare("ban") == 0) { - std::string strIP = SafeGetValue(pNode, "ip"), strSerial = SafeGetValue(pNode, "serial"), strAccount = SafeGetValue(pNode, "account"); - if (!strIP.empty() || !strSerial.empty() || !strAccount.empty()) + std::string strIP = SafeGetValue(pNode, "ip"), strSerial = SafeGetValue(pNode, "serial"); + if (!strIP.empty() || !strSerial.empty()) { CBan* pBan = AddBan(); if (IsValidIP(strIP.c_str())) { pBan->SetIP(strIP); } - pBan->SetAccount(strAccount); pBan->SetSerial(strSerial); pBan->SetBanner(SafeGetValue(pNode, "banner")); pBan->SetNick(SafeGetValue(pNode, "nick")); @@ -466,7 +409,6 @@ void CBanManager::SaveBanList() SafeSetValue(pNode, "nick", (*iter)->GetNick()); SafeSetValue(pNode, "ip", (*iter)->GetIP()); SafeSetValue(pNode, "serial", (*iter)->GetSerial()); - SafeSetValue(pNode, "account", (*iter)->GetAccount()); SafeSetValue(pNode, "banner", (*iter)->GetBanner()); SafeSetValue(pNode, "reason", (*iter)->GetReason()); SafeSetValue(pNode, "time", (unsigned int)(*iter)->GetTimeOfBan()); diff --git a/Server/mods/deathmatch/logic/CBanManager.h b/Server/mods/deathmatch/logic/CBanManager.h index e092a2fe9ad..63827d56f9d 100644 --- a/Server/mods/deathmatch/logic/CBanManager.h +++ b/Server/mods/deathmatch/logic/CBanManager.h @@ -28,18 +28,13 @@ class CBanManager CBan* AddSerialBan(CPlayer* pPlayer, CClient* pBanner = NULL, const SString& strReason = "", time_t tTimeOfUnban = 0); CBan* AddSerialBan(const SString& strSerial, CClient* pBanner = NULL, const SString& strReason = "", time_t tTimeOfUnban = 0); - CBan* AddAccountBan(CPlayer* pPlayer, CClient* pBanner = NULL, const SString& strReason = "", time_t tTimeOfUnban = 0); - CBan* AddAccountBan(const SString& szAccount, CClient* pBanner = NULL, const SString& strReason = "", time_t tTimeOfUnban = 0); - CBan* AddBan(const SString& strBanner = "Console", const SString& strReason = "", time_t tTimeOfUnban = 0); CBan* GetBanFromScriptID(uint uiScriptID); - bool IsSpecificallyBanned(const char* szIP); - bool IsSerialBanned(const char* szSerial); - bool IsAccountBanned(const char* szAccount); - CBan* GetBanFromAccount(const char* szAccount); - void RemoveBan(CBan* pBan); + bool IsSpecificallyBanned(const char* szIP); + bool IsSerialBanned(const char* szSerial); + void RemoveBan(CBan* pBan); CBan* GetBanFromSerial(const char* szSerial); CBan* GetBanFromIP(const char* szIP); diff --git a/Server/mods/deathmatch/logic/CBandwidthSettings.h b/Server/mods/deathmatch/logic/CBandwidthSettings.h index abfe7371a6d..1479402bc14 100644 --- a/Server/mods/deathmatch/logic/CBandwidthSettings.h +++ b/Server/mods/deathmatch/logic/CBandwidthSettings.h @@ -12,10 +12,10 @@ enum { - ZONE0, // Near sync - ZONE1, // Mid sync + out of fov - ZONE2, // Mid sync + way out of fov - ZONE3, // Far sync + ZONE0, // Near sync + ZONE1, // Mid sync + out of fov + ZONE2, // Mid sync + way out of fov + ZONE3, // Far sync ZONE_MAX }; @@ -95,17 +95,17 @@ struct CBandwidthSettings float fZone1Dot; float fZone2Dot; float fZone0RadiusSq; - SFixedArray ZoneUpdateIntervals; // First is always 0, next is Zone1 interval then Zone2 and Zone3 + SFixedArray ZoneUpdateIntervals; // First is always 0, next is Zone1 interval then Zone2 and Zone3 int iMaxZoneIfOtherCanSee; bool bLightSyncEnabled; protected: - float fZone0Radius; // 10 - 200 Use zone1&2 only if other player is at least this distance away - float fZone1Angle; // 90 - 350 Use zone1 if angle to other player is greater than this - float fZone2Angle; // 100 - 360 Use zone2 if angle to other player is greater than this - int iMaxZoneIfOtherCanSeeNormal; // Zone limit if other player can see us - int iMaxZoneIfOtherCanSeeBulletSync; // Zone limit if other player can see us when bullet sync is enabled - bool bBulletSyncEnabled; // Cache flag set by game + float fZone0Radius; // 10 - 200 Use zone1&2 only if other player is at least this distance away + float fZone1Angle; // 90 - 350 Use zone1 if angle to other player is greater than this + float fZone2Angle; // 100 - 360 Use zone2 if angle to other player is greater than this + int iMaxZoneIfOtherCanSeeNormal; // Zone limit if other player can see us + int iMaxZoneIfOtherCanSeeBulletSync; // Zone limit if other player can see us when bullet sync is enabled + bool bBulletSyncEnabled; // Cache flag set by game }; extern CBandwidthSettings* g_pBandwidthSettings; diff --git a/Server/mods/deathmatch/logic/CBuilding.cpp b/Server/mods/deathmatch/logic/CBuilding.cpp index 72afed4f39f..d9001e79bdb 100644 --- a/Server/mods/deathmatch/logic/CBuilding.cpp +++ b/Server/mods/deathmatch/logic/CBuilding.cpp @@ -21,7 +21,7 @@ CBuilding::CBuilding(CElement* pParent, CBuildingManager* pBuildingManager) : CE { // Init m_iType = CElement::BUILDING; - SetTypeName("buidling"); + SetTypeName("building"); m_pBuildingManager = pBuildingManager; m_model = 0xFFFF; @@ -38,7 +38,7 @@ CBuilding::CBuilding(const CBuilding& Copy) : CElement(Copy.m_pParent), m_pLowLo { // Init m_iType = CElement::BUILDING; - SetTypeName("buidling"); + SetTypeName("building"); m_pBuildingManager = Copy.m_pBuildingManager; m_model = Copy.m_model; @@ -209,4 +209,3 @@ bool CBuilding::SetLowLodBuilding(CBuilding* pNewLowLodBuilding) noexcept return true; } } - diff --git a/Server/mods/deathmatch/logic/CBuilding.h b/Server/mods/deathmatch/logic/CBuilding.h index 5ffeb1af12b..8dc89f8410c 100644 --- a/Server/mods/deathmatch/logic/CBuilding.h +++ b/Server/mods/deathmatch/logic/CBuilding.h @@ -19,8 +19,6 @@ class CBuildingManager; -#define SERVERSIDE_BUILDING_MIN_CLIENT_VERSION "1.6.0-9.22824" - class CBuilding final : public CElement { friend class CPlayer; diff --git a/Server/mods/deathmatch/logic/CCameraSpatialDatabase.cpp b/Server/mods/deathmatch/logic/CCameraSpatialDatabase.cpp index f28e8dd6ba6..33c951467d8 100644 --- a/Server/mods/deathmatch/logic/CCameraSpatialDatabase.cpp +++ b/Server/mods/deathmatch/logic/CCameraSpatialDatabase.cpp @@ -25,7 +25,7 @@ namespace { CBox box; }; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -214,7 +214,7 @@ bool CCameraSpatialDatabaseImpl::IsValidSphere(const CSphere& sphere) return false; // Check radius within limits - if (sphere.fRadius < -12000 || sphere.fRadius > 12000) // radius = sqrt(worldlimits*worldlimits + worldlimits*worldlimits) + if (sphere.fRadius < -12000 || sphere.fRadius > 12000) // radius = sqrt(worldlimits*worldlimits + worldlimits*worldlimits) return false; // Check position within limits diff --git a/Server/mods/deathmatch/logic/CCameraSpatialDatabase.h b/Server/mods/deathmatch/logic/CCameraSpatialDatabase.h index bdbf2e0a5e3..687898e3f48 100644 --- a/Server/mods/deathmatch/logic/CCameraSpatialDatabase.h +++ b/Server/mods/deathmatch/logic/CCameraSpatialDatabase.h @@ -11,7 +11,7 @@ class CPlayerCamera; // Bounding sphere z position for 2d objects -#define SPATIAL_2D_Z 0 +#define SPATIAL_2D_Z 0 // Result of a Query class CCameraQueryResult : public std::vector diff --git a/Server/mods/deathmatch/logic/CColCircle.cpp b/Server/mods/deathmatch/logic/CColCircle.cpp index 60f661ba673..ed4948af466 100644 --- a/Server/mods/deathmatch/logic/CColCircle.cpp +++ b/Server/mods/deathmatch/logic/CColCircle.cpp @@ -35,7 +35,7 @@ CElement* CColCircle::Clone(bool* bAddEntity, CResource* pResource) bool CColCircle::DoHitDetection(const CVector& vecNowPosition) { // Do a simple distance check between now position and our position - return IsPointNearPoint2D(vecNowPosition, m_vecPosition, m_fRadius); + return IsPointNearPoint2D(vecNowPosition, GetPosition(), m_fRadius); } bool CColCircle::ReadSpecialData(const int iLine) diff --git a/Server/mods/deathmatch/logic/CColCuboid.cpp b/Server/mods/deathmatch/logic/CColCuboid.cpp index d99756039f6..74113e11e98 100644 --- a/Server/mods/deathmatch/logic/CColCuboid.cpp +++ b/Server/mods/deathmatch/logic/CColCuboid.cpp @@ -31,9 +31,9 @@ bool CColCuboid::DoHitDetection(const CVector& vecNowPosition) // FIXME: What about radius? // See if the now position is within our cube - return (vecNowPosition.fX >= m_vecPosition.fX && vecNowPosition.fX <= m_vecPosition.fX + m_vecSize.fX && vecNowPosition.fY >= m_vecPosition.fY && - vecNowPosition.fY <= m_vecPosition.fY + m_vecSize.fY && vecNowPosition.fZ >= m_vecPosition.fZ && - vecNowPosition.fZ <= m_vecPosition.fZ + m_vecSize.fZ); + const CVector& vecPosition = GetPosition(); + return (vecNowPosition.fX >= vecPosition.fX && vecNowPosition.fX <= vecPosition.fX + m_vecSize.fX && vecNowPosition.fY >= vecPosition.fY && + vecNowPosition.fY <= vecPosition.fY + m_vecSize.fY && vecNowPosition.fZ >= vecPosition.fZ && vecNowPosition.fZ <= vecPosition.fZ + m_vecSize.fZ); } bool CColCuboid::ReadSpecialData(const int iLine) diff --git a/Server/mods/deathmatch/logic/CColPolygon.cpp b/Server/mods/deathmatch/logic/CColPolygon.cpp index 5149f486863..fbe949fac74 100644 --- a/Server/mods/deathmatch/logic/CColPolygon.cpp +++ b/Server/mods/deathmatch/logic/CColPolygon.cpp @@ -160,8 +160,9 @@ void CColPolygon::CalculateRadius(const CVector2D& vecPoint) bool CColPolygon::IsInBounds(CVector vecPoint) { - float fDistanceX = vecPoint.fX - m_vecPosition.fX; - float fDistanceY = vecPoint.fY - m_vecPosition.fY; + const CVector& vecPosition = GetPosition(); + float fDistanceX = vecPoint.fX - vecPosition.fX; + float fDistanceY = vecPoint.fY - vecPosition.fY; float fDist = sqrt(fDistanceX * fDistanceX + fDistanceY * fDistanceY); diff --git a/Server/mods/deathmatch/logic/CColRectangle.cpp b/Server/mods/deathmatch/logic/CColRectangle.cpp index b5b596d0f03..3e6dcfcaee2 100644 --- a/Server/mods/deathmatch/logic/CColRectangle.cpp +++ b/Server/mods/deathmatch/logic/CColRectangle.cpp @@ -34,8 +34,9 @@ bool CColRectangle::DoHitDetection(const CVector& vecNowPosition) // FIXME: What about radius? // See if the now position is within our cube - return (vecNowPosition.fX >= m_vecPosition.fX && vecNowPosition.fX <= m_vecPosition.fX + m_vecSize.fX && vecNowPosition.fY >= m_vecPosition.fY && - vecNowPosition.fY <= m_vecPosition.fY + m_vecSize.fY); + const CVector& vecPosition = GetPosition(); + return (vecNowPosition.fX >= vecPosition.fX && vecNowPosition.fX <= vecPosition.fX + m_vecSize.fX && vecNowPosition.fY >= vecPosition.fY && + vecNowPosition.fY <= vecPosition.fY + m_vecSize.fY); } bool CColRectangle::ReadSpecialData(const int iLine) diff --git a/Server/mods/deathmatch/logic/CColSphere.cpp b/Server/mods/deathmatch/logic/CColSphere.cpp index 5f177fbb5b0..331d7cb06f5 100644 --- a/Server/mods/deathmatch/logic/CColSphere.cpp +++ b/Server/mods/deathmatch/logic/CColSphere.cpp @@ -30,7 +30,7 @@ CElement* CColSphere::Clone(bool* bAddEntity, CResource* pResource) bool CColSphere::DoHitDetection(const CVector& vecNowPosition) { // Do a simple distance check between now position and our position - return IsPointNearPoint3D(vecNowPosition, m_vecPosition, m_fRadius); + return IsPointNearPoint3D(vecNowPosition, GetPosition(), m_fRadius); } bool CColSphere::ReadSpecialData(const int iLine) diff --git a/Server/mods/deathmatch/logic/CColTube.cpp b/Server/mods/deathmatch/logic/CColTube.cpp index 6466966e988..26c39066171 100644 --- a/Server/mods/deathmatch/logic/CColTube.cpp +++ b/Server/mods/deathmatch/logic/CColTube.cpp @@ -32,8 +32,9 @@ bool CColTube::DoHitDetection(const CVector& vecNowPosition) // FIXME: What about radius in height? // First see if we're within the circle. Then see if we're within its height - return (IsPointNearPoint2D(vecNowPosition, m_vecPosition, m_fRadius) && vecNowPosition.fZ >= m_vecPosition.fZ && - vecNowPosition.fZ <= m_vecPosition.fZ + m_fHeight); + const CVector& vecPosition = GetPosition(); + return (IsPointNearPoint2D(vecNowPosition, vecPosition, m_fRadius) && vecNowPosition.fZ >= vecPosition.fZ && + vecNowPosition.fZ <= vecPosition.fZ + m_fHeight); } bool CColTube::ReadSpecialData(const int iLine) diff --git a/Server/mods/deathmatch/logic/CColTube.h b/Server/mods/deathmatch/logic/CColTube.h index 8788de03726..c0dd337faf4 100644 --- a/Server/mods/deathmatch/logic/CColTube.h +++ b/Server/mods/deathmatch/logic/CColTube.h @@ -27,7 +27,7 @@ class CColTube : public CColShape float GetRadius() { return m_fRadius; }; void SetRadius(float fRadius) { - m_fRadius = fRadius; + m_fRadius = (fRadius / 2.0f) + 0.15f; SizeChanged(); }; float GetHeight() { return m_fHeight; }; diff --git a/Server/mods/deathmatch/logic/CCommon.h b/Server/mods/deathmatch/logic/CCommon.h index 4b6d823ad4a..41e379d6018 100644 --- a/Server/mods/deathmatch/logic/CCommon.h +++ b/Server/mods/deathmatch/logic/CCommon.h @@ -25,7 +25,7 @@ extern CServerInterface* g_pServerInterface; extern CNetServer* g_pNetServer; #define REMOTE_ADMIN_ID 254 -#define CONSOLE_ID 255 +#define CONSOLE_ID 255 #define MAX_HTTP_DOWNLOAD_URL 512 @@ -558,27 +558,27 @@ enum eWeaponProperty WEAPON_DEFAULT_COMBO, WEAPON_COMBOS_AVAILABLE, - WEAPON_FLAG_AIM_NO_AUTO, // 0x000001 - cant auto target to aim (disable automatic up/down adjustment when firing without aiming) + WEAPON_FLAG_AIM_NO_AUTO, // 0x000001 - cant auto target to aim (disable automatic up/down adjustment when firing without aiming) WEAPON_FLAG_FIRST = WEAPON_FLAG_AIM_NO_AUTO, - WEAPON_FLAG_AIM_ARM, // 0x000002 - only needs arm to aim (ie pistol/shotgun/tec9/uzi) - WEAPON_FLAG_AIM_1ST_PERSON, // 0x000004 - uses 1st person aim (ie sniper/rpg-hs - WEAPON_FLAG_AIM_FREE, // 0x000008 - can only use free aiming (ie country sniper/flame thrower/minigun/fire extinguisher) - WEAPON_FLAG_MOVE_AND_AIM, // 0x000010 - can move and aim at same time - WEAPON_FLAG_MOVE_AND_SHOOT, // 0x000020 - can move and fire at same time + WEAPON_FLAG_AIM_ARM, // 0x000002 - only needs arm to aim (ie pistol/shotgun/tec9/uzi) + WEAPON_FLAG_AIM_1ST_PERSON, // 0x000004 - uses 1st person aim (ie sniper/rpg-hs + WEAPON_FLAG_AIM_FREE, // 0x000008 - can only use free aiming (ie country sniper/flame thrower/minigun/fire extinguisher) + WEAPON_FLAG_MOVE_AND_AIM, // 0x000010 - can move and aim at same time + WEAPON_FLAG_MOVE_AND_SHOOT, // 0x000020 - can move and fire at same time WEAPON_FLAG_UNKNOWN_0040, WEAPON_FLAG_UNKNOWN_0080, - WEAPON_FLAG_TYPE_THROW, // 0x000100 - is a throwing weapon (ie satchel) - WEAPON_FLAG_TYPE_HEAVY, // 0x000200 - heavy weapon - can't jump (ie flame thrower/rpgs/minigun) - WEAPON_FLAG_TYPE_CONSTANT, // 0x000400 - fires every frame within loop (ie paint spray) - WEAPON_FLAG_TYPE_DUAL, // 0x000800 - can use 2x guns at same time (ie pistol/shotgun/tec9/uzi) - WEAPON_FLAG_ANIM_RELOAD, // 0x001000 - weapon has reload anims (ie everything except shotgun/snipers/flame thrower/rpgs/minigun/satchel) - WEAPON_FLAG_ANIM_CROUCH, // 0x002000 - weapon has crouching anims (ie everything except flame thrower/rpgs/minigun/satchel) - WEAPON_FLAG_ANIM_RELOAD_LOOP, // 0x004000 - loop from end of reload to fire loop start - WEAPON_FLAG_ANIM_RELOAD_LONG, // 0x008000 - force a longer reload time! (ie rpgs/snipers) - WEAPON_FLAG_SHOT_SLOWS, // 0x010000 - slows down (ie flame thrower) - WEAPON_FLAG_SHOT_RAND_SPEED, // 0x020000 - random speed (ie flame thrower) - WEAPON_FLAG_SHOT_ANIM_ABRUPT, // 0x040000 - force the anim to finish player after aim/fire rather than blending out (ie rpgs) - WEAPON_FLAG_SHOT_EXPANDS, // 0x080000 - expands + WEAPON_FLAG_TYPE_THROW, // 0x000100 - is a throwing weapon (ie satchel) + WEAPON_FLAG_TYPE_HEAVY, // 0x000200 - heavy weapon - can't jump (ie flame thrower/rpgs/minigun) + WEAPON_FLAG_TYPE_CONSTANT, // 0x000400 - fires every frame within loop (ie paint spray) + WEAPON_FLAG_TYPE_DUAL, // 0x000800 - can use 2x guns at same time (ie pistol/shotgun/tec9/uzi) + WEAPON_FLAG_ANIM_RELOAD, // 0x001000 - weapon has reload anims (ie everything except shotgun/snipers/flame thrower/rpgs/minigun/satchel) + WEAPON_FLAG_ANIM_CROUCH, // 0x002000 - weapon has crouching anims (ie everything except flame thrower/rpgs/minigun/satchel) + WEAPON_FLAG_ANIM_RELOAD_LOOP, // 0x004000 - loop from end of reload to fire loop start + WEAPON_FLAG_ANIM_RELOAD_LONG, // 0x008000 - force a longer reload time! (ie rpgs/snipers) + WEAPON_FLAG_SHOT_SLOWS, // 0x010000 - slows down (ie flame thrower) + WEAPON_FLAG_SHOT_RAND_SPEED, // 0x020000 - random speed (ie flame thrower) + WEAPON_FLAG_SHOT_ANIM_ABRUPT, // 0x040000 - force the anim to finish player after aim/fire rather than blending out (ie rpgs) + WEAPON_FLAG_SHOT_EXPANDS, // 0x080000 - expands WEAPON_FLAG_LAST = WEAPON_FLAG_SHOT_EXPANDS, }; @@ -587,7 +587,7 @@ enum eWeaponSkill WEAPONSKILL_POOR = 0, WEAPONSKILL_STD, WEAPONSKILL_PRO, - WEAPONSKILL_SPECIAL, // for cops using pistols differently for example + WEAPONSKILL_SPECIAL, // for cops using pistols differently for example WEAPONSKILL_MAX_NUMBER }; @@ -625,7 +625,7 @@ enum eWeaponType WEAPONTYPE_CHAINSAW, // gifts - WEAPONTYPE_DILDO1, // 10 + WEAPONTYPE_DILDO1, // 10 WEAPONTYPE_DILDO2, WEAPONTYPE_VIBE1, WEAPONTYPE_VIBE2, @@ -636,31 +636,31 @@ enum eWeaponType WEAPONTYPE_TEARGAS, WEAPONTYPE_MOLOTOV, WEAPONTYPE_ROCKET, - WEAPONTYPE_ROCKET_HS, // 20 + WEAPONTYPE_ROCKET_HS, // 20 WEAPONTYPE_FREEFALL_BOMB, // FIRST SKILL WEAPON - WEAPONTYPE_PISTOL, // handguns + WEAPONTYPE_PISTOL, // handguns WEAPONTYPE_PISTOL_SILENCED, WEAPONTYPE_DESERT_EAGLE, - WEAPONTYPE_SHOTGUN, // shotguns - WEAPONTYPE_SAWNOFF_SHOTGUN, // one handed + WEAPONTYPE_SHOTGUN, // shotguns + WEAPONTYPE_SAWNOFF_SHOTGUN, // one handed WEAPONTYPE_SPAS12_SHOTGUN, - WEAPONTYPE_MICRO_UZI, // submachine guns + WEAPONTYPE_MICRO_UZI, // submachine guns WEAPONTYPE_MP5, - WEAPONTYPE_AK47, // 30 // machine guns + WEAPONTYPE_AK47, // 30 // machine guns WEAPONTYPE_M4, - WEAPONTYPE_TEC9, // this uses stat from the micro_uzi + WEAPONTYPE_TEC9, // this uses stat from the micro_uzi // END SKILL WEAPONS - WEAPONTYPE_COUNTRYRIFLE, // rifles + WEAPONTYPE_COUNTRYRIFLE, // rifles WEAPONTYPE_SNIPERRIFLE, - WEAPONTYPE_ROCKETLAUNCHER, // specials + WEAPONTYPE_ROCKETLAUNCHER, // specials WEAPONTYPE_ROCKETLAUNCHER_HS, WEAPONTYPE_FLAMETHROWER, WEAPONTYPE_MINIGUN, WEAPONTYPE_REMOTE_SATCHEL_CHARGE, - WEAPONTYPE_DETONATOR, // 40 // plastic explosive + WEAPONTYPE_DETONATOR, // 40 // plastic explosive WEAPONTYPE_SPRAYCAN, WEAPONTYPE_EXTINGUISHER, WEAPONTYPE_CAMERA, @@ -672,12 +672,12 @@ enum eWeaponType WEAPONTYPE_ARMOUR, // these are possible ways to die WEAPONTYPE_RAMMEDBYCAR, - WEAPONTYPE_RUNOVERBYCAR, // 50 + WEAPONTYPE_RUNOVERBYCAR, // 50 WEAPONTYPE_EXPLOSION, WEAPONTYPE_UZI_DRIVEBY, WEAPONTYPE_DROWNING, WEAPONTYPE_FALL, - WEAPONTYPE_UNIDENTIFIED, // Used for damage being done + WEAPONTYPE_UNIDENTIFIED, // Used for damage being done WEAPONTYPE_ANYMELEE, WEAPONTYPE_ANYWEAPON, WEAPONTYPE_FLARE, @@ -691,15 +691,15 @@ enum eWeaponSlot WEAPONSLOT_TYPE_MELEE, WEAPONSLOT_TYPE_HANDGUN, WEAPONSLOT_TYPE_SHOTGUN, - WEAPONSLOT_TYPE_SMG, // 4 + WEAPONSLOT_TYPE_SMG, // 4 WEAPONSLOT_TYPE_MG, WEAPONSLOT_TYPE_RIFLE, WEAPONSLOT_TYPE_HEAVY, WEAPONSLOT_TYPE_THROWN, - WEAPONSLOT_TYPE_SPECIAL, // 9 - WEAPONSLOT_TYPE_GIFT, // 10 - WEAPONSLOT_TYPE_PARACHUTE, // 11 - WEAPONSLOT_TYPE_DETONATOR, // 12 + WEAPONSLOT_TYPE_SPECIAL, // 9 + WEAPONSLOT_TYPE_GIFT, // 10 + WEAPONSLOT_TYPE_PARACHUTE, // 11 + WEAPONSLOT_TYPE_DETONATOR, // 12 WEAPONSLOT_MAX }; @@ -758,6 +758,316 @@ enum eWeaponFlags WEAPONFLAGS_INSTANT_RELOAD, }; +enum eStats +{ + STAT_PROGRESS_MADE = 0, + STAT_TOTAL_PROGRESS = 1, + STAT_FURTHEST_HOOP = 2, + STAT_DISTANCE_TRAVELLED_ON_FOOT = 3, + STAT_DISTANCE_TRAVELLED_BY_CAR = 4, + STAT_DISTANCE_TRAVELLED_BY_MOTORBIKE = 5, + STAT_DISTANCE_TRAVELLED_BY_BOAT = 6, + STAT_DISTANCE_TRAVELLED_BY_GOLF_CART = 7, + STAT_DISTANCE_TRAVELLED_BY_HELICOPTER = 8, + STAT_DISTANCE_TRAVELLED_BY_PLANE = 9, + STAT_LONGEST_WHEELIE_DISTANCE = 10, + STAT_LONGEST_STOPPIE_DISTANCE = 11, + STAT_LONGEST_2_WHEELS_DISTANCE = 12, + STAT_WEAPON_BUDGET = 13, + STAT_FASHION_BUDGET = 14, + STAT_PROPERTY_BUDGET = 15, + STAT_AUTO_REPAIR_AND_PAINTING_BUDGET = 16, + STAT_LONGEST_WHEELIE_TIME = 17, + STAT_LONGEST_STOPPIE_TIME = 18, + STAT_LONGEST_2_WHEELS_TIME = 19, + STAT_FOOD_BUDGET = 20, + STAT_FAT = 21, + STAT_STAMINA = 22, + STAT_MUSCLE = 23, + STAT_MAX_HEALTH = 24, + STAT_SEX_APPEAL = 25, + STAT_DISTANCE_TRAVELLED_BY_SWIMMING = 26, + STAT_DISTANCE_TRAVELLED_BY_BICYCLE = 27, + STAT_DISTANCE_TRAVELLED_ON_TREADMILL = 28, + STAT_DISTANCE_TRAVELLED_ON_EXERCISE_BIKE = 29, + STAT_TATTOO_BUDGET = 30, + STAT_HAIRDRESSING_BUDGET = 31, + STAT_GIRLFRIEND_BUDGET = 32, + STAT_PROSTITUTE_BUDGET = 33, + STAT_FURNITURE_BUDGET = 34, + STAT_MONEY_SPENT_GAMBLING = 35, + STAT_MONEY_MADE_FROM_PIMPING = 36, + STAT_MONEY_WON_GAMBLING = 37, + STAT_BIGGEST_GAMBLING_WIN = 38, + STAT_BIGGEST_GAMBLING_LOSS = 39, + STAT_LARGEST_BURGLARY_SWAG = 40, + STAT_MONEY_MADE_FROM_BURGLARY = 41, + STAT_MONEY_SPENT_BUILDING_PROPERTY = 42, + STAT_UNUSED = 43, + STAT_LONGEST_TREADMILL_TIME = 44, + STAT_LONGEST_EXERCISE_BIKE_TIME = 45, + STAT_HEAVIEST_WEIGHT_ON_BENCH_PRESS = 46, + STAT_HEAVIEST_WEIGHT_ON_DUMBBELLS = 47, + STAT_BEST_TIME_IN_8_TRACK = 48, + STAT_BMX_BEST_TIME = 49, + STAT_LIGHTEST_WEIGHT = 50, + STAT_LONGEST_CHASE_TIME_WITH_5_OR_MORE_STARS = 51, + STAT_LAST_CHASE_TIME_WITH_5_OR_MORE_STARS = 52, + STAT_WAGE_BILL = 53, + STAT_STRIP_CLUB_BUDGET = 54, + STAT_CAR_MODIFICATION_BUDGET = 55, + STAT_TIME_SPENT_SHOPPING = 56, + STAT_TIME_SPENT_GAMBLING = 57, + STAT_TIME_SPENT_ON_LONGEST_MISSION = 58, + STAT_TIME_SPENT_ON_QUICKEST_MISSION = 59, + STAT_AVERAGE_MISSION_TIME = 60, + STAT_DRUGS_BUDGET = 61, + STAT_TOTAL_SHOPPING_BUDGET = 62, + STAT_TIME_SPENT_UNDERWATER = 63, + STAT_TOTAL_RESPECT = 64, + STAT_GIRLFRIEND_RESPECT = 65, + STAT_CLOTHES_RESPECT = 66, + STAT_FITNESS_RESPECT = 67, + STAT_RESPECT = 68, + STAT_PISTOL_SKILL = 69, + STAT_SILENCED_PISTOL_SKILL = 70, + STAT_DESERT_EAGLE_SKILL = 71, + STAT_SHOTGUN_SKILL = 72, + STAT_SAWN_OFF_SHOTGUN_SKILL = 73, + STAT_COMBAT_SHOTGUN_SKILL = 74, + STAT_MACHINE_PISTOL_SKILL = 75, + STAT_SMG_SKILL = 76, + STAT_AK_47_SKILL = 77, + STAT_M4_SKILL = 78, + STAT_RIFLE_SKILL = 79, + STAT_APPEARANCE = 80, + STAT_GAMBLING = 81, + + STAT_PEOPLE_WASTED_BY_OTHERS = 120, + STAT_PEOPLE_YOUVE_WASTED = 121, + STAT_ROAD_VEHICLES_DESTROYED = 122, + STAT_BOATS_DESTROYED = 123, + STAT_PLANES_HELICOPTERS_DESTROYED = 124, + STAT_COST_OF_PROPERTY_DAMAGED = 125, + STAT_BULLETS_FIRED = 126, + STAT_KGS_OF_EXPLOSIVES_USED = 127, + STAT_BULLETS_THAT_HIT = 128, + STAT_TIRES_POPPED_WITH_GUNFIRE = 129, + STAT_NUMBER_OF_HEADSHOTS = 130, + STAT_TOTAL_NUMBER_OF_WANTED_STARS_ATTAINED = 131, + STAT_TOTAL_NUMBER_OF_WANTED_STARS_EVADED = 132, + STAT_TIMES_BUSTED = 133, + STAT_DAYS_PASSED_IN_GAME = 134, + STAT_NUMBER_OF_HOSPITAL_VISITS = 135, + STAT_SAFEHOUSE_VISITS = 136, + STAT_TIMES_CHEATED = 137, + STAT_VEHICLE_RESPRAYS = 138, + STAT_MAXIMUM_INSANE_JUMP_DISTANCE = 139, + STAT_MAXIMUM_INSANE_JUMP_HEIGHT = 140, + STAT_MAXIMUM_INSANE_JUMP_FLIPS = 141, + STAT_MAXIMUM_INSANE_JUMP_ROTATION = 142, + STAT_BEST_INSANE_STUNT_AWARDED = 143, + STAT_UNIQUE_JUMPS_FOUND = 144, + STAT_UNIQUE_JUMPS_DONE = 145, + STAT_MISSION_ATTEMPTS = 146, + STAT_MISSIONS_PASSED = 147, + STAT_TOTAL_NUMBER_OF_MISSIONS_IN_GAME = 148, + STAT_CASH_MADE_IN_A_TAXI = 149, + STAT_PASSENGERS_DROPPED_OFF = 150, + STAT_PEOPLE_SAVED_IN_AN_AMBULANCE = 151, + STAT_CRIMINALS_KILLED_ON_VIGILANTE_MISSION = 152, + STAT_TOTAL_FIRES_EXTINGUISHED = 153, + STAT_PACKAGES_DELIVERED = 154, + STAT_ASSASSINATIONS = 155, + STAT_LAST_DANCE_SCORE = 156, + STAT_HIGHEST_VIGILANTE_MISSION_LEVEL = 157, + STAT_HIGHEST_PARAMEDIC_MISSION_LEVEL = 158, + STAT_HIGHEST_FIREFIGHTER_MISSION_LEVEL = 159, + STAT_DRIVING_SKILL = 160, + STAT_NUMBER_OF_TRUCK_MISSIONS_PASSED = 161, + STAT_MONEY_MADE_IN_TRUCK = 162, + STAT_RECRUITED_GANG_MEMBERS_KILLED = 163, + STAT_ARMOR = 164, + STAT_ENERGY = 165, + STAT_PHOTOGRAPHS_TAKEN = 166, + STAT_RAMPAGES_ATTEMPTED = 167, + STAT_RAMPAGES_PASSED = 168, + STAT_FLIGHT_TIME = 169, + STAT_TIMES_DROWNED = 170, + STAT_NUMBER_OF_GIRLS_PIMPED = 171, + STAT_BEST_POSITION_IN_8_TRACK = 172, + STAT_TIME_ON_JETPACK = 173, + STAT_SHOOTING_RANGE_LEVELS_PASSED = 174, + STAT_MOST_CARS_PARKED_ON_VALET_PARKING = 175, + STAT_KILLS_SINCE_LAST_CHECKPOINT = 176, + STAT_TOTAL_LEGITIMATE_KILLS = 177, + STAT_NUMBER_OF_BLOODRING_KILLS = 178, + STAT_TOTAL_TIME_IN_BLOODRING = 179, + STAT_NO_MORE_HURRICANES_FLAG = 180, + STAT_CITY_UNLOCKED = 181, + STAT_NUMBER_OF_POLICE_BRIBES = 182, + STAT_NUMBER_OF_CARS_STOLEN = 183, + STAT_CURRENT_NUMBER_OF_GIRLFRIENDS = 184, + STAT_NUMBER_OF_DISASTROUS_DATES = 185, + STAT_NUMBER_OF_GIRLS_DATED = 186, + STAT_NUMBER_OF_TIMES_SCORED_WITH_A_GIRL = 187, + STAT_NUMBER_OF_SUCCESSFUL_DATES = 188, + STAT_NUMBER_OF_GIRLS_DUMPED = 189, + STAT_NUMBER_OF_PROSTITUTES_VISITED = 190, + STAT_NUMBER_OF_HOUSES_BURGLED = 191, + STAT_NUMBER_OF_SAFES_CRACKED = 192, + STAT_BURGULAR_STATUS = 193, + STAT_NUMBER_OF_STOLEN_ITEMS_SOLD = 194, + STAT_NUMBER_OF_EIGHT_BALLS_IN_POOL = 195, + STAT_TOTAL_NUMBER_OF_WINS_PLAYING_POOL = 196, + STAT_TOTAL_NUMBER_OF_LOSSES_PLAYING_POOL = 197, + STAT_TIMES_VISITED_THE_GYM = 198, + STAT_BODY_TYPE = 199, + STAT_NUMBER_OF_MEALS_EATEN = 200, + STAT_MONEY_MADE_IN_QUARRY = 201, + STAT_TIME_TAKEN_TO_COMPLETE_QUARRY = 202, + STAT_NUMBER_OF_FURNITURE_PURCHASED = 203, + STAT_FAVORITE_CONSOLE_GAME = 204, + STAT_HIGHEST_CIVILIAN_PEDS_KILLED_ON_RAMPAGE = 205, + STAT_HIGHEST_POLICE_PEDS_KILLED_ON_RAMPAGE = 206, + STAT_HIGHEST_CIVILIAN_VEHICLES_DESTROYED_ON_RAMPAGE = 207, + STAT_HIGHEST_POLICE_VEHICLES_DESTROYED_ON_RAMPAGE = 208, + STAT_HIGHEST_NUMBER_OF_TANKS_DESTROYED_ON_RAMPAGE = 209, + STAT_PIMPING_LEVEL = 210, + STAT_KICKSTART_BEST_SCORE = 211, + STAT_BEST_LAP_TIME_IN_8_TRACK = 212, + STAT_NUMBER_OF_VEHICLES_EXPORTED = 213, + STAT_NUMBER_OF_VEHICLES_IMPORTED = 214, + STAT_HIGHEST_BASKETBALL_SCORE = 215, + STAT_FIRES_STARTED = 216, + STAT_AMOUNT_OF_DRUGS_SOLD = 217, + STAT_AMOUNT_OF_DRUGS_BOUGHT = 218, + STAT_BEST_LAP_TIME_IN_DIRT_TRACK = 219, + STAT_BEST_TIME_IN_DIRT_TRACK = 220, + STAT_BEST_POSITION_IN_DIRT_TRACK = 221, + STAT_NRG_500_BEST_TIME = 222, + STAT_FLYING_SKILL = 223, + STAT_RESPECT_MISSION = 224, + STAT_LUNG_CAPACITY = 225, + STAT_GAME_GORE_RATING = 226, + STAT_GAME_SEX_RATING = 227, + STAT_RESPECT_MISSION_TOTAL = 228, + STAT_BIKE_SKILL = 229, + STAT_CYCLING_SKILL = 230, + STAT_SNAPSHOTS_TAKEN = 231, + STAT_TOTAL_SNAPSHOTS = 232, + STAT_LUCK = 233, + STAT_TERRITORIES_TAKEN_OVER = 234, + STAT_TERRITORIES_LOST = 235, + STAT_TERRITORIES_HELD = 236, + STAT_HIGHEST_NUMBER_OF_TERRITORIES_HELD = 237, + STAT_GANG_MEMBERS_RECRUITED = 238, + STAT_ENEMY_GANG_MEMBERS_KILLED = 239, + STAT_FRIENDLY_GANG_MEMBERS_KILLED = 240, + STAT_HORSESHOES_COLLECTED = 241, + STAT_TOTAL_HORSESHOES = 242, + STAT_OYSTERS_COLLECTED = 243, + STAT_TOTAL_OYSTERS = 244, + STAT_CALORIES = 245, + STAT_2_PLAYER_RAMPAGE_BEST_TIME = 246, + STAT_2_PLAYER_CAR_RAMPAGE_BEST_TIME = 247, + STAT_2_PLAYER_ON_FOOT_RAMPAGE_BEST_TIME = 248, + STAT_2_PLAYER_CHOPPER_RAMPAGE_BEST_TIME = 249, + STAT_2_PLAYER_BIKE_RAMPAGE_BEST_TIME = 250, + STAT_KEEPIE_UPPY_BEST_TIME = 251, + STAT_PROGRESS_WITH_DENISE = 252, + STAT_PROGRESS_WITH_MICHELLE = 253, + STAT_PROGRESS_WITH_HELENA = 254, + STAT_PROGRESS_WITH_BARBARA = 255, + STAT_PROGRESS_WITH_KATIE = 256, + STAT_PROGRESS_WITH_MILLIE = 257, + STAT_BEST_POSITION_IN_LOWRIDER_RACE = 258, + STAT_BEST_TIME_IN_LOWRIDER_RACE = 259, + STAT_BEST_POSITION_IN_LITTLE_LOOP = 260, + STAT_BEST_TIME_IN_LITTLE_LOOP = 261, + STAT_BEST_POSITION_IN_BACKROAD_WANDERER = 262, + STAT_BEST_TIME_IN_BACKROAD_WANDERER = 263, + STAT_BEST_POSITION_IN_CITY_CIRCUIT = 264, + STAT_BEST_TIME_IN_CITY_CIRCUIT = 265, + STAT_BEST_POSITION_IN_VINEWOOD = 266, + STAT_BEST_TIME_IN_VINEWOOD = 267, + STAT_BEST_POSITION_IN_FREEWAY = 268, + STAT_BEST_TIME_IN_FREEWAY = 269, + STAT_BEST_POSITION_IN_INTO_THE_COUNTRY = 270, + STAT_BEST_TIME_IN_INTO_THE_COUNTRY = 271, + STAT_BEST_POSITION_IN_BADLANDS_A = 272, + STAT_BEST_TIME_IN_BADLANDS_A = 273, + STAT_BEST_POSITION_IN_BADLANDS_B = 274, + STAT_BEST_TIME_IN_BADLANDS_B = 275, + STAT_BEST_POSITION_IN_DIRTBIKE_DANGER = 276, + STAT_BEST_TIME_IN_DIRTBIKE_DANGER = 277, + STAT_BEST_POSITION_IN_BANDITO_COUNTY = 278, + STAT_BEST_TIME_IN_BANDITO_COUNTY = 279, + STAT_BEST_POSITION_IN_GO_GO_KART = 280, + STAT_BEST_TIME_IN_GO_GO_KART = 281, + STAT_BEST_POSITION_IN_SAN_FIERRO_FASTLANE = 282, + STAT_BEST_TIME_IN_SAN_FIERRO_FASTLANE = 283, + STAT_BEST_POSITION_IN_SAN_FIERRO_HILLS = 284, + STAT_BEST_TIME_IN_SAN_FIERRO_HILLS = 285, + STAT_BEST_POSITION_IN_COUNTRY_ENDURANCE = 286, + STAT_BEST_TIME_IN_COUNTRY_ENDURANCE = 287, + STAT_BEST_POSITION_IN_SF_TO_LV = 288, + STAT_BEST_TIME_IN_SF_TO_LV = 289, + STAT_BEST_POSITION_IN_DAM_RIDER = 290, + STAT_BEST_TIME_IN_DAM_RIDER = 291, + STAT_BEST_POSITION_IN_DESERT_TRICKS = 292, + STAT_BEST_TIME_IN_DESERT_TRICKS = 293, + STAT_BEST_POSITION_IN_LV_RINGROAD = 294, + STAT_BEST_TIME_IN_LV_RINGROAD = 295, + STAT_BEST_TIME_IN_WORLD_WAR_ACES = 296, + STAT_BEST_TIME_IN_BARNSTORMING = 297, + STAT_BEST_TIME_IN_MILITARY_SERVICE = 298, + STAT_BEST_TIME_IN_CHOPPER_CHECKPOINT = 299, + STAT_BEST_TIME_IN_WHIRLY_BIRD_WAYPOINT = 300, + STAT_BEST_TIME_IN_HELI_HELL = 301, + STAT_DRIVE_THRU_MISSION_ACCOMPLISHED = 302, + STAT_MANAGEMENT_ISSUES_MISSION_ACCOMPLISHED = 303, + STAT_555_WE_TIP_MISSION_ACCOMPLISHED = 304, + STAT_YAY_KA_BOOM_BOOM_MISSION_ACCOMPLISHED = 305, + STAT_FISH_IN_A_BARREL_MISSION_ACCOMPLISHED = 306, + STAT_BREAKING_THE_BANK_AT_CALIGULAS_MISSION_ACCOMPLISHED = 307, + STAT_A_HOME_IN_THE_HILLS_MISSION_ACCOMPLISHED = 308, + STAT_MAYBE_SET_RIOT_MODE = 309, + STAT_RYDERS_MISSION_ROBBING_UNCLE_SAM_ACCOMPLISHED = 310, + STAT_MIKE_TORENO_MISSION_ACCOMPLISHED = 311, + STAT_ARCHITECTURAL_ESPIONAGE_MISSION_ACCOMPLISHED = 312, + STAT_JIZZY_MISSION_ACCOMPLISHED = 313, + STAT_REUNITING_THE_FAMILIES_MISSION_ACCOMPLISHED = 314, + STAT_SMALL_TOWN_BANK_MISSION_ACCOMPLISHED = 315, + STAT_PHOTO_OPPORTUNITY_MISSION_ACCOMPLISHED = 316, + STAT_DON_PEYOTE_MISSION_ACCOMPLISHED = 317, + STAT_LOCAL_LIQUOR_STORE_MISSION_ACCOMPLISHED = 318, + STAT_BADLANDS_MISSION_ACCOMPLISHED = 319, + STAT_PLAYING_TIME = 320, + STAT_HIDDEN_PACKAGES_FOUND = 321, + STAT_TAGS_SPRAYED = 322, + STAT_LEAST_FAVORITE_GANG = 323, + STAT_GANG_MEMBERS_WASTED = 324, + STAT_CRIMINALS_WASTED = 325, + STAT_MOST_FAVORITE_RADIO_STATION = 326, + STAT_LEAST_FAVORITE_RADIO_STATION = 327, + STAT_CURRENT_WEAPON_SKILL = 328, + STAT_WEAPON_SKILL_LEVELS = 329, + STAT_PILOT_RANKING = 330, + STAT_STRONGEST_GANG = 331, + STAT_2ND_STRONGEST_GANG = 332, + STAT_3RD_STRONGEST_GANG = 333, + STAT_MONEY_LOST_GAMBLING = 334, + STAT_RIOT_MISSION_ACCOMPLISHED = 335, + STAT_GANG_STRENGTH = 336, + STAT_TERRITORY_UNDER_CONTROL = 337, + STAT_ARE_YOU_GOING_TO_SAN_FIERRO_MISSION_ACCOMPLISHED = 338, + STAT_HIGH_NOON_MISSION_ACCOMPLISHED = 339, + STAT_THE_GREEN_SABRE_MISSION_ACCOMPLISHED = 340, + STAT_MAYBE_CATALINA_MEETING = 341, + STAT_MAYBE_WU_ZI_MEETING = 342 +}; + #include "json.h" // Prettify toJSON (see mantis #9210) enum eJSONPrettyType @@ -772,20 +1082,20 @@ DECLARE_ENUM(eJSONPrettyType); // flags used to define weapon characteristics // aiming options -#define WEAPONTYPE_CANAIM (0x000001) // can auto target to aim -#define WEAPONTYPE_CANAIMWITHARM (0x000002) // only needs arm to aim -#define WEAPONTYPE_FIRSTPERSON (0x000004) // uses 1st person aim -#define WEAPONTYPE_CANFREEAIM (0x000008) // can only use free aiming +#define WEAPONTYPE_CANAIM (0x000001) // can auto target to aim +#define WEAPONTYPE_CANAIMWITHARM (0x000002) // only needs arm to aim +#define WEAPONTYPE_FIRSTPERSON (0x000004) // uses 1st person aim +#define WEAPONTYPE_CANFREEAIM (0x000008) // can only use free aiming // movement options -#define WEAPONTYPE_MOVEAIM (0x000010) // can move and aim at same time -#define WEAPONTYPE_MOVEFIRE (0x000020) // can move and fire at same time +#define WEAPONTYPE_MOVEAIM (0x000010) // can move and aim at same time +#define WEAPONTYPE_MOVEFIRE (0x000020) // can move and fire at same time // basic characteristics -#define WEAPONTYPE_THROW (0x000100) // is a throwing weapon -#define WEAPONTYPE_HEAVY (0x000200) // heavy weapon - can't jump -#define WEAPONTYPE_CONTINUOUS_FIRE (0x000400) // fires every frame within loop (ie paint spray) -#define WEAPONTYPE_TWIN_PISTOLS (0x000800) // can use 2x guns at same time +#define WEAPONTYPE_THROW (0x000100) // is a throwing weapon +#define WEAPONTYPE_HEAVY (0x000200) // heavy weapon - can't jump +#define WEAPONTYPE_CONTINUOUS_FIRE (0x000400) // fires every frame within loop (ie paint spray) +#define WEAPONTYPE_TWIN_PISTOLS (0x000800) // can use 2x guns at same time // these are gun anim options #define WEAPONTYPE_ANIM_RELOAD (0x001000) // weapon has reload anims @@ -794,7 +1104,7 @@ DECLARE_ENUM(eJSONPrettyType); #define WEAPONTYPE_LONG_RELOAD_TIME (0x008000) // force a longer reload time! // these are area effect/shot options -#define WEAPONTYPE_SLOWS_DOWN (0x010000) // -#define WEAPONTYPE_RANDOM_SPEED (0x020000) // +#define WEAPONTYPE_SLOWS_DOWN (0x010000) // +#define WEAPONTYPE_RANDOM_SPEED (0x020000) // #define WEAPONTYPE_FORCE_FINISH_ANIM (0x040000) // force the anim to finish player after aim/fire rather than blending out -#define WEAPONTYPE_EXPANDS (0x080000) // +#define WEAPONTYPE_EXPANDS (0x080000) // diff --git a/Server/mods/deathmatch/logic/CConnectHistory.cpp b/Server/mods/deathmatch/logic/CConnectHistory.cpp index dabd32be8b1..cd120d0fe74 100644 --- a/Server/mods/deathmatch/logic/CConnectHistory.cpp +++ b/Server/mods/deathmatch/logic/CConnectHistory.cpp @@ -73,7 +73,7 @@ CConnectHistoryItem& CConnectHistory::GetHistoryItem(const std::string& strIP) } #if MTA_DEBUG -#if 0 + #if 0 // Dump info const CConnectHistoryItem& historyItem = iter->second; if ( !historyItem.joinTimes.empty () ) @@ -86,7 +86,7 @@ CConnectHistoryItem& CConnectHistory::GetHistoryItem(const std::string& strIP) strInfo += "\n"; OutputDebugString ( strInfo ); } -#endif + #endif #endif return iter->second; diff --git a/Server/mods/deathmatch/logic/CConsoleClient.h b/Server/mods/deathmatch/logic/CConsoleClient.h index f28658b5a45..d3ff263a497 100644 --- a/Server/mods/deathmatch/logic/CConsoleClient.h +++ b/Server/mods/deathmatch/logic/CConsoleClient.h @@ -20,7 +20,7 @@ class CConsoleClient final : public CElement, public CClient { public: CConsoleClient(CConsole* pConsole); - virtual ~CConsoleClient(){}; + virtual ~CConsoleClient() {}; int GetClientType() { return CClient::CLIENT_CONSOLE; }; const char* GetNick() { return m_strNick; }; @@ -28,7 +28,7 @@ class CConsoleClient final : public CElement, public CClient void SendEcho(const char* szEcho) { CLogger::LogPrintf("%s\n", szEcho); }; void SendConsole(const char* szEcho) { CLogger::LogPrintf("%s\n", szEcho); }; - void Unlink(){}; + void Unlink() {}; protected: bool ReadSpecialData(const int iLine) override { return false; } diff --git a/Server/mods/deathmatch/logic/CConsoleCommands.cpp b/Server/mods/deathmatch/logic/CConsoleCommands.cpp index ba952df7c29..b5801f12fa2 100644 --- a/Server/mods/deathmatch/logic/CConsoleCommands.cpp +++ b/Server/mods/deathmatch/logic/CConsoleCommands.cpp @@ -32,7 +32,7 @@ extern CGame* g_pGame; static std::string GetAdminNameForLog(CClient* pClient) { std::string strName = pClient->GetNick(); - std::string strAccountName = pClient->GetAccount() ? pClient->GetAccount()->GetName() : "no account"; + std::string strAccountName = pClient->GetAccount() ? pClient->GetAccount()->GetName() : SStringX("no account"); if (strName == strAccountName) return strName; return SString("%s(%s)", strName.c_str(), strAccountName.c_str()); @@ -86,7 +86,8 @@ bool CConsoleCommands::StartResource(CConsole* pConsole, const char* szArguments if (!resource->IsLoaded()) { - pEchoClient->SendConsole(SString("start: Resource '%s' is loaded, but has errors (%s)", resourceName.c_str(), resource->GetFailureReason().c_str())); + pEchoClient->SendConsole( + SString("start: Resource '%s' is loaded, but has errors (%s)", resourceName.c_str(), resource->GetFailureReason().c_str())); continue; } @@ -135,7 +136,8 @@ bool CConsoleCommands::RestartResource(CConsole* pConsole, const char* szArgumen if (!resource->IsLoaded()) { - pEchoClient->SendConsole(SString("restart: Resource '%s' is loaded, but has errors (%s)", resourceName.c_str(), resource->GetFailureReason().c_str())); + pEchoClient->SendConsole( + SString("restart: Resource '%s' is loaded, but has errors (%s)", resourceName.c_str(), resource->GetFailureReason().c_str())); continue; } @@ -384,7 +386,7 @@ bool CConsoleCommands::Say(CConsole* pConsole, const char* szInArguments, CClien // Send the chat message and player pointer to the script CLuaArguments Arguments; Arguments.PushString(szArguments); - Arguments.PushNumber(MESSAGE_TYPE_PLAYER); // Normal chat + Arguments.PushNumber(MESSAGE_TYPE_PLAYER); // Normal chat bool bContinue = static_cast(pClient)->CallEvent("onPlayerChat", Arguments); if (bContinue) { @@ -519,7 +521,7 @@ bool CConsoleCommands::TeamSay(CConsole* pConsole, const char* szInArguments, CC // Send the chat message and player pointer to the script CLuaArguments Arguments; Arguments.PushString(szArguments); - Arguments.PushNumber(MESSAGE_TYPE_TEAM); // Team chat + Arguments.PushNumber(MESSAGE_TYPE_TEAM); // Team chat bool bContinue = static_cast(pClient)->CallEvent("onPlayerChat", Arguments); if (bContinue) { @@ -626,9 +628,9 @@ bool CConsoleCommands::Msg(CConsole* pConsole, const char* szInArguments, CClien // Send the message and player pointer to the script CLuaArguments Arguments; - Arguments.PushString(szArguments); // We don't want to remove this for backwards compatibility reasons + Arguments.PushString(szArguments); // We don't want to remove this for backwards compatibility reasons Arguments.PushElement(pPlayer); - Arguments.PushString(szMessage); // Fix #2135 + Arguments.PushString(szMessage); // Fix #2135 bool bContinue = pSender->CallEvent("onPlayerPrivateMessage", Arguments); if (bContinue) @@ -726,8 +728,8 @@ bool CConsoleCommands::Me(CConsole* pConsole, const char* szArguments, CClient* if (pClient->GetClientType() == CClient::CLIENT_PLAYER) { CLuaArguments Arguments; - Arguments.PushString(szArguments); // text - Arguments.PushNumber(MESSAGE_TYPE_ACTION); // Me chat + Arguments.PushString(szArguments); // text + Arguments.PushNumber(MESSAGE_TYPE_ACTION); // Me chat bool bContinue = static_cast(pClient)->CallEvent("onPlayerChat", Arguments); if (bContinue) { @@ -796,7 +798,7 @@ bool CConsoleCommands::Nick(CConsole* pConsole, const char* szArguments, CClient CLuaArguments Arguments; Arguments.PushString(pClient->GetNick()); Arguments.PushString(szNewNick); - Arguments.PushBoolean(true); // manually changed + Arguments.PushBoolean(true); // manually changed if (pPlayer->CallEvent("onPlayerChangeNick", Arguments)) { // Tell the console @@ -1295,8 +1297,8 @@ bool CConsoleCommands::DebugScript(CConsole* console, const char* arguments, CCl } CPlayer* player = static_cast(client); - int debugLevel = arguments[0] - '0'; // Convert the character to an integer (e.g., '2' -> 2) - int debugLevelCurrent = player->GetScriptDebugLevel(); + int debugLevel = arguments[0] - '0'; // Convert the character to an integer (e.g., '2' -> 2) + int debugLevelCurrent = player->GetScriptDebugLevel(); // Check if the level is the same if (debugLevel == debugLevelCurrent) @@ -1313,7 +1315,7 @@ bool CConsoleCommands::DebugScript(CConsole* console, const char* arguments, CCl } // Set the new level - player->SetScriptDebugLevel(debugLevel); + player->SetScriptDebugLevel(static_cast(debugLevel)); echoClient->SendEcho(("debugscript: Your debug mode was set to " + std::to_string(debugLevel)).c_str()); CLogger::LogPrintf("SCRIPT: %s set their script debug mode to %d\n", GetAdminNameForLog(client).c_str(), debugLevel); @@ -1570,7 +1572,7 @@ bool CConsoleCommands::OpenPortsTest(CConsole* pConsole, const char* szArguments { if (pClient->GetClientType() == CClient::CLIENT_CONSOLE) { -#if MTASA_VERSION_TYPE < VERSION_TYPE_RELEASE +#if MTASA_VERSION_TYPE < VERSION_TYPE_UNTESTED if (SStringX(szArguments) == "crashme") { // For testing crash handling @@ -1625,9 +1627,9 @@ bool DoAclRequest(CConsole* pConsole, const char* szArguments, CClient* pClient, std::vector parts; SStringX(szArguments).Split(" ", parts); - const SString& strAction = parts.size() > 0 ? parts[0] : ""; - const SString& strResourceName = parts.size() > 1 ? parts[1] : ""; - const SString& strRightName = parts.size() > 2 ? parts[2] : ""; + const SString& strAction = parts.size() > 0 ? parts[0] : SStringX(""); + const SString& strResourceName = parts.size() > 1 ? parts[1] : SStringX(""); + const SString& strRightName = parts.size() > 2 ? parts[2] : SStringX(""); bool bList = strAction == "list"; bool bAllow = strAction == "allow"; @@ -1695,8 +1697,8 @@ bool CConsoleCommands::AuthorizeSerial(CConsole* pConsole, const char* szArgumen std::vector parts; SStringX(szArguments).Split(" ", parts); - const SString& strAccountName = parts.size() > 0 ? parts[0] : ""; - const SString& strAction = parts.size() > 1 ? parts[1] : ""; + const SString& strAccountName = parts.size() > 0 ? parts[0] : SStringX(""); + const SString& strAction = parts.size() > 1 ? parts[1] : SStringX(""); bool bList = strAction == "list"; bool bAllow = strAction == ""; diff --git a/Server/mods/deathmatch/logic/CCustomData.cpp b/Server/mods/deathmatch/logic/CCustomData.cpp index 8ccd96a1685..0b3a317cd96 100644 --- a/Server/mods/deathmatch/logic/CCustomData.cpp +++ b/Server/mods/deathmatch/logic/CCustomData.cpp @@ -14,39 +14,39 @@ void CCustomData::Copy(CCustomData* pCustomData) { - std::map::const_iterator iter = pCustomData->IterBegin(); + auto iter = pCustomData->IterBegin(); for (; iter != pCustomData->IterEnd(); iter++) { - Set(iter->first.c_str(), iter->second.Variable); + Set(iter->first, iter->second.Variable); } } -SCustomData* CCustomData::Get(const char* szName) const +SCustomData* CCustomData::Get(const CStringName& name) const { - assert(szName); + assert(name); - std::map::const_iterator it = m_Data.find(szName); + auto it = m_Data.find(name); if (it != m_Data.end()) return (SCustomData*)&it->second; return NULL; } -SCustomData* CCustomData::GetSynced(const char* szName) +SCustomData* CCustomData::GetSynced(const CStringName& name) { - assert(szName); + assert(name); - std::map::const_iterator it = m_SyncedData.find(szName); + auto it = m_SyncedData.find(name); if (it != m_SyncedData.end()) return (SCustomData*)&it->second; return NULL; } -bool CCustomData::DeleteSynced(const char* szName) +bool CCustomData::DeleteSynced(const CStringName& name) { // Find the item and delete it - std::map::iterator iter = m_SyncedData.find(szName); + auto iter = m_SyncedData.find(name); if (iter != m_SyncedData.end()) { m_SyncedData.erase(iter); @@ -57,11 +57,11 @@ bool CCustomData::DeleteSynced(const char* szName) return false; } -void CCustomData::UpdateSynced(const char* szName, const CLuaArgument& Variable, ESyncType syncType) +void CCustomData::UpdateSynced(const CStringName& name, const CLuaArgument& Variable, ESyncType syncType) { if (syncType == ESyncType::BROADCAST) { - SCustomData* pDataSynced = GetSynced(szName); + SCustomData* pDataSynced = GetSynced(name); if (pDataSynced) { pDataSynced->Variable = Variable; @@ -72,27 +72,27 @@ void CCustomData::UpdateSynced(const char* szName, const CLuaArgument& Variable, SCustomData newData; newData.Variable = Variable; newData.syncType = syncType; - m_SyncedData[szName] = newData; + m_SyncedData[name] = newData; } } else { - DeleteSynced(szName); + DeleteSynced(name); } } -void CCustomData::Set(const char* szName, const CLuaArgument& Variable, ESyncType syncType) +void CCustomData::Set(const CStringName& name, const CLuaArgument& Variable, ESyncType syncType) { - assert(szName); + assert(name); // Grab the item with the given name - SCustomData* pData = Get(szName); + SCustomData* pData = Get(name); if (pData) { // Update existing pData->Variable = Variable; pData->syncType = syncType; - UpdateSynced(szName, Variable, syncType); + UpdateSynced(name, Variable, syncType); } else { @@ -101,18 +101,18 @@ void CCustomData::Set(const char* szName, const CLuaArgument& Variable, ESyncTyp newData.Variable = Variable; newData.syncType = syncType; newData.clientChangesMode = eCustomDataClientTrust::UNSET; - m_Data[szName] = newData; - UpdateSynced(szName, Variable, syncType); + m_Data[name] = newData; + UpdateSynced(name, Variable, syncType); } } -bool CCustomData::Delete(const char* szName) +bool CCustomData::Delete(const CStringName& name) { // Find the item and delete it - std::map::iterator it = m_Data.find(szName); + auto it = m_Data.find(name); if (it != m_Data.end()) { - DeleteSynced(szName); + DeleteSynced(name); m_Data.erase(it); return true; } @@ -121,15 +121,15 @@ bool CCustomData::Delete(const char* szName) return false; } -void CCustomData::SetClientChangesMode(const char* szName, eCustomDataClientTrust mode) +void CCustomData::SetClientChangesMode(const CStringName& name, eCustomDataClientTrust mode) { - SCustomData& pData = m_Data[szName]; + SCustomData& pData = m_Data[name]; pData.clientChangesMode = mode; } CXMLNode* CCustomData::OutputToXML(CXMLNode* pNode) { - std::map::const_iterator iter = m_Data.begin(); + auto iter = m_Data.begin(); for (; iter != m_Data.end(); iter++) { CLuaArgument* arg = (CLuaArgument*)&iter->second.Variable; @@ -138,19 +138,19 @@ CXMLNode* CCustomData::OutputToXML(CXMLNode* pNode) { case LUA_TSTRING: { - CXMLAttribute* attr = pNode->GetAttributes().Create(iter->first.c_str()); + CXMLAttribute* attr = pNode->GetAttributes().Create(iter->first.ToCString()); attr->SetValue(arg->GetString().c_str()); break; } case LUA_TNUMBER: { - CXMLAttribute* attr = pNode->GetAttributes().Create(iter->first.c_str()); + CXMLAttribute* attr = pNode->GetAttributes().Create(iter->first.ToCString()); attr->SetValue((float)arg->GetNumber()); break; } case LUA_TBOOLEAN: { - CXMLAttribute* attr = pNode->GetAttributes().Create(iter->first.c_str()); + CXMLAttribute* attr = pNode->GetAttributes().Create(iter->first.ToCString()); attr->SetValue(arg->GetBoolean()); break; } diff --git a/Server/mods/deathmatch/logic/CCustomData.h b/Server/mods/deathmatch/logic/CCustomData.h index 1fa5686780d..da52ba63253 100644 --- a/Server/mods/deathmatch/logic/CCustomData.h +++ b/Server/mods/deathmatch/logic/CCustomData.h @@ -44,28 +44,28 @@ class CCustomData public: void Copy(CCustomData* pCustomData); - SCustomData* Get(const char* szName) const; - SCustomData* GetSynced(const char* szName); - void Set(const char* szName, const CLuaArgument& Variable, ESyncType syncType = ESyncType::BROADCAST); + SCustomData* Get(const CStringName& name) const; + SCustomData* GetSynced(const CStringName& name); + void Set(const CStringName& name, const CLuaArgument& Variable, ESyncType syncType = ESyncType::BROADCAST); - bool Delete(const char* szName); + bool Delete(const CStringName& name); - void SetClientChangesMode(const char* szName, eCustomDataClientTrust mode); + void SetClientChangesMode(const CStringName& name, eCustomDataClientTrust mode); unsigned short CountOnlySynchronized(); CXMLNode* OutputToXML(CXMLNode* pNode); - std::map::const_iterator IterBegin() { return m_Data.begin(); } - std::map::const_iterator IterEnd() { return m_Data.end(); } + std::unordered_map::const_iterator IterBegin() { return m_Data.begin(); } + std::unordered_map::const_iterator IterEnd() { return m_Data.end(); } - std::map::const_iterator SyncedIterBegin() { return m_SyncedData.begin(); } - std::map::const_iterator SyncedIterEnd() { return m_SyncedData.end(); } + std::unordered_map::const_iterator SyncedIterBegin() { return m_SyncedData.begin(); } + std::unordered_map::const_iterator SyncedIterEnd() { return m_SyncedData.end(); } private: - bool DeleteSynced(const char* szName); - void UpdateSynced(const char* szName, const CLuaArgument& Variable, ESyncType syncType); + bool DeleteSynced(const CStringName& name); + void UpdateSynced(const CStringName& name, const CLuaArgument& Variable, ESyncType syncType); - std::map m_Data; - std::map m_SyncedData; + std::unordered_map m_Data; + std::unordered_map m_SyncedData; }; diff --git a/Server/mods/deathmatch/logic/CCustomWeapon.h b/Server/mods/deathmatch/logic/CCustomWeapon.h index ef0248170a5..01cc15a0630 100644 --- a/Server/mods/deathmatch/logic/CCustomWeapon.h +++ b/Server/mods/deathmatch/logic/CCustomWeapon.h @@ -39,7 +39,7 @@ struct SLineOfSightFlags bool bCheckDummies; bool bSeeThroughStuff; bool bIgnoreSomeObjectsForCamera; - bool bShootThroughStuff; // not used for IsLineOfSightClear + bool bShootThroughStuff; // not used for IsLineOfSightClear bool bCheckCarTires; }; @@ -120,7 +120,7 @@ class CCustomWeapon final : public CObject eBone m_targetBone; int m_itargetWheel; SWeaponConfiguration m_weaponConfig; - CPlayer* m_pOwner; // For lag compensation + CPlayer* m_pOwner; // For lag compensation int m_nAmmoTotal; int m_nAmmoInClip; eWeaponState m_PreviousState; diff --git a/Server/mods/deathmatch/logic/CDatabaseJobQueue.cpp b/Server/mods/deathmatch/logic/CDatabaseJobQueue.cpp index cc9ad55a37a..00dd1387e08 100644 --- a/Server/mods/deathmatch/logic/CDatabaseJobQueue.cpp +++ b/Server/mods/deathmatch/logic/CDatabaseJobQueue.cpp @@ -66,7 +66,7 @@ class CDatabaseJobQueueImpl : public CDatabaseJobQueue // Main thread variables CThreadHandle* m_pServiceThreadHandle; std::map m_ActiveJobHandles; - std::set m_FinishedList; // Result has been used, will be deleted next pulse + std::set m_FinishedList; // Result has been used, will be deleted next pulse uint m_uiJobCountWarnThresh; uint m_uiJobCount10sMin; CElapsedTime m_JobCountElpasedTime; @@ -435,7 +435,7 @@ bool CDatabaseJobQueueImpl::FreeCommand(CDbJobData* pJobData) } if (pJobData->result.bIgnoreResult) - return false; // Already ignoring query handle + return false; // Already ignoring query handle // if in command or result queue, then put in ignore result list bool bFound; diff --git a/Server/mods/deathmatch/logic/CDatabaseManager.cpp b/Server/mods/deathmatch/logic/CDatabaseManager.cpp index a1e1836e728..cc459bc27c6 100644 --- a/Server/mods/deathmatch/logic/CDatabaseManager.cpp +++ b/Server/mods/deathmatch/logic/CDatabaseManager.cpp @@ -585,7 +585,7 @@ SString CDatabaseManagerImpl::InsertQueryArguments(SConnectionHandle hConnection // Determine connection type SString* pstrType = MapFind(m_ConnectionTypeMap, hConnection); - SString strType = pstrType ? *pstrType : ""; + SString strType = pstrType ? *pstrType : SStringX(""); if (strType == "sqlite") return InsertQueryArgumentsSqlite(strQuery, pArgs); @@ -608,7 +608,7 @@ SString CDatabaseManagerImpl::InsertQueryArguments(SConnectionHandle hConnection { // Determine connection type SString* pstrType = MapFind(m_ConnectionTypeMap, hConnection); - SString strType = pstrType ? *pstrType : ""; + SString strType = pstrType ? *pstrType : SStringX(""); if (strType == "sqlite") return InsertQueryArgumentsSqlite(szQuery, vl); @@ -680,10 +680,10 @@ CDbJobData::~CDbJobData() bool CDbJobData::SetCallback(PFN_DBRESULT pfnDbResult, void* pContext) { if (callback.bSet) - return false; // One has already been set + return false; // One has already been set if (this->stage > EJobStage::RESULT) - return false; // Too late to set a callback now + return false; // Too late to set a callback now // Set new callback.pfnDbResult = pfnDbResult; diff --git a/Server/mods/deathmatch/logic/CDatabaseManager.h b/Server/mods/deathmatch/logic/CDatabaseManager.h index b238faa70af..86963aefc68 100644 --- a/Server/mods/deathmatch/logic/CDatabaseManager.h +++ b/Server/mods/deathmatch/logic/CDatabaseManager.h @@ -17,7 +17,7 @@ #define INVALID_DB_HANDLE (0) #define DB_SQLITE_QUEUE_NAME_INTERNAL "sqlite internal" -#define DB_SQLITE_QUEUE_NAME_DEFAULT "sqlite" // Note: MySql default queue name is the host string +#define DB_SQLITE_QUEUE_NAME_DEFAULT "sqlite" // Note: MySql default queue name is the host string class CDatabaseJobQueue; typedef uint SDbConnectionId; diff --git a/Server/mods/deathmatch/logic/CDatabaseType.h b/Server/mods/deathmatch/logic/CDatabaseType.h index 45f5a16ea26..ee300c17955 100644 --- a/Server/mods/deathmatch/logic/CDatabaseType.h +++ b/Server/mods/deathmatch/logic/CDatabaseType.h @@ -74,5 +74,5 @@ CDatabaseConnection* NewDatabaseConnectionSqlite(CDatabaseType* pManager, const // Create interfaces for mysql // CDatabaseType* NewDatabaseTypeMySql(); -typedef CDatabaseConnection*(NewDatabaseConnectionMySql_t)(CDatabaseType* pManager, const SString& strHost, const SString& strUsername, +typedef CDatabaseConnection*(NewDatabaseConnectionMySql_t)(CDatabaseType * pManager, const SString& strHost, const SString& strUsername, const SString& strPassword, const SString& strOptions); diff --git a/Server/mods/deathmatch/logic/CDatabaseTypeMySql.cpp b/Server/mods/deathmatch/logic/CDatabaseTypeMySql.cpp index 1a042352934..78e31964d87 100644 --- a/Server/mods/deathmatch/logic/CDatabaseTypeMySql.cpp +++ b/Server/mods/deathmatch/logic/CDatabaseTypeMySql.cpp @@ -198,8 +198,11 @@ CDatabaseConnection* CDatabaseTypeMySql::CallNewDatabaseConnectionMySql(CDatabas { SString strServerPath = g_pServerInterface->GetModManager()->GetServerPath(); m_DbconmyLib.Load(PathJoin(strServerPath, SERVER_BIN_PATH_MOD, LIB_DBCONMY)); - m_pfnNewDatabaseConnection = - reinterpret_cast((long long)(m_DbconmyLib.GetProcedureAddress("NewDatabaseConnectionMySql"))); + { + const auto procAddr = m_DbconmyLib.GetProcedureAddress("NewDatabaseConnectionMySql"); + static_assert(sizeof(m_pfnNewDatabaseConnection) == sizeof(procAddr), "Unexpected function pointer size"); + std::memcpy(&m_pfnNewDatabaseConnection, &procAddr, sizeof(m_pfnNewDatabaseConnection)); + } } if (!m_pfnNewDatabaseConnection) diff --git a/Server/mods/deathmatch/logic/CDynamicLibrary.cpp b/Server/mods/deathmatch/logic/CDynamicLibrary.cpp index c555fedb9f8..331ca2f7164 100644 --- a/Server/mods/deathmatch/logic/CDynamicLibrary.cpp +++ b/Server/mods/deathmatch/logic/CDynamicLibrary.cpp @@ -30,8 +30,8 @@ bool CDynamicLibrary::Load(const char* szFilename) // Unload the previous library Unload(); - // Load the new library - #ifdef WIN32 +// Load the new library +#ifdef WIN32 // Search at the same path for dependencies (path must be abslolute) m_hModule = LoadLibraryEx(szFilename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); @@ -43,7 +43,7 @@ bool CDynamicLibrary::Load(const char* szFilename) CLogger::ErrorPrintf("Could not load %s - %s", szFilename, szError); } - #else +#else m_hModule = dlopen(szFilename, RTLD_NOW); // Output error if needed @@ -51,7 +51,7 @@ bool CDynamicLibrary::Load(const char* szFilename) { CLogger::ErrorPrintf("Could not load %s - %s", szFilename, dlerror()); } - #endif +#endif // Return whether we succeeded or not return m_hModule != 0; @@ -62,11 +62,11 @@ void CDynamicLibrary::Unload() // Got a module? if (m_hModule != 0) { - #ifdef WIN32 +#ifdef WIN32 FreeLibrary(m_hModule); - #else +#else dlclose(m_hModule); - #endif +#endif // Zero out our library as it's no longer valid m_hModule = 0; @@ -83,9 +83,9 @@ void* CDynamicLibrary::GetProcedureAddress(const char* szProcName) // Got a module? if (m_hModule != 0) { - #ifdef WIN32 +#ifdef WIN32 return GetProcAddress(m_hModule, szProcName); - #else +#else char* szError = NULL; dlerror(); @@ -96,7 +96,7 @@ void* CDynamicLibrary::GetProcedureAddress(const char* szProcName) } return pFunc; - #endif +#endif } return NULL; diff --git a/Server/mods/deathmatch/logic/CDynamicLibrary.h b/Server/mods/deathmatch/logic/CDynamicLibrary.h index f948a7458ef..972fd47d9c6 100644 --- a/Server/mods/deathmatch/logic/CDynamicLibrary.h +++ b/Server/mods/deathmatch/logic/CDynamicLibrary.h @@ -12,9 +12,9 @@ #pragma once #ifdef WIN32 -#include + #include #else -#include + #include #endif class CDynamicLibrary @@ -30,9 +30,9 @@ class CDynamicLibrary void* GetProcedureAddress(const char* szProcName); private: - #ifdef WIN32 +#ifdef WIN32 HMODULE m_hModule; - #else +#else void* m_hModule; - #endif +#endif }; diff --git a/Server/mods/deathmatch/logic/CElement.cpp b/Server/mods/deathmatch/logic/CElement.cpp index 9dece62ab4c..c30ddf5640b 100644 --- a/Server/mods/deathmatch/logic/CElement.cpp +++ b/Server/mods/deathmatch/logic/CElement.cpp @@ -30,7 +30,7 @@ extern CGame* g_pGame; #if defined(_MSC_VER) -#pragma warning(disable : 4355) // warning C4355: 'this' : used in base member initializer list + #pragma warning(disable : 4355) // warning C4355: 'this' : used in base member initializer list #endif CElement::CElement(CElement* pParent) @@ -356,7 +356,7 @@ void CElement::ClearChildren() assert(m_pParent != this); // Process our children - Move up to our parent - if (!m_Children.empty()) // This check reduces cpu usage when unloading large maps (due to recursion) + if (!m_Children.empty()) // This check reduces cpu usage when unloading large maps (due to recursion) { while (!m_Children.empty()) (*m_Children.begin())->SetParentObject(m_pParent, false); @@ -438,10 +438,11 @@ bool CElement::CallEvent(const char* szName, const CLuaArguments& Arguments, CPl if (!g_pGame->GetDebugHookManager()->OnPreEvent(szName, Arguments, this, pCaller)) return false; - CEvents* pEvents = g_pGame->GetEvents(); + CEvents* pEvents = g_pGame->GetEvents(); + CEventContext eventContext; // Make sure our event-manager knows we're about to call an event - pEvents->PreEventPulse(); + pEvents->PreEventPulse(&eventContext); // Call the event on our parents/us first CallParentEvent(szName, Arguments, this, pCaller); @@ -450,12 +451,12 @@ bool CElement::CallEvent(const char* szName, const CLuaArguments& Arguments, CPl CallEventNoParent(szName, Arguments, this, pCaller); // Tell the event manager that we're done calling the event - pEvents->PostEventPulse(); + pEvents->PostEventPulse(&eventContext); g_pGame->GetDebugHookManager()->OnPostEvent(szName, Arguments, this, pCaller); // Return whether our event was cancelled or not - return (!pEvents->WasEventCancelled()); + return !eventContext.IsCancelled(); } bool CElement::DeleteEvent(CLuaMain* pLuaMain, const char* szName, const CLuaFunctionRef& iLuaFunction) @@ -508,12 +509,12 @@ void CElement::ReadCustomData(CEvents* pEvents, CXMLNode& Node) } } -CLuaArgument* CElement::GetCustomData(const char* szName, bool bInheritData, ESyncType* pSyncType, eCustomDataClientTrust* clientChangesMode) +CLuaArgument* CElement::GetCustomData(const CStringName& name, bool bInheritData, ESyncType* pSyncType, eCustomDataClientTrust* clientChangesMode) { - assert(szName); + assert(name); // Grab it and return a pointer to the variable - SCustomData* pData = m_CustomData.Get(szName); + SCustomData* pData = m_CustomData.Get(name); if (pData) { if (pSyncType) @@ -528,7 +529,7 @@ CLuaArgument* CElement::GetCustomData(const char* szName, bool bInheritData, ESy // If none, try returning parent's custom data if (bInheritData && m_pParent) { - return m_pParent->GetCustomData(szName, true, pSyncType, clientChangesMode); + return m_pParent->GetCustomData(name, true, pSyncType, clientChangesMode); } // None available @@ -540,20 +541,20 @@ CLuaArguments* CElement::GetAllCustomData(CLuaArguments* table) assert(table); // Grab it and return a pointer to the variable - map::const_iterator iter = m_CustomData.IterBegin(); + auto iter = m_CustomData.IterBegin(); for (; iter != m_CustomData.IterEnd(); iter++) { - table->PushString(iter->first.c_str()); // key - table->PushArgument(iter->second.Variable); // value + table->PushString(iter->first); // key + table->PushArgument(iter->second.Variable); // value } return table; } -bool CElement::GetCustomDataString(const char* szName, char* pOut, size_t sizeBuffer, bool bInheritData) +bool CElement::GetCustomDataString(const CStringName& name, char* pOut, size_t sizeBuffer, bool bInheritData) { // Grab the custom data variable - CLuaArgument* pData = GetCustomData(szName, bInheritData); + CLuaArgument* pData = GetCustomData(name, bInheritData); if (pData) { // Make sure it gets 0 terminated @@ -589,10 +590,10 @@ bool CElement::GetCustomDataString(const char* szName, char* pOut, size_t sizeBu return false; } -bool CElement::GetCustomDataInt(const char* szName, int& iOut, bool bInheritData) +bool CElement::GetCustomDataInt(const CStringName& name, int& iOut, bool bInheritData) { // Grab the custom data variable - CLuaArgument* pData = GetCustomData(szName, bInheritData); + CLuaArgument* pData = GetCustomData(name, bInheritData); if (pData) { // Write the content depending on what type it is @@ -627,10 +628,10 @@ bool CElement::GetCustomDataInt(const char* szName, int& iOut, bool bInheritData return false; } -bool CElement::GetCustomDataFloat(const char* szName, float& fOut, bool bInheritData) +bool CElement::GetCustomDataFloat(const CStringName& name, float& fOut, bool bInheritData) { // Grab the custom data variable - CLuaArgument* pData = GetCustomData(szName, bInheritData); + CLuaArgument* pData = GetCustomData(name, bInheritData); if (pData) { // Write the content depending on what type it is @@ -654,10 +655,10 @@ bool CElement::GetCustomDataFloat(const char* szName, float& fOut, bool bInherit return false; } -bool CElement::GetCustomDataBool(const char* szName, bool& bOut, bool bInheritData) +bool CElement::GetCustomDataBool(const CStringName& name, bool& bOut, bool bInheritData) { // Grab the custom data variable - CLuaArgument* pData = GetCustomData(szName, bInheritData); + CLuaArgument* pData = GetCustomData(name, bInheritData); if (pData) { // Write the content depending on what type it is @@ -709,78 +710,96 @@ bool CElement::GetCustomDataBool(const char* szName, bool& bOut, bool bInheritDa return false; } -void CElement::SetCustomData(const char* szName, const CLuaArgument& Variable, ESyncType syncType, CPlayer* pClient, bool bTriggerEvent) +bool CElement::SetCustomData(const CStringName& name, const CLuaArgument& Variable, ESyncType syncType, CPlayer* pClient, bool bTriggerEvent) { - assert(szName); - if (strlen(szName) > MAX_CUSTOMDATA_NAME_LENGTH) + assert(name); + if (name->length() > MAX_CUSTOMDATA_NAME_LENGTH) { // Don't allow it to be set if the name is too long - CLogger::ErrorPrintf("Custom data name too long (%s)\n", *SStringX(szName).Left(MAX_CUSTOMDATA_NAME_LENGTH + 1)); - return; + CLogger::ErrorPrintf("Custom data name too long (%s)\n", *SStringX(name.ToCString()).Left(MAX_CUSTOMDATA_NAME_LENGTH + 1)); + return false; } - // Grab the old variable + // Grab the old variable and sync type CLuaArgument oldVariable; - const SCustomData* pData = m_CustomData.Get(szName); + ESyncType oldSyncType = ESyncType::LOCAL; + const SCustomData* pData = m_CustomData.Get(name); if (pData) { oldVariable = pData->Variable; + oldSyncType = pData->syncType; } // Set the new data - m_CustomData.Set(szName, Variable, syncType); + m_CustomData.Set(name, Variable, syncType); if (bTriggerEvent) { // Trigger the onElementDataChange event on us CLuaArguments Arguments; - Arguments.PushString(szName); + Arguments.PushString(name); Arguments.PushArgument(oldVariable); Arguments.PushArgument(Variable); - CallEvent("onElementDataChange", Arguments, pClient); + if (!CallEvent("onElementDataChange", Arguments, pClient)) + { + // Event was cancelled, restore previous value + if (pData) + m_CustomData.Set(name, oldVariable, oldSyncType); + else + m_CustomData.Delete(name); + return false; + } } + return true; } -void CElement::DeleteCustomData(const char* szName) +bool CElement::DeleteCustomData(const CStringName& name) { // Grab the old variable - SCustomData* pData = m_CustomData.Get(szName); + SCustomData* pData = m_CustomData.Get(name); if (pData) { - CLuaArgument oldVariable; - oldVariable = pData->Variable; + CLuaArgument oldVariable = pData->Variable; + ESyncType oldSyncType = pData->syncType; // Delete the custom data - m_CustomData.Delete(szName); + m_CustomData.Delete(name); // Trigger the onElementDataChange event on us CLuaArguments Arguments; - Arguments.PushString(szName); + Arguments.PushString(name); Arguments.PushArgument(oldVariable); - Arguments.PushArgument(CLuaArgument()); // Use nil as the new value to indicate the data has been removed - CallEvent("onElementDataChange", Arguments); + Arguments.PushArgument(CLuaArgument()); // Use nil as the new value to indicate the data has been removed + if (!CallEvent("onElementDataChange", Arguments)) + { + // Event was cancelled, restore previous value + m_CustomData.Set(name, oldVariable, oldSyncType); + return false; + } + return true; } + return false; } // Used to send the root element data when a player joins void CElement::SendAllCustomData(CPlayer* pPlayer) { - for (map::const_iterator iter = m_CustomData.SyncedIterBegin(); iter != m_CustomData.SyncedIterEnd(); ++iter) + for (auto iter = m_CustomData.SyncedIterBegin(); iter != m_CustomData.SyncedIterEnd(); ++iter) { - const std::string& strName = iter->first; + const CStringName& name = iter->first; const SCustomData& customData = iter->second; if (customData.syncType == ESyncType::LOCAL) continue; // Tell our clients to update their data - unsigned short usNameLength = static_cast(strName.length()); + unsigned short usNameLength = static_cast(name->length()); CBitStream BitStream; BitStream.pBitStream->WriteCompressed(usNameLength); - BitStream.pBitStream->Write(strName.c_str(), usNameLength); + BitStream.pBitStream->Write(name.ToCString(), usNameLength); customData.Variable.WriteToBitStream(*BitStream.pBitStream); - if (customData.syncType == ESyncType::BROADCAST || pPlayer->IsSubscribed(this, strName)) + if (customData.syncType == ESyncType::BROADCAST || pPlayer->IsSubscribed(this, name)) pPlayer->Send(CElementRPCPacket(this, SET_ELEMENT_DATA, *BitStream.pBitStream)); } } @@ -847,7 +866,7 @@ bool CElement::LoadFromCustomData(CEvents* pEvents, CXMLNode& Node) void CElement::OnSubtreeAdd(CElement* pElement) { // Call the event on the elements that references us - if (!m_ElementReferenced.empty()) // This check reduces cpu usage when loading large maps (due to recursion) + if (!m_ElementReferenced.empty()) // This check reduces cpu usage when loading large maps (due to recursion) { std::list::const_iterator iter = m_ElementReferenced.begin(); for (; iter != m_ElementReferenced.end(); iter++) @@ -866,7 +885,7 @@ void CElement::OnSubtreeAdd(CElement* pElement) void CElement::OnSubtreeRemove(CElement* pElement) { // Call the event on the elements that references us - if (!m_ElementReferenced.empty()) // This check reduces cpu usage when unloading large maps (due to recursion) + if (!m_ElementReferenced.empty()) // This check reduces cpu usage when unloading large maps (due to recursion) { std::list::const_iterator iter = m_ElementReferenced.begin(); for (; iter != m_ElementReferenced.end(); iter++) @@ -1019,7 +1038,8 @@ void CElement::CallEventNoParent(const char* szName, const CLuaArguments& Argume } // Call it on all our children - for (CElement* pElement : *GetChildrenListSnapshot()) + CElementListSnapshotRef childrenList = GetChildrenListSnapshot(); + for (CElement* pElement : *childrenList) { if (!pElement->IsBeingDeleted()) { @@ -1179,7 +1199,7 @@ bool CElement::IsAttachedToElement(CElement* pElement, bool bRecursive) return true; if (!std::get(history.insert(pCurrent))) - break; // This should not be possible, but you never know + break; // This should not be possible, but you never know } return false; @@ -1236,14 +1256,15 @@ void CElement::GetAttachedPosition(CVector& vecPosition) { if (m_pAttachedTo) { - CVector vecRotation; + // Get the position of the element we're attached to vecPosition = m_pAttachedTo->GetPosition(); - m_pAttachedTo->GetRotation(vecRotation); - CVector vecPositionOffset = m_vecAttachedPosition; - // This works when rotating around z axis. Other axes need testing. - RotateVector(vecPositionOffset, CVector(vecRotation.fX, vecRotation.fY, -vecRotation.fZ)); - vecPosition += vecPositionOffset; + // Get the parent's matrix + CMatrix matParent; + m_pAttachedTo->GetMatrix(matParent); + + // Apply the transformation + vecPosition += matParent.TransformVectorByRotation(m_vecAttachedPosition); } } @@ -1252,7 +1273,9 @@ void CElement::GetAttachedRotation(CVector& vecRotation) if (m_pAttachedTo) { m_pAttachedTo->GetRotation(vecRotation); + ConvertRadiansToDegrees(vecRotation); vecRotation += m_vecAttachedRotation; + ConvertDegreesToRadians(vecRotation); } } diff --git a/Server/mods/deathmatch/logic/CElement.h b/Server/mods/deathmatch/logic/CElement.h index 6070b9bc577..f607861b0fe 100644 --- a/Server/mods/deathmatch/logic/CElement.h +++ b/Server/mods/deathmatch/logic/CElement.h @@ -20,26 +20,27 @@ #include #include "Enums.h" #include "CElementGroup.h" +#include "CStringName.h" // Used to check fast version of getElementsByType // #define CHECK_ENTITIES_FROM_ROOT MTA_DEBUG -#define IS_BLIP(element) ((element)->GetType()==CElement::BLIP) -#define IS_COLSHAPE(element) ((element)->GetType()==CElement::COLSHAPE) -#define IS_DUMMY(element) ((element)->GetType()==CElement::DUMMY) -#define IS_FILE(element) ((element)->GetType()==CElement::SCRIPTFILE) -#define IS_MARKER(element) ((element)->GetType()==CElement::MARKER) -#define IS_OBJECT(element) ((element)->GetType()==CElement::OBJECT) +#define IS_BLIP(element) ((element)->GetType() == CElement::BLIP) +#define IS_COLSHAPE(element) ((element)->GetType() == CElement::COLSHAPE) +#define IS_DUMMY(element) ((element)->GetType() == CElement::DUMMY) +#define IS_FILE(element) ((element)->GetType() == CElement::SCRIPTFILE) +#define IS_MARKER(element) ((element)->GetType() == CElement::MARKER) +#define IS_OBJECT(element) ((element)->GetType() == CElement::OBJECT) #define IS_PERPLAYER_ENTITY(element) ((element)->IsPerPlayerEntity()) -#define IS_PICKUP(element) ((element)->GetType()==CElement::PICKUP) -#define IS_PED(element) ((element)->GetType()==CElement::PLAYER||(element)->GetType()==CElement::PED) -#define IS_PLAYER(element) ((element)->GetType()==CElement::PLAYER) -#define IS_RADAR_AREA(element) ((element)->GetType()==CElement::RADAR_AREA) -#define IS_VEHICLE(element) ((element)->GetType()==CElement::VEHICLE) -#define IS_CONSOLE(element) ((element)->GetType()==CElement::CONSOLE) -#define IS_TEAM(element) ((element)->GetType()==CElement::TEAM) -#define IS_WATER(element) ((element)->GetType()==CElement::WATER) -#define IS_WEAPON(element) ((element)->GetType()==CElement::WEAPON) +#define IS_PICKUP(element) ((element)->GetType() == CElement::PICKUP) +#define IS_PED(element) ((element)->GetType() == CElement::PLAYER || (element)->GetType() == CElement::PED) +#define IS_PLAYER(element) ((element)->GetType() == CElement::PLAYER) +#define IS_RADAR_AREA(element) ((element)->GetType() == CElement::RADAR_AREA) +#define IS_VEHICLE(element) ((element)->GetType() == CElement::VEHICLE) +#define IS_CONSOLE(element) ((element)->GetType() == CElement::CONSOLE) +#define IS_TEAM(element) ((element)->GetType() == CElement::TEAM) +#define IS_WATER(element) ((element)->GetType() == CElement::WATER) +#define IS_WEAPON(element) ((element)->GetType() == CElement::WEAPON) class CLuaMain; @@ -83,7 +84,7 @@ class CElement ROOT, UNKNOWN, BUILDING, - _POINTLIGHTS, // client only + _POINTLIGHTS, // client only }; public: @@ -97,7 +98,7 @@ class CElement void SetIsBeingDeleted(bool bBeingDeleted) { m_bIsBeingDeleted = bBeingDeleted; }; virtual void Unlink() = 0; - ElementID GetID() { return m_ID; }; + ElementID GetID() const { return m_ID; }; virtual const CVector& GetPosition(); virtual void SetPosition(const CVector& vecPosition); @@ -138,15 +139,16 @@ class CElement void ReadCustomData(CEvents* pEvents, CXMLNode& Node); CCustomData& GetCustomDataManager() { return m_CustomData; } - CLuaArgument* GetCustomData(const char* szName, bool bInheritData, ESyncType* pSyncType = nullptr, eCustomDataClientTrust* clientChangesMode = nullptr); + CLuaArgument* GetCustomData(const CStringName& name, bool bInheritData, ESyncType* pSyncType = nullptr, + eCustomDataClientTrust* clientChangesMode = nullptr); CLuaArguments* GetAllCustomData(CLuaArguments* table); - bool GetCustomDataString(const char* szName, char* pOut, size_t sizeBuffer, bool bInheritData); - bool GetCustomDataInt(const char* szName, int& iOut, bool bInheritData); - bool GetCustomDataFloat(const char* szName, float& fOut, bool bInheritData); - bool GetCustomDataBool(const char* szName, bool& bOut, bool bInheritData); - void SetCustomData(const char* szName, const CLuaArgument& Variable, ESyncType syncType = ESyncType::BROADCAST, CPlayer* pClient = NULL, + bool GetCustomDataString(const CStringName& name, char* pOut, size_t sizeBuffer, bool bInheritData); + bool GetCustomDataInt(const CStringName& name, int& iOut, bool bInheritData); + bool GetCustomDataFloat(const CStringName& name, float& fOut, bool bInheritData); + bool GetCustomDataBool(const CStringName& name, bool& bOut, bool bInheritData); + bool SetCustomData(const CStringName& name, const CLuaArgument& Variable, ESyncType syncType = ESyncType::BROADCAST, CPlayer* pClient = NULL, bool bTriggerEvent = true); - void DeleteCustomData(const char* szName); + bool DeleteCustomData(const CStringName& name); void SendAllCustomData(CPlayer* pPlayer); CXMLNode* OutputToXML(CXMLNode* pNode); @@ -175,7 +177,7 @@ class CElement void OnSubtreeAdd(CElement* pElement); void OnSubtreeRemove(CElement* pElement); - virtual void UpdatePerPlayer(){}; + virtual void UpdatePerPlayer() {}; void UpdatePerPlayerEntities(); void AddCollision(class CColShape* pShape) { m_Collisions.push_back(pShape); } @@ -289,8 +291,8 @@ class CElement bool m_bDoubleSided; bool m_bUpdatingSpatialData; bool m_bCallPropagationEnabled; - bool m_canBeDestroyedByScript = true; // If true, destroyElement function will - // have no effect on this element + bool m_canBeDestroyedByScript = true; // If true, destroyElement function will + // have no effect on this element // Optimization for getElementsByType starting at root public: static void StartupEntitiesFromRoot(); diff --git a/Server/mods/deathmatch/logic/CElementRefManager.cpp b/Server/mods/deathmatch/logic/CElementRefManager.cpp index 54a6a9ca9df..7388f49aad2 100644 --- a/Server/mods/deathmatch/logic/CElementRefManager.cpp +++ b/Server/mods/deathmatch/logic/CElementRefManager.cpp @@ -139,11 +139,11 @@ void CElementRefManager::OnElementDelete(CElement* pElement) { // NULL invalid pointer pOther = NULL; - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG SString* pstrDebugInfo = MapFind(ms_ElementRefListDebugInfo, &pOther); assert(pstrDebugInfo); OutputDebugLine(SString("[ElementRef] Did null %s (%08x @ %08x)", **pstrDebugInfo, pElement, &pOther)); - #endif +#endif } } } @@ -164,11 +164,11 @@ void CElementRefManager::OnElementDelete(CElement* pElement) { // Remove invalid pointer from list - TODO - Think man, think itList = rList.erase(itList); - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG SString* pstrDebugInfo = MapFind(ms_ElementRefListListDebugInfo, &rList); assert(pstrDebugInfo); OutputDebugLine(SString("[ElementRef] Did list item %s (%08x @ %08x)", **pstrDebugInfo, pElement, &rList)); - #endif +#endif } else ++itList; diff --git a/Server/mods/deathmatch/logic/CElementRefManager.h b/Server/mods/deathmatch/logic/CElementRefManager.h index 9dbbca58fdf..23cb4503706 100644 --- a/Server/mods/deathmatch/logic/CElementRefManager.h +++ b/Server/mods/deathmatch/logic/CElementRefManager.h @@ -11,11 +11,9 @@ #pragma once #ifdef MTA_DEBUG - #define ELEMENT_REF_DEBUG( ptr, desc ) \ - SString ( "%p %s", ptr, desc ) + #define ELEMENT_REF_DEBUG(ptr, desc) SString("%p %s", ptr, desc) #else - #define ELEMENT_REF_DEBUG( ptr, desc ) \ - NULL + #define ELEMENT_REF_DEBUG(ptr, desc) NULL #endif class CElement; diff --git a/Server/mods/deathmatch/logic/CEvents.cpp b/Server/mods/deathmatch/logic/CEvents.cpp index eb82ea1e092..411822ccadc 100644 --- a/Server/mods/deathmatch/logic/CEvents.cpp +++ b/Server/mods/deathmatch/logic/CEvents.cpp @@ -123,38 +123,68 @@ void CEvents::RemoveAllEvents() m_EventHashMap.clear(); } -void CEvents::PreEventPulse() +void CEvents::PreEventPulse(CEventContext* pContext) { + assert(pContext); + m_CancelledList.push_back(m_bEventCancelled); + m_ContextStack.push_back(pContext); + + pContext->Reset(); + m_bEventCancelled = false; m_bWasEventCancelled = false; m_strLastError = ""; } -void CEvents::PostEventPulse() +void CEvents::PostEventPulse(CEventContext* pContext) { - m_bWasEventCancelled = m_bEventCancelled; + assert(pContext); + assert(!m_ContextStack.empty()); + assert(m_ContextStack.back() == pContext); + + m_bWasEventCancelled = pContext->IsCancelled(); m_bEventCancelled = m_CancelledList.back() ? true : false; m_CancelledList.pop_back(); + m_ContextStack.pop_back(); } void CEvents::CancelEvent(bool bCancelled) { - m_bEventCancelled = bCancelled; + CancelEvent(bCancelled, nullptr); } void CEvents::CancelEvent(bool bCancelled, const char* szReason) { + // ALWAYS set the old global variable for backward compatibility m_bEventCancelled = bCancelled; - m_strLastError = SStringX(szReason); + + // Also update context if it exists + if (!m_ContextStack.empty()) + { + CEventContext* pCurrentContext = m_ContextStack.back(); + if (bCancelled) + pCurrentContext->Cancel(szReason); + else + pCurrentContext->Reset(); + } + + if (szReason) + m_strLastError = szReason; } bool CEvents::WasEventCancelled() { - return m_bWasEventCancelled; + if (!m_ContextStack.empty()) + return m_ContextStack.back()->IsCancelled(); + + return m_bEventCancelled || m_bWasEventCancelled; } const char* CEvents::GetLastError() { + if (!m_ContextStack.empty()) + return m_ContextStack.back()->GetCancelReason().c_str(); + return m_strLastError; } diff --git a/Server/mods/deathmatch/logic/CEvents.h b/Server/mods/deathmatch/logic/CEvents.h index f15a112eb23..adb3b57e179 100644 --- a/Server/mods/deathmatch/logic/CEvents.h +++ b/Server/mods/deathmatch/logic/CEvents.h @@ -14,6 +14,7 @@ #include #include #include +#include "CEventContext.h" struct SEvent { @@ -40,8 +41,8 @@ class CEvents CFastHashMap::const_iterator IterBegin() { return m_EventHashMap.begin(); }; CFastHashMap::const_iterator IterEnd() { return m_EventHashMap.end(); }; - void PreEventPulse(); - void PostEventPulse(); + void PreEventPulse(CEventContext* pContext); + void PostEventPulse(CEventContext* pContext); void CancelEvent(bool bCancelled = true); void CancelEvent(bool bCancelled, const char* szReason); @@ -56,6 +57,7 @@ class CEvents std::vector m_CancelledList; bool m_bEventCancelled; bool m_bWasEventCancelled; + SString m_strLastError; - SString m_strLastError; + std::vector m_ContextStack; }; diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index 873a9f71695..2902c106f55 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -11,6 +11,12 @@ #include "StdInc.h" #include "CGame.h" + +#ifdef WIN32 + #include +#else + #include +#endif #include "CAccessControlListManager.h" #include "ASE.h" #include "CPerfStatManager.h" @@ -45,6 +51,7 @@ #include "CRegistryManager.h" #include "CLatentTransferManager.h" #include "CCommandFile.h" +#include "CWeaponNames.h" #include "packets/CVoiceEndPacket.h" #include "packets/CEntityAddPacket.h" #include "packets/CUpdateInfoPacket.h" @@ -78,8 +85,7 @@ #define MAX_EXPLOSION_SYNC_DISTANCE 400.0f #define MAX_PROJECTILE_SYNC_DISTANCE 400.0f -#define RELEASE_MIN_CLIENT_VERSION "1.6.0-0.00000" -#define FIREBALLDESTRUCT_MIN_CLIENT_VERSION "1.6.0-9.22199" +#define RELEASE_MIN_CLIENT_VERSION "1.7.0-0.00000" #define DEFAULT_GRAVITY 0.008f #define DEFAULT_GAME_SPEED 1.0f @@ -87,6 +93,7 @@ #define DEFAULT_AIRCRAFT_MAXHEIGHT 800 #define DEFAULT_AIRCRAFT_MAXVELOCITY 1.5f #define DEFAULT_MINUTE_DURATION 1000 +#define NUM_CLIENT_EVENT_ERROR_GAP 1000 #ifndef WIN32 #include @@ -153,7 +160,7 @@ void sighandler(int sig) } #endif -CGame::CGame() : m_FloodProtect(4, 30000, 30000) // Max of 4 connections per 30 seconds, then 30 second ignore +CGame::CGame() : m_FloodProtect(4, 30000, 30000) // Max of 4 connections per 30 seconds, then 30 second ignore { // Set our global pointer g_pGame = this; @@ -422,6 +429,7 @@ CGame::~CGame() SAFE_DELETE(m_pASE); SAFE_RELEASE(m_pHqComms); CSimControl::Shutdown(); + CThreadPool::getDefaultThreadPool().shutdown(); // Clear our global pointer g_pGame = NULL; @@ -735,7 +743,7 @@ bool CGame::Start(int iArgumentCount, char* szArguments[]) if (m_pMainConfig->IsHTTPEnabled()) { // Slight hack for internal HTTPD: Listen on all IPs if multiple IPs declared - SString strUseIP = (strServerIP == strServerIPList) ? strServerIP : ""; + SString strUseIP = (strServerIP == strServerIPList) ? strServerIP : SStringX(""); if (!m_pHTTPD->StartHTTPD(strUseIP, m_pMainConfig->GetHTTPPort())) { CLogger::ErrorPrintf("Could not start HTTP server on interface '%s' and port '%u'!\n", strUseIP.c_str(), m_pMainConfig->GetHTTPPort()); @@ -837,13 +845,21 @@ bool CGame::Start(int iArgumentCount, char* szArguments[]) if (m_pMainConfig->GetAseInternetListenEnabled()) { // Check if IP is one of the most common private IP addresses - in_addr serverIp; - serverIp.s_addr = inet_addr(strServerIP); - uchar a = ((uchar*)&serverIp.s_addr)[0]; - uchar b = ((uchar*)&serverIp.s_addr)[1]; - if (a == 10 || a == 127 || (a == 169 && b == 254) || (a == 192 && b == 168)) + in_addr serverIp{}; +#ifdef WIN32 + const bool parsed = InetPtonA(AF_INET, strServerIP, &serverIp) == 1; +#else + const bool parsed = inet_pton(AF_INET, strServerIP, &serverIp) == 1; +#endif + if (parsed) { - CLogger::LogPrintf("WARNING: Private IP '%s' with ase enabled! Use: auto\n", *strServerIP); + const uint32_t hostOrder = ntohl(serverIp.s_addr); + const uchar a = (hostOrder >> 24) & 0xFF; + const uchar b = (hostOrder >> 16) & 0xFF; + if (a == 10 || a == 127 || (a == 169 && b == 254) || (a == 192 && b == 168)) + { + CLogger::LogPrintf("WARNING: Private IP '%s' with ase enabled! Use: auto\n", *strServerIP); + } } } @@ -901,7 +917,7 @@ bool CGame::Start(int iArgumentCount, char* szArguments[]) m_pResourceManager = new CResourceManager; m_pSettings = new CSettings(m_pResourceManager); if (!m_pResourceManager->Refresh()) - return false; // Load cancelled + return false; // Load cancelled m_pUnoccupiedVehicleSync = new CUnoccupiedVehicleSync(m_pPlayerManager, m_pVehicleManager); m_pPedSync = new CPedSync(m_pPlayerManager, m_pPedManager); #ifdef WITH_OBJECT_SYNC @@ -1002,7 +1018,7 @@ bool CGame::Start(int iArgumentCount, char* szArguments[]) // Now load the rest of the config if (!m_pMainConfig->LoadExtended()) - return false; // Fail or cancelled + return false; // Fail or cancelled // Is the script debug log enabled? if (m_pMainConfig->GetScriptDebugLogEnabled()) @@ -1357,11 +1373,11 @@ void CGame::JoinPlayer(CPlayer& Player) marker.Set("Start"); // Let him join - Player.Send(CPlayerJoinCompletePacket(Player.GetID(), m_pMapManager->GetRootElement()->GetID(), m_pMainConfig->GetHTTPDownloadType(), - m_pMainConfig->GetHTTPPort(), m_pMainConfig->GetHTTPDownloadURL().c_str(), - m_pMainConfig->GetHTTPMaxConnectionsPerClient(), m_pMainConfig->GetEnableClientChecks(), - m_pMainConfig->IsVoiceEnabled(), m_pMainConfig->GetVoiceSampleRate(), m_pMainConfig->GetVoiceQuality(), - m_pMainConfig->GetVoiceBitrate(), m_pMainConfig->GetServerName().c_str())); + Player.Send(CPlayerJoinCompletePacket( + Player.GetID(), m_pMapManager->GetRootElement()->GetID(), m_pMainConfig->GetHTTPDownloadType(), m_pMainConfig->GetHTTPPort(), + m_pMainConfig->GetHTTPDownloadURL().c_str(), m_pMainConfig->GetHTTPMaxConnectionsPerClient(), m_pMainConfig->GetEnableClientChecks(), + m_pMainConfig->IsVoiceEnabled(), static_cast(m_pMainConfig->GetVoiceSampleRate()), + static_cast(m_pMainConfig->GetVoiceQuality()), m_pMainConfig->GetVoiceBitrate(), m_pMainConfig->GetServerName().c_str())); marker.Set("CPlayerJoinCompletePacket"); @@ -1411,7 +1427,7 @@ void CGame::InitialDataStream(CPlayer& Player) marker.Set("PlayerNotice"); // Tell the map manager - m_pMapManager->OnPlayerJoin(Player); // This sends the elements that are needed before the resources start + m_pMapManager->OnPlayerJoin(Player); // This sends the elements that are needed before the resources start marker.Set("SendMapElements"); @@ -1553,6 +1569,9 @@ void CGame::QuitPlayer(CPlayer& Player, CClient::eQuitReasons Reason, bool bSayI Player.CallEvent("onPlayerQuit", Arguments); + // Tell the resource manager + m_pResourceManager->OnPlayerQuit(Player); + // Tell the map manager m_pMapManager->OnPlayerQuit(Player); @@ -1669,6 +1688,9 @@ void CGame::AddBuiltInEvents() m_Events.AddEvent("onElementModelChange", "oldModel, newModel", NULL, false); m_Events.AddEvent("onElementDimensionChange", "oldDimension, newDimension", nullptr, false); m_Events.AddEvent("onElementInteriorChange", "oldInterior, newInterior", nullptr, false); + m_Events.AddEvent("onElementAttach", "attachSource, attachOffsetX, attachOffsetY, attachOffsetZ, attachOffsetRX, attachOffsetRY, attachOffsetRZ", nullptr, + false); + m_Events.AddEvent("onElementDetach", "detachSource, detachWorldX, detachWorldY, detachWorldZ, detachWorldRX, detachWorldRY, detachWorldRZ", nullptr, false); // Radar area events @@ -1699,7 +1721,7 @@ void CGame::AddBuiltInEvents() // Account events m_Events.AddEvent("onAccountDataChange", "account, key, value", NULL, false); - + m_Events.AddEvent("onAccountNameChange", "account, previousName, newName", nullptr, false); m_Events.AddEvent("onAccountCreate", "account", NULL, false); m_Events.AddEvent("onAccountRemove", "account", NULL, false); @@ -1720,15 +1742,15 @@ void CGame::ProcessTrafficLights(long long llCurrentTime) if (ulDiff >= 1000) { - if ((m_ucTrafficLightState == 0 || m_ucTrafficLightState == 3) && ulDiff >= 8000) // green + if ((m_ucTrafficLightState == 0 || m_ucTrafficLightState == 3) && ulDiff >= 8000) // green { ucNewState = m_ucTrafficLightState + 1; } - else if ((m_ucTrafficLightState == 1 || m_ucTrafficLightState == 4) && ulDiff >= 3000) // orange + else if ((m_ucTrafficLightState == 1 || m_ucTrafficLightState == 4) && ulDiff >= 3000) // orange { ucNewState = (m_ucTrafficLightState == 4) ? 0 : 2; } - else if (m_ucTrafficLightState == 2 && ulDiff >= 2000) // red + else if (m_ucTrafficLightState == 2 && ulDiff >= 2000) // red { ucNewState = 3; } @@ -1847,11 +1869,7 @@ void CGame::Packet_PlayerJoinData(CPlayerJoinDataPacket& Packet) CLogger::LogPrintf("CONNECT: %s failed to connect (Serial already in use) (%s)\n", szNick, strIPAndSerial.c_str()); // Tell the player the problem - if (pPlayer->CanBitStream(eBitStreamVersion::CheckDuplicateSerials)) - DisconnectPlayer(this, *pPlayer, CPlayerDisconnectedPacket::SERIAL_DUPLICATE); - else - DisconnectPlayer(this, *pPlayer, CPlayerDisconnectedPacket::KICK); - + DisconnectPlayer(this, *pPlayer, CPlayerDisconnectedPacket::SERIAL_DUPLICATE); return; } @@ -1903,7 +1921,6 @@ void CGame::Packet_PlayerJoinData(CPlayerJoinDataPacket& Packet) pPlayer->SetNick(szNick); pPlayer->SetGameVersion(Packet.GetGameVersion()); pPlayer->SetMTAVersion(Packet.GetMTAVersion()); - pPlayer->SetSerialUser(Packet.GetSerialUser()); pPlayer->SetSerial(strSerial, 0); pPlayer->SetSerial(strExtra, 1); pPlayer->SetPlayerVersion(strPlayerVersion); @@ -1955,7 +1972,7 @@ void CGame::Packet_PlayerJoinData(CPlayerJoinDataPacket& Packet) if (CBan* pBan = m_pBanManager->GetBanFromIP(strIP)) { time_t Duration = pBan->GetBanTimeRemaining(); - SString strBanMessage; // = "Serial is banned"; + SString strBanMessage; // = "Serial is banned"; SString strDurationDesc = pBan->GetDurationDesc(); if (strDurationDesc.length()) strBanMessage += " (" + strDurationDesc + ")"; @@ -1969,25 +1986,6 @@ void CGame::Packet_PlayerJoinData(CPlayerJoinDataPacket& Packet) return; } - if (!pPlayer->GetSerialUser().empty() && m_pBanManager->IsAccountBanned(pPlayer->GetSerialUser().c_str())) - { - // Tell the console - CLogger::LogPrintf("CONNECT: %s failed to connect (Account is banned) (%s)\n", szNick, strIPAndSerial.c_str()); - - CBan* pBan = m_pBanManager->GetBanFromAccount(pPlayer->GetSerialUser().c_str()); - time_t Duration = 0; - SString strReason; - if (pBan) - { - strReason = pBan->GetReason(); - Duration = pBan->GetBanTimeRemaining(); - } - - // Tell the player he's banned - DisconnectPlayer(this, *pPlayer, CPlayerDisconnectedPacket::BANNED_ACCOUNT, Duration, strReason.c_str()); - return; - } - #if MTASA_VERSION_TYPE > VERSION_TYPE_UNSTABLE if (Packet.GetPlayerVersion().length() > 0 && Packet.GetPlayerVersion() != pPlayer->GetPlayerVersion()) { @@ -2131,7 +2129,7 @@ void CGame::Packet_PedWasted(CPedWastedPacket& Packet) pPed->CallEvent("onPedWasted", Arguments); // Reset the weapons list, because a ped loses his weapons on death - for (unsigned int slot = 0; slot < WEAPON_SLOTS; ++slot) + for (unsigned char slot = 0; slot < WEAPON_SLOTS; ++slot) { pPed->SetWeaponType(0, slot); pPed->SetWeaponAmmoInClip(0, slot); @@ -2193,7 +2191,7 @@ void CGame::Packet_PlayerWasted(CPlayerWastedPacket& Packet) pPlayer->CallEvent("onPlayerWasted", Arguments); // Reset the weapons list, because a player loses his weapons on death - for (unsigned int slot = 0; slot < WEAPON_SLOTS; ++slot) + for (unsigned char slot = 0; slot < WEAPON_SLOTS; ++slot) { pPlayer->SetWeaponType(0, slot); pPlayer->SetWeaponAmmoInClip(0, slot); @@ -2271,7 +2269,7 @@ void CGame::RelayPlayerPuresync(CPacket& Packet) SViewerMapType& nearList = pPlayer->GetNearPlayerList(); // Array for holding players that need moving to the puresync far list - static std::vector moveToFarListList; // static to help reduce memory allocations + static std::vector moveToFarListList; // static to help reduce memory allocations moveToFarListList.clear(); // For each puresync near player @@ -2285,7 +2283,7 @@ void CGame::RelayPlayerPuresync(CPacket& Packet) { // Remove player from puresync near list (Has to be not near for 5 calls to get removed (The delay ensures timely updates of players moving far // away)) - if (!pPlayer->ShouldPlayerBeInNearList(pSendPlayer)) // Double check remove is required. + if (!pPlayer->ShouldPlayerBeInNearList(pSendPlayer)) // Double check remove is required. { moveToFarListList.push_back(pSendPlayer); continue; @@ -2463,7 +2461,7 @@ void CGame::Packet_VehicleDamageSync(CVehicleDamageSyncPacket& Packet) if (pOther->GetDimension() == pPlayer->GetDimension()) { // Newer clients only need sync if vehicle has no driver - if (pOther->GetBitStreamVersion() < 0x5D || pVehicle->GetOccupant(0) == NULL) + if (pVehicle->GetOccupant(0) == nullptr) { sendList.push_back(pOther); } @@ -2527,59 +2525,80 @@ void CGame::Packet_Keysync(CKeysyncPacket& Packet) } } -void CGame::Packet_Bulletsync(CBulletsyncPacket& Packet) +void CGame::Packet_Bulletsync(CBulletsyncPacket& packet) { - // Grab the source player - CPlayer* pPlayer = Packet.GetSourcePlayer(); - if (pPlayer && pPlayer->IsJoined()) - { - // Early return when the player attempts to fire a weapon they do not have - if (!pPlayer->HasWeaponType(Packet.m_WeaponType)) - return; + auto* player = packet.GetSourcePlayer(); + if (!player || !player->IsJoined()) + return; - // Relay to other players - RelayNearbyPacket(Packet); + const auto type = static_cast(packet.m_weapon); + if (!player->HasWeaponType(type)) + return; - // Call event - CLuaArguments Arguments; - Arguments.PushNumber(Packet.m_WeaponType); - Arguments.PushNumber(Packet.m_vecEnd.fX); - Arguments.PushNumber(Packet.m_vecEnd.fY); - Arguments.PushNumber(Packet.m_vecEnd.fZ); + const auto slot = CWeaponNames::GetSlotFromWeapon(type); + if (player->GetWeaponTotalAmmo(slot) <= 0) + return; - if (Packet.m_DamagedPlayerID == INVALID_ELEMENT_ID) - { - Arguments.PushNil(); - } - else - { - Arguments.PushElement(CElementIDs::GetElement(Packet.m_DamagedPlayerID)); - } + // Note: Don't check ammo in clip here - it can be out of sync due to network timing + // The total ammo check above is sufficient - Arguments.PushNumber(Packet.m_vecStart.fX); - Arguments.PushNumber(Packet.m_vecStart.fY); - Arguments.PushNumber(Packet.m_vecStart.fZ); - pPlayer->CallEvent("onPlayerWeaponFire", Arguments); - } + const auto stat = CWeaponStatManager::GetSkillStatIndex(packet.m_weapon); + const auto level = player->GetPlayerStat(stat); + auto* stats = g_pGame->GetWeaponStatManager()->GetWeaponStatsFromSkillLevel(packet.m_weapon, level); + + const float distanceSq = (packet.m_start - packet.m_end).LengthSquared(); + const float range = stats->GetWeaponRange(); + const float rangeSq = range * range; + + const float maxRangeSq = rangeSq * 1.1f; // 10% tolerance for floating point + if (distanceSq > maxRangeSq) + return; + + CLuaArguments args; + args.PushNumber(packet.m_weapon); + args.PushNumber(packet.m_end.fX); + args.PushNumber(packet.m_end.fY); + args.PushNumber(packet.m_end.fZ); + + if (packet.m_damaged == INVALID_ELEMENT_ID) + args.PushNil(); + else + args.PushElement(CElementIDs::GetElement(packet.m_damaged)); + + args.PushNumber(packet.m_start.fX); + args.PushNumber(packet.m_start.fY); + args.PushNumber(packet.m_start.fZ); + + player->CallEvent("onPlayerWeaponFire", args); + + // Sim sync only relays bullet packets to zone-0 viewers. Relay to the rest of the + // near list here so zone-1/2 observers still receive long-range bullet sync. + RelayNearbyPacket(packet); } -void CGame::Packet_WeaponBulletsync(CCustomWeaponBulletSyncPacket& Packet) +void CGame::Packet_WeaponBulletsync(CCustomWeaponBulletSyncPacket& packet) { - // Grab the source player - CPlayer* pPlayer = Packet.GetSourcePlayer(); - CCustomWeapon* pWeapon = Packet.GetWeapon(); - if (pPlayer && pPlayer->IsJoined() && pPlayer == Packet.GetWeaponOwner()) - { - // Tell our scripts the player has fired - CLuaArguments Arguments; - Arguments.PushElement(pPlayer); + auto* player = packet.GetSourcePlayer(); + if (!player || !player->IsJoined()) + return; - if (pWeapon->CallEvent("onWeaponFire", Arguments)) - { - // Relay to other players - m_pPlayerManager->BroadcastOnlyJoined(Packet, pPlayer); - } - } + if (player != packet.GetWeaponOwner()) + return; + + auto* weapon = packet.GetWeapon(); + if (weapon->GetAmmo() <= 0) + return; + + if (weapon->GetClipAmmo() <= 0) + return; + + CLuaArguments args; + args.PushElement(player); + + if (!weapon->CallEvent("onWeaponFire", args)) + return; + + m_pPlayerManager->BroadcastOnlyJoined(packet, player); } void CGame::Packet_PedTask(CPedTaskPacket& Packet) @@ -2670,9 +2689,13 @@ void CGame::Packet_LuaEvent(CLuaEventPacket& Packet) m_pScriptDebugging->LogError(NULL, "Client (%s) triggered serverside event %s, but event is not marked as remotely triggerable", pCaller->GetNick(), szName); } - } - else + else + { + // Limit this error to prevent debug / log files being flooded. + static std::uint64_t s_lastClientEventErrorLog = 0; + auto now = GetTickCount64_(); + if (now - s_lastClientEventErrorLog > NUM_CLIENT_EVENT_ERROR_GAP) { CLuaArguments arguments; arguments.PushString(szName); @@ -2680,7 +2703,9 @@ void CGame::Packet_LuaEvent(CLuaEventPacket& Packet) arguments.PushBoolean(false); pCaller->CallEvent("onPlayerTriggerInvalidEvent", arguments); m_pScriptDebugging->LogError(NULL, "Client (%s) triggered serverside event %s, but event is not added serverside", pCaller->GetNick(), szName); + s_lastClientEventErrorLog = now; } + } RegisterClientTriggeredEventUsage(pCaller, szName); } @@ -2704,12 +2729,12 @@ void CGame::Packet_CustomData(CCustomDataPacket& Packet) // Ignore if the wrong length if (strlen(szName) > MAX_CUSTOMDATA_NAME_LENGTH) { - CLogger::ErrorPrintf("Received oversized custom data name from %s (%s)", Packet.GetSourcePlayer()->GetNick(), + CLogger::ErrorPrintf("Received oversized custom data name from %s (%s)\n", Packet.GetSourcePlayer()->GetNick(), *SStringX(szName).Left(MAX_CUSTOMDATA_NAME_LENGTH + 1)); return; } - ESyncType lastSyncType = ESyncType::BROADCAST; + ESyncType lastSyncType = ESyncType::BROADCAST; eCustomDataClientTrust clientChangesMode{}; pElement->GetCustomData(szName, false, &lastSyncType, &clientChangesMode); @@ -2718,8 +2743,7 @@ void CGame::Packet_CustomData(CCustomDataPacket& Packet) : clientChangesMode == eCustomDataClientTrust::ALLOW; if (!changesAllowed) { - CLogger::ErrorPrintf("Client trying to change protected element data %s (%s)", Packet.GetSourcePlayer()->GetNick(), - szName); + CLogger::ErrorPrintf("Client trying to change protected element data %s (%s)\n", Packet.GetSourcePlayer()->GetNick(), szName); CLuaArguments arguments; arguments.PushElement(pElement); @@ -2729,25 +2753,45 @@ void CGame::Packet_CustomData(CCustomDataPacket& Packet) return; } - if (lastSyncType != ESyncType::LOCAL) + if (pElement->SetCustomData(szName, Value, lastSyncType, pSourcePlayer)) { - // Tell our clients to update their data. Send to everyone but the one we got this packet from. + if (lastSyncType != ESyncType::LOCAL) + { + // Tell our clients to update their data. Send to everyone but the one we got this packet from. + unsigned short usNameLength = static_cast(strlen(szName)); + CBitStream BitStream; + BitStream.pBitStream->WriteCompressed(usNameLength); + BitStream.pBitStream->Write(szName, usNameLength); + Value.WriteToBitStream(*BitStream.pBitStream); + if (lastSyncType == ESyncType::BROADCAST) + m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream), pSourcePlayer); + else + m_pPlayerManager->BroadcastOnlySubscribed(CElementRPCPacket(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream), pElement, szName, + pSourcePlayer); + + CPerfStatEventPacketUsage::GetSingleton()->UpdateElementDataUsageRelayed(szName, m_pPlayerManager->Count(), + BitStream.pBitStream->GetNumberOfBytesUsed()); + } + } + else + { + // Event was cancelled; sync the authoritative value back to the source player unsigned short usNameLength = static_cast(strlen(szName)); CBitStream BitStream; BitStream.pBitStream->WriteCompressed(usNameLength); BitStream.pBitStream->Write(szName, usNameLength); - Value.WriteToBitStream(*BitStream.pBitStream); - if (lastSyncType == ESyncType::BROADCAST) - m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream), pSourcePlayer); - else - m_pPlayerManager->BroadcastOnlySubscribed(CElementRPCPacket(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream), pElement, szName, - pSourcePlayer); - CPerfStatEventPacketUsage::GetSingleton()->UpdateElementDataUsageRelayed(szName, m_pPlayerManager->Count(), - BitStream.pBitStream->GetNumberOfBytesUsed()); + if (CLuaArgument* pServerValue = pElement->GetCustomData(szName, false)) + { + pServerValue->WriteToBitStream(*BitStream.pBitStream); + pSourcePlayer->Send(CElementRPCPacket(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream)); + } + else + { + BitStream.pBitStream->WriteBit(false); + pSourcePlayer->Send(CElementRPCPacket(pElement, REMOVE_ELEMENT_DATA, *BitStream.pBitStream)); + } } - - pElement->SetCustomData(szName, Value, lastSyncType, pSourcePlayer); } } } @@ -2920,23 +2964,23 @@ void CGame::Packet_ProjectileSync(CProjectileSyncPacket& Packet) } CLuaArguments arguments; - arguments.PushNumber(Packet.m_ucWeaponType); // "weaponType" - arguments.PushNumber(vecPosition.fX); // "posX" - arguments.PushNumber(vecPosition.fY); // "posY" - arguments.PushNumber(vecPosition.fZ); // "posZ" - arguments.PushNumber(Packet.m_fForce); // "force" + arguments.PushNumber(Packet.m_ucWeaponType); // "weaponType" + arguments.PushNumber(vecPosition.fX); // "posX" + arguments.PushNumber(vecPosition.fY); // "posY" + arguments.PushNumber(vecPosition.fZ); // "posZ" + arguments.PushNumber(Packet.m_fForce); // "force" CElement* pTarget = nullptr; if (Packet.m_bHasTarget && Packet.m_TargetID != INVALID_ELEMENT_ID) pTarget = CElementIDs::GetElement(Packet.m_TargetID); - arguments.PushElement(pTarget); // "target" - arguments.PushNumber(Packet.m_vecRotation.fX); // "rotX" - arguments.PushNumber(Packet.m_vecRotation.fY); // "rotY" - arguments.PushNumber(Packet.m_vecRotation.fZ); // "rotZ" - arguments.PushNumber(Packet.m_vecMoveSpeed.fX); // "velX" - arguments.PushNumber(Packet.m_vecMoveSpeed.fY); // "velY" - arguments.PushNumber(Packet.m_vecMoveSpeed.fZ); // "velZ" + arguments.PushElement(pTarget); // "target" + arguments.PushNumber(Packet.m_vecRotation.fX); // "rotX" + arguments.PushNumber(Packet.m_vecRotation.fY); // "rotY" + arguments.PushNumber(Packet.m_vecRotation.fZ); // "rotZ" + arguments.PushNumber(Packet.m_vecMoveSpeed.fX); // "velX" + arguments.PushNumber(Packet.m_vecMoveSpeed.fY); // "velY" + arguments.PushNumber(Packet.m_vecMoveSpeed.fZ); // "velZ" // Trigger Lua event and see if we are allowed to continue if (!pPlayer->CallEvent("onPlayerProjectileCreation", arguments)) @@ -2984,10 +3028,9 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) CElement* pPedElement = CElementIDs::GetElement(PedID); if (pPedElement && IS_PED(pPedElement)) { - CPed* pPed = static_cast(pPedElement); - bool bValidPed = false; - bool bValidVehicle = false; - CSendList sendListIncompatiblePlayers; + CPed* pPed = static_cast(pPedElement); + bool bValidPed = false; + bool bValidVehicle = false; // Grab the vehicle with the chosen ID ElementID VehicleID = Packet.GetVehicleID(); @@ -3014,31 +3057,6 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) { bValidPed = true; } - switch (ucAction) - { - // Check if we are finishing a jacking sequence - case VEHICLE_NOTIFY_JACK: - case VEHICLE_NOTIFY_JACK_ABORT: - { - // Are we jacking a ped? - CPed* pJacked = pVehicle->GetOccupant(0); - if (pJacked && !pJacked->IsPlayer()) - { - // Check that all clients have a compatible bitstream - for (auto iter = m_pPlayerManager->IterBegin(); iter != m_pPlayerManager->IterEnd(); iter++) - { - CPlayer* pSendPlayer = *iter; - if (!pSendPlayer->CanBitStream(eBitStreamVersion::PedEnterExit)) - { - if (pSendPlayer->IsJoined()) - // Store this player as incompatible for later - // This happens because the player joined during a player jacking a ped - sendListIncompatiblePlayers.push_back(pSendPlayer); - } - } - } - } - } } else { @@ -3046,34 +3064,6 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) if (pPed->GetSyncer() == pPlayer) { bValidPed = true; - - // Check that all clients have a compatible bitstream when we have a ped enter/exit - for (auto iter = m_pPlayerManager->IterBegin(); iter != m_pPlayerManager->IterEnd(); iter++) - { - CPlayer* pSendPlayer = *iter; - if (!pSendPlayer->CanBitStream(eBitStreamVersion::PedEnterExit)) - { - switch (ucAction) - { - // Is he requesting to start enter/exit then reject it - case VEHICLE_REQUEST_IN: - case VEHICLE_REQUEST_OUT: - case VEHICLE_NOTIFY_FELL_OFF: - { - bValidPed = false; - break; - } - // Otherwise allow it to move on - default: - { - if (pSendPlayer->IsJoined()) - // Store this player as incompatible for later - // This happens because the player joined during a ped enter/exit - sendListIncompatiblePlayers.push_back(pSendPlayer); - } - } - } - } } } } @@ -3130,7 +3120,7 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) bWarpIn = true; } if (usVehicleModel == VT_RCBARON) - { // warp in for rc baron. + { // warp in for rc baron. fCutoffDistance = 10.0f; bWarpIn = true; } @@ -3164,10 +3154,10 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Call the entering vehicle event CLuaArguments Arguments; - Arguments.PushElement(pPed); // player / ped - Arguments.PushNumber(0); // seat - Arguments.PushBoolean(false); // jacked - Arguments.PushNumber(ucDoor); // Door + Arguments.PushElement(pPed); // player / ped + Arguments.PushNumber(0); // seat + Arguments.PushBoolean(false); // jacked + Arguments.PushNumber(ucDoor); // Door if (pVehicle->CallEvent("onVehicleStartEnter", Arguments)) { // HACK?: check the ped's vehicle-action is still the same (not warped in?) @@ -3221,26 +3211,8 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) } else { - bool bValidOccupant = false; // Is the jacked ped stationary in the car (ie not getting in or out) - if (IS_PED(pOccupant) && pOccupant->GetVehicleAction() == CPed::VEHICLEACTION_NONE) - { - bValidOccupant = true; - // Check if we are jacking a ped - if (!IS_PLAYER(pOccupant)) - { - // Check that all clients have a compatible bitstream - for (auto iter = m_pPlayerManager->IterBegin(); iter != m_pPlayerManager->IterEnd(); iter++) - { - CPlayer* pSendPlayer = *iter; - if (!pSendPlayer->CanBitStream(eBitStreamVersion::PedEnterExit)) - { - bValidOccupant = false; - break; - } - } - } - } + bool bValidOccupant = (IS_PED(pOccupant) && pOccupant->GetVehicleAction() == CPed::VEHICLEACTION_NONE); if (bValidOccupant) { @@ -3252,10 +3224,10 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Call the entering vehicle event CLuaArguments EnterArguments; - EnterArguments.PushElement(pPed); // player / ped - EnterArguments.PushNumber(0); // seat - EnterArguments.PushElement(pOccupant); // jacked - EnterArguments.PushNumber(ucDoor); // Door + EnterArguments.PushElement(pPed); // player / ped + EnterArguments.PushNumber(0); // seat + EnterArguments.PushElement(pOccupant); // jacked + EnterArguments.PushNumber(ucDoor); // Door if (pVehicle->CallEvent("onVehicleStartEnter", EnterArguments)) { // HACK?: check the peds vehicle-action is still the same (not warped in?) @@ -3263,9 +3235,9 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) { // Call the exiting vehicle event CLuaArguments ExitArguments; - ExitArguments.PushElement(pOccupant); // player / ped - ExitArguments.PushNumber(ucSeat); // seat - ExitArguments.PushElement(pPed); // jacker + ExitArguments.PushElement(pOccupant); // player / ped + ExitArguments.PushNumber(ucSeat); // seat + ExitArguments.PushElement(pPed); // jacker if (pVehicle->CallEvent("onVehicleStartExit", ExitArguments)) { // HACK?: check the player's vehicle-action is still the same (not warped out?) @@ -3314,10 +3286,10 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Call the entering vehicle event CLuaArguments Arguments; - Arguments.PushElement(pPed); // player / ped - Arguments.PushNumber(ucSeat); // seat - Arguments.PushBoolean(false); // jacked - Arguments.PushNumber(ucDoor); // Door + Arguments.PushElement(pPed); // player / ped + Arguments.PushNumber(ucSeat); // seat + Arguments.PushBoolean(false); // jacked + Arguments.PushNumber(ucDoor); // Door if (pVehicle->CallEvent("onVehicleStartEnter", Arguments)) { // HACK?: check the player's vehicle-action is still the same (not warped in?) @@ -3402,9 +3374,12 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Is he entering? if (pPed->GetVehicleAction() == CPed::VEHICLEACTION_ENTERING) { - // Is he the occupant? (he must unless the client has fucked up) - unsigned char ucOccupiedSeat = pPed->GetOccupiedVehicleSeat(); - if (pPed == pVehicle->GetOccupant(ucOccupiedSeat)) + const unsigned int uiOccupiedSeat = pPed->GetOccupiedVehicleSeat(); + if (uiOccupiedSeat > 0xFF) + break; + + const unsigned char occupiedSeat = static_cast(uiOccupiedSeat); + if (pPed == pVehicle->GetOccupant(occupiedSeat)) { // Mark him as successfully entered pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE); @@ -3414,14 +3389,14 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) pVehicle->SetEngineOn(true); // Tell everyone he's in (they should warp him in) - CVehicleInOutPacket Reply(PedID, VehicleID, ucOccupiedSeat, VEHICLE_NOTIFY_IN_RETURN); + CVehicleInOutPacket Reply(PedID, VehicleID, static_cast(occupiedSeat), VEHICLE_NOTIFY_IN_RETURN); m_pPlayerManager->BroadcastOnlyJoined(Reply); // Call the player->vehicle event CLuaArguments Arguments; - Arguments.PushElement(pVehicle); // vehicle - Arguments.PushNumber(ucOccupiedSeat); // seat - Arguments.PushBoolean(false); // jacked + Arguments.PushElement(pVehicle); // vehicle + Arguments.PushNumber(occupiedSeat); // seat + Arguments.PushBoolean(false); // jacked if (pPed->IsPlayer()) pPed->CallEvent("onPlayerVehicleEnter", Arguments); else @@ -3429,9 +3404,9 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Call the vehicle->player event CLuaArguments Arguments2; - Arguments2.PushElement(pPed); // player / ped - Arguments2.PushNumber(ucOccupiedSeat); // seat - Arguments2.PushBoolean(false); // jacked + Arguments2.PushElement(pPed); // player / ped + Arguments2.PushNumber(occupiedSeat); // seat + Arguments2.PushBoolean(false); // jacked pVehicle->CallEvent("onVehicleEnter", Arguments2); } } @@ -3446,8 +3421,8 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) if (pPed->GetVehicleAction() == CPed::VEHICLEACTION_ENTERING) { // Is he the occupant? (he must unless the client has fucked up) - unsigned char ucOccupiedSeat = pPed->GetOccupiedVehicleSeat(); - if (pPed == pVehicle->GetOccupant(ucOccupiedSeat)) + unsigned int occupiedSeat = pPed->GetOccupiedVehicleSeat(); + if (pPed == pVehicle->GetOccupant(occupiedSeat)) { unsigned char ucDoor = Packet.GetDoor(); float fDoorAngle = Packet.GetDoorAngle(); @@ -3455,22 +3430,16 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Mark that he's in no vehicle pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE); pPed->SetOccupiedVehicle(NULL, 0); - pVehicle->SetOccupant(NULL, ucOccupiedSeat); + pVehicle->SetOccupant(NULL, occupiedSeat); // Update the door angle. pVehicle->SetDoorOpenRatio(ucDoor + 2, fDoorAngle); // Tell everyone he's out (they should warp him out) - CVehicleInOutPacket Reply(PedID, VehicleID, ucOccupiedSeat, VEHICLE_NOTIFY_IN_ABORT_RETURN, ucDoor); + CVehicleInOutPacket Reply(PedID, VehicleID, static_cast(occupiedSeat), VEHICLE_NOTIFY_IN_ABORT_RETURN, + ucDoor); Reply.SetDoorAngle(fDoorAngle); m_pPlayerManager->BroadcastOnlyJoined(Reply); - if (!sendListIncompatiblePlayers.empty()) - { - CBitStream BitStream; - BitStream.pBitStream->Write(pPed->GetSyncTimeContext()); - m_pPlayerManager->Broadcast(CElementRPCPacket(pPed, REMOVE_PED_FROM_VEHICLE, *BitStream.pBitStream), - sendListIncompatiblePlayers); - } } } @@ -3484,23 +3453,38 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) if (pPed->GetVehicleAction() == CPed::VEHICLEACTION_NONE) { // Does it have an occupant and is the occupant the requesting ped? - unsigned ucOccupiedSeat = pPed->GetOccupiedVehicleSeat(); - if (pPed == pVehicle->GetOccupant(ucOccupiedSeat)) + unsigned int occupiedSeat = pPed->GetOccupiedVehicleSeat(); + if (pPed == pVehicle->GetOccupant(occupiedSeat)) { + // Reset the occupant changed flag before calling the event + pVehicle->m_bOccupantChanged = false; + // Call the exiting vehicle event CLuaArguments Arguments; - Arguments.PushElement(pPed); // player / ped - Arguments.PushNumber(ucOccupiedSeat); // seat - Arguments.PushBoolean(false); // jacked - Arguments.PushNumber(Packet.GetDoor()); // door being used + Arguments.PushElement(pPed); // player / ped + Arguments.PushNumber(occupiedSeat); // seat + Arguments.PushBoolean(false); // jacked + Arguments.PushNumber(Packet.GetDoor()); // door being used if (pVehicle->CallEvent("onVehicleStartExit", Arguments) && pPed->GetOccupiedVehicle() == pVehicle) { - // Mark him as exiting the vehicle - pPed->SetVehicleAction(CPed::VEHICLEACTION_EXITING); + // Check if the occupant was changed during the event (e.g., by warpPedIntoVehicle) + if (!pVehicle->m_bOccupantChanged) + { + // Mark him as exiting the vehicle + pPed->SetVehicleAction(CPed::VEHICLEACTION_EXITING); - // Tell everyone he can start exiting the vehicle - CVehicleInOutPacket Reply(PedID, VehicleID, ucOccupiedSeat, VEHICLE_REQUEST_OUT_CONFIRMED, Packet.GetDoor()); - m_pPlayerManager->BroadcastOnlyJoined(Reply); + // Tell everyone he can start exiting the vehicle + CVehicleInOutPacket Reply(PedID, VehicleID, static_cast(occupiedSeat), VEHICLE_REQUEST_OUT_CONFIRMED, + Packet.GetDoor()); + m_pPlayerManager->BroadcastOnlyJoined(Reply); + } + else + { + // Script interfered with the exit process + // Don't proceed with the exit, send failure response + CVehicleInOutPacket Reply(PedID, VehicleID, 0, VEHICLE_ATTEMPT_FAILED); + pPlayer->Send(Reply); + } } else { @@ -3534,11 +3518,11 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) if (pPed->GetVehicleAction() == CPed::VEHICLEACTION_EXITING) { // Does it have an occupant and is the occupant the requesting ped? - unsigned char ucOccupiedSeat = pPed->GetOccupiedVehicleSeat(); - if (pPed == pVehicle->GetOccupant(ucOccupiedSeat)) + unsigned int occupiedSeat = pPed->GetOccupiedVehicleSeat(); + if (pPed == pVehicle->GetOccupant(occupiedSeat)) { // Mark the ped/vehicle as empty - pVehicle->SetOccupant(NULL, ucOccupiedSeat); + pVehicle->SetOccupant(NULL, occupiedSeat); pPed->SetOccupiedVehicle(NULL, 0); pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE); @@ -3549,23 +3533,15 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) } // Tell everyone he can start exiting the vehicle - CVehicleInOutPacket Reply(PedID, VehicleID, ucOccupiedSeat, VEHICLE_NOTIFY_OUT_RETURN); + CVehicleInOutPacket Reply(PedID, VehicleID, static_cast(occupiedSeat), VEHICLE_NOTIFY_OUT_RETURN); m_pPlayerManager->BroadcastOnlyJoined(Reply); - if (!sendListIncompatiblePlayers.empty()) - { - // Warp the ped out of the vehicle manually for incompatible players - CBitStream BitStream; - BitStream.pBitStream->Write(pPed->GetSyncTimeContext()); - m_pPlayerManager->Broadcast(CElementRPCPacket(pPed, REMOVE_PED_FROM_VEHICLE, *BitStream.pBitStream), - sendListIncompatiblePlayers); - } // Call the ped->vehicle event CLuaArguments Arguments; - Arguments.PushElement(pVehicle); // vehicle - Arguments.PushNumber(ucOccupiedSeat); // seat - Arguments.PushBoolean(false); // jacker - Arguments.PushBoolean(false); // forcedByScript + Arguments.PushElement(pVehicle); // vehicle + Arguments.PushNumber(occupiedSeat); // seat + Arguments.PushBoolean(false); // jacker + Arguments.PushBoolean(false); // forcedByScript if (pPed->IsPlayer()) pPed->CallEvent("onPlayerVehicleExit", Arguments); else @@ -3573,10 +3549,10 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Call the vehicle->player event CLuaArguments Arguments2; - Arguments2.PushElement(pPed); // player / ped - Arguments2.PushNumber(ucOccupiedSeat); // seat - Arguments2.PushBoolean(false); // jacker - Arguments2.PushBoolean(false); // forcedByScript + Arguments2.PushElement(pPed); // player / ped + Arguments2.PushNumber(occupiedSeat); // seat + Arguments2.PushBoolean(false); // jacker + Arguments2.PushBoolean(false); // forcedByScript pVehicle->CallEvent("onVehicleExit", Arguments2); } } @@ -3591,14 +3567,14 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) if (pPed->GetVehicleAction() == CPed::VEHICLEACTION_EXITING) { // Is he the occupant? - unsigned char ucOccupiedSeat = pPed->GetOccupiedVehicleSeat(); - if (pPed == pVehicle->GetOccupant(ucOccupiedSeat)) + unsigned int occupiedSeat = pPed->GetOccupiedVehicleSeat(); + if (pPed == pVehicle->GetOccupant(occupiedSeat)) { // Mark that he's no longer exiting pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE); // Tell everyone he's in (they should warp him in) - CVehicleInOutPacket Reply(PedID, VehicleID, ucOccupiedSeat, VEHICLE_NOTIFY_OUT_ABORT_RETURN); + CVehicleInOutPacket Reply(PedID, VehicleID, static_cast(occupiedSeat), VEHICLE_NOTIFY_OUT_ABORT_RETURN); m_pPlayerManager->BroadcastOnlyJoined(Reply); } } @@ -3609,12 +3585,12 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) case VEHICLE_NOTIFY_FELL_OFF: { // Check that the ped is in the given vehicle - unsigned char ucOccupiedSeat = pPed->GetOccupiedVehicleSeat(); - if (pVehicle->GetOccupant(ucOccupiedSeat) == pPed) + unsigned int occupiedSeat = pPed->GetOccupiedVehicleSeat(); + if (pVehicle->GetOccupant(occupiedSeat) == pPed) { // Remove him from the vehicle pPed->SetOccupiedVehicle(NULL, 0); - pVehicle->SetOccupant(NULL, ucOccupiedSeat); + pVehicle->SetOccupant(NULL, occupiedSeat); if (!m_pUnoccupiedVehicleSync->IsSyncerPersistent()) { @@ -3624,15 +3600,15 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE); // Tell the other players about it - CVehicleInOutPacket Reply(PedID, VehicleID, ucOccupiedSeat, VEHICLE_NOTIFY_FELL_OFF_RETURN); + CVehicleInOutPacket Reply(PedID, VehicleID, static_cast(occupiedSeat), VEHICLE_NOTIFY_FELL_OFF_RETURN); m_pPlayerManager->BroadcastOnlyJoined(Reply); // Call the ped->vehicle event CLuaArguments Arguments; - Arguments.PushElement(pVehicle); // vehicle - Arguments.PushNumber(ucOccupiedSeat); // seat - Arguments.PushBoolean(false); // jacker - Arguments.PushBoolean(false); // forcedByScript + Arguments.PushElement(pVehicle); // vehicle + Arguments.PushNumber(occupiedSeat); // seat + Arguments.PushBoolean(false); // jacker + Arguments.PushBoolean(false); // forcedByScript if (pPed->IsPlayer()) { pPed->CallEvent("onPlayerVehicleExit", Arguments); @@ -3644,17 +3620,17 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Call the vehicle->player event CLuaArguments Arguments2; - Arguments2.PushElement(pPed); // player / ped - Arguments2.PushNumber(ucOccupiedSeat); // seat - Arguments2.PushBoolean(false); // jacker - Arguments2.PushBoolean(false); // forcedByScript + Arguments2.PushElement(pPed); // player / ped + Arguments2.PushNumber(occupiedSeat); // seat + Arguments2.PushBoolean(false); // jacker + Arguments2.PushBoolean(false); // forcedByScript pVehicle->CallEvent("onVehicleExit", Arguments2); } break; } - case VEHICLE_NOTIFY_JACK: // Finished jacking him + case VEHICLE_NOTIFY_JACK: // Finished jacking him { // Is the ped jacking? if (pPed->GetVehicleAction() == CPed::VEHICLEACTION_JACKING) @@ -3681,10 +3657,10 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Execute the ped->vehicle script function for the jacked ped CLuaArguments ArgumentsExit; - ArgumentsExit.PushElement(pVehicle); // vehicle - ArgumentsExit.PushNumber(0); // seat - ArgumentsExit.PushElement(pPed); // jacker - ArgumentsExit.PushBoolean(false); // forcedByScript + ArgumentsExit.PushElement(pVehicle); // vehicle + ArgumentsExit.PushNumber(0); // seat + ArgumentsExit.PushElement(pPed); // jacker + ArgumentsExit.PushBoolean(false); // forcedByScript if (pJacked->IsPlayer()) pJacked->CallEvent("onPlayerVehicleExit", ArgumentsExit); else @@ -3692,17 +3668,17 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Execute the vehicle->ped script function for the jacked ped CLuaArguments ArgumentsExit2; - ArgumentsExit2.PushElement(pJacked); // player / ped - ArgumentsExit2.PushNumber(0); // seat - ArgumentsExit2.PushElement(pPed); // jacker - ArgumentsExit2.PushBoolean(false); // forcedByScript + ArgumentsExit2.PushElement(pJacked); // player / ped + ArgumentsExit2.PushNumber(0); // seat + ArgumentsExit2.PushElement(pPed); // jacker + ArgumentsExit2.PushBoolean(false); // forcedByScript pVehicle->CallEvent("onVehicleExit", ArgumentsExit2); // Execute the ped->vehicle script function CLuaArguments ArgumentsEnter; - ArgumentsEnter.PushElement(pVehicle); // vehicle - ArgumentsEnter.PushNumber(0); // seat - ArgumentsEnter.PushElement(pJacked); // jacked + ArgumentsEnter.PushElement(pVehicle); // vehicle + ArgumentsEnter.PushNumber(0); // seat + ArgumentsEnter.PushElement(pJacked); // jacked if (pPed->IsPlayer()) pPed->CallEvent("onPlayerVehicleEnter", ArgumentsEnter); else @@ -3710,9 +3686,9 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Execute the vehicle->ped script function CLuaArguments ArgumentsEnter2; - ArgumentsEnter2.PushElement(pPed); // player / ped - ArgumentsEnter2.PushNumber(0); // seat - ArgumentsEnter2.PushElement(pJacked); // jacked + ArgumentsEnter2.PushElement(pPed); // player / ped + ArgumentsEnter2.PushNumber(0); // seat + ArgumentsEnter2.PushElement(pJacked); // jacked pVehicle->CallEvent("onVehicleEnter", ArgumentsEnter2); } else @@ -3729,9 +3705,9 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Execute the player->vehicle script function CLuaArguments Arguments; - Arguments.PushElement(pVehicle); // vehicle - Arguments.PushNumber(0); // seat - Arguments.PushBoolean(false); // jacked + Arguments.PushElement(pVehicle); // vehicle + Arguments.PushNumber(0); // seat + Arguments.PushBoolean(false); // jacked if (pPed->IsPlayer()) pPed->CallEvent("onPlayerVehicleEnter", Arguments); else @@ -3739,22 +3715,11 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Execute the vehicle->player script function CLuaArguments Arguments2; - Arguments2.PushElement(pPed); // player / ped - Arguments2.PushNumber(0); // seat - Arguments2.PushBoolean(false); // jacked + Arguments2.PushElement(pPed); // player / ped + Arguments2.PushNumber(0); // seat + Arguments2.PushBoolean(false); // jacked pVehicle->CallEvent("onVehicleEnter", Arguments2); } - - if (!sendListIncompatiblePlayers.empty()) - { - // Warp the ped into the vehicle manually for incompatible players - CBitStream BitStream; - BitStream.pBitStream->Write(pVehicle->GetID()); - BitStream.pBitStream->Write((unsigned char)0); - BitStream.pBitStream->Write(pPed->GetSyncTimeContext()); - m_pPlayerManager->Broadcast(CElementRPCPacket(pPed, WARP_PED_INTO_VEHICLE, *BitStream.pBitStream), - sendListIncompatiblePlayers); - } } break; @@ -3766,7 +3731,7 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) if (pPed->GetVehicleAction() == CPed::VEHICLEACTION_JACKING) { unsigned char ucDoor = Packet.GetDoor(); - unsigned char ucOccupiedSeat = pPed->GetOccupiedVehicleSeat(); + unsigned int occupiedSeat = pPed->GetOccupiedVehicleSeat(); float fAngle = Packet.GetDoorAngle(); CPed* pJacked = pVehicle->GetOccupant(0); @@ -3801,10 +3766,10 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) m_pPlayerManager->BroadcastOnlyJoined(JackedReply); CLuaArguments Arguments; - Arguments.PushElement(pVehicle); // vehicle - Arguments.PushNumber(ucOccupiedSeat); // seat - Arguments.PushElement(pPed); // jacker - Arguments.PushBoolean(false); // forcedByScript + Arguments.PushElement(pVehicle); // vehicle + Arguments.PushNumber(occupiedSeat); // seat + Arguments.PushElement(pPed); // jacker + Arguments.PushBoolean(false); // forcedByScript if (pJacked->IsPlayer()) { @@ -3816,21 +3781,11 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) } CLuaArguments Arguments2; - Arguments2.PushElement(pJacked); // jacked - Arguments2.PushNumber(ucOccupiedSeat); // seat - Arguments2.PushElement(pPed); // jacker - Arguments2.PushBoolean(false); // forcedByScript - + Arguments2.PushElement(pJacked); // jacked + Arguments2.PushNumber(occupiedSeat); // seat + Arguments2.PushElement(pPed); // jacker + Arguments2.PushBoolean(false); // forcedByScript pVehicle->CallEvent("onVehicleExit", Arguments2); - - if (!sendListIncompatiblePlayers.empty()) - { - // Warp the ped out of the vehicle manually for incompatible players - CBitStream BitStream; - BitStream.pBitStream->Write(pJacked->GetSyncTimeContext()); - m_pPlayerManager->Broadcast(CElementRPCPacket(pJacked, REMOVE_PED_FROM_VEHICLE, *BitStream.pBitStream), - sendListIncompatiblePlayers); - } } pJacked->SetVehicleAction(CPed::VEHICLEACTION_NONE); } @@ -3939,7 +3894,7 @@ void CGame::Packet_VehicleTrailer(CVehicleTrailerPacket& Packet) m_pPlayerManager->BroadcastOnlyJoined(DetachPacket); } } - else // If we're detaching + else // If we're detaching { // Make sure they're attached if (pVehicle->GetTowedVehicle() == pTrailer && pTrailer->GetTowedByVehicle() == pVehicle) @@ -3967,17 +3922,15 @@ void CGame::Packet_Voice_Data(CVoiceDataPacket& Packet) { unsigned short usDataLength = 0; - if (m_pMainConfig->IsVoiceEnabled()) // Shouldn't really be receiving voice packets at all if voice is disabled + if (m_pMainConfig->IsVoiceEnabled()) // Shouldn't really be receiving voice packets at all if voice is disabled { - usDataLength = Packet.GetDataLength(); - - if (usDataLength > 0) + if (!Packet.IsEmpty()) { CPlayer* pPlayer = Packet.GetSourcePlayer(); if (pPlayer) { - if (pPlayer->IsVoiceMuted()) // Shouldn't be receiving voice packets, player should be muted client side + if (pPlayer->IsVoiceMuted()) // Shouldn't be receiving voice packets, player should be muted client side return; // Is it the start of the voice stream? @@ -3987,7 +3940,7 @@ void CGame::Packet_Voice_Data(CVoiceDataPacket& Packet) CLuaArguments Arguments; bool bEventTriggered = pPlayer->CallEvent("onPlayerVoiceStart", Arguments, pPlayer); - if (!bEventTriggered) // Was the event cancelled? + if (!bEventTriggered) // Was the event cancelled? { pPlayer->SetVoiceState(VOICESTATE_TRANSMITTING_IGNORED); return; @@ -3997,12 +3950,8 @@ void CGame::Packet_Voice_Data(CVoiceDataPacket& Packet) pPlayer->SetVoiceState(VOICESTATE_TRANSMITTING); } - if (pPlayer->GetVoiceState() == - VOICESTATE_TRANSMITTING) // If we reach here, and we're still in idle state, then the event was cancelled + if (pPlayer->GetVoiceState() == VOICESTATE_TRANSMITTING) // If we reach here, and we're still in idle state, then the event was cancelled { - const unsigned char* pBuffer = Packet.GetData(); - CVoiceDataPacket VoicePacket(pPlayer, pBuffer, usDataLength); - // Make list of players to send the voice packet to std::set playerSendMap; @@ -4045,7 +3994,7 @@ void CGame::Packet_Voice_Data(CVoiceDataPacket& Packet) } // Send to all players in the send list - CPlayerManager::Broadcast(VoicePacket, playerSendMap); + CPlayerManager::Broadcast(Packet, playerSendMap); } } } @@ -4054,7 +4003,7 @@ void CGame::Packet_Voice_Data(CVoiceDataPacket& Packet) void CGame::Packet_Voice_End(CVoiceEndPacket& Packet) { - if (m_pMainConfig->IsVoiceEnabled()) // Shouldn't really be receiving voice packets at all if voice is disabled + if (m_pMainConfig->IsVoiceEnabled()) // Shouldn't really be receiving voice packets at all if voice is disabled { CPlayer* pPlayer = Packet.GetSourcePlayer(); @@ -4279,25 +4228,24 @@ void CGame::Packet_PlayerNetworkStatus(CPlayerNetworkStatusPacket& Packet) if (pPlayer) { CLuaArguments Arguments; - Arguments.PushNumber(Packet.m_ucType); // 0-interruption began 1-interruption end - Arguments.PushNumber(Packet.m_uiTicks); // Ticks since interruption start + Arguments.PushNumber(Packet.m_ucType); // 0-interruption began 1-interruption end + Arguments.PushNumber(Packet.m_uiTicks); // Ticks since interruption start pPlayer->CallEvent("onPlayerNetworkStatus", Arguments, NULL); } } void CGame::Packet_PlayerResourceStart(CPlayerResourceStartPacket& Packet) { - CPlayer* pPlayer = Packet.GetSourcePlayer(); - if (pPlayer) - { - CResource* pResource = Packet.GetResource(); - if (pResource) - { - CLuaArguments Arguments; - Arguments.PushResource(pResource); - pPlayer->CallEvent("onPlayerResourceStart", Arguments, NULL); - } - } + CPlayer* sourcePlayer = Packet.GetSourcePlayer(); + CResource* resource = Packet.GetResource(); + unsigned int playerStartCounter = Packet.GetStartCounter(); + + if (!sourcePlayer || !resource || !resource->CanPlayerTriggerResourceStart(sourcePlayer, playerStartCounter)) + return; + + CLuaArguments Arguments; + Arguments.PushResource(resource); + sourcePlayer->CallEvent("onPlayerResourceStart", Arguments, nullptr); } void CGame::Packet_PlayerWorldSpecialProperty(CPlayerWorldSpecialPropertyPacket& packet) noexcept @@ -4421,7 +4369,7 @@ void CGame::PlayerCompleteConnect(CPlayer* pPlayer) CLuaArguments Arguments; Arguments.PushString(pPlayer->GetNick()); Arguments.PushString(pPlayer->GetSourceIP()); - Arguments.PushString(pPlayer->GetSerialUser().c_str()); + Arguments.PushString(""); Arguments.PushString(pPlayer->GetSerial().c_str()); Arguments.PushNumber(pPlayer->GetMTAVersion()); Arguments.PushString(pPlayer->GetPlayerVersion()); @@ -4670,7 +4618,7 @@ void CGame::HandleBackup() time_t timeSinceBackup = secondsNow - mktime(&timeinfo); if (timeSinceBackup < iBackupInterval * 86400L) - return; // No backup required + return; // No backup required } m_pMainConfig->NotifyDidBackup(); @@ -4684,7 +4632,7 @@ void CGame::HandleBackup() SString strTempZip = PathJoin(strBackupPath, strDateNow + "_temp.zip"); if (FileExists(strBackupZip)) - return; // Can't do backup as target file already exists + return; // Can't do backup as target file already exists MkDir(strBackupPath); @@ -4693,7 +4641,7 @@ void CGame::HandleBackup() CZipMaker zipMaker(strTempZip); if (!zipMaker.IsValid()) - return; // Can't do backup as can't create target zip + return; // Can't do backup as can't create target zip CLogger::LogPrintfNoStamp("Please wait...\n"); @@ -4791,7 +4739,7 @@ void CGame::SendPacketBatchEnd() bool CGame::IsBulletSyncActive() { bool bConfigSaysEnable = m_pMainConfig->GetBulletSyncEnabled(); -#if 0 // No auto bullet sync as there are some problems with it +#if 0 // No auto bullet sync as there are some problems with it bool bGlitchesSayEnable = ( m_Glitches [ GLITCH_FASTFIRE ] || m_Glitches [ GLITCH_CROUCHBUG ] ); #else bool bGlitchesSayEnable = false; @@ -4823,17 +4771,18 @@ void CGame::SendSyncSettings(CPlayer* pPlayer) MapInsert(weaponTypesUsingBulletSync, weaponList[i]); } - short sVehExtrapolateBaseMs = 5; - short sVehExtrapolatePercent = m_pMainConfig->GetVehExtrapolatePercent(); - short sVehExtrapolateMaxMs = m_pMainConfig->GetVehExtrapolatePingLimit(); - uchar ucVehExtrapolateEnabled = sVehExtrapolatePercent != 0; - uchar ucUseAltPulseOrder = m_pMainConfig->GetUseAltPulseOrder() != 0; - uchar ucAllowFastSprintFix = true; - uchar ucAllowDrivebyAnimFix = true; - uchar ucAllowShotgunDamageFix = true; + short sVehExtrapolateBaseMs = 5; + auto sVehExtrapolatePercent = static_cast(m_pMainConfig->GetVehExtrapolatePercent()); + auto sVehExtrapolateMaxMs = static_cast(m_pMainConfig->GetVehExtrapolatePingLimit()); + uchar ucVehExtrapolateEnabled = sVehExtrapolatePercent != 0; + uchar ucUseAltPulseOrder = m_pMainConfig->GetUseAltPulseOrder() != 0; + uchar ucAllowFastSprintFix = true; + uchar ucAllowDrivebyAnimFix = true; + uchar ucAllowShotgunDamageFix = true; + std::uint8_t multiCommandHandlerPolicy = static_cast(m_pMainConfig->GetAllowMultiCommandHandlers()); CSyncSettingsPacket packet(weaponTypesUsingBulletSync, ucVehExtrapolateEnabled, sVehExtrapolateBaseMs, sVehExtrapolatePercent, sVehExtrapolateMaxMs, - ucUseAltPulseOrder, ucAllowFastSprintFix, ucAllowDrivebyAnimFix, ucAllowShotgunDamageFix); + ucUseAltPulseOrder, ucAllowFastSprintFix, ucAllowDrivebyAnimFix, ucAllowShotgunDamageFix, multiCommandHandlerPolicy); if (pPlayer) pPlayer->Send(packet); else @@ -4888,12 +4837,6 @@ CMtaVersion CGame::CalculateMinClientRequirement() if (strNewMin < strMinClientRequirementFromResources) strNewMin = strMinClientRequirementFromResources; - if (!g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::FIREBALLDESTRUCT)) - { - if (strNewMin < FIREBALLDESTRUCT_MIN_CLIENT_VERSION) - strNewMin = FIREBALLDESTRUCT_MIN_CLIENT_VERSION; - } - // Log effective min client version if (strNewMin != m_strPrevMinClientConnectRequirement) { @@ -4915,12 +4858,6 @@ CMtaVersion CGame::CalculateMinClientRequirement() { CMtaVersion strKickMin; - if (!g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::FIREBALLDESTRUCT)) - { - if (strKickMin < FIREBALLDESTRUCT_MIN_CLIENT_VERSION) - strKickMin = FIREBALLDESTRUCT_MIN_CLIENT_VERSION; - } - if (strKickMin != m_strPrevMinClientKickRequirement) { m_strPrevMinClientKickRequirement = strKickMin; @@ -5018,7 +4955,7 @@ void CGame::ProcessClientTriggeredEventSpam() { if (GetTickCount64_() - data.m_llTicks >= m_iClientTriggeredEventsIntervalMs) { - if (data.m_uiCounter > m_iMaxClientTriggeredEventsPerInterval) + if (data.m_uiCounter > static_cast(m_iMaxClientTriggeredEventsPerInterval)) { CLuaArguments args; args.PushString(data.m_strLastEventName); diff --git a/Server/mods/deathmatch/logic/CGame.h b/Server/mods/deathmatch/logic/CGame.h index af491039d06..9d0ace7b1aa 100644 --- a/Server/mods/deathmatch/logic/CGame.h +++ b/Server/mods/deathmatch/logic/CGame.h @@ -158,7 +158,7 @@ class CSendList : public std::multimap class CGame { public: - ZERO_ON_NEW // To be sure everything is cleared + ZERO_ON_NEW // To be sure everything is cleared enum { VEHICLE_REQUEST_IN, VEHICLE_NOTIFY_IN, @@ -218,19 +218,19 @@ class CGame void SetIsFinished(bool bFinished) { m_bIsFinished = bFinished; }; bool IsFinished() { return m_bIsFinished; }; - CMainConfig* GetConfig() { return m_pMainConfig; } - CHandlingManager* GetHandlingManager() const noexcept { return m_HandlingManager.get(); } - CMapManager* GetMapManager() { return m_pMapManager; } - CPlayerManager* GetPlayerManager() { return m_pPlayerManager; } - CObjectManager* GetObjectManager() { return m_pObjectManager; } - CBuildingManager* GetBuildingManager() const noexcept { return m_pBuildingManager; } - CVehicleManager* GetVehicleManager() { return m_pVehicleManager; } - CTeamManager* GetTeamManager() { return m_pTeamManager; } - CUnoccupiedVehicleSync* GetUnoccupiedVehicleSync() { return m_pUnoccupiedVehicleSync; } - CPedSync* GetPedSync() { return m_pPedSync; } - CRegisteredCommands* GetRegisteredCommands() { return m_pRegisteredCommands; } + CMainConfig* GetConfig() { return m_pMainConfig; } + CHandlingManager* GetHandlingManager() const noexcept { return m_HandlingManager.get(); } + CMapManager* GetMapManager() { return m_pMapManager; } + CPlayerManager* GetPlayerManager() { return m_pPlayerManager; } + CObjectManager* GetObjectManager() { return m_pObjectManager; } + CBuildingManager* GetBuildingManager() const noexcept { return m_pBuildingManager; } + CVehicleManager* GetVehicleManager() { return m_pVehicleManager; } + CTeamManager* GetTeamManager() { return m_pTeamManager; } + CUnoccupiedVehicleSync* GetUnoccupiedVehicleSync() { return m_pUnoccupiedVehicleSync; } + CPedSync* GetPedSync() { return m_pPedSync; } + CRegisteredCommands* GetRegisteredCommands() { return m_pRegisteredCommands; } #ifdef WITH_OBJECT_SYNC - CObjectSync* GetObjectSync() { return m_pObjectSync; } + CObjectSync* GetObjectSync() { return m_pObjectSync; } #endif CConsole* GetConsole() { return m_pConsole; } CDatabaseManager* GetDatabaseManager() { return m_pDatabaseManager; } @@ -504,9 +504,9 @@ class CGame void Packet_VehicleDamageSync(class CVehicleDamageSyncPacket& Packet); void Packet_VehiclePuresync(class CVehiclePuresyncPacket& Packet); void Packet_Keysync(class CKeysyncPacket& Packet); - void Packet_Bulletsync(class CBulletsyncPacket& Packet); + void Packet_Bulletsync(class CBulletsyncPacket& packet); void Packet_PedTask(class CPedTaskPacket& Packet); - void Packet_WeaponBulletsync(class CCustomWeaponBulletSyncPacket& Packet); + void Packet_WeaponBulletsync(class CCustomWeaponBulletSyncPacket& packet); void Packet_Vehicle_InOut(class CVehicleInOutPacket& Packet); void Packet_VehicleTrailer(class CVehicleTrailerPacket& Packet); void Packet_LuaEvent(class CLuaEventPacket& Packet); @@ -532,30 +532,30 @@ class CGame // Technically, this could be put somewhere else. It's a callback function // which the voice server library will call to send out data. - CEvents m_Events; - CRemoteCalls* m_pRemoteCalls; - CHTTPD* m_pHTTPD; - CMainConfig* m_pMainConfig; - CBlipManager* m_pBlipManager; - CGroups* m_pGroups; - CColManager* m_pColManager; - CObjectManager* m_pObjectManager; - CBuildingManager* m_pBuildingManager; - CPickupManager* m_pPickupManager; - CPlayerManager* m_pPlayerManager; - CRadarAreaManager* m_pRadarAreaManager; - CVehicleManager* m_pVehicleManager; - CPacketTranslator* m_pPacketTranslator; - CMapManager* m_pMapManager; - CElementDeleter m_ElementDeleter; - CConnectHistory m_FloodProtect; - CLuaManager* m_pLuaManager; - CScriptDebugging* m_pScriptDebugging; - CConsole* m_pConsole; - CUnoccupiedVehicleSync* m_pUnoccupiedVehicleSync; - CPedSync* m_pPedSync; + CEvents m_Events; + CRemoteCalls* m_pRemoteCalls; + CHTTPD* m_pHTTPD; + CMainConfig* m_pMainConfig; + CBlipManager* m_pBlipManager; + CGroups* m_pGroups; + CColManager* m_pColManager; + CObjectManager* m_pObjectManager; + CBuildingManager* m_pBuildingManager; + CPickupManager* m_pPickupManager; + CPlayerManager* m_pPlayerManager; + CRadarAreaManager* m_pRadarAreaManager; + CVehicleManager* m_pVehicleManager; + CPacketTranslator* m_pPacketTranslator; + CMapManager* m_pMapManager; + CElementDeleter m_ElementDeleter; + CConnectHistory m_FloodProtect; + CLuaManager* m_pLuaManager; + CScriptDebugging* m_pScriptDebugging; + CConsole* m_pConsole; + CUnoccupiedVehicleSync* m_pUnoccupiedVehicleSync; + CPedSync* m_pPedSync; #ifdef WITH_OBJECT_SYNC - CObjectSync* m_pObjectSync; + CObjectSync* m_pObjectSync; #endif CMarkerManager* m_pMarkerManager; CClock* m_pClock; @@ -665,7 +665,7 @@ class CGame CLightsyncManager m_lightsyncManager; - bool m_bServerFullyUp; // No http operations should be allowed unless this is true + bool m_bServerFullyUp; // No http operations should be allowed unless this is true bool m_bLatentSendsEnabled; int m_iLatentSendsBandwidth; @@ -686,8 +686,8 @@ class CGame struct ClientTriggeredEventsInfo { - long long m_llTicks = 0; - uint32_t m_uiCounter = 0; + long long m_llTicks = 0; + uint32_t m_uiCounter = 0; std::string m_strLastEventName; }; diff --git a/Server/mods/deathmatch/logic/CHTTPD.cpp b/Server/mods/deathmatch/logic/CHTTPD.cpp index f50c24bb199..759bad55b06 100644 --- a/Server/mods/deathmatch/logic/CHTTPD.cpp +++ b/Server/mods/deathmatch/logic/CHTTPD.cpp @@ -24,16 +24,21 @@ #include #endif +#ifdef WIN32 + #include +#endif + extern CGame* g_pGame; CHTTPD::CHTTPD() - : m_BruteForceProtect(4, 30000, 60000 * 5) // Max of 4 attempts per 30 seconds, then 5 minute ignore - , m_HttpDosProtect(0, 0, 0) + : m_BruteForceProtect(4, 30000, 60000 * 5) // Max of 4 attempts per 30 seconds, then 5 minute ignore + , + m_HttpDosProtect(0, 0, 0) { m_pGuestAccount = g_pGame->GetAccountManager()->AddGuestAccount(HTTP_GUEST_ACCOUNT_NAME); m_HttpDosProtect = CConnectHistory(g_pGame->GetConfig()->GetHTTPDosThreshold(), 10000, - 60000 * 1); // Max of 'n' connections per 10 seconds, then 1 minute ignore + 60000 * 1); // Max of 'n' connections per 10 seconds, then 1 minute ignore std::vector excludeList; g_pGame->GetConfig()->GetHTTPDosExclude().Split(",", excludeList); @@ -71,21 +76,27 @@ bool CHTTPD::StartHTTPD(const char* szIP, unsigned int port) if (szIP && szIP[0]) { - // Convert the dotted ip to a long - long lIP = inet_addr(szIP); - parameters["bindip"] = lIP; + in_addr addr{}; +#ifdef WIN32 + if (InetPtonA(AF_INET, szIP, &addr) != 1) + return false; +#else + if (inet_pton(AF_INET, szIP, &addr) != 1) + return false; +#endif + parameters["bindip"] = static_cast(addr.s_addr); } else { // Bind to default; - parameters["bindip"] = (long)INADDR_ANY; + parameters["bindip"] = static_cast(INADDR_ANY); } - parameters["mode"] = "threadpool"; // or "singlethreaded"/"threadpool" + parameters["mode"] = "threadpool"; // or "singlethreaded"/"threadpool" parameters["threadcount"] = g_pGame->GetConfig()->GetHTTPThreadCount(); bResult = (StartServer(parameters) == STARTSERVER_SUCCESS); - m_bStartedServer = true; + m_bStartedServer = bResult; } return bResult; @@ -302,7 +313,7 @@ void CHTTPD::HttpPulse() { std::lock_guard guard(m_mutexLoggedInMap); - long long llExpireTime = GetTickCount64_() - 1000 * 60 * 5; // 5 minute timeout + long long llExpireTime = GetTickCount64_() - 1000 * 60 * 5; // 5 minute timeout map::iterator iter = m_LoggedInMap.begin(); while (iter != m_LoggedInMap.end()) diff --git a/Server/mods/deathmatch/logic/CHTTPD.h b/Server/mods/deathmatch/logic/CHTTPD.h index a27970b06c1..6235114b3b4 100644 --- a/Server/mods/deathmatch/logic/CHTTPD.h +++ b/Server/mods/deathmatch/logic/CHTTPD.h @@ -23,7 +23,7 @@ class CResource; class CHTTPD : public EHS { public: - CHTTPD(); // start the initial server + CHTTPD(); // start the initial server ~CHTTPD(); // EHS interface HttpResponse* RouteRequest(HttpRequest* ipoHttpRequest); @@ -43,7 +43,7 @@ class CHTTPD : public EHS private: CResource* m_resource{}; CHTTPD* m_server{}; - std::string m_strDefaultResourceName; // default resource name + std::string m_strDefaultResourceName; // default resource name EHSServerParameters m_Parameters; diff --git a/Server/mods/deathmatch/logic/CHandlingEntry.h b/Server/mods/deathmatch/logic/CHandlingEntry.h index 7f2afeca2aa..91e7bfa8d9c 100644 --- a/Server/mods/deathmatch/logic/CHandlingEntry.h +++ b/Server/mods/deathmatch/logic/CHandlingEntry.h @@ -16,58 +16,58 @@ class CHandlingEntry; class CTransmissionSAInterface { public: - unsigned char ucDriveType : 8; // +112 - unsigned char ucEngineType : 8; // +113 - unsigned char ucNumberOfGears : 8; // +114 - unsigned char ucUnknown : 8; // +115 + unsigned char ucDriveType : 8; // +112 + unsigned char ucEngineType : 8; // +113 + unsigned char ucNumberOfGears : 8; // +114 + unsigned char ucUnknown : 8; // +115 - unsigned int uiHandlingFlags; // +116 + unsigned int uiHandlingFlags; // +116 - float fEngineAcceleration; // +120 (value in handling.cfg * 0x86A950) - float fEngineInertia; // +124 - float fMaxVelocity; // +128 + float fEngineAcceleration; // +120 (value in handling.cfg * 0x86A950) + float fEngineInertia; // +124 + float fMaxVelocity; // +128 }; struct tHandlingData { - int iVehicleID; // +0 + int iVehicleID; // +0 - float fMass; // +4 + float fMass; // +4 - float fTurnMass; // +12 - float fDragCoeff; // +16 - CVector vecCenterOfMass; // +20 - unsigned int uiPercentSubmerged; // +32 + float fTurnMass; // +12 + float fDragCoeff; // +16 + CVector vecCenterOfMass; // +20 + unsigned int uiPercentSubmerged; // +32 - float fTractionMultiplier; // +40 + float fTractionMultiplier; // +40 - CTransmissionSAInterface Transmission; // +44 - float fBrakeDeceleration; // +148 - float fBrakeBias; // +152 - bool bABS; // +156 + CTransmissionSAInterface Transmission; // +44 + float fBrakeDeceleration; // +148 + float fBrakeBias; // +152 + bool bABS; // +156 - float fSteeringLock; // +160 - float fTractionLoss; // +164 - float fTractionBias; // +168 + float fSteeringLock; // +160 + float fTractionLoss; // +164 + float fTractionBias; // +168 - float fSuspensionForceLevel; // +172 - float fSuspensionDamping; // +176 - float fSuspensionHighSpdDamping; // +180 - float fSuspensionUpperLimit; // +184 - float fSuspensionLowerLimit; // +188 - float fSuspensionFrontRearBias; // +192 - float fSuspensionAntiDiveMultiplier; // +196 + float fSuspensionForceLevel; // +172 + float fSuspensionDamping; // +176 + float fSuspensionHighSpdDamping; // +180 + float fSuspensionUpperLimit; // +184 + float fSuspensionLowerLimit; // +188 + float fSuspensionFrontRearBias; // +192 + float fSuspensionAntiDiveMultiplier; // +196 - float fCollisionDamageMultiplier; // +200 + float fCollisionDamageMultiplier; // +200 - unsigned int uiModelFlags; // +204 - unsigned int uiHandlingFlags; // +208 - float fSeatOffsetDistance; // +212 - unsigned int uiMonetary; // +216 + unsigned int uiModelFlags; // +204 + unsigned int uiHandlingFlags; // +208 + float fSeatOffsetDistance; // +212 + unsigned int uiMonetary; // +216 - unsigned char ucHeadLight : 8; // +220 - unsigned char ucTailLight : 8; // +221 - unsigned char ucAnimGroup : 8; // +222 + unsigned char ucHeadLight : 8; // +220 + unsigned char ucTailLight : 8; // +221 + unsigned char ucAnimGroup : 8; // +222 }; class CHandlingEntry @@ -96,12 +96,12 @@ class CHandlingEntry }; // Constructor for creatable dummy entries - CHandlingEntry(){}; + CHandlingEntry() {}; // Constructor for original entries CHandlingEntry(tHandlingData* pOriginal); - ~CHandlingEntry(){}; + ~CHandlingEntry() {}; // Use this to copy data from an another handling class to this void ApplyHandlingData(const CHandlingEntry* const pData) noexcept; diff --git a/Server/mods/deathmatch/logic/CHandlingManager.cpp b/Server/mods/deathmatch/logic/CHandlingManager.cpp index 7776c55af05..72c5e10b184 100644 --- a/Server/mods/deathmatch/logic/CHandlingManager.cpp +++ b/Server/mods/deathmatch/logic/CHandlingManager.cpp @@ -39,39 +39,39 @@ CHandlingManager::CHandlingManager() // https://www.gtamodding.com/index.php?title=Handling.cfg#GTA_San_Andreas // https://projectcerbera.com/gta/sa/tutorials/handling - m_HandlingNames["mass"] = HANDLING_MASS; // works (mass > 0) - m_HandlingNames["turnMass"] = HANDLING_TURNMASS; // works - m_HandlingNames["dragCoeff"] = HANDLING_DRAGCOEFF; // works - m_HandlingNames["centerOfMass"] = HANDLING_CENTEROFMASS; // works - m_HandlingNames["percentSubmerged"] = HANDLING_PERCENTSUBMERGED; // works - m_HandlingNames["tractionMultiplier"] = HANDLING_TRACTIONMULTIPLIER; // works - m_HandlingNames["driveType"] = HANDLING_DRIVETYPE; // works - m_HandlingNames["engineType"] = HANDLING_ENGINETYPE; // works - m_HandlingNames["numberOfGears"] = HANDLING_NUMOFGEARS; // works - m_HandlingNames["engineAcceleration"] = HANDLING_ENGINEACCELERATION; // works - m_HandlingNames["engineInertia"] = HANDLING_ENGINEINERTIA; // works - m_HandlingNames["maxVelocity"] = HANDLING_MAXVELOCITY; // works - m_HandlingNames["brakeDeceleration"] = HANDLING_BRAKEDECELERATION; // works - m_HandlingNames["brakeBias"] = HANDLING_BRAKEBIAS; // works - m_HandlingNames["ABS"] = HANDLING_ABS; // has no effect in vanilla gta either - m_HandlingNames["steeringLock"] = HANDLING_STEERINGLOCK; // works - m_HandlingNames["tractionLoss"] = HANDLING_TRACTIONLOSS; // works - m_HandlingNames["tractionBias"] = HANDLING_TRACTIONBIAS; // works - m_HandlingNames["suspensionForceLevel"] = HANDLING_SUSPENSION_FORCELEVEL; // works - m_HandlingNames["suspensionDamping"] = HANDLING_SUSPENSION_DAMPING; // works - m_HandlingNames["suspensionHighSpeedDamping"] = HANDLING_SUSPENSION_HIGHSPEEDDAMPING; // works - m_HandlingNames["suspensionUpperLimit"] = HANDLING_SUSPENSION_UPPER_LIMIT; // works - m_HandlingNames["suspensionLowerLimit"] = HANDLING_SUSPENSION_LOWER_LIMIT; // works - m_HandlingNames["suspensionFrontRearBias"] = HANDLING_SUSPENSION_FRONTREARBIAS; // works - m_HandlingNames["suspensionAntiDiveMultiplier"] = HANDLING_SUSPENSION_ANTIDIVEMULTIPLIER; // works - m_HandlingNames["collisionDamageMultiplier"] = HANDLING_COLLISIONDAMAGEMULTIPLIER; // works - m_HandlingNames["seatOffsetDistance"] = HANDLING_SEATOFFSETDISTANCE; // works - m_HandlingNames["monetary"] = HANDLING_MONETARY; // useless as it only influences SP stats (value of damaged property) - m_HandlingNames["handlingFlags"] = HANDLING_HANDLINGFLAGS; // works - m_HandlingNames["modelFlags"] = HANDLING_MODELFLAGS; // works - m_HandlingNames["headLight"] = HANDLING_HEADLIGHT; // doesn't work - m_HandlingNames["tailLight"] = HANDLING_TAILLIGHT; // doesn't seem to work* - m_HandlingNames["animGroup"] = HANDLING_ANIMGROUP; // works model based + m_HandlingNames["mass"] = HANDLING_MASS; // works (mass > 0) + m_HandlingNames["turnMass"] = HANDLING_TURNMASS; // works + m_HandlingNames["dragCoeff"] = HANDLING_DRAGCOEFF; // works + m_HandlingNames["centerOfMass"] = HANDLING_CENTEROFMASS; // works + m_HandlingNames["percentSubmerged"] = HANDLING_PERCENTSUBMERGED; // works + m_HandlingNames["tractionMultiplier"] = HANDLING_TRACTIONMULTIPLIER; // works + m_HandlingNames["driveType"] = HANDLING_DRIVETYPE; // works + m_HandlingNames["engineType"] = HANDLING_ENGINETYPE; // works + m_HandlingNames["numberOfGears"] = HANDLING_NUMOFGEARS; // works + m_HandlingNames["engineAcceleration"] = HANDLING_ENGINEACCELERATION; // works + m_HandlingNames["engineInertia"] = HANDLING_ENGINEINERTIA; // works + m_HandlingNames["maxVelocity"] = HANDLING_MAXVELOCITY; // works + m_HandlingNames["brakeDeceleration"] = HANDLING_BRAKEDECELERATION; // works + m_HandlingNames["brakeBias"] = HANDLING_BRAKEBIAS; // works + m_HandlingNames["ABS"] = HANDLING_ABS; // has no effect in vanilla gta either + m_HandlingNames["steeringLock"] = HANDLING_STEERINGLOCK; // works + m_HandlingNames["tractionLoss"] = HANDLING_TRACTIONLOSS; // works + m_HandlingNames["tractionBias"] = HANDLING_TRACTIONBIAS; // works + m_HandlingNames["suspensionForceLevel"] = HANDLING_SUSPENSION_FORCELEVEL; // works + m_HandlingNames["suspensionDamping"] = HANDLING_SUSPENSION_DAMPING; // works + m_HandlingNames["suspensionHighSpeedDamping"] = HANDLING_SUSPENSION_HIGHSPEEDDAMPING; // works + m_HandlingNames["suspensionUpperLimit"] = HANDLING_SUSPENSION_UPPER_LIMIT; // works + m_HandlingNames["suspensionLowerLimit"] = HANDLING_SUSPENSION_LOWER_LIMIT; // works + m_HandlingNames["suspensionFrontRearBias"] = HANDLING_SUSPENSION_FRONTREARBIAS; // works + m_HandlingNames["suspensionAntiDiveMultiplier"] = HANDLING_SUSPENSION_ANTIDIVEMULTIPLIER; // works + m_HandlingNames["collisionDamageMultiplier"] = HANDLING_COLLISIONDAMAGEMULTIPLIER; // works + m_HandlingNames["seatOffsetDistance"] = HANDLING_SEATOFFSETDISTANCE; // works + m_HandlingNames["monetary"] = HANDLING_MONETARY; // useless as it only influences SP stats (value of damaged property) + m_HandlingNames["handlingFlags"] = HANDLING_HANDLINGFLAGS; // works + m_HandlingNames["modelFlags"] = HANDLING_MODELFLAGS; // works + m_HandlingNames["headLight"] = HANDLING_HEADLIGHT; // doesn't work + m_HandlingNames["tailLight"] = HANDLING_TAILLIGHT; // doesn't seem to work* + m_HandlingNames["animGroup"] = HANDLING_ANIMGROUP; // works model based } //* needs testing by someone who knows more about handling @@ -8157,27 +8157,27 @@ void CHandlingManager::InitializeDefaultHandlings() noexcept m_OriginalHandlingData[209].ucTailLight = 1; m_OriginalHandlingData[209].ucAnimGroup = 0; - m_OriginalHandlingData[210] = m_OriginalHandlingData[69]; // HT_HOTRINA = HT_HOTRING + m_OriginalHandlingData[210] = m_OriginalHandlingData[69]; // HT_HOTRINA = HT_HOTRING m_OriginalHandlingData[210].iVehicleID = 210; - m_OriginalHandlingData[211] = m_OriginalHandlingData[69]; // HT_HOTRINB = HT_HOTRING + m_OriginalHandlingData[211] = m_OriginalHandlingData[69]; // HT_HOTRINB = HT_HOTRING m_OriginalHandlingData[211].iVehicleID = 211; - m_OriginalHandlingData[212] = m_OriginalHandlingData[103]; // HT_SADLSHIT = HT_SADLER + m_OriginalHandlingData[212] = m_OriginalHandlingData[103]; // HT_SADLSHIT = HT_SADLER m_OriginalHandlingData[212].iVehicleID = 212; - m_OriginalHandlingData[213] = m_OriginalHandlingData[52]; // HT_GLENSHIT = HT_GLENDALE + m_OriginalHandlingData[213] = m_OriginalHandlingData[52]; // HT_GLENSHIT = HT_GLENDALE m_OriginalHandlingData[213].iVehicleID = 213; - m_OriginalHandlingData[214] = m_OriginalHandlingData[163]; // HT_FAGGIO = HT_PIZZABOY + m_OriginalHandlingData[214] = m_OriginalHandlingData[163]; // HT_FAGGIO = HT_PIZZABOY m_OriginalHandlingData[214].iVehicleID = 214; - m_OriginalHandlingData[215] = m_OriginalHandlingData[7]; // HT_FIRELA = HT_FIRETRUK + m_OriginalHandlingData[215] = m_OriginalHandlingData[7]; // HT_FIRELA = HT_FIRETRUK m_OriginalHandlingData[215].iVehicleID = 215; - m_OriginalHandlingData[216] = m_OriginalHandlingData[65]; // HT_RNCHLURE = HT_RANCHER + m_OriginalHandlingData[216] = m_OriginalHandlingData[65]; // HT_RNCHLURE = HT_RANCHER m_OriginalHandlingData[216].iVehicleID = 216; - m_OriginalHandlingData[217] = m_OriginalHandlingData[126]; // HT_FREIBOX = HT_FREIFLAT + m_OriginalHandlingData[217] = m_OriginalHandlingData[126]; // HT_FREIBOX = HT_FREIFLAT m_OriginalHandlingData[217].iVehicleID = 217; } diff --git a/Server/mods/deathmatch/logic/CLanBroadcast.cpp b/Server/mods/deathmatch/logic/CLanBroadcast.cpp index 5a62d228604..22cee03f76f 100644 --- a/Server/mods/deathmatch/logic/CLanBroadcast.cpp +++ b/Server/mods/deathmatch/logic/CLanBroadcast.cpp @@ -33,13 +33,13 @@ CLanBroadcast::CLanBroadcast(unsigned short usServerPort) return; } - // Set it to non blocking, so we dont have to wait for a packet - #ifdef WIN32 +// Set it to non blocking, so we dont have to wait for a packet +#ifdef WIN32 unsigned long ulNonBlock = 1; ioctlsocket(m_Socket, FIONBIO, &ulNonBlock); - #else +#else fcntl(m_Socket, F_SETFL, fcntl(m_Socket, F_GETFL) | O_NONBLOCK); - #endif +#endif // Set up the query messages std::stringstream ss; diff --git a/Server/mods/deathmatch/logic/CLightsyncManager.cpp b/Server/mods/deathmatch/logic/CLightsyncManager.cpp index 94e4ce8a708..700abd6bf65 100644 --- a/Server/mods/deathmatch/logic/CLightsyncManager.cpp +++ b/Server/mods/deathmatch/logic/CLightsyncManager.cpp @@ -33,7 +33,7 @@ void CLightsyncManager::RegisterPlayer(CPlayer* pPlayer) entry.ullTime = GetTickCount64_(); entry.pPlayer = pPlayer; entry.eType = SYNC_PLAYER; - entry.uiContext = 0; // Unused + entry.uiContext = 0; // Unused m_Queue.push_back(entry); } diff --git a/Server/mods/deathmatch/logic/CLightsyncManager.h b/Server/mods/deathmatch/logic/CLightsyncManager.h index 332555fc218..3250363eb3c 100644 --- a/Server/mods/deathmatch/logic/CLightsyncManager.h +++ b/Server/mods/deathmatch/logic/CLightsyncManager.h @@ -14,12 +14,12 @@ #include #ifndef _MSC_VER -#include + #include typedef int64_t __int64; #endif -#define LIGHTSYNC_HEALTH_THRESHOLD 2.0f -#define LIGHTSYNC_VEHICLE_HEALTH_THRESHOLD 50.0f +#define LIGHTSYNC_HEALTH_THRESHOLD 2.0f +#define LIGHTSYNC_VEHICLE_HEALTH_THRESHOLD 50.0f class CLightsyncManager { diff --git a/Server/mods/deathmatch/logic/CLogger.cpp b/Server/mods/deathmatch/logic/CLogger.cpp index a52d2c99c3b..e8f710fa22e 100644 --- a/Server/mods/deathmatch/logic/CLogger.cpp +++ b/Server/mods/deathmatch/logic/CLogger.cpp @@ -106,7 +106,7 @@ void CLogger::ErrorPrintvf(const char* format, va_list vlist) void CLogger::DebugPrintf(const char* szFormat, ...) { - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG // Compose the formatted message char szBuffer[MAX_STRING_LENGTH]; va_list marker; @@ -116,7 +116,7 @@ void CLogger::DebugPrintf(const char* szFormat, ...) // Timestamp and send to the console and logfile HandleLogPrint(true, "DEBUG: ", szBuffer, true, true, false); - #endif +#endif } void CLogger::AuthPrintf(const char* szFormat, ...) diff --git a/Server/mods/deathmatch/logic/CMainConfig.cpp b/Server/mods/deathmatch/logic/CMainConfig.cpp index affe0441532..a7e3ffbeede 100644 --- a/Server/mods/deathmatch/logic/CMainConfig.cpp +++ b/Server/mods/deathmatch/logic/CMainConfig.cpp @@ -2,6 +2,7 @@ * * PROJECT: Multi Theft Auto v1.0 * LICENSE: See LICENSE in the top level directory + * * FILE: mods/deathmatch/logic/CMainConfig.cpp * PURPOSE: XML-based main configuration file parser class * @@ -21,8 +22,9 @@ #include "CConsoleCommands.h" #include "CHTTPD.h" #include "CStaticFunctionDefinitions.h" +#include "CLanBroadcast.h" -#define MTA_SERVER_CONF_TEMPLATE "mtaserver.conf.template" +#define SETTINGS_TEMPLATE_PATH "mtaserver.conf.template" extern CGame* g_pGame; @@ -67,7 +69,7 @@ CMainConfig::CMainConfig(CConsole* pConsole) : CXMLConfig(NULL) m_bScriptDebugLogEnabled = false; m_uiScriptDebugLogLevel = 0; m_bDontBroadcastLan = false; - m_usFPSLimit = 36; + m_fpsLimit = 36; m_uiVoiceSampleRate = 1; m_ucVoiceQuality = 4; m_bVoiceEnabled = false; @@ -81,6 +83,7 @@ CMainConfig::CMainConfig(CConsole* pConsole) : CXMLConfig(NULL) m_bSyncMapElementData = true; m_elementDataWhitelisted = false; m_checkDuplicateSerials = true; + m_allowMultiCommandHandlers = 1; } bool CMainConfig::Load() @@ -136,12 +139,12 @@ bool CMainConfig::Load() } // Grab rules - CXMLNode* currentNode = nullptr; + CXMLNode* currentNode = nullptr; std::size_t currentIndex = 0; while (currentNode = m_pRootNode->FindSubNode("rule", currentIndex++)) { CXMLAttribute* attribute = currentNode->GetAttributes().Find("name"); - SString ruleName = attribute ? attribute->GetValue() : SString{}; + SString ruleName = attribute ? attribute->GetValue() : SString{}; attribute = currentNode->GetAttributes().Find("value"); SString ruleValue = attribute ? attribute->GetValue() : SString{}; @@ -149,7 +152,7 @@ bool CMainConfig::Load() if (!ruleName.empty() && !ruleValue.empty()) m_RulesForASEMap[std::move(ruleName)] = std::move(ruleValue); } - + // Strip spaces from beginning and end of server name m_strServerName = SString(m_strServerName).TrimStart(" ").TrimEnd(" "); @@ -258,13 +261,13 @@ bool CMainConfig::Load() { // Grab its "name" attribute CXMLAttribute* attribute = currentNode->GetAttributes().Find("name"); - SString name = attribute ? attribute->GetValue() : SString{}; + SString name = attribute ? attribute->GetValue() : SString{}; name = name.Replace("\\", "/").ToLower(); // Grab its "verify" attribute attribute = currentNode->GetAttributes().Find("verify"); SString verify = attribute ? attribute->GetValue() : SString{}; - bool shouldVerify = verify == "true" || verify == "yes" || verify == "1"; + bool shouldVerify = verify == "true" || verify == "yes" || verify == "1"; // Find bitnumber bool found = false; @@ -362,15 +365,11 @@ bool CMainConfig::Load() iResult = GetString(m_pRootNode, "password", m_strPassword, 1, 32); // Grab the server fps limit - int iFPSTemp = 0; - iResult = GetInteger(m_pRootNode, "fpslimit", iFPSTemp, 0, std::numeric_limits::max()); + int readFps = 0; + iResult = GetInteger(m_pRootNode, "fpslimit", readFps, FPSLimits::FPS_UNLIMITED, FPSLimits::FPS_MAX); if (iResult == IS_SUCCESS) { - if (iFPSTemp == 0 || iFPSTemp >= 25) - { - m_usFPSLimit = (unsigned short)iFPSTemp; - SetInteger(m_pRootNode, "fpslimit", (int)m_usFPSLimit); - } + FPSLimits::IsValidAndSetValid(static_cast(readFps), m_fpsLimit); } // Grab whether or not voice is enabled @@ -539,6 +538,8 @@ bool CMainConfig::Load() GetBoolean(m_pRootNode, "elementdata_whitelisted", m_elementDataWhitelisted); GetBoolean(m_pRootNode, "check_duplicate_serials", m_checkDuplicateSerials); + GetInteger(m_pRootNode, "allow_multi_command_handlers", m_allowMultiCommandHandlers); + m_allowMultiCommandHandlers = Clamp(0, m_allowMultiCommandHandlers, 2); ApplyNetOptions(); @@ -771,7 +772,8 @@ bool CMainConfig::LoadExtended() RegisterCommand("start", CConsoleCommands::StartResource, false, "Usage: start ...\nStart a loaded resource eg: start admin"); RegisterCommand("stop", CConsoleCommands::StopResource, false, "Usage: stop ...\nStop a resource eg: stop admin"); RegisterCommand("stopall", CConsoleCommands::StopAllResources, false, "Stop all running resources"); - RegisterCommand("restart", CConsoleCommands::RestartResource, false, "Usage: restart ...\nRestarts a running resource eg: restart admin"); + RegisterCommand("restart", CConsoleCommands::RestartResource, false, + "Usage: restart ...\nRestarts a running resource eg: restart admin"); RegisterCommand("refresh", CConsoleCommands::RefreshResources, false, "Refresh resource list to find new resources"); RegisterCommand("refreshall", CConsoleCommands::RefreshAllResources, false, "Refresh resources and restart any changed resources"); RegisterCommand("list", CConsoleCommands::ListResources, false, "Shows a list of resources"); @@ -864,26 +866,36 @@ bool CMainConfig::AddMissingSettings() if (!g_pGame->IsUsingMtaServerConf()) return false; - const SString templateFileName = PathJoin(g_pServerInterface->GetServerModPath(), "mtaserver.conf.template"); - + const std::string templateFileName = PathJoin(g_pServerInterface->GetServerModPath(), SETTINGS_TEMPLATE_PATH); if (!FileExists(templateFileName)) return false; - CXMLFile* templateFile = g_pServerInterface->GetXML()->CreateXML(templateFileName); - CXMLNode* templateRootNode = templateFile && templateFile->Parse() ? templateFile->GetRootNode() : nullptr; + std::unique_ptr templateFile(g_pServerInterface->GetXML()->CreateXML(templateFileName.c_str())); + if (!templateFile || !templateFile->Parse()) + { + CLogger::ErrorPrintf("Failed to parse template file: '%s'\n", templateFileName.c_str()); + return false; + } + + CXMLNode* templateRootNode = templateFile->GetRootNode(); if (!templateRootNode) { - CLogger::ErrorPrintf("Can't parse '%s'\n", *templateFileName); + CLogger::ErrorPrintf("Template file '%s' has no root node\n", templateFileName.c_str()); return false; } // Check that each item in the template also exists in the server config - bool hasConfigChanged = false; + bool configChanged = false; CXMLNode* previousNode = nullptr; + for (auto it = templateRootNode->ChildrenBegin(); it != templateRootNode->ChildrenEnd(); ++it) { - CXMLNode* templateNode = *it; - SString templateNodeTagName = templateNode->GetTagName(); + CXMLNode* templateNode = *it; + const std::string& templateNodeName = templateNode->GetTagName(); + + // Skip certain optional nodes + if (templateNodeName == "resource" || templateNodeName == "module") + continue; // Find node with exact same attributes CXMLAttributes& templateAttributes = templateNode->GetAttributes(); @@ -891,21 +903,25 @@ bool CMainConfig::AddMissingSettings() for (auto it2 = m_pRootNode->ChildrenBegin(); it2 != m_pRootNode->ChildrenEnd(); ++it2) { CXMLNode* tempNode = *it2; - if (tempNode->GetTagName() != templateNodeTagName) - { + if (tempNode->GetTagName() != templateNodeName) continue; - } + CXMLAttributes& attributes = tempNode->GetAttributes(); bool attributesMatch = true; for (auto it3 = templateAttributes.ListBegin(); it3 != templateAttributes.ListEnd(); ++it3) { CXMLAttribute* templateAttribute = *it3; - const SString& strKey = templateAttribute->GetName(); - const SString& strValue = templateAttribute->GetValue(); + const SString& attrName = templateAttribute->GetName(); + + // Don't check value attribute which is intended to be customized by the server + if (attrName == "value") + continue; - CXMLAttribute* foundAttribute = attributes.Find(strKey); - if (!foundAttribute || foundAttribute->GetValue() != strValue) + const SString& attrValue = templateAttribute->GetValue(); + + CXMLAttribute* foundAttribute = attributes.Find(attrName); + if (!foundAttribute || foundAttribute->GetValue() != attrValue) { attributesMatch = false; break; @@ -918,37 +934,28 @@ bool CMainConfig::AddMissingSettings() break; } } - // Create missing node if not found + if (!foundNode) { - CLogger::LogPrintf("Adding missing '%s' to mtaserver.conf\n", *templateNodeTagName); - SString value = templateNode->GetTagContent(); - SString commentText = templateNode->GetCommentText(); - foundNode = m_pRootNode->CreateSubNode(templateNodeTagName, previousNode); - foundNode->SetTagContent(value); - foundNode->SetCommentText(commentText, true); - - // Copy attributes from template node - CXMLAttributes& templateAttributes = templateNode->GetAttributes(); - for (auto it = templateAttributes.ListBegin(); it != templateAttributes.ListEnd(); ++it) - { - CXMLAttribute* templateAttribute = *it; - const SString& attributeName = templateAttribute->GetName(); - const SString& attributeValue = templateAttribute->GetValue(); + const std::string templateNodeValue = templateNode->GetTagContent(); + const SString templateNodeComment = templateNode->GetCommentText(); + + foundNode = m_pRootNode->CreateSubNode(templateNodeName.c_str(), previousNode); + foundNode->SetTagContent(templateNodeValue.c_str()); + foundNode->SetCommentText(templateNodeComment.c_str(), true); - CXMLAttribute* newAttribute = foundNode->GetAttributes().Create(attributeName); - if (newAttribute) - newAttribute->SetValue(attributeValue); + for (auto it3 = templateAttributes.ListBegin(); it3 != templateAttributes.ListEnd(); ++it3) + { + CXMLAttribute* templateAttribute = *it3; + foundNode->GetAttributes().Create(*templateAttribute); } - hasConfigChanged = true; + + CLogger::LogPrintf("Added missing '%s' setting to mtaserver.conf\n", templateNodeName.c_str()); + configChanged = true; } previousNode = foundNode; } - - // Clean up - g_pServerInterface->GetXML()->DeleteXML(templateFile); - FileDelete(templateFileName); - return hasConfigChanged; + return configChanged; } bool CMainConfig::IsValidPassword(const char* szPassword) @@ -990,19 +997,18 @@ bool CMainConfig::SetPassword(const char* szPassword, bool bSave) return true; } -bool CMainConfig::SetFPSLimit(unsigned short usFPS, bool bSave) +bool CMainConfig::SetFPSLimit(std::uint16_t newFps, bool save) { - if (usFPS == 0 || (usFPS >= 25 && usFPS <= std::numeric_limits::max())) + if (!FPSLimits::IsValidAndSetValid(newFps, m_fpsLimit)) { - m_usFPSLimit = usFPS; - if (bSave) - { - SetInteger(m_pRootNode, "fpslimit", usFPS); - Save(); - } - return true; + return false; } - return false; + if (save) + { + SetInteger(m_pRootNode, "fpslimit", m_fpsLimit); + Save(); + } + return true; } void CMainConfig::RegisterCommand(const char* szName, FCommandHandler* pFunction, bool bRestricted, const char* szConsoleHelpText) @@ -1332,7 +1338,7 @@ bool CMainConfig::SetSetting(const SString& strName, const SString& strValue, bo } else if (strName == "fpslimit") { - return CStaticFunctionDefinitions::SetFPSLimit(atoi(strValue), bSave); + return CStaticFunctionDefinitions::SetFPSLimit(static_cast(atoi(strValue)), bSave); } else if (strName == "networkencryption") { @@ -1529,8 +1535,10 @@ const std::vector& CMainConfig::GetIntSettingList() {false, false, 0, 1, 1, "database_credentials_protection", &m_bDatabaseCredentialsProtectionEnabled, NULL}, {false, false, 0, 0, 1, "fakelag", &m_bFakeLagCommandEnabled, NULL}, {true, true, 50, 1000, 5000, "player_triggered_event_interval", &m_iPlayerTriggeredEventIntervalMs, &CMainConfig::OnPlayerTriggeredEventIntervalChange}, - {true, true, 1, 100, 1000, "max_player_triggered_events_per_interval", &m_iMaxPlayerTriggeredEventsPerInterval, &CMainConfig::OnPlayerTriggeredEventIntervalChange}, + {true, true, 1, 100, 1000, "max_player_triggered_events_per_interval", &m_iMaxPlayerTriggeredEventsPerInterval, + &CMainConfig::OnPlayerTriggeredEventIntervalChange}, {true, true, 0, 1, 1, "resource_client_file_checks", &m_checkResourceClientFiles, nullptr}, + {true, true, 0, 1, 2, "allow_multi_command_handlers", &m_allowMultiCommandHandlers, &CMainConfig::OnAllowMultiCommandHandlersChange}, }; static std::vector settingsList; @@ -1580,6 +1588,11 @@ void CMainConfig::OnPlayerTriggeredEventIntervalChange() g_pGame->ApplyPlayerTriggeredEventIntervalChange(); } +void CMainConfig::OnAllowMultiCommandHandlersChange() +{ + g_pGame->SendSyncSettings(); +} + void CGame::ApplyPlayerTriggeredEventIntervalChange() { m_iClientTriggeredEventsIntervalMs = m_pMainConfig->GetPlayerTriggeredEventInterval(); diff --git a/Server/mods/deathmatch/logic/CMainConfig.h b/Server/mods/deathmatch/logic/CMainConfig.h index ffb0b8de8dd..6191c72f153 100644 --- a/Server/mods/deathmatch/logic/CMainConfig.h +++ b/Server/mods/deathmatch/logic/CMainConfig.h @@ -63,73 +63,73 @@ class CMainConfig : public CXMLConfig const std::string& GetPassword() { return m_strPassword; }; bool SetPassword(const char* szPassword, bool bSave); - bool IsVoiceEnabled(); - unsigned int GetVoiceSampleRate() { return m_uiVoiceSampleRate; }; - unsigned int GetVoiceQuality() { return m_ucVoiceQuality; }; - unsigned int GetVoiceBitrate() { return m_uiVoiceBitrate; }; - - bool GetAseInternetPushEnabled() { return m_iAseMode == 2 && !IsFakeLagCommandEnabled(); } - bool GetAseInternetListenEnabled() { return m_iAseMode == 1 && !IsFakeLagCommandEnabled(); } - bool GetAseLanListenEnabled() { return m_bDontBroadcastLan ? false : true; } - unsigned short GetHTTPPort(); - eHTTPDownloadType GetHTTPDownloadType() { return m_ucHTTPDownloadType; }; - const std::string& GetHTTPDownloadURL() { return m_strHTTPDownloadURL; }; - int GetHTTPMaxConnectionsPerClient() { return m_iHTTPMaxConnectionsPerClient; }; - int GetHTTPThreadCount() { return m_iHTTPThreadCount; }; - int GetHTTPDosThreshold() { return m_iHTTPDosThreshold; }; - const SString& GetHTTPDosExclude() { return m_strHTTPDosExclude; }; - int GetEnableClientChecks() { return m_iEnableClientChecks; }; - const std::string& GetLogFile() { return m_strLogFile; }; - const std::string& GetAuthFile() { return m_strAuthFile; }; - bool GetJoinFloodProtectionEnabled() { return m_bJoinFloodProtectionEnabled; }; - bool GetScriptDebugLogEnabled() { return m_bScriptDebugLogEnabled && !m_strScriptDebugLogFile.empty(); }; - const std::string& GetScriptDebugLogFile() { return m_strScriptDebugLogFile; }; - unsigned int GetScriptDebugLogLevel() { return m_uiScriptDebugLogLevel; }; - const std::string& GetAccessControlListFile() { return m_strAccessControlListFile; }; - bool GetSerialVerificationEnabled() { return m_bVerifySerials; }; + bool IsVoiceEnabled(); + unsigned char GetVoiceSampleRate() { return static_cast(m_uiVoiceSampleRate); }; + unsigned char GetVoiceQuality() { return m_ucVoiceQuality; }; + unsigned int GetVoiceBitrate() { return m_uiVoiceBitrate; }; + + bool GetAseInternetPushEnabled() { return m_iAseMode == 2 && !IsFakeLagCommandEnabled(); } + bool GetAseInternetListenEnabled() { return m_iAseMode == 1 && !IsFakeLagCommandEnabled(); } + bool GetAseLanListenEnabled() { return m_bDontBroadcastLan ? false : true; } + unsigned short GetHTTPPort(); + eHTTPDownloadType GetHTTPDownloadType() { return m_ucHTTPDownloadType; }; + const std::string& GetHTTPDownloadURL() { return m_strHTTPDownloadURL; }; + int GetHTTPMaxConnectionsPerClient() { return m_iHTTPMaxConnectionsPerClient; }; + int GetHTTPThreadCount() { return m_iHTTPThreadCount; }; + int GetHTTPDosThreshold() { return m_iHTTPDosThreshold; }; + const SString& GetHTTPDosExclude() { return m_strHTTPDosExclude; }; + int GetEnableClientChecks() { return m_iEnableClientChecks; }; + const std::string& GetLogFile() { return m_strLogFile; }; + const std::string& GetAuthFile() { return m_strAuthFile; }; + bool GetJoinFloodProtectionEnabled() { return m_bJoinFloodProtectionEnabled; }; + bool GetScriptDebugLogEnabled() { return m_bScriptDebugLogEnabled && !m_strScriptDebugLogFile.empty(); }; + const std::string& GetScriptDebugLogFile() { return m_strScriptDebugLogFile; }; + unsigned int GetScriptDebugLogLevel() { return m_uiScriptDebugLogLevel; }; + const std::string& GetAccessControlListFile() { return m_strAccessControlListFile; }; + bool GetSerialVerificationEnabled() { return m_bVerifySerials; }; const std::map& GetRulesForASE() const noexcept { return m_RulesForASEMap; }; - bool IsDisableAC(const char* szTagAC) { return MapContains(m_DisableComboACMap, szTagAC); }; - bool IsEnableDiagnostic(const char* szTag) { return MapContains(m_EnableDiagnosticMap, szTag); }; - CMtaVersion GetMinClientVersion() { return m_strMinClientVersion; } - const CMtaVersion& GetRecommendedClientVersion() { return m_strRecommendedClientVersion; } - int GetMinClientVersionAutoUpdate() { return m_iMinClientVersionAutoUpdate; } - const SString& GetIdFile() { return m_strIdFile; } - bool GetThreadNetEnabled() { return m_bThreadNetEnabled; } - const SString& GetGlobalDatabasesPath() { return m_strGlobalDatabasesPath; } - const SString& GetSystemDatabasesPath() { return m_strSystemDatabasesPath; } - const SString& GetBackupPath() { return m_strBackupPath; } - int GetBackupInterval() { return m_iBackupInterval; } - int GetBackupAmount() { return m_iBackupAmount; } - void NotifyDidBackup(); - bool ShouldCompactInternalDatabases(); - unsigned short GetFPSLimit() { return m_usFPSLimit; }; - bool SetFPSLimit(unsigned short usFPS, bool bSave); - int GetPendingWorkToDoSleepTime(); - int GetNoWorkToDoSleepTime(); - int GetServerLogicFpsLimit() { return m_iServerLogicFpsLimit; }; - const SString& GetDbLogFilename() { return m_strDbLogFilename; } - bool GetSyncMapElementData() const { return m_bSyncMapElementData; } - void SetSyncMapElementData(bool bOn) { m_bSyncMapElementData = bOn; } - bool GetBulletSyncEnabled() const { return m_bBulletSyncEnabled != 0; } - int GetVehExtrapolatePercent() const { return m_iVehExtrapolatePercent; } - int GetVehExtrapolatePingLimit() const { return m_iVehExtrapolatePingLimit; } - bool GetUseAltPulseOrder() const { return m_bUseAltPulseOrder != 0; } - const SString& GetLoadstringLogFilename() const { return m_strLoadstringLogFilename; } - bool GetLoadstringLogEnabled() const { return !m_strLoadstringLogFilename.empty(); } - bool GetCrashDumpUploadEnabled() const { return m_bCrashDumpUploadEnabled != 0; } - bool GetFilterDuplicateLogLinesEnabled() const { return m_bFilterDuplicateLogLinesEnabled != 0; } - bool IsAuthSerialGroup(const SString& strGroup) const { return ListContains(m_AuthSerialGroupList, strGroup); }; - bool IsAuthSerialHttpIpException(const SString& strIp) const { return ListContains(m_AuthSerialHttpIpExceptionList, strIp); } - bool GetAuthSerialEnabled() const { return !m_AuthSerialGroupList.empty(); }; - bool GetAuthSerialHttpEnabled() const { return m_bAuthSerialHttpEnabled && GetAuthSerialEnabled(); }; - const std::vector& GetAuthSerialGroupList() const { return m_AuthSerialGroupList; } - const std::vector& GetAuthSerialHttpIpExceptionList() const { return m_AuthSerialHttpIpExceptionList; } - const std::vector& GetOwnerEmailAddressList() const { return m_OwnerEmailAddressList; } - bool IsDatabaseCredentialsProtectionEnabled() const { return m_bDatabaseCredentialsProtectionEnabled != 0; } - bool IsFakeLagCommandEnabled() const { return m_bFakeLagCommandEnabled != 0; } - bool IsElementDataWhitelisted() const { return m_elementDataWhitelisted; } - bool IsCheckDuplicateSerialsEnabled() const noexcept { return m_checkDuplicateSerials; } - bool IsCheckResourceClientFilesEnabled() const noexcept { return m_checkResourceClientFiles != 0; } + bool IsDisableAC(const char* szTagAC) { return MapContains(m_DisableComboACMap, szTagAC); }; + bool IsEnableDiagnostic(const char* szTag) { return MapContains(m_EnableDiagnosticMap, szTag); }; + CMtaVersion GetMinClientVersion() { return m_strMinClientVersion; } + const CMtaVersion& GetRecommendedClientVersion() { return m_strRecommendedClientVersion; } + int GetMinClientVersionAutoUpdate() { return m_iMinClientVersionAutoUpdate; } + const SString& GetIdFile() { return m_strIdFile; } + bool GetThreadNetEnabled() { return m_bThreadNetEnabled; } + const SString& GetGlobalDatabasesPath() { return m_strGlobalDatabasesPath; } + const SString& GetSystemDatabasesPath() { return m_strSystemDatabasesPath; } + const SString& GetBackupPath() { return m_strBackupPath; } + int GetBackupInterval() { return m_iBackupInterval; } + int GetBackupAmount() { return m_iBackupAmount; } + void NotifyDidBackup(); + bool ShouldCompactInternalDatabases(); + std::uint16_t GetFPSLimit() const noexcept { return m_fpsLimit; }; + bool SetFPSLimit(std::uint16_t fps, bool save); + int GetPendingWorkToDoSleepTime(); + int GetNoWorkToDoSleepTime(); + int GetServerLogicFpsLimit() { return m_iServerLogicFpsLimit; }; + const SString& GetDbLogFilename() { return m_strDbLogFilename; } + bool GetSyncMapElementData() const { return m_bSyncMapElementData; } + void SetSyncMapElementData(bool bOn) { m_bSyncMapElementData = bOn; } + bool GetBulletSyncEnabled() const { return m_bBulletSyncEnabled != 0; } + int GetVehExtrapolatePercent() const { return m_iVehExtrapolatePercent; } + int GetVehExtrapolatePingLimit() const { return m_iVehExtrapolatePingLimit; } + bool GetUseAltPulseOrder() const { return m_bUseAltPulseOrder != 0; } + const SString& GetLoadstringLogFilename() const { return m_strLoadstringLogFilename; } + bool GetLoadstringLogEnabled() const { return !m_strLoadstringLogFilename.empty(); } + bool GetCrashDumpUploadEnabled() const { return m_bCrashDumpUploadEnabled != 0; } + bool GetFilterDuplicateLogLinesEnabled() const { return m_bFilterDuplicateLogLinesEnabled != 0; } + bool IsAuthSerialGroup(const SString& strGroup) const { return ListContains(m_AuthSerialGroupList, strGroup); }; + bool IsAuthSerialHttpIpException(const SString& strIp) const { return ListContains(m_AuthSerialHttpIpExceptionList, strIp); } + bool GetAuthSerialEnabled() const { return !m_AuthSerialGroupList.empty(); }; + bool GetAuthSerialHttpEnabled() const { return m_bAuthSerialHttpEnabled && GetAuthSerialEnabled(); }; + const std::vector& GetAuthSerialGroupList() const { return m_AuthSerialGroupList; } + const std::vector& GetAuthSerialHttpIpExceptionList() const { return m_AuthSerialHttpIpExceptionList; } + const std::vector& GetOwnerEmailAddressList() const { return m_OwnerEmailAddressList; } + bool IsDatabaseCredentialsProtectionEnabled() const { return m_bDatabaseCredentialsProtectionEnabled != 0; } + bool IsFakeLagCommandEnabled() const { return m_bFakeLagCommandEnabled != 0; } + bool IsElementDataWhitelisted() const { return m_elementDataWhitelisted; } + bool IsCheckDuplicateSerialsEnabled() const noexcept { return m_checkDuplicateSerials; } + bool IsCheckResourceClientFilesEnabled() const noexcept { return m_checkResourceClientFiles != 0; } SString GetSetting(const SString& configSetting); bool GetSetting(const SString& configSetting, SString& strValue); @@ -147,9 +147,11 @@ class CMainConfig : public CXMLConfig void OnTickRateChange(); void OnAseSettingChange(); void OnPlayerTriggeredEventIntervalChange(); + void OnAllowMultiCommandHandlersChange(); int GetPlayerTriggeredEventInterval() const { return m_iPlayerTriggeredEventIntervalMs; } int GetMaxPlayerTriggeredEventsPerInterval() const { return m_iMaxPlayerTriggeredEventsPerInterval; } + int GetAllowMultiCommandHandlers() const noexcept { return m_allowMultiCommandHandlers; } private: void RegisterCommand(const char* szName, FCommandHandler* pFunction, bool bRestricted, const char* szConsoleHelpText); @@ -191,7 +193,7 @@ class CMainConfig : public CXMLConfig unsigned int m_uiScriptDebugLogLevel; std::string m_strAccessControlListFile; bool m_bVerifySerials; - unsigned short m_usFPSLimit; + std::uint16_t m_fpsLimit; int m_bDontBroadcastLan; std::set m_DisableComboACMap; std::map m_RulesForASEMap; @@ -235,4 +237,5 @@ class CMainConfig : public CXMLConfig bool m_elementDataWhitelisted; bool m_checkDuplicateSerials; int m_checkResourceClientFiles; + int m_allowMultiCommandHandlers; }; diff --git a/Server/mods/deathmatch/logic/CMapEventManager.cpp b/Server/mods/deathmatch/logic/CMapEventManager.cpp index 5cc6d4d30e1..0ebc786c190 100644 --- a/Server/mods/deathmatch/logic/CMapEventManager.cpp +++ b/Server/mods/deathmatch/logic/CMapEventManager.cpp @@ -146,6 +146,7 @@ bool CMapEventManager::Call(const char* szName, const CLuaArguments& Arguments, // Copy the results into a array in case m_EventsMap is modified during the call std::vector matchingEvents; + matchingEvents.reserve(8); for (EventsIter iter = itPair.first; iter != itPair.second; ++iter) matchingEvents.push_back(iter->second); @@ -165,11 +166,11 @@ bool CMapEventManager::Call(const char* szName, const CLuaArguments& Arguments, // Grab the current VM lua_State* pState = pMapEvent->GetVM()->GetVM(); - LUA_CHECKSTACK(pState, 1); // Ensure some room + LUA_CHECKSTACK(pState, 1); // Ensure some room - #if MTA_DEBUG +#if MTA_DEBUG int luaStackPointer = lua_gettop(pState); - #endif +#endif TIMEUS startTime = GetTimeUs(); @@ -266,9 +267,9 @@ bool CMapEventManager::Call(const char* szName, const CLuaArguments& Arguments, OldClient.Push(pState); lua_setglobal(pState, "client"); - #if MTA_DEBUG +#if MTA_DEBUG assert(lua_gettop(pState) == luaStackPointer); - #endif +#endif CPerfStatLuaTiming::GetSingleton()->UpdateLuaTiming(pMapEvent->GetVM(), szName, GetTimeUs() - startTime); } diff --git a/Server/mods/deathmatch/logic/CMapManager.cpp b/Server/mods/deathmatch/logic/CMapManager.cpp index bf9a63dd5c4..29b9c7eb2e4 100644 --- a/Server/mods/deathmatch/logic/CMapManager.cpp +++ b/Server/mods/deathmatch/logic/CMapManager.cpp @@ -372,8 +372,8 @@ void CMapManager::BroadcastResourceElements(CElement* pResourceElement, CElement CEntityAddPacket Packet; Packet.Add(pResourceElement); - std::set doneElements; // Lookup map of elements already processed - std::vector pPerPlayerList; // A list of per player elements we will process the last + std::set doneElements; // Lookup map of elements already processed + std::vector pPerPlayerList; // A list of per player elements we will process the last if (pResourceElement->CountChildren() > 0) BroadcastElementChildren(pResourceElement, Packet, pPerPlayerList, doneElements); @@ -473,7 +473,7 @@ void CMapManager::OnPlayerJoin(CPlayer& Player) unsigned char ucBlendedWeatherHour = m_pBlendedWeather->GetBlendedStopHour(); // FPS Limit - unsigned short usFPSLimit = g_pGame->GetConfig()->GetFPSLimit(); + std::uint16_t fps = g_pGame->GetConfig()->GetFPSLimit(); // Garage states const SGarageStates& garageStates = g_pGame->GetGarageStates(); @@ -524,11 +524,11 @@ void CMapManager::OnPlayerJoin(CPlayer& Player) // Send the packet to the given player Player.Send(CMapInfoPacket(ucCurrentWeather, ucWeatherBlendingTo, ucBlendedWeatherHour, ucClockHour, ucClockMin, ulMinuteDuration, bNametagsEnabled, bRadarEnabled, fGravity, fGameSpeed, fWaveHeight, worldWaterLevelInfo, bHasSkyGradient, garageStates, ucTopRed, ucTopGreen, - ucTopBlue, ucBottomRed, ucBottomGreen, ucBottomBlue, bHasHeatHaze, heatHazeSettings, usFPSLimit, bCloudsEnabled, - fJetpackMaxHeight, bOverrideWaterColor, ucWaterRed, ucWaterGreen, ucWaterBlue, ucWaterAlpha, bInteriorSoundsEnabled, - bOverrideRainLevel, fRainLevel, bOverrideSunSize, fSunSize, bOverrideSunColor, ucCoreR, ucCoreG, ucCoreB, ucCoronaR, ucCoronaG, - ucCoronaB, bOverrideWindVelocity, fWindVelX, fWindVelY, fWindVelZ, bOverrideFarClipDistance, fFarClip, bOverrideFogDistance, - fFogDistance, fAircraftMaxHeight, fAircraftMaxVelocity, bOverrideMoonSize, iMoonSize)); + ucTopBlue, ucBottomRed, ucBottomGreen, ucBottomBlue, bHasHeatHaze, heatHazeSettings, fps, bCloudsEnabled, fJetpackMaxHeight, + bOverrideWaterColor, ucWaterRed, ucWaterGreen, ucWaterBlue, ucWaterAlpha, bInteriorSoundsEnabled, bOverrideRainLevel, fRainLevel, + bOverrideSunSize, fSunSize, bOverrideSunColor, ucCoreR, ucCoreG, ucCoreB, ucCoronaR, ucCoronaG, ucCoronaB, bOverrideWindVelocity, + fWindVelX, fWindVelY, fWindVelZ, bOverrideFarClipDistance, fFarClip, bOverrideFogDistance, fFogDistance, fAircraftMaxHeight, + fAircraftMaxVelocity, bOverrideMoonSize, iMoonSize)); marker.Set("SendMapInfoPacket"); diff --git a/Server/mods/deathmatch/logic/CMarker.cpp b/Server/mods/deathmatch/logic/CMarker.cpp index 5055b01b586..5eabd474891 100644 --- a/Server/mods/deathmatch/logic/CMarker.cpp +++ b/Server/mods/deathmatch/logic/CMarker.cpp @@ -14,6 +14,7 @@ #include "CMarkerManager.h" #include "CColCircle.h" #include "CColSphere.h" +#include "CColTube.h" #include "CResource.h" #include "CLogger.h" #include "Utils.h" @@ -342,15 +343,15 @@ void CMarker::Callback_OnCollision(CColShape& Shape, CElement& Element) { // Call the marker hit event CLuaArguments Arguments; - Arguments.PushElement(&Element); // Hit element - Arguments.PushBoolean(GetDimension() == Element.GetDimension()); // Matching dimension? + Arguments.PushElement(&Element); // Hit element + Arguments.PushBoolean(GetDimension() == Element.GetDimension()); // Matching dimension? CallEvent("onMarkerHit", Arguments); if (IS_PLAYER(&Element)) { CLuaArguments Arguments2; - Arguments2.PushElement(this); // marker - Arguments2.PushBoolean(GetDimension() == Element.GetDimension()); // Matching dimension? + Arguments2.PushElement(this); // marker + Arguments2.PushBoolean(GetDimension() == Element.GetDimension()); // Matching dimension? Element.CallEvent("onPlayerMarkerHit", Arguments2); } } @@ -363,15 +364,15 @@ void CMarker::Callback_OnLeave(CColShape& Shape, CElement& Element) { // Call the marker hit event CLuaArguments Arguments; - Arguments.PushElement(&Element); // Hit element - Arguments.PushBoolean(GetDimension() == Element.GetDimension()); // Matching dimension? + Arguments.PushElement(&Element); // Hit element + Arguments.PushBoolean(GetDimension() == Element.GetDimension()); // Matching dimension? CallEvent("onMarkerLeave", Arguments); if (IS_PLAYER(&Element)) { CLuaArguments Arguments2; - Arguments2.PushElement(this); // marker - Arguments2.PushBoolean(GetDimension() == Element.GetDimension()); // Matching dimension? + Arguments2.PushElement(this); // marker + Arguments2.PushBoolean(GetDimension() == Element.GetDimension()); // Matching dimension? Element.CallEvent("onPlayerMarkerLeave", Arguments2); } } @@ -398,6 +399,13 @@ void CMarker::UpdateCollisionObject(unsigned char ucOldType) m_pCollision = new CColCircle(m_pColManager, nullptr, m_vecPosition, m_fSize, true); } + else if (m_ucType == CMarker::TYPE_CYLINDER) + { + if (m_pCollision) + g_pGame->GetElementDeleter()->Delete(m_pCollision); + + m_pCollision = new CColTube(m_pColManager, nullptr, m_vecPosition, m_fSize, m_fSize); + } else if (ucOldType == CMarker::TYPE_CHECKPOINT) { if (m_pCollision) @@ -416,6 +424,12 @@ void CMarker::UpdateCollisionObject(unsigned char ucOldType) { static_cast(m_pCollision)->SetRadius(m_fSize); } + else if (m_ucType == CMarker::TYPE_CYLINDER) + { + CColTube* pShape = static_cast(m_pCollision); + pShape->SetRadius(m_fSize); + pShape->SetHeight(m_fSize <= 1.5 ? m_fSize + 1 : m_fSize); + } else { static_cast(m_pCollision)->SetRadius(m_fSize); diff --git a/Server/mods/deathmatch/logic/CMarker.h b/Server/mods/deathmatch/logic/CMarker.h index ddc9c4831ac..d48c08d2d67 100644 --- a/Server/mods/deathmatch/logic/CMarker.h +++ b/Server/mods/deathmatch/logic/CMarker.h @@ -72,7 +72,7 @@ class CMarker : public CPerPlayerEntity, private CColCallback SColor GetTargetArrowColor() const noexcept { return m_TargetArrowColor; }; float GetTargetArrowSize() const noexcept { return m_TargetArrowSize; }; - void SetTargetArrowProperties(const SColor color, float size) noexcept; + void SetTargetArrowProperties(const SColor color, float size) noexcept; protected: bool ReadSpecialData(const int iLine) override; diff --git a/Server/mods/deathmatch/logic/CObject.cpp b/Server/mods/deathmatch/logic/CObject.cpp index a56b0dea91c..4c5e7d30ec2 100644 --- a/Server/mods/deathmatch/logic/CObject.cpp +++ b/Server/mods/deathmatch/logic/CObject.cpp @@ -13,6 +13,9 @@ #include "CObject.h" #include "CLogger.h" #include "Utils.h" +#include "CGame.h" +#include "packets/CElementRPCPacket.h" +#include extern CGame* g_pGame; @@ -245,7 +248,7 @@ const CVector& CObject::GetPosition() } if (vecOldPosition != m_vecPosition) - UpdateSpatialData(); // This is necessary because 'GetAttachedPosition ( m_vecPosition )' can change alter this objects position + UpdateSpatialData(); // This is necessary because 'GetAttachedPosition ( m_vecPosition )' can change alter this objects position // Finally, return it return m_vecPosition; } @@ -271,12 +274,12 @@ void CObject::SetPosition(const CVector& vecPosition) void CObject::GetRotation(CVector& vecRotation) { - vecRotation = m_vecRotation; - // Are we attached to something? if (m_pAttachedTo) + { + vecRotation = m_vecRotation; GetAttachedRotation(vecRotation); - + } // Are we moving? else if (IsMoving()) { @@ -289,6 +292,11 @@ void CObject::GetRotation(CVector& vecRotation) } vecRotation = m_vecRotation; } + else + { + // Not moving and not attached, return stored rotation + vecRotation = m_vecRotation; + } } void CObject::SetRotation(const CVector& vecRotation) @@ -352,8 +360,7 @@ void CObject::Move(const CPositionRotationAnimation& a_rMoveAnimation) void CObject::StopMoving() { - // Were we moving in the first place - if (m_pMoveAnimation != NULL) + if (m_pMoveAnimation != nullptr) { SPositionRotation positionRotation; m_pMoveAnimation->GetValue(positionRotation); @@ -361,21 +368,22 @@ void CObject::StopMoving() m_vecRotation = positionRotation.m_vecRotation; delete m_pMoveAnimation; - m_pMoveAnimation = NULL; + m_pMoveAnimation = nullptr; UpdateSpatialData(); + NotifyMovementComplete(); } } const CPositionRotationAnimation* CObject::GetMoveAnimation() { - if (IsMoving()) // Call IsMoving since it will make sure the anim is stopped if it's finished + if (IsMoving()) // Call IsMoving since it will make sure the anim is stopped if it's finished { return m_pMoveAnimation; } else { - return NULL; + return nullptr; } } @@ -427,7 +435,7 @@ bool CObject::SetLowLodObject(CObject* pNewLowLodObject) // Clear there and here ListRemove(m_pLowLodObject->m_HighLodObjectList, this); - m_pLowLodObject = NULL; + m_pLowLodObject = nullptr; return true; } else @@ -437,7 +445,7 @@ bool CObject::SetLowLodObject(CObject* pNewLowLodObject) return false; // Remove any previous link - SetLowLodObject(NULL); + SetLowLodObject(nullptr); // Make new link m_pLowLodObject = pNewLowLodObject; @@ -449,6 +457,18 @@ bool CObject::SetLowLodObject(CObject* pNewLowLodObject) CObject* CObject::GetLowLodObject() { if (m_bIsLowLod) - return NULL; + return nullptr; return m_pLowLodObject; } + +void CObject::NotifyMovementComplete() +{ + CBitStream BitStream; + BitStream.pBitStream->Write(m_vecPosition.fX); + BitStream.pBitStream->Write(m_vecPosition.fY); + BitStream.pBitStream->Write(m_vecPosition.fZ); + BitStream.pBitStream->Write(m_vecRotation.fX); + BitStream.pBitStream->Write(m_vecRotation.fY); + BitStream.pBitStream->Write(m_vecRotation.fZ); + g_pGame->GetPlayerManager()->BroadcastOnlyJoined(CElementRPCPacket(this, STOP_OBJECT, *BitStream.pBitStream)); +} diff --git a/Server/mods/deathmatch/logic/CObject.h b/Server/mods/deathmatch/logic/CObject.h index fc794c6aafd..23a0cf91907 100644 --- a/Server/mods/deathmatch/logic/CObject.h +++ b/Server/mods/deathmatch/logic/CObject.h @@ -101,12 +101,14 @@ class CObject : public CElement bool m_bVisibleInAllDimensions = false; bool m_bRespawnable; + void NotifyMovementComplete(); + protected: bool m_bCollisionsEnabled; - const bool m_bIsLowLod; // true if this object is low LOD - CObject* m_pLowLodObject; // Pointer to low LOD version of this object - std::vector m_HighLodObjectList; // List of objects that use this object as a low LOD version + const bool m_bIsLowLod; // true if this object is low LOD + CObject* m_pLowLodObject; // Pointer to low LOD version of this object + std::vector m_HighLodObjectList; // List of objects that use this object as a low LOD version public: CPositionRotationAnimation* m_pMoveAnimation; diff --git a/Server/mods/deathmatch/logic/CObjectSync.cpp b/Server/mods/deathmatch/logic/CObjectSync.cpp index e6a98078b79..745d4f89da5 100644 --- a/Server/mods/deathmatch/logic/CObjectSync.cpp +++ b/Server/mods/deathmatch/logic/CObjectSync.cpp @@ -14,8 +14,8 @@ #ifdef WITH_OBJECT_SYNC -#define SYNC_RATE 500 -#define MAX_PLAYER_SYNC_DISTANCE 100.0f + #define SYNC_RATE 500 + #define MAX_PLAYER_SYNC_DISTANCE 100.0f CObjectSync::CObjectSync(CPlayerManager* pPlayerManager, CObjectManager* pObjectManager) { @@ -141,7 +141,7 @@ void CObjectSync::StartSync(CPlayer* pPlayer, CObject* pObject) // Call the onElementStartSync event CLuaArguments Arguments; - Arguments.PushElement(pPlayer); // New syncer + Arguments.PushElement(pPlayer); // New syncer pObject->CallEvent("onElementStartSync", Arguments); } @@ -158,7 +158,7 @@ void CObjectSync::StopSync(CObject* pObject) // Call the onElementStopSync event CLuaArguments Arguments; - Arguments.PushElement(pSyncer); // Old syncer + Arguments.PushElement(pSyncer); // Old syncer pObject->CallEvent("onElementStopSync", Arguments); } diff --git a/Server/mods/deathmatch/logic/CObjectSync.h b/Server/mods/deathmatch/logic/CObjectSync.h index e24eb1d928f..9aa8fee125b 100644 --- a/Server/mods/deathmatch/logic/CObjectSync.h +++ b/Server/mods/deathmatch/logic/CObjectSync.h @@ -13,9 +13,9 @@ #ifdef WITH_OBJECT_SYNC -#include "CPlayerManager.h" -#include "CObjectManager.h" -#include "packets/CObjectSyncPacket.h" + #include "CPlayerManager.h" + #include "CObjectManager.h" + #include "packets/CObjectSyncPacket.h" class CObjectSync { diff --git a/Server/mods/deathmatch/logic/CPacketTranslator.cpp b/Server/mods/deathmatch/logic/CPacketTranslator.cpp index 2d12509c502..20ced1ab808 100644 --- a/Server/mods/deathmatch/logic/CPacketTranslator.cpp +++ b/Server/mods/deathmatch/logic/CPacketTranslator.cpp @@ -250,10 +250,10 @@ CPacket* CPacketTranslator::Translate(const NetServerPlayerID& Socket, ePacketID else // Attempt to read the content, if we fail, delete the packet again if (!pTemp->Read(BitStream)) - { - delete pTemp; - pTemp = NULL; - } + { + delete pTemp; + pTemp = NULL; + } } // Return the class diff --git a/Server/mods/deathmatch/logic/CPad.cpp b/Server/mods/deathmatch/logic/CPad.cpp index b8676bde1ac..a7a3f2713f0 100644 --- a/Server/mods/deathmatch/logic/CPad.cpp +++ b/Server/mods/deathmatch/logic/CPad.cpp @@ -78,7 +78,7 @@ static const SString g_mtaControls[] = { "vehicle_next_weapon", "vehicle_previous_weapon", "sinfo", - "textscale" // Anything missing here? + "textscale" // Anything missing here? }; CPad::CPad(CPlayer* pPlayer) @@ -121,10 +121,10 @@ void CPad::UpdateKeys() m_ControlStates[0].bState = (m_csCurrentState.ButtonCircle) ? true : false; m_ControlStates[1].bState = (m_csCurrentState.RightShoulder2) ? true : false; m_ControlStates[2].bState = (m_csCurrentState.LeftShoulder2) ? true : false; - m_ControlStates[3].bState = (m_csCurrentState.LeftStickY < 0); // forwards - m_ControlStates[4].bState = (m_csCurrentState.LeftStickY > 0); // backwards - m_ControlStates[5].bState = (m_csCurrentState.LeftStickX < 0); // left - m_ControlStates[6].bState = (m_csCurrentState.LeftStickX > 0); // right + m_ControlStates[3].bState = (m_csCurrentState.LeftStickY < 0); // forwards + m_ControlStates[4].bState = (m_csCurrentState.LeftStickY > 0); // backwards + m_ControlStates[5].bState = (m_csCurrentState.LeftStickX < 0); // left + m_ControlStates[6].bState = (m_csCurrentState.LeftStickX > 0); // right m_ControlStates[7].bState = (m_csCurrentState.RightShoulder2) ? true : false; m_ControlStates[8].bState = (m_csCurrentState.LeftShoulder2) ? true : false; m_ControlStates[9].bState = (m_csCurrentState.LeftShoulder2) ? true : false; @@ -167,8 +167,8 @@ void CPad::UpdateKeys() m_ControlStates[37].bState = (m_csCurrentState.RightStickY > 0); m_ControlStates[38].bState = (m_csCurrentState.RightStickY < 0); } - m_ControlStates[9].bState = (m_csCurrentState.ButtonTriangle); // Enter Exit - m_ControlStates[10].bState = (m_csCurrentState.Select) ? true : false; // Change View + m_ControlStates[9].bState = (m_csCurrentState.ButtonTriangle); // Enter Exit + m_ControlStates[10].bState = (m_csCurrentState.Select) ? true : false; // Change View } } diff --git a/Server/mods/deathmatch/logic/CPad.h b/Server/mods/deathmatch/logic/CPad.h index 203e3d9ac99..18ea6cc5fe7 100644 --- a/Server/mods/deathmatch/logic/CPad.h +++ b/Server/mods/deathmatch/logic/CPad.h @@ -20,9 +20,9 @@ class CPad; class CControllerState { public: - signed short LeftStickX; // move/steer left (-128?)/right (+128) - signed short LeftStickY; // move back(+128)/forwards(-128?) - signed short RightStickX; // numpad 6(+128)/numpad 4(-128?) + signed short LeftStickX; // move/steer left (-128?)/right (+128) + signed short LeftStickY; // move back(+128)/forwards(-128?) + signed short RightStickX; // numpad 6(+128)/numpad 4(-128?) signed short RightStickY; // signed short LeftShoulder1; @@ -30,8 +30,8 @@ class CControllerState // signed short RightShoulder1; // target / hand brake signed short RightShoulder2; - signed short DPadUp; // radio change up - signed short DPadDown; // radio change down + signed short DPadUp; // radio change up + signed short DPadDown; // radio change down signed short DPadLeft; signed short DPadRight; @@ -44,7 +44,7 @@ class CControllerState // signed short ButtonCircle; // fire // signed short ShockButtonL; - signed short ShockButtonR; // look behind + signed short ShockButtonR; // look behind signed short m_bChatIndicated; // signed short m_bPedWalk; @@ -137,7 +137,7 @@ struct SGTAControlState bool bEnabled; }; -#define NUM_CONTROL_STATES 45 +#define NUM_CONTROL_STATES 45 #define NUM_MTA_CONTROL_STATES 19 class CPad diff --git a/Server/mods/deathmatch/logic/CPed.cpp b/Server/mods/deathmatch/logic/CPed.cpp index 65e7bcf6c95..17ad9fc56cd 100644 --- a/Server/mods/deathmatch/logic/CPed.cpp +++ b/Server/mods/deathmatch/logic/CPed.cpp @@ -41,7 +41,7 @@ CPed::CPed(CPedManager* pPedManager, CElement* pParent, unsigned short usModel) m_armor = 0.0f; memset(&m_fStats[0], 0, sizeof(m_fStats)); - m_fStats[24] = 569.0f; // default max_health + m_fStats[24] = 569.0f; // default max_health m_pClothes = new CPlayerClothes; m_pClothes->DefaultClothes(); @@ -63,7 +63,7 @@ CPed::CPed(CPedManager* pPedManager, CElement* pParent, unsigned short usModel) m_bSpawned = false; m_fRotation = 0.0f; m_pTargetedEntity = NULL; - m_ucFightingStyle = 15; // STYLE_GRAB_KICK + m_ucFightingStyle = 15; // STYLE_GRAB_KICK m_iMoveAnim = MOVE_DEFAULT; m_fGravity = 0.008f; m_bDoingGangDriveby = false; @@ -369,14 +369,12 @@ bool CPed::HasWeaponType(unsigned char ucWeaponType) float CPed::GetMaxHealth() { - // TODO: Verify this formula - // Grab his player health stat float fStat = GetPlayerStat(24 /*MAX_HEALTH*/); // Do a linear interpolation to get how much health this would allow - // Assumes: 100 health = 569 stat, 200 health = 1000 stat. - float fMaxHealth = 100.0f + (100.0f / 431.0f * (fStat - 569.0f)); + // Assumes: 100 health = 569 stat, 176 health = 1000 stat. + float fMaxHealth = fStat * 0.176f; // Return the max health. Make sure it can't be below 1 if (fMaxHealth < 1.0f) @@ -479,22 +477,28 @@ void CPed::SetSyncer(CPlayer* pPlayer) { case VEHICLEACTION_ENTERING: { - CVehicle* pVehicle = GetOccupiedVehicle(); - unsigned char ucOccupiedSeat = static_cast(GetOccupiedVehicleSeat()); - // Does it have an occupant and is the occupant us? - if (pVehicle && (this == pVehicle->GetOccupant(ucOccupiedSeat))) + CVehicle* pVehicle = GetOccupiedVehicle(); + const unsigned int uiOccupiedSeat = GetOccupiedVehicleSeat(); + if (uiOccupiedSeat > 0xFF) + break; + + const unsigned char occupiedSeat = static_cast(uiOccupiedSeat); + if (pVehicle && (this == pVehicle->GetOccupant(occupiedSeat))) { // Warp us into vehicle - CStaticFunctionDefinitions::WarpPedIntoVehicle(this, pVehicle, ucOccupiedSeat); + CStaticFunctionDefinitions::WarpPedIntoVehicle(this, pVehicle, occupiedSeat); } } case VEHICLEACTION_EXITING: { - CVehicle* pVehicle = GetOccupiedVehicle(); - unsigned char ucOccupiedSeat = GetOccupiedVehicleSeat(); - // Does it have an occupant and is the occupant us? - if (pVehicle && (this == pVehicle->GetOccupant(ucOccupiedSeat))) + CVehicle* pVehicle = GetOccupiedVehicle(); + const unsigned int uiOccupiedSeat = GetOccupiedVehicleSeat(); + if (uiOccupiedSeat > 0xFF) + break; + + const unsigned char occupiedSeat = static_cast(uiOccupiedSeat); + if (pVehicle && (this == pVehicle->GetOccupant(occupiedSeat))) { // Warp us out of vehicle CStaticFunctionDefinitions::RemovePedFromVehicle(this); diff --git a/Server/mods/deathmatch/logic/CPed.h b/Server/mods/deathmatch/logic/CPed.h index 4e8440afa80..e3c44201909 100644 --- a/Server/mods/deathmatch/logic/CPed.h +++ b/Server/mods/deathmatch/logic/CPed.h @@ -19,9 +19,9 @@ #include #define INVALID_VEHICLE_SEAT 0xFF -#define NUM_PLAYER_STATS 343 -#define WEAPON_SLOTS 13 -#define STEALTH_KILL_RANGE 2.5f +#define NUM_PLAYER_STATS 343 +#define WEAPON_SLOTS 13 +#define STEALTH_KILL_RANGE 2.5f enum ePedMoveAnim { @@ -115,7 +115,7 @@ struct SPlayerAnimData int blendTime{250}; bool taskToBeRestoredOnAnimEnd{false}; - std::int64_t startedTick{0}; + std::int64_t startTime{0}; float progress{0.0f}; float speed{1.0f}; @@ -309,6 +309,9 @@ class CPed : public CElement void SetAnimationProgress(float progress) { m_animData.progress = progress; }; void SetAnimationSpeed(float speed) { m_animData.speed = speed; }; + void SetHanging(bool hanging) noexcept { m_hanging = hanging; } + bool IsHanging() const noexcept { return m_hanging; } + protected: bool ReadSpecialData(const int iLine) override; @@ -350,6 +353,7 @@ class CPed : public CElement CVehicle* m_pJackingVehicle; SPlayerAnimData m_animData{}; float m_cameraRotation{}; + bool m_hanging{false}; // Is the player hanging during a climb task? CVehicle* m_pVehicle; unsigned int m_uiVehicleSeat; diff --git a/Server/mods/deathmatch/logic/CPedSync.cpp b/Server/mods/deathmatch/logic/CPedSync.cpp index 13dfad1c434..0523d7beb31 100644 --- a/Server/mods/deathmatch/logic/CPedSync.cpp +++ b/Server/mods/deathmatch/logic/CPedSync.cpp @@ -82,7 +82,7 @@ void CPedSync::OverrideSyncer(CPed* pPed, CPlayer* pPlayer, bool bPersist) void CPedSync::UpdateAllSyncer() { - auto currentTick = GetTickCount64_(); + auto currentTimestamp = GetTimestamp(); // Update all the ped's sync states for (auto iter = m_pPedManager->IterBegin(); iter != m_pPedManager->IterEnd(); iter++) @@ -91,7 +91,8 @@ void CPedSync::UpdateAllSyncer() const SPlayerAnimData& animData = (*iter)->GetAnimationData(); if (animData.IsAnimating()) { - float deltaTime = currentTick - animData.startedTick; + const std::int64_t elapsedMs = currentTimestamp >= animData.startTime ? (currentTimestamp - animData.startTime) : 0; + const float deltaTime = static_cast(elapsedMs); if (!animData.freezeLastFrame && animData.time > 0 && deltaTime >= animData.time) (*iter)->SetAnimationData({}); } @@ -163,7 +164,7 @@ void CPedSync::StartSync(CPlayer* pPlayer, CPed* pPed) // Call the onElementStartSync event CLuaArguments Arguments; - Arguments.PushElement(pPlayer); // New syncer + Arguments.PushElement(pPlayer); // New syncer pPed->CallEvent("onElementStartSync", Arguments); } @@ -180,7 +181,7 @@ void CPedSync::StopSync(CPed* pPed) // Call the onElementStopSync event CLuaArguments Arguments; - Arguments.PushElement(pSyncer); // Old syncer + Arguments.PushElement(pSyncer); // Old syncer pPed->CallEvent("onElementStopSync", Arguments); } diff --git a/Server/mods/deathmatch/logic/CPerPlayerEntity.cpp b/Server/mods/deathmatch/logic/CPerPlayerEntity.cpp index 9c4ec6969e3..050f6747df5 100644 --- a/Server/mods/deathmatch/logic/CPerPlayerEntity.cpp +++ b/Server/mods/deathmatch/logic/CPerPlayerEntity.cpp @@ -77,7 +77,7 @@ void CPerPlayerEntity::OnReferencedSubtreeRemove(CElement* pElement) void CPerPlayerEntity::UpdatePerPlayer() { - if (m_PlayersAdded.empty() && m_PlayersRemoved.empty()) // This check reduces cpu usage when loading large maps (due to recursion) + if (m_PlayersAdded.empty() && m_PlayersRemoved.empty()) // This check reduces cpu usage when loading large maps (due to recursion) return; // Remove entries that match in both added and removed lists @@ -310,7 +310,7 @@ void CPerPlayerEntity::AddPlayersBelow(CElement* pElement, std::set& A for (; iterChildren != pElement->IterEnd(); iterChildren++) { CElement* pElement = *iterChildren; - if (pElement->CountChildren() || IS_PLAYER(pElement)) // This check reduces cpu usage when loading large maps (due to recursion) + if (pElement->CountChildren() || IS_PLAYER(pElement)) // This check reduces cpu usage when loading large maps (due to recursion) AddPlayersBelow(pElement, Added); } } @@ -338,7 +338,7 @@ void CPerPlayerEntity::RemovePlayersBelow(CElement* pElement, std::set for (; iterChildren != pElement->IterEnd(); iterChildren++) { CElement* pElement = *iterChildren; - if (pElement->CountChildren() || IS_PLAYER(pElement)) // This check reduces cpu usage when unloading large maps (due to recursion) + if (pElement->CountChildren() || IS_PLAYER(pElement)) // This check reduces cpu usage when unloading large maps (due to recursion) RemovePlayersBelow(pElement, Removed); } } diff --git a/Server/mods/deathmatch/logic/CPerfStat.BandwidthUsage.cpp b/Server/mods/deathmatch/logic/CPerfStat.BandwidthUsage.cpp index 337868c283f..457abb7e291 100644 --- a/Server/mods/deathmatch/logic/CPerfStat.BandwidthUsage.cpp +++ b/Server/mods/deathmatch/logic/CPerfStat.BandwidthUsage.cpp @@ -52,7 +52,7 @@ namespace BWSTAT_INDEX_COUNT, }; - #define BW_STATS_TABLE_NAME "`perfstats_bandwidth_usage`" +#define BW_STATS_TABLE_NAME "`perfstats_bandwidth_usage`" SFixedArray BWStatIndexNameList = {{ "Special", @@ -83,11 +83,17 @@ namespace } // Unix time in, stats hours out - uint UnixTimeToStatsHours(time_t tTime) { return static_cast((tTime - 1293861600UL) / 3600UL); } + uint UnixTimeToStatsHours(time_t tTime) + { + return static_cast((tTime - 1293861600UL) / 3600UL); + } // Stats hours in, unix time out - time_t StatsHoursToUnixTime(uint uiStatsHours) { return uiStatsHours * 3600UL + 1293861600UL; } -} // namespace + time_t StatsHoursToUnixTime(uint uiStatsHours) + { + return uiStatsHours * 3600UL + 1293861600UL; + } +} // namespace /////////////////////////////////////////////////////////////// // @@ -302,8 +308,8 @@ void CPerfStatBandwidthUsageImpl::LoadStats() // Special item const SNetStatHistoryType& type = m_History[BWSTAT_INDEX_SPECIAL]; - uint uiStatsHoursThen = (uint)type.itemList[0].llGameSent; // Hours since 1/1/2011 - uint uiStatsHoursNow = UnixTimeToStatsHours(tTime); // Hours since 1/1/2011 + uint uiStatsHoursThen = (uint)type.itemList[0].llGameSent; // Hours since 1/1/2011 + uint uiStatsHoursNow = UnixTimeToStatsHours(tTime); // Hours since 1/1/2011 int iHoursElpased = uiStatsHoursNow - uiStatsHoursThen; // Max elapsed time of 13 months @@ -482,7 +488,7 @@ void CPerfStatBandwidthUsageImpl::AddSampleAtTime(time_t tTime, long long llGame else if (i == BWSTAT_INDEX_SPECIAL) { // Calculate special value - uint uiStatsHours = UnixTimeToStatsHours(tTime); // Hours since 1/1/2011 + uint uiStatsHours = UnixTimeToStatsHours(tTime); // Hours since 1/1/2011 if (uiStatsHours != (uint)type.itemList[0].llGameSent) { type.itemList[0].bDirty = true; @@ -626,7 +632,7 @@ void CPerfStatBandwidthUsageImpl::GetStats(CPerfStatResult* pResult, const std:: row[c++] = CPerfStatManager::GetScaledByteString(item.llGameRecv); row[c++] = CPerfStatManager::GetScaledByteString(item.llGameSent); if (bShowSentLoss[t]) - row[c++] = item.llGameResent ? CPerfStatManager::GetPercentString(item.llGameResent, item.llGameSent) : ""; + row[c++] = item.llGameResent ? CPerfStatManager::GetPercentString(item.llGameResent, item.llGameSent) : SStringX(""); row[c++] = CPerfStatManager::GetScaledByteString(item.llHttpSent); if (bShowBlocked[t]) row[c++] = CPerfStatManager::GetScaledByteString(item.llGameRecvBlocked); diff --git a/Server/mods/deathmatch/logic/CPerfStat.DebugInfo.cpp b/Server/mods/deathmatch/logic/CPerfStat.DebugInfo.cpp index d2d83362caa..a9251fa7350 100644 --- a/Server/mods/deathmatch/logic/CPerfStat.DebugInfo.cpp +++ b/Server/mods/deathmatch/logic/CPerfStat.DebugInfo.cpp @@ -20,7 +20,7 @@ namespace SString strHead; SString strData; }; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // diff --git a/Server/mods/deathmatch/logic/CPerfStat.DebugTable.cpp b/Server/mods/deathmatch/logic/CPerfStat.DebugTable.cpp index b27d27f7322..32e6d54d502 100644 --- a/Server/mods/deathmatch/logic/CPerfStat.DebugTable.cpp +++ b/Server/mods/deathmatch/logic/CPerfStat.DebugTable.cpp @@ -20,7 +20,7 @@ namespace CTickCount endTickCount; bool bHasEndTime; }; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -49,7 +49,7 @@ class CPerfStatDebugTableImpl : public CPerfStatDebugTable SString m_strCategoryName; CElapsedTime m_TimeSinceRemoveOld; std::map m_LineMap; - CCriticalSection m_CS; // Required as some methods are called from the database thread + CCriticalSection m_CS; // Required as some methods are called from the database thread }; /////////////////////////////////////////////////////////////// diff --git a/Server/mods/deathmatch/logic/CPerfStat.FunctionTiming.cpp b/Server/mods/deathmatch/logic/CPerfStat.FunctionTiming.cpp index 5e833a37286..58bca2c51da 100644 --- a/Server/mods/deathmatch/logic/CPerfStat.FunctionTiming.cpp +++ b/Server/mods/deathmatch/logic/CPerfStat.FunctionTiming.cpp @@ -76,7 +76,7 @@ namespace } }; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -421,10 +421,10 @@ void CPerfStatFunctionTimingImpl::GetStats(CPerfStatResult* pResult, const std:: row[c++] = SString("%2.0f ms", prev5s.fPeakMs); row[c++] = SString("%2.0f ms (%s)", prev5s.fResBiggestMs, *prev5s.strResBiggestMsName); - row[c++] = prev5s.uiTotalBytes < 10 ? "" : SString("%s", *CPerfStatManager::GetScaledByteString(prev5s.uiTotalBytes)); - // row[c++] = prev5s.uiPeakBytes < 10 ? "" : SString ( "%s ", *CPerfStatManager::GetScaledByteString( prev5s.uiPeakBytes ) ); + row[c++] = prev5s.uiTotalBytes < 10 ? SStringX("") : SString("%s", *CPerfStatManager::GetScaledByteString(prev5s.uiTotalBytes)); + // row[c++] = prev5s.uiPeakBytes < 10 ? SStringX("") : SString ( "%s ", *CPerfStatManager::GetScaledByteString( prev5s.uiPeakBytes ) ); row[c++] = prev5s.uiResBiggestBytes < 10 - ? "" + ? SStringX("") : SString("%s (%s)", *CPerfStatManager::GetScaledByteString(prev5s.uiResBiggestBytes), *prev5s.strResBiggestBytesName); } @@ -434,10 +434,10 @@ void CPerfStatFunctionTimingImpl::GetStats(CPerfStatResult* pResult, const std:: row[c++] = SString("%2.0f ms", prev60s.fPeakMs); row[c++] = SString("%2.0f ms (%s)", prev60s.fResBiggestMs, *prev60s.strResBiggestMsName); - row[c++] = prev60s.uiTotalBytes < 10 ? "" : SString("%s ", *CPerfStatManager::GetScaledByteString(prev60s.uiTotalBytes)); - // row[c++] = prev60s.uiPeakBytes < 10 ? "" : SString ( "%s ", *CPerfStatManager::GetScaledByteString( prev60s.uiPeakBytes ) ); + row[c++] = prev60s.uiTotalBytes < 10 ? SStringX("") : SString("%s ", *CPerfStatManager::GetScaledByteString(prev60s.uiTotalBytes)); + // row[c++] = prev60s.uiPeakBytes < 10 ? SStringX("") : SString ( "%s ", *CPerfStatManager::GetScaledByteString( prev60s.uiPeakBytes ) ); row[c++] = prev60s.uiResBiggestBytes < 10 - ? "" + ? SStringX("") : SString("%s (%s)", *CPerfStatManager::GetScaledByteString(prev60s.uiResBiggestBytes), *prev60s.strResBiggestBytesName); } } diff --git a/Server/mods/deathmatch/logic/CPerfStat.LibMemory.cpp b/Server/mods/deathmatch/logic/CPerfStat.LibMemory.cpp index 2b4c4a15b37..0aa6150095b 100644 --- a/Server/mods/deathmatch/logic/CPerfStat.LibMemory.cpp +++ b/Server/mods/deathmatch/logic/CPerfStat.LibMemory.cpp @@ -46,7 +46,7 @@ namespace CDynamicLibrary* pLibrary; PFNGETALLOCSTATS pfnGetAllocStats; }; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -217,16 +217,16 @@ void CPerfStatLibMemoryImpl::GetLibMemoryStats(CPerfStatResult* pResult, const s { CLibraryInfo info; info.strName = libs[i]; - #if MTA_DEBUG +#if MTA_DEBUG info.strName += "_d"; - #endif - #ifdef WIN32 +#endif +#ifdef WIN32 info.strName += ".dll"; - #elif defined(__APPLE__) +#elif defined(__APPLE__) info.strName += ".dylib"; - #else +#else info.strName += ".so"; - #endif +#endif info.pLibrary = new CDynamicLibrary(); SString strPathFilename = g_pServerInterface->GetAbsolutePath(info.strName); diff --git a/Server/mods/deathmatch/logic/CPerfStat.LuaMemory.cpp b/Server/mods/deathmatch/logic/CPerfStat.LuaMemory.cpp index 6302ae519bb..f930d51528c 100644 --- a/Server/mods/deathmatch/logic/CPerfStat.LuaMemory.cpp +++ b/Server/mods/deathmatch/logic/CPerfStat.LuaMemory.cpp @@ -41,7 +41,7 @@ namespace public: CLuaMainMemoryMap LuaMainMemoryMap; }; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -292,8 +292,8 @@ void CPerfStatLuaMemoryImpl::GetLuaMemoryStats(CPerfStatResult* pResult, const s // Some extra 'all VM' things c += 6; - row[c++] = !g_pStats->iDbJobDataCount ? "-" : SString("%d", g_pStats->iDbJobDataCount); - row[c++] = g_pStats->iDbConnectionCount - 2 == 0 ? "-" : SString("%d", g_pStats->iDbConnectionCount - 2); + row[c++] = !g_pStats->iDbJobDataCount ? SStringX("-") : SString("%d", g_pStats->iDbJobDataCount); + row[c++] = g_pStats->iDbConnectionCount - 2 == 0 ? SStringX("-") : SString("%d", g_pStats->iDbConnectionCount - 2); } // For each VM @@ -321,12 +321,12 @@ void CPerfStatLuaMemoryImpl::GetLuaMemoryStats(CPerfStatResult* pResult, const s row[c++] = SString("%d KB", LuaMainMemory.Current); row[c++] = SString("%d KB", LuaMainMemory.Max); - row[c++] = !LuaMainMemory.OpenXMLFiles ? "-" : SString("%d", LuaMainMemory.OpenXMLFiles); - row[c++] = !LuaMainMemory.OpenFiles ? "-" : SString("%d", LuaMainMemory.OpenFiles); - row[c++] = !LuaMainMemory.Refs ? "-" : SString("%d", LuaMainMemory.Refs); - row[c++] = !LuaMainMemory.TimerCount ? "-" : SString("%d", LuaMainMemory.TimerCount); - row[c++] = !LuaMainMemory.ElementCount ? "-" : SString("%d", LuaMainMemory.ElementCount); - row[c++] = !LuaMainMemory.TextDisplayCount ? "-" : SString("%d", LuaMainMemory.TextDisplayCount); - row[c++] = !LuaMainMemory.TextItemCount ? "-" : SString("%d", LuaMainMemory.TextItemCount); + row[c++] = !LuaMainMemory.OpenXMLFiles ? SStringX("-") : SString("%d", LuaMainMemory.OpenXMLFiles); + row[c++] = !LuaMainMemory.OpenFiles ? SStringX("-") : SString("%d", LuaMainMemory.OpenFiles); + row[c++] = !LuaMainMemory.Refs ? SStringX("-") : SString("%d", LuaMainMemory.Refs); + row[c++] = !LuaMainMemory.TimerCount ? SStringX("-") : SString("%d", LuaMainMemory.TimerCount); + row[c++] = !LuaMainMemory.ElementCount ? SStringX("-") : SString("%d", LuaMainMemory.ElementCount); + row[c++] = !LuaMainMemory.TextDisplayCount ? SStringX("-") : SString("%d", LuaMainMemory.TextDisplayCount); + row[c++] = !LuaMainMemory.TextItemCount ? SStringX("-") : SString("%d", LuaMainMemory.TextItemCount); } } diff --git a/Server/mods/deathmatch/logic/CPerfStat.LuaTiming.cpp b/Server/mods/deathmatch/logic/CPerfStat.LuaTiming.cpp index 842fd13252c..45af36c8b09 100644 --- a/Server/mods/deathmatch/logic/CPerfStat.LuaTiming.cpp +++ b/Server/mods/deathmatch/logic/CPerfStat.LuaTiming.cpp @@ -33,8 +33,8 @@ namespace struct CTimingPair { - CTiming acc; // Accumulator for current period - CTiming prev; // Result for previous period + CTiming acc; // Accumulator for current period + CTiming prev; // Result for previous period void Pulse(CTimingPair* above) { @@ -48,10 +48,10 @@ namespace class CTimingBlock { public: - CTimingPair s5; // 5 second period - CTimingPair s60; // 60 - CTimingPair m5; // 300 - CTimingPair m60; // 3600 + CTimingPair s5; // 5 second period + CTimingPair s60; // 60 + CTimingPair m5; // 300 + CTimingPair m60; // 3600 void Pulse1s(int flags) { @@ -102,7 +102,7 @@ namespace } } }; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -270,13 +270,13 @@ void CPerfStatLuaTimingImpl::DoPulse() int flags = 0; m_SecondCounter++; - if (m_SecondCounter % 5 == 0) // 1 second + if (m_SecondCounter % 5 == 0) // 1 second flags |= 1; - if (m_SecondCounter % 60 == 0) // 60 seconds + if (m_SecondCounter % 60 == 0) // 60 seconds flags |= 2; - if (m_SecondCounter % (60 * 5) == 0) // 5 mins + if (m_SecondCounter % (60 * 5) == 0) // 5 mins flags |= 4; - if (m_SecondCounter % (60 * 60) == 0) // 60 mins + if (m_SecondCounter % (60 * 60) == 0) // 60 mins flags |= 8; AllLuaTiming.Pulse1s(flags); @@ -430,9 +430,9 @@ void CPerfStatLuaTimingImpl::OutputTimingBlock(CPerfStatResult* pResult, const C double total_p = total_s / double(threshList[i]) * 100; - row[c++] = total_p > 0.005 ? SString("%2.2f%%", total_p) : "-"; - row[c++] = total_s > 0.0005 ? SString("%2.3f", total_s) : "-"; - row[c++] = p->prev.calls > 0 ? SString("%d", p->prev.calls) : ""; + row[c++] = total_p > 0.005 ? SString("%2.2f%%", total_p) : SStringX("-"); + row[c++] = total_s > 0.0005 ? SString("%2.3f", total_s) : SStringX("-"); + row[c++] = p->prev.calls > 0 ? SString("%d", p->prev.calls) : SStringX("-"); row[c++] = avg_s > 0.0005 ? SString("%2.3f", avg_s).c_str() : bSubBlock ? "-" : ""; row[c++] = max_s > 0.0005 ? SString("%2.3f", max_s).c_str() : bSubBlock ? "-" : ""; } diff --git a/Server/mods/deathmatch/logic/CPerfStat.PacketUsage.cpp b/Server/mods/deathmatch/logic/CPerfStat.PacketUsage.cpp index 19cc44d5e9d..3b4c8ebe4e6 100644 --- a/Server/mods/deathmatch/logic/CPerfStat.PacketUsage.cpp +++ b/Server/mods/deathmatch/logic/CPerfStat.PacketUsage.cpp @@ -252,7 +252,7 @@ void CPerfStatPacketUsageImpl::GetStats(CPerfStatResult* pResult, const std::map row[c++] = SString("%d", (statInDelta.iCount + 4) / 5); row[c++] = CPerfStatManager::GetScaledByteString((statInDelta.iTotalBytes + 4) / 5); row[c++] = SString("%2.2f%%", - statInDelta.totalTime / 50000.f); // Number of microseconds in sample period ( 5sec * 1000000 ) into percent ( * 100 ) + statInDelta.totalTime / 50000.f); // Number of microseconds in sample period ( 5sec * 1000000 ) into percent ( * 100 ) } else { diff --git a/Server/mods/deathmatch/logic/CPerfStat.PlayerPacketUsage.cpp b/Server/mods/deathmatch/logic/CPerfStat.PlayerPacketUsage.cpp index f6afb548235..81b3bd24253 100644 --- a/Server/mods/deathmatch/logic/CPerfStat.PlayerPacketUsage.cpp +++ b/Server/mods/deathmatch/logic/CPerfStat.PlayerPacketUsage.cpp @@ -19,7 +19,7 @@ extern CNetServer* g_pRealNetServer; namespace { - #define TOP_COUNT (3) +#define TOP_COUNT (3) struct CTopValue { @@ -47,8 +47,8 @@ namespace struct CTimeSpan { - CTopSet acc; // Accumulator for current period - CTopSet prev; // Result for previous period + CTopSet acc; // Accumulator for current period + CTopSet prev; // Result for previous period void Pulse(CTimeSpan* above) { @@ -62,10 +62,10 @@ namespace class CTimeSpanBlock { public: - CTimeSpan s5; // 5 second period - CTimeSpan s60; // 60 - CTimeSpan m5; // 300 - CTimeSpan m60; // 3600 + CTimeSpan s5; // 5 second period + CTimeSpan s60; // 60 + CTimeSpan m5; // 300 + CTimeSpan m60; // 3600 void Pulse1s(int flags) { @@ -95,7 +95,7 @@ namespace } } }; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -200,13 +200,13 @@ void CPerfStatPlayerPacketUsageImpl::DoPulse() int flags = 0; m_SecondCounter++; - if (m_SecondCounter % 5 == 0) // 5 second + if (m_SecondCounter % 5 == 0) // 5 second flags |= 1; - if (m_SecondCounter % 60 == 0) // 60 seconds + if (m_SecondCounter % 60 == 0) // 60 seconds flags |= 2; - if (m_SecondCounter % (5 * 60) == 0) // 5 mins + if (m_SecondCounter % (5 * 60) == 0) // 5 mins flags |= 4; - if (m_SecondCounter % (60 * 60) == 0) // 60 mins + if (m_SecondCounter % (60 * 60) == 0) // 60 mins flags |= 8; m_AllPlayerPacketUsage.Pulse1s(flags); @@ -408,11 +408,11 @@ void CPerfStatPlayerPacketUsageImpl::OutputTimeSpanBlock(CPerfStatResult* pResul const CTimeSpan* p = timeSpanList[i]; const CTopValue& value = (p->prev.data[0].uiPktsPerSec > p->acc.data[0].uiPktsPerSec) ? p->prev.data[iTopPos] : p->acc.data[iTopPos]; - row[c++] = value.uiPktsPerSec ? SString("%d", value.uiPktsPerSec) : "-"; + row[c++] = value.uiPktsPerSec ? SString("%d", value.uiPktsPerSec) : SStringX("-"); if (bDetail) { - row[c++] = value.uiBytesInPerSec ? SString("%d", value.uiBytesInPerSec) : "-"; - row[c++] = value.uiBytesOutPerSec ? SString("%d", value.uiBytesOutPerSec) : "-"; + row[c++] = value.uiBytesInPerSec ? SString("%d", value.uiBytesInPerSec) : SStringX("-"); + row[c++] = value.uiBytesOutPerSec ? SString("%d", value.uiBytesOutPerSec) : SStringX("-"); row[c++] = value.strSerial; } row[c++] = value.strName; diff --git a/Server/mods/deathmatch/logic/CPerfStat.ServerInfo.cpp b/Server/mods/deathmatch/logic/CPerfStat.ServerInfo.cpp index f997bb201d6..c9e170d044e 100644 --- a/Server/mods/deathmatch/logic/CPerfStat.ServerInfo.cpp +++ b/Server/mods/deathmatch/logic/CPerfStat.ServerInfo.cpp @@ -51,8 +51,8 @@ namespace return strResult; } - #define UDP_PACKET_OVERHEAD (28LL) -} // namespace +#define UDP_PACKET_OVERHEAD (28LL) +} // namespace /////////////////////////////////////////////////////////////// // @@ -237,11 +237,11 @@ SString CPerfStatServerInfoImpl::GetProcessMemoryUsage() long rss; statStream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt >> utime >> stime >> - cutime >> cstime >> priority >> nice >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest + cutime >> cstime >> priority >> nice >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest statStream.close(); - long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages + long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages uint vm_usage = vsize / (1024 * 1024); uint resident_set = rss * page_size_kb / 1024; diff --git a/Server/mods/deathmatch/logic/CPerfStat.SqliteTiming.cpp b/Server/mods/deathmatch/logic/CPerfStat.SqliteTiming.cpp index f66cd919a7e..226375ac238 100644 --- a/Server/mods/deathmatch/logic/CPerfStat.SqliteTiming.cpp +++ b/Server/mods/deathmatch/logic/CPerfStat.SqliteTiming.cpp @@ -28,7 +28,7 @@ namespace SString databaseName; SString resourceName; }; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // @@ -219,7 +219,7 @@ void CPerfStatSqliteTimingImpl::GetStats(CPerfStatResult* pResult, const std::ma { GetSqliteTimingStats(pResult, optionMap, strFilter); - uint uiTicks = 1000 * 10; // 10 seconds + uint uiTicks = 1000 * 10; // 10 seconds long long llTime = GetTickCount64_(); m_llRecordStatsEndTime = llTime + uiTicks; @@ -228,9 +228,9 @@ void CPerfStatSqliteTimingImpl::GetStats(CPerfStatResult* pResult, const std::ma for (std::map::iterator iter = m_RegistryMap.begin(); iter != m_RegistryMap.end(); ++iter) { if (m_bDisableBatching) - iter->first->SuspendBatching(uiTicks); // Suspend batching + iter->first->SuspendBatching(uiTicks); // Suspend batching else - iter->first->SuspendBatching(0); // Unsuspend batching + iter->first->SuspendBatching(0); // Unsuspend batching } } diff --git a/Server/mods/deathmatch/logic/CPerfStatManager.cpp b/Server/mods/deathmatch/logic/CPerfStatManager.cpp index 342984da0a1..b83a7d916cd 100644 --- a/Server/mods/deathmatch/logic/CPerfStatManager.cpp +++ b/Server/mods/deathmatch/logic/CPerfStatManager.cpp @@ -312,12 +312,12 @@ SString CPerfStatManager::GetScaledBitString(long long Amount) SString CPerfStatManager::GetScaledFloatString(float fValue) { if (fValue < 1) - return SString("%.2f", fValue); // 0.00 to 0.99 + return SString("%.2f", fValue); // 0.00 to 0.99 if (fValue < 5) - return SString("%.1f", fValue); // 1.0 to 4.9 + return SString("%.1f", fValue); // 1.0 to 4.9 - return SString("%.0f", fValue); // 5 to inf. and beyond + return SString("%.0f", fValue); // 5 to inf. and beyond } /////////////////////////////////////////////////////////////// diff --git a/Server/mods/deathmatch/logic/CPerfStatModule.h b/Server/mods/deathmatch/logic/CPerfStatModule.h index 9efa16bf246..fab0c4acd75 100644 --- a/Server/mods/deathmatch/logic/CPerfStatModule.h +++ b/Server/mods/deathmatch/logic/CPerfStatModule.h @@ -121,7 +121,7 @@ class CPerfStatModule virtual const SString& GetCategoryName() = 0; virtual void DoPulse() = 0; virtual void GetStats(CPerfStatResult* pOutResult, const std::map& optionMap, const SString& strFilter) = 0; - virtual void Stop(){}; + virtual void Stop() {}; }; // diff --git a/Server/mods/deathmatch/logic/CPickup.cpp b/Server/mods/deathmatch/logic/CPickup.cpp index 9ab57292b26..e53feb200a5 100644 --- a/Server/mods/deathmatch/logic/CPickup.cpp +++ b/Server/mods/deathmatch/logic/CPickup.cpp @@ -129,12 +129,16 @@ bool CPickup::ReadSpecialData(const int iLine) m_usModel = CPickupManager::GetArmorModel(); } else if (IsNumericString(szBuffer)) - { // could be a weapon - usBuffer = atoi(szBuffer); - if (CPickupManager::IsValidWeaponID(usBuffer)) - { // its a weapon - m_ucType = WEAPON; - m_usModel = CPickupManager::GetWeaponModel(m_ucWeaponType); + { // could be a weapon + const int iWeaponId = atoi(szBuffer); + if (iWeaponId >= 0 && iWeaponId <= 0xFFFF) + { + usBuffer = static_cast(iWeaponId); + if (CPickupManager::IsValidWeaponID(usBuffer)) + { // it's a weapon + m_ucType = WEAPON; + m_usModel = CPickupManager::GetWeaponModel(static_cast(usBuffer)); + } } } else if (stricmp(szBuffer, "custom") == 0) @@ -243,7 +247,7 @@ bool CPickup::ReadSpecialData(const int iLine) if (GetCustomDataInt("model", iTemp, true)) { // Valid id? - if (CObjectManager::IsValidModel(iTemp) || iTemp == 370) // 370 = jetpack - sort of a hack + if (CObjectManager::IsValidModel(iTemp) || iTemp == 370) // 370 = jetpack - sort of a hack { // Set the object id m_usModel = static_cast(iTemp); @@ -406,13 +410,13 @@ void CPickup::Use(CPlayer& Player) if (!CallEvent("onPickupUse", Arguments)) { CLuaArguments Arguments2; - Arguments2.PushElement(this); // pickup + Arguments2.PushElement(this); // pickup Player.CallEvent("onPlayerPickupUse", Arguments2); } else { CLuaArguments Arguments2; - Arguments2.PushElement(this); // pickup + Arguments2.PushElement(this); // pickup if (Player.CallEvent("onPlayerPickupUse", Arguments2)) { // Tell all the other players to hide it if the respawn intervals are bigger than 0 @@ -497,7 +501,7 @@ void CPickup::Callback_OnCollision(CColShape& Shape, CElement& Element) bool bContinue1 = CallEvent("onPickupHit", Arguments); CLuaArguments Arguments2; - Arguments2.PushElement(this); // pickup + Arguments2.PushElement(this); // pickup bool bContinue2 = Element.CallEvent("onPlayerPickupHit", Arguments2); if (bContinue1 && bContinue2) @@ -540,7 +544,7 @@ void CPickup::Callback_OnLeave(CColShape& Shape, CElement& Element) CallEvent("onPickupLeave", Arguments); CLuaArguments Arguments2; - Arguments2.PushElement(this); // pickup + Arguments2.PushElement(this); // pickup Element.CallEvent("onPlayerPickupLeave", Arguments2); } } diff --git a/Server/mods/deathmatch/logic/CPickupManager.cpp b/Server/mods/deathmatch/logic/CPickupManager.cpp index 827cf40f767..2c5ea86daea 100644 --- a/Server/mods/deathmatch/logic/CPickupManager.cpp +++ b/Server/mods/deathmatch/logic/CPickupManager.cpp @@ -14,11 +14,11 @@ #include "Utils.h" static SFixedArray g_usWeaponModels = {{ - 0, 331, 333, 334, 335, 336, 337, 338, 339, 341, // 9 - 321, 322, 323, 0, 325, 326, 342, 343, 344, 0, // 19 - 0, 0, 346, 347, 348, 349, 350, 351, 352, 353, // 29 - 355, 356, 372, 357, 358, 359, 360, 361, 362, 363, // 39 - 364, 365, 366, 367, 368, 369, 371 // 46 + 0, 331, 333, 334, 335, 336, 337, 338, 339, 341, // 9 + 321, 322, 323, 324, 325, 326, 342, 343, 344, 0, // 19 + 0, 0, 346, 347, 348, 349, 350, 351, 352, 353, // 29 + 355, 356, 372, 357, 358, 359, 360, 361, 362, 363, // 39 + 364, 365, 366, 367, 368, 369, 371 // 46 }}; CPickupManager::CPickupManager(CColManager* pColManager) @@ -65,7 +65,7 @@ bool CPickupManager::Exists(CPickup* pPickup) bool CPickupManager::IsValidWeaponID(unsigned int uiWeaponID) { - return (uiWeaponID > 0 && uiWeaponID != 13 && uiWeaponID != 19 && uiWeaponID != 20 && uiWeaponID != 21 && uiWeaponID <= 46); + return (uiWeaponID > 0 && uiWeaponID != 19 && uiWeaponID != 20 && uiWeaponID != 21 && uiWeaponID <= 46); } unsigned short CPickupManager::GetWeaponModel(unsigned int uiWeaponID) diff --git a/Server/mods/deathmatch/logic/CPlayer.cpp b/Server/mods/deathmatch/logic/CPlayer.cpp index e772b87b2de..35641fe7c9b 100644 --- a/Server/mods/deathmatch/logic/CPlayer.cpp +++ b/Server/mods/deathmatch/logic/CPlayer.cpp @@ -97,7 +97,7 @@ CPlayer::CPlayer(CPlayerManager* pPlayerManager, class CScriptDebugging* pScript m_ucNametagB = 0xFF; m_bNametagShowing = true; - m_ucBlurLevel = 36; // Default + m_ucBlurLevel = 36; // Default // Sync stuff m_bSyncingVelocity = false; @@ -217,16 +217,16 @@ bool CPlayer::ShouldIgnoreMinClientVersionChecks() return false; } -bool CPlayer::SubscribeElementData(CElement* pElement, const std::string& strName) +bool CPlayer::SubscribeElementData(CElement* pElement, CStringName name) { - OutputDebugLine(SString("[Data] SubscribeElementData %s [%s]", GetNick(), strName.c_str())); - return m_DataSubscriptions.emplace(std::make_pair(pElement, strName)).second; + OutputDebugLine(SString("[Data] SubscribeElementData %s [%s]", GetNick(), name.ToCString())); + return m_DataSubscriptions.emplace(std::make_pair(pElement, name)).second; } -bool CPlayer::UnsubscribeElementData(CElement* pElement, const std::string& strName) +bool CPlayer::UnsubscribeElementData(CElement* pElement, CStringName name) { - OutputDebugLine(SString("[Data] UnsubscribeElementData %s [%s]", GetNick(), strName.c_str())); - return m_DataSubscriptions.erase(std::make_pair(pElement, strName)) > 0; + OutputDebugLine(SString("[Data] UnsubscribeElementData %s [%s]", GetNick(), name.ToCString())); + return m_DataSubscriptions.erase(std::make_pair(pElement, name)) > 0; } bool CPlayer::UnsubscribeElementData(CElement* pElement) @@ -237,7 +237,7 @@ bool CPlayer::UnsubscribeElementData(CElement* pElement) { if (it->first == pElement) { - OutputDebugLine(SString("[Data] UnsubscribeElementData %s [%s]", GetNick(), it->second.c_str())); + OutputDebugLine(SString("[Data] UnsubscribeElementData %s [%s]", GetNick(), it->second.ToCString())); it = m_DataSubscriptions.erase(it); erased = true; } @@ -248,9 +248,9 @@ bool CPlayer::UnsubscribeElementData(CElement* pElement) return erased; } -bool CPlayer::IsSubscribed(CElement* pElement, const std::string& strName) const +bool CPlayer::IsSubscribed(CElement* pElement, CStringName name) const { - return m_DataSubscriptions.find(std::make_pair(pElement, strName)) != m_DataSubscriptions.end(); + return m_DataSubscriptions.find(std::make_pair(pElement, name)) != m_DataSubscriptions.end(); } const char* CPlayer::GetSourceIP() @@ -542,7 +542,7 @@ void CPlayer::Reset() // functions clientside and serverside possibly returning different results. memset(&m_fStats[0], 0, sizeof(m_fStats)); m_pPlayerStatsPacket->Clear(); - SetPlayerStat(24, 569.0f); // default max_health + SetPlayerStat(24, 569.0f); // default max_health m_pClothes->DefaultClothes(); m_bHasJetPack = false; @@ -556,7 +556,7 @@ void CPlayer::Reset() m_bCursorShowing = false; // Added - m_ucFightingStyle = 15; // STYLE_GRAB_KICK + m_ucFightingStyle = 15; // STYLE_GRAB_KICK SetNametagText(NULL); m_ucAlpha = 255; @@ -633,7 +633,7 @@ bool CPlayer::IsTimeForPuresyncFar() { int iSlowSyncRate = g_pBandwidthSettings->ZoneUpdateIntervals[ZONE3]; m_llNextFarPuresyncTime = llTime + iSlowSyncRate; - m_llNextFarPuresyncTime += rand() % (1 + iSlowSyncRate / 10); // Extra bit to help distribute the load + m_llNextFarPuresyncTime += rand() % (1 + iSlowSyncRate / 10); // Extra bit to help distribute the load // No far sync if light sync is enabled if (g_pBandwidthSettings->bLightSyncEnabled) @@ -646,7 +646,7 @@ bool CPlayer::IsTimeForPuresyncFar() g_pStats->lightsync.llSyncBytesSkipped += iNumPackets * GetApproxPuresyncPacketSize(); g_pStats->lightsync.llSyncPacketsSkipped += iNumSkipped; g_pStats->lightsync.llSyncBytesSkipped += iNumSkipped * GetApproxPuresyncPacketSize(); - return false; // No far sync if light sync is enabled + return false; // No far sync if light sync is enabled } // Add stats @@ -740,11 +740,11 @@ void CPlayer::MaybeUpdateOthersNearList() else // or player has moved too far if ((m_vecUpdateNearLastPosition - GetPosition()).LengthSquared() > MOVEMENT_UPDATE_THRESH * MOVEMENT_UPDATE_THRESH) - { - CLOCK("RelayPlayerPuresync", "UpdateNearList_Movement"); - UpdateOthersNearList(); - UNCLOCK("RelayPlayerPuresync", "UpdateNearList_Movement"); - } + { + CLOCK("RelayPlayerPuresync", "UpdateNearList_Movement"); + UpdateOthersNearList(); + UNCLOCK("RelayPlayerPuresync", "UpdateNearList_Movement"); + } } // Put this player in other players nearlist if this player can observe them in some way @@ -1091,7 +1091,7 @@ int CPlayer::GetPuresyncZone(CPlayer* pOther) vecDirToHere.Normalize(); float fDot = vecOtherCamFwd.DotProduct(&vecDirToHere); // 1=0 deg 0=90 deg -1=180 deg - if (fDot > 0.643) // 100 deg fov [cos ( DEG2RAD( 100 ) * 0.5f )] + if (fDot > 0.643) // 100 deg fov [cos ( DEG2RAD( 100 ) * 0.5f )] iZone = g_pBandwidthSettings->iMaxZoneIfOtherCanSee; } @@ -1121,7 +1121,10 @@ void CPlayer::SetPlayerStat(unsigned short usStat, float fValue) // Calculate weapon range using efficient stuffs float CPlayer::GetWeaponRangeFromSlot(uint uiSlot) { - eWeaponType eWeapon = static_cast(GetWeaponType(uiSlot)); + if (uiSlot > 0xFF) + return 0.0f; + + eWeaponType eWeapon = static_cast(GetWeaponType(static_cast(uiSlot))); float fSkill = GetPlayerStat(CWeaponStatManager::GetSkillStatIndex(eWeapon)); if (fSkill != m_fWeaponRangeLastSkill || eWeapon != m_eWeaponRangeLastWeapon || diff --git a/Server/mods/deathmatch/logic/CPlayer.h b/Server/mods/deathmatch/logic/CPlayer.h index dc6d5cce70c..b332f40eb12 100644 --- a/Server/mods/deathmatch/logic/CPlayer.h +++ b/Server/mods/deathmatch/logic/CPlayer.h @@ -23,6 +23,7 @@ class CPlayer; #include "CObject.h" #include "packets/CPacket.h" #include "packets/CPlayerStatsPacket.h" +#include "CStringName.h" class CKeyBinds; class CPlayerCamera; enum class eVehicleAimDirection : unsigned char; @@ -34,7 +35,7 @@ enum eVoiceState VOICESTATE_TRANSMITTING_IGNORED, }; -#define MOVEMENT_UPDATE_THRESH (5) +#define MOVEMENT_UPDATE_THRESH (5) #define DISTANCE_FOR_NEAR_VIEWER (310) struct SViewerInfo @@ -104,10 +105,10 @@ class CPlayer final : public CPed, public CClient bool IsJoined() { return m_bIsJoined; } void SetJoined() { m_bIsJoined = true; } - bool SubscribeElementData(CElement* pElement, const std::string& strName); - bool UnsubscribeElementData(CElement* pElement, const std::string& strName); + bool SubscribeElementData(CElement* pElement, CStringName name); + bool UnsubscribeElementData(CElement* pElement, CStringName name); bool UnsubscribeElementData(CElement* pElement); - bool IsSubscribed(CElement* pElement, const std::string& strName) const; + bool IsSubscribed(CElement* pElement, CStringName name) const; float GetCameraRotation() { return m_fCameraRotation; }; void SetCameraRotation(float fRotation) { m_fCameraRotation = fRotation; }; @@ -214,12 +215,6 @@ class CPlayer final : public CPed, public CClient const std::string& GetSerial(uint uiIndex = 0) { return m_strSerials[uiIndex % NUMELMS(m_strSerials)]; } void SetSerial(const std::string& strSerial, uint uiIndex) { m_strSerials[uiIndex % NUMELMS(m_strSerials)] = strSerial; } - const std::string& GetSerialUser() { return m_strSerialUser; }; - void SetSerialUser(const std::string& strUser) { m_strSerialUser = strUser; }; - - const std::string& GetCommunityID() { return m_strCommunityID; }; - void SetCommunityID(const std::string& strID) { m_strCommunityID = strID; }; - unsigned char GetBlurLevel() { return m_ucBlurLevel; } void SetBlurLevel(unsigned char ucBlurLevel) { m_ucBlurLevel = ucBlurLevel; } @@ -420,8 +415,6 @@ class CPlayer final : public CPed, public CClient bool m_bNametagShowing; std::string m_strSerials[2]; - std::string m_strSerialUser; - std::string m_strCommunityID; unsigned char m_ucBlurLevel; @@ -440,7 +433,7 @@ class CPlayer final : public CPed, public CClient std::map m_AnnounceValues; - std::set> m_DataSubscriptions; + std::set> m_DataSubscriptions; uint m_uiWeaponIncorrectCount; diff --git a/Server/mods/deathmatch/logic/CPlayerCamera.cpp b/Server/mods/deathmatch/logic/CPlayerCamera.cpp index 6936449b216..e48c0fcdfd5 100644 --- a/Server/mods/deathmatch/logic/CPlayerCamera.cpp +++ b/Server/mods/deathmatch/logic/CPlayerCamera.cpp @@ -14,6 +14,7 @@ #include "CCameraSpatialDatabase.h" #include "CPlayer.h" #include "Utils.h" +#include CPlayerCamera::CPlayerCamera(CPlayer* pPlayer) { @@ -52,7 +53,7 @@ void CPlayerCamera::SetMode(eCameraMode Mode) const CVector& CPlayerCamera::GetPosition() const { - if (m_Mode == CAMERAMODE_PLAYER && m_pTarget) + if (m_Mode == CAMERAMODE_PLAYER && m_pTarget && !m_pTarget->IsBeingDeleted()) { return m_pTarget->GetPosition(); } @@ -65,19 +66,26 @@ void CPlayerCamera::GetPosition(CVector& vecPosition) const { vecPosition = m_vecPosition; } - else if (m_pTarget) + else if (m_pTarget && !m_pTarget->IsBeingDeleted()) { vecPosition = m_pTarget->GetPosition(); } + else + { + vecPosition = CVector(); + } } void CPlayerCamera::SetPosition(const CVector& vecPosition) { - if (m_Mode == CAMERAMODE_FIXED) - { - m_vecPosition = vecPosition; - GetCameraSpatialDatabase()->UpdateItem(this); - } + if (m_Mode != CAMERAMODE_FIXED) + return; + + if (!std::isfinite(vecPosition.fX) || !std::isfinite(vecPosition.fY) || !std::isfinite(vecPosition.fZ)) + return; + + m_vecPosition = vecPosition; + GetCameraSpatialDatabase()->UpdateItem(this); } void CPlayerCamera::GetLookAt(CVector& vecLookAt) const @@ -94,26 +102,37 @@ void CPlayerCamera::GetLookAt(CVector& vecLookAt) const void CPlayerCamera::SetLookAt(const CVector& vecLookAt) { - if (m_Mode == CAMERAMODE_FIXED) - { - m_vecLookAt = vecLookAt; - } + if (m_Mode != CAMERAMODE_FIXED) + return; + + if (!std::isfinite(vecLookAt.fX) || !std::isfinite(vecLookAt.fY) || !std::isfinite(vecLookAt.fZ)) + return; + + m_vecLookAt = vecLookAt; } void CPlayerCamera::SetMatrix(const CVector& vecPosition, const CVector& vecLookAt) { - if (m_Mode == CAMERAMODE_FIXED) - { - m_vecPosition = vecPosition; - m_vecLookAt = vecLookAt; - GetCameraSpatialDatabase()->UpdateItem(this); - } + if (m_Mode != CAMERAMODE_FIXED) + return; + + if (!std::isfinite(vecPosition.fX) || !std::isfinite(vecPosition.fY) || !std::isfinite(vecPosition.fZ)) + return; + + if (!std::isfinite(vecLookAt.fX) || !std::isfinite(vecLookAt.fY) || !std::isfinite(vecLookAt.fZ)) + return; + + m_vecPosition = vecPosition; + m_vecLookAt = vecLookAt; + GetCameraSpatialDatabase()->UpdateItem(this); } void CPlayerCamera::SetTarget(CElement* pElement) { - if (!pElement) + if (!pElement || pElement->IsBeingDeleted()) + { pElement = m_pPlayer; + } if (m_pTarget != pElement) { @@ -127,6 +146,9 @@ void CPlayerCamera::SetTarget(CElement* pElement) void CPlayerCamera::SetRotation(CVector& vecRotation) { + if (!std::isfinite(vecRotation.fX) || !std::isfinite(vecRotation.fY) || !std::isfinite(vecRotation.fZ)) + return; + // Rotate a 1000,0,0 vector with the given rotation vector CVector vecRotationCopy = vecRotation; vecRotationCopy.fX = 0.0f; diff --git a/Server/mods/deathmatch/logic/CPlayerCamera.h b/Server/mods/deathmatch/logic/CPlayerCamera.h index a8e4b7adbef..f6345d76f5c 100644 --- a/Server/mods/deathmatch/logic/CPlayerCamera.h +++ b/Server/mods/deathmatch/logic/CPlayerCamera.h @@ -12,6 +12,8 @@ #pragma once #include +#include +#include "CameraScriptShared.h" class CPlayer; class CElement; @@ -45,9 +47,9 @@ class CPlayerCamera void SetTarget(CElement* pElement); float GetRoll() const { return m_fRoll; } - void SetRoll(float fRoll) { m_fRoll = fRoll; } + void SetRoll(float fRoll) { m_fRoll = CameraScriptShared::NormalizeRoll(fRoll); } float GetFOV() const { return m_fFOV; } - void SetFOV(float fFOV) { m_fFOV = fFOV; } + void SetFOV(float fFOV) { m_fFOV = CameraScriptShared::SanitizeFOV(fFOV); } void SetRotation(CVector& vecRotation); diff --git a/Server/mods/deathmatch/logic/CPlayerClothes.h b/Server/mods/deathmatch/logic/CPlayerClothes.h index d3efa24c659..063dfdf9c95 100644 --- a/Server/mods/deathmatch/logic/CPlayerClothes.h +++ b/Server/mods/deathmatch/logic/CPlayerClothes.h @@ -15,25 +15,25 @@ class CPlayerClothes; #include "CCommon.h" -#define PLAYER_CLOTHING_SLOTS 18 -#define TORSO_CLOTHING_MAX 68 -#define HAIR_CLOTHING_MAX 33 -#define LEGS_CLOTHING_MAX 45 -#define SHOES_CLOTHING_MAX 38 -#define LEFT_UPPER_ARM_CLOTHING_MAX 3 -#define LEFT_LOWER_ARM_CLOTHING_MAX 4 +#define PLAYER_CLOTHING_SLOTS 18 +#define TORSO_CLOTHING_MAX 68 +#define HAIR_CLOTHING_MAX 33 +#define LEGS_CLOTHING_MAX 45 +#define SHOES_CLOTHING_MAX 38 +#define LEFT_UPPER_ARM_CLOTHING_MAX 3 +#define LEFT_LOWER_ARM_CLOTHING_MAX 4 #define RIGHT_UPPER_ARM_CLOTHING_MAX 4 #define RIGHT_LOWER_ARM_CLOTHING_MAX 4 -#define BACK_TOP_CLOTHING_MAX 7 -#define LEFT_CHEST_CLOTHING_MAX 6 -#define RIGHT_CHEST_CLOTHING_MAX 7 -#define STOMACH_CLOTHING_MAX 7 -#define LOWER_BACK_CLOTHING_MAX 6 -#define EXTRA1_CLOTHING_MAX 12 -#define EXTRA2_CLOTHING_MAX 12 -#define EXTRA3_CLOTHING_MAX 17 -#define EXTRA4_CLOTHING_MAX 57 -#define SUIT_CLOTHING_MAX 9 +#define BACK_TOP_CLOTHING_MAX 7 +#define LEFT_CHEST_CLOTHING_MAX 6 +#define RIGHT_CHEST_CLOTHING_MAX 7 +#define STOMACH_CLOTHING_MAX 7 +#define LOWER_BACK_CLOTHING_MAX 6 +#define EXTRA1_CLOTHING_MAX 12 +#define EXTRA2_CLOTHING_MAX 12 +#define EXTRA3_CLOTHING_MAX 17 +#define EXTRA4_CLOTHING_MAX 57 +#define SUIT_CLOTHING_MAX 9 class CPed; diff --git a/Server/mods/deathmatch/logic/CPlayerManager.cpp b/Server/mods/deathmatch/logic/CPlayerManager.cpp index 7075a1dba88..4d3d9be10fe 100644 --- a/Server/mods/deathmatch/logic/CPlayerManager.cpp +++ b/Server/mods/deathmatch/logic/CPlayerManager.cpp @@ -338,11 +338,11 @@ void CPlayerManager::Broadcast(const CPacket& Packet, const std::multimap 312) - return false; // TODO: On client side maybe check if a model was allocated with engineRequestModel and it is a ped + return false; // TODO: On client side maybe check if a model was allocated with engineRequestModel and it is a ped switch (model) { - case 74: // Missing skin + case 74: // Missing skin case 149: case 208: return false; @@ -351,7 +351,7 @@ bool CPlayerManager::IsValidPlayerModel(unsigned short model) } } -void CPlayerManager::ClearElementData(CElement* pElement, const std::string& name) +void CPlayerManager::ClearElementData(CElement* pElement, CStringName name) { list::const_iterator iter = m_Players.begin(); for (; iter != m_Players.end(); iter++) diff --git a/Server/mods/deathmatch/logic/CPlayerManager.h b/Server/mods/deathmatch/logic/CPlayerManager.h index b1097c03354..bc383a021fc 100644 --- a/Server/mods/deathmatch/logic/CPlayerManager.h +++ b/Server/mods/deathmatch/logic/CPlayerManager.h @@ -56,7 +56,7 @@ class CPlayerManager static bool IsValidPlayerModel(unsigned short model); - void ClearElementData(CElement* pElement, const std::string& name); + void ClearElementData(CElement* pElement, CStringName name); void ClearElementData(CElement* pElement); void ResetAll(); diff --git a/Server/mods/deathmatch/logic/CPlayerTextManager.cpp b/Server/mods/deathmatch/logic/CPlayerTextManager.cpp index 2a50f14c044..1853dffed52 100644 --- a/Server/mods/deathmatch/logic/CPlayerTextManager.cpp +++ b/Server/mods/deathmatch/logic/CPlayerTextManager.cpp @@ -67,8 +67,8 @@ void CPlayerTextManager::Update(CTextItem* pTextItem, bool bRemovedFromDisplay) eTextPriority updatePriority = pTextItem->GetPriority(); CTextItem* pClonedItem = new CTextItem(*pTextItem); if (bRemovedFromDisplay) - pClonedItem->m_bDeletable = true; // we pretend that the text item has actually been deleted - // as far as the player is concerned, it has been + pClonedItem->m_bDeletable = true; // we pretend that the text item has actually been deleted + // as far as the player is concerned, it has been // Push it on the correct queue switch (updatePriority) diff --git a/Server/mods/deathmatch/logic/CRPCFunctions.cpp b/Server/mods/deathmatch/logic/CRPCFunctions.cpp index 5eacb499ac8..2965dd3871e 100644 --- a/Server/mods/deathmatch/logic/CRPCFunctions.cpp +++ b/Server/mods/deathmatch/logic/CRPCFunctions.cpp @@ -156,34 +156,34 @@ void CRPCFunctions::PlayerWeapon(NetBitStreamInterface& bitStream) unsigned char ucPrevSlot = m_pSourcePlayer->GetWeaponSlot(); // We don't get the puresync packet containing totalAmmo = 0 for slot 8 (THROWN), slot 7 (HEAVY) and slot 9 (SPECIAL) - if ((bitStream.Version() >= 0x44 && ucPrevSlot == WEAPONSLOT_TYPE_THROWN) || bitStream.Version() >= 0x4D) + if (bitStream.ReadBit() && (ucPrevSlot == WEAPONSLOT_TYPE_THROWN || ucPrevSlot == WEAPONSLOT_TYPE_HEAVY || ucPrevSlot == WEAPONSLOT_TYPE_SPECIAL)) { - if (bitStream.ReadBit() && (ucPrevSlot == WEAPONSLOT_TYPE_THROWN || - (bitStream.Version() >= 0x5A && (ucPrevSlot == WEAPONSLOT_TYPE_HEAVY || ucPrevSlot == WEAPONSLOT_TYPE_SPECIAL)))) - { - CWeapon* pPrevWeapon = m_pSourcePlayer->GetWeapon(ucPrevSlot); - pPrevWeapon->usAmmo = 0; - pPrevWeapon->usAmmoInClip = 0; - } + CWeapon* pPrevWeapon = m_pSourcePlayer->GetWeapon(ucPrevSlot); + pPrevWeapon->usAmmo = 0; + pPrevWeapon->usAmmoInClip = 0; } SWeaponSlotSync slot; bitStream.Read(&slot); - unsigned int uiSlot = slot.data.uiSlot; - if (uiSlot != ucPrevSlot) + if (slot.data.uiSlot > 0xFF) + return; + + const unsigned char ucSlot = static_cast(slot.data.uiSlot); + + if (ucSlot != ucPrevSlot) { CLuaArguments Arguments; Arguments.PushNumber(m_pSourcePlayer->GetWeaponType(ucPrevSlot)); - Arguments.PushNumber(m_pSourcePlayer->GetWeaponType(uiSlot)); + Arguments.PushNumber(m_pSourcePlayer->GetWeaponType(ucSlot)); m_pSourcePlayer->CallEvent("onPlayerWeaponSwitch", Arguments); } - m_pSourcePlayer->SetWeaponSlot(uiSlot); - CWeapon* pWeapon = m_pSourcePlayer->GetWeapon(uiSlot); + m_pSourcePlayer->SetWeaponSlot(ucSlot); + CWeapon* pWeapon = m_pSourcePlayer->GetWeapon(ucSlot); - if (CWeaponNames::DoesSlotHaveAmmo(uiSlot)) + if (CWeaponNames::DoesSlotHaveAmmo(ucSlot)) { if (pWeapon) { @@ -199,7 +199,7 @@ void CRPCFunctions::PlayerWeapon(NetBitStreamInterface& bitStream) pWeapon->usAmmo = 1; pWeapon->usAmmoInClip = 1; // Keep the server synced with the client (GTASA gives the client a detonator when they shoot so if they changed to slot 12 they obviously have one) - if (uiSlot == 12) + if (ucSlot == 12) // Give them the detonator CStaticFunctionDefinitions::GiveWeapon(m_pSourcePlayer, 40, 1, true); } @@ -355,10 +355,10 @@ void CRPCFunctions::RequestStealthKill(NetBitStreamInterface& bitStream) // You shouldn't be able to get here without cheating to get a knife. if (!g_pGame->GetConfig()->IsDisableAC("2")) { - // Kick disabled as sometimes causing false positives due weapon slot sync problems - #if 0 +// Kick disabled as sometimes causing false positives due weapon slot sync problems +#if 0 CStaticFunctionDefinitions::KickPlayer ( m_pSourcePlayer, NULL, "AC #2: You were kicked from the game" ); - #endif +#endif } } } diff --git a/Server/mods/deathmatch/logic/CRPCFunctions.h b/Server/mods/deathmatch/logic/CRPCFunctions.h index bf616d1f726..20736c5adb6 100644 --- a/Server/mods/deathmatch/logic/CRPCFunctions.h +++ b/Server/mods/deathmatch/logic/CRPCFunctions.h @@ -19,7 +19,7 @@ class CPlayer; class CGame; -#define DECLARE_RPC(a) static void a ( NetBitStreamInterface& bitStream ); +#define DECLARE_RPC(a) static void a(NetBitStreamInterface& bitStream); class CRPCFunctions { diff --git a/Server/mods/deathmatch/logic/CRegisteredCommands.cpp b/Server/mods/deathmatch/logic/CRegisteredCommands.cpp index 50706204feb..cf9c0ad6942 100644 --- a/Server/mods/deathmatch/logic/CRegisteredCommands.cpp +++ b/Server/mods/deathmatch/logic/CRegisteredCommands.cpp @@ -18,6 +18,9 @@ #include "CClient.h" #include "CConsoleClient.h" #include "CPlayer.h" +#include "CGame.h" +#include "CScriptDebugging.h" +#include "CMainConfig.h" CRegisteredCommands::CRegisteredCommands(CAccessControlListManager* pACLManager) { @@ -35,6 +38,27 @@ bool CRegisteredCommands::AddCommand(CLuaMain* pLuaMain, const char* szKey, cons assert(pLuaMain); assert(szKey); + if (CommandExists(szKey, nullptr)) + { + auto policy = static_cast(g_pGame->GetConfig()->GetAllowMultiCommandHandlers()); + + switch (policy) + { + case MultiCommandHandlerPolicy::BLOCK: + g_pGame->GetScriptDebugging()->LogError( + pLuaMain->GetVM(), "addCommandHandler: Duplicate command registration blocked for '%s' (multiple handlers disabled)", szKey); + return false; + + case MultiCommandHandlerPolicy::WARN: + g_pGame->GetScriptDebugging()->LogWarning(pLuaMain->GetVM(), "Attempt to register duplicate command '%s'", szKey); + break; + + case MultiCommandHandlerPolicy::ALLOW: + default: + break; + } + } + // Check if we already have this key and handler SCommand* pCommand = GetCommand(szKey, pLuaMain); @@ -139,7 +163,7 @@ bool CRegisteredCommands::CommandExists(const char* szKey, CLuaMain* pLuaMain) { assert(szKey); - return GetCommand(szKey, pLuaMain) != NULL; + return GetCommand(szKey, pLuaMain) != nullptr; } bool CRegisteredCommands::ProcessCommand(const char* szKey, const char* szArguments, CClient* pClient) @@ -166,7 +190,7 @@ bool CRegisteredCommands::ProcessCommand(const char* szKey, const char* szArgume if (m_pACLManager->CanObjectUseRight( pClient->GetAccount()->GetName().c_str(), CAccessControlListGroupObject::OBJECT_TYPE_USER, (*iter)->strKey, CAccessControlListRight::RIGHT_TYPE_COMMAND, - !(*iter)->bRestricted)) // If this command is restricted, the default access should be false unless granted specially + !(*iter)->bRestricted)) // If this command is restricted, the default access should be false unless granted specially { // Call it CallCommandHandler((*iter)->pLuaMain, (*iter)->iLuaFunction, (*iter)->strKey, szArguments, pClient); @@ -203,7 +227,7 @@ CRegisteredCommands::SCommand* CRegisteredCommands::GetCommand(const char* szKey } // Doesn't exist - return NULL; + return nullptr; } void CRegisteredCommands::CallCommandHandler(CLuaMain* pLuaMain, const CLuaFunctionRef& iLuaFunction, const char* szKey, const char* szArguments, @@ -253,7 +277,7 @@ void CRegisteredCommands::CallCommandHandler(CLuaMain* pLuaMain, const CLuaFunct while (arg) { Arguments.PushString(arg); - arg = strtok(NULL, " "); + arg = strtok(nullptr, " "); } delete[] szTempArguments; diff --git a/Server/mods/deathmatch/logic/CRegisteredCommands.h b/Server/mods/deathmatch/logic/CRegisteredCommands.h index a79f067f6cd..5bc7e963dc2 100644 --- a/Server/mods/deathmatch/logic/CRegisteredCommands.h +++ b/Server/mods/deathmatch/logic/CRegisteredCommands.h @@ -12,12 +12,20 @@ #pragma once #include "lua/CLuaFunctionRef.h" +#include #include #include -#define MAX_REGISTERED_COMMAND_LENGTH 64 +#define MAX_REGISTERED_COMMAND_LENGTH 64 #define MAX_REGISTERED_COMMANDHANDLER_LENGTH 64 +enum class MultiCommandHandlerPolicy : std::uint8_t +{ + BLOCK = 0, + WARN = 1, + ALLOW = 2 +}; + class CRegisteredCommands { struct SCommand diff --git a/Server/mods/deathmatch/logic/CRegistry.h b/Server/mods/deathmatch/logic/CRegistry.h index dcde1f528a5..4ccf50bb162 100644 --- a/Server/mods/deathmatch/logic/CRegistry.h +++ b/Server/mods/deathmatch/logic/CRegistry.h @@ -62,7 +62,7 @@ class CRegistry SString m_strFileName; private: - bool Query(const char* szQuery, CRegistryResult* pResult); // Not defined to catch incorrect usage + bool Query(const char* szQuery, CRegistryResult* pResult); // Not defined to catch incorrect usage }; struct CRegistryResultCell @@ -126,9 +126,9 @@ struct CRegistryResultCell return 0; } - int nType; // Type identifier, SQLITE_* - int nLength; // Length in bytes if nType == SQLITE_BLOB or SQLITE_TEXT - // (includes zero terminator if TEXT) + int nType; // Type identifier, SQLITE_* + int nLength; // Length in bytes if nType == SQLITE_BLOB or SQLITE_TEXT + // (includes zero terminator if TEXT) long long int nVal; float fVal; unsigned char* pVal; diff --git a/Server/mods/deathmatch/logic/CResource.AclRequest.cpp b/Server/mods/deathmatch/logic/CResource.AclRequest.cpp index d8a6a5a5aab..4bafafa7543 100644 --- a/Server/mods/deathmatch/logic/CResource.AclRequest.cpp +++ b/Server/mods/deathmatch/logic/CResource.AclRequest.cpp @@ -123,10 +123,6 @@ bool CResource::HasAutoPermissions(CXMLNode* pNodeAclRequest) /////////////////////////////////////////////////////////////// void CResource::RefreshAutoPermissions(CXMLNode* pNodeAclRequest) { - // Check if permissions already active - if (HasAutoPermissions(pNodeAclRequest)) - return; - // Ensure group and acl exist CAccessControlListGroup* pAutoGroup = g_pGame->GetACLManager()->AddGroup(GetAutoGroupName()); pAutoGroup->AddACL(GetAutoAcl()); diff --git a/Server/mods/deathmatch/logic/CResource.cpp b/Server/mods/deathmatch/logic/CResource.cpp index 276610e98d3..bf1982acb28 100644 --- a/Server/mods/deathmatch/logic/CResource.cpp +++ b/Server/mods/deathmatch/logic/CResource.cpp @@ -107,7 +107,7 @@ bool CResource::Load() m_uiVersionMajor = 0; m_uiVersionMinor = 0; m_uiVersionRevision = 0; - m_uiVersionState = 2; // release + m_uiVersionState = 2; // release m_bClientConfigs = true; m_bClientScripts = true; @@ -362,6 +362,23 @@ void CResource::Reload() Load(); } +bool CResource::CanPlayerTriggerResourceStart(CPlayer* player, unsigned int playerStartCounter) +{ + if (playerStartCounter != m_startCounter || m_eState != EResourceState::Running) + return false; + + if (m_isRunningForPlayer.contains(player)) + return false; + + m_isRunningForPlayer.insert(player); + return true; +} + +void CResource::OnPlayerQuit(CPlayer& Player) +{ + m_isRunningForPlayer.erase(&Player); +} + CResource::~CResource() { CIdArray::PushUniqueId(this, EIdClass::RESOURCE, m_uiScriptID); @@ -504,68 +521,70 @@ void CResource::SetInfoValue(const char* szKey, const char* szValue, bool bSave) std::future CResource::GenerateChecksumForFile(CResourceFile* pResourceFile) { - return SharedUtil::async([pResourceFile, this] { - SString strPath; - - if (!GetFilePath(pResourceFile->GetName(), strPath)) - return SString(); - - auto checksumOrError = CChecksum::GenerateChecksumFromFile(strPath); - if (std::holds_alternative(checksumOrError)) + return SharedUtil::async( + [pResourceFile, this] { - return SString(std::get(checksumOrError)); - } + SString strPath; - pResourceFile->SetLastChecksum(std::get(checksumOrError)); - pResourceFile->SetLastFileSizeHint(FileSize(strPath)); + if (!GetFilePath(pResourceFile->GetName(), strPath)) + return SString(); - // Check if file is blocked - char szHashResult[33]; - CMD5Hasher::ConvertToHex(pResourceFile->GetLastChecksum().md5, szHashResult); - SString strBlockReason = m_pResourceManager->GetBlockedFileReason(szHashResult); + auto checksumOrError = CChecksum::GenerateChecksumFromFile(strPath); + if (std::holds_alternative(checksumOrError)) + { + return SString(std::get(checksumOrError)); + } - if (!strBlockReason.empty()) - { - return SString("file '%s' is blocked (%s)", pResourceFile->GetName(), *strBlockReason); - } + pResourceFile->SetLastChecksum(std::get(checksumOrError)); + pResourceFile->SetLastFileSizeHint(static_cast(FileSize(strPath))); - // Copy file to http holding directory - switch (pResourceFile->GetType()) - { - case CResourceFile::RESOURCE_FILE_TYPE_CLIENT_SCRIPT: - case CResourceFile::RESOURCE_FILE_TYPE_CLIENT_CONFIG: - case CResourceFile::RESOURCE_FILE_TYPE_CLIENT_FILE: + // Check if file is blocked + char szHashResult[33]; + CMD5Hasher::ConvertToHex(pResourceFile->GetLastChecksum().md5, szHashResult); + SString strBlockReason = m_pResourceManager->GetBlockedFileReason(szHashResult); + + if (!strBlockReason.empty()) { - SString strCachedFilePath = pResourceFile->GetCachedPathFilename(); + return SString("file '%s' is blocked (%s)", pResourceFile->GetName(), *strBlockReason); + } - if (!g_pRealNetServer->ValidateHttpCacheFileName(strCachedFilePath)) + // Copy file to http holding directory + switch (pResourceFile->GetType()) + { + case CResourceFile::RESOURCE_FILE_TYPE_CLIENT_SCRIPT: + case CResourceFile::RESOURCE_FILE_TYPE_CLIENT_CONFIG: + case CResourceFile::RESOURCE_FILE_TYPE_CLIENT_FILE: { - FileDelete(strCachedFilePath); - return SString("ERROR: Resource '%s' client filename '%s' not allowed\n", GetName().c_str(), *ExtractFilename(strCachedFilePath)); - } + SString strCachedFilePath = pResourceFile->GetCachedPathFilename(); - CChecksum cachedChecksum = CChecksum::GenerateChecksumFromFileUnsafe(strCachedFilePath); + if (!g_pRealNetServer->ValidateHttpCacheFileName(strCachedFilePath)) + { + FileDelete(strCachedFilePath); + return SString("ERROR: Resource '%s' client filename '%s' not allowed\n", GetName().c_str(), *ExtractFilename(strCachedFilePath)); + } - if (pResourceFile->GetLastChecksum() != cachedChecksum) - { - if (!FileCopy(strPath, strCachedFilePath)) + CChecksum cachedChecksum = CChecksum::GenerateChecksumFromFileUnsafe(strCachedFilePath); + + if (pResourceFile->GetLastChecksum() != cachedChecksum) { - return SString("Could not copy '%s' to '%s'\n", *strPath, *strCachedFilePath); + if (!FileCopy(strPath, strCachedFilePath)) + { + return SString("Could not copy '%s' to '%s'\n", *strPath, *strCachedFilePath); + } + + // If script is 'no client cache', make sure there is no trace of it in the output dir + if (pResourceFile->IsNoClientCache()) + FileDelete(pResourceFile->GetCachedPathFilename(true)); } - // If script is 'no client cache', make sure there is no trace of it in the output dir - if (pResourceFile->IsNoClientCache()) - FileDelete(pResourceFile->GetCachedPathFilename(true)); + break; } - - break; + default: + break; } - default: - break; - } - return SString(); - }); + return SString(); + }); } bool CResource::GenerateChecksums() @@ -582,11 +601,28 @@ bool CResource::GenerateChecksums() for (auto& task : checksumTasks) { - const auto& result = task.get(); - if (!result.empty()) + try { - m_strFailureReason = result; - CLogger::LogPrintf(result); + const auto& result = task.get(); + if (!result.empty()) + { + m_strFailureReason = result; + CLogger::LogPrintf(result); + bOk = false; + } + } + catch (const std::future_error& e) + { + // Became invalid (e.g., during shutdown) + m_strFailureReason = SString("Checksum task failed: %s", e.what()); + CLogger::LogPrintf(m_strFailureReason); + bOk = false; + } + catch (const std::exception& e) + { + // Task threw + m_strFailureReason = SString("Checksum error: %s", e.what()); + CLogger::LogPrintf(m_strFailureReason); bOk = false; } } @@ -603,7 +639,7 @@ bool CResource::GenerateChecksums() bool CResource::HasResourceChanged() { - std::string strPath; + std::string strPath; std::string_view strDirPath = m_strResourceDirectoryPath; if (IsResourceZip()) @@ -729,7 +765,7 @@ bool CResource::GetCompatibilityStatus(SString& strOutStatus) { strOutStatus = " section in the meta.xml is incorrect or missing (expected at least "; strOutStatus += SString("client %s because of '%s')", *m_strMinClientReqFromSource, *m_strMinClientReason); - m_strMinClientRequirement = m_strMinClientReqFromSource; // Apply higher version requirement + m_strMinClientRequirement = m_strMinClientReqFromSource; // Apply higher version requirement } else if (m_strMinServerReqFromSource > m_strMinServerFromMetaXml) { @@ -1017,6 +1053,7 @@ bool CResource::Start(std::list* pDependents, bool bManualStart, con return false; } + m_startCounter = std::max(m_startCounter + 1, 1); // We consider zero to be an invalid start counter. m_bStartedManually = bManualStart; // Remember the client files state @@ -1028,7 +1065,7 @@ bool CResource::Start(std::list* pDependents, bool bManualStart, con // Broadcast new resourceelement that is loaded and tell the players that a new resource was started g_pGame->GetMapManager()->BroadcastResourceElements(m_pResourceElement, m_pDefaultElementGroup); - g_pGame->GetPlayerManager()->BroadcastOnlyJoined(CResourceStartPacket(m_strResourceName.c_str(), this)); + g_pGame->GetPlayerManager()->BroadcastOnlyJoined(CResourceStartPacket(m_strResourceName, this, m_startCounter)); SendNoClientCacheScripts(); m_bClientSync = true; @@ -1053,19 +1090,19 @@ void CResource::OnResourceStateChange(const char* state) noexcept stateArgs.PushResource(this); switch (m_eState) { - case EResourceState::Loaded: // When resource is stopped + case EResourceState::Loaded: // When resource is stopped stateArgs.PushString("loaded"); break; - case EResourceState::Running: // When resource is running + case EResourceState::Running: // When resource is running stateArgs.PushString("running"); break; - case EResourceState::Starting: // When resource is starting + case EResourceState::Starting: // When resource is starting stateArgs.PushString("starting"); break; - case EResourceState::Stopping: // When resource is stopping + case EResourceState::Stopping: // When resource is stopping stateArgs.PushString("stopping"); break; - case EResourceState::None: // When resource is not loaded + case EResourceState::None: // When resource is not loaded default: stateArgs.PushString("unloaded"); break; @@ -1174,6 +1211,9 @@ bool CResource::Stop(bool bManualStop) // Broadcast the packet to joined players g_pGame->GetPlayerManager()->BroadcastOnlyJoined(removePacket); + // Clear the list of players where this resource is running + std::exchange(m_isRunningForPlayer, {}); + OnResourceStateChange("loaded"); m_eState = EResourceState::Loaded; return true; @@ -1220,7 +1260,7 @@ bool CResource::DestroyVM() return true; } -void CResource::DisplayInfo() // duplicated for HTML +void CResource::DisplayInfo() // duplicated for HTML { CLogger::LogPrintf("== Details for resource '%s' ==\n", m_strResourceName.c_str()); @@ -1276,8 +1316,8 @@ void CResource::DisplayInfo() // duplicated for HTML { if (pIncludedResources->IsBadVersion()) { - CLogger::LogPrintf(" %s .. BAD VERSION (not between %d and %d)\n", pIncludedResources->GetMinimumVersion(), - pIncludedResources->GetMaximumVersion()); + CLogger::LogPrintf(" %s .. BAD VERSION (not between %d and %d)\n", pIncludedResources->GetName().c_str(), + pIncludedResources->GetMinimumVersion(), pIncludedResources->GetMaximumVersion()); } else { @@ -1364,9 +1404,9 @@ bool CResource::GetFilePath(const char* szFilename, string& strPath) std::vector CResource::GetFilePaths(const char* szFilename) { - std::vector vecFiles; - const std::string& strDirectory = IsResourceZip() ? m_strResourceCachePath : m_strResourceDirectoryPath; - const std::string strFilePath = strDirectory + szFilename; + std::vector vecFiles; + const std::string& strDirectory = IsResourceZip() ? m_strResourceCachePath : m_strResourceDirectoryPath; + const std::string strFilePath = strDirectory + szFilename; for (const std::filesystem::path& path : glob::rglob(strFilePath)) { @@ -1499,7 +1539,8 @@ bool CResource::ReadIncludedHTML(CXMLNode* pRoot) // This one is supposed to be default, but there's already a default page if (bFoundDefault && bIsDefault) { - CLogger::LogPrintf("Only one html item can be default per resource, ignoring %s in %s\n", strFilename.c_str(), m_strResourceName.c_str()); + CLogger::LogPrintf("Only one html item can be default per resource, ignoring %s in %s\n", strFilename.c_str(), + m_strResourceName.c_str()); bIsDefault = false; } @@ -1508,7 +1549,8 @@ bool CResource::ReadIncludedHTML(CXMLNode* pRoot) bFoundDefault = true; // Create a new resource HTML file and add it to the list - auto pResourceFile = new CResourceHTMLItem(this, strFilename.c_str(), strFullFilename.c_str(), &Attributes, bIsDefault, bIsRaw, bIsRestricted, m_bOOPEnabledInMetaXml); + auto pResourceFile = new CResourceHTMLItem(this, strFilename.c_str(), strFullFilename.c_str(), &Attributes, bIsDefault, bIsRaw, + bIsRestricted, m_bOOPEnabledInMetaXml); m_ResourceFiles.push_back(pResourceFile); // This is the first HTML file? Remember it @@ -1732,8 +1774,7 @@ bool CResource::ReadIncludedExports(CXMLNode* pRoot) if (functionName[0] == '\0') { - CLogger::ErrorPrintf("WARNING: Empty 'function' attribute of 'export' node of 'meta.xml' for resource '%s', ignoring\n", - m_strResourceName.c_str()); + CLogger::ErrorPrintf("WARNING: Empty 'function' attribute of 'export' node of 'meta.xml' for resource '%s', ignoring\n", m_strResourceName.c_str()); continue; } @@ -1758,15 +1799,14 @@ bool CResource::ReadIncludedExports(CXMLNode* pRoot) if (!isHttpFunction && isHttpRouter) { isHttpRouter = false; - CLogger::ErrorPrintf("WARNING: Regular function '%s' in resource '%s' uses HTTP router attribute\n", - functionName, m_strResourceName.c_str()); + CLogger::ErrorPrintf("WARNING: Regular function '%s' in resource '%s' uses HTTP router attribute\n", functionName, m_strResourceName.c_str()); } if (isHttpRouter && !m_httpRouterFunction.empty()) { isHttpRouter = false; - CLogger::ErrorPrintf("WARNING: HTTP router function '%s' in resource '%s' ignored, using '%s'\n", - functionName, m_strResourceName.c_str(), m_httpRouterFunction.c_str()); + CLogger::ErrorPrintf("WARNING: HTTP router function '%s' in resource '%s' ignored, using '%s'\n", functionName, m_strResourceName.c_str(), + m_httpRouterFunction.c_str()); } // See if the restricted attribute is true or false @@ -1797,8 +1837,8 @@ bool CResource::ReadIncludedExports(CXMLNode* pRoot) } else if (stricmp(value, "server") != 0) { - CLogger::LogPrintf("WARNING: Function '%s' in resource '%s' uses unknown function type, assuming 'server'\n", - functionName, m_strResourceName.c_str()); + CLogger::LogPrintf("WARNING: Function '%s' in resource '%s' uses unknown function type, assuming 'server'\n", functionName, + m_strResourceName.c_str()); } } @@ -1811,8 +1851,8 @@ bool CResource::ReadIncludedExports(CXMLNode* pRoot) continue; } - CLogger::LogPrintf("WARNING: HTTP router function '%s' in resource '%s' is not a server-sided function, ignoring\n", - functionName, m_strResourceName.c_str()); + CLogger::LogPrintf("WARNING: HTTP router function '%s' in resource '%s' is not a server-sided function, ignoring\n", functionName, + m_strResourceName.c_str()); continue; } @@ -2248,7 +2288,7 @@ bool CResource::RemoveFile(const char* szName) m_ResourceFiles.remove(pFileFound); } else - CLogger::LogPrintf("WARNING: Problems removing resource file from memory"); + CLogger::LogPrintf("WARNING: Problems removing resource file from memory\n"); } // Delete the file @@ -2256,7 +2296,7 @@ bool CResource::RemoveFile(const char* szName) snprintf(szFullFilepath, MAX_PATH, "%s%s", m_strResourceDirectoryPath.c_str(), szName); if (File::Delete(szFullFilepath) != 0) - CLogger::LogPrintf("WARNING: Problems deleting the actual file, but was removed from resource"); + CLogger::LogPrintf("WARNING: Problems deleting the actual file, but was removed from resource\n"); // Delete the metafile pMetaFile->Write(); @@ -2541,13 +2581,14 @@ HttpStatusCode CResource::HandleRequest(HttpRequest* ipoHttpRequest, HttpRespons std::string Unescape(std::string_view sv) { // Converts a character to a hexadecimal value - auto toHex = [](char c) { + auto toHex = [](char c) -> uint8_t + { if (c >= '0' && c <= '9') - return c - '0'; + return static_cast(c - '0'); if (c >= 'a' && c <= 'f') - return c - 'a' + 10; + return static_cast(c - 'a' + 10); if (c >= 'A' && c <= 'F') - return c - 'A' + 10; + return static_cast(c - 'A' + 10); return 0; }; @@ -2687,7 +2728,7 @@ HttpStatusCode CResource::HandleRequestCall(HttpRequest* ipoHttpRequest, HttpRes { switch (szArg[1]) { - case 'E': // element + case 'E': // element { int id = atoi(szArg + 3); CElement* pElement = nullptr; @@ -2707,7 +2748,7 @@ HttpStatusCode CResource::HandleRequestCall(HttpRequest* ipoHttpRequest, HttpRes break; } - case 'R': // resource + case 'R': // resource { CResource* pResource = g_pGame->GetResourceManager()->GetResource(szArg + 3); @@ -2758,7 +2799,7 @@ HttpStatusCode CResource::HandleRequestCall(HttpRequest* ipoHttpRequest, HttpRes Headers.PushString(pair.second.c_str()); } - LUA_CHECKSTACK(m_pVM->GetVM(), 1); // Ensure some room + LUA_CHECKSTACK(m_pVM->GetVM(), 1); // Ensure some room // cache old data lua_getglobal(m_pVM->GetVM(), "form"); @@ -2870,7 +2911,8 @@ static HttpStatusCode ParseLuaHttpRouterResponse(CLuaArguments& luaResponse, Htt { if (std::string_view body; argValue->TryGetString(body)) { - if (body.size() <= std::numeric_limits::max()) + const auto maxInt = static_cast(std::numeric_limits::max()); + if (body.size() <= maxInt) { hasBody = true; httpResponse.SetBody(body.data(), body.size()); @@ -2903,7 +2945,7 @@ static HttpStatusCode ParseLuaHttpRouterResponse(CLuaArguments& luaResponse, Htt argValue = (*cookies)[j + 1]; std::string_view n, v; - + if (argName->TryGetString(n) && argValue->TryGetString(v)) { CookieParameters cookie; @@ -3023,7 +3065,7 @@ HttpStatusCode CResource::HandleRequestRouter(HttpRequest* request, HttpResponse luaRequest.PushString("*"); break; } - + luaRequest.PushString("path"); luaRequest.PushString(path); @@ -3056,7 +3098,7 @@ HttpStatusCode CResource::HandleRequestRouter(HttpRequest* request, HttpResponse } luaRequest.PushString("formData"); luaRequest.PushTable(&formData); - + CLuaArguments cookies; for (const auto& pair : request->oCookieMap) { @@ -3176,10 +3218,10 @@ HttpStatusCode CResource::HandleRequestActive(HttpRequest* ipoHttpRequest, HttpR pResourceFile->GetType() == CResourceFile::RESOURCE_FILE_TYPE_CLIENT_SCRIPT || pResourceFile->GetType() == CResourceFile::RESOURCE_FILE_TYPE_CLIENT_FILE) { - return pResourceFile->Request(ipoHttpRequest, ipoHttpResponse); // sends back any file in the resource + return pResourceFile->Request(ipoHttpRequest, ipoHttpResponse); // sends back any file in the resource } } - else // handle the default page + else // handle the default page { if (!IsHttpAccessAllowed(pAccount)) { @@ -3312,8 +3354,7 @@ bool CResource::CheckState() void CResource::OnPlayerJoin(CPlayer& Player) { - // do the player join crap - Player.Send(CResourceStartPacket(m_strResourceName.c_str(), this)); + Player.Send(CResourceStartPacket(m_strResourceName.c_str(), this, m_startCounter)); SendNoClientCacheScripts(&Player); } @@ -3383,7 +3424,7 @@ bool CResource::UnzipResource() { // If we're using a zip file, we need a temp directory for extracting // 17 = already exists (on windows) - if (File::Mkdir(m_strResourceCachePath.c_str()) == -1 && errno != EEXIST) // check this is the correct return for *NIX too + if (File::Mkdir(m_strResourceCachePath.c_str()) == -1 && errno != EEXIST) // check this is the correct return for *NIX too { // Show error m_strFailureReason = SString("Couldn't create directory '%s' for resource '%s', check that the server has write access to the resources folder.\n", @@ -3423,7 +3464,7 @@ bool CResource::UnzipResource() unsigned long ulFileOnDiskCRC = CRCGenerator::GetCRCFromFile(strPath.c_str()); if (ulFileInZipCRC == ulFileOnDiskCRC) - continue; // we've already extracted EXACTLY this file before + continue; // we've already extracted EXACTLY this file before RemoveFile(strPath.c_str()); } @@ -3523,7 +3564,7 @@ void change_file_date(const char* filename, uLong dosdate, tm_unz tmu_date) SetFileTime(hFile, &ftm, &ftLastAcc, &ftm); CloseHandle(hFile); #else -#ifdef unix + #ifdef unix struct utimbuf ut; struct tm newdate; newdate.tm_sec = tmu_date.tm_sec; @@ -3539,7 +3580,7 @@ void change_file_date(const char* filename, uLong dosdate, tm_unz tmu_date) ut.actime = ut.modtime = mktime(&newdate); utime(filename, &ut); -#endif + #endif #endif } @@ -3693,7 +3734,7 @@ int do_extract_currentfile(unzFile uf, const int* popt_extract_without_path, int return err; } -bool CIncludedResources::CreateLink() // just a pointer to it +bool CIncludedResources::CreateLink() // just a pointer to it { // Grab the resource that we are m_pResource = m_pResourceManager->GetResource(m_strResourceName.c_str()); diff --git a/Server/mods/deathmatch/logic/CResource.h b/Server/mods/deathmatch/logic/CResource.h index 3b7abb2dcbc..aff0364111e 100644 --- a/Server/mods/deathmatch/logic/CResource.h +++ b/Server/mods/deathmatch/logic/CResource.h @@ -23,9 +23,9 @@ #include #include -#define MAX_AUTHOR_LENGTH 255 -#define MAX_RESOURCE_NAME_LENGTH 255 -#define MAX_FUNCTION_NAME_LENGTH 50 +#define MAX_AUTHOR_LENGTH 255 +#define MAX_RESOURCE_NAME_LENGTH 255 +#define MAX_FUNCTION_NAME_LENGTH 50 class CDummy; class CElement; @@ -84,8 +84,8 @@ class CIncludedResources SVersion m_MaxVersion; bool m_bExists; bool m_bBadVersion; - CResource* m_pResource; // the resource this links to - CResource* m_pOwner; // the resource this is inside + CResource* m_pResource; // the resource this links to + CResource* m_pOwner; // the resource this is inside CResourceManager* m_pResourceManager; public: @@ -125,10 +125,10 @@ class CIncludedResources enum class EResourceState : unsigned char { None, - Loaded, // its been loaded successfully (i.e. meta parsed ok), included resources loaded ok - Starting, // the resource is starting - Running, // resource items are running - Stopping, // the resource is stopping + Loaded, // its been loaded successfully (i.e. meta parsed ok), included resources loaded ok + Starting, // the resource is starting + Running, // resource items are running + Stopping, // the resource is stopping }; // A resource is either a directory with files or a ZIP file which contains the content of such directory. @@ -136,6 +136,7 @@ enum class EResourceState : unsigned char // It's a process-like environment for scripts, maps, images and other files. class CResource : public EHS { + friend class CResourceManager; // Allow CResourceManager access to protected members using KeyValueMap = CFastHashMap; public: @@ -153,6 +154,8 @@ class CResource : public EHS void Reload(); + bool CanPlayerTriggerResourceStart(CPlayer* player, unsigned int playerStartCounter); + // Get a resource default setting bool GetDefaultSetting(const char* szName, char* szValue, size_t sizeBuffer); @@ -250,11 +253,11 @@ class CResource : public EHS bool CheckIfStartable(); void DisplayInfo(); - bool GetFilePath(const char* szFilename, std::string& strPath); - std::vector GetFilePaths(const char* szFilename); + bool GetFilePath(const char* szFilename, std::string& strPath); + std::vector GetFilePaths(const char* szFilename); - const std::string& GetResourceDirectoryPath() const { return m_strResourceDirectoryPath; } - const std::string& GetResourceCacheDirectoryPath() const { return m_strResourceCachePath; } + const std::string& GetResourceDirectoryPath() const { return m_strResourceDirectoryPath; } + const std::string& GetResourceCacheDirectoryPath() const { return m_strResourceCachePath; } std::list& GetFiles() { return m_ResourceFiles; } size_t GetFileCount() const noexcept { return m_ResourceFiles.size(); } @@ -268,6 +271,7 @@ class CResource : public EHS uint GetScriptID() const noexcept { return m_uiScriptID; } void OnPlayerJoin(CPlayer& Player); + void OnPlayerQuit(CPlayer& Player); void SendNoClientCacheScripts(CPlayer* pPlayer = nullptr); void OnResourceStateChange(const char* state) noexcept; @@ -344,10 +348,10 @@ class CResource : public EHS void RefreshAutoPermissions(CXMLNode* pNodeAclRequest); void CommitAclRequest(const SAclRequest& request); - bool FindAclRequest(SAclRequest& request); + bool FindAclRequest(SAclRequest& result); private: - bool CheckState(); // if the resource has no Dependents, stop it, if it has, start it. returns true if the resource is started. + bool CheckState(); // if the resource has no Dependents, stop it, if it has, start it. returns true if the resource is started. bool ReadIncludedResources(CXMLNode* pRoot); bool ReadIncludedMaps(CXMLNode* pRoot); bool ReadIncludedScripts(CXMLNode* pRoot); @@ -374,15 +378,15 @@ class CResource : public EHS CResourceManager* m_pResourceManager; SString m_strResourceName; - SString m_strAbsPath; // Absolute path to containing directory i.e. /server/mods/deathmatch/resources - std::string m_strResourceZip; // Absolute path to zip file (if a zip) i.e. m_strAbsPath/resource_name.zip - std::string m_strResourceDirectoryPath; // Absolute path to resource files (if a dir) i.e. m_strAbsPath/resource_name - std::string m_strResourceCachePath; // Absolute path to unzipped cache (if a zip) i.e. /server/mods/deathmatch/resources/cache/resource_name + SString m_strAbsPath; // Absolute path to containing directory i.e. /server/mods/deathmatch/resources + std::string m_strResourceZip; // Absolute path to zip file (if a zip) i.e. m_strAbsPath/resource_name.zip + std::string m_strResourceDirectoryPath; // Absolute path to resource files (if a dir) i.e. m_strAbsPath/resource_name + std::string m_strResourceCachePath; // Absolute path to unzipped cache (if a zip) i.e. /server/mods/deathmatch/resources/cache/resource_name unsigned int m_uiVersionMajor = 0; unsigned int m_uiVersionMinor = 0; unsigned int m_uiVersionRevision = 0; - unsigned int m_uiVersionState = 2; // 2 = release + unsigned int m_uiVersionState = 2; // 2 = release int m_iDownloadPriorityGroup = 0; @@ -392,16 +396,19 @@ class CResource : public EHS CElement* m_pRootElement = nullptr; CDummy* m_pResourceElement = nullptr; CDummy* m_pResourceDynamicElementRoot = nullptr; - CElementGroup* m_pDefaultElementGroup = nullptr; // stores elements created by scripts in this resource + CElementGroup* m_pDefaultElementGroup = nullptr; // stores elements created by scripts in this resource CLuaMain* m_pVM = nullptr; + unsigned int m_startCounter{}; + std::unordered_set m_isRunningForPlayer; + KeyValueMap m_Info; - std::list m_IncludedResources; // we store them here temporarily, then read them once all the resources are loaded + std::list m_IncludedResources; // we store them here temporarily, then read them once all the resources are loaded std::list m_ResourceFiles; std::map m_ResourceFilesCountPerDir; - std::list m_Dependents; // resources that have "included" or loaded this one + std::list m_Dependents; // resources that have "included" or loaded this one std::list m_ExportedFunctions; - std::list m_TemporaryIncludes; // started by startResource script command + std::list m_TemporaryIncludes; // started by startResource script command int m_httpRouterCheck{}; std::string m_httpRouterFunction; @@ -427,23 +434,23 @@ class CResource : public EHS bool m_bUsingDbConnectMysql = false; bool m_bOOPEnabledInMetaXml = false; - bool m_bLinked = false; // if true, the included resources are already linked to this resource - bool m_bIsPersistent = false; // if true, the resource will remain even if it has no Dependents, mainly if started by the user or the startup + bool m_bLinked = false; // if true, the included resources are already linked to this resource + bool m_bIsPersistent = false; // if true, the resource will remain even if it has no Dependents, mainly if started by the user or the startup bool m_bDestroyed = false; - CXMLNode* m_pNodeSettings = nullptr; // Settings XML node, read from meta.xml and copied into it's own instance - CXMLNode* m_pNodeStorage = nullptr; // Dummy XML node used for temporary storage of stuff returned by CSettings::Get + CXMLNode* m_pNodeSettings = nullptr; // Settings XML node, read from meta.xml and copied into it's own instance + CXMLNode* m_pNodeStorage = nullptr; // Dummy XML node used for temporary storage of stuff returned by CSettings::Get - CMtaVersion m_strMinClientRequirement; // Min MTA client version - CMtaVersion m_strMinServerRequirement; // Min MTA server version - CMtaVersion m_strMinClientFromMetaXml; // Min MTA client version as declared in meta.xml - CMtaVersion m_strMinServerFromMetaXml; // Min MTA server version as declared in meta.xml - CMtaVersion m_strMinClientReqFromSource; // Min MTA client version as calculated by scanning the script source - CMtaVersion m_strMinServerReqFromSource; // Min MTA server version as calculated by scanning the script source + CMtaVersion m_strMinClientRequirement; // Min MTA client version + CMtaVersion m_strMinServerRequirement; // Min MTA server version + CMtaVersion m_strMinClientFromMetaXml; // Min MTA client version as declared in meta.xml + CMtaVersion m_strMinServerFromMetaXml; // Min MTA server version as declared in meta.xml + CMtaVersion m_strMinClientReqFromSource; // Min MTA client version as calculated by scanning the script source + CMtaVersion m_strMinServerReqFromSource; // Min MTA server version as calculated by scanning the script source SString m_strMinClientReason; SString m_strMinServerReason; - CChecksum m_metaChecksum; // Checksum of meta.xml last time this was loaded, generated in GenerateChecksums() + CChecksum m_metaChecksum; // Checksum of meta.xml last time this was loaded, generated in GenerateChecksums() uint m_uiFunctionRightCacheRevision = 0; CFastHashMap m_FunctionRightCacheMap; diff --git a/Server/mods/deathmatch/logic/CResourceChecker.Data.h b/Server/mods/deathmatch/logic/CResourceChecker.Data.h index 3f41f3728a5..a91d96f501a 100644 --- a/Server/mods/deathmatch/logic/CResourceChecker.Data.h +++ b/Server/mods/deathmatch/logic/CResourceChecker.Data.h @@ -15,6 +15,7 @@ namespace // Minimum version requirements for functions/events // +#if 0 // Activate the counterpart in CResourceChecker::CheckVersionRequirements when you add items to these lists struct SVersionItem { SString functionName; @@ -22,58 +23,15 @@ namespace }; SVersionItem clientFunctionInitList[] = { - // Features added in 1.6.0 - {"getAllElementData", "1.6.0-9.21695"}, - {"engineLoadIMG", "1.6.0-9.21695"}, - {"engineImageLinkDFF", "1.6.0-9.21695"}, - {"engineImageLinkTXD", "1.6.0-9.21695"}, - {"engineRestoreDFFImage", "1.6.0-9.21695"}, - {"engineRestoreTXDImage", "1.6.0-9.21695"}, - {"engineAddImage", "1.6.0-9.21695"}, - {"engineRemoveImage", "1.6.0-9.21695"}, - {"engineImageGetFilesCount", "1.6.0-9.21695"}, - {"engineImageGetFiles", "1.6.0-9.21695"}, - {"engineImageGetFile", "1.6.0-9.21695"}, - {"engineGetModelTXDID", "1.6.0-9.21695"}, - {"engineSetModelFlags", "1.6.0-9.21695"}, - {"engineGetModelFlags", "1.6.0-9.21695"}, - {"engineResetModelFlags", "1.6.0-9.21695"}, - {"engineGetModelFlag", "1.6.0-9.21695"}, - {"engineSetModelFlag", "1.6.0-9.21695"}, - {"fileGetContents", "1.6.0-9.21938"}, - {"fileGetHash", "1.6.0-9.23289"}, - {"engineStreamingSetModelCacheLimits", "1.6.0-9.21946"}, - {"engineStreamingRestoreBufferSize", "1.6.0-9.22195"}, - {"createBuilding", "1.6.0-9.22410"}, - {"restoreAllGameBuildings", "1.6.0-9.22420"}, - {"removeAllGameBuildings", "1.6.0-9.22420"}, - {"pathListDir", "1.6.0-9.22470"}, - {"pathIsFile", "1.6.0-9.22470"}, - {"pathIsDirectory", "1.6.0-9.22470"}, - {"engineGetPoolCapacity", "1.6.0-9.22471"}, - {"engineGetPoolDefaultCapacity", "1.6.0-9.22471"}, - {"engineGetPoolUsedCapacity", "1.6.0-9.22471"}, - {"engineSetPoolCapacity", "1.6.0-9.22471"}, + // Features added in 1.7.0 + // {"name", "1.7.0-9.bbbbb"}, }; SVersionItem serverFunctionInitList[] = { - // Features added in 1.6.0 - {"isObjectBreakable", "1.6.0-9.21765"}, - {"setObjectBreakable", "1.6.0-9.21765"}, - {"fileGetContents", "1.6.0-9.21938"}, - {"fileGetHash", "1.6.0-9.23289"}, - {"isWorldSpecialPropertyEnabled", "1.6.0-9.22195"}, - {"setWorldSpecialPropertyEnabled", "1.6.0-9.22195"}, - {"onResourceStateChange", "1.6.0-9.22430"}, - {"isObjectMoving", "1.6.0-9.22457"}, - {"onPlayerTriggerInvalidEvent", "1.6.0-9.22459"}, - {"pathListDir", "1.6.0-9.22470"}, - {"pathIsFile", "1.6.0-9.22470"}, - {"pathIsDirectory", "1.6.0-9.22470"}, - {"onAccountCreate", "1.6.0-9.22470"}, - {"onAccountRemove", "1.6.0-9.22470"}, - {"getAccountType", "1.6.0-9.22470"}, + // Features added in 1.7.0 + // {"name", "1.7.0-9.bbbbb"}, }; +#endif // // Deprecated function/events @@ -255,7 +213,7 @@ namespace {false, "getPlayerOccupiedVehicleSeat", "getPedOccupiedVehicleSeat"}, {false, "isPlayerInVehicle", "isPedInVehicle"}, {false, "getPlayerFromNick", "getPlayerFromName"}, - + // Client {false, "getClientName", "getPlayerName"}, {false, "getClientIP", "getPlayerIP"}, @@ -283,9 +241,8 @@ namespace // Base Encoding & Decoding {true, "base64Encode", "Please manually change this to encodeString (different syntax). Refer to the wiki for details"}, {true, "base64Decode", "Please manually change this to decodeString (different syntax). Refer to the wiki for details"}, - + // Ped {false, "setPedOnFire", "setElementOnFire"}, - {false, "isPedOnFire", "isElementOnFire"} - }; -} // namespace + {false, "isPedOnFire", "isElementOnFire"}}; +} // namespace diff --git a/Server/mods/deathmatch/logic/CResourceChecker.cpp b/Server/mods/deathmatch/logic/CResourceChecker.cpp index 9fa1f5c6e06..efde93c1f50 100644 --- a/Server/mods/deathmatch/logic/CResourceChecker.cpp +++ b/Server/mods/deathmatch/logic/CResourceChecker.cpp @@ -309,24 +309,24 @@ void CResourceChecker::CheckMetaFileForIssues(const string& strPath, const strin else // ..or do an upgrade if (m_bUpgradeScripts == true) - { - bool bHasChanged = false; - CheckMetaSourceForIssues(pRootNode, strFileName, strResourceName, ECheckerMode::UPGRADE, &bHasChanged); - - // Has contents changed? - if (bHasChanged) { - // Rename original to xml.old - if (!RenameBackupFile(strPath, ".old")) - return; + bool bHasChanged = false; + CheckMetaSourceForIssues(pRootNode, strFileName, strResourceName, ECheckerMode::UPGRADE, &bHasChanged); - // Save new content - metaFile->Write(); - CLogger::LogPrintf("Upgrading %s:%s ...........done\n", strResourceName.c_str(), strFileName.c_str()); + // Has contents changed? + if (bHasChanged) + { + // Rename original to xml.old + if (!RenameBackupFile(strPath, ".old")) + return; - m_upgradedFullPathList.push_back(strPath); + // Save new content + metaFile->Write(); + CLogger::LogPrintf("Upgrading %s:%s ...........done\n", strResourceName.c_str(), strFileName.c_str()); + + m_upgradedFullPathList.push_back(strPath); + } } - } delete metaFile; } @@ -422,11 +422,11 @@ void CResourceChecker::CheckLuaFileForIssues(const string& strPath, const string if (strFileContents.length() > 1000000) CLogger::LogPrintf("Please wait...\n"); - if (m_bUpgradeScripts == false) // Output warnings... + if (m_bUpgradeScripts == false) // Output warnings... { CheckLuaSourceForIssues(strFileContents, strFileName, strResourceName, bClientScript, bCompiledScript, ECheckerMode::WARNINGS); } - else if (!bCompiledScript) // ..or do an upgrade (if not compiled) + else if (!bCompiledScript) // ..or do an upgrade (if not compiled) { string strNewFileContents; CheckLuaSourceForIssues(strFileContents, strFileName, strResourceName, bClientScript, bCompiledScript, ECheckerMode::UPGRADE, &strNewFileContents); @@ -519,7 +519,7 @@ void CResourceChecker::CheckLuaSourceForIssues(string strLuaSource, const string { std::wstring strUTF16Script = ANSIToUTF16(strLuaSource); #ifdef WIN32 - std::setlocale(LC_CTYPE, ""); // Temporarilly use locales to read the script + std::setlocale(LC_CTYPE, ""); // Temporarilly use locales to read the script std::string strUTFScript = UTF16ToMbUTF8(strUTF16Script); std::setlocale(LC_CTYPE, "C"); #else @@ -540,8 +540,8 @@ void CResourceChecker::CheckLuaSourceForIssues(string strLuaSource, const string if (checkerMode == ECheckerMode::WARNINGS) { m_ulDeprecatedWarningCount++; - CLogger::LogPrintf("WARNING: %s/%s [%s] is encoded in ANSI instead of UTF-8. Please convert your file to UTF-8.\n", - strResourceName.c_str(), strFileName.c_str(), bClientScript ? "Client" : "Server"); + CLogger::LogPrintf("WARNING: %s/%s [%s] is encoded in ANSI instead of UTF-8. Please convert your file to UTF-8.\n", strResourceName.c_str(), + strFileName.c_str(), bClientScript ? "Client" : "Server"); } } } @@ -750,7 +750,7 @@ void CResourceChecker::CheckLuaSourceForIssues(string strLuaSource, const string continue; } - if (first == ']' && second == '=' && tokenLevel > 0) // Maybe close a long comment of level 1 and above: "]=]" or "]==]" or ... + if (first == ']' && second == '=' && tokenLevel > 0) // Maybe close a long comment of level 1 and above: "]=]" or "]==]" or ... { const unsigned char* start = current + 1; const unsigned char* equals = start + 1; @@ -907,7 +907,7 @@ void CResourceChecker::CheckLuaSourceForIssues(string strLuaSource, const string if (const size_t length = pos - current; length > 2) { - std::string_view literal(reinterpret_cast(current + 1), length - 2); // Do not include surrounding quotes. + std::string_view literal(reinterpret_cast(current + 1), length - 2); // Do not include surrounding quotes. tokenContent = literal; tokenLine = line; processStringLiteral(); @@ -957,7 +957,7 @@ void CResourceChecker::CheckLuaSourceForIssues(string strLuaSource, const string current += 1; continue; } - + // We are calling a function with several arguments or with a table: foo (...) or foo {...} if ((first == '(' && lastKeyword != "function") || first == '{') { @@ -1057,7 +1057,7 @@ ECheckerWhatType CResourceChecker::GetLuaFunctionNameUpgradeInfo(const string& s // Query the correct map with the cleaned function name SDeprecatedItem* pItem = MapFindRef(bClientScript ? clientUpgradeInfoMap : serverUpgradeInfoMap, strFunctionName); if (!pItem) - return ECheckerWhat::NONE; // Nothing found + return ECheckerWhat::NONE; // Nothing found strOutHow = pItem->strNewName; strOutVersion = pItem->strVersion; @@ -1085,6 +1085,7 @@ void CResourceChecker::CheckVersionRequirements(const string& strIdentifierName, static CHashMap clientFunctionMap; static CHashMap serverFunctionMap; +#if 0 // Check if lookup maps need initializing if (clientFunctionMap.empty()) { @@ -1094,6 +1095,7 @@ void CResourceChecker::CheckVersionRequirements(const string& strIdentifierName, for (uint i = 0; i < NUMELMS(serverFunctionInitList); i++) MapSet(serverFunctionMap, serverFunctionInitList[i].functionName, CMtaVersion(serverFunctionInitList[i].minMtaVersion)); } +#endif // Select client or server check const CHashMap& functionMap = bClientScript ? clientFunctionMap : serverFunctionMap; @@ -1154,11 +1156,11 @@ int CResourceChecker::ReplaceFilesInZIP(const string& strOrigZip, const string& { // open source and destination file zlib_filefunc_def ffunc; - #ifdef WIN32 +#ifdef WIN32 fill_win32_filefunc(&ffunc); - #else +#else fill_fopen_filefunc(&ffunc); - #endif +#endif zipFile szip = unzOpen2(strOrigZip.c_str(), &ffunc); if (szip == NULL) @@ -1213,9 +1215,9 @@ int CResourceChecker::ReplaceFilesInZIP(const string& strOrigZip, const string& if (unzGetCurrentFileInfo(szip, &unzfi, dos_fn, MAX_PATH, NULL, 0, NULL, 0) != UNZ_OK) break; char fn[MAX_PATH]; - #ifdef WIN32 +#ifdef WIN32 OemToChar(dos_fn, fn); - #endif +#endif // See if file should be replaced string fullPathReplacement; diff --git a/Server/mods/deathmatch/logic/CResourceClientConfigItem.h b/Server/mods/deathmatch/logic/CResourceClientConfigItem.h index 6c89159a51b..23e14f33c92 100644 --- a/Server/mods/deathmatch/logic/CResourceClientConfigItem.h +++ b/Server/mods/deathmatch/logic/CResourceClientConfigItem.h @@ -29,5 +29,5 @@ class CResourceClientConfigItem : public CResourceFile class CXMLFile* m_pXMLFile; CXMLNode* m_pXMLRootNode; - bool m_bInvalid; // it failed to load + bool m_bInvalid; // it failed to load }; diff --git a/Server/mods/deathmatch/logic/CResourceClientScriptItem.cpp b/Server/mods/deathmatch/logic/CResourceClientScriptItem.cpp index 138661f1871..ba8f4bacb7f 100644 --- a/Server/mods/deathmatch/logic/CResourceClientScriptItem.cpp +++ b/Server/mods/deathmatch/logic/CResourceClientScriptItem.cpp @@ -62,7 +62,7 @@ bool CResourceClientScriptItem::Start() // Compress the source unsigned int originalLength = m_sourceCode.length(); unsigned long bufferLength = - m_sourceCode.length() + 12 + (unsigned int)(m_sourceCode.length() * 0.001f); // Refer to the compress2() function documentation. + m_sourceCode.length() + 12 + (unsigned int)(m_sourceCode.length() * 0.001f); // Refer to the compress2() function documentation. char* compressedBuffer = new char[bufferLength]; if (compress2((Bytef*)compressedBuffer, (uLongf*)&bufferLength, (const Bytef*)m_sourceCode.c_str(), m_sourceCode.length(), Z_BEST_COMPRESSION) != Z_OK) { diff --git a/Server/mods/deathmatch/logic/CResourceConfigItem.h b/Server/mods/deathmatch/logic/CResourceConfigItem.h index 154a86abde9..d047e0a8417 100644 --- a/Server/mods/deathmatch/logic/CResourceConfigItem.h +++ b/Server/mods/deathmatch/logic/CResourceConfigItem.h @@ -15,7 +15,7 @@ #include #ifndef MAX_PATH -#define MAX_PATH 260 + #define MAX_PATH 260 #endif class CResourceConfigItem : public CResourceFile diff --git a/Server/mods/deathmatch/logic/CResourceFile.cpp b/Server/mods/deathmatch/logic/CResourceFile.cpp index 10b943ac4aa..f1fc3e5cbdd 100644 --- a/Server/mods/deathmatch/logic/CResourceFile.cpp +++ b/Server/mods/deathmatch/logic/CResourceFile.cpp @@ -74,17 +74,37 @@ HttpStatusCode CResourceFile::Request(HttpRequest* ipoHttpRequest, HttpResponse* long lBufferLength = ftell(file); rewind(file); + if (lBufferLength < 0) + { + fclose(file); + ipoHttpResponse->SetBody("Failed to determine file size", strlen("Failed to determine file size")); + return HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR; + } + // Allocate and read the entire file // TODO: This is inefficient. - char* szBuffer = new char[lBufferLength + 1]; - fread(szBuffer, 1, lBufferLength, file); - fclose(file); - - // - ipoHttpResponse->oResponseHeaders["content-type"] = "application/octet-stream"; // not really the right mime-type - ipoHttpResponse->SetBody(szBuffer, lBufferLength); - delete[] szBuffer; - return HTTP_STATUS_CODE_200_OK; + char* szBuffer = nullptr; + try + { + szBuffer = new char[lBufferLength + 1]; + size_t bytesRead = fread(szBuffer, 1, lBufferLength, file); + fclose(file); + file = nullptr; + + ipoHttpResponse->oResponseHeaders["content-type"] = "application/octet-stream"; + ipoHttpResponse->SetBody(szBuffer, static_cast(bytesRead)); + delete[] szBuffer; + return HTTP_STATUS_CODE_200_OK; + } + catch (const std::bad_alloc&) + { + delete[] szBuffer; + if (file) + fclose(file); + + ipoHttpResponse->SetBody("Server out of memory", strlen("Server out of memory")); + return HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR; + } } else { diff --git a/Server/mods/deathmatch/logic/CResourceFile.h b/Server/mods/deathmatch/logic/CResourceFile.h index 4cfc3b36d06..1898fa7f7bb 100644 --- a/Server/mods/deathmatch/logic/CResourceFile.h +++ b/Server/mods/deathmatch/logic/CResourceFile.h @@ -35,18 +35,18 @@ class CResourceFile RESOURCE_FILE_TYPE_HTML, RESOURCE_FILE_TYPE_CLIENT_FILE, RESOURCE_FILE_TYPE_NONE, - }; // TODO: sort all client-side enums and use >= (instead of each individual type) on comparisons that use this enum? + }; // TODO: sort all client-side enums and use >= (instead of each individual type) on comparisons that use this enum? protected: class CResource* m_resource; - std::string m_strResourceFileName; // full path - std::string m_strShortName; // just the filename - std::string m_strWindowsName; // the name with backwards slashes + std::string m_strResourceFileName; // full path + std::string m_strShortName; // just the filename + std::string m_strWindowsName; // the name with backwards slashes eResourceType m_type; class CLuaMain* m_pVM; - CChecksum m_checksum; // Checksum last time this was loaded, generated by GenerateChecksum() - uint m_uiFileSizeHint; - map m_attributeMap; // Map of attributes from the meta.xml file + CChecksum m_checksum; // Checksum last time this was loaded, generated by GenerateChecksum() + uint64 m_uiFileSizeHint; + map m_attributeMap; // Map of attributes from the meta.xml file public: CResourceFile(class CResource* resource, const char* szShortName, const char* szResourceFileName, CXMLAttributes* xmlAttributes); @@ -65,9 +65,9 @@ class CResourceFile CChecksum GetLastChecksum() { return m_checksum; } void SetLastChecksum(CChecksum checksum) { m_checksum = checksum; } - void SetLastFileSizeHint(uint uiFileSizeHint) { m_uiFileSizeHint = uiFileSizeHint; } + void SetLastFileSizeHint(uint64 uiFileSizeHint) { m_uiFileSizeHint = uiFileSizeHint; } - uint GetSizeHint() { return m_uiFileSizeHint; } // Only used by download counters + uint64 GetSizeHint() { return m_uiFileSizeHint; } // Only used by download counters string GetMetaFileAttribute(const string& key) { return m_attributeMap[key]; } SString GetCachedPathFilename(bool bForceClientCachePath = false); }; diff --git a/Server/mods/deathmatch/logic/CResourceHTMLItem.cpp b/Server/mods/deathmatch/logic/CResourceHTMLItem.cpp index 5fc623a2d74..cc3220ae286 100644 --- a/Server/mods/deathmatch/logic/CResourceHTMLItem.cpp +++ b/Server/mods/deathmatch/logic/CResourceHTMLItem.cpp @@ -122,21 +122,31 @@ HttpStatusCode CResourceHTMLItem::Request(HttpRequest* ipoHttpRequest, HttpRespo m_currentResponse = ipoHttpResponse; CLuaArguments querystring(formData); CLuaArguments args; - args.PushTable(&headers); // requestHeaders - args.PushTable(&formData); // form - args.PushTable(&cookies); // cookies - args.PushString(ipoHttpRequest->GetAddress().c_str()); // hostname - args.PushString(ipoHttpRequest->sOriginalUri.c_str()); // url - args.PushTable(&querystring); // querystring + args.PushTable(&headers); // requestHeaders + args.PushTable(&formData); // form + args.PushTable(&cookies); // cookies + args.PushString(ipoHttpRequest->GetAddress().c_str()); // hostname + args.PushString(ipoHttpRequest->sOriginalUri.c_str()); // url + args.PushTable(&querystring); // querystring args.PushAccount(account); - args.PushString(ipoHttpRequest->sBody); // requestBody - args.PushString(sMethod); // method + args.PushString(ipoHttpRequest->sBody); // requestBody + args.PushString(sMethod); // method // g_pGame->Lock(); // get the mutex (blocking) args.CallGlobal(m_pVM, "renderPage"); // g_pGame->Unlock(); // release the mutex - ipoHttpResponse->SetBody(m_strPageBuffer.c_str(), m_strPageBuffer.size()); + try + { + ipoHttpResponse->SetBody(m_strPageBuffer.c_str(), m_strPageBuffer.size()); + } + catch (const std::bad_alloc&) + { + m_strPageBuffer.clear(); + ipoHttpResponse->SetBody("Server out of memory", strlen("Server out of memory")); + m_bIsBeingRequested = false; + return HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR; + } m_strPageBuffer.clear(); } else @@ -146,14 +156,39 @@ HttpStatusCode CResourceHTMLItem::Request(HttpRequest* ipoHttpRequest, HttpRespo if (file) { fseek(file, 0, SEEK_END); - long lBufferLength = ftell(file); - char* pBuffer = new char[lBufferLength]; + long lBufferLength = ftell(file); rewind(file); - fread(pBuffer, 1, lBufferLength, file); - fclose(file); - ipoHttpResponse->oResponseHeaders["content-type"] = m_strMime; - ipoHttpResponse->SetBody(pBuffer, lBufferLength); - delete[] pBuffer; + + if (lBufferLength < 0) + { + fclose(file); + ipoHttpResponse->SetBody("Failed to determine file size", strlen("Failed to determine file size")); + m_bIsBeingRequested = false; + return HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR; + } + + char* pBuffer = nullptr; + try + { + pBuffer = new char[lBufferLength]; + size_t bytesRead = fread(pBuffer, 1, lBufferLength, file); + fclose(file); + file = nullptr; + + ipoHttpResponse->oResponseHeaders["content-type"] = m_strMime; + ipoHttpResponse->SetBody(pBuffer, static_cast(bytesRead)); + delete[] pBuffer; + } + catch (const std::bad_alloc&) + { + delete[] pBuffer; + if (file) + fclose(file); + + ipoHttpResponse->SetBody("Server out of memory", strlen("Server out of memory")); + m_bIsBeingRequested = false; + return HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR; + } } else { @@ -209,7 +244,7 @@ bool CResourceHTMLItem::Start() bool bIsShorthandCodeBlock = false; std::string strScript; strScript += "function renderPage ( requestHeaders, form, cookies, hostname, url, querystring, user, requestBody, method )\n"; - strScript += "\nhttpWrite ( \""; // bit hacky, possibly can be terminated straight away + strScript += "\nhttpWrite ( \""; // bit hacky, possibly can be terminated straight away unsigned char c; int i = 0; while (!feof(pFile)) @@ -218,19 +253,19 @@ bool CResourceHTMLItem::Start() if (feof(pFile)) break; - if (bInCode == false) // we're in a plain HTML section + if (bInCode == false) // we're in a plain HTML section { if (c == '<' && !feof(pFile)) { c = ReadChar(pFile); - if (c == '*') // we've found <* + if (c == '*') // we've found <* { bInCode = true; bJustStartedCodeBlock = true; - strScript.append("\" )\n"); // add ") to the end to terminate our last non-code section + strScript.append("\" )\n"); // add ") to the end to terminate our last non-code section } else - { // we found < but not a *, so just output both characters we read + { // we found < but not a *, so just output both characters we read strScript += '<'; strScript += c; } @@ -258,22 +293,22 @@ bool CResourceHTMLItem::Start() } } else - { // we're in a code block + { // we're in a code block if (c == '*' && !feof(pFile)) { c = ReadChar(pFile); - if (c == '>') // we've found *> + if (c == '>') // we've found *> { bInCode = false; if (bIsShorthandCodeBlock) { bIsShorthandCodeBlock = false; - strScript += ')'; // terminate the 'httpWrite' function + strScript += ')'; // terminate the 'httpWrite' function } - strScript.append("\nhttpWrite ( \""); // add httpWrite ( " to start a new non-code section + strScript.append("\nhttpWrite ( \""); // add httpWrite ( " to start a new non-code section } else - { // we found * but not a >, so just output both characters we read + { // we found * but not a >, so just output both characters we read strScript += '*'; strScript += c; } @@ -285,7 +320,7 @@ bool CResourceHTMLItem::Start() } else { - if (c != '\t' && c != ' ') // we allow whitespace before the shorthand '=' sign + if (c != '\t' && c != ' ') // we allow whitespace before the shorthand '=' sign bJustStartedCodeBlock = false; strScript += c; } diff --git a/Server/mods/deathmatch/logic/CResourceHTMLItem.h b/Server/mods/deathmatch/logic/CResourceHTMLItem.h index 506e0728611..f88505f8d45 100644 --- a/Server/mods/deathmatch/logic/CResourceHTMLItem.h +++ b/Server/mods/deathmatch/logic/CResourceHTMLItem.h @@ -15,7 +15,7 @@ #include "ehs/ehs.h" #ifndef MAX_PATH -#define MAX_PATH 260 + #define MAX_PATH 260 #endif class CResourceHTMLItem : public CResourceFile @@ -43,11 +43,11 @@ class CResourceHTMLItem : public CResourceFile char ReadChar(FILE* pFile) { return (unsigned char)fgetc(pFile); } void GetMimeType(const char* szFilename); - bool m_bIsBeingRequested; // crude mutex + bool m_bIsBeingRequested; // crude mutex bool m_bIsRaw; CLuaMain* m_pVM; - std::string m_strPageBuffer; // contains what we're sending - bool m_bDefault; // is this the default page for this resource? + std::string m_strPageBuffer; // contains what we're sending + bool m_bDefault; // is this the default page for this resource? std::string m_strMime; bool m_bRestricted; diff --git a/Server/mods/deathmatch/logic/CResourceManager.cpp b/Server/mods/deathmatch/logic/CResourceManager.cpp index 26c5938acbf..67dd48fd6d2 100644 --- a/Server/mods/deathmatch/logic/CResourceManager.cpp +++ b/Server/mods/deathmatch/logic/CResourceManager.cpp @@ -23,8 +23,8 @@ #include "CDatabaseManager.h" #include "CRegistry.h" -#define BLOCKED_DB_FILE_NAME "fileblock.db" -#define BLOCKED_DB_TABLE_NAME "`block_reasons`" +#define BLOCKED_DB_FILE_NAME "fileblock.db" +#define BLOCKED_DB_TABLE_NAME "`block_reasons`" // SResInfo - Item in list of potential resources - Used in Refresh() struct SResInfo @@ -172,19 +172,42 @@ bool CResourceManager::Refresh(bool bRefreshAll, const SString strJustThisResour if (!strJustThisResource.empty() && strJustThisResource != info.strName) continue; - if (!info.bPathIssue) - { - CResource* pResource = GetResource(info.strName); + if (info.bPathIssue) + continue; - if (bRefreshAll || !pResource || !pResource->CheckIfStartable()) - { - if (g_pServerInterface->IsRequestingExit()) - return false; + auto* pResource = GetResource(info.strName); - // Add the resource - Load(!info.bIsDir, info.strAbsPath, info.strName); - } + if (bRefreshAll || !pResource || !pResource->CheckIfStartable()) + { + if (g_pServerInterface->IsRequestingExit()) + return false; + + // Add the resource + Load(!info.bIsDir, info.strAbsPath, info.strName); + continue; } + + if (!pResource) + continue; + + // For existing resources, refresh ACL permissions without full reload + std::string strPath; + if (!pResource->GetFilePath("meta.xml", strPath)) + continue; + + std::unique_ptr pMetaFile(g_pServerInterface->GetXML()->CreateXML(strPath.c_str())); + if (!pMetaFile || !pMetaFile->Parse()) + continue; + + CXMLNode* pRoot = pMetaFile->GetRootNode(); + if (!pRoot) + continue; + + CXMLNode* pNodeAclRequest = pRoot->FindSubNode("aclrequest", 0); + if (pNodeAclRequest) + pResource->RefreshAutoPermissions(pNodeAclRequest); + else + pResource->RemoveAutoPermissions(); } marker.Set("AddNew"); @@ -526,7 +549,7 @@ CResource* CResourceManager::GetResourceFromNetID(unsigned short usNetID) { if ((*iter)->GetNetID() == usNetID) { - assert(0); // Should be in map + assert(0); // Should be in map return (*iter); } } @@ -543,6 +566,14 @@ void CResourceManager::OnPlayerJoin(CPlayer& Player) } } +void CResourceManager::OnPlayerQuit(CPlayer& Player) +{ + for (CResource* resource : CResource::m_StartedResources) + { + resource->OnPlayerQuit(Player); + } +} + // // Add resource <-> luaVM lookup mapping // @@ -840,11 +871,11 @@ void CResourceManager::ProcessQueue() } else if (sItem.eQueue == QUEUE_REFRESH) { - Refresh(false, sItem.pResource ? sItem.pResource->GetName() : ""); + Refresh(false, sItem.pResource ? sItem.pResource->GetName() : SStringX("")); } else if (sItem.eQueue == QUEUE_REFRESHALL) { - Refresh(true, sItem.pResource ? sItem.pResource->GetName() : ""); + Refresh(true, sItem.pResource ? sItem.pResource->GetName() : SStringX("")); } } } @@ -1328,11 +1359,11 @@ void CResourceManager::ReevaluateSyncMapElementDataOption() { if (iter->second) { - bSyncMapElementData = true; // Any 'true' will stop the set + bSyncMapElementData = true; // Any 'true' will stop the set break; } else - bSyncMapElementData = false; // Need at least one 'false' to set + bSyncMapElementData = false; // Need at least one 'false' to set } // Apply diff --git a/Server/mods/deathmatch/logic/CResourceManager.h b/Server/mods/deathmatch/logic/CResourceManager.h index eac0ab5fa11..59f2f94766d 100644 --- a/Server/mods/deathmatch/logic/CResourceManager.h +++ b/Server/mods/deathmatch/logic/CResourceManager.h @@ -19,7 +19,7 @@ #include "ehs/ehs.h" #include -#define INVALID_RESOURCE_NET_ID 0xFFFF +#define INVALID_RESOURCE_NET_ID 0xFFFF class CResource; @@ -67,6 +67,7 @@ class CResourceManager unsigned int GetResourceLoadedCount() { return m_uiResourceLoadedCount; } unsigned int GetResourceFailedCount() { return m_uiResourceFailedCount; } void OnPlayerJoin(CPlayer& Player); + void OnPlayerQuit(CPlayer& Player); const char* GetResourceDirectory(); diff --git a/Server/mods/deathmatch/logic/CResourceMapItem.cpp b/Server/mods/deathmatch/logic/CResourceMapItem.cpp index 92523d2a2ab..28100fc0143 100644 --- a/Server/mods/deathmatch/logic/CResourceMapItem.cpp +++ b/Server/mods/deathmatch/logic/CResourceMapItem.cpp @@ -45,7 +45,7 @@ CResourceMapItem::CResourceMapItem(CResource* pResource, const char* szShortName m_pWaterManager = g_pGame->GetWaterManager(); m_pEvents = g_pGame->GetEvents(); m_pElementGroup = nullptr; - m_iDimension = iDimension; + m_dimension = static_cast(iDimension); m_type = RESOURCE_FILE_TYPE_MAP; m_pMapElement = nullptr; } @@ -192,15 +192,6 @@ void CResourceMapItem::HandleNode(CXMLNode& Node, CElement* pParent) } case CElement::BUILDING: { - const CMtaVersion& minClientVersion = m_resource->GetMinClientFromMetaXml(); - - if (minClientVersion < CMtaVersion(SERVERSIDE_BUILDING_MIN_CLIENT_VERSION)) - { - CLogger::LogPrintf("Resource %s should have client min_mta_version higher or equal than %s\n", m_resource->GetName().c_str(), - SERVERSIDE_BUILDING_MIN_CLIENT_VERSION); - break; - } - pNode = m_pBuildingManager->CreateFromXML(pParent, Node, m_pEvents); break; } @@ -217,7 +208,15 @@ void CResourceMapItem::HandleNode(CXMLNode& Node, CElement* pParent) pNode->SetTypeName(strTagName); if (!pNode->GetDimension()) - pNode->SetDimension(m_iDimension); + { + int iDimension = m_dimension; + if (iDimension < 0) + iDimension = 0; + else if (iDimension > 0xFFFF) + iDimension = 0xFFFF; + + pNode->SetDimension(static_cast(iDimension)); + } if (m_pElementGroup) m_pElementGroup->Add(pNode); diff --git a/Server/mods/deathmatch/logic/CResourceMapItem.h b/Server/mods/deathmatch/logic/CResourceMapItem.h index 86591fbb4d8..9545e767998 100644 --- a/Server/mods/deathmatch/logic/CResourceMapItem.h +++ b/Server/mods/deathmatch/logic/CResourceMapItem.h @@ -70,5 +70,5 @@ class CResourceMapItem : public CResourceFile CEvents* m_pEvents; CDummy* m_pMapElement; CElementGroup* m_pElementGroup; - int m_iDimension; + unsigned short m_dimension; }; diff --git a/Server/mods/deathmatch/logic/CScriptDebugging.cpp b/Server/mods/deathmatch/logic/CScriptDebugging.cpp index 4a991521b93..813b1d90785 100644 --- a/Server/mods/deathmatch/logic/CScriptDebugging.cpp +++ b/Server/mods/deathmatch/logic/CScriptDebugging.cpp @@ -148,7 +148,8 @@ void CScriptDebugging::Broadcast(const CPacket& Packet, unsigned int uiMinimumDe // Tell everyone we log to about it for (const auto& pPlayer : m_Players) { - bool sufficientDebugLevel = CheckForSufficientDebugLevel(pPlayer->m_uiScriptDebugLevel, uiMinimumDebugLevel); + bool sufficientDebugLevel = + CheckForSufficientDebugLevel(static_cast(pPlayer->m_uiScriptDebugLevel), static_cast(uiMinimumDebugLevel)); if (sufficientDebugLevel) { diff --git a/Server/mods/deathmatch/logic/CScriptFile.h b/Server/mods/deathmatch/logic/CScriptFile.h index fbe1a6ff9fa..c9b03ebe6c3 100644 --- a/Server/mods/deathmatch/logic/CScriptFile.h +++ b/Server/mods/deathmatch/logic/CScriptFile.h @@ -32,7 +32,7 @@ class CScriptFile final : public CElement ~CScriptFile(); // Functions required by CElement - void Unlink(){}; + void Unlink() {}; // Load and unload routines bool Load(CResource* pResourceForFilePath, eMode Mode); diff --git a/Server/mods/deathmatch/logic/CSettings.cpp b/Server/mods/deathmatch/logic/CSettings.cpp index 00e1fe11e41..9f6f049c10c 100644 --- a/Server/mods/deathmatch/logic/CSettings.cpp +++ b/Server/mods/deathmatch/logic/CSettings.cpp @@ -16,7 +16,7 @@ #include "CGame.h" #include "CMapManager.h" -#define ERROR_BUFFER 32 +#define ERROR_BUFFER 32 CSettings::CSettings(CResourceManager* pResourceManager) { @@ -85,7 +85,7 @@ CXMLNode* CSettings::Get(CXMLNode* pSource, CXMLNode* pStorage, const char* szSo // Get the resource name from the specified setting if (!GetResourceName(szSetting, szQueryResource, MAX_RESOURCE_LENGTH - 1)) - { // (something): No resource specified, so use the local resource name + { // (something): No resource specified, so use the local resource name strncpy(szQueryResource, szLocalResource, MAX_RESOURCE_LENGTH - 1); } else @@ -169,7 +169,7 @@ CXMLNode* CSettings::Get(CXMLNode* pSource, CXMLNode* pStorage, const char* szSo } } else if (stricmp(szName, szQueryName) == 0 && stricmp(szResource, szQueryResource) == 0) - { // If the query name/resource and found node name/resource combinations are equal + { // If the query name/resource and found node name/resource combinations are equal eStatus = (stricmp(szResource, szLocalResource) == 0 || eAccess != CSettings::Private) ? Found : NoAccess; return pNode; } @@ -239,9 +239,9 @@ CXMLNode* CSettings::Get(const char* szLocalResource, const char* szSetting, boo // See if we found a matching setting if (eStatus == Found) - return pNode; // Found + return pNode; // Found else if (eStatus == NotFound) - { // Not found, continue searching + { // Not found, continue searching // Try to get the value for the appropriate setting from the resource's meta XML file if (pSource) pNode = Get(pSource, pStorage, pResource->GetName().c_str(), szLocalResource, szSetting, bDeleteNode, eStatus); @@ -257,7 +257,7 @@ CXMLNode* CSettings::Get(const char* szLocalResource, const char* szSetting, boo return pNode; } - return NULL; // No access or no settings found + return NULL; // No access or no settings found } // Creates a new setting and adds it to the destination node @@ -306,13 +306,13 @@ bool CSettings::Set(const char* szLocalResource, const char* szSetting, const ch // Check whether the setting exists in the settings registry pNode = Get(m_pNodeGlobalSettings, NULL, "", szLocalResource, szSetting, bDeleteNode, eStatus); - bExists = true; // Default value + bExists = true; // Default value // Try to get the value for the appropriate setting from the resource's meta XML file if (eStatus == NotFound && pSource) { pNode = Get(pSource, NULL, pResource->GetName().c_str(), szLocalResource, szSetting, bDeleteNode, eStatus); - bExists = false; // There's no node in the settings registry, so we create one + bExists = false; // There's no node in the settings registry, so we create one } // See if we have access @@ -340,11 +340,11 @@ bool CSettings::Set(const char* szLocalResource, const char* szSetting, const ch } if (!bExists || !pNode) - { // No existing settings registry entry, so create a new setting + { // No existing settings registry entry, so create a new setting CreateSetting(m_pNodeGlobalSettings, szBuffer, szContent); } else - { // Existing settings registry entry + { // Existing settings registry entry // Get the attributes pAttributes = &(pNode->GetAttributes()); @@ -392,13 +392,13 @@ bool CSettings::HasPrefix(char cCharacter) { switch (cCharacter) { - case SETTINGS_PREFIX_PRIVATE: // Private variable + case SETTINGS_PREFIX_PRIVATE: // Private variable return true; - case SETTINGS_PREFIX_PUBLIC: // Public variable + case SETTINGS_PREFIX_PUBLIC: // Public variable return true; - case SETTINGS_PREFIX_PROTECTED: // Protected variable + case SETTINGS_PREFIX_PROTECTED: // Protected variable return true; - default: // No variable + default: // No variable return false; } } @@ -408,13 +408,13 @@ CSettings::AccessType CSettings::GetAccessType(char cCharacter) { switch (cCharacter) { - case SETTINGS_PREFIX_PRIVATE: // Private variable + case SETTINGS_PREFIX_PRIVATE: // Private variable return CSettings::Private; - case SETTINGS_PREFIX_PUBLIC: // Public variable + case SETTINGS_PREFIX_PUBLIC: // Public variable return CSettings::Public; - case SETTINGS_PREFIX_PROTECTED: // Protected variable + case SETTINGS_PREFIX_PROTECTED: // Protected variable return CSettings::Protected; - default: // Default variable (as declared in SETTINGS_NO_PREFIX) + default: // Default variable (as declared in SETTINGS_NO_PREFIX) return SETTINGS_NO_PREFIX; } } @@ -424,7 +424,7 @@ inline const char* CSettings::GetResourceName(const char* szSetting, char* szBuf { const char* szChr = strchr(szSetting, SETTINGS_DELIMITER); if (szChr == NULL) - return NULL; // Not found? Return NULL, because there's no resource name. + return NULL; // Not found? Return NULL, because there's no resource name. // Strip off the prefix, if any if (HasPrefix(szSetting[0])) diff --git a/Server/mods/deathmatch/logic/CSpatialDatabase.cpp b/Server/mods/deathmatch/logic/CSpatialDatabase.cpp index fcf920d0ebe..affe883bd87 100644 --- a/Server/mods/deathmatch/logic/CSpatialDatabase.cpp +++ b/Server/mods/deathmatch/logic/CSpatialDatabase.cpp @@ -211,7 +211,7 @@ bool CSpatialDatabaseImpl::IsValidSphere(const CSphere& sphere) return false; // Check radius within limits - if (sphere.fRadius < -12000 || sphere.fRadius > 12000) // radius = sqrt(worldlimits*worldlimits + worldlimits*worldlimits) + if (sphere.fRadius < -12000 || sphere.fRadius > 12000) // radius = sqrt(worldlimits*worldlimits + worldlimits*worldlimits) return false; // Check position within limits diff --git a/Server/mods/deathmatch/logic/CSpatialDatabase.h b/Server/mods/deathmatch/logic/CSpatialDatabase.h index a268b17828a..6e64738f341 100644 --- a/Server/mods/deathmatch/logic/CSpatialDatabase.h +++ b/Server/mods/deathmatch/logic/CSpatialDatabase.h @@ -13,7 +13,7 @@ class CElement; #pragma once // Bounding sphere z position for 2d objects -#define SPATIAL_2D_Z 0 +#define SPATIAL_2D_Z 0 // Result of a Query class CElementResult : public std::vector diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 0620c1d6165..d91d9033226 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -23,6 +23,7 @@ #include "CWater.h" #include "CBuilding.h" #include "CPlayerCamera.h" +#include #include "CElementDeleter.h" #include "CMainConfig.h" #include "CRegistry.h" @@ -52,6 +53,7 @@ #include "CVehicleNames.h" #include "CUnoccupiedVehicleSync.h" #include "Utils.h" +#include "CameraScriptShared.h" #include "lua/CLuaFunctionParseHelpers.h" #include "packets/CLuaPacket.h" #include "packets/CElementRPCPacket.h" @@ -66,6 +68,7 @@ #include "packets/CConsoleEchoPacket.h" #include "packets/CChatClearPacket.h" #include "packets/CElementRPCPacket.h" +#include "packets/CVehicleInOutPacket.h" #include "version.h" #include @@ -80,28 +83,28 @@ extern CGame* g_pGame; extern CTimeUsMarker<20> markerLatentEvent; -static CLuaManager* m_pLuaManager; -static CColManager* m_pColManager; -static CPickupManager* m_pPickupManager; -static CPlayerManager* m_pPlayerManager; -static CVehicleManager* m_pVehicleManager; -static CObjectManager* m_pObjectManager; -static CMarkerManager* m_pMarkerManager; -static CMapManager* m_pMapManager; -static CBlipManager* m_pBlipManager; -static CRadarAreaManager* m_pRadarAreaManager; -static CTeamManager* m_pTeamManager; -static CClock* m_pClock; -static CEvents* m_pEvents; -static CElementDeleter* m_pElementDeleter; -static CMainConfig* m_pMainConfig; -static CRegistry* m_pRegistry; -static CAccountManager* m_pAccountManager; -static CBanManager* m_pBanManager; -static CPedManager* m_pPedManager; -static CWaterManager* m_pWaterManager; -static CCustomWeaponManager* m_pCustomWeaponManager; -static CHandlingManager* m_pHandlingManager; +static CLuaManager* m_pLuaManager; +static CColManager* m_pColManager; +static CPickupManager* m_pPickupManager; +static CPlayerManager* m_pPlayerManager; +static CVehicleManager* m_pVehicleManager; +static CObjectManager* m_pObjectManager; +static CMarkerManager* m_pMarkerManager; +static CMapManager* m_pMapManager; +static CBlipManager* m_pBlipManager; +static CRadarAreaManager* m_pRadarAreaManager; +static CTeamManager* m_pTeamManager; +static CClock* m_pClock; +static CEvents* m_pEvents; +static CElementDeleter* m_pElementDeleter; +static CMainConfig* m_pMainConfig; +static CRegistry* m_pRegistry; +static CAccountManager* m_pAccountManager; +static CBanManager* m_pBanManager; +static CPedManager* m_pPedManager; +static CWaterManager* m_pWaterManager; +static CCustomWeaponManager* m_pCustomWeaponManager; +static CHandlingManager* m_pHandlingManager; // Used to run a function on all the children of the elements too #define RUN_CHILDREN(func) \ @@ -331,24 +334,25 @@ bool CStaticFunctionDefinitions::DestroyElement(CElement* pElement) // We can't destroy the root or a player/remote client/console int iType = pElement->GetType(); - if (pElement == m_pMapManager->GetRootElement() || iType == CElement::PLAYER || iType == CElement::CONSOLE || + if (pElement == m_pMapManager->GetRootElement() || iType == CElement::PLAYER || iType == CElement::CONSOLE || g_pGame->GetResourceManager()->IsAResourceElement(pElement)) { return false; } - if (iType == CElement::TEAM) { // Its team trigger onPlayerTeamChange for each player in the team + if (iType == CElement::TEAM) + { // Its team trigger onPlayerTeamChange for each player in the team CTeam* pTeam = static_cast(pElement); - auto iterBegin = pTeam->PlayersBegin(); - auto iterEnd = pTeam->PlayersEnd(); + auto iterBegin = pTeam->PlayersBegin(); + auto iterEnd = pTeam->PlayersEnd(); CLuaArguments arguments; for (auto iter = iterBegin; iter != iterEnd; ++iter) { CPlayer* player = *iter; - arguments.PushElement(pTeam); // Return team element as oldteam - arguments.PushNil(); // No new team return nil + arguments.PushElement(pTeam); // Return team element as oldteam + arguments.PushNil(); // No new team return nil player->CallEvent("onPlayerTeamChange", arguments); arguments.DeleteArguments(); } @@ -360,7 +364,7 @@ bool CStaticFunctionDefinitions::DestroyElement(CElement* pElement) // Unsync it (will destroy it for those that know about it) CPerPlayerEntity* pEntity = static_cast(pElement); pEntity->Sync(false); - } + } // Tell everyone to destroy it CEntityRemovePacket Packet; @@ -478,13 +482,13 @@ CElement* CStaticFunctionDefinitions::GetElementByIndex(const char* szType, unsi return m_pMapManager->GetRootElement()->FindChildByType(szType, uiIndex, true); } -CLuaArgument* CStaticFunctionDefinitions::GetElementData(CElement* pElement, const char* szName, bool bInherit) +CLuaArgument* CStaticFunctionDefinitions::GetElementData(CElement* pElement, CStringName name, bool bInherit) { assert(pElement); - assert(szName); + assert(name); // Return its custom data - return pElement->GetCustomData(szName, bInherit); + return pElement->GetCustomData(name, bInherit); } CLuaArguments* CStaticFunctionDefinitions::GetAllElementData(CElement* pElement, CLuaArguments* table) @@ -998,71 +1002,73 @@ bool CStaticFunctionDefinitions::SetElementID(CElement* pElement, const char* sz return true; } -bool CStaticFunctionDefinitions::SetElementData(CElement* pElement, const char* szName, const CLuaArgument& Variable, ESyncType syncType, +bool CStaticFunctionDefinitions::SetElementData(CElement* pElement, CStringName name, const CLuaArgument& Variable, ESyncType syncType, std::optional clientTrust) { assert(pElement); - assert(szName); - assert(strlen(szName) <= MAX_CUSTOMDATA_NAME_LENGTH); + assert(name); + assert(name->length() <= MAX_CUSTOMDATA_NAME_LENGTH); ESyncType lastSyncType = ESyncType::BROADCAST; eCustomDataClientTrust lastClientTrust{}; - CLuaArgument* pCurrentVariable = pElement->GetCustomData(szName, false, &lastSyncType, &lastClientTrust); + CLuaArgument* pCurrentVariable = pElement->GetCustomData(name, false, &lastSyncType, &lastClientTrust); if (clientTrust.has_value() && lastClientTrust != clientTrust.value()) - pElement->GetCustomDataManager().SetClientChangesMode(szName, clientTrust.value()); + pElement->GetCustomDataManager().SetClientChangesMode(name, clientTrust.value()); if (!pCurrentVariable || *pCurrentVariable != Variable || lastSyncType != syncType) { + if (!pElement->SetCustomData(name, Variable, syncType)) + return false; // The server cancelled the change in onElementDataChange + if (syncType != ESyncType::LOCAL) { // Tell our clients to update their data - unsigned short usNameLength = static_cast(strlen(szName)); + unsigned short usNameLength = static_cast(name->length()); CBitStream BitStream; BitStream.pBitStream->WriteCompressed(usNameLength); - BitStream.pBitStream->Write(szName, usNameLength); + BitStream.pBitStream->Write(name.ToCString(), usNameLength); Variable.WriteToBitStream(*BitStream.pBitStream); const CElementRPCPacket packet(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream); const size_t numPlayers = syncType == ESyncType::BROADCAST ? m_pPlayerManager->BroadcastOnlyJoined(packet) - : m_pPlayerManager->BroadcastOnlySubscribed(packet, pElement, szName); + : m_pPlayerManager->BroadcastOnlySubscribed(packet, pElement, name.ToCString()); - CPerfStatEventPacketUsage::GetSingleton()->UpdateElementDataUsageOut(szName, numPlayers, BitStream.pBitStream->GetNumberOfBytesUsed()); + CPerfStatEventPacketUsage::GetSingleton()->UpdateElementDataUsageOut(name.ToCString(), numPlayers, BitStream.pBitStream->GetNumberOfBytesUsed()); } // Unsubscribe all the players if (lastSyncType == ESyncType::SUBSCRIBE && syncType != ESyncType::SUBSCRIBE) - m_pPlayerManager->ClearElementData(pElement, szName); + m_pPlayerManager->ClearElementData(pElement, name); - // Set its custom data - pElement->SetCustomData(szName, Variable, syncType); return true; } return false; } -bool CStaticFunctionDefinitions::RemoveElementData(CElement* pElement, const char* szName) +bool CStaticFunctionDefinitions::RemoveElementData(CElement* pElement, CStringName name) { assert(pElement); - assert(szName); - assert(strlen(szName) <= MAX_CUSTOMDATA_NAME_LENGTH); + assert(name); + assert(name->length() <= MAX_CUSTOMDATA_NAME_LENGTH); // Check it exists - if (pElement->GetCustomData(szName, false)) + if (pElement->GetCustomData(name, false)) { + if (!pElement->DeleteCustomData(name)) + return false; // The server cancelled the change in onElementDataChange + // Tell our clients to update their data - unsigned short usNameLength = static_cast(strlen(szName)); + unsigned short usNameLength = static_cast(name->length()); CBitStream BitStream; BitStream.pBitStream->WriteCompressed(usNameLength); - BitStream.pBitStream->Write(szName, usNameLength); - BitStream.pBitStream->WriteBit(false); // Unused (was recursive flag) + BitStream.pBitStream->Write(name.ToCString(), usNameLength); + BitStream.pBitStream->WriteBit(false); // Unused (was recursive flag) m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pElement, REMOVE_ELEMENT_DATA, *BitStream.pBitStream)); // Clean up after the data removal - m_pPlayerManager->ClearElementData(pElement, szName); + m_pPlayerManager->ClearElementData(pElement, name); - // Delete here - pElement->DeleteCustomData(szName); return true; } @@ -1070,30 +1076,30 @@ bool CStaticFunctionDefinitions::RemoveElementData(CElement* pElement, const cha return false; } -bool CStaticFunctionDefinitions::AddElementDataSubscriber(CElement* pElement, const char* szName, CPlayer* pPlayer) +bool CStaticFunctionDefinitions::AddElementDataSubscriber(CElement* pElement, CStringName name, CPlayer* pPlayer) { assert(pElement); - assert(szName); + assert(name); assert(pPlayer); ESyncType lastSyncType = ESyncType::LOCAL; - CLuaArgument* pCurrentVariable = pElement->GetCustomData(szName, false, &lastSyncType); + CLuaArgument* pCurrentVariable = pElement->GetCustomData(name, false, &lastSyncType); if (pCurrentVariable != nullptr && lastSyncType == ESyncType::SUBSCRIBE) { - if (!pPlayer->SubscribeElementData(pElement, szName)) + if (!pPlayer->SubscribeElementData(pElement, name)) return false; // Tell our clients to update their data - unsigned short usNameLength = static_cast(strlen(szName)); + unsigned short usNameLength = static_cast(name->length()); CBitStream BitStream; BitStream.pBitStream->WriteCompressed(usNameLength); - BitStream.pBitStream->Write(szName, usNameLength); + BitStream.pBitStream->Write(name.ToCString(), usNameLength); pCurrentVariable->WriteToBitStream(*BitStream.pBitStream); pPlayer->Send(CElementRPCPacket(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream)); - CPerfStatEventPacketUsage::GetSingleton()->UpdateElementDataUsageOut(szName, 1, BitStream.pBitStream->GetNumberOfBytesUsed()); + CPerfStatEventPacketUsage::GetSingleton()->UpdateElementDataUsageOut(name.ToCString(), 1, BitStream.pBitStream->GetNumberOfBytesUsed()); return true; } @@ -1101,22 +1107,22 @@ bool CStaticFunctionDefinitions::AddElementDataSubscriber(CElement* pElement, co return false; } -bool CStaticFunctionDefinitions::RemoveElementDataSubscriber(CElement* pElement, const char* szName, CPlayer* pPlayer) +bool CStaticFunctionDefinitions::RemoveElementDataSubscriber(CElement* pElement, CStringName name, CPlayer* pPlayer) { assert(pElement); - assert(szName); + assert(name); assert(pPlayer); - return pPlayer->UnsubscribeElementData(pElement, szName); + return pPlayer->UnsubscribeElementData(pElement, name); } -bool CStaticFunctionDefinitions::HasElementDataSubscriber(CElement* pElement, const char* szName, CPlayer* pPlayer) +bool CStaticFunctionDefinitions::HasElementDataSubscriber(CElement* pElement, CStringName name, CPlayer* pPlayer) { assert(pElement); - assert(szName); + assert(name); assert(pPlayer); - return pPlayer->IsSubscribed(pElement, szName); + return pPlayer->IsSubscribed(pElement, name); } bool CStaticFunctionDefinitions::SetElementParent(CElement* pElement, CElement* pParent) @@ -1132,7 +1138,7 @@ bool CStaticFunctionDefinitions::SetElementParent(CElement* pElement, CElement* const char* szTypeName = pTemp->GetTypeName().c_str(); if (szTypeName && strcmp(szTypeName, "map") == 0) { - bValidParent = true; // parents must be a map + bValidParent = true; // parents must be a map break; } @@ -1186,7 +1192,7 @@ bool CStaticFunctionDefinitions::GetElementRotation(CElement* pElement, CVector& case CElement::PLAYER: { CPed* pPed = static_cast(pElement); - vecRotation.fZ = ConvertRadiansToDegrees(pPed->GetRotation()); // No conversion since only Z is used + vecRotation.fZ = ConvertRadiansToDegrees(pPed->GetRotation()); // No conversion since only Z is used break; } @@ -1299,7 +1305,7 @@ bool CStaticFunctionDefinitions::SetElementPosition(CElement* pElement, const CV assert(pElement); RUN_CHILDREN(SetElementPosition(*iter, vecPosition, bWarp)) - if (IS_PLAYER(pElement)) + if (IS_PLAYER(pElement)) { CPlayer* player = static_cast(pElement); player->SetTeleported(true); @@ -1354,7 +1360,7 @@ bool CStaticFunctionDefinitions::SetElementRotation(CElement* pElement, const CV case CElement::PLAYER: { CPed* pPed = static_cast(pElement); - SetPedRotation(pPed, vecRotation.fZ, bNewWay); // No rotation order conversion required since only Z is used + SetPedRotation(pPed, vecRotation.fZ, bNewWay); // No rotation order conversion required since only Z is used break; } @@ -1598,27 +1604,53 @@ bool CStaticFunctionDefinitions::AttachElements(CElement* pElement, CElement* pA assert(pElement); assert(pAttachedToElement); - if (pElement->IsAttachToable() && pAttachedToElement->IsAttachable() && !pAttachedToElement->IsAttachedToElement(pElement) && - pElement->GetDimension() == pAttachedToElement->GetDimension()) + if (!pElement->IsAttachToable() || !pAttachedToElement->IsAttachable() || pAttachedToElement->IsAttachedToElement(pElement) || + pElement->GetDimension() != pAttachedToElement->GetDimension()) { - pElement->SetAttachedOffsets(vecPosition, vecRotation); - ConvertDegreesToRadians(vecRotation); - pElement->AttachTo(pAttachedToElement); + return false; + } - CBitStream BitStream; - BitStream.pBitStream->Write(pAttachedToElement->GetID()); - BitStream.pBitStream->Write(vecPosition.fX); - BitStream.pBitStream->Write(vecPosition.fY); - BitStream.pBitStream->Write(vecPosition.fZ); - BitStream.pBitStream->Write(vecRotation.fX); - BitStream.pBitStream->Write(vecRotation.fY); - BitStream.pBitStream->Write(vecRotation.fZ); - m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pElement, ATTACH_ELEMENTS, *BitStream.pBitStream)); + CLuaArguments Arguments; + Arguments.PushElement(pAttachedToElement); + Arguments.PushNumber(vecPosition.fX); + Arguments.PushNumber(vecPosition.fY); + Arguments.PushNumber(vecPosition.fZ); + Arguments.PushNumber(vecRotation.fX); + Arguments.PushNumber(vecRotation.fY); + Arguments.PushNumber(vecRotation.fZ); - return true; + if (!pElement->CallEvent("onElementAttach", Arguments)) + { + return false; } - return false; + pElement->SetAttachedOffsets(vecPosition, vecRotation); + ConvertDegreesToRadians(vecRotation); + pElement->AttachTo(pAttachedToElement); + + if (IS_MARKER(pElement)) + { + CMarker* pMarker = static_cast(pElement); + CVector attachedPosition; + pMarker->GetAttachedPosition(attachedPosition); + pMarker->SetPosition(attachedPosition); + + CColShape* pColShape = pMarker->GetColShape(); + if (pColShape) + RefreshColShapeColliders(pColShape); + } + + CBitStream BitStream; + BitStream.pBitStream->Write(pAttachedToElement->GetID()); + BitStream.pBitStream->Write(vecPosition.fX); + BitStream.pBitStream->Write(vecPosition.fY); + BitStream.pBitStream->Write(vecPosition.fZ); + BitStream.pBitStream->Write(vecRotation.fX); + BitStream.pBitStream->Write(vecRotation.fY); + BitStream.pBitStream->Write(vecRotation.fZ); + m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pElement, ATTACH_ELEMENTS, *BitStream.pBitStream)); + + return true; } bool CStaticFunctionDefinitions::DetachElements(CElement* pElement, CElement* pAttachedToElement) @@ -1626,28 +1658,55 @@ bool CStaticFunctionDefinitions::DetachElements(CElement* pElement, CElement* pA assert(pElement); CElement* pActualAttachedToElement = pElement->GetAttachedToElement(); - if (pActualAttachedToElement) + if (!pActualAttachedToElement || (pAttachedToElement && pActualAttachedToElement != pAttachedToElement)) { - if (pAttachedToElement == NULL || pActualAttachedToElement == pAttachedToElement) - { - // Detach it. Also generate a new time context to prevent sync screwup from - // old packes arriving. - CVector vecPosition = pElement->GetPosition(); - pElement->AttachTo(NULL); - pElement->GenerateSyncTimeContext(); + return false; + } - CBitStream BitStream; - BitStream.pBitStream->Write(pElement->GetSyncTimeContext()); - BitStream.pBitStream->Write(vecPosition.fX); - BitStream.pBitStream->Write(vecPosition.fY); - BitStream.pBitStream->Write(vecPosition.fZ); - m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pElement, DETACH_ELEMENTS, *BitStream.pBitStream)); + CVector vecPosition = pElement->GetPosition(); + CVector vecRotation; - return true; - } + pElement->GetRotation(vecRotation); + ConvertRadiansToDegrees(vecRotation); + + CLuaArguments Arguments; + Arguments.PushElement(pActualAttachedToElement); + Arguments.PushNumber(vecPosition.fX); + Arguments.PushNumber(vecPosition.fY); + Arguments.PushNumber(vecPosition.fZ); + Arguments.PushNumber(vecRotation.fX); + Arguments.PushNumber(vecRotation.fY); + Arguments.PushNumber(vecRotation.fZ); + + if (!pElement->CallEvent("onElementDetach", Arguments)) + { + return false; } - return false; + // Detach it. Also generate a new time context to prevent sync screwup from + // old packets arriving. + pElement->AttachTo(NULL); + pElement->GenerateSyncTimeContext(); + + if (IS_MARKER(pElement)) + { + CMarker* pMarker = static_cast(pElement); + CColShape* pColShape = pMarker->GetColShape(); + if (pColShape) + RefreshColShapeColliders(pColShape); + } + + CBitStream BitStream; + BitStream.pBitStream->Write(pElement->GetSyncTimeContext()); + BitStream.pBitStream->Write(vecPosition.fX); + BitStream.pBitStream->Write(vecPosition.fY); + BitStream.pBitStream->Write(vecPosition.fZ); + BitStream.pBitStream->Write(vecRotation.fX); + BitStream.pBitStream->Write(vecRotation.fY); + BitStream.pBitStream->Write(vecRotation.fZ); + m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pElement, DETACH_ELEMENTS, *BitStream.pBitStream)); + + return true; } bool CStaticFunctionDefinitions::SetElementAlpha(CElement* pElement, unsigned char ucAlpha) @@ -1728,6 +1787,8 @@ bool CStaticFunctionDefinitions::SetElementHealth(CElement* pElement, float fHea if (pPed->IsDead() && fHealth > 0.0f) pPed->SetIsDead(false); + else if (fHealth <= 0.0f && !pPed->IsDead()) + KillPed(pElement, nullptr, 0xFF, 0xFF, false); break; } @@ -1770,11 +1831,11 @@ bool CStaticFunctionDefinitions::SetElementModel(CElement* pElement, unsigned sh return false; if (!CPlayerManager::IsValidPlayerModel(usModel)) return false; - unsigned short usOldModel = pPed->GetModel(); // Get the old model + unsigned short usOldModel = pPed->GetModel(); // Get the old model CLuaArguments Arguments; Arguments.PushNumber(usOldModel); - pPed->SetModel(usModel); // Set the new model - Arguments.PushNumber(usModel); // Get the new model + pPed->SetModel(usModel); // Set the new model + Arguments.PushNumber(usModel); // Get the new model bool bContinue = pPed->CallEvent("onElementModelChange", Arguments); // Check for another call to setElementModel if (usModel != pPed->GetModel()) @@ -1795,11 +1856,11 @@ bool CStaticFunctionDefinitions::SetElementModel(CElement* pElement, unsigned sh return false; if (!CVehicleManager::IsValidModel(usModel)) return false; - unsigned short usOldModel = pVehicle->GetModel(); // Get the old model + unsigned short usOldModel = pVehicle->GetModel(); // Get the old model CLuaArguments Arguments; Arguments.PushNumber(usOldModel); - pVehicle->SetModel(usModel); // Set the new model - Arguments.PushNumber(usModel); // Get the new model + pVehicle->SetModel(usModel); // Set the new model + Arguments.PushNumber(usModel); // Get the new model bool bContinue = pVehicle->CallEvent("onElementModelChange", Arguments); // Check for another call to setElementModel if (usModel != pVehicle->GetModel()) @@ -1838,11 +1899,11 @@ bool CStaticFunctionDefinitions::SetElementModel(CElement* pElement, unsigned sh return false; if (!CObjectManager::IsValidModel(usModel)) return false; - unsigned short usOldModel = pObject->GetModel(); // Get the old model + unsigned short usOldModel = pObject->GetModel(); // Get the old model CLuaArguments Arguments; Arguments.PushNumber(usOldModel); - pObject->SetModel(usModel); // Set the new model - Arguments.PushNumber(usModel); // Get the new model + pObject->SetModel(usModel); // Set the new model + Arguments.PushNumber(usModel); // Get the new model bool bContinue = pObject->CallEvent("onElementModelChange", Arguments); // Check for another call to setElementModel if (usModel != pObject->GetModel()) @@ -2123,7 +2184,7 @@ bool CStaticFunctionDefinitions::SetPlayerName(CElement* pElement, const char* s CLuaArguments Arguments; Arguments.PushString(szNick); Arguments.PushString(szName); - Arguments.PushBoolean(false); // manually changed + Arguments.PushBoolean(false); // manually changed pPlayer->CallEvent("onPlayerChangeNick", Arguments); // Tell the console @@ -2418,7 +2479,7 @@ bool CStaticFunctionDefinitions::SetWeaponProperty(eWeaponProperty eProperty, eW case WEAPON_DAMAGE: { if (sData >= -10000 && sData <= 10000) - pWeaponInfo->SetDamagePerHit(sData); + pWeaponInfo->SetDamagePerHit(static_cast(sData)); else return false; break; @@ -2426,7 +2487,7 @@ bool CStaticFunctionDefinitions::SetWeaponProperty(eWeaponProperty eProperty, eW case WEAPON_MAX_CLIP_AMMO: { if (sData >= 0 && sData <= 1000) - pWeaponInfo->SetMaximumClipAmmo(sData); + pWeaponInfo->SetMaximumClipAmmo(static_cast(sData)); else return false; break; @@ -2450,7 +2511,7 @@ bool CStaticFunctionDefinitions::SetWeaponProperty(eWeaponProperty eProperty, eW BitStream.pBitStream->Write(static_cast(eProperty)); BitStream.pBitStream->Write(static_cast(eSkillLevel)); if (eProperty == WEAPON_FLAGS) - BitStream.pBitStream->Write(sData); // Backward compat because sent little end first + BitStream.pBitStream->Write(sData); // Backward compat because sent little end first else BitStream.pBitStream->Write((short)sData); m_pPlayerManager->BroadcastOnlyJoined(CLuaPacket(SET_WEAPON_PROPERTY, *BitStream.pBitStream)); @@ -3092,18 +3153,14 @@ const std::string& CStaticFunctionDefinitions::GetPlayerSerial(CPlayer* pPlayer, return pPlayer->GetSerial(uiIndex); } -const std::string& CStaticFunctionDefinitions::GetPlayerUserName(CPlayer* pPlayer) +std::string CStaticFunctionDefinitions::GetPlayerUserName(CPlayer* pPlayer) { - assert(pPlayer); - - return pPlayer->GetSerialUser(); + return ""; } -const std::string& CStaticFunctionDefinitions::GetPlayerCommunityID(CPlayer* pPlayer) +std::string CStaticFunctionDefinitions::GetPlayerCommunityID(CPlayer* pPlayer) { - assert(pPlayer); - - return pPlayer->GetCommunityID(); + return ""; } bool CStaticFunctionDefinitions::GetPlayerBlurLevel(CPlayer* pPlayer, unsigned char& ucLevel) @@ -3269,10 +3326,7 @@ bool CStaticFunctionDefinitions::TakePlayerScreenShot(CElement* pElement, uint u BitStream.pBitStream->Write(static_cast(uiQuality)); BitStream.pBitStream->Write(uiMaxBandwidth); BitStream.pBitStream->Write(static_cast(uiMaxPacketSize)); - if (BitStream.pBitStream->Version() >= 0x53) - BitStream.pBitStream->Write(pResource->GetNetID()); - else - BitStream.pBitStream->WriteString(pResource->GetName()); + BitStream.pBitStream->Write(pResource->GetNetID()); BitStream.pBitStream->Write(GetTickCount32()); pPlayer->Send(CLuaPacket(TAKE_PLAYER_SCREEN_SHOT, *BitStream.pBitStream)); @@ -3312,7 +3366,7 @@ bool CStaticFunctionDefinitions::SetPlayerScriptDebugLevel(CElement* pElement, u { CPlayer* pPlayer = static_cast(pElement); - if (pPlayer->SetScriptDebugLevel(uiLevel)) + if (pPlayer->SetScriptDebugLevel(static_cast(uiLevel))) return SetPlayerDebuggerVisible(pElement, uiLevel != 0); } } @@ -3827,7 +3881,7 @@ bool CStaticFunctionDefinitions::KillPed(CElement* pElement, CElement* pKiller, pPed->CallEvent("onPedWasted", Arguments); } - for (unsigned int slot = 0; slot < WEAPON_SLOTS; ++slot) + for (unsigned char slot = 0; slot < WEAPON_SLOTS; ++slot) { pPed->SetWeaponType(0, slot); pPed->SetWeaponAmmoInClip(0, slot); @@ -4226,6 +4280,10 @@ bool CStaticFunctionDefinitions::WarpPedIntoVehicle(CPed* pPed, CVehicle* pVehic if (uiSeat > 0 && pVehicle->GetMaxPassengers() == VEHICLE_PASSENGERS_UNDEFINED) return false; + // Camper only has 3 seats (0-2) + if (pVehicle->GetModel() == VT_CAMPER && uiSeat > 2) + return false; + // Valid seat id for that vehicle? // Temp fix: Disable driver seat for train carriages since the whole vehicle sync logic is based on the the player on the first seat being the vehicle // syncer (Todo) @@ -4274,9 +4332,9 @@ bool CStaticFunctionDefinitions::WarpPedIntoVehicle(CPed* pPed, CVehicle* pVehic // Call the player->vehicle event CLuaArguments PlayerVehicleArguments; - PlayerVehicleArguments.PushElement(pVehicle); // vehicle - PlayerVehicleArguments.PushNumber(uiSeat); // seat - if (pPreviousOccupant) // jacked + PlayerVehicleArguments.PushElement(pVehicle); // vehicle + PlayerVehicleArguments.PushNumber(uiSeat); // seat + if (pPreviousOccupant) // jacked PlayerVehicleArguments.PushElement(pPreviousOccupant); else PlayerVehicleArguments.PushBoolean(false); @@ -4288,9 +4346,9 @@ bool CStaticFunctionDefinitions::WarpPedIntoVehicle(CPed* pPed, CVehicle* pVehic // Call the vehicle->player event CLuaArguments VehiclePlayerArguments; - VehiclePlayerArguments.PushElement(pPed); // player - VehiclePlayerArguments.PushNumber(uiSeat); // seat - if (pPreviousOccupant) // jacked + VehiclePlayerArguments.PushElement(pPed); // player + VehiclePlayerArguments.PushNumber(uiSeat); // seat + if (pPreviousOccupant) // jacked VehiclePlayerArguments.PushElement(pPreviousOccupant); else VehiclePlayerArguments.PushBoolean(false); @@ -4319,15 +4377,37 @@ bool CStaticFunctionDefinitions::RemovePedFromVehicle(CElement* pElement) CPed* pPed = static_cast(pElement); // Grab his occupied vehicle - CVehicle* pVehicle = pPed->GetOccupiedVehicle(); - unsigned char ucOccupiedSeat = pPed->GetOccupiedVehicleSeat(); + CVehicle* pVehicle = pPed->GetOccupiedVehicle(); + auto ucOccupiedSeat = static_cast(pPed->GetOccupiedVehicleSeat()); if (pVehicle) { + unsigned int uiVehicleAction = pPed->GetVehicleAction(); + + // Handle mid-enter/exit states + if (uiVehicleAction == CPed::VEHICLEACTION_ENTERING || uiVehicleAction == CPed::VEHICLEACTION_JACKING) + { + pVehicle->SetOccupant(nullptr, ucOccupiedSeat); + pPed->SetOccupiedVehicle(nullptr, 0); + pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE); + + if (uiVehicleAction == CPed::VEHICLEACTION_JACKING) + pPed->SetJackingVehicle(nullptr); + + // Clean up client handshake + if (IS_PLAYER(pPed)) + { + CVehicleInOutPacket Reply(pPed->GetID(), pVehicle->GetID(), ucOccupiedSeat, CGame::VEHICLE_NOTIFY_IN_ABORT_RETURN); + m_pPlayerManager->BroadcastOnlyJoined(Reply); + } + + return true; + } + CLuaArguments Arguments; - Arguments.PushElement(pVehicle); // vehicle - Arguments.PushNumber(ucOccupiedSeat); // seat - Arguments.PushBoolean(false); // jacker - Arguments.PushBoolean(true); // forcedByScript + Arguments.PushElement(pVehicle); // vehicle + Arguments.PushNumber(ucOccupiedSeat); // seat + Arguments.PushBoolean(false); // jacker + Arguments.PushBoolean(true); // forcedByScript if (IS_PLAYER(pPed)) pPed->CallEvent("onPlayerVehicleExit", Arguments); else @@ -4335,15 +4415,15 @@ bool CStaticFunctionDefinitions::RemovePedFromVehicle(CElement* pElement) // Call the vehicle->ped event CLuaArguments Arguments2; - Arguments2.PushElement(pPed); // player / ped - Arguments2.PushNumber(ucOccupiedSeat); // seat - Arguments2.PushBoolean(false); // jacker - Arguments2.PushBoolean(true); // forcedByScript + Arguments2.PushElement(pPed); // player / ped + Arguments2.PushNumber(ucOccupiedSeat); // seat + Arguments2.PushBoolean(false); // jacker + Arguments2.PushBoolean(true); // forcedByScript pVehicle->CallEvent("onVehicleExit", Arguments2); // Remove him from the vehicle - pVehicle->SetOccupant(NULL, ucOccupiedSeat); - pPed->SetOccupiedVehicle(NULL, 0); + pVehicle->SetOccupant(nullptr, ucOccupiedSeat); + pPed->SetOccupiedVehicle(nullptr, 0); pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE); // Tell the players @@ -4410,7 +4490,8 @@ bool CStaticFunctionDefinitions::SetPedAnimation(CElement* pElement, const SStri pPed->SetChoking(false); // Store anim data - pPed->SetAnimationData(SPlayerAnimData{blockName, animName, iTime, bLoop, bUpdatePosition, bInterruptable, bFreezeLastFrame, iBlend, bTaskToBeRestoredOnAnimEnd, GetTickCount64_()}); + pPed->SetAnimationData(SPlayerAnimData{blockName, animName, iTime, bLoop, bUpdatePosition, bInterruptable, bFreezeLastFrame, iBlend, + bTaskToBeRestoredOnAnimEnd, GetTickCount64_()}); BitStream.pBitStream->WriteString(blockName); BitStream.pBitStream->WriteString(animName); @@ -4553,7 +4634,8 @@ bool CStaticFunctionDefinitions::SetPedFrozen(CElement* pElement, bool bIsFrozen return false; } -bool CStaticFunctionDefinitions::ReloadPedWeapon(CElement* pElement) noexcept { +bool CStaticFunctionDefinitions::ReloadPedWeapon(CElement* pElement) noexcept +{ assert(pElement); RUN_CHILDREN(ReloadPedWeapon(*iter)) @@ -4565,7 +4647,7 @@ bool CStaticFunctionDefinitions::ReloadPedWeapon(CElement* pElement) noexcept { bool result; CLuaArguments arguments; - std::uint8_t weapon = ped->GetWeaponType(); + std::uint8_t weapon = ped->GetWeaponType(); std::uint16_t clip = ped->GetWeaponAmmoInClip(); std::uint16_t ammo = ped->GetWeaponTotalAmmo(); @@ -4594,78 +4676,103 @@ bool CStaticFunctionDefinitions::GetCameraMatrix(CPlayer* pPlayer, CVector& vecP assert(pPlayer); CPlayerCamera* pCamera = pPlayer->GetCamera(); + if (!pCamera) + return false; - // Only allow this if we're in fixed mode? - if (pCamera->GetMode() == CAMERAMODE_FIXED) - { - pCamera->GetPosition(vecPosition); - pCamera->GetLookAt(vecLookAt); - fRoll = pCamera->GetRoll(); - fFOV = pCamera->GetFOV(); - return true; - } - return false; + pCamera->GetPosition(vecPosition); + pCamera->GetLookAt(vecLookAt); + fRoll = pCamera->GetRoll(); + fFOV = pCamera->GetFOV(); + + return true; } CElement* CStaticFunctionDefinitions::GetCameraTarget(CPlayer* pPlayer) { assert(pPlayer); CPlayerCamera* pCamera = pPlayer->GetCamera(); + if (!pCamera) + return nullptr; // Only allow this if we're targeting a player if (pCamera->GetMode() == CAMERAMODE_PLAYER) { return pCamera->GetTarget(); } - return NULL; + return nullptr; } bool CStaticFunctionDefinitions::GetCameraInterior(CPlayer* pPlayer, unsigned char& ucInterior) { assert(pPlayer); - ucInterior = pPlayer->GetCamera()->GetInterior(); + CPlayerCamera* pCamera = pPlayer->GetCamera(); + if (!pCamera) + return false; + + ucInterior = pCamera->GetInterior(); return true; } bool CStaticFunctionDefinitions::SetCameraMatrix(CElement* pElement, const CVector& vecPosition, CVector* pvecLookAt, float fRoll, float fFOV) { assert(pElement); - RUN_CHILDREN(SetCameraMatrix(*iter, vecPosition, pvecLookAt, fRoll, fFOV)) + CVector sanitizedPosition = vecPosition; + if (!CameraScriptShared::IsFiniteVector(sanitizedPosition)) + return false; + + CVector sanitizedLookAt; + CVector* pSanitizedLookAt = nullptr; + if (pvecLookAt) + { + sanitizedLookAt = *pvecLookAt; + if (!CameraScriptShared::IsFiniteVector(sanitizedLookAt)) + return false; + pSanitizedLookAt = &sanitizedLookAt; + } + + const float sanitizedFOV = CameraScriptShared::SanitizeFOV(fFOV); + const float sanitizedRoll = CameraScriptShared::NormalizeRoll(fRoll); + + RUN_CHILDREN(SetCameraMatrix(*iter, sanitizedPosition, pSanitizedLookAt, sanitizedRoll, sanitizedFOV)) if (IS_PLAYER(pElement)) { CPlayer* pPlayer = static_cast(pElement); CPlayerCamera* pCamera = pPlayer->GetCamera(); + if (!pCamera) + return false; pCamera->SetMode(CAMERAMODE_FIXED); - if (pvecLookAt) - pCamera->SetMatrix(vecPosition, *pvecLookAt); + if (pSanitizedLookAt) + pCamera->SetMatrix(sanitizedPosition, *pSanitizedLookAt); else - pCamera->SetPosition(vecPosition); + pCamera->SetPosition(sanitizedPosition); CVector vecLookAt; - if (pvecLookAt) - vecLookAt = *pvecLookAt; + if (pSanitizedLookAt) + vecLookAt = *pSanitizedLookAt; else pCamera->GetLookAt(vecLookAt); - pCamera->SetRoll(fRoll); - pCamera->SetFOV(fFOV); + if (!CameraScriptShared::IsFiniteVector(vecLookAt)) + vecLookAt = sanitizedPosition + CVector(0.0f, 1.0f, 0.0f); + + pCamera->SetRoll(sanitizedRoll); + pCamera->SetFOV(sanitizedFOV); // Tell the player CBitStream BitStream; - if (pPlayer->GetBitStreamVersion() >= 0x5E) - BitStream.pBitStream->Write(pCamera->GenerateSyncTimeContext()); - BitStream.pBitStream->Write(vecPosition.fX); - BitStream.pBitStream->Write(vecPosition.fY); - BitStream.pBitStream->Write(vecPosition.fZ); + BitStream.pBitStream->Write(pCamera->GenerateSyncTimeContext()); + BitStream.pBitStream->Write(sanitizedPosition.fX); + BitStream.pBitStream->Write(sanitizedPosition.fY); + BitStream.pBitStream->Write(sanitizedPosition.fZ); BitStream.pBitStream->Write(vecLookAt.fX); BitStream.pBitStream->Write(vecLookAt.fY); BitStream.pBitStream->Write(vecLookAt.fZ); - if (fRoll != 0.0f || fFOV != 70.0f) + if (sanitizedRoll != 0.0f || sanitizedFOV != CameraScriptShared::kDefaultFOV) { - BitStream.pBitStream->Write(fRoll); - BitStream.pBitStream->Write(fFOV); + BitStream.pBitStream->Write(sanitizedRoll); + BitStream.pBitStream->Write(sanitizedFOV); } pPlayer->Send(CLuaPacket(SET_CAMERA_MATRIX, *BitStream.pBitStream)); @@ -4684,6 +4791,8 @@ bool CStaticFunctionDefinitions::SetCameraTarget(CElement* pElement, CElement* p { CPlayer* pPlayer = static_cast(pElement); CPlayerCamera* pCamera = pPlayer->GetCamera(); + if (!pCamera) + return false; // If we don't have a target, change it to the player if (!pTarget) @@ -4702,8 +4811,7 @@ bool CStaticFunctionDefinitions::SetCameraTarget(CElement* pElement, CElement* p pCamera->SetFOV(70.0f); CBitStream BitStream; - if (pPlayer->GetBitStreamVersion() >= 0x5E) - BitStream.pBitStream->Write(pCamera->GenerateSyncTimeContext()); + BitStream.pBitStream->Write(pCamera->GenerateSyncTimeContext()); BitStream.pBitStream->Write(pTarget->GetID()); pPlayer->Send(CLuaPacket(SET_CAMERA_TARGET, *BitStream.pBitStream)); return true; @@ -4725,6 +4833,8 @@ bool CStaticFunctionDefinitions::SetCameraInterior(CElement* pElement, unsigned { CPlayer* pPlayer = static_cast(pElement); CPlayerCamera* pCamera = pPlayer->GetCamera(); + if (!pCamera) + return false; if (pCamera->GetInterior() != ucInterior) { @@ -4810,14 +4920,14 @@ bool CStaticFunctionDefinitions::GiveWeapon(CElement* pElement, unsigned char uc // Client ammo emulation mode - Try to ensure that the ammo we set on the server will be the same as the client) if (ucWeaponSlot <= 1 || ucWeaponSlot >= 10) - uiTotalAmmo = std::min(1U, uiTotalAmmo + usAmmo); // If slot 0,1,10,11,12 - Ammo is max 1 + uiTotalAmmo = std::min(1U, uiTotalAmmo + usAmmo); // If slot 0,1,10,11,12 - Ammo is max 1 else if ((ucWeaponSlot >= 3 && ucWeaponSlot <= 5) || ucPreviousWeaponID == ucWeaponID) - uiTotalAmmo += usAmmo; // If slot 3,4,5 or slot weapon the same, ammo is shared, so add + uiTotalAmmo += usAmmo; // If slot 3,4,5 or slot weapon the same, ammo is shared, so add else - uiTotalAmmo = usAmmo; // Otherwise ammo is not shared, so replace + uiTotalAmmo = usAmmo; // Otherwise ammo is not shared, so replace uiTotalAmmo = std::min(0xFFFFU, uiTotalAmmo); - pPed->SetWeaponTotalAmmo(uiTotalAmmo, ucWeaponSlot); + pPed->SetWeaponTotalAmmo(static_cast(uiTotalAmmo), ucWeaponSlot); CBitStream BitStream; @@ -4933,7 +5043,7 @@ bool CStaticFunctionDefinitions::SetWeaponAmmo(CElement* pElement, unsigned char { CPed* pPed = static_cast(pElement); CWeapon* pWeapon = pPed->GetWeapon(CWeaponNames::GetSlotFromWeapon(ucWeaponID)); - if (pPed->IsSpawned() && pWeapon) // Check We have that weapon + if (pPed->IsSpawned() && pWeapon) // Check We have that weapon { unsigned char ucWeaponID = pWeapon->ucType; if (ucWeaponID) @@ -5030,7 +5140,7 @@ bool CStaticFunctionDefinitions::GiveVehicleSirens(CVehicle* pVehicle, unsigned eVehicleType vehicleType = CVehicleManager::GetVehicleType(pVehicle->GetModel()); // Won't work with below. if (vehicleType != VEHICLE_CAR && vehicleType != VEHICLE_MONSTERTRUCK && vehicleType != VEHICLE_QUADBIKE) - return false; + return false; if (ucSirenType < 1 || ucSirenType > 6) return false; @@ -5421,8 +5531,7 @@ bool CStaticFunctionDefinitions::GetTrainSpeed(CVehicle* pVehicle, float& fSpeed if (pVehicle->GetVehicleType() != VEHICLE_TRAIN) return false; - const CVector& vecVelocity = pVehicle->GetVelocity(); - fSpeed = vecVelocity.Length(); + fSpeed = pVehicle->GetTrainSpeed(); return true; } @@ -5484,7 +5593,7 @@ bool CStaticFunctionDefinitions::BlowVehicle(CElement* pElement, std::optionalSetBlowState(createExplosion ? VehicleBlowState::AWAITING_EXPLOSION_SYNC : VehicleBlowState::BLOWN); CLuaArguments arguments; - arguments.PushBoolean(createExplosion); // withExplosion + arguments.PushBoolean(createExplosion); // withExplosion if (!vehicle->CallEvent("onVehicleExplode", arguments)) return false; @@ -5498,7 +5607,7 @@ bool CStaticFunctionDefinitions::BlowVehicle(CElement* pElement, std::optionalWrite(vehicle->GenerateSyncTimeContext()); - BitStream.pBitStream->WriteBit(createExplosion); // only consumed by clients with at least eBitStreamVersion::VehicleBlowStateSupport + BitStream.pBitStream->WriteBit(createExplosion); m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(vehicle, BLOW_VEHICLE, *BitStream.pBitStream)); return true; } @@ -5808,7 +5917,7 @@ bool CStaticFunctionDefinitions::GetEntryHandling(const CHandlingEntry* pEntry, case HANDLING_SEATOFFSETDISTANCE: fValue = pEntry->GetSeatOffsetDistance(); break; - case HANDLING_ABS: // bool + case HANDLING_ABS: // bool fValue = (float)(pEntry->GetABS() ? 1 : 0); break; default: @@ -5827,7 +5936,7 @@ bool CStaticFunctionDefinitions::GetEntryHandling(const CHandlingEntry* pEntry, { switch (eProperty) { - case HANDLING_PERCENTSUBMERGED: // unsigned int + case HANDLING_PERCENTSUBMERGED: // unsigned int uiValue = pEntry->GetPercentSubmerged(); break; case HANDLING_MONETARY: @@ -6012,7 +6121,7 @@ bool CStaticFunctionDefinitions::SetEntryHandling(CHandlingEntry* pEntry, eHandl if (ucValue >= 0 && ucValue <= 29) { if (ucValue != 3 && ucValue != 8 && ucValue != 17 && ucValue != 23) - return true; // Pretend it worked to avoid script warnings + return true; // Pretend it worked to avoid script warnings pEntry->SetAnimGroup(ucValue); return true; @@ -6745,13 +6854,13 @@ bool CStaticFunctionDefinitions::SetVehicleWheelStates(CElement* pElement, int i (iRearRight != -1 && iRearRight != pVehicle->m_ucWheelStates[REAR_RIGHT_WHEEL])) { if (iFrontLeft != -1) - pVehicle->m_ucWheelStates[FRONT_LEFT_WHEEL] = iFrontLeft; + pVehicle->m_ucWheelStates[FRONT_LEFT_WHEEL] = static_cast(iFrontLeft); if (iRearLeft != -1) - pVehicle->m_ucWheelStates[REAR_LEFT_WHEEL] = iRearLeft; + pVehicle->m_ucWheelStates[REAR_LEFT_WHEEL] = static_cast(iRearLeft); if (iFrontRight != -1) - pVehicle->m_ucWheelStates[FRONT_RIGHT_WHEEL] = iFrontRight; + pVehicle->m_ucWheelStates[FRONT_RIGHT_WHEEL] = static_cast(iFrontRight); if (iRearRight != -1) - pVehicle->m_ucWheelStates[REAR_RIGHT_WHEEL] = iRearRight; + pVehicle->m_ucWheelStates[REAR_RIGHT_WHEEL] = static_cast(iRearRight); CBitStream BitStream; BitStream.pBitStream->Write((const char*)&pVehicle->m_ucWheelStates[0], MAX_WHEELS); @@ -6795,7 +6904,8 @@ bool CStaticFunctionDefinitions::SetVehicleLightState(CElement* pElement, unsign return false; } -bool CStaticFunctionDefinitions::SetVehiclePanelState(CElement* pElement, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent, bool breakGlass) +bool CStaticFunctionDefinitions::SetVehiclePanelState(CElement* pElement, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent, + bool breakGlass) { assert(pElement); RUN_CHILDREN(SetVehiclePanelState(*iter, ucPanel, ucState, spawnFlyingComponent, breakGlass)) @@ -7309,6 +7419,7 @@ bool CStaticFunctionDefinitions::SetTrainSpeed(CVehicle* pVehicle, float fSpeed) vecVelocity.Normalize(); vecVelocity *= fSpeed; pVehicle->SetVelocity(vecVelocity); + pVehicle->SetTrainSpeed(fSpeed); CBitStream BitStream; BitStream.pBitStream->Write(fSpeed); @@ -7516,7 +7627,7 @@ bool CStaticFunctionDefinitions::ResetVehicleHandling(CVehicle* pVehicle, bool b handling.data.fTurnMass = pNewEntry->GetTurnMass(); handling.data.fDragCoeff = pNewEntry->GetDragCoeff(); handling.data.vecCenterOfMass = pNewEntry->GetCenterOfMass(); - handling.data.ucPercentSubmerged = pNewEntry->GetPercentSubmerged(); + handling.data.ucPercentSubmerged = static_cast(pNewEntry->GetPercentSubmerged()); handling.data.fTractionMultiplier = pNewEntry->GetTractionMultiplier(); handling.data.ucDriveType = pNewEntry->GetCarDriveType(); handling.data.ucEngineType = pNewEntry->GetCarEngineType(); @@ -7742,7 +7853,7 @@ CMarker* CStaticFunctionDefinitions::CreateMarker(CResource* pResource, const CV assert(szType); // Grab the type id - unsigned char ucType = CMarkerManager::StringToType(szType); + auto ucType = static_cast(CMarkerManager::StringToType(szType)); if (ucType != CMarker::TYPE_INVALID) { // Create the marker @@ -7833,7 +7944,7 @@ bool CStaticFunctionDefinitions::SetMarkerType(CElement* pElement, const char* s if (IS_MARKER(pElement)) { // Grab the marker type - unsigned char ucType = CMarkerManager::StringToType(szType); + auto ucType = static_cast(CMarkerManager::StringToType(szType)); if (ucType != CMarker::TYPE_INVALID) { // Set the new type @@ -8262,8 +8373,8 @@ bool CStaticFunctionDefinitions::SetObjectScale(CElement* pElement, const CVecto CBitStream BitStream; BitStream.pBitStream->Write(vecScale.fX); - BitStream.pBitStream->Write(vecScale.fY); // Ignored by clients with bitstream version < 0x41 - BitStream.pBitStream->Write(vecScale.fZ); // Ignored by clients with bitstream version < 0x41 + BitStream.pBitStream->Write(vecScale.fY); // Ignored by clients with bitstream version < 0x41 + BitStream.pBitStream->Write(vecScale.fZ); // Ignored by clients with bitstream version < 0x41 m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pObject, SET_OBJECT_SCALE, *BitStream.pBitStream)); return true; } @@ -8368,7 +8479,7 @@ bool CStaticFunctionDefinitions::BreakObject(CElement* pElement) CBitStream BitStream; m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pObject, BREAK_OBJECT, *BitStream.pBitStream)); - + return true; } @@ -8842,7 +8953,7 @@ bool CStaticFunctionDefinitions::CreateExplosion(const CVector& vecPosition, uns if (pElement) { RUN_CHILDREN(CreateExplosion(vecPosition, ucType, *iter)) - + if (IS_PLAYER(pElement)) { CPlayer* player = static_cast(pElement); @@ -9089,6 +9200,8 @@ bool CStaticFunctionDefinitions::UnbindKey(CPlayer* pPlayer, const char* szKey, (pControl && (bSuccess = pKeyBinds->RemoveControlFunction(szKey, pLuaMain, bCheckHitState, bHitState, iLuaFunction)) && !pKeyBinds->ControlFunctionExists(szKey, NULL, bCheckHitState, bHitState))) { + // Only send UNBIND_KEY RPC if there are no more function bindings for this key + // This allows user command bindings to persist unsigned char ucKeyLength = static_cast(strlen(szKey)); CBitStream bitStream; @@ -9388,14 +9501,14 @@ bool CStaticFunctionDefinitions::SetPlayerTeam(CPlayer* pPlayer, CTeam* pTeam) if (currentTeam) { Arguments.PushElement(currentTeam); - } + } else { - Arguments.PushNil(); // No oldTeam return nil + Arguments.PushNil(); // No oldTeam return nil } Arguments.PushElement(pTeam); if (!pPlayer->CallEvent("onPlayerTeamChange", Arguments)) - return false; // Event cancelled, return false + return false; // Event cancelled, return false // Change his team pPlayer->SetTeam(pTeam, true); @@ -10342,7 +10455,7 @@ bool CStaticFunctionDefinitions::SetMaxPlayers(unsigned int uiMax) if (uiMax > m_pMainConfig->GetHardMaxPlayers()) return false; m_pMainConfig->SetSoftMaxPlayers(uiMax); - g_pNetServer->SetMaximumIncomingConnections(uiMax); + g_pNetServer->SetMaximumIncomingConnections(static_cast(uiMax)); g_pGame->GetPlayerManager()->BroadcastOnlyJoined(CServerInfoSyncPacket(SERVER_INFO_FLAG_MAX_PLAYERS)); return true; } @@ -10472,10 +10585,9 @@ bool CStaticFunctionDefinitions::GetWaveHeight(float& fHeight) return true; } -bool CStaticFunctionDefinitions::GetFPSLimit(unsigned short& usLimit) +void CStaticFunctionDefinitions::GetFPSLimit(std::uint16_t& fps) noexcept { - usLimit = g_pGame->GetConfig()->GetFPSLimit(); - return true; + fps = g_pGame->GetConfig()->GetFPSLimit(); } bool CStaticFunctionDefinitions::GetMinuteDuration(unsigned long& ulDuration) @@ -10887,7 +10999,7 @@ bool CStaticFunctionDefinitions::RemoveWorldModel(unsigned short usModel, float BitStream.pBitStream->Write(vecPosition.fX); BitStream.pBitStream->Write(vecPosition.fY); BitStream.pBitStream->Write(vecPosition.fZ); - BitStream.pBitStream->Write(cInterior); // Only used by clients with bitstream version >= 0x039 + BitStream.pBitStream->Write(cInterior); // Only used by clients with bitstream version >= 0x039 m_pPlayerManager->BroadcastOnlyJoined(CLuaPacket(REMOVE_WORLD_MODEL, *BitStream.pBitStream)); return true; @@ -10903,7 +11015,7 @@ bool CStaticFunctionDefinitions::RestoreWorldModel(unsigned short usModel, float BitStream.pBitStream->Write(vecPosition.fX); BitStream.pBitStream->Write(vecPosition.fY); BitStream.pBitStream->Write(vecPosition.fZ); - BitStream.pBitStream->Write(cInterior); // Only used by clients with bitstream version >= 0x039 + BitStream.pBitStream->Write(cInterior); // Only used by clients with bitstream version >= 0x039 m_pPlayerManager->BroadcastOnlyJoined(CLuaPacket(RESTORE_WORLD_MODEL, *BitStream.pBitStream)); @@ -10941,17 +11053,12 @@ bool CStaticFunctionDefinitions::SendSyncIntervals(CPlayer* pPlayer) BitStream.pBitStream->Write(g_TickRateSettings.iObjectSync); BitStream.pBitStream->Write(g_TickRateSettings.iKeySyncRotation); BitStream.pBitStream->Write(g_TickRateSettings.iKeySyncAnalogMove); - - if (pPlayer->CanBitStream(eBitStreamVersion::FixSyncerDistance)) - { - BitStream.pBitStream->Write(g_TickRateSettings.iPedSyncerDistance); - BitStream.pBitStream->Write(g_TickRateSettings.iUnoccupiedVehicleSyncerDistance); - } + BitStream.pBitStream->Write(g_TickRateSettings.iPedSyncerDistance); + BitStream.pBitStream->Write(g_TickRateSettings.iUnoccupiedVehicleSyncerDistance); pPlayer->Send(CLuaPacket(SET_SYNC_INTERVALS, *BitStream.pBitStream)); }; - if (pPlayer) sendSyncIntervalPatket(pPlayer); else @@ -11085,18 +11192,16 @@ bool CStaticFunctionDefinitions::SetWaveHeight(float fHeight) return false; } -bool CStaticFunctionDefinitions::SetFPSLimit(unsigned short usLimit, bool bSave) +bool CStaticFunctionDefinitions::SetFPSLimit(std::uint16_t fps, bool save) { - if (g_pGame->GetConfig()->SetFPSLimit(usLimit, bSave)) - { - CBitStream BitStream; - BitStream.pBitStream->Write((short)usLimit); - m_pPlayerManager->BroadcastOnlyJoined(CLuaPacket(SET_FPS_LIMIT, *BitStream.pBitStream)); + if (!g_pGame->GetConfig()->SetFPSLimit(fps, save)) + return false; - return true; - } + CBitStream BitStream; + BitStream.pBitStream->Write(static_cast(fps)); + m_pPlayerManager->BroadcastOnlyJoined(CLuaPacket(SET_FPS_LIMIT, *BitStream.pBitStream)); - return false; + return true; } bool CStaticFunctionDefinitions::SetMinuteDuration(unsigned long ulDuration) @@ -11524,7 +11629,6 @@ bool CStaticFunctionDefinitions::GetAccountSerial(CAccount* pAccount, SString& s return bRegistered; } - bool CStaticFunctionDefinitions::SetAccountSerial(CAccount* account, const std::string& serial) noexcept { if (account && account->IsRegistered()) @@ -11676,7 +11780,15 @@ bool CStaticFunctionDefinitions::SetAccountName(CAccount* pAccount, SString strN } else { + CLuaArguments arguments; + arguments.PushAccount(pAccount); + arguments.PushString(pAccount->GetName().c_str()); + arguments.PushString(strNewName); + if (!m_pMapManager->GetRootElement()->CallEvent("onAccountNameChange", arguments)) + return false; + pAccount->SetName(strNewName); + return true; } } @@ -11810,19 +11922,18 @@ CBan* CStaticFunctionDefinitions::BanPlayer(CPlayer* pTargetPlayer, bool bIP, bo // Ban the player if (bIP) pBan = m_pBanManager->AddBan(pTargetPlayer, strResponsible, strReason, tUnban); - else if (bUsername || bSerial) + else if (bSerial) pBan = m_pBanManager->AddBan(strResponsible, strReason, tUnban); // If the ban was successful if (pBan) { - // Set the data if banned by either username or serial - if (bUsername) - pBan->SetAccount(pTargetPlayer->GetSerialUser()); + // Set the data if banned by serial if (bSerial) + { pBan->SetSerial(pTargetPlayer->GetSerial()); - if (bUsername || bSerial) pBan->SetNick(pTargetPlayer->GetNick()); + } // Check if we passed a responsible player if (pResponsible) @@ -11865,13 +11976,6 @@ CBan* CStaticFunctionDefinitions::BanPlayer(CPlayer* pTargetPlayer, bool bIP, bo bBan = (pBan->GetIP() == pPlayer->GetSourceIP()); } - // Check if the player's username matches the specified one, if specified, and he wasn't banned over IP yet - if (!bBan && bUsername && pBan->GetAccount().length() > 0) - { - const std::string& strPlayerUsername = pPlayer->GetSerialUser(); - bBan = stricmp(strPlayerUsername.c_str(), pBan->GetAccount().c_str()) == 0; - } - // Check if the player's serial matches the specified one, if specified, and he wasn't banned over IP or username yet if (!bBan && bSerial) { @@ -11956,10 +12060,6 @@ CBan* CStaticFunctionDefinitions::AddBan(SString strIP, SString strUsername, SSt { pBan = m_pBanManager->AddBan(strResponsible, strReason, tUnban); } - else if (bUsernameSpecified && !m_pBanManager->IsAccountBanned(strUsername)) - { - pBan = m_pBanManager->AddBan(strResponsible, strReason, tUnban); - } // If the ban was added if (pBan) @@ -11995,8 +12095,6 @@ CBan* CStaticFunctionDefinitions::AddBan(SString strIP, SString strUsername, SSt strMessage = strMessage.substr(0, 255); // Set the account or serial if either one is set to be banned - if (bUsernameSpecified) - pBan->SetAccount(strUsername); if (bSerialSpecified) pBan->SetSerial(strSerial); @@ -12046,13 +12144,6 @@ CBan* CStaticFunctionDefinitions::AddBan(SString strIP, SString strUsername, SSt bBan = (strIP == pPlayer->GetSourceIP()); } - // Check if the player's username matches the specified one, if specified, and he wasn't banned over IP yet - if (!bBan && bUsernameSpecified && strUsername.length() > 0) - { - const std::string& strPlayerUsername = pPlayer->GetSerialUser(); - bBan = stricmp(strPlayerUsername.c_str(), strUsername.c_str()) == 0; - } - // Check if the player's serial matches the specified one, if specified, and he wasn't banned over IP or username yet if (!bBan && bSerialSpecified) { @@ -12168,11 +12259,6 @@ bool CStaticFunctionDefinitions::GetBanSerial(CBan* pBan, SString& strOutSerial) bool CStaticFunctionDefinitions::GetBanUsername(CBan* pBan, SString& strOutUsername) { - if (!pBan->GetAccount().empty()) - { - strOutUsername = pBan->GetAccount(); - return true; - } return false; } @@ -12597,7 +12683,8 @@ bool CStaticFunctionDefinitions::SetColPolygonHeight(CColPolygon* pColPolygon, f return false; } -bool CStaticFunctionDefinitions::SpawnVehicleFlyingComponent(CVehicle* const vehicle, std::uint8_t nodeIndex, std::uint8_t collisionType, std::int32_t removalTime) +bool CStaticFunctionDefinitions::SpawnVehicleFlyingComponent(CVehicle* const vehicle, std::uint8_t nodeIndex, std::uint8_t collisionType, + std::int32_t removalTime) { CBitStream bitStream; bitStream.pBitStream->Write(nodeIndex); diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h index 6ff5758a5d4..0b642a1714d 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -51,7 +51,7 @@ class CStaticFunctionDefinitions static CElement* GetElementByIndex(const char* szType, unsigned int uiIndex); static CElement* GetElementChild(CElement* pElement, unsigned int uiIndex); static bool GetElementChildrenCount(CElement* pElement, unsigned int& uiCount); - static CLuaArgument* GetElementData(CElement* pElement, const char* szName, bool bInherit); + static CLuaArgument* GetElementData(CElement* pElement, CStringName name, bool bInherit); static CLuaArguments* GetAllElementData(CElement* pElement, CLuaArguments* table); static CElement* GetElementParent(CElement* pElement); static bool GetElementMatrix(CElement* pElement, CMatrix& matrix); @@ -83,12 +83,12 @@ class CStaticFunctionDefinitions // Element set funcs static bool ClearElementVisibleTo(CElement* pElement); static bool SetElementID(CElement* pElement, const char* szID); - static bool SetElementData(CElement* pElement, const char* szName, const CLuaArgument& Variable, ESyncType syncType, + static bool SetElementData(CElement* pElement, CStringName name, const CLuaArgument& Variable, ESyncType syncType, std::optional clientTrust); - static bool RemoveElementData(CElement* pElement, const char* szName); - static bool AddElementDataSubscriber(CElement* pElement, const char* szName, CPlayer* pPlayer); - static bool RemoveElementDataSubscriber(CElement* pElement, const char* szName, CPlayer* pPlayer); - static bool HasElementDataSubscriber(CElement* pElement, const char* szName, CPlayer* pPlayer); + static bool RemoveElementData(CElement* pElement, CStringName name); + static bool AddElementDataSubscriber(CElement* pElement, CStringName name, CPlayer* pPlayer); + static bool RemoveElementDataSubscriber(CElement* pElement, CStringName name, CPlayer* pPlayer); + static bool HasElementDataSubscriber(CElement* pElement, CStringName name, CPlayer* pPlayer); static bool SetElementParent(CElement* pElement, CElement* pParent); static bool SetElementMatrix(CElement* pElement, const CMatrix& matrix); static bool SetElementPosition(CElement* pElement, const CVector& vecPosition, bool bWarp = true); @@ -130,8 +130,8 @@ class CStaticFunctionDefinitions static bool GetPlayerNametagColor(CPlayer* pPlayer, unsigned char& ucR, unsigned char& ucG, unsigned char& ucB); static bool IsPlayerNametagShowing(CPlayer* pPlayer, bool& bShowing); static const std::string& GetPlayerSerial(CPlayer* pPlayer, uint uiIndex); - static const std::string& GetPlayerUserName(CPlayer* pPlayer); - static const std::string& GetPlayerCommunityID(CPlayer* pPlayer); + static std::string GetPlayerUserName(CPlayer* pPlayer); + static std::string GetPlayerCommunityID(CPlayer* pPlayer); static bool GetPlayerBlurLevel(CPlayer* pPlayer, unsigned char& ucLevel); static bool GetPlayerName(CElement* pElement, SString& strOutName); static bool GetPlayerIP(CElement* pElement, SString& strOutIP); @@ -243,7 +243,7 @@ class CStaticFunctionDefinitions // Vehicle create/destroy functions static CVehicle* CreateVehicle(CResource* pResource, unsigned short usModel, const CVector& vecPosition, const CVector& vecRotation, const char* szRegPlate, unsigned char ucVariant, unsigned char ucVariant2, bool bSynced); - static bool SpawnVehicleFlyingComponent(CVehicle* const vehicle, std::uint8_t nodeIndex, std::uint8_t collisionType, std::int32_t removalTime = -1); + static bool SpawnVehicleFlyingComponent(CVehicle* const vehicle, std::uint8_t nodeIndex, std::uint8_t collisionType, std::int32_t removalTime = -1); // Vehicle get functions static bool GetVehicleVariant(CVehicle* pVehicle, unsigned char& ucVariant, unsigned char& ucVariant2); @@ -314,7 +314,8 @@ class CStaticFunctionDefinitions static bool SetVehicleDoorState(CElement* pElement, unsigned char ucDoor, unsigned char ucState, bool spawnFlyingComponent); static bool SetVehicleWheelStates(CElement* pElement, int iFrontLeft, int iRearLeft = -1, int iFrontRight = -1, int iRearRight = -1); static bool SetVehicleLightState(CElement* pElement, unsigned char ucLight, unsigned char ucState); - static bool SetVehiclePanelState(CElement* pElement, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent = true, bool breakGlass = false); + static bool SetVehiclePanelState(CElement* pElement, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent = true, + bool breakGlass = false); static bool SetVehicleIdleRespawnDelay(CElement* pElement, unsigned long ulTime); static bool SetVehicleRespawnDelay(CElement* pElement, unsigned long ulTime); static bool GetVehicleRespawnPosition(CElement* pElement, CVector& vecPosition); @@ -371,7 +372,8 @@ class CStaticFunctionDefinitions static bool RemoveVehicleSirens(CVehicle* pVehicle); // Marker create/destroy functions - static CMarker* CreateMarker(CResource* pResource, const CVector& vecPosition, const char* szType, float fSize, const SColor color, CElement* pVisibleTo, bool ignoreAlphaLimits); + static CMarker* CreateMarker(CResource* pResource, const CVector& vecPosition, const char* szType, float fSize, const SColor color, CElement* pVisibleTo, + bool ignoreAlphaLimits); // Marker get functions static bool GetMarkerCount(unsigned int& uiCount); @@ -590,7 +592,7 @@ class CStaticFunctionDefinitions static bool GetGravity(float& fGravity); static bool GetGameSpeed(float& fSpeed); static bool GetWaveHeight(float& fHeight); - static bool GetFPSLimit(unsigned short& usLimit); + static void GetFPSLimit(std::uint16_t& fps) noexcept; static bool GetMinuteDuration(unsigned long& ulDuration); static bool IsGarageOpen(unsigned char ucGarageID, bool& bIsOpen); static bool GetTrafficLightState(unsigned char& ucState); @@ -624,7 +626,7 @@ class CStaticFunctionDefinitions static bool GetHeatHaze(SHeatHazeSettings& heatHazeSettings); static bool SetHeatHaze(const SHeatHazeSettings& heatHazeSettings); static bool ResetHeatHaze(); - static bool SetFPSLimit(unsigned short usLimit, bool bSave); + static bool SetFPSLimit(std::uint16_t fps, bool save); static bool SetMinuteDuration(unsigned long ulDuration); static bool SetGarageOpen(unsigned char ucGarageID, bool bIsOpen); static bool SetGlitchEnabled(const std::string& strGlitchName, bool bEnabled); diff --git a/Server/mods/deathmatch/logic/CTeam.h b/Server/mods/deathmatch/logic/CTeam.h index 69866b0acb9..6558472ff76 100644 --- a/Server/mods/deathmatch/logic/CTeam.h +++ b/Server/mods/deathmatch/logic/CTeam.h @@ -33,9 +33,9 @@ class CTeam final : public CElement const char* GetTeamName() { return m_strTeamName; } void SetTeamName(const char* szName); - void AddPlayer(CPlayer* pPlayer, bool bChangePlayer = false); - void RemovePlayer(CPlayer* pPlayer, bool bChangePlayer = false); - void RemoveAllPlayers(); + void AddPlayer(CPlayer* pPlayer, bool bChangePlayer = false); + void RemovePlayer(CPlayer* pPlayer, bool bChangePlayer = false); + void RemoveAllPlayers(); std::vector GetPlayers() const; void GetColor(unsigned char& ucRed, unsigned char& ucGreen, unsigned char& ucBlue); diff --git a/Server/mods/deathmatch/logic/CTrainTrack.cpp b/Server/mods/deathmatch/logic/CTrainTrack.cpp index 5cbae9d6fc9..54f49bcddf3 100644 --- a/Server/mods/deathmatch/logic/CTrainTrack.cpp +++ b/Server/mods/deathmatch/logic/CTrainTrack.cpp @@ -19,8 +19,8 @@ CTrainTrack::CTrainTrack(CTrainTrackManager* pManager, const std::vector m_Nodes; bool m_LinkLastNodes; - bool m_Default; uchar m_DefaultTrackId; }; diff --git a/Server/mods/deathmatch/logic/CTrainTrackManager.cpp b/Server/mods/deathmatch/logic/CTrainTrackManager.cpp index 3af2d1cdf35..5c05d29d02d 100644 --- a/Server/mods/deathmatch/logic/CTrainTrackManager.cpp +++ b/Server/mods/deathmatch/logic/CTrainTrackManager.cpp @@ -15,7 +15,11 @@ CTrainTrackManager::CTrainTrackManager() { - Reset(); + // Create default tracks + for (uchar i = 0; i < 4; ++i) + { + m_DefaultTracks[i] = CreateTrainTrack(OriginalTrackNodes[i], true, nullptr, i); + } } CTrainTrack* CTrainTrackManager::CreateTrainTrack(const std::vector& nodes, bool linkLastNodes, CElement* pParent, uchar defaultTrackId) @@ -33,25 +37,16 @@ CTrainTrack* CTrainTrackManager::CreateTrainTrack(const std::vector& void CTrainTrackManager::DestroyTrainTrack(CTrainTrack* pTrainTrack) { m_Tracks.erase(std::remove(m_Tracks.begin(), m_Tracks.end(), pTrainTrack)); + if (pTrainTrack->IsDefault()) + { + uchar defaultId = pTrainTrack->GetDefaultTrackId(); + m_DefaultTracks[defaultId] = nullptr; + } } -CTrainTrack* CTrainTrackManager::GetTrainTrackByIndex(unsigned int index) +CTrainTrack* CTrainTrackManager::GetDefaultTrackByIndex(uchar index) { - if (index >= m_Tracks.size()) + if (index >= MaxDefaultTracks) return nullptr; - - return m_Tracks[index]; -} - -void CTrainTrackManager::Reset() -{ - // Clear tracks - m_Tracks.clear(); - - // Create default tracks - for (std::size_t i = 0; i < 4; ++i) - { - // Create train tracks - CreateTrainTrack(OriginalTrackNodes[i], true, nullptr, i); - } + return m_DefaultTracks[index]; } diff --git a/Server/mods/deathmatch/logic/CTrainTrackManager.h b/Server/mods/deathmatch/logic/CTrainTrackManager.h index ec55dbfc2cd..58476581738 100644 --- a/Server/mods/deathmatch/logic/CTrainTrackManager.h +++ b/Server/mods/deathmatch/logic/CTrainTrackManager.h @@ -14,16 +14,19 @@ class CTrainTrackManager { public: CTrainTrackManager(); - void Reset(); CTrainTrack* CreateTrainTrack(const std::vector& nodes, bool linkLastNodes, CElement* pParent, uchar defaultTrackId = 0xFF); void DestroyTrainTrack(CTrainTrack* pTrainTrack); const std::vector& GetTracks() { return m_Tracks; } - CTrainTrack* GetTrainTrackByIndex(unsigned int index); + CTrainTrack* GetDefaultTrackByIndex(uchar index); private: constexpr static std::size_t MaxTracks = 255; - std::vector m_Tracks; + constexpr static std::size_t MaxDefaultTracks = 4; + + std::vector m_Tracks; + + CTrainTrack* m_DefaultTracks[MaxDefaultTracks]; }; diff --git a/Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp b/Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp index ea9986d4760..6f9a0678b9d 100644 --- a/Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp +++ b/Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp @@ -204,7 +204,7 @@ void CUnoccupiedVehicleSync::StartSync(CPlayer* pPlayer, CVehicle* pVehicle) // Call the onElementStartSync event CLuaArguments Arguments; - Arguments.PushElement(pPlayer); // New syncer + Arguments.PushElement(pPlayer); // New syncer pVehicle->CallEvent("onElementStartSync", Arguments); } @@ -221,7 +221,7 @@ void CUnoccupiedVehicleSync::StopSync(CVehicle* pVehicle) // Call the onElementStopSync event CLuaArguments Arguments; - Arguments.PushElement(pSyncer); // Old syncer + Arguments.PushElement(pSyncer); // Old syncer pVehicle->CallEvent("onElementStopSync", Arguments); } @@ -488,8 +488,8 @@ void CUnoccupiedVehicleSync::Packet_UnoccupiedVehiclePushSync(CUnoccupiedVehicle // Is the player syncing this vehicle and there is no driver? Also only process // this packet if the time context matches. if (pVehicle->GetSyncer() != pPlayer && pVehicle->GetTimeSinceLastPush() >= MIN_PUSH_ANTISPAM_RATE && - IsPointNearPoint3D(pVehicle->GetPosition(), pPlayer->GetPosition(), g_TickRateSettings.iVehicleContactSyncRadius) - && pVehicle->GetDimension() == pPlayer->GetDimension()) + IsPointNearPoint3D(pVehicle->GetPosition(), pPlayer->GetPosition(), static_cast(g_TickRateSettings.iVehicleContactSyncRadius)) && + pVehicle->GetDimension() == pPlayer->GetDimension()) { // Is there no player driver? CPed* pOccupant = pVehicle->GetOccupant(0); diff --git a/Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.h b/Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.h index 787329fc863..a6aa8feb94a 100644 --- a/Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.h +++ b/Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.h @@ -11,8 +11,8 @@ #pragma once -#define MIN_ROTATION_DIFF 0.1 -#define MIN_PUSH_ANTISPAM_RATE 1500 +#define MIN_ROTATION_DIFF 0.1 +#define MIN_PUSH_ANTISPAM_RATE 1500 class CVehicle; class CPlayer; diff --git a/Server/mods/deathmatch/logic/CVehicle.cpp b/Server/mods/deathmatch/logic/CVehicle.cpp index 0adb009616e..29b4749a5bc 100644 --- a/Server/mods/deathmatch/logic/CVehicle.cpp +++ b/Server/mods/deathmatch/logic/CVehicle.cpp @@ -132,16 +132,20 @@ CVehicle::~CVehicle() if (pPed->GetVehicleAction() == CPed::VEHICLEACTION_EXITING) { // Does it have an occupant and is the occupant the requesting ped? - unsigned char ucOccupiedSeat = pPed->GetOccupiedVehicleSeat(); - if (pPed == GetOccupant(ucOccupiedSeat)) + const uint uiOccupiedSeat = pPed->GetOccupiedVehicleSeat(); + if (uiOccupiedSeat > 0xFF) + continue; + + unsigned char occupiedSeat = static_cast(uiOccupiedSeat); + if (pPed == GetOccupant(occupiedSeat)) { // Mark the ped/vehicle as empty - SetOccupant(NULL, ucOccupiedSeat); + SetOccupant(NULL, occupiedSeat); pPed->SetOccupiedVehicle(NULL, 0); pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE); // Tell everyone he has exited the vehicle - CVehicleInOutPacket Reply(pPed->GetID(), GetID(), ucOccupiedSeat, CGame::VEHICLE_NOTIFY_OUT_RETURN); + CVehicleInOutPacket Reply(pPed->GetID(), GetID(), static_cast(occupiedSeat), CGame::VEHICLE_NOTIFY_OUT_RETURN); g_pGame->GetPlayerManager()->BroadcastOnlyJoined(Reply); } } @@ -312,7 +316,7 @@ bool CVehicle::ReadSpecialData(const int iLine) uchar ucValues[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; char* sz1 = strtok(szTemp, ", "); if (sz1) - ucValues[0] = atoi(sz1); + ucValues[0] = static_cast(atoi(sz1)); int i; for (i = 1; i < 12; i++) @@ -320,7 +324,7 @@ bool CVehicle::ReadSpecialData(const int iLine) char* szn = strtok(NULL, ", "); if (!szn) break; - ucValues[i] = atoi(szn); + ucValues[i] = static_cast(atoi(szn)); } if (i == 3 || i == 6 || i == 9 || i == 12) @@ -804,7 +808,7 @@ void CVehicle::GenerateRegPlate() } // Put it in the plate - m_szRegPlate[i] = iChar; + m_szRegPlate[i] = static_cast(iChar); } } @@ -887,7 +891,7 @@ void CVehicle::SetVehicleFlags(bool bEnable360, bool bEnableRandomiser, bool bEn } void CVehicle::RemoveVehicleSirens() { - for (int i = 0; i <= 7; i++) + for (unsigned char i = 0; i <= 7; i++) { m_tSirenBeaconInfo.m_tSirenInfo[i] = SSirenBeaconInfo(); SetVehicleSirenPosition(i, CVector(0, 0, 0)); diff --git a/Server/mods/deathmatch/logic/CVehicle.h b/Server/mods/deathmatch/logic/CVehicle.h index 8c24363d65a..4430a5a41bf 100644 --- a/Server/mods/deathmatch/logic/CVehicle.h +++ b/Server/mods/deathmatch/logic/CVehicle.h @@ -20,9 +20,9 @@ class CVehicle; #include "CVehicleUpgrades.h" #include "CHandlingEntry.h" -#define MAX_VEHICLE_SEATS 9 +#define MAX_VEHICLE_SEATS 9 #define DEFAULT_VEHICLE_HEALTH 1000 -#define MAX_VEHICLE_HEALTH 10000 +#define MAX_VEHICLE_HEALTH 10000 enum eWheelStatus { @@ -155,9 +155,9 @@ enum class eCarComponentCollisionTypes }; #define SIREN_TYPE_FIRST 1 -#define SIREN_TYPE_LAST 6 -#define SIREN_ID_MAX 7 -#define SIREN_COUNT_MAX 8 +#define SIREN_TYPE_LAST 6 +#define SIREN_ID_MAX 7 +#define SIREN_COUNT_MAX 8 struct SSirenBeaconInfo { @@ -501,7 +501,7 @@ class CVehicle final : public CElement bool m_bNeedsDimensionResync; ushort m_usLastUnoccupiedSyncDimension; -public: // 'Safe' variables (that have no need for accessors) +public: // 'Safe' variables (that have no need for accessors) bool m_bDamageProof; uint m_uiDamageInfoSendPhase; SFixedArray m_ucDoorStates; diff --git a/Server/mods/deathmatch/logic/CVehicleManager.cpp b/Server/mods/deathmatch/logic/CVehicleManager.cpp index c1a4ad8bfee..bab0e77a87e 100644 --- a/Server/mods/deathmatch/logic/CVehicleManager.cpp +++ b/Server/mods/deathmatch/logic/CVehicleManager.cpp @@ -14,40 +14,40 @@ #include "Utils.h" #include "lua/LuaCommon.h" -static const SFixedArray g_ucMaxPassengers = {{3, 1, 1, 1, 3, 3, 0, 1, 1, 3, 1, 1, 1, 3, 1, 1, // 400->415 - 3, 1, 3, 1, 3, 3, 1, 1, 1, 0, 3, 3, 3, 1, 0, 8, // 416->431 - 0, 1, 1, 255, 1, 8, 3, 1, 3, 0, 1, 1, 1, 3, 0, 1, // 432->447 - 0, 1, 255, 1, 0, 0, 0, 1, 1, 1, 3, 3, 1, 1, 1, // 448->462 - 1, 1, 1, 3, 3, 1, 1, 3, 1, 0, 0, 1, 1, 0, 1, 1, // 463->478 - 3, 1, 0, 3, 1, 0, 0, 0, 3, 1, 1, 3, 1, 3, 0, 1, // 479->494 - 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 0, 0, // 495->510 - 1, 0, 0, 1, 1, 3, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, // 511->526 - 1, 1, 3, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 3, 1, // 527->541 - 1, 1, 1, 1, 3, 3, 1, 1, 3, 3, 1, 0, 1, 1, 1, 1, // 542->557 - 1, 1, 3, 3, 1, 1, 0, 1, 3, 3, 0, 255, 1, 0, 0, // 558->572 - 1, 0, 1, 1, 1, 1, 3, 3, 1, 3, 0, 255, 3, 1, 1, 1, // 573->588 - 1, 255, 255, 1, 1, 1, 0, 3, 3, 3, 1, 1, 1, 1, 1, // 589->604 - 3, 1, 255, 255, 255, 3, 255, 255}}; // 605->611 +static const SFixedArray g_ucMaxPassengers = {{3, 1, 1, 1, 3, 3, 0, 1, 1, 3, 1, 1, 1, 3, 1, 1, // 400->415 + 3, 1, 3, 1, 3, 3, 1, 1, 1, 0, 3, 3, 3, 1, 0, 8, // 416->431 + 0, 1, 1, 255, 1, 8, 3, 1, 3, 0, 1, 1, 1, 3, 0, 1, // 432->447 + 0, 1, 255, 1, 0, 0, 0, 1, 1, 1, 3, 3, 1, 1, 1, // 448->462 + 1, 1, 1, 3, 3, 1, 1, 3, 1, 0, 0, 1, 1, 0, 1, 1, // 463->478 + 3, 1, 0, 3, 3, 0, 0, 0, 3, 1, 1, 3, 1, 3, 0, 1, // 479->494 + 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 0, 0, // 495->510 + 1, 0, 0, 1, 1, 3, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, // 511->526 + 1, 1, 3, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 3, 1, // 527->541 + 1, 1, 1, 1, 3, 3, 1, 1, 3, 3, 1, 0, 1, 1, 1, 1, // 542->557 + 1, 1, 3, 3, 1, 1, 0, 1, 3, 3, 0, 255, 1, 0, 0, // 558->572 + 1, 0, 1, 1, 1, 1, 3, 3, 1, 3, 0, 255, 3, 1, 1, 1, // 573->588 + 1, 255, 255, 1, 1, 1, 0, 3, 3, 3, 1, 1, 1, 1, 1, // 589->604 + 3, 1, 255, 255, 255, 3, 255, 255}}; // 605->611 // List over all vehicles with their special attributes -#define VEHICLE_HAS_TURRENT 0x001UL //1 -#define VEHICLE_HAS_SIRENS 0x002UL //2 -#define VEHICLE_HAS_LANDING_GEARS 0x004UL //4 -#define VEHICLE_HAS_ADJUSTABLE_PROPERTY 0x008UL //8 -#define VEHICLE_HAS_SMOKE_TRAIL 0x010UL //16 -#define VEHICLE_HAS_TAXI_LIGHTS 0x020UL //32 -#define VEHICLE_HAS_SEARCH_LIGHT 0x040UL //64 +#define VEHICLE_HAS_TURRENT 0x001UL // 1 +#define VEHICLE_HAS_SIRENS 0x002UL // 2 +#define VEHICLE_HAS_LANDING_GEARS 0x004UL // 4 +#define VEHICLE_HAS_ADJUSTABLE_PROPERTY 0x008UL // 8 +#define VEHICLE_HAS_SMOKE_TRAIL 0x010UL // 16 +#define VEHICLE_HAS_TAXI_LIGHTS 0x020UL // 32 +#define VEHICLE_HAS_SEARCH_LIGHT 0x040UL // 64 // Generated by MTA10\utils\gentable\gentable_vehattr.cpp static const SFixedArray g_ulVehicleAttributes = { - {0, 0, 0, 0, 0, 0, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 32, 0, 0, 2, 0, // 400-424 - 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, // 425-449 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 450-474 - 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 64, 0, 0, // 475-499 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 4, 12, 0, 0, 2, 8, // 500-524 - 8, 0, 0, 2, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, // 525-549 - 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 550-574 - 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 2, 2, 2, 2, // 575-599 + {0, 0, 0, 0, 0, 0, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 32, 0, 0, 2, 0, // 400-424 + 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, // 425-449 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 450-474 + 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 64, 0, 0, // 475-499 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 4, 12, 0, 0, 2, 8, // 500-524 + 8, 0, 0, 2, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, // 525-549 + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 550-574 + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 2, 2, 2, 2, // 575-599 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; static const SFixedArray gs_vehicleTypes = { diff --git a/Server/mods/deathmatch/logic/CVehicleManager.h b/Server/mods/deathmatch/logic/CVehicleManager.h index f8ecfdb5aeb..fe674982347 100644 --- a/Server/mods/deathmatch/logic/CVehicleManager.h +++ b/Server/mods/deathmatch/logic/CVehicleManager.h @@ -18,7 +18,7 @@ class CVehicleManager; #include // Undefined number of passengers (to disable custom passenger seats overriding in CVehicle) -#define VEHICLE_PASSENGERS_UNDEFINED 255 +#define VEHICLE_PASSENGERS_UNDEFINED 255 class CVehicleManager { diff --git a/Server/mods/deathmatch/logic/CVehicleNames.cpp b/Server/mods/deathmatch/logic/CVehicleNames.cpp index f608b00d1c5..ae8d51085fc 100644 --- a/Server/mods/deathmatch/logic/CVehicleNames.cpp +++ b/Server/mods/deathmatch/logic/CVehicleNames.cpp @@ -18,7 +18,7 @@ const char* szVehicleNameEmpty = ""; struct SVehicleName { const char* szName; - const char* szName_replaced; // Compatability + const char* szName_replaced; // Compatability }; static const SFixedArray VehicleNames = {{{"Landstalker"}, @@ -123,8 +123,8 @@ static const SFixedArray VehicleNames = {{{"Landstalker"}, {"Benson"}, {"Mesa"}, {"RC Goblin"}, - {"Hotring Racer 3"}, {"Hotring Racer 2"}, + {"Hotring Racer 3"}, {"Bloodring Banger"}, {"Rancher Lure"}, {"Super GT"}, diff --git a/Server/mods/deathmatch/logic/CVehicleUpgrades.cpp b/Server/mods/deathmatch/logic/CVehicleUpgrades.cpp index 0657e87eec8..f06d97855fb 100644 --- a/Server/mods/deathmatch/logic/CVehicleUpgrades.cpp +++ b/Server/mods/deathmatch/logic/CVehicleUpgrades.cpp @@ -87,7 +87,7 @@ bool CVehicleUpgrades::IsUpgradeCompatible(unsigned short usUpgrade) if (us == 1000 || us == 1001 || us == 1002 || us == 1003 || us == 1014 || /* spoiler */ us == 1015 || us == 1016 || us == 1023 || us == 1049 || us == 1050 || us == 1058 || us == 1060 || us == 1138 || us == 1139 || us == 1146 || - us == 1147 || us == 1158 || us == 1162 || us == 1163 || us == 116) + us == 1147 || us == 1158 || us == 1162 || us == 1163 || us == 1164) { return true; } @@ -97,7 +97,7 @@ bool CVehicleUpgrades::IsUpgradeCompatible(unsigned short usUpgrade) case 400: return (us == 1020 || us == 1021 || us == 1019 || us == 1018 || us == 1013 || us == 1024 || us == 1008 || us == 1009 || us == 1010); case 401: - return (us == 1005 || us == 1004 || us == 1142 || us == 1143 || us == 1144 || us == 114 || us == 1020 || us == 1019 || us == 1013 || us == 1008 || + return (us == 1005 || us == 1004 || us == 1142 || us == 1143 || us == 1144 || us == 1145 || us == 1020 || us == 1019 || us == 1013 || us == 1008 || us == 1009 || us == 1010 || us == 1006 || us == 1001 || us == 1003 || us == 1017 || us == 1007); case 402: return (us == 1009 || us == 1010); @@ -320,17 +320,17 @@ bool CVehicleUpgrades::GetSlotFromUpgrade(unsigned short us, unsigned char& ucSl ucSlot = 3; return true; } - if (us == 1115 || us == 1116) // front bullbars + if (us == 1115 || us == 1116) // front bullbars { ucSlot = 4; return true; } - if (us == 1109 || us == 1110) // rear bullbars + if (us == 1109 || us == 1110) // rear bullbars { ucSlot = 5; return true; } - if (us == 1013 || us == 1024) // lamps + if (us == 1013 || us == 1024) // lamps { ucSlot = 6; return true; @@ -342,17 +342,17 @@ bool CVehicleUpgrades::GetSlotFromUpgrade(unsigned short us, unsigned char& ucSl ucSlot = 7; return true; } - if (us == 1008 || us == 1009 || us == 1010) // nitro + if (us == 1008 || us == 1009 || us == 1010) // nitro { ucSlot = 8; return true; } - if (us == 1087) // hydraulics + if (us == 1087) // hydraulics { ucSlot = 9; return true; } - if (us == 1086) // stereo + if (us == 1086) // stereo { ucSlot = 10; return true; diff --git a/Server/mods/deathmatch/logic/CWeaponNames.cpp b/Server/mods/deathmatch/logic/CWeaponNames.cpp index f1c8164237a..3eab6927650 100644 --- a/Server/mods/deathmatch/logic/CWeaponNames.cpp +++ b/Server/mods/deathmatch/logic/CWeaponNames.cpp @@ -34,10 +34,10 @@ SWeaponName WeaponNames[] = {{"Fist"}, {"Poolstick"}, {"Katana"}, {"Chainsaw"}, + {"Purple Dildo"}, {"Dildo"}, - {"Dildo"}, - {"Vibrator"}, {"Vibrator"}, + {"Silver Vibrator"}, {"Flower"}, {"Cane"}, {"Grenade"}, @@ -104,12 +104,14 @@ unsigned char CWeaponNames::GetWeaponID(const char* szName) if (szName[0] == 0) return 0xFF; + static_assert(NUMELMS(WeaponNames) <= 0xFF, "WeaponNames table too large for unsigned char IDs"); + // Look for it in our table - for (unsigned int i = 0; i < NUMELMS(WeaponNames); i++) + for (std::size_t i = 0; i < NUMELMS(WeaponNames); i++) { if (stricmp(szName, WeaponNames[i].szName) == 0) { - return i; + return static_cast(i); } } diff --git a/Server/mods/deathmatch/logic/CWeaponStat.h b/Server/mods/deathmatch/logic/CWeaponStat.h index 281e19e4df0..d5e9e6b90c3 100644 --- a/Server/mods/deathmatch/logic/CWeaponStat.h +++ b/Server/mods/deathmatch/logic/CWeaponStat.h @@ -12,15 +12,15 @@ #include "CCommon.h" struct sWeaponStats { - eFireType m_eFireType; // type - instant hit (e.g. pistol), projectile (e.g. rocket launcher), area effect (e.g. flame thrower) + eFireType m_eFireType; // type - instant hit (e.g. pistol), projectile (e.g. rocket launcher), area effect (e.g. flame thrower) - FLOAT m_fTargetRange; // max targeting range - FLOAT m_fWeaponRange; // absolute gun range / default melee attack range - int m_modelId; // modelinfo id - int m_modelId2; // second modelinfo id + FLOAT m_fTargetRange; // max targeting range + FLOAT m_fWeaponRange; // absolute gun range / default melee attack range + int m_modelId; // modelinfo id + int m_modelId2; // second modelinfo id eWeaponSlot m_nWeaponSlot; - int m_nFlags; // flags defining characteristics + int m_nFlags; // flags defining characteristics // instead of storing pointers directly to anims, use anim association groups // NOTE: this is used for stealth kill anims for melee weapons @@ -29,39 +29,39 @@ struct sWeaponStats ////////////////////////////////// // Gun Data ///////////////////////////////// - short m_nAmmo; // ammo in one clip - short m_nDamage; // damage inflicted per hit - CVector m_vecFireOffset; // offset from weapon origin to projectile starting point + short m_nAmmo; // ammo in one clip + short m_nDamage; // damage inflicted per hit + CVector m_vecFireOffset; // offset from weapon origin to projectile starting point // skill settings - eWeaponSkill m_SkillLevel; // what's the skill level of this weapontype - int m_nReqStatLevel; // what stat level is required for this skill level - FLOAT m_fAccuracy; // modify accuracy of weapon - FLOAT m_fMoveSpeed; // how fast can move with weapon + eWeaponSkill m_SkillLevel; // what's the skill level of this weapontype + int m_nReqStatLevel; // what stat level is required for this skill level + FLOAT m_fAccuracy; // modify accuracy of weapon + FLOAT m_fMoveSpeed; // how fast can move with weapon // anim timings - FLOAT m_animLoopStart; // start of animation loop - FLOAT m_animLoopEnd; // end of animation loop - FLOAT m_animFireTime; // time in animation when weapon should be fired + FLOAT m_animLoopStart; // start of animation loop + FLOAT m_animLoopEnd; // end of animation loop + FLOAT m_animFireTime; // time in animation when weapon should be fired - FLOAT m_anim2LoopStart; // start of animation2 loop - FLOAT m_anim2LoopEnd; // end of animation2 loop - FLOAT m_anim2FireTime; // time in animation2 when weapon should be fired + FLOAT m_anim2LoopStart; // start of animation2 loop + FLOAT m_anim2LoopEnd; // end of animation2 loop + FLOAT m_anim2FireTime; // time in animation2 when weapon should be fired - FLOAT m_animBreakoutTime; // time after which player can break out of attack and run off + FLOAT m_animBreakoutTime; // time after which player can break out of attack and run off // projectile/area effect specific info - FLOAT m_fSpeed; // speed of projectile - FLOAT m_fRadius; // radius affected - FLOAT m_fLifeSpan; // time taken for shot to dissipate - FLOAT m_fSpread; // angle inside which shots are created + FLOAT m_fSpeed; // speed of projectile + FLOAT m_fRadius; // radius affected + FLOAT m_fLifeSpan; // time taken for shot to dissipate + FLOAT m_fSpread; // angle inside which shots are created - short m_nAimOffsetIndex; // index into array of aiming offsets + short m_nAimOffsetIndex; // index into array of aiming offsets ////////////////////////////////// // Melee Data ///////////////////////////////// - BYTE m_defaultCombo; // base combo for this melee weapon - BYTE m_nCombosAvailable; // how many further combos are available + BYTE m_defaultCombo; // base combo for this melee weapon + BYTE m_nCombosAvailable; // how many further combos are available }; class CWeaponStat { diff --git a/Server/mods/deathmatch/logic/CWeaponStatManager.cpp b/Server/mods/deathmatch/logic/CWeaponStatManager.cpp index 0aa0630d7b9..0aa0aef874b 100644 --- a/Server/mods/deathmatch/logic/CWeaponStatManager.cpp +++ b/Server/mods/deathmatch/logic/CWeaponStatManager.cpp @@ -483,8 +483,8 @@ void CWeaponStatManager::Init() OriginalNormalWeaponData[33].default_combo = 4; OriginalNormalWeaponData[33].combos_available = 1; // 34 - Sniper - OriginalNormalWeaponData[34].weapon_range = 300.0f; // Default is actually 100; - OriginalNormalWeaponData[34].target_range = 250.0f; // Default is actually 50; + OriginalNormalWeaponData[34].weapon_range = 300.0f; // Default is actually 100; + OriginalNormalWeaponData[34].target_range = 250.0f; // Default is actually 50; OriginalNormalWeaponData[34].accuracy = 1.0f; OriginalNormalWeaponData[34].damage = 125; OriginalNormalWeaponData[34].life_span = 0.0f; @@ -1597,71 +1597,38 @@ bool CWeaponStatManager::LoadDefault(CWeaponStat* pDest, eWeaponType weaponType, return true; } -unsigned short CWeaponStatManager::GetSkillStatIndex(eWeaponType eWeapon) +eStats CWeaponStatManager::GetSkillStatIndex(eWeaponType weapon) { - switch (eWeapon) + switch (weapon) { case WEAPONTYPE_PISTOL: - { - return 46; - break; - } + return STAT_PISTOL_SKILL; case WEAPONTYPE_PISTOL_SILENCED: - { - return 47; - break; - } + return STAT_SILENCED_PISTOL_SKILL; case WEAPONTYPE_DESERT_EAGLE: - { - return 48; - break; - } + return STAT_DESERT_EAGLE_SKILL; case WEAPONTYPE_SHOTGUN: - { - return 49; - break; - } + return STAT_SHOTGUN_SKILL; case WEAPONTYPE_SAWNOFF_SHOTGUN: - { - return 50; - break; - } + return STAT_SAWN_OFF_SHOTGUN_SKILL; case WEAPONTYPE_SPAS12_SHOTGUN: - { - return 51; - break; - } + return STAT_COMBAT_SHOTGUN_SKILL; case WEAPONTYPE_MICRO_UZI: - case WEAPONTYPE_TEC9: - { - return 52; - break; - } + return STAT_MACHINE_PISTOL_SKILL; case WEAPONTYPE_MP5: - { - return 53; - break; - } - case WEAPONTYPE_M4: - { - return 54; - break; - } + return STAT_SMG_SKILL; case WEAPONTYPE_AK47: - { - return 55; - break; - } - case WEAPONTYPE_SNIPERRIFLE: + return STAT_AK_47_SKILL; + case WEAPONTYPE_M4: + return STAT_M4_SKILL; + case WEAPONTYPE_TEC9: + return STAT_MACHINE_PISTOL_SKILL; case WEAPONTYPE_COUNTRYRIFLE: - { - return 56; - break; - } + return STAT_RIFLE_SKILL; + case WEAPONTYPE_SNIPERRIFLE: + return STAT_RIFLE_SKILL; default: - { - return 0; - } + return static_cast(0); } } diff --git a/Server/mods/deathmatch/logic/CWeaponStatManager.h b/Server/mods/deathmatch/logic/CWeaponStatManager.h index 30daf995902..61ef6db791b 100644 --- a/Server/mods/deathmatch/logic/CWeaponStatManager.h +++ b/Server/mods/deathmatch/logic/CWeaponStatManager.h @@ -14,24 +14,24 @@ #include // Straight out of CGameSA.h -#define CLASSSIZE_WeaponInfo 112 // ##SA## -#define NUM_WeaponInfosStdSkill WEAPONTYPE_LAST_WEAPONTYPE -#define NUM_WeaponInfosOtherSkill 11 -#define NUM_WeaponInfosTotal (NUM_WeaponInfosStdSkill + (3*NUM_WeaponInfosOtherSkill)) // std, (poor, pro, special) +#define CLASSSIZE_WeaponInfo 112 // ##SA## +#define NUM_WeaponInfosStdSkill WEAPONTYPE_LAST_WEAPONTYPE +#define NUM_WeaponInfosOtherSkill 11 +#define NUM_WeaponInfosTotal (NUM_WeaponInfosStdSkill + (3 * NUM_WeaponInfosOtherSkill)) // std, (poor, pro, special) class CWeaponStat; struct sWeaponInfo { - eFireType fire_type; // type - instant hit (e.g. pistol), projectile (e.g. rocket launcher), area effect (e.g. flame thrower) + eFireType fire_type; // type - instant hit (e.g. pistol), projectile (e.g. rocket launcher), area effect (e.g. flame thrower) - FLOAT target_range; // max targeting range - FLOAT weapon_range; // absolute gun range / default melee attack range - int model; // modelinfo id - int model2; // second modelinfo id + FLOAT target_range; // max targeting range + FLOAT weapon_range; // absolute gun range / default melee attack range + int model; // modelinfo id + int model2; // second modelinfo id eWeaponSlot weapon_slot; - int flags; // flags defining characteristics + int flags; // flags defining characteristics // instead of storing pointers directly to anims, use anim association groups // NOTE: this is used for stealth kill anims for melee weapons @@ -40,39 +40,39 @@ struct sWeaponInfo ////////////////////////////////// // Gun Data ///////////////////////////////// - short maximum_clip_ammo; // ammo in one clip - short damage; // damage inflicted per hit - CVector fire_offset; // offset from weapon origin to projectile starting point + short maximum_clip_ammo; // ammo in one clip + short damage; // damage inflicted per hit + CVector fire_offset; // offset from weapon origin to projectile starting point // skill settings - eWeaponSkill skill_level; // what's the skill level of this weapontype - int required_skill_level; // what stat level is required for this skill level - FLOAT accuracy; // modify accuracy of weapon - FLOAT move_speed; // how fast can move with weapon + eWeaponSkill skill_level; // what's the skill level of this weapontype + int required_skill_level; // what stat level is required for this skill level + FLOAT accuracy; // modify accuracy of weapon + FLOAT move_speed; // how fast can move with weapon // anim timings - FLOAT anim_loop_start; // start of animation loop - FLOAT anim_loop_stop; // end of animation loop - FLOAT anim_loop_bullet_fire; // time in animation when weapon should be fired + FLOAT anim_loop_start; // start of animation loop + FLOAT anim_loop_stop; // end of animation loop + FLOAT anim_loop_bullet_fire; // time in animation when weapon should be fired - FLOAT anim2_loop_start; // start of animation2 loop - FLOAT anim2_loop_stop; // end of animation2 loop - FLOAT anim2_loop_bullet_fire; // time in animation2 when weapon should be fired + FLOAT anim2_loop_start; // start of animation2 loop + FLOAT anim2_loop_stop; // end of animation2 loop + FLOAT anim2_loop_bullet_fire; // time in animation2 when weapon should be fired - FLOAT anim_breakout_time; // time after which player can break out of attack and run off + FLOAT anim_breakout_time; // time after which player can break out of attack and run off // projectile/area effect specific info - FLOAT firing_speed; // speed of projectile - FLOAT radius; // radius affected - FLOAT life_span; // time taken for shot to dissipate - FLOAT spread; // angle inside which shots are created + FLOAT firing_speed; // speed of projectile + FLOAT radius; // radius affected + FLOAT life_span; // time taken for shot to dissipate + FLOAT spread; // angle inside which shots are created - short aim_offset; // index into array of aiming offsets + short aim_offset; // index into array of aiming offsets ////////////////////////////////// // Melee Data ///////////////////////////////// - BYTE default_combo; // base combo for this melee weapon - BYTE combos_available; // how many further combos are available + BYTE default_combo; // base combo for this melee weapon + BYTE combos_available; // how many further combos are available }; #define WEAPON_STAT_MAX 112 @@ -90,8 +90,8 @@ class CWeaponStatManager float GetWeaponRangeFromSkillLevel(eWeaponType eWeapon, float fSkillLevel); // Static Methods - static unsigned short GetSkillStatIndex(eWeaponType eWeapon); - static bool HasWeaponBulletSync(uint32_t weaponID) noexcept; + static eStats GetSkillStatIndex(eWeaponType weapon); + static bool HasWeaponBulletSync(uint32_t weaponID) noexcept; private: std::list m_OriginalWeaponData; diff --git a/Server/mods/deathmatch/logic/CXMLConfig.cpp b/Server/mods/deathmatch/logic/CXMLConfig.cpp index b66a1713f06..0c996febfb5 100644 --- a/Server/mods/deathmatch/logic/CXMLConfig.cpp +++ b/Server/mods/deathmatch/logic/CXMLConfig.cpp @@ -12,6 +12,9 @@ #include "StdInc.h" #include "CXMLConfig.h" +#include +#include + CXMLConfig::CXMLConfig(const char* szFileName) { m_pFile = NULL; @@ -92,30 +95,39 @@ int CXMLConfig::GetString(CXMLNode* pParent, const char* szKey, std::string& str int CXMLConfig::GetRGBA(CXMLNode* pParent, const char* szKey, unsigned char& R, unsigned char& G, unsigned char& B, unsigned char& A) { int Status = INVALID_VALUE; - int iR, iG, iB, iA; // Grab the XML node CXMLNode* pNode = pParent->FindSubNode(szKey); if (pNode) { - char cDelimiter; - std::istringstream iss; - - std::string strValue; - strValue = pNode->GetTagContent(); + const std::string strValue = pNode->GetTagContent(); - try - { - iss >> iR >> cDelimiter >> iG >> cDelimiter >> iB >> cDelimiter >> iA; - R = iR; - G = iG; - B = iB; - A = iA; - Status = IS_SUCCESS; - } - catch (std::ios::failure e) + const char* p = strValue.c_str(); + int values[4] = {0, 0, 0, 0}; + for (int i = 0; i < 4; ++i) { + while (*p && (std::isspace(static_cast(*p)) || *p == ',')) + ++p; + + if (!*p) + return INVALID_VALUE; + + char* end = nullptr; + const long v = std::strtol(p, &end, 10); + if (end == p) + return INVALID_VALUE; + if (v < 0 || v > 255) + return INVALID_VALUE; + + values[i] = static_cast(v); + p = end; } + + R = static_cast(values[0]); + G = static_cast(values[1]); + B = static_cast(values[2]); + A = static_cast(values[3]); + Status = IS_SUCCESS; } else Status = DOESNT_EXIST; diff --git a/Server/mods/deathmatch/logic/common/CBitStream.h b/Server/mods/deathmatch/logic/common/CBitStream.h index 3926256f59d..d345d3f5713 100644 --- a/Server/mods/deathmatch/logic/common/CBitStream.h +++ b/Server/mods/deathmatch/logic/common/CBitStream.h @@ -20,18 +20,22 @@ class CBitStream { pBitStream = g_pNetServer->AllocateNetServerBitStream(0, pData, uiDataSize, bCopyData); } + ~CBitStream() { g_pNetServer->DeallocateNetServerBitStream((NetBitStreamInterface*)pBitStream); }; - NetBitStreamInterfaceNoVersion* operator->() { return pBitStream; } - NetBitStreamInterfaceNoVersion* pBitStream; + NetBitStreamInterface* operator->() { return pBitStream; } + + NetBitStreamInterface* pBitStream; }; // Use this if Version() is required - Make sure the player is the once receiving/sending the data class CPlayerBitStream { public: - CPlayerBitStream(class CPlayer* pPlayer); // { pBitStream = g_pNetServer->AllocateNetServerBitStream ( pPlayer->GetBitStreamVersion() ); }; + CPlayerBitStream(class CPlayer* pPlayer); + ~CPlayerBitStream() { g_pNetServer->DeallocateNetServerBitStream((NetBitStreamInterface*)pBitStream); }; + NetBitStreamInterface* operator->() { return pBitStream; } NetBitStreamInterface* pBitStream; diff --git a/Server/mods/deathmatch/logic/lua/CLuaArgument.cpp b/Server/mods/deathmatch/logic/lua/CLuaArgument.cpp index b189658ee97..80721720057 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaArgument.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaArgument.cpp @@ -21,7 +21,7 @@ extern CGame* g_pGame; #ifndef VERIFY_ELEMENT -#define VERIFY_ELEMENT(element) (g_pGame->GetMapManager()->GetRootElement ()->IsMyChild(element,true)&&!element->IsBeingDeleted()) + #define VERIFY_ELEMENT(element) (g_pGame->GetMapManager()->GetRootElement()->IsMyChild(element, true) && !element->IsBeingDeleted()) #endif using namespace std; @@ -31,6 +31,7 @@ CLuaArgument::CLuaArgument() m_iType = LUA_TNIL; m_pTableData = NULL; m_pUserData = NULL; + m_bWeakTableRef = false; } CLuaArgument::CLuaArgument(const CLuaArgument& Argument, CFastHashMap* pKnownTables) @@ -240,62 +241,71 @@ void CLuaArgument::Read(lua_State* luaVM, int iArgument, CFastHashMap* pKnownTables) const { - // Got any type? - if (m_iType != LUA_TNONE) + // Make sure the stack has enough room + LUA_CHECKSTACK(luaVM, 1); + + // Push it depending on the type + switch (m_iType) { - // Make sure the stack has enough room - LUA_CHECKSTACK(luaVM, 1); + case LUA_TNIL: + { + lua_pushnil(luaVM); + break; + } - // Push it depending on the type - switch (m_iType) + case LUA_TBOOLEAN: { - case LUA_TNIL: - { - lua_pushnil(luaVM); - break; - } + lua_pushboolean(luaVM, m_bBoolean); + break; + } - case LUA_TBOOLEAN: - { - lua_pushboolean(luaVM, m_bBoolean); - break; - } + case LUA_TLIGHTUSERDATA: + case LUA_TUSERDATA: + { + lua_pushuserdata(luaVM, m_pUserData); + break; + } - case LUA_TLIGHTUSERDATA: - case LUA_TUSERDATA: - { - lua_pushuserdata(luaVM, m_pUserData); - break; - } + case LUA_TNUMBER: + { + lua_pushnumber(luaVM, m_Number); + break; + } - case LUA_TNUMBER: + case LUA_TTABLE: + { + if (!m_pTableData) { - lua_pushnumber(luaVM, m_Number); + lua_pushnil(luaVM); break; } - case LUA_TTABLE: + int* pTableId; + if (pKnownTables && (pTableId = MapFind(*pKnownTables, m_pTableData))) { - int* pThingy; - if (pKnownTables && (pThingy = MapFind(*pKnownTables, m_pTableData))) - { - lua_getfield(luaVM, LUA_REGISTRYINDEX, "cache"); - lua_pushnumber(luaVM, *pThingy); - lua_gettable(luaVM, -2); - lua_remove(luaVM, -2); - } - else - { - m_pTableData->PushAsTable(luaVM, pKnownTables); - } - break; + lua_getfield(luaVM, LUA_REGISTRYINDEX, "cache"); + lua_pushnumber(luaVM, *pTableId); + lua_gettable(luaVM, -2); + lua_remove(luaVM, -2); } - - case LUA_TSTRING: + else { - lua_pushlstring(luaVM, m_strString.c_str(), m_strString.length()); - break; + m_pTableData->PushAsTable(luaVM, pKnownTables); } + break; + } + + case LUA_TSTRING: + { + lua_pushlstring(luaVM, m_strString.c_str(), m_strString.length()); + break; + } + + default: + { + // Unexpected type, keep the stack balanced for callers + lua_pushnil(luaVM); + break; } } } @@ -339,6 +349,13 @@ void CLuaArgument::ReadString(const std::string_view& string) m_strString = string; } +void CLuaArgument::ReadString(const CStringName& string) +{ + m_iType = LUA_TSTRING; + DeleteTableData(); + m_strString = string.ToString(); +} + void CLuaArgument::ReadString(const char* string) { m_iType = LUA_TSTRING; @@ -421,6 +438,7 @@ bool CLuaArgument::GetAsString(SString& strBuffer) bool CLuaArgument::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables) { DeleteTableData(); + m_iType = LUA_TNIL; SLuaTypeSync type; // Read out the type @@ -477,7 +495,10 @@ bool CLuaArgument::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vect { m_pTableData = new CLuaArguments(); if (!m_pTableData->ReadFromBitStream(bitStream, pKnownTables)) + { + DeleteTableData(); return false; + } m_bWeakTableRef = false; m_iType = LUA_TTABLE; m_pTableData->ValidateTableKeys(); @@ -846,9 +867,9 @@ json_object* CLuaArgument::WriteToJSONObject(bool bSerialize, CFastHashMapGetScriptDebugging()->LogError(NULL, "Couldn't convert userdata argument to JSON, elements not allowed for this function."); - else if (!bSerialize) // eg toJSON() with invalid element + else if (!bSerialize) // eg toJSON() with invalid element g_pGame->GetScriptDebugging()->LogError( NULL, "Couldn't convert userdata argument to JSON, only valid resources can be included for this function."); else @@ -1031,7 +1052,7 @@ bool CLuaArgument::ReadFromJSONObject(json_object* object, std::vectorGetResourceManager()->GetResource(strString.c_str() + 3); if (resource) @@ -1063,7 +1084,7 @@ bool CLuaArgument::ReadFromJSONObject(json_object* object, std::vector(atol(strString.c_str() + 3)); if (pKnownTables && ulTableID < pKnownTables->size()) diff --git a/Server/mods/deathmatch/logic/lua/CLuaArgument.h b/Server/mods/deathmatch/logic/lua/CLuaArgument.h index db11a1676b4..2ecf4114d48 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaArgument.h +++ b/Server/mods/deathmatch/logic/lua/CLuaArgument.h @@ -15,7 +15,7 @@ extern "C" { - #include "lua.h" +#include "lua.h" } #include "../common/CBitStream.h" #include "json.h" @@ -23,7 +23,7 @@ extern "C" class CElement; class CLuaArguments; -#define LUA_TTABLEREF 9 +#define LUA_TTABLEREF 9 #define LUA_TSTRING_LONG 10 class CLuaArgument @@ -45,6 +45,7 @@ class CLuaArgument void ReadNumber(double dNumber); void ReadString(const std::string& string); void ReadString(const std::string_view& string); + void ReadString(const CStringName& string); void ReadString(const char* string); void ReadElement(CElement* pElement); void ReadElementID(ElementID ID); diff --git a/Server/mods/deathmatch/logic/lua/CLuaArguments.cpp b/Server/mods/deathmatch/logic/lua/CLuaArguments.cpp index ac580b2a54b..0cf0fd73d08 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaArguments.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaArguments.cpp @@ -22,13 +22,13 @@ #include "CAccessControlListGroup.h" #ifndef WIN32 -#include + #include #endif extern CGame* g_pGame; #ifndef VERIFY_ELEMENT -#define VERIFY_ELEMENT(element) (g_pGame->GetMapManager()->GetRootElement()->IsMyChild(element, true) && !element->IsBeingDeleted()) + #define VERIFY_ELEMENT(element) (g_pGame->GetMapManager()->GetRootElement()->IsMyChild(element, true) && !element->IsBeingDeleted()) #endif CLuaArguments::CLuaArguments(const CLuaArguments& Arguments, CFastHashMap* pKnownTables) @@ -120,10 +120,10 @@ void CLuaArguments::ReadTable(lua_State* luaVM, int iIndexBegin, CFastHashMap::const_iterator iter = m_Arguments.begin(); for (; iter != m_Arguments.end() && (iter + 1) != m_Arguments.end(); ++iter) { - (*iter)->Push(luaVM, pKnownTables); // index + (*iter)->Push(luaVM, pKnownTables); // index ++iter; - (*iter)->Push(luaVM, pKnownTables); // value + (*iter)->Push(luaVM, pKnownTables); // value lua_settable(luaVM, -3); } @@ -231,7 +231,7 @@ bool CLuaArguments::Call(CLuaMain* pLuaMain, const CLuaFunctionRef& iLuaFunction while (lua_gettop(luaVM) - luaStackPointer > 0) lua_pop(luaVM, 1); - return false; // the function call failed + return false; // the function call failed } else { @@ -295,7 +295,7 @@ bool CLuaArguments::CallGlobal(CLuaMain* pLuaMain, const char* szFunction, CLuaA while (lua_gettop(luaVM) - luaStackPointer > 0) lua_pop(luaVM, 1); - return false; // the function call failed + return false; // the function call failed } else { @@ -351,7 +351,7 @@ CLuaArgument* CLuaArguments::PushNumber(double dNumber) CLuaArgument* CLuaArguments::PushArgument(const CLuaArgument& argument) { - CLuaArgument* pArgument = new CLuaArgument(argument); // create a copy + CLuaArgument* pArgument = new CLuaArgument(argument); // create a copy m_Arguments.push_back(pArgument); return pArgument; } @@ -372,6 +372,14 @@ CLuaArgument* CLuaArguments::PushString(const std::string_view& string) return arg; } +CLuaArgument* CLuaArguments::PushString(const CStringName& string) +{ + CLuaArgument* arg = new CLuaArgument(); + arg->ReadString(string); + m_Arguments.push_back(arg); + return arg; +} + CLuaArgument* CLuaArguments::PushString(const char* string) { CLuaArgument* arg = new CLuaArgument(); @@ -532,6 +540,15 @@ bool CLuaArguments::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vec unsigned int uiNumArgs; if (bitStream.ReadCompressed(uiNumArgs)) { + // Each argument needs at least 4 bits (SLuaTypeSync), reject obviously corrupt counts + int unreadBits = bitStream.GetNumberOfUnreadBits(); + if (unreadBits < 0 || uiNumArgs > static_cast(unreadBits) / 4) + { + if (bKnownTablesCreated) + delete pKnownTables; + return false; + } + pKnownTables->push_back(this); for (unsigned int ui = 0; ui < uiNumArgs; ++ui) { @@ -588,7 +605,7 @@ bool CLuaArguments::WriteToJSONString(std::string& strJSON, bool bSerialize, int if (my_array) { strJSON = json_object_to_json_string_ext(my_array, flags); - json_object_put(my_array); // dereference - causes a crash, is actually commented out in the example too + json_object_put(my_array); // dereference - causes a crash, is actually commented out in the example too return true; } return false; @@ -623,49 +640,53 @@ json_object* CLuaArguments::WriteTableToJSONObject(bool bSerialize, CFastHashMap bKnownTablesCreated = true; } - pKnownTables->insert(std::make_pair(this, pKnownTables->size())); + pKnownTables->insert({this, pKnownTables->size()}); - bool bIsArray = true; - unsigned int iArrayPos = 1; // lua arrays are 1 based - vector::const_iterator iter = m_Arguments.begin(); + bool bIsArray = true; + std::vector> vecSortedArguments; // lua arrays are not necessarily sorted + std::vector::const_iterator iter = m_Arguments.begin(); for (; iter != m_Arguments.end(); iter += 2) { CLuaArgument* pArgument = *iter; if (pArgument->GetType() == LUA_TNUMBER) { - double num = pArgument->GetNumber(); - unsigned int iNum = static_cast(num); - if (num == iNum) - { - if (iArrayPos != iNum) // check if the value matches its index in the table - { - bIsArray = false; - break; - } - } - else - { - bIsArray = false; - break; - } + double const num = pArgument->GetNumber(); + auto const iNum = static_cast(num); + + vecSortedArguments.push_back({iNum, *(iter + 1)}); } else { bIsArray = false; break; } - iArrayPos++; } - if (bIsArray) + if (bIsArray && !vecSortedArguments.empty()) // the table could possibly be an array { - json_object* my_array = json_object_new_array(); - vector::const_iterator iter = m_Arguments.begin(); - for (; iter != m_Arguments.end(); ++iter) + // sort the table based on the keys (already handled correctly by std::pair) + std::sort(vecSortedArguments.begin(), vecSortedArguments.end()); + + // only the first and last element are checked, everything else is correct by default because the vector was sorted + // the last key should match the size of vecSortedArguments to ensure there are no gaps in this array-like table + auto const iFirstKey = vecSortedArguments.front().first; + auto const iLastKey = vecSortedArguments.back().first; + + auto const iFirstArrayPos = 1U; // lua arrays are 1 based + auto const iLastArrayPos = static_cast(vecSortedArguments.size()); + + if (iFirstKey != iFirstArrayPos || iLastKey != iLastArrayPos) { - iter++; // skip the key values - CLuaArgument* pArgument = *iter; - json_object* object = pArgument->WriteToJSONObject(bSerialize, pKnownTables); + bIsArray = false; + } + } + + if (bIsArray) // the table is definitely an array + { + json_object* my_array = json_object_new_array(); + for (auto const& [iKey, pArgument] : vecSortedArguments) + { + json_object* object = pArgument->WriteToJSONObject(bSerialize, pKnownTables); if (object) { json_object_array_add(my_array, object); @@ -688,11 +709,11 @@ json_object* CLuaArguments::WriteTableToJSONObject(bool bSerialize, CFastHashMap char szKey[255]; szKey[0] = '\0'; CLuaArgument* pArgument = *iter; - if (!pArgument->WriteToString(szKey, 255)) // index + if (!pArgument->WriteToString(szKey, 255)) // index break; ++iter; pArgument = *iter; - json_object* object = pArgument->WriteToJSONObject(bSerialize, pKnownTables); // value + json_object* object = pArgument->WriteToJSONObject(bSerialize, pKnownTables); // value if (object) { @@ -736,11 +757,11 @@ bool CLuaArguments::ReadFromJSONString(const char* szJSON) json_object* arrayObject = json_object_array_get_idx(object, i); CLuaArgument* pArgument = new CLuaArgument(); bSuccess = pArgument->ReadFromJSONObject(arrayObject, &knownTables); - m_Arguments.push_back(pArgument); // then the value + m_Arguments.push_back(pArgument); // then the value if (!bSuccess) break; } - json_object_put(object); // dereference + json_object_put(object); // dereference return bSuccess; } else if (json_object_get_type(object) == json_type_object) @@ -748,12 +769,12 @@ bool CLuaArguments::ReadFromJSONString(const char* szJSON) std::vector knownTables; CLuaArgument* pArgument = new CLuaArgument(); bool bSuccess = pArgument->ReadFromJSONObject(object, &knownTables); - m_Arguments.push_back(pArgument); // value + m_Arguments.push_back(pArgument); // value json_object_put(object); return bSuccess; } - json_object_put(object); // dereference + json_object_put(object); // dereference } // else // g_pGame->GetScriptDebugging()->LogError ( "Could not parse invalid JSON object."); @@ -782,9 +803,9 @@ bool CLuaArguments::ReadFromJSONObject(json_object* object, std::vectorReadString(key); - m_Arguments.push_back(pArgument); // push the key first + m_Arguments.push_back(pArgument); // push the key first pArgument = new CLuaArgument(); - bSuccess = pArgument->ReadFromJSONObject(val, pKnownTables); // then the value + bSuccess = pArgument->ReadFromJSONObject(val, pKnownTables); // then the value m_Arguments.push_back(pArgument); if (!bSuccess) break; @@ -820,12 +841,12 @@ bool CLuaArguments::ReadFromJSONArray(json_object* object, std::vectorReadNumber(i + 1); // push the key + pArgument->ReadNumber(i + 1); // push the key m_Arguments.push_back(pArgument); pArgument = new CLuaArgument(); bSuccess = pArgument->ReadFromJSONObject(arrayObject, pKnownTables); - m_Arguments.push_back(pArgument); // then the valoue + m_Arguments.push_back(pArgument); // then the valoue if (!bSuccess) break; } diff --git a/Server/mods/deathmatch/logic/lua/CLuaArguments.h b/Server/mods/deathmatch/logic/lua/CLuaArguments.h index c41e58eeeee..3c550799d26 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaArguments.h +++ b/Server/mods/deathmatch/logic/lua/CLuaArguments.h @@ -13,7 +13,7 @@ extern "C" { - #include "lua.h" +#include "lua.h" } #include "CLuaArgument.h" @@ -69,6 +69,7 @@ class CLuaArguments CLuaArgument* PushNumber(double dNumber); CLuaArgument* PushString(const std::string& string); CLuaArgument* PushString(const std::string_view& string); + CLuaArgument* PushString(const CStringName& string); CLuaArgument* PushString(const char* string); CLuaArgument* PushElement(CElement* pElement); CLuaArgument* PushBan(CBan* pBan); diff --git a/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp b/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp index b91b79fdaef..ffe4133f790 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -78,6 +78,9 @@ ADD_ENUM(HUD_MONEY, "money") ADD_ENUM(HUD_VEHICLE_NAME, "vehicle_name") ADD_ENUM(HUD_AREA_NAME, "area_name") ADD_ENUM(HUD_RADAR, "radar") +ADD_ENUM(HUD_RADAR_MAP, "radar_map") +ADD_ENUM(HUD_RADAR_BLIPS, "radar_blips") +ADD_ENUM(HUD_RADAR_ALTIMETER, "radar_altimeter") ADD_ENUM(HUD_CLOCK, "clock") ADD_ENUM(HUD_RADIO, "radio") ADD_ENUM(HUD_WANTED, "wanted") @@ -313,12 +316,11 @@ CXMLNode* UserDataCast(CXMLNode* ptr, lua_State* luaState) // CLuaTimer* UserDataCast(CLuaTimer* ptr, lua_State* luaState) { - if (CLuaMain* luaMain = g_pGame->GetLuaManager()->GetVirtualMachine(luaState); luaMain != nullptr) - { - return luaMain->GetTimerManager()->GetTimerFromScriptID(reinterpret_cast(ptr)); - } + CLuaManager* luaManager = g_pGame->GetLuaManager(); + if (!luaManager) + return nullptr; - return nullptr; + return luaManager->FindTimerGlobally(reinterpret_cast(ptr)); } // @@ -494,13 +496,13 @@ CClient* UserDataCast(CClient* ptr, lua_State* luaState) // SString GetUserDataClassName(void* ptr, lua_State* luaVM, bool bFindElementType) { - if (CElement* pVar = UserDataCast((CElement*)ptr, luaVM)) // Try element + if (CElement* pVar = UserDataCast((CElement*)ptr, luaVM)) // Try element return bFindElementType ? pVar->GetTypeName() : GetClassTypeName(pVar); - if (auto* pVar = UserDataCast(static_cast(ptr), luaVM)) // Try resource + if (auto* pVar = UserDataCast(static_cast(ptr), luaVM)) // Try resource return GetClassTypeName(pVar); - if (auto* pVar = UserDataCast((CXMLNode*)ptr, luaVM)) // Try xml node + if (auto* pVar = UserDataCast((CXMLNode*)ptr, luaVM)) // Try xml node return GetClassTypeName(pVar); - if (auto* pVar = UserDataCast((CLuaTimer*)ptr, luaVM)) // Try timer + if (auto* pVar = UserDataCast((CLuaTimer*)ptr, luaVM)) // Try timer return GetClassTypeName(pVar); if (auto* pVar = UserDataCast((CAccount*)ptr, luaVM)) return GetClassTypeName(pVar); @@ -593,9 +595,9 @@ void MinServerReqCheck(CScriptArgReader& argStream, const char* szVersionReq, co { if (pResource->GetMinServerRequirement() < szVersionReq) { - #if MTASA_VERSION_TYPE == VERSION_TYPE_RELEASE +#if MTASA_VERSION_TYPE >= VERSION_TYPE_UNTESTED argStream.SetVersionWarning(szVersionReq, "server", szReason); - #endif +#endif } } } diff --git a/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h b/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h index 62d4312c51e..1d5bc7feee7 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h +++ b/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h @@ -56,6 +56,11 @@ enum eHudComponent HUD_WANTED, HUD_CROSSHAIR, HUD_ALL, + HUD_VITAL_STATS, // Unused on server, but used on client side + HUD_HELP_TEXT, // Unused on server, but used on client side + HUD_RADAR_MAP, + HUD_RADAR_BLIPS, + HUD_RADAR_ALTIMETER, }; DECLARE_ENUM(eHudComponent); diff --git a/Server/mods/deathmatch/logic/lua/CLuaFunctionRef.cpp b/Server/mods/deathmatch/logic/lua/CLuaFunctionRef.cpp index 935d0275854..39902037b31 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaFunctionRef.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaFunctionRef.cpp @@ -15,7 +15,7 @@ #include "CGame.h" #ifdef WIN32 - #pragma warning( disable : 4355 ) // warning C4355: 'this' : used in base member initializer list + #pragma warning(disable : 4355) // warning C4355: 'this' : used in base member initializer list #endif struct lua_State; diff --git a/Server/mods/deathmatch/logic/lua/CLuaFunctionRef.h b/Server/mods/deathmatch/logic/lua/CLuaFunctionRef.h index 79e9d2a41f4..b7da904de41 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaFunctionRef.h +++ b/Server/mods/deathmatch/logic/lua/CLuaFunctionRef.h @@ -11,9 +11,9 @@ #pragma once -#define LUA_REFNIL (-1) -#define VERIFY_FUNCTION(func) ( (func).ToInt () != LUA_REFNIL ) -#define IS_REFNIL(func) ( (func).ToInt () == LUA_REFNIL ) +#define LUA_REFNIL (-1) +#define VERIFY_FUNCTION(func) ((func).ToInt() != LUA_REFNIL) +#define IS_REFNIL(func) ((func).ToInt() == LUA_REFNIL) struct lua_State; diff --git a/Server/mods/deathmatch/logic/lua/CLuaMain.cpp b/Server/mods/deathmatch/logic/lua/CLuaMain.cpp index 9d3dd0ac5c8..b3c093f27e0 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaMain.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaMain.cpp @@ -53,7 +53,7 @@ static CLuaManager* m_pLuaManager; SString CLuaMain::ms_strExpectedUndumpHash; #define HOOK_INSTRUCTION_COUNT 1000000 -#define HOOK_MAXIMUM_TIME 5000 +#define HOOK_MAXIMUM_TIME 5000 extern CGame* g_pGame; extern CNetServer* g_pRealNetServer; @@ -172,7 +172,7 @@ void CLuaMain::InitClasses(lua_State* luaVM) if (!m_bEnableOOP) return; - CLuaElementDefs ::AddClass(luaVM); // keep this at the top because inheritance + CLuaElementDefs ::AddClass(luaVM); // keep this at the top because inheritance CLuaAccountDefs ::AddClass(luaVM); CLuaACLDefs ::AddClass(luaVM); CLuaBanDefs ::AddClass(luaVM); @@ -307,7 +307,7 @@ bool CLuaMain::LoadScriptFromBuffer(const char* cpInBuffer, unsigned int uiInSiz { std::string strBuffer = std::string(cpBuffer, uiSize); #ifdef WIN32 - std::setlocale(LC_CTYPE, ""); // Temporarilly use locales to read the script + std::setlocale(LC_CTYPE, ""); // Temporarilly use locales to read the script strUTFScript = UTF16ToMbUTF8(ANSIToUTF16(strBuffer)); std::setlocale(LC_CTYPE, "C"); #else @@ -604,14 +604,14 @@ const SString& CLuaMain::GetFunctionTag(int iLuaFunction) strText = SString("@func_%d NULL", iLuaFunction); } - #ifdef CHECK_FUNCTION_TAG +#ifdef CHECK_FUNCTION_TAG if (pTag) { // Check tag remains unchanged assert(strText == *pTag); return *pTag; } - #endif +#endif MapSet(m_FunctionTagMap, iLuaFunction, strText); pTag = MapFind(m_FunctionTagMap, iLuaFunction); @@ -629,7 +629,7 @@ const SString& CLuaMain::GetFunctionTag(int iLuaFunction) int CLuaMain::PCall(lua_State* L, int nargs, int nresults, int errfunc) { if (m_uiPCallDepth++ == 0) - m_WarningTimer.Reset(); // Only restart timer if initial call + m_WarningTimer.Reset(); // Only restart timer if initial call g_pGame->GetScriptDebugging()->PushLuaMain(this); int iret = lua_pcall(L, nargs, nresults, errfunc); diff --git a/Server/mods/deathmatch/logic/lua/CLuaMain.h b/Server/mods/deathmatch/logic/lua/CLuaMain.h index c78c2324956..6e64c4088d9 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaMain.h +++ b/Server/mods/deathmatch/logic/lua/CLuaMain.h @@ -35,7 +35,7 @@ struct CRefInfo int iFunction; }; -class CLuaMain //: public CClient +class CLuaMain //: public CClient { public: ZERO_ON_NEW @@ -140,7 +140,7 @@ class CLuaMain //: public CClient bool m_bEnableOOP; - bool m_bBeingDeleted; // prevent it being deleted twice + bool m_bBeingDeleted; // prevent it being deleted twice CElapsedTime m_FunctionEnterTimer; CElapsedTimeApprox m_WarningTimer; diff --git a/Server/mods/deathmatch/logic/lua/CLuaManager.cpp b/Server/mods/deathmatch/logic/lua/CLuaManager.cpp index a5c1264c0ea..abae51389ff 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaManager.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaManager.cpp @@ -43,6 +43,7 @@ #include "luadefs/CLuaVoiceDefs.h" #include "luadefs/CLuaWorldDefs.h" #include "luadefs/CLuaCompatibilityDefs.h" +#include "CIdArray.h" extern CGame* g_pGame; @@ -166,7 +167,7 @@ CLuaMain* CLuaManager::GetVirtualMachine(lua_State* luaVM) { if (luaVM == (*iter)->GetVirtualMachine()) { - dassert(0); // Why not in map? + dassert(0); // Why not in map? return *iter; } } @@ -184,6 +185,35 @@ CResource* CLuaManager::GetVirtualMachineResource(lua_State* luaVM) return NULL; } +CLuaTimer* CLuaManager::FindTimerGlobally(unsigned long scriptID) const +{ + // First check if timer exists in global ID system + CLuaTimer* luaTimer = static_cast(CIdArray::FindEntry(scriptID, EIdClass::TIMER)); + if (!luaTimer) + return nullptr; + + // Verify timer exists in any resource manager (ensures it's still valid) + for (std::list::const_iterator iter = m_virtualMachines.begin(); iter != m_virtualMachines.end(); ++iter) + { + CLuaMain* luaMain = *iter; + if (!luaMain) + continue; + + CLuaTimerManager* timerManager = luaMain->GetTimerManager(); + if (!timerManager) + continue; + + if (timerManager->GetTimerFromScriptID(scriptID) == luaTimer) + { + return luaTimer; + } + } + + // Timer exists in global ID array but not in any resource manager + // This indicates the timer has been cleaned up + return nullptr; +} + void CLuaManager::LoadCFunctions() { // Load the functions from our classes diff --git a/Server/mods/deathmatch/logic/lua/CLuaManager.h b/Server/mods/deathmatch/logic/lua/CLuaManager.h index dd4277b26fb..575d3444333 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaManager.h +++ b/Server/mods/deathmatch/logic/lua/CLuaManager.h @@ -22,6 +22,7 @@ class CLuaManager; // Predeclarations class CBlipManager; class CEvents; +class CLuaTimer; class CMapManager; class CObjectManager; class CPlayerManager; @@ -52,6 +53,8 @@ class CLuaManager void LoadCFunctions(); + CLuaTimer* FindTimerGlobally(unsigned long scriptID) const; + private: CBlipManager* m_pBlipManager; CObjectManager* m_pObjectManager; diff --git a/Server/mods/deathmatch/logic/lua/CLuaModule.cpp b/Server/mods/deathmatch/logic/lua/CLuaModule.cpp index 2e561bfbe1d..e616e954124 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaModule.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaModule.cpp @@ -11,6 +11,21 @@ #include "StdInc.h" #include "CLuaModule.h" + +#include + +#ifdef WIN32 +template +static T GetProcAddressAs(HMODULE module, const char* procName) +{ + FARPROC proc = module ? GetProcAddress(module, procName) : nullptr; + T fn = nullptr; + static_assert(sizeof(fn) == sizeof(proc), "Unexpected function pointer size"); + if (proc) + std::memcpy(&fn, &proc, sizeof(fn)); + return fn; +} +#endif #include "CLuaModuleManager.h" #include "CScriptDebugging.h" #include "CStaticFunctionDefinitions.h" @@ -95,20 +110,20 @@ int CLuaModule::_LoadModule() CLogger::LogPrintf("MODULE: File not found - %s\n", *strExpectedPathFilename); } else - #ifdef WIN_x64 +#ifdef WIN_x64 if (IsModule32Bit(strExpectedPathFilename)) { CLogger::LogPrintf("MODULE: File not 64 bit - %s\n", *strExpectedPathFilename); } else - #endif - #ifdef WIN_x86 +#endif +#ifdef WIN_x86 if (!IsModule32Bit(strExpectedPathFilename)) { CLogger::LogPrintf("MODULE: File not 32 bit - %s\n", *strExpectedPathFilename); } else - #endif +#endif { CLogger::LogPrintf("MODULE: Unable to load %s (%s)\n", *strExpectedPathFilename, *strError); } @@ -117,14 +132,14 @@ int CLuaModule::_LoadModule() // Find the initialisation function #ifdef WIN32 - pfnInitFunc = (InitModuleFunc)(GetProcAddress(m_hModule, "InitModule")); + pfnInitFunc = GetProcAddressAs(m_hModule, "InitModule"); if (pfnInitFunc == NULL) { CLogger::LogPrintf("MODULE: Unable to initialize %s!\n", *PathJoin(SERVER_BIN_PATH_MOD, "modules", m_szShortFileName)); return 2; } #else - pfnInitFunc = (InitModuleFunc)(dlsym(m_hModule, "InitModule")); + pfnInitFunc = reinterpret_cast(dlsym(m_hModule, "InitModule")); if (dlerror() != NULL) { CLogger::LogPrintf("MODULE: Unable to initialize %s (%s)!\n", *PathJoin(SERVER_BIN_PATH_MOD, "modules", m_szShortFileName), dlerror()); @@ -135,35 +150,35 @@ int CLuaModule::_LoadModule() // Initialise m_FunctionInfo.szFileName = m_szShortFileName; #ifdef WIN32 - m_FunctionInfo.DoPulse = (DefaultModuleFunc)(GetProcAddress(m_hModule, "DoPulse")); + m_FunctionInfo.DoPulse = GetProcAddressAs(m_hModule, "DoPulse"); if (m_FunctionInfo.DoPulse == NULL) return 3; - m_FunctionInfo.ShutdownModule = (DefaultModuleFunc)(GetProcAddress(m_hModule, "ShutdownModule")); + m_FunctionInfo.ShutdownModule = GetProcAddressAs(m_hModule, "ShutdownModule"); if (m_FunctionInfo.ShutdownModule == NULL) return 4; - m_FunctionInfo.RegisterFunctions = (RegisterModuleFunc)(GetProcAddress(m_hModule, "RegisterFunctions")); + m_FunctionInfo.RegisterFunctions = GetProcAddressAs(m_hModule, "RegisterFunctions"); if (m_FunctionInfo.RegisterFunctions == NULL) return 5; - m_FunctionInfo.ResourceStopping = (RegisterModuleFunc)(GetProcAddress(m_hModule, "ResourceStopping")); + m_FunctionInfo.ResourceStopping = GetProcAddressAs(m_hModule, "ResourceStopping"); // No error for backward compatibility // if ( m_FunctionInfo.ResourceStopping == NULL ) return 6; - m_FunctionInfo.ResourceStopped = (RegisterModuleFunc)(GetProcAddress(m_hModule, "ResourceStopped")); + m_FunctionInfo.ResourceStopped = GetProcAddressAs(m_hModule, "ResourceStopped"); // if ( m_FunctionInfo.ResourceStopped == NULL ) return 7; #else - m_FunctionInfo.DoPulse = (DefaultModuleFunc)(dlsym(m_hModule, "DoPulse")); + m_FunctionInfo.DoPulse = reinterpret_cast(dlsym(m_hModule, "DoPulse")); if (m_FunctionInfo.DoPulse == NULL) return 3; - m_FunctionInfo.ShutdownModule = (DefaultModuleFunc)(dlsym(m_hModule, "ShutdownModule")); + m_FunctionInfo.ShutdownModule = reinterpret_cast(dlsym(m_hModule, "ShutdownModule")); if (m_FunctionInfo.ShutdownModule == NULL) return 4; - m_FunctionInfo.RegisterFunctions = (RegisterModuleFunc)(dlsym(m_hModule, "RegisterFunctions")); + m_FunctionInfo.RegisterFunctions = reinterpret_cast(dlsym(m_hModule, "RegisterFunctions")); if (m_FunctionInfo.RegisterFunctions == NULL) return 5; - m_FunctionInfo.ResourceStopping = (RegisterModuleFunc)(dlsym(m_hModule, "ResourceStopping")); + m_FunctionInfo.ResourceStopping = reinterpret_cast(dlsym(m_hModule, "ResourceStopping")); // if ( m_FunctionInfo.ResourceStopping == NULL ) return 6; - m_FunctionInfo.ResourceStopped = (RegisterModuleFunc)(dlsym(m_hModule, "ResourceStopped")); + m_FunctionInfo.ResourceStopped = reinterpret_cast(dlsym(m_hModule, "ResourceStopped")); // if ( m_FunctionInfo.ResourceStopped == NULL ) return 7; #endif // Run initialisation function @@ -285,7 +300,7 @@ bool CLuaModule::RegisterFunction(lua_State* luaVM, const char* szFunctionName, CLuaCFunctions::AddFunction(szFunctionName, Func); lua_register(luaVM, szFunctionName, Func); if (!_DoesFunctionExist(szFunctionName)) - { // Check or it adds for each resource + { // Check or it adds for each resource m_Functions.push_back(szFunctionName); } } diff --git a/Server/mods/deathmatch/logic/lua/CLuaModule.h b/Server/mods/deathmatch/logic/lua/CLuaModule.h index 38558c370ec..fcac556c594 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaModule.h +++ b/Server/mods/deathmatch/logic/lua/CLuaModule.h @@ -59,7 +59,7 @@ class CLuaModule : public ILuaModuleManager10 void DebugPrintf(lua_State* luaVM, const char* szFormat, ...); bool RegisterFunction(lua_State* luaVM, const char* szFunctionName, lua_CFunction Func); bool GetResourceName(lua_State* luaVM, - std::string& strName); // This function might not work if module and MTA were compiled with different compiler versions + std::string& strName); // This function might not work if module and MTA were compiled with different compiler versions CChecksum GetResourceMetaChecksum(lua_State* luaVM); CChecksum GetResourceFileChecksum(lua_State* luaVM, const char* szFile); diff --git a/Server/mods/deathmatch/logic/lua/CLuaModuleManager.cpp b/Server/mods/deathmatch/logic/lua/CLuaModuleManager.cpp index 9b5f52bd45b..766747fc8e8 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaModuleManager.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaModuleManager.cpp @@ -55,7 +55,7 @@ void CLuaModuleManager::DoPulse() } int CLuaModuleManager::LoadModule(const char* szShortFileName, const char* szFileName, bool bLateLoad) -{ // 0 = Success, 1 = Can't find file, 2 = Can't find initialise function, 3 = can't find dopulse function, +{ // 0 = Success, 1 = Can't find file, 2 = Can't find initialise function, 3 = can't find dopulse function, // 4 = can't find shutdownmodule function, 5 = can't find register function, 6 = can't find resourcestopping function // 7 = can't find resourcestopped function, 8 = resource already loaded @@ -112,7 +112,7 @@ int CLuaModuleManager::ReloadModule(const char* szShortFileName, const char* szF } int CLuaModuleManager::UnloadModule(const char* szShortFileName) -{ // 0 = Success, 9 = Can't find module by name +{ // 0 = Success, 9 = Can't find module by name list::iterator iter = m_Modules.begin(); for (; iter != m_Modules.end(); ++iter) { diff --git a/Server/mods/deathmatch/logic/lua/LuaCommon.cpp b/Server/mods/deathmatch/logic/lua/LuaCommon.cpp index bcbe670fe22..ba4a131e885 100644 --- a/Server/mods/deathmatch/logic/lua/LuaCommon.cpp +++ b/Server/mods/deathmatch/logic/lua/LuaCommon.cpp @@ -250,7 +250,7 @@ void lua_pushobject(lua_State* luaVM, const char* szClass, void* pObject, bool b // Assign the class metatable lua_getclass(luaVM, szClass); - lua_setmetatable(luaVM, -2); // element + lua_setmetatable(luaVM, -2); // element } void lua_pushvector(lua_State* luaVM, const CVector4D& vector) @@ -342,30 +342,30 @@ void lua_newclass(lua_State* luaVM) void lua_getclass(lua_State* luaVM, const char* szName) { - lua_pushstring(luaVM, "mt"); // "mt" - lua_rawget(luaVM, LUA_REGISTRYINDEX); // mt + lua_pushstring(luaVM, "mt"); // "mt" + lua_rawget(luaVM, LUA_REGISTRYINDEX); // mt assert(lua_istable(luaVM, -1)); - lua_pushstring(luaVM, szName); // mt, class name - lua_rawget(luaVM, -2); // mt, class + lua_pushstring(luaVM, szName); // mt, class name + lua_rawget(luaVM, -2); // mt, class - lua_remove(luaVM, -2); // class + lua_remove(luaVM, -2); // class } void lua_registerclass(lua_State* luaVM, const char* szName, const char* szParent, bool bRegisterWithEnvironment) { if (szParent != NULL) { - lua_pushstring(luaVM, "mt"); // class table, "mt" - lua_rawget(luaVM, LUA_REGISTRYINDEX); // class table, mt table - lua_getfield(luaVM, -1, szParent); // class table, mt table, parent table + lua_pushstring(luaVM, "mt"); // class table, "mt" + lua_rawget(luaVM, LUA_REGISTRYINDEX); // class table, mt table + lua_getfield(luaVM, -1, szParent); // class table, mt table, parent table assert(lua_istable(luaVM, -1)); - lua_setfield(luaVM, -3, "__parent"); // class table, mt table + lua_setfield(luaVM, -3, "__parent"); // class table, mt table - lua_pop(luaVM, 1); // class table + lua_pop(luaVM, 1); // class table } lua_pushstring(luaVM, "mt"); diff --git a/Server/mods/deathmatch/logic/lua/LuaCommon.h b/Server/mods/deathmatch/logic/lua/LuaCommon.h index a62a0205161..1b7389519d8 100644 --- a/Server/mods/deathmatch/logic/lua/LuaCommon.h +++ b/Server/mods/deathmatch/logic/lua/LuaCommon.h @@ -13,9 +13,9 @@ extern "C" { - #include "lua.h" - #include "lualib.h" - #include "lauxlib.h" +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" } #include "CLuaFunctionRef.h" diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaACLDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaACLDefs.cpp index 28659f4edb2..0307318c578 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaACLDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaACLDefs.cpp @@ -888,7 +888,7 @@ int CLuaACLDefs::aclGroupRemoveObject(lua_State* luaVM) int CLuaACLDefs::hasObjectPermissionTo(lua_State* luaVM) { - // bool hasObjectPermissionTo ( string / element theObject, string theAction [, bool defaultPermission = true ] ) + // bool hasObjectPermissionTo ( string / element theObject, string theAction [, bool defaultPermission = false ] ) CResource* pResource = NULL; CElement* pElement = NULL; SString strObject; @@ -905,7 +905,7 @@ int CLuaACLDefs::hasObjectPermissionTo(lua_State* luaVM) argStream.ReadString(strObject); argStream.ReadString(strRightName); - argStream.ReadBool(bDefault, true); + argStream.ReadBool(bDefault, false); if (!argStream.HasErrors()) { @@ -1055,7 +1055,7 @@ int CLuaACLDefs::OOP_isObjectInACLGroup(lua_State* luaVM) std::vector CLuaACLDefs::aclObjectGetGroups(std::string strObject) { CAccessControlListGroupObject::EObjectType objectType; - const char* szObjectAfterDot = strObject.c_str(); + const char* szObjectAfterDot = strObject.c_str(); if (StringBeginsWith(szObjectAfterDot, "resource.")) { szObjectAfterDot += 9; @@ -1071,8 +1071,7 @@ std::vector CLuaACLDefs::aclObjectGetGroups(std::strin std::vector groups; - for (auto iter = m_pACLManager->Groups_Begin(); - iter != m_pACLManager->Groups_End(); ++iter) + for (auto iter = m_pACLManager->Groups_Begin(); iter != m_pACLManager->Groups_End(); ++iter) { if (!(*iter)->FindObjectMatch(szObjectAfterDot, objectType)) continue; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaAccountDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaAccountDefs.cpp index 00af2884165..cdeb86ae181 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaAccountDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaAccountDefs.cpp @@ -520,7 +520,6 @@ bool CLuaAccountDefs::SetAccountSerial(CAccount* account, std::string serial) no return CStaticFunctionDefinitions::SetAccountSerial(account, serial); } - int CLuaAccountDefs::SetAccountName(lua_State* luaVM) { // bool setAccountPassword ( account theAccount, string name[, bool allowCaseVariations = false ] ) diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaBlipDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaBlipDefs.cpp index 6b3bd66de02..2dbdd777eda 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaBlipDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaBlipDefs.cpp @@ -17,14 +17,18 @@ static constexpr std::uint8_t MAX_BLIP_SIZE = 25; -std::variant CLuaBlipDefs::CreateBlip(lua_State* luaVM, const CVector vecPosition, std::optional icon, std::optional size, std::optional r, std::optional g, std::optional b, std::optional a, std::optional ordering, std::optional visibleDistance, std::optional visibleTo) +std::variant CLuaBlipDefs::CreateBlip(lua_State* luaVM, const CVector vecPosition, std::optional icon, + std::optional size, std::optional r, std::optional g, + std::optional b, std::optional a, std::optional ordering, + std::optional visibleDistance, std::optional visibleTo) { if (icon.has_value() && !CBlipManager::IsValidIcon(icon.value())) throw std::invalid_argument("Invalid icon"); if (size.has_value() && size.value() > MAX_BLIP_SIZE) { - m_pScriptDebugging->LogWarning(luaVM, SString("Blip size beyond %i is no longer supported (got %i). It will be clamped between 0 and %i.", MAX_BLIP_SIZE, size.value(), MAX_BLIP_SIZE)); + m_pScriptDebugging->LogWarning(luaVM, SString("Blip size beyond %i is no longer supported (got %i). It will be clamped between 0 and %i.", + MAX_BLIP_SIZE, size.value(), MAX_BLIP_SIZE)); size = MAX_BLIP_SIZE; } @@ -41,14 +45,19 @@ std::variant CLuaBlipDefs::CreateBlip(lua_State* luaVM, const CVec return radarMarker; } -std::variant CLuaBlipDefs::CreateBlipAttachedTo(lua_State* luaVM, CElement* entity, std::optional icon, std::optional size, std::optional r, std::optional g, std::optional b, std::optional a, std::optional ordering, std::optional visibleDistance, std::optional visibleTo) +std::variant CLuaBlipDefs::CreateBlipAttachedTo(lua_State* luaVM, CElement* entity, std::optional icon, + std::optional size, std::optional r, std::optional g, + std::optional b, std::optional a, + std::optional ordering, std::optional visibleDistance, + std::optional visibleTo) { if (icon.has_value() && !CBlipManager::IsValidIcon(icon.value())) throw std::invalid_argument("Invalid icon"); if (size.has_value() && size.value() > MAX_BLIP_SIZE) { - m_pScriptDebugging->LogWarning(luaVM, SString("Blip size beyond %i is no longer supported (got %i). It will be clamped between 0 and %i.", MAX_BLIP_SIZE, size.value(), MAX_BLIP_SIZE)); + m_pScriptDebugging->LogWarning(luaVM, SString("Blip size beyond %i is no longer supported (got %i). It will be clamped between 0 and %i.", + MAX_BLIP_SIZE, size.value(), MAX_BLIP_SIZE)); size = MAX_BLIP_SIZE; } @@ -104,7 +113,8 @@ bool CLuaBlipDefs::SetBlipSize(lua_State* luaVM, CElement* radarMarker, std::uin { if (size > MAX_BLIP_SIZE) { - m_pScriptDebugging->LogWarning(luaVM, SString("Blip size beyond %i is no longer supported (got %i). It will be clamped between 0 and %i.", MAX_BLIP_SIZE, size, MAX_BLIP_SIZE)); + m_pScriptDebugging->LogWarning( + luaVM, SString("Blip size beyond %i is no longer supported (got %i). It will be clamped between 0 and %i.", MAX_BLIP_SIZE, size, MAX_BLIP_SIZE)); size = MAX_BLIP_SIZE; } diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaBlipDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaBlipDefs.h index 298486ef814..3d06f40f785 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaBlipDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaBlipDefs.h @@ -20,15 +20,21 @@ class CLuaBlipDefs : public CLuaDefs private: // Create functions - static std::variant CreateBlip(lua_State* luaVM, const CVector vecPosition, std::optional icon, std::optional size, std::optional r, std::optional g, std::optional b, std::optional a, std::optional ordering, std::optional visibleDistance, std::optional visibleTo); - static std::variant CreateBlipAttachedTo(lua_State* luaVM, CElement* entity, std::optional icon, std::optional size, std::optional r, std::optional g, std::optional b, std::optional a, std::optional ordering, std::optional visibleDistance, std::optional visibleTo); + static std::variant CreateBlip(lua_State* luaVM, const CVector vecPosition, std::optional icon, + std::optional size, std::optional r, std::optional g, + std::optional b, std::optional a, std::optional ordering, + std::optional visibleDistance, std::optional visibleTo); + static std::variant CreateBlipAttachedTo(lua_State* luaVM, CElement* entity, std::optional icon, + std::optional size, std::optional r, std::optional g, + std::optional b, std::optional a, std::optional ordering, + std::optional visibleDistance, std::optional visibleTo); // Get functions - static auto GetBlipIcon(CBlip* radarMarker) noexcept; - static auto GetBlipSize(CBlip* radarMarker) noexcept; - static auto GetBlipColor(CBlip* radarMarker) noexcept; - static auto GetBlipOrdering(CBlip* radarMarker) noexcept; - static auto GetBlipVisibleDistance(CBlip* radarMarker) noexcept; + static auto GetBlipIcon(CBlip* radarMarker) noexcept; + static auto GetBlipSize(CBlip* radarMarker) noexcept; + static auto GetBlipColor(CBlip* radarMarker) noexcept; + static auto GetBlipOrdering(CBlip* radarMarker) noexcept; + static auto GetBlipVisibleDistance(CBlip* radarMarker) noexcept; // Set functions static bool SetBlipIcon(CElement* radarMarker, std::uint8_t icon); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp index a9f907e41d2..192c9421720 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp @@ -36,7 +36,7 @@ void CLuaBuildingDefs::AddClass(lua_State* luaVM) } CBuilding* CLuaBuildingDefs::CreateBuilding(lua_State* const luaVM, std::uint16_t modelId, CVector pos, std::optional rot, - std::optional interior) + std::optional interior) { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); @@ -45,11 +45,6 @@ CBuilding* CLuaBuildingDefs::CreateBuilding(lua_State* const luaVM, std::uint16_ if (!pResource) throw std::logic_error("Cannot be done in current environment"); - const CMtaVersion& minClientVersion = pResource->GetMinClientFromMetaXml(); - - if (minClientVersion < CMtaVersion(SERVERSIDE_BUILDING_MIN_CLIENT_VERSION)) - throw std::logic_error("Expected client min_mta_version in meta.xml hinger or equal than " SERVERSIDE_BUILDING_MIN_CLIENT_VERSION); - if (!CBuildingManager::IsValidModel(modelId)) throw std::invalid_argument("Invalid building model id"); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h index e85353dec27..31520835aca 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h @@ -19,5 +19,5 @@ class CLuaBuildingDefs : public CLuaDefs static void AddClass(lua_State* luaVM); static CBuilding* CreateBuilding(lua_State* const luaVM, std::uint16_t modelId, CVector pos, std::optional rot, - std::optional interior); + std::optional interior); }; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaCameraDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaCameraDefs.h index 0a61c97f583..e120884d4ed 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaCameraDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaCameraDefs.h @@ -27,4 +27,4 @@ class CLuaCameraDefs : public CLuaDefs LUA_DECLARE(setCameraTarget); LUA_DECLARE(setCameraInterior); LUA_DECLARE(fadeCamera); -}; \ No newline at end of file +}; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaClassDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaClassDefs.cpp index 4b10ee3baa1..321907c87c0 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaClassDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaClassDefs.cpp @@ -14,75 +14,75 @@ int CLuaClassDefs::Index(lua_State* luaVM) { - lua_pushvalue(luaVM, lua_upvalueindex(1)); // ud, k, mt + lua_pushvalue(luaVM, lua_upvalueindex(1)); // ud, k, mt // First we look for a function - lua_pushstring(luaVM, "__class"); // ud, k, mt, "__class" - lua_rawget(luaVM, -2); // ud, k, mt, __class table + lua_pushstring(luaVM, "__class"); // ud, k, mt, "__class" + lua_rawget(luaVM, -2); // ud, k, mt, __class table if (!lua_istable(luaVM, -1)) { - lua_pop(luaVM, 1); // ud, k, mt + lua_pop(luaVM, 1); // ud, k, mt goto searchparent; } - lua_pushvalue(luaVM, 2); // ud, k, mt, __class table, k - lua_rawget(luaVM, -2); // ud, k, mt, __class table, function - lua_remove(luaVM, -2); // ud, k, mt, function + lua_pushvalue(luaVM, 2); // ud, k, mt, __class table, k + lua_rawget(luaVM, -2); // ud, k, mt, __class table, function + lua_remove(luaVM, -2); // ud, k, mt, function if (lua_isfunction(luaVM, -1)) - { // Found the function, clean up and return - lua_remove(luaVM, -2); // ud, k, function + { // Found the function, clean up and return + lua_remove(luaVM, -2); // ud, k, function return 1; } - lua_pop(luaVM, 1); // ud, k, mt + lua_pop(luaVM, 1); // ud, k, mt // Function not found, look for property - lua_pushstring(luaVM, "__get"); // ud, k, mt, "__get" - lua_rawget(luaVM, -2); // ud, k, mt, __get table + lua_pushstring(luaVM, "__get"); // ud, k, mt, "__get" + lua_rawget(luaVM, -2); // ud, k, mt, __get table if (!lua_istable(luaVM, -1)) { - lua_pop(luaVM, 1); // ud, k, mt + lua_pop(luaVM, 1); // ud, k, mt goto searchparent; } - lua_pushvalue(luaVM, 2); // ud, k, mt, __get table, k - lua_rawget(luaVM, -2); // ud, k, mt, __get table, function - lua_remove(luaVM, -2); // ud, k, mt, function + lua_pushvalue(luaVM, 2); // ud, k, mt, __get table, k + lua_rawget(luaVM, -2); // ud, k, mt, __get table, function + lua_remove(luaVM, -2); // ud, k, mt, function if (lua_isfunction(luaVM, -1)) - { // Found the property, - lua_remove(luaVM, -2); // ud, k, function + { // Found the property, + lua_remove(luaVM, -2); // ud, k, function - lua_pushvalue(luaVM, 1); // ud, k, function, ud - lua_call(luaVM, 1, 1); // ud, k, result + lua_pushvalue(luaVM, 1); // ud, k, function, ud + lua_call(luaVM, 1, 1); // ud, k, result return 1; } - lua_pop(luaVM, 1); // ud, k, mt + lua_pop(luaVM, 1); // ud, k, mt searchparent: - lua_pushstring(luaVM, "__parent"); // ud, k, mt, "__parent" - lua_rawget(luaVM, -2); // ud, k, mt, __parent table + lua_pushstring(luaVM, "__parent"); // ud, k, mt, "__parent" + lua_rawget(luaVM, -2); // ud, k, mt, __parent table if (lua_istable(luaVM, -1)) { - lua_pushstring(luaVM, "__index"); // ud, k, mt, __parent table, "__index" - lua_rawget(luaVM, -2); // ud, k, mt, __parent table, function + lua_pushstring(luaVM, "__index"); // ud, k, mt, __parent table, "__index" + lua_rawget(luaVM, -2); // ud, k, mt, __parent table, function if (lua_isfunction(luaVM, -1)) { - lua_pushvalue(luaVM, 1); // ud, k, mt, __parent table, function, ud - lua_pushvalue(luaVM, 2); // ud, k, mt, __parent table, function, ud, k + lua_pushvalue(luaVM, 1); // ud, k, mt, __parent table, function, ud + lua_pushvalue(luaVM, 2); // ud, k, mt, __parent table, function, ud, k - lua_call(luaVM, 2, 1); // ud, k, mt, __parent table, result + lua_call(luaVM, 2, 1); // ud, k, mt, __parent table, result - lua_replace(luaVM, -3); // ud, k, result, __parent table - lua_pop(luaVM, 1); // ud, k, result + lua_replace(luaVM, -3); // ud, k, result, __parent table + lua_pop(luaVM, 1); // ud, k, result return 1; } - lua_pop(luaVM, 1); // ud, k, mt, __parent table + lua_pop(luaVM, 1); // ud, k, mt, __parent table } - lua_pop(luaVM, 2); // ud, k + lua_pop(luaVM, 2); // ud, k lua_pushnil(luaVM); return 1; @@ -90,113 +90,113 @@ int CLuaClassDefs::Index(lua_State* luaVM) int CLuaClassDefs::NewIndex(lua_State* luaVM) { - lua_pushvalue(luaVM, lua_upvalueindex(1)); // ud, k, v, mt + lua_pushvalue(luaVM, lua_upvalueindex(1)); // ud, k, v, mt - lua_pushstring(luaVM, "__set"); // ud, k, v, mt, "__set" - lua_rawget(luaVM, -2); // ud, k, v, mt, __set table + lua_pushstring(luaVM, "__set"); // ud, k, v, mt, "__set" + lua_rawget(luaVM, -2); // ud, k, v, mt, __set table if (!lua_istable(luaVM, -1)) { - lua_pop(luaVM, 1); // ud, k, v, mt + lua_pop(luaVM, 1); // ud, k, v, mt goto searchparent; } - lua_pushvalue(luaVM, 2); // ud, k, v, mt, __set table, k - lua_rawget(luaVM, -2); // ud, k, v, mt, __set table, function - lua_remove(luaVM, -2); // ud, k, v, mt, function + lua_pushvalue(luaVM, 2); // ud, k, v, mt, __set table, k + lua_rawget(luaVM, -2); // ud, k, v, mt, __set table, function + lua_remove(luaVM, -2); // ud, k, v, mt, function if (lua_isfunction(luaVM, -1)) - { // Found the property - lua_pushvalue(luaVM, 1); // ud, k, v, mt, function, ud - lua_pushvalue(luaVM, 3); // ud, k, v, mt, function, ud, v + { // Found the property + lua_pushvalue(luaVM, 1); // ud, k, v, mt, function, ud + lua_pushvalue(luaVM, 3); // ud, k, v, mt, function, ud, v - lua_call(luaVM, 2, 0); // ud, k, v, mt + lua_call(luaVM, 2, 0); // ud, k, v, mt - lua_pop(luaVM, 1); // ud, k, v + lua_pop(luaVM, 1); // ud, k, v return 0; } - lua_pop(luaVM, 1); // ud, k, v, mt + lua_pop(luaVM, 1); // ud, k, v, mt searchparent: - lua_pushstring(luaVM, "__parent"); // ud, k, v, mt, "__parent" - lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table + lua_pushstring(luaVM, "__parent"); // ud, k, v, mt, "__parent" + lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table if (lua_istable(luaVM, -1)) { - lua_pushstring(luaVM, "__newindex"); // ud, k, v, mt, __parent table, "__newindex" - lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table, function + lua_pushstring(luaVM, "__newindex"); // ud, k, v, mt, __parent table, "__newindex" + lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table, function if (lua_isfunction(luaVM, -1)) { - lua_pushvalue(luaVM, 1); // ud, k, v, mt, __parent table, function, ud - lua_pushvalue(luaVM, 2); // ud, k, v, mt, __parent table, function, ud, k - lua_pushvalue(luaVM, 3); // ud, k, v, mt, __parent table, function, ud, k, v + lua_pushvalue(luaVM, 1); // ud, k, v, mt, __parent table, function, ud + lua_pushvalue(luaVM, 2); // ud, k, v, mt, __parent table, function, ud, k + lua_pushvalue(luaVM, 3); // ud, k, v, mt, __parent table, function, ud, k, v - lua_call(luaVM, 3, 0); // ud, k, v, mt, __parent table + lua_call(luaVM, 3, 0); // ud, k, v, mt, __parent table - lua_pop(luaVM, 2); // ud, k, v + lua_pop(luaVM, 2); // ud, k, v return 0; } - lua_pop(luaVM, 1); // ud, k, v, mt, __parent table + lua_pop(luaVM, 1); // ud, k, v, mt, __parent table } - lua_pop(luaVM, 2); // ud, k, v + lua_pop(luaVM, 2); // ud, k, v return 0; } int CLuaClassDefs::StaticNewIndex(lua_State* luaVM) { - lua_pushvalue(luaVM, lua_upvalueindex(1)); // ud, k, v, mt + lua_pushvalue(luaVM, lua_upvalueindex(1)); // ud, k, v, mt - lua_pushstring(luaVM, "__set"); // ud, k, v, mt, "__set" - lua_rawget(luaVM, -2); // ud, k, v, mt, __set table + lua_pushstring(luaVM, "__set"); // ud, k, v, mt, "__set" + lua_rawget(luaVM, -2); // ud, k, v, mt, __set table if (!lua_istable(luaVM, -1)) { - lua_pop(luaVM, 1); // ud, k, v, mt + lua_pop(luaVM, 1); // ud, k, v, mt goto searchparent; } - lua_pushvalue(luaVM, 2); // ud, k, v, mt, __set table, k - lua_rawget(luaVM, -2); // ud, k, v, mt, __set table, function - lua_remove(luaVM, -2); // ud, k, v, mt, function + lua_pushvalue(luaVM, 2); // ud, k, v, mt, __set table, k + lua_rawget(luaVM, -2); // ud, k, v, mt, __set table, function + lua_remove(luaVM, -2); // ud, k, v, mt, function if (lua_isfunction(luaVM, -1)) - { // Found the property - lua_pushvalue(luaVM, 3); // ud, k, v, mt, function, v + { // Found the property + lua_pushvalue(luaVM, 3); // ud, k, v, mt, function, v - lua_call(luaVM, 1, 0); // ud, k, v, mt + lua_call(luaVM, 1, 0); // ud, k, v, mt - lua_pop(luaVM, 1); // ud, k, v + lua_pop(luaVM, 1); // ud, k, v return 0; } - lua_pop(luaVM, 1); // ud, k, v, mt + lua_pop(luaVM, 1); // ud, k, v, mt searchparent: - lua_pushstring(luaVM, "__parent"); // ud, k, v, mt, "__parent" - lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table + lua_pushstring(luaVM, "__parent"); // ud, k, v, mt, "__parent" + lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table if (lua_istable(luaVM, -1)) { - lua_pushstring(luaVM, "__newindex"); // ud, k, v, mt, __parent table, "__newindex" - lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table, function + lua_pushstring(luaVM, "__newindex"); // ud, k, v, mt, __parent table, "__newindex" + lua_rawget(luaVM, -2); // ud, k, v, mt, __parent table, function if (lua_isfunction(luaVM, -1)) { - lua_pushvalue(luaVM, 1); // ud, k, v, mt, __parent table, function, ud - lua_pushvalue(luaVM, 2); // ud, k, v, mt, __parent table, function, ud, k - lua_pushvalue(luaVM, 3); // ud, k, v, mt, __parent table, function, ud, k, v + lua_pushvalue(luaVM, 1); // ud, k, v, mt, __parent table, function, ud + lua_pushvalue(luaVM, 2); // ud, k, v, mt, __parent table, function, ud, k + lua_pushvalue(luaVM, 3); // ud, k, v, mt, __parent table, function, ud, k, v - lua_call(luaVM, 3, 0); // ud, k, v, mt, __parent table + lua_call(luaVM, 3, 0); // ud, k, v, mt, __parent table - lua_pop(luaVM, 2); // ud, k, v + lua_pop(luaVM, 2); // ud, k, v return 0; } - lua_pop(luaVM, 1); // ud, k, v, mt, __parent table + lua_pop(luaVM, 1); // ud, k, v, mt, __parent table } - lua_pop(luaVM, 2); // ud, k, v + lua_pop(luaVM, 2); // ud, k, v return 0; } diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaClassDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaClassDefs.h index 248958b11fd..798ae7675e8 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaClassDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaClassDefs.h @@ -13,9 +13,9 @@ extern "C" { - #include "lua.h" - #include "lualib.h" - #include "lauxlib.h" +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" } #include "CLuaDefs.h" diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaColShapeDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaColShapeDefs.cpp index 51a52b61ba2..11adf5ff4e7 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaColShapeDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaColShapeDefs.cpp @@ -805,30 +805,39 @@ int CLuaColShapeDefs::RemoveColPolygonPoint(lua_State* luaVM) return luaL_error(luaVM, argStream.GetFullErrorMessage()); } -std::tuple CLuaColShapeDefs::GetColPolygonHeight(CColPolygon* pColPolygon) +CLuaMultiReturn CLuaColShapeDefs::GetColPolygonHeight(CColShape* shape) { - float fFloor, fCeil; - pColPolygon->GetHeight(fFloor, fCeil); - return std::make_tuple(fFloor, fCeil); + if (shape->GetShapeType() != COLSHAPE_POLYGON) + { + throw std::invalid_argument("Shape must be a polygon"); + } + + auto* polygon = static_cast(shape); + + float floor; + float ceil; + + polygon->GetHeight(floor, ceil); + + return {floor, ceil}; } -bool CLuaColShapeDefs::SetColPolygonHeight(CColPolygon* pColPolygon, std::variant floor, std::variant ceil) +bool CLuaColShapeDefs::SetColPolygonHeight(CColShape* shape, std::variant floor, std::variant ceil) { - // bool SetColPolygonHeight ( colshape theColShape, float floor, float ceil ) - float fFloor, fCeil; + if (shape->GetShapeType() != COLSHAPE_POLYGON) + { + throw std::invalid_argument("Shape must be a polygon"); + } - if (std::holds_alternative(floor)) - fFloor = std::numeric_limits::lowest(); - else - fFloor = std::get(floor); + auto* polygon = static_cast(shape); - if (std::holds_alternative(ceil)) - fCeil = std::numeric_limits::max(); - else - fCeil = std::get(ceil); + float lowest = std::holds_alternative(floor) ? std::numeric_limits::lowest() : std::get(floor); + float highest = std::holds_alternative(ceil) ? std::numeric_limits::max() : std::get(ceil); - if (fFloor > fCeil) - std::swap(fFloor, fCeil); + if (lowest > highest) + { + std::swap(lowest, highest); + } - return CStaticFunctionDefinitions::SetColPolygonHeight(pColPolygon, fFloor, fCeil); + return CStaticFunctionDefinitions::SetColPolygonHeight(polygon, lowest, highest); } diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaColShapeDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaColShapeDefs.h index 1787bc3feca..4fe67df1938 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaColShapeDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaColShapeDefs.h @@ -41,6 +41,6 @@ class CLuaColShapeDefs : public CLuaDefs LUA_DECLARE(IsInsideColShape); LUA_DECLARE(GetColShapeType); - static std::tuple GetColPolygonHeight(CColPolygon* pColPolygon); - static bool SetColPolygonHeight(CColPolygon* pColPolygon, std::variant floor, std::variant ceil); + static CLuaMultiReturn GetColPolygonHeight(CColShape* shape); + static bool SetColPolygonHeight(CColShape* shape, std::variant floor, std::variant ceil); }; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaCompatibilityDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaCompatibilityDefs.cpp index 9737d64068d..11a5e3525fe 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaCompatibilityDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaCompatibilityDefs.cpp @@ -85,7 +85,8 @@ void CLuaCompatibilityDefs::LoadFunctions() // Old Discord implementation (see #2499) {"setPlayerDiscordJoinParams", - [](lua_State* luaVM) -> int { + [](lua_State* luaVM) -> int + { lua_pushboolean(luaVM, false); return 1; }}, diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaDatabaseDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaDatabaseDefs.cpp index d2ba048e8e3..9c021326c2a 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaDatabaseDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaDatabaseDefs.cpp @@ -292,7 +292,7 @@ int CLuaDatabaseDefs::DbConnect(lua_State* luaVM) // Set default values if required GetOption(strOptions, "log", bLoggingEnabled, 1); GetOption(strOptions, "tag", strLogTag, "script"); - GetOption(strOptions, "queue", strQueueName, (strType == "mysql") ? strHost : DB_SQLITE_QUEUE_NAME_DEFAULT); + GetOption(strOptions, "queue", strQueueName, (strType == "mysql") ? strHost : SStringX(DB_SQLITE_QUEUE_NAME_DEFAULT)); SetOption(strOptions, "log", bLoggingEnabled); SetOption(strOptions, "tag", strLogTag); SetOption(strOptions, "queue", strQueueName); @@ -526,7 +526,7 @@ void PushRegistryResultTable(lua_State* luaVM, const CRegistryResultData* Result // Push the column name lua_pushlstring(luaVM, Result->ColNames[j].c_str(), Result->ColNames[j].size()); - switch (cell.nType) // push the value with the right type + switch (cell.nType) // push the value with the right type { case SQLITE_INTEGER: lua_pushnumber(luaVM, static_cast(cell.nVal)); @@ -609,15 +609,15 @@ int CLuaDatabaseDefs::DbPoll(lua_State* luaVM) lua_pushnumber(luaVM, i + 1); lua_newtable(luaVM); { - lua_pushnumber(luaVM, 1); // [1] - table of result rows + lua_pushnumber(luaVM, 1); // [1] - table of result rows PushRegistryResultTable(luaVM, Result); lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); // [2] - NumAffectedRows + lua_pushnumber(luaVM, 2); // [2] - NumAffectedRows lua_pushnumber(luaVM, Result->uiNumAffectedRows); lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); // [3] - LastInsertId + lua_pushnumber(luaVM, 3); // [3] - LastInsertId lua_pushnumber(luaVM, static_cast(Result->ullLastInsertId)); lua_settable(luaVM, -3); } @@ -687,10 +687,10 @@ int CLuaDatabaseDefs::ExecuteSQLQuery(lua_State* luaVM) { const CRegistryResultRow& row = *iter; // for ( int i = 0; i < Result.nRows; i++ ) { - lua_newtable(luaVM); // new table - lua_pushnumber(luaVM, i + 1); // row index number (starting at 1, not 0) - lua_pushvalue(luaVM, -2); // value - lua_settable(luaVM, -4); // refer to the top level table + lua_newtable(luaVM); // new table + lua_pushnumber(luaVM, i + 1); // row index number (starting at 1, not 0) + lua_pushvalue(luaVM, -2); // value + lua_settable(luaVM, -4); // refer to the top level table for (int j = 0; j < Result->nColumns; j++) { const CRegistryResultCell& cell = row[j]; @@ -699,7 +699,7 @@ int CLuaDatabaseDefs::ExecuteSQLQuery(lua_State* luaVM) // Push the column name lua_pushlstring(luaVM, Result->ColNames[j].c_str(), Result->ColNames[j].size()); - switch (cell.nType) // push the value with the right type + switch (cell.nType) // push the value with the right type { case SQLITE_INTEGER: lua_pushnumber(luaVM, static_cast(cell.nVal)); @@ -718,7 +718,7 @@ int CLuaDatabaseDefs::ExecuteSQLQuery(lua_State* luaVM) } lua_settable(luaVM, -3); } - lua_pop(luaVM, 1); // pop the inner table + lua_pop(luaVM, 1); // pop the inner table } return 1; } @@ -765,10 +765,10 @@ int CLuaDatabaseDefs::ExecuteSQLSelect(lua_State* luaVM) { const CRegistryResultRow& row = *iter; // for ( int i = 0; i < Result.nRows; i++ ) { - lua_newtable(luaVM); // new table - lua_pushnumber(luaVM, i + 1); // row index number (starting at 1, not 0) - lua_pushvalue(luaVM, -2); // value - lua_settable(luaVM, -4); // refer to the top level table + lua_newtable(luaVM); // new table + lua_pushnumber(luaVM, i + 1); // row index number (starting at 1, not 0) + lua_pushvalue(luaVM, -2); // value + lua_settable(luaVM, -4); // refer to the top level table for (int j = 0; j < Result->nColumns; j++) { const CRegistryResultCell& cell = row[j]; @@ -777,7 +777,7 @@ int CLuaDatabaseDefs::ExecuteSQLSelect(lua_State* luaVM) // Push the column name lua_pushlstring(luaVM, Result->ColNames[j].c_str(), Result->ColNames[j].size()); - switch (cell.nType) // push the value with the right type + switch (cell.nType) // push the value with the right type { case SQLITE_INTEGER: lua_pushnumber(luaVM, static_cast(cell.nVal)); @@ -796,7 +796,7 @@ int CLuaDatabaseDefs::ExecuteSQLSelect(lua_State* luaVM) } lua_settable(luaVM, -3); } - lua_pop(luaVM, 1); // pop the inner table + lua_pop(luaVM, 1); // pop the inner table } return 1; } diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaDatabaseDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaDatabaseDefs.h index 42a369d6cab..af7b787e9cd 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaDatabaseDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaDatabaseDefs.h @@ -36,4 +36,4 @@ class CLuaDatabaseDefs : public CLuaDefs LUA_DECLARE(ExecuteSQLSelect); LUA_DECLARE(ExecuteSQLUpdate); LUA_DECLARE(ExecuteSQLQuery); -}; \ No newline at end of file +}; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaDefs.cpp index 6dc009ef3c8..dfbe215e4e0 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaDefs.cpp @@ -36,7 +36,7 @@ namespace }; std::list ms_TimingFunctionStack; bool ms_bRegisterdPostCallHook = false; -} // namespace +} // namespace CElementDeleter* CLuaDefs::m_pElementDeleter = NULL; CBlipManager* CLuaDefs::m_pBlipManager = NULL; @@ -232,7 +232,7 @@ void CLuaDefs::DidUseFunction(lua_CFunction f, lua_State* luaVM) if (pFunction) { CResource* pResource = g_pGame->GetResourceManager()->GetResourceFromLuaState(info.luaVM); - SString strResourceName = pResource ? pResource->GetName() : "unknown"; + SString strResourceName = pResource ? pResource->GetName() : SStringX("unknown"); CPerfStatFunctionTiming::GetSingleton()->UpdateTiming(strResourceName, pFunction->GetName().c_str(), elapsedTime, uiDeltaBytes); } } diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaDefs.h index 412ad98ea7a..291f51da15e 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaDefs.h @@ -34,24 +34,7 @@ #include "../CDatabaseManager.h" #include -// Used by script handlers to verify elements -#define SCRIPT_VERIFY_BLIP(blip) (m_pBlipManager->Exists(blip)&&!blip->IsBeingDeleted()) -#define SCRIPT_VERIFY_ELEMENT(element) ((element)!=NULL&&m_pRootElement->IsMyChild((element),true)&&!element->IsBeingDeleted()) -#define SCRIPT_VERIFY_ENTITY(entity) ((entity)!=NULL&&m_pRootElement->IsMyChild((entity),true)&&entity->IsEntity()&&!entity->IsBeingDeleted()) -#define SCRIPT_VERIFY_MARKER(marker) (m_pMarkerManager->Exists(marker)&&!marker->IsBeingDeleted()) -#define SCRIPT_VERIFY_OBJECT(object) (m_pObjectManager->Exists(object)&&!object->IsBeingDeleted()) -#define SCRIPT_VERIFY_PICKUP(pickup) (m_pPickupManager->Exists(pickup)&&!pickup->IsBeingDeleted()) -#define SCRIPT_VERIFY_PLAYER(player) (m_pPlayerManager->Exists(player)&&!player->IsBeingDeleted()) -#define SCRIPT_VERIFY_FUNCTION(func) ((func)!=LUA_REFNIL) -#define SCRIPT_VERIFY_RADAR_AREA(radararea) (m_pRadarAreaManager->Exists(radararea)&&!radararea->IsBeingDeleted()) -#define SCRIPT_VERIFY_VEHICLE(vehicle) (m_pVehicleManager->Exists(vehicle)&&!vehicle->IsBeingDeleted()) -#define SCRIPT_VERIFY_TIMER(timer) (luaMain->GetTimerManager ()->Exists(timer)) -#define SCRIPT_VERIFY_PATH(path) (m_pPathManager->Exists(path)&&!path->IsBeingDeleted()) -#define SCRIPT_VERIFY_TEAM(team) (m_pTeamManager->Exists(team)) -#define SCRIPT_VERIFY_ACCOUNT(account) (m_pAccountManager->Exists(account)) -#define SCRIPT_VERIFY_COLSHAPE(colshape) (m_pColManager->Exists(colshape)) -#define SCRIPT_VERIFY_RESOURCE(resource) (m_pResourceManager->Exists(resource)) -#define LUA_DECLARE(x) static int x ( lua_State * luaVM ); +#define LUA_DECLARE(x) static int x(lua_State* luaVM); #define LUA_DECLARE_OOP(x) LUA_DECLARE(x) LUA_DECLARE(OOP_##x) class CLuaDefs @@ -96,7 +79,7 @@ class CLuaDefs template static inline int ArgumentParserWarn(lua_State* L) { - return CLuaFunctionParser()(L, m_pScriptDebugging); + return CLuaFunctionParser>()(L, m_pScriptDebugging); } // Special case for overloads @@ -106,8 +89,8 @@ class CLuaDefs { // Pad functions to have the same number of parameters by // filling both up to the larger number of parameters with dummy_type arguments - using PaddedFunctionA = pad_func_with_func; - using PaddedFunctionB = pad_func_with_func; + using PaddedFunctionA = pad_func_with_func, remove_noexcept_fn_v>; + using PaddedFunctionB = pad_func_with_func, remove_noexcept_fn_v>; // Combine functions using Overload = CLuaOverloadParser; @@ -118,7 +101,7 @@ class CLuaDefs template static inline int ArgumentParser(lua_State* L) { - return CLuaFunctionParser()(L, m_pScriptDebugging); + return CLuaFunctionParser>()(L, m_pScriptDebugging); } // Special case for overloads @@ -128,8 +111,8 @@ class CLuaDefs { // Pad functions to have the same number of parameters by // filling both up to the larger number of parameters with dummy_type arguments - using PaddedFunctionA = pad_func_with_func; - using PaddedFunctionB = pad_func_with_func; + using PaddedFunctionA = pad_func_with_func, remove_noexcept_fn_v>; + using PaddedFunctionB = pad_func_with_func, remove_noexcept_fn_v>; // Combine functions using Overload = CLuaOverloadParser; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp index c13299374cc..078383c4b28 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp @@ -1011,7 +1011,8 @@ CElementResult CLuaElementDefs::getElementsWithinRange(CVector pos, float radius if (interior || dimension || typeHash) { result.erase(std::remove_if(result.begin(), result.end(), - [&, radiusSq = radius * radius](CElement* pElement) { + [&, radiusSq = radius * radius](CElement* pElement) + { if (typeHash && typeHash != pElement->GetTypeHash()) return true; @@ -1539,10 +1540,10 @@ int CLuaElementDefs::setElementID(lua_State* luaVM) int CLuaElementDefs::setElementData(lua_State* luaVM) { // bool setElementData ( element theElement, string key, var value, [var syncMode = true] ) - CElement* pElement; - CStringName key; - CLuaArgument value; - ESyncType syncType = ESyncType::BROADCAST; + CElement* pElement; + CStringName key; + CLuaArgument value; + ESyncType syncType = ESyncType::BROADCAST; std::optional clientTrust{}; CScriptArgReader argStream(luaVM); @@ -1579,7 +1580,7 @@ int CLuaElementDefs::setElementData(lua_State* luaVM) key = key->substr(0, MAX_CUSTOMDATA_NAME_LENGTH); } - if (CStaticFunctionDefinitions::SetElementData(pElement, key.ToCString(), value, syncType, clientTrust)) + if (CStaticFunctionDefinitions::SetElementData(pElement, key, value, syncType, clientTrust)) { lua_pushboolean(luaVM, true); return 1; @@ -1595,7 +1596,7 @@ int CLuaElementDefs::setElementData(lua_State* luaVM) int CLuaElementDefs::removeElementData(lua_State* luaVM) { // bool removeElementData ( element theElement, string key ) - CElement* pElement; + CElement* pElement; CStringName key; CScriptArgReader argStream(luaVM); @@ -1630,9 +1631,9 @@ int CLuaElementDefs::removeElementData(lua_State* luaVM) int CLuaElementDefs::addElementDataSubscriber(lua_State* luaVM) { // bool addElementDataSubscriber ( element theElement, string key, player thePlayer ) - CElement* pElement; + CElement* pElement; CStringName key; - CPlayer* pPlayer; + CPlayer* pPlayer; CScriptArgReader argStream(luaVM); argStream.ReadUserData(pElement); @@ -1659,9 +1660,9 @@ int CLuaElementDefs::addElementDataSubscriber(lua_State* luaVM) int CLuaElementDefs::removeElementDataSubscriber(lua_State* luaVM) { // bool removeElementDataSubscriber ( element theElement, string key, player thePlayer ) - CElement* pElement; + CElement* pElement; CStringName key; - CPlayer* pPlayer; + CPlayer* pPlayer; CScriptArgReader argStream(luaVM); argStream.ReadUserData(pElement); @@ -1688,9 +1689,9 @@ int CLuaElementDefs::removeElementDataSubscriber(lua_State* luaVM) int CLuaElementDefs::hasElementDataSubscriber(lua_State* luaVM) { // bool hasElementDataSubscriber ( element theElement, string key, player thePlayer ) - CElement* pElement; + CElement* pElement; CStringName key; - CPlayer* pPlayer; + CPlayer* pPlayer; CScriptArgReader argStream(luaVM); argStream.ReadUserData(pElement); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Event.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Event.cpp index cef47c2e4cd..6d9d55d634d 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Event.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Event.cpp @@ -17,7 +17,7 @@ #include "CLatentTransferManager.h" #include "CDebugHookManager.h" -#define MIN_SERVER_REQ_TRIGGERCLIENTEVENT_SENDLIST "1.3.0-9.04570" +#define MIN_SERVER_REQ_TRIGGERCLIENTEVENT_SENDLIST "1.3.0-9.04570" extern CTimeUsMarker<20> markerLatentEvent; @@ -81,7 +81,7 @@ int CLuaFunctionDefs::AddEventHandler(lua_State* luaVM) } if (!StringToEnum(strPriority, eventPriority)) - argStream.SetTypeError(GetEnumTypeName(eventPriority), 5); // priority is argument #5 + argStream.SetTypeError(GetEnumTypeName(eventPriority), 5); // priority is argument #5 } if (!argStream.HasErrors()) diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Server.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Server.cpp index 845b9fc519f..af2fa3c1a21 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Server.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Server.cpp @@ -18,11 +18,11 @@ #include "CPerfStatManager.h" #include "CMapManager.h" -#define MIN_SERVER_REQ_CALLREMOTE_QUEUE_NAME "1.5.3-9.11270" -#define MIN_SERVER_REQ_CALLREMOTE_CONNECTION_ATTEMPTS "1.3.0-9.04563" -#define MIN_SERVER_REQ_CALLREMOTE_CONNECT_TIMEOUT "1.3.5" -#define MIN_SERVER_REQ_CALLREMOTE_OPTIONS_TABLE "1.5.4-9.11342" -#define MIN_SERVER_REQ_CALLREMOTE_OPTIONS_FORMFIELDS "1.5.4-9.11413" +#define MIN_SERVER_REQ_CALLREMOTE_QUEUE_NAME "1.5.3-9.11270" +#define MIN_SERVER_REQ_CALLREMOTE_CONNECTION_ATTEMPTS "1.3.0-9.04563" +#define MIN_SERVER_REQ_CALLREMOTE_CONNECT_TIMEOUT "1.3.5" +#define MIN_SERVER_REQ_CALLREMOTE_OPTIONS_TABLE "1.5.4-9.11342" +#define MIN_SERVER_REQ_CALLREMOTE_OPTIONS_FORMFIELDS "1.5.4-9.11413" int CLuaFunctionDefs::AddCommandHandler(lua_State* luaVM) { @@ -409,7 +409,7 @@ int CLuaFunctionDefs::SetGameType(lua_State* luaVM) SString strGameType; CScriptArgReader argStream(luaVM); - argStream.ReadIfNextIsString(strGameType, ""); // Default to empty for backward compat with previous implementation + argStream.ReadIfNextIsString(strGameType, ""); // Default to empty for backward compat with previous implementation if (!argStream.HasErrors()) { @@ -433,7 +433,7 @@ int CLuaFunctionDefs::SetMapName(lua_State* luaVM) SString strMapName; CScriptArgReader argStream(luaVM); - argStream.ReadIfNextIsString(strMapName, ""); // Default to empty for backward compat with previous implementation + argStream.ReadIfNextIsString(strMapName, ""); // Default to empty for backward compat with previous implementation if (!argStream.HasErrors()) { @@ -764,7 +764,7 @@ int CLuaFunctionDefs::GetPerformanceStats(lua_State* luaVM) for (int c = 0; c < Result.ColumnCount(); c++) { const SString& name = Result.ColumnName(c); - lua_pushnumber(luaVM, c + 1); // row index number (starting at 1, not 0) + lua_pushnumber(luaVM, c + 1); // row index number (starting at 1, not 0) lua_pushlstring(luaVM, name.c_str(), name.length()); lua_settable(luaVM, -3); } @@ -772,10 +772,10 @@ int CLuaFunctionDefs::GetPerformanceStats(lua_State* luaVM) lua_newtable(luaVM); for (int r = 0; r < Result.RowCount(); r++) { - lua_newtable(luaVM); // new table - lua_pushnumber(luaVM, r + 1); // row index number (starting at 1, not 0) - lua_pushvalue(luaVM, -2); // value - lua_settable(luaVM, -4); // refer to the top level table + lua_newtable(luaVM); // new table + lua_pushnumber(luaVM, r + 1); // row index number (starting at 1, not 0) + lua_pushvalue(luaVM, -2); // value + lua_settable(luaVM, -4); // refer to the top level table for (int c = 0; c < Result.ColumnCount(); c++) { @@ -784,7 +784,7 @@ int CLuaFunctionDefs::GetPerformanceStats(lua_State* luaVM) lua_pushlstring(luaVM, cell.c_str(), cell.length()); lua_settable(luaVM, -3); } - lua_pop(luaVM, 1); // pop the inner table + lua_pop(luaVM, 1); // pop the inner table } return 2; } diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Weapon.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Weapon.cpp index 19897098aa4..de986285805 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Weapon.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Weapon.cpp @@ -15,7 +15,7 @@ #include "CStaticFunctionDefinitions.h" #include "CWeaponNames.h" -#define MIN_SERVER_REQ_WEAPON_PROPERTY_FLAG "1.3.5-9.06139" +#define MIN_SERVER_REQ_WEAPON_PROPERTY_FLAG "1.3.5-9.06139" int CLuaFunctionDefs::SetWeaponAmmo(lua_State* luaVM) { diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.cpp index 26bd9125105..dbf615c5875 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.cpp @@ -12,73 +12,104 @@ #include "StdInc.h" #include "CLuaFunctionDefs.h" -CTimeUsMarker<20> markerLatentEvent; // For timing triggerLatentClientEvent +CTimeUsMarker<20> markerLatentEvent; // For timing triggerLatentClientEvent void CLuaFunctionDefs::LoadFunctions() { - constexpr static const std::pair functions[] - { - {"addEvent", CLuaFunctionDefs::AddEvent}, {"addEventHandler", CLuaFunctionDefs::AddEventHandler}, - {"removeEventHandler", CLuaFunctionDefs::RemoveEventHandler}, {"getEventHandlers", CLuaFunctionDefs::GetEventHandlers}, - {"triggerEvent", CLuaFunctionDefs::TriggerEvent}, {"triggerClientEvent", CLuaFunctionDefs::TriggerClientEvent}, - {"cancelEvent", CLuaFunctionDefs::CancelEvent}, {"wasEventCancelled", CLuaFunctionDefs::WasEventCancelled}, - {"getCancelReason", CLuaFunctionDefs::GetCancelReason}, {"triggerLatentClientEvent", CLuaFunctionDefs::TriggerLatentClientEvent}, - {"getLatentEventHandles", CLuaFunctionDefs::GetLatentEventHandles}, {"getLatentEventStatus", CLuaFunctionDefs::GetLatentEventStatus}, - {"cancelLatentEvent", CLuaFunctionDefs::CancelLatentEvent}, {"addDebugHook", CLuaFunctionDefs::AddDebugHook}, - {"removeDebugHook", CLuaFunctionDefs::RemoveDebugHook}, - - // Explosion create funcs - {"createExplosion", CLuaFunctionDefs::CreateExplosion}, - - // Ped body funcs? - {"getBodyPartName", CLuaFunctionDefs::GetBodyPartName}, {"getClothesByTypeIndex", CLuaFunctionDefs::GetClothesByTypeIndex}, - {"getTypeIndexFromClothes", CLuaFunctionDefs::GetTypeIndexFromClothes}, {"getClothesTypeName", CLuaFunctionDefs::GetClothesTypeName}, - - // Weapon funcs - {"getWeaponNameFromID", CLuaFunctionDefs::GetWeaponNameFromID}, {"getWeaponIDFromName", CLuaFunctionDefs::GetWeaponIDFromName}, - {"getWeaponProperty", CLuaFunctionDefs::GetWeaponProperty}, {"getOriginalWeaponProperty", CLuaFunctionDefs::GetOriginalWeaponProperty}, - {"setWeaponProperty", CLuaFunctionDefs::SetWeaponProperty}, {"setWeaponAmmo", CLuaFunctionDefs::SetWeaponAmmo}, - {"getSlotFromWeapon", CLuaFunctionDefs::GetSlotFromWeapon}, - - #if MTASA_VERSION_TYPE < VERSION_TYPE_RELEASE - {"createWeapon", CLuaFunctionDefs::CreateWeapon}, {"fireWeapon", CLuaFunctionDefs::FireWeapon}, - {"setWeaponState", CLuaFunctionDefs::SetWeaponState}, {"getWeaponState", CLuaFunctionDefs::GetWeaponState}, - {"setWeaponTarget", CLuaFunctionDefs::SetWeaponTarget}, {"getWeaponTarget", CLuaFunctionDefs::GetWeaponTarget}, - {"setWeaponOwner", CLuaFunctionDefs::SetWeaponOwner}, {"getWeaponOwner", CLuaFunctionDefs::GetWeaponOwner}, - {"setWeaponFlags", CLuaFunctionDefs::SetWeaponFlags}, {"getWeaponFlags", CLuaFunctionDefs::GetWeaponFlags}, - {"setWeaponFiringRate", CLuaFunctionDefs::SetWeaponFiringRate}, {"getWeaponFiringRate", CLuaFunctionDefs::GetWeaponFiringRate}, - {"resetWeaponFiringRate", CLuaFunctionDefs::ResetWeaponFiringRate}, {"getWeaponAmmo", CLuaFunctionDefs::GetWeaponAmmo}, - {"getWeaponClipAmmo", CLuaFunctionDefs::GetWeaponClipAmmo}, {"setWeaponClipAmmo", CLuaFunctionDefs::SetWeaponClipAmmo}, - #endif - - // Console funcs - {"addCommandHandler", CLuaFunctionDefs::AddCommandHandler}, {"removeCommandHandler", CLuaFunctionDefs::RemoveCommandHandler}, - {"executeCommandHandler", CLuaFunctionDefs::ExecuteCommandHandler}, {"getCommandHandlers", CLuaFunctionDefs::GetCommandHandlers}, - - // Loaded map funcs - {"getRootElement", CLuaFunctionDefs::GetRootElement}, {"loadMapData", CLuaFunctionDefs::LoadMapData}, - {"saveMapData", CLuaFunctionDefs::SaveMapData}, - - // All-Seeing Eye Functions - {"getGameType", CLuaFunctionDefs::GetGameType}, {"getMapName", CLuaFunctionDefs::GetMapName}, {"setGameType", CLuaFunctionDefs::SetGameType}, - {"setMapName", CLuaFunctionDefs::SetMapName}, {"getRuleValue", CLuaFunctionDefs::GetRuleValue}, {"setRuleValue", CLuaFunctionDefs::SetRuleValue}, - {"removeRuleValue", CLuaFunctionDefs::RemoveRuleValue}, - - // Registry functions - {"getPerformanceStats", CLuaFunctionDefs::GetPerformanceStats}, - - // Misc funcs - {"resetMapInfo", CLuaFunctionDefs::ResetMapInfo}, {"getServerPort", CLuaFunctionDefs::GetServerPort}, - - // Settings registry funcs - {"get", CLuaFunctionDefs::Get}, {"set", CLuaFunctionDefs::Set}, - - // Utility - {"getVersion", CLuaFunctionDefs::GetVersion}, {"getNetworkUsageData", CLuaFunctionDefs::GetNetworkUsageData}, - {"getNetworkStats", CLuaFunctionDefs::GetNetworkStats}, {"getLoadedModules", CLuaFunctionDefs::GetModules}, - {"getModuleInfo", CLuaFunctionDefs::GetModuleInfo}, - - {"setDevelopmentMode", CLuaFunctionDefs::SetDevelopmentMode}, {"getDevelopmentMode", CLuaFunctionDefs::GetDevelopmentMode}, + constexpr static const std::pair functions[]{ + {"addEvent", CLuaFunctionDefs::AddEvent}, + {"addEventHandler", CLuaFunctionDefs::AddEventHandler}, + {"removeEventHandler", CLuaFunctionDefs::RemoveEventHandler}, + {"getEventHandlers", CLuaFunctionDefs::GetEventHandlers}, + {"triggerEvent", CLuaFunctionDefs::TriggerEvent}, + {"triggerClientEvent", CLuaFunctionDefs::TriggerClientEvent}, + {"cancelEvent", CLuaFunctionDefs::CancelEvent}, + {"wasEventCancelled", CLuaFunctionDefs::WasEventCancelled}, + {"getCancelReason", CLuaFunctionDefs::GetCancelReason}, + {"triggerLatentClientEvent", CLuaFunctionDefs::TriggerLatentClientEvent}, + {"getLatentEventHandles", CLuaFunctionDefs::GetLatentEventHandles}, + {"getLatentEventStatus", CLuaFunctionDefs::GetLatentEventStatus}, + {"cancelLatentEvent", CLuaFunctionDefs::CancelLatentEvent}, + {"addDebugHook", CLuaFunctionDefs::AddDebugHook}, + {"removeDebugHook", CLuaFunctionDefs::RemoveDebugHook}, + + // Explosion create funcs + {"createExplosion", CLuaFunctionDefs::CreateExplosion}, + + // Ped body funcs? + {"getBodyPartName", CLuaFunctionDefs::GetBodyPartName}, + {"getClothesByTypeIndex", CLuaFunctionDefs::GetClothesByTypeIndex}, + {"getTypeIndexFromClothes", CLuaFunctionDefs::GetTypeIndexFromClothes}, + {"getClothesTypeName", CLuaFunctionDefs::GetClothesTypeName}, + + // Weapon funcs + {"getWeaponNameFromID", CLuaFunctionDefs::GetWeaponNameFromID}, + {"getWeaponIDFromName", CLuaFunctionDefs::GetWeaponIDFromName}, + {"getWeaponProperty", CLuaFunctionDefs::GetWeaponProperty}, + {"getOriginalWeaponProperty", CLuaFunctionDefs::GetOriginalWeaponProperty}, + {"setWeaponProperty", CLuaFunctionDefs::SetWeaponProperty}, + {"setWeaponAmmo", CLuaFunctionDefs::SetWeaponAmmo}, + {"getSlotFromWeapon", CLuaFunctionDefs::GetSlotFromWeapon}, + +#if MTASA_VERSION_TYPE < VERSION_TYPE_UNTESTED + {"createWeapon", CLuaFunctionDefs::CreateWeapon}, + {"fireWeapon", CLuaFunctionDefs::FireWeapon}, + {"setWeaponState", CLuaFunctionDefs::SetWeaponState}, + {"getWeaponState", CLuaFunctionDefs::GetWeaponState}, + {"setWeaponTarget", CLuaFunctionDefs::SetWeaponTarget}, + {"getWeaponTarget", CLuaFunctionDefs::GetWeaponTarget}, + {"setWeaponOwner", CLuaFunctionDefs::SetWeaponOwner}, + {"getWeaponOwner", CLuaFunctionDefs::GetWeaponOwner}, + {"setWeaponFlags", CLuaFunctionDefs::SetWeaponFlags}, + {"getWeaponFlags", CLuaFunctionDefs::GetWeaponFlags}, + {"setWeaponFiringRate", CLuaFunctionDefs::SetWeaponFiringRate}, + {"getWeaponFiringRate", CLuaFunctionDefs::GetWeaponFiringRate}, + {"resetWeaponFiringRate", CLuaFunctionDefs::ResetWeaponFiringRate}, + {"getWeaponAmmo", CLuaFunctionDefs::GetWeaponAmmo}, + {"getWeaponClipAmmo", CLuaFunctionDefs::GetWeaponClipAmmo}, + {"setWeaponClipAmmo", CLuaFunctionDefs::SetWeaponClipAmmo}, +#endif + + // Console funcs + {"addCommandHandler", CLuaFunctionDefs::AddCommandHandler}, + {"removeCommandHandler", CLuaFunctionDefs::RemoveCommandHandler}, + {"executeCommandHandler", CLuaFunctionDefs::ExecuteCommandHandler}, + {"getCommandHandlers", CLuaFunctionDefs::GetCommandHandlers}, + + // Loaded map funcs + {"getRootElement", CLuaFunctionDefs::GetRootElement}, + {"loadMapData", CLuaFunctionDefs::LoadMapData}, + {"saveMapData", CLuaFunctionDefs::SaveMapData}, + + // All-Seeing Eye Functions + {"getGameType", CLuaFunctionDefs::GetGameType}, + {"getMapName", CLuaFunctionDefs::GetMapName}, + {"setGameType", CLuaFunctionDefs::SetGameType}, + {"setMapName", CLuaFunctionDefs::SetMapName}, + {"getRuleValue", CLuaFunctionDefs::GetRuleValue}, + {"setRuleValue", CLuaFunctionDefs::SetRuleValue}, + {"removeRuleValue", CLuaFunctionDefs::RemoveRuleValue}, + + // Registry functions + {"getPerformanceStats", CLuaFunctionDefs::GetPerformanceStats}, + + // Misc funcs + {"resetMapInfo", CLuaFunctionDefs::ResetMapInfo}, + {"getServerPort", CLuaFunctionDefs::GetServerPort}, + + // Settings registry funcs + {"get", CLuaFunctionDefs::Get}, + {"set", CLuaFunctionDefs::Set}, + + // Utility + {"getVersion", CLuaFunctionDefs::GetVersion}, + {"getNetworkUsageData", CLuaFunctionDefs::GetNetworkUsageData}, + {"getNetworkStats", CLuaFunctionDefs::GetNetworkStats}, + {"getLoadedModules", CLuaFunctionDefs::GetModules}, + {"getModuleInfo", CLuaFunctionDefs::GetModuleInfo}, + + {"setDevelopmentMode", CLuaFunctionDefs::SetDevelopmentMode}, + {"getDevelopmentMode", CLuaFunctionDefs::GetDevelopmentMode}, }; // Add all functions diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaHTTPDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaHTTPDefs.h index 595bd68f17f..cdecbfbe10f 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaHTTPDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaHTTPDefs.h @@ -25,4 +25,4 @@ class CLuaHTTPDefs : public CLuaDefs LUA_DECLARE(httpSetResponseCode); LUA_DECLARE(httpClear); LUA_DECLARE(httpRequestLogin); -}; \ No newline at end of file +}; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaHandlingDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaHandlingDefs.cpp index 552cde4a63e..a62170d8ef3 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaHandlingDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaHandlingDefs.cpp @@ -98,7 +98,7 @@ int CLuaHandlingDefs::SetVehicleHandling(lua_State* luaVM) } break; } - case HANDLING_PERCENTSUBMERGED: // unsigned int + case HANDLING_PERCENTSUBMERGED: // unsigned int // case HANDLING_MONETARY: case HANDLING_HANDLINGFLAGS: case HANDLING_MODELFLAGS: @@ -275,7 +275,7 @@ int CLuaHandlingDefs::SetModelHandling(lua_State* luaVM) } break; } - case HANDLING_PERCENTSUBMERGED: // unsigned int + case HANDLING_PERCENTSUBMERGED: // unsigned int // case HANDLING_MONETARY: case HANDLING_HANDLINGFLAGS: case HANDLING_MODELFLAGS: @@ -498,7 +498,7 @@ int CLuaHandlingDefs::GetVehicleHandling(lua_State* luaVM) lua_pushstring(luaVM, "rwd"); else if (eDriveType == CHandlingEntry::FOURWHEEL) lua_pushstring(luaVM, "awd"); - else // What the ... (yeah, security) + else // What the ... (yeah, security) lua_pushnil(luaVM); lua_setfield(luaVM, -2, "driveType"); @@ -664,7 +664,7 @@ int CLuaHandlingDefs::GetModelHandling(lua_State* luaVM) lua_pushstring(luaVM, "rwd"); else if (eDriveType == CHandlingEntry::FOURWHEEL) lua_pushstring(luaVM, "awd"); - else // What the ... (yeah, security) + else // What the ... (yeah, security) lua_pushnil(luaVM); lua_setfield(luaVM, -2, "driveType"); @@ -828,7 +828,7 @@ int CLuaHandlingDefs::GetOriginalHandling(lua_State* luaVM) lua_pushstring(luaVM, "rwd"); else if (eDriveType == CHandlingEntry::FOURWHEEL) lua_pushstring(luaVM, "awd"); - else // What the ... (yeah, security) + else // What the ... (yeah, security) lua_pushnil(luaVM); lua_setfield(luaVM, -2, "driveType"); CHandlingEntry::eEngineType eEngineType = entry->GetCarEngineType(); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaHandlingDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaHandlingDefs.h index cd515c55804..a43acb308b0 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaHandlingDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaHandlingDefs.h @@ -116,4 +116,4 @@ class CLuaHandlingDefs : public CLuaDefs LUA_DECLARE ( handlingSetHeadLightType ); LUA_DECLARE ( handlingSetTailLightType ); LUA_DECLARE ( handlingSetAnimGroup );*/ -}; \ No newline at end of file +}; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.cpp index fe2e5e11155..dc927344cd3 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.cpp @@ -54,13 +54,13 @@ void CLuaMarkerDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "getIcon", "getMarkerIcon"); lua_classfunction(luaVM, "getSize", "getMarkerSize"); lua_classfunction(luaVM, "getTarget", "getMarkerTarget", OOP_GetMarkerTarget); - lua_classfunction(luaVM, "getColor", "getMarkerColor"); // color + lua_classfunction(luaVM, "getColor", "getMarkerColor"); // color lua_classfunction(luaVM, "setType", "setMarkerType"); lua_classfunction(luaVM, "setIcon", "setMarkerIcon"); lua_classfunction(luaVM, "setSize", "setMarkerSize"); lua_classfunction(luaVM, "setTarget", "setMarkerTarget"); - lua_classfunction(luaVM, "setColor", "setMarkerColor"); // color + lua_classfunction(luaVM, "setColor", "setMarkerColor"); // color lua_classvariable(luaVM, "markerType", "setMarkerType", "getMarkerType"); lua_classvariable(luaVM, "icon", "setMarkerIcon", "getMarkerIcon"); @@ -206,7 +206,7 @@ int CLuaMarkerDefs::GetMarkerColor(lua_State* luaVM) lua_pushnumber(luaVM, static_cast(color.B)); if (!pMarker->AreAlphaLimitsIgnored() && (pMarker->GetMarkerType() == CMarker::TYPE_CHECKPOINT || pMarker->GetMarkerType() == CMarker::TYPE_ARROW)) - lua_pushnumber(luaVM, 255); // fake alpha + lua_pushnumber(luaVM, 255); // fake alpha else lua_pushnumber(luaVM, static_cast(color.A)); @@ -423,7 +423,8 @@ int CLuaMarkerDefs::SetMarkerIcon(lua_State* luaVM) return 1; } -bool CLuaMarkerDefs::SetMarkerTargetArrowProperties(CMarker* marker, std::optional r, std::optional g, std::optional b, std::optional a, std::optional size) +bool CLuaMarkerDefs::SetMarkerTargetArrowProperties(CMarker* marker, std::optional r, std::optional g, + std::optional b, std::optional a, std::optional size) { SColor color; color.R = r.value_or(255); @@ -434,7 +435,8 @@ bool CLuaMarkerDefs::SetMarkerTargetArrowProperties(CMarker* marker, std::option return CStaticFunctionDefinitions::SetMarkerTargetArrowProperties(marker, color, size.value_or(marker->GetSize() * 0.625f)); } -std::variant, bool> CLuaMarkerDefs::GetMarkerTargetArrowProperties(CMarker* marker) noexcept +std::variant, bool> CLuaMarkerDefs::GetMarkerTargetArrowProperties( + CMarker* marker) noexcept { if (!marker->HasTarget() || marker->GetMarkerType() != CMarker::TYPE_CHECKPOINT) return false; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.h index 519cf725cc8..ad1f1990c42 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaMarkerDefs.h @@ -36,6 +36,8 @@ class CLuaMarkerDefs : public CLuaDefs LUA_DECLARE(SetMarkerColor); LUA_DECLARE(SetMarkerTarget); LUA_DECLARE(SetMarkerIcon); - static bool SetMarkerTargetArrowProperties(CMarker* marker, std::optional r, std::optional g, std::optional b, std::optional a, std::optional size); - static std::variant, bool> GetMarkerTargetArrowProperties(CMarker* marker) noexcept; + static bool SetMarkerTargetArrowProperties(CMarker* marker, std::optional r, std::optional g, std::optional b, + std::optional a, std::optional size); + static std::variant, bool> GetMarkerTargetArrowProperties( + CMarker* marker) noexcept; }; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp index 1d10a059162..135e5a4e9a8 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp @@ -35,7 +35,7 @@ void CLuaPedDefs::LoadFunctions() {"getPedTotalAmmo", GetPedTotalAmmo}, {"getPedWeapon", GetPedWeapon}, {"getPedClothes", GetPedClothes}, - {"isPedWearingJetpack", DoesPedHaveJetPack}, // introduced in 1.5.5-9.13846 + {"isPedWearingJetpack", DoesPedHaveJetPack}, // introduced in 1.5.5-9.13846 {"isPedOnGround", IsPedOnGround}, {"getPedFightingStyle", GetPedFightingStyle}, {"getPedWalkingStyle", GetPedMoveAnim}, @@ -58,7 +58,7 @@ void CLuaPedDefs::LoadFunctions() {"setPedStat", SetPedStat}, {"addPedClothes", AddPedClothes}, {"removePedClothes", RemovePedClothes}, - {"setPedWearingJetpack", SetPedWearingJetpack}, // introduced in 1.5.5-9.13846 + {"setPedWearingJetpack", SetPedWearingJetpack}, // introduced in 1.5.5-9.13846 {"setPedFightingStyle", SetPedFightingStyle}, {"setPedWalkingStyle", SetPedMoveAnim}, {"setPedGravity", SetPedGravity}, @@ -106,7 +106,7 @@ void CLuaPedDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "removeClothes", "removePedClothes"); lua_classfunction(luaVM, "removeFromVehicle", "removePedFromVehicle"); lua_classfunction(luaVM, "removeJetPack", "removePedJetPack"); - lua_classfunction(luaVM, "doesHaveJetpack", "doesPedHaveJetPack"); // deprecated in 1.5.5-9.13846 + lua_classfunction(luaVM, "doesHaveJetpack", "doesPedHaveJetPack"); // deprecated in 1.5.5-9.13846 lua_classfunction(luaVM, "isDead", "isPedDead"); lua_classfunction(luaVM, "isDucked", "isPedDucked"); @@ -118,7 +118,7 @@ void CLuaPedDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "isDoingGangDriveby", "isPedDoingGangDriveby"); lua_classfunction(luaVM, "isFrozen", "isPedFrozen"); lua_classfunction(luaVM, "isHeadless", "isPedHeadless"); - lua_classfunction(luaVM, "isWearingJetpack", "isPedWearingJetpack"); // introduced in 1.5.5-9.13846 + lua_classfunction(luaVM, "isWearingJetpack", "isPedWearingJetpack"); // introduced in 1.5.5-9.13846 lua_classfunction(luaVM, "isReloadingWeapon", "isPedReloadingWeapon"); lua_classfunction(luaVM, "getArmor", "getPedArmor"); @@ -150,7 +150,7 @@ void CLuaPedDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "setAnimation", "setPedAnimation"); lua_classfunction(luaVM, "setAnimationProgress", "setPedAnimationProgress"); lua_classfunction(luaVM, "setAnimationSpeed", "setPedAnimationSpeed"); - lua_classfunction(luaVM, "setWearingJetpack", "setPedWearingJetpack"); // introduced in 1.5.5-9.13846 + lua_classfunction(luaVM, "setWearingJetpack", "setPedWearingJetpack"); // introduced in 1.5.5-9.13846 lua_classvariable(luaVM, "inVehicle", NULL, "isPedInVehicle"); lua_classvariable(luaVM, "ducked", NULL, "isPedDucked"); @@ -170,7 +170,7 @@ void CLuaPedDefs::AddClass(lua_State* luaVM) lua_classvariable(luaVM, "contactElement", NULL, "getPedContactElement"); lua_classvariable(luaVM, "vehicle", "warpPedIntoVehicle", "getPedOccupiedVehicle", OOP_WarpPedIntoVehicle, GetPedOccupiedVehicle); lua_classvariable(luaVM, "walkingStyle", "setPedWalkingStyle", "getPedWalkingStyle"); - lua_classvariable(luaVM, "jetpack", "setPedWearingJetpack", "isPedWearingJetpack"); // introduced in 1.5.5-9.13846 + lua_classvariable(luaVM, "jetpack", "setPedWearingJetpack", "isPedWearingJetpack"); // introduced in 1.5.5-9.13846 lua_classvariable(luaVM, "reloadingWeapon", nullptr, "isPedReloadingWeapon"); // TODO(qaisjp): setting this to any value will kill the ped. add OOP_KillPed that only allows `true`. @@ -421,7 +421,9 @@ bool CLuaPedDefs::SetPedAnimation(CElement* pPed, std::optional> blockName, std::optional> animName, std::optional time, std::optional loop, std::optional updatePosition, std::optional interruptable, std::optional freezeLastFrame, std::optional blendTime, std::optional restoreTask); + static bool SetPedAnimation(CElement* pPed, std::optional> blockName, + std::optional> animName, std::optional time, std::optional loop, + std::optional updatePosition, std::optional interruptable, std::optional freezeLastFrame, + std::optional blendTime, std::optional restoreTask); LUA_DECLARE(SetPedAnimationProgress); LUA_DECLARE(SetPedAnimationSpeed); LUA_DECLARE(SetPedWeaponSlot); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp index 41ea5464808..20572e7d5e0 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp @@ -235,7 +235,7 @@ int CLuaPlayerDefs::CanPlayerUseFunction(lua_State* luaVM) int CLuaPlayerDefs::GetPlayerName(lua_State* luaVM) { // string getPlayerName ( player thePlayer ) - CElement* pElement; // player or console + CElement* pElement; // player or console CScriptArgReader argStream(luaVM); argStream.ReadUserData(pElement); @@ -264,7 +264,7 @@ int CLuaPlayerDefs::GetPlayerName(lua_State* luaVM) int CLuaPlayerDefs::GetPlayerIP(lua_State* luaVM) { // string getPlayerIP ( player thePlayer ) - CElement* pElement; // player or console + CElement* pElement; // player or console CScriptArgReader argStream(luaVM); argStream.ReadUserData(pElement); @@ -314,7 +314,7 @@ int CLuaPlayerDefs::GetPlayerVersion(lua_State* luaVM) int CLuaPlayerDefs::GetPlayerAccount(lua_State* luaVM) { // account getPlayerAccount ( player thePlayer ) - CElement* pElement; // player or console + CElement* pElement; // player or console CScriptArgReader argStream(luaVM); argStream.ReadUserData(pElement); @@ -1536,7 +1536,7 @@ int CLuaPlayerDefs::UnbindKey(lua_State* luaVM) argStream.ReadUserData(pPlayer); argStream.ReadString(strKey); - if (argStream.NextIsString(1)) // Check if has command + if (argStream.NextIsString(1)) // Check if has command { // bool unbindKey ( player thePlayer, string key, string keyState, string command ) argStream.ReadString(strHitState); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h index 73c499d8f4a..21768454c8e 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h @@ -38,8 +38,8 @@ class CLuaPlayerDefs : public CLuaDefs LUA_DECLARE(GetPlayerNametagColor); LUA_DECLARE(IsPlayerNametagShowing); LUA_DECLARE(GetPlayerSerial); - LUA_DECLARE(GetPlayerCommunityID); // deprecate me - LUA_DECLARE(GetPlayerUserName); // deprecate me + LUA_DECLARE(GetPlayerCommunityID); // deprecate me + LUA_DECLARE(GetPlayerUserName); // deprecate me LUA_DECLARE(GetPlayerBlurLevel); LUA_DECLARE(GetPlayerName); LUA_DECLARE(GetPlayerIP); @@ -53,7 +53,7 @@ class CLuaPlayerDefs : public CLuaDefs LUA_DECLARE(GivePlayerMoney); LUA_DECLARE(TakePlayerMoney); LUA_DECLARE(SpawnPlayer); - LUA_DECLARE(ShowPlayerHudComponent); // deprecate me + LUA_DECLARE(ShowPlayerHudComponent); // deprecate me LUA_DECLARE(SetPlayerWantedLevel); LUA_DECLARE(ForcePlayerMap); LUA_DECLARE(SetPlayerNametagText); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaRadarAreaDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaRadarAreaDefs.h index 2f846f17749..f31d1449128 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaRadarAreaDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaRadarAreaDefs.h @@ -31,4 +31,4 @@ class CLuaRadarAreaDefs : public CLuaDefs LUA_DECLARE(SetRadarAreaSize); LUA_DECLARE(SetRadarAreaColor); LUA_DECLARE(SetRadarAreaFlashing); -}; \ No newline at end of file +}; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp index a09e1888a8d..1fffce55261 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp @@ -97,7 +97,7 @@ void CLuaResourceDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "getFromName", "getResourceFromName"); lua_classfunction(luaVM, "getAll", "getResources"); lua_classfunction(luaVM, "getThis", "getThisResource"); - lua_classfunction(luaVM, "refresh", "refreshResources"); // Can't use "all" here because that's an argument + lua_classfunction(luaVM, "refresh", "refreshResources"); // Can't use "all" here because that's an argument lua_classfunction(luaVM, "create", "createResource"); lua_classfunction(luaVM, "start", "startResource"); @@ -339,7 +339,7 @@ int CLuaResourceDefs::addResourceConfig(lua_State* luaVM) iType = CResourceFile::RESOURCE_FILE_TYPE_CONFIG; if (strType != "server") { - CLogger::LogPrintf("WARNING: Unknown config file type specified for %s. Defaulting to 'server'", lua_tostring(luaVM, lua_upvalueindex(1))); + CLogger::LogPrintf("WARNING: Unknown config file type specified for %s. Defaulting to 'server'\n", lua_tostring(luaVM, lua_upvalueindex(1))); } } @@ -595,7 +595,7 @@ int CLuaResourceDefs::stopResource(lua_State* luaVM) int CLuaResourceDefs::restartResource(lua_State* luaVM) { CResource* pResource = nullptr; - bool bPersistent = false; // unused + bool bPersistent = false; // unused SResourceStartOptions StartOptions; CScriptArgReader argStream(luaVM); @@ -1140,7 +1140,7 @@ int CLuaResourceDefs::call(lua_State* luaVM) args.ReadArguments(luaVM, 3); CLuaArguments returns; - LUA_CHECKSTACK(targetLuaVM, 1); // Ensure some room + LUA_CHECKSTACK(targetLuaVM, 1); // Ensure some room // Lets grab the original hidden variables so we can restore them later lua_getglobal(targetLuaVM, "sourceResource"); @@ -1237,10 +1237,10 @@ int CLuaResourceDefs::getResourceACLRequests(lua_State* luaVM) lua_newtable(luaVM); for (uint i = 0; i < Result.size(); i++) { - lua_newtable(luaVM); // new table - lua_pushnumber(luaVM, i + 1); // row index number (starting at 1, not 0) - lua_pushvalue(luaVM, -2); // value - lua_settable(luaVM, -4); // refer to the top level table + lua_newtable(luaVM); // new table + lua_pushnumber(luaVM, i + 1); // row index number (starting at 1, not 0) + lua_pushvalue(luaVM, -2); // value + lua_settable(luaVM, -4); // refer to the top level table const SAclRequest& request = Result[i]; lua_pushstring(luaVM, "name"); @@ -1263,7 +1263,7 @@ int CLuaResourceDefs::getResourceACLRequests(lua_State* luaVM) lua_pushstring(luaVM, request.strDate); lua_settable(luaVM, -3); - lua_pop(luaVM, 1); // pop the inner table + lua_pop(luaVM, 1); // pop the inner table } return 1; } diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h index 69524ece50e..8739dd658a3 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h @@ -55,7 +55,7 @@ class CLuaResourceDefs : public CLuaDefs LUA_DECLARE(isResourceArchived); static std::string GetResourceName(lua_State* luaVM, std::optional resourceElement); - static bool isResourceProtected(CResource* const resource); + static bool isResourceProtected(CResource* const resource); // Set stuff LUA_DECLARE(setResourceInfo); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaTeamDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaTeamDefs.cpp index f81c0c06844..e4d7f7ea24e 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaTeamDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaTeamDefs.cpp @@ -15,24 +15,22 @@ void CLuaTeamDefs::LoadFunctions() { - constexpr static const std::pair functions[]{ - // Team create/destroy functions - {"createTeam", ArgumentParserWarn}, - - // Team get funcs - {"getTeamName", ArgumentParserWarn}, - {"getTeamFromName", ArgumentParserWarn}, - {"getTeamColor", ArgumentParserWarn}, - {"getTeamFriendlyFire", ArgumentParserWarn}, - {"getPlayersInTeam", ArgumentParserWarn}, - {"countPlayersInTeam", ArgumentParserWarn}, - - // Team set funcs - {"setPlayerTeam", ArgumentParserWarn}, - {"setTeamName", ArgumentParserWarn}, - {"setTeamColor", ArgumentParserWarn}, - {"setTeamFriendlyFire", ArgumentParserWarn} - }; + constexpr static const std::pair functions[]{// Team create/destroy functions + {"createTeam", ArgumentParserWarn}, + + // Team get funcs + {"getTeamName", ArgumentParserWarn}, + {"getTeamFromName", ArgumentParserWarn}, + {"getTeamColor", ArgumentParserWarn}, + {"getTeamFriendlyFire", ArgumentParserWarn}, + {"getPlayersInTeam", ArgumentParserWarn}, + {"countPlayersInTeam", ArgumentParserWarn}, + + // Team set funcs + {"setPlayerTeam", ArgumentParserWarn}, + {"setTeamName", ArgumentParserWarn}, + {"setTeamColor", ArgumentParserWarn}, + {"setTeamFriendlyFire", ArgumentParserWarn}}; // Add functions for (const auto& [name, func] : functions) @@ -48,7 +46,7 @@ void CLuaTeamDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "countPlayers", "countPlayersInTeam"); lua_classfunction(luaVM, "getPlayers", "getPlayersInTeam"); lua_classfunction(luaVM, "outputChat", "outputChatBox", ArgumentParserWarn); - + lua_classfunction(luaVM, "getFriendlyFire", "getTeamFriendlyFire"); lua_classfunction(luaVM, "getName", "getTeamName"); lua_classfunction(luaVM, "getColor", "getTeamColor"); @@ -65,9 +63,10 @@ void CLuaTeamDefs::AddClass(lua_State* luaVM) lua_registerclass(luaVM, "Team", "Element"); } -std::variant CLuaTeamDefs::CreateTeam(lua_State* lua, const std::string name, const std::optional red, const std::optional green, const std::optional blue) +std::variant CLuaTeamDefs::CreateTeam(lua_State* lua, const std::string name, const std::optional red, + const std::optional green, const std::optional blue) { - CLuaMain& vm = lua_getownercluamain(lua); + CLuaMain& vm = lua_getownercluamain(lua); CResource* resource = vm.GetResource(); if (!resource) diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaTeamDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaTeamDefs.h index 5e309460aab..4caf9c6a8d1 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaTeamDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaTeamDefs.h @@ -19,15 +19,16 @@ class CLuaTeamDefs : public CLuaDefs private: // Team create/destroy functions - static std::variant CreateTeam(lua_State* lua, const std::string name, const std::optional red, const std::optional green, const std::optional blue); + static std::variant CreateTeam(lua_State* lua, const std::string name, const std::optional red, + const std::optional green, const std::optional blue); // Team get funcs - static std::variant GetTeamFromName(const std::string name); - static std::string GetTeamName(CTeam* team); + static std::variant GetTeamFromName(const std::string name); + static std::string GetTeamName(CTeam* team); static CLuaMultiReturn GetTeamColor(CTeam* team) noexcept; - static bool GetTeamFriendlyFire(CTeam* team) noexcept; - static std::vector GetPlayersInTeam(CTeam* team); - static std::uint32_t CountPlayersInTeam(CTeam* team) noexcept; + static bool GetTeamFriendlyFire(CTeam* team) noexcept; + static std::vector GetPlayersInTeam(CTeam* team); + static std::uint32_t CountPlayersInTeam(CTeam* team) noexcept; // Team set funcs static bool SetPlayerTeam(CPlayer* player, std::optional team) noexcept; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaTextDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaTextDefs.cpp index a328869d87f..b2453e97459 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaTextDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaTextDefs.cpp @@ -174,14 +174,14 @@ int CLuaTextDefs::textCreateTextItem(lua_State* luaVM) { unsigned char ucFormat = 0; if (strHorzAlign == "center") - ucFormat |= 0x00000001; // DT_CENTER + ucFormat |= 0x00000001; // DT_CENTER else if (strHorzAlign == "right") - ucFormat |= 0x00000002; // DT_RIGHT + ucFormat |= 0x00000002; // DT_RIGHT if (strVertAlign == "center") - ucFormat |= 0x00000004; // DT_VCENTER + ucFormat |= 0x00000004; // DT_VCENTER else if (strVertAlign == "bottom") - ucFormat |= 0x00000008; // DT_BOTTOM + ucFormat |= 0x00000008; // DT_BOTTOM // Grab our virtual machine CLuaMain* luaMain = m_pLuaManager->GetVirtualMachine(luaVM); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaTextDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaTextDefs.h index 04cba64314c..1865755ae73 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaTextDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaTextDefs.h @@ -40,4 +40,4 @@ class CLuaTextDefs : public CLuaDefs LUA_DECLARE(textItemGetColor); LUA_DECLARE(textItemSetPriority); LUA_DECLARE(textItemGetPriority); -}; \ No newline at end of file +}; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp index 857f70b443c..fb234bccbdc 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp @@ -16,9 +16,14 @@ void CLuaTimerDefs::LoadFunctions() { constexpr static const std::pair functions[]{ - {"setTimer", SetTimer}, {"killTimer", KillTimer}, {"resetTimer", ResetTimer}, - {"setTimerPaused", ArgumentParser},{"isTimerPaused", ArgumentParser}, - {"getTimers", GetTimers}, {"isTimer", IsTimer},{"getTimerDetails", GetTimerDetails}, + {"setTimer", SetTimer}, + {"killTimer", KillTimer}, + {"resetTimer", ResetTimer}, + {"setTimerPaused", ArgumentParser}, + {"isTimerPaused", ArgumentParser}, + {"getTimers", GetTimers}, + {"isTimer", IsTimer}, + {"getTimerDetails", GetTimerDetails}, }; // Add functions diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp index 13d72615fcd..63f0565b73c 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp @@ -17,6 +17,8 @@ #include "CScriptArgReader.h" #include "packets/CElementRPCPacket.h" +#include "lua/CLuaShared.h" // for CLuaShared::CustomTrainTracks + void CLuaVehicleDefs::LoadFunctions() { constexpr static const std::pair functions[]{ @@ -64,7 +66,6 @@ void CLuaVehicleDefs::LoadFunctions() {"isTrainDerailable", IsTrainDerailable}, {"getTrainDirection", GetTrainDirection}, {"getTrainSpeed", GetTrainSpeed}, - //{"getTrainTrack", ArgumentParser}, {"getTrainPosition", GetTrainPosition}, {"isVehicleBlown", ArgumentParserWarn}, {"getVehicleHeadLightColor", GetVehicleHeadLightColor}, @@ -115,7 +116,6 @@ void CLuaVehicleDefs::LoadFunctions() {"setTrainDerailable", SetTrainDerailable}, {"setTrainDirection", SetTrainDirection}, {"setTrainSpeed", SetTrainSpeed}, - //{"setTrainTrack", ArgumentParser}, {"setTrainPosition", SetTrainPosition}, {"setVehicleHeadLightColor", SetVehicleHeadLightColor}, {"setVehicleTurretPosition", SetVehicleTurretPosition}, @@ -133,6 +133,13 @@ void CLuaVehicleDefs::LoadFunctions() // Add functions for (const auto& [name, func] : functions) CLuaCFunctions::AddFunction(name, func); + + // Add train track related functions + if (CLuaShared::CustomTrainTracks) + { + CLuaCFunctions::AddFunction("getTrainTrack", ArgumentParser); + CLuaCFunctions::AddFunction("setTrainTrack", ArgumentParser); + } } void CLuaVehicleDefs::AddClass(lua_State* luaVM) @@ -175,7 +182,8 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "getSirens", "getVehicleSirens"); lua_classfunction(luaVM, "getDirection", "getTrainDirection"); lua_classfunction(luaVM, "getTrainSpeed", "getTrainSpeed"); - // lua_classfunction(luaVM, "getTrack", "getTrainTrack"); + if (CLuaShared::CustomTrainTracks) + lua_classfunction(luaVM, "getTrainTrack", "getTrainTrack"); lua_classfunction(luaVM, "getTrainPosition", "getTrainPosition"); lua_classfunction(luaVM, "getHeadLightColor", "getVehicleHeadLightColor"); lua_classfunction(luaVM, "getColor", "getVehicleColor"); @@ -198,7 +206,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "getTowingVehicle", "getVehicleTowingVehicle"); lua_classfunction(luaVM, "getTurnVelocity", "getVehicleTurnVelocity", CLuaVehicleDefs::OOP_GetVehicleTurnVelocity); lua_classfunction(luaVM, "getTurretPosition", "getVehicleTurretPosition"); - lua_classfunction(luaVM, "getVehicleType", "getVehicleType"); // This isn't "getType" because it would overwrite Element.getType + lua_classfunction(luaVM, "getVehicleType", "getVehicleType"); // This isn't "getType" because it would overwrite Element.getType lua_classfunction(luaVM, "getUpgradeOnSlot", "getVehicleUpgradeOnSlot"); lua_classfunction(luaVM, "getUpgrades", "getVehicleUpgrades"); lua_classfunction(luaVM, "getWheelStates", "getVehicleWheelStates"); @@ -240,9 +248,10 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "setDerailable", "setTrainDerailable"); lua_classfunction(luaVM, "setDerailed", "setTrainDerailed"); lua_classfunction(luaVM, "setDirection", "setTrainDirection"); - // lua_classfunction(luaVM, "setTrack", "setTrainTrack"); + if (CLuaShared::CustomTrainTracks) + lua_classfunction(luaVM, "setTrainTrack", "setTrainTrack"); lua_classfunction(luaVM, "setTrainPosition", "setTrainPosition"); - lua_classfunction(luaVM, "setTrainSpeed", "setTrainSpeed"); // Reduce confusion + lua_classfunction(luaVM, "setTrainSpeed", "setTrainSpeed"); // Reduce confusion lua_classfunction(luaVM, "spawnFlyingComponent", "spawnVehicleFlyingComponent"); lua_classvariable(luaVM, "damageProof", "setVehicleDamageProof", "isVehicleDamageProof"); @@ -252,7 +261,8 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classvariable(luaVM, "blown", "blowVehicle", "isVehicleBlown"); lua_classvariable(luaVM, "direction", "setTrainDirection", "getTrainDirection"); lua_classvariable(luaVM, "trainSpeed", "setTrainSpeed", "getTrainSpeed"); - // lua_classvariable(luaVM, "track", "setTrainTrack", "getTrainTrack"); + if (CLuaShared::CustomTrainTracks) + lua_classvariable(luaVM, "trainTrack", "setTrainTrack", "getTrainTrack"); lua_classvariable(luaVM, "trainPosition", "setTrainPosition", "getTrainPosition"); lua_classvariable(luaVM, "taxiLightOn", "setVehicleTaxiLightOn", "isVehicleTaxiLightOn"); lua_classvariable(luaVM, "fuelTankExplodable", "setVehicleFuelTankExplodable", "isVehicleFuelTankExplodable"); @@ -638,37 +648,37 @@ int CLuaVehicleDefs::GetVehicleSirenParams(lua_State* luaVM) argStream.ReadUserData(pVehicle); if (argStream.HasErrors() == false) { - tSirenInfo = pVehicle->m_tSirenBeaconInfo; // Create a new table + tSirenInfo = pVehicle->m_tSirenBeaconInfo; // Create a new table lua_newtable(luaVM); lua_pushstring(luaVM, "SirenCount"); lua_pushnumber(luaVM, tSirenInfo.m_ucSirenCount); - lua_settable(luaVM, -3); // End of SirenCount Property + lua_settable(luaVM, -3); // End of SirenCount Property lua_pushstring(luaVM, "SirenType"); lua_pushnumber(luaVM, tSirenInfo.m_ucSirenType); - lua_settable(luaVM, -3); // End of SirenType Property + lua_settable(luaVM, -3); // End of SirenType Property lua_pushstring(luaVM, "Flags"); lua_newtable(luaVM); lua_pushstring(luaVM, "360"); lua_pushboolean(luaVM, tSirenInfo.m_b360Flag); - lua_settable(luaVM, -3); // End of 360 Property + lua_settable(luaVM, -3); // End of 360 Property lua_pushstring(luaVM, "DoLOSCheck"); lua_pushboolean(luaVM, tSirenInfo.m_bDoLOSCheck); - lua_settable(luaVM, -3); // End of DoLOSCheck Property + lua_settable(luaVM, -3); // End of DoLOSCheck Property lua_pushstring(luaVM, "UseRandomiser"); lua_pushboolean(luaVM, tSirenInfo.m_bUseRandomiser); - lua_settable(luaVM, -3); // End of UseRandomiser Property + lua_settable(luaVM, -3); // End of UseRandomiser Property lua_pushstring(luaVM, "Silent"); lua_pushboolean(luaVM, tSirenInfo.m_bSirenSilent); - lua_settable(luaVM, -3); // End of Silent Property + lua_settable(luaVM, -3); // End of Silent Property - lua_settable(luaVM, -3); // End of Flags table + lua_settable(luaVM, -3); // End of Flags table return 1; } @@ -688,7 +698,7 @@ int CLuaVehicleDefs::GetVehicleSirens(lua_State* luaVM) argStream.ReadUserData(pVehicle); if (argStream.HasErrors() == false) { - tSirenInfo = pVehicle->m_tSirenBeaconInfo; // Create a new table + tSirenInfo = pVehicle->m_tSirenBeaconInfo; // Create a new table lua_newtable(luaVM); for (int i = 0; i < tSirenInfo.m_ucSirenCount; i++) @@ -700,37 +710,37 @@ int CLuaVehicleDefs::GetVehicleSirens(lua_State* luaVM) lua_pushstring(luaVM, "Min_Alpha"); lua_pushnumber(luaVM, info.m_dwMinSirenAlpha); - lua_settable(luaVM, -3); // End of Min_Alpha property + lua_settable(luaVM, -3); // End of Min_Alpha property lua_pushstring(luaVM, "Red"); lua_pushnumber(luaVM, info.m_RGBBeaconColour.R); - lua_settable(luaVM, -3); // End of Red property + lua_settable(luaVM, -3); // End of Red property lua_pushstring(luaVM, "Green"); lua_pushnumber(luaVM, info.m_RGBBeaconColour.G); - lua_settable(luaVM, -3); // End of Green property + lua_settable(luaVM, -3); // End of Green property lua_pushstring(luaVM, "Blue"); lua_pushnumber(luaVM, info.m_RGBBeaconColour.B); - lua_settable(luaVM, -3); // End of Blue property + lua_settable(luaVM, -3); // End of Blue property lua_pushstring(luaVM, "Alpha"); lua_pushnumber(luaVM, info.m_RGBBeaconColour.A); - lua_settable(luaVM, -3); // End of Alpha property + lua_settable(luaVM, -3); // End of Alpha property lua_pushstring(luaVM, "x"); lua_pushnumber(luaVM, info.m_vecSirenPositions.fX); - lua_settable(luaVM, -3); // End of X property + lua_settable(luaVM, -3); // End of X property lua_pushstring(luaVM, "y"); lua_pushnumber(luaVM, info.m_vecSirenPositions.fY); - lua_settable(luaVM, -3); // End of Y property + lua_settable(luaVM, -3); // End of Y property lua_pushstring(luaVM, "z"); lua_pushnumber(luaVM, info.m_vecSirenPositions.fZ); - lua_settable(luaVM, -3); // End of Z property + lua_settable(luaVM, -3); // End of Z property - lua_settable(luaVM, -3); // End of Table + lua_settable(luaVM, -3); // End of Table } return 1; @@ -1471,7 +1481,7 @@ int CLuaVehicleDefs::GetVehiclePlateText(lua_State* luaVM) if (!argStream.HasErrors()) { - char szPlateText[9] = {0}; // 8 chars + \0 + char szPlateText[9] = {0}; // 8 chars + \0 if (CStaticFunctionDefinitions::GetVehiclePlateText(pVehicle, szPlateText)) { lua_pushstring(luaVM, szPlateText); @@ -2813,9 +2823,7 @@ bool CLuaVehicleDefs::SetTrainTrack(CVehicle* pVehicle, CTrainTrack* pTrainTrack if (pVehicle->GetVehicleType() != VEHICLE_TRAIN) return false; else if (pVehicle->IsDerailed()) - { return false; - } // TODO(qaisjp, feature/custom-train-tracks): this needs to support non-default train tracks if (!pTrainTrack->IsDefault()) @@ -2990,10 +2998,12 @@ int CLuaVehicleDefs::SetVehiclePlateText(lua_State* luaVM) return 1; } -bool CLuaVehicleDefs::SpawnVehicleFlyingComponent(CVehicle* const vehicle, std::uint8_t nodeIndex, std::optional componentCollisionType, std::optional removalTime) +bool CLuaVehicleDefs::SpawnVehicleFlyingComponent(CVehicle* const vehicle, std::uint8_t nodeIndex, std::optional componentCollisionType, + std::optional removalTime) { auto partNodeIndex = static_cast(nodeIndex); - auto collisionType = componentCollisionType.has_value() ? static_cast(componentCollisionType.value()) : eCarComponentCollisionTypes::COL_NODE_PANEL; + auto collisionType = componentCollisionType.has_value() ? static_cast(componentCollisionType.value()) + : eCarComponentCollisionTypes::COL_NODE_PANEL; if (nodeIndex < 1 || partNodeIndex >= eCarNodes::NUM_NODES) throw std::invalid_argument("Invalid component index"); @@ -3059,4 +3069,4 @@ bool CLuaVehicleDefs::SetVehicleNitroActivated(CVehicle* vehicle, bool state) no m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(vehicle, SET_VEHICLE_NITRO_ACTIVATED, *BitStream.pBitStream)); return true; -} \ No newline at end of file +} diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h index 38652371c00..8fb2530b6a6 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h @@ -92,7 +92,7 @@ class CLuaVehicleDefs : public CLuaDefs LUA_DECLARE(SetVehicleRespawnRotation); LUA_DECLARE_OOP(GetVehicleRespawnPosition); LUA_DECLARE_OOP(GetVehicleRespawnRotation); - static bool IsVehicleRespawnable(CVehicle* vehicle) noexcept; + static bool IsVehicleRespawnable(CVehicle* vehicle) noexcept; static uint32_t GetVehicleRespawnDelay(CVehicle* vehicle) noexcept; static uint32_t GetVehicleIdleRespawnDelay(CVehicle* vehicle) noexcept; LUA_DECLARE(ToggleVehicleRespawn); @@ -125,7 +125,8 @@ class CLuaVehicleDefs : public CLuaDefs LUA_DECLARE(GetVehicleSirens); LUA_DECLARE(GetVehicleSirenParams); LUA_DECLARE(SetVehiclePlateText); - - static bool SpawnVehicleFlyingComponent(CVehicle* const vehicle, std::uint8_t nodeIndex, std::optional componentCollisionType, std::optional removalTime); + + static bool SpawnVehicleFlyingComponent(CVehicle* const vehicle, std::uint8_t nodeIndex, std::optional componentCollisionType, + std::optional removalTime); static bool SetVehicleNitroActivated(CVehicle* vehicle, bool state) noexcept; }; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaVoiceDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaVoiceDefs.h index 22ec6567046..9a54ca38533 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaVoiceDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaVoiceDefs.h @@ -19,4 +19,4 @@ class CLuaVoiceDefs : public CLuaDefs LUA_DECLARE(IsVoiceEnabled); LUA_DECLARE(SetPlayerVoiceBroadcastTo); LUA_DECLARE(setPlayerVoiceIgnoreFrom); -}; \ No newline at end of file +}; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaWaterDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaWaterDefs.h index 31a55fcb9bb..5b8e007c549 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaWaterDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaWaterDefs.h @@ -26,4 +26,4 @@ class CLuaWaterDefs : public CLuaDefs LUA_DECLARE(GetWaterColor); LUA_DECLARE(SetWaterColor); LUA_DECLARE(ResetWaterColor); -}; \ No newline at end of file +}; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp index c46e1872bc7..2e6d521400c 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp @@ -16,84 +16,85 @@ void CLuaWorldDefs::LoadFunctions() { - constexpr static const std::pair functions[]{// Get - {"getTime", getTime}, - {"getWeather", getWeather}, - {"getZoneName", getZoneName}, - {"getGravity", getGravity}, - {"getGameSpeed", getGameSpeed}, - {"getWaveHeight", getWaveHeight}, - {"getFPSLimit", getFPSLimit}, - {"getMinuteDuration", getMinuteDuration}, - {"getTrafficLightState", getTrafficLightState}, - {"getJetpackMaxHeight", getJetpackMaxHeight}, - {"getSkyGradient", getSkyGradient}, - {"getHeatHaze", getHeatHaze}, - {"getJetpackWeaponEnabled", getJetpackWeaponEnabled}, - {"getCloudsEnabled", getCloudsEnabled}, - {"getInteriorSoundsEnabled", getInteriorSoundsEnabled}, - {"getRainLevel", getRainLevel}, - {"getSunSize", getSunSize}, - {"getSunColor", getSunColor}, - {"getWindVelocity", getWindVelocity}, - {"getFarClipDistance", getFarClipDistance}, - {"getFogDistance", getFogDistance}, - {"getAircraftMaxHeight", getAircraftMaxHeight}, - {"getAircraftMaxVelocity", getAircraftMaxVelocity}, - {"getOcclusionsEnabled", getOcclusionsEnabled}, - {"getMoonSize", getMoonSize}, - - // Set - {"setTime", setTime}, - {"setWeather", setWeather}, - {"setWeatherBlended", setWeatherBlended}, - {"setGravity", setGravity}, - {"setGameSpeed", setGameSpeed}, - {"setWaveHeight", setWaveHeight}, - {"setSkyGradient", setSkyGradient}, - {"setHeatHaze", setHeatHaze}, - {"setFPSLimit", setFPSLimit}, - {"setMinuteDuration", setMinuteDuration}, - {"setGarageOpen", setGarageOpen}, - {"setGlitchEnabled", setGlitchEnabled}, - {"setCloudsEnabled", setCloudsEnabled}, - {"setTrafficLightState", setTrafficLightState}, - {"setTrafficLightsLocked", setTrafficLightsLocked}, - {"setJetpackMaxHeight", setJetpackMaxHeight}, - {"setInteriorSoundsEnabled", setInteriorSoundsEnabled}, - {"setRainLevel", setRainLevel}, - {"setSunSize", setSunSize}, - {"setSunColor", setSunColor}, - {"setWindVelocity", setWindVelocity}, - {"setFarClipDistance", setFarClipDistance}, - {"setFogDistance", setFogDistance}, - {"setAircraftMaxHeight", setAircraftMaxHeight}, - {"setAircraftMaxVelocity", setAircraftMaxVelocity}, - {"setOcclusionsEnabled", setOcclusionsEnabled}, - {"setMoonSize", setMoonSize}, - {"setJetpackWeaponEnabled", setJetpackWeaponEnabled}, - {"setWorldSpecialPropertyEnabled", ArgumentParserWarn}, - - // Reset - {"resetSkyGradient", resetSkyGradient}, - {"resetHeatHaze", resetHeatHaze}, - {"resetRainLevel", resetRainLevel}, - {"resetSunSize", resetSunSize}, - {"resetSunColor", resetSunColor}, - {"resetWindVelocity", resetWindVelocity}, - {"resetFarClipDistance", resetFarClipDistance}, - {"resetFogDistance", resetFogDistance}, - {"removeWorldModel", RemoveWorldModel}, - {"restoreWorldModel", RestoreWorldModel}, - {"restoreAllWorldModels", RestoreAllWorldModels}, - {"resetMoonSize", resetMoonSize}, - {"resetWorldProperties", ArgumentParser}, - - // Check - {"isGarageOpen", isGarageOpen}, - {"isGlitchEnabled", isGlitchEnabled}, - {"isWorldSpecialPropertyEnabled", ArgumentParserWarn}, - {"areTrafficLightsLocked", areTrafficLightsLocked}}; + constexpr static const std::pair functions[]{ + // Get + {"getTime", getTime}, + {"getWeather", getWeather}, + {"getZoneName", getZoneName}, + {"getGravity", getGravity}, + {"getGameSpeed", getGameSpeed}, + {"getWaveHeight", getWaveHeight}, + {"getFPSLimit", getFPSLimit}, + {"getMinuteDuration", getMinuteDuration}, + {"getTrafficLightState", getTrafficLightState}, + {"getJetpackMaxHeight", getJetpackMaxHeight}, + {"getSkyGradient", getSkyGradient}, + {"getHeatHaze", getHeatHaze}, + {"getJetpackWeaponEnabled", getJetpackWeaponEnabled}, + {"getCloudsEnabled", getCloudsEnabled}, + {"getInteriorSoundsEnabled", getInteriorSoundsEnabled}, + {"getRainLevel", getRainLevel}, + {"getSunSize", getSunSize}, + {"getSunColor", getSunColor}, + {"getWindVelocity", getWindVelocity}, + {"getFarClipDistance", getFarClipDistance}, + {"getFogDistance", getFogDistance}, + {"getAircraftMaxHeight", getAircraftMaxHeight}, + {"getAircraftMaxVelocity", getAircraftMaxVelocity}, + {"getOcclusionsEnabled", getOcclusionsEnabled}, + {"getMoonSize", getMoonSize}, + + // Set + {"setTime", setTime}, + {"setWeather", setWeather}, + {"setWeatherBlended", setWeatherBlended}, + {"setGravity", setGravity}, + {"setGameSpeed", setGameSpeed}, + {"setWaveHeight", setWaveHeight}, + {"setSkyGradient", setSkyGradient}, + {"setHeatHaze", setHeatHaze}, + {"setFPSLimit", setFPSLimit}, + {"setMinuteDuration", setMinuteDuration}, + {"setGarageOpen", setGarageOpen}, + {"setGlitchEnabled", setGlitchEnabled}, + {"setCloudsEnabled", setCloudsEnabled}, + {"setTrafficLightState", setTrafficLightState}, + {"setTrafficLightsLocked", setTrafficLightsLocked}, + {"setJetpackMaxHeight", setJetpackMaxHeight}, + {"setInteriorSoundsEnabled", setInteriorSoundsEnabled}, + {"setRainLevel", setRainLevel}, + {"setSunSize", setSunSize}, + {"setSunColor", setSunColor}, + {"setWindVelocity", setWindVelocity}, + {"setFarClipDistance", setFarClipDistance}, + {"setFogDistance", setFogDistance}, + {"setAircraftMaxHeight", setAircraftMaxHeight}, + {"setAircraftMaxVelocity", setAircraftMaxVelocity}, + {"setOcclusionsEnabled", setOcclusionsEnabled}, + {"setMoonSize", setMoonSize}, + {"setJetpackWeaponEnabled", setJetpackWeaponEnabled}, + {"setWorldSpecialPropertyEnabled", ArgumentParserWarn}, + + // Reset + {"resetSkyGradient", resetSkyGradient}, + {"resetHeatHaze", resetHeatHaze}, + {"resetRainLevel", resetRainLevel}, + {"resetSunSize", resetSunSize}, + {"resetSunColor", resetSunColor}, + {"resetWindVelocity", resetWindVelocity}, + {"resetFarClipDistance", resetFarClipDistance}, + {"resetFogDistance", resetFogDistance}, + {"removeWorldModel", RemoveWorldModel}, + {"restoreWorldModel", RestoreWorldModel}, + {"restoreAllWorldModels", RestoreAllWorldModels}, + {"resetMoonSize", resetMoonSize}, + {"resetWorldProperties", ArgumentParser}, + + // Check + {"isGarageOpen", isGarageOpen}, + {"isGlitchEnabled", isGlitchEnabled}, + {"isWorldSpecialPropertyEnabled", ArgumentParserWarn}, + {"areTrafficLightsLocked", areTrafficLightsLocked}}; // Add functions for (const auto& [name, func] : functions) @@ -119,11 +120,11 @@ int CLuaWorldDefs::getTime(lua_State* luaVM) int CLuaWorldDefs::getWeather(lua_State* luaVM) { - unsigned char ucWeather, ucWeatherBlendingTo; + unsigned char ucWeather; + unsigned char ucWeatherBlendingTo; if (CStaticFunctionDefinitions::GetWeather(ucWeather, ucWeatherBlendingTo)) { lua_pushnumber(luaVM, static_cast(ucWeather)); - if (ucWeatherBlendingTo != 0xFF) lua_pushnumber(luaVM, static_cast(ucWeatherBlendingTo)); else @@ -202,14 +203,11 @@ int CLuaWorldDefs::getWaveHeight(lua_State* luaVM) int CLuaWorldDefs::getFPSLimit(lua_State* luaVM) { - unsigned short usLimit; - if (CStaticFunctionDefinitions::GetFPSLimit(usLimit)) - { - lua_pushnumber(luaVM, usLimit); - return 1; - } + // int getFPSLimit () + std::uint16_t fpsLimit; + CStaticFunctionDefinitions::GetFPSLimit(fpsLimit); - lua_pushboolean(luaVM, false); + lua_pushnumber(luaVM, fpsLimit); return 1; } @@ -237,7 +235,7 @@ int CLuaWorldDefs::isGarageOpen(lua_State* luaVM) if (!argStream.HasErrors()) { bool bIsOpen; - if (CStaticFunctionDefinitions::IsGarageOpen(iGarageID, bIsOpen)) + if (CStaticFunctionDefinitions::IsGarageOpen(static_cast(iGarageID), bIsOpen)) { lua_pushboolean(luaVM, bIsOpen); return 1; @@ -319,7 +317,7 @@ int CLuaWorldDefs::setTrafficLightState(lua_State* luaVM) if (!argStream.HasErrors()) { - if (CStaticFunctionDefinitions::SetTrafficLightState(iState)) + if (CStaticFunctionDefinitions::SetTrafficLightState(static_cast(iState))) { lua_pushboolean(luaVM, true); return 1; @@ -430,7 +428,7 @@ int CLuaWorldDefs::setWeather(lua_State* luaVM) if (!argStream.HasErrors()) { - if (CStaticFunctionDefinitions::SetWeather(iWeather)) + if (CStaticFunctionDefinitions::SetWeather(static_cast(iWeather))) { lua_pushboolean(luaVM, true); return 1; @@ -454,7 +452,7 @@ int CLuaWorldDefs::setWeatherBlended(lua_State* luaVM) if (!argStream.HasErrors()) { - if (CStaticFunctionDefinitions::SetWeatherBlended(iWeather)) + if (CStaticFunctionDefinitions::SetWeatherBlended(static_cast(iWeather))) { lua_pushboolean(luaVM, true); return 1; @@ -1130,15 +1128,15 @@ int CLuaWorldDefs::RestoreAllWorldModels(lua_State* luaVM) int CLuaWorldDefs::setFPSLimit(lua_State* luaVM) { - // bool setFPSLimit ( int fpsLimit ) - unsigned short usLimit; + // bool setFPSLimit ( int fpsLimit ) + std::uint16_t fps; CScriptArgReader argStream(luaVM); - argStream.ReadNumber(usLimit); + argStream.ReadNumber(fps); if (!argStream.HasErrors()) { - if (CStaticFunctionDefinitions::SetFPSLimit(usLimit, false)) + if (CStaticFunctionDefinitions::SetFPSLimit(fps, false)) { lua_pushboolean(luaVM, true); return 1; @@ -1450,7 +1448,11 @@ int CLuaWorldDefs::getOcclusionsEnabled(lua_State* luaVM) return 1; } -void CLuaWorldDefs::ResetWorldProperties(std::optional resetSpecialWorldProperties, std::optional resetWorldProperties, std::optional resetWeatherProperties, std::optional resetLODs, std::optional resetSounds, std::optional resetGlitches, std::optional resetJetpackWeapons) noexcept +void CLuaWorldDefs::ResetWorldProperties(std::optional resetSpecialWorldProperties, std::optional resetWorldProperties, + std::optional resetWeatherProperties, std::optional resetLODs, std::optional resetSounds, + std::optional resetGlitches, std::optional resetJetpackWeapons) noexcept { - g_pGame->ResetWorldProperties(ResetWorldPropsInfo{resetSpecialWorldProperties.value_or(true), resetWorldProperties.value_or(true), resetWeatherProperties.value_or(true), resetLODs.value_or(true), resetSounds.value_or(true), resetGlitches.value_or(true), resetJetpackWeapons.value_or(true)}); + g_pGame->ResetWorldProperties(ResetWorldPropsInfo{resetSpecialWorldProperties.value_or(true), resetWorldProperties.value_or(true), + resetWeatherProperties.value_or(true), resetLODs.value_or(true), resetSounds.value_or(true), + resetGlitches.value_or(true), resetJetpackWeapons.value_or(true)}); } diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h index 49032579b38..be9a0d9dce8 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h @@ -95,5 +95,7 @@ class CLuaWorldDefs : public CLuaDefs LUA_DECLARE(RestoreAllWorldModels); LUA_DECLARE(resetMoonSize); - static void ResetWorldProperties(std::optional resetSpecialWorldProperties, std::optional resetWorldProperties, std::optional resetWeatherProperties, std::optional resetLODs, std::optional resetSounds, std::optional resetGlitches, std::optional resetJetpackWeapons) noexcept; + static void ResetWorldProperties(std::optional resetSpecialWorldProperties, std::optional resetWorldProperties, + std::optional resetWeatherProperties, std::optional resetLODs, std::optional resetSounds, + std::optional resetGlitches, std::optional resetJetpackWeapons) noexcept; }; diff --git a/Server/mods/deathmatch/logic/net/CNetBuffer.cpp b/Server/mods/deathmatch/logic/net/CNetBuffer.cpp index 292111c2b48..c0e461f8ce0 100644 --- a/Server/mods/deathmatch/logic/net/CNetBuffer.cpp +++ b/Server/mods/deathmatch/logic/net/CNetBuffer.cpp @@ -102,7 +102,7 @@ namespace ms_StatsSendCmdsTotal += ms_StatsSendNumCommands; ms_StatsSendCmdsMax = std::max(ms_StatsSendCmdsMax, ms_StatsSendNumCommands); } -} // namespace +} // namespace /////////////////////////////////////////////////////////////////////////// // @@ -237,7 +237,7 @@ void CNetServerBuffer::DoPulse() shared.m_Mutex.Lock(); fSyncFPS = static_cast(shared.m_iThreadFrameCount); shared.m_iThreadFrameCount = 0; - shared.m_iuGamePlayerCount = g_pGame->GetPlayerManager()->Count(); // Also update player count here (for scaling buffer size checks) + shared.m_iuGamePlayerCount = g_pGame->GetPlayerManager()->Count(); // Also update player count here (for scaling buffer size checks) shared.m_Mutex.Unlock(); // Compress high counts @@ -1089,29 +1089,54 @@ void CNetServerBuffer::ProcessCommand(CNetJobData* pJobData) #define CALLPRE0(func) \ case TYPE_##func: \ { - #define CALLPRE(func) \ case TYPE_##func: \ { \ S##func##Args& a = *(S##func##Args*)pJobData->pArgs; -#define CALLREALNET0(func) CALLPRE0(func) m_pRealNetServer->func (); CALLPOST -#define CALLREALNET1(func,t1,n1) CALLPRE(func) m_pRealNetServer->func ( a.n1 ); CALLPOST -#define CALLREALNET2(func,t1,n1,t2,n2) CALLPRE(func) m_pRealNetServer->func ( a.n1, a.n2 ); CALLPOST -#define CALLREALNET3(func,t1,n1,t2,n2,t3,n3) CALLPRE(func) m_pRealNetServer->func ( a.n1, a.n2, a.n3 ); CALLPOST -#define CALLREALNET4(func,t1,n1,t2,n2,t3,n3,t4,n4) CALLPRE(func) m_pRealNetServer->func ( a.n1, a.n2, a.n3, a.n4 ); CALLPOST -#define CALLREALNET5(func,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5) CALLPRE(func) m_pRealNetServer->func ( a.n1, a.n2, a.n3, a.n4, a.n5 ); CALLPOST -#define CALLREALNET6(func,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6) CALLPRE(func) m_pRealNetServer->func ( a.n1, a.n2, a.n3, a.n4, a.n5, a.n6 ); CALLPOST - -#define CALLREALNET0R(ret,func) CALLPRE(func) a.result = m_pRealNetServer->func (); CALLPOST -#define CALLREALNET1R(ret,func,t1,n1) CALLPRE(func) a.result = m_pRealNetServer->func ( a.n1 ); CALLPOST -#define CALLREALNET2R(ret,func,t1,n1,t2,n2) CALLPRE(func) a.result = m_pRealNetServer->func ( a.n1, a.n2 ); CALLPOST -#define CALLREALNET3R(ret,func,t1,n1,t2,n2,t3,n3) CALLPRE(func) a.result = m_pRealNetServer->func ( a.n1, a.n2, a.n3 ); CALLPOST -#define CALLREALNET4R(ret,func,t1,n1,t2,n2,t3,n3,t4,n4) CALLPRE(func) a.result = m_pRealNetServer->func ( a.n1, a.n2, a.n3, a.n4 ); CALLPOST -#define CALLREALNET7R(ret,func,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7) CALLPRE(func) a.result = m_pRealNetServer->func ( a.n1, a.n2, a.n3, a.n4, a.n5, a.n6, a.n7 ); CALLPOST +#define CALLREALNET0(func) \ + CALLPRE0(func) m_pRealNetServer->func(); \ + CALLPOST +#define CALLREALNET1(func, t1, n1) \ + CALLPRE(func) m_pRealNetServer->func(a.n1); \ + CALLPOST +#define CALLREALNET2(func, t1, n1, t2, n2) \ + CALLPRE(func) m_pRealNetServer->func(a.n1, a.n2); \ + CALLPOST +#define CALLREALNET3(func, t1, n1, t2, n2, t3, n3) \ + CALLPRE(func) m_pRealNetServer->func(a.n1, a.n2, a.n3); \ + CALLPOST +#define CALLREALNET4(func, t1, n1, t2, n2, t3, n3, t4, n4) \ + CALLPRE(func) m_pRealNetServer->func(a.n1, a.n2, a.n3, a.n4); \ + CALLPOST +#define CALLREALNET5(func, t1, n1, t2, n2, t3, n3, t4, n4, t5, n5) \ + CALLPRE(func) m_pRealNetServer->func(a.n1, a.n2, a.n3, a.n4, a.n5); \ + CALLPOST +#define CALLREALNET6(func, t1, n1, t2, n2, t3, n3, t4, n4, t5, n5, t6, n6) \ + CALLPRE(func) m_pRealNetServer->func(a.n1, a.n2, a.n3, a.n4, a.n5, a.n6); \ + CALLPOST + +#define CALLREALNET0R(ret, func) \ + CALLPRE(func) a.result = m_pRealNetServer->func(); \ + CALLPOST +#define CALLREALNET1R(ret, func, t1, n1) \ + CALLPRE(func) a.result = m_pRealNetServer->func(a.n1); \ + CALLPOST +#define CALLREALNET2R(ret, func, t1, n1, t2, n2) \ + CALLPRE(func) a.result = m_pRealNetServer->func(a.n1, a.n2); \ + CALLPOST +#define CALLREALNET3R(ret, func, t1, n1, t2, n2, t3, n3) \ + CALLPRE(func) a.result = m_pRealNetServer->func(a.n1, a.n2, a.n3); \ + CALLPOST +#define CALLREALNET4R(ret, func, t1, n1, t2, n2, t3, n3, t4, n4) \ + CALLPRE(func) a.result = m_pRealNetServer->func(a.n1, a.n2, a.n3, a.n4); \ + CALLPOST +#define CALLREALNET7R(ret, func, t1, n1, t2, n2, t3, n3, t4, n4, t5, n5, t6, n6, t7, n7) \ + CALLPRE(func) a.result = m_pRealNetServer->func(a.n1, a.n2, a.n3, a.n4, a.n5, a.n6, a.n7); \ + CALLPOST #define CALLPOST \ - break; \ + break; \ } switch (pJobData->pArgs->type) @@ -1215,10 +1240,7 @@ void CNetServerBuffer::ProcessPacket(unsigned char ucPacketID, const NetServerPl } else if (ucPacketID == PACKET_ID_PLAYER_BULLETSYNC) { - // See about handling the packet relaying here m_pSimPlayerManager->HandleBulletSync(Socket, BitStream); - - // Reset bitstream pointer so game can also read the packet data BitStream->ResetReadPointer(); } else if (ucPacketID == PACKET_ID_PED_TASK) @@ -1291,10 +1313,10 @@ void CNetServerBuffer::GetQueueSizes(uint& uiFinishedList, uint& uiOutCommandQue bool CNetJobData::SetCallback(PFN_NETRESULT pfnNetResult, void* pContext) { if (callback.bSet) - return false; // One has already been set + return false; // One has already been set if (this->stage > EJobStage::RESULT) - return false; // Too late to set a callback now + return false; // Too late to set a callback now // Set new callback.pfnNetResult = pfnNetResult; diff --git a/Server/mods/deathmatch/logic/net/CNetBuffer.h b/Server/mods/deathmatch/logic/net/CNetBuffer.h index 6b62788c395..c2231860391 100644 --- a/Server/mods/deathmatch/logic/net/CNetBuffer.h +++ b/Server/mods/deathmatch/logic/net/CNetBuffer.h @@ -111,26 +111,110 @@ class CNetServerBuffer : public CNetServer virtual void SetNetOptions(const SNetOptions& options); virtual void GenerateRandomData(void* pOutData, uint uiLength); - // - // Macros of doom to declare function argument structures - // - #define DOTYPE(func) const static int TYPE_##func = __COUNTER__; - #define SETTYPE(func) type=TYPE_##func; - - #define DECLARE_FUNC_ARGS0(func) DOTYPE(func) struct S##func##Args : SArgs { S##func##Args ( ) {SETTYPE(func)} }; - #define DECLARE_FUNC_ARGS1(func,t1,n1) DOTYPE(func) struct S##func##Args : SArgs { S##func##Args ( t1 n1 ) : n1(n1) {SETTYPE(func)} t1 n1; }; - #define DECLARE_FUNC_ARGS2(func,t1,n1,t2,n2) DOTYPE(func) struct S##func##Args : SArgs { S##func##Args ( t1 n1,t2 n2 ) : n1(n1), n2(n2) {SETTYPE(func)} t1 n1; t2 n2; }; - #define DECLARE_FUNC_ARGS3(func,t1,n1,t2,n2,t3,n3) DOTYPE(func) struct S##func##Args : SArgs { S##func##Args ( t1 n1,t2 n2,t3 n3 ) : n1(n1), n2(n2), n3(n3) {SETTYPE(func)} t1 n1; t2 n2; t3 n3; }; - #define DECLARE_FUNC_ARGS4(func,t1,n1,t2,n2,t3,n3,t4,n4) DOTYPE(func) struct S##func##Args : SArgs { S##func##Args ( t1 n1,t2 n2,t3 n3,t4 n4 ) : n1(n1), n2(n2), n3(n3), n4(n4) {SETTYPE(func)} t1 n1; t2 n2; t3 n3; t4 n4; }; - #define DECLARE_FUNC_ARGS5(func,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5) DOTYPE(func) struct S##func##Args : SArgs { S##func##Args ( t1 n1,t2 n2,t3 n3,t4 n4,t5 n5 ) : n1(n1), n2(n2), n3(n3), n4(n4), n5(n5) {SETTYPE(func)} t1 n1; t2 n2; t3 n3; t4 n4; t5 n5; }; - #define DECLARE_FUNC_ARGS6(func,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6) DOTYPE(func) struct S##func##Args : SArgs { S##func##Args ( t1 n1,t2 n2,t3 n3,t4 n4,t5 n5,t6 n6 ) : n1(n1), n2(n2), n3(n3), n4(n4), n5(n5), n6(n6) {SETTYPE(func)} t1 n1; t2 n2; t3 n3; t4 n4; t5 n5; t6 n6; }; - - #define DECLARE_FUNC_ARGS0R(ret,func) DOTYPE(func) struct S##func##Args : SArgs { S##func##Args ( ) {SETTYPE(func)} ret result; }; - #define DECLARE_FUNC_ARGS1R(ret,func,t1,n1) DOTYPE(func) struct S##func##Args : SArgs { S##func##Args ( t1 n1 ) : n1(n1) {SETTYPE(func)} t1 n1; ret result; }; - #define DECLARE_FUNC_ARGS2R(ret,func,t1,n1,t2,n2) DOTYPE(func) struct S##func##Args : SArgs { S##func##Args ( t1 n1,t2 n2 ) : n1(n1), n2(n2) {SETTYPE(func)} t1 n1; t2 n2; ret result; }; - #define DECLARE_FUNC_ARGS3R(ret,func,t1,n1,t2,n2,t3,n3) DOTYPE(func) struct S##func##Args : SArgs { S##func##Args ( t1 n1,t2 n2,t3 n3 ) : n1(n1), n2(n2), n3(n3) {SETTYPE(func)} t1 n1; t2 n2; t3 n3; ret result; }; - #define DECLARE_FUNC_ARGS4R(ret,func,t1,n1,t2,n2,t3,n3,t4,n4) DOTYPE(func) struct S##func##Args : SArgs { S##func##Args ( t1 n1,t2 n2,t3 n3,t4 n4 ) : n1(n1), n2(n2), n3(n3), n4(n4) {SETTYPE(func)} t1 n1; t2 n2; t3 n3; t4 n4; ret result; }; - #define DECLARE_FUNC_ARGS7R(ret,func,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7) DOTYPE(func) struct S##func##Args : SArgs { S##func##Args ( t1 n1,t2 n2,t3 n3,t4 n4,t5 n5,t6 n6,t7 n7 ) : n1(n1), n2(n2), n3(n3), n4(n4), n5(n5), n6(n6), n7(n7) {SETTYPE(func)} t1 n1; t2 n2; t3 n3; t4 n4; t5 n5; t6 n6; t7 n7; ret result; }; +// +// Macros of doom to declare function argument structures +// +#define DOTYPE(func) const static int TYPE_##func = __COUNTER__; +#define SETTYPE(func) type = TYPE_##func; + +#define DECLARE_FUNC_ARGS0(func) \ + DOTYPE(func) struct S##func##Args : SArgs \ + { \ + S##func##Args() { SETTYPE(func) } \ + }; +#define DECLARE_FUNC_ARGS1(func, t1, n1) \ + DOTYPE(func) struct S##func##Args : SArgs \ + { \ + S##func##Args(t1 n1) : n1(n1){SETTYPE(func)} t1 n1; \ + }; +#define DECLARE_FUNC_ARGS2(func, t1, n1, t2, n2) \ + DOTYPE(func) struct S##func##Args : SArgs \ + { \ + S##func##Args(t1 n1, t2 n2) : n1(n1), n2(n2){SETTYPE(func)} t1 n1; \ + t2 n2; \ + }; +#define DECLARE_FUNC_ARGS3(func, t1, n1, t2, n2, t3, n3) \ + DOTYPE(func) struct S##func##Args : SArgs \ + { \ + S##func##Args(t1 n1, t2 n2, t3 n3) : n1(n1), n2(n2), n3(n3){SETTYPE(func)} t1 n1; \ + t2 n2; \ + t3 n3; \ + }; +#define DECLARE_FUNC_ARGS4(func, t1, n1, t2, n2, t3, n3, t4, n4) \ + DOTYPE(func) struct S##func##Args : SArgs \ + { \ + S##func##Args(t1 n1, t2 n2, t3 n3, t4 n4) : n1(n1), n2(n2), n3(n3), n4(n4){SETTYPE(func)} t1 n1; \ + t2 n2; \ + t3 n3; \ + t4 n4; \ + }; +#define DECLARE_FUNC_ARGS5(func, t1, n1, t2, n2, t3, n3, t4, n4, t5, n5) \ + DOTYPE(func) struct S##func##Args : SArgs \ + { \ + S##func##Args(t1 n1, t2 n2, t3 n3, t4 n4, t5 n5) : n1(n1), n2(n2), n3(n3), n4(n4), n5(n5){SETTYPE(func)} t1 n1; \ + t2 n2; \ + t3 n3; \ + t4 n4; \ + t5 n5; \ + }; +#define DECLARE_FUNC_ARGS6(func, t1, n1, t2, n2, t3, n3, t4, n4, t5, n5, t6, n6) \ + DOTYPE(func) struct S##func##Args : SArgs \ + { \ + S##func##Args(t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6) : n1(n1), n2(n2), n3(n3), n4(n4), n5(n5), n6(n6){SETTYPE(func)} t1 n1; \ + t2 n2; \ + t3 n3; \ + t4 n4; \ + t5 n5; \ + t6 n6; \ + }; + +#define DECLARE_FUNC_ARGS0R(ret, func) \ + DOTYPE(func) struct S##func##Args : SArgs \ + { \ + S##func##Args(){SETTYPE(func)} ret result; \ + }; +#define DECLARE_FUNC_ARGS1R(ret, func, t1, n1) \ + DOTYPE(func) struct S##func##Args : SArgs \ + { \ + S##func##Args(t1 n1) : n1(n1){SETTYPE(func)} t1 n1; \ + ret result; \ + }; +#define DECLARE_FUNC_ARGS2R(ret, func, t1, n1, t2, n2) \ + DOTYPE(func) struct S##func##Args : SArgs \ + { \ + S##func##Args(t1 n1, t2 n2) : n1(n1), n2(n2){SETTYPE(func)} t1 n1; \ + t2 n2; \ + ret result; \ + }; +#define DECLARE_FUNC_ARGS3R(ret, func, t1, n1, t2, n2, t3, n3) \ + DOTYPE(func) struct S##func##Args : SArgs \ + { \ + S##func##Args(t1 n1, t2 n2, t3 n3) : n1(n1), n2(n2), n3(n3){SETTYPE(func)} t1 n1; \ + t2 n2; \ + t3 n3; \ + ret result; \ + }; +#define DECLARE_FUNC_ARGS4R(ret, func, t1, n1, t2, n2, t3, n3, t4, n4) \ + DOTYPE(func) struct S##func##Args : SArgs \ + { \ + S##func##Args(t1 n1, t2 n2, t3 n3, t4 n4) : n1(n1), n2(n2), n3(n3), n4(n4){SETTYPE(func)} t1 n1; \ + t2 n2; \ + t3 n3; \ + t4 n4; \ + ret result; \ + }; +#define DECLARE_FUNC_ARGS7R(ret, func, t1, n1, t2, n2, t3, n3, t4, n4, t5, n5, t6, n6, t7, n7) \ + DOTYPE(func) struct S##func##Args : SArgs \ + { \ + S##func##Args(t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6, t7 n7) : n1(n1), n2(n2), n3(n3), n4(n4), n5(n5), n6(n6), n7(n7){SETTYPE(func)} t1 n1; \ + t2 n2; \ + t3 n3; \ + t4 n4; \ + t5 n5; \ + t6 n6; \ + t7 n7; \ + ret result; \ + }; typedef NetServerPlayerID NetServerPlayerIDRef; @@ -209,7 +293,7 @@ class CNetServerBuffer : public CNetServer std::list m_OutCommandQueue; std::list m_OutResultQueue; std::list m_InResultQueue; - std::set m_FinishedList; // Result has been used, will be deleted next pulse (shared access with watchdog thread) + std::set m_FinishedList; // Result has been used, will be deleted next pulse (shared access with watchdog thread) CComboMutex m_Mutex; CNetBufferWatchDog* m_pWatchDog; int m_iThreadFrameCount; diff --git a/Server/mods/deathmatch/logic/net/CNetBufferWatchDog.cpp b/Server/mods/deathmatch/logic/net/CNetBufferWatchDog.cpp index 763c1427ec8..4953218b384 100644 --- a/Server/mods/deathmatch/logic/net/CNetBufferWatchDog.cpp +++ b/Server/mods/deathmatch/logic/net/CNetBufferWatchDog.cpp @@ -359,6 +359,7 @@ bool CNetBufferWatchDog::IsUnreliableSyncPacket(uchar ucPacketID) case PACKET_ID_UNOCCUPIED_VEHICLE_SYNC: case PACKET_ID_PED_SYNC: case PACKET_ID_CAMERA_SYNC: + case PACKET_ID_PED_TASK: return true; default: return false; diff --git a/Server/mods/deathmatch/logic/net/CSimBulletsyncPacket.cpp b/Server/mods/deathmatch/logic/net/CSimBulletsyncPacket.cpp index 2b5894f3028..1d5c4735e95 100644 --- a/Server/mods/deathmatch/logic/net/CSimBulletsyncPacket.cpp +++ b/Server/mods/deathmatch/logic/net/CSimBulletsyncPacket.cpp @@ -1,6 +1,6 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * * Multi Theft Auto is available from https://www.multitheftauto.com/ @@ -12,70 +12,55 @@ #include "CPickupManager.h" #include "CWeaponStatManager.h" -CSimBulletsyncPacket::CSimBulletsyncPacket(ElementID PlayerID) : m_PlayerID(PlayerID) +CSimBulletsyncPacket::CSimBulletsyncPacket(ElementID id) : m_id(id) { - m_Cache.ucOrderCounter = 0; - m_Cache.fDamage = 0; - m_Cache.ucHitZone = 0; - m_Cache.DamagedPlayerID = INVALID_ELEMENT_ID; } -// -// Should do the same this as what CBulletsyncPacket::Read() does -// -bool CSimBulletsyncPacket::Read(NetBitStreamInterface& BitStream) +bool CSimBulletsyncPacket::Read(NetBitStreamInterface& stream) { - char cWeaponType = 0; - if (!BitStream.Read(cWeaponType) || !CWeaponStatManager::HasWeaponBulletSync(cWeaponType)) + char type = 0; + if (!stream.Read(type) || !CWeaponStatManager::HasWeaponBulletSync(type)) return false; - m_Cache.weaponType = (eWeaponType)cWeaponType; - if (!BitStream.Read((char*)&m_Cache.vecStart, sizeof(CVector)) || !BitStream.Read((char*)&m_Cache.vecEnd, sizeof(CVector))) + m_cache.weapon = static_cast(type); + + if (!stream.Read(reinterpret_cast(&m_cache.start), sizeof(CVector)) || !stream.Read(reinterpret_cast(&m_cache.end), sizeof(CVector))) return false; - if (!m_Cache.vecStart.IsValid() || !m_Cache.vecEnd.IsValid()) + if (!m_cache.start.IsValid() || !m_cache.end.IsValid()) return false; - // Duplicate packet protection - if (!BitStream.Read(m_Cache.ucOrderCounter)) + if (!stream.Read(m_cache.order)) return false; - if (BitStream.ReadBit()) + if (stream.ReadBit()) { - BitStream.Read(m_Cache.fDamage); - BitStream.Read(m_Cache.ucHitZone); - BitStream.Read(m_Cache.DamagedPlayerID); + stream.Read(m_cache.damage); + stream.Read(m_cache.zone); + stream.Read(m_cache.damaged); } return true; } -// -// Should do the same this as what CBulletsyncPacket::Write() does -// -bool CSimBulletsyncPacket::Write(NetBitStreamInterface& BitStream) const +bool CSimBulletsyncPacket::Write(NetBitStreamInterface& stream) const { - // Write the source player id - BitStream.Write(m_PlayerID); - - // Write the bulletsync data - BitStream.Write((char)m_Cache.weaponType); - BitStream.Write((const char*)&m_Cache.vecStart, sizeof(CVector)); - BitStream.Write((const char*)&m_Cache.vecEnd, sizeof(CVector)); - - // Duplicate packet protection - BitStream.Write(m_Cache.ucOrderCounter); + stream.Write(m_id); + stream.Write(static_cast(m_cache.weapon)); + stream.Write(reinterpret_cast(&m_cache.start), sizeof(CVector)); + stream.Write(reinterpret_cast(&m_cache.end), sizeof(CVector)); + stream.Write(m_cache.order); - if (m_Cache.fDamage > 0 && m_Cache.DamagedPlayerID != INVALID_ELEMENT_ID) + if (m_cache.damage > 0 && m_cache.damaged != INVALID_ELEMENT_ID) { - BitStream.WriteBit(true); - BitStream.Write(m_Cache.fDamage); - BitStream.Write(m_Cache.ucHitZone); - BitStream.Write(m_Cache.DamagedPlayerID); + stream.WriteBit(true); + stream.Write(m_cache.damage); + stream.Write(m_cache.zone); + stream.Write(m_cache.damaged); } else { - BitStream.WriteBit(false); + stream.WriteBit(false); } return true; diff --git a/Server/mods/deathmatch/logic/net/CSimBulletsyncPacket.h b/Server/mods/deathmatch/logic/net/CSimBulletsyncPacket.h index 8412c8c6778..9c920151de6 100644 --- a/Server/mods/deathmatch/logic/net/CSimBulletsyncPacket.h +++ b/Server/mods/deathmatch/logic/net/CSimBulletsyncPacket.h @@ -1,40 +1,36 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ -// -// For bouncing a bullet sync packet -// +#pragma once + class CSimBulletsyncPacket : public CSimPacket { public: - ZERO_ON_NEW - - CSimBulletsyncPacket(ElementID PlayerID); + CSimBulletsyncPacket() = default; + explicit CSimBulletsyncPacket(ElementID id); ePacketID GetPacketID() const { return PACKET_ID_PLAYER_BULLETSYNC; }; unsigned long GetFlags() const { return PACKET_MEDIUM_PRIORITY | PACKET_RELIABLE; }; - bool Read(NetBitStreamInterface& BitStream); - bool Write(NetBitStreamInterface& BitStream) const; + bool Read(NetBitStreamInterface& stream); + bool Write(NetBitStreamInterface& stream) const; - // Set in constructor - const ElementID m_PlayerID; + const ElementID m_id{}; - // Set in Read () struct { - eWeaponType weaponType; - CVector vecStart; - CVector vecEnd; - uchar ucOrderCounter; - float fDamage; - uchar ucHitZone; - ElementID DamagedPlayerID; - } m_Cache; + eWeaponType weapon = eWeaponType::WEAPONTYPE_UNARMED; + CVector start{}; + CVector end{}; + std::uint8_t order{}; + float damage{}; + uchar zone{}; + ElementID damaged = INVALID_ELEMENT_ID; + } m_cache; }; diff --git a/Server/mods/deathmatch/logic/net/CSimControl.cpp b/Server/mods/deathmatch/logic/net/CSimControl.cpp index 36b4c67cf10..428f7fd6f2c 100644 --- a/Server/mods/deathmatch/logic/net/CSimControl.cpp +++ b/Server/mods/deathmatch/logic/net/CSimControl.cpp @@ -21,7 +21,7 @@ namespace bool ms_bEnableRequest = false; CNetServerBuffer* ms_pNetServerBuffer = NULL; CSimPlayerManager* ms_pSimPlayerManager = NULL; -} // namespace +} // namespace /////////////////////////////////////////////////////////////// // diff --git a/Server/mods/deathmatch/logic/net/CSimKeysyncPacket.cpp b/Server/mods/deathmatch/logic/net/CSimKeysyncPacket.cpp index 239779aed80..5f77f68797f 100644 --- a/Server/mods/deathmatch/logic/net/CSimKeysyncPacket.cpp +++ b/Server/mods/deathmatch/logic/net/CSimKeysyncPacket.cpp @@ -64,23 +64,29 @@ bool CSimKeysyncPacket::Read(NetBitStreamInterface& BitStream) if (m_ucPlayerGotWeaponType != ucClientWeaponType) { - bWeaponCorrect = false; // Possibly old weapon data. - ucUseWeaponType = ucClientWeaponType; // Use the packet supplied weapon type to skip over the correct amount of data + bWeaponCorrect = false; // Possibly old weapon data. + ucUseWeaponType = ucClientWeaponType; // Use the packet supplied weapon type to skip over the correct amount of data } - m_Cache.bWeaponCorrect = bWeaponCorrect; // Copied from PlayerPuresyncPacket + m_Cache.bWeaponCorrect = bWeaponCorrect; // Copied from PlayerPuresyncPacket // Read out the current weapon slot and set it SWeaponSlotSync slot; if (!BitStream.Read(&slot)) return false; - unsigned int uiSlot = slot.data.uiSlot; + auto ucSlot = static_cast(slot.data.uiSlot); if (bWeaponCorrect) - m_Cache.ucWeaponSlot = uiSlot; + { + const unsigned int uiCurrSlot = slot.data.uiSlot; + if (uiCurrSlot > 0xFF) + return false; + + m_Cache.ucWeaponSlot = static_cast(uiCurrSlot); + } // Did he have a weapon? - if (CWeaponNames::DoesSlotHaveAmmo(uiSlot)) + if (CWeaponNames::DoesSlotHaveAmmo(ucSlot)) { // And ammo in clip SWeaponAmmoSync ammo(ucUseWeaponType, false, true); @@ -168,7 +174,7 @@ bool CSimKeysyncPacket::Write(NetBitStreamInterface& BitStream) const if (m_sharedControllerState.ButtonCircle || (m_sharedControllerState.RightShoulder1)) { // Write his current weapon slot - unsigned int uiSlot = m_Cache.ucWeaponSlot; // check m_Cache.bWeaponCorrect ! + unsigned int uiSlot = m_Cache.ucWeaponSlot; // check m_Cache.bWeaponCorrect ! SWeaponSlotSync slot; slot.data.uiSlot = uiSlot; BitStream.Write(&slot); diff --git a/Server/mods/deathmatch/logic/net/CSimKeysyncPacket.h b/Server/mods/deathmatch/logic/net/CSimKeysyncPacket.h index ad22f144d04..3b3f6cf6518 100644 --- a/Server/mods/deathmatch/logic/net/CSimKeysyncPacket.h +++ b/Server/mods/deathmatch/logic/net/CSimKeysyncPacket.h @@ -43,10 +43,10 @@ class CSimKeysyncPacket : public CSimPacket SKeysyncFlags flags; bool bWeaponCorrect; - uchar ucWeaponSlot; // Only valid if bWeaponCorrect - ushort usAmmoInClip; // Only valid if bWeaponCorrect + uchar ucWeaponSlot; // Only valid if bWeaponCorrect + ushort usAmmoInClip; // Only valid if bWeaponCorrect - float fAimDirection; // Only valid if bWeaponCorrect + float fAimDirection; // Only valid if bWeaponCorrect CVector vecSniperSource; CVector vecTargetting; diff --git a/Server/mods/deathmatch/logic/net/CSimPlayer.h b/Server/mods/deathmatch/logic/net/CSimPlayer.h index 7519c140706..16885e303a0 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayer.h +++ b/Server/mods/deathmatch/logic/net/CSimPlayer.h @@ -39,11 +39,11 @@ class CSimPlayer unsigned short m_usBitStreamVersion; NetServerPlayerID m_PlayerSocket; std::vector m_PuresyncSendListFlat; - std::multimap m_PuresyncSendListGrouped; // Send list grouped by bitstream version + std::multimap m_PuresyncSendListGrouped; // Send list grouped by bitstream version bool m_bSendListChanged; bool m_bHasOccupiedVehicle; bool m_bIsExitingVehicle; - CControllerState m_sharedControllerState; // Updated by CSim*Packet code + CControllerState m_sharedControllerState; // Updated by CSim*Packet code // Used in CSimPlayerPuresyncPacket and CSimVehiclePuresyncPacket ElementID m_PlayerID; diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp b/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp index 4460a403f99..6ad6c25120a 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp +++ b/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp @@ -41,7 +41,7 @@ /////////////////////////////////////////////////////////////////////////// void CSimPlayerManager::AddSimPlayer(CPlayer* pPlayer) { - LockSimSystem(); // Prevent any sim activity on the sync thread + LockSimSystem(); // Prevent any sim activity on the sync thread // Create CSimPlayer* pSim = new CSimPlayer(); @@ -72,7 +72,7 @@ void CSimPlayerManager::AddSimPlayer(CPlayer* pPlayer) /////////////////////////////////////////////////////////////////////////// void CSimPlayerManager::RemoveSimPlayer(CPlayer* pPlayer) { - LockSimSystem(); // Prevent any sim activity on the sync thread + LockSimSystem(); // Prevent any sim activity on the sync thread // Check assert(pPlayer->m_pSimPlayer->m_pRealPlayer == pPlayer); @@ -110,7 +110,7 @@ void CSimPlayerManager::RemoveSimPlayer(CPlayer* pPlayer) /////////////////////////////////////////////////////////////////////////// void CSimPlayerManager::UpdateSimPlayer(CPlayer* pPlayer) { - LockSimSystem(); // TODO - only lock the CSimPlayer + LockSimSystem(); // TODO - only lock the CSimPlayer // Get matching sim player CSimPlayer* pSim = pPlayer->m_pSimPlayer; @@ -136,7 +136,10 @@ void CSimPlayerManager::UpdateSimPlayer(CPlayer* pPlayer) pSim->m_ucWeaponType = pPlayer->GetWeaponType(); pSim->m_usVehicleModel = pVehicle ? pVehicle->GetModel() : 0; pSim->m_ucSyncTimeContext = pPlayer->GetSyncTimeContext(); - pSim->m_ucOccupiedVehicleSeat = pPlayer->GetOccupiedVehicleSeat(); + { + const uint uiSeat = pPlayer->GetOccupiedVehicleSeat(); + pSim->m_ucOccupiedVehicleSeat = uiSeat <= 0xFF ? static_cast(uiSeat) : 0xFF; + } pSim->m_fWeaponRange = pPlayer->GetWeaponRangeFromSlot(); pSim->m_bVehicleHasHydraulics = pVehicle ? pVehicle->GetUpgrades()->HasUpgrade(1087) : false; pSim->m_bVehicleIsPlaneOrHeli = pVehicle ? pVehicle->GetVehicleType() == VEHICLE_PLANE || pVehicle->GetVehicleType() == VEHICLE_HELI : false; @@ -162,7 +165,7 @@ void CSimPlayerManager::UpdateSimPlayer(CPlayer* pPlayer) if (pSendSimPlayer && pSendSimPlayer->m_bDoneFirstUpdate) pSim->m_PuresyncSendListFlat.push_back(pSendSimPlayer); else - pPlayer->m_bPureSyncSimSendListDirty = true; // Retry next time + pPlayer->m_bPureSyncSimSendListDirty = true; // Retry next time } } @@ -228,7 +231,7 @@ bool CSimPlayerManager::HandlePlayerPureSync(const NetServerPlayerID& Socket, Ne if (!CNetBufferWatchDog::CanSendPacket(PACKET_ID_PLAYER_PURESYNC)) return true; - LockSimSystem(); // Prevent player additions and deletions + LockSimSystem(); // Prevent player additions and deletions // Grab the source player CSimPlayer* pSourceSimPlayer = Get(Socket); @@ -266,7 +269,7 @@ bool CSimPlayerManager::HandleVehiclePureSync(const NetServerPlayerID& Socket, N if (!CNetBufferWatchDog::CanSendPacket(PACKET_ID_PLAYER_VEHICLE_PURESYNC)) return true; - LockSimSystem(); // Prevent player additions and deletions + LockSimSystem(); // Prevent player additions and deletions // Grab the source player CSimPlayer* pSourceSimPlayer = Get(Socket); @@ -305,7 +308,7 @@ bool CSimPlayerManager::HandleKeySync(const NetServerPlayerID& Socket, NetBitStr if (!CNetBufferWatchDog::CanSendPacket(PACKET_ID_PLAYER_KEYSYNC)) return true; - LockSimSystem(); // Prevent player additions and deletions + LockSimSystem(); // Prevent player additions and deletions // Grab the source player CSimPlayer* pSourceSimPlayer = Get(Socket); @@ -332,42 +335,35 @@ bool CSimPlayerManager::HandleKeySync(const NetServerPlayerID& Socket, NetBitStr return true; } -/////////////////////////////////////////////////////////////// -// -// CSimPlayerManager::HandleBulletSync -// -// Thread: sync -// CS should be locked: no -// -/////////////////////////////////////////////////////////////// -bool CSimPlayerManager::HandleBulletSync(const NetServerPlayerID& Socket, NetBitStreamInterface* BitStream) +bool CSimPlayerManager::HandleBulletSync(const NetServerPlayerID& socket, NetBitStreamInterface* stream) { if (!CNetBufferWatchDog::CanSendPacket(PACKET_ID_PLAYER_BULLETSYNC)) return true; - LockSimSystem(); // Prevent player additions and deletions - - // Grab the source player - CSimPlayer* pSourceSimPlayer = Get(Socket); + LockSimSystem(); - // Check is good for bullet sync - if (pSourceSimPlayer && pSourceSimPlayer->IsJoined()) + auto* player = Get(socket); + if (!player || !player->IsJoined()) { - // Read the incoming packet data - CSimBulletsyncPacket* pPacket = new CSimBulletsyncPacket(pSourceSimPlayer->m_PlayerID); + UnlockSimSystem(); + return true; + } - if (pPacket->Read(*BitStream)) - { - // Relay it to nearbyers, if the player really has this weapon - if (pSourceSimPlayer->m_pRealPlayer->HasWeaponType(pPacket->m_Cache.weaponType)) - { - Broadcast(*pPacket, pSourceSimPlayer->GetPuresyncSendList()); - } - } + auto packet = std::make_unique(player->m_PlayerID); + if (!packet->Read(*stream)) + { + UnlockSimSystem(); + return true; + } - delete pPacket; + if (!player->m_pRealPlayer->HasWeaponType(packet->m_cache.weapon)) + { + UnlockSimSystem(); + return true; } + Broadcast(*packet, player->GetPuresyncSendList()); + UnlockSimSystem(); return true; } @@ -385,7 +381,7 @@ bool CSimPlayerManager::HandlePedTaskPacket(const NetServerPlayerID& Socket, Net if (!CNetBufferWatchDog::CanSendPacket(PACKET_ID_PED_TASK)) return true; - LockSimSystem(); // Prevent player additions and deletions + LockSimSystem(); // Prevent player additions and deletions // Grab the source player CSimPlayer* pSourceSimPlayer = Get(Socket); diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerManager.h b/Server/mods/deathmatch/logic/net/CSimPlayerManager.h index 04f3c953fec..2c7b6e0b3fd 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerManager.h +++ b/Server/mods/deathmatch/logic/net/CSimPlayerManager.h @@ -25,7 +25,7 @@ class CSimPlayerManager bool HandlePlayerPureSync(const NetServerPlayerID& Socket, NetBitStreamInterface* BitStream); bool HandleVehiclePureSync(const NetServerPlayerID& Socket, NetBitStreamInterface* BitStream); bool HandleKeySync(const NetServerPlayerID& Socket, NetBitStreamInterface* BitStream); - bool HandleBulletSync(const NetServerPlayerID& Socket, NetBitStreamInterface* BitStream); + bool HandleBulletSync(const NetServerPlayerID& socket, NetBitStreamInterface* stream); bool HandlePedTaskPacket(const NetServerPlayerID& Socket, NetBitStreamInterface* BitStream); CSimPlayer* Get(const NetServerPlayerID& PlayerSocket); void Broadcast(const CSimPacket& Packet, const std::multimap& sendList); diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp index 8542cb4793a..69f2f5e3e69 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp @@ -115,8 +115,8 @@ bool CSimPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) if (m_PlayerGotWeaponType != ucClientWeaponType) { - bWeaponCorrect = false; // Possibly old weapon data. - ucUseWeaponType = ucClientWeaponType; // Use the packet supplied weapon type to skip over the correct amount of data + bWeaponCorrect = false; // Possibly old weapon data. + ucUseWeaponType = ucClientWeaponType; // Use the packet supplied weapon type to skip over the correct amount of data } // Update check counts @@ -231,7 +231,7 @@ bool CSimPlayerPuresyncPacket::Write(NetBitStreamInterface& BitStream) const if (m_Cache.flags.data.bHasAWeapon) { - unsigned int uiSlot = m_Cache.ucWeaponSlot; // check m_Cache.bWeaponCorrect ! + unsigned int uiSlot = m_Cache.ucWeaponSlot; // check m_Cache.bWeaponCorrect ! SWeaponSlotSync slot; slot.data.uiSlot = uiSlot; BitStream.Write(&slot); diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h index a3132568f71..aba98cb7572 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h +++ b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h @@ -73,13 +73,13 @@ class CSimPlayerPuresyncPacket : public CSimPacket CVector vecCamFwd; bool bWeaponCorrect; - uchar ucWeaponSlot; // Only valid if bWeaponCorrect - ushort usAmmoInClip; // Only valid if bWeaponCorrect - ushort usTotalAmmo; // Only valid if bWeaponCorrect + uchar ucWeaponSlot; // Only valid if bWeaponCorrect + ushort usAmmoInClip; // Only valid if bWeaponCorrect + ushort usTotalAmmo; // Only valid if bWeaponCorrect bool bIsAimFull; - float fAimDirection; // Only valid if bWeaponCorrect - CVector vecSniperSource; // Only valid if bWeaponCorrect and bIsAimFull - CVector vecTargetting; // Only valid if bWeaponCorrect and bIsAimFull + float fAimDirection; // Only valid if bWeaponCorrect + CVector vecSniperSource; // Only valid if bWeaponCorrect and bIsAimFull + CVector vecTargetting; // Only valid if bWeaponCorrect and bIsAimFull } m_Cache; }; diff --git a/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.cpp b/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.cpp index dbfb098cf94..a52aaaf841a 100644 --- a/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.cpp @@ -55,10 +55,7 @@ bool CSimVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) return false; // Read out the remote model - if (BitStream.Version() >= 0x05F) - BitStream.Read(m_Cache.iModelID); - else - m_Cache.iModelID = m_usVehicleGotModel; + BitStream.Read(m_Cache.iModelID); // Read out its position SPositionSync position(false); @@ -66,7 +63,7 @@ bool CSimVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) return false; m_Cache.PlrPosition = position.data.vecPosition; - if (CVehicleManager::GetVehicleType(m_Cache.iModelID) == VEHICLE_TRAIN) + if (CVehicleManager::GetVehicleType(static_cast(m_Cache.iModelID)) == VEHICLE_TRAIN) { // Train specific data float fRailPosition = 0.0f; @@ -166,25 +163,6 @@ bool CSimVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) } } - // Read Damage info, but do not store, as we do not relay this info - if (BitStream.Version() >= 0x047) - { - if (BitStream.ReadBit() == true) - { - ElementID DamagerID; - if (!BitStream.Read(DamagerID)) - return false; - - SWeaponTypeSync weaponType; - if (!BitStream.Read(&weaponType)) - return false; - - SBodypartSync bodyPart; - if (!BitStream.Read(&bodyPart)) - return false; - } - } - // Player health SPlayerHealthSync health; if (!BitStream.Read(&health)) @@ -213,7 +191,7 @@ bool CSimVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) if (m_Cache.flags.data.bIsDoingGangDriveby && CWeaponNames::DoesSlotHaveAmmo(slot.data.uiSlot)) { // Read the ammo states - SWeaponAmmoSync ammo(m_ucPlayerGotWeaponType, BitStream.Version() >= 0x44, true); + SWeaponAmmoSync ammo(m_ucPlayerGotWeaponType, true, true); if (!BitStream.Read(&ammo)) return false; m_Cache.usAmmoInClip = ammo.data.usAmmoInClip; @@ -251,8 +229,7 @@ bool CSimVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) m_sharedControllerState.RightShoulder2 = BitStream.ReadBit() * 255; } - if (BitStream.Can(eBitStreamVersion::SetElementOnFire)) - m_Cache.isOnFire = BitStream.ReadBit(); + m_Cache.isOnFire = BitStream.ReadBit(); // Success return true; @@ -282,8 +259,7 @@ bool CSimVehiclePuresyncPacket::Write(NetBitStreamInterface& BitStream) const WriteFullKeysync(m_sharedControllerState, BitStream); // Write the serverside model (#8800) - if (BitStream.Version() >= 0x05F) - BitStream.Write(m_Cache.iModelID); + BitStream.Write(m_Cache.iModelID); // Write the vehicle matrix only if he's the driver CVector vecTemp; @@ -325,25 +301,22 @@ bool CSimVehiclePuresyncPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(&health); // Write trailer chain - if (BitStream.Version() >= 0x42) + for (std::vector::const_iterator it = m_Cache.TrailerList.begin(); it != m_Cache.TrailerList.end(); ++it) { - for (std::vector::const_iterator it = m_Cache.TrailerList.begin(); it != m_Cache.TrailerList.end(); ++it) - { - BitStream.WriteBit(true); - - BitStream.Write(it->m_TrailerID); + BitStream.WriteBit(true); - SPositionSync trailerPosition(false); - trailerPosition.data.vecPosition = it->m_TrailerPosition; - BitStream.Write(&trailerPosition); + BitStream.Write(it->m_TrailerID); - SRotationDegreesSync trailerRotation; - trailerRotation.data.vecRotation = it->m_TrailerRotationDeg; - BitStream.Write(&trailerRotation); - } + SPositionSync trailerPosition(false); + trailerPosition.data.vecPosition = it->m_TrailerPosition; + BitStream.Write(&trailerPosition); - BitStream.WriteBit(false); + SRotationDegreesSync trailerRotation; + trailerRotation.data.vecRotation = it->m_TrailerRotationDeg; + BitStream.Write(&trailerRotation); } + + BitStream.WriteBit(false); } // Player health and armor @@ -371,7 +344,7 @@ bool CSimVehiclePuresyncPacket::Write(NetBitStreamInterface& BitStream) const if (m_Cache.flags.data.bIsDoingGangDriveby && CWeaponNames::DoesSlotHaveAmmo(slot.data.uiSlot)) { // Write the ammo states - SWeaponAmmoSync ammo(ucWeaponType, BitStream.Version() >= 0x44, true); + SWeaponAmmoSync ammo(ucWeaponType, true, true); ammo.data.usAmmoInClip = m_Cache.usAmmoInClip; ammo.data.usTotalAmmo = m_Cache.usTotalAmmo; BitStream.Write(&ammo); @@ -405,24 +378,20 @@ bool CSimVehiclePuresyncPacket::Write(NetBitStreamInterface& BitStream) const } // Write parts state - if (BitStream.Version() >= 0x5D) - { - SVehicleDamageSyncMethodeB damage; - // Check where we are in the cycle - uint uiPhase = (m_uiDamageInfoSendPhase & 3); - damage.data.bSyncDoors = (uiPhase == 0); - damage.data.bSyncWheels = (uiPhase == 1); - damage.data.bSyncPanels = (uiPhase == 2); - damage.data.bSyncLights = (uiPhase == 3); - damage.data.doors.data.ucStates = m_DamageInfo.m_ucDoorStates; - damage.data.wheels.data.ucStates = m_DamageInfo.m_ucWheelStates; - damage.data.panels.data.ucStates = m_DamageInfo.m_ucPanelStates; - damage.data.lights.data.ucStates = m_DamageInfo.m_ucLightStates; - BitStream.Write(&damage); - } - - if (BitStream.Can(eBitStreamVersion::SetElementOnFire)) - BitStream.WriteBit(m_Cache.isOnFire); + SVehicleDamageSyncMethodeB damage; + // Check where we are in the cycle + uint uiPhase = (m_uiDamageInfoSendPhase & 3); + damage.data.bSyncDoors = (uiPhase == 0); + damage.data.bSyncWheels = (uiPhase == 1); + damage.data.bSyncPanels = (uiPhase == 2); + damage.data.bSyncLights = (uiPhase == 3); + damage.data.doors.data.ucStates = m_DamageInfo.m_ucDoorStates; + damage.data.wheels.data.ucStates = m_DamageInfo.m_ucWheelStates; + damage.data.panels.data.ucStates = m_DamageInfo.m_ucPanelStates; + damage.data.lights.data.ucStates = m_DamageInfo.m_ucLightStates; + BitStream.Write(&damage); + + BitStream.WriteBit(m_Cache.isOnFire); // Success return true; @@ -456,7 +425,7 @@ void CSimVehiclePuresyncPacket::ReadVehicleSpecific(NetBitStreamInterface& BitSt } // Door angles. - if (CVehicleManager::HasDoors(m_Cache.iModelID)) + if (CVehicleManager::HasDoors(static_cast(m_Cache.iModelID))) { SDoorOpenRatioSync door; @@ -487,7 +456,7 @@ void CSimVehiclePuresyncPacket::WriteVehicleSpecific(NetBitStreamInterface& BitS } // Door angles. - if (CVehicleManager::HasDoors(m_Cache.iModelID)) + if (CVehicleManager::HasDoors(static_cast(m_Cache.iModelID))) { SDoorOpenRatioSync door; for (unsigned int i = 2; i < 6; ++i) diff --git a/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.h b/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.h index a05385cb6d0..0446ca52b3e 100644 --- a/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.h +++ b/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.h @@ -69,7 +69,7 @@ class CSimVehiclePuresyncPacket : public CSimPacket CVector vecCamPosition; CVector vecCamFwd; - CVector VehPosition; // Same as PlrPosition ? + CVector VehPosition; // Same as PlrPosition ? CVector VehRotationDeg; CVector BothVelocity; CVector VehTurnSpeed; diff --git a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp index da3e74bfba8..a185a2d892b 100644 --- a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp @@ -13,83 +13,248 @@ #include "net/SyncStructures.h" #include "CPlayer.h" #include "CWeaponStatManager.h" +#include "CElementIDs.h" +#include "CElement.h" +#include "CWeaponNames.h" -CBulletsyncPacket::CBulletsyncPacket(CPlayer* pPlayer) +CBulletsyncPacket::CBulletsyncPacket(CPlayer* player) + : m_weapon(WEAPONTYPE_UNARMED), m_start(), m_end(), m_order(0), m_damage(0.0f), m_zone(0), m_damaged(INVALID_ELEMENT_ID) { - m_pSourceElement = pPlayer; - m_WeaponType = WEAPONTYPE_UNARMED; - m_ucOrderCounter = 0; - m_fDamage = 0; - m_ucHitZone = 0; - m_DamagedPlayerID = INVALID_ELEMENT_ID; + m_pSourceElement = player; } -bool CBulletsyncPacket::Read(NetBitStreamInterface& BitStream) +bool CBulletsyncPacket::IsValidVector(const CVector& vec) noexcept { - // Got a player? - if (m_pSourceElement) + if (!vec.IsValid()) + return false; + + if (IsNaN(vec.fX)) + return false; + + if (IsNaN(vec.fY)) + return false; + + if (IsNaN(vec.fZ)) + return false; + + return true; +} + +bool CBulletsyncPacket::IsValidWeaponId(unsigned char weaponId) noexcept +{ + return CWeaponStatManager::HasWeaponBulletSync(static_cast(weaponId)); +} + +bool CBulletsyncPacket::ValidateTrajectory() const noexcept +{ + const float dx = m_end.fX - m_start.fX; + const float dy = m_end.fY - m_start.fY; + const float dz = m_end.fZ - m_start.fZ; + + const float movementSq = (dx * dx) + (dy * dy) + (dz * dz); + + if (IsNaN(movementSq)) + return false; + + if (movementSq < MIN_DISTANCE_SQ) + return false; + + if (movementSq > MAX_DISTANCE_SQ) + return false; + + return true; +} + +void CBulletsyncPacket::ResetDamageData() noexcept +{ + m_damage = 0.0f; + m_zone = 0; + m_damaged = INVALID_ELEMENT_ID; +} + +bool CBulletsyncPacket::ReadWeaponAndPositions(NetBitStreamInterface& stream) +{ + unsigned char type = 0; + if (!stream.Read(type)) + return false; + + if (!IsValidWeaponId(type)) + return false; + + m_weapon = static_cast(type); + + if (!stream.Read(reinterpret_cast(&m_start), sizeof(CVector))) + return false; + + if (!stream.Read(reinterpret_cast(&m_end), sizeof(CVector))) + return false; + + if (!IsValidVector(m_start)) + return false; + + if (!IsValidVector(m_end)) + return false; + + if (!ValidateTrajectory()) + return false; + + return true; +} + +bool CBulletsyncPacket::ReadOptionalDamage(NetBitStreamInterface& stream) +{ + if (!stream.ReadBit()) + { + ResetDamageData(); + return true; + } + + stream.Read(m_damage); + stream.Read(m_zone); + stream.Read(m_damaged); + + if (IsNaN(m_damage)) + { + ResetDamageData(); + return false; + } + + if (m_damage < 0.0f || m_damage > MAX_DAMAGE) + { + ResetDamageData(); + return false; + } + + if (m_zone > MAX_BODY_ZONE) + { + ResetDamageData(); + return false; + } + + if (m_damaged == 0) { - char cWeaponType = 0; - if (!BitStream.Read(cWeaponType) || !CWeaponStatManager::HasWeaponBulletSync(cWeaponType)) + ResetDamageData(); + return false; + } + + // Check that target element exists (if specified) + // Note: m_damaged can be INVALID_ELEMENT_ID when shooting at ground/world + if (m_damaged != INVALID_ELEMENT_ID) + { + CElement* pElement = CElementIDs::GetElement(m_damaged); + if (!pElement) + { + ResetDamageData(); return false; - m_WeaponType = (eWeaponType)cWeaponType; + } + // Element exists + } - if (!BitStream.Read((char*)&m_vecStart, sizeof(CVector)) || !BitStream.Read((char*)&m_vecEnd, sizeof(CVector))) + return true; +} + +bool CBulletsyncPacket::Read(NetBitStreamInterface& stream) +{ + if (!m_pSourceElement) + return false; + + CPlayer* pPlayer = static_cast(m_pSourceElement); + if (pPlayer) + { + // Check if player is spawned and alive + if (!pPlayer->IsSpawned() || pPlayer->IsDead()) return false; - if (!m_vecStart.IsValid() || !m_vecEnd.IsValid()) + // Check player position is reasonable relative to bullet start + const CVector& playerPos = pPlayer->GetPosition(); + const float maxShootDistance = 50.0f; // Max distance from player to bullet start + + // This check will be done after we read positions + } + + if (!ReadWeaponAndPositions(stream)) + return false; + + // Now validate player position relative to shot origin + if (pPlayer) + { + const CVector& playerPos = pPlayer->GetPosition(); + float dx = m_start.fX - playerPos.fX; + float dy = m_start.fY - playerPos.fY; + float dz = m_start.fZ - playerPos.fZ; + float distSq = dx * dx + dy * dy + dz * dz; + + // Allow larger distance if player is in vehicle (vehicle guns like Hunter have offsets of ~5m, + // plus vehicle size, plus network lag compensation) + const float maxShootDistanceSq = pPlayer->GetOccupiedVehicle() ? (100.0f * 100.0f) : (50.0f * 50.0f); + if (distSq > maxShootDistanceSq) return false; - // Duplicate packet protection - if (!BitStream.Read(m_ucOrderCounter)) + // Check if player has this weapon + if (!pPlayer->HasWeaponType(static_cast(m_weapon))) return false; - if (BitStream.ReadBit()) - { - BitStream.Read(m_fDamage); - BitStream.Read(m_ucHitZone); - BitStream.Read(m_DamagedPlayerID); - } - return true; + // Check if weapon has ammo + const auto type = static_cast(m_weapon); + const auto slot = CWeaponNames::GetSlotFromWeapon(type); + if (pPlayer->GetWeaponTotalAmmo(slot) <= 0) + return false; } - return false; + if (!stream.Read(m_order)) + return false; + + if (!ReadOptionalDamage(stream)) + return false; + + return true; } -// Note: Relays a previous Read() -bool CBulletsyncPacket::Write(NetBitStreamInterface& BitStream) const +bool CBulletsyncPacket::Write(NetBitStreamInterface& stream) const { - // Got a player to write? - if (m_pSourceElement) - { - CPlayer* pSourcePlayer = static_cast(m_pSourceElement); + if (!m_pSourceElement) + return false; - // Write the source player id - ElementID PlayerID = pSourcePlayer->GetID(); - BitStream.Write(PlayerID); + const auto* pPlayer = static_cast(m_pSourceElement); + if (!pPlayer) + return false; - // Write the bulletsync data - BitStream.Write((char)m_WeaponType); - BitStream.Write((const char*)&m_vecStart, sizeof(CVector)); - BitStream.Write((const char*)&m_vecEnd, sizeof(CVector)); + const ElementID id = pPlayer->GetID(); - // Duplicate packet protection - BitStream.Write(m_ucOrderCounter); + if (id == INVALID_ELEMENT_ID) + return false; - if (m_fDamage > 0 && m_DamagedPlayerID != INVALID_ELEMENT_ID) - { - BitStream.WriteBit(true); - BitStream.Write(m_fDamage); - BitStream.Write(m_ucHitZone); - BitStream.Write(m_DamagedPlayerID); - } - else - { - BitStream.WriteBit(false); - } + if (id == 0) + return false; - return true; + if (!IsValidVector(m_start)) + return false; + + if (!IsValidVector(m_end)) + return false; + + if (!ValidateTrajectory()) + return false; + + const unsigned char weaponType = static_cast(m_weapon); + if (!IsValidWeaponId(weaponType)) + return false; + + stream.Write(id); + stream.Write(weaponType); + stream.Write(reinterpret_cast(&m_start), sizeof(CVector)); + stream.Write(reinterpret_cast(&m_end), sizeof(CVector)); + stream.Write(m_order); + + const bool hasDamage = (m_damage > EPSILON) && (m_damaged != INVALID_ELEMENT_ID); + stream.WriteBit(hasDamage); + + if (hasDamage) + { + stream.Write(m_damage); + stream.Write(m_zone); + stream.Write(m_damaged); } - return false; + return true; } diff --git a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.h b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.h index 857d03a2709..0f46f8e9646 100644 --- a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.h +++ b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.h @@ -3,11 +3,15 @@ * PROJECT: Multi Theft Auto v1.0 * LICENSE: See LICENSE in the top level directory * FILE: mods/deathmatch/logic/packets/CBulletsyncPacket.h + * PURPOSE: Bullet synchronization packet class * * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ +#ifndef __CBULLETSYNCPACKET_H +#define __CBULLETSYNCPACKET_H + #pragma once #include "CPacket.h" @@ -16,21 +20,41 @@ class CBulletsyncPacket final : public CPacket { public: - CBulletsyncPacket(){}; - CBulletsyncPacket(class CPlayer* pPlayer); - - bool HasSimHandler() const { return true; } - ePacketID GetPacketID() const { return PACKET_ID_PLAYER_BULLETSYNC; }; - unsigned long GetFlags() const { return PACKET_MEDIUM_PRIORITY | PACKET_RELIABLE; }; - - bool Read(NetBitStreamInterface& BitStream); - bool Write(NetBitStreamInterface& BitStream) const; - - eWeaponType m_WeaponType; - CVector m_vecStart; - CVector m_vecEnd; - uchar m_ucOrderCounter; - float m_fDamage; - uchar m_ucHitZone; - ElementID m_DamagedPlayerID; + static constexpr float MIN_DISTANCE_SQ = 0.0001f; + static constexpr float MAX_DISTANCE_SQ = 160000.0f; + static constexpr float EPSILON = 0.0001f; + static constexpr float EPSILON_SQ = EPSILON * EPSILON; + static constexpr unsigned char MAX_BODY_ZONE = 9; + static constexpr float MAX_DAMAGE = 200.0f; + + CBulletsyncPacket() = default; + explicit CBulletsyncPacket(class CPlayer* player); + + bool HasSimHandler() const noexcept override { return true; } + ePacketID GetPacketID() const noexcept override { return PACKET_ID_PLAYER_BULLETSYNC; } + unsigned long GetFlags() const noexcept override { return PACKET_MEDIUM_PRIORITY | PACKET_RELIABLE; } + + bool Read(NetBitStreamInterface& stream) override; + bool Write(NetBitStreamInterface& stream) const override; + +private: + bool ReadWeaponAndPositions(NetBitStreamInterface& stream); + bool ReadOptionalDamage(NetBitStreamInterface& stream); + bool ValidateTrajectory() const noexcept; + void ResetDamageData() noexcept; + + static constexpr bool IsNaN(float value) noexcept { return value != value; } + static bool IsValidVector(const CVector& vec) noexcept; + static bool IsValidWeaponId(unsigned char weaponId) noexcept; + +public: + eWeaponType m_weapon{}; + CVector m_start{}; + CVector m_end{}; + std::uint8_t m_order{}; + float m_damage{}; + std::uint8_t m_zone{}; + ElementID m_damaged{INVALID_ELEMENT_ID}; }; + +#endif // __CBULLETSYNCPACKET_H diff --git a/Server/mods/deathmatch/logic/packets/CCameraSyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CCameraSyncPacket.cpp index 03e7944e30b..e3f08398ebb 100644 --- a/Server/mods/deathmatch/logic/packets/CCameraSyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CCameraSyncPacket.cpp @@ -17,20 +17,15 @@ bool CCameraSyncPacket::Read(NetBitStreamInterface& BitStream) { - if (BitStream.Version() >= 0x5E) - { - CPlayer* pPlayer = GetSourcePlayer(); - if (!pPlayer) - return false; + CPlayer* pPlayer = GetSourcePlayer(); + if (!pPlayer) + return false; - // Check the time context - uchar ucTimeContext = 0; - BitStream.Read(ucTimeContext); - if (!pPlayer->GetCamera()->CanUpdateSync(ucTimeContext)) - { - return false; - } - } + // Check the time context + uchar ucTimeContext = 0; + BitStream.Read(ucTimeContext); + if (!pPlayer->GetCamera()->CanUpdateSync(ucTimeContext)) + return false; if (!BitStream.ReadBit(m_bFixed)) return false; diff --git a/Server/mods/deathmatch/logic/packets/CChatClearPacket.h b/Server/mods/deathmatch/logic/packets/CChatClearPacket.h index b85cf2012e4..de68b520313 100644 --- a/Server/mods/deathmatch/logic/packets/CChatClearPacket.h +++ b/Server/mods/deathmatch/logic/packets/CChatClearPacket.h @@ -16,7 +16,7 @@ class CChatClearPacket final : public CPacket { public: - CChatClearPacket(){}; + CChatClearPacket() {}; // Chat uses low priority channel to avoid getting queued behind large map downloads #6877 ePacketID GetPacketID() const { return PACKET_ID_CHAT_CLEAR; }; diff --git a/Server/mods/deathmatch/logic/packets/CChatEchoPacket.cpp b/Server/mods/deathmatch/logic/packets/CChatEchoPacket.cpp index ac28361d296..6352cff9b6f 100644 --- a/Server/mods/deathmatch/logic/packets/CChatEchoPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CChatEchoPacket.cpp @@ -22,20 +22,14 @@ bool CChatEchoPacket::Write(NetBitStreamInterface& BitStream) const BitStream.WriteBit(m_bColorCoded); // Write the client's ID - if (BitStream.Can(eBitStreamVersion::OnClientChatMessage_PlayerSource)) - { - BitStream.Write(GetSourceElement() ? GetSourceElement()->GetID() : INVALID_ELEMENT_ID); - } + BitStream.Write(GetSourceElement() ? GetSourceElement()->GetID() : INVALID_ELEMENT_ID); // Too short? size_t sizeMessage = m_strMessage.length(); if (sizeMessage >= MIN_CHATECHO_LENGTH) { - if (BitStream.Can(eBitStreamVersion::OnClientChatMessage_MessageType)) - { - // Write the message type - BitStream.Write(m_ucMessageType); - } + // Write the message type + BitStream.Write(m_ucMessageType); // Write the string BitStream.Write(m_strMessage.c_str(), sizeMessage); diff --git a/Server/mods/deathmatch/logic/packets/CChatEchoPacket.h b/Server/mods/deathmatch/logic/packets/CChatEchoPacket.h index 7abf8aa279a..0d65f611bb1 100644 --- a/Server/mods/deathmatch/logic/packets/CChatEchoPacket.h +++ b/Server/mods/deathmatch/logic/packets/CChatEchoPacket.h @@ -14,13 +14,13 @@ #include "CPacket.h" #include "../../Config.h" -#define CHATCOLOR_SAY 235, 221, 178 -#define CHATCOLOR_TEAMSAY 235, 221, 178 -#define CHATCOLOR_MESSAGE 255, 168, 0 -#define CHATCOLOR_INFO 255, 100, 100 -#define CHATCOLOR_ME 255, 0, 255 -#define CHATCOLOR_ADMINSAY 131, 205, 241 -#define CHATCOLOR_CONSOLESAY 223, 149, 232 +#define CHATCOLOR_SAY 235, 221, 178 +#define CHATCOLOR_TEAMSAY 235, 221, 178 +#define CHATCOLOR_MESSAGE 255, 168, 0 +#define CHATCOLOR_INFO 255, 100, 100 +#define CHATCOLOR_ME 255, 0, 255 +#define CHATCOLOR_ADMINSAY 131, 205, 241 +#define CHATCOLOR_CONSOLESAY 223, 149, 232 enum eMessageType { diff --git a/Server/mods/deathmatch/logic/packets/CCustomWeaponBulletSyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CCustomWeaponBulletSyncPacket.cpp index b7d350fd2de..83b37ef062f 100644 --- a/Server/mods/deathmatch/logic/packets/CCustomWeaponBulletSyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CCustomWeaponBulletSyncPacket.cpp @@ -1,8 +1,7 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory - * FILE: mods/deathmatch/logic/packets/CCustomWeaponBulletSyncPacket.cpp * * Multi Theft Auto is available from https://www.multitheftauto.com/ * @@ -14,58 +13,47 @@ #include "CPlayer.h" #include "lua/CLuaFunctionParseHelpers.h" -CCustomWeaponBulletSyncPacket::CCustomWeaponBulletSyncPacket(CPlayer* pPlayer) +CCustomWeaponBulletSyncPacket::CCustomWeaponBulletSyncPacket(CPlayer* player) { - m_pSourceElement = pPlayer; - m_pWeapon = NULL; - m_ucOrderCounter = 0; + m_pSourceElement = player; } -bool CCustomWeaponBulletSyncPacket::Read(NetBitStreamInterface& BitStream) +bool CCustomWeaponBulletSyncPacket::Read(NetBitStreamInterface& stream) { - // Got a player? if (m_pSourceElement) - { - ElementID WeaponID = INVALID_ELEMENT_ID; - BitStream.Read(WeaponID); - m_pWeapon = GetElementFromId(WeaponID); + return false; - BitStream.Read((char*)&m_vecStart, sizeof(CVector)); - BitStream.Read((char*)&m_vecEnd, sizeof(CVector)); + ElementID id = INVALID_ELEMENT_ID; + if (!stream.Read(id)) + return false; - // Duplicate packet protection - if (!BitStream.Read(m_ucOrderCounter)) - return false; + m_weapon = GetElementFromId(id); - return true; - } + if (!stream.Read(reinterpret_cast(&m_start), sizeof(CVector)) || !stream.Read(reinterpret_cast(&m_end), sizeof(CVector))) + return false; - return false; -} + if (!m_start.IsValid() || !m_end.IsValid()) + return false; -// Note: Relays a previous Read() -bool CCustomWeaponBulletSyncPacket::Write(NetBitStreamInterface& BitStream) const -{ - // Got a player to write? - if (m_pSourceElement) - { - CPlayer* pSourcePlayer = static_cast(m_pSourceElement); + if (!stream.Read(m_order)) + return false; - // Write the source player id - ElementID PlayerID = pSourcePlayer->GetID(); - BitStream.Write(PlayerID); + return true; +} - // Write the bulletsync data - ElementID WeaponID = m_pWeapon->GetID(); - BitStream.Write(WeaponID); - BitStream.Write((const char*)&m_vecStart, sizeof(CVector)); - BitStream.Write((const char*)&m_vecEnd, sizeof(CVector)); +bool CCustomWeaponBulletSyncPacket::Write(NetBitStreamInterface& stream) const +{ + if (!m_pSourceElement) + return false; - // Duplicate packet protection - BitStream.Write(m_ucOrderCounter); + auto* player = static_cast(m_pSourceElement); + auto id = player->GetID(); - return true; - } + stream.Write(id); + stream.Write(m_weapon->GetID()); + stream.Write(reinterpret_cast(&m_start), sizeof(CVector)); + stream.Write(reinterpret_cast(&m_end), sizeof(CVector)); + stream.Write(m_order); - return false; + return true; } diff --git a/Server/mods/deathmatch/logic/packets/CCustomWeaponBulletSyncPacket.h b/Server/mods/deathmatch/logic/packets/CCustomWeaponBulletSyncPacket.h index d35bfad012b..633e1177881 100644 --- a/Server/mods/deathmatch/logic/packets/CCustomWeaponBulletSyncPacket.h +++ b/Server/mods/deathmatch/logic/packets/CCustomWeaponBulletSyncPacket.h @@ -1,8 +1,7 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory - * FILE: mods/deathmatch/logic/packets/CCustomWeaponBulletSyncPacket.h * * Multi Theft Auto is available from https://www.multitheftauto.com/ * @@ -16,22 +15,22 @@ class CCustomWeaponBulletSyncPacket final : public CPacket { public: - CCustomWeaponBulletSyncPacket(){}; - CCustomWeaponBulletSyncPacket(class CPlayer* pPlayer); + CCustomWeaponBulletSyncPacket() = default; + explicit CCustomWeaponBulletSyncPacket(class CPlayer* player); ePacketID GetPacketID() const { return PACKET_ID_WEAPON_BULLETSYNC; }; unsigned long GetFlags() const { return PACKET_MEDIUM_PRIORITY | PACKET_RELIABLE; }; - bool Read(NetBitStreamInterface& BitStream); - bool Write(NetBitStreamInterface& BitStream) const; + bool Read(NetBitStreamInterface& stream); + bool Write(NetBitStreamInterface& stream) const; - CPlayer* GetWeaponOwner() { return m_pWeapon != NULL ? m_pWeapon->GetOwner() : NULL; }; - CCustomWeapon* GetWeapon() { return m_pWeapon; }; - CVector GetStart() { return m_vecStart; }; - CVector GetEnd() { return m_vecEnd; }; + CPlayer* GetWeaponOwner() { return m_weapon != NULL ? m_weapon->GetOwner() : NULL; }; + CCustomWeapon* GetWeapon() { return m_weapon; }; + CVector GetStart() { return m_start; }; + CVector GetEnd() { return m_end; }; - CCustomWeapon* m_pWeapon; - CVector m_vecStart; - CVector m_vecEnd; - uchar m_ucOrderCounter; + CCustomWeapon* m_weapon{}; + CVector m_start{}; + CVector m_end{}; + std::uint8_t m_order{}; }; diff --git a/Server/mods/deathmatch/logic/packets/CDebugEchoPacket.h b/Server/mods/deathmatch/logic/packets/CDebugEchoPacket.h index 83cea1181dd..8cb7783a54a 100644 --- a/Server/mods/deathmatch/logic/packets/CDebugEchoPacket.h +++ b/Server/mods/deathmatch/logic/packets/CDebugEchoPacket.h @@ -14,9 +14,9 @@ #include "CPacket.h" #include "../../Config.h" -#define DEBUGCOLOR_WARNING 255, 128, 0 -#define DEBUGCOLOR_ERROR 255, 0, 0 -#define DEBUGCOLOR_INFO 0, 255, 0 +#define DEBUGCOLOR_WARNING 255, 128, 0 +#define DEBUGCOLOR_ERROR 255, 0, 0 +#define DEBUGCOLOR_INFO 0, 255, 0 class CDebugEchoPacket final : public CPacket { diff --git a/Server/mods/deathmatch/logic/packets/CDetonateSatchelsPacket.cpp b/Server/mods/deathmatch/logic/packets/CDetonateSatchelsPacket.cpp index f9fbfd68cec..8e25f709bbc 100644 --- a/Server/mods/deathmatch/logic/packets/CDetonateSatchelsPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CDetonateSatchelsPacket.cpp @@ -29,7 +29,8 @@ bool CDetonateSatchelsPacket::Write(NetBitStreamInterface& BitStream) const { BitStream.Write(m_pSourceElement->GetID()); - unsigned short usLatency = static_cast(m_pSourceElement)->GetPing(); + const unsigned int uiPing = static_cast(m_pSourceElement)->GetPing(); + const unsigned short usLatency = uiPing <= 0xFFFF ? static_cast(uiPing) : 0xFFFF; BitStream.WriteCompressed(usLatency); } else diff --git a/Server/mods/deathmatch/logic/packets/CElementRPCPacket.h b/Server/mods/deathmatch/logic/packets/CElementRPCPacket.h index c99ede97e65..d87d1facc50 100644 --- a/Server/mods/deathmatch/logic/packets/CElementRPCPacket.h +++ b/Server/mods/deathmatch/logic/packets/CElementRPCPacket.h @@ -17,7 +17,7 @@ class CElementRPCPacket final : public CPacket { public: CElementRPCPacket(CElement* pSourceElement, unsigned char ucActionID, NetBitStreamInterface& BitStream) - : m_ucActionID(ucActionID), m_BitStream(BitStream), m_pSourceElement(pSourceElement){}; + : m_ucActionID(ucActionID), m_BitStream(BitStream), m_pSourceElement(pSourceElement) {}; ePacketID GetPacketID() const { return PACKET_ID_LUA_ELEMENT_RPC; }; unsigned long GetFlags() const { return PACKET_HIGH_PRIORITY | PACKET_RELIABLE | PACKET_SEQUENCED; }; diff --git a/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp b/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp index dd3038f7418..936206c7dd6 100644 --- a/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp @@ -172,22 +172,20 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const } BitStream.WriteBit(bCollisionsEnabled); - - if (BitStream.Version() >= 0x56) - BitStream.WriteBit(pElement->IsCallPropagationEnabled()); + BitStream.WriteBit(pElement->IsCallPropagationEnabled()); // Write custom data CCustomData& pCustomData = pElement->GetCustomDataManager(); BitStream.WriteCompressed(pCustomData.CountOnlySynchronized()); - map::const_iterator iter = pCustomData.SyncedIterBegin(); + auto iter = pCustomData.SyncedIterBegin(); for (; iter != pCustomData.SyncedIterEnd(); ++iter) { - const char* szName = iter->first.c_str(); + const CStringName name = iter->first; const CLuaArgument* pArgument = &iter->second.Variable; - unsigned char ucNameLength = static_cast(strlen(szName)); + unsigned char ucNameLength = static_cast(name->length()); BitStream.Write(ucNameLength); - BitStream.Write(szName, ucNameLength); + BitStream.Write(name.ToCString(), ucNameLength); pArgument->WriteToBitStream(BitStream); } @@ -219,7 +217,7 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const // Position position.data.vecPosition = pObject->GetPosition(); - SilentlyFixIndeterminate(position.data.vecPosition); // Crash fix for pre r6459 clients + SilentlyFixIndeterminate(position.data.vecPosition); // Crash fix for pre r6459 clients BitStream.Write(&position); // Rotation @@ -248,15 +246,11 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const BitStream.WriteBit(bIsDoubleSided); // Breakable - if (BitStream.Can(eBitStreamVersion::CEntityAddPacket_ObjectBreakable)) - BitStream.WriteBit(pObject->IsBreakable()); + BitStream.WriteBit(pObject->IsBreakable()); // Visible in all dimensions - if (BitStream.Can(eBitStreamVersion::DimensionOmnipresence)) - { - bool bIsVisibleInAllDimensions = pObject->IsVisibleInAllDimensions(); - BitStream.WriteBit(bIsVisibleInAllDimensions); - } + bool bIsVisibleInAllDimensions = pObject->IsVisibleInAllDimensions(); + BitStream.WriteBit(bIsVisibleInAllDimensions); // Moving const CPositionRotationAnimation* pMoveAnimation = pObject->GetMoveAnimation(); @@ -272,27 +266,20 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const // Scale const CVector& vecScale = pObject->GetScale(); - if (BitStream.Version() >= 0x41) + bool bIsUniform = (vecScale.fX == vecScale.fY && vecScale.fX == vecScale.fZ); + BitStream.WriteBit(bIsUniform); + if (bIsUniform) { - bool bIsUniform = (vecScale.fX == vecScale.fY && vecScale.fX == vecScale.fZ); - BitStream.WriteBit(bIsUniform); - if (bIsUniform) - { - bool bIsUnitSize = (vecScale.fX == 1.0f); - BitStream.WriteBit(bIsUnitSize); - if (!bIsUnitSize) - BitStream.Write(vecScale.fX); - } - else - { + bool bIsUnitSize = (vecScale.fX == 1.0f); + BitStream.WriteBit(bIsUnitSize); + if (!bIsUnitSize) BitStream.Write(vecScale.fX); - BitStream.Write(vecScale.fY); - BitStream.Write(vecScale.fZ); - } } else { BitStream.Write(vecScale.fX); + BitStream.Write(vecScale.fY); + BitStream.Write(vecScale.fZ); } // Frozen @@ -305,18 +292,16 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(&health); // is object break? - if (BitStream.Can(eBitStreamVersion::BreakObject_Serverside)) - BitStream.WriteBit(pObject->GetHealth() <= 0); + BitStream.WriteBit(pObject->GetHealth() <= 0); // Respawnable - if (BitStream.Can(eBitStreamVersion::RespawnObject_Serverside)) - BitStream.WriteBit(pObject->IsRespawnEnabled()); + BitStream.WriteBit(pObject->IsRespawnEnabled()); if (ucEntityTypeID == CElement::WEAPON) { CCustomWeapon* pWeapon = static_cast(pElement); unsigned char targetType = pWeapon->GetTargetType(); - BitStream.WriteBits(&targetType, 3); // 3 bits = 4 possible values. + BitStream.WriteBits(&targetType, 3); // 3 bits = 4 possible values. switch (targetType) { @@ -334,12 +319,12 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const { // Send full unsigned char... bone documentation looks scarce. unsigned char ucSubTarget = pWeapon->GetTargetBone(); - BitStream.Write(ucSubTarget); // Send the entire unsigned char as there are a lot of bones. + BitStream.Write(ucSubTarget); // Send the entire unsigned char as there are a lot of bones. } else if (IS_VEHICLE(pTarget)) { - unsigned char ucSubTarget = pWeapon->GetTargetWheel(); - BitStream.WriteBits(&ucSubTarget, 4); // 4 bits = 8 possible values. + unsigned char ucSubTarget = static_cast(pWeapon->GetTargetWheel()); + BitStream.WriteBits(&ucSubTarget, 4); // 4 bits = 8 possible values. } break; } @@ -359,7 +344,7 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const float fAccuracy = pWeaponStat->GetAccuracy(); float fTargetRange = pWeaponStat->GetTargetRange(); float fWeaponRange = pWeaponStat->GetWeaponRange(); - BitStream.WriteBits(&usDamage, 12); // 12 bits = 2048 values... plenty. + BitStream.WriteBits(&usDamage, 12); // 12 bits = 2048 values... plenty. BitStream.Write(fAccuracy); BitStream.Write(fTargetRange); BitStream.Write(fWeaponRange); @@ -380,11 +365,11 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const BitStream.WriteBit(weaponConfig.flags.bSeeThroughStuff); BitStream.WriteBit(weaponConfig.flags.bShootThroughStuff); - unsigned short usAmmo = pWeapon->GetAmmo(); - unsigned short usClipAmmo = pWeapon->GetAmmo(); + unsigned short usAmmo = static_cast(pWeapon->GetAmmo()); + unsigned short usClipAmmo = static_cast(pWeapon->GetAmmo()); ElementID OwnerID = pWeapon->GetOwner() == NULL ? INVALID_ELEMENT_ID : pWeapon->GetOwner()->GetID(); - unsigned char ucWeaponState = pWeapon->GetWeaponState(); - BitStream.WriteBits(&ucWeaponState, 4); // 4 bits = 8 possible values for weapon state + unsigned char ucWeaponState = static_cast(pWeapon->GetWeaponState()); + BitStream.WriteBits(&ucWeaponState, 4); // 4 bits = 8 possible values for weapon state BitStream.Write(usAmmo); BitStream.Write(usClipAmmo); BitStream.Write(OwnerID); @@ -399,7 +384,7 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const // Position position.data.vecPosition = pPickup->GetPosition(); - SilentlyFixIndeterminate(position.data.vecPosition); // Crash fix for pre r6459 clients + SilentlyFixIndeterminate(position.data.vecPosition); // Crash fix for pre r6459 clients BitStream.Write(&position); // Grab the model and write it @@ -462,12 +447,7 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(&position); BitStream.Write(&rotationDegrees); - // Vehicle id as a char - // I'm assuming the "-400" is for adjustment so that all car values can - // fit into a char? Why doesn't someone document this? - // - // --slush - BitStream.Write(static_cast(pVehicle->GetModel() - 400)); + BitStream.Write(static_cast(pVehicle->GetModel())); // Health SVehicleHealthSync health; @@ -475,23 +455,20 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(&health); // Blow state - if (BitStream.Can(eBitStreamVersion::VehicleBlowStateSupport)) - { - unsigned char blowState = 0; + unsigned char blowState = 0; - switch (pVehicle->GetBlowState()) - { - case VehicleBlowState::AWAITING_EXPLOSION_SYNC: - blowState = 1; - break; - case VehicleBlowState::BLOWN: - blowState = 2; - break; - } - - BitStream.WriteBits(&blowState, 2); + switch (pVehicle->GetBlowState()) + { + case VehicleBlowState::AWAITING_EXPLOSION_SYNC: + blowState = 1; + break; + case VehicleBlowState::BLOWN: + blowState = 2; + break; } + BitStream.WriteBits(&blowState, 2); + // Color CVehicleColor& vehColor = pVehicle->GetColor(); uchar ucNumColors = vehColor.GetNumColorsUsed() - 1; @@ -629,7 +606,7 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const handling.data.fTurnMass = pEntry->GetTurnMass(); handling.data.fDragCoeff = pEntry->GetDragCoeff(); handling.data.vecCenterOfMass = pEntry->GetCenterOfMass(); - handling.data.ucPercentSubmerged = pEntry->GetPercentSubmerged(); + handling.data.ucPercentSubmerged = static_cast(pEntry->GetPercentSubmerged()); handling.data.fTractionMultiplier = pEntry->GetTractionMultiplier(); handling.data.ucDriveType = pEntry->GetCarDriveType(); handling.data.ucEngineType = pEntry->GetCarEngineType(); @@ -676,31 +653,28 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const else BitStream.WriteBit(false); - if (BitStream.Version() >= 0x02B) + unsigned char ucSirenCount = pVehicle->m_tSirenBeaconInfo.m_ucSirenCount; + unsigned char ucSirenType = pVehicle->m_tSirenBeaconInfo.m_ucSirenType; + bool bSync = pVehicle->m_tSirenBeaconInfo.m_bOverrideSirens; + BitStream.WriteBit(bSync); + if (bSync) { - unsigned char ucSirenCount = pVehicle->m_tSirenBeaconInfo.m_ucSirenCount; - unsigned char ucSirenType = pVehicle->m_tSirenBeaconInfo.m_ucSirenType; - bool bSync = pVehicle->m_tSirenBeaconInfo.m_bOverrideSirens; - BitStream.WriteBit(bSync); - if (bSync) - { - BitStream.Write(ucSirenCount); - BitStream.Write(ucSirenType); + BitStream.Write(ucSirenCount); + BitStream.Write(ucSirenType); - for (int i = 0; i < ucSirenCount; i++) - { - SVehicleSirenSync syncData; - syncData.data.m_bOverrideSirens = true; - syncData.data.m_b360Flag = pVehicle->m_tSirenBeaconInfo.m_b360Flag; - syncData.data.m_bDoLOSCheck = pVehicle->m_tSirenBeaconInfo.m_bDoLOSCheck; - syncData.data.m_bUseRandomiser = pVehicle->m_tSirenBeaconInfo.m_bUseRandomiser; - syncData.data.m_bEnableSilent = pVehicle->m_tSirenBeaconInfo.m_bSirenSilent; - syncData.data.m_ucSirenID = i; - syncData.data.m_vecSirenPositions = pVehicle->m_tSirenBeaconInfo.m_tSirenInfo[i].m_vecSirenPositions; - syncData.data.m_colSirenColour = pVehicle->m_tSirenBeaconInfo.m_tSirenInfo[i].m_RGBBeaconColour; - syncData.data.m_dwSirenMinAlpha = pVehicle->m_tSirenBeaconInfo.m_tSirenInfo[i].m_dwMinSirenAlpha; - BitStream.Write(&syncData); - } + for (unsigned char i = 0; i < ucSirenCount; i++) + { + SVehicleSirenSync syncData; + syncData.data.m_bOverrideSirens = true; + syncData.data.m_b360Flag = pVehicle->m_tSirenBeaconInfo.m_b360Flag; + syncData.data.m_bDoLOSCheck = pVehicle->m_tSirenBeaconInfo.m_bDoLOSCheck; + syncData.data.m_bUseRandomiser = pVehicle->m_tSirenBeaconInfo.m_bUseRandomiser; + syncData.data.m_bEnableSilent = pVehicle->m_tSirenBeaconInfo.m_bSirenSilent; + syncData.data.m_ucSirenID = i; + syncData.data.m_vecSirenPositions = pVehicle->m_tSirenBeaconInfo.m_tSirenInfo[i].m_vecSirenPositions; + syncData.data.m_colSirenColour = pVehicle->m_tSirenBeaconInfo.m_tSirenInfo[i].m_RGBBeaconColour; + syncData.data.m_dwSirenMinAlpha = pVehicle->m_tSirenBeaconInfo.m_tSirenInfo[i].m_dwMinSirenAlpha; + BitStream.Write(&syncData); } } break; @@ -712,7 +686,7 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const // Position position.data.vecPosition = pMarker->GetPosition(); - SilentlyFixIndeterminate(position.data.vecPosition); // Crash fix for pre r6459 clients + SilentlyFixIndeterminate(position.data.vecPosition); // Crash fix for pre r6459 clients BitStream.Write(&position); // Type @@ -739,7 +713,7 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const position.data.vecPosition = pMarker->GetTarget(); BitStream.Write(&position); - if (markerType.data.ucType == CMarker::TYPE_CHECKPOINT && BitStream.Can(eBitStreamVersion::SetMarkerTargetArrowProperties)) + if (markerType.data.ucType == CMarker::TYPE_CHECKPOINT) { SColor color = pMarker->GetTargetArrowColor(); @@ -755,8 +729,7 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const } // Alpha limit - if (BitStream.Can(eBitStreamVersion::Marker_IgnoreAlphaLimits)) - BitStream.WriteBit(pMarker->AreAlphaLimitsIgnored()); + BitStream.WriteBit(pMarker->AreAlphaLimitsIgnored()); break; } @@ -799,13 +772,13 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const // Write the position SPosition2DSync position2D(false); position2D.data.vecPosition = pArea->GetPosition(); - SilentlyFixIndeterminate(position2D.data.vecPosition); // Crash fix for pre r6459 clients + SilentlyFixIndeterminate(position2D.data.vecPosition); // Crash fix for pre r6459 clients BitStream.Write(&position2D); // Write the size SPosition2DSync size2D(false); size2D.data.vecPosition = pArea->GetSize(); - SilentlyFixIndeterminate(size2D.data.vecPosition); // Crash fix for pre r6459 clients + SilentlyFixIndeterminate(size2D.data.vecPosition); // Crash fix for pre r6459 clients BitStream.Write(&size2D); // And the color @@ -924,11 +897,8 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(&alpha); // Move anim - if (BitStream.Version() > 0x4B) - { - uchar ucMoveAnim = pPed->GetMoveAnim(); - BitStream.Write(ucMoveAnim); - } + uchar ucMoveAnim = pPed->GetMoveAnim(); + BitStream.Write(ucMoveAnim); // clothes unsigned char ucNumClothes = 0; @@ -959,57 +929,52 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const } // weapons - if (BitStream.Version() >= 0x61) + // Get a list of weapons + for (unsigned char slot = 0; slot < WEAPONSLOT_MAX; ++slot) { - // Get a list of weapons - for (unsigned char slot = 0; slot < WEAPONSLOT_MAX; ++slot) + CWeapon* pWeapon = pPed->GetWeapon(slot); + if (pWeapon->ucType != 0) { - CWeapon* pWeapon = pPed->GetWeapon(slot); - if (pWeapon->ucType != 0) - { - BitStream.Write(slot); - BitStream.Write(pWeapon->ucType); - BitStream.Write(pWeapon->usAmmo); + BitStream.Write(slot); + BitStream.Write(pWeapon->ucType); + BitStream.Write(pWeapon->usAmmo); - // ammoInClip is not implemented generally - // BitStream.Write ( pWeapon->usAmmoInClip ); - } + // ammoInClip is not implemented generally + // BitStream.Write ( pWeapon->usAmmoInClip ); } + } - // Write end marker (slot) - BitStream.Write((unsigned char)0xFF); + // Write end marker (slot) + BitStream.Write((unsigned char)0xFF); - // Send the current weapon spot - unsigned char currentWeaponSlot = pPed->GetWeaponSlot(); - BitStream.Write(currentWeaponSlot); - } + // Send the current weapon spot + unsigned char currentWeaponSlot = pPed->GetWeaponSlot(); + BitStream.Write(currentWeaponSlot); // Animation - if (BitStream.Can(eBitStreamVersion::AnimationsSync)) - { - const SPlayerAnimData& animData = pPed->GetAnimationData(); + const SPlayerAnimData& animData = pPed->GetAnimationData(); + bool animRunning = animData.IsAnimating(); + BitStream.WriteBit(animRunning); - // Contains animation data? - bool animRunning = animData.IsAnimating(); - BitStream.WriteBit(animRunning); - - if (animRunning) - { - BitStream.WriteString(animData.blockName); - BitStream.WriteString(animData.animName); - BitStream.Write(animData.time); - BitStream.WriteBit(animData.loop); - BitStream.WriteBit(animData.updatePosition); - BitStream.WriteBit(animData.interruptable); - BitStream.WriteBit(animData.freezeLastFrame); - BitStream.Write(animData.blendTime); - BitStream.WriteBit(animData.taskToBeRestoredOnAnimEnd); - - // Write elapsed time & speed - float elapsedTime = GetTickCount64_() - animData.startedTick; - BitStream.Write(elapsedTime); - BitStream.Write(animData.speed); - } + if (animRunning) + { + BitStream.WriteString(animData.blockName); + BitStream.WriteString(animData.animName); + BitStream.Write(animData.time); + BitStream.WriteBit(animData.loop); + BitStream.WriteBit(animData.updatePosition); + BitStream.WriteBit(animData.interruptable); + BitStream.WriteBit(animData.freezeLastFrame); + BitStream.Write(animData.blendTime); + BitStream.WriteBit(animData.taskToBeRestoredOnAnimEnd); + + // Write elapsed time & speed + const uint64_t nowTick = GetTickCount64_(); + const uint64_t elapsedMs = + nowTick >= static_cast(animData.startTime) ? (nowTick - static_cast(animData.startTime)) : 0; + const float elapsedTime = static_cast(elapsedMs); + BitStream.Write(elapsedTime); + BitStream.Write(animData.speed); } break; @@ -1118,14 +1083,11 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(&vertex); } - if (BitStream.Can(eBitStreamVersion::SetColPolygonHeight)) - { - float fFloor, fCeil; - pPolygon->GetHeight(fFloor, fCeil); + float fFloor, fCeil; + pPolygon->GetHeight(fFloor, fCeil); - BitStream.Write(fFloor); - BitStream.Write(fCeil); - } + BitStream.Write(fFloor); + BitStream.Write(fCeil); break; } default: @@ -1147,19 +1109,12 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write((short)vecVertex.fY); BitStream.Write(vecVertex.fZ); } - if (BitStream.Can(eBitStreamVersion::Water_bShallow_ServerSide)) - BitStream.WriteBit(pWater->IsWaterShallow()); + BitStream.WriteBit(pWater->IsWaterShallow()); break; } case CElement::BUILDING: { - if (!BitStream.Can(eBitStreamVersion::ServersideBuildingElement)) - { - CLogger::LogPrintf("not sending this element - id: %i\n", pElement->GetType()); - break; - } - CBuilding* pBuilding = static_cast(pElement); // Position @@ -1178,7 +1133,7 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const BitStream.WriteCompressed(pBuilding->GetInterior()); CBuilding* pLowLodBuilding = pBuilding->GetLowLodElement(); - ElementID lowLodBuildingID = pLowLodBuilding ? pLowLodBuilding->GetID() : INVALID_ELEMENT_ID; + ElementID lowLodBuildingID = pLowLodBuilding ? pLowLodBuilding->GetID() : INVALID_ELEMENT_ID; BitStream.Write(lowLodBuildingID); break; } diff --git a/Server/mods/deathmatch/logic/packets/CExplosionSyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CExplosionSyncPacket.cpp index c1f4bd4145d..68732ee9db4 100644 --- a/Server/mods/deathmatch/logic/packets/CExplosionSyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CExplosionSyncPacket.cpp @@ -37,7 +37,7 @@ bool CExplosionSyncPacket::Read(NetBitStreamInterface& BitStream) if (bHasOrigin && !BitStream.Read(m_OriginID)) return false; - if (bHasOrigin && BitStream.Can(eBitStreamVersion::VehicleBlowStateSupport)) + if (bHasOrigin) { if (!BitStream.ReadBit(m_isVehicleResponsible)) return false; @@ -70,7 +70,8 @@ bool CExplosionSyncPacket::Write(NetBitStreamInterface& BitStream) const ElementID ID = m_pSourceElement->GetID(); BitStream.Write(ID); - unsigned short usLatency = static_cast(m_pSourceElement)->GetPing(); + const unsigned int uiPing = static_cast(m_pSourceElement)->GetPing(); + const unsigned short usLatency = uiPing <= 0xFFFF ? static_cast(uiPing) : 0xFFFF; BitStream.WriteCompressed(usLatency); } else @@ -83,13 +84,10 @@ bool CExplosionSyncPacket::Write(NetBitStreamInterface& BitStream) const BitStream.WriteBit(true); BitStream.Write(m_OriginID); - if (BitStream.Can(eBitStreamVersion::VehicleBlowStateSupport)) - { - BitStream.WriteBit(m_isVehicleResponsible); + BitStream.WriteBit(m_isVehicleResponsible); - if (m_isVehicleResponsible) - BitStream.WriteBit(m_blowVehicleWithoutExplosion); - } + if (m_isVehicleResponsible) + BitStream.WriteBit(m_blowVehicleWithoutExplosion); } else BitStream.WriteBit(false); diff --git a/Server/mods/deathmatch/logic/packets/CFireSyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CFireSyncPacket.cpp index 2cb1a6426b6..cc14b3ee8f9 100644 --- a/Server/mods/deathmatch/logic/packets/CFireSyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CFireSyncPacket.cpp @@ -38,7 +38,8 @@ bool CFireSyncPacket::Write(NetBitStreamInterface& BitStream) const ElementID ID = m_pSourceElement->GetID(); BitStream.Write(ID); - unsigned short usLatency = static_cast(m_pSourceElement)->GetPing(); + const unsigned int uiPing = static_cast(m_pSourceElement)->GetPing(); + const unsigned short usLatency = uiPing <= 0xFFFF ? static_cast(uiPing) : 0xFFFF; BitStream.WriteCompressed(usLatency); } else diff --git a/Server/mods/deathmatch/logic/packets/CKeysyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CKeysyncPacket.cpp index 0e523de6e6d..0987ab189fc 100644 --- a/Server/mods/deathmatch/logic/packets/CKeysyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CKeysyncPacket.cpp @@ -70,28 +70,37 @@ bool CKeysyncPacket::Read(NetBitStreamInterface& BitStream) if (pSourcePlayer->GetWeaponType() != ucClientWeaponType) { - bWeaponCorrect = false; // Possibly old weapon data. - ucUseWeaponType = ucClientWeaponType; // Use the packet supplied weapon type to skip over the correct amount of data + bWeaponCorrect = false; // Possibly old weapon data. + ucUseWeaponType = ucClientWeaponType; // Use the packet supplied weapon type to skip over the correct amount of data } // Read out the current weapon slot and set it SWeaponSlotSync slot; if (!BitStream.Read(&slot)) return false; - unsigned int uiSlot = slot.data.uiSlot; + auto ucSlot = static_cast(slot.data.uiSlot); if (bWeaponCorrect) - pSourcePlayer->SetWeaponSlot(uiSlot); + { + const unsigned int uiCurrSlot = slot.data.uiSlot; + if (uiCurrSlot != static_cast(pSourcePlayer->GetWeaponSlot())) + { + if (uiCurrSlot > 0xFF) + return false; + + pSourcePlayer->SetWeaponSlot(static_cast(uiCurrSlot)); + } + } // Did he have a weapon? - if (CWeaponNames::DoesSlotHaveAmmo(uiSlot)) + if (CWeaponNames::DoesSlotHaveAmmo(ucSlot)) { // And ammo in clip SWeaponAmmoSync ammo(ucUseWeaponType, false, true); if (!BitStream.Read(&ammo)) return false; - float fWeaponRange = pSourcePlayer->GetWeaponRangeFromSlot(uiSlot); + float fWeaponRange = pSourcePlayer->GetWeaponRangeFromSlot(ucSlot); // Read the aim data SWeaponAimSync aim(fWeaponRange); @@ -131,7 +140,7 @@ bool CKeysyncPacket::Read(NetBitStreamInterface& BitStream) { ReadVehicleSpecific(pVehicle, BitStream); - if (pVehicle->GetUpgrades()->HasUpgrade(1087)) // Hydraulics? + if (pVehicle->GetUpgrades()->HasUpgrade(1087)) // Hydraulics? { short sRightStickX, sRightStickY; if (!BitStream.Read(sRightStickX) || !BitStream.Read(sRightStickY)) @@ -235,7 +244,7 @@ bool CKeysyncPacket::Write(NetBitStreamInterface& BitStream) const { WriteVehicleSpecific(pVehicle, BitStream); - if (pVehicle->GetUpgrades()->HasUpgrade(1087)) // Hydraulics? + if (pVehicle->GetUpgrades()->HasUpgrade(1087)) // Hydraulics? { BitStream.Write(ControllerState.RightStickX); BitStream.Write(ControllerState.RightStickY); diff --git a/Server/mods/deathmatch/logic/packets/CKeysyncPacket.h b/Server/mods/deathmatch/logic/packets/CKeysyncPacket.h index 7d555d6d210..f02ba6cc48b 100644 --- a/Server/mods/deathmatch/logic/packets/CKeysyncPacket.h +++ b/Server/mods/deathmatch/logic/packets/CKeysyncPacket.h @@ -17,7 +17,7 @@ class CKeysyncPacket final : public CPacket { public: - CKeysyncPacket(){}; + CKeysyncPacket() {}; CKeysyncPacket(class CPlayer* pPlayer); bool HasSimHandler() const { return true; } diff --git a/Server/mods/deathmatch/logic/packets/CLightsyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CLightsyncPacket.cpp index 0288de2a406..3c3c7d7eade 100644 --- a/Server/mods/deathmatch/logic/packets/CLightsyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CLightsyncPacket.cpp @@ -45,7 +45,8 @@ bool CLightsyncPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(pPlayer->GetID()); BitStream.Write((unsigned char)pPlayer->GetSyncTimeContext()); - unsigned short usLatency = pPlayer->GetPing(); + const unsigned int uiPing = pPlayer->GetPing(); + const unsigned short usLatency = uiPing <= 0xFFFF ? static_cast(uiPing) : 0xFFFF; BitStream.WriteCompressed(usLatency); BitStream.WriteBit(data.health.bSync); diff --git a/Server/mods/deathmatch/logic/packets/CLuaEventPacket.cpp b/Server/mods/deathmatch/logic/packets/CLuaEventPacket.cpp index e0e80c48b41..a3d3a9f11f6 100644 --- a/Server/mods/deathmatch/logic/packets/CLuaEventPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CLuaEventPacket.cpp @@ -22,7 +22,7 @@ CLuaEventPacket::CLuaEventPacket(const char* szName, ElementID ID, CLuaArguments { m_strName.AssignLeft(szName, MAX_EVENT_NAME_LENGTH); m_ElementID = ID; - m_pArguments = pArguments; // Use a pointer to save copying the arguments + m_pArguments = pArguments; // Use a pointer to save copying the arguments } bool CLuaEventPacket::Read(NetBitStreamInterface& BitStream) diff --git a/Server/mods/deathmatch/logic/packets/CLuaPacket.h b/Server/mods/deathmatch/logic/packets/CLuaPacket.h index 384c9973de5..ad319000c6b 100644 --- a/Server/mods/deathmatch/logic/packets/CLuaPacket.h +++ b/Server/mods/deathmatch/logic/packets/CLuaPacket.h @@ -16,7 +16,7 @@ class CLuaPacket final : public CPacket { public: - CLuaPacket(unsigned char ucActionID, NetBitStreamInterface& BitStream) : m_ucActionID(ucActionID), m_BitStream(BitStream){}; + CLuaPacket(unsigned char ucActionID, NetBitStreamInterface& BitStream) : m_ucActionID(ucActionID), m_BitStream(BitStream) {}; ePacketID GetPacketID() const { return PACKET_ID_LUA; }; unsigned long GetFlags() const { return PACKET_HIGH_PRIORITY | PACKET_RELIABLE | PACKET_SEQUENCED; }; diff --git a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp index 614ff8c9ab8..aceac1b129f 100644 --- a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp @@ -22,7 +22,7 @@ CMapInfoPacket::CMapInfoPacket(unsigned char ucWeather, unsigned char ucWeatherB float fWaveHeight, const SWorldWaterLevelInfo& worldWaterLevelInfo, bool bHasSkyGradient, const SGarageStates& garageStates, unsigned char ucSkyGradientTR, unsigned char ucSkyGradientTG, unsigned char ucSkyGradientTB, unsigned char ucSkyGradientBR, unsigned char ucSkyGradientBG, unsigned char ucSkyGradientBB, bool bHasHeatHaze, const SHeatHazeSettings& heatHazeSettings, - unsigned short usFPSLimit, bool bCloudsEnabled, float fJetpackMaxHeight, bool bOverrideWaterColor, unsigned char ucWaterRed, + unsigned short fps, bool bCloudsEnabled, float fJetpackMaxHeight, bool bOverrideWaterColor, unsigned char ucWaterRed, unsigned char ucWaterGreen, unsigned char ucWaterBlue, unsigned char ucWaterAlpha, bool bInteriorSoundsEnabled, bool bOverrideRainLevel, float fRainLevel, bool bOverrideSunSize, float fSunSize, bool bOverrideSunColor, unsigned char ucSunCoreR, unsigned char ucSunCoreG, unsigned char ucSunCoreB, unsigned char ucSunCoronaR, @@ -52,7 +52,7 @@ CMapInfoPacket::CMapInfoPacket(unsigned char ucWeather, unsigned char ucWeatherB m_ucSkyGradientBB = ucSkyGradientBB; m_bHasHeatHaze = bHasHeatHaze; m_HeatHazeSettings = heatHazeSettings; - m_usFPSLimit = usFPSLimit; + m_fpsLimit = fps; m_bCloudsEnabled = bCloudsEnabled; m_fJetpackMaxHeight = fJetpackMaxHeight; m_bOverrideWaterColor = bOverrideWaterColor; @@ -142,15 +142,12 @@ bool CMapInfoPacket::Write(NetBitStreamInterface& BitStream) const { BitStream.Write(m_WorldWaterLevelInfo.fNonSeaLevel); } - if (BitStream.Can(eBitStreamVersion::SetWaterLevel_ChangeOutsideWorldLevel)) + BitStream.WriteBit(m_WorldWaterLevelInfo.bOutsideLevelSet); + if (m_WorldWaterLevelInfo.bOutsideLevelSet) { - BitStream.WriteBit(m_WorldWaterLevelInfo.bOutsideLevelSet); - if (m_WorldWaterLevelInfo.bOutsideLevelSet) - { - BitStream.Write(m_WorldWaterLevelInfo.fOutsideLevel); - } + BitStream.Write(m_WorldWaterLevelInfo.fOutsideLevel); } - BitStream.WriteCompressed(m_usFPSLimit); + BitStream.WriteCompressed(m_fpsLimit); // Write the garage states for (unsigned char i = 0; i < MAX_GARAGES; i++) @@ -166,39 +163,36 @@ bool CMapInfoPacket::Write(NetBitStreamInterface& BitStream) const funBugs.data.bFastMove = g_pGame->IsGlitchEnabled(CGame::GLITCH_FASTMOVE); funBugs.data.bCrouchBug = g_pGame->IsGlitchEnabled(CGame::GLITCH_CROUCHBUG); funBugs.data.bCloseRangeDamage = g_pGame->IsGlitchEnabled(CGame::GLITCH_CLOSEDAMAGE); - funBugs.data2.bHitAnim = g_pGame->IsGlitchEnabled(CGame::GLITCH_HITANIM); - funBugs.data3.bFastSprint = g_pGame->IsGlitchEnabled(CGame::GLITCH_FASTSPRINT); - funBugs.data4.bBadDrivebyHitboxes = g_pGame->IsGlitchEnabled(CGame::GLITCH_BADDRIVEBYHITBOX); - funBugs.data5.bQuickStand = g_pGame->IsGlitchEnabled(CGame::GLITCH_QUICKSTAND); - funBugs.data6.vehicleRapidStop = g_pGame->IsGlitchEnabled(CGame::GLITCH_VEHICLE_RAPID_STOP); + funBugs.data.bHitAnim = g_pGame->IsGlitchEnabled(CGame::GLITCH_HITANIM); + funBugs.data.bFastSprint = g_pGame->IsGlitchEnabled(CGame::GLITCH_FASTSPRINT); + funBugs.data.bBadDrivebyHitboxes = g_pGame->IsGlitchEnabled(CGame::GLITCH_BADDRIVEBYHITBOX); + funBugs.data.bQuickStand = g_pGame->IsGlitchEnabled(CGame::GLITCH_QUICKSTAND); + funBugs.data.vehicleRapidStop = g_pGame->IsGlitchEnabled(CGame::GLITCH_VEHICLE_RAPID_STOP); BitStream.Write(&funBugs); // Write world special properties states - if (BitStream.Can(eBitStreamVersion::WorldSpecialProperties)) - { - SWorldSpecialPropertiesStateSync wsProps; - wsProps.data.hovercars = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::HOVERCARS); - wsProps.data.aircars = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::AIRCARS); - wsProps.data.extrabunny = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::EXTRABUNNY); - wsProps.data.extrajump = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::EXTRAJUMP); - wsProps.data.randomfoliage = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::RANDOMFOLIAGE); - wsProps.data.snipermoon = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::SNIPERMOON); - wsProps.data.extraairresistance = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::EXTRAAIRRESISTANCE); - wsProps.data.underworldwarp = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::UNDERWORLDWARP); - wsProps.data.vehiclesunglare = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLESUNGLARE); - wsProps.data.coronaztest = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::CORONAZTEST); - wsProps.data.watercreatures = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::WATERCREATURES); - wsProps.data.burnflippedcars = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::BURNFLIPPEDCARS); - wsProps.data2.fireballdestruct = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::FIREBALLDESTRUCT); - wsProps.data3.roadsignstext = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::ROADSIGNSTEXT); - wsProps.data4.extendedwatercannons = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::EXTENDEDWATERCANNONS); - wsProps.data5.tunnelweatherblend = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::TUNNELWEATHERBLEND); - wsProps.data6.ignoreFireState = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::IGNOREFIRESTATE); - wsProps.data7.flyingcomponents = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::FLYINGCOMPONENTS); - wsProps.data8.vehicleburnexplosions = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLEBURNEXPLOSIONS); - wsProps.data9.vehicleEngineAutoStart = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLE_ENGINE_AUTOSTART); - BitStream.Write(&wsProps); - } + SWorldSpecialPropertiesStateSync wsProps; + wsProps.data.hovercars = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::HOVERCARS); + wsProps.data.aircars = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::AIRCARS); + wsProps.data.extrabunny = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::EXTRABUNNY); + wsProps.data.extrajump = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::EXTRAJUMP); + wsProps.data.randomfoliage = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::RANDOMFOLIAGE); + wsProps.data.snipermoon = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::SNIPERMOON); + wsProps.data.extraairresistance = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::EXTRAAIRRESISTANCE); + wsProps.data.underworldwarp = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::UNDERWORLDWARP); + wsProps.data.vehiclesunglare = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLESUNGLARE); + wsProps.data.coronaztest = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::CORONAZTEST); + wsProps.data.watercreatures = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::WATERCREATURES); + wsProps.data.burnflippedcars = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::BURNFLIPPEDCARS); + wsProps.data.fireballdestruct = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::FIREBALLDESTRUCT); + wsProps.data.roadsignstext = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::ROADSIGNSTEXT); + wsProps.data.extendedwatercannons = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::EXTENDEDWATERCANNONS); + wsProps.data.tunnelweatherblend = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::TUNNELWEATHERBLEND); + wsProps.data.ignoreFireState = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::IGNOREFIRESTATE); + wsProps.data.flyingcomponents = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::FLYINGCOMPONENTS); + wsProps.data.vehicleburnexplosions = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLEBURNEXPLOSIONS); + wsProps.data.vehicleEngineAutoStart = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLE_ENGINE_AUTOSTART); + BitStream.Write(&wsProps); BitStream.Write(m_fJetpackMaxHeight); @@ -222,13 +216,10 @@ bool CMapInfoPacket::Write(NetBitStreamInterface& BitStream) const } // Moon size - if (BitStream.Version() >= 0x40) + BitStream.WriteBit(m_bOverrideMoonSize); + if (m_bOverrideMoonSize) { - BitStream.WriteBit(m_bOverrideMoonSize); - if (m_bOverrideMoonSize) - { - BitStream.Write(m_iMoonSize); - } + BitStream.Write(m_iMoonSize); } // Sun size @@ -274,19 +265,15 @@ bool CMapInfoPacket::Write(NetBitStreamInterface& BitStream) const } BitStream.Write(m_fAircraftMaxHeight); + BitStream.Write(m_fAircraftMaxVelocity); - if (BitStream.Version() >= 0x3E) - BitStream.Write(m_fAircraftMaxVelocity); - - if (BitStream.Version() >= 0x30) + for (int i = WEAPONTYPE_BRASSKNUCKLE; i < WEAPONTYPE_PISTOL; i++) { - for (int i = WEAPONTYPE_BRASSKNUCKLE; i < WEAPONTYPE_PISTOL; i++) - { - bool bEnabled; - bEnabled = g_pGame->GetJetpackWeaponEnabled((eWeaponType)i); - BitStream.WriteBit(bEnabled); - } + bool bEnabled; + bEnabled = g_pGame->GetJetpackWeaponEnabled((eWeaponType)i); + BitStream.WriteBit(bEnabled); } + for (int i = WEAPONTYPE_PISTOL; i <= WEAPONTYPE_EXTINGUISHER; i++) { sWeaponPropertySync WeaponProperty; @@ -311,10 +298,8 @@ bool CMapInfoPacket::Write(NetBitStreamInterface& BitStream) const WeaponProperty.data.anim_breakout_time = pWeaponStat->GetWeaponAnimBreakoutTime(); BitStream.Write(&WeaponProperty); - if (BitStream.Version() >= 0x30) - { - BitStream.WriteBit(g_pGame->GetJetpackWeaponEnabled((eWeaponType)i)); - } + + BitStream.WriteBit(g_pGame->GetJetpackWeaponEnabled((eWeaponType)i)); } for (int i = WEAPONTYPE_PISTOL; i <= WEAPONTYPE_TEC9; i++) @@ -344,19 +329,15 @@ bool CMapInfoPacket::Write(NetBitStreamInterface& BitStream) const WeaponProperty.data.anim_breakout_time = pWeaponStat->GetWeaponAnimBreakoutTime(); BitStream.Write(&WeaponProperty); } - if (BitStream.Version() >= 0x36) - { - BitStream.WriteBit(g_pGame->GetJetpackWeaponEnabled((eWeaponType)i)); - } + + BitStream.WriteBit(g_pGame->GetJetpackWeaponEnabled((eWeaponType)i)); } - if (BitStream.Version() >= 0x30) + + for (int i = WEAPONTYPE_CAMERA; i <= WEAPONTYPE_PARACHUTE; i++) { - for (int i = WEAPONTYPE_CAMERA; i <= WEAPONTYPE_PARACHUTE; i++) - { - bool bEnabled; - bEnabled = g_pGame->GetJetpackWeaponEnabled((eWeaponType)i); - BitStream.WriteBit(bEnabled); - } + bool bEnabled; + bEnabled = g_pGame->GetJetpackWeaponEnabled((eWeaponType)i); + BitStream.WriteBit(bEnabled); } multimap::const_iterator iter = g_pGame->GetBuildingRemovalManager()->IterBegin(); @@ -369,18 +350,12 @@ bool CMapInfoPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(pBuildingRemoval->GetPosition().fX); BitStream.Write(pBuildingRemoval->GetPosition().fY); BitStream.Write(pBuildingRemoval->GetPosition().fZ); - if (BitStream.Version() >= 0x039) - { - BitStream.Write(pBuildingRemoval->GetInterior()); - } + BitStream.Write(pBuildingRemoval->GetInterior()); } BitStream.WriteBit(false); - if (BitStream.Version() >= 0x25) - { - bool bOcclusionsEnabled = g_pGame->GetOcclusionsEnabled(); - BitStream.WriteBit(bOcclusionsEnabled); - } + bool bOcclusionsEnabled = g_pGame->GetOcclusionsEnabled(); + BitStream.WriteBit(bOcclusionsEnabled); return true; } diff --git a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.h b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.h index fb3224b6fe9..9425a0687e6 100644 --- a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.h +++ b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.h @@ -32,12 +32,12 @@ class CMapInfoPacket final : public CPacket float fWaveHeight, const SWorldWaterLevelInfo& worldWaterLevelInfo, bool bHasSkyGradient, const SGarageStates& garageStates, unsigned char ucSkyGradientTR, unsigned char ucSkyGradientTG, unsigned char ucSkyGradientTB, unsigned char ucSkyGradientBR, unsigned char ucSkyGradientBG, unsigned char ucSkyGradientBB, bool bHasHeatHaze, const SHeatHazeSettings& heatHazeSettings, - unsigned short usFPSLimit = 36, bool bCloudsEnabled = true, float fJetpackMaxHeight = 100, bool bOverrideWaterColor = false, - unsigned char ucWaterRed = 0, unsigned char ucWaterGreen = 0, unsigned char ucWaterBlue = 0, unsigned char ucWaterAlpha = 0, - bool bInteriorSoundsEnabled = true, bool bOverrideRainLevel = false, float fRainLevel = 0, bool bOverrideSunSize = false, - float fSunSize = 0, bool bOverrideSunColor = false, unsigned char ucSunCoreR = 0, unsigned char ucSunCoreG = 0, - unsigned char ucSunCoreB = 0, unsigned char ucSunCoronaR = 0, unsigned char ucSunCoronaG = 0, unsigned char ucSunCoronaB = 0, - bool bOverrideWindVelocity = false, float fWindVelX = 0, float fWindVelY = 0, float fWindVelZ = 0, + unsigned short fps = FPSLimits::FPS_MIN, bool bCloudsEnabled = true, float fJetpackMaxHeight = 100, + bool bOverrideWaterColor = false, unsigned char ucWaterRed = 0, unsigned char ucWaterGreen = 0, unsigned char ucWaterBlue = 0, + unsigned char ucWaterAlpha = 0, bool bInteriorSoundsEnabled = true, bool bOverrideRainLevel = false, float fRainLevel = 0, + bool bOverrideSunSize = false, float fSunSize = 0, bool bOverrideSunColor = false, unsigned char ucSunCoreR = 0, + unsigned char ucSunCoreG = 0, unsigned char ucSunCoreB = 0, unsigned char ucSunCoronaR = 0, unsigned char ucSunCoronaG = 0, + unsigned char ucSunCoronaB = 0, bool bOverrideWindVelocity = false, float fWindVelX = 0, float fWindVelY = 0, float fWindVelZ = 0, bool bOverrideFarClipDistance = false, float fFarClip = 0, bool bOverrideFogDistance = false, float fFogDistance = 0, float fAircraftMaxHeight = 800, float fAircraftMaxVelocity = 1.5f, bool bOverrideMoonSize = false, int iMoonSize = 3); @@ -64,7 +64,7 @@ class CMapInfoPacket final : public CPacket unsigned char m_ucSkyGradientBR, m_ucSkyGradientBG, m_ucSkyGradientBB; bool m_bHasHeatHaze; SHeatHazeSettings m_HeatHazeSettings; - unsigned short m_usFPSLimit; + std::uint16_t m_fpsLimit; const SGarageStates* m_pGarageStates; bool m_bCloudsEnabled; float m_fJetpackMaxHeight; diff --git a/Server/mods/deathmatch/logic/packets/CPacket.h b/Server/mods/deathmatch/logic/packets/CPacket.h index 93c466e74f4..455e9a1c418 100644 --- a/Server/mods/deathmatch/logic/packets/CPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPacket.h @@ -35,7 +35,7 @@ class CPacket { public: CPacket(); - virtual ~CPacket(){}; + virtual ~CPacket() {}; virtual bool RequiresSourcePlayer() const { return true; } virtual bool HasSimHandler() const { return false; } diff --git a/Server/mods/deathmatch/logic/packets/CPedStartSyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CPedStartSyncPacket.cpp index 70c4d6c9377..33f00726ad5 100644 --- a/Server/mods/deathmatch/logic/packets/CPedStartSyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPedStartSyncPacket.cpp @@ -37,8 +37,7 @@ bool CPedStartSyncPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(m_pPed->GetHealth()); BitStream.Write(m_pPed->GetArmor()); - if (BitStream.Can(eBitStreamVersion::PedSync_CameraRotation)) - BitStream.Write(m_pPed->GetCameraRotation()); + BitStream.Write(m_pPed->GetCameraRotation()); return true; } diff --git a/Server/mods/deathmatch/logic/packets/CPedSyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CPedSyncPacket.cpp index dba8f3351b6..54679c1da42 100644 --- a/Server/mods/deathmatch/logic/packets/CPedSyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPedSyncPacket.cpp @@ -38,18 +38,13 @@ bool CPedSyncPacket::Read(NetBitStreamInterface& BitStream) return false; Data.ucFlags = ucFlags; - if (BitStream.Can(eBitStreamVersion::PedSync_CameraRotation)) - { - if (!BitStream.Read(Data.flags2)) - return false; - } - else - Data.flags2 = 0; + if (!BitStream.Read(Data.flags2)) + return false; // Did we recieve position? if (ucFlags & 0x01) - { - if (!(BitStream.Can(eBitStreamVersion::PedSync_Revision) ? Data.ReadSpatialData(BitStream) : Data.ReadSpatialDataBC(BitStream))) + { + if (!Data.ReadSpatialData(BitStream)) return false; } @@ -80,7 +75,7 @@ bool CPedSyncPacket::Read(NetBitStreamInterface& BitStream) return false; } - if (ucFlags & 0x60 && BitStream.Can(eBitStreamVersion::IsPedReloadingWeapon)) + if (ucFlags & 0x60) { if (!BitStream.ReadBit(Data.isReloadingWeapon)) return false; @@ -115,44 +110,18 @@ bool CPedSyncPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(Data.ucSyncTimeContext); BitStream.Write(Data.ucFlags); + BitStream.Write(Data.flags2); - if (BitStream.Can(eBitStreamVersion::PedSync_CameraRotation)) - BitStream.Write(Data.flags2); - - if (BitStream.Can(eBitStreamVersion::PedSync_Revision)) - { - // Position and rotation - if (Data.ucFlags & 0x01) - BitStream.Write(&Data.position); - - if (Data.ucFlags & 0x02) - BitStream.Write(&Data.rotation); - - // Velocity - if (Data.ucFlags & 0x04) - BitStream.Write(&Data.velocity); - } - else - { - // Position and rotation - if (Data.ucFlags & 0x01) - { - BitStream.Write(Data.position.data.vecPosition.fX); - BitStream.Write(Data.position.data.vecPosition.fY); - BitStream.Write(Data.position.data.vecPosition.fZ); - } + // Position and rotation + if (Data.ucFlags & 0x01) + BitStream.Write(&Data.position); - if (Data.ucFlags & 0x02) - BitStream.Write(Data.rotation.data.fRotation); + if (Data.ucFlags & 0x02) + BitStream.Write(&Data.rotation); - // Velocity - if (Data.ucFlags & 0x04) - { - BitStream.Write(Data.velocity.data.vecVelocity.fX); - BitStream.Write(Data.velocity.data.vecVelocity.fY); - BitStream.Write(Data.velocity.data.vecVelocity.fZ); - } - } + // Velocity + if (Data.ucFlags & 0x04) + BitStream.Write(&Data.velocity); // Health, armour, on fire and is in water if (Data.ucFlags & 0x08) @@ -169,7 +138,7 @@ bool CPedSyncPacket::Write(NetBitStreamInterface& BitStream) const if (Data.ucFlags & 0x20) BitStream.WriteBit(Data.bOnFire); - if (Data.ucFlags & 0x60 && BitStream.Can(eBitStreamVersion::IsPedReloadingWeapon)) + if (Data.ucFlags & 0x60) BitStream.Write(Data.isReloadingWeapon); if (Data.ucFlags & 0x40) BitStream.Write(Data.bIsInWater); @@ -181,21 +150,21 @@ bool CPedSyncPacket::SyncData::ReadSpatialData(NetBitStreamInterface& BitStream) { // Did we recieve position? if (ucFlags & 0x01) - { + { if (!BitStream.Read(&position)) return false; } // Rotation if (ucFlags & 0x02) - { + { if (!BitStream.Read(&rotation)) return false; } // Velocity if (ucFlags & 0x04) - { + { if (!BitStream.Read(&velocity)) return false; } diff --git a/Server/mods/deathmatch/logic/packets/CPedSyncPacket.h b/Server/mods/deathmatch/logic/packets/CPedSyncPacket.h index 00824233f94..9513619b663 100644 --- a/Server/mods/deathmatch/logic/packets/CPedSyncPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPedSyncPacket.h @@ -21,19 +21,19 @@ class CPedSyncPacket final : public CPacket public: struct SyncData { - ElementID ID; - unsigned char ucFlags; - std::uint8_t flags2; - unsigned char ucSyncTimeContext; - SPositionSync position; - SPedRotationSync rotation; - SVelocitySync velocity; - float fHealth; - float fArmor; - bool bOnFire; - bool bIsInWater; - bool isReloadingWeapon; - float cameraRotation; + ElementID ID; + unsigned char ucFlags; + std::uint8_t flags2; + unsigned char ucSyncTimeContext; + SPositionSync position; + SPedRotationSync rotation; + SVelocitySync velocity; + float fHealth; + float fArmor; + bool bOnFire; + bool bIsInWater; + bool isReloadingWeapon; + float cameraRotation; bool ReadSpatialData(NetBitStreamInterface& BitStream); // Backward compatibility @@ -42,7 +42,7 @@ class CPedSyncPacket final : public CPacket public: // Used when receiving ped sync from clients, can contain multiple SyncData - CPedSyncPacket(){}; + CPedSyncPacket() {}; // Used when sending ped sync to clients, only contains one SyncData CPedSyncPacket(SyncData& pReadData); diff --git a/Server/mods/deathmatch/logic/packets/CPedWastedPacket.cpp b/Server/mods/deathmatch/logic/packets/CPedWastedPacket.cpp index ff77caa82d8..05a1e99be43 100644 --- a/Server/mods/deathmatch/logic/packets/CPedWastedPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPedWastedPacket.cpp @@ -49,7 +49,10 @@ bool CPedWastedPacket::Read(NetBitStreamInterface& BitStream) BitStream.Read(&bodyPart) && BitStream.Read(&pos) && BitStream.Read(m_PedID)) { m_ucKillerWeapon = weapon.data.ucWeaponType; - m_ucBodyPart = bodyPart.data.uiBodypart; + if (bodyPart.data.uiBodypart > 0xFF) + return false; + + m_ucBodyPart = static_cast(bodyPart.data.uiBodypart); m_vecPosition = pos.data.vecPosition; SWeaponAmmoSync ammo(m_ucKillerWeapon, true, false); diff --git a/Server/mods/deathmatch/logic/packets/CPlayerACInfoPacket.h b/Server/mods/deathmatch/logic/packets/CPlayerACInfoPacket.h index b485f8b5e4a..af5b0e8e26b 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerACInfoPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPlayerACInfoPacket.h @@ -17,7 +17,7 @@ class CPlayerACInfoPacket final : public CPacket { public: ePacketID GetPacketID() const { return PACKET_ID_PLAYER_ACINFO; }; - unsigned long GetFlags() const { return 0; }; // Not used + unsigned long GetFlags() const { return 0; }; // Not used bool Read(NetBitStreamInterface& BitStream); diff --git a/Server/mods/deathmatch/logic/packets/CPlayerClothesPacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerClothesPacket.cpp index 3cf103baeff..5ea2d6260d6 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerClothesPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPlayerClothesPacket.cpp @@ -18,8 +18,8 @@ CPlayerClothesPacket::~CPlayerClothesPacket() std::vector::iterator iter = m_List.begin(); for (; iter != m_List.end(); ++iter) { - delete[](*iter)->szTexture; - delete[](*iter)->szModel; + delete[] (*iter)->szTexture; + delete[] (*iter)->szModel; delete *iter; } m_List.clear(); diff --git a/Server/mods/deathmatch/logic/packets/CPlayerDiagnosticPacket.h b/Server/mods/deathmatch/logic/packets/CPlayerDiagnosticPacket.h index d985f73e0db..623b9ba0d78 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerDiagnosticPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPlayerDiagnosticPacket.h @@ -17,7 +17,7 @@ class CPlayerDiagnosticPacket final : public CPacket { public: ePacketID GetPacketID() const { return PACKET_ID_PLAYER_DIAGNOSTIC; }; - unsigned long GetFlags() const { return 0; }; // Not used + unsigned long GetFlags() const { return 0; }; // Not used bool Read(NetBitStreamInterface& BitStream); diff --git a/Server/mods/deathmatch/logic/packets/CPlayerJoinCompletePacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerJoinCompletePacket.cpp index 3e9ec7eed25..e4c821532b6 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerJoinCompletePacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPlayerJoinCompletePacket.cpp @@ -90,10 +90,7 @@ bool CPlayerJoinCompletePacket::Write(NetBitStreamInterface& BitStream) const BitStream.WriteCompressed(m_uiBitrate); // fakelag command enabled - if (BitStream.Can(eBitStreamVersion::FakeLagCommand)) - { - BitStream.WriteBit(g_pGame->GetConfig()->IsFakeLagCommandEnabled()); - } + BitStream.WriteBit(g_pGame->GetConfig()->IsFakeLagCommandEnabled()); // Tellclient about maybe throttling back http client requests BitStream.Write(m_iHTTPMaxConnectionsPerClient); @@ -122,8 +119,7 @@ bool CPlayerJoinCompletePacket::Write(NetBitStreamInterface& BitStream) const break; } - if (BitStream.Can(eBitStreamVersion::CPlayerJoinCompletePacket_ServerName)) - BitStream.WriteString(m_szServerName); + BitStream.WriteString(m_szServerName); return true; } diff --git a/Server/mods/deathmatch/logic/packets/CPlayerJoinDataPacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerJoinDataPacket.cpp index c1f1078b66c..5791ad800d9 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerJoinDataPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPlayerJoinDataPacket.cpp @@ -26,13 +26,12 @@ bool CPlayerJoinDataPacket::Read(NetBitStreamInterface& BitStream) m_bOptionalUpdateInfoRequired = BitStream.ReadBit(); if (BitStream.Read(m_ucGameVersion) && BitStream.ReadStringCharacters(m_strNick, MAX_PLAYER_NICK_LENGTH) && - BitStream.Read(reinterpret_cast(&m_Password), 16) && BitStream.ReadStringCharacters(m_strSerialUser, MAX_SERIAL_LENGTH)) + BitStream.Read(reinterpret_cast(&m_Password), 16)) { // Shrink string sizes to fit m_strNick = *m_strNick; - m_strSerialUser = *m_strSerialUser; - return true; } + return false; } diff --git a/Server/mods/deathmatch/logic/packets/CPlayerJoinDataPacket.h b/Server/mods/deathmatch/logic/packets/CPlayerJoinDataPacket.h index 02891111e52..78e37b380a5 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerJoinDataPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPlayerJoinDataPacket.h @@ -39,9 +39,6 @@ class CPlayerJoinDataPacket final : public CPacket const MD5& GetPassword() { return m_Password; }; void SetPassword(const MD5& Password) { m_Password = Password; }; - const char* GetSerialUser() { return m_strSerialUser; } - void SetSerialUser(const char* szSerialUser) { m_strSerialUser.AssignLeft(szSerialUser, MAX_SERIAL_LENGTH); } - bool IsOptionalUpdateInfoRequired() { return m_bOptionalUpdateInfoRequired; } private: @@ -52,6 +49,5 @@ class CPlayerJoinDataPacket final : public CPacket bool m_bOptionalUpdateInfoRequired; SString m_strNick; MD5 m_Password; - SString m_strSerialUser; CMtaVersion m_strPlayerVersion; }; diff --git a/Server/mods/deathmatch/logic/packets/CPlayerListPacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerListPacket.cpp index d329d290a8e..fd20c1d7fd9 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerListPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPlayerListPacket.cpp @@ -116,16 +116,13 @@ bool CPlayerListPacket::Write(NetBitStreamInterface& BitStream) const } // Version info - if (BitStream.Version() >= 0x34) - { - BitStream.Write(pPlayer->GetBitStreamVersion()); - BitStream.Write(pPlayer->GetPlayerVersion().GetBuildNumber()); - } + BitStream.Write(pPlayer->GetBitStreamVersion()); + BitStream.Write(pPlayer->GetPlayerVersion().GetBuildNumber()); // Flags bool bInVehicle = (pPlayer->GetOccupiedVehicle() != NULL); BitStream.WriteBit(pPlayer->IsDead()); - BitStream.WriteBit(true); // (Was IsSpawned) Used by the client to determine if extra info was sent (in this packet) + BitStream.WriteBit(true); // (Was IsSpawned) Used by the client to determine if extra info was sent (in this packet) BitStream.WriteBit(bInVehicle); BitStream.WriteBit(pPlayer->HasJetPack()); BitStream.WriteBit(pPlayer->IsNametagShowing()); @@ -139,12 +136,6 @@ bool CPlayerListPacket::Write(NetBitStreamInterface& BitStream) const if (szNametagText) ucNametagTextLength = static_cast(strlen(szNametagText)); - if (!BitStream.Can(eBitStreamVersion::UnicodeNametags)) - { - // Old client version has a fixed buffer of 22 characters - ucNametagTextLength = std::min(ucNametagTextLength, 22); - } - BitStream.Write(ucNametagTextLength); if (ucNametagTextLength > 0) BitStream.Write(szNametagText, ucNametagTextLength); @@ -160,11 +151,8 @@ bool CPlayerListPacket::Write(NetBitStreamInterface& BitStream) const } // Move anim - if (BitStream.Version() > 0x4B) - { - uchar ucMoveAnim = pPlayer->GetMoveAnim(); - BitStream.Write(ucMoveAnim); - } + uchar ucMoveAnim = pPlayer->GetMoveAnim(); + BitStream.Write(ucMoveAnim); // Always send extra info (Was: "Write spawn info if he's spawned") if (true) @@ -191,7 +179,10 @@ bool CPlayerListPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(pVehicle->GetID()); SOccupiedSeatSync seat; - seat.data.ucSeat = pPlayer->GetOccupiedVehicleSeat(); + { + const uint uiSeat = pPlayer->GetOccupiedVehicleSeat(); + seat.data.ucSeat = uiSeat <= 0xFF ? static_cast(uiSeat) : 0xFF; + } BitStream.Write(&seat); } else @@ -214,10 +205,10 @@ bool CPlayerListPacket::Write(NetBitStreamInterface& BitStream) const alpha.data.ucAlpha = pPlayer->GetAlpha(); BitStream.Write(&alpha); - BitStream.Write(pPlayer->GetInterior()); + BitStream.Write(static_cast(pPlayer->GetInterior())); // Write the weapons of the player weapon slots - for (unsigned int i = 0; i < 16; ++i) + for (unsigned char i = 0; i < 16; ++i) { CWeapon* pWeapon = pPlayer->GetWeapon(i); if (pWeapon && pWeapon->ucType != 0) @@ -230,6 +221,25 @@ bool CPlayerListPacket::Write(NetBitStreamInterface& BitStream) const else BitStream.WriteBit(false); } + + const SPlayerAnimData& animData = pPlayer->GetAnimationData(); + bool animRuning = animData.IsAnimating(); + + BitStream.WriteBit(animRuning); + if (animRuning) + { + BitStream.WriteString(animData.blockName); + BitStream.WriteString(animData.animName); + BitStream.Write(animData.time); + BitStream.WriteBit(animData.loop); + BitStream.WriteBit(animData.updatePosition); + BitStream.WriteBit(animData.interruptable); + BitStream.WriteBit(animData.freezeLastFrame); + BitStream.Write(animData.blendTime); + BitStream.WriteBit(animData.taskToBeRestoredOnAnimEnd); + BitStream.Write(static_cast(animData.startTime)); + BitStream.Write(animData.speed); + } } } diff --git a/Server/mods/deathmatch/logic/packets/CPlayerModInfoPacket.h b/Server/mods/deathmatch/logic/packets/CPlayerModInfoPacket.h index bcc283d3964..ad1a7faaf44 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerModInfoPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPlayerModInfoPacket.h @@ -34,7 +34,7 @@ class CPlayerModInfoPacket final : public CPacket { public: ePacketID GetPacketID() const { return PACKET_ID_PLAYER_MODINFO; }; - unsigned long GetFlags() const { return 0; }; // Not used + unsigned long GetFlags() const { return 0; }; // Not used bool Read(NetBitStreamInterface& BitStream); diff --git a/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp index 88c53ea8720..cb05c2138f7 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp @@ -35,8 +35,8 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) if (!BitStream.Read(ucTimeContext)) return false; - // Only read this packet if it matches the current time context that - // player is in. + // Only read this packet if it matches the current time context + // Time context is validated for all players (alive and dead) to prevent stale packets if (!pSourcePlayer->CanUpdateSync(ucTimeContext)) { return false; @@ -61,9 +61,12 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) pSourcePlayer->SetAkimboArmUp(flags.data.bAkimboTargetUp); pSourcePlayer->SetOnFire(flags.data.bIsOnFire); pSourcePlayer->SetStealthAiming(flags.data.bStealthAiming); + pSourcePlayer->SetReloadingWeapon(flags.data.isReloadingWeapon); - if (BitStream.Can(eBitStreamVersion::IsPedReloadingWeapon)) - pSourcePlayer->SetReloadingWeapon(flags.data2.isReloadingWeapon); + if (flags.data.animInterrupted) + pSourcePlayer->SetAnimationData({}); + + pSourcePlayer->SetHanging(flags.data.hangingDuringClimb); // Contact element CElement* pContactElement = NULL; @@ -78,6 +81,7 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) // Player position SPositionSync position(false); bool positionRead = BitStream.Read(&position); + const CVector vecRelativePosition = position.data.vecPosition; if (positionRead && pContactElement != nullptr) { @@ -91,9 +95,8 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) break; } - if (radius > -1 && - (!IsPointNearPoint3D(pSourcePlayer->GetPosition(), pContactElement->GetPosition(), radius) || - pSourcePlayer->GetDimension() != pContactElement->GetDimension())) + if (radius > -1 && (!IsPointNearPoint3D(pSourcePlayer->GetPosition(), pContactElement->GetPosition(), static_cast(radius)) || + pSourcePlayer->GetDimension() != pContactElement->GetDimension())) { pContactElement = nullptr; // Use current player position. They are not reporting their absolute position so we have to disregard it. @@ -107,7 +110,7 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) { position.data.vecPosition = pSourcePlayer->GetPosition(); } - + CElement* pPreviousContactElement = pSourcePlayer->GetContactElement(); pSourcePlayer->SetContactElement(pContactElement); @@ -142,7 +145,7 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) // if (position.data.vecPosition.fX != 0.0f || position.data.vecPosition.fY != 0.0f || position.data.vecPosition.fZ != 0.0f) { CVector playerPosition = pSourcePlayer->GetPosition(); - float playerDistancePosition = DistanceBetweenPoints3D(playerPosition, position.data.vecPosition); + float playerDistancePosition = DistanceBetweenPoints3D(playerPosition, position.data.vecPosition); if (playerDistancePosition >= g_TickRateSettings.playerTeleportAlert) { if (!pSourcePlayer->GetTeleported()) @@ -202,7 +205,10 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) // Read the camera orientation CVector vecCamPosition, vecCamFwd; - ReadCameraOrientation(position.data.vecPosition, BitStream, vecCamPosition, vecCamFwd); + // Camera orientation is encoded against the same position basis the client wrote. + CVector vecCameraBasePosition = pContactElement ? vecRelativePosition : position.data.vecPosition; + + ReadCameraOrientation(vecCameraBasePosition, BitStream, vecCamPosition, vecCamFwd); pSourcePlayer->SetCameraOrientation(vecCamPosition, vecCamFwd); if (flags.data.bHasAWeapon) @@ -218,8 +224,8 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) if (pSourcePlayer->GetWeaponType() != ucClientWeaponType) { - bWeaponCorrect = false; // Possibly old weapon data. - ucUseWeaponType = ucClientWeaponType; // Use the packet supplied weapon type to skip over the correct amount of data + bWeaponCorrect = false; // Possibly old weapon data. + ucUseWeaponType = ucClientWeaponType; // Use the packet supplied weapon type to skip over the correct amount of data } // Update check counts @@ -229,11 +235,17 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) SWeaponSlotSync slot; if (!BitStream.Read(&slot)) return false; - unsigned int uiSlot = slot.data.uiSlot; + auto ucSlot = static_cast(slot.data.uiSlot); // Set weapon slot if (bWeaponCorrect) - pSourcePlayer->SetWeaponSlot(uiSlot); + { + const unsigned int uiCurrSlot = slot.data.uiSlot; + if (uiCurrSlot > 0xFF) + return false; + + pSourcePlayer->SetWeaponSlot(static_cast(uiCurrSlot)); + } else { // remove invalid weapon data to prevent this from being relayed to other players @@ -241,14 +253,14 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) slot.data.uiSlot = 0; } - if (CWeaponNames::DoesSlotHaveAmmo(uiSlot)) + if (CWeaponNames::DoesSlotHaveAmmo(ucSlot)) { // Read out the ammo states SWeaponAmmoSync ammo(ucUseWeaponType, true, true); if (!BitStream.Read(&ammo)) return false; - float fWeaponRange = pSourcePlayer->GetWeaponRangeFromSlot(uiSlot); + float fWeaponRange = pSourcePlayer->GetWeaponRangeFromSlot(ucSlot); // Read out the aim data SWeaponAimSync sync(fWeaponRange, (ControllerState.RightShoulder1 || ControllerState.ButtonCircle)); @@ -303,7 +315,7 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) if (!BitStream.Read(&bodyPart)) return false; - pSourcePlayer->SetDamageInfo(DamagerID, weaponType.data.ucWeaponType, bodyPart.data.uiBodypart); + pSourcePlayer->SetDamageInfo(DamagerID, weaponType.data.ucWeaponType, static_cast(bodyPart.data.uiBodypart)); } // If we know the player's dead, make sure the health we send on is 0 @@ -351,7 +363,7 @@ bool CPlayerPuresyncPacket::Write(NetBitStreamInterface& BitStream) const CPlayer* pSourcePlayer = static_cast(m_pSourceElement); ElementID PlayerID = pSourcePlayer->GetID(); - unsigned short usLatency = pSourcePlayer->GetPing(); + unsigned short usLatency = static_cast(pSourcePlayer->GetPing()); const CControllerState& ControllerState = pSourcePlayer->GetPad()->GetCurrentControllerState(); CElement* pContactElement = pSourcePlayer->GetContactElement(); @@ -372,9 +384,8 @@ bool CPlayerPuresyncPacket::Write(NetBitStreamInterface& BitStream) const flags.data.bHasAWeapon = (ucWeaponSlot != 0); flags.data.bSyncingVelocity = (!flags.data.bIsOnGround || pSourcePlayer->IsSyncingVelocity()); flags.data.bStealthAiming = (pSourcePlayer->IsStealthAiming() == true); - - if (pSourcePlayer->CanBitStream(eBitStreamVersion::IsPedReloadingWeapon)) - flags.data2.isReloadingWeapon = pSourcePlayer->IsReloadingWeapon(); + flags.data.isReloadingWeapon = pSourcePlayer->IsReloadingWeapon(); + flags.data.hangingDuringClimb = pSourcePlayer->IsHanging(); CVector vecPosition = pSourcePlayer->GetPosition(); if (pContactElement) diff --git a/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.h b/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.h index ac53d4d773e..04cff3a99c2 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.h @@ -16,7 +16,7 @@ class CPlayerPuresyncPacket final : public CPacket { public: - CPlayerPuresyncPacket(){}; + CPlayerPuresyncPacket() {}; explicit CPlayerPuresyncPacket(CPlayer* pPlayer); bool HasSimHandler() const { return true; } diff --git a/Server/mods/deathmatch/logic/packets/CPlayerResourceStartPacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerResourceStartPacket.cpp index b543b9140c0..c38d9fc1f0a 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerResourceStartPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPlayerResourceStartPacket.cpp @@ -15,8 +15,11 @@ bool CPlayerResourceStartPacket::Read(NetBitStreamInterface& BitStream) { - ushort usResourceNetId; - BitStream.Read(usResourceNetId); + ushort usResourceNetId{}; + + if (!BitStream.Read(usResourceNetId) || !BitStream.Read(m_startCounter)) + return false; + m_pResource = g_pGame->GetResourceManager()->GetResourceFromNetID(usResourceNetId); return true; } diff --git a/Server/mods/deathmatch/logic/packets/CPlayerResourceStartPacket.h b/Server/mods/deathmatch/logic/packets/CPlayerResourceStartPacket.h index 156f09344cf..830f1c93d43 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerResourceStartPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPlayerResourceStartPacket.h @@ -17,16 +17,18 @@ class CResource; class CPlayerResourceStartPacket final : public CPacket { public: - CPlayerResourceStartPacket() {} + CPlayerResourceStartPacket() = default; - ePacketID GetPacketID() const { return PACKET_ID_PLAYER_RESOURCE_START; } - unsigned long GetFlags() const { return PACKET_HIGH_PRIORITY | PACKET_RELIABLE | PACKET_SEQUENCED; }; - virtual ePacketOrdering GetPacketOrdering() const { return PACKET_ORDERING_DEFAULT; } + ePacketID GetPacketID() const override { return PACKET_ID_PLAYER_RESOURCE_START; } + unsigned long GetFlags() const override { return PACKET_HIGH_PRIORITY | PACKET_RELIABLE | PACKET_SEQUENCED; } + ePacketOrdering GetPacketOrdering() const override { return PACKET_ORDERING_DEFAULT; } bool Read(NetBitStreamInterface& BitStream); - CResource* GetResource() const { return m_pResource; } + CResource* GetResource() const noexcept { return m_pResource; } + unsigned int GetStartCounter() const noexcept { return m_startCounter; } private: - CResource* m_pResource; + CResource* m_pResource{}; + unsigned int m_startCounter{}; }; diff --git a/Server/mods/deathmatch/logic/packets/CPlayerScreenShotPacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerScreenShotPacket.cpp index d4a34940a83..e8d4844810f 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerScreenShotPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPlayerScreenShotPacket.cpp @@ -34,24 +34,15 @@ bool CPlayerScreenShotPacket::Read(NetBitStreamInterface& BitStream) // minimized, disabled or error bHasGrabTime = true; BitStream.Read(uiServerGrabTime); - if (BitStream.Version() >= 0x053) - { - ushort usResourceNetId; - BitStream.Read(usResourceNetId); - m_pResource = g_pGame->GetResourceManager()->GetResourceFromNetID(usResourceNetId); - } - else - { - SString strResourceName; - BitStream.ReadString(strResourceName); - m_pResource = g_pGame->GetResourceManager()->GetResource(strResourceName); - } + + ushort usResourceNetId; + BitStream.Read(usResourceNetId); + m_pResource = g_pGame->GetResourceManager()->GetResourceFromNetID(usResourceNetId); if (!BitStream.ReadString(m_strTag)) return false; - if (BitStream.Version() >= 0x53) - BitStream.ReadString(m_strError); + BitStream.ReadString(m_strError); } else if (m_ucStatus == EPlayerScreenShotResult::SUCCESS) { @@ -75,18 +66,11 @@ bool CPlayerScreenShotPacket::Read(NetBitStreamInterface& BitStream) BitStream.Read(uiServerGrabTime); BitStream.Read(m_uiTotalBytes); BitStream.Read(m_usTotalParts); - if (BitStream.Version() >= 0x053) - { - ushort usResourceNetId; - BitStream.Read(usResourceNetId); - m_pResource = g_pGame->GetResourceManager()->GetResourceFromNetID(usResourceNetId); - } - else - { - SString strResourceName; - BitStream.ReadString(strResourceName); - m_pResource = g_pGame->GetResourceManager()->GetResource(strResourceName); - } + + ushort usResourceNetId; + BitStream.Read(usResourceNetId); + m_pResource = g_pGame->GetResourceManager()->GetResourceFromNetID(usResourceNetId); + if (!BitStream.ReadString(m_strTag)) return false; } diff --git a/Server/mods/deathmatch/logic/packets/CPlayerScreenShotPacket.h b/Server/mods/deathmatch/logic/packets/CPlayerScreenShotPacket.h index e73321e7f95..a4715adb94b 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerScreenShotPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPlayerScreenShotPacket.h @@ -19,11 +19,11 @@ class CPlayerScreenShotPacket final : public CPacket { public: ePacketID GetPacketID() const { return PACKET_ID_PLAYER_SCREENSHOT; }; - unsigned long GetFlags() const { return 0; }; // Not used + unsigned long GetFlags() const { return 0; }; // Not used bool Read(NetBitStreamInterface& BitStream); - uchar m_ucStatus; // 1 = has image, 2 = minimized, 3 = disabled, 4 = error + uchar m_ucStatus; // 1 = has image, 2 = minimized, 3 = disabled, 4 = error // With every packet if status is 1 ushort m_usScreenShotId; diff --git a/Server/mods/deathmatch/logic/packets/CPlayerStatsPacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerStatsPacket.cpp index f7b19179725..ac0f8909ebe 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerStatsPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPlayerStatsPacket.cpp @@ -21,7 +21,7 @@ bool CPlayerStatsPacket::Write(NetBitStreamInterface& BitStream) const // Write the source elements's ID BitStream.Write(m_pSourceElement->GetID()); - BitStream.WriteCompressed(static_cast(m_map.size())); // Write stat count + BitStream.WriteCompressed(static_cast(m_map.size())); // Write stat count for (auto&& [statID, value] : m_map) { BitStream.Write(statID); @@ -36,10 +36,10 @@ void CPlayerStatsPacket::Add(unsigned short usID, float fValue) if (auto iter = m_map.find(usID); iter != m_map.end()) { if (fValue == 0.0f) - m_map.erase(iter); // Erase stat + m_map.erase(iter); // Erase stat else - iter->second = fValue; // Update value + iter->second = fValue; // Update value } - else // Not in map + else // Not in map m_map.emplace(usID, fValue); } diff --git a/Server/mods/deathmatch/logic/packets/CPlayerStatsPacket.h b/Server/mods/deathmatch/logic/packets/CPlayerStatsPacket.h index 9398f264541..d8429b06dd7 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerStatsPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPlayerStatsPacket.h @@ -31,5 +31,5 @@ class CPlayerStatsPacket final : public CPacket size_t GetSize() const noexcept { return m_map.size(); } private: - std::map m_map; // id - value pairs + std::map m_map; // id - value pairs }; diff --git a/Server/mods/deathmatch/logic/packets/CPlayerTransgressionPacket.h b/Server/mods/deathmatch/logic/packets/CPlayerTransgressionPacket.h index 7b48d60a8c5..8183c6e3b4e 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerTransgressionPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPlayerTransgressionPacket.h @@ -17,7 +17,7 @@ class CPlayerTransgressionPacket final : public CPacket { public: ePacketID GetPacketID() const { return PACKET_ID_PLAYER_TRANSGRESSION; }; - unsigned long GetFlags() const { return 0; }; // Not used + unsigned long GetFlags() const { return 0; }; // Not used bool Read(NetBitStreamInterface& BitStream); diff --git a/Server/mods/deathmatch/logic/packets/CPlayerWastedPacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerWastedPacket.cpp index 6a9d26ad4c4..541d0899808 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerWastedPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPlayerWastedPacket.cpp @@ -52,7 +52,10 @@ bool CPlayerWastedPacket::Read(NetBitStreamInterface& BitStream) if (BitStream.Read(&ammo)) { m_vecPosition = pos.data.vecPosition; - m_ucBodyPart = bodyPart.data.uiBodypart; + if (bodyPart.data.uiBodypart > 0xFF) + return false; + + m_ucBodyPart = static_cast(bodyPart.data.uiBodypart); m_ucKillerWeapon = weapon.data.ucWeaponType; m_usAmmo = ammo.data.usTotalAmmo; return true; diff --git a/Server/mods/deathmatch/logic/packets/CProjectileSyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CProjectileSyncPacket.cpp index 1e369b2d8d1..8387f6ed699 100644 --- a/Server/mods/deathmatch/logic/packets/CProjectileSyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CProjectileSyncPacket.cpp @@ -44,10 +44,10 @@ bool CProjectileSyncPacket::Read(NetBitStreamInterface& BitStream) switch (m_ucWeaponType) { - case 16: // WEAPONTYPE_GRENADE - case 17: // WEAPONTYPE_TEARGAS - case 18: // WEAPONTYPE_MOLOTOV - case 39: // WEAPONTYPE_REMOTE_SATCHEL_CHARGE + case 16: // WEAPONTYPE_GRENADE + case 17: // WEAPONTYPE_TEARGAS + case 18: // WEAPONTYPE_MOLOTOV + case 39: // WEAPONTYPE_REMOTE_SATCHEL_CHARGE { SFloatSync<7, 17> projectileForce; if (!BitStream.Read(&projectileForce)) @@ -61,8 +61,8 @@ bool CProjectileSyncPacket::Read(NetBitStreamInterface& BitStream) break; } - case 19: // WEAPONTYPE_ROCKET - case 20: // WEAPONTYPE_ROCKET_HS + case 19: // WEAPONTYPE_ROCKET + case 20: // WEAPONTYPE_ROCKET_HS { if (!BitStream.ReadBit(m_bHasTarget)) return false; @@ -83,8 +83,8 @@ bool CProjectileSyncPacket::Read(NetBitStreamInterface& BitStream) break; } - case 58: // WEAPONTYPE_FLARE - case 21: // WEAPONTYPE_FREEFALL_BOMB + case 58: // WEAPONTYPE_FLARE + case 21: // WEAPONTYPE_FREEFALL_BOMB break; default: @@ -101,7 +101,8 @@ bool CProjectileSyncPacket::Write(NetBitStreamInterface& BitStream) const BitStream.WriteBit(true); BitStream.Write(m_pSourceElement->GetID()); - unsigned short usLatency = static_cast(m_pSourceElement)->GetPing(); + const unsigned int uiPing = static_cast(m_pSourceElement)->GetPing(); + const unsigned short usLatency = uiPing <= 0xFFFF ? static_cast(uiPing) : 0xFFFF; BitStream.WriteCompressed(usLatency); } else @@ -127,10 +128,10 @@ bool CProjectileSyncPacket::Write(NetBitStreamInterface& BitStream) const switch (m_ucWeaponType) { - case 16: // WEAPONTYPE_GRENADE - case 17: // WEAPONTYPE_TEARGAS - case 18: // WEAPONTYPE_MOLOTOV - case 39: // WEAPONTYPE_REMOTE_SATCHEL_CHARGE + case 16: // WEAPONTYPE_GRENADE + case 17: // WEAPONTYPE_TEARGAS + case 18: // WEAPONTYPE_MOLOTOV + case 39: // WEAPONTYPE_REMOTE_SATCHEL_CHARGE { SFloatSync<7, 17> projectileForce; projectileForce.data.fValue = m_fForce; @@ -142,8 +143,8 @@ bool CProjectileSyncPacket::Write(NetBitStreamInterface& BitStream) const break; } - case 19: // WEAPONTYPE_ROCKET - case 20: // WEAPONTYPE_ROCKET_HS + case 19: // WEAPONTYPE_ROCKET + case 20: // WEAPONTYPE_ROCKET_HS { if (m_TargetID != INVALID_ELEMENT_ID) { @@ -163,7 +164,7 @@ bool CProjectileSyncPacket::Write(NetBitStreamInterface& BitStream) const break; } - case 58: // WEAPONTYPE_FLARE + case 58: // WEAPONTYPE_FLARE break; } diff --git a/Server/mods/deathmatch/logic/packets/CResourceClientScriptsPacket.cpp b/Server/mods/deathmatch/logic/packets/CResourceClientScriptsPacket.cpp index 8968df0da69..ba9b62a8641 100644 --- a/Server/mods/deathmatch/logic/packets/CResourceClientScriptsPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CResourceClientScriptsPacket.cpp @@ -33,8 +33,7 @@ bool CResourceClientScriptsPacket::Write(NetBitStreamInterface& BitStream) const for (std::vector::const_iterator iter = m_vecItems.begin(); iter != m_vecItems.end(); ++iter) { - if (BitStream.Version() >= 0x50) - BitStream.WriteString(ConformResourcePath((*iter)->GetFullName())); + BitStream.WriteString(ConformResourcePath((*iter)->GetFullName())); const SString& data = (*iter)->GetSourceCode(); unsigned int len = data.length(); diff --git a/Server/mods/deathmatch/logic/packets/CResourceStartPacket.cpp b/Server/mods/deathmatch/logic/packets/CResourceStartPacket.cpp index 264cbe07049..6f518ca4ebf 100644 --- a/Server/mods/deathmatch/logic/packets/CResourceStartPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CResourceStartPacket.cpp @@ -18,137 +18,125 @@ #include "CResource.h" #include "CDummy.h" -CResourceStartPacket::CResourceStartPacket(const char* szResourceName, CResource* pResource) +CResourceStartPacket::CResourceStartPacket(const std::string& resourceName, CResource* resource, unsigned int startCounter) + : m_strResourceName{resourceName}, m_pResource{resource}, m_startCounter{startCounter} { - m_strResourceName = szResourceName; - m_pResource = pResource; } bool CResourceStartPacket::Write(NetBitStreamInterface& BitStream) const { - if (!m_strResourceName.empty()) + if (m_strResourceName.empty()) + return false; + + // Write the resource name + unsigned char sizeResourceName = static_cast(m_strResourceName.size()); + BitStream.Write(sizeResourceName); + if (sizeResourceName > 0) { - // Write the resource name - unsigned char sizeResourceName = static_cast(m_strResourceName.size()); - BitStream.Write(sizeResourceName); - if (sizeResourceName > 0) - { - BitStream.Write(m_strResourceName.c_str(), sizeResourceName); - } + BitStream.Write(m_strResourceName.c_str(), sizeResourceName); + } - // Write the resource id - BitStream.Write(m_pResource->GetNetID()); + // Write the start counter + BitStream.Write(m_startCounter); - // Write the resource element id - BitStream.Write(m_pResource->GetResourceRootElement()->GetID()); + // Write the resource id + BitStream.Write(m_pResource->GetNetID()); - // Write the resource dynamic element id - BitStream.Write(m_pResource->GetDynamicElementRoot()->GetID()); + // Write the resource element id + BitStream.Write(m_pResource->GetResourceRootElement()->GetID()); - // Count the amount of 'no client cache' scripts - unsigned short usNoClientCacheScriptCount = 0; - if (m_pResource->IsClientScriptsOn() == true) + // Write the resource dynamic element id + BitStream.Write(m_pResource->GetDynamicElementRoot()->GetID()); + + // Count the amount of 'no client cache' scripts + unsigned short usNoClientCacheScriptCount = 0; + if (m_pResource->IsClientScriptsOn()) + { + for (CResourceFile* resourceFile : m_pResource->GetFiles()) { - std::list::iterator iter = m_pResource->IterBegin(); - for (; iter != m_pResource->IterEnd(); ++iter) + if (resourceFile->GetType() == CResourceScriptItem::RESOURCE_FILE_TYPE_CLIENT_SCRIPT && + static_cast(resourceFile)->IsNoClientCache()) { - if ((*iter)->GetType() == CResourceScriptItem::RESOURCE_FILE_TYPE_CLIENT_SCRIPT && - static_cast(*iter)->IsNoClientCache() == true) - { - ++usNoClientCacheScriptCount; - } + ++usNoClientCacheScriptCount; } } - BitStream.Write(usNoClientCacheScriptCount); + } + BitStream.Write(usNoClientCacheScriptCount); - // Write the declared min client version for this resource - if (BitStream.Version() >= 0x32) - { - BitStream.WriteString(m_pResource->GetMinServerRequirement()); - BitStream.WriteString(m_pResource->GetMinClientRequirement()); - } - if (BitStream.Version() >= 0x45) - { - BitStream.WriteBit(m_pResource->IsOOPEnabledInMetaXml()); - } + // Write the declared min client version for this resource + BitStream.WriteString(m_pResource->GetMinServerRequirement()); + BitStream.WriteString(m_pResource->GetMinClientRequirement()); + BitStream.WriteBit(m_pResource->IsOOPEnabledInMetaXml()); + BitStream.Write(m_pResource->GetDownloadPriorityGroup()); - if (BitStream.Version() >= 0x62) + // Send the resource files info + for (CResourceFile* resourceFile : m_pResource->GetFiles()) + { + if ((resourceFile->GetType() == CResourceScriptItem::RESOURCE_FILE_TYPE_CLIENT_CONFIG && m_pResource->IsClientConfigsOn()) || + (resourceFile->GetType() == CResourceScriptItem::RESOURCE_FILE_TYPE_CLIENT_SCRIPT && m_pResource->IsClientScriptsOn() && + static_cast(resourceFile)->IsNoClientCache() == false) || + (resourceFile->GetType() == CResourceScriptItem::RESOURCE_FILE_TYPE_CLIENT_FILE && m_pResource->IsClientFilesOn())) { - BitStream.Write(m_pResource->GetDownloadPriorityGroup()); - } + // Write the Type of chunk to read (F - File, E - Exported Function) + BitStream.Write(static_cast('F')); - // Send the resource files info - std::list::iterator iter = m_pResource->IterBegin(); - for (; iter != m_pResource->IterEnd(); iter++) - { - if (((*iter)->GetType() == CResourceScriptItem::RESOURCE_FILE_TYPE_CLIENT_CONFIG && m_pResource->IsClientConfigsOn()) || - ((*iter)->GetType() == CResourceScriptItem::RESOURCE_FILE_TYPE_CLIENT_SCRIPT && m_pResource->IsClientScriptsOn() && - static_cast(*iter)->IsNoClientCache() == false) || - ((*iter)->GetType() == CResourceScriptItem::RESOURCE_FILE_TYPE_CLIENT_FILE && m_pResource->IsClientFilesOn())) + // Write the map name + const char* szFileName = resourceFile->GetWindowsName(); + size_t sizeFileName = strlen(szFileName); + + // Make sure we don't have any backslashes in the name + char* szCleanedFilename = new char[sizeFileName + 1]; + strcpy(szCleanedFilename, szFileName); + for (unsigned int i = 0; i < sizeFileName; i++) + { + if (szCleanedFilename[i] == '\\') + szCleanedFilename[i] = '/'; + } + + BitStream.Write(static_cast(sizeFileName)); + if (sizeFileName > 0) { - // Write the Type of chunk to read (F - File, E - Exported Function) - BitStream.Write(static_cast('F')); - - // Write the map name - const char* szFileName = (*iter)->GetWindowsName(); - size_t sizeFileName = strlen(szFileName); - - // Make sure we don't have any backslashes in the name - char* szCleanedFilename = new char[sizeFileName + 1]; - strcpy(szCleanedFilename, szFileName); - for (unsigned int i = 0; i < sizeFileName; i++) - { - if (szCleanedFilename[i] == '\\') - szCleanedFilename[i] = '/'; - } - - BitStream.Write(static_cast(sizeFileName)); - if (sizeFileName > 0) - { - BitStream.Write(szCleanedFilename, sizeFileName); - } - - // ChrML: Don't forget this... - delete[] szCleanedFilename; - - BitStream.Write(static_cast((*iter)->GetType())); - CChecksum checksum = (*iter)->GetLastChecksum(); - BitStream.Write(checksum.ulCRC); - BitStream.Write((const char*)checksum.md5.data, sizeof(checksum.md5.data)); - BitStream.Write((double)(*iter)->GetSizeHint()); // Has to be double for bitstream format compatibility - if ((*iter)->GetType() == CResourceScriptItem::RESOURCE_FILE_TYPE_CLIENT_FILE) - { - CResourceClientFileItem* pRCFItem = reinterpret_cast(*iter); - // write bool whether to download or not - BitStream.WriteBit(pRCFItem->IsAutoDownload()); - } + BitStream.Write(szCleanedFilename, sizeFileName); + } + + // ChrML: Don't forget this... + delete[] szCleanedFilename; + + BitStream.Write(static_cast(resourceFile->GetType())); + CChecksum checksum = resourceFile->GetLastChecksum(); + BitStream.Write(checksum.ulCRC); + BitStream.Write((const char*)checksum.md5.data, sizeof(checksum.md5.data)); + BitStream.Write((double)resourceFile->GetSizeHint()); // Has to be double for bitstream format compatibility + if (resourceFile->GetType() == CResourceScriptItem::RESOURCE_FILE_TYPE_CLIENT_FILE) + { + CResourceClientFileItem* pRCFItem = reinterpret_cast(resourceFile); + // write bool whether to download or not + BitStream.WriteBit(pRCFItem->IsAutoDownload()); } } + } - // Loop through the exported functions - std::list::iterator iterExportedFunction = m_pResource->IterBeginExportedFunctions(); - for (; iterExportedFunction != m_pResource->IterEndExportedFunctions(); iterExportedFunction++) + // Loop through the exported functions + std::list::iterator iterExportedFunction = m_pResource->IterBeginExportedFunctions(); + for (; iterExportedFunction != m_pResource->IterEndExportedFunctions(); iterExportedFunction++) + { + // Check to see if the exported function is 'client' + if (iterExportedFunction->GetType() == CExportedFunction::EXPORTED_FUNCTION_TYPE_CLIENT) { - // Check to see if the exported function is 'client' - if (iterExportedFunction->GetType() == CExportedFunction::EXPORTED_FUNCTION_TYPE_CLIENT) + // Write the Type of chunk to read (F - File, E - Exported Function) + BitStream.Write(static_cast('E')); + + // Write the exported function + std::string strFunctionName = iterExportedFunction->GetFunctionName(); + size_t sizeFunctionName = strFunctionName.length(); + + BitStream.Write(static_cast(sizeFunctionName)); + if (sizeFunctionName > 0) { - // Write the Type of chunk to read (F - File, E - Exported Function) - BitStream.Write(static_cast('E')); - - // Write the exported function - std::string strFunctionName = iterExportedFunction->GetFunctionName(); - size_t sizeFunctionName = strFunctionName.length(); - - BitStream.Write(static_cast(sizeFunctionName)); - if (sizeFunctionName > 0) - { - BitStream.Write(strFunctionName.c_str(), sizeFunctionName); - } + BitStream.Write(strFunctionName.c_str(), sizeFunctionName); } } - - return true; } - return false; + return true; } diff --git a/Server/mods/deathmatch/logic/packets/CResourceStartPacket.h b/Server/mods/deathmatch/logic/packets/CResourceStartPacket.h index ad50562d434..1550962565e 100644 --- a/Server/mods/deathmatch/logic/packets/CResourceStartPacket.h +++ b/Server/mods/deathmatch/logic/packets/CResourceStartPacket.h @@ -1,6 +1,6 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: mods/deathmatch/logic/packets/CResourceStartPacket.h * PURPOSE: Resource start packet class @@ -12,19 +12,22 @@ #pragma once #include "CPacket.h" -#include +#include + +class CResource; class CResourceStartPacket final : public CPacket { public: - CResourceStartPacket(const char* szResourceName, class CResource* pResource); + CResourceStartPacket(const std::string& resourceName, CResource* resource, unsigned int startCounter); - ePacketID GetPacketID() const { return PACKET_ID_RESOURCE_START; }; - unsigned long GetFlags() const { return PACKET_HIGH_PRIORITY | PACKET_RELIABLE | PACKET_SEQUENCED; }; + ePacketID GetPacketID() const override { return PACKET_ID_RESOURCE_START; } + unsigned long GetFlags() const override { return PACKET_HIGH_PRIORITY | PACKET_RELIABLE | PACKET_SEQUENCED; } - bool Write(NetBitStreamInterface& BitStream) const; + bool Write(NetBitStreamInterface& BitStream) const override; private: - std::string m_strResourceName; - CResource* m_pResource; + std::string m_strResourceName; + CResource* m_pResource{}; + unsigned int m_startCounter{}; }; diff --git a/Server/mods/deathmatch/logic/packets/CServerInfoSyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CServerInfoSyncPacket.cpp index 2e298371073..cfde9f6739d 100644 --- a/Server/mods/deathmatch/logic/packets/CServerInfoSyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CServerInfoSyncPacket.cpp @@ -14,14 +14,14 @@ bool CServerInfoSyncPacket::Write(NetBitStreamInterface& BitStream) const { - if (m_ActualInfo) // Flag is set + if (m_ActualInfo) // Flag is set { BitStream.Write(m_ActualInfo); // Check the flags one by one & write in order if (maxPlayers) - BitStream.Write(static_cast( - CStaticFunctionDefinitions::GetMaxPlayers())); // static_cast ensures the type is uint in case it's changed in future + BitStream.Write( + static_cast(CStaticFunctionDefinitions::GetMaxPlayers())); // static_cast ensures the type is uint in case it's changed in future // other info diff --git a/Server/mods/deathmatch/logic/packets/CServerInfoSyncPacket.h b/Server/mods/deathmatch/logic/packets/CServerInfoSyncPacket.h index bb6d9fcfb4a..2b16a121338 100644 --- a/Server/mods/deathmatch/logic/packets/CServerInfoSyncPacket.h +++ b/Server/mods/deathmatch/logic/packets/CServerInfoSyncPacket.h @@ -14,9 +14,9 @@ enum EServerInfoSyncFlag : uint8 { - SERVER_INFO_FLAG_ALL = 0xFF, // 0b11111111 - SERVER_INFO_FLAG_MAX_PLAYERS = 1, // 0b00000001 - SERVER_INFO_FLAG_RESERVED = 1 << 1 // 0b00000010 and so on + SERVER_INFO_FLAG_ALL = 0xFF, // 0b11111111 + SERVER_INFO_FLAG_MAX_PLAYERS = 1, // 0b00000001 + SERVER_INFO_FLAG_RESERVED = 1 << 1 // 0b00000010 and so on }; class CServerInfoSyncPacket final : public CPacket @@ -37,7 +37,7 @@ class CServerInfoSyncPacket final : public CPacket struct { bool maxPlayers : 1; - bool reserved : 7; // for future? + bool reserved : 7; // for future? }; }; }; diff --git a/Server/mods/deathmatch/logic/packets/CSyncSettingsPacket.cpp b/Server/mods/deathmatch/logic/packets/CSyncSettingsPacket.cpp index 5c1ea2be6c1..55886337c0a 100644 --- a/Server/mods/deathmatch/logic/packets/CSyncSettingsPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CSyncSettingsPacket.cpp @@ -15,7 +15,7 @@ CSyncSettingsPacket::CSyncSettingsPacket(const std::set& weaponTypesUsingBulletSync, uchar ucVehExtrapolateEnabled, short sVehExtrapolateBaseMs, short sVehExtrapolatePercent, short sVehExtrapolateMaxMs, uchar ucUseAltPulseOrder, uchar ucAllowFastSprintFix, - uchar ucAllowDrivebyAnimationFix, uchar ucAllowShotgunDamageFix) + uchar ucAllowDrivebyAnimationFix, uchar ucAllowShotgunDamageFix, std::uint8_t multiCommandHandlerPolicy) { m_weaponTypesUsingBulletSync = weaponTypesUsingBulletSync; m_ucVehExtrapolateEnabled = ucVehExtrapolateEnabled; @@ -26,6 +26,7 @@ CSyncSettingsPacket::CSyncSettingsPacket(const std::set& weaponType m_ucAllowFastSprintFix = ucAllowFastSprintFix; m_ucAllowDrivebyAnimationFix = ucAllowDrivebyAnimationFix; m_ucAllowShotgunDamageFix = ucAllowShotgunDamageFix; + m_multiCommandHandlerPolicy = multiCommandHandlerPolicy; } bool CSyncSettingsPacket::Read(NetBitStreamInterface& BitStream) @@ -43,33 +44,15 @@ bool CSyncSettingsPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write((uchar)*iter); } - if (BitStream.Version() >= 0x35) - { - BitStream.Write(m_ucVehExtrapolateEnabled); - BitStream.Write(m_sVehExtrapolateBaseMs); - BitStream.Write(m_sVehExtrapolatePercent); - BitStream.Write(m_sVehExtrapolateMaxMs); - } - - if (BitStream.Version() >= 0x3D) - { - BitStream.Write(m_ucUseAltPulseOrder); - } - - if (BitStream.Version() >= 0x58) - { - BitStream.Write(m_ucAllowFastSprintFix); - } - - if (BitStream.Version() >= 0x59) - { - BitStream.Write(m_ucAllowDrivebyAnimationFix); - } - - if (BitStream.Can(eBitStreamVersion::ShotgunDamageFix)) - { - BitStream.Write(m_ucAllowShotgunDamageFix); - } + BitStream.Write(m_ucVehExtrapolateEnabled); + BitStream.Write(m_sVehExtrapolateBaseMs); + BitStream.Write(m_sVehExtrapolatePercent); + BitStream.Write(m_sVehExtrapolateMaxMs); + BitStream.Write(m_ucUseAltPulseOrder); + BitStream.Write(m_ucAllowFastSprintFix); + BitStream.Write(m_ucAllowDrivebyAnimationFix); + BitStream.Write(m_ucAllowShotgunDamageFix); + BitStream.Write(m_multiCommandHandlerPolicy); return true; } diff --git a/Server/mods/deathmatch/logic/packets/CSyncSettingsPacket.h b/Server/mods/deathmatch/logic/packets/CSyncSettingsPacket.h index b4c22df18f1..0c70154fa60 100644 --- a/Server/mods/deathmatch/logic/packets/CSyncSettingsPacket.h +++ b/Server/mods/deathmatch/logic/packets/CSyncSettingsPacket.h @@ -16,10 +16,10 @@ class CSyncSettingsPacket final : public CPacket { public: - CSyncSettingsPacket(){}; + CSyncSettingsPacket() {}; CSyncSettingsPacket(const std::set& weaponTypesUsingBulletSync, uchar ucVehExtrapolateEnabled, short sVehExtrapolateBaseMs, short sVehExtrapolatePercent, short sVehExtrapolateMaxMs, uchar ucUseAltPulseOrder, uchar ucAllowFastSprintFix, - uchar ucAllowDrivebyAnimationFix, uchar ucAllowShotgunDamageFix); + uchar ucAllowDrivebyAnimationFix, uchar ucAllowShotgunDamageFix, std::uint8_t multiCommandHandlerPolicy); ePacketID GetPacketID() const { return PACKET_ID_SYNC_SETTINGS; }; unsigned long GetFlags() const { return PACKET_HIGH_PRIORITY | PACKET_RELIABLE | PACKET_SEQUENCED; }; @@ -36,4 +36,5 @@ class CSyncSettingsPacket final : public CPacket uchar m_ucAllowFastSprintFix; uchar m_ucAllowDrivebyAnimationFix; uchar m_ucAllowShotgunDamageFix; + std::uint8_t m_multiCommandHandlerPolicy; }; diff --git a/Server/mods/deathmatch/logic/packets/CUnoccupiedVehiclePushPacket.h b/Server/mods/deathmatch/logic/packets/CUnoccupiedVehiclePushPacket.h index 5c6aa90d47b..1d7efad9f0d 100644 --- a/Server/mods/deathmatch/logic/packets/CUnoccupiedVehiclePushPacket.h +++ b/Server/mods/deathmatch/logic/packets/CUnoccupiedVehiclePushPacket.h @@ -19,10 +19,10 @@ class CVehicle; class CUnoccupiedVehiclePushPacket final : public CPacket { public: - CUnoccupiedVehiclePushPacket(){}; + CUnoccupiedVehiclePushPacket() {}; ePacketID GetPacketID() const { return PACKET_ID_VEHICLE_PUSH_SYNC; }; - unsigned long GetFlags() const { return 0; }; // Not used + unsigned long GetFlags() const { return 0; }; // Not used bool Read(NetBitStreamInterface& BitStream); diff --git a/Server/mods/deathmatch/logic/packets/CUnoccupiedVehicleSyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CUnoccupiedVehicleSyncPacket.cpp index 3f9369f56e9..7a51d7cb192 100644 --- a/Server/mods/deathmatch/logic/packets/CUnoccupiedVehicleSyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CUnoccupiedVehicleSyncPacket.cpp @@ -27,7 +27,7 @@ bool CUnoccupiedVehicleSyncPacket::Read(NetBitStreamInterface& BitStream) { if (i > uiMaxCount) { - CLogger::LogPrintf("WARN: Received excess unoccupied vehicle sync data (%d bytes)", BitStream.GetNumberOfUnreadBits() / 8); + CLogger::LogPrintf("WARN: Received excess unoccupied vehicle sync data (%d bytes)\n", BitStream.GetNumberOfUnreadBits() / 8); break; } diff --git a/Server/mods/deathmatch/logic/packets/CUnoccupiedVehicleSyncPacket.h b/Server/mods/deathmatch/logic/packets/CUnoccupiedVehicleSyncPacket.h index 380faae7ef7..e07e33c1da5 100644 --- a/Server/mods/deathmatch/logic/packets/CUnoccupiedVehicleSyncPacket.h +++ b/Server/mods/deathmatch/logic/packets/CUnoccupiedVehicleSyncPacket.h @@ -26,7 +26,7 @@ class CUnoccupiedVehicleSyncPacket final : public CPacket }; public: - CUnoccupiedVehicleSyncPacket(){}; + CUnoccupiedVehicleSyncPacket() {}; ~CUnoccupiedVehicleSyncPacket(); ePacketID GetPacketID() const { return PACKET_ID_UNOCCUPIED_VEHICLE_SYNC; }; diff --git a/Server/mods/deathmatch/logic/packets/CVehicleInOutPacket.cpp b/Server/mods/deathmatch/logic/packets/CVehicleInOutPacket.cpp index b88fa9fd203..03b2e228885 100644 --- a/Server/mods/deathmatch/logic/packets/CVehicleInOutPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CVehicleInOutPacket.cpp @@ -76,17 +76,10 @@ CVehicleInOutPacket::~CVehicleInOutPacket() bool CVehicleInOutPacket::Read(NetBitStreamInterface& BitStream) { m_PedID = INVALID_ELEMENT_ID; - if (BitStream.Can(eBitStreamVersion::PedEnterExit)) + BitStream.Read(m_PedID); + if (m_PedID == INVALID_ELEMENT_ID) { - BitStream.Read(m_PedID); - if (m_PedID == INVALID_ELEMENT_ID) - { - return false; - } - } - else - { - m_PedID = GetSourcePlayer()->GetID(); + return false; } // Read out the vehicle id diff --git a/Server/mods/deathmatch/logic/packets/CVehicleInOutPacket.h b/Server/mods/deathmatch/logic/packets/CVehicleInOutPacket.h index 2e034208efb..bdffb4bdb7a 100644 --- a/Server/mods/deathmatch/logic/packets/CVehicleInOutPacket.h +++ b/Server/mods/deathmatch/logic/packets/CVehicleInOutPacket.h @@ -52,16 +52,16 @@ class CVehicleInOutPacket final : public CPacket void SetCorrectVector(const CVector& vector) { m_pCorrectVector = new CVector(vector.fX, vector.fY, vector.fZ); } private: - ElementID m_PedID; // The ped - ElementID m_VehicleID; // The vehicle - unsigned char m_ucSeat; // The seat - unsigned char m_ucAction; // The action, see CGame.h - ElementID m_PedIn; // The ped jacking - ElementID m_PedOut; // The ped getting jacked - unsigned char m_ucStartedJacking; // 1 = client reports he started jacking - unsigned char m_ucFailReason; // eFailReasons - CVector* m_pCorrectVector; // Ped position reported by client - bool m_bOnWater; // Vehicle in water reported by client - unsigned char m_ucDoor; // Door ID - float m_fDoorAngle; // Door angle + ElementID m_PedID; // The ped + ElementID m_VehicleID; // The vehicle + unsigned char m_ucSeat; // The seat + unsigned char m_ucAction; // The action, see CGame.h + ElementID m_PedIn; // The ped jacking + ElementID m_PedOut; // The ped getting jacked + unsigned char m_ucStartedJacking; // 1 = client reports he started jacking + unsigned char m_ucFailReason; // eFailReasons + CVector* m_pCorrectVector; // Ped position reported by client + bool m_bOnWater; // Vehicle in water reported by client + unsigned char m_ucDoor; // Door ID + float m_fDoorAngle; // Door angle }; diff --git a/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp index 0d33be5f4ca..096f60b57f6 100644 --- a/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp @@ -58,14 +58,11 @@ bool CVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) return false; // Read out the remote model - int iModelID = pVehicle->GetModel(); - int iRemoteModelID = iModelID; - - if (BitStream.Version() >= 0x05F) - BitStream.Read(iRemoteModelID); + int iRemoteModelID = 0; + BitStream.Read(iRemoteModelID); eVehicleType vehicleType = pVehicle->GetVehicleType(); - eVehicleType remoteVehicleType = CVehicleManager::GetVehicleType(iRemoteModelID); + eVehicleType remoteVehicleType = CVehicleManager::GetVehicleType(static_cast(iRemoteModelID)); // Read out its position SPositionSync position(false); @@ -89,7 +86,7 @@ bool CVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) // Note: here we use a uchar, in the CTT branch this is a uint. Just don't forget that, it might be important uchar trackIndex; BitStream.Read(trackIndex); - pTrainTrack = g_pGame->GetTrainTrackManager()->GetTrainTrackByIndex(trackIndex); + pTrainTrack = g_pGame->GetTrainTrackManager()->GetDefaultTrackByIndex(trackIndex); // But we should only actually apply that train-specific data if that vehicle is train on our side if (vehicleType == VEHICLE_TRAIN) @@ -295,7 +292,7 @@ bool CVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) if (!BitStream.Read(&bodyPart)) return false; - pSourcePlayer->SetDamageInfo(DamagerID, weaponType.data.ucWeaponType, bodyPart.data.uiBodypart); + pSourcePlayer->SetDamageInfo(DamagerID, weaponType.data.ucWeaponType, static_cast(bodyPart.data.uiBodypart)); } } @@ -311,31 +308,18 @@ bool CVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) // Less than last packet's frame? if (fHealth < fOldHealth && fHealthLoss > 0) { - if (BitStream.Version() <= 0x046) - { - // Call the onPlayerDamage event - CLuaArguments Arguments; - Arguments.PushNil(); - Arguments.PushNumber(false); - Arguments.PushNumber(false); - Arguments.PushNumber(fHealthLoss); - pSourcePlayer->CallEvent("onPlayerDamage", Arguments); - } - else - { - // Call the onPlayerDamage event - CLuaArguments Arguments; + // Call the onPlayerDamage event + CLuaArguments Arguments; - CElement* pDamageSource = CElementIDs::GetElement(pSourcePlayer->GetPlayerAttacker()); - if (pDamageSource) - Arguments.PushElement(pDamageSource); - else - Arguments.PushNil(); - Arguments.PushNumber(pSourcePlayer->GetAttackWeapon()); - Arguments.PushNumber(pSourcePlayer->GetAttackBodyPart()); - Arguments.PushNumber(fHealthLoss); - pSourcePlayer->CallEvent("onPlayerDamage", Arguments); - } + CElement* pDamageSource = CElementIDs::GetElement(pSourcePlayer->GetPlayerAttacker()); + if (pDamageSource) + Arguments.PushElement(pDamageSource); + else + Arguments.PushNil(); + Arguments.PushNumber(pSourcePlayer->GetAttackWeapon()); + Arguments.PushNumber(pSourcePlayer->GetAttackBodyPart()); + Arguments.PushNumber(fHealthLoss); + pSourcePlayer->CallEvent("onPlayerDamage", Arguments); } pSourcePlayer->SetHealth(fHealth); @@ -351,31 +335,18 @@ bool CVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) // Less than last packet's frame? if (fArmor < fOldArmor && fArmorLoss > 0) { - if (BitStream.Version() <= 0x046) - { - // Call the onPlayerDamage event - CLuaArguments Arguments; - Arguments.PushNil(); - Arguments.PushNumber(false); - Arguments.PushNumber(false); - Arguments.PushNumber(fArmorLoss); - pSourcePlayer->CallEvent("onPlayerDamage", Arguments); - } - else - { - // Call the onPlayerDamage event - CLuaArguments Arguments; + // Call the onPlayerDamage event + CLuaArguments Arguments; - CElement* pDamageSource = CElementIDs::GetElement(pSourcePlayer->GetPlayerAttacker()); - if (pDamageSource) - Arguments.PushElement(pDamageSource); - else - Arguments.PushNil(); - Arguments.PushNumber(pSourcePlayer->GetAttackWeapon()); - Arguments.PushNumber(pSourcePlayer->GetAttackBodyPart()); - Arguments.PushNumber(fArmorLoss); - pSourcePlayer->CallEvent("onPlayerDamage", Arguments); - } + CElement* pDamageSource = CElementIDs::GetElement(pSourcePlayer->GetPlayerAttacker()); + if (pDamageSource) + Arguments.PushElement(pDamageSource); + else + Arguments.PushNil(); + Arguments.PushNumber(pSourcePlayer->GetAttackWeapon()); + Arguments.PushNumber(pSourcePlayer->GetAttackBodyPart()); + Arguments.PushNumber(fArmorLoss); + pSourcePlayer->CallEvent("onPlayerDamage", Arguments); } pSourcePlayer->SetArmor(fArmor); @@ -401,12 +372,11 @@ bool CVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) float fWeaponRange = pSourcePlayer->GetWeaponRangeFromSlot(slot.data.uiSlot); // Read the ammo states - SWeaponAmmoSync ammo(pSourcePlayer->GetWeaponType(), BitStream.Version() >= 0x44, true); + SWeaponAmmoSync ammo(pSourcePlayer->GetWeaponType(), true, true); if (!BitStream.Read(&ammo)) return false; pSourcePlayer->SetWeaponAmmoInClip(ammo.data.usAmmoInClip); - if (BitStream.Version() >= 0x44) - pSourcePlayer->SetWeaponTotalAmmo(ammo.data.usTotalAmmo); + pSourcePlayer->SetWeaponTotalAmmo(ammo.data.usTotalAmmo); // Read aim data SWeaponAimSync aim(fWeaponRange, true); @@ -451,8 +421,7 @@ bool CVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) pSourcePlayer->GetPad()->NewControllerState(ControllerState); - if (BitStream.Can(eBitStreamVersion::SetElementOnFire)) - pVehicle->SetOnFire(BitStream.ReadBit()); + pVehicle->SetOnFire(BitStream.ReadBit()); // Success return true; @@ -484,7 +453,8 @@ bool CVehiclePuresyncPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(pSourcePlayer->GetSyncTimeContext()); // Write his ping divided with 2 plus a small number so the client can find out when this packet was sent - unsigned short usLatency = pSourcePlayer->GetPing(); + const unsigned int uiPing = pSourcePlayer->GetPing(); + const unsigned short usLatency = uiPing <= 0xFFFF ? static_cast(uiPing) : 0xFFFF; BitStream.WriteCompressed(usLatency); // Write the keysync data @@ -492,8 +462,7 @@ bool CVehiclePuresyncPacket::Write(NetBitStreamInterface& BitStream) const WriteFullKeysync(ControllerState, BitStream); // Write the serverside model (#8800) - if (BitStream.Version() >= 0x05F) - BitStream.Write((int)pVehicle->GetModel()); + BitStream.Write((int)pVehicle->GetModel()); // Write the vehicle matrix only if he's the driver CVector vecTemp; @@ -559,36 +528,33 @@ bool CVehiclePuresyncPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(&health); // Write the trailer chain - if (BitStream.Version() >= 0x42) + CVehicle* pTrailer = pVehicle->GetTowedVehicle(); + while (pTrailer) { - CVehicle* pTrailer = pVehicle->GetTowedVehicle(); - while (pTrailer) - { - BitStream.WriteBit(true); - BitStream.Write(pTrailer->GetID()); + BitStream.WriteBit(true); + BitStream.Write(pTrailer->GetID()); - // Write the position and rotation - CVector vecTrailerPosition, vecTrailerRotationDegrees; + // Write the position and rotation + CVector vecTrailerPosition, vecTrailerRotationDegrees; - // Write the matrix - vecTrailerPosition = pTrailer->GetPosition(); - pTrailer->GetRotationDegrees(vecTrailerRotationDegrees); + // Write the matrix + vecTrailerPosition = pTrailer->GetPosition(); + pTrailer->GetRotationDegrees(vecTrailerRotationDegrees); - SPositionSync trailerPosition(false); - trailerPosition.data.vecPosition = vecTrailerPosition; - BitStream.Write(&trailerPosition); - - SRotationDegreesSync trailerRotation; - trailerRotation.data.vecRotation = vecTrailerRotationDegrees; - BitStream.Write(&trailerRotation); + SPositionSync trailerPosition(false); + trailerPosition.data.vecPosition = vecTrailerPosition; + BitStream.Write(&trailerPosition); - // Get the next towed vehicle - pTrailer = pTrailer->GetTowedVehicle(); - } + SRotationDegreesSync trailerRotation; + trailerRotation.data.vecRotation = vecTrailerRotationDegrees; + BitStream.Write(&trailerRotation); - // End of our trailer chain - BitStream.WriteBit(false); + // Get the next towed vehicle + pTrailer = pTrailer->GetTowedVehicle(); } + + // End of our trailer chain + BitStream.WriteBit(false); } // Player health and armor @@ -629,7 +595,7 @@ bool CVehiclePuresyncPacket::Write(NetBitStreamInterface& BitStream) const if (flags.data.bIsDoingGangDriveby && CWeaponNames::DoesSlotHaveAmmo(slot.data.uiSlot)) { // Write the ammo states - SWeaponAmmoSync ammo(ucWeaponType, BitStream.Version() >= 0x44, true); + SWeaponAmmoSync ammo(ucWeaponType, true, true); ammo.data.usAmmoInClip = pSourcePlayer->GetWeaponAmmoInClip(); ammo.data.usTotalAmmo = pSourcePlayer->GetWeaponTotalAmmo(); BitStream.Write(&ammo); @@ -663,24 +629,20 @@ bool CVehiclePuresyncPacket::Write(NetBitStreamInterface& BitStream) const } // Write parts state - if (BitStream.Version() >= 0x5D) - { - SVehicleDamageSyncMethodeB damage; - // Check where we are in the cycle - uchar ucMode = (pVehicle->m_uiDamageInfoSendPhase & 3); - damage.data.bSyncDoors = (ucMode == 0); - damage.data.bSyncWheels = (ucMode == 1); - damage.data.bSyncPanels = (ucMode == 2); - damage.data.bSyncLights = (ucMode == 3); - damage.data.doors.data.ucStates = pVehicle->m_ucDoorStates; - damage.data.wheels.data.ucStates = pVehicle->m_ucWheelStates; - damage.data.panels.data.ucStates = pVehicle->m_ucPanelStates; - damage.data.lights.data.ucStates = pVehicle->m_ucLightStates; - BitStream.Write(&damage); - } - - if (BitStream.Can(eBitStreamVersion::SetElementOnFire)) - BitStream.WriteBit(pVehicle->IsOnFire()); + SVehicleDamageSyncMethodeB damage; + // Check where we are in the cycle + uchar ucMode = (pVehicle->m_uiDamageInfoSendPhase & 3); + damage.data.bSyncDoors = (ucMode == 0); + damage.data.bSyncWheels = (ucMode == 1); + damage.data.bSyncPanels = (ucMode == 2); + damage.data.bSyncLights = (ucMode == 3); + damage.data.doors.data.ucStates = pVehicle->m_ucDoorStates; + damage.data.wheels.data.ucStates = pVehicle->m_ucWheelStates; + damage.data.panels.data.ucStates = pVehicle->m_ucPanelStates; + damage.data.lights.data.ucStates = pVehicle->m_ucLightStates; + BitStream.Write(&damage); + + BitStream.WriteBit(pVehicle->IsOnFire()); // Success return true; @@ -717,11 +679,11 @@ void CVehiclePuresyncPacket::ReadVehicleSpecific(CVehicle* pVehicle, NetBitStrea } // Door angles. - if (CVehicleManager::HasDoors(iRemoteModel)) + if (CVehicleManager::HasDoors(static_cast(iRemoteModel))) { SDoorOpenRatioSync door; - for (unsigned int i = 2; i < 6; ++i) + for (unsigned char i = 2; i < 6; ++i) { if (!BitStream.Read(&door)) return; @@ -754,7 +716,7 @@ void CVehiclePuresyncPacket::WriteVehicleSpecific(CVehicle* pVehicle, NetBitStre if (CVehicleManager::HasDoors(usModel)) { SDoorOpenRatioSync door; - for (unsigned int i = 2; i < 6; ++i) + for (unsigned char i = 2; i < 6; ++i) { door.data.fRatio = pVehicle->GetDoorOpenRatio(i); BitStream.Write(&door); diff --git a/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.h b/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.h index 4a86ad957a2..f924bd170a6 100644 --- a/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.h +++ b/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.h @@ -19,7 +19,7 @@ class CVehicle; class CVehiclePuresyncPacket final : public CPacket { public: - CVehiclePuresyncPacket(){}; + CVehiclePuresyncPacket() {}; explicit CVehiclePuresyncPacket(class CPlayer* pPlayer); bool HasSimHandler() const { return true; } diff --git a/Server/mods/deathmatch/logic/packets/CVehicleResyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CVehicleResyncPacket.cpp index c6648b5b54a..68dfe3a7a37 100644 --- a/Server/mods/deathmatch/logic/packets/CVehicleResyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CVehicleResyncPacket.cpp @@ -52,19 +52,16 @@ bool CVehicleResyncPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(&health); // Write parts state - if (BitStream.Version() >= 0x5D) - { - SVehicleDamageSyncMethodeB damage; - damage.data.bSyncDoors = true; - damage.data.bSyncWheels = true; - damage.data.bSyncPanels = true; - damage.data.bSyncLights = true; - damage.data.doors.data.ucStates = m_pVehicle->m_ucDoorStates; - damage.data.wheels.data.ucStates = m_pVehicle->m_ucWheelStates; - damage.data.panels.data.ucStates = m_pVehicle->m_ucPanelStates; - damage.data.lights.data.ucStates = m_pVehicle->m_ucLightStates; - BitStream.Write(&damage); - } + SVehicleDamageSyncMethodeB damage; + damage.data.bSyncDoors = true; + damage.data.bSyncWheels = true; + damage.data.bSyncPanels = true; + damage.data.bSyncLights = true; + damage.data.doors.data.ucStates = m_pVehicle->m_ucDoorStates; + damage.data.wheels.data.ucStates = m_pVehicle->m_ucWheelStates; + damage.data.panels.data.ucStates = m_pVehicle->m_ucPanelStates; + damage.data.lights.data.ucStates = m_pVehicle->m_ucLightStates; + BitStream.Write(&damage); return true; } diff --git a/Server/mods/deathmatch/logic/packets/CVehicleTrailerPacket.h b/Server/mods/deathmatch/logic/packets/CVehicleTrailerPacket.h index b9eae09fa20..b6ed1affdff 100644 --- a/Server/mods/deathmatch/logic/packets/CVehicleTrailerPacket.h +++ b/Server/mods/deathmatch/logic/packets/CVehicleTrailerPacket.h @@ -19,7 +19,7 @@ class CVehicle; class CVehicleTrailerPacket final : public CPacket { public: - CVehicleTrailerPacket(){}; + CVehicleTrailerPacket() {}; CVehicleTrailerPacket(CVehicle* pVehicle, CVehicle* pTrailer, bool bAttached); ePacketID GetPacketID() const { return PACKET_ID_VEHICLE_TRAILER; }; diff --git a/Server/mods/deathmatch/logic/packets/CVoiceDataPacket.cpp b/Server/mods/deathmatch/logic/packets/CVoiceDataPacket.cpp index 6caf2dd2384..79d246e01cf 100644 --- a/Server/mods/deathmatch/logic/packets/CVoiceDataPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CVoiceDataPacket.cpp @@ -1,11 +1,11 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: mods/deathmatch/logic/packets/CVoiceDataPacket.cpp * PURPOSE: Voice data packet class * - * Multi Theft Auto is available from https://www.multitheftauto.com/ + * Multi Theft Auto is available from https://multitheftauto.com/ * *****************************************************************************/ @@ -15,37 +15,17 @@ CVoiceDataPacket::CVoiceDataPacket() { - m_pBuffer = NULL; - m_usDataBufferSize = 0; - m_usActualDataLength = 0; - - AllocateBuffer(1024); -} - -CVoiceDataPacket::CVoiceDataPacket(CPlayer* pPlayer, const unsigned char* pbSrcBuffer, unsigned short usLength) -{ - m_pBuffer = NULL; - m_usDataBufferSize = 0; - m_usActualDataLength = 0; - - SetSourceElement(pPlayer); - SetData(pbSrcBuffer, usLength); -} -CVoiceDataPacket::~CVoiceDataPacket() -{ - DeallocateBuffer(); + m_voiceBuffer.reserve(2048); } bool CVoiceDataPacket::Read(NetBitStreamInterface& BitStream) { - if (m_pBuffer) + unsigned short voiceBufferLength{}; + + if (BitStream.Read(voiceBufferLength) && voiceBufferLength <= m_voiceBuffer.capacity()) { - BitStream.Read(m_usActualDataLength); - if (m_usActualDataLength) - { - BitStream.Read(reinterpret_cast(m_pBuffer), m_usActualDataLength <= m_usDataBufferSize ? m_usActualDataLength : m_usDataBufferSize); - } - return true; + m_voiceBuffer.resize(voiceBufferLength); + return BitStream.Read(reinterpret_cast(m_voiceBuffer.data()), m_voiceBuffer.size()); } return false; @@ -53,74 +33,29 @@ bool CVoiceDataPacket::Read(NetBitStreamInterface& BitStream) bool CVoiceDataPacket::Write(NetBitStreamInterface& BitStream) const { - if (m_usActualDataLength) + if (!m_voiceBuffer.empty()) { + const auto voiceBuffer = reinterpret_cast(m_voiceBuffer.data()); + const auto voiceBufferLength = static_cast(m_voiceBuffer.size()); + // Write the source player - ElementID ID = m_pSourceElement->GetID(); - BitStream.Write(ID); + BitStream.Write(m_pSourceElement->GetID()); // Write the length as an unsigned short and then write the string - BitStream.Write(m_usActualDataLength); - BitStream.Write(reinterpret_cast(m_pBuffer), m_usActualDataLength); + BitStream.Write(voiceBufferLength); + BitStream.Write(voiceBuffer, voiceBufferLength); return true; } return false; } -void CVoiceDataPacket::AllocateBuffer(unsigned short usBufferSize) -{ - // Test to see if we already have an allocated buffer - // that will hold the requested size. - if (m_usDataBufferSize < usBufferSize) - { - // It's not... resize the buffer. - if (m_pBuffer) - { - // Free the current buffer. - delete[] m_pBuffer; - } - - // Allocate new buffer. - m_pBuffer = new unsigned char[usBufferSize]; - - // Clear buffer. - memset(m_pBuffer, 0, usBufferSize); - - // Save the new size. - m_usDataBufferSize = usBufferSize; - } -} - -void CVoiceDataPacket::DeallocateBuffer() +void CVoiceDataPacket::SetVoiceData(const unsigned char* voiceBuffer, unsigned short voiceBufferLength) { - if (m_pBuffer) - { - delete[] m_pBuffer; - m_pBuffer = NULL; - m_usDataBufferSize = 0; - m_usActualDataLength = 0; - } -} + m_voiceBuffer.clear(); -void CVoiceDataPacket::SetData(const unsigned char* pbSrcBuffer, unsigned short usLength) -{ - // Allocate new buffer. - AllocateBuffer(usLength); + if (!voiceBuffer || !voiceBufferLength || voiceBufferLength > m_voiceBuffer.capacity()) + return; - // Copy in the data. - if (m_pBuffer) - { - memcpy(m_pBuffer, pbSrcBuffer, usLength); - m_usActualDataLength = usLength; - } -} - -const unsigned char* CVoiceDataPacket::GetData() const -{ - return m_pBuffer; -} - -unsigned short CVoiceDataPacket::GetDataLength() const -{ - return m_usActualDataLength; + m_voiceBuffer.resize(voiceBufferLength); + std::copy_n(voiceBuffer, voiceBufferLength, m_voiceBuffer.data()); } diff --git a/Server/mods/deathmatch/logic/packets/CVoiceDataPacket.h b/Server/mods/deathmatch/logic/packets/CVoiceDataPacket.h index ed23c3c11cd..9641eb3d2e4 100644 --- a/Server/mods/deathmatch/logic/packets/CVoiceDataPacket.h +++ b/Server/mods/deathmatch/logic/packets/CVoiceDataPacket.h @@ -1,24 +1,23 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: mods/deathmatch/logic/packets/CVoiceDataPacket.h * PURPOSE: Voice data packet class * - * Multi Theft Auto is available from https://www.multitheftauto.com/ + * Multi Theft Auto is available from https://multitheftauto.com/ * *****************************************************************************/ #pragma once #include "CPacket.h" +#include class CVoiceDataPacket final : public CPacket { public: - CVoiceDataPacket(CPlayer* pPlayer, const unsigned char* pbSrcBuffer, unsigned short usLength); CVoiceDataPacket(); - ~CVoiceDataPacket(); ePacketID GetPacketID() const { return PACKET_ID_VOICE_DATA; } unsigned long GetFlags() const { return PACKET_LOW_PRIORITY | PACKET_SEQUENCED; }; @@ -27,16 +26,10 @@ class CVoiceDataPacket final : public CPacket bool Read(NetBitStreamInterface& BitStream); bool Write(NetBitStreamInterface& BitStream) const; - void SetData(const unsigned char* pbSrcBuffer, unsigned short usLength); + void SetVoiceData(const unsigned char* voiceBuffer, unsigned short voiceBufferLength); - unsigned short GetDataLength() const; - const unsigned char* GetData() const; + bool IsEmpty() const noexcept { return m_voiceBuffer.empty(); } private: - void AllocateBuffer(unsigned short usBufferSize); - void DeallocateBuffer(); - - unsigned char* m_pBuffer; - unsigned short m_usDataBufferSize; - unsigned short m_usActualDataLength; + std::vector m_voiceBuffer; }; diff --git a/Server/mods/deathmatch/mtaserver.conf b/Server/mods/deathmatch/mtaserver.conf index 2dd6960ae0b..21b736a6bb1 100644 --- a/Server/mods/deathmatch/mtaserver.conf +++ b/Server/mods/deathmatch/mtaserver.conf @@ -94,6 +94,11 @@ Available values: special detection (SD) codes ; (e.g. To enable special detection #15 use: 15) --> + + 1 + - - - Default MTA Server - - - - - - - - - - - - - - - - - - - - - - - - - - - auto - - - 22003 - - - 32 - - - 22005 - - - - - - 5 - - - 20 - - - - - - none - - - - - - - - - - - - - - - - 1 - - - - - - 1 - - - 0 - - - - - - medium - - - - 100 - - 1500 - - 500 - - 400 - - 2000 - - 400 - - 100 - - 100 - - - 1 - - - 30 - - - 100 - - - 0 - - - 150 - - - 0 - - - server-id.keys - - - logs/server.log - - - logs/server_auth.log - - - logs/db.log - - - - - - acl.xml - - - logs/scripts.log - - - 0 - - - 0 - - - 1 - - - 60 - - - 0 - - - 1 - - - 4 - - - - - - backups - - - 3 - - - 10 - - - 1 - - - 1 - - - Admin - - - 1 - - - 127.0.0.1 - - - 1 - - - 0 - - - 1 - - - 1000 - 100 - - - 1 - diff --git a/Server/mods/deathmatch/premake5.lua b/Server/mods/deathmatch/premake5.lua index ddecdfb1796..78e1c708292 100644 --- a/Server/mods/deathmatch/premake5.lua +++ b/Server/mods/deathmatch/premake5.lua @@ -3,6 +3,7 @@ project "Deathmatch" kind "SharedLib" targetname "deathmatch" targetdir(buildpath("server/mods/deathmatch")) + clangtidy "On" pchheader "StdInc.h" pchsource "StdInc.cpp" diff --git a/Server/mods/deathmatch/utils/CFunctionUseLogger.cpp b/Server/mods/deathmatch/utils/CFunctionUseLogger.cpp index 12a12413fbd..f392b781312 100644 --- a/Server/mods/deathmatch/utils/CFunctionUseLogger.cpp +++ b/Server/mods/deathmatch/utils/CFunctionUseLogger.cpp @@ -74,7 +74,7 @@ void CFunctionUseLogger::OnFunctionUse(lua_State* luaVM, const char* szFunctionN return; CResource* pResource = g_pGame->GetResourceManager()->GetResourceFromLuaState(luaVM); - SString strResourceName = pResource ? pResource->GetName() : "Unknown"; + SString strResourceName = pResource ? pResource->GetName() : SStringX("Unknown"); SString strKey("%s-%s", szFunctionName, *strResourceName); diff --git a/Server/mods/deathmatch/utils/CHqComms.h b/Server/mods/deathmatch/utils/CHqComms.h index 8be9247f0fc..18ddeba4f35 100644 --- a/Server/mods/deathmatch/utils/CHqComms.h +++ b/Server/mods/deathmatch/utils/CHqComms.h @@ -49,7 +49,7 @@ class CHqComms : public CRefCountable m_Stage = HQCOMMS_STAGE_QUERY; CBitStream bitStream; - bitStream->Write((char)4); // Data version + bitStream->Write((char)4); // Data version bitStream->WriteStr(g_pGame->GetConfig()->GetServerIP()); bitStream->Write(g_pGame->GetConfig()->GetServerPort()); bitStream->WriteStr(CStaticFunctionDefinitions::GetVersionSortable()); @@ -91,7 +91,7 @@ class CHqComms : public CRefCountable bitStream->WriteStr(SString::Join(",", g_pGame->GetConfig()->GetOwnerEmailAddressList())); // Send request - this->AddRef(); // Keep object alive + this->AddRef(); // Keep object alive SHttpRequestOptions options; options.strPostData = SStringX((const char*)bitStream->GetData(), bitStream->GetNumberOfBytesUsed()); options.bPostBinary = true; @@ -107,7 +107,7 @@ class CHqComms : public CRefCountable { CHqComms* pHqComms = (CHqComms*)result.pObj; pHqComms->DownloadFinishedCallback(result); - pHqComms->Release(); // No need to keep object alive now + pHqComms->Release(); // No need to keep object alive now } // @@ -247,7 +247,7 @@ class CHqComms : public CRefCountable static CNetHTTPDownloadManagerInterface* GetDownloadManager() { return g_pNetServer->GetHTTPDownloadManager(EDownloadMode::ASE); } protected: - ~CHqComms() {} // Must use Release() + ~CHqComms() {} // Must use Release() int m_iPollInterval; int m_iPrevBadFileHashesRev; @@ -256,5 +256,5 @@ class CHqComms : public CRefCountable SString m_strURL; SString m_strPrevMessage; SString m_strCrashLogFilename; - SString m_strCrashDumpMeta; // Filename of file which contains the latest crash dump filename + SString m_strCrashDumpMeta; // Filename of file which contains the latest crash dump filename }; diff --git a/Server/mods/deathmatch/utils/CMasterServerAnnouncer.h b/Server/mods/deathmatch/utils/CMasterServerAnnouncer.h index 4278a819fdb..35be9577894 100644 --- a/Server/mods/deathmatch/utils/CMasterServerAnnouncer.h +++ b/Server/mods/deathmatch/utils/CMasterServerAnnouncer.h @@ -46,12 +46,12 @@ class CMasterServer : public CRefCountable { m_Stage = ANNOUNCE_STAGE_INITIAL; m_uiInitialAnnounceRetryAttempts = 5; - m_uiInitialAnnounceRetryInterval = 1000 * 60 * 5; // 5 mins initial announce retry interval - m_uiPushInterval = 1000 * 60 * 10; // 10 mins push interval + m_uiInitialAnnounceRetryInterval = 1000 * 60 * 5; // 5 mins initial announce retry interval + m_uiPushInterval = 1000 * 60 * 10; // 10 mins push interval } protected: - ~CMasterServer() {} // Must use Release() + ~CMasterServer() {} // Must use Release() public: // // Pulse this master server @@ -81,7 +81,7 @@ class CMasterServer : public CRefCountable m_llLastAnnounceTime = llTickCountNow; // Send request - this->AddRef(); // Keep object alive + this->AddRef(); // Keep object alive m_bStatusBusy = true; SHttpRequestOptions options; options.uiConnectionAttempts = 2; @@ -115,7 +115,7 @@ class CMasterServer : public CRefCountable { CMasterServer* pMasterServer = (CMasterServer*)result.pObj; pMasterServer->DownloadFinishedCallback(result); - pMasterServer->Release(); // No need to keep object alive now + pMasterServer->Release(); // No need to keep object alive now } // @@ -151,7 +151,7 @@ class CMasterServer : public CRefCountable } else { - bool bCanRetry = (result.iErrorCode == 28); // We can retry if 'Timeout was reached' + bool bCanRetry = (result.iErrorCode == 28); // We can retry if 'Timeout was reached' if (m_Stage == ANNOUNCE_STAGE_INITIAL) { diff --git a/Server/mods/deathmatch/utils/CZipMaker.cpp b/Server/mods/deathmatch/utils/CZipMaker.cpp index 7ac45238f6e..38f91d5b7db 100644 --- a/Server/mods/deathmatch/utils/CZipMaker.cpp +++ b/Server/mods/deathmatch/utils/CZipMaker.cpp @@ -31,7 +31,7 @@ CZipMaker::CZipMaker(const SString& strZipPathFilename) fill_win32_filefunc(&ffunc); m_uzFile = zipOpen2(strZipPathFilename, APPEND_STATUS_CREATE, nullptr, &ffunc); #else - m_uzFile = zipOpen(strZipPathFilename, APPEND_STATUS_CREATE); // Use APPEND_STATUS_ADDINZIP to open existing + m_uzFile = zipOpen(strZipPathFilename, APPEND_STATUS_CREATE); // Use APPEND_STATUS_ADDINZIP to open existing #endif } diff --git a/Server/sdk/MTAPlatform.h b/Server/sdk/MTAPlatform.h index a7ec32c7854..ee4e2274146 100644 --- a/Server/sdk/MTAPlatform.h +++ b/Server/sdk/MTAPlatform.h @@ -17,38 +17,38 @@ extern "C" bool g_bNoTopBar; /** Operating system identifiers **/ #if defined(WIN32) #ifdef _WIN64 - #define MTA_OS_STRING "Windows x64" + #define MTA_OS_STRING "Windows x64" #elif defined(_M_ARM64) - #define MTA_OS_STRING "Windows arm64" + #define MTA_OS_STRING "Windows arm64" #elif defined(_M_ARM) - #define MTA_OS_STRING "Windows arm" + #define MTA_OS_STRING "Windows arm" #else - #define MTA_OS_STRING "Windows" + #define MTA_OS_STRING "Windows" #endif - #define MTA_LIB_EXTENSION ".dll" + #define MTA_LIB_EXTENSION ".dll" #elif defined(__linux__) #ifdef __x86_64__ - #define MTA_OS_STRING "GNU/Linux x64" + #define MTA_OS_STRING "GNU/Linux x64" #elif defined(__aarch64__) - #define MTA_OS_STRING "GNU/Linux arm64" + #define MTA_OS_STRING "GNU/Linux arm64" #elif defined(__arm__) - #define MTA_OS_STRING "GNU/Linux arm" + #define MTA_OS_STRING "GNU/Linux arm" #else - #define MTA_OS_STRING "GNU/Linux" + #define MTA_OS_STRING "GNU/Linux" #endif - #define MTA_LIB_EXTENSION ".so" + #define MTA_LIB_EXTENSION ".so" #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) - #define MTA_OS_STRING "BSD" - #define MTA_LIB_EXTENSION ".so" + #define MTA_OS_STRING "BSD" + #define MTA_LIB_EXTENSION ".so" #elif defined(__APPLE__) - #define MTA_OS_STRING "macOS" - #define MTA_LIB_EXTENSION ".dylib" + #define MTA_OS_STRING "macOS" + #define MTA_LIB_EXTENSION ".dylib" #else #error "Unsupported operating system" #endif #if defined(MTA_DEBUG) - #define MTA_LIB_SUFFIX "_d" + #define MTA_LIB_SUFFIX "_d" #else #define MTA_LIB_SUFFIX #endif diff --git a/Server/sdk/core/CExceptionInformation.h b/Server/sdk/core/CExceptionInformation.h index 4ef8afe16c5..50c2f175d10 100644 --- a/Server/sdk/core/CExceptionInformation.h +++ b/Server/sdk/core/CExceptionInformation.h @@ -36,4 +36,24 @@ class CExceptionInformation virtual unsigned long GetGS() = 0; virtual unsigned long GetSS() = 0; virtual unsigned long GetEFlags() = 0; + +#if defined(_M_X64) || defined(__x86_64__) || defined(_M_AMD64) || defined(__amd64__) + virtual unsigned long long GetRAX() = 0; + virtual unsigned long long GetRBX() = 0; + virtual unsigned long long GetRCX() = 0; + virtual unsigned long long GetRDX() = 0; + virtual unsigned long long GetRSI() = 0; + virtual unsigned long long GetRDI() = 0; + virtual unsigned long long GetRBP() = 0; + virtual unsigned long long GetRSP() = 0; + virtual unsigned long long GetRIP() = 0; + virtual unsigned long long GetR8() = 0; + virtual unsigned long long GetR9() = 0; + virtual unsigned long long GetR10() = 0; + virtual unsigned long long GetR11() = 0; + virtual unsigned long long GetR12() = 0; + virtual unsigned long long GetR13() = 0; + virtual unsigned long long GetR14() = 0; + virtual unsigned long long GetR15() = 0; +#endif }; diff --git a/Server/sdk/net/CNetServer.h b/Server/sdk/net/CNetServer.h index eb8868c9ae1..e1171db035a 100644 --- a/Server/sdk/net/CNetServer.h +++ b/Server/sdk/net/CNetServer.h @@ -16,7 +16,7 @@ #include "ns_playerid.h" #include "net/CNetHTTPDownloadManagerInterface.h" -#define MAX_CALL_REMOTE_QUEUES 100 +#define MAX_CALL_REMOTE_QUEUES 100 namespace EDownloadMode { diff --git a/Server/sdk/net/ns_common.h b/Server/sdk/net/ns_common.h index 8467b706ad2..2902720698c 100644 --- a/Server/sdk/net/ns_common.h +++ b/Server/sdk/net/ns_common.h @@ -18,10 +18,10 @@ const NetServerPlayerID NET_INVALID_PLAYER_ID; #define NET_INVALID_PLAYER_INDEX 255; -#define NET_MAX_PLAYER_COUNT 64 -#define NET_MAX_VEHICLE_COUNT 250 +#define NET_MAX_PLAYER_COUNT 64 +#define NET_MAX_VEHICLE_COUNT 250 -#define NET_MAX_PLAYER_NAME_LENGTH 32 +#define NET_MAX_PLAYER_NAME_LENGTH 32 typedef struct __static_client_data_t { @@ -48,7 +48,7 @@ enum NetServerPacketReliability PACKET_RELIABILITY_UNRELIABLE_SEQUENCED, PACKET_RELIABILITY_RELIABLE, PACKET_RELIABILITY_RELIABLE_ORDERED, - PACKET_RELIABILITY_RELIABLE_SEQUENCED // Can drop packets + PACKET_RELIABILITY_RELIABLE_SEQUENCED // Can drop packets }; // Copy of raknet statistics diff --git a/Server/sdk/net/ns_playerid.h b/Server/sdk/net/ns_playerid.h index 5b8612b176c..bacfff6fbae 100644 --- a/Server/sdk/net/ns_playerid.h +++ b/Server/sdk/net/ns_playerid.h @@ -47,7 +47,7 @@ class NetServerPlayerID m_usPort = usPort; }; - ~NetServerPlayerID(){}; + ~NetServerPlayerID() {}; friend inline int operator==(const NetServerPlayerID& left, const NetServerPlayerID& right) { diff --git a/Server/sdk/premake5.lua b/Server/sdk/premake5.lua index 4c41bd822a2..9c2694319bf 100644 --- a/Server/sdk/premake5.lua +++ b/Server/sdk/premake5.lua @@ -7,6 +7,7 @@ project "Server SDK" language "C++" kind "None" targetname "sdk" + clangtidy "On" vpaths { ["Headers/*"] = { "**.h", "**.hpp" }, diff --git a/Shared/XML/CXMLArray.cpp b/Shared/XML/CXMLArray.cpp index 28df306d617..521b42c3f8f 100644 --- a/Shared/XML/CXMLArray.cpp +++ b/Shared/XML/CXMLArray.cpp @@ -13,7 +13,7 @@ using namespace std; -#define XML_ARRAY_BASE_ID 0x01000000 +#define XML_ARRAY_BASE_ID 0x01000000 CStack CXMLArray::m_IDStack; std::vector CXMLArray::m_Elements; diff --git a/Shared/XML/CXMLAttributeImpl.cpp b/Shared/XML/CXMLAttributeImpl.cpp index 13d3ce384ed..546a196bc98 100644 --- a/Shared/XML/CXMLAttributeImpl.cpp +++ b/Shared/XML/CXMLAttributeImpl.cpp @@ -11,7 +11,7 @@ #include "StdInc.h" -#define XML_ATTRIBUTE_VALUE_BUFFER 40 +#define XML_ATTRIBUTE_VALUE_BUFFER 40 CXMLAttributeImpl::CXMLAttributeImpl(CXMLAttributesImpl& Attributes, TiXmlElement& Node, const std::string& strName) : m_ulID(INVALID_XML_ID), diff --git a/Shared/XML/CXMLImpl.cpp b/Shared/XML/CXMLImpl.cpp index 9cbd481c726..e289f4f1f33 100644 --- a/Shared/XML/CXMLImpl.cpp +++ b/Shared/XML/CXMLImpl.cpp @@ -13,7 +13,7 @@ #define ALLOC_STATS_MODULE_NAME "xml" #include #ifndef MAX_PATH -#define MAX_PATH 260 + #define MAX_PATH 260 #endif #include "SharedUtil.hpp" diff --git a/Shared/XML/CXMLNodeImpl.cpp b/Shared/XML/CXMLNodeImpl.cpp index f9ce0bf9242..f439b0b633f 100644 --- a/Shared/XML/CXMLNodeImpl.cpp +++ b/Shared/XML/CXMLNodeImpl.cpp @@ -231,7 +231,7 @@ bool CXMLNodeImpl::GetTagContent(bool& bContent) return true; } - return false; // Invalid + return false; // Invalid } bool CXMLNodeImpl::GetTagContent(int& iContent) @@ -328,7 +328,7 @@ void CXMLNodeImpl::SetTagContent(float fContent) { // Convert to string and set it char szBuffer[40]; - sprintf(szBuffer, "%f", fContent); + snprintf(szBuffer, sizeof(szBuffer), "%f", fContent); SetTagContent(szBuffer); } diff --git a/Shared/XML/StdInc.h b/Shared/XML/StdInc.h index b55ac90d4ba..969629fe8a1 100644 --- a/Shared/XML/StdInc.h +++ b/Shared/XML/StdInc.h @@ -1,9 +1,9 @@ #ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include + #define WIN32_LEAN_AND_MEAN + #include #else -#include + #include #endif #include diff --git a/Shared/XML/premake5.lua b/Shared/XML/premake5.lua index 254831a536e..df404a67733 100644 --- a/Shared/XML/premake5.lua +++ b/Shared/XML/premake5.lua @@ -3,6 +3,7 @@ project "XML" kind "SharedLib" targetname "xmll" targetdir(buildpath("server")) + clangtidy "On" includedirs { "../sdk", diff --git a/Shared/animation/CEasingCurve.cpp b/Shared/animation/CEasingCurve.cpp index e1ad2b2179f..ee46f1e40bf 100644 --- a/Shared/animation/CEasingCurve.cpp +++ b/Shared/animation/CEasingCurve.cpp @@ -10,12 +10,12 @@ #include "StdInc.h" #include "CEasingCurve.h" #include "lua/CLuaFunctionParseHelpers.h" -#include "EasingEquations.hpp" //Included from cpp to separate just visually maths equations from framework +#include "EasingEquations.hpp" //Included from cpp to separate just visually maths equations from framework // For easing functions that require more parameters than time (like amplitude, period, overshot) class CComplexEasingFunction { -public: // All public since it's only an internal class +public: // All public since it's only an internal class enum eType { In = 0, @@ -113,7 +113,7 @@ class CBounceEase : public CComplexEasingFunction class CEasingCurve_Impl { -public: // All public since it's only an internal class +public: // All public since it's only an internal class explicit CEasingCurve_Impl(CEasingCurve::eType a_eType); ~CEasingCurve_Impl(); @@ -124,7 +124,7 @@ class CEasingCurve_Impl CEasingCurve::eType m_eType; CEasingCurve::SimpleEasingFunction m_pSimpleFunction; CComplexEasingFunction* m_pComplexFunction; - bool m_bFinishesAtOne; // f(1) = 1? + bool m_bFinishesAtOne; // f(1) = 1? }; CEasingCurve_Impl::CEasingCurve_Impl(CEasingCurve::eType a_eType) : m_eType(CEasingCurve::EASING_INVALID), m_pSimpleFunction(NULL), m_pComplexFunction(NULL) diff --git a/Shared/animation/CEasingCurve.h b/Shared/animation/CEasingCurve.h index 791bc8b6bb2..43013a2d8e7 100644 --- a/Shared/animation/CEasingCurve.h +++ b/Shared/animation/CEasingCurve.h @@ -75,7 +75,7 @@ class CEasingCurve void GetParams(double& a_rfPeriod, double& a_rfAmplitude, double& a_rfOvershoot) const; float ValueForProgress(float progress) const; - bool IsTargetValueFinalValue() const; // at t=1 can we use target as the final value (false for sin & cos) + bool IsTargetValueFinalValue() const; // at t=1 can we use target as the final value (false for sin & cos) protected: CEasingCurve_Impl* m_pImplementation; }; diff --git a/Shared/animation/CPositionRotationAnimation.cpp b/Shared/animation/CPositionRotationAnimation.cpp index 35cd953cb98..aff05fd4af2 100644 --- a/Shared/animation/CPositionRotationAnimation.cpp +++ b/Shared/animation/CPositionRotationAnimation.cpp @@ -81,7 +81,7 @@ void CPositionRotationAnimation::ToBitStream(NetBitStreamInterface& a_rBitStream positionSync.data.vecPosition = m_SourceValue.m_vecPosition; a_rBitStream.Write(&positionSync); - SRotationRadiansSync rotationSync(true); // RPC function used floats when join time packet didn't, let's go for float + SRotationRadiansSync rotationSync(true); // RPC function used floats when join time packet didn't, let's go for float rotationSync.data.vecRotation = m_SourceValue.m_vecRotation; a_rBitStream.Write(&rotationSync); @@ -91,7 +91,7 @@ void CPositionRotationAnimation::ToBitStream(NetBitStreamInterface& a_rBitStream a_rBitStream.WriteBit(m_bDeltaRotationMode); if (m_bDeltaRotationMode) { - rotationSync.data.vecRotation = m_DeltaValue.m_vecRotation; // We serialize DELTA + rotationSync.data.vecRotation = m_DeltaValue.m_vecRotation; // We serialize DELTA } else { @@ -116,7 +116,7 @@ CPositionRotationAnimation* CPositionRotationAnimation::FromBitStream(NetBitStre return NULL; } - CPositionRotationAnimation* pAnimation = new CPositionRotationAnimation(); // It's up to the caller do delete it if we return it + CPositionRotationAnimation* pAnimation = new CPositionRotationAnimation(); // It's up to the caller do delete it if we return it if (bResumeMode) { diff --git a/Shared/animation/CPositionRotationAnimation.h b/Shared/animation/CPositionRotationAnimation.h index f5486ae6877..5af64c48e80 100644 --- a/Shared/animation/CPositionRotationAnimation.h +++ b/Shared/animation/CPositionRotationAnimation.h @@ -65,5 +65,5 @@ class CPositionRotationAnimation : public TInterpolation static CPositionRotationAnimation* FromBitStream(NetBitStreamInterface& a_rBitStream); protected: - bool m_bDeltaRotationMode; // defines if the rotation provided is a relative rotation + bool m_bDeltaRotationMode; // defines if the rotation provided is a relative rotation }; diff --git a/Shared/animation/EasingDeclarations.hpp b/Shared/animation/EasingDeclarations.hpp index 651a6785b65..3e933949d31 100644 --- a/Shared/animation/EasingDeclarations.hpp +++ b/Shared/animation/EasingDeclarations.hpp @@ -22,4 +22,4 @@ DECLARE_EASING(InOutBounce) DECLARE_EASING(OutInBounce) DECLARE_EASING(SineCurve) -DECLARE_EASING(CosineCurve) \ No newline at end of file +DECLARE_EASING(CosineCurve) diff --git a/Shared/animation/EasingEquations.hpp b/Shared/animation/EasingEquations.hpp index 92ed2f0a573..6d6e233745d 100644 --- a/Shared/animation/EasingEquations.hpp +++ b/Shared/animation/EasingEquations.hpp @@ -35,10 +35,10 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE #include #ifndef M_PI -#define M_PI 3.14159265358979323846 + #define M_PI 3.14159265358979323846 #endif #ifndef M_PI_2 -#define M_PI_2 (M_PI / 2) + #define M_PI_2 (M_PI / 2) #endif static double easeNone(double progress) diff --git a/Shared/animation/TInterpolation.h b/Shared/animation/TInterpolation.h index 405c20d9bd6..09054ff3898 100644 --- a/Shared/animation/TInterpolation.h +++ b/Shared/animation/TInterpolation.h @@ -17,7 +17,7 @@ class TInterpolation public: TInterpolation() : m_easingCurve(CEasingCurve::Linear), m_ullStartTime(0), m_ullEndTime(0), m_ulDuration(0) {} - virtual ~TInterpolation(){}; + virtual ~TInterpolation() {}; virtual void SetSourceValue(const T& a_rValue) { @@ -67,8 +67,8 @@ class TInterpolation unsigned long long ullNow = _GetTime(); float fElapsedTime = static_cast(ullNow - m_ullStartTime); - float fAnimationTime = fElapsedTime / m_ulDuration; // Division by 0 is handled by IsRunning () - fAnimationTime = m_easingCurve.ValueForProgress(fAnimationTime); // Get the animation time to use (since it can be non linear) + float fAnimationTime = fElapsedTime / m_ulDuration; // Division by 0 is handled by IsRunning () + fAnimationTime = m_easingCurve.ValueForProgress(fAnimationTime); // Get the animation time to use (since it can be non linear) _GetValue(a_rResult, fAnimationTime); @@ -90,7 +90,7 @@ class TInterpolation } else { - float fAnimationTime = m_easingCurve.ValueForProgress(1.0); // Get the animation time to use (since it can be non linear) + float fAnimationTime = m_easingCurve.ValueForProgress(1.0); // Get the animation time to use (since it can be non linear) _GetValue(a_rResult, fAnimationTime); } } @@ -130,7 +130,7 @@ class TInterpolation T m_SourceValue; T m_TargetValue; - T m_DeltaValue; // Used for calculations, also allows some subtypes to use a different way to set delta + T m_DeltaValue; // Used for calculations, also allows some subtypes to use a different way to set delta CEasingCurve m_easingCurve; diff --git a/Shared/data/MTA San Andreas/MTA/cgui/images/version.png b/Shared/data/MTA San Andreas/MTA/cgui/images/version.png index 2dc7ffb895e..e6540782897 100644 Binary files a/Shared/data/MTA San Andreas/MTA/cgui/images/version.png and b/Shared/data/MTA San Andreas/MTA/cgui/images/version.png differ diff --git a/Shared/data/MTA San Andreas/MTA/d3dcompiler_47.maetro.dll b/Shared/data/MTA San Andreas/MTA/d3dcompiler_47.maetro.dll new file mode 100644 index 00000000000..7e41f25c508 Binary files /dev/null and b/Shared/data/MTA San Andreas/MTA/d3dcompiler_47.maetro.dll differ diff --git a/Shared/data/MTA San Andreas/MTA/locale/ar_SA/client.pot b/Shared/data/MTA San Andreas/MTA/locale/ar_SA/client.pot index 95cbb28153f..097b9a6a553 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/ar_SA/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/ar_SA/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:18\n" "Last-Translator: \n" "Language-Team: Arabic\n" "Language: ar_SA\n" @@ -17,121 +17,174 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "توجد مشاكل ÙÙŠ أثناء إعادة تشغيل MTA:SA\n\n" -"إذا استمرت المشكلة قم Ø¨ÙØªØ­ مدير المهام Ùˆ\n" -"أوق٠عملية 'gta_sa.exe' Ùˆ 'Multi Theft Auto.exe'\n\n\n" -"إعادة محاولة تشغيل MTA:SAØŸ" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "قم بتشغيل Grand Theft Auto: San Andreas ثم انقر على إعادة المحاولة.\n" +"تأكد من وجود اللعبة ÙÙŠ مجلد 'Program Files (x86)'." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "خطأ" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "جاري البحث عن GTA: San Andreas" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "لعبة MTA تعمل مسبقًا Ø¨Ø§Ù„ÙØ¹Ù„.\n\n" -"إذا تكررت المشكلة يرجى اعادة تشغيل الكمبيوتر" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "عذرًا، لم يتم العثور على اللعبة.\n" +"قم بتشغيل Grand Theft Auto: San Andreas ثم انقر على إعادة المحاولة.\n" +"تأكد من وجود اللعبة ÙÙŠ مجلد 'Program Files (x86)'." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "لعبة MTA تعمل مسبقًا Ø¨Ø§Ù„ÙØ¹Ù„.\n\n" -"هل تريد إيقاÙها؟" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "اختر مسار تثبيت Grand Theft Auto: San Andreas" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA تحتاج إلى صلاحيات المسؤول Ù„Ù„ÙˆØ¸ÙŠÙØ© التالية:\n\n" +" '%s'\n\n" +"الرجاء التأكيد ÙÙŠ Ø§Ù„Ù†Ø§ÙØ°Ø© التالية." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "خطأ ÙÙŠ تحميل الوحدة البرمجية %s !(%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "جاري نسخ Ø§Ù„Ù…Ù„ÙØ§Øª..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "تم إكمال نسخ Ø§Ù„Ù…Ù„ÙØ§Øª مبكرًا. كل شيء على مايرام." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "جاري الانتهاء..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "تم!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "تم الكش٠عن تثبيت جديد لـ s%. \n\n" +"هل تريد أن تنسخ إعداداتك من s% ØŸ" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA واجهت مشكلة ÙÙŠ ÙØªØ­ المل٠'%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA تÙقد المل٠'%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA عانت من مشكلة اثناء تحميل الموديل." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "إذا قمت بتعديل gta3.img مؤخرًا، حاول إعادة تثبيت GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA عانت من مشكلة اثناء Ø¥Ø¶Ø§ÙØ© تحسينات المركبة." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA وجدت أخطاء ÙÙŠ المل٠'%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "هل أعاد جهازك التشغيل أثناء لعب MTA:SAØŸ" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "الرجاء إيقا٠البرامج التالية قبل الاستمرار:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "تم اكتشا٠مسار وحدة غير صالح.\n" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "إصدار المل٠لا يتطابق. أعد تثبيت MTA:SA إن كنت تواجه مشاكل.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "بعض Ø§Ù„Ù…Ù„ÙØ§Øª Ù…Ùقودة. أعد تثبيت MTA:SA إذا واجهت مشاكل.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA غير متواÙقة مع \"وضع الأمان\" ÙÙŠ الويندوز.\n\n" +"الرجاء إعادة تشغيل جهازك.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "هل تواجه مشاكل ÙÙŠ تشغيل MTAØŸ \n\n" "هل تريد العودة إلى إصدار سابق؟" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" -msgstr "يبدو أن هناك مشكلة خلال تشغيل MTA:SA.\n" -"إعادة تعيين الإعدادات قد يكون الحل بعض الأحيان.\n\n" -"هل تريد إعادة تهيئة إعدادات GTA الآن؟" +msgstr "يبدو أن هناك مشكلة ÙÙŠ تشغيل MTA:SA.\n" +"إعادة ضبط إعدادات GTA قد تحل هذه المشكلة أحيانًا.\n\n" +"هل ترغب ÙÙŠ إعادة ضبط إعدادات GTA الآن؟" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "تمت إعادة تعيين إعدادات GTA.\n\n" "اضغط حسنا للاستمرار." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "لم يتم حذ٠المل٠'%s' تعذر ذلك." #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "هل لديك مشاكل ÙÙŠ تشغيل MTA:SAØŸ.\n\n" "هل تريد رؤية بعض المعلومات المساعدة على الإنترنت؟" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "هل تواجه مشاكل ÙÙŠ تشغيل MTA:SAØŸ.\n\n" "هل تود تغيير الإعداد التالي؟" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "وضع ملء الشاشة:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" -msgstr "Ù†Ø§ÙØ°Ø© بلا حدود" +msgstr "Ù†Ø§ÙØ°Ø© بلا إطار" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "هل تواجه مشاكل ÙÙŠ تشغيل MTA:SAØŸ\n\n" "جرب تعطيل جميع منتجات GTA Ùˆ MTA التالية:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,131 +192,295 @@ msgstr "تحذير\n\n" "MTA:SA ÙƒØ´ÙØª عن نشاطات غير اعتيادية.\n" "الرجاء تشغيل ÙØ­Øµ Ù…ÙƒØ§ÙØ­Ø© الÙيروسات للتأكد من أمان جهازك.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "المل٠المكتش٠هو: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "يوجد نسخة تعمل من جراند تيڤت أوتو: سان أندرياس Ø¨Ø§Ù„ÙØ¹Ù„ قيد العمل. يجب أن يتم إنهاؤها قبل تشغيل MTA:SA. هل تريد ÙØ¹Ù„ ذلك الآن؟" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "معلومات" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "هناك مشكلة ÙÙŠ إيقا٠GTA: San Andreas. إذا تكررت المشكلة، الرجاء إعادة تشغيل جهاز الكمبيوتر." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "توجد مشاكل ÙÙŠ أثناء إعادة تشغيل MTA:SA\n\n" +"إذا استمرت المشكلة قم Ø¨ÙØªØ­ مدير المهام Ùˆ\n" +"أوق٠عملية 'gta_sa.exe' Ùˆ 'Multi Theft Auto.exe'\n\n\n" +"إعادة محاولة تشغيل MTA:SAØŸ" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "خطأ" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "هناك نسخة أخرى من MTA قيد التشغيل Ø¨Ø§Ù„ÙØ¹Ù„.\n\n" +"إذا استمرت هذه المشكلة، يرجى إعادة تشغيل جهاز الكمبيوتر الخاص بك" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "هناك نسخة أخرى من MTA قيد التشغيل Ø¨Ø§Ù„ÙØ¹Ù„.\n\n" +"هل تريد إنهاؤها؟" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "مدخلات الرجستري (محرر التسجيل) Ù…Ùقودة. يرجى إعادة تثبيت ملتي تيڤت أوتو: سان أندرياس." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "المسار المثبت Ùيه لعبة GTA: San Andreas يحتوي على حرو٠غير مدعومة (Unicode). الرجاء نقل تثبيت GTA: San Andreas لمسار متواÙÙ‚ يحتوي على حرو٠(ASCII) Ùقط وإعادة تثبيت Multi Theft Auto: San Andreas من جديد." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "المسار الخاص بتثبيت 'MTA:SA' أو 'GTA: San Andreas' يحتوي على 'Ø›' (ÙØ§ØµÙ„Ø© منقوطة). \n" -"ÙÙŠ حالة مواجهة مشاكل أثناء تشغيل MTA:SAØŒ\n" -"قم بتغيير مسار التثبيت إلى مسار لا يحتوي على ÙØ§ØµÙ„Ø© منقوطة." +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "يحتوي مسار تثبيت 'MTA:SA' أو 'GTA: San Andreas' على ';' (ÙØ§ØµÙ„Ø© منقوطة).\n\n" +"إذا واجهت مشاكل عند تشغيل MTA:SAØŒ\n" +"قم بنقل تثبيت اللعبة إلى مسار لا يحتوي على ÙØ§ØµÙ„Ø© منقوطة." -#: Client/loader/MainFunctions.cpp:810 +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "تم اكتشا٠مسارات تثبيت غير صالحة." + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "ÙØ´Ù„ التشغيل. يرجى التأكد من تثبيت أحدث Ù…Ù„ÙØ§Øª البيانات بشكل صحيح." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "ÙØ´Ù„ التشغيل. الرجاء التأكد من تثبيت %s بشكل صحيح." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "ÙØ´Ù„ التشغيل. تعذر إيجاد مل٠gta_sa.exe ÙÙŠ %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "ÙØ´Ù„ التشغيل. %s موجود ÙÙŠ مجلد GTA . يرجى حذÙÙ‡ قبل المتابعة" -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "المل٠الرئيسي يحمل اسم خاطئ (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "هذا المل٠غير موقع. احتمال نشاط Ùيروسي.\n\n" -"انظر التعليمات عبر الإنترنت إذا كانت MTA لا تعمل بشكل صحيح." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "مل٠البيانات %s Ù…Ùقود. نشاط Ùيروسي محتمل.\n\n" -"ضع ÙÙŠ اعتبارك إعادة تثبيت Multi Theft Auto من أجل أمانك.\n" -"راجع التعليمات عبر الإنترنت إذا لم تعمل MTA بشكل صحيح." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "مل٠البيانات %s Ù…Ùقود. قد يكون هناك نشاط Ùيروسي محتمل." + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "مل٠%s تم تعديله. نشاط Ùيروسي محتمل.\n\n" -"ضع ÙÙŠ اعتبارك إعادة تثبيت Multi Theft Auto من أجل أمانك.\n" -"راجع التعليمات عبر الإنترنت إذا لم تعمل MTA بشكل صحيح." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "مل٠asi. موجودة ÙÙŠ مجلد التثبيت لـ 'MTA: SA' أو 'GTA: San Andreas'\n\n" -"قم بإزالة Ù…Ù„ÙØ§Øª asi. إذا كنت تواجه مشاكل مع MTA: SA." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "إصدار المل٠لا يتطابق. أعد تثبيت MTA: SA إن كنت تواجه مشاكل.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "مل٠البيانات %s تم تعديله. قد يكون هناك نشاط Ùيروسي محتمل." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "بعض Ø§Ù„Ù…Ù„ÙØ§Øª Ù…Ùقودة. أعد تثبيت MTA:SA إذا واجهت مشاكل.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "يوجد Ù…Ù„ÙØ§Øª .asi ÙÙŠ مجلد التثبيت.\n" +"قم Ø¨Ø­Ø°Ù Ù…Ù„ÙØ§Øª .asi إذا واجهت مشاكل." -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA غير متواÙقة مع \"وضع الأمان\" ÙÙŠ الويندوز.\n\n" -"الرجاء إعادة تشغيل جهازك.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "تم الكش٠عن مسارات غير صحيحة للعبة." -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "إصلاح مشاكل الإعدادات" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "حل خطأ \"elevation required\"" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "يبدو أن GTA: San Andreas لم تشغل بشكل صحيح. هل تريد إغلاقها؟" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "غير معروÙ" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "المل٠'%s' مغلق حاليًا من قبل عمليات %zu.\n\n" +"هل تريد إنهاء العمليات التالية وإكمال التحديث؟\n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "قد يكون تثبيتك تالÙًا الآن.\n\n" +"تعذر استرجاع %zu من %zu مل٠من النسخة الاحتياطية.\n\n" +"يجب عليك إعادة تثبيت Multi Theft Auto من www.multitheftauto.com أو إعادة تشغيل التحديث مع صلاحية المسؤول." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "جاري تثبيت التحديث..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "جاري استخراج Ø§Ù„Ù…Ù„ÙØ§Øª..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "لعبة MTA:SA لا يمكنها إكمال المهمة التالية:\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** ÙØ´Ù„ التشغيل بسبب خطأ ÙÙŠ معر٠الرسومات **\n\n" +"** يرجى تحديث برنامج معر٠الرسومات الخاص بك **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "** Ù†ÙØ¯Øª الذاكرة العشوائية - هذا التعطل ناتج عن قلة الذاكرة المتاحة أو تجزؤها. **" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "تثبيت Ù…Ù„ÙØ§Øª MTA:SA محدثة" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "تعذر تحديث بسبب تعارض Ø§Ù„Ù…Ù„ÙØ§Øª. الرجاء إغلاق أي برامج أخرى وإعادة المحاولة" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "لم يتم تثبيت ملتي تيڤت أوتو بشكل صحيح، الرجاء إعادة تثبيتها مرة أخرى. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "إنشاء روابط لـ GTA:SA" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "لا يمكن بدء تشغيل MTA:SA بسبب ÙØ´Ù„ نسخ ملÙ:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "لا يمكن بدء MTA:SA لأن مل٠MTA:SA غير صحيح أو Ù…Ùقود:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "نسخ Ù…Ù„ÙØ§Øª MTA:SA" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "لا يمكن تشغيل MTA:SA لأن مل٠MTA:SA غير صحيح أو Ù…Ùقود:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "تصحيح GTA:SA" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "لا يمكن تشغيل MTA:SA لأن المل٠التنÙيذي GTA:SA غير صحيح أو Ù…Ùقود:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "الرجاء التحقق من Ù…ÙƒØ§ÙØ­ الÙيروسات الخاص بك من النتائج الخاطئة، جرب Ø¥Ø¶Ø§ÙØ© استثناء للمل٠التنÙيذي Ù„ GTA:SA وأعد تشغيل MTA:SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "توليد GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "لا يمكن تشغيل MTA:SA لأن المل٠التنÙيذي GTA:SA غير صحيح أو Ù…Ùقود:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "تصحيح GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "لا يمكن تشغيل MTA:SA بسبب ÙØ´Ù„ تصحيح GTA:SA:" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "تعذر تشغيل Grand Theft Auto: San Andreas. الرجاء محاولة إعادة التشغيل، أو ÙÙŠ حال استمرار المشكلة، قم بالتواصل على العنوان www.multitheftauto.com. \n" -" [%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA لا يمكن أن يستمر لأن القرص %s ليس به مساحة كاÙية" + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "مل٠مÙقود:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "إذا ÙØ´Ù„ تشغيل MTAØŒ أعد تثبيت GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "تحديث إعدادات التثبيت" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "من المحتمل ألا تكون GTA: San Andreas قد اشتغلت بشكل صحيح. هل تريد إنهاءها؟" +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "تحديث إعدادات التواÙÙ‚" #. ///////////////////////////////////////////////////////////////////////// #. @@ -271,167 +488,167 @@ msgstr "من المحتمل ألا تكون GTA: San Andreas قد اشتغلت #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "نعم" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "لا" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "مواÙÙ‚" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "خروج" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "مساعدة" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "إلغاء" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA:SA واجهت مشكلة ما" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "معلومات ÙØ´Ù„ التشغيل" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "ضع علامة ÙÙŠ خانة الاختيار لإرسال معلومات ÙØ´Ù„ التشغيل لمطوري اللعبة باستخدام MTA باستخدام 'الإنترنت'" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "هذا Ø§Ù„ÙØ¹Ù„ سيزيد من ÙØ±ØµØ© تصليح ÙØ´Ù„ التشغيل" -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" -msgstr "هل تريد إعادة تشغيل MTA: San AndreasØŸ" +msgstr "MTA: San AndreasØŸ هل تريد إعادة تشغيل" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - تحذير" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "مسار تثبيت Grand Theft Auto: San Andreas الخاص بك يحتوي هذه Ø§Ù„Ù…Ù„ÙØ§Øª:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "هذه Ø§Ù„Ù…Ù„ÙØ§Øª غير مطلوبة وقد تتداخل مع الميزات الرسومية ÙÙŠ هذه النسخة من MTA:SA.\n\n" "ÙŠÙنصح بإزالة أو إعادة تسمية هذه Ø§Ù„Ù…Ù„ÙØ§Øª." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "ابق٠هذه Ø§Ù„Ù…Ù„ÙØ§ØªØŒ ولكن أظهر هذا التحذير ÙÙŠ التشغيل القادم" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "لا تذكرني بهذه Ø§Ù„Ù…Ù„ÙØ§Øª مرة أخرى" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "أعد تسمية هذه Ø§Ù„Ù…Ù„ÙØ§Øª من dll.* إلى dll.bak.*" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "أظهر لي هذه Ø§Ù„Ù…Ù„ÙØ§Øª" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "ألعب MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - خيارات مربكة" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "تم اكتشا٠NVidia Optimus!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "قم بتجربة كل خيار وانظر أيهم يعمل:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - NVidia القياسي" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - NVidia بديل" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Intel القياسي" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Intel بديل" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr ":إذا تشتت هذا قد يساعد" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "إذا كنت ÙØ¹Ù„ًا قد اخترت خيارًا يعمل، ÙØ¥Ù† هذا قد يساعد:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "إجبار وضع Ø§Ù„Ù†Ø§ÙØ°Ø©" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "لا تظهر ذلك مرة أخرى" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" -msgstr "ملتي تيڤت اوتو: سان أندرياس" +msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "تحذير: تعذر الكش٠عن منتج Ù„Ù…ÙƒØ§ÙØ­Ø© الÙيروسات" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -439,1109 +656,1183 @@ msgstr "MTA تعذرت الكش٠عن Ù…ÙƒØ§ÙØ­ Ùيروسات ÙÙŠ هذا ا "الÙيروسات تتداخل مع MTA وتحط من تجربة اللعب الخاصة بك.\n\n" "أضغط 'مساعدة' للمزيد من المعلومات." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "أنا قد ثبت Ù…ÙƒØ§ÙØ­ Ùيروسات مسبقًا" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "لن أثبت Ù…ÙƒØ§ÙØ­ Ùيروسات.\n" "أريد أن يصاب جهازي بالبطء." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "العطل الذي واجهته ناتج عن إساءة استخدام الذاكرة من قبل الخوادم.\n\n" +"حتى مع ØªÙˆØ§ÙØ± قدر كبير من ذاكرة الوصول العشوائي (RAM)ØŒ ÙØ¥Ù† هذه اللعبة تعمل بنظام 32 بت (x86) ولها حد أقصى لمساحة العناوين يصل إلى 3.6 جيجابايت. بعض الخوادم الغير محسنة بشكل جيد وتحتوي على العديد من التعديلات (أو حتى بعض السكربتات المكتوبة بطريقة سيئة) تؤدي إلى حدوث هذا العطل وإلى بطء اللعبة أيضًا.\n\n" +"لمزيد من المعلومات، يرجى التواصل مع مالك الخادم أو دعم MTA عبر منصة Discord الرسمية: https://discord.gg/mtasa" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "معلومات عن Ù†ÙØ§Ø° الذاكرة - MTA: San Andreas" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "جاري البحث عن Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "يرجى تشغيل Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "جاري تثبيت التحديث..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "تعذر الاتصال. الاسم المستخدم غير صالح!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "جاري استخراج Ø§Ù„Ù…Ù„ÙØ§Øª..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "تعذر الاتصال. المضي٠غير صالح!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "جاري نسخ Ø§Ù„Ù…Ù„ÙØ§Øª..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "تعذر الاتصال بـ %s ÙÙŠ Ø§Ù„Ù…Ù†ÙØ° %u!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "تم إكمال نسخ Ø§Ù„Ù…Ù„ÙØ§Øª مبكرًا. كل شيء على مايرام." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "الاتصال بـ %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "جاري الانتهاء..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "إعادة الاتصال بـ %s:%u ..." -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "تم!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "جاري الاتصال" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA تحتاج إلى صلاحيات المسؤول Ù„Ù„ÙˆØ¸ÙŠÙØ© التالية:\n\n" -" '%s'\n\n" -"الرجاء التأكيد ÙÙŠ Ø§Ù„Ù†Ø§ÙØ°Ø© التالية." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "انتهت مهلة الاتصال" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "لعبة MTA:SA لا يمكنها إكمال المهمة التالية:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "قطع الاتصال: خطأ ÙÙŠ بروتوكول غير معروÙ" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** ÙØ´Ù„ التشغيل بسبب خطأ ÙÙŠ معر٠الرسومات **\n\n" -"** يرجى تحديث برنامج معر٠الرسومات الخاص بك **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "قطع الاتصال: قطع الاتصال عن بعد" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "تثبيت Ù…Ù„ÙØ§Øª MTA:SA محدثة" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "قطع الاتصال: Ùقد الاتصال عن بعد" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "تعذر تحديث بسبب تعارض Ø§Ù„Ù…Ù„ÙØ§Øª. الرجاء إغلاق أي برامج أخرى وإعادة المحاولة" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "قطع الاتصال: أنت محظور من الدخول إلى هذا الخادم" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "قطع الاتصال: قطع الاتصال من الخادم" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "قطع الاتصال: تم Ùقد الاتصال بالخادم" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "قطع الاتصال: تم Ø±ÙØ¶ الاتصال" -#: Client/loader/CInstallManager.cpp:561 +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "لم يتم تثبيت ملتي تيڤت أوتو بشكل صحيح، الرجاء إعادة تثبيتها مرة أخرى. %s" +msgid "No such mod installed (%s)" +msgstr "لا يوجد mod Ù…ÙØ´Ø§Ø¨Ù‡ Ù…ÙØ«Ø¨Øª (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "إنشاء روابط لـ GTA:SA" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "استجابة خادم سيئة (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "لا يمكن بدء تشغيل MTA:SA بسبب ÙØ´Ù„ نسخ ملÙ:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "استجابة خادم سيئة (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "لا يمكن بدء MTA:SA لأن مل٠MTA:SA غير صحيح أو Ù…Ùقود:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "العربية" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "نسخ Ù…Ù„ÙØ§Øª MTA:SA" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "مشغول" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "لا يمكن تشغيل MTA:SA لأن مل٠MTA:SA غير صحيح أو Ù…Ùقود:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "لا يمكن التحقق من التحديثات الآن" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "تصحيح GTA:SA" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "مطلوب MTA:SA %s" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "لا يمكن تشغيل MTA:SA لأن المل٠التنÙيذي GTA:SA غير صحيح أو Ù…Ùقود:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "هناك نسخة محدثة من MTA:SA %s مطلوبة من أجل الدخول إلى الخادم المختار.\n\n" +"هل تود تنزيل وتثبيت MTA:SA %s ØŸ" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "الرجاء التحقق من Ù…ÙƒØ§ÙØ­ الÙيروسات الخاص بك من النتائج الخاطئة، جرب Ø¥Ø¶Ø§ÙØ© استثناء للمل٠التنÙيذي Ù„ GTA:SA وأعد تشغيل MTA:SA." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "هل تريد تشغيل MTA:SA %s والدخول إلى هذا الخادم؟" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "توليد GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "لا يمكن الاتصال ÙÙŠ هذا الوقت.\n\n" +"يرجى المحاولة لاحقًا." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "لا يمكن تشغيل MTA:SA لأن المل٠التنÙيذي GTA:SA غير صحيح أو Ù…Ùقود:" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "جاري الاتصال" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "تصحيح GTA:SA" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "الرجاء الإنتظار..." -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "لا يمكن تشغيل MTA:SA بسبب ÙØ´Ù„ تصحيح GTA:SA:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "جاري التحقق" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA لا يمكن أن يستمر لأن القرص %s ليس به مساحة كاÙية" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "التحقق من التحديثات" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "مل٠مÙقود:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "لا يوجد تحديث مطلوب" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "إذا ÙØ´Ù„ تشغيل MTAØŒ أعد تثبيت GTA:SA" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "جاري التنزيل" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "تحديث إعدادات التثبيت" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "قيد الانتظار..." -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "تحديث إعدادات التواÙÙ‚" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "تحديث الزامي" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "غير معروÙ" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "للدخول إلى هذا الخادم، يجب عليك تحديث MTA.\n\n" +"هل تريد التحديث الآن؟" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "المل٠'%s' مغلق حاليًا من قبل عمليات %zu.\n\n" -"هل تريد إنهاء العمليات التالية وإكمال التحديث؟\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "تحديث اختياري" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "قد يكون تثبيتك تالÙًا الآن.\n\n" -"تعذر استرجاع %zu من %zu مل٠من النسخة الاحتياطية.\n\n" -"يجب عليك إعادة تثبيت Multi Theft Auto من www.multitheftauto.com أو إعادة تشغيل التحديث مع صلاحية المسؤول." +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "الخادم يوصي بالتحديث، ولكنه ليس إجباري.\n\n" +"هل تريد التحديث الآن؟" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "ابدأ Grand Theft Auto: San Andreas.\n" -"تم وضع اللعبة ÙÙŠ مجلد ' Program Files (x86)'." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "التحديث غير Ù…ØªÙˆÙØ± حاليًا.\n\n" +"يرجى التحقق من www.multitheftauto.com" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "جاري البحث عن GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "خطأ أثناء Ø§Ù„Ø­ÙØ¸" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "عذرًا، لم يتم العثور على اللعبة.\n" -"قم بتشغيل لعبة Grand Theft Auto: San Andreas ثم اضغط إعادة المحاولة.\n" -"تأكد من أن اللعبة موجودة ÙÙŠ مجلد 'Program Files (x86)'.\n" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "تعذَر إنشاء الملÙ." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "اختر مسار تثبيت Grand Theft Auto: San Andreas" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "خطأ أثناء التنزيل" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "خطأ ÙÙŠ تحميل الوحدة البرمجية %s !(%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "يبدو أن المل٠الذي تم تنزيله غير صحيح." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "تم الكش٠عن تثبيت جديد لـ s%. \n\n" -"هل تريد أن تنسخ إعداداتك من s% ØŸ" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "لسبب ما." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA واجهت مشكلة ÙÙŠ ÙØªØ­ المل٠'%s'" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "اكتمل التنزيل" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA تÙقد المل٠'%s'." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr "- مشكلة غير Ù…Ø¹Ø±ÙˆÙØ© ÙÙŠ _DialogUpdateResult" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA عانت من مشكلة اثناء تحميل الموديل." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "Ù…Ù„ÙØ§Øª مخصصة GTA:SA" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "إذا قمت بتعديل gta3.img مؤخرًا، حاول إعادة تثبيت GTA:SA." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "مواÙÙ‚" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA عانت من مشكلة اثناء Ø¥Ø¶Ø§ÙØ© تحسينات المركبة." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "خطأ" + +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "بعض Ù…Ù„ÙØ§Øª MTA:SA Ù…Ùقودة. \n\n\n" +"يرجى إعادة تثبيت MTA:SA" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA وجدت أخطاء ÙÙŠ المل٠'%s'" +msgid "%3d %% completed" +msgstr "اكتمل %3d %%" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "هل تمت إعادة تشغيل جهاز الكمبيوتر الخاص بك عند لعب MTA: SAØŸ" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"بإنتظار إستجابة من الخادم - %-3d" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "الرجاء إيقا٠البرامج التالية قبل الاستمرار:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ مساعدة ÙÙŠ الأوامر ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "طلبات الموقع الإلكتروني" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* الوقت الآن %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "يطلب الخادم المواقع الإلكترونية الآتية من أجل تحميلها (لاحقاً):" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "الاتصال: الشبكة غير جاهزة، الرجاء الانتظار لحظات" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "لا تقم أبدًا بإدخال معلومات حساسة لحمايتها من التعرّض للسرقة" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "تصحيح: تركيبة الأمر بالشكل الآتي: '[<كلمة المرور> <الاسم>] <Ø§Ù„Ù…Ù†ÙØ°> <الخادم> connect'" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "تذكر اختياري" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "الاتصال: خطأ ÙÙŠ رقم Ø§Ù„Ù…Ù†ÙØ°" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "سماح" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "الاتصال: جاري الاتصال بـ %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Ø±ÙØ¶" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "الاتصال: تعذر الاتصال بـ %s:%u!" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "القائمة الرئيسية" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "الاتصال: ÙØ´Ù„ ÙÙŠ إلغاء تحميل المود الحالي" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "أنت تستخدم نسخة تجريبية! هذه نسخة بناء Ùقط لا يمكن من خلالها الاتصال بالخوادم العامة!" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "إعادة الاتصال: الشبكة غير متاحة حاليًا، يرجى الانتظار" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "لن تتلقى MTA تحديثات على نظامي التشغيل XP Ùˆ Vista بعد يوليو 2019.\n\n" -"يرجى تحديث ويندوز للعب على أحدث الخوادم." +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "إعادة الاتصال: رقم Ø§Ù„Ù…Ù†ÙØ° خاطئ" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "سيؤدي هذا الإجراء إلى قطع اتصالك بالخادم الحالي.\n\n" -"هل أنت متأكد من رغبتك ÙÙŠ قطع الاتصال؟" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "إعادة الاتصال: جاري الاتصال بـ %s:%u..." -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "تحذير انقطع الاتصال" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "إعادة الاتصال: تعذر الاتصال بـ %s:%u!" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "معلومات" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "تمت إعادة الاختصارات Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ© لـ GTA" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "العربية" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "تم Ø­ÙØ¸ مل٠الإعدادات" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* الرقم التسلسلي (السيريال) الخاص بك هو : %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "الإعدادات" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "لعب جماعي" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "الÙيديو" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "التأثيرات" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "الصوت" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "الأزرار" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "التحكم" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "الواجهة" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Ù…ØªØµÙØ­ الويب" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "متقدم" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "استعادة الإعدادات Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠØ©" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "حساسية Ø§Ù„ÙØ£Ø±Ø©:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "حساسية التصويب العمودي:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "إعدادات Ø§Ù„ÙØ£Ø±Ø©" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "عكس Ø§Ù„ÙØ£Ø±Ù‡ بشكل رأسي" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "توجيه مع Ø§Ù„ÙØ£Ø±Ù‡" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "طيران مع Ø§Ù„ÙØ£Ø±Ø©" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "إعدادات عصا التحكم" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "إعدادات التحكم القياسية (Ø§Ù„ÙØ£Ø±Ø© + لوحة Ø§Ù„Ù…ÙØ§ØªÙŠØ­)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "التحكم الكلاسيكي (عصا التحكم)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "المنطقة الميتة" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "التشبع" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "استعمل قائمة 'الأزرار' لأزرار عصا التحكم." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "العصا اليسرى" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "العصا اليمنى" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "الوصÙ" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "Ø§Ù„Ù…ÙØªØ§Ø­" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "Ù…ÙØªØ§Ø­ بديل" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "الاسم المستعار:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Ø­ÙØ¸ كلمات مرور الخوادم" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "تحديث تلقائي Ù„Ù…ØªØµÙØ­ الخوادم" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "السماح Ø¨Ø±ÙØ¹ لقطة من الشاشة" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "السماح بالأصوات الخارجية" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "إظهار Ù†Ø§ÙØ°Ø© التنزيل دائمًا" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "السماح بالاتصال بـ Discord Rich Presence" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" -msgstr "" +msgstr "السماح بعرض حالة GTA:SA خلال اللعب على Steam" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "Ø­ÙØ¸ الصور الملتقطة بكاميرا السلاح ÙÙŠ مجلد GTA San Andreas User Files" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "اطلب التأكيد قبل قطع الاتصال بالخادم عبر القائمة الرئيسية" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "إستخدام Ù…Ù„ÙØ§Øª معدلة لـ GTA:SA" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "إعدادات عرض الخريطة" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Ø§Ù„Ø´ÙØ§Ùية:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "دقة الصورة:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "1024 x 1024 (Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "حجم الصوت:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "شدة الصوت لـ الراديو:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "مستوى أصوات التأثيرات:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "مستوى أصوات MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "مستوى صوت المايك:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "وضع التشغيل:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "عام" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "خيارات الراديو" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "موازن صوت الراديو" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "التشغيل التلقائي للراديو" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "خيارات أصوات المستخدم" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "راديو" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "عشوائي" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "تسلسلي" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Ø§Ù„ÙØ­Øµ التلقائي Ù„Ù…Ù„ÙØ§Øª الوسائط" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "إعدادات الكتم" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "كتم جميع الأصوات عند تصغير اللعبة" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "كتم صوت الراديو عند تصغير اللعبة" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "كتم جميع المؤثرات الصوتية عند تصغير اللعبة" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "كتم أصوات MTA عند تصغير اللعبة" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "كتم صوت المايك عند تصغير اللعبة" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "الجودة:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "مجال الرؤية:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Ù…Ø³Ø§ÙØ© الرسومات:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "السطوع:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "جودة التأثيرات:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "الترشيح متباين الخواص:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "معالجة الحواÙ:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "نسبة Ø§Ù„Ø§Ø±ØªÙØ§Ø¹ إلى العرض:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "وضع Ø§Ù„Ù†Ø§ÙØ°Ø©" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "إدراك الـ DPI" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "قياسي" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "بلا حدود Ù„Ù„Ø­ÙØ§Ø¸ على الدقة" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "رسم الخرائط" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "المزامنة الرأسية" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Ù…Ù†Ø­ÙØ¶Ø©" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "متوسطة" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Ù…Ø±ØªÙØ¹Ø©" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Ù…Ø±ØªÙØ¹Ø© جدًا" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "إيقاÙ" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "تلقائي" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD يطابق نسبة العرض إلى Ø§Ù„Ø¥Ø±ØªÙØ§Ø¹" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "أبعاد الظلال" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "تأثير العشب" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "توهج الظل \"الضباب\"" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "دخان" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "ظلال الشخصيات الديناميكية" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "ضبابية الحركة" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "إنعكاسات المطر" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "تصغير ملئ الشاشة" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "تمكين الجهاز من تحديد الحوار" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "إظهار الدقات الغير آمنة" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "عرض المركبات دائمًا Ø¨ØªÙØ§ØµÙŠÙ„ عالية" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "عرض الشخصيات دائمًا Ø¨ØªÙØ§ØµÙŠÙ„ عالية" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "غاما:" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "التباين:" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "التشبع:" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "تطبيق التعديلات ÙÙŠ وضع Ø§Ù„Ù†Ø§ÙØ°Ø©" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "تطبيق التعديلات ÙÙŠ وضع ملء الشاشة" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "تمكين الاتصال بالمواقع الخارجية" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "تمكين Javascript ÙÙŠ المواقع الخارجية" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" -msgstr "تمكين ÙˆØ¸ÙŠÙØ© بطاقة العرض" +msgstr "تمكين العرض باستخدام وحدة معالجة الرسوميات" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "لائحة سوداء خاصة" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "ادخل نطاقًا (مثلًا google.com)" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "حظر" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "نطاق(دومين)" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "إزالة النطاق" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "قائمة بيضاء مخصصة" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "سماح" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "متنوعات" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "تحميل سريع لملابس CJ:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "سرعة Ø§Ù„Ù…ØªØµÙØ­:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "اتصال واحد:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "شعار الرزم:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "حركة التقدم:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "أولوية العمل:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "إعداد التصحيح:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "استخدام الذاكرة العشوائية:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "نوع بنية التحديث:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "تثبيت التحديثات المهمة:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Ù…ÙØ¹Ù„" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "بطيء جدًا" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "سريع" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "عادي" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "أعلى من العادي" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "اﻷدنى" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "أقصى" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "التواÙÙ‚ مع ويندوز 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "ألوان 16-بت" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "إصلاح Ø§Ù„ÙØ£Ø±Ø©" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Ù…Ù„ÙØ§Øª موارد العميل:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "العرض ÙÙŠ المستكشÙ" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" -msgstr "تعيين ارتباط المعالج CPU 0 لتحسين أداء اللعبة" +msgstr "اضبط ارتباط المعالج على 0 لتحسين أداء اللعبة" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "المحدث التلقائي" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "التحقق من وجود تحديث الآن" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "ستتغير بعض الإعدادات عند إعادة تشغيل MTA ÙÙŠ المرة القادمة" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "هل تريد إعادة التشغيل الآن؟" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "يلزم إعادة التشغيل" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "بعض الإعدادات ستتغير عند قطع الاتصال من الخادم الحالي" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "هل تريد قطع الاتصال الآن؟" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "يلزم قطع الاتصال" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "لم يتم العثور على عصا التحكم- تحقق الاتصال وأعد تشغيل اللعبة" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "ربط المحور" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "حرك المحور للربط، أو اضغط Escape للإزالة" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "اللغة:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "المظهر:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "إعدادات مسبقة:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "الدردشة" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "تعيين" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "الألوان" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "التصميم" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "الخيارات" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "خلÙية الدردشة" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "نص المحادثة" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "إدخال الخلÙية" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "نص الإدخال" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "الأسطر:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "الحجم:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "العرض: " -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "الحجم" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "بعد" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "إلى" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "ثانية" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "بهوت" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "تلاشي المحادثات القديمة" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Ø£Ùقي:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "عمودي:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "إتجاه النص:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "الإزاحة على محور X:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "الإزاحة على محور Y:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "موقع" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "يسار" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "الوسط" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "يمين" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "الأعلى" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "الأسÙÙ„" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "الخط" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Ø¥Ø®ÙØ§Ø¡ الخلÙية عند عدم الكتابة" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "تكملة تلقائية للإسم المستعار عند إستخدام زر \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "السماح للخادم بعمل وميض Ù„Ù„Ù†Ø§ÙØ°Ø©" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "السماح بالإشعارات المصغرة" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "إظهار خط خارجي باللون الأسود/أبيض لنص الدردشة" @@ -1549,112 +1840,116 @@ msgstr "إظهار خط خارجي باللون الأسود/أبيض لنص ا #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "إضغط على الزر الذي تريد ربطه، أو اضغط Esc للمسح" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "ربط زر أساسي" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "ربط زر ثانوي" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "إعدادات GTA SA بـ التحكم" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "إعدادات متعدد اللاعبين" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "اسمك المستعار يحتوي على حرو٠ممنوعة!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "القائمة الرئيسية" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "ÙÙŠ اللعبة" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "أحمر:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "أخضر:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "أزرق:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Ø§Ù„Ø´ÙØ§Ùية:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "اللون" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "معاينة" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "يرجى قطع الاتصال من بالخادم قبل تغيير اللغة" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "يرجى قطع الاتصال عن الخادم قبل تغيير الشخصية" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "الظلال الحجمية من الممكن أن تسبب بطئ للنظام.\n\n" "هل انت متأكد بأنك تريد ØªÙØ¹ÙŠÙ„ها؟" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "تحذير بالنسبة للأداء" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Ø±ÙØ¹ لقطة من الشاشة قد تكون إلزامية لبعض الخوادم لأسباب تتعلق Ø¨Ù…ÙƒØ§ÙØ­Ø© الغش.\n\n" "(مربع الدردشة وواجهة اللعبة مستبعدتان من اللقطة)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "معلومات عن Ø±ÙØ¹ صورة الشاشة" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "بعض النصوص(السكربتات) ربما تقوم بتشغيل اصوات, كالراديو مثلاً عن طريق الإنترنت.\n\n" "تعطيل هذا الخيار ربما يقلل من إستهلاك الإنترنت.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "الأصوات الخارجية" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "يبدو أنك Ù…ÙØ¹Ù„ خيار الاتصال بالديسكورد.\n" -"هل ترغب بالسماح بمشاركة بياناته للخوادم؟\n\n" -"يتضمن ذلك المعر٠الخاص بك." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "المواÙقة على السماح بمشاركة بياناتك" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1664,11 +1959,7 @@ msgstr "بعض Ø§Ù„Ù…Ù„ÙØ§Øª ÙÙŠ مسار لعبة GTA:SA معدل عليها "ولكن، Ø§Ù„Ù…Ù„ÙØ§Øª المعدل عليها مسبقًا محظورة من قبل الكثير من الخوادم.\n\n" "هل أنت متأكد بأنك تريد استخدامهم؟" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "Ù…Ù„ÙØ§Øª مخصصة GTA:SA" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1678,552 +1969,253 @@ msgstr "ميزة معر٠الـDPI هي حالياً تجريبية Ùˆ\n" "ربما تواجه مشاكل رسومية ÙÙŠ حالة إستخدام هذه الميزة.\n\n" "هل أنت متأكد بأنك تريد استخدام هذه الميزة؟" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "ميزة قيد التجريب" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "لا ينصح بتعطيل هذا الخيار إلا ÙÙŠ حال مواجهتك لمشاكل ÙÙŠ الأداء.\n\n" "هل أنت متأكد من رغبتك ÙÙŠ تعطيله؟" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "الرجاء إدخال إسم مستعار" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "الرجاء إدخال الإسم المستعار لاستخدامه ÙÙŠ اللعبة.\n" "وسيكون هذا الاسم عند الاتصال Ùˆ اللعب ÙÙŠ الخادم. " -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "خاصية تجريبية جداً." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "توق٠الشك بوجود Ø§Ø®ØªÙ„Ø§ÙØ§Øª CJ (يستخدم 65MB أكثر RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "المودمات القديمة قد تتطلب سرعة مسح أبطأ" -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "التحول إلى استخدام اتصال واحد Ùقط عند تنزيل." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "وضع علامة على حزام الشبكة لمساعدة مزود خدمة الإنترنت ÙÙŠ التعر٠على حركة MTA." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "دوار التحميل الظاهر أسÙÙ„ الشاشة" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "حدد Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ Ø¯Ø§Ø¦Ù…Ø§Ù‹. (لم يتم Ø­ÙØ¸ هذا الإعداد)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "الحد الأقصى هو Ø§Ù„Ø£ÙØ¶Ù„ عادةً" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "تحديث تلقائي:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "تحديد Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠ Ø¥Ù„Ø§ إذا كنت ØªÙØ¶Ù„ تعبئة تقارير الأخطاء" -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "اختر Ø§Ù„Ø£ÙØªØ±Ø§Ø¶ÙŠ Ø­ØªÙ‰ يتم تثبيت التحديثات المهمة تلقائياً." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "ألوان 16-بت:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "ØªÙØ¹ÙŠÙ„ وضع الألوان 16 بت - ستحتاج إلى إعادة تشغيل MTA" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "إصلاح Ø§Ù„ÙØ£Ø±Ø©:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "إصلاح حركة Ø§Ù„ÙØ£Ø±Ø© - قد يتطلب إعادة تشغيل الجهاز" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" -msgstr "ارتباط المعالج التقارب CPU:" +msgstr "ارتباط المعالج:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "غير هذا الخيار Ùقط إذا كنت تواجه مشاكل ÙÙŠ الاستقرار." -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "أمر غير معرو٠أو cvar: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "مشغول" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "لا يمكن التحقق من التحديثات الآن" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "مطلوب MTA:SA %s" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "هناك نسخة محدثة من MTA:SA %s مطلوبة من أجل الدخول إلى الخادم المختار.\n\n" -"هل تود تنزيل وتثبيت MTA:SA %s ØŸ" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "هل تريد تشغيل MTA:SA %s والدخول إلى هذا الخادم؟" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "لا يمكن الدخول ÙÙŠ هذا الوقت. \n\n" -"الرجاء المحاولة لاحقاً." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "جاري الاتصال" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "الرجاء الإنتظار..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "جاري التحقق" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "التحقق من التحديثات" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "لا يوجد تحديث مطلوب" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "جاري التحميل" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "قيد الانتظار..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "تحديث الزامي" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "للدخول إلى هذا الخادم، يجب عليك تحديث MTA.\n\n" -"هل تريد التحديث الآن؟" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "تحديث اختياري" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "الخادم يوصي بالتحديث، ولكنه ليس إجباري.\n\n" -"هل تريد التحديث الآن؟" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "التحديث غير Ù…ØªÙˆÙØ± حاليًا.\n\n" -"يرجى التحقق من www.multitheftauto.com" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "خطأ أثناء Ø§Ù„Ø­ÙØ¸" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "تعذَر إنشاء الملÙ." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "خطأ أثناء التحميل" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "يبدو أن المل٠الذي تم تنزيله غير صحيح." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "لسبب ما." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "تم الانتهاء من التحميل" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "- مشكلة غير Ù…Ø¹Ø±ÙˆÙØ© ÙÙŠ _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "مواÙÙ‚" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "خطأ" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "بعض Ù…Ù„ÙØ§Øª MTA:SA Ù…Ùقودة. \n\n\n" -"يرجى إعادة تثبيت MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "اكتمل %3d %%" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"بإنتظار إستجابة من الخادم - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "تعذر الاتصال. الاسم المستخدم غير صالح!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "تعذر الاتصال. المضي٠غير صالح!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "تعذر الاتصال بـ %s ÙÙŠ Ø§Ù„Ù…Ù†ÙØ° %u!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "الاتصال بـ %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "إعادة الاتصال بـ %s:%u ..." - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "جاري الاتصال" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "انتهت مهلة الاتصال" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "قطع الاتصال: خطأ ÙÙŠ بروتوكول غير معروÙ" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "قطع الاتصال: قطع الاتصال عن بعد" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "قطع الاتصال: Ùقد الاتصال عن بعد" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "قطع الاتصال: أنت محظور من الدخول إلى هذا الخادم" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "قطع الاتصال: قطع الاتصال من الخادم" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "قطع الاتصال: تم Ùقد الاتصال بالخادم" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "قطع الاتصال: تم Ø±ÙØ¶ الاتصال" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "لا يوجد mod Ù…ÙØ´Ø§Ø¨Ù‡ Ù…ÙØ«Ø¨Øª (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "استجابة خادم سيئة (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "استجابة خادم سيئة (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "الأخبار" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "زيارة مقال آخر الأخبار" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "لوحة التحكم" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "خطأ ÙØ§Ø¯Ø­" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "للإصلاح، قم بإزالة هذا الملÙ:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "وحدة %s غير صحيحة!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "خطأ ÙÙŠ تنÙيذ الرابط" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "شاشة المساعدة هذه" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "الخروج من التطبيق" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "إظهار الإصدار" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "إظهار الوقت" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "إظهار معلومات اللعب (Hud)" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "إظهار جميع الأزرار المربوطة" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "يظهر رقمك التسلسلي" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "الاتصال بـ خادم (Ø§Ù„Ù…Ø¶ÙŠÙ Ø§Ù„Ù…Ù†ÙØ° الاسم المستخدم كلمة المرور)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "يتصل بخادم سابق" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "يربط بـ الزر (Ù…ÙØªØ§Ø­ التحكم)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "يزيل الربط عن الزر (الزر)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "ينسخ ضوابط اللعبة Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©" -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "يخرج لقطة من الشاشة" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "ÙŠØ­ÙØ¸ الإعدادات على الÙور" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "ينظ٠عرض تصحيح الأخطاء" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "تمرير صندوق الدردشة للأعلى" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "تمرير صندوق الدردشة للأسÙÙ„" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "ÙŠØ±ÙØ¹ معالج الأخطاء إلى الأعلى" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "ينزل معالج الأخطاء إلى الاسÙÙ„" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "يظهر إحصائيات الذاكرة" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "يظهر مخطط توقيت الإطار" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "للمطورين: إعادة تحميل الأخبار" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ مساعدة ÙÙŠ الأوامر ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* الوقت الآن %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "الاتصال: الشبكة غير جاهزة، الرجاء الانتظار لحظات" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "تصحيح: تركيبة الأمر بالشكل الآتي: '[<كلمة المرور> <الاسم>] <Ø§Ù„Ù…Ù†ÙØ°> <الخادم> connect'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "الاتصال: خطأ ÙÙŠ رقم Ø§Ù„Ù…Ù†ÙØ°" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "الاتصال: جاري الاتصال بـ %s:%u..." +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "يخرج لقطة من الشاشة" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "الاتصال: تعذر الاتصال بـ %s:%u!" +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "ÙŠØ­ÙØ¸ الإعدادات على الÙور" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "الاتصال: ÙØ´Ù„ ÙÙŠ إلغاء تحميل المود الحالي" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "ينظ٠عرض تصحيح الأخطاء" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "إعادة الاتصال: لم يتم تجهيز الشبكة بعد، ÙŠÙØ±Ø¬Ù‰ الانتظار قليلاً" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "تمرير صندوق الدردشة للأعلى" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "إعادة الاتصال: رقم Ø§Ù„Ù…Ù†ÙØ° خاطئ" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "تمرير صندوق الدردشة للأسÙÙ„" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "إعادة الاتصال: جاري الاتصال بـ %s:%u..." +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "ÙŠØ±ÙØ¹ معالج الأخطاء إلى الأعلى" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "إعادة الاتصال: تعذر الاتصال بـ %s:%u!" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "ينزل معالج الأخطاء إلى الاسÙÙ„" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "تمت إعادة الاختصارات Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ© لـ GTA" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "يظهر إحصائيات الذاكرة" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "تم Ø­ÙØ¸ مل٠الإعدادات" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "يظهر مخطط توقيت الإطار" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* الرقم التسلسلي (السيريال) الخاص بك هو : %s" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "للمطورين: إعادة تحميل الأخبار" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "تسريع المحور" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "أنت تستخدم نسخة تجريبية! هذه نسخة بناء Ùقط لا يمكن من خلالها الاتصال بالخوادم العامة!" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "مكابح المحور" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "لن تتلقى MTA تحديثات على نظامي التشغيل XP Ùˆ Vista بعد يوليو 2019.\n\n" +"يرجى تحديث ويندوز للعب على أحدث الخوادم." -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "البرمجة" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "سيؤدي هذا الإجراء إلى قطع اتصالك بالخادم الحالي.\n\n" +"هل أنت متأكد من رغبتك ÙÙŠ قطع الاتصال؟" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "المساهمون" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "تحذير انقطع الاتصال" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "تصميم اللعبة / البرمجة" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "معلومات" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "أقاليم اللغة" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "الأخبار" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "المساهمين ÙÙŠ البرمجة" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "زيارة مقال آخر الأخبار" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "شكر خاص" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "لقطة الشاشة حصلت على %d بايت، لكن المتوقع %d" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "يستخدم هذا البرنامج والمشروع المكتبات والبرامج التالية:" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "تعذر تصوير الشاشة" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "هل تريد أن ترى بعض المساعدة على الإنترنت عن هذه المشكلة؟" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "تم أخذ لقطة للشاشة : '%s'" + +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "أمر غير معرو٠أو cvar: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2398,25 +2390,56 @@ msgid "Group control backwards" msgstr "زر تحكم المجموعة للخلÙ" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "الشخصية التي قمت بإختيارها لا يمكن تحميلها, والشخصية الأساسية لا يمكن تحميلها أيضاً, الرجاء إعادة تثبيت MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "لقطة الشاشة حصلت على %d بايت، لكن المتوقع %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "هل تريد أن ترى بعض المساعدة على الإنترنت عن هذه المشكلة؟" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "تعذر تصوير الشاشة" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "لوحة التحكم" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "تم أخذ لقطة للشاشة : '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "البرمجة" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "المساهمون" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "تصميم اللعبة / البرمجة" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "أقاليم اللغة" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "المساهمين ÙÙŠ البرمجة" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "شكر خاص" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "يستخدم هذا البرنامج والمشروع المكتبات والبرامج التالية:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "تسريع المحور" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "مكابح المحور" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2424,6 +2447,69 @@ msgstr "تعذر تهئية Direct3D9.\n\n" "الرجاء التأكد من تثبيت حزمة تشغيل DirectX\n" "وآخر اصدار من حزمة خدمات وندوز بشكل صحيح." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "غير ÙØ¹Ù‘ال" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "لاعب" +msgstr[1] "لاعب" +msgstr[2] "Ù„Ø§Ø¹ÙØ¨ÙŠÙ‘Ù†" +msgstr[3] "Ù„Ø§Ø¹ÙØ¨ÙˆÙ†" +msgstr[4] "لاعبون" +msgstr[5] "لاعبون" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "ÙÙŠ" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "خادم" +msgstr[1] "خادم" +msgstr[2] "خادمان" +msgstr[3] "خوادم" +msgstr[4] "خوادم" +msgstr[5] "خوادم" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "جاري طلب قائمة الخادم الرئيسي (%lu جزء من الثانية انقضت)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "تعذر تحميل قائمة الخوادم الرئيسية." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "لا يمكن استرجاع قائمة الخادم الرئيسي." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(قائمة الخادم الاحتياطي)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "تعذر إنشاء مقبس البث عبر الشبكة المحلية (LAN)" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "لا يمكن ربط توصيل شبكة LAN-broadcast" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "جاري محاولة استكشا٠خوادم محلية" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2477,7 +2563,7 @@ msgstr "زمن الإستجابة:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "قائمة اللاعبين" @@ -2504,354 +2590,414 @@ msgstr "الدخول إلى الخادم ÙÙŠ حين إيجاد ÙØ±ØµØ© متا msgid "PLEASE ENTER SERVER PASSWORD" msgstr "الرجاء إدخال كلمة المرور الخاصة بالخادم" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "انتهت مهلة الاتصال" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "جاري الإستعلام..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "مستعرض الخوادم" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "الإنترنت" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "محلي" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Ø§Ù„Ù…ÙØ¶Ù„Ø©" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "المستخدمة حديثاً" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" -msgstr "للإتصال السريع:\n\n" -"ادخل عنوان الـ IP ÙˆØ§Ù„Ù…Ù†ÙØ° ÙÙŠ شريط العنوان.\n" -"أو أختر خادم من قائمة الخوادم المستخدمة حدياً وإضغط على 'إتصال'" +msgstr "للاتصال السريع:\n\n" +"اكتب العنوان ÙˆØ§Ù„Ù…Ù†ÙØ° ÙÙŠ شريط العنوان.\n" +"أو اختر خادمًا من قائمة المستخدمة حديثًا واضغط على 'اتصال'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "مساعدة" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "تحديث" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "أض٠إلى Ø§Ù„Ù…ÙØ¶Ù„Ø©" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" -msgstr "إتصال" +msgstr "اتصال" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "معلومات الخادم" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "البحث عن الخوادم" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "البحث عن لاعبين" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "إبدء البحث" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "حذ٠او إلغاء من الاحدث" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "بحث عن اللاعبين..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "البحث عن خوادم" -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "الاسم" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "اللاعبين" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "التأخير" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "نوع اللعب" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "يتضمن:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "ÙØ§Ø±Øº" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "ممتلئ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "مقÙÙ„" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "غير متّصل" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "إصدارات أخرى" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "الخلÙ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "جاري التحميل..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..جاري التحميل.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "لا يوجد عنوان محدد!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "بروتوكول غير معروÙ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "الرجاء إستخدام بروتوكول mtasa://!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "اسم غير صحيح! الرجاء الذهاب إلى الإعدادات ووضع اسم جديد!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." -msgstr "يجب إختيار خادم للإتصال به." +msgstr "يجب اختيار خادم للاتصال به." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "غير ÙØ¹Ù‘ال" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "مشكلة ÙÙŠ معرّ٠الرسوم" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "لاعب" -msgstr[1] "لاعب" -msgstr[2] "Ù„Ø§Ø¹ÙØ¨ÙŠÙ‘Ù†" -msgstr[3] "Ù„Ø§Ø¹ÙØ¨ÙˆÙ†" -msgstr[4] "لاعبون" -msgstr[5] "لاعبون" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "لا يمكن العثور على دقة شاشة صالحة" -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "ÙÙŠ" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "هل أنت متأكد من أنك تريد استخدام دقة الشاشة هذه؟" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "خادم" -msgstr[1] "خادم" -msgstr[2] "خادمان" -msgstr[3] "خوادم" -msgstr[4] "خوادم" -msgstr[5] "خوادم" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "ÙØ´Ù„ تهيئة game_sa" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "جاري طلب قائمة الخادم الرئيسي (%lu جزء من الثانية انقضت)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "ÙØ´Ù„ تخصيص الذاكرة" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "تعذر تحميل قائمة الخوادم الرئيسية." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "طلبات الموقع الإلكتروني" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "لا يمكن استرجاع قائمة الخادم الرئيسي." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "يطلب الخادم المواقع الإلكترونية الآتية من أجل تحميلها (لاحقاً):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(قائمة الخادم الاحتياطي)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "لا تقم أبدًا بإدخال معلومات حساسة لحمايتها من التعرّض للسرقة" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "لا يمكن ربط توصيل شبكة LAN-broadcast" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "تذكر اختياري" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "جاري محاولة استكشا٠خوادم محلية" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Ø±ÙØ¶" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "هذه النسخة منتهية" -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "انقطع الاتصال من اللعبة" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "إظهار الألقاب" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "إظهار صندوق الدردشة" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "إظهار إحصائيات الشبكة" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "ÙØªØ­ الإدخال للدردشة" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "ينقل الصوت للاعبين آخرين" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "يدخل السيارة كراكب" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "قناة الراديو التالية" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "قناة الراديو السابقة" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "ØªÙØ¹ÙŠÙ„ خريطة الرادار" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" -msgstr "يصغر خريطة اللاعب" +msgstr "تكبير خريطة اللاعب" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "تصغير خريطة اللاعب" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" -msgstr "يحرك خريطة اللاعب إلى الشمال" +msgstr "تحريك خريطة اللاعب نحو الشمال" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "تحريك خريطة اللاعب جنوبًا" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" -msgstr "يحرك خريطة اللاعب إلى الشرق" +msgstr "تحريك خريطة اللاعب نحو الشرق" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "يحرك خريطة اللاعب إلى الغرب" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" -msgstr "ÙŠÙلحق خريطة اللاعب" +msgstr "يربط خريطة اللاعب" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" -msgstr "يقلل وضوح خريطة اللاعب" +msgstr "Ø®ÙØ¶ Ø´ÙØ§Ùية خريطة اللاعب" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" -msgstr "يزيد وضوح خريطة اللاعب" +msgstr "Ø±ÙØ¹ Ø´ÙØ§Ùية خريطة اللاعب" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" -msgstr "يبدل نص مساعده خريطة اللاعب" +msgstr "يبدّل عرض نص المساعدة لخريطة اللاعب" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "إرسال رسالة للاعب محدد" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "التغيير إلى السلاح التالي خلال التواجد ÙÙŠ مركبة" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "التغيير إلى السلاح السابق خلال التواجد ÙÙŠ مركبة" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "إظهار معلومات عن الخادم الحالي" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "يعر٠المقاس لكل النصوص" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(وضع التطوير) يظهر الـ colshape" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(وضع التطوير) يطبع أرقام أصوات العالم ÙÙŠ Ù†Ø§ÙØ°Ø© التصحيح" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "خادم اللعبة" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "الموارد" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "اسم الخادم:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "كلمة المرور:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "الحد الأقصى للاعبين:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "إذاعة: " + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "الشبكة المحلية" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "المحدد" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "الكل" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "تشغيل" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "تغيير الوضع: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "التكبير: %s/%s الحركة: %s, %s, %s, %s Ø§Ù„Ø´ÙØ§Ùية: %s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "تبديل الخريطة: %s تبديل نص المساعدة: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "يتبع اللاعب" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "يتحرك بحرية" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "تقدم تحميل الخريطة:" #: Client/mods/deathmatch/logic/CTransferBox.cpp:28 msgid "Download Progress:" -msgstr "تقدم التحميل:" +msgstr "تقدم التنزيل:" #. Find our largest piece of text, so we can size accordingly #: Client/mods/deathmatch/logic/CTransferBox.cpp:42 @@ -2863,176 +3009,176 @@ msgstr "%s من %s" #: Client/mods/deathmatch/logic/CTransferBox.cpp:44 #: Client/mods/deathmatch/logic/CTransferBox.cpp:65 msgid "Disconnect to cancel download" -msgstr "اقطع الاتصال حتى تلغي التحميل" +msgstr "اقطع الاتصال لإلغاء التنزيل" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "قطع الاتصال: الاسم المستعار غير صالح" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "انقطع الاتصال من الخادم" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "قطع الاتصال: الرقم التسلسلي (السيريال) محظور.\n" "السبب: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "قطع الاتصال: أنت محظور.\n" "السبب: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "قطع الاتصال: الحساب محظور.\n" "السبب: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "قطع الاتصال: عدم تطابق الإصدار" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "قطع الاتصال: مضاد التكرار. الرجاء الانتظار دقيقة ثم الاتصال مرة اخرى." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "قطع الاتصال: الخادم من Ø£ÙØ±Ø¹ Ù…Ø®ØªÙ„ÙØ©.\n" "المعلومات: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "قطع الاتصال: نسخة سيئة.\n" "معلومات: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "قطع الاتصال: الخادم يعمل على نسخة حديثة.\n" "معلومات: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "قطع الاتصال: الخادم يعمل على نسخة قديمة.\n" "المعلومات: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "قطع الاتصال: الاسم المستعار مستخدم Ø¨Ø§Ù„ÙØ¹Ù„" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "قطع الاتصال: تعذر إنشاء عنصر اللاعب." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "قطع الاتصال: الخادم Ø±ÙØ¶ الاتصال: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "قطع الاتصال: ÙØ´Ù„ التحقق من الرقم التسلسلي" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "قطع الاتصال: الرقم التسلسلي مستخدم Ø¨Ø§Ù„ÙØ¹Ù„" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "قطع الاتصال: الاتصال غير متزامن %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "قطع الاتصال: لقد تم طردك من قبل %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "قطع الاتصال: لقد تم حظرك من قبل %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "قطع الاتصال: الخادم يتم إغلاقه أو يعاد تشغيله" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "تم طردك من اللعبة" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "هذا الخادم يتطلب مل٠gta_sa.exe غير معدل مسبقًا" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "يرجى استبدال gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "هذا الخادم لا يسمح Ø¨Ù…Ù„ÙØ§Øª D3D9.DLL معدلة مسبقًا" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "قم بإزالة مل٠D3D9.DLL من مجلد GTA ثم قم أعيد تشغيل MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "هذا الخادم لا يسمح بالأجهزة Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "هذا الخادم يتطلب أن يكون \"driver signing\" Ù…ÙØ¹Ù„ًا" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "الرجاء إعادة تشغيل جهاز الكمبيوتر" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "اكتش٠هذا الخادم أن بعض مكونات Ù…ÙƒØ§ÙØ­Ø© الغش Ù…Ùقودة" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "حاول إعادة تشغيل MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "هذا الخادم يتطلب نسخة من gta3.img Ùˆ gta_int.img غير معدل عليهم مسبقًا" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "يرجى استبدال ملÙÙŠ gta3.img Ùˆ gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "هذا الخادم لا يسمح بالمشغل Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠ Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "الرجاء التأكد من عدم وجود أي برامج أخرى تقوم بتعديل MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "الوقت المتبقي: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" @@ -3043,7 +3189,7 @@ msgstr[3] "أيام %d" msgstr[4] "أيام %d" msgstr[5] "أيام %d" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" @@ -3054,7 +3200,7 @@ msgstr[3] "ساعات %d" msgstr[4] "ساعات %d" msgstr[5] "ساعات %d" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" @@ -3065,7 +3211,7 @@ msgstr[3] "%d دقائق" msgstr[4] "%d دقيقة" msgstr[5] "%d دقيقة" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3077,296 +3223,206 @@ msgstr[4] "%d ثواني" msgstr[5] "%d ثواني" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "قطع الاتصال" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "خطأ خلال التنزيل: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "يقود جسم طائر مجهول حول" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "يتجول حول" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "يركب أمواج" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "يركب القطار ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "يحلق حول" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "يقود حول" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "يقود شاحنة الوحش حول" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "يقود دراجة رباعية حول" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "ÙŠÙ‚ÙØ² كالأرنب حول" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "يقوم بأشياء غريبة ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "يتسلق ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "يطلق نار من مركبة متحركة ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "بلوب بلوب..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "ÙŠØªÙ†ÙØ³ الماء" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "يغرق ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "ينحني للتغطية ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "يقاتل ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" -msgstr "يرمي القبضات ÙÙŠ" +msgstr "يضرب بالقبضات ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" -msgstr "يطلق على الحمقي ÙÙŠ" +msgstr "يطلق النار على الأوغاد ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" -msgstr "يطلق على" +msgstr "يطلق النار" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" -msgstr "يركب الجت باك ÙÙŠ" +msgstr "يتنقل بالطيران بحقيبة Ù†ÙØ§Ø«Ø© ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "حرÙيًا يحترق ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "يحترق ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "يسبح ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "يطÙÙˆ ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "تتم مطاردته من قبل سمك القرش" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "يختنق حتى الموت ÙÙŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "جاري الدخول إلى اللعبة ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "غير متصل؛ يرجى استخدم 'الاتصال السريع' أو استخدم الأمر connect للاتصال بخادم." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "تعذر بدء تشغيل الخادم المحلي، Ø§ÙØªØ­ وحدة التحكم console للحصول على Ø§Ù„ØªÙØ§ØµÙŠÙ„." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "خادم محلي" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "جاري تشغيل خادم محلي ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "منطقة 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "يتجول ÙÙŠ " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "تم طردك من اللعبة ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "جاري الاتصال بالخادم المحلي..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "خطأ خلال الاتصال بالخادم." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "انتهت مهلة الاتصال بالخادم المحلي. انظر إلى Console لمزيد من Ø§Ù„ØªÙØ§ØµÙŠÙ„." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "لقد Ùقد الاتصال بالخادم" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "قطع الاتصال: الخادم ممتلئ حاليًا" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "قطع الاتصال: كلمة المرور المدخلة غير صحيحة" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "ÙØ´Ù„ التحقق من العميل MTA!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "داخل خندق" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "ÙÙŠ طريقه إلى المستشÙÙ‰" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "ودع الحياة" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "يندم على قراراته" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "مات" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "خادم اللعبة" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "الموارد" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "اسم الخادم:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "كلمة المرور:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "الحد الأقصى للاعبين:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "إذاعة: " - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "الشبكة المحلية" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "المحدد" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "الكل" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "تشغيل" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "تغيير الوضع: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "التكبير: %s من %s الحركة: %sØŒ %sØŒ %sØŒ %s Ø§Ù„Ø´ÙØ§Ùية: %s من %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "ØªÙØ¹ÙŠÙ„/إلغاء الخريطة: %s ØªÙØ¹ÙŠÙ„/إلغاء نص المساعدة: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "تتبع اللاعب" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "تحرك بحرية" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "مشكلة ÙÙŠ معرّ٠الرسوم" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "لا يمكن العثور على دقة شاشة صالحة" - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "هل أنت متأكد من أنك تريد استخدام دقة الشاشة هذه؟" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "ÙØ´Ù„ تهيئة game_sa" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "اعتمادات الذاكرة ÙØ´Ù„ت" +msgid "Download error: %s" +msgstr "خطأ خلال التنزيل: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3387,11 +3443,11 @@ msgstr "خطأ بروتوكول (%u). إذا استمرت هذه المشكلة msgid "Connection error" msgstr "خطأ ÙÙŠ الاتصال." -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "لم يتم تثبيت Multi Theft Auto بشكل صحيح، الرجاء إعادة التثبيت." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "سو٠يعرض Ø§Ù„Ù…ØªØµÙØ­ الآن ØµÙØ­Ø© ويب مع بعض المعلومات للمساعدة.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/az_AZ/client.pot b/Shared/data/MTA San Andreas/MTA/locale/az_AZ/client.pot index 69701c1d97a..fe34333d6e1 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/az_AZ/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/az_AZ/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:32\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Azerbaijani\n" "Language: az_AZ\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "MTA: SA baÅŸlarkÉ™n problem yarandı\n\n" -"Problem davam edÉ™rsÉ™, Tapşırıq Menecerini açın vÉ™\n" -"'gta_sa.exe' vÉ™ 'Multi Theft Auto.exe' proseslÉ™rini dayandırın\n\n" -"MTA:SA-nı yenidÉ™n iÅŸÉ™ salmaq istÉ™yirsiniz?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "XÉ™ta" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "BaÅŸqa bir MTA tÉ™tbiqi artıq iÅŸlÉ™yir.\n\n" -"Bu problem davam edÉ™rsÉ™, zÉ™hmÉ™t olmasa kompüterinizi yenidÉ™n baÅŸladın" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "BaÅŸqa bir MTA tÉ™tbiqi artıq iÅŸlÉ™yir.\n\n" -"Dayandırmaq istÉ™yirsiniz?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Grand Theft Auto: San Andreas quraÅŸdırma qovluÄŸunu seçin" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA cari tapşırıq üçün idarəçi haqqını tÉ™lÉ™b elÉ™yir:\n\n" +"'%s'\n\n" +"ZÉ™hmÉ™t olmasa sonrakı pÉ™ncÉ™rÉ™dÉ™ icazÉ™ verin." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "%s modulunun yüklÉ™nmÉ™sindÉ™ xÉ™ta baÅŸ verdi! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "SÉ™nÉ™dlÉ™r köçürülür..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "KöçürtmÉ™ tamamlandı. HÉ™r ÅŸey yaxşıdır." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Tamamlanır..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Hazırdır!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "%s yeni quraÅŸdırma versiyası aÅŸkarlandı.\n\n" +"%s -dÉ™n seçimlÉ™rinizi köçürtmÉ™k istÉ™yirsiniz?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA '%s' sÉ™nÉ™dini oxuyanda xÉ™ta baÅŸ verdi" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA '%s' sÉ™nÉ™dini tapa bilmÉ™di." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA modeli yüklÉ™yÉ™ bilmÉ™di." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Bu yaxınlarda gta3.img sÉ™nÉ™dini dÉ™yiÅŸdirmisinizsÉ™, GTA: SA-nı yenidÉ™n quraÅŸdırmaÄŸa cÉ™hd edin." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA: SA nÉ™qliyyata yığdırma É™lavÉ™ edÉ™rkÉ™n problemlÉ™ üzləşdi." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA '%s' sÉ™nÉ™dindÉ™ xÉ™talar tapdı" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "MTA:SA oynayarkÉ™n kompüteriniz yenidÉ™n baÅŸladı?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "ZÉ™hmÉ™t olmasa davam etmÉ™zdÉ™n É™vvÉ™l tÉ™lÉ™b olunan proqramları sonlandırın:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "SÉ™nÉ™d versiyasının xÉ™tası. Problemi hÉ™ll etmÉ™k üçün MTA: SA -nı yenidÉ™n quraÅŸdırın.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "SÉ™nÉ™d versiyasının xÉ™tası. Problemi hÉ™ll etmÉ™k üçün MTA: SA -nı yenidÉ™n quraÅŸdırın.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA Windows 'TÉ™hlükÉ™sizlik rejimindÉ™' iÅŸlÉ™mir.\n\n" +"ZÉ™hmÉ™t olmasa kompüterivizi yenidÉ™n baÅŸlatın.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "MTA: SA-nı baÅŸlatmaqda çətinlik çəkirsiniz?\n\n" "KöhnÉ™ versiyaya qayıtmaq istÉ™rdinizmi?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "MTA:SA'nın baÅŸladılmasında problem yarandı.\n" "GTA seçimlÉ™rini sıfırlamaq bÉ™zÉ™n bu xÉ™tanı düzÉ™ldir.\n\n" "GTA seçimlÉ™rini indi sıfırlamaq istÉ™yirsiniz?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA seçimlÉ™ri sıfırlandı.\n\n" "Davam etmÉ™k üçün Ok'a basın." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "SÉ™nÉ™d silinÉ™ bilmÉ™di: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "MTA: SA-nı baÅŸlatmaqda çətinlik çəkirsiniz?\n\n" "Onlayn kömÉ™yÉ™ baxmaq istÉ™yirsiniz?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "MTA: SA-nı baÅŸlatmaqda çətinlik çəkirsiniz?\n\n" "Cari seçimi dÉ™yiÅŸmÉ™k istÉ™yirsiniz?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Tam ekran rejimi:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "ÇərçivÉ™siz pÉ™ncÉ™rÉ™" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "MTA:SA-nı iÅŸÉ™ salmaqda çətinlik çəkirsiniz?\n\n" "GTA vÉ™ MTA üçün bu proqramları deaktiv etmÉ™yÉ™ çalışın:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,133 +189,294 @@ msgstr "XÆBÆRDARLIQ\n\n" "MTA: SA qeyri-adi bir fÉ™aliyyÉ™t aÅŸkar etdi.\n" "ZÉ™hmÉ™t olmasa sisteminizin tÉ™hlükÉ™siz olduÄŸundan É™min olmaq üçün virus yoxlanışı elÉ™yin.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Tapılmış sÉ™nÉ™d: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Ayrı bir GTA:San Andreas tÉ™tbiqi artıq iÅŸlÉ™yir. MTA:SA-nın baÅŸladılması üçün bu tÉ™tbiqin dayandırılması tÉ™lÉ™b olunur. İndi bunu etmÉ™k istÉ™yirsiniz?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "MÉ™lumat" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "GTA: San Andreas-ı dayandırmaq alınmadı. ÆgÉ™r problem davam edÉ™rsÉ™, zÉ™hmÉ™t olmasa kompüterivizi yeniden baÅŸlatın." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "MTA: SA baÅŸlarkÉ™n problem yarandı\n\n" +"Problem davam edÉ™rsÉ™, Tapşırıq Menecerini açın vÉ™\n" +"'gta_sa.exe' vÉ™ 'Multi Theft Auto.exe' proseslÉ™rini dayandırın\n\n" +"MTA:SA-nı yenidÉ™n iÅŸÉ™ salmaq istÉ™yirsiniz?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "XÉ™ta" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "BaÅŸqa bir MTA tÉ™tbiqi artıq iÅŸlÉ™yir.\n\n" +"Bu problem davam edÉ™rsÉ™, zÉ™hmÉ™t olmasa kompüterinizi yenidÉ™n baÅŸladın" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "BaÅŸqa bir MTA tÉ™tbiqi artıq iÅŸlÉ™yir.\n\n" +"Dayandırmaq istÉ™yirsiniz?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "ReyestrdÉ™ tÉ™lÉ™b olunan yazılar yoxdur. ZÉ™hmÉ™t olmasa Multi Theft Auto: San Andreas-i yenidÉ™n qurun." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "GTA: San Andreas quraÅŸdırma qovluÄŸunda dÉ™stÉ™klÉ™nmÉ™yÉ™n (unicode) simvollar var.\n" "ZÉ™hmÉ™t olmasa Grand Theft Auto: San Andreas quraÅŸdırmavızı yalnız standart ASCII simvolları olan uyÄŸun bir yola köçürün vÉ™ Multi Theft Auto: San Andreas-ı yenidÉ™n quraÅŸdırın." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "'MTA:SA' vÉ™ ya'GTA San Andreas' quraÅŸdırma yolunda\n" -"';' (nöqtÉ™li vergül) var\n\n" -"MTA:SA-nı baÅŸladarkÉ™n problem olsa,\n" -"quraÅŸdırma(ları)nızı nöqtÉ™li vergül olmayan qovluqa daşıyın." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "BaÅŸlatmaq xÉ™tası. Æn son mÉ™lumat fayllarının düzgün quraÅŸdırıldığını yoxlayın." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "BaÅŸlatmaq xÉ™tası. ZÉ™hmÉ™t olmasa %s düzgün quraÅŸdırıldığını yoxlayın." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "BaÅŸlatmaq xÉ™tası. gta_sa.exe %s qovluÄŸunda tapılmadı." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "BaÅŸlatmaq xÉ™tası. BaÅŸlatmadan É™vvÉ™l GTA qovluÄŸundakı %s faylını silin." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Æsas sÉ™nÉ™din yanlış adı var (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Æsas sÉ™nÉ™d imzasızdır. Bunun sÉ™bÉ™bi kompüterinizdÉ™ki virus ola bilÉ™r\n\n" -"MTA düzgün iÅŸlÉ™mÉ™sÉ™, onlayn yardıma baxın." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "%s data faylı çatışmır. Mümkün virus fÉ™aliyyÉ™ti ola bilÉ™r.\n\n" -"TÉ™hlükÉ™sizliyiniz üçün Multi Theft Auto tÉ™tbiqini yenidÉ™n quraÅŸdırmağı nÉ™zÉ™rdÉ™ tutun.\n" -"MTA düzgün iÅŸlÉ™mirsÉ™, onlayn yardıma baxın." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "%s data faylı dÉ™yiÅŸdirilib. Mümkün virus fÉ™aliyyÉ™ti ola bilÉ™r.\n\n" -"TÉ™hlükÉ™sizliyiniz üçün Multi Theft Auto tÉ™tbiqini yenidÉ™n quraÅŸdırmağı nÉ™zÉ™rdÉ™ tutun.\n" -"MTA düzgün iÅŸlÉ™mirsÉ™, onlayn yardıma baxın." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "'MTA: SA' vÉ™ ya GTA: San Andreas qovluqlarında .asi uzantılı sÉ™nÉ™dlÉ™r var.\n\n" -"MTA: SA ilÉ™ problemlÉ™ qarşılaÅŸsanız .asi sÉ™nÉ™dlÉ™rini bu qovluqlardan silin." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "SÉ™nÉ™d versiyasının xÉ™tası. Problemi hÉ™ll etmÉ™k üçün MTA: SA -nı yenidÉ™n quraÅŸdırın.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "SÉ™nÉ™d versiyasının xÉ™tası. Problemi hÉ™ll etmÉ™k üçün MTA: SA -nı yenidÉ™n quraÅŸdırın.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA Windows 'TÉ™hlükÉ™sizlik rejimindÉ™' iÅŸlÉ™mir.\n\n" -"ZÉ™hmÉ™t olmasa kompüterivizi yenidÉ™n baÅŸlatın.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Konfiqurasiya problemini hÉ™ll edin" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "SÉ™hvi düzÉ™ldÉ™rkÉ™n xÉ™ta baÅŸ verdi" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "NamÉ™lum" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "'%s' faylı hal hazırda %zu proseslÉ™ri ilÉ™ kilidlÉ™nib.\n\n" +"AÅŸağıdakı proseslÉ™ri dayandırıb yenilÉ™mÉ™yÉ™ davam etmÉ™k istÉ™yirsiniz?\n\n" +"%s" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/Install.cpp:479 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Grand Theft Auto: San Andreas baÅŸlanıla bilmÉ™di. ZÉ™hmÉ™t olmasa yenidÉ™n cÉ™hd edin, vÉ™ ya problem davam edÉ™rsÉ™, www.multitheftauto.com MTA ilÉ™ É™laqÉ™ saxlayın.\n\n" -"[%s]" +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "QuraÅŸdırmanız indi xarab ola bilÉ™r.\n\n" +"%zu É™dÉ™d fayldan %zu É™dÉ™d fayl ehtiyat nüsxÉ™dÉ™n bÉ™rpa edilÉ™ bilmÉ™di.\n\n" +"Multi Theft Auto tÉ™tbiqini www.multitheftauto.com saytından yenidÉ™n quraÅŸdırmalısınız\n" +"vÉ™ ya yenilÉ™mÉ™ni inzibatçı hüquqları ilÉ™ iÅŸÉ™ salın." -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas düzgün baÅŸlana bilmÉ™di. Dayandırmaq istÉ™yirsiniz?" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "YenilÉ™mÉ™ quraÅŸdırılır..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "SÉ™nÉ™dlÉ™r çıxarılır..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA cari tapşırıqı tamamlaya bilmir:\n\n" +"'%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** XÉ™ta ekran-kartı drayverindÉ™ çıxdı **\n\n" +"** ZÉ™hmÉ™t olmasa qrafik-kartı drayverini yenilÉ™yin **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "YenilÉ™nmiÅŸ MTA:SA sÉ™nÉ™dlÉ™rini quraÅŸdır" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "YenilÉ™nmÉ™ alınmadı. ZÉ™hmÉ™t olmasa digÉ™r tÉ™tbiqlÉ™ri baÄŸlayın vÉ™ yenidÉ™n cÉ™hd edin" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto düzgün quraÅŸdırılmayıb, zÉ™hmÉ™t olmasa yenidÉ™n quraÅŸdırın. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "GTA:SA qovÅŸaqlarını yarat" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA baÅŸlamadı, çünki fayl köçürülÉ™ bilmÉ™di:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA baÅŸladıla bilmÉ™di, çünki MTA:SA faylı sÉ™hvdir vÉ™ ya yoxdur:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "MTA:SA fayllarını köçürün" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA baÅŸladıla bilmÉ™di, çünki GTA:SA faylı sÉ™hvdir vÉ™ ya yoxdur:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "GTA:SA aslılığını yamaqla" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA baÅŸladıla bilmÉ™di, çünki GTA:SA icrası sÉ™hvdir vÉ™ ya yoxdur:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "ZÉ™hmÉ™t olmasa, antivirusunuzu yanlış-müsbÉ™t aÅŸkarlama üçün yoxlayın, icra olunan GTA:SA üçün istisna É™lavÉ™ etmÉ™yÉ™ çalışın vÉ™ MTA:SA-nı yenidÉ™n baÅŸladın." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "GTA: SA yaradın" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA baÅŸladıla bilmÉ™di, çünki GTA:SA icrası yüklÉ™nÉ™ bilmir:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "GTA:SA-nı yamaqla" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA baÅŸladıla bilmÉ™di, çünki GTA:SA yamaqları uÄŸursuz oldu:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA davam edÉ™ bilmÉ™z, çünki %s diskindÉ™ kifayÉ™t qÉ™dÉ™r yer yoxdur." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "İtmiÅŸ sÉ™nÉ™d:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "MTA yüklÉ™nÉ™ bilmirsÉ™, zÉ™hmÉ™t olmasa GTA:SA-nı yenidÉ™n quraÅŸdırın" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "YüklÉ™mÉ™ seçimlÉ™rini yenilÉ™" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "UyÄŸunluq seçimlÉ™rini yenilÉ™" #. ///////////////////////////////////////////////////////////////////////// #. @@ -273,167 +484,167 @@ msgstr "GTA: San Andreas düzgün baÅŸlana bilmÉ™di. Dayandırmaq istÉ™yirsiniz? #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "BÉ™li" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Xeyr" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "Ok" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Çıx" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "KömÉ™k" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Ləğv et" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas problemlÉ™ qarşılaÅŸdı" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "ÇökmÉ™ mÉ™lumatı" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "ÇökmÉ™ mÉ™lumatını 'internet' vasitÉ™si ilÉ™ MTA inÅŸaatçılarına göndÉ™rmÉ™k üçün quÅŸ qoyun" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Bu addımla çökmÉ™ sÉ™bÉ™binin düzÉ™liÅŸ ÅŸansını artıra bilÉ™rsiniz." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "MTA: San Andreas tÉ™tbiqini yenidÉ™n baÅŸlatmaq istÉ™yirsiniz?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - XÉ™bÉ™rdarlıq" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "Sizin Grand Theft Auto: San Andreas quraÅŸdırma qovluÄŸunda göstÉ™rilmiÅŸ sÉ™nÉ™d var:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Bu sÉ™nÉ™d lazım deyil vÉ™ MTA-nın bu versiyasındakı qrafiki xüsisiyyÉ™tliklÉ™ri ilÉ™ problem yarada bilÉ™r.\n\n" "GöstÉ™rilmiÅŸ sÉ™nÉ™dinin silmÉ™niz vÉ™ya yenidÉ™n adlandırmanız tÉ™lÉ™b olunur." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "GöstÉ™rilmiÅŸ sÉ™nÉ™di iÅŸlÉ™t, vÉ™ mÉ™nÉ™ gÉ™lÉ™n dÉ™fÉ™ bu xÉ™bÉ™rdarlıqı göstÉ™r" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Bu sÉ™nÉ™d haqqında xÉ™bÉ™rdarlıq göstÉ™rmÉ™" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "SÉ™nÉ™di *.dll yerinÉ™ *.dll.bak adlandır" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "MÉ™nÉ™ sÉ™nÉ™di göstÉ™r" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "MTA:SA Oyna" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - ÇaÅŸqın seçimlÉ™r" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus aÅŸkarlandı!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "HÉ™r seçimi dÉ™nÉ™ vÉ™ nÉ™yin iÅŸlÉ™diyini gör:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Standard NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Alternativ NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Standart Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Alternativ Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Ümidsiz olsanız, bu sizÉ™ kömÉ™k edÉ™ bilÉ™r:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "İşlÉ™yÉ™n bir seçim tÉ™yin etmisinizsÉ™, bu kömÉ™k edÉ™ bilÉ™r:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "MÉ™cburi pÉ™ncÉ™rÉ™ rejimi" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "YenidÉ™n göstÉ™rmÉ™" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "XÉ™bÉ™rdarlıq: Anti-virus programı aÅŸkarlanmadı" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -441,1110 +652,1180 @@ msgstr "MTA kompüterivizdÉ™ anti-virus programı tapa bilmÉ™di.\n\n" "Viruslar MTA-ya müdaxilÉ™ edÉ™ bilÉ™r vÉ™ oyununuzu korlaya bilÉ™r.\n\n" "Daha çox mÉ™lumat üçün 'KömÉ™k' düymÉ™sinÉ™ basın." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "MÉ™nim anti-virusum var" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Anti-virüs yüklÉ™mÉ™yÉ™cÉ™m.\n" "Kompüterimin donması ve botnetin parçası omlmağını istÉ™yirÉ™m." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Grand Theft Auto San Andreas axtarılır..." -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "ZÉ™hmÉ™t olmasa Grand Theft Auto San Andreas'i baÅŸlat" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "YenilÉ™mÉ™ quraÅŸdırılır..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "BaÄŸlantı alınmadı. Yanlış lÉ™qÉ™b daxil olunub!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "SÉ™nÉ™dlÉ™r çıxarılır..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "BaÄŸlantı alınmadı. Daxil edilmiÅŸ server ünvanı yanlışdır!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "SÉ™nÉ™dlÉ™r köçürülür..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "%u portunda %s baÄŸlantısı alınmadı!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "KöçürtmÉ™ tamamlandı. HÉ™r ÅŸey yaxşıdır." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "%s:%u serverinÉ™ qoÅŸulur ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Tamamlanır..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Hazırdır!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "QOÅžULUR" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA cari tapşırıq üçün idarəçi haqqını tÉ™lÉ™b elÉ™yir:\n\n" -"'%s'\n\n" -"ZÉ™hmÉ™t olmasa sonrakı pÉ™ncÉ™rÉ™dÉ™ icazÉ™ verin." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "BaÄŸlantı vaxtı bitdi" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA cari tapşırıqı tamamlaya bilmir:\n\n" -"'%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "BaÄŸlantı kÉ™sildi: namÉ™lum protokol xÉ™tası" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** XÉ™ta ekran-kartı drayverindÉ™ çıxdı **\n\n" -"** ZÉ™hmÉ™t olmasa qrafik-kartı drayverini yenilÉ™yin **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "BaÄŸlantı kÉ™sildi: uzaqdan qoÅŸulma kÉ™sildi" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "YenilÉ™nmiÅŸ MTA:SA sÉ™nÉ™dlÉ™rini quraÅŸdır" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "BaÄŸlantı kÉ™sildi: uzaqdan qoÅŸulma itdi" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "YenilÉ™nmÉ™ alınmadı. ZÉ™hmÉ™t olmasa digÉ™r tÉ™tbiqlÉ™ri baÄŸlayın vÉ™ yenidÉ™n cÉ™hd edin" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "BaÄŸlantı kÉ™sildi: siz serverdÉ™n qadaÄŸalandınız" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "BaÄŸlantı kÉ™sildi: server ilÉ™ olan baÄŸlantı kÉ™sildi" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "BaÄŸlantı kÉ™sildi: server ilÉ™ baÄŸlantı itdi" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "BaÄŸlantı kÉ™sildi: baÄŸlantı rÉ™dd edildi" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto düzgün quraÅŸdırılmayıb, zÉ™hmÉ™t olmasa yenidÉ™n quraÅŸdırın. %s" +msgid "No such mod installed (%s)" +msgstr "(%s) adlı mod quraÅŸdırılmayıb" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "GTA:SA qovÅŸaqlarını yarat" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "ServerdÉ™n yanlış cavab(2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA baÅŸlamadı, çünki fayl köçürülÉ™ bilmÉ™di:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "ServerdÉ™n yanlış cavab(1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA baÅŸladıla bilmÉ™di, çünki MTA:SA faylı sÉ™hvdir vÉ™ ya yoxdur:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "AzÉ™rbaycanca" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "MTA:SA fayllarını köçürün" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Məşğul" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA baÅŸladıla bilmÉ™di, çünki GTA:SA faylı sÉ™hvdir vÉ™ ya yoxdur:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Hal hazırda yenilÉ™nmÉ™lÉ™ri yoxlamaq mümkün deyil" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "GTA:SA aslılığını yamaqla" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s tÉ™lÉ™b olunur" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA baÅŸladıla bilmÉ™di, çünki GTA:SA icrası sÉ™hvdir vÉ™ ya yoxdur:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Bu serverÉ™ daxil olmaq üçün MTA:SA %s tÉ™lÉ™b olunur.\n\n" +"MTA:SA %s versiyasını yüklÉ™yib quraÅŸdırmaq istÉ™yirsinizmi?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "ZÉ™hmÉ™t olmasa, antivirusunuzu yanlış-müsbÉ™t aÅŸkarlama üçün yoxlayın, icra olunan GTA:SA üçün istisna É™lavÉ™ etmÉ™yÉ™ çalışın vÉ™ MTA:SA-nı yenidÉ™n baÅŸladın." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "MTA:SA %s yi iÅŸÉ™ salıb vÉ™ bu serverÉ™ qoÅŸulmaq istÉ™rmisiniz?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "GTA: SA yaradın" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "BaÄŸlantı hal hazırda mümkün deyil.\n\n" +"ZÉ™hmÉ™t olmasa daha sonra cÉ™hd edin." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA baÅŸladıla bilmÉ™di, çünki GTA:SA icrası yüklÉ™nÉ™ bilmir:" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "QoÅŸulur" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "GTA:SA-nı yamaqla" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "ZÉ™hmÉ™t olmasa gözlÉ™yin..." -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA baÅŸladıla bilmÉ™di, çünki GTA:SA yamaqları uÄŸursuz oldu:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "YOXLANILIR" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA davam edÉ™ bilmÉ™z, çünki %s diskindÉ™ kifayÉ™t qÉ™dÉ™r yer yoxdur." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "YENİLÆNMÆ YOXLANMASI" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "İtmiÅŸ sÉ™nÉ™d:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "YenilÉ™mÉ™ tÉ™lÉ™b olunmur" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "MTA yüklÉ™nÉ™ bilmirsÉ™, zÉ™hmÉ™t olmasa GTA:SA-nı yenidÉ™n quraÅŸdırın" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "YÜKLÆNİLİR" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "YüklÉ™mÉ™ seçimlÉ™rini yenilÉ™" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "GözlÉ™nilir..." -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "UyÄŸunluq seçimlÉ™rini yenilÉ™" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "VACİB YENİLÆNMÆ" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "NamÉ™lum" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Bu serverÉ™ qoÅŸulmaq üçün MTA-nı yenilÉ™mÉ™k tÉ™lÉ™b olunur.\n\n" +"İndi yenilÉ™mÉ™k istÉ™yirsiniz?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "'%s' faylı hal hazırda %zu proseslÉ™ri ilÉ™ kilidlÉ™nib.\n\n" -"AÅŸağıdakı proseslÉ™ri dayandırıb yenilÉ™mÉ™yÉ™ davam etmÉ™k istÉ™yirsiniz?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "MÆCBURİ OLMAYAN YENİLÆMÆ" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "QuraÅŸdırmanız indi xarab ola bilÉ™r.\n\n" -"%zu É™dÉ™d fayldan %zu É™dÉ™d fayl ehtiyat nüsxÉ™dÉ™n bÉ™rpa edilÉ™ bilmÉ™di.\n\n" -"Multi Theft Auto tÉ™tbiqini www.multitheftauto.com saytından yenidÉ™n quraÅŸdırmalısınız\n" -"vÉ™ ya yenilÉ™mÉ™ni inzibatçı hüquqları ilÉ™ iÅŸÉ™ salın." +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Server klienti yenilÉ™mÉ™k tÉ™klif edir, amma bu mÉ™cburi deyil.\n\n" +"İndi yenilÉ™mÉ™k istÉ™yirsiniz?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "YADDA SAXLAMA XÆTASI" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "SÉ™nÉ™d yaradıla bilmÉ™di." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Grand Theft Auto: San Andreas quraÅŸdırma qovluÄŸunu seçin" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "YÜKLÆMÆ XÆTASI" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "%s modulunun yüklÉ™nmÉ™sindÉ™ xÉ™ta baÅŸ verdi! (%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "YüklÉ™nilmiÅŸ sÉ™nÉ™d yanlışdır." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "%s yeni quraÅŸdırma versiyası aÅŸkarlandı.\n\n" -"%s -dÉ™n seçimlÉ™rinizi köçürtmÉ™k istÉ™yirsiniz?" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "NÉ™dÉ™nsÉ™." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA '%s' sÉ™nÉ™dini oxuyanda xÉ™ta baÅŸ verdi" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "YÜKLÆNMÆ TAMAMLANDI" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA '%s' sÉ™nÉ™dini tapa bilmÉ™di." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " _DialogUpdateResult-da namÉ™lum problem" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA modeli yüklÉ™yÉ™ bilmÉ™di." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "DÆYİŞDİRİLMİŞ GTA:SA SÆNÆDLÆRİ" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Bu yaxınlarda gta3.img sÉ™nÉ™dini dÉ™yiÅŸdirmisinizsÉ™, GTA: SA-nı yenidÉ™n quraÅŸdırmaÄŸa cÉ™hd edin." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Tamam" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA: SA nÉ™qliyyata yığdırma É™lavÉ™ edÉ™rkÉ™n problemlÉ™ üzləşdi." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "XÆTA" + +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "BÉ™zi MTA:SA sÉ™nÉ™dlÉ™ri itkin düşüb.\n\n\n" +"ZÉ™hmÉ™t olmasa MTA:SA-nı tÉ™krar quraÅŸdırın" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA '%s' sÉ™nÉ™dindÉ™ xÉ™talar tapdı" +msgid "%3d %% completed" +msgstr "%3d %% tamamlandı" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "MTA:SA oynayarkÉ™n kompüteriniz yenidÉ™n baÅŸladı?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Cavab gözlÉ™nilir %-3d" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "ZÉ™hmÉ™t olmasa davam etmÉ™zdÉ™n É™vvÉ™l tÉ™lÉ™b olunan proqramları sonlandırın:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ ÆMR KÖMÆYİ ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Website istÉ™klÉ™ri" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Saat %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Server, (sonradan) yüklÉ™mÉ™ etmÉ™k üçün bu saytları tÉ™lÉ™b edir:" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "OÄžURLANMASININ QARÅžISINI ALMAÄž ÜÇÜN HEÇ VAXT VACİB MÆLUMATLARI YAZMAYIN" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "connect: QoÅŸulmaq üçün 'connect [ <ÅŸifrÉ™>]' istifadÉ™ edin" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "QÉ™rarı xatırla" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "baÄŸlantı: Yanlış port nömrÉ™si" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "İcazÉ™ ver" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "baÄŸlantı: %s:%u serverinÉ™ qoÅŸulur..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "RÉ™dd et" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "baÄŸlantı: %s:%u'e baÄŸlanılamadı!" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "Æsas menyu" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "baÄŸlantı: Cari mod sıradan çıxarıla bilmÉ™di" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Siz 'feature-brand' quruluÅŸundan istifadÉ™ edirsiniz! Bu test quruluÅŸudur, vÉ™ bu quruluÅŸla adi serverlÉ™rÉ™ qoÅŸulmaq mümkün deyil!" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA 2019-cu ilin iyul ayından sonra XP/Vista-ya yenilÉ™mÉ™lÉ™r almayacaq\n\n" -"Yeni serverlÉ™rdÉ™ oynamaq üçün Windows-u yenilÉ™yin." +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Bu sizi qoÅŸulduÄŸuvuz serverdÉ™n ayıracaq.\n\n" -"Ayrılmaq istÉ™yinizÉ™ É™minsiniz?" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "AYIRILMA XÆBÆRDARLIÄžI" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "[ARABIC]\n" -"معلومات" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "GTA-dan bütün idarÉ™etmÉ™ seçimlÉ™ri köçürüldü" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "AzÉ™rbaycanca" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Konfiqurasiya sÉ™nÉ™di yadda saxlanıldı" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Serial nömrÉ™niz: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "SEÇİMLÆR" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Multipleyer" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Video" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "SÉ™s" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "DüymÉ™lÉ™r" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "İdarÉ™etmÉ™" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "İnterfeys" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "İnternet Brauzer" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Qabaqcıl" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Sıfırla" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Siçan hÉ™ssaslığı:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Åžaquli niÅŸanlanma hÉ™ssaslığı:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Siçan seçimlÉ™ri" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Siçanı ÅŸaquli olaraq çevirin" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Siçan ilÉ™ idarÉ™ edin" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Siçan ilÉ™ uçmaq" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Joypad seçimlÉ™ri" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standart idarÉ™etmÉ™ vasitÉ™lÉ™ri (Siçan + Klaviatura)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Klassik idarÉ™etmÉ™lÉ™r (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Ölü zona" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Saturasiya" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Joypad düymÉ™lÉ™ri üçün 'DüymÉ™lÉ™r' qovluÄŸundan istifadÉ™ edin." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Sol Çubuq" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "SaÄŸ Çubuq" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "MÆLUMAT" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "DÜYMÆ" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. DÜYMÆ" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "İstifadəçi adı:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Server ÅŸifrÉ™lÉ™rini yadda saxlayın" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Server siyahısını avtomatik yenilÉ™" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Ekran ÅŸÉ™kilin çəkilmÉ™sinÉ™ icazÉ™ ver" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Xarici sÉ™slÉ™rÉ™ icazÉ™ ver" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "HÉ™miÅŸÉ™ yüklÉ™mÉ™ pÉ™ncÉ™rÉ™sini göstÉ™r" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Discord Rich Presence ilÉ™ É™laqÉ™ yaratmaÄŸa icazÉ™ verin" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" -msgstr "[ARABIC]\n" -"اسأل قبل قطع الاتصال بالخادم عند استخدام القائمة الرئيسية" +msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Xüsusi GTA:SA sÉ™nÉ™dlÉ™rinin istifadÉ™sinÉ™ icazÉ™ ver" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "XÉ™ritÉ™ göstÉ™rmÉ™ seçimlÉ™ri" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Şəffaflıq:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" -msgstr "2048 x 2048" +msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Ümumi sÉ™s:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Radio sÉ™si:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "EffektlÉ™r sÉ™si:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA sÉ™si:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Avaz sÉ™viyyÉ™si:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Oynatma rejimi:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Ümumi" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Radio seçimlÉ™ri" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Radio tarazlayıcısı" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Radionun avtomatik sazlanması" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "İstifadəçi musiqilÉ™rinin seçimlÉ™ri" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Radio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "TÉ™sadüfi" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Ardıcıl" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Avtomatik musiqi axtarışıı" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Susdurma seçimlÉ™ri" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "KiçikləşdirildikdÉ™ bütün sÉ™slÉ™ri susdurun" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "KiçikləşdirildikdÉ™ radio sÉ™slÉ™rini susdurun" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "KiçikləşdirildikdÉ™ effekt (SFX) sÉ™slÉ™ri susdurun" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "KiçikləşdirildikdÉ™ MTA-nın sÉ™slÉ™rini susdurun" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "KiçikləşdirdikdÉ™ avaz sÉ™slÉ™rini susdur" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Görüntü imkanı:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "FOV:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Render uzaqlığı:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Parlaqlıq:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Effekt keyfiyyÉ™ti:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anizatropik filtrasiya:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "YumuÅŸaltma:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Ekran nisbÉ™ti:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "PÉ™ncÉ™rÉ™ rejimi" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI hÉ™ssaslığı" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Standart" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "ÇərçivÉ™li pÉ™ncÉ™rÉ™" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Detallar(MipMap)" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "AÅŸağı" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Ortam" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "YüksÉ™k" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Çox yüksÉ™k" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "BaÄŸlı" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Avtomatik" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD-u ekran nisbÉ™tinÉ™ uyÄŸunlaÅŸdır" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Dinamik kölgÉ™lÉ™r" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Ot effekti" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "İstilik bulanması" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "TÉ™kÉ™r tüstüsü vÉ™ s" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Dinamik piyada kölgÉ™lÉ™ri" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "HÉ™rÉ™kÉ™t bulanıqlığı" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Korona yağış parıltısı" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Tam Ekran KiçiltmÉ™si" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Ekran seçimi pÉ™ncÉ™rÉ™sini aktiv et" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "TÉ™hlükÉ™li ekran nisbÉ™tlÉ™rini göstÉ™rin" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "NÉ™qliyyatları hÉ™r zaman yüksÉ™k detallaÅŸmış göstÉ™rin" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Adamları hÉ™miÅŸÉ™ yüksÉ™k detallaÅŸmış göstÉ™rin" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Ayrı saytlara icazÉ™ ver" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Ayrı saytlarda Javascript-É™ icazÉ™ ver" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" -msgstr "ØªÙØ¹ÙŠÙ„ عرض الرسومات باستخدام وحدة معالجة الرسومات GPU" +msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Bloklanmış saytlar" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Domen daxil et, mÉ™s. dabandashi.az" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Blokla" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Sayt" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Domeni sil" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "İcazÉ™li saytlar" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "İcazÉ™ ver" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Ayrı" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "CJ paltarlarının sürÉ™tli yüklÉ™nmÉ™si:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Server siyahısının yenilÉ™mÉ™ sürÉ™ti:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "TÉ™k baÄŸlantı:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Paket etiketi:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "YüklÉ™mÉ™ animasiyası:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "TÉ™tbiqin prioriteti:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Debug seçimlÉ™ri:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Video yaddaÅŸ:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "YenilÉ™mÉ™ tipi:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Vacib yenilÉ™mÉ™lÉ™ri quraÅŸdırın:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Yandır" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Çox yavaÅŸ" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Standart" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "SürÉ™tli" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normal" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Normaldan üstün" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Æn az" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Æn çox" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 uyÄŸunluÄŸu:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-bit rÉ™ng" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Siçan düzÉ™liÅŸi" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "YüklÉ™nilÉ™n resursların qovluÄŸu:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "QovluÄŸu aç" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" -msgstr "[ARABIC]\n" -"تعيين ارتباط المعالج إلى 0 لتحسين أداء اللعبة" +msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Avtomatik yenilÉ™yici" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "YenilÉ™mÉ™lÉ™ri yoxla" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "MTA-nı növbÉ™ti dÉ™fÉ™ baÅŸlatdığınızda seçimlÉ™r dÉ™yiÅŸdirilÉ™cÉ™kdir" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "İndi yenidÉ™n baÅŸlatmaq istÉ™yirsiniz?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "YENİDÆN BAÅžLATMA TÆLÆB OLUNUR" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "BÉ™zi seçimlÉ™r cari serverdÉ™n çıxdığınızdan sonra dÉ™yiÅŸilÉ™cÉ™kdir" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "ServerdÉ™n indi ayırılmaq istÉ™yirsiniz?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "AYIRILMAQ TÆLÆB OLUNUR" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad aÅŸkarlanmadı - QoÅŸulmasını yoxlayın vÉ™ oyunu yenidÉ™n baÅŸladın" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Oxlar sazlanması" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Sazlamaq üçün joystiki hÉ™rÉ™kÉ™t etdirin, vÉ™ ya silmÉ™k üçün ESC basın." -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Dil:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Üslub:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "SeçimlÉ™r:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "SöhbÉ™t" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "YüklÉ™" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "RÉ™nglÉ™r" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "SöhbÉ™t maketi" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "SeçimlÉ™r" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "SöhbÉ™tin arxa planı" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "SöhbÉ™t mÉ™tni" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "DaxiletmÉ™ arxa planı" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "DaxiletmÉ™ mÉ™tni" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "SÉ™tirlÉ™r:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Miqyas:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "En:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Ölçü" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "sonra" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "üçün" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "saniyÉ™" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Solmaq" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "MÉ™ktubların solması" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Üfüqi:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Åžaquli:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "MÉ™tn düzÉ™liÅŸi:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X SürüşdürmÉ™si:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y SürüşdürmÉ™si:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Yerləşim" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Sol" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "MÉ™rkÉ™z" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "SaÄŸ" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Üst" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Alt" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Åžrift" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Arxa planı tÉ™k daxil edÉ™ndÉ™ göstÉ™r" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "\"Tab\" düymÉ™si ilÉ™ lÉ™qÉ™blÉ™ri tamamla" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "PÉ™ncÉ™rÉ™ni işıqlandırmaq üçün serverÉ™ icazÉ™ ver" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "MÉ™ktubları bildiriÅŸ sÉ™tirindÉ™ göstÉ™r" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "SöhbÉ™t mÉ™tninin qara/aÄŸ konturu" @@ -1552,89 +1833,95 @@ msgstr "SöhbÉ™t mÉ™tninin qara/aÄŸ konturu" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "BaÄŸlamaq üçün istÉ™nilÉ™n düymÉ™ni, vÉ™ tÉ™mizlÉ™mÉ™k üçün ESC basın" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Æsas düymÉ™nin seçimi" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "ÆlavÉ™ düymÉ™nin seçimi" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA OYUN SEÇİMLÆRİ" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "MULTİPLEYER SEÇİMLÆRİ" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "LÉ™qÉ™binizdÉ™ yanlış simvollar var!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Æsas menyu" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "Oyunda" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Qırmızı:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Yaşıl:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Mavi:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Şəffaflıq:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "RÉ™ng" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "ÖnizlÉ™mÉ™" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "ZÉ™hmÉ™t olmasa, dili dÉ™yiÅŸdirmÉ™dÉ™n É™vvÉ™l serverdÉ™n ayırılın" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "ZÉ™hmÉ™t olmasa, üslüb dÉ™yiÅŸdirmÉ™dÉ™n É™vvÉ™l serverdÉ™n ayırılın" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "HÉ™cmli kölgÉ™lÉ™r sistemin yavaÅŸlamasının sÉ™bÉ™bi ola bilÉ™r.\n\n" "Onları aktivləşdirmÉ™k istÉ™diyinizÉ™ É™minsiniz?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "PERFORMANS XÆBÆRDARLIQI" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Ekran ÅŸÉ™kilin çəkilmÉ™si serverlÉ™rdÉ™ anti-çit sistemi üçün tÉ™lÉ™b olunur.\n\n" "(SöhbÉ™t pÉ™ncÉ™rÉ™si vÉ™ GUI elementlÉ™ri ÅŸÉ™kilÉ™ düşmür)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "EKRAN ÅžÆKİLİ YÜKLÆMÆK MÆLUMATI" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1642,21 +1929,21 @@ msgstr "BÉ™zi skriptlÉ™r radio kimi sÉ™slÉ™ri internetdÉ™n sÉ™slÉ™ndirÉ™ bilÉ™r. "Bu seçimi deaktiv etdikcÉ™ internet ÅŸÉ™bÉ™kÉ™nin\n" "bandwidth iÅŸlÉ™dilmÉ™sini azalda bilÉ™r.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "XARİCİ SÆSLÆR" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1666,11 +1953,7 @@ msgstr "GTA:SA qovluÄŸunda bÉ™zi sÉ™nÉ™dlÉ™r dÉ™yiÅŸdirilib.\n" "HÉ™rhalda, DÆYİŞİLMİŞ GTA:SA SÆNÆDLÆRİ SERVERLÆRİN ÇOXSUNDA QADAÄžANDIR\n\n" "DÉ™yiÅŸilmiÅŸ sÉ™nÉ™dlÉ™ri istifadÉ™ etmÉ™k istÉ™diyinizÉ™ É™minsiniz?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "DÆYİŞDİRİLMİŞ GTA:SA SÆNÆDLÆRİ" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1680,558 +1963,252 @@ msgstr "DPİ HÉ™ssalıqı eksperimental xüsusiyyÉ™tdir vÉ™\n" "Bu xüsusiyyÉ™t aktiv olduÄŸu halda siz qrafiki problemlÉ™rlÉ™r qarşılaÅŸa bilÉ™rsiniz.\n\n" "Bu xüsusiyyÉ™ti aktivləşdirmÉ™k istÉ™diyinizÉ™ É™minsiniz?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "EKSPERİMENTAL XÜSUSİYYÆT" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" -msgstr "[ARABIC]\n" -"تعطيل هذا الخيار غير مستحب إلا إذا كنت تعاني من مشاكل ÙÙŠ الأداء.\n" -"هل أنت متأكد من رغبتك ÙÙŠ تعطيله؟" +msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "LÉ™qÉ™b daxil edin" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "ZÉ™hmÉ™t olmasa, lÉ™qÉ™b daxil edin.\n" "Bu lÉ™qÉ™b qoÅŸulduÄŸunuz serverdÉ™ sizin adıvız olacaq" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "HÉ™ddindÉ™n artıq eksperimental xüsusiyyÉ™t." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "CJ paltar dÉ™yiÅŸmÉ™sinin optimallaÅŸdırılması (65MB É™lavÉ™ RAM tÉ™lÉ™b olunur)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "KöhnÉ™ modemlÉ™r yavaÅŸ yenilÉ™mÉ™ sürÉ™ti ilÉ™ daha yaxşı iÅŸlÉ™yÉ™cÉ™klÉ™r." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "YüklÉ™mÉ™ zamanı bir baÄŸlantılı qoÅŸulma iÅŸlÉ™t." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "MTA trafikinin eyniləşdirmÉ™sini asandlaÅŸdırmaq üçün internet paketlÉ™rini etiketlÉ™." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Ekranın altındakı yüklÉ™mÉ™ dairÉ™sinin animasiyası" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Susdurulmaya görÉ™ seçin. (Bu seçim yadda saxlanmır)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maksimal seçimi daha yaxşı sayılır" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Avtomatik yenilÉ™yici:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "ÆgÉ™r tÉ™k sabit versiyaları yüklÉ™mÉ™k istÉ™yirsiniszÉ™ \"Susdurmaya görÉ™\" seçin" -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Vacib yüklÉ™nmÉ™lÉ™ri avtomatik olaraq yüklÉ™mÉ™k üçün \"susdurmaya görÉ™\" seçin." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16 bit rÉ™ng:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "16-bit rÉ™nglÉ™r rejimini aktiv et. MTA-nın yenidÉ™n baÅŸlanması tÉ™lÉ™b olunur" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Siçan düzÉ™liÅŸi:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Siçan hÉ™rÉ™kÉ™tini düzÉ™lt - Kompüterin yenidÉ™n baÅŸlanması tÉ™lÉ™b olunur" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" -msgstr "[ARABIC]\n" -"ارتباط المعالج:" +msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." -msgstr "[ARABIC]\n" -"غيّر هذا Ùقط إذا كنت تواجه مشكلات ÙÙŠ الاستقرار." - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "NamÉ™lum É™mr vÉ™ ya cvar:" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Məşğul" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Hal hazırda yenilÉ™nmÉ™lÉ™ri yoxlamaq mümkün deyil" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s tÉ™lÉ™b olunur" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Bu serverÉ™ daxil olmaq üçün MTA:SA %s tÉ™lÉ™b olunur.\n\n" -"MTA:SA %s versiyasını yüklÉ™yib quraÅŸdırmaq istÉ™yirsinizmi?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "MTA:SA %s yi iÅŸÉ™ salıb vÉ™ bu serverÉ™ qoÅŸulmaq istÉ™rmisiniz?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "BaÄŸlantı hal hazırda mümkün deyil.\n\n" -"ZÉ™hmÉ™t olmasa daha sonra cÉ™hd edin." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "QoÅŸulur" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "ZÉ™hmÉ™t olmasa gözlÉ™yin..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "YOXLANILIR" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "YENİLÆNMÆ YOXLANMASI" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "YenilÉ™mÉ™ tÉ™lÉ™b olunmur" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "YÜKLÆNİLİR" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "GözlÉ™nilir..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "VACİB YENİLÆNMÆ" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Bu serverÉ™ qoÅŸulmaq üçün MTA-nı yenilÉ™mÉ™k tÉ™lÉ™b olunur.\n\n" -"İndi yenilÉ™mÉ™k istÉ™yirsiniz?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "MÆCBURİ OLMAYAN YENİLÆMÆ" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Server klienti yenilÉ™mÉ™k tÉ™klif edir, amma bu mÉ™cburi deyil.\n\n" -"İndi yenilÉ™mÉ™k istÉ™yirsiniz?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "[ARABIC]\n" -"لا يوجد تحديث متاح حالياً.\n" -"يرجى زيارة www.multitheftauto.com" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "YADDA SAXLAMA XÆTASI" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "SÉ™nÉ™d yaradıla bilmÉ™di." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "YÜKLÆMÆ XÆTASI" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "YüklÉ™nilmiÅŸ sÉ™nÉ™d yanlışdır." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "NÉ™dÉ™nsÉ™." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "YÜKLÆNMÆ TAMAMLANDI" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " _DialogUpdateResult-da namÉ™lum problem" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Tamam" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "XÆTA" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "BÉ™zi MTA:SA sÉ™nÉ™dlÉ™ri itkin düşüb.\n\n\n" -"ZÉ™hmÉ™t olmasa MTA:SA-nı tÉ™krar quraÅŸdırın" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% tamamlandı" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Cavab gözlÉ™nilir %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "BaÄŸlantı alınmadı. Yanlış lÉ™qÉ™b daxil olunub!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "BaÄŸlantı alınmadı. Daxil edilmiÅŸ server ünvanı yanlışdır!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "%u portunda %s baÄŸlantısı alınmadı!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "%s:%u serverinÉ™ qoÅŸulur ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." msgstr "" -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "QOÅžULUR" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "BaÄŸlantı vaxtı bitdi" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "BaÄŸlantı kÉ™sildi: namÉ™lum protokol xÉ™tası" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "BaÄŸlantı kÉ™sildi: uzaqdan qoÅŸulma kÉ™sildi" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "BaÄŸlantı kÉ™sildi: uzaqdan qoÅŸulma itdi" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "BaÄŸlantı kÉ™sildi: siz serverdÉ™n qadaÄŸalandınız" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "BaÄŸlantı kÉ™sildi: server ilÉ™ olan baÄŸlantı kÉ™sildi" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "BaÄŸlantı kÉ™sildi: server ilÉ™ baÄŸlantı itdi" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "BaÄŸlantı kÉ™sildi: baÄŸlantı rÉ™dd edildi" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "(%s) adlı mod quraÅŸdırılmayıb" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "ServerdÉ™n yanlış cavab(2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "ServerdÉ™n yanlış cavab(1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "XÆBÆRLÆR" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Son xÉ™bÉ™rlÉ™rÉ™ baxın" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONSOL" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Ölümcül xÉ™ta" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "DÜZÆLTMÆK ÜÇÜN BU SÆNÆDİ SİLİN:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s modulu yanlışdır!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "URL icra edÉ™rkÉ™n xÉ™ta baÅŸ verdi" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "bu yardım sÉ™hifÉ™si" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "tÉ™tbiqdÉ™n çıxır" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "versiyanı göstÉ™rir" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "vaxtı göstÉ™rir" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "interfeysi göstÉ™rir" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "bütün baÄŸlı düymÉ™lÉ™ri göstÉ™rir" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "serial nömrÉ™vizi göstÉ™rir" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "serverÉ™ qoÅŸulur (ip, port, lÉ™qÉ™b, ÅŸifrÉ™)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "É™vvÉ™lki serverÉ™ qoÅŸulur" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "düymÉ™ni baÄŸlayır (düymÉ™ idarÉ™etmÉ™)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "düymÉ™ni sıfırlayır (düymÉ™)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "standart gta seçimlÉ™rini bura köçürür" -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "ekran ÅŸÉ™kilini çəkir" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "seçimlÉ™ri saxlayır" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "debug pÉ™ncÉ™rÉ™sini tÉ™mizlÉ™yir" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "söhbÉ™t pÉ™ncÉ™rÉ™sini yuxarı sürüşdürür" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "söhbÉ™t pÉ™ncÉ™rÉ™sini aÅŸağı sürüşdürür" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "debug pÉ™ncÉ™rÉ™sini yuxarı sürüşdürür" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "debug pÉ™ncÉ™rÉ™sini aÅŸağı sürüşdürür" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "yaddaÅŸ istifadÉ™si statistikalarını göstÉ™rir" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "frame-time qrafikini göstÉ™rir" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "tÉ™rtibatçılar üçün: xÉ™bÉ™rlÉ™ri yenilÉ™" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ ÆMR KÖMÆYİ ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Saat %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "[ARABIC]\n" -"الاتصال: الشبكة غير جاهزة، يرجى الانتظار قليلاً" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "connect: QoÅŸulmaq üçün 'connect [ <ÅŸifrÉ™>]' istifadÉ™ edin" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "baÄŸlantı: Yanlış port nömrÉ™si" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "baÄŸlantı: %s:%u serverinÉ™ qoÅŸulur..." +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "ekran ÅŸÉ™kilini çəkir" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "baÄŸlantı: %s:%u'e baÄŸlanılamadı!" +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "seçimlÉ™ri saxlayır" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "baÄŸlantı: Cari mod sıradan çıxarıla bilmÉ™di" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "debug pÉ™ncÉ™rÉ™sini tÉ™mizlÉ™yir" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "[ARABIC]\n" -"إعادة الاتصال: الشبكة غير جاهزة، يرجى الانتظار قليلاً" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "söhbÉ™t pÉ™ncÉ™rÉ™sini yuxarı sürüşdürür" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "إعادة الاتصال: رقم Ø§Ù„Ù…Ù†ÙØ° غير صالح" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "söhbÉ™t pÉ™ncÉ™rÉ™sini aÅŸağı sürüşdürür" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "debug pÉ™ncÉ™rÉ™sini yuxarı sürüşdürür" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "debug pÉ™ncÉ™rÉ™sini aÅŸağı sürüşdürür" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "GTA-dan bütün idarÉ™etmÉ™ seçimlÉ™ri köçürüldü" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "yaddaÅŸ istifadÉ™si statistikalarını göstÉ™rir" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Konfiqurasiya sÉ™nÉ™di yadda saxlanıldı" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "frame-time qrafikini göstÉ™rir" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Serial nömrÉ™niz: %s" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "tÉ™rtibatçılar üçün: xÉ™bÉ™rlÉ™ri yenilÉ™" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "SürÉ™tlÉ™nmÉ™ oxu" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Siz 'feature-brand' quruluÅŸundan istifadÉ™ edirsiniz! Bu test quruluÅŸudur, vÉ™ bu quruluÅŸla adi serverlÉ™rÉ™ qoÅŸulmaq mümkün deyil!" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "ÆylÉ™c oxu" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA 2019-cu ilin iyul ayından sonra XP/Vista-ya yenilÉ™mÉ™lÉ™r almayacaq\n\n" +"Yeni serverlÉ™rdÉ™ oynamaq üçün Windows-u yenilÉ™yin." -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "ProqramlaÅŸdırma" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Bu sizi qoÅŸulduÄŸuvuz serverdÉ™n ayıracaq.\n\n" +"Ayrılmaq istÉ™yinizÉ™ É™minsiniz?" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "İştirakçılar" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "AYIRILMA XÆBÆRDARLIÄžI" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Oyun Dizaynı / Modlama" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "TÉ™rcüməçilÉ™r" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "XÆBÆRLÆR" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "DüzÉ™liÅŸ müəlliflÉ™ri" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Son xÉ™bÉ™rlÉ™rÉ™ baxın" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Xüsusi təşəkkürlÉ™r" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Ekran ÅŸÉ™kili %d bayt oldu, amma %d olması tÉ™lÉ™b olunur" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Bu proqram vÉ™ proyekt aÅŸağıdakı kitabxanalardan vÉ™ proqram tÉ™minatlarını istifadÉ™ edir:" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Ekran ÅŸÉ™kili alınmadı" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Bu problemlÉ™ baÄŸlı onlayn yardım görmÉ™k istÉ™yirsiniz?" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Ekran ÅŸÉ™kili çəkildi: '%s'" + +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "NamÉ™lum É™mr vÉ™ ya cvar:" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2406,25 +2383,56 @@ msgid "Group control backwards" msgstr "Qrup: geri" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Seçdiyiniz üslub yüklÉ™nÉ™ bilmÉ™di, hÉ™mçinin standart üslub yüklÉ™nilÉ™ bilmÉ™di. ZÉ™hmÉ™t olmasa, MTA-nı yenidÉ™n quraÅŸdırın." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Ekran ÅŸÉ™kili %d bayt oldu, amma %d olması tÉ™lÉ™b olunur" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Bu problemlÉ™ baÄŸlı onlayn yardım görmÉ™k istÉ™yirsiniz?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Ekran ÅŸÉ™kili alınmadı" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONSOL" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Ekran ÅŸÉ™kili çəkildi: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "ProqramlaÅŸdırma" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "İştirakçılar" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Oyun Dizaynı / Modlama" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "TÉ™rcüməçilÉ™r" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "DüzÉ™liÅŸ müəlliflÉ™ri" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Xüsusi təşəkkürlÉ™r" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Bu proqram vÉ™ proyekt aÅŸağıdakı kitabxanalardan vÉ™ proqram tÉ™minatlarını istifadÉ™ edir:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "SürÉ™tlÉ™nmÉ™ oxu" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "ÆylÉ™c oxu" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2432,6 +2440,61 @@ msgstr "Direct3D9 baÅŸladıla bilmÉ™di.\n\n" "ZÉ™hmÉ™t olmasa DirectX End-User Runtime vÉ™\n" "son çıxan Windows Service Pack quraÅŸdırın." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Aktiv deyil" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "oyunçu" +msgstr[1] "oyunçu" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "açıq" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "server" +msgstr[1] "server" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Server siyahısı alınır. (%lu ms keçdi)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Master-server siyahısı alınmadı." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Master-server siyahı mÉ™lumatı alına bilmÉ™di." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(YedÉ™klÉ™nmiÅŸ server siyahısı)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "LAN-yayın soketi birləşdirilÉ™ bilmÉ™di" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "LAN serverlÉ™ri axtarılı" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2485,7 +2548,7 @@ msgstr "GecikmÉ™:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Oyunçular siyahısı" @@ -2512,40 +2575,39 @@ msgstr "ServerdÉ™ yer boÅŸaldıqca qoÅŸul." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "SERVER ŞİFRÆSİNİ DAXİL EDİN" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "BaÄŸlantı vaxtı bitdi" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "SorÄŸulanır..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "SERVERLÆR PÆNCÆRÆSİ" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "İnternet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Yerli" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "SevimlilÉ™r" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Son oynananlar" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2553,298 +2615,367 @@ msgstr "TEZ QOÅžULMAQ ÜÇÜN:\n\n" "IP vÉ™ portu adres sÉ™tirinÉ™ yazın.\n" "VÉ™ ya son oynanılan server siyahısından birin seçib 'QoÅŸul'a basın" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "KÖMÆK" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "YenilÉ™" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "SevimlilÉ™rÉ™ É™lavÉ™ et" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "QoÅŸul" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Server mÉ™lumatı" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Server axtar" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Oyunçu axtar" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Axtarmağı baÅŸlat" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Oyunçu axtar..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Server axtar..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Ad" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Oyunçular" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Ping" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Oyun modu" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "GöstÉ™r:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "BoÅŸ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Dolu" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "BaÄŸlı" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Söndürülmüş" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "DigÉ™r versiyalı" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Geri" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "YüklÉ™nir..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..yüklÉ™nir.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Server ünvanı daxil edilmÉ™yib!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "NamÉ™lum protokol" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "ZÉ™hmÉ™t olmasa mtasa:// protokolundan istifadÉ™ edin!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Yanlış lÉ™qÉ™b daxil olunub! ZÉ™hmÉ™t olmasa, seçimlÉ™ri açın vÉ™ lÉ™qÉ™bi dÉ™yiÅŸin!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "QoÅŸulmaq üçün server seçin." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Aktiv deyil" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Ekran-kartı drayver xÉ™tası" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "oyunçu" -msgstr[1] "oyunçu" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "UyÄŸun görüntü imkanı tapılmadı." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "açıq" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Bu görüntü imkanını iÅŸlÉ™tmÉ™yinizdÉ™ É™minsiniz?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "server" -msgstr[1] "server" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Server siyahısı alınır. (%lu ms keçdi)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Master-server siyahısı alınmadı." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Website istÉ™klÉ™ri" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Master-server siyahı mÉ™lumatı alına bilmÉ™di." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Server, (sonradan) yüklÉ™mÉ™ etmÉ™k üçün bu saytları tÉ™lÉ™b edir:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(YedÉ™klÉ™nmiÅŸ server siyahısı)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "OÄžURLANMASININ QARÅžISINI ALMAÄž ÜÇÜN HEÇ VAXT VACİB MÆLUMATLARI YAZMAYIN" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "LAN-yayın soketi birləşdirilÉ™ bilmÉ™di" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "QÉ™rarı xatırla" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "LAN serverlÉ™ri axtarılı" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "RÉ™dd et" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Bu versiya köhnÉ™lib." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "serverdÉ™n ayırılma" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "ad etiketlÉ™rini göstÉ™r" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "söhbÉ™t pÉ™ncÉ™rÉ™sini göstÉ™r" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "baÄŸlantı statistikasını göstÉ™r" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "söhbÉ™t sÉ™tirini aç" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "sÉ™sivizi digÉ™r oyunçulara ötür" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "NÉ™qliyyat: SÉ™rniÅŸin kimi otur" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "növbÉ™ti radiostansiya" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "É™vvÉ™lki radiostansiya" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" -msgstr "ÙŠÙÙØ¹Ù‘Ù„ عرض خريطة اللاعب ( الرادار )" +msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "seçilmiÅŸ oyunçuya mÉ™ktub göndÉ™rir" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "NÉ™qliyyat: NövbÉ™ti silah" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "NÉ™qliyyat: ÆvvÉ™lki silah" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "cari server haqqında mÉ™lumat verir" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "mÉ™tnin ekranda göstÉ™rmÉ™ ölçüsünün tÉ™yin edilmÉ™si" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(İnÅŸaatcılıq rejimi) colshapelÉ™ri göstÉ™r" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(İnÅŸaatcılıq rejimi) debug pÉ™ncÉ™rÉ™sinÉ™ oyun sÉ™s id-lÉ™rini yazın" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "SERVER QURAÅžDIR" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Resurslar" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Server adı:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "ÅžifrÉ™:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Maks oyunçu:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Yayım:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Seçilib" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Hamısı" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "BaÅŸlat" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "XÉ™ritÉ™ yüklÉ™mÉ™ tÉ™rÉ™qqisi:" @@ -2865,195 +2996,195 @@ msgstr "%s'dan %s'ı" msgid "Disconnect to cancel download" msgstr "YüklÉ™mÉ™ni dayandırmaq üçün serverdÉ™n ayırılın" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "BaÄŸlantı kÉ™sildi: yanlış lÉ™qÉ™b" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "ServerdÉ™n ayırılma" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "BaÄŸlantı kÉ™sildi. Serial nömrÉ™viz qadaÄŸalanıb.\n" "SÉ™bÉ™b: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "BaÄŸlantı kÉ™sildi: Siz qadaÄŸalandını.\n" "SÉ™bÉ™b: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "BaÄŸlantı kÉ™sildi: Hesab qadaÄŸalanıb.\n" "SÉ™bÉ™b: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "BaÄŸlantı kÉ™sildi: Versiyalar uyÄŸun deyil" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "BaÄŸlantı kÉ™sildi: QoÅŸulma fludları. ZÉ™hmÉ™t olmasa bir dÉ™qiqÉ™ gözlÉ™yin, vÉ™ sonra yenidÉ™n cÉ™hd edin." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "BaÄŸlantı kÉ™sildi: Server fÉ™rqli versiyalıdır.\n" "MÉ™lumat: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "BaÄŸlantı kÉ™sildi: Yanlış versiya.\n" "MÉ™lumat: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "BaÄŸlantı kesildi: Server daha yeni versiyada iÅŸlÉ™yir.\n" "MÉ™lumat: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "BaÄŸlantı kÉ™sildi: Server daha köhnÉ™ versiyada iÅŸlÉ™yir.\n" "MÉ™lumat: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "BaÄŸlantı kÉ™sildi: Bu lÉ™qÉ™b iÅŸlÉ™nilir" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "BaÄŸlantı kÉ™sildi: Oyunçu elementi yaradıla bilmir." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "BaÄŸlantı kÉ™sildi: Server baÄŸlantını kÉ™sdi: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "BaÄŸlantı kÉ™sildi: Serial nömrÉ™sinin yoxlanışı alınmadı" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "BaÄŸlantı kÉ™sildi: BaÄŸlantı sinxronizasiya xÉ™tası%s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "BaÄŸlantı kÉ™sildi: %s tÉ™rÉ™findÉ™n tÉ™piklÉ™ndinız" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "BaÄŸlantı kÉ™sildi: %s tÉ™rÉ™findÉ™n qadaÄŸalandınız" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "BaÄŸlantı kÉ™sildi: Server söndürüldü, yada yenidÉ™n baÅŸlanır" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Sizi serverdÉ™n tÉ™piklÉ™dilÉ™r" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Bu server dÉ™yiÅŸilmÉ™miÅŸ gta_sa.exe tÉ™lÉ™b elÉ™yir" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "ZÉ™hmÉ™t olmasa gta_sa.exe sÉ™nÉ™dini dÉ™yiÅŸin" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Bu server xüsusi D3D9.DLL iÅŸlÉ™tmÉ™yÉ™ icazÉ™ vermir" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "GTA qovluÄŸundan D3D9.DLL sÉ™nÉ™dini silin, vÉ™ MTA-nı yenidÉ™n baÅŸlatın" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Bu server virtual maşınlara icazÉ™ vermir" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Bu server driver imzası qoÅŸulu olmasını tÉ™lÉ™b elÉ™yir" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "ZÉ™hmÉ™t olmasa, kompüterivizi yenidÉ™n baÅŸlatın" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Bu server itkin anti-cheat komponentlÉ™ri aÅŸkar etdi" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "MTA-nı yenidÉ™n baÅŸlatın" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Bu server dÉ™yiÅŸilmÉ™miÅŸ gta3.img vÉ™ gta_int.img tÉ™lÉ™b elÉ™yir" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "ZÉ™hmÉ™t olmasa, gta3.img yada gta_int.img sÉ™nÉ™dini dÉ™yiÅŸin" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Bu server Wine tÉ™tbiqinÉ™ icazÉ™ vermir" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "BaÅŸqa heç bir proqram MTA: SA-nı dÉ™yiÅŸdirmÉ™diyini yoxlayın" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Qalan vaxt: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d gün" msgstr[1] "%d gün" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d saat" msgstr[1] "%d saat" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d dÉ™qiqÉ™" msgstr[1] "%d dÉ™qiqÉ™" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3061,297 +3192,206 @@ msgstr[0] "%d saniyÉ™" msgstr[1] "%d saniyÉ™" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "BaÄŸlantı kÉ™sildi" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "YüklÉ™mÉ™ xÉ™tası: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "Yaxınlıqda NUO uçurdur" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "Yaxınlıqda sülÉ™nir" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "dalÄŸalarında üzür" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" -msgstr "ÙŠÙ‚ÙØ² متكرراً حول" +msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Oyuna qoÅŸulur..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "QoÅŸula bilmÉ™di; zÉ™hmÉ™t olmasa Tez QoÅŸul vÉ™ ya 'connect' kodunu iÅŸlÉ™dib bir serverÉ™ qoÅŸulun." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Yerli server baÅŸlatıla bilmÉ™di. MÉ™lumat üçün konsola baxın." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Yerli Server" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Yerli server baÅŸlanılır ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Sizi serverdÉ™n tÉ™piklÉ™dilÉ™r ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Yerli serverÉ™ qoÅŸulma gedir..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "ServerÉ™ qoÅŸularkÉ™n xÉ™ta baÅŸ verdi." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Yerli serverÉ™ qoÅŸulma vaxtı bitdi. Ætraflı mÉ™lumat üçün konsola baxın." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Server ilÉ™ baÄŸlantı itdi" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "BaÄŸlantı kÉ™sildi: server hal hazırda doludur" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "BaÄŸlantı kÉ™sildi: yanlış ÅŸifrÉ™ daxil olunub" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA klient yoxlanması alınmadı" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "QÉ™bÉ™rdi" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "SERVER QURAÅžDIR" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Resurslar" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Server adı:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "ÅžifrÉ™:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Maks oyunçu:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Yayım:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Seçilib" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Hamısı" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "BaÅŸlat" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "[ARABIC]\n" -"التكبير: %s/%s الحركة: %sØŒ %sØŒ %sØŒ %s Ø§Ù„Ø´ÙØ§Ùية: %s/%s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Ekran-kartı drayver xÉ™tası" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "UyÄŸun görüntü imkanı tapılmadı." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Bu görüntü imkanını iÅŸlÉ™tmÉ™yinizdÉ™ É™minsiniz?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "YüklÉ™mÉ™ xÉ™tası: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3372,11 +3412,11 @@ msgstr "" msgid "Connection error" msgstr "BaÄŸlantı xÉ™tası" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto düzgün quraÅŸdırılmayıb, zÉ™hmÉ™t olmasa yenidÉ™n quraÅŸdırın." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Brauzeriviz kömÉ™k mÉ™lumatı ilÉ™ bir sÉ™hifÉ™ açacaq.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/bg_BG/client.pot b/Shared/data/MTA San Andreas/MTA/locale/bg_BG/client.pot index 9e767210e24..a0a12d68c63 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/bg_BG/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/bg_BG/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:18\n" "Last-Translator: \n" "Language-Team: Bulgarian\n" "Language: bg_BG\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Проблем при реÑтартирането на MTA:SA\n\n" -"Ðко проблемът не може да бъде решен, отворете ТаÑк Мениджъра и\n" -"Ñпрете 'gta_sa.exe' и 'Multi Theft Auto.exe' процеÑите\n\n\n" -"Опитайте Ñе да пуÑнете MTA:SA отново?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Грешка" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Друга инÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð½Ð° МТРв момента Ñе изпълнÑва.\n\n" -"Ðко този проблем не може да бъде разрешен, реÑтартирайте компютъра Ñи" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Друга инÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð½Ð° МТРÑе изпълÑнва.\n\n" -"ИÑкате ли да Ñ Ñпрете?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "ПоÑочете вашата Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ð° Grand Theft Auto: San Andreas" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA има нужда от ÐдминиÑтраторÑки права, за да изпълни Ñледните задачи:\n\n" +"'%s'\n\n" +"ÐœÐ¾Ð»Ñ Ð¿Ð¾Ñ‚Ð²ÑŠÑ€Ð´ÐµÑ‚Ðµ в ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€ÐµÑ†." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Грешка при зареждането %s модул! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Копиране на файлове..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Копирането завърши по-рано. Ð’Ñичко е ОК." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Завършване..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Готово!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Ðова инÑÑ‚Ð°Ð»Ð°Ñ†Ð¸Ñ Ð½Ð° %s заÑечено.\n\n" +"ИÑкате ли да копирате вашите наÑтройки от %s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA имаше проблем Ñ Ð¾Ñ‚Ð²Ð°Ñ€Ñнето на файла '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA липÑва файла '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTa:SA имаше проблем при зареждането на модел." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Ðко наÑкоре Ñте модифицирали gta3.img, Ð¼Ð¾Ð»Ñ Ð¾Ð¿Ð¸Ñ‚Ð°Ð¹Ñ‚Ðµ преинÑталиране на GTA:Sa." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA имаше проблем при добавÑнето на подобрение към превозното ÑредÑтво." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA намери грешки в файла '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Да не би компютърът ви да Ñе е реÑтартирал при игрането на MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "ÐœÐ¾Ð»Ñ Ñпрете Ñледните програми преди да продължите:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Файловите верÑии Ñе разминават. ПреинÑталирайте MTA:Sa ако имате проблеми.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "ÐÑкои файлове липÑват. ПреинÑталирайте МТÐ:SA ако имате проблеми.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "МТÐ:SA не може да Ñе Ñработи Ñ Windows 'БезопаÑен Режим'.\n\n" +"ÐœÐ¾Ð»Ñ Ñ€ÐµÑтартирайте Ð²Ð°ÑˆÐ¸Ñ ÐºÐ¾Ð¼Ð¿ÑŽÑ‚ÑŠÑ€.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Имате проблем Ñ MTA:SA?.\n\n" "ИÑкате ли да върнете на по-Ñтара верÑиÑ?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "Изглежда, че има проблем ÑÑŠÑ Ñтартиране "ПонÑкога реÑтартирането на наÑтройките на GTA може да поправи проблема.\n\n" "ИÑкате ли да реÑтартирате GTA наÑтройките Ñега?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA наÑтройките бÑха реÑтартирани.\n\n" "ÐатиÑнете ОК за да продължите." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Файлът не е изтрит: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Имате проблеми Ñ MTA:SA?\n\n" "ИÑкате ли да видите помощ онлайн?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Имате проблем Ñ MTA:SA?.\n\n" "ИÑкате ли да промените тези наÑтройки?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Режим на пълен екран:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Прозорец без краища" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Имате проблем Ñ ÐœÐ¢Ð:SA?\n\n" "Опитайте Ñе да Ñпрете дадените продукти за GTA и МТÐ:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,128 +189,288 @@ msgstr "Ð’ÐИМÐÐИЕ\n\n" "MTA:SA заÑече Ñтранна дейноÑÑ‚.\n" "Изпълнете вируÑно Ñканиране, за да Ñе обедите, че вашата ÑиÑтема е защитена.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "ЗаÑечениÑÑ‚ файл беше: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "ИнÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð½Ð° GTA:San Andreas вече Ñе изпълÑнва. ТрÑбва да бъде ÑпрÑна преди MTA:SA да бъде Ñтартирана. ИÑкате ли да направите това Ñега?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "ИнформациÑ" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Ðевъзможно Ñпиране на GTA: San Andreas. ÐœÐ¾Ð»Ñ Ñ€ÐµÑтартирайте Ð²Ð°ÑˆÐ¸Ñ ÐºÐ¾Ð¼Ð¿ÑŽÑ‚ÑŠÑ€." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Проблем при реÑтартирането на MTA:SA\n\n" +"Ðко проблемът не може да бъде решен, отворете ТаÑк Мениджъра и\n" +"Ñпрете 'gta_sa.exe' и 'Multi Theft Auto.exe' процеÑите\n\n\n" +"Опитайте Ñе да пуÑнете MTA:SA отново?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Грешка" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Друга инÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð½Ð° МТРв момента Ñе изпълнÑва.\n\n" +"Ðко този проблем не може да бъде разрешен, реÑтартирайте компютъра Ñи" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Друга инÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð½Ð° МТРÑе изпълÑнва.\n\n" +"ИÑкате ли да Ñ Ñпрете?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "РегиÑтърни входове липÑват. ÐœÐ¾Ð»Ñ Ð¿Ñ€ÐµÐ¸Ð½Ñталирайте Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "ДиректориÑта за GTA: San Andreas Ñъдържа знаци, които не Ñе поддържат. (unicode) ÐœÐ¾Ð»Ñ Ð¿Ñ€ÐµÐ¼ÐµÑтете Grand Theft Auto: San Andreas на друго мÑÑто, коÑто Ñъдържа Ñамо ASCII знаци и преинÑталирайте Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "ДиректориÑта за 'MTA:SA' или 'GTA: San Andreas'\n" -"Ñъдържа ';'.\n\n" -"Ðко имате проблеми Ñ MTA:SA,\n" -"премеÑтете ги нÑкъде, където го нÑма този знак." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Зареждането провалено. ÐœÐ¾Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐµÑ‚Ðµ дали поÑледните дата файлове Ñа инÑталирани правилно." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Зареждането провалено. ÐœÐ¾Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐµÑ‚Ðµ дали %s е инÑталирано правилно." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Зареждането провалено. Ðе може да бъде открито gta_sa.exe в %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Зареждането провалено. %s Ñе ÑÑŠÑтои в директориÑта на GTA. ÐœÐ¾Ð»Ñ Ð¸Ð·Ñ‚Ñ€Ð¸Ð¹Ñ‚Ðµ го преди да продължите." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "ГлавниÑÑ‚ файл има неправилно име (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "ГлавниÑÑ‚ файл е неподпиÑан. Възможно вируÑно дейÑтвие.\n\n" -"Вижте помощ онлайн ако МТРне работи правилно." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 +#, c-format +msgid "Data file %s is modified. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" +msgstr "Поправи конфигурационен проблем" + +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/Install.cpp:479 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asi файловете в 'MTA:SA' или 'GTA: San Andreas' директориÑта.\n\n" -"Премахнете тези .asi файлове ако имате проблеми Ñ MTA:SA." +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "ИнÑталиране на актуализациÑ..." -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Файловите верÑии Ñе разминават. ПреинÑталирайте MTA:Sa ако имате проблеми.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Извличане на файлове..." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "ÐÑкои файлове липÑват. ПреинÑталирайте МТÐ:SA ако имате проблеми.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA не упÑÑ Ð´Ð° завърши Ñледните задачи:\n\n" +"'%s'\n" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "МТÐ:SA не може да Ñе Ñработи Ñ Windows 'БезопаÑен Режим'.\n\n" -"ÐœÐ¾Ð»Ñ Ñ€ÐµÑтартирайте Ð²Ð°ÑˆÐ¸Ñ ÐºÐ¾Ð¼Ð¿ÑŽÑ‚ÑŠÑ€.\n" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Крашът беше предизвикан от проблеми Ñ Ð³Ñ€Ð°Ñ„Ð¸Ñ‡ÐµÑките драйвъри **\n\n" +"** ÐœÐ¾Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²ÐµÑ‚Ðµ графичеÑките Ñи драйвъри **" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" -msgstr "Поправи конфигурационен проблем" +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "ИнÑталирайте обновените MTA:SA файлове" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Ðктуализирането не възможно поради файлови конфликти. ÐœÐ¾Ð»Ñ Ñпрете другите Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ опитайте" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Mutli Theft Auto не беше инÑталиран правилно, Ð¼Ð¾Ð»Ñ Ð¿Ñ€ÐµÐ¸Ð½Ñталирайте. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Коригирайте необходимата грешка" +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Ðевъзможно Ñтартиране на Grand Theft Auto: San Andreas. ÐœÐ¾Ð»Ñ Ð¾Ð¿Ð¸Ñ‚Ð°Ð¹Ñ‚Ðµ реÑтартиране или ако има проблем, поÑетете МТРв www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA не може да продължи, защото драйв %s нÑма доÑтатъчно проÑтранÑтво." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "ЛипÑващ файл:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Ðко MTA не уÑпее да зареди, Ð¼Ð¾Ð»Ñ Ð¿Ñ€ÐµÐ¸Ð½Ñталирайте GTA:SA" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas може да не е било пуÑнато правилно. ИÑкате ли да го Ñпрете?" +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Обновете инÑталиращите наÑтройки" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Обновете ÑъвмеÑтимите наÑтройки" #. ///////////////////////////////////////////////////////////////////////// #. @@ -268,166 +478,166 @@ msgstr "GTA: San Andreas може да не е било пуÑнато прав #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Да" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Ðе" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "ОК" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Изход" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Помощ" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Откажи" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas Ñрещна проблем" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° краша" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Сложете тик в тази кутийка, за да изпратите краш инфо до МТРразработчиците използвайки интернет" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Правенето на това ще увеиличи ÑˆÐ°Ð½Ñ Ñ‚Ð¾Ð·Ð¸ краш да бъде поправен." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "ИÑкате ли да реÑтартирате MTA: San Andreas ?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Внимание" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Играй MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Объркващи наÑтройки" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus заÑечен!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Пробвайте вÑички опции и вижте кое работи:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Стандартна NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Ðлтернативна NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Ðко Ñе колебаете, това може да помогне:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Режим на прозорец" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Внимание: Ðе може да Ñе заÑече анти-вируÑна програма" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -435,1102 +645,1180 @@ msgstr "МТРне уÑÐ¿Ñ Ð´Ð° заÑече анти-вируÑна прог "ВируÑите пречат на МТРда работи правилно, Ñледователно и на ваÑ.\n\n" "ÐатиÑнете 'Помощ' за повече информациÑ." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Имам инÑталирана анти-вируÑна програма" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "ÐÑма да инÑталирам анти-вируÑна програма.\n" "ИÑкам компютърът ми да работи бавно и да бъде чаÑÑ‚ от ботнет." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "ТърÑене на Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "ÐœÐ¾Ð»Ñ Ð¿ÑƒÑнете Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "ИнÑталиране на актуализациÑ..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "ÐеуÑпешно Ñвързване. ПредоÑтавен е невалиден никнейм!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Извличане на файлове..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "ÐеуÑпешно Ñвързване. ПредоÑтавен е невалиден хоÑÑ‚!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Копиране на файлове..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Свързването към %s Ñ Ð¿Ð¾Ñ€Ñ‚ %u неуÑпешно!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Копирането завърши по-рано. Ð’Ñичко е ОК." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Свързване към %s%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Завършване..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Готово!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "СВЪРЗВÐÐЕ" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA има нужда от ÐдминиÑтраторÑки права, за да изпълни Ñледните задачи:\n\n" -"'%s'\n\n" -"ÐœÐ¾Ð»Ñ Ð¿Ð¾Ñ‚Ð²ÑŠÑ€Ð´ÐµÑ‚Ðµ в ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€ÐµÑ†." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "ПроÑрочено време за връзка" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA не упÑÑ Ð´Ð° завърши Ñледните задачи:\n\n" -"'%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Връзката прекъÑната : неизвеÑтна по протокола грешка" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Крашът беше предизвикан от проблеми Ñ Ð³Ñ€Ð°Ñ„Ð¸Ñ‡ÐµÑките драйвъри **\n\n" -"** ÐœÐ¾Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²ÐµÑ‚Ðµ графичеÑките Ñи драйвъри **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Връзката прекъÑната: Връзката бе прекъÑната диÑтанционно" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "ИнÑталирайте обновените MTA:SA файлове" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Разкачени: връзката прекъÑна диÑтанционно" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Ðктуализирането не възможно поради файлови конфликти. ÐœÐ¾Ð»Ñ Ñпрете другите Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ опитайте" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Разкачени: вие Ñте баннати от този Ñървър" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Разкачени: разкачени Ñте от Ñървъра" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Разкачени: връзката ÑÑŠÑ Ñървъра Ñе загуби" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Разкачени: връзката ÑÑŠÑ Ñървъра Ñе отхвърли" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Mutli Theft Auto не беше инÑталиран правилно, Ð¼Ð¾Ð»Ñ Ð¿Ñ€ÐµÐ¸Ð½Ñталирайте. %s" +msgid "No such mod installed (%s)" +msgstr "ÐÑма такъв инÑталиран мод (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Лош отговор на Ñървъра (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Лош отговор на Ñървъра (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "българÑки" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Зает" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Ðе може да провери за Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñега" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "МТÐ:SA %s е нужен" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Ðктуализирана верÑÐ¸Ñ Ð½Ð° MTA:SA %s Ñе изиÑква, за да Ñе приÑъедините към Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ñървър.\n\n" +"ИÑкате ли да изтеглите и инÑталирате MTA:SA %s ?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "ИÑкате ли да пуÑнете MTA:SA %s и да Ñе приÑъедините към този Ñървър ?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Ðе е възможно Ñвързването в момента.\n\n" +"ÐœÐ¾Ð»Ñ Ð¾Ð¿Ð¸Ñ‚Ð°Ð¹Ñ‚Ðµ по-къÑно." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Свързване" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "ÐœÐ¾Ð»Ñ Ð¸Ð·Ñ‡Ð°ÐºÐ°Ð¹Ñ‚Ðµ..." -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "ПРОВЕРЯВÐÐЕ" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA не може да продължи, защото драйв %s нÑма доÑтатъчно проÑтранÑтво." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "ПРОВЕРКРÐРОБÐОВЛЕÐИЕ" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "ЛипÑващ файл:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "ÐÑма нужда от обновÑване" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Ðко MTA не уÑпее да зареди, Ð¼Ð¾Ð»Ñ Ð¿Ñ€ÐµÐ¸Ð½Ñталирайте GTA:SA" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "ИЗТЕГЛЯÐЕ" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Обновете инÑталиращите наÑтройки" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "чакане..." -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Обновете ÑъвмеÑтимите наÑтройки" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "ЗÐДЪЛЖИТЕЛÐО ОБÐОВЛЕÐИЕ" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "За да Ñе приÑъедините към този Ñървър трÑбва да актуализирате MTA.\n\n" +"ИÑкате ли да направите актуализациÑта Ñега ?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "ÐКТУÐЛИЗÐЦИЯ ПО ИЗБОР" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Сървърът твърди, че актуализациÑта е препоръчана, но не и задължителна.\n\n" +"ИÑкате ли да актуализирате Ñега ?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "ГРЕШКРПРИ ЗÐПÐМЕТЯВÐÐЕ" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Ðевъзможно Ñъздаване на файла." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "ПоÑочете вашата Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ð° Grand Theft Auto: San Andreas" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "ГРЕШКРПРИ ИЗТЕГЛЯÐЕ" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Грешка при зареждането %s модул! (%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "ИзтеглениÑÑ‚ файл не е правилен." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Ðова инÑÑ‚Ð°Ð»Ð°Ñ†Ð¸Ñ Ð½Ð° %s заÑечено.\n\n" -"ИÑкате ли да копирате вашите наÑтройки от %s ?" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Поради нÑкаква причина." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA имаше проблем Ñ Ð¾Ñ‚Ð²Ð°Ñ€Ñнето на файла '%s'" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "ИЗТЕГЛЯÐЕТО ЗÐВЪРШЕÐО" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA липÑва файла '%s'." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr "- Проблем в _DialogUpdateResult" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTa:SA имаше проблем при зареждането на модел." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "ПЕРСОÐÐЛИЗИРÐÐИ GTA:SA ФÐЙЛОВЕ" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Ðко наÑкоре Ñте модифицирали gta3.img, Ð¼Ð¾Ð»Ñ Ð¾Ð¿Ð¸Ñ‚Ð°Ð¹Ñ‚Ðµ преинÑталиране на GTA:Sa." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ок" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA имаше проблем при добавÑнето на подобрение към превозното ÑредÑтво." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "ГРЕШКÐ" -#: Client/loader/Utils.cpp:1631 -#, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA намери грешки в файла '%s'" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "ÐÑкои MTA:SA дата файлове липÑват.\n\n\n" +"ÐœÐ¾Ð»Ñ Ð¿Ñ€ÐµÐ¸Ð½Ñталирайте MTA:SA" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Да не би компютърът ви да Ñе е реÑтартирал при игрането на MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% завършено" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "ÐœÐ¾Ð»Ñ Ñпрете Ñледните програми преди да продължите:" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Изчакване на отговор - %-3d" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "ЗаÑвки на уебÑайта" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ ПОМОЩ ЗРКОМÐÐДР]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Сървърът иÑка Ñледните уебÑайти за да ги зареди (поÑле):" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "ЧаÑÑŠÑ‚ в момента е %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "ÐИКОГРÐЕ ВЪВЕЖДÐЙТЕ ТÐЙÐИ ДÐÐÐИ ЗРДРГИ ЗÐЩИТИТЕ ОТ КРÐЖБÐ" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Запомни решение" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "Ñвържете: СинтакÑÐ¸Ñ Ðµ 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Позволи" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "Ñвържете: Лош номер на порта" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Отхвърли" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "Ñвързване: Свързване към %s:%u..." -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "Ñвързване: Свързването към %s:%u е неуÑпешно!" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Вие използвате теÑтов билд! Това е теÑтов билд, който не може да Ñе Ñвързва към публични Ñървъри!" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "Ñвързване: ÐеуÑпешно излизане от Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ð¼Ð¾Ð´" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "мта нÑма да има повече ъпдейти за xp/vista Ñлед юли 2019.\n\n" -"обновете УиндолÑа за да играете в най новите Ñървири." +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Това ще ви отвърже от Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ñървър.\n\n" -"Сигурни ли Ñте, че иÑкате да бъдете отвързани?" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "Ð’ÐИМÐÐИЕ ЗРОТВЪРЗВÐÐЕ" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" msgstr "" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "българÑки" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Свържи вÑички контроли от GTA" + +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Запазен конфигурационен файл" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* ВашиÑÑ‚ serial е: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "ÐÐСТРОЙКИ" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Онлайн игра" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Видео" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Звук" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Биндове" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Контроли" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "ИнтерфейÑ" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Уеб Браузър" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "За напреднали" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Зареди по подразбиране" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "ЧувÑтвителноÑÑ‚ на мишката:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Вертикална прицелна чувÑтвителноÑÑ‚:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Опции на мишката" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Обърни мишката вертикално" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Завивай Ñ Ð¼Ð¸ÑˆÐºÐ°" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Лети Ñ Ð¼Ð¸ÑˆÐºÐ°" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "ÐаÑтройки на джойпад" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Стандартни контроли (Мишка + Клавиатура)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "КлаÑичеÑки контроли (Джойпад)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Мъртва Зона" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "ÐаÑитеноÑÑ‚" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Използвайте чаÑтта 'Биндове' за джойпад бутоните." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "ЛÑв Стик" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "ДеÑен Стик" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "ОПИСÐÐИЕ" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "БУТОÐ" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT.БУТОÐ" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Ðикнейм:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "ЗапаметÑвай пароли за Ñървъри" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Ðвтоматично обновÑване на Ñървър търÑачката" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "ПозволÑвай екранно качване" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "ПозволÑване на външни звуци" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Използвай перÑонализирани GTA:SA файлове" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "ÐаÑтройки за зареждането на картата" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "ÐепрозрачноÑÑ‚:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Радио звук:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "SFX звук:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "МТРзвук:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Звук на глаÑове:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Игрален режим:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Генерални" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Радио Еквалайзер" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Радио автоматично" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "ПеÑни на потребителÑ, наÑтройки" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Радио" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Случаен" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Следващ" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Ðвтоматично Сканиране на МедиÑта" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Заглужи звуци на Радиото при минимизиране" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Заглужи звуци на SFX при минимизиране" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Заглужи звуци на MTA при минимизиране" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Заглужи звуци на ГлаÑове при минимизиране" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "РезолюциÑ:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Поле на виждане:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "ЯркоÑÑ‚:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX КачеÑтво:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Ðнизотропно филтриране:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Ðнти-заглаждане:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Съотношение:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Прозорец" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Стандартен" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Без краища запази резолюциÑ" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mip картографиране" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "ÐиÑък" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Среден" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "ВиÑок" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Много виÑок" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Изключен" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1Ñ…" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2Ñ…" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3Ñ…" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Ðвтоматично" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "ХУД Съобразено ÑÑŠÑ Ñъотношението" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Обемни Сенки" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Ефект на тревата" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Топлинна мъгла" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Пушек от гуми и тн" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Минимизиране при голÑм екран" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Позволи избор на уред " -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Покажи непредпазени резолюции" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Зареждай превозни ÑредÑтва винаги Ñ Ð³Ð¾Ð»Ñм детайл" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Позволи уебÑайтове за диÑтанционно контролиране" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Позволи Javascript на Ñайтове" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "ПотребителÑки черен ÑпиÑък" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Въведете домейн примерно google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Блокирай" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Домейн" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Премахни домейн" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "ПотребителÑки позволен ÑпиÑък" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Позволи" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Разни" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Бързо зареждане на дрехи на CJ:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "СкороÑÑ‚ на браузър:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Единична връзка:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Пакетен таг:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "ПрогреÑивна анимациÑ:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "ПредимеÑтво на процеÑ:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Дебъг наÑтройка:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Памет за излъчване:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Обнови билд типа:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "ИнÑталирай важни обновлениÑ:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Включено" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Много бавно" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "По подразбиране" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Бързо" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Ðормално" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Ðад нормално" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Минимум" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "МакÑимум" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "СъвмеÑтимоÑÑ‚ Ñ Ð£Ð¸Ð½Ð´Ð¾ÑƒÑ 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-битов цвÑÑ‚" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "ОправÑне на мишка" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Клиент реÑурÑи, файл:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Покажи в ТърÑачката" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Ðвто обновител" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Провери за Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñега" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "ÐÑкои наÑтройки ще бъдат промонени при Ñледващото ви Ñтартиране на МТÐ" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "ИÑкате ли да реÑтартирате Ñега?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "ÐУЖДРОТ РЕСТÐРТ" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "ÐÑкои наÑтройки ще Ñе променÑÑ‚ при напуÑкането на Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ñървър" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "ИÑкате ли да Ñе отвържете Ñега?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "ОТВЪРЗВÐÐЕ Е ÐУЖÐО" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Джойпадът не е заÑечен - Проверете Ñвързване и реÑтартирайте играта" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "ÐžÑ Ð½Ð° биндване" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "ПремеÑтете оÑ, за да бинднете или излезте, за да изчиÑтите" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Език:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Скин:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Предварителни наÑтройки:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Чат" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Зареди" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Цветове" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Оформление" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "ÐаÑтройки" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Фон на чата" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Чат текÑÑ‚" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Фон на въвеждане" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Въвеждане текÑÑ‚" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Редове:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Скала:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Широчина:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Размер" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "Ñлед" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "за" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "Ñек" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Затихване" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "ИзчиÑтване на Ñтарите редове" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Хоризонтално:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Вертикално:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Подреждане на текÑта:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "Ð¥-ИзмеÑтване:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-ИзмеÑтване:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "ПозициÑ" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "ÐалÑво" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Център" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "ÐадÑÑно" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Ðай-отгоре" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Долу" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Шрифт" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Скривай фон-а, когато не пиша" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Завършване на никнейм използвайки \"Таб\" бутона" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Позволи на Ñървър да премигва прозореца" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Разрешаване на извеÑтиÑта в балони" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Чат текÑÑ‚ бÑло/черно подчертаване" @@ -1538,109 +1826,115 @@ msgstr "Чат текÑÑ‚ бÑло/черно подчертаване" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "ÐатиÑнете бутон да бинднете или Esc, за да отмените" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Биндване на първичен бутон" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Биндване на вторичен бутон" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA ИГРÐЛÐИ КОÐТРОЛИ" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "КОÐТРОЛИ ПРИ ОÐЛÐЙРИГРÐ" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "ВашиÑÑ‚ никнейм Ñъдържа невалидни знаци!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Червено:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Зелено:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Синьо:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "ПрозрачноÑÑ‚:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "ЦвÑÑ‚" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Предварителен поглед" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "ÐœÐ¾Ð»Ñ Ð¾Ñ‚Ð²ÑŠÑ€Ð¶ÐµÑ‚Ðµ Ñе преди промÑната на език" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "ÐœÐ¾Ð»Ñ Ð¾Ñ‚Ð²ÑŠÑ€Ð¶ÐµÑ‚Ðµ Ñе преди промÑната на Ñкин" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Обемните Ñенки могат да забавÑÑ‚ нÑкои ÑиÑтеми.\n\n" "ÐаиÑтина ли иÑкате да ги активирате?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "ПРОИЗВОДИТЕЛÐО Ð’ÐИМÐÐИЕ" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Качването на екрана Ñе изиÑква от нÑкои Ñървъри, за да бъдат използвани Ñрещу измама.\n\n" "(Чатът и GUI Ñа изключени от качването)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "ИÐФОРМÐЦИЯ ЗРЕКРÐÐÐО КÐЧВÐÐЕ" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1650,561 +1944,259 @@ msgstr "ÐÑкои файлове в директориÑта на GTA:SA Ñа "ПЕРСОÐÐЛИЗИРÐÐИТЕ GTA:SA СРБЛОКИРÐÐИ ОТ МÐОГО СЪРВЪРИ\n\n" "ÐаиÑтина ли иÑкате да ги използвате?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "ПЕРСОÐÐЛИЗИРÐÐИ GTA:SA ФÐЙЛОВЕ" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" "Are you sure you want to enable this option?" msgstr "" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "ÐœÐ¾Ð»Ñ Ð²ÑŠÐ²ÐµÐ´ÐµÑ‚Ðµ никнейм" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "ÐœÐ¾Ð»Ñ Ð²ÑŠÐ²ÐµÑ‚Ðµ никнейм, който ще Ñе използва в играта. \n" "Това ще бъдете вашето име, когато Ñе приÑъедините и играете в Ñървър" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Много екÑпериментална функциÑ." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Спира Ñтало-ве Ñ CJ вариации (Използва 65МБ повече РÐМ)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "По-Ñтарите рутери може да имат нужда от по-бавно Ñканиране." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "ПуÑнете, за да Ñе използва Ñамо едно Ñвързване при изтеглÑне." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Таг-нете интернет пакети, за да помогнете на ISP-тата да познаÑÑ‚ МТРтрафика." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "ÐнимациÑта Ñ Ð²ÑŠÑ€Ñ‚ÑÑ‰Ð¸Ñ ÐºÑ€ÑŠÐ³ в долната чаÑÑ‚ на екрана" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Избирайте по подразбиране винаги. (Тази Ð¾Ð¿Ñ†Ð¸Ñ Ð½Ðµ е запаметена)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "МакÑимум е чеÑто най-доброто" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Ðвтоматичен обновител:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Изберете по подразбиране оÑвен ако не обичате да изпращате доклади за бъгове." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Изберете по подразбиране за автоматично инÑталиране на важни обновлениÑ." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-битов цвÑÑ‚:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Позволи 16 битови цветови модове - Ðуждае Ñе от реÑтарт на МТÐ" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "ОправÑне на мишката:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "ОправÑне на движение на мишката - Може да Ñе нуждае от реÑтарт на компютъра" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Ðепозната команда или cvar: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Зает" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Ðе може да провери за Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñега" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "МТÐ:SA %s е нужен" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Ðктуализирана верÑÐ¸Ñ Ð½Ð° MTA:SA %s Ñе изиÑква, за да Ñе приÑъедините към Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ñървър.\n\n" -"ИÑкате ли да изтеглите и инÑталирате MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "ИÑкате ли да пуÑнете MTA:SA %s и да Ñе приÑъедините към този Ñървър ?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Ðе е възможно Ñвързването в момента.\n\n" -"ÐœÐ¾Ð»Ñ Ð¾Ð¿Ð¸Ñ‚Ð°Ð¹Ñ‚Ðµ по-къÑно." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Свързване" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "ÐœÐ¾Ð»Ñ Ð¸Ð·Ñ‡Ð°ÐºÐ°Ð¹Ñ‚Ðµ..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "ПРОВЕРЯВÐÐЕ" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "ПРОВЕРКРÐРОБÐОВЛЕÐИЕ" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "ÐÑма нужда от обновÑване" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "ИЗТЕГЛЯÐЕ" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "чакане..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "ЗÐДЪЛЖИТЕЛÐО ОБÐОВЛЕÐИЕ" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "За да Ñе приÑъедините към този Ñървър трÑбва да актуализирате MTA.\n\n" -"ИÑкате ли да направите актуализациÑта Ñега ?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "ÐКТУÐЛИЗÐЦИЯ ПО ИЗБОР" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Сървърът твърди, че актуализациÑта е препоръчана, но не и задължителна.\n\n" -"ИÑкате ли да актуализирате Ñега ?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "ГРЕШКРПРИ ЗÐПÐМЕТЯВÐÐЕ" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Ðевъзможно Ñъздаване на файла." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "ГРЕШКРПРИ ИЗТЕГЛЯÐЕ" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "ИзтеглениÑÑ‚ файл не е правилен." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Поради нÑкаква причина." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "ИЗТЕГЛЯÐЕТО ЗÐВЪРШЕÐО" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "- Проблем в _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ок" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "ГРЕШКÐ" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "ÐÑкои MTA:SA дата файлове липÑват.\n\n\n" -"ÐœÐ¾Ð»Ñ Ð¿Ñ€ÐµÐ¸Ð½Ñталирайте MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% завършено" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Изчакване на отговор - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "ÐеуÑпешно Ñвързване. ПредоÑтавен е невалиден никнейм!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "ÐеуÑпешно Ñвързване. ПредоÑтавен е невалиден хоÑÑ‚!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Свързването към %s Ñ Ð¿Ð¾Ñ€Ñ‚ %u неуÑпешно!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Свързване към %s%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "СВЪРЗВÐÐЕ" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "ПроÑрочено време за връзка" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Връзката прекъÑната : неизвеÑтна по протокола грешка" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Връзката прекъÑната: Връзката бе прекъÑната диÑтанционно" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Разкачени: връзката прекъÑна диÑтанционно" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Разкачени: вие Ñте баннати от този Ñървър" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Разкачени: разкачени Ñте от Ñървъра" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Разкачени: връзката ÑÑŠÑ Ñървъра Ñе загуби" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Разкачени: връзката ÑÑŠÑ Ñървъра Ñе отхвърли" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "ÐÑма такъв инÑталиран мод (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Лош отговор на Ñървъра (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Лош отговор на Ñървъра (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "КОÐЗОЛÐ" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Фатална грешка" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "ЗРДРСЕ ОПРÐВИ, ПРЕМÐÐ¥ÐЕТЕ ТОЗИ ФÐЙЛ:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s модулът е неправилен!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Грешка при изпълнÑване на URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "този помощен екран" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "излиза от приложението" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "показва верÑиÑта" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "показва времето" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "показва hud-а" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "показва вÑички контроли" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "показва Ð²Ð°ÑˆÐ¸Ñ Ñериал" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "Ñвързва ви към Ñървър (host port nick pass)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "Ñвързва към предишен Ñървър" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "бинд-ва бутон (key control)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "премахва бинд от бутон (key)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "копира контролите по подразбиране на gta" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "изкарва екранна Ñнимка" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "незабавно запаметÑва наÑтройката" -#: Client/core/CCore.cpp:1391 +#: Client/core/CCore.cpp:1494 msgid "clears the debug view" msgstr "изчиÑтва дебъг виждането" -#: Client/core/CCore.cpp:1392 +#: Client/core/CCore.cpp:1495 msgid "scrolls the chatbox upwards" msgstr "превърта чата нагоре" -#: Client/core/CCore.cpp:1393 +#: Client/core/CCore.cpp:1496 msgid "scrolls the chatbox downwards" msgstr "превърта чата надолу" -#: Client/core/CCore.cpp:1394 +#: Client/core/CCore.cpp:1497 msgid "scrolls the debug view upwards" msgstr "превърта дебъг виждането нагоре" -#: Client/core/CCore.cpp:1395 +#: Client/core/CCore.cpp:1498 msgid "scrolls the debug view downwards" msgstr "превърта дебъг виждането надолу" -#: Client/core/CCore.cpp:1398 +#: Client/core/CCore.cpp:1501 msgid "shows the memory statistics" msgstr "показва ÑтатиÑтиките за паметта" -#: Client/core/CCore.cpp:1399 +#: Client/core/CCore.cpp:1502 msgid "shows the frame timing graph" msgstr "показва графата за кадрите" -#: Client/core/CCore.cpp:1403 +#: Client/core/CCore.cpp:1506 msgid "for developers: reload news" msgstr "" -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ ПОМОЩ ЗРКОМÐÐДР]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "ЧаÑÑŠÑ‚ в момента е %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "Ñвържете: СинтакÑÐ¸Ñ Ðµ 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "Ñвържете: Лош номер на порта" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Вие използвате теÑтов билд! Това е теÑтов билд, който не може да Ñе Ñвързва към публични Ñървъри!" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "Ñвързване: Свързване към %s:%u..." +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "мта нÑма да има повече ъпдейти за xp/vista Ñлед юли 2019.\n\n" +"обновете УиндолÑа за да играете в най новите Ñървири." -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "Ñвързване: Свързването към %s:%u е неуÑпешно!" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Това ще ви отвърже от Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ñървър.\n\n" +"Сигурни ли Ñте, че иÑкате да бъдете отвързани?" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "Ñвързване: ÐеуÑпешно излизане от Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ð¼Ð¾Ð´" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "Ð’ÐИМÐÐИЕ ЗРОТВЪРЗВÐÐЕ" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" msgstr "" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" msgstr "" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" msgstr "" -#: Client/core/CCommandFuncs.cpp:325 +#: Client/core/CScreenShot.cpp:200 #, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Свържи вÑички контроли от GTA" +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Екранната Ñнимка получи %d байта, но очакваше %d" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Запазен конфигурационен файл" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Екранната Ñнимка Ñе провали" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 +#: Client/core/CScreenShot.cpp:256 #, c-format -msgid "* Your serial is: %s" -msgstr "* ВашиÑÑ‚ serial е: %s" - -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "УÑкорителна ОÑ" - -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Спирачна ОÑ" - -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Програмиране" - -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Сътрудници" - -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Дизайн на играта / Скриптване" - -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Езиково Локализиране" - -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Сътрудници за пача" - -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Специални БлагодарноÑти" - -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "" +msgid "Screenshot taken: '%s'" +msgstr "Екранна Ñнимка заÑнета: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "ИÑкате ли да видите помощ за този проблем онлайн?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Ðепозната команда или cvar: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2379,25 +2371,56 @@ msgid "Group control backwards" msgstr "Група контроли назад" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Скинът, който избрахте не може да бъде зареден, Ñъщо и обикновенниÑÑ‚ Ñкин, Ð¼Ð¾Ð»Ñ Ð¿Ñ€ÐµÐ¸Ð½Ñталирайте MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Екранната Ñнимка получи %d байта, но очакваше %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "ИÑкате ли да видите помощ за този проблем онлайн?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Екранната Ñнимка Ñе провали" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "КОÐЗОЛÐ" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Екранна Ñнимка заÑнета: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Програмиране" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Сътрудници" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Дизайн на играта / Скриптване" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Езиково Локализиране" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Сътрудници за пача" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Специални БлагодарноÑти" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "УÑкорителна ОÑ" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Спирачна ОÑ" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2405,6 +2428,61 @@ msgstr "Ðе уÑÐ¿Ñ Ð´Ð° Ñе Ñтартира Direct3D9.\n\n" "ÐœÐ¾Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐµÑ‚Ðµ дали DirectX End-User Runtime и\n" "поÑледниÑÑ‚ Windows Service Packs Ñа инÑталирани правилно." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Без работа" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "играч" +msgstr[1] "играчи" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "включено" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "Ñървър" +msgstr[1] "Ñървъри" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "ИзиÑкване на главен Ñървър лиÑÑ‚ (%lu ms загубени)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Ð“Ð»Ð°Ð²Ð½Ð¸Ñ Ñървър лиÑÑ‚ не може да бъде парÑнат." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "ГлавниÑÑ‚ Ñървър лиÑÑ‚ не може да бъде изкаран." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Бекъп Ñървър лиÑÑ‚)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Ðе може да Ñе биндне LAN-Ð¸Ð·Ð»ÑŠÑ‡Ð²Ð°Ñ‰Ð¸Ñ Ñокет" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Опит да Ñе намерÑÑ‚ LAN Ñървъри" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2458,7 +2536,7 @@ msgstr "Лаг:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "ЛиÑÑ‚ от играчи" @@ -2485,40 +2563,39 @@ msgstr "ПриÑъединете Ñъм към Ñървъра щом има Ñв msgid "PLEASE ENTER SERVER PASSWORD" msgstr "МОЛЯ ВЪВЕДЕТЕ ПÐРОЛРЗРСЪРВЪРÐ" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Времето Изтече" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "ЗаÑвка..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "ТЪРСÐЧКРÐРСЪРВЪРИ" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Интернет" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Локален" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Любими" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "ПоÑледни" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2526,298 +2603,367 @@ msgstr "ЗРБЪРЗО СВЪРЗВÐÐЕ:\n\n" "Въведете адреÑа и порта в полето за адреÑ\n" "Или изберете Ñървър от иÑÑ‚Ð¾Ñ€Ð¸Ñ Ñ‡Ð°Ñтта и натиÑнете 'Свържи'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "ПОМОЩ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Обнови" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Добави към любими" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Свържи" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° Ñървъра" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "ТърÑи Ñървъри" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "ТърÑи играчи" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Започни търÑене" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "ТърÑи играчи..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "ТърÑи Ñървъри..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Име" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Играчи" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Пинг" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Игрален режим" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Включва:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Празен" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Пълен" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Заключен" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Извън линиÑ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Друга верÑиÑ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Ðазад" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Зареждане..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "...зареждане.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Ðе е въведен адреÑ!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Ðепознат протокол" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "ÐœÐ¾Ð»Ñ Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð¹Ñ‚Ðµ mtasa:// протокола!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Ðевалиден никнейм! ÐœÐ¾Ð»Ñ Ð¾Ñ‚Ð¸Ð´ÐµÑ‚Ðµ в ÐаÑтройки и задайте нов!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "ТрÑбва да изберете Ñървър, за който да Ñе Ñвържете," -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Без работа" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Проблем Ñ Ð³Ñ€Ð°Ñ„Ð¸Ñ‡Ð½Ð¸Ñ Ð´Ñ€Ð°Ð¹Ð²ÑŠÑ€" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "играч" -msgstr[1] "играчи" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Ðе може да Ñе намери валидна екранна резолюциÑ." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "включено" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Сигурни ли Ñте, че иÑкате да използвате тази екранна резолюциÑ?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "Ñървър" -msgstr[1] "Ñървъри" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "ИзиÑкване на главен Ñървър лиÑÑ‚ (%lu ms загубени)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Ð“Ð»Ð°Ð²Ð½Ð¸Ñ Ñървър лиÑÑ‚ не може да бъде парÑнат." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "ЗаÑвки на уебÑайта" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "ГлавниÑÑ‚ Ñървър лиÑÑ‚ не може да бъде изкаран." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Сървърът иÑка Ñледните уебÑайти за да ги зареди (поÑле):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Бекъп Ñървър лиÑÑ‚)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "ÐИКОГРÐЕ ВЪВЕЖДÐЙТЕ ТÐЙÐИ ДÐÐÐИ ЗРДРГИ ЗÐЩИТИТЕ ОТ КРÐЖБÐ" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Ðе може да Ñе биндне LAN-Ð¸Ð·Ð»ÑŠÑ‡Ð²Ð°Ñ‰Ð¸Ñ Ñокет" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Запомни решение" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Опит да Ñе намерÑÑ‚ LAN Ñървъри" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Отхвърли" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Тази верÑÐ¸Ñ Ðµ проÑрочена." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "отвържи Ñе от игра" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "показва таговете на имената" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "показва чата" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "показва интернет ÑтатиÑтиките" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "Ð¾Ñ‚Ð²Ð°Ñ€Ñ Ñ‡Ð°Ñ‚ входа" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "предава звук към оÑтаналите играчи" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "качва Ñе в кола като паÑажер" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "Ñледваща радио ÑтанциÑ" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "предишна радио ÑтанциÑ" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "изпраща Ñъобщение до Ð´Ð°Ð´ÐµÐ½Ð¸Ñ Ð¸Ð³Ñ€Ð°Ñ‡" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "ÑÐ¼ÐµÐ½Ñ Ð½Ð° Ñледващото оръжие в превозно ÑредÑтво" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "ÑÐ¼ÐµÐ½Ñ Ð½Ð° предишно оръжие в превозно ÑредÑтво" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "изпиÑва Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ñървър" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñ Ñкалата за умножение на текÑÑ‚-показването" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Разработчик мод) показва кол-формите" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Разработчик мод) принтира ИД-то на звуците в дебъг прозореца" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "ХОСТ ИГРÐ" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "РеÑурÑи" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Име на Ñървъра:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Парола:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "МакÑимален брой играчи:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Излъчване:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "ЛÐÐ" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Избрано" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Ð’Ñички" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Старт" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "ÐŸÑ€Ð¾Ð³Ñ€ÐµÑ Ð½Ð° изтеглÑне на картата:" @@ -2838,195 +2984,195 @@ msgstr "%s от %s" msgid "Disconnect to cancel download" msgstr "Отвържете Ñе за да откажете изтеглÑнето" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Отвързани: Ðевалиден никнейм" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Отвързани от Ñървъра" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Отвързани: Сериалът е баннат.\n" "Причина: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Отвързани: Вие Ñте баннат.\n" "Причина: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Отвързани: Профилът е баннат.\n" "Причина: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Отвързани: ВерÑиите не Ñъвпадат" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Отвързани: Пренатоварено влизане. Изчакайте минута и пробвайте, молÑ." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Отвързани: Сървър от различен клон.\n" "ИнформациÑ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Отвързани: Грешна верÑиÑ.\n" "ИнформациÑ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Отвързани: Сървърът е на по-нов билд.\n" "ИнформациÑ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Отвързани: Сървърът е на по-Ñтар билд.\n" "ИнформациÑ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Отвързани: Ðикнеймът Ñе използва" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Отвързани: Сървъръз отказа връзката: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Отвързани: Сериалът провали да бъде проверен" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Отвързани: Грешка при Ñвързване %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Отвързани: Вие бÑхте изхвърлен от %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Отвързани: Вие бÑхте баннат от %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Отвързани: Сървърът Ñе изключи или Ñе реÑтартира" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Вие Ñте изхвърлен от играта" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "ОÑтатъчно Време: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d ден" msgstr[1] "%d дни" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d чаÑ" msgstr[1] "%d чаÑове" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d минута" msgstr[1] "%d минути" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3034,296 +3180,206 @@ msgstr[0] "%d Ñекунда" msgstr[1] "%d Ñекунди" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Отвързани" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Грешка при изтеглÑне: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Влизане в игра ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Ðе Ñте Ñвързан; Ð¼Ð¾Ð»Ñ Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð¹Ñ‚Ðµ Бързо Свързване или 'Ñвързване' командата за да влезнете в Ñървър." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Ðе уÑпешно Ñтартиране на Ð»Ð¾ÐºÐ°Ð»Ð½Ð¸Ñ Ñървър. Вижте конзолата за детайли." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Локален Ñървър" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Стартиране на локален Ñървър ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Вие Ñте изхвърлен от играта ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Свързване към локален Ñървър..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Грешка при Ñвързване към Ñървър." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Грешка при Ñвързване към локален Ñървър. Вижте конзолата за детайли." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Връзката ÑÑŠÑ Ñървъра бе загубена" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Отвързани: Ñървърът е пълен" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Отвързани: невалидна парола е въведена" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "МТРКлиента не уÑÐ¿Ñ Ð´Ð° бъде верифициран!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "ХОСТ ИГРÐ" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "РеÑурÑи" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Име на Ñървъра:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Парола:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "МакÑимален брой играчи:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Излъчване:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "ЛÐÐ" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Избрано" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Ð’Ñички" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Старт" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Проблем Ñ Ð³Ñ€Ð°Ñ„Ð¸Ñ‡Ð½Ð¸Ñ Ð´Ñ€Ð°Ð¹Ð²ÑŠÑ€" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Ðе може да Ñе намери валидна екранна резолюциÑ." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Сигурни ли Ñте, че иÑкате да използвате тази екранна резолюциÑ?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Грешка при изтеглÑне: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3344,11 +3400,11 @@ msgstr "" msgid "Connection error" msgstr "Грешка при Ñвързване" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto не бе инталиран правилно, Ð¼Ð¾Ð»Ñ Ð¿Ñ€ÐµÐ¸Ð½Ñталирайте." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "ВашиÑÑ‚ браузър ще покаже уеб Ñтраница Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ за това.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/bs_BA/client.pot b/Shared/data/MTA San Andreas/MTA/locale/bs_BA/client.pot index 90e59feed7b..aa6945aa3a3 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/bs_BA/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/bs_BA/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:32\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Bosnian\n" "Language: bs_BA\n" @@ -17,228 +17,439 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "" + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "" + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." msgstr "" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "" + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "" + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "" + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "" + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "" + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" msgstr "" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "" -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" msgstr "" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "" -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "" -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "" -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." msgstr "" -#: Client/loader/MainFunctions.cpp:810 +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "" -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "" -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "" -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "" -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Data file %s is modified. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "" + +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." msgstr "" -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" msgstr "" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" msgstr "" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1088 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." msgstr "" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" msgstr "" #. ///////////////////////////////////////////////////////////////////////// @@ -247,1257 +458,1336 @@ msgstr "" #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "" -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." msgstr "" -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "" -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" msgstr "" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" msgstr "" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" msgstr "" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." msgstr "" -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" msgstr "" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" msgstr "" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" msgstr "" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" msgstr "" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" msgstr "" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" msgstr "" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgid "No such mod installed (%s)" msgstr "" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" msgstr "" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" msgstr "" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" msgstr "" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" msgstr "" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" msgstr "" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" msgstr "" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" msgstr "" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" msgstr "" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." msgstr "" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" msgstr "" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." msgstr "" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" msgstr "" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" msgstr "" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" msgstr "" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" msgstr "" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." msgstr "" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" msgstr "" -#: Client/loader/Install.cpp:265 -msgid "Unknown" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" msgstr "" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" msgstr "" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" msgstr "" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" msgstr "" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." msgstr "" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" msgstr "" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." msgstr "" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." msgstr "" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" msgstr "" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" msgstr "" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" msgstr "" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" msgstr "" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" msgstr "" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "" + +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" +msgid "%3d %% completed" msgstr "" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" msgstr "" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "" + +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" msgstr "" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" msgstr "" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" msgstr "" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" msgstr "" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "" -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "" @@ -1505,660 +1795,368 @@ msgstr "" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" "Are you sure you want to use them?" msgstr "" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" "Are you sure you want to enable this option?" msgstr "" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "" -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "" -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "" -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "" - -#: Client/core/CSettings.cpp:4987 -msgid "Spinning circle animation at the bottom of the screen" -msgstr "" - -#: Client/core/CSettings.cpp:4989 -msgid "Select default always. (This setting is not saved)" -msgstr "" - -#: Client/core/CSettings.cpp:4991 -msgid "Maximum is usually best" -msgstr "" - -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 -msgid "Auto updater:" -msgstr "" - -#: Client/core/CSettings.cpp:4993 -msgid "Select default unless you like filling out bug reports." -msgstr "" - -#: Client/core/CSettings.cpp:4995 -msgid "Select default to automatically install important updates." -msgstr "" - -#: Client/core/CSettings.cpp:4997 -msgid "16-bit color:" -msgstr "" - -#: Client/core/CSettings.cpp:4997 -msgid "Enable 16 bit color modes - Requires MTA restart" -msgstr "" - -#: Client/core/CSettings.cpp:4999 -msgid "Mouse fix:" -msgstr "" - -#: Client/core/CSettings.cpp:4999 -msgid "Mouse movement fix - May need PC restart" -msgstr "" - -#: Client/core/CSettings.cpp:5001 -msgid "CPU affinity:" -msgstr "" - -#: Client/core/CSettings.cpp:5001 -msgid "Only change if you're having stability issues." -msgstr "" - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "" - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" + +#: Client/core/CSettings.cpp:6029 +msgid "Spinning circle animation at the bottom of the screen" msgstr "" -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" +#: Client/core/CSettings.cpp:6031 +msgid "Select default always. (This setting is not saved)" msgstr "" -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" +#: Client/core/CSettings.cpp:6033 +msgid "Maximum is usually best" msgstr "" -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 +msgid "Auto updater:" msgstr "" -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" +#: Client/core/CSettings.cpp:6035 +msgid "Select default unless you like filling out bug reports." msgstr "" -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" +#: Client/core/CSettings.cpp:6037 +msgid "Select default to automatically install important updates." msgstr "" -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" +#: Client/core/CSettings.cpp:6039 +msgid "16-bit color:" msgstr "" -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" +#: Client/core/CSettings.cpp:6039 +msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "" -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" +#: Client/core/CSettings.cpp:6041 +msgid "Mouse fix:" msgstr "" -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" +#: Client/core/CSettings.cpp:6041 +msgid "Mouse movement fix - May need PC restart" msgstr "" -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" +#: Client/core/CSettings.cpp:6043 +msgid "CPU affinity:" msgstr "" -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" +#: Client/core/CSettings.cpp:6043 +msgid "Only change if you're having stability issues." msgstr "" -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "" -#: Client/core/CCore.cpp:1391 +#: Client/core/CCore.cpp:1494 msgid "clears the debug view" msgstr "" -#: Client/core/CCore.cpp:1392 +#: Client/core/CCore.cpp:1495 msgid "scrolls the chatbox upwards" msgstr "" -#: Client/core/CCore.cpp:1393 +#: Client/core/CCore.cpp:1496 msgid "scrolls the chatbox downwards" msgstr "" -#: Client/core/CCore.cpp:1394 +#: Client/core/CCore.cpp:1497 msgid "scrolls the debug view upwards" msgstr "" -#: Client/core/CCore.cpp:1395 +#: Client/core/CCore.cpp:1498 msgid "scrolls the debug view downwards" msgstr "" -#: Client/core/CCore.cpp:1398 +#: Client/core/CCore.cpp:1501 msgid "shows the memory statistics" msgstr "" -#: Client/core/CCore.cpp:1399 +#: Client/core/CCore.cpp:1502 msgid "shows the frame timing graph" msgstr "" -#: Client/core/CCore.cpp:1403 +#: Client/core/CCore.cpp:1506 msgid "for developers: reload news" msgstr "" -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" msgstr "" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." msgstr "" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" msgstr "" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" msgstr "" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" msgstr "" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" msgstr "" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" msgstr "" -#: Client/core/CCommandFuncs.cpp:325 +#: Client/core/CScreenShot.cpp:200 #, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" +msgid "Screenshot got %d bytes, but expected %d" msgstr "" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" msgstr "" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 +#: Client/core/CScreenShot.cpp:256 #, c-format -msgid "* Your serial is: %s" -msgstr "" - -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "" - -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "" - -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "" - -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "" - -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "" - -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "" - -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "" - -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "" - -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" +msgid "Screenshot taken: '%s'" msgstr "" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " msgstr "" #: Client/core/CKeyBinds.cpp:186 @@ -2334,30 +2332,118 @@ msgid "Group control backwards" msgstr "" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "" -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" msgstr "" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" msgstr "" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" msgstr "" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." msgstr "" +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2411,7 +2497,7 @@ msgstr "" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "" @@ -2438,339 +2524,405 @@ msgstr "" msgid "PLEASE ENTER SERVER PASSWORD" msgstr "" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "" #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "" -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "" @@ -2791,167 +2943,167 @@ msgstr "" msgid "Disconnect to cancel download" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" @@ -2959,7 +3111,7 @@ msgstr[0] "" msgstr[1] "" msgstr[2] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" @@ -2967,7 +3119,7 @@ msgstr[0] "" msgstr[1] "" msgstr[2] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" @@ -2975,7 +3127,7 @@ msgstr[0] "" msgstr[1] "" msgstr[2] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -2984,295 +3136,205 @@ msgstr[1] "" msgstr[2] "" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "" - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" +msgid "Download error: %s" msgstr "" #. Populate the message and show the box @@ -3294,11 +3356,11 @@ msgstr "" msgid "Connection error" msgstr "" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "" -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "" diff --git a/Shared/data/MTA San Andreas/MTA/locale/cs_CZ/client.pot b/Shared/data/MTA San Andreas/MTA/locale/cs_CZ/client.pot index 3ba35d3a1ed..eef6e015e8e 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/cs_CZ/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/cs_CZ/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:18\n" "Last-Translator: \n" "Language-Team: Czech\n" "Language: cs_CZ\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Potíže pÅ™i restartování MTA:SA\n\n" -"Pokud problém pÅ™etrvává, otevÅ™i správce úloh a\n" -"ukonÄi procesy 'gta_sa.exe' a 'Multi Theft Auto.exe'\n\n\n" -"Zkusit znovu spustit MTA:SA?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Chyba" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Jiná instance MTA již běží.\n\n" -"Pokud tento problém pÅ™etrvává, restartuj svůj PC" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Již beží jiná instance MTA.\n\n" -"ChceÅ¡ ji terminovat?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Zvol tvůj Grand Theft Auto: San Andreas instalaÄní adresář" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA potÅ™ebuje Administrátorská oprávnÄ›ní pro následující operaci:\n\n" +" '%s'\n\n" +"Prosím potvrÄ v následujícím oknÄ›." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Chyba pÅ™i naÄítání %s modulu! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Kopíruji soubory..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopírování zkonÄilo pÅ™edÄasnÄ›. VÅ¡e OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "DokonÄování..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Hotovo!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Byla zaznamenána nová instalace %s.\n\n" +"Chcete vaÅ¡e nastavení zkopírovat z %s?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA mÄ›lo potíže pÅ™i otevírání souboru '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA zaznamenalo chybÄ›jící soubor '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA objevilo potíže pÅ™i naÄítání modelu." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Pokud jsi v nedávné dobÄ› upravoval gta3.img, zkus pÅ™einstalovat GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA odhalilo problém pÅ™i pokusu o pÅ™idání vylepÅ¡ení na vozidlo." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA nalezlo chyby v souboru '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Restartoval se tvůj poÄítaÄ pÅ™i hraní MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "UkonÄi, prosím, následující programy pÅ™ed pokraÄováním:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Verze souboru se liší. Pokud zaznamenáváte problémy, pÅ™einstalujte MTA:SA.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "NÄ›které soubory chybí. Pokud zaznamenáváte problémy, pÅ™einstalujte MTA:SA.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA není kompatibilní s nouzovým režimem systému Windows.\n\n" +"Prosím, restartujte svůj poÄítaÄ.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Máš problémy se spuÅ¡tÄ›ním MTA:SA?\n\n" "ChceÅ¡ se vrátit na starší verzi?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "Vypadá to že nastal problém pÅ™i spuÅ¡tÄ›ní MTA:SA.\n" "Resetování GTA nastavení nÄ›kdy pomůže vyÅ™eÅ¡it tento problém.\n\n" "ChceÅ¡ restarovat GTA nastavení nyní?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA nastavení byla zresetována.\n\n" "Klikni na OK pro pokraÄování." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Soubor nemohl být smazán: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Máš problémy se spouÅ¡tÄ›ním MTA:SA?.\n\n" "ChceÅ¡ se podívat na online pomoc?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Máte problémy se spuÅ¡tÄ›ním MTA:SA?\n\n" "Chcete zmÄ›nit následující nastavení?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Celoobrazový režim:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Okno bez okraje" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Máte problémy se spuÅ¡tÄ›ním MTA:SA?\n\n" "Zkuste vypnout následující programy pro GTA a MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +189,293 @@ msgstr "VAROVÃNÃ\n\n" "MTA:SA zaznamenalo neobvyklou aktivitu.\n" "ZapnÄ›te, prosím, virový sken, abyste se ujistili, že je váš systém v bezpeÄí.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Odhalený soubor: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Instance GTA: San Andreas již běží. Je zapotÅ™ebí ji terminovat pÅ™ed spuÅ¡tÄ›ním MTA:SA. ChceÅ¡ to udÄ›lat nyní?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informace" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Nelze ukonÄit GTA: San Andreas. Pokud problém pÅ™etrvává, zkus zrestartovat tvůj poÄítaÄ." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Potíže pÅ™i restartování MTA:SA\n\n" +"Pokud problém pÅ™etrvává, otevÅ™i správce úloh a\n" +"ukonÄi procesy 'gta_sa.exe' a 'Multi Theft Auto.exe'\n\n\n" +"Zkusit znovu spustit MTA:SA?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Chyba" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Jiná instance MTA již běží.\n\n" +"Pokud tento problém pÅ™etrvává, restartuj svůj PC" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Již beží jiná instance MTA.\n\n" +"ChceÅ¡ ji terminovat?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Záznamy v registrech nenalezeny. Prosím reinstaluj Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Cesta k tvé instalaci GTA: San Andreas obsahuje nepodporované (unicode) znaky. Prosím pÅ™esuň tvou Grand Theft Auto: San Andreas instalaci do a komatibilního adresáře který obsahuje pouze standartní ASCII znaky a reinstaluj Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Cesta k tvé instalaci 'MTA:SA' nebo 'GTA: San Andreas'\n" -"obsahuje ';' (stÅ™edník).\n\n" -" Pokud budeÅ¡ mít potíže s MTA:SA,\n" -" pÅ™esuň tvojí instalaci(e) do cesty, která neobsahuje stÅ™edník." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "NaÄtení selhalo. Prosím zkontroluj zda jsou správnÄ› nainstalovány poslední data soubory." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "NaÄtení selhalo. Prosím zkontroluj že %s je nainstalován správnÄ›." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "NaÄtení selhalo. Nelze nalézt gta_sa.exe v %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "NaÄtení selhalo. %s existuje v GTA adresáři. Prosím o smazání pÅ™ed pokraÄováním." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Hlavní soubor má nesprávné jméno (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Hlavní soubor není podepsaný. Potenciální virová aktivita.\n\n" -"Pokud MTA nepracuje správnÄ›, podívej se na online nápovÄ›du." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Datový soubor %s nelze najít. Problém mohl způsobit virus.\n\n" -"Zvaž pÅ™einstalování Multi Theft Auto v zájmu vlastní bezpeÄnosti.\n" -"Pokud MTA nefunguje správnÄ›, pÅ™eÄti si online nápovÄ›du." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Datový soubor %s je upraven. Problém mohl způsobit virus.\n\n" -"Zvaž pÅ™einstalování Multi Theft Auto v zájmu vlastní bezpeÄnosti.\n" -"Pokud MTA nefunguje správnÄ›, pÅ™eÄti si online nápovÄ›du." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "V instalaÄním adresáři 'MTA:SA' nebo 'GTA: San Andreas' se nachází .asi soubory.\n\n" -"Pokud zaznamenáváte potíže s MTA:SA, odstraňte tyto .asi soubory." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Verze souboru se liší. Pokud zaznamenáváte problémy, pÅ™einstalujte MTA:SA.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "NÄ›které soubory chybí. Pokud zaznamenáváte problémy, pÅ™einstalujte MTA:SA.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA není kompatibilní s nouzovým režimem systému Windows.\n\n" -"Prosím, restartujte svůj poÄítaÄ.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Opravit problémy s konfigurací" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Opravit chybu s potÅ™ebnou elevací" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Neznámý" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "Soubor '%s' je blokován %zu procesy.\n\n" +"PÅ™ejeÅ¡ si ukonÄit tyto procesy a pokraÄovat v aktualizaci?\n\n" +"%s" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/Install.cpp:479 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Nelze spustit Grand Theft Auto: San Andreas. Prosím, zkus to znovu, nebo pokud problém pÅ™etrvává, kontaktuj MTA na www.multitheftauto.com. \n\n" -"[%s]" +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "Tvá instalace může být poÅ¡kozená.\n\n" +"%zu z %zu souborů se nepodaÅ™ilo obnovit ze zálohy.\n\n" +"MÄ›l bys pÅ™einstalovat Multi Theft Auto ze stránky www.multitheftauto.com\n" +"nebo zkusit spustit aktualizaci s oprávnÄ›ním administrátora." -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas se možná nespustilo správnÄ›. ChceÅ¡ to ukonÄit?" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Instaluji aktualizace..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Rozbaluji soubory..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA nemohl dokonÄit následující úlohu:\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Pád byl způsoben chybou v ovladaÄích grafické karty **\n\n" +"** Prosím aktualizuj ovladaÄe tvé grafické karty **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Instalovat aktualizované MTA:SA soubory" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Nemohly probÄ›hnout aktualizace kvůli souborovým konfliktům. UkonÄi ostatní aplikace a zkus to znovu" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto nebylo nainstalováno správnÄ›, prosím pÅ™einstaluj jej. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "VytvoÅ™it GTA:SA spojení" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA nebylo možno spustit z důvodu chyby bÄ›hem kopírování souborů:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA nebylo možno spustit z důvodu poÅ¡kozeného nebo chybÄ›jícího MTA:SA souboru:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Kopírovat soubory MTA:SA" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA nebylo možno spustit z důvodu poÅ¡kozeného nebo chybÄ›jícího GTA:SA souboru:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "Aktualizovat závislosti GTA:SA" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA nebylo možno spustit z důvodu poÅ¡kozeného nebo chybÄ›jícího spouÅ¡tÄ›Äe GTA:SA:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Prosím zkontrolujte svůj antivirový program a zkuste v nÄ›m zapnout výjimku pro spouÅ¡tÄ›Ä GTA:SA, následnÄ› restartujte MTA:SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "Generovat GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA nebylo možno spustit z důvodu nespustitelného spouÅ¡tÄ›Äe GTA:SA:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Aktualizovat GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA nebylo možno spustit z důvodu chyby bÄ›hem aktualizace GTA:SA:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA nemůže pokraÄovat, protože na disku %s není dostatek místa." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "ChybÄ›jící soubor:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Pokud naÄtení MTA selže, pÅ™einstalujte, prosím, GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Aktualizovat nastavení instalace" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Aktualizovat nastavení kompatibility" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +483,167 @@ msgstr "GTA: San Andreas se možná nespustilo správnÄ›. ChceÅ¡ to ukonÄit?" #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Ano" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Ne" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "OK" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "UkonÄit" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Pomoc" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "ZruÅ¡it" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "V aplikaci MTA: San Andreas doÅ¡lo k problému" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Informace o pádu" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "ZaÅ¡krtnÄ›te pro odeslání informace o pádu vývojářům MTA prostÅ™ednictvím internetu" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Pokud tak uÄiníte, zvýšíte Å¡anci na opravení této chyby." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Chcete restartovat MTA: San Andreas?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Varování" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "Váš instalaÄní adresář Grand Theft Auto: San Andreas obsahuje tyto soubory:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Tyto soubory nejsou hrou vyžadovány a mohou být v konfliktu s grafickými funkcemi této verze MTA:SA.\n\n" "DoporuÄuje se, abyste tyto soubory odstranili nebo pÅ™ejmenovali." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "Zachovat soubory, ale zobrazit toto varování i pÅ™i dalším spuÅ¡tÄ›ní" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Neupozorňovat mne již na tyto soubory" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "PÅ™ejmenovat tyto soubory z *.dll na *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Zobrazit tyto soubory" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Hrát MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Matoucí nastavení" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "Technologie NVidia Optimus byla detekována!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Zkuste každou možnost a uvidíte, která funguje:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Standardní NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Alternativní NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Standardní Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Alternativní Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Pokud jsi zoufalý, toto ti může pomoct:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Pokud jsi již vybral možnost, která funguje, tohle by mohlo pomoct:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Vynutit režim v oknÄ›" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Znovu nezobrazovat" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Varování: Nebyl nalezen žádný antivirus" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1107 +651,1180 @@ msgstr "MTA nenalezlo žádný antivir na tvém poÄítaÄi.\n\n" "Viry ovlivňují MTA a mohou kazit tvůj herní zážitek.\n\n" "Klikni na tlaÄíto 'NápovÄ›da' pro více informací." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Antivir mám již nainstalovaný" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Nehodlám si antivir nainstalovat.\n" "Chci, aby se můj poÄítaÄ sekal a byl souÄástí botnetu." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Hledám Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Prosím spusÅ¥ Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Instaluji aktualizace..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "PÅ™ipojování selhalo. Neplatný nick!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Rozbaluji soubory..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "PÅ™ipojování selhalo. Neplatný hostitel!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Kopíruji soubory..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "PÅ™ipojování k %s na portu %u selhalo!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopírování zkonÄilo pÅ™edÄasnÄ›. VÅ¡e OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "PÅ™ipojuji k %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "DokonÄování..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Hotovo!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "PŘIPOJUJI" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA potÅ™ebuje Administrátorská oprávnÄ›ní pro následující operaci:\n\n" -" '%s'\n\n" -"Prosím potvrÄ v následujícím oknÄ›." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "ÄŒasový limit spojení vyprÅ¡el" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA nemohl dokonÄit následující úlohu:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Odpojeno: neznámá chyba protokolu" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Pád byl způsoben chybou v ovladaÄích grafické karty **\n\n" -"** Prosím aktualizuj ovladaÄe tvé grafické karty **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Odpojeno: odpojeno vzdálenÄ›" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Instalovat aktualizované MTA:SA soubory" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Odpojeno: spojení ztraceno vzdálenÄ›" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Nemohly probÄ›hnout aktualizace kvůli souborovým konfliktům. UkonÄi ostatní aplikace a zkus to znovu" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Odpojeno: jsi zabanován na tomto serveru" -#: Client/loader/CInstallManager.cpp:561 -#, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto nebylo nainstalováno správnÄ›, prosím pÅ™einstaluj jej. %s" +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Odpojeno: odpojeno od serveru" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "VytvoÅ™it GTA:SA spojení" +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Odpojeno: spojení se serverem bylo ztraceno" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA nebylo možno spustit z důvodu chyby bÄ›hem kopírování souborů:" +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Odpojeno: spojení bylo odmítnuto" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA nebylo možno spustit z důvodu poÅ¡kozeného nebo chybÄ›jícího MTA:SA souboru:" +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 +#, c-format +msgid "No such mod installed (%s)" +msgstr "Není nainstalován takový mód (%s)" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Kopírovat soubory MTA:SA" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Å patná odpovÄ›Ä od serveru (2)" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA nebylo možno spustit z důvodu poÅ¡kozeného nebo chybÄ›jícího GTA:SA souboru:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Å patná odpovÄ›Ä od serveru (1)" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Aktualizovat závislosti GTA:SA" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "ÄŒeÅ¡tina" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA nebylo možno spustit z důvodu poÅ¡kozeného nebo chybÄ›jícího spouÅ¡tÄ›Äe GTA:SA:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "ZaneprázdnÄ›n" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Prosím zkontrolujte svůj antivirový program a zkuste v nÄ›m zapnout výjimku pro spouÅ¡tÄ›Ä GTA:SA, následnÄ› restartujte MTA:SA." +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Nyní nelze zkontrolovat aktualizace" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Generovat GTA:SA" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s je potÅ™eba" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA nebylo možno spustit z důvodu nespustitelného spouÅ¡tÄ›Äe GTA:SA:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Aktualizovaná verze MTA:SA %s je zapotÅ™ebí pro pÅ™ipojení k zvolenému serveru.\n\n" +"ChceÅ¡ stáhnout a nainstalovat MTA:SA %s ?" + +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "ChceÅ¡ spustit MTA:SA %s a pÅ™ipojit se k tomuto serveru?" + +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Není možné se teÄ pÅ™ipojit.\n\n" +"Zkus to pozdÄ›ji." -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Aktualizovat GTA:SA" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "PÅ™ipojuje se" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA nebylo možno spustit z důvodu chyby bÄ›hem aktualizace GTA:SA:" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Prosím Äekej..." -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA nemůže pokraÄovat, protože na disku %s není dostatek místa." +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "KONTROLUJI" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "ChybÄ›jící soubor:" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "KONTROLA AKTUALIZACÃ" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Pokud naÄtení MTA selže, pÅ™einstalujte, prosím, GTA:SA" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Není tÅ™eba žádná aktualizace" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Aktualizovat nastavení instalace" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "STAHOVÃNÃ" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Aktualizovat nastavení kompatibility" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "Äekám..." -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Neznámý" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "POTŘEBNà AKTUALIZACE" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "Soubor '%s' je blokován %zu procesy.\n\n" -"PÅ™ejeÅ¡ si ukonÄit tyto procesy a pokraÄovat v aktualizaci?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Pro pÅ™ipojení k tomuto serveru musíš aktualizovat MTA.\n\n" +" ChceÅ¡ aktualizovat nyní?" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "Tvá instalace může být poÅ¡kozená.\n\n" -"%zu z %zu souborů se nepodaÅ™ilo obnovit ze zálohy.\n\n" -"MÄ›l bys pÅ™einstalovat Multi Theft Auto ze stránky www.multitheftauto.com\n" -"nebo zkusit spustit aktualizaci s oprávnÄ›ním administrátora." +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "VOLITELNà AKTUALIZACE" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Server doporuÄuje aktualizaci, která vÅ¡ak není nutná.\n\n" +" ChceÅ¡ aktualizovat nyní?" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "CHYBA UKLÃDÃNÃ" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Zvol tvůj Grand Theft Auto: San Andreas instalaÄní adresář" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Nelze vytvoÅ™it soubor." -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Chyba pÅ™i naÄítání %s modulu! (%s)" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "CHYBA STAHOVÃNÃ" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Byla zaznamenána nová instalace %s.\n\n" -"Chcete vaÅ¡e nastavení zkopírovat z %s?" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Stažený soubor se zdá být nesprávný." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA mÄ›lo potíže pÅ™i otevírání souboru '%s'" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Z nÄ›jakého důvodu." -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA zaznamenalo chybÄ›jící soubor '%s'." +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "STAHOVÃNà DOKONÄŒENO" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA objevilo potíže pÅ™i naÄítání modelu." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Neznámý problém v _DialogUpdateResult" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Pokud jsi v nedávné dobÄ› upravoval gta3.img, zkus pÅ™einstalovat GTA:SA." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "UPRAVENÉ GTA:SA SOUBORY" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA odhalilo problém pÅ™i pokusu o pÅ™idání vylepÅ¡ení na vozidlo." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ok" + +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "CHYBA" + +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "NÄ›které soubory dat MTA:SA nebyli nenalezeny.\n\n\n" +"Prosím pÅ™einstaluj MTA:SA" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA nalezlo chyby v souboru '%s'" +msgid "%3d %% completed" +msgstr "%3d %% dokonÄeno" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Restartoval se tvůj poÄítaÄ pÅ™i hraní MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"ÄŒekám na odpovÄ›Ä - %-3d" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "UkonÄi, prosím, následující programy pÅ™ed pokraÄováním:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ PŘÃKAZY ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Požadavky stránek" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* PrávÄ› je %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Server požaduje tvé povolení následujících stránek pro jejich (pozdÄ›jší) naÄtení:" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NIKDY NEZADÃVEJTE CITLIVÉ INFORMACE PRO OCHRANU PŘED ODCIZENÃM" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "connect: Správný tvar je 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Pamatovat výbÄ›r" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "connect: Å patné Äíslo portu" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Povolit" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "connect: PÅ™ipojuji se k %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Odmítnout" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "connect: nelze se pÅ™ipojit k %s:%u!" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "Hlavní menu" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "connect: Selhalo vypínání aktuálního módu" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "PrávÄ› používáš verzi pro zkouÅ¡ení aktualizací! Tato verze je pouze pro testování a nemůže být použita pro pÅ™ipojení k veÅ™ejným serverům!" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA již nebude získavat aktualizace na XP/Vista po ÄŒervenci 2019.\n\n" -"Aktualizujte Windows pro hraní na nejnovÄ›jších serverech." +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Toto tÄ› odpojí z aktuálního serveru.\n\n" -"Jsi si jist že se chceÅ¡ odpojit?" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "VAROVÃNà O ODPOJENÃ" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "INFORMACE" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "NaÄtena ovládání z GTA" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "ÄŒeÅ¡tina" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "KonfiguraÄní soubor uložen" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Tvůj serial je: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "NASTAVENÃ" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Hra více hráÄů" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Grafika" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Zvuk" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Bindy" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Ovládání" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Rozhraní" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Internetový prohlížeÄ" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "PokroÄilé" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "NaÄíst výchozí" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Senzitivita myÅ¡i:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Senzitivita vertikálního zaměřování:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Možnosti myÅ¡i" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Obrátit myÅ¡ vertikálnÄ›" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Řídit myší" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Lítat myší" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Nastavení joypadu" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standartní ovládání (MyÅ¡ + Klávesnice)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Klasické ovládání (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Mrtvá zóna" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Sytost" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Použij záložku 'Bindy' pro tlaÄítka joypadu." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Levá páÄka" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Pravá páÄka" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "POPIS" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "KLÃVESA" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. KLÃVESA" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "PÅ™ezdívka:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Ukládat hesla serverů" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Automatická obnova prohlížeÄe serverů" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Povolit nahrávání screenů" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Povolit externí zvuky" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Vždy zobrazit okno stahování" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Povolit pÅ™ipojení pÅ™es Discord RPC" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Používat upravené soubory GTA:SA" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Možnosti vykreslování mapy" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Neprůhlednost:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "1024 x 1024 (Výchozí)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Hlavní hlasitost:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Hlasitost rádia:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "SFX Hlasitost:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA Hlasitost:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Hlasitost hlasu:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Herní mód:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Obecné" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Nastavení rádia" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Ekvalizér rádia" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Auto-tune rádia" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Usertrack nastavení" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Rádio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Náhodný" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "SekvenÄní" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Automatické skenování médií" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Možnosti ztlumení" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Ztlumit vÅ¡echny zvuky, když je hra minimalizována" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Ztlumit zvuky rádia, když je hra minimalizována" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Ztlumit SFX zvuky, když je hra minimalizována" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Ztlumit MTA zvuky, když je hra minimalizována" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Ztlumit hlasy, když je hra minimalizována" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "RozliÅ¡ení:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Zorné pole:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Vzdálenost vykreslování:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Jas:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX Kvalita:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anizotropní filtrování:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Vyhlazování:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "PomÄ›r stran:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "V oknÄ›" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI aware" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Standardní" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Bez okraje, zachovat rozliÅ¡ení" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "MIP mapování" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Nízké" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "StÅ™ední" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Vysoké" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Velmi vysoké" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Vypnuto" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Automaticky" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "PÅ™izpůsobit HUD pomÄ›ru stran" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Volumetrické Stíny" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Efekt trávy" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Tetelení" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "KouÅ™ pneumatik, apod." -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Dynamické stíny postav" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Rozmazání pÅ™i pohybu" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Odraz koróny v deÅ¡ti" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Celý Obraz Minimalizovat" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Povolit Dialog Zvolení Zařízení" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Zobrazit nebezpeÄná rozliÅ¡ení" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Vykreslovat vozidla vždy ve vysoké kvalitÄ›" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Vykreslovat postavy vždy ve vysoké kvalitÄ›" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Povolit vzdálené stránky" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Povolit Javascript na vzdálených stránkách" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Vlastní Äerná listina" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Zadej doménu, napÅ™.: google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Zablokovat" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Doména" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Odstranit doménu" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Vlastní bílá listina" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Povolit" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Různé" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Rychlé nahrávaní CJ obleÄení:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Rychlost prohlížeÄe:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Jednotné spojení:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "OznaÄení paketu:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Animace průbÄ›hu:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Priorita procesu:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Nastavení debugu:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Streamovací paměť:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Typ aktualizací:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Instalace důležitých aktualizací:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Zapnuto" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Velmi pomalu" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Výchozí" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Rychle" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normální" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Vyšší, než normální" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Min" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Max" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Kompatibilita s Windows 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16bitové barvy" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Fixace myÅ¡i" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Klientové soubory:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Zobrazit v průzkumníku" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Automatické aktualizace" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Zkontrolovat aktualizace nyní" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "NÄ›která nastavení budou zmÄ›nÄ›na až pÅ™i příštím spuÅ¡tÄ›ní MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "ChceÅ¡ provést restart teÄ?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "JE VYŽADOVÃN RESTART" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "NÄ›která nastavení budou zmÄ›nÄ›na až po odpojení ze serveru" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "ChceÅ¡ se nyní odpojit?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "VYŽADOVÃNO ODPOJENÃ" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad nebyl zjiÅ¡tÄ›n - Zkontroluj pÅ™ipojení a restartuj hru" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Bindovací osa" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Posuň osou pro bindování, nebo ESC pro zruÅ¡ení" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Jazyk:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Vzhled:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "PÅ™ednastavení:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Chat" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "NaÄíst" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Barvy" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Uspořádání" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Možnosti" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Pozadí chatu" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Text v chatu" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Pozadí vstupu" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Vstupní text" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Řádků:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Å kála:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Šířka:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Velikost" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "po" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "pro" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "sek" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "PÅ™echod" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Skrýt staré řádky" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horizontální:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Vertikální:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Zarovnání textu:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "Odsazení X:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Odsazení Y:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Pozice" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Vlevo" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "UprostÅ™ed" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Vpravo" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "NahoÅ™e" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Dole" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Písmo" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Skrýt pozadí když nepíši" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "DokonÄení rozepsaného jména klávesou \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Povolit serveru zablikat oknem" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Povolit notifikace v liÅ¡tÄ›" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "ÄŒerné/bílé obtažení textu v chatu" @@ -1548,89 +1832,95 @@ msgstr "ÄŒerné/bílé obtažení textu v chatu" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Stiskni klávesu pro bindování, nebo ESC pro zruÅ¡ení" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Bindování primárního tlaÄítka" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Bindování sekundárního tlaÄítka" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA HERNà OVLÃDÃNÃ" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "OVLÃDÃNà MULTIPLAYERU" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Tvůj nick obsahuje nepovolené znaky!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Hlavní menu" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "Ve hÅ™e" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "ÄŒervená:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Zelená:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Modrá:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Průhlednost:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Barva" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Ukázka" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Prosím, odpoj se, pÅ™ed zmÄ›nou jazyku" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Prosím odpoj se pÅ™ed zmÄ›nou skinu" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Volumetrické stíny mohou zpomalit tvůj poÄítaÄ.\n\n" "Jsi si jist, že je chceÅ¡ povolit?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "VAROVÃNà O VÃKONU" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Nahrávání screenů je vyžadováno nÄ›kterými servery pro úÄely anti-cheat ochran.\n\n" "(Okno chatu a GUI nejsou zahrnuty pÅ™i nahrávání)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "INFORMACE O NAHRÃVÃNà SCREENÅ®" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1638,23 +1928,21 @@ msgstr "NÄ›které skripty mohou pÅ™ehrávat zvuky z internetu, například rádi "Vypnutí tohoto nastavení může snížit\n" "spotÅ™ebu výkonu sítÄ›.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "EXTERNà ZVUKY" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "SOUHLAS S POVOLENÃM SDÃLENà DAT" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1664,11 +1952,7 @@ msgstr "NÄ›které soubory ve tvém GTA:SA adresáři jsou upravené.\n" "NicménÄ›, UPRAVENÉ GTA:SA SOUBORY JSOU BLOKOVÃNY NA SPOUSTÄš SERVERÅ®\n\n" "Jsi si jist, že je chceÅ¡ použít?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "UPRAVENÉ GTA:SA SOUBORY" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1678,550 +1962,252 @@ msgstr "Aktivace DPI awareness je experimentální funkce a\n" "Pokud tuto funkci povolíte, mohou se projevit grafické problémy.\n\n" "Jsi si jistý, že chceÅ¡ tuto funkci zapnout?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "EXPERIMENTÃLNà FUNKCE" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Prosím zadej pÅ™ezdívku" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Prosím vlož svoji pÅ™ezdívku, která bude použita ve hÅ™e. \n" "Toto bude tvé jméno zobrazované pÅ™i pÅ™ipojení a hraní na serveru" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Velmi experimentální prvek." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "PÅ™edchází zpomalování s variacemi CJe (Použije 65MB, Äi více RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Starší routery mohou vyžadovat pomalejší rychlost skenování." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Povol pro použití pouze jednoho spojení pÅ™i stahování." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "OznaÄ síťové pakety a pomož tak ISP identifikovat vytížení MTA." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Animace otáÄejícího koleÄka na spodu obrazovky" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Vždy zvol výchozí. (Nastavení se neukládá)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maximum je vÄ›tÅ¡inou nejlepší" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Automatické aktualizace:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Zvol výchozí jestliže nemáš rád vypisování ohlášení bugů." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Vyber výchozí pro automatickou instalaci důležitých aktualizací." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16ti bitové barvy:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Povolit režim 16ti bitových barev - Vyžaduje restart MTA" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Fixace myÅ¡i:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Fixace pohybu myÅ¡i - Může vyžadovat restart poÄítaÄe" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Neznámý příkaz nebo cvar: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "ZaneprázdnÄ›n" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Nyní nelze zkontrolovat aktualizace" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s je potÅ™eba" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Aktualizovaná verze MTA:SA %s je zapotÅ™ebí pro pÅ™ipojení k zvolenému serveru.\n\n" -"ChceÅ¡ stáhnout a nainstalovat MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "ChceÅ¡ spustit MTA:SA %s a pÅ™ipojit se k tomuto serveru?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Není možné se teÄ pÅ™ipojit.\n\n" -"Zkus to pozdÄ›ji." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "PÅ™ipojuje se" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Prosím Äekej..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "KONTROLUJI" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "KONTROLA AKTUALIZACÃ" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Není tÅ™eba žádná aktualizace" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "STAHOVÃNÃ" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "Äekám..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "POTŘEBNà AKTUALIZACE" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Pro pÅ™ipojení k tomuto serveru musíš aktualizovat MTA.\n\n" -" ChceÅ¡ aktualizovat nyní?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "VOLITELNà AKTUALIZACE" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Server doporuÄuje aktualizaci, která vÅ¡ak není nutná.\n\n" -" ChceÅ¡ aktualizovat nyní?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "CHYBA UKLÃDÃNÃ" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Nelze vytvoÅ™it soubor." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "CHYBA STAHOVÃNÃ" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Stažený soubor se zdá být nesprávný." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Z nÄ›jakého důvodu." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "STAHOVÃNà DOKONÄŒENO" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Neznámý problém v _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ok" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "CHYBA" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "NÄ›které soubory dat MTA:SA nebyli nenalezeny.\n\n\n" -"Prosím pÅ™einstaluj MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% dokonÄeno" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"ÄŒekám na odpovÄ›Ä - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "PÅ™ipojování selhalo. Neplatný nick!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "PÅ™ipojování selhalo. Neplatný hostitel!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "PÅ™ipojování k %s na portu %u selhalo!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "PÅ™ipojuji k %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "PŘIPOJUJI" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "ÄŒasový limit spojení vyprÅ¡el" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Odpojeno: neznámá chyba protokolu" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Odpojeno: odpojeno vzdálenÄ›" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Odpojeno: spojení ztraceno vzdálenÄ›" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Odpojeno: jsi zabanován na tomto serveru" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Odpojeno: odpojeno od serveru" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Odpojeno: spojení se serverem bylo ztraceno" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Odpojeno: spojení bylo odmítnuto" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Není nainstalován takový mód (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Å patná odpovÄ›Ä od serveru (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Å patná odpovÄ›Ä od serveru (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "NOVINKY" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "NavÅ¡tivte nejnovÄ›jší Älánek s novinkou" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONZOLE" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Fatální chyba" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "PRO OPRAVU ODSTRAŇ TENTO SOUBOR:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s modul je neplatný!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Chyba pÅ™i otevírání URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "toto pomocné okno" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "ukonÄí aplikaci" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "zobrazí verzi" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "zobrazí Äas" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "zobrazí hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "zobrazí vÅ¡echny bindy" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "zobrazí tvůj serial" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "pÅ™ipojí k serveru (hostitel port nick heslo)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "pÅ™ipojí k pÅ™edchozímu serveru" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "nabinduje tlaÄítko (klávesu)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "odbinduje tlaÄítko (klávesu)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "zkopíruje výchozí gta ovládání" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "uloží screenshot" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "okamžitÄ› uloží konfiguraci" -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "vyÄistí okno ladÄ›ní" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "zaroluje chatem nahoru" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "zaroluje chatem dolů" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "zaroluje debugem nahoru" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "zaroluje oknem ladÄ›ní dolů" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "zobrazí statistiky pamÄ›ti" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "zobrazí graf Äasování snímku" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "pro vývojáře: obnovte novinky" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ PŘÃKAZY ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* PrávÄ› je %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "connect: Správný tvar je 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "connect: Å patné Äíslo portu" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "connect: PÅ™ipojuji se k %s:%u..." - -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "connect: nelze se pÅ™ipojit k %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "vyÄistí okno ladÄ›ní" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "connect: Selhalo vypínání aktuálního módu" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "zaroluje chatem nahoru" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "zaroluje chatem dolů" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "zaroluje debugem nahoru" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "zaroluje oknem ladÄ›ní dolů" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "zobrazí statistiky pamÄ›ti" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "NaÄtena ovládání z GTA" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "zobrazí graf Äasování snímku" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "KonfiguraÄní soubor uložen" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "pro vývojáře: obnovte novinky" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Tvůj serial je: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "PrávÄ› používáš verzi pro zkouÅ¡ení aktualizací! Tato verze je pouze pro testování a nemůže být použita pro pÅ™ipojení k veÅ™ejným serverům!" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Osa akcelerace" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA již nebude získavat aktualizace na XP/Vista po ÄŒervenci 2019.\n\n" +"Aktualizujte Windows pro hraní na nejnovÄ›jších serverech." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Osa brždÄ›ní" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Toto tÄ› odpojí z aktuálního serveru.\n\n" +"Jsi si jist že se chceÅ¡ odpojit?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programování" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "VAROVÃNà O ODPOJENÃ" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "PÅ™ispÄ›vatelé" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "INFORMACE" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Herní Design / Scripting" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "NOVINKY" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Jazyková lokalizace" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "NavÅ¡tivte nejnovÄ›jší Älánek s novinkou" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Patch pÅ™ispÄ›vatelé" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Screenshot má %d bajtů, ale má být %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Zvláštní podÄ›kování" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Screenshot selhal" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Tento software a projekt používá následující knihovny a software:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Snímek obrazovky zachycen: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "ChceÅ¡ se podívat na online pomoc s tímto problémem?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Neznámý příkaz nebo cvar: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2396,25 +2382,56 @@ msgid "Group control backwards" msgstr "Skupinové ovládání dozadu" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Vybraný skin nemůže být naÄten a výchozí skin taktéž, prosím pÅ™einstaluj MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Screenshot má %d bajtů, ale má být %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "ChceÅ¡ se podívat na online pomoc s tímto problémem?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Screenshot selhal" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONZOLE" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Snímek obrazovky zachycen: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programování" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "PÅ™ispÄ›vatelé" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Herní Design / Scripting" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Jazyková lokalizace" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Patch pÅ™ispÄ›vatelé" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Zvláštní podÄ›kování" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Tento software a projekt používá následující knihovny a software:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Osa akcelerace" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Osa brždÄ›ní" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2422,6 +2439,65 @@ msgstr "Nelze inicializovat Direct3D9.\n\n" "Prosím zkontroluj že DirectX End-User Runtime a\n" "poslední Windows Service Pack jsou řádnÄ› nainstalovány." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "NeÄinný" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "hráÄ" +msgstr[1] "hráÄi" +msgstr[2] "hráÄů" +msgstr[3] "hráÄů" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "na" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "server" +msgstr[1] "servery" +msgstr[2] "serverů" +msgstr[3] "serverů" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "NaÄítám hlavní seznam serverů (ubÄ›hlo %lu ms)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Hlavní seznam serverů nemohl být získán." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Hlavní seznam serverů se nepodaÅ™ilo naÄíst." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Záložní seznam serverů)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Nelze svázat LAN-broadcast socket" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Pokouším se najít LAN servery" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2475,7 +2551,7 @@ msgstr "Latence:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Seznam hráÄů" @@ -2502,40 +2578,39 @@ msgstr "PÅ™ipojit se k serveru hned, jakmile se uvolní místo." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "PROSÃM VLOŽ HESLO SERVERU" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "ÄŒas vyprÅ¡el" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Dotazuje se..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "PROHLÃŽEÄŒ SERVERÅ®" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Lokální" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Oblíbené" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Nedávné" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2543,302 +2618,367 @@ msgstr "PRO RYCHLÉ PŘIPOJENÃ:\n\n" "NapiÅ¡ adresu a port do adresního řádku.\n" "Nebo zvol server z historie a stiskni 'PÅ™ipojit'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "POMOC" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Obnovit" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "PÅ™idat Oblíbené" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "PÅ™ipojit" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Server informace" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Hledat servery" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Hledat hráÄe" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "ZaÄít hledání" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Hledat hráÄe..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Hledat servery..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Jméno" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "HráÄi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Ping" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Herní mód" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Zahrnout:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Prázdný" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Plný" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "ZamÄený" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Offline" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Jiné verze" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "ZpÄ›t" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "NaÄítám..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..naÄítám.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Nebyla zadána adresa!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Neznámý protokol" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Prosím použij mtasa:// protokol!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Neplatný nick! Jdi do nastavení a nastav si jiný!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Musíš zvolit server pro pÅ™ipojení." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "NeÄinný" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problém s grafickým ovladaÄem" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "hráÄ" -msgstr[1] "hráÄi" -msgstr[2] "hráÄů" -msgstr[3] "hráÄů" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Nelze nalézt platné rozliÅ¡ení obrazovky." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "na" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Opravdu chcete použít toto rozliÅ¡ení obrazovky?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "server" -msgstr[1] "servery" -msgstr[2] "serverů" -msgstr[3] "serverů" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "NaÄítám hlavní seznam serverů (ubÄ›hlo %lu ms)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Hlavní seznam serverů nemohl být získán." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Požadavky stránek" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Hlavní seznam serverů se nepodaÅ™ilo naÄíst." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Server požaduje tvé povolení následujících stránek pro jejich (pozdÄ›jší) naÄtení:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Záložní seznam serverů)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NIKDY NEZADÃVEJTE CITLIVÉ INFORMACE PRO OCHRANU PŘED ODCIZENÃM" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Nelze svázat LAN-broadcast socket" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Pamatovat výbÄ›r" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Pokouším se najít LAN servery" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Odmítnout" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Tato verze expirovala." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "odpojit ze hry" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "zobrazí nametagy" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "zobrazí chatbox" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "zobrazí síťové statistiky" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "otevÅ™e chat input" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "pÅ™enáší hlas ostatním hráÄům" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "vstoupí do auta jako pasažér" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "další rádio stanice" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "pÅ™edchozí rádio kanál" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "poÅ¡le zprávu urÄenému hráÄi" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "pÅ™epne na další zbraň když jsi ve vozidle" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "pÅ™epne na pÅ™edchozí zbraň když jsi ve vozidle" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "vypisuje informace o aktuálním serveru" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "definuje násobiÄ Å¡kály vÅ¡ech text-zobrazení" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Vývojářský mód) zobrazí colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Vývojářský mód) vytiskne id svÄ›tových zvuků do okna debugu" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "HOSTOVAT HRU" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Resources" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Název serveru:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Heslo:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Max hráÄů:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Vysílání:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Vybráno" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "VÅ¡e" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Spustit" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "Volný pohyb" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Postup stahování mapy:" @@ -2859,174 +2999,174 @@ msgstr "%s z %s" msgid "Disconnect to cancel download" msgstr "Odpoj se pro zruÅ¡ení stahování" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Odpojeno: Neplatný nick" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Odpojeno od serveru" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Odpojeno: Serial je zabanován.\n" "Důvod: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Odpojeno: Jsi zabanován.\n" "Důvod: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Odpojeno: ÚÄet je zabanován.\n" "Důvod: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Odpojeno: Neshoda verzí" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Odpojeno: Join flood. Prosím poÄkej minutu, pak se znovu pÅ™ipoj." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Odpojeno: Server z jiné vÄ›tve.\n" "Informace: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Odpojeno: Å patná verze.\n" "Informace: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Odpojeno: Server běží na novÄ›jší nástavbÄ›.\n" "Informace: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Odpojeno: Server běží na starší nástavbÄ›.\n" "Informace: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Odpojeno: Tuto pÅ™ezdívku již nÄ›kdo používá" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Odpojeno: Objekt hráÄe se nepodaÅ™ilo vytvoÅ™it." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Odpojeno: Server odmítnul spojení: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Odpojeno: Ověřování serialu selhalo" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Odpojeno: Connection desync %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Odpojeno: Byl jsi vyhozen od %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Odpojeno: Byl jsi zabanován od %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Odpojeno: Server byl vypnut, nebo se restartuje" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Byl jsi vyhozen ze hry" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Tento server vyžaduje nepozmÄ›nÄ›ný gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Prosím nahraÄ gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Tento server nepovoluje vlastní D3D9.DLL" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Odstraň D3D9.DLL ze své instalaÄní složky GTA a restartuj MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Tento server nepovoluje virtuální stroje" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Tento server vyžaduje povolit podepisování ovladaÄů" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Prosím, restartuj svůj poÄítaÄ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Tento server detekoval chybÄ›jící anti-cheat komponenty" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Zkus restartovat MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Tento server vyžaduje neupravený gta3.img a gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Prosím, nahraÄ gta3.img nebo gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Tento server nepovoluje Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Ujisti se, že žádný jiný program nezasahuje do MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Zbývající Äas: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" @@ -3035,7 +3175,7 @@ msgstr[1] "%d dny" msgstr[2] "%d dní" msgstr[3] "%d dní" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" @@ -3044,7 +3184,7 @@ msgstr[1] "%d hodiny" msgstr[2] "%d hodin" msgstr[3] "%d hodin" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" @@ -3053,7 +3193,7 @@ msgstr[1] "%d minuty" msgstr[2] "%d minut" msgstr[3] "%d minut" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3063,296 +3203,206 @@ msgstr[2] "%d vteÅ™in" msgstr[3] "%d vteÅ™in" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Odpojeno" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Chyba pÅ™i stahování: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "Lítá s UFO v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "Jezdí v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "Jede na vlnách v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "Jede vlakem v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "Lítá v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "Jede v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "Jede s monster truckem v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "Jede se Ätyrkolkou v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "SkáÄe v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "DÄ›lá divné vÄ›ci v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "Leze v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "DÄ›lá drive-by v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "Blub blub..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "Dýchá vodu" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "Topí se v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "KrÄí se v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "Bojuje v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "Bojuje pomocí pÄ›stí v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "Střílí v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "Střílí" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "Lítá s jetpackem v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "Hoří v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "Hoří v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "Plave v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "Vznáší se v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "Je pronásledovaný žralokem" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "Dusí se v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Vstupuji do hry ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "NepÅ™ipojeno; prosím použij Rychlé PÅ™ipojení nebo příkaz 'connect' pro pÅ™ipojení k serveru." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Lokální server nemohl být spuÅ¡tÄ›n. Podívej se do konzole pro detaily." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Lokální Server" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "SpouÅ¡tím lokální server ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "Area 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "Chodí v " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Byl jsi vyhozen ze hry ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "PÅ™ipojuji k lokálnímu serveru..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Chyba pÅ™i pÅ™ipojování k serveru." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "PÅ™ipojování k lokálnímu serveru vyprÅ¡elo. Podívej se do konzole pro více inromací." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Spojení se serverem bylo ztraceno" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Odpojeno: server je momentálnÄ› plný" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Odpojeno: Å¡patné heslo" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA Client ověření selhalo!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "V příkopÄ›" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "Jede do nemocnice" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "StÅ™etává se s jeho markerem" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "Lituje jeho rozhodnutí" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "Je mrtvý" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "HOSTOVAT HRU" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Resources" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Název serveru:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Heslo:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Max hráÄů:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Vysílání:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Vybráno" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "VÅ¡e" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Spustit" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "Volný pohyb" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problém s grafickým ovladaÄem" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Nelze nalézt platné rozliÅ¡ení obrazovky." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Opravdu chcete použít toto rozliÅ¡ení obrazovky?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Chyba pÅ™i stahování: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3373,11 +3423,11 @@ msgstr "" msgid "Connection error" msgstr "Chyba pÅ™ipojení" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto nebylo správnÄ› nainstalováno, prosím reinstall." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Tvůj prohlížeÄ nyní zobrazí webovou stránku s nápovÄ›dou.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/da_DK/client.pot b/Shared/data/MTA San Andreas/MTA/locale/da_DK/client.pot index 227b0bc4caf..d3f557400f6 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/da_DK/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/da_DK/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:18\n" "Last-Translator: \n" "Language-Team: Danish\n" "Language: da_DK\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Besvær med at genstarte MTA:SA\n\n" -"Hvis problemet vedvarer, Ã¥bn Jobliste og\n" -"stop 'gta_sa.exe' og 'Multi Theft Auto.exe' processer\n\n\n" -"Prøv at starte MTA:SA igen?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Fejl" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "En anden instans af MTA kører allerede.\n\n" -"Hvis dette problem vedvarer, genstart venligst din computer" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "En anden instans af MTA kører allerede.\n\n" -"Ønsker du at afslutte den?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Vælg din Grand Theft Auto: San Andreas installations mappe" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA har brug for Adminstrator adgang for at udføre den følgende opgave:\n\n" +" '%s'\n\n" +"Vær venlig at bekræfte i det næste vindue." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Fejl i indlæsning af %s modul! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Kopiering af filer..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopi blev færdig før tid. Alt er OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Færdiggører..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Færdig!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Ny installation af %s fundet.\n\n" +"Ønsker du at kopiere dine indstillingere fra %s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA havde problemer med Ã¥bning af filen '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA mangler filen '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA havde problemer med indlæsning af en model." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Hvis du for nylig har modificeret gta3.img, sÃ¥ prøv at geninstaller GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA havde problemer med at tilføje en opgradering til et køretøj." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA har fundet fejl i filen '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Genstartede din computer imens du spillede MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Afslut venligst de følgende programmer for at fortsætte:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Fil version uoverensstemmelse fejl. Geinstaller MTA:SA hvis du oplever problemer.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Nogle filer mangler. Geinstaller MTA:SA hvis du oplever problemer.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA er ikke kompatibel med Windows 'Fejlsikker Tilstand'.\n\n" +"Genstart venligst din PC.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Har du problemer med at køre MTA:SA?.\n\n" "Ønsker du at vende tilbage til en tidligere version?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "Det lader til at MTA:SA har problemer med at starte.\n" "Nulstilling af GTA settings kan somme tider hjælpe pÃ¥ problemet.\n\n" "Ønsker du at nulstille GTA settings nu?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA indstillingere er nulstillet.\n\n" "Tryk OK for at fortsætte." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Fil kunne ikke fjernes: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Har du problemer med at køre MTA:SA?.\n\n" "Ønsker du at se noget online hjælp?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Har du problemer med at køre MTA:SA?.\n\n" "Ønsker du at ændre den følgende indstilling?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Fuldskærm tilstand:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Borderless vindue" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Har du problemer med at køre MTA:SA?.\n\n" "Prøv at deaktivere de følgende produkter for GTA og MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,128 +189,288 @@ msgstr "ADVARSEL\n\n" "MTA:SA har fundet usædvanlig aktivitet.\n" "Kør venligst et virus scan for at sikre at dit system er sikker.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Den registrerede fil var: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "En instans af GTA: San Andreas kører allerede. Det kræves at den afsluttes før MTA:SA kan startes. Ønsker du at gøre det nu?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Det var ikke muligt at afslutte GTA: San Andreas. Hvis problemet vedvarer, genstart venligst din computer." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Besvær med at genstarte MTA:SA\n\n" +"Hvis problemet vedvarer, Ã¥bn Jobliste og\n" +"stop 'gta_sa.exe' og 'Multi Theft Auto.exe' processer\n\n\n" +"Prøv at starte MTA:SA igen?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Fejl" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "En anden instans af MTA kører allerede.\n\n" +"Hvis dette problem vedvarer, genstart venligst din computer" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "En anden instans af MTA kører allerede.\n\n" +"Ønsker du at afslutte den?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Elementer i registreringsdatabasen mangler. Geninstaller venligst Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Stien til din installation af GTA: San Andreas indeholder ikke-understøttet (unicode) tegn. Flyt din Grand Theft Auto: San Andreas installation til en kompatibel sti, som kun indeholder standard ASCII tegn og geninstaller Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Stien til din installation af 'MTA:SA' eller 'GTA: San Andreas'\n" -"indeholder et ';' (semikolon).\n\n" -"Hvis du oplever problemer nÃ¥r MTA:SA kører,\n" -"sÃ¥ flyt din installation(er) til en sti, som ikke indeholder et semikolon." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Indlæsning fejlede. Sørg for at de seneste data filer er blevet installeret korrekt." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Indlæsning fejlede. Sørg for at %s er installeret korrekt." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Indlæsning fejlede. Kunne ikke finde gta_sa.exe i %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Indlæsning fejlede. %s findes i GTA folderen. Vær venlig at slette før du fortsætter." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Hovedfil har et ukorrekt navn (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Hovedfil er usigneret. Mulig virus aktivitet.\n\n" -"Se online hjælp hvis MTA ikke virker korrekt." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 +#, c-format +msgid "Data file %s is modified. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" +msgstr "Fiks konfiguration problemet" + +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "" + +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/Install.cpp:479 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "Der er fundet .asi filer i 'MTA:SA' eller 'GTA: San Andreas' installations folder.\n\n" -"Fjern disse .asi filer hvis du oplever problemer med MTA:SA." +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Installerer opdatering..." -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Fil version uoverensstemmelse fejl. Geinstaller MTA:SA hvis du oplever problemer.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Pakker filer ud..." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Nogle filer mangler. Geinstaller MTA:SA hvis du oplever problemer.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA kunne ikke fuldføre den følgende opgave:\n\n" +"'%s'\n" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA er ikke kompatibel med Windows 'Fejlsikker Tilstand'.\n\n" -"Genstart venligst din PC.\n" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** En fejl i grafikkortet's driver var grund til nedbruddet **\n\n" +"** Opdater venligst dit grafikkort's drivere **" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" -msgstr "Fiks konfiguration problemet" +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Fiks krævede højde fejl" +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Installer opdaterede MTA:SA filer" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Kunne ikke opdatere pga. konflikter med filer. Vær venlig at lukke andre applikationer og prøv igen" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1088 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Grand Theft Auto: San Andreas kunne ikke startes. Prøv venligst at genstarte din PC, eller hvis problemet vedvarer, kontakt MTA pÃ¥ www.multitheftauto.com. \n\n" -"[%s]" +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto blev ikke installeret ordentlig, vær venlig at prøve igen. %s" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "Det er muligt at GTA: San Andreas ikke startede korrekt. Ønsker du at afslutte det?" +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA kan ikke forsætte, da drev %s har utilstrækkeligt plads." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Manglende fil:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Hvis MTA fejler i at starte, prøv venligst at geninstallere GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Opdater installationsindstillinger" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Opdater kompatibilitetsindstillinger" #. ///////////////////////////////////////////////////////////////////////// #. @@ -268,166 +478,166 @@ msgstr "Det er muligt at GTA: San Andreas ikke startede korrekt. Ønsker du at a #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Ja" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Nej" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Afslut" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Hjælp" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Annullér" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas rendte ind i et problem" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Information fra uventet afslutning af spillet" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Tjek boksen for at sende info om uventet afslutning til MTA udviklere ved brug af 'internettet'" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Gør du det, vil det øge chancen for at fÃ¥ problemet løst." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Ønsker du at genstarte MTA: San Andreas?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Advarsel" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Spil MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Forvirrende valgmuligheder" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus opdaget!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Prøv hver af disse muligheder og se hvad der fungere:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Hvis du bliver desperat, kan dette mÃ¥ske hjælpe:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Tving vinduet tilstand" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Advarsel: Opdagede ikke noget anti-virus produkt" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -435,1102 +645,1180 @@ msgstr "MTA kunne ikke finde et anti-virus program pÃ¥ din PC.\n\n" "Viruser kan forstyrre MTA og forringe din spiloplevelse.\n\n" "Tryk 'Hjælp' for at finde mere information." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Jeg har allerede installeret anti-virus" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Jeg ønsker ikke at installere noget anti-virus.\n" "Jeg ønsker at min PC forbliver inficeret og samtidig forringe min spiloplevelse." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Søger efter Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Vær venlig at starte Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Installerer opdatering..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Forbindelsen mislykkedes. Ugyldigt navn!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Pakker filer ud..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Forbindelsen mislykkedes. Ugyldig host!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Kopiering af filer..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Tilslutning af %s port %u fejlet!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopi blev færdig før tid. Alt er OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Tilslutter til %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Færdiggører..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Færdig!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "TILSLUTTER" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA har brug for Adminstrator adgang for at udføre den følgende opgave:\n\n" -" '%s'\n\n" -"Vær venlig at bekræfte i det næste vindue." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Forbindelsen udløbede" -#: Client/loader/CInstallManager.cpp:376 +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Afbrudt: ukendt fejl i protokol" + +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Forbindelsen afbrudt: fjernt frakoblet" + +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Afbrudt: forbindelse mistet fjernt" + +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Afbrudt: du er blevet banned fra denne server" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Afbrudt: afbrudt fra serveren" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Afbrudt: mistede forbindelse til serveren" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Afbrudt: forbindelse blev nægtet" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA kunne ikke fuldføre den følgende opgave:\n\n" -"'%s'\n" +msgid "No such mod installed (%s)" +msgstr "Ingen sÃ¥dan mod er installeret (%s)" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** En fejl i grafikkortet's driver var grund til nedbruddet **\n\n" -"** Opdater venligst dit grafikkort's drivere **" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "DÃ¥rlig server respons (2)" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Installer opdaterede MTA:SA filer" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "DÃ¥rlig server respons (1)" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Kunne ikke opdatere pga. konflikter med filer. Vær venlig at lukke andre applikationer og prøv igen" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Dansk" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Travl" + +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Kan ikke se efter opdateringer lige nu" + +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto blev ikke installeret ordentlig, vær venlig at prøve igen. %s" +msgid "MTA:SA %s required" +msgstr "MTA:SA %s nødvendig" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "En opdateret version af MTA:SA %s er nødvendig for tilslutning af denne server.\n\n" +"Ønsker du at downloade og installere denne MTA:SA %s opdatering?" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Ønsker du at starte MTA:SA %s og tilslutte til denne server?" + +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Det er ikke muligt at tilslutte pÃ¥ dette tidspunkt.\n\n" +"Forsøg igen senere." + +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Tilslutter" + +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Vent venligst..." -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "TJEKKER" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "OPDATERING CHECK" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Ingen opdatering behøvet" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "DOWNLOADER" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "venter..." -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "OBLIGATORISK OPDATERING" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "For at tilslutte til denne server, skal du opdatere MTA.\n\n" +"Ønsker du at opdatere nu?" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "FRIVILLIG OPDATERING" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Serveren siger at en opdatering anbefales, men er ikke væsentlig.\n\n" +"Ønsker du at opdatere nu?" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA kan ikke forsætte, da drev %s har utilstrækkeligt plads." - -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Manglende fil:" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "FEJL I GEMNING" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Hvis MTA fejler i at starte, prøv venligst at geninstallere GTA:SA" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Det var ikke muligt at skabe filen." -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Opdater installationsindstillinger" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "FEJL I DOWNLOAD" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Opdater kompatibilitetsindstillinger" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Den hentede fil lader til at være ukorrekt." -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Af en eller anden grund." -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "DOWNLOAD FULDFØRT" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr "- Ukendt problem i _DialogUpdateResult" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "MODIFICEREDE GTA:SA FILER" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" msgstr "" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "FEJL" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Vælg din Grand Theft Auto: San Andreas installations mappe" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Nogle MTA:SA data filer mangler.\n\n\n" +"Geninstaller venligst MTA:SA" -#: Client/loader/Utils.cpp:1066 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "Error loading %s module! (%s)" -msgstr "Fejl i indlæsning af %s modul! (%s)" +msgid "%3d %% completed" +msgstr "%3d %% fuldført" -#: Client/loader/Utils.cpp:1499 +#: Client/core/CVersionUpdater.cpp:2840 #, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Ny installation af %s fundet.\n\n" -"Ønsker du at kopiere dine indstillingere fra %s ?" +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Venter pÃ¥ svar - %-3d" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA havde problemer med Ã¥bning af filen '%s'" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ KOMMANDO HJÆLP ]***\n" -#: Client/loader/Utils.cpp:1560 +#: Client/core/CCommandFuncs.cpp:158 #, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA mangler filen '%s'." +msgid "* The time is %d:%02d:%02d" +msgstr "* Klokken er %d:%02d:%02d" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA havde problemer med indlæsning af en model." +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Hvis du for nylig har modificeret gta3.img, sÃ¥ prøv at geninstaller GTA:SA." +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "tilslut: Syntax er 'tilslut [ ]'" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA havde problemer med at tilføje en opgradering til et køretøj." +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "tilslut: DÃ¥rligt port nummer" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CCommandFuncs.cpp:255 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA har fundet fejl i filen '%s'" - -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Genstartede din computer imens du spillede MTA:SA?" - -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Afslut venligst de følgende programmer for at fortsætte:" - -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Hjemmeside anmoder" - -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Serveren anmoder om den følgende hjemmeside for at kunne indlæses (senere):" - -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "ALDRIG INDTAST SKRØBELIG DATA FOR AT BESKYTTE DET FRA AT BLIVE STJÃ…LET" - -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Husk beslutning" +msgid "connect: Connecting to %s:%u..." +msgstr "tilslut: Tilslutter til %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Tillad" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "tilslut: kunne ikke tilslutte til %s:%u!" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Afvis" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "tilslut: Lykkedes ikke at fjerne nuværende mod" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Du benytter et funktions-gren build! Dette er kun et test build, hvilket ikke kan bruges for tilslutning til offentlige servere!" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA vil ikke modtage opdateringer pÃ¥ XP/Vista efter Juli 2019.\n\n" -"Opgrader Windows for at spille pÃ¥ de nyeste servere." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Dette vil afbryde dig fra din nuværende server.\n\n" -"Er du sikker pÃ¥ at du vil afbryde?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "AFBRYDELSE ADVARSEL" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Bundet alle knapper fra GTA" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Gemt konfigurationsfil" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Dansk" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Dit serienummer er: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "INDSTILLINGER" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Lyd" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Bindinger" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Kontroller" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Brugerflade" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Internet Browser" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Avanceret" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Indlæs standarder" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Musefølsomhed:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Lodret-sigte følsomhed:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Mus valgmuligheder" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Vend musen lodret" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Styr med musen" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Flyv med musen" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Joypad indstillinger" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standard kontrollerer (Mus + Tastatur)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Klassiske kontrollerer (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Dødszone" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Mætning" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Brug \"Bindinger\" fanen til joypad knapper." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Venstre pind" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Højre pind" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "BESKRIVELSE" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "KNAP" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. KNAPPEN" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Øgenavn:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Gem server kodeord" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Auto-opdater serverlisten" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Tillad skærmbillede upload" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Tillad eksterne lyde" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Brug modificerede GTA:SA filer" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Kort opløsnings valgmuligheder" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Gennemsigtighed:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Master lyd:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Radio lyd:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "SFX lyd:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA lyd:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Stemme lyd:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Afspilningstilstand:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Generalt" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Radio valgmuligheder" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Radio automatisk indstilling" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Brugerspor valgmuligheder" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Tilfældig" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Sekventiel" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Automatisk Medier Scan" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Dæmpning valgmuligheder" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Dæmp alle lyde nÃ¥r minimeret" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Dæmp radio lyde nÃ¥r minimeret" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Dæmp SFX lyde nÃ¥r minimeret" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Dæmp MTA lyde nÃ¥r minimeret" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Dæmp stemmer nÃ¥r minimeret" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Opløsning:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Lysstyrke:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX Kvalitet:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anisotropisk filtrering:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Billedformat:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Vinduet tilstand" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI opmærksom" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Borderless behold opløsning" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Lav" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Høj" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Meget høj" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Fra" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD Match Billedformat" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Volumetriske Skygger" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Græs effekt" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Varme dis" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Bildæk røg osv" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Fuldskærm minimering" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Vis dialog for valg af enhed" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Vis usikre opløsninger" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Vis altid biler i høj detalje" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Vis altid peds i høj detalje" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Aktiver eksterne hjemmesider" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Aktiver Javascript pÃ¥ eksterne hjemmesider" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Brugerdefineret blacklist" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Indsæt et domæne, f.eks google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Bloker" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Domæne" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Fjern domæne" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Brugerdefineret whitelist" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Tillad" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Div" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Hurtig indlæsning af CJ beklædning:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Browser hastighed:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Enkelt forbindelse:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Pakkemærke:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Fremskridts animation:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Process prioritet:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Debug indstilling:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Streaming hukommelse:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Opdater build type:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Installer vigtige opdateringer:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Til" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Meget langsom" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Standard" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Hurtig" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normalt" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Over normalt" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Minimum" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Maks" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 kompatibilitet:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-bit farve" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Mus fiks" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Klient ressource filer:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Vis i Explorer" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Auto opdatering" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Check efter opdatering nu" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Nogle indstillinger vil ændres næste gang du starter MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Ønsker du at genstarte nu?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "GENSTART PÃ…KRÆVET" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Nogle indstillinger vil ændres nÃ¥r du afslutter fra serveren" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Ønsker du at afslutte nu?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "AFKOBLING FRA SERVEREN NØDVENDIGT" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad blev ikke blev ikke registreret - Check kabler og genstart spillet" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Binder akse" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Bevæg en akse for at binde, eller Esc for at rydde" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Sprog:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Forudindstillingere:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Indlæs" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Farver" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Opsætning" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Valgmuligheder" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Chat baggrund" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Chat tekst" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Input baggrund" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Input tekst" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Linjer:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Skala:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Bredde:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Størrelse" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "efter" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "sek" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Falmer" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Gamle linjer falmes ud" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Vandret:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Lodret:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Tekst tilpasning:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Venstre" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Midten" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Højre" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Bund" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Skrifttype" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Skjul baggrund nÃ¥r der ikke skrives" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Færdiggørelse af øgenavn ved knapen \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Tillad serveren at fÃ¥ vinduet til at blinke" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Tillad systembakke notifikationer" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Chat tekst sort/hvid outline" @@ -1538,89 +1826,95 @@ msgstr "Chat tekst sort/hvid outline" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Tryk en knap for at binde, eller Esc for at rydde" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Binder en primær knap" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Binder en sekundær knap" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA SPIL KONTROLLERE" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "MULTIPLAYER KONTROLLERE" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Dit navn indeholder ugyldige tegn!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Rød:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Grøn:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "BlÃ¥:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Gennemsigtighed:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Farve" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "ForhÃ¥ndsvisning" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Afslut venligst fra serveren før at du ændrer sprog" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Afslut venligst fra serveren før du at ændrer skin" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Volumetriske skygger kan medføre sinket hastighed af visse systemer.\n\n" "Er du sikker pÃ¥ at du vil aktivere dem?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "YDEEVNE ADVARSEL" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Upload af skærmens billede er pÃ¥krævet af nogle servere, med hensigt pÃ¥ anti-cheat.\n\n" "(Chat boksen og GUI er ekskluderet i uploaden)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "SKÆRM UPLOAD INFORMATION" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1628,21 +1922,21 @@ msgstr "Nogle scripts kan afspille visse lyde, sÃ¥som radio, fra internettet.\n\ "Deaktivering af denne indstilling kan formindske netværk\n" "bÃ¥ndbredde forbrugelse.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "EKSTERN LYDE" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1652,11 +1946,7 @@ msgstr "Nogle filer i din GTA:SA data folder er modificeret.\n" "Giv agt, MODIFICEREDE GTA:SA FILER ER BLOKERET AF MANGE SERVERE\n\n" "Er du sikker pÃ¥ at du vil benytte dem? " -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "MODIFICEREDE GTA:SA FILER" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1666,550 +1956,252 @@ msgstr "Aktivering af opmærksomhed pÃ¥ DPI er en eksperimental funktion og\n" "Du kan opleve grafiske problemer hvis du aktiverer denne indstilling.\n\n" "Er du sikker pÃ¥ at du vil aktivere denne indstilling?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "EKSPERIMENTAL FUNKTION" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Vær venlig at indtaste et øgenavn" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Vær venlig at indtaste dit øgenavn som skal bruges i spillet. \n" "Dette vil være dit navn nÃ¥r du slutter til og spiller en server" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Meget eksperimental funktion." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Stopper med at gÃ¥ i stÃ¥ ved CJ variationer (Bruger 65MB mere RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Ældre routere kan behøve en langsommere scanning." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Aktiver for kun at bruge én forbindelse ved downloadning." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Afmærk netværk pakker for at hjælpe ISPs med at identificere MTA traffik." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Spindende cirkel animation i bunden af skærmen" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Vælg standard altid. (Denne indstilling gemmes ikke)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Det maksimale er som regel det bedste" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Auto opdaterer:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Vælg standard, medmindre du kan lide at fylde fejlfinder rapporter." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Vælg standard for automatisk at installere vigtige opdateringer." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-bit farver:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "SlÃ¥ 16 bit farve tilstand til - Det kræver at MTA genstartes" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Mus fiks:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Mus bevægelses fiks - Kan kræve PC genstart" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Ukendt kommando eller variabel:" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Travl" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Kan ikke se efter opdateringer lige nu" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s nødvendig" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "En opdateret version af MTA:SA %s er nødvendig for tilslutning af denne server.\n\n" -"Ønsker du at downloade og installere denne MTA:SA %s opdatering?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Ønsker du at starte MTA:SA %s og tilslutte til denne server?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Det er ikke muligt at tilslutte pÃ¥ dette tidspunkt.\n\n" -"Forsøg igen senere." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Tilslutter" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Vent venligst..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "TJEKKER" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "OPDATERING CHECK" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Ingen opdatering behøvet" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "DOWNLOADER" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "venter..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "OBLIGATORISK OPDATERING" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "For at tilslutte til denne server, skal du opdatere MTA.\n\n" -"Ønsker du at opdatere nu?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "FRIVILLIG OPDATERING" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Serveren siger at en opdatering anbefales, men er ikke væsentlig.\n\n" -"Ønsker du at opdatere nu?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "FEJL I GEMNING" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Det var ikke muligt at skabe filen." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "FEJL I DOWNLOAD" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Den hentede fil lader til at være ukorrekt." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Af en eller anden grund." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "DOWNLOAD FULDFØRT" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "- Ukendt problem i _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "FEJL" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Nogle MTA:SA data filer mangler.\n\n\n" -"Geninstaller venligst MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% fuldført" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Venter pÃ¥ svar - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Forbindelsen mislykkedes. Ugyldigt navn!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Forbindelsen mislykkedes. Ugyldig host!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Tilslutning af %s port %u fejlet!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Tilslutter til %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "TILSLUTTER" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Forbindelsen udløbede" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Afbrudt: ukendt fejl i protokol" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Forbindelsen afbrudt: fjernt frakoblet" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Afbrudt: forbindelse mistet fjernt" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Afbrudt: du er blevet banned fra denne server" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Afbrudt: afbrudt fra serveren" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Afbrudt: mistede forbindelse til serveren" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Afbrudt: forbindelse blev nægtet" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Ingen sÃ¥dan mod er installeret (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "DÃ¥rlig server respons (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "DÃ¥rlig server respons (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Besøg senest nyhedsartikel" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Fatal fejl" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "FOR AT FIKSE, FJERN DENNE FIL:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s modul er ukorrekt!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Fejl under eksekvering af URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "denne hjælpe skærm" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "afslutter programmet" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "viser versionen" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "viser tiden" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "viser HUD" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "viser alle bindinger" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "viser dit serienummer" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "tilslutter til en server (host port navn kode)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "tilslutter til en tidligere server" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "binder en tast (tast handling)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "afbind en tast (key)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "kopierer de standard gta kontrollere" -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "producerer et skærmbillede" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "øjeblikkelig gemmer konfigurations filen" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "tømmer debug vinduet" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "ruller chatboksen opad" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "ruller chatboksen nedad" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "ruller debug vinduet opad" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "ruller debug vinduet nedad" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "viser hukommelsesstatistik" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "viser billed timingens graf" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ KOMMANDO HJÆLP ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Klokken er %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "tilslut: Syntax er 'tilslut [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "tilslut: DÃ¥rligt port nummer" +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "producerer et skærmbillede" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "tilslut: Tilslutter til %s:%u..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "øjeblikkelig gemmer konfigurations filen" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "tilslut: kunne ikke tilslutte til %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "tømmer debug vinduet" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "tilslut: Lykkedes ikke at fjerne nuværende mod" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "ruller chatboksen opad" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "ruller chatboksen nedad" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "ruller debug vinduet opad" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "ruller debug vinduet nedad" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "viser hukommelsesstatistik" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Bundet alle knapper fra GTA" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "viser billed timingens graf" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Gemt konfigurationsfil" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Dit serienummer er: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Du benytter et funktions-gren build! Dette er kun et test build, hvilket ikke kan bruges for tilslutning til offentlige servere!" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Accelererer akse" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA vil ikke modtage opdateringer pÃ¥ XP/Vista efter Juli 2019.\n\n" +"Opgrader Windows for at spille pÃ¥ de nyeste servere." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Bremse Akse" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Dette vil afbryde dig fra din nuværende server.\n\n" +"Er du sikker pÃ¥ at du vil afbryde?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programmering" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "AFBRYDELSE ADVARSEL" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Bidragere" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Spil design / programmering" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Sprog Lokalisering" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Besøg senest nyhedsartikel" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Patch bidragere" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Screenshot fik %d bytes, men forventede %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Særlig tak til" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Screenshot fejlede" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Skærmbillede taget: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Vil du gerne se noget online hjælp omkring dette problem?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Ukendt kommando eller variabel:" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2384,25 +2376,56 @@ msgid "Group control backwards" msgstr "Gruppe kontrol bagud" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Hverken det skin du valgte, eller det standard skin, kunne indlæses. Vær venlig at geninstallere MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Screenshot fik %d bytes, men forventede %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Vil du gerne se noget online hjælp omkring dette problem?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Screenshot fejlede" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Skærmbillede taget: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programmering" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Bidragere" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Spil design / programmering" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Sprog Lokalisering" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Patch bidragere" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Særlig tak til" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Accelererer akse" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Bremse Akse" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2410,6 +2433,61 @@ msgstr "Kunne ikke initialisere Direct3D9.\n\n" "Tjek venligst om DirectX End-User Runtime og\n" "de seneste Windows Service Packs er installeret korrekt." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Inaktiv" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "spiller" +msgstr[1] "spillere" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "pÃ¥" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "" +msgstr[1] "servere" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Anmoder om master server listen (%lu ms forløbet)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Master server listen kunne ikke eksekveres." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Master server listen kunne ikke hentes." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Backup server liste)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Kan ikke binde LAN-broadcast socket" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Forsøger at finde LAN servere" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2463,7 +2541,7 @@ msgstr "Forsinkelse:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Spiller liste" @@ -2490,40 +2568,39 @@ msgstr "Tilslut til serveren nÃ¥r der er en ledig plads." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "ANGIV SERVERENS KODEORD" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Tiden løb ud" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Forespørger..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "SERVER LISTE" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Lokal" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Favoritter" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Seneste" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2531,298 +2608,367 @@ msgstr "FOR TILSLUTNING:\n\n" "Angiv adressen og porten i adressebaren.\n" "Eller vælg en server fra historikken og tryk 'Tilslut'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "HJÆLP" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Opdater" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Tilføj favorit" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Tilslut" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Søg i servere" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Søg i spillere" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Start søgning" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Søg i spillere..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Søg i servere..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Navn" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Spillere" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Spiltype" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Inkluder:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Tom" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Fuld" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "LÃ¥st" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Andre versioner" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Tilbage" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Indlæser..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "..indlæser.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Ingen adresse angivet!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Ukendt protokol" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Brug venligst mtasa:// protokollen!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Ugyldigt øgenavn! GÃ¥ venligst til Indstillinger og lav et nyt!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Du skal vælge en server at forbinde til." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Inaktiv" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problem med grafikkort driver" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "spiller" -msgstr[1] "spillere" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Kunne ikke finde en gyldig skærm opløsning." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "pÃ¥" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Er du sikker pÃ¥ at du vil bruge denne skærm opløsning?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "" -msgstr[1] "servere" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Anmoder om master server listen (%lu ms forløbet)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Master server listen kunne ikke eksekveres." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Hjemmeside anmoder" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Master server listen kunne ikke hentes." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Serveren anmoder om den følgende hjemmeside for at kunne indlæses (senere):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Backup server liste)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "ALDRIG INDTAST SKRØBELIG DATA FOR AT BESKYTTE DET FRA AT BLIVE STJÃ…LET" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Kan ikke binde LAN-broadcast socket" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Husk beslutning" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Forsøger at finde LAN servere" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Afvis" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Denne version er udløbet." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "frakobl fra spillet" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "viser navneskilte" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "viser chatboksen" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "viser netværk statistikkerne" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "Ã¥bn chatindgangen" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "transmiterrer stemme til andre spillere" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "træder ind i en bil som passager" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "næste radio kanal" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "forrige radio kanal" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "sender en besked til den mÃ¥lrettede spiller" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "skifter til det næste vÃ¥ben mens du er i et køretøj" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "skifter til det forrige vÃ¥ben mens du er i et køretøj" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "giver info om den nuværende server" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "definerer skala multiplikatoren af alle tekst visningere" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Udviklings tilstand) viser colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Udviklings tilstand) udskriver world lyd ID's til debug vinduet" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "HOST SPIL" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Ressourcer" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Server navn:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Adgangskode:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Maks spillere:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Valgt" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Alle" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Map download fremskridt:" @@ -2843,195 +2989,195 @@ msgstr "%s af %s" msgid "Disconnect to cancel download" msgstr "Afbryd for at annullere download" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Afbrudt: Ugyldigt øgenavn" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Afbryd fra server" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Afbrudt: Serienummer er banned.\n" "Grund: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Afbrudt: Du er banned.\n" "Grund: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Afbrudt: Bruger er banned.\n" "Grund: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Afbrudt: Version uoverensstemmelse" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Afbrudt: Overskydende tilslutningere. Vent venligst et minut, derefter prøv igen." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Afbrudt: Server fra anderledes gren.\n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Afbrudt: DÃ¥rlig version.\n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Afbrudt: Server kører pÃ¥ et nyere build.\n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Afbrudt: Server kører pÃ¥ et ældre build.\n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Afbrudt: Øgenavn allerede i brug" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Afbrudt: Server nægtede forbindelsen: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Afbrudt: Verifikation af serienummer fejlede" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Afbrudt: Forbindelse desynkronisering %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Afbrudt: Du blev smidt ud af %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Afbrudt: Du blev banned af %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Afbrudt: Server lukkes ned eller genstartes" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Du blev smidt ud af spillet" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Denne server pÃ¥kræver en ikke-modificeret gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Erstat gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Denne server tillader ikke modificerede D3D9.DLLs" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Fjern D3D9.DLL fra din GTA install folder og genstart MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Denne server tillader ikke virtuelle maskiner" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Denne server pÃ¥kræver at driver signering er aktiveret" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Genstart venligst din PC" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Denne server har fundet manglende anti-cheat komponenter" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Prøv at genstarte MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Denne server pÃ¥kræver en ikke-modificeret gta3.img og gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Erstat venligst gta3.img eller gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Denne server tillader ikke Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Sørg for at intet andet program modificerer MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Tid tilovers:" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d dag" msgstr[1] "%d dage" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d time" msgstr[1] "%d timer" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d minut" msgstr[1] "%d minutter" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3039,296 +3185,206 @@ msgstr[0] "%d sekund" msgstr[1] "%d sekunder" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Afbrudt" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Download fejl: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "GÃ¥r ind i spillet ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Ikke tilsluttet; benyt venligst Quick Connect eller 'connect' kommando for at tilslutte til en server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Kunne ikke starte den lokale server. Check console for detaljer." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Lokal Server" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Starter lokal server ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Du blev smidt ud af spillet ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Tilslutter til lokal server..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Fejl i forbindelse til server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Forbindelse til lokal server timed out. Check console for detaljer." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Forbindelsen med serveren blev mistet." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Afbrudt: serveren er i øjeblikket fuld" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Afbrudt: ugyldigt kodeord specificeret" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA klient verifikation fejlede!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "HOST SPIL" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Ressourcer" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Server navn:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Adgangskode:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Maks spillere:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Valgt" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Alle" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problem med grafikkort driver" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Kunne ikke finde en gyldig skærm opløsning." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Er du sikker pÃ¥ at du vil bruge denne skærm opløsning?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Download fejl: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3349,11 +3405,11 @@ msgstr "" msgid "Connection error" msgstr "Forbindelse fejl" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto er ikke blevet installeret korrekt, geninstaller venligst." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Din browser vil nu vise en hjemmeside med hjælpende information.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/de_DE/client.pot b/Shared/data/MTA San Andreas/MTA/locale/de_DE/client.pot index a9c67b85e4e..0a990f4a5f1 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/de_DE/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/de_DE/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:18\n" "Last-Translator: \n" "Language-Team: German\n" "Language: de_DE\n" @@ -17,72 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Problem beim Neustart von MTA:SA\n\n" -"Wenn dieses Problem weiterhin besteht, öffne den Task Manager und\n" -"beende die 'gta_sa.exe' und 'Multi Theft Auto.exe' Prozesse\n\n\n" -"Starten von MTA:SA erneut versuchen?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Grand Theft Auto: San Andreas starten.\n" +"Stellen Sie sicher, dass das Spiel im Ordner „Programme (x86)“ abgelegt ist." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Fehler" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "Suche nach GTA: San Andreas" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Eine weitere Instanz von MTA läuft bereits.\n\n" -"Wenn dieses Problem weiterhin besteht starte bitte deinen Computer neu" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Entschuldigung, das Spiel wurde nicht gefunden.\n" +"Starte Grand Theft Auto: San Andreas und klicke auf erneut versuchen.\n" +"Stelle sicher, dass sich das Spiel im 'Program Files (x86)' Ordner befindet." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Eine weitere Instanz von MTA läuft bereits.\n\n" -"Möchtest du sie beenden?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Wähle den Installationsordner von Grand Theft Auto: San Andreas aus" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA benötigt Administratorzugriff für die folgende Aufgabe:\n\n" +" '%s'\n\n" +"Bitte bestätigen Sie dies im nächsten Fenster." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Fehler beim Laden des Moduls %s! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Kopiere Dateien..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopiervorgang beendet. Alles ist in Ordnung." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Fertigstellen..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Fertig!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Neue Installation von %s erkannt.\n\n" +"Möchtest du deine Einstellungen von %s kopieren?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA konnte die Datei '%s' nicht öffnen" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA fehlt die Datei '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA konnte ein Modell nicht laden." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Wenn du kürzlich gta3.img modifiziert hast, versuche GTA:SA neu zu installieren." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA konnte ein Fahrzeugupgrade nicht hinzufügen." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA hat Fehler in der Datei '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Startete dein Computer neu als du MTA:SA gespielt hast?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Bitte schließe erst folgende Programme:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "Ungültigen Modulpfad erkannt.\n" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Dateiversion stimmt nicht überein. Installiere MTA:SA neu, wenn du Probleme hast.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Einige Dateien fehlen. Installiere MTA:SA neu, wenn Probleme auftreten.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA ist nicht kompatibel mit dem 'abgesicherten Modus'.\n\n" +"Bitte starte deinen PC neu.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Hast du Probleme beim Starten von MTA:SA?\n\n" "Möchtest du auf eine ältere Version zurücksetzen?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +143,48 @@ msgstr "Es scheint ein Problem beim Starten von MTA:SA vorzuliegen.\n" "Manchmal kann das Zurücksetzen der GTA Einstellungen dieses Problem beheben.\n\n" "Möchtest du die GTA Einstellungen jetzt zurücksetzen?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA Einstellungen wurden zurückgesetzt.\n\n" "Drücke OK um fortzufahren." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Datei konnte nicht gelöscht werden: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Hast du ein Problem beim Starten von MTA:SA?\n\n" "Möchtest du dazu eine Onlinehilfe sehen?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Hast du Probleme mit MTA:SA?.\n\n" "Möchtest du folgende Einstellung ändern?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Vollbildmodus:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Randloses Fenster" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Hast du Probleme mit MTA:SA?.\n\n" "Versuche die folgenden Produkte für GTA und MTA zu deaktivieren:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +192,293 @@ msgstr "WARNUNG\n\n" "MTA:SA hat ungewöhnliche Aktivitäten erkannt.\n" "Bitte starte einen Virusscan, um die Sicherheit deines Systems sicherzustellen.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Die erkannte Datei ist: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Eine Instanz von GTA: San Andreas läuft bereits. Diese muss beendet werden, bevor MTA:SA gestartet werden kann. Möchtest du dies jetzt tun?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informationen" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Konnte GTA: San Andreas nicht beenden. Wenn dieses Problem weiterhin besteht starte deinen Computer neu." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Problem beim Neustart von MTA:SA\n\n" +"Wenn dieses Problem weiterhin besteht, öffne den Task Manager und\n" +"beende die 'gta_sa.exe' und 'Multi Theft Auto.exe' Prozesse\n\n\n" +"Starten von MTA:SA erneut versuchen?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Fehler" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Eine weitere Instanz von MTA läuft bereits.\n\n" +"Wenn dieses Problem weiterhin besteht starte bitte deinen Computer neu" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Eine weitere Instanz von MTA läuft bereits.\n\n" +"Möchtest du sie beenden?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Registrierungseinträge fehlen. Bitte installiere Multi Theft Auto: San Andreas neu." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Der Pfad zu deiner Installation von GTA: San Andreas enthält ungültige Unicode Zeichen. Bitte ändere den Pfad deiner GTA: San Andreas Installation, sodass dieser nur ASCII Zeichen enthält und installiere Multi Theft Auto: San Andreas neu." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Der Pfad zu deiner Installation von 'MTA:SA' oder 'GTA: San Andreas'\n" -"enthält ';' (Semikolon).\n\n" -" Wenn du Probleme bei der Ausführung von MTA:SA hast,\n" -" ändere bitte deinen Installationspfad auf einen Pfad der kein Semikolon enthält." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "Der Pfad deiner 'MTA:SA' oder 'GTA: San Andreas' Installation enthält ein ';' Semikolon." + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "Ungültigen Installationspfad erkannt." + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Ladevorgang fehlgeschlagen. Bitte stelle sicher, dass die aktuellen Data Files korrekt installiert wurden." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Ladevorgang fehlgeschlagen. Bitte stelle sicher, dass %s korrekt installiert wurde." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Ladevorgang fehlgeschlagen. Konnte gta_sa.exe nicht in %s finden." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Ladevorgang fehlgeschlagen. Die Datei %s existiert im GTA Installationsordner. Bitte lösche diese Datei." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Hauptdatei hat einen falschen Namen (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Hauptdatei ist nicht signiert. Grund dafür könnte ein Virus sein.\n\n" -"Siehe Onlinehilfe, wenn MTA nicht korrekt funktioniert." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Die Datei %s fehlt. Möglicherweise handelt es sich um einen Virus.\n\n" -"Sie sollten zur Sicherheit eine Neuinstallation von Multi Theft Auto in Betracht ziehen.\n" -"Siehe online Hilfe, falls MTA nicht korrekt funktioniert." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "Datei %s fehlt. Mögliche Virusaktivität." + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Die Datei %s wurde verändert. Möglicherweise handelt es sich um einen Virus.\n\n" -"Sie sollten zur Sicherheit eine Neuinstallation von Multi Theft Auto in Betracht ziehen.\n" -"Siehe online Hilfe, falls MTA nicht korrekt funktioniert." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asi Dateien befinden sich im 'MTA:SA' oder 'GTA: San Andreas' Installationsverzeichnis.\n\n" -"Entferne die .asi Dateien, wenn du Probleme mit MTA:SA feststellst." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Dateiversion stimmt nicht überein. Installiere MTA:SA neu, wenn du Probleme hast.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "Datei %s wurde verändert. Mögliche Virusaktivität." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Einige Dateien fehlen. Installiere MTA:SA neu, wenn Probleme auftreten.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr ".asi Dateien sind im Installationsverzeichnis.\n\n" +"Entferne die .asi Dateien, falls Probleme auftreten." -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA ist nicht kompatibel mit dem 'abgesicherten Modus'.\n\n" -"Bitte starte deinen PC neu.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "Ungültige Spielpfade erkannt." -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Behebung eines Konfigurationsproblems" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Rechteproblem beheben" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "GTA: San Andreas konnte möglicherweise nicht korrekt ausgeführt werden. Beenden?" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Unbekannt" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "Die Datei '%s' ist derzeit durch %zu Prozesse gesperrt.\n\n" +"Möchtest du die nachfolgenden Prozesse beenden und den Update Vorgang fortführen?\n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "Deine Installation ist möglicherweise korrumpiert.\n\n" +"Es konnten %zu von insgesamt %zu Dateien nicht wieder aus dem Backup hergestellt werden.\n\n" +"Du solltest Multi Theft Auto von www.multitheftauto.com neu installieren oder ein Update mit Administratoren Rechten starten." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Installiere Update..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Extrahiere Dateien..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA konnte die folgende Operation nicht erfolgreich durchführen:\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Der Absturz wurde durch einen Grafiktreiberfehler verursacht **\n\n" +"** Bitte aktualisieren Sie Ihre Grafiktreiber **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "** Nicht genügend Arbeitsspeicher – dieser Absturz wurde verursacht, da nicht genug freier Speicher verfügbar ist oder der Speicher fragmentiert ist. **" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Aktualisierte MTA:SA-Dateien installieren" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Die Aktualisierung konnte aufgrund von Dateikonflikten nicht durchgeführt werden. Bitte schließen Sie andere Anwendungen und versuchen Sie es erneut" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto wurde nicht richtig installiert, bitte installieren Sie es neu. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "GTA:SA-Kreuzungen erstellen" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA kann nicht starten, weil das Kopieren einer Datei fehlgeschlagen ist:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA kann nicht gestartet werden, da eine MTA:SA Datei fehlerhaft ist oder fehlt:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "MTA:SA-Dateien kopieren" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA kann nicht gestartet werden, da eine GTA:SA Datei fehlerhaft ist oder fehlt:" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "Patch GTA:SA-Abhängigkeit" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA kann nicht gestartet werden, weil die ausführbare Datei GTA:SA falsch ist oder fehlt:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Bitte überprüfen Sie Ihr Antivirenprogramm auf eine falsch-positive Erkennung, versuchen Sie, eine Ausnahme für die ausführbare Datei GTA:SA hinzuzufügen und starten Sie MTA:SA neu." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "GTA:SA generieren" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA kann nicht starten, weil die ausführbare Datei GTA:SA nicht geladen werden kann:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Aufnäher GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA kann nicht starten, weil das Patchen von GTA:SA fehlgeschlagen ist:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Konnte Grand Theft Auto: San Andreas nicht starten. Bitte versuche es erneut, oder, wenn das Problem weiterhin auftritt, kontaktiere das MTA Team via www.multitheftauto.com.\n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA kann nicht fortgesetzt werden, da das Laufwerk %s nicht über genügend Speicherplatz verfügt." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Fehlende Datei:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Wenn MTA nicht geladen werden kann, installieren Sie bitte GTA:SA neu" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Installationseinstellungen aktualisieren" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas scheint nicht richtig gestartet zu sein. Möchtest du es beenden?" +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Kompatibilitätseinstellungen aktualisieren" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +486,167 @@ msgstr "GTA: San Andreas scheint nicht richtig gestartet zu sein. Möchtest du e #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Ja" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Nein" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "OK" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Verlassen" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Hilfe" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Abbrechen" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas ist auf ein Problem gestoßen" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Informationen zum Absturz" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Aktivieren Sie das Kontrollkästchen, um diese Absturzinformationen über das Internet an die MTA-Entwickler zu senden" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Wenn du dies machst, kann der Fehler leichter behoben werden." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Möchten du MTA: San Andreas neustarten?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Warnung" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "Das Installationsverzeichnis von Grand Theft Auto: San Andreas enthält diese Dateien:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Diese Dateien werden nicht benötigt und können die grafischen Funktionen in dieser Version von MTA: SA beeinträchtigen.\n\n" "Es wird empfohlen, diese Dateien zu entfernen oder umzubenennen." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "Behalten Sie diese Dateien, aber zeigen Sie beim nächsten Start auch diese Warnung an" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Erinnern Sie mich nicht mehr an diese Dateien" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Benennen Sie diese Dateien von *.dll in *.dll.bak um" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Zeigen Sie mir diese Dateien" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "MTA:SA spielen" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Verwirrende Optionen" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus erkannt!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Versuche jede Option und schaue, was funktioniert:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Standard NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Alternatives NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Standard Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Standard Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Wenn du verzweifelst, könnte folgendes helfen:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Wenn Sie bereits eine funktionierende Option ausgewählt haben, könnte dies helfen:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Fenstermodus erzwingen" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Nicht mehr anzeigen" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Warnung: Konnte keine Antivirensoftware erkennen" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1109 +654,1181 @@ msgstr "MTA konnte keine Antivirensoftware auf deinem PC finden.\n\n" "Viren beinträchtigen MTA und verschlechtern dein Spielerlebnis.\n\n" "Drücke 'Hilfe' für weitere Informationen." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "I habe bereits eine Antivirensoftware installiert" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Ich werde keine Antivirensoftware installieren.\n" "Ich möchte, dass mein PC laggt und Teil eines Botnetz ist." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Suche nach Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Bitte starte Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Installiere Update..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Verbinden fehlgeschlagen. Ungültiger Nickname angegeben!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Extrahiere Dateien..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Verbindungsaufbau fehlgeschlagen. Ungültiger Host angegeben!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Kopiere Dateien..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Die Verbindung zu %s an Port %u ist fehlgeschlagen!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopiervorgang beendet. Alles ist in Ordnung." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Verbindung zu %s:%u herstellen ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Fertigstellen..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "Wiederverbinden zu %s:%u ..." -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Fertig!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "VERBINDEN" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA benötigt Administratorzugriff für die folgende Aufgabe:\n\n" -" '%s'\n\n" -"Bitte bestätigen Sie dies im nächsten Fenster." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Zeitüberschreitung der Verbindung" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA konnte die folgende Operation nicht erfolgreich durchführen:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Verbindung getrennt: Unbekannter Protokollfehler" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Der Absturz wurde durch einen Grafiktreiberfehler verursacht **\n\n" -"** Bitte aktualisieren Sie Ihre Grafiktreiber **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Verbindung getrennt: Verbindung zum Server getrennt" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Aktualisierte MTA:SA-Dateien installieren" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Verbindung getrennt: Verbindung zum Server verloren" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Die Aktualisierung konnte aufgrund von Dateikonflikten nicht durchgeführt werden. Bitte schließen Sie andere Anwendungen und versuchen Sie es erneut" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Verbindung getrennt: Du wurdest von diesem Server gebannt" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Verbindung getrennt: Verbindung zum Server getrennt" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Verbindung getrennt: Verbindung zum Server verloren" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Verbindung getrennt: Verbindung verweigert" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto wurde nicht richtig installiert, bitte installieren Sie es neu. %s" +msgid "No such mod installed (%s)" +msgstr "Mod %s ist nicht installiert" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "GTA:SA-Kreuzungen erstellen" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Ungültige Serverantwort (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA kann nicht starten, weil das Kopieren einer Datei fehlgeschlagen ist:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Ungültige Serverantwort (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA kann nicht gestartet werden, da eine MTA:SA Datei fehlerhaft ist oder fehlt:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Deutsch" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "MTA:SA-Dateien kopieren" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Beschäftigt" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA kann nicht gestartet werden, da eine GTA:SA Datei fehlerhaft ist oder fehlt:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Kann derzeit nicht auf Updates prüfen" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Patch GTA:SA-Abhängigkeit" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s erforderlich" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA kann nicht gestartet werden, weil die ausführbare Datei GTA:SA falsch ist oder fehlt:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Eine neuere Version von MTA:SA %s ist notwendig, um diesen Server zu betreten.\n\n" +"Möchtest du MTA:SA %s herunterladen und installieren?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Bitte überprüfen Sie Ihr Antivirenprogramm auf eine falsch-positive Erkennung, versuchen Sie, eine Ausnahme für die ausführbare Datei GTA:SA hinzuzufügen und starten Sie MTA:SA neu." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Möchtest du MTA:SA %s starten und dich mit diesem Server verbinden?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "GTA:SA generieren" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Es ist zu diesem Zeitpunkt nicht möglich, eine Verbindung aufzubauen.\n\n" +"Bitte versuche es später erneut." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA kann nicht starten, weil die ausführbare Datei GTA:SA nicht geladen werden kann:" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Verbindungsaufbau" + +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Bitte warten..." -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Aufnäher GTA:SA" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "ÜBERPRÜFE" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA kann nicht starten, weil das Patchen von GTA:SA fehlgeschlagen ist:" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "AKTUALISIERUNGSÜBERPRÜFUNG" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA kann nicht fortgesetzt werden, da das Laufwerk %s nicht über genügend Speicherplatz verfügt." +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Keine Aktualisierung notwendig" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Fehlende Datei:" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "LÄDT HERUNTER" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Wenn MTA nicht geladen werden kann, installieren Sie bitte GTA:SA neu" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "warten..." -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Installationseinstellungen aktualisieren" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "VERPFLICHTENDES UPDATE" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Kompatibilitätseinstellungen aktualisieren" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Um dich mit diesem Server zu verbinden, musst du MTA aktualisieren.\n\n" +" Möchtest du diese Aktualisierung jetzt durchführen?" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Unbekannt" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "OPTIONALES UPDATE" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "Die Datei '%s' ist derzeit durch %zu Prozesse gesperrt.\n\n" -"Möchtest du die nachfolgenden Prozesse beenden und den Update Vorgang fortführen?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Der Server empfiehlt eine Aktualisierung durchzuführen, die aber nicht notwendig ist, um dich mit dem Server zu verbinden.\n\n" +" Möchtest du diese Aktualisierung jetzt durchführen?" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "Deine Installation ist möglicherweise korrumpiert.\n\n" -"Es konnten %zu von insgesamt %zu Dateien nicht wieder aus dem Backup hergestellt werden.\n\n" -"Du solltest Multi Theft Auto von www.multitheftauto.com neu installieren oder ein Update mit Administratoren Rechten starten." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "Derzeit ist kein Update verfügbar.\n\n" +"Bitte überprüfe www.multitheftauto.com" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Grand Theft Auto: San Andreas starten.\n" -"Stellen Sie sicher, dass das Spiel im Ordner „Programme (x86)“ abgelegt ist." +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "FEHLER BEIM SPEICHERN" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "Suche nach GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Erstellen der Datei nicht möglich." -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Entschuldigung, das Spiel wurde nicht gefunden.\n" -"Starte Grand Theft Auto: San Andreas und klicke auf erneut versuchen.\n" -"Stelle sicher, dass sich das Spiel im 'Program Files (x86)' Ordner befindet." +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "DOWNLOADFEHLER" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Wähle den Installationsordner von Grand Theft Auto: San Andreas aus" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Die heruntergeladene Datei scheint nicht in Ordnung zu sein." -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Fehler beim Laden des Moduls %s! (%s)" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Aus irgendeinem Grund." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Neue Installation von %s erkannt.\n\n" -"Möchtest du deine Einstellungen von %s kopieren?" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "DOWNLOAD ABGESCHLOSSEN" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA konnte die Datei '%s' nicht öffnen" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Unbekanntes Problem in _DialogUpdateResult" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA fehlt die Datei '%s'." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "VERÄNDERTE GTA:SA DATEIEN" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA konnte ein Modell nicht laden." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ok" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Wenn du kürzlich gta3.img modifiziert hast, versuche GTA:SA neu zu installieren." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "FEHLER" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA konnte ein Fahrzeugupgrade nicht hinzufügen." +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Einige MTA:SA Dateien konnten nicht gefunden werden.\n\n\n" +"Bitte installiere MTA:SA neu." -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA hat Fehler in der Datei '%s'" +msgid "%3d %% completed" +msgstr "%3d %% abgeschlossen" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Startete dein Computer neu als du MTA:SA gespielt hast?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Warte auf eine Antwort - %-3d" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Bitte schließe erst folgende Programme:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ BEFEHL HILFE ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Website-Anfragen" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Die Zeit ist %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Der Server fordert die folgenden Websites an, um sie (später) zu laden:" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "Verbinden: Netzwerk ist nicht bereit, bitte warten" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NIEMALS SENSIBLE DATEN EINGEBEN, UM SIE VOR DIEBSTAHL ZU SCHÜTZEN" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "verbinden: Syntax ist 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Entscheidung erinnern" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "verbinden: Falscher Hafen" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Erlauben Sie" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "verbinden: Verbindung zu %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Verweigern" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "connect: konnte keine Verbindung zu %s:%u herstellen!" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "Hauptmenü" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "verbinden: Entladen der aktuellen Mod fehlgeschlagen" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Du benutzt einen Featurebranch-Build! Dies ist nur ein Testbuild, der nicht benutzt werden kann, um öffentliche Server zu betreten." +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "Wiederverbinden: Netzwerk ist nicht bereit, bitte warten" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA wird für XP/Vista ab Juli 2019 keine Updates mehr erhalten.\n\n" -"Aktualisiere Windows, um auf aktuellen Servern zu spielen." +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "Wiederverbinden: Ungültige Port Nummer" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Dies wird deine Verbindung zum aktuellen Server trennen.\n\n" -"Bist du sicher, dass du die Verbindung trennen willst?" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "Wiederverbinden: Erneut verbinden zu %s:%u..." -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "VERBINDUNG GETRENNT" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "Wiederverbinden: Es konnte keine Verbindung zu %s:%u hergestellt werden!" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Binden Sie alle Kontrollen aus GTA" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Deutsch" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Gespeicherte Konfigurationsdatei" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Ihre Seriennummer lautet: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "EINSTELLUNGEN" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Mehrspieler" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Video" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Audio" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Tastenbelegungen" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Steuerung" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Schnittstelle" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Webbrowser" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Erweitert" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Einstellungen zurücksetzen" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Mausempfindlichkeit:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Vertikale Zielempfindlichkeit:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Cursoroptionen" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Maus vertikal invertieren" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Mit der Maus steuern" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Mit der Maus fliegen" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Joypadoptionen" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standardsteuerung (Maus + Tastatur)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Klassische Steuerung (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Tote Zone" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Sättigung" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Den Tab 'Tastenbelegungen' für die Joypadbelegungen nutzen." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Linker Stick" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Rechter Stick" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "BESCHREIBUNG" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "TASTE" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. TASTE" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Nick:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Serverpasswörter speichern" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Serverbrowser automatisch aktualisieren" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Upload von Screenshots erlauben" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Externe Sounds erlauben" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Download-Fenster immer anzeigen" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Verbindung mit Discord Rich Presence zulassen" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" -msgstr "" +msgstr "GTA:SA Spielstatus auf Steam zulassen" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "Sichere Fotos die mit der Kamera-Waffe geschossen wurden im GTA San Andreas User Files Ordner" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" -msgstr "" +msgstr "Nachfragen, bevor die Verbindung zum Server über das Hauptmenü getrennt wird" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Veränderte GTA:SA Dateien verwenden" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Kartenrenderoptionen" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Transparenz:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "Bild Auflösung:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "1024 x 1024 (Standard)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Hauptlautstärke:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Radiolautstärke:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "SFX Lautstärke:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA Lautstärke:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Voicelautstärke:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Abspielmodus:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Allgemein" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Radiooptionen" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Radio Equalizer" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Radio Auto-tune" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Usertrack Optionen" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Radio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Zufallswiedergabe" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Sequentiell" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Automatischer Medienscan" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Stummschaltungsoptionen" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Schalte SFX Töne stumm, wenn minimiert" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Schaltet das Radio stumm wenn minimiert" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Schaltet die SFX Töne stumm wenn minimiert" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Schaltet die MTA Töne stumm wenn minimiert" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Schaltet die Voice Töne stumm wenn minimiert" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Auflösung:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "FOV:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Renderweite:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Helligkeit:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX Qualität:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anisotropische Filterung:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Anti-aliasing:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Bildseitenverhältnis:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Fenstermodus" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI-bewusst" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Standard" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Rahmenlos, behalte Auflösung" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mip-Mapping" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Niedrig" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Mittel" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Hoch" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Sehr Hoch" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Aus" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Auto" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD dem Bildschirmverhältnis anpassen" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Volumetrische Schatten" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Graseffekte" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Hitzeschleier" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Rauchende Reifen etc" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Dynamische Passanten-Schatten" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Bewegungsunschärfe" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Corona Regen Reflexionen" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Minimieren bei Vollbild erlauben" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Monitorauswahldialog aktivieren" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Zeige unsichere Auflösungen" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Fahrzeuge immer mit vielen Details" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Pädiatrie immer mit hohem Detailgrad rendern" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Externe Webseiten aktivieren" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Javascript auf externen Webseiten" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "GPU-Rendering aktivieren" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Eigene Blackliste" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Bitte eine Domain eingeben" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Blockieren" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Domäne" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Domain entfernen" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Eigene Whiteliste" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Erlauben Sie" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Sonstiges" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Schnelles Laden von CJ Kleidung:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Geschwindigkeit des Serverbrowsers:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Nur eine Verbindung nutzen:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Paket Kennzeichnung:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Fortschrittsanimation" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Prozesspriorität:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Debugeinstellung:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Speicher zum Streamen:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Buildtyp für Aktualisierungen:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Wichtige Updates installieren:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "An" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Sehr langsam" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Standard" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Schnell" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normal" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Über normal" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Min" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Max" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 Kompatibilität:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-Bit Farbe" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Maus Fix" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Clientressourcen Dateien:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Im Explorer öffnen" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" -msgstr "" +msgstr "CPU 0 Affinität zur Verbesserung der Spielleistung aktivieren" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Auto Updater" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Jetzt nach Update suchen" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Manche Einstellungen werden nach einem Neustart von MTA angewendet" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Möchtest du jetzt neu starten?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "NEUSTART ERFORDERLICH" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Einige Einstellungen werden geändert, sobald du den derzeitigen Server verlässt" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Möchtest du die Verbindung jetzt trennen?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "VERBINDUNG MUSS GETRENNT WERDEN" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad konnte nicht gefunden werden - Überprüfe die Verbindung und starte das Spiel erneut" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Achse zuweisen" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Bewege eine Achse zum Belegen, oder drücke Escape um abzubrechen" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Sprache:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Haut:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Voreinstellungen:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Chatten" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Laden" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Farben" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Befehl" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Optionen" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Chathintergrund" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Chat-Text" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Eingabehintergrund" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Eingabetext" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Zeilen:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Größe:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Breite:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Größe" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "nach" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "für" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "sek" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Verblassen" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Alte Zeilen ausfaden" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horizontale:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Vertikal:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Textausrichtung:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-Versatz:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-Versatz:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Standpunkt" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Links" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Mitte" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Rechts" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Oben" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Unten" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Schriftart" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Hintergrund verstecken, sofern nicht getippt wird" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Nicknamen Vervollständigung mit Tab" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Blinken des Fensters durch Server erlauben" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Traybenachrichtigungen zulassen" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Schwarz/weiße Umrandung des Chats" @@ -1550,112 +1836,116 @@ msgstr "Schwarz/weiße Umrandung des Chats" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Drücke eine Taste zum Belegen, oder drücke Escape um abzubrechen" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Primärtaste festlegen" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Sekundärtaste festlegen" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA Steuerung" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "Multiplayer Steuerung" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Dein Nickname enthält ungültige Zeichen!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Hauptmenü" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "Im Spiel" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Rot:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Grün:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Blau:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Transparenz:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Farbe" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Vorschau" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Bitte trenne die Verbindung bevor du die Sprache wechselst" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Bitte trenne die Verbindung bevor du den Skin änderst" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Volumetrische Schatten können auf einigen Systemen zu Performanceeinschränkungen führen.\n\n" "Bist du sicher, dass du diese aktivieren möchtest?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "PERFORMANCE WARNUNG" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Screenshotupload wird von einigen Servern zur Erkennung von Cheats benötigt.\n\n" "(Die Chatbox und andere GUIs werden nicht hochgeladen)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "SCREENSHOT UPLOAD INFORMATION" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "Einige Skripte können Töne aus dem Internet abspielen, wie ein Radio. \n\n" "Deaktivieren dieser Einstellung kann den Netzwerkverbrauch senken.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "Externe Sounds" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "Es scheint, dass die Rich Presence-Verbindungsoption aktiviert ist.\n" -"Möchten Sie erlauben, dass Server Ihre Daten teilen?\n\n" -"Dazu gehört auch Ihre eindeutige ID." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "ZUSTIMMUNG ZUR DATENFREIGABE" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1665,11 +1955,7 @@ msgstr "Einige Dateien in deinem GTA:SA Datenverzeichnis wurden modifiziert.\n" "VERÄNDERTE GTA:SA DATEIEN WERDEN JEDOCH AUF VIELEN SERVERN BLOCKIERT\n\n" "Bist du sicher, dass du sie dennoch nutzen möchtest?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "VERÄNDERTE GTA:SA DATEIEN" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1679,550 +1965,253 @@ msgstr "Die Aktivierung der DPI-Erkennung ist eine experimentelle Funktion und\n "Es kann zu grafischen Problemen kommen, wenn Sie diese Option aktivieren.\n\n" "Sind Sie sicher, dass Sie diese Option aktivieren möchten?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "EXPERIMENTELLE FUNKTION" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" -msgstr "" +msgstr "Das Deaktivieren dieser Option wird nicht empfohlen, außer Sie haben Probleme mit der Leistung.\n\n" +"Sind Sie sicher, dass Sie sie deaktivieren wollen?" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Bitte gib einen Nicknamen ein" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Bitte gib einen Nicknamen ein, der ingame genutzt werden soll. \n" "Dies wird dein Name sein, mit dem du auf einem Server spielst" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Sehr experimentelles Feature." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Verhindert Ruckler mit Variationen mit CJ (Benötigt 65MB mehr Arbeitsspeicher)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Ältere Router könnten eine langsamere Suchgeschwindigkeit benötigen." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Aktivieren, um nur eine Verbindung beim Herunterladen zu nutzen." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Netzwerkpakete kennzeichnen, um Providern zu helfen MTA Pakete zu erkennen" -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Drehender Kreis an der unteren Kante des Bildschirms" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Immer Standard auswählen. (Diese Einstellung wird nicht gespeichert)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maximum ist normalerweise am besten" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Automatischer Updater:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Wähle 'Standard', außer du willst Bugreports ausfüllen." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Standard auswählen, um automatisch wichtige Updates zu installieren" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-Bit Farbe:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "16-Bit Farbmodi aktivieren - Benötigt Neustart" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Maus Fix:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Maus-Bewegungs Fix - Benötigt möglicherweise Reboot" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" -msgstr "" +msgstr "CPU Affinität:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." -msgstr "" - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Unbekannter Befehl oder cvar: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Beschäftigt" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Kann derzeit nicht auf Updates prüfen" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s erforderlich" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Eine neuere Version von MTA:SA %s ist notwendig, um diesen Server zu betreten.\n\n" -"Möchtest du MTA:SA %s herunterladen und installieren?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Möchtest du MTA:SA %s starten und dich mit diesem Server verbinden?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Es ist zu diesem Zeitpunkt nicht möglich, eine Verbindung aufzubauen.\n\n" -"Bitte versuche es später erneut." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Verbindungsaufbau" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Bitte warten..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "ÜBERPRÜFE" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "AKTUALISIERUNGSÜBERPRÜFUNG" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Keine Aktualisierung notwendig" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "LÄDT HERUNTER" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "warten..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "VERPFLICHTENDES UPDATE" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Um dich mit diesem Server zu verbinden, musst du MTA aktualisieren.\n\n" -" Möchtest du diese Aktualisierung jetzt durchführen?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "OPTIONALES UPDATE" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Der Server empfiehlt eine Aktualisierung durchzuführen, die aber nicht notwendig ist, um dich mit dem Server zu verbinden.\n\n" -" Möchtest du diese Aktualisierung jetzt durchführen?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "FEHLER BEIM SPEICHERN" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Erstellen der Datei nicht möglich." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "DOWNLOADFEHLER" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Die heruntergeladene Datei scheint nicht in Ordnung zu sein." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Aus irgendeinem Grund." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "DOWNLOAD ABGESCHLOSSEN" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Unbekanntes Problem in _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ok" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "FEHLER" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Einige MTA:SA Dateien konnten nicht gefunden werden.\n\n\n" -"Bitte installiere MTA:SA neu." - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% abgeschlossen" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Warte auf eine Antwort - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Verbinden fehlgeschlagen. Ungültiger Nickname angegeben!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Verbindungsaufbau fehlgeschlagen. Ungültiger Host angegeben!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Die Verbindung zu %s an Port %u ist fehlgeschlagen!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Verbindung zu %s:%u herstellen ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "Wiederverbinden zu %s:%u ..." - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "VERBINDEN" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Zeitüberschreitung der Verbindung" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Verbindung getrennt: Unbekannter Protokollfehler" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Verbindung getrennt: Verbindung zum Server getrennt" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Verbindung getrennt: Verbindung zum Server verloren" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Verbindung getrennt: Du wurdest von diesem Server gebannt" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Verbindung getrennt: Verbindung zum Server getrennt" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Verbindung getrennt: Verbindung zum Server verloren" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Verbindung getrennt: Verbindung verweigert" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Mod %s ist nicht installiert" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Ungültige Serverantwort (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Ungültige Serverantwort (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "NEWS" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Letzten Artikel aufrufen" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONSOLE" +msgstr "Nur ändern bei Stabilitätsproblemen." -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Fataler Fehler" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "ZUR BEHEBUNG ENTFERNE DIESE DATEI:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "Modul %s ist fehlerhaft!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Fehler beim Ausführen der URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "Diese Ausgabe" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "Beendet die Anwendung" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "Gibt die Version aus" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "Gibt die Zeit aus" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "Zeigt alle HUD Komponenten" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "Gibt alle Tastenbelegungen aus" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "Zeigt deine Serial an" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "Verbindet zu einem Server (host port nick pass)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "Verbindet zum vorherigen Server" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "Belegt eine Taste (Tastenbelegung)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "Entfernt eine Tastenbelegung (Taste)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "Kopiert die Standard GTA Steuerung" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" -msgstr "gibt ein Bildschirmfoto zurück" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "speichert sofort die config" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "Leert das Debug-Fenster" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "Scrollt die Chatbox aufwärts" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "Scrollt die Chatbox abwärts" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "Scrollt das Debug-Fenster aufwärts" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "Scrollt das Debug-Fenster abwärts" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "Zeigt die Speicherstatistik" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "zeigt das frame timing diagramm" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "für Entwickler: reload news" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ BEFEHL HILFE ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Die Zeit ist %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "verbinden: Syntax ist 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "verbinden: Falscher Hafen" +msgstr "gibt ein Bildschirmfoto zurück" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "verbinden: Verbindung zu %s:%u..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "speichert sofort die config" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "connect: konnte keine Verbindung zu %s:%u herstellen!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "Leert das Debug-Fenster" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "verbinden: Entladen der aktuellen Mod fehlgeschlagen" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "Scrollt die Chatbox aufwärts" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "Scrollt die Chatbox abwärts" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "Wiederverbinden: Ungültige Port Nummer" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "Scrollt das Debug-Fenster aufwärts" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "Wiederverbinden: Erneut verbinden zu %s:%u..." +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "Scrollt das Debug-Fenster abwärts" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "Wiederverbinden: Es konnte keine Verbindung zu %s:%u hergestellt werden!" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "Zeigt die Speicherstatistik" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Binden Sie alle Kontrollen aus GTA" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "zeigt das frame timing diagramm" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Gespeicherte Konfigurationsdatei" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "für Entwickler: reload news" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Ihre Seriennummer lautet: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Du benutzt einen Featurebranch-Build! Dies ist nur ein Testbuild, der nicht benutzt werden kann, um öffentliche Server zu betreten." -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Beschleunigungsachse" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA wird für XP/Vista ab Juli 2019 keine Updates mehr erhalten.\n\n" +"Aktualisiere Windows, um auf aktuellen Servern zu spielen." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Bremsachse" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Dies wird deine Verbindung zum aktuellen Server trennen.\n\n" +"Bist du sicher, dass du die Verbindung trennen willst?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programmierung" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "VERBINDUNG GETRENNT" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Beitragende" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "INFORMATION" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Spieldesign / Scripting" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "NEWS" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Sprachlokalisierung" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Letzten Artikel aufrufen" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Patch Beitragende" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Das Bildschirmfoto hat %d bytes, benötigt aber %d bytes." -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Besonderen Dank an" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Bildschirmfoto fehlgeschlagen" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Diese Software und dieses Projekt verwenden die folgenden Bibliotheken und Software:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Bildschirmfoto aufgenommen: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Möchten Sie Online-Hilfe zu diesem Problem sehen?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Unbekannter Befehl oder cvar: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2397,25 +2386,56 @@ msgid "Group control backwards" msgstr "Gruppenkontrolle rückwärts" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Der ausgewählte Skin konnte nicht geladen werden und der Standardskin konnte ebenfalls nicht geladen werden. Bitte installiere MTA neu." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Das Bildschirmfoto hat %d bytes, benötigt aber %d bytes." +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Möchten Sie Online-Hilfe zu diesem Problem sehen?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Bildschirmfoto fehlgeschlagen" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONSOLE" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Bildschirmfoto aufgenommen: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programmierung" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Beitragende" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Spieldesign / Scripting" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Sprachlokalisierung" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Patch Beitragende" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Besonderen Dank an" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Diese Software und dieses Projekt verwenden die folgenden Bibliotheken und Software:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Beschleunigungsachse" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Bremsachse" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2423,6 +2443,61 @@ msgstr "Konnte Direct3D9 nicht initialisieren.\n\n" "Bitte stelle sicher, dass die DirectX End-User Runtime und \n" "das aktuelle Windows Service Pack korrekt installiert wurden." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Pausiert" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "Spieler" +msgstr[1] "Spieler" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "an" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "Server" +msgstr[1] "Server" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Master-Server wird abgefragt (%lu ms vergangen)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Serverliste konnte nicht verarbeitet werden." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Serverliste konnte nicht empfangen werden." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Ausweichserverliste)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "LAN-Broadcast-Socket kann nicht gebunden werden" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "LAN wird nach Servern durchsucht" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2476,7 +2551,7 @@ msgstr "Latenz:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Spielerliste" @@ -2503,40 +2578,39 @@ msgstr "Spiel beitreten, sobald ein Platz verfügbar ist." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "BITTE GIB DAS SERVERPASSWORT EIN" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Zeitüberschreitung" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Abfrage läuft..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "SERVER-BROWSER" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Lokal" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Favoriten" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Verlauf" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2544,298 +2618,367 @@ msgstr "Für schnelles Verbinden:\n\n" "Gib die Adresse und den Port in die Adresszeile ein.\n" "Wähle alternativ einen Server aus dem Verlauf und drücke 'Verbinden'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "HILFE" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Aktualisieren" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Favorit hinzufügen" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Verbinden" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Serverinformationen" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Nach Servern suchen" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Nach Spielern suchen" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Suche starten" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Suche nach Spielernamen..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Suche nach Servernamen..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Name" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Spieler" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Verzögerung" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Spielmodus" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Filter:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Leer" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Voll" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Passwortgeschützt" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Offline" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Andere Version" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Zurück" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Lade..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..Lade.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Keine Adresse angegeben!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Unbekanntes Protokoll" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Bitte nutze das mtasa:// Protokoll!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Ungültiger Nickname! Bitte setze einen neuen in den Einstellungen!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Du musst einen Server zum Verbinden auswählen." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Pausiert" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problem mit dem Grafikkartentreiber" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "Spieler" -msgstr[1] "Spieler" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Konnte keine gültigen Bildschirmauflösungen finden." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "an" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Bist du dir sicher, dass du diese Bildschirmauflösungen verwenden willst?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "Server" -msgstr[1] "Server" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "Initialisierung von game_sa fehlgeschlagen" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Master-Server wird abgefragt (%lu ms vergangen)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "Speicher Zuweisung fehlgeschlagen" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Serverliste konnte nicht verarbeitet werden." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Website-Anfragen" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Serverliste konnte nicht empfangen werden." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Der Server fordert die folgenden Websites an, um sie (später) zu laden:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Ausweichserverliste)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NIEMALS SENSIBLE DATEN EINGEBEN, UM SIE VOR DIEBSTAHL ZU SCHÜTZEN" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "LAN-Broadcast-Socket kann nicht gebunden werden" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Entscheidung erinnern" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "LAN wird nach Servern durchsucht" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Verweigern" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Diese Version ist abgelaufen." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "Verbindung zum Server schließen" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "Nametags anzeigen" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "Chatbox anzeigen" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "zeigt die Netzwerkstatistiken" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "Eingabezeile des Chats öffnen" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "Sprachübertragung an andere Spieler starten" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "Als Passagier in ein Fahrzeug steigen" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "Nächsten Radiokanal" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "Vorherigen Radiokanal" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "Aktiviert die Spieler-Karte Sicht" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "Zoomt in die Spieler-Karte" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "Zoomt aus der Spieler-Karte raus" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "Bewegt die Spieler-Karte nach Norden" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "Bewegt die Spieler-Karte nach Süden" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "Bewegt die Spieler-Karte nach Osten" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "Bewegt die Spieler-Karte nach Westen" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "Hängt die Spieler-Karte an" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "Verringert die Deckkraft der Spieler-Karte" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "Erhöht die Deckkraft der Spieler-Karte" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "Schaltet den Spieler-Karten Text um" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "Eine Nachricht an den Zielspieler schicken" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "In einem Fahrzeug die nächste Waffe auswählen" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "In einem Fahrzeug die vorherige Waffe auswählen" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "gibt Informationen über den aktuellen Server aus" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "Definiert den Vergrößerungsmultiplikator aller Textanzeigen" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Entwicklungsmodus) Zeigt Colshapes an" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Entwicklungsmodus) gibt world sound ids im Debugfenster aus" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "SPIEL HOSTEN" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Resourcen" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Servername:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Passwort:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Max Spieler:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Rundfunk:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Ausgewählte" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Alle" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Starten" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "Modus geändert: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "Zoom: %s/%s Bewegung: %s, %s, %s, %s Deckkraft: %s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "Karte umschalten: %s Hilfstext umschalten %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "Spieler folgen" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "Freie Bewegung" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Karten-Download-Fortschritt:" @@ -2856,195 +2999,195 @@ msgstr "%s von %s" msgid "Disconnect to cancel download" msgstr "Trenne die Verbindung, um den Download abzubrechen." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Verbindung getrennt: Ungültiger Nickname" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Verbindung vom Server getrennt" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Verbindung getrennt: Serial ist gebannt.\n" "Grund:%s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Verbindung getrennt: Du bist gebannt.\n" "Grund: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Verbindung getrennt: Account wurde gebannt.\n" "Grund: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Verbindung getrennt: Versionen stimmen nicht überein" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Verbindung getrennt: Zu viele Verbindungsversuche. Bitte warte eine Minute und versuche es dann erneut." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Verbindung getrennt: Server ist aus anderem Branch.\n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Verbindung getrennt: Ungültige Version.\n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Verbindung getrennt: Server nutzt einen neueren Build.\n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Verbindung getrennt: Server nutzt einen älteren Build.\n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Verbindung getrennt: Nickname wird bereits verwendet" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Verbindung unterbrochen: Das Spielerelement konnte nicht erstellt werden." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Verbindung getrennt: Server hat die Verbindung verweigert: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Verbindung getrennt: Verfizierung der Serial fehlgeschlagen" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "Verbindung getrennt: Seriennummer wird bereits verwendet" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Verbindung getrennt: Verbindungsdesynchronisation %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Verbindung getrennt: Du wurdest von %s gekickt" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Verbindung getrennt: Du wurdest von %s gebannt" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Verbindung getrennt: Server wurde heruntergefahren oder startet neu" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Du wurdest aus dem Spiel geworfen" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Dieser Server benötigt eine unmodifizierte gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Bitte ersetze gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Dieser Server erlaubt keine angepassten D3D9.DLLs" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Entferne D3D9.DLL aus deinem GTA Installationsordner und starte MTA neu" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Dieser Server erlaubt keine virtuellen Maschinen" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Dieser Server benötigt aktivierte Treibersignierung" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Bitte starte deinen PC neu" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Dieser Server hat fehlende Komponenten des Anticheats festgestellt" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Versuche MTA neu zu starten" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Dieser Server benötigt eine unmodifizierte gta3.img und gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Bitte ersetze gta3.img oder gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Dieser Server erlaubt Wine nicht" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Stelle sicher, dass kein anderes Programm MTA:SA modifiziert" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Zeit verbleibend: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d Tag" msgstr[1] "%d Tage" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d Stunde" msgstr[1] "%d Stunden" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d Minute" msgstr[1] "%d Minuten" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3052,302 +3195,212 @@ msgstr[0] "%d Sekunde" msgstr[1] "%d Sekunden" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Verbindung getrennt" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Downloadfehler: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "Ein UFO herumfliegen lassen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "Herumfahren" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "Reiten auf den Wellen der" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "Mit dem Zug fahren in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "Herumfliegen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "Herumreiten" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "Monstertrucks fahren herum" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "Quaddeln um" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "Häschen hüpft herum" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "Seltsame Dinge tun in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "Herumklettern in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "Im Vorbeifahren in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "Blub blub..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "Wasser atmen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "Ertrinken in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "Sich in Deckung ducken in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "Kämpfen in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "Die Fäuste in die Hand nehmen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "Narren in die Luft jagen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "Hochschießen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "Jetpacking in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "Buchstäblich brennend in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "Aufflammen in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "Schwimmen in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "Herumschweben in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "Von einem Hai gejagt zu werden" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "Erstickungstod in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Spiel wird betreten..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Nicht verbunden. Bitte verwende den Serverbrowser oder den 'connect' Befehl um zu einem Server zu verbinden." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Konnte lokalen Server nicht starten. Für Details siehe Konsole." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Lokaler Server" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Lokaler Server wird gestartet..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "Area 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "Herumlaufen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Du wurdest aus dem Spiel geworfen ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Verbinde zu lokalem Server..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Fehler beim Verbinden zum Server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Zeitüberschreitung beim Verbinden zum lokalen Server. Siehe Konsole für weitere Details." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Verbindung zum Server verloren" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Verbindung getrennt: Der Server ist voll" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Verbindung getrennt: Ungültiges Passwort angegeben" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "Verifikation des MTA Clients fehlgeschlagen!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "In einem Graben" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "Auf dem Weg ins Krankenhaus" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "Begegnung mit ihrem Schöpfer" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "Bedauern über ihre Entscheidungen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "Vergeudet" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "SPIEL HOSTEN" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Resourcen" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Servername:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Passwort:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Max Spieler:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Rundfunk:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Ausgewählte" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Alle" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Starten" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "Modus geändert: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "Zoom: %s/%s Bewegung: %s, %s, %s, %s Deckkraft: %s/%s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "Karte umschalten: %s Hilfstext umschalten %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "Spieler folgen" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "Freie Bewegung" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problem mit dem Grafikkartentreiber" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Konnte keine gültigen Bildschirmauflösungen finden." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Bist du dir sicher, dass du diese Bildschirmauflösungen verwenden willst?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "Initialisierung von game_sa fehlgeschlagen" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "Speicher Zuweisung fehlgeschlagen" +msgid "Download error: %s" +msgstr "Downloadfehler: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 #, c-format msgid "Fatal error (%u). If this problem persists, please check out multitheftauto.com for support." -msgstr "" +msgstr "Schwerwiegender Fehler (%u). Wenn das Problem bestehen bleibt, wende dich an multitheftauto.com für Unterstützung." #. #ifdef MTA_DEBUG #. assert ( 0 ); @@ -3356,17 +3409,17 @@ msgstr "" #: Shared/mods/deathmatch/logic/Utils.cpp:143 #, c-format msgid "Protocol error (%u). If this problem persists, please check out multitheftauto.com for support." -msgstr "" +msgstr "Protokollfehler (%u). Wenn das Problem bestehen bleibt, wende dich an multitheftauto.com für Unterstützung." #: Shared/mods/deathmatch/logic/Utils.cpp:145 msgid "Connection error" msgstr "Verbindungsfehler" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto wurde nicht korrekt installiert. Bitte installiere es erneut." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Dein Browser wird jetzt eine Webseite mit Informationen anzeigen, die dir helfen könnten.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/el_GR/client.pot b/Shared/data/MTA San Andreas/MTA/locale/el_GR/client.pot index 26a6446a19e..d453a948f2a 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/el_GR/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/el_GR/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:18\n" "Last-Translator: \n" "Language-Team: Greek\n" "Language: el_GR\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "ΠÏόβλημα επανεκκίνησης του MTA:SΑ\n\n" -"Εάν το Ï€Ïόβλημα παÏαμένει, ανοίξτε τη ΔιαχείÏιση ΕÏγασιών και\n" -"σταματήστε τις διαδικασίες 'gta_sa.exe' και 'Multi Theft Auto.exe'\n\n\n" -"ΠÏοσπαθήστε να ξεκινήσετε ξανά το MTA:SA;" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Σφάλμα" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Μια άλλη παÏάμετÏος του MTA εκτελείται ήδη.\n\n" -"Εάν το Ï€Ïόβλημα παÏαμένει, κάντε επανεκκίνηση του υπολογιστή σας" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Μια άλλη παÏάμετÏος του MTA εκτελείται ήδη.\n\n" -"Θέλετε να τη τεÏματίσετε;" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Επιλέξτε τον Ï€ÏοοÏισμό εγκατάστασης του Grand Theft Auto: San Andreas" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "Το MTA:SA χÏειάζεται άδεια διαχειÏιστή για την ακόλουθη εÏγασία:\n\n" +" '%s'\n\n" +"ΠαÏακαλώ επιβεβαιώστε το επόμενο παÏάθυÏο." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Σφάλμα κατά τη φόÏτωση του %s δομοστοιχείου! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "ΑντιγÏαφή αÏχείων..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Η αντιγÏαφή ολοκληÏώθηκε νωÏίς. Όλα εντάξει." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Τελειώνοντας..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Έγινε!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Îέα εγκατάσταση του %s ανιχνεÏθηκε.\n\n" +"Θέλετε να αντιγÏάψετε τις Ïυθμίσεις σας από το %s ;" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "To GTA:SA αντιμετώπισε Ï€Ïόβλημα με το άνοιγμα του αÏχείου '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "Στο GTA:SA λείπει το αÏχείο '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "Το GTA:SA αντιμετώπισε Ï€Ïόβλημα κατά τη φόÏτωση ενός μοντέλου." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Αν Ï„Ïοποποιήσατε Ï€Ïόσφατα το gta3.img, δοκιμάστε να επανεγκαταστήσετε το GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "Το GTA:SA αντιμετώπισε Ï€Ïόβλημα στην Ï€Ïοσθήκη αναβάθμισης σε ένα όχημα." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "Το GTA:SA βÏήκε σφάλματα στο αÏχείο '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Έγινε επανεκκίνηση του υπολογιστή σας κατά την αναπαÏαγωγή του MTA:SA;" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "ΠαÏακαλείστε να τεÏματίσετε τα ακόλουθα Ï€ÏογÏάμματα Ï€Ïιν συνεχίσετε:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Σφάλμα αναντιστοιχίας έκδοσης αÏχείου. Επανεγκαταστήστε το MTA:SA αν αντιμετωπίσετε Ï€Ïοβλήματα.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Κάποια αÏχεία λείπουν. Επανεγκαταστήστε το MTA:SA αν αντιμετωπίσετε Ï€Ïοβλήματα.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "Το MTA:SA δεν είναι συμβατό με την 'ασφαλή λειτουÏγία' των Windows.\n\n" +"Κάντε επανεκκίνηση του υπολογιστή σας.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Έχετε Ï€Ïοβλήματα με την εκτέλεση του MTA:SA;.\n\n" "Θέλετε να επανέλθετε σε Ï€ÏοηγοÏμενη έκδοση;" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "Φαίνεται ότι υπάÏχει Ï€Ïόβλημα με την εκ "Η επαναφοÏά των Ïυθμίσεων GTA μποÏεί μεÏικές φοÏές να διοÏθώσει αυτό το Ï€Ïόβλημα.\n\n" "Θέλετε να επαναφέÏετε τις Ïυθμίσεις GTA τώÏα;" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "Οι Ïυθμίσεις GTA έχουν επαναφεÏθεί.\n\n" "Πατήστε Εντάξει για να συνεχίσετε." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Το αÏχείο δεν μπόÏεσε να διαγÏαφεί: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Έχετε Ï€Ïοβλήματα με την εκτέλεση του MTA:SA?.\n\n" "Θέλετε να δείτε κάποια βοήθεια στο διαδίκτυο;" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Έχετε Ï€Ïοβλήματα με την εκτέλεση του MTA:SA;.\n\n" "Θέλετε να αλλάξετε την ακόλουθη ÏÏθμιση;" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "ΠλήÏης οθόνη:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "ΠαÏάθυÏο χωÏίς πεÏιθώÏια" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Έχετε Ï€Ïοβλήματα με την εκτέλεση του MTA:SA;.\n\n" "Δοκιμάστε να απενεÏγοποιήσετε τα παÏακάτω Ï€Ïοϊόντα για το GTA και το MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,128 +189,288 @@ msgstr "ΠΡΟΕΙΔΟΠΟΙΗΣΗ\n\n" "Το MTA:SA έχει εντοπίσει ασυνήθιστη δÏαστηÏιότητα.\n" "Εκτελέστε μια σάÏωση ιών για να βεβαιωθείτε ότι το σÏστημά σας είναι ασφαλές.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Το αÏχείο που εντοπίστηκε ήταν: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Μια αναφοÏά του GTA: San Andreas είναι ήδη σε λειτουÏγία. ΠÏέπει να τεÏματιστεί Ï€Ïιν ξεκινήσει το MTA:SA. Θέλετε να το κάνετε τώÏα;" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "ΠληÏοφοÏία" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Δεν είναι δυνατό να τεÏματιστεί το GTA:San Andreas. Εάν το Ï€Ïόβλημα παÏαμένει, παÏακαλώ κάντε επανεκκίνηση του υπολογιστή σας." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "ΠÏόβλημα επανεκκίνησης του MTA:SΑ\n\n" +"Εάν το Ï€Ïόβλημα παÏαμένει, ανοίξτε τη ΔιαχείÏιση ΕÏγασιών και\n" +"σταματήστε τις διαδικασίες 'gta_sa.exe' και 'Multi Theft Auto.exe'\n\n\n" +"ΠÏοσπαθήστε να ξεκινήσετε ξανά το MTA:SA;" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Σφάλμα" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Μια άλλη παÏάμετÏος του MTA εκτελείται ήδη.\n\n" +"Εάν το Ï€Ïόβλημα παÏαμένει, κάντε επανεκκίνηση του υπολογιστή σας" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Μια άλλη παÏάμετÏος του MTA εκτελείται ήδη.\n\n" +"Θέλετε να τη τεÏματίσετε;" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Δεν υπάÏχουν καταχωÏήσεις μητÏώου. ΠαÏακαλώ επανεγκαταστήστε το Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Η διαδÏομή για την εγκατάσταση του GTA: San Andreas πεÏιέχει μη υποστηÏιζόμενους χαÏακτήÏες (unicode). Μετακινήστε την εγκατάσταση Grand Theft Auto: San Andreas σε συμβατή διαδÏομή που πεÏιέχει μόνο τυπικοÏÏ‚ χαÏακτήÏες ASCII και επανεγκαταστήστε το Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Η διαδÏομή για την εγκατάσταση του 'MTA:SA' ή 'GTA: San Andreas'\n" -"πεÏιέχει ένα ';' (εÏωτηματικό).\n\n" -"Αν αντιμετωπίζετε Ï€Ïοβλήματα κατά την εκτέλεση του MTA:SA,\n" -"μετακινήστε την εγκατάσταση ή τις εγκαταστάσεις σας σε μια διαδÏομή που δεν πεÏιέχει εÏωτηματικό." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Η φόÏτωση απέτυχε. Βεβαιωθείτε ότι τα τελευταία αÏχεία δεδομένων έχουν εγκατασταθεί σωστά." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Η φόÏτωση απέτυχε. Βεβαιωθείτε ότι το %s έχει εγκατασταθεί σωστά." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Η φόÏτωση απέτυχε. Δεν ήταν δυνατή η εÏÏεση του gta_sa.exe στο %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Η φόÏτωση απέτυχε. %s υπάÏχει στον Ï€ÏοοÏισμό του GTA. ΠαÏακαλώ διαγÏάψτε Ï€Ïιν συνεχίσετε." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Το κÏÏιο αÏχείο έχει ένα λάθος όνομα (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Το κÏÏιο αÏχείο δεν είναι υπογεγÏαμμένο. Πιθανή δÏαστηÏιότητα ιοÏ.\n\n" -"ΑνατÏέξτε στην ηλεκτÏονική βοήθεια, εάν το MTA δεν λειτουÏγεί σωστά." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Data file %s is modified. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" +msgstr "Επίλυση ζητήματος διαμόÏφωσης" + +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "" + +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "ΑÏχεία .asi βÏίσκονται στον Ï€ÏοοÏισμό εγκατάστασης του 'MTA:SA' ή του 'GTA: San Andreas'.\n\n" -"ΚαταÏγήστε αυτά τα αÏχεία .asi αν αντιμετωπίσετε Ï€Ïοβλήματα με το MTA:SA." +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "" -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Σφάλμα αναντιστοιχίας έκδοσης αÏχείου. Επανεγκαταστήστε το MTA:SA αν αντιμετωπίσετε Ï€Ïοβλήματα.\n" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Εγκατάσταση ενημέÏωσης..." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Κάποια αÏχεία λείπουν. Επανεγκαταστήστε το MTA:SA αν αντιμετωπίσετε Ï€Ïοβλήματα.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Εξαγωγή αÏχείων..." -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "Το MTA:SA δεν είναι συμβατό με την 'ασφαλή λειτουÏγία' των Windows.\n\n" -"Κάντε επανεκκίνηση του υπολογιστή σας.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "Το MTA:SA δεν μπόÏεσε να ολοκληÏώσει την ακόλουθη εÏγασία:\n\n" +" '%s'\n" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" -msgstr "Επίλυση ζητήματος διαμόÏφωσης" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Το crash Ï€Ïοκλήθηκε από ένα σφάλμα στον οδηγό γÏαφικών **\n\n" +"** ΠαÏακαλώ αναβαθμίστε του οδηγοÏÏ‚ γÏαφικών σας **" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "ΕπιδιόÏθωση σφάλματος ανÏψωσης" +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Εγκατάσταση αναβαθμισμένων MTA:SA αÏχείων" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Δεν είναι δυνατή η αναβάθμιση λόγω αντικÏουόμενων αÏχείων. ΠαÏακαλώ κλείστε τις άλλες εφαÏμογές και ξαναπÏοσπαθήστε" + +#: Client/loader/CInstallManager.cpp:1088 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Δεν ήταν δυνατή η εκκίνηση του Grand Theft Auto: San Andreas. ΠαÏακαλώ δοκιμάστε να κάνετε επανεκκίνηση ή εάν το Ï€Ïόβλημα παÏαμένει, επικοινωνήστε με το MTA στη διεÏθυνση www.multitheftauto.com. \n\n" -"[%s]" +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Το Multi Theft Auto δεν έχει εγκατασταθεί σωστά, παÏακαλώ επανεγκαταστήστε. %s" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "Το GTA: San Andreas μποÏεί να μην έχει ξεκινήσει σωστά. Θέλετε να το τεÏματίσετε;" +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "Το MTA:SA δεν είναι δυνατό να συνεχίσει διότι ο οδηγός %s δεν έχει αÏκετό χώÏο." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Χαμένο αÏχείο:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Εάν το MTA αποτÏχει να φοÏτώσει, παÏακαλώ επανεγκαταστήστε το GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Αναβάθμιση Ïυθμίσεων εγκατάστασης" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Αναβάθμιση Ïυθμίσεων συμβατότητας" #. ///////////////////////////////////////////////////////////////////////// #. @@ -268,166 +478,166 @@ msgstr "Το GTA: San Andreas μποÏεί να μην έχει ξεκινήσε #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Îαι" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Όχι" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "Εντάξει" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Έξοδος" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Βοήθεια" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "ΑκÏÏωση" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "Το MTA: San Andreas συνάντησε ένα Ï€Ïόβλημα" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "ΠληÏοφοÏίες Crash" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "ΤικάÏετε το πλαίσιο για να στείλετε πληÏοφοÏίες του crash στους MTA Ï€ÏογÏαμματιστές χÏησιμοποιώντας το 'διαδίκτυο'" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Κάνοντας το θα αυξήσει τις πιθανότητες για αυτό το crash να φτιαχτεί." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Θέλετε να επανεκκινήσετε το MTA: San Andreas ;" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - ΠÏοειδοποιήση" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Παίξτε MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - ΠεÏίπλοκες Ïυθμίσεις" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "Το NVidia Optimus ανιχνεÏθηκε!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "ΠÏοσπαθήστε κάθε επιλογή και δείτε πως λειτουÏγεί:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Εάν είστε απελπισμένος, αυτό μποÏεί να βοηθήσει:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Αναγκάστε λειτουÏγία παÏαθÏÏου" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Îα μην εμφανιστεί ξανά" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "ΠÏοειδοποίηση: Δεν ήταν δυνατή η ανίχνευση anti-virus Ï€Ïοϊόντων " -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -435,1102 +645,1180 @@ msgstr "Το MTA δεν μπόÏεσε να ανιχνεÏσει έναν anti-v "Οι ιοί παÏεμβαίνουν στο MTA και υποβαθμίζουν την εμπειÏία Ï€Î±Î¹Ï‡Î½Î¹Î´Î¹Î¿Ï ÏƒÎ±Ï‚. \n\n" "Πατήστε 'Βοήθεια' για πεÏισσότεÏες πληÏοφοÏίες." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Έχω ήδη εγκαταστήσει ένα anti-virus" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Δεν θα εγκαταστήσω ένα anti-virus.\n" "Θέλω ο υπολογιστής μου να μείνει και να είναι μέÏος ενός botnet." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Ψάχνοντας για το Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "ΠαÏακαλώ ξεκινήστε το Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Εγκατάσταση ενημέÏωσης..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Η σÏνδεση απέτυχε: Δόθηκε άτοπο ψευδώνυμο!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Εξαγωγή αÏχείων..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Η ΣÏνδεση απέτυχε. Δόθηκε άτοπος διοÏγανωτής!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "ΑντιγÏαφή αÏχείων..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "H σÏνδεση στο %s με θÏÏα %u απέτυχε!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Η αντιγÏαφή ολοκληÏώθηκε νωÏίς. Όλα εντάξει." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "ΣÏνδεση στο %s:%u... " -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Τελειώνοντας..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Έγινε!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "ΣΥÎΔΕΕΤΕ" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "Το MTA:SA χÏειάζεται άδεια διαχειÏιστή για την ακόλουθη εÏγασία:\n\n" -" '%s'\n\n" -"ΠαÏακαλώ επιβεβαιώστε το επόμενο παÏάθυÏο." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Λήξη χÏόνου σÏνδεσης" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "Το MTA:SA δεν μπόÏεσε να ολοκληÏώσει την ακόλουθη εÏγασία:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Αποσυνδέθηκες: άγνωστο σφάλμα Ï€Ïωτοκόλλου" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Το crash Ï€Ïοκλήθηκε από ένα σφάλμα στον οδηγό γÏαφικών **\n\n" -"** ΠαÏακαλώ αναβαθμίστε του οδηγοÏÏ‚ γÏαφικών σας **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Αποσυνδέθηκες: αποσυνδέθηκες απομακÏυσμένα" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Εγκατάσταση αναβαθμισμένων MTA:SA αÏχείων" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Αποσυνδέθηκες: χάθηκε η απομακÏυσμένη σÏνδεση" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Δεν είναι δυνατή η αναβάθμιση λόγω αντικÏουόμενων αÏχείων. ΠαÏακαλώ κλείστε τις άλλες εφαÏμογές και ξαναπÏοσπαθήστε" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Αποσυνδέθηκες: Έχεις αποκλειστεί από αυτό τον διακομιστή" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Αποσυνδέθηκες: αποσυνδέθηκες από τον διακομιστή" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Αποσυνδέθηκες: χάθηκε η σÏνδεση με τον διακομιστή" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Αποσυνδέθηκες: η σÏνδεση αποÏÏίφθηκε" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Το Multi Theft Auto δεν έχει εγκατασταθεί σωστά, παÏακαλώ επανεγκαταστήστε. %s" +msgid "No such mod installed (%s)" +msgstr "Δεν έχει εγκατασταθεί τέτοια Ï„Ïοποποίηση (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Κακή ανταπόκÏιση διακομιστή (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Κακή ανταπόκÏιση διακομιστή (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Ελληνικά" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Απασχολημένος" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Δεν είναι δυνατός ο έλεγχος για ενημεÏώσεις αυτή την στιγμή" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s απαιτείται" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Μια ενημεÏωμένη έκδοση του MTA:SA %s απαιτείται για την σÏνδεση στον επιλεγμένο διακομιστή.\n\n" +"Θέλετε να κάνετε λήψη και να την εγκαταστήσετε MTA:SA %s ;" + +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Θέλετε να αÏχίσετε το MTA:SA %s και να συνδεθείτε σε αυτόν τον διακομιστή ;" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Δεν είναι δυνατό να συνδεθείτε αυτή τη στιγμή.\n\n" +"ΠαÏακαλώ Ï€Ïοσπαθήστε αÏγότεÏα." -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Συνδέετε" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "ΠαÏακαλώ πεÏιμένετε..." -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "ΠΡΑΓΜΑΤΟΠΟΙΕΙΤΑΙ ΕΛΕΓΧΟΣ" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "ΕΛΕΓΧΟΣ ΕÎΗΜΕΡΩΣΗΣ" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "Το MTA:SA δεν είναι δυνατό να συνεχίσει διότι ο οδηγός %s δεν έχει αÏκετό χώÏο." +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Δεν χÏειάζεται ενημέÏωση" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Χαμένο αÏχείο:" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "ΓΙÎΕΤΑΙ ΛΗΨΗ" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Εάν το MTA αποτÏχει να φοÏτώσει, παÏακαλώ επανεγκαταστήστε το GTA:SA" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "αναμείνατε..." -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Αναβάθμιση Ïυθμίσεων εγκατάστασης" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "ΥΠΟΧΡΕΩΤΙΚΗ ΕÎΗΜΕΡΩΣΗ" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Αναβάθμιση Ïυθμίσεων συμβατότητας" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Για να συνδεθείτε σε αυτόν τον διακομιστή, Ï€Ïέπει να ενημεÏώσετε το MTA.\n\n" +"Θέλετε να το ενημεÏώσετε τώÏα ;" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "ΠΡΟΑΙΡΕΤΙΚΗ ΕÎΗΜΕΡΩΣΗ" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Ο διακομιστής λέει ότι μια ενημέÏωση συνίσταται, αλλά δεν είναι απαÏαίτητη.\n\n" +"Θέλετε να ενημεÏώσετε τώÏα ;" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "ΣΦΑΛΜΑ ΑΠΟΘΗΚΕΥΣΗΣ" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Δεν είναι δυνατή η δημιουÏγία του αÏχείου." -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "ΣΦΑΛΜΑ ΛΗΨΗΣ" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Επιλέξτε τον Ï€ÏοοÏισμό εγκατάστασης του Grand Theft Auto: San Andreas" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Ο ληφθέν φάκελος φαίνεται να είναι εσφαλμένος." -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Σφάλμα κατά τη φόÏτωση του %s δομοστοιχείου! (%s)" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Για κάποιο λόγο." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Îέα εγκατάσταση του %s ανιχνεÏθηκε.\n\n" -"Θέλετε να αντιγÏάψετε τις Ïυθμίσεις σας από το %s ;" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "Η ΛΗΨΗ ΟΛΟΚΛΗΡΩΘΗΚΕ" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "To GTA:SA αντιμετώπισε Ï€Ïόβλημα με το άνοιγμα του αÏχείου '%s'" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Άγνωστο Ï€Ïόβλημα in _DialogUpdateResult" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "Στο GTA:SA λείπει το αÏχείο '%s'." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "ΕΞΑΤΟΜΙΚΕΥΜΕÎΑ GTA:SA ΑΡΧΕΙΑ" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "Το GTA:SA αντιμετώπισε Ï€Ïόβλημα κατά τη φόÏτωση ενός μοντέλου." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Εντάξει" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Αν Ï„Ïοποποιήσατε Ï€Ïόσφατα το gta3.img, δοκιμάστε να επανεγκαταστήσετε το GTA:SA." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "ΣΦΑΛΜΑ" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "Το GTA:SA αντιμετώπισε Ï€Ïόβλημα στην Ï€Ïοσθήκη αναβάθμισης σε ένα όχημα." +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Κάποια MTA:SA αÏχεία δεδομένων λείπουν.\n\n\n" +"ΠαÏακαλώ επανεγκαταστήστε το MTA:SA" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "Το GTA:SA βÏήκε σφάλματα στο αÏχείο '%s'" +msgid "%3d %% completed" +msgstr "%3d %% ολοκληÏώθηκε" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Έγινε επανεκκίνηση του υπολογιστή σας κατά την αναπαÏαγωγή του MTA:SA;" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Αναμονή για απόκÏιση - %-3d" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "ΠαÏακαλείστε να τεÏματίσετε τα ακόλουθα Ï€ÏογÏάμματα Ï€Ïιν συνεχίσετε:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ ΕÎΤΟΛH ΒΟHΘΕΙΑ ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Αιτήματα ιστότοπου" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Η ÏŽÏα είναι %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Ο διακομιστής ζητάει τα ακόλουθους ιστότοπους έτσι ώστε να τους φοÏτώσει (αÏγότεÏα):" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "ΠΟΤΕ ΜΗΠΕΙΣΑΓΕΤΕ ΕΥΑΙΣΘΗΤΑ ΔΕΔΟΜΕÎΑ ΩΣΤΕ ÎΑ ΜΗΠΚΛΑΠΟΥÎ" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "ΣÏνδεση: Η σÏνταξη είναι 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Θυμήσου την απόφαση" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "ΣÏνδεση: Κακός αÏιθμός θÏÏας" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "ΕπέτÏεψε" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "ΣÏνδεση: Συνδέεται στο %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "ΑÏνοÏμαι" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "ΣÏνδεση: δεν μπόÏεσε να συνδεθεί στο %s:%u!" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "ΣÏνδεση: H αποφόÏτωση της Ï„Ïοποποίησης ήταν ανεπιτυχής" + +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "ΧÏησιμοποιείται ένα χαÏακτηÏιστικό τμήμα έκδοσης! Αυτή είναι μια δοκιμαστική έκδοση μόνο για όσους δεν μποÏοÏν να συνδεθοÏν στους ανοιχτοÏÏ‚ διακοσμητές!" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "Το MTA δεν θα δεχτεί αναβάθμισεις σε XP/Vista μετά τον ΙοÏλιο του 2019.\n\n" -"Αναβάθμιστε σε windows για να συνεχίζεται να παίζεται στους τελευταίους Διακομιστές." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Αυτό θα σας αποσυνδέσει από τον Ï„Ïέχων διακομιστή.\n\n" -"Είστε σίγουÏος ότι θέλετε να αποσυνδεθείτε;" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "ΠΡΟΕΙΔΟΠΟΙΗΣΗ ΑΠΟΣΥÎΔΕΣΗΣ" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "ΔεσμεÏτηκαν όλα τα κουμπιά από το GTA" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "To αÏχείο Ïυθμίσεων αποθηκεÏτηκε" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Ελληνικά" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Ο σειÏιακός αÏιθμός σου είναι: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "ΡΥΘΜΙΣΕΙΣ" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Πολλαπλοί παίκτες" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Βίντεο" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Ήχος" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "ΔεσμεÏσεις" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "ΧειÏισμός" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Διεπαφή" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "ΠεÏιηγητής δικτÏου" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "ΠÏοχωÏημένα" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "ΦόÏτωση Ï€Ïοεπιλεγμένων" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Ευαισθησία ποντικιοÏ:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "ΚατακόÏυφη ευαισθησία στόχευσης:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Ρυθμίσεις ποντικιοÏ" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "ΚατακόÏυφη αναστÏοφή ποντικιοÏ" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Ελιγμοί με ποντίκι" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Πτήση με ποντίκι" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Ρυθμίσεις joypad" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Κανονικά πλήκτÏα (Ποντίκι + ΠληκτÏολόγιο)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Κλασσικά πλήκτÏα (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "ÎεκÏή Ζώνη" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "ΚοÏεσμός" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "ΧÏησιμοποιήστε την καÏτέλα 'ΔεσμεÏσεις' για τα πλήκτÏα joypad." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "ΑÏιστεÏός Μοχλός" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Δεξιός Μοχλός" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "ΠΕΡΙΓΡΑΦΗ" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "ΠΛΗΚΤΡΟ" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ΕÎΑΛ. ΠΛΗΚΤΡΟ" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Ψευδώνυμο:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Αποθήκευση κωδικών διακομιστή" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Αυτόματη ανανέωση πεÏιήγησης διακομιστών" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "ΕπιτÏέπω αναφόÏτωση οθόνης" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Îα επιτÏέπονται οι εξωτεÏικοί ήχοι" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Îα εμφανίζεται πάντα το παÏάθυÏο λήψης" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "ΧÏησιμοποιήστε εξατομικευμένα GTA:SA αÏχεία" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Ρυθμίσεις απόδοσης χάÏτη" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Αδιαφάνεια:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "ΚÏÏια ένταση:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Ένταση Ïαδιοφώνου:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Ένταση SFX:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "Ένταση MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Ένταση ομιλιών:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "ΛειτουÏγία παιχνιδιοÏ:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Γενικά" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Επιλογές Ïαδιοφώνου" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Ισοσταθμιστής Ïαδιοφώνου" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Αυτόματος συντονισμός Ïαδιοφώνου" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Ρυθμίσεις κομματιών χÏήστη" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Ραδιόφωνο" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Τυχαίος" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Διαδοχικός" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Αυτόματη σάÏωση Media" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Ρυθμίσεις απενεÏγοποίησης ήχου" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "ΑπενεÏγοποίηση όλων των ήχων κατά την ελαχιστοποίηση" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "ΑπενεÏγοποίηση ήχων Ïαδιοφώνου κατά την ελαχιστοποίηση" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "ΑπενεÏγοποίηση ήχων SFX κατά την ελαχιστοποίηση" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "ΑπενεÏγοποίηση ήχων MTA κατά την ελαχιστοποίηση" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "ΑπενεÏγοποίηση ήχων ομιλιών κατά την ελαχιστοποίηση" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Ανάλυση:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Οπτικό Πεδίο (FOV):" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Σχεδίαση απόστασης:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Φωτεινότητα:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX Ποιότητα:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "ΦίλτÏο ανισοτÏοπίας:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "ΕυκÏίνεια ΚυÏτών ΓÏαμμών (AA):" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Αναλογία ΠλευÏών:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "ΛειτουÏγία παÏαθÏÏου" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Κανονικό" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "ΧωÏίς πεÏιθώÏια με διατηÏημένη ανάλυση" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mip ΧαÏτογÏάφηση" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Χαμηλά" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "ΜέτÏια" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Υψηλά" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Î Î¿Î»Ï Ï…ÏˆÎ·Î»Î¬" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "ΑπενεÏγοποιήση" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Αυτόματο" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD Αντιστοίχηση συντελεστή αναλογίας" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "ΟγκομετÏικές σκιές" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Εφέ χόÏτου" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "ΘολοÏÏα ζέστης" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Καπνός λάστιχων κτλ" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "ΠλήÏης οθόνη Ελαχιστοποίηση" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "ΕνεÏγοποίηση συσκευής επιλογής Dialog" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Εμφάνιση επικίνδυνων αναλÏσεων" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Αποδίδετε τα οχήματα πάντα με μεγάλη λεπτομέÏεια" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "ΕνεÏγοποίηση απομακÏυσμένων ιστότοπων" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "ΕνεÏγοποιήση Javascript σε απομακÏυσμένους ιστότοπους" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "ΠÏοσαÏμοσμένη μαÏÏη λίστα" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Εισαγάγετε έναν τομέα, Ï€.χ. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "ΜπλόκαÏε" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Τομέας" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "ΑφαίÏεση τομέα" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "ΠÏοεπιλεγμένη άσπÏη λίστα (whitelist)" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "ΕπέτÏεψε" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Λοιπά" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "ΓÏήγοÏα CJ ÏοÏχα φοÏτώνονται:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "ΤαχÏτητα πεÏιήγησης:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Μοναδική σÏνδεση:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Πακέτο ετικετών:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "ΠÏόοδος animation:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Διαδικασία Ï€ÏοτεÏαιότητας:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "ΡÏθμιση απασφαλμάτωσης:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Ροή μνήμης:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "ΕνημέÏωση Ï„Ïπου αναπτÏγματος:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Εγκατάσταση σημαντικών ενημεÏώσεων:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "ΕνεÏγοποίηση" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Î Î¿Î»Ï Î±Ïγό" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "ΠÏοεπιλογμένο" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "ΓÏήγοÏο" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Κανονικό" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "ΠαÏαπάνω από το κανονικό" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Ελάσσων" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Μέγιστο" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 συμβατότητα:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-bit χÏώμα" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "ΣταθεÏοποιήση ποντικιοÏ" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Βοηθήματα αÏχείων Ï€ÏόγÏαμμα-πελάτη:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "ΠÏοβολή στον εξεÏευνητή" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Αυτόματος ενημεÏωτής" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Έλεγχος για ενημέÏωση τώÏα" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Κάποιες Ïυθμίσεις θα αλλάξουν στην επόμενη εκκίνηση του MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Θέλετε να Ï€Ïαγματοποιηθεί επανεκκίνηση τώÏα;" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "ΑΠΑΙΤΕΙΤΕ ΕΠΑÎΕΚΚΙÎΗΣΗ" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Κάποιες Ïυθμίσεις θα αλλάξουν όταν αποσυνδεθείτε από τον Ï„Ïέχων διακομιστή" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Θέλετε να αποσυνδεθείτε τώÏα;" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "ΑΠΑΙΤΕΙΤΑΙ ΑΠΟΣΥÎΔΕΣΗ" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Δεν βÏέθηκε Joypad - Ελέγξτε τις συνδέσεις και επανεκκινήστε το παιχνίδι" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "ΔεσμεÏοντας άξονες" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Κουνήστε έναν άξονα για δέσμευση, ή escape για εκκαθάÏιση" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Γλώσσα:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Σώμα:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "ΠÏοÏυθμίσεις:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Συνομιλία" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "ΦόÏτωση" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "ΧÏώματα" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Διάταξη" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Ρυθμίσεις" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Φόντο Συνομιλίας" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Κείμενο συνομιλίας" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Είσοδος Συνομιλίας" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Εισαγωγή Κειμένου" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "ΓÏαμμές:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Κλίμακα:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Πλάτος:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Μέγεθος" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "μετά" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "για" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "δευτεÏ" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Eξασθένηση" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Εξασθενημένες παλιές γÏαμμές" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "ΟÏιζόντιος:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "ΚατακόÏυφος:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "ΕυθυγÏάμμιση Κειμένου:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "Αντιστάθμισμα Χ:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Αντιστάθμισμα Ψ:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Θέση" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "ΑÏιστεÏά" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "ΚέντÏο" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Δεξιά" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "ΚοÏυφή" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Κάτω μέÏος" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "ΓÏαμματοσειÏά" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "ΑπόκÏυψη φόντου όταν δεν πληκτÏολογείτε" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "ΟλοκλήÏωση ψευδωνÏμου χÏησιμοποιώντας το πλήκτÏο \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "ΕπιτÏέπω τον διακομιστή να δείχνει στιγμιαία ένα παÏάθυÏο" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "ΕπιτÏέπω tray balloon ειδοποιήσεις" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "ΆσπÏο/μαÏÏο πεÏίγÏαμμα κειμένου συνομιλίας" @@ -1538,110 +1826,116 @@ msgstr "ΆσπÏο/μαÏÏο πεÏίγÏαμμα κειμένου συνομι #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Πατήστε ένα πλήκτÏο για να το δεσμεÏσετε, ή escape για εκκαθάÏιση" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "ΔεσμεÏοντας ένα Ï€ÏωταÏχικό πλήκτÏο" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "ΔεσμεÏοντας ένα δευτεÏεÏων πλήκτÏο" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA ΠΛΗΚΤΡΑ ΠΑΙΧÎΙΔΙΟΥ" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "MULTIPLAYER ΠΛΗΚΤΡΑ" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Το ψευδώνυμο σας πεÏιέχει άκυÏους χαÏακτήÏες!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Κόκκινο:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "ΠÏάσινο:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Μπλε:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Διαφάνεια:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "ΧÏώμα" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "ΠÏοεπισκόπηση" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "ΠαÏακαλώ αποσυνδεθείτε Ï€Ïιν αλλάξετε γλώσσα" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "ΠαÏακαλώ αποσυνδεθείτε Ï€Ïιν αλλάξετε σώμα" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Οι ογκομετÏικές σκιές μποÏεί να Ï€Ïοκαλέσουν κάποια συστήματα να επιβÏαδÏνουν.\n\n" "Είστε σίγουÏος ότι θέλετε να τις ενεÏγοποιήσετε;" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "ΠΡΟΕΙΔΟΠΟΙΗΣΗ ΑΠΟΔΟΣΗΣ" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Η αναφόÏτωση οθόνης είναι απαÏαίτητη για μεÏικοÏÏ‚ διακομιστές για anti-cheat λόγους.\n\n" "(Το πλαίσιο συνομιλίας και το ΓÏαφικό πεÏιβάλλον διεπαφής χÏήστη (GUI) δεν συμπεÏιλαμβάνονται στην αναφόÏτωση)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "ΠΛΗΡΟΦΟΡΙΕΣ ΑÎΑΦΟΡΤΩΣΗΣ ΟΘΟÎΗΣ" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "ΟÏισμένα σενάÏια μποÏεί να αναπαÏάγουν ήχους, όπως το Ïαδιόφωνο, από το διαδίκτυο.\n\n" "Η απενεÏγοποίηση αυτής της ÏÏθμισης μποÏεί να μειώσει την χÏήση δικτÏου.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "ΕΞΩΤΕΡΙΚΟΊ ΉΧΟΙ" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1651,11 +1945,7 @@ msgstr "ΜεÏικά αÏχεία στον Ï€ÏοοÏισμό δεδομένων "Ωστόσο, ΤΑ ΕΞΑΤΟΜΙΚΕΥΜΕÎΑ GTA:SA ΑΡΧΕΙΑ ΕΙÎΑΙ ΑΠΟΚΛΕΙΣΜΕÎΑ ΣΕ ΠΟΛΛΟΥΣ ΔΙΑΚΟΜΙΣΤΕΣ\n\n" "Είστε σίγουÏος ότι θέλετε να τα χÏησιμοποιήσετε;" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "ΕΞΑΤΟΜΙΚΕΥΜΕÎΑ GTA:SA ΑΡΧΕΙΑ" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1665,550 +1955,252 @@ msgstr "Η ενεÏγοποίηση της ενημέÏωσης DPI είναι "Ενδέχεται να αντιμετωπίσετε γÏαφικά Ï€Ïοβλήματα αν ενεÏγοποιήσετε αυτήν την επιλογή.\n\n" "Είστε βέβαιοι ότι θέλετε να ενεÏγοποιήσετε αυτήν την επιλογή;" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "ΠΕΙΡΑΜΑΤΙΚΉ ΛΕΙΤΟΥΡΓΊΑ" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "ΠαÏακαλώ εισάγετε το ψευδώνυμο" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "ΠαÏακαλώ εισάγετε το ψευδώνυμο που θα χÏησιμοποιείτε στο παιχνίδι. \n" "Αυτό θα είναι το όνομα σας όταν συνδέεστε και παίζετε σε ένα διακομιστή" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Î Î¿Î»Ï Ï€ÎµÎ¹Ïαματικό χαÏακτηÏιστικό." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Εμποδίζει τις παÏαλλαγές του CJ (ΧÏησιμοποιεί 65MB πεÏισσότεÏη μνήμη RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Οι παλαιότεÏοι δÏομολογητές (router) μποÏεί να χÏειάζονται βÏαδÏτεÏη ταχÏτητα σάÏωσης." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "ΕνεÏγοποίηση χÏήσης μόνο μιας σÏνδεσης όταν γίνεται λήψη." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Πακέτα ετικετών δικτÏου για βοήθεια των ISPs στην αναγνώÏιση της MTA κίνησης δεδομένων. " -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Animation πεÏιστÏεφόμενου κÏκλου στο κάτω μέÏος της οθόνης" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Επιλογή Ï€Ïοεπιλογής πάντα. (Αυτή η ÏÏθμιση δεν είναι αποθηκευμένη)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Το μέγιστο είναι συνήθως το καλÏτεÏο" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Αυτόματος ενημεÏωτής:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Επιλέξτε τα Ï€Ïοεπιλεγμένα εκτός αν θέλετε να συμπληÏώνετε αναφοÏές σφαλμάτων." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Επιλέξτε τα Ï€Ïοεπιλεγμένα για να εγκαθίστανται αυτόματα οι σημαντικές ενημεÏώσεις." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-bit χÏώμα:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "ΕνεÏγοποίηση 16 bit χÏώματος - Απαιτείται επανεκκίνηση του MTA" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "ΣταθεÏοποιήση ποντικιοÏ:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "ΣταθεÏοποιήση κίνησης Ï€Î¿Î½Ï„Î¹ÎºÎ¹Î¿Ï - ΜποÏεί να χÏειαστεί επανεκκίνηση του υπολογιστή" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Άγνωστη εντολή ή cvar: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Απασχολημένος" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Δεν είναι δυνατός ο έλεγχος για ενημεÏώσεις αυτή την στιγμή" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s απαιτείται" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Μια ενημεÏωμένη έκδοση του MTA:SA %s απαιτείται για την σÏνδεση στον επιλεγμένο διακομιστή.\n\n" -"Θέλετε να κάνετε λήψη και να την εγκαταστήσετε MTA:SA %s ;" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Θέλετε να αÏχίσετε το MTA:SA %s και να συνδεθείτε σε αυτόν τον διακομιστή ;" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Δεν είναι δυνατό να συνδεθείτε αυτή τη στιγμή.\n\n" -"ΠαÏακαλώ Ï€Ïοσπαθήστε αÏγότεÏα." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Συνδέετε" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "ΠαÏακαλώ πεÏιμένετε..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "ΠΡΑΓΜΑΤΟΠΟΙΕΙΤΑΙ ΕΛΕΓΧΟΣ" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "ΕΛΕΓΧΟΣ ΕÎΗΜΕΡΩΣΗΣ" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Δεν χÏειάζεται ενημέÏωση" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "ΓΙÎΕΤΑΙ ΛΗΨΗ" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "αναμείνατε..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "ΥΠΟΧΡΕΩΤΙΚΗ ΕÎΗΜΕΡΩΣΗ" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Για να συνδεθείτε σε αυτόν τον διακομιστή, Ï€Ïέπει να ενημεÏώσετε το MTA.\n\n" -"Θέλετε να το ενημεÏώσετε τώÏα ;" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "ΠΡΟΑΙΡΕΤΙΚΗ ΕÎΗΜΕΡΩΣΗ" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Ο διακομιστής λέει ότι μια ενημέÏωση συνίσταται, αλλά δεν είναι απαÏαίτητη.\n\n" -"Θέλετε να ενημεÏώσετε τώÏα ;" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "ΣΦΑΛΜΑ ΑΠΟΘΗΚΕΥΣΗΣ" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Δεν είναι δυνατή η δημιουÏγία του αÏχείου." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "ΣΦΑΛΜΑ ΛΗΨΗΣ" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Ο ληφθέν φάκελος φαίνεται να είναι εσφαλμένος." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Για κάποιο λόγο." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "Η ΛΗΨΗ ΟΛΟΚΛΗΡΩΘΗΚΕ" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Άγνωστο Ï€Ïόβλημα in _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Εντάξει" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "ΣΦΑΛΜΑ" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Κάποια MTA:SA αÏχεία δεδομένων λείπουν.\n\n\n" -"ΠαÏακαλώ επανεγκαταστήστε το MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% ολοκληÏώθηκε" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Αναμονή για απόκÏιση - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Η σÏνδεση απέτυχε: Δόθηκε άτοπο ψευδώνυμο!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Η ΣÏνδεση απέτυχε. Δόθηκε άτοπος διοÏγανωτής!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "H σÏνδεση στο %s με θÏÏα %u απέτυχε!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "ΣÏνδεση στο %s:%u... " - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "ΣΥÎΔΕΕΤΕ" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Λήξη χÏόνου σÏνδεσης" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Αποσυνδέθηκες: άγνωστο σφάλμα Ï€Ïωτοκόλλου" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Αποσυνδέθηκες: αποσυνδέθηκες απομακÏυσμένα" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Αποσυνδέθηκες: χάθηκε η απομακÏυσμένη σÏνδεση" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Αποσυνδέθηκες: Έχεις αποκλειστεί από αυτό τον διακομιστή" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Αποσυνδέθηκες: αποσυνδέθηκες από τον διακομιστή" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Αποσυνδέθηκες: χάθηκε η σÏνδεση με τον διακομιστή" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Αποσυνδέθηκες: η σÏνδεση αποÏÏίφθηκε" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Δεν έχει εγκατασταθεί τέτοια Ï„Ïοποποίηση (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Κακή ανταπόκÏιση διακομιστή (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Κακή ανταπόκÏιση διακομιστή (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Επισκεφθείτε το τελευταίο άÏθÏο ειδήσεων" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "Κονσόλα" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "ΚÏίσιμο σφάλμα" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "ΓΙΑ ΔΙΟΡΘΩΣΗ, ΑΦΑΙΡΕΣΤΕ ΑΥΤΟ ΤΟ ΑΡΧΕΙΟ:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s δομοστοιχείο είναι εσφαλμένο!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Σφάλμα κατά την εκτέλεση του URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "αυτή η οθόνη βοήθειας" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "έξοδος από την εφαÏμογή" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "εμφάνιση της έκδοσης" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "εμφάνιση της ÏŽÏας" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "εμφάνιση του hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "εμφάνιση όλων των δεσμευμένων κουμπιών" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "εμφάνιση του σειÏÎ¹Î±ÎºÎ¿Ï Î±ÏιθμοÏ" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "σÏνδεση με τον διακομιστή (διοÏγανωτής θÏÏα όνομα κωδικός)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "συνδέετε σε έναν Ï€ÏοηγοÏμενο διακομιστή" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "δέσμευση ενός πλήκτÏου (πλήκτÏο έλεγχος)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "Αποδέσμευση ενός πλήκτÏου (πλήκτÏο)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "αντιγÏαφή των Ï€Ïοεπιλεγμένων gta πλήκτÏων " -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "απόδοση στιγμιότυπου οθόνης" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "άμεση αποθήκευση του config" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "εκκαθάÏιση της απασφαλματωμένης όψης" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "κÏλιση του πλαισίου συνομιλίας Ï€Ïος τα επάνω" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "κÏλιση του πλαισίου συνομιλίας Ï€Ïος τα κάτω" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "κÏλιση της απασφαλματωμένης όψης Ï€Ïος τα πάνω" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "κÏλιση της απασφαλματωμένης όψης Ï€Ïος τα κάτω" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "Ï€Ïοβολή στατιστικών στοιχείων μνήμης" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "Ï€Ïοβολή γÏαφήματος συγχÏÎ¿Î½Î¹ÏƒÎ¼Î¿Ï ÎµÎ¹ÎºÏŒÎ½Î±Ï‚" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ ΕÎΤΟΛH ΒΟHΘΕΙΑ ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Η ÏŽÏα είναι %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "ΣÏνδεση: Η σÏνταξη είναι 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "ΣÏνδεση: Κακός αÏιθμός θÏÏας" +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "απόδοση στιγμιότυπου οθόνης" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "ΣÏνδεση: Συνδέεται στο %s:%u..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "άμεση αποθήκευση του config" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "ΣÏνδεση: δεν μπόÏεσε να συνδεθεί στο %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "εκκαθάÏιση της απασφαλματωμένης όψης" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "ΣÏνδεση: H αποφόÏτωση της Ï„Ïοποποίησης ήταν ανεπιτυχής" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "κÏλιση του πλαισίου συνομιλίας Ï€Ïος τα επάνω" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "κÏλιση του πλαισίου συνομιλίας Ï€Ïος τα κάτω" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "κÏλιση της απασφαλματωμένης όψης Ï€Ïος τα πάνω" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "κÏλιση της απασφαλματωμένης όψης Ï€Ïος τα κάτω" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "Ï€Ïοβολή στατιστικών στοιχείων μνήμης" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "ΔεσμεÏτηκαν όλα τα κουμπιά από το GTA" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "Ï€Ïοβολή γÏαφήματος συγχÏÎ¿Î½Î¹ÏƒÎ¼Î¿Ï ÎµÎ¹ÎºÏŒÎ½Î±Ï‚" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "To αÏχείο Ïυθμίσεων αποθηκεÏτηκε" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Ο σειÏιακός αÏιθμός σου είναι: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "ΧÏησιμοποιείται ένα χαÏακτηÏιστικό τμήμα έκδοσης! Αυτή είναι μια δοκιμαστική έκδοση μόνο για όσους δεν μποÏοÏν να συνδεθοÏν στους ανοιχτοÏÏ‚ διακοσμητές!" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Άξονας επιτάχυνσης" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "Το MTA δεν θα δεχτεί αναβάθμισεις σε XP/Vista μετά τον ΙοÏλιο του 2019.\n\n" +"Αναβάθμιστε σε windows για να συνεχίζεται να παίζεται στους τελευταίους Διακομιστές." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Άξονας επιβÏάδυνσης" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Αυτό θα σας αποσυνδέσει από τον Ï„Ïέχων διακομιστή.\n\n" +"Είστε σίγουÏος ότι θέλετε να αποσυνδεθείτε;" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "ΠÏογÏαμματισμός" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "ΠΡΟΕΙΔΟΠΟΙΗΣΗ ΑΠΟΣΥÎΔΕΣΗΣ" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "ΣυνεÏγάτες" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Σχεδίαση / Scripting ΠαιχνιδιοÏ" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Γλωσσική τοπικοποίηση" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Επισκεφθείτε το τελευταίο άÏθÏο ειδήσεων" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "ΣυνεÏγάτες Î»Î¿Î³Î¹ÏƒÎ¼Î¹ÎºÎ¿Ï ÎµÎ½Î·Î¼Î­Ïωσης" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Το στιγμιότυπο οθόνης έλαβε %d bytes, αλλά αναμένονταν %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "ΙδιαίτεÏες ΕυχαÏιστίες!" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Το στιγμιότυπο οθόνης απέτυχε" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Αυτό το λογισμικό κάνει χÏήση των ακολοÏθων βιβλιοθηκών και Ï€ÏογÏαμμάτων:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Στιγμιότυπο οθόνης Ï€Ïοστέθηκε: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Θέλεις να δεις κάποια βοήθεια στο διαδίκτυο για αυτό το Ï€Ïόβλημα ;" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Άγνωστη εντολή ή cvar: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2383,25 +2375,56 @@ msgid "Group control backwards" msgstr "ΠλήκτÏο ομάδας πίσω" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Το σώμα που επιλέξατε δεν μπόÏεσε να φοÏτώσει, και το Ï€Ïοεπιλεγμένο σώμα επίσης δεν μπόÏεσε να φοÏτώσει, παÏακαλώ επανεγκαταστήστε το MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Το στιγμιότυπο οθόνης έλαβε %d bytes, αλλά αναμένονταν %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Θέλεις να δεις κάποια βοήθεια στο διαδίκτυο για αυτό το Ï€Ïόβλημα ;" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Το στιγμιότυπο οθόνης απέτυχε" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "Κονσόλα" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Στιγμιότυπο οθόνης Ï€Ïοστέθηκε: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "ΠÏογÏαμματισμός" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "ΣυνεÏγάτες" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Σχεδίαση / Scripting ΠαιχνιδιοÏ" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Γλωσσική τοπικοποίηση" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "ΣυνεÏγάτες Î»Î¿Î³Î¹ÏƒÎ¼Î¹ÎºÎ¿Ï ÎµÎ½Î·Î¼Î­Ïωσης" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "ΙδιαίτεÏες ΕυχαÏιστίες!" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Αυτό το λογισμικό κάνει χÏήση των ακολοÏθων βιβλιοθηκών και Ï€ÏογÏαμμάτων:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Άξονας επιτάχυνσης" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Άξονας επιβÏάδυνσης" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2409,6 +2432,61 @@ msgstr "Δεν ήταν δυνατή η αÏχικοποίηση του Direct3D "ΠαÏακαλώ σιγουÏευτείτε ότι το DirectX End-User Runtime και\n" "τα τελευταία Windows Service Packs έχουν εγκατασταθεί επιτυχώς." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "ΑδÏανής" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "παίχτης" +msgstr[1] "παίχτες" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "ενεÏγοποίηση" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "διακομιστής" +msgstr[1] "διακομιστές" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Αίτηση της κÏÏιας λίστας διακομιστών (%lu ms πέÏασαν)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Η κÏÏια λίστα διακομιστών δεν μπόÏεσε να αναλυθεί." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Η κÏÏια λίστα διακομιστών δεν μποÏοÏσε να ανακτηθεί." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(ΑντίγÏαφο ασφαλείας λίστας διακομιστών)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Δεν είναι δυνατή η δέσμευση LAN-broadcast socket" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "ΠÏοσπάθεια ÎµÎ½Ï„Î¿Ï€Î¹ÏƒÎ¼Î¿Ï LAN διακομιστών" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2462,7 +2540,7 @@ msgstr "ΚαθυστέÏηση μεταφοÏάς:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Λίστα παιχτών" @@ -2489,40 +2567,39 @@ msgstr "Συνδεθείτε στον διακομιστή αμέσως μόλι msgid "PLEASE ENTER SERVER PASSWORD" msgstr "ΠΑΡΑΚΑΛΩ ΕΙΣΑΓΕΤΕ ΤΟΠΚΩΔΙΚΟ ΤΟΥ ΔΙΑΚΟΜΙΣΤΗ" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Λήξη χÏόνου" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Αμφισβήτηση..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "ΠΕΡΙΗΓΗΣΗ ΔΙΑΚΟΜΙΣΤΩÎ" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Διαδίκτυο" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Τοπικά" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Αγαπημένα" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "ΠÏόσφατα" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2530,298 +2607,367 @@ msgstr "ΓΙΑ ΓΡΗΓΟΡΗ ΣΥÎΔΕΣΗ:\n\n" "ΠληκτÏολογήστε την διεÏθυνση και την θÏÏα στην μπάÏα διεÏθυνσης.\n" "Ή επιλέξτε ένα διακομιστή από το ιστοÏικό και πατήστε 'ΣÏνδεση'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "ΒΟΗΘΕΙΑ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Ανανέωση" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "ΠÏοσθήκη στα Αγαπημένα" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "ΣÏνδεση" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "ΠληÏοφοÏίες διακομιστή" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Αναζήτηση διακομιστών" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Αναζήτηση παιχτών" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "ΈναÏξη αναζήτησης" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Αναζήτηση παιχτών..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Αναζήτηση διακομιστών..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Όνομα" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Παίχτες" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Ping" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "ΤÏπος παιχνιδιοÏ" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "ΠεÏιλαμβάνω:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Άδειος" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "ΠλήÏης" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Κλειδωμένος" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Εκτός σÏνδεσης" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Άλλες εκδόσεις" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Πίσω" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "ΦόÏτωση..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..φόÏτωση.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "ΑπÏοσδιόÏιστη διεÏθυνση!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Άγνωστο Ï€Ïωτόκολλο" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "ΠαÏακαλώ χÏησιμοποιήστε το mtasa:// protocol!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Άτοπο ψευδώνυμο! ΠαÏακαλώ πηγαίνετε στις Ïυθμίσεις και αναθέστε ένα νέο!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "ΠÏέπει να επιλέξετε ένα διακομιστή για να συνδεθείτε σε αυτόν." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "ΑδÏανής" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "ΠÏόβλημα με την οδηγό γÏαφικών" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "παίχτης" -msgstr[1] "παίχτες" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Δεν μποÏεί να βÏεθεί έγκυÏη ανάλυση οθόνης" -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "ενεÏγοποίηση" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Είστε σίγουÏος ότι θέλετε να χÏησιμοποιήσετε αυτή την ανάλυση οθόνης;" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "διακομιστής" -msgstr[1] "διακομιστές" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Αίτηση της κÏÏιας λίστας διακομιστών (%lu ms πέÏασαν)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Η κÏÏια λίστα διακομιστών δεν μπόÏεσε να αναλυθεί." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Αιτήματα ιστότοπου" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Η κÏÏια λίστα διακομιστών δεν μποÏοÏσε να ανακτηθεί." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Ο διακομιστής ζητάει τα ακόλουθους ιστότοπους έτσι ώστε να τους φοÏτώσει (αÏγότεÏα):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(ΑντίγÏαφο ασφαλείας λίστας διακομιστών)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "ΠΟΤΕ ΜΗΠΕΙΣΑΓΕΤΕ ΕΥΑΙΣΘΗΤΑ ΔΕΔΟΜΕÎΑ ΩΣΤΕ ÎΑ ΜΗΠΚΛΑΠΟΥÎ" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Δεν είναι δυνατή η δέσμευση LAN-broadcast socket" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Θυμήσου την απόφαση" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "ΠÏοσπάθεια ÎµÎ½Ï„Î¿Ï€Î¹ÏƒÎ¼Î¿Ï LAN διακομιστών" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "ΑÏνοÏμαι" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Αυτή η έκδοση έχει λήξει." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "αποσÏνδεση από το παιχνίδι" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "εμφανίζει τις ετικέτες των παιχτών" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "εμφανίζει το πλαίσιο συνομιλίας" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "εμφανίζει τα στατιστικά στοιχεία του δικτÏου" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "ανοίγει την είσοδο συνομιλίας" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "μεταδίδει φωνή σε άλλους παίκτες" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "εισέÏχεται σε ένα αυτοκίνητο ως επιβάτης" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "επόμενος σταθμός Ïαδιοφώνου" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "Ï€ÏοηγοÏμενος σταθμός Ïαδιοφώνου" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "στέλνει ένα μήνυμα στον επιλεγμένο παίκτη" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "αλλάζει στο επόμενο όπλο ενώ βÏίσκεστε σε ένα όχημα" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "αλλάζει στο Ï€ÏοηγοÏμενο όπλο ενώ βÏίσκεστε σε ένα όχημα" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "εξάγει πληÏοφοÏίες σχετικά με τον Ï„Ïέχοντα διακομιστή" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "οÏίζει τον πολλαπλασιαστή κλίμακας όλων των απεικονίσεων κειμένου" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(ΛειτουÏγία ανάπτυξης) δείχνει τις πεÏικοπές" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(ΛειτουÏγία ανάπτυξης) εκτυπώνει τα παγκόσμια ids ήχου στο παÏάθυÏο απασφαλμάτωσης" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "ΔΙΟΡΓΑÎΩΣΤΕ ΠΑΙΧÎΙΔΙ" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Βοηθήματα" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Όνομα διακομιστή:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Κωδικός:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Μέγιστος αÏιθμός παιχτών:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Μετάδοση:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "Τοπικό δίκτυο" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Επιλεγμένο" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Όλα" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "ΈναÏξη" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "ΠÏόοδος λήψης χάÏτη:" @@ -2842,195 +2988,195 @@ msgstr "%s του %s" msgid "Disconnect to cancel download" msgstr "Αποσυνδεθείτε για να ακυÏώσετε την λήψη" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "ΑποσÏνδεση: Μη έγκυÏο ψευδώνυμο" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "ΑποσÏνδεση από το διακομιστή" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "ΑποσÏνδεση: Ο σειÏιακός αÏιθμός έχει αποκλειστεί.\n" "Λόγος: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "ΑποσÏνδεση: Είστε αποκλεισμένοι.\n" "Λόγος: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "ΑποσÏνδεση: Ο λογαÏιασμός είναι αποκλεισμένος.\n" "Λόγος: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "ΑποσÏνδεση: Αναντιστοιχία έκδοσης" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "ΑποσÏνδεση: ΥπεÏχείλιση συνδέσεων. ΠαÏακαλώ πεÏιμένετε ένα λεπτό και στη συνέχεια επανασυνδεθείτε." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "ΑποσÏνδεση: Ο διακομιστής είναι από διαφοÏετικό τομέα (branch).\n" "ΠληÏοφοÏίες: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "ΑποσÏνδεση: Κακή έκδοση.\n" "ΠληÏοφοÏίες: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "ΑποσÏνδεση: Ο διακομιστής εκτελεί νεότεÏο ανάπτυγμα (build).\n" "ΠληÏοφοÏίες: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "ΑποσÏνδεση: Ο διακομιστής εκτελεί παλαιότεÏο ανάπτυγμα (build).\n" "ΠληÏοφοÏίες: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "ΑποσÏνδεση: Το ψευδώνυμο χÏησιμοποιείτε ήδη" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "ΑποσÏνδεση: Ο διακομιστής απέÏÏιψε την σÏνδεση: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "ΑποσÏνδεση: Η επαλήθευση του σειÏÎ¹Î±ÎºÎ¿Ï Î±ÏÎ¹Î¸Î¼Î¿Ï Î±Ï€Î­Ï„Ï…Ï‡Îµ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "ΑποσÏνδεση: Η σÏνδεση αποσυγχÏονίστηκε %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "ΑποσÏνδεση: Έχετε εκδιωχθεί από %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "ΑποσÏνδεση: Έχετε αποκλειστεί από %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "ΑποσÏνδεση: Ο διακομιστής έκλεισε ή κάνει επανεκκίνηση" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Διωχθήκατε από το παιχνίδι" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Αυτός ο διακομιστής χÏειάζεται μια μη Ï„Ïοποποιημένη έκδοση του gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "ΠαÏακαλώ αντικαταστήστε το gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Αυτός ο διακομιστής δεν επιτÏέπει Ï„Ïοποποιημένο D3D9.DLLs" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "ΑφαιÏέστε το D3D9.DLL από τον κατάλογο εγκατάστασης του GTA και επανεκκίνηστε το MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Αυτός ο διακομιστής δεν επιτÏέπει εικονικές μηχανές " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Αυτός ο διακομιστής απαιτεί ενεÏγοποιημένο singing οδηγό" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "ΠαÏακαλώ επανεκκίνηστε τον Η/Î¥" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Ο διακομιστής έχει εντοπίσει αγνοοÏμενα anti-cheat στοιχεία" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "ΠÏοσπαθήστε να επανεκκίνησετε το MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Ο διακομιστής απαιτεί μη Ï„Ïοποποίημενα gta3.img και gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "ΠαÏακαλώ αντικαταστήστε το gta3.img ή το gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Ο διακομιστής δεν επιτÏέπει το Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Εξασφαλίστε ότι κανένα άλλο Ï€ÏόγÏαμμα δεν Ï„Ïοποποιεί το MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Εναπομείνοντας χÏόνος: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d ημέÏα" msgstr[1] "%d ημέÏες" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d ÏŽÏα" msgstr[1] "%d ÏŽÏες" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d λεπτό" msgstr[1] "%d λεπτά" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3038,296 +3184,206 @@ msgstr[0] "%d δευτεÏόλεπτο" msgstr[1] "%d δευτεÏόλεπτα" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "ΑποσÏνδεση" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Σφάλμα λήψης: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Είσοδος στο παιχνίδι ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Δεν είστε συνδεδεμένος, χÏησιμοποιήστε την ΓÏήγοÏη ΣÏνδεση ή την εντολή 'σÏνδεση' για να συνδεθείτε σε ένα διακομιστή." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Δεν ήταν δυνατή η εκκίνηση του Ï„Î¿Ï€Î¹ÎºÎ¿Ï Î´Î¹Î±ÎºÎ¿Î¼Î¹ÏƒÏ„Î®. ΑνατÏέξτε στην κονσόλα για λεπτομέÏειες." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Τοπικός Διακομιστής" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Ξεκινώντας τοπικό διακομιστή ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Διωχθήκατε από το παιχνίδι ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "ΣÏνδεση με τοπικό διακομιστή..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Σφάλμα σÏνδεσης με τον διακομιστή." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Η σÏνδεση σας με τον τοπικό διακομιστή έχει λήξει. ΑνατÏέξτε στην κονσόλα για λεπτομέÏειες." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Η σÏνδεση με τον διακομιστή χάθηκε." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "ΑποσÏνδεση: ο διακομιστής είναι πλήÏης" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "ΑποσÏνδεση: καθοÏίστηκε μη έγκυÏος κωδικός Ï€Ïόσβασης" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "Η επαλήθευση του Ï€ÏόγÏαμμα-πελάτη του MTA απέτυχε!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "ΔΙΟΡΓΑÎΩΣΤΕ ΠΑΙΧÎΙΔΙ" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Βοηθήματα" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Όνομα διακομιστή:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Κωδικός:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Μέγιστος αÏιθμός παιχτών:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Μετάδοση:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "Τοπικό δίκτυο" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Επιλεγμένο" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Όλα" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "ΈναÏξη" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "ΠÏόβλημα με την οδηγό γÏαφικών" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Δεν μποÏεί να βÏεθεί έγκυÏη ανάλυση οθόνης" - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Είστε σίγουÏος ότι θέλετε να χÏησιμοποιήσετε αυτή την ανάλυση οθόνης;" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Σφάλμα λήψης: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3348,11 +3404,11 @@ msgstr "" msgid "Connection error" msgstr "Σφάλμα σÏνδεσης" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Το Multi Theft Auto δεν έχει εγκατασταθεί σωστά, εγκαταστήστε ξανά." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Το Ï€ÏόγÏαμμα πεÏιήγησής σας θα εμφανίσει τώÏα μια ιστοσελίδα με κάποιες πληÏοφοÏίες βοήθειας.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot b/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot index be3d2308b15..7ebffbb8cd6 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: MTA San Andreas 1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-27 23:26+0000\n" +"POT-Creation-Date: 2026-04-06 01:28+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,76 +18,348 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "" -"Trouble restarting MTA:SA\n" -"\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n" -"\n" -"\n" -"Try to launch MTA:SA again?" +#: Client/game_sa/CGameSA.cpp:259 Client/game_sa/CGameSA.cpp:270 +msgid "Failed initialization game_sa" +msgstr "" + +#: Client/game_sa/CGameSA.cpp:261 +msgid "Memory allocations failed" msgstr "" #. Show a message that the connection timed out and abort #. Show failed message and abort the attempt #. Show timeout message and disconnect #. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:848 -#: Client/loader/CInstallManager.cpp:563 Client/loader/CInstallManager.cpp:572 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/game_sa/CGameSA.cpp:265 Client/game_sa/CGameSA.cpp:276 +#: Client/loader/CInstallManager.cpp:1129 +#: Client/loader/CInstallManager.cpp:1138 Client/loader/MainFunctions.cpp:1182 +#: Client/loader/MainFunctions.cpp:1204 Client/loader/MainFunctions.cpp:1209 +#: Client/loader/MainFunctions.cpp:1617 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:273 Client/core/CConnectManager.cpp:331 +#: Client/core/CConnectManager.cpp:417 Client/core/CConnectManager.cpp:424 +#: Client/core/CConnectManager.cpp:434 Client/core/CSettings.cpp:3833 +#: Client/core/CSettings.cpp:5209 Client/core/CSettings.cpp:5237 +#: Client/core/CSettings.cpp:5995 Client/core/CGUI.cpp:94 +#: Client/core/CCore.cpp:1410 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1608 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1630 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1689 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1763 #: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:651 -#: Client/mods/deathmatch/logic/CClientGame.cpp:725 -#: Client/mods/deathmatch/logic/CClientGame.cpp:749 -#: Client/mods/deathmatch/logic/CClientGame.cpp:771 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1184 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1264 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1274 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1343 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1380 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1429 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1441 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 +#: Client/mods/deathmatch/logic/CClientGame.cpp:683 +#: Client/mods/deathmatch/logic/CClientGame.cpp:751 +#: Client/mods/deathmatch/logic/CClientGame.cpp:775 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1213 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1372 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1458 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1470 #: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:495 msgid "Error" msgstr "" -#: Client/loader/MainFunctions.cpp:266 +#: Client/game_sa/CGameSA.cpp:272 Client/loader/MainFunctions.cpp:197 +#: Client/loader/MainFunctions.cpp:1036 Client/loader/MainFunctions.cpp:1043 +#: Client/loader/MainFunctions.cpp:2008 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1715 +#: Client/core/ServerBrowser/CServerInfo.cpp:319 +msgid "Information" +msgstr "" + +#: Client/game_sa/CSettingsSA.cpp:833 +msgid "Can't find valid screen resolution." +msgstr "" + +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:909 +msgid "Are you sure you want to use this screen resolution?" +msgstr "" + +#: Client/game_sa/CSettingsSA.cpp:911 Client/loader/Dialogs.cpp:127 +msgid "MTA: San Andreas" +msgstr "" + +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2940 +msgid "Problem with graphics driver" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "" + +#: Client/loader/Install.cpp:272 +#, c-format msgid "" -"Another instance of MTA is already running.\n" +"The file '%s' is currently locked by %zu processes.\n" "\n" -"If this problem persists, please restart your computer" +"Do you want to terminate the following processes and continue updating?\n" +"\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:269 +#: Client/loader/Install.cpp:479 +#, c-format msgid "" -"Another instance of MTA is already running.\n" +"Your installation may be corrupt now.\n" "\n" -"Do you want to terminate it?" +"%zu out of %zu files could not be restored from the backup.\n" +"\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "" + +#: Client/loader/Install.cpp:873 Client/loader/Dialogs.cpp:1081 +msgid "Installing update..." +msgstr "" + +#: Client/loader/Install.cpp:965 Client/loader/Dialogs.cpp:1089 +msgid "Extracting files..." +msgstr "" + +#: Client/loader/CInstallManager.cpp:434 Client/loader/Utils.cpp:1177 +#, c-format +msgid "" +"MTA:SA needs Administrator access for the following task:\n" +"\n" +" '%s'\n" +"\n" +"Please confirm in the next window." +msgstr "" + +#: Client/loader/CInstallManager.cpp:449 +#, c-format +msgid "" +"MTA:SA could not complete the following task:\n" +"\n" +" '%s'\n" +msgstr "" + +#: Client/loader/CInstallManager.cpp:518 +msgid "" +"** The crash was caused by a graphics driver error **\n" +"\n" +"** Please update your graphics drivers **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:528 +msgid "" +"** Out of memory - this crash was caused by insufficient free or fragmented " +"memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:534 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1108 +msgid "Install updated MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1129 +msgid "" +"Could not update due to file conflicts. Please close other applications and " +"retry" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1138 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1213 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1219 +#: Client/loader/CInstallManager.cpp:1261 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1228 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1252 +#: Client/loader/CInstallManager.cpp:1331 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1338 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1386 +msgid "" +"MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1390 +msgid "" +"Please check your anti-virus for a false-positive detection, try to add an " +"exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1396 +msgid "Generate GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1411 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1418 +#: Client/loader/CInstallManager.cpp:1441 +msgid "Patch GTA:SA" msgstr "" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/CInstallManager.cpp:1434 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1615 Client/core/CCore.cpp:865 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1671 +msgid "Missing file:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1675 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1710 +msgid "Update install settings" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1865 +msgid "Update compatibility settings" +msgstr "" + +#: Client/loader/Utils.cpp:689 +msgid "" +"Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" + +#: Client/loader/Utils.cpp:690 Client/loader/Utils.cpp:706 +msgid "Searching for GTA: San Andreas" +msgstr "" + +#: Client/loader/Utils.cpp:704 +msgid "" +"Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" + +#: Client/loader/Utils.cpp:774 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "" + +#: Client/loader/Utils.cpp:1318 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "" + +#: Client/loader/Utils.cpp:1659 Client/loader/Dialogs.cpp:1094 +msgid "Copying files..." +msgstr "" + +#: Client/loader/Utils.cpp:1719 Client/loader/Dialogs.cpp:1099 +msgid "Copy finished early. Everything OK." +msgstr "" + +#: Client/loader/Utils.cpp:1725 Client/loader/Dialogs.cpp:1104 +msgid "Finishing..." +msgstr "" + +#: Client/loader/Utils.cpp:1727 Client/loader/Dialogs.cpp:1108 +msgid "Done!" +msgstr "" + +#: Client/loader/Utils.cpp:1767 +#, c-format +msgid "" +"New installation of %s detected.\n" +"\n" +"Do you want to copy your settings from %s ?" +msgstr "" + +#: Client/loader/Utils.cpp:1806 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1828 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "" + +#: Client/loader/Utils.cpp:1853 +msgid "GTA:SA had trouble loading a model." +msgstr "" + +#: Client/loader/Utils.cpp:1855 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "" + +#: Client/loader/Utils.cpp:1880 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "" + +#: Client/loader/Utils.cpp:1899 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1981 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "" + +#: Client/loader/Utils.cpp:2046 +msgid "Please terminate the following programs before continuing:" +msgstr "" + +#: Client/loader/MainFunctions.cpp:197 Client/loader/MainFunctions.cpp:2008 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/MainFunctions.cpp:379 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:403 +msgid "" +"File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:411 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:421 +msgid "" +"MTA:SA is not compatible with Windows 'Safe Mode'.\n" +"\n" +"Please restart your PC.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:602 msgid "" "Are you having problems running MTA:SA?.\n" "\n" "Do you want to revert to an earlier version?" msgstr "" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:630 msgid "" "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n" @@ -95,20 +367,20 @@ msgid "" "Do you want to reset GTA settings now?" msgstr "" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:645 msgid "" "GTA settings have been reset.\n" "\n" "Press OK to continue." msgstr "" -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:650 #, c-format msgid "File could not be deleted: '%s'" msgstr "" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:658 msgid "" "Are you having problems running MTA:SA?.\n" "\n" @@ -116,31 +388,31 @@ msgid "" msgstr "" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:695 msgid "" "Are you having problems running MTA:SA?.\n" "\n" "Do you want to change the following setting?" msgstr "" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:696 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1666 msgid "Fullscreen mode:" msgstr "" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:696 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2332 msgid "Borderless window" msgstr "" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:765 msgid "" "Are you having problems running MTA:SA?.\n" "\n" "Try disabling the following products for GTA and MTA:" msgstr "" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:800 msgid "" "WARNING\n" "\n" @@ -149,37 +421,54 @@ msgid "" "\n" msgstr "" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:803 #, c-format msgid "The detected file was: %s\n" msgstr "" -#: Client/loader/MainFunctions.cpp:604 +#: Client/loader/MainFunctions.cpp:1035 msgid "" "An instance of GTA: San Andreas is already running. It needs to be " "terminated before MTA:SA can be started. Do you want to do that now?" msgstr "" -#: Client/loader/MainFunctions.cpp:605 Client/loader/MainFunctions.cpp:612 -#: Client/loader/MainFunctions.cpp:1221 -#: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 -msgid "Information" -msgstr "" - -#: Client/loader/MainFunctions.cpp:611 +#: Client/loader/MainFunctions.cpp:1042 msgid "" "Unable to terminate GTA: San Andreas. If the problem persists, please " "restart your computer." msgstr "" -#: Client/loader/MainFunctions.cpp:634 +#: Client/loader/MainFunctions.cpp:1177 +msgid "" +"Trouble restarting MTA:SA\n" +"\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n" +"\n" +"\n" +"Try to launch MTA:SA again?" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1202 +msgid "" +"Another instance of MTA is already running.\n" +"\n" +"If this problem persists, please restart your computer" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1207 +msgid "" +"Another instance of MTA is already running.\n" +"\n" +"Do you want to terminate it?" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1244 msgid "" "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "" -#: Client/loader/MainFunctions.cpp:640 +#: Client/loader/MainFunctions.cpp:1249 msgid "" "The path to your installation of GTA: San Andreas contains unsupported " "(unicode) characters. Please move your Grand Theft Auto: San Andreas " @@ -187,206 +476,162 @@ msgid "" "characters and reinstall Multi Theft Auto: San Andreas." msgstr "" -#: Client/loader/MainFunctions.cpp:650 +#: Client/loader/MainFunctions.cpp:1262 msgid "" "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n" "\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." msgstr "" -#: Client/loader/MainFunctions.cpp:812 +#: Client/loader/MainFunctions.cpp:1450 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1579 msgid "" "Load failed. Please ensure that the latest data files have been installed " "correctly." msgstr "" -#: Client/loader/MainFunctions.cpp:821 +#: Client/loader/MainFunctions.cpp:1588 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "" -#: Client/loader/MainFunctions.cpp:828 +#: Client/loader/MainFunctions.cpp:1595 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "" -#: Client/loader/MainFunctions.cpp:838 +#: Client/loader/MainFunctions.cpp:1606 #, c-format msgid "" "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "" -#: Client/loader/MainFunctions.cpp:847 +#: Client/loader/MainFunctions.cpp:1616 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "" -#: Client/loader/MainFunctions.cpp:858 -msgid "" -"Main file is unsigned. Possible virus activity.\n" -"\n" -"See online help if MTA does not work correctly." -msgstr "" - -#: Client/loader/MainFunctions.cpp:884 +#: Client/loader/MainFunctions.cpp:1658 #, c-format -msgid "" -"Data file %s is missing. Possible virus activity.\n" -"\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Data file %s is missing. Possible virus activity." msgstr "" -#: Client/loader/MainFunctions.cpp:895 +#: Client/loader/MainFunctions.cpp:1665 #, c-format -msgid "" -"Data file %s is modified. Possible virus activity.\n" -"\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Data file %s is modified. Possible virus activity." msgstr "" -#: Client/loader/MainFunctions.cpp:909 +#: Client/loader/MainFunctions.cpp:1688 msgid "" -".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation " -"directory.\n" +".asi files are in the installation directory.\n" "\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "" - -#: Client/loader/MainFunctions.cpp:1011 -msgid "" -"File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "" - -#: Client/loader/MainFunctions.cpp:1020 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +"Remove these .asi files if you experience problems." msgstr "" -#: Client/loader/MainFunctions.cpp:1032 -msgid "" -"MTA:SA is not compatible with Windows 'Safe Mode'.\n" -"\n" -"Please restart your PC.\n" +#: Client/loader/MainFunctions.cpp:1855 +msgid "Invalid game paths detected." msgstr "" -#: Client/loader/MainFunctions.cpp:1125 +#: Client/loader/MainFunctions.cpp:1863 msgid "Fix configuration issue" msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1159 -msgid "Fix elevation required error" -msgstr "" - -#: Client/loader/MainFunctions.cpp:1166 -#, c-format -msgid "" -"Could not start Grand Theft Auto: San Andreas. Please try restarting, or if " -"the problem persists,contact MTA at www.multitheftauto.com. \n" -"\n" -"[%s]" -msgstr "" - -#: Client/loader/MainFunctions.cpp:1221 -msgid "" -"GTA: San Andreas may not have launched correctly. Do you want to terminate " -"it?" -msgstr "" - #. ///////////////////////////////////////////////////////////////////////// #. #. Dialog strings #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CSettings.cpp:2104 +#: Client/core/CSettings.cpp:2128 Client/core/CSettings.cpp:5643 +#: Client/core/CSettings.cpp:5717 Client/core/CSettings.cpp:5747 +#: Client/core/CSettings.cpp:5796 Client/core/CSettings.cpp:5858 +#: Client/core/CMainMenu.cpp:1245 Client/core/CQuestionBox.cpp:195 +#: Client/core/CVersionUpdater.cpp:1635 Client/core/CVersionUpdater.cpp:1653 +#: Client/core/CVersionUpdater.cpp:1922 Client/core/CVersionUpdater.cpp:1941 +#: Client/core/ServerBrowser/CServerInfo.cpp:563 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:65 Client/core/CSettings.cpp:2103 +#: Client/core/CSettings.cpp:2127 Client/core/CSettings.cpp:5642 +#: Client/core/CSettings.cpp:5716 Client/core/CSettings.cpp:5746 +#: Client/core/CSettings.cpp:5795 Client/core/CSettings.cpp:5857 +#: Client/core/CMainMenu.cpp:1244 Client/core/CQuestionBox.cpp:194 +#: Client/core/CVersionUpdater.cpp:1634 Client/core/CVersionUpdater.cpp:1652 +#: Client/core/CVersionUpdater.cpp:1921 Client/core/CVersionUpdater.cpp:1940 +#: Client/core/ServerBrowser/CServerInfo.cpp:563 msgid "No" msgstr "" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:66 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:6016 Client/core/CMainMenu.cpp:1265 +#: Client/core/CVersionUpdater.cpp:1670 Client/core/CVersionUpdater.cpp:1886 +#: Client/core/CVersionUpdater.cpp:1979 Client/core/CVersionUpdater.cpp:2001 +#: Client/core/CVersionUpdater.cpp:2019 Client/core/CVersionUpdater.cpp:2031 +#: Client/core/CVersionUpdater.cpp:2183 Client/core/CVersionUpdater.cpp:2192 +#: Client/core/CVersionUpdater.cpp:2201 Client/core/CVersionUpdater.cpp:2215 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:67 msgid "Quit" msgstr "" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:68 +#: Client/core/ServerBrowser/CServerBrowser.cpp:719 msgid "Help" msgstr "" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:69 Client/core/CSettings.cpp:562 +#: Client/core/CSettings.cpp:6015 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:84 msgid "MTA: San Andreas has encountered a problem" msgstr "" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:85 msgid "Crash information" msgstr "" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:86 msgid "" "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:87 msgid "Doing so will increase the chance of this crash being fixed." msgstr "" -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:88 msgid "Do you want to restart MTA: San Andreas ?" msgstr "" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:95 msgid "MTA: San Andreas - Warning" msgstr "" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:96 msgid "" "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:98 msgid "" "These files are not required and may interfere with the graphical features " "in this version of MTA:SA.\n" @@ -394,79 +639,75 @@ msgid "" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:100 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:101 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:102 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:103 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:104 msgid "Play MTA:SA" msgstr "" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:110 msgid "MTA: San Andreas - Confusing options" msgstr "" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:111 msgid "NVidia Optimus detected!" msgstr "" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:112 msgid "Try each option and see what works:" msgstr "" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:113 msgid "A - Standard NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:114 msgid "B - Alternate NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:115 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:116 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:117 msgid "If you get desperate, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:118 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:119 msgid "Force windowed mode" msgstr "" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:120 msgid "Don't show again" msgstr "" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:898 -msgid "MTA: San Andreas" -msgstr "" - -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:128 msgid "Warning: Could not detect anti-virus product" msgstr "" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:130 msgid "" "MTA could not detect an anti-virus on your PC.\n" "\n" @@ -475,1132 +716,986 @@ msgid "" "Press 'Help' for more information." msgstr "" -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:133 msgid "I have already installed an anti-virus" msgstr "" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:135 msgid "" "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "" -#: Client/loader/Dialogs.cpp:678 -msgid "Searching for Grand Theft Auto San Andreas" -msgstr "" - -#: Client/loader/Dialogs.cpp:681 -msgid "Please start Grand Theft Auto San Andreas" -msgstr "" - -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "" - -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "" - -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "" - -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "" - -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "" - -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "" - -#: Client/loader/CInstallManager.cpp:362 Client/loader/Utils.cpp:965 -#, c-format -msgid "" -"MTA:SA needs Administrator access for the following task:\n" -"\n" -" '%s'\n" -"\n" -"Please confirm in the next window." -msgstr "" - -#: Client/loader/CInstallManager.cpp:377 -#, c-format -msgid "" -"MTA:SA could not complete the following task:\n" -"\n" -" '%s'\n" -msgstr "" - -#: Client/loader/CInstallManager.cpp:428 -msgid "" -"** The crash was caused by a graphics driver error **\n" -"\n" -"** Please update your graphics drivers **" -msgstr "" - -#: Client/loader/CInstallManager.cpp:441 -msgid "" -"** Out of memory - this crash was caused by insufficient free or fragmented " -"memory. **" -msgstr "" - -#: Client/loader/CInstallManager.cpp:543 -msgid "Install updated MTA:SA files" -msgstr "" - -#: Client/loader/CInstallManager.cpp:563 -msgid "" -"Could not update due to file conflicts. Please close other applications and " -"retry" -msgstr "" - -#: Client/loader/CInstallManager.cpp:572 -#, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "" - -#: Client/loader/CInstallManager.cpp:624 -msgid "Create GTA:SA junctions" -msgstr "" - -#: Client/loader/CInstallManager.cpp:668 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "" - -#: Client/loader/CInstallManager.cpp:674 Client/loader/CInstallManager.cpp:714 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "" - -#: Client/loader/CInstallManager.cpp:683 -msgid "Copy MTA:SA files" -msgstr "" - -#: Client/loader/CInstallManager.cpp:706 Client/loader/CInstallManager.cpp:784 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "" - -#: Client/loader/CInstallManager.cpp:791 -msgid "Patch GTA:SA dependency" -msgstr "" - -#: Client/loader/CInstallManager.cpp:839 -msgid "" -"MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "" - -#: Client/loader/CInstallManager.cpp:843 -msgid "" -"Please check your anti-virus for a false-positive detection, try to add an " -"exception for the GTA:SA executable and restart MTA:SA." -msgstr "" - -#: Client/loader/CInstallManager.cpp:849 -msgid "Generate GTA:SA" -msgstr "" - -#: Client/loader/CInstallManager.cpp:864 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "" - -#: Client/loader/CInstallManager.cpp:871 Client/loader/CInstallManager.cpp:894 -msgid "Patch GTA:SA" -msgstr "" - -#: Client/loader/CInstallManager.cpp:887 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "" - -#: Client/loader/CInstallManager.cpp:1068 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "" - -#: Client/loader/CInstallManager.cpp:1124 -msgid "Missing file:" -msgstr "" - -#: Client/loader/CInstallManager.cpp:1128 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "" - -#: Client/loader/CInstallManager.cpp:1163 -msgid "Update install settings" -msgstr "" - -#: Client/loader/CInstallManager.cpp:1316 -msgid "Update compatibility settings" -msgstr "" - -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "" - -#: Client/loader/Install.cpp:272 -#, c-format -msgid "" -"The file '%s' is currently locked by %zu processes.\n" -"\n" -"Do you want to terminate the following processes and continue updating?\n" -"\n" -"%s" -msgstr "" - -#: Client/loader/Install.cpp:479 -#, c-format +#: Client/loader/Dialogs.cpp:716 msgid "" -"Your installation may be corrupt now.\n" +"The crash you experienced is due to memory abuse by servers.\n" "\n" -"%zu out of %zu files could not be restored from the backup.\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to " +"3.6GB and some highly unoptimized servers with a lot of mods (or just a few " +"poorly written scripts) can make this happen, as well as lag your game.\n" "\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "" - -#: Client/loader/Utils.cpp:535 -msgid "" -"Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +"Contact the server owner or MTA support in the MTA official discord (https://" +"discord.gg/mtasa) for more information." msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" +#: Client/loader/Dialogs.cpp:722 +msgid "MTA: San Andreas - Out of Memory Information" msgstr "" -#: Client/loader/Utils.cpp:548 -msgid "" -"Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/loader/Dialogs.cpp:1070 +msgid "Searching for Grand Theft Auto San Andreas" msgstr "" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +#: Client/loader/Dialogs.cpp:1073 +msgid "Please start Grand Theft Auto San Andreas" msgstr "" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" msgstr "" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "" -"New installation of %s detected.\n" -"\n" -"Do you want to copy your settings from %s ?" +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" msgstr "" -#: Client/loader/Utils.cpp:1538 +#: Client/core/CConnectManager.cpp:132 #, c-format -msgid "GTA:SA had trouble opening the file '%s'" +msgid "Connecting to %s at port %u failed!" msgstr "" -#: Client/loader/Utils.cpp:1560 +#. Display the status box +#: Client/core/CConnectManager.cpp:153 #, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "" - -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "" - -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "" - -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgid "Connecting to %s:%u ..." msgstr "" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CConnectManager.cpp:155 #, c-format -msgid "GTA:SA found errors in the file '%s'" +msgid "Reconnecting to %s:%u ..." msgstr "" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:699 +msgid "CONNECTING" msgstr "" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" +#: Client/core/CConnectManager.cpp:273 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1372 +msgid "Connection timed out" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" +#: Client/core/CConnectManager.cpp:287 Client/core/CConnectManager.cpp:291 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1420 +msgid "Disconnected: unknown protocol error" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "" -"The server requests the following websites in order to load them (later):" +#: Client/core/CConnectManager.cpp:295 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1424 +msgid "Disconnected: disconnected remotely" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +#: Client/core/CConnectManager.cpp:299 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1428 +msgid "Disconnected: connection lost remotely" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" +#: Client/core/CConnectManager.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1432 +msgid "Disconnected: you are banned from this server" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" +#: Client/core/CConnectManager.cpp:310 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1440 +msgid "Disconnected: disconnected from the server" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" +#: Client/core/CConnectManager.cpp:314 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +msgid "Disconnected: connection to the server was lost" msgstr "" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:543 -msgid "Main menu" +#: Client/core/CConnectManager.cpp:321 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1452 +msgid "Disconnected: connection was refused" msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "" -"You are using a feature-branch build! This is a test build only which cannot " -"be used to connect to public servers!" +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:416 +#, c-format +msgid "No such mod installed (%s)" msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "" -"MTA will not receive updates on XP/Vista after July 2019.\n" -"\n" -"Upgrade Windows to play on the latest servers." +#: Client/core/CConnectManager.cpp:424 +msgid "Bad server response (2)" msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "" -"This will disconnect you from the current server.\n" -"\n" -"Are you sure you want to disconnect?" +#: Client/core/CConnectManager.cpp:434 +msgid "Bad server response (1)" msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" msgstr "" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" msgstr "" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" msgstr "" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:498 msgid "SETTINGS" msgstr "" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:545 msgid "Multiplayer" msgstr "" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:546 msgid "Video" msgstr "" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:547 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:548 msgid "Audio" msgstr "" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:549 msgid "Binds" msgstr "" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:550 msgid "Controls" msgstr "" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:551 msgid "Interface" msgstr "" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:552 msgid "Web Browser" msgstr "" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:553 msgid "Advanced" msgstr "" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:578 Client/core/CSettings.cpp:787 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 +#: Client/core/CSettings.cpp:1510 msgid "Load defaults" msgstr "" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:595 Client/core/CSettings.cpp:619 msgid "Mouse sensitivity:" msgstr "" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:595 Client/core/CSettings.cpp:640 msgid "Vertical aim sensitivity:" msgstr "" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:598 msgid "Mouse options" msgstr "" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:605 msgid "Invert mouse vertically" msgstr "" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:609 msgid "Steer with mouse" msgstr "" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:613 msgid "Fly with mouse" msgstr "" +#: Client/core/CSettings.cpp:660 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:666 msgid "Joypad options" msgstr "" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:679 msgid "Standard controls (Mouse + Keyboard)" msgstr "" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:686 msgid "Classic controls (Joypad)" msgstr "" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:723 msgid "Dead Zone" msgstr "" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:728 msgid "Saturation" msgstr "" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:734 msgid "Use the 'Binds' tab for joypad buttons." msgstr "" -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:773 msgid "Left Stick" msgstr "" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:779 msgid "Right Stick" msgstr "" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:794 msgid "DESCRIPTION" msgstr "" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:795 msgid "KEY" msgstr "" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:797 msgid "ALT. KEY" msgstr "" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:802 Client/core/CSettings.cpp:805 msgid "Nick:" msgstr "" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:827 msgid "Save server passwords" msgstr "" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:832 msgid "Auto-refresh server browser" msgstr "" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:837 msgid "Allow screen upload" msgstr "" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:842 msgid "Allow external sounds" msgstr "" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:847 msgid "Always show download window" msgstr "" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:853 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:858 msgid "Allow GTA:SA ingame status on Steam" msgstr "" -#. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:865 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1538 +#: Client/core/CSettings.cpp:2910 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:3995 msgid "Radio" msgstr "" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:3997 msgid "Random" msgstr "" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:3999 msgid "Sequential" msgstr "" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1430 Client/core/CSettings.cpp:1452 msgid "Brightness:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2330 msgid "Standard" msgstr "" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2334 msgid "Borderless keep res" msgstr "" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2234 msgid "Low" msgstr "" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2236 msgid "Medium" msgstr "" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1749 +#: Client/core/CSettings.cpp:2238 Client/core/CSettings.cpp:4053 msgid "High" msgstr "" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2240 msgid "Very high" msgstr "" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1680 +#: Client/core/CSettings.cpp:1734 Client/core/CSettings.cpp:1884 +#: Client/core/CSettings.cpp:2244 Client/core/CSettings.cpp:4060 +#: Client/core/CSettings.cpp:4092 Client/core/CSettings.cpp:4138 +#: Client/core/CSettings.cpp:5388 msgid "Off" msgstr "" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2246 msgid "1x" msgstr "" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2248 msgid "2x" msgstr "" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2250 msgid "3x" msgstr "" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1682 +#: Client/core/CSettings.cpp:2256 Client/core/CSettings.cpp:4062 msgid "Auto" msgstr "" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2258 msgid "4:3" msgstr "" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2260 msgid "16:10" msgstr "" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2262 msgid "16:9" msgstr "" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1430 Client/core/CSettings.cpp:1436 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1430 Client/core/CSettings.cpp:1468 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1430 Client/core/CSettings.cpp:1484 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1500 +msgid "Apply adjustments in windowed/borderless mode" +msgstr "" + +#: Client/core/CSettings.cpp:1506 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1544 msgid "Enable remote websites" msgstr "" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1549 msgid "Enable Javascript on remote websites" msgstr "" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1554 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1558 msgid "Custom blacklist" msgstr "" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1569 Client/core/CSettings.cpp:1617 msgid "Enter a domain e.g. google.com" msgstr "" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1577 msgid "Block" msgstr "" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1592 Client/core/CSettings.cpp:1638 msgid "Domain" msgstr "" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1594 Client/core/CSettings.cpp:1640 msgid "Remove domain" msgstr "" +#: Client/core/CSettings.cpp:1599 Client/core/CSettings.cpp:1645 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1606 msgid "Custom whitelist" msgstr "" +#: Client/core/CSettings.cpp:1625 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1659 msgid "Misc" msgstr "" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1665 Client/core/CSettings.cpp:1673 +#: Client/core/CSettings.cpp:6034 msgid "Fast CJ clothes loading:" msgstr "" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1665 Client/core/CSettings.cpp:1687 +#: Client/core/CSettings.cpp:6036 msgid "Browser speed:" msgstr "" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1665 Client/core/CSettings.cpp:1701 +#: Client/core/CSettings.cpp:6038 msgid "Single connection:" msgstr "" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1665 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:6040 msgid "Packet tag:" msgstr "" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1666 Client/core/CSettings.cpp:1727 +#: Client/core/CSettings.cpp:6042 msgid "Progress animation:" msgstr "" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1666 Client/core/CSettings.cpp:1740 +#: Client/core/CSettings.cpp:6032 msgid "Process priority:" msgstr "" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1666 Client/core/CSettings.cpp:1754 +#: Client/core/CSettings.cpp:6044 msgid "Debug setting:" msgstr "" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1667 Client/core/CSettings.cpp:1777 +#: Client/core/CSettings.cpp:6046 msgid "Streaming memory:" msgstr "" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1667 Client/core/CSettings.cpp:1898 msgid "Update build type:" msgstr "" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1667 Client/core/CSettings.cpp:1877 msgid "Install important updates:" msgstr "" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1681 Client/core/CSettings.cpp:1709 +#: Client/core/CSettings.cpp:1722 Client/core/CSettings.cpp:4064 +#: Client/core/CSettings.cpp:4080 Client/core/CSettings.cpp:4087 msgid "On" msgstr "" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1694 Client/core/CSettings.cpp:4069 msgid "Very slow" msgstr "" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1695 Client/core/CSettings.cpp:1708 +#: Client/core/CSettings.cpp:1721 Client/core/CSettings.cpp:1735 +#: Client/core/CSettings.cpp:1761 Client/core/CSettings.cpp:1773 +#: Client/core/CSettings.cpp:1885 Client/core/CSettings.cpp:1905 +#: Client/core/CSettings.cpp:4071 Client/core/CSettings.cpp:4078 +#: Client/core/CSettings.cpp:4085 Client/core/CSettings.cpp:4094 +#: Client/core/CSettings.cpp:4131 msgid "Default" msgstr "" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1696 Client/core/CSettings.cpp:4073 msgid "Fast" msgstr "" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1747 Client/core/CSettings.cpp:4049 msgid "Normal" msgstr "" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1748 Client/core/CSettings.cpp:4051 msgid "Above normal" msgstr "" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1784 msgid "Min" msgstr "" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1809 msgid "Max" msgstr "" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1817 msgid "Windows 8 compatibility:" msgstr "" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1821 msgid "16-bit color" msgstr "" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1826 msgid "Mouse fix" msgstr "" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1844 msgid "Client resource files:" msgstr "" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1848 msgid "Show in Explorer" msgstr "" -#. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1864 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1870 Client/core/CSettings.cpp:1873 msgid "Auto updater" msgstr "" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1911 msgid "Check for update now" msgstr "" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2097 msgid "Some settings will be changed when you next start MTA" msgstr "" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2098 msgid "" "\n" "\n" "Do you want to restart now?" msgstr "" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2101 msgid "RESTART REQUIRED" msgstr "" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2121 msgid "Some settings will be changed when you disconnect the current server" msgstr "" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2122 msgid "" "\n" "\n" "Do you want to disconnect now?" msgstr "" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2125 msgid "DISCONNECT REQUIRED" msgstr "" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2569 msgid "Joypad not detected - Check connections and restart game" msgstr "" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2822 msgid "Binding axis" msgstr "" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2822 msgid "Move an axis to bind, or escape to clear" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2901 msgid "Language:" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2901 msgid "Skin:" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2901 msgid "Presets:" msgstr "" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2950 msgid "Chat" msgstr "" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2967 msgid "Load" msgstr "" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2979 msgid "Colors" msgstr "" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2980 msgid "Layout" msgstr "" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2981 Client/core/CSettings.cpp:3227 msgid "Options" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2987 msgid "Chat Background" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2987 msgid "Chat Text" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2987 msgid "Input Background" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2987 msgid "Input Text" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3010 msgid "Lines:" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3010 msgid "Scale:" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3010 msgid "Width:" msgstr "" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3013 msgid "Size" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3062 msgid "after" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3062 msgid "for" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3062 msgid "sec" msgstr "" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3065 msgid "Fading" msgstr "" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3071 msgid "Fade out old lines" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3111 msgid "Horizontal:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3111 msgid "Vertical:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3111 msgid "Text-Align:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3111 msgid "X-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3112 msgid "Y-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3118 msgid "Position" msgstr "" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3132 Client/core/CSettings.cpp:3160 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3133 Client/core/CSettings.cpp:3147 msgid "Center" msgstr "" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3134 Client/core/CSettings.cpp:3161 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3146 msgid "Top" msgstr "" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3148 msgid "Bottom" msgstr "" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3196 msgid "Font" msgstr "" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3233 msgid "Hide background when not typing" msgstr "" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3238 msgid "Nickname completion using the \"Tab\" key" msgstr "" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3243 msgid "Allow server to flash the window" msgstr "" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3248 msgid "Allow tray balloon notifications" msgstr "" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3253 msgid "Chat text black/white outline" msgstr "" @@ -1608,91 +1703,96 @@ msgstr "" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3502 Client/core/CSettings.cpp:3509 msgid "Press a key to bind, or escape to clear" msgstr "" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3503 msgid "Binding a primary key" msgstr "" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3510 msgid "Binding a secondary key" msgstr "" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3586 msgid "GTA GAME CONTROLS" msgstr "" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3588 msgid "MULTIPLAYER CONTROLS" msgstr "" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3833 Client/core/CSettings.cpp:5995 msgid "Your nickname contains invalid characters!" msgstr "" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1099 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4435 Client/core/CMainMenu.cpp:311 +#: Client/core/CCore.cpp:728 Client/mods/deathmatch/logic/CClientGame.cpp:557 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4439 Client/core/CCore.cpp:728 +#: Client/mods/deathmatch/logic/CResource.cpp:385 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1129 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4792 msgid "Red:" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4792 msgid "Green:" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4792 msgid "Blue:" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4792 msgid "Transparency:" msgstr "" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4795 msgid "Color" msgstr "" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4901 msgid "Preview" msgstr "" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5209 msgid "Please disconnect before changing language" msgstr "" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5237 msgid "Please disconnect before changing skin" msgstr "" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5636 msgid "" "Volmetric shadows can cause some systems to slow down.\n" "\n" "Are you sure you want to enable them?" msgstr "" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5640 msgid "PERFORMANCE WARNING" msgstr "" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5660 msgid "" "Screen upload is required by some servers for anti-cheat purposes.\n" "\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5662 msgid "SCREEN UPLOAD INFORMATION" msgstr "" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5677 msgid "" "Some scripts may play sounds, such as radio, from the internet.\n" "\n" @@ -1700,23 +1800,23 @@ msgid "" "bandwidth consumption.\n" msgstr "" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5680 msgid "EXTERNAL SOUNDS" msgstr "" -#: Client/core/CSettings.cpp:4690 +#: Client/core/CSettings.cpp:5709 msgid "" -"It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n" +"Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n" "\n" -"This includes yours unique ID identifier." +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5714 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5738 msgid "" "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n" @@ -1726,11 +1826,11 @@ msgid "" "Are you sure you want to use them?" msgstr "" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 +#: Client/core/CSettings.cpp:5744 Client/core/CVersionUpdater.cpp:2144 msgid "CUSTOMIZED GTA:SA FILES" msgstr "" -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5787 msgid "" "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" @@ -1739,11 +1839,11 @@ msgid "" "Are you sure you want to enable this option?" msgstr "" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5793 Client/core/CSettings.cpp:5848 msgid "EXPERIMENTAL FEATURE" msgstr "" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5850 msgid "" "Disabling this option is not recommended unless you are experiencing " "performance issues.\n" @@ -1751,442 +1851,306 @@ msgid "" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6013 msgid "Please enter a nickname" msgstr "" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6014 msgid "" "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6032 msgid "Very experimental feature." msgstr "" -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6034 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6036 msgid "Older routers may require a slower scan speed." msgstr "" -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6038 msgid "Switch on to use only one connection when downloading." msgstr "" -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6040 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "" -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6042 msgid "Spinning circle animation at the bottom of the screen" msgstr "" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6044 msgid "Select default always. (This setting is not saved)" msgstr "" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6046 msgid "Maximum is usually best" msgstr "" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6048 Client/core/CSettings.cpp:6050 msgid "Auto updater:" msgstr "" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6048 msgid "Select default unless you like filling out bug reports." msgstr "" -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6050 msgid "Select default to automatically install important updates." msgstr "" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6052 msgid "16-bit color:" msgstr "" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6052 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6054 msgid "Mouse fix:" msgstr "" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6054 msgid "Mouse movement fix - May need PC restart" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6056 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6056 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "" -"An updated version of MTA:SA %s is required to join the selected server.\n" -"\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "" -"It is not possible to connect at this time.\n" -"\n" -"Please try later." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1857 +#: Client/core/CMainMenu.cpp:340 msgid "" -"To join this server, you must update MTA.\n" -"\n" -" Do you want to update now ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" +"You are using a feature-branch build! This is a test build only which cannot " +"be used to connect to public servers!" msgstr "" -#: Client/core/CVersionUpdater.cpp:1876 +#: Client/core/CMainMenu.cpp:359 msgid "" -"Server says an update is recommended, but not essential.\n" +"MTA will not receive updates on XP/Vista after July 2019.\n" "\n" -" Do you want to update now ?" +"Upgrade Windows to play on the latest servers." msgstr "" -#: Client/core/CVersionUpdater.cpp:1915 +#: Client/core/CMainMenu.cpp:1238 msgid "" -"An update is currently not available.\n" +"This will disconnect you from the current server.\n" "\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." +"Are you sure you want to disconnect?" msgstr "" -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" +#: Client/core/CMainMenu.cpp:1242 +msgid "DISCONNECT WARNING" msgstr "" -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" +#: Client/core/CMainMenu.cpp:1263 +msgid "INFORMATION" msgstr "" -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1633 +msgid "Do you want to see some on-line help about this problem ?" msgstr "" -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" +#: Client/core/CJoystickManager.cpp:1584 +msgid "Accelerate Axis" msgstr "" -#: Client/core/CVersionUpdater.cpp:2097 -msgid "" -"Some MTA:SA data files are missing.\n" -"\n" -"\n" -"Please reinstall MTA:SA" +#: Client/core/CJoystickManager.cpp:1586 +msgid "Brake Axis" msgstr "" -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " msgstr "" -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format +#. Even the default skin doesn't work, so give up +#: Client/core/CGUI.cpp:93 msgid "" -"\n" -"\n" -"Waiting for response - %-3d" -msgstr "" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." +"The skin you selected could not be loaded, and the default skin also could " +"not be loaded, please reinstall MTA." msgstr "" -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." +#: Client/core/CKeyBinds.cpp:186 +msgid "Fire" msgstr "" -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:667 -msgid "CONNECTING" +#: Client/core/CKeyBinds.cpp:187 +msgid "Next weapon" msgstr "" -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1343 -msgid "Connection timed out" +#: Client/core/CKeyBinds.cpp:188 +msgid "Previous weapon" msgstr "" -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1391 -msgid "Disconnected: unknown protocol error" +#: Client/core/CKeyBinds.cpp:189 +msgid "Forwards" msgstr "" -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 -msgid "Disconnected: disconnected remotely" +#: Client/core/CKeyBinds.cpp:190 +msgid "Backwards" msgstr "" -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1399 -msgid "Disconnected: connection lost remotely" +#: Client/core/CKeyBinds.cpp:193 +msgid "Zoom in" msgstr "" -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1403 -msgid "Disconnected: you are banned from this server" +#: Client/core/CKeyBinds.cpp:194 +msgid "Zoom out" msgstr "" -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1411 -msgid "Disconnected: disconnected from the server" +#: Client/core/CKeyBinds.cpp:195 +msgid "Enter/Exit" msgstr "" -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1415 -msgid "Disconnected: connection to the server was lost" +#: Client/core/CKeyBinds.cpp:196 +msgid "Change camera" msgstr "" -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1423 -msgid "Disconnected: connection was refused" +#. 10 +#: Client/core/CKeyBinds.cpp:197 +msgid "Jump" msgstr "" -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" +#: Client/core/CKeyBinds.cpp:198 +msgid "Sprint" msgstr "" -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" +#: Client/core/CKeyBinds.cpp:199 +msgid "Look behind" msgstr "" -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" +#: Client/core/CKeyBinds.cpp:200 +msgid "Crouch" msgstr "" -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" +#: Client/core/CKeyBinds.cpp:201 +msgid "Action" msgstr "" -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" +#: Client/core/CKeyBinds.cpp:202 +msgid "Walk" msgstr "" -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" +#: Client/core/CKeyBinds.cpp:203 +msgid "Vehicle fire" msgstr "" -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 -msgid "Fatal error" +#: Client/core/CKeyBinds.cpp:204 +msgid "Vehicle secondary fire" msgstr "" -#: Client/core/CCore.cpp:934 -msgid "TO FIX, REMOVE THIS FILE:" +#: Client/core/CKeyBinds.cpp:205 +msgid "Vehicle left" msgstr "" -#: Client/core/CCore.cpp:966 -#, c-format -msgid "%s module is incorrect!" +#: Client/core/CKeyBinds.cpp:206 +msgid "Vehicle right" msgstr "" -#: Client/core/CCore.cpp:1272 -msgid "Error executing URL" +#. 20 +#: Client/core/CKeyBinds.cpp:207 +msgid "Steer forwards/down" msgstr "" -#. m_pCommands->Add ( "e", CCommandFuncs::Editor ); -#. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 -msgid "this help screen" +#: Client/core/CKeyBinds.cpp:208 +msgid "Steer backwards/up" msgstr "" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 -msgid "exits the application" +#: Client/core/CKeyBinds.cpp:209 +msgid "Accelerate" msgstr "" -#: Client/core/CCore.cpp:1370 -msgid "shows the version" +#: Client/core/CKeyBinds.cpp:210 +msgid "Brake/Reverse" msgstr "" -#: Client/core/CCore.cpp:1371 -msgid "shows the time" +#: Client/core/CKeyBinds.cpp:211 +msgid "Radio next" msgstr "" -#: Client/core/CCore.cpp:1372 -msgid "shows the hud" +#: Client/core/CKeyBinds.cpp:212 +msgid "Radio previous" msgstr "" -#: Client/core/CCore.cpp:1373 -msgid "shows all the binds" +#: Client/core/CKeyBinds.cpp:213 +msgid "Radio user track skip" msgstr "" -#: Client/core/CCore.cpp:1374 -msgid "shows your serial" +#: Client/core/CKeyBinds.cpp:214 +msgid "Horn" msgstr "" -#: Client/core/CCore.cpp:1383 -msgid "connects to a server (host port nick pass)" +#: Client/core/CKeyBinds.cpp:215 +msgid "Sub-mission" msgstr "" -#: Client/core/CCore.cpp:1384 -msgid "connects to a previous server" +#: Client/core/CKeyBinds.cpp:216 +msgid "Handbrake" msgstr "" -#: Client/core/CCore.cpp:1385 -msgid "binds a key (key control)" +#. 30 +#: Client/core/CKeyBinds.cpp:217 +msgid "Vehicle look left" msgstr "" -#: Client/core/CCore.cpp:1386 -msgid "unbinds a key (key)" +#: Client/core/CKeyBinds.cpp:218 +msgid "Vehicle look right" msgstr "" -#: Client/core/CCore.cpp:1387 -msgid "copies the default gta controls" +#: Client/core/CKeyBinds.cpp:219 +msgid "Vehicle look behind" msgstr "" -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" +#: Client/core/CKeyBinds.cpp:220 +msgid "Vehicle mouse look" msgstr "" -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" +#: Client/core/CKeyBinds.cpp:221 +msgid "Special control left" msgstr "" -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" +#: Client/core/CKeyBinds.cpp:222 +msgid "Special control right" msgstr "" -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" +#: Client/core/CKeyBinds.cpp:223 +msgid "Special control down" msgstr "" -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" +#: Client/core/CKeyBinds.cpp:224 +msgid "Special control up" msgstr "" -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" +#: Client/core/CKeyBinds.cpp:225 +msgid "Aim weapon" msgstr "" -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" +#: Client/core/CKeyBinds.cpp:226 +msgid "Conversation yes" msgstr "" -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" +#. 40 +#: Client/core/CKeyBinds.cpp:227 +msgid "Conversation no" msgstr "" -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" +#: Client/core/CKeyBinds.cpp:228 +msgid "Group control forwards" msgstr "" -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" +#: Client/core/CKeyBinds.cpp:229 +msgid "Group control backwards" msgstr "" #: Client/core/CCommandFuncs.cpp:24 @@ -2232,265 +2196,335 @@ msgstr "" msgid "reconnect: Bad port number" msgstr "" -#: Client/core/CCommandFuncs.cpp:321 +#: Client/core/CCommandFuncs.cpp:325 #, c-format msgid "reconnect: Reconnecting to %s:%u..." msgstr "" -#: Client/core/CCommandFuncs.cpp:325 +#: Client/core/CCommandFuncs.cpp:329 #, c-format msgid "reconnect: could not connect to %s:%u!" msgstr "" -#: Client/core/CCommandFuncs.cpp:359 +#: Client/core/CCommandFuncs.cpp:363 msgid "Bound all controls from GTA" msgstr "" -#: Client/core/CCommandFuncs.cpp:373 +#: Client/core/CCommandFuncs.cpp:377 msgid "Saved configuration file" msgstr "" #. Print it -#: Client/core/CCommandFuncs.cpp:452 +#: Client/core/CCommandFuncs.cpp:456 #, c-format msgid "* Your serial is: %s" msgstr "" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" +#: Client/core/CCore.cpp:867 Shared/mods/deathmatch/logic/Utils.cpp:129 +msgid "Fatal error" msgstr "" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" +#: Client/core/CCore.cpp:988 +msgid "TO FIX, REMOVE THIS FILE:" msgstr "" -#: Client/core/CCredits.cpp:34 -msgid "Programming" +#: Client/core/CCore.cpp:1020 +#, c-format +msgid "%s module is incorrect!" msgstr "" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" +#: Client/core/CCore.cpp:1410 +msgid "Error executing URL" msgstr "" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" +#. m_pCommands->Add ( "e", CCommandFuncs::Editor ); +#. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); +#: Client/core/CCore.cpp:1505 +msgid "this help screen" msgstr "" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" +#: Client/core/CCore.cpp:1506 Client/core/CCore.cpp:1507 +msgid "exits the application" msgstr "" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" +#: Client/core/CCore.cpp:1508 +msgid "shows the version" msgstr "" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" +#: Client/core/CCore.cpp:1509 +msgid "shows the time" msgstr "" -#: Client/core/CCredits.cpp:265 -msgid "" -"This software and project makes use of the following libraries and software:" +#: Client/core/CCore.cpp:1510 +msgid "shows the hud" msgstr "" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" +#: Client/core/CCore.cpp:1511 +msgid "shows all the binds" msgstr "" -#: Client/core/CKeyBinds.cpp:186 -msgid "Fire" +#: Client/core/CCore.cpp:1512 +msgid "shows your serial" msgstr "" -#: Client/core/CKeyBinds.cpp:187 -msgid "Next weapon" +#: Client/core/CCore.cpp:1521 +msgid "connects to a server (host port nick pass)" msgstr "" -#: Client/core/CKeyBinds.cpp:188 -msgid "Previous weapon" +#: Client/core/CCore.cpp:1522 +msgid "connects to a previous server" msgstr "" -#: Client/core/CKeyBinds.cpp:189 -msgid "Forwards" +#: Client/core/CCore.cpp:1523 +msgid "binds a key (key control)" msgstr "" -#: Client/core/CKeyBinds.cpp:190 -msgid "Backwards" +#: Client/core/CCore.cpp:1524 +msgid "unbinds a key (key)" msgstr "" -#: Client/core/CKeyBinds.cpp:193 -msgid "Zoom in" +#: Client/core/CCore.cpp:1525 +msgid "copies the default gta controls" msgstr "" -#: Client/core/CKeyBinds.cpp:194 -msgid "Zoom out" +#: Client/core/CCore.cpp:1526 +msgid "outputs a screenshot" msgstr "" -#: Client/core/CKeyBinds.cpp:195 -msgid "Enter/Exit" +#: Client/core/CCore.cpp:1527 +msgid "immediately saves the config" msgstr "" -#: Client/core/CKeyBinds.cpp:196 -msgid "Change camera" +#: Client/core/CCore.cpp:1529 +msgid "clears the debug view" msgstr "" -#. 10 -#: Client/core/CKeyBinds.cpp:197 -msgid "Jump" +#: Client/core/CCore.cpp:1530 +msgid "scrolls the chatbox upwards" msgstr "" -#: Client/core/CKeyBinds.cpp:198 -msgid "Sprint" +#: Client/core/CCore.cpp:1531 +msgid "scrolls the chatbox downwards" msgstr "" -#: Client/core/CKeyBinds.cpp:199 -msgid "Look behind" +#: Client/core/CCore.cpp:1532 +msgid "scrolls the debug view upwards" msgstr "" -#: Client/core/CKeyBinds.cpp:200 -msgid "Crouch" +#: Client/core/CCore.cpp:1533 +msgid "scrolls the debug view downwards" msgstr "" -#: Client/core/CKeyBinds.cpp:201 -msgid "Action" +#: Client/core/CCore.cpp:1536 +msgid "shows the memory statistics" msgstr "" -#: Client/core/CKeyBinds.cpp:202 -msgid "Walk" +#: Client/core/CCore.cpp:1537 +msgid "shows the frame timing graph" msgstr "" -#: Client/core/CKeyBinds.cpp:203 -msgid "Vehicle fire" +#: Client/core/CCore.cpp:1541 +msgid "for developers: reload news" msgstr "" -#: Client/core/CKeyBinds.cpp:204 -msgid "Vehicle secondary fire" +#: Client/core/CCredits.cpp:34 +msgid "Programming" msgstr "" -#: Client/core/CKeyBinds.cpp:205 -msgid "Vehicle left" +#: Client/core/CCredits.cpp:67 +msgid "Contributors" msgstr "" -#: Client/core/CKeyBinds.cpp:206 -msgid "Vehicle right" +#: Client/core/CCredits.cpp:86 +msgid "Game Design / Scripting" msgstr "" -#. 20 -#: Client/core/CKeyBinds.cpp:207 -msgid "Steer forwards/down" +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" msgstr "" -#: Client/core/CKeyBinds.cpp:208 -msgid "Steer backwards/up" +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" msgstr "" -#: Client/core/CKeyBinds.cpp:209 -msgid "Accelerate" +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" msgstr "" -#: Client/core/CKeyBinds.cpp:210 -msgid "Brake/Reverse" +#: Client/core/CCredits.cpp:265 +msgid "" +"This software and project makes use of the following libraries and software:" msgstr "" -#: Client/core/CKeyBinds.cpp:211 -msgid "Radio next" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" msgstr "" -#: Client/core/CKeyBinds.cpp:212 -msgid "Radio previous" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" msgstr "" -#: Client/core/CKeyBinds.cpp:213 -msgid "Radio user track skip" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" msgstr "" -#: Client/core/CKeyBinds.cpp:214 -msgid "Horn" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" msgstr "" -#: Client/core/CKeyBinds.cpp:215 -msgid "Sub-mission" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" msgstr "" -#: Client/core/CKeyBinds.cpp:216 -msgid "Handbrake" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" msgstr "" -#. 30 -#: Client/core/CKeyBinds.cpp:217 -msgid "Vehicle look left" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "" + +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "" +"An updated version of MTA:SA %s is required to join the selected server.\n" +"\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "" + +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "" + +#: Client/core/CVersionUpdater.cpp:1669 +msgid "" +"It is not possible to connect at this time.\n" +"\n" +"Please try later." +msgstr "" + +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "" + +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "" + +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "" + +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "" + +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "" + +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "" + +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "" + +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "" + +#: Client/core/CVersionUpdater.cpp:1920 +msgid "" +"To join this server, you must update MTA.\n" +"\n" +" Do you want to update now ?" msgstr "" -#: Client/core/CKeyBinds.cpp:218 -msgid "Vehicle look right" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" msgstr "" -#: Client/core/CKeyBinds.cpp:219 -msgid "Vehicle look behind" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "" +"Server says an update is recommended, but not essential.\n" +"\n" +" Do you want to update now ?" msgstr "" -#: Client/core/CKeyBinds.cpp:220 -msgid "Vehicle mouse look" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "" +"An update is currently not available.\n" +"\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/core/CKeyBinds.cpp:221 -msgid "Special control left" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" msgstr "" -#: Client/core/CKeyBinds.cpp:222 -msgid "Special control right" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." msgstr "" -#: Client/core/CKeyBinds.cpp:223 -msgid "Special control down" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" msgstr "" -#: Client/core/CKeyBinds.cpp:224 -msgid "Special control up" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." msgstr "" -#: Client/core/CKeyBinds.cpp:225 -msgid "Aim weapon" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." msgstr "" -#: Client/core/CKeyBinds.cpp:226 -msgid "Conversation yes" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" msgstr "" -#. 40 -#: Client/core/CKeyBinds.cpp:227 -msgid "Conversation no" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" msgstr "" -#: Client/core/CKeyBinds.cpp:228 -msgid "Group control forwards" +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" msgstr "" -#: Client/core/CKeyBinds.cpp:229 -msgid "Group control backwards" +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" msgstr "" -#. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CVersionUpdater.cpp:2160 msgid "" -"The skin you selected could not be loaded, and the default skin also could " -"not be loaded, please reinstall MTA." +"Some MTA:SA data files are missing.\n" +"\n" +"\n" +"Please reinstall MTA:SA" msgstr "" -#: Client/core/CScreenShot.cpp:117 +#: Client/core/CVersionUpdater.cpp:2840 #, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "" - -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" +msgid "%3d %% completed" msgstr "" -#: Client/core/CScreenShot.cpp:173 +#: Client/core/CVersionUpdater.cpp:2843 #, c-format -msgid "Screenshot taken: '%s'" +msgid "" +"\n" +"\n" +"Waiting for response - %-3d" msgstr "" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "" "Could not initialize Direct3D9.\n" "\n" @@ -2498,120 +2532,85 @@ msgid "" "latest Windows Service Packs are installed correctly." msgstr "" -#. Create queue window -#: Client/core/ServerBrowser/CServerInfo.cpp:32 -#: Client/core/ServerBrowser/CServerInfo.cpp:302 -msgid "SERVER IS FULL" -msgstr "" - -#. Determine our label draw position for L10n -#. Start position -#. Server Name -#: Client/core/ServerBrowser/CServerInfo.cpp:44 -#: Client/core/ServerBrowser/CServerInfo.cpp:53 -msgid "Name:" -msgstr "" - -#. Server IP -#: Client/core/ServerBrowser/CServerInfo.cpp:44 -#: Client/core/ServerBrowser/CServerInfo.cpp:64 -msgid "Server Address:" -msgstr "" - -#. Gamemode -#: Client/core/ServerBrowser/CServerInfo.cpp:44 -#: Client/core/ServerBrowser/CServerInfo.cpp:75 -msgid "Gamemode:" -msgstr "" - -#. Map -#: Client/core/ServerBrowser/CServerInfo.cpp:44 -#: Client/core/ServerBrowser/CServerInfo.cpp:86 -msgid "Map:" -msgstr "" - -#. Players -#: Client/core/ServerBrowser/CServerInfo.cpp:45 -#: Client/core/ServerBrowser/CServerInfo.cpp:97 -msgid "Players:" +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" msgstr "" -#. Passworded -#: Client/core/ServerBrowser/CServerInfo.cpp:45 -#: Client/core/ServerBrowser/CServerInfo.cpp:108 -msgid "Passworded:" -msgstr "" +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "player" +msgid_plural "players" +msgstr[0] "" +msgstr[1] "" -#. Latency -#: Client/core/ServerBrowser/CServerInfo.cpp:45 -#: Client/core/ServerBrowser/CServerInfo.cpp:119 -msgid "Latency:" +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" msgstr "" -#. Column for player names -#. Player List Columns -#: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 -msgid "Player list" -msgstr "" +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3170 +msgid "server" +msgid_plural "servers" +msgstr[0] "" +msgstr[1] "" -#. Close button -#: Client/core/ServerBrowser/CServerInfo.cpp:144 -msgid "Close" +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:309 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" msgstr "" -#. Join Game button -#: Client/core/ServerBrowser/CServerInfo.cpp:152 -msgid "Join Game" +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:328 +msgid "Master server list could not be parsed." msgstr "" -#. Please enter password label -#: Client/core/ServerBrowser/CServerInfo.cpp:166 -msgid "Please enter the password to the server:" +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:338 +msgid "Master server list could not be retrieved." msgstr "" -#: Client/core/ServerBrowser/CServerInfo.cpp:177 -msgid "Join the server as soon as a player slot is available." +#: Client/core/ServerBrowser/CServerList.cpp:354 +msgid "(Backup server list)" msgstr "" -#: Client/core/ServerBrowser/CServerInfo.cpp:310 -msgid "PLEASE ENTER SERVER PASSWORD" +#: Client/core/ServerBrowser/CServerList.cpp:424 +msgid "Cannot create LAN-broadcast socket" msgstr "" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 -msgid "Timed Out" +#: Client/core/ServerBrowser/CServerList.cpp:434 +msgid "Cannot bind LAN-broadcast socket" msgstr "" -#. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 -msgid "Querying..." +#: Client/core/ServerBrowser/CServerList.cpp:477 +msgid "Attempting to discover LAN servers" msgstr "" #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:311 msgid "" "FOR QUICK CONNECT:\n" "\n" @@ -2619,507 +2618,607 @@ msgid "" "Or select a server from the history list and press 'Connect'" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:323 msgid "HELP" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:332 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 msgid "Refresh" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:332 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Add Favorite" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:332 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 +#: Client/core/ServerBrowser/CServerBrowser.cpp:459 +#: Client/core/ServerBrowser/CServerBrowser.cpp:530 msgid "Connect" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:332 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Server information" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:333 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Search servers" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:333 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 msgid "Search players" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:333 +#: Client/core/ServerBrowser/CServerBrowser.cpp:379 msgid "Start search" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:333 +#: Client/core/ServerBrowser/CServerBrowser.cpp:380 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2090 msgid "Search players..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:580 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2088 msgid "Search servers..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Name" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Players" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:614 msgid "Ping" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:615 msgid "Gamemode" msgstr "" +#. Player List Columns +#. Column for player names +#: Client/core/ServerBrowser/CServerBrowser.cpp:637 +#: Client/core/ServerBrowser/CServerInfo.cpp:138 +msgid "Player list" +msgstr "" + #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:649 msgid "Include:" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:655 msgid "Empty" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:661 msgid "Full" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:667 msgid "Locked" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:679 msgid "Offline" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:692 msgid "Other Versions" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:713 msgid "Back" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1014 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1028 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1725 msgid "Loading..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1570 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3046 msgid " ..loading.." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1608 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1763 msgid "No address specified!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1621 msgid "Unknown protocol" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1621 msgid "Please use the mtasa:// protocol!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:651 -#: Client/mods/deathmatch/logic/CClientGame.cpp:749 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1630 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1689 +#: Client/mods/deathmatch/logic/CClientGame.cpp:683 +#: Client/mods/deathmatch/logic/CClientGame.cpp:775 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1715 msgid "You have to select a server to connect to." msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" +#. Create queue window +#: Client/core/ServerBrowser/CServerInfo.cpp:32 +#: Client/core/ServerBrowser/CServerInfo.cpp:302 +msgid "SERVER IS FULL" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "" -msgstr[1] "" +#. Determine our label draw position for L10n +#. Start position +#. Server Name +#: Client/core/ServerBrowser/CServerInfo.cpp:44 +#: Client/core/ServerBrowser/CServerInfo.cpp:53 +msgid "Name:" +msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" +#. Server IP +#: Client/core/ServerBrowser/CServerInfo.cpp:44 +#: Client/core/ServerBrowser/CServerInfo.cpp:64 +msgid "Server Address:" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "" -msgstr[1] "" +#. Gamemode +#: Client/core/ServerBrowser/CServerInfo.cpp:44 +#: Client/core/ServerBrowser/CServerInfo.cpp:75 +msgid "Gamemode:" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" +#. Map +#: Client/core/ServerBrowser/CServerInfo.cpp:44 +#: Client/core/ServerBrowser/CServerInfo.cpp:86 +msgid "Map:" msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." +#. Players +#: Client/core/ServerBrowser/CServerInfo.cpp:45 +#: Client/core/ServerBrowser/CServerInfo.cpp:97 +msgid "Players:" msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." +#. Passworded +#: Client/core/ServerBrowser/CServerInfo.cpp:45 +#: Client/core/ServerBrowser/CServerInfo.cpp:108 +msgid "Passworded:" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" +#. Latency +#: Client/core/ServerBrowser/CServerInfo.cpp:45 +#: Client/core/ServerBrowser/CServerInfo.cpp:119 +msgid "Latency:" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" +#. Close button +#: Client/core/ServerBrowser/CServerInfo.cpp:144 +msgid "Close" +msgstr "" + +#. Join Game button +#: Client/core/ServerBrowser/CServerInfo.cpp:152 +msgid "Join Game" +msgstr "" + +#. Please enter password label +#: Client/core/ServerBrowser/CServerInfo.cpp:166 +msgid "Please enter the password to the server:" +msgstr "" + +#: Client/core/ServerBrowser/CServerInfo.cpp:177 +msgid "Join the server as soon as a player slot is available." +msgstr "" + +#: Client/core/ServerBrowser/CServerInfo.cpp:310 +msgid "PLEASE ENTER SERVER PASSWORD" +msgstr "" + +#: Client/core/ServerBrowser/CServerInfo.cpp:477 +msgid "Timed Out" +msgstr "" + +#. Set every GUI elements text to blank +#: Client/core/ServerBrowser/CServerInfo.cpp:513 +msgid "Querying..." +msgstr "" + +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "" + +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "" +"The server requests the following websites in order to load them (later):" +msgstr "" + +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "" + +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "" -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "disconnect from the game" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the nametags" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the chatbox" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:62 msgid "shows the network statistics" msgstr "" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "open the chat input" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "transmits voice to other players" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "enters a car as passenger" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "next radio channel" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "previous radio channel" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "sends a message to the targetted player" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the next weapon whilst in a vehicle" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "changes to the previous weapon whilst in a vehicle" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:84 msgid "outputs info about the current server" msgstr "" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:87 msgid "defines the scale multiplier of all text-displays" msgstr "" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) shows the colshapes" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:95 msgid "(Development mode) prints world sound ids into the debug window" msgstr "" -#: Client/mods/deathmatch/logic/CTransferBox.cpp:25 -msgid "Map download progress:" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" msgstr "" -#: Client/mods/deathmatch/logic/CTransferBox.cpp:28 -msgid "Download Progress:" +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" msgstr "" -#. Find our largest piece of text, so we can size accordingly -#: Client/mods/deathmatch/logic/CTransferBox.cpp:42 -#: Client/mods/deathmatch/logic/CTransferBox.cpp:105 -#, c-format -msgid "%s of %s" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" msgstr "" -#: Client/mods/deathmatch/logic/CTransferBox.cpp:44 -#: Client/mods/deathmatch/logic/CTransferBox.cpp:65 -msgid "Disconnect to cancel download" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "" + +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 +#, c-format +msgid "Download error: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:509 msgid "Disconnected: Invalid nickname" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:513 msgid "Disconnect from server" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "" "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "" "Disconnected: You are banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:529 #, c-format msgid "" "Disconnected: Account is banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:534 msgid "Disconnected: Version mismatch" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:538 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:542 #, c-format msgid "" "Disconnected: Server from different branch.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:547 #, c-format msgid "" "Disconnected: Bad version.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:552 #, c-format msgid "" "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:557 #, c-format msgid "" "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:562 msgid "Disconnected: Nick already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:566 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:570 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:575 msgid "Disconnected: Serial verification failed" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:579 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:583 #, c-format msgid "Disconnected: Connection desync %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:592 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:597 #, c-format msgid "Disconnected: You were banned by %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:608 msgid "Disconnected: Server shutdown or restarting" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "You were kicked from the game" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 msgid "This server requires a non-modifed gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:641 msgid "Please replace gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "This server does not allow custom D3D9.DLLs" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "This server does not allow virtual machines" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires driver signing to be enabled" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please restart your PC" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server has detected missing anti-cheat components" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Try restarting MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 msgid "Please replace gta3.img or gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:642 msgid "This server does not allow Wine" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:643 msgid "Ensure no other program is modifying MTA:SA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:657 msgid "Time Remaining: " msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "" msgstr[1] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:669 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "" msgstr[1] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "" msgstr[1] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:673 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3127,297 +3226,244 @@ msgstr[0] "" msgstr[1] "" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:677 msgid "Disconnected" msgstr "" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 #, c-format -msgid "Download error: %s" +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:81 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:792 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:794 +msgid "Free Movement" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:391 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:381 +#: Client/mods/deathmatch/logic/CClientGame.cpp:391 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:381 +#: Client/mods/deathmatch/logic/CClientGame.cpp:391 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:381 +#: Client/mods/deathmatch/logic/CClientGame.cpp:392 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:382 +#: Client/mods/deathmatch/logic/CClientGame.cpp:392 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:382 +#: Client/mods/deathmatch/logic/CClientGame.cpp:392 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:402 +#: Client/mods/deathmatch/logic/CClientGame.cpp:413 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:403 +#: Client/mods/deathmatch/logic/CClientGame.cpp:414 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:667 +#: Client/mods/deathmatch/logic/CClientGame.cpp:699 msgid "Entering the game ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:725 +#: Client/mods/deathmatch/logic/CClientGame.cpp:751 msgid "" "Not connected; please use Quick Connect or the 'connect' command to connect " "to a server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:771 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Could not start the local server. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:781 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1253 +#: Client/mods/deathmatch/logic/CClientGame.cpp:807 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1282 msgid "Local Server" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:781 +#: Client/mods/deathmatch/logic/CClientGame.cpp:807 msgid "Starting local server ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1029 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1057 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1038 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1066 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1184 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1213 #, c-format msgid "You were kicked from the game ( %s )" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1253 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1282 msgid "Connecting to local server..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1264 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1293 msgid "Error connecting to server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1303 msgid "Connecting to local server timed out. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 msgid "Connection with the server was lost" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1407 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1436 msgid "Disconnected: the server is currently full" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1419 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1448 msgid "Disconnected: invalid password specified" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1441 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1470 msgid "MTA Client verification failed!" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5642 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5729 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5642 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5729 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5642 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5729 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5643 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5729 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5643 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5729 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" +#: Client/mods/deathmatch/logic/CTransferBox.cpp:25 +msgid "Map download progress:" msgstr "" -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +#: Client/mods/deathmatch/logic/CTransferBox.cpp:28 +msgid "Download Progress:" msgstr "" -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Find our largest piece of text, so we can size accordingly +#: Client/mods/deathmatch/logic/CTransferBox.cpp:42 +#: Client/mods/deathmatch/logic/CTransferBox.cpp:105 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "" - -#: Client/game_sa/CSettingsSA.cpp:820 -msgid "Can't find valid screen resolution." -msgstr "" - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:896 -msgid "Are you sure you want to use this screen resolution?" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" +msgid "%s of %s" msgstr "" -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" +#: Client/mods/deathmatch/logic/CTransferBox.cpp:44 +#: Client/mods/deathmatch/logic/CTransferBox.cpp:65 +msgid "Disconnect to cancel download" msgstr "" #. Populate the message and show the box @@ -3443,11 +3489,11 @@ msgstr "" msgid "Connection error" msgstr "" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:495 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "" -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1647 msgid "" "Your browser will now display a web page with some help infomation.\n" "\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/es_ES/client.pot b/Shared/data/MTA San Andreas/MTA/locale/es_ES/client.pot index c2d9b5dcbdb..e3853e3139d 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/es_ES/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/es_ES/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:18\n" "Last-Translator: \n" "Language-Team: Spanish\n" "Language: es_ES\n" @@ -17,72 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Problemas al reiniciar MTA:SA\n\n" -"Si el problema persiste, abre el Administrador de Tareas y\n" -"detén los procesos 'gta_sa.exe' y 'Multi Theft Auto.exe'\n\n\n" -"¿Intentar abrir MTA:SA de nuevo? " +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Inicia Grand Theft Auto: San Andreas.\n" +"Asegúrate de que el juego está en la carpeta «Archivos de programa (x86)»." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Error" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "Buscando GTA: San Andreas" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Ya se está ejecutando otra instancia de MTA.\n\n" -"Si el problema persiste reinicia el equipo" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Lo sentimos, no se ha encontrado el juego.\n" +"Inicia Grand Theft Auto: San Andreas y haz clic en reintentar.\n" +"Asegúrate de que el juego está en la carpeta «Archivos de programa (x86)»." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Ya se está ejecutando otra instancia de MTA.\n\n" -"¿Desea terminarla?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Selecciona el directorio de instalación de Grand Theft Auto: San Andreas" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA necesita acceso de Administrador para la siguiente tarea:\n\n" +" '%s'\n\n" +"Por favor confirma en al siguiente ventana." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "¡Error al cargar el módulo %s! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Copiando archivos..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "La copia termino pronto. Todo en orden." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Finalizando..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "¡Listo!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Nueva instalación de %s detectada.\n\n" +"¿Deseas copiar tu configuración desde %s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA tuvo un problema al abrir el archivo '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "A GTA:SA le falta el archivo '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA tuvo un problema cargando un modelo." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Si has modificado gta3.img recientemente, entonces intenta reinstalar GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA ha tenido un problema para añadir una mejora a un vehículo." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA encontró errores en el archivo '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Reiniciaste tu computadora mientras jugabas MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Por favor, cierra los siguientes programas antes de continuar:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "Ruta inválida para el módulo detectada." + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Desajuste de la versión del archivo. Por favor, reinstala MTA:SA si experiencias problemas.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Algunos archivos están perdidos. Reinstala MTA:SA si experiencias problemas.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA no es compatible con el 'Modo Seguro' de Windows.\n\n" +"Por favor reinicia tu PC.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "¿Está teniendo problemas ejecutando MTA:SA?.\n\n" "¿Desea volver a una versión anterior?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +143,48 @@ msgstr "Parece que hay un problema al ejecutar MTA:SA.\n" "Restablecer los ajustes de GTA a veces puede solucionar este problema.\n\n" "¿Desea restablecer la configuración de GTA ahora?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "La configuración de GTA se ha restablecido.\n\n" "Pulse OK para continuar." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "El archivo: '%s' no se pudo eliminar" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "¿Está teniendo problemas para ejecutar MTA:SA?.\n\n" "¿Desea ver la ayuda en línea?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "¿Estas teniendo problemas al ejecutar MTA:SA?.\n\n" "¿Quieres cambiar la siguiente configuración?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Modo pantalla completa:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Ventana sin bordes" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "¿Estas teniendo problemas al ejecutar MTA:SA?.\n\n" "Intenta deshabilitar los siguientes productos para GTA y MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +192,297 @@ msgstr "ADVERTENCIA\n\n" "MTA:SA ha detectado una actividad inusual.\n" "Por favor, analiza tu equipo con un antivirus para descartar la posibilidad de que tu equipo está infectado.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "El archivo detectado fue: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Una instancia de GTA: San Andreas ya se está ejecutando. Se debe cerrar antes de que MTA:SA pueda iniciarse. ¿Desea hacerlo ahora?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Información" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "No se puede cerrar GTA: San Andreas. Si el problema persiste, por favor reinicie el equipo." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Problemas al reiniciar MTA:SA\n\n" +"Si el problema persiste, abre el Administrador de Tareas y\n" +"detén los procesos 'gta_sa.exe' y 'Multi Theft Auto.exe'\n\n\n" +"¿Intentar abrir MTA:SA de nuevo? " + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Error" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Ya se está ejecutando otra instancia de MTA.\n\n" +"Si el problema persiste reinicia el equipo" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Ya se está ejecutando otra instancia de MTA.\n\n" +"¿Desea terminarla?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Faltan entradas en el registro. Por favor, reinstala Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "La ruta de la instalación de tu GTA: San Andreas contiene caracteres (unicode) no soportados. Por favor mueve tu instalación de Grand Theft Auto: San Andreas a una ruta compatible que solo contenga caracteres ASCII estándar y reinstala Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "La ruta de instalación de 'MTA:SA' o 'GTA: San Andreas'\n" -"contiene un ';' (punto y coma).\n\n" -"Si experimentas problemas al ejecutar MTA:SA,\n" -"mueve tu(s) instalación(es) a una ruta donde no haya un punto y coma." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "La ruta para tu instalación de 'MTA:SA' o 'GTA: San Andreas' contiene el símbolo ';' (punto y coma).\n\n" +"Si experimenta problemas al correr\n" +" MTA:SA,\n" +"mueva su(s) archivo(s) de instalación a una ruta que no tenga punto y coma." + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "Rutas de instalación detectadas como inválidas." + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Fallo al cargar. Por favor asegúrate de que los últimos archivos de datos hayan sido instalados correctamente." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Fallo al cargar. Por favor asegúrate de que %s este instalado correctamente." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Fallo al cargar. No se pudo encontrar gta_sa.exe en %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Fallo al cargar. %s existe en el directorio de GTA. Por favor elimínelo antes de continuar." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "El archivo principal contiene un nombre incorrecto (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "El archivo principal no está firmado. Es probable que lo haya causado un virus.\n\n" -"Consulta ayuda en línea si MTA no funciona correctamente." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "El archivo de datos %s no fue encontrado. Posible actividad de virus.\n\n" -"Considera reinstalar Multi Theft Auto para tu seguridad.\n" -"Consulta la ayuda en línea si MTA no funciona correctamente." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "Archivo de dato %s está perdido/faltante. Posible virus activo en su sistema." + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "El archivo de datos %s ha sido modificado. Posible actividad de virus.\n\n" -"Considera reinstalar Multi Theft Auto para tu seguridad.\n" -"Consulta la ayuda en línea si MTA no funciona correctamente." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "Hay archivos .asi en el directorio de MTA:SA' o 'GTA: San Andreas'\n\n" -"Elimina estos archivos .asi si experiencias problemas con MTA:SA" - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Desajuste de la versión del archivo. Por favor, reinstala MTA:SA si experiencias problemas.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "Archivo de dato %s está perdido/faltante. Posible virus activo en el sistema." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Algunos archivos están perdidos. Reinstala MTA:SA si experiencias problemas.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "Los archivos .asi están en el directorio de instalación.\n\n" +"Elimina estos archivos .asi si experimenta problemas." -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA no es compatible con el 'Modo Seguro' de Windows.\n\n" -"Por favor reinicia tu PC.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "Rutas para el juego detectadas como inválidas." -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Arreglar problema de configuración" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Arreglar error de elevación requerida" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "GTA: San Andreas puede no haberse iniciado correctamente. ¿Quieres cerrar el proceso?" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Desconocido" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "El archivo '%s' está actualmente bloqueado por %zu procesos.\n\n" +"¿Desea finalizar los siguientes procesos y continuar con la actualización? \n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "Su instalación puede estar corrupta ahora.\n\n" +"%zu de %zu archivos no pudieron ser restaurados desde la copia de seguridad.\n\n" +"Se recomienda reinstalar Multi Theft Auto desde www.multitheftauto.com\n" +"o intentar correr la actualización con permisos de administrador." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Instalando actualización..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Extrayendo archivos..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA no pudo terminar la siguiente tarea:\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Ocurrió un problema con los controladores del controlador gráfico **\n\n" +"** Por favor, actualiza tus controladores de tu tarjeta gráfica **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "**Sin memoria disponible - este cierre fue causado debido a memoria insuficiente o fragmentada" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Instalar archivos actualizados de MTA:SA" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "No se pudo actualizar debido a un conflicto de archivos. Por favor, cierra otras aplicaciones e inténtalo de nuevo." + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto no ha sido instalado correctamente; por favor, reinstálalo. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "Crear uniones/puntos de unión en GTA:SA" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA no puede iniciarse porque ha fallado la copia de un archivo:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA no puede iniciarse porque falta un archivo o es incorrecto:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Copiar archivos de MTA:SA" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA no puede iniciarse porque un archivo de GTA:SA no existe o es erróneo:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "Parchear dependencia de GTA:SA" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA no puede iniciarse porque el ejecutable de GTA:SA no existe o es erróneo:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Por favor verifica tu antivirus en busca de un falso positivo, intenta añadir una excepción para el ejecutable de GTA:SA y reinicia MTA:SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "Generar GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA no puede iniciarse porque el ejecutable de GTA:SA no se puede cargar:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Instalar parche en GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA no puede iniciarse porque ha fallado la copia de un archivo:" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "No se pudo iniciar Grand Theft Auto: San Andreas. Por favor intente reiniciar, o si el problema persiste, contacte a MTA en www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA no puede continuar ya que el disco %s no posee suficiente espacio." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Falta archivo:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Si MTA falla al cargar, por favor, reinstala GTA:SA" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas pudo no haberse iniciado correctamente. ¿Quieres terminarlo?" +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Actualizar opciones de instalación" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Actualizar la configuración de compatibilidad" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +490,167 @@ msgstr "GTA: San Andreas pudo no haberse iniciado correctamente. ¿Quieres termi #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Sí" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "No" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "OK" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Salir" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Ayuda" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Cancelar" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas ha encontrado un problema" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Información del cierre" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Marca esta casilla de verificación para enviar información del cierre a los desarrolladores de MTA mediante 'internet'" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Haciéndolo podrás aumentar las posibilidades de que este problema sea arreglado." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "¿Quieres reiniciar MTA: San Andreas ?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Advertencia" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "Tu directorio de instalación de Grand Theft Auto: San Andreas contiene estos archivos:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Estos archivos no son necesarios y pueden interferir con las características gráficas de esta versión de MTA:SA.\n\n" "Se recomienda eliminar o cambiar el nombre de estos archivos." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" -msgstr "Mantenga estos archivos, pero también muestre esta advertencia en el próximo inicio" +msgstr "Mantener estos archivos, pero también muestre esta advertencia en el próximo inicio" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" -msgstr "No me vuelvas a recordar sobre estos archivos" +msgstr "No recordarme de nuevo nada sobre estos archivos" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Cambie el nombre de estos archivos de *.dll a *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Muéstrame estos archivos" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Jugar MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Opciones confusas" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "¡Se ha detectado NVidia Optimus!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Utiliza cada opción y descubre que puede funcionar:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - NVidia Estándar" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - NVidia Alternativo" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Intel estándar" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Intel alternativo" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Si estás desesperado, esto puede ayudar:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Si ya haz seleccionado una opción que funciona, esto podría ayudar:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Forzar modo ventana" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "No mostrar nuevamente" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Advertencia: no se detectó una solución antivirus" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1110 +658,1183 @@ msgstr "MTA no ha podido encontrar un antivirus en tu equipo.\n\n" "Los virus pueden interfieren con MTA y pueden degradar tu experiencia de juego.\n\n" "Presiona 'Ayuda' para más información." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Ya tengo instalado un antivirus" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "No instalaré un anti-virus.\n" "Quiero que mi equipo funcione lento y sea parte de una botnet." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "Este fallo/cierre que experimentó se debe a un abuso de memoria por parte de los servidores\n\n" +"Aún con abundancia de RAM, este es un juego x86 con límites de espacio predeterminados a un máximo de 3.6GB y algunos servidores faltos de optimización con demasiados mods (o unos pocos scripts pobremente escritos) pueden causar escenarios como este, así como causar lag en su juego\n\n" +"Contacte al dueño del servidor o a soporte de MTA en el discord oficial de MTA (https://discord.gg/mtasa) para más información." + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "MTA: San Andreas - Sin información de Memoria" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Buscando Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Por favor inicia Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Instalando actualización..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Conexión fallida. ¡Nick inválido!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Extrayendo archivos..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Conexión fallida. ¡Se ha proporcionado una dirección invalida!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Copiando archivos..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "¡La conexión a %s en el puerto %u ha fallado!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "La copia termino pronto. Todo en orden." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Estableciendo conexión a %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Finalizando..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "Reconectando con %s:%u ..." -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "¡Listo!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "CONECTANDO" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA necesita acceso de Administrador para la siguiente tarea:\n\n" -" '%s'\n\n" -"Por favor confirma en al siguiente ventana." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "La conexión ha expirado" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA no pudo terminar la siguiente tarea:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Desconectado: error de protocolo desconocido" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Ocurrió un problema con los controladores del controlador gráfico **\n\n" -"** Por favor, actualiza tus controladores de tu tarjeta gráfica **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Desconectado: desconectado remotamente" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Instalar archivos actualizados de MTA:SA" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Desconectado: conexión perdida remotamente" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "No se pudo actualizar debido a un conflicto de archivos. Por favor, cierra otras aplicaciones e inténtalo de nuevo." +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Desconectado: estás baneado de este servidor" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Desconectado: desconectado del servidor" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Desconectado: se ha perdido la conexión con el servidor" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Desconectado: la conexión fue rechazada" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto no ha sido instalado correctamente; por favor, reinstálalo. %s" +msgid "No such mod installed (%s)" +msgstr "Modificación no instalada (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "Crear intersecciones en GTA:SA" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Respuesta del servidor incorrecta (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA no puede iniciarse porque ha fallado la copia de un archivo:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Respuesta del servidor incorrecta (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA no puede iniciarse porque falta un archivo o es incorrecto:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Español" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Copiar archivos de MTA:SA" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Ocupado" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA no puede iniciarse porque un archivo de GTA:SA no existe o es erróneo:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "No se puede comprobar si hay actualizaciones en este momento" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Parchear dependencia de GTA:SA" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "Se requiere MTA:SA %s" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA no puede iniciarse porque el ejecutable de GTA:SA no existe o es erróneo:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Se requiere una versión actualizada de MTA:SA %s para entrar al servidor seleccionado.\n\n" +"¿Deseas descargar e instalar MTA:SA %s ?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Por favor verifica tu antivirus por la detección de un falso positivo, intenta añadir una excepción para el ejecutable de GTA:SA y reinicia MTA:SA." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "¿Quieres iniciar MTA:SA %s y conectarse a este servidor?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Generar GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "No es posible conectarse en este momento.\n\n" +"Por favor inténtelo más tarde." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA no puede iniciarse porque el ejecutable de GTA:SA no se puede cargar:" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Conectando" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Parchear GTA:SA" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Por favor, espere..." -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA no puede iniciarse porque el parcheo de GTA:SA ha fallado:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "COMPROBANDO" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA no puede continuar ya que el disco %s no posee suficiente espacio." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "COMPROBANDO ACTUALIZACIÓN" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Falta archivo:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "No se necesita actulización" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Si MTA falla al cargar, por favor, reinstala GTA:SA" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "DESCARGANDO" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Actualizar opciones de instalación" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "esperando..." -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Actualizar la configuración de compatibilidad" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "ACTUALIZACIÓN OBLIGATORIA" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Desconocido" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Para unirte a este servidor, necesitas actualizar MTA.\n\n" +"¿Quieres actualizar ahora?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "El archivo '%s' está actualmente bloqueado por %zu procesos.\n\n" -"¿Desea finalizar los siguientes procesos y continuar con la actualización? \n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "ACTUALIZACIÓN OPCIONAL" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "Su instalación puede estar corrupta ahora.\n\n" -"%zu de %zu archivos no pudieron ser restaurados desde la copia de seguridad.\n\n" -"Deberías reinstalar Multi Theft Auto desde www.multitheftauto.com\n" -"o intentar correr la actualización con permisos de administrador." +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "El servidor dice que se recomienda una actualización, pero no es esencial.\n\n" +" ¿Desea actualizar ahora?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Inicia Grand Theft Auto: San Andreas.\n" -"Asegúrate de que el juego está en la carpeta «Archivos de programa (x86)»." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "Actualmente no hay ninguna actualización disponible.\n\n" +"Revise nuestra web: www.multitheftauto.com" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "Buscando GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "ERROR AL GUARDAR" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Lo sentimos, no se ha encontrado el juego.\n" -"Inicia Grand Theft Auto: San Andreas y haz clic en reintentar.\n" -"Asegúrate de que el juego está en la carpeta «Archivos de programa (x86)»." +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "No se pudo crear el archivo." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Selecciona el directorio de instalación de Grand Theft Auto: San Andreas" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "ERROR AL DESCARGAR" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "¡Error al cargar el módulo %s! (%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "El archivo descargado parece ser incorrecto." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Nueva instalación de %s detectada.\n\n" -"¿Deseas copiar tu configuración desde %s ?" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Por alguna razón." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA tuvo un problema al abrir el archivo '%s'" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "DESCARGA COMPLETA" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "A GTA:SA le falta el archivo '%s'." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr "- Problema desconocido en _DialogUpdateResult" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA tuvo un problema cargando un modelo." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "ARCHIVOS PERSONALIZADOS DE GTA:SA" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Si has modificado gta3.img recientemente, entonces intenta reinstalar GTA:SA." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ok" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA ha tenido un problema para añadir una mejora a un vehículo." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "ERROR" + +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Faltan algunos archivos de MTA:SA.\n\n\n" +"Por favor reinstala MTA:SA" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA encontró errores en el archivo '%s'" +msgid "%3d %% completed" +msgstr "%3d %% completado" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Reiniciaste tu computadora mientras jugabas MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Esperando respuesta - %-3d" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Por favor, cierra los siguientes programas antes de continuar:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ AYUDA DE COMANDOS ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Solicitudes del sitio web" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* La hora es %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "El servidor solicita los siguientes sitios web para poder cargarlos (luego):" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "Connect: La red no está lista, por favor espera un momento" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NUNCA INGRESES INFORMACIÓN SENSIBLE PARA PROTEGERLA DE SER ROBADA" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "connect: La sintaxis es 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Recordar decisión" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "conexión: Número de puerto incorrecto" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Permitir" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "conexión: Conectando a %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Denegar" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "conexión: ¡no se pudo conectar a %s:%u!" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "Menú principal" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "connect: Error al desactivar la modificación actual" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "¡Estas utilizando una versión de la rama de prueba! ¡Esta es una versión de prueba que no te permitirá conectarte a servidores públicos!" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "Reconnect: La red no está lista, por favor espera un momento" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA no va a recibir actualizaciones en los sistemas XP/Vista a partir de Julio de 2019.\n\n" -"Actualiza Windows para jugar en los servidores más nuevos." +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "Reconnect: Puerto incorrecto" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Esto te desconectará del servidor actual.\n\n" -"¿Estás seguro de que quieres desconectarte?" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "Reconnect: Reconectando %s:%u..." -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "ALERTA DE DESCONEXIÓN" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "reconectar: no se ha podido conectar a %s:%u!" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "INFORMACIÓN" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Se han copiado todos los controles desde GTA" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Español" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Se guardó el archivo de configuración" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Tu serial es: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "AJUSTES" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Multijugador" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Vídeo" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "PostFX" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Audio" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Teclas" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Controles" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Interfaz" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Explorador Web" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Avanzado" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Cargar predeterminados" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Sensibilidad del ratón:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Sensibilidad del eje vertical:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Opciones del ratón" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Invertir ratón verticalmente" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Dirigir con el ratón" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Volar con ratón" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "Use la sensibilidad del ratón para apuntar" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Opciones del mando" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Controles estándar (Ratón + Teclado)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Controles clásicos (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Zona Muerta" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Saturación" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Utilice la pestaña 'Teclas' para administrar los botones del mando." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Stick izquierdo" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Stick derecho" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "DESCRIPCIÓN" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "TECLA" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "TECLA ALT." #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Apodo/Nick:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Guardar contraseñas de servidores" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Actualizar automáticamente el buscador de servidores" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Permitir subir capturas de pantalla" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Permitir sonidos externos" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Mostrar siempre la ventana de descarga" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" -msgstr "Permitir conectar con Discord Rich Presence" +msgstr "Permitir conexión con Discord Rich Presence" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" -msgstr "" +msgstr "Permitir estatus ingame a GTA:SA en Steam" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "Guarda las fotos tomadas con la cámara en la carpeta GTA San Andreas User Files" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" -msgstr "" +msgstr "Preguntar antes de desconectar del servidor usando el menú principal" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Usar archivos personalizados de GTA:SA" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Opciones de representación del mapa" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Opacidad:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "Resolución de imagen:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "1024 x 1024 (Por defecto)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Volumen Maestro:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Volumen de la Radio:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Volumen SFX:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "Volumen de MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Volumen de Voz:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Modo de reproducción:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "General" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Opciones de la Radio" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Ecualizador de Radio" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Auto-sintonizar Radio" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Opciones de las Canciones del Usuario" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Radio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Aleatorio" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Secuencial" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Escaneo Automático de Medios" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Opciones de silenciado" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Silenciar Todos los sonidos al minimizar" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Silenciar sonidos de la Radio al minimizar" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Silenciar efectos de sonido al minimizar" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Silenciar sonidos de MTA al minimizar" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Silenciar sonidos de voz al minimizar" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "ResolucioÌn:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Campo de Visión:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Distancia de Dibujado:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Brillo:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Calidad de Efectos:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Filtrado anisotrópico:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Suavizado:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Relación de Aspecto:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Ventana" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI consciente" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Estándar" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Mantener resolución sin bordes" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mapeo Mip" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "Sincronización Vertical" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Bajo" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Medio" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Alto" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Muy alto" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Apagado" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Automático" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "Proporción del Aspecto de la Interfaz Visual" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Sombras volumétricas" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Efecto de hierba" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Ondas de calor" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Humo de las ruedas etc" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Sombras dinámicas de personaje" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Desenfoque de movimiento" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Reflejos de luces al llover" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Minimizar Pantalla Completa" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Activar el Diálogo de Selección de Dispositivo" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Mostrar resoluciones no seguras" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Renderizar siempre los vehículos en alto detalle" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Renderizar siempre los peds en alto detalle" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "Gamma: " + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "Contraste: " + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "Saturación" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "Aplicar los ajustes en modo ventana" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "Aplicar los ajustes en modo pantalla completa" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Habilitar sitios web remotos" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Habilitar Javascript en sitios remotos" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "Activar el renderizado en GPU" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Lista negra personalizada" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Ingresa un dominio ej: google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Bloquear" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Dominio" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Eliminar dominio" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Lista blanca personalizada" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Permitir" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Varios" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Carga rápida de la ropa de CJ:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Velocidad del buscador:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Conexión única:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Etiqueta del paquete:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Animación de progreso:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Prioridad del proceso:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Opciones del depurador:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Streaming de memoria:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Actualizar tipo de build:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Instalar actualizaciones importantes:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Encendido" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Muy lento" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Predeterminado" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Rápido" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normal" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Por encima de lo normal" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Mínimo" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Máximo" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Compatibilidad con Windows 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "Color de 16 bits" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Arreglo del ratón" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Archivos de recursos del cliente:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Mostrar en el Explorador" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "Desactiva la afinidad del CPU 0 con la intención de mejorar el rendimiento" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Auto actualizador" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Comprobar actualizaciones" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Algunos ajustes serán aplicados cuando vuelvas a iniciar MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "¿Quieres reiniciar ahora?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "SE REQUIERE REINICIAR" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Algunos ajustes serán cambiados cuando te desconectes del servidor actual" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "¿Quieres desconectarte ahora?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "Desconexión necesaria" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "No se ha detectado un joypad. Comprueba las conexiones y reinicia el juego" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Asignación de ejes" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Mueve un eje para asignarlo, o escape para borrar" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Idioma:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Apariencia:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Preajustes:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Chat" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Cargar" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Colores" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Diseño" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Opciones" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Fondo del Chat" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Texto del Chat" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Fondo de la Entrada de Texto" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Fondo de la Entrada de Texto" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Líneas:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Escala:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Ancho:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Tamaño" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "después" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "para" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "seg" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Desvanecimiento" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Ocultar líneas antiguas" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horizontal:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Vertical:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Alineación del Texto:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "Compensación-X:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Compensación-Y:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Posición" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Izquierda" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Centro" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Derecha" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Arriba" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Abajo" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Fuente" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Ocultar el fondo cuando no se escriba" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Auto-completado de nick usando la tecla \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Permitir al servidor que parpadeé la ventana" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Permitir notificaciones emergentes" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Contorno blanco/negro del texto del chat" @@ -1551,89 +1842,95 @@ msgstr "Contorno blanco/negro del texto del chat" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Presiona una tecla para asignarla, o escape para borrar" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Asignando una tecla primaria" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Asignando una tecla secundaria" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "CONTROLES DE GTA" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "CONTROLES MULTIJUGADOR" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "¡Tu nick contiene carácteres inválidos!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Menú principal" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "En el juego" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Rojo:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Verde:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Azul:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Transparencia:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Color" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Vista Previa" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Por favor desconectate antes de cambiar el idioma" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Por favor desconectate antes de cambiar la apariencia" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Las sombras volumétricas pueden ralentizar algunos sistemas.\n\n" "¿Estás seguro de que quieres activarlas?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "ADVERTENCIA DE RENDIMIENTO" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "La subida de capturas de pantalla se requiere por algunos servidores para evitar trampas.\n\n" "(La captura de pantalla excluye el chat y la interfaz)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "INFORMACIÓN DE SUBIDA DE CAPTURA DE PANTALLA" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1641,23 +1938,21 @@ msgstr "Algunos scripts podrían reproducir sonidos, como el de la radio, de int "Deshabilitar esta configuración podría reducir\n" "el consumo de bando de ancha.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "SONIDOS EXTERNOS" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "Parece que tienes habilitada la opción de conexión Rich Presence.\n" -"¿Quieres permitir que los servidores compartan sus datos?\n\n" -"Esto incluye el suyo identificador de identificación único." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "CONSENTIMIENTO PARA PERMITIR EL INTERCAMBIO DE DATOS" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1667,11 +1962,7 @@ msgstr "Algunos archivos en tu directorio de datos de GTA:SA están modificados. "Sin embargo, LOS ARCHIVOS MODIFICADOS DE GTA:SA SON BLOQUEADOS POR MUCHOS SERVIDORES\n\n" "¿Estás seguro que quieres utilizarlos?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "ARCHIVOS PERSONALIZADOS DE GTA:SA" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1681,551 +1972,253 @@ msgstr "Habilitar DPI consciente es una característica experimental y\n" "Quizá experimentes algunos problemas gráficos si habilitas esta opción.\n\n" "Estas seguro que deseas habilitar esta opción?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "CARACTERÃSTICA EXPERIMENTAL" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" -msgstr "" +msgstr "Desactivar esta opción no está recomendado a menos que experimente problemas de estabilidad\n\n" +"¿Está seguro de desactivar la opción?" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Por favor introduzca un apodo/nick" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Por favor introduzca un apodo/nick para usarse en el juego.\n" "Este sera su nombre cuando se conecte y juegue en un servidor." -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Una característica muy experimental." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Detener las paradas con las variaciones de CJ (Utiliza 65MB más de RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Los routers viejos quizá requieran de una velocidad mas lenta de escaneo." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Cambiar a utilizar solo una conexión al descargar." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Marca los paquetes de red para ayudar a los ISP a identificar el tráfico de MTA." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Animación de círculo giratorio en la parte inferior de la pantalla" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Seleccionar predeterminado siempre. (Esta configuración no se guarda)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Máximo es usualmente lo mejor" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Actualizador automático:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Selecciona predeterminado a menos que te guste rellenar reportes de errores." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Selecciona por defecto para instalar automáticamente importantes actualizaciones." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "Color 16-bit:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Activar modos de color 16-bit - Se requiere reiniciar MTA" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Arreglo del ratón:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Arreglo del movimiento del ratón - Puede que se necesite reiniciar el equipo" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "Afinidad CPU:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." -msgstr "" - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Comando o variable de cliente desconocida: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Ocupado" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "No se puede comprobar si hay actualizaciones en este momento" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "Se requiere MTA:SA %s" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Se requiere una versión actualizada de MTA:SA %s para entrar al servidor seleccionado.\n\n" -"¿Deseas descargar e instalar MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "¿Quieres iniciar MTA:SA %s y conectarse a este servidor?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "No es posible conectarse en este momento.\n\n" -"Por favor inténtelo más tarde." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Conectando" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Por favor, espere..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "COMPROBANDO" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "COMPROBANDO ACTUALIZACIÓN" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "No se necesita actulización" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "DESCARGANDO" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "esperando..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "ACTUALIZACIÓN OBLIGATORIA" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Para unirte a este servidor, necesitas actualizar MTA.\n\n" -"¿Quieres actualizar ahora?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "ACTUALIZACIÓN OPCIONAL" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "El servidor dice que se recomienda una actualización, pero no es esencial.\n\n" -" ¿Desea actualizar ahora?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "Actualmente no hay ninguna actualización disponible.\n\n" -"Revise nuestra web: www.multitheftauto.com" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "ERROR AL GUARDAR" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "No se pudo crear el archivo." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "ERROR AL DESCARGAR" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "El archivo descargado parece ser incorrecto." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Por alguna razón." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "DESCARGA COMPLETA" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "- Problema desconocido en _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ok" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "ERROR" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Faltan algunos archivos de MTA:SA.\n\n\n" -"Por favor reinstala MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% completado" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Esperando respuesta - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Conexión fallida. ¡Nick inválido!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Conexión fallida. ¡Se ha proporcionado una dirección invalida!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "¡La conexión a %s en el puerto %u ha fallado!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Estableciendo conexión a %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "Reconectando %s:%u ..." - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "CONECTANDO" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "La conexión ha expirado" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Desconectado: error de protocolo desconocido" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Desconectado: desconectado remotamente" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Desconectado: conexión perdida remotamente" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Desconectado: estás baneado de este servidor" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Desconectado: desconectado del servidor" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Desconectado: se ha perdido la conexión con el servidor" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Desconectado: la conexión fue rechazada" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Modificación no instalada (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Respuesta del servidor incorrecta (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Respuesta del servidor incorrecta (1)" +msgstr "Solo cámbielo si tiene problemas de estabilidad" -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "NOTICIAS" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Visitar el ultimo artículo de noticia" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "CONSOLA" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Error fatal" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "PARA ARREGLARLO, REMUEVE ESTE ARCHIVO:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "¡El módulo %s es incorrecto!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Error al ejecutar URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "esta pantalla de ayuda" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "cierra la aplicación" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "muestra la versión" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "muestra la hora" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "muestra la interfaz" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "muestra todas las teclas asignadas" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "muestra tu serial" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "conecta a un servidor (dirección puerto nombre contraseña)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "conecta a un servidor previo" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "asigna una tecla (tecla de control)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "restablece una tecla (tecla)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" -msgstr "copia los controles por defecto de gta" - -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "guarda una captura de pantalla" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "guarda la configuración inmediatamente" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "borra la vista de depuración" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "desplaza el chat hacia arriba" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "desplaza el chat hacia abajo" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "desplaza hacia arriba la vista de depuración" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "desplaza hacia abajo la vista de depuración" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "muestra las estadísticas de memoria" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "muestra el gráfico de FPS" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "para desarrolladores: recargar noticias" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ AYUDA DE COMANDOS ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* La hora es %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "connect: La red no está lista, por favor espera un momento." - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "connect: La sintaxis es 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "conexión: Número de puerto incorrecto" +msgstr "copia los controles por defecto de gta" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "conexión: Conectando a %s:%u..." +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "guarda una captura de pantalla" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "conexión: ¡no se pudo conectar a %s:%u!" +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "guarda la configuración inmediatamente" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "connect: Error al desactivar la modificación actual" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "borra la vista de depuración" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "reconnect: La red no está lista, por favor espera un momento." +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "desplaza el chat hacia arriba" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "reconectar: Puerto incorrecto" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "desplaza el chat hacia abajo" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "reconectar: Reconectando %s:%u..." +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "desplaza hacia arriba la vista de depuración" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "reconectar: no se ha podido conectar a %s:%u!" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "desplaza hacia abajo la vista de depuración" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Se han copiado todos los controles desde GTA" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "muestra las estadísticas de memoria" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Se guardó el archivo de configuración" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "muestra el gráfico de FPS" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Tu serial es: %s" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "para desarrolladores: recargar noticias" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Eje de Acelerador" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "¡Estas utilizando una versión de la rama de prueba! ¡Esta es una versión de prueba que no te permitirá conectarte a servidores públicos!" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Eje de Freno" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA no va a recibir actualizaciones en los sistemas XP/Vista a partir de Julio de 2019.\n\n" +"Actualiza Windows para jugar en los servidores más nuevos." -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programación" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Esto te desconectará del servidor actual.\n\n" +"¿Estás seguro de que quieres desconectarte?" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Contribuyentes" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "ALERTA DE DESCONEXIÓN" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Diseño del juego / Scripting" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "INFORMACIÓN" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Traducciones" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "NOTICIAS" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Contribuyentes de parches" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Visitar el ultimo artículo de noticia" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Agradecimientos" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "La captura de pantalla tiene %d bytes, pero se esperaba %d" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Este software y proyecto hace uso de las siguientes bibliotecas y software:" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "La captura de pantalla ha fallado" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "¿Quieres ver ayuda en línea acerca de este problema?" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Imagen tomada: '%s'" + +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Comando o variable de cliente desconocida: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2400,25 +2393,56 @@ msgid "Group control backwards" msgstr "Control de grupo hacia atrás" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "No se pudo cargar el skin seleccionado, al igual que la skin por defecto, por favor reinstale MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "La captura de pantalla tiene %d bytes, pero se esperaba %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "¿Quieres ver ayuda en línea acerca de este problema?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "La captura de pantalla ha fallado" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "CONSOLA" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Imagen tomada: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programación" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Contribuyentes" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Diseño del juego / Scripting" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Traducciones" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Contribuyentes de parches" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Agradecimientos" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Este software y proyecto hace uso de las siguientes bibliotecas y software:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Eje de Acelerador" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Eje de Freno" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2426,6 +2450,61 @@ msgstr "No se pudo inicializar Direct3D9.\n\n" "Asegúrese de que DirectX End-User Runtime y los\n" "últimos Service Pack de Windows están instalados correctamente." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Inactivo" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "jugador" +msgstr[1] "jugadores" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "activo" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "servidor" +msgstr[1] "servidores" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Solicitando la lista al servidor maestro... (%lu ms transcurrido)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "No se pudo analizar la lista del servidor maestro." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "No se pudo recuperar la lista del servidor maestro." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Copia de seguridad de la lista de servidores)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "No se puede crear el socket de transmisión LAN" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "No se pudo enlazar el socket de transmisión LAN" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Intentando encontrar servidores LAN" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2479,7 +2558,7 @@ msgstr "Latencia:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Lista de jugadores" @@ -2506,40 +2585,39 @@ msgstr "Unirse al servidor cuando tenga un espacio disponible." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "POR FAVOR ESCRIBA LA CONTRASEÑA DEL SERVIDOR" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Se ha agotado el tiempo de espera del servidor" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Consultando…" #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "BUSCADOR DE SERVIDORES" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Local" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Favoritos" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Recientes" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2547,298 +2625,367 @@ msgstr "PARA CONECTARSE RÃPIDAMENTE:\n\n" "Escriba la dirección y el puerto en la barra de direcciones.\n" "O seleccione un servidor del historial y presione \"Conectar\"" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "AYUDA" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Actualizar" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Agregar como favorito" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Conectar" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Información del servidor" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Buscar servidores" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Buscar jugadores" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Empezar busqueda" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "Borrar desde reciente" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Buscar jugadores..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Buscar servidores..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Nombre" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Jugadores" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Latencia" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Modo de juego" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Incluye:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Vacío" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Lleno" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Bloqueado" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Fuera de línea" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Otras Versiones" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Atrás" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Cargando..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..cargando.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "¡No se especificó la dirección!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr " Protocolo desconocido" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "¡Por favor utilice el protocolo mtasa://!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "¡Nick inválido! ¡Por favor ve a Configuración y ponte a uno nuevo!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Tienes que seleccionar un servidor al cual conectarte." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Inactivo" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problema con el driver de la tarjeta gráfica" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "jugador" -msgstr[1] "jugadores" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "No se puede encontrar una resolución válida." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "activo" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "¿Estás seguro de que quieres utilizar esta resolución?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "servidor" -msgstr[1] "servidores" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "Fallo en la inicialización game_sa" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Solicitando la lista al servidor maestro... (%lu ms transcurrido)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "Fallo en la asignación de memoria" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "No se pudo analizar la lista del servidor maestro." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Solicitudes del sitio web" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "No se pudo recuperar la lista del servidor maestro." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "El servidor solicita los siguientes sitios web para poder cargarlos (luego):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Copia de seguridad de la lista de servidores)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NUNCA INGRESES INFORMACIÓN SENSIBLE PARA PROTEGERLA DE SER ROBADA" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "No se pudo enlazar el socket de transmisión LAN" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Recordar decisión" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Intentando encontrar servidores LAN" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Denegar" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Esta versión ha expirado." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "desconectado del juego" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "mostrar etiquetas de nombre" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "mostrar el cuadro de chat" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "muestra las estadísticas de red" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "abrir la entrada de chat" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "transmite voz a otros jugadores" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "entra en un coche como pasajero" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "siguiente estación de radio" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "anterior estación de radio" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "activar vista del mapa" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "ampliar el mapa" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "alejar el mapa" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "mover el mapa hacia el norte" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "mover el mapa hacia el sur" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "mover el mapa hacia el este" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "mover el mapa hacia el oeste" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" -msgstr "" +msgstr "Une el mapa-jugador" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "reducir opacidad del mapa" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "aumentar opacidad del mapa" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "mostrar texto de ayuda del mapa" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "envía un mensaje al jugador objetivo" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "cambia a la siguiente arma mientras estas en un vehículo" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "cambia a la arma anterior mientras estas en un vehículo" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "muestra la información del servidor actual" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "define el multiplicador de escala de todas las visualizaciones de texto" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Modo de desarrollo) muestra los colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Modo de desarrollo) envía los ids de los sonidos del mundo a la ventana de depuración" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "ORGANIZAR PARTIDA" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Recursos" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Nombre del servidor:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Contraseña:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Jugadores máx:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Difusión:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Seleccionado" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Todos" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Iniciar" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "Modo cambiado: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "Zoom: %s/%s Movimiento: %s, %s, %s, %s Opacidad: %s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "Mostrar mapa: %s Alternar texto de ayuda: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "Siguiendo jugador" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "Movimiento libre" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Progreso de la descarga de los mapas:" @@ -2859,195 +3006,195 @@ msgstr "%s de %s" msgid "Disconnect to cancel download" msgstr "Desconectate para cancelar la descarga" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Desconectado: Apodo/Nick invalido" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Desconectar del servidor" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Desconectado: El serial esta baneado.\n" "Razón: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Desconectado: Estas baneado.\n" "Razón: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Desconectado: La cuenta esta baneada.\n" "Razón: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Desconectado: Versión inválida" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Desconectado: Flood de conexiones. Por favor espere un minuto, luego vuelva a intentarlo." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Desconectado: Servidor de una rama diferente.\n" "Información: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Desconectado: Versión mala.\n" "Información: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Desconectado: El servidor está usando una versión más reciente.\n" "Información: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Desconectado: El servidor está usando una versión más antigua.\n" "Información: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Desconectado: El apodo/nick ya esta en uso" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Desconectado: No se pudo crear el elemento del jugador." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Desconectado: El servidor rechazó la conexión: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Desconectado: Falló al verificar el serial" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "Desconectado: El serial ya está en uso" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Desconectado: Desincronización de conexión %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Desconectado: Fuiste expulsado por %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Desconectado: Fuiste baneado por %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Desconectado: Servidor apagado o reiniciando" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Fuiste expulsado del juego" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Este servidor requiere un gta_sa.exe no modificado" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Por favor, remplace gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Este servidor no permite D3D9.DLLs modificados" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Remueve D3D9.DLL del directorio de instalación de tu GTA y reinicia MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Este servidor no permite máquinas virtuales" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Este servidor requiere que la firma de controladores esté habilitada" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Por favor, reinicia tu PC" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Este servidor ha detectado que faltan componentes anti-trampa" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Intenta reiniciar MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Este servidor requiere un gta3.img y gta_int.img no modificados" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Por favor, remplace gt3.img o gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Este servidor no permite Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Asegúrese de que ningún otro programa esté modificando MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Tiempo Restante: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d día" msgstr[1] "%d dias" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d hora" msgstr[1] "%d horas" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d minuto" msgstr[1] "%d minutos" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3055,302 +3202,212 @@ msgstr[0] "%d segundo" msgstr[1] "%d segundos" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Desconectado" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Error de descarga: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "Volando un OVNI por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "Conduciendo por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "Surcando las olas de" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "Conduciendo el tren en" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "Volando por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "Manejando por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "En un monster truck por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "En quad por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "Saltando por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "Haciendo cosas raras en" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "Escalando alrededor de" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "Tiroteando desde el vehículo en" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "Bajo el agua..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "Respirando agua" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "Ahogado en" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "Agachándose para cubrirse en" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "Peleando en" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "Peleando a puñetazos en" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "Eliminando tontos en" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "Disparando en" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "Volando en jetpack por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "Literalmente en llamas en" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "Quemándose en" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "Nadando en" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "Flotando alrededor de" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "Siendo perseguido por un tiburón" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "Muriendo por asfixia en" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Entrando al juego ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "No conectado; por favor usa Conexión Rapida o el comando 'connect' para conectarse a un servidor." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "No se pudo iniciar el servidor local. Vea la consola para más detalles." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Servidor Local" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Iniciando servidor local ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "Area 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "Caminando alrededor de " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Fuiste expulsado del juego ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Conectando al servidor local..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Error al conectarse al servidor." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "La conexión con el servidor local ha expirado. Vea la consola para más detalles." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Se ha perdido la conexión con el servidor" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Desconectado: el servidor está lleno" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Desconectado: la contraseña especificada es inválida" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "¡La verificación del Cliente MTA ha fallado!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "Enterrado" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "En camino al hospital" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "Conociendo a su creador" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "Lamentándose de sus decisiones" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "Muerto" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "ORGANIZAR PARTIDA" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Recursos" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Nombre del servidor:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Contraseña:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Jugadores máx:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Difusión:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Seleccionado" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Todos" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Iniciar" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "Modo cambiado: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "Zoom: %s/%s Movimiento: %s, %s, %s, %s Opacidad: %s/%s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "Mostrar mapa: %s Alternar texto de ayuda: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "Siguiendo jugador" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "Movimiento libre" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problema con el driver de la tarjeta gráfica" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "No se puede encontrar una resolución válida." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "¿Estás seguro de que quieres utilizar esta resolución?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "Fallo en la inicialización game_sa" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "Fallo en la asignación de memoria" +msgid "Download error: %s" +msgstr "Error de descarga: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 #, c-format msgid "Fatal error (%u). If this problem persists, please check out multitheftauto.com for support." -msgstr "" +msgstr "Error fatal (%u). Si el problema persiste, por favor visite multitheftauto.com para una mejor ayuda" #. #ifdef MTA_DEBUG #. assert ( 0 ); @@ -3359,17 +3416,17 @@ msgstr "" #: Shared/mods/deathmatch/logic/Utils.cpp:143 #, c-format msgid "Protocol error (%u). If this problem persists, please check out multitheftauto.com for support." -msgstr "" +msgstr "error de protocolo (%u). Si el problema persiste, por favor visite multitheftauto.com para una mejor ayuda" #: Shared/mods/deathmatch/logic/Utils.cpp:145 msgid "Connection error" msgstr "Error de conexión" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto no ha sido instalado correctamente, por favor reinstale." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Tu explorador mostrará una página web con información de ayuda.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/et_EE/client.pot b/Shared/data/MTA San Andreas/MTA/locale/et_EE/client.pot index ee929431a09..12985e91dd4 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/et_EE/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/et_EE/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:32\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Estonian\n" "Language: et_EE\n" @@ -17,72 +17,120 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Probleem MTA:SA taaskäivitamisel\n\n" -"Kui probleem jätkub siis avage Task Manager ja\n" -"lõpetage 'gta_sa.exe' ning 'Multi Theft Auto.exe' protsessid\n\n\n" -"Kas avan MTA:SA uuesti?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Viga" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Üks MTA klient juba käib.\n\n" -"Kui probleem jätkub siis palun taaskäivitage oma arvuti" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Üks MTA klient juba käib.\n\n" -"Kas soovite selle sulgeda?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Vali oma Grand Theft Auto: San Andrease kaust" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA vajab administraatori õiguseid järgnevaks tegevuseks:\n\n" +"'%s'\n\n" +"Palun nõustuge järgnevas aknas." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Viga mooduli %s laadimises! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Kopeerin faile..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopeerimine lõpetatud varakult. Kõik on korras." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Lõpetamine..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Valmis!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "" + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "" + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "" + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "" + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Kas on probleeme MTA:SA käivitamisega?.\n\n" "Kas soovid proovida vanemat versiooni?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,170 +138,333 @@ msgstr "Tundub, et on probleeme MTA:SA käivitamisel.\n" "GTA seadete taastamine suudab mõnikord selle probleemi kõrvaldada.\n\n" "Kas soovid GTA seadeid taastada?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA seaded on taastatud.\n\n" "Vajuta OK et jätkata." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Ei suutnud faili kustutada: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Kas esineb probleeme MTA:SA käivitamisel?.\n\n" "Kas soovid näha onlain abi?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Täisekraanirežiim:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Ilma raamita aken" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" msgstr "" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Üks GTA: San Andreas juba käib. See peab olema suletud enne kui soovite MTA:SA käivitada. Kas soovid seda kohe teha?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informatsioon" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Ei suutnud GTA: San Andreas sulgeda. Kui probleem jätkub siis palun taaskäivitage oma arvuti." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Probleem MTA:SA taaskäivitamisel\n\n" +"Kui probleem jätkub siis avage Task Manager ja\n" +"lõpetage 'gta_sa.exe' ning 'Multi Theft Auto.exe' protsessid\n\n\n" +"Kas avan MTA:SA uuesti?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Viga" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Üks MTA klient juba käib.\n\n" +"Kui probleem jätkub siis palun taaskäivitage oma arvuti" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Üks MTA klient juba käib.\n\n" +"Kas soovite selle sulgeda?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Registrikanne puudub. Palun paigaldage Multi Theft Auto: San Andreas uuesti." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "GTA: San Andrease paigalduse kaust sisaldab toetamatuid tähti. Palun liigutage oma Grand Theft Auto: San Andreas kuhugi mujale, mis koosneks ainult tavalistest ASCII tähtedest ja paigaldage Multi Theft Auto: San Andreas uuesti." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Asukoht 'MTA:SA' või 'GTA: San Andrease' jaoks\n" -"sisaldab ';' (semikoolonit).\n\n" -"Kui sul tekib probleeme MTA:SA käivitamisega siis\n" -"paigaldage need sinna, kus pole semikooloneid." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Laadimine ebaõnnestus: Palun tehke kindlaks, et viimased andmefailid on paigaldatud korrektselt." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Laadimine ebaõnnestus. Palun tehke kindlaks, kas %s on paigaldatud korrektselt." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Laadimine ebaõnnestus. Ei suutnud leida gta_sa.exe kohast %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Laadimine ebaõnnestus. %s eksisteerib GTA kaustas. Palun kustutage ennem jätkamist." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 +#, c-format +msgid "Data file %s is modified. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "" + +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/Install.cpp:479 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." msgstr "" -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA ei suutnud täita järgnevat käsku:\n\n" +"'%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Kokkujooksu põhjustas graafika draiverite viga **\n\n" +"** Palun uuenda oma graafika draivereid **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" msgstr "" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Paigalda uuendatud MTA:SA failid" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Ei suuda uuendada faili konflikti pärast. Palun sulgege teised rakendused ja proovige uuesti" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto ei ole paigaldatud korrektselt, palun paigaldage uuesti. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" msgstr "" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Ei suuda käivitada Grand Theft Auto: San Andreast. Proovige taaskäivitada ning kui probleem jätkub siis kontakteeruge MTA tiimiga veebilehelt www.multitheftauto.com\n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA ei saa edasi minna, sest teie %s kettal ei ole piisavalt ruumi." -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas ei käivitunud korrektselt. Kas soovite selle sulgeda?" +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Uuenda paigaldamise seadeid" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "" #. ///////////////////////////////////////////////////////////////////////// #. @@ -261,1265 +472,1344 @@ msgstr "GTA: San Andreas ei käivitunud korrektselt. Kas soovite selle sulgeda?" #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Jah" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Ei" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "Sobib" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Lõpeta" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Abi" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Loobu" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "" -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." msgstr "" -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "" -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Otsin Grand Theft Auto San Andreast" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Palun käivitage Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "" +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Ühendamine ebaõnnestus. Teie mängunimi ei sobi!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Ühendamine ebaõnnestus. Vale serveri IP!" + +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Ühendumine serveriga %s pordiga %u ebaõnnstus!" + +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Loon ühendust serveriga %s:%u ..." + +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." msgstr "" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Kopeerin faile..." +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "Ühendan" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopeerimine lõpetatud varakult. Kõik on korras." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Ühendus aegus" -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Lõpetamine..." +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Ühendus katkestati: teadmata protokolli viga" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Valmis!" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Ühendus katkestati: katkestati kuskilt mujalt" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Ühendus katkestati: ühendus kadus" + +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Ühendus katkestati: sa oled bannitud selles serverist" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Ühendus katkestati: lahkusid serverist" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Ühendus katkestati: ühendus serveriga katkes" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Ühendus katkestati: server ei soovi ühendada" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA vajab administraatori õiguseid järgnevaks tegevuseks:\n\n" -"'%s'\n\n" -"Palun nõustuge järgnevas aknas." +msgid "No such mod installed (%s)" +msgstr "Pole sellist modifikatsiooni installeeritud (%s)" + +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Server ei vasta (2)" + +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Server ei vasta (1)" -#: Client/loader/CInstallManager.cpp:376 +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Eesti" + +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Hõivatud" + +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Hetkel pole võimalik uuendusi kontrollida" + +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA ei suutnud täita järgnevat käsku:\n\n" -"'%s'\n" +msgid "MTA:SA %s required" +msgstr "MTA:SA %s on nõutud" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Kokkujooksu põhjustas graafika draiverite viga **\n\n" -"** Palun uuenda oma graafika draivereid **" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Uuem versioon MTA:SA-st (%s) on vajalik, et serveriga ühenduda.\n\n" +"Kas te tahate MTA:SA %s alla laadida ja installida?" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Paigalda uuendatud MTA:SA failid" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Kas soovid käivitada MTA:SA %s ja liituda selle serveriga ?" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Ei suuda uuendada faili konflikti pärast. Palun sulgege teised rakendused ja proovige uuesti" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Pole võimalik ühendust luua sellel korral.\n\n" +"Palun proovige hiljem uuesti." + +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Ühendamine" + +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Palun oodake..." + +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "UURIN" + +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "UUENDUSTE KONTROLLIMINE" -#: Client/loader/CInstallManager.cpp:561 -#, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto ei ole paigaldatud korrektselt, palun paigaldage uuesti. %s" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Uuendada pole vaja" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "LAEN ALLA" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "ootan..." -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "KOHUSTUSLIK UUENDUS" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Et liituda selle serveriga pead uuendama oma MTA.\n\n" +"Kas soovid uuendada kohe ?" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "VALIKULINE UUENDUS" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Server ütleb, et uuendus on soovituslik, aga mitte vajalik.\n\n" +"Kas soovid uuendada kohe ?" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "VIGADE SALVESTAMINE" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Ei suutnud luua uut faili." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "VIGA ALLA LAADIMISEL" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Alla laetud failid tunduvad olevat ebasobivad." -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Mingil põhjusel" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA ei saa edasi minna, sest teie %s kettal ei ole piisavalt ruumi." +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "ALLA LAADIMINE LÕPETATUD" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr "- Teadmata probleem _DialogUpdateResult -ga" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "MUUDETUD GTA:SA FAILID" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Uuenda paigaldamise seadeid" +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Sobib" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "VIGA" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Mõned tähtsad MTA:SA failid on puudu.\n\n\n" +"Palun paigaldage MTA:SA uuesti" -#: Client/loader/Install.cpp:272 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "" +msgid "%3d %% completed" +msgstr "%3d %% valmis" -#: Client/loader/Install.cpp:479 +#: Client/core/CVersionUpdater.cpp:2840 #, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "" +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Ootan vastust - %-3d" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ KÄSK ABI ]***\n" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Aeg on %d:%02d:%02d" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" msgstr "" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Vali oma Grand Theft Auto: San Andrease kaust" - -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Viga mooduli %s laadimises! (%s)" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "Ühendus: Syntax on 'connect [ ]'" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "ühenda: Port number ei sobi" -#: Client/loader/Utils.cpp:1538 +#: Client/core/CCommandFuncs.cpp:255 #, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "" +msgid "connect: Connecting to %s:%u..." +msgstr "ühenda: Loon ühendust serveriga %s:%u ..." -#: Client/loader/Utils.cpp:1560 +#: Client/core/CCommandFuncs.cpp:259 #, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "" +msgid "connect: could not connect to %s:%u!" +msgstr "ühenda: Ei suutnud luua ühendust serveriga %s:%u!" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "ühenda: Ei suutnud eemaldada modifikatsiooni" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" msgstr "" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" msgstr "" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CCommandFuncs.cpp:325 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "" - -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "" - -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" +msgid "reconnect: Reconnecting to %s:%u..." msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Veebilehe Taotlused" - -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Server taotleb nende laadimiseks (hiljem) järgmisi veebisaite:" - -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "ÄRGE KUNAGI SISESTAGE TÄHTSAID ANDMEID, ET KAITSTA ENNAST NENDE VARGUSTE EEST" - -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Jäta meelde otsus" - -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Luba" - -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Eira" - -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Kasutate funktsiooniharu järgu! See on ainult testversioon, mida ei saa kasutada avalike serveritega ühenduse loomiseks!" - -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA ei saa uuendusi XP-l/Vista-l pärast juulit 2019.\n\n" -"Uuenda oma Windowsi versiooni, et mängida uuematel serveritel." - -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "See toiming katkestab ühenduse praeguse serveriga.\n\n" -"Oled sa kindel, et tahad ühendust katkestada?" - -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "ÜHENDUSE KATKEMISE HOIATUS" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Seo kõik nupud GTA-ga" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Seadistusfail on salvestatud" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Eesti" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Sinu serial on: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "SEADED" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Mitmikmäng" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Video" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Heli" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Bindid" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Nupud" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Kasutajaliides" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Veebilehitseja" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Täpsemalt" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Laadi tavalised" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Hiire tundlikus:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Vertikaalse shitimise tundlikus:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Hiire seaded" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Pööra hiirt vertikaalselt" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Juhi hiirega" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Lenda hiirega" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Joypad valikud" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Tavalised nupud (Hiirt + Klaviatuur)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Klassikalised nupud (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Surnud tsoon" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Värvilisus" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Kasuta \"Binds\" vahetahvlit joypadi nuppude joaks." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Vasakule kang" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Paremale kang" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "KIRJELDUS" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "NUPP" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. NUPP" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Mängunimi:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Salvesta serverite salasõnad" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Automaatselt värskenda serverite listi" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Luba ekraani üleslaadmist" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Luba väliseid helisid" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Alati näita allalaadimis akent" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Kasuta muudetud GTA:SA faile" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Kaardi laadimise valikud" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Katvus:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Meistri Volüüm:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Raadio helitugevus:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Mängu helitugevus:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA helitugevus:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Hääle helitugevus:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Mängu tüüp:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Üldine" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Raadio seaded" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Raadio ekvalaiser" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Raadio auto-tune" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Kasutaja lugude valikud" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Raadio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Juhuslik" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Järjestikune" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Automaatne meedia skäneerimine" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Vaigistamis seaded" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Vaigista kõik helid, kui on minimeeritud" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Vaigista raadio heli kui mäng on all" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Vaigista mängu helid kui mäng on all" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Vaigista MTA helid kui mäng on all" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Vaigista mängijate mikrofoni helid kui mäng on all" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Resolutsioon:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "FOV:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Vaatekaugus:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Heledus:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX kvaliteet:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anisotroopne filtreering:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Antialias:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Kuvasuhe:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Aknal" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI teadlik" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Standart" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Hoia äärteta resolutsiooni" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mip kaardistamine" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Madal" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Keskmine" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Kõrge" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Väga kõrge" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Väljas" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Automaatne" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD sobitamise kuvasuhe" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Volumeetrilised varjud" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Muru efekt" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Soojus laine" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Rehvi toss jne" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Täisekraanirežiimi allapanek" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Võimalda seadme valiku dialoog" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Näita ebaturvalisi resolutsioone" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Renderdage sõidukeid alati kõrge detailiga" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Renderdage pedde alati kõrge detailiga" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Luba kaugveebisaidid" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Luba Javascript kaugveebisaitidel" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Kohandatud must nimekiri" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Sisesta domeen nt. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Blockeeri" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Domeen" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Eemalda domeen" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Kohandatud valge nimekiri" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Luba" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Muu" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Kiire CJ riiete laadimine:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Brauseri kiirus:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Üksik ühendus:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Paketi silt:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Edenemise animatsioon:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Protsessi prioteet:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Debug seaded:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Striiming mälu:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Uuenduse tüüp:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Paigalda tähtsad uuendused:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Peal" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Väga aeglane" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Tavaline" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Ilma ääreta aken" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Tavaline" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Üle normaalse" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Miinimum" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Maksimum" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 ühilduvus:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-bit värv" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Hiire parandus" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Klient resurss failid:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Näita Exploreris" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Automaatne uuendaja" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Kontrolli uuendusi" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "MTA järgmisel käivitamisel muudetakse mõnda seadet" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Kas soovite taaskäivitada kohe?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "TAASKÄIVITUS NÕUTUD" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Mõnda seadet muudetakse, kui katkestate ühenduse praeguse serveriga" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Kas soovite ühenduse kohe katkestada?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "KATKESTUS VAJATUD" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypadi ei avastatud - Kontrolli ühendusi ja taaskäivita mäng" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Siduv telg" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Liiguta telge, et bindida või ärge liigutage midagi, et puhastada" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Keel:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Välimus:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Valmisseadistus:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Vestlus" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Lae" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Värvid" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Paigutus" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Seaded" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Vestluse taust" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Chati tekst" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Sisend taust" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Sisestuskasti tekst" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Ridu:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Suurus:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Laius:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Suurus" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "pärast" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "jaoks" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "sek" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Hääbuv" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Eemalda vanad read" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horisontaalne:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Vertikaalne:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Teksti-Paigutus:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-Nihe:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-Nihe:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Positsioon" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Vasakule" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Keskel" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Paremale" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Tipus" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "All" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Font" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Peida taust kui ei kirjuta" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Hüüdnime täitmine klahvi \"Tab\" abil" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Luba serveril aken vilkuda" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "" @@ -1527,109 +1817,115 @@ msgstr "" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Vajutage nuppu, et bindida, või ärge tehke midagi, et puhastada" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Bindin põhilise nupu" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Bindin sekundaarse nupu" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA MÄNGU NUPUD" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "MITMIKMÄNGU NUPUD" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Teie mängunimi sisaldab ebasobivaid märke!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Punane:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Roheline:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Sinine:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Läbipaistvus:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Palun katkestage ühendus enne välimuse muutmist" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Volumeetrilised varjud võivad teie süsteemi aeglustada.\n\n" "Oled kindel, et soovid neid lubada?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "JÕUDLUSE HOIATUS" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Pildi üleslaadimine on nõutud osade serverite poolt anti-cheat eesmärgil.\n\n" "(Chat ja lahtiolevad aknad ei kuulu üleslaadimisele)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "PILDI ÜLESLAADIMISE INFORMATSIOON" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1639,561 +1935,259 @@ msgstr "Mõned failid sinu GTA:SA kaustas on muudetud.\n" "Kuid, MUUDETUD FAILID ON KEELATUD PALJUDES SERVERITES\n\n" "Old kindel, et soovid neid kasutada?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "MUUDETUD GTA:SA FAILID" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" "Are you sure you want to enable this option?" msgstr "" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Palun sisesta mängunimi" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Palun sisesta mängunimi, et liituda serveritega. \n" "Seda kasutatakse sinu äratundmiseks mängus" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Väga eksperimentaalne funktsioon." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Peatab kioskid CJ variatsioonidega (Kasutab 65MB rohkem RAMi)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Vanemad ruuterid võivad nõuda aeglasemat skäneerimise kiirust." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Lülita sisse, et kasutaks ainult ühte ühendust kui laeb faile alla." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "" -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Vali alati tavaline. (See säte ei ole salvestatud)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maksimaalne on tavaliselt parim" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Automaatne uuendamine:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Vali tavaline kui sulle ei meelde täita bug reporte." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Tundmatu käsk või sõna:" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Hõivatud" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Hetkel pole võimalik uuendusi kontrollida" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s on nõutud" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Uuem versioon MTA:SA-st (%s) on vajalik, et serveriga ühenduda.\n\n" -"Kas te tahate MTA:SA %s alla laadida ja installida?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Kas soovid käivitada MTA:SA %s ja liituda selle serveriga ?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Pole võimalik ühendust luua sellel korral.\n\n" -"Palun proovige hiljem uuesti." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Ühendamine" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Palun oodake..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "UURIN" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "UUENDUSTE KONTROLLIMINE" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Uuendada pole vaja" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "LAEN ALLA" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "ootan..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "KOHUSTUSLIK UUENDUS" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Et liituda selle serveriga pead uuendama oma MTA.\n\n" -"Kas soovid uuendada kohe ?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "VALIKULINE UUENDUS" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Server ütleb, et uuendus on soovituslik, aga mitte vajalik.\n\n" -"Kas soovid uuendada kohe ?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "VIGADE SALVESTAMINE" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Ei suutnud luua uut faili." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "VIGA ALLA LAADIMISEL" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Alla laetud failid tunduvad olevat ebasobivad." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Mingil põhjusel" - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "ALLA LAADIMINE LÕPETATUD" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "- Teadmata probleem _DialogUpdateResult -ga" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Sobib" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "VIGA" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Mõned tähtsad MTA:SA failid on puudu.\n\n\n" -"Palun paigaldage MTA:SA uuesti" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% valmis" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Ootan vastust - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Ühendamine ebaõnnestus. Teie mängunimi ei sobi!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Ühendamine ebaõnnestus. Vale serveri IP!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Ühendumine serveriga %s pordiga %u ebaõnnstus!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Loon ühendust serveriga %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "Ühendan" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Ühendus aegus" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Ühendus katkestati: teadmata protokolli viga" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Ühendus katkestati: katkestati kuskilt mujalt" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Ühendus katkestati: ühendus kadus" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Ühendus katkestati: sa oled bannitud selles serverist" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Ühendus katkestati: lahkusid serverist" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Ühendus katkestati: ühendus serveriga katkes" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Ühendus katkestati: server ei soovi ühendada" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Pole sellist modifikatsiooni installeeritud (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Server ei vasta (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Server ei vasta (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Külastage viimast uudiste artiklit" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONSOOL" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Tõsine viga" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "ET PARANDADA, EEMALDAGE JÄRGMINE FAIL:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s moodul on ebasobiv!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Viga URL-i avamisel" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "see abi leht" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "sulgeb rakenduse" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "näitab versiooni" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "näitab aega" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "näitab displeid" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "näitab kõiki binde" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "näitab sinu seriali" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "ühendab serveriga (ip port mängunimi salasõna)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "ühendab eelmise serveriga" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "bindib nupu (nupp)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "vabastab nupu bindist (nupp)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "kopeerib tavalise GTA nupud" -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "väljastab pildi mängust" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "salvestab seaded koheselt" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "puhastab debug akna" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "kerib chati üles" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "kerib chati alla" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "kerib debug akent üles" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "kerib debug akent alla" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "näitab mälu(RAM) statistikat" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "näitab kaadrite kohta graafikut" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ KÄSK ABI ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Aeg on %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "Ühendus: Syntax on 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "ühenda: Port number ei sobi" +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "väljastab pildi mängust" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "ühenda: Loon ühendust serveriga %s:%u ..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "salvestab seaded koheselt" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "ühenda: Ei suutnud luua ühendust serveriga %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "puhastab debug akna" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "ühenda: Ei suutnud eemaldada modifikatsiooni" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "kerib chati üles" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "kerib chati alla" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "kerib debug akent üles" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "kerib debug akent alla" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "näitab mälu(RAM) statistikat" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Seo kõik nupud GTA-ga" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "näitab kaadrite kohta graafikut" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Seadistusfail on salvestatud" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Sinu serial on: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Kasutate funktsiooniharu järgu! See on ainult testversioon, mida ei saa kasutada avalike serveritega ühenduse loomiseks!" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Kiirenduse kang" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA ei saa uuendusi XP-l/Vista-l pärast juulit 2019.\n\n" +"Uuenda oma Windowsi versiooni, et mängida uuematel serveritel." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Pidurdamise kang" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "See toiming katkestab ühenduse praeguse serveriga.\n\n" +"Oled sa kindel, et tahad ühendust katkestada?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programmeerimine" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "ÜHENDUSE KATKEMISE HOIATUS" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Panustajad" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Mängu disain / Koodimine" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Keel lokaliseerimine" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Külastage viimast uudiste artiklit" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Patchi koostajad" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Pilt tuli %d baiti, aga eeldati %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Eriline tänu" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Pildi tegemine ebaõnnestus" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Pilt on tehtud: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Kas soovid näha onlain abi selle probleemi kohta ?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Tundmatu käsk või sõna:" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2368,25 +2362,56 @@ msgid "Group control backwards" msgstr "Grupi käsk tagasi" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Valitud välimust pole võimalik laadida, ka tavalist välimust ei suudetud laadida. Palun installi MTA uuesti." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Pilt tuli %d baiti, aga eeldati %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Kas soovid näha onlain abi selle probleemi kohta ?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Pildi tegemine ebaõnnestus" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONSOOL" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Pilt on tehtud: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programmeerimine" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Panustajad" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Mängu disain / Koodimine" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Keel lokaliseerimine" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Patchi koostajad" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Eriline tänu" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Kiirenduse kang" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Pidurdamise kang" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2394,6 +2419,61 @@ msgstr "Ei suudetud käivitada Direct3D9.\n\n" "Palun tehtke kindlaks, et DirectX End-User Runtime ja\n" "viimane Windows Service Pack on paigaldatud korrektselt." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Tegevuseta" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "mängija" +msgstr[1] "mängijad" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "peal" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "" +msgstr[1] "serverid" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Nõuan peaserveri listi (%lu ms läbitud)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Peaserveri listi pole võimalik lugeda." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Peaserveri listi pole võimalik laadida." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Tagavara serveri list)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Ei suuda siduda LAN-braodcast pesa" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Proovin avastada LAN servereid" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2447,7 +2527,7 @@ msgstr "Latents:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Mängijate list" @@ -2474,40 +2554,39 @@ msgstr "Liitu serveriga esimesel võimalusel kui koht vabaneb." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "PALUN SISESTA SERVERI SALASÕNA" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Ühendus aegus" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Päring..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "SERVERI LIST" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Kohalik" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Lemmikud" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Hiljutine" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2515,298 +2594,367 @@ msgstr "KIIRE ÜHENDUSE LOOMISEKS:\n\n" "Kirjuta serveri IP ja port aadressi ribale.\n" "Või vali server ajaloo listist ja vajuta 'Ühenda'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "ABI" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Värskenda" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Lisa lemmik" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Ühenda" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Serveri informatsioon" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Otsi servereid" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Otsi mängijaid" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Alusta otsingut" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Otsi mängijaid..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Otsi servereid..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Nimi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Mängijad" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Mängutüüp" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Kaasa:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Tühi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Täis" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Lukus" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Offlain" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Muud versioonid" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Tagasi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Laadimine..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..laadimine.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Aadressi pole määratud!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Tundmatu protokoll" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Palun kasuta mtasa:// protokolli!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Vale mängunimi! Palun mine seadetesse ja vali uus!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Sa pead valima serveri millega ühenduda." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Tegevuseta" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "mängija" -msgstr[1] "mängijad" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "peal" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "" -msgstr[1] "serverid" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Nõuan peaserveri listi (%lu ms läbitud)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Peaserveri listi pole võimalik lugeda." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Veebilehe Taotlused" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Peaserveri listi pole võimalik laadida." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Server taotleb nende laadimiseks (hiljem) järgmisi veebisaite:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Tagavara serveri list)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "ÄRGE KUNAGI SISESTAGE TÄHTSAID ANDMEID, ET KAITSTA ENNAST NENDE VARGUSTE EEST" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Ei suuda siduda LAN-braodcast pesa" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Jäta meelde otsus" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Proovin avastada LAN servereid" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Eira" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "See versioon on aegunud." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "katkestab serveriga ühenduse" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "näitab nimesilte" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "näitab chatti" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "näitab võrgu statistikat" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "ava chati sisestuskast" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "edastab hääle teistele mängijatele" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "siseneb autosse kaasreisijana" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "järgmine raadiojaam" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "eelmine raadiojaam" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "saadab sõnumi märgistatud mängijale" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "võtab järgmise relva autos olles" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "võtab eelmise relva autos olles" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "defineerib suuruse korrutise tekstidele" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Arendus mood) näitab jooniseid" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Arendus mood) näitab maailma helide id-si debug aknas" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "LOO MÄNG" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Ressursid" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Serveri nimi:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Salasõna:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Maks mängijaid:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Ülekanne:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Valitud" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Kõik" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Alusta" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Kaardi allalaadimise protsess:" @@ -2827,195 +2975,195 @@ msgstr "%s / %s" msgid "Disconnect to cancel download" msgstr "Katkesta ühendus, et loobuda allalaadimisest" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Ühendus katkestatud: Ebasobiv mängunimi" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Katkesta ühendus" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Ühendus katkestatud: Serial on bannitud.\n" "Põhjus: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Ühendus katkestatud: Oled bannitud.\n" "Põhjus: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Ühendus katkestatud: Kasutaja on bannitud.\n" "Põhjus: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Ühendus katkestatud: Versioonid ei kattu" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Ühendus katkestatud: Proovid liituda liiga kiiresti. Palun oota minut ja siis proovi uuesti." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Ühendus katkestatud: Server asub teises alas.\n" "Informatsioon: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Ühendus katkes: Ebasobiv versioon.\n" "Informatsioon: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Ühendus katkes: Server jooksutab uuemat versiooni.\n" "Informatsioon: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Ühendus katkes: Server jooksutab vanemat versiooni.\n" "Informatsioon: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Ühendus katkestati: Mängunimi on juba kasutusel" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Ühendus katkestati: Serveri ei soovi ühendust luua %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Ühendus katkestatud: Seriali auditeerimine ebaõnnestus" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Ühendus katkestatud: Ühendus pole sünkroonitud %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Ühendus katkestatud: Said kicki %s poolt" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Ühendus katkestatud: Said banni %s poolt" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Teid visati mängust välja" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Palun taaskäivita enda arvuti" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Aega jäänud: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d päev" msgstr[1] "%d päeva" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d tund" msgstr[1] "%d tundi" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d minut" msgstr[1] "%d minutit" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3023,296 +3171,206 @@ msgstr[0] "" msgstr[1] "" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Ühendus katkestatud" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Alla laadimise viga: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Sisenen mängu ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Pole ühendatud: palun kasutage Loo Ühendus või \"Ühenda\" käsku, et liituda serveriga." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Ei suuda kohalikku serverit käivitada. Rohkem informatsiooni konsoolis." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Kohalik server" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Käivitan kohalikku serverit ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Teid visati mängust välja ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Ühendan kohaliku serveriga..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Viga serveriga ühendusmisel." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Ühendamine lokaalse serveriga aegus. Vaata konsooli, et näha rohkem informatsiooni." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Ühendus serveriga katkes" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Ühendus katkestati: server on täis" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Ühendus katkestatud: vale salasõna" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA Kliendi auditeerimine ebaõnnestus!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "LOO MÄNG" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Ressursid" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Serveri nimi:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Salasõna:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Maks mängijaid:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Ülekanne:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Valitud" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Kõik" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Alusta" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "" - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Alla laadimise viga: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3333,11 +3391,11 @@ msgstr "" msgid "Connection error" msgstr "Ühenduse viga" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto pole paigaldatud korrektselt, palun paigaldage uuesti." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Sinu brauser näitab veebilehte koos abistava tekstiga.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/fa_IR/client.pot b/Shared/data/MTA San Andreas/MTA/locale/fa_IR/client.pot index ad67dcc8439..de40c3acd94 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/fa_IR/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/fa_IR/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 04:08+0000\n" -"PO-Revision-Date: 2025-07-17 23:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Persian\n" "Language: fa_IR\n" @@ -17,72 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "مشکل در راه‌اندازی مجددی MTA:SA\n\n" -"اگر مشکل ادامه ÛŒØ§ÙØªØŒ 'Task Manager' را باز کرده\n" -"Ùˆ 'gta_sa.exe' Ùˆ 'Multi Theft Auto.exe' را متوق٠کنید\n\n\n" -"تلاش مجدد برای اجرای MTA:SA ØŸ" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "بازی Grand Theft Auto: San Andreas را اجرا کنید.\n" +"اطمینان حاصل کنید Ú©Ù‡ بازی در پوشه 'Program Files (x86)' قرار دارد." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:651 -#: Client/mods/deathmatch/logic/CClientGame.cpp:725 -#: Client/mods/deathmatch/logic/CClientGame.cpp:749 -#: Client/mods/deathmatch/logic/CClientGame.cpp:771 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1184 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1264 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1274 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1343 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1380 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1429 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1441 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "خطا" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "درحال جستجو GTA: San Andreas" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "یک نسخه دیگر از MTA از قبل در حال اجرا Ù…ÛŒ باشد.\n\n" -"اگر این مشکل پابرجا ماند، Ù„Ø·ÙØ§ کامپیوتر خود را دوباره راه‌اندازی کنید" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "متاسÙÙ…ØŒ بازی پیدا نشد.\n" +"بازی Grand Theft Auto: San Andreas را اجرا کنید Ùˆ روی \"تلاش مجدد\" کلیک کنید.\n" +"اطمینان حاصل کنید Ú©Ù‡ بازی در پوشه 'Program Files (x86)' قرار دارد." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "یک نسخه از MTA در حال حاضر در حال اجرا است.\n\n" -"آیا Ù…ÛŒ خواهید آن را متوق٠کنید؟" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Ù„Ø·ÙØ§Ù‹ محل نصب بازی Grand Theft Auto: San Andreas را انتخاب کنید" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA برای عملیات های زیر نیاز به دسترسی ناظر دارد:\n\n" +"'%s'\n\n" +"Ù„Ø·ÙØ§ در پنجره بعدی تایید کنید." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "خطا در بارگذاری %s ماژول! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "در حال Ú©Ù¾ÛŒ ÙØ§ÛŒÙ„ ها..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Ú©Ù¾ÛŒ زود تمام شد. همه Ú†ÛŒ اوکیه." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "در حال اتمام..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "انجام شد!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "نسخه نصبی جدید %s شناسایی شد.\n\n" +"آیا میخواهید تنظیمات خود را از %s بازیابی کنید ØŸ" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA مشکل در باز کردن ÙØ§ÛŒÙ„ '%s' دارد" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "ÙØ§ÛŒÙ„ '%s' در GTA:SA وجود ندارد." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA در بارگذاری این مدل مشکل داشت." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "اگر به تازگی gta3.img را دستکاری کردید، GTA:SA را مجددا نصب کنید." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA مشکل در Ø§ÙØ²ÙˆØ¯Ù† یک ارتقاء به یک وسیله نقلیه داشت." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA خطاهایی را در ÙØ§ÛŒÙ„ '%s' پیدا کرد" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "آیا کامپیوتر شما هنگام بازی کردن در MTA:SA دوباره راه‌اندازی شد؟" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Ù„Ø·ÙØ§Ù‹ قبل از ادامه، از برنامه های زیر خارج شوید:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "مسیر ماژول نامعتبر شناسایی شد.\n" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "عدم سازگاری نسخه ÙØ§ÛŒÙ„‌. اگر مشکلاتی دارید MTA:SA را دوباره نصب کنید.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "برخی از ÙØ§ÛŒÙ„ ها وجود ندارند. اگر مشکلاتی دارید MTA:SA را دوباره نصب کنید.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA با 'Safe Mode' ویندوز سازگار نیست.\n\n" +"Ù„Ø·ÙØ§ کامپیوتر خود را دوباره راه‌اندازی کنید.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "آیا در اجرای MTA:SA ای به مشکل برخوردید؟\n\n" "آیا Ù…ÛŒ خواهد به نسخه قبلی برگردید؟" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +143,48 @@ msgstr "به نظر Ù…ÛŒ رسد در اجرای MTA:SA مشکلی به وجود "بازنشایی تنظیمات GTA ممکن است مشکل را حل کند.\n\n" "آیا Ù…ÛŒ خواهید تنظیمات GTA را بازنشایی کنید؟" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "تنظیمات GTA بازنشانی شد.\n\n" "بر روی دکمه 'بسیار خب' برای ادامه کلیک کنید." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Ø­Ø°Ù ÙØ§ÛŒÙ„ انجام نشد: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "آیا در اجرای MTA:SA مشکل دارید؟\n\n" "آیا تمایل به مشاهده Ú©Ù…Ú© آنلاین دارید؟" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "آیا در اجرای MTA:SA مشکل دارید؟ \n\n" "آیا میخواهید تنظیمات زیر را تغییر دهید؟" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "حالت تمام ØµÙØ­Ù‡:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "پنجره بدون مرز" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "آیا در اجرای MTA:SA مشکل دارید؟\n\n" "Ù…ÛŒ توانید ØºÛŒØ±ÙØ¹Ø§Ù„ کردن تنظیمات/گزینه های زیر را برای GTA Ùˆ MTA امتحان کنید:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,130 +192,294 @@ msgstr "هشدار\n\n" "MTA:SA ÙØ¹Ø§Ù„یت های غیرمعمولی را شناسایی کرده است.\n" "Ù„Ø·ÙØ§ 'Virus Scan' را ÙØ¹Ø§Ù„ کنید تا از امنیت سیستم خود مطمئن شوید.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "ÙØ§ÛŒÙ„ شناسایی شده: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "یک نمونه از GTA: San Andreas در حال حاضر در حال اجرا است. قبل از اجرای MTA:SA نیاز به توق٠آن است. الان میخواهید این کار را انجام دهید؟" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "اطلاعات" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "بستن GTA: San Andreas ناموÙÙ‚ بود، اگر مشکل همچنان ادامه داشت، کامپیوتر خود را راه‌اندازی مجدد کنید." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "مشکل در راه‌اندازی مجددی MTA:SA\n\n" +"اگر مشکل ادامه ÛŒØ§ÙØªØŒ 'Task Manager' را باز کرده\n" +"Ùˆ 'gta_sa.exe' Ùˆ 'Multi Theft Auto.exe' را متوق٠کنید\n\n\n" +"تلاش مجدد برای اجرای MTA:SA ØŸ" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "خطا" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "یک نسخه دیگر از MTA از قبل در حال اجرا Ù…ÛŒ باشد.\n\n" +"اگر این مشکل پابرجا ماند، Ù„Ø·ÙØ§ کامپیوتر خود را دوباره راه‌اندازی کنید" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "یک نسخه از MTA در حال حاضر در حال اجرا است.\n\n" +"آیا Ù…ÛŒ خواهید آن را متوق٠کنید؟" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "ورودی های رجیستری وجود ندارد. Ù„Ø·ÙØ§ Multi Theft Auto: San Andreas را مجدد نصب نمایید." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "مسیر نصب GTA: San Andreas شما حاوی کاراکتر های غیرمجاز (unicode) Ù…ÛŒ باشد. Ù„Ø·ÙØ§ Grand Theft Auto: San Andreas را به یک مسیر پشتیبانی شده Ú©Ù‡ حاوی کاراکتر های استاندارد (ASCII) است انتقال داده Ùˆ Multi Theft Auto: San Andreas را مجدد نصب نمایید." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "مکان نصب 'MTA:SA' یا 'GTA: San Andreas' شامل یک ';' (نقطه ویرگول) Ù…ÛŒ باشد.\n\n" -"اگر در اجرای MTA:SA به مشکل برخوردید، محل نصب GTA یا MTA:SA را به محلی Ú©Ù‡ شامل ';' نمیباشد تغییر دهید." +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" -#: Client/loader/MainFunctions.cpp:810 +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "مسیرهای نصب نامعتبر شناسایی شدند." + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "خطا در بارگذاری. Ù„Ø·ÙØ§ مطمئن شوید آخرین ÙØ§ÛŒÙ„ های بروزرسانی به درستی نصب شده اند." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "خطا در بارگذاری Ù„Ø·ÙØ§ مطمئن شوید ÙØ§ÛŒÙ„ %s به درستی نصب شده باشد." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "خطا در بارگذاری. ÙØ§ÛŒÙ„ gta_sa.exe در مسیر %s پیدا نشد." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "خطا در بارگذاری. ÙØ§ÛŒÙ„ %s در پوشه GTA وجود دارد. قبل از ادامه این ÙØ§ÛŒÙ„ را حذ٠کنید." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "ÙØ§ÛŒÙ„ اصلی نام اشتباهی دارد (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "ÙØ§ÛŒÙ„ اصلی بدون امضا می‌باشد. احتمال وجود ویروس.\n\n" -"اگر MTA به درستی کار نمیکند به پشتیبانی آنلاین مراجعه کنید." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "ÙØ§ÛŒÙ„ %s وجود ندارد. احتمال وجود ویروس.\n\n" -"برای امنیت خود، Multi Theft Auto را دوباره نصب کنید.\n" -"اگر MTA به درستی کار نمی کند، به پشتیبانی آنلاین مراجعه کنید." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "ÙØ§ÛŒÙ„ داده %s Ú¯Ù… شده است. احتمال ÙØ¹Ø§Ù„یت ویروسی وجود دارد." + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "ÙØ§ÛŒÙ„ داده %s دستکاری شده است. احتمال وجود ویروس\n\n" -"برای امنیت خود، Multi Theft Auto را دوباره نصب کنید.\n" -"اگر MTA به درستی کار نمی کند، به پشتیبانی آنلاین مراجعه کنید." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "ÙØ§ÛŒÙ„ های .asi در محل نصب 'GTA: San Andreas' یا 'MTA:SA' وجود دارند. \n\n" -"اگر مشکلاتی در MTA:SA دارید ÙØ§ÛŒÙ„ های .asi را حذ٠کنید." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "عدم سازگاری نسخه ÙØ§ÛŒÙ„‌. اگر مشکلاتی دارید MTA:SA را دوباره نصب کنید.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "ÙØ§ÛŒÙ„ داده %s تغییر کرده است. احتمال ÙØ¹Ø§Ù„یت ویروسی وجود دارد." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "برخی از ÙØ§ÛŒÙ„ ها وجود ندارند. اگر مشکلاتی دارید MTA:SA را دوباره نصب کنید.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA با 'Safe Mode' ویندوز سازگار نیست.\n\n" -"Ù„Ø·ÙØ§ کامپیوتر خود را دوباره راه‌اندازی کنید.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Ø±ÙØ¹ مشکل پیکربندی" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Ø±ÙØ¹ خطای دسترسی" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "ناشناخته" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "ÙØ§ÛŒÙ„ '%s' در حال حاضر توسط ÙØ±Ø¢ÛŒÙ†Ø¯Ù‡Ø§ÛŒ %zu Ù‚ÙÙ„ شده است.\n\n" +"آیا Ù…ÛŒ خواهید ÙØ¹Ø§Ù„یت زیر را خاتمه دهید Ùˆ به بروزرسانی ادامه دهید؟\n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "ÙØ±Ø§ÛŒÙ†Ø¯ نصب شما ممکن است در حال حاضر خراب باشد.\n\n" +"ÙØ§ÛŒÙ„ %zu از %zu از نسخه پشتیبان نمیتواند بازیابی شود.\n\n" +"میبایست Multi Theft Auto را از www.multitheftauto.com دوباره نصب کنید\n" +"یا سعی کنید بروزرسانی را با دسترسی administrator اجرا کنید." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "در حال نصب بروزرسانی..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "در حال استخراج ÙØ§ÛŒÙ„ ها..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA نتوانست عملیات های زیر را انجام دهد:\n\n" +"'%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** دلیل خرابی به خاطر خطای درایور کارت گراÙیک است **\n\n" +"** Ù„Ø·ÙØ§ درایور کارت گراÙیک خود را بروزرسانی نمایید **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "** خارج از Ø­Ø§ÙØ¸Ù‡ – این خرابی به‌خاطر کمبود یا به‌هم‌ریختگی Ø­Ø§ÙØ¸Ù‡ آزاد رخ داده است. **" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "نصب ÙØ§ÛŒÙ„ های بروزرسانی شده MTA:SA" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "به دلیل درگیر بودن ÙØ§ÛŒÙ„ ها نمی توان بروزرسانی کرد. Ù„Ø·ÙØ§ برنامه های دیگر را بسته Ùˆ مجددا تلاش کنید" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "مولتی Ø¯ÙØª آتو به درستی نصب نشده است, Ù„Ø·ÙØ§ دوباره نصب کنید. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "اتصالات GTA:SA را بسازید" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA اجرا نشد زیرا Ú©Ù¾ÛŒ یک ÙØ§ÛŒÙ„ با شکست مواجه شد:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA اجرا نشد زیرا برخی ÙØ§ÛŒÙ„ ها خراب یا وجود ندارند:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Ú©Ù¾ÛŒ کردن ÙØ§ÛŒÙ„ های MTA:SA" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA اجرا نشد زیرا برخی ÙØ§ÛŒÙ„ های GTA:SA خراب یا وجود ندارند:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "بسته تکمیلی پیشنیاز های GTA:SA" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA اجرا نشد زیرا ÙØ§ÛŒÙ„ اجرایی GTA:SA وجود ندارد یا خراب است:\n" +"به دلیل مشکل در نقص یا کمبود ÙØ§ÛŒÙ„ های اجرایی GTA:SA, لانچر MTA:SA نمی تواند اجرا شود:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "بررسی کنید Ú©Ù‡ آنتی ویروس شما به اشتباه ÙØ§ÛŒÙ„ اجرایی GTA:SA بعنوان ویروس شناسایی نکرده باشد سعی کنید ÙØ§ÛŒÙ„ اجرایی GTA:SA را در لیست استثناها قراردهید Ùˆ MTA:SA را راه‌اندازی مجدد کنید." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "ساختن GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA اجرا نشد زیرا ÙØ§ÛŒÙ„ اجرایی GTA:SA قابل بارگذاری نیست:" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "بسته تکمیلی GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA اجرا نشد زیرا اعمال بسته تکمیلی GTA:SA با شکست مواجه شد:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "خطا در اجرای Grand Theft Auto: San Andreas. Ù„Ø·ÙØ§ MTA را دوباره راه‌ اندازی کنید، اگر همچنان با خطا مواجه شدید با MTA در www.multitheftauto.com تماس بگیرید.\n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA نمی تواند ادامه دهد زیرا محل ذخیره سایزی %s ÙØ¶Ø§ÛŒ کاÙÛŒ ندارد‎â€â€Žâ€ªâ€Žâ€." -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas ممکن است به درستی اجرا نشده باشد. آیا Ù…ÛŒ خواهید آن را ببندید؟" +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "ÙØ§ÛŒÙ„ ÛŒØ§ÙØª نشده:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "اگر MTA در بارگزاری شکست خورد، Ù„Ø·ÙØ§ GTA:SA را مجدد نصب کنید" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "بروزرسانی تنظیمات نصب" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "بروزرسانی تنظیمات سازگاری" #. ///////////////////////////////////////////////////////////////////////// #. @@ -270,167 +487,167 @@ msgstr "GTA: San Andreas ممکن است به درستی اجرا نشده با #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "بله" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "خیر" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "تایید" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "خروج" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Ú©Ù…Ú©" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "لغو" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas به مشکل برخورده است." -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "اطلاعات کرش" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "برای ارسال اطلاعات این کرش به توسعه دهندگان ام تی ای از طریق اینترنت Ú†Ú© باکس را تیک بزنید" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "انجام اینکار احتمال کرش شدن را زیاد Ù…ÛŒ کند." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "آیا Ù…ÛŒ خواهید MTA: San Andreas را راه‌اندازی مجدد کنید؟" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "ام تی ای: سن آندریاس - اخطار" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "محل نصب Grand Theft Auto: San Andreas شما شامل این ÙØ§ÛŒÙ„‌ها است:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "وجود این ÙØ§ÛŒÙ„ ها الزامی نیست Ùˆ ممکن است با عملکرد های گراÙیکی این نسخه MTA:SA تداخل ایجاد کند.\n\n" "پیشنهاد میشود Ú©Ù‡ این ÙØ§ÛŒÙ„ ها را حذ٠یا تغییر نام دهید." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "ÙØ§ÛŒÙ„ ها را نگهدار اما همچنان در اجرای بعدی این هشدار را نشان بده" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "این ÙØ§ÛŒÙ„ ها را به من یاداوری Ù†Ú©Ù†" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "نام این ÙØ§ÛŒÙ„ ها را از.dll به.dll.bak تغییر بده" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "این ÙØ§ÛŒÙ„ ها را به من نشان بده" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "اجرای MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - تنظیمات گیج کننده" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus شناسایی شد!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "گزینه های زیر را امتحان کنید Ùˆ ببیند کدام جواب میدهد:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "ال٠- Nvidia استاندارد" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "ب - NVidia جایگزین" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "Ù¾ - Intel استاندارد" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "ت - Intel جایگزین" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "اگر ناامید شدید، ممکن است این کمکتان کند:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "اگر تا به حال گزینه ای را Ú©Ù‡ کار میکند را انتخاب کردید، این ممکن است کمکتان کند:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "حالت پنجره ای اجباری" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "دیگر نمایش نده" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "هشدار: برنامه آنتی ویروس شناسایی نشد" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -438,1111 +655,1181 @@ msgstr "MTA نتوانست آنتی ویروسی روی کامپیوتر شما "ویروس ها Ù…ÛŒ توانند در تجربه MTA Ùˆ بازی کردن شما اختلال ایجاد کنند.\n\n" "برای دیدن اطلاعات بیشتر روی دکمه 'Ú©Ù…Ú©' کلیک کنید." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "من از قبل آنتی ویروس نصب کرده ام" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "من آنتی ویروس نصب نمی‌کنم.\n" "من می‌خواهم کامپیوترم کند شود Ùˆ قسمتی از یک بات‌نت باشد." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "در حال جستجوی Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Ù„Ø·ÙØ§ Grand Theft Auto San Andreas را اجرا کنید" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "در حال نصب بروزرسانی..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "اتصال ناموÙÙ‚. لقب وارد شده نامعتبر است!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "در حال استخراج ÙØ§ÛŒÙ„ ها..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "اتصال ناموÙÙ‚. آدرس وارد شده نامعتبر است!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "در حال Ú©Ù¾ÛŒ ÙØ§ÛŒÙ„ ها..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "اتصال به %s با پورت %u ناموÙÙ‚ بود!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Ú©Ù¾ÛŒ زود تمام شد. همه Ú†ÛŒ اوکیه." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "در حال اتصال به %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "در حال اتمام..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "اتصال مجدد به %s:%u..." -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "انجام شد!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "در حال اتصال" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA برای عملیات های زیر نیاز به دسترسی ناظر دارد:\n\n" -"'%s'\n\n" -"Ù„Ø·ÙØ§ در پنجره بعدی تایید کنید." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "اتصال منقضی شد" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA نتوانست عملیات های زیر را انجام دهد:\n\n" -"'%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "اتصال قطع شد: خطای پروتوکل ناشناخته" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** دلیل خرابی به خاطر خطای درایور کارت گراÙیک است **\n\n" -"** Ù„Ø·ÙØ§ درایور کارت گراÙیک خود را بروزرسانی نمایید **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "اتصال قطع شد: قطع اتصال از راه دور" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "نصب ÙØ§ÛŒÙ„ های بروزرسانی شده MTA:SA" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "قطع اتصال: ارتباط از راه دور قطع شد" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "به دلیل درگیر بودن ÙØ§ÛŒÙ„ ها نمی توان بروزرسانی کرد. Ù„Ø·ÙØ§ برنامه های دیگر را بسته Ùˆ مجددا تلاش کنید" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "قطع اتصال: شما از این سرور محروم شده اید" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "قطع اتصال: شما از سرور قطع اتصال کردید" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "قطع اتصال: ارتباط با سرور قطع شد" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "قطع اتصال: ارتباط با سرور رد شد" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "مولتی Ø¯ÙØª آتو به درستی نصب نشده است, Ù„Ø·ÙØ§ دوباره نصب کنید. %s" +msgid "No such mod installed (%s)" +msgstr "مود مورد نظر نصب نشده است (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "اتصالات GTA:SA را بسازید" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "پاسخ بد از سرور (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA اجرا نشد زیرا Ú©Ù¾ÛŒ یک ÙØ§ÛŒÙ„ با شکست مواجه شد:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "پاسخ بد از سرور (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA اجرا نشد زیرا برخی ÙØ§ÛŒÙ„ ها خراب یا وجود ندارند:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "پارسی" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Ú©Ù¾ÛŒ کردن ÙØ§ÛŒÙ„ های MTA:SA" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "مشغول" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA اجرا نشد زیرا برخی ÙØ§ÛŒÙ„ های GTA:SA خراب یا وجود ندارند:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "در حال حاضر نمی توان برای بروزرسانی بررسی کرد." -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "بسته تکمیلی پیشنیاز های GTA:SA" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "نسخه %s MTA:SA نیار است" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA اجرا نشد زیرا ÙØ§ÛŒÙ„ اجرایی GTA:SA وجود ندارد یا خراب است:\n" -"به دلیل مشکل در نقص یا کمبود ÙØ§ÛŒÙ„ های اجرایی GTA:SA, لانچر MTA:SA نمی تواند اجرا شود:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "برای اتصال به این سرور نسخه MTA:SA %s لازم است. \n\n" +"آیا Ù…ÛŒ خواهید این نسخه را دانلود Ùˆ نصب نمایید؟" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "بررسی کنید Ú©Ù‡ آنتی ویروس شما به اشتباه ÙØ§ÛŒÙ„ اجرایی GTA:SA بعنوان ویروس شناسایی نکرده باشد سعی کنید ÙØ§ÛŒÙ„ اجرایی GTA:SA را در لیست استثناها قراردهید Ùˆ MTA:SA را راه‌اندازی مجدد کنید." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "آیا Ù…ÛŒ خواهید MTA:SA %s اجرا Ùˆ به این سرور متصل شود؟" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "ساختن GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "برقراری اتصال در حال حاضر امکان پذیر نمی باشد.\n\n" +"Ù„Ø·ÙØ§ بعدا تلاش نمایید." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA اجرا نشد زیرا ÙØ§ÛŒÙ„ اجرایی GTA:SA قابل بارگذاری نیست:" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "در حال اتصال" + +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Ù„Ø·ÙØ§ منتظر بمانید..." -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "بسته تکمیلی GTA:SA" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "در حال بررسی" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA اجرا نشد زیرا اعمال بسته تکمیلی GTA:SA با شکست مواجه شد:" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "بررسی بروزرسانی" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA نمی تواند ادامه دهد زیرا محل ذخیره سایزی %s ÙØ¶Ø§ÛŒ کاÙÛŒ ندارد‎â€â€Žâ€ªâ€Žâ€." +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "نیازی به بروزرسانی نیست" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "ÙØ§ÛŒÙ„ ÛŒØ§ÙØª نشده:" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "در حال دانلود" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "اگر MTA در بارگزاری شکست خورد، Ù„Ø·ÙØ§ GTA:SA را مجدد نصب کنید" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "در حال انتظار..." -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "بروزرسانی تنظیمات نصب" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "بروزرسانی اجباری" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "بروزرسانی تنظیمات سازگاری" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "برای ورود به این سرور باید MTA خود را بروزرسانی نمایید.\n\n" +"آیا Ù…ÛŒ خواهید همین الان بروزرسانی کنید؟" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "ناشناخته" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "بروزرسانی اختیاری" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "ÙØ§ÛŒÙ„ '%s' در حال حاضر توسط ÙØ±Ø¢ÛŒÙ†Ø¯Ù‡Ø§ÛŒ %zu Ù‚ÙÙ„ شده است.\n\n" -"آیا Ù…ÛŒ خواهید ÙØ¹Ø§Ù„یت زیر را خاتمه دهید Ùˆ به بروزرسانی ادامه دهید؟\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "سرور: بروزرسانی MTA پیشنهاد Ù…ÛŒ شود اما اجباری نیست.\n\n" +"آیا Ù…ÛŒ خواهید همین الان بروزرسانی کنید؟" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "ÙØ±Ø§ÛŒÙ†Ø¯ نصب شما ممکن است در حال حاضر خراب باشد.\n\n" -"ÙØ§ÛŒÙ„ %zu از %zu از نسخه پشتیبان نمیتواند بازیابی شود.\n\n" -"میبایست Multi Theft Auto را از www.multitheftauto.com دوباره نصب کنید\n" -"یا سعی کنید بروزرسانی را با دسترسی administrator اجرا کنید." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "هم‌اکنون به‌روزرسانی در دسترس نیست.\n\n" +"Ù„Ø·ÙØ§ www.multitheftauto.com را بررسی کنید" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "بازی Grand Theft Auto: San Andreas را اجرا کنید.\n" -"اطمینان حاصل کنید Ú©Ù‡ بازی در پوشه 'Program Files (x86)' قرار دارد." +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "خطا در ذخیره‌سازی" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "درحال جستجو GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "خطا در ایجاد ÙØ§ÛŒÙ„." -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "متاسÙÙ…ØŒ بازی پیدا نشد.\n" -"بازی Grand Theft Auto: San Andreas را اجرا کنید Ùˆ روی \"تلاش مجدد\" کلیک کنید.\n" -"اطمینان حاصل کنید Ú©Ù‡ بازی در پوشه 'Program Files (x86)' قرار دارد." +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "خطا در دانلود کردن" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Ù„Ø·ÙØ§Ù‹ محل نصب بازی Grand Theft Auto: San Andreas را انتخاب کنید" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "ÙØ§ÛŒÙ„ دانلود شده به نظر نادرست است." -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "خطا در بارگذاری %s ماژول! (%s)" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "بنا به دلایلی." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "نسخه نصبی جدید %s شناسایی شد.\n\n" -"آیا میخواهید تنظیمات خود را از %s بازیابی کنید؟" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "دانلود انجام شد" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA مشکل در باز کردن ÙØ§ÛŒÙ„ '%s' دارد" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - مشکل ناشناخته در _DialogUpdateResult" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "ÙØ§ÛŒÙ„ '%s' در GTA:SA وجود ندارد." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "ÙØ§ÛŒÙ„ های دستکاری شده GTA:SA" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA در بارگذاری این مدل مشکل داشت." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "تایید" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "اگر به تازگی gta3.img را دستکاری کردید، GTA:SA را مجددا نصب کنید." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "خطا" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA مشکل در Ø§ÙØ²ÙˆØ¯Ù† یک ارتقاء به یک وسیله نقلیه داشت." +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "تعدادی از ÙØ§ÛŒÙ„ های MTA:SA موجود نمی باشند.\n\n\n" +"Ù„Ø·ÙØ§ MTA:SA را مجددا نصب ÙØ±Ù…ایید" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA خطاهایی را در ÙØ§ÛŒÙ„ '%s' پیدا کرد" +msgid "%3d %% completed" +msgstr "%3d %% تکمیل شد" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "آیا کامپیوتر شما هنگام بازی کردن در MTA:SA دوباره راه‌اندازی شد؟" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"منتظر پاسخ - %-3d" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Ù„Ø·ÙØ§Ù‹ قبل از ادامه، از برنامه های زیر خارج شوید:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ Ú©Ù…Ú© دستور ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "درخواست های وبسایت‫" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "زمان %d:%02d:%02d Ù…ÛŒ باشد" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "سرور وبسایت های زیر را برای لود کردن درخواست کرده است (بعدا):" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "اتصال: شبکه آماده نمی‌باشد لحظه ای صبر کنید" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "جهت Ø­ÙØ¸ اطلاعات حساس خود از دزدیده شدن به هیچ عنوان آن ها را وارد ننماید" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "اتصال: نحو 'connect <آدرس> [<پورت> <لقب> <گذرواژه>]'" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "بیاد بسپار" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "اتصال: شماره پورت نادرست" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "اجازه بده" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "اتصال: در حال اتصال به %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "رد Ú©Ù†" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "اتصال: اتصال به %s:%u ناموÙÙ‚!" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:543 -msgid "Main menu" -msgstr "Ùهرست اصلی" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "اتصال: آنلود سازی مود ÙØ¹Ù„ÛŒ ناموÙÙ‚" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "شما از نسخه (نمایش قابلیت جدید) Ø§Ø³ØªÙØ§Ø¯Ù‡ Ù…ÛŒ کنید! این نسخه تست Ù…ÛŒ باشد Ùˆ نمی توان از آن برای اتصال به سرور های عمومی Ø§Ø³ØªÙØ§Ø¯Ù‡ کرد." +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "اتصال مجدد: شبکه آماده نمی‌باشد لحظه ای صبر کنید" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA بعد از ژوئیه 2019 به‌روزرسانی‌های XP/Vista را Ø¯Ø±ÛŒØ§ÙØª نخواهد کرد.\n\n" -"برای بازی کردن در سرور های جدید ویندوز خود را ارتقا دهید." +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "اتصال مجدد: شماره پورت نادرست است" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "این کار شما را از سرور ÙØ¹Ù„ÛŒ قطع اتصال Ù…ÛŒ کند.\n\n" -"آیا مطمئن هستید Ú©Ù‡ Ù…ÛŒ خواهید قطع اتصال کنید؟" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "اتصال مجدد: اتصال مجدد به %s:%u..." -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "اخطار قطع اتصال" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "اتصال مجدد: نتوانست به %s وصل شود:%u!" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "اطلاعات" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Ø§Ø³ØªÙØ§Ø¯Ù‡ از تنظیمات کنترل GTA" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "پارسی" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "ÙØ§ÛŒÙ„ تنظیمات ذخیره شد" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* سریال شما: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "تنظیمات" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Ú†Ù†Ø¯Ù†ÙØ±Ù‡" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "تصویر" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "پست اÙ‌اکس" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "صدا" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "بایند ها" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "کنترل ها" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "رابط کاربری" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "مرورگر وب" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Ù¾ÛŒØ´Ø±ÙØªÙ‡" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "بارگذاری Ù¾ÛŒØ´ÙØ±Ø¶ ها" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "حساسیت موس:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "حساسیت عمودی نشانه گیری:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "گزینه های موس" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "حساسیت عمودی موس" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "ÙØ±Ù…ان دادن با موس" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "پرواز با موس" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "گزینه های Joypad" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "کنترل های استاندارد (موس + کیبورد)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "کنترل های کلاسیک (جوی پد)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "دد زون" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" -msgstr "اشباع رنگ" +msgstr "اشباع" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "از تب 'بایند ها' برای دکمه های جوی پد Ø§Ø³ØªÙØ§Ø¯Ù‡ نمایید." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "استیک Ú†Ù¾" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "استیک راست" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "توضیحات" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "کلید" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "کلید دوم" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "لقب:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "ذخیره گذرواژه سرور ها" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "بروزرسانی خودکار مرورگر سرور ها" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "اجازه آپلود ØµÙØ­Ù‡" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "مجاز کردن صداهای خارجی" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "همیشه پنجره دانلود را نشان بده" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "اجازه برقراری ارتباط با Discord Rich Presence" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "نمایش \"وضعیت درون‌بازی\" GTA:SA را در استیم ÙØ¹Ø§Ù„ Ú©Ù†" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "عکس‌های Ú¯Ø±ÙØªÙ‡â€ŒØ´Ø¯Ù‡ با دوربین را در پوشه‌ی ÙØ§ÛŒÙ„‌های کاربری GTA San Andreas ذخیره کنید" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "پیش از قطع ارتباط با سرور از راه Ùهرست اصلی، پرس‌وجو شود" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Ø§Ø³ØªÙØ§Ø¯Ù‡ از ÙØ§ÛŒÙ„ های Ø³ÙØ§Ø±Ø´ÛŒ شده GTA:SA" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "گزینه های رندرینگ نقشه" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Ø´ÙØ§Ùیت:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "وضوح تصویر:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "1024x1024 (پیش ÙØ±Ø¶)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048x2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "صدای اصلی:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "میزان صدای رادیو:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "میزان صدای اÙکت ها:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "میزان صدای MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "صدای بازیکنان:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "حالت پخش:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "عمومی" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "گزینه های رادیو" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "اکولایزر رادیو" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "تظیم خودکار رادیو" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "گزینه های آهنگ کاربر" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "رادیو" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "تصادÙÛŒ" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "پشت سر هم" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "اسکن اتوماتیک رسانه" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "گزینه های میوت" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "بی صدا بودن تمامی صداها هنگام مینمایز" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "بی صدا بودن رادیو هنگام مینمایز" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "بی صدا بودن اÙکت ها هنگام مینمایز" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "بی صدا کردن MTA هنگام مینیمایز" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "بی صدا بودن تمامی صداها هنگام مینمایز بودن" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "وضوح تصویر:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "ا٠او ÙˆÛŒ:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "محدوده دید:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "روشنایی:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Ú©ÛŒÙیت ا٠اکس:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Ùیلتر بینظیر کردن:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Ø´ÙØ§Ù سازی:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "نسبت ابعاد:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "پنجره ای" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "آگاه DPI" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "استاندارد" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "بی حد Ùˆ مرز Ùˆ رزولوشن ثابت" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "نقشه برداری Mip" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Ú©Ù…" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "متوسط" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "زیاد" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "خیلی زیاد" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "خاموش" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1 برابر" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "دو برابر" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3 برابر" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "خودکار" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "همخوانی نسبت ابعاد با HUD" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "سایه های حجمی" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "اÙکت چمن" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "گرمای هوا" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "دود تایر Ùˆ غیره" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "سایه متحرک کارکترها" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "کدری متحرک" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "بازتاب لامپ های کرونا توسط باران" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "تمام ØµÙØ­Ù‡ مینیمایز" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "ÙØ¹Ø§Ù„‌سازی ØµÙØ­Ù‡Ù” انتخاب دستگاه" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "نمایش وضوح های غیر امن" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "نمایش وسایل نقلیه با جزئیات زیاد" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "نمایش پدها با جزئیات زیاد" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "گاما:" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "کنتراست:" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "غلظت رنگ:" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "اعمال تنظیمات در حالت پنجره‌ای" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "اعمال تنظیمات در حالت ØªÙ…Ø§Ù…â€ŒØµÙØ­Ù‡" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "ÙØ¹Ø§Ù„ کردن وبسایت های از خارجی" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "ÙØ¹Ø§Ù„ سازی Javascript بر روی وبسایت های خارجی" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "ÙØ¹Ø§Ù„ کردن رندر GPU" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "لیست سیاه Ø³ÙØ§Ø±Ø´ÛŒ" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "یک دامنه را وارد کنید. مثال: google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "مسدود کردن" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "دامنه" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "حذ٠دامنه" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "لیست سÙید Ø³ÙØ§Ø±Ø´ÛŒ" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "اجازه بده" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "غیره" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "بارگذاری سریع لباس های CJ:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "سرعت مرورگر:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "اتصال تکی:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "برچسب پکت:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "انیمیشن پیشروی:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "اولویت پردازش:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "تنظیمات اشکال زدایی:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Ø­Ø§ÙØ¸Ù‡ استریم:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "نوع ساختار بروزرسانی:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "نصب بروزرسانی های مهم:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "روشن" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "خیلی کند" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Ù¾ÛŒØ´ÙØ±Ø¶" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "سریع" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "عادی" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "بالاتر از معمول" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "حداقل" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "حداکثر" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "سازگاری با Windows 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "رنگ 16 بیت" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Ø±ÙØ¹ مشکل موس" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "ÙØ§ÛŒÙ„‌های منبع کلاینت:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "نمایش در اکسپلورر" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "برای بهبود عملکرد بازی، وابستگی پردازنده را روی 0 تنظیم کنید" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "بروزرسانی کننده خودکار" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "هم‌اکنون بررسی بروزرسانی را انجام دهید" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "بعضی تنظیمات هنگام اجرای بعدی MTA تغییر خواهند ÛŒØ§ÙØª" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "آیا Ù…ÛŒ خواهید همین الان راه‌اندازی مجدد کنید؟" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "نیازمند راه‌اندازی مجدد" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "با قطع اتصال سرور ÙØ¹Ù„ی، برخی از تنظیمات تغییر خواهند کرد" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "آیا Ù…ÛŒ خواهید همین الان قطع اتصال کنید؟" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "نیاز به قطع اتصال" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad ÛŒØ§ÙØª نشد - اتصالات را بررسی نموده Ùˆ بازی را مجددا اجرا ÙØ±Ù…ایید" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "محور بایند" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "برای بایند، یک محور را تکان دهید یا Esc را برای پاک کردن ÙØ´Ø§Ø± دهید" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "زبان:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "اسکین:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "نمونه ها:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Ú¯ÙØªâ€ŒÙˆÚ¯Ùˆ" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "بارگذاری" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "رنگ ها" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "طرح" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "گزینه ها" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "پس زمینه Ú¯ÙØª Ùˆ Ú¯Ùˆ" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "متن Ú¯ÙØª Ùˆ Ú¯Ùˆ" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "پس زمینه ورودی" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "ورودی متن" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "خط ها:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "مقیاس:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "عرض:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "اندازه" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "پس از" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "برای" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "ثانیه" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "محو سازی" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "محو سازی خط های قدیمی" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "اÙÙ‚ÛŒ:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "عمودی:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "تراز-متن:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-Ø¢ÙØ³Øª:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-Ø¢ÙØ³Øª:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "موقعیت" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Ú†Ù¾" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "وسط" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "راست" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "بالا" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "پایین" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Ùونت" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "مخÙÛŒ کردن پس زمینه هنگام ننوشتن نکردن" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "تکمیل کردن نام مستعار هنگام Ø§Ø³ØªÙØ§Ø¯Ù‡ از کلید \"TAB\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "اجازه به سرور برای چشمک زدن پنجره" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "اجازهٔ نمایش نوار اعلان‌ها" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "هایلایت سیاه Ùˆ سÙید متن Ú¯ÙØª Ùˆ Ú¯Ùˆ" @@ -1550,112 +1837,116 @@ msgstr "هایلایت سیاه Ùˆ سÙید متن Ú¯ÙØª Ùˆ Ú¯Ùˆ" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "برای بایند کردن کلید مورد نظر ÙØ´Ø§Ø± دهید یا برای پاک کردن Escape را ÙØ´Ø§Ø± دهید" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "بایند کردن یک کلید اصلی" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "بایند کردن یک کلید ÙØ±Ø¹ÛŒ" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "کنترل های بازی GTA" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "کنترل های آنلاین" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "نام مستعار وارد شده حاوی کاراکتر های غیرمجاز است!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1099 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Ùهرست اصلی" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "در بازی" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "قرمز:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "سبز:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "آبی:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Ø´ÙØ§Ùیت:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "رنگ" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "پیش نمایش" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Ù„Ø·ÙØ§ قبل از تغییر زبان قطع اتصال کنید" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Ù„Ø·ÙØ§ قبل از تغییر اسکین قطع اتصال کنید" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "سایه های حجمی Ù…ÛŒ تواند باعث کند در بعضی سیستم های شود. \n\n" "آیا برای ÙØ¹Ø§Ù„ سازی اطمینان دارید؟" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "هشدار عملکرد" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "آپلود ØµÙØ­Ù‡ برای برخی از سرور ها به منظور آنتی-چیت نیاز است.\n\n" "(محدوده Ú¯ÙØª Ùˆ Ú¯Ùˆ Ùˆ رابط کاربری آپلود نخواهند شد)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "مشخصات آپلود ØµÙØ­Ù‡" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "بعضی از اسکریپت ها ممکن است صداهایی را از اینترنت پخش کنند. مانند رادیو Ùˆ غیره.\n\n" "ØºÛŒØ±ÙØ¹Ø§Ù„ کردن این تنظیمات ممکن است باعث کاهش مصر٠پهنای باند شبکه ارتباطی شود." -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "صداهای خارجی" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "به نظر Ù…ÛŒ رسد Ú©Ù‡ گزینه اتصال Rich Presence را ÙØ¹Ø§Ù„ کرده اید.\n" -"آیا به سرورها اجازه می‌دهید داده های خود را به اشتراک بگذارند؟\n\n" -"این شامل شناسه منحصر Ø¨ÙØ±Ø¯ شما نیز می‌شود." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "رضایت برای اجازه به اشتراک گذاری داده‌ها" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1663,13 +1954,9 @@ msgid "Some files in your GTA:SA data directory are customized.\n" msgstr "بعضی از ÙØ§ÛŒÙ„ ها GTA:SA شما دستکاری شده اند.\n" "MTA تنها در صورت تیک خوردن این Ú†Ú© باکس از این ÙØ§ÛŒÙ„ ها Ø§Ø³ØªÙØ§Ø¯Ù‡ Ù…ÛŒ کند.\n\n" "با این حال، خیلی از سرور ها دستکاری ÙØ§ÛŒÙ„ های GTA:SA را بلاک کرده اند.\n\n" -"آیا برای Ø§Ø³ØªÙØ§Ø¯Ù‡ از این ÙØ§ÛŒÙ„ ها اطمینان دارید؟" - -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "ÙØ§ÛŒÙ„ های دستکاری شده GTA:SA" +"آیا برای Ø§Ø³ØªÙØ§Ø¯Ù‡ از این ÙØ§ÛŒÙ„ ها اطمینان دارید؟" -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1677,552 +1964,253 @@ msgid "Enabling DPI awareness is an experimental feature and\n" msgstr "ÙØ¹Ø§Ù„ کردن DPI Awareness این قابلیت تستی است Ùˆ Ø§Ø³ØªÙØ§Ø¯Ù‡ آن را در مانیتور مقیاس شده پیشنهاد میکنیم. احتمال بروز مشکلات گراÙیکی پس از ÙØ¹Ø§Ù„ سازی امکان پذبر است.\n\n" "آیا از ÙØ¹Ø§Ù„ سازی اطمینان دارید؟" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "قابلیت آزمایشی" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "ØºÛŒØ±ÙØ¹Ø§Ù„ کردن این گزینه توصیه نمیشود جز در مواردی Ú©Ù‡ دچار مشکلاتی در عملکرد بازی هستید.\n\n" "از ØºÛŒØ±ÙØ¹Ø§Ù„ کردن آن مطمئنید؟" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Ù„Ø·ÙØ§ یک نام مستعار وارد نمایید" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Ù„Ø·ÙØ§Ù‹ یک نام مستعار برای Ø§Ø³ØªÙØ§Ø¯Ù‡ در بازی وارد نمایید.\n" "این نام، زمانی Ú©Ù‡ به سرور متصل می‌شوید Ùˆ بازی می‌کنید، نمایش داده می‌شود" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "قابلیت بسیار آزمایشی." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "توق٠لگ احتمالی CJ (65 مگابایت رم بیشتر مصر٠می کند)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "ممکن است روتر های قدیمی نیاز به سرعت جستجوی پایین‌تر داشته باشند." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "تنها برای دانلود تک اتصالی روشن نمایید." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "بسته های شبکه را برای Ú©Ù…Ú© به ISP ها در شناسایی تراÙیک MTA برچسب گذاری کنید." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "دایره در حال چرخش پایین ØµÙØ­Ù‡" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "انتخاب Ù¾ÛŒØ´ÙØ±Ø´ همیشه. (این تظیمات ذخیره نشده است)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "حداکثر همیشه بهتر است" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "بروزرسانی کننده خودکار:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Ù¾ÛŒØ´ÙØ±Ø¶ را انتحاب نمایید مگر آنکه تمایل به پر کردن ÙØ±Ù… گزارش خرابی را دارید." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "برای Ø¯Ø±ÛŒØ§ÙØª خودکار بروزرسانی‌های مهم Ù¾ÛŒØ´ÙØ±Ø¶ را انتخاب نمایید." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "رنگ 16 بیت:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "ÙØ¹Ø§Ù„سازی حالت رنگ 16 بیت - MTA نیاز به راه اندازی مجدد دارد" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Ø±ÙØ¹ اشکال موس:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Ø±ÙØ¹ اشکال موس - ممکن است نیاز به راه انداری مجدد رایانه باشد" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "وابستگی پردازنده (CPU):" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "Ùقط در صورتی Ú©Ù‡ دچار مشکلات پایداری عملکرد بازی هستید، آن را تغییر دهید." -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "ÙØ±Ù…ان یا دستور ناشناخته: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "مشغول" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "در حال حاضر نمی توان برای بروزرسانی بررسی کرد." - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "نسخه %s MTA:SA نیار است" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "برای اتصال به این سرور نسخه MTA:SA %s لازم است. \n\n" -"آیا Ù…ÛŒ خواهید این نسخه را دانلود Ùˆ نصب نمایید؟" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "آیا Ù…ÛŒ خواهید MTA:SA %s اجرا Ùˆ به این سرور متصل شود؟" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "برقراری اتصال در حال حاضر امکان پذیر نمی باشد.\n\n" -"Ù„Ø·ÙØ§ بعدا تلاش نمایید." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "در حال اتصال" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Ù„Ø·ÙØ§ منتظر بمانید..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "در حال بررسی" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "بررسی بروزرسانی" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "نیازی به بروزرسانی نیست" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "در حال دانلود" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "در حال انتظار..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "بروزرسانی اجباری" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "برای ورود به این سرور باید MTA خود را بروزرسانی نمایید.\n\n" -"آیا Ù…ÛŒ خواهید همین الان بروزرسانی کنید؟" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "بروزرسانی اختیاری" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "سرور: بروزرسانی MTA پیشنهاد Ù…ÛŒ شود اما اجباری نیست.\n\n" -"آیا Ù…ÛŒ خواهید همین الان بروزرسانی کنید؟" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "هم‌اکنون به‌روزرسانی در دسترس نیست.\n\n" -"Ù„Ø·ÙØ§ www.multitheftauto.com را بررسی کنید" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "خطا در ذخیره‌سازی" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "خطا در ایجاد ÙØ§ÛŒÙ„." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "خطا در دانلود کردن" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "ÙØ§ÛŒÙ„ دانلود شده به نظر نادرست است." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "بنا به دلایلی." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "دانلود انجام شد" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - مشکل ناشناخته در _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "تایید" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "خطا" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "تعدادی از ÙØ§ÛŒÙ„ های MTA:SA موجود نمی باشند.\n\n\n" -"Ù„Ø·ÙØ§ MTA:SA را مجددا نصب ÙØ±Ù…ایید" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% تکمیل شد" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"منتظر پاسخ - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "اتصال ناموÙÙ‚. لقب وارد شده نامعتبر است!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "اتصال ناموÙÙ‚. آدرس وارد شده نامعتبر است!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "اتصال به %s با پورت %u ناموÙÙ‚ بود!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "در حال اتصال به %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "اتصال مجدد به %s:%u..." - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:667 -msgid "CONNECTING" -msgstr "در حال اتصال" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1343 -msgid "Connection timed out" -msgstr "اتصال منقضی شد" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1391 -msgid "Disconnected: unknown protocol error" -msgstr "اتصال قطع شد: خطای پروتوکل ناشناخته" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 -msgid "Disconnected: disconnected remotely" -msgstr "اتصال قطع شد: قطع اتصال از راه دور" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1399 -msgid "Disconnected: connection lost remotely" -msgstr "قطع اتصال: ارتباط از راه دور قطع شد" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1403 -msgid "Disconnected: you are banned from this server" -msgstr "قطع اتصال: شما از این سرور محروم شده اید" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1411 -msgid "Disconnected: disconnected from the server" -msgstr "قطع اتصال: شما از سرور قطع اتصال کردید" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1415 -msgid "Disconnected: connection to the server was lost" -msgstr "قطع اتصال: ارتباط با سرور قطع شد" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1423 -msgid "Disconnected: connection was refused" -msgstr "قطع اتصال: ارتباط با سرور رد شد" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "مود مورد نظر نصب نشده است (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "پاسخ بد از سرور (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "پاسخ بد از سرور (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "اخبار" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "مشاهده آخرین مقاله خبری" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "کنسول" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "خطای جدی" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "برای درست کردن، این ÙØ§ÛŒÙ„ را حذ٠کنید:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "ماژول %s نادرست است!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "خطا در اجرای لینک" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "این ØµÙØ­Ù‡ راهنما" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "از برنامه خارج Ù…ÛŒ شود" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "نسخه را نشان Ù…ÛŒ دهد" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "زمان را نشان Ù…ÛŒ دهد" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "HUD را نشان Ù…ÛŒ دهد" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "تمامی بایند ها را نشان Ù…ÛŒ دهد" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "سریال شما را نشان Ù…ÛŒ دهد" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "اتصال به یک سرور (آدرس پورت لقب رمز)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "اتصال به سرور پیشین" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "یک کلید را بایند Ù…ÛŒ کند (کلید کنترل)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "یک کلید را آنباید Ù…ÛŒ کند (کلید)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "تنظیمات کنترل Ù¾ÛŒØ´ÙØ±Ø¶ GTA را Ú©Ù¾ÛŒ Ù…ÛŒ کند" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "یک اسکرین شات را خروجی Ù…ÛŒ دهد" -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "Ø¨Ù„Ø§ÙØ§ØµÙ„Ù‡ تنظیمات را ذخیره Ù…ÛŒ کند" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "نمای اشکال زدایی را پاک Ù…ÛŒ کند" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "محدوده Ú¯ÙØª Ùˆ Ú¯Ùˆ را به سمت بالا اسکرول Ù…ÛŒ کند" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "محدوده Ú¯ÙØª Ùˆ Ú¯Ùˆ را به سمت پایین اسکرول Ù…ÛŒ کند" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "اشکال زدایی را به سمت بالا اسکرول Ù…ÛŒ کند" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "اشکال زدایی را به سمت پایین اسکرول Ù…ÛŒ کند" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "جزییات Ø­Ø§ÙØ¸Ù‡ را نشان Ù…ÛŒ دهد" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "زمانبندی ÙØ±ÛŒÙ… را به صورت نمودار نشان Ù…ÛŒ دهد" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "برای توسعه دهندگان: بروزرسانی اخبار" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ Ú©Ù…Ú© دستور ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "زمان %d:%02d:%02d Ù…ÛŒ باشد" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "اتصال: شبکه آماده نمی‌باشد لحظه ای صبر کنید" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "اتصال: نحو 'connect <آدرس> [<پورت> <لقب> <گذرواژه>]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "اتصال: شماره پورت نادرست" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "اتصال: در حال اتصال به %s:%u..." - -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "اتصال: اتصال به %s:%u ناموÙÙ‚!" +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "Ø¨Ù„Ø§ÙØ§ØµÙ„Ù‡ تنظیمات را ذخیره Ù…ÛŒ کند" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "اتصال: آنلود سازی مود ÙØ¹Ù„ÛŒ ناموÙÙ‚" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "نمای اشکال زدایی را پاک Ù…ÛŒ کند" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "اتصال مجدد: شبکه آماده نمی‌باشد لحظه ای صبر کنید" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "محدوده Ú¯ÙØª Ùˆ Ú¯Ùˆ را به سمت بالا اسکرول Ù…ÛŒ کند" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "اتصال مجدد: شماره پورت نادرست است" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "محدوده Ú¯ÙØª Ùˆ Ú¯Ùˆ را به سمت پایین اسکرول Ù…ÛŒ کند" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "اتصال مجدد: اتصال مجدد به %s:%u..." +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "اشکال زدایی را به سمت بالا اسکرول Ù…ÛŒ کند" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "اتصال مجدد: نتوانست به %s وصل شود:%u!" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "اشکال زدایی را به سمت پایین اسکرول Ù…ÛŒ کند" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Ø§Ø³ØªÙØ§Ø¯Ù‡ از تنظیمات کنترل GTA" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "جزییات Ø­Ø§ÙØ¸Ù‡ را نشان Ù…ÛŒ دهد" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "ÙØ§ÛŒÙ„ تنظیمات ذخیره شد" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "زمانبندی ÙØ±ÛŒÙ… را به صورت نمودار نشان Ù…ÛŒ دهد" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* سریال شما: %s" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "برای توسعه دهندگان: بروزرسانی اخبار" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "محور گاز" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "شما از نسخه (نمایش قابلیت جدید) Ø§Ø³ØªÙØ§Ø¯Ù‡ Ù…ÛŒ کنید! این نسخه تست Ù…ÛŒ باشد Ùˆ نمی توان از آن برای اتصال به سرور های عمومی Ø§Ø³ØªÙØ§Ø¯Ù‡ کرد." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "محور ترمز" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA بعد از ژوئیه 2019 به‌روزرسانی‌های XP/Vista را Ø¯Ø±ÛŒØ§ÙØª نخواهد کرد.\n\n" +"برای بازی کردن در سرور های جدید ویندوز خود را ارتقا دهید." -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "برنامه نویسی" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "این کار شما را از سرور ÙØ¹Ù„ÛŒ قطع اتصال Ù…ÛŒ کند.\n\n" +"آیا مطمئن هستید Ú©Ù‡ Ù…ÛŒ خواهید قطع اتصال کنید؟" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "مشارکت کنندگان" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "اخطار قطع اتصال" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "طراحی بازی / اسکریپ نویسی" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "اطلاعات" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "بومی سازی زبان" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "اخبار" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "اهدا کنندگان بسته تکمیلی" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "مشاهده آخرین مقاله خبری" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "تشکر ویژه" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "حجم اسکرین شات %d بایت Ù…ÛŒ باشد، ولی باید %d بایت Ù…ÛŒ بود" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "این برنامه Ùˆ پروژه از کتابخانه ها Ùˆ Ù†Ø±Ù…â€ŒØ§ÙØ²Ø§Ø± های زیر Ø§Ø³ØªÙØ§Ø¯Ù‡ Ù…ÛŒ کند:" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "خطای اسکرین شات" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "آیا Ù…ÛŒ خواهید در مورد این مشکل راهنمای آنلاین را مشاهده نمایید؟" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "اسکرین شات Ú¯Ø±ÙØªÙ‡ شد: '%s'" + +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "ÙØ±Ù…ان یا دستور ناشناخته: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2397,31 +2385,117 @@ msgid "Group control backwards" msgstr "کنترل گروه عقب" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "اسکین انتخابی شما نمی تواند باگذاری شود، همچنین اسکین های Ù¾ÛŒØ´ÙØ±Ø¶ØŒ Ù„Ø·ÙØ§ مجددا MTA را نصب نمایید." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "حجم اسکرین شات %d بایت Ù…ÛŒ باشد، ولی باید %d بایت Ù…ÛŒ بود" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "آیا Ù…ÛŒ خواهید در مورد این مشکل راهنمای آنلاین را مشاهده نمایید؟" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "خطای اسکرین شات" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "کنسول" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "اسکرین شات Ú¯Ø±ÙØªÙ‡ شد: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "برنامه نویسی" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "مشارکت کنندگان" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "طراحی بازی / اسکریپ نویسی" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "بومی سازی زبان" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "اهدا کنندگان بسته تکمیلی" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "تشکر ویژه" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "این برنامه Ùˆ پروژه از کتابخانه ها Ùˆ Ù†Ø±Ù…â€ŒØ§ÙØ²Ø§Ø± های زیر Ø§Ø³ØªÙØ§Ø¯Ù‡ Ù…ÛŒ کند:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "محور گاز" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "محور ترمز" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." msgstr "Direct3D9 اجرا نشد.\n\n" "Ù„Ø·ÙØ§ از آخرین نسخه بودن DirectX Ùˆ سرویس Ù¾Ú©/بروزرسانی ویندوز خود اطمینان حاصل ÙØ±Ù…ایید." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "بیکار" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "بازیکن" +msgstr[1] "بازیکنان" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "روشن" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "سرور" +msgstr[1] "سرورها" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "در حال درخواست Ùهرست سرور اصلی (%lu میلی ثانیه گذشته)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "نمی توان Ùهرست سرور را تحلیل کرد." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "نمی توان Ùهرست سرور را Ø¯Ø±ÛŒØ§ÙØª کرد." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(پشتیبانی Ùهرست سرور)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "نمی توان پخش شبکه لن را بایند سوکت کرد" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "تلاش برای ÛŒØ§ÙØªÙ† سرور های لن" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2475,7 +2549,7 @@ msgstr "تاخیر:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Ùهرست بازیکن‌ها" @@ -2502,40 +2576,39 @@ msgstr "ورود به سرور در اولین موقعیتی Ú©Ù‡ سرور جا msgid "PLEASE ENTER SERVER PASSWORD" msgstr "Ù„Ø·ÙØ§ گذرواژه سرور را وارد نمایید" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "تایم اوت شد" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Ø¯Ø±ÛŒØ§ÙØª اطلاعات..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "سرورها" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "اینترنت" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "محلی" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "مورد علاقه ها" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "اخیر" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2543,298 +2616,367 @@ msgstr "برای اتصال سریع\n\n" "آدرس Ùˆ پورت را وارد نمایید.\n" "یا سرور مورد نظر را از لیست سوابق انتحاب نموده Ùˆ 'اتصال' را ÙØ´Ø§Ø± دهید." -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "Ú©Ù…Ú©" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "بارگذاری مجدد" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "اضاÙÙ‡ به مورد علاقه ها" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "اتصال" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "اطلاعات سرور" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "جستجوی سرورها" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "جستجوی بازیکنان" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "شروع جستجو" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "جستجوی بازیکنان..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "جستجوی سرورها..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "نام" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "بازیکنان" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "پینگ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "گیم مود" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "شامل:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "خالی" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "پر" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Ù‚ÙÙ„ شده" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Ø¢Ùلاین" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "نسخه های دیگر" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "بازگشت" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "درحال بارگذاری..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "..درحال بارگذاری.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "هیچ آدرسی وارد نشده است!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "پروتوکل ناشناخته" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Ù„Ø·ÙØ§ از پروتوکل mtasa:// Ø§Ø³ØªÙØ§Ø¯Ù‡ نمایید!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:651 -#: Client/mods/deathmatch/logic/CClientGame.cpp:749 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "نام مستعار نادرست! Ù„Ø·ÙØ§ به تنظیمات Ø±ÙØªÙ‡ Ùˆ نام مستعار جدیدی ثبت نمایید!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "برای اتصال سروری را انتخاب نمایید." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "بیکار" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "مشکل با درایور گراÙیک" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "بازیکن" -msgstr[1] "بازیکنان" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "اندازه‌ی ØµÙØ­Ù‡ متناسب پیدا نشد." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "روشن" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "آیا مطمئنید میخواهید از این اندازه‌ی ØµÙØ­Ù‡ Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید؟" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "سرور" -msgstr[1] "سرورها" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "عدم موÙقیت در راه‌اندازی بازی game_sa" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "در حال درخواست Ùهرست سرور اصلی (%lu میلی ثانیه گذشته)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "عدم موÙقیت در اختصاص دادن Ø­Ø§ÙØ¸Ù‡" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "نمی توان Ùهرست سرور را تحلیل کرد." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "درخواست های وبسایت‫" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "نمی توان Ùهرست سرور را Ø¯Ø±ÛŒØ§ÙØª کرد." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "سرور وبسایت های زیر را برای لود کردن درخواست کرده است (بعدا):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(پشتیبانی Ùهرست سرور)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "جهت Ø­ÙØ¸ اطلاعات حساس خود از دزدیده شدن به هیچ عنوان آن ها را وارد ننماید" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "نمی توان پخش شبکه لن را بایند سوکت کرد" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "بیاد بسپار" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "تلاش برای ÛŒØ§ÙØªÙ† سرور های لن" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "رد Ú©Ù†" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "این نسخه منقضی شده است." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "از بازی قطع اتصال میکند" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "نمایش برجسب‌های نام" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "محدوده Ú¯ÙØª Ùˆ Ú¯Ùˆ را نشان Ù…ÛŒ دهد" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "جزییات شبکه را نشان Ù…ÛŒ دهد" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "ورودی Ú¯ÙØª Ùˆ Ú¯Ùˆ را باز میکند" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "صدا را به بازیکنان دیگر منتقل Ù…ÛŒ کند" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "به عنوان Ù…Ø³Ø§ÙØ± وارد ماشین Ù…ÛŒ شود" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "کانال رادیویی بعدی" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "کانال رادیویی قبلی" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "ÙØ¹Ø§Ù„ سازی نمایش نقشه بازیکن" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "بزرگ نمایی نقشه بازیکن" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "Ú©ÙˆÚ†Ú© نمایی نقشه بازیکن" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "حرکت نقشه بازیکن به سمت شمال" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "حرکت نقشه بازیکن به سمت جنوب" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "حرکت نقشه بازیکن به سمت شرق" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "حرکت نقشه بازیکن به سمت غرب" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "متصل کردن نقشه بازیکن" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "کاهش Ø´ÙØ§Ùیت نقشه بازیکن" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "Ø§ÙØ²Ø§ÛŒØ´ Ø´ÙØ§Ùیت نقشه بازیکن" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "تغییر وضعیت متن راهنمای نقشه بازیکن" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "پیامی را به بازیکن مورد نظر ارسال می‌کند" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "درون ماشین اسلحه را به بعدی تغییر میدهد" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "درون ماشین اسلحه را به قبلی تغییر میدهد" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "اطلاعات مربوط به سرور ÙØ¹Ù„ÛŒ را خروجی Ù…ÛŒ دهد" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "مقیاس تمام نمایشگرهای متنی را تعری٠می‌کند" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(حالت برنامه‌نویس) تمام colshape ها را قابل مشاهده میکند" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(حالت برنامه‌نویس) شناسه های صدای محیط را در پنجره اشکال زدایی چاپ Ù…ÛŒ کند" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "میزبانی بازی" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "منابع" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "نام سرور:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "گذرواژه:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "حداکثر بازیکنان:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "ارائه:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "شبکه خانگی" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "انتخاب شده" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "همه" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "شروع" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "تغییرد حالت: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "بزرگنمایی: %s/%s حرکت: %sØŒ %sØŒ %sØŒ %s کدورت: %s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "تغییر نقشه: %s تغییر متن راهنما: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "دنبال کردن بازیکن" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "حرکت آزاد" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Ù¾ÛŒØ´Ø±ÙØª دانلود نقشه:" @@ -2855,195 +2997,195 @@ msgstr "%s از %s" msgid "Disconnect to cancel download" msgstr "برای لغو دانلود، اتصال را قطع کنید" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "اتصال قطع شد: نام مستعار نامعتبر" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "قطع ارتباط از سرور" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "اتصال قطع شد: سریال شما محروم شده است.\n" "دلیل: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "اتصال قطع شد: شما محروم شده اید.\n" "دلیل:%s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "اتصال قطع شد: حساب شما محروم شده است.\n" "دلیل: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "اتصال قطع شد: عدم تطابق نسخه" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "اتصال قطع شد: Ù„Ø·ÙØ§Ù‹ یک دقیقه صبر کنید، سپس سعی کنید Ú©Ù‡ دوباره متصل شوید." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "اتصال قطع شد: سرور از شاخه های مختلÙ.\n" "اطلاعات: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "اتصال قطع شد: نسخه بد.\n" "اطلاعات: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "اتصال قطع شد: سرور در حال اجرای یک نسخه جدیدتر است.\n" "اطلاعات: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "اتصال قطع شد: سرور در حال اجرای یک نسخه قدیمی تر است.\n" "اطلاعات: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "اتصال قطع شد: این اسم در حال حاضر در حال Ø§Ø³ØªÙØ§Ø¯Ù‡ میباشد" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "اتصال قطع شد: عنصر (Element) بازیکن ساخته نشد." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "اتصال قطع شد: سرور اتصال را رد کرد: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "اتصال قطع شد: تأیید سریال ناموÙÙ‚ بود" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "قطع ارتباط: سریال از قبل در حال Ø§Ø³ØªÙØ§Ø¯Ù‡ است" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "اتصال قطع شد: عدم همگام سازی اتصال %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "اتصال قطع شد: شما توسط %s از بازی اخراج شدید" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "اتصال قطع شد: شما توسط %s محروم شدید" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "اتصال قطع شد: سرور خاموش یا راه‌اندازی مجدد شد" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "شما از بازی اخراج شدید" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "این سرور به یک gta_sa.exe تغییر ÛŒØ§ÙØªÙ‡ نشده نیاز دارد" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Ù„Ø·ÙØ§ gta_sa.exe را جایگزین کنید" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "این سرور به D3D9.DLL های Ø³ÙØ§Ø±Ø´ÛŒ اجازه ورود نمی دهد" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "D3D9.DLL را از محل نصب GTA خود حذ٠کرده Ùˆ MTA را مجددا راه‌اندازی کنید" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "این سرور به ماشین های مجازی اجازه ورود نمی دهد" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "برای ورود به این سرور نیاز به driver signing دارید" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Ù„Ø·ÙØ§ کامپیوتر خود را مجددا راه‌اندازی کنید" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "سرور بررسی کرد Ùˆ متوجه شده Ú©Ù‡ بعضی قسمت‌های ضد تقلب (Anti-Cheat) وجود ندارند" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "MTA را دوباره راه‌اندازی کنید" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "این سرور به gta3.img Ùˆ gta_int.img تغییر ÛŒØ§ÙØªÙ‡ نشده نیاز دارد" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Ù„Ø·ÙØ§Ù‹ gta3.img یا gta_int.img را جایگزین کنید" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "این سرور اجازه ورود Ø§ÙØ±Ø§Ø¯ توسط برنامه Wine را نمیدهد" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "اطمینان حاصل کنید Ú©Ù‡ هیچ برنامهٔ دیگری در حال تغییر MTA: SA نیست" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "زمان باقی مانده: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d روز" msgstr[1] "روزها %d" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d ساعت" msgstr[1] "%d ساعت ها" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d دقیقه" msgstr[1] "%d دقیقه ها" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3051,296 +3193,206 @@ msgstr[0] "%d ثانیه" msgstr[1] "%d ثانیه ها" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "اتصال قطع شد" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "خطای دانلود: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "پرواز یک بشقاب پرنده در اطراÙ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "گشت Ùˆ گذار در اطراÙ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "موج سواری" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "سوار قطار در" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "پرواز در اطراÙ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:381 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "راندن در اطراÙ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:381 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "کامیون هیولا در اطراÙ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:381 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "کوآد سواری در اطراÙ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:382 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "پریدن به اطراÙ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:382 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "انجام کارهای عجیب Ùˆ غریب در" -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "بالا Ø±ÙØªÙ† از اطراÙ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "شلیک از داخل ماشین در" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "حباب حباب..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "ØªÙ†ÙØ³ آبی" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "غرق شدن در" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "خم شدن برای پناه Ú¯Ø±ÙØªÙ† در" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "مبارزه کردن در" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "حمله با مشت در" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "احمق های بالستین در" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "تیراندازی کردن" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "جت Ù¾Ú© سواری در" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" -msgstr "به معنای واقعی کلمه در حال سوختن" +msgstr "به معنای واقعی کلمه درحال سوختن" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "سوختن در" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "شنا در" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "شناور در اطراÙ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:402 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "تعقیب شدن توسط کوسه" -#: Client/mods/deathmatch/logic/CClientGame.cpp:403 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "Ø®ÙÚ¯ÛŒ تا حد مرگ در" -#: Client/mods/deathmatch/logic/CClientGame.cpp:667 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "در حال ورود به بازی ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:725 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "اتصال برقرار نشد؛ Ù„Ø·ÙØ§ از اتصال سریع یا ÙØ±Ù…ان 'connect' برای اتصال به سرور Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید." -#: Client/mods/deathmatch/logic/CClientGame.cpp:771 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "سرور محلی راه‌اندازی نشد. برای جزئیات بیشتر به کنسول مراجعه کنید." -#: Client/mods/deathmatch/logic/CClientGame.cpp:781 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1253 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "سرور محلی" -#: Client/mods/deathmatch/logic/CClientGame.cpp:781 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "در حال راه‌اندازی سرور محلی ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1029 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "منطقه 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1038 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "قدم زدن در اطرا٠" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1184 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "شما از بازی اخراج شدید ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1253 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "در حال اتصال به سرور محلی..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1264 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "خطا در اتصال به سرور." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "مشکلی در اتصال به سرور محلی وجود داشت. برای جزئیات بیشتر به کنسول مراجعه کنید." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "ارتباط با سرور قطع شد" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1407 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "اتصال قطع شد: سرور در حال حاضر پر است" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1419 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "اتصال قطع شد: گذرواژه اشتباه میباشد" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1441 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "بررسی MTA Client با شکست مواجه شد!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5642 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" -msgstr "در Ø­ÙØ±Ù‡" +msgstr "توی یه گودال" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5642 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "در مسیر بیمارستان" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5642 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "ملاقات با خالقشان" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5643 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "پشیمانی از تصمیمات" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5643 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "از دست Ø±ÙØªÙ†" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "میزبانی بازی" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "منابع" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "نام سرور:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "گذرواژه:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "حداکثر بازیکنان:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "ارائه:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "شبکه خانگی" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "انتخاب شده" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "همه" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "شروع" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "تغییرد حالت: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "بزرگنمایی: %s/%s حرکت: %sØŒ %sØŒ %sØŒ %s کدورت: %s/%s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "تغییر نقشه: %s تغییر متن راهنما: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "دنبال کردن بازیکن" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "حرکت آزاد" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "مشکل با درایور گراÙیک" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "اندازه‌ی ØµÙØ­Ù‡ متناسب پیدا نشد." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "آیا مطمئنید میخواهید از این اندازه‌ی ØµÙØ­Ù‡ Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید؟" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "عدم موÙقیت در راه‌اندازی بازی game_sa" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "عدم موÙقیت در اختصاص دادن Ø­Ø§ÙØ¸Ù‡" +msgid "Download error: %s" +msgstr "خطای دانلود: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3361,11 +3413,11 @@ msgstr "خطای پروتکل (%u). در صورت حل نشدن مشکل، بر msgid "Connection error" msgstr "خطای اتصال" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "مولتی Ø¯ÙØª آتو به درستی نصب نشده است, Ù„Ø·ÙØ§ دوباره نصب نمایید." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "مرورگر شما اکنون یک ØµÙØ­Ù‡ وب با برخی اطلاعات راهنما نمایش Ù…ÛŒ دهد.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/fi_FI/client.pot b/Shared/data/MTA San Andreas/MTA/locale/fi_FI/client.pot index 388a386f7c7..03f7e7fb455 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/fi_FI/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/fi_FI/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:18\n" "Last-Translator: \n" "Language-Team: Finnish\n" "Language: fi_FI\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Ongelmia MTA:SA:n uudelleenkäynnistyksessä\n\n" -"Jos ongelma jatkuu, avaa Tehtävienhallinta ja\n" -"pysäytä \"gta_sa.exe\"- ja \"Multi Theft Auto.exe\" -prosessit\n\n\n" -"Yritetäänkö käynnistää MTA:SA uudelleen?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Virhe" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "MTA on jo käynnissä.\n\n" -"Jos ongelma jatkuu, käynnistä tietokone uudelleen" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "MTA on jo käynnissä.\n\n" -"Haluatko sulkea sen?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Valitse Grand Theft Auto: San Andreaksen asennushakemisto" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA tarvitsee järjestelmänvalvojan käyttöoikeudet seuraavaan tehtävään:\n\n" +" '%s'\n\n" +"Vahvista seuraavassa ikkunassa." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Virhe ladatessa %s moduulia! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Kopioidaan tiedostoja..." -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopiointi valmistui etuajassa. Kaikki OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Viimeistellään…" + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Valmis!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Uusi %s asennus havaittu.\n\n" +"Haluatko kopioida asetuksesi %s:sta?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA törmäsi ongelmaan avatessaan tiedostoa '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA:sta puuttuu tiedosto '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA törmäsi ongelmaan ladatessaan mallia." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Jos muokkasit gta3.img tiedostoa viime aikoina, kokeile asentaa GTA:SA uudelleen." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA törmäsi ongelmaan lisätessään tehostusta ajoneuvoon." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA löysi virheitä tiedostossa '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Käynnistyikö tietokoneesi uudelleen pelatessasi MTA:ta?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Ole hyvä ja lopeta seuraavat ohjelmat ennen jatkamista:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Tiedostojen versiot eivät täsmää. Asenna MTA:SA uudelleen mikäli havaitset ongelmia.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Jotkin tiedostot puuttuvat. Asenna MTA:SA uudelleen mikäli havaitset ongelmia.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA ei ole yhteensopiva Windowsin vikasietotilan kanssa.\n\n" +"Ole hyvä ja käynnistä tietokoneesi uudelleen.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Onko sinulla ongelmia MTA:SA:n käytössä?\n\n" "Haluatko palata aikaisempaan versioon?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "MTA:SA:n käynnistämisessä näyttää olevan ongelma.\n" "GTA-asetusten nollaaminen voi joskus korjata tämän ongelman.\n\n" "Haluatko nollata GTA-asetukset nyt?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA-asetukset on nollattu.\n\n" "Jatka painamalla OK." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Tiedostoa ei voitu poistaa: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Onko sinulla ongelmia MTA:SA:n käytössä?\n\n" "Haluatko etsiä apua tähän ongelmaan?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Onko sinulla ongelmia MTA:SA:n käytössä?\n\n" "Haluatko muuttaa seuraavia asetuksia?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Koko näytön tila:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Reunaton ikkuna" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Onko sinulla ongelmia MTA:SA:n käytössä?\n\n" "Kokeile poistaa käytöstä seuraavat tuotteet GTA:ta ja MTA:ta varten:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,131 +189,293 @@ msgstr "VAROITUS\n\n" "MTA:SA on havainnut epätavallista käytöstä.\n" "Suorita virustarkistus varmistaaksesi, että järjestelmäsi on suojattu.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Havaittu tiedosto oli: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "GTA: San Andreas on jo käynnissä. Se tulee lopettaa ennen kuin MTA:SA voidaan käynnistää. Haluatko tehdä sen nyt?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Tietoja" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "GTA: San Andreasta ei pystytty lopettamaan. Jos ongelma jatkuu, ole hyvä ja käynnistä tietokoneesi uudelleen." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Ongelmia MTA:SA:n uudelleenkäynnistyksessä\n\n" +"Jos ongelma jatkuu, avaa Tehtävienhallinta ja\n" +"pysäytä \"gta_sa.exe\"- ja \"Multi Theft Auto.exe\" -prosessit\n\n\n" +"Yritetäänkö käynnistää MTA:SA uudelleen?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Virhe" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "MTA on jo käynnissä.\n\n" +"Jos ongelma jatkuu, käynnistä tietokone uudelleen" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "MTA on jo käynnissä.\n\n" +"Haluatko sulkea sen?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Rekisteritietoja puuttuu. Ole hyvä ja asenna Multi Theft Auto: San Andreas uudelleen." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "GTA:SA-asennuspolkusi sisältää (unicode) merkkejä joita ei tueta. Ole hyvä ja uudelleenasenna GTA:SA polkuun, joka sisältää vain perinteisiä ASCII-merkkejä ja uudelleenasenna sitten MTA:SA." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "MTA- tai GTA-asennuspolkusi sisältää ';' merkin (puolipisteen).\n\n" -" Jos koet ongelmia MTA:n kanssa, asenna MTA/GTA\n" -" polkuun joka ei sisällä puolipistettä." +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:810 +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Lataus epäonnistui. Ole hyvä ja varmista että viimeisimmät datatiedostot ovat asennettu oikein." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Lataus epäonnistui. Ole hyvä ja varmista että %s on asennettu oikein." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Lataus epäonnistui. gta_sa.exe tiedostoa ei löytynyt polusta %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Lataus epäonnistui. %s löytyi GTA hakemistosta. Ole hyvä ja poista se ennen jatkamista." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Päätiedostolla on väärä nimi (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Päätiedosto on allekirjoittamaton. Mahdollista viruksen toimintaa.\n\n" -"Etsi online-apua mikäli MTA ei toimi oikein." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Datatiedosto %s puuttuu. Mahdollista viruksen toimintaa.\n\n" -"Harkitse MTA:n uudelleenasennusta turvallisuussyistä.\n" -"Etsi apua netistä jos MTA ei toimi oikein." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Datatiedosto %s on muuttunut. Mahdollista viruksen toimintaa.\n\n" -"Harkitse MTA:n uudelleenasennusta turvallisuussyistä.\n" -"Etsi apua netistä jos MTA ei toimi oikein." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asi tiedostoja löytyi 'MTA:SA' tai 'GTA: San Andreas' asennushakemistoista.\n\n" -"Poista nämä .asi tiedostot mikäli havaitset ongelmia MTA:n kanssa." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Tiedostojen versiot eivät täsmää. Asenna MTA:SA uudelleen mikäli havaitset ongelmia.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Jotkin tiedostot puuttuvat. Asenna MTA:SA uudelleen mikäli havaitset ongelmia.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA ei ole yhteensopiva Windowsin vikasietotilan kanssa.\n\n" -"Ole hyvä ja käynnistä tietokoneesi uudelleen.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Korjaa asetukset" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Korjaa oikeudet" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Tuntematon" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "Tiedosto '%s' on lukittuna %zu prosessin toimesta.\n\n" +"Haluatko lopettaa seuraavat prosessit ja jatkaa päivitystä?\n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "Asennuksesi saattaa olla korruptoitunut.\n\n" +"%zu/%zu tiedostoa ei voitu palauttaa varmuuskopiosta.\n\n" +"Asenna Multi Theft Auto uudelleen osoitteesta www.multitheftauto.com\n" +"tai kokeile päivittää järjestelmänvalvojan oikeuksilla." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Asennetaan päivitystä..." -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Puretaan tiedostoja..." + +#: Client/loader/CInstallManager.cpp:391 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Grand Theft Auto: San Andreasta ei voitu käynnistää. Ole hyvä ja kokeile käynnistää tietokoneesi uudelleen, ja jos ongelma jatkuu, ota yhteyttä tukeen osoitteessa www.multitheftauto.com.\n\n" -"[%s]" +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA ei voinut suorittaa seuraavaa tehtävää:\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Ohjelma kaatui grafiikka-ajurin virheen myötä **\n\n" +"** Ole hyvä ja päivitä grafiikka-ajurisi **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas ei välttämättä käynnistynyt oikein. Haluatko lopettaa sen?" +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Asenna päivitetyt MTA:SA-tiedostot" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Päivitys epäonnistui tiedostojen välisen ristiriidan takia. Ole hyvä ja sulje muut sovellukset ja kokeile uudelleen." + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Autoa ei ole asennettu oikein, ole hyvä ja asenna se uudelleen. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "Luo GTA:SA risteykset" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA ei pysty käynnistymään koska tiedoston kopiointi epäonnistui:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA ei pysty käynnistymään koska jokin MTA:n tiedosto on virheellinen tai ei löydy:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Kopioi MTA:SA tiedostot" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA ei pysty käynnistymään koska jokin GTA:SA:n tiedosto on virheellinen tai ei löydy:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "Korjaa GTA:SA riippuvuus" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA ei pysty käynnistymään koska GTA:SA on virheellinen tai ei löydy:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Tarkista antiviruksestasi mahdollinen karanteeni tai muu esto, lisää GTA:SA:lle poikkeus, ja kokeile sitten käynnistää MTA:SA uudelleen." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "Generoi GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA ei pysty käynnistymään koska GTA:SA:ta ei voida ladata käyttöön:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Korjaa GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA ei pysty käynnistymään koska GTA:SA:n korjaus epäonnistui:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA ei voi jatkaa, koska %s levyllä ei ole tarpeeksi tilaa." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Puuttuva tiedosto:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Jos MTA ei lataudu, asenna GTA:SA uudelleen" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Päivitä asennusasetukset" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Päivitä yhteensopivuusasetukset" #. ///////////////////////////////////////////////////////////////////////// #. @@ -271,167 +483,167 @@ msgstr "GTA: San Andreas ei välttämättä käynnistynyt oikein. Haluatko lopet #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Kyllä" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Ei" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "OK" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Lopeta" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Apua" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Peruuta" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas törmäsi ongelmaan" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Tietoa ohjelman kaatumisesta" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Valitse lähettääksesi automaattisen raportin ohjelman kaatumisesta MTA:n kehittäjille" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Lähettäessäsi lisäät todennäköisyyttä että tämä kaatuminen korjataan." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Haluatko käynnistää MTA:n uudelleen?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Varoitus" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "Grand Theft Auto: San Andreas asennushakemistosi sisältää nämä tiedostot:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Näitä tiedostoja ei tarvita ja ne saattavat häiritä MTA:n graafisten ominaisuuksien kanssa.\n\n" "Suosittelemme että poistat tai uudelleennimeät nämä tiedostot." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "Pidä nämä tiedostot ja näytä tämä varoitus seuraavalla kerralla" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Älä muistuta näistä tiedostoista" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Uudelleennimeä nämä *.dll tiedostot *.dll.bak:ksi" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Näytä tiedostot" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Pelaa MTA:ta" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Sekavat asetukset" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus havaittu!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Kokeile jokaista vaihtoehtoa ja katso mikä toimii:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Perinteinen NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Vaihtoehtoinen NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Standard Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Alternate Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Jos tulet epätoivoiseksi, tämä saattaa auttaa:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Jos olet jo valinnut toimivan vaihtoehdon, tämä saattaa auttaa:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Pakota ikkunaan" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Älä näytä uudelleen" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Varoitus: Viruksentorjuntatuotetta ei havaittu" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -439,1107 +651,1180 @@ msgstr "MTA ei pystynyt havaitsemaan virustorjuntaa tietokoneessasi.\n\n" "Virukset häiritsevät MTA:ta ja heikentävät pelikokemustasi.\n\n" "Paina 'Ohje' saadaksesi lisätietoja." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Olen jo asentanut virustorjuntaohjelman" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "En asenna virustorjuntaa.\n" "Haluan tietokoneeni lagaavan ja olevan osa bottiverkkoa." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Etsitään Grand Theft Auto San Andreasia" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Käynnistä Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Asennetaan päivitystä..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Yhdistäminen epäonnistui. Virheellinen nimimerkki!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Puretaan tiedostoja..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Yhdistäminen epäonnistui. Virheellinen isäntä!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Kopioidaan tiedostoja..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Yhdistäminen osoitteeseen %s portissa %u epäonnistui!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopiointi valmistui etuajassa. Kaikki OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Yhdistetään osoitteeseen %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Viimeistellään…" +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Valmis!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "YHDISTETÄÄN" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA tarvitsee järjestelmänvalvojan käyttöoikeudet seuraavaan tehtävään:\n\n" -" '%s'\n\n" -"Vahvista seuraavassa ikkunassa." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Yhteyden aikakatkaisu" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA ei voinut suorittaa seuraavaa tehtävää:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Yhteys katkaistu: isäntä katkaisi yhteyden" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Ohjelma kaatui grafiikka-ajurin virheen myötä **\n\n" -"** Ole hyvä ja päivitä grafiikka-ajurisi **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Yhteys katkaistu: yhteys katkaistu etänä" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Asenna päivitetyt MTA:SA-tiedostot" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Yhteys katkaistu: yhteys menetetty etänä" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Päivitys epäonnistui tiedostojen välisen ristiriidan takia. Ole hyvä ja sulje muut sovellukset ja kokeile uudelleen." +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Yhteys katkaistu: sinulla on porttikielto tälle palvelimelle" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Yhteys katkaistu: palvelin katkaisi yhteyden" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Yhteys katkaistu: yhteys palvelimeen menetetty" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Yhteys katkaistu: yhteys evättiin" -#: Client/loader/CInstallManager.cpp:561 +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Autoa ei ole asennettu oikein, ole hyvä ja asenna se uudelleen. %s" +msgid "No such mod installed (%s)" +msgstr "Modia ei asennettu (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "Luo GTA:SA risteykset" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Virheellinen vastaus palvelimelta (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA ei pysty käynnistymään koska tiedoston kopiointi epäonnistui:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Virheellinen vastaus palvelimelta (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA ei pysty käynnistymään koska jokin MTA:n tiedosto on virheellinen tai ei löydy:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Suomi" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Kopioi MTA:SA tiedostot" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Varattu" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA ei pysty käynnistymään koska jokin GTA:SA:n tiedosto on virheellinen tai ei löydy:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Päivityksiä ei pysty tarkistamaan juuri nyt" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Korjaa GTA:SA riippuvuus" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s vaaditaan" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA ei pysty käynnistymään koska GTA:SA on virheellinen tai ei löydy:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Sinun pitää päivittää MTA:SA %s yhdistääksesi tälle pelipalvelimelle.\n\n" +"Haluatko ladata ja asentaa MTA:SA %s?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Tarkista antiviruksestasi mahdollinen karanteeni tai muu esto, lisää GTA:SA:lle poikkeus, ja kokeile sitten käynnistää MTA:SA uudelleen." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Haluatko käynnistää MTA:SA %s ja yhdistää tähän pelipalvelimeen?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Generoi GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Palvelimelle ei pysty yhdistämään juuri nyt.\n\n" +"Kokeile myöhemmin uudelleen." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA ei pysty käynnistymään koska GTA:SA:ta ei voida ladata käyttöön:" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Yhdistetään" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Korjaa GTA:SA" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Odota hetki..." -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA ei pysty käynnistymään koska GTA:SA:n korjaus epäonnistui:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "TARKISTETAAN" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA ei voi jatkaa, koska %s levyllä ei ole tarpeeksi tilaa." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "PÄIVITYSTARKISTUS" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Puuttuva tiedosto:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Päivitystä ei tarvita" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Jos MTA ei lataudu, asenna GTA:SA uudelleen" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "LADATAAN" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Päivitä asennusasetukset" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "odotetaan..." -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Päivitä yhteensopivuusasetukset" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "PÄIVITYS VAADITAAN" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Tuntematon" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Jotta voit liittyä tälle palvelimelle, sinun on päivitettävä MTA.\n\n" +"Haluatko päivittää sen nyt?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "Tiedosto '%s' on lukittuna %zu prosessin toimesta.\n\n" -"Haluatko lopettaa seuraavat prosessit ja jatkaa päivitystä?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "VALINNAINEN PÄIVITYS" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "Asennuksesi saattaa olla korruptoitunut.\n\n" -"%zu/%zu tiedostoa ei voitu palauttaa varmuuskopiosta.\n\n" -"Asenna Multi Theft Auto uudelleen osoitteesta www.multitheftauto.com\n" -"tai kokeile päivittää järjestelmänvalvojan oikeuksilla." +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Palvelin sanoo, että MTA:n päivitys on suositeltavaa, mutta ei välttämätöntä.\n\n" +"Haluatko päivittää nyt?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "VIRHE TALLENTAESSA" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Tiedoston luominen ei onnistu." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Valitse Grand Theft Auto: San Andreaksen asennushakemisto" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "LATAUSVIRHE" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Virhe ladatessa %s moduulia! (%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Ladattu tiedosto vaikuttaa olevan virheellinen." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Uusi %s asennus havaittu.\n\n" -"Haluatko kopioida asetuksesi %s:sta?" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Jostakin syystä." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA törmäsi ongelmaan avatessaan tiedostoa '%s'" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "LATAUS SUORITETTU" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA:sta puuttuu tiedosto '%s'." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Unknown problem in _DialogUpdateResult" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA törmäsi ongelmaan ladatessaan mallia." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "MUKAUTETUT GTA:SA TIEDOSTOT" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Jos muokkasit gta3.img tiedostoa viime aikoina, kokeile asentaa GTA:SA uudelleen." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ok" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA törmäsi ongelmaan lisätessään tehostusta ajoneuvoon." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "VIRHE" + +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Jotkin MTA:SA datatiedostot puuttuvat.\n\n" +"Ole hyvä ja asenna MTA:SA uudelleen" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA löysi virheitä tiedostossa '%s'" +msgid "%3d %% completed" +msgstr "%3d %% valmista" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Käynnistyikö tietokoneesi uudelleen pelatessasi MTA:ta?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Odotetaan vastausta - %-3d" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Ole hyvä ja lopeta seuraavat ohjelmat ennen jatkamista:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ KOMENTO-OHJE ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Verkkosivupyynnöt" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Kello on %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Pelipalvelin pyytää oikeuksia ladata seuraavat verkkosivut:" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "ÄLÄ KOSKAAN SYÖTÄ ARKALUONTOISTA TIETOA, JOTTA VOIT SUOJATA NIITÄ VARASTAMISELTA" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "connect: Syntaksi on 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Muista valinta jatkossa" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "connect: Virheellinen porttinumero" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Salli" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "connect: Yhdistetään osoitteeseen %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Estä" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "connect: osoitteeseen %s:%u ei saatu yhteyttä!" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "connect: Modin purkaminen epäonnistui" + +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Käytät ominaisuushaara-koontiversiota! Tämä on vain testiversio, jota ei voida käyttää yhteyden muodostamiseen julkisiin palvelimiin!" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA ei saa päivityksiä XP/Vistaan ​​heinäkuun 2019 jälkeen.\n\n" -" Päivitä Windows pelataksesi uusimmilla palvelimilla." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Tämä katkaisee yhteyden nykyiseen palvelimeen.\n\n" -"Haluatko varmasti katkaista yhteyden?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "VAROITUS YHTEYDEN KATKAISUSTA" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Määritetty kaikki näppäimet GTA:sta" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Kokoonpanotiedosto tallennettiin" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Suomi" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Serialisi on: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "ASETUKSET" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Moninpeli" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Kuva" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Ääni" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Näppäinmääritykset" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Ohjaus" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Käyttöliittymä" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Nettiselain" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Lisäasetukset" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Palauta oletusarvot" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Hiiren herkkyys:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Pystysuuntainen tähtäysherkkyys:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Hiiren asetukset" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Käänteinen hiiren liike pystysuunnassa" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Ohjaa hiirellä" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Lennä hiirellä" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Peliohjaimen asetukset" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Tavallinen ohjaus (hiiri + näppäimistö)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Klassinen ohjaus (peliohjain)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Kuollut alue" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Kylläisyys" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Käytä 'Näppäinmääritykset' välilehteä sauvan painikkeiden määritykseen." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Vasen sauva" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Oikea sauva" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "KUVAUS" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "NÄPPÄIN" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "TOISSIJ. NÄPPÄIN" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Nimimerkki:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Tallenna palvelinten salasanat" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Päivitä palvelinselain automaattisesti" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Salli kuvakaappauksen lähetys" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Salli ulkoiset äänet" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Näytä latausikkuna aina" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Käytä muokattuja GTA:SA-tiedostoja" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Kartan renderöintiasetukset" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Läpinäkyvyys:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Pää-äänenvoimakkuus:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Radion äänenvoimakkuus:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Äänitehosteiden voimakkuus:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA:n äänenvoimakkuus:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Puheen voimakkuus:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Toistomoodi:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Yleinen" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Radioasetukset" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Radion taajuuskorjain" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Radion automaattinen viritys" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Käyttäjäradion asetukset" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Radio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Satunnainen" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Peräkkäinen" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Automaattinen median haku" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Mykistysasetukset" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Mykistä kaikki äänet, kun peli on pienennetty" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Hiljennä radio, kun peli pienennetään" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Hiljennä äänitehosteet, kun peli pienennetään" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Hiljennä MTA:n äänet, kun peli pienennetään" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Hiljennä puhe, kun peli pienennetään" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Tarkkuus:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Näkökenttä (FOV):" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Piirtoetäisyys (LOD):" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Kirkkaus:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Laatu:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anisotrooppinen suodatus:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Reunojen pehmennys:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Kuvasuhde:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Ikkunallinen" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI-tietoinen" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Vakio" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Reunaton pidä res" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mip-kartoitus" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Matala" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Keskitaso" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Korkea" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Erittäin korkea" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Pois käytöstä" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Automaattinen" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD vastaa kuvasuhdetta" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Volumetriset varjot" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Ruohoefekti" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Lämpöaallot" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Renkaan savua jne" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Dynaamiset varjot" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Motion blur" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Koronan heijastukset sateella" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Koko näytön pienennys" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Ota käyttöön näytön valintaikkuna käynnistäessä" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Näytä epäturvalliset resoluutiot" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Renderöi ajoneuvot aina yksityiskohtaisesti" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Renderöi hahmot aina yksityiskohtaisesti" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Ota etäsivustot käyttöön" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Ota JavaScript käyttöön etäsivustoilla" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Mukautettu musta lista" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Syötä verkkotunnus esim. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Estä" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Verkkotunnus" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Poista verkkotunnus" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Mukautettu sallittujen lista" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Salli" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Muut" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Nopea CJ:n vaatteiden lataus:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Palvelinselaimen nopeus:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Yksittäinen yhteys:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Pakettien merkintä:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Etenemisanimaatio:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Prosessin prioriteetti:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Vianetsintäasetukset:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Suoratoistomuisti:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Päivityksen tyyppi:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Asenna tärkeät päivitykset:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Päällä" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Erittäin hidas" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Oletus" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Nopea" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normaali" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Normaalia parempi" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Min" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Max" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 yhteensopivuus:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-bittinen väri" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Hiiren korjaus" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Resurssitiedostot:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Avaa resurssienhallinnassa" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Automaattinen päivitys" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Tarkista päivitykset nyt" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Jotkut asetukset muuttuvat, kun seuraavan kerran käynnistät MTA:n" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Haluatko käynnistää uudelleen nyt?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "UUDELLEENKÄYNNISTYS VAADITAAN" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Jotkut asetukset muuttuvat, kun katkaiset yhteyden nykyiseen palvelimeen" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Haluatko katkaista yhteyden?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "VAADITAAN YHTEYDEN KATKAISEMINEN" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Sauvaohjainta ei havaittu - Tarkista liitännät ja käynnistä peli uudelleen" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Sitova akseli" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Liikuta akselia määrittääksesi, tai paina poistumisnäppäintä tyhjentääksesi" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Kieli:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Ulkoasu:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Esiasetukset:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Chatti" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Lataa" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Värit" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Asettelu" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Asetukset" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Chatin tausta" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Chatin teksti" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Syötön tausta" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Syötön teksti" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Rivit:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Skaalaus:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Leveys:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Koko" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "jälkeen" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "kesto" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "sek" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Häivytys" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Häivytä vanhat linjat" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Vaakasuora:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Pystysuora:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Tekstin tasaus:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-etäisyys:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-etäisyys:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Sijainti" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Vasemmalle" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Keskikohta" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Oikealle" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Ylä" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Ala" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Fontti" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Piilota tausta, kun et kirjoita" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Nimen täyttö sarkaimen avulla" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Salli palvelimen väläyttää ikkunaa" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Salli ilmoitukset tehtäväpalkissa" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Chatin tekstin musta/valko ääriviiva" @@ -1547,110 +1832,116 @@ msgstr "Chatin tekstin musta/valko ääriviiva" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Paina näppäintä määrittääksesi, tai paina poistumisnäppäintä tyhjentääksesi" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Ensisijaisen näppäimen määritys" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Toissijaisen näppäimen määritys" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA OHJAINASETUKSET" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "MONINPELIN OHJAINASETUKSET" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Nimesi sisältää virheellisiä merkkejä!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Punainen:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Vihreä:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Sininen:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Läpinäkyvyys:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Väri" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Esikatselu" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Ole hyvä ja katkaise yhteys ennen kielen vaihtamista" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Ole hyvä ja poistu pelipalvelimelta ennen ulkoasun vaihtamista" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Volumetriset varjot voivat hidastaa joitakin järjestelmiä.\n\n" "Haluatko varmasti ottaa ne käyttöön?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "SUORITUSKYKYVAROITUS" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Kuvakaappuksen lähetys on vaadittu jollain palvelimilla huijauksen eston takia.\n\n" "(Chatti ja graafinen käyttöliittymä on piilotettu kuvakaappauksesta)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "KUVAKAAPPAUKSEN LÄHETYS" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "Jotkut skriptit saattavat toistaa ääniä, kuten radiota, internetistä.\n\n" "Tämän asetuksen poistaminen käytöstä voi vähentää verkon kulutusta.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "ULKOISET ÄÄNET" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1660,11 +1951,7 @@ msgstr "Jotkin tiedostot GTA:SA hakemistossasi ovat muokattuja.\n" "Huomaa, että muokatut GTA:SA tiedostot ovat estettyjä monilla pelipalvelimilla!\n\n" "Oletko varma että haluat käyttää niitä?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "MUKAUTETUT GTA:SA TIEDOSTOT" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1674,550 +1961,252 @@ msgstr "DPI-tietoisuus on kokeellinen ominaisuus ja suosittelemme\n" "Saatat kokea visuaalisia häiriöitä jos käytät tätä asetusta.\n\n" "Oletko varma että haluat käyttää tätä asetusta?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "KOKEELLINEN OMINAISUUS" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Ole hyvä ja syötä nimimerkki" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Ole hyvä ja syötä nimimerkki.\n" "Tämä on nimesi joka näkyy liittyessäsi ja pelatessasi palvelimella" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Erityisen kokeellinen ominaisuus." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Auttaa CJ-variaatioiden latausten kanssa (Käyttää 65MB enemmän muistia)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Vanhemmat reitittimet voivat vaatia hitaamman skannausnopeuden." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Valitse tämä käyttääksesi vain yhtä yhteyttä latauksissa." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Merkitsee paketit auttaakseen internet-palveluntarjoajia tunnistamaan MTA:n verkkoliikenteen." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Pyörivä latausanimaatio ruudun alareunassa" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Valitse oletus aina. (Tätä asetusta ei tallenneta)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Korkein asetus on yleensä paras" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Automaattinen päivitys:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Valitse oletus ellet pidä bugien raportoinnista." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Valitse oletus asentaaksesi tärkeät päivitykset automaattisesti." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-bittinen väri:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Käytä 16 bittistä väriavaruutta - Tarvitsee MTA:n uudelleenkäynnistyksen" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Hiiren korjaus:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Hiiren liikkeen korjaus - Saattaa tarvita PC:n uudelleenkäynnistyksen" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Tuntematon komento tai cvar: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Varattu" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Päivityksiä ei pysty tarkistamaan juuri nyt" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s vaaditaan" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Sinun pitää päivittää MTA:SA %s yhdistääksesi tälle pelipalvelimelle.\n\n" -"Haluatko ladata ja asentaa MTA:SA %s?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Haluatko käynnistää MTA:SA %s ja yhdistää tähän pelipalvelimeen?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Palvelimelle ei pysty yhdistämään juuri nyt.\n\n" -"Kokeile myöhemmin uudelleen." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Yhdistetään" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Odota hetki..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "TARKISTETAAN" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "PÄIVITYSTARKISTUS" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Päivitystä ei tarvita" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "LADATAAN" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "odotetaan..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "PÄIVITYS VAADITAAN" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Jotta voit liittyä tälle palvelimelle, sinun on päivitettävä MTA.\n\n" -"Haluatko päivittää sen nyt?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "VALINNAINEN PÄIVITYS" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Palvelin sanoo, että MTA:n päivitys on suositeltavaa, mutta ei välttämätöntä.\n\n" -"Haluatko päivittää nyt?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "VIRHE TALLENTAESSA" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Tiedoston luominen ei onnistu." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "LATAUSVIRHE" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Ladattu tiedosto vaikuttaa olevan virheellinen." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Jostakin syystä." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "LATAUS SUORITETTU" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Unknown problem in _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ok" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "VIRHE" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Jotkin MTA:SA datatiedostot puuttuvat.\n\n" -"Ole hyvä ja asenna MTA:SA uudelleen" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% valmista" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Odotetaan vastausta - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Yhdistäminen epäonnistui. Virheellinen nimimerkki!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Yhdistäminen epäonnistui. Virheellinen isäntä!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Yhdistäminen osoitteeseen %s portissa %u epäonnistui!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Yhdistetään osoitteeseen %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "YHDISTETÄÄN" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Yhteyden aikakatkaisu" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Yhteys katkaistu: isäntä katkaisi yhteyden" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Yhteys katkaistu: yhteys katkaistu etänä" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Yhteys katkaistu: yhteys menetetty etänä" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Yhteys katkaistu: sinulla on porttikielto tälle palvelimelle" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Yhteys katkaistu: palvelin katkaisi yhteyden" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Yhteys katkaistu: yhteys palvelimeen menetetty" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Yhteys katkaistu: yhteys evättiin" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Modia ei asennettu (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Virheellinen vastaus palvelimelta (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Virheellinen vastaus palvelimelta (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "UUTISET" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Tutustu uusimpaan uutisartikkeliin" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONSOLI" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Vakava virhe" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "KORJAA POISTAMALLA TÄMÄ TIEDOSTO:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s moduuli on väärä!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Virhe suoritettaessa URL:ää" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "tämä ohje" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "poistuu sovelluksesta" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "näyttää version" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "näyttää ajan" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "näyttää hud:n" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "näyttää kaikki näppäinmääritykset" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "näyttää serialin" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "yhdistää palvelimeen (isäntä portti nimimerkki salasana)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "yhdistää aikaisempaan palvelimeen" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "määrittää näppäimen" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "poistaa näppäimen määrityksen" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "kopioi gta:n oletusnäppäinmääritykset" -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "ottaa kuvakaappauksen" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "tallentaa asetustiedoston välittömästi" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "tyhjentää vianetsintäikkunan" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "vierittää chat-ruutua ylöspäin" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "vierittää chat-ruutua alaspäin" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "vierittää vianetsintäikkunaa ylöspäin" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "vierittää vianetsintäikkunaa alaspäin" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "näyttää muistitilastot" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "näyttää ruutuaikakuvaajan" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "kehittäjille: päivitä uutiset" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ KOMENTO-OHJE ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Kello on %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "connect: Syntaksi on 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "connect: Virheellinen porttinumero" +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "ottaa kuvakaappauksen" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "connect: Yhdistetään osoitteeseen %s:%u..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "tallentaa asetustiedoston välittömästi" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "connect: osoitteeseen %s:%u ei saatu yhteyttä!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "tyhjentää vianetsintäikkunan" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "connect: Modin purkaminen epäonnistui" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "vierittää chat-ruutua ylöspäin" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "vierittää chat-ruutua alaspäin" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "vierittää vianetsintäikkunaa ylöspäin" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "vierittää vianetsintäikkunaa alaspäin" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "näyttää muistitilastot" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Määritetty kaikki näppäimet GTA:sta" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "näyttää ruutuaikakuvaajan" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Kokoonpanotiedosto tallennettiin" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "kehittäjille: päivitä uutiset" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Serialisi on: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Käytät ominaisuushaara-koontiversiota! Tämä on vain testiversio, jota ei voida käyttää yhteyden muodostamiseen julkisiin palvelimiin!" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Kiihdytysakseli" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA ei saa päivityksiä XP/Vistaan ​​heinäkuun 2019 jälkeen.\n\n" +" Päivitä Windows pelataksesi uusimmilla palvelimilla." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Jarrutusakseli" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Tämä katkaisee yhteyden nykyiseen palvelimeen.\n\n" +"Haluatko varmasti katkaista yhteyden?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Ohjelmointi" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "VAROITUS YHTEYDEN KATKAISUSTA" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Avustajat" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Pelisuunnittelu / Skriptaus" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "UUTISET" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Lokalisointi" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Tutustu uusimpaan uutisartikkeliin" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Kehitykseen osallistuneet" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Kuvakaappaus on %d tavua, kun odotettiin %d tavua" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Erityiskiitokset" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Kuvankaappaus epäonnistui" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Tämä ohjelmisto ja projekti käyttää hyväksi seuraavia kirjastoja ja ohjelmia:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Kuvankaappaus otettu: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Haluatko etsiä apua tähän ongelmaan?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Tuntematon komento tai cvar: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2392,25 +2381,56 @@ msgid "Group control backwards" msgstr "Taaksepäin (ryhmäohjaus)" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Valitsemaasi ulkoasua ei voitu ladata, oletusulkoasua ei voitu myöskään ladata. Ole hyvä ja asenna MTA uudelleen." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Kuvakaappaus on %d tavua, kun odotettiin %d tavua" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Haluatko etsiä apua tähän ongelmaan?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Kuvankaappaus epäonnistui" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONSOLI" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Kuvankaappaus otettu: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Ohjelmointi" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Avustajat" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Pelisuunnittelu / Skriptaus" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Lokalisointi" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Kehitykseen osallistuneet" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Erityiskiitokset" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Tämä ohjelmisto ja projekti käyttää hyväksi seuraavia kirjastoja ja ohjelmia:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Kiihdytysakseli" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Jarrutusakseli" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2418,6 +2438,61 @@ msgstr "Direct3D9:n alustaminen epäonnistui.\n\n" "Varmista, että DirectX End-User Runtime sekä\n" "viimeisimmät Windows Service Packit on asennettu oikein." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Idle" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "pelaaja" +msgstr[1] "pelaajaa" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr " " + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "palvelimella" +msgstr[1] "palvelimella" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Haetaan palvelinluetteloa (%lu ms kulunut)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Palvelinluetteloa ei voitu lukea." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Palvelinluetteloa ei voitu hakea." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Vara-palvelinlista)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Ei voitu yhdistää LAN-broadcast sokettiin" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Etsitään LAN palvelimia" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2471,7 +2546,7 @@ msgstr "Viive:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Pelaajaluettelo" @@ -2498,40 +2573,39 @@ msgstr "Liity palvelimelle heti, kun paikka vapautuu." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "SYÖTÄ PALVELIMEN SALASANA" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Aikakatkaisu" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Pyydetään tietoja..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "PALVELINSELAIN" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "LAN" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Suosikit" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Viimeaikaiset" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2539,298 +2613,367 @@ msgstr "PIKAYHTEYS:\n\n" "Kirjoita osoite ja portti osoiteriville.\n" "Tai valitse palvelin historiasta ja klikkaa 'Yhdistä'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "APUA" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Päivitä" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Lisää suosikki" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Yhdistä" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Tietoja palvelimesta" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Etsi palvelimia" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Etsi pelaajia" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Aloita haku" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Etsi pelaajia..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Etsi palvelimia..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Nimi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Pelaajia" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Viive" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Pelimuoto" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Sisällytä:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Tyhjä" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Täysi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Lukittu" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Pois käytöstä" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Muut versiot" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Takaisin" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Ladataan..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..ladataan.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Osoitetta ei määritelty!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Tuntematon protokolla" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Käytä mtasa://-protokollaa!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Virheellinen nimimerkki! Määritä itsellesi uusi nimimerkki Asetukset-valikosta!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Sinun on valittava palvelin, johon yhdistetään." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Idle" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Ongelma grafiikka-ajurin kanssa" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "pelaaja" -msgstr[1] "pelaajaa" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Näytön resoluutiota ei löydy." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr " " +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Haluatko varmasti käyttää tätä näytön resoluutiota?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "palvelimella" -msgstr[1] "palvelimella" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Haetaan palvelinluetteloa (%lu ms kulunut)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Palvelinluetteloa ei voitu lukea." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Verkkosivupyynnöt" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Palvelinluetteloa ei voitu hakea." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Pelipalvelin pyytää oikeuksia ladata seuraavat verkkosivut:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Vara-palvelinlista)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "ÄLÄ KOSKAAN SYÖTÄ ARKALUONTOISTA TIETOA, JOTTA VOIT SUOJATA NIITÄ VARASTAMISELTA" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Ei voitu yhdistää LAN-broadcast sokettiin" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Muista valinta jatkossa" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Etsitään LAN palvelimia" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Estä" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Tämä versio on vanhentunut." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "katkaise yhteys palvelimeen" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "näyttää nimitagit" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "näyttää chatin" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "näyttää verkkotilastot" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "avaa chatin syöttökentän" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "lähettää ääntä toisille pelaajille" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "nousee autoon matkustajana" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "seuraava radiokanava" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "edellinen radiokanava" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "lähettää yksityisviestin kyseiselle pelaajalle" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "vaihtaa seuraavaan aseeseen kun olet ajoneuvossa sisällä" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "vaihtaa edelliseen aseeseen kun olet ajoneuvossa sisällä" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "tulostaa konsoliin tietoja pelipalvelimesta" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "määrittää kaikkien text-display elementtien skaalan" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Kehitystila) näyttää/piilottaa colshapet" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Kehitystila) tulostaa maailman äänten id:t debug konsoliin" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "ISÄNNÖI PELIÄ" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Resurssit" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Palvelimen nimi:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Salasana:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Max. pelaajat:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Broadcast:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Valittu" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Kaikki" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Käynnistä" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Kartan latauksen edistyminen:" @@ -2851,195 +2994,195 @@ msgstr "%s / %s" msgid "Disconnect to cancel download" msgstr "Katkaise yhteys peruuttaaksesi latauksen" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Yhteys katkaistu: Virheellinen nimimerkki" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Katkaise yhteys palvelimeen" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Yhteys katkaistu: Sarjanumero on estetty.\n" "Syy: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Yhteys katkaistu: Sinut on estetty.\n" "Syy: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Yhteys katkaistu: Tili on estetty.\n" "Syy: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Yhteys katkaistu: Versio ei täsmää" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Yhteys katkaistu: Liittymistulva. Ole hyvä ja odota minuutti, yhdistä sitten uudelleen." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Yhteys katkaistu: Palvelin on eri juuressa.\n" "Tiedot: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Yhteys katkaistu: Väärä versio.\n" "Tiedot: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Yhteys katkaistu: Palvelin pyörii uudemmalla versiolla.\n" "Tiedot: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Yhteys katkaistu: Palvelin pyörii vanhemmalla versiolla.\n" "Tiedot: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Yhteys katkaistu: Nimimerkki on jo käytössä" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Yhteys katkaistu: Hahmoa ei pystytty luomaan." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Yhteys katkaistu: Palvelin esti yhteyden: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Yhteys katkaistu: Sarjanumeron varnennus epäonnistui" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Yhteys katkaistu: Synkronointivirhe %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Yhteys katkaistu: Käyttäjä %s poisti sinut palvelimelta" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Yhteys katkaistu: Käyttäjä %s antoi sinulle porttikiellon" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Yhteys katkaistu: Palvelin sammuu tai käynnistyy uudelleen" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Sinut potkittiin pelistä" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Tämä palvelin vaatii muokkaamattoman gta_sa.exe:n" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Ole hyvä ja korvaa gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Tämä pelipalvelin ei salli kustomoituja D3D9.DLL tiedostoja" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Poista D3D9.DLL GTA asennushakemistosta ja käynnistä MTA uudelleen" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Tämä pelipalvelin ei salli virtuaalikoneita" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Ajurien allekirjoitus on oltava käytössä pelataksesi tällä palvelimella." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Ole hyvä ja käynnistä tietokoneesi uudelleen" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Tämä palvelin on havainnut puuttuvia komponentteja huijauksen estosta" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Kokeile käynnistää MTA uudelleen" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Tämä palvelin vaatii muokkaamattoman gta3.img:n ja gta_int.img:n" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Ole hyvä ja korvaa gta3.img tai gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Wine ei ole sallittu tällä pelipalvelimella" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Varmista että mikään toinen ohjelma ei muuta MTA:ta" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Aikaa jäljellä: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d päivä" msgstr[1] "%d päivää" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d tunti" msgstr[1] "%d tuntia" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d minuutti" msgstr[1] "%d minuuttia" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3047,296 +3190,206 @@ msgstr[0] "%d sekunti" msgstr[1] "%d sekuntia" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Yhteys katkaistu" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Latausvirhe: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Liitytään peliin..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Ei yhdistetty; ole hyvä ja käytä Yhdistä-painiketta tai 'connect' komentoa yhdistääksesi pelipalvelimelle." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Paikallisen palvelimen käynnistäminen epäonnistui. Katso lisätietoja konsolista." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Paikallinen palvelin" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Käynnistetään paikallista palvelinta..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Sinut potkittiin pelistä (%s)" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Yhdistetään paikalliselle palvelimelle..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Virhe yhdistettäessä palvelimeen." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Paikalliselle palvelimelle yhdistäminen aikakatkaistiin. Katso konsolista lisätietoja." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Yhteys palvelimeen menetetty" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Yhteys katkaistu: Palvelin on täynnä" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Yhteys katkaistu: Väärä salasana" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA:n varmennus epäonnistui!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "ISÄNNÖI PELIÄ" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Resurssit" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Palvelimen nimi:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Salasana:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Max. pelaajat:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Broadcast:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Valittu" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Kaikki" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Käynnistä" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Ongelma grafiikka-ajurin kanssa" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Näytön resoluutiota ei löydy." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Haluatko varmasti käyttää tätä näytön resoluutiota?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Latausvirhe: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3357,11 +3410,11 @@ msgstr "" msgid "Connection error" msgstr "Yhteysvirhe" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Autoa ei ole asennettu oikein, ole hyvä ja asenna uudelleen." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Oletusselaimesi avaa nyt sivun josta löydät lisätietoja.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/fil_PH/client.pot b/Shared/data/MTA San Andreas/MTA/locale/fil_PH/client.pot index 6dae1bf016a..cd3ca9c0061 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/fil_PH/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/fil_PH/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:32\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Filipino\n" "Language: fil_PH\n" @@ -17,228 +17,439 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "" + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "" + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "" + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "" + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "" + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "" + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "" + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." msgstr "" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" msgstr "" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "" -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" msgstr "" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "" -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "" -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "" -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." msgstr "" -#: Client/loader/MainFunctions.cpp:810 +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "" -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "" -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "" -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "" -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Data file %s is modified. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." msgstr "" -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" msgstr "" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" msgstr "" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." msgstr "" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" msgstr "" #. ///////////////////////////////////////////////////////////////////////// @@ -247,1257 +458,1336 @@ msgstr "" #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "" -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." msgstr "" -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "" -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" msgstr "" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" msgstr "" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" msgstr "" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." msgstr "" -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" msgstr "" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" msgstr "" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" msgstr "" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" msgstr "" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" msgstr "" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" msgstr "" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgid "No such mod installed (%s)" msgstr "" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" msgstr "" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" msgstr "" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" msgstr "" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" msgstr "" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" msgstr "" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" msgstr "" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" msgstr "" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" msgstr "" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." msgstr "" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" msgstr "" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." msgstr "" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" msgstr "" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" msgstr "" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" msgstr "" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" msgstr "" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." msgstr "" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" msgstr "" -#: Client/loader/Install.cpp:265 -msgid "Unknown" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" msgstr "" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" msgstr "" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" msgstr "" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" msgstr "" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." msgstr "" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" msgstr "" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." msgstr "" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." msgstr "" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" msgstr "" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" msgstr "" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" msgstr "" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" msgstr "" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" msgstr "" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "" + +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" +msgid "%3d %% completed" msgstr "" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" msgstr "" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Mga kahilingan na website" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Ang server ay hinihiling ang mga sumusunod upang mag-load ang mga ito (mamaya):" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "HUWAG KAILANMAN MAGLALAGAY NG MGA SENSITIBONG DATOS UPANG MAPROTEKTAHAN ANG MGA ITO MULA SA PAGNAKAW" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Tandaan ang desisyon" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Payagan" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "" + +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Tanggihan" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" msgstr "" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" msgstr "" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" msgstr "" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "" -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Payagan" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "" @@ -1505,660 +1795,368 @@ msgstr "" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" "Are you sure you want to use them?" msgstr "" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" "Are you sure you want to enable this option?" msgstr "" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "" -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "" -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "" -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "" -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "" - -#: Client/core/CSettings.cpp:4991 -msgid "Maximum is usually best" -msgstr "" - -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 -msgid "Auto updater:" -msgstr "" - -#: Client/core/CSettings.cpp:4993 -msgid "Select default unless you like filling out bug reports." -msgstr "" - -#: Client/core/CSettings.cpp:4995 -msgid "Select default to automatically install important updates." -msgstr "" - -#: Client/core/CSettings.cpp:4997 -msgid "16-bit color:" -msgstr "" - -#: Client/core/CSettings.cpp:4997 -msgid "Enable 16 bit color modes - Requires MTA restart" -msgstr "" - -#: Client/core/CSettings.cpp:4999 -msgid "Mouse fix:" -msgstr "" - -#: Client/core/CSettings.cpp:4999 -msgid "Mouse movement fix - May need PC restart" -msgstr "" - -#: Client/core/CSettings.cpp:5001 -msgid "CPU affinity:" -msgstr "" - -#: Client/core/CSettings.cpp:5001 -msgid "Only change if you're having stability issues." -msgstr "" - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "" - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" + +#: Client/core/CSettings.cpp:6033 +msgid "Maximum is usually best" msgstr "" -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 +msgid "Auto updater:" msgstr "" -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" +#: Client/core/CSettings.cpp:6035 +msgid "Select default unless you like filling out bug reports." msgstr "" -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" +#: Client/core/CSettings.cpp:6037 +msgid "Select default to automatically install important updates." msgstr "" -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" +#: Client/core/CSettings.cpp:6039 +msgid "16-bit color:" msgstr "" -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" +#: Client/core/CSettings.cpp:6039 +msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "" -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" +#: Client/core/CSettings.cpp:6041 +msgid "Mouse fix:" msgstr "" -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" +#: Client/core/CSettings.cpp:6041 +msgid "Mouse movement fix - May need PC restart" msgstr "" -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" +#: Client/core/CSettings.cpp:6043 +msgid "CPU affinity:" msgstr "" -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" +#: Client/core/CSettings.cpp:6043 +msgid "Only change if you're having stability issues." msgstr "" -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "" -#: Client/core/CCore.cpp:1391 +#: Client/core/CCore.cpp:1494 msgid "clears the debug view" msgstr "" -#: Client/core/CCore.cpp:1392 +#: Client/core/CCore.cpp:1495 msgid "scrolls the chatbox upwards" msgstr "" -#: Client/core/CCore.cpp:1393 +#: Client/core/CCore.cpp:1496 msgid "scrolls the chatbox downwards" msgstr "" -#: Client/core/CCore.cpp:1394 +#: Client/core/CCore.cpp:1497 msgid "scrolls the debug view upwards" msgstr "" -#: Client/core/CCore.cpp:1395 +#: Client/core/CCore.cpp:1498 msgid "scrolls the debug view downwards" msgstr "" -#: Client/core/CCore.cpp:1398 +#: Client/core/CCore.cpp:1501 msgid "shows the memory statistics" msgstr "" -#: Client/core/CCore.cpp:1399 +#: Client/core/CCore.cpp:1502 msgid "shows the frame timing graph" msgstr "" -#: Client/core/CCore.cpp:1403 +#: Client/core/CCore.cpp:1506 msgid "for developers: reload news" msgstr "" -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" msgstr "" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." msgstr "" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" msgstr "" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" msgstr "" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" msgstr "" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" msgstr "" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" msgstr "" -#: Client/core/CCommandFuncs.cpp:325 +#: Client/core/CScreenShot.cpp:200 #, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" +msgid "Screenshot got %d bytes, but expected %d" msgstr "" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" msgstr "" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 +#: Client/core/CScreenShot.cpp:256 #, c-format -msgid "* Your serial is: %s" -msgstr "" - -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "" - -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "" - -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "" - -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "" - -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "" - -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "" - -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "" - -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "" - -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" +msgid "Screenshot taken: '%s'" msgstr "" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " msgstr "" #: Client/core/CKeyBinds.cpp:186 @@ -2334,30 +2332,116 @@ msgid "Group control backwards" msgstr "" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "" -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" msgstr "" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" msgstr "" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" msgstr "" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." msgstr "" +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "" +msgstr[1] "" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "" +msgstr[1] "" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2411,7 +2495,7 @@ msgstr "" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "" @@ -2438,337 +2522,405 @@ msgstr "" msgid "PLEASE ENTER SERVER PASSWORD" msgstr "" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "" #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "" -msgstr[1] "" - -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "" -msgstr[1] "" - -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "" +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Mga kahilingan na website" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "" +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Ang server ay hinihiling ang mga sumusunod upang mag-load ang mga ito (mamaya):" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "HUWAG KAILANMAN MAGLALAGAY NG MGA SENSITIBONG DATOS UPANG MAPROTEKTAHAN ANG MGA ITO MULA SA PAGNAKAW" + +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Tandaan ang desisyon" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Tanggihan" + +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Ang bersyon na ito ay nag-expire na." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "idiskonekta mula sa laro" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "ipinapakita ang mga pangalan" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "ipinapakita ang chatbox" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "ipinapakita ang istatistika ng network" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "buksan ang input ng chat" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "nagpapadala ng boses sa ibang mga manlalaro" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "pumapasok sa sasakyan bilang pasahero" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "susunod na channel ng radyo" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "naunang channel ng radyo" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "nagpapadala ng mensahe sa target na player" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "nagpapalit ng susunod na armas habang nasa sasakyan" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "nagpapalit ng naunang armas habang nasa sasakyan" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "ipinapakita ang impormasyon tungkol sa kasalukuyang server" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "tinutukoy ang scale multiplier ng lahat ng text-displays" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Development mode) ipinapakita ang colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Development mode) ipinapakita ang world sound ids sa debug window" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Progreso ng pagdownload ng mapa:" @@ -2789,195 +2941,195 @@ msgstr "%s ng %s" msgid "Disconnect to cancel download" msgstr "Idiskonekta para kanselahin ang pagdownload" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Nadiskonekta: Di-wastong pangalan" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Idiskonekta mula sa server" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Nadiskonekta: Ang serial ay pinagbawalan.\n" "Rason: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Nadiskonekta: Ikaw ay pinagbawalan.\n" "Rason: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Nadiskonekta: Ang account ay pinagbawalan.\n" "Rason: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Nadiskonekta: Ang bersyon ay hindi tugma" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Nadiskoneta: Napakaraming pagsali. Maghintay ng isang minuto at sumali ulit." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Nadiskonekta: Server mula sa iba't ibang sangay.\n" "Impormasyon: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Nadiskonekta: Masamang bersyon.\n" "Impormasyon: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Nadiskonekta: Ang server ay nagpapatakbo ng mas bagong build.\n" "Impormasyon: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Nadiskonekta: Ang server ay nagpapatakbo ng mas lumang build.\n" "Impormasyon: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Nadiskonekta: Ang pangalan ay kasalukuyang ginagamit" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "" msgstr[1] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "" msgstr[1] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "" msgstr[1] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -2985,295 +3137,205 @@ msgstr[0] "" msgstr[1] "" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "" - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" +msgid "Download error: %s" msgstr "" #. Populate the message and show the box @@ -3295,11 +3357,11 @@ msgstr "" msgid "Connection error" msgstr "" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "" -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "" diff --git a/Shared/data/MTA San Andreas/MTA/locale/fr_FR/client.pot b/Shared/data/MTA San Andreas/MTA/locale/fr_FR/client.pot index 7bb5dd00799..f680c252046 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/fr_FR/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/fr_FR/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 04:08+0000\n" -"PO-Revision-Date: 2025-07-16 19:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:18\n" "Last-Translator: \n" "Language-Team: French\n" "Language: fr_FR\n" @@ -17,72 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Difficulté de redémarrage de MTA:SA:\n\n" -"Si le problème persiste, ouvrez le Gestionnaire des tâches et\n" -"arrêtez les processus 'gta_sa.exe' et 'Multi Theft Auto.exe'.\n\n\n" -"Voulez-vous tenter de relancer MTA:SA?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Lancez Grand Theft Auto: San Andreas.\n" +"Assurez-vous que le jeu est placé dans le dossier 'Program Files (x86)'." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:651 -#: Client/mods/deathmatch/logic/CClientGame.cpp:725 -#: Client/mods/deathmatch/logic/CClientGame.cpp:749 -#: Client/mods/deathmatch/logic/CClientGame.cpp:771 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1184 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1264 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1274 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1343 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1380 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1429 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1441 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Erreur" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "Recherche de GTA: San Andreas" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Une instance de MTA:SA est déjà en cours d'exécution.\n\n" -"Si ce problème persiste, veuillez redémarrer votre ordinateur" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Désolé, jeu introuvable.\n" +"Lancez Grand Theft Auto : San Andreas et cliquez sur Réessayer.\n" +"Assurez-vous que le jeu est placé dans le dossier 'Programmes (x86)'." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Une instance de MTA:SA est déjà en cours d'exécution.\n\n" -"Voulez-vous la terminer?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Sélectionnez le répertoire d'installation de Grand Theft Auto: San Andreas" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA nécessite un Accès Administrateur pour effectuer la tâche suivante:\n\n" +" '%s'\n\n" +"Veuillez confirmer dans la prochaine fenêtre." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Erreur de chargement du module %s! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Copie des fichiers..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "La copie s'est terminée prématurément. Tout va bien." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Finition..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Terminé!" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Une nouvelle installation de %s a été détectée.\n\n" +"Voulez-vous copier les paramètres à partir de %s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA a rencontré un problème en ouvrant le fichier '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA a besoin d'un fichier introuvable: '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA a rencontré un problème durant le chargement d'un model." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Si vous avez récemment modifié gta3.img, essayez de réinstaller GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA a rencontré un problème durant l'ajout d'une amélioration de véhicule." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA a détecté des erreurs dans le fichier '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Votre ordinateur a-t-il redémarré alors que vous jouiez à MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Veuillez fermer les programmes suivants, avant de continuer:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "Chemin d'accès au module invalide détecté.\n" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "La version du fichier ne correspond pas. Veuillez réinstaller MTA:SA si vous constatez des problèmes.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Des fichiers sont manquants. Veuillez réinstaller MTA:SA si vous constatez des problèmes.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA n'est pas compatible avec le Mode Sans Echec de Windows.\n\n" +"Veuillez redémarrer votre ordinateur.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Rencontrez-vous des difficultés pour démarrer MTA:SA?\n\n" "Voulez-vous revenir à une version antérieure? " -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +143,48 @@ msgstr "Il semble y avoir un problème au démarrage de MTA:.SA\n" "La réinitialisation des paramètres de GTA:SA peut parfois résoudre ce problème.\n\n" "Voulez-vous réinitialiser les paramètres de GTA:SA?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "Les paramètres de GTA:SA ont été réinitialisés.\n\n" "Appuyez sur OK pour continuer." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Le fichier n'a pas pu être effacé: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Rencontrez-vous des difficultés pour démarrer MTA:SA?\n\n" "Voulez-vous consulter de l'Aide en ligne?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Rencontrez-vous des problèmes avec MTA:SA?\n\n" "Voulez-vous modifier le paramètre suivant?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Mode plein écran:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Fenêtre sans bordures" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Rencontrez-vous des problèmes avec MTA:SA?\n\n" "Tentez de désactiver les produits suivants pour GTA and MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,300 +192,464 @@ msgstr "ATTENTION\n\n" "MTA:SA a détecté une activité suspecte.\n" "Veuillez lancer un scan de virus pour vous assurer de la sécurité de votre système.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Le fichier détecté était: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Une instance de GTA: San Andreas est déjà en cours d'exécution, et doit être terminée pour que MTA:SA puisse démarrer. Voulez-vous la terminer maintenant?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Information" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Impossible de terminer GTA: San Andreas. Si le problème persiste, veuillez redémarrer votre ordinateur." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Difficulté de redémarrage de MTA:SA:\n\n" +"Si le problème persiste, ouvrez le Gestionnaire des tâches et\n" +"arrêtez les processus 'gta_sa.exe' et 'Multi Theft Auto.exe'.\n\n\n" +"Voulez-vous tenter de relancer MTA:SA?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Erreur" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Une instance de MTA:SA est déjà en cours d'exécution.\n\n" +"Si ce problème persiste, veuillez redémarrer votre ordinateur" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Une instance de MTA:SA est déjà en cours d'exécution.\n\n" +"Voulez-vous la terminer?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Certaines clés du Registre sont manquantes. Veuillez réinstaller Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "L'emplacement d'installation de GTA: San Andreas contient des caractères non supportés (Unicode). Veuillez déplacer les fichiers de GTA: San Andreas à un emplacement contenant uniquement des caractères standards (ASCII) et réinstaller Multi Theft Auto: San Andreas" -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "L'emplacement de l'installation de MTA:SA ou GTA: San Andreas\n" -"contient un ';' (point-virgule).\n\n" -"Si vous rencontrez des probèmes en utilisant MTA:SA,\n" -"déplacez votre installation à un emplacement ne contenant pas ce caractère." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "Le chemin d'accès à votre installation de 'MTA:SA' ou 'GTA: San Andreas' contient un ';' (point-virgule).\n\n" +"Si vous rencontrez des problèmes lors de l'exécution de MTA:SA,\n" +"déplacez votre ou vos installations vers un chemin d'accès qui ne contient pas de point-virgule." + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "Chemins d'installation non valides détectés." + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Le chargement a échoué. Veuillez vous assurer que les fichiers Data les plus récents ont été installés correctement." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Le chargement a échoué. Veuillez vous assurer que %s est installé correctement." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Le chargement a échoué. Impossible de localiser gta_sa.exe dans %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Le chargement a échoué. %s existe à l'emplacement de GTA: San Andreas. Veuillez le supprimer avant de continuer." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Le fichier principal a un nom incorrect (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Le fichier principal n'est pas signé, et pourrait être infecté.\n\n" -"Veuillez consulter l'Aide en ligne, si MTA ne fonctionne pas correctement." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Le fichier %s est manquant. Activité d'un virus possible.\n\n" -"Envisagez de réinstaller Multi Theft Auto pour votre sécurité.\n" -"Consultez l'aide en ligne si MTA ne fonctionne pas correctement." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "Le fichier de données %s est manquant. Activité virus possible." + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Le fichier %s est modifié. Activité d'un virus possible.\n\n" -"Envisagez de réinstaller Multi Theft Auto pour votre sécurité.\n" -"Consultez l'aide en ligne si MTA ne fonctionne pas correctement." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "Des fichiers .asi ont été trouvés dans les dossiers d'installation de GTA:SA ou MTA:SA.\n\n" -"Supprimez ou déplacez ces fichiers si vous constatez des problèmes avec MTA:SA." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "La version du fichier ne correspond pas. Veuillez réinstaller MTA:SA si vous constatez des problèmes.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "Le fichier de données %s est modifié. Activité virus possible." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Des fichiers sont manquants. Veuillez réinstaller MTA:SA si vous constatez des problèmes.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "Il y a des fichiers .asi dans votre dossier d'installation.\n\n" +"Effacez ces fichiers .asi si vous rencontrez des problèmes." -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA n'est pas compatible avec le Mode Sans Echec de Windows.\n\n" -"Veuillez redémarrer votre ordinateur.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "Chemins d'accès aux jeux non valides détectés." -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Correction d'un problème de configuration" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Correction de l'erreur d'élévation requise" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "GTA: San Andreas n'a peut-être pas démarré correctement. Voulez-vous l'arrêter?" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Inconnu" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/Install.cpp:272 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Impossible de démarrer GTA: San Andreas. Veuillez tenter de réinstaller, ou si le problème persiste, contactez l'équipe de MTA à l'adresse www.multitheftauto.com. \n\n" -"[%s]" +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "Le fichier '%s' est actuellement verrouillé par %zu processus.\n\n" +"Voulez-vous mettre fin aux processus suivants et continuer la mise à jour ?\n\n" +"%s" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas n'a peut-être pas démarré correctement. Voulez-vous l'arrêter?" +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "Votre installation est peut-être corrompue.\n\n" +"%zu sur %zu fichiers n'ont pas pu être restaurés à partir de la sauvegarde.\n\n" +"Vous devriez réinstaller Multi Theft Auto depuis www.multitheftauto.com\n" +"ou essayez d'exécuter la mise à jour avec les droits d'administrateur." -#. ///////////////////////////////////////////////////////////////////////// -#. -#. Dialog strings -#. -#. -#. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 -#: Client/gui/CGUIMessageBox_Impl.cpp:72 -msgid "Yes" -msgstr "Oui" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Installation de la mise à jour..." -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 -msgid "No" -msgstr "Non" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Extraction des fichiers..." -#. Create buttons -#. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 -#: Client/gui/CGUIMessageBox_Impl.cpp:64 -msgid "OK" -msgstr "OK" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA n'a pas pu accomplir la tâche suivante:\n\n" +" '%s'\n" -#: Client/loader/Dialogs.cpp:38 -msgid "Quit" -msgstr "Quitter" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Ce crash a été causé par une erreur du pilote graphique **\n\n" +"** Veuillez mettre à jour le pilote graphique **" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 -msgid "Help" -msgstr "Aide" +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "** Mémoire insuffisante - ce crash a été causé par mémoire libre insuffisante ou fragmentée. **" -#. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 -#: Client/gui/CGUIMessageBox_Impl.cpp:68 -msgid "Cancel" -msgstr "Annuler" +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" -#: Client/loader/Dialogs.cpp:55 -msgid "MTA: San Andreas has encountered a problem" -msgstr "MTA: San Andreas a rencontré un problème" +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Installer les fichiers révisés de MTA:SA" -#: Client/loader/Dialogs.cpp:56 -msgid "Crash information" -msgstr "Informations à propos du crash" +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Impossible de mettre à jour à cause de conflits de fichier. Veuillez fermer les autres programmes et réessayer" -#: Client/loader/Dialogs.cpp:57 -msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" -msgstr "Cochez cette case pour envoyer un rapport aux développeurs" +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto n'a pas été installé correctement. Veuillez réinstaller. %s" -#: Client/loader/Dialogs.cpp:58 -msgid "Doing so will increase the chance of this crash being fixed." -msgstr "Cela augmentera les chances que le problème soit résolu." +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "Créer les jonctions GTA:SA" -#: Client/loader/Dialogs.cpp:59 -msgid "Do you want to restart MTA: San Andreas ?" -msgstr "Voulez-vous redémarrer MTA: San Andreas?" +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA ne peut pas être lancé car la copie d'un fichier a échoué:" -#: Client/loader/Dialogs.cpp:66 -msgid "MTA: San Andreas - Warning" -msgstr "MTA: San Andreas - Avertissement" +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA ne peut pas être lancé car un fichier MTA:SA est incorrect ou manquant:" -#: Client/loader/Dialogs.cpp:67 -msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" -msgstr "Votre répertoire d'installation de Grand Theft Auto: San Andreas contient les fichiers suivants :" +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Copier les fichiers de MTA:SA" -#: Client/loader/Dialogs.cpp:69 -msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" -"It is recommended that you remove or rename these files." -msgstr "Ces fichiers ne sont pas requis et pourraient interférer avec les fonctionnalités graphiques de cette version de MTA:SA.\n\n" -"Il est recommandé de supprimer ou renommer ces fichiers." +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA ne peut pas être lancé car un fichier GTA:SA est incorrect ou manquant:" -#: Client/loader/Dialogs.cpp:71 -msgid "Keep these files, but also show this warning on next start" -msgstr "Garder ces fichiers, mais afficher cet avertissement au prochain lancement" +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "Patcher la dépendance de GTA:SA" -#: Client/loader/Dialogs.cpp:72 -msgid "Do not remind me about these files again" +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA ne peut pas être lancé car l'exécutable de GTA:SA est incorrect ou manquant:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Veuillez vérifier votre antivirus pour une détection de faux positifs, essayez d'ajouter une exception pour l'exécutable GTA:SA et redémarrez MTA:SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "Générer GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA ne peut pas être lancé car l'exécutable de GTA:SA n'est pas chargeable:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Patcher GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA ne peut pas être lancé car la correction de GTA:SA a échoué:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA ne peut pas continuer car il n'y a pas assez d'espace libre sur le lecteur %s." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Fichier manquant:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Si MTA ne démarre pas, veuillez réinstaller GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "MAJ des paramètres d'installation" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "MAJ des paramètres de compatibilité" + +#. ///////////////////////////////////////////////////////////////////////// +#. +#. Dialog strings +#. +#. +#. ///////////////////////////////////////////////////////////////////////// +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 +#: Client/gui/CGUIMessageBox_Impl.cpp:72 +msgid "Yes" +msgstr "Oui" + +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 +msgid "No" +msgstr "Non" + +#. Create buttons +#. OK button +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 +#: Client/gui/CGUIMessageBox_Impl.cpp:64 +msgid "OK" +msgstr "OK" + +#: Client/loader/Dialogs.cpp:66 +msgid "Quit" +msgstr "Quitter" + +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 +msgid "Help" +msgstr "Aide" + +#. Cancel button +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 +#: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +msgid "Cancel" +msgstr "Annuler" + +#: Client/loader/Dialogs.cpp:83 +msgid "MTA: San Andreas has encountered a problem" +msgstr "MTA: San Andreas a rencontré un problème" + +#: Client/loader/Dialogs.cpp:84 +msgid "Crash information" +msgstr "Informations à propos du crash" + +#: Client/loader/Dialogs.cpp:85 +msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" +msgstr "Cochez cette case pour envoyer un rapport aux développeurs" + +#: Client/loader/Dialogs.cpp:86 +msgid "Doing so will increase the chance of this crash being fixed." +msgstr "Cela augmentera les chances que le problème soit résolu." + +#: Client/loader/Dialogs.cpp:87 +msgid "Do you want to restart MTA: San Andreas ?" +msgstr "Voulez-vous redémarrer MTA: San Andreas?" + +#: Client/loader/Dialogs.cpp:94 +msgid "MTA: San Andreas - Warning" +msgstr "MTA: San Andreas - Avertissement" + +#: Client/loader/Dialogs.cpp:95 +msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" +msgstr "Votre répertoire d'installation de Grand Theft Auto: San Andreas contient les fichiers suivants :" + +#: Client/loader/Dialogs.cpp:97 +msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" +"It is recommended that you remove or rename these files." +msgstr "Ces fichiers ne sont pas requis et pourraient interférer avec les fonctionnalités graphiques de cette version de MTA:SA.\n\n" +"Il est recommandé de supprimer ou renommer ces fichiers." + +#: Client/loader/Dialogs.cpp:99 +msgid "Keep these files, but also show this warning on next start" +msgstr "Garder ces fichiers, mais afficher cet avertissement au prochain lancement" + +#: Client/loader/Dialogs.cpp:100 +msgid "Do not remind me about these files again" msgstr "Ne plus m'avertir à propos de ces fichiers à l'avenir" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Remomer ces fichiers de *.dll en *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Afficher les fichiers" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Jouer à MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Options confuses" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus détecté!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Testez chaque option et voyez ce qui fonctionne:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - NVidia Standard" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - NVidia Alternatif" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Intel standard" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Intel alternatif" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Si vous êtes désespérés, ceci pourrait vous aider:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Si vous avez déjà sélectionné une option qui fonctionne, ceci peut vous aider:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Forcer le mode fenêtré" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Ne plus afficher" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Avertissement: Impossible de détecter un anti-virus" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1110 +657,1183 @@ msgstr "MTA n'a pas pu détecter d'anti-virus sur votre ordinateur.\n\n" "Les virus interfèrent avec MTA et dégradent votre expérience de jouabilité...\n\n" "Appuyez sur 'Aide' pour plus d'informations." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "J'ai déjà installé un anti-virus" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Je n'installerai pas d'anti-virus.\n" "Je veux que mon ordinateur soit lent et fasse partie d'un botnet." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "Le crash que vous avez rencontré est dû à un usage abusif de la mémoire par les serveurs.\n\n" +"Même avec beaucoup de RAM, il s'agit d'un jeu x86 avec des limites d'espace d'adressage allant jusqu'à 3,6 Go et certains serveurs très peu optimisés avec de nombreux mods (ou juste quelques scripts mal écrits) peuvent provoquer cela, ainsi que ralentir votre jeu.\n\n" +"Contactez le propriétaire du serveur ou le support MTA sur le discord officiel de MTA (https://discord.gg/mtasa) pour plus d'informations." + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "MTA : San Andreas - Informations sur le manque de mémoire" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Recherche de Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Veuillez démarrer Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Installation de la mise à jour..." - -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Extraction des fichiers..." - -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Copie des fichiers..." - -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "La copie s'est terminée prématurément. Tout va bien." - -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Finition..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "La connexion a échoué. Nom d'utilisateur incorrect!" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Terminé!" +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "La connexion a échoué. Nom d'hôte incorrect!" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 +#: Client/core/CConnectManager.cpp:132 #, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA nécessite un Accès Administrateur pour effectuer la tâche suivante:\n\n" -" '%s'\n\n" -"Veuillez confirmer dans la prochaine fenêtre." +msgid "Connecting to %s at port %u failed!" +msgstr "La connexion à %s:%u a échoué!" -#: Client/loader/CInstallManager.cpp:376 +#. Display the status box +#: Client/core/CConnectManager.cpp:153 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA n'a pas pu accomplir la tâche suivante:\n\n" -" '%s'\n" +msgid "Connecting to %s:%u ..." +msgstr "Connexion à %s:%u ..." -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Ce crash a été causé par une erreur du pilote graphique **\n\n" -"** Veuillez mettre à jour le pilote graphique **" +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "Reconnexion à %s:%u ..." -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Installer les fichiers révisés de MTA:SA" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "CONNEXION" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Impossible de mettre à jour à cause de conflits de fichier. Veuillez fermer les autres programmes et réessayer" +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "La connexion a expiré" -#: Client/loader/CInstallManager.cpp:561 -#, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto n'a pas été installé correctement. Veuillez réinstaller. %s" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Déconnecté: erreur de protocole inconnue." -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "Créer les jonctions GTA:SA" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Déconnecté: déconnecté à distance." -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA ne peut pas être lancé car la copie d'un fichier a échoué:" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Déconnecté: perte de connexion à distance." -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA ne peut pas être lancé car un fichier MTA:SA est incorrect ou manquant:" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Déconnecté: vous êtes banni de ce serveur." -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Copier les fichiers de MTA:SA" +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Déconnecté: déconnecté du serveur." -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA ne peut pas être lancé car un fichier GTA:SA est incorrect ou manquant:" +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Déconnecté: la connexion au serveur a été perdue." -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Patcher la dépendance de GTA:SA" +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Déconnecté: la connexion a été refusée." -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA ne peut pas être lancé car l'exécutable de GTA:SA est incorrect ou manquant:" +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 +#, c-format +msgid "No such mod installed (%s)" +msgstr "Ce mod n'est pas installé (%s)" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Veuillez vérifier votre antivirus pour une détection de faux positifs, essayez d'ajouter une exception pour l'exécutable GTA:SA et redémarrez MTA:SA." +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Réponse du serveur invalide (2)" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Générer GTA:SA" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Réponse du serveur invalide (1)" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA ne peut pas être lancé car l'exécutable de GTA:SA n'est pas chargeable:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Français" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Patcher GTA:SA" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Indisponible" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA ne peut pas être lancé car la correction de GTA:SA a échoué:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Impossible de rechercher une mise à jour actuellement" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 #, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA ne peut pas continuer car il n'y a pas assez d'espace libre sur le lecteur %s." +msgid "MTA:SA %s required" +msgstr "MTA:SA %s nécessaire" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Fichier manquant:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Une mise à jour de MTA:SA %s est nécessaire pour se connecter à ce serveur.\n\n" +"Voulez-vous télécharger et installer MTA:SA %s ?" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Si MTA ne démarre pas, veuillez réinstaller GTA:SA" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Voulez-vous démarrer MTA:SA %s et vous connecter à ce serveur ?" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "MAJ des paramètres d'installation" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Impossible de se connecter actuellement.\n\n" +"Veuillez réessayer plus tard." -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "MAJ des paramètres de compatibilité" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Connexion en cours" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Inconnu" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Veuillez patienter..." -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "Le fichier '%s' est actuellement verrouillé par %zu processus.\n\n" -"Voulez-vous mettre fin aux processus suivants et continuer la mise à jour ?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "VÉRIFICATION" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "Votre installation est peut-être corrompue.\n\n" -"%zu sur %zu fichiers n'ont pas pu être restaurés à partir de la sauvegarde.\n\n" -"Vous devriez réinstaller Multi Theft Auto depuis www.multitheftauto.com\n" -"ou essayez d'exécuter la mise à jour avec les droits d'administrateur." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "VÉRIFICATION DE MISE À JOUR" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Lancez Grand Theft Auto: San Andreas.\n" -"Assurez-vous que le jeu est placé dans le dossier 'Programmes (x86)'." +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Aucune mise à jour nécessaire" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "Recherche de GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "TÉLÉCHARGEMENT EN COURS" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Désolé, jeu introuvable.\n" -"Lancez Grand Theft Auto : San Andreas et cliquez sur Réessayer.\n" -"Assurez-vous que le jeu est placé dans le dossier 'Programmes (x86)'." +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "En attente..." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Sélectionnez le répertoire d'installation de Grand Theft Auto: San Andreas" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "MISE À JOUR OBLIGATOIRE" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Erreur de chargement du module %s! (%s)" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Vous devez mettre à jour MTA pour vous connecter à ce serveur.\n\n" +"Voulez-vous télécharger la mise à jour maintenant?" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Une nouvelle installation de %s a été détectée.\n\n" -"Voulez-vous copier les paramètres à partir de %s ?" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "MISE À JOUR FACULTATIVE" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA a rencontré un problème en ouvrant le fichier '%s'" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Le serveur recommande une mise à jour qui n'est pas essentielle.\n\n" +"Voulez-vous télécharger la mise à jour maintenant?" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA a besoin d'un fichier introuvable: '%s'." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "Aucune mise à jour n’est actuellement disponible\n\n" +"Veuillez vérifier www.multitheftauto.com" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA a rencontré un problème durant le chargement d'un model." +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "ERREUR DE SAUVEGARDE" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Si vous avez récemment modifié gta3.img, essayez de réinstaller GTA:SA." +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Impossible de créer le fichier." -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA a rencontré un problème durant l'ajout d'une amélioration de véhicule." +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "ERREUR DE TÉLÉCHARGEMENT" + +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Le fichier téléchargé semble incorrect." + +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Pour une raison quelconque." + +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "TÉLÉCHARGEMENT TERMINÉ" + +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Problème inconnu dans _DialogUpdateResult" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "FICHIERS GTA:SA PERSONNALISÉS" + +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "OK" + +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "ERREUR" + +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Certains fichiers de MTA:SA sont manquants.\n\n\n" +"Veuillez réinstaller MTA:SA" + +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA a détecté des erreurs dans le fichier '%s'" +msgid "%3d %% completed" +msgstr "%3d%% effectués" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Votre ordinateur a-t-il redémarré alors que vous jouiez à MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Attente d'une réponse - %-3d" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Veuillez fermer les programmes suivants, avant de continuer:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ AIDE DES COMMANDES ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Requêtes de sites web" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Il est %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Le serveur sollicite les sites web suivants, afin de pouvoir les charger:" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "connexion : Le réseau n’est pas prêt, veuillez patienter" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NE JAMAIS ENTRER D'INFORMATIONS SENSIBLES, AFIN D'ÉVITER LE PIRATAGE" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "connect: La syntaxe est 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Se souvenir de la décision" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "connect: Numéro de port invalide" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Autoriser" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "connect: Connexion à %s:%u ..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Refuser" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "connect: Échec de la connexion à %s:%u !" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:543 -msgid "Main menu" -msgstr "Menu principal" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "connect: Impossible de décharger le mod actuel" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Vous utilisez une version de développement! Il s'agit d'une version de test qui ne peut pas être utilisée pour se connecter à des serveurs publics!" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "reconnect : Le réseau n’est pas prêt, veuillez patienter" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA ne recevra plus de mises à jour sur Windows XP/Vista après juillet 2019.\n\n" -"Veuillez mettre à niveau Windows pour jouer sur les serveurs récents." +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "reconnect: Numéro de port invalide" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Vous serez déconnecté du serveur.\n\n" -"Êtes-vous sûr de vouloir continuer?" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "reconnect: Connexion à %s:%u ..." -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "AVERTISSEMENT DE DÉCONNEXION" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "reconnect: Échec de la connexion à %s:%u !" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "INFORMATION" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Tous les contrôles ont été assignés" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Français" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Fichier de configuration enregistré" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Votre numéro de série est: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "PARAMÈTRES" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Multijoueur" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Vidéo" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "PostFX" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Audio" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Touches" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Commandes" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Interface" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Navigateur Web" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Avancé" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Réinitialiser" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Sensibilité de la souris:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Sensibilité de la visée verticale:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Paramètres de souris" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Inverser l'axe vertical" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Diriger avec la souris" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Voler avec la souris" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "Utiliser la sensibilité de la souris pour viser" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Paramètres du joypad" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Commandes standards (souris + clavier)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Commandes classiques (joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Zone morte" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Saturation" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Utilisez l'onglet 'Touches' pour configurer les boutons du joypad." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Stick gauche" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Stick droit" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "DESCRIPTION" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "TOUCHE" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "TOUCHE ALTERNATIVE" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Pseudonyme:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Enregistrer les mots de passe des serveurs" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Actualiser automatiquement l'explorateur de serveurs" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Autoriser l'envoi de captures d'écran" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Autoriser les sons externes" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Toujours afficher la fenêtre de téléchargement" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Autoriser la connexion avec Discord Rich Presence" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "Autoriser l’affichage du statut en jeu de GTA:SA sur Steam" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "Enregistrer les photos prises avec l'appareil photo dans le dossier GTA San Andreas User Files" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "Demander confirmation avant de se déconnecter du serveur via le menu principal" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Utiliser des fichiers GTA:SA personnalisés" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Paramètres de rendu de la carte" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Opacité:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "Résolution d'image:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "1024 x 1024 (Défaut)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Volume principal:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Volume de la radio:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Volume des effets:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "Volume de MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Volume des voix:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Mode de lecture" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Général" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Radio" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Égaliseur" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Auto-tuning" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Pistes utilisateur" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Radio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Aléatoire" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Séquentiel" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Scanner les médias automatiquement" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Sourdine" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Désactiver tous les sons quand le jeu est minimisé" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Désactiver la radio quand le jeu est minimisé" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Désactiver les effets quand le jeu est minimisé" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Désactiver les sons de MTA quand le jeu est minimisé" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Désactiver les voix quand le jeu est minimisé" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Résolution:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Champ de vision:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Distance d'affichage:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Luminosité:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Qualité des effets:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Filtrage anisotrope:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Anticrénelage:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Ratio d'aspect:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Mode fenêtré" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "Prise en charge DPI" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Standard" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Fenêtre sans bordures, résolution native" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "MIP mapping" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "Synchronisation verticale" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Basse" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Moyenne" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Haute" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Maximale" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Désactivé" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Automatique" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "Corriger le HUD" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Ombres volumétriques" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Effet 'herbe'" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Effet 'chaleur'" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Fumée des pneus, etc" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Ombres dynamiques des piétons" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Flou de mouvement" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Reflets de pluie des Corona" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Réduire en Plein Ecran" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Activer la boîte de dialogue 'Sélection du périphérique'" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Afficher toutes les résolutions" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Toujours afficher les véhicules en haute qualité" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Toujours afficher les personnages en haute qualité" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "Gamma :" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "Contraste :" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "Saturation:" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "Appliquer les ajustements en mode fenêtré" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "Appliquer les ajustements en mode plein écran" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Activer les sites web distants" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Activer Javascript sur les sites web distants" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "Activer le rendu GPU" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Liste noire personnalisée" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Entrez un nom de domaine (par ex. google.fr)" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Bloquer" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Domaine" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Supprimer le domaine" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "Tout supprimer" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Liste blanche personnalisée" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Autoriser" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Divers" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Chargement rapide des vêtements de CJ:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Vitesse de l'explorateur:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Connexion unique:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Étiquette de paquet:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Animation de la progression:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Priorité du processus:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Mode debug:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Mémoire de streaming:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Type de version:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Installer les mises à jour importantes:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Activé" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Très lente" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Par défaut" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Rapide" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normale" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Supérieure à la normale" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Min" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Max" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Compatibilité Windows 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "Couleurs 16 bits" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Correctif de souris" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Fichiers de ressources client:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Ouvrir l'Explorateur" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "Définir l’affinité sur le CPU 0 pour améliorer les performances du jeu" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Mise à jour automatique" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Rechercher une mise à jour" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Certains réglages ne seront modifiés qu'après le redémarrage de MTA." -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Voulez-vous redémarrer maintenant?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "REDÉMARRAGE NÉCESSAIRE" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Certains paramètres seront modifiés quand vous vous déconnecterez du serveur actuel" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Voulez-vous vous déconnecter maintenant?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "DÉCONNEXION NÉCESSAIRE" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Aucun joypad détecté - Vérifiez le branchement et redémarrez MTA" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Assignation de l'axe" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Déplacez un axe, ou appuyez sur Esc pour effacer" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Langue:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Thème:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Préréglages:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Tchat" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Charger" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Couleurs" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Disposition" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Options" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Arrière-plan Tchat" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Texte Tchat" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Arrière-plan Entrée" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Texte Entrée" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Lignes:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Échelle:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Largeur:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Taille" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "Après" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "Pendant" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "secondes" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Fondu" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Fondu des anciennes lignes" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horizontale:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Verticale:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Alignement:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "Décalage X:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Décalage Y:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Position" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Gauche" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Centre" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Droite" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Haut" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Bas" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Police" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Masquer l'arrière-plan lorsque vous n'écrivez pas" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Auto-complétion du pseudonyme avec la touche TAB" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Permettre au serveur de flasher la fenêtre" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Autoriser les bulles de notifications" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Contour du texte" @@ -1551,89 +1841,95 @@ msgstr "Contour du texte" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Appuyez sur une touche, ou sur Esc pour effacer" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Assignation d'une touche primaire" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Assignation d'une touche secondaire" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "CONTRÔLES DE GTA" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "CONTRÔLES MULTIJOUEUR" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Votre pseudonyme contient des caractères invalides!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1099 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Menu principal" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "Dans le jeu" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Rouge:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Vert:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Bleu:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Opacité:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Couleur" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Prévisualisation" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Veuillez vous déconnecter afin de changer le langage" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Veuillez vous déconnecter pour pouvoir changer le Thème" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Les ombres volumétriques peuvent provoquer des ralentissement sur certains systèmes.\n\n" "Êtes-vous sûr de vouloir les activer?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "MISE EN GARDE SUR LES PERFORMANCES" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "L'envoi de captures d'écrans est nécessaire sur certains serveurs utilisant l'anti-triche.\n\n" "(Le Tchat et l'Interface Graphique sont exclus de la capture d'écran)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "INFORMATION SUR L'ENVOI DE CAPTURES D'ÉCRANS" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1641,23 +1937,21 @@ msgstr "Certains scripts peuvent lire des sons, comme une radio, à partir d'int "Désactiver cette option peut diminuer la consommation\n" "de la bande passante.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "SONS EXTERNES" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "Il semble que vous ayez activé l'option de connexion Rich Presence.\n" -"Souhaitez-vous autoriser les serveurs à partager leurs données ?\n\n" -"Cela inclut votre identifiant Discord unique." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "CONSENTEMENT À L'ÉCHANGE DE DONNÉES" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1667,11 +1961,7 @@ msgstr "Certains fichiers dans le dossier Data de GTA:SA sont personnalisés.\n" "Cependant, les fichiers personnalisés seront bloqués sur la plupart des serveurs.\n\n" "Êtes-vous sûr de vouloir les utiliser?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "FICHIERS GTA:SA PERSONNALISÉS" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1681,552 +1971,253 @@ msgstr "La prise en charge DPI est une fonctionnalité expérimentale, qui devra "Des problèmes graphiques peuvent apparaître si vous activez cette option.\n\n" "Êtes-vous sûr de vouloir activer cette option?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "FONCTIONNALITÉ EXPÉRIMENTALE" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "Désactiver cette option n'est pas recommandée, sauf si vous rencontrez des problèmes de performances.\n\n" "Êtes-vous sûr de vouloir la désactiver?" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Veuillez saisir un pseudonyme" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Veuillez saisir un pseudonyme. \n" "Ce sera votre nom quand vous vous connecterez et jouerez sur un serveur." -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Fonctionnalité expérimentale." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Empêche les ralentissements avec les variations de CJ (utilise ~65 Mo de RAM)." -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Certains routeurs anciens peuvent nécessiter une vitesse plus faible." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Activez cette fonctionnalité pour n'utiliser qu'une seule connexion pendant les téléchargements." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Étiqueter les paquets pour aider les FAI à identifier le trafic MTA." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Animation en bas de l'écran" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Sélectionnez Par défaut. Ce paramètre n'est pas sauvegardé." -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maximum est généralement préférable." -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Mise à jour automatique:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Sélectionnez Par défaut, sauf si vous aimez remplir des rapports de bug." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Sélectionnez Par défaut pour installer automatiquement les mises à jour importantes." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "Couleurs 16 bits" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Active le mode Couleur 16 bits - Nécessite un redémarrage de MTA." -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Correctif de souris:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Correction du mouvement de la souris - Peut nécessiter un redémarrage de votre ordinateur." -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "Affinité du CPU:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "À modifier uniquement en cas de problèmes de stabilité." -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Commande ou cvar inconnue:" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Indisponible" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Impossible de rechercher une mise à jour actuellement" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s nécessaire" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Une mise à jour de MTA:SA %s est nécessaire pour se connecter à ce serveur.\n\n" -"Voulez-vous télécharger et installer MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Voulez-vous démarrer MTA:SA %s et vous connecter à ce serveur ?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Impossible de se connecter actuellement.\n\n" -"Veuillez réessayer plus tard." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Connexion en cours" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Veuillez patienter..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "VÉRIFICATION" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "VÉRIFICATION DE MISE À JOUR" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Aucune mise à jour nécessaire" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "TÉLÉCHARGEMENT EN COURS" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "En attente..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "MISE À JOUR OBLIGATOIRE" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Vous devez mettre à jour MTA pour vous connecter à ce serveur.\n\n" -"Voulez-vous télécharger la mise à jour maintenant?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "MISE À JOUR FACULTATIVE" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Le serveur recommande une mise à jour qui n'est pas essentielle.\n\n" -"Voulez-vous télécharger la mise à jour maintenant?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "Aucune mise à jour n’est actuellement disponible\n\n" -"Veuillez vérifier www.multitheftauto.com" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "ERREUR DE SAUVEGARDE" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Impossible de créer le fichier." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "ERREUR DE TÉLÉCHARGEMENT" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Le fichier téléchargé semble incorrect." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Pour une raison quelconque." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "TÉLÉCHARGEMENT TERMINÉ" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Problème inconnu dans _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "OK" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "ERREUR" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Certains fichiers de MTA:SA sont manquants.\n\n\n" -"Veuillez réinstaller MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d%% effectués" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Attente d'une réponse - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "La connexion a échoué. Nom d'utilisateur incorrect!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "La connexion a échoué. Nom d'hôte incorrect!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "La connexion à %s:%u a échoué!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Connexion à %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "Reconnexion à %s:%u ..." - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:667 -msgid "CONNECTING" -msgstr "CONNEXION" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1343 -msgid "Connection timed out" -msgstr "La connexion a expiré" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1391 -msgid "Disconnected: unknown protocol error" -msgstr "Déconnecté: erreur de protocole inconnue." - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 -msgid "Disconnected: disconnected remotely" -msgstr "Déconnecté: déconnecté à distance." - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1399 -msgid "Disconnected: connection lost remotely" -msgstr "Déconnecté: perte de connexion à distance." - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1403 -msgid "Disconnected: you are banned from this server" -msgstr "Déconnecté: vous êtes banni de ce serveur." - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1411 -msgid "Disconnected: disconnected from the server" -msgstr "Déconnecté: déconnecté du serveur." - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1415 -msgid "Disconnected: connection to the server was lost" -msgstr "Déconnecté: la connexion au serveur a été perdue." - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1423 -msgid "Disconnected: connection was refused" -msgstr "Déconnecté: la connexion a été refusée." - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Ce mod n'est pas installé (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Réponse du serveur invalide (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Réponse du serveur invalide (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "ACTUALITÉS" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Lire les actualités" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "CONSOLE" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Erreur fatale" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "Pour corriger ce problème, veuillez effacer ce fichier:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "Le module %s est incorrect!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Erreur d'exécution URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "cet écran d'aide" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "quitte l'application" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "affiche la version" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "affiche l'heure" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "affiche le HUD" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "affiche toutes les touches assignées" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "affiche votre numéro de série" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "connexion à un serveur ( [ ] )" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "connexion à un serveur précédent" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "assigne une touche" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "désassigne une touche" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "copie les contrôles par défaut" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "capture d'écran" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "enregistre la configuration" -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "vide la console de débogage" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "fait défiler le tchat vers le haut" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "fait défiler le tchat vers le bas" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "fait défiler la console de débogage vers le haut" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "fait défiler la console de débogage vers le bas" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "affiche les statistiques mémoire" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "affiche le diagramme de synchronisation de trame" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "pour les développeurs : rafraîchir les actualités" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ AIDE DES COMMANDES ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Il est %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "connexion : Le réseau n’est pas prêt, veuillez patienter" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "connect: La syntaxe est 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "connect: Numéro de port invalide" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "connect: Connexion à %s:%u ..." - -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "connect: Échec de la connexion à %s:%u !" - -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "connect: Impossible de décharger le mod actuel" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "vide la console de débogage" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "fait défiler le tchat vers le haut" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "fait défiler le tchat vers le bas" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "fait défiler la console de débogage vers le haut" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "fait défiler la console de débogage vers le bas" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Tous les contrôles ont été assignés" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "affiche les statistiques mémoire" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Fichier de configuration enregistré" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "affiche le diagramme de synchronisation de trame" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Votre numéro de série est: %s" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "pour les développeurs : rafraîchir les actualités" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Axe des gaz" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Vous utilisez une version de développement! Il s'agit d'une version de test qui ne peut pas être utilisée pour se connecter à des serveurs publics!" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Axe des freins" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA ne recevra plus de mises à jour sur Windows XP/Vista après juillet 2019.\n\n" +"Veuillez mettre à niveau Windows pour jouer sur les serveurs récents." -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programmation" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Vous serez déconnecté du serveur.\n\n" +"Êtes-vous sûr de vouloir continuer?" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Contributeurs" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "AVERTISSEMENT DE DÉCONNEXION" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Design et scripting" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "INFORMATION" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Traduction française" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "ACTUALITÉS" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Contributeurs (patches)" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Lire les actualités" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Remerciements particuliers" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "La capture d'écran pèse %d octets, mais devrait peser %d" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Ce logiciel et ce projet utilisent les bibliothèques et logiciels suivants :" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "La capture d'écran a échoué" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Voulez-vous voir de l'aide en ligne à propos de ce problème ?" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Capture d'écran: '%s'" + +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Commande ou cvar inconnue:" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2401,25 +2392,56 @@ msgid "Group control backwards" msgstr "Vers l'arrière (contrôle groupe)" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Le Thème que vous avez sélectionné n'a pas pu être chargé, ni le Thème par défaut. Veuillez réinstaller MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "La capture d'écran pèse %d octets, mais devrait peser %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Voulez-vous voir de l'aide en ligne à propos de ce problème ?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "La capture d'écran a échoué" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "CONSOLE" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Capture d'écran: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programmation" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Contributeurs" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Design et scripting" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Traduction française" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Contributeurs (patches)" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Remerciements particuliers" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Ce logiciel et ce projet utilisent les bibliothèques et logiciels suivants :" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Axe des gaz" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Axe des freins" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2427,6 +2449,61 @@ msgstr "Impossible d'initialiser Direct3D9.\n\n" "Veuillez vous assurer que les Composants d'Exécution Utilisateur Final DirectX et\n" "les derniers Service Packs de Windows sont installés correctement." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Inactif" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "joueur" +msgstr[1] "joueurs" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "sur" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "serveur" +msgstr[1] "serveurs" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Sollicitation de la liste du Serveur principal (%lu ms écoulées)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "La liste du Serveur principal n'a pas pu être analysée." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "La liste du Serveur Principal n'a pas pu être récupérée." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Liste de serveurs à partir d'une sauvegarde)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "Impossible d'établir un socket de diffusion sur le LAN" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Impossible d'établir un socket de diffusion sur le LAN" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Tentative de découverte de serveurs LAN" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2480,7 +2557,7 @@ msgstr "Latence:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Liste des joueurs" @@ -2507,40 +2584,39 @@ msgstr "Se connecter au serveur dès qu'une place est disponible." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "VEUILLEZ SAISIR LE MOT DE PASSE DU SERVEUR" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Délai expiré" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Requête..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "EXPLORATEUR DE SERVEURS" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Local" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Favoris" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Récents" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2548,298 +2624,367 @@ msgstr "POUR LA CONNEXION RAPIDE:\n\n" "Saisir l'adresse et le port dans la barre d'adresse\n" "ou sélectionnez un serveur dans l'Historique." -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "AIDE" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Actualiser" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Ajouter aux Favoris" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Connexion" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Information du serveur" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Rechercher des serveurs" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Rechercher des joueurs" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Démarrer la recherche" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "Supprimer des récents" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Rechercher des joueurs..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Rechercher des serveurs..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Nom" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Joueurs" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Latence" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Mode de jeu" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Inclure:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Vide" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Plein" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Verrouillé" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Hors ligne" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Autres versions" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Retour" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Chargement..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..chargement.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Adresse non spécifiée!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Protocole inconnu" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Veuillez utiliser le protocole mtasa:// !" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:651 -#: Client/mods/deathmatch/logic/CClientGame.cpp:749 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Pseudonyme invalide! Allez dans Paramètres pour le changer!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Vous devez sélectionner un serveur auquel se connecter." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Inactif" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problème avec le pilote graphique" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "joueur" -msgstr[1] "joueurs" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Impossible de trouver une résolution valide." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "sur" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Voulez-vous vraiment utiliser cette résolution d'écran?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "serveur" -msgstr[1] "serveurs" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "Échec de l'initialisation game_sa" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Sollicitation de la liste du Serveur principal (%lu ms écoulées)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "Échec d'allocation de mémoire" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "La liste du Serveur principal n'a pas pu être analysée." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Requêtes de sites web" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "La liste du Serveur Principal n'a pas pu être récupérée." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Le serveur sollicite les sites web suivants, afin de pouvoir les charger:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Liste de serveurs à partir d'une sauvegarde)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NE JAMAIS ENTRER D'INFORMATIONS SENSIBLES, AFIN D'ÉVITER LE PIRATAGE" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Impossible d'établir un socket de diffusion sur le LAN" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Se souvenir de la décision" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Tentative de découverte de serveurs LAN" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Refuser" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Cette version a expirée." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "quitte le serveur" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "affiche les noms des joueurs" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "affiche le tchat" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "affiche les statistiques réseau" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "ouvre la zone de saisie du Tchat" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "active le microphone" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "entrer dans un véhicule en tant que passager" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "station radio suivante" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "station radio précédente" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" -msgstr "" +msgstr "active la map" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" -msgstr "" +msgstr "zoome sur la map" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" -msgstr "" +msgstr "dézoome sur la map" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" -msgstr "" +msgstr "déplace la map vers le nord" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" -msgstr "" +msgstr "déplace la map vers le sud" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" -msgstr "" +msgstr "déplace la map vers l'est" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" -msgstr "" +msgstr "déplace la map vers l'ouest" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" -msgstr "" +msgstr "attache la map au joueur" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" -msgstr "" +msgstr "réduit l'opacité de la map" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" -msgstr "" +msgstr "augmente l'opacité de la map" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" -msgstr "" +msgstr "active/désactive le texte d'aide de la map" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "envoie un message au joueur ciblé" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "sélectionne l'arme suivante en étant dans un véhicule" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "sélectionne l'arme précédente en étant dans un véhicule" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "affiche des informations à propos du serveur actuel" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "définit le multiplicateur d'échelle de tous les textes" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(mode développeur) affiche les colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Mode développeur) affiche les world sound ids dans la fenêtre Debug" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "HÉBERGER UNE PARTIE" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Ressources" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Nom du serveur:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Mot de passe:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Joueurs max. :" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Diffusion:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "Réseau local" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Ressources sélectionnées" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Ressources disponibles" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Démarrer" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "Changer de mode: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "Zoom: %s/%s Mouvement: %s, %s, %s, %s Opacité: %s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "Map: %s Texte d'aide: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "Suivant Joueur" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "Mouvement Libre" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Progression du téléchargement de la carte:" @@ -2860,195 +3005,195 @@ msgstr "%s de %s" msgid "Disconnect to cancel download" msgstr "Déconnectez pour annuler le téléchargement" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Déconnecté: pseudonyme invalide." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Déconnecté du serveur." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Déconnecté: ce Serial est banni.\n" "Motif: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Déconnecté: vous êtes banni.\n" "Motif: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Déconnecté: ce compte est banni.\n" "Motif: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Déconnecté: version incompatible." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Déconnecté: trop de connexions simultanées. Veuillez réessayer dans quelques instants." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Déconnecté: le serveur provient d'une branche différente.\n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Déconnecté: version incorrecte.\n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Déconnecté: le serveur utilise une version plus récente.\n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Déconnecté: le serveur utilise une version plus ancienne.\n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Déconnecté: ce pseudonyme est déjà utilisé." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Déconnecté: l'élément du Joueur n'a pas pu être créé." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Déconnecté: le serveur a refusé la connexion: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Déconnecté: la vérification du Serial a échoué." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" -msgstr "" +msgstr "Déconnecté: votre Serial est déjà utilisé" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Déconnecté: désynchronisation de la connexion: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Déconnecté: vous avez été exclus par %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Déconnecté: vous avez été banni par %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Déconnecté: le serveur est fermé ou redémarre" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Vous avez été exclus du jeu" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Ce serveur nécessite un fichier 'gta_sa.exe' original" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Veuillez remplacer 'gta_sa.exe'" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Ce serveur n'autorise pas les fichiers 'd3d9.dll' modifiés" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Supprimez le fichier 'd3d9.dll' de votre dossier d'installation de GTA:SA et redémarrez MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Ce serveur n'autorise pas les machines virtuelles" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Ce serveur nécessite que la signature de pilotes soit activée" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Veuillez redémarrer votre ordinateur" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Ce serveur a détecté des composants anti-triche manquants" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Essayez de redémarrer MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Ce serveur nécessite des fichiers 'gta3.img' et 'gta_int.img' originaux" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Veuillez remplacer 'gta3.img' et 'gta_int.img'" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Ce serveur n'autorise pas Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Assurez-vous qu'aucun programme ne modifie MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Temps restant:" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d jour" msgstr[1] "%d jours" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d heure" msgstr[1] "%d heures" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d minute" msgstr[1] "%d minutes" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3056,302 +3201,212 @@ msgstr[0] "%d seconde" msgstr[1] "%d secondes" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Déconnecté" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Erreur de téléchargement: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "Pilote un OVNI autour de" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "Se balade à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "Surfe sur les vagues de" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "A bord d'un train à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "En train de survoler" -#: Client/mods/deathmatch/logic/CClientGame.cpp:381 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "En train de rouler à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:381 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "Conduit un Monster Truck à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:381 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "Conduit un Quad à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:382 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "Saute partout à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:382 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "Fait des trucs bizarres à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "Fait de l'escalade à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "En plein drive-by à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "Glou glou..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "En train de se noyer" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "Se noie à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "A l'abri à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "Se bat à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "Se bagarre à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "En train de tirer à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "En pleine fusillade" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "Vole en Jetpack au-dessus de" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "En feu à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "En train de brûler vivant à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "En train de nager à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "Nage autour de" -#: Client/mods/deathmatch/logic/CClientGame.cpp:402 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "Poursuivi par un requin" -#: Client/mods/deathmatch/logic/CClientGame.cpp:403 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "En train d'être étouffé à mort à" -#: Client/mods/deathmatch/logic/CClientGame.cpp:667 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Démarrage de la partie..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:725 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Non connecté. Veuillez utiliser la Connexion Rapide ou la commande 'connect' pour joindre un serveur." -#: Client/mods/deathmatch/logic/CClientGame.cpp:771 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Impossible de démarrer le serveur local. Voir les détails dans la Console." -#: Client/mods/deathmatch/logic/CClientGame.cpp:781 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1253 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Serveur local" -#: Client/mods/deathmatch/logic/CClientGame.cpp:781 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Démarrage du serveur local..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1029 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "Zone 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1038 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "En train de se promener à " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1184 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Vous avez été exclus du jeu ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1253 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Connexion au serveur local..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1264 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Erreur de connexion au serveur." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "La connexion au serveur local a expirée. Voir les détails dans la Console." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "La connexion au serveur a été perdue" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1407 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Déconnecté: le serveur est plein." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1419 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Déconnecté: mot de passe invalide." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1441 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "La vérification du Client MTA a échoué!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5642 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "Dans un fossé" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5642 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "En route vers l'hôpital" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5642 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "Sur le chemin du paradis" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5643 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "En train de regretter ses décisions" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5643 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "Mort" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "HÉBERGER UNE PARTIE" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Ressources" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Nom du serveur:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Mot de passe:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Joueurs max. :" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Diffusion:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "Réseau local" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Ressources sélectionnées" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Ressources disponibles" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Démarrer" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problème avec le pilote graphique" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Impossible de trouver une résolution valide." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Voulez-vous vraiment utiliser cette résolution d'écran?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Erreur de téléchargement: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 #, c-format msgid "Fatal error (%u). If this problem persists, please check out multitheftauto.com for support." -msgstr "" +msgstr "Erreur fatale (%u). Si le problème persiste, veuillez consulter multitheftauto.com pour obtenir de l'aide." #. #ifdef MTA_DEBUG #. assert ( 0 ); @@ -3360,17 +3415,17 @@ msgstr "" #: Shared/mods/deathmatch/logic/Utils.cpp:143 #, c-format msgid "Protocol error (%u). If this problem persists, please check out multitheftauto.com for support." -msgstr "" +msgstr "Erreur de protocole (%u). Si ce problème persiste, veuillez consulter multitheftauto.com pour obtenir de l'aide." #: Shared/mods/deathmatch/logic/Utils.cpp:145 msgid "Connection error" msgstr "Erreur de connexion" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto n'a pas été installé correctement. Veuillez réinstaller." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Votre navigateur va s'ouvrir sur une page Web contenant de l'aide.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/he_IL/client.pot b/Shared/data/MTA San Andreas/MTA/locale/he_IL/client.pot index 77646fd8d49..e7134771f8f 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/he_IL/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/he_IL/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Hebrew\n" "Language: he_IL\n" @@ -17,228 +17,439 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "שגי××”" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "" + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "" + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "" + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "" + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" msgstr "" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "" + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "" + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "" + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "" + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" msgstr "" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "" -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" msgstr "" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "" -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "שגי××”" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "" -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "" -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." msgstr "" -#: Client/loader/MainFunctions.cpp:810 +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "" -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "" -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "" -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "" -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Data file %s is modified. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." msgstr "" -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" msgstr "" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" msgstr "" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA ×œ× ×™×›×•×œ×” להמשיך ×›×™ כונן %s ×ין בו מספיק זיכרון." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" msgstr "" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" msgstr "" #. ///////////////////////////////////////////////////////////////////////// @@ -247,1258 +458,1336 @@ msgstr "" #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "כן" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "ל×" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "×ישור" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "עזרה" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "ביטול" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "" -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." msgstr "" -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "" -#: Client/loader/Dialogs.cpp:678 -msgid "Searching for Grand Theft Auto San Andreas" -msgstr "" - -#: Client/loader/Dialogs.cpp:681 -msgid "Please start Grand Theft Auto San Andreas" +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." msgstr "" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" msgstr "" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." +#: Client/loader/Dialogs.cpp:1024 +msgid "Searching for Grand Theft Auto San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." +#: Client/loader/Dialogs.cpp:1027 +msgid "Please start Grand Theft Auto San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "" +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "ההתחברות נכשלה. הכינוי ×ינו תקין!" -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" msgstr "" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 +#. Display the status box +#: Client/core/CConnectManager.cpp:153 #, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "" +msgid "Connecting to %s:%u ..." +msgstr "מתחבר ל-%s:%u..." -#: Client/loader/CInstallManager.cpp:376 +#: Client/core/CConnectManager.cpp:155 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" +msgid "Reconnecting to %s:%u ..." msgstr "" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "מתחבר" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "פג זמנה של ההתחברות" + +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "התנתקות: שגי××” ×œ× ×™×“×•×¢×” בפרוטוקול" + +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" msgstr "" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" msgstr "" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "התנתקות: נחסמת מן השרת" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "התנתקות: התנתקות מהשרת" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "החיבור ×ל השרת נותק." + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "התנתקות: ההתחברות נדחתה" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "" +msgid "No such mod installed (%s)" +msgstr "מוד שכזה ×ינו מותקן (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" msgstr "" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" msgstr "" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "×נגלית" + +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" msgstr "" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" msgstr "" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" msgstr "" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" msgstr "" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" msgstr "" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." msgstr "" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" msgstr "" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." msgstr "" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" msgstr "" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" msgstr "" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA ×œ× ×™×›×•×œ×” להמשיך ×›×™ כונן %s ×ין בו מספיק זיכרון." +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" msgstr "" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." msgstr "" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" msgstr "" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" msgstr "" -#: Client/loader/Install.cpp:265 -msgid "Unknown" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" msgstr "" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" msgstr "" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." msgstr "" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" msgstr "" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." msgstr "" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." msgstr "" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" msgstr "" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" msgstr "" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" msgstr "" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" msgstr "" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" msgstr "" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" msgstr "" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" +msgid "%3d %% completed" msgstr "" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" msgstr "" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ עזרה בפקודה ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* השעה ×”×™× %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "התחברות: הסינטקס ×”×•× 'התחברות <הוסט> [<פורט> <ש×> <סיסמה>]'" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "התחברות: פורט שגוי" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "התחברות: מתחבר ל-%s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "התחברות: נכשלה ההתחברות ×ל %s:%u!" + +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "התחברות: נכשלה הפריקה של מצב המשחק הנוכחי" + +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" msgstr "" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "תפריט ר×שי" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "תנותק מהשרת הנוכחי.\n\n" -"×תה בטוח ש×תה מעוניין להתנתק?" - -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "×זהרת התנתקות" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "חוברו כל המפתחות מGTA" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "התצורה הנוכחית נשמרה" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "×נגלית" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* מספרך הסידורי הו×: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "הגדרות" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "ויד×ו" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "טען ברירות מחדל" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "רגישות עכבר:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "" -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "תי×ור" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "מקש" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "מקש ALT" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "ברירת מחדל" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "שמ×ל" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "ימין" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "" @@ -1506,662 +1795,371 @@ msgstr "" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "תפריט ר×שי" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "בזמן משחק" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" "Are you sure you want to use them?" msgstr "" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" "Are you sure you want to enable this option?" msgstr "" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "" -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "" -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "" -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "" -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "" -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "" -#: Client/core/CSettings.cpp:4999 -msgid "Mouse fix:" -msgstr "" - -#: Client/core/CSettings.cpp:4999 -msgid "Mouse movement fix - May need PC restart" -msgstr "" - -#: Client/core/CSettings.cpp:5001 -msgid "CPU affinity:" -msgstr "" - -#: Client/core/CSettings.cpp:5001 -msgid "Only change if you're having stability issues." -msgstr "" - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "ההתחברות נכשלה. הכינוי ×ינו תקין!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "מתחבר ל-%s:%u..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "מתחבר" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "פג זמנה של ההתחברות" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "התנתקות: שגי××” ×œ× ×™×“×•×¢×” בפרוטוקול" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "התנתקות: נחסמת מן השרת" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "התנתקות: התנתקות מהשרת" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "החיבור ×ל השרת נותק." - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "התנתקות: ההתחברות נדחתה" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "מוד שכזה ×ינו מותקן (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" +#: Client/core/CSettings.cpp:6041 +msgid "Mouse fix:" msgstr "" -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "עדכוני×" +#: Client/core/CSettings.cpp:6041 +msgid "Mouse movement fix - May need PC restart" +msgstr "" -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "לבקר ×ת עמוד ×”×¢×“×›×•× ×™× ×”×¨×חרון" +#: Client/core/CSettings.cpp:6043 +msgid "CPU affinity:" +msgstr "" -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "קונסולה" +#: Client/core/CSettings.cpp:6043 +msgid "Only change if you're having stability issues." +msgstr "" -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "שגי×ת מערכת" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "כדי לתקן, הסיר קובץ ×–×”:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "מודול של %s ×ינו נכון!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "שגי××” בהעל×ת URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "חלון עזרה ×–×”" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "×™×•×¦× ×ž×”×™×™×©×•×" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "מציג ×ת הגרס×" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "מציג ×ת השעה" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "מציג ×ת ×”-HUD" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "לר×ות ×ת כל המפתחות" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "מר××” ×ת המספר הסירי×לי שלך" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "מתחבר לשרת קוד×" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "מעתיק ×ת בקרת המחדל של GTA" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "שומר ×ת התצורה מיידית" -#: Client/core/CCore.cpp:1391 +#: Client/core/CCore.cpp:1494 msgid "clears the debug view" msgstr "" -#: Client/core/CCore.cpp:1392 +#: Client/core/CCore.cpp:1495 msgid "scrolls the chatbox upwards" msgstr "" -#: Client/core/CCore.cpp:1393 +#: Client/core/CCore.cpp:1496 msgid "scrolls the chatbox downwards" msgstr "" -#: Client/core/CCore.cpp:1394 +#: Client/core/CCore.cpp:1497 msgid "scrolls the debug view upwards" msgstr "" -#: Client/core/CCore.cpp:1395 +#: Client/core/CCore.cpp:1498 msgid "scrolls the debug view downwards" msgstr "" -#: Client/core/CCore.cpp:1398 +#: Client/core/CCore.cpp:1501 msgid "shows the memory statistics" msgstr "מציג ×ת סטטיסטיקות הזיכרון" -#: Client/core/CCore.cpp:1399 +#: Client/core/CCore.cpp:1502 msgid "shows the frame timing graph" msgstr "" -#: Client/core/CCore.cpp:1403 +#: Client/core/CCore.cpp:1506 msgid "for developers: reload news" msgstr "" -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ עזרה בפקודה ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* השעה ×”×™× %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" msgstr "" -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "התחברות: הסינטקס ×”×•× 'התחברות <הוסט> [<פורט> <ש×> <סיסמה>]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "התחברות: פורט שגוי" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "התחברות: מתחבר ל-%s:%u..." +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "התחברות: נכשלה ההתחברות ×ל %s:%u!" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "תנותק מהשרת הנוכחי.\n\n" +"×תה בטוח ש×תה מעוניין להתנתק?" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "התחברות: נכשלה הפריקה של מצב המשחק הנוכחי" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "×זהרת התנתקות" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" msgstr "" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "עדכוני×" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "לבקר ×ת עמוד ×”×¢×“×›×•× ×™× ×”×¨×חרון" -#: Client/core/CCommandFuncs.cpp:325 +#: Client/core/CScreenShot.cpp:200 #, c-format -msgid "reconnect: could not connect to %s:%u!" +msgid "Screenshot got %d bytes, but expected %d" msgstr "" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "חוברו כל המפתחות מGTA" - -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "התצורה הנוכחית נשמרה" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "צילו×-מסך נכשל" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 +#: Client/core/CScreenShot.cpp:256 #, c-format -msgid "* Your serial is: %s" -msgstr "* מספרך הסידורי הו×: %s" - -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "ציר ×”×צה" - -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "ציר בלימה" - -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "תכנות" - -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "תורמי×" - -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "עיצוב משחק \\ סקריפטי×" - -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" +msgid "Screenshot taken: '%s'" msgstr "" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "×ª×•×¨×ž×™× ×œ×˜×œ××™" - -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "תודה מיוחדת" - -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " msgstr "" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "×¨×•×¦×™× ×¢×–×¨×” לגבי בעיה זו ב×ינטרנט?" - #: Client/core/CKeyBinds.cpp:186 msgid "Fire" msgstr "×ש" @@ -2335,30 +2333,120 @@ msgid "Group control backwards" msgstr "מפתח קבוצה ×חורה" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "הדמות שבחרת ×œ× × ×˜×¢× ×”, וכן דמות ברירת המחדל, ×× × ×”×ª×§×Ÿ מחדש ×ת MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "×¨×•×¦×™× ×¢×–×¨×” לגבי בעיה זו ב×ינטרנט?" + +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "קונסולה" + +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "תכנות" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "תורמי×" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "עיצוב משחק \\ סקריפטי×" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" msgstr "" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "צילו×-מסך נכשל" +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "×ª×•×¨×ž×™× ×œ×˜×œ××™" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "תודה מיוחדת" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" msgstr "" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "ציר ×”×צה" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "ציר בלימה" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." msgstr "" +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(גבה רשימת שרתי×)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2412,7 +2500,7 @@ msgstr "" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "רשימת שחקני×" @@ -2439,341 +2527,405 @@ msgstr "" msgid "PLEASE ENTER SERVER PASSWORD" msgstr "" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "" #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "×ינטרנט" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "עזרה" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "רענן" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "הוסף למועדפי×" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "התחברות" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "מידע שרת" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "חפש שרתי×" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "חפש שחקני×" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "התחל בחיפוש" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "כלול:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "ריק" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "מל×" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "נעול" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "מנותק" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "גרס×ות ×חרות" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "כינוי שגוי! ×× × ×©× ×” ×ותו דרך לוח ההגדרות!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(גבה רשימת שרתי×)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "" -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "סיסמ×:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "" @@ -2794,167 +2946,167 @@ msgstr "" msgid "Disconnect to cancel download" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" @@ -2963,7 +3115,7 @@ msgstr[1] "" msgstr[2] "" msgstr[3] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" @@ -2972,7 +3124,7 @@ msgstr[1] "" msgstr[2] "" msgstr[3] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" @@ -2981,7 +3133,7 @@ msgstr[1] "" msgstr[2] "" msgstr[3] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -2991,295 +3143,205 @@ msgstr[2] "" msgstr[3] "" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "סיסמ×:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "" - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" +msgid "Download error: %s" msgstr "" #. Populate the message and show the box @@ -3301,11 +3363,11 @@ msgstr "" msgid "Connection error" msgstr "" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "" -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "" diff --git a/Shared/data/MTA San Andreas/MTA/locale/hi_IN/client.pot b/Shared/data/MTA San Andreas/MTA/locale/hi_IN/client.pot index 8c521de68a1..0fa7a5a3f21 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/hi_IN/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/hi_IN/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:32\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Hindi\n" "Language: hi_IN\n" @@ -17,228 +17,439 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Kharabi" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "" + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "" + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "" + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "" + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "समापà¥à¤¤!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "" + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "" + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "" + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "" + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" msgstr "" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" msgstr "" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "" -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "फà¥à¤²à¤¸à¥à¤•à¥à¤°à¥€à¤¨ मोड:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "बॉरà¥à¤¡à¤°à¤²à¥‡à¤¸ विंडो" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" msgstr "" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "जानकारी" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "" -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Kharabi" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "" -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "" -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." msgstr "" -#: Client/loader/MainFunctions.cpp:810 +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "" -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "" -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "" -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "" -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Data file %s is modified. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "अननोन" + +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." msgstr "" -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" msgstr "" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" msgstr "" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" msgstr "" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" msgstr "" #. ///////////////////////////////////////////////////////////////////////// @@ -247,1258 +458,1336 @@ msgstr "" #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Yes" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "नहीं" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "ओके" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "कà¥à¤µà¤¿à¤Ÿ" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "सहायता" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "कैंसिल" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "" -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "MTA:SA खेल" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "दोबारा न दिखाà¤à¤‚" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." msgstr "" -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "" -#: Client/loader/Dialogs.cpp:678 -msgid "Searching for Grand Theft Auto San Andreas" +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." msgstr "" -#: Client/loader/Dialogs.cpp:681 -msgid "Please start Grand Theft Auto San Andreas" -msgstr "" - -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" msgstr "" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." +#: Client/loader/Dialogs.cpp:1024 +msgid "Searching for Grand Theft Auto San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." +#: Client/loader/Dialogs.cpp:1027 +msgid "Please start Grand Theft Auto San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "" +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "कनेकà¥à¤Ÿ करना विफल रहा. अमानà¥à¤¯ नाम पà¥à¤°à¤¦à¤¾à¤¨ किया गया!" -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "" +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "कनेकà¥à¤Ÿ करना विफल रहा। अमानà¥à¤¯ होसà¥à¤Ÿ पà¥à¤°à¤¦à¤¾à¤¨ किया गया!" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "समापà¥à¤¤!" +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "पोरà¥à¤Ÿ %u पर %s से कनेकà¥à¤Ÿ करना विफल!" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 +#. Display the status box +#: Client/core/CConnectManager.cpp:153 #, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "" +msgid "Connecting to %s:%u ..." +msgstr "%s:%u ... से कनेकà¥à¤Ÿ हो रहा है:" -#: Client/loader/CInstallManager.cpp:376 +#: Client/core/CConnectManager.cpp:155 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" +msgid "Reconnecting to %s:%u ..." msgstr "" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "कनेकà¥à¤Ÿà¤¿à¤‚ग" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "" +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "कनेकà¥à¤¶à¤¨ का समय समापà¥à¤¤" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "डिसà¥à¤•नेकà¥à¤Ÿ किया गया: अजà¥à¤žà¤¾à¤¤ पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल तà¥à¤°à¥à¤Ÿà¤¿" -#: Client/loader/CInstallManager.cpp:561 -#, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" msgstr "" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" msgstr "" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" msgstr "" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" msgstr "" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" msgstr "" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" msgstr "" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 +#, c-format +msgid "No such mod installed (%s)" msgstr "" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" msgstr "" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" msgstr "" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "अंगà¥à¤°à¥‡à¤œà¥€" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "वà¥à¤¯à¤¸à¥à¤¤" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" msgstr "" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" msgstr "" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 +#: Client/core/CVersionUpdater.cpp:1631 #, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" msgstr "" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" msgstr "" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." msgstr "" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "कनेकà¥à¤Ÿà¤¿à¤‚ग" + +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "कृपया पà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾ करें..." + +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" msgstr "" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" msgstr "" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "अननोन" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" msgstr "" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "पà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾ करे" + +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" msgstr "" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" msgstr "" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" msgstr "" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" msgstr "" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." msgstr "" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" msgstr "" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." msgstr "" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." msgstr "" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" msgstr "" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" msgstr "" -#: Client/loader/Utils.cpp:1631 -#, c-format -msgid "GTA:SA found errors in the file '%s'" +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" msgstr "" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "ठीक है" + +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" msgstr "" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ आदेश मदद ]***\n" + +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* समय है %d:%02d:%02d" + +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "मेरा फैसला याद रखे" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "कनेकà¥à¤Ÿ: सिंटेकà¥à¤¸ ' [ ] कनेकà¥à¤Ÿ' है" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "अनà¥à¤®à¤¤ करें" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "कनेकà¥à¤Ÿ: बà¥à¤°à¤¾ पोरà¥à¤Ÿ संखà¥à¤¯à¤¾" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "मना करना" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "कनेकà¥à¤Ÿ:%s से कनेकà¥à¤Ÿ कर रहा है:%u" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "मà¥à¤–à¥à¤¯ मेनू" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "Connect: %s:%u ko connect nahi keya ja raha ha!" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "आप फीचर-बà¥à¤°à¤¾à¤‚च बिलà¥à¤¡ का उपयोग कर रहे हैं! यह केवल à¤à¤• टेसà¥à¤Ÿ बिलà¥à¤¡ है जिसका उपयोग सारà¥à¤µà¤œà¤¨à¤¿à¤• सरà¥à¤µà¤° से कनेकà¥à¤Ÿ करने के लिठनहीं किया जा सकता है!" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "Connect: mojuda mod ko nikalna ma aasafal raha" + +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "" + +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA को जà¥à¤²à¤¾à¤ˆ 2019 के बाद XP/Vista पर अपडेट पà¥à¤°à¤¾à¤ªà¥à¤¤ नहीं होंगे।" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "यह आपको वरà¥à¤¤à¤®à¤¾à¤¨ सरà¥à¤µà¤° से डिसà¥à¤•नेकà¥à¤Ÿ कर देगा।" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "डिसà¥à¤•नेकà¥à¤Ÿ चेतावनी\n" -"#: कà¥à¤²à¤¾à¤‡à¤‚ट/कोर/सीà¤à¤®à¤®à¥‡à¤¨à¤®à¥‡à¤¨à¥‚.सीपीपी:1150" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "sara GTA control bound ho gaya" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" msgstr "" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "अंगà¥à¤°à¥‡à¤œà¥€" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* आपका सीरियल है: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "सेटिंग" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "मलà¥à¤Ÿà¥€à¤ªà¥à¤²à¥‡à¤¯à¤°" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "वीडियो" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "ऑडियो" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "बाइंड" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "कनà¥à¤Ÿà¥à¤°à¥‹à¤²à¥à¤œà¤¼" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "इंटरफेस" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "वेब बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤°" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "à¤à¤¡à¤µà¤¾à¤‚सà¥à¤¡" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "लोड डिफॉलà¥à¤Ÿ" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "माउस सेनà¥à¤¸à¤¿à¤Ÿà¤¿à¤µà¤¿à¤Ÿà¥€:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "वरà¥à¤Ÿà¤¿à¤•ल à¤à¤® सेनà¥à¤¸à¤¿à¤Ÿà¤¿à¤µà¤¿à¤Ÿà¥€:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "माउस ऑपà¥à¤¶à¤¨" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "इनà¥à¤µà¤°à¥à¤Ÿ माउस वरà¥à¤Ÿà¤¿à¤•à¥à¤²à¥€" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "सà¥à¤Ÿà¤¿à¤° विद माउस" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "फà¥à¤²à¤¾à¤‡ विद माउस" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "जॉयपैड ऑपà¥à¤¶à¤¨" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "सà¥à¤Ÿà¥ˆà¤¨à¥à¤¡à¤°à¥à¤¡ कनà¥à¤Ÿà¥à¤°à¥‹à¤²à¥à¤œà¤¼ (माउस + कीबोरà¥à¤¡)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "कà¥à¤²à¥ˆà¤¸à¤¿à¤• कनà¥à¤Ÿà¥à¤°à¥‹à¤²à¥à¤œà¤¼ (जॉयपैड)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "डेड ज़ोन" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "सैचरेशन" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "यूस द \"बाइनà¥à¤¡\" टैब फॉर जॉयपैड बटन।" -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "लेफà¥à¤Ÿ सà¥à¤Ÿà¤¿à¤•" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "राइट सà¥à¤Ÿà¤¿à¤•" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "डिसà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤¶à¤¨" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "बटन" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ऑलà¥à¤Ÿà¤°à¥à¤¨à¤Ÿà¤¿à¤µ बटन" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "नेम:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "सेव सरà¥à¤µà¤° पैसà¥à¤µà¤°à¥à¤¡" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "ऑटो-रिफà¥à¤°à¥‡à¤¶ सरà¥à¤µà¤° बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤°" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "सà¥à¤•à¥à¤°à¥€à¤¨ अपलोड की अनà¥à¤®à¤¤à¤¿ दें" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "बाहरी साउंड की अनà¥à¤®à¤¤à¤¿ दें" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "हमेशा डाउनलोड विंडो दिखाà¤à¤‚" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "डिसà¥à¤•ॉरà¥à¤¡ रिच पà¥à¤°à¥‡à¤œà¥‡à¤‚स को चालू की अनà¥à¤®à¤¤à¤¿ दें" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "उसे कसà¥à¤Ÿà¤®à¤¾à¤‡à¤œà¥à¤¡ GTA:SA फाइलà¥à¤¸" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "ओपैसटी" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "मासà¥à¤Ÿà¤° वोलà¥à¤¯à¥‚म:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "रेडीओ वॉलà¥à¤¯à¥‚म:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "SFX वॉलà¥à¤¯à¥‚म:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA वॉलà¥à¤¯à¥‚म:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "वॉइस वॉलà¥à¤¯à¥‚म:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "पà¥à¤²à¥‡ मोड:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "जेनरल" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "रेडीओ आपà¥à¤¶à¤¨" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "रेडीओ ईकà¥à¤µà¤²à¤¾à¤‡à¤œà¤¼à¤°" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "रेडीओ ऑटो-टून" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "यूज़रटà¥à¤°à¥ˆà¤• आपà¥à¤¶à¤¨" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "रेडियो" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "रैंडम" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "सेकेंटिअल" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "मà¥à¤¯à¥‚ट ऑपà¥à¤¶à¤¨" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "रेजोलà¥à¤¯à¥à¤¶à¤¨:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "FOV:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "डà¥à¤°à¤¾ डिसà¥à¤Ÿà¥‡à¤‚स:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "बà¥à¤°à¤¾à¤‡à¤Ÿà¤¨à¥‡à¤¸:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX कà¥à¤µà¤¾à¤²à¤¿à¤Ÿà¥€:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "आइसोटà¥à¤°à¥‰à¤ªà¤¿à¤• फ़िलà¥à¤Ÿà¤°à¤¿à¤‚ग:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "à¤à¤‚टी-अलियासिंग:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "à¤à¤¸à¥à¤ªà¥‡à¤•à¥à¤Ÿ रैशीओ:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "विंडोड" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI अवेयर" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "सà¥à¤Ÿà¥ˆà¤£à¥à¤¡à¤°à¥à¤¡" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "बॉरà¥à¤¡à¤°à¤²à¥‡à¤¸ कीप रेसोलà¥à¤¶à¤¨" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "कम" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "मीडियम" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "हाई" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "वैरी हाई" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "बंद" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "ऑटो" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "बà¥à¤²à¥‰à¤•" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "डोमेन" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "डोमेन निकालें" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "अनà¥à¤®à¤¤ करें" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "विविध" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "चालू" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "फ़ासà¥à¤Ÿ" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "नारà¥à¤®à¤²" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "सामानà¥à¤¯ से ऊपर" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "सà¥à¤•िन:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "पà¥à¤°à¥€à¤¸à¥‡à¤Ÿ:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "लाइनà¥à¤¸" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "सà¥à¤•ेल:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "चौड़ाई:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "साइज" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "बादमें" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "के लिये" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "सेकंड" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "फडिंग" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "हॉरिज़ोंटल:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "वरà¥à¤Ÿà¤¿à¤•ल:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "पोजीशन" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "बाà¤à¤‚" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "सेणà¥à¤Ÿà¤°" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "दाà¤à¤" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "टॉप" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "बॉटम" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "फ़ॉनà¥à¤Ÿ" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "" @@ -1506,662 +1795,371 @@ msgstr "" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "मà¥à¤–à¥à¤¯ मेनू" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "इन गेम" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "लाल:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "हरा:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "नीला:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "टà¥à¤°à¤¾à¤‚सपेरेंट:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "रंग" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "पà¥à¤°à¥€à¤µà¥à¤¯à¥‚" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" "Are you sure you want to use them?" msgstr "" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" "Are you sure you want to enable this option?" msgstr "" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "" -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "" -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "" -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "" -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "" -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "" -#: Client/core/CSettings.cpp:4999 -msgid "Mouse fix:" -msgstr "" - -#: Client/core/CSettings.cpp:4999 -msgid "Mouse movement fix - May need PC restart" -msgstr "" - -#: Client/core/CSettings.cpp:5001 -msgid "CPU affinity:" -msgstr "" - -#: Client/core/CSettings.cpp:5001 -msgid "Only change if you're having stability issues." -msgstr "" - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "वà¥à¤¯à¤¸à¥à¤¤" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "कनेकà¥à¤Ÿà¤¿à¤‚ग" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "कृपया पà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾ करें..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "पà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾ करे" - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "ठीक है" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "कनेकà¥à¤Ÿ करना विफल रहा. अमानà¥à¤¯ नाम पà¥à¤°à¤¦à¤¾à¤¨ किया गया!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "कनेकà¥à¤Ÿ करना विफल रहा। अमानà¥à¤¯ होसà¥à¤Ÿ पà¥à¤°à¤¦à¤¾à¤¨ किया गया!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "पोरà¥à¤Ÿ %u पर %s से कनेकà¥à¤Ÿ करना विफल!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "%s:%u ... से कनेकà¥à¤Ÿ हो रहा है:" - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "कनेकà¥à¤Ÿà¤¿à¤‚ग" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "कनेकà¥à¤¶à¤¨ का समय समापà¥à¤¤" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "डिसà¥à¤•नेकà¥à¤Ÿ किया गया: अजà¥à¤žà¤¾à¤¤ पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल तà¥à¤°à¥à¤Ÿà¤¿" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" +#: Client/core/CSettings.cpp:6041 +msgid "Mouse fix:" msgstr "" -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "नà¥à¤¯à¥‚ज़" +#: Client/core/CSettings.cpp:6041 +msgid "Mouse movement fix - May need PC restart" +msgstr "" -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "नवीनतम समाचार लेख पर जाà¤à¤" +#: Client/core/CSettings.cpp:6043 +msgid "CPU affinity:" +msgstr "" -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "कानà¥à¤¸à¥‹à¤²" +#: Client/core/CSettings.cpp:6043 +msgid "Only change if you're having stability issues." +msgstr "" -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "फेटल à¤à¤°à¤°" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "समय दिखाता है" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "हà¥à¤¡ दिखाता है" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "सभी बैंडà¥à¤¸ दिखाता है" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "आपका सीरियल दिखाता है" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "सरà¥à¤µà¤° से जà¥à¥œà¤¤à¤¾ है (host port nick pass)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "पिछले सरà¥à¤µà¤° से जà¥à¥œà¤¤à¤¾ है" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "à¤à¤• बटन बांधता है (बटन नियंतà¥à¤°à¤£)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "बटन निकलता है (बटन)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "सà¥à¤•à¥à¤°à¥€à¤¨à¤¶à¥‰à¤Ÿ ले" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "" -#: Client/core/CCore.cpp:1391 +#: Client/core/CCore.cpp:1494 msgid "clears the debug view" msgstr "" -#: Client/core/CCore.cpp:1392 +#: Client/core/CCore.cpp:1495 msgid "scrolls the chatbox upwards" msgstr "" -#: Client/core/CCore.cpp:1393 +#: Client/core/CCore.cpp:1496 msgid "scrolls the chatbox downwards" msgstr "" -#: Client/core/CCore.cpp:1394 +#: Client/core/CCore.cpp:1497 msgid "scrolls the debug view upwards" msgstr "" -#: Client/core/CCore.cpp:1395 +#: Client/core/CCore.cpp:1498 msgid "scrolls the debug view downwards" msgstr "" -#: Client/core/CCore.cpp:1398 +#: Client/core/CCore.cpp:1501 msgid "shows the memory statistics" msgstr "" -#: Client/core/CCore.cpp:1399 +#: Client/core/CCore.cpp:1502 msgid "shows the frame timing graph" msgstr "" -#: Client/core/CCore.cpp:1403 +#: Client/core/CCore.cpp:1506 msgid "for developers: reload news" msgstr "" -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ आदेश मदद ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* समय है %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "कनेकà¥à¤Ÿ: सिंटेकà¥à¤¸ ' [ ] कनेकà¥à¤Ÿ' है" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "कनेकà¥à¤Ÿ: बà¥à¤°à¤¾ पोरà¥à¤Ÿ संखà¥à¤¯à¤¾" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "आप फीचर-बà¥à¤°à¤¾à¤‚च बिलà¥à¤¡ का उपयोग कर रहे हैं! यह केवल à¤à¤• टेसà¥à¤Ÿ बिलà¥à¤¡ है जिसका उपयोग सारà¥à¤µà¤œà¤¨à¤¿à¤• सरà¥à¤µà¤° से कनेकà¥à¤Ÿ करने के लिठनहीं किया जा सकता है!" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "कनेकà¥à¤Ÿ:%s से कनेकà¥à¤Ÿ कर रहा है:%u" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA को जà¥à¤²à¤¾à¤ˆ 2019 के बाद XP/Vista पर अपडेट पà¥à¤°à¤¾à¤ªà¥à¤¤ नहीं होंगे।" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "Connect: %s:%u ko connect nahi keya ja raha ha!" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "यह आपको वरà¥à¤¤à¤®à¤¾à¤¨ सरà¥à¤µà¤° से डिसà¥à¤•नेकà¥à¤Ÿ कर देगा।" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "Connect: mojuda mod ko nikalna ma aasafal raha" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "डिसà¥à¤•नेकà¥à¤Ÿ चेतावनी\n" +"#: कà¥à¤²à¤¾à¤‡à¤‚ट/कोर/सीà¤à¤®à¤®à¥‡à¤¨à¤®à¥‡à¤¨à¥‚.सीपीपी:1150" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" msgstr "" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "नà¥à¤¯à¥‚ज़" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "नवीनतम समाचार लेख पर जाà¤à¤" -#: Client/core/CCommandFuncs.cpp:325 +#: Client/core/CScreenShot.cpp:200 #, c-format -msgid "reconnect: could not connect to %s:%u!" +msgid "Screenshot got %d bytes, but expected %d" msgstr "" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "sara GTA control bound ho gaya" - -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" msgstr "" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 +#: Client/core/CScreenShot.cpp:256 #, c-format -msgid "* Your serial is: %s" -msgstr "* आपका सीरियल है: %s" - -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "गति की à¤à¤•à¥à¤¸à¤¿à¤¸" - -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "बà¥à¤°à¥‡à¤• की à¤à¤•à¥à¤¸à¤¿à¤¸" - -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤®à¤¿à¤‚ग" - -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "सहयोगी" - -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "" - -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" +msgid "Screenshot taken: '%s'" msgstr "" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "पैच कंटà¥à¤°à¥€à¤¬à¥à¤¯à¥à¤Ÿà¤°à¥à¤¸" - -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "विशेष धनà¥à¤¯à¤µà¤¾à¤¦" - -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " msgstr "" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "कà¥à¤¯à¤¾ आप इस समसà¥à¤¯à¤¾ के बारे में कà¥à¤› ऑनलाइन सहायता देखना चाहते हैं?" - #: Client/core/CKeyBinds.cpp:186 msgid "Fire" msgstr "फायर" @@ -2335,30 +2333,116 @@ msgid "Group control backwards" msgstr "" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "" -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "कà¥à¤¯à¤¾ आप इस समसà¥à¤¯à¤¾ के बारे में कà¥à¤› ऑनलाइन सहायता देखना चाहते हैं?" + +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "कानà¥à¤¸à¥‹à¤²" + +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤®à¤¿à¤‚ग" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "सहयोगी" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" msgstr "" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" msgstr "" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "पैच कंटà¥à¤°à¥€à¤¬à¥à¤¯à¥à¤Ÿà¤°à¥à¤¸" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "विशेष धनà¥à¤¯à¤µà¤¾à¤¦" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" msgstr "" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "गति की à¤à¤•à¥à¤¸à¤¿à¤¸" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "बà¥à¤°à¥‡à¤• की à¤à¤•à¥à¤¸à¤¿à¤¸" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." msgstr "" +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "इडली" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "पà¥à¤²à¥‡à¤¯à¤°" +msgstr[1] "पà¥à¤²à¥‡à¤¯à¤°à¥à¤¸" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "चालू" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "सरà¥à¤µà¤°" +msgstr[1] "" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2412,7 +2496,7 @@ msgstr "लेटेंसी:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "पà¥à¤²à¥‡à¤¯à¤° लिसà¥à¤Ÿ" @@ -2439,337 +2523,405 @@ msgstr "" msgid "PLEASE ENTER SERVER PASSWORD" msgstr "" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "" #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "नाम" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "पà¥à¤²à¥‡à¤¯à¤°à¥à¤¸" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "पिंग" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "गेममोड" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "शामिल:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "खाली" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "भरा हà¥à¤†" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "बंद" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "ऑफ़लाइन" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "पीछे" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "इडली" - -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "पà¥à¤²à¥‡à¤¯à¤°" -msgstr[1] "पà¥à¤²à¥‡à¤¯à¤°à¥à¤¸" - -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "चालू" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "सरà¥à¤µà¤°" -msgstr[1] "" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "मेरा फैसला याद रखे" + +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "मना करना" + +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "यह संसà¥à¤•रण समापà¥à¤¤ हो चà¥à¤•ा है." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "खेल से डिसà¥à¤•नेकà¥à¤Ÿ करें" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "नेमटैग दिखाता है" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "चैटबॉकà¥à¤¸ दिखाता है" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "नेटवरà¥à¤• आà¤à¤•ड़े दिखाता है" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "चैट इनपà¥à¤Ÿ खोलें" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "अनà¥à¤¯ खिलाड़ियों तक आवाज पहà¥à¤‚चाता है" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "यातà¥à¤°à¥€ के रूप में कार में पà¥à¤°à¤µà¥‡à¤¶ करता है" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "अगला रेडियो चैनल" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "पिछला रेडियो चैनल" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "सरà¥à¤µà¤° नाम:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "पासवरà¥à¤¡:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "सारे" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "शà¥à¤°à¥‚ करें" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "" @@ -2790,188 +2942,188 @@ msgstr "%s का %s" msgid "Disconnect to cancel download" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d दिन" msgstr[1] "%d दिन" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d घंटा" msgstr[1] "%d घंटे" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d मिनट" msgstr[1] "%d मिनट" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -2979,296 +3131,206 @@ msgstr[0] "%d सेकंड" msgstr[1] "%d सेकंड" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "डिसकनेकà¥à¤Ÿ हो गया है" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "डाउनलोड à¤à¤°à¤°: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "सरà¥à¤µà¤° नाम:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "पासवरà¥à¤¡:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "सारे" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "शà¥à¤°à¥‚ करें" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "" - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "डाउनलोड à¤à¤°à¤°: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3289,11 +3351,11 @@ msgstr "" msgid "Connection error" msgstr "कनेकà¥à¤¶à¤¨ à¤à¤°à¤°" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "" -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "" diff --git a/Shared/data/MTA San Andreas/MTA/locale/hr_HR/client.pot b/Shared/data/MTA San Andreas/MTA/locale/hr_HR/client.pot index e0eab9bea71..c3906e9b4d6 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/hr_HR/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/hr_HR/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:32\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Croatian\n" "Language: hr_HR\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Kvar u ponovnom pokretanju MTA:SA\n\n" -"Ako problem ustraje, otvorite Task Manager i\n" -"zaustavite 'gta_sa.exe' i 'Multi Theft Auto.exe' procese\n\n\n" -"PokuÅ¡aj pokrenuti MTA:SA opet?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "PogreÅ¡ka" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Jedna instanca MTA je već pokrenuta.\n\n" -"Ako ovaj problem ustraje, molimo da ponovno pokrenite vaÅ¡e raÄunalo." +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Jedna instanca MTA je već pokrenuta.\n\n" -"Želite li je okonÄati?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Odaberite vaÅ¡ Grand Theft Auto: San Andreas Instalacijski Direktorij" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA treba dozvolu Administratora za sljedeći zadatak:\n\n" +"'%s'\n\n" +"Molimo potvrdite u sljedećem prozoru." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "PogreÅ¡ka uÄitavanja %s module! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Kopiranje fajlova..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopija zavrÅ¡ena ranije. Sve OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "ZavrÅ¡avam..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "ZavrÅ¡eno!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Nova instalacija %s je pronaÄ‘ena.\n\n" +"Želite li kopirati svoje postavke iz %s?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA je imao problema s otvaranjem datoteke '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "Nedostaje datoteka '%s' u GTA:SA." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA je imao poteÅ¡koća pri uÄitavanju modela." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Ako ste nedavno mijenjali gta3.img, pokuÅ¡ajte reinstalacijom GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA je imao poteÅ¡koća pri dodavanju dodatka na vozilo." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA je pronaÅ¡ao greÅ¡ke u datoteci '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Je li se VaÅ¡e raÄunalo ponovno pokrenulo tijekom igranja MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Molimo ugasite sljedeće programe prije nego Å¡to nastavite:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "GreÅ¡ka neusklaÄ‘enosti verzije datoteke. Ponovno instalirajte MTA:SA ako doživite probleme.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Neke datoteke nedostaju. Ponovno instalirajte MTA:SA ako uoÄite probleme.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA nije kompatibilan sa sigurnim naÄinom rada Windowsa.\n\n" +"Molimo ponovno pokrenite svoje raÄunalo.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Imate li probleme s pokretanjem MTA:SA?.\n\n" "Želite li se vratiti na raniju verziju?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "ÄŒini se da postoji problem s pokretanjem MTA:SA.\n" "Resetiranje GTA postavka može ponekada popraviti ovaj problem.\n\n" "Želite li resetirati GTA postavke sada?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA postavke su resetirane.\n\n" "Pritisnike OK za nastavak." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Fajl nije mogao biti izbrisan: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Imate li problema s pokretanjem MTA:SA?.\n\n" "Želite li vidjeti neku online pomoć?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Imate problem s pokretanjem MTA:SA?.\n\n" "Želite li promijeniti sljedeću postavku?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Preko punog zaslona:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Prozor bez okvira" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Imate problem s pokretanjem MTA:SA?.\n\n" "PokuÅ¡ajte s onesposobljavanjem sljedećih proizvoda za GTA i MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,128 +189,288 @@ msgstr "UPOZORENJE\n\n" "MTA:SA je prepoznao neobiÄnu aktivnost.\n" "Molimo pokrenite skeniranje na viruse da biste bili sigurni da je VaÅ¡ sistem siguran.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "PronaÄ‘ena datoteka je: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Instanca GTA:SA je već pokrenuta. Mora biti prekinuta prije nego li MTA:SA može biti pokrenut. Želite li to uÄiniti sada?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informacije" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Nemoguće prekinuti GTA: San Andreas. Ako problem ustraje, molimo ponovno pokrenite vaÅ¡e raÄunalo." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Kvar u ponovnom pokretanju MTA:SA\n\n" +"Ako problem ustraje, otvorite Task Manager i\n" +"zaustavite 'gta_sa.exe' i 'Multi Theft Auto.exe' procese\n\n\n" +"PokuÅ¡aj pokrenuti MTA:SA opet?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "PogreÅ¡ka" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Jedna instanca MTA je već pokrenuta.\n\n" +"Ako ovaj problem ustraje, molimo da ponovno pokrenite vaÅ¡e raÄunalo." + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Jedna instanca MTA je već pokrenuta.\n\n" +"Želite li je okonÄati?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Unosi registra nedostaju. Molimo ponovno instalirajte Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Put do vaÅ¡e GTA: San Andreas instalacije sadrži nepodržane (unikod) znakove.Molimo pomaknite vaÅ¡u Grand Theft Auto: San Andreas instalaciju na kompatibilno mjesto koje sadrži samo standardne ASCII znakove i ponovno instalirajte Multi Theft Auto: San Andreas. " -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Direktorij od instalacije 'MTA:SA' ili 'GTA: San Andreas'\n" -"sadrži ';' (toÄka-zarez).\n\n" -" Ukoliko budete imali problema tijekom koriÅ¡tenja MTA:SA,\n" -" premjestite instalaciju(e) u direktorij koji ne sadrži toÄku-zarez." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "UÄitavanje neuspjeÅ¡no. Uvjerite se da su zadnje data datoteke instalirane pravilno." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "UÄitavanje neuspjelo. Molimo uvjerite se da je %s instaliran ispravno." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "UÄitavanje neuspjelo. Nije moguće pronaći gta_sa.exe u %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "UÄitavanje neuspjelo. %s postoji u GTA direktoriju. Molimo izbriÅ¡ite ga prije nastavljanja." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Glavna datoteka ima pogreÅ¡no ime (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Glavna datoteka je neupisana. Moguća aktivnost virusa.\n\n" -"Potražite pomoć na internetu ako MTA ne radi kako treba." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 +#, c-format +msgid "Data file %s is modified. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" +msgstr "RjeÅ¡avanje problema s konfiguracijom" + +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/Install.cpp:479 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asi datoteke su pronaÄ‘ene u 'MTA:SA' ili 'GTA: San Andreas' instalacijskim datotekama.\n\n" -"Uklonite te .asi datoteke ako uoÄite probleme sa MTA:SA." +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Instalacija dogradnji..." -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "GreÅ¡ka neusklaÄ‘enosti verzije datoteke. Ponovno instalirajte MTA:SA ako doživite probleme.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Otpakiravam datoteke..." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Neke datoteke nedostaju. Ponovno instalirajte MTA:SA ako uoÄite probleme.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA nije mogao dovrÅ¡iti sljedeći zadatak:\n\n" +"'%s'\n" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA nije kompatibilan sa sigurnim naÄinom rada Windowsa.\n\n" -"Molimo ponovno pokrenite svoje raÄunalo.\n" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Pad je uzrokovan greÅ¡kom drivera grafiÄke kartice **\n\n" +"** Molimo ažurirajte svoje drivere grafiÄke kartice **" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" -msgstr "RjeÅ¡avanje problema s konfiguracijom" +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Instaliraj ažurirane MTA:SA fajlove." + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Nemoguće nadograditi zbog sukoba datoteka. Molimo zatvorite ostale aplikacije i pokuÅ¡ajte ponovno" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto nije instaliran prikladno, molimo instalirajte ponovno. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Ispravite 'elevation required' pogreÅ¡ku" +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Nije moguće pokrenuti Grand Theft Auto: San Andreas. Molimo pokuÅ¡ajte pokrenuti ponovno, ili ako problem ustraje, kontaktirajte MTA na www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA ne može nastaviti jer disk %s nema dovoljno prostora." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Nedostaje datoteka:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Ako se MTA ne uÄita, molimo ponovno instalirajte GTA:SA" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas se možda nije pokrenuo ispravno. Želite li ga zaustaviti?" +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Nadogradi instalacijske postavke" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Ažuriraj postavke kompatibilnosti" #. ///////////////////////////////////////////////////////////////////////// #. @@ -268,166 +478,166 @@ msgstr "GTA: San Andreas se možda nije pokrenuo ispravno. Želite li ga zaustav #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Da" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Ne" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "U redu" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Izlaz" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Pomoć" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Odustani" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas je naiÅ¡ao na problem" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Informacije o padu" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "OznaÄite kućicu da biste poslali informacije o padu MTA programerima koristeći 'internet'" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Ovom akcijom povećava se Å¡ansa da se pad popravi." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Želite li ponovno pokrenuti MTA: San Andreas ?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Upozorenje" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Igraj MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Zbunjujuće opcije" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus otkriven!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "PokuÅ¡ajte svaku opciju i vidite Å¡to radi:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Standardna NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Alternativna NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Ako postanete bespomoćni, ovo može pomoći:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Prisili prozorni naÄin" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Upozorenje: Nemoguće pronaći anti-virusni softver" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -435,1102 +645,1180 @@ msgstr "MTA nije uspio pronaći anti-virusni program na VaÅ¡em raÄunalu.\n\n" "Virusi se mogu umijeÅ¡ati u MTA i smanjiti vaÅ¡e iskustvo u igri.\n\n" "Pritisnite 'Pomoć' za viÅ¡e informacija." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Već sam instalirao anti-virusni program" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Ne želim instalirati anti virusni program.\n" "Želim da moje raÄunalo bude usporeno." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "U potrazi za Grand Theft Auto San Andreasom" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Molimo pokrenite Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Instalacija dogradnji..." - -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Otpakiravam datoteke..." - -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Kopiranje fajlova..." - -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopija zavrÅ¡ena ranije. Sve OK." - -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "ZavrÅ¡avam..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Povezivanje neuspjelo. Nevažeći nadimak unesen!" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "ZavrÅ¡eno!" +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Povezivanje neuspjelo. Nevažeći poslužitelj unesen!" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 +#: Client/core/CConnectManager.cpp:132 #, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA treba dozvolu Administratora za sljedeći zadatak:\n\n" -"'%s'\n\n" -"Molimo potvrdite u sljedećem prozoru." +msgid "Connecting to %s at port %u failed!" +msgstr "Povezivanje na %s sa portom %u je neuspjelo!" -#: Client/loader/CInstallManager.cpp:376 +#. Display the status box +#: Client/core/CConnectManager.cpp:153 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA nije mogao dovrÅ¡iti sljedeći zadatak:\n\n" -"'%s'\n" - -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Pad je uzrokovan greÅ¡kom drivera grafiÄke kartice **\n\n" -"** Molimo ažurirajte svoje drivere grafiÄke kartice **" - -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Instaliraj ažurirane MTA:SA fajlove." - -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Nemoguće nadograditi zbog sukoba datoteka. Molimo zatvorite ostale aplikacije i pokuÅ¡ajte ponovno" +msgid "Connecting to %s:%u ..." +msgstr "Povezivanje na %s:%u ..." -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:155 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto nije instaliran prikladno, molimo instalirajte ponovno. %s" - -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "" - -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "" - -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgid "Reconnecting to %s:%u ..." msgstr "" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "POVEZIVANJE" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "" +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Veza je istekla" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Odspojeni: nepoznata greÅ¡ka protokola" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Odspojeni: odspojeni ste daljinski" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Odspojeni: veza izgubljena daljinski" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Odspojeni: trajno ste izbaÄeni sa ovog servera" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "" +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Odspojeni: odspojeni sa servera" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "" +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Odspojeni: veza sa serverom se izgubila" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "" +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Odspojeni: veza je odbijena" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA ne može nastaviti jer disk %s nema dovoljno prostora." +msgid "No such mod installed (%s)" +msgstr "Takva modifikacija nije instalirana (%s)" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Nedostaje datoteka:" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "PogreÅ¡an odgovor poslužitelja (2)" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Ako se MTA ne uÄita, molimo ponovno instalirajte GTA:SA" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "PogreÅ¡an odgovor poslužitelja (1)" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Nadogradi instalacijske postavke" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Hrvatski" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Ažuriraj postavke kompatibilnosti" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Zauzeto" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Ne možete provjeriti za nove nadogradnje trenutno" -#: Client/loader/Install.cpp:272 +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 #, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "" +msgid "MTA:SA %s required" +msgstr "MTA:SA %s potreban" -#: Client/loader/Install.cpp:479 +#: Client/core/CVersionUpdater.cpp:1631 #, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "" +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "NadograÄ‘ena verzija MTA:SA %s je potrebna da se možete pridružiti odabranom serveru.\n\n" +"Želite li skinuti i instalirati MTA:SA %s ?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Želite li pokrenuti MTA:SA %s i povezati se na ovaj server ?" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Nije se moguće povezati u ovo vrijeme.\n\n" +"Molimo pokuÅ¡ajte kasnije." -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Povezivanje" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Odaberite vaÅ¡ Grand Theft Auto: San Andreas Instalacijski Direktorij" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Molimo priÄekajte..." -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "PogreÅ¡ka uÄitavanja %s module! (%s)" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "PROVJERAVANJE" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Nova instalacija %s je pronaÄ‘ena.\n\n" -"Želite li kopirati svoje postavke iz %s?" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "PROVJERA AŽURIRANJA" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA je imao problema s otvaranjem datoteke '%s'" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Nije potrebno ažuriranje" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "Nedostaje datoteka '%s' u GTA:SA." +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "SKIDANJE" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA je imao poteÅ¡koća pri uÄitavanju modela." +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "Äekanje..." -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Ako ste nedavno mijenjali gta3.img, pokuÅ¡ajte reinstalacijom GTA:SA." +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "OBAVEZNO AŽURIRANJE" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA je imao poteÅ¡koća pri dodavanju dodatka na vozilo." +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Da bi se mogli pridružiti ovom serveru, morate nadograditi MTA.\n\n" +"Želite li nadograditi sada ?" -#: Client/loader/Utils.cpp:1631 -#, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA je pronaÅ¡ao greÅ¡ke u datoteci '%s'" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "IZBORNO AŽURIRANJE" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Je li se VaÅ¡e raÄunalo ponovno pokrenulo tijekom igranja MTA:SA?" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Poslužitelj preporuÄa nadogradnju, ali ne osnovnu.\n\n" +"Želite li nadograditi sada ?" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Molimo ugasite sljedeće programe prije nego Å¡to nastavite:" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Zahtjevi web stranice" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "POGREÅ KA PRI SPREMANJU" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Server zahtijeva sljedeće web stranice kako bi ih uÄitao (kasnije):" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Nije moguće izraditi datoteku." -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NIKADA NE UNOSITE OSJETLJIVE PODATKE DA SPRIJEÄŒITE NJIHOVU KRAÄU" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "POGREÅ KA PRI SKIDANJU" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Zapamti odluku" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Skinuta datoteka je neispravna." -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Dopusti" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Za neki razlog." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Odbij" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "SKIDANJE ZAVRÅ ENO" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Nepoznati problem u _DialogUpdateResult" + +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "PROMIJENJENE GTA:SA DATOTEKE" + +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "U redu" + +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "GREÅ KA" + +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Neke MTA:SA datoteke nedostaju.\n\n\n" +"Molimo ponovno instalirajte MTA:SA." + +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% gotovo" + +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"ÄŒekanje odgovora - %-3d" + +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ KOMANDA POMOĆ ]***\n" + +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Vrijeme %d:%02d:%02d" + +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Upotrebljavate gradiliÅ¡te znaÄajki! Ovo je samo test koji se ne može koristiti za povezivanje s javnim poslužiteljima!" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "connect: Sintaksa je 'connect [ ]'" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA prestaje sa ažuriranjima na XP/Vista nakon srpnja 2019-e godine.\n\n" -"Ako želite igrati na najnovijim serverima nadogradite Windows." +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "connect: LoÅ¡ broj porta" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Odspojit će te se sa trenutnog servera.\n\n" -"Jeste li sigurni da se želite odspojiti?" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "connect: Povezivanje na %s:%u..." -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "ODSPAJANJE UPOZORENJE" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "connect: nemoguće povezati na %s:%u!" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "connect: Neuspjeh u iskrcavanju trenutnog moda" + +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" msgstr "" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Hrvatski" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" + +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" + +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "" + +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Preuzmi sve kontrole iz GTA" + +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Konfiguracijska datoteka je spremljena" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* VaÅ¡ serijski broj je: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "POSTAVKE" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Slika" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Zvuk" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Povezane kontrole" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Kontrole" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "SuÄelje" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Internet preglednik" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Napredno" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "UÄitaj zadano" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Osjetljivost miÅ¡a:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Osjetljivost vertikalnog ciljnika:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Postavke miÅ¡a" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Vertikalno okreni miÅ¡" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Vozi miÅ¡em" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Leti miÅ¡em" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Joypad postavke" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standardne kontrole (MiÅ¡ + Tipkovnica)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "KlasiÄne kontrole (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Mrtva Zona" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Zasićenje" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Koristite 'Povezane kontrole' za joypad tipke." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Lijeva palica" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Desna palica" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "OPIS" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "TIPKA" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. TIPKA" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Nadimak:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Spremi lozinke servera" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Automatski-osvježi pretraživaÄ" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Dopusti upload zaslona" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Koristi prilagoÄ‘ene GTA:SA datoteke" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Postavke uÄitavanja mape" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Neprozirnost:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Glavna glasnoća:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "JaÄina zvuka radija:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "JaÄina zvuka efekata:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "JaÄina zvuka igre:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "JaÄina zvuka glasa:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "NaÄin igre:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Općenito" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Radio mogućnosti" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Radijski ujednaÄivaÄ" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "SamopodeÅ¡avanje radija" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Postavke korisniÄkih zapisa" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "NasumiÄno" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Sekvencionalni" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Automatsko Skeniranje Medija" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Opcije utiÅ¡avanja" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "UtiÅ¡aj sve zvukove kada je minimizirano" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "IskljuÄi zvukove radija kada je minimizirano" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "IskljuÄi zvukove efekata kada je minimizirano" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "IskljuÄi MTA zvukove kada je minimizirano" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "IskljuÄi zvukove glasa kada je minimizirano" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Rezolucija:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Udaljenost slike:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Udaljenost Slike:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Svjetlina:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX Kvaliteta:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anizotropno filtriranje:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "ZaglaÄ‘ivanje rubova:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Omjer prikaza:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "U prozoru" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Standardno" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Rezolucija bez rubova" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mip Mapiranje" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Nisko" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Srednje" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Visoko" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Vrlo visoko" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "IskljuÄeno" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Automatski" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD rejting prilagodbe" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "VolumetriÄne sjene" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Efekt trave" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Toplinska magla" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Dim guma itd" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Minimiziraj Puni Zaslon" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Omogući prozor za odabir ureÄ‘aja" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Pokaži nesigurne rezolucije" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Prikazuj vozila uvijek s visokim detaljima" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Omogući udaljene web stranice" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Omogući Javascript na udaljenim web stranicama" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Blokirano po izboru" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Unesi domenu npr. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Blokiraj" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Domena" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Ukloni domenu" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "DopuÅ¡teno po izboru" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Dopusti" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Razno" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Brzo uÄitavanje CJ-eve odjeće:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Brzina pretraživaÄa:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Jednostavna veza:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Oznaka paketa:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Napredak animacije:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Prioritet procesa:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Debug postavka:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Memorija strujanja:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Tip ažuriranja:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Instaliraj važna ažuriranja:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "UkljuÄeno" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Vrlo sporo" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "UobiÄajeno" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Brzo" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normalno" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Iznad prosjeka" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Minimalno" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Maksimalno" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 kompatibilnost:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-bitna boja" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "MiÅ¡ fix" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Klijentske datoteke resursa:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Pokaži u pretraživaÄu" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Automatsko ažuriranje" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Provjeri za nadogradnju" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Neke postavke će se promijeniti kada ponovno upalite MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Želite li ponovno pokrenuti sada?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "PONOVNO POKRETANJE POTREBNO" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Neke postavke će se promijeniti kada se odspojite s trenutnog servera" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Želite li se odspojiti sada?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "ODSPAJANJE POTREBNO" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad nije detektiran - Provjerite veze i ponovno pokrenite igru" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Povezna os" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Pomakni os za povezivanje, ili escape za brisanje" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Jezik:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "PodeÅ¡enja:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "ÄŒavrljanje" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "UÄitaj" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Boje" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Izgled" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Opcije" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Pozadina chat-a" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Tekst ÄŒavrljanja" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Pozadina unosa" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Ulazni Tekst" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Linije:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Skaliranje:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Å irina:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "VeliÄina" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "poslije" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "za" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "sek" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "BlijeÄ‘enje" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Postepeno blijedi stari tekst" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horizontalno:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Vertikalno:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Poravnanje teksta:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-pomak:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-Pomak:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Položaj" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Lijevo" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Centar" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Desno" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Vrh" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Dno" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Sakrij pozadinu kada se ne tipka" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Nadopunjavanje nadimaka koristeći \"Tab\" tipku" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Dopusti serveru treperenje prozora" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Dozvoli obavijesti alatne trake" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Crno/bijelo podebljanje teksta" @@ -1538,109 +1826,115 @@ msgstr "Crno/bijelo podebljanje teksta" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Pritisni tipku za povezivanje, ili escape za brisanje" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Povezivanje primarne tipke" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Povezivanje sekundarne tipke" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA KONTROLE" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "MULTIPLAYER KONTROLE" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "VaÅ¡ nadimak sadrži neispravne znakove!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Crveno:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Zeleno:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Plava:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Prozirnost:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Boja" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Pregled" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Molimo odspojite se prije mijenjanja jezika" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Molimo odspojite se prije mijenjanja skin-a" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "VolumetriÄne sjene mogu uzrokovati usporavanje nekih sistema.\n\n" "Jeste li sigurni da ih želite omogućiti?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "UPOZORENJE ZA PERFORMANSE" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Upload zaslona je potreban za neke poslužitelje zbog anti-cheat razloga.\n\n" "(Chat i grafiÄko suÄelje nisu ukljuÄeni u upload)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "INFORMACIJA UPLOAD-a ZASLONA" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1650,561 +1944,259 @@ msgstr "Neki fajlovi u vaÅ¡em GTA:SA direktoriju podataka su promijenjeni.\n" "MeÄ‘utim, PROMIJENJENI GTA:SA FAJLOVI SU BLOKIRANI OD VEĆINE SERVERA\n\n" "Jeste li sigurni da ih želite koristiti?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "PROMIJENJENE GTA:SA DATOTEKE" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" "Are you sure you want to enable this option?" msgstr "" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Molimo unesite nadimak" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Molimo unesite nadimak koji će biti koriÅ¡ten u igri. \n" "Ovo će biti vaÅ¡e ime kada se povežete i igrate na poslužitelju" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Vrlo eksperimentalna znaÄajka." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Zaustavlja staje s CJ-ovim varijacijama (Koristi 65MB viÅ¡e RAMA)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Stariji routeri mogu zahtijevati sporiju brzinu skeniranja." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "UkljuÄi da koristiÅ¡ samo jednu vezu pri skidanju." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "OznaÄi mrežne pakete da biste pomogli pružatelju internet usluge pri identifikaciji MTA prometa." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Kružna animacija pri dnu zaslona" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Odaberi zadano uvijek. (Ova postavka nije snimljena)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maksimum je obiÄno najbolji" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Automatska provjera ažuriranja:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Izaberi zadano osim ako voliÅ¡ popunjavati velike izvjeÅ¡taje bugova." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Odaberite zadano da biste automatski instalirali važna ažuriranja." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-bitna boja" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Omogući 16-bitne naÄine boja - Zahtijeva ponovno pokretanje MTA" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "MiÅ¡ fix:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Popravak pomicanja miÅ¡a - Može zahtijevati ponovno pokretanje raÄunala" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Nepoznata naredba ili klijentska varijabla: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Zauzeto" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Ne možete provjeriti za nove nadogradnje trenutno" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s potreban" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "NadograÄ‘ena verzija MTA:SA %s je potrebna da se možete pridružiti odabranom serveru.\n\n" -"Želite li skinuti i instalirati MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Želite li pokrenuti MTA:SA %s i povezati se na ovaj server ?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Nije se moguće povezati u ovo vrijeme.\n\n" -"Molimo pokuÅ¡ajte kasnije." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Povezivanje" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Molimo priÄekajte..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "PROVJERAVANJE" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "PROVJERA AŽURIRANJA" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Nije potrebno ažuriranje" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "SKIDANJE" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "Äekanje..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "OBAVEZNO AŽURIRANJE" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Da bi se mogli pridružiti ovom serveru, morate nadograditi MTA.\n\n" -"Želite li nadograditi sada ?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "IZBORNO AŽURIRANJE" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Poslužitelj preporuÄa nadogradnju, ali ne osnovnu.\n\n" -"Želite li nadograditi sada ?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "POGREÅ KA PRI SPREMANJU" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Nije moguće izraditi datoteku." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "POGREÅ KA PRI SKIDANJU" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Skinuta datoteka je neispravna." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Za neki razlog." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "SKIDANJE ZAVRÅ ENO" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Nepoznati problem u _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "U redu" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "GREÅ KA" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Neke MTA:SA datoteke nedostaju.\n\n\n" -"Molimo ponovno instalirajte MTA:SA." - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% gotovo" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"ÄŒekanje odgovora - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Povezivanje neuspjelo. Nevažeći nadimak unesen!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Povezivanje neuspjelo. Nevažeći poslužitelj unesen!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Povezivanje na %s sa portom %u je neuspjelo!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Povezivanje na %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "POVEZIVANJE" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Veza je istekla" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Odspojeni: nepoznata greÅ¡ka protokola" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Odspojeni: odspojeni ste daljinski" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Odspojeni: veza izgubljena daljinski" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Odspojeni: trajno ste izbaÄeni sa ovog servera" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Odspojeni: odspojeni sa servera" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Odspojeni: veza sa serverom se izgubila" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Odspojeni: veza je odbijena" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Takva modifikacija nije instalirana (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "PogreÅ¡an odgovor poslužitelja (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "PogreÅ¡an odgovor poslužitelja (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONZOLA" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Ozbiljna greÅ¡ka" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "ZA POPRAVAK, UKLONITE OVU DATOTEKU:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "Modul %s je neispravan!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "PogreÅ¡ka tijekom izvrÅ¡avanja URL-a" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "ovaj pomoćni zaslon" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "izlazi iz aplikacije" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "pokazuje verziju" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "prikazuje vrijeme" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "prikazuje hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "prikazuje sve kontrole" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "prikazuje tvoj serijski broj" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "spaja se na server (poslužitelj port nadimak lozinka)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "spaja se na prethodni server" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "veže tipku (tipka kontrole)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "odvezuje tipku (tipka)" -#: Client/core/CCore.cpp:1387 -msgid "copies the default gta controls" -msgstr "kopira zadane GTA kontrole" - -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "izbacuje fotografiju" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "odmah sprema konfiguraciju" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "Äisti debug pregled" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "pomiÄe Äavrljanje nagore" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "pomiÄe Äavrljanje nadolje" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "pomiÄe debug nagore" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "pomiÄe debug nadolje" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "prikazuje statistike memorije" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "prikazuje okvir vremenskog grafa" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ KOMANDA POMOĆ ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Vrijeme %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "connect: Sintaksa je 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "connect: LoÅ¡ broj porta" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "connect: Povezivanje na %s:%u..." - -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "connect: nemoguće povezati na %s:%u!" - -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "connect: Neuspjeh u iskrcavanju trenutnog moda" +#: Client/core/CCore.cpp:1490 +msgid "copies the default gta controls" +msgstr "kopira zadane GTA kontrole" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "izbacuje fotografiju" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "odmah sprema konfiguraciju" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "Äisti debug pregled" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "pomiÄe Äavrljanje nagore" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Preuzmi sve kontrole iz GTA" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "pomiÄe Äavrljanje nadolje" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Konfiguracijska datoteka je spremljena" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "pomiÄe debug nagore" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* VaÅ¡ serijski broj je: %s" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "pomiÄe debug nadolje" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Os ubrzanja" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "prikazuje statistike memorije" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Os koÄnice" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "prikazuje okvir vremenskog grafa" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programiranje" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Doprinositelji" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Upotrebljavate gradiliÅ¡te znaÄajki! Ovo je samo test koji se ne može koristiti za povezivanje s javnim poslužiteljima!" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Dizajn igre / Skriptanje" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA prestaje sa ažuriranjima na XP/Vista nakon srpnja 2019-e godine.\n\n" +"Ako želite igrati na najnovijim serverima nadogradite Windows." -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Lokalizacija jezika" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Odspojit će te se sa trenutnog servera.\n\n" +"Jeste li sigurni da se želite odspojiti?" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Doprinositelji zakrpa" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "ODSPAJANJE UPOZORENJE" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Posebne zahvale" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" msgstr "" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Želite li vidjeti online pomoć oko ovog problema ?" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "" + +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Uslikavanje dobilo %d bajta, ali oÄekivano je %d" + +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Uslikavanje neuspjelo" + +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Screenshot uzet: '%s'" + +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Nepoznata naredba ili klijentska varijabla: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2379,25 +2371,56 @@ msgid "Group control backwards" msgstr "Grupna kontrola nazad" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Model kojeg ste izabrali nije se mogao uÄitati, te se takoÄ‘er zadani model nije mogao uÄitati, molimo ponovno instalirajte MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Uslikavanje dobilo %d bajta, ali oÄekivano je %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Želite li vidjeti online pomoć oko ovog problema ?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Uslikavanje neuspjelo" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONZOLA" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Screenshot uzet: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programiranje" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Doprinositelji" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Dizajn igre / Skriptanje" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Lokalizacija jezika" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Doprinositelji zakrpa" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Posebne zahvale" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Os ubrzanja" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Os koÄnice" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2405,6 +2428,63 @@ msgstr "Nije moguće uÄitati Direct3D9.\n\n" "Molimo provjerite imate li instalirane DirectX End-User Runtime i\n" "posljednje Windows servisne zakrpe." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Mirovanje" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "igraÄ" +msgstr[1] "igraÄi" +msgstr[2] "igraÄi" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "ukljuÄen" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "poslužitelj" +msgstr[1] "poslužitelji" +msgstr[2] "" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Zahtijevanje glavne liste svih poslužitelja (proteklo %lu ms)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Glavna lista poslužitelja nije mogla biti analizirana." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Glavna lista poslužitelja nije mogla biti uÄitana." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Rezervna lista poslužitelja)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Nije moguće povezivanje LAN-broadcast socketa" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "PokuÅ¡avanje otkrivanja LAN poslužitelja" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2458,7 +2538,7 @@ msgstr "Latencija:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Popis igraÄa" @@ -2485,40 +2565,39 @@ msgstr "Pridruži se poslužitelju Äim se oslobodi mjesto." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "MOLIMO UNESITE LOZINKU POSLUŽITELJA" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Isteklo Vrijeme ÄŒekanja" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Pretraživanje..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "PREGLEDNIK POSLUŽITELJA" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Lokalni" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Omiljeni" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Nedavni" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2526,300 +2605,367 @@ msgstr "ZA BRZO POVEZIVANJE:\n\n" "Unesi adresu i port u adresnu traku.\n" "Ili odaberi poslužitelja iz popisa povijesti i pritisni 'Poveži'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "POMOĆ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Osvježi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Dodaj Favorite" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Poveži" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Informacije servera" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Pretraži servere" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Pretraži igraÄe" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "ZapoÄni pretragu" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Pretraži igraÄe..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Pretraži poslužitelje..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Ime" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "IgraÄi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Gamemod" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "UkljuÄi:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Prazno" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Pun" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "ZakljuÄano" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Neumreženo" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Ostale Verzije" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Prethodna" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "UÄitavanje..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "..uÄitavanje.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Nije odreÄ‘ena adresa!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Nepoznati protokol" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Molimo Vas da koristite mtasa:// protokol!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Nevaljan nadimak! Molimo idite u postavke i postavite novi!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Morate izabrati poslužitelj na koji ćete se povezati." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Mirovanje" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problem s grafiÄkim driverima" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "igraÄ" -msgstr[1] "igraÄi" -msgstr[2] "igraÄi" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Nije moguće pronaći ispravnu rezoluciju zaslona." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "ukljuÄen" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Jeste li sigurni da želite koristiti ovu rezoluciju zaslona?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "poslužitelj" -msgstr[1] "poslužitelji" -msgstr[2] "" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Zahtijevanje glavne liste svih poslužitelja (proteklo %lu ms)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Glavna lista poslužitelja nije mogla biti analizirana." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Zahtjevi web stranice" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Glavna lista poslužitelja nije mogla biti uÄitana." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Server zahtijeva sljedeće web stranice kako bi ih uÄitao (kasnije):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Rezervna lista poslužitelja)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NIKADA NE UNOSITE OSJETLJIVE PODATKE DA SPRIJEÄŒITE NJIHOVU KRAÄU" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Nije moguće povezivanje LAN-broadcast socketa" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Zapamti odluku" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "PokuÅ¡avanje otkrivanja LAN poslužitelja" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Odbij" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Ova verzija je istekla." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "iskljuÄi se iz igre" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "pokazuje oznake s imenom" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "prikazuje statistike memorije" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "prikazuje statistike memorije" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "otvori unos Äavrljanja" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "prenosi glas na druge igraÄe" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "ulazi u vozilo kao suvozaÄ" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "sljedeći radio kanal" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "prethodni radio kanal" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "Å¡alje poruku odreÄ‘enom igraÄu" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "mijenja na sljedeće oružje u vozilu" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "mijenja na prethodno oružje u vozilu" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "izbacuje informacije o trenutnom serveru" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "definira skalu multiplikatora svih tekst-prikaza" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Razvojni naÄin) prikazuje colshapeove" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Razvitak) prikazuje colshapeove" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "POKRENI IGRU" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Resursi" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Ime poslužitelja:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Lozinka:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Ime poslužitelja:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "OdaÅ¡iljanje:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Odabrano" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Sve" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Pokreni" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Napredak skidanja mape:" @@ -2840,174 +2986,174 @@ msgstr "%s od %s" msgid "Disconnect to cancel download" msgstr "Odspojite se da prekinete skidanje" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Odspojeni: Nevažeći nadimak" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Prekini vezu s poslužiteljem" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Odspojeni: Serial je prognan.\n" "Razlog: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Odspojeni: Prognani ste.\n" "Razlog: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Odspojeni: RaÄun je prognan.\n" "Razlog: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Odspojeni: NeusklaÄ‘enost verzija" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Odspojeni: PreviÅ¡e igraÄa se pridružuje istovremeno. Molimo priÄekajte minutu, te se ponovno povežite." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Odspojeni: Poslužitelj je sa drukÄije grane.\n" "Informacija: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Odspojeni: LoÅ¡a verzija.\n" "Informacija: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Odspojeni: Poslužitelj je na novijoj graÄ‘i.\n" "Informacija: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Odspojeni: Poslužitelj je na starijoj graÄ‘i.\n" "Informacija: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Odspojeni: Nadimak se već koristi" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Odspojeni: Poslužitelj je odbacio vezu: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Odspojeni: Potvrda seriala neuspjela" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Odspojeni: Veza nesinkronizirana %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Odspojeni: Izbacio/la vas je %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Odspojeni: Prognao/la vas je %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Odspojeni: Server ugaÅ¡en ili se ponovno pali" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "IzbaÄeni ste iz igre" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Preostalo Vrijeme:" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" @@ -3015,7 +3161,7 @@ msgstr[0] "%d dan" msgstr[1] "%d dana" msgstr[2] "%d dana" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" @@ -3023,7 +3169,7 @@ msgstr[0] "%d sat" msgstr[1] "%d sata" msgstr[2] "%d sati" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" @@ -3031,7 +3177,7 @@ msgstr[0] "%d minuta" msgstr[1] "%d minute" msgstr[2] "%d minuta" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3040,296 +3186,206 @@ msgstr[1] "%d sekunde" msgstr[2] "%d sekundi" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Veza prekinuta" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "PogreÅ¡ka preuzimanja: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Ulazak u igru ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Nije spojeno: molimo koristite Brzo Povezivanje ili 'poveži' naredbu za spajanje na poslužitelj." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Lokalni poslužitelj se nije mogao pokrenuti. Pogledajte konzolu za detalje." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Lokalni Poslužitelj" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Pokretanje lokalnog poslužitelja ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "IzbaÄeni ste iz igre ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Povezivanje na lokalni poslužitelj..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "GreÅ¡ka prilikom spajanja na poslužitelj." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Povezivanje sa lokalnim poslužiteljem isteklo. Pogledajte konzolu za detalje." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Veza sa poslužiteljem se prekinula!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Odspojeni: server je trenutno pun" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Odspojeni: nevažeća lozinka odreÄ‘ena" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "Potvrda MTA klijenta neuspjela!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "POKRENI IGRU" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Resursi" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Ime poslužitelja:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Lozinka:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Ime poslužitelja:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "OdaÅ¡iljanje:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Odabrano" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Sve" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Pokreni" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problem s grafiÄkim driverima" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Nije moguće pronaći ispravnu rezoluciju zaslona." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Jeste li sigurni da želite koristiti ovu rezoluciju zaslona?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "PogreÅ¡ka preuzimanja: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3350,11 +3406,11 @@ msgstr "" msgid "Connection error" msgstr "GreÅ¡ka pri spajanju" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto nije instaliran prikladno, molimo instalirajte ponovno." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "VaÅ¡ pretraživaÄ Ä‡e sada prikazati stranicu sa nekim pomoćnim informacijama.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/hu_HU/client.pot b/Shared/data/MTA San Andreas/MTA/locale/hu_HU/client.pot index e375b52b13f..27e29b2380c 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/hu_HU/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/hu_HU/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 18:15\n" "Last-Translator: \n" "Language-Team: Hungarian\n" "Language: hu_HU\n" @@ -17,72 +17,126 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Probléma lépett fel az MTA:SA újraindításával\n\n" -"Ha ez a probléma továbbra is fenn áll, nyisd meg a feladatkezelÅ‘t\n" -"és zárd be a 'gta_sa.exe' és 'Multi Theft Auto.exe' folyamatokat.\n\n\n" -"Megpróbálod újraindítani az MTA:SA-t?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Sajnáljuk, de a játék nem található. Indítsd el a Grand Theft Auto: San Andreas-t, majd kattints az újrapróbálkozás gombra. \n" +"GyÅ‘zÅ‘dj meg róla, hogy a játék a 'Program Files (x86)' mappában van." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Hiba" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "GTA: San Andreas keresése" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Egy másik példánya az MTA-nak fut.\n\n" -"Ha ez a probléma továbbra is fenn áll, indítsd újra a számítógéped." +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Sajnáljuk, de a játék nem található. \n" +"Indítsd el a Grand Theft Auto: San Andreas-t, majd kattints az újrapróbálkozás gombra. \n" +"GyÅ‘zÅ‘dj meg róla, hogy a játék a 'Program Files (x86)' mappában van." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Egy másik példánya az MTA-nak már fut.\n\n" -"Leakarod állítani?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Válaszd ki a Grand Theft Auto: San Andreas fÅ‘könyvtárát" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA-nak rendszergazda jogosultság kell a következÅ‘ feladathoz:\n\n" +"'%s'\n\n" +"Kérlek fogadd el a következÅ‘ ablakban." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Hibás betöltés: %s modul! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Fájl másolás..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Másolás befejezve. Minden OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Befejezés..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Kész!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Új telepítés %s észlelt.\n" +" \n" +" Szeretné másolni a beállításokat innen %s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "A GTA:SA összeomlott a következÅ‘ fájl megnyitásakor '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "Hiányzó GTA:SA fájl '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "A GTA:SA összeomlott modell betöltés közben." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Ha nemrégiben módosítottad a gta3.img fájlod, telepítsd újra a GTA:SA-t." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "A GTA:SA összeomlott jármű tuningolás miatt." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA hibákat talált a '%s' fájlban" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Újrainduljon a számítógép miközben játszik az MTA:SA-val?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Kérjük állítsa le a következÅ‘ programokat a folytatás elÅ‘tt:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "Érvénytelen modulútvonal lett észlelve.\n" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Fájl verzió hiba. Telepítse újra az MTA:SA-t, ha problémák merülnének fel.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Egyes fájlok hiányoznak. Telepítse újra az MTA: SA-t, ha problémák merülnek fel.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA nem kompatibilis a Windows 'Csökkentett módjával'.\n\n" +"Kérlek indítsd újra a számítógéped.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Problémád akadt az MTA:SA futtatásával?\n\n" "Akarod hogy a játék egy régebbi verzióját telepítse?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +144,48 @@ msgstr "Úgy tűnik, hogy probléma akadt az MTA:SA elindításával.\n" "A GTA beállításainak resetelése megoldhatja ezt a problémát.\n\n" "Akarod resetelni a GTA beállításait most?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA beállításai resetelve.\n\n" "Nyomd meg az OK gombot." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Fájl nem törölhetÅ‘: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Problémád akadt az MTA:SA futtatásával?.\n\n" "Szeretnél online segítséget kapni?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Problémáid vannak az MTA:SA futtatásával?.\n\n" "Szeretnéd megváltoztatni a következÅ‘ beállításokat?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Teljes képernyÅ‘s mód:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Keret nélküli ablak" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Problémáid vannak az MTA:SA futtatásával?.\n\n" "Próbáld meg kikapcsolni a következÅ‘ programokat a GTA és az MTA miatt:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -140,133 +194,297 @@ msgstr "FIGYELEM\n" " MTA:SA szokatlan tevékenységet észlelt.\n" " Kérjük, futtass egy víruskeresést, amely biztosítja, hogy a rendszer biztonságos.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Az észlelt fájl volt: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Egy példánya a GTA: San Andreas-nak már fut. Le kell állítani, mielÅ‘tt az MTA:SA elindítható. Leakarja állítani most?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Információ" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Nem lehet leállítani a GTA: San Andreas-t. Ha a probléma továbbra is fennáll, indítsa újra a számítógépet." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Probléma lépett fel az MTA:SA újraindításával\n\n" +"Ha ez a probléma továbbra is fenn áll, nyisd meg a feladatkezelÅ‘t\n" +"és zárd be a 'gta_sa.exe' és 'Multi Theft Auto.exe' folyamatokat.\n\n\n" +"Megpróbálod újraindítani az MTA:SA-t?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Hiba" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Egy másik példánya az MTA-nak fut.\n\n" +"Ha ez a probléma továbbra is fenn áll, indítsd újra a számítógéped." + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Egy másik példánya az MTA-nak már fut.\n\n" +"Leakarod állítani?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Registry bejegyzések hiányoznak. Telepítse újra a Multi Theft Auto: San Andreas-t." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "A GTA: San Andreas útja nem támogatott (Unicode) karaktereket tartalmaz. Kérjük helyezze a Grand Theft Auto: San Andreas telepítését egy kompatibilis útra, amely csak szabványos ASCII karaktereket tartalmaz és telepítse újra a Multi Theft Auto: San Andreas-t." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." msgstr "A telepítési útvonala 'MTA:SA' vagy 'GTA: San Andreas'\n" "tartalmaz ';' (pontosvesszÅ‘).\n\n" "Ezzel problémák merülhetnek fel, ha fut az MTA:SA,\n" -"Helyezze át egy pontosvesszÅ‘t nem tartalmazó útvonalra.'" +"Helyezze át egy pontosvesszÅ‘t nem tartalmazó útvonalra." + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "Érvénytelen telepítési útvonalak lettek észlelve." -#: Client/loader/MainFunctions.cpp:810 +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Betöltés sikertelen. GyÅ‘zÅ‘djön meg arról, hogy a legfrissebb data fájlok vannak telepítve." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Betöltés sikertelen. GyÅ‘zÅ‘djön meg arról, hogy a %s jól van-e telepítve." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Betöltés sikertelen. Nem találom a gta_sa.exe-t itt %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Betöltés sikertelen. %s létezik a GTA könyvtárban. Kérjük törölje a folytatás elÅ‘tt." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Az alap fájlnak helytelen a neve (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Az alap fájl aláíratlan. Lehetséges vírus aktivitása.\n\n" -"Nézd meg az online segítséget, ha az MTA nem működik megfelelÅ‘en." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "A(z) %s adatfájl hiányzik. Lehetséges vírusaktivitás.\n\n" -"Biztonságod érdekében fontold meg a Multi Theft Auto újratelepítését.\n" -"Ha az MTA nem működik megfelelÅ‘en, nézd meg az online súgót." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "A(z) %s adatfájl hiányzik. Lehetséges vírusaktivitás." + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "A(z) %s adatfájl módosult. Lehetséges vírusaktivitás.\n\n" -"Biztonságod érdekében fontold meg a Multi Theft Auto újratelepítését.\n" -"Ha az MTA nem működik megfelelÅ‘en, nézd meg az online súgót." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asi fájlok vannak az 'MTA:SA' vagy a 'GTA: San Andreas' telepítési könyvtárban.\n\n" -"Törölje ezeket a fájlokat, ha problémája van az MTA:SA-val." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Fájl verzió hiba. Telepítse újra az MTA:SA-t, ha problémák merülnének fel.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "A(z) %s adatfájl módosult. Lehetséges vírusaktivitás." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Egyes fájlok hiányoznak. Telepítse újra az MTA: SA-t, ha problémák merülnek fel.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr ".asi fájlok találhatók a telepítési könyvtárban.\n\n" +"Távolítsd el ezeket a .asi fájlokat, ha problémákat tapasztalsz." -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA nem kompatibilis a Windows 'Csökkentett módjával'.\n\n" -"Kérlek indítsd újra a számítógéped.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "Érvénytelen játékútvonalak lettek észlelve." -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Konfigurációs probléma helyreállítás" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Szükséges hibák javítása" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "Lehetséges, hogy a GTA: San Andreas nem indult el megfelelÅ‘en. Megszakítod?" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Ismeretlen" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "A '%s' fájl jelenleg %zu folyamat(ok) által zárolva van.\n\n" +"Szeretnéd leállítani az alábbi folyamatokat és folytatni a frissítést?\n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "Lehet, hogy a telepítés most sérült.\n\n" +"%zu fájlból %zu nem állítható vissza a biztonsági másolatból.\n\n" +"Telepítsd újra a Multi Theft Auto-t a www.multitheftauto.com webhelyrÅ‘l\n" +"vagy próbáld meg futtatni a frissítést rendszergazdai jogokkal." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Frissítés telepítése..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Fájlok kicsomagolása..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA nem tudta befejezni a feladatot:\n\n" +"'%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** A crash-t a grafikus driver hibája okozta **\n\n" +"** Kérlek frissítsd a grafikus drivered **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "** Nincs elég memória – a hibát az elégtelen szabad vagy töredezett memória okozta. **" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "** A program a következÅ‘ indításkor részletesebb hibajelentést fog készíteni. **" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Frissített MTA:SA fájlok telepítése" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Nem lehet frissíteni egy fájl ütközése miatt. Kérlek zárj be minden egyéb alkalmazást és próbáld újra." + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto nem lett megfelelÅ‘en telepítve, kérlek telepítsd újra. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "GTA:SA kapcsolatok létrehozása" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA nem tudott elindulni, mert egy fájl másolása nem sikerült:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA nem tudott elindulni, mert egy MTA:SA fájl hibás vagy hiányzik:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "MTA:SA fájlok másolása" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA nem tudott elindulni, mert egy GTA:SA fájl hibás vagy hiányzik:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "GTA:SA tartozékok frissítése" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "Az MTA:SA nem indul el, mert a GTA:SA alkalmazás hibás vagy hiányzik:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Kérlek ellenÅ‘rizd az antivírus programod téves észlelésért, próbálj hozzáadni egy kivételt a GTA:SA alkalmazáshoz, majd indítsd újra az MTA:SA-t." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "GTA:SA generálása" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA nem tudott elindulni, mert a GTA:SA alkalmazás nem tölthetÅ‘ be:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "GTA:SA frissítése" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA nem tudott elindulni, mert a GTA:SA javítása nem sikerült:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Nem lehet elindítani a Grand Theft Auto: San Andreas-t. Kérjük, próbálja meg újraindítani, vagy ha a probléma továbbra is fennáll, lépjen\n" -" kapcsolatba az MTA-val itt: www.multitheftauto.com.\n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA nem folytatható, mert a %s meghajtón nincs elég hely." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Hiányzó fájl:" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas nem indult el megfelelÅ‘en. Szeretnéd ezt megszüntetni?" +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Ha az MTA nem tud betölteni, telepítse újra a GTA:SA-t" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Telepítési beállítások frissítés" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Kompatibilitási beállítások frissítés" #. ///////////////////////////////////////////////////////////////////////// #. @@ -274,167 +492,167 @@ msgstr "GTA: San Andreas nem indult el megfelelÅ‘en. Szeretnéd ezt megszüntetn #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Igen" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Nem" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "OK" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Kilépés" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Segítség" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Mégse" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas hibát észlelt" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Crash információ" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Jelölje be a jelölÅ‘négyzetet, ha szeretne küldeni crash információkat a fejlesztÅ‘knek az internet segítségével" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Ha így tesz, növeli az esélyét a crash kijavításának." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Szeretné újraindítani az MTA: San Andreas-t ?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Figyelmeztetés" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "A Grand Theft Auto: San Andreas telepítési könyvtára a következÅ‘ fájlokat tartalmazza:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Ezek a fájlok nem szükségesek, és zavarhatják az MTA:SA jelen verziójának grafikus funkcióit.\n\n" "Javasoljuk, hogy távolítsd el vagy nevezd át ezeket a fájlokat." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "Årizze meg ezeket a fájlokat, de a következÅ‘ indításkor is jelenítse meg ezt a figyelmeztetést" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Ne emlékeztessen többet ezekrÅ‘l a fájlokról" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Nevezze át ezeket a fájlokat *.dll-rÅ‘l *.dll.bak-ra" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Mutasd meg ezeket a fájlokat" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "MTA:SA elindítása" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Zavaros beállítások" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus észlelve!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Próbálj meg minden lehetÅ‘séget, és lássuk mi működik:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Ãltalános NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Alternatív NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Ãltalános Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D – Alternatív Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Ha kétségbeesett, ez segíthet:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Ha már kiválasztott egy működÅ‘ opciót, ez segíthet:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Kényszer ablakos mód" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Ne jelenjen meg többször" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Figyelem: Nem található anti-vírus termék" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -442,1111 +660,1183 @@ msgstr "Az MTA nem talált anti-vírus terméket a számítógépen.\n\n" "A vírusok zavarják az MTA-t és rontják a játékélményt.\n\n" "Nyomja meg a 'Segítség' gombot a további információkért." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Van telepítve anti-vírus termék" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Nem fogok telepíteni anti-vírus terméket.\n" "Azt akarom, hogy a PC laggoljon, és része legyen egy botnet hálózatnak." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "A tapasztalt összeomlást a szerverek túlzott memóriahasználata okozza.\n\n" +"Még bÅ‘séges RAM esetén is ez egy x86-os játék, amelynek címtartomány-korlátja legfeljebb 3.6 GB. Néhány erÅ‘sen optimalizálatlan szerver sok moddal (vagy akár pár rosszul megírt szkripttel) ezt elÅ‘idézheti, valamint laggolást is okozhat a játékban.\n\n" +"További információért lépj kapcsolatba a szerver tulajdonosával vagy az MTA támogatással az MTA hivatalos Discordján: (https://discord.gg/mtasa)." + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "MTA: San Andreas – Memóriahiány információ" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Keresése: Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Kérem indítsd el a Grand Theft Auto San Andreas-t" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Frissítés telepítése..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Kapcsolódás sikertelen. A megadott felhasználónév érvénytelen!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Fájlok kicsomagolása..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Kapcsolódás sikertelen. A megadott hoszt érvénytelen!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Fájl másolás..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Kapcsolódás ide %s:%u sikertelen!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Másolás befejezve. Minden OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Csatlakozás ide %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Befejezés..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "Újracsatlakozás a %s:%u címre..." -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Kész!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "CSATLAKOZÃS" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA-nak rendszergazda jogosultság kell a következÅ‘ feladathoz:\n\n" -"'%s'\n\n" -"Kérlek fogadd el a következÅ‘ ablakban." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "IdÅ‘túllépés miatt a kapcsolat megszakadt" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA nem tudta befejezni a feladatot:\n\n" -"'%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Lecsatlakozva: ismeretlen protokoll hiba" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** A crash-t a grafikus driver hibája okozta **\n\n" -"** Kérlek frissítsd a grafikus drivered **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Lecsatlakozva: lecsatlakozva távolról" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Frissített MTA:SA fájlok telepítése" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Lecsatlakozva: kapcsolat megszakítva távolról" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Nem lehet frissíteni egy fájl ütközése miatt. Kérlek zárj be minden egyéb alkalmazást és próbáld újra." +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Lecsatlakozva: ki lettél tiltva a szerverrÅ‘l" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Lecsatlakozva: lecsatlakozva a szerverrÅ‘l" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Lecsatlakozva: a kapcsolat megszakadt a szerverrel" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Lecsatlakozva: a kapcsolat visszautasítva" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto nem lett megfelelÅ‘en telepítve, kérlek telepítsd újra. %s" +msgid "No such mod installed (%s)" +msgstr "Nincs ilyen mód telepítve (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "GTA:SA kapcsolatok létrehozása" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Nincs szerver válasz (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA nem tudott elindulni, mert egy fájl másolása nem sikerült:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Nincs szerver válasz (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA nem tudott elindulni, mert egy MTA:SA fájl hibás vagy hiányzik:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Magyar" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "MTA:SA fájlok másolása" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Foglalt" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA nem tudott elindulni, mert egy GTA:SA fájl hibás vagy hiányzik:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Nem lehet frissítést keresni jelenleg." -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "GTA:SA tartozékok frissítése" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s szükséges" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "Az MTA:SA nem indul el, mert a GTA:SA alkalmazás hibás vagy hiányzik:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Egy frissebb MTA:SA verzió %s szükséges hogy játszhass a kiválasztott szerveren.\n\n" +"Akarod hogy az MTA:SA letöltse és telepítse a frissítést %s ?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Kérlek ellenÅ‘rizd az antivírus programod téves észlelésért, próbálj hozzáadni egy kivételt a GTA:SA alkalmazáshoz, majd indítsd újra az MTA:SA-t." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "El akarod indítani az MTA:SA %s és csatlakozni erre a szerverre?" + +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Nem lehetséges, hogy csatlakozz erre a szerverre jelen pillanatban.\n\n" +"Kérlek próbálkozz késÅ‘bb." -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "GTA:SA generálása" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Kapcsolódás" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA nem tudott elindulni, mert a GTA:SA alkalmazás nem tölthetÅ‘ be:" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Kérem várjon..." -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "GTA:SA frissítése" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "ELLENÅRZÉS" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA nem tudott elindulni, mert a GTA:SA javítása nem sikerült:" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "FRISSÃTÉS ELLENÅRZÉS" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA nem folytatható, mert a %s meghajtón nincs elég hely." +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Nincs szükséges frissítés" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Hiányzó fájl:" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "LETÖLTÉS" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Ha az MTA nem tud betölteni, telepítse újra a GTA:SA-t" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "várakozás…" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Telepítési beállítások frissítés" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "KÖTELEZÅ FRISSÃTÉS" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Kompatibilitási beállítások frissítés" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Hogy csatlakozhass erre a szerverre, frissítened kell az MTA-t.\n\n" +"Szeretnéd frissíteni most?" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Ismeretlen" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "OPCIONÃLIS FRISSÃTÉS" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "A '%s' fájl jelenleg %zu folyamat(ok) által zárolva van.\n\n" -"Szeretnéd leállítani az alábbi folyamatokat és folytatni a frissítést?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "A szerver ajánlott egy frissítést, de nem kötelezÅ‘.\n\n" +"Szeretnéd frissíteni most?" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "Lehet, hogy a telepítés most sérült.\n\n" -"%zu fájlból %zu nem állítható vissza a biztonsági másolatból.\n\n" -"Telepítsd újra a Multi Theft Auto-t a www.multitheftauto.com webhelyrÅ‘l\n" -"vagy próbáld meg futtatni a frissítést rendszergazdai jogokkal." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "Jelenleg nem érhetÅ‘ el frissítés.\n\n" +"Kérjük, ellenÅ‘rizd a www.multitheftauto.com oldalt" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Sajnáljuk, de a játék nem található. Indítsd el a Grand Theft Auto: San Andreas-t, majd kattints az újrapróbálkozás gombra. \n" -"GyÅ‘zÅ‘dj meg róla, hogy a játék a 'Program Files (x86)' mappában van." +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "MENTÉS HIBA" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "GTA: San Andreas keresése" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Nem sikerült létrehozni a fájlt." -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Sajnáljuk, de a játék nem található. \n" -"Indítsd el a Grand Theft Auto: San Andreas-t, majd kattints az újrapróbálkozás gombra. \n" -"GyÅ‘zÅ‘dj meg róla, hogy a játék a 'Program Files (x86)' mappában van." +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "HIBÃS LETÖLTÉS" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Válaszd ki a Grand Theft Auto: San Andreas fÅ‘könyvtárát" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "A letöltött fájl úgy tűnik, hogy helytelen." -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Hibás betöltés: %s modul! (%s)" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Valamilyen oknál fogva." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Új telepítés %s észlelt.\n" -" \n" -" Szeretné másolni a beállításokat innen %s ?" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "LETÖLTÉS BEFEJEZVE" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "A GTA:SA összeomlott a következÅ‘ fájl megnyitásakor '%s'" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr "Ismeretlen hiba ebben: _DialogUpdateResult" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "Hiányzó GTA:SA fájl '%s'." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "ÃTALAKÃTOTT GTA:SA FÃJLOK" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "A GTA:SA összeomlott modell betöltés közben." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ok" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Ha nemrégiben módosítottad a gta3.img fájlod, telepítsd újra a GTA:SA-t." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "HIBA" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "A GTA:SA összeomlott jármű tuningolás miatt." +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Néhány MTA:SA data fájl elveszett.\n\n\n" +"Kérlek telepítsd újra az MTA:SA-t" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA hibákat talált a '%s' fájlban" +msgid "%3d %% completed" +msgstr "%3d %% kész" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Újrainduljon a számítógép miközben játszik az MTA:SA-val?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Várakozás a válaszra - %-3d" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Kérjük állítsa le a következÅ‘ programokat a folytatás elÅ‘tt:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ PARANCS SEGÃTSÉG ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Weboldal lekérések" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Az idÅ‘ %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "A szerver a késÅ‘bbiekben a következÅ‘ weboldalakról szeretne tartalmat betölteni:" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "connect: A hálózat nem áll készen, kérlek várj egy pillanatot" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "VÉDD AZ ADATAIDAT! SOHA NE ADJ MEG ÉRZÉKENY ADATOKAT ILLETÉKTELENEKNEK" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "kapcsolódás: Példa: 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Döntés megjegyzése" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "kapcsolódás: Hibás port" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Engedélyezés" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "kapcsolódás: Kapcsolódás ide %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Megtagad" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "kapcsolódás: nem lehet kapcsolódni ide %s:%u!" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "FÅ‘menü" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "kapcsolódás: A jelenlegi mód betöltése sikertelen" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Te egy olyan MTA:SA-t használsz, ami a késÅ‘bbiekben lesz hivatalosan kiadva! Ez egy teszt verzió, amellyel nem tudsz felcsatlakozni publikus szerverekre!" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "reconnect: A hálózat nem áll készen, kérlek várj egy pillanatot" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA nem kap frissítéseket XP-re/Vistára 2019 július után.\n\n" -"Frissítsd a Windowst hogy játszhass a legújabb szervereken." +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "kapcsolódás: Hibás port" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Ezzel lefogsz csatlakozni a jelenlegi szerverrÅ‘l.\n\n" -"Biztos vagy benne, hogy lecsatlakozol?" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "reconnect: Újracsatlakozás a %s:%u címre..." -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "LECSATLAKOZÃS FIGYELMEZTETÉS" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "kapcsolódás: nem lehet kapcsolódni ide %s:%u!" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Az összes irányítás importálása a GTA-ból" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Magyar" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Konfigurációs fájl elmentve" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* A te serialod: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "BEÃLLÃTÃSOK" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Többjátékos" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Videó" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "PostFX" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Audió" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Bindek" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Irányítás" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Felület" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "WebböngészÅ‘" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Haladó" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Alapértelmezések betöltése" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Egér érzékenysége:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "FüggÅ‘leges érzékenység:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Egér beállítások" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Inverz egér" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Kormányzás az egérrel" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Repülés az egérrel" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "Egérérzékenység használata célzáskor" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Joypad beállítások" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standard irányítás (Egér + Billentyűzet)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Klasszikus irányítás (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Holtjáték" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Telítettség" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Használd a 'Bindek' fület a joypad gombok beállításához." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Bal kar" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Jobb kar" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "LEÃRÃS" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "GOMB" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. GOMB" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Felhasználónév:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Szerver jelszavak elmentése" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "SzerverkeresÅ‘ automatikus frissítése" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Képfeltöltés engedélyezése" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "KülsÅ‘ hangok engedélyezése" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Mindig mutassa a letöltési ablakot" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Csatlakozás engedélyezése a Discord Rich Presence szolgáltatással" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" -msgstr "" +msgstr "GTA:SA játékbeli státusz engedélyezése Steamen" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "Mentsd el a kamerával készített képeket a GTA San Andreas User Files mappába" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" -msgstr "" +msgstr "Rákérdezzen a szerverrÅ‘l való kilépésre a fÅ‘menü használatakor" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Egyéni GTA:SA fájlok használata" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Map renderelési opciók" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "ÃttetszÅ‘ség:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "Képfelbontás:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "1024 x 1024 (Alapértelmezett)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "FÅ‘ hangerÅ‘:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Rádió hangerÅ‘:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "SFX hangerÅ‘:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA hangerÅ‘:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Beszéd hangerÅ‘:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Lejátszási mód:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Ãltalános" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Rádió beállítások" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Rádió hangszínszabályzó" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Rádió automatikus hangolása" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Egyéni zenelista beállítások" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Rádió" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Véletlenszerű" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Egymás utáni" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Automatikus média fájl felismerés" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Némítási beállítások" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Összes hang némítása, ha az alkalmazás a háttérben fut" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Némítsa a rádió hangokat amikor minimalizálva van" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Némítsa az SFX hangokat amikor minimalizálva van" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Némítsa az MTA hangokat amikor minimalizálva van" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Némítsa a Beszéd hangokat amikor minimalizálva van" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Felbontás:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Látótér:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Látóhatár:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "FényerÅ‘:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX MinÅ‘ség:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anizotróp szűrés:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Élsimítás:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Képarány:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Ablakos mód" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI felismerés" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Alap" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Ablak keret nélkül" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mip Mapping" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "V-Sync" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Alacsony" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Közepes" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Magas" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Nagyon magas" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Nincs" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Automatikus" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD Match arány" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Volumetrikus Ãrnyékok" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Fű effekt" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "HÅ‘ség effekt" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Gumi füstölés stb." -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Dinamikus karakter árnyékok" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Mozgási elmosódás" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "EsÅ‘ tükrözÅ‘dés" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Minimalizálás teljes képernyÅ‘s módban" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Párbeszédablak engedélyezése" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Nem biztonságos felbontások mutatása" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Jármű renderelés magas felbontáson" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Játékos/NPC renderelés magas felbontáson" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "Gamma:" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "Kontraszt:" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "Szaturáció:" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "Beállítások alkalmazása ablakos módban" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "Beállítások alkalmazása teljes képernyÅ‘s módban" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Távoli weboldalak engedélyezése" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Javascript engedélyezése távoli weboldalakon" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "GPU renderelés engedélyezése" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Egyéni feketelista" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Üss be egy domaint, pl. : google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Tiltás" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Domain" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Domain törlése" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "Összes eltávolítása" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Egyéni fehérlista" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Engedélyezés" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Egyéb" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Gyors CJ ruházat töltés:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Keresési sebesség:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Egyetlen kapcsolat:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Csomag megjelölés:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "FolyamatjelzÅ‘ animáció:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Folyamat prioritása:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Hibakeresési beállítás:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Streaming memória:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Frissítés típusa:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Fontos frissítések telepítése:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Bekapcsol" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Nagyon lassú" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Alapértelmezett" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Gyors" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normál" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Normálnál nagyobb" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Minimum" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Maximum" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 kompatibilitás:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16 bites színmélység" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Egér fixálás" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Kliens oldali resource-ok:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Megjelenítés az IntézÅ‘ben" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" -msgstr "" +msgstr "CPU 0 affinitás beállítása a játék teljesítményének javításához" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Automatikus frissítÅ‘" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Frissítés keresése most" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Néhány beállítás megváltozik, amikor legközelebb elindítod a MTA-t" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Újraindítod most?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "ÚJRAINDÃTÃS SZÜKSÉGES" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Néhány beállítás megváltozik, amikor lecsatlakozol a jelenlegi szerverrÅ‘l" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Újraindítod most?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "LECSATLAKOZÃS SZÜKSÉSES" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad nem érzékelhetÅ‘ - EllenÅ‘rizd hogy csatlakoztatva van-e és indítsd újra a játékot" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Tengely bindelése" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Mozgasd a tengelyt, hogy beállítsd vagy nyomj esc-et" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Nyelv:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Megjelenés:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Beállítások:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Chat" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Betöltés" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Színek" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Elrendezés" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Beállítások" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Chat háttér" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Chat Szöveg" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Bemenet háttere" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Beviteli Szöveg" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Sorok:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Méretezés:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Szélesség:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Méret" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "Ennyi után" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "Ennyi alatt" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "mp" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Halványulás" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Régi sorok elhomályosítása" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horizontálisan:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Vertikálisan:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Szöveg elrendezés:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-Eltolás:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-Eltolás:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Pozíció:" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Balra" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Közép" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Jobbra" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Fent" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Lent" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Betűtípus" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Háttér elrejtése amikor nem írsz" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Játékosnevek listázása a \"Tab\" gombbal" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Ablak villogás engedélyezése" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Asztali értesítések engedélyezése" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Chat fekete/fehér körvonal" @@ -1554,89 +1844,95 @@ msgstr "Chat fekete/fehér körvonal" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Nyomj egy gombot a bindeléshez, hogy beállítsd vagy nyomj esc-et a törléshez" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "ElsÅ‘dleges gomb bindelése" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Másodlagos gomb bindelése" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA JÃTÉK IRÃNYÃTÃS" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "TÖBBJÃTÉKOS IRÃNYÃTÃS" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "A felhasználónevedben tiltott karakter van!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "FÅ‘menü" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "Játékban" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Vörös:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Zöld:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Kék:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Ãtlátszóság:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Szín" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "ElÅ‘nézet" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Kérlek csatlakozz le mielÅ‘tt nyelvet váltasz" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Kérlek csatlakozz le mielÅ‘tt kinézetet váltasz" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "A volumetrikus árnyék lelassíthatja a számítógéped teljesítményét.\n\n" "Biztos vagy benne hogy bekapcsolod?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "TELJESÃTMÉNY FIGYELMEZTETÉS" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Screenshot feltöltés szükséges egyes szerverek anti-cheat rendszere miatt.\n\n" "(A chat box és a GUI nem lesz rajta a képen)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "KÉP FELTÖLTÉSÉNEK INFORMÃCIÓI" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1644,23 +1940,23 @@ msgstr "Egyes szkriptek hangot, például rádiót játszhatnak le az internetr "Ennek a beállításnak a letiltása csökkentheti\n" "a hálózat sávszélesség fogyasztását.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "KÜLSÅ HANGOK" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "Úgy tűnik, hogy be van kapcsolva a Rich Presence csatlakozási lehetÅ‘ség.\n" -"Engedélyezed, hogy a szerverek megosszák adataid?\n\n" -"Ez magában foglalja az egyedi azonosítód is." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "A Rich Presence jelenleg be van kapcsolva.\n" +"Szeretnéd engedélyezni az adatmegosztást azokkal a szerverekkel, amelyekhez csatlakozol?\n\n" +"Ez magában foglalja a Discord kliensazonosítódat és a játék állapotára vonatkozó információkat." -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "HOZZÃJÃRULÃS AZ ADATMEGOSZTÃSHOZ" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1670,11 +1966,7 @@ msgstr "Néhány fájl a GTA:SA mappádban átlett alakítva.\n" "Mindenesetre, az átalakított GTA:SA fájlok tiltva vannak rengeteg szerver által\n\n" "Biztos vagy benne hogy használatba veszed Å‘ket?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "ÃTALAKÃTOTT GTA:SA FÃJLOK" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1684,551 +1976,253 @@ msgstr "A DPI-felismerés engedélyezése egy kísérleti szolgáltatás és\n" "Grafikus problémákat tapasztalhat, ha engedélyezi ezt az opciót.\n\n" "Biztos benne, hogy engedélyezni kívánja ezt az opciót?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "KÃSÉRLETI FUNKCIÓ" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "Ennek a beállításnak a kikapcsolása nem ajánlott, kivéve, ha teljesítményproblémák merülnek fel.\n\n" "Biztos, hogy ki akarja kapcsolni?" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Kérlek adj meg egy felhasználónevet!" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Kérlek írj be egy felhasználónevet amit a játékon belül fogsz használni. \n" "Ez lesz a neved, amikor egy szerverre felcsatlakozol és játszol." -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Nagyon kísérleti funkció." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Fagyás megakadályozása a CJ ruhaváltozatoknál (65MB-al több RAM-ot használ)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Régebbi routereknél lehet szükség a lassabb keresési sebességre." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Ãtváltás arra, hogy csak egy kapcsolatot használjon letöltéskor." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Jelöld meg a hálózati csomagokat, hogy segíts az internetszolgáltatóknak azonosítani az MTA forgalmát." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Forgó kör animáció a képernyÅ‘ alján" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Alapértelmezett választása mindig. (Ez a beállítás nem kerül mentésre)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "A maximum általában a legjobb." -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Automatikus frissítÅ‘:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Válaszd az alapértelmezettet ha nem szeretsz bug jelentéseket kitölteni." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Válaszd az alapértelmezettet, hogy automatikusan telepítÅ‘djenek a fontos frissítések." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16 bites színmélység:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "16 bites színmélység bekapcsolása - MTA újraindítást igényel" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Egér fixálás:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Egér mozgás fixálás - PC újraindítást igényelhet" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" -msgstr "" +msgstr "CPU affinitás:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "Csak akkor változtasson, ha problémái vannak a stabilitással." -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Ismeretlen parancs vagy beállítás: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Foglalt" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Nem lehet frissítést keresni jelenleg." - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s szükséges" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Egy frissebb MTA:SA verzió %s szükséges hogy játszhass a kiválasztott szerveren.\n\n" -"Akarod hogy az MTA:SA letöltse és telepítse a frissítést %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "El akarod indítani az MTA:SA %s és csatlakozni erre a szerverre?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Nem lehetséges, hogy csatlakozz erre a szerverre jelen pillanatban.\n\n" -"Kérlek próbálkozz késÅ‘bb." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Kapcsolódás" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Kérem várjon..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "ELLENÅRZÉS" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "FRISSÃTÉS ELLENÅRZÉS" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Nincs szükséges frissítés" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "LETÖLTÉS" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "várakozás…" - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "KÖTELEZÅ FRISSÃTÉS" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Hogy csatlakozhass erre a szerverre, frissítened kell az MTA-t.\n\n" -"Szeretnéd frissíteni most?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "OPCIONÃLIS FRISSÃTÉS" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "A szerver ajánlott egy frissítést, de nem kötelezÅ‘.\n\n" -"Szeretnéd frissíteni most?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "MENTÉS HIBA" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Nem sikerült létrehozni a fájlt." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "HIBÃS LETÖLTÉS" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "A letöltött fájl úgy tűnik, hogy helytelen." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Valamilyen oknál fogva." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "LETÖLTÉS BEFEJEZVE" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "Ismeretlen hiba ebben: _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ok" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "HIBA" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Néhány MTA:SA data fájl elveszett.\n\n\n" -"Kérlek telepítsd újra az MTA:SA-t" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% kész" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Várakozás a válaszra - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Kapcsolódás sikertelen. A megadott felhasználónév érvénytelen!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Kapcsolódás sikertelen. A megadott hoszt érvénytelen!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Kapcsolódás ide %s:%u sikertelen!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Csatlakozás ide %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "Újracsatlakozás a %s:%u címre..." - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "CSATLAKOZÃS" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "IdÅ‘túllépés miatt a kapcsolat megszakadt" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Lecsatlakozva: ismeretlen protokoll hiba" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Lecsatlakozva: lecsatlakozva távolról" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Lecsatlakozva: kapcsolat megszakítva távolról" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Lecsatlakozva: ki lettél tiltva a szerverrÅ‘l" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Lecsatlakozva: lecsatlakozva a szerverrÅ‘l" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Lecsatlakozva: a kapcsolat megszakadt a szerverrel" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Lecsatlakozva: a kapcsolat visszautasítva" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Nincs ilyen mód telepítve (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Nincs szerver válasz (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Nincs szerver válasz (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "HÃREK" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Nézd meg a legfrissebb híreket" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONZOL" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Végzetes hiba" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "A helyreállításhoz töröld ezt a fájlt:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s modul hibás!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Hiba történt az URL megnyitásakor" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "segítség" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "kilépés az alkalmazásból" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "verzió mutatása" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "idÅ‘ mutatása" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "hud mutatása" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "bindek mutatása" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "serial mutatása" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "kapcsolódás a szerverre (hoszt port felhasználónév jelszó)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "kapcsolódás az elÅ‘zÅ‘ szerverhez" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "Egy gomb bebindelése (billentyűzet)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "Egy gomb unbindelése (billentyűzet)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "alap gta irányítási beállítások másolása" -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "kiad egy screenshotot" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "konfig mentése azonnal" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "debug chat tisztítás" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "chatbox görgetése felfelé" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "chatbox görgetése lefelé" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "a debug chat felfelé görgetése" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "a debug chat lefelé görgetése" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "memória statisztika mutatása" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "frame grafikon mutatása" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "fejlesztÅ‘knek: hírek újratöltése" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ PARANCS SEGÃTSÉG ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Az idÅ‘ %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "kapcsolódás: Példa: 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "kapcsolódás: Hibás port" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "kapcsolódás: Kapcsolódás ide %s:%u..." +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "kiad egy screenshotot" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "kapcsolódás: nem lehet kapcsolódni ide %s:%u!" +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "konfig mentése azonnal" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "kapcsolódás: A jelenlegi mód betöltése sikertelen" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "debug chat tisztítás" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "chatbox görgetése felfelé" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "kapcsolódás: Hibás port" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "chatbox görgetése lefelé" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "reconnect: Újracsatlakozás a %s:%u címre..." +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "a debug chat felfelé görgetése" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "kapcsolódás: nem lehet kapcsolódni ide %s:%u!" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "a debug chat lefelé görgetése" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Az összes irányítás importálása a GTA-ból" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "memória statisztika mutatása" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Konfigurációs fájl elmentve" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "frame grafikon mutatása" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* A te serialod: %s" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "fejlesztÅ‘knek: hírek újratöltése" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Gyorsulás" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Te egy olyan MTA:SA-t használsz, ami a késÅ‘bbiekben lesz hivatalosan kiadva! Ez egy teszt verzió, amellyel nem tudsz felcsatlakozni publikus szerverekre!" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Lassulás" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA nem kap frissítéseket XP-re/Vistára 2019 július után.\n\n" +"Frissítsd a Windowst hogy játszhass a legújabb szervereken." -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programozás" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Ezzel lefogsz csatlakozni a jelenlegi szerverrÅ‘l.\n\n" +"Biztos vagy benne, hogy lecsatlakozol?" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "KözreműködÅ‘k" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "LECSATLAKOZÃS FIGYELMEZTETÉS" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Játék Dizájn / Scriptelés" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "INFORMÃCIÓ" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Honosítás" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "HÃREK" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Javítás közreműködÅ‘i" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Nézd meg a legfrissebb híreket" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Külön köszönet:" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Screenshot készítve %d bájt, de körülbelül %d" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Ez a szoftver és projekt a következÅ‘ könyvtárakat és szoftvereket használja:" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Screenshot készítése sikertelen" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Szeretne néhány online tanácsot kapni errÅ‘l a hibáról?" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Screenshot létrehozva: '%s" + +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Ismeretlen parancs vagy beállítás: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2403,25 +2397,56 @@ msgid "Group control backwards" msgstr "Csoportos irányítás hátra" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "A kinézet amit választottál nem betölthetÅ‘, és az alap kinézet sem tölthetÅ‘ be, kérlek telepítsd újra az MTA-t." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Screenshot készítve %d bájt, de körülbelül %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Szeretne néhány online tanácsot kapni errÅ‘l a hibáról?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Screenshot készítése sikertelen" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONZOL" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Screenshot létrehozva: '%s" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programozás" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "KözreműködÅ‘k" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Játék Dizájn / Scriptelés" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Honosítás" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Javítás közreműködÅ‘i" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Külön köszönet:" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Ez a szoftver és projekt a következÅ‘ könyvtárakat és szoftvereket használja:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Gyorsulás" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Lassulás" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2429,6 +2454,61 @@ msgstr "Nem lehet inicializálni Direct3D9.\n\n" "Kérlek ellenÅ‘rizd le, hogy a legújabb DirectX és\n" "Windows Service Pack fel van-e telepítve." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Tétlen" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "játékos" +msgstr[1] "játékosok" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "és" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "szerver" +msgstr[1] "szerverek" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Mester szerver lista lekérdezése (%lu ms eltelt)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "A mester szerver lista nem elemezhetÅ‘." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "A mester szerver lista nem található." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Backup szerver lista)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "Nem lehet létrehozni a LAN socketet" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Nem lehet összekötni: LAN-broadcast socket" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Kísérlet a LAN szerverek felfedézésre" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2482,7 +2562,7 @@ msgstr "Ping:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Játékos lista" @@ -2509,40 +2589,39 @@ msgstr "Csatlakozás amint egy férÅ‘hely szabaddá válik." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "ADJA MEG A SZERVER JELSZAVÃT" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "IdÅ‘túllépés" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Lekérdezés…" #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "SZERVER KERESÅ" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Helyi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Kedvencek" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Legutóbbi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2550,298 +2629,367 @@ msgstr "GYORS CSATLAKOZÃS:\n\n" "Ãrd be a címsávba a szerver elérését.\n" "Vagy a legutóbbi szerverek közül válassz egyet és nyomd meg a 'Csatlakozás' gombot." -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "SEGÃTSÉG" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Frissítés" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Hozzáadás a kedvencekhez" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Csatlakozás" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Szerver információ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Szerver keresés" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Játékos keresés" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Keresés megkezdése" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "Törlés a legutóbbiak közül" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Játékos keresése..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Szerver keresése..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Név" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Játékosok" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Ping" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Játékmód" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Tartalmazza:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Üres" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Tele" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Zárolt" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Nem elérhetÅ‘" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Egyéb verziók" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Vissza" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Betöltés..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "...betöltés..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Nincs elérés megadva!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Ismeretlen protokoll" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Kérlek használd az mtasa:// protokoll-t!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Helytelen felhasználónév! Kérlek menj a Beállítások menübe és változtasd meg!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Választanod kell egy szervert, ahová szeretnél csatlakozni." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Tétlen" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Probléma a grafikus illesztÅ‘programmal" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "játékos" -msgstr[1] "játékosok" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Nem található érvényes képernyÅ‘felbontás." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "és" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Biztos benne, hogy szeretné használni ezt a képernyÅ‘ felbontását?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "szerver" -msgstr[1] "szerverek" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "Nem sikerült inicializálni: game_sa" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Mester szerver lista lekérdezése (%lu ms eltelt)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "A memóriafoglalás nem sikerült" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "A mester szerver lista nem elemezhetÅ‘." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Weboldal lekérések" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "A mester szerver lista nem található." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "A szerver a késÅ‘bbiekben a következÅ‘ weboldalakról szeretne tartalmat betölteni:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Backup szerver lista)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "VÉDD AZ ADATAIDAT! SOHA NE ADJ MEG ÉRZÉKENY ADATOKAT ILLETÉKTELENEKNEK" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Nem lehet összekötni: LAN-broadcast socket" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Döntés megjegyzése" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Kísérlet a LAN szerverek felfedézésre" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Megtagad" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Ez a verzió már elavult." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "lecsatlakozás a játékból" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "nevek mutatása" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "chatbox mutatása" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "kapcsolat statisztika mutatása" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "chat beviteli mezÅ‘ megnyitása" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "hang továbbítása a többi játékos felé" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "járműbe szállás utasként" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "következÅ‘ rádió csatorna" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "elÅ‘zÅ‘ rádió csatorna" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "radar nézet engedélyezése" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "radar nagyítása" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "radar kicsinyítése" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "radar északra mozgatása" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "radar délre mozgatása" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "radar keletre mozgatása" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "radar nyugatra mozgatása" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "radar csatolása" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "radar átlátszóságának csökkentése" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "radar átlátszóságának növelése" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "súgószöveg mutatása a radaron" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "üzenet küldése a címzett játékosnak" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "következÅ‘ fegyverre váltás járműben" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "elÅ‘zÅ‘ fegyverre váltás járműben" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "kimenÅ‘ információ az aktuális szerverrÅ‘l" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "beállítja a képernyÅ‘n megjelenÅ‘ összes szöveg méretét" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(FejlesztÅ‘i mód) colshapes-ek megjelenítése" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(FejlesztÅ‘i mód) kiírja az alap játék hangjainak azonosítóját a debug chatbe" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "SZERVER INDÃTÃS" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "ErÅ‘források" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Szerver neve:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Jelszó:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Max játékos:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Közvetítés:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Kijelölve" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Összes" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Indítás" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "Módváltás: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "Nagyítás: %s/%s Mozgás: %s, %s, %s, %s Ãtlátszóság: %s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "Radar mutatása: %s Súgószöveg mutatása: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "Játékos Követése" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "Szabad Mozgás" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Pálya letöltési folyamat:" @@ -2862,195 +3010,195 @@ msgstr "%s a(z) %s-ból" msgid "Disconnect to cancel download" msgstr "Csatlakozz le, ha megakarod szakítani a letöltést." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Lecsatlakozva: Hibás felhasználónév" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Lecsatlakozva a szerverrÅ‘l" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Lecsatlakozva: A serialod kivan tiltva.\n" "Indok: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Lecsatlakozva: Ki vagy tiltva.\n" "Indok: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Lecsatlakozva: Az accountod ki van tiltva.\n" "Indok: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Lecsatlakozva: Nem megfelelÅ‘ verziópárosítás" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Lecsatlakozva: Belépés flood. Kérjük várjon egy percet, majd csatlakozzon újra." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Lecsatlakozva: A szerver forráskódja eltér a hivatalos verziótól.\n" "Információ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Lecsatlakozva: Rossz verzió.\n" "Információ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Lecsatlakozva: A szerver újabb verzión fut.\n" "Információ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Lecsatlakozva: A szerver régebbi verzión fut.\n" "Információ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Lecsatlakozva: A felhasználónév már használatban van" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Lecsatlakoztatva: A karaktert nem sikerült létrehozni." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Lecsatlakozva: A szerver megtagadta a kapcsolatot: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Lecsatlakozva: Serial aktiválás hiba" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "Lecsatlakoztatva: Ez a serial már használatban van" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Lecsatlakozva: A kapcsolat nem szinkronizált %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Lecsatlakozva: Ki lettél rúgva általa: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Lecsatlakozva: Ki lettél tiltva általa: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Lecsatlakozva: Szerver leállt vagy újraindul" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Ki lettél rúgva a játékból" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Ehhez a szerverhez nem módosított gta_sa.exe szükséges" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Kérlek cseréld ki a gta_sa.exe fájlt" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Ez a szerver nem engedélyezi az egyedi D3D9.DLL fájlokat" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Távolítsd el a D3D9.DLL fájlt a GTA telepítési könyvtárából és indítsd újra az MTA-t" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "A szerver nem engedélyezi a virtuális gépek használatát" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "A szerverhez való csatlakozáshoz engedélyezned kell az illesztÅ‘programok digitális aláírását" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Kérlek indítsd újra a számítógépet" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "A szerver hiányzó anti-cheat összetevÅ‘ket észlelt" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Próbáld meg újraindítani az MTA-t" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "A szerverhez való csatlakozáshoz egy nem módosított gta3.img és gta_int.img szükséges" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Kérjük cseréld ki a gta3.img vagy a gta_int.img fájlt" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Ez a szerver nem engedélyezi a Wine használatát" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "GyÅ‘zÅ‘dj meg arról, hogy más program nem módosítja az MTA:SA-t" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "HátralevÅ‘ idÅ‘:" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d nap" msgstr[1] "%d napok" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d óra" msgstr[1] "%d órák" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d perc" msgstr[1] "%d percek" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3058,302 +3206,212 @@ msgstr[0] "%d másodperc" msgstr[1] "%d másodperc" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Lecsatlakozva" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Letöltés hiba: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "UFO-val repülni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "Krúzolás" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "Meglovagolni a hullámokat" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "Felülni a vonatra" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "Repülni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "Krúzol" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "Monster Truckozni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "Quadozik" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "Bunny hoppolni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "Furcska dolgokat művelni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "Körbemászni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "Kihajolva lÅ‘ni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "Blugy blugy..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "Folyadéklégzés" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "Belefulladni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "Fedezékbe húzódni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "Harcolni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "Verekedni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "Lövöldözik itt:" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "Növekedni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "Jetpackelni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "Szó szerint lángolni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "Felidegesedni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "Úszni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "Úszik itt:" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "Egy cápa által üldözve lenni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "Megfulladni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Belépés a játékba ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Nem csatlakozott; Használd a Gyors csatlakozás, illetve a 'csatlakozás' gombot." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Nem sikerült elindítani a helyi szervert. Információkért nyisd meg a konzolt." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Helyi szerver" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Helyi szerver indítása ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "51-es körzet" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "Sétálni " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Ki lettél rúgva a játékból ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Csatlakozás a helyi szerverhez..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Hiba történt a szerverre csatlakozás közben." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "IdÅ‘túllépés miatt a csatlakozás megszakadt. Adatokért nyisd meg a konzolt." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "A kapcsolat megszakadt a szerverrel" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Lecsatlakozva: a szerver jelenleg tele van" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Lecsatlakozva: helytelen jelszó" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA kliens ellenÅ‘rzése nem sikerült!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "Egy árokban" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "Úton a kórházba" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "Találkozni a készítÅ‘jükkel" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "Megbánják a döntéseiket" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "Meghalt" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "SZERVER INDÃTÃS" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "ErÅ‘források" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Szerver neve:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Jelszó:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Max játékos:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Közvetítés:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Kijelölve" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Összes" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Indítás" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "Módváltás: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "Nagyítás: %s/%s Mozgás: %s, %s, %s, %s Ãtlátszóság: %s/%s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "Radar mutatása: %s Súgószöveg mutatása: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "Játékos Követése" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "Szabad Mozgás" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Probléma a grafikus illesztÅ‘programmal" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Nem található érvényes képernyÅ‘felbontás." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Biztos benne, hogy szeretné használni ezt a képernyÅ‘ felbontását?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "Nem sikerült inicializálni: game_sa" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "A memóriafoglalás nem sikerült" +msgid "Download error: %s" +msgstr "Letöltés hiba: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 #, c-format msgid "Fatal error (%u). If this problem persists, please check out multitheftauto.com for support." -msgstr "" +msgstr "Végzetes hiba (%u). Ha a probléma továbbra is fennáll, kérjük, látogass el a multitheftauto.com oldalra támogatásért." #. #ifdef MTA_DEBUG #. assert ( 0 ); @@ -3362,17 +3420,17 @@ msgstr "" #: Shared/mods/deathmatch/logic/Utils.cpp:143 #, c-format msgid "Protocol error (%u). If this problem persists, please check out multitheftauto.com for support." -msgstr "" +msgstr "Protokollhiba (%u). Ha a probléma továbbra is fennáll, kérjük, látogass el a multitheftauto.com oldalra támogatásért." #: Shared/mods/deathmatch/logic/Utils.cpp:145 msgid "Connection error" msgstr "Csatlakozási hiba" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto nincs megfelelÅ‘en feltelepítve, kérlek telepítsd újra." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "A böngészÅ‘ most megjeleníti a weboldalt néhány információval.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/id_ID/client.pot b/Shared/data/MTA San Andreas/MTA/locale/id_ID/client.pot index 0e3045a9bab..46366f70034 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/id_ID/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/id_ID/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Indonesian\n" "Language: id_ID\n" @@ -17,72 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Masalah saat memulai ulang MTA:SA\n\n" -"Apabila masalahnya berlanjut, buka Manajer Tugas dan\n" -"akhiri proses 'gta_sa.exe' dan 'Multi Theft Auto.exe'\n\n\n" -"Coba luncurkan MTA:SA lagi?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Memulai Grand Theft Auto: Sand Andreas.\n" +"Pastikan gamenya diletakan pada folder 'Program Files (x86)'." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Kesalahan" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "Mencari GTA: San Andreas" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Instansi selain MTA sedang berjalan.\n\n" -"Apabila masalah berlanjut, silakan mulai ulang komputer anda" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Maaf, game tidak ditemukan.\n" +"Mulai Grand Theft Auto: San Andreas dan klik coba ulang.\n" +"Pastikan gamenya diletakan pada folder 'Program Files (x86)'." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Instansi selain MTA sedang berjalan.\n\n" -"Apakah anda ingin mengakhirinya?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Pilih direktori pemasangan Grand Theft Auto: San Andreas anda" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA membutuhkan akses Administrator untuk tugas berikut:\n\n" +" '%s'\n\n" +"Silakan konfirmasi di jendela berikutnya." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Kesalahan memuat modul %s! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Menyalin berkas..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Penyalinan selesai lebih awal. Semuanya OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Menyelesaikan..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Selesai!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Pemasangan baru dari %s terdeteksi.\n\n" +"Apakah anda ingin menyalin pengaturan dari %s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA mengalami masalah saat membuka berkas '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA kehilangan berkas '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA mengalami masalah saat memuat model." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Jika anda belakangan ini memodifikasi gta3.img, coba pasang ulang GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA mengalami masalah saat menambah peningkatan ke sebuah kendaraan." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA menemukan kesalahan di dalam berkas '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Apakah komputer anda memulai ulang saat bermain MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Mohon akhiri program berikut sebelum melanjutkan:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Ketidakcocokan pada versi berkas. Pasang ulang MTA:SA jika anda mengalami masalah.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Beberapa berkas hilang. Pasang ulang MTA:SA jika anda mengalami masalah.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA tidak kompatibel dengan 'Mode Aman' Windows.\n\n" +"Silakan mulai ulang PC anda.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Apakah anda mengalami masalah dalam menjalankan MTA:SA?\n\n" "Apakah anda ingin kembali ke versi sebelumnya?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +143,48 @@ msgstr "Sepertinya ada masalah saat meluncurkan MTA:SA.\n" "Kadang-kadang pengaturan ulang GTA dapat memperbaiki masalah ini.\n\n" "Apakah anda ingin mengulang pengaturan GTA sekarang?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "Pengaturan GTA telah diulangi.\n\n" "Tekan OK untuk melanjutkan." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Berkas tidak dapat dihapus: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Apakah anda mengalami masalah saat menjalankan MTA:SA?.\n\n" "Apakah anda ingin untuk melihat beberapa bantuan daring?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Apakah anda mengalami masalah saat menjalankan MTA:SA?\n\n" "Apakah anda ingin mengganti pengaturan berikut?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Mode layar penuh:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Jendela tanpa tepi" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Apakah anda mengalami masalah saat menjalankan MTA:SA?\n\n" "Coba non-aktifkan produk berikut untuk GTA dan MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +192,293 @@ msgstr "PERINGATAN\n\n" "MTA:SA mendeteksi aktivitas tidak biasa.\n" "Mohon jalankan pemindaian virus untuk memastikan keamanan sistem anda.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Berkas yang terdeteksi adalah: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Instansi GTA: San Andreas sedang berjalan. Itu harus diakhiri agar MTA:SA dapat berjalan. Apakah anda ingin melakukannya sekarang?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informasi" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Tidak dapat mengakhiri GTA: San Andreas. Apabila masalahnya berlanjut, silakan mulai ulang komputer anda." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Masalah saat memulai ulang MTA:SA\n\n" +"Apabila masalahnya berlanjut, buka Manajer Tugas dan\n" +"akhiri proses 'gta_sa.exe' dan 'Multi Theft Auto.exe'\n\n\n" +"Coba luncurkan MTA:SA lagi?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Kesalahan" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Instansi selain MTA sedang berjalan.\n\n" +"Apabila masalah berlanjut, silakan mulai ulang komputer anda" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Instansi selain MTA sedang berjalan.\n\n" +"Apakah anda ingin mengakhirinya?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Entri registry hilang. Silakan pasang ulang Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Jalur menuju pemasangan GTA: San Andreas anda mengandung karakter yang tidak mendukung (unicode). Silakan pindahkan pemasangan Grand Theft Auto: San Andreas ke jalur yang kompatibel yang hanya mengandung karakter ASCII dan pasang ulang Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Jalur menuju pemasangan 'MTA:SA' atau 'GTA: San Andreas' anda\n" -"mengandung sebuah ';' (titik koma).\n\n" -" Apabila anda mengalami masalah saat menjalankan MTA:SA,\n" -" pindahkan pemasangan anda ke jalur yang tidak mengandung titik koma." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Gagal memuat. Pastikan bahwa berkas data terbaru telah terpasang dengan benar." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Gagal memuat. Pastikan bahwa %s telah terpasang dengan benar." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Gagal memuat. Tidak dapat menemukan gta_sa.exe di %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Gagal memuat. %s terdapat di direktori GTA. Silakan hapus sebelum melanjutkan." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Berkas utama memiliki nama yang salah (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Berkas utama tidak ditandai. Kemungkinan ada aktivitas virus.\n\n" -"Lihat bantuan daring apabila MTA tidak bekerja dengan benar." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Berkas data %s hilang. Kemungkinan aktifitas virus.\n\n" -"Pertimbangkan untuk menginstal ulang Multi Theft Auto untuk keamanan Anda.\n" -"Lihat bantuan online jika MTA tidak berfungsi dengan benar." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Berkas data %s telah diubah. Kemungkinan aktifitas virus.\n\n" -"Pertimbangkan untuk menginstal ulang Multi Theft Auto untuk keamanan Anda.\n" -"Lihat bantuan online jika MTA tidak berfungsi dengan benar." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "Berkas .asi ada di direktori pemasangan 'MTA:SA' atau 'GTA: San Andreas'.\n\n" -"Hapus berkas .asi tersebut jika anda mengalami masalah dengan MTA:SA." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Ketidakcocokan pada versi berkas. Pasang ulang MTA:SA jika anda mengalami masalah.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Beberapa berkas hilang. Pasang ulang MTA:SA jika anda mengalami masalah.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA tidak kompatibel dengan 'Mode Aman' Windows.\n\n" -"Silakan mulai ulang PC anda.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Perbaiki masalah konfigurasi" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Perbaiki masalah keperluan peningkatan" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Tidak diketahui" + +#: Client/loader/Install.cpp:272 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Tidak dapat memulai Grand Theft Auto: San Andreas. Silakan coba untuk memulai ulang, atau apabila masalahnya berlanjut, hubungi MTA di www.multitheftauto.com.\n\n" -"[%s]" +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "Berkas '%s' sedang dikunci oleh proses %zu .\n\n" +"Apakah Anda ingin mengakhiri proses berikut dan melanjutkan pembaharuan?\n\n" +"%s" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas mungkin tidak diluncurkan dengan benar. Apakah anda ingin mengakhirinya?" +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "Instalasi Anda mungkin korup sekarang.\n\n" +"%zu dari %zu berkas tidak dapat dipulihkan kembali dari cadangannya.\n\n" +"Anda harus menginstal ulang Multi Theft Auta dari www.multitheftauto.com\n" +"atau coba untuk melanjankan pembaharuannya dengan hak administrasi." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Memasang pembaruan..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Mengekstrak berkas..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA tidak dapat menyelesaikan tugas berikut:\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Kecelakaan itu disebabkan oleh kesalahan driver grafik **\n\n" +"** Silakan perbarui driver grafik anda **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Pasang berkas MTA:SA yang telah diperbarui" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Tidak dapat memperbarui dikarenakan konflik berkas. Mohon tutup aplikasi lain dan coba lagi" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto tidak terpasang dengan benar, mohon instal ulang. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "Buat persimpangan GTA:SA" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA tidak dapat diluncurkan karena telah gagal menyalin sebuah berkas:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA tidak dapat diluncurkan karena ada sebuah berkas MTA:SA yang salah atau hilang:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Salin berkas MTA:SA" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA tidak dapat diluncurkan karena ada sebuah berkas GTA:SA yang salah atau hilang:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "Tambal dependensi GTA:SA" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA tidak dapat diluncurkan karena executable GTA:SA (.exe) salah atau hilang:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Mohon untuk memperiksa anti-virus Anda untuk deteksi positif palsu, coba untuk menambahkan sebuah pengecualian untuk executable GTA:SA dan memulai ulang MTA:SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "Menggenerasi GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA tidak dapat diluncurkan karena executable GTA:SA tidak dapat dimuat:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Menambal GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA tidak dapat diluncurkan karena penambalan GTA:SA telah gagal:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA tidak dapat dilanjutkan karena drive %s tidak mempunyai ruang yang cukup." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Berkas yang hilang:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Jika MTA gagal memuat, mohon pasang ulang GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Perbarui pengaturan pemasangan" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Perbarui pengaturan kompatibilitas" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +486,167 @@ msgstr "GTA: San Andreas mungkin tidak diluncurkan dengan benar. Apakah anda ing #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Ya" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Tidak" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "Oke" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Keluar" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Bantuan" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Batal" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas telah mengalami sebuah kesalahan" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Informasi kerusakan" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Centang kotak untuk mengirim info kerusakan ini kpd pengembang MTA menggunakan 'internet'" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Hal ini akan meningkatkan kemungkinan kerusakan ini diperbaiki." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Apakah anda ingin memulai ulang MTA: San Andreas ?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Peringatan" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "Direktori pemasangan Grand Theft Auto: San Andreas anda yang berisi berkas ini:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Berkas ini tidak diperlukan dan mungkin mengganggu ciri grafik dari versi MTA:SA ini.\n\n" "Dianjurkan agar anda menghapus atau mengganti nama berkas ini." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "Simpan berkas ini, tetapi juga tunjukkan peringatan ini saat mulai selanjutnya" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Jangan ingatkan saya lagi tentang berkas ini lagi" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Ganti nama berkas ini dari *.dll ke *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Tunjukkan berkas berkas ini" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Mainkan MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Opsi yang membingungkan" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus terdeteksi!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Coba setiap pilihan dan lihat apa yang bekerja:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - NVidia standar" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - NVidia alternatif" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Intel Standar" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Intel Alternatif" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Jika anda tidak tahu, ini mungkin membantu:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Jika anda sudah memilih opsi yang berhasil, ini mungkin membantu:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Paksa jadi mode jendela" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Jangan lihatkan lagi" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Peringatan: Tidak dapat mendeteksi produk anti-virus" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1110 +654,1180 @@ msgstr "MTA tidak dapat mendeteksi anti-virus di PC anda.\n\n" "Virus mengganggu MTA dan menurunkan pengalaman bermain anda.\n\n" "Tekan 'Bantuan' untuk informasi lebih lanjut." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Saya sudah memasang anti-virus" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Saya tidak akan memasang anti-virus.\n" "Saya mau PC saya untuk lag dan menjadi bagian dari botnet." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Mencari Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Silakan mulai Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Memasang pembaruan..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Proses penyambungan gagal. Nama yang diberikan tidak valid!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Mengekstrak berkas..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Proses penyambungan gagal. Pengelola yang diberikan tidak valid!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Menyalin berkas..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Proses penyambungan ke %s pada port %u gagal!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Penyalinan selesai lebih awal. Semuanya OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Menyambungkan ke %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Menyelesaikan..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "Menyambung ulang ke %s:%u ..." -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Selesai!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "MENYAMBUNGKAN" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA membutuhkan akses Administrator untuk tugas berikut:\n\n" -" '%s'\n\n" -"Silakan konfirmasi di jendela berikutnya." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Koneksi terputus" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA tidak dapat menyelesaikan tugas berikut:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Terputus: kesalahan protokol tidak diketahui" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Kecelakaan itu disebabkan oleh kesalahan driver grafik **\n\n" -"** Silakan perbarui driver grafik anda **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Terputus: diputuskan dari jarak jauh" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Pasang berkas MTA:SA yang telah diperbarui" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Terputus: koneksi hilang dari jarak jauh" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Tidak dapat memperbarui dikarenakan konflik berkas. Mohon tutup aplikasi lain dan coba lagi" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Terputus: anda dilarang dari server ini" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Terputus: terputus dari server" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Terputus: koneksi dengan server hilang" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Terputus: koneksi ditolak" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto tidak terpasang dengan benar, mohon instal ulang. %s" +msgid "No such mod installed (%s)" +msgstr "Tidak ada mod yang terpasang (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "Buat persimpangan GTA:SA" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Respon server tidak baik (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA tidak dapat diluncurkan karena telah gagal menyalin sebuah berkas:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Respon server tidak baik (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA tidak dapat diluncurkan karena ada sebuah berkas MTA:SA yang salah atau hilang:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Bahasa Indonesia" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Salin berkas MTA:SA" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Sibuk" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA tidak dapat diluncurkan karena ada sebuah berkas GTA:SA yang salah atau hilang:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Tidak dapat memeriksa pembaruan sekarang" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Tambal dependensi GTA:SA" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "Diperlukan MTA:SA %s" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA tidak dapat diluncurkan karena executable GTA:SA (.exe) salah atau hilang:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Versi dari MTA:SA %s yang terbaru dibutuhkan untuk bergabung dengan server yang dipilih.\n\n" +"Apakah anda ingin mengunduh dan memasang MTA:SA %s ?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Mohon untuk memperiksa anti-virus Anda untuk deteksi positif palsu, coba untuk menambahkan sebuah pengecualian untuk executable GTA:SA dan memulai ulang MTA:SA." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Apakah anda ingin meluncurkan MTA:SA %s dan menyambungkannya ke server ini ? " -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Menggenerasi GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Tidak memungkinkan untuk menyambungkan saat ini.\n\n" +"Silakan coba nanti." + +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Menyambungkan" + +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Mohon tunggu..." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA tidak dapat diluncurkan karena executable GTA:SA tidak dapat dimuat:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "SEDANG MEMERIKSA" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Menambal GTA:SA" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "PEMERIKSAAN UPDATE" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA tidak dapat diluncurkan karena penambalan GTA:SA telah gagal:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Tidak ada pembaruan yang dibutuhkan" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA tidak dapat dilanjutkan karena drive %s tidak mempunyai ruang yang cukup." +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "SEDANG MENGUNDUH" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Berkas yang hilang:" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "sedang menunggu..." -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Jika MTA gagal memuat, mohon pasang ulang GTA:SA" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "PEMBARUAN YANG WAJIB" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Perbarui pengaturan pemasangan" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Untuk bergabung ke server ini, anda harus memperbarui MTA.\n\n" +" Apakah anda ingin memperbarui sekarang ?" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Perbarui pengaturan kompatibilitas" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "PEMBARUAN OPSIONAL" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Tidak diketahui" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Pembaruan direkomendasikan oleh server, tapi tidak wajib.\n\n" +" Apakah anda ingin memperbarui sekarang ?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "Berkas '%s' sedang dikunci oleh proses %zu .\n\n" -"Apakah Anda ingin mengakhiri proses berikut dan melanjutkan pembaharuan?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "Instalasi Anda mungkin korup sekarang.\n\n" -"%zu dari %zu berkas tidak dapat dipulihkan kembali dari cadangannya.\n\n" -"Anda harus menginstal ulang Multi Theft Auta dari www.multitheftauto.com\n" -"atau coba untuk melanjankan pembaharuannya dengan hak administrasi." +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "KESALAHAN SAAT MENYIMPAN" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Memulai Grand Theft Auto: Sand Andreas.\n" -"Pastikan gamenya diletakan pada folder 'Program Files (x86)'." +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Tidak dapat membuat berkas." -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "Mencari GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "KESALAHAN SAAT MENGUNDUH" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Maaf, game tidak ditemukan.\n" -"Mulai Grand Theft Auto: San Andreas dan klik coba ulang.\n" -"Pastikan gamenya diletakan pada folder 'Program Files (x86)'." +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Berkas yang telah diunduh sepertinya salah." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Pilih direktori pemasangan Grand Theft Auto: San Andreas anda" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Untuk beberapa alasan." -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Kesalahan memuat modul %s! (%s)" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "PENGUNDUHAN SELESAI" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Pemasangan baru dari %s terdeteksi.\n\n" -"Apakah anda ingin menyalin pengaturan dari %s ?" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Kesalahan yang tidak diketahui pada _DialogUpdateResult" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA mengalami masalah saat membuka berkas '%s'" +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "BERKAS GTA:SA YANG TELAH DIKUSTOMISASI" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA kehilangan berkas '%s'." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Oke" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA mengalami masalah saat memuat model." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "KESALAHAN" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Jika anda belakangan ini memodifikasi gta3.img, coba pasang ulang GTA:SA." +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Beberapa berkas data MTA:SA hilang.\n\n\n" +"Mohon pasang ulang MTA:SA" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA mengalami masalah saat menambah peningkatan ke sebuah kendaraan." +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% telah selesai" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2840 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA menemukan kesalahan di dalam berkas '%s'" +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Sedang menunggu respon - %-3d" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Apakah komputer anda memulai ulang saat bermain MTA:SA?" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ BANTUAN PERINTAH ]***\n" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Mohon akhiri program berikut sebelum melanjutkan:" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Waktunya adalah %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Permintaan website" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "menyambung: Jaringan belum siap, mohon tunggu sebentar" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Server meminta situs web berikut untuk memuatnya (nanti):" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "menyambung: Sintaksisnya adalah 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "JANGAN PERNAH MEMASUKAN DATA SENSITIF UNTUK MELINDUNGINYA DARI PENCURIAN" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "menyambung: Nomor port buruk" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Ingat keputusan" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "menyambung: Menyambungkan ke %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Izinkan" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "menyambung: tidak dapat tersambung ke %s:%u!" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Tolak" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "menyambung: Gagal untuk melepas mod" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "Menu utama" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "menyambung ulang: Jaringan belum siap, mohon tunggu sebentar" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Anda menggunakan fitur build cabang! Ini hanyalah sebuah tes build yang tidak dapat digunakan untuk menyambungkan ke server publik!" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "menyambung ulang: Nomor port yang tidak bagus" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA tidak akan menerima pembaharuan di XP/Vista setelah July 2019.\n" -"Perbarui Windows untuk bermain di server terbaru." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "menyambung ulang: Menyambung ulang ke %s:%u..." -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Ini akan memutuskan anda dari server ini.\n\n" -"Apakah anda yakin ingin memutuskan?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "menyambung ulang: tidak dapat menyambung ke %s:%u!" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "PERINGATAN PEMUTUSAN" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Semua kontrol dari GTA telah terikat" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "INFORMASI" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Berkas konfigurasi telah tersimpan" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Bahasa Indonesia" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Serial anda adalah: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "PENGATURAN" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Multi pemain" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Vidio" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Audio" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Ikatan" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Kontrol" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Tampilan" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Penjelajah Web" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Tingkat lanjut" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Memuat default" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Sensitivitas mouse:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Sensitivitas bidikan vertikal:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Pengaturan mouse" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Balikkan mouse secara vertikal" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Setir menggunakan mouse" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Terbang menggunakan mouse" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Pengaturan joypad" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Kontrol standar (Mouse + Keyboard)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Kontrol klasik (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Zona Mati" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Kejenuhan" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Gunakan tab 'Ikatan' untuk pengaturan tombol joypad." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Stick Kiri" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Stick Kanan" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "DESKRIPSI" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "TOMBOL" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "TOMBOL ALT." #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Nama:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Simpan kata sandi server" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Segarkan penjelajah server secara otomatis" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Izinkan mengunggah layar" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Izinkan suara luar" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Selalu perlihatkan jendela unduhan" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Perbolehkan penyambungan dengan Discord Rich Presence" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "Menyimpan foto yang diambil oleh kamera senjata ke folder GTA San Andreas User Files" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Gunakan berkas GTA:SA yang telah dikustomisasi" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Pengaturan rendering peta" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Opasitas:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "Resolusi gambar:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "1024 x 1024 (Bawaan)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Volume utama:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Volume radio:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Volume SFX:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "Volume MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Volume suara:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Mode putar:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Umum" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Pilihan radio" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Penyama Radio" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Penyelaras Otomatis Radio" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Pengaturan track pengguna" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Radio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Acak" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Berurutan" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Pemindai Media Otomatis" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Pilihan bisu" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Bisukan semua suara ketika jendela diminimalkan" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Bisukan suara Radio ketika diminimalkan" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Bisukan suara SFX ketika diminimalkan" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Bisukan suara MTA ketika diminimalkan" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Bisukan suara ketika diminimalkan" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Resolusi:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Ruang Pandang:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Jarak Pandang:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Kecerahan:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Kualitas FX:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Filter anisotropik:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Anti-aliasing:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Rasio Aspek:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Mode jendela" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "Kesadaran DPI" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Standar" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Tanpa bingkai resolusi tetap" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Pemetaan Mip" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Rendah" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Sedang" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Tinggi" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Sangat tinggi" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Mati" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Otomatis" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "Cocokkan HUD dengan Rasio Aspek" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Bayangan Volumetrik" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Efek rumput" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Kabut panas" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Asap Ban dll" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Bayangan dinamik ped" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Gerakan buram" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Korona refleksi hujan" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Minimalkan layar penuh" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Aktifkan Dialog Pemilihan Perangkat" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Tampilkan resolusi yang tidak aman" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Selalu render kendaraan dalam detail tinggi" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Render pejalan kaki selalu dalam detail tinggi" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Aktifkan kendali situs web" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Aktifkan Javascript di situs web yang dikendalikan" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "Aktifkan render GPU" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Daftar hitam khusus" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Masukkan sebuah domain spt. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Blok" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Domain" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Hapus domain" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Daftar putih khusus" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Izinkan" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Lainnya" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Muat pakaian CJ dengan cepat:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Kecepatan penjelajah:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Koneksi tunggal:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Tanda paket:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Animasi perkembangan:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Prioritas proses:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Pengaturan debug:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Memori streaming:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Tipe pembaruan build:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Pasang pembaruan penting:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Nyala" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Sangat lambat" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Bawaan" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Cepat" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Biasa" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Di atas normal" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Minimal" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Maks" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Kompatibilitas dengan Windows 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "warna 16-bit" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Penetapan mouse" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Berkas sumber klien:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Tampilkan di Explorer" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "Atur afinitas CPU ke 0 untuk meningkatkan performa game" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Pembaru otomatis" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Periksa pembaruan sekarang" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Beberapa pengaturan akan berubah ketika anda menjalankan MTA selanjutnya" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Apa anda ingin memulai kembali sekarang?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "DIPERLUKAN MULAI ULANG" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Beberapa pengaturan akan berubah ketika anda putus dari server ini" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Apa anda ingin memutus sekarang?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "DIPERLUKAN PEMUTUSAN" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad tidak terdeteksi - Periksa koneksi dan mulai ulang permainan" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Mengikat sumbu" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Pindahkan sumbu untuk mengikat, atau escape untuk menghapus" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Bahasa:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Tampilan:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Pengaturan awal:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Obrolan" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Muat" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Warna" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Tata letak" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Pengaturan" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Latar belakang Obrolan" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Teks Obrolan" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Latar belakang input" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Teks Input" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Baris:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Skala:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Lebar:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Ukuran" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "setelah" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "selama" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "detik" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Kepudaran" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Pudarkan obrolan lama" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horisontal:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Vertikal:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Jajaran-Teks:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-Offset:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-Offset:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Posisi" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Bergerak ke kiri" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Tengah" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Bergerak ke kanan" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Atas" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Bawah" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Jenis Huruf" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Sembunyikan latar belakang ketika tidak sedang mengetik" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Penyelesaian nama menggunakan tombol \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Izinkan server untuk mengedipkan jendela" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Izinkan notifikasi balon baki" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Garis luar hitam/putih pada teks obrolan" @@ -1551,112 +1835,116 @@ msgstr "Garis luar hitam/putih pada teks obrolan" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Tekan tombol untuk mengikat, atau escape untuk menghapus" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Mengikat tombol utama" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Mengikat tombol sekunder" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "KONTROL PERMAINAN GTA" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "KONTROL MULTI PEMAIN" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Nama anda mengandung karakter yang tidak valid!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Menu utama" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "Dalam permainan" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Merah:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Hijau:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Biru:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Transparansi:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Warna" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Pratinjau" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Silahkan putuskan sebelum mengganti bahasa" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Silakan putuskan sebelum mengganti skin" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Bayangan volumetrik dapat menyebabkan beberapa sistem menjadi lambat.\n\n" "Apakah anda yakin ingin mengaktifkannya?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "PERINGATAN KINERJA" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Unggah layar diperlukan oleh beberapa server untuk kepentingan anti-cheat.\n\n" "(Kotak obrolan dan GUI tidak termasuk dalam pengunggahan)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "INFORMASI UNGGAH LAYAR" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "Beberapa scripts mungkin memainkan suara, seperti radio, dari internet.\n\n" "Nonaktifkan setting ini mungkin bisa mengurangi konsumsi pita jaringan.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "SUARA LUAR" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "Sepertinya Anda telah menyalakan opsi koneksi Rich Presence.\n" -"Apakah Anda ingin memperbolehkan server untuk membagikan datanya?\n\n" -"Ini termasuk ID unik identifikasi Anda." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "MENGIZINKAN UNTUK MEMBAGIKAN DATA" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1666,11 +1954,7 @@ msgstr "Beberapa berkas dalam direktori data GTA:SA anda telah dikustomisasi.\n" "Namun, BERKAS GTA:SA YANG TELAH DIKUSTOMISASI DIBLOK OLEH BANYAK SERVER\n\n" "Apakah anda yakin ingin menggunakannya?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "BERKAS GTA:SA YANG TELAH DIKUSTOMISASI" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1679,550 +1963,252 @@ msgstr "Pengaktifan kesadaran DPI adalah sebuah fitur eksperimen dan kami hanya "Anda mungkin mengalami masalah grafik jika anda mengaktifkan opsi ini.\n\n" "Apakah anda yakin akan mengaktifkan opsi ini?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "FITUR EKSPERIMEN" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Silakan masukkan nama" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Silakan masukkan nama untuk digunakan dalam permainan. \n" "Ini akan menjadi nama anda ketika anda terhubung dan bermain di sebuah server" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Fitur yang sangat eksperimental." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Hentikan variasi CJ (Menggunakan 65MB lebih banyak RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Router lama mungkin memerlukan kecepatan pemindaian yang lebih lambat." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Nyalakan untuk menggunakan hanya satu sambungan ketika mengunduh." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Tandai paket jaringan untuk membantu ISP mengidentifikasi arus MTA." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Animasi lingkaran berputar di bagian bawah layar" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Selalu pilih default. (Pengaturan ini tidak di simpan)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maksimum biasanya yang paling baik" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Pemuktahir otomatis:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Pilih default kecuali anda ingin mengisi laporan bug." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Pilih default untuk memasang pembaruan penting secara otomatis." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "warna 16-bit:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Aktifkan mode warna 16 bit - MTA perlu dimulai ulang" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Penetapan mouse:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Penetapan gerakan mouse - Mungkin PC perlu dimulai ulang" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "Afinitas CPU:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Perintah tidak dikenal atau cvar: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Sibuk" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Tidak dapat memeriksa pembaruan sekarang" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "Diperlukan MTA:SA %s" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Versi dari MTA:SA %s yang terbaru dibutuhkan untuk bergabung dengan server yang dipilih.\n\n" -"Apakah anda ingin mengunduh dan memasang MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Apakah anda ingin meluncurkan MTA:SA %s dan menyambungkannya ke server ini ? " - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Tidak memungkinkan untuk menyambungkan saat ini.\n\n" -"Silakan coba nanti." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Menyambungkan" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Mohon tunggu..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "SEDANG MEMERIKSA" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "PEMERIKSAAN UPDATE" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Tidak ada pembaruan yang dibutuhkan" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "SEDANG MENGUNDUH" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "sedang menunggu..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "PEMBARUAN YANG WAJIB" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Untuk bergabung ke server ini, anda harus memperbarui MTA.\n\n" -" Apakah anda ingin memperbarui sekarang ?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "PEMBARUAN OPSIONAL" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Pembaruan direkomendasikan oleh server, tapi tidak wajib.\n\n" -" Apakah anda ingin memperbarui sekarang ?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "KESALAHAN SAAT MENYIMPAN" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Tidak dapat membuat berkas." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "KESALAHAN SAAT MENGUNDUH" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Berkas yang telah diunduh sepertinya salah." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Untuk beberapa alasan." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "PENGUNDUHAN SELESAI" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Kesalahan yang tidak diketahui pada _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Oke" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "KESALAHAN" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Beberapa berkas data MTA:SA hilang.\n\n\n" -"Mohon pasang ulang MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% telah selesai" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Sedang menunggu respon - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Proses penyambungan gagal. Nama yang diberikan tidak valid!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Proses penyambungan gagal. Pengelola yang diberikan tidak valid!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Proses penyambungan ke %s pada port %u gagal!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Menyambungkan ke %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "Menyambung ulang ke %s:%u ..." - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "MENYAMBUNGKAN" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Koneksi terputus" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Terputus: kesalahan protokol tidak diketahui" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Terputus: diputuskan dari jarak jauh" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Terputus: koneksi hilang dari jarak jauh" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Terputus: anda dilarang dari server ini" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Terputus: terputus dari server" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Terputus: koneksi dengan server hilang" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Terputus: koneksi ditolak" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Tidak ada mod yang terpasang (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Respon server tidak baik (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Respon server tidak baik (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "BERITA" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Kunjungi artikel berita terbaru" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONSOL" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Kesalahan fatal" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "UNTUK MEMPERBAIKI, HAPUS BERKAS INI:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "Modul %s salah!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Kesalahan menjalankan URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "layar bantuan ini" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "keluar dari aplikasi" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "menampilkan versi" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "menampilkan waktu" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "menampilkan hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "menampilkan semua ikatan" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "menampilkan serial anda" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "menyambungkan ke server (host port nama sandi)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "menyambungkan ke server sebelumnya" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "mengikat sebuah tombol (tombol kontrol)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "melepas ikatan sebuah tombol (tombol)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" -msgstr "menyalin kontrol default gta" - -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "mengeluarkan sebuah tangkapan layar" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "langsung menyimpan pengaturan" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "membersihkan tampilan debug" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "menggulung kotak obrolan ke atas" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "menggulung kotak obrolan ke bawah" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "menggulung tampilan debug ke atas" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "menggulung tampilan debug ke bawah" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "menampilkan statistik penyimpanan" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "menampilkan grafik frame waktu" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "untuk developer: muat ulang berita" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ BANTUAN PERINTAH ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Waktunya adalah %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "menyambung: Jaringan belum siap, mohon tunggu sebentar" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "menyambung: Sintaksisnya adalah 'connect [ ]'" +msgstr "menyalin kontrol default gta" -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "menyambung: Nomor port buruk" +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "mengeluarkan sebuah tangkapan layar" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "menyambung: Menyambungkan ke %s:%u..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "langsung menyimpan pengaturan" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "menyambung: tidak dapat tersambung ke %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "membersihkan tampilan debug" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "menyambung: Gagal untuk melepas mod" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "menggulung kotak obrolan ke atas" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "menyambung ulang: Jaringan belum siap, mohon tunggu sebentar" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "menggulung kotak obrolan ke bawah" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "menyambung ulang: Nomor port yang tidak bagus" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "menggulung tampilan debug ke atas" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "menyambung ulang: Menyambung ulang ke %s:%u..." +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "menggulung tampilan debug ke bawah" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "menyambung ulang: tidak dapat menyambung ke %s:%u!" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "menampilkan statistik penyimpanan" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Semua kontrol dari GTA telah terikat" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "menampilkan grafik frame waktu" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Berkas konfigurasi telah tersimpan" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "untuk developer: muat ulang berita" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Serial anda adalah: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Anda menggunakan fitur build cabang! Ini hanyalah sebuah tes build yang tidak dapat digunakan untuk menyambungkan ke server publik!" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Sumbu Akselerasi" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA tidak akan menerima pembaharuan di XP/Vista setelah July 2019.\n" +"Perbarui Windows untuk bermain di server terbaru." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Sumbu Rem" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Ini akan memutuskan anda dari server ini.\n\n" +"Apakah anda yakin ingin memutuskan?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Pemrograman" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "PERINGATAN PEMUTUSAN" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Kontributor" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "INFORMASI" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Desain Game / Scripting" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "BERITA" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Lokalisasi Bahasa" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Kunjungi artikel berita terbaru" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Kontributor penambalan" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Tangkapan layar mempunyai %d byte, tetapi seharusnya %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Terima Kasih Khusus" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Tangkapan layar gagal" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Perangkat lunak dan proyek ini menggunakan libraries (.lib) dan perangkat lunak berikut:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Tangkapan layar terambil: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Apakah anda ingin melihat beberapa bantuan daring tentang masalah ini ?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Perintah tidak dikenal atau cvar: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2397,25 +2383,56 @@ msgid "Group control backwards" msgstr "Kontrol grup ke belakang" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Skin yang kamu pilih tidak dapat dimuat, dan skin default juga tidak dapat dimuat, silakan pasang ulang MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Tangkapan layar mempunyai %d byte, tetapi seharusnya %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Apakah anda ingin melihat beberapa bantuan daring tentang masalah ini ?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Tangkapan layar gagal" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONSOL" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Tangkapan layar terambil: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Pemrograman" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Kontributor" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Desain Game / Scripting" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Lokalisasi Bahasa" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Kontributor penambalan" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Terima Kasih Khusus" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Perangkat lunak dan proyek ini menggunakan libraries (.lib) dan perangkat lunak berikut:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Sumbu Akselerasi" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Sumbu Rem" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2423,6 +2440,59 @@ msgstr "Tidak dapat menginisialisasi Direct3D9.\n\n" "Pastikan bahwa DirectX End-User Runtime dan\n" "Windows Service Packs yang terbaru telah terpasang dengan benar." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Diam" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "pemainpemain" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "pada" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "serverserver" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Meminta daftar master server (%lu ms telah lewat)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "List master server tidak dapat diurai." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "List master server tidak dapat diperoleh." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Daftar cadangan server)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Tidak dapat mengikat soket LAN-broadcast" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Mencoba untuk menemukan server LAN" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2476,7 +2546,7 @@ msgstr "Latensi:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Daftar pemain" @@ -2503,40 +2573,39 @@ msgstr "Segera bergabung ke server jika slot pemain tersedia." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "SILAKAN MASUKKAN KATA SANDI SERVER" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Terputus" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Sedang query..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "PENJELAJAH SERVER" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Lokal" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Favorit" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Belakangan ini" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2544,296 +2613,367 @@ msgstr "UNTUK SAMBUNGAN CEPAT:\n\n" "Ketik alamat dan port ke kolom alamat.\n" "Atau pilih salah satu server dari daftar riwayat dan tekan 'Sambung'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "BANTUAN" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Segarkan" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Tambahkan ke Favorit" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Sambung" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Informasi server" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Cari server" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Cari pemain" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Mulai pencarian" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Cari pemain..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Cari server..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Nama" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Pemain" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Ping" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Mode permainan" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Termasuk:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Kosong" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Penuh" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Terkunci" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Luring" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Versi Lainnya" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Kembali" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Memuat..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..memuat.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Tidak ada alamat yang ditujukan!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Protokol tidak dikenal" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Mohon gunakan protokol mtasa://!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Nickname tidak valid! Harap pergi ke Pengaturan dan tulis yang baru!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Anda harus memilih sebuah server untuk disambungi." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Diam" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Masalah dengan driver grafik" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "pemainpemain" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Tidak dapat menemukan resolusi layar yang valid." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "pada" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Apa anda yakin ingin menggunakan resolusi layar ini?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "serverserver" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "Gagal menginisialisasi game_sa" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Meminta daftar master server (%lu ms telah lewat)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "Gagal mengalokasikan memori" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "List master server tidak dapat diurai." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Permintaan website" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "List master server tidak dapat diperoleh." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Server meminta situs web berikut untuk memuatnya (nanti):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Daftar cadangan server)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "JANGAN PERNAH MEMASUKAN DATA SENSITIF UNTUK MELINDUNGINYA DARI PENCURIAN" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Tidak dapat mengikat soket LAN-broadcast" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Ingat keputusan" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Mencoba untuk menemukan server LAN" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Tolak" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Versi ini sudah kadaluarsa." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "memutuskan dari permainan" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "menampilkan tanda nama" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "menampilkan kotak obrolan" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "menunjukkan statistik jaringan" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "membuka input obrolan" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "mentransmisikan suara ke pemain lain" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "masuk ke mobil sebagai penumpang" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "saluran radio selanjutnya" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "saluran radio sebelumnya" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "mengaktifkan tampilan peta pemain" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "perbesar peta pemain" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "perkecil peta pemain" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "pindahkan peta pemain kearah utara" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "pindahkan peta pemain kearah selatan" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "pindahkan peta pemain kearah timur" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "pindahkan peta pemain kearah barat" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "melampirkan peta pemain" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "mengurangi opasitas peta pemain" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "menambahkan opasitas peta pemain" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "mengaktifkan teks bantuan peta pemain" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "mengirim pesan ke pemain yang dituju" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "mengganti ke senjata selanjutnya ketika di dalam kendaraan" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "mengganti ke senjata sebelumnya ketika di dalam kendaraan" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "mengeluarkan info tentang server" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "menetapkan skala perkalian dari semua tampilan teks" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Mode pengembangan) menampilkan colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Mode pengembangan) mencetak suara dunia ids ke jendela debug" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "BUAT SERVER" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Sumber" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Nama server:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Kata sandi:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Jlh maks pemain:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Penyiaran:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Terpilih" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Semua" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Mulai" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "Ubah mode: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "Pembesaran: %s %s Pergerakan: %s, %s, %s, %s Opasitas: %s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "Aktifkan peta: %s Aktifkan teks bantuan: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "Mengikuti Pemain" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "Bebaskan Gerakan" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Kemajuan pengunduhan peta:" @@ -2854,488 +2994,398 @@ msgstr "%s dari %s" msgid "Disconnect to cancel download" msgstr "Putuskan untuk membatalkan pengunduhan" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Terputus: Namanya tidak valid" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Terputus dari server" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Terputus: Serialnya telah dilarang.\n" "Alasan: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Terputus: Anda telah dilarang.\n" "Alasan: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Terputus: Akunnya telah dilarang.\n" "Alasan: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Terputus: Versi tidak cocok" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Terputus: Terlalu banyak yang bergabung. Mohon tunggu semenit, lalu sambungkan ulang." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Terputus: Server dari cabang lainnya.\n" "Informasi: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Terputus: Versi yang buruk.\n" "Informasi: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Terputus: Server sedang menjalankan build yang lebih baru.\n" "Informasi: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Terputus: Server sedang menjalankan build yang lebih lama.\n" "Informasi: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Terputus: Nama telah digunakan" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Koneksi Putus: Pemain elemen tidak bisa dibuat." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Terputus: Server menolak sambungan: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Terputus: Verifikasi serial gagal" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "Terputuskan: Serial sudah terpakai" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Terputus: Desinkronisasi koneksi %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Terputus: Anda diusir oleh %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Terputus: Anda dilarang oleh %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Terputus: Server mati atau sedang memulai ulang" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Anda diusir dari permainan" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Server ini membutuhkan sebuah gta_sa.exe yang tidak termodifikasi" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Mohon mengganti gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Server ini tidak mengizinkan untuk custom D3D9.DLL" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Hapus D3D9.DLL dari ruang instalasi GTA anda dan mulai ulang MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Server ini tidak mengizinkan untuk memakai mesin virtual" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Server ini membutuhkan driver signing untuk diaktifkan" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Mohon mulai ulang PC anda" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Server ini telah mendeteksi komponen anti-cheat tidak ada" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Coba mulai ulang MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Server ini membutuhkan sebuah gta3.img dan gta_int.img yang tidak dimodifikasi" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Mohon ganti gta3.img atau gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Server ini tidak megizinkan menggunakan Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Pastikan tidak ada program lain yang memodifikasi MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Waktu Tersisa: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d hari" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d jam" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d menit" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" msgstr[0] "%d detik" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Terputus" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Kesalahan pengunduhan: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "Menerbangkan sebuah UFO keliling" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "Berkeliling sekitar" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "Menunggangi ombak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "Menaiki kereta pada" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "Terbang berkeliling" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "Berkeliling" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "Berkeliling menggunakan Truk Monster" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "Berkeliling dengan kendaraan empat roda" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "Melompat-lompat sekeliling" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "Melakukan hal aneh di" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "Memanjat-manjat pada" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "Melakukan sebuah drive-by pada" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "Blub blub..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "Menghirup air" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "Tenggelam di" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "Menunduk untuk perlindungan di" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "Bertarung di" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "Bertarung tangan di" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "Meledakkan orang bodoh di" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "Menembaki" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "Meng-jetpack di" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "Benar-benar terbakar di" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "Terbakar di" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "Berenang di" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "Melayang-layang di" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "Sedang dikejar oleh seekor hiu" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "Tersedak hingga mati di" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Memasuki permainan ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Tidak tersambung; silakan gunakan Sambungan Cepat atau perintah 'connect' untuk menyambungkan ke server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Tidak dapat memulai server lokal. Lihat konsol untuk lebih rinci." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Server Lokal" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Memulai server lokal ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "Area 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "Berjalan-jalan " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Anda diusir dari permainan ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Menyambungkan ke server lokal..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Kesalahan saat menyambung ke server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Terputus saat menyambung ke server lokal. Lihat konsol untuk lebih rinci." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Sambungan dengan server hilang" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Terputus: server sedang penuh" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Terputus: kata sandi yang diberikan tidak valid" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "Verifikasi klien MTA gagal!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "Di sebuah selokan" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "Dalam perjalanan ke rumah sakit" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "Menemui sang pencipta mereka" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "Menyesali keputusan mereka" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "Meninggal" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "BUAT SERVER" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Sumber" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Nama server:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Kata sandi:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Jlh maks pemain:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Penyiaran:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Terpilih" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Semua" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Mulai" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "Ubah mode: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "Pembesaran: %s %s Pergerakan: %s, %s, %s, %s Opasitas: %s/%s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "Aktifkan peta: %s Aktifkan teks bantuan: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "Mengikuti Pemain" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "Bebaskan Gerakan" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Masalah dengan driver grafik" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Tidak dapat menemukan resolusi layar yang valid." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Apa anda yakin ingin menggunakan resolusi layar ini?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "Gagal menginisialisasi game_sa" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "Gagal mengalokasikan memori" +msgid "Download error: %s" +msgstr "Kesalahan pengunduhan: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3356,11 +3406,11 @@ msgstr "" msgid "Connection error" msgstr "Kesalahan koneksi" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto tidak terpasang dengan benar, silahkan pasang ulang." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Penjelajah anda akan menampilkan situs web dengan beberapa informasi bantuan.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/it_IT/client.pot b/Shared/data/MTA San Andreas/MTA/locale/it_IT/client.pot index 2f224493d42..f50e3769fdf 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/it_IT/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/it_IT/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Italian\n" "Language: it_IT\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Problemi nel riavvio di MTA:SA\n\n" -"Se il problema persiste, aprire Task Manager e\n" -"fermare i processi 'gta_sa.exe' e 'Multi Theft Auto.exe'\n\n\n" -"Avviare nuovamente MTA:SA?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Errore" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Un'altra istanza di MTA è già in esecuzione.\n\n" -"Se il problema persiste riavviare il computer" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Un'altra istanza di MTA è già in esecuzione.\n\n" -"Desideri terminarla?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Seleziona la tua directory di installazione di Grand Theft Auto: San Andreas" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA richiede l'accesso come amministratore per il seguente compito:\n\n" +"'%s'\n\n" +"Per favore conferma nella prossima finestra." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Errore durante il caricamento del modulo %s! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Copiando i files..." -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Copia finita presto. Tutto OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Completamento in corso..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Fatto!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Nuova installazione di %s rilevata.\n\n" +"Copiare le impostazioni da %s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA sta avendo problemi ad aprire il file '%s" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA non ha il file %s." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA sta avendo problemi a caricare un modello." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Se gta3.img è stato modificato di recente, provare a reinstallare GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA ha avuto problemi ad aggiungere un potenziamento ad un veicolo." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA ha trovato errori nel file '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Il tuo computer è stato riavviato mentre giocavi a MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Terminare i seguenti programmi prima di continuare:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Errore sulla versione dei file. Se si riscontrano problemi reinstallare MTA:SA.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Alcuni file sono mancanti. Se si riscontrano problemi reinstallare MTA:SA.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA non è compatibile con la 'modalità provvisoria' di Windows.\n\n" +"Riavviare il PC.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Stai avendo problemi utilizzando MTA:SA?.\n\n" "Vuoi riutilizzare una versione precedente?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "Sembra ci sia un problema nell'avvio di MTA:SA.\n" "Resettare le impostazioni di GTA può risolvere questo problema.\n\n" "Vuoi resettare le impostazioni di GTA ora?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "Le impostazioni di GTA sono state resettate.\n\n" "Premi OK per continuare." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Il file non può essere cancellato: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Stai avendo problemi utilizzando MTA:SA?.\n\n" "Vuoi controllare il supporto online?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Stai avendo problemi a eseguire MTA:SA?.\n\n" "Vuoi cambiare le seguenti impostazioni?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Modalità tutto schermo:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Finestra senza bordi " -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Stai avendo problemi ad eseguire MTA:SA?.\n\n" "Prova a disabilitare i seguenti prodotti per GTA e MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +189,293 @@ msgstr "ATTENZIONE\n\n" "MTA:SA ha rilevato un'attività sospetta.\n" "Eseguire una scansione virus per assicuarsi che il sistema sia al sicuro.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Il file rilevato era: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Un'istanza di GTA: San Andreas è già in esecuzione. Ha bisogno di essere chiusa prima di poter avviare MTA:SA. Vuoi farlo adesso?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informazioni" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Impossibile terminare GTA: San Andreas. Se il problema persiste riavviare il computer." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Problemi nel riavvio di MTA:SA\n\n" +"Se il problema persiste, aprire Task Manager e\n" +"fermare i processi 'gta_sa.exe' e 'Multi Theft Auto.exe'\n\n\n" +"Avviare nuovamente MTA:SA?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Errore" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Un'altra istanza di MTA è già in esecuzione.\n\n" +"Se il problema persiste riavviare il computer" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Un'altra istanza di MTA è già in esecuzione.\n\n" +"Desideri terminarla?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Voci di registro mancanti. Per favore reinstalla Multi Theft Auto: San Andreas" -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Il percorso d'installazione di GTA: San Andreas contiene dei caratteri non supportati (unicode). Per favore muovi la tua installazione di Grand Theft Auto: San Andreas in un percorso compatibile che contenga solo caratteri ASCII standard e reinstalla Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Il percorso d'installazione di 'MTA:SA' o 'GTA: San Andreas'\n" -"contiene un ';' (punto e virgola).\n\n" -"Se riscontri problemi utilizzando MTA:SA,\n" -"sposta l'installazione/installazioni in un percorso che non contiene il punto e virgola." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Caricamento fallito. Per favore assicurati che i file dati più recenti siano stati installati correttamente." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Caricamento fallito. Per favore assicurati che %s sia installato correttamente." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Caricamento fallito. Impossibile trovare gta_sa.exe in %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Caricamento fallito: %s esiste nella directory di GTA. Per favore eliminalo prima di continuare." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Il file principale ha un nome incoretto (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Il file principale non è certificato. Potrebbe esserci un virus.\n\n" -"Se MTA non funziona correttamente, chiedi aiuto online." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Il file data %s è mancante. E' possibile che sia stato un virus.\n\n" -"Si consiglia di reinstallare Multi Theft Auto per la vostra sicurezza.\n" -"Cercare aiuto online se MTA non funziona correttamente." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Il file data %s è stato modificato. E' possibile che sia stato un virus.\n\n" -"Si consiglia di reinstallare Multi Theft Auto per la vostra sicurezza.\n" -"Cercare aiuto online se MTA non funziona correttamente." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "Dei file .asi sono nella cartella di installazione di 'MTA:SA' o 'GTA:San Andreas'.\n\n" -"Se si riscontrano problemi, rimuovere questi file .asi." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Errore sulla versione dei file. Se si riscontrano problemi reinstallare MTA:SA.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Alcuni file sono mancanti. Se si riscontrano problemi reinstallare MTA:SA.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA non è compatibile con la 'modalità provvisoria' di Windows.\n\n" -"Riavviare il PC.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Risolvere problema di configurazione" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Risolvere errore di elevazione richiesta" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Sconosciuto" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "Il file '%s' iè bloccato da %zu processi.\n\n" +"Terminare i seguenti processi e continuare l'aggiornamento?\n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "La tua installazione potrebbe essere corrotta.\n\n" +"%zu di %zu file non sono stati recuperati dal backup.\n\n" +"Reinstallare Multi Theft Auto da www.multitheftauto.com o provare \n" +"ad eseguire l'aggiornamento con i permessi di amministratore." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Installazione aggiornamento..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Estrazione dei file..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA non può completare il compito seguente:\n\n" +"'%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "**Il blocco è stato causato da un errore del driver grafico**\n\n" +"**Per favore aggiorna i tuoi driver grafici**" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Installa i file aggiornati di MTA:SA" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Impossibile aggiornare a causa di un conflitto dei file. Per favore chiudi le applicazioni e riprova" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto non è stato installato correttamente, per favore installalo nuovamente. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "Crea giunzioni per GTA:SA" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA non si può avviare perchè la copia di un file è fallita:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA non si può avviare perchè un file di MTA:SA non è corretto o mancante:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Copia file di MTA:SA" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA non si può avviare perchè un file di GTA:SA non è corretto o mancante:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "Patch dipendenze di GTA:SA" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA non si può avviare perchè l'eseguibile di GTA:SA non è corretto o mancante:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Si raccomanda di controllare l'antivirus per un falso positivo, provare ad aggiungere l'eseguibile di GTA:SA come eccezione e riavviare MTA:SA." -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "Genera GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA non si è avviato perchè l'eseguibile di GTA:SA non si carica:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Patch GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA non si può avviare perchè il patching di GTA:SA è fallito:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Impossibile avviare Grand Theft Auto: San Andreas. Per favore prova a riavviarlo, oppure se il problema persiste, contatta MTA a www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA non può continuare perché l'unità %s non ha spazio sufficiente." -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA:SA potrebbe non essere stato avviato correttamente. Vuoi terminarlo?" +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "File mancante:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Se MTA non funziona correttamente, reinstallare GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Aggiorna le impostazioni di installazione" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Aggiorna impostazioni compatibilità" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +483,167 @@ msgstr "GTA:SA potrebbe non essere stato avviato correttamente. Vuoi terminarlo? #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Si" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "No" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "OK" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Esci" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Aiuto" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Annulla" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas ha riscontrato un problema" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Informazioni sul crash" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Seleziona la casella di spunta per inviare le informazioni sul crash agli sviluppatori di MTA usando 'internet'" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Facendo questo sarà più probabile che il crash non si verifichi." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Riaprire MTA: San Andreas?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Attenzione" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "La tua cartella d'installazione di Grand Theft Auto: San Andreas ha questi file:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Questi file non sono richiesti e potrebbero interferire con le caratteristiche grafiche in questa versione di MTA:SA.\n\n" "È raccomandato rimuovere o rinominare questi file." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "Mantieni questi file, ma mostra questo avviso al prossimo avvio" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Non avvisare più di questi file" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Rinomina questi file da *.dll a *dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Mostra questi file" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Avvia MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Opzioni confusionarie" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus rilevato!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Prova ogni opzione e verifica quale funziona:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - NVidia Standard" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - NVidia Alternativo" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Intel Standard" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Intel Alternativo" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Se ti stai disperando, questo potrebbe aiutarti:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Se hai già selezionato un'opzione che funziona, questo potrebbe aiutarti:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Forza modalità finestra" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Non mostrare più" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Attenzione: Nessun anti-virus rilevato" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1107 +651,1180 @@ msgstr "MTA non riesce a trovare un anti-virus nel tuo PC.\n\n" "I virus interferiscono con MTA e rovinano la tua esperienza di gameplay.\n\n" "Premi \"Aiuto\" per maggiori informazioni." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Ho già installato un anti-virus" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Non installerò un anti-virus.\n" "Voglio che il mio PC vada lento e fare parte di un botnet." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "In ricerca di Grand Theft Auto: San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Per favore avvia Grand Theft Auto: San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Installazione aggiornamento..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Connessione fallita. Fornito nick non valido!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Estrazione dei file..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Connessione fallita. Fornito host non valido!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Copiando i files..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Connessione a %s con porta %u fallita!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Copia finita presto. Tutto OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Connessione a %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Completamento in corso..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Fatto!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "CONNESSIONE" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA richiede l'accesso come amministratore per il seguente compito:\n\n" -"'%s'\n\n" -"Per favore conferma nella prossima finestra." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Connessione scaduta" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA non può completare il compito seguente:\n\n" -"'%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Disconnesso: protocollo d'errore sconosciuto" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "**Il blocco è stato causato da un errore del driver grafico**\n\n" -"**Per favore aggiorna i tuoi driver grafici**" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Disconnesso: disconnesso remotamente " -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Installa i file aggiornati di MTA:SA" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Disconnesso: connessione persa remotamente " -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Impossibile aggiornare a causa di un conflitto dei file. Per favore chiudi le applicazioni e riprova" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Disconnesso: sei stato bannato da questo server" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Disconnesso: disconnesso dal server" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Disconnesso: la connessione al server è stata perduta" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Disconnesso: la connessione è stata rifiutata" -#: Client/loader/CInstallManager.cpp:561 +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto non è stato installato correttamente, per favore installalo nuovamente. %s" +msgid "No such mod installed (%s)" +msgstr "Questa mod non è installata (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "Crea giunzioni per GTA:SA" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Cattiva risposta del server (2) " -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA non si può avviare perchè la copia di un file è fallita:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Cattiva risposta del server (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA non si può avviare perchè un file di MTA:SA non è corretto o mancante:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Italiano" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Copia file di MTA:SA" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Occupato" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA non si può avviare perchè un file di GTA:SA non è corretto o mancante:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Impossibile controllare gli aggiornamenti in questo momento" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Patch dipendenze di GTA:SA" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s richiesto" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA non si può avviare perchè l'eseguibile di GTA:SA non è corretto o mancante:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Una versione aggiornata di MTA:SA %s è richiesta per entrare nel server selezionato.\n\n" +"Vuoi scaricare ed installare MTA:SA %s?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Si raccomanda di controllare l'antivirus per un falso positivo, provare ad aggiungere l'eseguibile di GTA:SA come eccezione e riavviare MTA:SA." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Vuoi avviare MTA:SA %s e connetterti a questo server?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Genera GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Non è possibile connettersi in questo momento.\n\n" +"Per favore prova più tardi." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA non si è avviato perchè l'eseguibile di GTA:SA non si carica:" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Connessione in corso" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Patch GTA:SA" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Attendere prego..." -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA non si può avviare perchè il patching di GTA:SA è fallito:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "CONTROLLO" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA non può continuare perché l'unità %s non ha spazio sufficiente." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "CONTROLLO AGGIORNAMENTI" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "File mancante:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Nessun aggiornamento necessario" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Se MTA non funziona correttamente, reinstallare GTA:SA" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "IN DOWNLOAD" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Aggiorna le impostazioni di installazione" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "in attesa...." -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Aggiorna impostazioni compatibilità" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "AGGIORNAMENTO OBBLIGATORIO" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Sconosciuto" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Per entrare in questo server devi aggiornare MTA.\n\n" +"Vuoi aggiornare ora?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "Il file '%s' iè bloccato da %zu processi.\n\n" -"Terminare i seguenti processi e continuare l'aggiornamento?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "AGGIORNAMENTO OPZIONALE" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "La tua installazione potrebbe essere corrotta.\n\n" -"%zu di %zu file non sono stati recuperati dal backup.\n\n" -"Reinstallare Multi Theft Auto da www.multitheftauto.com o provare \n" -"ad eseguire l'aggiornamento con i permessi di amministratore." +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Il server raccomanda un aggiornamento anche se non essenziale.\n\n" +"Vuoi aggiornare ora?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "ERRORE DI SALVATAGGIO" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Impossibile creare il file." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Seleziona la tua directory di installazione di Grand Theft Auto: San Andreas" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "ERRORE DI DOWNLOAD" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Errore durante il caricamento del modulo %s! (%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "I file di download sembrano incorretti." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Nuova installazione di %s rilevata.\n\n" -"Copiare le impostazioni da %s ?" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Per qualche motivo." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA sta avendo problemi ad aprire il file '%s" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "DOWNLOAD COMPLETO" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA non ha il file %s." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr "-Problema sconosciuto in _DialogUpdateResult" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA sta avendo problemi a caricare un modello." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "FILE PERSONALIZZATI DI GTA:SA" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Se gta3.img è stato modificato di recente, provare a reinstallare GTA:SA." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ok" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA ha avuto problemi ad aggiungere un potenziamento ad un veicolo." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "ERRORE" + +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Alcuni file dati di MTA:SA sono mancanti.\n\n\n" +"Per favore reinstalla MTA:SA" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA ha trovato errori nel file '%s'" +msgid "%3d %% completed" +msgstr "%3d %% completato" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Il tuo computer è stato riavviato mentre giocavi a MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"In attesa di risposta - %-3d" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Terminare i seguenti programmi prima di continuare:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ AIUTO COMANDO ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Richieste del sito web" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Sono le ore %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Il server richiede i seguenti siti Web per caricarli (in seguito):" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NON INSERIRE MAI DATI SENSIBILI PER EVITARE CHE VENGANO RUBATI" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "connessione: Sintassi 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Salva la decisione" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "connessione: Numero porta errata" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Permetti" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "connessione: Connessione a %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Rifiuta" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "connessione: impossibile connettersi a %s:%u!" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "connessione: Impossibile fermare la mod corrente" + +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Stai utilizzando una build di rami di funzionalità! Questa è solo una build di prova che non può essere utilizzata per connettersi a server pubblici!" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA non riceverà più aggiornamenti per XP/Vista dopo Luglio 2019.\n\n" -"Aggiornate Windows per continuare a giocare aggiornati." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Questo ti disconnetterà dal server corrente.\n\n" -"Sei sicuro di volerti disconnettere?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "AVVERTIMENTO DI DISCONNESSIONE" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Associa tutti i controlli da GTA" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "File di configurazione salvato" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Italiano" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Il tuo numero seriale è: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "IMPOSTAZIONI" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Multigiocatore" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Video" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Audio" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Associazioni" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Controlli" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Interfaccia" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Browser Web" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Avanzate" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Carica i predefiniti" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Sensibilità del Mouse:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Sensibilità di mira verticale:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Opzioni del mouse" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Inverti il mouse verticalmente" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Sterzo via mouse" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Volo via mouse" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Opzioni del Joypad" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Controlli standard (mouse + tastiera)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Controlli classici (joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Zona morta" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Saturazione" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Usa la tabella d'associazione per i tasti del joypad." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Levetta Sinistra" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Levetta Destra" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "DESCRIZIONE" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "TASTO" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "TASTO.ALT" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Nome:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Salva la password del server" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Aggiorna automaticamente la ricerca dei server" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Permetti l'upload delle immagini" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Consenti suoni esterni" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Mostra sempre la finestra di download" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Usa file personalizzati di GTA:SA" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Opzioni di render della mappa" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Opacità:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Volume principale:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Volume radio:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Volume SFX:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "Volume MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Volume voce:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Modalità riproduzione:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Generale" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Opzioni radio" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Equalizzatore Radio" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Auto sintonizzazione radio" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Opzioni usertrack" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Radio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Casuale" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Sequenziale" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Scansione automatica dei file" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Opzioni di disattivazione dell'audio" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Disattiva tutti i suoni quando ridotto a icona" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Muta la radio quando minimizzato" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Muta SFX quando minimizzato" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Muta i suoni di MTA quando minimizzato" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Muta la voce quando il suono è minimo " #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Risoluzione:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Campo visivo:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Distanza di visualizzazione:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Luminosità:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Qualità FX:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Filtro anisotropico:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Antialiasing:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Rapporto dimensioni:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "In finestra" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "Consapevolezza DPI" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Normale" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Mantenere risoluzione senza bordi" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mappatura Mip" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Bassa" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Media" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Alta" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Molto alta" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Nessuno" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Automatica" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD Corrispondenza aspetto" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Ombre volumetriche" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Effetto erba" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Foschia calore" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Fumo su ruote e altro" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Ombre dinamiche dei pedoni" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Sfuocatura di movimento" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Riflessi pioggia" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Minimizza schermo intero" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Abilità la finestra di selezione del dispositivo" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Mostra risoluzioni non sicure" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Rendi i veicoli sempre in dettaglio" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Rendi i pedoni sempre in dettaglio" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Abilita siti Web remoti" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Abilita Javascript su siti Web remoti" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Lista nera personalizzata" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Inserisci un dominio, ad es. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Bloccare" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Dominio" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Rimuovi dominio" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Lista bianca personalizzata" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Permetti" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Varie" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Caricamento rapido dei vestiti di CJ:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Velocità del browser:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Connesione Singola:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Etichetta del pacchetto:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Progresso dell'animazione:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Priorità di processo:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Impostazioni di debug:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Trasmissione memoria:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Metodo di aggiornamento:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Installa aggiornamenti importanti:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Attivo" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Molto Lenta" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Predefinita" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Veloce" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normale" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Superiore al normale" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Minimo" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Massimo" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 compatibile:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "Colore a 16 bit" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Correzione del mouse" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "File di risorse del cliente:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Mostra in Explorer" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Aggiornamento automatico" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Controllo aggiornamenti" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Alcune impostazioni verranno modificate al prossimo avvio di MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Vuoi riavviare ora?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "RIAVVIO RICHIESTO" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Alcune impostazioni verranno modificate dopo la disconnessione dal server corrente" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Vuoi disconnetterti ora?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "DISCONNESSIONE RICHIESTA" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad non rilevato - Controlla la connessione e riavvia il gioco" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Associazione assi" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Muovi un asse per associarlo, oppure ESC per annullare" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Lingua:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Tema:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Preimpostazioni:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Chat" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Carica" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Colori" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Layout" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Opzioni" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Sfondo chat" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Testo chat" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Sfondo di input" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Testo input" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Linee:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Scala:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Larghezza:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Dimensione" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "dopo" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "per" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "secondi" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Dissolvenza" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Dissolvi linee vecchie " -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Orizzontale:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Verticale:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Allinea testo:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "Scostamento X:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Scostamento Y:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Posizione" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Sinistra" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Al centro" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Destra" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Superiore" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Basso" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Font" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Nascondi lo sfondo mentre non si scrive " -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Completamento del nickname con il tasto \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Consenti al server di far lampeggiare la finestra" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Permetti notifiche a fumetto" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Contorno bianco/nero del testo della chat" @@ -1548,89 +1832,95 @@ msgstr "Contorno bianco/nero del testo della chat" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Premi un tasto per associarlo, oppure ESC per annullare" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Associazione tasto primario" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Associare un tasto secondario" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "CONTROLLI GIOCO DI GTA" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "CONTROLLI MULTIPLAYER" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Il tuo nickname contiene caratteri non validi!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Rosso:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Verde:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Blu:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Trasparenza:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Colore" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Anteprima" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Si prega di disconnettersi prima di cambiare lingua" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Per favore disconnettiti prima di cambiare skin" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Le ombre volumetriche possono causare il rallentamento del sistema.\n\n" "Sei sicuro di volerle attivare?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "PROBLEMA DI PERFORMANCE " -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "L'upload dello schermo è richiesto da alcuni server per ragioni anti-cheat.\n\n" "(Chat Box e GUI sono eslcusi dall'upload)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "INFORMAZIONI UPLOAD SCHERMO" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1638,21 +1928,21 @@ msgstr "Alcuni script possono riprodurre suoni, come la radio, da Internet.\n\n" "La disabilitazione di questa impostazione potrebbe ridurre la rete\n" "consumo di banda.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "SUONI ESTERNI" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1662,11 +1952,7 @@ msgstr "Alcuni file nella tua cartella di GTA:SA sono personalizzati.\n" "Tuttavia, I FILE PERSONALIZZATI DI GTA:SA SONO BLOCCATI IN MOLTI SERVER\n\n" "Sei sicuro di volerli utilizzare?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "FILE PERSONALIZZATI DI GTA:SA" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1676,550 +1962,252 @@ msgstr "L'abilitazione del riconoscimento DPI è una funzionalità sperimentale "Potresti riscontrare problemi grafici se abiliti questa opzione.\n\n" "Sei sicuro di voler abilitare questa opzione?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "FUNZIONE SPERIMENTALE" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Per favore inserisci un nickname" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Per favore inserisci un nickname da usare in gioco.\n" "Questo sarà il tuo nome quando ti connetterai e giocherai in un server" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Caratteristica molto sperimentale" -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Ferma gli stalli durante le variazioni di CJ (Utilizza 65Mb di RAM aggiuntivi)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "I router più vecchi potrebbero richiedere un'inferiore velocità di scansione." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Imposta su on per utilizzare solamente una connessione durante i downlaod." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Contrassegna i pacchetti di rete per aiutare gli ISP a identificare il traffico MTA." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Animazione del cerchio rotante nella parte inferiore dello schermo" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Seleziona sempre predefinito. (Questo settaggio non è salvato)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Il massimo è normalmente migliore" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Aggiornamenti automatici:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Seleziona di defalut, a meno che non ti piaccia compilare la segnalazione dei bug." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Seleziona predefinito per installare automaticamente gli aggiornamenti importanti." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "Colore a 16 bit:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Abilita modalità colore a 16 bit - Richiede il riavvio di MTA" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Correzione del mouse:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Correzione del movimento del mouse: potrebbe essere necessario riavviare il PC" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Comando o cvar sconosciuto" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Occupato" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Impossibile controllare gli aggiornamenti in questo momento" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s richiesto" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Una versione aggiornata di MTA:SA %s è richiesta per entrare nel server selezionato.\n\n" -"Vuoi scaricare ed installare MTA:SA %s?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Vuoi avviare MTA:SA %s e connetterti a questo server?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Non è possibile connettersi in questo momento.\n\n" -"Per favore prova più tardi." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Connessione in corso" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Attendere prego..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "CONTROLLO" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "CONTROLLO AGGIORNAMENTI" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Nessun aggiornamento necessario" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "IN DOWNLOAD" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "in attesa...." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "AGGIORNAMENTO OBBLIGATORIO" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Per entrare in questo server devi aggiornare MTA.\n\n" -"Vuoi aggiornare ora?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "AGGIORNAMENTO OPZIONALE" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Il server raccomanda un aggiornamento anche se non essenziale.\n\n" -"Vuoi aggiornare ora?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "ERRORE DI SALVATAGGIO" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Impossibile creare il file." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "ERRORE DI DOWNLOAD" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "I file di download sembrano incorretti." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Per qualche motivo." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "DOWNLOAD COMPLETO" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "-Problema sconosciuto in _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ok" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "ERRORE" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Alcuni file dati di MTA:SA sono mancanti.\n\n\n" -"Per favore reinstalla MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% completato" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"In attesa di risposta - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Connessione fallita. Fornito nick non valido!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Connessione fallita. Fornito host non valido!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Connessione a %s con porta %u fallita!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Connessione a %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "CONNESSIONE" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Connessione scaduta" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Disconnesso: protocollo d'errore sconosciuto" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Disconnesso: disconnesso remotamente " - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Disconnesso: connessione persa remotamente " - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Disconnesso: sei stato bannato da questo server" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Disconnesso: disconnesso dal server" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Disconnesso: la connessione al server è stata perduta" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Disconnesso: la connessione è stata rifiutata" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Questa mod non è installata (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Cattiva risposta del server (2) " - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Cattiva risposta del server (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "NOTIZIE" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Visita le ultime notizie" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "CONSOLE " - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Errore fatale" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "Per risolvere, elimina questo file:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "Il modulo %s non è corretto!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Errore durante l'esecuzione dell'URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "questa schermata d'aiuto" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "esci dall'applicazione" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "mostra la versione" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "mostra l'ora" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "mostra l'hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "mostra tutte le associazioni" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "mostra il tuo seriale" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "connette a un server (host porta nome password)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "connette a un server precedente" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "associa un tasto (controllo tasto)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "dissocia un tasto (tasto)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "copia i controlli originali di gta" -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "emettere uno screenshot" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "salva la configurazione immediatamente" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "pulisce la visuale di debug" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "scorre la chatbox verso l'alto" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "scorre la chatbox verso il basso" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "scorre la visuale di debug verso l'alto" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "scorre la visuale di debug verso il basso" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "mostra le statistiche di memoria" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "mostra il grafico dei frame" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "Per gli sviluppatori: ricarica le notizie" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ AIUTO COMANDO ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Sono le ore %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "connessione: Sintassi 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "connessione: Numero porta errata" +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "emettere uno screenshot" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "connessione: Connessione a %s:%u..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "salva la configurazione immediatamente" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "connessione: impossibile connettersi a %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "pulisce la visuale di debug" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "connessione: Impossibile fermare la mod corrente" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "scorre la chatbox verso l'alto" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "scorre la chatbox verso il basso" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "scorre la visuale di debug verso l'alto" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "scorre la visuale di debug verso il basso" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "mostra le statistiche di memoria" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Associa tutti i controlli da GTA" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "mostra il grafico dei frame" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "File di configurazione salvato" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "Per gli sviluppatori: ricarica le notizie" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Il tuo numero seriale è: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Stai utilizzando una build di rami di funzionalità! Questa è solo una build di prova che non può essere utilizzata per connettersi a server pubblici!" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Accelera asse" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA non riceverà più aggiornamenti per XP/Vista dopo Luglio 2019.\n\n" +"Aggiornate Windows per continuare a giocare aggiornati." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Rallenta asse" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Questo ti disconnetterà dal server corrente.\n\n" +"Sei sicuro di volerti disconnettere?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programmazione" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "AVVERTIMENTO DI DISCONNESSIONE" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Collaboratori" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Progettazione / Scripting" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "NOTIZIE" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "localizzazione lingua" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Visita le ultime notizie" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Collaboratori per le patch" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Lo screenshot ha ottenuto %d bytes, ma ne aspettava %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Ringraziamenti particolari" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Screenshot fallito" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Questo software e progetto fa uso delle seguenti librerie e software:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Screenshot catturato: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Vuoi controllare il supporto in linea riguardo a questo problema?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Comando o cvar sconosciuto" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2394,25 +2382,56 @@ msgid "Group control backwards" msgstr "Controlli di gruppo (ritirarsi)" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "La skin che hai selezionato e la skin di defalut non possono essere caricate, per favore reinstalla MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Lo screenshot ha ottenuto %d bytes, ma ne aspettava %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Vuoi controllare il supporto in linea riguardo a questo problema?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Screenshot fallito" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "CONSOLE " -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Screenshot catturato: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programmazione" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Collaboratori" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Progettazione / Scripting" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "localizzazione lingua" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Collaboratori per le patch" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Ringraziamenti particolari" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Questo software e progetto fa uso delle seguenti librerie e software:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Accelera asse" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Rallenta asse" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2420,6 +2439,61 @@ msgstr "Impossibile inizializzare Direct3D9.\n\n" "Per favore assicurati che le DirectX End-User Runtime e\n" "il più recente Service Pack di Windows siano installati correttamente." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Inattivo" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "Giocatore" +msgstr[1] "Giocatori" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "in" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "Server" +msgstr[1] "Servers" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Richiedendo la lista del master server (%lu ms elapsed)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Impossibile analizzare la lista del master server." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Impossibile recuperare la lista del master server." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Recupero della lista dei server)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Impossibile associare un LAN-Broadcast socket" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Tentativo di ricercare i server LAN" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2473,7 +2547,7 @@ msgstr "Latenza:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Elenco dei giocatori" @@ -2500,40 +2574,39 @@ msgstr "Partecipa alla partita appena un posto diventa disponibile." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "PER FAVORE IMMETTI LA PASSWORD DEL SERVER" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Scaduto" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Interrogazione in corso..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "Sfoglia i server" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Locali" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Preferiti" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Recenti" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2541,298 +2614,367 @@ msgstr "PER CONNETTERSI RAPIDAMENTE :\n\n" "Scrivi indirizzo e porta direttamente nella barra degli indirizzi.\n" "Oppure seleziona un server dalla cronologia e premi 'Connettiti'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "AIUTO" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Aggiorna" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Aggiungi ai preferiti" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Connettiti" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Informazioni Server" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Cerca server" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Cerca giocatori" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Inizia ricerca" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Ricerca giocatori..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Ricerca server..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Nome" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Giocatori" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Latenza" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Modalità" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Includi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Vuoti" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Pieni" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Bloccati" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Non in linea" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Altre Versioni" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Indietro" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Caricamento..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "..caricamento.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Nessun indirizzo specificato!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Protocollo sconosciuto!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Per favore usa il protocollo mtasa://" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Nickname non valido! Per favore vai nelle impostazioni e scegline un'altro." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Hai selezionato un server alla quale connetterti." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Inattivo" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problemi con il driver grafico" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "Giocatore" -msgstr[1] "Giocatori" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Impossibile trovare una risoluzione dello schermo valida." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "in" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Sei sicuro di voler utilizzare questa risoluzione dello schermo?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "Server" -msgstr[1] "Servers" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Richiedendo la lista del master server (%lu ms elapsed)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Impossibile analizzare la lista del master server." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Richieste del sito web" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Impossibile recuperare la lista del master server." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Il server richiede i seguenti siti Web per caricarli (in seguito):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Recupero della lista dei server)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NON INSERIRE MAI DATI SENSIBILI PER EVITARE CHE VENGANO RUBATI" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Impossibile associare un LAN-Broadcast socket" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Salva la decisione" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Tentativo di ricercare i server LAN" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Rifiuta" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Questa versione è scaduta." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "disconnettiti dalla partita" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "mostra i tag dei nomi" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "mostra la chatbox" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "mostra le statistiche della rete" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "apre la chat" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "trasmette la voce ad altri giocatori" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "entra in un'auto come passeggero" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "stazione radio successiva" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "stazione radio precedente" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "invia un messaggio al giocatore sotto mira" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "cambia l'arma mentre si è alla guida" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "Cambia arma mentre guidi con la precedente" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "info output del server corrente" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "definisce la scala di tutti i testi sul display" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(modalità sviluppo) mostra le colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(modalità sviluppo) immette i suoni del mondo nella finestra di debug" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "OSPITA PARTITA" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Risorse" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Nome del server:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Password:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "N. massimo di giocatori:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Trasmissione:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Selezionato" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Tutti" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Inizia" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Avanzamento Download Mappa:" @@ -2853,195 +2995,195 @@ msgstr "%s su %s" msgid "Disconnect to cancel download" msgstr "Disconnettiti per annullare il download" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Disconnesso: Nickname non valido" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Disconnesso dal server" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Disconnesso: Il seriale è bannato.\n" "Ragione: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Disconnesso: Sei stato bannato.\n" "Ragione: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Disconnesso: Account bannato.\n" "Ragione: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Disconnesso: Versione non corrispondente" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Disconnesso: Flood di ingresso. Per favore aspetta un minuto, quindi riprova." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Disconnesso: Server di ramo differente.\n" "Informazioni: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Disconnesso: Versione errata.\n" "Informazioni: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Disconnesso: Il server sta utilizzando una nuova versione.\n" "Informazioni: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Disconnesso: Il server sta utilizzando una vecchia versione.\n" "Informazioni: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Disconnesso: Nickname già in uso" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Disconnessione: Impossibile creare l'elemento del giocatore." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Disconnesso: Il server ha rifiutato la connessione: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Disconnesso: Verifica del seriale fallita" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Disconnesso: desync connessione %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Disconnesso: Sei stato espulso da %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Disconnesso: Sei stato bannato da %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Disconnessione: Il server è stato chiuso o si sta riavviando" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Sei stato espulso dalla partita" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Questo server richiede gta_sa.exe non modificato" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Sostituire gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Questo server non accetta file D3D9.DLL modificati" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Rimuovere D3D9.DLL dalla cartella di installazione di GTA e riavviare MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Questo server non accetta macchine virtuali" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Questo server richiede la certificazione dei driver abilitata" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Per favore riavvia il PC" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Questo server ha rilevato componenti anti-cheat mancanti" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Prova a riavviare MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Questo server richiede gta3.img e gta_int.img non modificati" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Per favore sostituisci gta3.img o gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Questo server non accetta Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Assicurarsi che nessun programma stia modificando MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Tempo Rimanente:" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d giorno" msgstr[1] "%d giorni" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d ora" msgstr[1] "%d ore" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d minuto" msgstr[1] "%d minuti" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3049,296 +3191,206 @@ msgstr[0] "%d secondi" msgstr[1] "%d secondi" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Disconnesso" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Errore di download: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Entrando nel gioco..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Non connesso; per favore usa la connessione rapida o il comando 'connettiti' per connetterti ad un server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Impossibile avviare il server locale. Consultare la console per i dettagli." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Server Locale" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Avvio del server locale..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Sei stato espulso dalla partita (%s)" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Connessione al server locale..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Errore durante la connessione al server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Connessione al server locale scaduta. Consultare la console per i dettagli." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "La connessione col server è stata persa" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Disconnesso: il server attualmente è pieno" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Disconnesso: password specificata invalida" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "Verifica del Client MTA fallita!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "OSPITA PARTITA" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Risorse" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Nome del server:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Password:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "N. massimo di giocatori:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Trasmissione:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Selezionato" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Tutti" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Inizia" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problemi con il driver grafico" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Impossibile trovare una risoluzione dello schermo valida." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Sei sicuro di voler utilizzare questa risoluzione dello schermo?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Errore di download: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3359,11 +3411,11 @@ msgstr "" msgid "Connection error" msgstr "Errore di connessione" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto non è stato installato correttamente, per favore ripeti l'installazione." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Il tuo browser ora visualizzerà una pagina web con alcune informazioni utili.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/ja_JP/client.pot b/Shared/data/MTA San Andreas/MTA/locale/ja_JP/client.pot index 9a7453bf952..5623740b068 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/ja_JP/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/ja_JP/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Japanese\n" "Language: ja_JP\n" @@ -17,72 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "MTA:SAå†å®Ÿè¡Œå¤±æ•—\n\n" -"ã“ã®å•題ãŒç¶šã„ãŸã‚‰ã€ã‚¿ã‚¹ã‚¯ãƒžãƒã‚¸ãƒ£ãƒ¼ã‚’é–‹ã‘ã¦\n" -"「gta_sa.exeã€ã¨ã€ŒMulti Theft Auto.exeã€ã®ãƒ—ãƒ­ã‚»ã‚¹ã‚’åœæ­¢ã—ã¦ãã ã•ã„\n\n\n" -"å†èµ·å‹•ã—ã¾ã™ã‹ï¼Ÿ" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Grand Theft Auto: San Andreas ã‚’èµ·å‹•ã—ã¦ãã ã•ã„。\n" +"ゲームãŒã€ŒProgram Files (x86)ã€ãƒ•ォルダã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "エラー" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "Grand Theft Auto: San Andreas を探ã—ã¦ã„ã¾ã™" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "ä»–ã®MTAインスタンスãŒå®Ÿè¡Œã—ã¦ã„ã¾ã™ã€‚\n\n" -"ã“ã®å•題ãŒç¶šã„ãŸã‚‰ã€ãƒ‘ソコンをå†èµ·å‹•ã—ã¦ãã ã•ã„" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "申ã—訳ã‚りã¾ã›ã‚“ã€ã‚²ãƒ¼ãƒ ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" +"Grand Theft Auto: San Andreas ã‚’èµ·å‹•ã—ã¦ã‹ã‚‰ã€å†è©¦è¡Œã—ã¦ãã ã•ã„。\n" +"ゲームãŒã€ŒProgram Files (x86)ã€ãƒ•ォルダã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "ä»–ã®MTAインスタンスãŒå®Ÿè¡Œã—ã¦ã„ã¾ã™ã€‚\n\n" -"終了ã—ã¾ã™ã‹ï¼Ÿ" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "GTA:San Andreasã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ‘スをé¸ã‚“ã§ãã ã•ã„" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "下記ã®ã‚¿ã‚¹ã‚¯ã‚’を完æˆã™ã‚‹ãŸã‚ã«ã€ç®¡ç†è€…アクセスãŒå¿…è¦ã§ã™\n\n" +" '%s'\n\n" +"次ã®ã‚¦ã‚¤ãƒ³ãƒ‰ã‚¦ã§ç¢ºèªã—ã¦ãã ã•ã„。" + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "%s モジュールã®èª­ã¿è¾¼ã¿ãŒå¤±æ•—ã—ã¾ã—㟠(%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "ファイルコピー中。。。" + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "ファイルコピーãŒå®Œæˆã—ã¾ã—ãŸã€‚å…¨ã¦ã¯OKã§ã™ã€‚" + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "終了。。。" + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "完了ã§ã™!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "%s ã®æœ€æ–°ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚’検出ã•れã¾ã—ãŸã€‚\n\n" +"%s ã‹ã‚‰è¨­å®šã‚’コピーã—ã¾ã™ã‹ï¼Ÿ" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA㯠'%s' ファイル読ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA㌠'%s' ファイルãŒä¸è¶³ã—ã¦ã„ã¾ã™ã€‚" + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SAã¯ãƒ¢ãƒ‡ãƒ«ã‚’読ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸã€‚" + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "最近「gta3.imgã€ã‚’変更ã—ãŸå ´åˆã¯ã€GTA:SAã‚’å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ã¿ã¦ãã ã•ã„。" + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SAãŒè»Šã®ã‚¢ãƒƒãƒ—グレードã«å¤±æ•—ã—ã¾ã—ãŸã€‚" + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SAã¯ã€Œ%sã€ãƒ•ァイルã«ã‚¨ãƒ©ãƒ¼ã‚’発見ã—ã¾ã—ãŸ" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "MTA:SAをプレイ中ã«ãƒ‘ソコンをå†èµ·å‹•ã—ã¾ã—ãŸã‹ï¼Ÿ" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "ç¶šã‘ã‚‹å‰ã«ã€æ¬¡ã®ãƒ—ログラムを閉ã˜ã¦ãã ã•ã„:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "ファイルãƒãƒ¼ã‚¸ãƒ§ãƒ³ãƒŸã‚¹ãƒžãƒƒãƒã‚¨ãƒ©ãƒ¼ã€‚MTA:SAã¨å•題ãŒã‚ã£ãŸã‚‰ã€å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "ファイルä¸è¶³ã€‚å•題ãŒã‚ã£ãŸã‚‰ã€MTA:SAã‚’å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚’ã—ã¦ãã ã•ã„。\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SAã¯ã€Œã‚»ãƒ¼ãƒ•モードã€ã§å®Ÿè¡Œã§ãã¾ã›ã‚“。\n\n" +"パソコンをå†èµ·å‹•ã—ã¦ãã ã•ã„。\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "MTA:SA実行å•題ãŒã‚りã¾ã™ã‹ï¼Ÿ\n\n" "以å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«æˆ»ã—ã¾ã™ã‹ï¼Ÿ" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +143,48 @@ msgstr "MTA:SA実行å•題ãŒã‚ã‚‹ãã†ã§ã™ã€‚\n" "GTAã®è¨­å®šã‚’リセットã™ã‚‹ã¨ã€å•題ãŒä¿®æ­£ã•れるã‹ã‚‚ã—れã¾ã›ã‚“。\n\n" "GTAã®è¨­å®šã‚’リセットã—ã¾ã™ã‹ï¼Ÿ" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA設定ãŒãƒªã‚»ãƒƒãƒˆã•れã¾ã—ãŸã€‚\n\n" "ç¶šã‘ã‚‹ã«ã€ŒOKã€ã‚’押ã—ã¦ãã ã•ã„。" -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "次ã®ãƒ•ァイルを消ã™ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸï¼š %s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "MTA:SA実行å•題ãŒã‚りã¾ã™ã‹ã€‚\n\n" "オンラインã§ãƒ˜ãƒ«ãƒ—を調ã¹ã¾ã™ã‹ï¼Ÿ" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "MTA:SA実行å•題ãŒã‚りã¾ã‹ï¼Ÿ\n\n" "次ã®è¨­å®šã‚’変更ã—ãŸã„ã§ã™ã‹ï¼Ÿ" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "フルスクリーンモード:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "ボーダーãªã—ウィンドウ" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "MTA:SA実行å•題ã‚りã¾ã™ã‹ï¼Ÿ\n\n" "次ã®ã‚½ãƒ•トを無効ã—ã¦ã¿ã¦ãã ã•ã„:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,131 +192,293 @@ msgstr "警告\n\n" "MTA:SAã¯çã—ã„æ´»å‹•ãŒæ¤œå‡ºã•れã¾ã—ãŸã€‚\n" "システム安全ã®ãŸã‚ã«ã€ã‚¦ã‚¤ãƒ«ã‚¹ã‚¹ã‚­ãƒ£ãƒ³ã‚’ã—ã¦ãã ã•ã„。\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "検出ã•れãŸãƒ•ァイルã¯ï¼š %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "GTA: San Andreasã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã¯ã¾ã å®Ÿè¡Œã—ã¦ã„ã¾ã™ã€‚実行ã™ã‚‹å‰ã«çµ‚了ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。ãã†ã—ã¾ã™ã‹ï¼Ÿ" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "情報" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "GTA: San Andreasã‚’åœæ­¢ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®å•題ãŒç¶šã„ãŸã‚‰ã€ãƒ‘ソコンをå†èµ·å‹•ã—ã¦ãã ã•ã„。" -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "MTA:SAå†å®Ÿè¡Œå¤±æ•—\n\n" +"ã“ã®å•題ãŒç¶šã„ãŸã‚‰ã€ã‚¿ã‚¹ã‚¯ãƒžãƒã‚¸ãƒ£ãƒ¼ã‚’é–‹ã‘ã¦\n" +"「gta_sa.exeã€ã¨ã€ŒMulti Theft Auto.exeã€ã®ãƒ—ãƒ­ã‚»ã‚¹ã‚’åœæ­¢ã—ã¦ãã ã•ã„\n\n\n" +"å†èµ·å‹•ã—ã¾ã™ã‹ï¼Ÿ" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "エラー" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "ä»–ã®MTAインスタンスãŒå®Ÿè¡Œã—ã¦ã„ã¾ã™ã€‚\n\n" +"ã“ã®å•題ãŒç¶šã„ãŸã‚‰ã€ãƒ‘ソコンをå†èµ·å‹•ã—ã¦ãã ã•ã„" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "ä»–ã®MTAインスタンスãŒå®Ÿè¡Œã—ã¦ã„ã¾ã™ã€‚\n\n" +"終了ã—ã¾ã™ã‹ï¼Ÿ" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "レジストリエントリãŒãªã„ã§ã™ã€‚MTA:SAã‚’å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。" -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "GTA: San Andreas ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ‘ã‚¹ã®æ–‡å­—ãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“(ユニコード)。Grand Theft Auto: San Andreas ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ•ォルダをASCIIã®ã¿ã«ã‚るパスã«ç§»å‹•ã—ã¦ã€Multi Theft Auto: San Andreas ã‚’å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。" -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "「MTA:SAã€ã‚„「GTA:SAã€ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ‘スã«ã€Œï¼›ã€ãŒå«ã‚“ã§ã„ã¾ã™ã€‚\n\n" -" å•題ãŒã‚ã£ãŸã‚‰ã€\n" -" インストールフォルダを「;ã€ã®ãªã„パスã«ç§»å‹•ã—ã¦ãã ã•ã„。" +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:810 +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "読ã¿è¾¼ã¿å¤±æ•—。最新データファイルãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ã„ã‚‹ã®ã‚’確èªã—ã¦ä¸‹ã•ã„。" -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "読ã¿è¾¼ã¿å¤±æ•—。%s ãŒæ­£ã—ãã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れãŸã®ã‚’確èªã—ã¦ä¸‹ã•ã„。" -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "読ã¿è¾¼ã¿å¤±æ•—。gta_sa.exe 㯠%s ã«è¦‹ã¤ã‹ã‚Œã¾ã›ã‚“ã§ã—ãŸ" -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "読ã¿è¾¼ã¿å¤±æ•—。%s ã¯GTAインストールフォルダã«å­˜åœ¨ã—ã¦ã„ã¾ã™ã€‚ç¶šãå‰ã«ã€ã“ã®ãƒ•ァイルを消ã—ã¦ãŠã„ã¦ãã ã•ã„。" -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "メインファイルã¯ç„¡åйãªåå‰ã§ã‚ã‚‹ (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "メインファイルãŒç½²åã•れã¦ã„ã¾ã›ã‚“ã€‚ã‚¦ã‚¤ãƒ«ã‚¹ã®æ´»å‹•ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。\n\n" -"MTAã«ãªã«ã‹ã€çã—ã„ã“ã¨ã€ã¾ãŸã¯å®Ÿè¡Œã—ã¦ã„ãªã„å ´åˆã¯ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã§æ¤œç´¢ã—ã¦ãã ã•ã„。" - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "ファイル %s ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã€‚ã‚¦ã‚¤ãƒ«ã‚¹ã®æ´»å‹•ãŒåŽŸå› ã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚\n\n" -"セキュリティã®ãŸã‚ã€Multi Theft Auto ã®å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚’検討ã—ã¦ãã ã•ã„。\n" -"MTAãŒæ­£ã—ã動作ã—ãªã„å ´åˆã¯ã€ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ãƒ˜ãƒ«ãƒ—ã‚’å‚ç…§ã—ã¦ãã ã•ã„。" - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "ファイル %s ãŒæ”¹ç«„ã•れã¦ã„ã¾ã™ã€‚ã‚¦ã‚¤ãƒ«ã‚¹ã®æ´»å‹•ãŒåŽŸå› ã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚\n\n" -"セキュリティã®ãŸã‚ã€Multi Theft Auto ã®å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚’検討ã—ã¦ãã ã•ã„。\n" -"MTAãŒæ­£ã—ã動作ã—ãªã„å ´åˆã¯ã€ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ãƒ˜ãƒ«ãƒ—ã‚’å‚ç…§ã—ã¦ãã ã•ã„。" - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asiファイルã¯ã€ŒMTA:SAã€ã‚„「GTA:SAã€ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ‘ã‚¹ã«æ¤œå‡ºã•れã¾ã—ãŸã€‚\n\n" -"MTAã¨å•題ãŒã‚ã£ãŸã‚‰ã€ã“ã®ãƒ•ァイルを消ã—ã¦ãã ã•ã„。" - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "ファイルãƒãƒ¼ã‚¸ãƒ§ãƒ³ãƒŸã‚¹ãƒžãƒƒãƒã‚¨ãƒ©ãƒ¼ã€‚MTA:SAã¨å•題ãŒã‚ã£ãŸã‚‰ã€å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "ファイルä¸è¶³ã€‚å•題ãŒã‚ã£ãŸã‚‰ã€MTA:SAã‚’å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚’ã—ã¦ãã ã•ã„。\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SAã¯ã€Œã‚»ãƒ¼ãƒ•モードã€ã§å®Ÿè¡Œã§ãã¾ã›ã‚“。\n\n" -"パソコンをå†èµ·å‹•ã—ã¦ãã ã•ã„。\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "設定å•題を修正ã™ã‚‹" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "アドミンå•題を修正ã™ã‚‹" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "䏿˜Ž" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "ファイル '%s' ã¯ç¾åœ¨ %zu 個ã®ãƒ—ロセスã«ã‚ˆã£ã¦ãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã™ã€‚\n\n" +"以下ã®ãƒ—ロセスを終了ã—ã¦ã‚¢ãƒƒãƒ—デートを続行ã—ã¾ã™ã‹ï¼Ÿ\n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "インストールãŒç ´æã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚\n\n" +"%zu 個中 %zu 個ã®ãƒ•ァイルãŒãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã‹ã‚‰å¾©å…ƒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n\n" +"www.multitheftauto.com ã‹ã‚‰Multi Theft Autoã‚’å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã‹\n" +"管ç†è€…権é™ã§ã‚¢ãƒƒãƒ—デートを試ã—ã¦ã¿ã¦ãã ã•ã„。" + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "アップデートインストール中。。。" + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "ファイルを抽出中。。。" + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SAã¯ä¸‹è¨˜ã®ã‚¿ã‚¹ã‚¯ã‚’完æˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "**グラフィックドライãƒã®å½±éŸ¿ã§ã‚²ãƒ¼ãƒ ãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã—ã¾ã—ãŸï¼Šï¼Š\n\n" +"**グラフィックドライãƒã‚’アップデートã—ã¦ãã ã•ã„**" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "アプデートã—ãŸMTA:SAファイルをインストールã™ã‚‹" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "ä»–ã®ãƒ—ログラムã®å½±éŸ¿ã§ã‚¢ãƒ—デートã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ä»–ã®ãƒ—ログラムを閉ã˜ã¦ã€ã‚‚ã†ä¸€å›žè©¦ã—ã¦ã¿ã¦ãã ã•ã„" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "MTAã¯å®Œå…¨ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。 %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "GTA:SA ジャンクションを作る" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "ファイルをコピーã™ã‚‹ã“ã¨ãŒã§ããªã„ãŸã‚ã€MTAãŒå®Ÿè¡Œã§ãã¾ã›ã‚“:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SAã®ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ­£ã—ããªã„ã¾ãŸã¯è¦‹ã¤ã‹ã‚‰ãªã„ãŸã‚ã€MTA:SAã‚’èµ·å‹•ã§ãã¾ã›ã‚“:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "MTASAファイルをコピーã™ã‚‹" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "GTA:SAã®ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ­£ã—ããªã„ã¾ãŸã¯è¦‹ã¤ã‹ã‚‰ãªã„ãŸã‚ã€MTA:SAã‚’èµ·å‹•ã§ãã¾ã›ã‚“:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "GTASAä¾å­˜é–¢ä¿‚ファイルをパッãƒã™ã‚‹" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "GTA:SAã®å®Ÿè¡Œãƒ•ァイルãŒä¸æ­£ã¾ãŸã¯è¦‹ã¤ã‹ã‚‰ãªã„ãŸã‚ã€MTA:SAã‚’èµ·å‹•ã§ãã¾ã›ã‚“:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "ãŸã¾ã«ã‚¢ãƒ³ãƒã‚¦ã‚¤ãƒ«ã‚¹ã¯èª¤æ¤œçŸ¥ã‚’検出ã™ã‚‹ãŸã‚ã€GTA:SA exeを例外を追加ã—ã¦ã€MTA:SA ã‚’å†èµ·å‹•ã—ã¦ãã ã•ã„。" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "GTASAを生æˆã™ã‚‹" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "GTA:SAã®å®Ÿè¡Œãƒ•ァイルãŒèª­ã¿è¾¼ã‚ãªã„ãŸã‚ã€MTA:SAã‚’èµ·å‹•ã§ãã¾ã›ã‚“:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "GTASAをパッãƒã™ã‚‹" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "GTASAã®ãƒ‘ッãƒãŒå¤±æ•—ã—ãŸãŸã‚ã€MTA:SAãŒå®Ÿè¡Œã§ãã¾ã›ã‚“:" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "GTA:San AndreasãŒå®Ÿè¡Œã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ å†èµ·å‹•ã—ã¦ãã ã•ã„。ã“ã®å•題ãŒç¶šã„ãŸã‚‰ã€MTAを「www.multitheftauto.com. ã€ã¾ã§ã«é€£çµ¡ã—ã¦ãã ã•ã„。 \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "%s ドライブスペースãŒä¸è¶³ã—ã¦ã„ã‚‹ãŸã‚ã€MTA:SAã¯ç¶šè¡Œã“ã¨ãŒã§ãã¾ã›ã‚“。" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA:San Andreas ãŒæ­£ã—ã実行ã—ãªã‹ã£ãŸã‹ã‚‚ã—れã¾ã›ã‚“。終了ã—ã¾ã™ã‹ï¼Ÿ" +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "ä¸è¶³ãƒ•ァイル:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "ã‚‚ã—MTAãŒãƒ­ãƒ¼ãƒ‰ã‚’失敗ã—ãŸã‚‰ã€GTA:SAã‚’å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚’ã—ã¦ãã ã•ã„" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "アップデートインストール設定" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "äº’æ›æ€§è¨­å®šã‚¢ãƒƒãƒ—デート" #. ///////////////////////////////////////////////////////////////////////// #. @@ -271,167 +486,167 @@ msgstr "GTA:San Andreas ãŒæ­£ã—ã実行ã—ãªã‹ã£ãŸã‹ã‚‚ã—れã¾ã›ã‚“ #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "ã¯ã„" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "ã„ã„ãˆ" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "OK" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "終了" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "ヘルプ" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "キャンセル" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreasã¯å•題ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "クラッシュ情報" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "MTAデベロッパーã«ã“ã®æƒ…報をé€ã‚‹ãŸã‚ã«ã€ã“ã®ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã«ãƒã‚§ãƒƒã‚¯ã—ã¦ãã ã•ã„" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "ã™ã‚‹ã¨ã€ã“ã®ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã‚’修正ã™ã‚‹å¯èƒ½æ€§ãŒé«˜ããªã‚Šã¾ã™ã€‚" -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "MTA: San Andreasã‚’å†èµ·å‹•ã—ã¾ã™ã‹ï¼Ÿ" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - 警告" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "Grand Theft Auto: San Andreas ãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れãŸãƒ•ォルダーã«ã¯ä»¥ä¸‹ã®ãƒ•ァイルãŒå«ã¾ã‚Œã¦ã„ã¾ã™ï¼š" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "ã“れらã®ãƒ•ァイルã¯ä¸è¦ã§ã‚りã€ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®MTA:SAã®ã‚°ãƒ©ãƒ•ィック機能ã«å¹²æ¸‰ã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚\n\n" "ã“れらã®ãƒ•ァイルを削除ã¾ãŸã¯åå‰å¤‰æ›´ã™ã‚‹ã“ã¨ã‚’推奨ã—ã¾ã™ã€‚" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "ã“ã®ä¸€è¦§ã®ãƒ•ァイルをä¿ç•™ã—ã€æ¬¡å›žã«èµ·å‹•ã™ã‚‹ã¨ãã‚‚åŒã˜è­¦å‘Šã‚’表示ã—ã¾ã™ã€‚" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "ã“ã®è­¦å‘Šã‚’ã“れã‹ã‚‰è¡¨ç¤ºã—ãªã„よã†ã«ã—ã¾ã™ã€‚" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "ã“れらã®ãƒ•ァイルåã‚’ *.dll ã‹ã‚‰ *.dll.bak ã«å¤‰æ›´ã—ã¾ã™ã€‚" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "一覧ã®ãƒ•ァイルをエクスプローラーã‹ã‚‰é–‹ãã¾ã™ã€‚" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "MTA:SAをプレイã™ã‚‹" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - 紛らã‚ã—ã„オプション" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus ãŒæ¤œå‡ºã•れã¾ã—ãŸï¼" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "オプションを試ã—ã¦ã¿ã¦ãã ã•ã„:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - NVIDIAスタンダード" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - 別ã®NVIDIA" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - 標準 Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - 代替 Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "çµ¶æœ›çš„ãªæ™‚ã«ã€ã“れãŒåŠ©ã‘ã¦ãれる:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "動作ã§ãるオプションをé¸ã‚“ã å ´åˆã¯ã€ã“れも助ã‹ã‚‹ã‹ã‚‚ã—れãªã„:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "ウィンドウモードを強制" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "二度ã¨è¡¨ç¤ºã—ãªã„" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "警告: アンãƒã‚¦ã‚¤ãƒ«ã‚¹ã‚½ãƒ•トãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -439,1110 +654,1181 @@ msgstr "MTAã¯ãƒ‘ソコンã«ã‚¢ãƒ³ãƒã‚¦ã‚¤ãƒ«ã‚¹ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã— "ウイルスã¯MTAã¨å¦¨å®³ã—ã€ã‚²ãƒ¼ãƒ çµŒé¨“を悪ãã™ã‚‹ã‚‚ã—れã¾ã›ã‚“。\n\n" "情報ã«é–¢ã—ã¦ã¯ã€Œãƒ˜ãƒ«ãƒ—ã€ã‚’クリックã—ã¦ãã ã•ã„。" -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "ç§ã¯ã‚‚ã†ã‚¢ãƒ³ãƒã‚¦ã‚¤ãƒ«ã‚¹ã‚’インストールã—ã¦ã„ã¾ã™" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "ç§ã€ã‚¢ãƒ³ãƒã‚¦ã‚¤ãƒ«ã‚¹ã‚’インストールã—ã¾ã›ã‚“。\n" "パソコンãŒé…ããªã£ã¦ã€ãƒœãƒƒãƒˆãƒãƒƒãƒˆã®ä¸€éƒ¨ã«ãªã£ã¦ãŒè‰¯ã„。" -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Grand Theft Auto San Andreas を探ã—ã¦ã„ã¾ã™" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Grand Theft Auto San Andreas をスタートã—ã¦ãã ã•ã„" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "アップデートインストール中。。。" +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "接続ã«å¤±æ•—ã—ã¾ã—ãŸã€‚無効ãªãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ ãŒè¨˜å…¥ã•れã¾ã—ãŸ!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "ファイルを抽出中。。。" +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "接続ã«å¤±æ•—ã—ã¾ã—ãŸã€‚無効ãªãƒ›ã‚¹ãƒˆãŒè¨˜å…¥ã•れã¾ã—ãŸ!!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "ファイルコピー中。。。" +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "%sã®%u ã®æŽ¥ç¶šãŒå¤±æ•—ã—ã¾ã—ãŸï¼" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "ファイルコピーãŒå®Œæˆã—ã¾ã—ãŸã€‚å…¨ã¦ã¯OKã§ã™ã€‚" +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "%s:%u ã«æŽ¥ç¶šä¸­ã€‚ã€‚ã€‚" -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "終了。。。" +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "%s:%u ã«å†æŽ¥ç¶šã—ã¦ã„ã¾ã™â€¦" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "完了ã§ã™!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "接続中" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "下記ã®ã‚¿ã‚¹ã‚¯ã‚’を完æˆã™ã‚‹ãŸã‚ã«ã€ç®¡ç†è€…アクセスãŒå¿…è¦ã§ã™\n\n" -" '%s'\n\n" -"次ã®ã‚¦ã‚¤ãƒ³ãƒ‰ã‚¦ã§ç¢ºèªã—ã¦ãã ã•ã„。" +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "接続ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SAã¯ä¸‹è¨˜ã®ã‚¿ã‚¹ã‚¯ã‚’完æˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "åˆ‡æ–­ï¼šä¸æ˜Žãªãƒ—ロトコルエラー" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "**グラフィックドライãƒã®å½±éŸ¿ã§ã‚²ãƒ¼ãƒ ãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã—ã¾ã—ãŸï¼Šï¼Š\n\n" -"**グラフィックドライãƒã‚’アップデートã—ã¦ãã ã•ã„**" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "接続切断:リモートã‹ã‚‰æŽ¥ç¶šãŒåˆ‡æ–­ã•れã¾ã—ãŸ" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "アプデートã—ãŸMTA:SAファイルをインストールã™ã‚‹" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "切断: ãƒªãƒ¢ãƒ¼ãƒˆã§æŽ¥ç¶šãŒå¤±ã‚れã¾ã—ãŸ" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "ä»–ã®ãƒ—ログラムã®å½±éŸ¿ã§ã‚¢ãƒ—デートã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ä»–ã®ãƒ—ログラムを閉ã˜ã¦ã€ã‚‚ã†ä¸€å›žè©¦ã—ã¦ã¿ã¦ãã ã•ã„" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "切断: ã‚ãªãŸã¯ã“ã®ã‚µãƒ¼ãƒãƒ¼ã‹ã‚‰ç¦æ­¢ã•れã¾ã—ãŸ" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "切断: サーãƒãƒ¼ã‹ã‚‰åˆ‡æ–­ã•れã¾ã—ãŸ" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "切断:サーãƒãƒ¼ã¨ã®æŽ¥ç¶šãŒå¤±ã‚れã¾ã—ãŸ" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "切断: æŽ¥ç¶šãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "MTAã¯å®Œå…¨ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。 %s" +msgid "No such mod installed (%s)" +msgstr "MODã¯ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ã„ã¾ã›ã‚“ (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "GTA:SA ジャンクションを作る" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "無効ãªã‚µãƒ¼ãƒãƒ¼ãƒ¬ã‚¹ãƒãƒ³ã‚¹ (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "ファイルをコピーã™ã‚‹ã“ã¨ãŒã§ããªã„ãŸã‚ã€MTAãŒå®Ÿè¡Œã§ãã¾ã›ã‚“:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "無効ãªã‚µãƒ¼ãƒãƒ¼è¿”ç­”ã§ã—㟠(1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SAã®ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ­£ã—ããªã„ã¾ãŸã¯è¦‹ã¤ã‹ã‚‰ãªã„ãŸã‚ã€MTA:SAã‚’èµ·å‹•ã§ãã¾ã›ã‚“:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "日本語" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "MTASAファイルをコピーã™ã‚‹" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "å¿™ã—ã„" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "GTA:SAã®ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ­£ã—ããªã„ã¾ãŸã¯è¦‹ã¤ã‹ã‚‰ãªã„ãŸã‚ã€MTA:SAã‚’èµ·å‹•ã§ãã¾ã›ã‚“:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "ç¾åœ¨ã€ã‚¢ãƒƒãƒ—デートãƒã‚§ãƒƒã‚¯ã¯å‡ºæ¥ã¾ã›ã‚“" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "GTASAä¾å­˜é–¢ä¿‚ファイルをパッãƒã™ã‚‹" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s ãŒå¿…è¦ã§ã™" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "GTA:SAã®å®Ÿè¡Œãƒ•ァイルãŒä¸æ­£ã¾ãŸã¯è¦‹ã¤ã‹ã‚‰ãªã„ãŸã‚ã€MTA:SAã‚’èµ·å‹•ã§ãã¾ã›ã‚“:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã«å‚加ã™ã‚‹ãŸã‚ã«ã€MTA:SA %s ã®æœ€æ–°ã‚¢ãƒƒãƒ—デートãŒå¿…è¦ã§ã™ã€‚\n\n" +"MTA:SA %s をダウンロードã—ã¦ã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¾ã™ã‹ï¼Ÿ" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "ãŸã¾ã«ã‚¢ãƒ³ãƒã‚¦ã‚¤ãƒ«ã‚¹ã¯èª¤æ¤œçŸ¥ã‚’検出ã™ã‚‹ãŸã‚ã€GTA:SA exeを例外を追加ã—ã¦ã€MTA:SA ã‚’å†èµ·å‹•ã—ã¦ãã ã•ã„。" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "MTA:SA %s を実行ã—ã¦ã€ã“ã®ã‚µãƒ¼ãƒãƒ¼ã«å‚加ã—ã¾ã™ã‹ï¼Ÿ" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "GTASAを生æˆã™ã‚‹" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "ç¾åœ¨ã€ã‚µãƒ¼ãƒãƒ¼ã«æŽ¥ç¶šã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。\n\n" +"後ã§ã€ã‚‚ã†ä¸€å›žè©¦ã—ã¦ã¿ã¦ãã ã•ã„。" + +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "接続中" + +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„。。。" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "GTA:SAã®å®Ÿè¡Œãƒ•ァイルãŒèª­ã¿è¾¼ã‚ãªã„ãŸã‚ã€MTA:SAã‚’èµ·å‹•ã§ãã¾ã›ã‚“:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "ãƒã‚§ãƒƒã‚¯ä¸­" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "GTASAをパッãƒã™ã‚‹" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "アップデートãƒã‚§ãƒƒã‚¯ä¸­" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "GTASAã®ãƒ‘ッãƒãŒå¤±æ•—ã—ãŸãŸã‚ã€MTA:SAãŒå®Ÿè¡Œã§ãã¾ã›ã‚“:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "アップデートã™ã‚‹å¿…è¦ã¯ã‚りã¾ã›ã‚“" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "%s ドライブスペースãŒä¸è¶³ã—ã¦ã„ã‚‹ãŸã‚ã€MTA:SAã¯ç¶šè¡Œã“ã¨ãŒã§ãã¾ã›ã‚“。" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "ダウンロード中" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "ä¸è¶³ãƒ•ァイル:" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "待機中..." -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "ã‚‚ã—MTAãŒãƒ­ãƒ¼ãƒ‰ã‚’失敗ã—ãŸã‚‰ã€GTA:SAã‚’å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚’ã—ã¦ãã ã•ã„" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "義務的ãªã‚¢ãƒƒãƒ—デート" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "アップデートインストール設定" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã«å‚加ã™ã‚‹ãŸã‚ã«ã€MTAをアップデートã™ã‚‹ã“ã¨ãŒå¿…è¦ã§ã™ã€‚\n\n" +"今ã«ã‚¢ãƒƒãƒ—デートã—ã¾ã™ã‹ã€‚" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "äº’æ›æ€§è¨­å®šã‚¢ãƒƒãƒ—デート" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "ä¸è¦ãªã‚¢ãƒƒãƒ—デート" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "䏿˜Ž" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "サーãƒãƒ¼ã¯ã‚¢ãƒƒãƒ—ãƒ‡ãƒ¼ãƒˆã¯æŽ¨å¥¨ã•れã¦ã„ã¾ã™ãŒã€ã‚¢ãƒƒãƒ—デート必è¦ã¯ã‚りã¾ã›ã‚“。\n\n" +"アップデートã—ã¾ã™ã‹ï¼Ÿ" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "ファイル '%s' ã¯ç¾åœ¨ %zu 個ã®ãƒ—ロセスã«ã‚ˆã£ã¦ãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã™ã€‚\n\n" -"以下ã®ãƒ—ロセスを終了ã—ã¦ã‚¢ãƒƒãƒ—デートを続行ã—ã¾ã™ã‹ï¼Ÿ\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "ç¾åœ¨ã€ã‚¢ãƒƒãƒ—デートã¯ã§ããªã„状態ã§ã™ã€‚\n\n" +"www.multitheftauto.com ã‚’ã”確èªãã ã•ã„" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "インストールãŒç ´æã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚\n\n" -"%zu 個中 %zu 個ã®ãƒ•ァイルãŒãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã‹ã‚‰å¾©å…ƒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n\n" -"www.multitheftauto.com ã‹ã‚‰Multi Theft Autoã‚’å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã‹\n" -"管ç†è€…権é™ã§ã‚¢ãƒƒãƒ—デートを試ã—ã¦ã¿ã¦ãã ã•ã„。" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "ä¿å­˜ã‚¨ãƒ©ãƒ¼" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Grand Theft Auto: San Andreas ã‚’èµ·å‹•ã—ã¦ãã ã•ã„。\n" -"ゲームãŒã€ŒProgram Files (x86)ã€ãƒ•ォルダã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "ファイルを作æˆã§ãã¾ã›ã‚“。" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "Grand Theft Auto: San Andreas を探ã—ã¦ã„ã¾ã™" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "ダウンロードエラー" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "申ã—訳ã‚りã¾ã›ã‚“ã€ã‚²ãƒ¼ãƒ ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" -"Grand Theft Auto: San Andreas ã‚’èµ·å‹•ã—ã¦ã‹ã‚‰ã€å†è©¦è¡Œã—ã¦ãã ã•ã„。\n" -"ゲームãŒã€ŒProgram Files (x86)ã€ãƒ•ォルダã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "ダウンロードã—ãŸãƒ•ァイルã¯ç„¡åйã®ã‚ˆã†ã§ã™ã€‚" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "GTA:San Andreasã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ‘スをé¸ã‚“ã§ãã ã•ã„" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "ãªã‚“ã¨ã‹ã€‚" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "%s モジュールã®èª­ã¿è¾¼ã¿ãŒå¤±æ•—ã—ã¾ã—㟠(%s)" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "ダウンロードæˆåŠŸ" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "%s ã®æœ€æ–°ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚’検出ã•れã¾ã—ãŸã€‚\n\n" -"%s ã‹ã‚‰è¨­å®šã‚’コピーã—ã¾ã™ã‹ï¼Ÿ" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr "- _DialogUpdateResult ã«ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼ " -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA㯠'%s' ファイル読ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ" +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "カスタムGTA:SAファイル" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA㌠'%s' ファイルãŒä¸è¶³ã—ã¦ã„ã¾ã™ã€‚" +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "OK" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SAã¯ãƒ¢ãƒ‡ãƒ«ã‚’読ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸã€‚" +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "エラー" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "最近「gta3.imgã€ã‚’変更ã—ãŸå ´åˆã¯ã€GTA:SAã‚’å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ã¿ã¦ãã ã•ã„。" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "MTA:SAファイルã®ä¸€éƒ¨ãŒä¸è¶³ã—ã¦ã„ã¾ã™ã€‚\n\n\n" +"MTA:SAã‚’å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SAãŒè»Šã®ã‚¢ãƒƒãƒ—グレードã«å¤±æ•—ã—ã¾ã—ãŸã€‚" +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% 完了" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2840 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SAã¯ã€Œ%sã€ãƒ•ァイルã«ã‚¨ãƒ©ãƒ¼ã‚’発見ã—ã¾ã—ãŸ" +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"返事を待ã£ã¦ã„ã¾ã™ - %-3d" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "MTA:SAをプレイ中ã«ãƒ‘ソコンをå†èµ·å‹•ã—ã¾ã—ãŸã‹ï¼Ÿ" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ コマンド ヘルプ ]***\n" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "ç¶šã‘ã‚‹å‰ã«ã€æ¬¡ã®ãƒ—ログラムを閉ã˜ã¦ãã ã•ã„:" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* 時間㯠%d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "ウェッブサイトリクエスト" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "接続:ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ãŒæº–å‚™ã§ãã¦ã„ã¾ã›ã‚“。ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "後ã«ãƒ­ãƒ¼ãƒ‰ã™ã‚‹ãŸã‚ã€ã‚µãƒ¼ãƒãƒ¼ã¯æ¬¡ã®ã‚¦ã‚§ãƒƒãƒ–サイトをリクエストã—ã¦ã„ã¾ã™ï¼š" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "接続:'connect <ホスト> [<ãƒãƒ¼ãƒˆ> <ニック> <パスワード>]'" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "ç›—ã¾ã‚‰ãªã„よã†ã«ã€å€‹äººæƒ…報を絶対書ã‹ãªã„ã§ãã ã•ã„" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "接続: 無効ãªãƒãƒ¼ãƒˆç•ªå·" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "決定をä¿å­˜ã™ã‚‹" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "接続: %s:%uã«æŽ¥ç¶šã—ã¦ã„ã‚‹..." -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "有効" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "接続: %s:%u ã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸï¼" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "å¦å®š" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "接続:ç¾åœ¨MODをアンロードã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "メインメニュー" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "å†æŽ¥ç¶šï¼šãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ãŒæº–å‚™ã§ãã¦ã„ã¾ã›ã‚“。ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "新機能ブランãƒã‚’利用ã—ã¦ã„ã¾ã™ï¼ã“れã¯ãƒ†ã‚¹ãƒˆãƒ“ルドã§ã‚ã‚‹ãŸã‚ã€å…¬å…±ã‚µãƒ¼ãƒãƒ¼ã«ã¯æŽ¥ç¶šã§ãã¾ã›ã‚“ï¼" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "å†æŽ¥ç¶šï¼šç„¡åŠ¹ãªãƒãƒ¼ãƒˆç•ªå·ã§ã™" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "ï¼’ï¼ï¼‘9年7月以æ¥ã€MTAã¯XP/Vistaã®ã‚¢ãƒƒãƒ—ãƒ‡ãƒ¼ãƒˆã‚’åœæ­¢ã—ã¾ã™ã€‚\n\n" -"æ–°ã—ã„サーãƒãƒ¼ã§ãƒ—レイã™ã‚‹ãŸã‚ã«Windowsをアップデートã—ã¦ãã ã•ã„。" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "å†æŽ¥ç¶šï¼š%s:%u ã«å†æŽ¥ç¶šä¸­â€¦" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "サーãƒãƒ¼ã‹ã‚‰åˆ‡æ–­ã•れるã“ã¨ã«ãªã‚Šã¾ã™ã€‚\n\n" -"サーãƒãƒ¼ã‹ã‚‰åˆ‡æ–­ã«ç¢ºã‹ã§ã™ã‹ï¼Ÿ" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "å†æŽ¥ç¶šï¼š%s:%u ã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸï¼" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "切断警告" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "å…¨ã¦ã®ãƒã‚¤ãƒ³ãƒ‰ã¯GTAã‹ã‚‰ã‚³ãƒ”ーã•れã¾ã—ãŸ" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "情報" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "ä¿å­˜ã—ãŸè¨­å®šãƒ•ァイル" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "日本語" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "*ã‚ãªãŸã®ã‚·ãƒªã‚¢ãƒ«ç•ªå·ã¯ï¼š %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "設定" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "ãƒãƒƒãƒˆã‚²ãƒ¼ãƒ " -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "ビデオ" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "サウンド" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "ãƒã‚¤ãƒ³ãƒ‰" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "コントロール" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "インターフェース" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "ウェブブラウザー" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "上級" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "デフォルトを読ã¿è¾¼ã‚€" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "マウス感度:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "åž‚ç›´ç‹™ã„æ„Ÿåº¦:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "マウスオプション" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "マウスを垂直ã«å転ã™ã‚‹" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "ãƒžã‚¦ã‚¹ã§æ“縦ã™ã‚‹" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "マウスã§é£›ã¶" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "ジョイパッドオプション" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "普通ã®ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ« (マウスã¨ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ï¼‰" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "クラシックコントロール (ジョイパッド)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "デッドゾーン" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "彩度" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "ジョイパッドボタンを設定ã™ã‚‹ãŸã‚ã«ã€Œãƒã‚¤ãƒ³ãƒ‰ã€ã‚’使ã£ã¦ãã ã•ã„。" -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "左スティック" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "å³ã‚¹ãƒ†ã‚£ãƒƒã‚¯" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "説明" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "キー" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "二次キー" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "ニックãƒãƒ¼ãƒ :" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "サーãƒãƒ¼ã®ãƒ‘スワードをä¿å­˜ã™ã‚‹" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "サーãƒãƒ¼ãƒ–ラウザを自動リフレッシュã™ã‚‹" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "スクリーンショットアップロードを有効ã™ã‚‹" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "外部音を許å¯ã™ã‚‹" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "ダウンロードウィンドウを表示ã™ã‚‹" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Discordリッãƒãƒ—レゼンスã¨ã®é€£æºã‚’許å¯ã™ã‚‹" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "ã‚«ãƒ¡ãƒ©ã§æ’®ã£ãŸå†™çœŸã‚’「GTA San Andreas User Filesã€ãƒ•ォルダーã«ä¿å­˜" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "メインメニューã‹ã‚‰ã‚µãƒ¼ãƒãƒ¼åˆ‡æ–­ã™ã‚‹å‰ã«ç¢ºèªã™ã‚‹" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "カスタムGTA:SAファイルを利用ã™ã‚‹" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "マップレンダリングオプション" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "ä¸é€æ˜Žåº¦:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "ç”»åƒè§£åƒåº¦ï¼š" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "1024 x 1024 (åˆæœŸå€¤)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "マスタ音é‡ï¼š" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "ラジオã®éŸ³é‡ï¼š" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "SFX音é‡ï¼š" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA音é‡ï¼š" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "声音é‡ï¼š" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "プレイモード:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "一般的ãªè¨­å®š" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "ラジオ設定" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "ラジオイコライザー" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "ラジオオートãƒãƒ¥ãƒ¼ãƒ³" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "ユーザートラックオプション" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "ラジオ" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "ランダム" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "順番ã«" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "自動メディアスキャン" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "ミュートオプションス" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "ウィンドウを隠ã™éš›ã€SFXã®éŸ³ã‚’ミュートã™ã‚‹" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "ウインドウを隠ã™éš›ã€ãƒ©ã‚¸ã‚ªã®éŸ³ã‚’ミュートã™ã‚‹" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "ウインドウを隠ã™éš›ã€SFXã®éŸ³ã‚’ミュートã™ã‚‹" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "ウインドウを隠ã™éš›ã€MTAã®éŸ³ã‚’ミュートã™ã‚‹" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "ウインドウを隠ã™éš›ã€å£°ã®éŸ³ã‚’ミュートã™ã‚‹" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "è§£åƒåº¦ï¼š" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "FOV:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "レンダリングè·é›¢ï¼š" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "è¼åº¦ï¼š" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FXã®è³ªï¼š" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "異方性フィルタリング:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "アンãƒã‚¨ã‚¤ãƒªã‚¢ã‚¹ï¼š" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "アスペクト比:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "ウィンドウ" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI承知" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "標準" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "ボーダーãªã—ウィンドウã«ã—ã¦è§£åƒåº¦ã‚’ä¿å­˜ã™ã‚‹" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "ミップマッピング" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "低" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "中" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "高" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "最高" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "無効" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "自動" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUDアスペクト比" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "体ç©å½±" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "グラスFX" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "陽炎" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "タイヤã®ç…™ãªã©" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "å‹•çš„ãªã‚­ãƒ£ãƒ©ã‚¯ã‚¿ãƒ¼ã®å½±" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "モーションブラー" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "コロナ雨ã®åå°„" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "フルスクリーン最å°åŒ–" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "デãƒã‚¤ã‚¹æœ‰åŠ¹é¸æŠžãƒ€ã‚¤ã‚¢ãƒ­ã‚°" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "ä¸å®‰å…¨ãªè§£åƒåº¦ã‚’表示ã™ã‚‹" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "車を最高質ã§ãƒ¬ãƒ³ãƒ€ãƒ¼ã™ã‚‹" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "ペッドを最高質ã§ãƒ¬ãƒ³ãƒ€ãƒ¼ã™ã‚‹" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "リモートウェブサイトを有効ã™ã‚‹" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "リモートウェブサイトã«Javascriptを有効ã™ã‚‹" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "GPUレンダリングを有効ã«ã™ã‚‹" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "カスタムブラックリスト" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "ドメインを入力ã—ã¦ãã ã•ã„(例:google.com)" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "ブロック" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "ドメイン" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "ドメインを消ã™" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "カスタムホワイトリスト" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "有効" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "ãã®ä»–" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "CJã®æœã‚’高速読ã¿è¾¼ã¿:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "ブラウザã®é€Ÿã•:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "å˜ä¸€æŽ¥ç¶š:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "パケットタッグ:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "アニメーション進歩:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "プロセス優先度:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "デãƒãƒƒã‚°è¨­å®šï¼š" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "ストリーミングメモリé‡ï¼š" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "ビルドタイプをアップデートã™ã‚‹ï¼š" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "é‡è¦ãªã‚¢ãƒƒãƒ—デートをインストール:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "ã¤ã‘ã‚‹" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "ã•らã«é…ã" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "デフォルト" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "速ã„" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "普通" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "良ã„" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "最å°" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "最大" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 サãƒãƒ¼ãƒˆï¼š" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-ビットカラー" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "マウスフィックス" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "クライアント資æºãƒ•ァイル:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "エクスプローラã«è¡¨ç¤ºã™ã‚‹" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "CPU 0 ã®è¦ªå’Œæ€§ã‚’設定ã—ã¦ã‚²ãƒ¼ãƒ ãƒ‘フォーマンスを最é©åŒ–ã™ã‚‹" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "自動アップデータ" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "今ã«ã‚¢ãƒƒãƒ—デートをãƒã‚§ãƒƒã‚¯ã™ã‚‹" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "今度ã€MTAを実行ã™ã‚‹éš›ã€ã‚る設定ãŒå¤‰ã‚りã¾ã™" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "今ã«å†èµ·å‹•ã—ã¾ã™ã‹ï¼Ÿ" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "å†èµ·å‹•ã¯å¿…è¦ã§ã™" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "サーãƒãƒ¼ã‹ã‚‰åˆ‡æ–­ã™ã‚‹ã¨ã€ã‚る設定ãŒå¤‰ã‚りã¾ã™" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "今ã«åˆ‡æ–­ã—ã¾ã™ã‹ï¼Ÿ" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "切断必è¦" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "ジョイパッドã¯ã¤ãªãŒã£ã¦ã„ã¾ã›ã‚“ - 接続をãƒã‚§ãƒƒã‚¯ã—ã¦ã€ã‚²ãƒ¼ãƒ ã‚’å†èµ·å‹•ã—ã¦ãã ã•ã„" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°è»¸" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "ãƒã‚¤ãƒ³ãƒ‰ã™ã‚‹ãŸã‚ã€è»¸ã‚’å‹•ã‹ã—ã¦ãã ã•ã„。ã¾ãŸã¯ã€ESCを押ã—ã¦ã‚¯ãƒªã‚¢ã—ã¦ãã ã•ã„。" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "言語:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "スキン:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "プリセット:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "ãƒãƒ£ãƒƒãƒˆ" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "読ã¿è¾¼ã¿" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "色" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "設計" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "設定" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "インプットBG" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "ãƒãƒ£ãƒƒãƒˆãƒ†ã‚­ã‚¹ãƒˆ" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "インプットBG" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "インプットテキスト" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "ライン数:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "拡大縮å°ï¼š" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "幅:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "サイス" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "後" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "ã®" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "ç§’" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "薄れ" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "å¤ã„ラインをフェードアウトã™ã‚‹" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "横:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "縦:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "テキストアライメント:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "Xオフセット:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Yオフセット:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "ä½ç½®" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "å·¦" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "中" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "å³" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "トップ" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "底" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "フォント" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "書ã„ã¦ã„ãªã„時ã«BGã‚’éš ã™" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "「タッブã€ã‚­ãƒ¼ã§ãƒ‹ãƒƒã‚¯å®Œæˆã™ã‚‹" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "サーãƒãƒ¼ã‚’ウィンドウフラッシュã™ã‚‹ã®ã‚’有効ã™ã‚‹" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "トレイ通知を有効ã™ã‚‹" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "ãƒãƒ£ãƒƒãƒˆãƒ†ã‚­ã‚¹ãƒˆç™½é»’アウトライン" @@ -1550,89 +1836,95 @@ msgstr "ãƒãƒ£ãƒƒãƒˆãƒ†ã‚­ã‚¹ãƒˆç™½é»’アウトライン" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "キーを押ã—ã¦ã€ãƒã‚¤ãƒ³ãƒ‰ã—ã¦ãã ã•ã„。ã¾ãŸã¯ã€ESCを押ã—ã¦ã€ã‚¯ãƒªã‚¢ã—ã¦ãã ã•ã„。" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "一次キーをãƒã‚¤ãƒ³ãƒ‰ã—ã¦ã„ã¾ã™" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "二次キーをãƒã‚¤ãƒ³ãƒ‰ã—ã¦ã„ã¾ã™" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTAゲームコントロール" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "ãƒãƒƒãƒˆã‚²ãƒ¼ãƒ ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ«" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "ニックãƒãƒ¼ãƒ ã«ç„¡åŠ¹ãªæ–‡å­—ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ï¼" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "メインメニュー" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "ゲーム内" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "R (赤):" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "G (ç·‘):" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "B (é’):" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "逿˜Ž:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "色" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "プリビュー" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "言語を変更ã™ã‚‹å‰ã«ã€åˆ‡æ–­ã—ã¦ãã ã•ã„" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "スキンを変更ã™ã‚‹å‰ã«ã€åˆ‡æ–­ã—ã¦ãã ã•ã„" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "æµé‡å½±ãŒOS速度をè½ã¨ã™ã‹ã‚‚ã—れã¾ã›ã‚“。\n\n" "有効ã«ãŸã—ã‹ã§ã™ã‹ï¼Ÿ" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "パフォーマンス警告" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "時々アンãƒãƒãƒ¼ãƒˆã®ãŸã‚ã€ç”»é¢ã‚¢ãƒƒãƒ—ロードã¯ã‚るサーãƒãƒ¼ã«å¿…è¦ã§ã™ã€‚\n\n" "(ãƒãƒ£ãƒƒãƒˆãƒœãƒƒã‚¯ã‚¹ã¨GUIãŒã‚¢ãƒƒãƒ—ロードã«é™¤å¤–ã•れã¦ã„ã¾ã™ï¼‰\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "スクリーンアップロード情報" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1640,23 +1932,21 @@ msgstr "ã‚るスクリプトãŒéŸ³ã‚’ã—ã¾ã™ã€‚例ãˆã€ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒƒãƒˆ "ã“ã®è¨­å®šã‚’無効ã«ã—ãŸã‚‰\n" "å¸¯åŸŸå¹…æ¶ˆè²»ãŒæ¸›ã‚Šã¾ã™ã€‚\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "外部音" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "リッãƒãƒ—レゼンス連æºã‚ªãƒ—ã‚·ãƒ§ãƒ³ãŒæœ‰åйã«ãªã£ã¦ã„ã‚‹ã¿ãŸã„ã§ã™ã€‚\n" -"サーãƒãƒ¼ã«ãƒ‡ãƒ¼ã‚¿ã‚’共有ã™ã‚‹ã“ã¨ã‚’許å¯ã—ã¾ã™ã‹ï¼Ÿ\n\n" -"ã“れã«ã¯ã‚ãªãŸã®å€‹äººIDãŒå«ã¾ã‚Œã¾ã™ã€‚" +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "データ共有ã®è¨±è«¾" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1666,11 +1956,7 @@ msgstr "GTA:SAインストールフォルダーã«ã‚るカスタムデーター "ã—ã‹ã—ã€ã‚«ã‚¹ã‚¿ãƒ ãƒ•ァイルã¯ã‚るサーãƒãƒ¼ã«åˆ©ç”¨ç¦æ­¢ã§ã™ã€‚\n\n" "利用ã™ã‚‹ã«ç¢ºã‹ã§ã™ã‹ï¼Ÿ" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "カスタムGTA:SAファイル" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1680,552 +1966,253 @@ msgstr "DPI承知ã¯å®Ÿé¨“的機能ã§ã‚ã‚‹ãŸã‚\n" "ã“ã®è¨­å®šã‚’有効ã—ãŸã‚‰ã‚°ãƒ©ãƒ•ィックå•題ãŒç¾ã‚Œã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。\n\n" "ã“ã®è¨­å®šã‚’有効ã—ã¾ã™ã‹ã€‚" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "実験的機能" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "ã“ã®ã‚ªãƒ—ションを無効ã«ã™ã‚‹ã“ã¨ã¯ã€ãƒ‘フォーマンスã®å•題ãŒç™ºç”Ÿã—ã¦ã„ã‚‹å ´åˆã‚’除ãã€æŽ¨å¥¨ã—ã¾ã›ã‚“。\n\n" "無効ã«ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "ニックãƒãƒ¼ãƒ ã‚’入れã¦ãã ã•ã„" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "ゲームã§åˆ©ç”¨ã™ã‚‹ãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ ã‚’記入ã—ã¦ã€‚ \n" "ã“れã¯ã‚µãƒ¼ãƒãƒ¼ã«æŽ¥ç¶šã—プレイã™ã‚‹ãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ ã«ãªã‚Šã¾ã™" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "ã¨ã¦ã‚‚å®Ÿé¨“çš„ãªæ©Ÿèƒ½" -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "CJãƒãƒªã‚¨ãƒ¼ã‚·ãƒ§ãƒ³å±‹å°ã‚’åœæ­¢ï¼ˆ65MB RAM以上)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "å¤ã„ルーターã¯é…ã„スキャンスピードãŒå¿…è¦ã‹ã‚‚知れã¾ã›ã‚“。" -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "ダウンロード中ã«å˜ä¸€æŽ¥ç¶šã«ã‚¹ã‚¤ãƒƒãƒã—ã¾ã™ã€‚" -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "ISPãŒMTAã®äº¤é€šã‚’確èªã™ã‚‹ãŸã‚ã€ãƒ‘ケットをタッグã—ã¾ã™ã€‚" -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "ç”»é¢ã®åº•ã«å›žè»¢ã™ã‚‹ã‚µãƒ¼ã‚¯ãƒ«" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "ã„ã¤ã‚‚デフォルトをé¸ã¶ã€‚(ã“ã®è¨­å®šã¯ä¿å­˜ã•れã¾ã›ã‚“)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "æœ€é«˜ã¯æ™®é€šã«ä¸€ç•ªè‰¯ã„" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "自動アップデータ:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆãŒå¾—æ„ãªäººä»¥å¤–ã€ãƒ‡ãƒ•ォルトをé¸ã‚“ã§ãã ã•ã„。" -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "é‡è¦ãªã‚¢ãƒƒãƒ—デートをインストールã™ã‚‹ã‚ˆã†ã«ãƒ‡ã‚£ãƒ•ォルトをé¸ã‚“ã§ãã ã•ã„。" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-ビットカラー" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "16-ビットカラーモードを有効ã™ã‚‹ - MTAã‚’å†èµ·å‹•ã™ã‚‹ã®ãŒå¿…è¦ã§ã™" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "マウス修正:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "マウス移動修正 - パソコンをå†èµ·å‹•ã™ã‚‹ã®ãŒå¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "CPU親和性:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "安定性ã®å•題ãŒç™ºç”Ÿã—ã¦ã„ã‚‹å ´åˆã®ã¿å¤‰æ›´ã—ã¦ãã ã•ã„。" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "䏿˜Žãªã‚³ãƒžãƒ³ãƒ‰:" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "å¿™ã—ã„" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "ç¾åœ¨ã€ã‚¢ãƒƒãƒ—デートãƒã‚§ãƒƒã‚¯ã¯å‡ºæ¥ã¾ã›ã‚“" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s ãŒå¿…è¦ã§ã™" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã«å‚加ã™ã‚‹ãŸã‚ã«ã€MTA:SA %s ã®æœ€æ–°ã‚¢ãƒƒãƒ—デートãŒå¿…è¦ã§ã™ã€‚\n\n" -"MTA:SA %s をダウンロードã—ã¦ã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¾ã™ã‹ï¼Ÿ" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "MTA:SA %s を実行ã—ã¦ã€ã“ã®ã‚µãƒ¼ãƒãƒ¼ã«å‚加ã—ã¾ã™ã‹ï¼Ÿ" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "ç¾åœ¨ã€ã‚µãƒ¼ãƒãƒ¼ã«æŽ¥ç¶šã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。\n\n" -"後ã§ã€ã‚‚ã†ä¸€å›žè©¦ã—ã¦ã¿ã¦ãã ã•ã„。" - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "接続中" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„。。。" - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "ãƒã‚§ãƒƒã‚¯ä¸­" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "アップデートãƒã‚§ãƒƒã‚¯ä¸­" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "アップデートã™ã‚‹å¿…è¦ã¯ã‚りã¾ã›ã‚“" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "ダウンロード中" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "待機中..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "義務的ãªã‚¢ãƒƒãƒ—デート" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã«å‚加ã™ã‚‹ãŸã‚ã«ã€MTAをアップデートã™ã‚‹ã“ã¨ãŒå¿…è¦ã§ã™ã€‚\n\n" -"今ã«ã‚¢ãƒƒãƒ—デートã—ã¾ã™ã‹ã€‚" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "ä¸è¦ãªã‚¢ãƒƒãƒ—デート" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "サーãƒãƒ¼ã¯ã‚¢ãƒƒãƒ—ãƒ‡ãƒ¼ãƒˆã¯æŽ¨å¥¨ã•れã¦ã„ã¾ã™ãŒã€ã‚¢ãƒƒãƒ—デート必è¦ã¯ã‚りã¾ã›ã‚“。\n\n" -"アップデートã—ã¾ã™ã‹ï¼Ÿ" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "ç¾åœ¨ã€ã‚¢ãƒƒãƒ—デートã¯ã§ããªã„状態ã§ã™ã€‚\n\n" -"www.multitheftauto.com ã‚’ã”確èªãã ã•ã„" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "ä¿å­˜ã‚¨ãƒ©ãƒ¼" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "ファイルを作æˆã§ãã¾ã›ã‚“。" - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "ダウンロードエラー" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "ダウンロードã—ãŸãƒ•ァイルã¯ç„¡åйã®ã‚ˆã†ã§ã™ã€‚" - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "ãªã‚“ã¨ã‹ã€‚" - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "ダウンロードæˆåŠŸ" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "- _DialogUpdateResult ã«ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼ " - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "OK" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "エラー" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "MTA:SAファイルã®ä¸€éƒ¨ãŒä¸è¶³ã—ã¦ã„ã¾ã™ã€‚\n\n\n" -"MTA:SAã‚’å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% 完了" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"返事を待ã£ã¦ã„ã¾ã™ - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "接続ã«å¤±æ•—ã—ã¾ã—ãŸã€‚無効ãªãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ ãŒè¨˜å…¥ã•れã¾ã—ãŸ!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "接続ã«å¤±æ•—ã—ã¾ã—ãŸã€‚無効ãªãƒ›ã‚¹ãƒˆãŒè¨˜å…¥ã•れã¾ã—ãŸ!!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "%sã®%u ã®æŽ¥ç¶šãŒå¤±æ•—ã—ã¾ã—ãŸï¼" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "%s:%u ã«æŽ¥ç¶šä¸­ã€‚ã€‚ã€‚" - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "%s:%u ã«å†æŽ¥ç¶šã—ã¦ã„ã¾ã™â€¦" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "接続中" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "接続ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "åˆ‡æ–­ï¼šä¸æ˜Žãªãƒ—ロトコルエラー" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "接続切断:リモートã‹ã‚‰æŽ¥ç¶šãŒåˆ‡æ–­ã•れã¾ã—ãŸ" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "切断: ãƒªãƒ¢ãƒ¼ãƒˆã§æŽ¥ç¶šãŒå¤±ã‚れã¾ã—ãŸ" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "切断: ã‚ãªãŸã¯ã“ã®ã‚µãƒ¼ãƒãƒ¼ã‹ã‚‰ç¦æ­¢ã•れã¾ã—ãŸ" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "切断: サーãƒãƒ¼ã‹ã‚‰åˆ‡æ–­ã•れã¾ã—ãŸ" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "切断:サーãƒãƒ¼ã¨ã®æŽ¥ç¶šãŒå¤±ã‚れã¾ã—ãŸ" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "切断: æŽ¥ç¶šãŒæ‹’å¦ã•れã¾ã—ãŸ" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "MODã¯ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ã„ã¾ã›ã‚“ (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "無効ãªã‚µãƒ¼ãƒãƒ¼ãƒ¬ã‚¹ãƒãƒ³ã‚¹ (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "無効ãªã‚µãƒ¼ãƒãƒ¼è¿”ç­”ã§ã—㟠(1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "ãŠçŸ¥ã‚‰ã›" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "最新ニュース記事を読む" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "コンソール" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "致命的ãªã‚¨ãƒ©ãƒ¼" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "修正ã™ã‚‹ã«ã¯ã€ã“ã®ãƒ•ァイルを消ã—ã¦ãã ã•ã„:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¯æ­£ã—ãã‚りã¾ã›ã‚“ï¼" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "URL実行エラー" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "ã“ã®ãƒ˜ãƒ«ãƒ—ç”»é¢" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "アプリケーションを終了ã™ã‚‹" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’表示ã™ã‚‹" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "時間を表示ã™ã‚‹" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "HUDを表示ã™ã‚‹" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "ã™ã¹ã¦ã®ãƒã‚¤ãƒ³ãƒ‰ã‚’表示ã™ã‚‹" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "シリアル番å·ã‚’表示ã™ã‚‹" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "サーãƒãƒ¼ã«æŽ¥ç¶šã™ã‚‹ (ホスト ãƒãƒ¼ãƒˆ ニックãƒãƒ¼ãƒ  パスワード)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "以å‰ã®ã‚µãƒ¼ãƒãƒ¼ã«æŽ¥ç¶šã™ã‚‹" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "キーをãƒã‚¤ãƒ³ãƒ‰ã—ã¾ã™ (キーコントローラ)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "キーãƒã‚¤ãƒ³ãƒ‰ã‚’削除ã—ã¾ã™ (キー)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" -msgstr "GTA: San Andreasã®ãƒ‡ãƒ•ォルトコントロールをコピーã™ã‚‹" - -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "スクリーンショットを出ã™" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "設定をã™ãã«ä¿å­˜ã™ã‚‹" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "デãƒãƒƒã‚°ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚’消ã™" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "ãƒãƒ£ãƒƒãƒˆãƒœãƒƒã‚¯ã‚¹ã‚’上ã«ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«ã™ã‚‹" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "ãƒãƒ£ãƒƒãƒˆãƒœãƒƒã‚¯ã‚¹ã‚’下ã«ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«ã™ã‚‹" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "デãƒãƒƒã‚°ã‚’上ã«ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«ã™ã‚‹" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "デãƒãƒƒã‚°ã‚’下ã«ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«ã™ã‚‹" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "メモリデータを表示ã™ã‚‹" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "FPSグラフを表示ã™ã‚‹" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "ディベロッパーå‘ã:ニュースå†èª­ã¿è¾¼ã¿" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ コマンド ヘルプ ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* 時間㯠%d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "接続:ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ãŒæº–å‚™ã§ãã¦ã„ã¾ã›ã‚“。ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "接続:'connect <ホスト> [<ãƒãƒ¼ãƒˆ> <ニック> <パスワード>]'" +msgstr "GTA: San Andreasã®ãƒ‡ãƒ•ォルトコントロールをコピーã™ã‚‹" -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "接続: 無効ãªãƒãƒ¼ãƒˆç•ªå·" +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "スクリーンショットを出ã™" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "接続: %s:%uã«æŽ¥ç¶šã—ã¦ã„ã‚‹..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "設定をã™ãã«ä¿å­˜ã™ã‚‹" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "接続: %s:%u ã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸï¼" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "デãƒãƒƒã‚°ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚’消ã™" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "接続:ç¾åœ¨MODをアンロードã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "ãƒãƒ£ãƒƒãƒˆãƒœãƒƒã‚¯ã‚¹ã‚’上ã«ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«ã™ã‚‹" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "å†æŽ¥ç¶šï¼šãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ãŒæº–å‚™ã§ãã¦ã„ã¾ã›ã‚“。ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "ãƒãƒ£ãƒƒãƒˆãƒœãƒƒã‚¯ã‚¹ã‚’下ã«ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«ã™ã‚‹" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "å†æŽ¥ç¶šï¼šç„¡åŠ¹ãªãƒãƒ¼ãƒˆç•ªå·ã§ã™" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "デãƒãƒƒã‚°ã‚’上ã«ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«ã™ã‚‹" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "å†æŽ¥ç¶šï¼š%s:%u ã«å†æŽ¥ç¶šä¸­â€¦" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "デãƒãƒƒã‚°ã‚’下ã«ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«ã™ã‚‹" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "å†æŽ¥ç¶šï¼š%s:%u ã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸï¼" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "メモリデータを表示ã™ã‚‹" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "å…¨ã¦ã®ãƒã‚¤ãƒ³ãƒ‰ã¯GTAã‹ã‚‰ã‚³ãƒ”ーã•れã¾ã—ãŸ" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "FPSグラフを表示ã™ã‚‹" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "ä¿å­˜ã—ãŸè¨­å®šãƒ•ァイル" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "ディベロッパーå‘ã:ニュースå†èª­ã¿è¾¼ã¿" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "*ã‚ãªãŸã®ã‚·ãƒªã‚¢ãƒ«ç•ªå·ã¯ï¼š %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "新機能ブランãƒã‚’利用ã—ã¦ã„ã¾ã™ï¼ã“れã¯ãƒ†ã‚¹ãƒˆãƒ“ルドã§ã‚ã‚‹ãŸã‚ã€å…¬å…±ã‚µãƒ¼ãƒãƒ¼ã«ã¯æŽ¥ç¶šã§ãã¾ã›ã‚“ï¼" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "加速軸" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "ï¼’ï¼ï¼‘9年7月以æ¥ã€MTAã¯XP/Vistaã®ã‚¢ãƒƒãƒ—ãƒ‡ãƒ¼ãƒˆã‚’åœæ­¢ã—ã¾ã™ã€‚\n\n" +"æ–°ã—ã„サーãƒãƒ¼ã§ãƒ—レイã™ã‚‹ãŸã‚ã«Windowsをアップデートã—ã¦ãã ã•ã„。" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "ブレーキ軸" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "サーãƒãƒ¼ã‹ã‚‰åˆ‡æ–­ã•れるã“ã¨ã«ãªã‚Šã¾ã™ã€‚\n\n" +"サーãƒãƒ¼ã‹ã‚‰åˆ‡æ–­ã«ç¢ºã‹ã§ã™ã‹ï¼Ÿ" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "プログラミング" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "切断警告" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "寄稿者" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "情報" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "ゲームデザイン / スクリプティング" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "ãŠçŸ¥ã‚‰ã›" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "言語ローカリゼーション" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "最新ニュース記事を読む" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "パッãƒå”力者" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "スクリーンショット㯠%d ãƒã‚¤ãƒˆã§ã™ãŒã€%d ãŒæ‰€æœŸã•れã¾ã—ãŸ" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "ç‰¹åˆ¥ãªæ„Ÿè¬" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "スクリーンショット失敗" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "ã“ã®ã‚½ãƒ•トï¼ãƒ—ロジェクトãŒä¸‹è¨˜ã®ãƒ©ã‚¤ãƒ–ラリやソフトを利用ã—ã¦ã„ã¾ã™:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "スクリーンショットを撮影ã—ã¾ã—ãŸ: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "ã“ã®å•題ã«ã¤ã„ã¦ã«ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã§èª¿ã¹ãŸã„ã§ã™ã‹ï¼Ÿ" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "䏿˜Žãªã‚³ãƒžãƒ³ãƒ‰:" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2400,25 +2387,56 @@ msgid "Group control backwards" msgstr "グループコントロール後方" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "é¸æŠžã—ãŸã‚¹ã‚­ãƒ³ã¨ãƒ‡ãƒ•ォルトã®ã‚¹ã‚­ãƒ³ã‚’ロードã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚MTAã‚’å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。" -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "スクリーンショット㯠%d ãƒã‚¤ãƒˆã§ã™ãŒã€%d ãŒæ‰€æœŸã•れã¾ã—ãŸ" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "ã“ã®å•題ã«ã¤ã„ã¦ã«ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã§èª¿ã¹ãŸã„ã§ã™ã‹ï¼Ÿ" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "スクリーンショット失敗" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "コンソール" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "スクリーンショットを撮影ã—ã¾ã—ãŸ: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "プログラミング" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "寄稿者" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "ゲームデザイン / スクリプティング" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "言語ローカリゼーション" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "パッãƒå”力者" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "ç‰¹åˆ¥ãªæ„Ÿè¬" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "ã“ã®ã‚½ãƒ•トï¼ãƒ—ロジェクトãŒä¸‹è¨˜ã®ãƒ©ã‚¤ãƒ–ラリやソフトを利用ã—ã¦ã„ã¾ã™:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "加速軸" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "ブレーキ軸" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2427,6 +2445,59 @@ msgstr "Direct3D9ã¯åˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n\n" "最新WindowsサービスパックãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«\n" "ã•れã¦ã„ã‚‹ã‹ç¢ºèªã—ã¦ãã ã•ã„。" +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "待機中ã§ã™" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "プレイヤープレイヤー" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "ã«" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "サーãƒãƒ¼ã‚µãƒ¼ãƒãƒ¼" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "マスターリストをリクエストã—ã¦ã„ã¾ã™ã€‚(%lu ms éŽãŽã¾ã—ãŸ)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "マスターサーãƒãƒ¼ãƒªã‚¹ãƒˆãŒè§£æžã§ãã¾ã›ã‚“ã§ã—ãŸã€‚" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "マスターサーãƒãƒ¼ãƒªã‚¹ãƒˆãŒå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚" + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—サーãƒãƒ¼ãƒªã‚¹ãƒˆï¼‰" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "LAN放é€ã‚½ã‚±ãƒƒãƒˆã‚’ãƒã‚¤ãƒ³ãƒ‰ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "LANサーãƒãƒ¼ã‚’検索中" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2480,7 +2551,7 @@ msgstr "レイテンシ:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "プレイヤーリスト" @@ -2507,40 +2578,39 @@ msgstr "スペースãŒç©ºã„ãŸã‚‰ã€ã™ãã«å‚加ã™ã‚‹ã€‚" msgid "PLEASE ENTER SERVER PASSWORD" msgstr "パスワードを入れã¦ãã ã•ã„" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "タイムアウト" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "å•ã„åˆã‚ã›ã¦ã„ã¾ã™ã€‚。。" #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "サーãƒãƒ¼ãƒ–ラウザ" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "インターãƒãƒƒãƒˆ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "ローカル" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "ãŠæ°—ã«å…¥ã‚Š" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "最近" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2548,296 +2618,367 @@ msgstr "æ—©ã‚ã«æŽ¥ç¶šã™ã‚‹ãŸã‚ã«ï¼š\n\n" "アドレスãƒãƒ¼ã«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¨ãƒãƒ¼ãƒˆã‚’記入ã—ã¦ãã ã•ã„。\n" "ã¾ãŸã¯ã€æœ€è¿‘ã®ã‚µãƒ¼ãƒãƒ¼ãƒªã‚¹ãƒˆã§ã‚µãƒ¼ãƒãƒ¼ã‚’é¸ã‚“㧠「接続ã™ã‚‹ã€ã‚’クリックã—ã¦ãã ã•ã„。" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "ヘルプ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "リフレッシュ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "ãŠæ°—ã«å…¥ã‚Šã«è¿½åŠ " -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "接続ã™ã‚‹" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "サーãƒãƒ¼æƒ…å ±" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "サーãƒã‚’検索" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "プレイヤーを検索ã™ã‚‹" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "検索開始" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "プレイヤー検索。。。" -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "サーãƒãƒ¼ã‚’検索ã™ã‚‹â€¦" -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "åå‰" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "プレイヤー" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "レイテンシ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "ゲームモード" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "å«ã‚€:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "空" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "満æ¯" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "ロック中" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "オフライン" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "ä»–ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "戻る" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "読ã¿è¾¼ã¿ä¸­ã€‚。。" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " 。。読ã¿è¾¼ã¿ä¸­ã€‚。" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "ã‚¢ãƒ‰ãƒ¬ã‚¹ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“ï¼" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "䏿˜Žãªãƒ—ロトコル" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "「mtasa://ã€ãƒ—ロトコルを利用ã—ã¦ãã ã•ã„ï¼" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "無効ãªãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ ã§ã™ï¼ 設定ã§ãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ ã‚’変更ã—ã¦ãã ã•ã„ï¼" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "サーãƒãƒ¼ã‚’é¸ã‚“ã§ãã ã•ã„。" -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "待機中ã§ã™" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "グラフィックドライãƒã¨å•題ãŒã‚りã¾ã™" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "プレイヤープレイヤー" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "有効ãªè§£åƒåº¦ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚" -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "ã«" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "ã“ã®è§£åƒåº¦ã‚’利用ã™ã‚‹ã«ç¢ºã‹ã§ã™ã‹ï¼Ÿ" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "サーãƒãƒ¼ã‚µãƒ¼ãƒãƒ¼" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "game_sa ã®åˆæœŸåŒ–ã«å¤±æ•—ã—ã¾ã—ãŸ" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "マスターリストをリクエストã—ã¦ã„ã¾ã™ã€‚(%lu ms éŽãŽã¾ã—ãŸ)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "メモリ割り当ã¦ã«å¤±æ•—ã—ã¾ã—ãŸ" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "マスターサーãƒãƒ¼ãƒªã‚¹ãƒˆãŒè§£æžã§ãã¾ã›ã‚“ã§ã—ãŸã€‚" +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "ウェッブサイトリクエスト" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "マスターサーãƒãƒ¼ãƒªã‚¹ãƒˆãŒå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚" +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "後ã«ãƒ­ãƒ¼ãƒ‰ã™ã‚‹ãŸã‚ã€ã‚µãƒ¼ãƒãƒ¼ã¯æ¬¡ã®ã‚¦ã‚§ãƒƒãƒ–サイトをリクエストã—ã¦ã„ã¾ã™ï¼š" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—サーãƒãƒ¼ãƒªã‚¹ãƒˆï¼‰" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "ç›—ã¾ã‚‰ãªã„よã†ã«ã€å€‹äººæƒ…報を絶対書ã‹ãªã„ã§ãã ã•ã„" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "LAN放é€ã‚½ã‚±ãƒƒãƒˆã‚’ãƒã‚¤ãƒ³ãƒ‰ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ã§ã—ãŸ" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "決定をä¿å­˜ã™ã‚‹" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "LANサーãƒãƒ¼ã‚’検索中" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "å¦å®š" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒå¤±åйã—ã¾ã—ãŸã€‚" -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "ゲームã‹ã‚‰åˆ‡æ–­ã™ã‚‹" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "ãƒãƒ¼ãƒ ã‚¿ã‚°ã‚’表示ã™ã‚‹" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "ãƒãƒ£ãƒƒãƒˆãƒœãƒƒã‚¯ã‚¹ã‚’表示ã™ã‚‹" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "ãƒãƒƒãƒˆçµ±è¨ˆã‚’表示ã™ã‚‹" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "ãƒãƒ£ãƒƒãƒˆå…¥åŠ›ã‚’é–‹ã‘ã‚‹" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "ä»–ã®ãƒ—レーヤーã«å£°ã‚’é€ä¿¡ã™ã‚‹" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "åŒä¹—ã§è»Šã«ä¹—ã‚‹" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "次ã®ãƒ©ã‚¸ã‚ªãƒãƒ£ãƒ³ãƒãƒ«" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "å‰ã®ãƒ©ã‚¸ã‚ªãƒãƒ£ãƒ³ãƒãƒ«" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "プレイヤーマップを表示" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "プレイヤーマップ拡大" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "プレイヤーマップ縮å°" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "プレイヤーマップ 北ã¸ç§»å‹•" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "プレイヤーマップ å—ã¸ç§»å‹•" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "プレイヤーマップ æ±ã¸ç§»å‹•" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "プレイヤーマップ 西ã¸ç§»å‹•" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "プレイヤーマップを固定" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "プレイヤーマップ ä¸é€æ˜Žåº¦æ¸›å°‘" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "プレイヤーマップ ä¸é€æ˜Žåº¦å¢—加" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "プレイヤーマップ ヘルプ表示切り替ãˆ" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "é¸ã‚“ã ãƒ—レーヤーã«ãƒ¡ã‚»ãƒ¼ã‚¸ã‚’é€ã‚‹" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "車ã«ä¹—ã£ã¦ã„ã‚‹æ™‚ã€æ¬¡ã®æ­¦å™¨ã«å¤‰ãˆã‚‹ã€‚" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "車ã«ä¹—ã£ã¦ã„る時ã€å‰ã®æ­¦å™¨ã«å¤‰ãˆã‚‹ã€‚" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "ç¾åœ¨ã‚µãƒ¼ãƒãƒ¼ã®æƒ…報を表示ã™ã‚‹" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "テキストã®ã‚¹ã‚±ãƒ¼ãƒ«ãƒžãƒ«ãƒãƒ—ライヤ設定" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(デベロップメントモード)コリジョン形を表示ã™ã‚‹" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(デベロップメントモード)世界音IDをデãƒãƒƒã‚°ã‚¦ã‚¤ãƒ³ãƒ‰ã‚¦ã«è¡¨ç¤ºã™ã‚‹" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "ゲームホストã™ã‚‹" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "資æº" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "サーãƒå:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "パスワード:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "最大プレイヤー数:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "放é€ï¼š" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "é¸æŠž" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "全部" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "é–‹å§‹" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "モード変更:%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "ズーム:%s/%s 移動:%s, %s, %s, %s ä¸é€æ˜Žåº¦ï¼š%s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "マップ表示切替:%s ヘルプ表示切替:%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "プレイヤー追尾" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "自由移動" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "マップダウンロード進æ—:" @@ -2858,488 +2999,398 @@ msgstr "%s ã® %s" msgid "Disconnect to cancel download" msgstr "ダウンロードをキャンセルã™ã‚‹ã«ã¯ã€åˆ‡æ–­ã—ã¦ãã ã•ã„" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "切断:無効ãªãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "サーãƒãƒ¼ã‹ã‚‰åˆ‡æ–­ã™ã‚‹" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "切断:シリアルãŒç¦æ­¢ã•れã¾ã—ãŸã€‚\n" "ç†ç”±ï¼š %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "切断: ã‚ãªãŸãŒç¦æ­¢ã•れã¾ã—ãŸã€‚\n" "ç†ç”±ï¼š%s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "切断:アカウントãŒç¦æ­¢ã•れã¾ã—ãŸã€‚\n" "ç†ç”±ï¼š %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "切断: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãƒŸã‚¹ãƒžãƒƒãƒ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "切断: å‚加溢水。ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„。後ã§å‚加ã—ã¦ã¿ã¦ãã ã•ã„。" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "切断: サーãƒãƒ¼ã®ãƒ–ランãƒã¯é•ã„ã¾ã™ã€‚\n" "情報: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "切断: 無効ãªãƒãƒ¼ã‚¸ãƒ§ãƒ³ã€‚\n" "情報: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "切断: サーãƒãƒ¼ã¯æ–°ã—ã„ビルドã§å®Ÿè¡Œã—ã¦ã„ã¾ã™ã€‚\n" "情報: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "切断: サーãƒãƒ¼ã¯å¤ã„ビルドã§å®Ÿè¡Œã—ã¦ã„ã¾ã™ã€‚\n" "情報: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "切断: ニックãƒãƒ¼ãƒ ã¯ã‚‚ã†åˆ©ç”¨ã•れã¦ã„ã¾ã™" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "切断: プレーヤーエレメントãŒä½œæˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "切断: サーãƒãƒ¼ãŒæŽ¥ç¶šã‚’断りã¾ã—ãŸï¼š %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "切断: シリアル確èªãŒå¤±æ•—ã—ã¾ã—ãŸ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "切断ã•れã¾ã—ãŸï¼šãƒžã‚·ãƒ³ã‚·ãƒªã‚¢ãƒ«ãŒæ—¢ã«ä½¿ç”¨ã•れã¦ã„ã¾ã™" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "切断: 接続éžåŒæœŸåŒ– %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "切断: %s ã«ã‚­ãƒƒã‚¯ã•れã¾ã—ãŸ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "切断: %s ã«ç¦æ­¢ã•れã¾ã—ãŸ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "切断:サーãƒãƒ¼åœæ­¢ã—ãŸã‚ˆã†ã§ã™ã€‚ã‚‚ã—ãã¯å†èµ·å‹•ã—ã¦ã„るよã†ã§ã™" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "ゲームã‹ã‚‰ã‚­ãƒƒã‚¯ã•れã¾ã—ãŸ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã¯å¤‰æ›´ã•れã¦ã„ãªã„gta_sa.exeãŒå¿…è¦ã§ã™" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "gta_sa.exeを変更ã—ã¦ãã ã•ã„" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã¯ã‚«ã‚¹ã‚¿ãƒ D3D9.DLLã‚’ç¦ã˜ã—ã¦ã„ã¾ã™" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "GTAインストールフォルダã‹ã‚‰D3D9.DLLを消ã—ã¦ã€MTAã‚’å†èµ·å‹•ã—ã¦ãã ã•ã„" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã¯ä»®æƒ³ãƒžã‚·ãƒ³ã‚’ç¦ã˜ã—ã¦ã„ã¾ã™" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã¯ãƒ‰ãƒ©ã‚¤ãƒãƒ¼ç½²åを有効ã™ã‚‹ã®ãŒå¿…è¦ã§ã™" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "パソコンをå†èµ·å‹•ã—ã¦ãã ã•ã„" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã¯ä¸è¶³ã—ã¦ã„るアンãƒãƒãƒ¼ãƒˆã‚³ãƒ³ãƒãƒãƒ³ãƒˆã‚’検出ã—ã¾ã—ãŸ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "MTAã‚’å†èµ·å‹•ã—ã¦ã¿ã¦ãã ã•ã„" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã¯å¤‰æ›´ã•れã¦ã„ãªã„gta3.imgã¨gta_int.imgãŒå¿…è¦ã§ã™" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "gta3.imgã€ã‚ã‚‹ã„ã¯gta_int.imgを変更ã—ã¦ãã ã•ã„" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã¯Wineã‚’ç¦ã˜ã—ã¦ã„ã¾ã™" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "ä»–ã®ãƒ—ログラムãŒMTA:SAを変更ã—ã¦ã„ãªã„ã®ã‚’確èªã—ã¦ãã ã•ã„" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "残り時間: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d æ—¥" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d 時間" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d 分" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" msgstr[0] "%d ç§’" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "切断ã•れã¾ã—ãŸ" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "ダウンロードエラー: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "UFOã§å®‡å®™æ—…行気分" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "街をゆるã£ã¨å¾˜å¾Šä¸­" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "波乗りãªã†" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "電車ã§ã‚¬ã‚¿ãƒ³ã‚´ãƒˆãƒ³" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "空中散歩中" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "乗り回ã—ã¦ã‚‹ãœ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "モンスタートラック暴走中" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "ãƒã‚®ãƒ¼ä¹—り回ã—ã ãœ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "ã²ãŸã™ã‚‰ãƒãƒ‹ãƒ›ã´ã‚‡ã‚“ã´ã‚‡ã‚“" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "ãªã‚“ã‹ãƒ¤ãƒã„ã“ã¨ã—ã¦ã‚‹" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "高ã„ã¨ã“目指ã—ã¦ã‚ˆã˜ç™»ã‚Šä¸­" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "ドライブãƒã‚¤ã‹ã¾ã—中" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "ã¶ãã¶ã…" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "死人魚ã«ãªã‚Šã¾ã—ãŸ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "絶賛溺れ中" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "物陰ã«éš ã‚Œã¦ã‚‹ãœ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "ドンパãƒã‚„ã£ã¦ã‚‹ãœ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "素手タイマン中" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "敵をã¶ã£é£›ã°ã—ã¦ã‚‹ãœ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "乱射中ã ãœ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "ジェットパック空中散歩" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "文字通り物ç†çš„炎上中" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "燃ãˆå°½ããã†" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "スイミングãªã†" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "ã·ã‹ã·ã‹æ¼‚æµä¸­" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "サメã«è¿½ã‚れã¦ã‚‹ãªã†" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "窒æ¯ã—ãã†" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "å‚加中。。。" -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "接続ã—ã¦ã„ã¾ã›ã‚“;「クイックコãƒã‚¯ãƒˆã€ã‚„「connectã€ã‚³ãƒžãƒ³ãƒ‰ã‚’利用ã—ã¦ã€ã‚µãƒ¼ãƒãƒ¼ã«å‚加ã—ã¦ãã ã•ã„。" -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "ローカルサーãƒãƒ¼ãŒå®Ÿè¡Œã§ãã¾ã›ã‚“ã§ã—ãŸã€‚詳ã—ã„æƒ…å ±ã¯ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã«ã‚りã¾ã™ã€‚" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "ローカルサーãƒãƒ¼" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "ローカルサーãƒãƒ¼ã‚’実行ã—ã¦ã„ã¾ã™ã€‚。。" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "エリア 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "ãŠæ•£æ­©ä¸­ " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "ゲームã‹ã‚‰ã‚­ãƒƒã‚¯ã•れã¾ã—㟠(ç†ç”±ï¼š %s)" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "ローカルサーãƒãƒ¼ã«æŽ¥ç¶šä¸­..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "サーãƒãƒ¼æŽ¥ç¶šã‚¨ãƒ©ãƒ¼ã€‚" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "ローカルサーãƒã®æŽ¥ç¶šãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¦ã—ã¾ã„ã¾ã—ãŸã€‚情報ã¯ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã«ã‚りã¾ã™ã€‚" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "サーãƒãƒ¼ã¨ã®æŽ¥ç¶šãŒå¤±ã‚れã¦ã—ã¾ã„ã¾ã—ãŸ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "切断:サーãƒãƒ¼ã¯ç¾åœ¨æº€ã¡ã¦ã„ã¾ã™" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "切断:パスワードã¯ç„¡åйã§ã™ã€‚" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTAクライアント確èªå¤±æ•—ï¼" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "æºã«ãƒãƒžã‚Šä¸­" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "病院直行便ã«ä¹—車" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "神様ã¨é¢è«‡ä¸­" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "やらã‹ã—ã¦å¾Œæ‚”ãªã†" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "ç„¡äº‹ã€æ­»äº¡" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "ゲームホストã™ã‚‹" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "資æº" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "サーãƒå:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "パスワード:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "最大プレイヤー数:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "放é€ï¼š" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "é¸æŠž" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "全部" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "é–‹å§‹" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "モード変更:%s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "ズーム:%s/%s 移動:%s, %s, %s, %s ä¸é€æ˜Žåº¦ï¼š%s/%s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "マップ表示切替:%s ヘルプ表示切替:%s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "プレイヤー追尾" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "自由移動" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "グラフィックドライãƒã¨å•題ãŒã‚りã¾ã™" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "有効ãªè§£åƒåº¦ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚" - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "ã“ã®è§£åƒåº¦ã‚’利用ã™ã‚‹ã«ç¢ºã‹ã§ã™ã‹ï¼Ÿ" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "game_sa ã®åˆæœŸåŒ–ã«å¤±æ•—ã—ã¾ã—ãŸ" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "メモリ割り当ã¦ã«å¤±æ•—ã—ã¾ã—ãŸ" +msgid "Download error: %s" +msgstr "ダウンロードエラー: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3360,11 +3411,11 @@ msgstr "プロトコルエラー (%u) ã§ã™ã€‚ã“ã®å•題ãŒç¶šãå ´åˆã¯ã€ msgid "Connection error" msgstr "接続エラー" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Autoã¯æ­£ã—ãインストールã§ãã¾ã›ã‚“ã§ã—ãŸã€‚å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。" -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "ãƒ–ãƒ©ã‚¦ã‚¶ã¯æƒ…å ±ã®ã‚るウェッブページを表ã™ã€‚\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/ka_GE/client.pot b/Shared/data/MTA San Andreas/MTA/locale/ka_GE/client.pot index 301ae2e7944..ce1b75a93a8 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/ka_GE/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/ka_GE/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Georgian\n" "Language: ka_GE\n" @@ -17,228 +17,439 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "შეცდáƒáƒ›áƒ" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "" + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "" + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "" + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "" + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "" + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "" + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "" + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "" + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" msgstr "" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" msgstr "" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "" -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" msgstr "" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "" -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "შეცდáƒáƒ›áƒ" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "" -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "" -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." msgstr "" -#: Client/loader/MainFunctions.cpp:810 +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "" -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "" -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "" -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "" -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Data file %s is modified. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." msgstr "" -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" msgstr "" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" msgstr "" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA ვერ გáƒáƒ’რძელდებáƒ, რáƒáƒ“გáƒáƒœ %s დისკზე áƒáƒ  áƒáƒ áƒ˜áƒ¡ სáƒáƒ™áƒ›áƒáƒ áƒ˜áƒ¡áƒ˜ სივრცე." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" msgstr "" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" msgstr "" #. ///////////////////////////////////////////////////////////////////////// @@ -247,1258 +458,1336 @@ msgstr "" #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "დიáƒáƒ®" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "áƒáƒ áƒ" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "OK" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "დáƒáƒ®áƒ›áƒáƒ áƒ”ბáƒ" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "გáƒáƒ£áƒ¥áƒ›áƒ”ბáƒ" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "" -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." msgstr "" -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "" -#: Client/loader/Dialogs.cpp:678 -msgid "Searching for Grand Theft Auto San Andreas" -msgstr "" - -#: Client/loader/Dialogs.cpp:681 -msgid "Please start Grand Theft Auto San Andreas" +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." msgstr "" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" msgstr "" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." +#: Client/loader/Dialogs.cpp:1024 +msgid "Searching for Grand Theft Auto San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." +#: Client/loader/Dialogs.cpp:1027 +msgid "Please start Grand Theft Auto San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" msgstr "" -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" msgstr "" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 +#. Display the status box +#: Client/core/CConnectManager.cpp:153 #, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "" +msgid "Connecting to %s:%u ..." +msgstr "უკáƒáƒ•შირდებრსერვერს %s:%u ..." -#: Client/loader/CInstallManager.cpp:376 +#: Client/core/CConnectManager.cpp:155 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" +msgid "Reconnecting to %s:%u ..." msgstr "" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "დáƒáƒ™áƒáƒ•შირებáƒ" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "" +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "კáƒáƒ•შირის დრრáƒáƒ›áƒáƒ˜áƒ¬áƒ£áƒ áƒ" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეტილიáƒ: უცნáƒáƒ‘ი პრáƒáƒ¢áƒáƒ™áƒáƒšáƒ˜" + +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეტილიáƒ: გáƒáƒ—იშულირდისტáƒáƒœáƒªáƒ˜áƒ£áƒ áƒáƒ—" + +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეტილიáƒ: კáƒáƒ•შირი დáƒáƒ˜áƒ™áƒáƒ áƒ’რდისტáƒáƒœáƒªáƒ˜áƒ£áƒ áƒáƒ“" + +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეტილიáƒ: თქვენ გáƒáƒ“ევთ ბáƒáƒœáƒ˜ áƒáƒ¦áƒœáƒ˜áƒ¨áƒœáƒ£áƒš სერვერზე" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეტილიáƒ: კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეტილირსერვერთáƒáƒœ" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეტილიáƒ: თქვენ დáƒáƒ™áƒáƒ áƒ’ეტ კáƒáƒœáƒ¢áƒáƒ¥áƒ¢áƒ˜ სერვერთáƒáƒœ" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეთილიáƒ: კáƒáƒ•შირზე უáƒáƒ áƒ˜ მიიღეთ" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "" +msgid "No such mod installed (%s)" +msgstr "áƒáƒ¡áƒ”თი რეჟიმი áƒáƒ  áƒáƒ áƒ˜áƒ¡ დáƒáƒ§áƒ”ნებული (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "ცუდ სერვერზე პáƒáƒ¡áƒ£áƒ®áƒ˜ (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "სერვერი მიუწვდáƒáƒ›áƒ”ლირ(1)" + +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" msgstr "" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" msgstr "" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" msgstr "" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" msgstr "" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" msgstr "" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" msgstr "" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." msgstr "" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" msgstr "" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." msgstr "" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" msgstr "" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" msgstr "" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA ვერ გáƒáƒ’რძელდებáƒ, რáƒáƒ“გáƒáƒœ %s დისკზე áƒáƒ  áƒáƒ áƒ˜áƒ¡ სáƒáƒ™áƒ›áƒáƒ áƒ˜áƒ¡áƒ˜ სივრცე." +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" msgstr "" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." msgstr "" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" msgstr "" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" msgstr "" -#: Client/loader/Install.cpp:265 -msgid "Unknown" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" msgstr "" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" msgstr "" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." msgstr "" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" msgstr "" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." msgstr "" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." msgstr "" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" msgstr "" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" msgstr "" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" msgstr "" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" msgstr "" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" msgstr "" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" msgstr "" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" +msgid "%3d %% completed" msgstr "" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" msgstr "" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "დრáƒ: %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "დáƒáƒ™áƒáƒ•შირებáƒ: სინტáƒáƒ¥áƒ¡áƒ˜ áƒáƒ áƒ˜áƒ¡ 'დáƒáƒ™áƒáƒ•შირებრ[ ]" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "დáƒáƒ›áƒáƒ®áƒ¡áƒáƒ•რებáƒ" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "დáƒáƒ™áƒáƒ•შირებáƒ: áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ პáƒáƒ áƒ¢áƒ˜" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "დáƒáƒ¨áƒ•ებáƒ" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "დáƒáƒ™áƒáƒ•შირებáƒ: თქვენ შედიხáƒáƒ áƒ— %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "უáƒáƒ áƒ§áƒáƒ¤áƒ" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "დáƒáƒ™áƒáƒ•შირებáƒ: თქვენ ვერ დáƒáƒ£áƒ™áƒáƒ•შირდით სერვერს %s:%u!" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "დáƒáƒ™áƒáƒ•შირებáƒ: ვერ მáƒáƒ®áƒ”რხდრგáƒáƒœáƒ¢áƒ•ირთვრმიმდინáƒáƒ áƒ” რეჟიმში" + +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "ეს გáƒáƒ’იწყვითáƒáƒ•თ კáƒáƒ•შირს áƒáƒ¦áƒœáƒ˜áƒ¨áƒœáƒ£áƒš სერვერთáƒáƒœ.\n\n" -"დáƒáƒ áƒ¬áƒ›áƒ£áƒœáƒ”ბული ხáƒáƒ áƒ— რáƒáƒ› გსურთ კáƒáƒ•შირის გáƒáƒ¬áƒ§áƒ•ეტáƒ?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "გáƒáƒ¤áƒ áƒ—ხილებრკáƒáƒ•შირის გáƒáƒ¬áƒ§áƒ•ეტის შესáƒáƒ®áƒ”ბ" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "ყველრსáƒáƒ•áƒáƒšáƒ“ებულრკáƒáƒœáƒ¢áƒ áƒáƒšáƒ˜ GTA-დáƒáƒœ" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "შეინáƒáƒ®áƒ კáƒáƒœáƒ¤áƒ˜áƒ’ურáƒáƒªáƒ˜áƒ˜áƒ¡ ფáƒáƒ˜áƒšáƒ˜" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "თქვენი სერიული ნáƒáƒ›áƒ”რი áƒáƒ áƒ˜áƒ¡: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "პáƒáƒ áƒáƒ›áƒ”ტრები" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "áƒáƒœáƒšáƒáƒ˜áƒœ თáƒáƒ›áƒáƒ¨áƒ˜" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "ვიდეáƒ" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "áƒáƒ£áƒ“იáƒ" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "კáƒáƒœáƒ¢áƒ áƒáƒšáƒ”ბი" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "კáƒáƒœáƒ¢áƒ áƒáƒšáƒ”ბი" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "ინტერფეისი" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "დáƒáƒ›áƒáƒ¢áƒ”ბითი" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "მáƒáƒ£áƒ¡áƒ˜áƒ— ფრენáƒ" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "ჯáƒáƒ˜áƒ¡áƒ¢áƒ˜áƒ™áƒ˜áƒ¡ პáƒáƒ áƒáƒ›áƒ”ტრები" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "სტáƒáƒœáƒ“áƒáƒ áƒ¢áƒ£áƒšáƒ˜ კáƒáƒœáƒ¢áƒ áƒáƒšáƒ˜ (მáƒáƒ£áƒ¡áƒ˜ + კლáƒáƒ•იáƒáƒ¢áƒ£áƒ áƒ)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "კლáƒáƒ¡áƒ˜áƒ™áƒ£áƒ áƒ˜ კáƒáƒœáƒ¢áƒ áƒáƒšáƒ˜ (ჯáƒáƒ˜áƒ¡áƒ¢áƒ˜áƒ™áƒ˜)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "მკვდáƒáƒ áƒ˜ ზáƒáƒœáƒ" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "ნáƒáƒ¯áƒ”რáƒáƒ‘áƒ" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "გáƒáƒ›áƒáƒ˜áƒ§áƒ”ნე 'ღილáƒáƒ™áƒ”ბი' კáƒáƒ˜áƒ¡áƒ¢áƒ˜áƒ™áƒ˜áƒ¡áƒ—ვის." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "მáƒáƒ áƒªáƒ®áƒ”ნრჯáƒáƒ®áƒ˜" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "მáƒáƒ áƒ¯áƒ•ენრჯáƒáƒ®áƒ˜" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "áƒáƒ¦áƒ¬áƒ”რáƒ" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "ნიკნეიმი:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "სერვერის ბრáƒáƒ£áƒ–ერის áƒáƒ•ტáƒáƒ›áƒáƒ¢áƒ£áƒ áƒ˜ გáƒáƒœáƒáƒ®áƒšáƒ”ბáƒ" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "დáƒáƒ£áƒ¨áƒ•ით ეკრáƒáƒœáƒ˜áƒ¡ áƒáƒ¢áƒ•ირთვáƒ" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "გáƒáƒ›áƒáƒ˜áƒ§áƒ”ნეთ მáƒáƒ áƒ’ებული GTA:SA ფáƒáƒ˜áƒšáƒ”ბი" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "გáƒáƒ›áƒ­áƒ•ირვáƒáƒšáƒáƒ‘áƒ:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "რáƒáƒ“იáƒáƒ¡ ხმáƒ" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "თáƒáƒ›áƒáƒ¨áƒ˜áƒ¡ ხმáƒ" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA-ს ხმáƒ" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "მიკრáƒáƒ¤áƒáƒœáƒ˜áƒ¡ ხმáƒ" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "თáƒáƒ›áƒáƒ¨áƒ˜áƒ¡ რეჟიმი" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "მთáƒáƒ•áƒáƒ áƒ˜" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "რáƒáƒ“იáƒ" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "შემთხვევითი" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "თáƒáƒœáƒ›áƒ˜áƒ›áƒ“ევრული" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "მედიის სკáƒáƒœáƒ˜áƒ áƒ”ბრáƒáƒ•ტáƒáƒ›áƒáƒ¢áƒ£áƒ áƒáƒ“" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "გáƒáƒ áƒ©áƒ”ვáƒáƒ“áƒáƒ‘áƒ" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "მხედველáƒáƒ‘ის რáƒáƒ“იუსი:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "გáƒáƒœáƒáƒ—ებáƒ:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "გრáƒáƒ¤áƒ˜áƒ™áƒ˜áƒ¡ ხáƒáƒ áƒ˜áƒ¡áƒ®áƒ˜" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "ფილტრáƒáƒªáƒ˜áƒ" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "დáƒáƒ‘áƒáƒšáƒ˜" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "სáƒáƒ¨áƒ£áƒáƒšáƒ" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "მáƒáƒ¦áƒáƒšáƒ˜" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "ძáƒáƒšáƒ˜áƒáƒœ მáƒáƒ¦áƒáƒšáƒ˜" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "გáƒáƒ›áƒáƒ áƒ—" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "áƒáƒ•ტáƒáƒ›áƒáƒ¢áƒ£áƒ áƒ˜" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "მáƒáƒªáƒ£áƒšáƒáƒ‘ითი ჩრდილები" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "ბáƒáƒšáƒáƒ®áƒ˜áƒ¡ ეფექტი" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "დáƒáƒ‘ლáƒáƒ™áƒ•áƒ" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "დáƒáƒ›áƒ”ნი" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "დáƒáƒ›áƒ”ინის წáƒáƒ¨áƒšáƒ" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "დáƒáƒ¨áƒ•ებáƒ" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "სხვáƒáƒ“áƒáƒ¡áƒ®áƒ•áƒ" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "ჩáƒáƒ áƒ—" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "ძáƒáƒšáƒ˜áƒáƒœ ნელი" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "სწრáƒáƒ¤áƒ˜" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "სáƒáƒ¨áƒ£áƒáƒšáƒ" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "სáƒáƒ¨áƒ£áƒáƒšáƒáƒ–ე მáƒáƒ¦áƒáƒšáƒ˜" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "მინ" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "მáƒáƒ¥áƒ¡" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "ენáƒ:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "სკინი:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "მáƒáƒ›áƒáƒ áƒ—ვáƒ:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "ჩáƒáƒ—ი" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "ჩáƒáƒ¢áƒ•ირთვáƒ" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "პáƒáƒ áƒáƒ›áƒ”ტრები" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "ჩáƒáƒ—ის ტექსტი:" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "ჩáƒáƒ¡áƒ•ით ტექსტი" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "ხáƒáƒ–ები" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "მáƒáƒ áƒªáƒ®áƒœáƒ˜áƒ•" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "მáƒáƒ áƒ¯áƒ•ნივ" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "ფáƒáƒœáƒ¢áƒ˜" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "" @@ -1506,661 +1795,370 @@ msgstr "" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "წითელი:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "მწვáƒáƒœáƒ”:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "ლურჯი:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "გáƒáƒ›áƒ­áƒ˜áƒ áƒ•áƒáƒšáƒ”:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "ფერი" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "გáƒáƒ“áƒáƒ®áƒ”დვáƒ" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" "Are you sure you want to use them?" msgstr "" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" "Are you sure you want to enable this option?" msgstr "" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "" -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "" -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "" -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "" -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "" -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" -msgstr "" - -#: Client/core/CSettings.cpp:4997 -msgid "Enable 16 bit color modes - Requires MTA restart" -msgstr "" - -#: Client/core/CSettings.cpp:4999 -msgid "Mouse fix:" -msgstr "" - -#: Client/core/CSettings.cpp:4999 -msgid "Mouse movement fix - May need PC restart" -msgstr "" - -#: Client/core/CSettings.cpp:5001 -msgid "CPU affinity:" -msgstr "" - -#: Client/core/CSettings.cpp:5001 -msgid "Only change if you're having stability issues." -msgstr "" - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "უცნáƒáƒ‘ი ბრძáƒáƒœáƒ”ბáƒ" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "უკáƒáƒ•შირდებრსერვერს %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "დáƒáƒ™áƒáƒ•შირებáƒ" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "კáƒáƒ•შირის დრრáƒáƒ›áƒáƒ˜áƒ¬áƒ£áƒ áƒ" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეტილიáƒ: უცნáƒáƒ‘ი პრáƒáƒ¢áƒáƒ™áƒáƒšáƒ˜" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეტილიáƒ: გáƒáƒ—იშულირდისტáƒáƒœáƒªáƒ˜áƒ£áƒ áƒáƒ—" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეტილიáƒ: კáƒáƒ•შირი დáƒáƒ˜áƒ™áƒáƒ áƒ’რდისტáƒáƒœáƒªáƒ˜áƒ£áƒ áƒáƒ“" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეტილიáƒ: თქვენ გáƒáƒ“ევთ ბáƒáƒœáƒ˜ áƒáƒ¦áƒœáƒ˜áƒ¨áƒœáƒ£áƒš სერვერზე" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეტილიáƒ: კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეტილირსერვერთáƒáƒœ" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეტილიáƒ: თქვენ დáƒáƒ™áƒáƒ áƒ’ეტ კáƒáƒœáƒ¢áƒáƒ¥áƒ¢áƒ˜ სერვერთáƒáƒœ" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "კáƒáƒ•შირი გáƒáƒ¬áƒ§áƒ•ეთილიáƒ: კáƒáƒ•შირზე უáƒáƒ áƒ˜ მიიღეთ" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "áƒáƒ¡áƒ”თი რეჟიმი áƒáƒ  áƒáƒ áƒ˜áƒ¡ დáƒáƒ§áƒ”ნებული (%s)" +msgstr "" -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "ცუდ სერვერზე პáƒáƒ¡áƒ£áƒ®áƒ˜ (2)" +#: Client/core/CSettings.cpp:6039 +msgid "Enable 16 bit color modes - Requires MTA restart" +msgstr "" -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "სერვერი მიუწვდáƒáƒ›áƒ”ლირ(1)" +#: Client/core/CSettings.cpp:6041 +msgid "Mouse fix:" +msgstr "" -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" +#: Client/core/CSettings.cpp:6041 +msgid "Mouse movement fix - May need PC restart" msgstr "" -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" +#: Client/core/CSettings.cpp:6043 +msgid "CPU affinity:" msgstr "" -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "კáƒáƒœáƒ¡áƒáƒšáƒ˜" +#: Client/core/CSettings.cpp:6043 +msgid "Only change if you're having stability issues." +msgstr "" -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "შეცდáƒáƒ›áƒ" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "გáƒáƒ›áƒáƒ¡áƒáƒ¡áƒ¬áƒáƒ áƒ”ბლáƒáƒ“, წáƒáƒ¨áƒáƒšáƒ”თ შემდეგი ფáƒáƒ˜áƒšáƒ˜:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s მáƒáƒ“ული áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜áƒ!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "ეს დáƒáƒ›áƒ®áƒ›áƒáƒ áƒ” გვერდი" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "თáƒáƒ›áƒáƒ¨áƒ˜áƒ“áƒáƒœ გáƒáƒ¡áƒ•ლáƒ" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "áƒáƒ©áƒ•ენებს hud-ს" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "ყველრკáƒáƒœáƒ¢áƒ áƒáƒšáƒ˜áƒ¡ ჩვენებáƒ" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "თქვენი სერიული ნáƒáƒ›áƒ áƒ˜áƒ¡ ჩვენებáƒ" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "უკáƒáƒ•შირდებრსერვერს (host port nick pass)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "უკáƒáƒ•შირდებრწინრსერვერს" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "დáƒáƒáƒ§áƒ”ნეთ კáƒáƒœáƒ¢áƒ áƒáƒšáƒ˜" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "გáƒáƒáƒ£áƒ¥áƒ›áƒ”თ კáƒáƒœáƒ¢áƒ áƒáƒšáƒ˜ (key)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "დáƒáƒáƒ§áƒ”ნეთ სტáƒáƒœáƒ“áƒáƒ áƒ¢áƒ£áƒšáƒ˜ კáƒáƒœáƒ¢áƒ áƒáƒšáƒ˜" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "შედეგები სკრინშáƒáƒ¢áƒ˜-ზე" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "" -#: Client/core/CCore.cpp:1391 +#: Client/core/CCore.cpp:1494 msgid "clears the debug view" msgstr "" -#: Client/core/CCore.cpp:1392 +#: Client/core/CCore.cpp:1495 msgid "scrolls the chatbox upwards" msgstr "" -#: Client/core/CCore.cpp:1393 +#: Client/core/CCore.cpp:1496 msgid "scrolls the chatbox downwards" msgstr "" -#: Client/core/CCore.cpp:1394 +#: Client/core/CCore.cpp:1497 msgid "scrolls the debug view upwards" msgstr "" -#: Client/core/CCore.cpp:1395 +#: Client/core/CCore.cpp:1498 msgid "scrolls the debug view downwards" msgstr "" -#: Client/core/CCore.cpp:1398 +#: Client/core/CCore.cpp:1501 msgid "shows the memory statistics" msgstr "" -#: Client/core/CCore.cpp:1399 +#: Client/core/CCore.cpp:1502 msgid "shows the frame timing graph" msgstr "" -#: Client/core/CCore.cpp:1403 +#: Client/core/CCore.cpp:1506 msgid "for developers: reload news" msgstr "" -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" msgstr "" -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "დრáƒ: %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." msgstr "" -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "დáƒáƒ™áƒáƒ•შირებáƒ: სინტáƒáƒ¥áƒ¡áƒ˜ áƒáƒ áƒ˜áƒ¡ 'დáƒáƒ™áƒáƒ•შირებრ[ ]" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "დáƒáƒ™áƒáƒ•შირებáƒ: áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ პáƒáƒ áƒ¢áƒ˜" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "დáƒáƒ™áƒáƒ•შირებáƒ: თქვენ შედიხáƒáƒ áƒ— %s:%u..." - -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "დáƒáƒ™áƒáƒ•შირებáƒ: თქვენ ვერ დáƒáƒ£áƒ™áƒáƒ•შირდით სერვერს %s:%u!" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "ეს გáƒáƒ’იწყვითáƒáƒ•თ კáƒáƒ•შირს áƒáƒ¦áƒœáƒ˜áƒ¨áƒœáƒ£áƒš სერვერთáƒáƒœ.\n\n" +"დáƒáƒ áƒ¬áƒ›áƒ£áƒœáƒ”ბული ხáƒáƒ áƒ— რáƒáƒ› გსურთ კáƒáƒ•შირის გáƒáƒ¬áƒ§áƒ•ეტáƒ?" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "დáƒáƒ™áƒáƒ•შირებáƒ: ვერ მáƒáƒ®áƒ”რხდრგáƒáƒœáƒ¢áƒ•ირთვრმიმდინáƒáƒ áƒ” რეჟიმში" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "გáƒáƒ¤áƒ áƒ—ხილებრკáƒáƒ•შირის გáƒáƒ¬áƒ§áƒ•ეტის შესáƒáƒ®áƒ”ბ" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" msgstr "" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" msgstr "" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" msgstr "" -#: Client/core/CCommandFuncs.cpp:325 +#: Client/core/CScreenShot.cpp:200 #, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "ყველრსáƒáƒ•áƒáƒšáƒ“ებულრკáƒáƒœáƒ¢áƒ áƒáƒšáƒ˜ GTA-დáƒáƒœ" +msgid "Screenshot got %d bytes, but expected %d" +msgstr "სქრინშáƒáƒ—ი იშáƒáƒ•რ%d ბáƒáƒ˜áƒ¢áƒ”ბში, მáƒáƒ’რáƒáƒ› მáƒáƒ¡áƒáƒšáƒáƒ“ნელირ%d" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "შეინáƒáƒ®áƒ კáƒáƒœáƒ¤áƒ˜áƒ’ურáƒáƒªáƒ˜áƒ˜áƒ¡ ფáƒáƒ˜áƒšáƒ˜" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "სქრინშáƒáƒ—ი ვერ მáƒáƒ®áƒ”რხდáƒ" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 +#: Client/core/CScreenShot.cpp:256 #, c-format -msgid "* Your serial is: %s" -msgstr "თქვენი სერიული ნáƒáƒ›áƒ”რი áƒáƒ áƒ˜áƒ¡: %s" - -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "" - -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "" - -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "პრáƒáƒ’რáƒáƒ›áƒ˜áƒ áƒ”ბáƒ" - -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "დáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ები" - -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "თáƒáƒ›áƒáƒ¨áƒ˜áƒ¡ დიზáƒáƒ˜áƒœáƒ˜ / კáƒáƒ“ირებáƒ" - -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "ენის ლáƒáƒ™áƒáƒšáƒ˜áƒ–áƒáƒªáƒ˜áƒ" - -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "პáƒáƒ¢áƒ©áƒ˜áƒ¡ დáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ები" - -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "გáƒáƒœáƒ¡áƒáƒ™áƒ£áƒ—რებული მáƒáƒ“ლáƒáƒ‘áƒ" - -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" +msgid "Screenshot taken: '%s'" msgstr "" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "უცნáƒáƒ‘ი ბრძáƒáƒœáƒ”ბáƒ" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2335,30 +2333,116 @@ msgid "Group control backwards" msgstr "ჯგუფური კáƒáƒœáƒ¢áƒ áƒáƒšáƒ˜ უკáƒáƒœ" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "" -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "სქრინშáƒáƒ—ი იშáƒáƒ•რ%d ბáƒáƒ˜áƒ¢áƒ”ბში, მáƒáƒ’რáƒáƒ› მáƒáƒ¡áƒáƒšáƒáƒ“ნელირ%d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "სქრინშáƒáƒ—ი ვერ მáƒáƒ®áƒ”რხდáƒ" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "კáƒáƒœáƒ¡áƒáƒšáƒ˜" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "პრáƒáƒ’რáƒáƒ›áƒ˜áƒ áƒ”ბáƒ" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "დáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ები" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "თáƒáƒ›áƒáƒ¨áƒ˜áƒ¡ დიზáƒáƒ˜áƒœáƒ˜ / კáƒáƒ“ირებáƒ" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "ენის ლáƒáƒ™áƒáƒšáƒ˜áƒ–áƒáƒªáƒ˜áƒ" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "პáƒáƒ¢áƒ©áƒ˜áƒ¡ დáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ები" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "გáƒáƒœáƒ¡áƒáƒ™áƒ£áƒ—რებული მáƒáƒ“ლáƒáƒ‘áƒ" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" msgstr "" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." msgstr "" +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "" +msgstr[1] "" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "" +msgstr[1] "" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "მიმდინáƒáƒ áƒ”áƒáƒ‘ს სერვერების áƒáƒ¦áƒ›áƒáƒ©áƒ”ნრLAN-ში" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2412,7 +2496,7 @@ msgstr "შეყáƒáƒ•ნებáƒ" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "" @@ -2439,337 +2523,405 @@ msgstr "შედით სერვერზე მáƒáƒšáƒ” რáƒáƒ’áƒáƒ áƒª msgid "PLEASE ENTER SERVER PASSWORD" msgstr "გთხáƒáƒ•თ შეიყვáƒáƒœáƒáƒ— სერვერის პáƒáƒ áƒáƒšáƒ˜" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "ვáƒáƒ“áƒáƒ’áƒáƒ¡áƒ£áƒšáƒ˜áƒ" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "ეკითხებáƒ..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "დáƒáƒ®áƒ›áƒáƒ áƒ”ბáƒ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "გáƒáƒœáƒáƒ®áƒšáƒ”ბáƒ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "ფáƒáƒ•áƒáƒ áƒ˜áƒ—ებში დáƒáƒ›áƒáƒ¢áƒ”ბáƒ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "დáƒáƒ™áƒáƒ•შირებáƒ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "ინფáƒáƒ áƒ›áƒáƒªáƒ˜áƒ სერვერის შესáƒáƒ®áƒ”ბ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "მáƒáƒ«áƒ”ბნე სერვერები" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "მáƒáƒ«áƒ”ბნეთ მáƒáƒ—áƒáƒ›áƒáƒ¨áƒ”ები" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "ძიების დáƒáƒ¬áƒ§áƒ”ბáƒ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "მáƒáƒ—áƒáƒ›áƒáƒ¨áƒ”ების ძიებáƒ..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "დáƒáƒ‘ლáƒáƒ™áƒ˜áƒšáƒ˜áƒ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "კáƒáƒ•შირგáƒáƒ áƒ”შე" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "სხვრვერსიები" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "უკáƒáƒœ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "იტვირთებáƒ..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "..იტვირთებáƒ.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "მისáƒáƒ›áƒáƒ áƒ—ი áƒáƒ  áƒáƒ áƒ˜áƒ¡ მითითებული!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "უცნáƒáƒ‘ი პრáƒáƒ¢áƒáƒ™áƒáƒšáƒ˜" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "" -msgstr[1] "" - -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "" -msgstr[1] "" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "მიმდინáƒáƒ áƒ”áƒáƒ‘ს სერვერების áƒáƒ¦áƒ›áƒáƒ©áƒ”ნრLAN-ში" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "დáƒáƒ›áƒáƒ®áƒ¡áƒáƒ•რებáƒ" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "უáƒáƒ áƒ§áƒáƒ¤áƒ" + +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "" -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "" @@ -2790,188 +2942,188 @@ msgstr "" msgid "Disconnect to cancel download" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "" msgstr[1] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "" msgstr[1] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "" msgstr[1] "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -2979,295 +3131,205 @@ msgstr[0] "" msgstr[1] "" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "" - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" +msgid "Download error: %s" msgstr "" #. Populate the message and show the box @@ -3289,11 +3351,11 @@ msgstr "" msgid "Connection error" msgstr "" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "" -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "" diff --git a/Shared/data/MTA San Andreas/MTA/locale/ko_KR/client.pot b/Shared/data/MTA San Andreas/MTA/locale/ko_KR/client.pot index 09381a0a419..a5a0499a8e2 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/ko_KR/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/ko_KR/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Korean\n" "Language: ko_KR\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "MTA:SA를 다시 시작하는 ë™ì•ˆ 문제가 ë°œìƒí–ˆìŠµë‹ˆë‹¤.\n\n" -"문제가 ì§€ì†ë˜ë©´ 작업 관리ìžë¥¼ ì—´ê³ \n" -"gta_sa.exe' ë° 'Multi Treft Auto.exe' 프로세스를 중지하십시오.\n\n\n" -"MTA:SA를 다시 시작하시겠습니까?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "오류" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "다른 MTA ì¸ìŠ¤í„´ìŠ¤ê°€ ì´ë¯¸ 실행 중입니다.\n\n" -"ì´ ë¬¸ì œê°€ ì§€ì†ë˜ë©´ 컴퓨터를 다시 시작하십시오." +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "다른 MTA ì¸ìŠ¤í„´ìŠ¤ê°€ ì´ë¯¸ 실행 중입니다.\n\n" -"종료하시겠습니까?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Grand Theft Auto: San Andreasê°€ ì„¤ì¹˜ëœ í´ë”를 지정하십시오" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "ì•„ëž˜ì˜ ìž‘ì—…ì„ ìˆ˜í–‰í•˜ê¸° 위해 MTA:SA는 ê´€ë¦¬ìž ê¶Œí•œì´ í•„ìš”í•©ë‹ˆë‹¤:\n\n" +" '%s'\n\n" +"ë‹¤ìŒ ì°½ì—서 확ì¸í•˜ì‹­ì‹œì˜¤." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "%s ëª¨ë“ˆì„ ë¶ˆëŸ¬ì˜¤ëŠ”ë° ì˜¤ë¥˜ê°€ ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "íŒŒì¼ ë³µì‚¬ 중..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "복사가 ì¼ì° ë났습니다. 모든 ê²ƒì´ ì¢‹ìŠµë‹ˆë‹¤." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "마무리 짓는 중..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "완료!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "%sì˜ ìƒˆ 설치가 ê°ì§€ë˜ì—ˆìŠµë‹ˆë‹¤.\n\n" +"%sì—서 ì„¤ì •ì„ ë³µì‚¬í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SAì—서 '%s' 파ì¼ì„ 여는 ë° ë¬¸ì œê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤." + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SAì— '%s' 파ì¼ì´ 없습니다." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SAì—서 모ë¸ì„ 불러오는 ë° ë¬¸ì œê°€ 있었습니다." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "ìµœê·¼ì— gta3.img를 수정한 경우 GTA:SA를 다시 설치해 보십시오." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SAì—서 ì°¨ëŸ‰ì— ì—…ê·¸ë ˆì´ë“œë¥¼ 추가하는 ë° ë¬¸ì œê°€ 있었습니다." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SAê°€ '%s' 파ì¼ì—서 오류를 발견했습니다." + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "MTA:SA를 플레ì´í•  때 컴퓨터가 다시 시작ë˜ì—ˆìŠµë‹ˆê¹Œ?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "계ì†í•˜ê¸° ì „ì— ë‹¤ìŒ í”„ë¡œê·¸ëž¨ì„ ì¢…ë£Œí•˜ì‹­ì‹œì˜¤:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "íŒŒì¼ ë²„ì „ì´ ì¼ì¹˜í•˜ì§€ 않습니다. 문제가 ë°œìƒí•˜ë©´ MTA:SA를 다시 설치하십시오.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "ì¼ë¶€ 파ì¼ì´ 없습니다. 문제가 ë°œìƒí•˜ë©´ MTA:SA를 다시 설치하십시오.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA는 Windows '안전 모드'와 호환ë˜ì§€ 않습니다.\n\n" +"PC를 다시 시작하십시오.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "MTA:SA를 실행하는 ë° ë¬¸ì œê°€ 있습니까?\n\n" "ì´ì „ 버전으로 ë˜ëŒë¦¬ì‹œê² ìŠµë‹ˆê¹Œ?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "MTA:SA를 시작하는 ë° ë¬¸ì œê°€ 있는 것 같습니다.\n" "GTA ì„¤ì •ì„ ìž¬ì„¤ì •í•˜ë©´ ì´ ë¬¸ì œê°€ í•´ê²°ë  ìˆ˜ 있습니다.\n\n" "지금 GTA ì„¤ì •ì„ ìž¬ì„¤ì •í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA ì„¤ì •ì´ ìž¬ì„¤ì •ë˜ì—ˆìŠµë‹ˆë‹¤.\n\n" "계ì†í•˜ë ¤ë©´ 확ì¸ì„ 누르십시오." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "'%s' 파ì¼ì„ 삭제할 수 없습니다." #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "MTA:SA를 실행하는 ë° ë¬¸ì œê°€ 있습니까?\n\n" "온ë¼ì¸ ë„움ë§ì„ 보시겠습니까?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "MTA:SA를 실행하는 ë° ë¬¸ì œê°€ 있습니까?\n\n" "ë‹¤ìŒ ì„¤ì •ì„ ë³€ê²½í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "ì „ì²´ 화면 모드:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "경계 없는 ì°½ 모드" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "MTA:SA를 실행하는 ë° ë¬¸ì œê°€ 있습니까?\n\n" "GTA ë° MTAì— ëŒ€í•´ ë‹¤ìŒ ì œí’ˆì„ ë¹„í™œì„±í™”í•´ 보십시오:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +189,293 @@ msgstr "경고문\n\n" "MTA:SAê°€ 비정ìƒì ì¸ 활ë™ì„ ê°ì§€í–ˆìŠµë‹ˆë‹¤.\n" "ë°”ì´ëŸ¬ìФ 검사를 실행하여 ì‹œìŠ¤í…œì´ ì•ˆì „í•œì§€ 확ì¸í•˜ì‹­ì‹œì˜¤.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "íƒì§€ëœ 파ì¼: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "GTA ì¸ìŠ¤í„´ìŠ¤: GTA: San Andreasê°€ ì´ë¯¸ 실행 중입니다. MTA:SA를 시작하기 ì „ì— ì¢…ë£Œí•´ì•¼ 합니다. 지금하시겠습니까?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "ì •ë³´" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "GTA: San Andreas를 종료할 수 없습니다. 문제가 ì§€ì†ë˜ë©´ 컴퓨터를 다시 시작하십시오." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "MTA:SA를 다시 시작하는 ë™ì•ˆ 문제가 ë°œìƒí–ˆìŠµë‹ˆë‹¤.\n\n" +"문제가 ì§€ì†ë˜ë©´ 작업 관리ìžë¥¼ ì—´ê³ \n" +"gta_sa.exe' ë° 'Multi Treft Auto.exe' 프로세스를 중지하십시오.\n\n\n" +"MTA:SA를 다시 시작하시겠습니까?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "오류" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "다른 MTA ì¸ìŠ¤í„´ìŠ¤ê°€ ì´ë¯¸ 실행 중입니다.\n\n" +"ì´ ë¬¸ì œê°€ ì§€ì†ë˜ë©´ 컴퓨터를 다시 시작하십시오." + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "다른 MTA ì¸ìŠ¤í„´ìŠ¤ê°€ ì´ë¯¸ 실행 중입니다.\n\n" +"종료하시겠습니까?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "레지스트리 í•­ëª©ì´ ì—†ìŠµë‹ˆë‹¤. Multi Theft Auto: San Andreas를 다시 설치하십시오." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "GTA: San Andreas 설치 ê²½ë¡œì— ì§€ì›ë˜ì§€ 않는(유니코드) 문ìžê°€ í¬í•¨ë˜ì–´ 있습니다. Grand Theft Auto: San Andreas 설치를 표준 ASCII 문ìžë§Œ í¬í•¨ëœ 호환ë˜ëŠ” 경로로 ì´ë™í•˜ê³  Multi Theft Auto: San Andreas를 다시 설치하십시오." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "'MTA:SA' ë˜ëŠ” 'GTA:San Andreas' 설치 경로\n" -"ì—는 ';'(세미í´ë¡ )ì´ í¬í•¨ë©ë‹ˆë‹¤.\n\n" -" MTA:SA를 실행할 때 문제가 ë°œìƒí•  경우,\n" -" 설치를 세미í´ë¡ ì„ í¬í•¨í•˜ì§€ 않는 경로로 ì´ë™í•©ë‹ˆë‹¤." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "ë¡œë“œì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤. 최신 ë°ì´í„° 파ì¼ì´ 올바르게 설치ë˜ì—ˆëŠ”ì§€ 확ì¸í•˜ì‹­ì‹œì˜¤." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "ë¡œë“œì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤. %sì´(ê°€) 올바르게 설치ë˜ì—ˆëŠ”ì§€ 확ì¸í•˜ì‹­ì‹œì˜¤." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "ë¡œë“œì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤. %sì—서 gta_sa.exe를 ì°¾ì„ ìˆ˜ 없습니다." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "ë¡œë“œì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤. %sì´(ê°€) GTA ë””ë ‰í† ë¦¬ì— ìžˆìŠµë‹ˆë‹¤. 계ì†í•˜ê¸° ì „ì— ì‚­ì œí•˜ì‹­ì‹œì˜¤." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "주 파ì¼ì˜ ì´ë¦„(%s)ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤." -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "기본 파ì¼ì´ 서명ë˜ì§€ 않았습니다. ë°”ì´ëŸ¬ìФ í™œë™ ê°€ëŠ¥ì„±ì´ ìžˆìŠµë‹ˆë‹¤.\n\n" -"MTAê°€ 올바르게 ìž‘ë™í•˜ì§€ 않는 경우 온ë¼ì¸ ë„움ë§ì„ 참조하십시오." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "ë°ì´í„° íŒŒì¼ %sì´(ê°€) 없습니다. ë°”ì´ëŸ¬ìФ í™œë™ ê°€ëŠ¥ì„±ì´ ìžˆìŠµë‹ˆë‹¤.\n\n" -"ë³´ì•ˆì„ ìœ„í•´ Multi Theft Auto를 다시 설치하는 ê²ƒì„ ê³ ë ¤í•´ 보십시오.\n" -"MTAê°€ 올바르게 ìž‘ë™í•˜ì§€ 않는 경우 온ë¼ì¸ ë„움ë§ì„ 참조하십시오." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "%s ë°ì´í„° 파ì¼ì´ 수정ë˜ì—ˆìŠµë‹ˆë‹¤. ë°”ì´ëŸ¬ìФ í™œë™ ê°€ëŠ¥ì„±ì´ ìžˆìŠµë‹ˆë‹¤.\n\n" -"ë³´ì•ˆì„ ìœ„í•´ Multi Theft Auto를 다시 설치하는 ê²ƒì„ ê³ ë ¤í•´ 보십시오.\n" -"MTAê°€ 올바르게 ìž‘ë™í•˜ì§€ 않는 경우 온ë¼ì¸ ë„움ë§ì„ 참조하십시오." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asi 파ì¼ì´ 'MTA:SA' ë˜ëŠ” 'GTA:San Andreas' 설치 ë””ë ‰í† ë¦¬ì— ìžˆìŠµë‹ˆë‹¤.\n\n" -"MTA:SAì—서 문제가 ë°œìƒí•˜ë©´ ì´ëŸ¬í•œ .asi 파ì¼ì„ 제거합니다." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "íŒŒì¼ ë²„ì „ì´ ì¼ì¹˜í•˜ì§€ 않습니다. 문제가 ë°œìƒí•˜ë©´ MTA:SA를 다시 설치하십시오.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "ì¼ë¶€ 파ì¼ì´ 없습니다. 문제가 ë°œìƒí•˜ë©´ MTA:SA를 다시 설치하십시오.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA는 Windows '안전 모드'와 호환ë˜ì§€ 않습니다.\n\n" -"PC를 다시 시작하십시오.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "구성 문제 í•´ê²°" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "ê³ ë„ ìˆ˜ì •ì´ í•„ìš”í•œ 오류" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "알 수 ì—†ìŒ" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "'%s' 파ì¼ì´ 현재 %zu í”„ë¡œì„¸ìŠ¤ì— ì˜í•´ 잠겨 있습니다.\n\n" +"ë‹¤ìŒ í”„ë¡œì„¸ìŠ¤ë¥¼ 종료하고 ì—…ë°ì´íŠ¸ë¥¼ 계ì†í•˜ì‹œê² ìŠµë‹ˆê¹Œ?\n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "설치가 ì†ìƒë˜ì—ˆì„ 수 있습니다.\n\n" +"%zu íŒŒì¼ ì¤‘ %zu 파ì¼ì„ 백업ì—서 ë³µì›í•  수 없습니다.\n\n" +"www.multitheftauto.com ì—서 Multi Treft Auto를 다시 설치해야 합니다.\n" +"ë˜ëŠ” ê´€ë¦¬ìž ê¶Œí•œìœ¼ë¡œ ì—…ë°ì´íŠ¸ë¥¼ 실행해 보십시오." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "ì—…ë°ì´íЏ 설치 중..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "파ì¼ì„ 추출하는 중..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SAê°€ ë‹¤ìŒ ìž‘ì—…ì„ ì™„ë£Œí•  수 없습니다:\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** 그래픽 드ë¼ì´ë²„ 오류로 ì¸í•œ ì¶©ëŒ **\n\n" +"** 그래픽 드ë¼ì´ë²„ **를 ì—…ë°ì´íŠ¸í•˜ì‹­ì‹œì˜¤" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "ì—…ë°ì´íŠ¸ëœ MTA:SA íŒŒì¼ ì„¤ì¹˜" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "íŒŒì¼ ì¶©ëŒë¡œ ì¸í•´ ì—…ë°ì´íŠ¸í•  수 없습니다. 다른 ì‘ìš© í”„ë¡œê·¸ëž¨ì„ ë‹«ê³  다시 시ë„하십시오" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Autoê°€ 제대로 설치ë˜ì§€ 않았습니다. 다시 설치하십시오. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "GTA:SA ì •ì…˜ ìƒì„±" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "íŒŒì¼ ë³µì‚¬ì— ì‹¤íŒ¨í–ˆê¸° ë•Œë¬¸ì— MTA:SA를 시작할 수 없습니다:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA 파ì¼ì´ 잘못ë˜ì—ˆê±°ë‚˜ 누ë½ë˜ì–´ MTA:SA를 시작할 수 없습니다:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "MTA:SA íŒŒì¼ ë³µì‚¬" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "GTA:SA 파ì¼ì´ 잘못ë˜ì—ˆê±°ë‚˜ 누ë½ë˜ì–´ MTA:SA를 시작할 수 없습니다:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "패치 GTA:SA 종ì†ì„±" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "GTA:SA 실행 파ì¼ì´ 잘못ë˜ì—ˆê±°ë‚˜ 누ë½ë˜ì–´ MTA:SA를 시작할 수 없습니다:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "백신ì—서 ìž˜ëª»ëœ ê²€ì¶œì„ í™•ì¸í•˜ê³  GTA:SA 실행 파ì¼ì— 대한 예외를 추가한 후 MTA:SA를 다시 시작하십시오." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "GTA:SA ìƒì„±" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "GTA:SA 실행 파ì¼ì„ 로드할 수 없기 ë•Œë¬¸ì— MTA:SA를 시작할 수 없습니다:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "패치 GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "GTA:SA 패치가 실패했기 ë•Œë¬¸ì— MTA:SA를 시작할 수 없습니다:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Grand Theft Auto: San Andreas를 시작할 수 없습니다. 다시 시작해 보거나 문제가 ì§€ì†ë˜ë©´ MTA(www.multitheftauto.com)ì— ë¬¸ì˜í•˜ì‹­ì‹œì˜¤.\n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "%s 드ë¼ì´ë¸Œì— ê³µê°„ì´ ë¶€ì¡±í•˜ê¸° ë•Œë¬¸ì— MTA:SA를 계ì†í•  수 없습니다." -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreasê°€ 제대로 실행ë˜ì§€ ì•Šì•˜ì„ ìˆ˜ 있습니다. 종료하시겠습니까?" +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "누ë½ëœ 파ì¼:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "MTAê°€ 로드ë˜ì§€ 않으면 GTA:SA를 다시 설치하십시오" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "설치 설정 ì—…ë°ì´íЏ" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "호환성 설정 ì—…ë°ì´íЏ" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +483,167 @@ msgstr "GTA: San Andreasê°€ 제대로 실행ë˜ì§€ ì•Šì•˜ì„ ìˆ˜ 있습니다. #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "예" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "아니오" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "확ì¸" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "종료" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "ë„움ë§" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "취소" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreasì— ë¬¸ì œê°€ ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤." -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "ì¶©ëŒ ì •ë³´" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "ì²´í¬í•˜ë©´ 'ì¸í„°ë„·'ì„ ì‚¬ìš©í•˜ì—¬ MTA 개발ìžì—게 ì´ ì¶©ëŒ ì •ë³´ë¥¼ 보냅니다." -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "ì¶©ëŒì´ í•´ê²°ë  ê°€ëŠ¥ì„±ì´ ë†’ì•„ì§‘ë‹ˆë‹¤." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "MTA: San Andreas를 다시 시작하시겠습니까?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - 주ì˜" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "Grand Treft Auto: San Andreas 설치 ë””ë ‰í† ë¦¬ì— ë‹¤ìŒ íŒŒì¼ì´ í¬í•¨ë˜ì–´ 있습니다:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "ì´ëŸ¬í•œ 파ì¼ì€ 필요하지 않으며 ì´ ë²„ì „ì˜ MTA:SAì—서 그래픽 ê¸°ëŠ¥ì„ ë°©í•´í•  수 있습니다.\n\n" "ì´ëŸ¬í•œ 파ì¼ì„ 제거하거나 ì´ë¦„ì„ ë°”ê¾¸ëŠ” ê²ƒì´ ì¢‹ìŠµë‹ˆë‹¤." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "ì´ íŒŒì¼ì„ ìœ ì§€í•˜ë˜ ë‹¤ìŒ ì‹œìž‘ 시 ì´ ê²½ê³ ë¥¼ 표시합니다." -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "ì´ íŒŒì¼ì— 대해 다시 알려주지 않ìŒ." -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "íŒŒì¼ ì´ë¦„ì„ *.dllì—서 *.dll.bak로 변경합니다." -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "ì´ íŒŒì¼ í‘œì‹œ" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "MTA:SA 시작" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - 혼ë™ë˜ëŠ” 설정" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimusê°€ íƒì§€ë˜ì—ˆìŠµë‹ˆë‹¤!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "ê° ì˜µì…˜ì„ ì‚¬ìš©í•˜ê³  ìž‘ë™ ë‚´ìš©ì„ í™•ì¸í•˜ì‹­ì‹œì˜¤:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Standard NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Alternate NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Standard Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Alternate Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "만약 ì—¬ëŸ¬ë¶„ì´ ì ˆë§í•œë‹¤ë©´, ì´ê²ƒì€ ë„ì›€ì´ ë  ê²ƒìž…ë‹ˆë‹¤:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "ì˜µì…˜ì„ ì´ë¯¸ ì„ íƒí•œ 경우 다ìŒì— ë„ì›€ì´ ë  ìˆ˜ 있습니다:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "ê°•ì œ ì°½ 모드" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "다시 표시하지 않ìŒ" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "경고: 안티바ì´ëŸ¬ìФ ì œí’ˆì„ íƒì§€í•  수 없습니다" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1107 +651,1180 @@ msgstr "MTAê°€ PCì—서 ë°±ì‹ ì„ íƒì§€í•  수 없습니다.\n\n" "ë°”ì´ëŸ¬ìŠ¤ê°€ MTA를 방해하고 게임 í”Œë ˆì´ ê²½í—˜ì„ ì €í•˜ì‹œí‚µë‹ˆë‹¤.\n\n" "ìžì„¸í•œ ë‚´ìš©ì„ ë³´ë ¤ë©´ 'ë„움ë§'ì„ ëˆ„ë¥´ì‹­ì‹œì˜¤." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "나는 ë°±ì‹ ì„ ì´ë¯¸ 설치했습니다." -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "ë°±ì‹ ì„ ì„¤ì¹˜í•˜ì§€ 않습니다.\n" "나는 ì»´í“¨í„°ì— ë ‰ì´ ê±¸ë¦¬ê³  ë´‡ë„·ì˜ ì¼ë¶€ê°€ ë˜ì–´ë„ ìƒê´€ 없습니다." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Grand Theft Auto San Andreas를 찾는 중" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Grand Theft Auto San Andreas를 시작하십시오" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "ì—…ë°ì´íЏ 설치 중..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "ì—°ê²°ì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤. ìž˜ëª»ëœ ë‹‰ë„¤ìž„!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "파ì¼ì„ 추출하는 중..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "ì—°ê²°ì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤. ìž˜ëª»ëœ í˜¸ìŠ¤íŠ¸!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "íŒŒì¼ ë³µì‚¬ 중..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "%u í¬íЏì—서 %sì— ì—°ê²°í•˜ì§€ 못했습니다!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "복사가 ì¼ì° ë났습니다. 모든 ê²ƒì´ ì¢‹ìŠµë‹ˆë‹¤." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "%s:%u ... ì— ì—°ê²° 중" -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "마무리 짓는 중..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "완료!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "ì—°ê²° 중" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "ì•„ëž˜ì˜ ìž‘ì—…ì„ ìˆ˜í–‰í•˜ê¸° 위해 MTA:SA는 ê´€ë¦¬ìž ê¶Œí•œì´ í•„ìš”í•©ë‹ˆë‹¤:\n\n" -" '%s'\n\n" -"ë‹¤ìŒ ì°½ì—서 확ì¸í•˜ì‹­ì‹œì˜¤." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "ì—°ê²° ì‹œê°„ì´ ì´ˆê³¼ë˜ì—ˆìŠµë‹ˆë‹¤." -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SAê°€ ë‹¤ìŒ ìž‘ì—…ì„ ì™„ë£Œí•  수 없습니다:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "ì—°ê²° ëŠê¹€: 알 수 없는 프로토콜 오류" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** 그래픽 드ë¼ì´ë²„ 오류로 ì¸í•œ ì¶©ëŒ **\n\n" -"** 그래픽 드ë¼ì´ë²„ **를 ì—…ë°ì´íŠ¸í•˜ì‹­ì‹œì˜¤" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "ì—°ê²° ëŠê¹€: ì›ê²©ìœ¼ë¡œ ì—°ê²°ì´ ëŠì–´ì§" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "ì—…ë°ì´íŠ¸ëœ MTA:SA íŒŒì¼ ì„¤ì¹˜" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "ì—°ê²° ëŠê¹€: ì›ê²©ìœ¼ë¡œ ì—°ê²°ì´ ëŠì–´ì§" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "íŒŒì¼ ì¶©ëŒë¡œ ì¸í•´ ì—…ë°ì´íŠ¸í•  수 없습니다. 다른 ì‘ìš© í”„ë¡œê·¸ëž¨ì„ ë‹«ê³  다시 시ë„하십시오" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "ì—°ê²° ëŠê¹€: ì´ ì„œë²„ì—서 ë°´ë˜ì—ˆìŠµë‹ˆë‹¤" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "ì—°ê²° ëŠê¹€: ì„œë²„ì™€ì˜ ì—°ê²°ì´ ëŠì–´ì¡ŒìŠµë‹ˆë‹¤" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "ì—°ê²° ëŠê¹€: ì„œë²„ì— ëŒ€í•œ ì—°ê²°ì´ ëŠì–´ì¡ŒìŠµë‹ˆë‹¤" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "ì—°ê²° ëŠê¹€: ì—°ê²°ì´ ê±°ë¶€ë˜ì—ˆìŠµë‹ˆë‹¤" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Autoê°€ 제대로 설치ë˜ì§€ 않았습니다. 다시 설치하십시오. %s" +msgid "No such mod installed (%s)" +msgstr "해당 모드가 설치ë˜ì§€ 않았습니다(%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "GTA:SA ì •ì…˜ ìƒì„±" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "서버 ì‘답 불량(2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "íŒŒì¼ ë³µì‚¬ì— ì‹¤íŒ¨í–ˆê¸° ë•Œë¬¸ì— MTA:SA를 시작할 수 없습니다:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "서버 ì‘답 불량(1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA 파ì¼ì´ 잘못ë˜ì—ˆê±°ë‚˜ 누ë½ë˜ì–´ MTA:SA를 시작할 수 없습니다:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "한국어" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "MTA:SA íŒŒì¼ ë³µì‚¬" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "사용 중" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "GTA:SA 파ì¼ì´ 잘못ë˜ì—ˆê±°ë‚˜ 누ë½ë˜ì–´ MTA:SA를 시작할 수 없습니다:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "ì—…ë°ì´íŠ¸ë¥¼ 지금 확ì¸í•  수 없습니다." -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "패치 GTA:SA 종ì†ì„±" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %sì´(ê°€) 필요합니다." -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "GTA:SA 실행 파ì¼ì´ 잘못ë˜ì—ˆê±°ë‚˜ 누ë½ë˜ì–´ MTA:SA를 시작할 수 없습니다:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "ì„ íƒí•œ ì„œë²„ì— ì ‘ì†í•˜ë ¤ë©´ MTA:SA %sì˜ ì—…ë°ì´íЏ ë²„ì „ì´ í•„ìš”í•©ë‹ˆë‹¤.\n\n" +"MTA:SA %sì„(를) 다운로드하여 설치하시겠습니까?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "백신ì—서 ìž˜ëª»ëœ ê²€ì¶œì„ í™•ì¸í•˜ê³  GTA:SA 실행 파ì¼ì— 대한 예외를 추가한 후 MTA:SA를 다시 시작하십시오." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "MTA:SA %sì„(를) 시작하고 ì´ ì„œë²„ì— ì—°ê²°í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "GTA:SA ìƒì„±" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "ì§€ê¸ˆì€ ì—°ê²°í•  수 없습니다.\n\n" +"ë‚˜ì¤‘ì— ì‹œë„하십시오." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "GTA:SA 실행 파ì¼ì„ 로드할 수 없기 ë•Œë¬¸ì— MTA:SA를 시작할 수 없습니다:" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "ì—°ê²° 중" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "패치 GTA:SA" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "잠시 기다려 주십시오..." -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "GTA:SA 패치가 실패했기 ë•Œë¬¸ì— MTA:SA를 시작할 수 없습니다:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "í™•ì¸ ì¤‘" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "%s 드ë¼ì´ë¸Œì— ê³µê°„ì´ ë¶€ì¡±í•˜ê¸° ë•Œë¬¸ì— MTA:SA를 계ì†í•  수 없습니다." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "ì—…ë°ì´íЏ 확ì¸" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "누ë½ëœ 파ì¼:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "ì—…ë°ì´íЏ 필요없ìŒ" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "MTAê°€ 로드ë˜ì§€ 않으면 GTA:SA를 다시 설치하십시오" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "다운로드 중" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "설치 설정 ì—…ë°ì´íЏ" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "대기 중..." -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "호환성 설정 ì—…ë°ì´íЏ" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "필수 ì—…ë°ì´íЏ" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "알 수 ì—†ìŒ" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "ì´ ì„œë²„ì— ì ‘ì†í•˜ë ¤ë©´ MTA를 ì—…ë°ì´íŠ¸í•´ì•¼ 합니다.\n\n" +" 지금 ì—…ë°ì´íŠ¸í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "'%s' 파ì¼ì´ 현재 %zu í”„ë¡œì„¸ìŠ¤ì— ì˜í•´ 잠겨 있습니다.\n\n" -"ë‹¤ìŒ í”„ë¡œì„¸ìŠ¤ë¥¼ 종료하고 ì—…ë°ì´íŠ¸ë¥¼ 계ì†í•˜ì‹œê² ìŠµë‹ˆê¹Œ?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "ì„ íƒì  ì—…ë°ì´íЏ" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "설치가 ì†ìƒë˜ì—ˆì„ 수 있습니다.\n\n" -"%zu íŒŒì¼ ì¤‘ %zu 파ì¼ì„ 백업ì—서 ë³µì›í•  수 없습니다.\n\n" -"www.multitheftauto.com ì—서 Multi Treft Auto를 다시 설치해야 합니다.\n" -"ë˜ëŠ” ê´€ë¦¬ìž ê¶Œí•œìœ¼ë¡œ ì—…ë°ì´íŠ¸ë¥¼ 실행해 보십시오." +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "서버ì—서 ì—…ë°ì´íŠ¸ê°€ 권장ë˜ì§€ë§Œ 필수는 아니ë¼ê³  합니다.\n\n" +" 지금 ì—…ë°ì´íŠ¸í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "저장 오류" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "파ì¼ì„ ìƒì„±í•  수 없습니다." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Grand Theft Auto: San Andreasê°€ ì„¤ì¹˜ëœ í´ë”를 지정하십시오" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "다운로드 오류" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "%s ëª¨ë“ˆì„ ë¶ˆëŸ¬ì˜¤ëŠ”ë° ì˜¤ë¥˜ê°€ ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤! (%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "다운로드한 파ì¼ì´ 올바르지 ì•Šì€ ê²ƒ 같습니다." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "%sì˜ ìƒˆ 설치가 ê°ì§€ë˜ì—ˆìŠµë‹ˆë‹¤.\n\n" -"%sì—서 ì„¤ì •ì„ ë³µì‚¬í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "몇 가지 ì´ìœ " -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SAì—서 '%s' 파ì¼ì„ 여는 ë° ë¬¸ì œê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤." +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "다운로드 완료" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SAì— '%s' 파ì¼ì´ 없습니다." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - _DialogUpdateResultì˜ ì•Œ 수 없는 문제" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SAì—서 모ë¸ì„ 불러오는 ë° ë¬¸ì œê°€ 있었습니다." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "ì‚¬ìš©ìž ì •ì˜ëœ GTA:SA 파ì¼" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "ìµœê·¼ì— gta3.img를 수정한 경우 GTA:SA를 다시 설치해 보십시오." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "확ì¸" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SAì—서 ì°¨ëŸ‰ì— ì—…ê·¸ë ˆì´ë“œë¥¼ 추가하는 ë° ë¬¸ì œê°€ 있었습니다." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "오류" + +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "ì¼ë¶€ MTA:SA ë°ì´í„° 파ì¼ì´ 없습니다.\n\n\n" +"MTA:SA를 다시 설치하십시오" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SAê°€ '%s' 파ì¼ì—서 오류를 발견했습니다." +msgid "%3d %% completed" +msgstr "%3d %% 완료" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "MTA:SA를 플레ì´í•  때 컴퓨터가 다시 시작ë˜ì—ˆìŠµë‹ˆê¹Œ?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"ì‘답 대기 중 - %-3d" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "계ì†í•˜ê¸° ì „ì— ë‹¤ìŒ í”„ë¡œê·¸ëž¨ì„ ì¢…ë£Œí•˜ì‹­ì‹œì˜¤:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ 명령어 ë„ì›€ë§ ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "웹 사ì´íЏ 요청" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* ì‹œê°„ì€ %d:%02d:%02d 입니다." -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "서버는 ë‚˜ì¤‘ì— ì›¹ 사ì´íŠ¸ë¥¼ 로드하기 위해 ë‹¤ìŒ ì›¹ 사ì´íŠ¸ë¥¼ 요청합니다:" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "ë³´ì•ˆì„ ìœ„í•´ 중요한 ë°ì´í„°ë¥¼ 절대 입력하지 마십시오." +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "ì—°ê²°: êµ¬ë¬¸ì€ 'connect [ ]' 입니다." -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "기억하기" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "ì—°ê²°: 올바르지 ì•Šì€ í¬ë“œ" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "허용" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "ì—°ê²°: ì—°ê²° 중 %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "ê±°ë¶€" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "ì—°ê²°: %s:%u ì— ì—°ê²°í•  수 없습니다!" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "ì—°ê²°: 현재 모드를 언로드하지 못했습니다." + +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "새로운 기능 빌드를 사용하고 있습니다. 공용 ì„œë²„ì— ì—°ê²°í•˜ëŠ” ë° ì‚¬ìš©í•  수 없는 테스트 빌드입니다!" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA는 2019ë…„ 7ì›” ì´í›„ì—는 XP/Vistaì— ëŒ€í•œ ì—…ë°ì´íŠ¸ë¥¼ 받지 못할 것입니다.\n\n" -"최신 서버ì—서 재ìƒí•˜ë„ë¡ Windows를 업그레ì´ë“œí•©ë‹ˆë‹¤." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "현재 ì„œë²„ì™€ì˜ ì—°ê²°ì´ ëŠì–´ì§‘니다.\n\n" -"ì—°ê²°ì„ ëŠìœ¼ì‹œê² ìŠµë‹ˆê¹Œ?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "ì—°ê²° í•´ì œ 경고" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "모든 ì»¨íŠ¸ë¡¤ì„ GTAì—서 ë°”ì¸ë”©" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "ì €ìž¥ëœ êµ¬ì„± 파ì¼" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "한국어" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* ë‹¹ì‹ ì˜ ì‹œë¦¬ì–¼ 넘버: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "설정" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "멀티플레ì´" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "비디오" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "오디오" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "ë°”ì¸ë“œ" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "컨트롤" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "ì¸í„°íŽ˜ì´ìФ" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "웹 브ë¼ìš°ì €" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "고급 설정" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "기본값 불러오기" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "마우스 ê°ë„:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "ìˆ˜ì§ ê°ë„:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "마우스 설정" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "마우스 ìƒí•˜ 반전" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "마우스로 조종" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "마우스로 비행" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "ì¡°ì´íŒ¨ë“œ 설정" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "기본 컨트롤 (마우스 + 키보드)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "í´ëž˜ì‹ 컨트롤 (ì¡°ì´íŒ¨ë“œ)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "ë°ë“œ ì¡´" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "í¬í™”ë„" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "ì¡°ì´íŒ¨ë“œ ë²„íŠ¼ì˜ ê²½ìš° 'ë°”ì¸ë“œ' íƒ­ì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "왼쪽 스틱" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "오른쪽 스틱" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "제목" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "키" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "부가 키" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "닉네임:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "서버 비밀번호 저장" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "서버 브ë¼ìš°ì € ìžë™ 새로고침" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "화면 업로드 허용" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "외부 사운드 허용" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "í•­ìƒ ë‹¤ìš´ë¡œë“œ ì°½ 표시" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "커스터마ì´ì§• ëœ GTA:SA íŒŒì¼ ì‚¬ìš©" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "ë§µ ë Œë”ë§ ì„¤ì •" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "불투명ë„:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "주 ìŒëŸ‰:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "ë¼ë””오 ìŒëŸ‰:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "SFX ìŒëŸ‰:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA ìŒëŸ‰:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "ìŒì„± ìŒëŸ‰:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "ìž¬ìƒ ëª¨ë“œ:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "ì¼ë°˜" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "ë¼ë””오 설정" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "ë¼ë””오 ì´í€„ë¼ì´ì €" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "ë¼ë””오 오토튠" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "ì‚¬ìš©ìž íŠ¸ëž™ 설정" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "ë¼ë””오" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "ëžœë¤" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "순차ì " -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "ìžë™ 미디어 스캔" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "ìŒì†Œê±° 설정" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "최소화 시 모든 소리 ìŒì†Œê±°" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "최소화 시 ë¼ë””오 ìŒì†Œê±°" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "최소화 시 SFX 소리 ìŒì†Œê±°" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "최소화 시 MTA 소리 ìŒì†Œê±°" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "최소화 시 ìŒì„± ìŒì†Œê±°" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "í•´ìƒë„:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "FOV:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "가시 거리:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "ë°ê¸°:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX 품질:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "ì´ë°©ì„± í•„í„°ë§:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "안티 앨리어싱:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "화면비:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "ì°½ 모드" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI aware" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "기본" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "í…Œë‘리 없는 ì°½ í•´ìƒë„ 유지" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "ë°‰ ë§µ" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "ë‚®ìŒ" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "중간" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "높ìŒ" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "매우 높ìŒ" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "ë„기" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "ìžë™" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD ì¼ì¹˜ 종횡비" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "ì²´ì  ê·¸ë¦¼ìž" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "잔디 효과" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "ì—´ í—¤ì´ì¦ˆ" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "타ì´ì–´ 연기 등" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "다ì´ë‚˜ë¯¹ 패드 그림ìž" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "모션블러" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Corona 비 반사" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "전체화면 최소화" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "장치 ì„ íƒ ë‹¤ì´ì–¼ë¡œê·¸ 활성화" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "불안전한 í•´ìƒë„ 표시" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "ì°¨ëŸ‰ì„ í•­ìƒ ìµœê³  디테ì¼ë¡œ ë Œë”ë§" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "패드를 í•­ìƒ ìµœê³  ë””í…Œì¼ ë Œë”ë§" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "ì›ê²© 웹 사ì´íЏ 사용" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "ì›ê²© 웹 사ì´íЏì—서 ìžë°”스í¬ë¦½íЏ 사용" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "ì‚¬ìš©ìž ì§€ì • 블랙리스트" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "ë„ë©”ì¸ ìž…ë ¥ (예: google.com)" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "차단" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "ë„ë©”ì¸" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "ë„ë©”ì¸ ì œê±°" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "ì‚¬ìš©ìž ì§€ì • í™”ì´íŠ¸ë¦¬ìŠ¤íŠ¸" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "허용" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "기타" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "빠른 CJ 옷 로딩:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "브ë¼ìš°ì € ì†ë„:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "ë‹¨ì¼ ì—°ê²°:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "패킷 태그:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "ì§„í–‰ 애니메ì´ì…˜:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "프로세스 ìš°ì„ ë„:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "디버그 설정:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "ìŠ¤íŠ¸ë¦¬ë° ë©”ëª¨ë¦¬:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "빌드 유형 ì—…ë°ì´íЏ:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "중요한 ì—…ë°ì´íŠ¸ë¥¼ 설치합니다:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "켜기" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "매우 ëŠë¦¬ê²Œ" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "기본값" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "빠르게" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "보통" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "보통 ì´ìƒ" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "최소" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "최대" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "윈ë„ìš° 8 호환성:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16비트 색ìƒ" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "마우스 수정" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "í´ë¼ì´ì–¸íЏ 리소스 파ì¼:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "íƒìƒ‰ê¸°ì— 표시" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "ìžë™ ì—…ë°ì´í„°" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "ì—…ë°ì´íЏ 확ì¸" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "ì¼ë¶€ ì„¤ì •ì€ ë‹¤ìŒì— MTA를 시작할 때 변경ë©ë‹ˆë‹¤." -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "지금 다시 시작하시겠습니까?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "재시작 í•„ìš”" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "ì¼ë¶€ ì„¤ì •ì€ í˜„ìž¬ ì„œë²„ì˜ ì—°ê²°ì„ ëŠì„ 때 변경ë©ë‹ˆë‹¤." -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "지금 ì—°ê²°ì„ ëŠìœ¼ì‹œê² ìŠµë‹ˆê¹Œ?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "ì—°ê²° ëŠê¸° í•„ìš”" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "ì¡°ì´íŒ¨ë“œê°€ ì¸ì‹ë˜ì§€ ì•ŠìŒ - ì—°ê²°ì„ í™•ì¸í•˜ê³  ê²Œìž„ì„ ë‹¤ì‹œ 시작하십시오." -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "ë°”ì¸ë”© ì¶•" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "ì¶•ì„ ì›€ì§ì—¬ ë°”ì¸ë“œ 하거나, Esc를 눌러 지우십시오" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "언어:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "스킨:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "프리셋:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "채팅" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "불러오기" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "색ìƒ" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "ë ˆì´ì•„웃" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "설정" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "채팅 ë°°ê²½" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "채팅 í…스트" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "채팅 ë°°ê²½" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "í…스트 ìž…ë ¥" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "줄:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "스케ì¼:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "너비:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "í¬ê¸°:" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "후" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "ë™ì•ˆ" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "ì´ˆ" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "페ì´ë”©" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "ì˜¤ëž˜ëœ ì¤„ 사ë¼ì§" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "수í‰:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "수ì§:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "í…스트 ì •ë ¬:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-오프셋:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-오프셋:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "위치" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "왼쪽" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "중앙" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "오른쪽" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "ìƒë‹¨" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "하단" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "í°íЏ" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "입력하지 ì•Šì„ ë•Œ ë°°ê²½ 숨기기" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "\"탭\" 키를 사용하여 닉네임 완성" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "서버가 ì°½ì„ ê¹œë°•ì¼ ìˆ˜ 있ë„ë¡ í—ˆìš©" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "íŠ¸ë ˆì´ í’ì„  알림 허용" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "채팅 í…스트 ê²€ì€ìƒ‰/í°ìƒ‰ 윤곽선" @@ -1548,110 +1832,116 @@ msgstr "채팅 í…스트 ê²€ì€ìƒ‰/í°ìƒ‰ 윤곽선" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "ì›í•˜ëŠ” 키를 누르거나, Esc를 눌러 초기화하세요." -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "주 키 ë°”ì¸ë”©" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "부가 키 ë°”ì¸ë”©" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA 게임 컨트롤" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "ë©€í‹°í”Œë ˆì´ ì»¨íŠ¸ë¡¤" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "ë‹‰ë„¤ìž„ì— ìž˜ëª»ëœ ë¬¸ìžê°€ í¬í•¨ë˜ì–´ 있습니다!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "빨강:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "ì´ˆë¡:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "파랑:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "투명ë„:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "색ìƒ:" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "미리보기" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "언어를 변경하기 ì „ì— ì—°ê²°ì„ ëŠìœ¼ì‹­ì‹œì˜¤" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "ìŠ¤í‚¨ì„ ë³€ê²½í•˜ê¸° ì „ì— ì—°ê²°ì„ ëŠìœ¼ì‹­ì‹œì˜¤" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "그림ìžë¡œ ì¸í•´ ì¼ë¶€ ì‹œìŠ¤í…œì˜ ì†ë„ê°€ ëŠë ¤ì§ˆ 수 있습니다.\n\n" "사용하ë„ë¡ ì„¤ì •í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "성능 주ì˜" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "부정행위 방지를 위해 ì¼ë¶€ 서버ì—서 화면 업로드가 필요합니다.\n\n" "(채팅창 ë° GUI는 업로드 대ìƒì—서 제외)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "화면 업로드 ì •ë³´" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "ì¼ë¶€ 스í¬ë¦½íŠ¸ëŠ” ì¸í„°ë„·ì—서 ë¼ë””오와 ê°™ì€ ì†Œë¦¬ë¥¼ 재ìƒí•  수 있습니다.\n\n" "ì´ ì„¤ì •ì„ ë¹„í™œì„±í™”í•˜ë©´ ë„¤íŠ¸ì›Œí¬ ëŒ€ì—­í­ ì†Œë¹„ê°€ ê°ì†Œí•  수 있습니다.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "외부 사운드" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1661,11 +1951,7 @@ msgstr "GTA:SA ë°ì´í„° ë””ë ‰í† ë¦¬ì˜ ì¼ë¶€ 파ì¼ì´ ì‚¬ìš©ìž ì •ì˜ë©ë‹ˆ "그러나 ì‚¬ìš©ìž ì •ì˜ëœ GTA:SA 파ì¼ì´ ë§Žì€ ì„œë²„ì— ì˜í•´ 차단ë˜ì—ˆìŠµë‹ˆë‹¤.\n\n" "사용하시겠습니까?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "ì‚¬ìš©ìž ì •ì˜ëœ GTA:SA 파ì¼" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1675,550 +1961,252 @@ msgstr "DPI awarenessì„ í™œì„±í™”í•˜ëŠ” ê²ƒì€ ì‹¤í—˜ì ì¸ 기능입니다.\n" "ì´ ì˜µì…˜ì„ í™œì„±í™”í•˜ë©´ 그래픽 문제가 ë°œìƒí•  수 있습니다.\n\n" "ì´ ì˜µì…˜ì„ í™œì„±í™”í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "실험ì ì¸ 기능" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "ë‹‰ë„¤ìž„ì„ ìž…ë ¥í•˜ì‹­ì‹œì˜¤." -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "게임 ë‚´ì—서 사용할 ë‹‰ë„¤ìž„ì„ ìž…ë ¥í•˜ì‹­ì‹œì˜¤. \n" "ì´ê²ƒì€ ì„œë²„ì— ì—°ê²°í•˜ê³  서버ì—서 재ìƒí•  때 ê·€í•˜ì˜ ì´ë¦„ì´ ë  ê²ƒìž…ë‹ˆë‹¤." -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "매우 실험ì ì¸ 기능." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "CJ 버전으로 스톨 중지(65MB ì´ìƒì˜ RAM 사용)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "구형 ë¼ìš°í„°ëŠ” 스캔 ì†ë„ê°€ ëŠë ¤ì§ˆ 수 있습니다." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "다운로드할 때 ì—°ê²°ì„ í•˜ë‚˜ë§Œ 사용하려면 켜십시오." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "ISPê°€ MTA íŠ¸ëž˜í”½ì„ ì‹ë³„í•  수 있ë„ë¡ ë„¤íŠ¸ì›Œí¬ íŒ¨í‚·ì— íƒœê·¸ë¥¼ 지정합니다." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "화면 í•˜ë‹¨ì˜ íšŒì „ ì› ì• ë‹ˆë©”ì´ì…˜" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "í•­ìƒ ê¸°ë³¸ê°’ì„ ì„ íƒí•©ë‹ˆë‹¤. (ì´ ì„¤ì •ì€ ì €ìž¥ë˜ì§€ 않ìŒ)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "ì¼ë°˜ì ìœ¼ë¡œ ìµœëŒ€ê°’ì´ ê°€ìž¥ 좋습니다." -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "ìžë™ ì—…ë°ì´í„°:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "버그 보고서 ìž‘ì„±ì„ ì›í•˜ì§€ 않는 경우 ê¸°ë³¸ê°’ì„ ì„ íƒí•˜ì‹­ì‹œì˜¤." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "중요한 ì—…ë°ì´íŠ¸ë¥¼ ìžë™ìœ¼ë¡œ 설치하려면 ê¸°ë³¸ê°’ì„ ì„ íƒí•˜ì‹­ì‹œì˜¤." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16비트 색ìƒ:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "16비트 ìƒ‰ìƒ ëª¨ë“œ 사용 - MTA를 다시 시작해야 합니다." -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "마우스 수정:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "마우스 ì´ë™ 수정 - PC를 다시 시작해야 í•  수 있습니다." -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "알 수 없는 명령 ë˜ëŠ” cvar: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "사용 중" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "ì—…ë°ì´íŠ¸ë¥¼ 지금 확ì¸í•  수 없습니다." - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %sì´(ê°€) 필요합니다." - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "ì„ íƒí•œ ì„œë²„ì— ì ‘ì†í•˜ë ¤ë©´ MTA:SA %sì˜ ì—…ë°ì´íЏ ë²„ì „ì´ í•„ìš”í•©ë‹ˆë‹¤.\n\n" -"MTA:SA %sì„(를) 다운로드하여 설치하시겠습니까?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "MTA:SA %sì„(를) 시작하고 ì´ ì„œë²„ì— ì—°ê²°í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "ì§€ê¸ˆì€ ì—°ê²°í•  수 없습니다.\n\n" -"ë‚˜ì¤‘ì— ì‹œë„하십시오." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "ì—°ê²° 중" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "잠시 기다려 주십시오..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "í™•ì¸ ì¤‘" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "ì—…ë°ì´íЏ 확ì¸" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "ì—…ë°ì´íЏ 필요없ìŒ" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "다운로드 중" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "대기 중..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "필수 ì—…ë°ì´íЏ" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "ì´ ì„œë²„ì— ì ‘ì†í•˜ë ¤ë©´ MTA를 ì—…ë°ì´íŠ¸í•´ì•¼ 합니다.\n\n" -" 지금 ì—…ë°ì´íŠ¸í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "ì„ íƒì  ì—…ë°ì´íЏ" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "서버ì—서 ì—…ë°ì´íŠ¸ê°€ 권장ë˜ì§€ë§Œ 필수는 아니ë¼ê³  합니다.\n\n" -" 지금 ì—…ë°ì´íŠ¸í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "저장 오류" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "파ì¼ì„ ìƒì„±í•  수 없습니다." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "다운로드 오류" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "다운로드한 파ì¼ì´ 올바르지 ì•Šì€ ê²ƒ 같습니다." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "몇 가지 ì´ìœ " - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "다운로드 완료" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - _DialogUpdateResultì˜ ì•Œ 수 없는 문제" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "확ì¸" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "오류" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "ì¼ë¶€ MTA:SA ë°ì´í„° 파ì¼ì´ 없습니다.\n\n\n" -"MTA:SA를 다시 설치하십시오" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% 완료" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"ì‘답 대기 중 - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "ì—°ê²°ì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤. ìž˜ëª»ëœ ë‹‰ë„¤ìž„!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "ì—°ê²°ì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤. ìž˜ëª»ëœ í˜¸ìŠ¤íŠ¸!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "%u í¬íЏì—서 %sì— ì—°ê²°í•˜ì§€ 못했습니다!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "%s:%u ... ì— ì—°ê²° 중" - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "ì—°ê²° 중" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "ì—°ê²° ì‹œê°„ì´ ì´ˆê³¼ë˜ì—ˆìŠµë‹ˆë‹¤." - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "ì—°ê²° ëŠê¹€: 알 수 없는 프로토콜 오류" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "ì—°ê²° ëŠê¹€: ì›ê²©ìœ¼ë¡œ ì—°ê²°ì´ ëŠì–´ì§" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "ì—°ê²° ëŠê¹€: ì›ê²©ìœ¼ë¡œ ì—°ê²°ì´ ëŠì–´ì§" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "ì—°ê²° ëŠê¹€: ì´ ì„œë²„ì—서 ë°´ë˜ì—ˆìŠµë‹ˆë‹¤" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "ì—°ê²° ëŠê¹€: ì„œë²„ì™€ì˜ ì—°ê²°ì´ ëŠì–´ì¡ŒìŠµë‹ˆë‹¤" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "ì—°ê²° ëŠê¹€: ì„œë²„ì— ëŒ€í•œ ì—°ê²°ì´ ëŠì–´ì¡ŒìŠµë‹ˆë‹¤" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "ì—°ê²° ëŠê¹€: ì—°ê²°ì´ ê±°ë¶€ë˜ì—ˆìŠµë‹ˆë‹¤" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "해당 모드가 설치ë˜ì§€ 않았습니다(%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "서버 ì‘답 불량(2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "서버 ì‘답 불량(1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "소ì‹" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "최근 소ì‹ê¸€ 방문" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "콘솔" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "치명ì ì¸ 오류" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "고치기 위해서, ì´ íŒŒì¼ì„ 지우십시오:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s ëª¨ë“ˆì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "URL 실행 중 오류 ë°œìƒ" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "ì´ ë„ì›€ë§ í™”ë©´" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "프로그램 종료" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "버전 표시" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "시간 표시" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "hud 표시" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "모든 ë°”ì¸ë“œ 표시" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "시리얼 넘버 표시" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "ì„œë²„ì— ì—°ê²° (호스트 í¬íЏ 닉네임 패스)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "ì´ì „ ì„œë²„ì— ì—°ê²°" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "키 ë°”ì¸ë”©(키 컨트롤)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "ë°”ì¸ë“œ í•´ì œ (키)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" -msgstr "기본 gta 컨트롤 복사" - -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "스í¬ë¦°ìƒ· 출력" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "즉시 êµ¬ì„±ì„ ì €ìž¥í•©ë‹ˆë‹¤" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "디버그 보기 지우기" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "ì±„íŒ…ì°½ì„ ìœ„ë¡œ 스í¬ë¡¤í•©ë‹ˆë‹¤" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "ì±„íŒ…ì°½ì„ ì•„ëž˜ë¡œ 스í¬ë¡¤í•©ë‹ˆë‹¤" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "디버그 보기를 위로 스í¬ë¡¤í•©ë‹ˆë‹¤" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "디버그 보기를 아래로 스í¬ë¡¤í•©ë‹ˆë‹¤" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "메모리 통계를 ë³´ì—¬ì¤ë‹ˆë‹¤" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "프레임 타ì´ë° 그래프를 ë³´ì—¬ì¤ë‹ˆë‹¤" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "개발ìžìš©: ì†Œì‹ ë‹¤ì‹œ 로드" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ 명령어 ë„ì›€ë§ ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* ì‹œê°„ì€ %d:%02d:%02d 입니다." - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "ì—°ê²°: êµ¬ë¬¸ì€ 'connect [ ]' 입니다." - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "ì—°ê²°: 올바르지 ì•Šì€ í¬ë“œ" +msgstr "기본 gta 컨트롤 복사" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "ì—°ê²°: ì—°ê²° 중 %s:%u..." +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "스í¬ë¦°ìƒ· 출력" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "ì—°ê²°: %s:%u ì— ì—°ê²°í•  수 없습니다!" +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "즉시 êµ¬ì„±ì„ ì €ìž¥í•©ë‹ˆë‹¤" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "ì—°ê²°: 현재 모드를 언로드하지 못했습니다." +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "디버그 보기 지우기" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "ì±„íŒ…ì°½ì„ ìœ„ë¡œ 스í¬ë¡¤í•©ë‹ˆë‹¤" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "ì±„íŒ…ì°½ì„ ì•„ëž˜ë¡œ 스í¬ë¡¤í•©ë‹ˆë‹¤" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "디버그 보기를 위로 스í¬ë¡¤í•©ë‹ˆë‹¤" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "디버그 보기를 아래로 스í¬ë¡¤í•©ë‹ˆë‹¤" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "모든 ì»¨íŠ¸ë¡¤ì„ GTAì—서 ë°”ì¸ë”©" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "메모리 통계를 ë³´ì—¬ì¤ë‹ˆë‹¤" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "ì €ìž¥ëœ êµ¬ì„± 파ì¼" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "프레임 타ì´ë° 그래프를 ë³´ì—¬ì¤ë‹ˆë‹¤" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* ë‹¹ì‹ ì˜ ì‹œë¦¬ì–¼ 넘버: %s" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "개발ìžìš©: ì†Œì‹ ë‹¤ì‹œ 로드" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "ì¶• ê°€ì†" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "새로운 기능 빌드를 사용하고 있습니다. 공용 ì„œë²„ì— ì—°ê²°í•˜ëŠ” ë° ì‚¬ìš©í•  수 없는 테스트 빌드입니다!" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "ì¶• 브레ì´í¬" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA는 2019ë…„ 7ì›” ì´í›„ì—는 XP/Vistaì— ëŒ€í•œ ì—…ë°ì´íŠ¸ë¥¼ 받지 못할 것입니다.\n\n" +"최신 서버ì—서 재ìƒí•˜ë„ë¡ Windows를 업그레ì´ë“œí•©ë‹ˆë‹¤." -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "프로그래ë°" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "현재 ì„œë²„ì™€ì˜ ì—°ê²°ì´ ëŠì–´ì§‘니다.\n\n" +"ì—°ê²°ì„ ëŠìœ¼ì‹œê² ìŠµë‹ˆê¹Œ?" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "기여ìž" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "ì—°ê²° í•´ì œ 경고" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "게임 ë””ìžì¸ / 스í¬ë¦½íŒ…" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "언어 현지화" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "소ì‹" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "패치 기여ìž" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "최근 소ì‹ê¸€ 방문" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "특별 ê°ì‚¬" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "스í¬ë¦°ìƒ·ì€ %d ë°”ì´íЏì´ì§€ë§Œ, %d 로 예ìƒë©ë‹ˆë‹¤." -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "ì´ ì†Œí”„íŠ¸ì›¨ì–´ ë° í”„ë¡œì íŠ¸ëŠ” ë‹¤ìŒ ë¼ì´ë¸ŒëŸ¬ë¦¬ ë° ì†Œí”„íŠ¸ì›¨ì–´ë¥¼ 사용합니다:" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "스í¬ë¦°ìƒ· ì €ìž¥ì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤." -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "ì´ ë¬¸ì œì— ëŒ€í•œ 온ë¼ì¸ ë„움ë§ì„ 보시겠습니까?" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "스í¬ë¦°ìƒ· ì´¬ì˜ë¨: '%s'" + +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "알 수 없는 명령 ë˜ëŠ” cvar: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2393,25 +2381,56 @@ msgid "Group control backwards" msgstr "그룹 조종 후진" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "ì„ íƒí•œ ìŠ¤í‚¨ì„ ë¡œë“œí•  수 없으며 기본 ìŠ¤í‚¨ë„ ë¡œë“œí•  수 없습니다. MTA를 다시 설치하십시오." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "스í¬ë¦°ìƒ·ì€ %d ë°”ì´íЏì´ì§€ë§Œ, %d 로 예ìƒë©ë‹ˆë‹¤." +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "ì´ ë¬¸ì œì— ëŒ€í•œ 온ë¼ì¸ ë„움ë§ì„ 보시겠습니까?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "스í¬ë¦°ìƒ· ì €ìž¥ì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤." +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "콘솔" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "스í¬ë¦°ìƒ· ì´¬ì˜ë¨: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "프로그래ë°" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "기여ìž" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "게임 ë””ìžì¸ / 스í¬ë¦½íŒ…" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "언어 현지화" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "패치 기여ìž" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "특별 ê°ì‚¬" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "ì´ ì†Œí”„íŠ¸ì›¨ì–´ ë° í”„ë¡œì íŠ¸ëŠ” ë‹¤ìŒ ë¼ì´ë¸ŒëŸ¬ë¦¬ ë° ì†Œí”„íŠ¸ì›¨ì–´ë¥¼ 사용합니다:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "ì¶• ê°€ì†" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "ì¶• 브레ì´í¬" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2419,6 +2438,60 @@ msgstr "Direct3D9를 초기화할 수 없습니다.\n\n" "DirectX 최종 ì‚¬ìš©ìž ëŸ°íƒ€ìž„ì„ í™•ì¸í•˜ê³ \n" "최신 Windows 서비스 íŒ©ì´ ì˜¬ë°”ë¥´ê²Œ 설치ë˜ì—ˆëŠ”ì§€ 확ì¸í•˜ì‹­ì‹œì˜¤." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "ì—†ìŒ" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "플레ì´ì–´\n\n" +"플레ì´ì–´ë“¤" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "ì ‘ì† ì¤‘" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "서버" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "마스터 서버 ëª©ë¡ ìš”ì²­( %lu ms 경과)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "마스터 서버 목ë¡ì„ 검색할 수 없습니다." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "마스터 서버 목ë¡ì„ 검색할 수 없습니다." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(백업 서버 목ë¡)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "LAN 브로드ìºìŠ¤íŠ¸ ì†Œì¼“ì„ ë°”ì¸ë”©í•  수 없습니다." + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "LAN 서버 검색 중" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2472,7 +2545,7 @@ msgstr "ë ˆì´í„´ì‹œ" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "플레ì´ì–´ 목ë¡" @@ -2499,40 +2572,39 @@ msgstr "플레ì´ì–´ ìŠ¬ë¡¯ì„ ì‚¬ìš©í•  수 있는 즉시 ì„œë²„ì— ì ‘ì†í•© msgid "PLEASE ENTER SERVER PASSWORD" msgstr "서버 암호를 입력하십시오" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "시간 초과ë¨" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "쿼리 중..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "서버 브ë¼ìš°ì €" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "ì¸í„°ë„·" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "로컬" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "ì¦ê²¨ì°¾ê¸°" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "최근" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2540,297 +2612,367 @@ msgstr "빠른 ì—°ê²°:\n\n" "주소 í‘œì‹œì¤„ì— ì£¼ì†Œì™€ í¬íŠ¸ë¥¼ 입력합니다.\n" "ë˜ëŠ” 목ë¡ì—서 서버를 ì„ íƒí•˜ê³  'ì—°ê²°'ì„ ëˆ„ë¦…ë‹ˆë‹¤" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "ë„움ë§" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "새로고침" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "ì¦ê²¨ì°¾ê¸° 추가" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "ì—°ê²°" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "서버 ì •ë³´" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "서버 검색" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "플레ì´ì–´ 검색" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "검색 시작" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "플레ì´ì–´ 검색..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "서버 검색..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "ì´ë¦„" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "플레ì´ì–´" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "í•‘" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "게임 모드" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "í¬í•¨:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "비어있ìŒ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "ê°€ë“ ì°¸" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "ìž ê¹€" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "오프ë¼ì¸" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "다른 버전" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "뒤로가기" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "불러오는 중…" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..불러오는 중.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "주소가 ìž…ë ¥ë˜ì§€ 않았습니다!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "알 수 없는 프로토콜" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Mtasa:// í”„ë¡œí† ì½œì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "ìž˜ëª»ëœ ë‹‰ë„¤ìž„ìž…ë‹ˆë‹¤! 설정으로 ì´ë™í•˜ì—¬ 새 ë‹‰ë„¤ìž„ì„ ì„¤ì •í•˜ì‹­ì‹œì˜¤!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "ì—°ê²°í•  서버를 ì„ íƒí•´ì•¼ 합니다." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "ì—†ìŒ" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "그래픽 드ë¼ì´ë²„ 문제" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "플레ì´ì–´\n\n" -"플레ì´ì–´ë“¤" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "올바른 화면 í•´ìƒë„를 ì°¾ì„ ìˆ˜ 없습니다." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "ì ‘ì† ì¤‘" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "ì´ í™”ë©´ í•´ìƒë„를 사용하시겠습니까?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "서버" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "마스터 서버 ëª©ë¡ ìš”ì²­( %lu ms 경과)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "마스터 서버 목ë¡ì„ 검색할 수 없습니다." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "웹 사ì´íЏ 요청" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "마스터 서버 목ë¡ì„ 검색할 수 없습니다." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "서버는 ë‚˜ì¤‘ì— ì›¹ 사ì´íŠ¸ë¥¼ 로드하기 위해 ë‹¤ìŒ ì›¹ 사ì´íŠ¸ë¥¼ 요청합니다:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(백업 서버 목ë¡)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "ë³´ì•ˆì„ ìœ„í•´ 중요한 ë°ì´í„°ë¥¼ 절대 입력하지 마십시오." -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "LAN 브로드ìºìŠ¤íŠ¸ ì†Œì¼“ì„ ë°”ì¸ë”©í•  수 없습니다." +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "기억하기" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "LAN 서버 검색 중" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "ê±°ë¶€" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "ì´ ë²„ì „ì€ ë§Œë£Œë˜ì—ˆìŠµë‹ˆë‹¤." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "서버와 ì—°ê²° ëŠê¸°" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "네임태그 표시" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "채팅창 표시" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "ì¸í„°ë„· 통계 표시" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "채팅 입력창 열기" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "다른 플레ì´ì–´ì—게 ìŒì„± 전송" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "승ê°ìœ¼ë¡œ 탑승" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "ë‹¤ìŒ ë¼ë””오 채ë„" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "ì´ì „ ë¼ë””오 채ë„" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "ëŒ€ìƒ í”Œë ˆì´ì–´ì—게 메시지를 보냅니다" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "ì°¨ëŸ‰ì— íƒ‘ìŠ¹í•˜ëŠ” ë™ì•ˆ ë‹¤ìŒ ë¬´ê¸°ë¡œ 변경" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "ì°¨ëŸ‰ì— íƒ‘ìŠ¹í•˜ëŠ” ë™ì•ˆ ì´ì „ 무기로 변경" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "현재 ì„œë²„ì— ëŒ€í•œ ì •ë³´ 출력" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "모든 í…스트 디스플레ì´ì˜ ìŠ¤ì¼€ì¼ ë©€í‹°í”ŒëŸ¬ë¥¼ ì •ì˜" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(ê°œë°œìž ëª¨ë“œ) colshapes 표시" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(ê°œë°œìž ëª¨ë“œ) 월드 사운드 Id를 디버그 ì°½ì— ì¶œë ¥" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "호스트 게임" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "리소스" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "서버 ì´ë¦„:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "비밀번호:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "최대 ì¸ì›:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "브로드ìºìŠ¤íŠ¸:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "ëžœ" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "ì„ íƒë¨" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "모ë‘" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "시작" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "ë§µ 다운로드 진행률:" @@ -2851,488 +2993,398 @@ msgstr "%s 중 %s" msgid "Disconnect to cancel download" msgstr "다운로드를 취소하려면 ì—°ê²°ì„ ëŠìœ¼ì‹­ì‹œì˜¤" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "ì—°ê²° ëŠê¹€: ìž˜ëª»ëœ ë‹‰ë„¤ìž„" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "ì„œë²„ì™€ì˜ ì—°ê²°ì´ ëŠê²¼ìŠµë‹ˆë‹¤." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "ì—°ê²° ëŠê¹€: ì´ìš©ì´ ê¸ˆì§€ëœ ì‹œë¦¬ì–¼ 넘버입니다.\n" "ì´ìœ : %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "ì—°ê²° ëŠê¹€: ë‹¹ì‹ ì€ ì´ìš©ì´ 금지ë˜ì—ˆìŠµë‹ˆë‹¤.\n" "ì´ìœ : %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "ì—°ê²° ëŠê¹€: ì´ìš©ì´ ê¸ˆì§€ëœ ê³„ì •ìž…ë‹ˆë‹¤.\n" "ì´ìœ : %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "ì—°ê²° ëŠê¹€: ë²„ì „ì´ ë‹¤ë¦„." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "ì—°ê²° ëŠê¹€: 대량 ì ‘ì†. 잠시 기다렸다가 다시 연결하십시오." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "ì—°ê²° ëŠê¹€: 다른 ì§€ì ì˜ 서버입니다.\n" "ì •ë³´: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "ì—°ê²° ëŠê¹€: ìž˜ëª»ëœ ë²„ì „.\n" "ì •ë³´: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "ì—°ê²° ëŠê¹€: 서버ì—서 최신 빌드로 구ë™ë˜ê³  있습니다.\n" "ì •ë³´: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "ì—°ê²° ëŠê¹€: 서버ì—서 ì˜¤ëž˜ëœ ë¹Œë“œë¡œ 구ë™ë˜ê³  있습니다.\n" "ì •ë³´: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "ì—°ê²° ëŠê¹€: ì´ë¯¸ 사용 ì¤‘ì¸ ë‹‰ë„¤ìž„." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "ì—°ê²° ëŠê¹€: 플레ì´ì–´ 요소를 만들 수 없습니다." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "ì—°ê²° ëŠê¹€: 서버가 ì—°ê²°ì„ ê±°ë¶€í–ˆìŠµë‹ˆë‹¤. %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "ì—°ê²° ëŠê¹€: 시리얼 넘버 ì¸ì¦ 실패." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "ì—°ê²° ëŠê¹€: ì—°ê²° 비ë™ê¸°í™” %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "ì—°ê²° ëŠê¹€: %sì— ì˜í•´ 추방ë˜ì—ˆìŠµë‹ˆë‹¤." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "ì—°ê²° ëŠê¹€: ë‹¹ì‹ ì€ %s ì— ì˜í•´ ì´ìš©ì´ 금지ë˜ì—ˆìŠµë‹ˆë‹¤." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "ì—°ê²° ëŠê¹€: 서버 종료 ë˜ëŠ” 다시 시작" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "ë‹¹ì‹ ì€ ê²Œìž„ì—서 추방ë˜ì—ˆìŠµë‹ˆë‹¤." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "ì´ ì„œë²„ì—는 수정ë˜ì§€ ì•Šì€ gta_sa.exeê°€ 필요합니다." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Gta_sa.exe를 êµì²´í•˜ì‹­ì‹œì˜¤." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "ì´ ì„œë²„ëŠ” ì‚¬ìš©ìž ì§€ì • D3D9.DLLì„ í—ˆìš©í•˜ì§€ 않습니다." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "GTA 설치 디렉토리ì—서 D3D9.DLLì„ ì œê±°í•˜ê³  MTA를 다시 시작하십시오." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "ì´ ì„œë²„ëŠ” ê°€ìƒ ì‹œìŠ¤í…œì„ í—ˆìš©í•˜ì§€ 않습니다." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "ì´ ì„œë²„ì—서 드ë¼ì´ë²„ ì„œëª…ì„ ì‚¬ìš©í•˜ë„ë¡ ì„¤ì •í•´ì•¼ 합니다." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "PC를 재시작 하십시오." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "ì´ ì„œë²„ê°€ 부정행위 ë°©ì§€ 구성요소 누ë½ì„ ê°ì§€í–ˆìŠµë‹ˆë‹¤." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "MTA를 다시 시작하십시오." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "ì´ ì„œë²„ì—는 수정ë˜ì§€ ì•Šì€ gta3.img ë° gta_int.imgê°€ 필요합니다." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Gta3.img ë˜ëŠ” gta_int.img를 êµì²´í•˜ì‹­ì‹œì˜¤." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "ì´ ì„œë²„ëŠ” Wineì„ í—ˆìš©í•˜ì§€ 않습니다" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "다른 í”„ë¡œê·¸ëž¨ì´ MTA:SA를 수정하지 않는지 확ì¸í•©ë‹ˆë‹¤." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "ë‚¨ì€ ì‹œê°„: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%dì¼" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d 시간" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d ë¶„" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" msgstr[0] "%d ì´ˆ" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "ì—°ê²° ëŠê¹€" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "다운로드 오류: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "ê²Œìž„ì— ì ‘ì†í•˜ëŠ” 중..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "ì—°ê²°ë˜ì§€ 않았습니다. 빠른 ì—°ê²° ë˜ëŠ” 'ì—°ê²°' ëª…ë ¹ì„ ì‚¬ìš©í•˜ì—¬ ì„œë²„ì— ì—°ê²°í•˜ì‹­ì‹œì˜¤." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "로컬 서버를 시작할 수 없습니다. ìžì„¸í•œ ë‚´ìš©ì€ ì½˜ì†”ì„ ì°¸ì¡°í•˜ì‹­ì‹œì˜¤." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "로컬 서버" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "로컬 서버 시작 중..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "ë‹¹ì‹ ì€ ê²Œìž„ì—서 추방ë˜ì—ˆìŠµë‹ˆë‹¤. (%s)" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "로컬 ì„œë²„ì— ì—°ê²° 중..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "ì„œë²„ì— ì ‘ì† ì¤‘ 오류 ë°œìƒ." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "로컬 ì„œë²„ì— ì ‘ì† ì¤‘ 타임아웃 ë˜ì—ˆìŠµë‹ˆë‹¤. ìžì„¸í•œ ì‚¬í•­ì€ ì½˜ì†”ì„ í™•ì¸í•˜ì‹­ì‹œì˜¤." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "ì„œë²„ì™€ì˜ ì—°ê²°ì´ ëŠì–´ì¡ŒìŠµë‹ˆë‹¤." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "ì—°ê²° ëŠê¹€: 서버 ì¸ì›ì´ 꽉 찼습니다." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "ì—°ê²° ëŠê¹€: ìž˜ëª»ëœ ì•”í˜¸ìž…ë‹ˆë‹¤." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA í´ë¼ì´ì–¸íЏ ì¸ì¦ 실패!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "호스트 게임" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "리소스" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "서버 ì´ë¦„:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "비밀번호:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "최대 ì¸ì›:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "브로드ìºìŠ¤íŠ¸:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "ëžœ" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "ì„ íƒë¨" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "모ë‘" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "시작" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "그래픽 드ë¼ì´ë²„ 문제" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "올바른 화면 í•´ìƒë„를 ì°¾ì„ ìˆ˜ 없습니다." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "ì´ í™”ë©´ í•´ìƒë„를 사용하시겠습니까?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "다운로드 오류: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3353,11 +3405,11 @@ msgstr "" msgid "Connection error" msgstr "ì—°ê²° 오류" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Autoê°€ 제대로 설치ë˜ì§€ 않았습니다. 다시 설치하십시오." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "ì´ì œ 브ë¼ìš°ì €ì— ë„ì›€ë§ ì •ë³´ê°€ í¬í•¨ëœ 웹 페ì´ì§€ê°€ 표시ë©ë‹ˆë‹¤.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/lt_LT/client.pot b/Shared/data/MTA San Andreas/MTA/locale/lt_LT/client.pot index e9666b3b6bc..283fe7198a1 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/lt_LT/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/lt_LT/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Lithuanian\n" "Language: lt_LT\n" @@ -17,72 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Problema paleidžiant MTA:SA\n\n" -"Jei problema kartosis, atidarykite užduoÄių tvarkyklÄ™ ir\n" -"sustabdykite 'gta_sa.exe' bei 'Multi Theft Auto.exe' procesus\n\n\n" -"Ar norite pabandyti paleisti MTA:SA dar kartÄ…?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Paleiskite Grand Theft Auto: San Andreas.\n" +"Ä®sitikinkite, kad žaidimas yra įraÅ¡ytas į „Program Files (x86)“ aplankÄ…." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Klaida" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "Vykdoma GTA: San Andreas paieÅ¡ka" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "MTA jau yra paleistas.\n\n" -"Jei problema kartosis, praÅ¡ome perkrauti savo kompiuterį" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "AtsipraÅ¡ome, žaidimas nerastas.\n" +"Paleiskite Grand Theft Auto: San Andreas ir spustelÄ—kite „Bandyti dar kartą“.\n" +"Ä®sitikinkite, kad žaidimas įdiegtas aplanke „Program Files (x86)“." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "MTA jau yra paleistas.\n\n" -"Ar norite sunaikinti šį procesÄ…?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Pasirinkite savo Grand Theft Auto: San Andreas įdiegimo aplankÄ…" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA reikalauja Administratoriaus teisių, kad galÄ—tų:\n\n" +"'%s'\n\n" +"PraÅ¡ome suteikti teises sekanÄiame žingsnyje." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Klaida įkeliant %s modulį! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Kopijuojamos bylos..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopijavimas baigtas anksti. Viskas pavyko." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Baigiama..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Baigta!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Tai pirmas %s paleidimas.\n\n" +"Ar norite nukopijuoti nustatymus iÅ¡ %s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA nepavyko atidaryti failo '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "TrÅ«ksta GTA:SA failo '%s'. " + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA nepavyko įkelti modelio." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Jei neseniai keitÄ—te gta3.img, tada pabandykite perraÅ¡yti GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA nepavyko pridÄ—ti patobulinimo maÅ¡inai." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA surado klaidų faile '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Ar jÅ«sų kompiuteris persikrovÄ— bežaidžiant MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "PraÅ¡ome iÅ¡jungti sekanÄias programas prieÅ¡ tÄ™sdami darbÄ…:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Neteisingos failo versijos klaida. PerraÅ¡ykite MTA:SA, jei patirsite nesklandumų.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "TrÅ«ksta kai kurių failų. PerraÅ¡ykite MTA:SA, jei patirsite nesklandumų.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA yra nepalaikomas su Windows 'Safe Mode'.\n\n" +"Perkraukite savo PC.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Ar jÅ«s turite problemų paleidžiant MTA:SA?.\n\n" "Norite sugražinti ankstesnÄ™ versijÄ…?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +143,48 @@ msgstr "Atrtodo, jog yra problemų paleidžiant MTA:SA.\n" "Sugražinant numatytuosius GTA nustatymus kartais padeda sutvarkyti Å¡iÄ… problemÄ….\n\n" "Ar norite sugražinti GTA nustatymus dabar?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA nustatymai sugražinti.\n\n" "Spauskite Gerai." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Neišėjo iÅ¡trinti bylos: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Ar turite problemų paleidžiant MTA:SA?.\n\n" "NorÄ—tumÄ—t pamatyti Å¡iek tiek pagalbos tinkle?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Turite problemų dÄ—l MTA:SA paleidimo?.\n\n" "Norite pakeisti Å¡iuos nustatymus?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Pilno ekrano režimas:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Langas be kraÅ¡tų" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Turite problemų dÄ—l MTA:SA paleidimo?.\n\n" "Pabandykite iÅ¡jungti Å¡iuos produktus žaidimui GTA ir MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +192,293 @@ msgstr "Ä®SPÄ–JIMAS\n\n" "MTA:SA aptiko neįprastÄ… veiklÄ….\n" "PraÅ¡ome paleisti virusų skenavimo programÄ…, kad įsitikintumÄ—te sistemos saugumu.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Aptiktas failas buvo: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "GTA: San Andreas jau yra paleistas. Šį procesÄ… reikia sunaikinti prieÅ¡ paleidžiant MTA:SA. Ar norite tai padaryti dabar?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informacija" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Neįmanoma sunaikinti GTA: San Andreas proceso. Jei problema kartosis, praÅ¡ome perkrauti savo kompiuterį." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Problema paleidžiant MTA:SA\n\n" +"Jei problema kartosis, atidarykite užduoÄių tvarkyklÄ™ ir\n" +"sustabdykite 'gta_sa.exe' bei 'Multi Theft Auto.exe' procesus\n\n\n" +"Ar norite pabandyti paleisti MTA:SA dar kartÄ…?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Klaida" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "MTA jau yra paleistas.\n\n" +"Jei problema kartosis, praÅ¡ome perkrauti savo kompiuterį" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "MTA jau yra paleistas.\n\n" +"Ar norite sunaikinti šį procesÄ…?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "TrÅ«ksta reikalingų įvesÄių registre. PraÅ¡ome įdiegti Multi Theft Auto: San Andreas iÅ¡ naujo." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Nurodyta vieta iki GTA: San Andreas susideda iÅ¡ nepalaikomų simbolių. PraÅ¡ome patraukti savo Grand Theft Auto: San Andreas įdiegimo aplankÄ… į palaikomÄ… vietÄ…, kuri susideda tik iÅ¡ standartinių ASCII simbolių ir įdiekite Multi Theft Auto: San Andreas iÅ¡ naujo." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Vieta iki įdiegtos 'MTA:SA' ar 'GTA: San Andreas' versijos\n" -"susideda iÅ¡ ';' (kabliataÅ¡kio).\n\n" -"Jei patirsite problemų paleidžiant MTA:SA,\n" -"patraukite savo žaidimÄ…(us) į vietÄ…, nesusidedanÄiÄ… iÅ¡ kabliataÅ¡kio." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Ä®kÄ—limas nepavyko. PraÅ¡ome įsitikinti, jog paskutinÄ—s data bylos buvo įdiegtos teisingai." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Ä®kÄ—limas nepavyko. PraÅ¡ome įsitikinti, kad %s yra įdiegtas teisingai." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Ä®kÄ—limas nepavyko. Nerastas gta_sa.exe nurodytoje vietoje %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Ä®kÄ—limas nepavyko. %s egzistuoja GTA direktorijoje. PraÅ¡ome iÅ¡trinti prieÅ¡ tÄ™siant." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Pagrindinis failas yra blogai užvadintas (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Pagrindinis failas yra nepatvirtintas. Galimas virusų aktyvumas.\n\n" -"PeržiÅ«rÄ—kite pagalbÄ… internete, jei MTA neveikia." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "TrÅ«ksta duomenų failo %s. Galimas viruso aktyvumas.\n\n" -"Apsvarstykite galimybÄ™ iÅ¡ naujo įdiegti „Multi Theft Auto“ savo saugumui.\n" -"Jei MTA neveikia tinkamai, žr. internetinÄ™ žinynÄ…." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Duomenų failas %s pakeistas. Galimas viruso aktyvumas.\n\n" -"Apsvarstykite galimybÄ™ iÅ¡ naujo įdiegti „Multi Theft Auto“ savo saugumui.\n" -"Jei MTA neveikia tinkamai, žr. internetinÄ™ žinynÄ…." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asi failai aptikti 'MTA:SA' arba 'GTA: San Andreas' aplankale.\n\n" -"IÅ¡trinkite .asi failus jei patirsite nesklandumų su MTA:SA." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Neteisingos failo versijos klaida. PerraÅ¡ykite MTA:SA, jei patirsite nesklandumų.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "TrÅ«ksta kai kurių failų. PerraÅ¡ykite MTA:SA, jei patirsite nesklandumų.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA yra nepalaikomas su Windows 'Safe Mode'.\n\n" -"Perkraukite savo PC.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Sutaisyti konfigÅ«racijos problemas" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Sutaisyti privilegijų reikalavimo klaidÄ…" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Nežinomas" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "Failas '%s' Å¡iuo metu užrakintas %zu procesų.\n\n" +"Ar norite užbaigti Å¡iuos procesus ir tÄ™sti atnaujinimÄ…?\n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "JÅ«sų diegimas gali bÅ«ti sugadintas.\n\n" +"%zu iÅ¡ %zu failų nepavyko atkurti iÅ¡ atsarginÄ—s kopijos.\n\n" +"TurÄ—tumÄ—te iÅ¡ naujo įdiegti „Multi Theft Auto“ iÅ¡ www.multitheftauto.com\n" +"arba pabandyti paleisti naujinimÄ… su administratoriaus teisÄ—mis." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Ä®raÅ¡omas atnaujinimas..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "IÅ¡skleidžiami failai..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA negalÄ—jo užbaigti Å¡ios užduoties:\n\n" +"'%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Žaidimas lūžo dÄ—l grafikos tvarkyklių klaidos **\n\n" +"** PraÅ¡ome atsinaujinti savo grafikos tvarkykles **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "Atminties trÅ«kumas – klaida įvyko dÄ—l nepakankamos arba susiskaidžiusios atminties" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Ä®diegti atnaujintas MTA:SA bylas" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Neįmanoma atnaujinti dÄ—l konflikto bylose. PraÅ¡ome uždaryti kitas programas ir bandyti iÅ¡ naujo" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto nebuvo tinkamai įraÅ¡ytas, praÅ¡ome įdiegti iÅ¡ naujo. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA negalima paleisti, nes nepavyko nukopijuoti failo:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA negalima paleisti, nes MTA:SA failas yra netinkamas arba jo nÄ—ra:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Kopijuoti MTA:SA failus" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA negalima paleisti, nes GTA:SA failas yra netinkamas arba jo nÄ—ra:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA negalima paleisti, nes GTA:SA yra netinkamas arba jo nÄ—ra:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Patikrinkite, ar antivirusinÄ—je nÄ—ra klaidingai aptiktas, pabandykite pridÄ—ti GTA:SA kaip programos iÅ¡imtį ir iÅ¡ naujo paleiskite MTA:SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "Generuoti GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA negalima paleisti, nes GTA:SA vykdomas failas neįkeliamas:" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Sutvarkyti GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA negalima paleisti, nes nepavyko pataisyti GTA:SA:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Nepavyko paleisti Grand Theft Auto: San Andreas. PraÅ¡ome paleisti iÅ¡ naujo, arba, jei problema kartosis, susisiekti su MTA svetainÄ—je www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA negali tÄ™sti darbo, nes diske %s nepakanka laisvos vietos." -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas galÄ—jo bÅ«ti paleistas neteisingai. Ar norite sunaikinti šį procesÄ…?" +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "TrÅ«ksta failo:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Jei MTA nepasileidžia, praÅ¡ome perraÅ¡yti GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Atnaujinti diegimo nustatymus" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Atnaujinti suderinamumo nustatymus" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +486,167 @@ msgstr "GTA: San Andreas galÄ—jo bÅ«ti paleistas neteisingai. Ar norite sunaikin #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Taip" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Ne" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "Gerai" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "IÅ¡eiti" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Pagalba" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "AtÅ¡aukti" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas aptiko problemÄ…" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Lūžio informacija" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "PažymÄ—kite varnelÄ™, kad Å¡i lūžio informacija bÅ«tų iÅ¡siųsta MTA kÅ«rÄ—jams internetu" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Taip padarius padidinsite Å¡ansus, jog Å¡is lūžis nebepasikartotų ateityje." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Ar norite paleisti MTA: San Andreas iÅ¡ naujo ?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - PerspÄ—jimas" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "JÅ«sų Grand Theft Auto: San Andreas įraÅ¡ymo vietoje aptiktas d3d9.dll failas:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Å is failas yra nebÅ«tinas ir gali sukelti nesklandumų su naujomis grafikos galimybÄ—mis Å¡ioje MTA:SA versijoje.\n\n" "Rekomenduojama paÅ¡alinti arba pervadinti failÄ… d3d9.dll." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "Naudoti d3d9.dll, bet taip pat parodyti šį įspÄ—jimÄ… kitÄ… kartÄ… paleidus" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Nebepriminti apie Å¡iuos failus" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Pervadinti Å¡iuos failus iÅ¡ *.dll į *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Rodyti failus" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Žaisti MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - PainÅ«s nustatymai" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus aptikta!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "IÅ¡bandykite kiekvienÄ… nustatymÄ… ir patrikrinkite, kuris veiks:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Standartinis NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Alternatyvus NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "E - Standartinis Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" -msgstr "" +msgstr "D – Alternatyvus Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Jei pulsite į neviltį, tai gali jums padÄ—ti:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Jei jau pasirinkote tinkamÄ… parinktį, tai gali padÄ—ti:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Priverstinai paleisti lange" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Nerodyti daugiau" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "PerspÄ—jimas: Nepavyko aptikti anti-virusinÄ—s sistemos" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1102 +654,1181 @@ msgstr "MTA nepavyko aptikti anti-virusinÄ—s sistemos jÅ«sų kompiuteryje.\n\n" "Virusai gali trigdyti MTA darbÄ… ir sumažinti jÅ«sų žaidimo malonumÄ….\n\n" "Spauskite 'Pagalba' detalesnei informacijai." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "AÅ¡ jau turiu įsirašęs anti-virusinÄ™ sistemÄ…" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "AÅ¡ neįsiraÅ¡inÄ—siu anti-virsinÄ—s sistemos.\n" "Noriu, kad mano kompiuteris striginÄ—tų ir bÅ«tų valdomas hakerių." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "IeÅ¡koma Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "PraÅ¡ome paleisti Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Ä®raÅ¡omas atnaujinimas..." - -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "IÅ¡skleidžiami failai..." - -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Kopijuojamos bylos..." - -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopijavimas baigtas anksti. Viskas pavyko." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Prisijungimas nepavyko. Pateiktas netinkamas slapyvardis!" -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Baigiama..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Prisijungimas nepavyko. Pateiktas netinkamas adresas!" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Baigta!" +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Prisijungimas į %s su portu %u nepavyko!" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 +#. Display the status box +#: Client/core/CConnectManager.cpp:153 #, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA reikalauja Administratoriaus teisių, kad galÄ—tų:\n\n" -"'%s'\n\n" -"PraÅ¡ome suteikti teises sekanÄiame žingsnyje." +msgid "Connecting to %s:%u ..." +msgstr "Jungiamasi į %s:%u ..." -#: Client/loader/CInstallManager.cpp:376 +#: Client/core/CConnectManager.cpp:155 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA negalÄ—jo užbaigti Å¡ios užduoties:\n\n" -"'%s'\n" +msgid "Reconnecting to %s:%u ..." +msgstr "Jungiamasi iÅ¡ naujo prie %s:%u ..." -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Žaidimas lūžo dÄ—l grafikos tvarkyklių klaidos **\n\n" -"** PraÅ¡ome atsinaujinti savo grafikos tvarkykles **" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "JUNGIAMASI" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Ä®diegti atnaujintas MTA:SA bylas" +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "BaigÄ—si prisijungimui skirtas laikas" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Neįmanoma atnaujinti dÄ—l konflikto bylose. PraÅ¡ome uždaryti kitas programas ir bandyti iÅ¡ naujo" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Atjungta: nežinoma protokolo klaida" -#: Client/loader/CInstallManager.cpp:561 -#, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto nebuvo tinkamai įraÅ¡ytas, praÅ¡ome įdiegti iÅ¡ naujo. %s" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Atjungta: buvote atjungtas nuotoliniu bÅ«du" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Atsijungta: NutrÅ«ko ryÅ¡ys su nuotoliu" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA negalima paleisti, nes nepavyko nukopijuoti failo:" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Atjungta: jÅ«sų prisijungimas yra užblokuotas Å¡iame serveryje" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA negalima paleisti, nes MTA:SA failas yra netinkamas arba jo nÄ—ra:" +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Atsijungta: atsijungta nuo serverio " -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Kopijuoti MTA:SA failus" +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Atsijungta: ryÅ¡ys su serveriu buvo prarastas" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA negalima paleisti, nes GTA:SA failas yra netinkamas arba jo nÄ—ra:" +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Atjungta: prisijungimas buvo atmestas" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "" +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 +#, c-format +msgid "No such mod installed (%s)" +msgstr "Tokia modifikacija nÄ—ra įdiegta (%s)" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA negalima paleisti, nes GTA:SA yra netinkamas arba jo nÄ—ra:" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Blogas atsakas iÅ¡ serverio (2)" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Patikrinkite, ar antivirusinÄ—je nÄ—ra klaidingai aptiktas, pabandykite pridÄ—ti GTA:SA kaip programos iÅ¡imtį ir iÅ¡ naujo paleiskite MTA:SA." +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Blogas atsakas iÅ¡ serverio (1)" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Generuoti GTA:SA" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Lietuvių" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA negalima paleisti, nes GTA:SA vykdomas failas neįkeliamas:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Užimta" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Sutvarkyti GTA:SA" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Å iuo metu neįmanoma patikrinti atnaujinimų" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA negalima paleisti, nes nepavyko pataisyti GTA:SA:" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "Reikalaujamas MTA:SA %s" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 +#: Client/core/CVersionUpdater.cpp:1631 #, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA negali tÄ™sti darbo, nes diske %s nepakanka laisvos vietos." +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Patobulintos MTA:SA %s versijos atnaujinimas yra bÅ«tinas norint prisijungti į šį serverį.\n\n" +"Ar norite atsisiųsti ir įdiegti MTA:SA %s ?" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "TrÅ«ksta failo:" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Ar norite paleisti MTA:SA %s ir prisijungti į šį serverį ?" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Jei MTA nepasileidžia, praÅ¡ome perraÅ¡yti GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Å iuo metu prisijungti neįmanoma.\n\n" +"PraÅ¡ome bandyti vÄ—liau." -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Atnaujinti diegimo nustatymus" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Jungiamasi" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Atnaujinti suderinamumo nustatymus" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "PraÅ¡ome palaukti..." -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Nežinomas" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "TIKRINAMA" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "ATNAUJINIMO PATIKRINIMAS" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Atnaujinimo nereikia" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "ATSISIUNÄŒIAMA" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "laukiama..." -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "PRIVALOMAS ATNAUJINIMAS" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Pasirinkite savo Grand Theft Auto: San Andreas įdiegimo aplankÄ…" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Jei norite prisijungti, privalote atnaujinti MTA.\n\n" +"Ar norite atnaujinti dabar ?" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Klaida įkeliant %s modulį! (%s)" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "NEPRIVALOMAS ATNAUJINIMAS" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Tai pirmas %s paleidimas.\n\n" -"Ar norite nukopijuoti nustatymus iÅ¡ %s ?" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Serveris rekomenduoja atsinaujinti, bet tai nÄ—ra privaloma.\n\n" +"Ar norite atsinaujinti dabar ?" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA nepavyko atidaryti failo '%s'" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "Å iuo metu atnaujinimas nÄ—ra prieinamas.\n\n" +"PraÅ¡ome patikrinti www.multitheftauto.com" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "TrÅ«ksta GTA:SA failo '%s'. " +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "KLAIDŲ IÅ SAUGOJIMAS" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA nepavyko įkelti modelio." +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Neįmanoma sukurti bylos." -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Jei neseniai keitÄ—te gta3.img, tada pabandykite perraÅ¡yti GTA:SA." +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "ATSISIUNTIMO KLAIDA" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA nepavyko pridÄ—ti patobulinimo maÅ¡inai." +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Atsisiųstas failas yra neteisingas." -#: Client/loader/Utils.cpp:1631 -#, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA surado klaidų faile '%s'" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "DÄ—l neaiÅ¡kios priežasties." -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Ar jÅ«sų kompiuteris persikrovÄ— bežaidžiant MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "ATSISIUNTIMAS BAIGTAS" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "PraÅ¡ome iÅ¡jungti sekanÄias programas prieÅ¡ tÄ™sdami darbÄ…:" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr "- Nežinoma problema ties _DialogUpdateResult" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Tinklalapio praÅ¡ymai" +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "PAKEISTOS GTA:SA BYLOS" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Serveris praÅ¡o užkrauti Å¡ias svetaines (vÄ—liau):" +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Gerai" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NIEKADA NEÄ®VESKITE SVARBIOS INFORMACIJOS APSAUGAI NUO VAGYSÄŒIŲ" +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "KLAIDA" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Prisiminti pasirinkimÄ…" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Kai kurių MTA:SA data bylÅ« trÅ«ksta.\n\n\n" +"PraÅ¡ome įdiegti MTA:SA iÅ¡ naujo" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Leisti" +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% baigta" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "AtÅ¡aukti" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Laukiama atsakymo - %-3d" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ KOMANDOS PAGALBA ]***\n" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Naudojate kÅ«rÄ—jų versijÄ…! Tai yra versija skirta testavimui ir negali bÅ«ti naudojama prisijungimui į vieÅ¡us serverius!" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Å iuo metu yra %d:%02d:%02d" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA negaus daugiau atnaujinimų Vista ir XP operacinÄ—se sistemose po 2019 metų liepos mÄ—nesio.\n\n" -"Atnaujinkite Windows, kad galÄ—tumÄ—te žaisti naujausiuose serveriuose." +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "bandoma prisijungti: tinklas dar nÄ—ra paruoÅ¡tas, palaukite truputį" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Ketinate atsijungti iÅ¡ serverio.\n\n" -"Ar tikrai to norite?" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "Prisijungti: SintaksÄ— yra 'connect [ ]'" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "ATSIJUNGIMO PERSPÄ–JIMAS" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "prisijungti: Netinkamas porto numeris" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "prisijungti: Jungiamasi į %s:%u..." -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Lietuvių" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "prisijungti: nepavyko prisijungti į %s:%u" + +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "prisijungti: Nepavyko iÅ¡krauti dabartinÄ—s modifikacijos" + +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "bandymas prisijungti iÅ¡ naujo: tinklas dar nÄ—ra paruoÅ¡tas, palaukite truputį" + +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "bandymas prisijungti iÅ¡ naujo: neteisingas prievado numeris" + +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "bandymas prisijungti iÅ¡ naujo prie %s:%u..." + +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "bandymas prisijungti iÅ¡ naujo prie %s:%u nepavyko!" + +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Ä®kelti visus valdymo nustatymus iÅ¡ GTA" + +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "KonfigÅ«racijos byla iÅ¡saugota" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "JÅ«sų serijinis numeris yra: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "NUSTATYMAI" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Pagrindinis" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Vaizdas" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Garsas" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Mygtukų priskirimai" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Valdikliai" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "SÄ…saja" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Interneto NarÅ¡yklÄ—" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "IÅ¡samiau" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Ä®kelti numatytuosius" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "PelÄ—s jautrumas:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Vertikalaus nusitaikymo jautrumas:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "PelÄ—s nustatymai" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Sukeisti pelÄ—s vertikaliÄ… ašį" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Vairavimas su pele" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Skraidymas su pele" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Valdymo pulto nustatymai" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standartinis valdymas (PelÄ— + KlaviatÅ«ra)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Klasikinis valdymas (Valdymo pultas)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Negyvoji Zona" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Sodrumas" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Pasirinkite 'Mygtukų priskirimai' valdymo pulto mygtukams." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Kairioji valdymo pulto svirtis" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "DeÅ¡inioji valdymo pulto svirtis" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "APIBŪDINIMAS" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "MYGTUKAS" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. MYGTUKAS" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Slapyvardis:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "IÅ¡saugoti serverių slaptažodžius" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "AutomatiÅ¡kai naujinti serverių narÅ¡yklÄ™" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Leisti siųsti ekrano turinį" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Leisti iÅ¡orinius garsus" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Visada rodyti atsisiuntimo langÄ…" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" -msgstr "" +msgstr "Ä®jungti ryšį su Discord Rich Presence" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" -msgstr "" +msgstr "Ä®jungti GTA:SA žaidimo bÅ«senos rodymÄ… „Steam“ platformoje" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" -msgstr "" +msgstr "IÅ¡saugoti nuotraukas, padarytas fotoaparatu, į GTA San Andreas naudotojo failų aplankÄ…" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" -msgstr "" +msgstr "Paklausti patvirtinimo prieÅ¡ atsijungiant nuo serverio per pagrindinį meniu" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Naudoti modifikuotas GTA:SA bylas" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "ŽemÄ—lapio atkÅ«rimo parinktys" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Nepermatomumas:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" -msgstr "" +msgstr "Vaizdo raiÅ¡ka:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" -msgstr "" +msgstr "1024 x 1024 (Numatytoji)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" -msgstr "" +msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Pagrindinis garsas:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Radijo garsumas:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Efektų garsumas:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA garsai:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "KalbanÄiųjų garsumas:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Grojimo režimas:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Bendra" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Radijos pasirinkimai" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Radijo Glodintuvas" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Autom. radijo derinimas" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Ä®keltų dainų parinktys" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Radijas" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Atsitiktinis" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Nuoseklus" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "AutomatinÄ— medijos paieÅ¡ka" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Nutildymo pasirinkimai" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Nutildyti visus garsus kol žaidimas nuleistas" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Nutildyti radijo garsus kol žaidimas nuleistas" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Nutildyti efektų garsus kol žaidimas nuleistas" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Nutildyti MTA garsus kol žaidimas nuleistas" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Nutildyti Å¡nekanÄiųjų garsus kol žaidimas nuleistas" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Skiriamoji geba:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Matymo laukas:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Matomumo distancija:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "RyÅ¡kumas:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Efektų kokybÄ—:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anisotropic filtravimas:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "AÅ¡trių kraÅ¡tų glodinimo bÅ«das:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Vaizdo santykis:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Paleisti lange" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "Atsižvelgti į DPI" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Standartinis" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Be kraÅ¡tų iÅ¡laikant rez." -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mip Mapping" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Žema" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "VidutinÄ—" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "AukÅ¡ta" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Labai aukÅ¡ta" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "IÅ¡jungta" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Auto" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD santykis su ekranu" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Volumetriniai Å ešėliai" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "ŽolÄ—s efektas" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "KarÅ¡Äio bangelÄ—s" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Padangų dÅ«mai ir t.t." -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "DinamiÅ¡ki pÄ—sÄiųjų Å¡ešėliai" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Liejimas judesiu" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Vainiko lietaus atspindžiai" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Pilnas Lango Nuleidimas" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Ä®jungti Prietaisų Pasirinkimo DialogÄ…" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Rodyti netinkamas ekrano raiÅ¡kas" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Visada vaizduoti transporto priemones aukÅ¡Äiausia raiÅ¡ka" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Visada vaizduoti personažus aukÅ¡Äiausia raiÅ¡ka" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Naudoti nutolusius tinklalapius" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Naudoti Javascript nutolusiuose tinklalapiuose" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" -msgstr "" +msgstr "Ä®jungti vaizdo apdorojimÄ… GPU" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Juodasis sÄ…raÅ¡as" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Ä®veskite puslapį pvz. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Blokuoti" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Puslapis" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Panaikinti puslapį" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Baltasis sÄ…raÅ¡as" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Leisti" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Kita" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Greitas CJ rÅ«bų krovimas:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "NarÅ¡yklÄ—s greitis:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Pavienis prisijungimas:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Paketo etiketÄ—:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Progreso animacija:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Veiksmų pirmenybÄ—:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Derinimo nustatymas:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Laikinoji atmintis:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Versijos atnaujinimo tipas:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Ä®raÅ¡yti svarbius atnaujinimus:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Ä®jungta" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Labai lÄ—tas" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Numatytas" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Greitas" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normalus" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "VirÅ¡ normalaus" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Min" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Maks" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 suderinamumas:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-bitų spalvos" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "PelÄ—s pataisymas" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Kliento resursų failai:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Rodyti tinklo narÅ¡yklÄ—je" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" -msgstr "" +msgstr "Nustatyti CPU 0 branduolį, kad pagerintumÄ—te žaidimo naÅ¡umÄ…" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Automatinis naujinimas" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Tikrinti, ar yra atnaujinimų" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Kai kurie nustatymai pasikeis tik paleidus MTA iÅ¡ naujo" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Ar norite perkrauti dabar?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "REIKALINGAS PERKROVIMAS" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Kai kurie nustatymai bus pakeisti kai atsijungsite iÅ¡ serverio" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Ar norite atsijungti dabar?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "ATSIJUNGIMAS BŪTINAS" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Valdymo pultas nerastas - Patikrinkite jungtis ir perkraukite žaidimÄ…" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Priskiriama aÅ¡is" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Pajudinkite ašį priskirimui, arba ESC iÅ¡valymui" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Kalba:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "IÅ¡vaizda:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "RuoÅ¡iniai:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Kalb. langas" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Ä®kelti" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Spalvos" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "IÅ¡sidÄ—stymas" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Nustatymai" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "SusiraÅ¡inÄ—jimo Fonas" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Kalb. lango tekstas" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Ä®vedimo Fonas" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Ä®vesties lango tekstas" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Linijos:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Dydis:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Ilgis:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Dydis" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "po" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "kitoms" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "sek" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Blukimas" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "PaslÄ—pti senas eilutes" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horizontalus:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Vertikalus:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Teksto Lygiavimas:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-Kompensacija:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-Kompensacija:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Pozicija" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "KairÄ—n" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Centre" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "DeÅ¡inÄ—n" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "VirÅ¡uj" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "ApaÄioj" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Å riftas" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "PaslÄ—pti fonÄ…, kai nÄ—ra raÅ¡oma" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Slapyvardžio užbaigimas paspaudus \"Tab\" mygtukÄ…" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Leisti serveriui tvykstelÄ—ti langÄ…" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Leisti 'tray balloon' praneÅ¡imus" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "SusiraÅ¡inÄ—jimo teksto juodos/baltos kontÅ«ras" @@ -1543,89 +1836,95 @@ msgstr "SusiraÅ¡inÄ—jimo teksto juodos/baltos kontÅ«ras" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Spauskite mygtukÄ… priskyrimui, arba ESC iÅ¡valymui" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Priskiriamas pirminis mygtukas" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Priskiriamas antrinis mygtukas" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA ŽAIDIMO VALDYMAS" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "MTA VALDYMAS" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "JÅ«sų slapyvardyje yra netinkamų simbolių!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Pagrindinis meniu" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" -msgstr "" +msgstr "Žaidime" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Raudona:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Žalia:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "MÄ—lyna:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Permatomumas:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Spalva" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "PeržiÅ«ra" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "PraÅ¡ome atsijungti prieÅ¡ pakeiÄiant kalbÄ…" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "PraÅ¡ome atsijungti prieÅ¡ keiÄiant iÅ¡vaizdÄ…" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Volumetriniai Å¡ešėliai gali sukelti sunkumų kai kurioms sistemoms.\n\n" "Ar tikrai norite įjungti juos?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "VEIKIMO Ä®SPÄ–JIMAS" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Ekrano siuntimas yra reikalaujamas kai kuriuose serveriuose dÄ—l sukÄiavimo susekimo.\n\n" "(KalbÄ—jimo langas ir GUI yra neįtraukiamas į nuotraukÄ…)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "EKRANO Ä®KÄ–LIMO INFORMACIJA" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1633,21 +1932,21 @@ msgstr "Kai kurie skriptai gali leisti garsus, pvz., radijÄ…, iÅ¡ interneto.\n\n "IÅ¡jungus šį nustatymÄ… gali suprasteti tinklo ryÅ¡ys\n" "pralaidumo suvartojimas.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "IÅ ORINIAI GARSAI" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" -msgstr "" +msgstr "SUTIKIMAS LEISTI DUOMENŲ DALINIMÄ„SI" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1657,11 +1956,7 @@ msgstr "Kai kurie failai Å¡io GTA:SA data aplanko vietoje yra pakeisti.\n" "TaÄiau, PAKEISTOS GTA:SA BYLOS YRA BLOKUOJAMOS DAUGELIO SERVERIŲ\n\n" "Ar tikrai norite jas naudoti?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "PAKEISTOS GTA:SA BYLOS" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1671,550 +1966,253 @@ msgstr "DPI suvokimo įgalinimas yra eksperimentinÄ— funkcija ir\n" "Jei įjungsite Å¡iÄ… parinktį, gali kilti grafinių problemų.\n\n" "Ar tikrai norite įjungti Å¡iÄ… parinktį?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "EKSPERIMENTINÄ– FUNKCIJA" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" -msgstr "" +msgstr "Å ios parinkties iÅ¡jungimas nerekomenduojamas, nebent patiriate naÅ¡umo problemų.\n\n" +"Ar tikrai norite jÄ… iÅ¡jungti?" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "PraÅ¡ome įvesti slapyvardį" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "PraÅ¡ome įvesti slapyvardį, kurį naudosite žaidime. \n" "Tai bus jÅ«sų vardas su kuriuo prisijungsite ir žaisite serveryje" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Labai eksperimentinÄ— naujovÄ—" -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Sustabdo strigimus su CJ variacijomis (Naudoja 65MB daugiau RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Senesni marÅ¡rutizatoriai gali reikalauti lÄ—tesnio greiÄio atnaujinant." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Ä®junkite, jei norite naudoti tik vienÄ… prisijungimÄ… kol siunÄiatÄ—s." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "ŽymÄ—ti tinklo paketus MTA srauto identifikavimui tiekÄ—jams." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "BesisukanÄio ratuko animacija ekrano apaÄioje" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Visada pasirinkite numatytÄ…. (Å is nustatymas neiÅ¡saugomas)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maksimalus paprastai yra geriausias" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Auto naujinimas:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Pasirinkite numatytÄ…, nebent pageidaujate pildyti klaidų ataskaitas." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Pasirinkite numatytÄ… automatiniam atnaujinimų įraÅ¡ymui." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-bitų spalvos:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Ä®jungti 16 bitų spalvų režimus - Reikalingas MTA paleidimas iÅ¡ naujo" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "PelÄ—s pataisymas:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "PelÄ—s valdymo pataisymas - Gali prireikti paleisti kompiuterį iÅ¡ naujo" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" -msgstr "" +msgstr "CPU branduolis:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." -msgstr "" - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Nežinoma komanda arba veiksmažodis" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Užimta" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Å iuo metu neįmanoma patikrinti atnaujinimų" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "Reikalaujamas MTA:SA %s" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Patobulintos MTA:SA %s versijos atnaujinimas yra bÅ«tinas norint prisijungti į šį serverį.\n\n" -"Ar norite atsisiųsti ir įdiegti MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Ar norite paleisti MTA:SA %s ir prisijungti į šį serverį ?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Å iuo metu prisijungti neįmanoma.\n\n" -"PraÅ¡ome bandyti vÄ—liau." +msgstr "Keiskite tik jei kyla stabilumo problemų." -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Jungiamasi" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "PraÅ¡ome palaukti..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "TIKRINAMA" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "ATNAUJINIMO PATIKRINIMAS" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Atnaujinimo nereikia" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "ATSISIUNÄŒIAMA" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "laukiama..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "PRIVALOMAS ATNAUJINIMAS" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Jei norite prisijungti, privalote atnaujinti MTA.\n\n" -"Ar norite atnaujinti dabar ?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "NEPRIVALOMAS ATNAUJINIMAS" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Serveris rekomenduoja atsinaujinti, bet tai nÄ—ra privaloma.\n\n" -"Ar norite atsinaujinti dabar ?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "KLAIDŲ IÅ SAUGOJIMAS" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Neįmanoma sukurti bylos." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "ATSISIUNTIMO KLAIDA" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Atsisiųstas failas yra neteisingas." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "DÄ—l neaiÅ¡kios priežasties." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "ATSISIUNTIMAS BAIGTAS" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "- Nežinoma problema ties _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Gerai" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "KLAIDA" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Kai kurių MTA:SA data bylÅ« trÅ«ksta.\n\n\n" -"PraÅ¡ome įdiegti MTA:SA iÅ¡ naujo" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% baigta" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Laukiama atsakymo - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Prisijungimas nepavyko. Pateiktas netinkamas slapyvardis!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Prisijungimas nepavyko. Pateiktas netinkamas adresas!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Prisijungimas į %s su portu %u nepavyko!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Jungiamasi į %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "JUNGIAMASI" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "BaigÄ—si prisijungimui skirtas laikas" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Atjungta: nežinoma protokolo klaida" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Atjungta: buvote atjungtas nuotoliniu bÅ«du" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Atsijungta: NutrÅ«ko ryÅ¡ys su nuotoliu" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Atjungta: jÅ«sų prisijungimas yra užblokuotas Å¡iame serveryje" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Atsijungta: atsijungta nuo serverio " - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Atsijungta: ryÅ¡ys su serveriu buvo prarastas" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Atjungta: prisijungimas buvo atmestas" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Tokia modifikacija nÄ—ra įdiegta (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Blogas atsakas iÅ¡ serverio (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Blogas atsakas iÅ¡ serverio (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "NAUJIENOS" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "PeržiÅ«rÄ—kite paskutines naujienas" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONSOLÄ–" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "KritinÄ— klaida" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "KAD PATAISYTI, PAÅ ALINKITE FAILÄ„:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s modulis yra neteisingas!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Klaida vykdant URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "Å¡is pagalbos ekranas" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "iÅ¡jungia programÄ…" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "rodo versijÄ…" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "rodo laikÄ…" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "rodo vartotojo sÄ…sajÄ…" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "rodo visus mygtukų priskirimus" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "rodo jÅ«sų serijinį numerį" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "jungiasi į serverį (adresas portas slapyvardis slaptažodis)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "jungiasi į ankstesnį serverį" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "priskiria mygtukÄ… (mygtukas valdiklis)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "paÅ¡alina priskirimÄ… (mygtukas)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "nukopijuoja numatytuosius gta valdiklius" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "padaro nuotraukÄ…" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "nedelsiant iÅ¡saugo konfiguracijÄ…" -#: Client/core/CCore.cpp:1391 +#: Client/core/CCore.cpp:1494 msgid "clears the debug view" msgstr "iÅ¡valo derinimo vaizdÄ…" -#: Client/core/CCore.cpp:1392 +#: Client/core/CCore.cpp:1495 msgid "scrolls the chatbox upwards" msgstr "paslenka pokalbį aukÅ¡tyn" -#: Client/core/CCore.cpp:1393 +#: Client/core/CCore.cpp:1496 msgid "scrolls the chatbox downwards" msgstr "paslenka pokalbį žemyn" -#: Client/core/CCore.cpp:1394 +#: Client/core/CCore.cpp:1497 msgid "scrolls the debug view upwards" msgstr "paslenka derinimo tekstÄ… aukÅ¡tyn" -#: Client/core/CCore.cpp:1395 +#: Client/core/CCore.cpp:1498 msgid "scrolls the debug view downwards" msgstr "paslenka derinimo tekstÄ… žemyn" -#: Client/core/CCore.cpp:1398 +#: Client/core/CCore.cpp:1501 msgid "shows the memory statistics" msgstr "rodo atminties statistikas" -#: Client/core/CCore.cpp:1399 +#: Client/core/CCore.cpp:1502 msgid "shows the frame timing graph" msgstr "rodo kadrų laiko grafikÄ…" -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ KOMANDOS PAGALBA ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Å iuo metu yra %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "Prisijungti: SintaksÄ— yra 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "prisijungti: Netinkamas porto numeris" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "prisijungti: Jungiamasi į %s:%u..." - -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "prisijungti: nepavyko prisijungti į %s:%u" - -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "prisijungti: Nepavyko iÅ¡krauti dabartinÄ—s modifikacijos" - -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" - -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Ä®kelti visus valdymo nustatymus iÅ¡ GTA" - -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "KonfigÅ«racijos byla iÅ¡saugota" - -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "JÅ«sų serijinis numeris yra: %s" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "skirta kÅ«rÄ—jams: naujienų perkrovimas" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "PagreiÄio AÅ¡is" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Naudojate kÅ«rÄ—jų versijÄ…! Tai yra versija skirta testavimui ir negali bÅ«ti naudojama prisijungimui į vieÅ¡us serverius!" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Stabdymo AÅ¡is" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA negaus daugiau atnaujinimų Vista ir XP operacinÄ—se sistemose po 2019 metų liepos mÄ—nesio.\n\n" +"Atnaujinkite Windows, kad galÄ—tumÄ—te žaisti naujausiuose serveriuose." -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programavimas" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Ketinate atsijungti iÅ¡ serverio.\n\n" +"Ar tikrai to norite?" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Pagalbininkai" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "ATSIJUNGIMO PERSPÄ–JIMAS" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Žaidimo Dizainas / Scenarijus" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "INFORMACIJA" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Kalbos PlÄ—tra" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "NAUJIENOS" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Atnaujinimų autoriai" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "PeržiÅ«rÄ—kite paskutines naujienas" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Ypatinga padÄ—ka" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Nuotraukos dydis %d baitų, bet tikÄ—tasi %d" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Å i programinÄ— įranga ir projektas naudoja Å¡ias bibliotekas ir programinÄ™ įrangÄ…:" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Ekranvaizdis nepavyko" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Ar norite pamatyti Å¡iek tiek pagalbos tinkle apie Å¡ia problemÄ… ?" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Ekranas nufotografuotas: '%s'" + +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Nežinoma komanda arba veiksmažodis" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2389,25 +2387,56 @@ msgid "Group control backwards" msgstr "Gaujos nurodymas atsitraukti" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Nepavyko įkelti jÅ«sų pasirinktos iÅ¡vaizdos bei numatytosios iÅ¡vaizdos, praÅ¡ome įdiegti MTA iÅ¡ naujo." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Nuotraukos dydis %d baitų, bet tikÄ—tasi %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Ar norite pamatyti Å¡iek tiek pagalbos tinkle apie Å¡ia problemÄ… ?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Ekranvaizdis nepavyko" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONSOLÄ–" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Ekranas nufotografuotas: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programavimas" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Pagalbininkai" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Žaidimo Dizainas / Scenarijus" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Kalbos PlÄ—tra" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Atnaujinimų autoriai" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Ypatinga padÄ—ka" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Å i programinÄ— įranga ir projektas naudoja Å¡ias bibliotekas ir programinÄ™ įrangÄ…:" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "PagreiÄio AÅ¡is" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Stabdymo AÅ¡is" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2415,6 +2444,65 @@ msgstr "Nepavyko paleisti Direct3D9.\n\n" "PraÅ¡ome įsitikinti, kad DirectX End-User Runtime ir\n" "naujausi Windows Service Packs yra teisingai įraÅ¡yti." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Neutralus" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "žaidÄ—jas" +msgstr[1] "žaidÄ—jai" +msgstr[2] "žaidÄ—jų" +msgstr[3] "žaidÄ—jai" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "įjungta" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "serveris" +msgstr[1] "serveriai" +msgstr[2] "serverių" +msgstr[3] "serveriai" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Laukiamas pirminis serverių sÄ…raÅ¡as (praÄ—jo %lu ms)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Pirminis serverių sÄ…raÅ¡as nepasiekiamas." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Pirminis serverių sÄ…raÅ¡as negautas." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Atsarginių serverių sÄ…raÅ¡as)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Neįmanoma pririÅ¡ti LAN-transliavimo prievado" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Bandoma surasti LAN serverius" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2468,7 +2556,7 @@ msgstr "VÄ—lavimas:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "ŽaidÄ—jų sÄ…raÅ¡as" @@ -2495,40 +2583,39 @@ msgstr "Prisijungti į serverį, kai tiktai atsiras vietos." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "PRAÅ OME PATEIKTI SERVERIO SLAPTAŽODÄ®" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "BaigÄ—si laikas" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Užklausiama..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "SERVERIŲ NARÅ YKLÄ–" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internetas" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Vietinis" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "MÄ—gstamiausi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Paskutiniai" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2536,302 +2623,367 @@ msgstr "GREITAM PRISIJUNGIMUI:\n\n" "Ä®raÅ¡ykite adresÄ… ir portÄ… į adresam skirtÄ… laukÄ….\n" "Arba pasirinkite serverį iÅ¡ narÅ¡ytųjų ir spauskite 'Jungtis'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "PAGALBA" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Atnaujinti" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "PridÄ—ti prie mÄ—gstamiausiųjų" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Prisijungti" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Serverio informacija" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "IeÅ¡koti serverių" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "IeÅ¡koti žaidÄ—jų" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "PradÄ—ti paieÅ¡kÄ…" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "IeÅ¡koti žaidÄ—jų..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "IeÅ¡koti serverių..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Vardas" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "ŽaidÄ—jai" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Delsa" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Žaidimo tipas" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Ä®traukti:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "TuÅ¡Äias" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Pilnas" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Užrakintas" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "IÅ¡jungtas" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Kitos Versijos" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Atgal" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Ä®keliama..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "..kraunama.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Nepateiktas adresas!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Nežinomas protokolas!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "PraÅ¡ome naudoti mtasa:// protokolÄ…!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Netinkamas slapyvardis! PraÅ¡ome eiti į nustatymus ir pasirinkti naujÄ… slapyvardį!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Kad prisijungtumÄ—te į serverį, jums reikia jį pasirinkti." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Neutralus" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problema su grafikos tvarkykle" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "žaidÄ—jas" -msgstr[1] "žaidÄ—jai" -msgstr[2] "žaidÄ—jų" -msgstr[3] "žaidÄ—jai" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Nepavyksta rasti tinkamos ekrano raiÅ¡kos." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "įjungta" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Ar tikrai norite naudoti Å¡iÄ… ekrano raiÅ¡kÄ…?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "serveris" -msgstr[1] "serveriai" -msgstr[2] "serverių" -msgstr[3] "serveriai" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Laukiamas pirminis serverių sÄ…raÅ¡as (praÄ—jo %lu ms)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Pirminis serverių sÄ…raÅ¡as nepasiekiamas." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Tinklalapio praÅ¡ymai" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Pirminis serverių sÄ…raÅ¡as negautas." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Serveris praÅ¡o užkrauti Å¡ias svetaines (vÄ—liau):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Atsarginių serverių sÄ…raÅ¡as)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NIEKADA NEÄ®VESKITE SVARBIOS INFORMACIJOS APSAUGAI NUO VAGYSÄŒIŲ" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Neįmanoma pririÅ¡ti LAN-transliavimo prievado" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Prisiminti pasirinkimÄ…" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Bandoma surasti LAN serverius" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "AtÅ¡aukti" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Versijos galiojimo laikas baigÄ—si." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "atsijungia iÅ¡ žaidimo" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "rodo vardų etiketes" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "rodo pokalbių langÄ…" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "rodo tinklo statistikas" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "atidaro pokalbių įvedimo langÄ…" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "perduoda balsÄ… kitiems žaidÄ—jams" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "įlipa į tr. priemonÄ™ kaip keleivis" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "sekantis radijo kanalas" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "buvÄ™s radijos kanalas" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" -msgstr "" +msgstr "įjungia žaidÄ—jo žemÄ—lapio vaizdÄ…" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" -msgstr "" +msgstr "padidina žaidÄ—jo žemÄ—lapio vaizdÄ…" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" -msgstr "" +msgstr "sumažina žaidÄ—jo žemÄ—lapio vaizdÄ…" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" -msgstr "" +msgstr "judina žaidÄ—jo žemÄ—lapį į Å¡iaurÄ™" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" -msgstr "" +msgstr "judina žaidÄ—jo žemÄ—lapį į pietus" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" -msgstr "" +msgstr "judina žaidÄ—jo žemÄ—lapį į rytus" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" -msgstr "" +msgstr "judina žaidÄ—jo žemÄ—lapį į vakarus" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" -msgstr "" +msgstr "prisega žaidÄ—jo žemÄ—lapį" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" -msgstr "" +msgstr "sumažina žaidÄ—jo žemÄ—lapio skaidrumÄ…" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" -msgstr "" +msgstr "padidina žaidÄ—jo žemÄ—lapio skaidrumÄ…" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" -msgstr "" +msgstr "įjungia arba iÅ¡jungia žaidÄ—jo žemÄ—lapio pagalbos tekstÄ…" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "iÅ¡siunÄia žinutÄ™ pasirinktam žaidÄ—jui" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "pakeiÄia į sekantį ginklÄ… sÄ—dint tr. priemonÄ—je" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "pakeiÄia į buvusį ginklÄ… sÄ—dint tr. priemonÄ—je" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "paraÅ¡o informacijÄ… apie dabartinį serverį" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "nustato dydžio daugiklį visiems tekstiniams rodmenims" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Derinimo režimas) rodo 'colshapes'" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Derinimo režimas) paraÅ¡o pasaulio garsų id į derinimo langÄ…" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "SUKURTI SERVERÄ®" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Resursai" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Serverio pavadinimas:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Slaptažodis:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Maks. žaidÄ—jai:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Transliavimas:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Pasirinktas" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Visi" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "PradÄ—ti" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "Seku žaidÄ—jÄ…" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "Laisvas judÄ—jimas" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "ŽemÄ—lapio atsisiuntimo progresas:" @@ -2852,174 +3004,174 @@ msgstr "%s iÅ¡ %s" msgid "Disconnect to cancel download" msgstr "Atsijunkite norÄ—dami atÅ¡aukti siuntimÄ…" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Atjungta: netinkamas slapyvardis" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Atsijungta iÅ¡ serverio" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Atjungta: Serijinis numeris užblokuotas.\n" "Priežastis: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Atjungta: PriÄ—jimas užblokuotas.\n" "Priežastis: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Atjungta: SÄ…skaita užblokuota.\n" "Priežastis: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Atjungta: Versija nesutampa" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Atjungta: Per daug prisijungimų. PraÅ¡ome palaukti minutÄ™ ir bandyti dar kartÄ…." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Atjungta: Serveris iÅ¡ skirtingos Å¡akos.\n" "Informacija: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Atjungta: Bloga versija.\n" "Informacija: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Atjungta: Serveris naudoja naujesnÄ™ versijÄ….\n" "Informacija: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Atjungta: Serveris naudoja senesnÄ™ versijÄ….\n" "Informacija: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Atjungta: Slapyvardis jau naudojamas" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Atsijungta: nepavyko sukurti žaidÄ—jo elemento." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Atjungta: Serveris atmetÄ— prisijungimÄ…: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Atjungta: Serijinio kodo patvirtinimas nepavyko" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" -msgstr "" +msgstr "Atsijungta: serijinis numeris jau naudojamas" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Atjungta: Prisijungimo desinchronizacija %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Atjungta: %s iÅ¡metÄ— jus iÅ¡ serverio" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Atjungta: %s uždraudÄ— jums priÄ—jimÄ… prie serverio" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Atjungta: Serveris iÅ¡sijungÄ— arba persikrauna" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "JÅ«s buvote iÅ¡mestas iÅ¡ žaidimo" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Å is serveris reikalauja originalaus gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "PraÅ¡ome pakeisti gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Å is serveris neleidžia modifikuotu D3D9.DLL" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "PaÅ¡alinkite D3D9.DLL iÅ¡ GTA aplanko ir paleiskite MTA iÅ¡ naujo" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Serveris neleidžia naudoti virtualių maÅ¡inų" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Å is serveris praÅ¡o, kad bÅ«tų ijungtas driver signing" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "IÅ¡ naujo paleiskite kompiuterį" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Serveris aptiko trÅ«kstamų anti-cheat komponentų" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Perkraukite MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Serveris praÅ¡o originalaus gta3.img ir gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Pakeiskite gta3.img arba gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Å is serveris draudžia Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Ä®sitikinkite, kad jokia kita programa nemodifikuoja MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Liko Laiko:" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" @@ -3028,7 +3180,7 @@ msgstr[1] "%d dienos" msgstr[2] "%d dienų" msgstr[3] "%d dienos" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" @@ -3037,7 +3189,7 @@ msgstr[1] "%d valandos" msgstr[2] "%d valandų" msgstr[3] "%d valandos" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" @@ -3046,7 +3198,7 @@ msgstr[1] "%d minutÄ—s" msgstr[2] "%d minuÄių" msgstr[3] "%d minutÄ—s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3056,296 +3208,206 @@ msgstr[2] "%d minuÄių" msgstr[3] "%d sekundÄ—s" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Atjungta" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Atsisiuntimo klaida: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" -msgstr "" +msgstr "Skraidau su UFO aplink" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" -msgstr "" +msgstr "Ramiai važinÄ—ju aplink" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" -msgstr "" +msgstr "Plaukiu bangomis" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" -msgstr "" +msgstr "Važiuoju traukiniu į" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" -msgstr "" +msgstr "Skraidau aplink" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" -msgstr "" +msgstr "VažinÄ—ju aplink" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" -msgstr "" +msgstr "MonstriÅ¡ku džipu važinÄ—ju aplink" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" -msgstr "" +msgstr "KeturraÄiu važinÄ—ju aplink" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" -msgstr "" +msgstr "Å okinÄ—ju aplink" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" -msgstr "" +msgstr "Darau keistus dalykus" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" -msgstr "" +msgstr "Laipioju aplink" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" -msgstr "" +msgstr "Å audau iÅ¡ automobilio važiuojant" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." -msgstr "" +msgstr "Blub blub..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" -msgstr "" +msgstr "Kvepuoju vandeniu" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" -msgstr "" +msgstr "SkÄ™stu" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" -msgstr "" +msgstr "Slepiuosi už priedangos" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" -msgstr "" +msgstr "Kovoju" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" -msgstr "" +msgstr "Mosikuoju kumÅ¡Äiais" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" -msgstr "" +msgstr "Å audau kvailius" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" -msgstr "" +msgstr "Skraidau su jetpack" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" -msgstr "" +msgstr "Literaliai užsidegÄ™s" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" -msgstr "" +msgstr "Degu" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" -msgstr "" +msgstr "Plaukiu" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" -msgstr "" +msgstr "PlÅ«duriuoju aplink" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" -msgstr "" +msgstr "Persekiojamas ryklio" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" -msgstr "" +msgstr "Dustu iki mirties" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Ä®einama į žaidimÄ… ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Neprisijungta; praÅ¡ome naudoti Jungtis arba komandÄ… 'connect', kad prisijungtumÄ—te į serverį." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Nepavyko paleisti vietinio serverio. Žvilgtelkite į konsolÄ™, norÄ—dami sužinoti detaliau." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Vietinis Serveris" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Paleidžiamas vietinis serveris ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" -msgstr "" +msgstr "51 zona" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " -msgstr "" +msgstr "VaikÅ¡tau aplink " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "JÅ«s buvote iÅ¡mestas iÅ¡ žaidimo ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Jungiamasi prie vietinio serverio..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Klaida jungiantis prie serverio." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Prisijungimui prie vietinio serverio baigÄ—si laikas. Pažvelkite į konsolÄ™ detalÄ—ms sužinoti." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Prisijungimas su serveriu prarastas" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Atjungta: serveris Å¡iuo metu yra pilnas" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Atjungta: pateiktas neteisingas slaptažodis" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA kliento patvirtinimas nepavyko!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" -msgstr "" +msgstr "Griovyje" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" -msgstr "" +msgstr "Kelyje į ligoninÄ™" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" -msgstr "" +msgstr "Susitinku su savo kÅ«rÄ—ju" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" -msgstr "" +msgstr "Gailisi savo pasirinkimų" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "SUKURTI SERVERÄ®" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Resursai" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Serverio pavadinimas:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Slaptažodis:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Maks. žaidÄ—jai:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Transliavimas:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Pasirinktas" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Visi" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "PradÄ—ti" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" +msgstr "Miriau" -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problema su grafikos tvarkykle" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Nepavyksta rasti tinkamos ekrano raiÅ¡kos." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Ar tikrai norite naudoti Å¡iÄ… ekrano raiÅ¡kÄ…?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Atsisiuntimo klaida: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3366,11 +3428,11 @@ msgstr "" msgid "Connection error" msgstr "Prisijungimo klaida" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto nebuvo įdiegtas teisingai, praÅ¡ome įdiegti iÅ¡ naujo." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "JÅ«sų narÅ¡klÄ— dabar atidarys tinklapį su Å¡iek tiek informacijos.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/lv_LV/client.pot b/Shared/data/MTA San Andreas/MTA/locale/lv_LV/client.pot index 8bc9430edb9..0353a2c5e41 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/lv_LV/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/lv_LV/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:32\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Latvian\n" "Language: lv_LV\n" @@ -17,72 +17,123 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Kļūda restartÄ“jot MTA:SA\n\n" -"Ja problÄ“ma atkartojÄs, atveriet Uzdevumu PÄrvaldnieku un\n" -"apstÄdiniet 'gta_sa.exe' un 'Multi Theft Auto.exe' procesus\n\n\n" -"MēģinÄt palaist MTA:SA vÄ“lreiz?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "IeslÄ“dz Grand Theft Auto: San Andreas.\n" +"PÄrbaudi, vai spÄ“le atrodas \"Program Files (x86)\" mapÄ“." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Kļūda" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Cita MTA instance darbojÄs.\n\n" -"Ja šī problÄ“ma atkÄrtojÄs, lÅ«dzu restartÄ“jiet savu datoru" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Cita MTA instance darbojÄs.\n\n" -"Vai vÄ“laties to izbeigt?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "IzvÄ“lieties JÅ«su Grand Theft Auto: San Andreas instalÄcijas mapi" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA ir nepiecieÅ¡ama Administratora piekļuve sekojoÅ¡am uzdevumam:\n\n" +" '%s'\n\n" +"LÅ«dzu apstipriniet nÄkoÅ¡ajÄ logÄ." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Kļūda ielÄdÄ“jot %s moduli! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "KopÄ“ failus..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopēšana pabeigta. Viss kÄrtÄ«bÄ." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Pabeidz..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Gatavs!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Jauna %s instalÄcija atrasta.\n\n" +"Vai JÅ«s vÄ“laties kopÄ“t JÅ«su iestatÄ«jumus no %s?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA notika kļūme atverot failu '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA ir pazudis fails '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA ir kļūme ielÄdÄ“jot modeli." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Ja jÅ«s nesen modificÄ“jÄt gta3.img, tad pamēģiniet pÄrinstalÄ“t GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA ir kļūme pievienojot uzlabojumu transportlÄ«dzeklim." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA atrada kļūdu failÄ '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Vai JÅ«su dators restartÄ“jÄs, kad spÄ“lÄ“jÄt MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "LÅ«dzu, aiztaisiet sekojoÅ¡as programmas, pirms turpiniet:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Faila versijas neatbilstÄ«bas kļūda. PÄrinstalÄ“jiet MTA:SA, ja Jums ar to ir problÄ“mas.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Daži faili ir pazuduÅ¡i. PÄrinstalÄ“jiet MTA:SA, ja Jums ar to ir problÄ“mas.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA nav saderÄ«gs ar Windows 'Safe Mode'.\n\n" +"LÅ«dzu restartÄ“jiet jÅ«su datoru.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Vai Jums ir problÄ“mas ar MTA:SA darbÄ«bu?\n\n" "Vai vÄ“laties atgriezt vecÄku versiju?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +141,48 @@ msgstr "Notika problÄ“ma palaižot MTA:SA.\n" "Atgriežot GTA iestatÄ«jumus, dažreiz Å¡o problÄ“mu izdodÄs salabot.\n\n" "Vai jÅ«s vÄ“laties atgriezt GTA iestatÄ«jumus?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA uzstÄdÄ«jumi tika atgriezti.\n\n" "Spiediet LABI, lai turpinÄtu." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Failu nevar izdzÄ“st: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Vai jums ir problÄ“mas ar MTA:SA dabinÄÅ¡anu?.\n\n" "Vai jÅ«s vÄ“laties saņemt tieÅ¡saistes palÄ«dzÄ«bu?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Vai jums ir problÄ“mas startÄ“t MTA:SA?.\n\n" "Vai vÄ“laties nomainÄ«t norÄdÄ«tÄs opcijas?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "PilnekrÄna režīms:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Bez-rÄmju logs" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Vai jums ir problÄ“mas startÄ“t MTA:SA?.\n\n" "Mēģiniet atspÄ“jot norÄdÄ«tos produktus no GTA un MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +190,293 @@ msgstr "BRĪDINÄ€JUMS\n\n" "MTA:SA konstatÄ“ja neparastu aktivitÄti.\n" "LÅ«dzu veiciet datora skenēšanu lai novÄ“rstu draudus sistÄ“mai.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "KonstatÄ“tais fails bija: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "KÄda no GTA: San Andreas instancÄ“m Å¡obrÄ«d darbojÄs. TÄm ir jÄbÅ«t aizvÄ“rtÄm, pirms startÄ“jat MTA:SA. Vai vÄ“laties to darÄ«t tagad?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "InformÄcija" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "NespÄ“j apturÄ“t GTA: San Andreas. Ja problÄ“ma joprojÄm pastÄv, restartÄ“jiet datoru." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Kļūda restartÄ“jot MTA:SA\n\n" +"Ja problÄ“ma atkartojÄs, atveriet Uzdevumu PÄrvaldnieku un\n" +"apstÄdiniet 'gta_sa.exe' un 'Multi Theft Auto.exe' procesus\n\n\n" +"MēģinÄt palaist MTA:SA vÄ“lreiz?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Kļūda" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Cita MTA instance darbojÄs.\n\n" +"Ja šī problÄ“ma atkÄrtojÄs, lÅ«dzu restartÄ“jiet savu datoru" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Cita MTA instance darbojÄs.\n\n" +"Vai vÄ“laties to izbeigt?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "IztrÅ«kst reÄ£istru ieraksti. LÅ«dzu pÄrinstalÄ“jiet Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Ceļs uz JÅ«su GTA: San Andreas instalÄciju satur neatbalstÄ«tas (unicode) rakstzÄ«mes. LÅ«dzu pÄrvietojiet savu Grand Theft Auto: San Andreas instalÄciju, lai izveidotu saderÄ«gu ceļu, kurÅ¡ satur standarta ASCII rakstzÄ«mes un lÅ«dzu pÄrinstalÄ“jiet Multi Theft Auto San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Ceļš uz jÅ«su 'MTA:SA' vai 'GTA: San Andreas'\n" -"instalÄciju satur ';' (semikolu).\n\n" -" Ja jÅ«s satopieties ar problÄ“mÄm darbinot MTA:SA,\n" -" pÄrvietojiet instalÄciju(s) uz vietu kura nesatur semikolu." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "IelÄde neizdevÄs. LÅ«dzu pÄrliecinieties, ka pÄ“dÄ“jie datu faili ir uzinstalÄ“ti pareizi." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "IelÄde neizdevÄs. LÅ«dzu pÄrliecinieties, ka %s ir instalÄ“ts pareizi." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "IelÄde neizdevÄs. NespÄ“j atrast gta_sa.exe iekÅ¡ %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "IelÄde neizdevÄs. %s atrodas GTA mapÄ“. LÅ«dzu izdzÄ“siet, pirms turpiniet." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Galvenajam failam ir nepareizs nosaukums (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "GalvenÄ faila certifikÄta problÄ“ma. IespÄ“jama vÄ«rusu aktivitÄte..\n\n" -"Skatiet tieÅ¡saistes palÄ«dzÄ«bu, ja MTA nestrÄdÄ pareizi." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Datu fails %s ir pazudis. IespÄ“jama vÄ«rusu aktivitÄte.\n\n" -"Apsveriet Multi Theft Auto pÄrinstalēšanu drošības nolÅ«kos.\n" -"Ja MTA nedarbojas pareizi, skatieties tieÅ¡saistes palÄ«dzÄ«bu." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Datu fails %s ir modificÄ“ts. IespÄ“jama vÄ«rusu aktivitÄte.\n\n" -"Apsveriet Multi Theft Auto pÄrinstalēšanu drošības nolÅ«kos.\n" -"Ja MTA nedarbojas pareizi, skatieties tieÅ¡saistes palÄ«dzÄ«bu." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asi faili atrodÄs iekÅ¡ 'MTA:SA' vai 'GTA: San Andreas' instalÄcijas direktorijas.\n\n" -"Noņemiet Å¡os .asi failus, ja Jums ir problÄ“mas ar MTA:SA." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Faila versijas neatbilstÄ«bas kļūda. PÄrinstalÄ“jiet MTA:SA, ja Jums ar to ir problÄ“mas.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Daži faili ir pazuduÅ¡i. PÄrinstalÄ“jiet MTA:SA, ja Jums ar to ir problÄ“mas.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA nav saderÄ«gs ar Windows 'Safe Mode'.\n\n" -"LÅ«dzu restartÄ“jiet jÅ«su datoru.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Labot konfigurÄcijas kļūdu" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Labot nepiecieÅ¡amo pacÄ“luma kļūdu" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "NezinÄms" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "Fails '%s' paÅ¡laik ir bloÄ·Ä“ts %zu procesu dēļ.\n\n" +"Vai vÄ“laties pÄrtraukt sekojoÅ¡os procesus un turpinÄt atjauninÄÅ¡anu?\n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "JÅ«su instalÄcija varÄ“tu bÅ«t bojÄta.\n\n" +"%zu no %zu failiem nevarÄ“ja tikt atjaunoti no rezerves kopijas.\n\n" +"Jums vajadzÄ“tu pÄrinstalÄ“t Multi Theft Auto no vietnes www.multitheftauto.com\n" +"vai mēģinÄt palaist atjaunoÅ¡anu ar administratora tiesÄ«bÄm." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "InstalÄ“ atjauninÄjumus..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Atspiež failus..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA nespÄ“j izpildÄ«t sekojoÅ¡u uzdevumu:\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** AvÄrija notika graphics driver error **\n\n" +"** LÅ«dzu atjaunojiet graphics drivers **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "InstalÄ“t atjaunotos MTA:SA failus" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "NespÄ“j atjaunot failu konfliktu dēļ. LÅ«dzu aizveriet citas aplikÄcijas un atkÄrtojiet" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto netika uzinstalÄ“ts pareizi, lÅ«dzu pÄrinstalÄ“jiet. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "Izveidojiet GTA:SA saites" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA nevar tikt palaists, jo faila kopēšana neizdevÄs:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA nevar tikt palaists, jo MTA:SA fails ir nepareizs vai trÅ«kst:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "KopÄ“t MTA:SA failus" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA nevar tikt palaists, jo GTA:SA fails ir nepareizs vai trÅ«kst:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "Izlabot GTA:SA bibliotÄ“kas" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA nevar tikt palaists, jo GTA:SA izpildÄmais fails ir nepareizs vai trÅ«kst:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "LÅ«dzu, pÄrbaudiet savu pretvÄ«rusa programmu, iespÄ“jams, notikusi nepamatota pozitÄ«va atklÄÅ¡ana. Mēģiniet pievienot izņēmumu GTA:SA izpildÄmajam failam un restartÄ“jiet MTA:SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "Ä¢enerÄ“t GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA nevar tikt palaists, jo GTA:SA izpildÄmais fails nav ielÄdÄ“jams:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Izlabot GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA nevar palaist, jo GTA:SA laboÅ¡ana neizdevÄs:" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "NespÄ“j palaist Grand Theft Auto: San Andreas. LÅ«dzu mēģiniet restartÄ“t, ja problÄ“ma turpinÄs,kontaktÄ“jiet MTA iekÅ¡ www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA instalÄcija nevar turpinÄties, jo %s diskÄ nav vietas." -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas varÄ“tu bÅ«t palaists nepareizi. Vai vÄ“laties to izslÄ“gt?" +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Nevar atrast failu:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Ja MTA nespÄ“j ieslÄ“gties, lÅ«dzu pÄrinstalÄ“jiet GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Atjaunot instalÄcijas uzstÄdÄ«jumus" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Atjaunot saderÄ«bas uzstÄdÄ«jumus" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +484,167 @@ msgstr "GTA: San Andreas varÄ“tu bÅ«t palaists nepareizi. Vai vÄ“laties to izsl #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "JÄ" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "NÄ“" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "LABI" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Iziet" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "PalÄ«dzÄ«ba" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Atcelt" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas radÄs kļūda" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "AvÄrijas informÄcija" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "AtÄ·eksÄ“jiet lai aizsÅ«tÄ«tu Å¡o avÄrijas informÄciju MTA ražotÄjiem" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "TÄdÄ“jÄdi jÅ«s paaugstinÄsiet izredzes Å¡ai avÄrijai tikt novÄ“rstai." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Vai jÅ«s vÄ“laties restartÄ“t MTA: San Andreas ?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - BrÄ«dinÄjums" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "JÅ«su Grand Theft Auto: San Andreas instalÄcijas direktorija sastÄv no Å¡Ädiem failiem:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Å ie faili nav vajadzÄ«gi un var traucÄ“t grafisko lÄ«dzekļu darbÄ«bu Å¡ajÄ MTA:SA versijÄ.\n\n" "Ieteicams Å¡os failus noņemt vai pÄrdÄ“vÄ“t." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "SaglabÄt Å¡os failus un parÄdiet Å¡o brÄ«dinÄjumu arÄ« nÄkamajÄ palaiÅ¡anas reizÄ“" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "NeatgÄdinÄt par Å¡iem failiem atkÄrtoti" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "PÄrdÄ“vÄ“t Å¡os failus no *.dll uz *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "ParÄdÄ«t Å¡os failus" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "SpÄ“lÄ“t MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Nepareizas opcijas" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "Tika konstatÄ“ts NVidia Optimus!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Pamēģiniet katru no šīm opcijÄm, un izvÄ“lieties to, kura strÄdÄ:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Standarta NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - AlternatÄ«vÄ NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Standarta Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - AlternatÄ«vÄ Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Ja jÅ«s nevarat atrisinÄt problÄ“mu, Å¡is var palÄ«dzÄ“t:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Ja jÅ«s jau esat izvÄ“lÄ“juÅ¡ies opciju kura darbojas, Å¡im vajadzÄ“tu palÄ«dzÄ“t:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Piespiedu loga režīms" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "NerÄdÄ«t atkÄrtoti" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "BrÄ«dinÄjums: NevarÄ“ja atrast antivÄ«rusa programmu" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1106 +652,1180 @@ msgstr "MTA nevarÄ“ja noteikt anti-vÄ«rusa aplikÄciju jÅ«su PC.\n\n" "VÄ«rusi sabojÄ MTA darbÄ«bu un var samazinÄt veiktspÄ“ju.\n\n" "Nospiediet 'Help' vairÄk informÄcijas iegūšanai." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Esmu jau instalÄ“jis antivÄ«rusu" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Es neinstalēšu antivÄ«rusu.\n" "Es vÄ“los, lai mans PC lagotu un bÅ«tu iekÅ¡ botneta." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "MeklÄ“ pÄ“c Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "LÅ«dzu palaidiet Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "InstalÄ“ atjauninÄjumus..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Savienojums neizdevÄs. NorÄdÄ«ts nederÄ«gs segvÄrds!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Atspiež failus..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "SavienoÅ¡anÄs neizdevÄs. NorÄdÄ«ts nederÄ«gs hosts!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "KopÄ“ failus..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "SavienoÅ¡anÄs ar %s caur %u portu neizdevÄs!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopēšana pabeigta. Viss kÄrtÄ«bÄ." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Savienojas ar %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Pabeidz..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Gatavs!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "SAVIENOJAS" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA ir nepiecieÅ¡ama Administratora piekļuve sekojoÅ¡am uzdevumam:\n\n" -" '%s'\n\n" -"LÅ«dzu apstipriniet nÄkoÅ¡ajÄ logÄ." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Savienojums iztecÄ“jis" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA nespÄ“j izpildÄ«t sekojoÅ¡u uzdevumu:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "AtvienoÅ¡anÄs: nezinÄma protokola kļūda" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** AvÄrija notika graphics driver error **\n\n" -"** LÅ«dzu atjaunojiet graphics drivers **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "AtvienoÅ¡anÄs: savienojums pazuda attÄlinÄti" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "InstalÄ“t atjaunotos MTA:SA failus" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "AtvienoÅ¡anÄs: savienojums pazuda attÄlinÄti" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "NespÄ“j atjaunot failu konfliktu dēļ. LÅ«dzu aizveriet citas aplikÄcijas un atkÄrtojiet" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Atvienots: jums ir liegta piekļuve Å¡im serverim" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Atvienots: atvienojÄs no servera" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "AtvienojÄs: pÄrtrÅ«ka savienojums ar serveri" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Atvienots: neizdevÄs savienoties" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto netika uzinstalÄ“ts pareizi, lÅ«dzu pÄrinstalÄ“jiet. %s" +msgid "No such mod installed (%s)" +msgstr "Nav ieinstalÄ“ta šī modifikÄcija (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "Izveidojiet GTA:SA saites" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Nav servera atbildes (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA nevar tikt palaists, jo faila kopēšana neizdevÄs:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Nav servera atbildes (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA nevar tikt palaists, jo MTA:SA fails ir nepareizs vai trÅ«kst:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "LatvieÅ¡u" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "KopÄ“t MTA:SA failus" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Aizņemts" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA nevar tikt palaists, jo GTA:SA fails ir nepareizs vai trÅ«kst:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Å obrÄ«d nespÄ“j pÄrbaudÄ«t atjauninÄjumus" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Izlabot GTA:SA bibliotÄ“kas" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s pieprasa" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA nevar tikt palaists, jo GTA:SA izpildÄmais fails ir nepareizs vai trÅ«kst:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "MTA:SA %s atjauninÄjums ir nepiecieÅ¡ams, lai pievienotos izvÄ“lÄ“tajam serverim.\n\n" +"Vai vÄ“laties lejupielÄdÄ“t un instalÄ“t MTA:SA %s ?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "LÅ«dzu, pÄrbaudiet savu pretvÄ«rusa programmu, iespÄ“jams, notikusi nepamatota pozitÄ«va atklÄÅ¡ana. Mēģiniet pievienot izņēmumu GTA:SA izpildÄmajam failam un restartÄ“jiet MTA:SA." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Vai JÅ«s vÄ“laties palaist MTA:SA %s un pievienoties Å¡im serverim ?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Ä¢enerÄ“t GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Å obrÄ«d, nav iespÄ“jams savienoties.\n\n" +"Mēģiniet vÄ“lÄk." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA nevar tikt palaists, jo GTA:SA izpildÄmais fails nav ielÄdÄ“jams:" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "SavienojÄs" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Izlabot GTA:SA" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "LÅ«dzu uzgaidiet..." -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA nevar palaist, jo GTA:SA laboÅ¡ana neizdevÄs:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "PÄ€RBAUDA" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA instalÄcija nevar turpinÄties, jo %s diskÄ nav vietas." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "ATJAUNINÄ€JUMA PÄ€RBAUDE" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Nevar atrast failu:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Nav nepiecieÅ¡ams atjauninÄjums" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Ja MTA nespÄ“j ieslÄ“gties, lÅ«dzu pÄrinstalÄ“jiet GTA:SA" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "LEJUPIELÄ€DÄ’" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Atjaunot instalÄcijas uzstÄdÄ«jumus" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "gaida..." -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Atjaunot saderÄ«bas uzstÄdÄ«jumus" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "OBLIGÄ€TS ATJAUNINÄ€JUMS" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "NezinÄms" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Lai pievienotos Å¡im serverim, Jums ir jÄatjauno MTA.\n\n" +" Vai JÅ«s vÄ“laties atjaunot tagad ?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "Fails '%s' paÅ¡laik ir bloÄ·Ä“ts %zu procesu dēļ.\n\n" -"Vai vÄ“laties pÄrtraukt sekojoÅ¡os procesus un turpinÄt atjauninÄÅ¡anu?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "IETEICAMS ATJAUNINÄ€JUMS" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "JÅ«su instalÄcija varÄ“tu bÅ«t bojÄta.\n\n" -"%zu no %zu failiem nevarÄ“ja tikt atjaunoti no rezerves kopijas.\n\n" -"Jums vajadzÄ“tu pÄrinstalÄ“t Multi Theft Auto no vietnes www.multitheftauto.com\n" -"vai mēģinÄt palaist atjaunoÅ¡anu ar administratora tiesÄ«bÄm." +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Serveris saka, ka ir atjauninÄjums ir ieteicams, bet ne obligÄti.\n\n" +"Vai JÅ«s vÄ“laties atjaunot tagad ?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "KĻŪDAS SAGLABĀŠANA" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "NespÄ“j izveidot failu." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "IzvÄ“lieties JÅ«su Grand Theft Auto: San Andreas instalÄcijas mapi" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "KĻŪDA LEJUPIELÄ€DÄ’JOT" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Kļūda ielÄdÄ“jot %s moduli! (%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "LejupielÄdÄ“tais fails izskatÄs nederÄ«gs." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Jauna %s instalÄcija atrasta.\n\n" -"Vai JÅ«s vÄ“laties kopÄ“t JÅ«su iestatÄ«jumus no %s?" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "KÄda iemesla dēļ." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA notika kļūme atverot failu '%s'" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "LEJUPIELÄ€DE PABEIGTA" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA ir pazudis fails '%s'." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - NezinÄma problÄ“ma iekÅ¡ _DialogUpdateResult" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA ir kļūme ielÄdÄ“jot modeli." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "PÄ€RVEIDOTIE GTA:SA FAILI" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Ja jÅ«s nesen modificÄ“jÄt gta3.img, tad pamēģiniet pÄrinstalÄ“t GTA:SA." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Labi" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA ir kļūme pievienojot uzlabojumu transportlÄ«dzeklim." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "KĻŪDA" -#: Client/loader/Utils.cpp:1631 -#, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA atrada kļūdu failÄ '%s'" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Daži MTA:SA datu faili ir pazuduÅ¡i.\n\n\n" +"LÅ«dzu pÄrinstalÄ“jiet MTA:SA" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Vai JÅ«su dators restartÄ“jÄs, kad spÄ“lÄ“jÄt MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% pabeigti" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "LÅ«dzu, aiztaisiet sekojoÅ¡as programmas, pirms turpiniet:" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Gaida atbildi - %-3d" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "MÄjaslapu pieprasÄ«jumi" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ KOMANDAS PALIDZIBA ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Serveris pieprasa pieeju Å¡ÄdÄm mÄjaslapÄm:" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Pareizs laiks ir %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NEKAD NEIEVADIET PRIVÄ€TU INFORMÄ€CIJU, LAI PASARGÄ€TU TO NO NOZAGÅ ANAS" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "AtcerÄ“ties izvÄ“li" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "connect: Pareiza forma ir 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Atļaut" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "connect: Nepareizs ports" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Neļaut" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "connect: PieslÄ“dzas pie %s:%u..." -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "GalvenÄ izvÄ“lne" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "connect: NeizdevÄs pieslÄ“gties pie %s:%u!" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "JÅ«s izmantojat feature-branch build! Å is ir testa veidojums, kas nevar tikt izmantots lai savienotos ar publiskajiem serveriem!" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "connect: NeizdevÄs atslÄ“gt esoÅ¡o modu" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA vairs nesniegs atjauninÄjumus XP/Vista lietotÄjiem pÄ“c 2019. gada jÅ«lija." +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Å Ä« darbÄ«ba JÅ«s atslÄ“gs no esoÅ¡Ä servera.\n\n" -"Vai JÅ«s tik tieÅ¡Äm vÄ“laties atslÄ“gties?" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "ATSLÄ’GÅ ANÄ€S BRĪDINÄ€JUMS" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" msgstr "" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "LatvieÅ¡u" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Iebindotas visas kontroles no GTA" + +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "KonfigurÄcijas fails tika saglabÄts" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* JÅ«su sÄ“rijas kods ir: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "UZSTÄ€DĪJUMI" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "DaudzspÄ“lÄ“tÄju" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Video" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Skaņa" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "SaistÄ«bas" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "VadÄ«ba" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Intrefeiss" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Interneta pÄrlÅ«ks" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "PaplaÅ¡inÄts" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "IelÄdÄ“t noklusÄ“juma" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Peles jÅ«tÄ«gums:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "VertikÄlÄs mÄ“rķēšanas jÅ«tÄ«gums:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Peles opcijas" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "ApvÄ“rst peli vertikÄli" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "StÅ«rÄ“t ar peli" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Lidot ar peli" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Joypada opcijas" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standarta vadÄ«ba (Pele + TastatÅ«ra)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Klasiska vadÄ«ba (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "MelnÄ zona" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "PiesÄtinÄjums" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Izmantojiet 'SaistÄ«bas' sadaļu priekÅ¡ joypada pogÄm." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "KreisÄ" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "LabÄ" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "APRAKSTS" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "POGA" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. POGA" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "SegvÄrds:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "SaglabÄt serveru paroles" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "AutomÄtiskÄ atjaunoÅ¡anÄs serveru pÄrlÅ«kÄ" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Ä»aut ekrÄna augÅ¡upielÄdi" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Atļaut ÄrÄ“jÄs skaņas" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Atļaut redzÄ“t lejupielÄdes logu" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Atļaut savienojumu ar Discord Rich Presence" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Lietot pÄrveidotos GTA:SA failus" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Kartes utilizÄcijas opcijas" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "CaurredzamÄ«ba:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Galvenais skaļums:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Radio skaļums:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "SFX skaļums:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA skaļums:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Balss skaļums:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "SpÄ“lēšanas veids:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "VispÄrÄ“js" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Radio opcijas" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Radio Ekvalaizers" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Radio AutomÄtiskÄ UzstÄdīšana" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "LietotÄja dziesmu opcijas" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Radio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "NejauÅ¡s" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "SecÄ«gs" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "AutomÄtiskÄ Multivides PÄrbaudīšana" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Skaņas iestatÄ«jumi" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "ApklusinÄt visas skaņas, ja minimizÄ“ts" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "ApklusinÄt Radio skaņas, ja minimizÄ“ts" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "ApklusinÄt SFX skaņas, ja minimizÄ“ts" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "ApklusinÄt MTA skaņas, ja minimizÄ“ts" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "ApklusinÄt Balss skaņas, ja minimizÄ“ts" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "IzšķirtspÄ“ja:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "FOV:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "RedzamÄ«bas AttÄlums:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Spilgtums:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX KvalitÄte:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "AnizotropÄ filtrēšana:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Anti-aliasingi:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "IzmÄ“ru AttiecÄ«ba:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Loga režīms" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI IespÄ“joÅ¡ana" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Standarta" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Bez-rÄmju keep res" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mip Mappings" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Zema" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "VidÄ“ja" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Augsta" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Ä»oti augsta" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "IzslÄ“gts" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "x1" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "x2" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "x3" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "AutomÄtiski" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD SavietoÅ¡ana ar malu attiecÄ«bu" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Volumetriskas Ä’nas" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "ZÄles efekts" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Siltuma tveice" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Riepu dÅ«mi utml" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Dinamiskas ped Ä“nas" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "KustÄ«bu migloÅ¡ana" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Ūdens atspulgs" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "PilnekrÄna Minimizēšana" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "IespÄ“jot IerÄ«ces IzvÄ“les Dialogu" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "ParÄdÄ«t nedroÅ¡as izšķirtspÄ“jas" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "VienmÄ“r attÄ“lot transportu augstÄ kvalitÄtÄ“" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "VienmÄ“r attÄ“lot personÄžus augstÄ kvalitÄtÄ“" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Atļaut attÄlas mÄjaslapas" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "IespÄ“jot Javascript attÄlÄs vietnÄ“s" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "BloÄ·Ä“tÄs vietnes" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "IevadÄ«t jebkÄdu domÄ“mu, piem. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "BloÄ·Ä“t" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "DomÄ“ns" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Noņemt domeinu" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "SlÄ“gtais saraksts" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Atļaut" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "DažÄdi" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Ä€trÄ CJ apģērbu ielÄdēšana:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "PÄrlÅ«koÅ¡anas Ätrums:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Viens savienojums:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "PakeÅ¡u marķēšana:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "PakeÅ¡u marķēšana:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Procesu prioritÄte:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "AtkļūdoÅ¡anas uzstÄdÄ«jumi:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Straumēšanas atmiņa:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "AtjauninÄjumu veids:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "InstalÄ“t svarÄ«gus atjauninÄjumus:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "IeslÄ“gts" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Ä»oti lÄ“ni" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "NoklusÄ“juma" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Ä€tri" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "NormÄls" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Virs normÄla" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "MinimÄlais" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Maks." #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 saderÄ«ba:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-bitu krÄsas" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "FiksÄ“ta pele" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Klienta resursi:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "ParÄdÄ«t iekÅ¡ Windows:" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "AutomÄtiskais atjaunotÄjs" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "PÄrbaudÄ«t atjauninÄjumus" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Daži uzstÄdÄ«jumi tiks mainÄ«ti, kad jÅ«s nÄkoÅ¡ajÄ reizÄ“ startÄ“siet MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Vai vÄ“laties restartÄ“t Å¡obrÄ«d?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "NEPIECIEÅ AMS RESTARTS" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Daži uzstÄdÄ«jumi tiks mainÄ«ti, kad atslÄ“gsieties no servera" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Vai vÄ“laties atslÄ“gties?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "NepiecieÅ¡ams atslÄ“gties" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad nav atrasts - PÄrbaudiet savienojumu un restartÄ“jiet spÄ“li" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "SaistÄ«t asis" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Pakustiniet asi, lai savienotu, vai esc, lai iztÄ«rÄ«tu" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Valoda:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "MotÄ«vs:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Iepriekšējie:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Sarakste" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "IelÄdÄ“t" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "KrÄsas" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "IzkÄrtojums" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Opcijas" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "ÄŒata fons" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Sarakstes Teksts" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Teksta ievades fons" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Ievades Teksts" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "LÄ«nijas:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "MÄ“rogs:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Platums:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Lielums" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "pÄ“c" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "priekÅ¡" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "sek" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "IeslÄ«dēšana" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "IzgaisinÄt vecÄs lÄ«nijas" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "HorizontÄlais:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "VertikÄlais:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Teksta izkÄrtojums:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-NobÄ«de:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-NobÄ«de:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "PozÄ«cija" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Pa kreisi" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Centrs" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Pa labi" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "AugÅ¡a" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "ApakÅ¡a" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Fonts" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "PaslÄ“pt fonu, ja neraksta" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Nika pabeigÅ¡ana izmantojot 'TAB' pogu" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Atļaut serverim iemirdzinÄt logu" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Atļaut paziņojumus Windows vidÄ“" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "ÄŒata teksta melnais/baltais rÄmis" @@ -1547,89 +1833,95 @@ msgstr "ÄŒata teksta melnais/baltais rÄmis" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Nospiediet pogu, pie kuras piesaistÄ«t, vai arÄ« esc, lai iztÄ«rÄ«tu" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "SaistÄ«t primÄro pogu" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "SaistÄ«t sekundÄro pogu" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA SPÄ’LES KONTROLES" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "MULTIPLAYER KONTROLES" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "JÅ«su segvÄrds satur neatļautas rakstzÄ«mes!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "GalvenÄ izvÄ“lne" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "IekÅ¡ spÄ“les" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Sarkans:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Zaļš:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Zils:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "CaurredzamÄ«ba:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "KrÄsa" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "ApskatÄ«t" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "LÅ«dzu atslÄ“dzieties pirms mainÄt valodu" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "LÅ«dzu atslÄ“dzieties pirms mainÄt motÄ«vu" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "VolumektriskÄs Ä“nas var palÄ“linÄt sistÄ“mas darbÄ«nu.\n\n" "Vai JÅ«s tik tieÅ¡Äm vÄ“laties tÄs iespÄ“jot?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "VEIKTSPÄ’JAS BRĪDINÄ€JUMS" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "EkrÄna augÅ¡upielÄde ir dažos serveros nepiecieÅ¡ama kÄ anti-chear lÄ«dzeklis.\n\n" "(Sarakste un GUI logi netiek attÄ“loti augÅ¡upielÄdÄ“s)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "EKRÄ€NA AUGÅ UPIELÄ€DES INFORMÄ€CIJA" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1637,23 +1929,21 @@ msgstr "Daži skripti atskaņo skaņas, piemÄ“ram radio no interneta.\n\n" "AtspÄ“jojot Å¡o opciju, var samazinÄties \n" "tÄ«kla noslogojums.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "Ä€RÄ’JÄ€S SKAÅ…AS" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "IzrÄdÄs ka jums ir Rich Presence savienojuma opcija ieslÄ“gta.\n" -"Vai atļauj spÄ“les serveriem parsÅ«tit savus datus?\n\n" -"Iekļauj arÄ« jÅ«su Ä«paÅ¡o ID identifikÄtoru." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "PiekriÅ¡ana datu dalīšanai" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1661,13 +1951,9 @@ msgid "Some files in your GTA:SA data directory are customized.\n" msgstr "Daži faili iekÅ¡ JÅ«su GTA:SA datu mapÄ“ ir laboti.\n" "MTA izmantos tikai Å¡os failus, ja šī rÅ«tiņa ir ieÄ·eksÄ“ta.\n\n" "JebkurÄ ziņÄ, LABOTI GTA:SA FAILI IR BLOĶĒTI VAIRÄ€KOS SERVEROS\n\n" -"Vai JÅ«s tik tieÅ¡Äm vÄ“laties izmantot?" - -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "PÄ€RVEIDOTIE GTA:SA FAILI" +"Vai JÅ«s tik tieÅ¡Äm vÄ“laties izmantot?" -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1677,550 +1963,251 @@ msgstr "DPI ir eksperimentÄls produkts, kuru iesakÄm iespÄ“jot \n" "IespÄ“jojot Å¡o opciju ir iespÄ“ja sastapties ar grafiskÄm nepilnÄ«bÄm.\n\n" "Vai esi droÅ¡s ka vÄ“lies to darÄ«t?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "EKSPERIMENTÄ€LS PRODUKTS" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "LÅ«dzu ievadiet segvÄrdu" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "LÅ«dzu ievadiet segvÄrdu, kuru izmantosiet spÄ“lÄ“jot. \n" "Tas bÅ«s JÅ«su vÄrds, ar kuru savienosieties uz spÄ“lÄ“siet serverÄ«" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Ä»oti eksperimentÄla funkcija." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Aptur stendus ar CJ variÄcijÄm (Izmanto 65MB vairÄk RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "VecÄkiem marÅ¡rutÄ“tÄjiem ieteicams lÄ“nÄks meklēšanas Ätrums." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "IeslÄ“dziet, lai izmantotu tikai vienu savienojumu lejupielÄdÄ“jot." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "AtzÄ«mÄ“jiet tÄ«kla paketes, lai palÄ«dzÄ“tu ISP identificÄ“t MTA trafiku." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "RotÄ“joÅ¡a apļa animÄcija ekrÄna apakÅ¡Ä" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "VienmÄ“r izvÄ“lÄ“ts sÄkotnÄ“s. (Å is uzstÄdÄ«jums netiek saglabÄts)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "MaksimÄlais vienmÄ“r ir labÄkais" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "AutomÄtiskais atjaunotÄjs:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "IzvÄ“lieties sÄkotnÄ“ju, ja vien jums patÄ«k aizpildÄ«t kļūdu ziņojumus." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "IzvÄ“lies noklusÄ“juma, lai automÄtiski instalÄ“tu vajadzÄ«gos atjauninÄjumus." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16 bitu krÄsa:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "IespÄ“jot 16 bitu krÄsu režīmus - NepiecieÅ¡ama MTA restartēšana" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Peles fiksēšana:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Peles kustÄ«bas fiksēšana - NepiecieÅ¡ama MTA restartēšana" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "NezinÄma komanda vai cvar:" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Aizņemts" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Å obrÄ«d nespÄ“j pÄrbaudÄ«t atjauninÄjumus" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s pieprasa" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "MTA:SA %s atjauninÄjums ir nepiecieÅ¡ams, lai pievienotos izvÄ“lÄ“tajam serverim.\n\n" -"Vai vÄ“laties lejupielÄdÄ“t un instalÄ“t MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Vai JÅ«s vÄ“laties palaist MTA:SA %s un pievienoties Å¡im serverim ?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Å obrÄ«d, nav iespÄ“jams savienoties.\n\n" -"Mēģiniet vÄ“lÄk." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "SavienojÄs" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "LÅ«dzu uzgaidiet..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "PÄ€RBAUDA" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "ATJAUNINÄ€JUMA PÄ€RBAUDE" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Nav nepiecieÅ¡ams atjauninÄjums" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "LEJUPIELÄ€DÄ’" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "gaida..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "OBLIGÄ€TS ATJAUNINÄ€JUMS" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Lai pievienotos Å¡im serverim, Jums ir jÄatjauno MTA.\n\n" -" Vai JÅ«s vÄ“laties atjaunot tagad ?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "IETEICAMS ATJAUNINÄ€JUMS" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Serveris saka, ka ir atjauninÄjums ir ieteicams, bet ne obligÄti.\n\n" -"Vai JÅ«s vÄ“laties atjaunot tagad ?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "KĻŪDAS SAGLABĀŠANA" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "NespÄ“j izveidot failu." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "KĻŪDA LEJUPIELÄ€DÄ’JOT" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "LejupielÄdÄ“tais fails izskatÄs nederÄ«gs." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "KÄda iemesla dēļ." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "LEJUPIELÄ€DE PABEIGTA" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - NezinÄma problÄ“ma iekÅ¡ _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Labi" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "KĻŪDA" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Daži MTA:SA datu faili ir pazuduÅ¡i.\n\n\n" -"LÅ«dzu pÄrinstalÄ“jiet MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% pabeigti" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Gaida atbildi - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Savienojums neizdevÄs. NorÄdÄ«ts nederÄ«gs segvÄrds!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "SavienoÅ¡anÄs neizdevÄs. NorÄdÄ«ts nederÄ«gs hosts!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "SavienoÅ¡anÄs ar %s caur %u portu neizdevÄs!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Savienojas ar %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "SAVIENOJAS" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Savienojums iztecÄ“jis" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "AtvienoÅ¡anÄs: nezinÄma protokola kļūda" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "AtvienoÅ¡anÄs: savienojums pazuda attÄlinÄti" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "AtvienoÅ¡anÄs: savienojums pazuda attÄlinÄti" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Atvienots: jums ir liegta piekļuve Å¡im serverim" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Atvienots: atvienojÄs no servera" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "AtvienojÄs: pÄrtrÅ«ka savienojums ar serveri" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Atvienots: neizdevÄs savienoties" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Nav ieinstalÄ“ta šī modifikÄcija (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Nav servera atbildes (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Nav servera atbildes (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "JAUNUMI" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Apskatiet jaunÄkÄs ziņas" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONSOLE" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "FatÄla kļūda" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "Lai salabotu, izdzÄ“s Å¡o failu:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s modulis ir nepareizs!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Kļūda izpildot URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "Å¡is palÄ«dzÄ«bas ekrÄns" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "iziet no aplikÄcijas" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "uzrÄda versiju" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "uzrÄda laiku" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "uzrÄda hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "uzrÄda visas saistÄ«bas" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "uzrÄda jÅ«su seriÄlu" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "savienojÄs ar serveri (hosts pors segvÄrds parole)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "savienojÄs ar iepriekšējo serveri" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "savieno pogu (pogu kontrole)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "atvieno pogu (poga)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "nokopÄ“ noklusÄ“juma gta vadÄ«bas" -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "izveido ekrÄnÅ¡Äviņu" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "nekavÄ“joties saglabÄ konfigurÄciju" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "iztÄ«ra atkļūdoÅ¡anÄs logu" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "pavirza saraksti uz augÅ¡u" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "pavirza saraksti uz leju" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "pavirza atkļūdoÅ¡anÄs skatu uz augÅ¡u" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "pavirza atkļūdoÅ¡anÄs skatu uz leju" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "uzrÄda atmiņas statistiku" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "uzrÄda kadru laikoÅ¡anas grafiku" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "izstrÄdÄtÄjiem: pÄrlÄdÄ“t ziņas" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ KOMANDAS PALIDZIBA ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Pareizs laiks ir %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "connect: Pareiza forma ir 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "connect: Nepareizs ports" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "connect: PieslÄ“dzas pie %s:%u..." +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "izveido ekrÄnÅ¡Äviņu" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "connect: NeizdevÄs pieslÄ“gties pie %s:%u!" +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "nekavÄ“joties saglabÄ konfigurÄciju" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "connect: NeizdevÄs atslÄ“gt esoÅ¡o modu" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "iztÄ«ra atkļūdoÅ¡anÄs logu" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "pavirza saraksti uz augÅ¡u" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "pavirza saraksti uz leju" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "pavirza atkļūdoÅ¡anÄs skatu uz augÅ¡u" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "pavirza atkļūdoÅ¡anÄs skatu uz leju" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Iebindotas visas kontroles no GTA" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "uzrÄda atmiņas statistiku" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "KonfigurÄcijas fails tika saglabÄts" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "uzrÄda kadru laikoÅ¡anas grafiku" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* JÅ«su sÄ“rijas kods ir: %s" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "izstrÄdÄtÄjiem: pÄrlÄdÄ“t ziņas" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "AkselerÄcijas Ass" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "JÅ«s izmantojat feature-branch build! Å is ir testa veidojums, kas nevar tikt izmantots lai savienotos ar publiskajiem serveriem!" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Bremžu Ass" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA vairs nesniegs atjauninÄjumus XP/Vista lietotÄjiem pÄ“c 2019. gada jÅ«lija." -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programmēšana" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Å Ä« darbÄ«ba JÅ«s atslÄ“gs no esoÅ¡Ä servera.\n\n" +"Vai JÅ«s tik tieÅ¡Äm vÄ“laties atslÄ“gties?" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "AtbalstÄ«tÄji" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "ATSLÄ’GÅ ANÄ€S BRĪDINÄ€JUMS" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "SpÄ“les Dizains / KodÄ“jums" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Valodas LokalizÄcija" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "JAUNUMI" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "IelÄpa atbalstÄ«tÄji" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Apskatiet jaunÄkÄs ziņas" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "ĪpaÅ¡as PateicÄ«bas" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "EkrÄnÅ¡Äviņš aizņēma %d baitus, bet paredzÄ“ts %d" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Å Ä« programmatÅ«ra un projekts izmanto Å¡Ädas bibliotÄ“kas un programmatÅ«ru:" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "EkrÄnÅ¡Äviņš neizdevÄs" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Vai jÅ«s vÄ“laties atrast kÄdu tieÅ¡saistes palÄ«dzÄ«bu saistÄ«bÄ ar Å¡o problÄ“mu ?" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "EkrÄņšÄviņš izveidots: '%s'" + +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "NezinÄma komanda vai cvar:" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2395,25 +2382,56 @@ msgid "Group control backwards" msgstr "Grupas kontrole uz atpakaļu" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "MotÄ«vs, kuru JÅ«s izvÄ“lÄ“jaties, nav iespÄ“jams ielÄdÄ“t un sÄkotnÄ“jo motÄ«vu arÄ« nevar ielÄdÄ“t, lÅ«dzu pÄrinstalÄ“jiet MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "EkrÄnÅ¡Äviņš aizņēma %d baitus, bet paredzÄ“ts %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Vai jÅ«s vÄ“laties atrast kÄdu tieÅ¡saistes palÄ«dzÄ«bu saistÄ«bÄ ar Å¡o problÄ“mu ?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "EkrÄnÅ¡Äviņš neizdevÄs" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONSOLE" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "EkrÄņšÄviņš izveidots: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programmēšana" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "AtbalstÄ«tÄji" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "SpÄ“les Dizains / KodÄ“jums" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Valodas LokalizÄcija" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "IelÄpa atbalstÄ«tÄji" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "ĪpaÅ¡as PateicÄ«bas" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Å Ä« programmatÅ«ra un projekts izmanto Å¡Ädas bibliotÄ“kas un programmatÅ«ru:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "AkselerÄcijas Ass" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Bremžu Ass" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2421,6 +2439,63 @@ msgstr "NespÄ“j inicializÄ“t Direct3D9.\n\n" "LÅ«dzu pÄrliecinieties, ka DirectX End-User Runtime un\n" "pÄ“dÄ“jÄs Windows Servisu Pakotnes ir uzstÄdÄ«tas pareizi." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "DÄ«kstÄve" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "spÄ“lÄ“tÄjs" +msgstr[1] "spÄ“lÄ“tÄji" +msgstr[2] "spÄ“lÄ“tÄji" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "uz" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "serveris" +msgstr[1] "serveri" +msgstr[2] "serveri" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Pieprasa serveru sarakstu (%lu ms pagÄjuÅ¡as)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Servera sarakstu nespÄ“j parsÄ“t." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Servera sarakstu nespÄ“j saņemt." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Rezerves servera saraksts)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "NespÄ“j savienot LAN-apraides soketu" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Mēģina atklÄt LAN serverus" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2474,7 +2549,7 @@ msgstr "Latensija:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "SpÄ“lÄ“tÄju saraksts" @@ -2501,40 +2576,39 @@ msgstr "Pievienoties serverim, kad tajÄ atbrÄ«vojÄs brÄ«va vieta." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "LŪDZU IEVADIET SERVERA PAROLI" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Noilgums" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "PÄrbauda..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "SERVERA PÄ€RLŪKS" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Interneta" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "LokÄlie" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "FavorÄ«ti" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Nesenie" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2542,300 +2616,367 @@ msgstr "Ä€TRAIS SAVIENOJUMS:\n\n" "Ievadiet servera adresi un portu adreÅ¡u joslÄ.\n" "Vai izvÄ“lieties serveri no vÄ“stures un spiediet 'Vienoties'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "PALĪDZĪBA" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Atjaunot" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Pievienot FavorÄ«tiem" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Vienoties" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Servera informÄcija" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "MeklÄ“t serverus" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "MeklÄ“t spÄ“lÄ“tÄjus" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "SÄkt meklÄ“t" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "MeklÄ“t spÄ“lÄ“tÄjus..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "MeklÄ“t serverus..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "VÄrds" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "SpÄ“lÄ“tÄji" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Pings" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Gamemods" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Iekļaut:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "TukÅ¡s" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Pilns" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "SlÄ“gts" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Nepieejams" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Citas Versijas" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Atpakaļ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "IelÄdÄ“..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..ielÄdÄ“.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Nav norÄdÄ«ta adrese!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "NezinÄms protokols" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "LÅ«dzu izmantojiet mtasa:// protokolu!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "NederÄ«gs segvÄrds! LÅ«dzu dodieties uz UzstÄdÄ«jumiem un uzstÄdiet citu!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Jums ir jÄizvÄ“las serveris, pie kura pievienoties." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "DÄ«kstÄve" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "ProblÄ“mas ar grafiskajiem draiveriem" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "spÄ“lÄ“tÄjs" -msgstr[1] "spÄ“lÄ“tÄji" -msgstr[2] "spÄ“lÄ“tÄji" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Nevar atrast derÄ«gu ekrÄna izšķirtspÄ“ju." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "uz" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Vai jÅ«s esat pÄrliecinÄts, ka vÄ“laties izmantot Å¡o izšķirtspÄ“ju?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "serveris" -msgstr[1] "serveri" -msgstr[2] "serveri" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Pieprasa serveru sarakstu (%lu ms pagÄjuÅ¡as)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Servera sarakstu nespÄ“j parsÄ“t." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "MÄjaslapu pieprasÄ«jumi" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Servera sarakstu nespÄ“j saņemt." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Serveris pieprasa pieeju Å¡ÄdÄm mÄjaslapÄm:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Rezerves servera saraksts)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NEKAD NEIEVADIET PRIVÄ€TU INFORMÄ€CIJU, LAI PASARGÄ€TU TO NO NOZAGÅ ANAS" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "NespÄ“j savienot LAN-apraides soketu" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "AtcerÄ“ties izvÄ“li" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Mēģina atklÄt LAN serverus" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Neļaut" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Å Ä« versija ir iztecÄ“jusi." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "atslÄ“gties no spÄ“les" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "parÄda namtagus" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "uzrÄda saraksti" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "uzrÄda tÄ«kla statistiku" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "atver sarakstes ievadi" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "pÄrraida balsi citiem spÄ“lÄ“tÄjiem" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "iekÄp kÄ pasažieris" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "nÄkoÅ¡Ä radio stacija" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "iepriekšējÄ radio stacija" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "nosÅ«ta ziņojumu mÄ“rÄ·Ä“tajam spÄ“lÄ“tÄjam" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "pÄrmaina uz nÄkoÅ¡o ieroci atrodoties transportlÄ«dzeklÄ«" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "pÄrmaina uz iepriekšējo ieroci atrodoties transportlÄ«dzeklÄ«" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "izvada informÄciju par paÅ¡reizÄ“jo serveri" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "definÄ“ mÄ“rogu reizinÄtÄju visiem attÄ“lotajiem tekstiem" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(IzstrÄdÄtÄja režīms) attÄ“lo colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(IzstrÄdÄtÄja režīms) attÄ“lo pasaules skaņas id iekÅ¡ atkļūdoÅ¡anas loga" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "HOSTÄ’T SPÄ’LI" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Resursi" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Servera nosaukums:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Parole:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Max spÄ“lÄ“tÄji:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Apraide:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "IzvÄ“lÄ“ts" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Visi" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "SÄkt" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Mapes lejupielÄdes progress:" @@ -2856,174 +2997,174 @@ msgstr "%s no %s" msgid "Disconnect to cancel download" msgstr "AtslÄ“dzieties, lai atceltu lejupielÄdi" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "AtslÄ“gÅ¡anÄs: NederÄ«gs segvÄrds" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "AtslÄ“gties no servera" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "AtslÄ“gÅ¡anÄs: SeriÄls ir melnajÄ sarakstÄ.\n" "Iemesls: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "AtslÄ“gÅ¡anÄs: JÅ«s esat melnajÄ sarakstÄ.\n" "Iemesls: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "AtslÄ“gÅ¡anÄs: Kontam ir liegta piekļuve.\n" "Iemesls: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "AtslÄ“gÅ¡anÄs: Versijas nesakriÅ¡ana" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "AtslÄ“gÅ¡anÄs: PÄrmÄ“rÄ«ga pieslÄ“gÅ¡anÄs. Uzgaidiet minÅ«ti, un tad mēģiniet vÄ“lreiz." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "AtslÄ“gÅ¡anÄs: Serveris ir no citas nozares.\n" "InformÄcija: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "AtslÄ“gÅ¡anÄs: Nepareiza versija.\n" "InformÄcija: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "AtslÄ“gÅ¡anÄs: Serveris darbojÄs zem jaunÄkas bÅ«vversijas.\n" "InformÄcija: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "AtslÄ“gÅ¡anÄs: Serveris darbojÄs uz vecÄku bÅ«vÄ“jumu.\n" "InformÄcija: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "AtslÄ“gÅ¡anÄs: SegvÄrds jau tiek izmantots" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "AtvienoÅ¡anÄs: SpÄ“lÄ“tÄja elements netika izveidots." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "AtslÄ“gÅ¡anÄs: Serveris noraida savienojumu: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "AtslÄ“gÅ¡anÄs: SeriÄla pÄrbaude neizdevÄs" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "AtslÄ“gÅ¡anÄs: Savienojuma pÄrsinhronizÄ“ja %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "AtslÄ“gÅ¡anÄs: JÅ«s izmeta %s no servera" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "AtslÄ“gÅ¡anÄs: %s liedza Jums piekļuvi" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "AtvienoÅ¡anÄs: Serveris izslÄ“dzÄs vai tika restartÄ“ts" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "JÅ«s tikÄt izmests no spÄ“les" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Å is serveris pieprasa nemodificÄ“tu gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "LÅ«dzu samaini gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Å is serveris neatbalsta modificÄ“tus D3D9.DLL failus" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Noņem D3D9.DLL no jÅ«su GTA instalÄcijas vietas un restartÄ“ MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Å is serveris neatbalsta virtuÄlÄs mašīnas" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Å is serveris pieprasa iespÄ“jotu 'driver signing'" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "LÅ«dzu restartÄ“ datoru" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Å im serverim trÅ«kst pÄris anti-cheat komponentes" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Pamēģini restartÄ“t MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Å is serveris pieprasa nemodificÄ“tus gta3.img un gta_int.img failus" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "LÅ«dzu samainiet gta3.img vai gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Å is serveris neatbalsta 'Wine'" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "PÄrliecinies ka neviena programma nemodificÄ“ MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "AtlikuÅ¡ais Laiks: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" @@ -3031,7 +3172,7 @@ msgstr[0] "%d diena" msgstr[1] "%d dienas" msgstr[2] "%d dienas" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" @@ -3039,7 +3180,7 @@ msgstr[0] "%d stunda" msgstr[1] "%d stundas" msgstr[2] "%d stundas" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" @@ -3047,7 +3188,7 @@ msgstr[0] "%d minÅ«te" msgstr[1] "%d minÅ«tes" msgstr[2] "%d minÅ«tes" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3056,296 +3197,206 @@ msgstr[1] "%d sekunde" msgstr[2] "%d sekundes" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "AtslÄ“dzies" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "LejupielÄdes kļūda: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "Lido ar kosmosa kuÄŸi" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "BraukÄ apkÄrt" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "KuÄŸo pa vilņiem" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "BraukÄ ar vilcienu" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "LidinÄs apkÄrt" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "BraukÄ apkÄrt" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "BraukÄ ar monster kravu automaÅ¡inu" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "KvadraciklÄ“ apkÄrt" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "LÄ“ka apkÄrt" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "Dara savÄdas lietas iekÅ¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "KÄpj apkÄrt iekÅ¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "TÄ“mÄ“ ieroci pa logu no automašīnas iekÅ¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "Blub blub..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "Elpo Å«deni" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "SlÄ«kst iekÅ¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "Pietupies priekÅ¡ seguma iekÅ¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "KaujÄs iekÅ¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "Sit apkÄrt iekÅ¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "Spridzina muļķus iekÅ¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "ApÅ¡auda" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "LidinÄs ar raÄ·eÅ¡u somu iekÅ¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "Deg iekÅ¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "Deg iekÅ¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "Peld iekÅ¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "LidinÄs apkÄrt iekÅ¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "VajÄ haizivs" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "Aizrijies lÄ«dz nÄvei iekÅ¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Ieiet spÄ“lÄ“ ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "NepieslÄ“dzÄs; lÄ«dzu izmantojiet Ä€tro Savienojumu vai 'connect' komandu, lai pieslÄ“gtos serverim." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "NespÄ“j palaist lokÄlo serveri. Skatiet konsoli, lai redzÄ“ti detaļas." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "LokÄlais Serveris" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "StartÄ“ lokÄlo serveri ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "Arena 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "StaigÄ apkÄrt " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "JÅ«s tikÄt izmests no spÄ“les ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "SavienojÄs ar lokÄlo serveri..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Kļūda savienojoties ar serveri." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "SavienoÅ¡anÄs ar lokÄlo serveri iztecÄ“ja. Apskaties konsoli priekÅ¡ detaļÄm." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Savienojums ar serveri pazuda" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "AtslÄ“gÅ¡anÄs: serveris Å¡obrÄ«d ir pilns" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "AtslÄ“gÅ¡anÄs: norÄdÄ«ta nederÄ«ga parole" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA Klineta pÄrbaude neizdevÄs!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "IekÅ¡ grÄvja" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "CeÄ¼Ä uz slimnÄ«cu" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "Sasniedz savu marÄ·ieri" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "Nožēlo savas izvÄ“les" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "Miris" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "HOSTÄ’T SPÄ’LI" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Resursi" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Servera nosaukums:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Parole:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Max spÄ“lÄ“tÄji:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Apraide:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "IzvÄ“lÄ“ts" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Visi" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "SÄkt" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "ProblÄ“mas ar grafiskajiem draiveriem" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Nevar atrast derÄ«gu ekrÄna izšķirtspÄ“ju." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Vai jÅ«s esat pÄrliecinÄts, ka vÄ“laties izmantot Å¡o izšķirtspÄ“ju?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "LejupielÄdes kļūda: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3366,11 +3417,11 @@ msgstr "" msgid "Connection error" msgstr "Savienojuma kļūda" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto nav ticis pareizi uzinstalÄ“ts, lÅ«dzu pÄrinstalÄ“jiet." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "JÅ«su pÄrlÅ«ks uzrÄdÄ«s tÄ«mekļa vietni ar palÄ«dzÄ«bas informÄciju.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/mk_MK/client.pot b/Shared/data/MTA San Andreas/MTA/locale/mk_MK/client.pot index ddd380a0649..19e88d1ba2e 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/mk_MK/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/mk_MK/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Macedonian\n" "Language: mk_MK\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Проблеми Ñо реÑтартирање на MTA:SA\n\n" -"доколку проблемот продолжи отворете Task Manager и\n" -"Ñтопирајте го 'gta_sa.exe' и 'Multi Theft Auto.exe' прецеÑот\n\n\n" -"Пробајте да ја вклучите MTA:SA повторно?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Грешка" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Уште една копија од MTA е веќе вклучена.\n\n" -"Доколку проблемот продолжи, реÑтартирајте го компјутерот" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Уште една копија од MTA е вклучена.\n\n" -"Дали Ñакате да ја иÑклучите?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Селектирајте ја дирекцијата за инÑталирање на Grand Theft Auto: San Andreas" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA бара дозвола за Ñледнава задача:\n\n" +" '%s'\n\n" +"Ве молиме потврдете во Ñледниов прозор." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Погрешно вчитување %s модел! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Копирање на фајлови..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Копирањето заврши порано. Се е во ред." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Завршува..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Готово!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Ðова инÑталација од %s е детектирана.\n\n" +"Дали Ñакате да ги копирате вашите опции од %s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA имаше проблеми да го отвори овој фајл '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA и недоÑтаÑува фајлот '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA имаше проблеми да го вчита овој модел." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Ðко неодамна Ñте го модифицирале gta3.img, тогаш пробајте Ñо ре-инÑталирање на GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA имаше проблем Ñо додавање на надградба на ова возило." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA пронајде грешки во фајлот '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Дали твојот компјутер Ñе реÑтартил кога MTA:SA билa вклучена?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Ве молиме Ñледниве програми иÑклучете ги пред да продолжите:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Грешка во фајловите на верзијата. РеинÑталирајте ја MTA:SA доколку имате проблеми.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Ðекои фајлови Ñе недоÑтапни.ПреинÑталирајте ја MTA:SA доколку имате некој проблем.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA не е компатибилен Ñо Windows 'Safe Mode'.\n\n" +"Ве молиме реÑтартирајте го компјутерот.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Дали имате проблеми Ñо вклучување на MTA:SA?.\n\n" "Дали Ñакате да ја вратите во поÑтара верзија?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "Се појави проблем Ñо Ñтартување на MTA:SA.\ "РеÑтартирање на GTA опциите може да го реши проблемот.\n\n" "Дали Ñакате да ги реÑтартирате GTA опциите Ñега?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA поÑтавувањата Ñе реÑетирани.\n\n" "ПритиÑнете OK за да продолжите." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Фајлот не може да Ñе избрише: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Дали имате проблеми Ñо Ñтартување на MTA:SA?.\n\n" "Дали Ñакате да побарате помош онлајн?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Дали имате проблеми Ñо Ñтартување на MTA:SA?.\n\n" "Дали Ñакате да ги промените Ñледните опции?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Режим на цел екран:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Прозорец без рамки" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Дали имате проблеми Ñо Ñтартување на MTA:SA?.\n\n" "Пробајте Ñо деактивирање на Ñледните продукти за GTA и MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,128 +189,288 @@ msgstr "ПРЕДУПРЕДУВÐЊЕ\n\n" "MTA:SA забележа необични активноÑти.\n" "Ве молиме направете Ð²Ð¸Ñ€ÑƒÑ Ñкенирање за да Ñе оÑигурате дека вашиот ÑиÑтем е безбеден.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Детектираниот фајл е: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Уште една копија од GTA: San Andreas е веќе вклучена и треба да Ñе иÑклучи пред MTA:SA да биде Ñтартувана.Дали Ñакате тоа да го направите Ñега?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Информации" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "ИÑклучување на GTA: San Andreas беше невозможно.Доколку проблемот продолжи, реÑтартирајте го вашиот компјутер." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Проблеми Ñо реÑтартирање на MTA:SA\n\n" +"доколку проблемот продолжи отворете Task Manager и\n" +"Ñтопирајте го 'gta_sa.exe' и 'Multi Theft Auto.exe' прецеÑот\n\n\n" +"Пробајте да ја вклучите MTA:SA повторно?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Грешка" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Уште една копија од MTA е веќе вклучена.\n\n" +"Доколку проблемот продолжи, реÑтартирајте го компјутерот" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Уште една копија од MTA е вклучена.\n\n" +"Дали Ñакате да ја иÑклучите?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "РегиÑтарÑките влеза недоÑтигаат.Ве молиме реинÑталирајте ја Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Линкот од инÑталацијата на GTA: San Andreas Ñодржат неподржани (уникод) карактери. Ве молиме инÑталацијата на Grand Theft Auto: San Andreas премеÑтете ја на компатибилен линк што Ñодржи Ñамо Ñтандарни ASCII карактери и реинÑталирајте ја Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Линкот до инÑталацијата на 'MTA:SA' или 'GTA: San Andreas'\n" -"Ñодржи ';' (точказапирка).\n\n" -" Доколку имате проблеми Ñо MTA:SA,\n" -" премеÑтете ја инÑталацијата во друг линк што не Ñодржи точказапирка." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Вчитувањето е неуÑпешно. Ве молиме проверете дали најновите фајлови ви Ñе инÑталирани." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Вчитувањето е неуÑпешно. Ве молиме проверете дали %s е инÑталиран правилно." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Вчитувањето е неуÑпешно. gta_sa.exe во %s не може да Ñе пронајде." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Вчитувањето е неуÑпешно. %s поÑтои во GTA дирекцијата. Ве молиме тргнете го пред да продолжите." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Главниот фајл има погрешно име (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Главниот фајл е непотпишан. Можни вируÑни активноÑти.\n\n" -"Побарајте онлјан помош доколку MTA не работи како што треба." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 +#, c-format +msgid "Data file %s is modified. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" +msgstr "Поправете го проблемот Ñо конфигурацијата" + +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/Install.cpp:479 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asi фајловите Ñе лоцирани во инÑталационот фолдер во 'MTA:SA' или 'GTA: San Andreas'.\n\n" -"Избришете ги тие фајлови ако имате проблеми Ñо MTA:SA" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "ИнÑталирање на ажурирање" -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Грешка во фајловите на верзијата. РеинÑталирајте ја MTA:SA доколку имате проблеми.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Извлекување на фајлови..." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Ðекои фајлови Ñе недоÑтапни.ПреинÑталирајте ја MTA:SA доколку имате некој проблем.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA неможе Ñе да ја изврши Ñледнава задача:\n\n" +" '%s'\n" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA не е компатибилен Ñо Windows 'Safe Mode'.\n\n" -"Ве молиме реÑтартирајте го компјутерот.\n" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Прекинот беше поради грешка во графичкиот драјвер **\n\n" +"** Ве молиме апдејтирајте ги графичките драјвери **" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" -msgstr "Поправете го проблемот Ñо конфигурацијата" +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "ИнÑталирај ажурирани MTA:SA фајлови" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Ðе може Ñе да Ñе ажурира поради конфликт Ñо фајловите. Ве молиме затворете ги другите апликации и пробајте одново" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto не е инÑталирана правилно, ве молиме ре-инÑталирајте ја. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Поправете ја грешката" +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Grand Theft Auto: San Andreas не може да Ñе Ñтартува. РеÑтартирајте, или ако проблемот продолжи, контактирајте ги MTA на www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA неможе да продолжи бидејќи драјверот %s нема доволно меÑто." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Фајл што недоÑтаÑува:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Ðко MTA не уÑпее да вчита, ве молиме ре-инÑталирајте ја GTA:SA" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas не е вклучена коректно. Дали Ñакате да ја иÑклучите?" +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Ðжурирање на опции за инÑталирање" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Ðжурирање на опции за компатибилноÑÑ‚ " #. ///////////////////////////////////////////////////////////////////////// #. @@ -268,166 +478,166 @@ msgstr "GTA: San Andreas не е вклучена коректно. Дали Ñ #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Да" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Ðе" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "Ок" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "ИÑклучи" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Помош" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Откажи" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas наиде на проблем" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Информации за иÑклучувањето" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Штиклирајте за да пратите репорт до MTA девелоперите употребувајќи интернет" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Правејќи го ова ќе Ñе зголеми шанÑата од проблемot да биде решен." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Дали Ñакате да ја реÑтартирате MTA: San Andreas ?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Предупредување" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Играј MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Збунувачки опции" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus детектиран!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Пробајте ја Ñекоја опција и проверете која работи:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Стандарна NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Ðлтернативна NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Доколку Ñте очајни, ова може да ви помогне:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "ПриÑилен \"Windowed\" мод" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Предупредување: Ðе е во можноÑÑ‚ да Ñе детектира анти вируÑ" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -435,1101 +645,1180 @@ msgstr "MTA не може да детектира анти Ð²Ð¸Ñ€ÑƒÑ Ð²Ð¾ ва "ВируÑите може да направат проблем Ñо вашата MTA.\n\n" "ПритиÑнете на \"Помош\" за повеќе информации." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "ÐˆÐ°Ñ Ð²ÐµÑœÐµ имам инÑталирано анти вируÑ" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "ÐˆÐ°Ñ Ð½ÐµÐ¼Ð° да инÑталирам анти вируÑ.\n" "ÐˆÐ°Ñ Ñакам мојот РС да лагира и да бидам дел од бот мрежата." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Пребарување на Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Ве молиме Ñтартувајте ја Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "ИнÑталирање на ажурирање" +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Конекцијата е неуÑпешна: Приложеното име е невалидно" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Извлекување на фајлови..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Конекцијата е неуÑпешна: Приложениот хоÑÑ‚ е невалиден" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Копирање на фајлови..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Конектирањето до %s портата %u е неуÑпешно!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Копирањето заврши порано. Се е во ред." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Се конектира на %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Завршува..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Готово!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "Поврзување" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA бара дозвола за Ñледнава задача:\n\n" -" '%s'\n\n" -"Ве молиме потврдете во Ñледниов прозор." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Конекцијата е прекината " -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA неможе Ñе да ја изврши Ñледнава задача:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "ДиÑконектиран: непозната грешка на протоколот" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Прекинот беше поради грешка во графичкиот драјвер **\n\n" -"** Ве молиме апдејтирајте ги графичките драјвери **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "ДиÑконектиран: диÑконектиран рачно" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "ИнÑталирај ажурирани MTA:SA фајлови" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "ДиÑконектиран: конекцијата е изгубена рачно" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Ðе може Ñе да Ñе ажурира поради конфликт Ñо фајловите. Ве молиме затворете ги другите апликации и пробајте одново" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "ДиÑконектиран: Вие Ñте баниран од Ñерверот" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "ДиÑконектиран: ДиÑконектиран од Ñерверот" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Ð’Ñ€Ñката Ñо Ñерверот беше прекината." + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "ДиÑконектиран: конекцијата e oдбиена" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto не е инÑталирана правилно, ве молиме ре-инÑталирајте ја. %s" +msgid "No such mod installed (%s)" +msgstr "ÐепоÑтоечки мод (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Погрешен одговор од Ñерверот (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Погрешен одговор од Ñерверот (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "МакедонÑки" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Зафатен" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Ðе е возможно да Ñе прегледат ажурирањата во моментот" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s е потребна" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Понова верзија од MTA:SA %s е потребна за да влезеш во Ñелектираниот Ñервер.\n\n" +"Дали Ñакате да ја Ñимнете и инÑталирате MTA:SA %s?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Дали Ñакате да ја започнете MTA:SA %s и конектирате на овој Ñервер ?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Ðе е возможно да Ñе конектирате во моментот.\n\n" +"Ве молиме пробајте подоцна." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Се конектира" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Ве молиме почекајте..." -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "Се проверува" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA неможе да продолжи бидејќи драјверот %s нема доволно меÑто." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "Ðжурирањето Ñе проверува" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Фајл што недоÑтаÑува:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Ðе Ñе потребни ажурирања" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Ðко MTA не уÑпее да вчита, ве молиме ре-инÑталирајте ја GTA:SA" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "СИМÐУВÐЊЕ" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Ðжурирање на опции за инÑталирање" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "почекајте..." -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Ðжурирање на опции за компатибилноÑÑ‚ " +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "ЗÐДОЛЖИТЕЛÐÐ ÐÐДГРÐДБÐ" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "За да влезете во Ñерверот, треба да ја ажурирате MTA.\n\n" +" Сакате ли да ја ажурирате Ñега?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "ОПТИОÐÐЛÐО ÐЖУРИРÐЊЕ" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Серверот препорачува надградба, но не е опходна.\n\n" +" Дали Ñакате да надградите Ñега ?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "Грешка Зачувување" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Фајлот не беше во можноÑÑ‚ да Ñе креира." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Селектирајте ја дирекцијата за инÑталирање на Grand Theft Auto: San Andreas" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "Грешка Симнување" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Погрешно вчитување %s модел! (%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Симнатиот фајл изгледа е неточен." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Ðова инÑталација од %s е детектирана.\n\n" -"Дали Ñакате да ги копирате вашите опции од %s ?" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Поради некои причини." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA имаше проблеми да го отвори овој фајл '%s'" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "Симнувањето е УÑпешно" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA и недоÑтаÑува фајлот '%s'." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Ðепознат проблем во _DialogUpdateResult" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA имаше проблеми да го вчита овој модел." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "МОДИФИЦИРÐÐИ GTA:SA ФÐЈЛОВИ" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Ðко неодамна Ñте го модифицирале gta3.img, тогаш пробајте Ñо ре-инÑталирање на GTA:SA." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA имаше проблем Ñо додавање на надградба на ова возило." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "ГРЕШКÐ" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Ðекои MTA:SA дата фајлови недоÑтаÑуваат.\n\n\n" +"Ве молиме ре-инÑталирајте ја MTA:SA" + +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA пронајде грешки во фајлот '%s'" +msgid "%3d %% completed" +msgstr "%3d %% комплетирарно" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Дали твојот компјутер Ñе реÑтартил кога MTA:SA билa вклучена?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Се чека одговор - %-3d" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Ве молиме Ñледниве програми иÑклучете ги пред да продолжите:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ КОМÐÐДРПОМОШ ] ***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Барање на вебÑајт" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* ЧаÑот е %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Серверот ги бара Ñледниве вебÑајтови за да може да ги лоадира (подоцна)" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "ÐИКОГÐШ ÐЕ Ð’ÐЕСУВÐЈТЕ Ð’ÐЖÐИ ИÐФОРМÐЦИИ ЗРДРÐЕ БИДÐТ УКРÐДЕÐИ" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "конекција: СинтакÑата е конектирана на <хоÑÑ‚> [<порта> <име> <паÑворд>]'" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Запамти ја одлуката" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "конекција: Погрешна бројка на портата" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Одобри" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "Конекција: Се конектира %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Одбиј" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "Конекција: Конекцијата е неуÑпешна %s.%u! " -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "Конекција: ÐеуÑпешно отпакување на модот" + +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Вие кориÑтите нова верзија, и иÑтата не може да Ñе конектира на јавни Ñервери!" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Ова ќе ве диÑконектира од Ñерверот.\n\n" -"Дали Ñте Ñигурни дека Ñакате да Ñе диÑконектирате?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "ДИСКОÐЕКЦИЈРПРЕДУПРЕДУВÐЊЕ" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Сврзи ги Ñите контроли од ГТÐ" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Фајлот за конфигурација е зачуван" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "МакедонÑки" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "*Твојот ÑериÑки број е: %s " #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "ПОСТÐВКИ" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Мултиплеер" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Видео" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Ðудио" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Сврзувања" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Контроли" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "ИнтерфејÑ" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Веб пребарувач" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Ðапредно" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Стандарно вчитување" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "СензитивноÑÑ‚ на мауÑот:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Вертикална ÑензитивноÑÑ‚ на аимот:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "ÐœÐ°ÑƒÑ Ð¾Ð¿Ñ†Ð¸Ð¸" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Инвертна вертикалноÑÑ‚ на мауÑот" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Мрдај Ñо мауÑот" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Летај Ñо мауÑот" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Joypad опции" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Стандарни контроли ( ÐœÐ°ÑƒÑ + ТаÑтатура)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "КлаÑични контроли (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Мртва Зона" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Сатурација" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Употребете го 'Сврзување' табот за joypad копчиња." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Лев Ñтик" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "ДеÑен Ñтик" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "ОПИС" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "КЛУЧ" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. Копче" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Име:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Зачувај го паÑвордот на Ñерверот" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "ÐвтоматÑко-оÑвежување на пребарувачот на Ñервери" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Дозволи аплоадирање на Ñлика" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Употреби модифицирани GTA:SA фајлови" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Опции за нацрт на мапа" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "ÐепроѕирноÑÑ‚:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Севкупна Јачина:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Ð“Ð»Ð°Ñ Ð½Ð° радиото:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "SFX јачина:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA јачина:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Јачина на глаÑот:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Вид на игра:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Општо" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Радио опции" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Изедначување на радио" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "ÐвтоматÑко нагодување на радиото" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "КориÑнички опции" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Радио" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Случајно" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Секвенцијален" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "ÐвтоматÑки медија Ñкенер" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Опции за мутирање" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Мутирање на целиот звук кога е минимизирано" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Мутирај го звукот на радиото кога е минимизирано" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Мутирај SFX звук кога е минимизирано" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Мутирај MTA звук кога е минимизирано" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Мутирај глаÑовен звук кога е минимизирано" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Резолуција:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "СоÑтавна ДиÑтанца:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Светлина:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX квалитет:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "ÐнизотропÑки филтер:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Ðнти-лаг:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "ÐÑпект Рејтио:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Без рамки" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Стандардно" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Резолуција без рамка" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Мапирање" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Слабо" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Средно" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "ВиÑоко" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Многу виÑоко" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "ИÑклучување" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "ÐвтоматÑки" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD-от Ñе вклопува " -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "ВолуметриÑки Сенки" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Ефект на трева" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Магловита топлина" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Гумо Чад итн" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "ЦелоÑно Минимизирање" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Дозволи уред за Ñелекција на диалог" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Прикажи ги небезбедните резолуции" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Рендирање на возилата Ñекогаш детални" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Вклучете вебÑајти" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Вклучете јава Ñкрипти на далечинÑки вебÑајти" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Црна лиÑта" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "ВнеÑете домејн како на пример google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Блок" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Домен" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "ОтÑтрани домен" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Бела лиÑта" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Одобри" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Разно" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Брзи СЈ облеки Ñе вчитува:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Брзина на прелиÑтувачот:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Единечна конекција:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Таг на пакет:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Ðнимација на прогреÑ:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "ÐŸÑ€Ð¾Ñ†ÐµÑ Ð½Ð° приоритет:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Дебаг опции:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Стриминг меморија:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Ðадградете го типот: " #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "ИнÑталирај важни надградби:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Вклучување" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Многу бавно" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Стандарно" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Брзи" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Ðормално" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Ðормално" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Минимум" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Махимим" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Ð’Ð¸Ð½Ð´Ð¾ÑƒÑ 8 компатибилноÑÑ‚: " -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-битна боја " -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Поправка на мауÑ" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Фајлови и реÑурÑи на клиентот:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Прикажи во Explorer" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "ÐвтоматÑко ажурирање" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Провери ги ажурирањата Ñега" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Ðекои опции ќе бидат промените Ñледниот пат кога ќе ја вклучите MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Дали Ñакате Ñега да реÑтартирате?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "РЕСТÐРТИРÐЊЕ Е ЗÐДОЛЖИТЕЛÐО" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Ðекои поÑтавки ќе бидат Ñменети кога ќе Ñе диÑконектирате од Ñерверот" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Дали Ñакате да Ñе диÑконектирате Ñега?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "ДИСКОÐЕКТИРÐЊЕ Е ЗÐДОЛЖИТЕЛÐО" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad не е детектиран - Проверете ја конекцијата и реÑтартирајте ја играта" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Сврзувачки оÑки" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "ПремеÑти оÑка до Ñврзување, или притиÑни еÑкејп за да иÑклучиш" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Јазик:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Скин:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Стабилизатор:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Чат" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Вчитај" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Бои" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "РаÑпоред" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Опции" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Позадина на чатот" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Чат текÑÑ‚" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "ВнеÑување на позадина" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Влезен ТекÑÑ‚ " -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Линии: " -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Скала:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Ширина:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Големина" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "поÑле" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "за" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "Ñекунда" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Избледнување" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Да иÑчезнат Ñтарите линии" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Хоризонтално:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Вертикално:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "ТекÑÑ‚-Порамнување:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-офÑет:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-офÑет:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Позиција" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Лево" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Центар" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "ДеÑно" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Врв" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Дно" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Фонт" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Сокриј во позадина кога не пишуваш" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Завршување на името притиÑнувајќи го копчето \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Дозволи Ñерверот да го оÑветли прозорот" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Дозволи нотификации во вид на балон" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Чат текÑÑ‚ црно/бел надворешен" @@ -1537,109 +1826,115 @@ msgstr "Чат текÑÑ‚ црно/бел надворешен" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "ПритиÑнете на копче за да Ñврзете, или еÑкејп за да излезете" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Сврзување на оÑновен клуч" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Сврзување на Ñекундарен клуч" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA ИГРÐЧКИ КОÐТРОЛИ" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "МУЛТИПЛЕЕР КОÐТРОЛИ" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Вашето име Ñодржи забранети знаци!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Црвена:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Зелена:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Плава:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "ТранÑпарентноÑÑ‚:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Боја" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Преглед" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Ве молиме диÑконектирајте Ñе пред да го Ñмените јазикот" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Ве молиме диÑконектирајте Ñе пред да го Ñмените Ñкинот" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Волуметрички Ñенки може да предизвикаат некои ÑиÑтеми да уÑпорат.\n\n" "Дали Ñте Ñигурни дека Ñакате да ги вклучите?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "ПРЕДУПРЕДУВÐЊЕ ЗРПЕРФОМÐÐСÐ" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Ðплоадирање на Ñлика е задолжително од некои Ñервери поради анти-читерÑки потреби.\n\n" "(Чат прозорчето и GUI е иÑклучено од аплоадирањето)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "Информации за аплоадирањето на Ñлика" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1649,561 +1944,258 @@ msgstr "Ðекои фајлови во вашата GTA:SA дата фолдер "Како и да е, МОДИФИЦИРÐÐИ GTA:SA ФÐЈЛОВИ СЕ БЛОКИРÐÐИ ОД ПОВЕЌЕТО СЕРВЕРИ\n\n" "Дали Ñте Ñигурни дека Ñакате да ги употребите?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "МОДИФИЦИРÐÐИ GTA:SA ФÐЈЛОВИ" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" "Are you sure you want to enable this option?" msgstr "" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Ве молиме внеÑете име" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Ве молиме внеÑете име што ќе биде употребувано во играта. \n" "Ова ќе виде вашето име кога ќе Ñе конектирате и играте на Ñерверот" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "ЕкÑпериментална функција" -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "ПреÑтанување на СЈ варијации (Употребува 65MB повеќе RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "ПоÑтарите рутери може да бараат поÑпора брзина на Ñкенерот." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Додека Ñимнувате притиÑнете на \"On\" за да кориÑтите една конекција." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Тагирајте мрежни пакети за ISPs да може да го препознае MTA Ñообраќајот." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Круг на дното од екранот" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Селектирајте Ñекогаш Ñтандарно. (Оваа опција не е зачувана)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "МакÑимум е обично најдобро" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "ÐвтоматÑко надоградување:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Селектирај Ñтандарно доколку не Ñакаш да добиваш багови." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Селектирајте Ñтандарно за автоматÑки да Ñе инÑталираат важни ажурирања." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-битна боја: " -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Овозможете 16 битна боја на модот - РеÑтартирање на MTA е задолжително" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Поправка на мауÑ:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Поправка на движењето на мауÑот - Можно е реÑтартирање на копмјутерот" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 -msgid "Only change if you're having stability issues." -msgstr "" - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Ðепозната команда" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Зафатен" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Ðе е возможно да Ñе прегледат ажурирањата во моментот" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s е потребна" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Понова верзија од MTA:SA %s е потребна за да влезеш во Ñелектираниот Ñервер.\n\n" -"Дали Ñакате да ја Ñимнете и инÑталирате MTA:SA %s?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Дали Ñакате да ја започнете MTA:SA %s и конектирате на овој Ñервер ?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Ðе е возможно да Ñе конектирате во моментот.\n\n" -"Ве молиме пробајте подоцна." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Се конектира" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Ве молиме почекајте..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "Се проверува" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "Ðжурирањето Ñе проверува" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Ðе Ñе потребни ажурирања" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "СИМÐУВÐЊЕ" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "почекајте..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "ЗÐДОЛЖИТЕЛÐÐ ÐÐДГРÐДБÐ" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "За да влезете во Ñерверот, треба да ја ажурирате MTA.\n\n" -" Сакате ли да ја ажурирате Ñега?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "ОПТИОÐÐЛÐО ÐЖУРИРÐЊЕ" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Серверот препорачува надградба, но не е опходна.\n\n" -" Дали Ñакате да надградите Ñега ?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "Грешка Зачувување" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Фајлот не беше во можноÑÑ‚ да Ñе креира." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "Грешка Симнување" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Симнатиот фајл изгледа е неточен." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Поради некои причини." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "Симнувањето е УÑпешно" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Ðепознат проблем во _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "ГРЕШКÐ" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Ðекои MTA:SA дата фајлови недоÑтаÑуваат.\n\n\n" -"Ве молиме ре-инÑталирајте ја MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% комплетирарно" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Се чека одговор - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Конекцијата е неуÑпешна: Приложеното име е невалидно" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Конекцијата е неуÑпешна: Приложениот хоÑÑ‚ е невалиден" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Конектирањето до %s портата %u е неуÑпешно!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Се конектира на %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "Поврзување" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Конекцијата е прекината " - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "ДиÑконектиран: непозната грешка на протоколот" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "ДиÑконектиран: диÑконектиран рачно" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "ДиÑконектиран: конекцијата е изгубена рачно" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "ДиÑконектиран: Вие Ñте баниран од Ñерверот" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "ДиÑконектиран: ДиÑконектиран од Ñерверот" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Ð’Ñ€Ñката Ñо Ñерверот беше прекината." - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "ДиÑконектиран: конекцијата e oдбиена" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "ÐепоÑтоечки мод (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Погрешен одговор од Ñерверот (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Погрешен одговор од Ñерверот (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "Конзола" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CSettings.cpp:6043 +msgid "Only change if you're having stability issues." +msgstr "" + +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "ОпаÑна грешка" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "ЗРДРСЕ ПОПРÐВИ, ИЗБРИШЕТЕ ГО ОВОЈ ФÐЈЛ:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s моделот е неточен!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Грешно извршување URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "ова помошно прозорче" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "напуштање на апликацијата" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "прикажување на верзијата" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "прикажување на времето" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "прикажување на HUD" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "прикажување на Ñите Ñврзувања" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "го покажува твојот ÑериÑки број" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "Ñе конектира на Ñерверот (хоÑÑ‚ порта ник паÑворд)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "Ñе конектира на минатион Ñервер" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "Ñврзување на контрола (контрола)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "одврзување на контрола" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "Ñе копираат Ñтандарните гта контроли" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "произлегува Ñлика " -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "конфигурацијата ќе Ñе зачува веднаш" -#: Client/core/CCore.cpp:1391 +#: Client/core/CCore.cpp:1494 msgid "clears the debug view" msgstr "чиÑÑ‚ дебаг преглед" -#: Client/core/CCore.cpp:1392 +#: Client/core/CCore.cpp:1495 msgid "scrolls the chatbox upwards" msgstr "Ñкролниго чатот нагоре" -#: Client/core/CCore.cpp:1393 +#: Client/core/CCore.cpp:1496 msgid "scrolls the chatbox downwards" msgstr "Ñкролниго чатот надоле" -#: Client/core/CCore.cpp:1394 +#: Client/core/CCore.cpp:1497 msgid "scrolls the debug view upwards" msgstr "Ñкролниго дебаг прегледот нагоре" -#: Client/core/CCore.cpp:1395 +#: Client/core/CCore.cpp:1498 msgid "scrolls the debug view downwards" msgstr "Ñкролниго дебаг прегледот надоле" -#: Client/core/CCore.cpp:1398 +#: Client/core/CCore.cpp:1501 msgid "shows the memory statistics" msgstr "прикажување на мемориÑката ÑтатиÑтика" -#: Client/core/CCore.cpp:1399 +#: Client/core/CCore.cpp:1502 msgid "shows the frame timing graph" msgstr "прикажување на временÑката графа" -#: Client/core/CCore.cpp:1403 +#: Client/core/CCore.cpp:1506 msgid "for developers: reload news" msgstr "" -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ КОМÐÐДРПОМОШ ] ***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* ЧаÑот е %d:%02d:%02d" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Вие кориÑтите нова верзија, и иÑтата не може да Ñе конектира на јавни Ñервери!" -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." msgstr "" -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "конекција: СинтакÑата е конектирана на <хоÑÑ‚> [<порта> <име> <паÑворд>]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "конекција: Погрешна бројка на портата" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "Конекција: Се конектира %s:%u..." - -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "Конекција: Конекцијата е неуÑпешна %s.%u! " +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Ова ќе ве диÑконектира од Ñерверот.\n\n" +"Дали Ñте Ñигурни дека Ñакате да Ñе диÑконектирате?" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "Конекција: ÐеуÑпешно отпакување на модот" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "ДИСКОÐЕКЦИЈРПРЕДУПРЕДУВÐЊЕ" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" msgstr "" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" msgstr "" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" msgstr "" -#: Client/core/CCommandFuncs.cpp:325 +#: Client/core/CScreenShot.cpp:200 #, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Сврзи ги Ñите контроли од ГТÐ" +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Сликата има %d бајти, но очекувано е %d" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Фајлот за конфигурација е зачуван" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Сликата Ñе изгуби" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 +#: Client/core/CScreenShot.cpp:256 #, c-format -msgid "* Your serial is: %s" -msgstr "*Твојот ÑериÑки број е: %s " - -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Забрзана оÑка" - -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Запирачка оÑка" - -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Програмирање" - -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Соработници" - -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Дизајн на Играта / Скрипти" - -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Локација на Јазикот" - -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Поврзани Ñоработници" - -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Специјално Заблагодарување" - -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "" +msgid "Screenshot taken: '%s'" +msgstr "Сликата е Ñпремна: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Дали Ñакате да побарате онлајн помош во врÑка Ñо овој проблем ?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Ðепозната команда" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2378,25 +2370,56 @@ msgid "Group control backwards" msgstr "Групна контрола наназад" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Скинот што го одбравте неможе Ñе да Ñе прикаже, иÑто така и Ñтандарниот неможе Ñе да прикаже, ве молиме ре-инÑталирајте ја MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Сликата има %d бајти, но очекувано е %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Дали Ñакате да побарате онлајн помош во врÑка Ñо овој проблем ?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Сликата Ñе изгуби" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "Конзола" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Сликата е Ñпремна: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Програмирање" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Соработници" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Дизајн на Играта / Скрипти" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Локација на Јазикот" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Поврзани Ñоработници" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Специјално Заблагодарување" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Забрзана оÑка" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Запирачка оÑка" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2404,6 +2427,61 @@ msgstr "Ðе беше во можноÑÑ‚ да иницијализира Direct "Ве молиме оÑигурете Ñе дека DirectX End-User Runtime и\n" "најновиот ÑервиÑен пакет на Windows е инÑталиран правилно." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Ðеактивен" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "играч" +msgstr[1] "играчи" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "на" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "Ñервер" +msgstr[1] "Ñервери" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Се бара маÑтер лиÑта (%lu ms изминал)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Главниот лиÑÑ‚ на Ñервер неможе да биде разложен." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Главната лиÑта на Ñервери неможе Ñе да биде извадена." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Резерва лиÑта на Ñервери)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Ðе може Ñе да Ñе Ñврзе LAN приклучокот" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Се обидува да иÑтражи LAN Ñервери." + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2457,7 +2535,7 @@ msgstr "Пинг:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "ЛиÑта на Играчи" @@ -2484,40 +2562,39 @@ msgstr "Приклучете Ñе на Ñерверот кога Ñлободе msgid "PLEASE ENTER SERVER PASSWORD" msgstr "ВЕ МОЛИМЕ Ð’ÐЕСЕТЕ ГО ПÐСВОРДОТ ÐРСЕРВЕРОТ" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Времето ви ИÑтече" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Се бара..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "ПРЕБÐРУВÐЧ ÐРСЕРВЕРОТ" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Интернет" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Локал" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Омилени" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Ðеодамна" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2525,298 +2602,367 @@ msgstr "ЗРБРЗО КОÐЕКТИРÐЊЕ:\n\n" "Пишете ја адреÑата и портата во празното меÑто за адреÑа.\n" "Или Ñелектирајте Ñервер од лиÑтата на неодмна поÑетени Ñервери и притиÑнете 'Kонектирај'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "ПОМОШ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "ОÑвежи" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Додај во Омилени" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Конектирај" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Информации за Серверот" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Пребарување на Ñервери" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Пребарај играчи" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Почни Ñо пребарување" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Пребарување на играчи..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Пребарување на Ñервери..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Име" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Играчи" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Пинг" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Мод на Игра" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Вклучи:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Празно" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Полн" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Заклучен" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Офлајн" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Други Верзии" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Ðазад" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Се вчитува..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..Ñе вчитува.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Ðиедна адреÑа не беше Ñпицифицирана!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Ðепознат протокол" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Ве молиме употребете го mtasa:// протоколот!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Ðеважечко име! Ве молиме одете во Опции и впишете ново име!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Вие мора да Ñелектирате Ñервер за да Ñе конектирате на него." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Ðеактивен" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Проблеми Ñо графичките драјвери" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "играч" -msgstr[1] "играчи" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Ðе можам да најдам валидна резолуција за екранот>" -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "на" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Дали Ñте Ñигурни дека Ñакате да ја употребувате оваа резолуција на екранот?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "Ñервер" -msgstr[1] "Ñервери" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Се бара маÑтер лиÑта (%lu ms изминал)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Главниот лиÑÑ‚ на Ñервер неможе да биде разложен." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Барање на вебÑајт" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Главната лиÑта на Ñервери неможе Ñе да биде извадена." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Серверот ги бара Ñледниве вебÑајтови за да може да ги лоадира (подоцна)" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Резерва лиÑта на Ñервери)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "ÐИКОГÐШ ÐЕ Ð’ÐЕСУВÐЈТЕ Ð’ÐЖÐИ ИÐФОРМÐЦИИ ЗРДРÐЕ БИДÐТ УКРÐДЕÐИ" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Ðе може Ñе да Ñе Ñврзе LAN приклучокот" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Запамти ја одлуката" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Се обидува да иÑтражи LAN Ñервери." +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Одбиј" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Оваа верзија е оÑтарена." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "диÑконекција од играта" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "прикажување на таговите на имињата" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "покажува чатбокÑ" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "прикажување на мемориÑката ÑтатиÑтика" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "отвори го внатрешниот чат" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "пренеÑи Ð³Ð»Ð°Ñ Ð´Ð¾ друг играч" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "влези во колата како Ñовозач" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "Ñледниот радио канал" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "минатиот радио канал" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "праќање на порака до наÑочениот играч" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "промена на Ñледното оружје додека Ñте во возило" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "промена на минатото оружје додека Ñте во возило" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "надворешна информација за моменталниот Ñервер" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "дефинициÑки мултипликатор на Ñкала на Ñите текÑтуални прилози" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(ДевелоперÑки мод) прикажување на фигури" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(ДевелоперÑки мод) ÑветÑки отпечатоци за музика во дебугиран прозорец" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "ХОСТИРÐЊЕ ИГРÐ" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "РеÑурÑи" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Име на Ñервер:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "ПаÑворд:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "МакÑимум играчи:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Емитување:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "Мрежно" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Селектиран" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Се" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Старт" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "ÐŸÑ€Ð¾Ð³Ñ€ÐµÑ Ð½Ð° Ñимнување на мапата:" @@ -2837,195 +2983,195 @@ msgstr "%s од %s" msgid "Disconnect to cancel download" msgstr "ДиÑконектирај Ñе за да го прекинеш Ñимнувањето" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "ДиÑконектиран: Ðикот е погрешен" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "ДиÑконектирање од Ñерверот" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "ДиÑконектиран: СериÑкиот број е баниран.\n" "Причина %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "ДиÑконектиран: Вие Ñте банирани.\n" "Причина: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "ДиÑконектиран: Ðкаунтот е баниран.\n" "Причина: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "ДиÑконектиран: Погрешна верзија" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "ДиÑконектиран: Ве молиме почекајте минута и поÑле тоа реконектирајте Ñе." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "ДиÑконектиран: Сервер од различна верзија.\n" "Информации: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "ДиÑконектиран: Лоша верзија.\n" "Информации: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "ДиÑконектиран: Серверот работи на поново верзија.\n" "Информации: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "ДиÑконектиран: Серверот работи на поÑтара верзија.\n" "Информации: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "ДиÑконектиран: Името е веќе во употреба" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "ДиÑконектиран: Серверот ја одби конекцијата: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "ДиÑконектиран: Верификацијата на ÑериÑкиот број е неуÑпешен" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "ДиÑконектиран: ДеÑинк на конекцијата %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "ДиÑконектиран: Вие Ñте кикнати од %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "ДиÑконектиран: Вие бевте банирани од %s " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "ДиÑконектиран: Серверот е иÑклучен или Ñе реÑтартира" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Вие Ñте кикнати од играта" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "ПреоÑтанато време: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d ден" msgstr[1] "%d денови" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d чаÑ" msgstr[1] "%d чаÑови" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d минута" msgstr[1] "%d минути" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3033,296 +3179,206 @@ msgstr[0] "%d Ñекунда" msgstr[1] "%d Ñекунди" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "ДиÑконектиран" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Грешка во Ñимnувањето: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Влегување во игра ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Ðе Ñте конектирани; ве молиме употребете ја Брзо Вклучување или 'вклучување' командата за да Ñе вклучите во Ñерверот." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Стартување на локален Ñервер е невозможно. Види ја конзолата за повеќе детали." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Локален Сервер" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Започнување на локален Ñервер ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Вие Ñте кикнати од играта ( %s)" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Конектирање на локален Ñервер..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Погрешно конектирање на Ñерверот." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Конектирањето на локален Ñервер е прекинат.Проверете ја конзолата за детали." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Конекцијата Ñо Ñерверот е прекината" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "ДиÑконектиран: Ñерверот моментално е полн" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "ДиÑконектиран: паÑвордот е погрешен" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA Клиент верификацијата е неуÑпешна!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "ХОСТИРÐЊЕ ИГРÐ" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "РеÑурÑи" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Име на Ñервер:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "ПаÑворд:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "МакÑимум играчи:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Емитување:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "Мрежно" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Селектиран" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Се" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Старт" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Проблеми Ñо графичките драјвери" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Ðе можам да најдам валидна резолуција за екранот>" - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Дали Ñте Ñигурни дека Ñакате да ја употребувате оваа резолуција на екранот?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Грешка во Ñимnувањето: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3343,11 +3399,11 @@ msgstr "" msgid "Connection error" msgstr "Погрешна конекција" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto не е инÑталирана правилно, ве молиме ре-инÑталирајте ја. " -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Вашиот пребарувач ќе покаже веб Ñтрана Ñо кориÑни информации.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/nb_NO/client.pot b/Shared/data/MTA San Andreas/MTA/locale/nb_NO/client.pot index 264e41a5377..a6e2e3fd6fa 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/nb_NO/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/nb_NO/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:32\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Norwegian Bokmal\n" "Language: nb_NO\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Problemer med omstart av MTA:SA\n\n" -"Om problemet fortsetter, Ã¥pne oppgavebehandleren og\n" -"stopp 'gta_sa.exe' og 'Multi Theft Auto.exe' prosessene\n\n\n" -"Prøv og starte MTA:SA igjen?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Feil" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "MTA kjører allerede.\n\n" -"Om dette problemet fortsetter, vennligst start datamaskinen pÃ¥ nytt" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "MTA kjører allerede.\n\n" -"Ønsker du Ã¥ avslutte den?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Velg din Grand Theft Auto: San Andreas Installasjons Mappe" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA trenger Administrator tilgang for denne oppgaven:\n\n" +" '%s'\n\n" +"Vennligst bekreft i neste vindu." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Feil ved lasting av %s modulen! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Kopierer filer..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopiering avsluttet tidlig. Alt er OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Fullfører..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Ferdig!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Ny installasjon av %s funnet.\n\n" +"Ønsker du Ã¥ kopiere innstillingene dine fra %s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA hadde problemer med Ã¥ Ã¥pne filen '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA mangler filen '%s'" + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA hadde problemer med Ã¥ laste en modell." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Om du nylig modifiserte gta3.img, prøv Ã¥ installere GTA:SA pÃ¥ nytt." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA hadde problemer med Ã¥ legge en oppgradering til ett kjøretøy." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA har funnet feil i filen '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Startet din datamaskin pÃ¥ nytt nÃ¥r du spilte MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Vennligst avslutt følgende programmer før du fortsetter:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Fil versjon matcher ikke. Reinstaller MTA:SA om du opplever problemer.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Noen filer mangler. Reinstaller MTA:SA om du opplever problemer.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA er ikke kompatibel med Windows 'Safe Mode'.\n\n" +"Vennligst start din PC pÃ¥ nytt.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Har du problemer med Ã¥ kjøre MTA:SA?.\n\n" "Ønsker du Ã¥ reversere til en tidligere versjon?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "Det ser ut til Ã¥ være ett problem med Ã¥ starte MTA:SA.\n" "Ã… tilbakestille GTA innstillingene kan noen ganger fikse dette.\n\n" "Ønsker du Ã¥ tilbakestille GTA innstillingene nÃ¥?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA innstillingene er blitt tilbakestilt.\n\n" "Trykk OK for Ã¥ fortsette." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Filen kunne ikke bli slettet: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Har du problemer med Ã¥ kjøre MTA:SA?.\n\n" "Ønsker du online hjelp?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Har du problemer med Ã¥ kjøre MTA:SA?.\n\n" "Ønsker du Ã¥ endre følgende innstillinger?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Fullskjermmodus:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Rammeløst vindu" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Har du problemer med Ã¥ kjøre MTA:SA?.\n\n" "Prøv Ã¥ deaktivere følgende produkter for GTA og MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,128 +189,288 @@ msgstr "ADVARSEL\n\n" "MTA:SA har oppdaget unaturlig aktivitet.\n" "Vennligst kjør ett virus søk for Ã¥ forsikre at ditt system er sikkert.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Den oppdagede filen var: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "GTA: San Andreas kjører allerede. Den mÃ¥ bli avsluttet før MTA:SA kan starte. Ønsker du Ã¥ gjøre det nÃ¥?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informasjon" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Kunne ikke avslutte GTA: San Andreas, om problemet fortsetter, vennligst start datamaskinen pÃ¥ nytt." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Problemer med omstart av MTA:SA\n\n" +"Om problemet fortsetter, Ã¥pne oppgavebehandleren og\n" +"stopp 'gta_sa.exe' og 'Multi Theft Auto.exe' prosessene\n\n\n" +"Prøv og starte MTA:SA igjen?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Feil" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "MTA kjører allerede.\n\n" +"Om dette problemet fortsetter, vennligst start datamaskinen pÃ¥ nytt" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "MTA kjører allerede.\n\n" +"Ønsker du Ã¥ avslutte den?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Register oppføringer mangler. Vennligst reinstaller Multi Theft Auto San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Banen til din GTA: San Andreas installasjon inneholder tegn som ikke støttes (unicode). Vennligst flytt din Grand Theft Auto: San Andreas installasjon til en kompatibel bane som bare inneholder ASCII tegn og reinstaller Mutli Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Banen til din installasjon av 'MTA:SA' eller 'GTA: San Andreas'\n" -"inneholder ett ';' (semikolon).\n\n" -" om du opplever problemer med Ã¥ kjøre MTA:SA,\n" -" flytt installasjonen til en bane som ikke inneholder ett semikolon." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Feil ved lasting. Vennligst forsikre deg om at de nyeste data filene har blitt installert korrekt." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Feil ved lasting. Vennligst forsikre deg om at %s er installert korrekt." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Feil ved lasting. Kunne ikke finne gta_sa.exe i %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Feil ved lasting. %s eksisterer i GTA mappen. Vennligst slett den før du fortsetter." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Hoved fil har ett ugyldig navn (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Hoved fil er usignert. Mulig virus aktivitet.\n\n" -"Se pÃ¥ nettet etter hjelp om MTA ikke fungerer korrekt." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 +#, c-format +msgid "Data file %s is modified. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" +msgstr "Fiks konfigurasjons feil" + +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "" + +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/Install.cpp:479 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asi filer er i din installasjon av 'MTA:SA' eller 'GTA: San Andreas'.\n\n" -"Fjern disse .asi filene om du opplever problemer med MTA:SA." +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Installerer oppdatering..." -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Fil versjon matcher ikke. Reinstaller MTA:SA om du opplever problemer.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Pakker ut filer..." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Noen filer mangler. Reinstaller MTA:SA om du opplever problemer.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA kunne ikke fullføre følgene oppgave:\n\n" +" '%s'\n" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA er ikke kompatibel med Windows 'Safe Mode'.\n\n" -"Vennligst start din PC pÃ¥ nytt.\n" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Krasjet ble forÃ¥rsaket av en grafikkdriver feil **\n\n" +"** Vennligst oppdater dine grafikkdrivere **" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" -msgstr "Fiks konfigurasjons feil" +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Fiks nødvendig høyde feil" +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Installer oppdaterte MTA:SA filer" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Kunne ikke oppdatere pÃ¥ grunn av fil konflikter. Vennligst lukk andre programmer og prøv pÃ¥ nytt" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1088 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Kunne ikke starte Grand Theft Auto: San Andreas. Vennligst prøv Ã¥ starte pÃ¥ nytt, eller om problemet fortsetter, kontakt MTA pÃ¥ www.multitheftauto.com. \n\n" -"[%s]" +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto har ikke blitt installert korrekt, vennligst reinstaller. %s" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas har kanskje ikke startet korrekt. Ønsker du Ã¥ avslutte den?" +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA kan ikke fortsette siden disk %s har ikke nok plass." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Mangler fil:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Om MTA feiler med Ã¥ laste inn, vennligst reinstaller GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Oppdater installerings innstillinger" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Oppdater kompatibilitets innstillinger" #. ///////////////////////////////////////////////////////////////////////// #. @@ -268,166 +478,166 @@ msgstr "GTA: San Andreas har kanskje ikke startet korrekt. Ønsker du Ã¥ avslutt #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Ja" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Nei" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Avslutt" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Hjelp" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Avbryt" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas har støtt pÃ¥ ett problem" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Krasj informasjon" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Kryss av i boksen for Ã¥ sende denne krasj informasjonen til MTA utviklerne ved Ã¥ bruke 'internettet'" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Ved Ã¥ gjøre det øker det sjansen for at denne feilen blir rettet." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Ønsker du Ã¥ starte MTA: San Andres pÃ¥ nytt ?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Advarsel" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Spill MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Forvirrende innstillinger" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus oppdaget!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Prøv hver innstilling og se hva som virker:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Alternativ NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Om du er desperat sÃ¥ kan dette hjelpe:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Tving vindus modus" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Advarsel: kunne ikke oppdage ett anti-virus produkt" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -435,1102 +645,1180 @@ msgstr "MTA kunne ikke oppdage ett anti-virus pÃ¥ din datamaskin.\n\n" "Viruser forstyrrer MTA og degraderer din spill opplevelse.\n\n" "Trykk 'Hjelp' for mer informasjon." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Jeg har allerede installert ett anti-virus" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Jeg vill ikke installere ett anti-virus.\n" "Jeg ønsker at min datamaskin er treg og er del av ett botnet." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Søker etter Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Vennligst start Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Installerer oppdatering..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Tilkobling feilet. Ugyldig navn gitt!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Pakker ut filer..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Tilkobling feilet. Ugyldig host gitt!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Kopierer filer..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Tilkoblingen til %s port %u feilet!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopiering avsluttet tidlig. Alt er OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Kobler til %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Fullfører..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Ferdig!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "KOBLER TIL" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA trenger Administrator tilgang for denne oppgaven:\n\n" -" '%s'\n\n" -"Vennligst bekreft i neste vindu." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Oppkoblingen overskred tidsgrensen" -#: Client/loader/CInstallManager.cpp:376 +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Frakoblet: ukjent protokoll feil" + +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Frakoblet: koblet fra eksternt" + +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Frakoblet: tilkobling mistet eksternt" + +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Frakoblet: du er utestengt fra denne serveren" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Frakoblet: frakoblet fra serveren" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Frakoblet: mistet tilkoblingen til serveren" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Frakoblet: tilkoblingen ble nektet" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA kunne ikke fullføre følgene oppgave:\n\n" -" '%s'\n" +msgid "No such mod installed (%s)" +msgstr "Ingen slik modifikasjon installert (%s)" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Krasjet ble forÃ¥rsaket av en grafikkdriver feil **\n\n" -"** Vennligst oppdater dine grafikkdrivere **" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "DÃ¥rlig svar fra server (2)" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Installer oppdaterte MTA:SA filer" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "DÃ¥rlig svar fra server (1)" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Kunne ikke oppdatere pÃ¥ grunn av fil konflikter. Vennligst lukk andre programmer og prøv pÃ¥ nytt" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Norsk bokmÃ¥l" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Opptatt" + +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Kan ikke se etter oppdateringer akkurat nÃ¥" + +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto har ikke blitt installert korrekt, vennligst reinstaller. %s" +msgid "MTA:SA %s required" +msgstr "MTA:SA %s krevet" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "En oppdatert versjon av MTA:SA %s er pÃ¥krevd for Ã¥ delta i den valgte serveren.\n\n" +"Ønsker du Ã¥ laste ned og installere MTA:SA %s ?" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Ønsker du Ã¥ starte MTA:SA %s og koble til denne serveren ?" + +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Det er ikke mulig Ã¥ koble til akkurat nÃ¥.\n\n" +"Vennligst prøv igjen senere." + +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Kobler til" + +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Vennligst vent..." -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "SJEKKER" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "OPPDATERINGS SJEKK" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Ingen oppdateringer funnet" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "LASTER NED" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "venter..." -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "VIKTIG OPPDATERING" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "For Ã¥ bli med i denne server, sÃ¥ mÃ¥ du oppdatere MTA.\n\n" +" Har du lyst til Ã¥ oppdatere nÃ¥ ?" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "VALGFRI OPPDATERING" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Serveren sier at en oppdatering er anbefalt, men ikke nødvendig.\n\n" +" Har du lyst til Ã¥ oppdatere nÃ¥ ?" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA kan ikke fortsette siden disk %s har ikke nok plass." - -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Mangler fil:" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "FEIL I LAGRING" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Om MTA feiler med Ã¥ laste inn, vennligst reinstaller GTA:SA" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Klarer ikke Ã¥ opprette filen." -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Oppdater installerings innstillinger" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "FEIL I NEDLASTING" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Oppdater kompatibilitets innstillinger" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Den nedlastede filen ser ut til Ã¥ være feil." -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "For en grunn." -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "NEDLASTING FERDIG" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Ukjent feil i _DialogUpdateResult" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "MODIFISERTE GTA:SA FILER" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" msgstr "" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "FEIL" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Velg din Grand Theft Auto: San Andreas Installasjons Mappe" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Noen MTA:SA data filer mangler.\n\n\n" +"Vennligst reinstaller MTA:SA" -#: Client/loader/Utils.cpp:1066 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "Error loading %s module! (%s)" -msgstr "Feil ved lasting av %s modulen! (%s)" +msgid "%3d %% completed" +msgstr "%3d %% ferdig" -#: Client/loader/Utils.cpp:1499 +#: Client/core/CVersionUpdater.cpp:2840 #, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Ny installasjon av %s funnet.\n\n" -"Ønsker du Ã¥ kopiere innstillingene dine fra %s ?" +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Venter pÃ¥ respons - %-3d" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA hadde problemer med Ã¥ Ã¥pne filen '%s'" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ KOMMANDO HJELP ]***\n" -#: Client/loader/Utils.cpp:1560 +#: Client/core/CCommandFuncs.cpp:158 #, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA mangler filen '%s'" +msgid "* The time is %d:%02d:%02d" +msgstr "* Tiden er %d:%02d:%02d" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA hadde problemer med Ã¥ laste en modell." +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Om du nylig modifiserte gta3.img, prøv Ã¥ installere GTA:SA pÃ¥ nytt." +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "koble til: Syntax er 'koble til [ ]'" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA hadde problemer med Ã¥ legge en oppgradering til ett kjøretøy." +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "koble til: DÃ¥rlig port nummer" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CCommandFuncs.cpp:255 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA har funnet feil i filen '%s'" - -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Startet din datamaskin pÃ¥ nytt nÃ¥r du spilte MTA:SA?" - -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Vennligst avslutt følgende programmer før du fortsetter:" - -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Nettsted forespørsler" - -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Serveren ber om følgende hjemmesider for Ã¥ laste dem (senere):" - -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "FOR DIN EGEN BESKYTTELSE, LEGG ALDRI INN SENSITIV DATA" - -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Husk valg" +msgid "connect: Connecting to %s:%u..." +msgstr "koble til: Kobler til %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Tillat" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "koble til: kunne ikke koble til %s:%u!" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Avvis" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "koble til: Klarte ikke Ã¥ laste ut gjeldende mod" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Du bruker en funksjons build! Dette er en test build som ikke kan brukes pÃ¥ offentlige servere!" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA vill ikke motta oppdatering pÃ¥ XP/Vista etter Juli 2019.\n\n" -"Oppgrader Windows for Ã¥ spille pÃ¥ de nyeste serverne." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Dette vill koble deg fra den gjeldende serveren.\n\n" -"Er du sikker pÃ¥ at du vil koble fra?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "FRAKOBLINGS ADVARSEL" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Bundet alle knapper fra GTA" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Lagret konfigurasjonsfilen" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Norsk bokmÃ¥l" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Din serial er: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "INNSTILLINGER" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Flerspiller" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Lyd" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Bindinger" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Kontroller" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Brukergrensesnitt" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Nettleser" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Avansert" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Last inn standardverdier" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Mus sensitivitet:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Vertikal siktings sensitivitet:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Mus innstillinger" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Inverter musen vertikalt" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Styr med mus" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Fly med mus" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "HÃ¥ndkontroller innstillinger" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standard kontroll (Mus + Tastatur)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Klassisk kontroll (HÃ¥ndkontroll)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Død zone" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Metning" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Bruk 'Bindinger' fanen for hÃ¥ndkontroll knapper." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Venstre Stikke" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Høyre Stikke" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "BESKRIVELSE" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "KNAPP" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. KNAPP" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Kallenavn:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Lagre server passord" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Oppdater server listen automatisk" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Tillat skjermbilde opplastning" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Bruk egendefinerte GTA:SA filer" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Map rendring instillinger" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Gjennomsiktighet:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Hovedvolum:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Radio volum:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "SFX volum:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA volum:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Stemme volum:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Spill modus:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Generelt" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Radio innstillinger" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Radio tonekontroll" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Bruker spor instillinger" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Tilfeldig" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Sekvensiell" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Automatisk Medie Skann" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Demp innstillinger" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Demp alle lyder ved minimering" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Demp Radio lyder ved minimering" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Demp SFX lyder ved minimering" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Demp MTA lyder ved minimering" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Demp Stemmer ved minimering" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Oppløsning:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Tegne Avstand:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Lysstyrke:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX Kvalitet:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anisotropisk filtrering:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Kantutjevning:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Aspektforhold:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Vindu" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Rammeløs behold oppløsning" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Lav" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Middels" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "HÂøy" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Veldig høy" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Av" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Automatisk" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD Samsvarer med Sideforhold" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Volumetriske Skygger" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Gress effekt" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Varmedis" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Dekkrøyk etc" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Minimer Fullskjerm" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Aktiver Enhet Dialog Utvalg" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Vis utrygge oppløsninger" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Alltid render kjøretøy i høy detalj" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Aktiver eksterne nettsteder" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Aktiver Javascript pÃ¥ eksterne nettsteder" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Tilpasset svarteliste" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Skriv inn ett domene f.eks. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Blokker" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Domene" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Fjern domene" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Tilpasset hviteliste" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Tillat" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Div" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Rask lasting av CJ klær:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Leser fart:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Enkel tilkobling:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Pakke tagg:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Animasjon for framdrift:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Prosess prioritet:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Feilsøkingsinnstillinger:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Strømnings minne:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Oppdater versjons type:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Installer viktige oppdateringer:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "PÃ¥" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Svært langsom" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Standard" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Rask" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Over noraml" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Maks" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 kompatibilitet:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-bit farge" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Mus fiks" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Klient ressursfiler:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Vis i utforsker" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Oppdater automatisk" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Se etter oppdateringer nÃ¥" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Noen innstillinger vill bli forandret neste gang du starter MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Vill du starte pÃ¥ nytt nÃ¥?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "KREVER OMSTART" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Noen innstillinger vill bli endret nÃ¥r du kobler fra denne serveren" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Ønsker du Ã¥ koble fra nÃ¥?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "FRAKOBLING KREVES" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "HÃ¥ndkontroller ikke oppdaget - Sjekk tilkoblingen og start spillet pÃ¥ nytt" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Binder akse" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Beveg en akse for Ã¥ binde, eller escape for Ã¥ tømme" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "SprÃ¥k:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Tema:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "ForhÃ¥ndsinnstillinger:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Last inn" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Farger" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Oppsett" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Innstillinger" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Chat bakgrunn" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Chat tekst" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Input bakgrunn" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Linjer:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Skalering:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Bredde:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Størrelse" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "etter" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "i" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "sek" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Falming" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Ton ut gamle linjer" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horisontal:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Vertikal:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Tekst-Justering:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Posisjon" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Venstre" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Senter" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Høyre" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Topp" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Bunn" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Skrift" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Skjul bakgrunnen nÃ¥r du ikke skriver" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Kallenavn fullføring ved Ã¥ bruke \"Tab\" knappen" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Tillat server Ã¥ flashe vinduet" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Tillat oppgavelinje notifikasjoner" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Chat tekst svart/hvit omriss" @@ -1538,109 +1826,115 @@ msgstr "Chat tekst svart/hvit omriss" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Trykk en knapp for Ã¥ binde, eller escape for Ã¥ tømme" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Binder en primær knapp" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Binder en sekundær knapp" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA SPILL KONTROLLER" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "FLERSPILLER KONTROLLER" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Kallenavnet inneholder ugyldige tegn!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Rød:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Grønn:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "BlÃ¥:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Gjennomsiktighet:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Farge" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "ForhÃ¥ndsvisning" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Vennligst koble fra før du endrer sprÃ¥k" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Vennligst koble fra før du bytter skin" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Volumetriske skygger kan fÃ¥ noen systemer til Ã¥ gÃ¥ tregere.\n\n" "Er du sikker pÃ¥ at du vil aktivere dem?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "YTELSE ADVARSEL" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Skjerm opplasting er pÃ¥krevd av noen servere for anti-juks grunner.\n\n" "(Chat boksen og Brukergrensesnittet gjelder ikke for dette)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "SKJERM OPPLASTINGS INFORMASJON" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1650,561 +1944,259 @@ msgstr "Noen filer i din GTA:SA data mappe er forandret.\n" "Men, MODIFISERTE GTA:SA FILER ER BLOKKERT AV MANGE SERVERE\n\n" "Er du sikker pÃ¥ at du vill bruke dem?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "MODIFISERTE GTA:SA FILER" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" "Are you sure you want to enable this option?" msgstr "" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Vennligst oppgi ett kallenavn" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Vennligst skriv inn ett brukernavn for bruk i spillet. \n" "Dette vill være ditt navn nÃ¥r du kobler til og spiller pÃ¥ en server" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Meget eksperimentelle funksjoner." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Motvirker forsinkelser med CJ variasjoner (Bruker 65MB mer RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Eldre rutere kan kreve en tregere skannings fart." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "SlÃ¥ pÃ¥ for Ã¥ bare bruke en tilkobling under nedlasting." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Tagg nettverk pakker for Ã¥ hjelpe ISPer Ã¥ identifisere MTA trafikk." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Snurrende sirkel animasjon nederst pÃ¥ skjermen" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Alltid velg standard. (Denne innstillingen er ikke lagret)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maksimum er vanligvis best" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Oppdater automatisk:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Velg standard viss du ikke liker Ã¥ skrive bug rapporter." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Velg standard for Ã¥ automatisk installere viktige oppdateringer." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-bit farge:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Aktiver 16-bit farge modus - MTA mÃ¥ startes pÃ¥ nytt" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Mus fiks:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Mus bevegelses fiks - Omstart av datamaskinen er kanskje pÃ¥krevd" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Ukjent kommando eller cvar: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Opptatt" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Kan ikke se etter oppdateringer akkurat nÃ¥" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s krevet" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "En oppdatert versjon av MTA:SA %s er pÃ¥krevd for Ã¥ delta i den valgte serveren.\n\n" -"Ønsker du Ã¥ laste ned og installere MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Ønsker du Ã¥ starte MTA:SA %s og koble til denne serveren ?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Det er ikke mulig Ã¥ koble til akkurat nÃ¥.\n\n" -"Vennligst prøv igjen senere." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Kobler til" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Vennligst vent..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "SJEKKER" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "OPPDATERINGS SJEKK" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Ingen oppdateringer funnet" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "LASTER NED" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "venter..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "VIKTIG OPPDATERING" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "For Ã¥ bli med i denne server, sÃ¥ mÃ¥ du oppdatere MTA.\n\n" -" Har du lyst til Ã¥ oppdatere nÃ¥ ?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "VALGFRI OPPDATERING" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Serveren sier at en oppdatering er anbefalt, men ikke nødvendig.\n\n" -" Har du lyst til Ã¥ oppdatere nÃ¥ ?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "FEIL I LAGRING" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Klarer ikke Ã¥ opprette filen." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "FEIL I NEDLASTING" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Den nedlastede filen ser ut til Ã¥ være feil." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "For en grunn." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "NEDLASTING FERDIG" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Ukjent feil i _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "FEIL" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Noen MTA:SA data filer mangler.\n\n\n" -"Vennligst reinstaller MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% ferdig" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Venter pÃ¥ respons - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Tilkobling feilet. Ugyldig navn gitt!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Tilkobling feilet. Ugyldig host gitt!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Tilkoblingen til %s port %u feilet!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Kobler til %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "KOBLER TIL" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Oppkoblingen overskred tidsgrensen" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Frakoblet: ukjent protokoll feil" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Frakoblet: koblet fra eksternt" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Frakoblet: tilkobling mistet eksternt" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Frakoblet: du er utestengt fra denne serveren" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Frakoblet: frakoblet fra serveren" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Frakoblet: mistet tilkoblingen til serveren" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Frakoblet: tilkoblingen ble nektet" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Ingen slik modifikasjon installert (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "DÃ¥rlig svar fra server (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "DÃ¥rlig svar fra server (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "از آخرین مقاله خبری دیدن کنید" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONSOLL" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Kritisk feil" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "FOR Ã… FIKSE, FJERN DENNE FILEN:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s modul er feil!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Feil ved utføring av URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "denne hjelpeskjermen" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "avslutter programmet" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "viser versjonen" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "viser tiden" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "viser HUDen" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "viser alle bindingene" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "viser din serial" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "kobler till en server (host port navn pass)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "kobler til en tidligere server" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "binder en knapp (knapp kontrol)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "fjerner bindingen til en knapp (knapp)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "kopierer de vanlige gta kontrollene" -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "gir et skjermbilde" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "lagrer umiddelbart konfigen" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "tømmer debug vinduet" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "ruller chatbox oppover" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "ruller chatbox nedover" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "ruller debug vinduet nedover" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "ruller debug vinduet nedover" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "viser minnestatistikken" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "viser bildetid grafen" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ KOMMANDO HJELP ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Tiden er %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "koble til: Syntax er 'koble til [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "koble til: DÃ¥rlig port nummer" +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "gir et skjermbilde" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "koble til: Kobler til %s:%u..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "lagrer umiddelbart konfigen" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "koble til: kunne ikke koble til %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "tømmer debug vinduet" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "koble til: Klarte ikke Ã¥ laste ut gjeldende mod" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "ruller chatbox oppover" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "ruller chatbox nedover" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "ruller debug vinduet nedover" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "ruller debug vinduet nedover" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "viser minnestatistikken" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Bundet alle knapper fra GTA" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "viser bildetid grafen" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Lagret konfigurasjonsfilen" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Din serial er: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Du bruker en funksjons build! Dette er en test build som ikke kan brukes pÃ¥ offentlige servere!" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Akselerasjons Akse" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA vill ikke motta oppdatering pÃ¥ XP/Vista etter Juli 2019.\n\n" +"Oppgrader Windows for Ã¥ spille pÃ¥ de nyeste serverne." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Bremse Akse" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Dette vill koble deg fra den gjeldende serveren.\n\n" +"Er du sikker pÃ¥ at du vil koble fra?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programmering" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "FRAKOBLINGS ADVARSEL" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Bidragsytere" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Spill design / Scripting" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "SprÃ¥k Lokalisering" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "از آخرین مقاله خبری دیدن کنید" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Patch bidragsytere" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Skjermbilde fikk %d bytes, men forventet %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Særlig Takk til" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Skjermdump feilet" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Skjermbilde tatt: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Ønsker du søke internettet for hjelp for dette problemet ?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Ukjent kommando eller cvar: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2379,25 +2371,56 @@ msgid "Group control backwards" msgstr "Gruppe kontroll bakover" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Skin som ble valgt kunne ikke lastes, og standard skin kunne heller ikke lastes, vennligst reinstaller MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Skjermbilde fikk %d bytes, men forventet %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Ønsker du søke internettet for hjelp for dette problemet ?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Skjermdump feilet" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONSOLL" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Skjermbilde tatt: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programmering" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Bidragsytere" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Spill design / Scripting" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "SprÃ¥k Lokalisering" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Patch bidragsytere" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Særlig Takk til" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Akselerasjons Akse" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Bremse Akse" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2405,6 +2428,61 @@ msgstr "Kunne ikke starte Direct3D9.\n\n" "Vennligst sikre at DirectX End-User Runtime og\n" "nyeste Windows Service Pack er installert korrekt." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Inaktiv" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "spiller" +msgstr[1] "spillere" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "pÃ¥" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "" +msgstr[1] "servere" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Ber om master server listen (%lu ms gÃ¥tt)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Master server listen kunne ikke analyseres." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Server listen kunne ikke hentes." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Sikkerhetskopier server listen)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Prøver Ã¥ finne LAN servere" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2458,7 +2536,7 @@ msgstr "Latens:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Spiller liste" @@ -2485,40 +2563,39 @@ msgstr "Bli med i serveren sÃ¥ fort det er en plass ledig." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "VENNLIGST SKRIV INN SERVER PASSORD" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Tidsavbrudd" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Sender forespørsel..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "SERVER LISTE" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internett" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Lokalt" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Favoritter" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Siste" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2526,298 +2603,367 @@ msgstr "FOR RASK TILKOBLING:\n\n" "Skriv inn adressen og port inn i adresse vinduet.\n" "Eller velg en server fra historie listen og trykk 'Koble til'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "HJELP" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Oppdater" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Legg til favoritt" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Koble til" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Server informasjon" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Søk i servere" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Søk i spillere" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Start søk" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Søk i spillere..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Søk servere..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Navn" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Spillere" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Spillmodus" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Ta med:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Tom" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "LÃ¥st" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Frakoblet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Andre versjoner" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Tilbake" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Laster inn..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..laster.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Ingen adresse oppgitt!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Ukjent protokoll" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Vennligst bruk mtasa:// protokollen!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Ugyldig kallenavn! Vennligst gÃ¥ til Innstillinger og velg ett nytt!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Du mÃ¥ velge en server for Ã¥ koble til." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Inaktiv" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problem med grafikk driver" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "spiller" -msgstr[1] "spillere" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Kan ikke finne gyldig skjerm oppløsning." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "pÃ¥" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Er du sikker pÃ¥ at du ønsker Ã¥ bruke denne oppløsningen?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "" -msgstr[1] "servere" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Ber om master server listen (%lu ms gÃ¥tt)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Master server listen kunne ikke analyseres." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Nettsted forespørsler" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Server listen kunne ikke hentes." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Serveren ber om følgende hjemmesider for Ã¥ laste dem (senere):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Sikkerhetskopier server listen)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "FOR DIN EGEN BESKYTTELSE, LEGG ALDRI INN SENSITIV DATA" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Husk valg" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Prøver Ã¥ finne LAN servere" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Avvis" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Denne versjonen er utløpt." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "koble fra spillet" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "viser navne merker" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "viser chat boksen" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "viser nettverks statistikken" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "Ã¥pne chat inngangen" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "overfører tale til andre spillere" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "entre en bil som passasjer" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "neste radio kanal" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "forrige radio kanal" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "sender en melding til en valg spiller" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "endrer til det neste vÃ¥penet mens i et kjøretøy" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "endrer til det forrige vÃ¥penet mens i et kjøretøy" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "Gir informasjon om serveren" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "definerer skala multiplikatoren for alle tekst flater" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Utvikler modus) viser colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Utvikler modus) skriver verdens lyd IDene inn i debug vinduet" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "OPPRETT SPILL" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Ressurser" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Server navn:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Passord:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Maks spillere:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Kringkast:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Merket" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Alle" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Kart nedlastnings fremdrift:" @@ -2838,195 +2984,195 @@ msgstr "%s av %s" msgid "Disconnect to cancel download" msgstr "Koble fra for Ã¥ kansellere nedlasting" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Frakoblet: Ugyldig kallenavn" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Koble fra server" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Frakoblet: Serial er utestengt.\n" "Grunn: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Frakoblet: Du er utestengt.\n" "Grunn: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Frakoblet: Konto er utestengt.\n" "Grunn: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Frakoblet: Versjon matcher ikke" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Frakoblet: Tilkoblings flod. Vennligst vent en stund, sÃ¥ prøv igjen." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Frakoblet: Server fra annen gren.\n" "Informasjon: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Frakoblet: DÃ¥rlig versjon.\n" "Informasjon: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Frakoblet: Serveren kjører en nyere versjon.\n" "Informasjon: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Frakoblet: Server kjører en eldre versjon.\n" "Informasjon: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Frakoblet: Kallenavn allerede i bruk" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Frakoblet: Serveren nektet tilgang: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Frakoblet: Serial verifisering feilet" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Frakoblet: Tilkobling avsynkronisert %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Frakoblet: Du ble kastet ut av %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Frakoblet: Du ble utestengt av %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Koblet fra: Server avsluttet eller starter pÃ¥ nytt" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Du ble kastet ut av spillet" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Denne serveren krever en ikke modifisert versjon av gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Vennligst bytt gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Denne serveren tillater ikke bruk av modifiserte D3D9.DLL filer" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Fjern D3D9.DLL fra din GTA installasjons mappe og start MTA pÃ¥ nytt" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Denne serveren tillater ikke Virtuelle maskiner" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Denne serveren krever at driver signering er aktivert" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Vennligst start din datamaskin pÃ¥ nytt" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Denne serveren har oppdaget manglende anti-juks komponenter" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Prøv Ã¥ starte MTA pÃ¥ nytt" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Denne serveren krever ett ikke modifisert gta.img og gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Vennligst bytt gta.img eller gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Denne serveren tillater ikke Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Sørg for at ingen andre programmer modifiserer MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Gjenværende tid: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d dag" msgstr[1] "%d dager" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d time" msgstr[1] "%d timer" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d minutt" msgstr[1] "%d minutter" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3034,296 +3180,206 @@ msgstr[0] "%d sekund" msgstr[1] "%d sekunder" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Forbindelse brutt" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Nedlastingsfeil: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Blir med i spill ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Ikke tilkoblet; vennligst bruk Rask Tilkobling eller 'connect' kommandoen for Ã¥ koble til en server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Kunne ikke starte lokal server. Se konsoll for detaljer." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Lokal Server" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Starter lokal server ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Du ble kastet ut av spillet ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Kobler til lokal server..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Feil under oppkobling til server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Oppkobling til lokal server timet ut. Se konsoll for detaljer." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Tilkobling til serveren gikk tapt" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Frakoblet: serveren er full" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Frakoblet: Feil passord oppgitt" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA klient verifisering feilet!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "OPPRETT SPILL" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Ressurser" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Server navn:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Passord:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Maks spillere:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Kringkast:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Merket" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Alle" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problem med grafikk driver" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Kan ikke finne gyldig skjerm oppløsning." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Er du sikker pÃ¥ at du ønsker Ã¥ bruke denne oppløsningen?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Nedlastingsfeil: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3344,11 +3400,11 @@ msgstr "" msgid "Connection error" msgstr "Tilkoblingsfeil" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto har ikke blitt installert rett, vennligst reinstaller." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Din nettleser vill nÃ¥ vise en side som inneholder hjelpe informasjon.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/nl_NL/client.pot b/Shared/data/MTA San Andreas/MTA/locale/nl_NL/client.pot index 17d93b79c4b..7ce0ac27c8c 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/nl_NL/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/nl_NL/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Dutch\n" "Language: nl_NL\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Moeite met herstarten van MTA:SA\n\n" -"Als het probleem aanhoudt, open taakbeheer en\n" -"stop de 'gta_sa.exe' and 'Multi Theft Auto.exe' processen\n\n\n" -"MTA:SA proberen te herstarten?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Fout" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Een ander exemplaar van MTA is al actief.\n\n" -"Als dit probleem aanhoudt, gelieve uw computer te herstarten" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Een ander exemplaar van MTA is al actief.\n\n" -"Wilt u het beëindigen?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Selecteer uw Grand Theft Auto: San Andreas installatie pad" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA heeft Administrator toegang nodig voor de volgende opdracht:\n\n" +" '%s'\n\n" +"Gelieve te bevestigen in het volgende venster." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Fout bij het laden van %s module! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Bestanden kopiëren..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopie is vroeger klaar. Alles OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Voltooien..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Klaar!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Nieuwe installatie van %s ontdekt.\n\n" +"Wilt u uw instelling van %s kopiëren?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA kon het bestand '%s' niet openen" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "Het bestand '%s' ontbreekt in uw GTA:SA installatie." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA kon een model niet laden." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Als je onlangs gta3.img hebt aangepast, probeer dan GTA:SA opnieuw te installeren." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA kon geen vehicle upgrade toevoegen." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA heeft fouten gevonden in het bestand '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Is uw computer herstart tijdens het spelen van MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Gelieve de volgende programma's te beëindigen voor u verdergaat:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Bestandsversie komt niet overeen. Herinstalleer MTA:SA als u problemen ondervindt.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Sommige bestanden onderbreken. Herinstalleer MTA:SA als u problemen ondervindt.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA is niet compatibel met Windows 'Veilige Modus'.\n\n" +"Herstart uw PC.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Heeft u problemen met MTA:SA?.\n\n" "Wilt u terugkeren naar een oudere versie?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "Er lijkt een probleem te zijn bij het starten van MTA:SA.\n" "GTA instellingen resetten kan dit probleem soms oplossen.\n\n" "Wilt u de GTA instellingen nu resetten?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA instellen zijn gereset.\n\n" "Druk OK om door te gaan." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Bestand kon niet worden verwijderd: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Heeft u problemen met MTA:SA?.\n\n" "Wilt u online hulp raadplegen?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Heeft u problemen met MTA:SA?.\n\n" "Wilt u de volgende instelling aanpassen?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Volledig scherm:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Randloos venster" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Heb je problemen met het uitvoeren van MTA:SA?.\n\n" "Probeer de volgende producten voor GTA en MTA uit te schakelen:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +189,293 @@ msgstr "WAARSCHUWING\n\n" "MTA:SA heeft vreemde activiteiten ontdekt.\n" "Gelieve een virusscan uit te voeren om te verzekeren dat uw systeem veilig is.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Het gedetecteerde bestand was: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Een exemplaar van GTA: San Andreas is al actief. Het moet gestopt worden voor MTA:SA kan worden gestart. Wilt u dit nu doen?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informatie" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Kan GTA: San Andreas niet beëindigen. Als dit probleem aanhoudt, gelieve uw computer te herstarten." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Moeite met herstarten van MTA:SA\n\n" +"Als het probleem aanhoudt, open taakbeheer en\n" +"stop de 'gta_sa.exe' and 'Multi Theft Auto.exe' processen\n\n\n" +"MTA:SA proberen te herstarten?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Fout" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Een ander exemplaar van MTA is al actief.\n\n" +"Als dit probleem aanhoudt, gelieve uw computer te herstarten" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Een ander exemplaar van MTA is al actief.\n\n" +"Wilt u het beëindigen?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Registervermeldingen ontbreken. Gelieve Multi Theft Auto: San Andreas te herinstalleren." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Het pad naar uw GTA: San Andreas installatie bevat niet ondersteunde (unicode) karakters. Gelieve uw Grand Theft Auto: San Andreas installatie naar een compatibel pad te verplaatsen dat enkel ASCII karakters bevat. En Multi Theft Auto: San Andreas te herinstalleren." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Het pad naar uw 'MTA:SA' of 'GTA: San Andreas' installatie\n" -"bevat een ';' (puntkomma).\n\n" -" Als u problemen ondervindt met MTA:SA,\n" -" verplaats dan uw installatiepad(en) naar een pad dat geen puntkomma bevat." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Laden mislukt. Gelieve te verzekeren dat de laatste data bestanden correct zijn geïnstalleerd." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Laden mislukt. Gelieve te verzekeren dat %s correct is geïnstalleerd." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Laden mislukt. Kon gta_sa.exe niet vinden in %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Laden mislukt. %s bestaat in uw GTA pad. Gelieve het te verwijderen voor u doorgaat." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Hoofdbestand had een foute naam (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Hoofdbestand is niet ondertekend. Mogelijke virusactiviteit.\n\n" -"Gelieve online hulp te raadplegen als MTA niet correct werkt." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Data-bestand %s ontbreekt. Mogelijke virusactiviteit.\n\n" -"Overweeg Multi Theft Auto opnieuw te installeren voor je veiligheid.\n" -"Raadpleeg de online hulp als MTA niet correct werkt." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Data-bestand %s is gewijzigd. Mogelijke virusactiviteit.\n\n" -"Overweeg Multi Theft Auto opnieuw te installeren voor je veiligheid.\n" -"Raadpleeg de online hulp als MTA niet correct werkt." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "Er bevinden zich .asi bestand in de 'MTA:SA' of 'GTA: San Andreas' installatiemap.\n\n" -"Verwijder deze .asi bestanden als u problemen heeft met MTA:SA." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Bestandsversie komt niet overeen. Herinstalleer MTA:SA als u problemen ondervindt.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Sommige bestanden onderbreken. Herinstalleer MTA:SA als u problemen ondervindt.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA is niet compatibel met Windows 'Veilige Modus'.\n\n" -"Herstart uw PC.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Probleem met configuratie oplossen" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Probleem met vereiste admin-rechten oplossen" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Onbekend" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "Het bestand '%s' is momenteel vergrendeld door %zu processen.\n\n" +"Wilt u de volgende processen beëindigen en doorgaan met updaten?\n\n" +"%s" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/Install.cpp:479 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Kon Grand Theft Auto: San Andreas niet starten. Probleem te herstarten, of als het probleem aanhoudt, contacteer MTA op www.multitheftauto.com. \n\n" -"[%s]" +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "Uw installatie is nu mogelijk beschadigd.\n\n" +"%zu van %zu bestanden konden niet worden hersteld vanaf de back-up.\n\n" +"U moet Multi Theft Auto opnieuw installeren vanaf www.multitheftauto.com\n" +"of probeer de update uit te voeren met beheerdersrechten." -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas is mogelijks niet correct gestart. Wilt u het beëindigen?" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Update installeren..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Bestanden uitpakken..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA kon te volgende opdracht niet afwerken:\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** De crash werd veroorzaakt door een grafische driver fout **\n\n" +"** Gelieve uw grafische driver te updaten **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Geüpdatet MTA:SA bestanden installeren" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Kon niet updaten door bestandsconflicten. Gelieve andere toepassingen te sluiten en opnieuw te proberen" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto werd niet correct geïnstalleerd, gelieve te herinstalleren. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA kan niet worden gestart omdat het kopiëren van een bestand is mislukt:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA kan niet worden gestart omdat een MTA:SA-bestand onjuist of ontbreekt is:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Kopieer MTA:SA-bestanden" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA kan niet worden gestart omdat een GTA:SA-bestand onjuist is of ontbreekt:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "Patch GTA:SA afhankelijkheid" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA kan niet worden gestart omdat het GTA:SA-uitvoerbaar bestand onjuist is of ontbreekt:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Controleer alsjeblieft je antivirus op een vals-positieve detectie, probeer een uitzondering toe te voegen voor het GTA:SA-uitvoerbaar bestand en herstart MTA:SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "Genereer GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA kan niet worden gestart omdat het GTA:SA-uitvoerbaar bestand niet laadbaar is:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Patch GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA kan niet worden gestart omdat het patchen van GTA:SA is mislukt:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA kan niet verdergaan omdat schijf %s niet genoeg ruimte heeft." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Ontbrekend bestand:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Als MTA niet kan starten, gelieve GTA:SA te herinstalleren" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Installatie instellingen vernieuwen" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Compatibiliteitsinstellingen vernieuwen" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +483,167 @@ msgstr "GTA: San Andreas is mogelijks niet correct gestart. Wilt u het beëindig #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Ja" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Nee" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "OK" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Afsluiten" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Help" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Annuleren" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas is tegen een probleem aangelopen" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Crash informatie" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Vink dit vakje aan om deze crash info te verzenden naar de MTA ontwikkelaars via het 'internet'" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Dit vergroot de kans dat deze crash wordt opgelost." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Wilt u MTA: San Andreas herstarten?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Waarschuwing" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "Uw Grand Theft Auto: San Andreas installatiemap bevat deze bestanden:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Deze bestanden zijn niet vereist en kunnen het goed functioneren van de grafische functies verhinderen in deze versie van MTA:SA.\n\n" "Het wordt aanbevolen om deze bestanden te verwijderen of te hernoemen." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "Houd deze bestanden, maar toon ook deze waarschuwing bij de volgende start" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Herinner me niet opnieuw aan deze bestanden" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Hernoem deze bestanden van *.dll naar *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Toon mij deze bestanden" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Speel MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - verwarrende opties" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus gedecteerd!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Probeer iedere mogelijkheid en kijk wat er werkt:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Standaard NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Alternatief NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Standaard Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Alternatief Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Als u wanhopig wordt, dit helpt mogelijks:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Als je al een optie hebt geselecteerd die werkt, kan dit helpen:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Venstermodus forceren" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Niet meer tonen" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Waarschuwing: Kon geen anti-virus software detecteren" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1106 +651,1179 @@ msgstr "MTA kon geen anti-virus software detecteren op uw PC.\n\n" "Virussen storen MTA en degraderen uw gebruikservaring.\n\n" "Druk 'Help' voor meer informatie." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Ik heb al een anti-virus software" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "I zal geen anti-virus software installeren.\n" "I wil dat mijn PC sloom is en deel uitmaakt van een botnet." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Grand Theft Auto San Andreas zoeken..." -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Gelieve Grand Theft Auto San Andreas te starten" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Update installeren..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Verbinding mislukt. Ongeldige gebruikersnaam opgegeven!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Bestanden uitpakken..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Verbinding mislukt. Ongeldige host opgegeven!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Bestanden kopiëren..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Verbinding met %s op poort %u is mislukt!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopie is vroeger klaar. Alles OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Verbinden met %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Voltooien..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Klaar!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "VERBINDEN" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA heeft Administrator toegang nodig voor de volgende opdracht:\n\n" -" '%s'\n\n" -"Gelieve te bevestigen in het volgende venster." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Verbinden duurde te lang" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA kon te volgende opdracht niet afwerken:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Verbinding verbroken: onbekende protocol fout" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** De crash werd veroorzaakt door een grafische driver fout **\n\n" -"** Gelieve uw grafische driver te updaten **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Verbinding verbroken: verbroken op afstand" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Geüpdatet MTA:SA bestanden installeren" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Verbinding verbroken: verbinding verloren op afstand" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Kon niet updaten door bestandsconflicten. Gelieve andere toepassingen te sluiten en opnieuw te proberen" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Verbinding verbroken: u bent verbannen van deze server" -#: Client/loader/CInstallManager.cpp:561 -#, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto werd niet correct geïnstalleerd, gelieve te herinstalleren. %s" +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Verbinding verbroken: verbinding verbroken met de server" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "" +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Verbinding verbroken: verbinding naar de server is verbroken" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA kan niet worden gestart omdat het kopiëren van een bestand is mislukt:" +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Verbinding verbroken: verbinding geweigerd" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA kan niet worden gestart omdat een MTA:SA-bestand onjuist of ontbreekt is:" +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 +#, c-format +msgid "No such mod installed (%s)" +msgstr "Geen dergelijke mod geïnstalleerd (%s)" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Kopieer MTA:SA-bestanden" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Slecht antwoord van de server (2)" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA kan niet worden gestart omdat een GTA:SA-bestand onjuist is of ontbreekt:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Slecht antwoord van de server (1)" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Patch GTA:SA afhankelijkheid" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Nederlands" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA kan niet worden gestart omdat het GTA:SA-uitvoerbaar bestand onjuist is of ontbreekt:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Bezig" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Controleer alsjeblieft je antivirus op een vals-positieve detectie, probeer een uitzondering toe te voegen voor het GTA:SA-uitvoerbaar bestand en herstart MTA:SA." +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Kan momenteel niet op updates controleren" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Genereer GTA:SA" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s nodig" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA kan niet worden gestart omdat het GTA:SA-uitvoerbaar bestand niet laadbaar is:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Een nieuwere versie van MTA:SA %s is nodig om de geselecteerde server binnen te komen.\n\n" +"Wilt u de nieuwere versie van MTA:SA %s downloaden en installeren?" + +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Wilt u MTA:SA %s starten en verbinden met deze server?" + +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Op dit moment is het niet mogelijk te verbinden.\n\n" +"Probeer het later nog een keer." -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Patch GTA:SA" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Aan het verbinden" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA kan niet worden gestart omdat het patchen van GTA:SA is mislukt:" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Gelieve te wachten..." -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA kan niet verdergaan omdat schijf %s niet genoeg ruimte heeft." +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "CONTROLEREN" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Ontbrekend bestand:" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "ZOEKEN NAAR UPDATES" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Als MTA niet kan starten, gelieve GTA:SA te herinstalleren" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Geen update nodig" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Installatie instellingen vernieuwen" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "AAN HET DOWNLOADEN" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Compatibiliteitsinstellingen vernieuwen" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "wachten..." -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Onbekend" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "VERPLICHTE UPDATE" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "Het bestand '%s' is momenteel vergrendeld door %zu processen.\n\n" -"Wilt u de volgende processen beëindigen en doorgaan met updaten?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Om deze server te joinen moet u MTA updaten.\n\n" +" Wilt u nu updaten?" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "Uw installatie is nu mogelijk beschadigd.\n\n" -"%zu van %zu bestanden konden niet worden hersteld vanaf de back-up.\n\n" -"U moet Multi Theft Auto opnieuw installeren vanaf www.multitheftauto.com\n" -"of probeer de update uit te voeren met beheerdersrechten." +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "OPTIONELE UPDATE" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "De server raad een update aan, dit is echter niet noodzakelijk.\n\n" +" Wilt u nu updaten?" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "ERROR BIJ HET OPSLAAN" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Selecteer uw Grand Theft Auto: San Andreas installatie pad" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Kon het bestand niet maken." -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Fout bij het laden van %s module! (%s)" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "FOUT BIJ HET DOWNLOADEN" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Nieuwe installatie van %s ontdekt.\n\n" -"Wilt u uw instelling van %s kopiëren?" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Het gedownloade bestand lijkt verkeerd." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA kon het bestand '%s' niet openen" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Om de een of andere reden." -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "Het bestand '%s' ontbreekt in uw GTA:SA installatie." +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "DOWNLOAD VOLTOOID" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA kon een model niet laden." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Onbekend probleem in _DialogUpdateResult" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Als je onlangs gta3.img hebt aangepast, probeer dan GTA:SA opnieuw te installeren." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "GEWIJZIGDE GTA:SA BESTANDEN" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA kon geen vehicle upgrade toevoegen." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Oké" -#: Client/loader/Utils.cpp:1631 -#, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA heeft fouten gevonden in het bestand '%s'" +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "FOUT" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Is uw computer herstart tijdens het spelen van MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Sommige MTA:SA data bestanden ontbreken.\n\n\n" +"Gelieve MTA:SA te herinstalleren" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Gelieve de volgende programma's te beëindigen voor u verdergaat:" +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% voltooid" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Website verzoeken" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Wachten op antwoord - %-3d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "De server vraagt toestemming om de volgende websites (later) te laden:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ COMMANDO HULP ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NOOIT GEVOELIGE GEGEVENS INGEVEN ZODAT ZE NIET GESTOLEN WORDEN" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* De tijd is %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Mijn keuze onthouden" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Toestaan" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "connect: Syntaxis is 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Weigeren" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "connect: Foutief poort nummer" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "Hoofdmenu" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "connect: Verbinden met %s:%u..." -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Je draait een testversie uit de feature-branch! Deze is alleen voor testdoeleinden en kan niet gebruikt worden om verbinding te maken met reguliere servers" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "connect: Kan niet verbinden naar %s:%u!" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA zal na Juli 2019 geen updates meer uitbrengen voor gebruikers op Windows XP/Vista.\n\n" -"Upgrade je versie van Windows om te kunnen blijven spelen op de nieuwste servers." +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "connect: Kan huidige mod niet stoppen" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Dit zal de verbinding met de huidige server verbreken.\n\n" -"Weet je zeker dat je de verbinding wilt verbreken?" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "VERBINDINGSWAARSCHUWING" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." msgstr "" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Nederlands" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "" + +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Elke besturing staat aan van GTA" + +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Configuratiebestand opgeslagen" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Uw serial is: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "INSTELLINGEN" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Multiplayer" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Video" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Geluid" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Toetsen" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Besturing" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Interface" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Webbrowser" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Geavanceerd" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Laad standaard" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Muis gevoeligheid:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Verticale richting gevoeligheid:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Muis opties" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Muis verticaal omkeren" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Met de muis sturen" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Vliegen met de muis" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Joypad opties" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standaard toetsen (Muis + Toetsenbord)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Klassieke Besturing (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Dode Zone" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Verzadiging" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Gebruik de 'Binds' tab voor joypad knoppen." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "linker Stok" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Rechter Stok" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "BESCHRIJVING" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "TOETS" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. TOETS" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Bijnaam:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Server wachtwoorden opslaan" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Automatisch serverlijst vernieuwen" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Schermupload toestaan" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Externe geluiden toestaan" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Downloadvenster altijd weergeven" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Toestaan verbinding te maken met Discord Rich Presence" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Gebruik aangepaste GTA:SA bestanden" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Map teken opties" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Opaciteit:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Hoofd volume:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Radio volume:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Geluidseffecten volume:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA volume:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Stem volume:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Afspeel modus:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Algemeen" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Radio opties" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Radio Equalizer" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Radio automatisch afstellen" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Usertrack opties" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Radio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Willekeurig" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Sequentieel" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Automatisch mediabestanden scannen" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Demp opties" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Demp alle geluiden als MTA geminimaliseerd is" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Demp radio geluid als MTA geminimaliseerd is" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Demp geluidseffecten als MTA geminimaliseerd is" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Demp MTA geluiden als MTA geminimaliseerd is" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Demp stemgeluiden als MTA geminimaliseerd is" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Resolutie:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "FOV:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Tekenafstand:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Helderheid:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Beeldkwaliteit:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anisotropische filtering:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Anti-aliasing:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Beeldverhouding:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Venstermodus" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI bewust" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Standaard" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Hou de resolutie zonder randen" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mip Mappen" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Laag" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Gemiddeld" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Hoog" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Zeer hoog" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Uit" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Automatisch" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD beeldverhouding koppelen" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Volumetrische Schaduwen" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Gras effecten" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Hittewaas" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Rokende banden enz." -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Dynamische voetgangersschaduwen" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Motion blur" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Corona regenreflecties" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Volledig Scherm Minimaliseren" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Zet Het Apparaten Dialoogvenster Aan" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Toon onveilige resoluties" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Voertuigen altijd met hoge details weergeven" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Peds altijd met hoge kwaliteit renderen" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Externe websites inschakelen" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Javascript inschakelen op externe websites" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Aangepaste zwarte lijst" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Voer een domein in, bijv. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Blokkeren" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Domein" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Domein verwijderen" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Aangepaste whitelist" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Toestaan" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Overig" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "CJ's kledij snel laden:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Browser snelheid:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Enkelvoudige verbinding:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Pakket tag:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Voortgangsanimatie:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Proces prioriteit:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Debug instellingen:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Streaming geheugen:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Update versie type:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Installeer belangrijke updates:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Aan" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Erg langzaam" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Standaard" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Snel" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normaal" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Meer dan normaal" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Min" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Max" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 compatibiliteit:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-bit kleuren" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Aanwijzer fixen" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Client resource bestanden:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Toon in Verkenner" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Automatisch bijwerken" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Check nu voor updates" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Sommige instellingen zullen worden gewijzigd wanneer u de volgende keer MTA start" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Wil je nu herstarten?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "HERSTART NODIG" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Sommige instellingen zullen worden gewijzigd wanneer u de huidige verbinding verbreekt" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "Wil je de verbinding nu verbreken?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "VERBINDING VERBREKEN VEREIST" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad niet gevonden - Check de connecties en herstart het spel" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "as koppelen" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Beweeg een as om te koppelen, of druk escape om te wissen" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Taal:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Thema:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Voorinstellingen:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Chat" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Laad" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Kleuren" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Layout" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Instellingen" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Chat Achtergrond" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Chat Tekst" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Invoer Achtergrond" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Invoer Tekst" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Regels:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Schaal:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Breedte:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Afmeting" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "na" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "voor" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "sec" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Vervaging" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Oude tekstregels vervagen" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horizontaal:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Verticaal:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Text-Uitlijning:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-Positie:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-Positie:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Positie" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Links" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Middelpunt" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Rechts" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Bovenzijde" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Onderkant" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Lettertype" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Achtergrond verbergen wanneer men niet typt" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Nickname-aanvulling met de \"Tab\" toets" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Sta servers toe om het gamevenster op te lichten" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Sta taakbalknotificaties toe" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Zwarte/witte uitlijning van text in de chat" @@ -1547,111 +1831,116 @@ msgstr "Zwarte/witte uitlijning van text in de chat" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Druk op een toets om op te slaan, of escape om te wissen" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Primaire toets aan het vastleggen" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Secundaire toets aan het vastleggen" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA TOETSEN" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "MULTIPLAYER TOETSEN" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Uw gebruikersnaam bevat verboden tekens!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Hoofdmenu" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "In-Game" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Rood:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Groen:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Blauw:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Transparantie:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Kleur" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Voorbeeld" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Graag de verbinding verbreken alvorens de taal te veranderen" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Gelieve de verbinding te verbreken voordat u uw thema verandert" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Volumetrische schaduwen kunnen uw systeem vertragen.\n\n" "Weet u zeker dat u deze wil inschakelen?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "PRESTATIE WAARSCHUWING" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Het uploaden van je scherm is soms vereist in servers omdat ze anti-cheat programma's hebben.\n\n" "(De chat box en GUI worden niet geüpload)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "SCHERM UPLOAD INFORMATIE" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "Sommige servers hebben scripts die geluid, zoals radio, van het internet afspelen.\n\n" "Door dit uit te schakelen, kunt u wellicht besparen op het datagebruik van uw netwerk.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "EXTERNE GELUIDEN" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "Het lijkt erop dat je de Rich Presence verbindingsmogelijkheid hebt ingeschakeld. Wil je toestaan dat servers hun gegevens delen?\n\n" -"Dit omvat jouw unieke ID-identificatie." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "GEEF TOESTEMMING VOOR HET DELEN VAN GEGEVENS" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1661,11 +1950,7 @@ msgstr "Sommige bestanden in uw GTA:SA data map zijn gewijzigd.\n" "Echter, GEWIJZIGDE GTA:SA BESTANDEN ZIJN GEBLOKEERD DOOR VEEL SERVERS\n\n" "Weet u zeker dat u ze wilt gebruiken?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "GEWIJZIGDE GTA:SA BESTANDEN" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1673,550 +1958,252 @@ msgid "Enabling DPI awareness is an experimental feature and\n" msgstr "DPI bewustzijn (beter bekend als \"DPI awareness\") is een experimentele functie, en we raden het alleen aan voor gebruikers die MTA spelen op een geschaalde monitor. Bij het gebruik van deze optie kun je mogelijk visuele of beeldproblemen ervaren.\n\n" "Weet je zeker dat je deze functie aan wilt zetten?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "EXPERIMENTELE FUNCTIE" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Gelieve een gebruikersnaam in te vullen" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Voer een nickname in die gebruikt zal worden in het spel. \n" "Dit wordt jou nickname wanneer je verbinding maakt met een server." -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Zeer experimentele functie." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Stopt haperingen met CJ variaties (Gebruikt 65MB meer RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Oudere routers hebben mogelijks een lagere scan snelheid nodig." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "1 verbinding gebruiken tijdens het downloaden." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Label paketten uit je internetverkeer om providers te helpen MTA netwerkverkeer te onderscheiden." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Draaiende cirkel animatie onderin het scherm" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Selecteer altijd standaard. (Deze instelling wordt niet opgeslagen)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maximum is meestal het beste" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Automatisch bijwerken:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Selecteer standaard tenzij u graag bug reports invult." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Selecteer standaard, om automatisch belangrijke updates te installeren." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-bit kleuren:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Schakel 16 bit kleuren modus in - MTA moet herstart worden" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Aanwijzer fixen:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Beweging aanwijzer fixen - Uw PC moet mogelijks herstart worden" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Command of cvar onbekend: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Bezig" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Kan momenteel niet op updates controleren" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s nodig" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Een nieuwere versie van MTA:SA %s is nodig om de geselecteerde server binnen te komen.\n\n" -"Wilt u de nieuwere versie van MTA:SA %s downloaden en installeren?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Wilt u MTA:SA %s starten en verbinden met deze server?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Op dit moment is het niet mogelijk te verbinden.\n\n" -"Probeer het later nog een keer." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Aan het verbinden" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Gelieve te wachten..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "CONTROLEREN" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "ZOEKEN NAAR UPDATES" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Geen update nodig" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "AAN HET DOWNLOADEN" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "wachten..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "VERPLICHTE UPDATE" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Om deze server te joinen moet u MTA updaten.\n\n" -" Wilt u nu updaten?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "OPTIONELE UPDATE" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "De server raad een update aan, dit is echter niet noodzakelijk.\n\n" -" Wilt u nu updaten?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "ERROR BIJ HET OPSLAAN" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Kon het bestand niet maken." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "FOUT BIJ HET DOWNLOADEN" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Het gedownloade bestand lijkt verkeerd." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Om de een of andere reden." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "DOWNLOAD VOLTOOID" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Onbekend probleem in _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Oké" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "FOUT" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Sommige MTA:SA data bestanden ontbreken.\n\n\n" -"Gelieve MTA:SA te herinstalleren" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% voltooid" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Wachten op antwoord - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Verbinding mislukt. Ongeldige gebruikersnaam opgegeven!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Verbinding mislukt. Ongeldige host opgegeven!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Verbinding met %s op poort %u is mislukt!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Verbinden met %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "VERBINDEN" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Verbinden duurde te lang" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Verbinding verbroken: onbekende protocol fout" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Verbinding verbroken: verbroken op afstand" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Verbinding verbroken: verbinding verloren op afstand" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Verbinding verbroken: u bent verbannen van deze server" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Verbinding verbroken: verbinding verbroken met de server" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Verbinding verbroken: verbinding naar de server is verbroken" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Verbinding verbroken: verbinding geweigerd" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Geen dergelijke mod geïnstalleerd (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Slecht antwoord van de server (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Slecht antwoord van de server (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "Nieuws" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Bezoek laatste nieuwsartikel" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "CONSOLE" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Fatale fout" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "OM OP TE LOSSEN, VERWIJDER DIT BESTAND:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s module is niet correct!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Fout bij uitvoeren van URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "Dit hulpscherm tonen" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "de applicatie afstuiten" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "toont de versie" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "toont de tijd" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "toont de hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "toont alle besturingselementen" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "toont jou seriecode" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "verbind naar een server (host port nick wachtwoord)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "verbind naar de vorige server" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "wijst een toets toe (toets besturing)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "verwijdert de toewijzing (toets)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "kopieert de standaard gta besturing" -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "Geeft een screenshot" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "Slaat de configuratie direct op" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "schakelt het debugscherm uit" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "scrolt de chatbox omhoog" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "scrolt de chatbox omlaag" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "scrolt het debug zicht omhoog" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "scrolt het debug zicht omlaag" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "Toont de geheugenstatistieken" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "toont de frame tijdsgrafiek" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "voor programmeurs: nieuws verversen" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ COMMANDO HULP ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* De tijd is %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "connect: Syntaxis is 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "connect: Foutief poort nummer" +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "Geeft een screenshot" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "connect: Verbinden met %s:%u..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "Slaat de configuratie direct op" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "connect: Kan niet verbinden naar %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "schakelt het debugscherm uit" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "connect: Kan huidige mod niet stoppen" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "scrolt de chatbox omhoog" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "scrolt de chatbox omlaag" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "scrolt het debug zicht omhoog" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "scrolt het debug zicht omlaag" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "Toont de geheugenstatistieken" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Elke besturing staat aan van GTA" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "toont de frame tijdsgrafiek" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Configuratiebestand opgeslagen" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "voor programmeurs: nieuws verversen" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Uw serial is: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Je draait een testversie uit de feature-branch! Deze is alleen voor testdoeleinden en kan niet gebruikt worden om verbinding te maken met reguliere servers" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Versnel Assen" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA zal na Juli 2019 geen updates meer uitbrengen voor gebruikers op Windows XP/Vista.\n\n" +"Upgrade je versie van Windows om te kunnen blijven spelen op de nieuwste servers." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Vertraag Assen" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Dit zal de verbinding met de huidige server verbreken.\n\n" +"Weet je zeker dat je de verbinding wilt verbreken?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programmeren" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "VERBINDINGSWAARSCHUWING" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Bijdragers" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Spel Ontwerp / Scripting" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "Nieuws" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Taal Lokaliseren" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Bezoek laatste nieuwsartikel" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Patch bijdragers" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Screenshot heeft %d bytes, maar verwachtte %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Met bijzondere dank aan" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Screenshot mislukt" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Deze software en dit project maken gebruik van de volgende bibliotheken en software:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Screensshot gemaakt: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Wilt u online ondersteuning voor dit probleem?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Command of cvar onbekend: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2391,25 +2378,56 @@ msgid "Group control backwards" msgstr "Groepsbesturing achteruit" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Het gekozen thema kon niet geladen worden, en het standaard uiterlijk kon ook niet geladen worden, gelieve MTA te herinstalleren." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Screenshot heeft %d bytes, maar verwachtte %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Wilt u online ondersteuning voor dit probleem?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Screenshot mislukt" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "CONSOLE" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Screensshot gemaakt: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programmeren" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Bijdragers" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Spel Ontwerp / Scripting" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Taal Lokaliseren" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Patch bijdragers" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Met bijzondere dank aan" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Deze software en dit project maken gebruik van de volgende bibliotheken en software:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Versnel Assen" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Vertraag Assen" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2417,6 +2435,61 @@ msgstr "Was niet in staat om Direct3D9 te initialiseren.\n\n" "Gelieve ervoor te zorgen dat de DirectX End-User Runtime en\n" "laatste Windows Service Packs correct geïnstalleerd zijn." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Inactief" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "Speler" +msgstr[1] "Spelers" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "aan" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "server" +msgstr[1] "servers" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Hoofdserver lijst opvragen (%lu ms verstreken)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Hoofdserver lijst kan niet worden ontcijferd." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Hoofdserver lijst kan niet worden opgehaald." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Backup server lijst)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Kan niet verbinden met LAN-uitzending aansluiting" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Probeert LAN servers te vinden" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2470,7 +2543,7 @@ msgstr "Latentie:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Speler lijst" @@ -2497,40 +2570,39 @@ msgstr "Verbind met de server zodra een speler slot beschikbaar is." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "VOER SERVER WACHTWOORD IN" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Tijd Verlopen" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Opvragen…" #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "SERVER BROWSER" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Lokaal" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Favorieten" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Recent" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2538,298 +2610,367 @@ msgstr "VOOR SNELLE VERBINDING:\n\n" "Typ het adres en port in de adresbalk.\n" "Of selecteer een server uit de geschiedenis lijst en druk op 'Verbinden'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "HULP" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Vernieuwen" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Voeg Favoriet toe" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Verbinden" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Server informatie" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Zoek naar servers" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Zoek naar spelers" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Start met zoeken" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "spelers zoeken..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "servers zoeken..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Naam" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Spelers" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Ping" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Spelmode" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Toevoegen:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Leeg" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Vol" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Vergrendeld" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Offline" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Andere Versies" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Terug" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Laden..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..laden.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Geen adres geselecteerd!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Onbekend protocol" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Gebruik a.u.b. het mtasa:// protocol!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Ongeldige gebruikersnaam! Gelieve naar Instellingen te gaan en een nieuwe instellen!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Je moet een server selecteren om mee te verbinden." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Inactief" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Probleem met het stuurprogramma van je videokaart" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "Speler" -msgstr[1] "Spelers" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Kan geen geschikte schermresolutie vinden." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "aan" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Bent u zeker dat u deze schermresolutie wilt gebruiken?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "server" -msgstr[1] "servers" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Hoofdserver lijst opvragen (%lu ms verstreken)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Hoofdserver lijst kan niet worden ontcijferd." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Website verzoeken" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Hoofdserver lijst kan niet worden opgehaald." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "De server vraagt toestemming om de volgende websites (later) te laden:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Backup server lijst)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NOOIT GEVOELIGE GEGEVENS INGEVEN ZODAT ZE NIET GESTOLEN WORDEN" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Kan niet verbinden met LAN-uitzending aansluiting" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Mijn keuze onthouden" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Probeert LAN servers te vinden" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Weigeren" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Deze versie is verlopen." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "Verbinding verbroken" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "toon de naamplaatjes" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "toont de chatbox" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "toont de netwerk statistieken" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "opent de chat invoer" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "zend stem uit naar andere spelers" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "stapt in een auto als passagier" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "volgende radio zender" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "vorige radio zender" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "zend een bericht naar een bepaalde speler" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "verander naar een volgend wapen wanneer je in een voertuig zit" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "verander naar een vorig wapen wanneer je in een voertuig zit" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "toont informatie omtrent de huidige server" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "bepaald de schaal vermenigvuldiger van alle tekst-voorstellingen" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Ontwikkelingsmodus) toont alle colvormen" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Ontwikkelingsmodus) toont geluid-ids in een debug venster" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "HOST SPEL" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Bronnen" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Server naam:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Wachtwoord:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Max spelers:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Uitzenden:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Geselecteerde" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Alle" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Start" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Kaart download vooruitgang:" @@ -2850,195 +2991,195 @@ msgstr "%s van %s" msgid "Disconnect to cancel download" msgstr "Verbreek de verbinding om het downloaden te stoppen" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Verbinding verbroken: Ongeldige gebruikersnaam" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Verbinding verbroken" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Verbinding verbroken: Serienummer is verbannen.\n" "Reason: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Verbinding verbroken: U werd verbannen.\n" " Reden: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Verbinding verbroken: Account is verbannen.\n" "Reden: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Verbinding verbroken: Versies komen niet overeen" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Verbinding verbroken: Teveel aanmeldingen. Een minuut wachten alstublieft, probeer het dan opnieuw." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Verbinding verbroken: Server van andere tak.\n" "Informatie: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Verbinding verbroken: Slechte versie.\n" "Informatie: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Verbinding verbroken: Server draait een nieuwere versie.\n" "Informatie: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Verbinding verbroken: Server draait een oudere versie.\n" "Informatie: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Verbinding verbroken: Gebruikersnaam al in gebruik" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Verbinding verbroken: Spelerelement kon niet worden aangemaakt." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Verbinding verbroken: server weigerde de verbinding: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Verbinding verbroken: Serienummer verificatie mislukt" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Verbinding verbroken: Verbindings-desynchronisatie %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Verbinding verbroken: U werd uit de server gegooid door %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Verbinding verbroken: U werd verbannen door %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Verbinding verbroken: Server is uitgezet of wordt opnieuw opgestart" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "U werd uit het spel gegooid" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Deze server vereist een niet gewijzigde gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Gelieve gta_sa.exe te vervangen" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Deze server staat aangepaste D3D9.DLLs niet toe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Verwijder D3D9.DLL uit je GTA-installatiemap en herstart MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Deze server staat geen virtuele machines toe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Deze server vereist dat ondertekende stuurprogramma's ingeschakeld zijn" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Start je PC opnieuw op" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Deze server heeft ontbrekende anti-cheat componenten gedetecteerd" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Probeer MTA opnieuw te starten" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Deze server vereist een onaangepaste gta3.img en gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Gelieve gta3.img of gta_int.img te vervangen" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Deze server staat Wine niet toe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Zorg ervoor dat geen ander programma MTA:SA aanpast" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Resterende Tijd: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d dag" msgstr[1] "%d dagen" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d uur" msgstr[1] "%d uren" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d minuut" msgstr[1] "%d minuten" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3046,296 +3187,206 @@ msgstr[0] "%d seconde" msgstr[1] "%d seconden" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Verbinding verbroken" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Download fout: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "Een UFO rondvliegen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "Rondtoeren" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "De golven berijden van" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "Met de trein reizen in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "Rondvliegen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "Rondrijden" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "Met een monstertruck rondrijden" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "Met een quad rondrijden" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "Rond bunny hoppen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "Rare dingen doen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "Rondklimmen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "Een drive-by uitvoeren in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "Blub blub..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "Water inademen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "Verdrinken in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "Dekking zoeken in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "Vechten in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "Met vuisten slaan in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "Dwazen neerknallen in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "Spuiten" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "Met een jetpack rondvliegen" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "Letterlijk in brand in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "In vuur en vlam staan in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "Zwemmen in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "Rondzweven in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "Achtervolgd worden door een haai" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "Stikken tot de dood in" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Spel aan het joinen ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Niet verbonden; gelieve Quick Connect of het 'connect' commando te gebruiken om te verbinden met een server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Kon lokale server niet starten. Bekijk de console voor details." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Lokale Server" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Lokale server aan het starten ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "Area 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "Rondlopen " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "U werd uit het spel gegooid ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Verbinden met lokale server..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Fout bij het verbinden met de server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Verbinden met de lokale server duurde te lang. Zie console voor details." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Verbinden met de server werd verloren" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Verbinding verbroken: de server zit momenteel vol" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Verbinding verbroken: verkeerd paswoord ingevoerd" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA Client verificatie mislukt!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "In een greppel" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "Onderweg naar het ziekenhuis" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "Hun maker ontmoeten" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "Spijt hebben van hun keuzes" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "Overleden" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "HOST SPEL" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Bronnen" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Server naam:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Wachtwoord:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Max spelers:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Uitzenden:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Geselecteerde" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Alle" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Start" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Probleem met het stuurprogramma van je videokaart" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Kan geen geschikte schermresolutie vinden." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Bent u zeker dat u deze schermresolutie wilt gebruiken?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Download fout: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3356,11 +3407,11 @@ msgstr "" msgid "Connection error" msgstr "Verbindingsfout" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto werd niet correct geïnstalleerd, gelieve te herinstalleren." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Uw browser zal nu een webpagina tonen met hulpinformatie.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/pl_PL/client.pot b/Shared/data/MTA San Andreas/MTA/locale/pl_PL/client.pot index 55dd173fc46..925cf7d0f4f 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/pl_PL/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/pl_PL/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-26 01:09+0000\n" +"PO-Revision-Date: 2026-01-29 17:21\n" "Last-Translator: \n" "Language-Team: Polish\n" "Language: pl_PL\n" @@ -17,72 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Problem ze zrestartowaniem MTA:SA\n\n" -"JeÅ›li problem siÄ™ powtarza, otwórz Menedżer ZadaÅ„\n" -"i zatrzymaj procesy 'gta_sa.exe' i 'Multi Theft Auto.exe'\n\n\n" -"Czy chcesz zrestartować MTA:SA jeszcze raz?" +#: Client/loader/Utils.cpp:537 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Uruchom Grand Theft Auto: San Andreas.\n" +"Gra powinna znajdować siÄ™ w katalogu 'Program Files (x86)'." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Błąd" +#: Client/loader/Utils.cpp:538 Client/loader/Utils.cpp:554 +msgid "Searching for GTA: San Andreas" +msgstr "Wyszukiwanie GTA: San Andreas" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Proces MTA jest już włączony.\n\n" -"JeÅ›li problem siÄ™ powtarza, zrestartuj swój komputer" +#: Client/loader/Utils.cpp:552 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Przepraszamy, nie udaÅ‚o nam siÄ™ znaleźć gry.\n" +"Uruchom Grand Theft Auto: San Andreas i naciÅ›nij 'retry' lub 'ponów'.\n" +"Gra powinna znajdować siÄ™ w katalogu 'Program Files (x86)'." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Proces MTA jest już uruchomiony.\n\n" -"Czy chcesz go zatrzymać?" +#: Client/loader/Utils.cpp:622 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Wybierz folder z zainstalowanÄ… grÄ… Grand Theft Auto: San Andreas" + +#: Client/loader/Utils.cpp:1025 Client/loader/CInstallManager.cpp:434 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA potrzebuje praw administratora dla nastÄ™pujÄ…cej czynnoÅ›ci:\n\n" +" '%s'\n\n" +"ProszÄ™ je potwierdzić w nastÄ™pnym oknie." + +#: Client/loader/Utils.cpp:1126 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Błąd przy Å‚adowaniu moduÅ‚u %s! (%s)" + +#: Client/loader/Utils.cpp:1451 Client/loader/Dialogs.cpp:1094 +msgid "Copying files..." +msgstr "KopiujÄ™ pliki..." + +#: Client/loader/Utils.cpp:1511 Client/loader/Dialogs.cpp:1099 +msgid "Copy finished early. Everything OK." +msgstr "Kopiowanie zakoÅ„czone przed czasem. Wszystko w porzÄ…dku." + +#: Client/loader/Utils.cpp:1517 Client/loader/Dialogs.cpp:1104 +msgid "Finishing..." +msgstr "KoÅ„czenie..." + +#: Client/loader/Utils.cpp:1519 Client/loader/Dialogs.cpp:1108 +msgid "Done!" +msgstr "Gotowe!" + +#: Client/loader/Utils.cpp:1559 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Wykryto nowÄ… instalacjÄ™ %s.\n\n" +"Czy chcesz skopiować swoje ustawienia z %s ?" + +#: Client/loader/Utils.cpp:1598 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA miaÅ‚o problem z otwarciem pliku '%s'" + +#: Client/loader/Utils.cpp:1620 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA nie może otworzyć brakujÄ…cego pliku '%s'." + +#: Client/loader/Utils.cpp:1645 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA miaÅ‚o problem z zaÅ‚adowaniem modelu." + +#: Client/loader/Utils.cpp:1647 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "JeÅ›li niedawno zmodyfikowaÅ‚eÅ› plik 'gta3.img', spróbuj przeinstalować GTA:SA." + +#: Client/loader/Utils.cpp:1672 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA miaÅ‚o problem z dodaniem ulepszenia do pojazdu." + +#: Client/loader/Utils.cpp:1691 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA znalazÅ‚o błędy w pliku '%s'" + +#: Client/loader/Utils.cpp:1773 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Czy Twój komputer zrestartowaÅ‚ siÄ™ podczas gry w MTA:SA?" + +#: Client/loader/Utils.cpp:1838 +msgid "Please terminate the following programs before continuing:" +msgstr "ProszÄ™ zakoÅ„czyć pracÄ™ nastÄ™pujÄ…cych programów przed kontynuowaniem:" + +#: Client/loader/MainFunctions.cpp:313 +msgid "Invalid module path detected.\n" +msgstr "Åšcieżka do jednego z modułów .dll jest nieprawidÅ‚owa." + +#: Client/loader/MainFunctions.cpp:337 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "WystÄ…piÅ‚ błąd z rozbieżnoÅ›ciÄ… wersji plików. Przeinstaluj MTA:SA jeÅ›li doÅ›wiadczasz problemów z dziaÅ‚aniem gry.\n" + +#: Client/loader/MainFunctions.cpp:345 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Brakuje niektórych plików. Przeinstaluj MTA:SA jeÅ›li doÅ›wiadczasz problemów z dziaÅ‚aniem gry.\n" + +#: Client/loader/MainFunctions.cpp:355 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA nie jest kompatybilne z trybem awaryjnym systemu Windows.\n\n" +"Zrestartuj swój komputer.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:534 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Masz problemy z uruchamianiem MTA:SA?\n\n" "Czy chcesz powrócić do poprzedniej wersji?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:562 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +143,48 @@ msgstr "Wykryto problem z uruchomieniem MTA:SA.\n" "Możliwe, że zresetowanie ustawieÅ„ dla GTA:SA pomoże go rozwiÄ…zać.\n\n" "Czy chcesz zresetować ustawienia gry GTA:SA?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:577 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "Ustawienia gry GTA:SA zostaÅ‚y zresetowane.\n\n" "WciÅ›nij OK aby kontynuować." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:582 #, c-format msgid "File could not be deleted: '%s'" msgstr "Plik nie mógÅ‚ zostać usuniÄ™ty: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:590 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Masz problemy z uruchamianiem MTA:SA?\n\n" "Czy chcesz uzyskać pomoc on-line?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:627 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Masz problemy z dziaÅ‚aniem MTA:SA?.\n\n" "Czy chcesz zmienić nastÄ™pujÄ…ce ustawienie?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:628 Client/core/CSettings.cpp:1163 +#: Client/core/CSettings.cpp:1677 msgid "Fullscreen mode:" msgstr "Tryb peÅ‚noekranowy:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:628 Client/core/CSettings.cpp:1173 +#: Client/core/CSettings.cpp:2343 msgid "Borderless window" msgstr "Okno bez ramki (Borderless)" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:697 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Masz problemy z dziaÅ‚aniem MTA:SA?\n\n" "Spróbuj wyłączyć nastÄ™pujÄ…ce ustawienia lub dodatki dla GTA oraz MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:732 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +192,294 @@ msgstr "OSTRZEÅ»ENIE\n\n" "MTA:SA wykryÅ‚o podejrzanÄ… aktywność na tym komputerze.\n" "ProszÄ™ przeskanować komputer przy użyciu programu antywirusowego aby upewnić siÄ™, że jest on bezpieczny.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:735 #, c-format msgid "The detected file was: %s\n" msgstr "Wykryty plik to: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:982 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Proces gry GTA: San Andreas jest już uruchomiony. Przed włączeniem MTA:SA proces ten musi być zatrzymany. Czy chcesz go teraz zatrzymać?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:983 Client/loader/MainFunctions.cpp:990 +#: Client/loader/MainFunctions.cpp:1949 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1723 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informacja" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:989 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Nie udaÅ‚o siÄ™ zatrzymać procesu GTA: San Andreas. JeÅ›li problem siÄ™ powtarza, zrestartuj swój komputer." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1123 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Problem ze zrestartowaniem MTA:SA\n\n" +"JeÅ›li problem siÄ™ powtarza, otwórz Menedżer ZadaÅ„\n" +"i zatrzymaj procesy 'gta_sa.exe' i 'Multi Theft Auto.exe'\n\n\n" +"Czy chcesz zrestartować MTA:SA jeszcze raz?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1128 Client/loader/MainFunctions.cpp:1150 +#: Client/loader/MainFunctions.cpp:1155 Client/loader/MainFunctions.cpp:1562 +#: Client/loader/CInstallManager.cpp:1116 +#: Client/loader/CInstallManager.cpp:1125 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:273 Client/core/CConnectManager.cpp:331 +#: Client/core/CConnectManager.cpp:417 Client/core/CConnectManager.cpp:424 +#: Client/core/CConnectManager.cpp:434 Client/core/CSettings.cpp:3847 +#: Client/core/CSettings.cpp:5223 Client/core/CSettings.cpp:5251 +#: Client/core/CSettings.cpp:5990 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1616 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1638 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1697 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1771 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1201 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1281 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1291 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1360 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1446 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1458 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Błąd" + +#: Client/loader/MainFunctions.cpp:1148 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Proces MTA jest już włączony.\n\n" +"JeÅ›li problem siÄ™ powtarza, zrestartuj swój komputer" + +#: Client/loader/MainFunctions.cpp:1153 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Proces MTA jest już uruchomiony.\n\n" +"Czy chcesz go zatrzymać?" + +#: Client/loader/MainFunctions.cpp:1190 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Nie odnaleziono wymaganych wpisów w Rejestrze systemu. Zainstaluj ponownie MTA:SA." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1195 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Åšcieżka do Twojej instalacji gry GTA: San Andreas zawiera niewspierane znaki Unicode. PrzenieÅ› swojÄ… instalacjÄ™ gry Grand Theft Auto: San Andreas do Å›cieżki zawierajÄ…cej wyłącznie znaki ASCII i przeinstaluj moda Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1208 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Åšcieżka do Twojej instalacji 'MTA:SA' lub 'GTA: San Andreas'\n" -"zawiera znak ';' (Å›rednik).\n\n" -" JeÅ›li bÄ™dziesz miaÅ‚ problemy z dziaÅ‚aniem MTA:SA,\n" -" zainstaluj grÄ™ i moda w Å›cieżkach, które nie zawierajÄ… znaku Å›rednika." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "Åšcieżka instalacji GTA:SA lub MTA:SA zawiera ';' (Å›rednik).\n\n" +"JeÅ›li doÅ›wiadczasz problemów z uruchomieniem MTA:SA, zmieÅ„ katalog instalacyjny na taki, który nie zawiera Å›rednika w Å›cieżce." + +#: Client/loader/MainFunctions.cpp:1396 +msgid "Invalid installation paths detected." +msgstr "Åšcieżka instalacji GTA San Andreas lub Multi Theft Auto jest nieprawidÅ‚owa." + +#: Client/loader/MainFunctions.cpp:1524 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Uruchomienie moda nie powiodÅ‚o siÄ™. Upewnij siÄ™, że zainstalowano najnowsze pliki danych moda." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1533 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Uruchomienie moda nie powiodÅ‚o siÄ™. Upewnij siÄ™, że %s zostaÅ‚o poprawnie zainstalowane." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1540 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Uruchomienie moda nie powiodÅ‚o siÄ™. Nie znaleziono pliku gta_sa.exe w %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1551 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Uruchomienie moda nie powiodÅ‚o siÄ™. %s istnieje w katalogu z GTA:SA. UsuÅ„ ten plik przed kontynuowaniem." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Plik główny ma nieprawidÅ‚owÄ… nazwÄ™ (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Plik główny jest niepodpisany. Możliwa aktywność wirusa.\n\n" -"Zapoznaj siÄ™ z pomocÄ… on-line jeÅ›li MTA nie dziaÅ‚a poprawnie." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1603 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Brakuje pliku danych %s. Możliwa aktywność wirusa.\n\n" -"Rozważ zainstalowanie Multi Theft Auto na nowo dla Twojego bezpieczeÅ„stwa.\n" -"Sprawdź pomoc online, jeÅ›li MTA nie dziaÅ‚a poprawnie." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "Brak pliku danych %s. Możliwa aktywność wirusa." + +#: Client/loader/MainFunctions.cpp:1610 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Plik danych %s jest zmodyfikowany. Możliwa aktywność wirusa.\n\n" -"Rozważ zainstalowanie Multi Theft Auto na nowo dla Twojego bezpieczeÅ„stwa.\n" -"Sprawdź pomoc online, jeÅ›li MTA nie dziaÅ‚a poprawnie." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "Piliki z rozszerszeniem .asi znajdujÄ… siÄ™ w folderze instalacyjnym 'MTA:SA' lub 'GTA: San Andreas'.\n\n" -"UsuÅ„ pliki z rozszerszeniem .asi, jeÅ›li doÅ›wiadczasz problemów z dziaÅ‚aniem MTA:SA." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "WystÄ…piÅ‚ błąd z rozbieżnoÅ›ciÄ… wersji plików. Przeinstaluj MTA:SA jeÅ›li doÅ›wiadczasz problemów z dziaÅ‚aniem gry.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "Plik danych %s jest zmodyfikowany. Możliwa aktywność wirusa." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Brakuje niektórych plików. Przeinstaluj MTA:SA jeÅ›li doÅ›wiadczasz problemów z dziaÅ‚aniem gry.\n" +#: Client/loader/MainFunctions.cpp:1633 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "Wykryto pliki .asi w katalogu GTA San Andreas lub Multi Theft Auto.\n\n" +"JeÅ›li doÅ›wiadczasz problemów z uruchomieniem lub stabilnoÅ›ciÄ… gry, zalecamy usuniÄ™cie tych plików." -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA nie jest kompatybilne z trybem awaryjnym systemu Windows.\n\n" -"Zrestartuj swój komputer.\n" +#: Client/loader/MainFunctions.cpp:1800 +msgid "Invalid game paths detected." +msgstr "Åšcieżka do GTA San Andreas lub Multi Theft Auto jest nieprawidÅ‚owa." -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1808 msgid "Fix configuration issue" msgstr "Napraw problem z konfiguracjÄ…" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Napraw błąd z uprawnieniami" +#: Client/loader/MainFunctions.cpp:1949 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "Prawdopodobnie GTA San Andreas uruchomiÅ‚o siÄ™ nieprawidÅ‚owo i nie odpowiada. Czy chcesz przerwać uruchamianie?" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Nieznany" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "Plik '%s' jest aktualnie zablokowany przez %zu procesów.\n\n" +"Czy chcesz zakoÅ„czyć powyższe procesy i kontynuować aktualizacjÄ™?\n\n" +"%s" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/Install.cpp:479 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Nie udaÅ‚o siÄ™ uruchomić Grand Theft Auto: San Andreas. Spróbuj uruchomić moda ponownie, lub jeÅ›li problem dalej wystÄ™puje, skontaktuj siÄ™ z nami na www.multitheftauto.com. \n\n" -"[%s]" +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "Twoja instalacja może być uszkodzona.\n\n" +"%zu z %zu plików nie może być przywróconych z kopii zapasowej.\n\n" +"PowinieneÅ› przeinstalować Multi Theft Auto z www.multitheftauto.com lub spróbować uruchomić aktualizacjÄ™ z prawami administratora." + +#: Client/loader/Install.cpp:867 Client/loader/Dialogs.cpp:1081 +msgid "Installing update..." +msgstr "Instalowanie aktualizacji..." + +#: Client/loader/Install.cpp:949 Client/loader/Dialogs.cpp:1089 +msgid "Extracting files..." +msgstr "Wypakowywanie plików..." + +#: Client/loader/CInstallManager.cpp:449 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA nie mogÅ‚o wykonać nastÄ™pujÄ…cej czynnoÅ›ci:\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:518 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Program zawiesiÅ‚ siÄ™ z powodu błędu w sterowniku karty graficznej **\n\n" +"** ProszÄ™ zaktualizować swoje sterowniki do karty graficznej **" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "Gra GTA: San Andreas mogÅ‚a nie uruchomić siÄ™ prawidÅ‚owo. Czy chcesz jÄ… wyłączyć?" +#: Client/loader/CInstallManager.cpp:528 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "**Brak pamiÄ™ci - przyczynÄ… awarii byÅ‚a niewystarczajÄ…ca ilość wolnej lub pofragmentowanej pamiÄ™ci.**" + +#: Client/loader/CInstallManager.cpp:534 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "** Przy nastÄ™pnym uruchomieniu zostanie podjÄ™ta próba zaawansowanej diagnostyki ostatniego crasha. **" + +#: Client/loader/CInstallManager.cpp:1096 +msgid "Install updated MTA:SA files" +msgstr "Zainstaluj zaktualizowane pliki MTA:SA" + +#: Client/loader/CInstallManager.cpp:1116 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Nie udaÅ‚o siÄ™ zaktualizować ze wzglÄ™du na konflikt dostÄ™pu do plików. Zamknij inne aplikacje i spróbuj ponownie" + +#: Client/loader/CInstallManager.cpp:1125 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto nie zostaÅ‚o prawidÅ‚owo zainstalowane, proszÄ™ zainstalować ponownie. %s" + +#: Client/loader/CInstallManager.cpp:1177 +msgid "Create GTA:SA junctions" +msgstr "Utwórz łącze do GTA:SA" + +#: Client/loader/CInstallManager.cpp:1221 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA nie może wystartować, ponieważ kopiowanie pliku nie powiodÅ‚o siÄ™:" + +#: Client/loader/CInstallManager.cpp:1227 +#: Client/loader/CInstallManager.cpp:1267 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA nie może zostać uruchomiony, ponieważ plik MTA:SA jest nieprawidÅ‚owy lub brakuje go:" + +#: Client/loader/CInstallManager.cpp:1236 +msgid "Copy MTA:SA files" +msgstr "Skopiuj pliki MTA:SA" + +#: Client/loader/CInstallManager.cpp:1259 +#: Client/loader/CInstallManager.cpp:1337 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA nie może siÄ™ uruchomić, ponieważ plik GTA:SA jest nieprawidÅ‚owy lub brakuje go:" + +#: Client/loader/CInstallManager.cpp:1344 +msgid "Patch GTA:SA dependency" +msgstr "Wykonaj patch zależnoÅ›ci GTA:SA" + +#: Client/loader/CInstallManager.cpp:1392 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "Nie można uruchomić MTA:SA, ponieważ plik wykonywalny GTA:SA jest nieprawidÅ‚owy lub brakuje go:" + +#: Client/loader/CInstallManager.cpp:1396 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "ProszÄ™ sprawdzić w swoim antywirusie, czy nie wykryÅ‚ faÅ‚szywie, spróbować dodać wyjÄ…tek dla pliku wykonywalnego GTA:SA i zrestartować MTA:SA." + +#: Client/loader/CInstallManager.cpp:1402 +msgid "Generate GTA:SA" +msgstr "Wygeneruj GTA:SA" + +#: Client/loader/CInstallManager.cpp:1417 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA nie może zostać uruchomione, ponieważ plik wykonywalny GTA:SA nie może zostać zaÅ‚adowany:" + +#: Client/loader/CInstallManager.cpp:1424 +#: Client/loader/CInstallManager.cpp:1447 +msgid "Patch GTA:SA" +msgstr "Patch GTA:SA" + +#: Client/loader/CInstallManager.cpp:1440 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA nie może siÄ™ uruchomić, ponieważ Å‚atanie GTA:SA nie powiodÅ‚o siÄ™:" + +#: Client/loader/CInstallManager.cpp:1621 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA nie może kontynuować, ponieważ nie ma wystarczajÄ…cej iloÅ›ci wolnego miejsca na dysku %s." + +#: Client/loader/CInstallManager.cpp:1677 +msgid "Missing file:" +msgstr "Brak pliku:" + +#: Client/loader/CInstallManager.cpp:1681 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "JeÅ›li MTA siÄ™ nie uruchamia, proszÄ™ przeinstalować GTA:SA" + +#: Client/loader/CInstallManager.cpp:1716 +msgid "Update install settings" +msgstr "ZmieÅ„ ustawienia instalacji" + +#: Client/loader/CInstallManager.cpp:1871 +msgid "Update compatibility settings" +msgstr "ZmieÅ„ ustawienia zgodnoÅ›ci" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +487,167 @@ msgstr "Gra GTA: San Andreas mogÅ‚a nie uruchomić siÄ™ prawidÅ‚owo. Czy chcesz #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2115 +#: Client/core/CSettings.cpp:2139 Client/core/CSettings.cpp:5638 +#: Client/core/CSettings.cpp:5712 Client/core/CSettings.cpp:5742 +#: Client/core/CSettings.cpp:5791 Client/core/CSettings.cpp:5853 +#: Client/core/CMainMenu.cpp:1245 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:563 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Tak" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2114 +#: Client/core/CSettings.cpp:2138 Client/core/CSettings.cpp:5637 +#: Client/core/CSettings.cpp:5711 Client/core/CSettings.cpp:5741 +#: Client/core/CSettings.cpp:5790 Client/core/CSettings.cpp:5852 +#: Client/core/CMainMenu.cpp:1244 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:563 msgid "No" msgstr "Nie" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:66 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:559 +#: Client/core/CSettings.cpp:6011 Client/core/CMainMenu.cpp:1265 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "OK" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:67 msgid "Quit" msgstr "ZakoÅ„cz" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:68 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Pomoc" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:69 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:564 Client/core/CSettings.cpp:6010 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Anuluj" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:84 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas napotkaÅ‚o problem" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:85 msgid "Crash information" msgstr "Informacje o zawieszeniu siÄ™ programu" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:86 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Zaznacz to pole aby wysÅ‚ać informacje w trybie online o zawieszeniu siÄ™ programu do deweloperów MTA" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:87 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Wykonanie tej czynnoÅ›ci zwiÄ™kszy szanse na naprawienie tego błędu." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:88 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Czy chcesz uruchomić ponownie MTA: San Andreas?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:95 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Ostrzeżenie" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:96 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "Katalog instalacyjny GTA: San Andreas zawiera nastÄ™pujÄ…ce pliki:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:98 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Pliki te nie sÄ… wymagane i mogÄ… zakłócać dziaÅ‚anie funkcji graficznych w tej wersji MTA.\n\n" "Zaleca siÄ™ usuniÄ™cie lub zmianÄ™ nazwy tych plików." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:100 msgid "Keep these files, but also show this warning on next start" msgstr "Zachowaj te pliki, ale pokaż również to ostrzeżenie przy nastÄ™pnym uruchomieniu" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:101 msgid "Do not remind me about these files again" msgstr "Nie przypominaj mi ponownie o tych plikach" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:102 msgid "Rename these files from *.dll to *.dll.bak" msgstr "ZmieÅ„ nazwy tych plików z *.dll na *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:103 msgid "Show me these files" msgstr "Pokaż mi te pliki" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:104 msgid "Play MTA:SA" msgstr "Uruchom MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:110 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - MylÄ…ce opcje" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:111 msgid "NVidia Optimus detected!" msgstr "Wykryto platformÄ™ NVidia Optimus!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:112 msgid "Try each option and see what works:" msgstr "Wypróbuj każdÄ… opcjÄ™ i zobacz, która z nich dziaÅ‚a najlepiej na Twoim komputerze:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:113 msgid "A - Standard NVidia" msgstr "A - Standardowa NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:114 msgid "B - Alternate NVidia" msgstr "B - Alternatywna NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:115 msgid "C - Standard Intel" msgstr "C - Standardowy Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:116 msgid "D - Alternate Intel" msgstr "D - Alternatywny Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:117 msgid "If you get desperate, this might help:" msgstr "W razie problemów, poniższa opcja może Ci pomóc:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:118 msgid "If you have already selected an option that works, this might help:" msgstr "JeÅ›li wybraÅ‚eÅ› już opcjÄ™ która dziaÅ‚a, to poniższe może pomóc:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:119 msgid "Force windowed mode" msgstr "WymuÅ› tryb okienkowy" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:120 msgid "Don't show again" msgstr "Nie pokazuj wiÄ™cej" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:127 Client/game_sa/CSettingsSA.cpp:911 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:128 msgid "Warning: Could not detect anti-virus product" msgstr "Ostrzeżenie: Nie wykryto oprogramowania antywirusowego" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:130 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1109 +655,1181 @@ msgstr "MTA nie wykryÅ‚o oprogramowania antywirusowego na Twoim komputerze.\n\n" "Wirusy wpÅ‚ywajÄ… na dziaÅ‚anie MTA i zmniejszajÄ… komfort grania.\n\n" "Kliknij 'Pomoc' aby dowiedzieć siÄ™ wiÄ™cej." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:133 msgid "I have already installed an anti-virus" msgstr "Już mam odpowiedni program antywirusowy" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:135 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Nie zainstalujÄ™ programu antywirusowego.\n" "Jestem doÅ›wiadczonym użytkownikiem komputerów i nie straszne mi wirusy!" -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:716 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "Crash, którego doÅ›wiadczyÅ‚eÅ›, wystÄ…piÅ‚ z powodu nieodpowiedniego zarzÄ…dzania pamiÄ™ciÄ… przez serwer, na którym graÅ‚eÅ›.\n\n" +"Bez wzglÄ™du na ilość Twojej pamiÄ™ci RAM, pamięć dla GTA jest ograniczona do maksymalnie 4 GB i wynika to z tego, że GTA:SA jest grÄ… x86. Niektóre serwery z dużą iloÅ›ciÄ… wÅ‚asnych modeli lub nieoptymalnych skryptów może spowodować takie wycieki oraz spadek wydajnoÅ›ci tj. spadek FPS, lub zauważalne lagi.\n\n" +"Skontaktuj siÄ™ z wÅ‚aÅ›cicielem serwera lub wsparciem MTA na oficjalnym serwerze Discord (https://discord.gg/mtasa) w celu uzyskania wiÄ™cej informacji." + +#: Client/loader/Dialogs.cpp:722 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "MTA: San Andreas - Informacja o braku pamiÄ™ci" + +#: Client/loader/Dialogs.cpp:1070 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Wyszukiwanie Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1073 msgid "Please start Grand Theft Auto San Andreas" msgstr "ProszÄ™ włączyć Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Instalowanie aktualizacji..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Połączenie nieudane. Podano nieprawidÅ‚owy nick!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Wypakowywanie plików..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Połączenie nieudane. Podano nieprawidÅ‚owy host!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "KopiujÄ™ pliki..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Połączenie z adresem %s na porcie %u nie powiodÅ‚o siÄ™!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopiowanie zakoÅ„czone przed czasem. Wszystko w porzÄ…dku." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "ÅÄ…czenie z %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "KoÅ„czenie..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "Ponowne łączenie z %s:%u ..." -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Gotowe!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "ÅÄ„CZENIE" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA potrzebuje praw administratora dla nastÄ™pujÄ…cej czynnoÅ›ci:\n\n" -" '%s'\n\n" -"ProszÄ™ je potwierdzić w nastÄ™pnym oknie." +#: Client/core/CConnectManager.cpp:273 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1360 +msgid "Connection timed out" +msgstr "Połączenie przekroczyÅ‚o czas oczekiwania" + +#: Client/core/CConnectManager.cpp:287 Client/core/CConnectManager.cpp:291 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1408 +msgid "Disconnected: unknown protocol error" +msgstr "Rozłączono: Nieznany błąd protokoÅ‚u" -#: Client/loader/CInstallManager.cpp:376 +#: Client/core/CConnectManager.cpp:295 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1412 +msgid "Disconnected: disconnected remotely" +msgstr "Rozłączono: Rozłączono zdalnie" + +#: Client/core/CConnectManager.cpp:299 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1416 +msgid "Disconnected: connection lost remotely" +msgstr "Rozłączono: Utracono połączenie zdalne" + +#: Client/core/CConnectManager.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1420 +msgid "Disconnected: you are banned from this server" +msgstr "Rozłączono: ZostaÅ‚eÅ› zbanowany na tym serwerze" + +#: Client/core/CConnectManager.cpp:310 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1428 +msgid "Disconnected: disconnected from the server" +msgstr "Rozłączono: Rozłączono z serwerem" + +#: Client/core/CConnectManager.cpp:314 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1432 +msgid "Disconnected: connection to the server was lost" +msgstr "Rozłączono: Połączenie z serwerem zostaÅ‚o przerwane" + +#: Client/core/CConnectManager.cpp:321 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1440 +msgid "Disconnected: connection was refused" +msgstr "Rozłączono: połączenie zostaÅ‚o odrzucone" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:416 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA nie mogÅ‚o wykonać nastÄ™pujÄ…cej czynnoÅ›ci:\n\n" -" '%s'\n" +msgid "No such mod installed (%s)" +msgstr "Ten mod nie jest zainstalowany (%s)" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Program zawiesiÅ‚ siÄ™ z powodu błędu w sterowniku karty graficznej **\n\n" -"** ProszÄ™ zaktualizować swoje sterowniki do karty graficznej **" +#: Client/core/CConnectManager.cpp:424 +msgid "Bad server response (2)" +msgstr "NieprawidÅ‚owa odpowiedź serwera (2)" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Zainstaluj zaktualizowane pliki MTA:SA" +#: Client/core/CConnectManager.cpp:434 +msgid "Bad server response (1)" +msgstr "NieprawidÅ‚owa odpowiedź serwera (1)" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Nie udaÅ‚o siÄ™ zaktualizować ze wzglÄ™du na konflikt dostÄ™pu do plików. Zamknij inne aplikacje i spróbuj ponownie" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Polski" + +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "ZajÄ™ty" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Nie można w tej chwili sprawdzić uaktualnieÅ„" + +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto nie zostaÅ‚o prawidÅ‚owo zainstalowane, proszÄ™ zainstalować ponownie. %s" +msgid "MTA:SA %s required" +msgstr "Wymagane MTA:SA %s" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "Utwórz łącze do GTA:SA" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Do połączenia z tym serwerem wymagana jest nowsza wersja MTA:SA - %s.\n\n" +"Czy chcesz Å›ciÄ…gnąć i zainstalować MTA:SA %s ?" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA nie może wystartować, ponieważ kopiowanie pliku nie powiodÅ‚o siÄ™:" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Czy chcesz uruchomić MTA:SA %s aby połączyć siÄ™ z tym serwerem ?" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA nie może zostać uruchomiony, ponieważ plik MTA:SA jest nieprawidÅ‚owy lub brakuje go:" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Nie można siÄ™ połączyć w tej chwili.\n\n" +"Spróbuj ponownie później." -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Skopiuj pliki MTA:SA" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "ÅÄ…czenie" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA nie może siÄ™ uruchomić, ponieważ plik GTA:SA jest nieprawidÅ‚owy lub brakuje go:" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "ProszÄ™ czekać..." -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Wykonaj patch zależnoÅ›ci GTA:SA" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "SPRAWDZANIE" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "Nie można uruchomić MTA:SA, ponieważ plik wykonywalny GTA:SA jest nieprawidÅ‚owy lub brakuje go:" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "AKTUALIZACJA" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "ProszÄ™ sprawdzić w swoim antywirusie, czy nie wykryÅ‚ faÅ‚szywie, spróbować dodać wyjÄ…tek dla pliku wykonywalnego GTA:SA i zrestartować MTA:SA." +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Posiadasz najnowszÄ… wersjÄ™." -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Wygeneruj GTA:SA" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "POBIERANIE" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA nie może zostać uruchomione, ponieważ plik wykonywalny GTA:SA nie może zostać zaÅ‚adowany:" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "oczekiwanie..." -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Patch GTA:SA" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "AKTUALIZACJA KRYTYCZNA" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA nie może siÄ™ uruchomić, ponieważ Å‚atanie GTA:SA nie powiodÅ‚o siÄ™:" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Aby połączyć siÄ™ z tym serwerem, musisz zaktualizować MTA.\n\n" +" Czy chcesz je teraz zaktualizować ?" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA nie może kontynuować, ponieważ nie ma wystarczajÄ…cej iloÅ›ci wolnego miejsca na dysku %s." +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "AKTUALIZACJA OPCJONALNA" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Brak pliku:" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Serwer zaleca zaktualizowanie MTA, ale nie jest to niezbÄ™dne.\n\n" +" Czy chcesz je teraz zaktualizować ?" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "JeÅ›li MTA siÄ™ nie uruchamia, proszÄ™ przeinstalować GTA:SA" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "Aktualizacja jest w tej chwili niedostÄ™pna.\n\n" +"Sprawdź zakÅ‚adkÄ™ \"Download\" na www.multitheftauto.com" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "ZmieÅ„ ustawienia instalacji" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "BÅÄ„D PRZY ZAPISIE" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "ZmieÅ„ ustawienia zgodnoÅ›ci" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Nie udaÅ‚o siÄ™ utworzyć pliku." -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Nieznany" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "BÅÄ„D PRZY POBIERANIU" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "Plik '%s' jest aktualnie zablokowany przez %zu procesów.\n\n" -"Czy chcesz zakoÅ„czyć powyższe procesy i kontynuować aktualizacjÄ™?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Pobrany plik zdaje siÄ™ być nieprawidÅ‚owy." -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "Twoja instalacja może być uszkodzona.\n\n" -"%zu z %zu plików nie może być przywróconych z kopii zapasowej.\n\n" -"PowinieneÅ› przeinstalować Multi Theft Auto z www.multitheftauto.com lub spróbować uruchomić aktualizacjÄ™ z prawami administratora." +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Z jakiegoÅ› powodu." -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Uruchom Grand Theft Auto: San Andreas.\n" -"Gra powinna znajdować siÄ™ w katalogu 'Program Files (x86)'." +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "POBIERANIE UKOŃCZONE" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "Wyszukiwanie GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Nieznany problem w _DialogUpdateResult" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Przepraszamy, nie udaÅ‚o nam siÄ™ znaleźć gry.\n" -"Uruchom Grand Theft Auto: San Andreas i naciÅ›nij 'retry' lub 'ponów'.\n" -"Gra powinna znajdować siÄ™ w katalogu 'Program Files (x86)'." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5739 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "ZMODYFIKOWANE PLIKI GTA:SA" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Wybierz folder z zainstalowanÄ… grÄ… Grand Theft Auto: San Andreas" +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ok" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Błąd przy Å‚adowaniu moduÅ‚u %s! (%s)" +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "BÅÄ„D" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Wykryto nowÄ… instalacjÄ™ %s.\n\n" -"Czy chcesz skopiować swoje ustawienia z %s ?" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Brakuje niektórych plików moda MTA:SA.\n\n\n" +"ProszÄ™ zainstalować ponownie MTA:SA" -#: Client/loader/Utils.cpp:1538 +#: Client/core/CVersionUpdater.cpp:2840 #, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA miaÅ‚o problem z otwarciem pliku '%s'" +msgid "%3d %% completed" +msgstr "%3d %% ukoÅ„czone" -#: Client/loader/Utils.cpp:1560 +#: Client/core/CVersionUpdater.cpp:2843 #, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA nie może otworzyć brakujÄ…cego pliku '%s'." - -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA miaÅ‚o problem z zaÅ‚adowaniem modelu." - -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "JeÅ›li niedawno zmodyfikowaÅ‚eÅ› plik 'gta3.img', spróbuj przeinstalować GTA:SA." +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Oczekiwanie na odpowiedź - %-3d" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA miaÅ‚o problem z dodaniem ulepszenia do pojazdu." +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ POMOC DLA KOMEND ]***\n" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CCommandFuncs.cpp:158 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA znalazÅ‚o błędy w pliku '%s'" - -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Czy Twój komputer zrestartowaÅ‚ siÄ™ podczas gry w MTA:SA?" - -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "ProszÄ™ zakoÅ„czyć pracÄ™ nastÄ™pujÄ…cych programów przed kontynuowaniem:" +msgid "* The time is %d:%02d:%02d" +msgstr "* Bieżący czas to %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Żądania stron WWW" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "connect: Sieć nie jest gotowa, zaczekaj chwilÄ™" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Serwer prosi o zgodÄ™ na dostÄ™p do nastÄ™pujÄ…cych stron WWW w celu ich (późniejszego) zaÅ‚adowania:" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "connect: SkÅ‚adnia komendy to 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NIGDY NIE PRZEKAZUJ SWOICH WRAÅ»LIWYCH DANYCH OSOBOM TRZECIM, ABY ZAPOBIEC ICH KRADZIEÅ»Y" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "connect: NieprawidÅ‚owy port" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "ZapamiÄ™taj ten wybór" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "connect: ÅÄ…czenie z %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Zezwól" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "connect: Nie można połączyć siÄ™ z %s:%u!" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Odmów" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "connect: Nie udaÅ‚o siÄ™ wyłączyć obecnej modyfikacji" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "Menu główne" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "reconnect: Sieć nie jest gotowa, zaczekaj chwilÄ™" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Ta kompilacja zawiera nowÄ…, konkretnÄ… funkcjonalność! Jest to testowa wersja, która nie może być użyta do łączenia z serwerami publicznymi." +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "reconnect: NieprawidÅ‚owy port" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA nie otrzyma aktualizacji dla systemów Windows XP/Vista po lipcu 2019.\n\n" -"Przejdź na nowszy system Windows aby móc grać na najnowszych serwerach." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "reconnect: Ponowne łączenie z %s:%u..." -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Zostaniesz zaraz rozłączony z bieżącym serwerem.\n\n" -"Czy jesteÅ› pewien, że chcesz siÄ™ rozłączyć?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "reconnect: Nie udaÅ‚o siÄ™ połączyć z %s:%u!" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "UWAGA - ROZÅÄ„CZENIE" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Pobrano ustawienia sterowania z GTA" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "INFORMACJA" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Zapisano plik konfiguracyjny" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Polski" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Twój numer seryjny to: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:500 msgid "SETTINGS" msgstr "USTAWIENIA" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:547 msgid "Multiplayer" msgstr "Gra wieloosobowa" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:548 msgid "Video" msgstr "Grafika" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:549 +msgid "PostFX" +msgstr "PostFX" + +#: Client/core/CSettings.cpp:550 msgid "Audio" msgstr "DźwiÄ™k" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:551 msgid "Binds" msgstr "Bindy" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:552 msgid "Controls" msgstr "Sterowanie" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:553 msgid "Interface" msgstr "Interfejs" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:554 msgid "Web Browser" msgstr "PrzeglÄ…darka Internetowa" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:555 msgid "Advanced" msgstr "Zaawansowane" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:580 Client/core/CSettings.cpp:789 +#: Client/core/CSettings.cpp:1121 Client/core/CSettings.cpp:1417 msgid "Load defaults" msgstr "Wczytaj domyÅ›lne" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:597 Client/core/CSettings.cpp:621 msgid "Mouse sensitivity:" msgstr "CzuÅ‚ość myszy:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:597 Client/core/CSettings.cpp:642 msgid "Vertical aim sensitivity:" msgstr "CzuÅ‚ość celowania w pionie:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:600 msgid "Mouse options" msgstr "Opcje myszy" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:607 msgid "Invert mouse vertically" msgstr "ZamieÅ„ osie w pionie" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:611 msgid "Steer with mouse" msgstr "Używaj myszki do kierowania pojazdami" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:615 msgid "Fly with mouse" msgstr "Używaj myszki do sterowania lotem" +#: Client/core/CSettings.cpp:662 +msgid "Use mouse sensitivity for aiming" +msgstr "Użyj czuÅ‚oÅ›ci myszy do celowania" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:668 msgid "Joypad options" msgstr "Opcje gamepada" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:681 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standardowe sterowanie (Mysz + Klawiatura)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:688 msgid "Classic controls (Joypad)" msgstr "Klasyczne sterowanie (Gamepad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:725 msgid "Dead Zone" msgstr "Martwa strefa" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:730 msgid "Saturation" msgstr "Nasycenie" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:736 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Użyj zakÅ‚adki 'Bindy' do przycisków gamepada." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:775 msgid "Left Stick" msgstr "Lewa gaÅ‚ka" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:781 msgid "Right Stick" msgstr "Prawa gaÅ‚ka" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:796 msgid "DESCRIPTION" msgstr "OPIS" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:797 msgid "KEY" msgstr "KLAWISZ" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:799 msgid "ALT. KEY" msgstr "KLAWISZ 2" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:804 Client/core/CSettings.cpp:807 msgid "Nick:" msgstr "Pseudonim:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:829 msgid "Save server passwords" msgstr "Przechowuj hasÅ‚a do serwerów" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:834 msgid "Auto-refresh server browser" msgstr "Automatycznie odÅ›wieżaj przeglÄ…darkÄ™ serwerów" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:839 msgid "Allow screen upload" msgstr "Zezwól na wgrywanie zrzutów ekranu" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:844 msgid "Allow external sounds" msgstr "Zezwalaj na zewnÄ™trzne dźwiÄ™ki" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:849 msgid "Always show download window" msgstr "Zawsze pokazuj okno pobierania" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Zezwól na wyÅ›wietlanie aktywnoÅ›ci Discord" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" -msgstr "" +msgstr "WyÅ›wietlaj status \"w grze GTA:SA\" na Steam" -#. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:867 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "Zapisuj zdjÄ™cia z aparatu do katalogu GTA San Andreas User Files w dokumentach" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:873 msgid "Ask before disconnecting from server using main menu" msgstr "Pytaj o rozłączenie gdy używasz \"Rozłącz\" w menu głównym" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:878 msgid "Use customized GTA:SA files" msgstr "Użyj zmienionych plików GTA:SA" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:883 msgid "Map rendering options" msgstr "Opcje renderowania mapy" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:891 msgid "Opacity:" msgstr "Przezroczystość:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:914 msgid "Image resolution:" msgstr "Rozdzielczość obrazu:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:921 msgid "1024 x 1024 (Default)" msgstr "1024 x 1024 (DomyÅ›lnie)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:922 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:928 Client/core/CSettings.cpp:937 msgid "Master volume:" msgstr "GÅ‚oÅ›ność główna:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:928 Client/core/CSettings.cpp:959 msgid "Radio volume:" msgstr "GÅ‚oÅ›ność stacji radiowych:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:928 Client/core/CSettings.cpp:981 msgid "SFX volume:" msgstr "GÅ‚oÅ›ność dźwiÄ™ków gry:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:928 Client/core/CSettings.cpp:1003 msgid "MTA volume:" msgstr "GÅ‚oÅ›ność dźwiÄ™ków MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1025 msgid "Voice volume:" msgstr "GÅ‚oÅ›ność czata gÅ‚osowego:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1069 msgid "Play mode:" msgstr "Tryb odtwarzania:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:931 Client/core/CSettings.cpp:1549 +#: Client/core/CSettings.cpp:2924 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Ogólne" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1047 msgid "Radio options" msgstr "Opcje radia" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1053 msgid "Radio Equalizer" msgstr "Korektor dla stacji radiowych (Radio Equalizer)" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1058 msgid "Radio Auto-tune" msgstr "Automatyczne strojenie radia (Radio Auto-tune)" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1063 msgid "Usertrack options" msgstr "Opcje odtwarzania wÅ‚asnych utworów muzycznych" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4009 msgid "Radio" msgstr "Stacja radiowa" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1078 Client/core/CSettings.cpp:4011 msgid "Random" msgstr "Losowo" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1079 Client/core/CSettings.cpp:4013 msgid "Sequential" msgstr "Sekwencyjnie" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1082 msgid "Automatic Media Scan" msgstr "Automatyczne skanowanie Å›cieżek" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1089 msgid "Mute options" msgstr "Opcje wyciszenia" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1095 msgid "Mute All sounds when minimized" msgstr "Wycisz wszystkie dźwiÄ™ki gry, gdy zminimalizowane" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1100 msgid "Mute Radio sounds when minimized" msgstr "Wycisz dźwiÄ™ki Radia gdy zminimalizowane" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1105 msgid "Mute SFX sounds when minimized" msgstr "Wycisz dźwiÄ™ki gry gdy zminimalizowane" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1110 msgid "Mute MTA sounds when minimized" msgstr "Wycisz dźwiÄ™ki MTA gdy zminimalizowane" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1115 msgid "Mute Voice sounds when minimized" msgstr "Wycisz gÅ‚os gdy zminimalizowane" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1131 Client/core/CSettings.cpp:1137 msgid "Resolution:" msgstr "Rozdzielczość:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1131 Client/core/CSettings.cpp:1192 msgid "FOV:" msgstr "Pole widzenia (FOV):" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1131 Client/core/CSettings.cpp:1211 msgid "Draw Distance:" msgstr "OdlegÅ‚ość rysowania:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1131 Client/core/CSettings.cpp:1232 +#: Client/core/CSettings.cpp:1432 Client/core/CSettings.cpp:1462 msgid "Brightness:" msgstr "Jasność:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1131 Client/core/CSettings.cpp:1253 msgid "FX Quality:" msgstr "Jakość efektów graficznych:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1132 Client/core/CSettings.cpp:1267 msgid "Anisotropic filtering:" msgstr "Filtrowanie anizotropowe:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1132 Client/core/CSettings.cpp:1304 msgid "Anti-aliasing:" msgstr "WygÅ‚adzanie krawÄ™dzi (AA):" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1132 Client/core/CSettings.cpp:1318 msgid "Aspect Ratio:" msgstr "Proporcje ekranu (AR):" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1149 msgid "Windowed" msgstr "Tryb okienkowy" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1155 msgid "DPI aware" msgstr "Dostosuj do ust. DPI" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2341 msgid "Standard" msgstr "Standardowy" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1174 Client/core/CSettings.cpp:2345 msgid "Borderless keep res" msgstr "Bez ramki (borderless) z tÄ… sama rozdzielczoÅ›ciÄ…" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1177 msgid "Mip Mapping" msgstr "Teksturowanie bitmapami" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1184 +msgid "V-Sync" +msgstr "Synchronizacja pionowa" + +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:2245 msgid "Low" msgstr "Niska" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2247 msgid "Medium" msgstr "Åšrednia" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1263 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4067 msgid "High" msgstr "Wysoka" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1264 Client/core/CSettings.cpp:2251 msgid "Very high" msgstr "Bardzo wysoka" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1281 Client/core/CSettings.cpp:1284 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:1691 +#: Client/core/CSettings.cpp:1745 Client/core/CSettings.cpp:1895 +#: Client/core/CSettings.cpp:2255 Client/core/CSettings.cpp:4074 +#: Client/core/CSettings.cpp:4106 Client/core/CSettings.cpp:4152 +#: Client/core/CSettings.cpp:5383 msgid "Off" msgstr "Wyłączone" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2257 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1314 Client/core/CSettings.cpp:2259 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1315 Client/core/CSettings.cpp:2261 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:2267 Client/core/CSettings.cpp:4076 msgid "Auto" msgstr "Automatyczne" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2269 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1330 Client/core/CSettings.cpp:2271 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1331 Client/core/CSettings.cpp:2273 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1334 msgid "HUD Match Aspect Ratio" msgstr "Dopasuj HUD do proporcji ekranu" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1340 msgid "Volumetric Shadows" msgstr "Cienie objÄ™toÅ›ciowe (Volumetric Shadows)" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1344 msgid "Grass effect" msgstr "Efekty traw (Grass effect)" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1348 msgid "Heat haze" msgstr "MgÅ‚a cieplna (Heat haze)" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1352 msgid "Tyre Smoke etc" msgstr "DymiÄ…ce opony itd." -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1356 msgid "Dynamic ped shadows" msgstr "Dynamiczne cienie postaci" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1360 msgid "Motion blur" msgstr "Rozmycie obrazu w ruchu" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1364 msgid "Corona rain reflections" msgstr "Refleksy koron podczas deszczu" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1369 msgid "Full Screen Minimize" msgstr "Minimalizowanie peÅ‚noekranowe" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1381 msgid "Enable Device Selection Dialog" msgstr "Włącz okno wyboru urzÄ…dzenia" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1393 msgid "Show unsafe resolutions" msgstr "Pokaż niezgodne rozdzielczoÅ›ci" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1405 msgid "Render vehicles always in high detail" msgstr "Renderuj pojazdy zawsze w wysokich detalach" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1409 msgid "Render peds always in high detail" msgstr "Renderuj postacie zawsze w wysokich detalach" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1432 Client/core/CSettings.cpp:1442 +msgid "Gamma:" +msgstr "Gamma:" + +#: Client/core/CSettings.cpp:1432 Client/core/CSettings.cpp:1482 +msgid "Contrast:" +msgstr "Kontrast:" + +#: Client/core/CSettings.cpp:1432 Client/core/CSettings.cpp:1502 +msgid "Saturation:" +msgstr "Nasycenie:" + +#: Client/core/CSettings.cpp:1518 +msgid "Apply adjustments in windowed mode" +msgstr "Zastosuj zmiany w trybie okienkowym" + +#: Client/core/CSettings.cpp:1524 +msgid "Apply adjustments in fullscreen mode" +msgstr "Zastosuj zmiany w trybie peÅ‚noekranowym" + +#: Client/core/CSettings.cpp:1555 msgid "Enable remote websites" msgstr "Zezwalaj na strony zewnÄ™trzne" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1560 msgid "Enable Javascript on remote websites" msgstr "Zezwalaj na Javascript na stronach zewnÄ™tznych" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1565 msgid "Enable GPU rendering" msgstr "Włącz renderowanie z użyciem GPU" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1569 msgid "Custom blacklist" msgstr "Blokuj te strony (blacklist)" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1580 Client/core/CSettings.cpp:1628 msgid "Enter a domain e.g. google.com" msgstr "Wpisz domenÄ™, np. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1588 msgid "Block" msgstr "Blokuj" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1603 Client/core/CSettings.cpp:1649 msgid "Domain" msgstr "Domena" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1605 Client/core/CSettings.cpp:1651 msgid "Remove domain" msgstr "UsuÅ„ domenÄ™" +#: Client/core/CSettings.cpp:1610 Client/core/CSettings.cpp:1656 +msgid "Remove all" +msgstr "UsuÅ„ wszystko" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1617 msgid "Custom whitelist" msgstr "Zezwalaj na te strony (whitelist)" +#: Client/core/CSettings.cpp:1636 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Zezwól" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1670 msgid "Misc" msgstr "Różne" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1676 Client/core/CSettings.cpp:1684 +#: Client/core/CSettings.cpp:6029 msgid "Fast CJ clothes loading:" msgstr "Szybkie Å‚adowanie ubraÅ„ dla CJ:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1676 Client/core/CSettings.cpp:1698 +#: Client/core/CSettings.cpp:6031 msgid "Browser speed:" msgstr "Szybkość skanowania serwerów:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1676 Client/core/CSettings.cpp:1712 +#: Client/core/CSettings.cpp:6033 msgid "Single connection:" msgstr "Pojedyncze połączenie:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1676 Client/core/CSettings.cpp:1725 +#: Client/core/CSettings.cpp:6035 msgid "Packet tag:" msgstr "Znakowanie pakietów:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1677 Client/core/CSettings.cpp:1738 +#: Client/core/CSettings.cpp:6037 msgid "Progress animation:" msgstr "Animowany postÄ™p:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1677 Client/core/CSettings.cpp:1751 +#: Client/core/CSettings.cpp:6027 msgid "Process priority:" msgstr "Priorytet procesu gry:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1677 Client/core/CSettings.cpp:1765 +#: Client/core/CSettings.cpp:6039 msgid "Debug setting:" msgstr "Ustawienia debugowania:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1678 Client/core/CSettings.cpp:1788 +#: Client/core/CSettings.cpp:6041 msgid "Streaming memory:" msgstr "Pamięć dla strumieniowania:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1678 Client/core/CSettings.cpp:1909 msgid "Update build type:" msgstr "Rodzaj wydania:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1678 Client/core/CSettings.cpp:1888 msgid "Install important updates:" msgstr "Instaluj ważne aktualizacje:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1692 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:1733 Client/core/CSettings.cpp:4078 +#: Client/core/CSettings.cpp:4094 Client/core/CSettings.cpp:4101 msgid "On" msgstr "Włączone" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1705 Client/core/CSettings.cpp:4083 msgid "Very slow" msgstr "Bardzo wolna" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1706 Client/core/CSettings.cpp:1719 +#: Client/core/CSettings.cpp:1732 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:1772 Client/core/CSettings.cpp:1784 +#: Client/core/CSettings.cpp:1896 Client/core/CSettings.cpp:1916 +#: Client/core/CSettings.cpp:4085 Client/core/CSettings.cpp:4092 +#: Client/core/CSettings.cpp:4099 Client/core/CSettings.cpp:4108 +#: Client/core/CSettings.cpp:4145 msgid "Default" msgstr "DomyÅ›lne" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1707 Client/core/CSettings.cpp:4087 msgid "Fast" msgstr "Szybka" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1758 Client/core/CSettings.cpp:4063 msgid "Normal" msgstr "Normalny" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1759 Client/core/CSettings.cpp:4065 msgid "Above normal" msgstr "Powyżej normalnego" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1795 msgid "Min" msgstr "Minimum" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1820 msgid "Max" msgstr "Maksimum" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1828 msgid "Windows 8 compatibility:" msgstr "Zgodność z Windows 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1832 msgid "16-bit color" msgstr "Kolor 16-bit" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1837 msgid "Mouse fix" msgstr "Poprawka dla ruchu myszy" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1855 msgid "Client resource files:" msgstr "Pliki zasobów po stronie klienta:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1859 msgid "Show in Explorer" msgstr "Pokaż w Eksploratorze" -#. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1875 msgid "Set CPU 0 affinity to improve game performance" msgstr "Ustaw zalecanÄ… koaligacjÄ™ procesora, aby zwiÄ™kszyć wydajność w grze" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1881 Client/core/CSettings.cpp:1884 msgid "Auto updater" msgstr "Aktualizator" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1922 msgid "Check for update now" msgstr "Sprawdź aktualizacje" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2108 msgid "Some settings will be changed when you next start MTA" msgstr "Niektóre ustawienia zostanÄ… zmienione dopiero po zrestartowaniu MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2109 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Czy chcesz teraz zrestartować MTA?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2112 msgid "RESTART REQUIRED" msgstr "WYMAGANY RESTART" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2132 msgid "Some settings will be changed when you disconnect the current server" msgstr "Niektóre ustawienia zostanÄ… zmienione dopiero gdy rozłączysz siÄ™ z serwerem" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2133 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Czy chcesz teraz rozłączyć siÄ™ z serwerem?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2136 msgid "DISCONNECT REQUIRED" msgstr "WYMAGANE ROZÅÄ„CZENIE Z SERWEREM" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2580 msgid "Joypad not detected - Check connections and restart game" msgstr "Nie wykryto gamepada - Sprawdź, czy jest podłączony do komputera i uruchom grÄ™ ponownie" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2836 msgid "Binding axis" msgstr "Przypisywanie osi" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2836 msgid "Move an axis to bind, or escape to clear" msgstr "Porusz gaÅ‚kÄ… aby przypisać, lub wciÅ›nij klawisz Escape aby wyczyÅ›cić" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2915 msgid "Language:" msgstr "JÄ™zyk:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2915 msgid "Skin:" msgstr "Skórka:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2915 msgid "Presets:" msgstr "Zestaw ustawieÅ„:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2964 msgid "Chat" msgstr "Czat" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2981 msgid "Load" msgstr "Wczytaj" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2993 msgid "Colors" msgstr "Kolory" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2994 msgid "Layout" msgstr "UkÅ‚ad" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2995 Client/core/CSettings.cpp:3241 msgid "Options" msgstr "Opcje" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:3001 msgid "Chat Background" msgstr "TÅ‚o czatu" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:3001 msgid "Chat Text" msgstr "Tekst czatu" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:3001 msgid "Input Background" msgstr "TÅ‚o wpisywania tekstu" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:3001 msgid "Input Text" msgstr "Tekst wejÅ›cia" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3024 msgid "Lines:" msgstr "Wiersze:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3024 msgid "Scale:" msgstr "Skala:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3024 msgid "Width:" msgstr "Szerokość:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3027 msgid "Size" msgstr "Wielkość" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3076 msgid "after" msgstr "po" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3076 msgid "for" msgstr "do" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3076 msgid "sec" msgstr "sek" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3079 msgid "Fading" msgstr "Cieniowanie" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3085 msgid "Fade out old lines" msgstr "Usuwaj stare wiersze" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3125 msgid "Horizontal:" msgstr "Poziomo:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3125 msgid "Vertical:" msgstr "Pionowo:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3125 msgid "Text-Align:" msgstr "Wyrównanie tekstu:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3125 msgid "X-Offset:" msgstr "PrzesuniÄ™cie X:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3126 msgid "Y-Offset:" msgstr "PrzesuniÄ™cie Y:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3132 msgid "Position" msgstr "Pozycja" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3146 Client/core/CSettings.cpp:3174 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "W lewo" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3147 Client/core/CSettings.cpp:3161 msgid "Center" msgstr "Åšrodek" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3148 Client/core/CSettings.cpp:3175 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "W prawo" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3160 msgid "Top" msgstr "Góra" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3162 msgid "Bottom" msgstr "Dół" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3210 msgid "Font" msgstr "Czcionka" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3247 msgid "Hide background when not typing" msgstr "Ukryj tÅ‚o gdy tekst nie jest wpisywany" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3252 msgid "Nickname completion using the \"Tab\" key" msgstr "Auto-uzupeÅ‚nianie nicków klawiszem \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3257 msgid "Allow server to flash the window" msgstr "Pozwól serwerowi migać oknem" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3262 msgid "Allow tray balloon notifications" msgstr "Zezwalaj na powiadomienia w zasobniku systemowym" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3267 msgid "Chat text black/white outline" msgstr "Czarno biaÅ‚y kontur tekstu czatu" @@ -1550,112 +1837,118 @@ msgstr "Czarno biaÅ‚y kontur tekstu czatu" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3516 Client/core/CSettings.cpp:3523 msgid "Press a key to bind, or escape to clear" msgstr "WciÅ›nij przycisk do przypisania, lub wciÅ›nij klawisz Escape aby wyczyÅ›cić" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3517 msgid "Binding a primary key" msgstr "Przypisywanie przycisku podstawowego" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3524 msgid "Binding a secondary key" msgstr "Przypisywanie przycisku pomocniczego" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3600 msgid "GTA GAME CONTROLS" msgstr "STEROWANIE GTASA" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3602 msgid "MULTIPLAYER CONTROLS" msgstr "STEROWANIE MTA" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3847 Client/core/CSettings.cpp:5990 msgid "Your nickname contains invalid characters!" msgstr "Twój nick zawiera nieprawidÅ‚owe znaki!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4449 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:311 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Menu główne" + +#: Client/core/CSettings.cpp:4453 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1117 +#: Client/mods/deathmatch/logic/CResource.cpp:386 msgid "In-game" msgstr "W grze" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4806 msgid "Red:" msgstr "Czerwony:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4806 msgid "Green:" msgstr "Zielony:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4806 msgid "Blue:" msgstr "Niebieski:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4806 msgid "Transparency:" msgstr "Przezroczystość:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4809 msgid "Color" msgstr "Kolor" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4915 msgid "Preview" msgstr "PodglÄ…d" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5223 msgid "Please disconnect before changing language" msgstr "Rozłącz siÄ™ z serwerem przed zmianÄ… jÄ™zyka" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5251 msgid "Please disconnect before changing skin" msgstr "Rozłącz siÄ™ z serwerem przed zmianÄ… skórki" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5631 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Cienie pojemnoÅ›ciowe mogÄ… spowodować wolniejsze dziaÅ‚anie gry.\n\n" "Czy na pewno chcesz je włączyć?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5635 msgid "PERFORMANCE WARNING" msgstr "OSTRZEÅ»ENIE - MOÅ»LIWY SPADEK WYDAJNOÅšCI" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5655 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Wgrywanie zrzutów ekranów jest wymagane przez niektóre serwery na potrzeby funkcji Anti-Cheat.\n\n" "(Okna czata i GUI nie sÄ… umieszczane na zrzutach ekranu)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5657 msgid "SCREEN UPLOAD INFORMATION" msgstr "INFORMACJA - ZRZUTY EKRANU" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5672 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "Niektóre skrypty mogÄ… odtwarzać dźwiÄ™ki (np. radio) przez Internet.\n\n" "Wyłączenie tego ustawienia może zmniejszyć zużycie połączenia sieciowego.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5675 msgid "EXTERNAL SOUNDS" msgstr "ZEWNĘTRZNE DŹWIĘKI" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "WyglÄ…da na to, że masz włączonÄ… opcjÄ™ Discord Rich Presence.\n" -"Czy chcesz pozwolić serwerom na udostÄ™pnianie ich danych?\n\n" -"Dotyczy to również Twojego unikalnego identyfikatora ID." +#: Client/core/CSettings.cpp:5704 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "Status aktywnoÅ›ci jest aktualnie włączony.\n" +"Czy chcesz zezwolić na udostÄ™pnianie danych serwerom, z którymi siÄ™ łączysz?\n\n" +"Dane zawierajÄ… twoje ID konta Discord oraz informacje o stanie gry." -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5709 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "ZGODA NA UDOSTĘPNIANIE DANYCH" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5733 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1665,11 +1958,7 @@ msgstr "Wykryto, że niektóre pliki w Twojej instalacji gry sÄ… zmodyfikowane.\ "PamiÄ™taj jednak, że WIELE SERWERÓW BLOKUJE ZMODYFIKOWANE PLIKI\n\n" "Czy na pewno chcesz z nich korzystać?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "ZMODYFIKOWANE PLIKI GTA:SA" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5782 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1679,552 +1968,253 @@ msgstr "Dostosowywanie do ustawieÅ„ DPI jest eksperymentalnÄ… opcjÄ… i polecamy\ "Możesz doÅ›wiadczyć problemów wizualnych jeÅ›li włączysz to ustawienie.\n\n" "Czy na pewno chcesz włączyć to ustawienie?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5788 Client/core/CSettings.cpp:5843 msgid "EXPERIMENTAL FEATURE" msgstr "OPCJA EKSPERYMENTALNA" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5845 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "Wyłączenie tej opcji jest niezalecane jeÅ›li nie doÅ›wiadczasz problemów z wydajnoÅ›ciÄ… gry.\n\n" "Czy na pewno chcesz wyłączyć tÄ… opcjÄ™?" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6008 msgid "Please enter a nickname" msgstr "Podaj nick" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6009 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Podaj nick, który bÄ™dzie używany w grze. \n" "To bÄ™dzie Twoja nazwa, gdy łączysz siÄ™ z serwerem i w trakcie gry" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6027 msgid "Very experimental feature." msgstr "Ustawienie bardzo eksperymentalne." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6029 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Usuwa przyciÄ™cia przy Å‚adowaniu różnych wariacji ubraÅ„ dla CJ (zużywa o 65MB wiÄ™cej pamiÄ™ci RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6031 msgid "Older routers may require a slower scan speed." msgstr "Starsze routery mogÄ… wymagać wolniejszego ustawienia." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6033 msgid "Switch on to use only one connection when downloading." msgstr "Włącz, aby używać tylko jednego połączenia przy pobieraniu." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6035 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Oznaczaj pakiety aby pomóc dostawcom internetowym identyfikować ruch sieciowy zwiÄ…zany z MTA." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6037 msgid "Spinning circle animation at the bottom of the screen" msgstr "Animacja krÄ™cÄ…cego siÄ™ kółka u doÅ‚u ekranu" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6039 msgid "Select default always. (This setting is not saved)" msgstr "Wybieraj zawsze \"DomyÅ›lne\". (To ustawienie nie jest zapisywane)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6041 msgid "Maximum is usually best" msgstr "Maksimum jest zwykle najlepszym ustawieniem" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6043 Client/core/CSettings.cpp:6045 msgid "Auto updater:" msgstr "Automatyczna aktualizacja:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6043 msgid "Select default unless you like filling out bug reports." msgstr "Wybierz DomyÅ›lne, chyba, że lubisz zgÅ‚aszać błędy programistom." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6045 msgid "Select default to automatically install important updates." msgstr "Wybierz domyÅ›lne aby automatycznie instalować ważne aktualizacje." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6047 msgid "16-bit color:" msgstr "16-bitowy kolor:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6047 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Włącz 16-bitowe tryby kolorów - Wymagany restart MTA" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6049 msgid "Mouse fix:" msgstr "Poprawka dla myszy:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6049 msgid "Mouse movement fix - May need PC restart" msgstr "Popraw ruch myszy - Może wymagać ponownego uruchomienia komputera" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6051 msgid "CPU affinity:" msgstr "Koaligacja procesora:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6051 msgid "Only change if you're having stability issues." msgstr "ZmieÅ„ tylko jeÅ›li masz problemy ze stabilnoÅ›ciÄ… lub wydajnoÅ›ciÄ…." -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Nieznana komenda lub cvar: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "ZajÄ™ty" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Nie można w tej chwili sprawdzić uaktualnieÅ„" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "Wymagane MTA:SA %s" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Do połączenia z tym serwerem wymagana jest nowsza wersja MTA:SA - %s.\n\n" -"Czy chcesz Å›ciÄ…gnąć i zainstalować MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Czy chcesz uruchomić MTA:SA %s aby połączyć siÄ™ z tym serwerem ?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Nie można siÄ™ połączyć w tej chwili.\n\n" -"Spróbuj ponownie później." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "ÅÄ…czenie" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "ProszÄ™ czekać..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "SPRAWDZANIE" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "AKTUALIZACJA" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Posiadasz najnowszÄ… wersjÄ™." - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "POBIERANIE" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "oczekiwanie..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "AKTUALIZACJA KRYTYCZNA" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Aby połączyć siÄ™ z tym serwerem, musisz zaktualizować MTA.\n\n" -" Czy chcesz je teraz zaktualizować ?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "AKTUALIZACJA OPCJONALNA" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Serwer zaleca zaktualizowanie MTA, ale nie jest to niezbÄ™dne.\n\n" -" Czy chcesz je teraz zaktualizować ?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "Aktualizacja jest w tej chwili niedostÄ™pna.\n\n" -"Sprawdź zakÅ‚adkÄ™ \"Download\" na www.multitheftauto.com" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "BÅÄ„D PRZY ZAPISIE" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Nie udaÅ‚o siÄ™ utworzyć pliku." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "BÅÄ„D PRZY POBIERANIU" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Pobrany plik zdaje siÄ™ być nieprawidÅ‚owy." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Z jakiegoÅ› powodu." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "POBIERANIE UKOŃCZONE" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Nieznany problem w _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ok" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "BÅÄ„D" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Brakuje niektórych plików moda MTA:SA.\n\n\n" -"ProszÄ™ zainstalować ponownie MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% ukoÅ„czone" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Oczekiwanie na odpowiedź - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Połączenie nieudane. Podano nieprawidÅ‚owy nick!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Połączenie nieudane. Podano nieprawidÅ‚owy host!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Połączenie z adresem %s na porcie %u nie powiodÅ‚o siÄ™!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "ÅÄ…czenie z %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "Ponowne łączenie z %s:%u ..." - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "ÅÄ„CZENIE" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Połączenie przekroczyÅ‚o czas oczekiwania" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Rozłączono: Nieznany błąd protokoÅ‚u" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Rozłączono: Rozłączono zdalnie" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Rozłączono: Utracono połączenie zdalne" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Rozłączono: ZostaÅ‚eÅ› zbanowany na tym serwerze" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Rozłączono: Rozłączono z serwerem" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Rozłączono: Połączenie z serwerem zostaÅ‚o przerwane" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Rozłączono: połączenie zostaÅ‚o odrzucone" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Ten mod nie jest zainstalowany (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "NieprawidÅ‚owa odpowiedź serwera (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "NieprawidÅ‚owa odpowiedź serwera (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "NOWOÅšCI" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Zobacz najnowsze wiadomoÅ›ci" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONSOLA" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Błąd krytyczny" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "ABY NAPRAWIĆ BÅÄ„D, USUŃ TEN PLIK:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "ModuÅ‚ %s jest nieprawidÅ‚owy!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Błąd podczas wykonywania adresu URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "ten ekran pomocy" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "wyłącza grÄ™" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "pokazuje numer wersji" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "pokazuje bieżący czas" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "pokazuje interfejs użytkownika" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "wyÅ›wietla wszystkie bindy" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "pokazuje Twój numer seryjny" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "łączy z serwerem (host port nick hasÅ‚o)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "łączy z poprzednim serwerem" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "tworzy binda (klawisz komenda/czynność)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "usuwa binda (klawisz)" -#: Client/core/CCore.cpp:1387 -msgid "copies the default gta controls" -msgstr "kopiuje ustawienia sterowania z GTA" - -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "wykonuje zrzut ekranu" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "wykonuje natychmiastowe zapisanie ustawieÅ„" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "czyÅ›ci okienko debugowania" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "przesuwa tekst czatu do góry" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "przesuwa tekst czatu do doÅ‚u" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "przesuwa tekst w okienku debugowania do góry" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "przesuwa tekst w okienku debugowania do doÅ‚u" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "pokazuje statystyki pamiÄ™ci" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "pokazuje wykres czasu klatek" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "Dla deweloperów: przeÅ‚aduj nowoÅ›ci" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ POMOC DLA KOMEND ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Bieżący czas to %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "connect: Sieć nie jest gotowa, zaczekaj chwilÄ™" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "connect: SkÅ‚adnia komendy to 'connect [ ]'" +#: Client/core/CCore.cpp:1490 +msgid "copies the default gta controls" +msgstr "kopiuje ustawienia sterowania z GTA" -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "connect: NieprawidÅ‚owy port" +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "wykonuje zrzut ekranu" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "connect: ÅÄ…czenie z %s:%u..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "wykonuje natychmiastowe zapisanie ustawieÅ„" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "connect: Nie można połączyć siÄ™ z %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "czyÅ›ci okienko debugowania" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "connect: Nie udaÅ‚o siÄ™ wyłączyć obecnej modyfikacji" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "przesuwa tekst czatu do góry" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "reconnect: Sieć nie jest gotowa, zaczekaj chwilÄ™" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "przesuwa tekst czatu do doÅ‚u" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "reconnect: NieprawidÅ‚owy port" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "przesuwa tekst w okienku debugowania do góry" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "reconnect: Ponowne łączenie z %s:%u..." +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "przesuwa tekst w okienku debugowania do doÅ‚u" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "reconnect: Nie udaÅ‚o siÄ™ połączyć z %s:%u!" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "pokazuje statystyki pamiÄ™ci" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Pobrano ustawienia sterowania z GTA" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "pokazuje wykres czasu klatek" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Zapisano plik konfiguracyjny" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "Dla deweloperów: przeÅ‚aduj nowoÅ›ci" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Twój numer seryjny to: %s" +#: Client/core/CMainMenu.cpp:340 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Ta kompilacja zawiera nowÄ…, konkretnÄ… funkcjonalność! Jest to testowa wersja, która nie może być użyta do łączenia z serwerami publicznymi." -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "OÅ› przyspieszenia" +#: Client/core/CMainMenu.cpp:359 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA nie otrzyma aktualizacji dla systemów Windows XP/Vista po lipcu 2019.\n\n" +"Przejdź na nowszy system Windows aby móc grać na najnowszych serwerach." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "OÅ› hamowania" +#: Client/core/CMainMenu.cpp:1238 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Zostaniesz zaraz rozłączony z bieżącym serwerem.\n\n" +"Czy jesteÅ› pewien, że chcesz siÄ™ rozłączyć?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "ProgramiÅ›ci" +#: Client/core/CMainMenu.cpp:1242 +msgid "DISCONNECT WARNING" +msgstr "UWAGA - ROZÅÄ„CZENIE" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Współpracownicy" +#: Client/core/CMainMenu.cpp:1263 +msgid "INFORMATION" +msgstr "INFORMACJA" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Twórcy poziomów i skryptów" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "NOWOÅšCI" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "TÅ‚umacze" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Zobacz najnowsze wiadomoÅ›ci" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Twórcy Å‚atek" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Zrzut ekranu ma %d bajtów, a oczekiwano %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Specjalne podziÄ™kowania dla" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Nie udaÅ‚o siÄ™ wykonać zrzutu ekranu" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "To oprogramowanie i projekt korzystajÄ… z poniższych bibliotek i technologii:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Wykonano zrzut ekranu: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Czy chcesz uzyskać pomoc dla tego problemu w trybie online?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Nieznana komenda lub cvar: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2399,25 +2389,56 @@ msgid "Group control backwards" msgstr "Kieruj grupÄ™ do tyÅ‚u" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Nie udaÅ‚o siÄ™ zaÅ‚adować ustawionej skórki, a skórka domyÅ›lna nie jest dostÄ™pna. ProszÄ™ zainstalować ponownie MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Zrzut ekranu ma %d bajtów, a oczekiwano %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1473 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Czy chcesz uzyskać pomoc dla tego problemu w trybie online?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Nie udaÅ‚o siÄ™ wykonać zrzutu ekranu" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONSOLA" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Wykonano zrzut ekranu: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "ProgramiÅ›ci" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CCredits.cpp:67 +msgid "Contributors" +msgstr "Współpracownicy" + +#: Client/core/CCredits.cpp:86 +msgid "Game Design / Scripting" +msgstr "Twórcy poziomów i skryptów" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "TÅ‚umacze" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Twórcy Å‚atek" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Specjalne podziÄ™kowania dla" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "To oprogramowanie i projekt korzystajÄ… z poniższych bibliotek i technologii:" + +#: Client/core/CJoystickManager.cpp:1584 +msgid "Accelerate Axis" +msgstr "OÅ› przyspieszenia" + +#: Client/core/CJoystickManager.cpp:1586 +msgid "Brake Axis" +msgstr "OÅ› hamowania" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2426,6 +2447,65 @@ msgstr "Nie można zainicjować Direct3D9.\n\n" "najnowszy Dodatek Service Pack dla systemu Windows\n" "zostaÅ‚y zainstalowane poprawnie." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Bezczynny" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3169 +msgid "player" +msgid_plural "players" +msgstr[0] "gracz" +msgstr[1] "graczy" +msgstr[2] "graczy" +msgstr[3] "graczy" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "na" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3175 +msgid "server" +msgid_plural "servers" +msgstr[0] "serwerze" +msgstr[1] "serwerów" +msgstr[2] "serwerów" +msgstr[3] "serwerów" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:307 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Pobieranie listy serwerów (upÅ‚ynęło %lu ms)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:325 +msgid "Master server list could not be parsed." +msgstr "Nie udaÅ‚o siÄ™ odczytać serwerów z głównej listy." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:335 +msgid "Master server list could not be retrieved." +msgstr "Nie udaÅ‚o siÄ™ pozyskać głównej listy serwerów." + +#: Client/core/ServerBrowser/CServerList.cpp:350 +msgid "(Backup server list)" +msgstr "(Zapasowa lista serwerów)" + +#: Client/core/ServerBrowser/CServerList.cpp:420 +msgid "Cannot create LAN-broadcast socket" +msgstr "Nie udaÅ‚o siÄ™ utworzyć socketu LAN" + +#: Client/core/ServerBrowser/CServerList.cpp:430 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Nie można przypisać socketu dla rozgÅ‚aszania w sieci LAN" + +#: Client/core/ServerBrowser/CServerList.cpp:473 +msgid "Attempting to discover LAN servers" +msgstr "Próba odnalezienia serwerów w sieci LAN" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2479,7 +2559,7 @@ msgstr "Ping: " #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Lista graczy" @@ -2506,40 +2586,39 @@ msgstr "Połącz z serwerem jak tylko bÄ™dzie wolny slot." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "PODAJ HASÅO SERWERA" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:477 msgid "Timed Out" msgstr "UpÅ‚ynÄ…Å‚ limit czasu odpowiedzi" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:513 msgid "Querying..." msgstr "Odpytywanie..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "PRZEGLÄ„DARKA SERWERÓW" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Lokalne" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Ulubione" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Ostatnie" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2547,302 +2626,367 @@ msgstr "SZYBKIE POÅÄ„CZENIE:\n\n" "Wpisz adres serwera i port w pasku adresu lub\n" "wybierz serwer z historii serwerów i kliknij 'Połącz'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "POMOC" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "OdÅ›wież" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Dodaj do ulubionych" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Połącz" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Informacje o serwerze" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Wyszukaj serwery" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Wyszukaj graczy" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Rozpocznij wyszukiwanie" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "UsuÅ„ z ostatnio odwiedzonych" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2098 msgid "Search players..." msgstr "Wyszukaj graczy..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2096 msgid "Search servers..." msgstr "Wyszukaj serwery..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Nazwa" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Gracze" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Ping" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Tryb gry" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "UwzglÄ™dnij serwery:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Puste" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "PeÅ‚ne" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Z hasÅ‚em" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "NiedostÄ™pny" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "W innej wersji" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Zamknij" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1733 msgid "Loading..." msgstr "Wczytywanie..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3051 msgid " ..loading.." msgstr " ..wczytywanie.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1616 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1771 msgid "No address specified!" msgstr "Nie podano adresu!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1629 msgid "Unknown protocol" msgstr "Nieznany protokół" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1629 msgid "Please use the mtasa:// protocol!" msgstr "ProszÄ™ użyć protokoÅ‚u mtasa:// !" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1638 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1697 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "NieprawidÅ‚owy nick! Przejdź do UstawieÅ„ i wprowadź inny!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1723 msgid "You have to select a server to connect to." msgstr "Musisz wybrać serwer, z którym chcesz siÄ™ połączyć." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Bezczynny" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2244 +msgid "Problem with graphics driver" +msgstr "Problem ze sterownikiem karty graficznej" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "gracz" -msgstr[1] "graczy" -msgstr[2] "graczy" -msgstr[3] "graczy" +#: Client/game_sa/CSettingsSA.cpp:833 +msgid "Can't find valid screen resolution." +msgstr "Nie można znaleźć prawidÅ‚owej rozdzielczoÅ›ci ekranu." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "na" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:909 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Czy na pewno chcesz użyć tej rozdzielczoÅ›ci ekranu?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "serwerze" -msgstr[1] "serwerów" -msgstr[2] "serwerów" -msgstr[3] "serwerów" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "Nie udaÅ‚o siÄ™ zainicjalizować game_sa" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Pobieranie listy serwerów (upÅ‚ynęło %lu ms)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "Nie udaÅ‚o siÄ™ alokować pamiÄ™ci" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Nie udaÅ‚o siÄ™ odczytać serwerów z głównej listy." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Żądania stron WWW" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Nie udaÅ‚o siÄ™ pozyskać głównej listy serwerów." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Serwer prosi o zgodÄ™ na dostÄ™p do nastÄ™pujÄ…cych stron WWW w celu ich (późniejszego) zaÅ‚adowania:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Zapasowa lista serwerów)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NIGDY NIE PRZEKAZUJ SWOICH WRAÅ»LIWYCH DANYCH OSOBOM TRZECIM, ABY ZAPOBIEC ICH KRADZIEÅ»Y" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Nie można przypisać socketu dla rozgÅ‚aszania w sieci LAN" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "ZapamiÄ™taj ten wybór" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Próba odnalezienia serwerów w sieci LAN" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Odmów" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Ta wersja już wygasÅ‚a." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "disconnect from the game" msgstr "rozłącza z gry" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the nametags" msgstr "pokazuje etykiety z nazwami graczy" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the chatbox" msgstr "pokazuje okienko czatu" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:62 msgid "shows the network statistics" msgstr "pokazuje statystyki sieci" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "open the chat input" msgstr "otwiera okienko do wpisywania na czacie" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "transmits voice to other players" msgstr "przesyÅ‚a gÅ‚os do innych graczy" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "enters a car as passenger" msgstr "wchodzi do pojazdu jako pasażer" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "next radio channel" msgstr "nastÄ™pny kanaÅ‚ radiowy" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "previous radio channel" msgstr "poprzedni kanaÅ‚ radiowy" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "enables the player-map view" msgstr "włącza widok mapy" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map in" msgstr "przybliża widok mapy" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "zooms the player-map out" msgstr "oddala widok mapy" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map north" msgstr "przesuwa mapÄ™ na północ" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map south" msgstr "przesuwa mapÄ™ na poÅ‚udnie" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map east" msgstr "przesuwa mapÄ™ na wschód" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "moves the player-map west" msgstr "przesuwa mapÄ™ na zachód" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "attaches the player-map" msgstr "przyczepia mapÄ™" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "reduces player-map opacity" msgstr "zmniejsza przeźroczystość mapy" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "increases player-map opacity" msgstr "zwiÄ™ksza przeźroczystość mapy" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "toggles player-map help text" msgstr "pokazuje/ukrywa tekst pomocniczy mapy" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "sends a message to the targetted player" msgstr "wysyÅ‚a wiadomość do wybranego gracza" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the next weapon whilst in a vehicle" msgstr "zmienia broÅ„ na nastÄ™pnÄ… w trakcie bycia w pojeździe" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "changes to the previous weapon whilst in a vehicle" msgstr "zmienia broÅ„ na poprzedniÄ… w trakcie bycia w pojeździe" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:84 msgid "outputs info about the current server" msgstr "wyÅ›wietla informacje o aktualnym serwerze" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:87 msgid "defines the scale multiplier of all text-displays" msgstr "ustawia mnożnik skalowania dla wszystkich wyÅ›wietlanych treÅ›ci tekstowych" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) shows the colshapes" msgstr "(Tryb dewelopera) pokazuje colshape'y" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:95 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Tryb dewelopera) wyÅ›wietla identyfikatory dźwiÄ™ków gry w okienku debug" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "UTWÓRZ SERWER" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Zasoby" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Nazwa serwera:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "HasÅ‚o:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Maks. liczba graczy:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "RozgÅ‚aszaj w sieci:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Wybrane" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Wszystkie" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Uruchom" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "ZmieÅ„ tryb: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:81 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "Przybliżenie: %s/%s Ruch: %s, %s, %s, %s Przeźroczystość: %s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "Mapa: %s Tekst pomocniczy: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:713 +msgid "Following Player" +msgstr "Podążanie za graczem" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:715 +msgid "Free Movement" +msgstr "Swobodny ruch" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "PostÄ™p pobierania mapy:" @@ -2863,175 +3007,175 @@ msgstr "%s z %s" msgid "Disconnect to cancel download" msgstr "Rozłącz siÄ™ aby zatrzymać pobieranie" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Rozłączono: NieprawidÅ‚owy nick" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Rozłącz z serwerem" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Rozłączono: Twój numer seryjny jest zablokowany.\n" "Powód: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Rozłączono: ZostaÅ‚eÅ› zbanowany.\n" "Powód: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Rozłączono: To konto jest zablokowane.\n" "Powód: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Rozłączono: Rozbieżność wersji" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Rozłączono: Zbyt duża ilość prób podłączeÅ„.\n\n" "Poczekaj kilka minut i spróbuj ponownie." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Rozłączono: Serwer oparty na innej gałęzi moda.\n" "Informacja: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Rozłączono: NiewÅ‚aÅ›ciwa wersja.\n" "Informacja: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Rozłączono: Serwer dziaÅ‚a w oparciu o nowszÄ… wersjÄ™.\n" "Informacja: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Rozłączono: Serwer dziaÅ‚a w oparciu o starszÄ… wersjÄ™.\n" "Informacja: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Rozłączono: Ten nick jest już w użyciu" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Rozłączono: Nie udaÅ‚o siÄ™ utworzyć obiektu gracza." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Rozłączono: Serwer odrzuciÅ‚ połączenie: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Rozłączono: Nie udaÅ‚o siÄ™ zweryfikować numeru seryjnego" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "Rozłączono: Numer seryjny jest już w użyciu" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Rozłączono: Zdesynchronizowane połączenie %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Rozłączono: ZostaÅ‚eÅ› wyrzucony przez %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Rozłączono: ZostaÅ‚eÅ› zbanowany przez %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Rozłączono: Serwer zostaÅ‚ wyłączony lub zrestartowany." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "ZostaÅ‚eÅ› wyrzucony z gry" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Ten serwer wymaga niezmodyfikowanego pliku gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "ProszÄ™ podmienić gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Ten serwer nie zezwala na używanie niestandardowych plików D3D9.DLL" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "UsuÅ„ plik D3D9.DLL z katalogu instalacyjnego GTA i uruchom ponownie MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Serwer nie zezwala na maszyny wirtualne" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Ten serwer wymaga, aby podpisywanie sterowników byÅ‚o włączone" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Uruchom ponownie komputer" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Serwer wykryÅ‚ braki w komponentach anti-cheat" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Spróbuj zrestartować MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Ten serwer wymaga niezmodyfikowanych plików gta3.img oraz gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "ProszÄ™ podmienić pliki gta3.img lub gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Serwer nie pozwala na emulacjÄ™ przez Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Upewnij siÄ™, że żaden inny program nie modyfikuje MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "PozostaÅ‚y czas: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" @@ -3040,7 +3184,7 @@ msgstr[1] "%d dni" msgstr[2] "%d dni" msgstr[3] "%d dni" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" @@ -3049,7 +3193,7 @@ msgstr[1] "%d godziny" msgstr[2] "%d godzin" msgstr[3] "%d godzin" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" @@ -3058,7 +3202,7 @@ msgstr[1] "%d minut" msgstr[2] "%d minut" msgstr[3] "%d minut" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3068,296 +3212,206 @@ msgstr[2] "%d sekund" msgstr[3] "%d sekund" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Rozłączono" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Błąd pobierania: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "Lata UFO w okolicy" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "Krąży w okolicy" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "PÅ‚ywa w okolicy" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "Jedzie pociÄ…giem w okolicy" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "Lata w okolicy" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "Jeździ w okolicy" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "Jeździ monster truckiem w okolicy" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "Jeździ quadem w okolicy" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "Skacze niczym królik w okolicy" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "Robi dziwne rzeczy w" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "Wspina siÄ™ w okolicy" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "Wykonuje drive-by w" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "Blub blub..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "Oddycha wodÄ…" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "Tonie w" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "Kryje siÄ™ za przeszkodÄ… w" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "Walczy w" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "Walczy wrÄ™cz w" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "Strzela durniów w" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "Strzela" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "Lata jetpackiem w" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "DosÅ‚ownie w ogniu w" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "Pali siÄ™ w" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "PÅ‚ywa w" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "Unosi siÄ™ w okolicy" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "Ucieka przed rekinem" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "Åšmiertelnie siÄ™ dusi w" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "WchodzÄ™ do gry ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Nie połączono; użyj Szybkiego ÅÄ…czenia lub komendy 'connect' aby połączyć siÄ™ z serwerem." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Nie udaÅ‚o siÄ™ uruchomić serwera lokalnego. Sprawdź konsolÄ™ aby uzyskać wiÄ™cej informacji." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1270 msgid "Local Server" msgstr "Serwer lokalny" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Uruchamiam serwer lokalny ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "Strefa 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "Chodzi w okolicy " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1201 #, c-format msgid "You were kicked from the game ( %s )" msgstr "ZostaÅ‚eÅ› wyrzucony z gry ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1270 msgid "Connecting to local server..." msgstr "ÅÄ…czÄ™ siÄ™ z serwerem lokalnym..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1281 msgid "Error connecting to server." msgstr "Błąd podczas łączenia z serwerem." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1291 msgid "Connecting to local server timed out. See console for details." msgstr "UpÅ‚ynÄ…Å‚ limit czasu podczas łączenia siÄ™ z lokalnym serwerem. Sprawdź konsolÄ™ aby dowiedzieć siÄ™ wiÄ™cej." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 msgid "Connection with the server was lost" msgstr "Utracono połączenie z serwerem" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1424 msgid "Disconnected: the server is currently full" msgstr "Rozłączono: serwer jest obecnie peÅ‚ny" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1436 msgid "Disconnected: invalid password specified" msgstr "Rozłączono: podano nieprawidÅ‚owe hasÅ‚o" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1458 msgid "MTA Client verification failed!" msgstr "Błąd! Weryfikacja klienta MTA:SA siÄ™ nie powiodÅ‚a!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5693 msgid "In a ditch" msgstr "W rowie" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5693 msgid "En-route to hospital" msgstr "W drodze do szpitala" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5693 msgid "Meeting their maker" msgstr "Spotyka swojego stworzyciela" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5693 msgid "Regretting their decisions" msgstr "Å»aÅ‚uje swoich decyzji" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5693 msgid "Wasted" msgstr "Zgon" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "UTWÓRZ SERWER" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Zasoby" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Nazwa serwera:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "HasÅ‚o:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Maks. liczba graczy:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "RozgÅ‚aszaj w sieci:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Wybrane" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Wszystkie" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Uruchom" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "ZmieÅ„ tryb: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "Przybliżenie: %s/%s Ruch: %s, %s, %s, %s Przeźroczystość: %s/%s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "Mapa: %s Tekst pomocniczy: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "Podążanie za graczem" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "Swobodny ruch" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problem ze sterownikiem karty graficznej" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Nie można znaleźć prawidÅ‚owej rozdzielczoÅ›ci ekranu." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Czy na pewno chcesz użyć tej rozdzielczoÅ›ci ekranu?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "Nie udaÅ‚o siÄ™ zainicjalizować game_sa" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "Nie udaÅ‚o siÄ™ alokować pamiÄ™ci" +msgid "Download error: %s" +msgstr "Błąd pobierania: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3378,11 +3432,11 @@ msgstr "Błąd protokoÅ‚u (%u). Jesli problem siÄ™ powtarza, sprawdź multitheft msgid "Connection error" msgstr "Błąd połączenia" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Mod Multi Theft Auto nie zostaÅ‚ prawidÅ‚owo zainstalowany - zainstaluj go ponownie." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1487 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Zobaczysz teraz stronÄ™ internetowÄ… z pomocÄ… dla tego problemu.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/pt_BR/client.pot b/Shared/data/MTA San Andreas/MTA/locale/pt_BR/client.pot index 969c59155b0..8b112cc3e29 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/pt_BR/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/pt_BR/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Portuguese, Brazilian\n" "Language: pt_BR\n" @@ -17,72 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Houve um problema ao reiniciar o MTA:SA\n\n" -"Se o problema persistir, abra o Gerenciador de Tarefas e\n" -"pare os processos 'gta_sa.exe' e 'Multi Theft Auto.exe'\n\n\n" -"Tentar iniciar o MTA:SA mais uma vez?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Inicie o Grand Theft Auto: San Andreas.\n" +"Certifique-se de que o jogo se encontra na pasta “Arquivos de Programas (x86)â€." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Erro" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "Procurando pelo GTA: San Andreas" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Outro processo do MTA já está em execução.\n\n" -"Se o problema persistir, por favor reinicie o seu computador" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Desculpa, não conseguimos encontrar o jogo.\n" +"Inicie o Grand Theft Auto: San Andreas e clique em tentar novamente.\n" +"Certifique-se de que o jogo se encontra na pasta “Arquivos de Programas (x86)â€." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Outro processo do MTA já está em execução.\n\n" -"Você deseja encerrá-lo?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Selecione o local de instalação do Grand Theft Auto: San Andreas" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA precisa de acesso do administrador para a seguinte tarefa:\n\n" +" '%s'\n\n" +"Por favor confirme na próxima janela." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Houve um erro ao carregar o módulo %s! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Copiando arquivos..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "O processo de cópia terminou mais cedo. Tudo OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Concluindo..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Pronto!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Nova instalação do %s detectada.\n\n" +"Você deseja copiar suas configurações do %s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA encontrou um problema ao abrir o arquivo '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "O arquivo '%s' está ausente na instalação do GTA:SA." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "O GTA:SA teve um problema em carregar um modelo." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Se você modificou o arquivo gta3.img recentemente, então tente reinstalar o GTA:SA" + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "O GTA:SA teve um problema em adicionar itens de tunagem ao veículo." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "O GTA:SA encontrou erros no arquivo '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "O seu computador reiniciou quando jogava MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Feche os programas a seguir antes de continuar:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Há arquivos incompatíveis com os desta versão. Se ocorrer problemas reinstale o MTA:SA.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Alguns arquivos estão faltando. Reinstale o MTA:SA se acontecer algum problema.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "O MTA:SA não é compatível com o 'Modo Seguro' do Windows.\n\n" +"Por favor, reinicie o seu computador.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Você está tendo problemas ao rodar o MTA:SA?.\n\n" "Você quer voltar a uma versão anterior?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +143,48 @@ msgstr "Parece que houve um problema ao iniciar o MTA:SA.\n" "Redefinir as configurações do GTA pode resolver este problema.\n\n" "Você deseja redefini-las agora?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "As configurações do GTA foram restauradas.\n\n" "Clique OK para continuar." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Arquivo não pode ser deletado: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Você está tendo problemas ao executar o MTA:SA?.\n\n" "Você deseja obter ajuda online?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Está tendo problemas ao executar o MTA:SA?.\n\n" "Deseja mudar a seguinte configuração?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Modo em Tela Cheia:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Janela sem bordas" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Você está tendo problemas ao executar o MTA:SA?.\n\n" "Tente desabilitar os seguintes produtos para o GTA e o MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,300 +192,463 @@ msgstr "ATENÇÃO\n\n" "O MTA:SA detectou atividades suspeitas.\n" "Por gentileza, rode seu antivírus para verificar se seu sistema está seguro.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "O arquivo detectado foi: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Há um processo do GTA: San Andreas em execução. Ele precisa ser encerrado para que o MTA:SA seja iniciado. Você deseja fazer isso agora?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informação" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Não foi possível fechar o GTA: San Andreas. Se o problema persistir, por favor reinicie o seu computador." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Houve um problema ao reiniciar o MTA:SA\n\n" +"Se o problema persistir, abra o Gerenciador de Tarefas e\n" +"pare os processos 'gta_sa.exe' e 'Multi Theft Auto.exe'\n\n\n" +"Tentar iniciar o MTA:SA mais uma vez?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Erro" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Outro processo do MTA já está em execução.\n\n" +"Se o problema persistir, por favor reinicie o seu computador" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Outro processo do MTA já está em execução.\n\n" +"Você deseja encerrá-lo?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Entradas de registro estão faltando. Por favor reinstale o MTA:SA." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "O caminho para a sua instalação do GTA: San Andreas contém caracteres não suportados (unicode). Por favor mova o seu GTA: San Andreas para um caminho compatível que contenha apenas caracteres ASCII padrão e reinstale o MTA:SA." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." msgstr "O caminho para a sua instalação do 'MTA:SA' ou 'GTA: San Andreas'\n" "contém um ';' (Ponto e vírgula).\n\n" " Se você perceber problemas ao rodar o MTA:SA,\n" " mova sua(as) instalação(ões) para um caminho que não contenha um Ponto e vírgula." -#: Client/loader/MainFunctions.cpp:810 +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Não foi possível carregar os arquivos necessários do MTA. Certifique-se que todos eles estão instalados corretamente." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Não foi possível carregar o arquivo %s. Certifique-se que este está instalado corretamente." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Falha ao carregar. Não foi possível localizar o gta_sa.exe em %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Não foi possível carregar o MTA, pois o arquivo %s está na pasta do GTA. Delete-o antes de continuar." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "O arquivo executável está com nome incorreto (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "O executável do GTA:SA apresenta uma assinatura diferente, portanto pode conter um vírus.\n\n" -"Se o MTA não funcionar corretamente, procure por ajuda online." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "O arquivo de dados %s está faltando. Possível atividade de vírus.\n\n" -"Considere reinstalar o Multi Theft Auto para sua segurança.\n" -"Consulte a ajuda online se o MTA não funcionar corretamente." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "O arquivo de dados %s está modificado. Possível atividade de vírus.\n\n" -"Considere reinstalar o Multi Theft Auto para sua segurança.\n" -"Consulte a ajuda online se o MTA não funcionar corretamente." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "Arquivos \".asi foram encontrados no diretório do MTA ou GTA:SA.\n\n" -"Se o MTA não funcionar corretamente, é recomendado removê-los." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Há arquivos incompatíveis com os desta versão. Se ocorrer problemas reinstale o MTA:SA.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Alguns arquivos estão faltando. Reinstale o MTA:SA se acontecer algum problema.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "O MTA:SA não é compatível com o 'Modo Seguro' do Windows.\n\n" -"Por favor, reinicie o seu computador.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Corrigir problema de configuração" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Corrigir erro de elevação necessária" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "GTA: San Andreas may not have launched correctly. Terminate it?" -#: Client/loader/MainFunctions.cpp:1164 -#, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Não foi possível iniciar o GTA: San Andreas. Por favor reinicie seu computador, mas se o problema persistir, entre em contato em www.multitheftauto.com. \n\n" -"[%s]" +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Desconhecido" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas pode não ter sido iniciado corretamente. Você deseja encerrá-lo?" +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "O arquivo '%s' está atualmente bloqueado por %zu processos.\n\n" +"Deseja encerrar os seguintes processos e continuar atualizando?\n\n" +"%s" -#. ///////////////////////////////////////////////////////////////////////// -#. -#. Dialog strings -#. -#. -#. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 -#: Client/gui/CGUIMessageBox_Impl.cpp:72 -msgid "Yes" -msgstr "Sim" +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "Sua instalação pode estar corrompida agora.\n\n" +"%zu de %zu arquivos não puderam ser restaurados do backup.\n\n" +"Você deve reinstalar o Multi Theft Auto a partir de www.multitheftauto.com ou tentar executar a atualização como administrador." -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 -msgid "No" -msgstr "Não" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Instalando atualização..." -#. Create buttons -#. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 -#: Client/gui/CGUIMessageBox_Impl.cpp:64 -msgid "OK" -msgstr "OK" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Extraindo arquivos..." -#: Client/loader/Dialogs.cpp:38 -msgid "Quit" -msgstr "Sair" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "O MTA:SA não pôde completar a seguinte tarefa:\n\n" +" '%s'\n" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 -msgid "Help" -msgstr "Ajuda" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** O travamento foi causado por uma falha no driver de vídeo **\n\n" +"** Atualize o driver da sua placa de vídeo **" -#. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 -#: Client/gui/CGUIMessageBox_Impl.cpp:68 -msgid "Cancel" -msgstr "Cancelar" +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "** Memória insuficiente — esta falha foi causada por memória livre insuficiente ou fragmentada. **" -#: Client/loader/Dialogs.cpp:55 -msgid "MTA: San Andreas has encountered a problem" -msgstr "MTA: San Andreas encontrou um problema" +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" -#: Client/loader/Dialogs.cpp:56 -msgid "Crash information" -msgstr "Informação do erro" +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "A instalação atualizou os arquivos do MTA:SA" -#: Client/loader/Dialogs.cpp:57 -msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" -msgstr "Marque a caixa para enviar as informações deste erro aos desenvolvedores do MTA usando a internet" +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Não foi possível realizar a atualização devido a conflitos entre arquivos. Feche todos os outros programas e tente novamente" -#: Client/loader/Dialogs.cpp:58 -msgid "Doing so will increase the chance of this crash being fixed." -msgstr "Fazendo isso aumentará as chances do erro ser corrigido." +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "O Multi Theft Auto não foi instalado corretamente. Reinstale por favor. %s" -#: Client/loader/Dialogs.cpp:59 -msgid "Do you want to restart MTA: San Andreas ?" -msgstr "Você quer reiniciar o MTA: San Andreas?" +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "Criar junções GTA:SA" -#: Client/loader/Dialogs.cpp:66 -msgid "MTA: San Andreas - Warning" -msgstr "MTA: San Andreas - Aviso" +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "O MTA:SA não pode ser iniciado porque a cópia de um arquivo falhou:" -#: Client/loader/Dialogs.cpp:67 -msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" -msgstr "Seu diretório de instalação do Grand Theft Auto: San Andreas contém estes arquivos:" +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "O MTA:SA não pode ser iniciado porque um arquivo do MTA:SA está incorreto ou ausente:" -#: Client/loader/Dialogs.cpp:69 -msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" -"It is recommended that you remove or rename these files." -msgstr "Esses arquivos não são obrigatórios e podem interferir nos recursos gráficos desta versão do MTA:SA.\n\n" -"É recomendável remover ou renomear esses arquivos." +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Copiar arquivos do MTA:SA" -#: Client/loader/Dialogs.cpp:71 -msgid "Keep these files, but also show this warning on next start" -msgstr "Manter esses arquivos, mas também mostrar este aviso na próxima inicialização" +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "O MTA:SA não pode ser iniciado porque um arquivo do GTA:SA está incorreto ou ausente:" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "Corrigir dependência do GTA:SA" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "O MTA:SA não pode ser iniciado porque o executável do GTA:SA está incorreto ou ausente:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Por favor, verifique se o seu antivírus detectou um falso positivo, tente adicionar uma exceção para o executável do GTA:SA e reinicie o MTA:SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "Gerar GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "O MTA:SA não pode ser iniciado porque o executável do GTA:SA não pode ser carregado:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Corrigir GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "O MTA:SA não pode ser iniciado porque a correção do GTA:SA falhou:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "O MTA:SA não pôde continuar com a instalação porque o disco %s não possui espaço suficiente." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Faltando arquivo:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Se o MTA falhar ao carregar, por favor reinstale o GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Atualizar as configurações de instalação" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Atualizar configurações de compatibilidade" + +#. ///////////////////////////////////////////////////////////////////////// +#. +#. Dialog strings +#. +#. +#. ///////////////////////////////////////////////////////////////////////// +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 +#: Client/gui/CGUIMessageBox_Impl.cpp:72 +msgid "Yes" +msgstr "Sim" + +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 +msgid "No" +msgstr "Não" + +#. Create buttons +#. OK button +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 +#: Client/gui/CGUIMessageBox_Impl.cpp:64 +msgid "OK" +msgstr "OK" + +#: Client/loader/Dialogs.cpp:66 +msgid "Quit" +msgstr "Sair" + +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 +msgid "Help" +msgstr "Ajuda" + +#. Cancel button +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 +#: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +msgid "Cancel" +msgstr "Cancelar" + +#: Client/loader/Dialogs.cpp:83 +msgid "MTA: San Andreas has encountered a problem" +msgstr "MTA: San Andreas encontrou um problema" + +#: Client/loader/Dialogs.cpp:84 +msgid "Crash information" +msgstr "Informação do erro" + +#: Client/loader/Dialogs.cpp:85 +msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" +msgstr "Marque a caixa para enviar as informações deste erro aos desenvolvedores do MTA usando a internet" + +#: Client/loader/Dialogs.cpp:86 +msgid "Doing so will increase the chance of this crash being fixed." +msgstr "Fazendo isso aumentará as chances do erro ser corrigido." + +#: Client/loader/Dialogs.cpp:87 +msgid "Do you want to restart MTA: San Andreas ?" +msgstr "Você quer reiniciar o MTA: San Andreas?" + +#: Client/loader/Dialogs.cpp:94 +msgid "MTA: San Andreas - Warning" +msgstr "MTA: San Andreas - Aviso" + +#: Client/loader/Dialogs.cpp:95 +msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" +msgstr "Seu diretório de instalação do Grand Theft Auto: San Andreas contém estes arquivos:" + +#: Client/loader/Dialogs.cpp:97 +msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" +"It is recommended that you remove or rename these files." +msgstr "Esses arquivos não são obrigatórios e podem interferir nos recursos gráficos desta versão do MTA:SA.\n\n" +"É recomendável remover ou renomear esses arquivos." + +#: Client/loader/Dialogs.cpp:99 +msgid "Keep these files, but also show this warning on next start" +msgstr "Manter esses arquivos, mas também mostrar este aviso na próxima inicialização" + +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Não me avise sobre esses arquivos novamente" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Renomeiar esses arquivos de *.dll para *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Mostre-me esses arquivos" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Jogar MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Opções confusas" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus detectado!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Tente cada opção e veja qual funciona:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - NVidia Padrão" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - NVidia Alternativo" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Intel Padrão" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Intel Alternativo" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Se você ficar desesperado, isto pode ajudar:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Se você já selecionou uma opção que funciona, isso pode ajudar:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Forçar modo janela" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Não mostrar novamente" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Aviso: Não foi possível encontrar um antivírus" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1109 +656,1181 @@ msgstr "O MTA não conseguiu encontrar um antivírus em seu PC.\n\n" "Vírus interferem no MTA e estragam sua jogabilidade\n\n" "Clique em 'Ajuda' para mais informações." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Eu já instalei um antivírus" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Eu não instalarei um antivírus.\n" "Portanto, quero meu PC travando e ser alvo de botnet." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Procurando o local de instalação do Grand Theft Auto: San Andreas..." -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Por favor, inicie o Grand Theft Auto: San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Instalando atualização..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Falha na conexão. Nick inválido!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Extraindo arquivos..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Falha na conexão. IP inválido!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Copiando arquivos..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Falha ao conectar a %s na porta %u!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "O processo de cópia terminou mais cedo. Tudo OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Conectando a %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Concluindo..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "Conectando ao servidor %s:%u ..." -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Pronto!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "CONECTANDO" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA precisa de acesso do administrador para a seguinte tarefa:\n\n" -" '%s'\n\n" -"Por favor confirme na próxima janela." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "O tempo da conexão expirou" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "O MTA:SA não pôde completar a seguinte tarefa:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Desconectado: erro de protocolo desconhecido" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** O travamento foi causado por uma falha no driver de vídeo **\n\n" -"** Atualize o driver da sua placa de vídeo **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Desconectado: desconectado remotamente" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "A instalação atualizou os arquivos do MTA:SA" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Desconectado: conexão foi perdida remotamente" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Não foi possível realizar a atualização devido a conflitos entre arquivos. Feche todos os outros programas e tente novamente" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Desconectado: você está banido desse servidor" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Desconectado: desconectado do servidor" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Desconectado: conexão com o servidor foi perdida" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Desconectado: conexão foi recusada" -#: Client/loader/CInstallManager.cpp:561 +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "O Multi Theft Auto não foi instalado corretamente. Reinstale por favor. %s" +msgid "No such mod installed (%s)" +msgstr "Este mod não está instalado: (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "Criar junções GTA:SA" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Resposta do servidor inválida (2) " -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "O MTA:SA não pode ser iniciado porque a cópia de um arquivo falhou:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Resposta do servidor inválida (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "O MTA:SA não pode ser iniciado porque um arquivo do MTA:SA está incorreto ou ausente:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Português (BR)" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Copiar arquivos do MTA:SA" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Ocupado" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "O MTA:SA não pode ser iniciado porque um arquivo do GTA:SA está incorreto ou ausente:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Não foi possível verificar se há atualizações. Tente mais tarde." -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Corrigir dependência do GTA:SA" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "O MTA:SA %s é necessário para efetuar esta operação" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "O MTA:SA não pode ser iniciado porque o executável do GTA:SA está incorreto ou ausente:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Uma versão mais atual do MTA:SA %s é necessária para entrar no servidor selecionado.\n\n" +"Você quer baixar e instalar o MTA:SA %s ?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Por favor, verifique se o seu antivírus detectou um falso positivo, tente adicionar uma exceção para o executável do GTA:SA e reinicie o MTA:SA." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Você quer iniciar o MTA:SA %s e conectar a esse servidor ?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Gerar GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Não foi possível conectar agora.\n\n" +"Por favor tente mais tarde." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "O MTA:SA não pode ser iniciado porque o executável do GTA:SA não pode ser carregado:" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Conectando" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Corrigir GTA:SA" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Por favor aguarde..." + +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "CHECANDO" + +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "VERIFICANDO ATUALIZAÇÃO" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "O MTA:SA não pode ser iniciado porque a correção do GTA:SA falhou:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Nenhuma atualização disponível" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "O MTA:SA não pôde continuar com a instalação porque o disco %s não possui espaço suficiente." +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "BAIXANDO" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Faltando arquivo:" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "aguardando..." -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Se o MTA falhar ao carregar, por favor reinstale o GTA:SA" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "ATUALIZAÇÃO OBRIGATÓRIA" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Atualizar as configurações de instalação" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Para entrar nesse servidor você precisa atualizar o MTA.\n\n" +" Você quer atualizar agora ?" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Atualizar configurações de compatibilidade" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "ATUALIZAÇÃO OPCIONAL" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Desconhecido" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "O servidor diz que uma atualização é recomendada, mas não essencial.\n\n" +" Você quer atualizar agora ?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "O arquivo '%s' está atualmente bloqueado por %zu processos.\n\n" -"Deseja encerrar os seguintes processos e continuar atualizando?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "Uma atualização não está disponível no momento.\n\n" +"Por favor, olhe www.multitheftauto.com" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "Sua instalação pode estar corrompida agora.\n\n" -"%zu de %zu arquivos não puderam ser restaurados do backup.\n\n" -"Você deve reinstalar o Multi Theft Auto a partir de www.multitheftauto.com ou tentar executar a atualização como administrador." +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "ERRO AO SALVAR" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Inicie o Grand Theft Auto: San Andreas.\n" -"Certifique-se de que o jogo se encontra na pasta “Arquivos de Programas (x86)â€." +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Não foi possível criar o arquivo." -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "Procurando pelo GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "ERRO AO BAIXAR" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Desculpa, não conseguimos encontrar o jogo.\n" -"Inicie o Grand Theft Auto: San Andreas e clique em tentar novamente.\n" -"Certifique-se de que o jogo se encontra na pasta “Arquivos de Programas (x86)â€." +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "O arquivo baixado parece estar incorreto." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Selecione o local de instalação do Grand Theft Auto: San Andreas" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Por alguma razão." -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Houve um erro ao carregar o módulo %s! (%s)" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "DOWNLOAD COMPLETO" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Nova instalação do %s detectada.\n\n" -"Você deseja copiar suas configurações do %s ?" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Problema desconhecido em _DialogUpdateResult" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA encontrou um problema ao abrir o arquivo '%s'" +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "ARQUIVOS MODIFICADOS DO GTA:SA" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "O arquivo '%s' está ausente na instalação do GTA:SA." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ok" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "O GTA:SA teve um problema em carregar um modelo." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "ERRO" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Se você modificou o arquivo gta3.img recentemente, então tente reinstalar o GTA:SA" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Alguns arquivos do MTA:SA estão faltando.\n\n\n" +"Por favor reinstale o MTA:SA" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "O GTA:SA teve um problema em adicionar itens de tunagem ao veículo." +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% completado" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2840 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "O GTA:SA encontrou erros no arquivo '%s'" +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Aguardando resposta - %-3d" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "O seu computador reiniciou quando jogava MTA:SA?" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ COMANDOS DISPONÃVEIS ]***\n" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Feche os programas a seguir antes de continuar:" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* O horário atual é: %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Solicitações de sites" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "conexão: A rede não está pronta, aguarde um momento" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "O servidor solicita os seguintes websites para carregá-los (mais tarde):" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "conectar: A sintaxe correta é 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NUNCA INSIRA DADOS PESSOAIS PARA PROTEGÊ-LOS DE SEREM ROUBADOS" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "conectar: Número da porta inválido" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Lembrar decisão" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "conectar: Conectando ao servidor %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Permitir" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "conectar: não foi possível conectar a %s:%u!" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Negar" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "conectar: Falha ao desativar a modificação atual" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "Tela principal" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "conexão: A rede não está pronta, aguarde um momento" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Você está utilizando uma compilação de teste! Com uma build de teste você não pode se conectar a servidores públicos!" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "conectar: Número da porta inválido" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "O MTA não receberá atualizações no XP/Vista após Julho de 2019.\n\n" -"Atualize o Windows para jogar nos servidores mais recentes." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "reconectando: Reconectando ao servidor %s:%u..." -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Isso o desconectará do servidor atual.\n\n" -"Tem certeza que deseja desconectar?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "reconectando: não foi possível conectar a %s:%u!" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "AVISO DE DESCONEXÃO" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "As configurações de controles do GTA foram importadas" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "INFORMAÇÕES" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Arquivo de configuração salvo" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Português (BR)" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* O seu serial é: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "CONFIGURAÇÕES" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Multijogador" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Vídeo" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "PostFX" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Ãudio" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Teclas" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Controles" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Interface" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Navegador de Internet" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Avançado" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Redefinir as configurações" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Sensibilidade do mouse:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Sensibilidade na mira vertical:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Mouse" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Inverter mouse verticalmente" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Dirigir com o mouse" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Pilotar com o mouse" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Opções do Controle" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Padrão (Mouse + Teclado)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Clássico (Joystick)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Zona Limite" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Saturação" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Use a aba 'Teclas' para configurar os botões do joystick." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Eixo Esquerdo" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Eixo Direito" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "DESCRIÇÃO" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "TECLA" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "TECLA ALT." #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Apelido:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Salvar senha dos servidores" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Atualizar automaticamente o navegador" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Permitir o envio de capturas de tela" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Permitir sons externos" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Sempre mostrar a janela de download" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Permitir conexão com a bio de Atividade do Discord" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" -msgstr "" +msgstr "Permitir o status do jogo GTA:SA na Steam" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "Salva as fotos tiradas pela arma da câmera na pasta GTA San Andreas User Files" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" -msgstr "" +msgstr "Pergunte antes de se desconectar do servidor usando o menu principal" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Usar arquivos modificados do GTA:SA" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Opções de renderização do mapa" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Transparência:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "Resolução de imagem:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "1024 x 1024 (Padrão)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Volume principal:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Volume do rádio:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Volume do ambiente:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "Volume do MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Volume da voz:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Modo de reprodução:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Geral" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Opções da rádio:" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Equalizador do Rádio" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Sintonização automática do Rádio" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Configurações do Tocador do Usuário" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Rádio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Aleatório" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Sequencial" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Verificar automaticamente se há novas músicas" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Opções de volume mudo" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Desativar sons do ambiente ao minimizar" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Silenciar sons do rádio ao minimizar" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Silenciar sons do ambiente ao minimizar" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Silenciar sons do MTA ao minimizar" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Silenciar sons da voz ao minimizar" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Resolução:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Campo de visão:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Distância do horizonte:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Brilho:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Qualidade dos efeitos:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Filtragem anisotrópica:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Anti-serrilhamento:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Proporção de tela:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Modo janela" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "Reconhecimento de DPI" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Normal" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Manter reso. sem borda" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mapeamento Mip" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "Sinc. Vertical" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Baixa" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Média" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Alta" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Muito alta" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Desligado" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Automático" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "Ajustar HUD" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Sombras volumétricas" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Detalhes na grama" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Ondas de calor" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Fumaça dos pneus, etc." -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Sombras dinâmicas do ped" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Desfoque de movimento" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Reflexos de chuva" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Minimizar modo de Tela Cheia" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Este ativa a janela para escolher a placa-de-vídeo" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Mostrar resoluções não seguras" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Renderizar veículos sempre em alto detalhe" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Renderizar peds sempre em alto detalhe" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Habilitar websites remotos" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Permitir o uso de Javascript em websites remotos" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "Renderizar com GPU" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Lista negra" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Digite um domínio ex. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Bloquear" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Domínio" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Remover domínio" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Whitelist personalizada" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Permitir" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Configurações avançadas" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Carregamento rápido das roupas do CJ:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Velocidade do Navegador:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Conexão unitária:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Tag do pacote:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Animação do progresso:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Prioridade do processo:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Tipo de Depuração:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Memória para Streaming:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Tipo de atualização:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Instalar atualizações importantes:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Ligado" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Bem lento" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Padrão" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Rápido" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normal" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Acima do normal" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Mín" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Máx" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Compatibilidade com Windows 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "Cor 16-bit" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Correção do mouse" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Arquivos de recursos do cliente:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Mostrar no Explorer" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "Define a afinidade da CPU 0 para melhorar o desempenho do jogo" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Atualização automática" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Procurar por atualizações" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Algumas alterações serão aplicadas na próxima vez que o MTA for iniciado" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Você deseja reiniciá-lo agora?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "É NECESSÃRIO REINICIAR O MTA" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Algumas configurações serão alteradas quando você se desconectar do servidor atual" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Deseja se desconectar agora?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "DESCONEXÃO NECESSÃRIA" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "O controle não foi encontrado - Verifique as entradas do computador e reinicie o jogo" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Vinculando o analog" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Mova o analog para vinculá-lo ou pressione Esc para limpar o campo" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Idioma:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Tema:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Tema:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Bate-papo" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Carregar" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Cores" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Layout" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Opções" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Fundo do Bate-papo" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Texto" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Fundo da Entrada" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Texto de Entrada" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Linhas:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Escala:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Largura:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Tamanho" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "depois de" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "por" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "seg" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Desaparecimento" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Ocultar linhas antigas" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horizontal:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Vertical:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Alinhamento do texto:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "Offset-X:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Offset-Y:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Posição" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Esquerda" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Centro" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Direita" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Topo" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Inferior" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Fonte" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Esconder o fundo enquanto não estiver digitando" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Completar apelido de jogadores usando a tecla \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Permitir que o servidor pisque a janela" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Permitir notificações do balão da bandeja" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Borda preto/branca do texto do chat" @@ -1550,89 +1838,95 @@ msgstr "Borda preto/branca do texto do chat" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Pressione uma tecla para definir o controle ou tecle Esc para limpar o campo" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Definindo a tecla primária" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Definindo a tecla secundária" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "CONTROLES DO GTA" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "CONTROLES DO MTA" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "O seu apelido contém caracteres inválidos!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Tela principal" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "No jogo" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Vermelho:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Verde:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Azul:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Transparência:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Cor" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Prévia" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Por favor desconecte antes de mudar o idioma" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Por favor desconecte antes de mudar de tema" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Sombras volumétricas podem causar perda de performance.\n\n" "Você tem certeza que deseja ativar?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "ATENÇÃO: SUA PERFORMANCE ESTà MUITO BAIXA" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Habilitar o envio de capturas de tela é requisitado por alguns servidores em razão de prevenir trapaças durante as partidas.\n\n" "(Lembrando que o chat e o GUI (janelas do MTA) não são incluídos na captura de tela)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "INFORMAÇÃO SOBRE O ENVIO DE CAPTURAS DE TELA" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1640,37 +1934,31 @@ msgstr "Alguns scripts podem reproduzir sons, como rádio, da internet.\n\n" "Desabilitando esta configuração pode diminuir o\n" "consumo de uso de rede.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "SONS EXTERNOS" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "Você tem a opção de conexão \"Rich Presence\" ativada.\n" -"Quer permitir que os servidores mostrem seus dados?\n" -"Isso inclui o seu identificador de ID exclusivo." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "CONSENTIMENTO PARA PERMITIR O COMPARTILHAMENTO DE DADOS" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" "Are you sure you want to use them?" msgstr "Alguns arquivos da pasta do GTA:SA estão modificados.\n" "O MTA só irá ler-los se este item estiver marcado.\n\n" -"Entretanto, ESSA PRÃTICA NÃO É AUTORIZADA POR MUITOS SERVIDORES\n\n" -"Você tem certeza que deseja mantê-los?" - -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "ARQUIVOS MODIFICADOS DO GTA:SA" +"Entretanto, ESSA PRÃTICA NÃO É AUTORIZADA POR MUITOS SERVIDORES\n\n" +"Você tem certeza que deseja mantê-los?" -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1681,551 +1969,253 @@ msgstr "O reconhecimento de DPI é um recurso experimental e\n" "Você pode enfrentar problemas gráficos se ativar esta opção.\n\n" "Tem certeza de que deseja ativar esta opção?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "RECURSO EXPERIMENTAL" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" -msgstr "" +msgstr "Não é recomendável desativar esta opção, a menos que você esteja enfrentando problemas de desempenho.\n\n" +"Tem certeza de que deseja desativá-la?" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Por favor coloque um apelido" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Por favor coloque um apelido para ser usado durante o jogo. \n" "Ele vai ser o seu nome quando você conectar e jogar em um servidor" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Opção em fase bem experimental" -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Otimiza o carregamento dos acessórios do CJ (Este utiliza 65MB de RAM adicionais)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Roteadores mais antigos podem requisitar uma velocidade menor." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Habilite este item para usar somente uma conexão quando estiver fazendo download" -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Marca os pacotes de rede para ajudar os provedores identificar o tráfego do MTA." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Animação de círculo girando na parte inferior da tela" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Lembrando que essa opção não será salva na próxima inicialização" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "É recomendado que esse permaneça no máximo" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Atualização automática:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "O recomendado é deixar este item como 'padrão', a menos que você curta enfrentar bugs nas versões de teste." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Selecione padrão para instalar automaticamente atualizações importantes." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "Cor 16-bit:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Habilitar cor 16-bit (É necessário reiniciar o MTA)" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Correção do mouse:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Correção dos movimentos do mouse (Talvez seja necessário reiniciar o PC)" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "Afinidade de CPU:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." -msgstr "" - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Comando ou cvar desconhecido: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Ocupado" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Não foi possível verificar se há atualizações. Tente mais tarde." - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "O MTA:SA %s é necessário para efetuar esta operação" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Uma versão mais atual do MTA:SA %s é necessária para entrar no servidor selecionado.\n\n" -"Você quer baixar e instalar o MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Você quer iniciar o MTA:SA %s e conectar a esse servidor ?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Não foi possível conectar agora.\n\n" -"Por favor tente mais tarde." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Conectando" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Por favor aguarde..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "CHECANDO" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "VERIFICANDO ATUALIZAÇÃO" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Nenhuma atualização disponível" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "BAIXANDO" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "aguardando..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "ATUALIZAÇÃO OBRIGATÓRIA" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Para entrar nesse servidor você precisa atualizar o MTA.\n\n" -" Você quer atualizar agora ?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "ATUALIZAÇÃO OPCIONAL" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "O servidor diz que uma atualização é recomendada, mas não essencial.\n\n" -" Você quer atualizar agora ?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "Uma atualização não está disponível no momento.\n\n" -"Por favor, olhe www.multitheftauto.com" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "ERRO AO SALVAR" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Não foi possível criar o arquivo." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "ERRO AO BAIXAR" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "O arquivo baixado parece estar incorreto." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Por alguma razão." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "DOWNLOAD COMPLETO" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Problema desconhecido em _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ok" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "ERRO" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Alguns arquivos do MTA:SA estão faltando.\n\n\n" -"Por favor reinstale o MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% completado" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Aguardando resposta - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Falha na conexão. Nick inválido!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Falha na conexão. IP inválido!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Falha ao conectar a %s na porta %u!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Conectando a %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "Conectando ao servidor %s:%u ..." - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "CONECTANDO" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "O tempo da conexão expirou" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Desconectado: erro de protocolo desconhecido" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Desconectado: desconectado remotamente" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Desconectado: conexão foi perdida remotamente" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Desconectado: você está banido desse servidor" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Desconectado: desconectado do servidor" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Desconectado: conexão com o servidor foi perdida" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Desconectado: conexão foi recusada" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Este mod não está instalado: (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Resposta do servidor inválida (2) " - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Resposta do servidor inválida (1)" +msgstr "Mude apenas se estiver enfrentando problemas de estabilidade." -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "NOTÃCIAS" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Ver as últimas notícias" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "CONSOLE" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Erro fatal" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "PARA CORRIGIR, REMOVA ESTE ARQUIVO:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "O módulo %s está incorreto!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Erro ao abrir a URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "mostra esta mensagem de ajuda" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "fecha a aplicação" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "mostra a versão" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "mostra o horário" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "mostra o hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "mostra todos os comandos vinculados" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "mostra o seu serial" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "conecta a um servidor (IP porta nick senha)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "conecta ao servidor anterior" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "define um comando a partir de uma tecla" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "desfaz um comando vinculado a uma tecla" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "copia os comandos padrões do GTA" -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "salva uma captura da tela" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "salva as configurações imediatamente" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "limpa o espaço de debug" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "rola o chat para cima" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "rola o chat para baixo" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "rola o painel de depuração para cima" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "rola o painel de depuração para baixo" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "mostra as estatísticas de memória" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "mostra um gráfico dos quadros renderizados em relação ao tempo" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "para desenvolvedores: recarregar notícias" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ COMANDOS DISPONÃVEIS ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* O horário atual é: %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "conexão: A rede não está pronta, aguarde um momento" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "conectar: A sintaxe correta é 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "conectar: Número da porta inválido" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "conectar: Conectando ao servidor %s:%u..." +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "salva uma captura da tela" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "conectar: não foi possível conectar a %s:%u!" +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "salva as configurações imediatamente" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "conectar: Falha ao desativar a modificação atual" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "limpa o espaço de debug" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "conexão: A rede não está pronta, aguarde um momento" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "rola o chat para cima" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "conectar: Número da porta inválido" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "rola o chat para baixo" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "reconectando: Reconectando ao servidor %s:%u..." +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "rola o painel de depuração para cima" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "reconectando: não foi possível conectar a %s:%u!" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "rola o painel de depuração para baixo" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "As configurações de controles do GTA foram importadas" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "mostra as estatísticas de memória" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Arquivo de configuração salvo" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "mostra um gráfico dos quadros renderizados em relação ao tempo" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* O seu serial é: %s" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "para desenvolvedores: recarregar notícias" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Eixo de Aceleração" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Você está utilizando uma compilação de teste! Com uma build de teste você não pode se conectar a servidores públicos!" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Eixo de Freio" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "O MTA não receberá atualizações no XP/Vista após Julho de 2019.\n\n" +"Atualize o Windows para jogar nos servidores mais recentes." -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programação" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Isso o desconectará do servidor atual.\n\n" +"Tem certeza que deseja desconectar?" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Colaboradores" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "AVISO DE DESCONEXÃO" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Design / Scripting do Jogo" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "INFORMAÇÕES" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Tradutores" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "NOTÃCIAS" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Contribuidores de Patch" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Ver as últimas notícias" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Agradecimentos especiais" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "A captura de tela gerou %d bytes de dados, mas o esperado era %d" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Este software e projeto utiliza as seguintes bibliotecas e software:" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Falha ao gerar a captura de tela" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Deseja obter ajuda online sobre este problema?" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Captura de tela pronta: '%s'" + +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Comando ou cvar desconhecido: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2400,25 +2390,56 @@ msgid "Group control backwards" msgstr "Ordenar ao grupo para recuar" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "O tema que você selecionou, inclusive o padrão, não puderam ser carregados. Por favor, reinstale o MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "A captura de tela gerou %d bytes de dados, mas o esperado era %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Deseja obter ajuda online sobre este problema?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Falha ao gerar a captura de tela" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "CONSOLE" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Captura de tela pronta: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programação" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Colaboradores" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Design / Scripting do Jogo" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Tradutores" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Contribuidores de Patch" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Agradecimentos especiais" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Este software e projeto utiliza as seguintes bibliotecas e software:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Eixo de Aceleração" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Eixo de Freio" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2426,6 +2447,61 @@ msgstr "Não foi possível iniciar o Direct3D9.\n\n" "Certifique-se que o \"DirectX End-User Runtime\" e\n" "os últimos \"Service Packs\" do Windows estejam corretamente instalados." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Inativo" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "jogador" +msgstr[1] "jogadores" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "em" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "servidor" +msgstr[1] "servidores" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Esperando fazer o download da lista dos servidores... (Já se passaram %lu ms)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "A lista de servidores não pôde ser processada." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "A lista de servidores não pôde ser obtida." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Fazendo um backup da lista de servidores)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Não foi possível se conectar ao soquete da 'LAN-broadcast'" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Procurando servidores locais..." + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2479,7 +2555,7 @@ msgstr "Latência:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Lista de jogadores" @@ -2506,40 +2582,39 @@ msgstr "Entrar no servidor quando um jogador desconectar." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "POR FAVOR DIGITE A SENHA DO SERVIDOR" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "O tempo de conexão expirou" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Consultando..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "SERVIDORES" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Local" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Favoritos" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Recentes" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2547,298 +2622,367 @@ msgstr "PARA SE CONECTAR RAPIDAMENTE:\n\n" "Digite o endereço e a porta na barra de endereço.\n" "Ou selecione um servidor na aba Recentes e clique em 'Conectar'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "AJUDA" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Atualizar" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Adicionar aos favoritos" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Conectar" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Informações do servidor" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Procurar servidores" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Procurar jogadores" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Iniciar procura" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "Apagar dos recentes" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Procurar jogadores..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Procurar servidores..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Nome" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Jogadores" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Latência" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Modo de jogo" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Incluir:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Vazio" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Cheio" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Com senha" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Offline" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Outras versões" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Voltar" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Carregando..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..carregando.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "O endereço não foi preenchido!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Protocolo desconhecido" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Você esqueceu de usar o prefixo mtasa:// antes do IP!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Apelido inválido! Por favor, entre nas Configurações e mude-o." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Você deve selecionar um servidor para se conectar." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Inativo" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problema com o driver de gráficos" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "jogador" -msgstr[1] "jogadores" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Não foi possível encontrar uma resolução válida." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "em" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Você tem certeza que deseja usar essa resolução?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "servidor" -msgstr[1] "servidores" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "Falha na inicialização do game_sa" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Esperando fazer o download da lista dos servidores... (Já se passaram %lu ms)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "Alocação de memória falhou" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "A lista de servidores não pôde ser processada." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Solicitações de sites" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "A lista de servidores não pôde ser obtida." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "O servidor solicita os seguintes websites para carregá-los (mais tarde):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Fazendo um backup da lista de servidores)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NUNCA INSIRA DADOS PESSOAIS PARA PROTEGÊ-LOS DE SEREM ROUBADOS" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Não foi possível se conectar ao soquete da 'LAN-broadcast'" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Lembrar decisão" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Procurando servidores locais..." +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Negar" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Esta versão expirou." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "desconecta do jogo" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "mostra os 'nametags'" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "mostra o chat" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "mostra as estatísticas de internet" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "abre o campo para escrever no chat" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "transmite a voz para outros jogadores" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "entra em um carro como passageiro" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "próxima estação de rádio" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "estação de rádio anterior" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "habilita a visualização de mapa do jogador" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "aumenta o zoom do mapa do jogador" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "reduz o zoom do mapa do jogador" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "move o mapa do jogador para o norte" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "move o mapa do jogador para o sul" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "move o mapa do jogador para o leste" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "move o mapa do jogador para oeste" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "anexa o mapa do jogador" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "reduz a opacidade do mapa do jogador" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "aumenta a opacidade do mapa do jogador" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "alternar texto de ajuda do mapa do jogador" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "envia uma mensagem a um jogador específico" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "próxima arma (veículo)" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "arma anterior (veículo)" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "mostra informações sobre o servidor" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "define a escala de todos os textos a serem mostrados na tela" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Modo de desenvolvimento) mostra os colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Modo de desenvolvimento) mostra o ID dos sons do ambiente no painel de depuração" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "CRIAR UM SERVIDOR" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Recursos" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Nome do servidor:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Senha:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Capacidade máxima:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Transmissão:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Selecionado" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Todos" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Iniciar" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "Mudar modo: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "Ampliação: %s/%s Movimento: %s, %s, %s, %s Opacidade: %s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "Alternar mapa: %s Alternar texto de ajuda: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "Seguindo o jogador" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "Livre Circulação" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Progresso do download do mapa:" @@ -2859,195 +3003,195 @@ msgstr "%s de %s" msgid "Disconnect to cancel download" msgstr "Desconecte para cancelar o download" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Desconectado: Apelido inválido" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Desconectado do servidor" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Desconectado: Serial está banido.\n" "Motivo: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Desconectado: Você está banido.\n" "Motivo: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Desconectado: Conta banida.\n" "Motivo: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Desconectado: Incompatibilidade de versão" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Você foi desconectado, pois detectamos que você está reentrando no jogo diversas vezes. Por favor, espere um minuto e tente novamente." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Desconectado: O servidor pertence a um branch diferente.\n" "Detalhes: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Desconectado: Versão inválida.\n" "Detalhes: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Desconectado: O servidor está rodando uma versão mais recente.\n" "Detalhes: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Desconectado: O servidor está rodando uma versão mais antiga.\n" "Detalhes: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Desconectado: O seu apelido já está em uso" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Desconectado: O jogador não pôde ser criado." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Desconectado: O servidor recusou a conexão: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Desconectado: Falha ao verificar o serial" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "Desconectado: Seu serial esta em uso" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Desconectado: A conexão dessincronizou %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Desconectado: Você foi expulso do servidor por %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Desconectado: Você foi banido do servidor por %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Desconectado: O servidor desligou ou está reiniciando" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Você foi expulso do jogo" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Este servidor requer um gta_sa.exe sem modificação" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Por favor substitua o gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Este servidor não aceita D3D9.DLLs modificados" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Remova o D3D9.DLL da pasta de instalação do GTA e reinicie o MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Este servidor não aceita máquinas virtuais" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Este servidor requer que a assinatura de driver esteja ativada" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Por favor reinicie o seu PC" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Este servidor detectou a falta de componentes do anti-cheat" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Tente reiniciar o MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Este servidor requer um gta3.img e gta_int.img sem modificação" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Por favor substitua o gta3.img ou gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Este servidor não aceita o Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Certifique-se de que nenhum outro programa esteja modificando o MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Tempo restante: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d dia" msgstr[1] "%d dias" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d hora" msgstr[1] "%d horas" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d minuto" msgstr[1] "%d minutos" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3055,296 +3199,206 @@ msgstr[0] "%d segundo" msgstr[1] "%d segundos" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Desconectado" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Erro de download: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "Voando em um OVNI" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "Passeando por aí" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "Pegando as ondas de" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "Andando de trem em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "Voando por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "Andando por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "Andando de caminhão monstro por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "Rolê por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "Pulando por aí" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "Fazendo esquisitice em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "Escalando por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "Atirando de um veículo em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "Blá Blá..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "Respirando água" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "Se afogando em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "Agachado para cobertura em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "Brigando em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "Trocando soco em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "Deitando tanso em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "Atirando" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "Voando de mochila a jato em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "Literalmente pegando fogo em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "Se queimando em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "Nadando em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "Flutuando por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "Sendo perseguido por um tubarão" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "Sufocando até a morte em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Entrando no jogo ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Não foi possível conectar. Use a opção Conexão Rápida ou o comando 'connect' para se conectar a um servidor." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Não foi possível iniciar o servidor local. Verifique o console para mais informações." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Servidor Local" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Iniciando servidor local ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "Ãrea 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "Andando por" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Você foi expulso do jogo ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Conectando ao servidor local..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Erro ao conectar ao servidor." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Conexão ao servidor local expirou. Veja o console para mais detalhes." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "A conexão com o servidor foi perdida" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Desconectado: o servidor está cheio" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Desconectado: senha inválida" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "Verificação ao cliente do MTA falhou!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "Ta na vala" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "Indo para o hospital" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "Se encontrando com seu criador" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "Arrependendo de suas decisões" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "Morreu" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "CRIAR UM SERVIDOR" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Recursos" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Nome do servidor:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Senha:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Capacidade máxima:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Transmissão:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Selecionado" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Todos" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Iniciar" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "Mudar modo: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "Ampliação: %s/%s Movimento: %s, %s, %s, %s Opacidade: %s/%s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "Alternar mapa: %s Alternar texto de ajuda: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "Seguindo o jogador" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "Livre Circulação" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problema com o driver de gráficos" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Não foi possível encontrar uma resolução válida." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Você tem certeza que deseja usar essa resolução?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "Falha na inicialização do game_sa" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "Alocação de memória falhou" +msgid "Download error: %s" +msgstr "Erro de download: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3365,11 +3419,11 @@ msgstr "Houve um erro de protocolo (%u). Se este problema persistir, visite o mu msgid "Connection error" msgstr "Erro de conexão" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "O Multi Theft Auto não foi instalado corretamente, por favor reinstale." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Seu navegador agora exibirá uma página da web com algumas informações de ajuda.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/pt_PT/client.pot b/Shared/data/MTA San Andreas/MTA/locale/pt_PT/client.pot index cfa139c9d1e..d91a67ae84c 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/pt_PT/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/pt_PT/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Portuguese\n" "Language: pt_PT\n" @@ -17,71 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Erro ao reiniciar o MTA:SA\n\n" -"Se o problema persistir, abra o Gestor de Tarefas e\n" -"pare os processos 'gta_sa.exe' e 'Multi Theft Auto.exe'" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Inicie o Grand Theft Auto: San Andreas\n" +"Certifique-se de que o jogo está na pasta 'Program Files (x86)'." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Erro" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "À procura do GTA: San Andreas" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Outra instância do MTA já está a correr.\n\n" -"Se o problema persistir, reinicie o seu PC" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Infelizmente o jogo não foi encontrado.\n" +"Inicie o Grand Theft Auto: San Andreas e clique em tentar novamente.\n" +"Certifique-se de que o jogo está na pasta 'Program Files (x86)'." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Outra instância do MTA já está a correr.\n\n" -"Deseja fechá-la?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Selecione a pasta de instalação do Grand Theft Auto: San Andreas" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA precisa de acesso de administrador para a seguinte tarefa:\n\n" +" '%s'\n\n" +"Por favor, confirme na próxima janela." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Erro ao carregar o módulo %s! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "A copiar ficheiros..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Cópia acabou mais cedo. Está tudo OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "A finalizar..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Pronto!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Nova instalação de %s detetada.\n\n" +"Deseja copiar as suas definições de %s?" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA teve dificuldade em abrir o ficheiro '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA está faltando o ficheiro '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA teve dificuldade em carregar um modelo." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Se o gta3.img foi modificado recentemente, tente reinstalar o GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA teve dificuldade em adicionar um upgrade a um veículo." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA encontrou erros no ficheiro '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "O seu PC reiniciou quando jogava MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Por favor, encerre os seguintes programas antes de continuar:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "Caminho do módulo inválido detetado.\n" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Erro de incompatibilidade da versão do ficheiro. Volte a instalar o MTA:SA se tiver problemas.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Alguns ficheiros estão faltando. Reinstale o MTA:SA se tiver problemas.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA não é compatível com o 'Modo de Segurança' do Windows.\n\n" +"Por favor, reinicie o seu PC.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Está a ter problemas ao correr MTA:SA?\n\n" "Deseja reverter para uma versão anterior?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -89,48 +143,48 @@ msgstr "Foram detetados problemas ao lançar MTA:SA.\n" "Redefinir opções do GTA poderá corrigir este problema.\n\n" "Deseja fazê-lo agora?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "Opções do GTA foram redefinidas.\n\n" "Pressione OK para continuar." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Ficheiro não pode ser eliminado: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Está a ter problemas a correr MTA:SA?\n\n" "Deseja obter ajuda online?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Está a ter problemas a correr MTA:SA?\n\n" "Deseja alterar a definição seguinte?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Modo ecrã inteiro:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Janela sem contornos" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Está a ter problemas a correr MTA:SA?\n\n" "Tente desativar os produtos seguintes para GTA e MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -138,133 +192,295 @@ msgstr "AVISO\n\n" "MTA:SA detetou atividade anormal.\n" "Utilize um anti-virus para analisar o seu PC.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "O ficheiro detetado foi: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Uma instância do GTA: San Andreas já está a correr. O jogo tem de estar fechado antes de lançar o MTA:SA.\n" "Deseja terminá-lo agora?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informação" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Incapaz de fechar o GTA: San Andreas. Se o problema persistir reinicie o seu PC." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Erro ao reiniciar o MTA:SA\n\n" +"Se o problema persistir, abra o Gestor de Tarefas e\n" +"pare os processos 'gta_sa.exe' e 'Multi Theft Auto.exe'" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Erro" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Outra instância do MTA já está a correr.\n\n" +"Se o problema persistir, reinicie o seu PC" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Outra instância do MTA já está a correr.\n\n" +"Deseja fechá-la?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Algo está em falta no Registry do Windows. Por favor, reinstale Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "O caminho para a sua instalação do GTA: San Andreas contém caracteres não suportados (unicode). Por favor, mova a sua instalação do Grand Theft Auto: San Andreas para um caminho compatível que contenha apenas caracteres ASCII padrão e reinstale o Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "O caminho para a sua instalação do 'MTA:SA' ou 'GTA: San Andreas'\n" -"contém um ';', (ponto e vírgula).\n\n" +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "O caminho para a sua instalação do 'MTA:SA' ou 'GTA: San Andreas' contém um ';' (ponto e vírgula).\n\n" "Se tiver problemas ao executar o MTA:SA,\n" -" mova a sua(s) instalação(ões) para um caminho que não contenha um ponto e vírgula." +"mova a(s) sua(s) instalações para um caminho que não contenha ponto e vírgula." -#: Client/loader/MainFunctions.cpp:810 +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "Foram detetados caminhos de instalação inválidos." + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "A carga falhou. Certifique-se de que os ficheiros de dados mais recentes foram instalados corretamente." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "A carga falhou. Certifique-se de que %s está instalado corretamente." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "A carga falhou. Não foi possível encontrar o gta_sa.exe em %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "A carga falhou. %s existe na pasta do GTA. Por favor, apague antes de continuar." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "O ficheiro principal tem um nome incorreto (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "O ficheiro principal não está assinado. Possível atividade de vírus.\n\n" -"Consulte a ajuda online se o MTA não funcionar corretamente." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "O ficheiro de dados %s está faltando. Possível atividade de vírus.\n\n" -"Considere reinstalar o Multi Theft Auto para a sua segurança.\n" -"Consulte a ajuda online se o MTA não funcionar corretamente." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "Ficheiro de dados %s em falta. Possível atividade de vírus." + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "O ficheiro de dados %s está modificado. Possível atividade de vírus.\n\n" -"Considere reinstalar o Multi Theft Auto para a sua segurança.\n" -"Consulte a ajuda online se o MTA não funcionar corretamente." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "Ficheiros .asi estão na pasta de instalação do 'MTA:SA' ou 'GTA: San Andreas'\n\n" -"Remova estes ficheiros .asi se tiver problemas com o MTA:SA." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Erro de incompatibilidade da versão do ficheiro. Volte a instalar o MTA:SA se tiver problemas.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "Ficheiro de dados %s modificado. Possível atividade de vírus." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Alguns ficheiros estão faltando. Reinstale o MTA:SA se tiver problemas.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "Existem ficheiros .asi no diretório de instalação.\n\n" +"Remova esses ficheiros .asi se tiver problemas." -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA não é compatível com o 'Modo de Segurança' do Windows.\n\n" -"Por favor, reinicie o seu PC.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "Caminhos de jogos inválidos detetados." -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Corrigir problema de configuração" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Corrigir erro de elevação necessária" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "O GTA: San Andreas pode não ter sido iniciado corretamente. Quer encerrá-lo?" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Desconhecido" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "O ficheiro '%s' está atualmente bloqueado por %zu processos.\n\n" +"Deseja encerrar os seguintes processos e continuar atualizando?\n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "Sua instalação pode estar corrompida agora.\n\n" +"%zu de %zu ficheiros não puderam ser restaurados a partir do backup.\n\n" +"Você deve reinstalar o Multi Theft Auto a partir de www.multitheftauto.com ou tentar executar a atualização como administrador." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "A instalar atualização..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "A extrair ficheiros..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA: SA não pode completar a seguinte tarefa:\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** O crash foi causado por uma falha de driver gráfico **\n\n" +"** Por favor, atualize os seus drivers gráficos **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "** Memória insuficiente - esta falha foi causada por memória livre insuficiente ou fragmentada. **" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Instalar ficheiros do MTA:SA atualizados" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Não foi possível atualizar devido a conflitos de ficheiros. Por favor, feche outras aplicações e tente novamente" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto não foi instalado corretamente, por favor reinstale. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "Criar junções GTA:SA" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "O MTA:SA não pode ser iniciado porque a cópia de um ficheiro falhou:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "O MTA:SA não pode ser iniciado porque um ficheiro do MTA:SA está incorreto ou em falta:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Copiar ficheiros do MTA:SA" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "O MTA:SA não pode ser iniciado porque um ficheiro do GTA:SA está incorreto ou em falta:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "Corrigir dependência do GTA:SA" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "O MTA:SA não pode ser iniciado porque o executável do GTA:SA está incorreto ou em falta:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Por favor, verifique se o seu antivírus detectou um falso positivo, tente adicionar uma exceção para o executável do GTA:SA e reinicie o MTA:SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "Gerar GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "O MTA:SA não pode ser iniciado porque o executável do GTA:SA não pode ser carregado:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Reparar GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "O MTA:SA não pode ser iniciado porque o reparo do GTA:SA falhou:" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Não foi possível iniciar o Grand Theft Auto: San Andreas. Por favor tente reiniciar, ou se o problema persistir, contacte o MTA em www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA não pode continuar porque o drive %s não tem espaço suficiente." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Ficheiro em falta:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Se o MTA não carregar, reinstale o GTA:SA" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas pode não ter iniciado corretamente. Quer terminar?" +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Atualizar configurações de instalação" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Atualizar configurações de compatibilidade" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +488,167 @@ msgstr "GTA: San Andreas pode não ter iniciado corretamente. Quer terminar?" #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Sim" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Não" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "OK" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Sair" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Ajuda" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Cancelar" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas encontrou um problema" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Informação de crash" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Selecione para enviar informação sobre o crash à equipa do MTA usando a 'internet'" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Fazer isso aumentará a chance deste crash ser corrigido." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Deseja reiniciar o MTA: San Andreas?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Aviso" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "A pasta de instalação do Grand Theft Auto: San Andreas contém esses ficheiros:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Esses ficheiros não são obrigatórios e podem interferir nos recursos gráficos desta versão do MTA:SA.\n\n" "É recomendável remover ou renomear esses ficheiros." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "Manter esses ficheiros, mas mostrar este aviso ao reiniciar" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Não me lembre destes ficheiros de novo" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Renomear esses ficheiros de *.dll para *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Mostre-me esses ficheiros" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Jogar MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Opções confusas" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus detetado!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Experimente cada opção para ver o que funciona:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - NVidia Padrão" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - NVidia Alternativo" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Intel Padrão" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Intel Alternativo" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Se nada resultar, isto pode ajudar:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Se tiver selecionado uma opção que funciona, isto pode ajudar:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Forçar modo janela" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Não mostrar novamente" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Aviso: Anti-virus não detetado no seu PC" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1106 +656,1181 @@ msgstr "MTA não pode detetar nenhum anti-virus a correr no seu PC.\n\n" "Virus podem interferir com o MTA e degradar a sua gameplay.\n\n" "Pressione 'Ajuda' para obter mais informação." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Já instalei um anti-virus" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Não vou instalar nenhum anti-virus.\n" "Quero lagar e fazer parte dum botnet." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "A procurar Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Por favor inicie Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "A instalar atualização..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Falha de conexão. Nick inválido!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "A extrair ficheiros..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Falha de conexão. Host inválido!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "A copiar ficheiros..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "A conexão para %s na porta %u falhou!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Cópia acabou mais cedo. Está tudo OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "A conectar a %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "A finalizar..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "A re-conectar a %s:%u ..." -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Pronto!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "A CONECTAR" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA precisa de acesso de administrador para a seguinte tarefa:\n\n" -" '%s'\n\n" -"Por favor, confirme na próxima janela." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Conexão caiu" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA: SA não pode completar a seguinte tarefa:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Desconectado: erro de protocolo desconhecido" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** O crash foi causado por uma falha de driver gráfico **\n\n" -"** Por favor, atualize os seus drivers gráficos **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Desconectado: desconectado remotamente" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Instalar ficheiros do MTA:SA atualizados" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Desconectado: conexão perdida remotamente" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Não foi possível atualizar devido a conflitos de ficheiros. Por favor, feche outras aplicações e tente novamente" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Desconectado: foi banido do servidor" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Desconectado: desconectado do servidor" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Desconectado: conexão ao servidor perdida" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Desconectado: conexão foi recusada" -#: Client/loader/CInstallManager.cpp:561 +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto não foi instalado corretamente, por favor reinstale. %s" +msgid "No such mod installed (%s)" +msgstr "Mod não instalado (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "Criar junções GTA:SA" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Resposta do servidor inválida (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "O MTA:SA não pode ser iniciado porque a cópia de um ficheiro falhou:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Resposta do servidor inválida (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "O MTA:SA não pode ser iniciado porque um ficheiro do MTA:SA está incorreto ou em falta:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Português (PT)" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Copiar ficheiros do MTA:SA" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Ocupado" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "O MTA:SA não pode ser iniciado porque um ficheiro do GTA:SA está incorreto ou em falta:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Não é possível verificar se há atualizações de momento" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Corrigir dependência do GTA:SA" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s necessário" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "O MTA:SA não pode ser iniciado porque o executável do GTA:SA está incorreto ou em falta:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Uma versão atualizada do MTA:SA %s é necessária para entrar no servidor selecionado.\n\n" +"Deseja descarregar e instalar o MTA:SA %s ?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Por favor, verifique se o seu antivírus detectou um falso positivo, tente adicionar uma exceção para o executável do GTA:SA e reinicie o MTA:SA." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Deseja iniciar o MTA:SA %s e conectar-se a este servidor?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Gerar GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Não é possível conectar-se de momento.\n\n" +"Por favor, tente mais tarde." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "O MTA:SA não pode ser iniciado porque o executável do GTA:SA não pode ser carregado:" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "A conectar" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Reparar GTA:SA" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Por favor, aguarde..." -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "O MTA:SA não pode ser iniciado porque o reparo do GTA:SA falhou:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "A VERIFICAR" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA não pode continuar porque o drive %s não tem espaço suficiente." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "VERIFICAÇÃO DE ATUALIZAÇÃO" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Ficheiro em falta:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Nenhuma atualização necessária" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Se o MTA não carregar, reinstale o GTA:SA" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "A DESCARREGAR" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Atualizar configurações de instalação" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "à espera..." -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Atualizar configurações de compatibilidade" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "ATUALIZAÇÃO OBRIGATÓRIA" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Desconhecido" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Para entrar neste servidor tem de atualizar o MTA.\n\n" +" Deseja fazê-lo agora?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "O ficheiro '%s' está atualmente bloqueado por %zu processos.\n\n" -"Deseja encerrar os seguintes processos e continuar atualizando?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "ATUALIZAÇÃO OPCIONAL" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "Sua instalação pode estar corrompida agora.\n\n" -"%zu de %zu ficheiros não puderam ser restaurados a partir do backup.\n\n" -"Você deve reinstalar o Multi Theft Auto a partir de www.multitheftauto.com ou tentar executar a atualização como administrador." +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "O servidor diz que uma atualização é recomendada, mas não é essencial.\n\n" +" Deseja atualizar agora?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "Atualmente, não há atualizações disponíveis.\n\n" +"Consulte www.multitheftauto.com" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "ERRO AO GUARDAR" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Não foi possível criar o ficheiro." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Selecione a pasta de instalação do Grand Theft Auto: San Andreas" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "ERRO AO DESCARREGAR" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Erro ao carregar o módulo %s! (%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "O ficheiro descarregado parece estar incorreto." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Nova instalação de %s detetada.\n\n" -"Deseja copiar as suas definições de %s?" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Por algum motivo." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA teve dificuldade em abrir o ficheiro '%s'" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "DESCARREGAMENTO COMPLETO" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA está faltando o ficheiro '%s'." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Problema desconhecido em _DialogUpdateResult" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA teve dificuldade em carregar um modelo." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "FICHEIROS GTA:SA MODIFICADOS" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Se o gta3.img foi modificado recentemente, tente reinstalar o GTA:SA." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ok" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA teve dificuldade em adicionar um upgrade a um veículo." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "ERRO" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Alguns ficheiros do MTA:SA estão em falta.\n\n\n" +"Reinstale o MTA:SA" + +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA encontrou erros no ficheiro '%s'" +msgid "%3d %% completed" +msgstr "%3d %% concluído" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "O seu PC reiniciou quando jogava MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"À espera de resposta - %-3d" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Por favor, encerre os seguintes programas antes de continuar:" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ AJUDA DE COMANDO ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Pedidos de website" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* São %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "O servidor requer os seguintes websites para poder carregá-los (mais tarde):" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "connect: A rede não está pronta, aguarde um momento" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NUNCA INTRODUZA DADOS SENSÃVEIS PARA OS PROTEGER DE SEREM ROUBADOS" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "connect: A síntaxe é 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Lembrar decisão" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "connect: Número de porta incorreto" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Autorizar" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "connect: A ligar a %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Recusar" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "connect: Não foi possível ligar a %s:%u!" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "Menu principal" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "connect: Falhou a desativação do mod atual" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Está a usar uma versão de testes! Esta build não pode ser usada para conectar a servidores públicos!" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "reconnect: A rede não está pronta, aguarde um momento" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA não vai receber atualizações para XP/Vista depois de Julho 2019.\n\n" -"Atualize o Windows para jogar nos servidores mais recentes." +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "reconnect: Número de porta incorreto" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Vai ser desconectado do servidor.\n\n" -"Tem a certeza que quer continuar?" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "reconnect: A ligar a %s:%u..." -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "AVISO DE DESCONEXÃO" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "reconnect: Não foi possível ligar a %s:%u!" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Associados todos os controles do GTA" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Português (PT)" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Ficheiro de configuração guardado" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* O seu serial é: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "DEFINIÇÕES" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Multi-jogadores" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Vídeo" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Ãudio" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Teclas" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Controles" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Interface" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Navegador Web" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Avançado" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Carregar definições padrão" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Sensibilidade do rato:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Sensibilidade vertical da mira:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Opções de rato" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Inverter rato verticalmente" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Conduzir com rato" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Voar com rato" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Opções de joystick" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Controles predeterminados (Rato + Teclado)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Controlos clássicos (Joystick)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Zona Limite" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Saturação" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Utilize o separador 'Teclas' para os botões do joystick." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Manípulo Esquerdo" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Manípulo Direito" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "DESCRIÇÃO" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "TECLA" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "TECLA ALT." #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Nick:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Guardar palavras-passe de servidores" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Atualizar navegador de servidores automaticamente" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Permitir upload do ecrã ao servidor" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Permitir sons externos" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Mostrar janela de descarregamento" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Permitir conexão ao Discord Rich Presence (mostrar atividade personalizada)" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" -msgstr "" +msgstr "Permitir o estado do jogo GTA:SA na Steam" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" -msgstr "" +msgstr "Guardar fotos tiradas pela câmara (arma) na pasta GTA San Andreas User Files" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" -msgstr "" +msgstr "Confirmar antes de desconectar do servidor usando o menu principal" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Usar ficheiros customizados do GTA:SA" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Opções de renderização do mapa" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Opacidade:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" -msgstr "" +msgstr "Resolução da imagem:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" -msgstr "" +msgstr "1024 x 1024 (Por defeito)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" -msgstr "" +msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Volume principal:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Volume do rádio:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Volume SFX:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "Volume do MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Volume da Voz:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Modo de reprodução:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Geral" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Opções de Rádio" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Equalizador de Rádio" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Auto-tune de Rádio" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Opções do Usertrack" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Rádio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Aleatório" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Sequencial" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Procurar Mídia Automaticamente" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Opções de silenciamento" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Silenciar todos os sons ao minimizar" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Silenciar sons da Rádio ao minimizar" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Silenciar sons SFX ao minimizar" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Silenciar sons do MTA ao minimizar" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Silenciar sons da Voz ao minimizar" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Resolução:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "FOV (campo de visão):" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Distância de visibilidade:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Brilho:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Qualidade dos efeitos:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Filtragem anisotrópica:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Anti-aliasing:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Proporção do ecrã:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Modo janela" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "Conhecimento do DPI" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Padrão" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Manter reso. sem contornos" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mip Mapping" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Baixa" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Média" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Elevada" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Muito elevada" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Off" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Auto" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD Usar Mesma Proporção" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Sombras volumétricas" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Efeito de erva/folhas" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Névoa de calor" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Fumo de pneus" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Sombras dinâmicas do ped" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Borrão de movimento" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Reflexos de chuva" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Minimizar Ecrã Inteiro" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Ativar janela de seleção de dispositivo" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Mostrar resoluções inseguras" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Renderizar veículos sempre em detalhe elevado" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Renderizar pedestres sempre em detalhe elevado" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Permitir websites remotos" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Permitir Javascript em websites remotos" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" -msgstr "" +msgstr "Ativar renderização por GPU" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Blacklist personalizada" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Domínio (exemplo: google.com)" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Bloquear" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Domínio" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Remover domínio" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Whitelist personalizada" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Autorizar" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Diverso" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Carregamento rápido de roupas de CJ:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Velocidade do navegador:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Conexão única:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Tag do pacote:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Animação de progresso:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Prioridade do processo:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Definição de depuramento:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Memória de streaming:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Atualizar tipo da build:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Instalar atualizações importantes:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "On" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Muito lento" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Padrão" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Rápido" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normal" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Acima do normal" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Mínimo" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Máximo" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Compatibilidade com Windows 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "Cor 16-bit" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Correção do rato" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Arquivos de recurso do cliente:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Mostrar no Explorador" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" -msgstr "" +msgstr "Alterar a afinidade da CPU 0 para melhorar o desempenho do jogo" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Atualizador automático" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Procurar atualizações agora" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Algumas definições serão modificadas quando reiniciar o MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Deseja reiniciar agora?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "NECESSITA REINICIAR" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Algumas definições serão modificadas quando se desconectar do servidor atual" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Deseja desconectar-se agora?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "DESCONEXÃO NECESSÃRIA" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joystick não detetado - Verifica a ligação e reinicie o MTA:SA" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Eixo" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Mova um eixo para associar a um controle, ou Escape para limpar" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Idioma:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Skin:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Predefinições:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Chat" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Carregar" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Cores" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Disposição" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Opções" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Fundo do Chat" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Texto do Chat" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Fundo do Input" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Texto do Input" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Linhas:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Escala:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Largura:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Tamanho" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "depois" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "para" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "segundo" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Desaparecimento" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Esconder linhas antigas" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horizontal:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Vertical:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Alinhamento do texto:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-Offset:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-Offset:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Posição" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Esquerda" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Centro" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Direita" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Cima" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Baixo" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Tipo de letra" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Ocultar fundo quando não estiver a escrever" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Completar nick com a tecla \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Permitir que o servidor pisque a janela" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Permitir notificações de balão" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Contorno em preto/branco do chat" @@ -1547,112 +1838,116 @@ msgstr "Contorno em preto/branco do chat" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Pressione um botão para atribuir ou Escape para limpar" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Associar uma tecla primária" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Associar uma tecla secundária" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "CONTROLES DO GTA" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "CONTROLES DO MTA" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "O seu nick contém carateres inválidos!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Menu principal" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "Em jogo" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Vermelho:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Verde:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Azul:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Transparência:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Cor" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Pré-Visualizar" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Desconecte do servidor antes de mudar de idioma" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Desconecte do servidor antes de mudar de skin" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Sombras volumétricas poderão causar um abrandamento do seu sistema.\n\n" "Tem a certeza que deseja ativá-las?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "AVISO DE PERFORMANCE" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Upload do ecrã é requerido por alguns servidores para medidas de anti-cheat.\n\n" "(O chat e qualquer GUI (interfaces gráficas) não podem ser capturados)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "INFO - UPLOAD DE CAPTURA DE ECRÃ" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "Alguns scripts podem tocar sons, como rádio, da internet.\n\n" "Desativar esta configuração poderá diminuir o consumo de banda larga.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "SONS EXTERNOS" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "Tem a opção de conexão Rich Presence ativa.\n" -"Deseja partilhar alguns dos seus dados do Discord com servidores?\n\n" -"Isto inclui atualmente o seu ID único do Discord." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "CONSENTIMENTO PARA PERMITIR A PARTILHA DE DADOS" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1660,13 +1955,9 @@ msgid "Some files in your GTA:SA data directory are customized.\n" msgstr "Alguns ficheiros na sua pasta do GTA: SA foram modificados.\n" "MTA só usará estes arquivos modificados se selecionar esta opção.\n\n" "No entanto, FICHEIROS GTA:SA MODIFICADOS SÂO BLOQUEADOS POR MUITOS SERVIDORES\n\n" -"Tem certeza de que deseja usá-los?" - -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "FICHEIROS GTA:SA MODIFICADOS" +"Tem certeza de que deseja usá-los?" -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1676,550 +1967,253 @@ msgstr "Permitir o conhecimento do DPI é algo experimental e\n" "Poderá ter problemas gráficos se ativar esta opção.\n\n" "Tem certeza de que deseja ativar esta opção?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "FUNCIONALIDADE EXPERIMENTAL" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" -msgstr "" +msgstr "Não é recomendado desativar esta opção, a menos que esteja a enfrentar problemas de desempenho.\n\n" +"Tem a certeza de que deseja desativá-la?" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Escolha um nickname" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Escolha um nickname para ser usado no jogo.\n" "Este será o seu nome quando for jogar num servidor" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Funcionalidade bastante experimental." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Impede abrandamentos de variações do CJ (usa mais 65MB de RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Routers antigos podem requerer uma velocidade de verificação mais lenta." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Ative apenas quando estiver descarregando após se ter conectado." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Etiquetar pacotes de rede para ajudar os ISPs a identificar o tráfego do MTA." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Animação do círculo giratório na parte inferior do ecrã" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Selecionar padrão sempre. (Esta opção não é guardada)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Máximo geralmente é melhor" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Atualizações automáticas:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Selecione padrão a não ser que goste de submeter bug reports." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Selecione padrão para instalar atualizações importantes automaticamente." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "Cor 16-bit:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Ativar modo cor 16-bit - Requer reiniciar MTA" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Correção do rato:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Correção de movimento do rato - Pode precisar reiniciar o PC" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" -msgstr "" +msgstr "Afinidade CPU:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." -msgstr "" - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Comando ou cvar desconhecido: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Ocupado" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Não é possível verificar se há atualizações de momento" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s necessário" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Uma versão atualizada do MTA:SA %s é necessária para entrar no servidor selecionado.\n\n" -"Deseja descarregar e instalar o MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Deseja iniciar o MTA:SA %s e conectar-se a este servidor?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Não é possível conectar-se de momento.\n\n" -"Por favor, tente mais tarde." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "A conectar" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Por favor, aguarde..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "A VERIFICAR" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "VERIFICAÇÃO DE ATUALIZAÇÃO" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Nenhuma atualização necessária" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "A DESCARREGAR" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "à espera..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "ATUALIZAÇÃO OBRIGATÓRIA" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Para entrar neste servidor tem de atualizar o MTA.\n\n" -" Deseja fazê-lo agora?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "ATUALIZAÇÃO OPCIONAL" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "O servidor diz que uma atualização é recomendada, mas não é essencial.\n\n" -" Deseja atualizar agora?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "ERRO AO GUARDAR" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Não foi possível criar o ficheiro." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "ERRO AO DESCARREGAR" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "O ficheiro descarregado parece estar incorreto." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Por algum motivo." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "DESCARREGAMENTO COMPLETO" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Problema desconhecido em _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ok" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "ERRO" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Alguns ficheiros do MTA:SA estão em falta.\n\n\n" -"Reinstale o MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% concluído" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"À espera de resposta - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Falha de conexão. Nick inválido!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Falha de conexão. Host inválido!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "A conexão para %s na porta %u falhou!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "A conectar a %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "A CONECTAR" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Conexão caiu" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Desconectado: erro de protocolo desconhecido" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Desconectado: desconectado remotamente" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Desconectado: conexão perdida remotamente" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Desconectado: foi banido do servidor" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Desconectado: desconectado do servidor" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Desconectado: conexão ao servidor perdida" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Desconectado: conexão foi recusada" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Mod não instalado (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Resposta do servidor inválida (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Resposta do servidor inválida (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "NOTÃCIAS" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Ir para a última novidade publicada" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "CONSOLA" +msgstr "Mude apenas se estiver com problemas de estabilidade." -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Erro fatal" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "PARA REPARAR, REMOVA ESTE FICHEIRO:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "O módulo %s está incorreto!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Erro ao executar URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "este ecrã de ajuda" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "fecha a aplicação" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "mostra a versão" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "mostra a hora" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "mostra o hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "mostra todas as teclas" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "mostra o seu serial" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "conecta-se a um servidor (host porta nick palavra-passe)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "conecta-o ao servidor anterior" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "associa uma tecla (controle)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "desassocia uma tecla (controle)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "copia os controles padrões do gta" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "produz uma captura de ecrã" -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "guarda a configuração imediatamente" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "limpa a janela de depuração" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "desliza o chat para cima" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "desliza o chat para baixo" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "desliza a janela de depuração para cima" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "desliza a janela de depuração para baixo" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "mostra estatísticas de memória " - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "mostra o gráfico de frame timing" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "para desenvolvedores: recarregar notícias" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ AJUDA DE COMANDO ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* São %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "connect: A síntaxe é 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "connect: Número de porta incorreto" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "connect: A ligar a %s:%u..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "guarda a configuração imediatamente" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "connect: Não foi possível ligar a %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "limpa a janela de depuração" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "connect: Falhou a desativação do mod atual" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "desliza o chat para cima" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "desliza o chat para baixo" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "desliza a janela de depuração para cima" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "desliza a janela de depuração para baixo" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "mostra estatísticas de memória " -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Associados todos os controles do GTA" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "mostra o gráfico de frame timing" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Ficheiro de configuração guardado" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "para desenvolvedores: recarregar notícias" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* O seu serial é: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Está a usar uma versão de testes! Esta build não pode ser usada para conectar a servidores públicos!" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Acelerar (eixo)" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA não vai receber atualizações para XP/Vista depois de Julho 2019.\n\n" +"Atualize o Windows para jogar nos servidores mais recentes." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Travar (eixo)" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Vai ser desconectado do servidor.\n\n" +"Tem a certeza que quer continuar?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programação" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "AVISO DE DESCONEXÃO" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Contribuidores" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "INFORMAÇÃO" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Design do Jogo / Programação" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "NOTÃCIAS" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Tradução" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Ir para a última novidade publicada" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Contribuidores do Patch" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Captura de ecrã teve %d bytes, mas esperava-se %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Agradecimentos especiais" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Captura de ecrã falhou" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Este software e projeto utiliza as seguintes bibliotecas e software:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Captura de ecrã efetuada: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Quer ver ajuda online sobre este problema?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Comando ou cvar desconhecido: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2394,25 +2388,56 @@ msgid "Group control backwards" msgstr "Controlo de grupo trás" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "A skin que você selecionou não conseguiu ser carregada, e a skin predeterminada também não conseguiu ser carregada, por favor reinstale o MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Captura de ecrã teve %d bytes, mas esperava-se %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Quer ver ajuda online sobre este problema?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Captura de ecrã falhou" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "CONSOLA" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Captura de ecrã efetuada: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programação" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Contribuidores" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Design do Jogo / Programação" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Tradução" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Contribuidores do Patch" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Agradecimentos especiais" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Este software e projeto utiliza as seguintes bibliotecas e software:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Acelerar (eixo)" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Travar (eixo)" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2420,6 +2445,61 @@ msgstr "Erro ao inicializar Direct3D9.\n\n" "Por favor, assegure-se que DirectX End-User Runtime\n" "e os últimos Windows Service Packs estão instalados." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Standby" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "jogador" +msgstr[1] "jogadores" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "on" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "servidor" +msgstr[1] "servidores" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Solicitando a lista de servidores (%lu ms decorrido)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Não foi possível analisar a lista de servidores." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Não foi possível obter a lista de servidores." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Backup da lista de servidores)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Não é possível ligar-se ao socket LAN-broadcast" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "A tentar encontrar servidores LAN" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2473,7 +2553,7 @@ msgstr "Latência:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Lista de jogadores" @@ -2500,40 +2580,39 @@ msgstr "Entrar no servidor assim que um slot de jogador estiver disponível." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "DIGITE A PALAVRA-PASSE DO SERVIDOR" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Conexão Perdida" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Comunicando..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "SERVIDORES" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Local" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Favoritos" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Recentes" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2541,298 +2620,367 @@ msgstr "PARA CONEXÃO RÃPIDA:\n\n" "Digite o host e porta na barra.\n" "Ou selecione um servidor da lista e pressione 'Conectar-se'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "AJUDA" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Recarregar" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Adicionar Favorito" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Conectar-se" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Informação de servidor" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Procurar servidores" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Procurar jogadores" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Iniciar procura" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Procurar jogadores..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Procurar servidores..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Nome" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Jogadores" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Ping" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Gamemode" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Incluir:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Vazio" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Cheio" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Com palavra-passe" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Offline" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Outras versões" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Voltar" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "A carregar..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..a carregar.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Não foi especificado um host!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Protocolo desconhecido" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Utilize o protocolo mtasa://" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Nick inválido! Por favor vá a Definições e redefina!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Tem de selecionar um servidor para se conectar." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Standby" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problema com o driver de gráficos" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "jogador" -msgstr[1] "jogadores" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Não é possível encontrar resolução de ecrã válida." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "on" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Tem a certeza que deseja utilizar esta resolução de ecrã?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "servidor" -msgstr[1] "servidores" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "Falha na inicialização game_sa" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Solicitando a lista de servidores (%lu ms decorrido)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "Falha na alocação de memória" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Não foi possível analisar a lista de servidores." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Pedidos de website" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Não foi possível obter a lista de servidores." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "O servidor requer os seguintes websites para poder carregá-los (mais tarde):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Backup da lista de servidores)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NUNCA INTRODUZA DADOS SENSÃVEIS PARA OS PROTEGER DE SEREM ROUBADOS" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Não é possível ligar-se ao socket LAN-broadcast" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Lembrar decisão" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "A tentar encontrar servidores LAN" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Recusar" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Esta versão expirou." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "desconecta do jogo" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "mostra as nametags" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "mostra o chat" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "mostra as estatísticas da internet" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "abre o input do chat" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "transmite voz a outros jogadores" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "entra em um carro como passageiro" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "estação de rádio seguinte" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "estação de rádio anterior" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" -msgstr "" +msgstr "ativa a visualização do mapa do jogador" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" -msgstr "" +msgstr "amplia o mapa do jogador (zoom)" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" -msgstr "" +msgstr "afaste o mapa do jogador (zoom-out)" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" -msgstr "" +msgstr "move o mapa do jogador para norte" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" -msgstr "" +msgstr "move o mapa do jogador para sul" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" -msgstr "" +msgstr "move o mapa do jogador para este" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" -msgstr "" +msgstr "move o mapa do jogador para oeste" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" -msgstr "" +msgstr "prende o mapa ao jogador" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" -msgstr "" +msgstr "reduz a opacidade do mapa do jogador" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" -msgstr "" +msgstr "aumenta a opacidade do mapa do jogador" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" -msgstr "" +msgstr "ativa/desativa o texto de ajuda do mapa do jogador" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "envia uma mensagem para o jogador específicado" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "altera para a próxima arma enquanto em um veículo" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "altera para a arma anterior enquanto em um veículo" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "mostra informações sobre o servidor atual" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "define a escala de todos os textos mostrados no ecrã" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Modo de desenvolvimento) mostra as colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Modo de desenvolvimento) mostra os ids dos sons do ambiente no painel de depuração" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "HOSPEDAR JOGO" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Recursos" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Nome do servidor:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Palavra-passe:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Max. de Jogadores:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Transmissão:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Selecionado" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Todos" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Iniciar" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "Mudar modo: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "Zoom: %s/%s Movimento: %s, %s, %s, %s Opacidade: %s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "Mapa: %s Texto de ajuda: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "A Seguir Jogador" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "Movimento Livre" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Progresso do descarregamento do mapa:" @@ -2853,195 +3001,195 @@ msgstr "%s de %s" msgid "Disconnect to cancel download" msgstr "Desconecte-se para cancelar o descarregamento" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Desconectado: nickname inválido" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Desconectado do servidor" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Desconectado: Serial está banido.\n" "Motivo: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Desconectado: Você está banido.\n" "Motivo: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Desconectado: Conta está banida.\n" "Motivo: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Desconectado: Versão incompatível" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Desconectado: Entradas constantes. Por favor espere um minuto, e reconecte-se." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Desconectado: Servidor de um branch diferente.\n" "Informação: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Desconectado: Versão errada.\n" "Informação: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Desconectado: Servidor está a executar uma build mais recente.\n" "Informação: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Desconectado: Servidor está a executar uma build mais antiga.\n" "Informação: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Desconectado: Nick já está em uso" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Desconectado: O elemento do jogador não pôde ser criado." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Desconectado: O servidor recusou a ligação: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Desconectado: Verificação do serial falhou" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" -msgstr "" +msgstr "Desconectado: Serial já em uso" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Desconectado: Dessincronização de conexão %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Desconectado: Foste expulso por %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Desconectado: Foste banido por %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Desconectado: Servidor desligado ou a reiniciar" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Foste expulso do jogo" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Este servidor requer um gta_sa.exe não modificado" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Por favor, substitua o gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Este servidor não permite D3D9.DLLs customizadas" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Remova o D3D9.DLL da pasta de instalação do GTA e reinicie o MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Este servidor não permite máquinas virtuais" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Este servidor requer que a assinatura do driver esteja habilitada" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Por favor, reinicie o seu PC" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Este servidor detetou componentes do anti-cheat em falta" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Tente reiniciar o MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Este servidor requer um gta3.img e gta_int.img não modificados" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Por favor substitua o gta3.img ou gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Este servidor não permite Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Certifique-se de que nenhum outro programa está a modificar o MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Tempo Restante: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d dia" msgstr[1] "%d dias" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d hora" msgstr[1] "%d horas" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d minuto" msgstr[1] "%d minutos" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3049,302 +3197,212 @@ msgstr[0] "%d segundo" msgstr[1] "%d segundos" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Desconectado" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Erro de descarregamento: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "A voar com um OVNI em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "A conduzir em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "A navegar em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "A bordo de um comboio em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "A voar em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "A conduzir em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "A andar de Monster Truck em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "A andar de Quad em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "A saltitar em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "A fazer coisas duvidosas em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "A fazer parkour em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "A fazer drive-by em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "A afogar-se..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "A respirar água" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "A afogar-se em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "A abrigar-se em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "A lutar em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "A andar à pancada em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "A andar aos tiros em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "A disparar em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "A voar de Jetpack em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "A pegar fogo em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "A arder em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "A nadar em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "A flutuar na água em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "A ser perseguido por um tubarão" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "A ser estrangulado em" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "A entrar no jogo ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Não conectado; por favor use Conexão Rápida ou o comando 'connect' para conectar-se a um servidor." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Não foi possível iniciar o servidor local. Consulte a consola para detalhes." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Servidor Local" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Iniciando o servidor local ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "Ãrea 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "A passear em " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Você foi expulso do jogo ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "A conectar ao servidor local..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Erro ao conectar ao servidor." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Conexão com o servidor local caiu. Veja a consola para detalhes." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "A ligação com o servidor foi perdida" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Desconectado: o servidor está atualmente cheio" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Desconectado: palavra-passe incorreta" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "A verificação do cliente do MTA falhou!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "Numa fossa" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "A caminho do hospital" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "A ir ter com Deus" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "Em vias de falecer" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "Morto" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "HOSPEDAR JOGO" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Recursos" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Nome do servidor:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Palavra-passe:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Max. de Jogadores:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Transmissão:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Selecionado" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Todos" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Iniciar" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problema com o driver de gráficos" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Não é possível encontrar resolução de ecrã válida." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Tem a certeza que deseja utilizar esta resolução de ecrã?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Erro de descarregamento: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 #, c-format msgid "Fatal error (%u). If this problem persists, please check out multitheftauto.com for support." -msgstr "" +msgstr "Erro fatal (%u). Se este problema persistir, verifique multitheftauto.com para apoio." #. #ifdef MTA_DEBUG #. assert ( 0 ); @@ -3353,17 +3411,17 @@ msgstr "" #: Shared/mods/deathmatch/logic/Utils.cpp:143 #, c-format msgid "Protocol error (%u). If this problem persists, please check out multitheftauto.com for support." -msgstr "" +msgstr "Erro do protocolo (%u). Se este problema persistir, verifique multitheftauto.com para apoio." #: Shared/mods/deathmatch/logic/Utils.cpp:145 msgid "Connection error" msgstr "Erro de ligação" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto não foi instalado corretamente, por favor reinstale." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Seu navegador mostrará uma página web com algumas informações de ajuda.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/ro_RO/client.pot b/Shared/data/MTA San Andreas/MTA/locale/ro_RO/client.pot index c9fecc7716f..5a3506bcd92 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/ro_RO/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/ro_RO/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 04:08+0000\n" -"PO-Revision-Date: 2025-07-15 04:11\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 18:15\n" "Last-Translator: \n" "Language-Team: Romanian\n" "Language: ro_RO\n" @@ -17,72 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "A apărut o problemă la repornirea MTA:SA\n\n" -"Dacă problema persistă, deschide Managerul de activități È™i\n" -"opreÈ™te procesele 'gta_sa.exe' È™i 'Multi Theft Auto.exe'.\n\n\n" -"ÃŽncearcă să relansezi MTA:SA?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "PorneÈ™te Grand Theft Auto: San Andreas.\n" +"Asigură-te că jocul este localizat în dosarul 'Program Files (x86)'." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:651 -#: Client/mods/deathmatch/logic/CClientGame.cpp:725 -#: Client/mods/deathmatch/logic/CClientGame.cpp:749 -#: Client/mods/deathmatch/logic/CClientGame.cpp:771 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1184 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1264 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1274 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1343 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1380 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1429 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1441 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Eroare" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "ÃŽn căutarea GTA: San Andreas" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "O altă instanță a MTA rulează deja.\n\n" -"Dacă această problemă persistă, te rugăm restartează-È›i calculatorul" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Ne pare rău, jocul nu a fost găsit.\n" +"PorneÈ™te Grand Theft Auto: San Andreas È™i apasă reîncearcă.\n" +"Asigură-te că jocul este localizat în dosarul 'Program Files (x86)'." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "O altă instanță a MTA rulează deja.\n\n" -"DoreÈ™ti să o închizi?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Selectează directorul de instalare al Grand Theft Auto: San Andreas" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA necesită acces de administrator pentru următoarea sarcină:\n\n" +"'%s'\n\n" +"Te rugăm confirmă în fereastra următoare." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Eroare la încărcarea modulului %s! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Se copiază fiÈ™ierele..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Copierea s-a terminat rapid. Totul este OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Se finalizează..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Finalizat!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "O nouă instalare a %s a fost detectată.\n\n" +"DoreÈ™ti să copiezi setările din %s?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA a întâmpinat probleme la deschiderea fiÈ™ierului '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA duce lipsă de fiÈ™ierul '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA a întâmpinat probleme la încărcarea unui model." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Dacă aÈ›i modificat recent gta3.img, încercaÈ›i să reinstalaÈ›i GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA a întâmpinat probleme la adăugarea de îmbunătățiri unui vehicul." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA a găsit erori în fiÈ™ierul '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "S-a restartat calculatorul tău în timp ce jucai MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Te rugăm închide următoarele programe înainte de a continua:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "Detectată o adresă de modul nevalidă.\n" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Eroare de nepotrivire a versiunilor fiÈ™ierelor. Reinstalează MTA:SA dacă întâmpini probleme.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Unele fiÈ™iere lipsesc. Reinstalează MTA:SA dacă întâmpini probleme.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA nu este compatibil cu Windows 'Safe Mode'.\n\n" +"Vă rugăm să reporniÈ›i computerul.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Ai probleme la rularea MTA:SA?\n\n" "Vrei să revi la o versiune anterioară?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +143,48 @@ msgstr "Se pare că o problemă împiedică lansarea MTA:SA.\n" "Restabilirea setărilor iniÈ›iale a GTA poate rezolva uneori problema.\n\n" "Vrei să restabileÈ™ti setările GTA acum?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "Setările GTA au fost restabilite.\n\n" "Apasă OK pentru a continua." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "FiÈ™ierul nu a putut fi È™ters: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Ai probleme la rularea MTA:SA?\n\n" "Vrei să vezi niÈ™te ajutor on-line?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "AveÈ›i probleme atunci când rulaÈ›i MTA:SA?\n\n" "DoriÈ›i să schimbaÈ›i următoarele setări?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Mod ecran complet:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Fereastră fără margini" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "AveÈ›i probleme atunci când rulaÈ›i MTA:SA?\n\n" "ÃŽncercaÈ›i să dezactivaÈ›i următoarele produse pentru GTA È™i MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +192,297 @@ msgstr "AVERTISMENT\n\n" "MTA:SA a detectat activități neobiÈ™nuite.\n" "Te rugăm rulează o scanare de detectare a viruÈ™ilor pentru a te asigura că sistemul tău este în siguranță.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "FiÈ™ierul detectat a fost: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "O instanță a GTA: San Andreas rulează deja. Ea trebuie închisă înainte ca MTA:SA să file lansat. Vrei să o închizi acum?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "InformaÅ£ii" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "GTA: San Andreas nu poate fi închis. Dacă problema persistă te rugăm restartează-È›i calculatorul." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "A apărut o problemă la repornirea MTA:SA\n\n" +"Dacă problema persistă, deschide Managerul de activități È™i\n" +"opreÈ™te procesele 'gta_sa.exe' È™i 'Multi Theft Auto.exe'.\n\n\n" +"ÃŽncearcă să relansezi MTA:SA?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Eroare" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "O altă instanță a MTA rulează deja.\n\n" +"Dacă această problemă persistă, te rugăm restartează-È›i calculatorul" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "O altă instanță a MTA rulează deja.\n\n" +"DoreÈ™ti să o închizi?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Intrările din registru lipsesc. Te rugăm reinstalează Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Calea către dosarul tău cu instalarea GTA: San Andreas conÈ›ine caractere nesuportate (unicode). Te rugăm mută instalarea Grand Theft Auto: San Andreas într-un loc compatibil care conÈ›ine numai caractere standard de tip ASCII È™i reinstalează Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Calea către instalarea MTA: San Andreas sau instalarea GTA: San Andreas\n" +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "Calea către instalarea 'MTA:SA' sau 'GTA: San Andreas'\n" "conÈ›ine un simbol ';' (punct È™i virgulă).\n\n" -"Dacă întâmpinaÈ›i probleme în timpul rulării MTA:SA,\n" -"mutaÈ›i-vă instalarea sau instalările într-un loc care nu conÈ›ine acest simbol." +"Dacă întâmpini probleme în timp ce foloseÈ™ti MTA:SA,\n" +"mută instalarea către o cale care nu conÈ›ine acest simbol." + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "A fost detectată o adresă de instalare nevalidă." -#: Client/loader/MainFunctions.cpp:810 +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "ÃŽncărcarea a eÈ™uat. Te rugăm asigură-te că ultimele fiÈ™iere cu date au fost instalate corect." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "ÃŽncărcarea a eÈ™uat. Te rugăm asigură-te că %s este instalat corect." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "ÃŽncărcarea a eÈ™uat. Nu s-a putut găsi 'gta_sa.exe' în %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "ÃŽncărcarea a eÈ™uat. %s se află în directorul GTA. Te rugăm È™terge-l înainte de a continua." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "FiÈ™ierul principal are un nume incorect (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "FiÈ™ierul principal este nesemnat. Posibilă activitate a viruÈ™ilor.\n\n" -"Vezi ajutor on-line dacă MTA nu funcÈ›ionează corect." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "FiÈ™ierul de date %s lipseÈ™te. Posibilă activitate a unor viruÈ™i.\n\n" -"LuaÈ›i în considerare reinstalarea Multi Theft Auto pentru securitatea dumneavoastră.\n" -"CăutaÈ›i sprijin online dacă MTA nu funcÈ›ionează în mod corespunzător." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "FiÈ™ierul de date %s lipseÈ™te. Posibilă activitate virus." + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "FiÈ™ierul de date %s este modificat. Posibilă activitate a unor viruÈ™i.\n\n" -"LuaÈ›i în considerare reinstalarea Multi Theft Auto pentru securitatea dumneavoastră.\n" -"CăutaÈ›i sprijin online dacă MTA nu funcÈ›ionează în mod corespunzător." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "S-au găsit fiÈ™iere .asi în directorul de instalare al MTA: San Andreas sau al GTA: San Andreas.\n\n" -"Șterge aceste fiÈ™iere .asi dacă întâmpini probleme cu MTA:SA." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Eroare de nepotrivire a versiunilor fiÈ™ierelor. Reinstalează MTA:SA dacă întâmpini probleme.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "FiÈ™ierul de date %s este modificat. Posibilă activitate virus." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Unele fiÈ™iere lipsesc. Reinstalează MTA:SA dacă întâmpini probleme.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "FiÈ™iere .asi prezente în dosarul de instalare.\n\n" +"Șterge aceste fiÈ™iere .asi dacă întâmpini probleme." -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA nu este compatibil cu Windows 'Safe Mode'.\n\n" -"Vă rugăm să reporniÈ›i computerul.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "Au fost detectate adrese ale jocului nevalide." -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Repară problema de configurare" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "RemediaÈ›i eroarea de elevaÈ›ie" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "Este posibil ca GTA: San Andreas să nu fi pornit corect. DoreÈ™ti să închizi?" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Necunoscut" + +#: Client/loader/Install.cpp:272 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Nu s-a putut porni Grand Theft Auto: San Andreas. Te rugăm încearcă să-È›i restartezi calculatorul sau dacă problema persistă, să contactezi MTA la www.multitheftauto.com.\n\n" -"[%s]" +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "FiÈ™ierul '%s' este blocat de procesul %zu.\n\n" +"DoreÈ™ti să termini acest proces È™i să continui cu actualizarea?\n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "Descărcarea ta s-ar putea să fie coruptă.\n\n" +"%zu din %zu fiÈ™iere nu au putut fi restaurate din backup.\n\n" +"Ar trebui să reinstalezi Multi Theft Auto de pe www.multitheftauto.com\n" +"sau să încerci să actualizezi jocul folosind permisiunile de administrator." -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "Se poate ca GTA: San Andreas să nu fi fost lansat corect. Vrei să îl închizi?" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Se instalează actualizarea..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Se extrag fiÈ™ierele..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA nu a reuÈ™it să termine următoarea sarcină:\n\n" +"'%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Crashul a fost provocat de o eroare a driverului grafic **\n\n" +"** Te rugăm actualizează-È›i driverele grafice **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "** Out of memory - acest crash a fost cauzat de memorie insuficientă sau fragmentată. **" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "** Captură sporită crash va fi încercată la următoarea pornire. **" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Instalează fiÈ™ierele MTA:SA actualizate" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Nu s-a putut actualiza datorită conflictelor fiÈ™ierelor. Te rugăm închide celelalte aplicaÈ›ii È™i reîncearcă" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto nu a fost instalat corespunzător, te rugăm reinstalează-l. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "Creează intersecÈ›iile GTA:SA" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA nu poate fi lansat deoarece copierea unui fiÈ™ier a eÈ™uat:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA nu poate fi lansat deoarece un fiÈ™ier MTA:SA este incorect sau lipseÈ™te:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Copiază fiÈ™ierele MTA:SA" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA nu poate fi lansat deoarece un fiÈ™ier GTA:SA este incorect sau lipseÈ™te:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "Actualizează dependință GTA:SA" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA nu poate fi lansat deoarece executabilul GTA:SA este incorect sau lipseÈ™te:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Vă rugăm verificaÈ›i antivirusul pentru o detectare fals-pozitivă, încercaÈ›i să adăugaÈ›i o excepÈ›ie pentru executabilul GTA:SA È™i apoi reporniÈ›i MTA:SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "Generează GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA nu poate fi lansat deoarece executabilul GTA:SA nu poate fi încărcat:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Actualizează GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA nu poate fi lansat deoarece actualizarea GTA:SA a eÈ™uat:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA nu poate continua deoarece partiÅ£ia %s nu are destul spaÅ£iu." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "FiÈ™ier lipsă:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Dacă MTA nu reuÈ™eÈ™te să se încarce, te rugăm reinstalează GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Actualizează setările de instalare" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Actualizează setările de compatibilitate" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +490,167 @@ msgstr "Se poate ca GTA: San Andreas să nu fi fost lansat corect. Vrei să îl #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Da" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Nu" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "OK" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "IeÈ™ire" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Ajutor" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Anulează" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas a întâmpinat o problemă" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "InformaÈ›ii crash" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Bifează această casetă pentru a trimite aceste informaÈ›ii legate de crash către dezvoltatorii MTA folosind 'internetul'" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Acest lucru va spori È™ansele ca acest crash să fie reparat." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "EÈ™ti sigur că vrei să reporneÈ™ti MTA: San Andreas?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Avertisment" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "Directorul tău Grand Theft Auto: San Andreas conÈ›ine aceste fiÈ™iere:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Aceste fiÈ™iere nu sunt necesare È™i pot interfera cu caracteristicile grafice ale MTA:SA.\n\n" "Este recomandat să È™tergi sau să redenumeÈ™ti aceste fiÈ™iere." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "Păstrează aceste fiÈ™iere, dar arată acest avertisment È™i la următoarea pornire" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Nu îmi reaminti despre aceste fiÈ™iere" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "RedenumeÈ™te aceste fiÈ™iere din *.dll în *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Arată-mi fiÈ™ierele" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Lansează MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - OpÈ›iuni derutante" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "nVidia Optimus detectat!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "ÃŽncearcă fiecare opÈ›inue È™i vezi care funcÈ›ionează:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - nVidia Standard" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - nVidia Alternativ" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Intel Standard" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Intel Alternativ" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Dacă devi disperat, asta te-ar putea ajuta:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Dacă aÅ£i selectat deja o opÅ£iune care funcÅ£ionează, acest lucru ar putea ajuta:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "ForÈ›ează modul fereastră" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Nu arăta din nou" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Avertisment: Nu a putut fi detectat niciun produs anti-virus" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1109 +658,1182 @@ msgstr "MTA nu a putut detecta niciun anti-virus pe calculatorul dumneavoastră. "ViruÈ™ii interferează cu MTA È™i îți degradează experienÈ›a de joc.\n\n" "Apasă pe 'Ajutor' pentru mai multe informaÈ›ii." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Am deja un anti-virus instalat" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Nu voi instala un anti-virus." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "Crash-ul întâmpinat se datorează abuzului de memorie de către servere.\n\n" +"Chiar È™i cu multă memorie RAM, acesta este un joc x86 cu limite de spaÈ›iu pentru adrese de până la 3.6 GB, iar unele servere extrem de neoptimizate, cu multe modificări (sau doar câteva scripturi prost scrise), pot provoca acest lucru, precum È™i lag.\n\n" +"Contactează proprietarul serverului sau asistenÈ›a MTA pe Discord-ul oficial MTA (https://discord.gg/mtasa) pentru mai multe informaÈ›ii." + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "MTA: San Andreas - InformaÈ›ie Memorie Insuficientă" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Se caută Grand Theft Auto: San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Te rugăm lansează Grand Theft Auto: San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Se instalează actualizarea..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Conectarea a eÈ™uat. Numele de utilizator specificat este invalid!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Se extrag fiÈ™ierele..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Conectarea a eÈ™uat. Hostul specificat este invalid!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Se copiază fiÈ™ierele..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Conectarea la %s cu portul %u a eÈ™uat!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Copierea s-a terminat rapid. Totul este OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Se conectează la %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Se finalizează..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "Reconectare la %s:%u ..." -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Finalizat!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "SE CONECTEAZÄ‚" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA necesită acces de administrator pentru următoarea sarcină:\n\n" -"'%s'\n\n" -"Te rugăm confirmă în fereastra următoare." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Conexiunea a expirat" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA nu a reuÈ™it să termine următoarea sarcină:\n\n" -"'%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Deconectat: eroare de protocol necunoscută" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Crashul a fost provocat de o eroare a driverului grafic **\n\n" -"** Te rugăm actualizează-È›i driverele grafice **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Deconectat: deconectat automat" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Instalează fiÈ™ierele MTA:SA actualizate" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Deconectat: conexiune pierdută" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Nu s-a putut actualiza datorită conflictelor fiÈ™ierelor. Te rugăm închide celelalte aplicaÈ›ii È™i reîncearcă" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Deconectat: ai interdicÈ›ie pe acest server" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Deconectat: deconectat de la server" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Deconectat: conexiunea la server a fost pierdută" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Deconectat: conectarea a fost refuzată" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto nu a fost instalat corespunzător, te rugăm reinstalează-l. %s" +msgid "No such mod installed (%s)" +msgstr "Nu există asemena mod instalat (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "Creează intersecÈ›iile GTA:SA" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Răspuns invalid de la server (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA nu poate fi lansat deoarece copierea unui fiÈ™ier a eÈ™uat:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Răspuns invalid de la server (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA nu poate fi lansat deoarece un fiÈ™ier MTA:SA este incorect sau lipseÈ™te:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Română" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Copiază fiÈ™ierele MTA:SA" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Ocupat" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA nu poate fi lansat deoarece un fiÈ™ier GTA:SA este incorect sau lipseÈ™te:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Nu se poate verifica pentru actualizări acum" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Actualizează dependință GTA:SA" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s necesar" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA nu poate fi lansat deoarece executabilul GTA:SA este incorect sau lipseÈ™te:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "O versiune mai actuală de MTA:SA %s este necesară pentru a juca pe serverul selectat.\n\n" +"EÈ™ti sigur că vrei să descarci È™i să instalezi MTA:SA %s?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Vă rugăm verificaÈ›i antivirusul pentru o detectare fals-pozitivă, încercaÈ›i să adăugaÈ›i o excepÈ›ie pentru executabilul GTA:SA È™i apoi reporniÈ›i MTA:SA." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Vrei să porneÈ™ti MTA:SA %s È™i să te conectezi la acest server?" + +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Nu este posibil să te conectezi în acest moment.\n\n" +"ÃŽncearcă mai târziu." + +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Se conectează" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Generează GTA:SA" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "AÈ™teaptă..." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA nu poate fi lansat deoarece executabilul GTA:SA nu poate fi încărcat:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "SE VERIFICÄ‚" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Actualizează GTA:SA" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "VERIFICARE ACTUALIZARE" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA nu poate fi lansat deoarece actualizarea GTA:SA a eÈ™uat:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Nicio actualizare nu este necesară" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA nu poate continua deoarece partiÅ£ia %s nu are destul spaÅ£iu." +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "SE DESCARCÄ‚" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "FiÈ™ier lipsă:" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "se aÈ™teaptă..." -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Dacă MTA nu reuÈ™eÈ™te să se încarce, te rugăm reinstalează GTA:SA" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "ACTUALIZARE OBLIGATORIE" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Actualizează setările de instalare" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Pentru a juca pe acest server trebuie să actualizezi MTA.\n\n" +"DoreÈ™ti să actualizezi acum?" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Actualizează setările de compatibilitate" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "ACTUALIZARE OPÈšIONALÄ‚" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Necunoscut" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Serverul spune că o actualizare este recomandată, dar nu necesară.\n\n" +"DoreÈ™ti să actualizezi acum?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "FiÈ™ierul '%s' este blocat de procesul %zu.\n\n" -"DoreÈ™ti să termini acest proces È™i să continui cu actualizarea?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "Actualizarea nu este disponibilă momentan.\n\n" +"Te rugăm verifică www.multitheftauto.com" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "Descărcarea ta s-ar putea să fie coruptă.\n\n" -"%zu din %zu fiÈ™iere nu au putut fi restaurate din backup.\n\n" -"Ar trebui să reinstalezi Multi Theft Auto de pe www.multitheftauto.com\n" -"sau să încerci să actualizezi jocul folosind permisiunile de administrator." +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "EROARE SALVARE" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "PorneÈ™te Grand Theft Auto: San Andreas.\n" -"Asigură-te că jocul este localizat în dosarul 'Program Files (x86)'." +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Nu s-a putut crea fiÈ™ierul." -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "ÃŽn căutarea GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "EROARE DESCÄ‚RCARE" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Ne pare rău, jocul nu a fost găsit.\n" -"PorneÈ™te Grand Theft Auto: San Andreas È™i apasă reîncearcă.\n" -"Asigură-te că jocul este localizat în dosarul 'Program Files (x86)'." +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "FiÈ™ierul descărcat pare să fie incorect." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Selectează directorul de instalare al Grand Theft Auto: San Andreas" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Dintr-un anumit motiv." -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Eroare la încărcarea modulului %s! (%s)" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "DESCÄ‚RCARE COMPLETÄ‚" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "O nouă instalare a %s a fost detectată.\n\n" -"DoreÈ™ti să copiezi setările din %s?" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Problemă necunoscută în _DialogUpdateResult" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA a întâmpinat probleme la deschiderea fiÈ™ierului '%s'" +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "FIȘIERE GTA:SA MODIFICATE" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA duce lipsă de fiÈ™ierul '%s'." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ok" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA a întâmpinat probleme la încărcarea unui model." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "EROARE" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Dacă aÈ›i modificat recent gta3.img, încercaÈ›i să reinstalaÈ›i GTA:SA." +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Unele fiÈ™iere MTA:SA lipsesc.\n\n\n" +"Te rugăm să reinstalezi MTA:SA" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA a întâmpinat probleme la adăugarea de îmbunătățiri unui vehicul." +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d%% complet" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2840 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA a găsit erori în fiÈ™ierul '%s'" +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Se aÈ™teaptă un răspuns - %-3d" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "S-a restartat calculatorul tău în timp ce jucai MTA:SA?" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ AJUTOR COMENZI ]***\n" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Te rugăm închide următoarele programe înainte de a continua:" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Timpul este %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Solicitări website" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "conectare: ReÈ›eaua nu este gata, te rugăm aÈ™teaptă un moment" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Serverul solicită următoarele site-uri web pentru a le încărca (mai târziu):" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "connect: Sintaxa este 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NU INTRODUCEÈšI NICIODATÄ‚ DATE PERSONALE, PENTRU A EVITA SÄ‚ FIE FURATE" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "connect: Numărul portului este incorect" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Memorează decizia" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "connect: Se conectează la %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Permite" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "connect: nu s-a putut realiza conexiunea la %s:%u!" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Refuză" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "connect: Dezactivarea modificării curente a eÈ™uat" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:543 -msgid "Main menu" -msgstr "Meniu principal" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "reconectare: ReÈ›eaua nu este gata, te rugăm aÈ™teaptă un moment" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "FoloseÈ™ti un build de pe o ramură feature! Acesta este exclusiv un build de test È™i nu poate fi folosit pentru conectarea la servere publice!" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "reconectare: Număr port incorect" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA nu va primi actualizări pe XP/Vista după luna Iulie 2019.\n\n" -"ActualizaÈ›i-vă versiunea de Windows pentru a juca pe cele mai recente servere." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "reconectare: Se reconectează la %s:%u..." -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Acest lucru te va deconecta de la server.\n\n" -"EÈ™ti sigur că vrei să te deconectezi?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "reconectare: nu s-a putut conecta la %s:%u!" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "AVERTISMENT DECONECTARE" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "FoloseÈ™te controalele din GTA" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "INFORMAÈšIE" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "FiÅŸierul cu configuraÅ£ia a fost salvat" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Română" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Serialul tău este: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "SETÄ‚RI" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Multiplayer" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Video" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "PostFX" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Audio" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Taste" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Controale" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Interfaţă" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Navigator web" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Avansat" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "ÃŽncarcă setările implicite" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Sensibilitate mouse:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Sensibilitate È›intă verticală:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "OpÈ›iuni mouse" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Inversează mouseul vertical" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Dirijează cu mouseul" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Pilotează cu mouseul" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "FoloseÈ™te sensibilitatea mouse-ului pentru È›intire" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "OpÈ›iuni joypad" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Controale standard (Mouse + Tastatură)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Controale clasice (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Zonă moartă" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "SaturaÈ›ie" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "FoloseÈ™te tabul 'Taste' pentru butoanele joypadului." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Stickul stâng" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Stickul drept" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "DESCRIERE" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "TASTÄ‚" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "TASTÄ‚ ALTERNATIVÄ‚" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Nume:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Salvează parolele severelor" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Reîmprospătează automat lista cu servere" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Permite trimiterea capturilor de ecran către servere" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "PermiteÅ£i sunete externe" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Arată întotdeauna fereastra de descărcare" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Permite conectarea cu Discord Rich Presence" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "Permite statusul ingame a GTA:SA pe Steam" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "Salvează pozele făcute cu camera în dosarul GTA San Andreas User Files" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "ÃŽntreabă înainte să te deconectezi de pe server folosind meniul principal" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "FoloseÅŸte fiÅŸiere GTA:SA modificate" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "OpÈ›iuni de redare a hărÈ›ii" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Opacitate:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "RezoluÈ›ie imagine:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "1024 x 1024 (Standard)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Volum principal:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Volum radio:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Volum SFX:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "Volum MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Volum voce:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Mod de redare:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "General" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "OpÅ£iuni radio" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Egalizator radio" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Auto-reglare radio" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "OpÈ›iuni usertrack" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Radio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Aleator" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "SecvenÈ›ial" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Scanare media automată" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "OpÈ›iuni dezactivare sunet" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Dezactivează toate sunetele la minimizare" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "OpreÈ™te sunetele radio la minimizare" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "OpreÈ™te sunetele SFX la minimizare" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "OpreÈ™te sunetele MTA la minimizare" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "OpreÈ™te sunetele voce la minimizare" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "RezoluÈ›ie:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Câmp vizual:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Distanță de redare:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Luminozitate:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Calitate FX:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Modul de filtrare anizotropic:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Anti-aliasing:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Raport de aspect:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "ÃŽn fereastră" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI aware" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Standard" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Fără margini păstrează rezoluÈ›ia" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mip Mapping" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "V-Sync" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Scăzută" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Medie" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Ridicată" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Foarte ridicată" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Dezactivat" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Automat" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "PotriveÈ™te HUD-ul cu raportul de aspect" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Umbre volumetrice" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Efect iarbă" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Efect căldură" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Fum roÈ›i" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Umbre dinamice pentru personaje" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Estompare în miÈ™care" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "ReflecÈ›ii ploaie de tip corona" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Minimizare ecran întreg" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Activează dialogul de selectare a dispozitivelor" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "AfiÅŸează rezoluÅ£ii nesigure" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "AfiÈ™ează întotdeauna vehiculele cu detalii ridicate" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "AfiÈ™ează întotdeauna personajele cu detalii ridicate" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "Gamma:" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "Contrast:" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "SaturaÈ›ie:" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "Aplică ajustările în modul windowed" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "Aplică ajustările în modul fullscreen" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Activare website-uri externe" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Permite Javascript pe website-uri" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "Activează randarea GPU" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Listă interdicÅ£ie personalizată" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Introdu un domeniu (de ex. google.com)" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Blochează" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Domeniu" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Șterge domeniul" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "Șterge tot" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Listă acces personalizată" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Permite" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Diverse" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "ÃŽncărcare rapidă haine CJ:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Viteză navigator:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Conexiune solitară:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Tag pachete:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Progres animaÈ›ie:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Prioritate proces:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Setări depanare:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Memorie streaming:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Tip de actualizare aplicaÈ›ie:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Instalează actualizările importante:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Activat" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Foarte înceată" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Implicit" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Rapidă" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normal" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Peste normal" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Minimă" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Maximă" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Compatibilitate Windows 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "culoare pe 16 biÅ£i" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Fixare mouse" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "FiÈ™iere resursă client:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Deschide în Explorer" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "Setează afinitate CPU 0 pentru îmbunătățirea performanÈ›ei jocului" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Actualizator automat" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Verifică pentru actualizări acum" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Unele setări vor fi schimbate când porneÅŸti MTA data viitoare" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Vrei să reporneÈ™ti acum?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "REPORNIRE NECESARÄ‚" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Unele setări vor fi modificate doar atunci când deconectaÈ›i serverul curent" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "DoriÈ›i să vă deconectaÈ›i acum?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "DECONECTARE NECESARÄ‚" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad nedetectat - Verifică conexiunile È™i reporneÈ™te jocul" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Axe de legătură" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "MiÈ™că o axă pentru a ataÈ™a sau apasă Esc pentru a anula" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Limbă:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Temă:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Preconfigurări:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Chat" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "ÃŽncărcare" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Culori" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Aspect" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "OpÈ›iuni" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Fundal Chat" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Text chat" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Fundal de inserare" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Text intrare" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Linii:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Scală:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Lățime:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Dimensiune" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "după" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "pentru" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "secunde" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Decolorare graduală" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Estompează liniile vechi" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Orizontal:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Vertical:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Aliniere text:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "Offset X:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Offset Y:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "PoziÅ£ie" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Stânga" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Centru" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Dreapta" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Deasupra" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Dedesubt" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Font" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Ascunde fundalul când nu tastezi" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Completare nickname cu tasta \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Permite serverului să evidenÈ›ieze fereastra" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Permite notificări" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Contur text negru/alb" @@ -1550,112 +1841,118 @@ msgstr "Contur text negru/alb" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Apasă o tastă pentru a ataÈ™a sau apasă Esc pentru a anula" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "ATAȘARE TASTÄ‚ PRIMARÄ‚" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "ATAȘARE TASTÄ‚ SECUNDARÄ‚" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "CONTROALE DE JOC GTA" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "CONTROALE MULTIPLAYER" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Numele tău conÈ›ine caractere invalide!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1099 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Meniu principal" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "ÃŽn-joc" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "RoÈ™u:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Verde:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Albastru:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Transparență:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Culoare" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Previzualizare" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Vă rugăm să vă deconectaÈ›i înainte de schimbarea limbii" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Te rugăm să te deconectezi înainte de a schimba tema" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Umbrele volumetrice pot cauza probleme pe unele calculatoare.\n\n" "EÈ™ti sigur că vrei să le activezi?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "AVERTISMENT DE PERFORMANȚĂ" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Trimiterea capturilor de ecran este necesară pentru anumite servere din motive anti-cheat.\n\n" "(Fereastra de chat È™i GUI-ul sunt excluse din captură)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "INFORMAÅ¢II CAPTURÄ‚ DE ECRAN" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "Unele scripturi pot reda sunete, cum ar fi radio, de pe internet.\n\n" "Dezactivarea acestei setări poate reduce traficul de date.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "SUNETE EXTERNE" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "Se pare că ai opÈ›iunea de conexiune Rich Presence activată.\n" -"DoreÈ™ti să permiÈ›i serverelor să-È™i partajeze datele?\n\n" -"Acest lucru include ID-ul tău unic." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "Rich Presence este moment activat.\n" +"DoreÈ™ti să permiÈ›i partajarea datelor cu serverele la care te conectezi?\n\n" +"Acestea includ client ID-ul tău Discord, È™i informaÈ›ii despre starea jocului." -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "CONSIMȚĂMÂNT PRIVIND PARTAJAREA DATELOR" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1665,11 +1962,7 @@ msgstr "Unele fiÈ™iere din directorul tău de date GTA:SA sunt modificate.\n" "TotuÈ™i, FIȘIERELE GTA:SA MODIFICATE SUNT BLOCATE DE MULTE SERVERE\n\n" "EÈ™ti sigur că vrei să le foloseÈ™ti?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "FIȘIERE GTA:SA MODIFICATE" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1679,552 +1972,253 @@ msgstr "\"DPI aware\" este o caracteristică experimentală ÅŸi\n" "PuteÈ›i întâmpina probleme grafice dacă activaÈ›i această opÈ›iune.\n\n" "Sigur doriÈ›i să activaÈ›i această opÈ›iune?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "FUNCÈšIE EXPERIMENTALÄ‚" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "Dezactivarea acestei opÈ›iuni este recomandată numai dacă întâmpini probleme de performanță.\n\n" "EÈ™ti sigur că doreÈ™ti să o dezactivezi?" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Vă rugăm introduceÈ›i un nume" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Introdu un nume care va fi folosit în joc.\n" "Acesta va fi numele tău în momentul în care te conectezi la È™i te joci pe un server." -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "FuncÈ›ionalitate foarte experimentală." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "OpreÈ™te blocările încărcărilor variaÈ›iilor de CJ (FoloseÈ™te 65 MB de memorie RAM în plus)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Routerele mai vechi pot necesita o viteză mai înceată de scanare." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Activează pentru a folosi o singură conexiune atunci când descarci." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "EtichetaÈ›i pachetele de reÈ›ea pentru a ajuta furnizorii de internet să identifice traficul MTA." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Indicator de progres animat în partea de jos a ecranului" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Alege 'Implicit' mereu. (Această setare nu este salvată)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maximul este de obicei cel mai bun" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Actualizator automat:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Selectează 'Implicit' dacă nu doreÈ™ti să completezi rapoarte de erori." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "SelectaÈ›i \"implicit\" pentru a instala automat actualizările importante." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "culoare pe 16 biÅ£i:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Activează modurile de culori pe 16 biÅ£i - Necesită repornirea MTA" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Fixare mouse:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Fixează miÅŸcarea mouseului - Poate necesita restartarea calculatorului" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "Afinitate CPU:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "Modifică doar dacă ai probleme de stabilitate." -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Comandă necunoscută sau cvar necunoscut: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Ocupat" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Nu se poate verifica pentru actualizări acum" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s necesar" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "O versiune mai actuală de MTA:SA %s este necesară pentru a juca pe serverul selectat.\n\n" -"EÈ™ti sigur că vrei să descarci È™i să instalezi MTA:SA %s?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Vrei să porneÈ™ti MTA:SA %s È™i să te conectezi la acest server?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Nu este posibil să te conectezi în acest moment.\n\n" -"ÃŽncearcă mai târziu." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Se conectează" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "AÈ™teaptă..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "SE VERIFICÄ‚" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "VERIFICARE ACTUALIZARE" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Nicio actualizare nu este necesară" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "SE DESCARCÄ‚" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "se aÈ™teaptă..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "ACTUALIZARE OBLIGATORIE" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Pentru a juca pe acest server trebuie să actualizezi MTA.\n\n" -"DoreÈ™ti să actualizezi acum?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "ACTUALIZARE OPÈšIONALÄ‚" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Serverul spune că o actualizare este recomandată, dar nu necesară.\n\n" -"DoreÈ™ti să actualizezi acum?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "Actualizarea nu este disponibilă momentan.\n\n" -"Te rugăm verifică www.multitheftauto.com" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "EROARE SALVARE" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Nu s-a putut crea fiÈ™ierul." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "EROARE DESCÄ‚RCARE" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "FiÈ™ierul descărcat pare să fie incorect." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Dintr-un anumit motiv." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "DESCÄ‚RCARE COMPLETÄ‚" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Problemă necunoscută în _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ok" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "EROARE" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Unele fiÈ™iere MTA:SA lipsesc.\n\n\n" -"Te rugăm să reinstalezi MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d%% complet" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Se aÈ™teaptă un răspuns - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Conectarea a eÈ™uat. Numele de utilizator specificat este invalid!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Conectarea a eÈ™uat. Hostul specificat este invalid!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Conectarea la %s cu portul %u a eÈ™uat!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Se conectează la %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "Reconectare la %s:%u ..." - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:667 -msgid "CONNECTING" -msgstr "SE CONECTEAZÄ‚" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1343 -msgid "Connection timed out" -msgstr "Conexiunea a expirat" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1391 -msgid "Disconnected: unknown protocol error" -msgstr "Deconectat: eroare de protocol necunoscută" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 -msgid "Disconnected: disconnected remotely" -msgstr "Deconectat: deconectat automat" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1399 -msgid "Disconnected: connection lost remotely" -msgstr "Deconectat: conexiune pierdută" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1403 -msgid "Disconnected: you are banned from this server" -msgstr "Deconectat: ai interdicÈ›ie pe acest server" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1411 -msgid "Disconnected: disconnected from the server" -msgstr "Deconectat: deconectat de la server" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1415 -msgid "Disconnected: connection to the server was lost" -msgstr "Deconectat: conexiunea la server a fost pierdută" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1423 -msgid "Disconnected: connection was refused" -msgstr "Deconectat: conectarea a fost refuzată" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Nu există asemena mod instalat (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Răspuns invalid de la server (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Răspuns invalid de la server (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "NOUTĂȚI" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "VizitaÈ›i cel mai recent articol" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "CONSOLÄ‚" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Eroare fatală" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "PENTRU A REMEDIA, ȘTERGE ACEST FIȘIER:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "Modulul %s este incorect!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Eroare la executarea URL-ului" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "acest ecran de ajutor" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "iese din aplicaÈ›ie" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "arată versiunea" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "arată timpul" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "arată HUD-ul" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "arată toate legăturile" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "arată serialul tău" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "te conectează la un server (host, port, nume, parolă)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "te conectează la un server precedent" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "ataÈ™ează o tastă (control de tastă)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "eliberează o tastă (tastă)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "ataÈ™ează controalele implicite din GTA" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "creează o captură de ecran" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" -msgstr "salvează configuraÈ›ia imediat" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "curăță ecranul de depanare" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "derulează fereastra de chat în sus" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "derulează fereastra de chat în jos" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "derulează ecranul de depanare în sus" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "derulează ecranul de depanare în jos" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "arată statisticile despre memorie" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "arată graficul cu timpii cadrului" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "pentru dezvoltatori: reîncărcaÈ›i noutățile" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ AJUTOR COMENZI ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Timpul este %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "conectare: ReÈ›eaua nu este gata, te rugăm aÈ™teaptă un moment" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "connect: Sintaxa este 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "connect: Numărul portului este incorect" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "connect: Se conectează la %s:%u..." +msgstr "salvează configuraÈ›ia imediat" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "connect: nu s-a putut realiza conexiunea la %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "curăță ecranul de depanare" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "connect: Dezactivarea modificării curente a eÈ™uat" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "derulează fereastra de chat în sus" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "reconectare: ReÈ›eaua nu este gata, te rugăm aÈ™teaptă un moment" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "derulează fereastra de chat în jos" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "reconectare: Număr port incorect" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "derulează ecranul de depanare în sus" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "reconectare: Se reconectează la %s:%u..." +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "derulează ecranul de depanare în jos" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "reconectare: nu s-a putut conecta la %s:%u!" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "arată statisticile despre memorie" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "FoloseÈ™te controalele din GTA" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "arată graficul cu timpii cadrului" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "FiÅŸierul cu configuraÅ£ia a fost salvat" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "pentru dezvoltatori: reîncărcaÈ›i noutățile" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Serialul tău este: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "FoloseÈ™ti un build de pe o ramură feature! Acesta este exclusiv un build de test È™i nu poate fi folosit pentru conectarea la servere publice!" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Axa de accelerare" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA nu va primi actualizări pe XP/Vista după luna Iulie 2019.\n\n" +"ActualizaÈ›i-vă versiunea de Windows pentru a juca pe cele mai recente servere." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Axa de frânare" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Acest lucru te va deconecta de la server.\n\n" +"EÈ™ti sigur că vrei să te deconectezi?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programare" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "AVERTISMENT DECONECTARE" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Contribuitori" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "INFORMAÈšIE" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Design de joc / Scripting" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "NOUTĂȚI" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Localizare limbă" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "VizitaÈ›i cel mai recent articol" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Contribuitori cu patchuri" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Captura de ecran a înregistrat %d baiÈ›i, dar erau de aÈ™teptat %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "MulÈ›umiri speciale" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Capturarea ecranului a eÈ™uat" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Acest program È™i proiect utilizează următoarele librării È™i programe:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Captură de ecran efectuată: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "DoriÈ›i ajutor online pentru această problemă ?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Comandă necunoscută sau cvar necunoscut: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2399,25 +2393,56 @@ msgid "Group control backwards" msgstr "Control de grup înapoi" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Tema selectată de tine nu a putut fi încărcată, iar tema implicită nu a putut fi nici ea încărcată, te rugăm reinstalează MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Captura de ecran a înregistrat %d baiÈ›i, dar erau de aÈ™teptat %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "DoriÈ›i ajutor online pentru această problemă ?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Capturarea ecranului a eÈ™uat" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "CONSOLÄ‚" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Captură de ecran efectuată: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programare" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Contribuitori" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Design de joc / Scripting" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Localizare limbă" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Contribuitori cu patchuri" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "MulÈ›umiri speciale" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Acest program È™i proiect utilizează următoarele librării È™i programe:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Axa de accelerare" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Axa de frânare" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2425,6 +2450,63 @@ msgstr "Nu s-a putut iniÈ›ializa Direct3D9.\n\n" "VerificaÈ›i dacă DirectX End-User Runtime È™i\n" "ultimele pachete de servicii ale Windows sunt instalate corect." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Inactiv" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "jucător" +msgstr[1] "jucători" +msgstr[2] "jucătoare" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "pornit" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "server" +msgstr[1] "servere" +msgstr[2] "de servere" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Se încarcă lista cu servere (au trecut %lu ms)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Lista cu servere nu a putut fi analizată." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Lista cu servere nu a putut fi găsită." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Rezervă a listei de servere)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "Nu se poate crea socket-ul LAN-broadcast" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Nu se poate ataÈ™a socketul LAN-broadcast" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Se încearcă descoperirea serverelor LAN" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2478,7 +2560,7 @@ msgstr "Latență:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Listă cu jucători" @@ -2505,40 +2587,39 @@ msgstr "Intră în joc imediat ce un slot este disponibil." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "INTRODU PAROLA SERVERULUI" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Sesiunea a expirat" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Se procesează..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "CÄ‚UTARE SERVERE" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Local" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Favorite" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Recente" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2546,300 +2627,367 @@ msgstr "PENTRU CONECTARE RAPIDÄ‚:\n\n" "Tastează adresa È™i portul în bara de adrese.\n" "Sau selectează un server din istoric È™i apasă 'Conectare'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "AJUTOR" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Reîmprospătează" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Adaugă la favorite" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Conectare" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "InformaÈ›ii despre server" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Caută servere" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Caută jucători" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "PorneÅŸte căutarea" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "Șterge din recente" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Caută jucători..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Caută servere..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Nume" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Jucători" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Ping" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Mod de joc" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Include:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Goale" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Pline" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Parolate" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Off-line" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Alte versiuni" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "ÃŽnapoi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Se încarcă..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "..se încarcă.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Nicio adresă specificată!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Protocol necunoscut!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Te rugăm să foloseÈ™ti protocolul mtasa://" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:651 -#: Client/mods/deathmatch/logic/CClientGame.cpp:749 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Numele ales este invaild! Te rugăm mergi la Setări È™i setează unul nou!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Trebuie să selectezi un server la care să te conectezi." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Inactiv" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problemă cu placa grafică" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "jucător" -msgstr[1] "jucători" -msgstr[2] "jucătoare" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Nu se poate găsi o rezoluÅ£ie validă a ecranului." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "pornit" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "EÅŸti sigur că vrei să foloseÅŸti această rezoluÅ£ie?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "server" -msgstr[1] "servere" -msgstr[2] "de servere" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "IniÈ›ializare game_sa eÈ™uată" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Se încarcă lista cu servere (au trecut %lu ms)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "Alocare memorie eÈ™uată" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Lista cu servere nu a putut fi analizată." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Solicitări website" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Lista cu servere nu a putut fi găsită." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Serverul solicită următoarele site-uri web pentru a le încărca (mai târziu):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Rezervă a listei de servere)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NU INTRODUCEÈšI NICIODATÄ‚ DATE PERSONALE, PENTRU A EVITA SÄ‚ FIE FURATE" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Nu se poate ataÈ™a socketul LAN-broadcast" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Memorează decizia" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Se încearcă descoperirea serverelor LAN" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Refuză" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Această versiune a expirat." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "deconectează-te de la joc" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "afiÅŸează numele" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "afiÈ™ează fereastra de chat" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "afiÈ™ează statisticile conexiunii" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "activează intrarea ferestrei de chat" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "transmite vocea către ceilalÈ›i jucători" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "intră în maÅŸină ca pasager" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "staÈ›ia radio următoare" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "staÈ›ia radio precedentă" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "activează harta jucătorului" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "măreÈ™te harta jucătorului" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "micÈ™orează harta jucătorului" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "mută harta jucătorului la nord" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "mută harta jucătorului la sud" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "mută harta jucătorului la est" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "mută hartă jucătorului la vest" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "ataÈ™ează harta jucătorului" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "reduce opacitatea hărÈ›ii jucătorului" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "măreÈ™te opacitatea hărÈ›ii jucătorului" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "comută text ajutor hartă jucător" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "trimite un mesaj jucătorului specificat" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "schimbă la arma următoare în timp ce eÈ™ti într-un vehicul" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "schimbă la arma precedentă în timp ce eÈ™ti într-un vehicul" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "afiÈ™ează informaÈ›ii despre serverul curent" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "defineÈ™te multiplicatorul de scară al tuturor afiÈ™ajelor de text" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Mod de dezvoltare) afiÈ™ează toate poliedrele de coliziune" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Mod de dezvoltare) afiÈ™ează numărul de identificare al sunetelor în fereastra de depanare" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "GÄ‚ZDUIRE JOC" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Resurse" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Nume server:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Parolă:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Număr sloturi:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Transmisie:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Selectate" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Toate" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Lansează" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "Schimbă mod: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "MăreÈ™te: %s/%s MiÈ™care: %s, %s, %s, %s Opacitate: %s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "Comutare hartă: %s Comutare text ajutor: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "Urmărire jucător" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "MiÈ™care liberă" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Progresul descărcării hărÈ›ii:" @@ -2860,174 +3008,174 @@ msgstr "%s din %s" msgid "Disconnect to cancel download" msgstr "Deconectează-te pentru a anula descărcarea" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Deconectat: Nume invalid" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Deconectează-te de la server" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Deconectat: Serialul tău are interdicÈ›ie.\n" "Motiv: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Deconectat: Ai interdicÈ›ie.\n" "Motiv: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Deconectat: Contul este banat.\n" "Motiv: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Deconectat: Nepotrivire de versiune" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Deconectat: Server supraîncărcat. Te rugăm aÈ™teaptă un minut, apoi reconectează-te." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Deconectat: Serverul este dintr-o branșă diferită.\n" "InformaÈ›ii: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Deconectat: Versiune incorectă.\n" "InformaÈ›ii: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Deconectat: Serverul rulează o versiune mai nouă.\n" "InformaÈ›ii: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Deconectat: Serverul rulează o versiune mai veche.\n" "InformaÈ›ii: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Deconectat: Numele tău este deja folosit" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Deconectat: elementul Player nu a putut fi creat." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Deconectat: Serverul a refuzat conexiunea: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Deconectat: Verificarea serialului a eÈ™uat" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "Deconectat: Serial deja în folosință" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Deconectat: Desincronizare de conexiune %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Deconectat: Ai fost dat afară de către %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Deconectat: Ai primit interdicÈ›ie de la %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Deconectat: Serverul a fost închis sau repornit" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Ai fost dat afară din joc" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Acest server nu permite modificări ale fiÈ™ierului gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Te rugăm să înlocuieÈ™ti gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Acest server nu permite modificarea fiÈ™ierului D3D9.DLL" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "EliminaÈ›i D3D9.DLL din directorul de instalare GTA È™i reporniÈ›i MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Acest server nu permite maÈ™ini virtuale" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Acest server necesită activarea driverelor semnate" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Te rugăm să reporneÈ™ti computerul" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Acest server a detectat componente anti-cheat lipsă" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "ÃŽncercaÈ›i să reporniÈ›i MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Acest server nu permite conectarea cu fiÈ™iere gta3.img sau gta_int.img modificate" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Vă rugăm să înlocuiÅ£i gta3.img sau gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Acest server nu permite utilizarea Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "AsiguraÈ›i-vă că niciun alt program nu modifică MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Timp rămas: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" @@ -3035,7 +3183,7 @@ msgstr[0] "%d zi" msgstr[1] "%d zile" msgstr[2] "%d de zile" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" @@ -3043,7 +3191,7 @@ msgstr[0] "%d oră" msgstr[1] "%d ore" msgstr[2] "%d de ore" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" @@ -3051,7 +3199,7 @@ msgstr[0] "%d minut" msgstr[1] "%d minute" msgstr[2] "%d de minute" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3060,296 +3208,206 @@ msgstr[1] "%d secunde" msgstr[2] "%d de secunde" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Deconectat" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Eroare de descărcare: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "Pilotează un UFO prin" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "ÃŽn plimbare prin" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "Navigând pe valurile" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "Călătorind cu trenul în" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "Zboară prin" -#: Client/mods/deathmatch/logic/CClientGame.cpp:381 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "Călătorind prin" -#: Client/mods/deathmatch/logic/CClientGame.cpp:381 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "Cu Monster Truck-ul prin" -#: Client/mods/deathmatch/logic/CClientGame.cpp:381 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "Quaddin' prin" -#: Client/mods/deathmatch/logic/CClientGame.cpp:382 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "Bunny hopping prin" -#: Client/mods/deathmatch/logic/CClientGame.cpp:382 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "Face lucruri ciudate prin" -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "Se cațără în jurul" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "Făcând un drive-by în" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "Blub blub..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "Respiră apă" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "Se îneacă în" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "Ghemuit în cover în" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "Se luptă în" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "Aruncând pumni în" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "ÃŽmpuÈ™când fraieri în" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "Trage cu arma" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "Cu jetpack-ul în" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "Literalmente arde în" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "Arde în" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "ÃŽnoată în" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "Gravitează prin jurul" -#: Client/mods/deathmatch/logic/CClientGame.cpp:402 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "Urmărit de un rechin" -#: Client/mods/deathmatch/logic/CClientGame.cpp:403 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "Se îneacă până la moarte" -#: Client/mods/deathmatch/logic/CClientGame.cpp:667 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Se intră în joc ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:725 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Neconectat; te rugăm foloseÈ™te conectarea rapidă sau comanda 'connect' pentru a te conecta la un server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:771 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Nu s-a putut lansa serverul local. Vezi consola pentru detalii." -#: Client/mods/deathmatch/logic/CClientGame.cpp:781 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1253 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Server local" -#: Client/mods/deathmatch/logic/CClientGame.cpp:781 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Se porneÈ™te serverul local ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1029 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "Zona 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1038 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "Plimbându-se prin " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1184 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Ai fost dat afară din joc (%s)" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1253 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Se conectează la serverul local..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1264 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Eroare la conectarea la server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Conectarea la serverul local a expirat. Vezi consola pentru detalii." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Conexiunea cu serverul s-a pierdut" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1407 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Deconectat: serverul este momentan plin" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1419 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Deconectat: parola specificată este invalidă" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1441 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "Verificarea clientului MTA a eÈ™uat!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5642 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "ÃŽntr-un impas" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5642 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "ÃŽn drum spre spital" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5642 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "ÃŽntâlnindu-È™i creatorul" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5643 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "Regretându-È™i deciziile" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5643 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "Wasted" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "GÄ‚ZDUIRE JOC" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Resurse" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Nume server:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Parolă:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Număr sloturi:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Transmisie:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Selectate" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Toate" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Lansează" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "Schimbă mod: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "MăreÈ™te: %s/%s MiÈ™care: %s, %s, %s, %s Opacitate: %s/%s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "Comutare hartă: %s Comutare text ajutor: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "Urmărire jucător" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "MiÈ™care liberă" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problemă cu placa grafică" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Nu se poate găsi o rezoluÅ£ie validă a ecranului." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "EÅŸti sigur că vrei să foloseÅŸti această rezoluÅ£ie?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "IniÈ›ializare game_sa eÈ™uată" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "Alocare memorie eÈ™uată" +msgid "Download error: %s" +msgstr "Eroare de descărcare: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3370,11 +3428,11 @@ msgstr "Eroare de protocol (%u). Dacă această problemă persistă, te rugăm v msgid "Connection error" msgstr "Eroare de conexiune" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto nu a fost instalat corect, te rugăm reinstalează-l." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Navigatorul tău va afiÈ™a acum o pagină web cu informaÈ›ii ajutătoare.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/ru_RU/client.pot b/Shared/data/MTA San Andreas/MTA/locale/ru_RU/client.pot index 02b35dfe0ae..3b730378f30 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/ru_RU/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/ru_RU/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Russian\n" "Language: ru_RU\n" @@ -17,71 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Проблема перезапуÑка MTA:SA\n\n" -"ЕÑли проблема ÑохранилаÑÑŒ, то откройте диÑпетчер задач и оÑтановите процеÑÑÑ‹ 'gta_sa.exe' и 'Multi Theft Auto.exe' \n\n\n" -"Попробовать запуÑтить MTA:SA Ñнова?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "ЗапуÑтите Grand Theft Auto: San Andreas.\n" +"УбедитеÑÑŒ, что игра помещена в папку \"Program Files (x86)\"." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Ошибка" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "ПоиÑк игрового процеÑÑа: GTA: San Andreas" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Другой процеÑÑ Ñ MTA уже запущен.\n\n" -"ЕÑли проблема не решена, попробуйте перезагрузить ваш компьютер" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Извините, игра не найдена.\n" +"ЗапуÑтите Grand Theft Auto: San Andreas и нажмите повторить попытку.\n" +"УбедитеÑÑŒ, что игра находитÑÑ Ð² папке \"Program Files (x86)\"." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Другой процеÑÑ MTA уже запущен.\n\n" -"Ð’Ñ‹ хотите завершить Ñтот процеÑÑ?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Выберите директорию Ñ Grand Theft Auto: San Andreas" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA нужны права ÐдминиÑтратора Ð´Ð»Ñ Ñледующей задачи:\n\n" +"'%s'\n\n" +"ПожалуйÑта, подтвердите в Ñледующем окне." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Ошибка загрузки %s модулÑ! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Копирование файлов..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Копирование завершено. Ð’Ñе в порÑдке." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Завершение..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Готово!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "ÐÐ¾Ð²Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° %s обнаружена.\n\n" +"Ð’Ñ‹ хотите Ñкопировать ваши наÑтройки из %s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA не Ñмогла открыть файл '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA не нашла файл '%s'" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA не Ñмогла загрузить модель." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "ЕÑли вы недавно модифицировали gta3.img, попробуйте переуÑтановить GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA не Ñмогла добавить апгрейд транÑпортному ÑредÑтву." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA нашла ошибки в файле '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Ваш компьютер перезагрузилÑÑ Ð²Ð¾ Ð²Ñ€ÐµÐ¼Ñ Ð¸Ð³Ñ€Ñ‹ в MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Завершите Ñледующие программы Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "Обнаружен недопуÑтимый путь к модулю." + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Ошибка верÑий файлов. ПереуÑтановите MTA:SA Ð´Ð»Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ñ‹.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Ðекоторые файлы повреждены. ПереуÑтановите MTA во избежание проблем.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA не работает в 'БезопаÑном режиме'.\n\n" +"ПерезапуÑтите ваш компьютер.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "У Ð²Ð°Ñ ÐµÑть проблемы Ñ Ð·Ð°Ð¿ÑƒÑком MTA:SA?.\n\n" "Попробовать откатитьÑÑ Ðº ранней верÑии?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -89,48 +143,48 @@ msgstr "Возникли проблемы Ñ Ð·Ð°Ð¿ÑƒÑком MTA:SA. \n" "Ð¡Ð±Ñ€Ð¾Ñ Ð½Ð°Ñтроек GTA, возможно, уÑтранит Ñту проблему..\n\n" "Ð’Ñ‹ хотите ÑброÑить наÑтройки GTA?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "ÐаÑтройки GTA Ñброшены.\n\n" "Ðажмите OK, чтобы продолжить." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Файл не может быть удален. '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Возникли проблемы Ñ Ð·Ð°Ð¿ÑƒÑком MTA:SA? .\n\n" "Хотите поÑмотреть онлайн помощь?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "У Ð²Ð°Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ñ‹ Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¾Ð¹ MTA:SA?\n\n" "Ð’Ñ‹ хотите изменить текущие наÑтройки?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "ПолноÑкранный режим:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Окно в рамке" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "У Ð²Ð°Ñ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ»Ð¸ проблемы Ñ Ð·Ð°Ð¿ÑƒÑком MTA:SA?\n\n" "Попробуйте выключить Ñледующие продукты Ð´Ð»Ñ MTA и GTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -138,132 +192,296 @@ msgstr "Ð’ÐИМÐÐИЕ\n\n" "MTA:SA обнаружил подозрительную активноÑть.\n" "Проверьте вашу ÑиÑтему на наличие вируÑов, чтобы убедитьÑÑ Ð² безопаÑноÑти.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Был обнаружен файл: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Ðеобходимо завершить процеÑÑ GTA: San Andreas перед запуÑком MTA:SA. Сделать Ñто ÑейчаÑ?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "ИнформациÑ" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Ðевозможно завершить процеÑÑ GTA: San Andreas. ЕÑли проблема ÑохранилаÑÑŒ, то попробуйте перезагрузить ваш компьютер." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Проблема перезапуÑка MTA:SA\n\n" +"ЕÑли проблема ÑохранилаÑÑŒ, то откройте диÑпетчер задач и оÑтановите процеÑÑÑ‹ 'gta_sa.exe' и 'Multi Theft Auto.exe' \n\n\n" +"Попробовать запуÑтить MTA:SA Ñнова?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Ошибка" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Другой процеÑÑ Ñ MTA уже запущен.\n\n" +"ЕÑли проблема не решена, попробуйте перезагрузить ваш компьютер" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Другой процеÑÑ MTA уже запущен.\n\n" +"Ð’Ñ‹ хотите завершить Ñтот процеÑÑ?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "ОтÑутÑтвуют необходимые запиÑи в рееÑтре. ПереуÑтановите Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Путь к папке Ñ Ð²Ð°ÑˆÐµÐ¹ GTA: San Andreas имеет неподдерживаемые Ñимволы (юникод). Измените путь к Grand Theft Auto: San Andreas, чтобы в нём были только ASCII Ñимволы и переуÑтановите Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Путь к папке MTA:SA или GTA: San Andreas\n" -"имеет Ñимвол ';' (точку Ñ Ð·Ð°Ð¿Ñтой).\n\n" -"ПереуÑтановите MTA:SA и GTA: San Andreas, так, чтобы в \n" -"пути до папок не было точки Ñ Ð·Ð°Ð¿Ñтой." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "Путь к вашей уÑтановке MTA:SA или GTA: San Andreas\n" +"Ñодержит Ñимвол ';' (точка Ñ Ð·Ð°Ð¿Ñтой).\n\n" +"ЕÑли у Ð²Ð°Ñ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½ÑƒÑ‚ проблемы при запуÑке MTA:SA,\n" +"перемеÑтите вашу уÑтановку в путь, который не Ñодержит точки Ñ Ð·Ð°Ð¿Ñтой." + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "Обнаружены недопуÑтимые пути уÑтановки." + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Ошибка запуÑка, проверьте правильноÑть уÑтановки поÑледних data-файлов." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Загрузка не удалаÑÑŒ. УбедитеÑÑŒ что %s уÑтановлен правильно." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Загрузка не удалаÑÑŒ, поÑкольку gta_sa.exe не был найден в %s" -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Загрузка не удалаÑÑŒ. Удалите файл %s в папке GTA перед запуÑком." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "У оÑновного файла неверное Ð¸Ð¼Ñ (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "ОÑновной файл не подпиÑан. Возможна вируÑÐ½Ð°Ñ ÑƒÐ³Ñ€Ð¾Ð·Ð°.\n\n" -"ИÑпользуйте онлайн помощь, еÑли MTA работает некорректно" - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Ð’ файле %s отÑутÑтвуют данные. Возможно, вируÑное заражение.\n\n" -"Попробуйте переуÑтановить Multi Theft Auto Ð´Ð»Ñ Ð’Ð°ÑˆÐµÐ¹ безопаÑноÑти.\n" -"Смотрите помощь в интернете, еÑли МТРбудет работать некорректно." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "ОтÑутÑтвует файл %s. Возможна вируÑÐ½Ð°Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾Ñть." + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Ð’ файле %s изменены данные. Возможно, вируÑное заражение.\n\n" -"Попробуйте переуÑтановить Multi Theft Auto Ð´Ð»Ñ Ð’Ð°ÑˆÐµÐ¹ безопаÑноÑти.\n" -"Смотрите помощь в интернете, еÑли МТРбудет работать некорректно." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "Файлы Ñ Ñ€Ð°Ñширением .asi уÑтановлены в папку Ñ GTA San Andreas или MTA SA.\n\n" -"Удалите файлы Ñ Ñ€Ð°Ñширением .asi во избежание проблем Ñ MTA SA." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Ошибка верÑий файлов. ПереуÑтановите MTA:SA Ð´Ð»Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ñ‹.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "Файл %s изменён. Возможна вируÑÐ½Ð°Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾Ñть." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Ðекоторые файлы повреждены. ПереуÑтановите MTA во избежание проблем.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "Ð’ каталоге уÑтановки найдены файлы .asi.\n\n" +"Удалите файлы .asi, еÑли у Ð²Ð°Ñ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÑŽÑ‚ проблемы." -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA не работает в 'БезопаÑном режиме'.\n\n" -"ПерезапуÑтите ваш компьютер.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "Обнаружены недопуÑтимые пути к игре." -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "ИÑправить проблему конфигурации" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Ошибка при иÑправлении ошибки." +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "GTA: San Andreas возможно запуÑтилаÑÑŒ некорректно. Завершить её работу?" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "ÐеизвеÑтно" + +#: Client/loader/Install.cpp:272 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Ðевозможно запуÑтить Grand Theft Auto: San Andreas. Попробуйте перезапуÑтить. ЕÑли проблема не решена, то обратитеÑÑŒ за помощью на Ñайте www.multitheftauto.com. \n\n" -"[%s]" +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "Файл %s иÑпользуетÑÑ %zu.\n\n" +"Ð’Ñ‹ хотите завершить Ñтот процеÑÑ Ð¸ продолжить обновление?\n\n" +"%s" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "ПроцеÑÑ GTA: San Andreas не может быть запущен правильно. Ð’Ñ‹ хотите завершить его?" +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "УÑтановка может быть повреждена.\n\n" +"%zu из %zu файлов не удалоÑÑŒ воÑÑтановить из резервной копии.\n" +"ПереуÑтановите Multi Theft Auto Ñ Ñайта www.multitheftauto.com\n" +"или запуÑтите обновление от имени админиÑтратора." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "УÑтановка обновлениÑ..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Извлечение файлов..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA не может выполнить Ñледующую задачу:\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Вылет был вызван ошибкой графичеÑкого драйвера **\n\n" +"** Обновите драйвера вашей видеокарты **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "** ÐедоÑтаточно памÑти — Ñбой вызван нехваткой Ñвободной или фрагментированной памÑти. **" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "УÑтановка обновлённых MTA:SA файлов" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Ðевозможно обновитьÑÑ, так как файлы занÑты другими приложениÑми, закройте их и попробуйте Ñнова" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto уÑтановлена неправильно, переуÑтановите. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "Создание GTA:SA ÑоединениÑ" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA не может запуÑтитьÑÑ, потому что копирование файлов неудачно:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA не может запуÑтитьÑÑ Ð¿Ð¾Ñ‚Ð¾Ð¼Ñƒ что MTA:SA файл некорректен или отÑутÑтвует:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Копирование MTA:SA файлов" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA не может запуÑтитьÑÑ Ð¿Ð¾Ñ‚Ð¾Ð¼Ñƒ что GTA:SA файл некорректен или пропал:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "ЗавиÑимоÑть от иÑправлений GTA:SA" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA не может запуÑтитьÑÑ Ð¿Ð¾Ñ‚Ð¾Ð¼Ñƒ что GTA:SA иÑполнÑемый файл неверен или отÑутÑтвует:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "ПожалуйÑта, проверьте Ð°Ð½Ñ‚Ð¸Ð²Ð¸Ñ€ÑƒÑ Ð½Ð° предмет ложного обнаружениÑ, попробуйте добавить gta_sa.exe в иÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸ перезапуÑтить MTA:SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "Сгенерировать GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA не удаетÑÑ Ð·Ð°Ð¿ÑƒÑтить, поÑкольку иÑполнÑемый файл GTA:SA недоÑтупен Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Патч GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA не удаетÑÑ Ð·Ð°Ð¿ÑƒÑтить из-за ÑÐ±Ð¾Ñ ÑƒÑтановки патча GTA:SA:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "ÐедоÑтаточно меÑта на диÑке %s Ð´Ð»Ñ ÑƒÑтановки MTA:SA." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Ðе найден файл:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "ПереуÑтановите GTA:SA, еÑли MTA не запуÑкаетÑÑ" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Обновление наÑтроек уÑтановки" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Обновить наÑтройки ÑовмеÑтимоÑти" #. ///////////////////////////////////////////////////////////////////////// #. @@ -271,167 +489,167 @@ msgstr "ПроцеÑÑ GTA: San Andreas не может быть запущен #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Да" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Ðет" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "ОК" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Выйти" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Помощь" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Отмена" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas обнаружила ошибку" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± аварийном завершении программы" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "ПоÑтавьте галочку Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ разработчикам информации через интернет о падении MTA." -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Это повыÑит шанÑÑ‹ на уÑтранение данной ошибки" -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Ð’Ñ‹ хотите перезапуÑтить MTA: San Andreas ?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Предупреждение" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "Ð”Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ñ Grand Theft Auto: San Andreas Ñодержит файл:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." -msgstr "Эти файлы не требуютÑÑ Ð¸ могут конфликтовать Ñ Ð³Ñ€Ð°Ñ„Ð¸Ñ‡ÐµÑкими оÑобенноÑÑ‚Ñми в данной верÑии MTA:SA.\n\n" +msgstr "Эти файлы не ÑвлÑÑŽÑ‚ÑÑ Ð¾Ð±Ñзательными и могут мешать работе графичеÑких функций данной верÑии MTA:SA.\n\n" "РекомендуетÑÑ Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ñ‚ÑŒ или удалить Ñти файлы." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "ОÑтавить данные файлы, а также отобразить Ñто предупреждение при Ñледующем запуÑке" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Больше не Ñпрашивать об Ñтих файлах" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Переименовать данные файлы из *.dll в *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Показать Ñти файлы" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Играть в MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Сбитые наÑтройки" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "Обнаружен NVidia Optimus!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Попробуйте каждую опцию и поÑмотрите, что работает:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Стандартный NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Ðльтернативный NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" -msgstr "C - Стандарт интел" +msgstr "C - Стандарт Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" -msgstr "D - Ðльтернативный интел" +msgstr "D - Ðльтернативный Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "ЕÑли вы отчаÑлиÑÑŒ, то Ñто может помочь: " -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "ЕÑли вы уже выбирали работающую опцию, Ñто может помочь:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Принудительный оконный режим" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Ðе показывать Ñнова" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Внимание: Ðе удалоÑÑŒ обнаружить антивируÑ" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -439,1109 +657,1184 @@ msgstr "MTA не может обнаружить Ð°Ð½Ñ‚Ð¸Ð²Ð¸Ñ€ÑƒÑ Ð½Ð° ваш "ВируÑÑ‹ могут вмешиватьÑÑ Ð² работу MTA и портить вам игру.\n\n" "Ðажмите 'Помощь' Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾Ð¹ информации." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Я уже уÑтановил антивируÑ" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Я не буду уÑтанавливать антивируÑ.\n" "Я готов к риÑку Ñтать чаÑтью бот-Ñети и лагов." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "Сбой произошёл из-за чрезмерного иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð°Ð¼Ñти Ñерверами.\n\n" +"Даже при наличии большого объёма оперативной памÑти Ñта игра x86 Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð½Ñ‹Ð¼ адреÑным проÑтранÑтвом до 3,6 ГБ, и некоторые Ñильно неоптимизированные Ñерверы Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ð¼ количеÑтвом модов/реÑурÑов (или даже Ñ Ð½ÐµÑколькими плохо напиÑанными Ñкриптами) могут вызвать такую проблему, а также вызывать лаги в игре.\n\n" +"СвÑжитеÑÑŒ Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ¼ Ñервера или поддержкой MTA в официальном Discord (https://discord.gg/mtasa\n" +") Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации." + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "MTA: San Andreas - Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ нехватке памÑти" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "ПоиÑк Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "ЗапуÑтите Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "УÑтановка обновлениÑ..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Подключение не удалоÑÑŒ. Ðекорректное Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Извлечение файлов..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Ðе удалоÑÑŒ подключитÑÑ. Ðеверный Ð°Ð´Ñ€ÐµÑ Ñервера!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Копирование файлов..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Подключение на %s Ñ Ð¿Ð¾Ñ€Ñ‚Ð¾Ð¼ %u не удалоÑÑŒ!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Копирование завершено. Ð’Ñе в порÑдке." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Подключение к %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Завершение..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "Повторное подключение к %s:%u ..." -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Готово!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "ПОДКЛЮЧЕÐИЕ" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA нужны права ÐдминиÑтратора Ð´Ð»Ñ Ñледующей задачи:\n\n" -"'%s'\n\n" -"ПожалуйÑта, подтвердите в Ñледующем окне." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸Ñтекло" + +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Отключено: неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° протокола" + +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Отключено: удалённое отключение" + +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Отключение: потерÑно удаленное Ñоединение" + +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Отключение: вы забанены на Ñтом Ñервере" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Отключено: отключен от Ñервера" -#: Client/loader/CInstallManager.cpp:376 +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Отключено: ÑвÑзь Ñ Ñервером была потерÑна" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Отключено: Ñоединение было Ñброшено" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA не может выполнить Ñледующую задачу:\n\n" -" '%s'\n" +msgid "No such mod installed (%s)" +msgstr "Ðе уÑтановлен модуль (%s)" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Вылет был вызван ошибкой графичеÑкого драйвера **\n\n" -"** Обновите драйвера вашей видеокарты **" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Ðеверный ответ Ñервера (2)" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "УÑтановка обновлённых MTA:SA файлов" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Ðеверный ответ Ñервера (1)" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Ðевозможно обновитьÑÑ, так как файлы занÑты другими приложениÑми, закройте их и попробуйте Ñнова" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "РуÑÑкий" + +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "ЗанÑто" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Ðевозможно проверить Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð² данный момент" + +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto уÑтановлена неправильно, переуÑтановите. %s" +msgid "MTA:SA %s required" +msgstr "ТребуетÑÑ MTA:SA %s" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "Создание GTA:SA ÑоединениÑ" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "ТребуетÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ до MTA:SA %s, чтобы приÑоединитьÑÑ Ðº выбранному Ñерверу.\n\n" +"Ð’Ñ‹ хотите загрузить и уÑтановить MTA:SA %s?" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA не может запуÑтитьÑÑ, потому что копирование файлов неудачно:" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Ð’Ñ‹ уверены, что хотите запуÑтить MTA:SA %s и приÑоединитьÑÑ Ðº Ñтому Ñерверу?" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA не может запуÑтитьÑÑ Ð¿Ð¾Ñ‚Ð¾Ð¼Ñƒ что MTA:SA файл некорректен или отÑутÑтвует:" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Подключение ÑÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾.\n\n" +"Повторите попытку позже." -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Копирование MTA:SA файлов" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Подключение" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA не может запуÑтитьÑÑ Ð¿Ð¾Ñ‚Ð¾Ð¼Ñƒ что GTA:SA файл некорректен или пропал:" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "ПожалуйÑта, подождите..." -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "ЗавиÑимоÑть от иÑправлений GTA:SA" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "ПРОВЕРКÐ" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA не может запуÑтитьÑÑ Ð¿Ð¾Ñ‚Ð¾Ð¼Ñƒ что GTA:SA иÑполнÑемый файл неверен или отÑутÑтвует:" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "ПРОВЕРКРОБÐОВЛЕÐИЙ" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "ПожалуйÑта, проверьте Ð°Ð½Ñ‚Ð¸Ð²Ð¸Ñ€ÑƒÑ Ð½Ð° предмет ложного обнаружениÑ, попробуйте добавить gta_sa.exe в иÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸ перезапуÑтить MTA:SA." +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Ð’ обновлении нет необходимоÑти" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Сгенерировать GTA:SA" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "ЗÐГРУЗКÐ" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA не удаетÑÑ Ð·Ð°Ð¿ÑƒÑтить, поÑкольку иÑполнÑемый файл GTA:SA недоÑтупен Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸:" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "ожидание..." -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Патч GTA:SA" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "ОБЯЗÐТЕЛЬÐОЕ ОБÐОВЛЕÐИЕ" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA не удаетÑÑ Ð·Ð°Ð¿ÑƒÑтить из-за ÑÐ±Ð¾Ñ ÑƒÑтановки патча GTA:SA:" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Чтобы войти на Ñервер, вы должны обновить MTA.\n\n" +" Обновить ÑейчаÑ?" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "ÐедоÑтаточно меÑта на диÑке %s Ð´Ð»Ñ ÑƒÑтановки MTA:SA." +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "ДОПОЛÐИТЕЛЬÐОЕ ОБÐОВЛЕÐИЕ" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Ðе найден файл:" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Сервер предлагает обновить клиент, но Ñто не обÑзательно.\n\n" +"Ð’Ñ‹ хотите обновить?" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "ПереуÑтановите GTA:SA, еÑли MTA не запуÑкаетÑÑ" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ недоÑтупно.\n\n" +"ПожалуйÑта, проверьте www.multitheftauto.com" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Обновление наÑтроек уÑтановки" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "ОШИБКРСОХРÐÐЕÐИЯ" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Обновить наÑтройки ÑовмеÑтимоÑти" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Ðе удаётÑÑ Ñоздать файл." -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "ÐеизвеÑтно" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "ОШИБКРЗÐГРУЗКИ" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "Файл '%s' иÑпользуетÑÑ %zu.\n" -"Ð’Ñ‹ хотите завершить Ñтот процеÑÑ Ð¸ продолжить обновление?" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Загруженный файл некорректен." -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "УÑтановка может быть повреждена.\n\n" -"%zu из %zu файлов не удалоÑÑŒ воÑÑтановить из резервной копии.\n" -"ПереуÑтановите Multi Theft Auto Ñ Ñайта www.multitheftauto.com\n" -"или запуÑтите обновление от имени админиÑтратора." +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "По некоторым причинам." -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "ЗапуÑтите Grand Theft Auto: San Andreas.\n" -"УбедитеÑÑŒ, что игра помещена в папку \"Program Files (x86)\"." +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "ЗÐГРУЗКРЗÐВЕРШЕÐÐ" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "ПоиÑк игрового процеÑÑа: GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° в _DialogUpdateResult" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Извините, игра не найдена.\n" -"ЗапуÑтите Grand Theft Auto: San Andreas и нажмите повторить попытку.\n" -"УбедитеÑÑŒ, что игра находитÑÑ Ð² папке \"Program Files (x86)\"." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "МОДИФИЦИРОВÐÐÐЫЕ ФÐЙЛЫ GTA:SA" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Выберите директорию Ñ Grand Theft Auto: San Andreas" +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ок" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Ошибка загрузки %s модулÑ! (%s)" +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "ОШИБКÐ" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "ÐÐ¾Ð²Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° %s обнаружена.\n\n" -"Ð’Ñ‹ хотите Ñкопировать ваши наÑтройки из %s ?" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Ðекоторые MTA:SA файлы отÑутÑтвуют.\n\n\n" +"ПереуÑтановите MTA:SA." -#: Client/loader/Utils.cpp:1538 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA не Ñмогла открыть файл '%s'" +msgid "%3d %% completed" +msgstr "Загружено %3d %%" -#: Client/loader/Utils.cpp:1560 +#: Client/core/CVersionUpdater.cpp:2840 #, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA не нашла файл '%s'" - -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA не Ñмогла загрузить модель." - -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "ЕÑли вы недавно модифицировали gta3.img, попробуйте переуÑтановить GTA:SA." +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +" Ожидание ответа - %-3d" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA не Ñмогла добавить апгрейд транÑпортному ÑредÑтву." +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ ПОМОЩЬ ПО КОМÐÐДÐМ ]***\n" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CCommandFuncs.cpp:158 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA нашла ошибки в файле '%s'" - -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Ваш компьютер перезагрузилÑÑ Ð²Ð¾ Ð²Ñ€ÐµÐ¼Ñ Ð¸Ð³Ñ€Ñ‹ в MTA:SA?" - -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Завершите Ñледующие программы Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ:" +msgid "* The time is %d:%02d:%02d" +msgstr "* ВремÑ: %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ðº Ñайту" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "Соединение: Сеть не готова, пожалуйÑта, подождите немного" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Сервер делает запроÑÑ‹ к Ñледующим Ñайтам, Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾ чтобы загрузить их позднее:" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "ИÑпользуйте 'connect <адреÑ> [<порт> <ник> <пароль>]' Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "ÐЕ ВВОДИТЕ КОÐФИДЕÐЦИÐЛЬÐЫХ ДÐÐÐЫХ, ДÐБЫ ЗÐЩИТИТЬ ИХ ОТ КРÐЖИ" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "подключение: Ðеверный порт" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Запомнить решение" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "Подключение: Подключение к %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Разрешить" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "Подключение к %s:%u не удалоÑÑŒ!" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Запретить" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "подключение: Ðе удалоÑÑŒ выгрузить текущий мод" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "Главное меню" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "Переподключение: Сеть не готова, пожалуйÑта, подождите немного" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Ð’Ñ‹ иÑпользуете feature-branch разработку! Это теÑÑ‚Ð¾Ð²Ð°Ñ Ñборка, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð½Ðµ может иÑпользоватьÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº публичным Ñерверам!" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "Переподключение: неверный номер порта" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA не будет получать Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð° XP/Vista поÑле Ð¸ÑŽÐ»Ñ 2019.\n\n" -"Обновите Windows, чтобы играть на Ñерверах Ñ Ð¿Ð¾Ñледним обновлением." +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "Переподключение: Подключение к %s:%u..." -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Это дейÑтвие приведёт к отключению от текущего Ñервера.\n\n" -"Ð’Ñ‹ дейÑтвительно хотите отключитьÑÑ?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "Переподключение: к %s:%u не удалоÑÑŒ!" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "ПРЕДУПРЕЖДЕÐИЕ ОТКЛЮЧЕÐИЯ" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Скопировать управление из GTA" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "ИÐФОРМÐЦИЯ" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Файл конфигурации Ñохранен" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "РуÑÑкий" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Ваш Ñерийный номер: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "ÐÐСТРОЙКИ" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Мультиплеер" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Графика" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "ПоÑÑ‚ Ñффекты" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Звук" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Клавиши" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Управление" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "ИнтерфейÑ" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Браузер" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Дополнительные" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Загрузить Ñтандартные" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "ЧувÑтвительноÑть мыши:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Ð’ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ñ‡ÑƒÐ²ÑтвительноÑть мыши:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "ÐаÑтройки мыши" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "ИнверÑÐ¸Ñ Ð¼Ñ‹ÑˆÐ¸ по вертикали" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Управление транÑпортом Ñ Ð¼Ñ‹ÑˆÐ¸" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Управление полётом Ñ Ð¼Ñ‹ÑˆÐ¸" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "ИÑпользовать чувÑтвительноÑть мыши при прицеливании" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "ÐаÑтройки джойÑтика" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Стандартное управление (Мышь + Клавиатура)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "КлаÑÑичеÑкое управление (ДжойÑтик)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "ÐœÐµÑ€Ñ‚Ð²Ð°Ñ Ð·Ð¾Ð½Ð°" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "ÐаÑыщенноÑть" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Зайдите во вкладку 'Клавиши' Ð´Ð»Ñ Ð½Ð°Ñтройки джойÑтика." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Левый Ñтик" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Правый Ñтик" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "ОПИСÐÐИЕ" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "КЛÐВИШÐ" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ДОП. КЛÐВИШÐ" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "СохранÑть пароли Ñерверов" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "ÐвтоматичеÑкое обновление ÑпиÑка Ñерверов" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Разрешить загрузку Ñкриншотов" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Разрешить Ñторонние звуки" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Ð’Ñегда показывать окно загрузки" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Разрешить Ñоединение Ñ Discord Rich Presence" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" -msgstr "" +msgstr "Разрешите внутриигровой ÑÑ‚Ð°Ñ‚ÑƒÑ GTA:SA в Steam" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "СохранÑть фотографии, Ñделанные камерой, в папку GTA San Andreas User Files folder" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "СпроÑите перед отключением от Ñервера Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ главного меню" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "ИÑпользовать модифицированные файлы GTA:SA" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "ÐаÑтройки Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "ÐепрозрачноÑть:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "Разрешение изображениÑ:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "1024 x 1024 (Стандарт)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "ÐžÐ±Ñ‰Ð°Ñ Ð³Ñ€Ð¾Ð¼ÐºÐ¾Ñть:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "ГромкоÑть радио:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "ГромкоÑть Ñффектов:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "ГромкоÑть MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "ГромкоÑть речи:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Режим воÑпроизведениÑ:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Общие" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "ÐаÑтройки радио" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Эквалайзер радио" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "ÐвтонаÑтройка радио" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "ÐаÑтройки пользовательÑкой музыки" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Радио" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Случайно" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "ПоÑледовательно" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "ÐвтопоиÑк музыки" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "ÐаÑтройки заглушениÑ" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Заглушить вÑе звуки, когда игра Ñвёрнута" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Заглушить радио, когда игра Ñвернута" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Заглушить звуки Ñффектов, когда игра Ñвёрнута" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Выключать звук при Ñворачивании" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Выключать голоÑовой чат при Ñворачивании" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Разрешение:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Угол обзора:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "ДальноÑть прориÑовки:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "ЯркоÑть:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "КачеÑтво Ñффектов:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "ÐÐ½Ð¸Ð·Ð¾Ñ‚Ñ€Ð¾Ð¿Ð½Ð°Ñ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð°Ñ†Ð¸Ñ:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Сглаживание:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Соотношение Ñторон:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Оконный режим" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI адаптациÑ" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Стандарт" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Окно без рамки" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "ДетализациÑ" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "Ð’ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»ÑŒÐ½Ð°Ñ ÑинхронизациÑ" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Ðизкое" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Среднее" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Ð’Ñ‹Ñокое" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Очень выÑокое" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Отключено" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Ðвто" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "Ðдаптировать Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¿Ð¾Ð´ Ñоотношение Ñторон Ñкрана" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "ДинамичеÑкие тени" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Ð£Ð»ÑƒÑ‡ÑˆÐµÐ½Ð½Ð°Ñ Ñ‚Ñ€Ð°Ð²Ð°" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Эффект жары" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Дым шин и Ñ‚.д." -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "ДинамичеÑкие тени от перÑонажа" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Размытие в движении" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "ÐžÑ‚Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¶Ð´Ñ" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Сворачивание в полноÑкранном режиме" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Включить диалог выбора диÑплеÑ" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Показывать неподдерживаемые разрешениÑ" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Ð’Ñегда отображать транÑпорт в выÑоком качеÑтве " -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Ð’Ñегда отображать перÑонажей в выÑоком качеÑтве" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "Гамма:" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "КонтраÑÑ‚:" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "ÐаÑыщенноÑть:" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "ПрименÑть наÑтройки в оконном режиме" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "ПрименÑть наÑтройки в полноÑкранном режиме" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Разрешить Ñторонние Ñайты" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Разрешить Javascript на Ñторонних Ñайтах" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "Включить рендеринг через GPU" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Чёрный ÑпиÑок" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Введите адреÑ, например google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Запретить" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "ÐдреÑ" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Удалить адреÑ" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "Убрать вÑÑ‘" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Белый ÑпиÑок" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Разрешить" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Разное" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "БыÑÑ‚Ñ€Ð°Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ° одежды CJ:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "СкороÑть Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ ÑпиÑка Ñерверов:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Однопоточное подключение:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Тег пакета:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "ÐÐ½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð¸Ð½Ð´Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð° загрузки:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Приоритет процеÑÑа" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "ÐаÑтройка отладчика:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "ВидеопамÑть:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Тип обновлениÑ:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "УÑтановить важные обновлениÑ:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Включить" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Очень медленно" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "По умолчанию" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "БыÑтро" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Средне" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Выше Ñреднего" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Мин" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "МакÑ" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "СовмеÑтимоÑть Ñ Windows 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-битные цвета" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "ИÑправление мыши" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Путь загрузки реÑурÑов:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Открыть папку" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" -msgstr "УÑтановите ÑоответÑтвие CPU 0 Ð´Ð»Ñ Ð¿Ð¾Ð²Ñ‹ÑˆÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñти игры." +msgstr "УÑтановите ÑоответÑтвие CPU 0 Ð´Ð»Ñ Ð¿Ð¾Ð²Ñ‹ÑˆÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñти игры" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "ÐвтоматичеÑкое обновление" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Проверить обновлениÑ" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "ÐаÑтройки изменÑÑ‚ÑÑ Ð¿Ñ€Ð¸ Ñледующем запуÑке MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Ð’Ñ‹ хотите перезапуÑтить?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "ÐЕОБХОДИМ ПЕРЕЗÐПУСК" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Ðекоторые наÑтройки будут изменены поÑле того, как вы отключитеÑÑŒ от текущего Ñервера" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Ð’Ñ‹ хотите отключитьÑÑ?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "ÐЕОБХОДИМО ОТКЛЮЧЕÐИЕ" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "ДжоÑтик не найден. Проверьте, подключен ли он и перезапуÑтите игру" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "ÐаÑтройка оÑей" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Перемещайте джойÑтик Ð´Ð»Ñ Ð½Ð°Ñтройки или escape Ð´Ð»Ñ Ð¾Ñ‡Ð¸Ñтки" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Язык:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Тема:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "ПредуÑтановки:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Чат" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Загрузить" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Цвета" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Макет чата" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "ÐаÑтройки:" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Фон чата" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "ТекÑÑ‚ чата" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Фон Ð¿Ð¾Ð»Ñ Ð²Ð²Ð¾Ð´Ð°" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Цвет Ñтроки ввода" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Строки:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "МаÑштаб:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Ширина:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Размер" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "поÑле" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "за" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "Ñек" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Затухание" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Затухание Ñообщений" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Горизонтально" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Вертикально" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Выравнивание текÑта:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "Смещение по оÑи X:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Смещение по оÑи Y:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "ПозициÑ" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Влево" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Центр" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Вправо" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Верх" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Ðиз" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Шрифт:" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Отображать задний фон только при вводе" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Ð’ÑтавлÑть ник по кнопке \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Разрешить Ñерверу моргать окном приложениÑ" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Показывать ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð² облаÑти уведомлений" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "ЧёрнаÑ/Ð±ÐµÐ»Ð°Ñ Ð¾Ð±Ð²Ð¾Ð´ÐºÐ° текÑта чата" @@ -1549,89 +1842,95 @@ msgstr "ЧёрнаÑ/Ð±ÐµÐ»Ð°Ñ Ð¾Ð±Ð²Ð¾Ð´ÐºÐ° текÑта чата" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Ðажмите клавишу Ð´Ð»Ñ Ð½Ð°Ñтройки или escape Ð´Ð»Ñ Ð¾Ñ‡Ð¸Ñтки" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "ÐаÑтройка оÑновной клавиши" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "ÐаÑтройка дополнительной клавиши" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "УПРÐВЛЕÐИЕ GTA" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "УПРÐВЛЕÐИЕ МУЛЬТИПЛЕЕРÐ" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Ваш никнейм Ñодержит недопуÑтимые Ñимволы." -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Главное меню" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "Ð’ игре" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "КраÑный:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Зелёный:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Синий:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "ПрозрачноÑть:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Цвет" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "ПредпроÑмотр" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "ПожалуйÑта, отключитеÑÑŒ перед Ñменой Ñзыка" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "ПожалуйÑта, отключитеÑÑŒ перед Ñменой темы" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "ДинамичеÑкие тени могут вызвать падение производительноÑти.\n\n" "Ð’Ñ‹ уверены, что хотите активировать их?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "ПРЕДУПРЕЖДЕÐИЕ ПРОИЗВОДИТЕЛЬÐОСТИ" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Загрузка Ñкриншотов требуетÑÑ Ð¼Ð½Ð¾Ð³Ð¸Ð¼Ð¸ Ñерверами Ð´Ð»Ñ Ð°Ð½Ñ‚Ð¸-чит ÑиÑтемы.\n\n" "(ОблаÑть чата и Ñлементы интерфейÑа будут Ñкрыты)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "ИÐФОРМÐЦИЯ О ЗÐГРУЗКЕ СКРИÐШОТОВ" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1639,23 +1938,21 @@ msgstr "Ðекоторые Ñкрипты могут воÑпроизводит "Отключение Ñтой наÑтройки может Ñнизить потребление \n" "пропуÑкной ÑпоÑобноÑти Ñети.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "Ð’ÐЕШÐИЕ ЗВУКИ" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "КажетÑÑ, вы включили параметр Discord Rich Presence.\n" -"Желаете разрешить Ñерверам передавать данные Ñ Ð¸Ñ… Ñтороны?\n\n" -"Данные могут включать ваш уникальный идентификатор." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "СОГЛÐСИЕ ДЛЯ РÐЗРЕШЕÐИЯ ОБМЕÐРДÐÐÐЫМИ" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1665,11 +1962,7 @@ msgstr "Ðекоторые файлы в директории GTA:SA измен "Тем не менее, модифицированные файлы блокируютÑÑ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ð½Ñтвом Ñерверов\n\n" "Ð’Ñ‹ дейÑтвительно хотите иÑпользовать их?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "МОДИФИЦИРОВÐÐÐЫЕ ФÐЙЛЫ GTA:SA" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1679,552 +1972,253 @@ msgstr "Включение DPI адаптации ÑвлÑетÑÑ ÑкÑпер "Ð’Ñ‹ можете ÑтолкнутьÑÑ Ñ Ð³Ñ€Ð°Ñ„Ð¸Ñ‡ÐµÑкими проблемами, еÑли включите Ñту опцию.\n\n" "Ð’Ñ‹ уверены, что хотите включить Ñту опцию?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "ЭКСПЕРИМЕÐТÐЛЬÐÐЯ ФУÐКЦИЯ" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "Отключать Ñту опцию не рекомендуетÑÑ, еÑли у Ð²Ð°Ñ Ð½ÐµÑ‚ проблем Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñтью.\n\n" "Ð’Ñ‹ уверены, что хотите отключить ее?" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Введите никнейм" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Введите никнейм, который будет иÑпользован в игре \n" "Это будет вашем именем, когда вы подключитеÑÑŒ к Ñерверу" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Очень ÑкÑÐ¿ÐµÑ€Ð¸Ð¼ÐµÐ½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ" -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "ÐžÐ¿Ñ‚Ð¸Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñмены одежды CJ (ТребуютÑÑ Ð´Ð¾Ð¿. 65Мб ОЗУ)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Старые роутеры будут лучше работать Ñ Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ð¾Ð¹ ÑкороÑтью ÑканированиÑ" -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "ИÑпользовать однопоточное подключение при загрузке файлов." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Помечать Ñетевые пакеты Ð´Ð»Ñ ÑƒÐ¿Ñ€Ð¾Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ трафика MTA" -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "ÐÐ½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰ÐµÐ³Ð¾ÑÑ ÐºÑ€ÑƒÐ³Ð° внизу Ñкрана" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Ð’Ñегда по умолчанию. (Эта наÑтройка не ÑохранÑетÑÑ)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Лучше вÑего выделить макÑимальный объем" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "ÐвтоматичеÑкое обновление:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "ИÑпользуйте \"По умолчанию\" еÑли желаете загружать только Ñтабильные верÑии" -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Выберите значение по умолчанию Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑкой уÑтановки важных обновлений." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-битные цвета:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Включить режим 16-битных цветов. Требует перезапуÑка MTA." -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "ИÑправление мыши:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "ИÑправить Ð´Ð²Ð¸Ð¶ÐµÐ½Ð¸Ñ Ð¼Ñ‹ÑˆÐ¸ - Ðеобходим перезапуÑк ПК" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "СходÑтво Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑором CPU:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "Смените только в том Ñлучае, еÑли у Ð²Ð°Ñ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ»Ð¸ проблемы Ñо ÑтабильноÑтью." -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "ÐеизвеÑÑ‚Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° или переменнаÑ: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "ЗанÑто" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Ðевозможно проверить Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð² данный момент" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "ТребуетÑÑ MTA:SA %s" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "ТребуетÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ до MTA:SA %s, чтобы приÑоединитьÑÑ Ðº выбранному Ñерверу.\n\n" -"Ð’Ñ‹ хотите загрузить и уÑтановить MTA:SA %s?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Ð’Ñ‹ уверены, что хотите запуÑтить MTA:SA %s и приÑоединитьÑÑ Ðº Ñтому Ñерверу?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Подключение ÑÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾.\n\n" -"Повторите попытку позже." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Подключение" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "ПожалуйÑта, подождите..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "ПРОВЕРКÐ" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "ПРОВЕРКРОБÐОВЛЕÐИЙ" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Ð’ обновлении нет необходимоÑти" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "ЗÐГРУЗКÐ" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "ожидание..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "ОБЯЗÐТЕЛЬÐОЕ ОБÐОВЛЕÐИЕ" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Чтобы войти на Ñервер, вы должны обновить MTA.\n\n" -" Обновить ÑейчаÑ?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "ДОПОЛÐИТЕЛЬÐОЕ ОБÐОВЛЕÐИЕ" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Сервер предлагает обновить клиент, но Ñто не обÑзательно.\n\n" -"Ð’Ñ‹ хотите обновить?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ недоÑтупно.\n\n" -"ПожалуйÑта, проверьте www.multitheftauto.com" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "ОШИБКРСОХРÐÐЕÐИЯ" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Ðе удаётÑÑ Ñоздать файл." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "ОШИБКРЗÐГРУЗКИ" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Загруженный файл некорректен." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "По некоторым причинам." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "ЗÐГРУЗКРЗÐВЕРШЕÐÐ" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° в _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ок" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "ОШИБКÐ" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Ðекоторые MTA:SA файлы отÑутÑтвуют.\n\n\n" -"ПереуÑтановите MTA:SA." - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "Загружено %3d %%" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -" Ожидание ответа - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Подключение не удалоÑÑŒ. Ðекорректное Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Ðе удалоÑÑŒ подключитÑÑ. Ðеверный Ð°Ð´Ñ€ÐµÑ Ñервера!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Подключение на %s Ñ Ð¿Ð¾Ñ€Ñ‚Ð¾Ð¼ %u не удалоÑÑŒ!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Подключение к %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "Повторное подключение к %s:%u ..." - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "ПОДКЛЮЧЕÐИЕ" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸Ñтекло" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Отключено: неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° протокола" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Отключено: удалённое отключение" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Отключение: потерÑно удаленное Ñоединение" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Отключение: вы забанены на Ñтом Ñервере" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Отключено: отключен от Ñервера" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Отключено: ÑвÑзь Ñ Ñервером была потерÑна" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Отключено: Ñоединение было Ñброшено" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Ðе уÑтановлен модуль (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Ðеверный ответ Ñервера (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Ðеверный ответ Ñервера (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "ÐОВОСТИ" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "ПоÑмотреть поÑледние новоÑти" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "КОÐСОЛЬ" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "КритичеÑÐºÐ°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "ДЛЯ ИСПРÐВЛЕÐИЯ УДÐЛИТЕ ФÐЙЛ: " -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "Модуль %s некорректен!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Ошибка Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "Ñта Ñтраница помощи" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "выйти из приложениÑ" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "показать верÑию MTA" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "показать текущее времÑ" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "показать Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¸Ð³Ñ€Ð¾ÐºÐ°" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "показать вÑе наÑтройки клавиш" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "показать ваш Ñерийный номер" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "подключитьÑÑ Ðº Ñерверу (адреÑ, порт, ник, пароль)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "подключитьÑÑ Ðº поÑледнему поÑещённому Ñерверу" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "назначить клавишу управлениÑ" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "удалить задачу Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ¸" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "Ñкопировать наÑтройки из GTA:SA" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" -msgstr "Ñделать Ñкриншот" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "Ñохранить наÑтройки" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "очиÑтить окно отладки (debug)" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "прокрутить чат вверх" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "прокрутить чат вниз" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "прокрутить окно отладки вверх" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "прокрутить окно отладки вниз" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "показать ÑтатиÑтику иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð°Ð¼Ñти" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "показать график производительноÑти" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "Ð´Ð»Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ¾Ð²: обновите новоÑти" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ ПОМОЩЬ ПО КОМÐÐДÐМ ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* ВремÑ: %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "Подключение: Сеть не готова, пожалуйÑта, подождите немного" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "ИÑпользуйте 'connect <адреÑ> [<порт> <ник> <пароль>]' Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "подключение: Ðеверный порт" +msgstr "Ñделать Ñкриншот" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "Подключение: Подключение к %s:%u..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "Ñохранить наÑтройки" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "Подключение к %s:%u не удалоÑÑŒ!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "очиÑтить окно отладки (debug)" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "подключение: Ðе удалоÑÑŒ выгрузить текущий мод" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "прокрутить чат вверх" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "переподключение: Сеть не готова, пожалуйÑта, подождите немного" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "прокрутить чат вниз" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "переподключение: неверный номер порта" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "прокрутить окно отладки вверх" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "переподключение: Подключение к %s:%u..." +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "прокрутить окно отладки вниз" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "переподключение: к %s:%u не удалоÑÑŒ!" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "показать ÑтатиÑтику иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð°Ð¼Ñти" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Скопировать управление из GTA" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "показать график производительноÑти" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Файл конфигурации Ñохранен" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "Ð”Ð»Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ¾Ð²: обновите новоÑти" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Ваш Ñерийный номер: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Ð’Ñ‹ иÑпользуете feature-branch разработку! Это теÑÑ‚Ð¾Ð²Ð°Ñ Ñборка, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð½Ðµ может иÑпользоватьÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº публичным Ñерверам!" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "ОÑÑŒ уÑкорениÑ" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA не будет получать Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð° XP/Vista поÑле Ð¸ÑŽÐ»Ñ 2019.\n\n" +"Обновите Windows, чтобы играть на Ñерверах Ñ Ð¿Ð¾Ñледним обновлением." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "ОÑÑŒ торможениÑ" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Это дейÑтвие приведёт к отключению от текущего Ñервера.\n\n" +"Ð’Ñ‹ дейÑтвительно хотите отключитьÑÑ?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Программирование" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "ПРЕДУПРЕЖДЕÐИЕ ОТКЛЮЧЕÐИЯ" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "УчаÑтники" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "ИÐФОРМÐЦИЯ" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Игровой дизайн / Скриптинг" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "ÐОВОСТИ" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Язык" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "ПоÑмотреть поÑледние новоÑти" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Ðвторы иÑправлений" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Размер Ñкриншота %d байт, но ожидалоÑÑŒ %d " -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "ÐžÑ‚Ð´ÐµÐ»ÑŒÐ½Ð°Ñ Ð±Ð»Ð°Ð³Ð¾Ð´Ð°Ñ€Ð½Ð¾Ñть" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Ðе удалоÑÑŒ Ñделать Ñкриншот" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Это программное обеÑпечение и проект иÑпользуют Ñледующие библиотеки и программное обеÑпечение:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Скриншот Ñделан: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Хотите ли вы поÑмотреть помощь по Ñтой проблеме онлайн?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "ÐеизвеÑÑ‚Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° или переменнаÑ: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2399,25 +2393,56 @@ msgid "Group control backwards" msgstr "Группа: назад" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð²Ð°Ð¼Ð¸ графичеÑÐºÐ°Ñ Ñ‚ÐµÐ¼Ð° не может быть загружена, тема по-умолчанию также не может быть загружена, переуÑтановите MTA Ð´Ð»Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ñ‹." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Размер Ñкриншота %d байт, но ожидалоÑÑŒ %d " +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Хотите ли вы поÑмотреть помощь по Ñтой проблеме онлайн?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Ðе удалоÑÑŒ Ñделать Ñкриншот" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "КОÐСОЛЬ" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Скриншот Ñделан: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Программирование" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "УчаÑтники" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Игровой дизайн / Скриптинг" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Язык" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Ðвторы иÑправлений" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "ÐžÑ‚Ð´ÐµÐ»ÑŒÐ½Ð°Ñ Ð±Ð»Ð°Ð³Ð¾Ð´Ð°Ñ€Ð½Ð¾Ñть" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Это программное обеÑпечение и проект иÑпользуют Ñледующие библиотеки и программное обеÑпечение:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "ОÑÑŒ уÑкорениÑ" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "ОÑÑŒ торможениÑ" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2425,6 +2450,65 @@ msgstr "Ðевозможно инициализировать Direct3D9.\n\n" "УÑтановите DirectX End-User Runtime\n" "и Ñамую Ñвежую верÑию Windows Service Packs." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Ðеактивный" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "игрок" +msgstr[1] "игроков" +msgstr[2] "игроков" +msgstr[3] "игроки" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "на" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "Ñервере" +msgstr[1] "Ñерверах" +msgstr[2] "Ñерверах" +msgstr[3] "Ñерверы" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Получение ÑпиÑка Ñерверов (%lu Ð¼Ñ Ð¿Ñ€Ð¾ÑˆÐ»Ð¾)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "МаÑтер-Ñервер не отвечает." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "МаÑтер-Ñервер не может получить данные." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Ð ÐµÐ·ÐµÑ€Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ ÑпиÑка Ñерверов)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "Ðевозможно Ñоздать Ñокет широковещательной раÑÑылки в локальной Ñети (LAN)" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Ðе удалоÑÑŒ привÑзать локальный Ñокет" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Попытка Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ñ‹Ñ… Ñерверов" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2478,7 +2562,7 @@ msgstr "Задержка:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "СпиÑок игроков" @@ -2505,40 +2589,39 @@ msgstr "ПодключитьÑÑ, как оÑвободитÑÑ Ð¼ÐµÑто." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "ВВЕДИТЕ ПÐРОЛЬ СЕРВЕРÐ:" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð²Ñ‹ÑˆÐ»Ð¾" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Идет запроÑ..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "СПИСОК СЕРВЕРОВ" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Интернет" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Ð›Ð¾ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ñеть" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Избранное" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "ПоÑледние" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2546,302 +2629,367 @@ msgstr "ДЛЯ БЫСТРОГО ПОДКЛЮЧЕÐИЯ:\n\n" "Введите Ð°Ð´Ñ€ÐµÑ Ð¸ порт Ñервера в адреÑную Ñтроку.\n" "Или выберите Ñервер из иÑтории поÑледних и нажмите 'ПодключитьÑÑ'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "ПОМОЩЬ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Обновить" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Добавить в Избранное" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "ПодключитьÑÑ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ Ñервере" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "ПоиÑк по Ñерверам" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "ПоиÑк по игрокам" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Ðачать поиÑк" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "Удалить из недавних" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "ПоиÑк по игрокам..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "ПоиÑк по Ñерверам..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Ðазвание" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Игроки" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Пинг" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Игровой режим" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Показать:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "ПуÑтые" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Заполненные" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Под паролем" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Отключенные" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Другие верÑии" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Ðазад" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Загрузка..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "..загрузка.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "ÐÐ´Ñ€ÐµÑ Ñервера не указан!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "ÐеизвеÑтный протокол" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "ПожалуйÑта, иÑпользуйте протокол mtasa://" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Ðеверное Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ! ПожалуйÑта, откройте наÑтройки и измените его!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Выберите Ñервер Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Ðеактивный" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Проблема Ñ Ð³Ñ€Ð°Ñ„Ð¸Ñ‡ÐµÑким драйвером" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "игрок" -msgstr[1] "игроков" -msgstr[2] "игроков" -msgstr[3] "игроки" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Ðевозможно подобрать подходÑщее разрешение Ñкрана." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "на" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Ð’Ñ‹ уверены, что хотите иÑпользовать Ñто разрешение Ñкрана?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "Ñервере" -msgstr[1] "Ñерверах" -msgstr[2] "Ñерверах" -msgstr[3] "Ñерверы" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "ÐÐµÑƒÐ´Ð°Ñ‡Ð½Ð°Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ game_sa" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Получение ÑпиÑка Ñерверов (%lu Ð¼Ñ Ð¿Ñ€Ð¾ÑˆÐ»Ð¾)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "Ошибка Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿Ð°Ð¼Ñти" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "МаÑтер-Ñервер не отвечает." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ðº Ñайту" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "МаÑтер-Ñервер не может получить данные." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Сервер делает запроÑÑ‹ к Ñледующим Ñайтам, Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾ чтобы загрузить их позднее:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Ð ÐµÐ·ÐµÑ€Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ ÑпиÑка Ñерверов)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "ÐЕ ВВОДИТЕ КОÐФИДЕÐЦИÐЛЬÐЫХ ДÐÐÐЫХ, ДÐБЫ ЗÐЩИТИТЬ ИХ ОТ КРÐЖИ" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Ðе удалоÑÑŒ привÑзать локальный Ñокет" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Запомнить решение" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Попытка Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ñ‹Ñ… Ñерверов" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Запретить" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Эта верÑÐ¸Ñ ÑƒÑтарела." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "отключение от игры" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "показывать неймтеги" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "показать чат" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "Показывать ÑтатиÑтику ÑоединениÑ" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "Открыть чат" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "Передавать Ð³Ð¾Ð»Ð¾Ñ Ð²Ñем игрокам" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "ТранÑпорт: ПаÑÑажир" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "След. радиоÑтанциÑ" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "Пред. радиоÑтанциÑ" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "радар: Отобразить/СпрÑтать" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "увеличивает маÑштаб карты игрока в" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "увеличивает маÑштаб карты игрока из" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "перемещает карту игрока Ñевер" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "перемещает карту игрока на юг" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "перемещает карту игрока на воÑток" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "перемещает карту игрока на запад" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "прикреплÑет карту игрока" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "уменьшает непрозрачноÑть карты игрока" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "увеличивает непрозрачноÑть карты игрока" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "карта: Вкл/откл помощь" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "Сообщение выбранному игроку" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "ТранÑпорт: След. оружие" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "ТранÑпорт: Пред. оружие" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "Отобразить информацию о Ñервере" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "Определение маÑштаба Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ‚ÐµÐºÑта" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Режим разработки) показывать colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Режим разработки) пиÑать идентификаторы игровых звуков в окно отладчика" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "СОЗДÐТЬ СЕРВЕР" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "РеÑурÑÑ‹" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Ð˜Ð¼Ñ Ñервера:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Пароль:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "МакÑ. кол-во игроков:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "ВидимоÑть в:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "Ð›Ð¾ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ñеть" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Выбрано" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Ð’ÑÑ‘" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "ЗапуÑтить" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "Изменить режим: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "МаÑштаб: %s /%s Перемещение: %s, %s, %s, %s ÐепрозрачноÑть: %s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "Переключить карту: %s Переключить текÑÑ‚ помощи: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "Следующий игрок" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "Свободное передвижение" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "ПрогреÑÑ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ карты:" @@ -2862,174 +3010,174 @@ msgstr "%s из %s" msgid "Disconnect to cancel download" msgstr "ОтключитеÑÑŒ, чтобы оÑтановить загрузку" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Отключение: неверный никнейм." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Отключение от Ñервера" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Отключение: Серийный номер заблокирован. \n" "Причина: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Отключение: Ð’Ñ‹ забанены. \n" "Причина: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Отключение: Ðккаунт заблокирован. \n" "Причина: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Отключение: ВерÑии не Ñовпадают" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Отключение: Флуд подключениÑми. Подождите минуту перед новой попыткой." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Отключение: Сервер другой верÑии.\n" "ИнформациÑ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Отключение: ÐеподходÑÑ‰Ð°Ñ Ð²ÐµÑ€ÑиÑ.\n" "ИнформациÑ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "ОтÑоединен: Сервер работает на более новой верÑии.\n" "ИнформациÑ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "ОтÑоединен: Сервер работает на более Ñтарой верÑии.\n" "ИнформациÑ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Отключение: Такой никнейм уже иÑпользуетÑÑ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Отключение: \"Элемент\" игрок не может быть Ñоздан." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Отключение: Сервер ÑброÑил подключение: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Отключение: не удалаÑÑŒ проверка Ñерийного ключа." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "Отключено: Серийный номер уже иÑпользуетÑÑ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Отключение: подключение деÑинхронизировано %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Отключение: %s кикнул ваÑ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Отключение: %s заблокировал ваÑ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Отключено: Сервер выключен или перезапущен" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Ð’Ð°Ñ ÐºÐ¸ÐºÐ½ÑƒÐ»Ð¸ Ñ Ñервера" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Этот Ñервер требует не изменённый gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "ПожалуйÑта, замените gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Этот Ñервер не разрешает ÑобÑтвенные D3D9.DLL" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Удалите D3D9.DLL из директории GTA и перезапуÑтите MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Этот Ñервер не разрешает виртуальные машины" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Этот Ñервер требует, чтобы подпиÑÑŒ драйверов была включена" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "ПожалуйÑта, перезапуÑтите ваш компьютер" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Этот Ñервер обнаружил отÑутÑтвующие компоненты анти-чита" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Попробуйте перезапуÑтить MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Этот Ñервер требует не изменённый gta3.img и gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "ПожалуйÑта, замените gta3.img или gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Этот Ñервер не разрешает Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "УбедитеÑÑŒ, что Ð½Ð¸ÐºÐ°ÐºÐ°Ñ Ð´Ñ€ÑƒÐ³Ð°Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð° не изменÑет MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "ОÑтавшееÑÑ Ð²Ñ€ÐµÐ¼Ñ: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" @@ -3038,7 +3186,7 @@ msgstr[1] "%d днÑ" msgstr[2] "%d дней" msgstr[3] "%d дней" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" @@ -3047,7 +3195,7 @@ msgstr[1] "%d чаÑа" msgstr[2] "%d чаÑов" msgstr[3] "%d чаÑа" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" @@ -3056,7 +3204,7 @@ msgstr[1] "%d минута" msgstr[2] "%d минуты" msgstr[3] "%d мин" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3066,296 +3214,206 @@ msgstr[2] "%d Ñекунды" msgstr[3] "%d Ñекунды" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Отключение" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Ошибка ÑкачиваниÑ: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "Летает на ÐЛО вокруг" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "ПутешеÑтвует вокруг" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "Плавает по волнам в" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "Ездит на поезде в" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "Летает вокруг" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "Ездит вокруг" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "Крушит вÑе вокруг" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "КатаюÑÑŒ на квадроциклах по округе" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "Кролик прыгает вокруг" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "Творит Ñтранные вещи в" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "ВзбираетÑÑ Ñ€Ñдом Ñ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "Давит кого-то в" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "РыданиÑ, рыданиÑ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "Дышит водой" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "Тонет в" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "Ищет укрытие в" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "Летает в" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "Машет кулаками в" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "Взрывает дураков в" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "СтрелÑет вверх" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "Реактивный ранец в" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "Буквально горит в" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "Сгорает в" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "Плавает в" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "Плавает вокруг" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "ПреÑледуетÑÑ Ð°ÐºÑƒÐ»Ð¾Ð¹" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "ЗадыхаетÑÑ Ð´Ð¾ Ñмерти в" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Подключение к Ñерверу ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Ðе подключен; пожалуйÑта, иÑпользуйте ПОДКЛЮЧЕÐИЕ или команду 'connect', чтобы зайти на Ñервер." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Ðевозможно запуÑтить локальный Ñервер. Проверьте окно конÑоли на наличие информации." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Локальный Сервер" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "ЗапуÑк локального Ñервера ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "Зона 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "Ходит вокруг " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Ð’Ð°Ñ ÐºÐ¸ÐºÐ½ÑƒÐ»Ð¸ Ñ Ñервера ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Соединение Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ñ‹Ð¼ Ñервером..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Ошибка Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº Ñерверу." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ðµ к локальному Ñерверу иÑтекло. Откройте конÑоль, чтобы узнать подробноÑти." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Соединение Ñ Ñервером потерÑно" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Отключение: Ñервер переполнен." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Отключение: неверный пароль" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "Проверка клиента MTA не удалаÑÑŒ!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "в канаве" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "Ð’ пути до больницы" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "Ð’Ñтреча Ñ Ñоздателем" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "Сожалеет о Ñвоих решениÑÑ…" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "Потрачено" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "СОЗДÐТЬ СЕРВЕР" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "РеÑурÑÑ‹" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Ð˜Ð¼Ñ Ñервера:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Пароль:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "МакÑ. кол-во игроков:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "ВидимоÑть в:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "Ð›Ð¾ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ñеть" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Выбрано" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Ð’ÑÑ‘" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "ЗапуÑтить" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "Изменить режим: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "МаÑштаб: %s /%s Перемещение: %s, %s, %s, %s ÐепрозрачноÑть: %s/%s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "Переключить карту: %s Переключить текÑÑ‚ помощи: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "Следующий игрок" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "Свободное передвижение" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Проблема Ñ Ð³Ñ€Ð°Ñ„Ð¸Ñ‡ÐµÑким драйвером" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Ðевозможно подобрать подходÑщее разрешение Ñкрана." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Ð’Ñ‹ уверены, что хотите иÑпользовать Ñто разрешение Ñкрана?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "ÐÐµÑƒÐ´Ð°Ñ‡Ð½Ð°Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ game_sa" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "Ошибка Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿Ð°Ð¼Ñти" +msgid "Download error: %s" +msgstr "Ошибка ÑкачиваниÑ: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3376,11 +3434,11 @@ msgstr "Ошибка протокола (%u). ЕÑли проблема Ñохр msgid "Connection error" msgstr "Ошибка ÑоединениÑ" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto уÑтановлена неправильно, пожалуйÑта, переуÑтановите." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "ПоÑетите веб-Ñтраницу, чтобы получить больше информации.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/sk_SK/client.pot b/Shared/data/MTA San Andreas/MTA/locale/sk_SK/client.pot index 5ae5535700d..9d50c96b80f 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/sk_SK/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/sk_SK/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Slovak\n" "Language: sk_SK\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Problémy pri reÅ¡tartovaní MTA:SA\n\n" -"Ak problém pretrváva, otvor Správcu úloh a\n" -"ukonÄi procesy 'gta_sa.exe' a 'Multi Theft Auto.exe'\n\n\n" -"PokúsiÅ¥ sa spustiÅ¥ MTA:SA znova?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Chyba" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Iná súÄasÅ¥ MTA už beží.\n\n" -"Ak tento problém pretrváva, reÅ¡tartuj svoj poÄítaÄ" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Iná súÄasÅ¥ MTA už beží.\n\n" -"ChceÅ¡ ju ukonÄiÅ¥?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Vyber tvoje Grand Theft Auto: San Andreas inÅ¡talaÄné umiestnenie" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA potrebuje prístup administrátora pre nasledujúcu operáciu:\n\n" +"'%s'\n\n" +"Prosím potvrÄ v nasledujúcom okne." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Chyba pri naÄítaní %s modulu! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Kopírujem súbory..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopírovanie skonÄilo skoro. VÅ¡etko OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "DokonÄujem..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Hotovo!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Bola zistená nová inÅ¡talácia %s.\n\n" +"Chcete skopírovaÅ¥ nastavenia z %s?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA mal problém s otvorením súboru '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA zistilo chybu v súbore '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA malo problém s naÄítaním modelu." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Ak ste nedávno upravili gta3.img, skúste preinÅ¡talovaÅ¥ GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA malo problém s pridaním upgradu do vozidla." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA naÅ¡lo chyby v súbore '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "ReÅ¡tartoval sa váš poÄítaÄ pri hraní MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Pred pokraÄovaním ukonÄite nasledujúce programy:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Chyba nesúladu verzie súboru. Ak sa vyskytnú problémy, preinÅ¡talujte MTA:SA.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Niektoré súbory chýbajú. Ak sa vyskytnú problémy, preinÅ¡talujte MTA:SA.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA nie je kompatibilný s „Núdzovým režimom“ systému Windows.\n\n" +"ReÅ¡tartujte poÄítaÄ.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Máš problémy s behom MTA:SA?\n\n" "PovoliÅ¥ návrat na starÅ¡iu verziu?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "Vypadá to že nastal problém pri spúšťaní MTA:SA.\n" "Resetnutie GTA nastavení niekedy tento problém vyrieÅ¡i.\n\n" "ChceÅ¡ resetovaÅ¥ GTA nastavenia teraz?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA nastavenia boli resetované.\n\n" "StlaÄ OK pre pokraÄovanie." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Súbor nemôže byÅ¥ zmazaný: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Máš problémy so spustením MTA:SA?.\n\n" "ChceÅ¡ si pozrieÅ¥ nejakú pomoc online?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Máte problémy so spustením MTA:SA?.\n\n" "Chcete zmeniÅ¥ nasledujúce nastavenie?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Celá obrazovka:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Okno bez okraja" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Máte problémy so spustením MTA:SA?.\n\n\n" "Skúste zakázaÅ¥ nasledujúce produkty pre GTA a MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +189,293 @@ msgstr "POZOR\n\n" "MTA:SA zistila nezvyÄajnú aktivitu.\n" "Spustite antivírusovú kontrolu, aby ste sa uistili, že váš systém je bezpeÄný.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Rozpoznaný súbor bol: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "ÄŒasÅ¥ GTA: San Andreas je už spustená. Je potrebné ju pred Å¡tartom MTA:SA ukonÄiÅ¥. ChceÅ¡ to urobiÅ¥ teraz?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informácia" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Nemožno ukonÄiÅ¥ GTA: San Andreas. Ak problém pretrváva, reÅ¡tartuj prosím svoj poÄítaÄ." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Problémy pri reÅ¡tartovaní MTA:SA\n\n" +"Ak problém pretrváva, otvor Správcu úloh a\n" +"ukonÄi procesy 'gta_sa.exe' a 'Multi Theft Auto.exe'\n\n\n" +"PokúsiÅ¥ sa spustiÅ¥ MTA:SA znova?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Chyba" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Iná súÄasÅ¥ MTA už beží.\n\n" +"Ak tento problém pretrváva, reÅ¡tartuj svoj poÄítaÄ" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Iná súÄasÅ¥ MTA už beží.\n\n" +"ChceÅ¡ ju ukonÄiÅ¥?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Záznamy v registroch chýbajú. PreinÅ¡taluj prosím Mutli Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Umiestnenie tvojej inÅ¡talácie GTA: San Andreas obsahuje nepodporované (unicode) znaky. Presuň prosím túto inÅ¡taláciu do kompatibilného umiestnenia ktoré obsahuje iba Å¡tandardné ASCII znaky a potom preinÅ¡taluj Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Umiestnenie tvojej inÅ¡talácie 'MTA:SA' alebo 'GTA: San Andreas'\n" -"obsahuje znak ';' (bodkoÄiarka).\n\n" -"Pokiaľ budeÅ¡ maÅ¥ problémy pri spustení MTA:SA,\n" -"presuň tvoju inÅ¡taláciu(e) do umiestnenie ktoré neobsahuje bodkoÄiarku." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "NaÄítanie zlyhalo. Prosím uisti sa že posledné data súbory boli nainÅ¡talované správne." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "NaÄítanie zlyhalo. Uisti sa prosím že %s je nainÅ¡talovaný správne." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "NaÄítanie zlyhalo. Nemožno nájsÅ¥ gta_sa.exe v %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "NaÄítanie zlyhalo. %s existuje v GTA umiestnení. Zmaž ho prosím pred pokraÄovaním." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Hlavný súbor má nesprávny názov (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Hlavný súbor je neupravený. Možná aktivita vírusu.\n\n" -"Ak MTA nefunguje správne, pozrite si online pomoc." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Dátový súbor %s sa nedá nájsÅ¥. Problém mohol spôsobiÅ¥ vírus.\n\n" -"Zváž preinÅ¡talovanie Multi Theft Auto v záujme vlastnej bezpeÄnosti.\n" -"Ak MTA nefunguje správne, preÄítaj si online pomocníka." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Dátový súbor %s je upravený. Problém mohol spôsobiÅ¥ vírus.\n\n" -"Zváž preinÅ¡talovanie Multi Theft Auto v záujme vlastnej bezpeÄnosti.\n" -"Ak MTA nefunguje správne, preÄítaj si online pomocníka." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "Súbory .asi sú v inÅ¡talaÄnom adresári 'MTA:SA' alebo 'GTA: San Andreas'.\n\n" -"Ak máte problémy s MTA:SA, odstráňte tieto súbory typu .asi." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Chyba nesúladu verzie súboru. Ak sa vyskytnú problémy, preinÅ¡talujte MTA:SA.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Niektoré súbory chýbajú. Ak sa vyskytnú problémy, preinÅ¡talujte MTA:SA.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA nie je kompatibilný s „Núdzovým režimom“ systému Windows.\n\n" -"ReÅ¡tartujte poÄítaÄ.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Opravte problém s konfiguráciou" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Opravte vyžadovanú chybu" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Neznámy" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "Súbor '%s' je blokovaný %zu procesmi.\n\n" +"PrajeÅ¡ si ukonÄiÅ¥ tieto procesy a pokraÄovaÅ¥ v aktualizácii?\n\n" +"%s" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/Install.cpp:479 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Nemožno spustiÅ¥ Grand Theft Auto: San Andreas. Skús prosím reÅ¡tart, alebo ak problém pretrváva, kontaktuj MTA na www.multitheftauto.com. \n\n" -"[%s]" +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "Tvoja inÅ¡talácia môže byÅ¥ poÅ¡kodená.\n\n" +"%zu z %zu súborov sa nepodarilo obnoviÅ¥ zo zálohy.\n\n" +"Mal by si preinÅ¡talovaÅ¥ Multi Theft Auto zo stránky www.multitheftauto.com\n" +"alebo skúsiÅ¥ spustiÅ¥ aktualizáciu s oprávnením administrátora." -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas sa možno nespustilo správne. ChceÅ¡ ho ukonÄiÅ¥?" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "InÅ¡talujú sa aktualizácie..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Extrahovanie súborov..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA nemôže dokonÄiÅ¥ nasledovnú operáciu:\n\n" +"'%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Pád bol spôsobený chybou grafického ovládaÄa **\n\n" +"** Aktualizuj prosím svoj grafický ovládaÄ **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "InÅ¡talovaÅ¥ aktualizované MTA:SA súbory" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Nemožno aktualizovaÅ¥ kvôli konfliktom súborov. Zatvor prosím ostatné aplikácie a skús to znovu" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto nebolo správne nainÅ¡talované, prosím preinÅ¡taluj. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "VytvoriÅ¥ GTA:SA spojenie" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA nebolo možné spustiÅ¥ z dôvodu chyby poÄas kopírovania súborov:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA nebolo možné spustiÅ¥ z dôvodu poÅ¡kodeného alebo chýbajúceho MTA:SA súboru:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "KopírovaÅ¥ súbory MTA:SA" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA nebolo možné spustiÅ¥ z dôvodu poÅ¡kodeného alebo chýbajúceho GTA:SA súboru:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "AktualizovaÅ¥ závislosti GTA:SA" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA nebolo možné spustiÅ¥ z dôvodu poÅ¡kodeného alebo chýbajúceho spúšťaÄa GTA:SA:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Prosím skontrolujte svoj antivírusový program a skúste v ňom zapnúť výnimku pre spúšťaÄ GTA:SA, následne reÅ¡tartujte MTA:SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "GenerovaÅ¥ GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA nebolo možné spustiÅ¥ z dôvodu nespustiteľného spúšťaÄa GTA:SA:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "AktualizovaÅ¥ GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA nebolo možné spustiÅ¥ z dôvodu chyby poÄas aktualizácie GTA:SA:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA nemôže pokraÄovaÅ¥ pretože disk %s nemá dostatok voľného miesta." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Chýbajúce súbory:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Ak sa MTA nepodarí naÄítaÅ¥, znova preinÅ¡talujte GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "AktualizovaÅ¥ nastavenia inÅ¡talácie" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Aktualizujte nastavenia kompatibility" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +483,167 @@ msgstr "GTA: San Andreas sa možno nespustilo správne. ChceÅ¡ ho ukonÄiÅ¥?" #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Ãno" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Nie" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "OK" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "UkonÄiÅ¥" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Pomoc" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "ZruÅ¡iÅ¥" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas narazil na problém" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Informácie o zlyhaní" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "ZaÄiarknutím políÄka odoÅ¡lete tieto informácie o zlyhaní vývojárom MTA pomocou „internetu“" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Ak tak urobíte, zvýši sa Å¡anca na opravu tohto zlyhania." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Chcete reÅ¡tartovaÅ¥ MTA: San Andreas?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas – varovanie" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "VaÅ¡e GTA: San Andreas inÅ¡talaÄná složka obsahuje tieto súbory:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Tieto súbory nie sú povolené a môžu spôsobiÅ¥ chybu s grafickou kartou v tejto verzii MTA:SA\n\n" "DoporuÄuje sa aby ste ich vymazali alebo premenovali" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "Ponechajte tieto súbory, ale nechajte aby vyskakovalo okno upozornenia pri každom Å¡tarte" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Nepripominajte mi problémy o týchtoch súborov" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Premenujte tieto súbory ktoré majú koncovku .dll na .dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Ukažte mi tieto súbory" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "HraÅ¥ MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas – mätúce možnosti" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus je rozpoznaná!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Vyskúšajte každú možnosÅ¥ a uvidíte, Äo funguje:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Å tandardná NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Alternatívna NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Å tandardny Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Alternatívny Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Ak ste zúfalí, môže vám pomôcÅ¥ toto:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Ak ste už vybrali možnosÅ¥, ktorá funguje, môže vám pomôcÅ¥ toto:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "VynútiÅ¥ režim v okne" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Nabudúce nezobrazovaÅ¥" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Upozornenie: Nepodarilo sa zistiÅ¥ antivírus" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1107 +651,1180 @@ msgstr "MTA nedokázal rozpoznaÅ¥ antivírus vo vaÅ¡om poÄítaÄi.\n\n" "Vírusy zasahujú do MTA a zhorÅ¡ujú váš herný zážitok.\n\n" "ÄŽalÅ¡ie informácie získate stlaÄením tlaÄidla „Pomoc“." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Už mám nainÅ¡talovaný antivírus" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Nebudem inÅ¡talovaÅ¥ antivírus.\n" "Chcem, aby môj poÄítaÄ zaostal a bol súÄasÅ¥ou botnetu." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Hľadám Grand Theft Auto: San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Prosím spusti Grand Theft Auto: San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "InÅ¡talujú sa aktualizácie..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Pripájanie zlyhalo. Neplatný nick!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Extrahovanie súborov..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Pripájanie zlyhalo. Neplatný hostiteľ!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Kopírujem súbory..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Pripájanie k %s na porte %u zlyhalo!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopírovanie skonÄilo skoro. VÅ¡etko OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Pripájanie k %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "DokonÄujem..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Hotovo!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "PRIPÃJANIE" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA potrebuje prístup administrátora pre nasledujúcu operáciu:\n\n" -"'%s'\n\n" -"Prosím potvrÄ v nasledujúcom okne." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "ÄŒasový limit spojenia vyprÅ¡al" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA nemôže dokonÄiÅ¥ nasledovnú operáciu:\n\n" -"'%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Odpojené: neznámy protokol" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Pád bol spôsobený chybou grafického ovládaÄa **\n\n" -"** Aktualizuj prosím svoj grafický ovládaÄ **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Odpojené: odpojené vzdialene" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "InÅ¡talovaÅ¥ aktualizované MTA:SA súbory" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Odpojené: spojenie vzdialene stratené" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Nemožno aktualizovaÅ¥ kvôli konfliktom súborov. Zatvor prosím ostatné aplikácie a skús to znovu" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Odpojené: si zabanovaný na tomto serveri" -#: Client/loader/CInstallManager.cpp:561 -#, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto nebolo správne nainÅ¡talované, prosím preinÅ¡taluj. %s" +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Odpojené: odpojené zo servera" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "VytvoriÅ¥ GTA:SA spojenie" +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Odpojené: pripojenie na server bolo stratené" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA nebolo možné spustiÅ¥ z dôvodu chyby poÄas kopírovania súborov:" +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Odpojené: pripojenie bolo odmietnuté" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA nebolo možné spustiÅ¥ z dôvodu poÅ¡kodeného alebo chýbajúceho MTA:SA súboru:" +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 +#, c-format +msgid "No such mod installed (%s)" +msgstr "Nie je inÅ¡talovaný taký mód (%s)" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "KopírovaÅ¥ súbory MTA:SA" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Chybná odpoveÄ servera (2)" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA nebolo možné spustiÅ¥ z dôvodu poÅ¡kodeného alebo chýbajúceho GTA:SA súboru:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Chybná odpoveÄ servera (1)" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "AktualizovaÅ¥ závislosti GTA:SA" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "SlovenÄina" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA nebolo možné spustiÅ¥ z dôvodu poÅ¡kodeného alebo chýbajúceho spúšťaÄa GTA:SA:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Zaneprázdnený" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Prosím skontrolujte svoj antivírusový program a skúste v ňom zapnúť výnimku pre spúšťaÄ GTA:SA, následne reÅ¡tartujte MTA:SA." +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Momentálne nemôžem skontrolovaÅ¥ aktualizácie" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "GenerovaÅ¥ GTA:SA" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "vyžadované MTA:SA %s" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA nebolo možné spustiÅ¥ z dôvodu nespustiteľného spúšťaÄa GTA:SA:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Pre pripojenie na vybraný server je potrebné aktualizovaÅ¥ MTA:SA %s .\n\n" +"ChceÅ¡ stiahnuÅ¥ a nainÅ¡talovaÅ¥ MTA:SA %s ?" + +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "ChceÅ¡ spustiÅ¥ MTA:SA %s a pripojiÅ¥ sa na tento server?" + +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Nie je možné sa teraz pripojiÅ¥.\n\n" +"Skúste to neskôr." -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "AktualizovaÅ¥ GTA:SA" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Pripája sa" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA nebolo možné spustiÅ¥ z dôvodu chyby poÄas aktualizácie GTA:SA:" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Prosím poÄkajte..." -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA nemôže pokraÄovaÅ¥ pretože disk %s nemá dostatok voľného miesta." +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "KONTROLUJEM" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Chýbajúce súbory:" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "KONTROLA AKTUALIZÃCIÃ" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Ak sa MTA nepodarí naÄítaÅ¥, znova preinÅ¡talujte GTA:SA" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Nie je potreba aktualizácie" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "AktualizovaÅ¥ nastavenia inÅ¡talácie" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "SŤAHOVANIE" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Aktualizujte nastavenia kompatibility" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "ÄŒakám..." -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Neznámy" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "NUTNà UPDATE" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "Súbor '%s' je blokovaný %zu procesmi.\n\n" -"PrajeÅ¡ si ukonÄiÅ¥ tieto procesy a pokraÄovaÅ¥ v aktualizácii?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Pre pripojenie na tento server musíš aktualizovaÅ¥ MTA.\n\n" +"AktualizovaÅ¥ teraz?" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "Tvoja inÅ¡talácia môže byÅ¥ poÅ¡kodená.\n\n" -"%zu z %zu súborov sa nepodarilo obnoviÅ¥ zo zálohy.\n\n" -"Mal by si preinÅ¡talovaÅ¥ Multi Theft Auto zo stránky www.multitheftauto.com\n" -"alebo skúsiÅ¥ spustiÅ¥ aktualizáciu s oprávnením administrátora." +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "VOLITEĽNà UPDATE" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Server hovorí že je doporuÄené aktualizovaÅ¥ MTA, ale nie je to potrebné.\n\n" +"AktualizovaÅ¥ teraz?" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "CHYBA UKLADANIA" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Vyber tvoje Grand Theft Auto: San Andreas inÅ¡talaÄné umiestnenie" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Nepodarilo sa vytvoriÅ¥ súbor." -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Chyba pri naÄítaní %s modulu! (%s)" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "CHYBA SŤAHOVANIA" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Bola zistená nová inÅ¡talácia %s.\n\n" -"Chcete skopírovaÅ¥ nastavenia z %s?" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Stiahnutý súbor sa zdá byÅ¥ nekorektný." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA mal problém s otvorením súboru '%s'" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Z nejakého dôvodu." -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA zistilo chybu v súbore '%s'." +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "SŤAHOVANIE KOMPLETNÉ" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA malo problém s naÄítaním modelu." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr "- Neznámy problém v _DialogUpdateResult" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Ak ste nedávno upravili gta3.img, skúste preinÅ¡talovaÅ¥ GTA:SA." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "UPRAVENÉ GTA:SA SÚBORY" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA malo problém s pridaním upgradu do vozidla." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ok" -#: Client/loader/Utils.cpp:1631 -#, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA naÅ¡lo chyby v súbore '%s'" +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "CHYBA" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "ReÅ¡tartoval sa váš poÄítaÄ pri hraní MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Niektoré MTA:SA súbory chýbajú.\n\n\n" +"PreinÅ¡taluj prosím MTA:SA" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Pred pokraÄovaním ukonÄite nasledujúce programy:" +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% dokonÄené" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Požiadavky stránky" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"ÄŒakám na odpoveÄ - %-3d" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Server si vyžiadal povolenie na naÄítanie týchto stránok (neskorÅ¡ie):" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ PRÃKAZY ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NIKDY NEZADÃVAJTE CITLIVÉ INFORMÃCIE ABY VÃM NEBOLI UKRADNUTÉ" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Práve je %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "ZapamätaÅ¥ rozhodnutie" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "PovoliÅ¥" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "connect: Správny tvar je 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "ZakázaÅ¥" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "connect: Nesprávne Äíslo portu" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "Hlavné menu" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "connect: Pripája sa k %s:%u..." -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Používate novÅ¡iu verziu (feature-branch build)! Je to testovacia verzia a nemôže byÅ¥ použitá na pripojenie na public servery!" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "connect: nemôže sa pripojiÅ¥ k %s:%u!" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA nebude podporovaÅ¥ XP/Vista po Júli 2019.\n\n" -"Aktualizujte Windows aby ste mohli hraÅ¥ na aktuálnych serveroch." +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "connect: Zlyhalo vypínanie aktuálneho modu" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Toto Å¥a odpojí z aktuálneho serveru.\n\n" -"Si si istý, že sa chceÅ¡ odpojiÅ¥?" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "VAROVANIE O ODPOJENÃ" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." msgstr "" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "SlovenÄina" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "" + +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "NaÄítané vÅ¡etky ovládania z GTA" + +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "KonfiguraÄné súbory uložené" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Tvoj serial je: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "NASTAVENIA" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Multiplayer" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Video" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Zvuk" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Bindy" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Ovládanie" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Rozhranie" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Webový prehliadaÄ" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "PokroÄilé" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "NaÄítaÅ¥ predvolené" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "CitlivosÅ¥ myÅ¡i:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "CitlivosÅ¥ vertikálneho mierenia:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Nastavenia myÅ¡i" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "OtoÄiÅ¥ myÅ¡ vertikálne" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "RiadiÅ¥ myÅ¡ou" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "LietaÅ¥ myÅ¡ou" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Nastavenia joypadu" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Å tandardné ovládanie (MyÅ¡ + Klávesnica)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Klasické ovládanie (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "MÅ•tva Zóna" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "SýtosÅ¥" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Použi záložku 'Bindy' pre tlaÄidlá joypadu." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Ľavá PáÄka" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Pravá PáÄka" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "POPIS" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "TLAÄŒIDLO" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "KLÃVESA ALT" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Prezývka:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "UložiÅ¥ heslá k serverom" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Auto-obnova prehliadaÄa serverov" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "PovoliÅ¥ upload obrazovky" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "PovoliÅ¥ externé zvuky" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "PovoliÅ¥ zobrazenie okna sÅ¥ahovania" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "PovoliÅ¥ Discord Rich Presence" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "PoužívaÅ¥ zmenené GTA:SA súbory" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Možnosti zobrazovania mapy" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "NepriehľadnosÅ¥:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Celková hlasitosÅ¥:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "HlasitosÅ¥ rádia:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "HlasitosÅ¥ SFX:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "HlasitosÅ¥ MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "HlasitosÅ¥ hlasu:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Hrací mód:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Hlavné" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Možnosti rádia" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Rádio Ekvalizér" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Auto-ladenie Rádia" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Možnosti používateľských pesniÄiek" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Rádio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Náhodné" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Postupne" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Automatické skenovanie médií" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Nastavenia stlmenia" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "StlmiÅ¥ VÅ¡etky zvuky pri minimalizovaní" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "StlmiÅ¥ Rádio pri minimalizovaní" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "StlmiÅ¥ zvuky SFX pri minimalizovaní" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "StlmiÅ¥ MTA zvuky pri minimalizovaní" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "StlmiÅ¥ zvuky hlasu pri minimalizovaní" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Rozlíšenie:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "FOV:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Vykreslovacia vzdialenosÅ¥:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Jas:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Kvalita FX:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anizotropné filtrovanie:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Vyhladzovanie:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Pomer strán:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "V okne" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI aware" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Å tandardné" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "S okrajom - zachovaÅ¥ rozlíšenie" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "MIP mapovanie" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Nízke" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Stredné" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Vysoké" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Veľmi vysoké" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Vypnuté" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Auto" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD sa zhoduje s pomerom strán" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Odmerné tiene" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Efekt trávy" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Oparený vzduch" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Dym z pneumatík atÄ" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Dynamické tiene postáv" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Rozmazanie pri pohybe" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Dáždove reflekcie" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "MinimalizovaÅ¥ režim celej obrazovky" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "PovoliÅ¥ dialóg Zvolenia zariadenia" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "ZobraziÅ¥ nebezpeÄné rozlíšenia" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Vykresľujte vozidlá vždy vo vysokých detailoch" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Renderujte postavy vždy s vysokými detailmi" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "PovoliÅ¥ vzdialené webové stránky" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "PovoliÅ¥ Javascript na vzdialených webových stránkach" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Vlastná Äierna listina" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Zadajte doménu napr. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "BlokovaÅ¥" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Doména" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "OdstrániÅ¥ doménu" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Vlastná biela listina" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "PovoliÅ¥" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Rôzne" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Rýchle naÄítavanie obleÄenia CJ-a:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "RýchlosÅ¥ prehliadaÄa:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Jednotné pripojenie:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "ZnaÄka paketu:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Animácia priebehu:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Priorita procesu:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Nastavenie ladenia:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Streamovacia pamäť:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Typ aktualizácií:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "NainÅ¡talovaÅ¥ dôležité aktualizácie:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Zapnuté" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Veľmi pomaly" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Predvolené" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Rýchle" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normálne" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Nadpriemerné" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Minimalne" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Maximálne" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Kompatibilita so systémom Windows 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-bitová farba" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Oprava myÅ¡i" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Súbory prostriedkov klienta:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "ZobraziÅ¥ v prehliadaÄi" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Automatický updater" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "SkontrolovaÅ¥ aktualizácie" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Niektoré nastavenia sa zmenia pri ÄalÅ¡om spustení MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "ReÅ¡tartovaÅ¥ teraz?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "VYŽADOVANà REÅ TART" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Niektoré nastavenia sa zmenia, keÄ odpojíte aktuálny server" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Chcete sa teraz odpojiÅ¥?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "VYŽADUJE SA ODPOJENIE" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad nebol nájdený - Skontrolujte pripojenie a reÅ¡tartujte hru" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "NabindovaÅ¥ klavesu" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Presuň klávesu pre nabindovanie, alebo stlaÄ Esc pre zruÅ¡enie" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Jazyk:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Vzhľad:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Prednastavenia:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Chat" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "NaÄítaÅ¥" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Farby" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Rozloženie" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Nastavenia" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Pozadie chatu" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Text chatu" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Pozadie vstupu" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Vstupný text" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Riadky:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Mierka:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Šírka:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "VeľkosÅ¥" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "po" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "pre" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "sek" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Blednutie" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "SkryÅ¥ staré riadky" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horizontálne:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Vertikálne:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Zarovnanie textu:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "Posun X:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Posun Y:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Pozícia" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Vľavo" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Na stred" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Vpravo" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Hore" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Dole" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Písmo" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "SkryÅ¥ pozadie keÄ nepíšem" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Hore" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "PovoliÅ¥ serveru blikacie okno" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "PovoliÅ¥ 'tray balloon' upozornenia" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "ÄŒierno/biely obrys textu chatu" @@ -1548,89 +1832,95 @@ msgstr "ÄŒierno/biely obrys textu chatu" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "StlaÄ klávesu pre nabindovanie, alebo stlaÄ Esc pre zruÅ¡enie" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Bindovanie primárneho tlaÄidla" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Bindovanie sekundárneho tlaÄidla" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA HERNÉ OVLÃDANIE" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "OVLÃDANIE MULTIPLAYERU" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Tvoj nick obsahuje nepovolené znaky!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Hlavné menu" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "V hre" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "ÄŒervená:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Zelená:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Modrá:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "PriehľadnosÅ¥:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Farba" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Náhľad" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Prosím odpoj sa pred zmenou skinu" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Prosím odpoj sa pred zmenou skinu" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Odmerné tiene môžu spôsobiÅ¥ spomalenie niektorých PC.\n\n" "Si si istý že ich chceÅ¡ zapnúť?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "VAROVANIE O VÃKONE" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Upload obrazovky je vyžadovaný niektorými servermi pre anti-cheat ochranu.\n\n" "(Chat a GUI nie sú súÄasÅ¥ou uploadu)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "INFORMÃCIE O UPLOADE OBRAZOVKY" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1638,23 +1928,21 @@ msgstr "Niektoré skripty môžu prehrávaÅ¥ zvuky, ako napríklad rádio z inte "Zakázanie tohto nastavenia môže znížiÅ¥ sieÅ¥\n" "spotreby šírky pásma.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "EXTERNÉ ZVUKY" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "Zdá sa, že máš povolenú možnosÅ¥ pripojenia Rich Presence.\n" -"ChceÅ¡ serverom povoliÅ¥ zdieľanie ich dát?\n\n" -"To zahŕňa tvoj jedineÄný ID identifikátor." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "SÚHLAS S POVOLENÃM ZDIELANIA DÃT" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1664,11 +1952,7 @@ msgstr "Niektoré súbory vo vaÅ¡om GTA:SA prieÄinku sú upravené.\n" "Nakoľko, UPRAVENÉ GTA:SA SÚBORY SÚ BLOKOVANÉ NA MNOHO SERVEROCH\n\n" "Ste si istý že chcete tieto súbory používaÅ¥?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "UPRAVENÉ GTA:SA SÚBORY" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1678,550 +1962,252 @@ msgstr "Povolenie DPI je experimentálna funkcia a\n" "Ak povolíte túto možnosÅ¥, môžu sa vyskytnúť problémy s grafikou.\n\n" "Naozaj chcete povoliÅ¥ túto možnosÅ¥?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "EXPERIMENTÃLNA FUNKCIA" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Zadajte prosím prezývku" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Zadajte prosím prezývku ktorá bude použitá v hre. \n" "Toto bude vaÅ¡e meno po pripojení sa na server" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Veľmi experimentálny prvok." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Predchádza spomaľovaniu s variáciami CJ-a (Používa o 65MB viacej pamäte RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "StarÅ¡ie routery môžu vyžadovaÅ¥ slabÅ¡iu rýchlosÅ¥ skenovania." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Zapni pre zapnutie len jedného pripojenia pri sÅ¥ahovaní." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "OznaÄte sieÅ¥ové pakety, aby ste ISP pomohli identifikovaÅ¥ prevádzku MTA." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Animácia rotujúceho kruhu v spodnej Äasti obrazovky" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Vždy zvol predvolené. (Toto nastavenie sa naukladá)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maximum je väÄÅ¡inou najlepÅ¡ie" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Automatická aktualizácia:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Zvol predvolené pokiaľ nemáš rád ohlasovanie chýb." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Ak chcete automaticky nainÅ¡talovaÅ¥ dôležité aktualizácie, vyberte predvolené." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-bitová farba:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "PovoliÅ¥ 16-bitové farebné režimy – Vyžaduje reÅ¡tart MTA" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Oprava myÅ¡i:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Oprava pohybu myÅ¡i - Možno bude potrebné reÅ¡tartovaÅ¥ poÄítaÄ" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Neznámy príkaz alebo výraz" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Zaneprázdnený" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Momentálne nemôžem skontrolovaÅ¥ aktualizácie" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "vyžadované MTA:SA %s" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Pre pripojenie na vybraný server je potrebné aktualizovaÅ¥ MTA:SA %s .\n\n" -"ChceÅ¡ stiahnuÅ¥ a nainÅ¡talovaÅ¥ MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "ChceÅ¡ spustiÅ¥ MTA:SA %s a pripojiÅ¥ sa na tento server?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Nie je možné sa teraz pripojiÅ¥.\n\n" -"Skúste to neskôr." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Pripája sa" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Prosím poÄkajte..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "KONTROLUJEM" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "KONTROLA AKTUALIZÃCIÃ" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Nie je potreba aktualizácie" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "SŤAHOVANIE" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "ÄŒakám..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "NUTNà UPDATE" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Pre pripojenie na tento server musíš aktualizovaÅ¥ MTA.\n\n" -"AktualizovaÅ¥ teraz?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "VOLITEĽNà UPDATE" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Server hovorí že je doporuÄené aktualizovaÅ¥ MTA, ale nie je to potrebné.\n\n" -"AktualizovaÅ¥ teraz?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "CHYBA UKLADANIA" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Nepodarilo sa vytvoriÅ¥ súbor." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "CHYBA SŤAHOVANIA" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Stiahnutý súbor sa zdá byÅ¥ nekorektný." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Z nejakého dôvodu." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "SŤAHOVANIE KOMPLETNÉ" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "- Neznámy problém v _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ok" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "CHYBA" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Niektoré MTA:SA súbory chýbajú.\n\n\n" -"PreinÅ¡taluj prosím MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% dokonÄené" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"ÄŒakám na odpoveÄ - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Pripájanie zlyhalo. Neplatný nick!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Pripájanie zlyhalo. Neplatný hostiteľ!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Pripájanie k %s na porte %u zlyhalo!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Pripájanie k %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "PRIPÃJANIE" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "ÄŒasový limit spojenia vyprÅ¡al" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Odpojené: neznámy protokol" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Odpojené: odpojené vzdialene" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Odpojené: spojenie vzdialene stratené" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Odpojené: si zabanovaný na tomto serveri" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Odpojené: odpojené zo servera" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Odpojené: pripojenie na server bolo stratené" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Odpojené: pripojenie bolo odmietnuté" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Nie je inÅ¡talovaný taký mód (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Chybná odpoveÄ servera (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Chybná odpoveÄ servera (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "Novinky" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "NavÅ¡tíviÅ¥ najnovÅ¡ie oznámenie" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONZOLA" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Fatálna chyba" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "PRE OPRAVU, ODSTRÃŇTE NÃSLEDUJÚCI SÚBOR:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s modul je neplatný!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Chyba pri otváraní URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "táto pomocná obrazovka" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "ukonÄí aplikáciu" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "zobrazí verziu" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "zobrazí Äas" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "zobrazí hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "zobrazí vÅ¡etky bindy" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "zobrazí tvoj serial" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "pripojí na server (hostiteľ port nick heslo)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "pripojí k predchádzajúcemu serveru" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "nastaví bind (kontrola klávesy)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "zruší bind (klávesa)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "skopíruje predvolené gta ovládanie" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "uloží screenshot" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "okamžite uloží config" -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "vyÄistí debug" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "roluje chatom hore" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "roluje chatom dole" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "roluje debugom hore" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "roluje debugom dole" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "zobrazí Å¡tatistiky pamäte" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "zobrazí graf Äasovania snímkov" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "pre vývojárov: znovunaÄítajte novinky" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ PRÃKAZY ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Práve je %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "connect: Správny tvar je 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "connect: Nesprávne Äíslo portu" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "connect: Pripája sa k %s:%u..." - -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "connect: nemôže sa pripojiÅ¥ k %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "vyÄistí debug" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "connect: Zlyhalo vypínanie aktuálneho modu" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "roluje chatom hore" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "roluje chatom dole" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "roluje debugom hore" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "roluje debugom dole" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "zobrazí Å¡tatistiky pamäte" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "NaÄítané vÅ¡etky ovládania z GTA" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "zobrazí graf Äasovania snímkov" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "KonfiguraÄné súbory uložené" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "pre vývojárov: znovunaÄítajte novinky" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Tvoj serial je: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Používate novÅ¡iu verziu (feature-branch build)! Je to testovacia verzia a nemôže byÅ¥ použitá na pripojenie na public servery!" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Os akcelerácie" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA nebude podporovaÅ¥ XP/Vista po Júli 2019.\n\n" +"Aktualizujte Windows aby ste mohli hraÅ¥ na aktuálnych serveroch." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Os brzdenia" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Toto Å¥a odpojí z aktuálneho serveru.\n\n" +"Si si istý, že sa chceÅ¡ odpojiÅ¥?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programovanie" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "VAROVANIE O ODPOJENÃ" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Prispievatelia" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Herný Design / Scriptovanie" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "Novinky" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Jazyková lokalizácia" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "NavÅ¡tíviÅ¥ najnovÅ¡ie oznámenie" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Patch prispievatelia" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Screenshot má %d bytov, ale má byÅ¥ %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Å peciálne poÄakovanie" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Screenshot zlyhal" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Tento software a projekt používa nasledujúce knižnice a software:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Screenshot zachytený: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "ChceÅ¡ sa pozrieÅ¥ na online pomoc o tomto probléme ?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Neznámy príkaz alebo výraz" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2396,25 +2382,56 @@ msgid "Group control backwards" msgstr "Skupinové ovládanie dozadu" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Vybraný skin nemôže byÅ¥ naÄítaný ako aj predvolený skin, prosím preinÅ¡taluj MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Screenshot má %d bytov, ale má byÅ¥ %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "ChceÅ¡ sa pozrieÅ¥ na online pomoc o tomto probléme ?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Screenshot zlyhal" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONZOLA" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Screenshot zachytený: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programovanie" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Prispievatelia" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Herný Design / Scriptovanie" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Jazyková lokalizácia" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Patch prispievatelia" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Å peciálne poÄakovanie" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Tento software a projekt používa nasledujúce knižnice a software:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Os akcelerácie" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Os brzdenia" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2422,6 +2439,65 @@ msgstr "Nemožno inicializovaÅ¥ Direct3D3.\n\n" "Prosím uisti sa že DirectX End-User beží a\n" "že je Windows Service Pack správne nainÅ¡talovaný." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "NeÄinný" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "hráÄov" +msgstr[1] "hráÄ" +msgstr[2] "hráÄi" +msgstr[3] "hráÄov" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "na" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "serverov" +msgstr[1] "server" +msgstr[2] "servery" +msgstr[3] "servery" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Požiadavka na hlavný zoznam serverov (%lu ms ubehlo)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Zoznam hlavných serverov nemohol byÅ¥ naÄítaný." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Zoznam hlavných serverov nemohol byÅ¥ naÄítaný." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Záložný zoznam serverov)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Nie je možné pripojenie LAN" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Pokúšam sa nájsÅ¥ LAN servery" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2475,7 +2551,7 @@ msgstr "Oneskorenie:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Zoznam hráÄov" @@ -2502,40 +2578,39 @@ msgstr "PripojiÅ¥ na server hneÄ keÄ sa uvolní slot." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "PROSÃM ZADAJ HESLO K SERVERU" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "ÄŒas vyprÅ¡al" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "ZisÅ¥ovanie..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "SERVERY" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Lokálny" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Obľúbené" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Naposledy použité" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2543,302 +2618,367 @@ msgstr "PRE RÃCHLE PRIPOJENIE:\n\n" "Napíš adresu a port do adresného riadku.\n" "Alebo vyber server z histórie a klikni na 'PripojiÅ¥'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "POMOC" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "ObnoviÅ¥" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "PridaÅ¥ Obľúbené" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "PripojiÅ¥" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Informácie o serveri" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "VyhľadaÅ¥ servery" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "VyhľadaÅ¥ hráÄov" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "ZaÄaÅ¥ hľadanie" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "HľadaÅ¥ hráÄov..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "HľadaÅ¥ servery..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Meno" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "HráÄi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Odozva" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Herný mód" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Zahrnúť:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Prázdny" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Plný" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Na heslo" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Offline" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Iné verzie" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Späť" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "NaÄítavanie..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "..naÄítavanie.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Nebola zadaná adresa!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Neznámy protokol" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Prosím použi mtasa:// protokol!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Neplatný nick! ChoÄ do Nastavení a nastav si iný!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Musíš zvoliÅ¥ server na pripojenie." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "NeÄinný" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problém s grafickým ovládaÄom" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "hráÄov" -msgstr[1] "hráÄ" -msgstr[2] "hráÄi" -msgstr[3] "hráÄov" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Nedá sa nájsÅ¥ platné rozlíšenie obrazovky." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "na" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Naozaj chcete použiÅ¥ toto rozlíšenie obrazovky?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "serverov" -msgstr[1] "server" -msgstr[2] "servery" -msgstr[3] "servery" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Požiadavka na hlavný zoznam serverov (%lu ms ubehlo)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Zoznam hlavných serverov nemohol byÅ¥ naÄítaný." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Požiadavky stránky" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Zoznam hlavných serverov nemohol byÅ¥ naÄítaný." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Server si vyžiadal povolenie na naÄítanie týchto stránok (neskorÅ¡ie):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Záložný zoznam serverov)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NIKDY NEZADÃVAJTE CITLIVÉ INFORMÃCIE ABY VÃM NEBOLI UKRADNUTÉ" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Nie je možné pripojenie LAN" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "ZapamätaÅ¥ rozhodnutie" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Pokúšam sa nájsÅ¥ LAN servery" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "ZakázaÅ¥" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Táto verzia už vyprÅ¡ala." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "odpojiÅ¥ z hry" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "zobrazí nametagy" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "zobrazí chat" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "zobrazí sieÅ¥ové Å¡tatistiky" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "zobrazí vstup chatu" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "prenáša hlas ostatným hráÄom" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "vstúpi do auta ako pasažier" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "ÄalÅ¡ia rádio stanica" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "predchádzajúce rádio stanica" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "poÅ¡le správu oznaÄenému hráÄovi" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "prepne na ÄalÅ¡iu zbraň keÄ si vo vozidle" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "prepne na predchádzajúcu zbraň keÄ si vo vozidle" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "vypísaÅ¥ informácie o aktuálnom serveri" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "definuje násobiÄ mierky vÅ¡etkých textových zobrazení" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Vývojársky mód) zobrazí col tvary" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Vývojársky mód) zobrazí id svetových zvukov v okne debugu" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "VYTVORIŤ HRU" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Zdroje" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Meno serveru:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Heslo:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Max hráÄov:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Vysielanie:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Zvolené" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "VÅ¡etko" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Å tart" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Priebeh sÅ¥ahovania mapy:" @@ -2859,174 +2999,174 @@ msgstr "%s z %s" msgid "Disconnect to cancel download" msgstr "Odpoj sa pre zruÅ¡enie sÅ¥ahovania" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Odpojené: Neplatný nick" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Odpojené zo serveru" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Odpojené: Serial je zabanovaný.\n" "Dôvod: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Odpojené: Si zabanovaný.\n" "Dôvod: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Odpojené: ÚÄet je zabanovaný.\n" "Dôvod: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Odpojené: Nezhoda verzií" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Odpojené: Join flood. PoÄkaj prosím minútu, potom sa znovu pripoj." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Odpojené: Server z inej vetvy.\n" "Informácie: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Odpojené: Zlá verzia.\n" "Informácie: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Odpojené: Server beží na novÅ¡ej verzií (build).\n" "Informácie: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Odpojené: Server beží na starÅ¡ej verzií.\n" "Informácie: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Odpojené: Nick sa už používa" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Odpojené: Prvok sa nepodarilo vytvoriÅ¥." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Odpojené: Server odmietol spojenie: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Odpojené: Overovanie serialu zlyhalo" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Odpojené: Chyba pripojenia (desync) %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Odpojené: Bol si vyhodený hráÄom %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Odpojené: Bol si zabanovaný hráÄom %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Odpojené: Server sa vypol alebo sa reÅ¡tartuje" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Bol si vyhodený z hry" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Tento server vyžaduje neupravený súbor gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "NahraÄte súbor gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Tento server nepovoľuje vlastné D3D9.DLL" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Odstráňte D3D9.DLL z inÅ¡talaÄného adresára GTA a reÅ¡tartujte MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Tento server nepovoľuje virtuálne stroje" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Tento server vyžaduje povolenie podpisovania ovládaÄov" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Prosím reÅ¡tartujte PC" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Tento server zistil chýbajúce anti-cheat komponenty" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Skúste reÅ¡tartovaÅ¥ MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Tento server vyžaduje neupravené gta3.img a gta_int.img súbory" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "NahraÄte prosím gta3.img alebo gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Tento server nepovoľuje službu Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Uistite sa, že žiadny iný program neupravuje MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Zostávajúci Äas:" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" @@ -3035,7 +3175,7 @@ msgstr[1] "%d deň" msgstr[2] "%d dni" msgstr[3] "%d dní" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" @@ -3044,7 +3184,7 @@ msgstr[1] "%d hodina" msgstr[2] "%d hodiny" msgstr[3] "%d hodín" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" @@ -3053,7 +3193,7 @@ msgstr[1] "%d minúta" msgstr[2] "%d minúty" msgstr[3] "%d minúty" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3063,296 +3203,206 @@ msgstr[2] "%d Sekúnd" msgstr[3] "%d Sekundy" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Odpojené" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Chyba sÅ¥ahovania: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "Lieta s UFO v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "Pláva v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "Ide na vlnách v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "Ide vlakom v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "Lieta v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "Jazdí v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "Jazdí s monster truckom v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "Jazdí so Å¡tvorkolkou v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "SkáÄa v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "Robí divné veci v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "Lezie v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "Robí drive-by v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "Blub blub..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "Dýcha vodu" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "Topí sa v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "خم شدن برای پناه Ú¯Ø±ÙØªÙ†" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "Bojuje v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "Bojuje päsÅ¥ami v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "Strieľa v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "Strieľa" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "Lieta s jetpackom v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "Horí v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "Horí v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "Pláva v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "Vznáša sa v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "Je prenasledovaný žralokom" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "Dusí sa v" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Vstupujem do hry..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Nepripojené; použi prosím Rýchle pripojenie alebo príkaz 'connect' pre pripojenie k serveru." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Nemožno spustiÅ¥ lokálny server. Pozri konzolu pre viac informácií." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Lokálny server" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Spúšťam lokálny server..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "Area 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "Chodí v " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Bol si vyhodený z hry ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Pripájam sa k lokálnemu serveru..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Chyba pri pripájaní na server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "ÄŒas pripájania k lokálnemu serveru vyprÅ¡al. Pre viac informácií sa pozri do konzoly." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Spojenie zo serverom bolo stratené" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Odpojené: server je momentálne plný" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Odpojené: zadané nesprávne heslo" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "Overenie MTA Klienta zlyhalo!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "V priekope" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "Ide do nemocnice" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "Stretáva sa s jeho markerom" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "Ľutuje jeho rozhodnutie" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "Je mÅ•tvy" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "VYTVORIŤ HRU" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Zdroje" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Meno serveru:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Heslo:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Max hráÄov:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Vysielanie:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Zvolené" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "VÅ¡etko" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Å tart" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problém s grafickým ovládaÄom" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Nedá sa nájsÅ¥ platné rozlíšenie obrazovky." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Naozaj chcete použiÅ¥ toto rozlíšenie obrazovky?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Chyba sÅ¥ahovania: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3373,11 +3423,11 @@ msgstr "" msgid "Connection error" msgstr "Chyba pripojenia" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto nebolo správne nainÅ¡talované, prosím preinÅ¡taluj." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Tvoj prehliadaÄ teraz zobrazí web stránku s nejakými užitoÄnými informáciami.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/sl_SI/client.pot b/Shared/data/MTA San Andreas/MTA/locale/sl_SI/client.pot index 788ecef98c0..47f34edf3cd 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/sl_SI/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/sl_SI/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Slovenian\n" "Language: sl_SI\n" @@ -17,72 +17,120 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Težava pri ponovnem zagonu MTA:SA\n\n" -"ÄŒe se problem ponavlja, zaženite Upravitelja opravil in\n" -"konÄajte procesa 'gta_sa.exe' in 'Multi Theft Auto.exe'\n\n\n" -"Želite ponovno zagnati MTA:SA?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Napaka" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Druga instanca MTA že teÄe.\n\n" -"ÄŒe se ta problem ponavlja, prosimo, da ponovno zaženete svoj raÄunalnik" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Druga instanca MTA že teÄe.\n\n" -"Ali jo želite ustaviti?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Izberite svojo Grand Theft Auto: San Andreas namestitveno mapo" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA potrebuje dovoljenje administratorja za naslednjo nalogo:\n\n" +"'%s'\n\n" +"Prosimo potrdite v naslednjem oknu." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Napaka pri nalaganju %s modula! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Kopiram datoteke..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopija je konÄala zgodaj. Vse je v redu." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "ZakljuÄevanje..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "KonÄano!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "" + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "" + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "" + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "" + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Imate probleme med igranjem MTA:SA?\n\n" "Ali želite namestiti starejÅ¡o razliÄico?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,170 +138,333 @@ msgstr "Pri zagonu MTA:SA se je pojavil problem.\n" "Ponastavitev GTA nastavitev vÄasih reÅ¡i ta problem.\n\n" "Ali želite ponastaviti GTA nastavitve zdaj?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA nastavitve so bile ponastavljene.\n\n" "Pritisnite V redu za nadaljevanje." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Datoteke ni mogoÄe zbrisati: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Ali imate težave med igranjem MTA:SA?\n\n" "Ali si želite ogledati spletno pomoÄ?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Celozaslonski naÄin:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Okno brez okvirja" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" msgstr "" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Proces GTA: San Andreas že teÄe. Biti mora prekinjen, preden zaženete MTA:SA. Ali želite to narediti zdaj?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informacije" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Ni bilo mogoÄe prekiniti GTA: San Andreas. ÄŒe problem ostaja, prosimo, da ponovno zaženete svoj raÄunalnik." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Težava pri ponovnem zagonu MTA:SA\n\n" +"ÄŒe se problem ponavlja, zaženite Upravitelja opravil in\n" +"konÄajte procesa 'gta_sa.exe' in 'Multi Theft Auto.exe'\n\n\n" +"Želite ponovno zagnati MTA:SA?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Napaka" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Druga instanca MTA že teÄe.\n\n" +"ÄŒe se ta problem ponavlja, prosimo, da ponovno zaženete svoj raÄunalnik" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Druga instanca MTA že teÄe.\n\n" +"Ali jo želite ustaviti?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Vpisi registra manjkajo. Prosimo, ponovno namestite Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Pot, kjer je nameÅ¡Äen GTA: San Andreas vsebuje nepodprte (unicode) znake. Prosimo, premaknite Grand Theft Auto: San Andreas namestitev na združljivo pot, ki vsebuje samo standardne ASCII znake in ponovno namestite Multi Theft Auto: San Andreas" -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Pot do vaÅ¡e namestitvije 'MTA:SA' ali 'GTA: San Andreas'\n" -"vsebuje ';' (podpiÄje),\n\n" -"ÄŒe naletite na probleme med igranjem MTA:SA,\n" -"premaknite namestitev na pot, ki ne vsebuje podpiÄja." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Nalaganje se je izjalovilo. Prosimo preverite, da so bile najnovejÅ¡e podatkovne datoteke nameÅ¡Äene pravilno." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Nalaganje se je izjalovilo. Prosimo preverite, da je %s nameÅ¡Äen pravilno." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Nalaganje se je izjalovilo. Ni bilo mogoÄe najti gta_sa.exe v %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Nalaganje se je izjalovilo. %s obstaja v GTA mapi. Prosimo, da ga pred nadaljevanjem izbriÅ¡ete." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Data file %s is modified. Possible virus activity." msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" +msgstr "" + +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "" + +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." msgstr "" -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA ne more dokonÄati naslednje naloge:\n\n" +"'%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Sesutje je povzroÄila napaka na grafiÄnem gonilniku **\n\n" +"** Prosimo, posodobite gonilnik vaÅ¡e grafiÄne kartice **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" msgstr "" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Namestitev je posodobila MTA:SA datoteke" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Ni mogoÄe posodobiti zaradi konfliktov z datotekami. Prosimo, zaprite ostale aplikacije in poskusite znova" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto no bil nameÅ¡Äen pravilno, prosimo, da ponovno namestite. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Copiar archivos de MTA:SA" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" msgstr "" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Ni bilo mogoÄe zagnati Grand Theft Auto: San Andreas. Prosimo, da poskusite s ponovnim zagonom. ÄŒe pa se problem pojavlja, se obrnite na MTA na http://www.multitheftauto.com/ .\n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Posodobi namestitveno nastavitev" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas se ni zagnal pravilno. Ali hoÄete prekiniti ta proces?" +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "" #. ///////////////////////////////////////////////////////////////////////// #. @@ -261,1264 +472,1343 @@ msgstr "GTA: San Andreas se ni zagnal pravilno. Ali hoÄete prekiniti ta proces? #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Da" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Ne" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "V redu" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Izhod" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "PomoÄ" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "PrekliÄi" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "" -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." msgstr "" -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "" -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "IÅ¡Äem Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Prosimo zaženite Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "" +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Povezava prekinjena. Neveljavno ime!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Povezava prekinjena. NapaÄen gostitelj!" + +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Vzpostavljanje povezave s %s pri vratih %u ni uspelo!" + +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Vzpostavljanje povezave s %s:%u ..." + +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." msgstr "" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Kopiram datoteke..." +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "VZPOSTAVLJANJE POVEZAVE" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopija je konÄala zgodaj. Vse je v redu." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Povezava je potekla" -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "ZakljuÄevanje..." +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Prekinjeno: neznana napaka protokola" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "KonÄano!" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Povezava prekinjena: povezava prekinjena na daljavo" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA potrebuje dovoljenje administratorja za naslednjo nalogo:\n\n" -"'%s'\n\n" -"Prosimo potrdite v naslednjem oknu." +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Povezava prekinjena: povezava izgubljena na daljavo" + +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Povezava prekinjena: Nimate veÄ dostopa do strežnika" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Povezava prekinjena: Odjava iz strežnika" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Povezava prekinjena: Povezava s strežnikom je bila prekinjena." + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Povezava prekinjena: Povezava je bila zavrnjena" -#: Client/loader/CInstallManager.cpp:376 +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA ne more dokonÄati naslednje naloge:\n\n" -"'%s'\n" +msgid "No such mod installed (%s)" +msgstr "Tak naÄin ni nameÅ¡Äena (%s)" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Sesutje je povzroÄila napaka na grafiÄnem gonilniku **\n\n" -"** Prosimo, posodobite gonilnik vaÅ¡e grafiÄne kartice **" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Slab odziv strežnika (2)" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Namestitev je posodobila MTA:SA datoteke" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Slab odziv strežnika (1)" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Ni mogoÄe posodobiti zaradi konfliktov z datotekami. Prosimo, zaprite ostale aplikacije in poskusite znova" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "SlovenÅ¡Äina" + +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Zaposlen" + +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Trenutno ni mogoÄe preveriti za posodobitve" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto no bil nameÅ¡Äen pravilno, prosimo, da ponovno namestite. %s" +msgid "MTA:SA %s required" +msgstr "MTA:SA %s potreben" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Posodobljena verzija MTA:SA %s je potrebna, da se povežete s tem strežnikom.\n\n" +"Ali želite naložiti in namestiti MTA:SA %s ?" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Ali želite zagnati MTA:SA %s in se povezati s tem strežnikom?" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Trenutno se ni mogoÄe povezati.\n\n" +"Prosimo poskusite kasneje." -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Copiar archivos de MTA:SA" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Vzpostavljanje povezave" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Prosimo, poÄakajte..." -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "PREVERJANJE" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "PREVERJANJE POSODOBITVE" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Posodobitve niso potrebne" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "NALAGANJE" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "Äakanje..." -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "OBVEZNA POSODOBITEV" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Da se povežete s tem strežnikom, morate posodobiti MTA.\n\n" +"Želite posodobiti zdaj?" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "NEOBVEZNA POSODOBITEV" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Strežnik pravi da je priporoÄena posodobitev, ampak ne nujno.\n\n" +"Ali želite posodobiti zdaj?" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Posodobi namestitveno nastavitev" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "NAPAKA PRI SHRANJEVANJU" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Ni mogoÄe ustvariti datoteke." -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "NAPAKA PRI NALAGANJU" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Naložena datoteka je napaÄna." -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Iz neznanega razloga." -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "NALAGANJE ZAKLJUÄŒENO" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr "- Neznan problem v _DialogUpdateResult" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "SPREMENJENE GTA:SA DATOTEKE" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Izberite svojo Grand Theft Auto: San Andreas namestitveno mapo" +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "V redu" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Napaka pri nalaganju %s modula! (%s)" +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "NAPAKA" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Nekatere MTA:SA datoteke manjkajo.\n\n\n" +"Prosimo, da ponovno namestite MTA:SA" -#: Client/loader/Utils.cpp:1538 +#: Client/core/CVersionUpdater.cpp:2837 #, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "" +msgid "%3d %% completed" +msgstr "%3d %% konÄano" -#: Client/loader/Utils.cpp:1560 +#: Client/core/CVersionUpdater.cpp:2840 #, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "" - -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "" - -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "" +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"ÄŒakam na odziv - %-3d" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ POMOÄŒ ZA UKAZE ]***\n" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CCommandFuncs.cpp:158 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "" +msgid "* The time is %d:%02d:%02d" +msgstr "* Trenuten Äas je %d:%02d:%02d" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" msgstr "" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "povezava: Sintaksa je 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "povezava: Slaba Å¡tevilka vrat" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "povezava: Povezovanje na %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "povezava: ne more se povezati na %s:%u!" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "povezava: Trenutnega naÄina igre ni bilo mogoÄe naložiti" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" msgstr "" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." msgstr "" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" msgstr "" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA ne bo pridobivala posodobitev na XP/Vista po Juliju 2019.\n\n" -"Nadgradite Windows za igranje na najnovejÅ¡ih strežnikih." - -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "To bo prekinilo povezavo s trenutnim strežnikom.\n\n" -"Ali ste prepriÄani da želite prekiniti povezavo?" - -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "OPOZORILO O PREKINJENI POVEZAVI" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Zavezuje vse kontrole iz GTA" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Shrani nastavitve datoteke" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "SlovenÅ¡Äina" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* VaÅ¡a serijska Å¡tevilka je: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "NASTAVITVE" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "VeÄigralski naÄin" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Video posnetek" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Funkcije tipk" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Nadzor" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Vmesnik" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Napredno" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Naloži privzete vrednosti" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "ObÄutljivost miÅ¡ke:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "ObÄutljivost vertikalnega merjenja:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Možnosti miÅ¡ke" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Obrni miÅ¡ko vertikalno" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Vodi z miÅ¡ko" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Leti z miÅ¡ko" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Možnosti igralne konzole" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standardne kontrole (MiÅ¡ka + Tipkovnica)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "KlasiÄne kontrole (Igralna konzola)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Mrtva cona" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "NasiÄenost" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Uporabi zavihek 'Funkcije tipk' za gumbe na igralni konzoli." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Leva palica" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Desna palica" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "OPIS" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "TIPKA" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. TIPKA" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Vzdevek:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Shrani gesla strežnikov" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "AvtomatiÄno osveži brskalnik strežnikov" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Dovoli nalaganje zaslona" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Uporabi spremenjene GTA:SA datoteke" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Možnosti upodabljanja mape" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Motnost:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Glasnost radia:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Glasnost SFX:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA glasnost:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Glasnost glasu:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "NaÄin igranja:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "SploÅ¡ni" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Radijski izenaÄevalnik" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "OmogoÄi avtomatiÄno uglaÅ¡evanje na radiju" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Možnosti uporabnikove glasbe" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "NakljuÄno" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Zaporedno" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "AvtomatiÄno poiÅ¡Äi medije" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "UtiÅ¡aj radio, ko je MTA minimiran" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "UtiÅ¡aj SFX zvoke, ko je MTA minimiran" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "UtiÅ¡aj MTA zvoke, ko je MTA minimiran" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "UtiÅ¡aj glasovne zvoke, ko je MTA minimiran" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "LoÄljivost:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Razdalja risanja:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Svetlost:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX kakovost:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anizotropno filtriranje:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Glajenje robov:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Razmerje slike:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "V oknu" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Navadno" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Celozaslonski naÄin brez robov" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "MIP kartiranje" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Nizko" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Srednje" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Visoko" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Zelo visoko" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Izklopljeno" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1-krat" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2-krat" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3-krat" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Samodejno" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Prostorninsko senÄenje" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "UÄinek trave" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Toplotna megla" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Minimiraj v celozaslonskem naÄinu" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "OmogoÄi pogovorno okno za izbor naprave" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Razno" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Hitro nalaganje CJ-jevih oblek:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Hitrost brskalnika:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Ena povezava:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Prednost procesa:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Nastavitve odpravljalca napak:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Spomin za pretakanje:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Vrsta posodobitve:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "VkljuÄeno" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Zelo poÄasi" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Privzeto" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Hitro" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Najmanj" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "NajveÄ" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Samodejni posodobljevalnik" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Preveri za posodobitve" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Ali želite znova zagnati zdaj?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "POTREBEN PONOVEN ZAGON" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Niektóre ustawienia zostanÄ… zmienione po odłączeniu bieżącego serwera" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "WYMAGANE ODÅÄ„CZENIE" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Igralna konzola ni bila najdena - Preverite prikljuÄke in ponovno zaženite igro" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Os funkcij tipk" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Premakni os na funkcijo tipke, ali izhod za izbris" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Jezik:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Koža:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Prednastavitve:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Klepet" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Naloži" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Kolory" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "UkÅ‚ad" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Opcje" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "TÅ‚o czatu" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Besedilo klepeta" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Vnesi besedilo" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Vrstice:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Merilo:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Å irina:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Rozmiar" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "potem" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "za" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "sekunda" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Pobledi stare proge" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Poziomo:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Pionowo:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Wyrównanie tekstu:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Levo" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Desno" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Skrij ozadje ko ne tipkam" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "" @@ -1526,109 +1816,115 @@ msgstr "" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Pritisnite tipko za spremembo funkcije tipke, ali izhod za izbris" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "DoloÄi funkcijo primarni tipki" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "DoloÄi funkcijo sekundarni tipki" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "UKAZI IGRE GTA" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "UKAZI VEÄŒIGRALSKEGA NAÄŒINA" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "VaÅ¡ vzdevek vsebuje napaÄne znake!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "RdeÄa:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Zelena:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Modra:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Prosojnost:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Prosimo, da prekinete povezavo, preden spremenite kožo" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Prostorske sence lahko upoÄasnijo nekatere sisteme.\n\n" "Ali ste prepriÄani, da jih želite omogoÄiti?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "OPOZORILO UÄŒINKOVITOSTI" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Nalaganje zaslona je potrebno na nekaterih strežnikih za protigoljufijske namene.\n\n" "(Klepet in GUI sta izkljuÄena iz nalaganja)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "INFORMACIJE O NALOŽENEM ZASLONU" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1638,561 +1934,259 @@ msgstr "Nekatere datoteke v vaÅ¡i GTA:SA mapi so spremenjene.\n" "SPREMENJENE GTA:SA DATOTEKE SO BLOKIRANE NA VEÄŒ STREŽNIKIH\n\n" "Ali ste prepriÄani da jih želite uporabiti?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "SPREMENJENE GTA:SA DATOTEKE" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" "Are you sure you want to enable this option?" msgstr "" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Prosimo vnesite vzdevek" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Prosimo vnesite vzdevek, ki ga boste uporabljali v igri.\n" "To bo vaÅ¡e ime, ko boste povezani na strežnik" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Zelo eksperimentalna funkcija." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Ustavi stojnice z CJ-jevimi variacijami (Porabi 65MB veÄ spomina RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "StarejÅ¡i usmerjevalniki lahko zahtevajo poÄasnejÅ¡o hitrost pregledovanja." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "OznaÄite, Äe želite med nalaganjem uporabljati samo eno povezavo." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "" -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Vedno izberi privzeto. (Ta nastavitev se ne shrani)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "NajveÄ je obiÄajno najboljÅ¡e" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "AvtomatiÄni posodobljevalnik:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Izberite privzeto, razen Äe želite izpolnjevati poroÄila o napakah." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Neznan ukaz ali glagol:" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Zaposlen" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Trenutno ni mogoÄe preveriti za posodobitve" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s potreben" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Posodobljena verzija MTA:SA %s je potrebna, da se povežete s tem strežnikom.\n\n" -"Ali želite naložiti in namestiti MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Ali želite zagnati MTA:SA %s in se povezati s tem strežnikom?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Trenutno se ni mogoÄe povezati.\n\n" -"Prosimo poskusite kasneje." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Vzpostavljanje povezave" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Prosimo, poÄakajte..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "PREVERJANJE" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "PREVERJANJE POSODOBITVE" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Posodobitve niso potrebne" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "NALAGANJE" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "Äakanje..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "OBVEZNA POSODOBITEV" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Da se povežete s tem strežnikom, morate posodobiti MTA.\n\n" -"Želite posodobiti zdaj?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "NEOBVEZNA POSODOBITEV" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Strežnik pravi da je priporoÄena posodobitev, ampak ne nujno.\n\n" -"Ali želite posodobiti zdaj?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "NAPAKA PRI SHRANJEVANJU" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Ni mogoÄe ustvariti datoteke." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "NAPAKA PRI NALAGANJU" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Naložena datoteka je napaÄna." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Iz neznanega razloga." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "NALAGANJE ZAKLJUÄŒENO" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "- Neznan problem v _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "V redu" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "NAPAKA" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Nekatere MTA:SA datoteke manjkajo.\n\n\n" -"Prosimo, da ponovno namestite MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% konÄano" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"ÄŒakam na odziv - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Povezava prekinjena. Neveljavno ime!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Povezava prekinjena. NapaÄen gostitelj!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Vzpostavljanje povezave s %s pri vratih %u ni uspelo!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Vzpostavljanje povezave s %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "VZPOSTAVLJANJE POVEZAVE" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Povezava je potekla" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Prekinjeno: neznana napaka protokola" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Povezava prekinjena: povezava prekinjena na daljavo" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Povezava prekinjena: povezava izgubljena na daljavo" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Povezava prekinjena: Nimate veÄ dostopa do strežnika" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Povezava prekinjena: Odjava iz strežnika" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Povezava prekinjena: Povezava s strežnikom je bila prekinjena." - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Povezava prekinjena: Povezava je bila zavrnjena" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Tak naÄin ni nameÅ¡Äena (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Slab odziv strežnika (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Slab odziv strežnika (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONZOLA" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Usodna napaka" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s modul je napaÄen!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Napaka pri izvrÅ¡evanju internetnega naslova" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "ta stran z navodili" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "KonÄaj aplikacijo" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "prikaže razliÄico" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "prikaže Äas" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "pokaže hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "pokaže vse bližnjice" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "prikaže vaÅ¡o serijsko Å¡tevilko" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "se povezuje s strežnikom (gostitelj vrata ime geslo)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "se povezuje na prejÅ¡nji strežnik" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "doloÄi tipko kot funkcijo (tipka ukaz)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "zbriÅ¡e funkcijo na tipki (tipka)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "kopira privzete gta nastavitve" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "prikaže posnetek zaslona" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "takoj shrani konfiguracije" -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "poÄisti pogled odpravljalca napak" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "pomakne klepet navzgor" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "pomakne klepet navzdol" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "pomakne pogled odpravljalca napak navzgor" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "pomakne pogled odpravljalca napak navzdol" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "prikaže statistiko spomina" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "prikaže Äasovni graf okvirja" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ POMOÄŒ ZA UKAZE ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Trenuten Äas je %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "povezava: Sintaksa je 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "povezava: Slaba Å¡tevilka vrat" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "povezava: Povezovanje na %s:%u..." - -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "povezava: ne more se povezati na %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "poÄisti pogled odpravljalca napak" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "povezava: Trenutnega naÄina igre ni bilo mogoÄe naložiti" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "pomakne klepet navzgor" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "pomakne klepet navzdol" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "pomakne pogled odpravljalca napak navzgor" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "pomakne pogled odpravljalca napak navzdol" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "prikaže statistiko spomina" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Zavezuje vse kontrole iz GTA" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "prikaže Äasovni graf okvirja" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Shrani nastavitve datoteke" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* VaÅ¡a serijska Å¡tevilka je: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "PospeÅ¡itvena os" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA ne bo pridobivala posodobitev na XP/Vista po Juliju 2019.\n\n" +"Nadgradite Windows za igranje na najnovejÅ¡ih strežnikih." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Zavorna os" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "To bo prekinilo povezavo s trenutnim strežnikom.\n\n" +"Ali ste prepriÄani da želite prekiniti povezavo?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programiranje" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "OPOZORILO O PREKINJENI POVEZAVI" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Avtorji prispevkov" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Dizajn igre / Skriptanje" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Prevod" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Avtorji popravka" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Posnetek zaslona je prejel %d bitov od priÄakovanih %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Prevod" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Posnetek zaslona ni uspel" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Posnetek zaslona shranjen: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Ali si želite ogledati internetno pomoÄ o tem problemu?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Neznan ukaz ali glagol:" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2367,25 +2361,56 @@ msgid "Group control backwards" msgstr "Nadzor skupine nazaj" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Preobleka, ki ste jo izbrali, ni bilo mogoÄe naložiti, tudi privzete preobleke ni bilo mogoÄe naložiti, prosimo, da ponovno namestite MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Posnetek zaslona je prejel %d bitov od priÄakovanih %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Ali si želite ogledati internetno pomoÄ o tem problemu?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Posnetek zaslona ni uspel" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONZOLA" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Posnetek zaslona shranjen: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programiranje" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Avtorji prispevkov" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Dizajn igre / Skriptanje" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Prevod" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Avtorji popravka" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Prevod" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "PospeÅ¡itvena os" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Zavorna os" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2393,6 +2418,65 @@ msgstr "Ni bilo mogoÄe inicializirati Direct3D9.\n\n" "Prosimo preverite, Äe sta na vaÅ¡i napravi naložena DirectX End-User Runtime in\n" "najnovejÅ¡i Windows servisni paket.." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Nedejaven" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "igralcev" +msgstr[1] "igralec" +msgstr[2] "igralca" +msgstr[3] "igralci" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "na" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "na" +msgstr[1] "na" +msgstr[2] "na" +msgstr[3] "na" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Zahtevam glavni seznam strežnikov (%lu ms preteklo)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Glavnega seznama strežnikov ni bilo mogoÄe razÄleniti." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Glavni seznam strežnikov ni bil najden." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Rezervni seznam strežnikov)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Ne morem vezati LAN-broadcast vtiÄnice" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "PoskuÅ¡am odkriti LAN strežnike" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2446,7 +2530,7 @@ msgstr "Zakasnitev:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Seznam igralcev" @@ -2473,40 +2557,39 @@ msgstr "Pridruži se strežniku takoj, ko bo na voljo prostor." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "PROSIMO VNESITE GESLO STREŽNIKA" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Povezava je potekla" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Poizvedovanje..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "PoiÅ¡Äi strežnik" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Lokalno" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Priljubljene" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Nedavno" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2514,302 +2597,367 @@ msgstr "ZA HITER DOSTOP:\n\n" "VpiÅ¡ite naslov in vrata v naslovno vrstico.\n" "Ali izberite strežnik iz seznama zgodovine in pritisnite 'Vzpostavi povezavo'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "POMOÄŒ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Osveži" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Dodaj med priljubljene" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Poveži" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Informacije o strežniku" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "IÅ¡Äi strežnike" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "IÅ¡Äi igralce" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "ZaÄni z iskanjem" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "IÅ¡Äi igralce..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "IÅ¡Äi strežnike..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Ime" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Igralci" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "NaÄin igre" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "VkljuÄi:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Prazno" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Polno" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Zaklenjeno" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Brez povezave" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Druge razliÄice" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Nazaj" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Nalaganje..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "..nalaganje.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Naslov ni naveden!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Neznan protokol" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Prosimo uporabite mtasa:// protokol!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "NapaÄen vzdevek! Prosimo pojdite na Nastavitve in si izberite drugega!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Izbrati morate strežnik." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Nedejaven" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "igralcev" -msgstr[1] "igralec" -msgstr[2] "igralca" -msgstr[3] "igralci" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "No se puede encontrar una resolución válida." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "na" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "¿Estas seguro que quieres usar esta resolucion de pantalla?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "na" -msgstr[1] "na" -msgstr[2] "na" -msgstr[3] "na" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Zahtevam glavni seznam strežnikov (%lu ms preteklo)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Glavnega seznama strežnikov ni bilo mogoÄe razÄleniti." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Glavni seznam strežnikov ni bil najden." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Rezervni seznam strežnikov)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Ne morem vezati LAN-broadcast vtiÄnice" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "PoskuÅ¡am odkriti LAN strežnike" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Ta razliÄica je potekla." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "prekini povezavo z igro" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "prikaže imena" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "prikaže klepet" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "prikaže omrežne statistike" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "odpri klepet" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "odda zvok drugim igralcem" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "vstopi v avto kot potnik" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "naslednja radijska postaja" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "prejÅ¡nja radijska postaja" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "poÅ¡lje sporoÄilo do izbranega igralca" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "premakne na naslednje orožje, ko ste v vozilu" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "premakne na prejÅ¡nje orožje, ko ste v vozilu" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "doloÄi velikost vseh polj z besedilom" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Razvojni naÄin) pokaže colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Razvojni naÄin) kopira isd zvok sveta v okno odpravljalca napak" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "GOSTUJ IGRO" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Sredstva" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Ime strežnika:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Geslo:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "NajveÄje Å¡tevilo igralcev:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Oddajanje:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Izbrano" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Vse" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "ZaÄni" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Napredek nalaganja map:" @@ -2830,174 +2978,174 @@ msgstr "%s od %s" msgid "Disconnect to cancel download" msgstr "Prekinite povezavo, da prenehate z nalaganjem" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Povezava prekinjena: NapaÄen vzdevek" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Prekini povezavo s strežnikom" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Povezava prekinjena: Serijska Å¡tevilka je izkljuÄena.\n" "Razlog: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Povezava prekinjena: Bili ste izkljuÄeni.\n" "Razlog: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Povezava prekinjena: RaÄun je izkljuÄen.\n" "Razlog: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Povezava prekinjena: Neusklajenost razliÄice" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Povezava prekinjena: Poplava prijav. Prosimo, poÄakajte minuto, potem poskusite znova." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Povezava prekinjena: Strežnik je iz razliÄne veje.\n" "Informacije: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Povezava prekinjena: Slaba razliÄica.\n" "Informacije: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Povezava prekinjena: Strežnik teÄe na novejÅ¡i razliÄici.\n" "Informacije: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Povezava prekinjena: Strežnik teÄe na starejÅ¡i razliÄici.\n" "Informacije: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Povezava prekinjena: Vzdevek je že v uporabi" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Povezava prekinjena: Strežnik je zavrnil povezavo: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Povezava prekinjena: Serijsko preverjanje se je izjalovilo" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Povezava prekinjena: Povezava se je desinhronizirala %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Povezava prekinjena: %s te je brcnil iz strežnika" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Povezava prekinjena: %s te je izkljuÄil iz strežnika" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Bil si brcnjen iz igre" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Preostali Äas:" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" @@ -3006,7 +3154,7 @@ msgstr[1] "%d dan" msgstr[2] "%d dneva" msgstr[3] "%d dnevi" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" @@ -3015,7 +3163,7 @@ msgstr[1] "%d ura" msgstr[2] "%d uri" msgstr[3] "%d ure" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" @@ -3024,7 +3172,7 @@ msgstr[1] "%d minuta" msgstr[2] "%d minuti" msgstr[3] "%d minute" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3034,296 +3182,206 @@ msgstr[2] "" msgstr[3] "" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Povezava prekinjena" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Napaka pri nalaganju: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Vstopam v igro..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Niste povezani; prosimo uporabite Hitra vzpostavitev povezave ali ukaz 'poveži' da se povežete na strežnik." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Ni mogoÄe zaÄeti lokalnega strežnika. Glej konzolo za podrobnosti." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Lokalni strežnik" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Zaganjanje lokalnega strežnika ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Bil si brcnjen iz igre ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Vzpostavljam povezavo z lokalnim strežnikom..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Napaka pri vzpostavljanju povezave s strežnikom." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Vzpostavljanje povezave s strežnikom je poteklo. Glej konzolo za podrobnosti." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Povezava s strežnikom je bila izgubljena" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Povezava prekinjena: strežnik je trenutno poln" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Povezava prekinjena: doloÄeno napaÄno geslo" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "Preverjanje MTA klienta se je izjalovilo!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "GOSTUJ IGRO" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Sredstva" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Ime strežnika:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Geslo:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "NajveÄje Å¡tevilo igralcev:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Oddajanje:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Izbrano" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Vse" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "ZaÄni" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "No se puede encontrar una resolución válida." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "¿Estas seguro que quieres usar esta resolucion de pantalla?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Napaka pri nalaganju: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3344,11 +3402,11 @@ msgstr "" msgid "Connection error" msgstr "Napaka povezave" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto ni bil pravilno nameÅ¡Äen, prosimo, da ga ponovno namestite." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "VaÅ¡ brskalnik bo sedaj prikazal spletno stran za pomoÄ in informacije.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/srp/client.pot b/Shared/data/MTA San Andreas/MTA/locale/srp/client.pot index f5419fd6621..8102d4a10c5 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/srp/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/srp/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:32\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Serbian\n" "Language: srp\n" @@ -17,72 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Imamo teÅ¡koće u restartovanju MTA:SA\n\n" -"Ako se problem nastavi, otvorite Task Manager\n" -"izaustavite 'gta_sa.exe' i 'Multi Theft Auto.exe' procese\n\n\n" -"Da li da pokuÅ¡amo da otvorimo MTA:SA ponovo?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Startuj Grand Theft Auto: San Andreas.\n" +"Potvrdi da se igra nalazi u 'Program Files (x86)' folderu." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "GreÅ¡ka" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "Traženje GTA: San Andreas" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "JoÅ¡ jedan prozor MTA već radi.\n\n" -"Ako se problem nastavi, restartujte vaÅ¡ kompjuter" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Izvinite, igra nije naÄ‘ena.\n" +"Startuj Grand Theft Auto: San Andreas i klikni pokuÅ¡aj ponovo.\n" +"Potvrdi da se igra nalazi u 'Program Files (x86)' folderu." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "JoÅ¡ jedan prozor MTA već radi.\n\n" -"Da li želite da ga iskljuÄite?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Izaberite vaÅ¡ Grand Theft Auto: San Andreas Instalacioni Direktorijum" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA-u treba pristup Administratoru za sledeći zadatak:\n\n" +" '%s'\n\n" +"Molimo vas potvrdite u sledećem prozoru." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "GreÅ¡ka pri uÄitavanju %s modula! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Kopiranje fajlova..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopiranje je zavrseno ranije. Sve je OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "ZavrÅ¡avanje..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Gotovo!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Nova instalacija od %s je otkrivena.\n\n" +"Da li želite da kopirate vaÅ¡a podeÅ¡avanja iz %s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA je imao problema sa otvaranjem datoteke '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA nedostaje datoteka '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA je imao problem sa uÄitavanjem modela." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Ukoliko ste skorije modifikovali gta3.img, onda pokuÅ¡ajte ponovo instalirati GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA je imao problem sa dodavanjem nadogradnje na vozilo." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA je pronaÅ¡ao greÅ¡ke u datoteci '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Da li se vaÅ¡ raÄunar ponovo pokrenuo u toku igranja MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Molimo vas prekinite sledeći program pre nego Å¡to nastavite:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "Nevažeća putanja za modul pronaÄ‘ena.\n" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "NeusklaÄ‘ena verzija datoteke. Ponovo instalirajte MTA:SA ukoliko budete imali problem.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Neke datoteke nedostaju. Ponovo instalirajte MTA:SA ukoliko budete imali problem.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA nije kompatibilan sa Windows 'Safe Mode'.\n\n" +"Molimo vas ponovo pokrenite vaÅ¡ raÄunar.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Da li imate problema u pokretanju MTA:SA?\n\n" "Da li želite da se vratite na stariju verziju?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +143,48 @@ msgstr "Izgleda da ima problema u pokretanju MTA:SA.\n" "Resetovanje PodeÅ¡avanja GTA ponekad reÅ¡i ovaj problem.\n\n" "Da li želite da resetujete GTA podeÅ¡avanja sada?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA podeÅ¡avanja su resetovana.\n\n" "Kliknite OK da nastavite." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Fajl nije mogao biti izbrisan: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Da li imate problema sa MTA:SA?\n\n" "Da li želite online pomoć?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Da li imate problem sa pokretanjem MTA:SA?.\n\n" "Da li želite da izmenite sledeće postavke?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Preko celog ekrana:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Prozor bez ivice" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Da li imate problem sa pokretanjem MTA:SA?.\n\n" "PokuÅ¡ajte da onemogućite sledeće produkte za GTA i MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +192,297 @@ msgstr "UPOZORENJE\n\n" "MTA:SA je otkrio neuobiÄajenu aktivnost.\n" "Molimo vas pokrenite skeniranje virusa da se uverite da je vaÅ¡ sistem bezbedan.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Otkrivena datoteka je: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "GTA: San Andreas je vec pokrenut. Morate ga iskljuciti pre nego sto mozete da ukljucite MTA:SA. Da li zelite to odmah da uradite?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Informacije" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Nemoguće iskljuciti GTA: San Andreas. Ako se problem ponovo pojavi, molimo vas restartujte vas kumpjuter." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Imamo teÅ¡koće u restartovanju MTA:SA\n\n" +"Ako se problem nastavi, otvorite Task Manager\n" +"izaustavite 'gta_sa.exe' i 'Multi Theft Auto.exe' procese\n\n\n" +"Da li da pokuÅ¡amo da otvorimo MTA:SA ponovo?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "GreÅ¡ka" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "JoÅ¡ jedan prozor MTA već radi.\n\n" +"Ako se problem nastavi, restartujte vaÅ¡ kompjuter" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "JoÅ¡ jedan prozor MTA već radi.\n\n" +"Da li želite da ga iskljuÄite?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Neki podaci nedostaju. Molimo vas ponovo instalirajte Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Lokacija gde je vas GTA: San Andreas instaliran koristi nepodrzane (unikod) znakove. Molimo vas da pomerite vasu Grand Theft Auto: San Andreas instalaciju na lokaciju sa podrzanim znakovima i ponovo instalirate Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Lokacija vaseg 'MTA:SA' ili 'GTA: San Andreas'\n" -"sadrzi ';' (tacka-zarez),\n\n" -"Ako imate porbleme sa pokretanjem MTA:SA,\n" -"pomerite vasu(e) instalaciju(e) u lokaciju bez tacke-zareza. " - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "Putanja za instalaciju 'MTA:SA' ili 'GTA: San Andreas'\n" +"sadrži ';' (taÄku-zarez).\n\n" +"Ako imate problema sa pokretanjem MTA:SA,\n" +"pomerite vaÅ¡u instalaciju(je) u lokaciju koja ne sadrži taÄku-zarez." + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "Nevažeća putanja za instalaciju pronaÄ‘ena." + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Neuspelo uÄitavanje. Molimo vas uverite se da su najnovije datoteke podataka ispravno instalirane." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Neuspelo uÄitavanje. Molimo vas uverite se da je %s ispravno instaliran." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Neuspelo uÄitavanje. Nismo uspeli da pronaÄ‘emo gta_sa.exe u %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Neuspelo uÄitavanje. %s postoji u GTA direktorijumu. Molimo vas obriÅ¡ite ga pre nego Å¡to nastavite." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Glavna datoteka ima neispravno ime (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Datoteka podataka nije potpisana. Moguća aktivnost virusa.\n\n" -"Potražite pomoć online ukoliko MTA ne bude radio ispravno." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Datoteka podatka %s nedostaje. Moguća aktivnost virusa.\n\n" -"Razmotri reinstaliranje Multi Theft Auto radi vaÅ¡e bezbednosti.\n" -"Potražite pomoć online ukoliko MTA ne bude radio ispravno." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "Datoteka %s nedostaje. Moguća aktivnost virusa." + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Datoteka podatka %s je modifikovana. Moguća aktivnost virusa.\n\n" -"Razmotri reinstaliranje Multi Theft Auto radi vaÅ¡e bezbednosti.\n" -"Potražite pomoć online ukoliko MTA ne bude radio ispravno." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asi datoteke su u 'MTA:SA' ili 'GTA: San Andreas' direktorijumu instalacije\n\n" -"Uklonite .asi datoteke ukoliko budete imali problema sa MTA:SA." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "NeusklaÄ‘ena verzija datoteke. Ponovo instalirajte MTA:SA ukoliko budete imali problem.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "Datoteka %s modifikovana. Moguća aktivnost virusa." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Neke datoteke nedostaju. Ponovo instalirajte MTA:SA ukoliko budete imali problem.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr ".asi datoteke su u instalacionom folderu.\n\n" +"Uklonite ove .asi datoteke ako iskusite probleme." -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA nije kompatibilan sa Windows 'Safe Mode'.\n\n" -"Molimo vas ponovo pokrenite vaÅ¡ raÄunar.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "Nevažeće putanje za igru pronaÄ‘ene." -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Popravi problem sa konfiguracijom" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Popravi greÅ¡ku sa tražnjom poviÅ¡enja" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "GTA: San Andreas se nije ispravno pokrenuo. Da li želite da obustavite?" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Nepoznato" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/Install.cpp:272 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Nije moguće pokrenuti Grand Theft Auto: San Adnreas. Molimo pokuÅ¡ajte ponovno pokretanje ili ako se problem nastavi, kontakirajte MTA na www.multitheftauto.com.\n\n" -"[%s]" +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "Datoteka %s je trenutno zakljuÄana od strane %zu procesa.\n\n" +"Da li želite da obustavite sledeće procese i nastavite ažuriranje?\n\n" +"%s" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas se nije ispravno pokrenuo. Da li želite da obustavite?" +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "VaÅ¡a instalacija je možda neispravna.\n\n" +"%zu od %zu datoteki nije moguće vratiti iz rezervnih kopija.\n\n" +"PokuÅ¡ajte ponovo instalirati Multi Theft Auto sa www.multitheftauto.com\n" +"ili pokuÅ¡ajte pokrenuti ažuriranje sa administrativnim privilegijama." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Instaliranje nadogradnje..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Raspakivanje datoteka..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA nije uspeo da ispuni sledeći zadatak: \n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** IskljuÄivanje se desilo zbog greÅ¡ke u drajveru grafike **\n\n" +"** Molimo vas ažurirajte vaÅ¡ grafiÄki drajver **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "** Nedostatak memorije - Ova greÅ¡ka prouzrokovana je nedostatkom ili fragmentiranom memorijom.**" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Instalirajte ažurirane MTA:SA fajlove" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Nije uspelo ažuriranje zbog konflikta fajlova. Molimo vas iskljuÄite druge aplikacije i pokuÅ¡ajte ponovo" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto nije instaliran pravilno,molimo vas ponovo instalirajte. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "Napraviti GTA:SA raskrsnice" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA ne može da se pokrene zato Å¡to nije uspelo kopiranje datoteke:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA ne može da se pokrene zato Å¡to je netaÄna MTA:SA datoteka ili ona nedostaje:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Kopiraj MTA:SA datoteke" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA ne može da se pokrene žato Å¡to je netaÄna GTA:SA datoteka ili ona nedostaje:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "Zakrpi GTA:SA zavisnost" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA ne može da se pokrene zato Å¡to je GTA:SA izvrÅ¡na aplikacija netaÄna ili nedostaje:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Molimo proverite vaÅ¡ anti-virus za lažno-pozitivne detekcije, pokuÅ¡ajte da dodate izuzetak za GTA:SA izvrÅ¡nu aplikaciju i ponovo pokrenite MTA:SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "GeneriÅ¡i GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA ne može da se pokrene zato Å¡to GTA:SA izvrÅ¡na aplikacija ne može da se uÄita:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Zakrpi GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA ne može da se pokrene zato Å¡to krpljenje GTA:SA nije uspelo:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA ne može da nastavi zato Å¡to drive %s nema dovoljno prostora." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Nedostaje datoteka:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Ukoliko MTA ne uspe da se pokrene, molimo vas ponovo instalirajte GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Ažuriranje podeÅ¡avanja instaliranja" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Ažuriraj opcije kompatibilnosti" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +490,167 @@ msgstr "GTA: San Andreas se nije ispravno pokrenuo. Da li želite da obustavite? #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Da" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Ne" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "ОК" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "IzaÄ‘i" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Pomoć" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Otkaži" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas je naiÅ¡ao na problem" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Informacije o greÅ¡ki" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Å tiklirajte polje da poÅ¡aljete ovu informaciju o greÅ¡ki MTA programerima koristeći 'internet'" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Radeći ovo povećava verovatnoću da će greÅ¡ka biti ispravljena." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Da li želite ponovo pokrenuti MTA: San Andreas ?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Upozorenje" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "VaÅ¡ Grand Theft Auto: San Andreas direktorijum instalacije sadrži ove datoteke:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Ove datoteke nisu neophodne i mogu da naprave smetnju sa grafikom u ovoj verziji MTA:SA.\n\n" "PreporuÄuje se da obriÅ¡ete ili preimenujete ove datoteke." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "Koristi ove datoteke, ali mi takoÄ‘e pokaži ovo upozorenje pri sledećem paljenju" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Nemoj me viÅ¡e podsećati na ove datoteke" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Preimenujte ove datoteke sa *.dll na *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Prikažite mi ove datoteke" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Igraj MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Zbunjujuće postavke" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus otkrivena!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "PokuÅ¡aj svaku opciju i vidi koja radi:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Standard NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Alternate NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Standard Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Alternate Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Ako niÅ¡ta ne uspe, ovo će možda pomoći:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Ako ste već izabrali postavku koja radi, ovo će možda pomoći:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Prisilite režim prozora" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Ne prikazuj ponovo" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Upozorenje: Nismo detektovali anti-virus produkt" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1107 +658,1183 @@ msgstr "MTA nije detektovao anti-virus na vaÅ¡em raÄunaru.\n\n" "Virusi mogu uticati na MTA i pogorÅ¡ati vaÅ¡e iskustvo tokom igranja.\n\n" "Kliknite \"Pomoć\" za viÅ¡e informacija." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Već sam instalirao anti-virus" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Neću instalirati anti-virus.\n" "Želim da usporim svoj raÄunar i budem deo botneta." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "Ovaj pad koji ste iskusili je zbog zloupotrebe memorije od strane servera.\n\n" +"ÄŒak i sa dosta memorije, ovo je x86 igrica sa ograniÄenjima adresa do 3.6GB i neki jako loÅ¡e optimizovani serveri sa dosta modova (ili samo par loÅ¡e pisanih skripta) mogu prouzrokovati ovo, Äak i usporiti vaÅ¡u igru.\n\n" +"Kontaktirajte vlasnika servera ili MTA podrÅ¡ku u zvaniÄnom MTA discord serveru (https://discord.gg/mtasa) za viÅ¡e informacija." + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "MTA: San Andreas - Informacije o nedostatku memorije" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Traženje Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Molimo vas da ukljucite Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Instaliranje nadogradnje..." - -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Raspakivanje datoteka..." - -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Kopiranje fajlova..." - -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopiranje je zavrseno ranije. Sve je OK." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Konekcija nije uspela. PogreÅ¡no korisniÄko ime!" -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "ZavrÅ¡avanje..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Konekcija nije uspela. PogreÅ¡an domaćin!" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Gotovo!" +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Konekcija na %s na portu %u nije uspela!" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 +#. Display the status box +#: Client/core/CConnectManager.cpp:153 #, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA-u treba pristup Administratoru za sledeći zadatak:\n\n" -" '%s'\n\n" -"Molimo vas potvrdite u sledećem prozoru." +msgid "Connecting to %s:%u ..." +msgstr "Konektujem se na %s:%u ..." -#: Client/loader/CInstallManager.cpp:376 +#: Client/core/CConnectManager.cpp:155 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA nije uspeo da ispuni sledeći zadatak: \n\n" -" '%s'\n" +msgid "Reconnecting to %s:%u ..." +msgstr "Ponovno vezivanje na %s:%u ..." -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** IskljuÄivanje se desilo zbog greÅ¡ke u drajveru grafike **\n\n" -"** Molimo vas ažurirajte vaÅ¡ grafiÄki drajver **" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "KONEKTOVANJE" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Instalirajte ažurirane MTA:SA fajlove" +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Vreme za konekciju je isteklo" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Nije uspelo ažuriranje zbog konflikta fajlova. Molimo vas iskljuÄite druge aplikacije i pokuÅ¡ajte ponovo" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Diskonektovan: nepoznata greÅ¡ka u protokolu" -#: Client/loader/CInstallManager.cpp:561 -#, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto nije instaliran pravilno,molimo vas ponovo instalirajte. %s" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Diskonektovan: daljinski diskonektovan" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "Napraviti GTA:SA raskrsnice" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Diskonektovan: daljinski je izgubljena konekcija" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA ne može da se pokrene zato Å¡to nije uspelo kopiranje datoteke:" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Diskonektovan: banovan si sa ovog servera" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA ne može da se pokrene zato Å¡to je netaÄna MTA:SA datoteka ili ona nedostaje:" +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Diskonektovan: diskonektovan sa servera" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Kopiraj MTA:SA datoteke" +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Diskonektovan: veza sa serverom je izgubljena." -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA ne može da se pokrene žato Å¡to je netaÄna GTA:SA datoteka ili ona nedostaje:" +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Diskonektovan: konekcija je odbijena" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Zakrpi GTA:SA zavisnost" +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 +#, c-format +msgid "No such mod installed (%s)" +msgstr "Nije instaliran takav mod (%s)" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA ne može da se pokrene zato Å¡to je GTA:SA izvrÅ¡na aplikacija netaÄna ili nedostaje:" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "PogreÅ¡an odgovor servera (2)" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Molimo proverite vaÅ¡ anti-virus za lažno-pozitivne detekcije, pokuÅ¡ajte da dodate izuzetak za GTA:SA izvrÅ¡nu aplikaciju i ponovo pokrenite MTA:SA." +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "PogreÅ¡an odgovor servera (1)" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "GeneriÅ¡i GTA:SA" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Srpski" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA ne može da se pokrene zato Å¡to GTA:SA izvrÅ¡na aplikacija ne može da se uÄita:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Zauzeto" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Zakrpi GTA:SA" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Ne mogu proveriti da li ima novijih verzija baÅ¡ sada" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA ne može da se pokrene zato Å¡to krpljenje GTA:SA nije uspelo:" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s neophodan" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 +#: Client/core/CVersionUpdater.cpp:1631 #, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA ne može da nastavi zato Å¡to drive %s nema dovoljno prostora." +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Novija verzija MTA:SA %s je neophodna da biste se pridružili odabranom serveru.\n\n" +"Da li želite da skinete i instalirate MTA:SA %s ?" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Nedostaje datoteka:" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Da li želite da pokrenete MTA:SA %s i konektujete se na ovaj server ?" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Ukoliko MTA ne uspe da se pokrene, molimo vas ponovo instalirajte GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Nije moguće konektovati se sada.\n\n" +"Molimo vas da pokuÅ¡ate kasnije." -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Ažuriranje podeÅ¡avanja instaliranja" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Konektovanje" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Ažuriraj opcije kompatibilnosti" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Molimo saÄekajte..." -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Nepoznato" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "PROVERAVANJE" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "Datoteka %s je trenutno zakljuÄana od strane %zu procesa.\n\n" -"Da li želite da obustavite sledeće procese i nastavite ažuriranje?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "PROVERAVANJE ZA NOVIJU VERZIJU" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "VaÅ¡a instalacija je možda neispravna.\n\n" -"%zu od %zu datoteki nije moguće vratiti iz rezervnih kopija.\n\n" -"PokuÅ¡ajte ponovo instalirati Multi Theft Auto sa www.multitheftauto.com\n" -"ili pokuÅ¡ajte pokrenuti ažuriranje sa administrativnim privilegijama." +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Nije neophodno ažuriranje" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "SKIDANJE" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "Äekam..." -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "OBAVEZNO AŽURIRANJE" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Izaberite vaÅ¡ Grand Theft Auto: San Andreas Instalacioni Direktorijum" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Da biste se konektovali na ovaj server, morate ažurirati MTA.\n\n" +"Da li želite da ažurirate sada ?" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "GreÅ¡ka pri uÄitavanju %s modula! (%s)" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "OPCIONALNO AŽURIRANJE" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Nova instalacija od %s je otkrivena.\n\n" -"Da li želite da kopirate vaÅ¡a podeÅ¡avanja iz %s ?" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Server kaže da je ažuriranje preporuÄeno, ali ne neophodno.\n\n" +"Da li želite da ažurirate sada ?" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA je imao problema sa otvaranjem datoteke '%s'" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "Ažuriranje trenutno nije dostupno.\n\n" +"Proverite www.multitheftauto.com" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA nedostaje datoteka '%s'." +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "SAÄŒUVAVANJE GREÅ KE" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA je imao problem sa uÄitavanjem modela." +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Kreiranje fajla nije uspelo." -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Ukoliko ste skorije modifikovali gta3.img, onda pokuÅ¡ajte ponovo instalirati GTA:SA." +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "GREÅ KA U SKIDANJU" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA je imao problem sa dodavanjem nadogradnje na vozilo." +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Skinuti fajl je neispravan." -#: Client/loader/Utils.cpp:1631 -#, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA je pronaÅ¡ao greÅ¡ke u datoteci '%s'" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Iz nekog razloga." -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Da li se vaÅ¡ raÄunar ponovo pokrenuo u toku igranja MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "SKIDANJE ZAVRÅ ENO" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Molimo vas prekinite sledeći program pre nego Å¡to nastavite:" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Nepoznati problem u _DialogUpdateResult" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Website zahtevi" +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "IZMENJENE GTA:SA DATOTEKE" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Server zahteva sledeće sajtove radi njihovog (kasnijeg) pokretanja:" +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ok" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "NIKADA NE UNOSITE OSETLJIVE PODATKE DA BISTE IH ZAÅ TITILI OD KRAÄE" +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "GREÅ KA" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Zapamti odluku" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Neki MTA:SA fajlovi su nestali.\n\n\n" +"Molimo vas ponovo instalirajte MTA:SA" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Dozvoli" +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% zavrÅ¡eno" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Odbij" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"ÄŒekam odgovor - %-3d" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ POMOĆ ZA KOMANDE ]***\n" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Koristite feature-branch osnovu! Ovo je test osnova koja ne može da se koristi za povezivanje na javne servere!" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Vreme je: %d:%02d:%02d" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA neÄe viÅ¡e dobivati updejtove za Windows XP/Vista od Jula 2019.\n\n" -"Nadgradite svoj Windows, da možete igrati na najnovijim serverima." +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "vezivanje: Mreža nije spremna, molimo saÄekajte" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Ovo će vas diskonektovati sa ovog servera.\n\n" -"Da li ste sigurni da želite da se diskonektujete?" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "konekcija: Koristi 'connect [ ]'" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "UPOZORENJE ZA DISKONEKCIJU" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "konekcija: LoÅ¡ port" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "konekcija: Konektovanje na %s:%u..." -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Srpski" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "konekcija: Ne može da se konektuje na %s:%u!" + +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "konekcija: Nije uspelo odbacivanje trenutnog moda" + +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "ponovno vezivanje: Mreža nije spremna, molimo saÄekajte" + +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "ponovno vezivanje: LoÅ¡ broj porta" + +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "ponovno vezivanje: Vezivanje na %s:%u..." + +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "ponovno vezivanje: nemoguće vezivanje na %s:%u!" + +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Suzbiti sve kontrole sa GTA" + +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "SaÄuvaj konfiguraciju" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* VaÅ¡ serial je: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "PODEÅ AVANJA" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Multiplejer" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Video" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "PostFX" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Zvuk" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Bindovi" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Kontrole" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Interfejs" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Web Browser" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Napredno" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "UÄitaj podrazumevano" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Osetljivost miÅ¡a:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Osetljivost vertikalnog niÅ¡anjenja:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Opcije miÅ¡a" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Obrtanje miÅ¡a vertikalno" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Upravljanje miÅ¡em" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Letenje miÅ¡em" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Opcije za džojstik" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standardne kontrole (MiÅ¡ + Tastatura)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "KlasiÄne kontrole (Džojstik)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Mrtva Zona" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Zasićenost" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Koristite 'Binds' ploÄicu za dugmiće na džojstiku." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Levi Å¡tapić" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Desni Å¡tapić" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "OPIS" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "DUGME" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. DUGME" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Nadimak:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "SaÄuvaj passworde servera" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Auto-osveži brauzer servera" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Dozvoli upload ekrana" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Dozvoli spoljne zvukove" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Uvek pokaži prozor preuzimanja" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" -msgstr "" +msgstr "Omogući vezivanje sa Discord Rich Presence" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" -msgstr "" +msgstr "Omogući GTA:SA u igri status na Steamu" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" -msgstr "" +msgstr "SaÄuvaj slike slikane sa kamerom u GTA San Andreas User Files folder" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" -msgstr "" +msgstr "Pitaj pre iskljuÄivanja sa servera kroz glavni meni" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Koristi prilagoÄ‘ene GTA:SA datoteke" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Opcije za renderovanje mape" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Providnost:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" -msgstr "" +msgstr "Rezolucija slike:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" -msgstr "" +msgstr "1024 x 1024 (Podrazumevano)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" -msgstr "" +msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Glavna jaÄina zvuka:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "JaÄina radija:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "JaÄina zvuÄnih efekata:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "JaÄina MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "JaÄina glasa:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Mod igre:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "OpÅ¡te" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Radio opcije" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Ekvilajzer Radija" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Auto-tjun Radija" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Opcije korisniÄkih pesama" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Radio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "NasumiÄno" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "U sekvencama" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Automatski sken medija" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Opcije iskljuÄivanja zvuka" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "IskljuÄi sve zvukove kada se spusti prozor" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "IskljuÄiti zvuk radija kada je prozor spuÅ¡ten" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "IskljuÄi zvuk zvuÄnih efekata kada je prozor spuÅ¡ten" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "IskljuÄi zvuk MTA kada je prozor spuÅ¡ten" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "IskljuÄi zvuk glasa kada je prozor spuÅ¡ten" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Rezolucija:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Vidno polje:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Udaljenost crtanja:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Osvetljenje:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Kvalitet zvuÄnih efekata:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anizotropsko filtriranje:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "UmekÅ¡anje:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Odnos razmere:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Prozor" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI svestan" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Standardno" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Rezolucija bez ivice" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mapiranje Mipa" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "V-Sync" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Nisko" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Srednje" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Visoko" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Vrlo visoko" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "IskljuÄeno" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Automatski" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD poklopiti sa odnosom Å¡irine i visine" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "KoliÄina senki" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Efekat trave" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Izmaglica topline" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Dimljenje guma itd" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "DinamiÄne senke peÅ¡aka" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Pokretno zamućenje" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Corona kiÅ¡ne reflekcije" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Smanjenje celog ekrana" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "UkljuÄi dijalog za odabiranje uredjaja" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Pokaži nepouzdane rezolucije" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Render vozila uvek u visokim detaljima" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Render peÅ¡aka uvek u visokim detaljima" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "Gama:" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "Kontrast:" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "Zasićenost:" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "Primeni promene u režimu prozora" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "Primeni promene u režimu celog ekrana" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Omogućiti udaljene web stranice" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Omogućiti Javascript na udaljenim web stranicama" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" -msgstr "" +msgstr "UkljuÄi render grafiÄkom karticom" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "PrilagoÄ‘ena lista zabrana" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Unesite domen, npr. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Blokiraj" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Domen" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Ukloni domen" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "PrilagoÄ‘ena lista odobrenja" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Dozvoli" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Razno" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Brzo uÄitavanje CJ-eve odeće:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Brzina brauzera:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Jedna konekcija:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Paket tag:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Animacija napredka:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Važnost procesa:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "PodeÅ¡avanja debuga:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Tekuća memorija:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Unapredjivanje tipa gradje:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Instaliraj bitne nadogradnje:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "UkljuÄeno" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Vrlo sporo" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Podrazumevano" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Brzo" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normalan" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Iznad normale" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Minimalno" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Maksimalno" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 kompatibilnost:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-bitna boja" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Popravka miÅ¡a" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Datoteka Klijent resursa:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Prikaži u Exploreru" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" -msgstr "" +msgstr "Podesi CPU 0 prioritet za poboljÅ¡anje performanse igre" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Auto unapredjivanje" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Proveri za najnoviju verziju sada" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Neke opcije biće promenjene prilikom sledećeg pokretanja MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Da li želite da restartujete sada?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "RESTARTOVANJE NEOPHODNO" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Neke opcije biće promenjene kada se iskljuÄite sa trenutnog servera" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Da li želite da restartujete sada?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "NEOPHODNO ISKLJUÄŒENJE" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Džojstik nije detektovan - Proverite konekciju i restartujte igricu" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Bindovanje osa" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Pomerite osu da bindujete, ili escape da oÄistite" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Jezik:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Tema:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "PretpodeÅ¡avanja:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Ćaskanje" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "UÄitaj" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Boje" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Raspored" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Opcije" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Pozadina ćaskanja" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Tekst ćaskanja" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Pozadina unosa" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Tekst ulaza" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Redovi:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Razmera:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Å irina:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "VeliÄina" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "posle" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "za" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "sek." -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Nestajanje" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Postepeno gubljenje starih redova" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Horizontalno:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Vertikalno:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Poravnavanje teksta:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-Odstupanje:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-Odstupanje:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Pozicija" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Levo" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Sredina" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Desno" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Vrh" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Dno" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Font" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Sakrivanje pozadine dok ne kucate" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "ZavrÅ¡i nadimak koristeći \"Tab\" dugme" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Dozvoli serveru da blica taskbar ikonicu" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Dozvoli windows notifikacije" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "crno/beli ocrt za tekst ćaskanja" @@ -1548,89 +1842,95 @@ msgstr "crno/beli ocrt za tekst ćaskanja" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Pritisnite dugme da bindujete, ili escape da oÄistite" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Bindovanje primarnog dugmeta" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Bindovanje sekundarnog dugmeta" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "KONTROLE IGRE GTA" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "KONTROLE MULTIPLAYERA" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "VaÅ¡e korisniÄko ime sadrži nedozvoljene znake!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Glavni meni" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" -msgstr "" +msgstr "U igri" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Crvena:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Zelena:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Plava:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Providnost:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Boja" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Probni prikaz" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Molimo vas iskljuÄite se pre promene jezika" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Molimo vas diskonektujte se pre promene skina" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "VolumetriÄke senke mogu usporiti neke sisteme.\n\n" "Da li ste sigurni da želite da ih ukljuÄite?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "UPOZORENJE O PERFORMANSI" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Upload ekrana je neophodan za neke servere zbog anti-varanja.\n\n" "(Ćaskanje i GUI nisu slikani za upload)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "INFORMACIJE ZA UPLOAD EKRANA" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1638,21 +1938,21 @@ msgstr "Neke skripte mogu puÅ¡tati zvukove, kao na primer radio, sa interneta.\n "IskljuÄivanje ovog podeÅ¡avanja može smanjiti\n" "potroÅ¡nju protoka podataka.\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "SPOLJAÅ NJI ZVUKOVI" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" -msgstr "" +msgstr "SAGLASNOST ZA DOZVOLU DELJENJA PODATAKA" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1662,11 +1962,7 @@ msgstr "Neke datoteke u vaÅ¡em GTA:SA direktorijumu su izmenjene.\n" "MeÄ‘utim, IZMENJENE GTA:SA DATOTEKE SU BLOKIRANE OD STRANE MNOGIH SERVERA\n\n" "Da li ste sigurni da želite da ih koristite?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "IZMENJENE GTA:SA DATOTEKE" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1675,550 +1971,253 @@ msgstr "Omogućavanje DPI svesnosti je eksperimentalna odlika i preporuÄujemo j "Možete iskusiti problema sa grafikom ako omogućite ovu opciju.\n\n" "Da li ste sigurni da želite da omogućite ovu opciju?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "EKSPERIMENTALNA ODLIKA" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" -msgstr "" +msgstr "IskljuÄivanje ove opcije nije preporuÄeno osim ako imate problema sa performansama.\n\n" +"Da li ste sigurni da želite da iskljuÄite?" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Molimo vas unesite korisniÄko ime" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Molimo vas unesite nadimak koji će biti korišćen u igri. \n" "Ovo će biti vaÅ¡e ime kada se konektujete i igrate na serveru" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Vrlo eksperimentalni dodatak." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Zaustavlja stopiranja sa varijacijama CJ-a (Koristi 65MB viÅ¡e RAM-a)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Stariji ruteri možda traže sporiju brzinu skeniranja." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "UkljuÄite da koristite samo jednu konekciju prilikom skidanja." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Tagujte mrežne pakete da pomognete ISP-ovima da identifikuju MTA protok." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Okretajući krug animacija na donjem delu ekrana" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Uvek koristi normalna podeÅ¡avanja. (Ovo podeÅ¡avanje nije saÄuvano)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maksimalno je obiÄno najbolje" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Automatsko ažuriranje:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Izaberite normalno podeÅ¡avanje ako ne volite da ispunjavate izveÅ¡taje o bagovima." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Odaberite podrazumevano da automatski instalirate bitne nadogradnje." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-bitna boja:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Omogući 16-bitni režim boja - Zahteva ponovno pokretanje MTA" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Popravka miÅ¡a:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Popravka pokretanja miÅ¡a - Možda zahteva ponovno pokretanje raÄunara" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" -msgstr "" +msgstr "CPU afinitet:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." -msgstr "" - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Nepoznata komanda ili cvar:" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Zauzeto" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Ne mogu proveriti da li ima novijih verzija baÅ¡ sada" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s neophodan" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Novija verzija MTA:SA %s je neophodna da biste se pridružili odabranom serveru.\n\n" -"Da li želite da skinete i instalirate MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Da li želite da pokrenete MTA:SA %s i konektujete se na ovaj server ?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Nije moguće konektovati se sada.\n\n" -"Molimo vas da pokuÅ¡ate kasnije." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Konektovanje" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Molimo saÄekajte..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "PROVERAVANJE" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "PROVERAVANJE ZA NOVIJU VERZIJU" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Nije neophodno ažuriranje" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "SKIDANJE" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "Äekam..." +msgstr "Menjajte samo ako imate problema sa stabilnošću." -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "OBAVEZNO AŽURIRANJE" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Da biste se konektovali na ovaj server, morate ažurirati MTA.\n\n" -"Da li želite da ažurirate sada ?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "OPCIONALNO AŽURIRANJE" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Server kaže da je ažuriranje preporuÄeno, ali ne neophodno.\n\n" -"Da li želite da ažurirate sada ?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "SAÄŒUVAVANJE GREÅ KE" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Kreiranje fajla nije uspelo." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "GREÅ KA U SKIDANJU" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Skinuti fajl je neispravan." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Iz nekog razloga." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "SKIDANJE ZAVRÅ ENO" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Nepoznati problem u _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ok" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "GREÅ KA" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Neki MTA:SA fajlovi su nestali.\n\n\n" -"Molimo vas ponovo instalirajte MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% zavrÅ¡eno" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"ÄŒekam odgovor - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Konekcija nije uspela. PogreÅ¡no korisniÄko ime!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Konekcija nije uspela. PogreÅ¡an domaćin!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Konekcija na %s na portu %u nije uspela!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Konektujem se na %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "KONEKTOVANJE" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Vreme za konekciju je isteklo" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Diskonektovan: nepoznata greÅ¡ka u protokolu" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Diskonektovan: daljinski diskonektovan" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Diskonektovan: daljinski je izgubljena konekcija" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Diskonektovan: banovan si sa ovog servera" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Diskonektovan: diskonektovan sa servera" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Diskonektovan: veza sa serverom je izgubljena." - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Diskonektovan: konekcija je odbijena" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Nije instaliran takav mod (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "PogreÅ¡an odgovor servera (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "PogreÅ¡an odgovor servera (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "NOVOSTI" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Posetite Älanak najnovijih vesti" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONZOLA" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Fatalna greÅ¡ka" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "DA POPRAVITE, UKLONITE DATOTEKU:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "Modul %s je neispravan!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "GreÅ¡ka pri izvrÅ¡avanju URL-a" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "Ovaj prozor pomoći" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "Izlazi iz programa" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "Pokazuje verziju" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "Pokazuje vreme" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "Pokazuje hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "Pokazuje sve bindovane dugmiće" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "Pokazuje tvoj serialni kod" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "Konektuje se na server (domaćin,port,korisniÄko ime,password)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "Konektuje se na prethodni server" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "Binduje dugme (kontrola dugmića)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "Vraća dugme u svoju prethodnu funkciju (dugme)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "Kopira gta kontrole" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "Å alje sliku ekrana" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "Odmah saÄuvava konfiguraciju" -#: Client/core/CCore.cpp:1391 +#: Client/core/CCore.cpp:1494 msgid "clears the debug view" msgstr "RaÅ¡Äišćava debug" -#: Client/core/CCore.cpp:1392 +#: Client/core/CCore.cpp:1495 msgid "scrolls the chatbox upwards" msgstr "Skroluje chat nagore" -#: Client/core/CCore.cpp:1393 +#: Client/core/CCore.cpp:1496 msgid "scrolls the chatbox downwards" msgstr "Skroluje chat nadole" -#: Client/core/CCore.cpp:1394 +#: Client/core/CCore.cpp:1497 msgid "scrolls the debug view upwards" msgstr "Skroluje debug nagore" -#: Client/core/CCore.cpp:1395 +#: Client/core/CCore.cpp:1498 msgid "scrolls the debug view downwards" msgstr "Skroluje debug nadole" -#: Client/core/CCore.cpp:1398 +#: Client/core/CCore.cpp:1501 msgid "shows the memory statistics" msgstr "Prikazuje statistike memorije" -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "Prikazuje tempiranje frejmova" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "za programere: osveži novosti" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ POMOĆ ZA KOMANDE ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Vreme je: %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "konekcija: Koristi 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "konekcija: LoÅ¡ port" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "konekcija: Konektovanje na %s:%u..." - -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "konekcija: Ne može da se konektuje na %s:%u!" - -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "konekcija: Nije uspelo odbacivanje trenutnog moda" - -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" - -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Suzbiti sve kontrole sa GTA" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "Prikazuje tempiranje frejmova" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "SaÄuvaj konfiguraciju" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "za programere: osveži novosti" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* VaÅ¡ serial je: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Koristite feature-branch osnovu! Ovo je test osnova koja ne može da se koristi za povezivanje na javne servere!" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Osa za ubrzavanje" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA neÄe viÅ¡e dobivati updejtove za Windows XP/Vista od Jula 2019.\n\n" +"Nadgradite svoj Windows, da možete igrati na najnovijim serverima." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Osa za koÄenje" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Ovo će vas diskonektovati sa ovog servera.\n\n" +"Da li ste sigurni da želite da se diskonektujete?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programiranje" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "UPOZORENJE ZA DISKONEKCIJU" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Doprinosioci" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "INFORMACIJE" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Dizajn Igrice / Kodiranje" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "NOVOSTI" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Lokalizacija Jezika" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Posetite Älanak najnovijih vesti" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Doprinosioci Patchovima (Updateovima)" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Slika ekrana ima %d bajta, ali je oÄekivano %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Specijalno hvala" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Slikanje ekrana nije uspelo" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Ovaj softver koristi sledeće biblioteke i softver:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Slika ekrana je slikana: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Da li želite potražiti pomoć online u vezi ovog problema ?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Nepoznata komanda ili cvar:" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2393,25 +2392,56 @@ msgid "Group control backwards" msgstr "Grupna kontrola unazad" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Skin koji ste izabrali nije mogao biti uÄitan, a ni glavni skin nije mogao biti uÄitan i zbog toga vas molimo da reinstalirate MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Slika ekrana ima %d bajta, ali je oÄekivano %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Da li želite potražiti pomoć online u vezi ovog problema ?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Slikanje ekrana nije uspelo" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONZOLA" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Slika ekrana je slikana: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programiranje" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Doprinosioci" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Dizajn Igrice / Kodiranje" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Lokalizacija Jezika" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Doprinosioci Patchovima (Updateovima)" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Specijalno hvala" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Ovaj softver koristi sledeće biblioteke i softver:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Osa za ubrzavanje" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Osa za koÄenje" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2419,6 +2449,63 @@ msgstr "Nije uspelo uÄitavanje Direct3D9.\n\n" "Molimo vas da proverite da li su DirectX Runtime Krajnjeg Korisnika i \n" "poslednji Windows Servisni Paketi dobro instalirani." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Nepokretan" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "igraÄ" +msgstr[1] "igraÄi" +msgstr[2] "igraÄi" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "na" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "server" +msgstr[1] "serveri" +msgstr[2] "servera" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Zatražujem glavnu listu servera (%lu milisekunde su proÅ¡le)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Glavna lista servera nije mogla biti raÅ¡Älanjena." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Glavna lista servera nije mogla biti preuzeta." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Lista rezervnih servera)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "Nije moguće napraviti LAN-emitovanje soket" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Nije uspelo bindovanje utiÄnice za LAN-broadkast" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "PokuÅ¡avam otkriti LAN servere" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2472,7 +2559,7 @@ msgstr "Skrivenost:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Lista igraÄa" @@ -2499,40 +2586,39 @@ msgstr "PrikljuÄi se igri Äim je jedno mesto slobodno." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "MOLIMO VAS UKUCAJTE PASSWORD ZA SERVER" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Isteklo je vreme" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Zatražujem..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "BRAUZER SERVERA" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Lokalno" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Omiljeni" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Nedavno" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2540,300 +2626,367 @@ msgstr "ZA BRZU KONEKCIJU:\n\n" "Ukucajte adresu i port u bar za adresu.\n" "Ili izaberite server iz liste nedavnih i kliknite 'Connect'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "POMOĆ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Osveži" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Dodaj omiljeni" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Konektuj se" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Informacije o serveru" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Traži servere" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Traži igraÄe" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Pokreni pretragu" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "IzbriÅ¡i iz nedavnih" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Traženje igraÄa..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Traženje servera..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Ime" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "IgraÄi" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Ping" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Mod igre" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "UkljuÄi:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Prazno" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Puno" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "ZakljuÄano" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Nije na mreži" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Druge verzije" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Nazad" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "UÄitavanje..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..uÄitavanje.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Nije navedena adresa!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Nepoznat protokol" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Molimo vas koristite mtasa://protokol!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Neispravno korisniÄko ime! Molimo vas da odete u PodeÅ¡avanja i navedete novo!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Morate izabrati server na koji ćete se konektovati." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Nepokretan" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problem sa grafiÄkim drajverom" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "igraÄ" -msgstr[1] "igraÄi" -msgstr[2] "igraÄi" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Ne možemo pronaći validnu rezoluciju ekrana." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "na" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Da li ste sigurni da želite da koristite ovu rezoluciju ekrana?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "server" -msgstr[1] "serveri" -msgstr[2] "servera" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "NeuspeÅ¡na inicijalizacija game_sa" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Zatražujem glavnu listu servera (%lu milisekunde su proÅ¡le)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "NeuspeÅ¡na raspodela memorije" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Glavna lista servera nije mogla biti raÅ¡Älanjena." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Website zahtevi" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Glavna lista servera nije mogla biti preuzeta." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Server zahteva sledeće sajtove radi njihovog (kasnijeg) pokretanja:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Lista rezervnih servera)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "NIKADA NE UNOSITE OSETLJIVE PODATKE DA BISTE IH ZAÅ TITILI OD KRAÄE" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Nije uspelo bindovanje utiÄnice za LAN-broadkast" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Zapamti odluku" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "PokuÅ¡avam otkriti LAN servere" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Odbij" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Ova verzija je stara." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "iskljuÄenje iz igre" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "prikaži nadimke" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "prikaži kutiju ćaskanja" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "prikaži statistike mreže" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "otvori unos ćaskanja" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "prenos glasa drugim igraÄima" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "ulaz u vozilo kao putnik" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "sledeći radio kanal" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "prethodni radio kanal" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" -msgstr "" +msgstr "omogućuje radarski pogled" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" -msgstr "" +msgstr "zumira radarski pogled" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" -msgstr "" +msgstr "udaljava radarski pogled" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" -msgstr "" +msgstr "pomera radar severno" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" -msgstr "" +msgstr "pomera radar južno" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" -msgstr "" +msgstr "pomera radar istoÄno" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" -msgstr "" +msgstr "pomera radar zapadno" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" -msgstr "" +msgstr "vezuje radar za igraÄa" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" -msgstr "" +msgstr "smanjuje prozirnost radara" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" -msgstr "" +msgstr "povećava prozirnost radara" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" -msgstr "" +msgstr "ukljuÄi/iskljuÄi pomoćni tekst za radar" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "slanje poruke odabranom igraÄu" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "promena na sledeće oružje dok ste unutar vozila" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "promena na prethodno oružje dok ste unutar vozila" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "prikaz informacija o trenutnom serveru" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "definiÅ¡e skalu množenja svih tekstualnih prikaza" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Razvojni mod) pokazuje oblik granice sudara objekata" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Razvojni mod) ispisuje ID zvukova iz sveta u debug prozor" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "HOSTUJ IGRU" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Resursi" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Naziv servera:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Lozinka:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Maksimalno igraÄa:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Emitovanje:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Odabrani" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Svi" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Pokreni" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "Promeni mod: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "Zum: %s/%s Pokreti: %s,%s,%s,%s Prozirnost: %s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "UkljuÄi/IskljuÄi radar: %s Pomoćni tekst: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "Prati igraÄa" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "Slobodni pokreti" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Napredak preuzimanja mape:" @@ -2854,174 +3007,174 @@ msgstr "%s od %s" msgid "Disconnect to cancel download" msgstr "IskljuÄite se da zaustavite preuzimanje" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "IskljuÄenje: nevažeći nadimak" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "IskljuÄenje sa servera" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "IskljuÄenje: Serijski je zabranjen.\n" "Razlog: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "IskljuÄenje: Zabranjeno vam je.\n" "Razlog: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "IskljuÄenje: Nalog je zabranjen.\n" "Razlog: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "IskljuÄenje: NeusklaÄ‘ene verzije" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "IskljuÄenje: PreviÅ¡e ljudi se ukljuÄuje. Molimo saÄekajte minut, pa probajte ponovo." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "IskljuÄen: Server je sa druge verzije.\n" "Informacije: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "IskljuÄenje: LoÅ¡a verzija.\n" "Infomacije: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "IskljuÄenje: Server radi na novijoj verziji.\n" "Informacije: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "IskljuÄenje: Server radi na starijoj verziji.\n" "Informacije: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "IskljuÄenje: Nadimak je već u upotrebi" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "IskljuÄenje: Element IgraÄ nije mogla biti stvorena." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "IskljuÄenje: Server je odbio prikljuÄenje: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "IskljuÄenje: Verifikacija serijskog nije uspela" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" -msgstr "" +msgstr "IskljuÄenje: Serijski broj je već u upotrebi" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "IskljuÄenje: Konekcija nije sinhronizovana %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "IskljuÄenje: IzbaÄeni ste od strane %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "IskljuÄenje: Dobili ste zabranu od strane %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "IskljuÄenje: Server se iskljuÄuje ili ponovo pokreće" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "IzbaÄeni ste iz igre" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Ovaj server zahteva gta_sa.exe koji nije modifikovan" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Molimo vas zamenite gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Ovaj server ne dozvoljava izmenjene D3D9.DLLove" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Uklonite D3D9.DLL iz vaÅ¡eg GTA direktorijuma instalacije i ponovo pokrenite MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Ovaj server ne dozvoljava virtuelne maÅ¡ine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Ovaj server zahteva da potpisivanje drajvera bude omogućeno" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Molimo vas ponovo pokrenite vaÅ¡ raÄunar" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Server je otkrio nedostatak anti-cheat komponenti" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "PokuÅ¡ajte ponovo pokrenuti MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Ovaj server zahteva gta3.img i gta_int.img koji nisu modifikovani" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Molimo vas zamenite gta3.img ili gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Ovaj server ne dozvoljava Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Uverite se da nijedan drugi program ne modifikuje MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Preostalo vreme: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" @@ -3029,7 +3182,7 @@ msgstr[0] "%d dan" msgstr[1] "%d dana" msgstr[2] "%d dana" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" @@ -3037,7 +3190,7 @@ msgstr[0] "%d sat" msgstr[1] "%d sati" msgstr[2] "%d sati" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" @@ -3045,7 +3198,7 @@ msgstr[0] "%d minut" msgstr[1] "%d minuta" msgstr[2] "%d minuta" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3054,302 +3207,212 @@ msgstr[1] "%d sekundi" msgstr[2] "%d sekundi" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "IskljuÄenje" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "GreÅ¡ka prilikom preuzimanja: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" -msgstr "" +msgstr "Leti sa NLO" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" -msgstr "" +msgstr "Krstari okolo" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" -msgstr "" +msgstr "Surfuje talasima u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" -msgstr "" +msgstr "Vozi se vozom u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" -msgstr "" +msgstr "Leti okolo" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" -msgstr "" +msgstr "Vozika se okolo" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" -msgstr "" +msgstr "Vozika monster kamion okolo" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" -msgstr "" +msgstr "Vozika kvad okolo" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" -msgstr "" +msgstr "Skakuće okolo" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" -msgstr "" +msgstr "Radi Äudne stvari u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" -msgstr "" +msgstr "Pentra se u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" -msgstr "" +msgstr "Puca iz vozila u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." -msgstr "" +msgstr "Blub blub..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" -msgstr "" +msgstr "UdiÅ¡e vodu" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" -msgstr "" +msgstr "Davi se u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" -msgstr "" +msgstr "ÄŒuÄi sakriven u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" -msgstr "" +msgstr "Bori se u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" -msgstr "" +msgstr "Baca udarce u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" -msgstr "" +msgstr "Puca budale u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" -msgstr "" +msgstr "Upucava" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" -msgstr "" +msgstr "Uleće raketnim rancem" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" -msgstr "" +msgstr "Bukvalno gori u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" -msgstr "" +msgstr "Sagoreva u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" -msgstr "" +msgstr "Pliva u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" -msgstr "" +msgstr "Pluta u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" -msgstr "" +msgstr "Vija ga ajkula" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" -msgstr "" +msgstr "GuÅ¡i se do smrti u" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Ulazak u igru ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Niste povezani; molimo vas koristite Brzo Povezivanje ili 'poveži' komandu da se povežete na server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Lokalni server nije mogao da se pokrene. Pogledajte konzolu za viÅ¡e detalja." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Lokalni Server" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Pokretanje lokalnog servera ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" -msgstr "" +msgstr "Area 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " -msgstr "" +msgstr "Å ećka se okolo " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "IzbaÄeni ste iz igre ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "PrikljuÄivanje na lokalni server..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "GreÅ¡ka prilikom prikljuÄivanja na server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "PrikljuÄivanje na lokalni server nije uspelo. Pogledajte konzolu za viÅ¡e detalja." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Konekcija sa serverom je izgubljena" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "IskljuÄenje: server je trenutno pun" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "IskljuÄenje: uneta nevažeća lozinka" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA Klijent verifikacija nije uspela!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" -msgstr "" +msgstr "U jendeku" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" -msgstr "" +msgstr "Na putu do bolnice" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" -msgstr "" +msgstr "Upoznaje stvaratelja" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" -msgstr "" +msgstr "Kaje se odlukama" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "HOSTUJ IGRU" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Resursi" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Naziv servera:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Lozinka:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Maksimalno igraÄa:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Emitovanje:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Odabrani" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Svi" +msgstr "Mrtav" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Pokreni" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problem sa grafiÄkim drajverom" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Ne možemo pronaći validnu rezoluciju ekrana." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Da li ste sigurni da želite da koristite ovu rezoluciju ekrana?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "GreÅ¡ka prilikom preuzimanja: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 #, c-format msgid "Fatal error (%u). If this problem persists, please check out multitheftauto.com for support." -msgstr "" +msgstr "Fatalna greÅ¡ka (%u). Ukoliko se ovaj problem nastavi, molimo proverite multitheftauto.com za podrÅ¡ku." #. #ifdef MTA_DEBUG #. assert ( 0 ); @@ -3358,17 +3421,17 @@ msgstr "" #: Shared/mods/deathmatch/logic/Utils.cpp:143 #, c-format msgid "Protocol error (%u). If this problem persists, please check out multitheftauto.com for support." -msgstr "" +msgstr "GreÅ¡ka u protokolu (%u). Ukoliko se ovaj problem nastavi, molimo proverite multitheftauto.com za podrÅ¡ku." #: Shared/mods/deathmatch/logic/Utils.cpp:145 msgid "Connection error" msgstr "GreÅ¡ka pri prikljuÄivanju" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto nije pravilno instaliran, molimo vas da ga ponovo instalirate." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "VaÅ¡ pretraživaÄ Ä‡e upravo prikazati stranicu sa informacijama o pomoći.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/sv_SE/client.pot b/Shared/data/MTA San Andreas/MTA/locale/sv_SE/client.pot index f73d16a853b..52952f33d19 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/sv_SE/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/sv_SE/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Swedish\n" "Language: sv_SE\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Ett problem uppstod vid omstart utav MTA:SA\n\n" -"Om problemet kvarstÃ¥r, öppna aktivitetshanteraren och\n" -"stoppa 'gta_sa.exe' och 'Multi Theft Auto.exe' processerna\n\n\n" -"Vill du prova att öppna MTA:SA igen?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Fel" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "En annan instans av MTA körs redan.\n\n" -"Ifall det här problemet kvarstÃ¥r, var god starta om din dator" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "En annan instans av MTA körs redan.\n\n" -"Vill du avsluta den?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Välj din Grand Theft Auto: San Andreas Installations Katalog" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA behöver administrativa rättigheter för följande uppgift:\n\n" +" '%s'\n\n" +"Bekräfta i nästa fönster." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Fel vid laddning av %s modul! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Kopierar filer..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopieringen avslutades tidigt. Allt OK." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Slutför..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Klart!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Ny installation av %s upptäckt.\n\n" +"Vill du kopiera dina inställningar frÃ¥n %s?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA: SA hade problem med att öppna filen '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA: SA hade problem med att öppna filen '%s'" + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA: SA hade problem med att ladda en modell." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Om du nyligen modifierade gta3.img, försök sedan installera om GTA: SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA: SA hade problem med att lägga till en uppgradering till ett fordon." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA: SA hittade fel i filen '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Har datorn startat om du spelade MTA: SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Vänligen avsluta följande program innan du fortsätter:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Felaktigt fel i filversionen. Installera om MTA: SA om du upplever problem.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Vissa filer saknas. Installera om MTA: SA om du upplever problem.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA: SA är inte kompatibel med Windows Säkert läge.\n\n" +"Vänligen starta om datorn.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Har du problem med att köra MTA:SA?.\n\n" "Vill du Ã¥terställa till en tidigare version?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "Det har uppstÃ¥tt ett problem med att öppna MTA:SA\n" "Ã…terställning av inställningarna i GTA kan ibland Ã¥tgärda problemet.\n\n" "Vill du Ã¥terställa inställningarna i GTA nu?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA-inställningarna har Ã¥terställs.\n\n" "Tryck OK för att fortsätta." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Filen kunde inte tas bort: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Har du problem med att köra MTA:SA?.\n\n" "Vill du ha onlinehjälp?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Har du problem med att köra MTA: SA?.\n\n" "Vill du ändra följande inställning?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Fullskärmsläge:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Kantlöst fönster" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Har du problem med att köra MTA: SA?.\n\n" "Försök inaktivera följande produkter för GTA och MTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,128 +189,288 @@ msgstr "VARNING\n\n" "MTA: SA har upptäckt ovanlig aktivitet.\n" "Vänligen kör en virusskanning för att säkerställa att ditt system är säkert.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Den upptäckta filen var: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "En instans av GTA: San Andreas körs redan. Programmet mÃ¥ste avslutas innan MTA:SA kan startas. Vill du göra det nu?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Kunde inte avsluta GTA: San Andreas. Om problemet kvarstÃ¥r, var god starta om datorn." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Ett problem uppstod vid omstart utav MTA:SA\n\n" +"Om problemet kvarstÃ¥r, öppna aktivitetshanteraren och\n" +"stoppa 'gta_sa.exe' och 'Multi Theft Auto.exe' processerna\n\n\n" +"Vill du prova att öppna MTA:SA igen?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Fel" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "En annan instans av MTA körs redan.\n\n" +"Ifall det här problemet kvarstÃ¥r, var god starta om din dator" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "En annan instans av MTA körs redan.\n\n" +"Vill du avsluta den?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Registerposter saknas. Var god installera om Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "Installationssökvägen till GTA: San Andreas innehÃ¥ller otillÃ¥tna (unicode) tecken. Var god flytta din Grand Theft Auto: San Andreas installation till en kompatibel sökväg som endast innehÃ¥ller standard ASCII tecken och installera om Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "Sökvägen till din installation av 'MTA:SA' eller 'GTA: San Andreas'\n" -"innehÃ¥ller ett ';' (semikolon).\n\n" -" Om du fÃ¥r problem när du kör MTA:SA,\n" -" flytta din(a) installation(er) till en sökväg som ej innehÃ¥ller ett semikolon." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Initiering misslyckades. Försäkra dig om att de senaste datafilerna installerats korrekt." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Initiering misslyckades. Försäkra dig om att %s är installerat korrekt." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Initiering misslyckades. gta_sa.exe kunde inte hittas i %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Initiering misslyckades. %s finns i GTA sökvägen. Ta bort innan du fortsätter." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Huvudfilen har ett felaktigt namn (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Huvudfilen är osignerad. Möjlig virusaktivitet.\n\n" -"Se onlinehjälp om MTA inte fungerar korrekt." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 +#, c-format +msgid "Data file %s is modified. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" +msgstr "Lös konfigurationsproblem" + +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/Install.cpp:479 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asi filer finns i katalogen \"MTA: SA\" eller \"GTA: San Andreas\".\n\n" -"Ta bort dessa .asi-filer om du har problem med MTA: SA." +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Installerar uppdatering..." -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Felaktigt fel i filversionen. Installera om MTA: SA om du upplever problem.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Extrahera filer..." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Vissa filer saknas. Installera om MTA: SA om du upplever problem.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA kunde inte slutföra följande uppgift:\n\n" +" '%s'\n" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA: SA är inte kompatibel med Windows Säkert läge.\n\n" -"Vänligen starta om datorn.\n" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Kraschen orsakades utav problem med grafikdrivrutiner **\n\n" +"** Var vänlig uppdatera dina grafikdrivrutiner **" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" -msgstr "Lös konfigurationsproblem" +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Installera uppdaterade MTA:SA-filer" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Kunde inte uppdatera pÃ¥ grund av filkonflikter. Var god stäng av andra applikationer och försök igen" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto har inte installerats korrekt, var god installera om. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Fixa höjning krävs fel" +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Kunde inte starta Grand Theft Auto: San Andreas. Prova att starta om, eller om problemet kvarstÃ¥r, kontakta MTA pÃ¥ www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA kan inte fortsätta eftersom enheten %s inte har tillräckligt med utrymme." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Saknad fil:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Om MTA inte laddas, vänligen installera om GTA:SA" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas har kanske inte startats korrekt. Vill du avsluta det?" +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Uppdatera installationsinställningar" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Uppdatera kompatibilitetsinställningar" #. ///////////////////////////////////////////////////////////////////////// #. @@ -268,166 +478,166 @@ msgstr "GTA: San Andreas har kanske inte startats korrekt. Vill du avsluta det?" #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Ja" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Nej" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Sluta" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Hjälp" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Avbryt" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas har stött pÃ¥ ett problem" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Kraschinformation" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Markera kryssrutan för att skicka denna kraschinformation till MTA devs med hjälp av \"internet\"" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Om du gör det ökar risken för att denna krasch blir fixad." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Vill du starta om MTA: San Andreas?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Varning" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Spela MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Förvirrande alternativ" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus upptäckt!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Prova varje alternativ och se vad som fungerar:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Alternativ NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Om du blir desperat kan det här hjälpa till:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Tvinga windowed-läge" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Varning: Det gick inte att upptäcka antivirusprodukt" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -435,1102 +645,1180 @@ msgstr "MTA kunde inte upptäcka ett antivirusprogram pÃ¥ din dator.\n\n" "Virus stör MTA och försämra din spelupplevelse.\n\n" "Tryck pÃ¥ \"Hjälp\" för mer information." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Jag har redan installerat ett antivirusprogram" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Jag kommer inte installera ett antivirusprogram.\n" "Jag vill att min dator ska lagras och vara en del av en botnet." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Söker efter Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Var god starta Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Installerar uppdatering..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Anslutningen misslyckades. Ogiltigt nick angivet!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Extrahera filer..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Anslutningen misslyckades. Felaktig host angiven!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Kopierar filer..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Anslutningen till %s och port %u misslyckades!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopieringen avslutades tidigt. Allt OK." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Ansluter till %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Slutför..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Klart!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "ANSLUTER" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA behöver administrativa rättigheter för följande uppgift:\n\n" -" '%s'\n\n" -"Bekräfta i nästa fönster." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Anslutningen nÃ¥dde en maxtidsgräns" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA kunde inte slutföra följande uppgift:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "FrÃ¥nkopplad: okänt protokollfel" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Kraschen orsakades utav problem med grafikdrivrutiner **\n\n" -"** Var vänlig uppdatera dina grafikdrivrutiner **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "FrÃ¥nkopplad: frÃ¥nkopplad pÃ¥ distans" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Installera uppdaterade MTA:SA-filer" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "FrÃ¥nkopplad: anslutningen tappad pÃ¥ distans" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Kunde inte uppdatera pÃ¥ grund av filkonflikter. Var god stäng av andra applikationer och försök igen" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "FrÃ¥nkopplad: du är bannlyst frÃ¥n denna server" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "FrÃ¥nkopplad: frÃ¥nkopplad frÃ¥n servern" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "FrÃ¥nkopplad: anslutningen till servern gick förlorad" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "FrÃ¥nkopplad: anslutningen tilläts ej" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto har inte installerats korrekt, var god installera om. %s" +msgid "No such mod installed (%s)" +msgstr "Ingen sÃ¥dan modifikation installerad (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Fel vid serversvar (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Fel vid serversvar (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Svenska" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Upptagen" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Kan inte kolla efter uppdateringar just nu" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "MTA:SA %s krävs" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "En uppdaterad version av MTA:SA %s behövs om du vill gÃ¥ med i vald server.\n\n" +"Vill du ladda ned och installera MTA:SA %s ?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Vill du starta MTA:SA %s och ansluta till denna server ?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Det gÃ¥r inte att ansluta just nu.\n\n" +"Vänligen prova senare." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Ansluter" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Vänta..." -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "KOLLAR" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA kan inte fortsätta eftersom enheten %s inte har tillräckligt med utrymme." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "Uppdateringskoll" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Saknad fil:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Ingen uppdatering krävs" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Om MTA inte laddas, vänligen installera om GTA:SA" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "LADDAR NED" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Uppdatera installationsinställningar" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "väntar..." -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Uppdatera kompatibilitetsinställningar" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "OBLIGATORISK UPPDATERING" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "För att gÃ¥ med i den här servern mÃ¥ste du uppdatera MTA.\n\n" +"Vill du uppdatera nu?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "VALFRI UPPDATERING" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Servern rekommenderar en uppdatering, men är ej nödvändig.\n\n" +" Vill du uppdatera nu ?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "FEL VID SPARNING" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Kunde inte skapa filen." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Välj din Grand Theft Auto: San Andreas Installations Katalog" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "FEL VID HÄMTNING" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Fel vid laddning av %s modul! (%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Den nedladdade filen verkar vara felaktig." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Ny installation av %s upptäckt.\n\n" -"Vill du kopiera dina inställningar frÃ¥n %s?" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Av nÃ¥gon anledning." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA: SA hade problem med att öppna filen '%s'" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "NEDLADDNING KLAR" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA: SA hade problem med att öppna filen '%s'" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Okänt problem i _DialogUpdateResult" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA: SA hade problem med att ladda en modell." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "ANPASSADE GTA:SA-FILER" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Om du nyligen modifierade gta3.img, försök sedan installera om GTA: SA." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA: SA hade problem med att lägga till en uppgradering till ett fordon." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "FEL" -#: Client/loader/Utils.cpp:1631 -#, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA: SA hittade fel i filen '%s'" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Vissa MTA:SA datafiler fattas.\n\n\n" +"Var god ominstallera MTA:SA" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Har datorn startat om du spelade MTA: SA?" +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% klar" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Vänligen avsluta följande program innan du fortsätter:" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Väntar pÃ¥ svar - %-3d" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Webbplatsbegäran" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ KOMMANDOHJÄLP ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Servern gör förfrÃ¥gningar till följande webbplatser för att ladda ner dem senare:" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Aktuell tid är %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "INTE INNEHÃ…LLER KONFIDENTIELLA DATA, FÖR ATT SKYDDA DEM FRÃ…N KRAZH" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Kom ihÃ¥g beslut" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "anslut: Syntax är 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "TillÃ¥ta" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "anslut: Fel portnummer" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Förneka" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "anslut: Ansluter till %s:%u..." -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "anslut: kunde inte ansluta till %s:%u!" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Du använder en funktion-gren byggnad! Detta är en testbyggnad som inte kan användas för att ansluta till offentliga servrar!" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "anslut: Misslyckade att deaktivera aktuellt mod" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA kommer inte att ta emot fler uppdateringar för Windows XP/Vista frÃ¥n och med juli 2019.\n\n" -"Uppgradera Windows för att spela pÃ¥ de senaste servrarna." +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Detta kommer att avbryta anslutningen till nuvarande server.\n\n" -"Vill avbryta anslutningen?" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "FRÃ…NKOPPLINGSVARNING" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" msgstr "" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Svenska" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Bind alla tangenter frÃ¥n GTA" + +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Konfigurationsfilen sparad" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Ditt serienummer är: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "INSTÄLLNINGAR" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Flera spelare" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Grafik" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Ljud" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Bindningar" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Kontroller" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Gränssnitt" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Webbläsare" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Avancerat" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Ladda standardvärden" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Muskänslighet:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Vertikal sikteskänslighet:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Musinställningar" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Invertera mus vertikalt" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Styr med mus" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Flyg med musen" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Handkontrollsinställningar" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standardkontroller (Mus + Tangentbord)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Klassiska kontroller (Handkontroll)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Dödszon" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Mättnad" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Använd 'Bindningar' fliken för handkontrollsknappar." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Vänster Spak" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Höger Spak" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "BESKRIVNING" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "TANGENT" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. TANGENT" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Spara serverlösenord" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Auto-uppdatera serverlista" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "TillÃ¥t skärmuppladning" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Använd anpassade GTA:SA filer" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Kartrenderingsalternativ" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Genomskinlighet:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Mastervolym:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Radio volym:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "SFX volym:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA volym:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Röst volym:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Spelläge:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Allmänt" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Radio alternativ" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Radio Auto-lÃ¥t" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Användarradio inställningar" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Slumpmässigt" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Sekventiell" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Automatisk Media Skanning" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Stänga alternativ" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Stäng ljudeffekter i minimerat läge" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Stäng radioljud i minimerat läge" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Stäng ljudeffekter i minimerat läge" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Stäng MTA ljud i minimerat läge" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Stäng röstljud i minimerat läge" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Upplösning:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Ljusstyrka:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX Kvalitet:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anisotropisk filtrering:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Kantutjämning:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "BildförhÃ¥llande:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Fönster" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Kantlöst behÃ¥ll res" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "LÃ¥g" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Hög" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Väldigt hög" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Av" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Automatisk" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD MatchbildsförhÃ¥llande" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Volymetriska skuggor" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Gräseffekt" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Soldis" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Däck rök etc" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Fullskärmsläge Minimerat" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Aktivera enhetsväljardialogen" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Visa osäkra upplösningar" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Rendera fordon alltid i stor detalj" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Aktivera fjärrwebbplatser" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Aktivera Javascript pÃ¥ externa webbplatser" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Anpassad svartlista" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Ange en domän, t.ex. google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Blockera" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Domän" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Ta bort domänen" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Anpassad vitlista" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "TillÃ¥ta" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Blandat" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Snabb laddning av CJ kläder:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Serverlista uppdateringshastighet:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Singel anslutning:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Paketetikett:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Processprioritet:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Felsökningsinställning:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Streaming minne:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Uppdatera byggtyp:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Installera viktiga uppdateringar:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "PÃ¥" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Väldigt lÃ¥ngsam" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Standard" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Snabb" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Vanligt" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Above vanlight" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8-kompatibilitet:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-bitars färg" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Mus fixa" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "Klientresursfiler:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Visa i Explorer" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Auto uppdaterare" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Kolla efter uppdatering nu" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Vissa inställningar ändras när du börjar MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Vill du starta om nu?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "OMSTART KRÄVS" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Vissa inställningar ändras när du kopplar bort den aktuella servern" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Vill du starta om nu?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Handkontroll ej detekterad - Kontrollera anslutningar och starta om spelet" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Binder axel" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Rör en axel för att binda, eller tryck pÃ¥ escape för att nollställa" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "SprÃ¥k:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Skal:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Förinställningar:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Chatt" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Ladda" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Calar" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "alternativ" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Chatt bakgrund" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Chattext" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Inmatningsbakgrund" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Skriv in Text" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Rader:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Skala:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Bredd:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Storlek" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "efter" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "för" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "sek" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Fadinge" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Tona ut gamla linjer" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Verticale:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Texte-Aligne:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Placera" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Vänster" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Centrum" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Höger" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Topp" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Botten" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Typsnitt:" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Göm bakgrund när man inte skriver" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Avsluta smeknamnet med knappen \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "TillÃ¥t servern att blinka i fönstret" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "TillÃ¥t meddelanden om brickballong" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Chat text svart / vit skiss" @@ -1538,109 +1826,115 @@ msgstr "Chat text svart / vit skiss" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Tryck Tangent för bind, eller escape för nolställa" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Binder primär tangent" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Binder sekundär tangent" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA SPEL KONTROLLER" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "MULTIPLAYER KONTROLLER" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Användarnamnet innehÃ¥ller ogiltiga tecken!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Röd:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Grön:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "BlÃ¥:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Genomskinlighet:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Färg" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Förhandsvisning" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Koppla av innan du byter sprÃ¥k" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Avbryt anslutningen innan du ändrar skin" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Volumetriska skuggor kan göra att vissa system gÃ¥r segt.\n\n" "Är du säker pÃ¥ att du vill aktivera dem?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "PRESTANDA VARNING" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Bilduppladdning krävs av en del servrar för anti-fusk ändamÃ¥l.\n\n" "(Chattruta och GUI kommer inte att laddas upp)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "BILDUPPLADDNING INFORMATION" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1650,561 +1944,259 @@ msgstr "Vissa filer i din GTA:SA datakatalog är anpassade.\n" "Emellertid, ANPASSADE GTA:SA FILER ÄR BLOCKERADE AV MÃ…NGA SERVRAR\n\n" "Är du säker pÃ¥ att du vill använda dem?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "ANPASSADE GTA:SA-FILER" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" "Are you sure you want to enable this option?" msgstr "" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Ange ett användarnamn" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Ange ett användarnamn som ska användas i spelet. \n" "Det kommer att vara ditt namn när du ansluter till och spelar pÃ¥ en server." -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Väldig experimentiell funktion." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Motverkar fördröjningar med CJ-variationer (Använder 65MB mer RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Äldre routrar kan behöva en lägre skanningshastighet." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Aktivera för att bara använda en anslutning för nedladdningar." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Tag nätverkspaket för att hjälpa Internetleverantörer att identifiera MTA-trafik." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Spinning cirkel animering längst ner pÃ¥ skärmen" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Välj alltid standard. (Den här inställningen sparas inte)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maximum är vanligtvis bäst" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Autouppdaterare:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Välj standard sÃ¥vida du inte gillar att fylla i buggrapporter." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Välj standard för att automatiskt installera viktiga uppdateringar." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-bitars färg:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Aktivera 16-bitars färglägen - Kräver MTA-omstart" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Musfix:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Mus rörelse fix - kan behöva starta om datorn" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Okänt kommando eller cvar" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Upptagen" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Kan inte kolla efter uppdateringar just nu" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s krävs" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "En uppdaterad version av MTA:SA %s behövs om du vill gÃ¥ med i vald server.\n\n" -"Vill du ladda ned och installera MTA:SA %s ?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Vill du starta MTA:SA %s och ansluta till denna server ?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Det gÃ¥r inte att ansluta just nu.\n\n" -"Vänligen prova senare." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Ansluter" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Vänta..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "KOLLAR" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "Uppdateringskoll" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Ingen uppdatering krävs" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "LADDAR NED" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "väntar..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "OBLIGATORISK UPPDATERING" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "För att gÃ¥ med i den här servern mÃ¥ste du uppdatera MTA.\n\n" -"Vill du uppdatera nu?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "VALFRI UPPDATERING" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Servern rekommenderar en uppdatering, men är ej nödvändig.\n\n" -" Vill du uppdatera nu ?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "FEL VID SPARNING" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Kunde inte skapa filen." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "FEL VID HÄMTNING" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Den nedladdade filen verkar vara felaktig." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Av nÃ¥gon anledning." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "NEDLADDNING KLAR" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Okänt problem i _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "FEL" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Vissa MTA:SA datafiler fattas.\n\n\n" -"Var god ominstallera MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% klar" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Väntar pÃ¥ svar - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Anslutningen misslyckades. Ogiltigt nick angivet!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Anslutningen misslyckades. Felaktig host angiven!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Anslutningen till %s och port %u misslyckades!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Ansluter till %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "ANSLUTER" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Anslutningen nÃ¥dde en maxtidsgräns" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "FrÃ¥nkopplad: okänt protokollfel" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "FrÃ¥nkopplad: frÃ¥nkopplad pÃ¥ distans" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "FrÃ¥nkopplad: anslutningen tappad pÃ¥ distans" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "FrÃ¥nkopplad: du är bannlyst frÃ¥n denna server" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "FrÃ¥nkopplad: frÃ¥nkopplad frÃ¥n servern" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "FrÃ¥nkopplad: anslutningen till servern gick förlorad" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "FrÃ¥nkopplad: anslutningen tilläts ej" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Ingen sÃ¥dan modifikation installerad (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Fel vid serversvar (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Fel vid serversvar (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONSOL" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Allvarligt fel" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "ATT FIX, FÖLJ DENNA FIL:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s modul är inkorrekt!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Fel vid körning av URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "denna hjälpsida" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "avslutar applikationen" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "visar versionen" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "visar tiden" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "visar hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "visar alla bindningar" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "visar ditt serienummer" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "ansluter till en server (host port nick lösen)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "ansluter till en föregÃ¥ende server" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "binder en tangent (tangent kontroll)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "friar en tangent (tangent)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "kopierar standard gta kontrollerna" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "skapar en skärmdump" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "sparar konfigurationen direkt" -#: Client/core/CCore.cpp:1391 +#: Client/core/CCore.cpp:1494 msgid "clears the debug view" msgstr "rensar felsökningsvyn" -#: Client/core/CCore.cpp:1392 +#: Client/core/CCore.cpp:1495 msgid "scrolls the chatbox upwards" msgstr "skrollar chattrutan uppÃ¥t" -#: Client/core/CCore.cpp:1393 +#: Client/core/CCore.cpp:1496 msgid "scrolls the chatbox downwards" msgstr "skrollar chattrutan nedÃ¥t" -#: Client/core/CCore.cpp:1394 +#: Client/core/CCore.cpp:1497 msgid "scrolls the debug view upwards" msgstr "skrollar felsökningsvyn uppÃ¥t" -#: Client/core/CCore.cpp:1395 +#: Client/core/CCore.cpp:1498 msgid "scrolls the debug view downwards" msgstr "skrollar felsökningsvyn nedÃ¥t" -#: Client/core/CCore.cpp:1398 +#: Client/core/CCore.cpp:1501 msgid "shows the memory statistics" msgstr "visar minnesstatistik" -#: Client/core/CCore.cpp:1399 +#: Client/core/CCore.cpp:1502 msgid "shows the frame timing graph" msgstr "visar frame timing statistik" -#: Client/core/CCore.cpp:1403 +#: Client/core/CCore.cpp:1506 msgid "for developers: reload news" msgstr "" -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ KOMMANDOHJÄLP ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Aktuell tid är %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "anslut: Syntax är 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "anslut: Fel portnummer" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Du använder en funktion-gren byggnad! Detta är en testbyggnad som inte kan användas för att ansluta till offentliga servrar!" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "anslut: Ansluter till %s:%u..." +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA kommer inte att ta emot fler uppdateringar för Windows XP/Vista frÃ¥n och med juli 2019.\n\n" +"Uppgradera Windows för att spela pÃ¥ de senaste servrarna." -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "anslut: kunde inte ansluta till %s:%u!" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Detta kommer att avbryta anslutningen till nuvarande server.\n\n" +"Vill avbryta anslutningen?" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "anslut: Misslyckade att deaktivera aktuellt mod" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "FRÃ…NKOPPLINGSVARNING" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" msgstr "" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" msgstr "" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" msgstr "" -#: Client/core/CCommandFuncs.cpp:325 +#: Client/core/CScreenShot.cpp:200 #, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Bind alla tangenter frÃ¥n GTA" +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Skärmdump fick %d bytes, men väntade %d" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Konfigurationsfilen sparad" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Skärmdump misslyckades" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 +#: Client/core/CScreenShot.cpp:256 #, c-format -msgid "* Your serial is: %s" -msgstr "* Ditt serienummer är: %s" - -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Accelerations Axel" - -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Broms Axel" - -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programmering" - -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Medverkande" - -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Speldesign / Skriptning" - -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "SprÃ¥klokalisering" - -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Programfixbidragare" - -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Stort tack till" - -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "" +msgid "Screenshot taken: '%s'" +msgstr "Skärmdump tagen: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Vill du se onlinehjälp kring det här problemet ?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Okänt kommando eller cvar" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2379,25 +2371,56 @@ msgid "Group control backwards" msgstr "Grupp kontroll bakÃ¥t" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Spelarmodellen du valde kunde inte laddas, och standardmodellen kunde inte heller laddas, var god installera om MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Skärmdump fick %d bytes, men väntade %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Vill du se onlinehjälp kring det här problemet ?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Skärmdump misslyckades" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONSOL" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Skärmdump tagen: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programmering" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Medverkande" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Speldesign / Skriptning" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "SprÃ¥klokalisering" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Programfixbidragare" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Stort tack till" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Accelerations Axel" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Broms Axel" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2405,6 +2428,61 @@ msgstr "Kunde inte initiera Direct3D9.\n\n" "Vänligen se till att DirectX End-User Runtime och\n" "senaste Windows Service Packs är korrekt installerade." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Inaktiv" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "spelare" +msgstr[1] "spelare" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "pÃ¥" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "" +msgstr[1] "servrar" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Begär huvudserverlista (%lu ms förflutet)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Huvudserverlistan kunde ej tolkas." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Huvudserverlistan kunde ej hämtas." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Backupserverlista)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Kan ej binda LAN-sändnings socket" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Försöker hitta LAN servrar" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2458,7 +2536,7 @@ msgstr "Latenstid:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Spelarlista" @@ -2485,40 +2563,39 @@ msgstr "Anslut till servern sÃ¥ fort det finns en ledig spelarplats." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "VÄNLIGEN SKRIV SERVERLÖSENORDET" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Tidsgräns överskriden" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "FrÃ¥gar..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "SERVERLISTA" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Lokal" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Favoriter" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Senaste" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2526,298 +2603,367 @@ msgstr "FÖR SNABB ANSLUT:\n\n" "Skriv adressen och porten i adressfältet.\n" "Eller välj en server frÃ¥n historiken ock klicka pÃ¥ 'Anslut'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "HJÄLP" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Uppdatera" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Lägg till favorit" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Anslut" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Sök server" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Sök spelare" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Starta sökning" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Sök spelare..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Sök server..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Namn" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Spelare" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Latens" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Spelläge" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Inkludera:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Tom" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "LÃ¥st" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Andra Versioner" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Tillbaka" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Laddar..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..laddar.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Ingen adress angiven!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Okänt protokoll" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Vänligen använd mtasa:// protokollet!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Ogiltigt nick! Vänligen gÃ¥ till inställningar och välj ett nytt!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Du mÃ¥ste välja en server att ansluta till." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Inaktiv" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Problem med grafikdrivrutinen" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "spelare" -msgstr[1] "spelare" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Det gÃ¥r inte att hitta en giltig skärmupplösning." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "pÃ¥" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Är du säker pÃ¥ att du vill använda den här skärmupplösningen?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "" -msgstr[1] "servrar" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Begär huvudserverlista (%lu ms förflutet)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Huvudserverlistan kunde ej tolkas." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Webbplatsbegäran" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Huvudserverlistan kunde ej hämtas." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Servern gör förfrÃ¥gningar till följande webbplatser för att ladda ner dem senare:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Backupserverlista)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "INTE INNEHÃ…LLER KONFIDENTIELLA DATA, FÖR ATT SKYDDA DEM FRÃ…N KRAZH" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Kan ej binda LAN-sändnings socket" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Kom ihÃ¥g beslut" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Försöker hitta LAN servrar" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Förneka" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Versionen har gÃ¥tt ut." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "avbryt anslutningen frÃ¥n spelet" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "visar namnskyltarna" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "visar chattrutan" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "visar nätverksstatistik" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "öppna chattinmatningen" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "för över röst till andra spelare" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "gÃ¥r in i en bil som passagerare" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "radio nästa kanal" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "FöregÃ¥ende radio kanal" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "skickar ett meddelande till den angivna spelaren" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "ändrar till nästa vapen när du är i ett fordon" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "ändrar till det föregÃ¥ende vapnet inifrÃ¥n fordonet" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "Utmatar information om den aktuella servern" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "definierar skalningsmultiplikatorn av all text" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Utvecklingsläge) visar colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Utvecklingsläge) skriver ut världs ljud ids till felsökningsvyn" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "SKAPA SPEL" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Resurser" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Server namn:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Lösenord:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Max spelare:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Utsändning:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Vald" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Alla" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Starta" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Kart nedladdningsförlopp:" @@ -2838,195 +2984,195 @@ msgstr "%s av %s" msgid "Disconnect to cancel download" msgstr "Avbryt anslutning för att avbryta nedladdning" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "IfrÃ¥nkopplad: Ogiltigt användarnamn" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Avbryt anslutningen frÃ¥n servern" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "FrÃ¥nkopplad: Serienumret är avstängt.\n" "Orsak: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "FrÃ¥nkopplad: Du är avstängd.\n" "Orsak: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "FrÃ¥nkopplad: Konto är avstängt.\n" "Orsak: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "FrÃ¥nkopplad: Version matchar ej" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "FrÃ¥nkopplad: Anslutningsflod. Vänta en minut och anslut igen." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "FrÃ¥nkopplad: Server frÃ¥n annan gren. \n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "FrÃ¥nkopplad: Ogiltig version.\n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "FrÃ¥nkopplad: Servern kör en nyare build.\n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "FrÃ¥nkopplad: Servern kör en äldre build. \n" "Information: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "FrÃ¥nkopplad: Nick redan i bruk" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "FrÃ¥nkopplad: Servern vägrade anslutningen: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "FrÃ¥nkopplad: Serienummerverifikation misslyckades" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "FrÃ¥nkopplad: Anslutning desynkroniserad %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "FrÃ¥nkopplad: Du blev utsparkad av %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "FrÃ¥nkopplad: Du blev avstängd av %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Avkopplad: Serveravstängning eller omstart" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Du blev utsparkad frÃ¥n spelet" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Tid Kvar: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d dag" msgstr[1] "%d dagar" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d timme" msgstr[1] "%d timmar" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d minut" msgstr[1] "%d minuter" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3034,296 +3180,206 @@ msgstr[0] "%d sekund" msgstr[1] "%d sekunder" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Nedkopplad" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Nedladdningsfel %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "GÃ¥r med i spelet..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Inte ansluten; var vänlig använd Snabb Anslutning eller 'connect' kommandot för att ansluta till en server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Kunde inte starta lokal server. Se konsol för detaljer." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Lokal Server" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Startar lokal server ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Du blev utsparkad frÃ¥n spelet ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Ansluter till lokal server..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Fel vid anslutning till servern." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Anslutning till lokal server avbröts. Kolla konsolen för mer detaljer." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Anslutningen till servern gick förlorad" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "FrÃ¥nkopplad: servern är för närvarande full" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "FrÃ¥nkopplad: ogiltigt lösenord angivet" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA Klientverifikation misslyckades!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "SKAPA SPEL" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Resurser" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Server namn:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Lösenord:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Max spelare:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Utsändning:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Vald" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Alla" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Starta" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Problem med grafikdrivrutinen" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Det gÃ¥r inte att hitta en giltig skärmupplösning." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Är du säker pÃ¥ att du vill använda den här skärmupplösningen?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Nedladdningsfel %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3344,11 +3400,11 @@ msgstr "" msgid "Connection error" msgstr "Anslutnings fel" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto har inte installerats korrekt, var god installera om." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Din webbläsare kommer nu att visa en webbsida med hjälpinformation.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/tr_TR/client.pot b/Shared/data/MTA San Andreas/MTA/locale/tr_TR/client.pot index 87718661fed..c13c1f8628d 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/tr_TR/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/tr_TR/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Turkish\n" "Language: tr_TR\n" @@ -17,72 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "MTA:SA yeniden baÅŸlatılırken hata oluÅŸtu\n\n" -"Bu problem tekrar ederse, Görev Yöneticisini açın ve\n" -"'gta_sa.exe' ve 'Multi Theft Auto.exe' iÅŸlemlerini durdurun.\n\n\n" -"MTA:SA'yı tekrar baÅŸlatmak istiyor musunuz?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Grand Theft Auto: San Andreas’ı baÅŸlatın.\n" +"Oyunun 'Program Files (x86)' klasöründe bulunduÄŸundan emin olun." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Hata" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "GTA: San Andreas aranıyor" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "BaÅŸka bir MTA iÅŸlemi zaten çalışıyor.\n\n" -"Bu problem devam ederse, lütfen bilgisayarınızı yeniden baÅŸlatın" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Üzgünüz, oyun bulunamadı.\n" +"Grand Theft Auto: San Andreas’ı baÅŸlatın ve yeniden denemek için tıklayın.\n" +"Oyunun 'Program Files (x86)' klasöründe bulunduÄŸundan emin olun." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "BaÅŸka bir MTA zaten çalışıyor.\n\n" -"Durdurmak ister misiniz?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Grand Theft Auto: San Andreas'ın yüklü olduÄŸu klasörü seçiniz" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA ÅŸu görevi yürütebilmek için Yönetici izni istiyor:\n\n" +"'%s'\n\n" +"Lütfen bir sonraki pencereden onay verin. " + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "%s modülünü yüklemede hata! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Dosyalar kopyalanıyor..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Kopyalama iÅŸlemi erken bitti. Her ÅŸey yolunda." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Tamamlanıyor..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Bitti!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Yeni %s kurulumu algılandı.\n\n" +"%s ayarlarınızı kopyalamak ister misiniz?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA '%s' dosyasını açmakta sorun yaÅŸadı" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA '%s' dosyası kayıp." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA bir modeli yüklerken sorunla karşılaÅŸtı." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "EÄŸer yakın zamanda gta3.img dosyasını deÄŸiÅŸtirdiyseniz, GTA:SA'yı tekrar yüklemeyi deneyin." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA arabaya modifiye eklerken sorunla karşılaÅŸtı." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA '%s' dosyasında hatalar buldu" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "MTA:SA oynarken bilgisayarın yeniden mi baÅŸlatıldı?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Lütfen devam etmeden önce ÅŸu programları sonlandırınız:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "Geçersiz modül yolu algılandı.\n" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Dosya sürümü uyumsuzluk hatası. Bir problemle karşılaşırsanız MTA:SA'yı tekrar kurun.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Bazı dosyalar eksik. Bir problemle karşılaşırsanız MTA:SA'yı tekrar kurun.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA, Windows 'Güvenli Mod' ile uyumlu deÄŸildir.\n\n" +"Lütfen bilgisayarınızı yeniden baÅŸlatın.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "MTA:SA'yı baÅŸlatmakta sorun mu yaşıyorsunuz?.\n\n" "Bir önceki sürüme dönmek ister misiniz?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +143,48 @@ msgstr "MTA:SA'nın baÅŸlatmasında bir problem olduÄŸu görülüyor.\n" "GTA ayarlarını sıfırlamak bazen bu hatayı düzeltebilir.\n\n" "GTA ayarlarını ÅŸimdi sıfırlamak ister misiniz?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA ayarları sıfırlandı.\n\n" "Devam etmek için Tamam'a basın." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Dosya silinemedi: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "MTA:SA'yı çalıştırmakta sorun mu yaşıyorsunuz?\n\n" "Çevrimiçi yardım almak ister misiniz?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "MTA:SA'yı çalıştırırken sorun mu yaşıyorsunuz?.\n\n" "Åžu ayarı deÄŸiÅŸtirmek ister misiniz?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Ekran modu:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Çerçevesiz pencere" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "MTA:SA'yı çalıştırırken sorun mu yaşıyorsunuz?.\n\n" "Åžu programları GTA ve MTA için devre dışı bırakmayı deneyin:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +192,296 @@ msgstr "UYARI\n\n" "MTA:SA alışılmadık bir olay algıladı.\n" "Lütfen bilgisayarınızın güvenli olduÄŸundan emin olmak için virüs taraması yapın.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Algılanan dosya: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "BaÅŸka bir GTA:San Andreas iÅŸlemi zaten çalışıyor. MTA:SA'nın baÅŸlatılması için bu iÅŸlemin sonlandırılması gerekiyor. Åžu an yapmak ister misiniz?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Bilgiler" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "GTA: San Andreas sonlandırması baÅŸarısız oldu. EÄŸer sorun devam ederse, lütfen bilgisayarınızı yeniden baÅŸlatın." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "MTA:SA yeniden baÅŸlatılırken hata oluÅŸtu\n\n" +"Bu problem tekrar ederse, Görev Yöneticisini açın ve\n" +"'gta_sa.exe' ve 'Multi Theft Auto.exe' iÅŸlemlerini durdurun.\n\n\n" +"MTA:SA'yı tekrar baÅŸlatmak istiyor musunuz?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Hata" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "BaÅŸka bir MTA iÅŸlemi zaten çalışıyor.\n\n" +"Bu problem devam ederse, lütfen bilgisayarınızı yeniden baÅŸlatın" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "BaÅŸka bir MTA zaten çalışıyor.\n\n" +"Durdurmak ister misiniz?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Kayıt defteri girdileri eksik. Lütfen Multi Theft Auto: San Andreas'ı denetim masasından silip tekrar yükleyiniz." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "GTA: San Andreas yüklemenizin klasör yolu desteklenmeyen (unicode) harfler içeriyor. Lütfen Grand Theft Auto: San Andreas yüklemenizi sadece uyumlu bir yola, yani sadece standart ASCII karakterleri içeren bir yere taşıyın ve Multi Theft Auto: San Andreas'ı tekrar yükleyin." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "'MTA:SA' veya 'GTA San Andreas' yüklemenizin yolu\n" -"bir ';' (noktalı virgül) içeriyor.\n\n" +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "'MTA:SA' veya 'GTA: San Andreas' kurulumunuzun yolu\n" +"'; ' (noktalı virgül) içeriyor.\n\n" "MTA:SA'yı çalıştırırken sorun yaşıyorsanız,\n" -"yükleme(leri)nizi noktalı virgül içermeyen bir yola taşıyın. " +"kurulumlarınızı noktalı virgül içermeyen bir yola taşıyın." + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:810 +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Yükleme baÅŸarısız. Lütfen en yeni veri dosyalarının doÄŸru yüklendiÄŸinden emin olunuz." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Yükleme baÅŸarısız. Lütfen %s doÄŸru yüklendiÄŸinden emin olun." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Yükleme baÅŸarısız. gta_sa.exe %s konumunda bulunamadı" -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Yükleme baÅŸarısız. GTA klasöründe %s bulunmaktadır. Lütfen devam etmeden önce bunu siliniz." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "Ana dosya hatalı isme sahip (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "Ana dosya imzalanmamış. Buna bilgisayarınızdaki bir virüs sebep olmuÅŸ olabilir.\n\n" -"EÄŸer MTA doÄŸru bir biçimde çalışmazsa çevrimiçi yardıma bakın." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Veri dosyası %s eksik. Olası virüs aktivitesi.\n\n" -"GüvenliÄŸiniz için Multi Theft Auto'yu yeniden yüklemeyi düşünün.\n" -"MTA düzgün çalışmazsa çevrimiçi yardıma bakın." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Veri dosyası %s deÄŸiÅŸtirilmiÅŸ. Olası virüs etkinliÄŸi.\n\n" -"GüvenliÄŸiniz için Multi Theft Auto'yu yeniden yüklemeyi düşünün.\n" -"MTA düzgün çalışmazsa çevrimiçi yardıma bakın." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "'MTA:SA' veya 'GTA: San Andreas' klasörlerinde .asi uzantılı dosyalar var.\n\n" -"EÄŸer MTA:SA ile alakalı bir problemle karşılaşırsanız bu klasörlerden .asi uzantılı dosyalarını silin." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Dosya sürümü uyumsuzluk hatası. Bir problemle karşılaşırsanız MTA:SA'yı tekrar kurun.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Bazı dosyalar eksik. Bir problemle karşılaşırsanız MTA:SA'yı tekrar kurun.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA, Windows 'Güvenli Mod' ile uyumlu deÄŸildir.\n\n" -"Lütfen bilgisayarınızı yeniden baÅŸlatın.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Kurulum hatasını düzelt" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Yükseltme gerektiren hatayı düzelt" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Bilinmeyen" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "'%s' dosyası ÅŸu anda %zu iÅŸlemleri tarafından kilitlendi.\n\n" +"AÅŸağıdaki süreçleri sonlandırmak ve güncellemeye devam etmek istiyor musunuz?\n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "Kurulumunuz bozulmuÅŸ olabilir.\n\n" +"%zu dosyalarından %zu yedekten geri yüklenemedi.\n\n" +"Multi Theft Auto'yu www.multitheftauto.com adresinden yeniden yüklemeyi\n" +"veya güncellemeyi yönetici olarak çalıştırmayı deneyebilirsiniz." + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Güncelleme kuruluyor..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Dosyalar çıkarılıyor..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA bu görevi tamamlayamadı:\n\n" +"'%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Hata, ekran kartı sürücüsü nedeniyle oluÅŸtu **\n\n" +"** Lütfen ekran kartı sürücülerinizi güncelleyin**" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "** Bellek yetersizliÄŸi — Bu çökme, yeterli boÅŸ veya parçalanmış belleÄŸin olmamasından kaynaklanmıştır. **" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "GüncellenmiÅŸ MTA:SA dosyalarını yükle" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Dosya çakışmaları nedeniyle güncellenemedi. Lütfen diÄŸer uygulamaları kapatın ve tekrar deneyin" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto düzgün ÅŸekilde yüklenmemiÅŸ, lütfen tekrar yükleyin. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "GTA:SA baÄŸlantı noktalarını oluÅŸtur" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA baÅŸlatılamadı çünkü dosya kopyalama baÅŸarısız oldu:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA baÅŸlatılamadı çünkü bir MTA:SA dosyası hatalı veya eksik:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "MTA:SA dosyalarını kopyala" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA baÅŸlatılamadı çünkü bir GTA:SA dosyası hatalı veya eksik:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "GTA'SA'nın baÄŸlılığını yamala" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA baÅŸlatılamadı çünkü GTA:SA baÅŸlatma dosyası hatalı veya eksik:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Lütfen antivirüs programınızı yanlış pozitif bir algılama için kontrol edin, GTA: SA klasörü için bir istisna eklemeye çalışın ve MTA:SA'yı yeniden baÅŸlatın." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "GTA:SA OluÅŸtur" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA baÅŸlatılamadı çünkü GTA:SA baÅŸlatma dosyası çalıştırılamaz:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "GTA:SA'yı yama" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA baÅŸlatılamadı çünkü GTA:SA yaması baÅŸarısız oldu:" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Grand Theft Auto: San Andreas baÅŸlatılamadı. Lütfen tekrar deneyiniz, ya da sorun devam ederse, lütfen www.multitheftauto.com adresinden MTA ile iletiÅŸime geçiniz. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "%s diskinde yeterli alan olmadığı için MTA:SA devam edemiyor." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Eksik dosya:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "EÄŸer MTA açılırken baÅŸarısız olursa, lütfen GTA:San Andreas'ı tekrardan kurun" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Yükleme ayarlarını güncelle" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas doÄŸru çalıştırılamadı. Sonlandırmak ister misiniz?" +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Uyumluluk ayarlarını güncelle" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +489,167 @@ msgstr "GTA: San Andreas doÄŸru çalıştırılamadı. Sonlandırmak ister misin #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Evet" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Hayır" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "TAMAM" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Çık" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Yardım" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "İptal et" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas bir problemle karşılaÅŸtı" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Çökme bilgisi" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Çökme bilgisini 'internet' aracılığı ile MTA geliÅŸtiricilerine göndemek için kutucuÄŸu iÅŸaretleyin" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Bunu yapmak bu çökmenin onarılma ihtimalini arttırır." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "MTA: San Andreas'ı yeniden baÅŸlatmak istiyor musunuz?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Uyarı" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "Grand Theft Auto: San Andreas kurulum dizininiz ÅŸu dosyaları içeriyor:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Bu dosyalar gerekli deÄŸildir ve MTA:SA'nın bu sürümündeki grafik özellikleri etkileyebilir.\n\n" "Bu dosyaları kaldırmanız veya yeniden adlandırmanız önerilir." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "Bu dosyaları saklayın, ancak bir sonraki baÅŸlatmada bu uyarıyı da göster" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Bana bu dosyaları bir daha hatırlatma" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Bu dosyaları *.dll'den *.dll.bak'a yeniden adlandırın" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Dosyaları görüntüle" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "MTA:SA Oyna" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Åžaşırtıcı özellikler" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus algılandı!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Her seçeneÄŸi dene ve hangisinin iÅŸe yaradığını gör:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Standart NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Alternatif NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - Standart Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - Alternatif Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "EÄŸer hangisini seçeceÄŸinizi bilmiyorsanız, bu size yardımcı olabilir:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Çalışan bir seçenek belirlediyseniz, bu yardımcı olabilir:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Pencere moduna zorla" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Bir daha gösterme" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Uyarı: Anti-virüs programı bulunamadı" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1107 +657,1181 @@ msgstr "MTA bilgisayarınızda anti-virüs programı bulamadı.\n\n" "Virüsler, MTA ile çakışır ve oyun deneyiminizi düşürür.\n\n" "Daha fazla bilgi için 'Yardım' butonuna basın." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Ben zaten önceden anti-virüs kurdum" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Anti-virüs kurmayacağım.\n" "Bilgisayarımın yavaÅŸlamasını ve botnetin bir parçası olmasını istiyorum." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "." + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Grand Theft Auto: San Andreas aranıyor" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Lütfen Grand Theft Auto: San Andreas'ı baÅŸlatın" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Güncelleme kuruluyor..." - -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Dosyalar çıkarılıyor..." - -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Dosyalar kopyalanıyor..." - -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Kopyalama iÅŸlemi erken bitti. Her ÅŸey yolunda." - -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Tamamlanıyor..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "BaÄŸlantı baÅŸarısız. Girilen kullanıcı adı geçersiz!" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Bitti!" +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "BaÄŸlantı baÅŸarısız. Girilen sunucu adresi geçersiz!" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 +#: Client/core/CConnectManager.cpp:132 #, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA ÅŸu görevi yürütebilmek için Yönetici izni istiyor:\n\n" -"'%s'\n\n" -"Lütfen bir sonraki pencereden onay verin. " +msgid "Connecting to %s at port %u failed!" +msgstr "%s sunucusuna %u portundan yapılan baÄŸlantı baÅŸarısız!" -#: Client/loader/CInstallManager.cpp:376 +#. Display the status box +#: Client/core/CConnectManager.cpp:153 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA bu görevi tamamlayamadı:\n\n" -"'%s'\n" - -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Hata, ekran kartı sürücüsü nedeniyle oluÅŸtu **\n\n" -"** Lütfen ekran kartı sürücülerinizi güncelleyin**" - -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "GüncellenmiÅŸ MTA:SA dosyalarını yükle" - -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Dosya çakışmaları nedeniyle güncellenemedi. Lütfen diÄŸer uygulamaları kapatın ve tekrar deneyin" +msgid "Connecting to %s:%u ..." +msgstr "%s:%u'a baÄŸlanılıyor..." -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:155 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto düzgün ÅŸekilde yüklenmemiÅŸ, lütfen tekrar yükleyin. %s" - -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "GTA:SA baÄŸlantı noktalarını oluÅŸtur" - -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA baÅŸlatılamadı çünkü dosya kopyalama baÅŸarısız oldu:" - -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA baÅŸlatılamadı çünkü bir MTA:SA dosyası hatalı veya eksik:" +msgid "Reconnecting to %s:%u ..." +msgstr "%s:%u adresine yeniden baÄŸlanılıyor..." -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "MTA:SA dosyalarını kopyala" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "BAÄžLANILIYOR" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA baÅŸlatılamadı çünkü bir GTA:SA dosyası hatalı veya eksik:" +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "BaÄŸlantı zaman aşımına uÄŸradı" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "GTA'SA'nın baÄŸlılığını yamala" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "BaÄŸlantı kesildi: Bilinmeyen protokol hatası" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA baÅŸlatılamadı çünkü GTA:SA baÅŸlatma dosyası hatalı veya eksik:" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "BaÄŸlantı kesildi: baÄŸlantı uzaktan kesildi." -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Lütfen antivirüs programınızı yanlış pozitif bir algılama için kontrol edin, GTA: SA klasörü için bir istisna eklemeye çalışın ve MTA:SA'yı yeniden baÅŸlatın." +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "BaÄŸlanti kesildi: baÄŸlantı uzaktan kaybedildi" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "GTA:SA OluÅŸtur" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "BaÄŸlantı kesildi: bu sunucudan yasaklandınız" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA baÅŸlatılamadı çünkü GTA:SA baÅŸlatma dosyası çalıştırılamaz:" +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "BaÄŸlantı kesildi: sunucu ile olan baÄŸlantı kesildi" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "GTA:SA'yı yama" +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "BaÄŸlantı kesildi: sunucu ile yapılan baÄŸlantı koptu" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA baÅŸlatılamadı çünkü GTA:SA yaması baÅŸarısız oldu:" +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "BaÄŸlantı Koptu: baÄŸlantı reddedildi" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "%s diskinde yeterli alan olmadığı için MTA:SA devam edemiyor." +msgid "No such mod installed (%s)" +msgstr "Böyle bir mod yüklü deÄŸil (%s)" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Eksik dosya:" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Sunucudan yanıt alınamıyor (2)" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "EÄŸer MTA açılırken baÅŸarısız olursa, lütfen GTA:San Andreas'ı tekrardan kurun" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Sunucudan yanıt alınamıyor (1)" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Yükleme ayarlarını güncelle" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Türkçe" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Uyumluluk ayarlarını güncelle" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "MeÅŸgul" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Bilinmeyen" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Güncellemeler ÅŸuan kontrol edilemiyor" -#: Client/loader/Install.cpp:272 +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 #, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "'%s' dosyası ÅŸu anda %zu iÅŸlemleri tarafından kilitlendi.\n\n" -"AÅŸağıdaki süreçleri sonlandırmak ve güncellemeye devam etmek istiyor musunuz?\n\n" -"%s" +msgid "MTA:SA %s required" +msgstr "MTA:SA %s gerekli" -#: Client/loader/Install.cpp:479 +#: Client/core/CVersionUpdater.cpp:1631 #, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "Kurulumunuz bozulmuÅŸ olabilir.\n\n" -"%zu dosyalarından %zu yedekten geri yüklenemedi.\n\n" -"Multi Theft Auto'yu www.multitheftauto.com adresinden yeniden yüklemeyi\n" -"veya güncellemeyi yönetici olarak çalıştırmayı deneyebilirsiniz." +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Bu sunucuya girebilmek için MTA:SA'nın %s versiyonu gerekiyor.\n\n" +"MTA:SA'nın %s versiyonunu indirip yüklemek ister misiniz?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "MTA:SA'nın %s versiyonunu çalıştırıp bu sunucuya baÄŸlanmak ister misiniz?" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "BaÄŸlantı ÅŸu an mümkün deÄŸil.\n\n" +"Lütfen sonra tekrar deneyin." -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "BaÄŸlanılıyor" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Grand Theft Auto: San Andreas'ın yüklü olduÄŸu klasörü seçiniz" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Lütfen bekleyiniz..." -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "%s modülünü yüklemede hata! (%s)" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "KONTROL EDİLİYOR" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Yeni %s kurulumu algılandı.\n\n" -"%s ayarlarınızı kopyalamak ister misiniz?" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "GÜNCELLEME KONTROLÜ" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA '%s' dosyasını açmakta sorun yaÅŸadı" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Güncellemeye gerek yok" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA '%s' dosyası kayıp." +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "İNDİRİLİYOR" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA bir modeli yüklerken sorunla karşılaÅŸtı." +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "bekleniyor..." -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "EÄŸer yakın zamanda gta3.img dosyasını deÄŸiÅŸtirdiyseniz, GTA:SA'yı tekrar yüklemeyi deneyin." +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "ZORUNLU GÜNCELLEME" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA arabaya modifiye eklerken sorunla karşılaÅŸtı." +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Bu sunucuya baÄŸlanmak için MTA'yı güncellemeniz gerekiyor.\n\n" +"Åžimdi güncellemek ister misiniz?" -#: Client/loader/Utils.cpp:1631 -#, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA '%s' dosyasında hatalar buldu" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "İSTEÄžE BAÄžLI GÜNCELLEME" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "MTA:SA oynarken bilgisayarın yeniden mi baÅŸlatıldı?" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Sunucu bir güncelleme yapmanızı öneriyor, ama zorunlu deÄŸil.\n\n" +"Güncellemek ister misiniz?" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Lütfen devam etmeden önce ÅŸu programları sonlandırınız:" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "GüncelleÅŸtirme ÅŸu an mevcut deÄŸil.\n\n" +"Lütfen www.multitheftauto.com'a bakınız" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Website istekleri" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "KAYIT HATASI" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Sunucu, (sonradan) yükleme yapmak için ÅŸu siteleri talep ediyor:" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Dosya oluÅŸturulamıyor." -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "ÇALINMASINI ÖNLEMEK İÇİN ASLA ÖNEMLİ BİLGİLERİ GİRMEYİN" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "İNDİRME HATASI" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Seçimi hatırla" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "İndirilen dosya bozuk gibi gözüküyor." -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "İzin ver" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Bazı sebeplerden dolayı." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Reddet" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "İNDİRME TAMAMLANDI" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "Ana menü" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr "_DialogUpdateResult 'ta bilinmeyen bir problem." -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Yeni özelliklerin olduÄŸu bir versiyon kullanıyorsun! Bu versiyon sadece deneme amaçlıdır ve herhangi bir sunucuya baÄŸlanmak için kullanılamaz!" +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "DEĞİŞTİRİLMİŞ GTA:SA DOSYALARI" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "XP ve Vista, Temmuz 2019'dan sonra güncelleme almayacak.\n\n" -"En son ve güncel serverlarda oynamak için, Windows'unuzu güncelleyin." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Tamam" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Bu sizi mevcut sunucudan atacaktır.\n\n" -"Çıkmak istediÄŸinizden emin misiniz?" +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "HATA" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "BAÄžLANTI KESME UYARISI" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Bazı MTA:SA dosyaları bulunamıyor.\n\n\n" +"Lütfen MTA:SA'yı tekrar yükleyin." -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "" +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% tamamlandı" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Türkçe" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Cevap bekleniyor - %-3d" + +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ KOMUT YARDIMI ]***\n" + +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Saat %d:%02d:%02d" + +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "baÄŸlanma: AÄŸ hazır deÄŸil, lütfen bir süre bekleyin" + +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "baÄŸlan (/connect): Sözdizimi 'connect [ <ÅŸifre>]'" + +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "baÄŸlan: Hatalı port adresi" + +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "baÄŸlan: %s:%u...'e baÄŸlanılıyor..." + +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "baÄŸlan: %s:%u adresine baÄŸlanılamadı!" + +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "baÄŸlan: Mevcut mod devre dışı bırakılamadı" + +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "yeniden baÄŸlanma: AÄŸ hazır deÄŸil, lütfen bir süre bekleyin" + +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "yeniden baÄŸlanma: Geçersiz port numarası" + +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "yeniden baÄŸlanıyor: %s:%u adresine..." + +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "yeniden baÄŸlanma: %s:%u adresine baÄŸlanılamadı!" + +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Tüm kontrol atamaları GTA'dan alındı" + +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Yapılandırma dosyası kaydedildi" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Seri numaran: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "AYARLAR" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Çok Oyunculu" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Görüntü" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Ses" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "TuÅŸlar" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Kontroller" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Arayüz" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "İnternet Tarayıcısı" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "GeliÅŸmiÅŸ" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Varsayılanları yükle" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Fare hassasiyeti:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Dikey fare hassasiyeti:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Fare ayarları" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Fareyi dikine doÄŸru ters çevir" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Fare ile sürüş" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Fare ile uçuÅŸ" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Joypad ayarları" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Standart kontroller (Fare + Klavye)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Klasik kontroller (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Ölü alan" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Doygunluk" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Joypad tuÅŸları için 'TuÅŸ atamaları' sekmesini kullanın" -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Sol Çubuk" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "SaÄŸ Çubuk" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "AÇIKLAMA" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "TUÅž" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALTERNATİF TUÅž" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Kullanıcı adı:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Sunucu ÅŸifrelerini kaydet" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Sunucu tarayıcısını otomatik yenile" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Ekran yüklemesine izin ver" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Harici seslere izin ver" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "İndirme penceresini her zaman göster" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Discord Rich Presence ile baÄŸlantıya izin ver" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" -msgstr "" +msgstr "GTA:SA oyun içi durumunun Steam'de gösterilmesine izin ver" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" -msgstr "" +msgstr "Kamera silahıyla çekilen fotoÄŸrafları GTA San Andreas Kullanıcı Dosyaları klasörüne kaydet" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" -msgstr "" +msgstr "Ana menüyü kullanarak sunucudan ayrılmadan önce onay iste" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "DeÄŸiÅŸtirilmiÅŸ GTA San Andreas dosyalarını kullan" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Harita renderlama seçenekleri" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Opaklık:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" -msgstr "" +msgstr "Görüntü çözünürlüğü:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" -msgstr "" +msgstr "1024 x 1024 (Varsayılan)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Ana ses:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Radyo ses seviyesi:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "SFX ses düzeyi:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA ses düzeyi" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Ses düzeyi:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Oyun modu:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Genel" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Radyo ayarları" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Radyo Ekolayzer" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Radyo Otomatik Açıcı" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Kullanıcı radyosu ayarları" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Radyo" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Rastgele" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Ardışık Sıralı" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Otomatik Medya Taraması" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Susturma ayarları" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Simge durumuna küçültüldüğünde bütün sesleri sustur" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Simge durumuna küçültüldüğünde radyoyu sustur" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Simge durumuna küçültüldüğünde SFX seslerini sustur" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Simge durumuna küçültüldüğünde MTA seslerini sustur" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Simge durumuna küçültüldüğünde oyuncu mikrofonlarını sustur" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Çözünürlük:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Görüş Açısı:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Görüş Mesafesi:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Parlaklık:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX Kalitesi:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Anizotropik filtreleme:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "YumuÅŸatma:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Ekran Oranı:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Pencere modu" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI hassaslığı" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Standart" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Çerçevesiz tam ekran" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mip Haritalaması" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Düşük" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Orta" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Yüksek" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Çok yüksek" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Kapalı" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Otomatik" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD Boy Oranı EÅŸleÅŸmesi" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Volutmetrik Gölgeler" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Çim efektleri" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Isı bulanıklığı" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Lastik Dumanı vs" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Dinamik ped gölgeleri" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Hareket Bulanıklığı" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Corona yaÄŸmur yansımaları" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Tam Ekran Küçültmesi" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Cihaz Seçme DiyaloÄŸunu Aktif Hale Getir" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Güvenli olmayan çözünürlükleri göster" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Araçları her zaman yüksek detayda göster" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Pedleri her zaman yüksek detaylı olarak göster" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "İnternet web sayfalarını etkinleÅŸtir" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "İnternet web sayfalarında Javascript'i etkinleÅŸtir" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" -msgstr "" +msgstr "GPU renderlamayı etkinleÅŸtir" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Engelli siteler" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Alan adı girin, örneÄŸin: google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Engelle" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Alan Adı" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Alan adını kaldır" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "İzinli siteler" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "İzin ver" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "DiÄŸer" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Hızlı CJ giysileri yükleme:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Tarayıcı hızı:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Tek baÄŸlantı:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Paket etiketi:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Yükleme animasyonu:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "İşlem önceliÄŸi:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "GeliÅŸtirici ayarları:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Görüntüleme belleÄŸi:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Güncelleme türü:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Önemli güncellemeleri kur:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Açık" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Çok yavaÅŸ" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Varsayılan" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Hızlı" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Normal" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Normal üstü" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Min" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Maks" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 uyumluluÄŸu:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-bit renk" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Fareyi düzelt" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "İndirilen sunucu dosyaları: " -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Dosyalarda göster" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" -msgstr "" +msgstr "Oyunun performansını artırmak için CPU 0 baÄŸlanırlığını ayarla" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Otomatik güncelleyici" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Güncellemeleri kontrol et" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Bazı ayarlar MTA'yı bir sonraki baÅŸlattığınızda deÄŸiÅŸmiÅŸ olacak" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Åžimdi yeniden baÅŸlatmak istiyor musun?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "YENİDEN BAÅžLATMA GEREKİYOR" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Åžu anki sunucudan çıktığınızda bazı ayarlar deÄŸiÅŸtirilecektir" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "BaÄŸlantıyı ÅŸimdi kesmek istiyor musun?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "BAÄžLANTINIZI KESMENİZ GEREKMEKTEDİR" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Joypad bulunamadı - GiriÅŸleri kontrol edip oyunu tekrar baÅŸlatın" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "BaÄŸlama ekseni" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Bind için bir ekseni hareket ettir, yada temizlemek için ESC'ye bas." -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Dil:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Tema:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Kayıtlılar:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Sohbet" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Yükle" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Renkler" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Düzen" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Seçenekler" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Sohbet Arka Planı" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Sohbet Yazısı" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "GiriÅŸ Arka planı" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Yazı GiriÅŸi" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Satırlar:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Ölçek:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "GeniÅŸlik:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Boyut" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "sonra" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "için" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "saniye" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Solma" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Eski satırları soldurt" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Yatay:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Dikey:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Yazı-Hizası:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X-Dengesi:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y-Dengesi:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Pozisyon" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Sol" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Merkez" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "SaÄŸ" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "En Üst" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "En Alt" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Yazı tipi" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Yazı yazmıyorken arkaplanı gizle" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "\"Tab\" tuÅŸuyla isim tamamlama" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Sunucunun pencereyi yanıp söndürmesine izin ver" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Balon bildirimlere izin ver" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Chat mesajlarına siyah/beyaz çerçeve ekle" @@ -1548,89 +1839,95 @@ msgstr "Chat mesajlarına siyah/beyaz çerçeve ekle" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Atamak istediÄŸin tuÅŸa bas veya tuÅŸu temizlemek için ESC'ye bas" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Ana tuÅŸ ataması" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "İkincil tuÅŸ ataması" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA OYUN KONTROLLERİ" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "ÇOKLU OYUNCU KONTROLLERİ" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "İsminde izin verilmeyen karakterler var!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Ana menü" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "Oyunda" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Kırmızı:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "YeÅŸil:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Mavi:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Åžeffaflık:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Renk" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Ön izleme" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Lütfen dilinizi deÄŸiÅŸtirmeden önce sunucudan ayrılın" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Lütfen temanızı deÄŸiÅŸtirmeden önce sunucudan ayrılın" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Volumetrik gölgeler bazı sistemlerin yavaÅŸlamasına neden olabilir.\n\n" "EtkinleÅŸtirmek istediÄŸine emin misin?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "PERFORMANS UYARISI" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Ekran görüntüsü paylaşımı, bazı sunucular için anti-hile amacıyla gerekmektedir.\n\n" "(Sohbet kutusu ve kullanıcı arayüzü yüklemenin dışındadır)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "EKRAN YÜKLEME BİLGİSİ" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1638,23 +1935,21 @@ msgstr "Bazı scriptler, internetten -radyo gibi- sesleri oynatabilir.\n\n" "Bu ayarı kapatmak internet\n" "bant geniÅŸliÄŸini rahatlatabilir\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "HARİCİ SESLER" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "Görünüşe göre Rich Presence baÄŸlantı seçeneÄŸini etkinleÅŸtirmiÅŸsiniz.\n" -"Sunucuların verilerini paylaÅŸmasına izin vermek istiyor musunuz?\n\n" -"Bu sizin benzersiz kimlik tanımlayıcınızı içerir." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "VERI PAYLAÅžIMINA IZIN VERMEK IÇIN ONAY VER" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1664,11 +1959,7 @@ msgstr "GTA:SA klasörünüzdeki bazı dosyalar deÄŸiÅŸtirilmiÅŸ.\n" "Ancak, DEĞİŞTİRİLMİŞ GTA:SA DOSYALARI ÇOÄžU SUNUCU TARAFINDAN ENGELLENMİŞTİR.\n\n" "Bu dosyaları kullanmak istediÄŸinize emin misiniz?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "DEĞİŞTİRİLMİŞ GTA:SA DOSYALARI" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1678,551 +1969,253 @@ msgstr "DPI hassasiyetini aktif etmek, deneysel bir özellik ve sadece\n" "Aksi taktirde bazı grafiksel problemlerle karşılaÅŸabilirsiniz.\n\n" "Bu özelliÄŸi aktif etmek istiyor musunuz?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "DENEYSEL ÖZELLİK" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" -msgstr "" +msgstr "Bu seçeneÄŸin devre dışı bırakılması, performans sorunları yaşıyorsanız önerilmez.\n\n" +"Devre dışı bırakmak istediÄŸinizden emin misiniz?" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Lütfen bir isim girin" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Oyunda kullanılmak üzere bir nick girin. \n" "Bu, girdiÄŸiniz sunucularda sizin adınız olarak kullanılacak" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Çok deneysel özellik." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "CJ varyasyonlarındaki takılmaları durdurur (65MB daha fazla RAM kullanır)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Eski modemler daha yavaÅŸ tarama hızı gerektirebilir." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "İndirme yaparken sadece bir baÄŸlantı üzerinden indirme yapmak için aktif edin." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "AÄŸ paketlerini etiketleyerek MTA trafiÄŸini tanıyabilmesi için Internet Servis SaÄŸlayıcılarına yardımcı olun." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Ekranın alt kısmındaki dönen daire animasyonu" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Varsayılanı seçin. (Bu ayar kaydedilmez)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Maximum genellikle en iyidir" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Otomatik güncelleyici:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "EÄŸer hata raporu doldurmayı sevmiyorsanız varsayılanı seçin." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Önemli güncelleÅŸtirmeleri otomatik olarak yüklemek için varsayılan'ı seçin." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-bit renk:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "16-bit renk modunu etkinleÅŸtir - MTA'yı yeniden baÅŸlatmanı gerektirir" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Fare düzeltmesi:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Fare hareketini düzelt - Bilgisayarı yeniden baÅŸlatmayı gerektirebilir" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" -msgstr "" +msgstr "CPU baÄŸlanırlığı:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." -msgstr "" - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Bilinmeyen komut veya cvar: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "MeÅŸgul" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Güncellemeler ÅŸuan kontrol edilemiyor" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "MTA:SA %s gerekli" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Bu sunucuya girebilmek için MTA:SA'nın %s versiyonu gerekiyor.\n\n" -"MTA:SA'nın %s versiyonunu indirip yüklemek ister misiniz?" +msgstr "Yalnızca kararlılık sorunları yaşıyorsanız deÄŸiÅŸtirin." -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "MTA:SA'nın %s versiyonunu çalıştırıp bu sunucuya baÄŸlanmak ister misiniz?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "BaÄŸlantı ÅŸu an mümkün deÄŸil.\n\n" -"Lütfen sonra tekrar deneyin." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "BaÄŸlanılıyor" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Lütfen bekleyiniz..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "KONTROL EDİLİYOR" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "GÜNCELLEME KONTROLÜ" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Güncellemeye gerek yok" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "İNDİRİLİYOR" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "bekleniyor..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "ZORUNLU GÜNCELLEME" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Bu sunucuya baÄŸlanmak için MTA'yı güncellemeniz gerekiyor.\n\n" -"Åžimdi güncellemek ister misiniz?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "İSTEÄžE BAÄžLI GÜNCELLEME" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Sunucu bir güncelleme yapmanızı öneriyor, ama zorunlu deÄŸil.\n\n" -"Güncellemek ister misiniz?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "GüncelleÅŸtirme ÅŸu an mevcut deÄŸil.\n\n" -"Lütfen www.multitheftauto.com'a bakınız" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "KAYIT HATASI" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Dosya oluÅŸturulamıyor." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "İNDİRME HATASI" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "İndirilen dosya bozuk gibi gözüküyor." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Bazı sebeplerden dolayı." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "İNDİRME TAMAMLANDI" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "_DialogUpdateResult 'ta bilinmeyen bir problem." - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Tamam" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "HATA" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Bazı MTA:SA dosyaları bulunamıyor.\n\n\n" -"Lütfen MTA:SA'yı tekrar yükleyin." - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% tamamlandı" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Cevap bekleniyor - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "BaÄŸlantı baÅŸarısız. Girilen kullanıcı adı geçersiz!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "BaÄŸlantı baÅŸarısız. Girilen sunucu adresi geçersiz!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "%s sunucusuna %u portundan yapılan baÄŸlantı baÅŸarısız!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "%s:%u'a baÄŸlanılıyor..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "BAÄžLANILIYOR" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "BaÄŸlantı zaman aşımına uÄŸradı" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "BaÄŸlantı kesildi: Bilinmeyen protokol hatası" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "BaÄŸlantı kesildi: baÄŸlantı uzaktan kesildi." - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "BaÄŸlanti kesildi: baÄŸlantı uzaktan kaybedildi" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "BaÄŸlantı kesildi: bu sunucudan yasaklandınız" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "BaÄŸlantı kesildi: sunucu ile olan baÄŸlantı kesildi" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "BaÄŸlantı kesildi: sunucu ile yapılan baÄŸlantı koptu" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "BaÄŸlantı Koptu: baÄŸlantı reddedildi" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Böyle bir mod yüklü deÄŸil (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Sunucudan yanıt alınamıyor (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Sunucudan yanıt alınamıyor (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "HABERLER" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Son haber makalesini ziyaret et" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "KONSOL" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Sistemsel hata" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "DÜZELTMEK İÇİN, ÅžU DOSYAYI SİL:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s modülü yanlış!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "URL çalıştırılırken bir hata oluÅŸtu" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "bu yardım ekranı" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "uygulamadan çıkar" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "versiyonu gösterir" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "zamanı gösterir" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "arayüzü gösterir" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "bütün tuÅŸ atamalarını gösterir" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "seri numaranızı gösterir" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "bir sunucuya (ip port takma-ad ÅŸifre) baÄŸlanır" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "bir önceki sunucuya baÄŸlanır" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "bir tuÅŸ atamasını kaydeder (tuÅŸ kontrol)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "tuÅŸ atamasını çıkarır (tuÅŸ)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "varsayılan gta kontrollerini kopyalar" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "bir ekran görüntüsü kaydeder" -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "yapılandırmayı hemen kaydeder" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "debug görünümünü temizler" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "konuÅŸma penceresini yukarı kaydırır" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "konuÅŸma penceresini aÅŸağı kaydırır" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "debug görünümünü yukarıya doÄŸru kaydırır" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "debug görünümünü aÅŸağı doÄŸru kaydırır" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "hafıza istatistiklerini gösterir" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "çerçeve zamanlama grafiÄŸini gösterir" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "geliÅŸtiriciler için: haberleri yeniden yükle" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ KOMUT YARDIMI ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Saat %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "baÄŸlan (/connect): Sözdizimi 'connect [ <ÅŸifre>]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "baÄŸlan: Hatalı port adresi" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "baÄŸlan: %s:%u...'e baÄŸlanılıyor..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "yapılandırmayı hemen kaydeder" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "baÄŸlan: %s:%u adresine baÄŸlanılamadı!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "debug görünümünü temizler" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "baÄŸlan: Mevcut mod devre dışı bırakılamadı" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "konuÅŸma penceresini yukarı kaydırır" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "konuÅŸma penceresini aÅŸağı kaydırır" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "debug görünümünü yukarıya doÄŸru kaydırır" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "debug görünümünü aÅŸağı doÄŸru kaydırır" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "hafıza istatistiklerini gösterir" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Tüm kontrol atamaları GTA'dan alındı" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "çerçeve zamanlama grafiÄŸini gösterir" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Yapılandırma dosyası kaydedildi" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "geliÅŸtiriciler için: haberleri yeniden yükle" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Seri numaran: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Yeni özelliklerin olduÄŸu bir versiyon kullanıyorsun! Bu versiyon sadece deneme amaçlıdır ve herhangi bir sunucuya baÄŸlanmak için kullanılamaz!" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Ekseni hızlandır" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "XP ve Vista, Temmuz 2019'dan sonra güncelleme almayacak.\n\n" +"En son ve güncel serverlarda oynamak için, Windows'unuzu güncelleyin." -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Ekseni yavaÅŸlat" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Bu sizi mevcut sunucudan atacaktır.\n\n" +"Çıkmak istediÄŸinizden emin misiniz?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Programlama" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "BAÄžLANTI KESME UYARISI" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Katkıda Bulunanlar" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "BİLGİ" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Oyun Dizaynı / Modlama" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "HABERLER" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "YerelleÅŸtirme" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Son haber makalesini ziyaret et" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Aktif Katkıda Bulunanlar" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Ekran görüntüsü %d boyutunda, ancak %d olması gerekiyor" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Özel TeÅŸekkürler" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Ekran görüntüsü alınamadı" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Bu yazılım ve proje aÅŸağıdaki kütüphaneleri ve yazılımları kullanır:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Ekran görüntüsü alındı: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Bu problem hakkında önerilen çözümü görmek ister misiniz?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Bilinmeyen komut veya cvar: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2397,25 +2390,56 @@ msgid "Group control backwards" msgstr "Grup kontrol geri" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "SeçtiÄŸiniz oyuncu tipi yüklenemedi, ayrıca varsayılan tip de yüklenememiÅŸtir. Lütfen MTA' yı yeniden yükleyiniz." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Ekran görüntüsü %d boyutunda, ancak %d olması gerekiyor" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Bu problem hakkında önerilen çözümü görmek ister misiniz?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Ekran görüntüsü alınamadı" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "KONSOL" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Ekran görüntüsü alındı: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Programlama" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Katkıda Bulunanlar" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Oyun Dizaynı / Modlama" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "YerelleÅŸtirme" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Aktif Katkıda Bulunanlar" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Özel TeÅŸekkürler" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Bu yazılım ve proje aÅŸağıdaki kütüphaneleri ve yazılımları kullanır:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Ekseni hızlandır" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Ekseni yavaÅŸlat" + +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2423,6 +2447,61 @@ msgstr "Direct3D9 baÅŸlatılamadı.\n\n" "Lütfen DirectX End-User Runtime ve\n" "son çıkan Windows GüncelleÅŸtirmelerinin doÄŸru yüklendiÄŸini teyit edin." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Beklemede" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "oyuncu" +msgstr[1] "oyuncular" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "açık" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "sunucu" +msgstr[1] "sunucular" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Ana sunucu listesi alınıyor. (%lu ms geçti)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Ana sunucu listesi ayrıştırılamadı." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Ana sunucu listesi alınamadı." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Yedek sunucu listesi)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "LAN-yayın soketi atanamadı" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "LAN sunucuları aranıyor" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2476,7 +2555,7 @@ msgstr "Gecikme:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Oyuncu listesi" @@ -2503,40 +2582,39 @@ msgstr "Sunucuda yer açılınca otomatik olarak baÄŸlan." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "LÜTFEN SUNUCU ŞİFRESİNİ GİRİN" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Zaman Aşımı" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Sorguluyor..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "SUNUCU TARAYICI" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Internet" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Yerel" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Favoriler" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Son oynananlar" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2544,298 +2622,367 @@ msgstr "HIZLI BAÄžLANTI İÇİN:\n\n" "Adresi ve portu adres çubuÄŸuna yazın.\n" "Veya geçmiÅŸ listesinden bir sunucu seçin ve 'BaÄŸlan'a basın" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "YARDIM" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Yenile" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Favorilere ekle" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "BaÄŸlan" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Sunucu bilgileri" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Sunucu ara" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Oyuncu ara" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Aramayı baÅŸlat" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Oyuncu arama..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Sunucu arama..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "İsim" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Oyuncular" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Gecikme" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Oyun modu" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "İçersin:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "BoÅŸ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Dolu" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Kilitli" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Çevrimdışı" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "DiÄŸer Sürümler" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Geri" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Yükleniyor..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..yükleniyor.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Sunucu adresi girmediniz!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Bilinmeyen protokol" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Lütfen mtasa:// protokolünü kullanın!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Geçersiz isim! Ayarlardan yeni bir isim belirleyin!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "BaÄŸlanmak için bir sunucu seçmeniz gerekiyor." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Beklemede" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Ekran kartı sürücüsü ile problem" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "oyuncu" -msgstr[1] "oyuncular" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Geçerli ekran çözünürlüğü bulunamadı." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "açık" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Bu çözünürlüğü kullanmak istediÄŸinizden emin misiniz?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "sunucu" -msgstr[1] "sunucular" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "game_sa baÅŸlatılamadı" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Ana sunucu listesi alınıyor. (%lu ms geçti)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "Bellek tahsisi baÅŸarısız oldu" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Ana sunucu listesi ayrıştırılamadı." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Website istekleri" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Ana sunucu listesi alınamadı." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Sunucu, (sonradan) yükleme yapmak için ÅŸu siteleri talep ediyor:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Yedek sunucu listesi)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "ÇALINMASINI ÖNLEMEK İÇİN ASLA ÖNEMLİ BİLGİLERİ GİRMEYİN" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "LAN-yayın soketi atanamadı" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Seçimi hatırla" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "LAN sunucuları aranıyor" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Reddet" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Bu versiyon zaman aşımına uÄŸradı." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "oyundan ayrıl" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "isim etiketlerini gösterir" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "konuÅŸma kutusunu gösterir" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "baÄŸlantı istatistiklerini gösterir" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "sohbet giriÅŸini aç" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "sesi diÄŸer oyunculara iletir" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "bir araca yolcu olarak biner" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "sonraki radyo kanalı" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "önceki radyo kanalı" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" -msgstr "" +msgstr "oyuncu harita görünümünü etkinleÅŸtirir" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" -msgstr "" +msgstr "oyuncu haritasını yakınlaÅŸtırır" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" -msgstr "" +msgstr "oyuncu haritasını uzaklaÅŸtırır" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" -msgstr "" +msgstr "oyuncu haritasını kuzeye hareket ettirir" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" -msgstr "" +msgstr "oyuncu haritasını güneye hareket ettirir" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" -msgstr "" +msgstr "oyuncu haritasını doÄŸuya hareket ettirir" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" -msgstr "" +msgstr "oyuncu haritasını batıya hareket ettirir" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" -msgstr "" +msgstr "oyuncu haritasını iliÅŸtirir" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" -msgstr "" +msgstr "oyuncu haritasının saydamlığını azaltır" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" -msgstr "" +msgstr "oyuncu haritasının saydamlığını artırır" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" -msgstr "" +msgstr "oyuncu haritası yardım metnini açar veya kapatır" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "hedeflenen oyuncuya bir mesaj gönderir" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "araç içindeyken bir sonraki silaha geçer" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "araç içindeyken bir önceki silaha geçer" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "mevcut sunucu hakkında bilgi sunar" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "yazı görüntülerinin boyut ayarını belirtir" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(GeliÅŸtirme Modu) colshapeleri gösterir" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(GeliÅŸtirme Modu) dünya seslerinin id'lerini debug ekranına yollar" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "SUNUCU KUR" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "Kaynaklar" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Sunucu adı:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Parola:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Oyuncu limiti:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "Yayınla:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "LAN" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Seçili" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Tümü" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "BaÅŸlat" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "Mod deÄŸiÅŸtirildi: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "YakınlaÅŸtırma: %s/%s Hareket: %s, %s, %s, %s Saydamlık: %s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "Haritayı aç/kapat: %s Yardım metnini aç/kapat: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "Oyuncuyu takip ediyor" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "Serbest hareket" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Harita indirme süreci:" @@ -2856,195 +3003,195 @@ msgstr "%s'nin %s'i" msgid "Disconnect to cancel download" msgstr "İndirmeyi iptal etmek için baÄŸlantıyı kes" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "BaÄŸlantı Kesildi: Geçersiz nick" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Sunucu baÄŸlantısını sonlandır" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "BaÄŸlantı kesildi. Seri kodu yasaklandı.\n" "Gerekçe: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "BaÄŸlantı kesildi: Yasaklandınız.\n" "Gerekçe: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "BaÄŸlantı kesildi: Hesap yasaklı.\n" "Gerekçe: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "BaÄŸlantı kesildi: Sürüm uyumsuzluÄŸu" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "BaÄŸlantı kesildi: GiriÅŸ trafiÄŸi. Lütfen bir dakika bekleyin, ardından tekrar baÄŸlanın." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "BaÄŸlantı kesildi: Server farklı branch'tan.\n" "Bilgi: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "BaÄŸlantı kesildi: Kötü versiyon.\n" "Bilgi: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "BaÄŸlantı kesildi: Sunucu daha yeni bir versiyonda çalışıyor.\n" "Bilgi: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "BaÄŸlantı kesildi: Sunucu daha eski bir versiyonda çalışıyor.\n" "Bilgi: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "BaÄŸlantı kesildi: Nick zaten kullanılıyor" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "BaÄŸlantı kesildi: Oyuncu elementi yaratılamadı." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "BaÄŸlantı kesildi: Sunucu baÄŸlantıyı reddetti: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "BaÄŸlantı kesildi: Seri kod doÄŸrulaması baÅŸarısız oldu" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" -msgstr "" +msgstr "BaÄŸlantı kesildi: Seri zaten kullanılıyor" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "BaÄŸlantı kesildi: BaÄŸlantı desenkronize oldu %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "BaÄŸlantı kesildi: %s tarafından atıldınız." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "BaÄŸlantı kesildi: %s tarafından yasaklandınız." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "BaÄŸlantı Koptu: Server kapatıldı veya yeniden baÅŸlatılıyor" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Oyundan atıldınız" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Bu sunucu deÄŸiÅŸtirilmemiÅŸ bir gta_sa.exe dosyasına ihtiyaç duyuyor" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Lütfen gta_sa.exe dosyasını deÄŸiÅŸtirin" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Bu sunucu özelleÅŸtirilmiÅŸ D3D9.DLL dosyalarına izin vermiyor" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "D3D9.DLL dosyasını GTA yükleme dizininden kaldırın ve MTA'yı yeniden baÅŸlatın" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Bu sunucu sanal bilgisayarlara izin vermiyor" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Bu sunucu, sürücü imzalamasına izin verilmiÅŸ olmasını gerektiriyor" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Lütfen bilgisayarınızı yeniden baÅŸlatın" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Bu sunucu, eksik anti-hile bileÅŸenleri algıladı" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "MTA'yı yeniden baÅŸlatmayı deneyin" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Bu sunucu deÄŸiÅŸtirilmemiÅŸ gta3.img ve gta_int.img dosyalarına ihtiyaç duyuyor" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Lütfen gta3.img ve gta_int.img dosyalarının yerini seçin" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Bu sunucu Wine ile giriÅŸlere izin vermiyor" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "Farklı bir programın MTA:SA'yı deÄŸiÅŸtirmediÄŸinden emin olun" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Kalan Süre: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d gün" msgstr[1] "%d gün" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d saat" msgstr[1] "%d saat" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d dakika" msgstr[1] "%d dakika" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3052,302 +3199,212 @@ msgstr[0] "%d saniye" msgstr[1] "%d saniye" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "BaÄŸlantı kesildi" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "İndirme hatası: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "Etrafta bir UFO uçurmak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "Etrafta gezinmek" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "Dalgalar içinde yüzüyor" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "Trene binmek" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "Etrafta uçmak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "Etrafta dolaÅŸmak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "Monster kamyonetle gezinti" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "Quaddin' etrafında" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "Etrafta Zıplamak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "Garip ÅŸeyler yapmak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "Etrafta Tırmanmak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "Arabayla geçerken" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "Blub blub..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "Su solumak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "BoÄŸulmak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "Siper almak için eÄŸilmek" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "Dövüşmek" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "Yumruk atmak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "Aptalları patlatmak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "AteÅŸ etmek" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "İçinde jetpack açmak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "Gerçek anlamda yanmak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "Yanıyor" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "Yüzmek" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "Etrafta gezmek" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "Bir köpekbalığı tarafından kovalanmak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "BoÄŸulma sonucu ölüm" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Oyuna giriliyor ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "BaÄŸlanmadı; lütfen Hızlı BaÄŸlan veya 'connect' komutunu kullanın ve bir sunucuya baÄŸlanın." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Yerel sunucu baÅŸlatılamadı. Ayrıntılar için konsola bakın. " -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Yerel Sunucu" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Yerel sunucu baÅŸlatılıyor ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "51. Bölge" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "Etrafta dolaÅŸmak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Oyundan atıldınız ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Yerel sunucuya baÄŸlanılıyor..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Sunucuya baÄŸlanırken hata." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Yerel sunucuya baÄŸlantı zaman aşımına uÄŸradı. Detaylar için konsola bakınız." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Sunucuyla baÄŸlantı koptu." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "BaÄŸlantı Kesildi: sunucu dolu" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "BaÄŸlantı Kesildi: yanlış ÅŸifre girildi" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA İstemci doÄŸrulaması yapılamadı!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "Bir çukurda" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "Hastane yolunda" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "Yaratıcılarıyla tanışmak" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "Kararlarından piÅŸman oluyor" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "Yakalandı" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "SUNUCU KUR" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "Kaynaklar" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Sunucu adı:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Parola:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Oyuncu limiti:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "Yayınla:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "LAN" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Seçili" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Tümü" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "BaÅŸlat" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Ekran kartı sürücüsü ile problem" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Geçerli ekran çözünürlüğü bulunamadı." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Bu çözünürlüğü kullanmak istediÄŸinizden emin misiniz?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "İndirme hatası: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 #, c-format msgid "Fatal error (%u). If this problem persists, please check out multitheftauto.com for support." -msgstr "" +msgstr "Ciddi hata (%u). Bu sorun devam ederse, destek için lütfen multitheftauto.com adresini ziyaret edin." #. #ifdef MTA_DEBUG #. assert ( 0 ); @@ -3356,17 +3413,17 @@ msgstr "" #: Shared/mods/deathmatch/logic/Utils.cpp:143 #, c-format msgid "Protocol error (%u). If this problem persists, please check out multitheftauto.com for support." -msgstr "" +msgstr "Protokol hatası (%u). Bu sorun devam ederse, destek için lütfen multitheftauto.com adresini ziyaret edin." #: Shared/mods/deathmatch/logic/Utils.cpp:145 msgid "Connection error" msgstr "BaÄŸlantı hatası" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto düzgün yüklenmemiÅŸ, lütfen tekrar yükleyin." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Tarayıcınız yardım bilgisi bulunduran bir sayfa açacak.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/uk_UA/client.pot b/Shared/data/MTA San Andreas/MTA/locale/uk_UA/client.pot index 8dc8e055635..3a1fee38cf1 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/uk_UA/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/uk_UA/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Ukrainian\n" "Language: uk_UA\n" @@ -17,71 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Проблема перезапуÑку MTA:SA\n\n" -"Якщо проблема збереглаÑÑ, то відкрийте диÑпетчер завдань Ñ– зупиніть процеÑи 'gta_sa.exe' Ñ– 'Multi Theft Auto.exe' \n\n\n" -"Спробувати запуÑтити MTA:SA знову?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "ЗапуÑтіть Grand Theft Auto: San Andreas.\n" +"ПереконайтеÑÑ, що гра знаходитьÑÑ Ð² папці \"Program Files (x86)\"." -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Помилка" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "У пошуках GTA: San Andreas" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "Інший Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð· MTA вже запущений.\n\n" -"Якщо проблема не вирішена, Ñпробуйте перезавантажити комп'ютер" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "Вибачте, гра не знайдена.\n" +"ЗапуÑтіть Grand Theft Auto: San Andreas Ñ– натиÑніть \"Повторити\".\n" +"ПереконайтеÑÑ, що гра поміщена в папку \"Program Files (x86)\"." -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "Інший Ð¿Ñ€Ð¾Ñ†ÐµÑ MTA вже запущений.\n\n" -"Ви хочете завершити цей процеÑ?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Виберіть директорію з Grand Theft Auto: San Andreas" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA потрібні права адмініÑтратора Ð´Ð»Ñ Ð½Ð°Ñтупної задачі:\n\n" +"'%s'\n\n" +"Будь лаÑка, підтвердіть в наÑтупному вікні." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ %s модулÑ! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð²..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¾. Ð’Ñе в порÑдку." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "ЗавершеннÑ..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Готово!" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Ðова верÑÑ–Ñ ÐºÐ»Ñ–Ñ”Ð½Ñ‚Ð° %s виÑвлена.\n\n" +"Ви хочете Ñкопіювати ваші Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð· %s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA не зміг відкрити файл '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA не знайшов файл '%s'" + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA не зміг завантажити модель." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Якщо ви недавно модифікували gta3.img, Ñпробуйте переінÑталювати GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA не зміг додати апґрейд транÑпортному заÑобу." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA знайшов помилки в файлі '%s" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Ваш комп'ютер перезавантаживÑÑ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ Ð³Ñ€Ð¸ в MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Завершіть наÑтупні програми Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "ВиÑвлено недійÑний шлÑÑ… до модулÑ." + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Помилка верÑій файлів. ПереінÑталюйте MTA:SA Ð´Ð»Ñ Ð²Ð¸Ñ€Ñ–ÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¸.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "ДеÑкі файли пошкоджені. ПереінÑталюйте MTA щоб уникнути проблеми.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA не працює в 'Безпечному режимі'.\n\n" +"ПерезапуÑтіть ваш комп'ютер.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "У Ð²Ð°Ñ Ñ” проблеми з запуÑком MTA:SA?.\n\n" "Спробувати повернутиÑÑ Ð´Ð¾ попередньої верÑÑ–Ñ—?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -89,48 +143,48 @@ msgstr "Виникли проблеми з запуÑком MTA:SA. \n" "Ð¡ÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½ÑŒ GTA, цілком можливо, уÑуне цю проблему.\n\n" "Ви хочете Ñкинути Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ GTA?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ GTA Ñкинуті.\n\n" "ÐатиÑніть OK, щоб продовжити." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Файл не може бути видалений. '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Виникли проблеми з запуÑком MTA:SA? .\n\n" "Хочете побачити онлайн-довідку?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "У Ð²Ð°Ñ Ð²Ð¸Ð½Ð¸ÐºÐ»Ð¸ труднощі під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ MTA:SA?\n\n" "Ви хочете змінити поточні налаштуваннÑ?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Повноекранний режим:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Вікно в рамці" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "У Ð²Ð°Ñ Ð²Ð¸Ð½Ð¸ÐºÐ»Ð¸ проблеми з запуÑком MTA:SA?\n\n" "Спробуйте вимкнути наÑтупні продукти Ð´Ð»Ñ MTA та GTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -138,132 +192,287 @@ msgstr "УВÐГÐ\n\n" "MTA:SA виÑвив підозрілу активніÑть.\n" "Перевірте вашу ÑиÑтему на наÑвніÑть віруÑів, щоб переконатиÑÑ Ð² безпеці.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "Був виÑвлений файл: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Ðеобхідно завершити Ð¿Ñ€Ð¾Ñ†ÐµÑ GTA: San Andreas перед запуÑком MTA:SA. Зробити це зараз?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "ІнформаціÑ" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Ðе вдаєтьÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ñ‚Ð¸ Ð¿Ñ€Ð¾Ñ†ÐµÑ GTA: San Andreas. Якщо проблема збереглаÑÑ, то Ñпробуйте перезавантажити ваш комп'ютер." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Проблема перезапуÑку MTA:SA\n\n" +"Якщо проблема збереглаÑÑ, то відкрийте диÑпетчер завдань Ñ– зупиніть процеÑи 'gta_sa.exe' Ñ– 'Multi Theft Auto.exe' \n\n\n" +"Спробувати запуÑтити MTA:SA знову?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Помилка" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "Інший Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð· MTA вже запущений.\n\n" +"Якщо проблема не вирішена, Ñпробуйте перезавантажити комп'ютер" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "Інший Ð¿Ñ€Ð¾Ñ†ÐµÑ MTA вже запущений.\n\n" +"Ви хочете завершити цей процеÑ?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "ВідÑутні необхідні запиÑи в реєÑтрі. ПереінÑталюйте Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "ШлÑÑ… до теки з вашим GTA: San Andreas має непідтримувані Ñимволи (юнікод). Змінити шлÑÑ… до Grand Theft Auto: San Andreas, щоб в ньому були тільки ASCII Ñимволи Ñ– переінÑталюйте Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "ШлÑÑ… в теку MTA:SA або GTA: San Andreas\n" -"має Ñимвол ';' (крапку з комою).\n\n" -"ПереінÑталюйте MTA:SA и GTA: San Andreas, так, щоб в \n" -"шлÑху до тек не було крапки з комою." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Помилка запуÑку, перевірте правильніÑть інÑÑ‚Ð°Ð»ÑŽÐ²Ð°Ð½Ð½Ñ Ð¾Ñтанніх data-файлів." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ðµ вдалаÑÑ. ВпевнітьÑÑ, що %s вÑтановлено правильно." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸, оÑкільки gta_sa.exe не був знайдений в %s" -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ðµ вдалаÑÑ. Видаліть файл %s в теці GTA перед запуÑком." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "ОÑновний файл має неправильне ім'Ñ (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "ОÑновний файл не підпиÑаний. Можлива віруÑна загроза.\n\n" -"ВикориÑтовуйте онлайн-довідку, Ñкщо MTA працює неправильно" - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "ВідÑутній файл даних %s. Можлива віруÑна активніÑть.\n\n" -"РозглÑньте можливіÑть переÑтановки Multi Theft Auto Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ñ— безпеки.\n" -"ЗвернітьÑÑ Ð´Ð¾ онлайн-довідці, Ñкщо MTA працює некоректно." - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "Файл даних %s модифіковано. Можлива активніÑть віруÑу.\n\n" -"Подумайте про перевÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Multi Theft Auto Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ñ— безпеки.\n" -"Якщо MTA працює неправильно, звернітьÑÑ Ð´Ð¾ довідки в мережі." - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "Файли з розширеннÑм .asi інÑтальовано в теку з GTA San Andreas або MTA SA.\n\n" -"Видаліть файли з розширеннÑм .asi щоб уникнути проблем з MTA SA." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Помилка верÑій файлів. ПереінÑталюйте MTA:SA Ð´Ð»Ñ Ð²Ð¸Ñ€Ñ–ÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¸.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "ДеÑкі файли пошкоджені. ПереінÑталюйте MTA щоб уникнути проблеми.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA не працює в 'Безпечному режимі'.\n\n" -"ПерезапуÑтіть ваш комп'ютер.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "Виправте проблему конфігурації" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Виправте помилку необхідної виÑоти" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "Ðевідомо" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "" + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "ІнÑталÑÑ†Ñ–Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Ð’Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð²..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA не може виконати наÑтупну задачу:\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Виліт був викликаний помилкою графічного драйвера **\n\n" +"** Оновіть драйвера вашої відеокарти **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "ІнÑталÑÑ†Ñ–Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ… MTA:SA файлів" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Ðеможливо оновитиÑÑ, так Ñк файли зайнÑті іншими додатками, закрийте Ñ—Ñ… Ñ– Ñпробуйте знову" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto інÑтальовано неправильно, переінÑталюйте. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÑ…Ñ€ÐµÑть GTA:SA" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA не вдаєтьÑÑ Ð·Ð°Ð¿ÑƒÑтити з-за збою ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA: SA не вдаєтьÑÑ Ð·Ð°Ð¿ÑƒÑтити, тому що MTA: У файлі вказана неправильно або відÑутнÑ:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "Копіювати файли MTA:SA" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA: SA не вдаєтьÑÑ Ð·Ð°Ð¿ÑƒÑтити, тому що файл GTA: SA неправильний або відÑутній:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "Латка залежноÑті GTA: SA" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA: SA не вдаєтьÑÑ Ð·Ð°Ð¿ÑƒÑтити, тому що виконуваний файл GTA: SA неправильний або відÑутній:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "Будь лаÑка, перевірте ваш Ð°Ð½Ñ‚Ð¸Ð²Ñ–Ñ€ÑƒÑ Ð½Ð° ложноположительное виÑвленнÑ, Ñпробуйте додати винÑток Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ð½ÑƒÐ²Ð°Ð½Ð¾Ð³Ð¾ файлу GTA: SA Ñ– перезавантажте MTA: SA." + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "Згенерувати GTA: SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA: SA не може запуÑтитиÑÑ, тому що виконуваний файл GTA: SA недоÑтупний Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "Латка GTA: SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA: SA не може запуÑтитиÑÑ, тому що не вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ GTA: SA:" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити Grand Theft Auto: San Andreas. Спробуйте перезапуÑтити. Якщо проблема не вирішена, то звернітьÑÑ Ð·Ð° допомогою на Ñайті www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "Ð”Ð»Ñ Ñ–Ð½ÑталÑції MTA:SA бракує вільного міÑÑ†Ñ Ð½Ð° диÑку %s." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "Ðе знайдено файл:" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "ÐŸÑ€Ð¾Ñ†ÐµÑ GTA: San Andreas не може бути запущений правильно. Ви хочете завершити його?" +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "ПереінÑталюйте GTA:SA, Ñкщо MTA не запуÑкаєтьÑÑ" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½ÑŒ інÑталювань" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Оновити Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑуміÑноÑті" #. ///////////////////////////////////////////////////////////////////////// #. @@ -271,167 +480,167 @@ msgstr "ÐŸÑ€Ð¾Ñ†ÐµÑ GTA: San Andreas не може бути запущений #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Так" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "ÐÑ–" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "ОК" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Вийти" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Допомога" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Відміна" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas виÑвив помилку" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ аварійне Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¸" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "УÑтановіть прапорець, щоб надÑилати інформацію розробникам через Інтернет про Ð¿Ð°Ð´Ñ–Ð½Ð½Ñ MTA." -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Це підвищить шанÑи на уÑÑƒÐ½ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¾Ñ— помилки" -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Ви хочете перезапуÑтити MTA: San Andreas ?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - ПопередженнÑ" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "Ваш каталог вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Grand Theft Auto: San Andreas міÑтить такі файли:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "Ці файли не Ñ” обов’Ñзковими та можуть заважати графічним функціÑм у цій верÑÑ–Ñ— MTA:SA.\n\n" "РекомендуєтьÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ або перейменувати ці файли." -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "Зберегти ці файли, але також показувати це Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ Ð½Ð°Ñтупного запуÑку" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "Більше не нагадувати мені про ці файли" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "Перейменувати ці файли з *.dll на *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "Показати мені ці файли" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "Грати в MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Збиті налаштуваннÑ" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "ВиÑвлено NVidia Optimus!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Спробуйте кожну опцію Ñ– подивітьÑÑ, що працює:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - Стандартний NVidia" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - Ðльтернативна NVidia" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C — Стандартний Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D — Ðльтернативний Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Якщо ви зневірилиÑÑ, то це може допомогти: " -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "Якщо ви вже вибрали варіант, Ñкий працює, це може допомогти:" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "ПримуÑовий віконний режим" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "Більше не показувати" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Увага: Я не можу знайти антивіруÑ" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -439,1105 +648,1183 @@ msgstr "MTA не може виÑвити Ð°Ð½Ñ‚Ð¸Ð²Ñ–Ñ€ÑƒÑ Ð½Ð° вашому П "ВіруÑи можуть втручатиÑÑ Ð² роботу MTA Ñ– пÑувати вам гру.\n\n" "ÐатиÑніть 'Допомога' Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾ÐºÐ»Ð°Ð´Ð½Ñ–ÑˆÐ¾Ñ— інформації." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Я вже інÑталював антивіруÑ" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Я не буду інÑталювати антивіруÑ.\n" "Я готовий до ризику Ñтати чаÑтиною ботнету та лагів." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "Збій ÑтавÑÑ Ñ‡ÐµÑ€ÐµÐ· надмірне викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼â€™Ñті Ñерверами.\n\n" +"Ðавіть Ñкщо у Ð²Ð°Ñ Ð±Ð°Ð³Ð°Ñ‚Ð¾ оперативної пам’Ñті, Ñ†Ñ Ð³Ñ€Ð° x86 з обмеженнÑм адреÑного проÑтору до 3.6 ГБ, деÑкі Ñильно неоптимізовані Ñервери з великою кількіÑтю модів (або навіть кількома погано напиÑаними Ñкриптами) можуть Ñпричинити таку проблему, а також викликати лаги в грі.\n\n" +"ЗвернітьÑÑ Ð´Ð¾ влаÑника Ñервера або до підтримки MTA в офіційному Discord (https://discord.gg/mtasa) Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ñ— інформації." + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Пошук Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "ЗапуÑтіть Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "ІнÑталÑÑ†Ñ–Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ..." - -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Ð’Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð²..." - -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð²..." - -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¾. Ð’Ñе в порÑдку." - -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "ЗавершеннÑ..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ з'єднаннÑ. Хибне ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача!" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Готово!" +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Ðе вдалоÑÑ Ð¿Ñ–Ð´'єднатиÑÑ. ÐеприпуÑтима адреÑа Ñерверу!" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 +#: Client/core/CConnectManager.cpp:132 #, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA потрібні права адмініÑтратора Ð´Ð»Ñ Ð½Ð°Ñтупної задачі:\n\n" -"'%s'\n\n" -"Будь лаÑка, підтвердіть в наÑтупному вікні." +msgid "Connecting to %s at port %u failed!" +msgstr "Під'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð½Ð° %s з портом %u не вдалоÑÑ!" -#: Client/loader/CInstallManager.cpp:376 +#. Display the status box +#: Client/core/CConnectManager.cpp:153 #, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA не може виконати наÑтупну задачу:\n\n" -" '%s'\n" - -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Виліт був викликаний помилкою графічного драйвера **\n\n" -"** Оновіть драйвера вашої відеокарти **" - -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "ІнÑталÑÑ†Ñ–Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ… MTA:SA файлів" - -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Ðеможливо оновитиÑÑ, так Ñк файли зайнÑті іншими додатками, закрийте Ñ—Ñ… Ñ– Ñпробуйте знову" +msgid "Connecting to %s:%u ..." +msgstr "Під'єднатиÑÑ Ð´Ð¾ %s:%u ..." -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:155 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto інÑтальовано неправильно, переінÑталюйте. %s" - -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÑ…Ñ€ÐµÑть GTA:SA" - -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA не вдаєтьÑÑ Ð·Ð°Ð¿ÑƒÑтити з-за збою ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ:" - -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA: SA не вдаєтьÑÑ Ð·Ð°Ð¿ÑƒÑтити, тому що MTA: У файлі вказана неправильно або відÑутнÑ:" +msgid "Reconnecting to %s:%u ..." +msgstr "Повторне Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ %s:%u ..." -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "Копіювати файли MTA:SA" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "ПІД'ЄДÐÐÐÐЯ" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA: SA не вдаєтьÑÑ Ð·Ð°Ð¿ÑƒÑтити, тому що файл GTA: SA неправильний або відÑутній:" +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Ð§Ð°Ñ Ð¿Ñ–Ð´'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð¼Ð¸Ð½ÑƒÐ²" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "Латка залежноÑті GTA: SA" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Від'єднано: невідома помилка протоколу" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA: SA не вдаєтьÑÑ Ð·Ð°Ð¿ÑƒÑтити, тому що виконуваний файл GTA: SA неправильний або відÑутній:" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Від'єднано: віддалене від'єднаннÑ" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "Будь лаÑка, перевірте ваш Ð°Ð½Ñ‚Ð¸Ð²Ñ–Ñ€ÑƒÑ Ð½Ð° ложноположительное виÑвленнÑ, Ñпробуйте додати винÑток Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ð½ÑƒÐ²Ð°Ð½Ð¾Ð³Ð¾ файлу GTA: SA Ñ– перезавантажте MTA: SA." +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Від'єднано: втрачено віддалене з'єднаннÑ" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "Згенерувати GTA: SA" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Від'єднано: ви забанені на цьому Ñервері" -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA: SA не може запуÑтитиÑÑ, тому що виконуваний файл GTA: SA недоÑтупний Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ:" +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Від'єднано: від'єднаний від Ñервера" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "Латка GTA: SA" +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Від'єднано: зв'Ñзок з Ñервером було втрачено" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA: SA не може запуÑтитиÑÑ, тому що не вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ GTA: SA:" +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Від'єднано: з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð±ÑƒÐ»Ð¾ Ñкинуто" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "Ð”Ð»Ñ Ñ–Ð½ÑталÑції MTA:SA бракує вільного міÑÑ†Ñ Ð½Ð° диÑку %s." +msgid "No such mod installed (%s)" +msgstr "Ðе вÑтановлений модуль (%s)" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "Ðе знайдено файл:" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Хибна відповідь Ñервера (2)" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "ПереінÑталюйте GTA:SA, Ñкщо MTA не запуÑкаєтьÑÑ" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Хибна відповідь Ñервера (1)" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½ÑŒ інÑталювань" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "УкраїнÑька" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Оновити Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑуміÑноÑті" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "ЗайнÑто" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "Ðевідомо" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Ðеможливо перевірити Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð² даний момент" -#: Client/loader/Install.cpp:272 +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 #, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "" +msgid "MTA:SA %s required" +msgstr "Потрібно MTA:SA %s" -#: Client/loader/Install.cpp:479 +#: Client/core/CVersionUpdater.cpp:1631 #, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "" +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Потрібно Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ð¾ MTA:SA %s, щоб під'єднатиÑÑ Ð´Ð¾ вибраного Ñервера.\n\n" +"Ви хочете завантажити та інÑталювати MTA:SA %s?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "ЗапуÑтіть Grand Theft Auto: San Andreas.\n" -"ПереконайтеÑÑ, що гра знаходитьÑÑ Ð² папці \"Program Files (x86)\"." +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Ви впевнені, що хочете запуÑтити MTA:SA %s Ñ– під'єднатиÑÑ Ð´Ð¾ цього Ñервера?" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "У пошуках GTA: San Andreas" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Ðе вдаєтьÑÑ Ð·Ð°Ñ€Ð°Ð· під'єднатиÑÑ.\n\n" +"Повторіть Ñпробу пізніше." -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "Вибачте, гра не знайдена.\n" -"ЗапуÑтіть Grand Theft Auto: San Andreas Ñ– натиÑніть \"Повторити\".\n" -"ПереконайтеÑÑ, що гра поміщена в папку \"Program Files (x86)\"." +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Під'єднаннÑ" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Виберіть директорію з Grand Theft Auto: San Andreas" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Будь лаÑка, зачекайте..." -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ %s модулÑ! (%s)" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "ПЕРЕВІРКÐ" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Ðова верÑÑ–Ñ ÐºÐ»Ñ–Ñ”Ð½Ñ‚Ð° %s виÑвлена.\n\n" -"Ви хочете Ñкопіювати ваші Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð· %s ?" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "ПЕРЕВІРКРОÐОВЛЕÐЬ" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA не зміг відкрити файл '%s'" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Ð’ оновленні немає необхідноÑті" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA не знайшов файл '%s'" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "ЗÐÐ’ÐÐТÐЖЕÐÐЯ" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA не зміг завантажити модель." +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "очікуваннÑ..." -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Якщо ви недавно модифікували gta3.img, Ñпробуйте переінÑталювати GTA:SA." +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "ОБОВ'ЯЗКОВЕ ОÐОВЛЕÐÐЯ" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA не зміг додати апґрейд транÑпортному заÑобу." +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Щоб увійти на Ñервер, ви повинні оновити MTA.\n\n" +" Оновити зараз?" -#: Client/loader/Utils.cpp:1631 -#, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA знайшов помилки в файлі '%s" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "ДОДÐТКОВІ ОÐОВЛЕÐÐЯ" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Ваш комп'ютер перезавантаживÑÑ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ Ð³Ñ€Ð¸ в MTA:SA?" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Сервер пропонує оновити клієнт, але це не обов'Ñзково.\n\n" +"Ви хочете оновити?" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Завершіть наÑтупні програми Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ:" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð² цей момент недоÑтупне.\n\n" +"Будь лаÑка, перевірте www.multitheftauto.com" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Запит до Ñайту" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "ПОМИЛКРЗБЕРЕЖЕÐÐЯ" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Сервер робить запити до наÑтупних Ñайтів, Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾ щоб завантажити Ñ—Ñ… пізніше:" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Ðе вдаєтьÑÑ Ñтворити файл." -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "ÐІКОЛИ ÐЕ ВВОДЬТЕ КОÐФІДЕÐЦІЙÐІ ДÐÐІ, ЩОБ ЗÐХИСТИТИ ЇХ ВІД КРÐДІЖКИ" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "ПОМИЛКРЗÐÐ’ÐÐТÐЖЕÐÐЯ" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Запам'Ñтати рішеннÑ" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "Завантажений файл Ñ” хибним." -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Дозволити" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "З деÑких причин." -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "ЗапереченнÑ" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "ЗÐÐ’ÐÐТÐЖЕÐÐЯ ЗÐВЕРШЕÐО" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "Головне меню" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Ðевідома проблема в _DialogUpdateResult" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Ви викориÑтовуєте функціональну Ñтруктуру! Це лише теÑтова побудова, Ñка не може бути викориÑтана Ð´Ð»Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ загальнодоÑтупних Ñерверів!" +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "МОДИФІКОВÐÐІ ФÐЙЛИ GTA:SA" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA не отримуватиме оновлень Ð´Ð»Ñ XP/Vista піÑÐ»Ñ Ð»Ð¸Ð¿Ð½Ñ 2019 року.\n\n" -"Оновіть Windows, щоб грати на найновіших Ñерверах." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "Ок" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Ð¦Ñ Ð´Ñ–Ñ Ð¿Ñ€Ð¸Ð·Ð²ÐµÐ´Ðµ до від'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð²Ñ–Ð´ поточного Ñервера.\n\n" -"Ви дійÑно бажаєте від'єднатиÑÑ?" +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "ПОМИЛКÐ" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "ПОПЕРЕДЖЕÐÐЯ ВІД'ЄДÐÐÐÐЯ" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "ДеÑкі MTA:SA файли відÑутні.\n\n\n" +"ПереінÑталюйте MTA:SA." -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "ІÐФОРМÐЦIЯ" +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "Завантажено %3d %%" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "УкраїнÑька" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +" ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ñ– - %-3d" + +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ ДОПОМОГРПО КОМÐÐДÐМ ]***\n" + +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* ЧаÑ: %d:%02d:%02d" + +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "підключеннÑ: Мережа не готова, будь лаÑка, почекайте хвилинку" + +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "під'єднатиÑÑ: ВикориÑтовуйте 'connect <адреÑа> [<порт> <нік> <пароль>]'" + +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "під'єднаннÑ: Ðевірний номер порту" + +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "під'єднаннÑ: Під'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ %s:%u..." + +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "під'єднаннÑ: не вдалоÑÑ Ð¿Ñ–Ð´'єднатиÑÑ Ð´Ð¾ %s:%u!" + +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "під'єднаннÑ: Ðе вдалоÑÑ Ð²Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ поточний мод" + +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "повторне підключеннÑ: Мережа не готова, будь лаÑка, почекайте хвилинку" + +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "повторне підключеннÑ: Ðеправильний номер порту" + +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "перепідключеннÑ: ÐŸÐµÑ€ÐµÐ¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ %s:%u..." + +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "повторне підключеннÑ: не вдалоÑÑ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡Ð¸Ñ‚Ð¸ÑÑ Ð´Ð¾ %s:%u !" + +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Скопіювати ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ð· GTA" + +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Файл конфігурації збережений" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Ваш Ñерійний номер: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "ÐÐЛÐШТУВÐÐÐЯ" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Мультиплеєр" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Графіка" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Звук" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Клавіші" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "УправліннÑ" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "ІнтерфейÑ" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Браузер" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Додаткові" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Відновити Ñтандартні" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "ЧутливіÑть миші:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Вертикальна чутливіÑть прицілу:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ð¸ÑˆÑ–" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "ІнверÑÑ–Ñ Ð¼Ð¸ÑˆÑ– по вертикалі" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Ð£Ð¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ñ‚Ñ€Ð°Ð½Ñпортом з миші" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Ð£Ð¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ð¿Ð¾Ð»ÑŒÐ¾Ñ‚Ð¾Ð¼ з миші" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¶Ð¾Ð¹Ñтика" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Стандартне ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ (Миша + Клавіатура)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "КлаÑичне ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ (ДжойÑтик)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Мертва зона" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "ÐаÑиченіÑть" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Перейдіть в вкладку 'Клавіші' Ð´Ð»Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¶Ð¾Ð¹Ñтика" -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Лівий Ñтик" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Правий Ñтик" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "ОПИС" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "КЛÐВІШÐ" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ДОД. КЛÐВІШÐ" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Ðікнейм:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Зберігати паролі Ñерверів" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Ðвтоматичне Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÑпиÑку Ñерверів" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Дозволити Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÑ–Ð²" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Дозволити зовнішні звуки" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Завжди показувати вікно завантаженнÑ" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "Дозвольте з'єднатиÑÑ Ð· Багатим ПриÑутніÑтю Discord" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "Зберігайте фотографії, зроблені камерою weapon, в папку кориÑтувача файлів GTA San Andreas" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "Запитайте перед відключеннÑм від Ñервера, викориÑтовуючи головне меню" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "ВикориÑтовувати модифіковані файли GTA:SA" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Параметри Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ ÐºÐ°Ñ€Ñ‚Ð¸" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "ÐепрозоріÑть:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "Дозвіл зображеннÑ:" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "1024 x 1024 (Әдепкі)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Загальна гучніÑть:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "ГучніÑть радіо:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Загальна гучніÑть:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "ГучніÑть MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "ГучніÑть мовленнÑ:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Режим відтвореннÑ:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Загальні" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Параметри радіо" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Еквалайзер радіо" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "ÐÐ²Ñ‚Ð¾Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ€Ð°Ð´Ñ–Ð¾" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувацької музики" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Радіо" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Випадково" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "ПоÑлідовно" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Ðвтопошук музики" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Параметри Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ð½Ñ Ð·Ð²ÑƒÐºÑƒ" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Вимкнути вÑÑ– звуки при згортанні гри" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Заглушити радіо, коли гра згорнута" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Заглушити звуки ефектів, коли гра згорнута" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Заглушити звуки MTA, коли гра згорнута" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Заглушити голоÑовий чат, коли гра згорнута" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Дозвіл:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Кут оглÑду:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "ДальніÑть промальовуваннÑ:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "ЯÑкравіÑть:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "ЯкіÑть ефектів:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Ðнізотропна фільтраціÑ:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Екранне згладжуваннÑ:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Ð¡Ð¿Ñ–Ð²Ð²Ñ–Ð´Ð½Ð¾ÑˆÐµÐ½Ð½Ñ Ñторін:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Віконний режим" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI aware" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Стандарт" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Вікно без рамки" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "ДеталізаціÑ" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Ðизьке" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Середнє" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "ВиÑоке" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Дуже виÑоке" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Відключена" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Ðвто" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "Розмір HUD під ÑпіввідношеннÑ" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Динамічні тіні" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Покращена трава" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Ефект Ñпеки" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Дим шин, тощо" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "Динамічні тіні перÑонажів" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "Ð Ð¾Ð·Ð¼Ð¸Ñ‚Ñ‚Ñ Ð² руÑÑ–" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "Ð’Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¾Ð½Ð½Ð¾Ð³Ð¾ дощу" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Повноекранний режим (згорнути)" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Увімкнути діалог вибору приÑтрою" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Показати не підтримну роздільніÑть" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Завжди показувати транÑпорт у виÑокій деталізації" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Завжди показувати перÑонажів у виÑокій деталізації" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "ЗаÑтоÑовувати Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð² повноекранному режимі" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Дозволити Ñторонні веб-Ñайти" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Дозволити Javascript на Ñторонніх веб-Ñайтах" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "Включити візуалізацію графічного процеÑора" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Чорний ÑпиÑок" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Введіть домен, наприклад google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Блокувати" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "ÐдреÑа" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Видалити адреÑу" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Дозволений ÑпиÑок" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Дозволити" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Різне" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Швидке Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð¾Ð´Ñгу CJ:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "ШвидкіÑть Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÑпиÑку Ñерверів:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Одиночне під'єднаннÑ:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "Теґ пакета:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "ÐÐ½Ñ–Ð¼Ð°Ñ†Ñ–Ñ Ñ–Ð½Ð´Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð° завантаженнÑ:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "Пріоритет процеÑу" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "ÐаÑÑ‚Ñ€Ð¾ÑŽÐ²Ð°Ð½Ð½Ñ Ð½Ð°Ð»Ð°Ð³Ð¾Ð´Ð¶ÑƒÐ²Ð°Ñ‡Ð°:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Відеопам'Ñть:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Тип оновленнÑ:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "ІнÑталювати важливі оновленнÑ:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Увімкнути" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Дуже повільно" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "За промовчаннÑм" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Швидко" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Середнє" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Вище норми" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Мін." -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "МакÑ." #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "СуміÑний з Windows 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16-бітові кольори" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Ð’Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð¼Ð¸ÑˆÑ–" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "ШлÑÑ… Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ€ÐµÑурÑів:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Відкрити теку" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "Ð’Ñтановіть прив'Ñзку процеÑора до 0, щоб підвищити продуктивніÑть гри" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Ðвтоматичне оновленнÑ" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Перевірити наÑвніÑть оновлень" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð¼Ñ–Ð½ÑтьÑÑ Ð¿Ñ€Ð¸ наÑтупному Ñтарті MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Ви хочете перезапуÑтити?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "ÐЕОБХІДÐИЙ ПЕРЕЗÐПУСК" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "ДеÑкі Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð¼Ñ–Ð½ÑтьÑÑ Ð¿Ñ–ÑÐ»Ñ Ð²Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð²Ñ–Ð´ цього Ñервера" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Ви хочете від'єднатиÑÑ?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "ÐЕОБХІДÐО ВІД'ЄДÐÐТИСЯ" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Ðе знайдено джойÑтик. Перевірте, чи під'єднаний він та перезавантажте гру" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ñей" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Переміщайте джойÑтик Ð´Ð»Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ escape Ð´Ð»Ñ Ð¾Ñ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Мова:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Тема:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "ПередвÑтановленнÑ:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Чат" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Завантажити" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Кольори" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Макет чату" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Параметри" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Тло чату" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "ТекÑÑ‚ чату" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Тло Ñ€Ñдка чату" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Колір Ñ€Ñдка введеннÑ" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "РÑдки:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "МаÑштаб:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Ширина:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Величина" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "піÑлÑ" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "за" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "Ñек" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "ЗгаÑаннÑ" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "ЗгаÑÐ°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Горизонтально:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Вертикально:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Ð’Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ Ñ‚ÐµÐºÑту:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "Ð—Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¿Ð¾ X:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Ð—Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¿Ð¾ X:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "ПозиціÑ" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Ліворуч" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Центр" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Праворуч" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Верх" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Ðиз" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Шрифт" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Відображати тло тільки при введенні" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Ð’ÑтавлÑти нікнейм по кнопці \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Дозволити Ñерверу кліпати вікном додатка" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Показувати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð² облаÑті повідомлень" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Чорно-білий контур текÑту чату" @@ -1545,89 +1832,95 @@ msgstr "Чорно-білий контур текÑту чату" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "ÐатиÑніть клавішу Ð´Ð»Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ escape Ð´Ð»Ñ Ð¾Ñ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ñновної клавіші" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ñ— клавіші" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "УПРÐВЛІÐÐЯ GTA" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "УПРÐВЛІÐÐЯ МУЛЬТИПЛЕЄРУ" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Ваш нікнейм міÑтить неприпуÑтимі Ñимволи." -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "Головне меню" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "У грі" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Червоний:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Зелений:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Синій:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "ПрозоріÑть:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Колір" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "ПереглÑд" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Будь лаÑка, від'єднайтеÑÑ, перш ніж змінити мову" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Будь лаÑка, від'єднайтеÑÑ Ð¿ÐµÑ€Ñˆ ніж змінити тему" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Динамічні тіні можуть призвеÑти до Ð·Ð½Ð¸Ð¶ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ‚Ð¸Ð²Ð½Ð¾Ñті.\n\n" "Ви впевнені, що хочете активувати Ñ—Ñ…?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "ПОПЕРЕДЖЕÐÐЯ ПРОДУКТИВÐОСТІ" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÑ–Ð² вимагаєтьÑÑ Ð±Ð°Ð³Ð°Ñ‚ÑŒÐ¼Ð° Ñерверами Ð´Ð»Ñ Ð°Ð½Ñ‚Ð¸Ñ‡Ð¸Ñ‚ ÑиÑтеми.\n\n" "(ОблаÑть чату Ñ– елементи інтерфейÑу будуть приховані)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "ІÐФОРМÐЦІЯ ПРО ЗÐÐ’ÐÐТÐЖЕÐÐЯ ЗÐІМКІВ" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1635,23 +1928,21 @@ msgstr "ДеÑкі Ñкрипти можуть відтворювати звук "Ð’Ð¸Ð¼Ð¸ÐºÐ°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ параметру може привеÑти до Ð·Ð½Ð¸Ð¶ÐµÐ½Ð½Ñ ÐµÐ½ÐµÑ€Ð³Ð¾ÑÐ¿Ð¾Ð¶Ð¸Ð²Ð°Ð½Ð½Ñ Ð¼ÐµÑ€ÐµÐ¶Ñ– \n" "ÑÐ¿Ð¾Ð¶Ð¸Ð²Ð°Ð½Ð½Ñ Ñмуги пропуÑканнÑ." -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "ЗОВÐІШÐІ ЗВУКИ" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "Схоже, що у Ð²Ð°Ñ ÑƒÐ²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð¾ параметри Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Rich Presence.\n" -"Бажаєте дозволити Ñерверам обмінюватиÑÑ Ð´Ð°Ð½Ð¸Ð¼Ð¸?\n\n" -"Це включає ваш унікальний ідентифікатор ID." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "ЗГОДРÐРПЕРЕДÐЧУ ДÐÐИХ" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1661,11 +1952,7 @@ msgstr "ДеÑкі файли в директорії GTA:SA змінені.\n" "Проте, модифіковані файли блокуютьÑÑ Ð±Ñ–Ð»ÑŒÑˆÑ–Ñтю Ñерверами\n\n" "Ви дійÑно хочете викориÑтати Ñ—Ñ…?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "МОДИФІКОВÐÐІ ФÐЙЛИ GTA:SA" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1675,552 +1962,253 @@ msgstr "Ð£Ð²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð½Ñ ÑƒÑвідомлене, DPI Ñ” екÑперимен "Якщо ввімкнути цю опцію, у Ð²Ð°Ñ Ð¼Ð¾Ð¶ÑƒÑ‚ÑŒ виникнути проблеми з графікою.\n\n" "Ви впевнені, що бажаєте ввімкнути цю опцію?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "ЕКСПЕРИМЕÐТÐЛЬÐРФУÐКЦІЯ" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "Відключати цю опцію не рекомендуєтьÑÑ, Ñкщо у Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” проблем з продуктивніÑтю.\n\n" "Ви впевнені, що хочете вимкнути?" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Введіть нікнейм" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Введіть нікнейм, Ñкий буде викориÑтаний в грі \n" "Це буде ваше ім'Ñ, при підключенні до Ñервера" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "(Дуже екÑпериментальна функціÑ)" -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "ÐžÐ¿Ñ‚Ð¸Ð¼Ñ–Ð·Ð°Ñ†Ñ–Ñ Ð·Ð¼Ñ–Ð½Ð¸ одÑгу CJ (Потрібні дод. 65Мб RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Старі маршрутизатори будуть краще працювати з повільною швидкіÑтю ÑкануваннÑ" -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "ВикориÑтовувати одноточне під'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¸ завантаженні файлів." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Позначати мережеві пакети Ð´Ð»Ñ ÑÐ¿Ñ€Ð¾Ñ‰ÐµÐ½Ð½Ñ Ñ–Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ— трафіку MTA" -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "ÐÐ½Ñ–Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ð¾Ð²Ð¾Ñ€Ð¾Ñ‚Ð½Ð¾Ð³Ð¾ круга внизу екрана" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Завжди за промовчаннÑм. (Цей параметр не зберігаєтьÑÑ)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Ðайкраще виділити макÑимальний обÑÑг" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Ðвтоматичне оновленнÑ:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "ВикориÑтовуйте \"За промовчаннÑм\" Ñкщо бажаєте завантажувати тільки Ñтабільні верÑÑ–Ñ—" -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Виберіть Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð° промовчаннÑм Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾Ñ— інÑталÑції важливих оновлень." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16-бітові кольори:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Увімкнути режим 16-бітних кольорів. Потрібен перезапуÑк MTA." -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Ð’Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð¼Ð¸ÑˆÑ–:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Виправити рух миші - Ðеобхідний перезапуÑк ПК" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "Прив'Ñзка до процеÑора CPU:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "МінÑйте тільки в тому випадку, Ñкщо у Ð²Ð°Ñ Ð²Ð¸Ð½Ð¸ÐºÐ»Ð¸ проблеми зі ÑтабільніÑтю." -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Ðевідома команда або змінна: " - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "ЗайнÑто" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Ðеможливо перевірити Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð² даний момент" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "Потрібно MTA:SA %s" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Потрібно Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ð¾ MTA:SA %s, щоб під'єднатиÑÑ Ð´Ð¾ вибраного Ñервера.\n\n" -"Ви хочете завантажити та інÑталювати MTA:SA %s?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Ви впевнені, що хочете запуÑтити MTA:SA %s Ñ– під'єднатиÑÑ Ð´Ð¾ цього Ñервера?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Ðе вдаєтьÑÑ Ð·Ð°Ñ€Ð°Ð· під'єднатиÑÑ.\n\n" -"Повторіть Ñпробу пізніше." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Під'єднаннÑ" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Будь лаÑка, зачекайте..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "ПЕРЕВІРКÐ" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "ПЕРЕВІРКРОÐОВЛЕÐЬ" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Ð’ оновленні немає необхідноÑті" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "ЗÐÐ’ÐÐТÐЖЕÐÐЯ" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "очікуваннÑ..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "ОБОВ'ЯЗКОВЕ ОÐОВЛЕÐÐЯ" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Щоб увійти на Ñервер, ви повинні оновити MTA.\n\n" -" Оновити зараз?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "ДОДÐТКОВІ ОÐОВЛЕÐÐЯ" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Сервер пропонує оновити клієнт, але це не обов'Ñзково.\n\n" -"Ви хочете оновити?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð² цей момент недоÑтупне.\n\n" -"Будь лаÑка, перевірте www.multitheftauto.com" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "ПОМИЛКРЗБЕРЕЖЕÐÐЯ" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Ðе вдаєтьÑÑ Ñтворити файл." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "ПОМИЛКРЗÐÐ’ÐÐТÐЖЕÐÐЯ" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "Завантажений файл Ñ” хибним." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "З деÑких причин." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "ЗÐÐ’ÐÐТÐЖЕÐÐЯ ЗÐВЕРШЕÐО" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Ðевідома проблема в _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "Ок" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "ПОМИЛКÐ" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "ДеÑкі MTA:SA файли відÑутні.\n\n\n" -"ПереінÑталюйте MTA:SA." - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "Завантажено %3d %%" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -" ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ñ– - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ з'єднаннÑ. Хибне ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Ðе вдалоÑÑ Ð¿Ñ–Ð´'єднатиÑÑ. ÐеприпуÑтима адреÑа Ñерверу!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Під'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð½Ð° %s з портом %u не вдалоÑÑ!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Під'єднатиÑÑ Ð´Ð¾ %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "Повторне Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ %s:%u ..." - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "ПІД'ЄДÐÐÐÐЯ" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Ð§Ð°Ñ Ð¿Ñ–Ð´'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð¼Ð¸Ð½ÑƒÐ²" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Від'єднано: невідома помилка протоколу" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Від'єднано: віддалене від'єднаннÑ" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Від'єднано: втрачено віддалене з'єднаннÑ" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Від'єднано: ви забанені на цьому Ñервері" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Від'єднано: від'єднаний від Ñервера" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Від'єднано: зв'Ñзок з Ñервером було втрачено" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Від'єднано: з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð±ÑƒÐ»Ð¾ Ñкинуто" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Ðе вÑтановлений модуль (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Хибна відповідь Ñервера (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Хибна відповідь Ñервера (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "ÐОВИÐИ" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "ПроглÑнути оÑтанню Ñтаттю" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "КОÐСОЛЬ" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Фатальна помилка" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "ЩОБ ВИПРÐВИТИ, ВИЛУЧІТЬ ЦЕЙ ФÐЙЛ:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "Модуль %s хибний!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Помилка Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "Ñ†Ñ Ñторінка допомоги" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "вийти із заÑтоÑунку" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "показати верÑÑ–ÑŽ MTA" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "показати поточний чаÑ" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "показати Ñ–Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð³Ñ€Ð°Ð²Ñ†Ñ" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "показати вÑÑ– Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ»Ð°Ð²Ñ–Ñˆ" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "показати ваш Ñерійний номер" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "під'єднатиÑÑ Ð´Ð¾ Ñервера (адреÑ, порт, нік, пароль)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "під'єднатиÑÑ Ð´Ð¾ оÑтаннього відвіданого Ñервера" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "призначити клавішу управліннÑ" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "видалити задачу з клавіші" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "Ñкопіювати Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð· GTA:SA" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "зробити знімок екрана" -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "зберегти налаштуваннÑ" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "почиÑтити вікно Ð·Ð½ÐµÐ²Ð°Ð´Ð¶ÐµÐ½Ð½Ñ (debug)" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "прокрутити чат вгору" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "прокрутити чат вниз" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "прокрутити вікно Ð·Ð½ÐµÐ²Ð°Ð´Ð¶ÐµÐ½Ð½Ñ Ð²Ð³Ð¾Ñ€Ñƒ" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "прокрутити вікно Ð·Ð½ÐµÐ²Ð°Ð´Ð¶ÐµÐ½Ð½Ñ Ð²Ð½Ð¸Ð·" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "показати ÑтатиÑтику викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "показати графік продуктивноÑті" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "Ð´Ð»Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸ÐºÑ–Ð²: перезавантажити новини" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ ДОПОМОГРПО КОМÐÐДÐМ ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* ЧаÑ: %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "підключеннÑ: Мережа не готова, будь лаÑка, почекайте хвилинку" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "під'єднатиÑÑ: ВикориÑтовуйте 'connect <адреÑа> [<порт> <нік> <пароль>]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "під'єднаннÑ: Ðевірний номер порту" - -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "під'єднаннÑ: Під'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ %s:%u..." - -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "під'єднаннÑ: не вдалоÑÑ Ð¿Ñ–Ð´'єднатиÑÑ Ð´Ð¾ %s:%u!" +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "зберегти налаштуваннÑ" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "під'єднаннÑ: Ðе вдалоÑÑ Ð²Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ поточний мод" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "почиÑтити вікно Ð·Ð½ÐµÐ²Ð°Ð´Ð¶ÐµÐ½Ð½Ñ (debug)" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "повторне підключеннÑ: Мережа не готова, будь лаÑка, почекайте хвилинку" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "прокрутити чат вгору" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "повторне підключеннÑ: Ðеправильний номер порту" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "прокрутити чат вниз" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "перепідключеннÑ: ÐŸÐµÑ€ÐµÐ¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ %s:%u..." +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "прокрутити вікно Ð·Ð½ÐµÐ²Ð°Ð´Ð¶ÐµÐ½Ð½Ñ Ð²Ð³Ð¾Ñ€Ñƒ" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "повторне підключеннÑ: не вдалоÑÑ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡Ð¸Ñ‚Ð¸ÑÑ Ð´Ð¾ %s:%u !" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "прокрутити вікно Ð·Ð½ÐµÐ²Ð°Ð´Ð¶ÐµÐ½Ð½Ñ Ð²Ð½Ð¸Ð·" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Скопіювати ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ð· GTA" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "показати ÑтатиÑтику викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Файл конфігурації збережений" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "показати графік продуктивноÑті" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* Ваш Ñерійний номер: %s" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "Ð´Ð»Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸ÐºÑ–Ð²: перезавантажити новини" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Ð’Ñ–ÑÑŒ приÑкореннÑ" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Ви викориÑтовуєте функціональну Ñтруктуру! Це лише теÑтова побудова, Ñка не може бути викориÑтана Ð´Ð»Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ загальнодоÑтупних Ñерверів!" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Ð’Ñ–ÑÑŒ гальмуваннÑ" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA не отримуватиме оновлень Ð´Ð»Ñ XP/Vista піÑÐ»Ñ Ð»Ð¸Ð¿Ð½Ñ 2019 року.\n\n" +"Оновіть Windows, щоб грати на найновіших Ñерверах." -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "ПрограмуваннÑ" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Ð¦Ñ Ð´Ñ–Ñ Ð¿Ñ€Ð¸Ð·Ð²ÐµÐ´Ðµ до від'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð²Ñ–Ð´ поточного Ñервера.\n\n" +"Ви дійÑно бажаєте від'єднатиÑÑ?" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "УчаÑники" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "ПОПЕРЕДЖЕÐÐЯ ВІД'ЄДÐÐÐÐЯ" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Ігровий дизайн / Скриптинґ" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "ІÐФОРМÐЦIЯ" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Мова" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "ÐОВИÐИ" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Ðвтори виправлень" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "ПроглÑнути оÑтанню Ñтаттю" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "ОÑоблива подÑка" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Розмір знімка %d байт, але очікувалоÑÑ %d " -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "Це програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ñ– проект викориÑтовують наÑтупні бібліотеки та програмне забезпеченнÑ:" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Ðе вдалоÑÑ Ð·Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ знімок екрана" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Бажаєте переглÑнути довідку в мережі щодо цієї проблеми?" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "Знімок зроблено: '%s'" + +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Ðевідома команда або змінна: " #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2395,25 +2383,56 @@ msgid "Group control backwards" msgstr "Спільнота: назад" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Обрана вами графічна тема не може бути завантажена, тема за замовчуваннÑм також не може бути завантажена, перевÑтановіть MTA Ð´Ð»Ñ Ð²Ð¸Ñ€Ñ–ÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¸." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Розмір знімка %d байт, але очікувалоÑÑ %d " +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Бажаєте переглÑнути довідку в мережі щодо цієї проблеми?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Ðе вдалоÑÑ Ð·Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ знімок екрана" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "КОÐСОЛЬ" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Знімок зроблено: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "ПрограмуваннÑ" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "УчаÑники" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Ігровий дизайн / Скриптинґ" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Мова" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Ðвтори виправлень" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "ОÑоблива подÑка" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "Це програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ñ– проект викориÑтовують наÑтупні бібліотеки та програмне забезпеченнÑ:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Ð’Ñ–ÑÑŒ приÑкореннÑ" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Ð’Ñ–ÑÑŒ гальмуваннÑ" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2421,6 +2440,65 @@ msgstr "Ðе вдалоÑÑ Ñ–Ð½Ñ–Ñ†Ñ–Ð°Ð»Ñ–Ð·ÑƒÐ²Ð°Ñ‚Ð¸ Direct3D9.\n\n" "ІнÑталюйте DirectX End-User Runtime\n" "Ñ– найÑвіжішу верÑÑ–ÑŽ Windows Service Packs." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Ðеактивний" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "гравець" +msgstr[1] "гравців" +msgstr[2] "гравців" +msgstr[3] "гравців" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "на" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "Ñервері" +msgstr[1] "Ñерверах" +msgstr[2] "Ñерверах" +msgstr[3] "Ñерверах" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "ÐžÑ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ ÑпиÑку Ñерверів (%lu Ð¼Ñ Ð¿Ñ€Ð¾Ð¹ÑˆÐ»Ð¾)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "МайÑтер-Ñервер не відповідає." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "МайÑтер-Ñервер не може отримати дані." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Резервна ÐºÐ¾Ð¿Ñ–Ñ ÑпиÑку Ñерверів)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Ðе вдалоÑÑ Ð¿Ñ€Ð¸Ð²'Ñзати локальний Ñокет" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Спроба виÑÐ²Ð»ÐµÐ½Ð½Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¸Ñ… Ñерверів" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2474,7 +2552,7 @@ msgstr "Затримка:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "СпиÑок гравців" @@ -2501,40 +2579,39 @@ msgstr "Під'єднатиÑÑ, Ñк звільнитьÑÑ Ð¼Ñ–Ñце." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "ВВЕДІТЬ ПÐРОЛЬ СЕРВЕРÐ:" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Ð§Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ð¹ÑˆÐ¾Ð²" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Йде запит..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "СПИСОК СЕРВЕРІВ" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "Інтернет" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Локальна мережа" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Вподобане" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Ðещодавні" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2542,302 +2619,367 @@ msgstr "ДЛЯ ШВИДКОГО ПІД'ЄДÐÐÐÐЯ:\n\n" "Введіть адреÑу Ñ– порт Ñервера в адреÑному Ñ€Ñдку.\n" "Ðбо виберіть Ñервер з Ñ–Ñторії оÑтанніх та натиÑніть кнопку 'Під'єднатиÑÑ'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "ДОПОМОГÐ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Оновити" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Вподобати" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Під'єднатиÑÑ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "ВідомоÑті про Ñервер" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Пошук по Ñерверам" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Пошук по гравцÑм" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "ЗдійÑнити пошук" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Пошук по гравцÑм..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Пошук по Ñерверам..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Ðазва" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Гравці" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "Пінг" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Ігровий режим" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Показати:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Порожні" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Переповнені" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Запаролені" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "Відключені" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Інші верÑÑ–Ñ—" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Ðазад" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "ЗавантаженнÑ..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..завантаженнÑ.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Ðе вказано адреÑу Ñервера!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Ðевідомий протокол" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Будь лаÑка, викориÑтовуйте протокол mtasa://" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Ðевірний нікнейм! Будь лаÑка, відкрийте Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ– змініть Ñ—Ñ…!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Виберіть Ñервер Ð´Ð»Ñ Ð¿Ñ–Ð´'єднаннÑ." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Ðеактивний" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Проблема з графічним драйвером" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "гравець" -msgstr[1] "гравців" -msgstr[2] "гравців" -msgstr[3] "гравців" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Ðеможливо підібрати відповідну роздільніÑть диÑплеÑ." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "на" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Ви впевнені, що хочете викориÑтовувати цю роздільніÑть диÑплеÑ?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "Ñервері" -msgstr[1] "Ñерверах" -msgstr[2] "Ñерверах" -msgstr[3] "Ñерверах" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "ÐžÑ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ ÑпиÑку Ñерверів (%lu Ð¼Ñ Ð¿Ñ€Ð¾Ð¹ÑˆÐ»Ð¾)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "МайÑтер-Ñервер не відповідає." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Запит до Ñайту" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "МайÑтер-Ñервер не може отримати дані." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Сервер робить запити до наÑтупних Ñайтів, Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾ щоб завантажити Ñ—Ñ… пізніше:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Резервна ÐºÐ¾Ð¿Ñ–Ñ ÑпиÑку Ñерверів)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "ÐІКОЛИ ÐЕ ВВОДЬТЕ КОÐФІДЕÐЦІЙÐІ ДÐÐІ, ЩОБ ЗÐХИСТИТИ ЇХ ВІД КРÐДІЖКИ" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Ðе вдалоÑÑ Ð¿Ñ€Ð¸Ð²'Ñзати локальний Ñокет" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Запам'Ñтати рішеннÑ" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Спроба виÑÐ²Ð»ÐµÐ½Ð½Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¸Ñ… Ñерверів" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "ЗапереченнÑ" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Ð¦Ñ Ð²ÐµÑ€ÑÑ–Ñ Ð·Ð°Ñтаріла." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "від'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð²Ñ–Ð´ гри" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "показувати неймтеґи" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "показати чат" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "Відображати ÑтатиÑтику з'єднаннÑ" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "Відкрити чат" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "Передавати Ð³Ð¾Ð»Ð¾Ñ Ð²Ñім гравцÑм" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "ТранÑпорт: ПаÑажир" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "ÐаÑÑ‚. радіоÑтанціÑ" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "Поп. радіоÑтанціÑ" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" -msgstr "" +msgstr "переÑуває мапу Ð³Ñ€Ð°Ð²Ñ†Ñ Ð½Ð° захід" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð´Ð°Ð½Ð¾Ð¼Ñƒ гравцеві" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "ТранÑпорт: ÐаÑÑ‚. зброÑ" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "ТранÑпорт: Поп. зброÑ" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "Відобразити відомоÑті про Ñервер" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "Ð’Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¼Ð°Ñштабу Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ñ‚ÐµÐºÑту" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Режим розробки) показувати colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Режим розробки) пиÑати ідентифікатори ігрових звуків в вікно налагоджувача" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "СТВОРИТИ СЕРВЕР" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "РеÑурÑи" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Ім'Ñ Ñервера:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Пароль:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "МакÑ. кількіÑть гравців:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "ВидиміÑть в:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "Локальна мережа" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Вибрано" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "УÑе" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "ЗапуÑтити" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "ÐŸÑ€Ð¾Ð³Ñ€ÐµÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÐºÐ°Ñ€Ñ‚Ð¸:" @@ -2858,174 +3000,174 @@ msgstr "%s з %s" msgid "Disconnect to cancel download" msgstr "Від'єднайтеÑÑ, щоб зупинити завантаженнÑ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Від'єднаннÑ: невірний нікнейм." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Від'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð²Ñ–Ð´ Ñервера" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Від'єднаннÑ: Серійний номер заблокований. \n" "Причина: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Від'єднаннÑ: Ви забанені. \n" "Причина: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Від'єднаннÑ: Обліківка заблокована. \n" "Причина: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Від'єднаннÑ: ВерÑÑ–Ñ— не збігаютьÑÑ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Від'єднаннÑ: Флуд підключеннÑми. Зачекайте хвилину перед новою Ñпробою." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Від'єднаннÑ: Сервер іншою верÑією.\n" "ІнформаціÑ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Від'єднаннÑ: Ðевідповідна верÑÑ–Ñ.\n" "ІнформаціÑ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Від'єднаннÑ: Сервер працює на більш новій верÑÑ–Ñ—.\n" "ІнформаціÑ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Від'єднаннÑ: Сервер працює на більш Ñтарій верÑÑ–Ñ—.\n" "ІнформаціÑ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Від'єднаннÑ: Такий нікнейм вже викориÑтовуєтьÑÑ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "Від’єднано: не вдалоÑÑ Ñтворити елемент гравцÑ." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Від'єднаннÑ: Сервер Ñкинув під'єднаннÑ: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Від'єднаннÑ: не вдалаÑÑ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ° Ñерійного ключа." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Від'єднаннÑ: під'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´ÐµÑинхронізовано %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Від'єднаннÑ: %s кікнув ваÑ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Від'єднаннÑ: %s заблокував ваÑ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Від'єднаннÑ: Сервер вимкнений або перезапущений" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Ð’Ð°Ñ ÐºÑ–ÐºÐ½ÑƒÐ»Ñ– з Ñервера" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñервера потрібен немодифікований gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "Будь лаÑка, замініть gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "Цей Ñервер не дозволÑÑ” кориÑтувацькі файли D3D9.DLL" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "Видаліть D3D9.DLL з теки вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ GTA та перезапуÑтіть MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "Цей Ñервер не підтримує віртуальні машини" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñервера потрібно ввімкнути Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð°" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "Перезавантажте ПК" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "Ðа цьому Ñервері виÑвлено відÑутніÑть компонентів захиÑту від читів" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "Спробуйте перезапуÑтити MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñервера потрібні немодифіковані gta3.img та gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "Замініть gta3.img або gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "Цей Ñервер не дозволÑÑ” викориÑтовувати Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "ПереконайтеÑÑ, що жодна інша програма не змінює MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "ЗалишилоÑÑ Ñ‡Ð°Ñу: " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" @@ -3034,7 +3176,7 @@ msgstr[1] "%d днÑ" msgstr[2] "%d днів" msgstr[3] "%d днів" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" @@ -3043,7 +3185,7 @@ msgstr[1] "%d годин" msgstr[2] "%d години" msgstr[3] "%d годин" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" @@ -3052,7 +3194,7 @@ msgstr[1] "%d хвилин" msgstr[2] "%d хвилини" msgstr[3] "%d хвилин" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -3062,296 +3204,206 @@ msgstr[2] "%d Ñекунди" msgstr[3] "%d Ñекунд" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Від'єднаннÑ" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Помилка завантаженнÑ: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Під'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ Ñервера ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Ðемає під'єднаннÑ; будь лаÑка, викориÑтовуйте ПІД'ЄДÐÐÐÐЯ або команду 'connect', щоб зайти на Ñервер." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Ðеможливо запуÑтити локальний Ñервер. Перевірте вікно конÑолі на наÑвніÑть інформації." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Локальний Сервер" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "ЗапуÑк локального Ñервера ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "Зона 51" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Ð’Ð°Ñ ÐºÑ–ÐºÐ½ÑƒÐ»Ñ– з Ñервера ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· локальним Ñервером..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Помилка під'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ Ñервера." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Ð§Ð°Ñ Ð¿Ñ–Ð´'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ локального Ñерверу минув. Відкрийте конÑоль, щоб дізнатиÑÑ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð¸Ñ†Ñ–." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· Ñервером втрачено" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Від'єднаннÑ: Ñервер переповнений." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Від'єднаннÑ: невірний пароль" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "Перевірка клієнта MTA не вдалаÑÑ!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "У кюветі" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "СТВОРИТИ СЕРВЕР" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "РеÑурÑи" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Ім'Ñ Ñервера:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Пароль:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "МакÑ. кількіÑть гравців:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "ВидиміÑть в:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "Локальна мережа" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Вибрано" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "УÑе" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "ЗапуÑтити" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Проблема з графічним драйвером" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Ðеможливо підібрати відповідну роздільніÑть диÑплеÑ." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Ви впевнені, що хочете викориÑтовувати цю роздільніÑть диÑплеÑ?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Помилка завантаженнÑ: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3372,11 +3424,11 @@ msgstr "" msgid "Connection error" msgstr "Помилка з'єднаннÑ" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto інÑтальовано ​​неправильно, будь лаÑка, переінÑталюйте." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Відвідайте веб-Ñторінку, щоб отримати більше відомоÑтей.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/vi_VN/client.pot b/Shared/data/MTA San Andreas/MTA/locale/vi_VN/client.pot index a8ae4d1b4c1..06b123b0ae7 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/vi_VN/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/vi_VN/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Vietnamese\n" "Language: vi_VN\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "Lá»—i khi khởi động lại MTA:SA\n\n" -"Nếu vẫn còn bị lá»—i, hãy mở Task Manager và\n" -"tắt(stop) 'gta_sa.exe' và 'Multi Theft Auto.exe'\n\n\n" -"Sau đó thá»­ chạy lại MTA:SA?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "Lá»—i" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "MTA Ä‘ang chạy.\n\n" -"Nếu bạn vẫn bị lá»—i, hãy thá»­ khởi động lại máy tính" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "MTA Ä‘ang chạy.\n\n" -"Bạn có muốn tắt nó không?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "Chá»n thư mục nÆ¡i cài đặt Grand Theft Auto: San Andreas" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA cần quyá»n Administrator để thá»±c hiện task sau:\n\n" +" '%s'\n\n" +"Vui lòng xác nhận ở há»™p thoại tiếp theo." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "Lá»—i khi tải module %s ! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "Äang sao chép file..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "Việc sao chép được hoàn thành sá»›m. Má»i thứ Ä‘á»u Tá»T." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "Äang hoàn thành..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "Xong!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "Äã phát hiện cài đặt má»›i cá»§a %s.\n\n" +"Bạn có muốn sao chép các tùy chỉnh cài đặt cá»§a mình từ %s không?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA bị lá»—i khi mở file '%s'" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA bị thiếu file '%s'." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA bị lá»—i khi load model." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "Nếu như bạn đã chỉnh sá»­a file gta3.img, Hãy thá»­ cài đặt lại GTA:SA." + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA bị lá»—i khi thêm má»™t nâng cấp cho xe cá»™." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA tìm thấy lá»—i ở file '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "Máy tính bạn đã khởi động lại khi Ä‘ang chÆ¡i MTA:SA?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "Vui lòng tắt hẳn các chương trình sau trước khi tiếp tục:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "Lá»—i phiên bản file không trùng khá»›p. Cài đặt lại MTA:SA nếu bạn có bất kì lá»—i gì.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "Má»™t số file bị thiếu. Cài đặt lại MTA:SA nếu bạn gặp lá»—i.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA: SA không tương thích vá»›i Chế độ an toàn cá»§a Windows.\n\n" +"Vui lòng khởi động lại PC cá»§a bạn.\n" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "Bạn bị lá»—i khi chạy MTA:SA?.\n\n" "Bạn có muốn trở vá» phiên bản cÅ© hÆ¡n không?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "Có vẻ như Ä‘ang xảy ra lá»—i khi chạy MTA:SA.\n" "Khôi phục lại thiết lập GTA có thể sá»­a được lá»—i này.\n\n" "Bạn có muốn khôi phục lại thiết lập GTA không?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "Các thiết lập cá»§a GTA đã được khôi phục như ban đầu.\n\n" "Nhấn OK để tiếp tục." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "Không thể tìm thấy file: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "Bạn Ä‘ang bị lá»—i khi chÆ¡i MTA:SA?.\n\n" "Bạn có muốn tìm trợ giúp vá» lá»—i này ở trên mạng không?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "Bạn Ä‘ang bị lá»—i khi chạy MTA:SA?.\n\n" "Bạn có muốn thay đổi thiết lập sau không?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "Toàn màn hình:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "Cá»­a sổ không viá»n" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "Bạn Ä‘ang gặp trục trặc khi chÆ¡i MTA: SA?. \n\n" "Hãy thá»­ vô hiệu hóa các phần má»m(services) sau:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,128 +189,288 @@ msgstr "CẢNH BÃO\n\n" "MTA:SA đã phát hiện má»™t hoạt động bất thưá»ng không được an toàn.\n" "Hãy thá»­ quét vi-rút má»™t lần xem để đảm bảo máy tính bạn được an toàn.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "File đã được phát hiện: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "Hình như GTA: San Andreas Ä‘ang chạy. Bạn cần phải tắt GTA: San Andreas Ä‘i thì má»›i có thể chÆ¡i MTA:SA. Bạn có muốn tắt GTA: San Andreas không?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "Thông tin" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "Không tắt được GTA: San Andreas. Nếu vẫn bị lá»—i, hãy thá»­ khởi động lại máy tính." -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "Lá»—i khi khởi động lại MTA:SA\n\n" +"Nếu vẫn còn bị lá»—i, hãy mở Task Manager và\n" +"tắt(stop) 'gta_sa.exe' và 'Multi Theft Auto.exe'\n\n\n" +"Sau đó thá»­ chạy lại MTA:SA?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "Lá»—i" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "MTA Ä‘ang chạy.\n\n" +"Nếu bạn vẫn bị lá»—i, hãy thá»­ khởi động lại máy tính" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "MTA Ä‘ang chạy.\n\n" +"Bạn có muốn tắt nó không?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "Các entry cá»§a Registry bị thiếu. Vui lòng cài đặt lại Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "ÄÆ°á»ng dẫn đến thư mục cài đặt GTA: San Andreas chứa các ký tá»± (unicode) không được há»— trợ. Vui lòng di chuyển thư mục cài đặt Grand Theft Auto: San Andreas cá»§a bạn sang má»™t đưá»ng dẫn sá»­ dụng ký tá»± chuẩn ASCII và cài đặt lại Multi Theft Auto: San Andreas." -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "ÄÆ°á»ng dẫn đến nÆ¡i cài đặt 'MTA:SA' hoặc 'GTA: San Andreas'\n" -"có chứa dấu ';' (chấm phẩy).\n\n" -" Nếu bạn gặp trục trặc trong quá trình chÆ¡i MTA:SA,\n" -" Hãy di chuyển thư mục mục cài đặt đó sang má»™t đưá»ng dẫn khác không có chứa dấu chấm phẩy ';'." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "Không thể load. Hãy chắc chắn các file má»›i nhất đã được cài đặt đúng cách." -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "Không thể load. Hãy chắc chắn bạn đã cài đặt %s đúng cách." -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "Không thể load. Không tìm thấy file gta_sa.exe trong %s." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "Không thể load. %s Ä‘ang trong thư mục GTA. Vui lòng xóa nó Ä‘i trước khi tiếp tục." -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "File chính có tên không hợp lệ (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "File chính không được xác nhận. Có thể bị xem là vi-rút.\n\n" -"Tìm trợ giúp trên mạng nếu MTA không chạy được." +#: Client/loader/MainFunctions.cpp:1618 +#, c-format +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 +#, c-format +msgid "Data file %s is modified. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1827 +msgid "Fix configuration issue" +msgstr "Khắc phục sá»± cố cấu hình" + +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "" -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/Install.cpp:272 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" msgstr "" -#: Client/loader/MainFunctions.cpp:893 +#: Client/loader/Install.cpp:479 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." msgstr "" -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr "Các file có Ä‘uôi .asi Ä‘ang ở trong thư mục cài đặt 'MTA:SA' hoặc 'GTA: San Andreas'.\n\n" -"Xóa những file có Ä‘uôi .asi nếu bạn gặp lá»—i khi chạy MTA:SA." +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "Äang cài đặt bản cập nhật..." -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "Lá»—i phiên bản file không trùng khá»›p. Cài đặt lại MTA:SA nếu bạn có bất kì lá»—i gì.\n" +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "Äang giải nén file..." -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "Má»™t số file bị thiếu. Cài đặt lại MTA:SA nếu bạn gặp lá»—i.\n" +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA không thể thá»±c hiện task sau:\n\n" +" '%s'\n" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA: SA không tương thích vá»›i Chế độ an toàn cá»§a Windows.\n\n" -"Vui lòng khởi động lại PC cá»§a bạn.\n" +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** Lá»—i xung đột được gây ra bởi driver đồ há»a **\n\n" +"** Hãy cập nhật driver đồ há»a cá»§a bạn **" -#: Client/loader/MainFunctions.cpp:1123 -msgid "Fix configuration issue" -msgstr "Khắc phục sá»± cố cấu hình" +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "Cài đặt những file MTA:SA đã cập nhật" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "Không thể cập nhật do xung đột tệp. Vui lòng đóng các ứng dụng khác và thá»­ lại" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto không được cài đặt đúng cách, vui lòng cài đặt lại. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "Sá»­a lá»—i yêu cầu elevation" +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "Không thể chạy Grand Theft Auto: San Andreas. Thá»­ khởi động lại, nếu vẫn còn bị lá»—i, hay truy cập MTA tại mtasa.vn hoặc www.multitheftauto.com để nhá» sá»± trợ giúp. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTA:SA không thể tiếp tục vì ổ đĩa %s không đủ bá»™ nhá»› lưu trữ." + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "File bị mất:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "Nếu MTA không chạy được, vui lòng cài đặt lại GTA:SA" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas bị lá»—i khi chạy. Bạn có muốn tắt nó không?" +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "Cập nhật cài đặt cài đặt" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "Cập nhật cài đặt tương thích" #. ///////////////////////////////////////////////////////////////////////// #. @@ -268,166 +478,166 @@ msgstr "GTA: San Andreas bị lá»—i khi chạy. Bạn có muốn tắt nó khôn #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "Có" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "Không" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "Äồng ý" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "Thoát" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "Trợ giúp" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "Há»§y" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas đã gặp sá»± cố" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "Thông tin lá»—i xung đột" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "Tích vào ô để gá»­i thông tin lá»—i xung đột này đến nhà phát triển MTA thông qua 'internet'" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "Bằng việc làm vậy thì lá»—i xung đột sẽ được sá»­a sá»›m nhất có thể." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "Bạn có muốn khởi động lại MTA: San Andreas ?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - Cảnh báo" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "ChÆ¡i MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - Các tùy chá»n dá»… gây nhầm lẫn" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "Hãy thá»­ từng tùy chá»n và xem xem cái nào chạy được:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "Nếu bạn không tìm ra cách giải quyết, cái này có thể giúp ích cho bạn:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "Bắt buá»™c ở chế độ cá»­a sổ" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "Cảnh báo: Không tìm thấy chương trình diệt vi-rút" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -435,1102 +645,1180 @@ msgstr "MTA không tìm thấy phần má»m diệt vi-rút trong máy tính cá»§ "Vi-rút có thể làm ảnh hưởng đến MTA và làm giảm trải nghiệm khi chÆ¡i game.\n\n" "Nhấn 'Trợ giúp' để xem thêm." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "Tôi đã cài đặt phần má»m diệt vi-rút" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "Tôi sẽ không cài đặt phầm má»m diệt vi-rút.\n" "Tôi muốn máy tính cá»§a tôi bị lag và là má»™t phần cá»§a botnet." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "Äang tìm Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "Hãy bắt đầu khởi động Grand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "Äang cài đặt bản cập nhật..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "Kết nối thất bại. Tài khoản không hợp lệ!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "Äang giải nén file..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "Kết nối thất bại. Äịa chỉ server không hợp lệ!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "Äang sao chép file..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "Kết nối đến %s tại port %u không thành công!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "Việc sao chép được hoàn thành sá»›m. Má»i thứ Ä‘á»u Tá»T." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "Äang kết nối đến %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "Äang hoàn thành..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "Xong!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "ÄANG KẾT Ná»I" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA cần quyá»n Administrator để thá»±c hiện task sau:\n\n" -" '%s'\n\n" -"Vui lòng xác nhận ở há»™p thoại tiếp theo." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "Hết thá»i gian kết nối" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA không thể thá»±c hiện task sau:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "Ngắt kết nối: giao thức không hợp lệ" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** Lá»—i xung đột được gây ra bởi driver đồ há»a **\n\n" -"** Hãy cập nhật driver đồ há»a cá»§a bạn **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "Ngắt kết nối: ngắt kết nối từ xa" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "Cài đặt những file MTA:SA đã cập nhật" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "Ngắt kết nối: mất kết nối từ xa" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "Không thể cập nhật do xung đột tệp. Vui lòng đóng các ứng dụng khác và thá»­ lại" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "Ngắt kết nối: bạn bị cấm khá»i server này" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "Ngắt kết nối: ngắt kết nối khá»i server" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "Äã ngắt kết nối: không thể kết nối đến server" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "Äã ngắt kết nối: kết nối đã bị từ chối" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto không được cài đặt đúng cách, vui lòng cài đặt lại. %s" +msgid "No such mod installed (%s)" +msgstr "Chưa cài đặt bản mod nào (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "Phản hồi cá»§a server kém (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "Phản hồi cá»§a server kém (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "Tiếng Việt" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "Bận" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "Không thể kiểm tra các bản cập nhật ngay bây giá»" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "yêu cầu MTA: SA %s" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "Äể kết nối đến server đã chá»n, bạn buá»™c phải cài đặt má»™t phiên bản cập nhật cá»§a MTA:SA %s.\n\n" +"Bạn có muốn tải xuống và cài đặt MTA:SA %s không?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "Bạn có muốn chạy MTA: SA %s và kết nối vá»›i server này không?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "Hiện tại không thể kết nối.\n\n" +"Vui lòng thá»­ lại sau." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "Äang kết nối" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "Vui lòng chá»..." -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "ÄANG KIỂM TRA" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTA:SA không thể tiếp tục vì ổ đĩa %s không đủ bá»™ nhá»› lưu trữ." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "KIỂM TRA CẬP NHẬT" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "File bị mất:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "Không có bản cập nhật nào cả" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "Nếu MTA không chạy được, vui lòng cài đặt lại GTA:SA" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "ÄANG TẢI XUá»NG" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "Cập nhật cài đặt cài đặt" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "đợi..." -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "Cập nhật cài đặt tương thích" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "BẮT BUỘC CẬP NHẬT" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "Äể kết nối vá»›i server này, bạn cần phải cập nhật MTA.\n\n" +" Bạn có muốn cập nhật luôn không?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "CẬP NHẬT KHÔNG BẮT BUỘC" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "Server cho biết bạn nên cài đặt má»™t bản cập nhật, nhưng có vẻ không cần thiết cho lắm.\n\n" +" Bạn có muốn cập nhật không?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "Lá»–I KHI LƯU" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "Không thể tạo được file." -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "Chá»n thư mục nÆ¡i cài đặt Grand Theft Auto: San Andreas" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "Lá»–I KHI TẢI XUá»NG" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "Lá»—i khi tải module %s ! (%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "File đã tải xuống không đúng." -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "Äã phát hiện cài đặt má»›i cá»§a %s.\n\n" -"Bạn có muốn sao chép các tùy chỉnh cài đặt cá»§a mình từ %s không?" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "Vì má»™t số lý do." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA bị lá»—i khi mở file '%s'" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "Äà TẢI XONG" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA bị thiếu file '%s'." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - Lá»—i không xác định _DialogUpdateResult" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA bị lá»—i khi load model." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "FILE GTA:SA Äà TÙY CHỈNH" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "Nếu như bạn đã chỉnh sá»­a file gta3.img, Hãy thá»­ cài đặt lại GTA:SA." +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA bị lá»—i khi thêm má»™t nâng cấp cho xe cá»™." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "Lá»–I" -#: Client/loader/Utils.cpp:1631 -#, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA tìm thấy lá»—i ở file '%s'" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "Má»™t vài file dữ liệu MTA:SA đã bị xóa.\n\n\n" +"Hãy cài đặt lại MTA:SA" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "Máy tính bạn đã khởi động lại khi Ä‘ang chÆ¡i MTA:SA?" +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% đã hoàn thành" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "Vui lòng tắt hẳn các chương trình sau trước khi tiếp tục:" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"Äang chá» phản hồi - %-3d" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "Yêu cầu trang web" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ LỆNH TRỢ GIÚP ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "Server yêu cầu các địa chỉ trang web sau để load chúng (sau):" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* Thá»i gian %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "KHÔNG CUNG CẤP CÃC THÔNG TIN NHẠY CẢM ÄỂ TRÃNH BỊ ÄÃNH CẮP" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "Ghi nhá»› quyết định" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "kết nối: Cú pháp là 'connect [ ]'" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "Cho phép" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "Kết nối: Số port nguy hiểm" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "Từ chối" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "kết nối: Äang kết nối đến %s:%u..." -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "kết nối : không thể kết nối đến %s:%u!" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "Bạn Ä‘ang sá»­ dụng má»™t feature-branch build! Äây là bản build thá»­ nghiệm không thể kết nối đến má»™t server mở!" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "kết nối: Không thể gỡ bản mod hiện tại" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA hiện tại sẽ không phát hành các bản cập nhật dành cho XP/Vista sau Tháng 7/2019.\n" -"Hãy nâng cấp Windows để chÆ¡i trên các máy chá»§ có phiên bản má»›i nhất." +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "Thao tác này sẽ ngắt kết nối bạn khá»i server Ä‘ang kết nối hiện tại.\n\n" -"Bạn có chắc chắn muốn ngắt kết nối không?" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "CẢNH BÃO NGẮT KẾT Ná»I" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" msgstr "" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "Tiếng Việt" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "Ràng buá»™c tất cả các Ä‘iá»u khiển từ GTA" + +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "Äã lưu file cấu hình" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* Mã serial cá»§a bạn: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "CÀI ÄẶT" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "Nhiá»u ngưá»i chÆ¡i" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "Äồ há»a" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "Âm thanh" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "Phím" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "Äiá»u khiển" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "Thiết lập giao diện" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "Web" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "Thiết lập nâng cao" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "Khôi phục mặc định" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "Tốc độ chuá»™t:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "Tốc độ chuá»™t di chuyển khi ngắm theo chiá»u trên xuống:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "Thiết lập chuá»™t" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "Äảo ngược góc nhìn lên xuống khi dùng chuá»™t" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "Äiá»u khiển xe bằng chuá»™t" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "Äiá»u khiển báy bay bằng chuá»™t" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "Thiết lập Joypad" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "Äiá»u khiển tiêu chuẩn (Chuá»™t + Bàn phím)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "Äiá»u khiển bằng tay cầm (Joypad)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "Vùng chết" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "Äá»™ bão hòa" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "Sá»­ dụng tab 'Phím(Binds)' cho các nút joypad" -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "Phía bên trái tay cầm" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "Phía bên phải tay cầm" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "MÔ TẢ" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "Phím" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "Phím ALT" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "Nickname:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "Lưu mật khẩu cá»§a server" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "Tá»± động làm má»›i trình duyệt server" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "Cho phép tải lên ảnh màn hình" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "Cho phép âm thanh bên ngoài" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "Luôn hiển thị cá»­a sổ tải xuống" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "Sá»­ dụng các file GTA:SA đã tùy chỉnh" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "Tùy chá»n xem bản đồ" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "Äá»™ má»:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "Âm lượng tổng:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "Âm lượng Radio:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "Âm lượng hiệu ứng:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "Âm lượng MTA:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "Âm lượng đàm thoại:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "Chế độ:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "Chung" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "Tùy chá»n Radio" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "Tần số radio" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "Tá»± động Ä‘iá»u chỉnh radio" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "Tùy chá»n nhạc riêng" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "Radio" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "Ngẫu nhiên" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "Liên tiếp" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "Tá»± động quét nhạc" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "Tùy chá»n tắt tiếng" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "Tắt tất cả âm thanh khi thu nhá» cá»­a sổ (Alt + Tab)" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "Tắt âm thanh Radio khi thu nhá» cá»­a sổ (Alt + Tab)" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "Tắt âm thanh hiệu ứng game khi thu nhá» cá»­a sổ (Alt + Tab)" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "Tắt âm thanh MTA khi thu nhá» cá»­a sổ (Alt + Tab)" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "Tắt âm thanh đàm thoại khi thu nhá» cá»­a sổ (Alt + Tab)" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "Äá»™ phân giải:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "Góc nhìn thứ nhất" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "Load map ở khoảng cách:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "Äá»™ sáng:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "Chất lượng hiệu ứng:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "Lá»c bất đẳng hướng:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "Khá»­ răng cưa:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "Tá»· lệ khung hình" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "Cá»­a sổ" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "Mặc định" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "Không viá»n" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "Mip mapping" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "Thấp" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "Trung bình" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "Cao" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "Rất cao" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "Tắt" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "Tá»± động" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD thay đổi theo tỉ lệ khung hình" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "Hiệu ứng đổ bóng" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "Hiệu ứng cá» lá" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "Hiệu ứng nhiệt độ khi trá»i nóng nóng" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "Khói từ lốp xe v.v..." -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "Thu nhá» toàn màn hình" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "Bật há»™p thoại lá»±a chá»n thiết bị" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "Hiển thị các độ phân giải không phù hợp" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "Chi tiết đồ há»a cá»§a xe cá»™ ở mức cao" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "Chi tiết đồ há»a nhân vật ở mức cao" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "Bật trang web từ xa" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "Bật Javascript trên remote websites" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "Danh sách trang web không cho phép" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "Nhập má»™t địa chỉ web (ví dụ: google.com)" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "Chặn" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "Trang web" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "Xóa trang web" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "Danh sách trang web cho phép" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "Cho phép" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "Các tùy chá»n" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "Tốc độ load áo quần cá»§a CJ:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "Tốc độ duyệt web:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "Kết nối đơn:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "Hiệu ứng khi Load:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Cài đặt debug:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "Bá»™ nhá»› streaming:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "Thể loại cập nhật:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "Cài đặt các cập nhật quan trá»ng:" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "Bật" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "Rất chậm" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "Mặc định" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "Nhanh" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "Bình thưá»ng" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "Trên mức bình thưá»ng" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "Nhá» nhất" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "Tối Ä‘a" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Tương thích Windows 8:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "Màu 16 bit" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "Sá»­a chuá»™t" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "Hiển thị trong Explorer" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "Tá»± động cập nhật" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "Kiểm tra cập nhật" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "Má»™t vài thiết lập sẽ được áp dụng vào lần tiếp theo bạn chạy MTA" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "Bạn có muốn khởi động lại không?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "CẦN KHỞI ÄỘNG LẠI" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "Má»™t vài cài đặt sẽ bị thay đổi khi bạn ngắt kết nối máy chá»§ hiện tại" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "Bạn có muốn ngắt kết nối ngay?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "CẦN NGẮT KẾT Ná»I" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "Không tìm thấy Joypad - Kiểm tra đầu cắm và thá»­ khởi động lại game" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "Nút joystick" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "Di chuyển joystick để gán nút, hoặc nhấn escape để xóa" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "Ngôn ngữ:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "Giao diện:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "Thiết lập có sẵn:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "Trò chuyện" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "Tải" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "Màu" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "Bố trí" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "Tùy chá»n khác" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "Màu ná»n khung chat" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "Màu chữ chat" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "Màu ná»n ô gõ chữ chat" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "Màu chữ gõ chat" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "Dòng:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "Tỉ lệ:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "Chiá»u rá»™ng:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "Kích cỡ" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "sau" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "trong" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "giây" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "Má» dần" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "Làm má» các dòng cÅ©" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "Chiá»u ngang:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "Chiá»u dá»c:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "Căn chỉnh văn bản:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "Tá»a độ X:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Tá»a độ Y:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "Vị trí" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "Trái" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "Trung tâm" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "Phải" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "Trên" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "Dưới" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "Phông chữ" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "Ẩn ná»n khi không gõ chữ" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "Gợi ý nickname sá»­ dụng phím \"Tab\"" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "Cho phép server nháy màn hình" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "Cho phép thông báo trên tray" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "Viá»n chữ chat màu Ä‘en/trắng" @@ -1538,109 +1826,115 @@ msgstr "Viá»n chữ chat màu Ä‘en/trắng" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "Nhấn má»™t phím để gán, hoặc escape để xóa" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "Ràng buá»™c má»™t key chính" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "Ràng buá»™c má»™t key phụ" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "ÄIỀU KHIỂN GAME GTA" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "ÄIỀU KHIỂN MULTIPLAYER" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "Nickname cá»§a bạn chứa các ký tá»± không hợp lệ!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "Äá»:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "Xanh lục:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "Xanh dương:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "Äá»™ trong suốt:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "Màu sắc" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "Xem trước" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "Hãy ngắt kết nối trước khi thay đổi ngôn ngữ" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "Hãy ngắt kết nối trước khi thay đổi giao diện" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "Hiệu ứng đổ bóng có thể làm cho máy bạn chậm Ä‘i.\n\n" "Bạn có chắc muốn bật không?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "CẢNH BÃO HIỆU SUẤT" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "Tá»± động upload ảnh màn hình có thể được má»™t số server sá»­ dụng nhằm mục đích chống gian lận.\n\n" "(Chatbox và Hud sẽ không kèm theo khi chụp màn hình)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "THÔNG TIN TẢI LÊN ẢNH CHỤP MÀN HÃŒNH" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1650,561 +1944,259 @@ msgstr "Má»™t số file trong thư mục dữ liệu GTA:SA cá»§a bạn đã Ä‘ "Tuy nhiên, CÃC FILE Dá»® LIỆU GTA:SA Äà TÙY BIẾN BỊ CẤM BỞI NHIỀU SERVER\n\n" "Bạn có muốn sá»­ dụng chúng không?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "FILE GTA:SA Äà TÙY CHỈNH" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" "Are you sure you want to enable this option?" msgstr "" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "Hãy nhập má»™t nickname" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "Nhập vào má»™t nickname để sá»­ dụng trong game. \n" "Äây sẽ là tên cá»§a bạn khi kết nối đến và chÆ¡i tại server bất kỳ" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "Tính năng thá»­ nghiệm." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "Dá»±ng các quầy hàng vá»›i các tùy chá»n cá»§a CJ (Sá»­ dụng thêm 65MB RAM)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "Các bá»™ định tuyến cÅ© hÆ¡n có thể yêu cầu tốc độ quét chậm hÆ¡n." -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "Bật để sá»­ dụng duy nhất má»™t đưá»ng truyá»n kết nối khi tải xuống." -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "Gắn thẻ gói mạng để giúp ISP xác định lưu lượng truy cập MTA." -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "Biểu tượng loading xoay vòng ở dưới màn hình" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "Luôn luôn chá»n mặc định. (Tùy chá»n này sẽ không được lưu)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "Càng cao càng tốt" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "Tá»± động cập nhật:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "Chá»n mặc định trừ khi bạn muốn Ä‘iá»n vào các phản hồi vá» lá»—i." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "Chá»n mặc định để tá»± động cài đặt các cập nhật quan trá»ng." -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "Màu 16-bit:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "Bật chế độ 16-bit - Yêu cầu khởi động lại MTA" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "Sá»­a chuá»™t:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "Sá»­a lá»—i di chuyển chuá»™t - Có thể cần khởi động lại máy tính" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 -msgid "Only change if you're having stability issues." -msgstr "" - -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "Lệnh không hợp lệ được hoặc cvar: ~" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "Bận" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "Không thể kiểm tra các bản cập nhật ngay bây giá»" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "yêu cầu MTA: SA %s" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "Äể kết nối đến server đã chá»n, bạn buá»™c phải cài đặt má»™t phiên bản cập nhật cá»§a MTA:SA %s.\n\n" -"Bạn có muốn tải xuống và cài đặt MTA:SA %s không?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "Bạn có muốn chạy MTA: SA %s và kết nối vá»›i server này không?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "Hiện tại không thể kết nối.\n\n" -"Vui lòng thá»­ lại sau." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "Äang kết nối" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "Vui lòng chá»..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "ÄANG KIỂM TRA" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "KIỂM TRA CẬP NHẬT" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "Không có bản cập nhật nào cả" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "ÄANG TẢI XUá»NG" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "đợi..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "BẮT BUỘC CẬP NHẬT" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "Äể kết nối vá»›i server này, bạn cần phải cập nhật MTA.\n\n" -" Bạn có muốn cập nhật luôn không?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "CẬP NHẬT KHÔNG BẮT BUỘC" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "Server cho biết bạn nên cài đặt má»™t bản cập nhật, nhưng có vẻ không cần thiết cho lắm.\n\n" -" Bạn có muốn cập nhật không?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "Lá»–I KHI LƯU" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "Không thể tạo được file." - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "Lá»–I KHI TẢI XUá»NG" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "File đã tải xuống không đúng." - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "Vì má»™t số lý do." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "Äà TẢI XONG" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - Lá»—i không xác định _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "Lá»–I" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "Má»™t vài file dữ liệu MTA:SA đã bị xóa.\n\n\n" -"Hãy cài đặt lại MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% đã hoàn thành" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"Äang chá» phản hồi - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "Kết nối thất bại. Tài khoản không hợp lệ!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "Kết nối thất bại. Äịa chỉ server không hợp lệ!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "Kết nối đến %s tại port %u không thành công!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "Äang kết nối đến %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "ÄANG KẾT Ná»I" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "Hết thá»i gian kết nối" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "Ngắt kết nối: giao thức không hợp lệ" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "Ngắt kết nối: ngắt kết nối từ xa" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "Ngắt kết nối: mất kết nối từ xa" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "Ngắt kết nối: bạn bị cấm khá»i server này" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "Ngắt kết nối: ngắt kết nối khá»i server" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "Äã ngắt kết nối: không thể kết nối đến server" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "Äã ngắt kết nối: kết nối đã bị từ chối" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "Chưa cài đặt bản mod nào (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "Phản hồi cá»§a server kém (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "Phản hồi cá»§a server kém (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "Cập nhật các thông tin má»›i nhất" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "CONSOLE" +#: Client/core/CSettings.cpp:6043 +msgid "Only change if you're having stability issues." +msgstr "" -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "Lá»—i nghiêm trá»ng" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "ÄỂ SỬA, XÓA TỆP NÀY:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s mô-Ä‘un không hợp lệ!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "Lá»—i thá»±c thi URL" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "màn hình trợ giúp này" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "thoát khá»i ứng dụng" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "hiển thị phiên bản" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "hiển thị thá»i gian" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "hiển thị hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "hiển thị tất cả các phím" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "hiển thị mã serial cá»§a bạn" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "kết nối đến má»™t server (host port nick pass)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "kết nối vá»›i server trước đó đã dùng" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "gán má»™t phím (Ä‘iá»u khiển phím)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "bá» gán má»™t key (key)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "Sao chép các phím Ä‘iá»u khiển mặc định cá»§a gta" -#: Client/core/CCore.cpp:1388 +#: Client/core/CCore.cpp:1491 msgid "outputs a screenshot" msgstr "Xuất ra má»™t ảnh chụp màn hình" -#: Client/core/CCore.cpp:1389 +#: Client/core/CCore.cpp:1492 msgid "immediately saves the config" msgstr "Lưu các thông tin tùy chỉnh ngay" -#: Client/core/CCore.cpp:1391 +#: Client/core/CCore.cpp:1494 msgid "clears the debug view" msgstr "xóa các chế độ xem gỡ lá»—i" -#: Client/core/CCore.cpp:1392 +#: Client/core/CCore.cpp:1495 msgid "scrolls the chatbox upwards" msgstr "kéo khung trò chuyện lên" -#: Client/core/CCore.cpp:1393 +#: Client/core/CCore.cpp:1496 msgid "scrolls the chatbox downwards" msgstr "kéo khung trò chuyện xuống" -#: Client/core/CCore.cpp:1394 +#: Client/core/CCore.cpp:1497 msgid "scrolls the debug view upwards" msgstr "kéo khung xem debug lên" -#: Client/core/CCore.cpp:1395 +#: Client/core/CCore.cpp:1498 msgid "scrolls the debug view downwards" msgstr "kéo khung xem debug xuống" -#: Client/core/CCore.cpp:1398 +#: Client/core/CCore.cpp:1501 msgid "shows the memory statistics" msgstr "hiển thị thống kê bá»™ nhá»›" -#: Client/core/CCore.cpp:1399 +#: Client/core/CCore.cpp:1502 msgid "shows the frame timing graph" msgstr "hiển thị biểu đồ khung thá»i gian" -#: Client/core/CCore.cpp:1403 +#: Client/core/CCore.cpp:1506 msgid "for developers: reload news" msgstr "" -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ LỆNH TRỢ GIÚP ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* Thá»i gian %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "kết nối: Cú pháp là 'connect [ ]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "Kết nối: Số port nguy hiểm" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "Bạn Ä‘ang sá»­ dụng má»™t feature-branch build! Äây là bản build thá»­ nghiệm không thể kết nối đến má»™t server mở!" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "kết nối: Äang kết nối đến %s:%u..." +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA hiện tại sẽ không phát hành các bản cập nhật dành cho XP/Vista sau Tháng 7/2019.\n" +"Hãy nâng cấp Windows để chÆ¡i trên các máy chá»§ có phiên bản má»›i nhất." -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "kết nối : không thể kết nối đến %s:%u!" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "Thao tác này sẽ ngắt kết nối bạn khá»i server Ä‘ang kết nối hiện tại.\n\n" +"Bạn có chắc chắn muốn ngắt kết nối không?" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "kết nối: Không thể gỡ bản mod hiện tại" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "CẢNH BÃO NGẮT KẾT Ná»I" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" msgstr "" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" msgstr "" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "Cập nhật các thông tin má»›i nhất" -#: Client/core/CCommandFuncs.cpp:325 +#: Client/core/CScreenShot.cpp:200 #, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "Ràng buá»™c tất cả các Ä‘iá»u khiển từ GTA" +msgid "Screenshot got %d bytes, but expected %d" +msgstr "Ảnh chụp màn hình có dung lượng %d bytes, nhưng yêu cầu phải đạt %d" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "Äã lưu file cấu hình" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "Lá»—i! không thể chụp màn hình" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 +#: Client/core/CScreenShot.cpp:256 #, c-format -msgid "* Your serial is: %s" -msgstr "* Mã serial cá»§a bạn: %s" - -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "Nút tăng tốc" - -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "Nút phanh" - -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "Lập trình" - -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "Cá»™ng tác viên" - -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "Thiết kế Game / Scripting" - -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "Ngôn ngữ bản địa hóa" - -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "Ngưá»i trợ giúp bản patch" - -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "Lá»i cảm Æ¡n sâu sắc" - -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "" +msgid "Screenshot taken: '%s'" +msgstr "Ảnh đã được chụp: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "Bạn có muốn tìm kiếm trợ giúp vá» vẫn đỠnày ở trên mạng không?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "Lệnh không hợp lệ được hoặc cvar: ~" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2379,25 +2371,56 @@ msgid "Group control backwards" msgstr "Nhóm Ä‘iá»u khiển ngược" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "Giao diện mà bạn chá»n không thể sá»­ dụng, và đồng thá»i giao diện mặc định cÅ©ng không hoạt động luôn, vui lòng cài đặt lại MTA." -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "Ảnh chụp màn hình có dung lượng %d bytes, nhưng yêu cầu phải đạt %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "Bạn có muốn tìm kiếm trợ giúp vá» vẫn đỠnày ở trên mạng không?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "Lá»—i! không thể chụp màn hình" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "CONSOLE" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "Ảnh đã được chụp: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "Lập trình" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "Cá»™ng tác viên" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "Thiết kế Game / Scripting" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "Ngôn ngữ bản địa hóa" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "Ngưá»i trợ giúp bản patch" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "Lá»i cảm Æ¡n sâu sắc" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "Nút tăng tốc" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "Nút phanh" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2405,6 +2428,59 @@ msgstr "Không thể thiết lập Direct3D9.\n\n" "Hãy chắc chắn rằng DirectX End-User Runtime và\n" "bản Windows Service Packs má»›i nhất đã được cài đặt." +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "Trạng thái chá»" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "ngưá»i chÆ¡i" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "trên" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "server" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "Äang lấy danh sách server chính (%lu mili giây đã trôi qua)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "Không thể phân tích cú pháp danh sách server chính." + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "Không thể lấy danh sách server chính." + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(Danh sách server sao lưu)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "Không thể ràng buá»™c socket LAN-broadcast" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "Äang tìm kiếm các server trong mạng LAN" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2458,7 +2534,7 @@ msgstr "Äá»™ trá»…:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "Ngưá»i chÆ¡i" @@ -2485,40 +2561,39 @@ msgstr "Kết nối server ngay sau khi có chá»— trống." msgid "PLEASE ENTER SERVER PASSWORD" msgstr "HÃY NHẬP MẬT KHẨU MÃY CHỦ" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "Hết thá»i gian kết nối" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "Äang tải..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "TRÃŒNH DUYỆT CỦA SERVER" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "Cục bá»™" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "Yêu thích" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "Gần đây" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2526,296 +2601,367 @@ msgstr "ÄỂ KẾT Ná»I NGAY:\n\n" "Nhập địa chỉ server và port vào thanh địa chỉ.\n" "Hoặc bạn có thể chá»n má»™t server đã kết nối trước đó ở trong danh sách lịch sá»­ server đã kết nối và nhấn 'Kết nối'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "TRỢ GIÚP" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "Làm má»›i" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "Thêm vào mục yêu thích" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "Kết nối" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "Thông tin server" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "Tìm kiếm server" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "Tìm kiếm ngưá»i chÆ¡i" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "Tìm kiếm" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "Äang tìm kiếm ngưá»i chÆ¡i..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "Tìm kiếm server..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "Tên" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "Ngưá»i chÆ¡i" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "Thể loại" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "Bao gồm:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "Còn trống" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "Äầy" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "Äã khóa" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "Các phiên bản khác" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "Quay lại" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "Äang tải..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr " ..Ä‘ang tải.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "Không có địa chỉ truy cập cụ thể!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "Giao thức không xác định" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "Hãy sá»­ dụng giao thức mtasa:// !" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "Nickname không hợp lệ! Hãy vào Cài Äặt và tạo cái má»›i!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "Bạn phải chá»n má»™t server nào đó để có thể kết nối." -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "Trạng thái chá»" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "Vấn đỠvá»›i trình Ä‘iá»u khiển đồ há»a" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "ngưá»i chÆ¡i" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "Không thấy độ phân giải màn hình hợp lệ." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "trên" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "Bạn có chắc chắn muốn sá»­ dụng độ phân giải màn hình này không?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "server" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "Äang lấy danh sách server chính (%lu mili giây đã trôi qua)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "Không thể phân tích cú pháp danh sách server chính." +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "Yêu cầu trang web" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "Không thể lấy danh sách server chính." +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "Server yêu cầu các địa chỉ trang web sau để load chúng (sau):" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(Danh sách server sao lưu)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "KHÔNG CUNG CẤP CÃC THÔNG TIN NHẠY CẢM ÄỂ TRÃNH BỊ ÄÃNH CẮP" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "Không thể ràng buá»™c socket LAN-broadcast" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "Ghi nhá»› quyết định" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "Äang tìm kiếm các server trong mạng LAN" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "Từ chối" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "Phiên bản này đã hết hạn." -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "ngắt kết nối khá»i game" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "hiển thị thẻ gắn tên" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "hiển thị chatbox" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "hiển thị thống kê mạng" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "mở khung nhập chữ chat" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "truyá»n giá»ng nói cho ngưá»i chÆ¡i khác" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "Ä‘i vào xe hÆ¡i như hành khách" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "kênh radio tiếp theo" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "kênh radio trước" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "gá»­i tin nhắn đến trình phát được nhắm mục tiêu" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "thay đổi vÅ© khí tiếp theo khi Ä‘ang ở trong xe" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "thay đổi vÅ© khí trước đó khi Ä‘ang ở trong xe" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "thông tin đầu ra cá»§a server hiện tại" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "xác định tỉ lệ số nhân cá»§a tất cả các chữ hiển thị" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(Chế độ dev) hiển thị colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(Chế độ phát triển) in id âm thanh thế giá»›i vào cá»­a sổ gỡ lá»—i" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "Tên server:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "Mật khẩu:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "Ngưá»i chÆ¡i tối Ä‘a:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "Äã chá»n" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "Tất cả" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "Bắt đầu" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "Tiến trình tải xuống bản đồ:" @@ -2836,488 +2982,398 @@ msgstr "%s trong số %s" msgid "Disconnect to cancel download" msgstr "Ngắt kết nối để há»§y tải xuống" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "Äã ngắt kết nối: nickname không hợp lệ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "Ngắt kết nối khá»i server" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "Äã ngắt kết nối: Serial đã bị cấm.\n" "Lý do: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "Äã ngắt kết nối: Bạn đã bị cấm.\n" "Lý do: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "Äã ngắt kết nối: Tài khoản đã bị cấm.\n" "Lý do: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "Äã ngắt kết nối: Phiên bản không khá»›p" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "Äã ngắt kết nối: Join flood. Vui lòng chá» trong giây lát, rồi thá»­ lại sau." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "Äã ngắt kết nối: Server từ các nhánh khác nhau.\n" "Thông tin: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "Äã ngắt kết nối: Phiên bản không hợp lệ.\n" "Thông tin: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "Äã ngắt kết nối: Server Ä‘ang sá»­ dụng phiên bản MTA má»›i hÆ¡n.\n" "Thông tin: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "Äã ngắt kết nối: Server Ä‘ang sá»­ dụng phiên bản MTA cÅ© hÆ¡n.\n" "Thông tin: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "Äã ngắt kết nối: Nickname đã được sá»­ dụng" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "Äã ngắt kết nối: Server há»§y kết nối: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "Äã ngắt kết nối: Không thể xác minh serial" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "Äã ngắt kết nối: Kết nối không đồng bá»™ %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "Äã ngắt kết nối: Bạn đã bị kick bởi %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "Äã ngắt kết nối: Bạn đã bị cấm bởi %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "Äã ngắt kết nối: Server bảo trì hoặc Ä‘ang khởi động lại" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "Bạn đã bị kick khá»i game" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "Thá»i gian còn lại:" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d ngày" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d giá»" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "% d phút%d phút" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" msgstr[0] "%d giây" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "Äã ngắt kết nối" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "Lá»—i tải xuống: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "Äang vào game ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "Không thể kết nối; Chá»n Kết nối server hoặc dùng lệnh 'kết nối' để kết nối đến server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "Không thể khởi động server cục bá»™. Xem console để biết thêm thông tin." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "Server cục bá»™" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "Äang khởi động server cục bá»™ ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "Bạn đã bị kick khá»i game ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "Äang kết nối đến server cục bá»™..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "Lá»—i khi kết nối đến server." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "Hết thá»i gian kết nối đến server cục bá»™. Xem console để biết thêm thông tin." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "Không thể kết nối đến server" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "Äã ngắt kết nối: server hiện đã đầy ngưá»i chÆ¡i" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "Äã ngắt kết nối: mật khẩu không hợp lệ được chỉ định" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "Không thể xác minh Client MTA!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "Tên server:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "Mật khẩu:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "Ngưá»i chÆ¡i tối Ä‘a:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "Äã chá»n" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "Tất cả" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "Bắt đầu" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "Vấn đỠvá»›i trình Ä‘iá»u khiển đồ há»a" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "Không thấy độ phân giải màn hình hợp lệ." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "Bạn có chắc chắn muốn sá»­ dụng độ phân giải màn hình này không?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "Lá»—i tải xuống: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3338,11 +3394,11 @@ msgstr "" msgid "Connection error" msgstr "Lá»—i kết nối" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto chưa được cài đặt đúng cách, vui lòng cài đặt lại." -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "Trình duyệt cá»§a bạn bây giá» sẽ hiển thị má»™t trang web vá»›i má»™t số thông tin trợ giúp.\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/zh_CN/client.pot b/Shared/data/MTA San Andreas/MTA/locale/zh_CN/client.pot index 4ec4fd11c8c..b289b6a44c4 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/zh_CN/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/zh_CN/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Chinese Simplified\n" "Language: zh_CN\n" @@ -17,72 +17,122 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "é‡å¯ MTA:SA 时出现问题\n\n" -"如果问题继续存在,打开资æºç®¡ç†å™¨å¹¶\n" -"ç»“æŸ 'gta_sa.exe' å’Œ 'Multi Theft Auto.exe' 进程\n\n\n" -"冿¬¡å°è¯•å¯åЍ MTA:SA ?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "错误" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "å¦å¤–一个 MTA 正在è¿è¡Œ.\n\n" -"如果问题æŒç»­å‡ºçް,请é‡å¯ä½ çš„计算机" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "å¦å¤–一个 MTA 正在è¿è¡Œ.\n\n" -"你想è¦å…³é—­å®ƒå—?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "请选择 侠盗猎车手:圣安地列斯的安装目录" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA 需è¦ç®¡ç†å‘˜æƒé™è¿è¡Œä»¥ä¸‹ä»»åŠ¡:\n\n" +" '%s'\n\n" +"请在下一个窗å£ä¸­ç¡®è®¤æŒ‡ä»¤." + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "åœ¨è¯»å– %s æ¨¡å—æ—¶å‡ºé”™! (%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "å¤åˆ¶æ–‡ä»¶..." -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "文件æå‰å¤åˆ¶å®Œæ¯•.æ‰€æœ‰æ•°æ®æ­£å¸¸." + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "正在完æˆ..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "已完æˆ!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "检测到最近安装的 %s.\n\n" +"你想把é…置文件从%så¤åˆ¶åˆ°è¿™é‡Œå—?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA 在打开 '%s' 文件时é‡åˆ°é—®é¢˜." + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA 缺少 '%s' 文件." + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA 在加载模型文件时é‡åˆ°é—®é¢˜." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "如果您最近修改了gta3.img,请å°è¯•釿–°å®‰è£…GTA:SA。" + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA 在改装车辆时é‡åˆ°é—®é¢˜." + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA 在以下文件找到错误 '%s'" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "你在è¿è¡ŒMTA:SA的时候é‡å¯ç”µè„‘了å—?" + +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "请在è¿è¡Œå‰å…³é—­ä»¥ä¸‹ç¨‹åº:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "文件版本ä¸åŒ¹é…导致出错.å¦‚æžœæ¸¸æˆæ—¶é‡åˆ°äº†é—®é¢˜è¯·é‡æ–°å®‰è£…MTA:SA.\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "缺少部分文件. å¦‚æžœåœ¨æ¸¸æˆæ—¶é‡åˆ°äº†é—®é¢˜è¯·é‡æ–°å®‰è£…MTA:SA.\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA 与Windows的安全模å¼ä¸å…¼å®¹.\n\n" +"请é‡å¯ä½ çš„电脑.\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "在è¿è¡Œ MTA:SA 时出现问题?.\n\n" "你希望æ¢å¤åˆ°æ—©æœŸçš„版本å—?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +140,48 @@ msgstr "å¯åЍ MTA:SA时似乎出现了一点问题.\n" "é‡è®¾GTA内部设置有时候会修å¤è¿™ä¸ªé—®é¢˜.\n\n" "你希望é‡è®¾GTA设置å—?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA 游æˆè®¾ç½®å·²è¢«é‡è®¾t.\n\n" "点击确认继续." -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "指定文件ä¸å…许删除: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "在è¿è¡ŒMTA:SA?.æ—¶é‡åˆ°é—®é¢˜äº†å—?\n\n" "您需è¦åˆ°é€‰é¡¹é‡Œä¿®æ”¹è®¾ç½®å—?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "您在è¿è¡ŒMTA:SA?. 的时候出现问题了å—\n\n" "您需è¦ä¿®æ”¹ä»¥ä¸‹è®¾ç½®å—?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "免屿¨¡å¼:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "无边框窗å£" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "您在è¿è¡ŒMTA:SA?. 的时候出现问题了å—\n\n" "å°è¯•为GTAå’ŒMTA关闭以下产å“:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +189,293 @@ msgstr "警告\n\n" "MTA:SA æ£€æµ‹å‡ºä¸€äº›éžæ­£å¸¸æ´»åЍ.\n" "请è¿è¡Œæ€æ¯’软件以确ä¿ä½ çš„系统安全.\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "监测到的文件为: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "侠盗猎车手: 圣安地列斯的进程已ç»åœ¨è¿è¡Œ,MTA:SA需è¦å…³é—­å®ƒæ‰èƒ½å¯åЍ.ä½ æƒ³çŽ°åœ¨ç»“æŸæŽ‰è¿™ä¸ªè¿›ç¨‹å—?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "ä¿¡æ¯" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "无法关闭侠盗猎车手: 圣安地列斯. 如果问题ä»ç»§ç»­å‡ºçް, è¯·é‡æ–°å¯åŠ¨è®¡ç®—æœº" -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "é‡å¯ MTA:SA 时出现问题\n\n" +"如果问题继续存在,打开资æºç®¡ç†å™¨å¹¶\n" +"ç»“æŸ 'gta_sa.exe' å’Œ 'Multi Theft Auto.exe' 进程\n\n\n" +"冿¬¡å°è¯•å¯åЍ MTA:SA ?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "错误" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "å¦å¤–一个 MTA 正在è¿è¡Œ.\n\n" +"如果问题æŒç»­å‡ºçް,请é‡å¯ä½ çš„计算机" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "å¦å¤–一个 MTA 正在è¿è¡Œ.\n\n" +"你想è¦å…³é—­å®ƒå—?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "注册键值丢失.è¯·é‡æ–°å®‰è£… MTA:SA." -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "侠盗猎车手: 圣安地列斯的路径包å«ä¸æ”¯æŒçš„字符(unicode)。请移动你的GTA: San Andrea到一个åªåŒ…嫿 ‡å‡†ASCIIå­—ç¬¦çš„ç›®å½•å¹¶ä¸”é‡æ–°å®‰è£…MTA:SA" -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "您指定的 'MTA:SA' 或者 '侠盗猎车手: 圣安地列斯'的安装目录\n" -"包å«äº† ';' (分å·).\n\n" -"如果您有过对付 MTA:SA 问题的ç»éªŒ,\n" -"请移动你的安装目录到一个没有包å«åˆ†å·çš„目录." - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "载入失败.请确ä¿ä½ æœ€æ–°çš„æ•°æ®æ–‡ä»¶å·²ç»æ­£ç¡®å®‰è£…" -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "载入失败.è¯·ç¡®ä¿ %s å·²ç»æ­£ç¡®å®‰è£…" -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "载入失败. 无法在 %s é‡Œå®šä½ gta_sa.exe." -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "载入失败. %s 在GTA目录已ç»å­˜åœ¨.请在继续å‰åˆ é™¤" -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "ä¸»æ–‡ä»¶å«æœ‰é”™è¯¯åç§°(%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "主文件未被签å. 出现本问题有å¯èƒ½æ˜¯ç—…毒导致的.\n\n" -"è‹¥MTA无法正常è¿è¡Œè¯·æŸ¥çœ‹åœ¨çº¿å¸®åŠ©." - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "æ•°æ®æ–‡ä»¶ %s 丢失,有å¯èƒ½æ˜¯ç—…毒引起的。\n\n" -"è¯·è€ƒè™‘é‡æ–°å®‰è£…Multi Theft Auto以确ä¿ä½ çš„安全。\n" -"如果MTA无法正常工作,请查看在线帮助。" - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "æ•°æ®æ–‡ä»¶ %s 已被修改,å¯èƒ½æ˜¯ç—…毒引起的。\n\n" -"è¯·è€ƒè™‘é‡æ–°å®‰è£…Multi Theft Auto以确ä¿ä½ çš„安全。\n" -"如果MTA无法正常工作,请查看在线帮助。" - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asi 文件存在于 'MTA:SA' 或 '侠盗猎车手: 圣安地列斯' 的安装目录.\n\n" -"如果è¿è¡ŒMTA:SAæ—¶é‡åˆ°äº†é—®é¢˜è¯·åˆ é™¤è¿™äº› .asi 文件." - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "文件版本ä¸åŒ¹é…导致出错.å¦‚æžœæ¸¸æˆæ—¶é‡åˆ°äº†é—®é¢˜è¯·é‡æ–°å®‰è£…MTA:SA.\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "缺少部分文件. å¦‚æžœåœ¨æ¸¸æˆæ—¶é‡åˆ°äº†é—®é¢˜è¯·é‡æ–°å®‰è£…MTA:SA.\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA 与Windows的安全模å¼ä¸å…¼å®¹.\n\n" -"请é‡å¯ä½ çš„电脑.\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "ä¿®å¤é…置文件问题" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "ä¿®å¤é«˜ç¨‹è¦æ±‚错误" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" + +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "未知" + +#: Client/loader/Install.cpp:272 +#, c-format +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "文件 '%s' 当å‰è¢« %zu 个进程é”定。\n\n" +"你想è¦ç»ˆæ­¢ä»¥ä¸‹è¿›ç¨‹å¹¶ç»§ç»­æ›´æ–°å—?\n\n" +"%s" + +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "你的安装现å¯èƒ½å·²æŸå。\n\n" +"%zu 个文件中有 %zu 个无法从备份中æ¢å¤ã€‚\n\n" +"你应该从www.multitheftauto.com釿–°Multi Theft Auto\n" +"或å°è¯•以管ç†å‘˜æƒé™è¿è¡Œæ›´æ–°ã€‚" + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "安装更新中..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "解压文件中..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA 无法完æˆä»¥ä¸‹ä»»åŠ¡:\n\n" +"'%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** 崩溃的原因为显å¡é”™è¯¯ **\n\n" +"** 请更新驱动 **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "安装已更新的 MTA:SA 文件" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "本次更新由于文件冲çªå¯¼è‡´å¤±è´¥. 请关掉其他程åºåŽå†è¯•" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "Multi Theft Auto 没有被正确安装, è¯·é‡æ–°å®‰è£…. %s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "创建GTA:SA链接" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA无法å¯åŠ¨ï¼Œå› ä¸ºå¤åˆ¶æ–‡ä»¶å¤±è´¥ï¼š" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA无法å¯åŠ¨ï¼Œå› ä¸ºMTA:SAæ–‡ä»¶ä¸æ­£ç¡®æˆ–缺失:" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "å¤åˆ¶MTA:SA文件" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA无法å¯åŠ¨ï¼Œå› ä¸ºGTA:SAæ–‡ä»¶ä¸æ­£ç¡®æˆ–缺失:" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "ä¿®å¤GTA:SAè¿è¡Œåº“" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA无法å¯åŠ¨ï¼Œå› ä¸ºGTA:SA程åºä¸æ­£ç¡®æˆ–缺失:" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "è¯·æ£€æŸ¥ä½ çš„é˜²ç—…æ¯’è½¯ä»¶æ˜¯å¦æœ‰è¯¯æŠ¥ï¼Œå¦‚有请将GTA:SA加入白åå•,并é‡å¯MTA:SA。" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "生æˆGTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA无法å¯åŠ¨ï¼Œå› ä¸ºæ— æ³•åŠ è½½GTA:SA程åºï¼š" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "ä¿®å¤GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA无法å¯åŠ¨ï¼Œå› ä¸ºä¿®å¤GTA:SA失败:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "无法å¯åЍ GTA:SA. 请å°è¯•釿–°å¯åЍ, 如果问题æŒç»­å­˜åœ¨,请è”ç³» MTA, 地å€ä¸º www.multitheftauto.com. \n\n" -"[%s]" +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "由于驱动器 %s 没有足够的空间,MTA:SA 无法继续è¿è¡Œ." -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "侠盗猎车手: 圣安地列斯没有正常å¯åЍ.你想è¦å…³é—­å®ƒå—?" +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "缺少以下文件:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "è‹¥MTAåŠ è½½å¤±è´¥ï¼Œè¯·é‡æ–°å®‰è£…GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "更新安装设置" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "更新兼容性设置" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +483,167 @@ msgstr "侠盗猎车手: 圣安地列斯没有正常å¯åЍ.你想è¦å…³é—­å®ƒå— #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "是" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "å¦" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "确定" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "退出" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "帮助" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "å–æ¶ˆ" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas é‡åˆ°äº†é—®é¢˜" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "崩溃信æ¯" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "勾选本选项以使用‘互è”网’将本崩溃信æ¯å‘é€åˆ°MTAå¼€å‘团队" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "这样åšå¯ä»¥å¢žåŠ ä¿®å¤æ­¤å´©æºƒçš„æœºä¼šã€‚" -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "您想è¦é‡æ–°å¯åЍMTA: San Andreas å—?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas - 警告" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "你的《侠盗猎车手:圣安地列斯》安装目录包å«è¿™äº›æ–‡ä»¶ï¼š" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "è¿™äº›æ–‡ä»¶ä¸æ˜¯å¿…需的,å¯èƒ½ä¼šå¹²æ‰°è¿™ä¸ªç‰ˆæœ¬çš„ MTA:SA 中的图形功能。\n\n" "建议你删除或é‡å‘½å这些文件。" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "ä¿ç•™è¿™äº›æ–‡ä»¶ï¼Œä½†ä¸‹æ¬¡å¯åŠ¨æ—¶ä¹Ÿæ˜¾ç¤ºæ­¤è­¦å‘Š" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "ä¸è¦å†æé†’我这些文件了" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "将这些文件从 *.dll é‡å‘½å为 *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "显示这些文件" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "å¯åЍ MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas - 䏿˜Žç¡®çš„选项" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "æ£€æµ‹åˆ°æ˜¾å¡æ”¯æŒNVidia Optimus技术!" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "å°è¯•æ¯ä¸€ä¸ªé€‰é¡¹å†çœ‹å“ªç§æ¨¡å¼å¯ä»¥æ­£å¸¸è¿è¡Œ:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - 标准 NVidia 模å¼" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - 备用 NVidia 模å¼" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - 标准 Intel 模å¼" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - 备用 Intel 模å¼" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "如果以上模å¼éƒ½æ²¡æ³•çŽ©è®©ä½ ç—›ä¸æ¬²ç”Ÿ, è¿™ä¸ªæ¨¡å¼æˆ–许能拯救你:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "如果你已ç»é€‰æ‹©äº†ä¸€ä¸ªæœ‰æ•ˆçš„选项,这å¯èƒ½ä¼šæœ‰å¸®åŠ©ï¼š" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "强制窗å£åŒ–模å¼" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "ä¸å†æç¤º" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "警告:没有检测出å病毒软件" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1107 +651,1180 @@ msgstr "MTA 没有在当å‰è®¡ç®—机检测出å病毒软件.\n\n" "è®¡ç®—æœºç—…æ¯’ä¼šå½±å“ MTA 以åŠé™ä½Žä½ çš„æ¸¸æˆä½“验\n\n" "点击 '帮助' 以获得更多信æ¯." -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "æˆ‘å·²å®‰è£…æ€æ¯’软件" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "朕æ‰ä¸å®‰è£…å病毒软件.\n" "朕就喜欢慢点的电脑顺便æˆä¸ºåƒµå°¸ç½‘络的一份å­." -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "æœç´¢Grand Theft Auto: San Andreas" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "请å¯åЍGrand Theft Auto San Andreas" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "安装更新中..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "连接失败。使用了ä¸å¯ç”¨çš„æ˜µç§°!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "解压文件中..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "连接失败。æœåŠ¡å™¨åœ°å€æ— æ•ˆ!" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "å¤åˆ¶æ–‡ä»¶..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "连接 %s æ‰€åœ¨ç«¯å£ %u 失败!" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "文件æå‰å¤åˆ¶å®Œæ¯•.æ‰€æœ‰æ•°æ®æ­£å¸¸." +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "正在连接到 %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "正在完æˆ..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "" -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "已完æˆ!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "连接中" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA 需è¦ç®¡ç†å‘˜æƒé™è¿è¡Œä»¥ä¸‹ä»»åŠ¡:\n\n" -" '%s'\n\n" -"请在下一个窗å£ä¸­ç¡®è®¤æŒ‡ä»¤." +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "连接已超时" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA 无法完æˆä»¥ä¸‹ä»»åŠ¡:\n\n" -"'%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "已断开连接: 未知å议错误" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** 崩溃的原因为显å¡é”™è¯¯ **\n\n" -"** 请更新驱动 **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "已断开连接: æœåŠ¡å™¨ä¸»åŠ¨æ–­å¼€è¿žæŽ¥" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "安装已更新的 MTA:SA 文件" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "已断开连接: 与æœåŠ¡å™¨è¿žæŽ¥ä¸­æ–­" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "本次更新由于文件冲çªå¯¼è‡´å¤±è´¥. 请关掉其他程åºåŽå†è¯•" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "已断开连接: 你已被该æœåС噍å°ç¦ (Banned)" + +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "已断开连接: 从æœåŠ¡å™¨æ–­å¼€è¿žæŽ¥" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "已断开连接: 与æœåŠ¡å™¨çš„è¿žæŽ¥å·²ä¸­æ–­" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "已断开连接: æœåŠ¡å™¨æ‹’ç»è¿žæŽ¥" -#: Client/loader/CInstallManager.cpp:561 +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "Multi Theft Auto 没有被正确安装, è¯·é‡æ–°å®‰è£…. %s" +msgid "No such mod installed (%s)" +msgstr "未安装指定的 Mod (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "创建GTA:SA链接" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "æ„外的æœåС噍å“应 (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA无法å¯åŠ¨ï¼Œå› ä¸ºå¤åˆ¶æ–‡ä»¶å¤±è´¥ï¼š" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "æ„外的æœåС噍å“应 (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA无法å¯åŠ¨ï¼Œå› ä¸ºMTA:SAæ–‡ä»¶ä¸æ­£ç¡®æˆ–缺失:" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "简体中文" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "å¤åˆ¶MTA:SA文件" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "正忙" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA无法å¯åŠ¨ï¼Œå› ä¸ºGTA:SAæ–‡ä»¶ä¸æ­£ç¡®æˆ–缺失:" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "å½“å‰æš‚æ—¶æ— æ³•检查更新" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "ä¿®å¤GTA:SAè¿è¡Œåº“" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "è¦æ±‚ MTA:SA %s" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA无法å¯åŠ¨ï¼Œå› ä¸ºGTA:SA程åºä¸æ­£ç¡®æˆ–缺失:" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "该æœåŠ¡å™¨éœ€è¦æ›´é«˜çš„ MTA:SA %s 版本.\n\n" +"你希望下载并且安装 MTA:SA %s å—?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "è¯·æ£€æŸ¥ä½ çš„é˜²ç—…æ¯’è½¯ä»¶æ˜¯å¦æœ‰è¯¯æŠ¥ï¼Œå¦‚有请将GTA:SA加入白åå•,并é‡å¯MTA:SA。" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "你希望å¯åЍ MTA:SA %s 并连接到此æœåŠ¡å™¨å— ?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "生æˆGTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "ç³»ç»Ÿå½“å‰æ— æ³•连接.\n\n" +"请ç¨åŽå†è¯•." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA无法å¯åŠ¨ï¼Œå› ä¸ºæ— æ³•åŠ è½½GTA:SA程åºï¼š" +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "正在连接" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "ä¿®å¤GTA:SA" +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "请ç¨å€™..." -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA无法å¯åŠ¨ï¼Œå› ä¸ºä¿®å¤GTA:SA失败:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "检查中" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "由于驱动器 %s 没有足够的空间,MTA:SA 无法继续è¿è¡Œ." +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "检查更新" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "缺少以下文件:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "无最新更新" -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "è‹¥MTAåŠ è½½å¤±è´¥ï¼Œè¯·é‡æ–°å®‰è£…GTA:SA" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "下载中" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "更新安装设置" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "正在等待..." -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "更新兼容性设置" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "强制更新" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "未知" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "æ‚¨éœ€è¦æ›´æ–°MTA版本以登录该æœåС噍.\n\n" +"你想现在更新å—?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "文件 '%s' 当å‰è¢« %zu 个进程é”定。\n\n" -"你想è¦ç»ˆæ­¢ä»¥ä¸‹è¿›ç¨‹å¹¶ç»§ç»­æ›´æ–°å—?\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "å¯é€‰æ›´æ–°" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "你的安装现å¯èƒ½å·²æŸå。\n\n" -"%zu 个文件中有 %zu 个无法从备份中æ¢å¤ã€‚\n\n" -"你应该从www.multitheftauto.com釿–°Multi Theft Auto\n" -"或å°è¯•以管ç†å‘˜æƒé™è¿è¡Œæ›´æ–°ã€‚" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "æœåŠ¡å™¨ç§°æŽ¨èæ›´æ–°ç‰ˆæœ¬, 但并ä¸å¼ºåˆ¶æ›´æ–°.\n\n" +"ä½ æƒ³çŽ°åœ¨æ›´æ–°å— ?" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" msgstr "" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "ä¿å­˜é”™è¯¯" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "未能创建文件" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "请选择 侠盗猎车手:圣安地列斯的安装目录" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "下载错误" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "åœ¨è¯»å– %s æ¨¡å—æ—¶å‡ºé”™! (%s)" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "ä¸‹è½½çš„æ–‡ä»¶æ ¡æ£€ä¸æ­£ç¡®" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "检测到最近安装的 %s.\n\n" -"你想把é…置文件从%så¤åˆ¶åˆ°è¿™é‡Œå—?" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "由于æŸäº›åŽŸå› ." -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA 在打开 '%s' 文件时é‡åˆ°é—®é¢˜." +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "下载完毕" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA 缺少 '%s' 文件." +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr " - 在 _DialogUpdateResult 出现未知错误" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA 在加载模型文件时é‡åˆ°é—®é¢˜." +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "定制的 GTA:SA 文件" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "如果您最近修改了gta3.img,请å°è¯•釿–°å®‰è£…GTA:SA。" +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "确定" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA 在改装车辆时é‡åˆ°é—®é¢˜." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "错误" -#: Client/loader/Utils.cpp:1631 -#, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA 在以下文件找到错误 '%s'" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "部分 MTA:SA æ•°æ®æ–‡ä»¶å·²ä¸¢å¤±.\n\n\n" +"è¯·é‡æ–°å®‰è£… MTA:SA" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "你在è¿è¡ŒMTA:SA的时候é‡å¯ç”µè„‘了å—?" +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% 完æˆ" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "请在è¿è¡Œå‰å…³é—­ä»¥ä¸‹ç¨‹åº:" +#: Client/core/CVersionUpdater.cpp:2840 +#, c-format +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"等待å“应 - %-3d" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "网站请求" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ 指令帮助 ]***\n" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "本æœåŠ¡å™¨éœ€è¦ï¼ˆç¨åŽï¼‰åŠ è½½å¦‚ä¸‹ç½‘ç«™ï¼š" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* 当剿—¶é—´ä¸º %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "è¯·å‹¿è¾“å…¥æ•æ„Ÿä¿¡æ¯ï¼Œè°¨é˜²æ³„密" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "è®°ä½é€‰é¡¹" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "连接: 指令为 'connect <æœåŠ¡å™¨åœ°å€> [<端å£> <昵称> <密ç >]'" -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "å…许" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "连接: 无效的端å£å·" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "æ‹’ç»" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "连接: 正在连接到 %s:%u..." -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "主èœå•" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "连接: 无法连接到 %s:%u!" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "æ‚¨å½“å‰æ­£åœ¨ä½¿ç”¨ä¸€ä¸ªåˆ†æ”¯ç‰ˆæœ¬çš„å®¢æˆ·ç«¯ï¼æµ‹è¯•版本的客户端ä¸èƒ½è¢«ç”¨æ¥è¿žæŽ¥å…¬å…±æœåС噍ï¼" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "连接: å¸è½½å½“å‰ mod 失败" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA将在2019å¹´7月之åŽä¸å†æ”¯æŒXP/Vista。\n\n" -"å‡çº§Windows以在最新æœåŠ¡å™¨ä¸Šè¿›å…¥æ¸¸æˆã€‚" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "" -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "è¿™å°†ä¼šä½¿ä½ æ–­å¼€ä¸Žå½“å‰æœåŠ¡å™¨çš„è¿žæŽ¥ã€‚\n\n" -"ä½ ç¡®å®šè¦æ–­å¼€è¿žæŽ¥å—?" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "断开连接警告" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" msgstr "" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "简体中文" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "绑定 GTA 所有的控制设置" + +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "å·²ä¿å­˜çš„é…置文件" + +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* 您的åºåˆ—å·ä¸º : %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "设置" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "多人游æˆ" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "视频" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "音频" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "绑定" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "控制" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "界é¢" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "网页æµè§ˆå™¨" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "高级" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "读å–默认值" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "é¼ æ ‡çµæ•度:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "åž‚ç›´çž„å‡†çµæ•度:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "鼠标选项" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "鼠标垂直å转" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "用鼠标控制驾驶" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "使用鼠标飞行" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "手柄设置" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "标准控制 (é¼ æ ‡ + 键盘)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "ç»å…¸æŽ§åˆ¶ (手柄)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "盲区" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "饱和度" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "å°†'绑定'标签用于手柄按键。" -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "手柄 左方å‘" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "手柄 峿–¹å‘" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "说明" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "按键" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. 按键" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "昵称:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "ä¿å­˜æœåС噍坆ç " -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "自动刷新æœåС噍æµè§ˆå™¨" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "å…许上传å±å¹•ç”»é¢" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "å…许外部声音" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "始终显示下载窗å£" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "å…许通过Discord Rich Presence连接" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "使用定制的 GTA:SA 文件" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "地图渲染选项" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "ä¸é€æ˜Žåº¦:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "主音é‡ï¼š" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "电å°éŸ³é‡:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "音效音é‡:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA 音é‡:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "语音音é‡:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "æ¸¸æˆæ¨¡å¼:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "常规" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "电å°é€‰é¡¹" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "电å°å‡è¡¡å™¨" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "默认电å°" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "用户本地电å°é€‰é¡¹" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "收音机" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "éšæœº" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "顺åº" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "自动扫æåª’体文件" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "é™éŸ³é€‰é¡¹" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "最å°åŒ–æ—¶é™éŸ³æ‰€æœ‰å£°éŸ³" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "å½“çª—å£æœ€å°åŒ–æ—¶å±è”½ç”µå°éŸ³ä¹" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "å½“çª—å£æœ€å°åŒ–æ—¶å±è”½æ¸¸æˆéŸ³æ•ˆ" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "å½“çª—å£æœ€å°åŒ–æ—¶å±è”½ MTA 音效" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "å½“çª—å£æœ€å°åŒ–æ—¶å±è”½è¯­éŸ³" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "分辨率:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "FOV:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "显示è·ç¦»:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "亮度:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "效果质é‡:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "å„å‘异性过滤:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "抗锯齿:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "纵横比:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "çª—å£æ¨¡å¼" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI感知" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "标准" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "ä¿æŒæ— è¾¹æ¡†çª—å£" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "多é‡ç»†èŠ‚å±‚çº¹ç† (Mip Mapping)" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "低" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "中" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "高" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "éžå¸¸é«˜" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "å…³" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1x" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2x" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3x" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "自动" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD与显示纵横比相匹é…" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "体积阴影" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "è‰åœ°æ•ˆæžœ" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "热浪" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "轮胎烟雾等" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "动æ€è¡Œäººé˜´å½±" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "åŠ¨æ€æ¨¡ç³Š" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "光晕雨åå°„" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "å…¨å±å¹•最å°åŒ–" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "å¯ç”¨è®¾å¤‡é€‰æ‹©å¯¹è¯æ¡†" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "显示ä¸å®‰å…¨çš„分辨率" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "总是以高细节渲染载具" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "总是以高细节渲染人物" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "å¯ç”¨è¿œç¨‹ç½‘ç«™" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "在远程网站å¯ç”¨Javascript" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "自定义黑åå•" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "请输入域å 例:google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "阻止" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "域å" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "移除域å" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "自定义白åå•" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "å…许" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "其它" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "快速载入CJæœè£…:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "æµè§ˆå™¨é€Ÿåº¦:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "å•程连接:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "æ•°æ®åŒ…标签:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "进度动画:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "进程优先级:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "Debug 设置:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "æµåª’体缓存:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "更新构建类型:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "安装é‡è¦æ›´æ–°ï¼š" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "å¼€" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "éžå¸¸æ…¢" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "默认" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "å¿«" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "正常" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "高于正常" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "最低" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "最高" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 兼容模å¼:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16ä½è‰²" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "鼠标修正" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "å®¢æˆ·ç«¯èµ„æºæ–‡ä»¶ï¼š" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "在系统资æºç®¡ç†å™¨ä¸­æ˜¾ç¤º" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "自动更新" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "ç«‹å³æ£€æŸ¥æ›´æ–°" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "一些设置将会在您下次å¯åЍMTA时生效" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "你想现在é‡å¯å—?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "需è¦é‡æ–°å¯åЍ" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "当你退出本æœåŠ¡å™¨æ—¶æœ‰äº›è®¾ç½®å°†ä¼šæ”¹å˜" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "çŽ°åœ¨æƒ³è¦æ–­å¼€è¿žæŽ¥å—?" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "éœ€è¦æ–­å¼€æœåŠ¡å™¨è¿žæŽ¥" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "æœªèƒ½æ£€æµ‹åˆ°æ¸¸æˆæ‰‹æŸ„ - 请检查手柄连接以åŠé‡å¯æ¸¸æˆ" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "ç»‘å®šåæ ‡è½´" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "移动一个轴æ¥ç»‘定,或者离开以清除绑定" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "语言:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "皮肤:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "预设:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "èŠå¤©" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "载入" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "颜色" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "布局" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "选项" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "èŠå¤©èƒŒæ™¯" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "èŠå¤©æ–‡å­—" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "输入背景" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "输入文本" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "行:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "比例:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "宽度:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "大å°" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "åŽ" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "于" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "ç§’" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "淡化" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "淡出旧行数" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "水平:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "垂直:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "水平对é½ï¼š" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "Xè½´å移:" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Yè½´å移:" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "ä½ç½®" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "左移" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "中心" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "å³ç§»" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "顶部" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "底部" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "字体" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "ä¸è¾“入文字时éšè—背景" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "请按下 “Tabâ€å®Œæˆæ˜µç§°è¾“å…¥" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "å…许æœåŠ¡å™¨åˆ·æ–°çª—å£" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "å…许气泡显示通知" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "èŠå¤©æ–‡æœ¬é»‘白æè¾¹" @@ -1548,112 +1832,116 @@ msgstr "èŠå¤©æ–‡æœ¬é»‘白æè¾¹" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "输入你è¦ç»‘定的按键, 或离开以清除绑定" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "绑定一个主键" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "ç»‘å®šä¸€ä¸ªæ¬¡è¦æŒ‰é”®" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTA å†…ç½®æ¸¸æˆæŽ§åˆ¶" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "å¤šäººæ¸¸æˆæŽ§åˆ¶" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "你的昵称包å«éžæ³•字符!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "主èœå•" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "游æˆä¸­" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "红:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "绿:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "è“:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "逿˜Žåº¦:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "颜色" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "预览" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "请在更æ¢çš®è‚¤å‰æ–­å¼€æœåŠ¡å™¨çš„è¿žæŽ¥" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "请在更æ¢çš®è‚¤å‰æ–­å¼€æœåŠ¡å™¨çš„è¿žæŽ¥" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "多é‡é˜´å½±å°†ä¼šå¯¼è‡´éƒ¨åˆ†ç³»ç»Ÿé€Ÿåº¦ä¸‹é™.\n\n" "你确定è¦å¯ç”¨è¿™ä¸ªåŠŸèƒ½å—?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "性能警告" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "一些æœåŠ¡å™¨å°†ä¼šä»¥åä½œå¼Šçš„åŽŸå› è¦æ±‚使用上传å±å¹•功能.\n\n" "(èŠå¤©æ¡†å’ŒGUI界é¢å°†ä¸ä¼šè¢«ä¸Šä¼ )\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "å±å¹•上传信æ¯" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" msgstr "æŸäº›è„šæœ¬å¯èƒ½ä¼šä»Žäº’è”网播放声音,如电å°ç­‰ã€‚\n\n" "ç¦ç”¨æ­¤è®¾ç½®å¯èƒ½ä¼šå‡å°‘网络å ç”¨ã€‚\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "外部声音" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "你似乎已å¯ç”¨äº†Rich Presence连接选项。\n" -"你想å…许æœåŠ¡å™¨å…±äº«å®ƒä»¬çš„æ•°æ®å—?\n\n" -"这包括你的唯一ID标识符。" +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "åŒæ„æ•°æ®å…±äº«" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1663,11 +1951,7 @@ msgstr "有些文件在你的GTA:SAæ•°æ®ç›®å½•是定制的.\n" "但是,定制的GTA:SA文件被许多æœåŠ¡å™¨è¿‡æ»¤\n\n" "你确定你想使用它们å—?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "定制的 GTA:SA 文件" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1677,550 +1961,252 @@ msgstr "å¯ç”¨DPI感知是一个实验性功能,\n" "如果å¯ç”¨æ­¤é€‰é¡¹ï¼Œä½ å¯èƒ½ä¼šé‡åˆ°å›¾å½¢é—®é¢˜ã€‚\n\n" "你确定è¦å¯ç”¨æ­¤é€‰é¡¹å—?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "实验性功能" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "请输入一个昵称" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "请输入一个在游æˆé‡Œé¢ä½¿ç”¨çš„æ˜µç§° \n" " 这将会在你登陆æœåŠ¡å™¨æ—¶æ˜¾ç¤º" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "大é‡å®žéªŒæ€§åŠŸèƒ½." -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "åœæ­¢CJ的跳舞命令 (将会增加65MB内存å ç”¨)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "比较è€çš„è·¯ç”±ä¼šé™æ…¢æ‰«æçš„速度" -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "打开将会å¯ç”¨å•线程下载" -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "标记网络包以帮助ISP识别MTAæµé‡" -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "在å±å¹•底部显示旋转圈圈动画" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "总是设为默认值. (ä¸ä¿å­˜è®¾ç½®)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "数值最大通常是最好的" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "自动更新:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "如果你喜欢å‘é€é”™è¯¯æŠ¥å‘Šå°±å¯ä»¥ä¸é€‰æ‹©é»˜è®¤." -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "选项默认安装é‡è¦æ›´æ–°" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16ä½è‰²" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "å¯åЍ16ä½è‰²æ¨¡å¼ -需è¦é‡å¯MTA" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "鼠标修正:" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "鼠标移动修正 - å¯èƒ½éœ€è¦é‡å¯è®¡ç®—机" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "未知的命令或控制å°å˜é‡:" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "正忙" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "å½“å‰æš‚æ—¶æ— æ³•检查更新" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "è¦æ±‚ MTA:SA %s" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "该æœåŠ¡å™¨éœ€è¦æ›´é«˜çš„ MTA:SA %s 版本.\n\n" -"你希望下载并且安装 MTA:SA %s å—?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "你希望å¯åЍ MTA:SA %s 并连接到此æœåŠ¡å™¨å— ?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "ç³»ç»Ÿå½“å‰æ— æ³•连接.\n\n" -"请ç¨åŽå†è¯•." - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "正在连接" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "请ç¨å€™..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "检查中" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "检查更新" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "无最新更新" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "下载中" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "正在等待..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "强制更新" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "æ‚¨éœ€è¦æ›´æ–°MTA版本以登录该æœåС噍.\n\n" -"你想现在更新å—?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "å¯é€‰æ›´æ–°" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "æœåŠ¡å™¨ç§°æŽ¨èæ›´æ–°ç‰ˆæœ¬, 但并ä¸å¼ºåˆ¶æ›´æ–°.\n\n" -"ä½ æƒ³çŽ°åœ¨æ›´æ–°å— ?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "ä¿å­˜é”™è¯¯" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "未能创建文件" - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "下载错误" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "ä¸‹è½½çš„æ–‡ä»¶æ ¡æ£€ä¸æ­£ç¡®" - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "由于æŸäº›åŽŸå› ." - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "下载完毕" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr " - 在 _DialogUpdateResult 出现未知错误" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "确定" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "错误" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "部分 MTA:SA æ•°æ®æ–‡ä»¶å·²ä¸¢å¤±.\n\n\n" -"è¯·é‡æ–°å®‰è£… MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% 完æˆ" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"等待å“应 - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "连接失败。使用了ä¸å¯ç”¨çš„æ˜µç§°!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "连接失败。æœåŠ¡å™¨åœ°å€æ— æ•ˆ!" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "连接 %s æ‰€åœ¨ç«¯å£ %u 失败!" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "正在连接到 %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "" - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "连接中" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "连接已超时" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "已断开连接: 未知å议错误" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "已断开连接: æœåŠ¡å™¨ä¸»åŠ¨æ–­å¼€è¿žæŽ¥" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "已断开连接: 与æœåŠ¡å™¨è¿žæŽ¥ä¸­æ–­" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "已断开连接: 你已被该æœåС噍å°ç¦ (Banned)" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "已断开连接: 从æœåŠ¡å™¨æ–­å¼€è¿žæŽ¥" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "已断开连接: 与æœåŠ¡å™¨çš„è¿žæŽ¥å·²ä¸­æ–­" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "已断开连接: æœåŠ¡å™¨æ‹’ç»è¿žæŽ¥" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "未安装指定的 Mod (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "æ„外的æœåС噍å“应 (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "æ„外的æœåС噍å“应 (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "最新动æ€" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "查看最新动æ€" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "控制å°" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "致命错误" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "请移除该文件修å¤é—®é¢˜ï¼š" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "æ¨¡å— %s ä¸é€‚用!" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "执行 URL 时出错" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "此帮助画é¢" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "退出程åº" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "显示版本å·" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "显示时间" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "显示 HUD 界é¢" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "显示所有绑定设置" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "显示你的åºåˆ—å·" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "连接到一个æœåС噍 (æœåС噍 ç«¯å£ æ˜µç§° 密ç )" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "连接到之å‰ç™»é™†è¿‡çš„æœåŠ¡å™¨" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "绑定一个按键 (控制键)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "å–æ¶ˆç»‘定按键 (key)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" msgstr "å¤åˆ¶é»˜è®¤çš„ GTA 控制按键设置" -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "输出截图" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "立刻ä¿å­˜è®¾ç½®" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "清空调试视图" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "å‘上滚动èŠå¤©æ¡†" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "å‘下滚动èŠå¤©æ¡†" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "å‘上滚动调试视图" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "å‘下滚动调试视图" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "显示内存统计信æ¯" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "显示帧数图表" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "å¼€å‘è€…åŠŸèƒ½ï¼šé‡æ–°åŠ è½½æœ€æ–°åŠ¨æ€" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ 指令帮助 ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* 当剿—¶é—´ä¸º %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "连接: 指令为 'connect <æœåŠ¡å™¨åœ°å€> [<端å£> <昵称> <密ç >]'" - -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "连接: 无效的端å£å·" +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "输出截图" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "连接: 正在连接到 %s:%u..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "立刻ä¿å­˜è®¾ç½®" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "连接: 无法连接到 %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "清空调试视图" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "连接: å¸è½½å½“å‰ mod 失败" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "å‘上滚动èŠå¤©æ¡†" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "å‘下滚动èŠå¤©æ¡†" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "å‘上滚动调试视图" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "" +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "å‘下滚动调试视图" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "显示内存统计信æ¯" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "绑定 GTA 所有的控制设置" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "显示帧数图表" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "å·²ä¿å­˜çš„é…置文件" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "å¼€å‘è€…åŠŸèƒ½ï¼šé‡æ–°åŠ è½½æœ€æ–°åŠ¨æ€" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* 您的åºåˆ—å·ä¸º : %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "æ‚¨å½“å‰æ­£åœ¨ä½¿ç”¨ä¸€ä¸ªåˆ†æ”¯ç‰ˆæœ¬çš„å®¢æˆ·ç«¯ï¼æµ‹è¯•版本的客户端ä¸èƒ½è¢«ç”¨æ¥è¿žæŽ¥å…¬å…±æœåС噍ï¼" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "加速轴" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA将在2019å¹´7月之åŽä¸å†æ”¯æŒXP/Vista。\n\n" +"å‡çº§Windows以在最新æœåŠ¡å™¨ä¸Šè¿›å…¥æ¸¸æˆã€‚" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "制动轴" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "è¿™å°†ä¼šä½¿ä½ æ–­å¼€ä¸Žå½“å‰æœåŠ¡å™¨çš„è¿žæŽ¥ã€‚\n\n" +"ä½ ç¡®å®šè¦æ–­å¼€è¿žæŽ¥å—?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "程åºå¼€å‘" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "断开连接警告" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "贡献者" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "游æˆè®¾è®¡ / 脚本编写员" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "最新动æ€" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "本地化翻译" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "查看最新动æ€" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "è¡¥ä¸è´¡çŒ®è€…" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "æˆªå›¾åŒ…å« %d 个字节,但实际预期为 %d" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "特别鸣谢" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "截图失败" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "本软件和项目使用了以下库和软件:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "已截图: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "ä½ æƒ³è¦æŸ¥çœ‹å…³äºŽè¿™ä¸ªé—®é¢˜çš„在线帮助å—?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "未知的命令或控制å°å˜é‡:" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2395,25 +2381,56 @@ msgid "Group control backwards" msgstr "å°ç»„控制 åŽé€€" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "您选定的皮肤以åŠç³»ç»Ÿé»˜è®¤çš®è‚¤å‡æ— æ³•è½½å…¥ï¼Œè¯·é‡æ–°å®‰è£… MTA 。" -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "æˆªå›¾åŒ…å« %d 个字节,但实际预期为 %d" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "ä½ æƒ³è¦æŸ¥çœ‹å…³äºŽè¿™ä¸ªé—®é¢˜çš„在线帮助å—?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "截图失败" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "控制å°" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "已截图: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "程åºå¼€å‘" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "贡献者" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "游æˆè®¾è®¡ / 脚本编写员" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "本地化翻译" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "è¡¥ä¸è´¡çŒ®è€…" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "特别鸣谢" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "本软件和项目使用了以下库和软件:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "加速轴" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "制动轴" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2421,6 +2438,59 @@ msgstr "无法åˆå§‹åŒ– Direct3D9 。\n\n" "请确认您已正确安装了 DirectX 最终用户è¿è¡Œæ—¶ä»¥åŠ\n" "最新的系统更新包。" +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "空闲" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "个玩家个玩家" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "于" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "个æœåŠ¡å™¨ä¸ªæœåС噍" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "查询主æœåŠ¡å™¨åˆ—è¡¨ (已花费 %lu 毫秒)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "主æœåŠ¡å™¨åˆ—è¡¨æ— æ³•è§£æžã€‚" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "主æœåŠ¡å™¨åˆ—è¡¨æ— æ³•æ£€ç´¢ã€‚" + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(备份æœåŠ¡å™¨åˆ—è¡¨)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "无法绑定局域网广播套接字 (LAN-broadcast socket)" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "正在å°è¯•æœç´¢å±€åŸŸç½‘内的æœåС噍" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2474,7 +2544,7 @@ msgstr "传输延迟:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "玩家列表" @@ -2501,40 +2571,39 @@ msgstr "当æœåŠ¡å™¨æœ‰ç©ºä½æ—¶è¿›å…¥ã€‚" msgid "PLEASE ENTER SERVER PASSWORD" msgstr "请输入æœåС噍坆ç " -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "已超时" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "正在查询..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "æœåС噍æµè§ˆå™¨" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "互è”网" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "本地" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "æ”¶è—夹" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "最近" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2542,296 +2611,367 @@ msgstr "快速链接:\n\n" "è¯·åœ¨åœ°å€æ é‡Œè¾“å…¥æœåŠ¡å™¨åœ°å€åŠç«¯å£å·ã€‚\n" "或者在历å²è®°å½•里选择æœåŠ¡å™¨å¹¶ä¸”ç‚¹å‡» '连接'" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "帮助" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "刷新" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "添加到收è—夹" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "连接" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "æœåŠ¡å™¨ä¿¡æ¯" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "æœç´¢æœåС噍" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "æœç´¢çީ家" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "开始æœç´¢" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "æœç´¢çީ家䏭..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "æœç´¢æœåС噍䏭..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "åç§°" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "玩家数" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "网络延迟" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "æ¸¸æˆæ¨¡å¼" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "包å«:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "空" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "满" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "已上é”" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "离线" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "其他版本" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "返回" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "载入中..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "..载入中.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "未指定æœåŠ¡å™¨åœ°å€!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "未知åè®®" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "请使用 mtasa:// å议格å¼!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "无效的昵称! 请去设置画é¢é‚£é‡Œè®¾å®šä¸€ä¸ªæ–°æ˜µç§°!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "你需è¦é€‰æ‹©ä¸€ä¸ªæœåС噍æ¥è¿žæŽ¥ã€‚" -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "空闲" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "显å¡é©±åŠ¨å‡ºçŽ°é—®é¢˜" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "个玩家个玩家" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "无法找到有效的å±å¹•分辨率." -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "于" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "您确定è¦ä½¿ç”¨è¿™ä¸ªåˆ†è¾¨çއå—?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "个æœåŠ¡å™¨ä¸ªæœåС噍" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "查询主æœåŠ¡å™¨åˆ—è¡¨ (已花费 %lu 毫秒)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "主æœåŠ¡å™¨åˆ—è¡¨æ— æ³•è§£æžã€‚" +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "网站请求" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "主æœåŠ¡å™¨åˆ—è¡¨æ— æ³•æ£€ç´¢ã€‚" +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "本æœåŠ¡å™¨éœ€è¦ï¼ˆç¨åŽï¼‰åŠ è½½å¦‚ä¸‹ç½‘ç«™ï¼š" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(备份æœåŠ¡å™¨åˆ—è¡¨)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "è¯·å‹¿è¾“å…¥æ•æ„Ÿä¿¡æ¯ï¼Œè°¨é˜²æ³„密" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "无法绑定局域网广播套接字 (LAN-broadcast socket)" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "è®°ä½é€‰é¡¹" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "正在å°è¯•æœç´¢å±€åŸŸç½‘内的æœåС噍" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "æ‹’ç»" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "此版本已ç»è¿‡æœŸ" -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "从æœåŠ¡å™¨æ–­å¼€è¿žæŽ¥" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "显示用户标签" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "显示èŠå¤©æ¡†" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "显示网络统计信æ¯" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "打开èŠå¤©è¾“入框" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "与其他玩家å‘é€è¯­éŸ³" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "以乘员方å¼è¿›å…¥è½¦è¾†" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "下一雷达频é“" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "上一电å°é¢‘é“" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "å‘目标对象å‘é€ä¿¡æ¯" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "当进入载具时切æ¢ä¸‹ä¸€ä¸ªæ­¦å™¨" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "当进入载具时切æ¢ä¸Šä¸€ä¸ªæ­¦å™¨" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "当剿œåŠ¡å™¨çš„è¾“å‡ºä¿¡æ¯" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "定义文字显示的标度系数" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(开呿¨¡å¼) shows the colshapes" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(开呿¨¡å¼) prints world sound ids into the debug window" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "æœåŠ¡å™¨ä¸»æœº" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "资æº" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "æœåС噍åç§°:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "密ç :" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "最大å…许玩家:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "广播:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "本地局域网" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "已选择" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "所有" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "å¼€å¯" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "地图下载进度:" @@ -2852,488 +2992,398 @@ msgstr "%s 之 %s" msgid "Disconnect to cancel download" msgstr "æ–­å¼€è¿žæŽ¥ä»¥å–æ¶ˆä¸‹è½½" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "断开连接: 无效的昵称" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "与æœåŠ¡å™¨æ–­å¼€è¿žæŽ¥" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "断开连接: åºåˆ—å·è¢«å°ç¦.\n" "原因: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "断开连接: 您被å°ç¦.\n" "原因: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "断开连接: è´¦å·è¢«å°ç¦.\n" "原因: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "断开连接: 游æˆç‰ˆæœ¬ä¸å¯¹åº”" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "断开连接: è¿‡å¤šçŽ©å®¶åŒæ—¶è¿›å…¥æœåС噍,请等候几分钟åŽå†è¿›å…¥." -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "断开连接: æœåС噍æ¥è‡ªä¸åŒçš„分支.\n" "相关信æ¯: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "断开连接: 版本已æŸå.\n" "相关信æ¯: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "断开连接: 用户版本比æœåŠ¡å™¨ç‰ˆæœ¬æ—§.\n" "相关信æ¯: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "断开连接: 用户版本比æœåŠ¡å™¨ç‰ˆæœ¬æ–°.\n" "相关信æ¯: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "断开连接: 昵称已有人使用" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "断开连接:无法创建玩家元素。" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "断开连接: æœåŠ¡å™¨æ‹’ç»è¿žæŽ¥: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "断开连接: åºåˆ—验è¯å¤±è´¥" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" -msgstr "" +msgstr "断开连接: åºåˆ—å·å·²æœ‰äººä½¿ç”¨" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "断开连接: æ•°æ®ä¸åŒæ­¥ %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "断开连接: 您已ç»è¢« %s 踢出æœåС噍(KICKED)" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "断开连接: 您已ç»è¢« %s ç¦æ­¢è¿›å…¥æœåС噍" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "断开连接:æœåŠ¡å™¨å·²å…³é—­æˆ–é‡å¯" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "您已ç»è¢«è¸¢å‡ºæ¸¸æˆ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "æ­¤æœåŠ¡å™¨è¦æ±‚未修改的 gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "è¯·æ›¿æ¢ gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "æ­¤æœåС噍ä¸å…许自定义D3D9.DLL" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "请从你的GTA安装目录中移除D3D9.DLLå¹¶é‡å¯MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "æ­¤æœåС噍ä¸å…许使用虚拟机" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "æ­¤æœåŠ¡å™¨è¦æ±‚å¯ç”¨é©±åŠ¨ç¨‹åºç­¾å" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "请é‡å¯ä½ çš„电脑" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "æ­¤æœåŠ¡å™¨æ£€æµ‹åˆ°ç¼ºå°‘å作弊组件" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "å°è¯•é‡å¯MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "æ­¤æœåŠ¡å™¨è¦æ±‚未修改的gta3.imgå’Œgta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "请替æ¢gta3.img或gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "æ­¤æœåС噍ä¸å…许使用 Linux Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "ç¡®ä¿æ²¡æœ‰å…¶ä»–程åºä¿®æ”¹MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "剩余时间" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d 天" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d æ—¶" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d 分" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" msgstr[0] "%d ç§’" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "断开连接" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "下载错误: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "驾驶UFO四处游è¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "四处巡游" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "在风浪中骑行" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "在ç«è½¦ä¸Šéª‘行" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "飞æ¥é£žåŽ»" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "四处骑行" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "å¼€ç€æ€ªå…½å¡è½¦åˆ°å¤„è·‘" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "骑四轮摩托车到处跑" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "å…”å­è·³" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "åšå¥‡æ€ªçš„事" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "爬山" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "开枪" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "开枪" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "呼叿°´" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "淹死在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "寻找掩护在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "战斗在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "扔拳头在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "爆破在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "射击" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "喷射背包飞行在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "在ç«ä¸­" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "燃烧在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "游泳在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "漂浮在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "被鲨鱼追赶" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "çª’æ¯æ­»" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "进入游æˆä¸­ ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "未连接; 请使用快速连接或者 'connect' 命令æ¥è¿žæŽ¥æœåС噍." -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "无法å¯åŠ¨æœ¬åœ°æœåС噍.请在 console 中查看详细信æ¯" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "本地æœåС噍" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "正在å¯ç”¨æœ¬åœ°æœåС噍 ..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "51区" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "四处走走 " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "您已ç»è¢«è¸¢å‡ºæ¸¸æˆ ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "正在连接到本地æœåС噍..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "连接到æœåŠ¡å™¨æ—¶å‘生错误." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "连接本地æœåŠ¡å™¨è¶…æ—¶.请在console中查看详细内容" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "与æœåŠ¡å™¨ä¸¢å¤±è¿žæŽ¥" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "断开连接:æœåŠ¡å™¨æ»¡è½½" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "断开连接: 无效的密ç " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA客户端验è¯å¤±è´¥!" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "在沟壑中" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "å‰å¾€åŒ»é™¢çš„路上" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "与上å¸è§é¢" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "åŽæ‚”自己的决定" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "已死亡" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "æœåŠ¡å™¨ä¸»æœº" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "资æº" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "æœåС噍åç§°:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "密ç :" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "最大å…许玩家:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "广播:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "本地局域网" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "已选择" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "所有" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "å¼€å¯" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "显å¡é©±åŠ¨å‡ºçŽ°é—®é¢˜" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "无法找到有效的å±å¹•分辨率." - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "您确定è¦ä½¿ç”¨è¿™ä¸ªåˆ†è¾¨çއå—?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "" +msgid "Download error: %s" +msgstr "下载错误: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3354,11 +3404,11 @@ msgstr "" msgid "Connection error" msgstr "连接错误" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "Multi Theft Auto 没有被正确安装. è¯·é‡æ–°å®‰è£…" -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "ä½ çš„æµè§ˆå™¨å°†ä¼šæ˜¾ç¤ºä¸€ä¸ªå¸¦æœ‰å¸®åŠ©ä¿¡æ¯çš„网页\n\n" diff --git a/Shared/data/MTA San Andreas/MTA/locale/zh_TW/client.pot b/Shared/data/MTA San Andreas/MTA/locale/zh_TW/client.pot index a0a731c347c..2aef984447a 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/zh_TW/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/zh_TW/client.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-15 00:40+0000\n" -"PO-Revision-Date: 2025-07-15 01:31\n" +"POT-Creation-Date: 2026-01-08 15:06+0000\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Chinese Traditional\n" "Language: zh_TW\n" @@ -17,72 +17,125 @@ msgstr "" "X-Crowdin-File: /[multitheftauto.mtasa-blue] master/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot\n" "X-Crowdin-File-ID: 87\n" -#: Client/loader/MainFunctions.cpp:248 -msgid "Trouble restarting MTA:SA\n\n" -"If the problem persists, open Task Manager and\n" -"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" -"Try to launch MTA:SA again?" -msgstr "é‡å•ŸMTA:SA時有故障\n\n" -"è‹¥å•題ä¾ç„¶å­˜åœ¨ï¼Œé–‹å•Ÿå·¥ä½œç®¡ç†å“¡(Ctrl+Alt+Del)並\n" -"åœæ­¢ã€Œgta_sa.exeã€åŠã€ŒMulti Theft Auto.exeã€çš„處ç†ç¨‹åº\n\n\n" -"å†å˜—試啟動 MTA:SAå—Ž?" +#: Client/loader/Utils.cpp:535 +msgid "Start Grand Theft Auto: San Andreas.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "啟動俠盜çµè»Šæ‰‹ï¼šè–安地列斯。\n" +"請確èªéŠæˆ²å®‰è£åœ¨ 'Program Files (x86)' 資料夾。" -#. Show a message that the connection timed out and abort -#. Show failed message and abort the attempt -#. Show timeout message and disconnect -#. Display an error, reset the error status and exit -#: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 -#: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 -#: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4301 -#: Client/core/CSettings.cpp:4329 Client/core/CSettings.cpp:4940 -#: Client/core/CConnectManager.cpp:86 Client/core/CConnectManager.cpp:117 -#: Client/core/CConnectManager.cpp:133 Client/core/CConnectManager.cpp:271 -#: Client/core/CConnectManager.cpp:329 Client/core/CConnectManager.cpp:415 -#: Client/core/CConnectManager.cpp:422 Client/core/CConnectManager.cpp:432 -#: Client/core/CCore.cpp:1272 Client/core/CGUI.cpp:93 -#: Client/core/DXHook/CDirect3DHook9.cpp:127 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1427 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 -#: Client/game_sa/CGameSA.cpp:262 Client/game_sa/CGameSA.cpp:273 -#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 -#: Shared/sdk/SharedUtil.Misc.hpp:137 -msgid "Error" -msgstr "錯誤" +#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 +msgid "Searching for GTA: San Andreas" +msgstr "æœå°‹ 俠盜çµè»Šæ‰‹ï¼šè–安地列斯" -#: Client/loader/MainFunctions.cpp:266 -msgid "Another instance of MTA is already running.\n\n" -"If this problem persists, please restart your computer" -msgstr "å¦ä¸€å€‹MTA正在é‹è¡Œã€‚\n\n" -"若這å•題ä»ç„¶å­˜åœ¨ï¼Œè«‹é‡æ–°å•Ÿå‹•你的電腦" +#: Client/loader/Utils.cpp:548 +msgid "Sorry, game not found.\n" +"Start Grand Theft Auto: San Andreas and click retry.\n" +"Ensure the game is placed in the 'Program Files (x86)' folder." +msgstr "å¾ˆæŠ±æ­‰ï¼Œçœ‹èµ·ä¾†æ²’æœ‰æ‰¾åˆ°éŠæˆ²æœ¬é«”。\n" +"請啟動 俠盜çµè»Šæ‰‹ï¼šè–安地列斯 後å†é‡è©¦ä¸€æ¬¡ã€‚\n" +"並請確èªéŠæˆ²å®‰è£åœ¨ 'Program Files (x86)' 資料夾。" -#: Client/loader/MainFunctions.cpp:269 -msgid "Another instance of MTA is already running.\n\n" -"Do you want to terminate it?" -msgstr "å¦ä¸€å€‹MTA正在é‹è¡Œã€‚\n\n" -"你想è¦çµ‚止它嗎?" +#: Client/loader/Utils.cpp:606 +msgid "Select your Grand Theft Auto: San Andreas Installation Directory" +msgstr "鏿“‡ä½ Grand Theft Auto: San Andreas的安è£ç›®éŒ„" + +#: Client/loader/Utils.cpp:974 Client/loader/CInstallManager.cpp:376 +#, c-format +msgid "MTA:SA needs Administrator access for the following task:\n\n" +" '%s'\n\n" +"Please confirm in the next window." +msgstr "MTA:SA 需è¦ç‚ºä»¥ä¸‹çš„任務æä¾›ç®¡ç†å“¡æ¬Šé™:\n\n" +" '%s'\n\n" +"請在下一個窗å£é€²è¡Œç¢ºå®šã€‚" + +#: Client/loader/Utils.cpp:1075 +#, c-format +msgid "Error loading %s module! (%s)" +msgstr "錯誤載入 %s 模組!(%s)" + +#: Client/loader/Utils.cpp:1400 Client/loader/Dialogs.cpp:1048 +msgid "Copying files..." +msgstr "複製文件中..." + +#: Client/loader/Utils.cpp:1460 Client/loader/Dialogs.cpp:1053 +msgid "Copy finished early. Everything OK." +msgstr "早就完æˆè¤‡è£½ï¼Œä¸€åˆ‡å‡†å‚™å°±ç·’。" + +#: Client/loader/Utils.cpp:1466 Client/loader/Dialogs.cpp:1058 +msgid "Finishing..." +msgstr "正在完æˆ..." + +#: Client/loader/Utils.cpp:1468 Client/loader/Dialogs.cpp:1062 +msgid "Done!" +msgstr "完æˆ!" + +#: Client/loader/Utils.cpp:1508 +#, c-format +msgid "New installation of %s detected.\n\n" +"Do you want to copy your settings from %s ?" +msgstr "檢測到新安è£çš„%s\n\n" +"您想去複製您的設定從%s ?" + +#: Client/loader/Utils.cpp:1547 +#, c-format +msgid "GTA:SA had trouble opening the file '%s'" +msgstr "GTA:SA é‡åˆ°å•題在打開文件 '%s'時" + +#: Client/loader/Utils.cpp:1569 +#, c-format +msgid "GTA:SA is missing the file '%s'." +msgstr "GTA:SA éºå¤±é€™å€‹ '%s' 檔案" + +#: Client/loader/Utils.cpp:1594 +msgid "GTA:SA had trouble loading a model." +msgstr "GTA:SA 在載入模組時é‡åˆ°å•題." + +#: Client/loader/Utils.cpp:1596 +msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." +msgstr "若是您有修改éŽgta3.imgï¼Œè«‹è©¦è‘—é‡æ–°å®‰è£GTA:SA。" + +#: Client/loader/Utils.cpp:1621 +msgid "GTA:SA had trouble adding an upgrade to a vehicle." +msgstr "GTA:SA 發生å•題在新增å‡ç´šè»Šè¼›æ™‚" + +#: Client/loader/Utils.cpp:1640 +#, c-format +msgid "GTA:SA found errors in the file '%s'" +msgstr "GTA:SA é‹è¡Œæ™‚在檔案 '%s' 發生錯誤" + +#: Client/loader/Utils.cpp:1722 +msgid "Did your computer restart when playing MTA:SA?" +msgstr "在玩 MTA:SA時,您的電腦é‡èµ·å—Ž?" -#: Client/loader/MainFunctions.cpp:294 +#: Client/loader/Utils.cpp:1787 +msgid "Please terminate the following programs before continuing:" +msgstr "請在繼續之å‰çµ‚止下列程å¼:" + +#: Client/loader/MainFunctions.cpp:321 +msgid "Invalid module path detected.\n" +msgstr "" + +#: Client/loader/MainFunctions.cpp:348 +msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" +msgstr "檔版本ä¸åŒ¹é…錯誤。如果您é‡åˆ°å•é¡Œï¼Œè«‹é‡æ–°å®‰è£ MTA:SA。\n" + +#: Client/loader/MainFunctions.cpp:356 +msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" +msgstr "æŸäº›æª”是缺掉的。如果您é‡åˆ°å•é¡Œï¼Œè«‹é‡æ–°å®‰è£ MTA:SA。\n" + +#: Client/loader/MainFunctions.cpp:367 +msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" +"Please restart your PC.\n" +msgstr "MTA:SA無法在安全模å¼ä¸‹åŸ·è¡Œã€‚\n\n" +"è«‹é‡æ–°å•Ÿå‹•您的電腦。\n" + +#: Client/loader/MainFunctions.cpp:546 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to revert to an earlier version?" msgstr "ä½ é‹è¡ŒMTA:SA時有任何å•題?\n\n" "你想è¦å›žæº¯è‡³è¼ƒæ—©çš„版本嗎?" -#: Client/loader/MainFunctions.cpp:324 +#: Client/loader/MainFunctions.cpp:574 msgid "There seems to be a problem launching MTA:SA.\n" "Resetting GTA settings can sometimes fix this problem.\n\n" "Do you want to reset GTA settings now?" @@ -90,48 +143,48 @@ msgstr "啟動 MTA:SA時似乎有些å•題,\n" "é‡è¨­GTA的設定有時有助於修復這些å•題.\n\n" "你想è¦ç¾åœ¨é‡è¨­GTA的設定嗎?" -#: Client/loader/MainFunctions.cpp:339 +#: Client/loader/MainFunctions.cpp:589 msgid "GTA settings have been reset.\n\n" "Press OK to continue." msgstr "GTA的設定已被é‡è¨­.\n\n" "請按「確定ã€ä»¥ç¹¼çºŒã€‚" -#: Client/loader/MainFunctions.cpp:344 +#: Client/loader/MainFunctions.cpp:594 #, c-format msgid "File could not be deleted: '%s'" msgstr "無法刪除文件: '%s'" #. No settings to delete, or can't find them -#: Client/loader/MainFunctions.cpp:352 +#: Client/loader/MainFunctions.cpp:602 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to see some online help?" msgstr "ä½ é‹è¡ŒMTA:SA時é‡åˆ°ä»»ä½•å•題?\n\n" "你希望看看線上的幫助嗎?" #. Inform user -#: Client/loader/MainFunctions.cpp:388 +#: Client/loader/MainFunctions.cpp:639 msgid "Are you having problems running MTA:SA?.\n\n" "Do you want to change the following setting?" msgstr "您是å¦åœ¨é‹è¡ŒMTA:SA時é‡åˆ°ä»»ä½•å•題?\n\n" "您想è¦è®Šæ›´ç‚ºä»¥ä¸‹çš„設定嗎?" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:692 -#: Client/core/CSettings.cpp:1038 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1161 +#: Client/core/CSettings.cpp:1672 msgid "Fullscreen mode:" msgstr "全螢幕模å¼:" -#: Client/loader/MainFunctions.cpp:389 Client/core/CSettings.cpp:700 -#: Client/core/CSettings.cpp:1660 +#: Client/loader/MainFunctions.cpp:640 Client/core/CSettings.cpp:1171 +#: Client/core/CSettings.cpp:2337 msgid "Borderless window" msgstr "無邊框視窗化" -#: Client/loader/MainFunctions.cpp:431 +#: Client/loader/MainFunctions.cpp:711 msgid "Are you having problems running MTA:SA?.\n\n" "Try disabling the following products for GTA and MTA:" msgstr "您是å¦åœ¨é‹è¡ŒMTA:SA時é‡åˆ°ä»»ä½•å•題?\n\n" "試關閉以下程å¼ä»¥å…影響GTAå’ŒMTA:" -#: Client/loader/MainFunctions.cpp:465 +#: Client/loader/MainFunctions.cpp:744 msgid "WARNING\n\n" "MTA:SA has detected unusual activity.\n" "Please run a virus scan to ensure your system is secure.\n\n" @@ -139,132 +192,293 @@ msgstr "警告\n\n" "MTA:SA 已檢測到ä¸å°‹å¸¸çš„æ´»å‹•\n" "è«‹é‹è¡Œç—…毒掃æï¼Œä»¥ç¢ºä¿æ‚¨çš„系統是安全的\n\n" -#: Client/loader/MainFunctions.cpp:468 +#: Client/loader/MainFunctions.cpp:747 #, c-format msgid "The detected file was: %s\n" msgstr "檢測到的檔是: %s\n" -#: Client/loader/MainFunctions.cpp:602 +#: Client/loader/MainFunctions.cpp:995 msgid "An instance of GTA: San Andreas is already running. It needs to be terminated before MTA:SA can be started. Do you want to do that now?" msgstr "å¦ä¸€å€‹GTA:SA正在é‹è¡Œï¼Œå•Ÿå‹•MTA:SAå‰éœ€è¦å…ˆçµ‚止它。你想è¦ç¾åœ¨é€™éº¼åšå—Ž?" -#: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 -#: Client/loader/MainFunctions.cpp:1219 +#: Client/loader/MainFunctions.cpp:996 Client/loader/MainFunctions.cpp:1003 +#: Client/loader/MainFunctions.cpp:1969 #: Client/core/ServerBrowser/CServerInfo.cpp:319 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/game_sa/CGameSA.cpp:269 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 +#: Client/game_sa/CGameSA.cpp:270 msgid "Information" msgstr "資訊" -#: Client/loader/MainFunctions.cpp:609 +#: Client/loader/MainFunctions.cpp:1002 msgid "Unable to terminate GTA: San Andreas. If the problem persists, please restart your computer." msgstr "無法終止GTA:SA,若這å•題ä»ç„¶å­˜åœ¨ï¼Œè«‹é‡æ–°å•Ÿå‹•你的電腦。" -#: Client/loader/MainFunctions.cpp:632 +#: Client/loader/MainFunctions.cpp:1131 +msgid "Trouble restarting MTA:SA\n\n" +"If the problem persists, open Task Manager and\n" +"stop the 'gta_sa.exe' and 'Multi Theft Auto.exe' processes\n\n\n" +"Try to launch MTA:SA again?" +msgstr "é‡å•ŸMTA:SA時有故障\n\n" +"è‹¥å•題ä¾ç„¶å­˜åœ¨ï¼Œé–‹å•Ÿå·¥ä½œç®¡ç†å“¡(Ctrl+Alt+Del)並\n" +"åœæ­¢ã€Œgta_sa.exeã€åŠã€ŒMulti Theft Auto.exeã€çš„處ç†ç¨‹åº\n\n\n" +"å†å˜—試啟動 MTA:SAå—Ž?" + +#. Show a message that the connection timed out and abort +#. Show failed message and abort the attempt +#. Show timeout message and disconnect +#. Display an error, reset the error status and exit +#: Client/loader/MainFunctions.cpp:1136 Client/loader/MainFunctions.cpp:1157 +#: Client/loader/MainFunctions.cpp:1161 Client/loader/MainFunctions.cpp:1572 +#: Client/loader/CInstallManager.cpp:1079 +#: Client/loader/CInstallManager.cpp:1088 Client/core/CConnectManager.cpp:86 +#: Client/core/CConnectManager.cpp:117 Client/core/CConnectManager.cpp:133 +#: Client/core/CConnectManager.cpp:271 Client/core/CConnectManager.cpp:329 +#: Client/core/CConnectManager.cpp:415 Client/core/CConnectManager.cpp:422 +#: Client/core/CConnectManager.cpp:432 Client/core/CSettings.cpp:3839 +#: Client/core/CSettings.cpp:5215 Client/core/CSettings.cpp:5243 +#: Client/core/CSettings.cpp:5982 Client/core/CCore.cpp:1375 +#: Client/core/CGUI.cpp:94 Client/core/DXHook/CDirect3DHook9.cpp:128 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 +#: Client/game_sa/CGameSA.cpp:263 Client/game_sa/CGameSA.cpp:274 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1444 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 +#: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 +#: Shared/sdk/SharedUtil.Misc.hpp:381 +msgid "Error" +msgstr "錯誤" + +#: Client/loader/MainFunctions.cpp:1155 +msgid "Another instance of MTA is already running.\n\n" +"If this problem persists, please restart your computer" +msgstr "å¦ä¸€å€‹MTA正在é‹è¡Œã€‚\n\n" +"若這å•題ä»ç„¶å­˜åœ¨ï¼Œè«‹é‡æ–°å•Ÿå‹•你的電腦" + +#: Client/loader/MainFunctions.cpp:1159 +msgid "Another instance of MTA is already running.\n\n" +"Do you want to terminate it?" +msgstr "å¦ä¸€å€‹MTA正在é‹è¡Œã€‚\n\n" +"你想è¦çµ‚止它嗎?" + +#: Client/loader/MainFunctions.cpp:1196 msgid "Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas." msgstr "註冊表項éºå¤±ï¼Œè«‹é‡æ–°å®‰è£MTA:SA。" -#: Client/loader/MainFunctions.cpp:638 +#: Client/loader/MainFunctions.cpp:1202 msgid "The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas." msgstr "該安è£GTA:SA的路徑包å«ä¸å—支æŒçš„(Unicode)字符,請移動你安è£çš„GTA:SA到一個兼容並åªåŒ…嫿¨™æº–çš„ASCII字符的路徑,以åŠé‡æ–°å®‰è£MTA:SA。" -#: Client/loader/MainFunctions.cpp:648 +#: Client/loader/MainFunctions.cpp:1215 msgid "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n" "contains a ';' (semicolon).\n\n" -" If you experience problems when running MTA:SA,\n" -" move your installation(s) to a path that does not contain a semicolon." -msgstr "你安è£ã€ŒGTA:SAã€æˆ–「MTA:SAã€çš„路徑\n" -"包å«ã€Œ;ã€(分號),\n\n" -"若你é‹è¡ŒMTA:SA時é‡åˆ°å•題發生,\n" -"移動你安è£çš„「GTA:SAã€æˆ–「MTA:SAã€è‡³ä¸åŒ…å«åˆ†è™Ÿçš„路徑。" - -#: Client/loader/MainFunctions.cpp:810 +"If you experience problems when running MTA:SA,\n" +"move your installation(s) to a path that does not contain a semicolon." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1398 +msgid "Invalid installation paths detected." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1529 msgid "Load failed. Please ensure that the latest data files have been installed correctly." msgstr "è¼‰å…¥å¤±æ•—ï¼Œè«‹ç¢ºä¿æœ€æ–°çš„æ•¸æ“šæ–‡ä»¶å·²è¢«æ­£ç¢ºå®‰è£ã€‚" -#: Client/loader/MainFunctions.cpp:819 +#: Client/loader/MainFunctions.cpp:1538 #, c-format msgid "Load failed. Please ensure that %s is installed correctly." msgstr "è¼‰å…¥å¤±æ•—ï¼Œè«‹ç¢ºä¿ %s 已被正確安è£ã€‚" -#: Client/loader/MainFunctions.cpp:826 +#: Client/loader/MainFunctions.cpp:1547 #, c-format msgid "Load failed. Could not find gta_sa.exe in %s." msgstr "載入失敗,無法找到 gta_sa.exe 在 %s è£ã€‚" -#: Client/loader/MainFunctions.cpp:836 +#: Client/loader/MainFunctions.cpp:1561 #, c-format msgid "Load failed. %s exists in the GTA directory. Please delete before continuing." msgstr "載入失敗,%s 存在於GTA目錄,請先刪除å†ç¹¼çºŒã€‚" -#: Client/loader/MainFunctions.cpp:845 +#: Client/loader/MainFunctions.cpp:1571 #, c-format msgid "Main file has an incorrect name (%s)" msgstr "ä¸»æ–‡ä»¶æœ‰ä¸€å€‹ä¸æ­£ç¢ºçš„å稱 (%s)" -#: Client/loader/MainFunctions.cpp:856 -msgid "Main file is unsigned. Possible virus activity.\n\n" -"See online help if MTA does not work correctly." -msgstr "ä¸»è¦æ–‡ä»¶æ˜¯ç„¡ç¬¦è™Ÿã€‚å¯èƒ½çš„病毒活動.\n\n" -"請查看線上幫助,如果MTAä¸èƒ½æ­£å¸¸å·¥ä½œã€‚" - -#: Client/loader/MainFunctions.cpp:882 +#: Client/loader/MainFunctions.cpp:1618 #, c-format -msgid "Data file %s is missing. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "資料檔案 %s éºå¤±ã€‚å¯èƒ½å’Œé›»è…¦ç—…毒有關。\n\n" -"ç‚ºäº†æ‚¨çš„å®‰å…¨ï¼Œè«‹è€ƒæ…®é‡æ–°å®‰è£ Multi Theft Auto。\n" -"如果 MTA 無法正常é‹ä½œï¼Œè«‹åƒé–±ç·šä¸Šèªªæ˜Žã€‚" - -#: Client/loader/MainFunctions.cpp:893 +msgid "Data file %s is missing. Possible virus activity." +msgstr "" + +#: Client/loader/MainFunctions.cpp:1626 #, c-format -msgid "Data file %s is modified. Possible virus activity.\n\n" -"Consider reinstalling Multi Theft Auto for your security.\n" -"See online help if MTA does not work correctly." -msgstr "資料檔案 %s 被竄改éŽã€‚å¯èƒ½å’Œé›»è…¦ç—…毒有關。\n\n" -"ç‚ºäº†æ‚¨çš„å®‰å…¨ï¼Œè«‹è€ƒæ…®é‡æ–°å®‰è£ Multi Theft Auto。\n" -"如果 MTA 無法正常é‹ä½œï¼Œè«‹åƒé–±ç·šä¸Šèªªæ˜Žã€‚" - -#: Client/loader/MainFunctions.cpp:907 -msgid ".asi files are in the 'MTA:SA' or 'GTA: San Andreas' installation directory.\n\n" -"Remove these .asi files if you experience problems with MTA:SA." -msgstr ".asi 檔是在 'MTA:SA' 或 ' GTA: San Andreas 安è£ç›®éŒ„。\n\n" -"如果使用 MTA:SA é‡åˆ°äº†å•題,請刪除這些.asi 檔。" - -#: Client/loader/MainFunctions.cpp:1009 -msgid "File version mismatch error. Reinstall MTA:SA if you experience problems.\n" -msgstr "檔版本ä¸åŒ¹é…錯誤。如果您é‡åˆ°å•é¡Œï¼Œè«‹é‡æ–°å®‰è£ MTA:SA。\n" +msgid "Data file %s is modified. Possible virus activity." +msgstr "" -#: Client/loader/MainFunctions.cpp:1018 -msgid "Some files are missing. Reinstall MTA:SA if you experience problems.\n" -msgstr "æŸäº›æª”是缺掉的。如果您é‡åˆ°å•é¡Œï¼Œè«‹é‡æ–°å®‰è£ MTA:SA。\n" +#: Client/loader/MainFunctions.cpp:1650 +msgid ".asi files are in the installation directory.\n\n" +"Remove these .asi files if you experience problems." +msgstr "" -#: Client/loader/MainFunctions.cpp:1030 -msgid "MTA:SA is not compatible with Windows 'Safe Mode'.\n\n" -"Please restart your PC.\n" -msgstr "MTA:SA無法在安全模å¼ä¸‹åŸ·è¡Œã€‚\n\n" -"è«‹é‡æ–°å•Ÿå‹•您的電腦。\n" +#: Client/loader/MainFunctions.cpp:1819 +msgid "Invalid game paths detected." +msgstr "" -#: Client/loader/MainFunctions.cpp:1123 +#: Client/loader/MainFunctions.cpp:1827 msgid "Fix configuration issue" msgstr "修復é…ç½®å•題" -#. Try to relaunch as admin if not done so already -#: Client/loader/MainFunctions.cpp:1157 -msgid "Fix elevation required error" -msgstr "修復權é™éœ€æ±‚錯誤" +#: Client/loader/MainFunctions.cpp:1969 +msgid "GTA: San Andreas may not have launched correctly. Terminate it?" +msgstr "" -#: Client/loader/MainFunctions.cpp:1164 +#: Client/loader/Install.cpp:265 +msgid "Unknown" +msgstr "未知" + +#: Client/loader/Install.cpp:272 #, c-format -msgid "Could not start Grand Theft Auto: San Andreas. Please try restarting, or if the problem persists,contact MTA at www.multitheftauto.com. \n\n" -"[%s]" -msgstr "無法啟動 GTA:SAï¼Œè«‹å˜—è©¦é‡æ–°å•Ÿå‹•。若å•題ä¾ç„¶å­˜åœ¨ï¼Œè«‹è¯çµ¡MTAç¶²å€ www.multitheftauto.com。\n\n" -"[%s]" +msgid "The file '%s' is currently locked by %zu processes.\n\n" +"Do you want to terminate the following processes and continue updating?\n\n" +"%s" +msgstr "檔案 '%s' ç›®å‰è¢« %zu 個處ç†ç¨‹åºéŽ–å®šã€‚\n\n" +"是å¦è¦çµ‚止下列處ç†ç¨‹åºä¸¦ç¹¼çºŒæ›´æ–°ï¼Ÿ\n\n" +"%s" -#: Client/loader/MainFunctions.cpp:1219 -msgid "GTA: San Andreas may not have launched correctly. Do you want to terminate it?" -msgstr "GTA: San Andreas å¯èƒ½æ²’有正確地啟動。你想è¦ç¾åœ¨çµ‚止它嗎?" +#: Client/loader/Install.cpp:479 +#, c-format +msgid "Your installation may be corrupt now.\n\n" +"%zu out of %zu files could not be restored from the backup.\n\n" +"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" +"or try running the update with administrator rights." +msgstr "您的安è£ç¾åœ¨å‡ºç¾å•題å¯èƒ½å·²ææ¯€ã€‚\n\n" +"%zu / %zu 個檔案無法從備份中還原。\n\n" +"您應該從 www.multitheftauto.com 釿–°å®‰è£ Multi Theft Auto\n" +"或嘗試以管ç†å“¡èº«åˆ†åŸ·è¡Œæ›´æ–°ã€‚" + +#: Client/loader/Install.cpp:852 Client/loader/Dialogs.cpp:1035 +msgid "Installing update..." +msgstr "安装更新..." + +#: Client/loader/Install.cpp:934 Client/loader/Dialogs.cpp:1043 +msgid "Extracting files..." +msgstr "解開檔案中..." + +#: Client/loader/CInstallManager.cpp:391 +#, c-format +msgid "MTA:SA could not complete the following task:\n\n" +" '%s'\n" +msgstr "MTA:SA 無法完æˆä¸‹åˆ—的任務:\n\n" +" '%s'\n" + +#: Client/loader/CInstallManager.cpp:460 +msgid "** The crash was caused by a graphics driver error **\n\n" +"** Please update your graphics drivers **" +msgstr "** 造æˆå´©æ½°çš„原因是一個來自於圖形驅動程å¼çš„錯誤 **\n\n" +"** 請更新你的顯示å¡åœ–å½¢é©…å‹•ç¨‹å¼ **" + +#: Client/loader/CInstallManager.cpp:470 +msgid "** Out of memory - this crash was caused by insufficient free or fragmented memory. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:476 +msgid "** Enhanced crash capture will be attempted on next launch. **" +msgstr "" + +#: Client/loader/CInstallManager.cpp:1059 +msgid "Install updated MTA:SA files" +msgstr "安è£å·²æ›´æ–°çš„ MTA:SA 文件" + +#: Client/loader/CInstallManager.cpp:1079 +msgid "Could not update due to file conflicts. Please close other applications and retry" +msgstr "由於文件è¡çªå°Žè‡´ç„¡æ³•更新,請關閉其他軟體並é‡è©¦" + +#: Client/loader/CInstallManager.cpp:1088 +#, c-format +msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" +msgstr "MTA 並沒有被正確安è£ï¼Œè«‹é‡æ–°å®‰è£ã€‚%s" + +#: Client/loader/CInstallManager.cpp:1140 +msgid "Create GTA:SA junctions" +msgstr "創建GTA:SA交匯點" + +#: Client/loader/CInstallManager.cpp:1184 +msgid "MTA:SA cannot launch because copying a file failed:" +msgstr "MTA:SA 無法順利啟動,因為複製檔案失敗:" + +#: Client/loader/CInstallManager.cpp:1190 +#: Client/loader/CInstallManager.cpp:1230 +msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" +msgstr "MTA:SA 無法順利啟動,因為 MTA:SA 的檔案有錯誤或是éºå¤±ï¼š" + +#: Client/loader/CInstallManager.cpp:1199 +msgid "Copy MTA:SA files" +msgstr "複製 MTA:SA 檔案" + +#: Client/loader/CInstallManager.cpp:1222 +#: Client/loader/CInstallManager.cpp:1300 +msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" +msgstr "MTA:SA 無法啟動,因為 GTA:SA ä¸»ç¨‹å¼æœ¬é«”的檔案有錯誤或éºå¤±ï¼š" + +#: Client/loader/CInstallManager.cpp:1307 +msgid "Patch GTA:SA dependency" +msgstr "修補 GTA:SA çš„ä¾è³´é …" + +#: Client/loader/CInstallManager.cpp:1355 +msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" +msgstr "MTA:SA 無法順利啟動,因為 GTA:SA 主程å¼åŸ·è¡Œæª”有錯誤或是éºå¤±ï¼š" + +#: Client/loader/CInstallManager.cpp:1359 +msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." +msgstr "è«‹æª¢æŸ¥æ‚¨çš„é˜²æ¯’è»Ÿé«”æ˜¯å¦æœ‰èª¤åˆ¤çš„æƒ…形,å¯å˜—試將GTA:SA主程å¼åŸ·è¡Œæª”åŠ å…¥æŽ’é™¤æ¸…å–®ï¼Œç„¶å¾Œé‡æ–°å•Ÿå‹•MTA:SA。" + +#: Client/loader/CInstallManager.cpp:1365 +msgid "Generate GTA:SA" +msgstr "ç”Ÿæˆ GTA:SA" + +#: Client/loader/CInstallManager.cpp:1380 +msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" +msgstr "MTA:SA 無法順利啟動,因為 GTA:SA 主程å¼åŸ·è¡Œæª”無法被讀å–:" + +#: Client/loader/CInstallManager.cpp:1387 +#: Client/loader/CInstallManager.cpp:1410 +msgid "Patch GTA:SA" +msgstr "修補 GTA:SA" + +#: Client/loader/CInstallManager.cpp:1403 +msgid "MTA:SA cannot launch because patching GTA:SA has failed:" +msgstr "MTA:SA 無法順利啟動,因為修補GTA:SA主程å¼å¤±æ•—:" + +#: Client/loader/CInstallManager.cpp:1584 Client/core/CCore.cpp:846 +#, c-format +msgid "MTA:SA cannot continue because drive %s does not have enough space." +msgstr "MTASAä¸èƒ½ç¹¼çºŒ,因為ç£ç¢Ÿæ©Ÿ %s 空間ä¸è¶³" + +#: Client/loader/CInstallManager.cpp:1640 +msgid "Missing file:" +msgstr "éºå¤±æª”案:" + +#: Client/loader/CInstallManager.cpp:1644 +msgid "If MTA fails to load, please re-install GTA:SA" +msgstr "如果MTAè¼‰å…¥å¤±æ•—ï¼Œè«‹é‡æ–°å®‰è£ GTA:SA" + +#: Client/loader/CInstallManager.cpp:1679 +msgid "Update install settings" +msgstr "更新安è£è¨­å®š" + +#: Client/loader/CInstallManager.cpp:1832 +msgid "Update compatibility settings" +msgstr "更新相容性設置" #. ///////////////////////////////////////////////////////////////////////// #. @@ -272,167 +486,167 @@ msgstr "GTA: San Andreas å¯èƒ½æ²’有正確地啟動。你想è¦ç¾åœ¨çµ‚止它 #. #. #. ///////////////////////////////////////////////////////////////////////// -#: Client/loader/Dialogs.cpp:35 Client/core/CMainMenu.cpp:1202 -#: Client/core/CSettings.cpp:1434 Client/core/CSettings.cpp:1458 -#: Client/core/CSettings.cpp:4624 Client/core/CSettings.cpp:4698 -#: Client/core/CSettings.cpp:4728 Client/core/CSettings.cpp:4777 -#: Client/core/CSettings.cpp:4830 Client/core/CVersionUpdater.cpp:1572 -#: Client/core/CVersionUpdater.cpp:1590 Client/core/CVersionUpdater.cpp:1859 -#: Client/core/CVersionUpdater.cpp:1878 Client/core/CQuestionBox.cpp:195 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:63 Client/core/CVersionUpdater.cpp:1635 +#: Client/core/CVersionUpdater.cpp:1653 Client/core/CVersionUpdater.cpp:1922 +#: Client/core/CVersionUpdater.cpp:1941 Client/core/CSettings.cpp:2109 +#: Client/core/CSettings.cpp:2133 Client/core/CSettings.cpp:5630 +#: Client/core/CSettings.cpp:5704 Client/core/CSettings.cpp:5734 +#: Client/core/CSettings.cpp:5783 Client/core/CSettings.cpp:5845 +#: Client/core/CMainMenu.cpp:1238 Client/core/CQuestionBox.cpp:195 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 #: Client/gui/CGUIMessageBox_Impl.cpp:72 msgid "Yes" msgstr "是" -#: Client/loader/Dialogs.cpp:36 Client/core/CMainMenu.cpp:1201 -#: Client/core/CSettings.cpp:1433 Client/core/CSettings.cpp:1457 -#: Client/core/CSettings.cpp:4623 Client/core/CSettings.cpp:4697 -#: Client/core/CSettings.cpp:4727 Client/core/CSettings.cpp:4776 -#: Client/core/CSettings.cpp:4829 Client/core/CVersionUpdater.cpp:1571 -#: Client/core/CVersionUpdater.cpp:1589 Client/core/CVersionUpdater.cpp:1858 -#: Client/core/CVersionUpdater.cpp:1877 Client/core/CQuestionBox.cpp:194 -#: Client/core/ServerBrowser/CServerInfo.cpp:481 +#: Client/loader/Dialogs.cpp:64 Client/core/CVersionUpdater.cpp:1634 +#: Client/core/CVersionUpdater.cpp:1652 Client/core/CVersionUpdater.cpp:1921 +#: Client/core/CVersionUpdater.cpp:1940 Client/core/CSettings.cpp:2108 +#: Client/core/CSettings.cpp:2132 Client/core/CSettings.cpp:5629 +#: Client/core/CSettings.cpp:5703 Client/core/CSettings.cpp:5733 +#: Client/core/CSettings.cpp:5782 Client/core/CSettings.cpp:5844 +#: Client/core/CMainMenu.cpp:1237 Client/core/CQuestionBox.cpp:194 +#: Client/core/ServerBrowser/CServerInfo.cpp:565 msgid "No" msgstr "å¦" #. Create buttons #. OK button -#: Client/loader/Dialogs.cpp:37 Client/core/CMainMenu.cpp:1222 -#: Client/core/CSettings.cpp:128 Client/core/CSettings.cpp:4961 -#: Client/core/CVersionUpdater.cpp:1607 Client/core/CVersionUpdater.cpp:1823 -#: Client/core/CVersionUpdater.cpp:1916 Client/core/CVersionUpdater.cpp:1938 -#: Client/core/CVersionUpdater.cpp:1956 Client/core/CVersionUpdater.cpp:1968 -#: Client/core/CVersionUpdater.cpp:2120 Client/core/CVersionUpdater.cpp:2129 -#: Client/core/CVersionUpdater.cpp:2138 Client/core/CVersionUpdater.cpp:2152 +#: Client/loader/Dialogs.cpp:65 Client/core/CVersionUpdater.cpp:1670 +#: Client/core/CVersionUpdater.cpp:1886 Client/core/CVersionUpdater.cpp:1979 +#: Client/core/CVersionUpdater.cpp:2001 Client/core/CVersionUpdater.cpp:2019 +#: Client/core/CVersionUpdater.cpp:2031 Client/core/CVersionUpdater.cpp:2183 +#: Client/core/CVersionUpdater.cpp:2192 Client/core/CVersionUpdater.cpp:2201 +#: Client/core/CVersionUpdater.cpp:2215 Client/core/CSettings.cpp:561 +#: Client/core/CSettings.cpp:6003 Client/core/CMainMenu.cpp:1258 #: Client/gui/CGUIMessageBox_Impl.cpp:64 msgid "OK" msgstr "確定" -#: Client/loader/Dialogs.cpp:38 +#: Client/loader/Dialogs.cpp:66 msgid "Quit" msgstr "退出" -#: Client/loader/Dialogs.cpp:39 -#: Client/core/ServerBrowser/CServerBrowser.cpp:556 +#: Client/loader/Dialogs.cpp:67 +#: Client/core/ServerBrowser/CServerBrowser.cpp:717 msgid "Help" msgstr "說明" #. Cancel button -#: Client/loader/Dialogs.cpp:40 Client/core/CSettings.cpp:133 -#: Client/core/CSettings.cpp:4960 Client/core/CVersionUpdater.cpp:1790 -#: Client/core/CVersionUpdater.cpp:1806 Client/core/CVersionUpdater.cpp:1841 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 +#: Client/loader/Dialogs.cpp:68 Client/core/CVersionUpdater.cpp:1853 +#: Client/core/CVersionUpdater.cpp:1869 Client/core/CVersionUpdater.cpp:1904 +#: Client/core/CSettings.cpp:566 Client/core/CSettings.cpp:6002 #: Client/gui/CGUIMessageBox_Impl.cpp:68 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:123 msgid "Cancel" msgstr "å–æ¶ˆ" -#: Client/loader/Dialogs.cpp:55 +#: Client/loader/Dialogs.cpp:83 msgid "MTA: San Andreas has encountered a problem" msgstr "MTA: San Andreas 發生å•題" -#: Client/loader/Dialogs.cpp:56 +#: Client/loader/Dialogs.cpp:84 msgid "Crash information" msgstr "當機資訊" -#: Client/loader/Dialogs.cpp:57 +#: Client/loader/Dialogs.cpp:85 msgid "Tick the check box to send this crash info to MTA devs using the 'internet'" msgstr "勾é¸è©²æ ¸å–方塊以將此當機資訊發é€åˆ° MTA 開發者使用互è¯ç¶²" -#: Client/loader/Dialogs.cpp:58 +#: Client/loader/Dialogs.cpp:86 msgid "Doing so will increase the chance of this crash being fixed." msgstr "é€™æ¨£åšæœƒå¢žåŠ é€™å€‹å´©æ½°è¢«å›ºå®šçš„æ©Ÿæœƒ." -#: Client/loader/Dialogs.cpp:59 +#: Client/loader/Dialogs.cpp:87 msgid "Do you want to restart MTA: San Andreas ?" msgstr "ä½ æƒ³é‡æ–°å•Ÿå‹•MTA: San Andreas ?" -#: Client/loader/Dialogs.cpp:66 +#: Client/loader/Dialogs.cpp:94 msgid "MTA: San Andreas - Warning" msgstr "MTA: San Andreas-警告" -#: Client/loader/Dialogs.cpp:67 +#: Client/loader/Dialogs.cpp:95 msgid "Your Grand Theft Auto: San Andreas install directory contains these files:" msgstr "æ‚¨å®‰è£ Grand Theft Auto: San Andreas 的資料夾內包å«ä»¥ä¸‹æª”案:" -#: Client/loader/Dialogs.cpp:69 +#: Client/loader/Dialogs.cpp:97 msgid "These files are not required and may interfere with the graphical features in this version of MTA:SA.\n\n" "It is recommended that you remove or rename these files." msgstr "é€™äº›æª”æ¡ˆä¸¦ä¸æ˜¯MTA:SA必須的檔案,而且å¯èƒ½æœƒå°Žè‡´åœ–形功能出ç¾å•題。\n\n" "å»ºè­°æ‚¨åˆªé™¤æˆ–æ˜¯é‡æ–°å‘½å這些檔案。" -#: Client/loader/Dialogs.cpp:71 +#: Client/loader/Dialogs.cpp:99 msgid "Keep these files, but also show this warning on next start" msgstr "ä¿ç•™é€™äº›æª”案,但下次啟動時ä»ç„¶æœƒå‡ºç¾è©²è­¦å‘Šã€‚" -#: Client/loader/Dialogs.cpp:72 +#: Client/loader/Dialogs.cpp:100 msgid "Do not remind me about these files again" msgstr "ä¸è¦å†æé†’我關於這些檔案的警告" -#: Client/loader/Dialogs.cpp:73 +#: Client/loader/Dialogs.cpp:101 msgid "Rename these files from *.dll to *.dll.bak" msgstr "將這些 *.dll æª”æ¡ˆé‡æ–°å‘½å為 *.dll.bak" -#: Client/loader/Dialogs.cpp:74 +#: Client/loader/Dialogs.cpp:102 msgid "Show me these files" msgstr "顯示這些檔案" -#: Client/loader/Dialogs.cpp:75 +#: Client/loader/Dialogs.cpp:103 msgid "Play MTA:SA" msgstr "玩 MTA:SA" -#: Client/loader/Dialogs.cpp:81 +#: Client/loader/Dialogs.cpp:109 msgid "MTA: San Andreas - Confusing options" msgstr "MTA: San Andreas-迷惑é¸é …" -#: Client/loader/Dialogs.cpp:82 +#: Client/loader/Dialogs.cpp:110 msgid "NVidia Optimus detected!" msgstr "NVidia Optimus 檢測到 ï¼" -#: Client/loader/Dialogs.cpp:83 +#: Client/loader/Dialogs.cpp:111 msgid "Try each option and see what works:" msgstr "嘗試使用æ¯å€‹é¸é …,看看什麼效果:" -#: Client/loader/Dialogs.cpp:84 +#: Client/loader/Dialogs.cpp:112 msgid "A - Standard NVidia" msgstr "A - NVIDIA標準" -#: Client/loader/Dialogs.cpp:85 +#: Client/loader/Dialogs.cpp:113 msgid "B - Alternate NVidia" msgstr "B - 備用NVIDIA" -#: Client/loader/Dialogs.cpp:86 +#: Client/loader/Dialogs.cpp:114 msgid "C - Standard Intel" msgstr "C - 標準 Intel" -#: Client/loader/Dialogs.cpp:87 +#: Client/loader/Dialogs.cpp:115 msgid "D - Alternate Intel" msgstr "D - 替代 Intel" -#: Client/loader/Dialogs.cpp:88 +#: Client/loader/Dialogs.cpp:116 msgid "If you get desperate, this might help:" msgstr "如果你找ä¸åˆ°ï¼Œé€™å¯èƒ½æœƒèª¬æ˜Ž:" -#: Client/loader/Dialogs.cpp:89 +#: Client/loader/Dialogs.cpp:117 msgid "If you have already selected an option that works, this might help:" msgstr "å¦‚æžœæ‚¨å·²ç¶“é¸æ“‡äº†ä¸€å€‹é¸é …且正常é‹è¡Œï¼Œé€™å€‹å¯èƒ½æœƒå°æ‚¨æœ‰å¹«åŠ©ï¼š" -#: Client/loader/Dialogs.cpp:90 +#: Client/loader/Dialogs.cpp:118 msgid "Force windowed mode" msgstr "å¼·åˆ¶çª—å£æ¨¡å¼" -#: Client/loader/Dialogs.cpp:91 +#: Client/loader/Dialogs.cpp:119 msgid "Don't show again" msgstr "以後ä¸å†é¡¯ç¤º" -#: Client/loader/Dialogs.cpp:98 Client/game_sa/CSettingsSA.cpp:859 +#: Client/loader/Dialogs.cpp:126 Client/game_sa/CSettingsSA.cpp:910 msgid "MTA: San Andreas" msgstr "MTA: San Andreas" -#: Client/loader/Dialogs.cpp:99 +#: Client/loader/Dialogs.cpp:127 msgid "Warning: Could not detect anti-virus product" msgstr "警告:無法檢測到的防病毒軟體" -#: Client/loader/Dialogs.cpp:101 +#: Client/loader/Dialogs.cpp:129 msgid "MTA could not detect an anti-virus on your PC.\n\n" "Viruses interfere with MTA and degrade your gameplay experience.\n\n" "Press 'Help' for more information." @@ -440,1110 +654,1181 @@ msgstr "MTA無法檢測到您的PC上的防病毒軟件。\n\n" "病毒干擾MTA並é™ä½Žä½ çš„éŠæˆ²é«”驗。\n\n" "按下“幫助â€ä»¥ç²å–更多信æ¯ã€‚" -#: Client/loader/Dialogs.cpp:104 +#: Client/loader/Dialogs.cpp:132 msgid "I have already installed an anti-virus" msgstr "我已經安è£äº†é˜²ç—…毒軟體" -#: Client/loader/Dialogs.cpp:106 +#: Client/loader/Dialogs.cpp:134 msgid "I will not install an anti-virus.\n" "I want my PC to lag and be part of a botnet." msgstr "我將ä¸å®‰è£é˜²ç—…毒。\n" "我希望我的PC 變lag,並æˆç‚ºæ®­å±ç¶²çµ¡çš„一部分。" -#: Client/loader/Dialogs.cpp:678 +#: Client/loader/Dialogs.cpp:667 +msgid "The crash you experienced is due to memory abuse by servers.\n\n" +"Even with plenty of RAM, this is a x86 game with address space limits up to 3.6GB and some highly unoptimized servers with a lot of mods (or just a few poorly written scripts) can make this happen, as well as lag your game.\n\n" +"Contact the server owner or MTA support in the MTA official discord (https://discord.gg/mtasa) for more information." +msgstr "" + +#: Client/loader/Dialogs.cpp:673 +msgid "MTA: San Andreas - Out of Memory Information" +msgstr "" + +#: Client/loader/Dialogs.cpp:1024 msgid "Searching for Grand Theft Auto San Andreas" msgstr "æœå°‹ Grand Theft Auto San Andreas 中" -#: Client/loader/Dialogs.cpp:681 +#: Client/loader/Dialogs.cpp:1027 msgid "Please start Grand Theft Auto San Andreas" msgstr "請啟動 GTA SA" -#: Client/loader/Dialogs.cpp:689 Client/loader/Install.cpp:852 -msgid "Installing update..." -msgstr "安装更新..." +#: Client/core/CConnectManager.cpp:85 +msgid "Connecting failed. Invalid nick provided!" +msgstr "連線失敗。無效的匿åID!" -#: Client/loader/Dialogs.cpp:697 Client/loader/Install.cpp:934 -msgid "Extracting files..." -msgstr "解開檔案中..." +#: Client/core/CConnectManager.cpp:116 +msgid "Connecting failed. Invalid host provided!" +msgstr "連線失敗。æä¾›ç„¡æ•ˆçš„主機" -#: Client/loader/Dialogs.cpp:702 Client/loader/Utils.cpp:1391 -msgid "Copying files..." -msgstr "複製文件中..." +#: Client/core/CConnectManager.cpp:132 +#, c-format +msgid "Connecting to %s at port %u failed!" +msgstr "連接到 %s æ–¼åŸ å£ %u 失敗" -#: Client/loader/Dialogs.cpp:707 Client/loader/Utils.cpp:1451 -msgid "Copy finished early. Everything OK." -msgstr "早就完æˆè¤‡è£½ï¼Œä¸€åˆ‡å‡†å‚™å°±ç·’。" +#. Display the status box +#: Client/core/CConnectManager.cpp:153 +#, c-format +msgid "Connecting to %s:%u ..." +msgstr "正在連線至 %s:%u ..." -#: Client/loader/Dialogs.cpp:712 Client/loader/Utils.cpp:1457 -msgid "Finishing..." -msgstr "正在完æˆ..." +#: Client/core/CConnectManager.cpp:155 +#, c-format +msgid "Reconnecting to %s:%u ..." +msgstr "æ­£åœ¨é‡æ–°é€£ç·šè‡³ %s:%u ..." -#: Client/loader/Dialogs.cpp:716 Client/loader/Utils.cpp:1459 -msgid "Done!" -msgstr "完æˆ!" +#. Display the status box +#: Client/core/CConnectManager.cpp:156 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 +msgid "CONNECTING" +msgstr "連接中" -#: Client/loader/CInstallManager.cpp:361 Client/loader/Utils.cpp:965 -#, c-format -msgid "MTA:SA needs Administrator access for the following task:\n\n" -" '%s'\n\n" -"Please confirm in the next window." -msgstr "MTA:SA 需è¦ç‚ºä»¥ä¸‹çš„任務æä¾›ç®¡ç†å“¡æ¬Šé™:\n\n" -" '%s'\n\n" -"請在下一個窗å£é€²è¡Œç¢ºå®šã€‚" +#: Client/core/CConnectManager.cpp:271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1358 +msgid "Connection timed out" +msgstr "連線已逾時" -#: Client/loader/CInstallManager.cpp:376 -#, c-format -msgid "MTA:SA could not complete the following task:\n\n" -" '%s'\n" -msgstr "MTA:SA 無法完æˆä¸‹åˆ—的任務:\n\n" -" '%s'\n" +#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1406 +msgid "Disconnected: unknown protocol error" +msgstr "連線中斷: 未知的å”定錯誤" -#: Client/loader/CInstallManager.cpp:426 -msgid "** The crash was caused by a graphics driver error **\n\n" -"** Please update your graphics drivers **" -msgstr "** 造æˆå´©æ½°çš„原因是一個來自於圖形驅動程å¼çš„錯誤 **\n\n" -"** 請更新你的顯示å¡åœ–å½¢é©…å‹•ç¨‹å¼ **" +#: Client/core/CConnectManager.cpp:293 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1410 +msgid "Disconnected: disconnected remotely" +msgstr "連線中斷: é ç¨‹é€£ç·šä¸­æ–·" -#: Client/loader/CInstallManager.cpp:532 -msgid "Install updated MTA:SA files" -msgstr "安è£å·²æ›´æ–°çš„ MTA:SA 文件" +#: Client/core/CConnectManager.cpp:297 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 +msgid "Disconnected: connection lost remotely" +msgstr "連線中斷: 伺æœå™¨é€£ç·šä¸­æ–·" -#: Client/loader/CInstallManager.cpp:552 -msgid "Could not update due to file conflicts. Please close other applications and retry" -msgstr "由於文件è¡çªå°Žè‡´ç„¡æ³•更新,請關閉其他軟體並é‡è©¦" +#: Client/core/CConnectManager.cpp:301 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1418 +msgid "Disconnected: you are banned from this server" +msgstr "連線中斷: 你已經被å°éŽ–ç¦æ­¢é€²å…¥è©²ä¼ºæœå™¨" -#: Client/loader/CInstallManager.cpp:561 +#: Client/core/CConnectManager.cpp:308 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +msgid "Disconnected: disconnected from the server" +msgstr "連線中斷: 伺æœå™¨é€£ç·šä¸­æ–·" + +#: Client/core/CConnectManager.cpp:312 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1430 +msgid "Disconnected: connection to the server was lost" +msgstr "連線中斷: 與伺æœå™¨çš„連線已éºå¤±" + +#: Client/core/CConnectManager.cpp:319 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 +msgid "Disconnected: connection was refused" +msgstr "連線中斷: 連線已被拒絕" + +#. Failed loading the mod +#: Client/core/CConnectManager.cpp:414 #, c-format -msgid "Multi Theft Auto has not been installed properly, please reinstall. %s" -msgstr "MTA 並沒有被正確安è£ï¼Œè«‹é‡æ–°å®‰è£ã€‚%s" +msgid "No such mod installed (%s)" +msgstr "æœªç™¼ç¾æŒ‡å®šçš„ Mod (%s)" -#: Client/loader/CInstallManager.cpp:613 -msgid "Create GTA:SA junctions" -msgstr "創建GTA:SA交匯點" +#: Client/core/CConnectManager.cpp:422 +msgid "Bad server response (2)" +msgstr "ä¸ç•¶çš„伺æœå™¨å›žæ‡‰ (2)" -#: Client/loader/CInstallManager.cpp:657 -msgid "MTA:SA cannot launch because copying a file failed:" -msgstr "MTA:SA 無法順利啟動,因為複製檔案失敗:" +#: Client/core/CConnectManager.cpp:432 +msgid "Bad server response (1)" +msgstr "ä¸ç•¶çš„伺æœå™¨å›žæ‡‰ (1)" -#: Client/loader/CInstallManager.cpp:663 Client/loader/CInstallManager.cpp:703 -msgid "MTA:SA cannot launch because an MTA:SA file is incorrect or missing:" -msgstr "MTA:SA 無法順利啟動,因為 MTA:SA 的檔案有錯誤或是éºå¤±ï¼š" +#. TRANSLATORS: Replace with your language native name +#: Client/core/CLocalization.cpp:16 +msgid "English" +msgstr "ç¹é«”中文" -#: Client/loader/CInstallManager.cpp:672 -msgid "Copy MTA:SA files" -msgstr "複製 MTA:SA 檔案" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Busy" +msgstr "忙碌" -#: Client/loader/CInstallManager.cpp:695 Client/loader/CInstallManager.cpp:773 -msgid "MTA:SA cannot launch because a GTA:SA file is incorrect or missing:" -msgstr "MTA:SA 無法啟動,因為 GTA:SA ä¸»ç¨‹å¼æœ¬é«”的檔案有錯誤或éºå¤±ï¼š" +#: Client/core/CVersionUpdater.cpp:627 +msgid "Can't check for updates right now" +msgstr "ç›®å‰ç„¡æ³•檢查更新" -#: Client/loader/CInstallManager.cpp:780 -msgid "Patch GTA:SA dependency" -msgstr "修補 GTA:SA çš„ä¾è³´é …" +#: Client/core/CVersionUpdater.cpp:1630 Client/core/CVersionUpdater.cpp:1650 +#: Client/core/CVersionUpdater.cpp:1668 +#, c-format +msgid "MTA:SA %s required" +msgstr "éœ€è¦ MTA:SA %s" -#: Client/loader/CInstallManager.cpp:828 -msgid "MTA:SA cannot launch because the GTA:SA executable is incorrect or missing:" -msgstr "MTA:SA 無法順利啟動,因為 GTA:SA 主程å¼åŸ·è¡Œæª”有錯誤或是éºå¤±ï¼š" +#: Client/core/CVersionUpdater.cpp:1631 +#, c-format +msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" +"Do you want to download and install MTA:SA %s ?" +msgstr "若想加入目å‰çš„伺æœå™¨ï¼Œéœ€è¦å®‰è£æ›´æ–°ç‰ˆæœ¬çš„MTA:SA %s。\n\n" +"你想è¦ç¾åœ¨ä¸‹è¼‰åŠå®‰è£ MTA:SA %s å—Ž?" -#: Client/loader/CInstallManager.cpp:832 -msgid "Please check your anti-virus for a false-positive detection, try to add an exception for the GTA:SA executable and restart MTA:SA." -msgstr "è«‹æª¢æŸ¥æ‚¨çš„é˜²æ¯’è»Ÿé«”æ˜¯å¦æœ‰èª¤åˆ¤çš„æƒ…形,å¯å˜—試將GTA:SA主程å¼åŸ·è¡Œæª”åŠ å…¥æŽ’é™¤æ¸…å–®ï¼Œç„¶å¾Œé‡æ–°å•Ÿå‹•MTA:SA。" +#: Client/core/CVersionUpdater.cpp:1651 +#, c-format +msgid "Do you want to launch MTA:SA %s and connect to this server ?" +msgstr "你想è¦å•Ÿå‹• MTA:SA %s 並連線到該伺æœå™¨å—Ž?" -#: Client/loader/CInstallManager.cpp:838 -msgid "Generate GTA:SA" -msgstr "ç”Ÿæˆ GTA:SA" +#: Client/core/CVersionUpdater.cpp:1669 +msgid "It is not possible to connect at this time.\n\n" +"Please try later." +msgstr "ç¾åœ¨ä¸å¯èƒ½é€£ç·šã€‚\n\n" +"è«‹ç¨å¾Œå†è©¦ã€‚" + +#: Client/core/CVersionUpdater.cpp:1851 +msgid "Connecting" +msgstr "連線中" + +#: Client/core/CVersionUpdater.cpp:1852 Client/core/CVersionUpdater.cpp:1868 +msgid "Please wait..." +msgstr "è«‹ç¨ç­‰..." -#: Client/loader/CInstallManager.cpp:853 -msgid "MTA:SA cannot launch because the GTA:SA executable is not loadable:" -msgstr "MTA:SA 無法順利啟動,因為 GTA:SA 主程å¼åŸ·è¡Œæª”無法被讀å–:" +#: Client/core/CVersionUpdater.cpp:1867 +msgid "CHECKING" +msgstr "檢查中" -#: Client/loader/CInstallManager.cpp:860 Client/loader/CInstallManager.cpp:883 -msgid "Patch GTA:SA" -msgstr "修補 GTA:SA" +#: Client/core/CVersionUpdater.cpp:1884 Client/core/CVersionUpdater.cpp:1977 +msgid "UPDATE CHECK" +msgstr "更新檢查" -#: Client/loader/CInstallManager.cpp:876 -msgid "MTA:SA cannot launch because patching GTA:SA has failed:" -msgstr "MTA:SA 無法順利啟動,因為修補GTA:SA主程å¼å¤±æ•—:" +#: Client/core/CVersionUpdater.cpp:1885 +msgid "No update needed" +msgstr "ä¸éœ€è¦æ›´æ–°" -#: Client/loader/CInstallManager.cpp:1057 Client/core/CCore.cpp:811 -#, c-format -msgid "MTA:SA cannot continue because drive %s does not have enough space." -msgstr "MTASAä¸èƒ½ç¹¼çºŒ,因為ç£ç¢Ÿæ©Ÿ %s 空間ä¸è¶³" +#: Client/core/CVersionUpdater.cpp:1902 +msgid "DOWNLOADING" +msgstr "下載中" -#: Client/loader/CInstallManager.cpp:1113 -msgid "Missing file:" -msgstr "éºå¤±æª”案:" +#: Client/core/CVersionUpdater.cpp:1903 +msgid "waiting..." +msgstr "等待..." -#: Client/loader/CInstallManager.cpp:1117 -msgid "If MTA fails to load, please re-install GTA:SA" -msgstr "如果MTAè¼‰å…¥å¤±æ•—ï¼Œè«‹é‡æ–°å®‰è£ GTA:SA" +#: Client/core/CVersionUpdater.cpp:1919 +msgid "MANDATORY UPDATE" +msgstr "強制性更新" -#: Client/loader/CInstallManager.cpp:1152 -msgid "Update install settings" -msgstr "更新安è£è¨­å®š" +#: Client/core/CVersionUpdater.cpp:1920 +msgid "To join this server, you must update MTA.\n\n" +" Do you want to update now ?" +msgstr "è¦åŠ å…¥é€™ä¼ºæœå™¨ï¼Œä½ å¿…須更新 MTA。\n\n" +"你希望ç¾åœ¨æ›´æ–°å—Ž?" -#: Client/loader/CInstallManager.cpp:1305 -msgid "Update compatibility settings" -msgstr "更新相容性設置" +#: Client/core/CVersionUpdater.cpp:1938 +msgid "OPTIONAL UPDATE" +msgstr "å¯é¸æ“‡æ€§æ›´æ–°" -#: Client/loader/Install.cpp:265 -msgid "Unknown" -msgstr "未知" +#: Client/core/CVersionUpdater.cpp:1939 +msgid "Server says an update is recommended, but not essential.\n\n" +" Do you want to update now ?" +msgstr "伺æœå™¨è¡¨ç¤ºå»ºè­°ä½ é€²è¡Œæ›´æ–°ï¼Œä½†ä¸¦éžä¸€å®šè¦ã€‚\n\n" +"你想è¦ç¾åœ¨æ›´æ–°å—Ž?" -#: Client/loader/Install.cpp:272 -#, c-format -msgid "The file '%s' is currently locked by %zu processes.\n\n" -"Do you want to terminate the following processes and continue updating?\n\n" -"%s" -msgstr "檔案 '%s' ç›®å‰è¢« %zu 個處ç†ç¨‹åºéŽ–å®šã€‚\n\n" -"是å¦è¦çµ‚止下列處ç†ç¨‹åºä¸¦ç¹¼çºŒæ›´æ–°ï¼Ÿ\n\n" -"%s" +#: Client/core/CVersionUpdater.cpp:1978 +msgid "An update is currently not available.\n\n" +"Please check www.multitheftauto.com" +msgstr "ç›®å‰æ²’有å¯ç”¨çš„æ›´æ–°ã€‚\n\n" +"請至 www.multitheftauto.com 確èª" -#: Client/loader/Install.cpp:479 -#, c-format -msgid "Your installation may be corrupt now.\n\n" -"%zu out of %zu files could not be restored from the backup.\n\n" -"You should reinstall Multi Theft Auto from www.multitheftauto.com\n" -"or try running the update with administrator rights." -msgstr "您的安è£ç¾åœ¨å‡ºç¾å•題å¯èƒ½å·²ææ¯€ã€‚\n\n" -"%zu / %zu 個檔案無法從備份中還原。\n\n" -"您應該從 www.multitheftauto.com 釿–°å®‰è£ Multi Theft Auto\n" -"或嘗試以管ç†å“¡èº«åˆ†åŸ·è¡Œæ›´æ–°ã€‚" +#: Client/core/CVersionUpdater.cpp:1999 Client/core/CVersionUpdater.cpp:2181 +msgid "ERROR SAVING" +msgstr "錯誤ä¿å­˜" -#: Client/loader/Utils.cpp:535 -msgid "Start Grand Theft Auto: San Andreas.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "啟動俠盜çµè»Šæ‰‹ï¼šè–安地列斯。\n" -"請確èªéŠæˆ²å®‰è£åœ¨ 'Program Files (x86)' 資料夾。" +#: Client/core/CVersionUpdater.cpp:2000 Client/core/CVersionUpdater.cpp:2182 +msgid "Unable to create the file." +msgstr "無法建立檔案" -#: Client/loader/Utils.cpp:535 Client/loader/Utils.cpp:548 -msgid "Searching for GTA: San Andreas" -msgstr "æœå°‹ 俠盜çµè»Šæ‰‹ï¼šè–安地列斯" +#: Client/core/CVersionUpdater.cpp:2008 Client/core/CVersionUpdater.cpp:2017 +#: Client/core/CVersionUpdater.cpp:2190 Client/core/CVersionUpdater.cpp:2199 +msgid "ERROR DOWNLOADING" +msgstr "下載錯誤" -#: Client/loader/Utils.cpp:548 -msgid "Sorry, game not found.\n" -"Start Grand Theft Auto: San Andreas and click retry.\n" -"Ensure the game is placed in the 'Program Files (x86)' folder." -msgstr "å¾ˆæŠ±æ­‰ï¼Œçœ‹èµ·ä¾†æ²’æœ‰æ‰¾åˆ°éŠæˆ²æœ¬é«”。\n" -"請啟動 俠盜çµè»Šæ‰‹ï¼šè–安地列斯 後å†é‡è©¦ä¸€æ¬¡ã€‚\n" -"並請確èªéŠæˆ²å®‰è£åœ¨ 'Program Files (x86)' 資料夾。" +#: Client/core/CVersionUpdater.cpp:2009 Client/core/CVersionUpdater.cpp:2191 +msgid "The downloaded file appears to be incorrect." +msgstr "ä¸‹è¼‰çš„æ–‡ä»¶ä¸æ­£ç¢º" -#: Client/loader/Utils.cpp:597 -msgid "Select your Grand Theft Auto: San Andreas Installation Directory" -msgstr "鏿“‡ä½ Grand Theft Auto: San Andreas的安è£ç›®éŒ„" +#: Client/core/CVersionUpdater.cpp:2018 Client/core/CVersionUpdater.cpp:2200 +msgid "For some reason." +msgstr "因為æŸäº›åŽŸå› ã€‚" -#: Client/loader/Utils.cpp:1066 -#, c-format -msgid "Error loading %s module! (%s)" -msgstr "錯誤載入 %s 模組!(%s)" +#: Client/core/CVersionUpdater.cpp:2029 Client/core/CVersionUpdater.cpp:2213 +msgid "DOWNLOAD COMPLETE" +msgstr "下載完æˆ" -#: Client/loader/Utils.cpp:1499 -#, c-format -msgid "New installation of %s detected.\n\n" -"Do you want to copy your settings from %s ?" -msgstr "檢測到新安è£çš„%s\n\n" -"您想去複製您的設定從%s ?" +#: Client/core/CVersionUpdater.cpp:2053 +msgid " - Unknown problem in _DialogUpdateResult" +msgstr "- 未知的å•題發生在 _DialogUpdateResult" -#: Client/loader/Utils.cpp:1538 -#, c-format -msgid "GTA:SA had trouble opening the file '%s'" -msgstr "GTA:SA é‡åˆ°å•題在打開文件 '%s'時" +#: Client/core/CVersionUpdater.cpp:2144 Client/core/CSettings.cpp:5731 +msgid "CUSTOMIZED GTA:SA FILES" +msgstr "已修改俠盜çµè»Šæ‰‹:è–安地列斯的文件檔" -#: Client/loader/Utils.cpp:1560 -#, c-format -msgid "GTA:SA is missing the file '%s'." -msgstr "GTA:SA éºå¤±é€™å€‹ '%s' 檔案" +#: Client/core/CVersionUpdater.cpp:2151 Client/core/CVersionUpdater.cpp:2161 +msgid "Ok" +msgstr "確定" -#: Client/loader/Utils.cpp:1585 -msgid "GTA:SA had trouble loading a model." -msgstr "GTA:SA 在載入模組時é‡åˆ°å•題." +#: Client/core/CVersionUpdater.cpp:2159 +msgid "ERROR" +msgstr "錯誤" -#: Client/loader/Utils.cpp:1587 -msgid "If you recently modified gta3.img, then try reinstalling GTA:SA." -msgstr "若是您有修改éŽgta3.imgï¼Œè«‹è©¦è‘—é‡æ–°å®‰è£GTA:SA。" +#: Client/core/CVersionUpdater.cpp:2160 +msgid "Some MTA:SA data files are missing.\n\n\n" +"Please reinstall MTA:SA" +msgstr "æŸäº› MTA:SA資料éºå¤±\n\n\n" +"è«‹é‡æ–°å®‰è£ MTA:SA" -#: Client/loader/Utils.cpp:1612 -msgid "GTA:SA had trouble adding an upgrade to a vehicle." -msgstr "GTA:SA 發生å•題在新增å‡ç´šè»Šè¼›æ™‚" +#: Client/core/CVersionUpdater.cpp:2837 +#, c-format +msgid "%3d %% completed" +msgstr "%3d %% 已完æˆ" -#: Client/loader/Utils.cpp:1631 +#: Client/core/CVersionUpdater.cpp:2840 #, c-format -msgid "GTA:SA found errors in the file '%s'" -msgstr "GTA:SA é‹è¡Œæ™‚在檔案 '%s' 發生錯誤" +msgid "\n\n" +"Waiting for response - %-3d" +msgstr "\n\n" +"等待回應中 - %-3d" -#: Client/loader/Utils.cpp:1713 -msgid "Did your computer restart when playing MTA:SA?" -msgstr "在玩 MTA:SA時,您的電腦é‡èµ·å—Ž?" +#: Client/core/CCommandFuncs.cpp:24 +msgid "***[ COMMAND HELP ]***\n" +msgstr "***[ 指令幫助 ]***\n" -#: Client/loader/Utils.cpp:1778 -msgid "Please terminate the following programs before continuing:" -msgstr "請在繼續之å‰çµ‚止下列程å¼:" +#: Client/core/CCommandFuncs.cpp:158 +#, c-format +msgid "* The time is %d:%02d:%02d" +msgstr "* ç¾åœ¨æ™‚間是 %d:%02d:%02d" -#: Client/cefweb/CWebsiteRequests.cpp:19 -msgid "Website requests" -msgstr "網站請求" +#: Client/core/CCommandFuncs.cpp:191 +msgid "connect: Network is not ready, please wait a moment" +msgstr "連線:網路未就緒,請ç¨å€™" -#: Client/cefweb/CWebsiteRequests.cpp:27 -msgid "The server requests the following websites in order to load them (later):" -msgstr "ç¾åœ¨çš„伺æœå™¨ (以後) 需è¦è®€å–以下網站:" +#: Client/core/CCommandFuncs.cpp:225 +msgid "connect: Syntax is 'connect [ ]'" +msgstr "連線: 指令為 'connect <伺æœå™¨> [<連接埠> <暱稱> <密碼>]'" -#: Client/cefweb/CWebsiteRequests.cpp:33 -msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" -msgstr "為了防止您é‡è¦è³‡è¨Šè¢«ç«Šå–,請ä¸è¦è¼¸å…¥ä»»ä½•éš±ç§è¨Šæ¯" +#: Client/core/CCommandFuncs.cpp:233 +msgid "connect: Bad port number" +msgstr "連線: 無效的連接埠號碼" -#: Client/cefweb/CWebsiteRequests.cpp:46 -msgid "Remember decision" -msgstr "è¨˜ä½æˆ‘çš„é¸æ“‡" +#: Client/core/CCommandFuncs.cpp:255 +#, c-format +msgid "connect: Connecting to %s:%u..." +msgstr "連線: 正在連線到 %s:%u..." -#: Client/cefweb/CWebsiteRequests.cpp:51 Client/core/CSettings.cpp:1008 -msgid "Allow" -msgstr "å…許" +#: Client/core/CCommandFuncs.cpp:259 +#, c-format +msgid "connect: could not connect to %s:%u!" +msgstr "連線: 無法連線到 %s:%u!" -#: Client/cefweb/CWebsiteRequests.cpp:57 -msgid "Deny" -msgstr "拒絕" +#: Client/core/CCommandFuncs.cpp:264 +msgid "connect: Failed to unload current mod" +msgstr "連線: 移除指定 mod 失敗" -#: Client/core/CMainMenu.cpp:303 Client/core/CSettings.cpp:3569 -#: Client/core/CCore.cpp:674 Client/mods/deathmatch/logic/CClientGame.cpp:541 -msgid "Main menu" -msgstr "主é¸å–®" +#: Client/core/CCommandFuncs.cpp:284 +msgid "reconnect: Network is not ready, please wait a moment" +msgstr "釿–°é€£ç·šï¼šç¶²è·¯æœªå°±ç·’,請ç¨å€™" -#: Client/core/CMainMenu.cpp:332 -msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" -msgstr "æ‚¨æ­£åœ¨ä½¿ç”¨åˆ†æ”¯æ§‹å»ºçš„ç‰ˆæœ¬ï¼æ§‹å»ºç‰ˆæœ¬ä¸¦ç„¡æ³•用來連接公開伺æœå™¨ï¼" +#: Client/core/CCommandFuncs.cpp:306 +msgid "reconnect: Bad port number" +msgstr "釿–°é€£ç·šï¼šéŒ¯èª¤çš„連接埠號碼" -#: Client/core/CMainMenu.cpp:351 -msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" -"Upgrade Windows to play on the latest servers." -msgstr "MTA自2019å¹´7月以後將ä¸å†æ›´æ–°XP/Vista的版本。\n\n" -"è«‹å‡ç´šæ‚¨çš„Windows以便在最新版本的伺æœå™¨æš¢éŠã€‚" +#: Client/core/CCommandFuncs.cpp:325 +#, c-format +msgid "reconnect: Reconnecting to %s:%u..." +msgstr "釿–°é€£ç·šï¼šæ­£åœ¨é‡æ–°é€£ç·šåˆ° %s:%u..." -#: Client/core/CMainMenu.cpp:1195 -msgid "This will disconnect you from the current server.\n\n" -"Are you sure you want to disconnect?" -msgstr "這將會使你從目å‰ä¼ºæœå™¨çµæŸé€£ç·šã€‚\n\n" -"你確定è¦çµæŸé€£ç·šå—Ž?" +#: Client/core/CCommandFuncs.cpp:329 +#, c-format +msgid "reconnect: could not connect to %s:%u!" +msgstr "釿–°é€£ç·šï¼šç„¡æ³•連線到 %s:%uï¼" -#: Client/core/CMainMenu.cpp:1199 -msgid "DISCONNECT WARNING" -msgstr "斷線警告" +#: Client/core/CCommandFuncs.cpp:363 +msgid "Bound all controls from GTA" +msgstr "ç¶å®šGTA 所有的控制設定" -#: Client/core/CMainMenu.cpp:1220 -msgid "INFORMATION" -msgstr "資訊" +#: Client/core/CCommandFuncs.cpp:377 +msgid "Saved configuration file" +msgstr "設定已經ä¿å­˜" -#. TRANSLATORS: Replace with your language native name -#: Client/core/CLocalization.cpp:16 -msgid "English" -msgstr "ç¹é«”中文" +#. Print it +#: Client/core/CCommandFuncs.cpp:456 +#, c-format +msgid "* Your serial is: %s" +msgstr "* 您的åºåˆ—號為: %s" #. Create window (with frame) if it will fit inside the screen resolution -#: Client/core/CSettings.cpp:85 +#: Client/core/CSettings.cpp:503 msgid "SETTINGS" msgstr "設定" -#: Client/core/CSettings.cpp:117 +#: Client/core/CSettings.cpp:549 msgid "Multiplayer" msgstr "多人" -#: Client/core/CSettings.cpp:118 +#: Client/core/CSettings.cpp:550 msgid "Video" msgstr "視訊" -#: Client/core/CSettings.cpp:119 +#: Client/core/CSettings.cpp:551 +msgid "PostFX" +msgstr "" + +#: Client/core/CSettings.cpp:552 msgid "Audio" msgstr "音效" -#: Client/core/CSettings.cpp:120 +#: Client/core/CSettings.cpp:553 msgid "Binds" msgstr "ç¶å®š" -#: Client/core/CSettings.cpp:121 +#: Client/core/CSettings.cpp:554 msgid "Controls" msgstr "控制" -#: Client/core/CSettings.cpp:122 +#: Client/core/CSettings.cpp:555 msgid "Interface" msgstr "界é¢" -#: Client/core/CSettings.cpp:123 +#: Client/core/CSettings.cpp:556 msgid "Web Browser" msgstr "ç€è¦½å™¨" -#: Client/core/CSettings.cpp:124 +#: Client/core/CSettings.cpp:557 msgid "Advanced" msgstr "進階" -#: Client/core/CSettings.cpp:148 Client/core/CSettings.cpp:339 -#: Client/core/CSettings.cpp:650 Client/core/CSettings.cpp:919 +#: Client/core/CSettings.cpp:582 Client/core/CSettings.cpp:790 +#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:1415 msgid "Load defaults" msgstr "載入é è¨­å€¼" #. * #. * Controls tab #. * -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:182 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:623 msgid "Mouse sensitivity:" msgstr "æ»‘é¼ éˆæ•度:" #. VerticalAimSensitivity -#: Client/core/CSettings.cpp:158 Client/core/CSettings.cpp:200 +#: Client/core/CSettings.cpp:599 Client/core/CSettings.cpp:644 msgid "Vertical aim sensitivity:" msgstr "åž‚ç›´çž„å‡†éˆæ•度:" #. Mouse Options -#: Client/core/CSettings.cpp:161 +#: Client/core/CSettings.cpp:602 msgid "Mouse options" msgstr "滑鼠é¸é …" -#: Client/core/CSettings.cpp:168 +#: Client/core/CSettings.cpp:609 msgid "Invert mouse vertically" msgstr "å轉滑鼠垂直方å‘" -#: Client/core/CSettings.cpp:172 +#: Client/core/CSettings.cpp:613 msgid "Steer with mouse" msgstr "使用滑鼠轉å‘" -#: Client/core/CSettings.cpp:176 +#: Client/core/CSettings.cpp:617 msgid "Fly with mouse" msgstr "使用滑鼠飛行" +#: Client/core/CSettings.cpp:663 +msgid "Use mouse sensitivity for aiming" +msgstr "" + #. Joypad options -#: Client/core/CSettings.cpp:218 +#: Client/core/CSettings.cpp:669 msgid "Joypad options" msgstr "手把é¸é …" -#: Client/core/CSettings.cpp:231 +#: Client/core/CSettings.cpp:682 msgid "Standard controls (Mouse + Keyboard)" msgstr "標準控制(滑鼠+éµç›¤)" -#: Client/core/CSettings.cpp:238 +#: Client/core/CSettings.cpp:689 msgid "Classic controls (Joypad)" msgstr "經典控制(手把)" -#: Client/core/CSettings.cpp:275 +#: Client/core/CSettings.cpp:726 msgid "Dead Zone" msgstr "死亡å€åŸŸ" -#: Client/core/CSettings.cpp:280 +#: Client/core/CSettings.cpp:731 msgid "Saturation" msgstr "飽和度" -#: Client/core/CSettings.cpp:286 +#: Client/core/CSettings.cpp:737 msgid "Use the 'Binds' tab for joypad buttons." msgstr "使用“ç¶å®šâ€éµä½œç‚ºæ‰‹æŠŠæŒ‰éˆ•." -#: Client/core/CSettings.cpp:325 +#: Client/core/CSettings.cpp:776 msgid "Left Stick" msgstr "å·¦æ–æ¡¿" -#: Client/core/CSettings.cpp:331 +#: Client/core/CSettings.cpp:782 msgid "Right Stick" msgstr "峿–æ¡¿" -#: Client/core/CSettings.cpp:346 +#: Client/core/CSettings.cpp:797 msgid "DESCRIPTION" msgstr "æè¿°" -#: Client/core/CSettings.cpp:347 +#: Client/core/CSettings.cpp:798 msgid "KEY" msgstr "按éµ" -#: Client/core/CSettings.cpp:349 +#: Client/core/CSettings.cpp:800 msgid "ALT. KEY" msgstr "ALT. å¿«éµéµ" #. * #. * Multiplayer tab #. * -#: Client/core/CSettings.cpp:354 Client/core/CSettings.cpp:357 +#: Client/core/CSettings.cpp:805 Client/core/CSettings.cpp:808 msgid "Nick:" msgstr "暱稱:" -#: Client/core/CSettings.cpp:379 +#: Client/core/CSettings.cpp:830 msgid "Save server passwords" msgstr "儲存伺æœå™¨å¯†ç¢¼" -#: Client/core/CSettings.cpp:384 +#: Client/core/CSettings.cpp:835 msgid "Auto-refresh server browser" msgstr "è‡ªå‹•é‡æ•´ä¼ºæœå™¨ç€è¦½å™¨" -#: Client/core/CSettings.cpp:389 +#: Client/core/CSettings.cpp:840 msgid "Allow screen upload" msgstr "å…許畫é¢ä¸Šå‚³" -#: Client/core/CSettings.cpp:394 +#: Client/core/CSettings.cpp:845 msgid "Allow external sounds" msgstr "å…許外部音效" -#: Client/core/CSettings.cpp:399 +#: Client/core/CSettings.cpp:850 msgid "Always show download window" msgstr "總是顯示下載視窗" -#: Client/core/CSettings.cpp:404 +#: Client/core/CSettings.cpp:855 msgid "Allow connecting with Discord Rich Presence" msgstr "å…許é€éŽ Discord Rich Presence 連線顯示 Discord 狀態" -#: Client/core/CSettings.cpp:409 +#: Client/core/CSettings.cpp:860 msgid "Allow GTA:SA ingame status on Steam" msgstr "" #. Enable camera photos getting saved to documents folder -#: Client/core/CSettings.cpp:415 +#: Client/core/CSettings.cpp:866 msgid "Save photos taken by camera weapon to GTA San Andreas User Files folder" msgstr "å°‡ç›¸æ©Ÿæ­¦å™¨æ‹æ”的照片儲存到 GTA San Andreas User Files 資料夾" -#: Client/core/CSettings.cpp:420 +#: Client/core/CSettings.cpp:871 msgid "Ask before disconnecting from server using main menu" msgstr "在主é¸å–®ä¸­æ–·ä¼ºæœå™¨é€£ç·šå‰å…ˆè©¢å•" -#: Client/core/CSettings.cpp:425 +#: Client/core/CSettings.cpp:876 msgid "Use customized GTA:SA files" msgstr "使用自訂的俠盜çµè»Šæ‰‹:è–安地列斯文件" -#: Client/core/CSettings.cpp:430 +#: Client/core/CSettings.cpp:881 msgid "Map rendering options" msgstr "地圖渲染é¸é …" -#: Client/core/CSettings.cpp:438 +#: Client/core/CSettings.cpp:889 msgid "Opacity:" msgstr "ä¸é€æ˜Žåº¦:" -#: Client/core/CSettings.cpp:458 +#: Client/core/CSettings.cpp:912 msgid "Image resolution:" msgstr "å½±åƒè§£æžåº¦ï¼š" -#: Client/core/CSettings.cpp:465 +#: Client/core/CSettings.cpp:919 msgid "1024 x 1024 (Default)" msgstr "1024 x 1024 (é è¨­)" #. index 0 -#: Client/core/CSettings.cpp:466 +#: Client/core/CSettings.cpp:920 msgid "2048 x 2048" msgstr "2048 x 2048" #. * #. * Audio tab #. * -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:481 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:935 msgid "Master volume:" msgstr "主音é‡ï¼š" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:500 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:957 msgid "Radio volume:" msgstr "é›»å°éŸ³é‡:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:519 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:979 msgid "SFX volume:" msgstr "SFX音é‡:" -#: Client/core/CSettings.cpp:472 Client/core/CSettings.cpp:538 +#: Client/core/CSettings.cpp:926 Client/core/CSettings.cpp:1001 msgid "MTA volume:" msgstr "MTA音é‡ï¼š" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:557 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1023 msgid "Voice volume:" msgstr "語音音é‡:" -#: Client/core/CSettings.cpp:473 Client/core/CSettings.cpp:598 +#: Client/core/CSettings.cpp:927 Client/core/CSettings.cpp:1067 msgid "Play mode:" msgstr "éŠæˆ²æ¨¡å¼:" -#. * -#. * Webbrowser tab -#. * -#: Client/core/CSettings.cpp:475 Client/core/CSettings.cpp:934 -#: Client/core/CSettings.cpp:2070 +#: Client/core/CSettings.cpp:929 Client/core/CSettings.cpp:1548 +#: Client/core/CSettings.cpp:2916 #: Client/mods/deathmatch/logic/CLocalServer.cpp:51 msgid "General" msgstr "一般" -#: Client/core/CSettings.cpp:576 +#: Client/core/CSettings.cpp:1045 msgid "Radio options" msgstr "é›»å°è¨­å®š" -#: Client/core/CSettings.cpp:582 +#: Client/core/CSettings.cpp:1051 msgid "Radio Equalizer" msgstr "é›»å°å‡è¡¡å™¨" -#: Client/core/CSettings.cpp:587 +#: Client/core/CSettings.cpp:1056 msgid "Radio Auto-tune" msgstr "自動調整電å°" -#: Client/core/CSettings.cpp:592 +#: Client/core/CSettings.cpp:1061 msgid "Usertrack options" msgstr "使用者自訂音訊é¸é …" -#: Client/core/CSettings.cpp:606 Client/core/CSettings.cpp:3151 +#: Client/core/CSettings.cpp:1075 Client/core/CSettings.cpp:4001 msgid "Radio" msgstr "é›»å°" -#: Client/core/CSettings.cpp:607 Client/core/CSettings.cpp:3153 +#: Client/core/CSettings.cpp:1076 Client/core/CSettings.cpp:4003 msgid "Random" msgstr "隨機" -#: Client/core/CSettings.cpp:608 Client/core/CSettings.cpp:3155 +#: Client/core/CSettings.cpp:1077 Client/core/CSettings.cpp:4005 msgid "Sequential" msgstr "é †åº" -#: Client/core/CSettings.cpp:611 +#: Client/core/CSettings.cpp:1080 msgid "Automatic Media Scan" msgstr "自動掃æåª’é«”" -#: Client/core/CSettings.cpp:618 +#: Client/core/CSettings.cpp:1087 msgid "Mute options" msgstr "éœéŸ³è¨­å®š" -#: Client/core/CSettings.cpp:624 +#: Client/core/CSettings.cpp:1093 msgid "Mute All sounds when minimized" msgstr "最å°åŒ–時éœéŸ³æ‰€æœ‰éŸ³é‡" -#: Client/core/CSettings.cpp:629 +#: Client/core/CSettings.cpp:1098 msgid "Mute Radio sounds when minimized" msgstr "最å°åŒ–時éœéŸ³é›»å°éŸ³é‡" -#: Client/core/CSettings.cpp:634 +#: Client/core/CSettings.cpp:1103 msgid "Mute SFX sounds when minimized" msgstr "最å°åŒ–時éœéŸ³éŸ³æ•ˆ" -#: Client/core/CSettings.cpp:639 +#: Client/core/CSettings.cpp:1108 msgid "Mute MTA sounds when minimized" msgstr "最å°åŒ–時éœéŸ³MTA音é‡" -#: Client/core/CSettings.cpp:644 +#: Client/core/CSettings.cpp:1113 msgid "Mute Voice sounds when minimized" msgstr "最å°åŒ–時éœéŸ³èªžéŸ³éŸ³é‡" #. * #. * Video tab #. * -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:666 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1135 msgid "Resolution:" msgstr "è§£æžåº¦:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:713 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1190 msgid "FOV:" msgstr "視角è·é›¢ FOV:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:729 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1209 msgid "Draw Distance:" msgstr "顯示è·é›¢:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:747 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1230 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1461 msgid "Brightness:" msgstr "亮度:" -#: Client/core/CSettings.cpp:660 Client/core/CSettings.cpp:765 +#: Client/core/CSettings.cpp:1129 Client/core/CSettings.cpp:1251 msgid "FX Quality:" msgstr "FX 畫質:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:779 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1265 msgid "Anisotropic filtering:" msgstr "éžç­‰å‘éŽæ¿¾:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:806 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1302 msgid "Anti-aliasing:" msgstr "å鋸齒:" -#: Client/core/CSettings.cpp:661 Client/core/CSettings.cpp:820 +#: Client/core/CSettings.cpp:1130 Client/core/CSettings.cpp:1316 msgid "Aspect Ratio:" msgstr "ç•«é¢æ¯”例:" -#: Client/core/CSettings.cpp:678 +#: Client/core/CSettings.cpp:1147 msgid "Windowed" msgstr "視窗化" -#: Client/core/CSettings.cpp:684 +#: Client/core/CSettings.cpp:1153 msgid "DPI aware" msgstr "DPI感知" -#: Client/core/CSettings.cpp:699 Client/core/CSettings.cpp:1658 +#: Client/core/CSettings.cpp:1170 Client/core/CSettings.cpp:2335 msgid "Standard" msgstr "標準" -#: Client/core/CSettings.cpp:701 Client/core/CSettings.cpp:1662 +#: Client/core/CSettings.cpp:1172 Client/core/CSettings.cpp:2339 msgid "Borderless keep res" msgstr "ä¿æŒè§£æžåº¦çš„無邊框" -#: Client/core/CSettings.cpp:705 +#: Client/core/CSettings.cpp:1175 msgid "Mip Mapping" msgstr "å¤šé‡æè³ªè²¼åœ–" -#: Client/core/CSettings.cpp:773 Client/core/CSettings.cpp:1562 +#: Client/core/CSettings.cpp:1182 +msgid "V-Sync" +msgstr "" + +#: Client/core/CSettings.cpp:1259 Client/core/CSettings.cpp:2239 msgid "Low" msgstr "低" -#: Client/core/CSettings.cpp:774 Client/core/CSettings.cpp:1564 +#: Client/core/CSettings.cpp:1260 Client/core/CSettings.cpp:2241 msgid "Medium" msgstr "中等" -#: Client/core/CSettings.cpp:775 Client/core/CSettings.cpp:1121 -#: Client/core/CSettings.cpp:1566 Client/core/CSettings.cpp:3209 +#: Client/core/CSettings.cpp:1261 Client/core/CSettings.cpp:1755 +#: Client/core/CSettings.cpp:2243 Client/core/CSettings.cpp:4059 msgid "High" msgstr "高" -#: Client/core/CSettings.cpp:776 Client/core/CSettings.cpp:1568 +#: Client/core/CSettings.cpp:1262 Client/core/CSettings.cpp:2245 msgid "Very high" msgstr "éžå¸¸é«˜" -#: Client/core/CSettings.cpp:791 Client/core/CSettings.cpp:814 -#: Client/core/CSettings.cpp:1052 Client/core/CSettings.cpp:1106 -#: Client/core/CSettings.cpp:1242 Client/core/CSettings.cpp:1572 -#: Client/core/CSettings.cpp:3216 Client/core/CSettings.cpp:3248 -#: Client/core/CSettings.cpp:3294 Client/core/CSettings.cpp:4369 +#: Client/core/CSettings.cpp:1279 Client/core/CSettings.cpp:1282 +#: Client/core/CSettings.cpp:1310 Client/core/CSettings.cpp:1686 +#: Client/core/CSettings.cpp:1740 Client/core/CSettings.cpp:1889 +#: Client/core/CSettings.cpp:2249 Client/core/CSettings.cpp:4066 +#: Client/core/CSettings.cpp:4098 Client/core/CSettings.cpp:4144 +#: Client/core/CSettings.cpp:5375 msgid "Off" msgstr "關閉" -#: Client/core/CSettings.cpp:815 Client/core/CSettings.cpp:1574 +#: Client/core/CSettings.cpp:1311 Client/core/CSettings.cpp:2251 msgid "1x" msgstr "1å€" -#: Client/core/CSettings.cpp:816 Client/core/CSettings.cpp:1576 +#: Client/core/CSettings.cpp:1312 Client/core/CSettings.cpp:2253 msgid "2x" msgstr "2å€" -#: Client/core/CSettings.cpp:817 Client/core/CSettings.cpp:1578 +#: Client/core/CSettings.cpp:1313 Client/core/CSettings.cpp:2255 msgid "3x" msgstr "3å€" -#: Client/core/CSettings.cpp:830 Client/core/CSettings.cpp:1054 -#: Client/core/CSettings.cpp:1584 Client/core/CSettings.cpp:3218 +#: Client/core/CSettings.cpp:1326 Client/core/CSettings.cpp:1688 +#: Client/core/CSettings.cpp:2261 Client/core/CSettings.cpp:4068 msgid "Auto" msgstr "自動" -#: Client/core/CSettings.cpp:831 Client/core/CSettings.cpp:1586 +#: Client/core/CSettings.cpp:1327 Client/core/CSettings.cpp:2263 msgid "4:3" msgstr "4:3" -#: Client/core/CSettings.cpp:832 Client/core/CSettings.cpp:1588 +#: Client/core/CSettings.cpp:1328 Client/core/CSettings.cpp:2265 msgid "16:10" msgstr "16:10" -#: Client/core/CSettings.cpp:833 Client/core/CSettings.cpp:1590 +#: Client/core/CSettings.cpp:1329 Client/core/CSettings.cpp:2267 msgid "16:9" msgstr "16:9" -#: Client/core/CSettings.cpp:836 +#: Client/core/CSettings.cpp:1332 msgid "HUD Match Aspect Ratio" msgstr "HUD的比例" -#: Client/core/CSettings.cpp:842 +#: Client/core/CSettings.cpp:1338 msgid "Volumetric Shadows" msgstr "é™°å½±å“質" -#: Client/core/CSettings.cpp:846 +#: Client/core/CSettings.cpp:1342 msgid "Grass effect" msgstr "é›œè‰æ•ˆæžœ" -#: Client/core/CSettings.cpp:850 +#: Client/core/CSettings.cpp:1346 msgid "Heat haze" msgstr "熱煙霧" -#: Client/core/CSettings.cpp:854 +#: Client/core/CSettings.cpp:1350 msgid "Tyre Smoke etc" msgstr "輪胎煙霧等" -#: Client/core/CSettings.cpp:858 +#: Client/core/CSettings.cpp:1354 msgid "Dynamic ped shadows" msgstr "人物動態陰影" -#: Client/core/CSettings.cpp:862 +#: Client/core/CSettings.cpp:1358 msgid "Motion blur" msgstr "動態模糊" -#: Client/core/CSettings.cpp:866 +#: Client/core/CSettings.cpp:1362 msgid "Corona rain reflections" msgstr "雨天燈光粒å­åå°„" -#: Client/core/CSettings.cpp:871 +#: Client/core/CSettings.cpp:1367 msgid "Full Screen Minimize" msgstr "全螢幕最å°åŒ–" -#: Client/core/CSettings.cpp:883 +#: Client/core/CSettings.cpp:1379 msgid "Enable Device Selection Dialog" msgstr "啟用è£ç½®ä½¿ç”¨å°è©±æ¡†å¼é¸æ“‡" -#: Client/core/CSettings.cpp:895 +#: Client/core/CSettings.cpp:1391 msgid "Show unsafe resolutions" msgstr "展示ä¸å®‰å…¨çš„æ¨¡å¼" -#: Client/core/CSettings.cpp:907 +#: Client/core/CSettings.cpp:1403 msgid "Render vehicles always in high detail" msgstr "高解æžåº¦æ¸²æŸ“載具" -#: Client/core/CSettings.cpp:911 +#: Client/core/CSettings.cpp:1407 msgid "Render peds always in high detail" msgstr "高解æžåº¦æ¸²æŸ“人物" -#: Client/core/CSettings.cpp:940 +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1441 +msgid "Gamma:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1481 +msgid "Contrast:" +msgstr "" + +#: Client/core/CSettings.cpp:1431 Client/core/CSettings.cpp:1501 +msgid "Saturation:" +msgstr "" + +#: Client/core/CSettings.cpp:1517 +msgid "Apply adjustments in windowed mode" +msgstr "" + +#: Client/core/CSettings.cpp:1523 +msgid "Apply adjustments in fullscreen mode" +msgstr "" + +#: Client/core/CSettings.cpp:1554 msgid "Enable remote websites" msgstr "啟用外部網站" -#: Client/core/CSettings.cpp:945 +#: Client/core/CSettings.cpp:1559 msgid "Enable Javascript on remote websites" msgstr "在外部網站啟用Javascript" -#: Client/core/CSettings.cpp:950 +#: Client/core/CSettings.cpp:1564 msgid "Enable GPU rendering" msgstr "啟用 GPU 渲染" -#: Client/core/CSettings.cpp:954 +#: Client/core/CSettings.cpp:1568 msgid "Custom blacklist" msgstr "自訂å°éŽ–åå–®" -#: Client/core/CSettings.cpp:965 Client/core/CSettings.cpp:1000 +#: Client/core/CSettings.cpp:1579 Client/core/CSettings.cpp:1625 msgid "Enter a domain e.g. google.com" msgstr "請輸入一個網域 例如:google.com" -#: Client/core/CSettings.cpp:973 +#: Client/core/CSettings.cpp:1587 msgid "Block" msgstr "å°éŽ–" -#: Client/core/CSettings.cpp:981 Client/core/CSettings.cpp:1016 +#: Client/core/CSettings.cpp:1602 Client/core/CSettings.cpp:1646 msgid "Domain" msgstr "網域" -#: Client/core/CSettings.cpp:983 Client/core/CSettings.cpp:1018 +#: Client/core/CSettings.cpp:1604 Client/core/CSettings.cpp:1648 msgid "Remove domain" msgstr "刪除網域" +#: Client/core/CSettings.cpp:1608 Client/core/CSettings.cpp:1652 +msgid "Remove all" +msgstr "" + #. Reset vecTemp -#: Client/core/CSettings.cpp:989 +#: Client/core/CSettings.cpp:1614 msgid "Custom whitelist" msgstr "自訂許å¯åå–®" +#: Client/core/CSettings.cpp:1633 Client/cefweb/CWebsiteRequests.cpp:51 +msgid "Allow" +msgstr "å…許" + #. Misc section label -#: Client/core/CSettings.cpp:1031 +#: Client/core/CSettings.cpp:1665 msgid "Misc" msgstr "其它" #. Fast clothes loading -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1045 -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1679 +#: Client/core/CSettings.cpp:6021 msgid "Fast CJ clothes loading:" msgstr "快速載入CJæœè£:" #. Browser scan speed -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1059 -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1693 +#: Client/core/CSettings.cpp:6023 msgid "Browser speed:" msgstr "ç€è¦§å™¨é€Ÿåº¦:" #. Single download -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1073 -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1707 +#: Client/core/CSettings.cpp:6025 msgid "Single connection:" msgstr "單一連線:" #. Packet tag -#: Client/core/CSettings.cpp:1037 Client/core/CSettings.cpp:1086 -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:1671 Client/core/CSettings.cpp:1720 +#: Client/core/CSettings.cpp:6027 msgid "Packet tag:" msgstr "å°åŒ…標籤:" #. Progress animation -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1099 -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1733 +#: Client/core/CSettings.cpp:6029 msgid "Progress animation:" msgstr "進度動畫:" #. Process priority -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1112 -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1746 +#: Client/core/CSettings.cpp:6019 msgid "Process priority:" msgstr "å„ªå…ˆè™•ç†æ¬Š:" #. Debug setting -#: Client/core/CSettings.cpp:1038 Client/core/CSettings.cpp:1126 -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:1672 Client/core/CSettings.cpp:1760 +#: Client/core/CSettings.cpp:6031 msgid "Debug setting:" msgstr "除錯設定:" #. Streaming memory -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1149 -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1783 +#: Client/core/CSettings.cpp:6033 msgid "Streaming memory:" msgstr "串æµè¨˜æ†¶é«”:" #. Update build type -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1256 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1903 msgid "Update build type:" msgstr "更新組建類型:" #. UpdateAutoInstall -#: Client/core/CSettings.cpp:1039 Client/core/CSettings.cpp:1235 +#: Client/core/CSettings.cpp:1673 Client/core/CSettings.cpp:1882 msgid "Install important updates:" msgstr "安è£é‡è¦æ›´æ–°ï¼š" -#: Client/core/CSettings.cpp:1053 Client/core/CSettings.cpp:1081 -#: Client/core/CSettings.cpp:1094 Client/core/CSettings.cpp:3220 -#: Client/core/CSettings.cpp:3236 Client/core/CSettings.cpp:3243 +#: Client/core/CSettings.cpp:1687 Client/core/CSettings.cpp:1715 +#: Client/core/CSettings.cpp:1728 Client/core/CSettings.cpp:4070 +#: Client/core/CSettings.cpp:4086 Client/core/CSettings.cpp:4093 msgid "On" msgstr "開啟" -#: Client/core/CSettings.cpp:1066 Client/core/CSettings.cpp:3225 +#: Client/core/CSettings.cpp:1700 Client/core/CSettings.cpp:4075 msgid "Very slow" msgstr "éžå¸¸æ…¢" -#: Client/core/CSettings.cpp:1067 Client/core/CSettings.cpp:1080 -#: Client/core/CSettings.cpp:1093 Client/core/CSettings.cpp:1107 -#: Client/core/CSettings.cpp:1133 Client/core/CSettings.cpp:1145 -#: Client/core/CSettings.cpp:1243 Client/core/CSettings.cpp:1263 -#: Client/core/CSettings.cpp:3227 Client/core/CSettings.cpp:3234 -#: Client/core/CSettings.cpp:3241 Client/core/CSettings.cpp:3250 -#: Client/core/CSettings.cpp:3287 +#: Client/core/CSettings.cpp:1701 Client/core/CSettings.cpp:1714 +#: Client/core/CSettings.cpp:1727 Client/core/CSettings.cpp:1741 +#: Client/core/CSettings.cpp:1767 Client/core/CSettings.cpp:1779 +#: Client/core/CSettings.cpp:1890 Client/core/CSettings.cpp:1910 +#: Client/core/CSettings.cpp:4077 Client/core/CSettings.cpp:4084 +#: Client/core/CSettings.cpp:4091 Client/core/CSettings.cpp:4100 +#: Client/core/CSettings.cpp:4137 msgid "Default" msgstr "é è¨­" -#: Client/core/CSettings.cpp:1068 Client/core/CSettings.cpp:3229 +#: Client/core/CSettings.cpp:1702 Client/core/CSettings.cpp:4079 msgid "Fast" msgstr "å¿«" -#: Client/core/CSettings.cpp:1119 Client/core/CSettings.cpp:3205 +#: Client/core/CSettings.cpp:1753 Client/core/CSettings.cpp:4055 msgid "Normal" msgstr "一般" -#: Client/core/CSettings.cpp:1120 Client/core/CSettings.cpp:3207 +#: Client/core/CSettings.cpp:1754 Client/core/CSettings.cpp:4057 msgid "Above normal" msgstr "高於一般" -#: Client/core/CSettings.cpp:1156 +#: Client/core/CSettings.cpp:1790 msgid "Min" msgstr "最低" -#: Client/core/CSettings.cpp:1169 +#: Client/core/CSettings.cpp:1815 msgid "Max" msgstr "最大" #. Windows 8 compatibility -#: Client/core/CSettings.cpp:1176 +#: Client/core/CSettings.cpp:1823 msgid "Windows 8 compatibility:" msgstr "Windows 8 相容性:" -#: Client/core/CSettings.cpp:1180 +#: Client/core/CSettings.cpp:1827 msgid "16-bit color" msgstr "16ä½å…ƒé¡è‰²" -#: Client/core/CSettings.cpp:1185 +#: Client/core/CSettings.cpp:1832 msgid "Mouse fix" msgstr "修正滑鼠" #. Cache path info -#: Client/core/CSettings.cpp:1203 +#: Client/core/CSettings.cpp:1850 msgid "Client resource files:" msgstr "ç”¨æˆ¶ç«¯è³‡æºæª”案:" -#: Client/core/CSettings.cpp:1207 +#: Client/core/CSettings.cpp:1854 msgid "Show in Explorer" msgstr "在檔案總管中顯示" #. Process affinity -#: Client/core/CSettings.cpp:1222 +#: Client/core/CSettings.cpp:1869 msgid "Set CPU 0 affinity to improve game performance" msgstr "設定 CPU 0 親和性以æå‡éŠæˆ²æ•ˆèƒ½" #. Auto updater section label -#: Client/core/CSettings.cpp:1228 Client/core/CSettings.cpp:1231 +#: Client/core/CSettings.cpp:1875 Client/core/CSettings.cpp:1878 msgid "Auto updater" msgstr "自動更新" #. Check for updates -#: Client/core/CSettings.cpp:1269 +#: Client/core/CSettings.cpp:1916 msgid "Check for update now" msgstr "立刻檢查更新" -#: Client/core/CSettings.cpp:1427 +#: Client/core/CSettings.cpp:2102 msgid "Some settings will be changed when you next start MTA" msgstr "有些設定必須在你é‡å•ŸMTAä¹‹å¾Œæ‰æœƒç”Ÿæ•ˆ" -#: Client/core/CSettings.cpp:1428 +#: Client/core/CSettings.cpp:2103 msgid "\n\n" "Do you want to restart now?" msgstr "\n\n" "你想è¦é¦¬ä¸Šé‡å•Ÿå—Ž?" -#: Client/core/CSettings.cpp:1431 +#: Client/core/CSettings.cpp:2106 msgid "RESTART REQUIRED" msgstr "需è¦é‡æ–°å•Ÿå‹•" -#: Client/core/CSettings.cpp:1451 +#: Client/core/CSettings.cpp:2126 msgid "Some settings will be changed when you disconnect the current server" msgstr "退出當å‰çš„伺æœå™¨å¾Œå°‡æœƒè®Šæ›´æ‚¨çš„一些設定" -#: Client/core/CSettings.cpp:1452 +#: Client/core/CSettings.cpp:2127 msgid "\n\n" "Do you want to disconnect now?" msgstr "\n\n" "您想è¦é¦¬ä¸Šé›¢ç·šå—Žï¼Ÿ" -#: Client/core/CSettings.cpp:1455 +#: Client/core/CSettings.cpp:2130 msgid "DISCONNECT REQUIRED" msgstr "必須離開伺æœå™¨" #. Update the joystick name -#: Client/core/CSettings.cpp:1787 +#: Client/core/CSettings.cpp:2572 msgid "Joypad not detected - Check connections and restart game" msgstr "未檢測到手把 - 撿查手把與電腦的連接並é‡å•ŸéŠæˆ²" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Binding axis" msgstr "ç¶å®šä¸­çš„軸" -#: Client/core/CSettings.cpp:1984 +#: Client/core/CSettings.cpp:2828 msgid "Move an axis to bind, or escape to clear" msgstr "請移動一個軸以ç¶å®šï¼Œæˆ–按下ESCéµå–消" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Language:" msgstr "語言:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Skin:" msgstr "外觀:" -#: Client/core/CSettings.cpp:2061 +#: Client/core/CSettings.cpp:2907 msgid "Presets:" msgstr "é ç½®:" -#: Client/core/CSettings.cpp:2110 +#: Client/core/CSettings.cpp:2956 msgid "Chat" msgstr "èŠå¤©" -#: Client/core/CSettings.cpp:2127 +#: Client/core/CSettings.cpp:2973 msgid "Load" msgstr "讀å–" -#: Client/core/CSettings.cpp:2139 +#: Client/core/CSettings.cpp:2985 msgid "Colors" msgstr "é¡è‰²" -#: Client/core/CSettings.cpp:2140 +#: Client/core/CSettings.cpp:2986 msgid "Layout" msgstr "版é¢" -#: Client/core/CSettings.cpp:2141 Client/core/CSettings.cpp:2387 +#: Client/core/CSettings.cpp:2987 Client/core/CSettings.cpp:3233 msgid "Options" msgstr "é¸é …" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Background" msgstr "è¨Šæ¯æ¬„背景" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Chat Text" msgstr "èŠå¤©æ–‡å­—" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Background" msgstr "輸入框背景" -#: Client/core/CSettings.cpp:2147 +#: Client/core/CSettings.cpp:2993 msgid "Input Text" msgstr "輸入文字" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Lines:" msgstr "行數:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Scale:" msgstr "比例:" -#: Client/core/CSettings.cpp:2170 +#: Client/core/CSettings.cpp:3016 msgid "Width:" msgstr "寬度:" -#: Client/core/CSettings.cpp:2173 +#: Client/core/CSettings.cpp:3019 msgid "Size" msgstr "大å°" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "after" msgstr "之後" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "for" msgstr "為" -#: Client/core/CSettings.cpp:2222 +#: Client/core/CSettings.cpp:3068 msgid "sec" msgstr "ç§’" -#: Client/core/CSettings.cpp:2225 +#: Client/core/CSettings.cpp:3071 msgid "Fading" msgstr "淡變" -#: Client/core/CSettings.cpp:2231 +#: Client/core/CSettings.cpp:3077 msgid "Fade out old lines" msgstr "ç°è‰²åŒ–舊行數" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Horizontal:" msgstr "水平:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Vertical:" msgstr "垂直:" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "Text-Align:" msgstr "文字å°é½Šï¼š" -#: Client/core/CSettings.cpp:2271 +#: Client/core/CSettings.cpp:3117 msgid "X-Offset:" msgstr "X軸ä½ç§»" -#: Client/core/CSettings.cpp:2272 +#: Client/core/CSettings.cpp:3118 msgid "Y-Offset:" msgstr "Y軸ä½ç§»" -#: Client/core/CSettings.cpp:2278 +#: Client/core/CSettings.cpp:3124 msgid "Position" msgstr "ä½ç½®" -#: Client/core/CSettings.cpp:2292 Client/core/CSettings.cpp:2320 +#: Client/core/CSettings.cpp:3138 Client/core/CSettings.cpp:3166 #: Client/core/CKeyBinds.cpp:191 msgid "Left" msgstr "å‘å·¦" -#: Client/core/CSettings.cpp:2293 Client/core/CSettings.cpp:2307 +#: Client/core/CSettings.cpp:3139 Client/core/CSettings.cpp:3153 msgid "Center" msgstr "中間" -#: Client/core/CSettings.cpp:2294 Client/core/CSettings.cpp:2321 +#: Client/core/CSettings.cpp:3140 Client/core/CSettings.cpp:3167 #: Client/core/CKeyBinds.cpp:192 msgid "Right" msgstr "å‘å³" -#: Client/core/CSettings.cpp:2306 +#: Client/core/CSettings.cpp:3152 msgid "Top" msgstr "頂端" -#: Client/core/CSettings.cpp:2308 +#: Client/core/CSettings.cpp:3154 msgid "Bottom" msgstr "底部" -#: Client/core/CSettings.cpp:2356 +#: Client/core/CSettings.cpp:3202 msgid "Font" msgstr "å­—åž‹" -#: Client/core/CSettings.cpp:2393 +#: Client/core/CSettings.cpp:3239 msgid "Hide background when not typing" msgstr "ç•¶ä¸åœ¨è¼¸å…¥æ–‡å­—時隱è—背景" -#: Client/core/CSettings.cpp:2398 +#: Client/core/CSettings.cpp:3244 msgid "Nickname completion using the \"Tab\" key" msgstr "按下 \"Tabéµ\" ä¾†è‡ªå‹•å®Œæˆæš±ç¨±çš„輸入" -#: Client/core/CSettings.cpp:2403 +#: Client/core/CSettings.cpp:3249 msgid "Allow server to flash the window" msgstr "å…許伺æœå™¨é–ƒçˆè¦–窗" -#: Client/core/CSettings.cpp:2408 +#: Client/core/CSettings.cpp:3254 msgid "Allow tray balloon notifications" msgstr "å…許推é€é€šçŸ¥æœå‹™" -#: Client/core/CSettings.cpp:2413 +#: Client/core/CSettings.cpp:3259 msgid "Chat text black/white outline" msgstr "è¨Šæ¯æ–‡å­—黑白框線" @@ -1551,89 +1836,95 @@ msgstr "è¨Šæ¯æ–‡å­—黑白框線" #. SString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); #. Create a messagebox to notify the user #. sSString strText = SString::Printf ( "Press a key to bind to '%s'", pItemBind->GetText ().c_str () ); -#: Client/core/CSettings.cpp:2662 Client/core/CSettings.cpp:2669 +#: Client/core/CSettings.cpp:3508 Client/core/CSettings.cpp:3515 msgid "Press a key to bind, or escape to clear" msgstr "請按下一個按éµä»¥ç¶å®šï¼Œæˆ–按下ESCéµå–消" -#: Client/core/CSettings.cpp:2663 +#: Client/core/CSettings.cpp:3509 msgid "Binding a primary key" msgstr "ç¶å®šä¸€å€‹ä¸»æŒ‰éµ" -#: Client/core/CSettings.cpp:2670 +#: Client/core/CSettings.cpp:3516 msgid "Binding a secondary key" msgstr "ç¶å®šä¸€å€‹å‰¯æŒ‰éµ" -#: Client/core/CSettings.cpp:2746 +#: Client/core/CSettings.cpp:3592 msgid "GTA GAME CONTROLS" msgstr "GTAéŠæˆ²æŽ§åˆ¶" -#: Client/core/CSettings.cpp:2748 +#: Client/core/CSettings.cpp:3594 msgid "MULTIPLAYER CONTROLS" msgstr "å¤šäººéŠæˆ²æŽ§åˆ¶" -#: Client/core/CSettings.cpp:2993 Client/core/CSettings.cpp:4940 +#: Client/core/CSettings.cpp:3839 Client/core/CSettings.cpp:5982 msgid "Your nickname contains invalid characters!" msgstr "ä½ çš„æš±ç¨±ä¸­å«æœ‰ä¸æ­£ç•¶çš„å­—å…ƒ!" -#: Client/core/CSettings.cpp:3573 Client/core/CCore.cpp:674 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1097 -#: Client/mods/deathmatch/logic/CResource.cpp:372 +#: Client/core/CSettings.cpp:4441 Client/core/CCore.cpp:709 +#: Client/core/CMainMenu.cpp:303 +#: Client/mods/deathmatch/logic/CClientGame.cpp:552 +msgid "Main menu" +msgstr "主é¸å–®" + +#: Client/core/CSettings.cpp:4445 Client/core/CCore.cpp:709 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1115 +#: Client/mods/deathmatch/logic/CResource.cpp:384 msgid "In-game" msgstr "éŠæˆ²å…§" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Red:" msgstr "ç´…:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Green:" msgstr "ç¶ :" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Blue:" msgstr "è—色:" -#: Client/core/CSettings.cpp:3913 +#: Client/core/CSettings.cpp:4798 msgid "Transparency:" msgstr "逿˜Žåº¦:" -#: Client/core/CSettings.cpp:3916 +#: Client/core/CSettings.cpp:4801 msgid "Color" msgstr "é¡è‰²" -#: Client/core/CSettings.cpp:3993 +#: Client/core/CSettings.cpp:4907 msgid "Preview" msgstr "é è¦½" -#: Client/core/CSettings.cpp:4301 +#: Client/core/CSettings.cpp:5215 msgid "Please disconnect before changing language" msgstr "請先離線後å†è®Šæ›´èªžè¨€" -#: Client/core/CSettings.cpp:4329 +#: Client/core/CSettings.cpp:5243 msgid "Please disconnect before changing skin" msgstr "在更æ›çš®è†šå‰è«‹å…ˆæ–·ç·š" -#: Client/core/CSettings.cpp:4617 +#: Client/core/CSettings.cpp:5623 msgid "Volmetric shadows can cause some systems to slow down.\n\n" "Are you sure you want to enable them?" msgstr "陰影體ç©åŒ–有å¯èƒ½æœƒå°Žè‡´ç³»çµ±é€Ÿåº¦è®Šæ…¢\n\n" "你確定è¦å•Ÿç”¨é™°å½±é«”ç©åŒ–?" -#: Client/core/CSettings.cpp:4621 +#: Client/core/CSettings.cpp:5627 msgid "PERFORMANCE WARNING" msgstr "效能警告" -#: Client/core/CSettings.cpp:4641 +#: Client/core/CSettings.cpp:5647 msgid "Screen upload is required by some servers for anti-cheat purposes.\n\n" "(The chat box and GUI is excluded from the upload)\n" msgstr "為é”防止外掛發生目的,在æŸäº›ä¼ºæœå™¨ä¸­ä½ éœ€è¦ä¸Šå‚³èž¢å¹•截圖來證明。\n\n" "(å°è©±æ¡†åŠå…¶åœ–åƒå°‡ä¸æœƒé€£åŒèž¢å¹•截圖一併上傳)\n" -#: Client/core/CSettings.cpp:4643 +#: Client/core/CSettings.cpp:5649 msgid "SCREEN UPLOAD INFORMATION" msgstr "截圖上傳資訊" -#: Client/core/CSettings.cpp:4658 +#: Client/core/CSettings.cpp:5664 msgid "Some scripts may play sounds, such as radio, from the internet.\n\n" "Disabling this setting may decrease network\n" "bandwidth consumption.\n" @@ -1641,23 +1932,21 @@ msgstr "æœ‰äº›è…³æœ¬æœƒæ’­æ”¾éŸ³æ•ˆï¼Œåƒæ˜¯ç¶²è·¯ä¸Šçš„é›»å°éŸ³æ¨‚。\n\n" "關閉該設定\n" "會減少網路æµé‡çš„使用。\n" -#: Client/core/CSettings.cpp:4661 +#: Client/core/CSettings.cpp:5667 msgid "EXTERNAL SOUNDS" msgstr "外部音效" -#: Client/core/CSettings.cpp:4690 -msgid "It seems that you have the Rich Presence connection option enabled.\n" -"Do you want to allow servers to share their data?\n\n" -"This includes yours unique ID identifier." -msgstr "您似乎已啟用 Discord Rich Presence 連線é¸é …。\n" -"您是å¦è¦å…許伺æœå™¨åˆ†äº«å…¶è³‡æ–™ï¼Ÿ\n\n" -"é€™åŒ…å«æ‚¨çš„ID識別碼。" +#: Client/core/CSettings.cpp:5696 +msgid "Rich Presence is currently enabled.\n" +"Do you want to allow data sharing with servers you connect to?\n\n" +"This includes your Discord client ID, and game state info." +msgstr "" -#: Client/core/CSettings.cpp:4695 +#: Client/core/CSettings.cpp:5701 msgid "CONSENT TO ALLOW DATA SHARING" msgstr "åŒæ„資料分享é¸é …" -#: Client/core/CSettings.cpp:4719 +#: Client/core/CSettings.cpp:5725 msgid "Some files in your GTA:SA data directory are customized.\n" "MTA will only use these modified files if this check box is ticked.\n\n" "However, CUSTOMIZED GTA:SA FILES ARE BLOCKED BY MANY SERVERS\n\n" @@ -1667,11 +1956,7 @@ msgstr "在你的GTA:SA目錄有些æ±è¥¿æ˜¯æœ‰ç¶“éŽè‡ªè¡Œæ›´æ”¹çš„.\n" "然而,更改éŽçš„GTA SA將會備很多伺æœå™¨ç¦æ­¢\n\n" "你確定你è¦ä½¿ç”¨ä»–們嗎?" -#: Client/core/CSettings.cpp:4725 Client/core/CVersionUpdater.cpp:2081 -msgid "CUSTOMIZED GTA:SA FILES" -msgstr "已修改俠盜çµè»Šæ‰‹:è–安地列斯的文件檔" - -#: Client/core/CSettings.cpp:4768 +#: Client/core/CSettings.cpp:5774 msgid "Enabling DPI awareness is an experimental feature and\n" "we only recommend it when you play MTA:SA on a scaled monitor.\n" "You may experience graphical issues if you enable this option.\n\n" @@ -1681,552 +1966,253 @@ msgstr "啟用 DPI 感知是一項實驗性功能\n" "如果您啟用此é¸é …,å¯èƒ½æœƒå°Žè‡´ç•«é¢ç•°å¸¸ã€‚\n\n" "您確定è¦å•Ÿç”¨æ­¤é¸é …嗎?" -#: Client/core/CSettings.cpp:4774 Client/core/CSettings.cpp:4820 +#: Client/core/CSettings.cpp:5780 Client/core/CSettings.cpp:5835 msgid "EXPERIMENTAL FEATURE" msgstr "實驗性功能" -#: Client/core/CSettings.cpp:4822 +#: Client/core/CSettings.cpp:5837 msgid "Disabling this option is not recommended unless you are experiencing performance issues.\n\n" "Are you sure you want to disable it?" msgstr "é™¤éžæ‚¨é‡åˆ°æ•ˆèƒ½å•題,å¦å‰‡ä¸å»ºè­°åœç”¨æ­¤é¸é …。\n\n" "您確定è¦åœç”¨å—Žï¼Ÿ" -#: Client/core/CSettings.cpp:4958 +#: Client/core/CSettings.cpp:6000 msgid "Please enter a nickname" msgstr "請輸入一個暱稱" -#: Client/core/CSettings.cpp:4959 +#: Client/core/CSettings.cpp:6001 msgid "Please enter a nickname to be used ingame. \n" "This will be your name when you connect to and play in a server" msgstr "è«‹è¼¸å…¥æš±ç¨±ä»¥ç”¨æ–¼éŠæˆ²å…§ã€‚ \n" "當你進入伺æœå™¨å¾Œé€™å°‡æœƒæˆç‚ºä½ çš„å稱" -#: Client/core/CSettings.cpp:4977 +#: Client/core/CSettings.cpp:6019 msgid "Very experimental feature." msgstr "éžå¸¸å¯¦é©—性的功能。" -#: Client/core/CSettings.cpp:4979 +#: Client/core/CSettings.cpp:6021 msgid "Stops stalls with CJ variations (Uses 65MB more RAM)" msgstr "è«‹åœæ­¢ä½¿ç”¨CJ變數暫存檔(使用超éŽ65MB記憶體)" -#: Client/core/CSettings.cpp:4981 +#: Client/core/CSettings.cpp:6023 msgid "Older routers may require a slower scan speed." msgstr "較舊的路由器掃æé€Ÿåº¦å¯èƒ½è¼ƒæ…¢ã€‚" -#: Client/core/CSettings.cpp:4983 +#: Client/core/CSettings.cpp:6025 msgid "Switch on to use only one connection when downloading." msgstr "當下載時,開啟以åªä½¿ç”¨å–®ä¸€é€£ç·šã€‚" -#: Client/core/CSettings.cpp:4985 +#: Client/core/CSettings.cpp:6027 msgid "Tag network packets to help ISPs identify MTA traffic." msgstr "標記網路å°åŒ…來幫助網路供應商識別MTAçš„æµé‡ã€‚" -#: Client/core/CSettings.cpp:4987 +#: Client/core/CSettings.cpp:6029 msgid "Spinning circle animation at the bottom of the screen" msgstr "在畫é¢åº•部顯示轉圈動畫" -#: Client/core/CSettings.cpp:4989 +#: Client/core/CSettings.cpp:6031 msgid "Select default always. (This setting is not saved)" msgstr "ç¶“å¸¸é¸æ“‡é è¨­ã€‚(æ­¤é …è¨­å®šä¸¦ä¸æœƒå„²å­˜)" -#: Client/core/CSettings.cpp:4991 +#: Client/core/CSettings.cpp:6033 msgid "Maximum is usually best" msgstr "最大通常是最好" -#: Client/core/CSettings.cpp:4993 Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6035 Client/core/CSettings.cpp:6037 msgid "Auto updater:" msgstr "自動更新:" -#: Client/core/CSettings.cpp:4993 +#: Client/core/CSettings.cpp:6035 msgid "Select default unless you like filling out bug reports." msgstr "è«‹é¸æ“‡é è¨­ï¼Œæœ‰æ„願è¦å¡«å¯«æ¼æ´žå ±å‘Šã€‚" -#: Client/core/CSettings.cpp:4995 +#: Client/core/CSettings.cpp:6037 msgid "Select default to automatically install important updates." msgstr "鏿“‡é è¨­æœƒè‡ªå‹•安è£é‡è¦æ›´æ–°ã€‚" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "16-bit color:" msgstr "16ä½å…ƒçš„é¡è‰²:" -#: Client/core/CSettings.cpp:4997 +#: Client/core/CSettings.cpp:6039 msgid "Enable 16 bit color modes - Requires MTA restart" msgstr "啟動 16ä½å…ƒé¡è‰² 並將MTAé‡å•Ÿ" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse fix:" msgstr "修正滑鼠" -#: Client/core/CSettings.cpp:4999 +#: Client/core/CSettings.cpp:6041 msgid "Mouse movement fix - May need PC restart" msgstr "滑鼠移動修正 - å¯èƒ½éœ€è¦é‡å•Ÿé›»è…¦" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "CPU affinity:" msgstr "CPU 親和性:" -#: Client/core/CSettings.cpp:5001 +#: Client/core/CSettings.cpp:6043 msgid "Only change if you're having stability issues." msgstr "僅在é‡åˆ°ç©©å®šæ€§å•é¡Œæ™‚æ‰æ›´æ”¹ã€‚" -#. Unknown command -#: Client/core/CCommands.cpp:223 -msgid "Unknown command or cvar: " -msgstr "䏿˜Žçš„命令或指令:" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Busy" -msgstr "忙碌" - -#: Client/core/CVersionUpdater.cpp:626 -msgid "Can't check for updates right now" -msgstr "ç›®å‰ç„¡æ³•檢查更新" - -#: Client/core/CVersionUpdater.cpp:1567 Client/core/CVersionUpdater.cpp:1587 -#: Client/core/CVersionUpdater.cpp:1605 -#, c-format -msgid "MTA:SA %s required" -msgstr "éœ€è¦ MTA:SA %s" - -#: Client/core/CVersionUpdater.cpp:1568 -#, c-format -msgid "An updated version of MTA:SA %s is required to join the selected server.\n\n" -"Do you want to download and install MTA:SA %s ?" -msgstr "若想加入目å‰çš„伺æœå™¨ï¼Œéœ€è¦å®‰è£æ›´æ–°ç‰ˆæœ¬çš„MTA:SA %s。\n\n" -"你想è¦ç¾åœ¨ä¸‹è¼‰åŠå®‰è£ MTA:SA %s å—Ž?" - -#: Client/core/CVersionUpdater.cpp:1588 -#, c-format -msgid "Do you want to launch MTA:SA %s and connect to this server ?" -msgstr "你想è¦å•Ÿå‹• MTA:SA %s 並連線到該伺æœå™¨å—Ž?" - -#: Client/core/CVersionUpdater.cpp:1606 -msgid "It is not possible to connect at this time.\n\n" -"Please try later." -msgstr "ç¾åœ¨ä¸å¯èƒ½é€£ç·šã€‚\n\n" -"è«‹ç¨å¾Œå†è©¦ã€‚" - -#: Client/core/CVersionUpdater.cpp:1788 -msgid "Connecting" -msgstr "連線中" - -#: Client/core/CVersionUpdater.cpp:1789 Client/core/CVersionUpdater.cpp:1805 -msgid "Please wait..." -msgstr "è«‹ç¨ç­‰..." - -#: Client/core/CVersionUpdater.cpp:1804 -msgid "CHECKING" -msgstr "檢查中" - -#: Client/core/CVersionUpdater.cpp:1821 Client/core/CVersionUpdater.cpp:1914 -msgid "UPDATE CHECK" -msgstr "更新檢查" - -#: Client/core/CVersionUpdater.cpp:1822 -msgid "No update needed" -msgstr "ä¸éœ€è¦æ›´æ–°" - -#: Client/core/CVersionUpdater.cpp:1839 -msgid "DOWNLOADING" -msgstr "下載中" - -#: Client/core/CVersionUpdater.cpp:1840 -msgid "waiting..." -msgstr "等待..." - -#: Client/core/CVersionUpdater.cpp:1856 -msgid "MANDATORY UPDATE" -msgstr "強制性更新" - -#: Client/core/CVersionUpdater.cpp:1857 -msgid "To join this server, you must update MTA.\n\n" -" Do you want to update now ?" -msgstr "è¦åŠ å…¥é€™ä¼ºæœå™¨ï¼Œä½ å¿…須更新 MTA。\n\n" -"你希望ç¾åœ¨æ›´æ–°å—Ž?" - -#: Client/core/CVersionUpdater.cpp:1875 -msgid "OPTIONAL UPDATE" -msgstr "å¯é¸æ“‡æ€§æ›´æ–°" - -#: Client/core/CVersionUpdater.cpp:1876 -msgid "Server says an update is recommended, but not essential.\n\n" -" Do you want to update now ?" -msgstr "伺æœå™¨è¡¨ç¤ºå»ºè­°ä½ é€²è¡Œæ›´æ–°ï¼Œä½†ä¸¦éžä¸€å®šè¦ã€‚\n\n" -"你想è¦ç¾åœ¨æ›´æ–°å—Ž?" - -#: Client/core/CVersionUpdater.cpp:1915 -msgid "An update is currently not available.\n\n" -"Please check www.multitheftauto.com" -msgstr "ç›®å‰æ²’有å¯ç”¨çš„æ›´æ–°ã€‚\n\n" -"請至 www.multitheftauto.com 確èª" - -#: Client/core/CVersionUpdater.cpp:1936 Client/core/CVersionUpdater.cpp:2118 -msgid "ERROR SAVING" -msgstr "錯誤ä¿å­˜" - -#: Client/core/CVersionUpdater.cpp:1937 Client/core/CVersionUpdater.cpp:2119 -msgid "Unable to create the file." -msgstr "無法建立檔案" - -#: Client/core/CVersionUpdater.cpp:1945 Client/core/CVersionUpdater.cpp:1954 -#: Client/core/CVersionUpdater.cpp:2127 Client/core/CVersionUpdater.cpp:2136 -msgid "ERROR DOWNLOADING" -msgstr "下載錯誤" - -#: Client/core/CVersionUpdater.cpp:1946 Client/core/CVersionUpdater.cpp:2128 -msgid "The downloaded file appears to be incorrect." -msgstr "ä¸‹è¼‰çš„æ–‡ä»¶ä¸æ­£ç¢º" - -#: Client/core/CVersionUpdater.cpp:1955 Client/core/CVersionUpdater.cpp:2137 -msgid "For some reason." -msgstr "因為æŸäº›åŽŸå› ã€‚" - -#: Client/core/CVersionUpdater.cpp:1966 Client/core/CVersionUpdater.cpp:2150 -msgid "DOWNLOAD COMPLETE" -msgstr "下載完æˆ" - -#: Client/core/CVersionUpdater.cpp:1990 -msgid " - Unknown problem in _DialogUpdateResult" -msgstr "- 未知的å•題發生在 _DialogUpdateResult" - -#: Client/core/CVersionUpdater.cpp:2088 Client/core/CVersionUpdater.cpp:2098 -msgid "Ok" -msgstr "確定" - -#: Client/core/CVersionUpdater.cpp:2096 -msgid "ERROR" -msgstr "錯誤" - -#: Client/core/CVersionUpdater.cpp:2097 -msgid "Some MTA:SA data files are missing.\n\n\n" -"Please reinstall MTA:SA" -msgstr "æŸäº› MTA:SA資料éºå¤±\n\n\n" -"è«‹é‡æ–°å®‰è£ MTA:SA" - -#: Client/core/CVersionUpdater.cpp:2774 -#, c-format -msgid "%3d %% completed" -msgstr "%3d %% 已完æˆ" - -#: Client/core/CVersionUpdater.cpp:2777 -#, c-format -msgid "\n\n" -"Waiting for response - %-3d" -msgstr "\n\n" -"等待回應中 - %-3d" - -#: Client/core/CConnectManager.cpp:85 -msgid "Connecting failed. Invalid nick provided!" -msgstr "連線失敗。無效的匿åID!" - -#: Client/core/CConnectManager.cpp:116 -msgid "Connecting failed. Invalid host provided!" -msgstr "連線失敗。æä¾›ç„¡æ•ˆçš„主機" - -#: Client/core/CConnectManager.cpp:132 -#, c-format -msgid "Connecting to %s at port %u failed!" -msgstr "連接到 %s æ–¼åŸ å£ %u 失敗" - -#. Display the status box -#: Client/core/CConnectManager.cpp:153 -#, c-format -msgid "Connecting to %s:%u ..." -msgstr "正在連線至 %s:%u ..." - -#: Client/core/CConnectManager.cpp:155 -#, c-format -msgid "Reconnecting to %s:%u ..." -msgstr "æ­£åœ¨é‡æ–°é€£ç·šè‡³ %s:%u ..." - -#. Display the status box -#: Client/core/CConnectManager.cpp:156 -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 -msgid "CONNECTING" -msgstr "連接中" - -#: Client/core/CConnectManager.cpp:271 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1341 -msgid "Connection timed out" -msgstr "連線已逾時" - -#: Client/core/CConnectManager.cpp:285 Client/core/CConnectManager.cpp:289 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 -msgid "Disconnected: unknown protocol error" -msgstr "連線中斷: 未知的å”定錯誤" - -#: Client/core/CConnectManager.cpp:293 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 -msgid "Disconnected: disconnected remotely" -msgstr "連線中斷: é ç¨‹é€£ç·šä¸­æ–·" - -#: Client/core/CConnectManager.cpp:297 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 -msgid "Disconnected: connection lost remotely" -msgstr "連線中斷: 伺æœå™¨é€£ç·šä¸­æ–·" - -#: Client/core/CConnectManager.cpp:301 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 -msgid "Disconnected: you are banned from this server" -msgstr "連線中斷: 你已經被å°éŽ–ç¦æ­¢é€²å…¥è©²ä¼ºæœå™¨" - -#: Client/core/CConnectManager.cpp:308 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 -msgid "Disconnected: disconnected from the server" -msgstr "連線中斷: 伺æœå™¨é€£ç·šä¸­æ–·" - -#: Client/core/CConnectManager.cpp:312 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 -msgid "Disconnected: connection to the server was lost" -msgstr "連線中斷: 與伺æœå™¨çš„連線已éºå¤±" - -#: Client/core/CConnectManager.cpp:319 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1421 -msgid "Disconnected: connection was refused" -msgstr "連線中斷: 連線已被拒絕" - -#. Failed loading the mod -#: Client/core/CConnectManager.cpp:414 -#, c-format -msgid "No such mod installed (%s)" -msgstr "æœªç™¼ç¾æŒ‡å®šçš„ Mod (%s)" - -#: Client/core/CConnectManager.cpp:422 -msgid "Bad server response (2)" -msgstr "ä¸ç•¶çš„伺æœå™¨å›žæ‡‰ (2)" - -#: Client/core/CConnectManager.cpp:432 -msgid "Bad server response (1)" -msgstr "ä¸ç•¶çš„伺æœå™¨å›žæ‡‰ (1)" - -#. Create the window -#: Client/core/CNewsBrowser.cpp:153 -msgid "NEWS" -msgstr "最新訊æ¯" - -#. News link -#: Client/core/CNewsBrowser.cpp:171 Client/core/CNewsBrowser.cpp:172 -msgid "Visit latest news article" -msgstr "閱讀最新消æ¯" - -#. Create window -#: Client/core/CConsole.cpp:417 -msgid "CONSOLE" -msgstr "控制臺" - -#: Client/core/CCore.cpp:813 Shared/mods/deathmatch/logic/Utils.cpp:129 +#: Client/core/CCore.cpp:848 Shared/mods/deathmatch/logic/Utils.cpp:129 msgid "Fatal error" msgstr "åš´é‡çš„錯誤" -#: Client/core/CCore.cpp:934 +#: Client/core/CCore.cpp:969 msgid "TO FIX, REMOVE THIS FILE:" msgstr "為了修復å•題,請移除該檔案:" -#: Client/core/CCore.cpp:966 +#: Client/core/CCore.cpp:1001 #, c-format msgid "%s module is incorrect!" msgstr "%s æ¨¡çµ„ä¸æ­£ç¢ºï¼" -#: Client/core/CCore.cpp:1272 +#: Client/core/CCore.cpp:1375 msgid "Error executing URL" msgstr "åŸ·è¡Œç¶²å€æ™‚發生錯誤" #. m_pCommands->Add ( "e", CCommandFuncs::Editor ); #. m_pCommands->Add ( "clear", CCommandFuncs::Clear ); -#: Client/core/CCore.cpp:1367 +#: Client/core/CCore.cpp:1470 msgid "this help screen" msgstr "這個說明畫é¢" -#: Client/core/CCore.cpp:1368 Client/core/CCore.cpp:1369 +#: Client/core/CCore.cpp:1471 Client/core/CCore.cpp:1472 msgid "exits the application" msgstr "退出應用程å¼" -#: Client/core/CCore.cpp:1370 +#: Client/core/CCore.cpp:1473 msgid "shows the version" msgstr "顯示版本" -#: Client/core/CCore.cpp:1371 +#: Client/core/CCore.cpp:1474 msgid "shows the time" msgstr "顯示時間" -#: Client/core/CCore.cpp:1372 +#: Client/core/CCore.cpp:1475 msgid "shows the hud" msgstr "顯示 Hud" -#: Client/core/CCore.cpp:1373 +#: Client/core/CCore.cpp:1476 msgid "shows all the binds" msgstr "顯示所有ç¶å®šè¨­ç½®" -#: Client/core/CCore.cpp:1374 +#: Client/core/CCore.cpp:1477 msgid "shows your serial" msgstr "顯示你的åºåˆ—" -#: Client/core/CCore.cpp:1383 +#: Client/core/CCore.cpp:1486 msgid "connects to a server (host port nick pass)" msgstr "連線到一個伺æœå™¨ (伺æœå™¨ åŸ å£ æš±ç¨± 密碼)" -#: Client/core/CCore.cpp:1384 +#: Client/core/CCore.cpp:1487 msgid "connects to a previous server" msgstr "連線到å‰ä¸€æ¬¡ç™»å…¥éŽçš„伺æœå™¨" -#: Client/core/CCore.cpp:1385 +#: Client/core/CCore.cpp:1488 msgid "binds a key (key control)" msgstr "ç¶å®šä¸€å€‹æŒ‰éµ (控制éµ)" -#: Client/core/CCore.cpp:1386 +#: Client/core/CCore.cpp:1489 msgid "unbinds a key (key)" msgstr "解除ç¶å®šæŒ‰éµ (按éµ)" -#: Client/core/CCore.cpp:1387 +#: Client/core/CCore.cpp:1490 msgid "copies the default gta controls" -msgstr "複製é è¨­çš„GTA控制" - -#: Client/core/CCore.cpp:1388 -msgid "outputs a screenshot" -msgstr "輸出截圖" - -#: Client/core/CCore.cpp:1389 -msgid "immediately saves the config" -msgstr "立刻地儲存é…ç½®" - -#: Client/core/CCore.cpp:1391 -msgid "clears the debug view" -msgstr "清除除錯視圖" - -#: Client/core/CCore.cpp:1392 -msgid "scrolls the chatbox upwards" -msgstr "把å°è©±æ¡†å‘上移" - -#: Client/core/CCore.cpp:1393 -msgid "scrolls the chatbox downwards" -msgstr "把å°è©±æ¡†å‘下移" - -#: Client/core/CCore.cpp:1394 -msgid "scrolls the debug view upwards" -msgstr "把除錯視圖å‘上移" - -#: Client/core/CCore.cpp:1395 -msgid "scrolls the debug view downwards" -msgstr "把除錯視圖å‘下移" - -#: Client/core/CCore.cpp:1398 -msgid "shows the memory statistics" -msgstr "顯示記憶體狀態" - -#: Client/core/CCore.cpp:1399 -msgid "shows the frame timing graph" -msgstr "顯示æ¯ç§’幀數時間圖" - -#: Client/core/CCore.cpp:1403 -msgid "for developers: reload news" -msgstr "開發者專用功能: 釿–°è®€å–最新消æ¯" - -#: Client/core/CCommandFuncs.cpp:24 -msgid "***[ COMMAND HELP ]***\n" -msgstr "***[ 指令幫助 ]***\n" - -#: Client/core/CCommandFuncs.cpp:158 -#, c-format -msgid "* The time is %d:%02d:%02d" -msgstr "* ç¾åœ¨æ™‚間是 %d:%02d:%02d" - -#: Client/core/CCommandFuncs.cpp:191 -msgid "connect: Network is not ready, please wait a moment" -msgstr "連線:網路未就緒,請ç¨å€™" - -#: Client/core/CCommandFuncs.cpp:225 -msgid "connect: Syntax is 'connect [ ]'" -msgstr "連線: 指令為 'connect <伺æœå™¨> [<連接埠> <暱稱> <密碼>]'" +msgstr "複製é è¨­çš„GTA控制" -#: Client/core/CCommandFuncs.cpp:233 -msgid "connect: Bad port number" -msgstr "連線: 無效的連接埠號碼" +#: Client/core/CCore.cpp:1491 +msgid "outputs a screenshot" +msgstr "輸出截圖" -#: Client/core/CCommandFuncs.cpp:255 -#, c-format -msgid "connect: Connecting to %s:%u..." -msgstr "連線: 正在連線到 %s:%u..." +#: Client/core/CCore.cpp:1492 +msgid "immediately saves the config" +msgstr "立刻地儲存é…ç½®" -#: Client/core/CCommandFuncs.cpp:259 -#, c-format -msgid "connect: could not connect to %s:%u!" -msgstr "連線: 無法連線到 %s:%u!" +#: Client/core/CCore.cpp:1494 +msgid "clears the debug view" +msgstr "清除除錯視圖" -#: Client/core/CCommandFuncs.cpp:264 -msgid "connect: Failed to unload current mod" -msgstr "連線: 移除指定 mod 失敗" +#: Client/core/CCore.cpp:1495 +msgid "scrolls the chatbox upwards" +msgstr "把å°è©±æ¡†å‘上移" -#: Client/core/CCommandFuncs.cpp:284 -msgid "reconnect: Network is not ready, please wait a moment" -msgstr "釿–°é€£ç·šï¼šç¶²è·¯æœªå°±ç·’,請ç¨å€™" +#: Client/core/CCore.cpp:1496 +msgid "scrolls the chatbox downwards" +msgstr "把å°è©±æ¡†å‘下移" -#: Client/core/CCommandFuncs.cpp:306 -msgid "reconnect: Bad port number" -msgstr "釿–°é€£ç·šï¼šéŒ¯èª¤çš„連接埠號碼" +#: Client/core/CCore.cpp:1497 +msgid "scrolls the debug view upwards" +msgstr "把除錯視圖å‘上移" -#: Client/core/CCommandFuncs.cpp:321 -#, c-format -msgid "reconnect: Reconnecting to %s:%u..." -msgstr "釿–°é€£ç·šï¼šæ­£åœ¨é‡æ–°é€£ç·šåˆ° %s:%u..." +#: Client/core/CCore.cpp:1498 +msgid "scrolls the debug view downwards" +msgstr "把除錯視圖å‘下移" -#: Client/core/CCommandFuncs.cpp:325 -#, c-format -msgid "reconnect: could not connect to %s:%u!" -msgstr "釿–°é€£ç·šï¼šç„¡æ³•連線到 %s:%uï¼" +#: Client/core/CCore.cpp:1501 +msgid "shows the memory statistics" +msgstr "顯示記憶體狀態" -#: Client/core/CCommandFuncs.cpp:359 -msgid "Bound all controls from GTA" -msgstr "ç¶å®šGTA 所有的控制設定" +#: Client/core/CCore.cpp:1502 +msgid "shows the frame timing graph" +msgstr "顯示æ¯ç§’幀數時間圖" -#: Client/core/CCommandFuncs.cpp:373 -msgid "Saved configuration file" -msgstr "設定已經ä¿å­˜" +#: Client/core/CCore.cpp:1506 +msgid "for developers: reload news" +msgstr "開發者專用功能: 釿–°è®€å–最新消æ¯" -#. Print it -#: Client/core/CCommandFuncs.cpp:439 -#, c-format -msgid "* Your serial is: %s" -msgstr "* 您的åºåˆ—號為: %s" +#: Client/core/CMainMenu.cpp:332 +msgid "You are using a feature-branch build! This is a test build only which cannot be used to connect to public servers!" +msgstr "æ‚¨æ­£åœ¨ä½¿ç”¨åˆ†æ”¯æ§‹å»ºçš„ç‰ˆæœ¬ï¼æ§‹å»ºç‰ˆæœ¬ä¸¦ç„¡æ³•用來連接公開伺æœå™¨ï¼" -#: Client/core/CJoystickManager.cpp:1578 -msgid "Accelerate Axis" -msgstr "加速軸" +#: Client/core/CMainMenu.cpp:351 +msgid "MTA will not receive updates on XP/Vista after July 2019.\n\n" +"Upgrade Windows to play on the latest servers." +msgstr "MTA自2019å¹´7月以後將ä¸å†æ›´æ–°XP/Vista的版本。\n\n" +"è«‹å‡ç´šæ‚¨çš„Windows以便在最新版本的伺æœå™¨æš¢éŠã€‚" -#: Client/core/CJoystickManager.cpp:1580 -msgid "Brake Axis" -msgstr "制動軸" +#: Client/core/CMainMenu.cpp:1231 +msgid "This will disconnect you from the current server.\n\n" +"Are you sure you want to disconnect?" +msgstr "這將會使你從目å‰ä¼ºæœå™¨çµæŸé€£ç·šã€‚\n\n" +"你確定è¦çµæŸé€£ç·šå—Ž?" -#: Client/core/CCredits.cpp:34 -msgid "Programming" -msgstr "程å¼é–‹ç™¼" +#: Client/core/CMainMenu.cpp:1235 +msgid "DISCONNECT WARNING" +msgstr "斷線警告" -#: Client/core/CCredits.cpp:63 -msgid "Contributors" -msgstr "å”助開發者:" +#: Client/core/CMainMenu.cpp:1256 +msgid "INFORMATION" +msgstr "資訊" -#: Client/core/CCredits.cpp:84 -msgid "Game Design / Scripting" -msgstr "éŠæˆ²è¨­è¨ˆ/腳本師" +#. Create the window +#: Client/core/CNewsBrowser.cpp:154 +msgid "NEWS" +msgstr "最新訊æ¯" -#: Client/core/CCredits.cpp:104 -msgid "Language Localization" -msgstr "本土語言翻譯" +#. News link +#: Client/core/CNewsBrowser.cpp:172 Client/core/CNewsBrowser.cpp:173 +msgid "Visit latest news article" +msgstr "閱讀最新消æ¯" -#: Client/core/CCredits.cpp:110 -msgid "Patch contributors" -msgstr "補ä¸å”助開發員" +#: Client/core/CScreenShot.cpp:200 +#, c-format +msgid "Screenshot got %d bytes, but expected %d" +msgstr "截圖包å«%d å€‹å­—ç¯€ï¼Œä½†é æœŸç‚º %d 字節" -#: Client/core/CCredits.cpp:234 -msgid "Special Thanks" -msgstr "特別感è¬" +#: Client/core/CScreenShot.cpp:206 +msgid "Screenshot failed" +msgstr "截圖失敗" -#: Client/core/CCredits.cpp:265 -msgid "This software and project makes use of the following libraries and software:" -msgstr "這個軟體和專案使用了以下的庫和軟體:" +#: Client/core/CScreenShot.cpp:256 +#, c-format +msgid "Screenshot taken: '%s'" +msgstr "èž¢å¹•æˆªåœ–å·²æ‹æ”: '%s'" -#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:688 -msgid "Do you want to see some on-line help about this problem ?" -msgstr "你希望在線上看看關於此å•題的幫助嗎?" +#. Unknown command +#: Client/core/CCommands.cpp:233 +msgid "Unknown command or cvar: " +msgstr "䏿˜Žçš„命令或指令:" #: Client/core/CKeyBinds.cpp:186 msgid "Fire" @@ -2401,25 +2387,56 @@ msgid "Group control backwards" msgstr "團體控制往後" #. Even the default skin doesn't work, so give up -#: Client/core/CGUI.cpp:92 +#: Client/core/CGUI.cpp:93 msgid "The skin you selected could not be loaded, and the default skin also could not be loaded, please reinstall MTA." msgstr "你鏿“‡çš„皮膚無法被讀å–,默èªçš„皮膚也無法被讀å–ï¼Œè«‹é‡æ–°å®‰è£MTA。" -#: Client/core/CScreenShot.cpp:117 -#, c-format -msgid "Screenshot got %d bytes, but expected %d" -msgstr "截圖包å«%d å€‹å­—ç¯€ï¼Œä½†é æœŸç‚º %d 字節" +#: Client/core/CQuestionBox.cpp:192 Shared/sdk/SharedUtil.Misc.hpp:1462 +msgid "Do you want to see some on-line help about this problem ?" +msgstr "你希望在線上看看關於此å•題的幫助嗎?" -#: Client/core/CScreenShot.cpp:123 -msgid "Screenshot failed" -msgstr "截圖失敗" +#. Create window +#: Client/core/CConsole.cpp:417 +msgid "CONSOLE" +msgstr "控制臺" -#: Client/core/CScreenShot.cpp:173 -#, c-format -msgid "Screenshot taken: '%s'" -msgstr "èž¢å¹•æˆªåœ–å·²æ‹æ”: '%s'" +#: Client/core/CCredits.cpp:34 +msgid "Programming" +msgstr "程å¼é–‹ç™¼" + +#: Client/core/CCredits.cpp:65 +msgid "Contributors" +msgstr "å”助開發者:" + +#: Client/core/CCredits.cpp:85 +msgid "Game Design / Scripting" +msgstr "éŠæˆ²è¨­è¨ˆ/腳本師" + +#: Client/core/CCredits.cpp:105 +msgid "Language Localization" +msgstr "本土語言翻譯" + +#: Client/core/CCredits.cpp:111 +msgid "Patch contributors" +msgstr "補ä¸å”助開發員" + +#: Client/core/CCredits.cpp:234 +msgid "Special Thanks" +msgstr "特別感è¬" + +#: Client/core/CCredits.cpp:265 +msgid "This software and project makes use of the following libraries and software:" +msgstr "這個軟體和專案使用了以下的庫和軟體:" + +#: Client/core/CJoystickManager.cpp:1578 +msgid "Accelerate Axis" +msgstr "加速軸" + +#: Client/core/CJoystickManager.cpp:1580 +msgid "Brake Axis" +msgstr "制動軸" -#: Client/core/DXHook/CDirect3DHook9.cpp:124 +#: Client/core/DXHook/CDirect3DHook9.cpp:125 msgid "Could not initialize Direct3D9.\n\n" "Please ensure the DirectX End-User Runtime and\n" "latest Windows Service Packs are installed correctly." @@ -2427,6 +2444,59 @@ msgstr "無法åˆå§‹åŒ– Direct3D9。\n\n" "請確ä¿DirectX End-User Runtime åŠ\n" "最新的Windows 安全性更新是å¦å·²æ­£ç¢ºå®‰è£ã€‚" +#: Client/core/ServerBrowser/CServerList.cpp:25 +#: Client/core/ServerBrowser/CServerList.cpp:63 +msgid "Idle" +msgstr "é–’ç½®" + +#: Client/core/ServerBrowser/CServerList.cpp:168 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3158 +msgid "player" +msgid_plural "players" +msgstr[0] "玩家玩家數" + +#: Client/core/ServerBrowser/CServerList.cpp:169 +msgid "on" +msgstr "æ–¼" + +#: Client/core/ServerBrowser/CServerList.cpp:172 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3164 +msgid "server" +msgid_plural "servers" +msgstr[0] "伺æœå™¨ä¼ºæœå™¨æ•¸" + +#. We are polling for the master server list (first pass) +#: Client/core/ServerBrowser/CServerList.cpp:306 +#, c-format +msgid "Requesting master server list (%lu ms elapsed)" +msgstr "請求主伺æœå™¨åˆ—è¡¨ï¼ˆå·²éŽ %lu 毫秒)" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:324 +msgid "Master server list could not be parsed." +msgstr "主伺æœå™¨åˆ—表無法解æžã€‚" + +#. Abort +#: Client/core/ServerBrowser/CServerList.cpp:334 +msgid "Master server list could not be retrieved." +msgstr "主伺æœå™¨åˆ—表無法檢索。" + +#: Client/core/ServerBrowser/CServerList.cpp:349 +msgid "(Backup server list)" +msgstr "(備分伺æœå™¨åˆ—表)" + +#: Client/core/ServerBrowser/CServerList.cpp:419 +msgid "Cannot create LAN-broadcast socket" +msgstr "" + +#: Client/core/ServerBrowser/CServerList.cpp:429 +msgid "Cannot bind LAN-broadcast socket" +msgstr "ä¸èƒ½ç¶å®šå±€åŸŸç¶²å»£æ’­æ’座" + +#: Client/core/ServerBrowser/CServerList.cpp:472 +msgid "Attempting to discover LAN servers" +msgstr "正在嘗試尋找å€åŸŸç¶²è·¯ä¸­çš„伺æœå™¨" + #. Create queue window #: Client/core/ServerBrowser/CServerInfo.cpp:32 #: Client/core/ServerBrowser/CServerInfo.cpp:302 @@ -2480,7 +2550,7 @@ msgstr "å»¶é²:" #. Column for player names #. Player List Columns #: Client/core/ServerBrowser/CServerInfo.cpp:138 -#: Client/core/ServerBrowser/CServerBrowser.cpp:478 +#: Client/core/ServerBrowser/CServerBrowser.cpp:635 msgid "Player list" msgstr "玩家清單" @@ -2507,40 +2577,39 @@ msgstr "伺æœå™¨äººæ•¸æœ‰ç©ºç¼ºæ™‚會自動進入" msgid "PLEASE ENTER SERVER PASSWORD" msgstr "請輸入伺æœå™¨å¯†ç¢¼" -#. The server has timed out -#: Client/core/ServerBrowser/CServerInfo.cpp:402 +#: Client/core/ServerBrowser/CServerInfo.cpp:479 msgid "Timed Out" msgstr "已逾時" #. Set every GUI elements text to blank -#: Client/core/ServerBrowser/CServerInfo.cpp:431 +#: Client/core/ServerBrowser/CServerInfo.cpp:515 msgid "Querying..." msgstr "正在查詢..." #. Create the window -#: Client/core/ServerBrowser/CServerBrowser.cpp:85 +#: Client/core/ServerBrowser/CServerBrowser.cpp:189 msgid "SERVER BROWSER" msgstr "伺æœå™¨ç€è¦½å™¨" #. Create the tabs -#: Client/core/ServerBrowser/CServerBrowser.cpp:133 +#: Client/core/ServerBrowser/CServerBrowser.cpp:237 #: Client/mods/deathmatch/logic/CLocalServer.cpp:90 msgid "Internet" msgstr "網際網路" -#: Client/core/ServerBrowser/CServerBrowser.cpp:134 +#: Client/core/ServerBrowser/CServerBrowser.cpp:238 msgid "Local" msgstr "å€åŸŸ" -#: Client/core/ServerBrowser/CServerBrowser.cpp:135 +#: Client/core/ServerBrowser/CServerBrowser.cpp:239 msgid "Favourites" msgstr "我的最愛" -#: Client/core/ServerBrowser/CServerBrowser.cpp:136 +#: Client/core/ServerBrowser/CServerBrowser.cpp:240 msgid "Recent" msgstr "最近" -#: Client/core/ServerBrowser/CServerBrowser.cpp:191 +#: Client/core/ServerBrowser/CServerBrowser.cpp:309 msgid "FOR QUICK CONNECT:\n\n" "Type the address and port into the address bar.\n" "Or select a server from the history list and press 'Connect'" @@ -2548,296 +2617,367 @@ msgstr "快速連線:\n\n" "è¼¸å…¥åˆ°åœ°å€æ¬„的地å€å’Œç«¯å£ã€‚\n" "或從歷å²åˆ—è¡¨ä¸­é¸æ“‡ä¸€å€‹ä¼ºæœå™¨ï¼Œä¸¦æŒ‰ä¸‹ã€Œé€£æŽ¥ã€" -#: Client/core/ServerBrowser/CServerBrowser.cpp:203 +#: Client/core/ServerBrowser/CServerBrowser.cpp:321 msgid "HELP" msgstr "幫助" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:252 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:371 msgid "Refresh" msgstr "釿–°æ•´ç†" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:253 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:372 msgid "Add Favorite" msgstr "新增收è—" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:254 -#: Client/core/ServerBrowser/CServerBrowser.cpp:301 -#: Client/core/ServerBrowser/CServerBrowser.cpp:372 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:373 +#: Client/core/ServerBrowser/CServerBrowser.cpp:457 +#: Client/core/ServerBrowser/CServerBrowser.cpp:528 msgid "Connect" msgstr "連線" -#: Client/core/ServerBrowser/CServerBrowser.cpp:212 -#: Client/core/ServerBrowser/CServerBrowser.cpp:255 +#: Client/core/ServerBrowser/CServerBrowser.cpp:330 +#: Client/core/ServerBrowser/CServerBrowser.cpp:374 msgid "Server information" msgstr "伺æœå™¨è³‡è¨Š" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:256 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:375 msgid "Search servers" msgstr "æœå°‹ä¼ºæœå™¨" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:257 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:376 msgid "Search players" msgstr "æœå°‹çީ家" -#: Client/core/ServerBrowser/CServerBrowser.cpp:213 -#: Client/core/ServerBrowser/CServerBrowser.cpp:258 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:377 msgid "Start search" msgstr "é–‹å§‹æœå°‹" -#: Client/core/ServerBrowser/CServerBrowser.cpp:299 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1680 +#: Client/core/ServerBrowser/CServerBrowser.cpp:331 +#: Client/core/ServerBrowser/CServerBrowser.cpp:378 +msgid "Delete from recent" +msgstr "" + +#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2086 msgid "Search players..." msgstr "æœå°‹çީ家..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:422 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1678 +#: Client/core/ServerBrowser/CServerBrowser.cpp:578 +#: Client/core/ServerBrowser/CServerBrowser.cpp:2084 msgid "Search servers..." msgstr "æœå°‹ä¼ºæœå™¨..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:453 +#: Client/core/ServerBrowser/CServerBrowser.cpp:610 msgid "Name" msgstr "å稱" -#: Client/core/ServerBrowser/CServerBrowser.cpp:454 +#: Client/core/ServerBrowser/CServerBrowser.cpp:611 msgid "Players" msgstr "玩家數" -#: Client/core/ServerBrowser/CServerBrowser.cpp:455 +#: Client/core/ServerBrowser/CServerBrowser.cpp:612 msgid "Ping" msgstr "å»¶é²" -#: Client/core/ServerBrowser/CServerBrowser.cpp:456 +#: Client/core/ServerBrowser/CServerBrowser.cpp:613 msgid "Gamemode" msgstr "éŠæˆ²æ¨¡å¼" #. Include label -#: Client/core/ServerBrowser/CServerBrowser.cpp:486 +#: Client/core/ServerBrowser/CServerBrowser.cpp:647 msgid "Include:" msgstr "包括:" -#: Client/core/ServerBrowser/CServerBrowser.cpp:492 +#: Client/core/ServerBrowser/CServerBrowser.cpp:653 msgid "Empty" msgstr "空白" -#: Client/core/ServerBrowser/CServerBrowser.cpp:498 +#: Client/core/ServerBrowser/CServerBrowser.cpp:659 msgid "Full" msgstr "滿人" -#: Client/core/ServerBrowser/CServerBrowser.cpp:504 +#: Client/core/ServerBrowser/CServerBrowser.cpp:665 msgid "Locked" msgstr "鎖定" -#: Client/core/ServerBrowser/CServerBrowser.cpp:516 +#: Client/core/ServerBrowser/CServerBrowser.cpp:677 msgid "Offline" msgstr "離線" -#: Client/core/ServerBrowser/CServerBrowser.cpp:529 +#: Client/core/ServerBrowser/CServerBrowser.cpp:690 msgid "Other Versions" msgstr "其他版本" -#: Client/core/ServerBrowser/CServerBrowser.cpp:550 +#: Client/core/ServerBrowser/CServerBrowser.cpp:711 msgid "Back" msgstr "返回" -#: Client/core/ServerBrowser/CServerBrowser.cpp:741 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1012 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1026 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1718 msgid "Loading..." msgstr "載入中..." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1223 -#: Client/core/ServerBrowser/CServerBrowser.cpp:2150 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1563 +#: Client/core/ServerBrowser/CServerBrowser.cpp:3039 msgid " ..loading.." msgstr "..載入中.." -#: Client/core/ServerBrowser/CServerBrowser.cpp:1261 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1389 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1601 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1758 msgid "No address specified!" msgstr "尚未指定ä½å€!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Unknown protocol" msgstr "未知的å”è­°" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1274 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1614 msgid "Please use the mtasa:// protocol!" msgstr "請使用 mtasa:// protocol!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1283 -#: Client/core/ServerBrowser/CServerBrowser.cpp:1340 -#: Client/mods/deathmatch/logic/CClientGame.cpp:649 -#: Client/mods/deathmatch/logic/CClientGame.cpp:747 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1623 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1682 +#: Client/mods/deathmatch/logic/CClientGame.cpp:673 +#: Client/mods/deathmatch/logic/CClientGame.cpp:765 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "無效的暱稱! 請去設置那è£è¨­å®šæ–°çš„æš±ç¨±!" -#: Client/core/ServerBrowser/CServerBrowser.cpp:1363 +#: Client/core/ServerBrowser/CServerBrowser.cpp:1708 msgid "You have to select a server to connect to." msgstr "你需è¦é¸æ“‡ä¸€å€‹ä¼ºæœå™¨ä¾†é€£æŽ¥ã€‚" -#: Client/core/ServerBrowser/CServerList.cpp:25 -msgid "Idle" -msgstr "é–’ç½®" +#. Couldn't create render target for CPostEffects +#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:2225 +msgid "Problem with graphics driver" +msgstr "發ç¾é¡¯ç¤ºå¡é©…動程å¼å•題" -#: Client/core/ServerBrowser/CServerList.cpp:150 -msgid "player" -msgid_plural "players" -msgstr[0] "玩家玩家數" +#: Client/game_sa/CSettingsSA.cpp:832 +msgid "Can't find valid screen resolution." +msgstr "無法找到有效的螢幕分辨率。" -#: Client/core/ServerBrowser/CServerList.cpp:151 -msgid "on" -msgstr "æ–¼" +#. Confirm that res should be used +#: Client/game_sa/CSettingsSA.cpp:908 +msgid "Are you sure you want to use this screen resolution?" +msgstr "你確定你想è¦ä½¿ç”¨æ­¤èž¢å¹•分辨率?" -#: Client/core/ServerBrowser/CServerList.cpp:154 -msgid "server" -msgid_plural "servers" -msgstr[0] "伺æœå™¨ä¼ºæœå™¨æ•¸" +#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +msgid "Failed initialization game_sa" +msgstr "åˆå§‹åŒ– game_sa 失敗" -#. We are polling for the master server list (first pass) -#: Client/core/ServerBrowser/CServerList.cpp:238 -#, c-format -msgid "Requesting master server list (%lu ms elapsed)" -msgstr "請求主伺æœå™¨åˆ—è¡¨ï¼ˆå·²éŽ %lu 毫秒)" +#: Client/game_sa/CGameSA.cpp:259 +msgid "Memory allocations failed" +msgstr "記憶體分é…失敗" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:254 -msgid "Master server list could not be parsed." -msgstr "主伺æœå™¨åˆ—表無法解æžã€‚" +#: Client/cefweb/CWebsiteRequests.cpp:19 +msgid "Website requests" +msgstr "網站請求" -#. Abort -#: Client/core/ServerBrowser/CServerList.cpp:264 -msgid "Master server list could not be retrieved." -msgstr "主伺æœå™¨åˆ—表無法檢索。" +#: Client/cefweb/CWebsiteRequests.cpp:27 +msgid "The server requests the following websites in order to load them (later):" +msgstr "ç¾åœ¨çš„伺æœå™¨ (以後) 需è¦è®€å–以下網站:" -#: Client/core/ServerBrowser/CServerList.cpp:274 -msgid "(Backup server list)" -msgstr "(備分伺æœå™¨åˆ—表)" +#: Client/cefweb/CWebsiteRequests.cpp:33 +msgid "NEVER ENTER SENSITIVE DATA TO PROTECT THEM FROM BEING STOLEN" +msgstr "為了防止您é‡è¦è³‡è¨Šè¢«ç«Šå–,請ä¸è¦è¼¸å…¥ä»»ä½•éš±ç§è¨Šæ¯" -#: Client/core/ServerBrowser/CServerList.cpp:326 -msgid "Cannot bind LAN-broadcast socket" -msgstr "ä¸èƒ½ç¶å®šå±€åŸŸç¶²å»£æ’­æ’座" +#: Client/cefweb/CWebsiteRequests.cpp:46 +msgid "Remember decision" +msgstr "è¨˜ä½æˆ‘çš„é¸æ“‡" -#: Client/core/ServerBrowser/CServerList.cpp:345 -msgid "Attempting to discover LAN servers" -msgstr "正在嘗試尋找å€åŸŸç¶²è·¯ä¸­çš„伺æœå™¨" +#: Client/cefweb/CWebsiteRequests.cpp:57 +msgid "Deny" +msgstr "拒絕" -#: Client/mods/deathmatch/CClient.cpp:36 +#: Client/mods/deathmatch/CClient.cpp:38 msgid "This version has expired." msgstr "這個版本已經逾期。" -#: Client/mods/deathmatch/CClient.cpp:56 +#: Client/mods/deathmatch/CClient.cpp:58 msgid "disconnect from the game" msgstr "å¾žéŠæˆ²ä¸­æ–·é€£ç·š" -#: Client/mods/deathmatch/CClient.cpp:57 +#: Client/mods/deathmatch/CClient.cpp:59 msgid "shows the nametags" msgstr "顯示å稱標籤" -#: Client/mods/deathmatch/CClient.cpp:58 +#: Client/mods/deathmatch/CClient.cpp:60 msgid "shows the chatbox" msgstr "顯示å°è©±æ¡†" -#: Client/mods/deathmatch/CClient.cpp:59 +#: Client/mods/deathmatch/CClient.cpp:61 msgid "shows the network statistics" msgstr "顯示網路狀態" #. Key commands (registered as 'mod commands', can be disabled) -#: Client/mods/deathmatch/CClient.cpp:62 +#: Client/mods/deathmatch/CClient.cpp:64 msgid "open the chat input" msgstr "開啟å°è©±æ¡†è¼¸å…¥" -#: Client/mods/deathmatch/CClient.cpp:63 +#: Client/mods/deathmatch/CClient.cpp:65 msgid "transmits voice to other players" msgstr "傳輸語音給其他玩家" -#: Client/mods/deathmatch/CClient.cpp:64 +#: Client/mods/deathmatch/CClient.cpp:66 msgid "enters a car as passenger" msgstr "進入一輛車並作為乘客" -#: Client/mods/deathmatch/CClient.cpp:65 +#: Client/mods/deathmatch/CClient.cpp:67 msgid "next radio channel" msgstr "下一個電å°é »é“" -#: Client/mods/deathmatch/CClient.cpp:66 +#: Client/mods/deathmatch/CClient.cpp:68 msgid "previous radio channel" msgstr "å‰ä¸€å€‹é›»å°é »é“" -#: Client/mods/deathmatch/CClient.cpp:67 +#: Client/mods/deathmatch/CClient.cpp:69 msgid "enables the player-map view" msgstr "啟用玩家地圖檢視" -#: Client/mods/deathmatch/CClient.cpp:68 +#: Client/mods/deathmatch/CClient.cpp:70 msgid "zooms the player-map in" msgstr "放大玩家地圖" -#: Client/mods/deathmatch/CClient.cpp:69 +#: Client/mods/deathmatch/CClient.cpp:71 msgid "zooms the player-map out" msgstr "縮å°çŽ©å®¶åœ°åœ–" -#: Client/mods/deathmatch/CClient.cpp:70 +#: Client/mods/deathmatch/CClient.cpp:72 msgid "moves the player-map north" msgstr "將玩家地圖å‘北移動" -#: Client/mods/deathmatch/CClient.cpp:71 +#: Client/mods/deathmatch/CClient.cpp:73 msgid "moves the player-map south" msgstr "將玩家地圖å‘å—移動" -#: Client/mods/deathmatch/CClient.cpp:72 +#: Client/mods/deathmatch/CClient.cpp:74 msgid "moves the player-map east" msgstr "å°‡çŽ©å®¶åœ°åœ–å‘æ±ç§»å‹•" -#: Client/mods/deathmatch/CClient.cpp:73 +#: Client/mods/deathmatch/CClient.cpp:75 msgid "moves the player-map west" msgstr "將玩家地圖å‘西移動" -#: Client/mods/deathmatch/CClient.cpp:74 +#: Client/mods/deathmatch/CClient.cpp:76 msgid "attaches the player-map" msgstr "固定玩家地圖" -#: Client/mods/deathmatch/CClient.cpp:75 +#: Client/mods/deathmatch/CClient.cpp:77 msgid "reduces player-map opacity" msgstr "é™ä½ŽçŽ©å®¶åœ°åœ–ä¸é€æ˜Žåº¦" -#: Client/mods/deathmatch/CClient.cpp:76 +#: Client/mods/deathmatch/CClient.cpp:78 msgid "increases player-map opacity" msgstr "增加玩家地圖ä¸é€æ˜Žåº¦" -#: Client/mods/deathmatch/CClient.cpp:77 +#: Client/mods/deathmatch/CClient.cpp:79 msgid "toggles player-map help text" msgstr "開啟玩家地圖說明文字" -#: Client/mods/deathmatch/CClient.cpp:78 +#: Client/mods/deathmatch/CClient.cpp:80 msgid "sends a message to the targetted player" msgstr "傳é€äº†ä¸€å‰‡è¨Šæ¯çµ¦ä»–的目標玩家" -#: Client/mods/deathmatch/CClient.cpp:79 +#: Client/mods/deathmatch/CClient.cpp:81 msgid "changes to the next weapon whilst in a vehicle" msgstr "在車內轉æ›äº†ä¸‹ä¸€ç¨®æ­¦å™¨" -#: Client/mods/deathmatch/CClient.cpp:80 +#: Client/mods/deathmatch/CClient.cpp:82 msgid "changes to the previous weapon whilst in a vehicle" msgstr "在車內轉æ›äº†å‰ä¸€ç¨®æ­¦å™¨" -#: Client/mods/deathmatch/CClient.cpp:81 +#: Client/mods/deathmatch/CClient.cpp:83 msgid "outputs info about the current server" msgstr "輸出當å‰ä¼ºæœå™¨çš„資訊" #. ACHTUNG" Should this be handled by the atomic cvar setter? -#: Client/mods/deathmatch/CClient.cpp:84 +#: Client/mods/deathmatch/CClient.cpp:86 msgid "defines the scale multiplier of all text-displays" msgstr "å®šç¾©äº†æ‰€æœ‰æ–‡å­—é¡¯ç¤ºçš„å€æ•¸è¦æ¨¡" #. Development mode -#: Client/mods/deathmatch/CClient.cpp:91 +#: Client/mods/deathmatch/CClient.cpp:93 msgid "(Development mode) shows the colshapes" msgstr "(開發模å¼)顯示山å³å½¢ç‰©ä»¶" -#: Client/mods/deathmatch/CClient.cpp:92 +#: Client/mods/deathmatch/CClient.cpp:94 msgid "(Development mode) prints world sound ids into the debug window" msgstr "(開發模å¼)列出所有è²éŸ³id到除錯窗å£" +#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 +msgid "HOST GAME" +msgstr "ä¸»è¾¦éŠæˆ²" + +#. m_pTabs->CreateTab ( "Gamemode" ); +#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 +msgid "Resources" +msgstr "資æº" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 +msgid "Server name:" +msgstr "伺æœå™¨å稱:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 +msgid "Password:" +msgstr "密碼:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 +msgid "Max players:" +msgstr "最大玩家數:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 +#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 +msgid "Broadcast:" +msgstr "廣播:" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 +msgid "LAN" +msgstr "å€åŸŸç¶²è·¯" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 +msgid "Selected" +msgstr "å·²é¸å–" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 +msgid "All" +msgstr "全部" + +#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 +msgid "Start" +msgstr "啟動" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 +#, c-format +msgid "Change mode: %s" +msgstr "變更模å¼ï¼š %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 +#, c-format +msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" +msgstr "縮放:%s/%s 移動:%s, %s, %s, %s ä¸é€æ˜Žåº¦ï¼š%s/%s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#, c-format +msgid "Toggle map: %s Toggle help text: %s" +msgstr "開啟地圖: %s 開啟說明文字: %s" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 +msgid "Following Player" +msgstr "跟隨玩家" + +#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 +msgid "Free Movement" +msgstr "自由移動" + #: Client/mods/deathmatch/logic/CTransferBox.cpp:25 msgid "Map download progress:" msgstr "地圖下載進度:" @@ -2858,488 +2998,398 @@ msgstr "%s çš„ %s" msgid "Disconnect to cancel download" msgstr "ä¸­æ–·é€£ç·šä»¥å–æ¶ˆä¸‹è¼‰" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:506 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:503 msgid "Disconnected: Invalid nickname" msgstr "連線中斷: 無效的暱稱" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:510 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:507 msgid "Disconnect from server" msgstr "從伺æœä¸­æ–·é€£ç·š" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:514 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:511 #, c-format msgid "Disconnected: Serial is banned.\n" "Reason: %s" msgstr "連線中斷: åºåˆ—è¢«ç¦æ­¢ã€‚\n" "原因: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:520 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:517 #, c-format msgid "Disconnected: You are banned.\n" "Reason: %s" msgstr "連線中斷: ä½ å·²è¢«ç¦æ­¢ã€‚\n" "原因: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:526 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:523 #, c-format msgid "Disconnected: Account is banned.\n" "Reason: %s" msgstr "連線中斷: å¸³è™Ÿå·²è¢«ç¦æ­¢ã€‚\n" "原因: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:531 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:528 msgid "Disconnected: Version mismatch" msgstr "連線中斷: 版本ä¸ç›¸ç¬¦" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:535 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:532 msgid "Disconnected: Join flood. Please wait a minute, then reconnect." msgstr "連線中斷: 加入æµé‡éŽå¤§ï¼Œè«‹ç¨ç­‰å†é‡æ–°é€£ç·šã€‚" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:539 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:536 #, c-format msgid "Disconnected: Server from different branch.\n" "Information: %s" msgstr "連線中斷: ä¸åŒåˆ†æ”¯çš„伺æœå™¨ã€‚\n" "資訊: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:544 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:541 #, c-format msgid "Disconnected: Bad version.\n" "Information: %s" msgstr "連線中斷: 錯誤版本。\n" "資訊: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:549 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:546 #, c-format msgid "Disconnected: Server is running a newer build.\n" "Information: %s" msgstr "連線中斷: 伺æœå™¨æ­£åœ¨é‹è¡Œä¸€å€‹æ›´æ–°ç‰ˆæœ¬çš„組建。\n" "資訊: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:554 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:551 #, c-format msgid "Disconnected: Server is running an older build.\n" "Information: %s" msgstr "連線中斷: 伺æœå™¨æ­£åœ¨é‹è¡Œä¸€å€‹è¼ƒèˆŠç‰ˆæœ¬çš„組建。\n" "資訊: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:559 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:556 msgid "Disconnected: Nick already in use" msgstr "連線中斷: 暱稱已被使用" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:563 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:560 msgid "Disconnected: Player element could not be created." msgstr "已斷線:玩家元素建立失敗。" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:567 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:564 #, c-format msgid "Disconnected: Server refused the connection: %s" msgstr "連線中斷: 伺æœå™¨å·²æ‹’絕連線: %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:572 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:569 msgid "Disconnected: Serial verification failed" msgstr "連線中斷: åºåˆ—驗證失敗" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:576 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:573 msgid "Disconnected: Serial already in use" msgstr "已中斷連線:已有相åŒç¡¬é«”åºè™Ÿè¢«ä½¿ç”¨" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:580 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:577 #, c-format msgid "Disconnected: Connection desync %s" msgstr "連線中斷: 連線ä¸åŒæ­¥ %s" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:589 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:586 #, c-format msgid "Disconnected: You were kicked by %s" msgstr "連線中斷: 你己被 %s 剔除" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:594 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:591 #, c-format msgid "Disconnected: You were banned by %s" msgstr "連線中斷: 你已被 %s ç¦æ­¢" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:605 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:602 msgid "Disconnected: Server shutdown or restarting" msgstr "已斷線:伺æœå™¨å·²ç¶“é—œé–‰æˆ–æ˜¯æ­£åœ¨é‡æ–°å•Ÿå‹•。" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:622 msgid "You were kicked from the game" msgstr "ä½ å¾žéŠæˆ²ä¸­è¢«å‰”除了" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:623 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 msgid "This server requires a non-modifed gta_sa.exe" msgstr "該伺æœå™¨å¿…須使用未經修改éŽçš„ gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:638 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:624 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 msgid "Please replace gta_sa.exe" msgstr "è«‹æ›´æ› gta_sa.exe" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:625 msgid "This server does not allow custom D3D9.DLLs" msgstr "該伺æœå™¨ç¦æ­¢ä½¿ç”¨è‡ªè¨‚çš„D3D9.DLL" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:626 msgid "Remove D3D9.DLL from your GTA install directory and restart MTA" msgstr "請從GTA資料夾中刪除D3D9.DLL䏦釿–°å•Ÿå‹•MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:627 msgid "This server does not allow virtual machines" msgstr "該伺æœå™¨ç¦æ­¢åœ¨è™›æ“¬æ©Ÿä¸ŠåŸ·è¡Œ" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:628 msgid "This server requires driver signing to be enabled" msgstr "該伺æœå™¨éœ€è¦é–‹å•Ÿé©…動程å¼å¼·åˆ¶ç°½ç« " -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:629 msgid "Please restart your PC" msgstr "è«‹é‡æ–°å•Ÿå‹•您的電腦" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:630 msgid "This server has detected missing anti-cheat components" msgstr "該伺æœå™¨æª¢æ¸¬åˆ°éºå¤±çš„防作弊組件" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:634 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:631 msgid "Try restarting MTA" msgstr "嘗試é‡é–‹MTA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:635 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:632 msgid "This server requires a non-modifed gta3.img and gta_int.img" msgstr "該伺æœå™¨å¿…須使用未經修改的 gta3.img å’Œ gta_int.img" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:633 msgid "Please replace gta3.img or gta_int.img" msgstr "è«‹æ›´æ› gta3.img 或是 gta_int.img 回原版檔案" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:639 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:636 msgid "This server does not allow Wine" msgstr "該伺æœå™¨ç¦æ­¢ä½¿ç”¨Wine" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:640 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:637 msgid "Ensure no other program is modifying MTA:SA" msgstr "è«‹ç¢ºèªæ˜¯å¦æœ‰å…¶ä»–ç¨‹å¼æ­£åœ¨ä¿®æ”¹MTA:SA" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:654 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:651 msgid "Time Remaining: " msgstr "剩餘時間:" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:664 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:661 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "%d 天" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:666 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:663 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d å°æ™‚" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:668 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:665 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d 分é˜" -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:670 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:667 #, c-format msgid "%d second" msgid_plural "%d seconds" msgstr[0] "%d ç§’" #. Display the error -#: Client/mods/deathmatch/logic/CPacketHandler.cpp:674 +#: Client/mods/deathmatch/logic/CPacketHandler.cpp:671 msgid "Disconnected" msgstr "已中斷連線" -#. Throw the error and disconnect -#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 -#, c-format -msgid "Download error: %s" -msgstr "下載錯誤: %s" - -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Flying a UFO around" msgstr "開幽浮亂晃" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Cruising around" msgstr "在路上閒晃" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the waves of" msgstr "駕馭海波浪" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Riding the train in" msgstr "æ­è‘—列車到處éŠ" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Flying around" msgstr "開飛機亂繞" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Riding around" msgstr "騎著野狼飆車" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Monster truckin' around" msgstr "開大腳怪ç¸è»Šæ©«è¡ç›´æ’ž" -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Quaddin' around" msgstr "騎沙ç˜è»Šäº‚è·‘" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Bunny hopping around" msgstr "瘋狂兔å­è·³" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Doing weird stuff in" msgstr "æžç¥žç§˜åœ¨" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Climbing around in" msgstr "爬高高在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Doing a drive-by in" msgstr "開車掃射在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Blub blub..." msgstr "呃呃嗚嗚……" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:399 msgid "Breathing water" msgstr "è®Šæˆæ°´ä¸­æ­»äººé­š" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:400 msgid "Drowning in" msgstr "水裡å–到溺死" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:401 msgid "Ducking for cover in" msgstr "龜起來在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:402 msgid "Fighting in" msgstr "激烈戰鬥在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:403 msgid "Throwing fists in" msgstr "åˆ°è™•æ®æ‹³åœ¨" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:404 msgid "Blastin' fools in" msgstr "到處轟人在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:405 msgid "Shooting up" msgstr "äº‚æ§æ‰“人在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:406 msgid "Jetpacking in" msgstr "噴射背包爽飛在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:407 msgid "Literally on fire in" msgstr "燒起來了在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:397 +#: Client/mods/deathmatch/logic/CClientGame.cpp:408 msgid "Burning up in" msgstr "準備燒焦在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:398 +#: Client/mods/deathmatch/logic/CClientGame.cpp:409 msgid "Swimming in" msgstr "游泳在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:410 msgid "Floating around in" msgstr "水裡漂啊漂在" -#: Client/mods/deathmatch/logic/CClientGame.cpp:400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:411 msgid "Being chased by a shark" msgstr "被鯊魚追殺中" -#: Client/mods/deathmatch/logic/CClientGame.cpp:401 +#: Client/mods/deathmatch/logic/CClientGame.cpp:412 msgid "Choking to death in" msgstr "斷氣窒æ¯åœ¨" -#: Client/mods/deathmatch/logic/CClientGame.cpp:665 +#: Client/mods/deathmatch/logic/CClientGame.cpp:689 msgid "Entering the game ..." msgstr "é€²å…¥éŠæˆ²ä¸­..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:723 +#: Client/mods/deathmatch/logic/CClientGame.cpp:741 msgid "Not connected; please use Quick Connect or the 'connect' command to connect to a server." msgstr "未連線;請使用'快速連線'或'連線'指令去連線到伺æœå™¨ã€‚" -#: Client/mods/deathmatch/logic/CClientGame.cpp:769 +#: Client/mods/deathmatch/logic/CClientGame.cpp:787 msgid "Could not start the local server. See console for details." msgstr "無法啟動本地伺æœå™¨.查看控制å°ä»¥äº†è§£è©³æƒ…." -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Local Server" msgstr "本地伺æœå™¨" -#: Client/mods/deathmatch/logic/CClientGame.cpp:779 +#: Client/mods/deathmatch/logic/CClientGame.cpp:797 msgid "Starting local server ..." msgstr "啟動本地伺æœå™¨ä¸­..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1027 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1045 msgid "Area 51" msgstr "51å€" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1036 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1054 msgid "Walking around " msgstr "到處走 " -#: Client/mods/deathmatch/logic/CClientGame.cpp:1182 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1199 #, c-format msgid "You were kicked from the game ( %s )" msgstr "ä½ å¾žéŠæˆ²ä¸­è¢«å‰”除了 ( %s )" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1251 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1268 msgid "Connecting to local server..." msgstr "正在連線至本地伺æœå™¨..." -#: Client/mods/deathmatch/logic/CClientGame.cpp:1262 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1279 msgid "Error connecting to server." msgstr "連線到伺æœå™¨æ™‚發生錯誤。" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1272 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1289 msgid "Connecting to local server timed out. See console for details." msgstr "連線到本地伺æœå™¨é€¾æ™‚,請查看控制å°ä»¥è©³ç´°äº†è§£ã€‚" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1378 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 msgid "Connection with the server was lost" msgstr "與伺æœå™¨çš„連線已éºå¤±" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1422 msgid "Disconnected: the server is currently full" msgstr "連線中斷: 該伺æœå™¨ç›®å‰æ»¿äºº" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1417 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1434 msgid "Disconnected: invalid password specified" msgstr "連線中斷: 指定的密碼無效" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1439 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1456 msgid "MTA Client verification failed!" msgstr "MTA 客戶端驗證失敗" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "In a ditch" msgstr "åœ¨æºæ¸ è£¡" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "En-route to hospital" msgstr "æ­ä¸Šå¾€é†«é™¢çš„ç›´é”車" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5640 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Meeting their maker" msgstr "見上å¸åŽ»äº†" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Regretting their decisions" msgstr "悔其一生決定中" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5691 msgid "Wasted" msgstr "領便當了" -#: Client/mods/deathmatch/logic/CLocalServer.cpp:37 -msgid "HOST GAME" -msgstr "ä¸»è¾¦éŠæˆ²" - -#. m_pTabs->CreateTab ( "Gamemode" ); -#: Client/mods/deathmatch/logic/CLocalServer.cpp:53 -msgid "Resources" -msgstr "資æº" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:55 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:57 -msgid "Server name:" -msgstr "伺æœå™¨å稱:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:64 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:66 -msgid "Password:" -msgstr "密碼:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:73 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:75 -msgid "Max players:" -msgstr "最大玩家數:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:82 -#: Client/mods/deathmatch/logic/CLocalServer.cpp:84 -msgid "Broadcast:" -msgstr "廣播:" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:86 -msgid "LAN" -msgstr "å€åŸŸç¶²è·¯" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:99 -msgid "Selected" -msgstr "å·²é¸å–" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:116 -msgid "All" -msgstr "全部" - -#: Client/mods/deathmatch/logic/CLocalServer.cpp:118 -msgid "Start" -msgstr "啟動" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:78 -#, c-format -msgid "Change mode: %s" -msgstr "變更模å¼ï¼š %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:80 -#, c-format -msgid "Zoom: %s/%s Movement: %s, %s, %s, %s Opacity: %s/%s" -msgstr "縮放:%s/%s 移動:%s, %s, %s, %s ä¸é€æ˜Žåº¦ï¼š%s/%s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:84 +#. Throw the error and disconnect +#: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:141 #, c-format -msgid "Toggle map: %s Toggle help text: %s" -msgstr "開啟地圖: %s 開啟說明文字: %s" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:714 -msgid "Following Player" -msgstr "跟隨玩家" - -#: Client/mods/deathmatch/logic/CPlayerMap.cpp:716 -msgid "Free Movement" -msgstr "自由移動" - -#. Couldn't create render target for CPostEffects -#: Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp:1450 -msgid "Problem with graphics driver" -msgstr "發ç¾é¡¯ç¤ºå¡é©…動程å¼å•題" - -#: Client/game_sa/CSettingsSA.cpp:781 -msgid "Can't find valid screen resolution." -msgstr "無法找到有效的螢幕分辨率。" - -#. Confirm that res should be used -#: Client/game_sa/CSettingsSA.cpp:857 -msgid "Are you sure you want to use this screen resolution?" -msgstr "你確定你想è¦ä½¿ç”¨æ­¤èž¢å¹•分辨率?" - -#: Client/game_sa/CGameSA.cpp:256 Client/game_sa/CGameSA.cpp:267 -msgid "Failed initialization game_sa" -msgstr "åˆå§‹åŒ– game_sa 失敗" - -#: Client/game_sa/CGameSA.cpp:258 -msgid "Memory allocations failed" -msgstr "記憶體分é…失敗" +msgid "Download error: %s" +msgstr "下載錯誤: %s" #. Populate the message and show the box #: Shared/mods/deathmatch/logic/Utils.cpp:127 @@ -3360,11 +3410,11 @@ msgstr "通訊å”定錯誤 (%u)。如果å•題æŒçºŒå­˜åœ¨ï¼Œè«‹è‡³ multitheftau msgid "Connection error" msgstr "連線錯誤" -#: Shared/sdk/SharedUtil.Misc.hpp:137 +#: Shared/sdk/SharedUtil.Misc.hpp:381 msgid "Multi Theft Auto has not been installed properly, please reinstall." msgstr "MTA 並沒有被正確安è£ï¼Œè«‹é‡æ–°å®‰è£ã€‚" -#: Shared/sdk/SharedUtil.Misc.hpp:702 +#: Shared/sdk/SharedUtil.Misc.hpp:1476 msgid "Your browser will now display a web page with some help infomation.\n\n" "(If the page fails to load, paste (CTRL-V) the URL into your web browser)" msgstr "ä½ çš„ç€è¦§å™¨ç¾åœ¨æœƒé¡¯ç¤ºå‡ºå¹«åŠ©è³‡è¨Šçš„é é¢ã€‚\n\n" diff --git a/Shared/data/data files installer.nsi b/Shared/data/data files installer.nsi index 5156ec18286..7b35f7b0d73 100644 --- a/Shared/data/data files installer.nsi +++ b/Shared/data/data files installer.nsi @@ -16,7 +16,7 @@ Var Install_Dir !ifndef MAJOR_VER !define MAJOR_VER "1" - !define MINOR_VER "6" + !define MINOR_VER "7" !define MAINT_VER "0" !endif !define 0.0 "${MAJOR_VER}.${MINOR_VER}" @@ -84,14 +84,14 @@ Function .onInit ; Try to find previously saved MTA:SA install path ReadRegStr $Install_Dir HKLM "SOFTWARE\Multi Theft Auto: San Andreas All\${0.0}" "Last Install Location" - ${If} $Install_Dir == "" + ${If} $Install_Dir == "" ReadRegStr $Install_Dir HKLM "SOFTWARE\Multi Theft Auto: San Andreas ${0.0}" "Last Install Location" ${EndIf} - ${If} $Install_Dir == "" + ${If} $Install_Dir == "" strcpy $Install_Dir "$PROGRAMFILES\MTA San Andreas ${0.0}" ${EndIf} strcpy $INSTDIR $Install_Dir - + InitPluginsDir ;File /oname=$PLUGINSDIR\serialdialog.ini "serialdialog.ini" FunctionEnd @@ -141,9 +141,14 @@ Section "Data files" SEC01 File "${FILES_ROOT}\MTA San Andreas\mta\vog.dll" File "${FILES_ROOT}\MTA San Andreas\mta\vvo.dll" File "${FILES_ROOT}\MTA San Andreas\mta\vvof.dll" - + File "${FILES_ROOT}\MTA San Andreas\mta\d3dcompiler_43.dll" File "${FILES_ROOT}\MTA San Andreas\mta\d3dcompiler_47.dll" + !ifdef MTA_MAETRO + File /oname=d3dcompiler_47.dll "${FILES_ROOT}\MTA San Andreas\mta\d3dcompiler_47.maetro.dll" + !else + File "${FILES_ROOT}\MTA San Andreas\mta\d3dcompiler_47.dll" + !endif File "${FILES_ROOT}\MTA San Andreas\mta\libEGL.dll" File "${FILES_ROOT}\MTA San Andreas\mta\libGLESv2.dll" @@ -155,13 +160,13 @@ Section "Data files" SEC01 File "${FILES_ROOT}\MTA San Andreas\skins\Classic\CGUI.lnf.xml" File "${FILES_ROOT}\MTA San Andreas\skins\Classic\CGUI.png" File "${FILES_ROOT}\MTA San Andreas\skins\Classic\CGUI.xml" - + SetOutPath "$INSTDIR\skins\Default" File "${FILES_ROOT}\MTA San Andreas\skins\Default\CGUI.is.xml" File "${FILES_ROOT}\MTA San Andreas\skins\Default\CGUI.lnf.xml" File "${FILES_ROOT}\MTA San Andreas\skins\Default\CGUI.png" File "${FILES_ROOT}\MTA San Andreas\skins\Default\CGUI.xml" - + SetOutPath "$INSTDIR\skins\Lighter black" File "${FILES_ROOT}\MTA San Andreas\skins\Lighter black\CGUI.is.xml" File "${FILES_ROOT}\MTA San Andreas\skins\Lighter black\CGUI.lnf.xml" @@ -185,7 +190,7 @@ Section "Data files" SEC01 File "${FILES_ROOT}\MTA San Andreas\skins\GWEN Orange\CGUI.lnf.xml" File "${FILES_ROOT}\MTA San Andreas\skins\GWEN Orange\CGUI.png" File "${FILES_ROOT}\MTA San Andreas\skins\GWEN Orange\CGUI.xml" - + SetOutPath "$INSTDIR\MTA\cgui" File "${FILES_ROOT}\MTA San Andreas\mta\cgui\Falagard.xsd" File "${FILES_ROOT}\MTA San Andreas\mta\cgui\Font.xsd" @@ -207,7 +212,7 @@ Section "Data files" SEC01 SetOutPath "$INSTDIR\MTA\cgui\images\transferset" File "${FILES_ROOT}\MTA San Andreas\mta\cgui\images\transferset\*.png" - + SetOutPath "$INSTDIR\MTA\cgui\images\serverbrowser" File "${FILES_ROOT}\MTA San Andreas\mta\cgui\images\serverbrowser\*.png" diff --git a/Shared/data/launchers.maetro/CEFLauncher.exe b/Shared/data/launchers.maetro/CEFLauncher.exe new file mode 100644 index 00000000000..f27c9e2d7b4 Binary files /dev/null and b/Shared/data/launchers.maetro/CEFLauncher.exe differ diff --git a/Shared/data/launchers.maetro/MTA Server.exe b/Shared/data/launchers.maetro/MTA Server.exe new file mode 100644 index 00000000000..81b3f4c2657 Binary files /dev/null and b/Shared/data/launchers.maetro/MTA Server.exe differ diff --git a/Shared/data/launchers.maetro/MTA Server64.exe b/Shared/data/launchers.maetro/MTA Server64.exe new file mode 100644 index 00000000000..d5379a3ed76 Binary files /dev/null and b/Shared/data/launchers.maetro/MTA Server64.exe differ diff --git a/Shared/data/launchers.maetro/Multi Theft Auto.exe b/Shared/data/launchers.maetro/Multi Theft Auto.exe new file mode 100644 index 00000000000..19069c0ed47 Binary files /dev/null and b/Shared/data/launchers.maetro/Multi Theft Auto.exe differ diff --git a/Shared/data/launchers.maetro/wow64_helper.exe b/Shared/data/launchers.maetro/wow64_helper.exe new file mode 100644 index 00000000000..241bdc548ac Binary files /dev/null and b/Shared/data/launchers.maetro/wow64_helper.exe differ diff --git a/Shared/data/launchers/CEFLauncher.exe b/Shared/data/launchers/CEFLauncher.exe index f4fe952cf1d..52be9710e69 100644 Binary files a/Shared/data/launchers/CEFLauncher.exe and b/Shared/data/launchers/CEFLauncher.exe differ diff --git a/Shared/data/launchers/MTA Server ARM64.exe b/Shared/data/launchers/MTA Server ARM64.exe index 8a96dfc403d..492e5bdcc11 100644 Binary files a/Shared/data/launchers/MTA Server ARM64.exe and b/Shared/data/launchers/MTA Server ARM64.exe differ diff --git a/Shared/data/launchers/MTA Server.exe b/Shared/data/launchers/MTA Server.exe index d60641984c9..9c8b8a13a2d 100644 Binary files a/Shared/data/launchers/MTA Server.exe and b/Shared/data/launchers/MTA Server.exe differ diff --git a/Shared/data/launchers/MTA Server64.exe b/Shared/data/launchers/MTA Server64.exe index bc7b3c5bc26..d5379a3ed76 100644 Binary files a/Shared/data/launchers/MTA Server64.exe and b/Shared/data/launchers/MTA Server64.exe differ diff --git a/Shared/data/launchers/Multi Theft Auto.exe b/Shared/data/launchers/Multi Theft Auto.exe index 8f7ebd0a643..73f24909927 100644 Binary files a/Shared/data/launchers/Multi Theft Auto.exe and b/Shared/data/launchers/Multi Theft Auto.exe differ diff --git a/Shared/data/launchers/wow64_helper.exe b/Shared/data/launchers/wow64_helper.exe index 2a196aa7009..d528ec50c53 100644 Binary files a/Shared/data/launchers/wow64_helper.exe and b/Shared/data/launchers/wow64_helper.exe differ diff --git a/Shared/installer/NSIS dirs/Plugins/ApplicationID.dll b/Shared/installer/NSIS dirs/Plugins/ApplicationID.dll new file mode 100644 index 00000000000..5fc0480256d Binary files /dev/null and b/Shared/installer/NSIS dirs/Plugins/ApplicationID.dll differ diff --git a/Shared/installer/locale/ar_SA.pot b/Shared/installer/locale/ar_SA.pot index eed80cd867f..89debf9cfe5 100644 --- a/Shared/installer/locale/ar_SA.pot +++ b/Shared/installer/locale/ar_SA.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-05-10 06:51\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Arabic\n" "Language: ar_SA\n" @@ -18,201 +18,201 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "الإصدار الذي قمت بتنزيله لـ MTA:SA لا يدعم ويندوز XP أو Vista. يرجى تنزيل إصدار بديل من www.multitheftauto.com." #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "الإصدار الذي قمت بتنزيله لـ MTA:SA لا يدعم ويندوز 7ØŒ 8 أو 8.1. يرجى تنزيل إصدار بديل من www.multitheftauto.com." #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "الإصدار الذي قمت بتنزيله لـ MTA:SA مصمم لإصدارات ويندوز أقدم. يرجى تنزيل إصدار بديل من www.multitheftauto.com." #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" "Click Next to continue." -msgstr " معالج Ùˆ مرشد التثبيت او التحديث من $(^Name) ${REVISION_TAG}\n\n" -" ننصح بـ اغلاق جميع البرامج قبل بدء التثبيت .\n\n" -" [ ربما يتم طلب صلاحيات المسؤول لـ نظام Ùيستا Ùˆ ماÙوق .]\n\n" -"اضغط التالي للمتابعة.." +msgstr "سيساعدك هذا البرنامج ÙÙŠ تثبيت أو تحديث $(^Name) ${REVISION_TAG}\n\n" +"ÙŠÙنصح بإغلاق جميع التطبيقات الأخرى قبل بدء التثبيت.\n\n" +"[قد ÙŠÙØ·Ù„ب الوصول كمسؤول ÙÙŠ أنظمة Vista والإصدارات الأحدث]\n\n" +"انقر على \"التالي\" للمتابعة." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "مجلد Grand Theft Auto: San Andreas " #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "مكان لعبة Grand Theft Auto: San Andreas " #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" "$\n" "Click Install to begin installing." -msgstr "الرجاء اختيار مجلد لعبة Grand Theft Auto: San Andreas.$\n" +msgstr "يرجى تحديد مجلد Grand Theft Auto: San Andreas الخاص بك.$\n" " $\n" -" يجب ان تكون لديك نسخة مثبتة من اللعبة MTA) ØŒGrand Theft Auto: San Andreas v1.0) لا تدعم اي نسخة اخرى.$\n" +"يجب أن يكون لديك إصدار Grand Theft Auto: San Andreas 1.0 مثبتًا لاستخدام MTA:SAØŒ حيث إنه لا يدعم أي إصدارات أخرى.$\n" " $\n" -"انقر Ùوق تثبيت لبدء التركيب." +"انقر على تثبيت لبدء عملية التثبيت." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "إنشاء مجموعة ÙÙŠ قائمة ابدأ للتطبيقات المثبتة" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "انشاء اختصار ÙÙŠ سطح المكتب لـMTA:SA" #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "تسجيل بروتوكل mtasa:// لكي يكون قابل للنقر ÙÙŠ Ø§Ù„Ù…ØªØµÙØ­." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." -msgstr "أض٠الى مستكش٠العاب ويندوز ( اذا كان موجوداَ ) ." +msgstr "Ø¥Ø¶Ø§ÙØ© إلى مستعرض ألعاب ويندوز (إن ÙˆÙØ¬Ø¯)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "ثبت أو حدث DirectX (إن كان ضروريا)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." -msgstr "العناصراللازمة لـ تشغيل برنامج Multi Theft Auto." +msgstr "المكونات الأساسية المطلوبة لتشغيل Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." -msgstr "ÙÙŠ MTA:SA التعديل , يسمح لك اللعب اون لاين ." +msgstr "تعديل MTA:SAØŒ والذي يتيح لك اللعب عبر الإنترنت." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." -msgstr "يمكنك Ø§Ø³ØªØ¶Ø§ÙØ© Ø³ÙŠØ±ÙØ± MTA من جهازك * يتطلب اتصال انترنت سريع ." +msgstr "خادم Multi Theft Auto. يتيح لك هذا Ø§Ø³ØªØ¶Ø§ÙØ© الألعاب من جهازك. يتطلب اتصال إنترنت سريع." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." -msgstr "الشيء المطلوب من MTA هو انشاء Ø³ÙŠØ±ÙØ± Ùˆ التمكن من اللعب Ùية اون لاين ." +msgstr "خادم Multi Theft Auto. هذا مكون ضروري." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA تعديلها Ù„Ù„Ø³ÙŠØ±ÙØ± ." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "هذهـ بعض المودات المطلوبة Ù„Ù„Ø³ÙŠØ±ÙØ± ." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "هذا اختياري لـ وضع اغلب القيمات Ùˆ المابات لـ Ø³ÙŠØ±ÙØ±ÙƒÙ€ ." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "الـ MTA:SA 1.0 Map Editor يمكنك من خلاله عمل خريطة خاص بك لكي تستعملها ÙÙŠ أواضع لعب MTA ." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr " SDK لـ انشاء وحدات ثنائية للخادم الخاص بـ MTA اذا كانت لديك اللغة الجيدهـ ÙÙŠ برمجة C++ Ùقط !" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "كود التطوير Ùˆ الادوات تساعد الاعبين على الدخول لـ MTA ." #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "التطبيق هو البرنامج الذي تشلغه من اجل اللعب ÙÙŠ خادم ÙÙŠ Multi Theft Auto" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" -msgstr "المستخدم Ùˆ الخادم" +msgstr "العميل والخادم" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "للخادم Ùقط" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "تشغيل قائمة المجموعه " #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "ايقونة سطح المكتب" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "تسجيل بروتوكول //:mtasa" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Ø§Ø¶Ø§ÙØªØ© الى مستكش٠الالعاب" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "ثبت DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "لعبة كلنت ( عميل )" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "خادم خاص" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "المكونات الاساسية" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" -msgstr "لعبة وحدة" +msgstr "وحدة اللعبة" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "جاري الترقية ÙÙŠ Ù†ÙØ³ المكان ..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." -msgstr "تحديث الاذونات .. قد يستغرق دقائق معدودهـ ..." +msgstr "جاري تحديث الأذونات. قد يستغرق هذا بضع دقائق..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,192 +221,193 @@ msgstr "لم يتم العثور على : Grand Theft Auto: San Andreas ÙÙŠ ا "رجاءَ قم باعادهـ التثبيت اذا كان هناك مشكلة لاحقاَ ." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" -msgstr "المودات الاساسية" +msgstr "الموارد الأساسية" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" -msgstr "المودات الاختيارية" +msgstr "الموارد الاختيارية" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "المحرر ( التعديل )" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "تطوير" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." -msgstr "تمت إزالة $(^Name) بنجاح من حاسبك الألكتروني." +msgstr "تم إزالة $(^Name) بنجاح من جهاز الكمبيوتر الخاص بك." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" -msgstr "ÙØ´Ù„ الغاء التثبيت !" +msgstr "ÙØ´Ù„ إلغاء التثبيت!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" -msgstr "هل انت متأكد انك تريد ازالة $(^Name) Ùˆ جميع المكونات الخاصة بة ØŸ" +msgstr "هل أنت متأكد أنك تريد إزالة $(^Name) وكل مكوناته تمامًا؟" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." -msgstr "الغاء التثبيت قبل التحديث$\\r$\n" -"ليس ضروريا إلغاء التثبيت قبل تثبيت نسخة جديدة من MTA:SA$\\r$\n" -"شغل المثبت الجديد للتحديث Ùˆ Ø­ÙØ¸ إعداداتك" +msgstr "هل تريد إلغاء التثبيت قبل التحديث؟$\\r$\n" +"ليس من الضروري إلغاء التثبيت قبل تثبيت نسخة جديدة من MTA:SA.$\\r$\n" +"شغل المثبّت الجديد للترقية مع Ø§Ù„Ø­ÙØ§Ø¸ على إعداداتك." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." -msgstr "هل تود Ø­ÙØ¸ بياناتك مثل ( المودات , الصور لقطات الشاشة Ùˆ جميع اعدادات Ø§Ù„Ø³ÙŠØ±ÙØ± الخاص بـ جهازك ) ØŸ اذا قمت باختيار لا اي مود موجود او اعداد او لقطات للشاشة من قبل سو٠تذهب Ùˆ تزال نهائيا ." +msgstr "هل ترغب ÙÙŠ Ø§Ù„Ø§Ø­ØªÙØ§Ø¸ Ø¨Ù…Ù„ÙØ§Øª البيانات الخاصة بك (مثل الموارد، لقطات الشاشة، وتكوينات Ø§Ù„Ø³ÙŠØ±ÙØ±)ØŸ\n" +"إذا ضغطت لا، ÙØ³ÙŠØªÙ… Ùقدان أي موارد أو إعدادات أو لقطات شاشة قمت بإنشائها." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" -msgstr "هذا التثبيت يحتاج الى صلاحيات مسؤول حاول مرة اخرى " +msgstr "هذا المثبّت يحتاج صلاحيات المسؤول، حاول مرة أخرى" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" -msgstr "حاول ازالة التثبيت بـ صلاحيات مسؤول حاول مرة اخرى" +msgstr "إزالة التثبيت يحتاج صلاحيات المسؤول، حاول مرة أخرى" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" -msgstr "خدمة تسجيل الدخول لا تعمل! احباط!" +msgstr "خدمة تسجيل الدخول غير نشطة، تم الإلغاء!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" -msgstr "غير قادر على Ø§Ù„Ø±ÙØ¹ !" +msgstr "غير قادر على Ø±ÙØ¹ الصلاحيات" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" " Are you sure you want to overwrite MTA $1 at $INSTDIR ?" -msgstr "هناك نسخة سابقة من MTA ($1) ÙÙŠ هذا المسار.$\n" +msgstr "نسخة رئيسية Ù…Ø®ØªÙ„ÙØ© من MTA ($1) موجودة Ø¨Ø§Ù„ÙØ¹Ù„ ÙÙŠ ذلك المسار.$\n" " $\n" -"MTA تم اعدادها للاصدارات الرئيسية لم يتم التثبيت ÙÙŠ مسار مختل٠$\n" -"هل انت متأكد انك تريد تبديل وكتابة Ø§Ù„Ù…Ù„ÙØ§Øª $1 ÙÙŠ $INSTDIR ØŸ" +"MTA مصمم بحيث ØªÙØ«Ø¨Øª النسخ الرئيسية Ø§Ù„Ù…Ø®ØªÙ„ÙØ© ÙÙŠ مسارات Ù…Ù†ÙØµÙ„Ø©.$\n" +"هل أنت متأكد من رغبتك ÙÙŠ استبدال MTA $1 ÙÙŠ $INSTDIR ØŸ" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" "$DEFAULT_INSTDIR ?" -msgstr "MTA لا يمكن تثبيتها ÙÙŠ Ù†ÙØ³ مل٠GTA:SA$\n" +msgstr "لا يمكن تثبيت MTA ÙÙŠ Ù†ÙØ³ مجلد GTA:SA.$\n" "$\n" -"هل تريد استعمال مل٠التثبيت الأساسي؟$\n" -"$DEFAULT_INSTDIR ?" +"هل تريد استخدام مجلد التثبيت Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØŸ$\n" +"$DEFAULT_INSTDIR ØŸ" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" -msgstr " المسار المختار غير موجود .$\n" -" $\n" -" الرجاء اختيار مسار GTA:SA الخاص بك !" +msgstr "المجلد المختار غير موجود.$\n" +"$\n" +"يرجى اختيار مجلد تثبيت GTA:SA!" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" -msgstr "لم يتم العثور على GTA:SA مثبتة ÙÙŠ $GTA_DIR $\n" -" $\n" -"هل انت متأكد انك تريد المتابعة ØŸ" +msgstr "تعذر العثور على GTA:SA مثبتة ÙÙŠ $GTA_DIR $\n" +"$\n" +"هل أنت متأكد أنك تريد المتابعة؟" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "اختر مسار التثبيت" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "اختيار المجلد الذي سيتم Ùيه تثبيت ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" " Click Next to continue." -msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} سيتم تثبيتة ÙÙŠ المجلد التالي :$\n" -"لـ التثبيت ÙÙŠ مجلد اخر انقر Ùوق استعراض .$\n" -" $\n" -"انقر Ùوق التالي للاستكمال ." +msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} سيتم تثبيته ÙÙŠ المجلد التالي.$\n" +"لتثبيته ÙÙŠ مجلد Ù…Ø®ØªÙ„ÙØŒ اضغط على استعراض واختر مجلدًا آخر.$\n" +"$\n" +"اضغط التالي للمتابعة." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "وجهة المل٠( المسار )" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." -msgstr "استعراض" +msgstr "استعراض..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Ø§ÙØªØ±Ø§Ø¶ÙŠ" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "اخر استخدام" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "مخصص" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "اختر المجلد لـ تثبيت ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} ÙÙŠ:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." -msgstr "تحذير : هناك نسخة مثبتة من MTA ($1) ÙÙŠ هذا المسار مسبقا!" +msgstr "تحذير: نسخة رئيسية Ù…Ø®ØªÙ„ÙØ© من MTA ($1) موجودة Ø¨Ø§Ù„ÙØ¹Ù„ ÙÙŠ هذا المسار." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" -msgstr "نوع الثبيت : ترقية" +msgstr "نوع الثبيت: ترقية" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" -msgstr "التحديث عبر الانترنت ." +msgstr "تحديث عبر الانترنت" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" -msgstr "يتم التحقق من معلومات التحديث" +msgstr "جار٠التحقق من معلومات التحديث" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." -msgstr "جاري التحقق من معلومات مثبت التحديث..." +msgstr "جاري التحقق من معلومات تحديث برنامج التثبيت..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" -msgstr "الرجاء التأكد أن جدار الحماية الخاص بك لا يمنع" +msgstr "يرجى التأكد من أن جدار الحماية الخاص بك لا يمنع الاتصال" diff --git a/Shared/installer/locale/az_AZ.pot b/Shared/installer/locale/az_AZ.pot index 49b53911c37..2659f585143 100644 --- a/Shared/installer/locale/az_AZ.pot +++ b/Shared/installer/locale/az_AZ.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Azerbaijani\n" "Language: az_AZ\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Bu sehirbaz quraÅŸdırma vÉ™ güncÉ™lləşdirmÉ™ üçün sizi müşaiyÉ™ "DÉ™vam etmÉ™k üçün \"İrÉ™li\" basın." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreas yeri" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas qovluÄŸu" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "XahiÅŸ Grand Theft Auto: San Andreas qovluqunu seçin.$\n" "QuraÅŸdırmanı baÅŸlamaq üçün \"QuraÅŸdır\" basın." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "YüklÉ™nmiÅŸ proqramlar üçün \"BaÅŸlat\" menyusunda qrup yarat." #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "MTA:SA masaüstü qısayolu yarat." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "İnternetdÉ™n qoÅŸulmaq üçün brauzerinizdÉ™ mtasa:// protokolunu qeydiyyatdan keçirin." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Windows Games qovluquna É™lavÉ™ edin. (Varsa)" #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "DirectX'i yüklÉ™ vÉ™ ya güncÉ™llÉ™ (É™gÉ™r lazımdırsa)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Multi Theft Auto-nu iÅŸÉ™ salmaq üçün tÉ™lÉ™b olunan É™sas komponentlÉ™r." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA modu, Online oynamaq üçün sizi gözlÉ™yir." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto serveri. Serverinizi iÅŸÉ™ saldıqda, diqÉ™r oyunçuları ona baÄŸlamaq imkan verir. Bunun üçün sürÉ™tli internet baÄŸlantısı lazımdır." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto server. Bu tÉ™lÉ™b olunan komponentdir." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "Server üçün MTA: SA modifikasiyası." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Bu serveriniz üçün tövsiyÉ™ olunan resurslar siyahısıdır." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Bu, serveriniz üçün istÉ™yÉ™ baÄŸlı oyun modları vÉ™ xÉ™ritÉ™lÉ™r dÉ™stidir." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA: SA 1.0 XÉ™ritÉ™ Redaktoru. Bu, MTA üçün gamemodlarda istifadÉ™ üçün öz xÉ™ritÉ™lÉ™rinizi yaratmaq üçün istifadÉ™ edilÉ™ bilÉ™r." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "SDK. Server üçün modullar yaratmaq üçün lazımdır. Yalnız C ++ bilirsiniszÉ™ quraÅŸdırın!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Multi Theft Auto üçün modların yaradılmasına kömÉ™k edÉ™ bilÉ™n inÅŸaat kodu vÉ™ digÉ™r vasitÉ™lÉ™r" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Client Multi Theft Auto serverindÉ™ oynamaq üçün iÅŸlÉ™tdiyiniz proqramdır" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Client vÉ™ Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Yalnız Server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "BaÅŸlat menyusu" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Masaüstü tÉ™svir" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "mtasa:// protokolunu qeyd et" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Oyun tarayıcısına É™lavÉ™ edin" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "DirectX quraÅŸdırın" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Oyun istemcisi" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Xüsusi server" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Æsas komponentlÉ™r" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Oyun modulu" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Cari quraÅŸdırma yenilÉ™nir" #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "İcazÉ™lÉ™r güncÉ™llÉ™nir. Bu bir neçə dÉ™qiqÉ™ çəkÉ™ bilÉ™r ..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,43 +221,43 @@ msgstr "Grand Theft Auto : San Andreas ' ın lazımlı versiyası tapılmadı.$\ "ProblemlÉ™r aÅŸkarlansa tÉ™zÉ™dÉ™n quraÅŸdırın." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Æsas resurslar" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "İstÉ™yÉ™ baÄŸlı resurslar" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Redaktor" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "İnkiÅŸaf" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) sizin kompüterinizdÉ™n silindi" #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "SilinmÉ™ xÉ™ta ilÉ™ keçdi!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "\n" "$(^Name) vÉ™ onun bütün komponentlÉ™rini tamamilÉ™ silmÉ™k istÉ™diyinizÉ™ É™minsiniz?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -267,32 +267,32 @@ msgstr "\n" "ParametrlÉ™rinizi tÉ™kmilləşdirmÉ™k vÉ™ qorumaq üçün yeni quraÅŸdırıcını iÅŸÉ™ salın." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "MÉ™lumat fayllarınızı (resurslar, ekran görüntülÉ™ri vÉ™ server konfiqurasiyası kimi) saxlamaq istÉ™rdinizmi? Xeyr kliklÉ™sÉ™niz, yaratdığınız hÉ™r hansı resurs, konfiqurasiya vÉ™ ya ekran görüntülÉ™ri itirilÉ™cÉ™k." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Bu quraÅŸdırıcı admin haqqı tÉ™lÉ™b edir, yenidÉ™n cÉ™hd edin" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Bu silici admin haqqı tÉ™lÉ™b edir, yenidÉ™n cÉ™hd edin" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Daxil olma xidmÉ™ti iÅŸlÉ™mir, dayandırılır!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Ucaltmaq mümkün deyil" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -302,7 +302,7 @@ msgstr "MTA-nın fÉ™rqli É™sas versiyası ($1) hÉ™min yolda artıq mövcuddur.$\ " $INSTDIR-dÉ™ MTA $1-in üzÉ™rinÉ™ yazmaq istÉ™diyinizÉ™ É™minsiniz?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -313,7 +313,7 @@ msgstr "MTA GTA:SA.$ ilÉ™ eyni qovluÄŸa quraÅŸdırıla bilmÉ™z\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -322,7 +322,7 @@ msgstr "SeçilmiÅŸ kataloq mövcud deyil.$\n" "LütfÉ™n, GTA:SA quraÅŸdırma kataloqunu seçin" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -331,17 +331,17 @@ msgstr "$GTA_DIR $-da quraÅŸdırılmış GTA:SA-nı tapmaq mümkün olmadı\n" "Davam etmÉ™k istÉ™diyinizÉ™ É™minsiniz?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "YüklÉ™nÉ™cÉ™k yeri seç" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "QuraÅŸdırılacaq qovluÄŸu seçin ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -352,62 +352,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} aÅŸağıdakı qovluÄŸa quraÅŸd " Davam etmÉ™k üçün ilÉ™ri kliklÉ™yin." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "HÉ™dÉ™f qovluÄŸu" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Seç..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Standart" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Son istifadÉ™" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Xüsusi" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "YüklÉ™nÉ™cÉ™k qovluÄŸu seç ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} içərisinÉ™:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "XÉ™bÉ™rdarlıq: MTA-nın fÉ™rqli É™sas versiyası ($1) hÉ™min yolda artıq mövcuddur." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "QuraÅŸdırma növü: YüksÉ™ltmÉ™" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Onlayn YenilÉ™mÉ™" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "YenilÉ™mÉ™ mÉ™lumatı yoxlanılır" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "YüklÉ™mÉ™ mÉ™lumatı yoxlanılır..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "ZÉ™hmÉ™t olmasa, tÉ™hlükÉ™sizlik divarınız bloklanmadığından É™min olun" diff --git a/Shared/installer/locale/bg_BG.pot b/Shared/installer/locale/bg_BG.pot index 625778f1af0..e67107d093c 100644 --- a/Shared/installer/locale/bg_BG.pot +++ b/Shared/installer/locale/bg_BG.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Bulgarian\n" "Language: bg_BG\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Този помощник ще ви води през инÑталаци "Цъкнете Продължи за да продължите." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Папката на Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Папката на Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "ÐœÐ¾Ð»Ñ Ð¸Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ папката на Grand Theft Auto: San Andr "Цъкнете ИнÑталирай за да продължите." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Създай Стар Меню група за инÑталирани програми" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Създай прÑк път на Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¸Ñ Ð¿Ð»Ð¾Ñ‚ за MTA:SA Клиента." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "РегиÑтрирайте mtasa:// протокол за по-леÑно Ñвързване към Ñайтове." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Добави към Windows Games Explorer (ако ÑъщеÑтвува)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "ИнÑталирай или обнови DirectX (ако има нужда)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "ОÑновните компоненти, необходими за Ñтартиране Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA: SA е модификациÑ, коÑто Ви позволÑва да играете онлайн." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto Ñървър. Това Ви позволÑва да поддържате Ñървър от Ð²Ð°ÑˆÐ¸Ñ ÐºÐ¾Ð¼Ð¿ÑŽÑ‚ÑŠÑ€. ИзиÑква Ñе бърз интернет." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto Ñървър. Това е задължителен компонент" #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA: SA Ð¼Ð¾Ð´Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð½Ð° Ñървъра." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Това е набор от необходимите реÑурÑи за Ð²Ð°ÑˆÐ¸Ñ Ñървър." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Това е допълнителен набор от видовете за игра и карти за Ð²Ð°ÑˆÐ¸Ñ Ñървър." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA: SA 1.0 Map Editor. Това може да Ñе използва за Ñъздадаване на ÑобÑтвени карти за различните режими на игра в МТÐ." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Това е SDK за Ñъздаване на двукомпонентни модули за Ñървър на МТÐ. ИнÑталирайте Ñамо ако имате добро разбиране на C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Разработен код и инÑтрументи, които помагат при направата на модове за Multi Theft Auto." #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Клиентът е пограмата, коÑто използвате за да играете в Multi Theft Auto Ñървър" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Клиент и Сървър" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Само Сървър" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Група в началното меню" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Икона на Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¸Ñ Ð¿Ð»Ð¾Ñ‚" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "РегиÑтрирай mtasa:// протокол" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Добави в Games Explorer" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "ИнÑталирай DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Игрален клиент" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "СобÑтвен Ñървър" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "ОÑновни компоненти" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Игрален модул" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "ИзпълÑнване на надграждане..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Ðктуализиране на разрешениÑ. Това може да отнеме нÑколко минути ..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Ðе е намерена валидна Windows верÑÐ¸Ñ Ð½Ð° Grand "МолÑ, преинÑталирайте ако ÑъщеÑтвуват проблеми в бъдеще." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "ОÑновни РеÑурÑи" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Допълнителни РеÑурÑи" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Редактор" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Разработка" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) беше уÑпешно премахнат от Ð²Ð°ÑˆÐ¸Ñ ÐºÐ¾Ð¼Ð¿ÑŽÑ‚ÑŠÑ€." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Грешка при деинÑталиране!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Сигурни ли Ñте, че иÑкате да премахнете $(^Name) и вÑички компоненти Ñвързани Ñ Ð½ÐµÐ³Ð¾?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "ДеинÑталиране преди актуализациÑ?$\\r$\n" "Стартирайте Ð½Ð¾Ð²Ð¸Ñ Ð¸Ð½Ñталатор за да обновите и запазите наÑтройките Ñи." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Бихте ли иÑкали да запазите вашите файлове Ñ Ð´Ð°Ð½Ð½Ð¸ (като реÑурÑи, екранни Ñнимки и Ñървъри)? Ðко щракнете не, вÑички реÑурÑи, конфигурации и Ñнимки, които Ñте Ñъздали ще бъдат премахнати." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Този инÑталатор изиÑква админиÑтраторÑки права, пробвайте пак." #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "ДеинÑталаторът изиÑква админиÑтраторÑки права, пробвайте пак." #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "ВпиÑващата уÑлуга не работи, прекратÑване!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Ðевъзможно издигане" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Друга верÑÐ¸Ñ Ð½Ð° MTA:SA ($1) вече ÑъщеÑтвува "ÐаиÑтина ли иÑкате да презапишете MTA $1 в $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA не може да бъде инÑталирана в Ñъщата "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Избраната Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ ÑъщеÑтвува.$\n" "ÐœÐ¾Ð»Ñ Ð¸Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ папката, коÑто Ñъдържа GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Проблем Ñ Ð½Ð°Ð¼Ð¸Ñ€Ð°Ð½ÐµÑ‚Ð¾ на GTA: SA инÑталиран "Сигурни ли Ñте че иÑкате да продължите?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Изберете мÑÑто за инÑталиране" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Изберете папката, в коÑто да инÑталирате ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} ще бъдат инÑтали "ÐатиÑнете Продължи за да продължите." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Целева Папка" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Преглед..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "По подразбиране" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "ПоÑледно използван/а" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "ПерÑонализиран" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Изберете папка, за инÑталиране на ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} в:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Внимание: Друга верÑÐ¸Ñ Ð½Ð° MTA ($1) вече ÑъщеÑтвува в тази папка." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Ðачин на инÑталациÑ: Ðадграждане" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Онлайн обновÑване" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Проверка на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° обновление" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Проверка на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð° инÑталера..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "МолÑ, проверете дали защитната Ñтена не блокира" diff --git a/Shared/installer/locale/bs_BA.pot b/Shared/installer/locale/bs_BA.pot index 80c1e45c1f1..a59c7ae7bee 100644 --- a/Shared/installer/locale/bs_BA.pot +++ b/Shared/installer/locale/bs_BA.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Bosnian\n" "Language: bs_BA\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Ovaj Äarobnjak će vas voditi kroz instalaciju ili ažuriranje programa "Kliknite Dalje za nastavak." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreas lokacija" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Molimo odaberite Grand Theft Auto:. San Andreas direktorij.$\n" "Kliknite na Instaliraj za poÄetak instaliranja." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Kreiraj Start Menu grupu za instalirane aplikacije" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Kreiraj preÄicu na radnoj povrÅ¡ini za MTA: SA klijenta" #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registracija mtasa :/ / protokol za preglednik kliknuti-ness" #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Dodaj u Windows Explorer igre (ako postoji)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "" #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Jezgra komponente potrebne za pokretanje Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "U MTA: SA modifikacija, Å¡to vam omogućava da igraju online." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto Server. To vam omogućuje da domaćin igre sa vaÅ¡eg raÄunala. To zahtijeva brzu internet vezu." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto poslužitelj. To je obavezan komponentu." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "U MTA: SA modifikacija za server." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Ovo je set potrebnih resursa za VaÅ¡ server." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Ovo je opcionalna skup gamemodes i karata za VaÅ¡ server." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "U MTA: SA 1.0 karta Editor. To se može koristiti za stvaranje vaÅ¡e vrlo vlastiti mape za koriÅ¡tenje u gamemodes za MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Ovo je SDK za stvaranje binarnog modula za MTA poslužitelja. Instalirajte samo ako imate dobro razumijevanje C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Razvojni kod i alata koji pomoć u stvaranju Mods za Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Klijent je program pokrenete u igri Multi Theft Auto server" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Klijenta i poslužitelja" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "server samo" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Start izbornik grupa" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "desktop ikone" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Registracija mtasa:// protokol" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Dodaj u Games Explorer" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "igra klijent" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "osnovne komponente" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Game modul" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Obavljanje in-place upgrade..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Ažuriranje dozvole. To bi moglo potrajati nekoliko minuta..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,74 +221,74 @@ msgstr "A važeći Windows verzija Grand Theft Auto: San Andreas nije otkrio.$\\ "Molimo Vas vratite ako postoje problemi kasnije." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Core Resursi" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Opcionalno Resursi" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "urednik" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "razvoj" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) je uspjeÅ¡no uklonjen sa vaÅ¡eg raÄunala." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Deinstalacije nije uspjela!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Jeste li sigurni da želite ukloniti potpuno $(^Name) i sve njegove komponente?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." msgstr "" #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Želite li zadržati svoje podatke (kao Å¡to su resursi, screenshot i konfiguracije poslužitelja)? Ako kliknete Ne, resurse, konfiguracije ili zaslona koje ste napravili bit će izgubljeni." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -296,7 +296,7 @@ msgid "A different major version of MTA ($1) already exists at that path.$\n" msgstr "" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -304,31 +304,31 @@ msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" msgstr "" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" msgstr "" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" msgstr "" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -336,62 +336,62 @@ msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the follow msgstr "" #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "" #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "" #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "" #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "" diff --git a/Shared/installer/locale/cs_CZ.pot b/Shared/installer/locale/cs_CZ.pot index cbce5ca8a64..e16a4696659 100644 --- a/Shared/installer/locale/cs_CZ.pot +++ b/Shared/installer/locale/cs_CZ.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Czech\n" "Language: cs_CZ\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Tento průvodce tÄ› provede instalací nebo aktualizací $(^Name) ${REVI "Klikni na Další pro pokraÄování." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "UmístÄ›ní Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas složka" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Prosím zvol tvou Grand Theft Auto: San Andreas složku.$\n" "Klikni na Instalovat pro zahájení instalace." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "VytvoÅ™it skupinu v Nabídce Start pro nainstalované aplikace" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "VytvoÅ™it zástupce na ploÅ¡e pro MTA:SA klient." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registrovat protokol mtasa:// pro prohlížeÄe." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "PÅ™idat do ProhlížeÄe her Windows (je-li k dispozici)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Nainstalovat nebo aktualizovat DirectX (pokud je potÅ™eba)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Jádrové komponenty potÅ™ebné pro chod Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA modifikace, umožňující ti hrát online." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto Server. Toto ti umožňuje hostovat hry z tvého poÄítaÄe. Je zapotÅ™ebí rychlé internetové pÅ™ipojení." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto server. Toto je potÅ™ebná souÄást." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA modifikace pro server." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Skupina potÅ™ebných resources pro tvůj server." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Toto je sada volitelných herních módů a map pro tvůj server." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 Map Editor. Může být použit pro vytvoÅ™ení tvých vlastních map pro herní módy v MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Toto je SDK pro vytváření binárních modulů pro MTA server. Instaluj pouze pokud máš dobrou znalost C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Vývojářský kód a nástroje které můžou pomoci pÅ™i vývoji módu pro Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Klient je program který spustíš pro hraní na Multi Theft Auto serveru" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Client a Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Pouze server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Start menu skupina" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Ikona na ploÅ¡e" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Zaregistrovat mtasa:// protokol" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "PÅ™idat do ProhlížeÄe her" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Nainstalovat DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Herní klient" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Dedikovaný server" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Jádrové komponenty" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Herní modul" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Provádím místní aktualizaci..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Aktualizuji oprávnÄ›ní. To může trvát pár minut..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Platná verze hry Grand Theft Auto: San Andreas nebyla nalezena.$\\r$\n" "PÅ™einstalujte MTA v případÄ› pozdÄ›jších problémů." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Hlavní Resources" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Volitelné Resources" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Editor map" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Vývoj" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) byl úspěšnÄ› smazán z tvého poÄítaÄe." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Odinstalace selhala!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Jsi si jist že chceÅ¡ kompletnÄ› smazat $(^Name) a vÅ¡echny jeho souÄásti?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Odinstalovat pÅ™ed aktualizací?$\\r$\n" "SpusÅ¥ nový instalátor pro aktualizaci a zachování nastavení." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "ChceÅ¡ ponechat tvoje osobní soubory (jako skripty, screenshoty a nastavení serveru)? Pokud klikneÅ¡ na ne, vÅ¡echny skripty, nastavení a screenshoty, které jsi vytvoÅ™il budou ztraceny." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Tento instalátor vyžaduje admin. oprávnÄ›ní, zkus to znovu" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Tento odinstalátor vyžaduje admin. oprávnÄ›ní, zkus to znovu" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "PÅ™ihlaÅ¡ovací služba neběží, ukonÄuji!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Nelze povýšit" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Jiná hlavní verze MTA ($1) již existuje v daném umístÄ›ní.$\n" "Jsi si jist že chceÅ¡ pÅ™epsat MTA $1 v $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA nemůže být nainstalováno do stejného adresáře, jako je GTA:SA "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Vybraný adresář neexistuje.$\n" "Prosím zvol adresář s hrou GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "NepodaÅ™ilo se najít GTA:SA v $GTA_DIR $\n" "Jsi si jistý, že chceÅ¡ pokraÄovat?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Vyber umístÄ›ní instalace" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Vyber složku do které chceÅ¡ nainstalovat ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} bude nainstalován v následuj "Klikni na Další pro pokraÄování." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Cílový adresář" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Procházet..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Výchozí" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Naposledy použité" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Vlastní" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Vyber složku pro instalaci ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Varování: Jiná hlavní verze MTA ($1) již existuje v daném adresáři." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Typ instalace: Upgrade" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Online aktualizace" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Zjišťuji informace o aktualizaci" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Kontroluji informace o aktualizacích instalátoru..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Prosím, ujisti se, že firewall nÄ›co neblokuje" diff --git a/Shared/installer/locale/da_DK.pot b/Shared/installer/locale/da_DK.pot index db3865a2a8f..8c471514626 100644 --- a/Shared/installer/locale/da_DK.pot +++ b/Shared/installer/locale/da_DK.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Danish\n" "Language: da_DK\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Denne guide vil vejlede dig gennem installationen eller opdateringen af "Tryk Næste for at forsætte." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreas placering" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas mappe" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Vælg din placering af Grand Theft Auto: San Andreas mappen.$\n" " Klik pÃ¥ Næste for at begynde installationen." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Lav en Start Menu gruppe for installerede programmer" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Lav en skrivebordsgenvej til MTA:SA klienten" #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registrer mtasa:// protokol for browser klikbart-ness." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Tilføj til Windows Spil (hvis fundet)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Installer eller opdater DirectX (hvis nødvendigt)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Kerne komponenterne nødvendige til at køre Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA modifikationen, der gør dig i stand til at spille online." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto Serveren. Dette tillader at hoste spil fra din egen computer. Det kræver en hurtig internet forbindelse." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto serveren. Dette er et nødvendigt komponent." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA modifikationen for serveren." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Dette er et sæt med nødvendige ressourcer til din server." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Dette er et sæt valgfrie spiltyper og maps til din server." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 Map editoren. Dette kan bruges til at lave dine helt egne maps til brug i spiltyper til MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Dette er SDK'en til at lave binære moduler til MTA serveren. Installer kun, hvis du har erfaring med C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Udviklingskode og værktøjer som støtter udviklingen af modifikationer i Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Klienten er programmet du kører, til at kunne spille pÃ¥ en Multi Theft Auto server" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Klient og Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Kun server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Start menu gruppe" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Skrivebords ikon" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Registrer mtasa:// protokol" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Tilføj til Games Explorer" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Installer DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Spil klient" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Dedikeret server" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Kerne komponenter" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Spil modul" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Udfører in-place opgradering..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Opdaterer tilladelser. Dette kan tage et par minutter..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "En understøttet Windows version af Grand Theft Auto: San Andreas blev i "Vær venlig at geninstallere hvis der er vedvarende problemer." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Kerne ressourcer" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Valgfrie ressourcer" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Redigeringsprogram" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Udvikling" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) Er blevet fjernet fra din computer." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Afinstallationen mislykkedes!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Er du sikker pÃ¥, at du fuldstændig vil fjerne $(^Name) og al dens data?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Afinstaller før opdatering?$\\r$\n" "Kør det nye installeringsprogram for at opgradere og bevare dine indstillinger." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Vil du beholde dine datafiler (sÃ¥som ressourcer, skærmbilleder og server konfiguration)? Hvis du klikker nej, vil alle ressourcer, konfigurationer og skærmbilleder du har lavet, være tabt." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Denne installering kræver administrator rettigheder, prøv igen " #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Denne afinstallation kræver administrator tilladelse, prøv igen" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Logon service kører ikke, afbryder!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Kunne ikke hæve" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "En anden stor version af MTA ($1) findes allerede pÃ¥ den sti.$\n" "Er du sikker pÃ¥, at du vil overskrive MTA $1 pÃ¥ $INSTDIR?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA kan ikke blive installeret inde i den samme mappe som GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Den valgte mappe findes ikke.$\n" "Vælg den mappe som indeholder GTA:SA installationen " #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Kunne ikke finde GTA:SA installationen pÃ¥ $GTA_DIR $\n" "Er du sikker pÃ¥ at du vil fortsætte?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Vælg installations placering" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Vælg mappen du vil installere ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} i" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} vil blive installeret in den f "Klik Næste for at fortsætte." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Destinationsmappe" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Gennemse..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Standard" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Sidst anvendt" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Brugerdefineret" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Vælg mappen til at installere ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} i:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Advarsel: En anden større version af MTA ($1) findes allerede pÃ¥ den sti." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Installations type: Opgrader" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Online opdatering" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Søger efter opdaterings information" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Søger efter installation opdaterings information..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Sørg venligst for at din firewall ikke blokerer" diff --git a/Shared/installer/locale/de_DE.pot b/Shared/installer/locale/de_DE.pot index 4e7f26bf243..37ab369d158 100644 --- a/Shared/installer/locale/de_DE.pot +++ b/Shared/installer/locale/de_DE.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: German\n" "Language: de_DE\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "Die runtergeladene Version von MTA:SA unterstützt kein Windows XP oder Vista. Bitte lade eine alternative Version von www.multitheftauto.com runter." #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "Die runtergeladene Version von MTA:SA unterstützt kein Windows 7, 8 oder 8.1. Bitte lade eine alternative Version von www.multitheftauto.com runter." #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "Die runtergeladene Version von MTA:SA ist für ältere Windows Versionen ausgelegt. Bitte lade eine alternative Version von www.multitheftauto.com runter." #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Dieser Assistent führt Sie durch die Installation oder Aktualisierung v "Klicken Sie auf Weiter, um fortzufahren." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Standort von Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Ordner Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,153 +67,153 @@ msgstr "Bitte wählen Sie Ihren Grand Theft Auto: San Andreas-Ordner.$\n" "Klicken Sie auf Installieren, um die Installation zu starten." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Erstellen einer Startmenü Gruppe für installierte Anwendungen" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Erstellen Sie eine Desktop-Verknüpfung für den MTA:SA-Client." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registrieren Sie das mtasa://-Protokoll für die Anklickbarkeit im Browser." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Zum Windows-Spiele-Explorer hinzufügen (falls vorhanden)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Installieren oder aktualisieren Sie DirectX (falls erforderlich)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Die Kernkomponenten, die zur Ausführung von Multi Theft Auto erforderlich sind." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "Die MTA:SA-Modifikation, die es Ihnen ermöglicht, online zu spielen." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Der Multi Theft Auto Server. Damit können Sie Spiele von Ihrem Computer aus hosten. Dies erfordert eine schnelle Internetverbindung." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Der Multi Theft Auto-Server, Dies ist eine erforderliche Komponente.\n" "Contextrequest." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "Die MTA:SA-Änderung für den Server." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Dies ist eine Reihe von erforderlichen Ressourcen für Ihren Server." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Dies ist ein optionaler Satz von Spielmodi und Karten für Ihren Server." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "Der MTA:SA 1.0 Karteneditor. Damit können Sie Ihre eigenen Karten für die Verwendung in Spielmodi für MTA erstellen." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Dies ist das SDK zur Erstellung von Binärmodulen für den MTA-Server. Installieren Sie es nur, wenn Sie über gute C++-Kenntnisse verfügen!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Entwicklungscode und Tools, die bei der Erstellung von Mods für Multi Theft Auto helfen" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Der Client ist das Programm, das Sie ausführen, um auf einem Multi Theft Auto-Server zu spielen" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Klient und Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Nur für Server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Startmenü-Gruppe" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Symbol für den Desktop" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Register mtasa:// Protokoll" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Zum Spiele-Explorer hinzufügen" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "DirectX installieren" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Spiel-Client" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Dedizierter-Server" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Kernbestandteile" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Spiel-Modul" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Durchführung von In-Place-Upgrades..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Aktualisierung der Berechtigungen. Dies kann ein paar Minuten dauern..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -222,42 +222,42 @@ msgstr "Eine gültige Windows-Version von Grand Theft Auto: San Andreas wurde ni "Bitte installieren Sie erneut, falls später Probleme auftreten." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Zentrale Ressourcen" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Optionale Ressourcen" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Editor" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Entwicklung" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) wurde erfolgreich von Ihrem Computer entfernt." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Die Deinstallation ist fehlgeschlagen!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Sind Sie sicher, dass Sie $(^Name) und alle seine Komponenten vollständig entfernen wollen?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -266,32 +266,32 @@ msgstr "Deinstallation vor dem Update?$\\r$\n" "Führen Sie das neue Installationsprogramm aus, um zu aktualisieren und Ihre Einstellungen beizubehalten." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Möchten Sie Ihre Datendateien (wie Ressourcen, Screenshots und Serverkonfiguration) behalten? Wenn Sie auf \"Nein\" klicken, gehen alle Ressourcen, Konfigurationen und Screenshots, die Sie erstellt haben, verloren." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Dieses Installationsprogramm benötigt Admin-Zugang, versuchen Sie es erneut" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Dieses Deinstallationsprogramm erfordert Administratorrechte, versuchen Sie es erneut" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Anmeldedienst läuft nicht, wird abgebrochen!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Unfähig zu heben" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -302,7 +302,7 @@ msgstr "Eine andere Hauptversion von MTA ($1) existiert bereits unter diesem Pfa " Sind Sie sicher, dass Sie MTA $1 unter $INSTDIR überschreiben wollen?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -313,7 +313,7 @@ msgstr "MTA kann nicht in dasselbe Verzeichnis wie GTA:SA.$ installiert werden.\ "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -322,7 +322,7 @@ msgstr "Das ausgewählte Verzeichnis existiert nicht. $\n" "Bitte wählen Sie das GTA:SA-Installationsverzeichnis" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -331,17 +331,17 @@ msgstr "GTA:SA konnte nicht unter $GTA_DIR installiert werden $\n" "Sind Sie sicher, dass Sie fortfahren möchten?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Installationsort wählen" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Wählen Sie den Ordner, in dem ${PRODUCT_NAME_NO_VER} installiert werden soll ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -352,62 +352,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} wird in dem folgenden Ordner i " Klicken Sie auf Weiter, um fortzufahren." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Zielordner" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Durchsuchen Sie..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Standard" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Zuletzt verwendet" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Benutzerdefiniert" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Wählen Sie den Ordner für die Installation von ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} installiert werden soll:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Warnung: Eine andere Hauptversion von MTA ($1) existiert bereits unter diesem Pfad." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Installationsart: Upgrade" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Online-Aktualisierung" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Prüfen auf Aktualisierungsinformationen" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Suche nach Informationen zur Aktualisierung des Installationsprogramms..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Bitte stellen sie sicher, dass Ihre Firewall nicht blockiert" diff --git a/Shared/installer/locale/el_GR.pot b/Shared/installer/locale/el_GR.pot index c3a9702c6a8..0a9934f19ca 100644 --- a/Shared/installer/locale/el_GR.pot +++ b/Shared/installer/locale/el_GR.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Greek\n" "Language: el_GR\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Αυτός ο οδηγός θα σας καθοδηγήσει μέσα "Κάντε κλικ στο Επόμενο για να συνεχίσετε." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreas τοποθεσία" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas φάκελος" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "ΠαÏακαλώ επιλέξτε τον φάκελο του Grand Theft "Πατήστε Εγκατάσταση για να αÏχίσετε την εγκατάσταση." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "ΔημιουÏγήστε μια ομάδα στο Î¼ÎµÎ½Î¿Ï Î­Î½Î±Ïξης για εγκατεστημένες εφαÏμογές" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "ΔημιουÏγήστε μια συντόμευση στην επιφάνεια εÏγασίας για το MTA:SA Ï€ÏόγÏαμμα-πελάτης." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "ΕγγÏαφή mtasa:// protocol για την ικανότητα κλικ του πεÏιηγητή." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "ΠÏοσθήκη στο Windows Games Explorer (Εάν υπάÏχει)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Εγκαταστήστε ή ενημεÏώστε το DirectX (αν απαιτείται)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Τα βασικά στοιχεία απαιτοÏνται για να Ï„Ïέξεις το Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "Το MTA:SA, σε αφήνει να παίζεις στο διαδίκτυο." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Ο διακομιστής του Multi Theft Auto. Αυτός σε αφήνει να διοÏγανώνεις παιχνίδια από τον υπολογιστή σου. Αυτό Ï€Ïοϋποθέτει μια γÏήγοÏη σÏνδεση στο διαδίκτυο." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Ο διακομιστής του Multi Theft Auto. Αυτό είναι ένα απαÏαίτητο στοιχείο." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "Η MTA:SA μετατÏοπή για τον διακομιστή." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Αυτή είναι μία ομάδα απαÏαίτητων βοηθημάτων για τον διακομιστή." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Αυτή είναι μία ομάδα Ï€ÏοαιÏετικών Ï„Ïπων παιχνιδιών και χαÏτών για τον διακομιστή." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "Ο MTA:SA 1.0 ΕπεξεÏγαστής ΧάÏτη. Αυτό μποÏεί να χÏησιμοποιηθεί για την δημιουÏγία δικών σου χαÏτών για την χÏήση τους σε Ï„Ïπους παιχνιδιών του MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Αυτό είναι το SDK (ΕÏγαλειοθήκη Ανάπτυξης ΛογισμικοÏ) για την δημιουÏγία δυαδικών δομοστοιχείων για το MTA server. Εγκαταστήστε μόνο εάν έχετε καλή κατανόηση της C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Ο κώδικας και τα εÏγαλεία ανάπτυξης που σε βοηθοÏν στη δημιουÏγία μετατÏοπών για το Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "To Ï€ÏόγÏαμμα-πελάτης είναι ένα Ï€ÏόγÏαμμα που Ï„Ïέχει έναν Multi Theft Auto διακομιστή" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "ΠÏόγÏαμμα-πελάτης και Διακομιστής" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Διακομιστής μόνο" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Ομάδα Î¼ÎµÎ½Î¿Ï Î­Î½Î±Ïξης" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "εικόνα Επιφάνειας εÏγασίας" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "ΕγγÏαφή mtasa:// protocol" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "ΠÏοσθήκη στο Games Explorer" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Εγκαταστήστε το DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "ΠÏόγÏαμμα-πελάτης παιχνιδιοÏ" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Αφοσιωμένος διακομιστής" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Βασικά στοιχεία" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Δομοστοιχεία παιχνιδιοÏ" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "αναβάθμιση επί τόπου" #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "ΕνημέÏωση αδειών. Αυτό μποÏεί να διαÏκέσει μεÏικά λεπτά..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Δεν βÏέθηκε έγκυÏη έκδοση των Windows του Gr "ΠαÏακαλώ επανεγκαταστήστε αν υπάÏξουν Ï€Ïοβλήματα αÏγότεÏα." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Βασικά βοηθήματα" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "ΠÏοαιÏετικά βοηθήματα" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "ΕπεξεÏγαστής" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Ανάπτυξη" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) επιτυχώς αφαιÏέθηκε από τον υπολογιστή σας." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Η απεγκατάσταση απέτυχε!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Είσαι σίγουÏος ότι θες να αφαιÏέσεις εντελώς $(^Name) και όλα τα στοιχεία του;" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Απεγκατάσταση Ï€Ïιν την ενημέÏωση;$\\r$\n" "ΤÏέξτε το νέο Ï€ÏόγÏαμμα εγκατάστασης για την αναβάθμιση και την διατήÏηση των Ïυθμίσεων σας." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Θα θέλατε να διατηÏήσετε όλα τα αÏχεία σας (όπως βοηθήματα, αÏχεία εικόνας στιγμιοτÏπων οθόνης και ÏÏθμιση παÏαμέτÏων διακοσμητή); Εάν κάνετε κλικ στο όχι, οποιοδήποτε βοήθημα, ÏÏθμιση ή αÏχείο στιγμιότυπου οθόνης που δημιουÏγήσατε θα χαθεί." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Αυτό το Ï€ÏόγÏαμμα εγκατάστασης απαιτεί άδεια διαχειÏιστή, Ï€Ïοσπαθήστε πάλι" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Αυτό το Ï€ÏόγÏαμμα απεγκατάστασης απαιτεί άδεια διαχειÏιστή, Ï€Ïοσπαθήστε πάλι" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Η ΕξυπηÏέτηση σÏνδεσης δεν Ï„Ïέχει, ματαίωση!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Δεν είναι δυνατή η ανÏψωση" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Μια διαφοÏετική σημαντική έκδοση του MTA "Είσαι σίγουÏος ότι θες να αντικαταστήσεις MTA $1 στο $INSTDIR ;" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "Το MTA δεν μποÏεί να εγκατασταθεί στον ίδ "$DEFAULT_INSTDIR ;" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Ο επιλεγμένος Ï€ÏοοÏισμός δεν υπάÏχει$\n" "ΠαÏακαλώ επιλέξτε το Ï€ÏοοÏισμό εγκατάστασης του GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Δεν είναι δυνατή η εÏÏεση του GTA:SA εγκατ "Είστε σίγουÏος ότι θέλετε να συνεχίσετε;" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Επιλέξτε τοποθεσία εγκατάστασης" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Επιλέξτε τον φάκελο στον οποίο θα γίνει εγκατάσταση ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} θα εγκατασταθεί " Πατήστε Επόμενο για να συνεχίσετε." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "ΠÏοοÏισμός φακέλου" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "ΠεÏιήγηση..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "ΠÏοεπιλογή" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Τελευταία χÏήση" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "ΠÏοτίμηση" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Επιλέξτε τον φάκελο εγκατάστασης ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} στο:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "ΠÏοειδοποιήση: Μια διαφοÏετική σημαντική έκδοση του MTA ($1) υπάÏχει ήδη σε αυτόν το Ï€ÏοοÏισμό." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "ΤÏπος εγκατάστασης: Αναβάθμιση" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "ΕνημέÏωση σε σÏνδεση" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Έλεγχος για πληÏοφοÏίες ενημέÏωσης" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Έλεγχος για πληÏοφοÏίες Ï€ÏογÏάμματος ενημέÏωσης..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "ΠαÏακαλώ εξασφαλίστε ότι το Ï€ÏόγÏαμμα Ï€Ïοστασίας σας δεν εμποδίζει" diff --git a/Shared/installer/locale/en_US.pot b/Shared/installer/locale/en_US.pot index 6185ee64707..32d331b1e60 100644 --- a/Shared/installer/locale/en_US.pot +++ b/Shared/installer/locale/en_US.pot @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: MTA San Andreas Installer 1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" +"POT-Creation-Date: 2026-02-23 01:17\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -13,21 +13,21 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "" -"The version of MTA:SA you've downloaded does not support Windows XP or " -"Vista. Please download an alternative version from www.multitheftauto.com." +"Multi Theft Auto does not support Windows XP or Vista. Please upgrade your " +"computer." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "" "The version of MTA:SA you've downloaded does not support Windows 7, 8 or " "8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "" "The version of MTA:SA you've downloaded is designed for old versions of " "Windows. Please download an alternative version from " @@ -35,7 +35,7 @@ msgid "" msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "" "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n" "\n" @@ -47,17 +47,17 @@ msgid "" msgstr "" #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "" "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" @@ -67,160 +67,160 @@ msgid "" msgstr "" #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "" #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "" #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "" #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "" #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "" #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "" #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "" "The Multi Theft Auto Server. This allows you to host games from your " "computer. This requires a fast internet connection." msgstr "" #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "" #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "" #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "" #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "" #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "" "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps " "for use in gamemodes for MTA." msgstr "" #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "" "This is the SDK for creating binary modules for the MTA server. Only install" " if you have a good understanding of C++!" msgstr "" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "" "Development code and tools that aid in the creation of mods for Multi Theft " "Auto" msgstr "" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:479 msgid "Client and Server" msgstr "" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:480 msgid "Server only" msgstr "" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:494 msgid "Start menu group" msgstr "" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:495 msgid "Desktop icon" msgstr "" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:496 msgid "Register mtasa:// protocol" msgstr "" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:497 msgid "Add to Games Explorer" msgstr "" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:498 msgid "Install DirectX" msgstr "" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:532 msgid "Game client" msgstr "" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:533 msgid "Dedicated server" msgstr "" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:534 msgid "Core components" msgstr "" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:535 msgid "Game module" msgstr "" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:537 msgid "Performing in-place upgrade..." msgstr "" #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:538 msgid "Updating permissions. This could take a few minutes..." msgstr "" #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:539 msgid "" "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\r" "$\n" @@ -230,44 +230,44 @@ msgid "" msgstr "" #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:542 msgid "Core Resources" msgstr "" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:543 msgid "Optional Resources" msgstr "" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:544 msgid "Editor" msgstr "" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1046 msgid "Development" msgstr "" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1094 msgid "$(^Name) was successfully removed from your computer." msgstr "" #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1101 msgid "Uninstallation has failed!" msgstr "" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1109 msgid "" "Are you sure you want to completely remove $(^Name) and all of its " "components?" msgstr "" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1110 msgid "" "Uninstalling before update?$\r" "$\n" @@ -277,7 +277,7 @@ msgid "" msgstr "" #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1123 msgid "" "Would you like to keep your data files (such as resources, screenshots and " "server configuration)? If you click no, any resources, configurations or " @@ -285,27 +285,27 @@ msgid "" msgstr "" #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1293 msgid "This installer requires admin access, try again" msgstr "" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1294 msgid "This uninstaller requires admin access, try again" msgstr "" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1295 msgid "Logon service not running, aborting!" msgstr "" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1296 msgid "Unable to elevate" msgstr "" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1892 msgid "" "A different major version of MTA ($1) already exists at that path.$\n" "$\n" @@ -314,7 +314,7 @@ msgid "" msgstr "" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1896 msgid "" "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" @@ -323,7 +323,7 @@ msgid "" msgstr "" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1899 msgid "" "The selected directory does not exist.$\n" "$\n" @@ -331,7 +331,7 @@ msgid "" msgstr "" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1901 msgid "" "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" @@ -339,19 +339,19 @@ msgid "" msgstr "" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2019 msgid "Choose Install Location" msgstr "" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2020 msgid "" "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} " "${PRODUCT_VERSION}" msgstr "" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2021 msgid "" "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" @@ -360,63 +360,63 @@ msgid "" msgstr "" #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2023 msgid "Destination Folder" msgstr "" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2024 msgid "Browse..." msgstr "" #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2025 msgid "Default" msgstr "" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2026 msgid "Last used" msgstr "" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2027 msgid "Custom" msgstr "" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2205 msgid "" "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2223 msgid "" "Warning: A different major version of MTA ($1) already exists at that path." msgstr "" #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2224 msgid "Installation type: Upgrade" msgstr "" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2458 msgid "Online update" msgstr "" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2459 msgid "Checking for update information" msgstr "" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2460 msgid "Checking for installer update information..." msgstr "" #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2461 msgid "Please ensure your firewall is not blocking" msgstr "" diff --git a/Shared/installer/locale/es_ES.pot b/Shared/installer/locale/es_ES.pot index 4fb6785abf9..9cd3dfa84c2 100644 --- a/Shared/installer/locale/es_ES.pot +++ b/Shared/installer/locale/es_ES.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Spanish\n" "Language: es_ES\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "La versión de MTA:SA que has descargado no soporta Windows XP o Vista. Por favor descargue una versión compatible/alterna desde www.multitheftauto.com." #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "La versión de MTA:SA que has descargado no soporta Windows 7, 8 ni 8.1. Por favor descargue una versión compatible/alterna desde www.multitheftauto.com." #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "La versión de MTA:SA que has descargado no soporta versiones antiguas de Windows. Por favor descargue una versión compatible/alterna desde www.multitheftauto.com." #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Este asistente te guiará durante la instalación o actualización de $( "Haga clic en Siguiente para continuar." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Ubicación de Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Carpeta de Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Por favor selecciona la carpeta donde está instalado Grand Theft Auto: "Haga clic en Instalar para iniciar el proceso de instalación." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Crear un grupo en el Menú Inicio para las aplicaciones instaladas" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Crear un Acceso Directo en el escritorio para el cliente de MTA:SA." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registrar el protocolo mtasa:// para el acceso a servidores vía hipervínculos. " #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Agregar a Windows Games Explorer (si está presente)" #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Instalar o actualizar DirectX (si es requerido)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Los componentes principales necesarios para ejecutar Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "La modificación MTA:SA, te permite jugar en-línea." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "El servidor de Multi Theft Auto. Te permite hospedar un servidor desde tu computadora. Requiere una buena conexión a internet." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "El servidor de Multi Theft Auto. Este es un componente requerido." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "La modificación de MTA:SA para el servidor." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Este es un conjunto de recursos necesarios para tu servidor." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Este es un conjunto opcional de modos de juego y mapas para tu servidor." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "El editor de mapas 1.0 de MTA:SA. Puede ser usado para crear tus propios mapas y posteriormente usarlos en modos de juego de MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Este es el SDK para la creación de módulos binarios para el servidor de MTA. ¡Instálalo sólo si tienes una buena comprensión de C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Código y herramientas de desarrollo que ayudan en la creación de modificaciones para Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "El cliente es el programa que ejecutas para jugar en un servidor de Multi Theft Auto" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Cliente y Servidor" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Solo servidor" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Grupo en el menú inicio" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Icono en el escritorio" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Registrar el protocolo mtasa://" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Agregar al Explorador de Juegos" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Instalar DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Cliente del juego" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Servidor dedicado" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Componentes principales" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Modulo del Juego" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Realizando actualización en la misma ubicación..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Actualizando permisos. Esto podría tardar un par de minutos..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "No se ha detectado una versión válida de Grand Theft Auto: San Andrea "Por favor reinstale la aplicación en caso de problemas más adelante." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Recursos Primarios" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Recursos opcionales" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Editor" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Desarrollo" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) fue removido satisfactoriamente de tu computadora." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "¡La desinstalación ha fallado!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "¿Estás seguro de que quieres remover $(^Name) y todos sus componentes?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "¿Desinstalando antes de actualizar?$\\r$\n" "Ejecute el nuevo instalador para actualizarlo y conservar su configuración." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "¿Le gustaría preservar sus archivos de datos (como los recursos, capturas de pantalla y la configuración del servidor)? Si hace clic en no, se perderán los recursos, configuraciones o capturas de pantalla que haya creado." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Este instalador necesita privilegios de administrador, inténtelo de nuevo." #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Este desinstalador necesita privilegios de administrador, inténtelo de nuevo." #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "¡El servicio de inicio de sesión no está en ejecución, abortando!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "No es posible elevar" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Una versión diferente y más reciente de MTA ($1) ya existe en ese dire " ¿Está seguro de que quiere sobrescribir MTA $1 en $INSTDIR?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA no puede ser instalado en el mismo directorio que GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "El directorio seleccionado no existe.$\n" "Por favor seleccione el directorio donde está instalado GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "No se pudo encontrar GTA:SA instalado en $GTA_DIR $\n" "¿Está seguro de continuar?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Seleccione la Ubicación de Instalación" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Seleccione la carpeta en la cual instalará ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} se instalará en la siguiente " Haga clic en Siguiente para continuar." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Carpeta de destino" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Examinar..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Predeterminado" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Usado por última vez" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Personalizado" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Seleccione la carpeta en la que instalará ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Advertencia: Una versión diferente y más reciente de MTA ($1) ya existe en esa ubicación." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Tipo de instalación: Actualización" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Actualización en línea" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Comprobando información de actualización" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Comprobando información de actualización del instalador..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Por favor asegúrate que tu cortafuegos no este bloqueando" diff --git a/Shared/installer/locale/et_EE.pot b/Shared/installer/locale/et_EE.pot index 3d4045b9de7..accc650a252 100644 --- a/Shared/installer/locale/et_EE.pot +++ b/Shared/installer/locale/et_EE.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Estonian\n" "Language: et_EE\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "See rakendus aitab sul läbida $(^Name) ${REVISION_TAG} paigaldamise v "Vajutage Edasi kui soovite jätkata" #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andrease asukoht" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andrease kaust" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Palun vali oma Grand Theft Auto: San Andrease kaust.$\n" "Vajuta Paigalda, et alustada paigaldamisega." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Tee Start Menüü grupp paigaldatud rakendustele" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Tee desktopi lühitee MTA:SA rakendusele." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registreeri mtasa:// protokoll brauserite jaoks." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Lisa Windowsi Mängude hulka (kui on olemas)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Paigalda või uuenda DirectX (Kui on nõutud)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Põhilised kompondendid, mida vaja Multi Theft Auto käivitamiseks." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "See on MTA:SA modifikatsioon, mis lubab sul mängida onlainis." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto server. See lubab sul luua enda mänguserverit. Nõuab internetiühendust." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto server. See on nõutud komponent." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA modifikatsioon serveri jaoks." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "See on kogum ressursse sinu mänguserveri jaoks." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "See on valikuline kogum mängutüüpe ja kaarte sinu mänguserveri jaoks." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 Kaardi Loomise Rakendus. See aitab sul luua sinu enda kaarte, mida saab kasutada mängutüüpides." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "See on SDK, et luua mooduleid MTA serverile. Paigaldada ainult kui oskad hästi C++ keelt!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Arendamise kood ja tööriistad, mis aitavad luua modifikatsioone Multi Theft Auto jaoks" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Klient on rakendus, millega saad mängida Multi Theft Auto serveris" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Klient ja Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Ainult server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Start menüü grupp" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Desktopi ikoon" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Registreeri mtasa:// protokoll" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Lisa Games Exploreri" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Paigalda DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Mängu klient" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Virtuaalserver" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Põhilised komponendid" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Mängu moodul" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Uuendan..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Uuendan õiguseid. See võib võtta paar minutit..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Nõutud Windowsi versiooni Grand Theft Auto: San Andreasest ei leitud.$\ "Palun paigaldage uuesti kui rakendusega on hiljem probleeme." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Põhilised ressursid" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Valikulised ressursid" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Redaktor" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Arendus" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) on edukalt teie arvutist eemaldatud." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Eemaldamine ebaõnnestus!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Kas oled kindel, et soovid eemaldada $(^Name) ja kõik selle komponendid?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Desinstallimine enne värskendamist?$\\r$\n" "Seadete uuendamiseks ja säilitamiseks käivitage uus installer." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Kas sooviksid jätta mõned failid nagu ressursid, pildid ja serveri seaded? Kui vajutate ei siis kõik ressursid, pildid ja serveri seaded kustutatakse ära." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Paigaldamine nõuab administraatori õiguseid, proovige uuesti" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Eemaldamis rakendus vajab administraatori õiguseid, proovige uuesti" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Sisselogimise teenus ei tööta, katkestan!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Ei suuda tõsta" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Erinev versioon MTA-st ($1) on juba paigaldatud valitud kausta.$\n" "Oled kindel, et tahad MTA $1 üle kirjutada asukohas $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA-d ei saa paigaldada samasse kausta, kus on GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Valitud kaust ei eksisteeri.$\n" "Palun vali GTA:SA paigaldamise kaust" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Ei suuda leida paigaldatud GTA:SA kaustast $GTA_DIR $\n" "Oled kindel, et tahad jätkata ?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Vali paigaldamise asukoht" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Vali kaust kuhu paigaldada ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} paigaldatakse järnevasse kaus "Vajuta Edasi et jätkata." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Soovitud kaust" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Sirvi..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Tavaline" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Viimati kasutatud" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Kohandatud" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Vali kaust kuhu installida ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Hoiatus: Muu versioon MTA-st ($1) on juba paigaldatud valitud kausta." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Paigaldamise tüüp: Uuendus" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Võrgu uuendus" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Kontrollib uuenduste informatsiooni" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Kontrollib uuenduste informatsiooni..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Ole kindel, et teie tulemüür ei blokeeri" diff --git a/Shared/installer/locale/fa_IR.pot b/Shared/installer/locale/fa_IR.pot index 2ffe8bd1d92..8354f11dc2b 100644 --- a/Shared/installer/locale/fa_IR.pot +++ b/Shared/installer/locale/fa_IR.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-06-28 16:21\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Persian\n" "Language: fa_IR\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "این نسخه از MTA:SA Ú©Ù‡ دانلود کرده اید از ویندوز XP یا Vista پشتیبانی نمی کند. Ù„Ø·ÙØ§ نسخه‌ای مناسب را از www.multitheftauto.com دانلود کنید." #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "این نسخه از MTA:SA Ú©Ù‡ دانلود کرده اید از ویندوز 7ØŒ 8 یا 8.1 پشتیبانی نمی‌کند. Ù„Ø·ÙØ§ نسخه‌ای مناسب را از www.multitheftauto.com دانلود کنید." #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "این نسخه از MTA:SA برای نسخه های قدیمی ویندوز طراحی شده است. Ù„Ø·ÙØ§ نسخه‌ای مناسب را از www.multitheftauto.com دانلود کنید." #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "این برنامه به شما برای نصب Ùˆ یا آپدیت $(^Na "برای ادامه روی \"ادامه\" کلیک کنید." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreas مکان نصب" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas پوشه" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Ù„Ø·ÙØ§Ù‹ پوشه Grand Theft Auto: San Andreas را انتخاب Ú©Ù† "برای شروع نصب روی \"نصب\" کلیک کنید." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Ø§ÙØ²ÙˆØ¯Ù† در Ùهرست استارت ویندوز برای Ù†Ø±Ù…â€ŒØ§ÙØ²Ø§Ø± هایی Ú©Ù‡ نصب می‌شوند" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "ایجاد کردن یک میانبر بر روی دسکتاپ برای MTA:SA Client." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "پروتکل mtasa:// را برای قابلیت کلیک مرورگر ثبت کنید." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "اضاÙÙ‡ کردن به Windows Games Explorer (در صورت وجود)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "نصب Ùˆ یا بروزرسانی DirectX (در صورت نیاز)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "برای اجرای Multi Theft Auto نیاز Core Components است." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "دستکاری های MTA:SAØŒ به شما امکان بازی آنلاین را Ù…ÛŒ دهد." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "سرور Multi Theft Auto. به شما این امکان را Ù…ÛŒ دهد تا با Ø§Ø³ØªÙØ§Ø¯Ù‡ از کامپیوتر خود میزبانی یک بازی را به عهده بگیرید. این ویژگی نیازمند داشتن اتصالی پر سرعت است." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto server. یک جزء ضروری است." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "برای دستکاری در MTA:SA سرور Ø§Ø³ØªÙØ§Ø¯Ù‡ میشود." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "این مجموعه ای از منابع مورد نیاز برای سرور شما است." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "این مجموعه اختیاری از حالت های بازی Ùˆ نقشه ها برای سرور شما است." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "ویرایشگر نقشه MTA:SA 1.0. این Ù…ÛŒ تواند برای ایجاد نقشه های خود برای Ø§Ø³ØªÙØ§Ø¯Ù‡ در حالت های بازی برای MTA Ø§Ø³ØªÙØ§Ø¯Ù‡ شود." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "این SDK برای ایجاد ماژول های باینری برای سرور MTA است. Ùقط در صورتی نصب کنید Ú©Ù‡ درک خوبی از C++ دارید!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "کد Ùˆ ابزار های توسعه ای Ú©Ù‡ به ایجاد حالت‌ها برای Multi Theft Auto Ú©Ù…Ú© می‌کنند" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Client برنامه ای است Ú©Ù‡ برای بازی کردن روی Multi Theft Auto server اجرا Ù…ÛŒ کنید" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "سرور Ùˆ کلاینت" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Ùقط سرور" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Ùهرست start ویندوز" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "میانبر دسکتاپ" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "ثبت پروتکل mtasa://‎" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "اضاÙÙ‡ شدن به Games Explorer" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "نصب DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "نسخه بازیکن" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "سرور اختصاصی" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "اجزای اصلی" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "ماژول بازی" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "انجام ارتقاء در محل..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "بروزرسانی دسترسی‌ها. ممکن است چند دقیقه طول بکشد..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "نسخه معتبری از Grand Theft Auto: San Andreas پیدا نشد "Ù„Ø·ÙØ§ اگر بعدا مشکلی بود دوباره نصب کنید." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "منابع اصلی" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "منابع اختیاری" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "ویرایشگر" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "توسعه" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "(Name^)$ با موÙقیت از کامپیوتر شما حذ٠شد." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "عملیات حذ٠نصب با شکست مواجه شد!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "آیا مطمئن هستید Ú©Ù‡ می‌خواهید (Name^)$ Ùˆ همه‌ی اجزای آن را پاک کنید؟" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "آیا میخواهید قبل از بروزرسانی حذ٠کنید؟ "نصب کننده نسخه جدید را برای ارتقا Ùˆ Ø­ÙØ¸ تنظیمات خود اجرا کنید." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "آیا Ù…ÛŒ خواهید ÙØ§ÛŒÙ„ های داده خود (مانند منابع، اسکرین شات ها Ùˆ پیکربندی سرور) را Ø­ÙØ¸ کنید؟ اگر روی نه کلیک کنید، هر منبع، پیکربندی یا اسکرین شات‌هایی Ú©Ù‡ ایجاد کرده‌اید از بین می‌رود." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "این نصب کننده به دسترسی admin نیاز دارد، دوباره امتحان کنید" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "این حذ٠نصب نیاز به دسترسی admin دارد، دوباره امتحان کنید" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "سرویس ورود به سیستم اجرا نشده است. عملیات لغو شد!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "قادر به بالا آوردن نیست" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "نسخه اصلی دیگری از MTA ($1) از قبل در آن مسی " آیا مطمئن هستید Ú©Ù‡ Ù…ÛŒ خواهید MTA $1 را در $INSTDIR بازنویسی کنید؟" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA را نمی توان در مسیر GTA:SA.$ نصب کرد\n" "$DEFAULT_INSTDIR ØŸ" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "مسیر انتخاب شده وجود ندارد.$\n" "Ù„Ø·ÙØ§Ù‹ مسیر نصب GTA:SA را انتخاب کنید" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "GTA:SA نصب شده در $GTA_DIR $ ÛŒØ§ÙØª نشد\n" "آیا مطمئن هستید Ú©Ù‡ میخواهید ادامه دهید ØŸ" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "محل نصب را انتخاب کنید" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "پوشه‌ای را انتخاب کنید Ú©Ù‡ در آن ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} نصب شود" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} در پوشه زیر نصب Ø® " برای ادامه بر روی بعدی کلیک کنید." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "پوشه مقصد" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "مسیر..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "پیش ÙØ±Ø¶" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "مسیر قبلی" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Ø³ÙØ§Ø±Ø´ÛŒ" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "پوشه را برای نصب ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} در اینجا انتخاب کنید:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "هشدار: یک نسخه اصلی دیگر از نسخه ($1) MTA در همان مسیر وجود دارد." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "نوع نصب: ارتقا" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "بروزرسانی آنلاین" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "بررسی اطلاعات بروزرسانی" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "در حال بررسی اطلاعات بروزرسانی نصب‌کننده..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Ù„Ø·ÙØ§ مطمئن شوید Ú©Ù‡ ÙØ§ÛŒØ±ÙˆØ§Ù„ شما مسدود نشده است" diff --git a/Shared/installer/locale/fi_FI.pot b/Shared/installer/locale/fi_FI.pot index 1ce2b1ed927..6a948ef69fe 100644 --- a/Shared/installer/locale/fi_FI.pot +++ b/Shared/installer/locale/fi_FI.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Finnish\n" "Language: fi_FI\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -43,17 +43,17 @@ msgstr "Tällä työkalulla asennat tai päivität $(^Name) ${REVISION_TAG}\n\n" "Paina Next kun olet valmis." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreasin sijainti" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreasin hakemisto" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -66,152 +66,152 @@ msgstr "Valitse Grand Theft Auto: San Andreas -hakemistosi.$\n" "Klikkaa Asenna aloittaaksesi asennuksen." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Luo asennetuille sovelluksille ryhmä Käynnistä-valikkoon" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Lisää MTA:SA-pikakuvake työpöydälle." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Rekisteröi mtasa://-protokolla selaimessa klikattavaksi." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Lisää Windowsin Peliselaimeen (mikäli saatavilla)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Asenna tai päivitä DirectX (jos vaaditaan)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Multi Theft Auton suorittamiseen vaaditut ydinkomponentit." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA-modi, mahdollistaa moninpelin pelaamisen." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto -palvelin. Tämä mahdollistaa pelien isännöinnin tietokoneeltasi. Vaatii nopean internet-yhteyden." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto -palvelin. Tämä on vaadittu komponentti." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA pelipalvelimen pelikomponentti." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Lista vaadituista resursseista palvelintasi varten." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Lista vaihtoehtoisista pelimuodoista ja kartoista palvelintasi varten." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 Karttaeditori. Voit käyttää tätä omien MTA karttojen luomiseen eri pelimuotoja varten." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Tämä SDK on hyödyllinen moduulien rakentamisessa MTA pelipalvelimeen. Asenna vain jos osaat C++:aa!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Modien kehitystyökalut" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Pelisovellusta käytetään pelaamiseen Multi Theft Auto pelipalvelimilla." #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Peli ja pelipalvelin" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Vain palvelin" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Valikkoryhmä" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Pikakuvake" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Rekisteröi mtasa:// protokolla" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Lisää Games Exploreriin" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Asenna DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Pelisovellus" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Dedikoitu palvelin" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Ydinkomponentit" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Pelimoduuli" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Päivitetään..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Päivitetään lupia. Tämä voi viedä muutaman minuutin..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -220,42 +220,42 @@ msgstr "Kelvollista Windows Grand Theft Auto: San Andreas versiota ei havaittu.$ "Jos havaitset ongelmia myöhemmin, asenna MTA uudelleen." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Ydinresurssit" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Valinnaiset resurssit" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Karttaeditori" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Kehitys" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) poistettiin onnistuneesti tietokoneeltasi." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Asennuksen poisto epäonnistui!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Haluatko varmasti poistaa $(^Name):n ja kaikki sen osat?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -264,32 +264,32 @@ msgstr "Oletko poistamassa MTA:n päivitystä varten?$\\r$\n" "Aja päivitysohjelmisto päivittääksesi ja säilyttääksesi asetuksesi." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Haluatko säilyttää datatiedostot, kuten resurssit, kuvakaappaukset ja palvelimen asetukset? Jos valitset ei, kaikki resurssit, asetukset ja kuvakaappaukset poistetaan lopullisesti." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Tämä asennustyökalu vaatii järjestelmänvalvojan oikeudet, ola hyvä ja kokeile uudelleen." #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Tämä poistotyökalu vaatii järjestelmänvalvojan oikeudet, ola hyvä ja kokeile uudelleen." #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Logon service not running, aborting!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Ei voitu ylentää" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -300,7 +300,7 @@ msgstr "Toinen MTA versio ($1) on jo asennettuna tähän hakemistoon.$\n" "Haluatko varmasti ylikirjoittaa MTA $1:n hakemistossa $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -311,7 +311,7 @@ msgstr "MTA:ta ei voida asentaa GTA:SA:n kanssa samaan hakemistoon.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -320,7 +320,7 @@ msgstr "Valittua hakemistoa ei ole olemassa.$\n" "Ole hyvä ja valitse GTA:SA:n asennushakemisto." #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -329,17 +329,17 @@ msgstr "GTA:SA:ta ei löytynyt hakemistosta $GTA_DIR $\n" "Haluatko varmasti jatkaa?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Valitse asennuspolku" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Valitse hakemisto johon ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} asennetaan" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -350,62 +350,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} asennetaan seuraavaan hakemist "Paina Next kun olet valmis." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Kohdekansio" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Selaa..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Oletus" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Viimeksi käytetty" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Mukautettu" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Valitse hakemisto johon ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} asennetaan:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Varoitus: MTA:n eri pääversio ($1) on jo olemassa kyseisellä polulla." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Asennustyyppi: Parannus" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Verkkopäivitys" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Tarkistetaan päivitystietoja" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Tarkistetaan asennusohjelman päivitystietoja..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Varmista ettei palomuurisi estä yhteyttä" diff --git a/Shared/installer/locale/fil_PH.pot b/Shared/installer/locale/fil_PH.pot index 408a68e21ae..2a0630a9f54 100644 --- a/Shared/installer/locale/fil_PH.pot +++ b/Shared/installer/locale/fil_PH.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Filipino\n" "Language: fil_PH\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Gagabayan ka ng wizard na ito sa pag-install o pag-update ng $(^Name) ${ "I-click ang Susunod upang magpatuloy." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreas lokasyon" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas folder" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Pakipili ang iyong folder ng Grand Theft Auto: San Andreas.$\n" "I-click ang I-install upang simulan ang pag-install." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Lumikha ng pangkat ng Start Menu para sa mga naka-install na application" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Gumawa ng Desktop Shortcut para sa MTA:SA Client." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Magrehistro ng mtasa:// protocol para sa pagiging clickable ng browser." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Idagdag sa Windows Games Explorer (kung mayroon)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "I-install o i-update ang DirectX (kung kinakailangan)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Ang mga pangunahing bahagi na kinakailangan upang patakbuhin ang Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "Ang pagbabago ng MTA:SA, na nagbibigay-daan sa iyong maglaro online." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Ang Multi Theft Auto Server. Binibigyang-daan ka nitong mag-host ng mga laro mula sa iyong computer. Nangangailangan ito ng mabilis na koneksyon sa internet." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Ang Multi Theft Auto server. Ito ay isang kinakailangang sangkap." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "Ang pagbabago ng MTA:SA para sa server." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Ito ay isang hanay ng mga kinakailangang mapagkukunan para sa iyong server." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Isa itong opsyonal na hanay ng mga gamemode at mapa para sa iyong server." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "Ang MTA:SA 1.0 Map Editor. Magagamit ito para gumawa ng sarili mong mga mapa para magamit sa mga gamemode para sa MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Ito ang SDK para sa paglikha ng mga binary module para sa MTA server. I-install lamang kung mayroon kang mahusay na pag-unawa sa C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Development code at mga tool na tumutulong sa paggawa ng mga mod para sa Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Ang kliyente ay ang program na pinapatakbo mo upang i-play sa isang Multi Theft Auto server" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Kliyente at Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Server lang" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Simulan ang pangkat ng menu" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Icon sa desktop" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Magrehistro ng mtasa:// protocol" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Idagdag sa Games Explorer" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "I-install ang DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Kliyente ng laro" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Nakalaang server" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Mga pangunahing bahagi" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Module ng laro" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Nagsasagawa ng in-place upgrade..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Nagsasagawa ng in-place upgrade..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Ang isang wastong bersyon ng Windows ng Grand Theft Auto: San Andreas ay "Mangyaring muling i-install kung may mga problema sa ibang pagkakataon." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Mga Pangunahing Mapagkukunan" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Opsyonal na Mga Mapagkukunan" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Editor" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Pag-unlad" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "Matagumpay na naalis si $(^Name) sa iyong computer." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Nabigo ang pag-uninstall!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Sigurado ka bang gusto mong ganap na alisin ang $(^Name) at lahat ng bahagi nito?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Ina-uninstall bago i-update?$\\r$\n" "Patakbuhin ang bagong installer upang mag-upgrade at mapanatili ang iyong mga setting." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Gusto mo bang panatilihin ang iyong mga file ng data (tulad ng mga mapagkukunan, mga screenshot at configuration ng server)? Kung iki-click mo ang hindi, mawawala ang anumang mga mapagkukunan, configuration o screenshot na iyong ginawa." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Ang installer na ito ay nangangailangan ng admin access, subukang muli" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Ang uninstaller na ito ay nangangailangan ng admin access, subukang muli" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Ang serbisyo ng pag-logon ay hindi tumatakbo, ibinabagsak!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Hindi maiangat" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Mayroon nang ibang pangunahing bersyon ng MTA ($1) sa landas na iyon.$\n " Sigurado ka bang gusto mong i-overwrite ang MTA $1 sa $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "Hindi ma-install ang MTA sa parehong direktoryo gaya ng GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Ang napiling direktoryo ay wala.$\n" "Mangyaring piliin ang direktoryo ng pag-install ng GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Hindi mahanap ang GTA:SA na naka-install sa $GTA_DIR $\n" "Sigurado ka bang gusto mong magpatuloy ?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Piliin ang I-install ang Lokasyon" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Piliin ang folder kung saan ii-install ang ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "Ang ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} ay mai-install sa sumusuno " I-click ang Susunod upang magpatuloy." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Destination Folder" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Mag-browse..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Huling ginamit" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Custom" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Piliin ang folder upang i-install ang ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} sa:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Babala: Mayroon nang ibang pangunahing bersyon ng MTA ($1) sa landas na iyon." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Uri ng pag-install: Mag-upgrade" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Online update" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Sinusuri ang impormasyon sa pag-update" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Sinusuri ang impormasyon sa pag-update ng installer..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Pakitiyak na hindi nakaharang ang iyong firewall" diff --git a/Shared/installer/locale/fr_FR.pot b/Shared/installer/locale/fr_FR.pot index a60b8c9b54f..b1f055a96ff 100644 --- a/Shared/installer/locale/fr_FR.pot +++ b/Shared/installer/locale/fr_FR.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: French\n" "Language: fr_FR\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "La version de MTA:SA que vous avez téléchargée n'est pas compatible avec Windows XP ou Windows Vista. Veuillez télécharger une version alternative sur www.multitheftauto.com." #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "La version de MTA:SA que vous avez téléchargée ne prend pas en charge Windows 7, 8 ou 8.1. Veuillez télécharger une version alternative sur www.multitheftauto.com." #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "La version de MTA:SA que vous avez téléchargée est conçue pour les anciennes versions de Windows. Veuillez télécharger une version alternative sur www.multitheftauto.com." #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Cet assistant vous guidera dans l'installation ou la mise à jour de $(^ "Cliquez sur Suivant pour continuer." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Emplacement de Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Dossier de Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Veuillez sélectionner le dossier de Grand Theft Auto: San Andreas.$\n" "Cliquez sur Installer pour commencer l'installation." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Créer un raccourci dans le menu Démarrer" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Créer un raccourci sur le Bureau pour le Client MTA:SA." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Enregistrer le protocole mtasa:// pour les navigateurs." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Ajouter à l'Explorateur de Jeux Windows (si disponible)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Installer ou mettre à jour DirectX (si nécessaire)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Les composants de base nécessaires pour lancer MTA:SA." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "La modification MTA:SA, vous permettant de jouer en ligne." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Le Serveur Multi Theft Auto. Pour héberger votre propre serveur depuis votre ordinateur. Nécessite une connexion internet rapide." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Le Serveur Multi Theft Auto. Ceci est un composant nécessaire." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "La modification MTA:SA pour le Serveur." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Il s'agit d'un ensemble de ressources nécessaires pour votre serveur." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Il s'agit d'un ensemble facultatif de gamemodes et maps pour votre serveur." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "L'Editeur de Map pour MTA:SA. Pour créer vos propres maps et les utiliser dans les gamemodes de MTA:SA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Il s'agit du SDK pour créer des modules binaires pour le Serveur MTA:SA. Installez uniquement si vous avez une bonne connaissance du C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Outils et code de développement facilitant la création de mods pour Multi Theft Auto." #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Le client est le programme que vous exécutez pour jouer sur un serveur MTA:SA" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Client et Serveur" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Serveur uniquement" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Raccourci dans le menu Démarrer" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Raccourci sur le Bureau" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Enregistrer le protocole mtasa://" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Ajouter à l'Explorateur de Jeux" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Installer DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Client" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Serveur dédié" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Composants de base" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Module du jeu" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Mise à niveau en cours..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Mise à jour des permissions. Ceci peut prendre quelques minutes..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Aucune version valide de Grand Theft Auto: San Andreas n'a été détect "Veuillez réinstaller si vous rencontrez des problèmes plus tard." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Ressources principales" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Ressources facultatives" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Editeur" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Développement" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) a été désinstallé de votre ordinateur." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "La désinstallation a échoué!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Êtes-vous sûr de vouloir supprimer complètement $(^Name) et tous ses composants?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Désinstaller avant la mise à jour?$\\r$\n" "Exécutez le nouveau programme d'installation pour mettre à niveau en conservant vos paramètres." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Voulez-vous conserver vos fichiers de données (tels que ressources, captures d'écran et configuration du serveur)? Si vous cliquez sur Non, ces fichiers seront perdus." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Cet installeur nécessite un accès administrateur, veuillez réessayer" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Ce désinstalleur nécessite un accès administrateur, veuillez réessayer" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Le service Logon n'est pas en cours d'exécution, annulation!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Impossible d'élever" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Une version différente de MTA ($1) existe déjà à cet emplacement.$\n "Êtes-vous sûr de vouloir remplacer MTA $1 à l'emplacement $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA ne peut pas être installé dans le même répertoire que GTA:SA.$\n "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "L'emplacement sélectionné n'existe pas.$\n" "Veuillez sélectionner le dossier d'installation de GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Impossible de trouver GTA:SA à l'emplacement $GTA_DIR $\n" "Êtes-vous sûr de vouloir continuer?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Choisissez l'emplacement de l'installation" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Choisissez le dossier dans lequel sera installé ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} sera installé à l'emplacemen "Cliquez sur Suivant pour continuer." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Dossier de destination" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Parcourir..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Par défaut" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Dernière utilisation" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Personnalisée" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Sélectionnez le dossier dans lequel sera installé ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} :" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Avertissement: Une version différente de MTA ($1) existe déjà à cet emplacement." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Type d'installation: Mise à niveau" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Mise à jour en ligne" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Vérification des informations de mise à jour" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Vérification des informations de mise à jour du programme d'installation..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Veuillez vous assurer que votre pare-feu ne bloque pas" diff --git a/Shared/installer/locale/he_IL.pot b/Shared/installer/locale/he_IL.pot index 86f39dd679c..60e7cd8593e 100644 --- a/Shared/installer/locale/he_IL.pot +++ b/Shared/installer/locale/he_IL.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Hebrew\n" "Language: he_IL\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "×”×שף ×™× ×—×” ×ותך ×ותך דרך ההתקנה ×ו העדכו "לחץ ×”×‘× ×¢×œ מנת להמשיך." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "×”×ž×™×§×•× ×©×œ Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "תיקיית Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -66,152 +66,152 @@ msgstr "×× × ×‘×—×¨ ×ת תיקיית ×”-Grand Theft Auto: San Andreas שלך. "לחץ התקן על מנת להתחיל בהתקנה." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "צור קיצור דרך בשולחן העבודה עבור MTA:SA." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "×¨×©×•× ×ת הפרוטוקול mtasa:// עבור גישה מהדפדפן." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "הוסף לסייר ×”×ž×©×—×§×™× ×©×œ Windows (×× ×§×™×™×)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "" #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "רכיבי ליבה ×”× ×—×•×¦×™× ×¢×œ מנת להריץ ×ת Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "" #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "שרת המשחק. מ×פשר לך ל×רח ×ž×©×—×§×™× ×ž×ž×—×©×‘×š ×”×ישי. דורש חיבור ×ינטרנט מהיר." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "" #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "" #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "זהו ×וסף של מש××‘×™× ×”× ×“×¨×©×™× ×¢×‘×•×¨ השרת שלך." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "זהו ×וסף ×ופציונלי של מצבי משחק ומפות עבור השרת שלך." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "עורך המפות של MTA:SA 1.0. יכול לשמש ליצירה של מפות משלך לשימוש במצבי משחק של MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "קוד פיתוח ×•×›×œ×™× ×©×ž×¡×™×™×¢×™× ×‘×¤×™×ª×•×— ×ž×•×“×™× ×œ-Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "שרת ייעודי" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "רכיבי ליבה" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "" #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "מעדכן הרש×ות. עלול לקחת מספר דקות..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -220,74 +220,74 @@ msgstr "גרסת Windows תקינה של Grand Theft Auto: San Andreas ×œ× ×–×• "×× × ×”×ª×§×Ÿ מחדש ×× ×¦×¦×•×ª בעיות בהמשך." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "מש×בי ליבה" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "מש××‘×™× ×ופציונליי×" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "" #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." msgstr "" #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "×”×× ×ª×¨×¦×” לשמור ×ת קבצי המידע שלך (מש×בי×, צילומי-מסך ותצורת שרת)? ×× ×ª×‘×—×¨ ל×, כל המש×בי×, תצורות וצילומי-מסך שיצרת ×™×בדו." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "×שף ההתקנה דורש גישת מנהל, ×× × × ×¡×” שנית" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -295,7 +295,7 @@ msgid "A different major version of MTA ($1) already exists at that path.$\n" msgstr "" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -303,31 +303,31 @@ msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" msgstr "" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" msgstr "" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" msgstr "" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -335,62 +335,62 @@ msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the follow msgstr "" #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "תיקיית היעד" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "עיין..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "ברירת מחדל" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "שימוש ×חרון" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "הת×מה ×ישית" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "" #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "" #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "" diff --git a/Shared/installer/locale/hi_IN.pot b/Shared/installer/locale/hi_IN.pot index 0fa9db404ca..2a6a89cd535 100644 --- a/Shared/installer/locale/hi_IN.pot +++ b/Shared/installer/locale/hi_IN.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Hindi\n" "Language: hi_IN\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -41,17 +41,17 @@ msgid "This wizard will guide you through the installation or update of $(^Name) msgstr "ya wizard apko install varna update me madat karaga/nsetup shuru karna sa phela baki sab applications ko kripaya band kar de jeya/n[vista aur usa upre ka liya administrator ka pauch zarure ha/naaga bad na ka leya kripaya next badaya" #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "गà¥à¤°à¥ˆà¤‚ड थेफà¥à¤Ÿ ऑटो: सैन à¤à¤‚डà¥à¤°à¤¿à¤¯à¤¾à¤¸ का फ़ोलà¥à¤¡à¤°" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas ka folder" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -64,152 +64,152 @@ msgstr "Kripya Grand Theft Auto: San Andreas folder ko chuniye.$\n" "Installation shuru karne ke liye Install dabaaiye." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "अपने गà¥à¤°à¥ˆà¤‚ड थेफà¥à¤Ÿ ऑटो का चयन करें:. सैन à¤à¤‚डà¥à¤°à¤¿à¤¯à¤¾à¤¸ फ़ोलà¥à¤¡à¤° $ \\ N$ \\ Nसैन à¤à¤‚डà¥à¤°à¤¿à¤¯à¤¾à¤¸ 1.0 à¤à¤®à¤Ÿà¥€à¤ का उपयोग करने के लिठसà¥à¤¥à¤¾à¤ªà¤¿à¤¤: आप गà¥à¤°à¤¾à¤‚ड थेफà¥à¤Ÿ ऑटो जरूरी à¤à¤¸à¤, यह किसी भी अनà¥à¤¯ संसà¥à¤•रणों का समरà¥à¤¥à¤¨ नहीं करता $ \\ à¤à¤¨.$ \\ Nसà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करने शà¥à¤°à¥‚ करने के लिठसà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करें कà¥à¤²à¤¿à¤• करें." #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "MTA:SA Client ka liya Desktop shortcut banana" #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "रजिसà¥à¤Ÿà¤° mtasa:// पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल फॉर बà¥à¤°à¤¾à¤‰à¥›à¤° कà¥à¤²à¤¿à¤•कबà¥à¤²à¥‡-नेस." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "windows Games Explorer ma add " #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "DirectX इंसà¥à¤Ÿà¥‰à¤² या अपडेट करें (यदि आवशà¥à¤¯à¤• हो)।" #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "core components ka jarurat ha multi theft auto ko chalayana ka liya" #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA modification apko online khalna ka leya" #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi theft auto server. Yaa apko game host apna computer sa karna dayta ha.Is ka leya fast internet connection ka jarurat ha." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi theft auto server.Ya required component ha." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA सरà¥à¤µà¤° के लिठमॉडिफिकेशन।" #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Ya required resource ka set haa jo server ka liya jarure ha" #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Yaa optional gamemods aur maps ka set ha server ka liya" #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 मैप à¤à¤¡à¤¿à¤Ÿà¤°à¥¤ इसका उपयोग MTA के लिठगेममोड में उपयोग के लिठअपने सà¥à¤µà¤¯à¤‚ के मैप बनाने के लिठकिया जा सकता है।" #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "यह à¤à¤®à¤Ÿà¥€à¤ सरà¥à¤µà¤° के लिठबाइनरी मॉडà¥à¤¯à¥‚ल बनाने के लिठSDK है। केवल तभी सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करें जब आपको C++ की अचà¥à¤›à¥€ समठहो!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "डेवलपमेंट कोड और उपकरण जो Multi Theft Auto के लिठमॉड के निरà¥à¤®à¤¾à¤£ में सहायता करते हैं" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "कà¥à¤²à¤¾à¤‡à¤‚ट वह पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® है जिसे आप Multi Theft Auto सरà¥à¤µà¤° पर चलाने के लिठचलाते हैं" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "कà¥à¤²à¤¾à¤‡à¤‚ट और सरà¥à¤µà¤°" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "केवल सरà¥à¤µà¤° के लिà¤" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "सà¥à¤Ÿà¤¾à¤°à¥à¤Ÿ मेनू गà¥à¤°à¥à¤ª" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "डेसà¥à¤•टॉप आइकन" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "रजिसà¥à¤Ÿà¤° mtasa:// पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "गेमà¥à¤¸ à¤à¤•à¥à¤¸à¤ªà¥à¤²à¥‹à¤°à¤° में जोड़ें" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "इंसà¥à¤Ÿà¥‰à¤² DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "गेम कà¥à¤²à¤¾à¤‡à¤‚ट" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "समरà¥à¤ªà¤¿à¤¤ सरà¥à¤µà¤°" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "कोर कंपोनेंटà¥à¤¸" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "गेम मॉडल" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "इन-पà¥à¤²à¥‡à¤¸ अपगà¥à¤°à¥‡à¤¡ किया जा रहा है..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "अनà¥à¤®à¤¤à¤¿à¤¯à¥‹à¤‚ को अदà¥à¤¯à¤¤à¤¨ कर रहा है। इसमें कà¥à¤› मिनट लग सकते हैं..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -218,42 +218,42 @@ msgstr "Grant Theft Auto: San Andreas का वैध विंडोज वर "यदि बाद में कोई समसà¥à¤¯à¤¾ आती है तो कृपया रीइंसà¥à¤Ÿà¥‰à¤² करें।" #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "मà¥à¤–à¥à¤¯ संसाधन" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "वैकलà¥à¤ªà¤¿à¤• संसाधन" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "संपादक" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "विकास" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) आपके कंपà¥à¤¯à¥‚टर से सफलतापूरà¥à¤µà¤• हटा दिया गया है।" #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "सà¥à¤¥à¤¾à¤ªà¤¨à¤¾ रदà¥à¤¦ करना विफल रहा!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "कà¥à¤¯à¤¾ आप वाकई $(^Name) और उसके सभी अवयव को पूरी तरह से हटाना चाहते हैं?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -262,32 +262,32 @@ msgstr "अपडेट से पहले अनइंसà¥à¤Ÿà¥‰à¤² कर "अपनी सेटिंगà¥à¤¸ को अपगà¥à¤°à¥‡à¤¡ और संरकà¥à¤·à¤¿à¤¤ करने के लिठनया इंसà¥à¤Ÿà¥‰à¤²à¤° चलाà¤à¤‚।" #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "कà¥à¤¯à¤¾ आप अपनी डेटा फ़ाइलें (जैसे संसाधन, सà¥à¤•à¥à¤°à¥€à¤¨à¤¶à¥‰à¤Ÿ और सरà¥à¤µà¤° कॉनà¥à¤«à¤¼à¤¿à¤—रेशन) रखना चाहेंगे? यदि आप नहीं कà¥à¤²à¤¿à¤• करते हैं, तो आपके दà¥à¤µà¤¾à¤°à¤¾ बनाया गया कोई भी संसाधन, कॉनà¥à¤«à¤¼à¤¿à¤—रेशन या सà¥à¤•à¥à¤°à¥€à¤¨à¤¶à¥‰à¤Ÿ खो जाà¤à¤—ा।" #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "इस इंसà¥à¤Ÿà¥‰à¤²à¤° को वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤• पहà¥à¤‚च की आवशà¥à¤¯à¤•ता है, पà¥à¤¨à¤ƒ पà¥à¤°à¤¯à¤¾à¤¸ करें" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "इस अनइंसà¥à¤Ÿà¤¾à¤²à¤° को à¤à¤¡à¤®à¤¿à¤¨ à¤à¤•à¥à¤¸à¥‡à¤¸ की आवशà¥à¤¯à¤•ता है, पà¥à¤¨à¤ƒ पà¥à¤°à¤¯à¤¾à¤¸ करें" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "लॉगऑन सेवा नहीं चल रही है, निरसà¥à¤¤ की जा रही है!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "उनाबले तो à¤à¤²à¥‡à¤µà¤¤à¥‡" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -298,7 +298,7 @@ msgstr "उस पथ पर MTA ($1) का à¤à¤• अलग पà¥à¤°à¤®à¥à¤– " कà¥à¤¯à¤¾ आप वाकई $INSTDIR पर MTA $1 को ओवरराइट करना चाहते हैं?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -309,7 +309,7 @@ msgstr "MTA को GTA:SA के समान निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा म "$DEFAULT_INSTDIR" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -318,7 +318,7 @@ msgstr "चयनित निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा मौजूद नही "कृपया GTA:SA इंसà¥à¤Ÿà¥‰à¤² निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा का चयन करें" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -327,17 +327,17 @@ msgstr "GTA:SA $GTA_DIR पर सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ नहीं पाया "कà¥à¤¯à¤¾ तà¥à¤® वाकई जारी रखना चाहते हो ?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "इनसà¥à¤Ÿà¥‰à¤² लोकेशन चà¥à¤¨à¥‡à¤‚" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} इनसà¥à¤Ÿà¥‰à¤² करने के लिठफ़ोलà¥à¤¡à¤° चà¥à¤¨à¥‡à¤‚" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -347,62 +347,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} निमà¥à¤¨à¤²à¤¿à¤–ित " जारी रखने के लिठआगे दबाà¤à¤à¥¤" #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "गंतवà¥à¤¯ फ़ोलà¥à¤¡à¤°" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "बà¥à¤°à¤¾à¤‰à¤œà¤¼ करें..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "डिफॉलà¥à¤Ÿ" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "आखिरी बार इसà¥à¤¤à¥‡à¤®à¤¾à¤²" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "कसà¥à¤Ÿà¤®" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करने के लिठफ़ोलà¥à¤¡à¤° का चयन करें:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "चेतावनी: उस जघा पर MTA ($1) का à¤à¤• अलग पà¥à¤°à¤®à¥à¤– संसà¥à¤•रण पहले से मौजूद है।" #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "इंसà¥à¤Ÿà¤¾à¤²à¥‡à¤¶à¤¨ टाइप: अपगà¥à¤°à¥‡à¤¡" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "ऑनलाइन अपडेट" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "चेकिंग फॉर अपडेट इनफारà¥à¤®à¥‡à¤¶à¤¨" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "चेकिंग फॉर इंसà¥à¤Ÿà¤¾à¤²à¤° अपडेट इनफारà¥à¤®à¥‡à¤¶à¤¨..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "कृपया सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ करें कि आपका फ़ायरवॉल अवरà¥à¤¦à¥à¤§ नहीं हो रहा है" diff --git a/Shared/installer/locale/hr_HR.pot b/Shared/installer/locale/hr_HR.pot index b159c8aa0ed..6ac7646a995 100644 --- a/Shared/installer/locale/hr_HR.pot +++ b/Shared/installer/locale/hr_HR.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Croatian\n" "Language: hr_HR\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "ÄŒarobnjak će Vas voditi kroz instalaciju ili ažuriranje $(^Name) ${RE "Pritisnite Dalje za nastavak." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Mjesto instalacije Grand Theft Auto: San Andreasa" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas datoteka" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Molimo izaberite direktorij gdje je Grand Theft Auto: San Andreas instal "Pritisnite Instaliraj da zapoÄnete instalaciju." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Stvori Start Menu grupu za instalirane aplikacije" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Stvori Desktop preÄac za MTA:SA klijent." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registriraj mtasa:// protokol za selekciju pretraživaÄa." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Dodaj u Windows Games Explorer (ako prisutno)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Instalirajte ili ažurirajte DirectX (ako je potrebno)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Osnovne komponente potrebne za pokretanje Multi Theft Auto-a." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA modifikacija, omogućava vam igranje na mreži." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto Server. Omogućava Vam da budete domaćin igara sa vlastitog raÄunala. Zahtijeva brzu internet povezanost." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto server. Potrebna komponenta." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA modifikacija za server." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Ovo je set potrebnih resursa za VaÅ¡ server." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Ovo je neobavezan set igara i mapa za tvoj server." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 UreÄ‘ivaÄ Mapa. Ovo može biti korisno za izradu vlastitih mapa za koriÅ¡tenje u MTA serverima." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Ovo je SDK za izradu binarnih modula za MTA server. Instalacija istog podrazumijeva dobro razumijevanje C++ programskog jezika!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Razvojni kod i alati koji pomažu u izradi modova za Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Ovaj program se koristi za mogućnost igranja na Multi Theft Auto serveru" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Klijent i Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Samo server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Grupa poÄetnog izbornika" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Ikona radne povrÅ¡ine" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Registriraj mtasa:// protokol" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Dodaj u Games Explorer" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Instalirajte DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Klijent za igranje" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Samostalni server" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Osnovne komponente" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Modul igre" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "IzvrÅ¡avanje ažuriranja..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "NadograÄ‘ivanje dozvola. Ovo bih moglo potrajati par minuta..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Važeća Windows verzija Grand Theft Auto: San Andreas-a nije pronaÄ‘ena "Molimo instalirajte ponovno ako bude ikakvih problema kasnije." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Osnovni resursi" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Dodatni Resursi" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "UreÄ‘ivaÄ" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Razvoj" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) uspjeÅ¡no je uklonjen s raÄunala." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Deinstalacija nije uspjela!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Jeste li sigurni da želite u potpunosti ukloniti $(^Name) i sve njegove komponente?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "De-instalacija prije ažuriranja?$\\r$\n" "Pokrenite novi installer da biste ažurirali i saÄuvali svoje postavke." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Želite li ostaviti podatke (kao Å¡to su skripte, fotografije i server konfiguracija)? Ako ne, sve skripte, konfiguracije ili fotografije bit će uklonjene." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Ova instalacija zahtijeva pristup administratora, pokuÅ¡ajte ponovno" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Ova deinstalacija zahtijeva pristup administratora, pokuÅ¡ajte ponovno" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Usluga prijave nije pokrenuta, prekidanje!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Ne mogu podići" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Druga verzija MTA ($1) već je instalirana u tome direktoriju.$\n" "Jeste li sigurni da želite instalirati preko stare verzije MTA $1 u $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA ne može biti instaliran u isti direktorij kao i GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Izabran direktorij ne postoji.$\n" "Molimo odaberite GTA:SA instalacijski direktorij" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Nije moguće pronaći GTA:SA instaliran u $GTA_DIR $\n" "Jeste li sigurni da želite nastaviti?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Izaberi Instalacijsku Lokaciju" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Izaberi mapu u koju ćeÅ¡ instalirati ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} će biti instaliran u sljedeć "Pritisnite Dalje za nastavak." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "OdrediÅ¡ni Direktorij" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Pretraži…" #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "UobiÄajeno" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Zadnje koriÅ¡teno" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "PrilagoÄ‘eno" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Izaberite direktorij za instalaciju ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} :" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Upozorenje: DrugaÄija glavna verzija MTA ($1) već postoji na tom mjestu." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Tip instalacije: Nadogradnja" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Online nadogradnja" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Provjeravanje zakrpa" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Provjeravanje zakrpa za instalaciju" #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Provjerite da vatrozid ne blokira" diff --git a/Shared/installer/locale/hu_HU.pot b/Shared/installer/locale/hu_HU.pot index 7093aae88c5..901432f19a9 100644 --- a/Shared/installer/locale/hu_HU.pot +++ b/Shared/installer/locale/hu_HU.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-19 01:08\n" +"PO-Revision-Date: 2026-01-19 09:49\n" "Last-Translator: \n" "Language-Team: Hungarian\n" "Language: hu_HU\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 -msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." -msgstr "" +#: Shared/installer/nightly.nsi:206 +msgid "Multi Theft Auto does not support Windows XP or Vista. Please upgrade your computer." +msgstr "A Multi Theft Auto nem fut Windows XP-n és Windows Vistán. Kérjük, frissíts modernebb operációs rendszerre." #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "A letöltött MTA:SA verzió nem támogatja a Windows 7, 8 vagy 8.1 rendszereket. Kérjük, tölts le egy alternatív verziót a www.multitheftauto.com oldalról." #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "A letöltött MTA:SA verzió régi Windows-verziókhoz készült. Kérjük, tölts le egy alternatív verziót a www.multitheftauto.com oldalról." #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "A telepítÅ‘ segítségedre lesz a $(^Name) ${REVISION_TAG} telepítés "Kattints a Tovább gombra a folytatáshoz." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreas útvonala" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas mappája" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Válaszd ki a Grand Theft Auto: San Andreas mappáját.$\n" "Kattins a Telepítés gombra a telepítési folyamat megkezdéséhez." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Start menü csoport létrehozása a telepített alkalmazásoknak" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Parancsikon létrehozása az asztalon." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "mtasa:// protokoll hozzáadása a böngészÅ‘dhöz." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Hozzáadás a Windows-Játékokhoz (amennyiben elérhetÅ‘)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Telepítse, vagy frissítse a DirectX-et (amennyiben szükséges)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Az alapvetÅ‘ komponensek szükségesek a Multi Theft Auto futtatásához." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "Az MTA:SA módosításai lehetÅ‘vé teszik az online játékot." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Az MTA: SA Szerver lehetÅ‘vé teszi, hogy szervert indíts a saját gépedrÅ‘l. Ehhez gyors internetkapcsolat szükséges." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "A Multi Theft Auto Szerver. Ez egy nélkülözhetetlen komponens." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "Az MTA:SA Szerver módosításai." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Szükséges erÅ‘források a szerveredhez." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Opcionális erÅ‘források a szerveredhez." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "PályaszerkesztÅ‘ a szerveredhez. Ezzel elkészítheted a saját pályáidat, amelyeket felhasználhatsz az MTA:SA játékmódjaiban." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Egy szoftverfejlesztÅ‘i csomag, amely segítségével létrehozhatsz komponenseket a Multi Theft Auto Szerverhez. Telepítése csak abban az esetben javasolt, ha rendelkezel tapasztalattal a C++ programozási nyelv terén." #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Egy fejlesztÅ‘i kód- és eszközcsomag a mod-ok létrehozásához és szerkesztéséhez." #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "A kliens, amely segítségével csatlakozhatsz és játszhatsz a Multi Theft Auto szervereken." #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:479 msgid "Client and Server" msgstr "Kliens és Szerver" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:480 msgid "Server only" msgstr "Csak szerver" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:494 msgid "Start menu group" msgstr "Start menü csoport" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:495 msgid "Desktop icon" msgstr "Parancsikon az asztalon" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:496 msgid "Register mtasa:// protocol" msgstr "mtasa:// protokoll regisztráció" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:497 msgid "Add to Games Explorer" msgstr "Hozzáadás a Windows-Játékokhoz" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:498 msgid "Install DirectX" msgstr "DirectX telepítése" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:532 msgid "Game client" msgstr "Kliens" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:533 msgid "Dedicated server" msgstr "Dedikált szerver" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:534 msgid "Core components" msgstr "AlapvetÅ‘ komponensek" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:535 msgid "Game module" msgstr "Játék modul" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:537 msgid "Performing in-place upgrade..." msgstr "Helyi frissítés végrehajtása..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:538 msgid "Updating permissions. This could take a few minutes..." msgstr "Engedélyek frissítése. Ez eltarthat néhány percig..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:539 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Az eredeti Grand Theft Auto: San Andreas nem található.$\\r$\n" "Telepítsd újra, ha a késÅ‘bbiekben probléma merül fel." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:542 msgid "Core Resources" msgstr "AlapvetÅ‘ erÅ‘források" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:543 msgid "Optional Resources" msgstr "Opcionális erÅ‘források" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:544 msgid "Editor" msgstr "SzerkesztÅ‘" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1033 msgid "Development" msgstr "Fejlesztés" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1081 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) sikeresen el lett távolítva a számítógépedrÅ‘l." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1088 msgid "Uninstallation has failed!" msgstr "Sikertelen eltávolítás!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1096 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Biztosan el szeretnéd távolítani az $(^Name)-t és az összes komponensét?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1097 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Frissítés elÅ‘tt távolítanád el?$\\r$\n" "Futtasd az új telepítÅ‘t, így megmaradnak a beállításaid." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1110 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Szeretnéd megtartani az adataidat? (mint például erÅ‘források, képernyÅ‘képek és szerver konfiguráció)? Ha a Nem lehetÅ‘séget választod, minden erÅ‘forrás, beállítás és képernyÅ‘kép el fog veszni." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1300 msgid "This installer requires admin access, try again" msgstr "A telepítéshez rendszergazdai jogosultság szükséges, próbáld újra." #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1301 msgid "This uninstaller requires admin access, try again" msgstr "Az eltávolításhoz rendszergazdai jogosultság szükséges, próbáld újra." #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1302 msgid "Logon service not running, aborting!" msgstr "A bejelentkezési szolgáltatás nem fut, megszakítás!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1303 msgid "Unable to elevate" msgstr "A művelet elvégzéséhez magasabb jogosultsági szint szükséges." #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1899 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "A Multi Theft Auto $1-nek egy másik verziója már létezik a megadott "Biztosan felül szeretnéd írni a Multi Theft Auto $1-et a $INSTDIR útvonalon?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1903 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "A Multi Theft Auto-t nem lehet ugyanabban a mappában telepíteni, mint "$DEFAULT_INSTDIR" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1906 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "A kiválasztott mappa nem létezik.$\n" "Kérlek válaszd ki a GTA:SA elérési útvonalát." #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1908 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "A kiválasztott elérési útvonalon ($GTA_DIR) nem található a GTA:SA "Biztosan szeretnéd folytatni?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2026 msgid "Choose Install Location" msgstr "Válaszd ki a telepítés helyét" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2027 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Válaszd ki a mappát, ahova telepíteni szeretnéd a ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}-t" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2028 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "A ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} ezen mappában lesz telepít "Kattints a Tovább gombra a folytatáshoz." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2030 msgid "Destination Folder" msgstr "Célmappa" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2031 msgid "Browse..." msgstr "Tallózás..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2032 msgid "Default" msgstr "Alapértelmezett" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2033 msgid "Last used" msgstr "Utoljára használt" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2034 msgid "Custom" msgstr "Egyéni" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2212 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Válaszd ki a mappát, ahova telepíteni szeretnéd a ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}-t:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2230 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Figyelmeztetés: A Multi Theft Auto ($1) egy másik verziója már létezik ezen az elérési útvonalon." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2231 msgid "Installation type: Upgrade" msgstr "Telepítés típusa: Frissítés" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2465 msgid "Online update" msgstr "Online frissítés" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2466 msgid "Checking for update information" msgstr "Frissítési információk ellenÅ‘rzése" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2467 msgid "Checking for installer update information..." msgstr "TelepítÅ‘ frissítési információk ellenÅ‘rzése..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2468 msgid "Please ensure your firewall is not blocking" msgstr "Biztosítsd, hogy a tűzfal nem blokkolja a letöltést." diff --git a/Shared/installer/locale/id_ID.pot b/Shared/installer/locale/id_ID.pot index a67b492c16c..a18f5f9dc96 100644 --- a/Shared/installer/locale/id_ID.pot +++ b/Shared/installer/locale/id_ID.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Indonesian\n" "Language: id_ID\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Wizard ini akan memandu Anda melalui instalasi atau update $(^Name) ${RE "Klik Selanjutnya untuk melanjutkan." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Lokasi Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Folder Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Silahkan pilih folder Grand Theft Auto: San Andreas anda.$\n" "Klik Pasang untuk memulai pemasangan." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Buat grup Start Menu untuk aplikasi yang terpasang" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Buat Pintasan Desktop untuk Klien MTA:SA." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Daftar protokol mtasa:// agar dapat di-klik di browser." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Tambahkan ke Windows Games Explorer (jika tersedia)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Pasang atau perbarui DirectX (jika diperlukan)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Komponen inti diperlukan untuk menjalankan Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "Modifikasi MTA:SA, memungkinkan anda untuk bermain secara daring." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Server Multi Theft Auto. Hal ini memungkinkan anda untuk mengelola permainan dari komputer anda. Hal ini memerlukan koneksi internet yang cepat." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Server Multi Theft Auto. Ini adalah komponen yang diperlukan." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "Modifikasi MTA:SA untuk server." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Ini adalah satu set sumber daya yang diperlukan untuk server anda." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Ini adalah satu set opsional dari mode game dan peta untuk server anda." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "Penyunting Peta MTA:SA 1.0. Ini bisa digunakan untuk membuat peta anda sendiri untuk digunakan di mode permainan untuk MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Ini adalah SDK untuk membuat modul biner untuk server MTA. Hanya pasang apabila anda mempunyai pemahaman yang baik tentang C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Kode dan alat-alat pengembangan yang membantu dalam penciptaan mod untuk Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Klien adalah program yang anda jalankan untuk bermain di server Multi Theft Auto" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Klien dan Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Hanya server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Grup start menu" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Ikon desktop" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Daftarkan protokol mtasa://" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Tambahkan ke Games Explorer" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Pasang DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Klien permainan" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Server terdedikasi" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Komponen inti" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Modul permainan" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Menjalankan peningkatan di tempat..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Memperbarui izin. Ini dapat memakan beberapa menit..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Versi Windows yang valid dari Grand Theft Auto: San Andreas tidak terdet "Silakan pasang ulang apabila ada masalah nantinya." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Sumber Inti" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Sumber Opsional" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Penyunting" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Pengembangan" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) telah berhasil dihapus dari komputer anda." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Penghapusan telah gagal!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Apakah anda yakin untuk menghapus $(^Name) secara lengkap dan semua komponennya?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Menghapus sebelum update?$\\r$\n" "Jalankan pemasang baru untuk meningkatkan dan mempertahankan pengaturan anda." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Apakah anda ingin menyimpan data (seperti sumber, tangkapan layar, dan konfigurasi server)? Jika anda klik tidak, semua sumber, konfigurasi, atau tangkapan layar yang telah anda buat akan hilang." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Pemasang ini membutuhkan akses admin, coba lagi" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Penghapus ini membutuhkan akses admin, coba lagi" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Layanan masuk tidak berjalan, batalkan!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Tidak dapat meningkatkan" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Sebuah versi utama dari MTA ($1) sudah ada pada direktori itu.$\n" " Apakah anda yakin ingin menimpa MTA $1 dengan $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA tidak dapat dipasang ke dalam direktori yang sama dengan GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Direktori yang dipilih tidak ada.$\n" "Silakan pilih direktori pemasangan GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Tidak dapat menemukan GTA:SA terpasang di $GTA_DIR $\n" "Apakah anda yakin ingin melanjutkan ?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Pilih Lokasi Pemasangan" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Pilih folder yang akan dipasangkan ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} akan dipasang di folder beriku " Klik Selanjutnya untuk melanjutkan." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Folder Tujuan" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Telusuri..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Bawaan" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Terakhir digunakan" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Khusus" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Pilih folder untuk memasang ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} di:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Peringatan: Sebuah versi utama yang berbeda dari MTA ($1) sudah ada di direktori tersebut." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Jenis Pemasangan: Meningkatkan" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Pemutakhir daring" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Sedang memeriksa informasi pembaruan" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Sedang memeriksa pemasang informasi pembaruan..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Pastikan firewall anda tidak memblokir" diff --git a/Shared/installer/locale/it_IT.pot b/Shared/installer/locale/it_IT.pot index c0f7be95c75..88f8e23cebf 100644 --- a/Shared/installer/locale/it_IT.pot +++ b/Shared/installer/locale/it_IT.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Italian\n" "Language: it_IT\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Questo wizard ti guiderà attraverso l'installazione o l'aggiornamento d "Clicca su avanti per continuare." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Location di Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Folder di Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Per favore seleziona la cartella principale di Grand Theft Auto: San And "Clicca su installa per iniziare l'installazione." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Crea un menu di gruppo di Start per le applicazioni installate" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Crea un collegamento sul Desktop per MTA:SA Client" #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registra il protocollo mtasa:// per un ness clickabile del browser." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Aggiungi a Windows Game Explorer (se presente)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Installa o aggiorna DirectX (se necessario)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "I componenti principali richiesti per utilizzare Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "Le opzioni di MTA:SA, permettendoti di giocare online." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Il server di Multi Theft Auto. Questo componente permette di ospitare le partite dal proprio computer. Questo componente richiede una connessione ad internet veloce." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Il server di Multi Theft Auto. Questo è un componente obbligatorio." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "Le opzioni di MTA:SA per il server." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Questo è un insieme di risorse richieste per il tuo server." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Questo è un set opzionale di modalità e mappe per il tuo server." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "L'editor di mappe di MTA:SA 1.0. Può essere usato per creare le proprie mappe da utilizzare nelle modalità di MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Questo è l'SDK per creare moduli binari per il server di MTA. Installazione consigliata a chi possiede una buona conoscenza del C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Codici di sviluppo e strumenti che aiutano nella creazione di mods per Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Il client è il programma da utilizzare per giocare su un server di Multi Theft Auto" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Client e Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Solo server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Gruppo di menu Start" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Icona del Desktop" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Registra il protocollo mtasa://" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Aggiungi a Games Explorer" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Installa DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Client di gioco" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Server dedicato" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Componenti principali" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Modulo di gioco" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Esecuzione sul posto di un aggiornamento..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Aggiornamento delle autorizzazioni. Questo potrebbe richiedere qualche minuto..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Una versione di Windows valida di Grand Theft Auto: San Andreas non è s "In caso di problemi è consigliato ripetere l'installazione." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Risorse principali" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Risorse opzionali " #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Editor" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Sviluppo " #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) è stato rimosso con successo dal tuo computer." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "La disinstallazione è fallita!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Sei sicuro di voler rimuovere completamente $(^Name) e tutti i suoi componenti?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Disinstallare prima dell'aggiornamento?$\\r$\n" "Esegui il nuovo programma di installazione per mantenere le tue impostazioni." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Vuoi mantenere tutti i tuoi file dati (come risorse, screenshot e configurazioni del server)? Se clicchi no, qualsiasi risorsa, configurazione o screenshot creato sarà perso." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Questo programma d'installazione richiede l'accesso come amministratore, prova di nuovo" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Questo programma di disinstallazione richiede l'accesso come amministratore, prova di nuovo" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Servizio di Logon non funzionante, interruzione!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Impossibile elevare " #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Una versione maggiore differente di MTA ($1) esiste già in quel percors "Sei sicuro di voler sovrascrivere MTA $1 in $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -311,7 +311,7 @@ msgstr "MTA non può essere installato nella stessa cartella di GTA:SA.\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -320,7 +320,7 @@ msgstr "La directory selezionata non esiste$\n" "Per favore seleziona la directory di installazione di GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -329,17 +329,17 @@ msgstr "Impossibile trovare GTA:SA installato in$GTA_DIR $\n" "Sei sicuro di voler continuare?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Scegliere la location di installazione" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Scegliere la cartella di installazione per ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -350,62 +350,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} verrà installato nella seguen "Clicca su Avanti per continuare." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Cartella di destinazione" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Sfoglia..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Predefinito" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Ultimo utilizzo" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Personalizzato" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Scegli la cartella di installazione per ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Attenzione: una versione maggiore diversa di MTA ($1) è già presente in quel percorso." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Tipo di installazione: Aggiornamento" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Aggiornamento online" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Verifica delle informazioni sull'aggiornamento" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Verifica delle informazioni sull'aggiornamento del programma di installazione in corso..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Assicurati che il tuo firewall non stia bloccando" diff --git a/Shared/installer/locale/ja_JP.pot b/Shared/installer/locale/ja_JP.pot index 71d3ccec4aa..d45e809ce6f 100644 --- a/Shared/installer/locale/ja_JP.pot +++ b/Shared/installer/locale/ja_JP.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-05-06 07:11\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Japanese\n" "Language: ja_JP\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "ダウンロードã—ãŸMTA:SAã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã€Windows XPã¾ãŸã¯Vistaをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。www.multitheftauto.com ã‹ã‚‰åˆ¥ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã•ã„。" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "ダウンロードã—ãŸMTA:SAã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã€Windows 7ã€8ã€ã¾ãŸã¯ 8.1 ã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。www.multitheftauto.com ã‹ã‚‰åˆ¥ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã•ã„。" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "ダウンロードã—ãŸMTA:SAã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã€å¤ã„Windowså‘ã‘ã«ä½œã‚‰ã‚Œã¦ã„ã¾ã™ã€‚www.multitheftauto.com ã‹ã‚‰åˆ¥ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã•ã„。" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯ã€ã”使用ã®ã‚³ãƒ³ãƒ”ュータã¸$(^Name) ${R "「次ã¸ã€ã«ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€ç¶šè¡Œã—ã¦ãã ã•ã„。" #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreas ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ•ォルダー" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas ã®ãƒ•ォルダー" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Grand Theft Auto: San Andreasã‚’é¸ã‚“ã§ãã ã•ã„。$\n" "「インストールã€ã«ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€å§‹ã‚ã¦ãã ã•ã„。" #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "インストールã—ãŸã‚¢ãƒ—リケーションã«ã‚¹ã‚¿ãƒ¼ãƒˆãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚°ãƒ«ãƒ¼ãƒ—を作る" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "MTA:SAクライエントã®ãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—ショートカットを作る" #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "「mtasa://ã€ãƒ—ロトコールをブラウザã«ç™»éŒ²ã—ã¦ãã ã•ã„。 ã“れã¯ãƒ–ラウザã§ã‚µãƒ¼ãƒã«å‚加ã™ã‚‹ãŸã‚ã§ã™ã€‚" #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Windows Games Explorerã«è¿½åŠ  (存在ã—ã¦ã„ã‚‹å ´åˆï¼‰" #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "DirectXをインストール/アップデートã™ã‚‹ï¼ˆå¿…è¦ãªã‚‰ï¼‰ã€‚" #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "MTA:San Andreasを実行ã™ã‚‹ãŸã‚ã€ã‚³ã‚¢ã®ã‚³ãƒ³ãƒãƒãƒ³ãƒˆãŒå¿…è¦ã§ã™ã€‚" #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA ã€ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã§éŠã¹ã‚‹MOD。" #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "MTA Server。ã“れã§è‡ªåˆ†ã®ã‚²ãƒ¼ãƒ ã‚’ホストã™ã‚‹ã®ã¯ã§ãã¾ã™ã€‚快速インターãƒãƒƒãƒˆãŒå¿…è¦ã§ã™ã€‚" #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "MTA Server。 å¿…è¦ã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆã€‚" #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "サーãƒãƒ¼ã®ãŸã‚ã®MTA:SA MOD。 å¿…è¦ã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆã€‚" #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "ã“れã¯ã‚µãƒ¼ãƒã®ãƒ‡ãƒ•ォルト資æºã§ã™ã€‚" #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "ã“れã¯ã‚µãƒ¼ãƒã®ãƒ‡ãƒ•ォルトマップã¨ã‚²ãƒ¼ãƒ ãƒ¢ãƒƒãƒ‰ã§ã™ã€‚" #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 マップエディター。ã“ã®é“å…·ã§è‡ªåˆ†ã®ãƒžãƒƒãƒ—ãŒä½œã‚Œã¾ã™ã€‚" #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "ã“れã¯SDKモジュールã€ã“れã§ãƒã‚¤ãƒŠãƒªãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ãŒMTA Serverã®ãŸã‚ã«ä½œã‚‰ã‚Œã¾ã™ã€‚C++ã®çŸ¥è­˜ãŒã‚る者以外ã¯ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ãªãã¦ã‚‚大丈夫ã§ã™ã€‚" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "MTA:SAã®MODを作るãŸã‚ã«ã®ç™ºå±•コードやé“å…·ã§ã™ã€‚" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "ã“れã¯MTA:SAã®ã‚¯ãƒ©ã‚¤ã‚¨ãƒ³ãƒˆã€‚サーãƒã«ãƒ—レイã™ã‚‹ã®ã«ä½¿ã„ã¾ã™ã€‚" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "クライアントã¨ã‚µãƒ¼ãƒãƒ¼" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "サーãƒã®ã¿" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "スタートメニューグループ" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "デスクトップアイコン" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "「mtasa://ã€ãƒ—ロトコルを登録ã™ã‚‹" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "ゲームエクスプローラーã«è¿½åŠ " #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "DirectXをインストールã™ã‚‹" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "ゲームクライアント" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "専用サーãƒãƒ¼" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "コアコンãƒãƒ¼ãƒãƒ³ãƒˆ" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "ゲームモジュール" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "アップデート中。。。" #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "許å¯ã‚¢ãƒƒãƒ—デート中。 ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„。。。" #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Grand Theft Auto: San Andreasã¯ç™ºè¦‹ã•れã¾ã›ã‚“ã§ã—ãŸã€‚$\\r$\n "å•題ãŒç™ºç”Ÿã—ãŸã‚‰ã€å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。" #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "コアリソース" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "オプションりソース" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "エディター" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "開発" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) ã¯æˆåŠŸã«å‰Šé™¤ã•れã¾ã—ãŸã€‚" #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "アンインストールãŒå¤±æ•—ã—ã¾ã—ãŸï¼" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "$(^Name)ã¨ã¨ã‚‚ã«ã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆã‚’削除ã—ãŸã„ã§ã™ã‹ã€‚" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "アップデートã™ã‚‹å‰ã«ã‚¢ãƒ³ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¾ã™ã‹?$\\r$ "インストーラを実行ã™ã‚‹ã¨è‡ªå‹•çš„ã«ã‚¢ãƒƒãƒ—デートã§ãã¾ã™ã€‚" #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "個人的ãªã‚‚ã®ã‚’ä¿ã£ãŸã„ã§ã™ã‹ã€‚(資æºã€ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆã¨ã‚µãƒ¼ãƒãƒ¼ã‚³ãƒ³ãƒ•ィグレーション)?「ã„ã„ãˆã€ã«ã‚¯ãƒªãƒƒã‚¯ã—ãŸã‚‰ã€å€‹äººçš„ãªã‚‚ã®ã‚’失ã„ã¾ã™ã€‚" #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "ã“ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ©ã¯ã‚¢ãƒ‰ãƒŸãƒ³ã‚¢ã‚¯ã‚»ã‚¹ãŒå¿…è¦ã§ã™ã€ã‚‚ã†ä¸€åº¦å§‹ã‚ã¦ãã ã•ã„" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "ã“ã®ã‚¢ãƒ³ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ©ã¯ã‚¢ãƒ‰ãƒŸãƒ³ã‚¢ã‚¯ã‚»ã‚¹ãŒå¿…è¦ã§ã™ã€ã‚‚ã†ä¸€åº¦è©¦ã—ã¦ãã ã•ã„。" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Logonサービスã¯å®Ÿè¡Œã—ã¦ã„ã¾ã›ã‚“ã€ä¸­æ­¢ã—ã¾ã™ï¼" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "上ã’ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -302,7 +302,7 @@ msgstr "ãã®ãƒ‘ã‚¹ã«æœ€æ–°MTAãƒãƒ¼ã‚·ãƒ§ãƒ³ãŒã‚りã¾ã™ã€‚$\n" "$INSTDIRã®MTA $1ã«ä¸Šæ›¸ãã—ã¾ã™ã‹ï¼Ÿ" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -313,7 +313,7 @@ msgstr "MTAã¯GTA:SAã¨åŒã˜ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ•ォルダーã§ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -322,7 +322,7 @@ msgstr "ãã®ãƒ‘スã¯å­˜åœ¨ã—ã¦ã„ã¾ã›ã‚“。$\n" "GTA:SAã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ•ォルダーをé¸ã‚“ã§ãã ã•ã„" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -331,17 +331,17 @@ msgstr "$GTA_DIRã«GTA:SAãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚$\n" "ã¨ã‚Šã‚ãˆãšã€ç¶šã‘ã¾ã™ã‹ã€‚" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "インストールフォルダーをé¸ã‚“ã§ãã ã•ã„" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ãŸã„フォルダーをé¸ã‚“ã§ãã ã•ã„" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -352,62 +352,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}ã¯æ¬¡ã®ãƒ•ォルダã«ã‚¤ãƒ³ " 「次ã¸ã€ã«ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€ç¶šè¡Œã—ã¦ãã ã•ã„。" #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "宛先フォルダー" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "ブラウズ..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "デフォルト" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "å‰å›žåˆ©ç”¨" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "カスタム" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ•ォルダをé¸ã‚“ã§ãã ã•ã„:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "警告:ã“ã®ãƒ‘スã«MTA ($1) 最新ãƒãƒ¼ã‚·ãƒ§ãƒ³ãŒå­˜åœ¨ã—ã¦ã„ã¾ã™ã€‚" #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "インストールタイプ: アップデート" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "オンライン更新" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "更新情報を確èªã—ã¦ã„ã¾ã™" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ©ã®æ›´æ–°æƒ…報を確èªã—ã¦ã„ã¾ã™â€¦" #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "ファイアウォールã«ãƒ–ロックã•れã¦ã„ãªã„ã®ã‚’確èªã—ã¦ãã ã•ã„" diff --git a/Shared/installer/locale/ka_GE.pot b/Shared/installer/locale/ka_GE.pot index 7f0f2aa03d9..2d76b6cc55f 100644 --- a/Shared/installer/locale/ka_GE.pot +++ b/Shared/installer/locale/ka_GE.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Georgian\n" "Language: ka_GE\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -41,17 +41,17 @@ msgid "This wizard will guide you through the installation or update of $(^Name) msgstr "" #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -60,226 +60,226 @@ msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" msgstr "" #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "" #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "" #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "" #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "" #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "" #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "" #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "" #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "" #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "" #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "" #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "" #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "" #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "" #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "" #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." msgstr "" #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "" #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." msgstr "" #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "" #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -287,7 +287,7 @@ msgid "A different major version of MTA ($1) already exists at that path.$\n" msgstr "" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -295,31 +295,31 @@ msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" msgstr "" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" msgstr "" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" msgstr "" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -327,62 +327,62 @@ msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the follow msgstr "" #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "" #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "" #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "" #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "" diff --git a/Shared/installer/locale/ko_KR.pot b/Shared/installer/locale/ko_KR.pot index f45b6a8bf9a..0bf1ca60c25 100644 --- a/Shared/installer/locale/ko_KR.pot +++ b/Shared/installer/locale/ko_KR.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Korean\n" "Language: ko_KR\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "ì´ ë§ˆë²•ì‚¬ëŠ” $(^Name) ${REVISION_TAG} ì˜ ì„¤ì¹˜ ë˜ëŠ” ì—…ë°ì´íЏ "다ìŒì„ í´ë¦­í•˜ì—¬ 계ì†í•©ë‹ˆë‹¤." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "그랜드 테프트 오토: ì‚° 안드레아스 위치" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "그랜드 테프트 오토: ì‚° 안드레아스 í´ë”" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "그랜드 í…Œ 프트 오토를 ì„ íƒí•˜ì‹­ì‹œì˜¤ : ì‚° 안드레아스 "설치를 í´ë¦­í•˜ì—¬ 설치를 시작합니다." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "ì„¤ì¹˜ëœ ì‘ìš© í”„ë¡œê·¸ëž¨ì— ëŒ€í•œ 시작 메뉴 그룹 만들기" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "MTA:SA í´ë¼ì´ì–¸íŠ¸ì— ëŒ€í•œ ë°ìФí¬í†± 바로 가기를 만듭니다." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "브ë¼ìš°ì € í´ë¦­ì„± mtasa:// 위해 í”„ë¡œí† ì½œì„ ë“±ë¡í•©ë‹ˆë‹¤." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Windows 게임 íƒìƒ‰ê¸°ì— 추가합니다(있는 경우)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "DirectX를 설치하거나 ì—…ë°ì´íŠ¸í•©ë‹ˆë‹¤(필요한 경우)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Multi Theft Auto를 실행하는 ë° í•„ìš”í•œ 핵심 구성 요소입니다." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA 수정으로 온ë¼ì¸ìœ¼ë¡œ 플레ì´í•  수 있습니다." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "다중 ë„난 ìžë™ 서버. ì´ë ‡ê²Œí•˜ë©´ 컴퓨터ì—서 ê²Œìž„ì„ í˜¸ìŠ¤íŒ… í•  수 있습니다. ì´ë¥¼ 위해서는 빠른 ì¸í„°ë„· ì—°ê²°ì´ í•„ìš”í•©ë‹ˆë‹¤." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "다중 ë„난 ìžë™ 서버. ì´ëŠ” 필수 구성 요소입니다." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "ì„œë²„ì— ëŒ€í•œ MTA:SA 수정입니다." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "ì´ëŠ” ì„œë²„ì— í•„ìš”í•œ 리소스 집합입니다." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "ì´ê²ƒì€ ì„œë²„ì— ëŒ€í•œ 게임 모드 ë°ì§€ë„ì˜ ì„ íƒì  세트입니다." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 ë§µ 편집기. MTAì˜ ê²Œìž„ 모드ì—서 사용할 ìžì‹  ë§Œì˜ ë§µì„ ë§Œë“œëŠ” ë° ì‚¬ìš©í•  수 있습니다." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "MTA ì„œë²„ì— ëŒ€í•œ ì´ì§„ ëª¨ë“ˆì„ ë§Œë“¤ê¸° 위한 SDK입니다. C ++ì— ëŒ€í•´ 잘 알고있는 경우ì—ë§Œ 설치하십시오!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Multi Theft Autoìš© 모드 ì œìž‘ì— ë„ì›€ì´ ë˜ëŠ” 개발 코드 ë° ë„구" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "í´ë¼ì´ì–¸íŠ¸ëŠ” Multi Theft Auto 서버ì—서 플레ì´í•˜ê¸° 위해 실행하는 프로그램입니다." #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "í´ë¼ì´ì–¸íЏ ë° ì„œë²„" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "서버 ì „ìš©" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "시작 메뉴 그룹" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "바탕 화면 ì•„ì´ì½˜" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "레지스터 mtasa:// 프로토콜" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "게임 íƒìƒ‰ê¸°ì— 추가" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "다ì´ë ‰íЏ X 설치" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "게임 í´ë¼ì´ì–¸íЏ" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "ì „ìš© 서버" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "핵심 구성 요소" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "게임 모듈" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "현재 위치 업그레ì´ë“œ 수행 중..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "사용 권한 ì—…ë°ì´íЏ. ì´ ìž‘ì—…ì€ ëª‡ ë¶„ ì •ë„ ê±¸ë¦´ 수 있습니다..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Grand Theft Autoì˜ ìœ íš¨í•œ Windows 버전: San Andreasê°€ ê°ì§€ë˜ "ë‚˜ì¤‘ì— ë¬¸ì œê°€ ë°œìƒí•˜ë©´ 다시 설치하십시오." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "핵심 리소스" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "ì„ íƒì  리소스" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "편집ìž" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "발달" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) ê°€ 컴퓨터ì—서 성공ì ìœ¼ë¡œ 제거ë˜ì—ˆìŠµë‹ˆë‹¤." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "ì œê±°ì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "$(^Name) 와 모든 구성 요소를 완전히 제거하시겠습니까?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "ì—…ë°ì´íŠ¸í•˜ê¸° ì „ì— ì œê±°í•˜ì‹œê² ìŠµë‹ˆê¹Œ?$\\r$\n" "새 설치 관리ìžë¥¼ 실행하여 ì„¤ì •ì„ ì—…ê·¸ë ˆì´ë“œí•˜ê³  보존합니다." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "ë°ì´í„° 파ì¼(예: 리소스, 스í¬ë¦°ìƒ· ë° ì„œë²„ 구성) ì„ ìœ ì§€í•˜ì‹œê² ìŠµë‹ˆê¹Œ? 아니요를 í´ë¦­í•˜ë©´ 만든 리소스, 구성 ë˜ëŠ” 스í¬ë¦°ìƒ·ì´ ì†ì‹¤ë©ë‹ˆë‹¤." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "ì´ ì„¤ì¹˜ 관리ìžëŠ” ê´€ë¦¬ìž ì•¡ì„¸ìŠ¤ê°€ 필요하며 다시 시ë„하십시오." #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "ì´ ì œê±° í”„ë¡œê·¸ëž¨ì€ ê´€ë¦¬ìž ì•¡ì„¸ìŠ¤ê°€ 필요하며 다시 시ë„하십시오." #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "로그온 서비스가 실행ë˜ê³  있지 않고 중단ë˜ì—ˆìŠµë‹ˆë‹¤!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "ìƒìŠ¹í•  수 ì—†ìŒ" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "MTA ($1) ì˜ ë‹¤ë¥¸ 주요 ë²„ì „ì´ ì´ë¯¸ 해당 ê²½ë¡œì— ì¡´ìž¬í•© " $INSTDIRì— MTA $1ì„ ë®ì–´ 쓰시겠습니까?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA를 GTA:SA.$와 ë™ì¼í•œ ë””ë ‰í† ë¦¬ì— ì„¤ì¹˜í•  수 없습니다. "$DEFAULT_INSTDIR?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "ì„ íƒí•œ 디렉토리가 존재하지 않습니다\n" "GTA:SA 설치 디렉토리를 ì„ íƒí•˜ì‹­ì‹œì˜¤" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "$GTA_DIR $ì— ì„¤ì¹˜ëœ GTA:SA를 ì°¾ì„ ìˆ˜ 없습니다\n" "계ì†í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "설치 위치 ì„ íƒ" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} ì„(를) 설치할 í´ë”를 ì„ íƒí•©ë‹ˆë‹¤" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} ì´(ê°€) ë‹¤ìŒ í´ë”ì— ì„¤ " 계ì†í•˜ë ¤ë©´ 다ìŒì„ í´ë¦­í•©ë‹ˆë‹¤." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "ëŒ€ìƒ í´ë”" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "찾아보기..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "기본값" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "최근 사용" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "ì‚¬ìš©ìž ì •ì˜" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} ì„(를) 설치할 í´ë”를 ì„ íƒí•˜ì‹­ì‹œì˜¤:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "경고: 해당 ê²½ë¡œì— ë‹¤ë¥¸ 주 ë²„ì „ì˜ MTA($1) ê°€ ì´ë¯¸ 있습니다." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "설치 유형: 업그레ì´ë“œ" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "온ë¼ì¸ ì—…ë°ì´íЏ" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "ì—…ë°ì´íЏ ì •ë³´ í™•ì¸ ì¤‘" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "설치 ê´€ë¦¬ìž ì—…ë°ì´íЏ 정보를 확ì¸í•˜ëŠ” 중..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "ë°©í™”ë²½ì´ ì°¨ë‹¨ë˜ì–´ 있지 않ì€ì§€ 확ì¸í•˜ì‹­ì‹œì˜¤" diff --git a/Shared/installer/locale/lt_LT.pot b/Shared/installer/locale/lt_LT.pot index 8e14670cf5a..b0483028284 100644 --- a/Shared/installer/locale/lt_LT.pot +++ b/Shared/installer/locale/lt_LT.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Lithuanian\n" "Language: lt_LT\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Å is įdiegimo gidas jums padÄ—s įdiegti ar atnaujinti $(^Name) ${REVIS "NorÄ—dami tÄ™sti, spauskite Toliau." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreas įdiegimo vieta" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas aplankas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Pasirinkite Grand Theft Auto: San Andreas aplankÄ….$\n" "Spauskite Ä®diegti norÄ—dami pradÄ—ti įdiegimÄ…." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Sukurti Pradžios Meniu grupÄ™ įdiegtoms programoms" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Sukurti Darbalaukio NuorodÄ… MTA:SA Klientui." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Leisti mtasa:// protokolo panaudojimÄ… narÅ¡yklÄ—se." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "PridÄ—ti prie Windows Games Explorer (jei yra)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Ä®diegti ar atnaujinti DirectX (jei reikalinga)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Pagrindiniai komponentai reikalingi, kad veiktų Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA modifikacija, leidžianti jums žaisti internetu." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto serveris. Naudodamiesi juo jÅ«s galite sukurti savo žaidimo serverį. Reikalingas greitas interneto ryÅ¡ys." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto serveris. Å is komponentas yra privalomas." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA modifikacija serveriui." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Tai yra reikalingų resursų rinkinys jÅ«sų serveriui." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Tai yra neprivalomas žaidimo režimų ir žemÄ—lapių rinkinys jÅ«sų serveriui." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 ŽemÄ—lapių Redaktorius. Gali bÅ«ti panaudotas norint sukurti jÅ«sų paÄių trokÅ¡tamus žemÄ—lapius skirtus MTA žaidimo tipams." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Tai yra SDK norint kurti dvejetainius modulius MTA serveriui. Ä®diekite tik tuomet, jei turite gerÄ… supratimÄ… apie C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Vystymo kodas ir įrankiai, kurie padeda Multi Theft Auto modifikacijų kÅ«rime" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Klientas yra programa, kuriÄ… jÅ«s naudojate žaisdami Multi Theft Auto serveryje" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Klientas ir Serveris" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Tik serveris" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Pradžios meniu grupÄ—" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Darbalaukio piktograma" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Registruoti mtasa:// protokolÄ…" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "PridÄ—ti prie Games Explorer" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Ä®diegti DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Žaidimo klientas" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Dedikuotas serveris" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Pagrindiniai komponentai" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Žaidimo modulis" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Atliekamas vietos atnaujinimas..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Atnaujinami leidimai. Tai gali užtrukti kelias minutes..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Galiojanti Grand Theft Auto: San Andreas versija nerasta.$\\r$\n" "Jei kils problemų, praÅ¡ome įdiegti iÅ¡ naujo." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Pagrindiniai Resursai" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "NebÅ«tini Resursai" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Redaktorius" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "PlÄ—tojimas" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) buvo sÄ—kmingai paÅ¡alintas iÅ¡ jÅ«sų kompiuterio." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "PaÅ¡alinimas nepavyko!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Ar tikrai norite paÅ¡alinti $(^Name) ir visus jo komponentus?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "PaÅ¡alinama prieÅ¡ atnaujinimÄ…?$\\r$\n" "Paleiskite atnaujinimo diegimÄ… ir iÅ¡saugosite savo nustatymus." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Ar norÄ—tumÄ—te palikti savo duomenų bylas (pavyzdžiui resursus, nuotraukas ir serverio konfigÅ«racijÄ…)? Jei paspausite ne, tai visi resursai, konfigÅ«racijos ar nuotraukos kurias padarÄ—te, bus paÅ¡alinti." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Å is įdiegimo procesas reikalauja administratoriaus teisių, bandykite dar kartÄ…" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Å is paÅ¡alinimas reikalauja administratoriaus teisių, bandykite dar kartÄ…" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Prisijungimo paslauga neveikia, nutraukiama!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Nepavyko iÅ¡kelti" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Kita MTA ($1) pagrindinÄ— versija jau egzistuoja pasirinktoje vietoje.$\ " Ar jÅ«s įsitikinÄ™, jog norite perraÅ¡yti MTA $1 direktorijoje $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA negali bÅ«ti įdiegtas į tÄ… paÄiÄ… vietÄ… kaip GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Pasirinkta direktorija neegzistuoja.$\n" "PraÅ¡ome pasirinkti GTA:SA įdiegimo direktorijÄ…" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Nepavyko rasti GTA:SA pasirinktoje direktorijoje $GTA_DIR $\n" "Ar tikrai norite tÄ™sti ?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Pasirinkite Ä®diegimo VietÄ…" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Pasirinkite aplankÄ…, kuriame norÄ—tumÄ—te įdiegti ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} bus įdiegta Å¡iame aplanke.$\ "NorÄ—dami tÄ™sti, spauskite Toliau." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Pasirinktas Aplankas įdiegimui" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "NarÅ¡yti..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Numatytasis" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Paskutinį kartÄ… naudota(s)" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Pasirinktinis" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Pasirinkite aplankÄ… įdiegti ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "DÄ—mesio: Kita pagrindinÄ— MTA ($1) versija jau egzistuoja pasirinktoje vietoje." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Ä®diegimo tipas: Atnaujinimas" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Atnaujinimas tinklu" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Tikrinama ar yra atnaujinimų" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Tikrinama ar yra diegimo atnaujinimų..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "PraÅ¡ome įsitinkinti ar ugniasienÄ— neblokuoja" diff --git a/Shared/installer/locale/lv_LV.pot b/Shared/installer/locale/lv_LV.pot index 97078570994..19debd84d58 100644 --- a/Shared/installer/locale/lv_LV.pot +++ b/Shared/installer/locale/lv_LV.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Latvian\n" "Language: lv_LV\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Å Ä« instalÄcija palÄ«dzÄ“s Jums uzinstalÄ“t vai atjauninÄt $(^Name) $ "Spiediet TÄlÄk, lai turpinÄtu." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreas atraÅ¡anÄs vieta" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas mape" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "LÅ«dzu izvÄ“lieties Grand Theft Auto: San Andreas mapi.$\n" "Spiediet InstalÄ“t lai uzsÄktu instalÄciju." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Izveidot Start Menu grupu priekÅ¡ instalÄ“tajÄm aplikÄcijÄm" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Izveidot darbvirsmas saÄ«sni priekÅ¡ MTA:SA Klienta." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "ReÄ£istrÄ“t mtasa:// protokolu priekÅ¡ interneta pÄrlÅ«ka." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Pievienot pie Windows Spēļu PÄrlÅ«kotÄja (ja tÄds ir)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "InstalÄ“ vai atjauno DirectX (ja ir nepiecieÅ¡ams)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Galvenie elementi, kuri nepiecieÅ¡ami, lai palaistu Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA modifikÄcija ļauj Jums spÄ“lÄ“t tieÅ¡saistÄ“." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto Serveris. Å is ļaus Jums izveidot serveri uz JÅ«su datora. Pieprasa Ätru interneta savienojumu." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto serveris. Å Ä« ir nepiecieÅ¡ama sastÄvdaļa." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA modifikÄcija priekÅ¡ servera." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Å ie ir nepiecieÅ¡amie resursi priekÅ¡ jÅ«su servera." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Å ie ir nepiecieÅ¡amie spēļu veidi un mapes priekÅ¡ jÅ«su servera." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 Map Editors. Å o var izmantot, lai izveidotu pats savas mapes un izmantotu tos MTA serveros." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Å is ir SDK rÄ«ks, lai izveidotu binÄros moduļus priekÅ¡ MTA servera. InstalÄ“t tikai tad, ja JÅ«s saprotat C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "IzstrÄdÄtÄja kodi un rÄ«ki, kuri ir nepiecieÅ¡ami, lai izstrÄdÄtu Multi Theft Auto modifikÄcijas" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Klients ir programma, kuru JÅ«s izmantojat, lai spÄ“lÄ“ti iekÅ¡ Multi Theft Auto serveriem" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Klients un Serveris" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Tikai serveris" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "IzvÄ“lnes sÄkt grupa" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Darbvirsmas ikona" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "ReÄ£istrÄ“t mtasa:// protokolu" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Pievienot pie Spēļu PÄrlukotÄja" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "InstalÄ“t DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "SpÄ“les klients" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Serveris" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Kodola komponenti" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "SpÄ“les modulis" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Veicina ievietoÅ¡anas atjauninÄjumu..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Atjauno atļaujas. Tas var aizņemt pÄris minÅ«tes..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "DerÄ«ga Windows versija priekÅ¡ Grand Theft Auto: San Andreas netika atr "LÅ«dzu pÄrinstalÄ“jiet, ja ir kaut kÄdas problÄ“mas." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Kodola Resursi" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Ieteicamie Resursi" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Editors" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "IzstrÄdÄÅ¡ana" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) tikai sekmÄ«gi noņemts no jÅ«su datora." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Atinstalēšana neizdevÄs!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Vai JÅ«s tik tieÅ¡Äm vÄ“laties noņemt $(^Name) un visus tÄ komponentus?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Attisntelēšana atjauninÄjuma laikÄ?$\\r$\n" "StartÄ“jiet jaunu instalÄciju, un saglabÄjat arÄ« savus iestatijumus." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Vai JÅ«s vÄ“laties paturÄ“t datu failus (tÄdus kÄ resursu, ekrÄnÅ¡Äviņus un servera konfigurÄcijas)? Ja nospiedÄ«siet nÄ“, jebkuri resursi, konfigurÄcijas, vai ekrÄnÅ¡Äviņi tiks dzÄ“sti." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "InstalÄcija pieprasa administratora piekļuvi, mēģiniet vÄ“lreiz" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Atinstalators pieprasa administratora piekļuvi, mēģiniet vÄ“lreiz" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Logon pakalpojums nedarbojÄs, atceļ!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "NespÄ“j pacelt" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Cita MTA ($1) versija jau eksistÄ“ Å¡ajÄ ceļÄ.$\n" "Vai JÅ«s tik tieÅ¡Äm vÄ“laties pÄrrakstÄ«t MTA $1 iekÅ¡ $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA nevar bÅ«t instalÄ“ts tajÄ paÅ¡Ä vietÄ, kur atrodas GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "IzvÄ“lÄ“tÄ mape neeksitÄ“.$\n" "LÅ«dzu izvÄ“lieties GTA:SA instalÄcijas mapi" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "NespÄ“j atrast GTA:SA instalÄciju iekÅ¡ $GTA_DIR $\n" "Vai esat pÄrliecinÄts ka vÄ“laties turpinÄt ?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "IzvÄ“lÄ“ties InstalÄcijas AtraÅ¡anÄs Vietu" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "IzvÄ“lieties mapi, kurÄ tiks instalÄ“ts ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} tiks instalÄ“dz sekojoÅ¡Ä map "Spiediet tÄlÄk, lai turpinÄtu." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "MÄ“rÄ·a Mape" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "PÄrmeklÄ“t..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "SÄkotnÄ“js" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "PÄ“dÄ“jais izmantotais" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "PielÄgots" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "IzvÄ“lieties mapi, lai uzinstalÄ“tu ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "BrÄ«dinÄjums: Cita MTA ($1) jau eksistÄ“ Å¡ajÄ ceļÄ." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "InstalÄcijas tips: AtjauninÄjums" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "TieÅ¡saistes atjauninÄjums" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "PÄrbauda atjauninÄjumu informÄciju" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "PÄrbauda instalÄcijas informÄcijas atjaunoÅ¡anu" #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "LÅ«dzu pÄrliecinÄties ka jÅ«su ugunsmÅ«ris nav bloÄ·Ä“ts" diff --git a/Shared/installer/locale/mk_MK.pot b/Shared/installer/locale/mk_MK.pot index 17ecbce36b1..7d257788c40 100644 --- a/Shared/installer/locale/mk_MK.pot +++ b/Shared/installer/locale/mk_MK.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Macedonian\n" "Language: mk_MK\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Волшебникот ќе те води преку инÑталаци "СтиÑнете Next за да продолжиш." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreas локација" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas фолдер" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Ве молиме Ñелектирајте го вашиот Grand Theft "Кликнете на ИнÑталирај за да започне инÑталирањето." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Креирај Старт Мену група за инÑталираните апликации." #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Креирај ДекÑтоп кратенка за MTA:SA Клиентот" #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "РегиÑтрирај mtasa:// протокол за да може да Ñе притиÑне на прелиÑтувачот. " #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Додај во прозорецот за пребарување на игри (доколку е претÑтавен)" #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "ИнÑталирај или надгради го DirectX (доколку Ñе бара)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "ОÑновните компоненти Ñе потребни за да може да Ñе Ñтартува Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "Модификацијата на MTA:SA, ти дозволува да играш онлајн." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto Ñерверот ти овозможува да хоÑтираш игра од твојот компјутер.За тоа ти треба брза интернет конекција." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto Ñерверот е задолжителна компонента." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA модификација за Ñерверот." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Ова е Ñет од задолжителни реÑурÑи за твојот Ñервер." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Ова е оптимален Ñет од модови за игри и мапи за твојот Ñервер." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "Едиторот на мапа за MTA:SA 1.0. Ова може да Ñе употреби за креирање на мапи во модовите на игри за MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Ова е SDK за креирање на бинарни модели за MTA Ñерверот. ИнÑталирај го Ñамо доколку имаш добри познавање на C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Кодот за развој и алатки што помага во креирање на модови за Мulti Theft Auto." #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Овој клиент е програмата што ја кориÑтиш за да можеш да играш на Multi Theft Auto Ñерверите." #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Клиент и Сервер" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Само Ñервер" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Start menu група" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "ДеÑктоп икона" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "РегиÑтрирај mtasa:// протокол" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Додај во иÑтражувачот на игри" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "ИнÑталирање на DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Клиент за игра" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "ПоÑветен Ñервер" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "ОÑновни компоненти" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Модел на игра " #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Извршување на меÑто надградба..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Ðжурирање на барање. Ова може да потрае неколку минути..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Валидна верзија од Grand Theft Auto: San Andreas не б "Ве молиме ре-инÑталирајте доколку имате проблеми подоцна." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "ОÑновни реÑурÑи" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Оптимални реÑурÑи" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Уредник" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Развој" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Име) беше уÑпешно отÑтрането од вашиот компјутер." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "ДеинÑталирањето е неуÑпешно!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Дали Ñте Ñигурни дека Ñакате комплетно да го отÑтраните $(^Име) и Ñите други компоненти?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "ДеинÑталирање пред надградување?$\\r$\n" "Вклучете ја новата инÑталација за да надградете и вратете Ñтарите конфигурации." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Дали Ñакате да ги задржите вашите фајлови (како на пример реÑурÑи, Ñлики и конфигурации од Ñерверот)? Доколку притиÑнете не, било каква реÑурÑа, конфигурација или Ñлика што Ñте ги креирале ќе биде изгубена." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "ИнÑталацијата бара приÑтап на админот, пробајте повторно " #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "ДеинÑталацијата бара приÑтап до админот, пробајте повторно" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "СервиÑот за логирање не е во употреба, иÑклучување!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Грешка во подигање" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Поинаква поголема верзија од MTA ($1) веќе " Дали Ñте Ñигурни дека Ñакате да ја пребришете MTA $1 во $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA не може да Ñе инÑталира во иÑтата дир "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Селектираниот фолдер не поÑтои.$\n" "Ве молиме Ñелектирајте го инÑталациониот фолдер на GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Ðе може да Ñе најде инÑталацијата на GTA:S "Дали Ñте Ñигурни дека Ñакате да продолжите ?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Изберете меÑто за инÑталација" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Изберете фолдер во кој ќе инÑталирате ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} ќе Ñе инÑталира " Кликнете Следно за да продолжите." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "ДеÑтинација на фолдерот" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Пребарување..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Стандарно" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "ПоÑледно употребувано" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Обично" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Селектирајте го фолдерот за да инÑталирате ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} во:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Предупредување: Поинаква поголема верзија од MTA ($1) веќе поÑтои на тоа меÑто." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Вид на инÑталација: Ðадградба" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Онлјан надградба" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Проверка на информација за надградба" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Проверка на информација за надградба на инÑталацијата" #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Ве молиме оÑигурајте Ñе вашиот firewall да не блокира" diff --git a/Shared/installer/locale/nb_NO.pot b/Shared/installer/locale/nb_NO.pot index 8fb71cbf526..9b200bf5b33 100644 --- a/Shared/installer/locale/nb_NO.pot +++ b/Shared/installer/locale/nb_NO.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Norwegian Bokmal\n" "Language: nb_NO\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Denne veiviseren vil guide deg gjennom installasjonen eller oppdateringe "Klikk Neste for Ã¥ fortsette." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreas plassering" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas mappe" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Vennligst velg din Grand Theft Auto: San Andreas mappe.$\n" "Trykk Installer for Ã¥ begynne installasjonen." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Opprett en Start Meny gruppe for installerte programmer" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Opprett en snarvei pÃ¥ skrivebordet for MTA:SA klienten." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registrer mtasa:// protokoll for nettleser klikkbar-somhet." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Legg til i Windows Spill Utforsker (hvis den finnes)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Installer eller oppdater DirectX (om nødvendig)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Grunnkomponentene som trenges for Ã¥ kjøre Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA modifikasjonen tillater deg Ã¥ spille pÃ¥ nettet." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto server. Denne tillater deg Ã¥ opprette spill fra din datamaskin. Dette krever en rask Internett tilkobling." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto server. Dette er en nødvendig komponent." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA modifikasjonen for serveren." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Dette er et sett av nødvendige ressurser for serveren din." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Dette er ett sett av valgfrie spillmoduler og kart for serveren din." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 Kart Editor. Denne kan bli brukt til Ã¥ skape dine helt egne kart for bruk i spillmoduser for MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Dette er SDK'en for Ã¥ lage binære moduler for MTA serveren. Bare installere hvis du har en god forstÃ¥else for C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Utviklings kode og verktøy som kan benyttes for Ã¥ skape modifikasjoner for Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Klienten er programmet du kjører for Ã¥ spille pÃ¥ en Multi Theft Auto server" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Klient og Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Kun server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Start meny gruppe" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Skrivebordsikon" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Registrer mtasa:// protokoll" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Legg til i Spill Utforsker" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Installer DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Spill klient" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Dedikert server" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Kjernekomponenter" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Spill modul" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Utfører direkte oppgradering..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Oppdaterer tillatelser. Dette kan ta noen minutter..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "En gyldig Windows versjon av Grand Theft Auto: San Andreas ble ikke funn "Vennligst installer pÃ¥ nytt om problemer oppstÃ¥r senere." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Kjerne Ressurser" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Valgfrie Ressurser" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Redigerings verktøy" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Utvikling" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) ble fjernet fra din datamaskin." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Avinstallasjonen har feilet!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Er du sikker pÃ¥ at du vill fullstendig fjerne $(^Name) og alle dens komponenter?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Avinstallere før oppdatering?$\\r$\n" "Kjør det nye installasjonsprogrammet for Ã¥ oppgradere og bevare dine innstillinger." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Ville du like Ã¥ beholde alle dine data filer (Slikt som ressurser, skjermdumper og server konfigurasjon)? Om du trykker nei, vil alle ressurser, konfigureringer og skjermdumper du har laget bli slettet." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Dette installasjons verktøyet krever admin tilgang, prøv igjen" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Dette avinstallasjonsverktøyet krever admin tilgang, prøv igjen" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Logon-tjenesten kjører ikke, avbryter!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Kunne ikke oppheve" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "En annen stor versjon av MTA ($1) finnes allerede i denne banen.$\n" " Er du sikker pÃ¥ at du vil overskrive MTA $1 pÃ¥ $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA kan ikke installeres i samme mappe som GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Den valgte destinasjonen finnes ikke.$\n" "Vennligst velg GTA:SA installasjons mÃ¥lmappe" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Kunne ikke finne GTA:SA installert i $GTA_DIR $\n" "Er du sikker pÃ¥ at du vill fortsette ?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Velg MÃ¥lmappe" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Velg mappe hvor ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} skal installeres" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} vill bli installert i følgend " Klikk Neste for Ã¥ fortsette." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "MÃ¥lmappe" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Bla gjennom..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Standard" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Sist brukt" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Tilpasset" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Velg mappe for Ã¥ installere ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} i:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Advarsel: En annen stor versjon av MTA ($1) finnes allerede i den banen." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Installasjon type: Oppgrader" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Nettoppdatering" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Ser etter oppdaterings informasjon" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Ser etter oppdaterings informasjon for installasjonsprogrammet..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Vennligst sikre at brannmuren ikke blokkerer" diff --git a/Shared/installer/locale/nl_NL.pot b/Shared/installer/locale/nl_NL.pot index a40f6abd8f8..f4ef1d9e646 100644 --- a/Shared/installer/locale/nl_NL.pot +++ b/Shared/installer/locale/nl_NL.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Dutch\n" "Language: nl_NL\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Deze wizard zal u begeleiden door de installatie of update van $(^Name) "Klik op Volgende om door te gaan." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Locatie van Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Map met Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Selecteer het bestand waar Grand Theft Auto: San Andreas zich bevind.$\n " Klik op Installeer om met de installatie te beginnen." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Maak een groep in het Start Menu aan voor de geïnstalleerde applicatie" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Maak een snelkoppeling aan op het bureaublad voor MTA:SA." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registreer het mtasa:// protocol voor snelle toegang vanuit een webbrowser." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Voeg toe aan de Windows Spellen verkenner (indien aanwezig)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Installeer of update DirectX (indien nodig)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "De kern elementen die vereist zijn om Multi Theft Auto te kunnen spelen." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "De MTA:SA modificatie, laat je toe online te spelen." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "De Multi Theft Auto Server. Hiermee kan je spellen van op je computer aanbieden. Dit vereist een snelle internet verbinding." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "De Mulit Theft Auto server. Dit is een vereist onderdeel." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "De MTA:SA modificatie voor de server." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Dit is een set van vereiste bronnen voor je server." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Dit is een optionele set van spelmodi en werelden voor je server." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "De MTA:SA 1.0 Map Editor. Dit kan gebruikt worden om je eigen wereld mee te bouwen voor gebruik in spelmodi in MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Met deze SDK kan je binaire modules bouwen voor de MTA server. Enkel te installeren indien je een goede kennis van C++ hebt!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Ontwikkel code en gereedschap om te helpen bij het bouwen van mods voor Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "De client is het programma dat je start om te spelen op een Multi Theft Auto server" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Client en Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Enkel de server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Start menu groep" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Bureaublad icoon" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Registreer mtasa:// protocol" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Voeg toe aan de Spellen verkenner" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Installeer DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Client" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Losstaande server" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Essentiële onderdelen" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Spel module" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Vervangende upgrade aan het uitvoeren..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Aanpassen van bevoegdheden. Dit kan enkele minuten duren..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Een geldige Windows versie van Grand Theft Auto: San Andreas is niet ged "Alstublieft opnieuw installeren als er enige problemen zijn later." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Hoofd Bronnen" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Optionele bronnen" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Editor" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Ontwikkeling" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) was succesvol verwijderd van uw computer." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "De-installatie heeft gefaald!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Ben je zeker dat je $(^Name) en alle bijhorende onderdelen volledig wenst te verwijderen?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Verwijderen voor update?$\\r$\n" "Voer het nieuwe installatieprogramma uit om te upgraden en uw instellingen te behouden." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Wil je de data files behouden (zoals resources, screenshots en server configuration)? Als je op nee klikt, alle resources, configuraties of screenshots die gemaakt zijn zullen worden verwijdert." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Deze installer heeft administrator rechten nodig, probeer opnieuw" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Deze uninstaller heeft administrator rechten nodig, probeer opnieuw" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Aanmeld service is niet gestart, afbreken!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Verheffing niet mogelijk" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Een andere versie van MTA ($1) bestaat al in dat pad.$\n" "Weet je zeker dat je MTA $1 op $INSTDIR wilt overschrijven ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA kan niet worden geïnstalleerd in dezelfde map als GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,24 +321,24 @@ msgstr "Het geselecteerde bestand bestaat niet.$\n" " Selecteer de GTA:SA Installatie map" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" msgstr "Kies map waar ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} geïnstalleerd in moet worden" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Selecteer Installatie Locatie" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Kies map waar ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} geïnstalleerd in moet worden" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -349,62 +349,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} wordt in de volgende map geïn "Klik op volgende om door te gaan." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Doelmap" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Bladeren..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Standaard locatie" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Laatst gebruikt" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Aangepast" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Selecteer de map om ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in te installeren:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Waarschuwing: Een andere grote versie van MTA ($1) bestaat al op die locatie." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Installatie type: Bijwerken" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Online Update" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Controleren op update informatie" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Controleren op installatie update informatie..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Check of je firewall het niet blokkeert" diff --git a/Shared/installer/locale/pl_PL.pot b/Shared/installer/locale/pl_PL.pot index db446a22fa3..31124ff5a9a 100644 --- a/Shared/installer/locale/pl_PL.pot +++ b/Shared/installer/locale/pl_PL.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-05-11 17:01\n" +"POT-Creation-Date: 2026-01-19 01:08\n" +"PO-Revision-Date: 2026-01-25 00:30\n" "Last-Translator: \n" "Language-Team: Polish\n" "Language: pl_PL\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 -msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." -msgstr "Ta wersja MTA:SA nie obsÅ‚uguje systemów Windows XP i Vista. Pobierz innÄ… wersjÄ™ ze strony www.multitheftauto.com." +#: Shared/installer/nightly.nsi:206 +msgid "Multi Theft Auto does not support Windows XP or Vista. Please upgrade your computer." +msgstr "Multi Theft Auto nie obsÅ‚uguje systemów Windows XP i Vista. Zaktualizuj swój komputer." #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "Ta wersja MTA:SA nie obsÅ‚uguje systemów Windows 7, Windows 8 i 8.1. Pobierz innÄ… wersjÄ™ ze strony www.multitheftauto.com." #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "Ta wersja MTA:SA jest przeznaczona do starszych wersji systemu Windows. Pobierz innÄ… wersjÄ™ ze strony www.multitheftauto.com." #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Ten instalator pozwoli Ci przejść przez proces instalacji lub aktualiz "Kliknij przycisk Dalej aby kontynuować." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Lokalizacja Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Folder zawierajÄ…cy grÄ™ Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Wskaż folder, w którym zainstalowano grÄ™ Grand Theft Auto: San Andrea "Kliknij przycisk Zainstaluj aby rozpocząć instalacjÄ™." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Tworzy grupÄ™ dla instalowanej aplikacji w Menu Start" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Umieszcza skrót do Klienta MTA:SA na Pulpicie." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Rejestruje obsÅ‚ugÄ™ protokoÅ‚u mtasa:// aby umożliwić szybkie podłączanie siÄ™ do serwerów MTA poprzez linki w przeglÄ…darce." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Dodaje odnoÅ›nik do funkcji Eksploratora Gier w Windows (o ile dostÄ™pna)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Zainstaluj lub zaktualizuj DirectX (jeÅ›li jest wymagany)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Podstawowe komponenty wymagane do uruchomienia Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "Modyfikacja MTA:SA pozwala Ci grać online." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Serwer Multi Theft Auto. Pozwala na uruchomienie serwera do gry na Twoim komputerze. Wymaga szybkiego połączenia z internetem." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Serwer Multi Theft Auto. Ten komponent jest wymagany." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "Modyfikacja MTA:SA dla serwera." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Zestaw zasobów udostÄ™pniajÄ…cy podstawowÄ… funkcjonalność dla serwera." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Opcjonalny zestaw zasobów, zawierajÄ…cy standardowe tryby gry i mapy dla serwera." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "Edytor Map dla MTA:SA. Można go użyć do tworzenia lub edycji map dla rozmaitych trybów gry w MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Zestaw SDK do tworzenia modułów dla serwera MTA. Zainstaluj go tylko wtedy, gdy dobrze znasz jÄ™zyk C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Pomocniczy kod oraz narzÄ™dzia pomagajÄ…ce w tworzeniu modyfikacji do Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Klient jest programem, który sÅ‚uży do gry w Multi Theft Auto" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:479 msgid "Client and Server" msgstr "Klient i serwer" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:480 msgid "Server only" msgstr "Tylko serwer" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:494 msgid "Start menu group" msgstr "Utwórz grupÄ™ w Menu Start" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:495 msgid "Desktop icon" msgstr "Utwórz skrót na Pulpicie" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:496 msgid "Register mtasa:// protocol" msgstr "Zarejestruj protokół mtasa://" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:497 msgid "Add to Games Explorer" msgstr "Dodaj do Eksploratora Gier" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:498 msgid "Install DirectX" msgstr "Zainstaluj DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:532 msgid "Game client" msgstr "Klient gry" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:533 msgid "Dedicated server" msgstr "Serwer dedykowany" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:534 msgid "Core components" msgstr "Podstawowe komponenty" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:535 msgid "Game module" msgstr "ModuÅ‚ gry" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:537 msgid "Performing in-place upgrade..." msgstr "Przeprowadzam proces uaktualnienia..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:538 msgid "Updating permissions. This could take a few minutes..." msgstr "AktualizujÄ™ uprawnienia. Może to zająć kilka minut..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:539 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Nie wykryto poprawnie zainstalowanej gry Grand Theft Auto: San Andreas.$ "W razie problemów - zainstaluj moda jeszcze raz." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:542 msgid "Core Resources" msgstr "Podstawowe Zasoby" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:543 msgid "Optional Resources" msgstr "Opcjonalne Zasoby" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:544 msgid "Editor" msgstr "Edytor Map" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1033 msgid "Development" msgstr "NarzÄ™dzia dla programistów" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1081 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) zostaÅ‚o poprawnie usuniÄ™te z komputera." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1088 msgid "Uninstallation has failed!" msgstr "Odinstalowywanie nie powiodÅ‚o siÄ™!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1096 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Czy na pewno chcesz usunąć $(^Name) i wszystkie jego skÅ‚adniki?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1097 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Czy próbujesz odinstalować moda przed jego aktualizacjÄ…?$\\r$\n" "Wystarczy uruchomić instalator nowej wersji moda, żeby dokonać uaktualnienia i zachować swoje ustawienia." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1110 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Czy chcesz zachować utworzone pliki (takie jak Zasoby, zrzuty ekranu i ustawienia serwera)? JeÅ›li klikniesz Nie, wszystkie Zasoby, pliki konfiguracyjne i zrzuty ekranu jakie stworzyÅ‚eÅ› zostanÄ… usuniÄ™te." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1300 msgid "This installer requires admin access, try again" msgstr "Ten Instalator wymaga praw administratora do dziaÅ‚ania, spróbuj ponownie." #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1301 msgid "This uninstaller requires admin access, try again" msgstr "Ten Deinstalator wymaga praw administratora do dziaÅ‚ania, spróbuj ponownie." #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1302 msgid "Logon service not running, aborting!" msgstr "UsÅ‚uga Logon nie jest włączona, anulowanie instalacji!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1303 msgid "Unable to elevate" msgstr "Nie udaÅ‚o siÄ™ uzyskać praw administratora." #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1899 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "We wskazanym folderze zainstalowano już innÄ… wersjÄ™ głównÄ… MTA ($1 "Czy jesteÅ› pewien, że chcesz nadpisać MTA $1 w folderze $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1903 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA nie może być zainstalowane w tym samym folderze co GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1906 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Wskazany folder nie istnieje.$\n" "ProszÄ™ wskazać folder, gdzie zainstalowano grÄ™ GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1908 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Nie znaleziono gry GTA:SA we wskazanym folderze $GTA_DIR $\n" "Czy jesteÅ› pewien, że chcesz kontynuować instalacjÄ™?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2026 msgid "Choose Install Location" msgstr "Wybierz miejsce instalacji" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2027 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Wybierz folder, gdzie zainstalować ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2028 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} zostanie zainstalowane w nast " Kliknij przycisk Dalej aby kontynuować." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2030 msgid "Destination Folder" msgstr "Folder docelowy" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2031 msgid "Browse..." msgstr "PrzeglÄ…daj..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2032 msgid "Default" msgstr "DomyÅ›lny" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2033 msgid "Last used" msgstr "Ostatnio używany" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2034 msgid "Custom" msgstr "Niestandardowy" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2212 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Wybierz folder, gdzie ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} ma zostać zainstalowane:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2230 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Uwaga: W wybranym folderze znajduje siÄ™ już inna główna wersja MTA ($1)." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2231 msgid "Installation type: Upgrade" msgstr "Typ instalacji: Aktualizacja" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2465 msgid "Online update" msgstr "Aktualizacja Online" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2466 msgid "Checking for update information" msgstr "Sprawdzanie dostÄ™pnoÅ›ci aktualizacji" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2467 msgid "Checking for installer update information..." msgstr "Sprawdzanie dostÄ™pnoÅ›ci aktualizacji dla Instalatora..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2468 msgid "Please ensure your firewall is not blocking" msgstr "Upewnij siÄ™, że Twoja zapora sieciowa (firewall) nie blokuje Instalatora" diff --git a/Shared/installer/locale/pt_BR.pot b/Shared/installer/locale/pt_BR.pot index dcefdfe8c9f..6ea8fc80a99 100644 --- a/Shared/installer/locale/pt_BR.pot +++ b/Shared/installer/locale/pt_BR.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-14 17:23\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Portuguese, Brazilian\n" "Language: pt_BR\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "A versão do MTA:SA que você baixou não é compatível com o Windows XP ou Vista. Por favor, baixe uma versão alternativa em www.multitheftauto.com." #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "A versão do MTA:SA que você baixou não é compatível com Windows 7, 8 ou 8.1. Por favor, baixe uma versão alternativa em www.multitheftauto.com." #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "A versão do MTA:SA que você baixou foi projetada para versões antigas do Windows. Por favor, baixe uma versão alternativa em www.multitheftauto.com." #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Este assistente irá lhe guiar durante a instalação ou atualização d "Clique em Próximo para continuar." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Diretório de Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Pasta do Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Selecione a pasta onde Grand Theft Auto: San Andreas foi instalado.$\n" "Clique em Instalar para iniciar a instalação." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Cria um grupo no Menu Iniciar para as aplicações instaladas" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Cria um atalho do MTA:SA na Ãrea de Trabalho." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registra o protocolo mtasa:// para os navegadores redirecionarem algum link contendo este prefixo." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Adiciona ao Explorador de Jogos do Windows (se disponível)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Instala ou atualiza o DirectX (se necessário)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Os principais componentes necessários para executar o Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "A Modificação MTA:SA, que te permitirá jogar online." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "O Servidor do Multi Theft Auto. Ele permite hospedar um jogo a partir do seu computador. É necessário ter uma boa conexão com a internet." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "O Servidor do Multi Theft Auto. Este é um componente necessário." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "A modificação MTA:SA para o servidor." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Este é um conjunto de recursos necessários para o seu servidor." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Este é um conjunto opcional de modos de jogo e mapas para o seu servidor." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "O Editor de Mapas do MTA:SA 1.0. Ele é utilizado para criar seus próprios mapas para o seu modo de jogo do MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Este é o SDK (Kit de Desenvolvimento de Software) para criar módulos binários para o servidor do MTA. Instale apenas se tiver um bom conhecimento de C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Contém códigos e ferramentas com finalidade de auxiliar na criação de extensões para o Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "O cliente é o programa que lhe permite jogar em um servidor de MTA" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Cliente e Servidor" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Somente servidor" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Atalhos no Menu Iniciar" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Ãcone na Ãrea de Trabalho" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Registrar o protocolo mtasa://" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Atalho na pasta Jogos do Windows" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Instalar DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Cliente" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Servidor dedicado" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Componentes essenciais" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Módulo do Jogo" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Realizando uma atualização..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Atualizando permissões. Isto pode levar alguns minutos..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Uma versão válida do Grand Theft Auto: San Andreas para Windows não f "Por favor, reinstale caso houver problemas após a instalação." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Resources Principais" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Recursos Opcionais" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Editor" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Desenvolvimento" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) foi removido com sucesso de seu computador." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "A desinstalação falhou!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Você tem certeza que deseja remover completamente o $(^Name) e todos os seus componentes?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Desinstalar antes de atualizar?$\\r$\n" "Execute o novo instalador para atualizar e preservar as suas configurações." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Você gostaria de manter os seus dados (como recursos, capturas de tela e configurações do servidor)? Se você clicar em não, quaisquer recursos, configurações ou capturas de tela que você criou serão perdidos." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Este instalador necessita de acesso do administrador, tente novamente." #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Este desinstalador necessita de acesso do administrador, tente novamente." #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "O serviço 'Logon' não está em execução, a instalação será abortada!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Não foi possível obter o direito de execução necessário" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "A versão $1 do MTA já existe neste diretório.$\n" "Você tem certeza que deseja substituir o MTA $1 em $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "O MTA:SA não pode ser instalado no mesmo diretório do GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "O diretório selecionado não existe.$\n" "Selecione o diretório onde o GTA:SA está instalado" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Não foi possível encontrar o GTA:SA em $GTA_DIR $\n" "Você tem certeza que deseja continuar?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Selecione o local da Instalação" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Selecione a pasta em que será instalado o ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "O ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} será instalado na pasta sel "Clique em Seguinte para continuar." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Pasta de Destino" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Procurar..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Padrão" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Usado recentemente" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Customizado" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Selecione a pasta onde será instalado o ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} :" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Atenção: Uma outra versão do MTA ($1) já está instalada neste diretório." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Tipo de instalação: Atualização" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Atualização on-line" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Verificando informações da atualização" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Verificando informações do instalador..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Certifique-se que o seu firewall não esteja bloqueando este processo" diff --git a/Shared/installer/locale/pt_PT.pot b/Shared/installer/locale/pt_PT.pot index b7c97dac216..2aa61792796 100644 --- a/Shared/installer/locale/pt_PT.pot +++ b/Shared/installer/locale/pt_PT.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-14 17:23\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Portuguese\n" "Language: pt_PT\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "A versão do MTA:SA descarregada não é compatível com Windows XP ou o Vista. Por favor, descarregue uma versão alternativa a partir de www.multitheftauto.com." #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "A versão do MTA:SA descarregada não é compatível com Windows 7, 8 ou 8.1. Por favor, descarregue uma versão alternativa a partir de www.multitheftauto.com." #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "A versão do MTA:SA descarregada foi projetada para versões antigas do Windows. Por favor, descarregue uma versão alternativa a partir de www.multitheftauto.com." #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Este assistente irá guiá-lo através do processo de instalação ou at "Clique em Próximo para continuar." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Local do Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Pasta do Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Por favor selecione a sua pasta do Grand Theft Auto: San Andreas.$\n" "Clique em Instalar para começar a instalação." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Adiciona à barra \"Iniciar\"" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Cria um atalho no ambiente de trabalho para MTA:SA Client." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registra o protocolo mtasa:// para abrir com um browser." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Adiciona à pasta \"Jogos\" (se presente)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Instale ou atualize o DirectX (se necessário)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Principais componentes necessários para iniciar Multi Theft Auto" #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "Modificação MTA:SA, que permite jogar online." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Servidor Multi Theft Auto. Permite criar um servidor próprio a partir do seu PC. Isto requer uma ligação rápida à internet." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Servidor Multi Theft Auto. Este componente é obrigatório." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "Modificação MTA:SA para o servidor" #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Este é um conjunto de recursos necessários para o seu servidor." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Este é um conjunto opcional de modos de jogo e mapas para o seu servidor." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "O editor de mapas MTA:SA 1.0. Pode ser usado para criar os seus próprios mapas para utilizar em modos de jogo para o MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Isto é o SDK para criar módulos binários para o servidor MTA. Só instale se tiver um bom conhecimento de C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Código e ferramentas de desenvolvimento que auxiliam na criação de mods para Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "O cliente é o programa que você executa para jogar em um servidor Multi Theft Auto" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Cliente e Servidor" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Apenas servidor" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Grupo de menu inicial" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Ãcone da ambiente de trabalho" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Registrar o protocolo mtasa://" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Adicionar à pasta Jogos" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Instalar DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Cliente" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Servidor dedicado" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Componentes principais" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Módulo do jogo" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "A afetuar uma atualização..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "A atualizar permissões. Isto pode levar alguns minutos..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Uma versão válida do Grand Theft Auto: San Andreas para Windows não f "Por favor, reinstale se houver problemas mais tarde." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Recursos Principais" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Recursos Opcionais" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Editor" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Desenvolvimento" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) foi removido com sucesso do seu PC." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "A desinstalação falhou!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Tem a certeza que deseja remover completamente o $(^Name) e todos os seus componentes?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Desinstalar antes de atualizar?$\\r$\n" "Execute o novo instalador para atualizar e preservar as suas definições." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Gostaria de manter os seus ficheiros de dados (como recursos, capturas de ecrã e configuração do servidor)? Se clicar em não, quaisquer recursos, configurações ou capturas de ecrã que foram criados vão ser eliminados." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Este instalador requer privilégios de administrador, tente novamente" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Este desinstalador requer privilégios de administrador, tente novamente" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "O serviço início de sessão não está em execução, a terminar!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Não foi possível obter o direito de execução necessário" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Já existe uma diferente versão principal do MTA ($1) nesta localizaç " Tem a certeza que pretende substituir o MTA $1 em $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "O MTA não pode ser instalado na mesma pasta do GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "A pasta selecionada não existe.$\n" "Por favor selecione a pasta de instalação do GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Não foi possível encontrar o GTA:SA instalado em $GTA_DIR $\n" "Tem certeza que quer continuar?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Escolha o local de instalação" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Escolha a pasta para instalar o ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} será instalado na seguinta pa " Clique em Próximo para continuar." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Pasta de Destino" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Procurar..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Padrão" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Usado recentemente" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Personalizado" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Selecione a pasta para instalar o ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Atenção: Uma diferente versão principal do MTA ($1) já existe nesta localização." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Tipo de instalação: Atualização" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Atualização online" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "A verificar informações de atualização" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "A verificar informações do atualizador..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Por favor, certifique-se de que o seu firewall não está a bloquear" diff --git a/Shared/installer/locale/ro_RO.pot b/Shared/installer/locale/ro_RO.pot index 9dada635ae4..f20c8b9627f 100644 --- a/Shared/installer/locale/ro_RO.pot +++ b/Shared/installer/locale/ro_RO.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-09 05:01\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:19\n" "Last-Translator: \n" "Language-Team: Romanian\n" "Language: ro_RO\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "Versiunea de MTA:SA pe care ai descărcat-o nu este compatibilă cu Windows XP sau Vista. Te rugăm descarcă o versiune alternativă de pe www.multitheftauto.com." #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "Versiunea de MTA:SA pe care ai descărcat-o nu este compatibilă cu Windows 7, 8 sau 8.1. Te rugăm descarcă o versiune alternativă de pe www.multitheftauto.com." #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "Versiunea de MTA:SA pe care ai descărcat-o este destinată versiunilor vechi de Windows. Te rugăm descarcă o versiune alternativă de pe www.multitheftauto.com." #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Acest ghid te va ajuta la instalarea sau actualizarea $(^Name)${REVISION "Apasă pe Următorul pentru a continua." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "LocaÈ›ia Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Dosarul Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Vă rugăm să selectaÈ›i dosarul Grand Theft Auto: San Andreas.$\n" "Click pe Instalează pentru a începe." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Creează un grup în Meniul Start pentru aplicaÈ›iile instalate." #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Creează o scurtătură pe Desktop pentru Clientul MTA:SA." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "ÃŽnregistrează protocolul mtasa:// pentru acces rapid din browser." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Adaugă în Windows Games Explorer (dacă există)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Instalează sau actualizează DirectX (dacă este necesar)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Componentele principale, necesare pentru a rula Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "Modificarea MTA:SA, ce permite jocul online." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Serverul Multi Theft Auto. Acesta vă permite să găzduiÈ›i jocuri pe calculatorul dumneavoastră. Este necesară o conexiune rapidă la internet." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Serverul Multi Theft Auto. Acesta este un component necesar." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "Modificarea MTA:SA pentru server." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Acesta este un set de resurse necesare pentru serverul dumneavoastră." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Acesta este un set opÈ›ional de modificări de joc È™i hărÈ›i pentru serverul dumneavoastră." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "Editorul de hărÈ›i MTA:SA 1.0. Acesta poate fi folosit pentru a vă crea propriile hărÈ›i pentru modurile de joc pentru MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Acesta este SDK-ul pentru crearea modulelor binare ale serverului MTA. InstalaÈ›i numai dacă aveÈ›i un set de cunoÈ™tinÈ›e bun despre C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Cod È™i instrumente de dezvoltare ce ajută la crearea modificărilor pentru Multi Theft Auto." #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Clientul este programul pe care îl rulaÈ›i pentru a juca pe un server Multi Theft Auto." #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Client È™i Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Doar server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Grup în Meniul Start" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Pictogramă pe Desktop" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "ÃŽnregistrează protocolul mtasa://" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Adaugă în Games Explorer" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Instalează DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Client de joc" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Server dedicat" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Componente principale" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Modul de joc" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Se efectuează o actualizare pe loc..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Se actualizează permisiunile. Poate dura câteva minute..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "O versiune validă a Grand Theft Auto: San Andreas pentru Windows nu a f "Vă rugăm să reinstalaÈ›i dacă apar probleme mai târziu." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Resurse principale" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Resurse opÈ›ionale" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Editor" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Dezvoltare" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) a fost È™ters cu succes de pe calculatorul dumneavoastră." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Dezinstalarea a eÈ™uat!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "SunteÈ›i sigur că doriÈ›i sa eliminaÈ›i complet $(^Name) È™i toate componentele sale?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Dezinstalare înainte de actualizare?\\r$\n" "Execută noul fiÅŸier de instalare pentru a actualiza programul păstrând setările personale." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "DoriÈ›i să vă păstraÈ›i datele (cum ar fi resursele, capturile de ecran È™i configuraÈ›ia serverului)? Dacă apăsaÈ›i nu, orice resurse, configuraÈ›ii sau capturi de ecran create de dumneavoastră vor fi pierdute." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Acest program necesită acces de administrator, reîncercaÈ›i" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Acest dezinstalator necesită acces de administrator, reîncercaÈ›i" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Serviciul Logon nu rulează, se anulează!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Nu s-a putut eleva" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "O altă versiune majoră de MTA ($1) există deja în acel director.$\n" "Sigur doriÈ›i să înlocuiÈ›i MTA $1 din $INSTDIR?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA nu poate fi instalat în acelaÈ™i director cu GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Directorul selectat nu există.$\n" "SelectaÈ›i dosarul de instalare al GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Nu s-a găsit GTA:SA instalat în $GTA_DIR $\n" "SunteÈ›i sigur că vreÈ›i să continuaÈ›i?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "AlegeÈ›i locaÈ›ia instalării" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "AlegeÈ›i dosarul în care să instalaÈ›i ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} va fi instalat în dosarul urm "Apasă pe Următorul pentru a continua." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Dosarul destinaÈ›ie" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "RăsfoieÈ™te..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Implicită" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Ultima folosită" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Diferită" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "SelectaÈ›i dosarul instalării ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Avertisment: O altă versiune majoră de MTA ($1) există deja în acel director." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Tip de instalare: Actualizare" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Actualizare online" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Verificăm informaÈ›iile despre noua actualizare" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Verificăm informaÈ›iile pentru instalare..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Vă rugăm să vă asiguraÈ›i că firewall-ul dumneavoastră nu blochează" diff --git a/Shared/installer/locale/ru_RU.pot b/Shared/installer/locale/ru_RU.pot index 5e64c347871..3aaaee75977 100644 --- a/Shared/installer/locale/ru_RU.pot +++ b/Shared/installer/locale/ru_RU.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-06-13 10:31\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Russian\n" "Language: ru_RU\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "Ð—Ð°Ð³Ñ€ÑƒÐ¶ÐµÐ½Ð½Ð°Ñ Ð²Ð°Ð¼Ð¸ верÑÐ¸Ñ MTA:SA не поддерживает Windows XP или Vista. ПожалуйÑта, загрузите альтернативную верÑию Ñ Ñайта www.multitheftauto.com." #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "Ð—Ð°Ð³Ñ€ÑƒÐ¶ÐµÐ½Ð½Ð°Ñ Ð²Ð°Ð¼Ð¸ верÑÐ¸Ñ MTA:SA не поддерживает Windows 7, 8 или 8.1. ПожалуйÑта, Ñкачайте альтернативную верÑию Ñ Ñайта www.multitheftauto.com." #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "Ð—Ð°Ð³Ñ€ÑƒÐ¶ÐµÐ½Ð½Ð°Ñ Ð²Ð°Ð¼Ð¸ верÑÐ¸Ñ MTA:SA предназначена Ð´Ð»Ñ Ñтарых верÑий Windows. ПожалуйÑта, Ñкачайте альтернативную верÑию Ñ Ñайта www.multitheftauto.com." #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Этот уÑтановщик будет Ñопровождать Ð²Ð°Ñ "Ðажмите Далее Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "РаÑположение Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Путь до папки Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "ПожалуйÑта, выберите папку Grand Theft Auto: San "Ðажмите УÑтановить Ð´Ð»Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° уÑтановки." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Добавить пункт в меню \"ПуÑк\"" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Создать Ñрлык на рабочем Ñтоле." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "ЗарегиÑтрировать протокол mtasa:// Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ интернет-браузера." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Добавить в папку \"Игры\" (ЕÑли имеетÑÑ)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "УÑтановите или обновите DirectX (еÑли требуетÑÑ)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "ОÑновные компоненты, необходимые Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "ÐœÐ¾Ð´Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ MTA:SA, позволÑÑŽÑ‰Ð°Ñ Ð¸Ð³Ñ€Ð°Ñ‚ÑŒ по Ñети." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Сервер Multi Theft Auto. ПозволÑет запуÑтить Ñвой Ñервер Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº нему других игроков. ТребуетÑÑ Ð±Ñ‹Ñтрое интернет-Ñоединение." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Сервер Multi Theft Auto. Это необходимый компонент." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "ÐœÐ¾Ð´Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ MTA:SA Ð´Ð»Ñ Ñервера." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Это ÑпиÑок рекомендованных реÑурÑов Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ñервера." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Это ÑпиÑок необÑзательных игровых режимов и карт Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ñервера." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "Редактор карт MTA:SA 1.0. ИÑпользуетÑÑ Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñвоих ÑобÑтвенных карт, иÑпользуемых в игровых режимах Ð´Ð»Ñ MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "SDK Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¼Ð¾Ð´ÑƒÐ»ÐµÐ¹ Ð´Ð»Ñ MTA Ñервера. УÑтанавливайте, еÑли имеете опыт работы Ñ C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Программный код и ÑредÑтва, которые помогут в Ñоздании модификаций Ð´Ð»Ñ Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Клиент - Ñто программа, которую вы запуÑкаете Ð´Ð»Ñ Ð¸Ð³Ñ€Ñ‹ на Multi Theft Auto Ñерверах" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Клиент и Сервер" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Только Ñервер" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Меню \"ПуÑк\"" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Ярлык на рабочем Ñтоле" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "ЗарегиÑтрировать протокол mtasa://" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Добавить в папку \"Игры\"" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "УÑтановите DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Игровой клиент" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Выделенный Ñервер" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "ОÑновные компоненты" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Игровой модуль" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Обновление текущей уÑтановки..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Обновление прав. Это может занÑть неÑколько минут..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "ДопуÑÑ‚Ð¸Ð¼Ð°Ñ Windows-верÑÐ¸Ñ Grand Theft Auto: San Andreas "ПожалуйÑта, выполните переуÑтановку, еÑли поÑвÑÑ‚ÑÑ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ñ‹." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "ОÑновные реÑурÑÑ‹" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "ÐеобÑзательные РеÑурÑÑ‹" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Редактор" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Разработка" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) уÑпешно удалена Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ компьютера." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Ошибка удалениÑ!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Ð’Ñ‹ уверены, что хотите полноÑтью удалить $(^Name) и вÑе её компоненты?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Удалить перед обновлением?$\\r$\n" "ЗапуÑтите новый файл уÑтановки Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐ¸Ñ… данных." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Сохранить пользовательÑкие данные (реÑурÑÑ‹, Ñнимки Ñкрана и наÑтройки Ñервера)? ЕÑли нет, вÑе ваши реÑурÑÑ‹, наÑтройки и Ñнимки Ñкрана будут утерÑны." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Ð”Ð»Ñ ÑƒÑтановки необходимы права админиÑтратора, повторите еще раз" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Ð”Ð»Ñ ÑƒÐ½Ð¸Ð½Ñталлер требует права админиÑтратора, повторите еще раз" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Ð¡ÐµÑ€Ð²Ð¸Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ð¸ не запущен, завершение!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "ЗапуÑк невозможен" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "ВерÑÐ¸Ñ Ð½Ð¾Ð²ÐµÐµ MTA ($1) уже уÑтановлена по ÑÑ‚ "Ð’Ñ‹ уверены, что хотите перезапиÑать MTA $1 в $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA не может быть уÑтановлено в той же ди "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Выбранной директории не ÑущеÑтвует.$\n" "ПожалуйÑта, выберите директорию Ñ GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "GTA:SA не найдена по адреÑу $GTA_DIR $\n" "Ð’Ñ‹ уверены, что хотите продолжить?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Выберите директорию уÑтановки" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Выберите папку Ð´Ð»Ñ ÑƒÑтановки ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} будет уÑтановле "Ðажмите Далее Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Ð”Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð£Ñтановки" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Обзор…" #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "По умолчанию" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "ПоÑледнÑÑ Ð¸ÑпользованнаÑ" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Другой" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Выберите папку Ð´Ð»Ñ ÑƒÑтановки ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Предупреждение: Более ÑÐ²ÐµÐ¶Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ MTA ($1) уже уÑтановлена по указанному пути." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Тип уÑтановки: Обновление" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Онлайн обновление" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Проверить обновлениÑ" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Проверка обновлений уÑтановщика..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "ПожалуйÑта, убедитеÑÑŒ, что ваш брандмауÑÑ€ не блокирует" diff --git a/Shared/installer/locale/sk_SK.pot b/Shared/installer/locale/sk_SK.pot index f775743ba1f..eb636df1642 100644 --- a/Shared/installer/locale/sk_SK.pot +++ b/Shared/installer/locale/sk_SK.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Slovak\n" "Language: sk_SK\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Tento sprievodca Vás povedie poÄas inÅ¡talácie alebo aktualizácie $( "Kliknite na ÄŽalej pre pokraÄovanie." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Umiestnenie Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "PrieÄinok s Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Prosím vyberte prieÄinok s Grand Theft Auto: San Andreas.$\n" "Pre zaÄatie inÅ¡talácie kliknite na InÅ¡talovaÅ¥." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "PridaÅ¥ zástupcu do menu Å tart" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "PridaÅ¥ odkaz na plochu." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "ZaregistrovaÅ¥ protokol mtasa:// v prehliadaÄoch." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "PridaÅ¥ do Hier Windows (ak sú k dispozícií)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "NainÅ¡talujte alebo aktualizujte DirectX (ak je to potrebné)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Hlavné súÄasti potrebné k fungovaniu Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "SúÄasÅ¥ MTA:SA pre server" #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto Server. Umožňuje vytvoriÅ¥ server spustený z Vášho poÄítaÄa. Vyžaduje sa rýchle internetové pripojenie." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto server. Toto je potrebná súÄasÅ¥." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "SúÄasÅ¥ MTA:SA pre server." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Toto je zoznam vyžadovaných doplnkov pre Váš server." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Toto je voliteľný zoznam herných módov a máp pre Váš server." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 mapový editor. Môžete ho použiÅ¥ na vytvorenie vlastnej mapy ktorú použijete v niektorom hernom móde MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Toto je SDK - sada nástrojov pre vývojára. InÅ¡talujte iba ak máte dobré znalosti C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Vývojový kód a nástroje ktoré pomáhajú pri vytváraní módov pre Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Klient je program ktorý spustíte pre hranie na Multi Theft Auto serveri" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Klient a Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Len Server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Zástupca v menu Å tart" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Ikona na ploche" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "ZaregistrovaÅ¥ mtasa:// protokol" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "PridaÅ¥ do Hier Windows" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "NainÅ¡talujte DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Herný klient" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Dedikovaný server" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Hlavné súÄasti" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Herný modul" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Prevedenie miestnej aktualizácie..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Aktualizácia oprávnení. Toto môže trvaÅ¥ niekoľko minút..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Platná Windows verzia hry Grand Theft Auto: San Andreas nebola nájden "PreinÅ¡talujte MTA v prípade neskorších problémov." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Hlavné SúÄasti" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Voliteľné SúÄasti" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Mapový editor" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Vývoj" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) bol úspeÅ¡ne odstránený z Vášho poÄítaÄa." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "OdinÅ¡talácia neúspeÅ¡ná!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Ste si istý že chcete kompletne odstrániÅ¥ $(^Name) a vÅ¡etky jeho súÄasti?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "OdinÅ¡talovanie pred aktualizovaním?$\\r$\n" "Spustite novú inÅ¡taláciu, aby ste aktualizovali a zachovali svoje nastavenia." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Chcete ponechaÅ¥ VaÅ¡e osobné súbory (ako doplnky, screenshoty a nastavenie servera)? Ak kliknete na nie, vÅ¡etky doplnky, nastavenia a screenshoty ktoré ste vytvorili budú zmazané." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Tento inÅ¡talátor vyžaduje administrátorský prístup, skúste to znovu" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Tento odinÅ¡talátor vyžaduje administrátorský prístup, skúste to znovu" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Prihlasovacia služba nie je spustená, ukonÄenie!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Nemožno povýšiÅ¥" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "OdliÅ¡ná hlavná verzia MTA ($1) existuje v danom umiestnení.$\n" "Ste si istý, že chcete nahradiÅ¥ MTA $1 v $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA nemožno nainÅ¡talovaÅ¥ do rovnakého adresára ako GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Vybratý prieÄinok neexistuje.$\n" "Prosím zvoľte prieÄinok s hrou GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Nemožno nájsÅ¥ hru GTA:SA nainÅ¡talovanú v $GTA_DIR $\n" "Ste si istý že chcete pokraÄovaÅ¥?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Vyberte umiestnenie inÅ¡talácie" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Vyberte prieÄinok do ktorého chcete nainÅ¡talovaÅ¥ ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} bude nainÅ¡talovaný do nasled "Kliknite na ÄŽalej pre pokraÄovanie." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Cieľový prieÄinok" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "PrehľadávaÅ¥..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Predvolené" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Naposledy použité" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "PokroÄilé" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Vyberte prieÄinok pre inÅ¡taláciu ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Varovanie: OdliÅ¡ná hlavná verzia MTA ($1) existuje v danom umiestnení." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Typ inÅ¡talácie: Aktualizácia" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Online aktualizácia" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Hľadajú sa informácie o aktualizácii" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Hľadajú sa informácie o aktualizácii inÅ¡talátora..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Uistite sa, že váš firewall neni blokovaný" diff --git a/Shared/installer/locale/sl_SI.pot b/Shared/installer/locale/sl_SI.pot index 6b331fc0879..09348068515 100644 --- a/Shared/installer/locale/sl_SI.pot +++ b/Shared/installer/locale/sl_SI.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Slovenian\n" "Language: sl_SI\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Ta Äarovnik vas bo vodil skozi nameÅ¡Äanje ali posodabljanje programa "Klikni naprej za nadaljevanje." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Lokacija Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas mapa" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Prosimo izberite mapo, kjer je nameÅ¡Äen Grand Theft Auto: San Andreas. "Kliknite Namestitev za zaÄetek nameÅ¡Äanja." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Ustvari skupino na Start meniju za nameÅ¡Äene aplikacije" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Ustvari namizno bližnjico za MTA:SA Klient." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registrirajte mtasa:// protokol za klikanje po brskalniku." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Dodaj na Windows Games Explorer (Äe obstaja)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "" #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Glavne komponente, ki so potrebne za zagon Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA modifikacija ti dovoljuje, da igraÅ¡ preko interneta." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto Strežnik. To ti dovoljuje, da preko svojega raÄunalnika gostujeÅ¡ igre. Potrebna je hitra internetna povezava." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto strežnik. To je potrebna komponenta." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA modifikacija za strežnik." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "To je niz potrebnih virov za vaÅ¡ strežnik." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "To je neobvezen niz naÄinov igranja in map za vaÅ¡ strežnik." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 Urejevalnik map. To se uporablja za ustvarjanje lastnih map za razliÄne igralske naÄine v MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "To je SDK za ustvarjanje binarnih modulov za MTA strežnik. Namestite samo, Äe dobro razumete jezik C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Razvojna koda in orodja ki pomagajo pri ustvarjanju modifikacij za Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Klient je program, ki ga zaženete za igranje na Multi Theft Auto strežnikih" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Klient in strežnik" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Samo strežnik" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Skupina v start meniju" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Namizna ikona" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Registriraj mtasa:// protokol" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Dodaj na Games Explorer" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Klient za igro" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "PosveÄen strežnik" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Bistveni elementi" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Modul igre" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Opravljanje nadgradnje na mestu..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Posodabljanje dovoljenj. To lahko traja nekaj minut..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,74 +221,74 @@ msgstr "Veljavne Windows razliÄice Grand Theft Auto: San Andreas ni bilo mogoÄ "Prosimo, da ponovno namestite program, Äe se pozneje pojavijo problemi." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "KljuÄni viri" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Neobvezni viri" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Urejevalnik" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Razvoj" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) je bil uspeÅ¡no odstranjen iz vaÅ¡ega raÄunalnika." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Med odstranitvijo je priÅ¡lo do napake!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Ali ste prepriÄani, da želite popolnoma odstraniti $(^Name) in vse njegove komponente?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." msgstr "" #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Ali želite obdržati podatkovne datoteke (kot so viri, posnetki zaslona in konfiguracije strežnika)? ÄŒe kliknete ne, bodo vsi viri, konfiguracije ali posnetki zaslona ki ste jih ustvarili, izgubljeni." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Za nameÅ¡Äanje potrebujete dovoljenje administratorja, poskusite znova" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Za odstranitev potrebujete dovoljenje administratorja, poskusite znova" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Prijavna storitev ne teÄe, prekinjam!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Ni mogoÄe elevirati" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -299,7 +299,7 @@ msgstr "DrugaÄna glavna razliÄica programa MTA ($1) že obstaja na tej poti.$\ "Ali ste prepriÄani da želite prepisati MTA $1 v $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -307,7 +307,7 @@ msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" msgstr "" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -316,7 +316,7 @@ msgstr "Izbrana pot ne obstaja.$\n" "Prosimo, izberite pot, kjer je nameÅ¡Äen GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -325,17 +325,17 @@ msgstr "Ni bilo mogoÄe najti GTA:SA v $GTA_DIR $\n" "Ali ste prepriÄani da želite nadaljevati ?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Izberite lokacijo namestitve" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Izberite mapo kamor hoÄete namestiti ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -346,62 +346,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} bo nameÅ¡Äen v naslednjo mapo "Kliknite Naprej za nadaljevanje." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Ciljna mapa" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "IÅ¡Äi..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Privzeto" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Nazadnje uporabljeno" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Po meri" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Izberite mapo kjer želite namestiti ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} :" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Opozorilo: Na tej poti že obstaja glavna razliÄica MTA ($1) ." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Vrsta namestitve: Nadgradnja" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "" #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "" diff --git a/Shared/installer/locale/srp.pot b/Shared/installer/locale/srp.pot index 6ccdfe5282b..e4c3b0941be 100644 --- a/Shared/installer/locale/srp.pot +++ b/Shared/installer/locale/srp.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Serbian\n" "Language: srp\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "Verzija MTA:SA koju ste skinuli ne podržava Windows XP niti Vistu. Molimo vas skinite drugu verziju sa www.multitheftauto.com." #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "Verzija MTA:SA koju ste preuzeli ne podržava Windows 7, 8 ili 8,1. Molimo vas preuzmite drugu verziju sa www.multitheftauto.com." #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "Verzija MTA:SA koju ste preuzeli je dizajnirana za starije verzije Windows-a. Molimo vas preuzmite drugu verziju sa www.multitheftauto.com." #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Ovaj program će vas sprovesti kroz instalaciju ili ažuriranje $(^Name) "Kliknite \"Dalje\" da nastavite." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Lokacija Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas direktorijum" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Odaberite direktorijum gde je instaliran Grand Theft Auto: San Andreas.$ "Kliknite \"Instaliraj\" da bi ste zapoÄeli instalaciju." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Napraviti Start Menu grupu za instalirane aplikacije" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Napraviti Desktop preÄicu za MTA:SA." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registrovati mtasa:// protokol za kliktivost pretraživaÄa." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Dodaj u Windows Games Explorer (ako postoji)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Instaliraj ili ažuriraj DirectX (ukoliko je potrebno)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "KljuÄne komponente potrebne za pokretanje Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA modifikacija, omogućava vas da igrate online." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto Server. Ovo vam omogućava da hostujete igre na vaÅ¡em raÄunaru. Zahteva brzu internet konekciju." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto server. Ovo je neophodna komponenta." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA modifikacija za server." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Ovo je skup neophodnih resursa za vaÅ¡ server." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Ovo je opcionalni skup modova igre i mapa za vaÅ¡ server." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA Urednik Mape. Koristi se u svrhu stvaranja vaÅ¡e liÄne mape za vaÅ¡ mod igre za MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Ovo je SDK za stvaranje binarnih modula za MTA server. Instalirajte iskljuÄivo ako se dobro razumete u C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Razvojni kod i alat koji će vam pomoći pri stvaranju modova za Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Klijent je program koji pokrećete da bi igrali na Multi Theft Auto serveru" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Klijent i Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Samo Server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Start menu grupa" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Desktop ikonica" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Registrovati mtasa:// protokol" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Dodati u Games Explorer" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Instalirati DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Klijent igre" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Namenski server" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "KljuÄne komponente" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Modul igre" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "IzvrÅ¡avanje nadogradnje na mestu..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Ažuriranje dozvola. Može potrajati par minuta..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Validna Windows verzija Grand Theft Auto: San Andreas nije detektovana.$ "Molimo vas ponovo instalirajte u sluÄaju da kasnije nastane problem." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "KljuÄni Resursi" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Opcionalni resursi" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Urednik" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Razvoj" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) je uspeÅ¡no uklonjen sa vaÅ¡eg raÄunara." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Uklanjanje nije uspelo!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Da li ste sigurni da želite potpuno ukloniti $(^Name) i sve njegove komponente?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Ukloniti pre nadogradnje?$\\r$\n" "Pokrenite novi installer da nadogradite i saÄuvate vaÅ¡a podeÅ¡avanja." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Da li želite da saÄuvate datoteke sa podacima (kao na primer resurse, screenshot-ove i konfiguracije servera)? Ako kliknete ne, svi resursi, konfiguracije ili screenshot-ovi koje ste napravili biće izgubljeni." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Ovaj installer zahteva administratorski pristup, pokuÅ¡ajte ponovo" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Ovaj uninstaller zahteva administratorski pristup, pokuÅ¡ajte ponovo" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Servis za prijavljivanje ne radi, prekidanje!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Onemogućeno povećanje" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Druga glavna verzija MTA ($1) već postoji na ovoj putanji.$\n" "Da li ste sigurni da želite pisati preko MTA $1 u $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA ne može biti instaliran na istoj lokaciji kao GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Odabrani direktorijum ne postoji.$\n" "Molimo vas odaberite GTA:SA direktorijum instalacije" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Nismo mogli da pronaÄ‘emo GTA:SA instaliran na $GTA_DIR $\n" "Da li ste sigurni da želite da nastavite?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Odaberi lokaciju instalacije" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Odaberi direktorijum gde će biti instaliran ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} biće instalirana u direktorij " Kliknite Dalje da nastavite." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "OdrediÅ¡ni direktorijum" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Izaberi..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Podrazumevano" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Poslednja korišćena" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "PrilagoÄ‘eno" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Odaberite direktorijum gde će biti instaliran ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Upozorenje: Druga glavna verzija MTA ($1) već postoji na ovoj putanji." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Tip instalacije: Nadogradnja" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Online ažuriranje" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Provera za informacije o ažuriranju" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Provera za installer informacije o ažuriranju..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Molimo vas uverite se da vaÅ¡ firewall ne blokira" diff --git a/Shared/installer/locale/sv_SE.pot b/Shared/installer/locale/sv_SE.pot index 096410f7d29..edba77d836c 100644 --- a/Shared/installer/locale/sv_SE.pot +++ b/Shared/installer/locale/sv_SE.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Swedish\n" "Language: sv_SE\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Den här guiden leder dig genom installationen eller uppdateringen av $( "Klicka pÃ¥ Nästa för att fortsätta." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreas plats" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas mapp" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Vänligen välj din Grand Theft Auto: San Andreas mapp.$\n" "Klicka pÃ¥ Installera för att pÃ¥börja installationen." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Skapa en grupp i startmenyn för installerade program" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Skapa en skrivbordsgenväg till MTA:SA Klienten." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Registrera mtasa:// protokollet för webbläsarklickbarhet." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Lägg till i Windows Spelutforskaren (om sÃ¥dan finns)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "" #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "De centrala komponentera som krävs för att köra Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA modifikationen, sÃ¥ att du kan spela online." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto Servern. Detta ger dig möjlighet att vara värd för spel frÃ¥n din dator. Detta kräver en snabb internetuppkoppling." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto servern. Detta är en nödvändig komponent." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA modifikationen till server." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Detta är en uppsättning av nödvändiga resurser för din server." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Detta är en valfri uppsättning spellägen och kartor för din server." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 Kartskapare. Detta kan användas för att skapa dina alldeles egna kartor för användning i spellägen för MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Detta är en SDK för att skapa binära moduler för MTA-servern. Installera bara om du har en god förstÃ¥else för C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Utvecklingskod och verktyg som hjälper dig i skapandet av mods för Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Klienten är programmet du kör för att spela pÃ¥ en Multi Theft Auto server" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Klient och Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Bara server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Startmenygrupp" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Skrivbordsikon" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Registrera mtasa:// protokoll" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Lägg till i Spelutforskaren" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Spelklient" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Dedikerad server" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Centrala komponenter" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Spelmodul" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Utför uppgradering..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Uppdaterar behörigheter. Detta kan ta nÃ¥gra minuter..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,74 +221,74 @@ msgstr "En giltig Windows version av Grand Theft Auto: San Andreas hittades inte "Var god installera om, om det blir problem senare." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "Centrala resurser" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Valfria resurser" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Redigerare" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Utveckling" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) har tagits bort frÃ¥n datorn." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Avinstallationen misslyckades!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Är du säker pÃ¥ att du vill ta bort $(^Name) och alla dess komponenter?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." msgstr "" #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Vill du behÃ¥lla dina datafiler (t.ex. resurser, skärmdumpar och serverkonfiguration)? Om du klickar pÃ¥ nej kommer alla resurser, konfigurationer eller skärmdumpar som du har skapat att förloras." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Detta installationsprogram kräver administratörsbehörighet, försök igen" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Denna avinstallerare kräver administratörsbehörighet, försök igen" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Inloggningstjänsten körs inte, avbryter!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "Kunde inte höja" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -299,7 +299,7 @@ msgstr "En annan huvudversion av MTA ($1) finns redan i den sökvägen.$\n" " Är du säker pÃ¥ att du vill skriva över MTA $1 i $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -307,7 +307,7 @@ msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" msgstr "" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -316,7 +316,7 @@ msgstr "Den valda sökvägen finns inte.$\n" "Var god välj GTA:SA installationsmappen" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -325,17 +325,17 @@ msgstr "Kunde inte hitta GTA:SA installerat i $GTA_DIR $\n" "Är du säker pÃ¥ att du vill fortsätta ?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Välj Installationsmapp" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Välj mapp att installera ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -346,62 +346,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} kommer att installeras i följ " Klicka pÃ¥ Nästa för att fortsätta." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Destinationsmapp" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Bläddra..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Standard" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Senast använd" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Anpassad" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Välj mapp att installera ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} i:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Varning: En annan huvudversion av MTA ($1) finns redan i den sökvägen." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Installationstyp: Uppgradera" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "" #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "" diff --git a/Shared/installer/locale/tr_TR.pot b/Shared/installer/locale/tr_TR.pot index 427e74c4691..4c232cff7da 100644 --- a/Shared/installer/locale/tr_TR.pot +++ b/Shared/installer/locale/tr_TR.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-19 01:08\n" +"PO-Revision-Date: 2026-02-16 02:50\n" "Last-Translator: \n" "Language-Team: Turkish\n" "Language: tr_TR\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 -msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." -msgstr "" +#: Shared/installer/nightly.nsi:206 +msgid "Multi Theft Auto does not support Windows XP or Vista. Please upgrade your computer." +msgstr "Multi Theft Auto, Windows XP veya Vista'yı desteklemez. Lütfen bilgisayarınızı yükseltin." #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "İndirdiÄŸiniz MTA:SA sürümü Windows 7, 8 veya 8.1'i desteklemiyor. Lütfen www.multitheftauto.com adresinden alternatif bir sürüm indirin." #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "İndirdiÄŸiniz MTA:SA sürümü eski Windows sürümleri için tasarlanmıştır. Lütfen www.multitheftauto.com adresinden alternatif bir sürüm indirin." #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Bu sihirbaz $(^Name) ${REVISION_TAG} kurulum ve güncelleÅŸtirmesi için "Devam etmek için İleri tıklayın." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Grand Theft Auto: San Andreas konumu" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Grand Theft Auto: San Andreas klasörü" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Lütfen Grand Theft Auto: San Andreas oyununun kurulu olduÄŸu yeri seçi "Kurulumu baÅŸlatmak için tıklayın." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Yüklü uygulamalar için baÅŸlat menüsü grubu oluÅŸtur." #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "MTA:SA masaüstü kısayolu oluÅŸtur." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Tarayıcınızda tıklanabilir mtasa:// protokolünü kaydet." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Windows Games Tarayıcısına ekleyin. (Varsa)" #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "DirectX'i yükle veya güncelle (eÄŸer gerekliyse)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Temel bileÅŸenler, Multi Theft Auto'yu çalıştırmak için gerekli." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA, online oynamanıza imkan saÄŸlar." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto Sunucusu. Bu, bilgisayarınızdan sunucu kurabilmenizi saÄŸlar. Hızlı bir internet baÄŸlantısı gerektirir." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto sunucusu. Bu gerekli bir bileÅŸendir." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "Sunucu içi MTA:SA modifikasyonu." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Sunucu için gerekli kaynakların listesi." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Sunucunuz için isteÄŸe baÄŸlı oyun modları ve haritalar." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 Harita Editörü. Kendi haritalarınızı oluÅŸturmak için kullanabilirsiniz." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "SDK, MTA sunucuları için binary modül oluÅŸturmada kullanılır. Sadece C++ dilini biliyorsanız kurun!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "GeliÅŸtirici kodları ve araçlar Multi Theft Auto için mod oluÅŸturmada yardımcı olur" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "İstemci, bir Multi Theft Auto sunucusu üzerinde oynamak için kullanacağınız programdır" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:479 msgid "Client and Server" msgstr "İstemci ve Sunucu" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:480 msgid "Server only" msgstr "Sadece sunucu" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:494 msgid "Start menu group" msgstr "BaÅŸlat menüsü grubu" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:495 msgid "Desktop icon" msgstr "Masaüstü simgesi" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:496 msgid "Register mtasa:// protocol" msgstr "mtasa:// protokolünü kaydet" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:497 msgid "Add to Games Explorer" msgstr "Oyun tarayıcısına ekle" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:498 msgid "Install DirectX" msgstr "DirectX'i kur" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:532 msgid "Game client" msgstr "Oyun istemcisi" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:533 msgid "Dedicated server" msgstr "Özel sunucu" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:534 msgid "Core components" msgstr "Temel bileÅŸenler" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:535 msgid "Game module" msgstr "Oyun modülü" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:537 msgid "Performing in-place upgrade..." msgstr "Güncelleme gerçekleÅŸtiriliyor..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:538 msgid "Updating permissions. This could take a few minutes..." msgstr "Yetkiler güncelleniyor. Bu birkaç dakika sürebilir..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:539 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Geçerli bir Grand Theft Auto: San Andreas versiyonu bulunamadı.$\\r$\n "EÄŸer herhangi bir sorunla karşılaşırsanız tekrar yükleyin." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:542 msgid "Core Resources" msgstr "Temel Kaynaklar" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:543 msgid "Optional Resources" msgstr "İsteÄŸe BaÄŸlı Kaynaklar" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:544 msgid "Editor" msgstr "Editör" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1033 msgid "Development" msgstr "GeliÅŸtirme" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1081 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) bilgisayarınızdan sorunsuz bir ÅŸekilde silindi." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1088 msgid "Uninstallation has failed!" msgstr "Kaldırma baÅŸarısız oldu!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1096 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "$(^Name) ve bileÅŸenlerini tamamen kaldırmak istediÄŸinize emin misiniz?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1097 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Güncellemeden önce mi kaldırıyorsunuz?$\\r$\n" "Oyunu güncellemek ve ayarlarınızı korumak için yeni versiyonun kurulumunu baÅŸlatmanız yeterli." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1110 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Veri dosyalarınızı kaydetmek ister misiniz (kaynaklar, ekran görüntüleri ve sunucu ayarları)? EÄŸer hayıra basarsanız bütün ayarlarınız silinecektir." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1300 msgid "This installer requires admin access, try again" msgstr "Bu kurulum sihirbazı, yönetici izni gerektiriyor. Tekrar deneyin" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1301 msgid "This uninstaller requires admin access, try again" msgstr "Bu kaldırma sihirbazı, yönetici izni gerektiriyor. Tekrar deneyin" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1302 msgid "Logon service not running, aborting!" msgstr "Oturum Açma hizmeti çalışmıyor, iptal ediliyor!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1303 msgid "Unable to elevate" msgstr "Yükseltilemedi" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1899 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Farklı bir MTA ($1) ana sürümü zaten burada bulunmaktadır. $\n" " $INSTDIR konumundaki MTA $1 üzerine kurulum yapmak istediÄŸinizden emin misiniz?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1903 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA, GTA:SA ile aynı dizine kurulamaz.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1906 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Seçilen dizin bulunamıyor.$\n" "Lütfen GTA:SA kurulum yerini seçiniz" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1908 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr " $GTA_DIR konumunda GTA:SA bulunamadı $\n" "Devam etmek istediÄŸinize emin misiniz?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2026 msgid "Choose Install Location" msgstr "Kurulum yerini seçiniz" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2027 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} kurmak istediÄŸiniz klasörü seçiniz" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2028 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} bu klasöre kurulacaktır.$\n" "Devam etmek için İleri tuÅŸuna basın." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2030 msgid "Destination Folder" msgstr "Hedef Klasör" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2031 msgid "Browse..." msgstr "Gözat..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2032 msgid "Default" msgstr "Varsayılan" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2033 msgid "Last used" msgstr "Son kullanılan" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2034 msgid "Custom" msgstr "Özel" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2212 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} kurmak istediÄŸiniz klasörü seçin:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2230 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Uyarı: BaÅŸka bir MTA ($1) ana sürümü zaten bu konumda mevcut." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2231 msgid "Installation type: Upgrade" msgstr "Kurulum tipi: Güncelleme" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2465 msgid "Online update" msgstr "Çevrimiçi güncelleme" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2466 msgid "Checking for update information" msgstr "Güncelleme bilgileri kontrol ediliyor" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2467 msgid "Checking for installer update information..." msgstr "Kurulum sihirbazı güncellemesi kontrol ediliyor..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2468 msgid "Please ensure your firewall is not blocking" msgstr "Lütfen güvenlik duvarınızın engel olmadığına emin olun" diff --git a/Shared/installer/locale/uk_UA.pot b/Shared/installer/locale/uk_UA.pot index e6dfa0b8861..7843d1be164 100644 --- a/Shared/installer/locale/uk_UA.pot +++ b/Shared/installer/locale/uk_UA.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Ukrainian\n" "Language: uk_UA\n" @@ -18,22 +18,24 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "ВерÑÑ–Ñ MTA:SA, Ñку ви завантажили, не підтримує Windows XP або Vista.\n" +"Будь лаÑка, завантажте альтернативну верÑÑ–ÑŽ з www.multitheftauto.com." #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." -msgstr "" +msgstr "ВерÑÑ–Ñ MTA:SA, Ñку ви завантажили, призначена Ð´Ð»Ñ Ñтарих верÑій Windows.\n" +"Будь лаÑка, завантажте альтернативну верÑÑ–ÑŽ з www.multitheftauto.com." #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +46,17 @@ msgstr "Цей інÑталÑтор буде Ñупроводжувати Ð²Ð°Ñ "ÐатиÑніть кнопку Далі, щоб продовжити." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "Ð Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "ШлÑÑ… до теки Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +69,152 @@ msgstr "Будь лаÑка, виберіть теку Grand Theft Auto: San And "ÐатиÑніть ІнÑталювати Ð´Ð»Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° вÑтановленнÑ." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Додати пункт в меню \"ПуÑк\"" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Створити Ñрлик на робочому Ñтолі." #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "ЗареєÑтрувати протокол mtasa:// Ð´Ð»Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð·Ð° допомогою веб-браузера." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Додати в теку \"Ігри\" (Якщо у Ð²Ð°Ñ Ñ”)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "ІнÑталювати або оновити DirectX (Ñкщо потрібно)" #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "ОÑновні компоненти, необхідні Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑку Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "ÐœÐ¾Ð´Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ MTA:SA, що дозволÑÑ” грати по мережі." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Сервер Multi Theft Auto. ДозволÑÑ” запуÑтити Ñвій Ñервер Ð´Ð»Ñ Ð¿Ñ–Ð´'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ нього інших гравців. Потрібне швидке інтернет-з'єднаннÑ." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Сервер Multi Theft Auto. Це необхідний компонент." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "ÐœÐ¾Ð´Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ MTA:SA Ð´Ð»Ñ Ñервера." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Це ÑпиÑок рекомендованих реÑурÑів Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ Ñервера." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Це перелік необов'Ñзкових ігрових режимів Ñ– карт Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ Ñервера." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "Редактор карт MTA:SA 1.0. ВикориÑтовуєтьÑÑ Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñвоїх влаÑних карт, викориÑтовуваних в ігрових режимах Ð´Ð»Ñ MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "SDK Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ–Ð² Ð´Ð»Ñ MTA Ñервера. ІнÑталюйте, Ñкщо маєте доÑвід роботи з C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Програмний код Ñ– заÑоби, Ñкі допоможуть у Ñтворенні модифікацій Ð´Ð»Ñ Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Клієнт - це програма, Ñку ви запуÑкаєте Ð´Ð»Ñ Ð³Ñ€Ð¸ на Multi Theft Auto Ñерверах" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Клієнт Ñ– Сервер" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Тільки Ñервер" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Меню \"ПуÑк\"" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "Ярлик на робочому Ñтолі" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "ЗареєÑтрувати протокол mtasa://" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Додати в теку \"Ігри\"" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "ІнÑталÑÑ†Ñ–Ñ DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "Ігровий клієнт" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "Виділений Ñервер" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "ОÑновні компоненти" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Ігровий модуль" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¾Ñ— інÑталÑції..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð°Ð². Це може зайнÑти кілька хвилин..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +223,42 @@ msgstr "ДопуÑтима Windows-верÑÑ–Ñ Grand Theft Auto: San Andreas н "Будь лаÑка, виконайте переінÑталюваннÑ, Ñкщо з'ÑвлÑтьÑÑ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¸." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "ОÑновні реÑурÑи" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "Ðеобов'Ñзкові РеÑурÑи" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "Редактор" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "Розробка" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) уÑпішно видалено з вашого комп'ютера." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Помилка видаленнÑ!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Ви впевнені, що хочете повніÑтю видалити $(^Name) Ñ– вÑÑ– Ñ—Ñ— компоненти?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +267,32 @@ msgstr "Видалити перед оновленнÑм?$\\r$\n" "ЗапуÑтіть новий файл інÑталÑції Ð´Ð»Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ‚Ð° Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ð°ÑˆÐ¸Ñ… даних." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Бажаєте зберегти ваші дані (реÑурÑи, знімки та Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñервера)? Якщо ні, то вÑÑ– ваші реÑурÑи, Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ– знімки буде втрачено." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Ð”Ð»Ñ Ñ–Ð½ÑталÑції необхідно мати права адмініÑтратора, повторіть ще раз" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Цей уніÑталер вимагає права адмініÑтратора, повторіть ще раз" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Ð¡ÐµÑ€Ð²Ñ–Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ñ–Ñ— не запущено, завершеннÑ!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "ЗапуÑк неможливий" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +303,7 @@ msgstr "ВерÑÑ–Ñ Ð½Ð¾Ð²Ñ–ÑˆÐµ MTA ($1) вже інÑтальовано ​ "Ви впевнені, що хочете перезапиÑати MTA $1 в $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +314,7 @@ msgstr "MTA не може бути вÑтановлено в тій же дир "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +323,7 @@ msgstr "Вибраної директорії не Ñ–Ñнує.$\n" "Будь лаÑка, виберіть директорію з GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +332,17 @@ msgstr "GTA:SA не знайдено за адреÑою $GTA_DIR $\n" "Ви впевнені, що хочете продовжити?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Виберіть директорію інÑталÑції" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Виберіть теку Ð´Ð»Ñ Ñ–Ð½ÑталÑції ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +353,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} буде вÑтановлен "ÐатиÑніть Далі Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Ð”Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ñ–Ñ Ð†Ð½ÑталÑції" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "ОглÑд..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "За промовчаннÑм" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "ОÑтаннє викориÑтаннÑ" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Інший" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Виберіть теку, щоб інÑталювати ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "ПопередженнÑ: Більш Ñвіжа верÑÑ–Ñ MTA ($1) вже вÑтановлена ​​Ñюди ж." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Тип інÑталÑції: ОновленнÑ" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Онлайн оновленнÑ" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Перевірити оновленнÑ" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Перевірка оновлень інÑталÑтора..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Будь лаÑка, переконайтеÑÑ, що ваш брандмауер не блокує" diff --git a/Shared/installer/locale/vi_VN.pot b/Shared/installer/locale/vi_VN.pot index c776238e321..a2b0da1f9c9 100644 --- a/Shared/installer/locale/vi_VN.pot +++ b/Shared/installer/locale/vi_VN.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Vietnamese\n" "Language: vi_VN\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "Thuật sỹ này sẽ hướng dẫn bạn trong quá trình cài đặ "Nhấn Next để tiếp tục." #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "NÆ¡i cài đặt Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "Thư mục đã cài Grand Theft Auto: San Andreas" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "Hãy chá»n thư mục chứa game Grand Theft Auto: San Andreas.$\n" "Chá»n \"Install\" để bắt đầu cài đặt." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "Tạo nhóm mục ở Start Menu cho các phần má»m đã được cài đặt" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "Tạo icon MTA:SA ngoài Desktop" #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "Äăng ký giao thức kết nối mtasa:// để có thể sá»­ dụng ở trình duyệt web." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "Thêm vào Windows Games Explorer (nếu có)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "Cài đặt hoặc cập nhật DirectX (nếu cần thiết)." #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Các thành phần lõi cần thiết để chạy Multi Theft Auto." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "The MTA:SA modification, cho phép bạn chÆ¡i trá»±c tuyến." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "The Multi Theft Auto Server. Cho phép bạn tá»± tạo server MTA:SA từ chính máy tính cá»§a bạn. Cần có đưá»ng truyá»n mạng nhanh." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "The Multi Theft Auto server. Äây là thành phần cần thiết." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "Phiên bản MTA:SA modification cho server" #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "Äây là má»™t bá»™ resources cần thiết cho server cá»§a bạn." #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "Äây là má»™t bá»™ tùy chá»n chế độ (gamemodes) và bản đồ (maps) cho server cá»§a bạn." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "The MTA:SA 1.0 Map Editor. ÄÆ°á»£c sá»­ dụng để bạn có thể tạo bản đồ tùy thích sá»­ dụng trong các chế độ chÆ¡i cho MTA." #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "Äây là bá»™ SDK dùng để tạo các mô-Ä‘un binary cho server MTA. Cài đặt nó nếu bạn có thể lập trình bằng C++!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "Viết code và các công cụ há»— trợ trong việc tạo ra các mods cho Multi Theft Auto" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "Client là phần má»m giúp bạn kết nối đến server Multi Theft Auto" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "Client và Server" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "Server" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "Nhóm mục Start menu" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "Äăng ký giao thức mtasa:// protocol" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "Thêm vào Games Explorer" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "Cài đặt DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "Các thành phần lõi" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "Mô-Ä‘un game" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "Äang thá»±c hiện nâng cấp..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "Äang cập nhật quyá»n hạn. Có thể mất vài phút..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "Không tìm thấy phên bản Windows phù hợp vá»›i Grand Theft Auto "Vui lòng cài đặt lại nếu bị lá»—i trong quá trình cài đặt." #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) đã được xóa thành công khá»i máy tính cá»§a bạn." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "Gỡ bá» phần má»m thất bại!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "Bạn có muốn xóa hoàn toàn $(^Name) và tất cả các thành phần khác cá»§a nó?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "Gỡ bá» trước khi cập nhật?$\\r$\n" "Chạy file cài đặt để nâng cấp và sao lưu các tùy chá»n cá»§a bạn." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "Bạn có muốn giữ lại dữ liệu cá»§a bạn (Chẳng hạn như resources, ảnh chụp màn hình trong game và các tùy chỉnh server)? Nếu bạn chá»n không, thì resources, các tùy chỉnh hay ảnh chụp màn hình trong game mà bạn Ä‘ang có sẽ bị xóa." #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "Trình cài đặt này cần quyá»n Administrator, vui lòng thá»­ lại" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "Trình gỡ bá» này cần quyá»n Administrator, vui lòng thá»­ lại" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Login service không hoạt động, Ä‘ang há»§y lệnh!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "Má»™t phiên bản khác cá»§a MTA ($1) đã được cài đặt tại "Bạn có muốn ghi đè MTA $1 vào mục $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA không thể cài đặt trong cùng má»™t thư mục vá»›i GTA:SA.$ "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "Thư mục bạn vừa chá»n không tồn tại.$\n" "Hãy chá»n đưá»ng dẫn đến thư mục cài đặt GTA:SA" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "Không tìm thấy GTA:SA tại mục $GTA_DIR $\n" "Bạn có muốn tiếp tục?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "Chá»n đưá»ng dẫn cài đặt" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "Chá»n thư mục để cài đặt ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} sẽ được cài đặt vào " Nhấn Next để tiếp tục." #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "Thư cài đặt" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "Tìm duyệt..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "Mặc định" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "Như cÅ©" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "Tùy chá»n" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "Chá»n thư mục để cài đặt ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} vào trong:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "Cảnh báo: Má»™t phiên bản chính khác cá»§a MTA ($1) đã được cài đặt ở đưá»ng dẫn đó." #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "Loại cài đặt: Nâng cấp" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "Cập nhật trá»±c tuyến" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "Äang kiểm tra thông tin cập nhật" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "Äang kiểm tra thông tin cập nhật cá»§a trình cài đặt..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "Chắc chắc rằng tưá»ng lá»­a (firewall) cá»§a máy bạn không chặn phần má»m này" diff --git a/Shared/installer/locale/zh_CN.pot b/Shared/installer/locale/zh_CN.pot index bc4cdd5a89d..14f889538e4 100644 --- a/Shared/installer/locale/zh_CN.pot +++ b/Shared/installer/locale/zh_CN.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-04-08 23:03\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Chinese Simplified\n" "Language: zh_CN\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "本å‘导将会引导您安装或更新 $(^Name) ${REVISION_TAG}\n\n" "点击下一步继续。" #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "侠盗猎车手: 圣安地列斯的安装路径" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "侠盗猎车手: 圣安地列斯所在的文件夹" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "请选择你的侠盗猎车手: 圣安地列斯所在的文件夹。$\n" "请点击安装按钮开始安装。" #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "为程åºåˆ›å»ºå¼€å§‹èœå•组" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "为 MTA:SA 客户端创建桌é¢å¿«æ·æ–¹å¼ã€‚" #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "为æµè§ˆå™¨æ³¨å†Œ mtasa:// 超链接å议。" #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "增加到 Windows 游æˆç®¡ç†å™¨ (如果存在的è¯)。" #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "安装或更新 DirectX (如果需è¦ï¼‰" #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "è¿è¡Œ Multi Theft Auto éœ€è¦æ ¸å¿ƒç»„件。" #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA MOD å…è®¸æ‚¨åœ¨çº¿ä¸Žå…¶ä»–çŽ©å®¶ä¸€åŒæ¸¸çŽ©ã€‚" #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto æœåŠ¡å™¨ã€‚æ‚¨å¯ä»¥åœ¨è‡ªå·±çš„ç”µè„‘ä¸Šåˆ›å»ºæ¸¸æˆæœåŠ¡å™¨ä¸»æœºã€‚è¿™å°†éœ€è¦è¶³å¤Ÿå¸¦å®½çš„互è”网连接。" #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto æœåŠ¡å™¨ã€‚è¿™æ˜¯å¿…é¡»å®‰è£…çš„ç»„ä»¶ã€‚" #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "æœåŠ¡å™¨çš„ MTA:SA Mod æ”¯æŒæ¨¡å—。" #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "è¿™æ˜¯æ¸¸æˆæœåŠ¡å™¨éœ€æ±‚çš„èµ„æºæ–‡ä»¶é›†åˆã€‚" #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "这是一个å¯é€‰çš„æœåŠ¡å™¨ç«¯æ¸¸æˆæ¨¡å¼å’Œåœ°å›¾åŒ…。" #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 地图编辑器。它å¯ä»¥ç”¨æ¥åˆ›å»ºæ‚¨è‡ªå·±çš„地图,将在 MTA æ¸¸æˆæ¨¡å¼é‡Œè¢«ä½¿ç”¨ã€‚" #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "è¿™æ˜¯ç”¨äºŽå¼€å‘ MTA æœåŠ¡å™¨ç«¯äºŒè¿›åˆ¶æ¨¡å—的软件开å‘工具包(SDK)。仅供熟悉 C++ 的用户安装。" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "å¸®åŠ©æ‚¨å¼€å‘ MTA Mod 的开å‘代ç å’Œå·¥å…·åŒ…" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "让你å¯ä»¥åœ¨ Multi Theft Auto æœåŠ¡å™¨ä¸Šæ¸¸çŽ©çš„å®¢æˆ·ç«¯ç¨‹åºã€‚" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "å®¢æˆ·ç«¯åŠæœåŠ¡å™¨ç«¯" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "仅安装æœåŠ¡å™¨ç«¯" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "创建开始èœå•组" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "创建桌é¢å¿«æ·æ–¹å¼" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "注册 mtasa:// åè®®" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "加入游æˆç®¡ç†å™¨èœå•" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "安装 DIrectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "游æˆå®¢æˆ·ç«¯" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "专用æœåС噍" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "核心组件" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "æ¸¸æˆæ¨¡å—" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "正在å‡çº§ä¸­â€¦" #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "æ›´æ–°æƒé™ä¸­ã€‚这将å¯èƒ½èŠ±è´¹ä¸€äº›æ—¶é—´..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "没有检测到å¯ç”¨çš„ Windows 版本的 侠盗猎车手: 圣安地列 "如果 MTA 安装åŽå‡ºçŽ°é—®é¢˜ï¼Œè¯·é‡æ–°å®‰è£… GTA:SA 。" #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "核心资æº" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "å¯é€‰èµ„æº" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "编辑器" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "å¼€å‘包" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) å·²æˆåŠŸä»Žæ‚¨çš„ç”µè„‘ä¸­å¸è½½ã€‚" #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "å¸è½½å¤±è´¥!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "你确定è¦å®Œå…¨åˆ é™¤ $(^Name) 和相关组件å—?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "在安装更新å‰å¸è½½æ—§ç‰ˆæœ¬?$\\r$\n" "è¿è¡Œæ–°ç‰ˆæœ¬çš„安装程åºä»¥å‡çº§å’Œä½ çš„æ•°æ®." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "您è¦ä¿ç•™æ‚¨çš„ä¸ªäººæ•°æ® (例如资æºï¼Œæ¸¸æˆæˆªå›¾å’ŒæœåС噍é…置文件) å—? 如果你选择å¦ï¼Œæ‰€æœ‰èµ„æºã€é…置文件或截图都将会被删除。" #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "此安装程åºéœ€è¦ä»¥ç³»ç»Ÿç®¡ç†å‘˜èº«ä»½æ‰§è¡Œï¼Œè¯·é‡è¯•" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "æ­¤å¸è½½ç¨‹åºéœ€è¦ä»¥ç³»ç»Ÿç®¡ç†å‘˜èº«ä»½æ‰§è¡Œï¼Œè¯·é‡è¯•" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "Logon æœåŠ¡æ²¡æœ‰è¿è¡Œï¼Œå¼‚常终止!" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "无法æå‡" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "ä¸åŒä¸»ç‰ˆæœ¬çš„ MTA ($1) 已安装在该目录里。$\n" "您确定è¦è¦†ç›– MTA $1 到目录 $INSTDIR å—?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA 无法与 GTA:SA 安装在åŒä¸€ç›®å½•.$\n" "$DEFAULT_INSTDIR å—?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "所选的目录ä¸å­˜åœ¨ã€‚$\n" "请选择 GTA:SA 的安装目录" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "无法在 $GTA_DIR 中找到 GTA:SA çš„æ¸¸æˆæ–‡ä»¶ $\n" "您确定è¦ç»§ç»­å®‰è£…å— ?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "选择安装的ä½ç½®" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "请选择用于安装 ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} 的目录" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} 将会被安装到以下目录 "点击下一步继续。" #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "目标文件夹" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "æµè§ˆ..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "默认" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "上次使用的" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "自定义" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "请选择将è¦å®‰è£… ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} 的文件夹:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "警告: 一个ä¸åŒä¸»ç‰ˆæœ¬çš„ MTA ($1) 已安装在该目录。" #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "安装类型: å‡çº§" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "在线更新" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "正在检查更新信æ¯" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "正在检查安装包更新信æ¯..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "请确认您的防ç«å¢™æ²¡æœ‰é˜»æ­¢è¿žæŽ¥" diff --git a/Shared/installer/locale/zh_TW.pot b/Shared/installer/locale/zh_TW.pot index 467aa4a2156..b3b2230b6e4 100644 --- a/Shared/installer/locale/zh_TW.pot +++ b/Shared/installer/locale/zh_TW.pot @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: 2d3d942aa8adf891478198912ac0b233\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-08 22:41\n" -"PO-Revision-Date: 2025-05-05 21:31\n" +"POT-Creation-Date: 2026-01-06 11:14\n" +"PO-Revision-Date: 2026-01-08 17:20\n" "Last-Translator: \n" "Language-Team: Chinese Traditional\n" "Language: zh_TW\n" @@ -18,22 +18,22 @@ msgstr "" "X-Crowdin-File-ID: 89\n" #. GET_XPVISTA_PLEASE -#: Shared/installer/nightly.nsi:205 +#: Shared/installer/nightly.nsi:206 msgid "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." msgstr "您下載的 MTA:SA ç‰ˆæœ¬ä¸æ”¯æ´ Windows XP 或 Vista。請至 www.multitheftauto.com 下載其他版本。" #. GET_WIN81_PLEASE -#: Shared/installer/nightly.nsi:206 +#: Shared/installer/nightly.nsi:207 msgid "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." msgstr "您下載的 MTA:SA ç‰ˆæœ¬ä¸æ”¯æ´ Windows 7ã€8 或 8.1。請至 www.multitheftauto.com 下載其他版本。" #. GET_MASTER_PLEASE -#: Shared/installer/nightly.nsi:207 +#: Shared/installer/nightly.nsi:208 msgid "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." msgstr "您下載的 MTA:SA 版本是為舊版 Windows 製作的。請至 www.multitheftauto.com 下載其他版本。" #. WELCOME_TEXT -#: Shared/installer/nightly.nsi:208 +#: Shared/installer/nightly.nsi:209 msgid "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n" "It is recommended that you close all other applications before starting Setup.\n\n" "[Admin access may be requested for Vista and up]\n\n" @@ -44,17 +44,17 @@ msgstr "安è£ç²¾éˆæœƒå¼•å°Žæ‚¨å®‰è£æˆ–æ›´æ–° $(^Name) ${REVISION_TAG}\n\n" "點擊 下一步 以繼續安è£ã€‚" #. HEADER_Text -#: Shared/installer/nightly.nsi:212 +#: Shared/installer/nightly.nsi:213 msgid "Grand Theft Auto: San Andreas location" msgstr "俠盜çµè»Šæ‰‹: è–安地列斯的安è£è·¯å¾‘" #. DIRECTORY_Text_Dest -#: Shared/installer/nightly.nsi:213 +#: Shared/installer/nightly.nsi:214 msgid "Grand Theft Auto: San Andreas folder" msgstr "俠盜çµè»Šæ‰‹: è–安地列斯所在的資料夾" #. DIRECTORY_Text_Top -#: Shared/installer/nightly.nsi:214 +#: Shared/installer/nightly.nsi:215 msgid "Please select your Grand Theft Auto: San Andreas folder.$\n" "$\n" "You MUST have Grand Theft Auto: San Andreas 1.0 installed to use MTA:SA, it does not support any other versions.$\n" @@ -67,152 +67,152 @@ msgstr "è«‹é¸æ“‡æ‚¨çš„俠盜çµè»Šæ‰‹: è–安地列斯所在的資料夾.$\n" "請點擊安è£é–‹å§‹å®‰è£ç¨‹å¼." #. DESC_Section10 -#: Shared/installer/nightly.nsi:217 +#: Shared/installer/nightly.nsi:218 msgid "Create a Start Menu group for installed applications" msgstr "將程å¼å»ºç«‹åœ¨é–‹å§‹é¸å–®" #. DESC_Section11 -#: Shared/installer/nightly.nsi:218 +#: Shared/installer/nightly.nsi:219 msgid "Create a Desktop Shortcut for the MTA:SA Client." msgstr "å°‡MTA:SA å®¢æˆ¶ç«¯å»ºç«‹é–‹å§‹æ¡Œé¢æ·å¾‘" #. DESC_Section12 -#: Shared/installer/nightly.nsi:219 +#: Shared/installer/nightly.nsi:220 msgid "Register mtasa:// protocol for browser clickable-ness." msgstr "註冊å¯ä½¿ç¶²é ç€è¦½å™¨å¯ä»¥é»žæ“Šçš„ mtasa:// å”è­°." #. DESC_Section13 -#: Shared/installer/nightly.nsi:220 +#: Shared/installer/nightly.nsi:221 msgid "Add to Windows Games Explorer (if present)." msgstr "增加到 Windows éŠæˆ²ç®¡ç†å™¨ (如果存在)." #. DESC_DirectX -#: Shared/installer/nightly.nsi:221 +#: Shared/installer/nightly.nsi:222 msgid "Install or update DirectX (if required)." msgstr "å®‰è£æˆ–是更新 DirectX (若有需è¦)" #. DESC_Section1 -#: Shared/installer/nightly.nsi:222 +#: Shared/installer/nightly.nsi:223 msgid "The core components required to run Multi Theft Auto." msgstr "Multi Theft Auto éœ€è¦æ ¸å¿ƒå…ƒä»¶é‹è¡Œ." #. DESC_Section2 -#: Shared/installer/nightly.nsi:223 +#: Shared/installer/nightly.nsi:224 msgid "The MTA:SA modification, allowing you to play online." msgstr "MTA:SA 修改了è–安地列斯的功能,å…許您與其他玩家一起連線éŠçŽ©." #. DESC_SectionGroupServer -#: Shared/installer/nightly.nsi:226 +#: Shared/installer/nightly.nsi:227 msgid "The Multi Theft Auto Server. This allows you to host games from your computer. This requires a fast internet connection." msgstr "Multi Theft Auto 伺æœå™¨å…è¨±æ‚¨åœ¨è‡ªå·±çš„é›»è…¦å‰µå»ºéŠæˆ²,é€™å€‹è¦æ±‚必須具備快速的網際網路連線." #. DESC_Section4 -#: Shared/installer/nightly.nsi:227 +#: Shared/installer/nightly.nsi:228 msgid "The Multi Theft Auto server. This is a required component." msgstr "Multi Theft Auto 伺æœå™¨. 這個是必須的元件." #. DESC_Section5 -#: Shared/installer/nightly.nsi:228 +#: Shared/installer/nightly.nsi:229 msgid "The MTA:SA modification for the server." msgstr "MTA:SA 被修改為了伺æœå™¨." #. DESC_Section6 -#: Shared/installer/nightly.nsi:229 +#: Shared/installer/nightly.nsi:230 msgid "This is a set of required resources for your server." msgstr "伺æœå™¨å¯èƒ½æœƒä½¿ç”¨åˆ°çš„資æºè…³æœ¬ã€‚" #. DESC_Section7 -#: Shared/installer/nightly.nsi:230 +#: Shared/installer/nightly.nsi:231 msgid "This is an optional set of gamemodes and maps for your server." msgstr "這是一個å¯é¸çš„伺æœå™¨ Gamemode 和地圖包." #. DESC_Section8 -#: Shared/installer/nightly.nsi:231 +#: Shared/installer/nightly.nsi:232 msgid "The MTA:SA 1.0 Map Editor. This can be used to create your very own maps for use in gamemodes for MTA." msgstr "MTA:SA 1.0 地圖編輯器。 å¯ä»¥ç”¨ä¾†è£½ä½œæ‚¨ä½¿ç”¨æ–¼è…³æœ¬çš„地圖。" #. DESC_Section9 -#: Shared/installer/nightly.nsi:232 +#: Shared/installer/nightly.nsi:233 msgid "This is the SDK for creating binary modules for the MTA server. Only install if you have a good understanding of C++!" msgstr "這是供MTA 伺æœå™¨ä½¿ç”¨çš„äºŒé€²ä½æ¨¡çµ„. ä¸ç†Ÿæ‚‰C++者請勿安è£!" #. DESC_SectionGroupDev -#: Shared/installer/nightly.nsi:234 +#: Shared/installer/nightly.nsi:235 msgid "Development code and tools that aid in the creation of mods for Multi Theft Auto" msgstr "開發代碼和工具包 , 它å¯ä»¥å¹«åŠ©æ‚¨è£½ä½œ MTA 的模組包" #. DESC_SectionGroupClient -#: Shared/installer/nightly.nsi:235 +#: Shared/installer/nightly.nsi:236 msgid "The client is the program you run to play on a Multi Theft Auto server" msgstr "本客戶端是一個å¯ä»¥è®“你在 Multi Theft Auto 伺æœå™¨ä¸ŠéŠçŽ©çš„ç¨‹å¼" #. INST_CLIENTSERVER -#: Shared/installer/nightly.nsi:444 +#: Shared/installer/nightly.nsi:468 msgid "Client and Server" msgstr "客戶端åŠä¼ºæœå™¨ç«¯" #. INST_SERVER -#: Shared/installer/nightly.nsi:445 +#: Shared/installer/nightly.nsi:469 msgid "Server only" msgstr "僅安è£ä¼ºæœå™¨" #. INST_STARTMENU_GROUP -#: Shared/installer/nightly.nsi:459 +#: Shared/installer/nightly.nsi:483 msgid "Start menu group" msgstr "開始主é¸å–®ç¾¤çµ„" #. INST_DESKTOP_ICON -#: Shared/installer/nightly.nsi:460 +#: Shared/installer/nightly.nsi:484 msgid "Desktop icon" msgstr "桌é¢åœ–示" #. INST_PROTOCOL -#: Shared/installer/nightly.nsi:461 +#: Shared/installer/nightly.nsi:485 msgid "Register mtasa:// protocol" msgstr "註冊並登錄 mtasa:// protocol" #. INST_GAMES_EXPLORER -#: Shared/installer/nightly.nsi:462 +#: Shared/installer/nightly.nsi:486 msgid "Add to Games Explorer" msgstr "åŠ å…¥éŠæˆ²è‡³é¸å–®" #. INST_DIRECTX -#: Shared/installer/nightly.nsi:463 +#: Shared/installer/nightly.nsi:487 msgid "Install DirectX" msgstr "å®‰è£ DirectX" #. INST_SEC_CLIENT -#: Shared/installer/nightly.nsi:497 +#: Shared/installer/nightly.nsi:521 msgid "Game client" msgstr "éŠæˆ²å®¢æˆ¶ç«¯" #. INST_SEC_SERVER -#: Shared/installer/nightly.nsi:498 +#: Shared/installer/nightly.nsi:522 msgid "Dedicated server" msgstr "專用伺æœå™¨" #. INST_SEC_CORE -#: Shared/installer/nightly.nsi:499 +#: Shared/installer/nightly.nsi:523 msgid "Core components" msgstr "核心元件" #. INST_SEC_GAME -#: Shared/installer/nightly.nsi:500 +#: Shared/installer/nightly.nsi:524 msgid "Game module" msgstr "éŠæˆ²æ¨¡å¼" #. INFO_INPLACE_UPGRADE -#: Shared/installer/nightly.nsi:502 +#: Shared/installer/nightly.nsi:526 msgid "Performing in-place upgrade..." msgstr "執行å‡ç´šä¸­..." #. INFO_UPDATE_PERMISSIONS -#: Shared/installer/nightly.nsi:503 +#: Shared/installer/nightly.nsi:527 msgid "Updating permissions. This could take a few minutes..." msgstr "更新權é™ä¸­.這將å¯èƒ½èŠ±è²»ä¸€äº›æ™‚é–“..." #. MSGBOX_INVALID_GTASA -#: Shared/installer/nightly.nsi:504 +#: Shared/installer/nightly.nsi:528 msgid "A valid Windows version of Grand Theft Auto: San Andreas was not detected.$\\r$\n" "However installation will continue.$\\r$\n" "Please reinstall if there are problems later." @@ -221,42 +221,42 @@ msgstr "無法檢測到支æ´çš„Windows版 Grand Theft Auto: San Andreas éŠæˆ² "若安è£å¾Œé‡åˆ°å•é¡Œè«‹é‡æ–°å®‰è£ä¸€æ¬¡ã€‚" #. INST_SEC_CORE_RESOURCES -#: Shared/installer/nightly.nsi:507 +#: Shared/installer/nightly.nsi:531 msgid "Core Resources" msgstr "核心資æº" #. INST_SEC_OPTIONAL_RESOURCES -#: Shared/installer/nightly.nsi:508 +#: Shared/installer/nightly.nsi:532 msgid "Optional Resources" msgstr "å¯é¸è³‡æº" #. INST_SEC_EDITOR -#: Shared/installer/nightly.nsi:509 +#: Shared/installer/nightly.nsi:533 msgid "Editor" msgstr "編輯器" #. INST_SEC_DEVELOPER -#: Shared/installer/nightly.nsi:985 +#: Shared/installer/nightly.nsi:1014 msgid "Development" msgstr "程å¼é–‹ç™¼" #. UNINST_SUCCESS -#: Shared/installer/nightly.nsi:1033 +#: Shared/installer/nightly.nsi:1062 msgid "$(^Name) was successfully removed from your computer." msgstr "$(^Name) å·²æˆåŠŸå¾žä½ çš„é›»è…¦ä¸­ç§»é™¤." #. UNINST_FAIL -#: Shared/installer/nightly.nsi:1040 +#: Shared/installer/nightly.nsi:1069 msgid "Uninstallation has failed!" msgstr "解除安è£å¤±æ•—!" #. UNINST_REQUEST -#: Shared/installer/nightly.nsi:1048 +#: Shared/installer/nightly.nsi:1077 msgid "Are you sure you want to completely remove $(^Name) and all of its components?" msgstr "你確定è¦å®Œå…¨åˆªé™¤ $(^Name) 和所有相關檔案嗎?" #. UNINST_REQUEST_NOTE -#: Shared/installer/nightly.nsi:1049 +#: Shared/installer/nightly.nsi:1078 msgid "Uninstalling before update?$\\r$\n" "It is not necessary to uninstall before installing a new version of MTA:SA$\\r$\n" "Run the new installer to upgrade and preserve your settings." @@ -265,32 +265,32 @@ msgstr "æ›´æ–°å‰å¸è¼‰?$\\r$\n" "é‹è¡Œæ–°çš„安è£ç¨‹åºå‡ç´šï¼Œä¸¦ä¿å­˜è¨­ç½®." #. UNINST_DATA_REQUEST -#: Shared/installer/nightly.nsi:1062 +#: Shared/installer/nightly.nsi:1091 msgid "Would you like to keep your data files (such as resources, screenshots and server configuration)? If you click no, any resources, configurations or screenshots you have created will be lost." msgstr "您想ä¿å­˜æ‚¨çš„éŠæˆ²è³‡æ–™å—Ž (例如資æºã€éŠæˆ²æˆªåœ–和伺æœå™¨è¨­å®š)ï¼Ÿå¦‚æžœæ‚¨é¸æ“‡å¦ï¼Œæ‰€æœ‰çš„資æºã€è¨­å®šæˆ–截圖將會éºå¤±ã€‚" #. UAC_RIGHTS1 -#: Shared/installer/nightly.nsi:1245 +#: Shared/installer/nightly.nsi:1281 msgid "This installer requires admin access, try again" msgstr "此安è£éœ€è¦ä»¥ç®¡ç†å“¡èº«åˆ†åŸ·è¡Œï¼Œè«‹é‡è©¦" #. UAC_RIGHTS_UN -#: Shared/installer/nightly.nsi:1246 +#: Shared/installer/nightly.nsi:1282 msgid "This uninstaller requires admin access, try again" msgstr "解除安è£éœ€æä¾›ç®¡ç†å“¡æ¬Šé™ï¼Œè«‹é‡è©¦" #. UAC_RIGHTS3 -#: Shared/installer/nightly.nsi:1247 +#: Shared/installer/nightly.nsi:1283 msgid "Logon service not running, aborting!" msgstr "登錄æœå‹™æ²’有é‹è¡Œï¼Œçµ‚止中ï¼" #. UAC_RIGHTS4 -#: Shared/installer/nightly.nsi:1248 +#: Shared/installer/nightly.nsi:1284 msgid "Unable to elevate" msgstr "無法æå‡" #. INST_MTA_CONFLICT -#: Shared/installer/nightly.nsi:1844 +#: Shared/installer/nightly.nsi:1880 msgid "A different major version of MTA ($1) already exists at that path.$\n" "$\n" "MTA is designed for major versions to be installed in different paths.$\n" @@ -301,7 +301,7 @@ msgstr "ä¸åŒç‰ˆæœ¬çš„MTA ($1) 已經存在該路徑。$\n" "你確定è¦è¦†å¯«MTA $1 到 $INSTDIR ?" #. INST_GTA_CONFLICT -#: Shared/installer/nightly.nsi:1848 +#: Shared/installer/nightly.nsi:1884 msgid "MTA cannot be installed into the same directory as GTA:SA.$\n" "$\n" "Do you want to use the default install directory$\n" @@ -312,7 +312,7 @@ msgstr "MTA 無法安è£åˆ°åŒä¸€ç›®éŒ„ GTA:SA.$\n" "$DEFAULT_INSTDIR ?" #. INST_GTA_ERROR1 -#: Shared/installer/nightly.nsi:1851 +#: Shared/installer/nightly.nsi:1887 msgid "The selected directory does not exist.$\n" "$\n" "Please select the GTA:SA install directory" @@ -321,7 +321,7 @@ msgstr "鏿“‡çš„安è£ç›®éŒ„ä¸å­˜åœ¨.$\n" "è«‹é¸æ“‡GTA:SA的安è£ç›®éŒ„" #. INST_GTA_ERROR2 -#: Shared/installer/nightly.nsi:1853 +#: Shared/installer/nightly.nsi:1889 msgid "Could not find GTA:SA installed at $GTA_DIR $\n" "$\n" "Are you sure you want to continue ?" @@ -330,17 +330,17 @@ msgstr "找ä¸åˆ°ä¿ ç›œçµè»Šæ‰‹ï¼šè–安地列斯已安è£åœ¨ $GTA_DIR $\n" "您確定è¦ç¹¼çºŒå—Ž?" #. INST_CHOOSE_LOC_TOP -#: Shared/installer/nightly.nsi:1971 +#: Shared/installer/nightly.nsi:2007 msgid "Choose Install Location" msgstr "鏿“‡å®‰è£è·¯å¾‘" #. INST_CHOOSE_LOC -#: Shared/installer/nightly.nsi:1972 +#: Shared/installer/nightly.nsi:2008 msgid "Choose the folder in which to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION}" msgstr "è«‹é¸æ“‡ç”¨æ–¼å®‰è£ ${PRODUCT_NAME_NO_VER} $ {PRODUCT_VERSION} 的文件夾" #. INST_CHOOSE_LOC2 -#: Shared/installer/nightly.nsi:1973 +#: Shared/installer/nightly.nsi:2009 msgid "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} will be installed in the following folder.$\n" "To install in a different folder, click Browse and select another folder.$\n" "$\n" @@ -351,62 +351,62 @@ msgstr "${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} 將會被安è£åœ¨ä¸‹åˆ—的文 "~請按下一步以繼續" #. INST_CHOOSE_LOC3 -#: Shared/installer/nightly.nsi:1975 +#: Shared/installer/nightly.nsi:2011 msgid "Destination Folder" msgstr "目標文件夾" #. INST_CHOOSE_LOC_BROWSE -#: Shared/installer/nightly.nsi:1976 +#: Shared/installer/nightly.nsi:2012 msgid "Browse..." msgstr "ç€è¦½..." #. INST_CHOOSE_LOC_DEFAULT -#: Shared/installer/nightly.nsi:1977 +#: Shared/installer/nightly.nsi:2013 msgid "Default" msgstr "é è¨­" #. INST_CHOOSE_LOC_LAST_USED -#: Shared/installer/nightly.nsi:1978 +#: Shared/installer/nightly.nsi:2014 msgid "Last used" msgstr "上次使用的" #. INST_CHOOSE_LOC_CUSTOM -#: Shared/installer/nightly.nsi:1979 +#: Shared/installer/nightly.nsi:2015 msgid "Custom" msgstr "自訂" #. INST_CHOOSE_LOC4 -#: Shared/installer/nightly.nsi:2157 +#: Shared/installer/nightly.nsi:2193 msgid "Select the folder to install ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} in:" msgstr "鏿“‡å®‰è£æ–‡ä»¶å¤¾ ${PRODUCT_NAME_NO_VER} ${PRODUCT_VERSION} 在:" #. INST_LOC_OW -#: Shared/installer/nightly.nsi:2175 +#: Shared/installer/nightly.nsi:2211 msgid "Warning: A different major version of MTA ($1) already exists at that path." msgstr "警告: 一個ä¸åŒä¸»è¦ç‰ˆæœ¬çš„ MTA ($1) 已存在在這路徑中" #. INST_LOC_UPGRADE -#: Shared/installer/nightly.nsi:2176 +#: Shared/installer/nightly.nsi:2212 msgid "Installation type: Upgrade" msgstr "安è£é¡žåž‹:å‡ç´š" #. NETTEST_TITLE1 -#: Shared/installer/nightly.nsi:2410 +#: Shared/installer/nightly.nsi:2446 msgid "Online update" msgstr "線上更新" #. NETTEST_TITLE2 -#: Shared/installer/nightly.nsi:2411 +#: Shared/installer/nightly.nsi:2447 msgid "Checking for update information" msgstr "æ­£åœ¨ç¢ºèªæ›´æ–°è³‡è¨Š" #. NETTEST_STATUS1 -#: Shared/installer/nightly.nsi:2412 +#: Shared/installer/nightly.nsi:2448 msgid "Checking for installer update information..." msgstr "正在確èªå®‰è£ç¨‹å¼æ›´æ–°è³‡è¨Š..." #. NETTEST_STATUS2 -#: Shared/installer/nightly.nsi:2413 +#: Shared/installer/nightly.nsi:2449 msgid "Please ensure your firewall is not blocking" msgstr "請確èªé˜²ç«ç‰†æ˜¯å¦æœ‰å°éŽ–æ‚¨çš„é€£ç·š" diff --git a/Shared/installer/nightly.nsi b/Shared/installer/nightly.nsi index 08e9fab8120..a9860515532 100644 --- a/Shared/installer/nightly.nsi +++ b/Shared/installer/nightly.nsi @@ -51,17 +51,18 @@ Var ServerExePath Var UninstallExePath ; Games explorer: With each new X.X, update this GUID and the file at MTA10\launch\NEU\Multi Theft Auto.gdf.xml -!define GUID "{119D0ADB-56AF-4C85-9037-26564C0ACD57}" - +!define GUID "{8A7FC5C7-0023-4CD7-B1D6-89073CFD838F}" !ifndef MAJOR_VER !define MAJOR_VER "1" - !define MINOR_VER "6" + !define MINOR_VER "7" !define MAINT_VER "0" !endif !define 0.0 "${MAJOR_VER}.${MINOR_VER}" !define 0.0.0 "${MAJOR_VER}.${MINOR_VER}.${MAINT_VER}" +!define APPLICATION_ID "Multi Theft Auto ${0.0}" + ; ########################################################################################################### !ifndef FILES_ROOT !define LIGHTBUILD ; enable LIGHTBUILD for nightly @@ -202,7 +203,7 @@ VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "${VI_PRODUCT_VERSION}" ;@INSERT_TRANSLATIONS@ -LangString GET_XPVISTA_PLEASE ${LANG_ENGLISH} "The version of MTA:SA you've downloaded does not support Windows XP or Vista. Please download an alternative version from www.multitheftauto.com." +LangString GET_XPVISTA_PLEASE ${LANG_ENGLISH} "Multi Theft Auto does not support Windows XP or Vista. Please upgrade your computer." LangString GET_WIN81_PLEASE ${LANG_ENGLISH} "The version of MTA:SA you've downloaded does not support Windows 7, 8 or 8.1. Please download an alternative version from www.multitheftauto.com." LangString GET_MASTER_PLEASE ${LANG_ENGLISH} "The version of MTA:SA you've downloaded is designed for old versions of Windows. Please download an alternative version from www.multitheftauto.com." LangString WELCOME_TEXT ${LANG_ENGLISH} "This wizard will guide you through the installation or update of $(^Name) ${REVISION_TAG}\n\n\ @@ -255,16 +256,27 @@ Function .onInit !insertmacro UAC_AsUser_GetGlobalVar $LANGUAGE # Copy our selected language from the outer to the inner instance ${EndIf} + # MTA isn't supported on XP/Vista ${If} ${AtMostWinVista} MessageBox MB_OK "$(GET_XPVISTA_PLEASE)" ExecShell "open" "https://multitheftauto.com" Quit - ${ElseIf} ${AtMostWin8.1} - MessageBox MB_OK "$(GET_WIN81_PLEASE)" - ExecShell "open" "https://multitheftauto.com" - Quit ${EndIf} + !ifdef MTA_MAETRO + ${If} ${AtLeastWin10} + MessageBox MB_OK "$(GET_MASTER_PLEASE)" + ExecShell "open" "https://multitheftauto.com" + Quit + ${EndIf} + !else + ${If} ${AtMostWin8.1} + MessageBox MB_OK "$(GET_WIN81_PLEASE)" + ExecShell "open" "https://multitheftauto.com" + Quit + ${EndIf} + !endif + File /oname=$TEMP\image.bmp "connect.bmp" SetShellVarContext all @@ -372,7 +384,24 @@ Function .onInstSuccess # Add 'MaxLoaderThreads' DWORD value for gta_sa.exe to disable multi-threaded loading of DLLs. WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\gta_sa.exe" "MaxLoaderThreads" 1 - + + # Configure Windows Error Reporting to save crash dumps to MTA's folder + # This enables capture of fail-fast crashes (0xC0000409, 0xC0000374) that bypass normal exception handling + # WER is a 64-bit system service that reads from the native 64-bit registry, + # so we must use SetRegView 64 to write to the correct location (not WOW6432Node) + SetRegView 64 + # Configure for gta_sa.exe (game process) + ; DumpType: 0=Custom, 1=MiniDump, 2=FullDump - use 1 for smaller dumps + WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\gta_sa.exe" "DumpType" 1 + WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\gta_sa.exe" "DumpCount" 10 + WriteRegExpandStr HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\gta_sa.exe" "DumpFolder" "$INSTDIR\MTA\dumps\private" + # Configure for Multi Theft Auto.exe (loader process) + ; DumpType: 0=Custom, 1=MiniDump, 2=FullDump - use 1 for smaller dumps + WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\Multi Theft Auto.exe" "DumpType" 1 + WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\Multi Theft Auto.exe" "DumpCount" 10 + WriteRegExpandStr HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\Multi Theft Auto.exe" "DumpFolder" "$INSTDIR\MTA\dumps\private" + SetRegView 32 + # Initilize variables holding paths and names Call MTAInitFileNamesAndPaths ; Start menu items @@ -391,6 +420,12 @@ Function .onInstSuccess Push $StartMenuClientShortcutPath Call MTACreateShortÑut ${EndIf} + ${If} ${FileExists} $StartMenuClientShortcutPath + ApplicationID::Set "$StartMenuClientShortcutPath" "${APPLICATION_ID}" + ${If} ${Errors} + ${LogText} "Error setting Application ID for client shortcut" + ${EndIf} + ${EndIf} # Either update or create Server shortcut ${If} ${FileExists} $StartMenuServerShortcutPath Push $ServerExePath @@ -539,6 +574,10 @@ SectionGroup /e "$(INST_SEC_CLIENT)" SECGCLIENT SetOutPath "$INSTDIR\MTA" SetOverwrite on + # Create dumps directory for WER crash dumps + CreateDirectory "$INSTDIR\MTA\dumps" + CreateDirectory "$INSTDIR\MTA\dumps\private" + ############################################################# # Make the directory "$INSTDIR" read write accessible by all users # Make the directory "$APPDATA\MTA San Andreas All" read write accessible by all users @@ -679,12 +718,22 @@ SectionGroup /e "$(INST_SEC_CLIENT)" SECGCLIENT File "${FILES_ROOT}\mta\XInput9_1_0_mta.dll" File "${FILES_ROOT}\mta\xinput1_3_mta.dll" File "${FILES_ROOT}\mta\d3dcompiler_43.dll" - File "${FILES_ROOT}\mta\d3dcompiler_47.dll" + !ifdef MTA_MAETRO + File /oname=d3dcompiler_47.dll "${FILES_ROOT}\mta\d3dcompiler_47.maetro.dll" + File "${FILES_ROOT}\maetro32.dll" + File "${FILES_ROOT}\mta\maetro64.dll" + !else + File "${FILES_ROOT}\mta\d3dcompiler_47.dll" + !endif SetOutPath "$INSTDIR\MTA\CEF" File "${FILES_ROOT}\mta\CEF\CEFLauncher.exe" File "${FILES_ROOT}\mta\CEF\CEFLauncher_DLL.dll" + !ifdef MTA_MAETRO + File "${FILES_ROOT}\maetro32.dll" + !endif + # Added as per https://bitbucket.org/chromiumembedded/cef/commits/8424f166ccef # Not currently using \mta\cef\ due to https://github.com/chromiumembedded/cef/issues/3749#issuecomment-2278568964 (it's already crashing and likely won't remain supported) @@ -699,7 +748,7 @@ SectionGroup /e "$(INST_SEC_CLIENT)" SECGCLIENT #File "${FILES_ROOT}\mta\CEF\cef_100_percent.pak" #File "${FILES_ROOT}\mta\CEF\cef_200_percent.pak" #File "${FILES_ROOT}\mta\CEF\devtools_resources.pak" - + # Below file was included in the deprecation referenced above, but already disabled in MTA beforehand #File "${FILES_ROOT}\mta\CEF\cef_extensions.pak" @@ -722,7 +771,11 @@ SectionGroup /e "$(INST_SEC_CLIENT)" SECGCLIENT File "${FILES_ROOT}\mta\xinput1_3_mta.dll" File "${FILES_ROOT}\mta\d3dcompiler_43.dll" - File "${FILES_ROOT}\mta\d3dcompiler_47.dll" + !ifdef MTA_MAETRO + File /oname=d3dcompiler_47.dll "${FILES_ROOT}\mta\d3dcompiler_47.maetro.dll" + !else + File "${FILES_ROOT}\mta\d3dcompiler_47.dll" + !endif SetOutPath "$INSTDIR\MTA\data" File "${FILES_ROOT}\mta\data\gta_sa_diff.dat" @@ -800,6 +853,10 @@ SectionGroup /e "$(INST_SEC_CLIENT)" SECGCLIENT SetOutPath "$INSTDIR" File "${FILES_ROOT}\Multi Theft Auto.exe" + !ifdef MTA_MAETRO + File "${FILES_ROOT}\maetro32.dll" + !endif + # Ensure exe file can be updated without admin AccessControl::GrantOnFile "$INSTDIR\Multi Theft Auto.exe" "($PermissionsGroup)" "FullAccess" @@ -839,6 +896,9 @@ SectionGroup /e "$(INST_SEC_SERVER)" SECGSERVER File "${SERVER_FILES_ROOT}\MTA Server.exe" File "${SERVER_FILES_ROOT}\net.dll" File "${FILES_ROOT}\mta\pthread.dll" + !ifdef MTA_MAETRO + File "${FILES_ROOT}\maetro32.dll" + !endif ${LogText} "-Section end - SERVER CORE" SectionEnd @@ -857,6 +917,7 @@ SectionGroup /e "$(INST_SEC_SERVER)" SECGSERVER File "${SERVER_FILES_ROOT}\mods\deathmatch\libcrypto-3.dll" File "${SERVER_FILES_ROOT}\mods\deathmatch\libssl-3.dll" !endif + File "${SERVER_FILES_ROOT}\mods\deathmatch\mtaserver.conf.template" ;Only overwrite the following files if previous versions were bugged and explicitly need replacing !insertmacro FileIfMD5 "${SERVER_FILES_ROOT}\mods\deathmatch\editor_acl.xml" "711185d8f4ebb355542053ce408b82b3" @@ -1079,45 +1140,25 @@ Section Uninstall preservemapsfolder: Call un.DoServiceUninstall - ; server CORE FILES - Delete "$INSTDIR\server\core.dll" - Delete "$INSTDIR\server\MTA Server.exe" - Delete "$INSTDIR\server\net.dll" - Delete "$INSTDIR\server\pthread.dll" - Delete "$INSTDIR\server\xmll.dll" - ; server files - Delete "$INSTDIR\server\mods\deathmatch\dbconmy.dll" - Delete "$INSTDIR\server\mods\deathmatch\deathmatch.dll" - Delete "$INSTDIR\server\mods\deathmatch\libmysql.dll" - Delete "$INSTDIR\server\mods\deathmatch\libcrypto-3.dll" - Delete "$INSTDIR\server\mods\deathmatch\libssl-3.dll" - Delete "$INSTDIR\server\mods\deathmatch\lua5.1.dll" - Delete "$INSTDIR\server\mods\deathmatch\pcre3.dll" - - ; server x64 CORE FILES - Delete "$INSTDIR\server\MTA Server64.exe" - Delete "$INSTDIR\server\x64\core.dll" - Delete "$INSTDIR\server\x64\net.dll" - Delete "$INSTDIR\server\x64\pthread.dll" - Delete "$INSTDIR\server\x64\xmll.dll" + Delete "$INSTDIR\server\MTA Server.exe" + Delete "$INSTDIR\server\*.dll" + Delete "$INSTDIR\server\mods\deathmatch\*.dll" ; server x64 files - Delete "$INSTDIR\server\x64\dbconmy.dll" - Delete "$INSTDIR\server\x64\deathmatch.dll" - Delete "$INSTDIR\server\x64\libmysql.dll" - Delete "$INSTDIR\server\x64\libcrypto-3-x64.dll" - Delete "$INSTDIR\server\x64\libssl-3-x64.dll" - Delete "$INSTDIR\server\x64\lua5.1.dll" - Delete "$INSTDIR\server\x64\pcre3.dll" + Delete "$INSTDIR\server\MTA Server64.exe" + Delete "$INSTDIR\server\x64\*.dll" RmDir "$INSTDIR\server\x64" Delete "$INSTDIR\Multi Theft Auto.exe" Delete "$INSTDIR\Multi Theft Auto.exe.dat" Delete "$INSTDIR\Uninstall.exe" - Delete "$INSTDIR\mods\deathmatch\client.dll" - Delete "$INSTDIR\mods\deathmatch\pcre3.dll" + !ifdef MTA_MAETRO + Delete "$INSTDIR\maetro32.dll" + !endif + + Delete "$INSTDIR\mods\deathmatch\*.dll" RmDir /r "$INSTDIR\MTA\cgui" RmDir /r "$INSTDIR\MTA\data" @@ -1151,6 +1192,13 @@ Section Uninstall DeleteRegValue HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\gta_sa.exe" "MaxLoaderThreads" DeleteRegKey /ifempty HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\gta_sa.exe" + # Remove WER LocalDumps configuration for gta_sa.exe and Multi Theft Auto.exe + # WER config is in 64-bit registry (not WOW6432Node), so use SetRegView 64 + SetRegView 64 + DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\gta_sa.exe" + DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\Multi Theft Auto.exe" + SetRegView 32 + ${GameExplorer_RemoveGame} ${GUID} ; Delete client shortcuts diff --git a/Shared/mods/deathmatch/logic/CDebugHookManager.cpp b/Shared/mods/deathmatch/logic/CDebugHookManager.cpp index fbb96de0be8..8e5798c35aa 100644 --- a/Shared/mods/deathmatch/logic/CDebugHookManager.cpp +++ b/Shared/mods/deathmatch/logic/CDebugHookManager.cpp @@ -33,10 +33,10 @@ CDebugHookManager::CDebugHookManager() { m_MaskArgumentsMap = { #ifndef MTA_CLIENT - {"logIn", {{EArgType::Password, 2}}}, // player, account, 2=PASSWORD - {"addAccount", {{EArgType::Password, 1}}}, // name, 1=PASSWORD - {"getAccount", {{EArgType::Password, 1}}}, // name, 1=PASSWORD - {"setAccountPassword", {{EArgType::Password, 1}}}, // account, 1=PASSWORD + {"logIn", {{EArgType::Password, 2}}}, // player, account, 2=PASSWORD + {"addAccount", {{EArgType::Password, 1}}}, // name, 1=PASSWORD + {"getAccount", {{EArgType::Password, 1}}}, // name, 1=PASSWORD + {"setAccountPassword", {{EArgType::Password, 1}}}, // account, 1=PASSWORD {"dbConnect", {{EArgType::MaxArgs, 0}}}, {"dbExec", {{EArgType::MaxArgs, 0}}}, {"dbFree", {{EArgType::MaxArgs, 0}}}, @@ -44,15 +44,15 @@ CDebugHookManager::CDebugHookManager() {"dbPrepareString", {{EArgType::MaxArgs, 0}}}, {"dbQuery", {{EArgType::MaxArgs, 0}}}, {"executeSQLQuery", {{EArgType::MaxArgs, 0}}}, - {"callRemote", {{EArgType::MaxArgs, 1}, {EArgType::Url, 0}}}, // 0=URL, ... + {"callRemote", {{EArgType::MaxArgs, 1}, {EArgType::Url, 0}}}, // 0=URL, ... #endif - {"fetchRemote", {{EArgType::MaxArgs, 1}, {EArgType::Url, 0}}}, // 0=URL, ... - {"passwordHash", {{EArgType::Password, 0}}}, // 0=PASSWORD, ... - {"passwordVerify", {{EArgType::Password, 0}}}, // 0=PASSWORD, ... - {"encodeString", {{EArgType::MaxArgs, 2}}}, // algorithm, input, 2=SECRETKEY, ... - {"decodeString", {{EArgType::MaxArgs, 2}}}, // algorithm, input, 2=SECRETKEY, ... - {"teaEncode", {{EArgType::Password, 1}}}, // input, 1=SECRETKEY - {"teaDecode", {{EArgType::Password, 1}}}, // input, 1=SECRETKEY + {"fetchRemote", {{EArgType::MaxArgs, 1}, {EArgType::Url, 0}}}, // 0=URL, ... + {"passwordHash", {{EArgType::Password, 0}}}, // 0=PASSWORD, ... + {"passwordVerify", {{EArgType::Password, 0}}}, // 0=PASSWORD, ... + {"encodeString", {{EArgType::MaxArgs, 2}}}, // algorithm, input, 2=SECRETKEY, ... + {"decodeString", {{EArgType::MaxArgs, 2}}}, // algorithm, input, 2=SECRETKEY, ... + {"teaEncode", {{EArgType::Password, 1}}}, // input, 1=SECRETKEY + {"teaDecode", {{EArgType::Password, 1}}}, // input, 1=SECRETKEY }; } @@ -534,10 +534,10 @@ bool CDebugHookManager::IsNameAllowed(const char* szName, const std::vector + +class CEventContext +{ +public: + CEventContext() noexcept : m_isCancelled(false) {} + + void Cancel(const char* reason = nullptr) noexcept + { + m_isCancelled = true; + if (reason) + m_cancelReason = reason; + } + + bool IsCancelled() const noexcept { return m_isCancelled; } + const std::string& GetCancelReason() const noexcept { return m_cancelReason; } + + void Reset() noexcept + { + m_isCancelled = false; + m_cancelReason.clear(); + } + +private: + bool m_isCancelled; + std::string m_cancelReason; +}; diff --git a/Shared/mods/deathmatch/logic/CIdArray.cpp b/Shared/mods/deathmatch/logic/CIdArray.cpp index fa20dd40b2c..42a4ec9de2d 100644 --- a/Shared/mods/deathmatch/logic/CIdArray.cpp +++ b/Shared/mods/deathmatch/logic/CIdArray.cpp @@ -11,7 +11,7 @@ #include "StdInc.h" #include "CIdArray.h" -#define SHARED_ARRAY_BASE_ID 0x02000000 +#define SHARED_ARRAY_BASE_ID 0x02000000 CStack CIdArray::m_IDStack; std::vector CIdArray::m_Elements; @@ -35,7 +35,7 @@ void CIdArray::Initialize() m_uiCapacity = 0; m_bInitialized = true; m_uiPopIdCounter = 0; - m_uiMinTicksBetweenIdReuse = 1000 * 60 * 60; // 1 hour + m_uiMinTicksBetweenIdReuse = 1000 * 60 * 60; // 1 hour m_LastPeriodStart = CTickCount::Now(); ExpandBy(2000); } diff --git a/Shared/mods/deathmatch/logic/CIdArray.h b/Shared/mods/deathmatch/logic/CIdArray.h index ff8093d5b39..681199e5092 100644 --- a/Shared/mods/deathmatch/logic/CIdArray.h +++ b/Shared/mods/deathmatch/logic/CIdArray.h @@ -33,7 +33,7 @@ */ typedef unsigned long SArrayId; -#define INVALID_ARRAY_ID 0xFFFFFFFF +#define INVALID_ARRAY_ID 0xFFFFFFFF namespace EIdClass { diff --git a/Shared/mods/deathmatch/logic/CLatentReceiver.cpp b/Shared/mods/deathmatch/logic/CLatentReceiver.cpp index 4b85cc2cc7d..86fc869957a 100644 --- a/Shared/mods/deathmatch/logic/CLatentReceiver.cpp +++ b/Shared/mods/deathmatch/logic/CLatentReceiver.cpp @@ -97,8 +97,7 @@ void CLatentReceiver::OnReceive(NetBitStreamInterface* pBitStream) pBitStream->Read(usCategory); pBitStream->Read(uiFinalSize); pBitStream->Read(uiRate); - if (pBitStream->Version() >= 0x31) - pBitStream->Read(usResourceNetId); + pBitStream->Read(usResourceNetId); } else if (ucSpecialFlag == FLAG_TAIL) { diff --git a/Shared/mods/deathmatch/logic/CLatentSendQueue.cpp b/Shared/mods/deathmatch/logic/CLatentSendQueue.cpp index 35946e17700..6b676b3352d 100644 --- a/Shared/mods/deathmatch/logic/CLatentSendQueue.cpp +++ b/Shared/mods/deathmatch/logic/CLatentSendQueue.cpp @@ -97,8 +97,7 @@ void CLatentSendQueue::DoPulse(int iTimeMsBetweenCalls) pBitStream->Write(activeTx.usCategory); pBitStream->Write(activeTx.bufferRef->GetSize()); pBitStream->Write(activeTx.uiRate); - if (pBitStream->Version() >= 0x31) - pBitStream->Write(activeTx.usResourceNetId); + pBitStream->Write(activeTx.usResourceNetId); activeTx.bSendStarted = true; } else if (activeTx.bufferRef->GetSize() == activeTx.uiReadPosition) diff --git a/Shared/mods/deathmatch/logic/CLatentTransferManager.cpp b/Shared/mods/deathmatch/logic/CLatentTransferManager.cpp index f72155dd17a..92050e087fa 100644 --- a/Shared/mods/deathmatch/logic/CLatentTransferManager.cpp +++ b/Shared/mods/deathmatch/logic/CLatentTransferManager.cpp @@ -64,9 +64,9 @@ void CLatentTransferManager::DoPulse() // Smooth out time between calls, with more resistance when rising int iBetweenCallsChange = iDeltaTimeMs - m_iTimeMsBetweenCalls; if (iBetweenCallsChange > 0) - m_iTimeMsBetweenCalls += std::min(iBetweenCallsChange, std::max(1, m_iTimeMsBetweenCalls / 10)); // 10% max when rising + m_iTimeMsBetweenCalls += std::min(iBetweenCallsChange, std::max(1, m_iTimeMsBetweenCalls / 10)); // 10% max when rising else - m_iTimeMsBetweenCalls -= std::min(-iBetweenCallsChange, std::max(1, m_iTimeMsBetweenCalls / 5)); // 20% max when falling + m_iTimeMsBetweenCalls -= std::min(-iBetweenCallsChange, std::max(1, m_iTimeMsBetweenCalls / 5)); // 20% max when falling m_iTimeMsBetweenCalls = Clamp(1, m_iTimeMsBetweenCalls, 100); @@ -141,7 +141,7 @@ void CLatentTransferManager::AddSendBatchBegin(unsigned char ucPacketId, NetBitS // Copy data from bitstream into buffer buffer.SetSize(uiHeadSize + uiBitStreamBytesUsed); - *(buffer.GetData() + buffer.GetSize() - 1) = 0; // Zero last byte of destination buffer + *(buffer.GetData() + buffer.GetSize() - 1) = 0; // Zero last byte of destination buffer pBitStream->ResetReadPointer(); pBitStream->ReadBits(buffer.GetData() + uiHeadSize, uiBitStreamBitsUsed); @@ -375,7 +375,7 @@ bool DoStaticProcessPacket(unsigned char ucPacketID, NetPlayerID remoteId, NetBi void DoDisconnectRemote(NetPlayerID remoteId, const SString& strReason) { - g_pCore->ShowMessageBox(_("Error") + _E("CD61"), strReason, MB_BUTTON_OK | MB_ICON_ERROR); // DoDisconnectRemote + g_pCore->ShowMessageBox(_("Error") + _E("CD61"), strReason, MB_BUTTON_OK | MB_ICON_ERROR); // DoDisconnectRemote g_pCore->GetModManager()->RequestUnload(); } diff --git a/Shared/mods/deathmatch/logic/CLatentTransferManager.h b/Shared/mods/deathmatch/logic/CLatentTransferManager.h index 70510614dfe..7850b18d939 100644 --- a/Shared/mods/deathmatch/logic/CLatentTransferManager.h +++ b/Shared/mods/deathmatch/logic/CLatentTransferManager.h @@ -32,10 +32,10 @@ namespace LatentTransfer CATEGORY_PACKET, }; - const static int MIN_SEND_RATE = 500; // Bytes per second + const static int MIN_SEND_RATE = 500; // Bytes per second const static int MIN_PACKET_SIZE = 500; - const static int MAX_PACKET_SIZE = 1100; // Set to 1100 as MTU is hard coded at 1200 (as of 2012-01-28) -}; // namespace LatentTransfer + const static int MAX_PACKET_SIZE = 1100; // Set to 1100 as MTU is hard coded at 1200 (as of 2012-01-28) +}; // namespace LatentTransfer // // One complete item to send @@ -56,18 +56,18 @@ struct SSendItem { } - uint uiId; // Handle - CBufferRef bufferRef; // The data to transfer - uint uiRate; // Desired bytes per second - ushort usCategory; // Data category - uint uiReadPosition; // Current position in the buffer sent so far - bool bSendStarted; // true when the send actually starts - bool bSendFinishing; // true when the last part has been sent - void* pLuaMain; // For cancelling by VM - ushort usResourceNetId; // Only allow packet if this resource is running (ignored if 0xFFFF) - - int iEstSendDurationMsRemaining; // Used for status calculations - int iEstSendDurationMsUsed; // '' + uint uiId; // Handle + CBufferRef bufferRef; // The data to transfer + uint uiRate; // Desired bytes per second + ushort usCategory; // Data category + uint uiReadPosition; // Current position in the buffer sent so far + bool bSendStarted; // true when the send actually starts + bool bSendFinishing; // true when the last part has been sent + void* pLuaMain; // For cancelling by VM + ushort usResourceNetId; // Only allow packet if this resource is running (ignored if 0xFFFF) + + int iEstSendDurationMsRemaining; // Used for status calculations + int iEstSendDurationMsUsed; // '' }; // @@ -77,14 +77,14 @@ struct SReceiveItem { SReceiveItem() : usId(0), uiRate(0), usCategory(0), usResourceNetId(0xFFFF), uiWritePosition(0), bReceiveStarted(false) {} - ushort usId; // Part of handle - Used for verification - CBuffer buffer; // The receive buffer - uint uiRate; // Desired bytes per second (Info from the sender - not really used for anything here yet) - ushort usCategory; // Data category - ushort usResourceNetId; // Only allow packet if this resource is running (ignored if 0xFFFF) + ushort usId; // Part of handle - Used for verification + CBuffer buffer; // The receive buffer + uint uiRate; // Desired bytes per second (Info from the sender - not really used for anything here yet) + ushort usCategory; // Data category + ushort usResourceNetId; // Only allow packet if this resource is running (ignored if 0xFFFF) - uint uiWritePosition; // Current position in the buffer received so far - bool bReceiveStarted; // true when the receive actually starts + uint uiWritePosition; // Current position in the buffer received so far + bool bReceiveStarted; // true when the receive actually starts }; // @@ -92,10 +92,10 @@ struct SReceiveItem // struct SSendStatus { - int iStartTimeMsOffset; // Est. start time (Negative if already started) - int iEndTimeMsOffset; // Est. end time + int iStartTimeMsOffset; // Est. start time (Negative if already started) + int iEndTimeMsOffset; // Est. end time int iTotalSize; - double dPercentComplete; // How much done + double dPercentComplete; // How much done }; /////////////////////////////////////////////////////////////// diff --git a/Shared/mods/deathmatch/logic/CScriptDebugging.cpp b/Shared/mods/deathmatch/logic/CScriptDebugging.cpp index a303c010efe..ff37d7d7481 100644 --- a/Shared/mods/deathmatch/logic/CScriptDebugging.cpp +++ b/Shared/mods/deathmatch/logic/CScriptDebugging.cpp @@ -70,24 +70,21 @@ void CScriptDebugging::LogPCallError(lua_State* luaVM, const SString& strRes, bo bool CScriptDebugging::CheckForSufficientDebugLevel(std::uint8_t playerDebugLevel, std::uint8_t messageDebugLevel) const noexcept { - bool sufficientDebugLevel = false; - switch (messageDebugLevel) { case MESSAGE_TYPE_ERROR: - sufficientDebugLevel = (playerDebugLevel >= ERRORS_ONLY); - break; + return playerDebugLevel >= ERRORS_ONLY; case MESSAGE_TYPE_WARNING: - sufficientDebugLevel = (playerDebugLevel >= ERRORS_AND_WARNINGS); - break; + return playerDebugLevel >= ERRORS_AND_WARNINGS; case MESSAGE_TYPE_INFO: case MESSAGE_TYPE_CUSTOM: case MESSAGE_TYPE_DEBUG: - sufficientDebugLevel = (playerDebugLevel == ALL); + return playerDebugLevel == ALL; + default: break; } - return sufficientDebugLevel; + return false; } void CScriptDebugging::LogCustom(lua_State* luaVM, unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue, const char* szFormat, ...) diff --git a/Shared/mods/deathmatch/logic/CStringName.cpp b/Shared/mods/deathmatch/logic/CStringName.cpp index f3d6d18df81..9bfc5778e73 100644 --- a/Shared/mods/deathmatch/logic/CStringName.cpp +++ b/Shared/mods/deathmatch/logic/CStringName.cpp @@ -15,7 +15,7 @@ extern "C" { - #include "lua/src/lstring.h" +#include "lua/src/lstring.h" } static StringNameHash MakeStringNameHash(const std::string_view& str) @@ -37,8 +37,8 @@ class CStringNameStorage return &ZERO_NAME_DATA; } - const StringNameHash hash = MakeStringNameHash(str); - const uint32_t idx = hash & CStringName::STRING_TABLE_MASK; + const StringNameHash hash = MakeStringNameHash(str); + const uint32_t idx = hash & CStringName::STRING_TABLE_MASK; CIntrusiveDoubleLinkedList& list = m_table[idx]; CStringNameData* data = list.First(); @@ -59,7 +59,7 @@ class CStringNameStorage data->AddRef(); return data; - } + } void Release(CStringNameData* data) { @@ -71,7 +71,7 @@ class CStringNameStorage CStringNameData* Find(const std::string_view& str, StringNameHash hash) { - const uint32_t idx = hash & CStringName::STRING_TABLE_MASK; + const uint32_t idx = hash & CStringName::STRING_TABLE_MASK; CIntrusiveDoubleLinkedList& list = m_table[idx]; for (CStringNameData& data : list) @@ -95,7 +95,7 @@ class CStringNameStorage std::array, CStringName::STRING_TABLE_LEN> m_table; }; -CStringNameData CStringNameStorage::ZERO_NAME_DATA{ {}, 0u, 1 }; +CStringNameData CStringNameStorage::ZERO_NAME_DATA{{}, 0u, 1}; /* CStringNameData @@ -119,35 +119,29 @@ void CStringNameData::RemoveRef() */ const CStringName CStringName::ZERO{}; -CStringName::CStringName() : - m_data(CStringNameStorage::Instance().Get({})) +CStringName::CStringName() : m_data(CStringNameStorage::Instance().Get({})) { } -CStringName::CStringName(const char* str) : - m_data(CStringNameStorage::Instance().Get(str)) +CStringName::CStringName(const char* str) : m_data(CStringNameStorage::Instance().Get(str)) { } -CStringName::CStringName(const std::string& str) : - m_data(CStringNameStorage::Instance().Get(str)) +CStringName::CStringName(const std::string& str) : m_data(CStringNameStorage::Instance().Get(str)) { } -CStringName::CStringName(const std::string_view& str) : - m_data(CStringNameStorage::Instance().Get(str)) +CStringName::CStringName(const std::string_view& str) : m_data(CStringNameStorage::Instance().Get(str)) { } -CStringName::CStringName(const CStringName& name) : - m_data(name.m_data) +CStringName::CStringName(const CStringName& name) : m_data(name.m_data) { if (m_data) m_data->AddRef(); } -CStringName::CStringName(CStringNameData* data) : - m_data(data) +CStringName::CStringName(CStringNameData* data) : m_data(data) { if (m_data) m_data->AddRef(); diff --git a/Shared/mods/deathmatch/logic/CStringName.h b/Shared/mods/deathmatch/logic/CStringName.h index cd3fa79f022..bece80c9ee0 100644 --- a/Shared/mods/deathmatch/logic/CStringName.h +++ b/Shared/mods/deathmatch/logic/CStringName.h @@ -22,12 +22,7 @@ class CStringNameData : public CIntrusiveDoubleLinkedListNode public: CStringNameData() = default; - CStringNameData(const std::string_view& name, StringNameHash hash, size_t refs = 0) : - m_name(name), - m_hash(hash), - m_refs(refs) - { - } + CStringNameData(const std::string_view& name, StringNameHash hash, size_t refs = 0) : m_name(name), m_hash(hash), m_refs(refs) {} void AddRef(); @@ -44,11 +39,12 @@ class CStringName { friend class CStringNameStorage; - enum { - STRING_TABLE_BITS = 16, - STRING_TABLE_LEN = 1 << STRING_TABLE_BITS, - STRING_TABLE_MASK = STRING_TABLE_LEN - 1 - }; + enum + { + STRING_TABLE_BITS = 16, + STRING_TABLE_LEN = 1 << STRING_TABLE_BITS, + STRING_TABLE_MASK = STRING_TABLE_LEN - 1 + }; public: // Default constructor @@ -67,32 +63,32 @@ class CStringName CStringName(const CStringName& name); // Copy-assignment from another string name. - CStringName& operator =(const CStringName& name); + CStringName& operator=(const CStringName& name); // Copy-assignment from string. - CStringName& operator =(const std::string& str); + CStringName& operator=(const std::string& str); // Copy-assignment from string view. - CStringName& operator =(const std::string_view& str); + CStringName& operator=(const std::string_view& str); // Destruct ~CStringName(); // Test for equality with another string name. - bool operator ==(const CStringName& rhs) const { return m_data == rhs.m_data; } + bool operator==(const CStringName& rhs) const { return m_data == rhs.m_data; } // Test for inequality with another string name. - bool operator !=(const CStringName& rhs) const { return m_data != rhs.m_data; } + bool operator!=(const CStringName& rhs) const { return m_data != rhs.m_data; } // Test if less than another string name. - bool operator <(const CStringName& rhs) const { return m_data->m_hash < rhs.m_data->m_hash; } + bool operator<(const CStringName& rhs) const { return m_data->m_hash < rhs.m_data->m_hash; } // Test if greater than another string name. - bool operator >(const CStringName& rhs) const { return m_data->m_hash > rhs.m_data->m_hash; } + bool operator>(const CStringName& rhs) const { return m_data->m_hash > rhs.m_data->m_hash; } - const std::string* operator ->() const { return &m_data->m_name; } + const std::string* operator->() const { return &m_data->m_name; } - const std::string& operator *() const { return m_data->m_name; } + const std::string& operator*() const { return m_data->m_name; } // Return true if nonzero string name value. explicit operator bool() const { return m_data != nullptr; } @@ -122,14 +118,11 @@ class CStringName private: // String name data - CStringNameData* m_data{}; + CStringNameData* m_data{}; }; template <> struct std::hash { - std::size_t operator()(const CStringName& k) const - { - return static_cast(k.Hash()); - } + std::size_t operator()(const CStringName& k) const { return static_cast(k.Hash()); } }; diff --git a/Shared/mods/deathmatch/logic/CameraScriptShared.h b/Shared/mods/deathmatch/logic/CameraScriptShared.h new file mode 100644 index 00000000000..3cd4e84a5af --- /dev/null +++ b/Shared/mods/deathmatch/logic/CameraScriptShared.h @@ -0,0 +1,47 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: Shared/mods/deathmatch/logic/CameraScriptShared.h + * PURPOSE: Shared helpers for camera scripting sanitization + * + * Multi Theft Auto is available from https://multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include +#include + +namespace CameraScriptShared +{ + constexpr float kDefaultFOV = 70.0f; + constexpr float kMaxFOV = 179.0f; + constexpr float kFullRotationDegrees = 360.0f; + + inline bool IsFiniteVector(const CVector& vec) noexcept + { + return std::isfinite(vec.fX) && std::isfinite(vec.fY) && std::isfinite(vec.fZ); + } + + inline float SanitizeFOV(float fov) noexcept + { + if (!std::isfinite(fov) || fov <= 0.0f) + return kDefaultFOV; + if (fov >= 180.0f) + return kMaxFOV; + return fov; + } + + inline float NormalizeRoll(float rollDegrees) noexcept + { + if (!std::isfinite(rollDegrees)) + return 0.0f; + + float normalized = std::remainder(rollDegrees, kFullRotationDegrees); + if (normalized < 0.0f) + normalized += kFullRotationDegrees; + return normalized; + } +} diff --git a/Shared/mods/deathmatch/logic/Utils.cpp b/Shared/mods/deathmatch/logic/Utils.cpp index 9122d38d6ca..8be1bd7ed1e 100644 --- a/Shared/mods/deathmatch/logic/Utils.cpp +++ b/Shared/mods/deathmatch/logic/Utils.cpp @@ -84,8 +84,8 @@ bool IsValidFilePath(const char* szDir) // iterate through the char array for (unsigned int i = 0; i < uiLen; i++) { - c = szDir[i]; // current character - c_d = (i < (uiLen - 1)) ? szDir[i + 1] : 0; // one character ahead, if any + c = szDir[i]; // current character + c_d = (i < (uiLen - 1)) ? szDir[i + 1] : 0; // one character ahead, if any if (!IsVisibleCharacter(c) || c == ':' || (c == '.' && c_d == '.') || (c == '\\' && c_d == '\\')) return false; } @@ -102,8 +102,8 @@ bool IsValidFilePath(const char* szDir, size_t length) // iterate through the char array for (size_t i = 0; i < length; i++) { - c = szDir[i]; // current character - c_d = (i < (length - 1)) ? szDir[i + 1] : 0; // one character ahead, if any + c = szDir[i]; // current character + c_d = (i < (length - 1)) ? szDir[i + 1] : 0; // one character ahead, if any if (!IsVisibleCharacter(c) || c == ':' || (c == '.' && c_d == '.') || (c == '\\' && c_d == '\\')) return false; } @@ -119,9 +119,9 @@ void ReplaceOccurrencesInString(std::string& s, const char* a, const char* b) void RaiseFatalError(unsigned int uiCode) { -#ifdef MTA_DEBUG + #ifdef MTA_DEBUG assert(0); -#endif + #endif // Populate the message and show the box SString strBuffer(_("Fatal error (%u). If this problem persists, please check out multitheftauto.com for support."), uiCode); @@ -142,7 +142,7 @@ void RaiseProtocolError(unsigned int uiCode) // Populate the message and show the box SString strBuffer(_("Protocol error (%u). If this problem persists, please check out multitheftauto.com for support."), uiCode); SString strTroubleLink(SString("protocol-error&code=%d", uiCode)); - g_pCore->ShowErrorMessageBox(_("Connection error") + _E("CD63"), strBuffer, strTroubleLink); // Protocol error + g_pCore->ShowErrorMessageBox(_("Connection error") + _E("CD63"), strBuffer, strTroubleLink); // Protocol error // Request the mod unload g_pCore->GetModManager()->RequestUnload(); @@ -186,32 +186,29 @@ void AttachedMatrix(const CMatrix& matrix, CMatrix& returnMatrix, const CVector& void LongToDottedIP(unsigned long ulIP, char* szDottedIP) { - in_addr in{}; - in.s_addr = ulIP; - char* szTemp = inet_ntoa(in); - if (szTemp) - { - strncpy(szDottedIP, szTemp, 22); - } - else - { - szDottedIP[0] = 0; - } + const unsigned char b1 = static_cast((ulIP >> 24) & 0xFF); + const unsigned char b2 = static_cast((ulIP >> 16) & 0xFF); + const unsigned char b3 = static_cast((ulIP >> 8) & 0xFF); + const unsigned char b4 = static_cast(ulIP & 0xFF); + + const SString str = SString("%u.%u.%u.%u", b1, b2, b3, b4); + strncpy(szDottedIP, str, 22); + szDottedIP[21] = 0; } #else bool DoesDirectoryExist(const char* szPath) { -#ifdef WIN32 + #ifdef WIN32 DWORD dwAtr = GetFileAttributes(szPath); if (dwAtr == INVALID_FILE_ATTRIBUTES) return false; return ((dwAtr & FILE_ATTRIBUTE_DIRECTORY) != 0); -#else + #else struct stat Info; stat(szPath, &Info); return (S_ISDIR(Info.st_mode)); -#endif + #endif } bool CheckNickProvided(const char* szNick) @@ -376,22 +373,22 @@ void DisconnectConnectionDesync(CGame* pGame, CPlayer& Player, unsigned int uiCo bool InitializeSockets() { -#ifdef WIN32 + #ifdef WIN32 WSADATA wsaData; if (WSAStartup(0x202, &wsaData) == SOCKET_ERROR) { WSACleanup(); return false; } -#endif + #endif return true; } bool CleanupSockets() { -#ifdef WIN32 + #ifdef WIN32 WSACleanup(); -#endif + #endif return true; } #endif @@ -461,7 +458,7 @@ bool IsValidFilePath(const char* szDir) unsigned int uiLen = strlen(szDir); - if (uiLen > 0 && szDir[uiLen - 1] == '/') // will return false if ending with an invalid character, mainly used for linux (#6871) + if (uiLen > 0 && szDir[uiLen - 1] == '/') // will return false if ending with an invalid character, mainly used for linux (#6871) return false; unsigned char c, c_d; @@ -469,8 +466,8 @@ bool IsValidFilePath(const char* szDir) // iterate through the char array for (unsigned int i = 0; i < uiLen; i++) { - c = szDir[i]; // current character - c_d = (i < (uiLen - 1)) ? szDir[i + 1] : 0; // one character ahead, if any + c = szDir[i]; // current character + c_d = (i < (uiLen - 1)) ? szDir[i + 1] : 0; // one character ahead, if any if (!IsVisibleCharacter(c) || c == ':' || (c == '.' && c_d == '.') || (c == '\\' && c_d == '\\')) return false; } @@ -487,8 +484,8 @@ bool IsValidFilePath(const char* szDir, size_t length) // iterate through the char array for (size_t i = 0; i < length; i++) { - c = szDir[i]; // current character - c_d = (i < (length - 1)) ? szDir[i + 1] : 0; // one character ahead, if any + c = szDir[i]; // current character + c_d = (i < (length - 1)) ? szDir[i + 1] : 0; // one character ahead, if any if (!IsVisibleCharacter(c) || c == ':' || (c == '.' && c_d == '.') || (c == '\\' && c_d == '\\')) return false; } @@ -502,7 +499,7 @@ bool IsValidOrganizationPath(const char* szDir) unsigned int uiLen = strlen(szDir); - if (uiLen > 0 && szDir[uiLen - 1] == '/') // will return false if ending with an invalid character, mainly used for linux (#6871) + if (uiLen > 0 && szDir[uiLen - 1] == '/') // will return false if ending with an invalid character, mainly used for linux (#6871) return false; unsigned char c; @@ -511,7 +508,7 @@ bool IsValidOrganizationPath(const char* szDir) // iterate through the char array for (unsigned int i = 0; i < uiLen; i++) { - c = szDir[i]; // current character + c = szDir[i]; // current character // Enforce braces around visible letters if (!bInsideBraces && IsVisibleCharacter(c) && c != '[' && c != ']' && c != '/' && c != '\\') @@ -520,21 +517,21 @@ bool IsValidOrganizationPath(const char* szDir) if (c == '[') { if (bInsideBraces) - return false; // Duplicate braces (e.g. "[hel[lo]world]") + return false; // Duplicate braces (e.g. "[hel[lo]world]") else bInsideBraces = true; } else if (c == ']') { if (!bInsideBraces) - return false; // Ending brace without opening brace (e.g. "hello]") + return false; // Ending brace without opening brace (e.g. "hello]") else bInsideBraces = false; } else if (c == '/' || c == '\\') { if (bInsideBraces) - return false; // Slash within braches (e.g. "[hell/o]") + return false; // Slash within braches (e.g. "[hell/o]") } } @@ -730,47 +727,43 @@ bool ReadSmallKeysync(CControllerState& ControllerState, NetBitStreamInterface& if (!BitStream.Read(&keys)) return false; - // Put the result into the controllerstate - ControllerState.LeftShoulder1 = keys.data.bLeftShoulder1; - ControllerState.RightShoulder1 = keys.data.bRightShoulder1; short sButtonSquare = keys.data.bButtonSquare ? 255 : 0; short sButtonCross = keys.data.bButtonCross ? 255 : 0; - if (BitStream.Can(eBitStreamVersion::AnalogControlSync_AccelBrakeReverse)) { if (keys.data.ucButtonSquare != 0) - sButtonSquare = (short)keys.data.ucButtonSquare; // override controller state with analog data if present + sButtonSquare = (short)keys.data.ucButtonSquare; // override controller state with analog data if present if (keys.data.ucButtonCross != 0) - sButtonCross = (short)keys.data.ucButtonCross; // override controller state with analog data if present + sButtonCross = (short)keys.data.ucButtonCross; // override controller state with analog data if present } + + // Put the result into the controllerstate + ControllerState.LeftShoulder1 = keys.data.bLeftShoulder1; + ControllerState.RightShoulder1 = keys.data.bRightShoulder1; ControllerState.ButtonSquare = sButtonSquare; ControllerState.ButtonCross = sButtonCross; ControllerState.ButtonCircle = keys.data.bButtonCircle; ControllerState.ButtonTriangle = keys.data.bButtonTriangle; ControllerState.ShockButtonL = keys.data.bShockButtonL; ControllerState.m_bPedWalk = keys.data.bPedWalk; - if (BitStream.Version() >= 0x2C) - { - ControllerState.LeftStickX = keys.data.sLeftStickX; - ControllerState.LeftStickY = keys.data.sLeftStickY; - } - + ControllerState.LeftStickX = keys.data.sLeftStickX; + ControllerState.LeftStickY = keys.data.sLeftStickY; return true; } void WriteSmallKeysync(const CControllerState& ControllerState, NetBitStreamInterface& BitStream) { SSmallKeysyncSync keys; - keys.data.bLeftShoulder1 = (ControllerState.LeftShoulder1 != 0); // Action / Secondary-Fire - keys.data.bRightShoulder1 = (ControllerState.RightShoulder1 != 0); // Aim-Weapon / Handbrake - keys.data.bButtonSquare = (ControllerState.ButtonSquare != 0); // Jump / Reverse - keys.data.bButtonCross = (ControllerState.ButtonCross != 0); // Sprint / Accelerate - keys.data.bButtonCircle = (ControllerState.ButtonCircle != 0); // Fire // Fire - keys.data.bButtonTriangle = (ControllerState.ButtonTriangle != 0); // Enter/Exit/Special-Attack / Enter/exit - keys.data.bShockButtonL = (ControllerState.ShockButtonL != 0); // Crouch / Horn - keys.data.bPedWalk = (ControllerState.m_bPedWalk != 0); // Walk / - - keys.data.ucButtonSquare = (unsigned char)ControllerState.ButtonSquare; // Reverse - keys.data.ucButtonCross = (unsigned char)ControllerState.ButtonCross; // Accelerate + keys.data.bLeftShoulder1 = (ControllerState.LeftShoulder1 != 0); // Action / Secondary-Fire + keys.data.bRightShoulder1 = (ControllerState.RightShoulder1 != 0); // Aim-Weapon / Handbrake + keys.data.bButtonSquare = (ControllerState.ButtonSquare != 0); // Jump / Reverse + keys.data.bButtonCross = (ControllerState.ButtonCross != 0); // Sprint / Accelerate + keys.data.bButtonCircle = (ControllerState.ButtonCircle != 0); // Fire // Fire + keys.data.bButtonTriangle = (ControllerState.ButtonTriangle != 0); // Enter/Exit/Special-Attack / Enter/exit + keys.data.bShockButtonL = (ControllerState.ShockButtonL != 0); // Crouch / Horn + keys.data.bPedWalk = (ControllerState.m_bPedWalk != 0); // Walk / - + keys.data.ucButtonSquare = (unsigned char)ControllerState.ButtonSquare; // Reverse + keys.data.ucButtonCross = (unsigned char)ControllerState.ButtonCross; // Accelerate keys.data.sLeftStickX = ControllerState.LeftStickX; keys.data.sLeftStickY = ControllerState.LeftStickY; @@ -785,19 +778,19 @@ bool ReadFullKeysync(CControllerState& ControllerState, NetBitStreamInterface& B if (!BitStream.Read(&keys)) return false; - // Put the result into the controllerstate - ControllerState.LeftShoulder1 = keys.data.bLeftShoulder1; - ControllerState.RightShoulder1 = keys.data.bRightShoulder1; short sButtonSquare = keys.data.bButtonSquare ? 255 : 0; short sButtonCross = keys.data.bButtonCross ? 255 : 0; - if (BitStream.Can(eBitStreamVersion::AnalogControlSync_AccelBrakeReverse)) { if (keys.data.ucButtonSquare != 0) - sButtonSquare = (short)keys.data.ucButtonSquare; // override controller state with analog data if present + sButtonSquare = (short)keys.data.ucButtonSquare; // override controller state with analog data if present if (keys.data.ucButtonCross != 0) - sButtonCross = (short)keys.data.ucButtonCross; // override controller state with analog data if present + sButtonCross = (short)keys.data.ucButtonCross; // override controller state with analog data if present } + + // Put the result into the controllerstate + ControllerState.LeftShoulder1 = keys.data.bLeftShoulder1; + ControllerState.RightShoulder1 = keys.data.bRightShoulder1; ControllerState.ButtonSquare = sButtonSquare; ControllerState.ButtonCross = sButtonCross; ControllerState.ButtonCircle = keys.data.bButtonCircle; @@ -806,7 +799,6 @@ bool ReadFullKeysync(CControllerState& ControllerState, NetBitStreamInterface& B ControllerState.m_bPedWalk = keys.data.bPedWalk; ControllerState.LeftStickX = keys.data.sLeftStickX; ControllerState.LeftStickY = keys.data.sLeftStickY; - return true; } @@ -861,10 +853,10 @@ void ReadCameraOrientation(const CVector& vecBasePosition, NetBitStreamInterface uint uiNumBits; float fRange; } bitCountTable[4] = { - {3, 4.0f}, // 3 bits is +-4 12 bits total - {5, 16.0f}, // 5 bits is +-16 18 bits total - {9, 256.0f}, // 9 bits is +-256 30 bits total - {14, 8192.0f}, // 14 bits is +-8192 45 bits total + {3, 4.0f}, // 3 bits is +-4 12 bits total + {5, 16.0f}, // 5 bits is +-16 18 bits total + {9, 256.0f}, // 9 bits is +-256 30 bits total + {14, 8192.0f}, // 14 bits is +-8192 45 bits total }; // Read flag bool bUseAbsolutePosition = false; @@ -977,9 +969,12 @@ void RotateVector(CVector& vecLine, const CVector& vecRotation) SString LongToDottedIP(unsigned long ulIP) { - in_addr in; - in.s_addr = ulIP; - return inet_ntoa(in); + const unsigned char b1 = static_cast((ulIP >> 24) & 0xFF); + const unsigned char b2 = static_cast((ulIP >> 16) & 0xFF); + const unsigned char b3 = static_cast((ulIP >> 8) & 0xFF); + const unsigned char b4 = static_cast(ulIP & 0xFF); + + return SString("%u.%u.%u.%u", b1, b2, b3, b4); } #endif @@ -1011,7 +1006,7 @@ SString LongToDottedIP(unsigned long ulIP) CVector euler_ZXY_to_ZYX(const CVector& a_vZXY) { CVector vZXY(a_vZXY); - ConvertDegreesToRadiansNoWrap(vZXY); // NoWrap for this conversion since it's used for cos/sin only + ConvertDegreesToRadiansNoWrap(vZXY); // NoWrap for this conversion since it's used for cos/sin only float cx = cos(vZXY.fX); float sx = sin(vZXY.fX); @@ -1043,7 +1038,7 @@ CVector euler_ZXY_to_ZYX(const CVector& a_vZXY) CVector euler_ZYX_to_ZXY(const CVector& a_vZYX) { CVector vZYX(a_vZYX); - ConvertDegreesToRadiansNoWrap(vZYX); // NoWrap for this conversion since it's used for cos/sin only + ConvertDegreesToRadiansNoWrap(vZYX); // NoWrap for this conversion since it's used for cos/sin only float cx = cos(vZYX.fX); float sx = sin(vZYX.fX); diff --git a/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h b/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h index c4f74a3d9c5..9cf6f73f0e3 100644 --- a/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h +++ b/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h @@ -26,8 +26,7 @@ class LuaFunctionError bool m_bWarning; public: - constexpr LuaFunctionError(const char* what, bool throwWarning = true) noexcept - : m_message(what), m_bWarning(throwWarning) {} + constexpr LuaFunctionError(const char* what, bool throwWarning = true) noexcept : m_message(what), m_bWarning(throwWarning) {} constexpr const char* what() const noexcept { return m_message; } constexpr bool IsWarning() const noexcept { return m_bWarning; } @@ -95,7 +94,7 @@ struct CLuaFunctionParserBase else if constexpr (std::is_same_v) return "colour"; else if constexpr (std::is_same_v) - return ""; // not reachable + return ""; // not reachable else if constexpr (is_variant::value) { SString strTypes; @@ -325,10 +324,9 @@ struct CLuaFunctionParserBase return false; using class_t = std::remove_pointer_t; - int tempIndex{index}; - void* pValue = lua::PopPrimitive(L, tempIndex); - auto result = iArgument == LUA_TLIGHTUSERDATA ? UserDataCast((class_t*)pValue, L) : - UserDataCast(*reinterpret_cast(pValue), L); + int tempIndex{index}; + void* pValue = lua::PopPrimitive(L, tempIndex); + auto result = iArgument == LUA_TLIGHTUSERDATA ? UserDataCast((class_t*)pValue, L) : UserDataCast(*reinterpret_cast(pValue), L); return result != nullptr; } @@ -410,7 +408,7 @@ struct CLuaFunctionParserBase return lua::PopPrimitive(L, index); else if constexpr (std::is_same_v) return lua::PopPrimitive(L, index); - else if constexpr (std::is_integral_v || std::is_floating_point_v) // bool is an integral type, so must pop it before ^^ + else if constexpr (std::is_integral_v || std::is_floating_point_v) // bool is an integral type, so must pop it before ^^ { const auto number = lua::PopPrimitive(L, index); @@ -481,7 +479,7 @@ struct CLuaFunctionParserBase return std::nullopt; } - else if constexpr (is_2specialization::value) // 2 specialization due to allocator + else if constexpr (is_2specialization::value) // 2 specialization due to allocator { using param = typename is_2specialization::param1_t; T vecData; @@ -497,7 +495,7 @@ struct CLuaFunctionParserBase int i = -1; vecData.emplace_back(PopUnsafe(L, i)); - lua_pop(L, 1); // drop value, keep key for lua_next + lua_pop(L, 1); // drop value, keep key for lua_next } ++index; return vecData; @@ -527,7 +525,7 @@ struct CLuaFunctionParserBase auto v = PopUnsafe(L, i); auto k = PopUnsafe(L, i); map.emplace(std::move(k), std::move(v)); - lua_pop(L, 2); // drop values(key copy and value), keep original key for lua_next + lua_pop(L, 2); // drop values(key copy and value), keep original key for lua_next } ++index; return map; @@ -579,9 +577,10 @@ struct CLuaFunctionParserBase int iType = lua_type(L, index); bool isLightUserData = iType == LUA_TLIGHTUSERDATA; void* pValue = lua::PopPrimitive(L, index); - auto cast = [isLightUserData, pValue, L](auto null) { + auto cast = [isLightUserData, pValue, L](auto null) + { return isLightUserData ? UserDataCast(reinterpret_cast(pValue), L) - : UserDataCast(*reinterpret_cast(pValue), L); + : UserDataCast(*reinterpret_cast(pValue), L); }; // A vector2 may also be filled from a vector3/vector4 if (CLuaVector2D* pVec2D = cast((CLuaVector2D*)0); pVec2D != nullptr) @@ -609,9 +608,10 @@ struct CLuaFunctionParserBase int iType = lua_type(L, index); bool isLightUserData = iType == LUA_TLIGHTUSERDATA; void* pValue = lua::PopPrimitive(L, index); - auto cast = [isLightUserData, pValue, L](auto null) { + auto cast = [isLightUserData, pValue, L](auto null) + { return isLightUserData ? UserDataCast(reinterpret_cast(pValue), L) - : UserDataCast(*reinterpret_cast(pValue), L); + : UserDataCast(*reinterpret_cast(pValue), L); }; // A vector3 may also be filled from a vector4 if (CLuaVector3D* pVec3D = cast((CLuaVector3D*)0); pVec3D != nullptr) @@ -638,9 +638,10 @@ struct CLuaFunctionParserBase int iType = lua_type(L, index); bool isLightUserData = iType == LUA_TLIGHTUSERDATA; void* pValue = lua::PopPrimitive(L, index); - auto cast = [isLightUserData, pValue, L](auto null) { + auto cast = [isLightUserData, pValue, L](auto null) + { return isLightUserData ? UserDataCast(reinterpret_cast(pValue), L) - : UserDataCast(*reinterpret_cast(pValue), L); + : UserDataCast(*reinterpret_cast(pValue), L); }; // A vector3 may also be filled from a vector4 if (CLuaVector4D* pVec4D = cast((CLuaVector4D*)0); pVec4D != nullptr) @@ -689,9 +690,10 @@ struct CLuaFunctionParserBase int iType = lua_type(L, index); bool isLightUserData = iType == LUA_TLIGHTUSERDATA; void* pValue = lua::PopPrimitive(L, index); - auto cast = [isLightUserData, pValue, L](auto null) { + auto cast = [isLightUserData, pValue, L](auto null) + { return isLightUserData ? UserDataCast(reinterpret_cast(pValue), L) - : UserDataCast(*reinterpret_cast(pValue), L); + : UserDataCast(*reinterpret_cast(pValue), L); }; // A vector4 may also be filled from a CLuaMatrix if (CLuaMatrix* pMatrix = cast((CLuaMatrix*)0); pMatrix != nullptr) @@ -832,7 +834,7 @@ struct CLuaFunctionParser : CLuaFunctionP // Case where F is a class method pointer // Note: If you see weird compiler errors like: Undefined type, overload resolution failed, etc.. // Ask on Dev Discord(#new-argument-parser), because rn this implementation is pretty beta. - 03/2021 -template +template struct CLuaFunctionParser { // Remove constness here, because we must be able to std::move diff --git a/Shared/mods/deathmatch/logic/lua/CLuaOverloadParser.h b/Shared/mods/deathmatch/logic/lua/CLuaOverloadParser.h index 7e77df4ebd0..be5a61eaf01 100644 --- a/Shared/mods/deathmatch/logic/lua/CLuaOverloadParser.h +++ b/Shared/mods/deathmatch/logic/lua/CLuaOverloadParser.h @@ -59,13 +59,14 @@ struct CLuaOverloadParser static ChosenFunction MakeChoice(std::variant var) { return std::visit( - [](auto&& f) { + [](auto&& f) + { using ft = decltype(f); if constexpr (!std::is_convertible_v>) - return ChosenFunction::FUNCB; // if it cannot match A, B it is + return ChosenFunction::FUNCB; // if it cannot match A, B it is if constexpr (!std::is_convertible_v>) - return ChosenFunction::FUNCA; // if it cannot match B, A it is - return ChosenFunction::COMMON; // Both match + return ChosenFunction::FUNCA; // if it cannot match B, A it is + return ChosenFunction::COMMON; // Both match }, var); } diff --git a/Shared/mods/deathmatch/logic/lua/CLuaShared.cpp b/Shared/mods/deathmatch/logic/lua/CLuaShared.cpp index 2b83816e1cf..b64034a46f4 100644 --- a/Shared/mods/deathmatch/logic/lua/CLuaShared.cpp +++ b/Shared/mods/deathmatch/logic/lua/CLuaShared.cpp @@ -78,9 +78,11 @@ void CLuaShared::LoadFunctions() CLuaFileDefs::LoadFunctions(); CLuaXMLDefs::LoadFunctions(); CLuaPathDefs::LoadFunctions(); - CLuaTrainTrackDefs::LoadFunctions(); CLuaUTFDefs::LoadFunctions(); CLuaUtilDefs::LoadFunctions(); + + if (CustomTrainTracks) + CLuaTrainTrackDefs::LoadFunctions(); } void CLuaShared::AddClasses(lua_State* luaVM) @@ -88,6 +90,9 @@ void CLuaShared::AddClasses(lua_State* luaVM) CLuaFileDefs::AddClass(luaVM); CLuaPathDefs::AddClass(luaVM); CLuaXMLDefs::AddClass(luaVM); + + if (CustomTrainTracks) + CLuaTrainTrackDefs::AddClass(luaVM); } SharedUtil::CAsyncTaskScheduler* CLuaShared::GetAsyncTaskScheduler() diff --git a/Shared/mods/deathmatch/logic/lua/CLuaShared.h b/Shared/mods/deathmatch/logic/lua/CLuaShared.h index ee78828134c..046d9b6d00f 100644 --- a/Shared/mods/deathmatch/logic/lua/CLuaShared.h +++ b/Shared/mods/deathmatch/logic/lua/CLuaShared.h @@ -7,7 +7,7 @@ *****************************************************************************/ #pragma once -#define LUA_GC_EXTRA_BYTES 30 // Used in hack to make lua GC more aggressive when using OOP Matrix & Vector +#define LUA_GC_EXTRA_BYTES 30 // Used in hack to make lua GC more aggressive when using OOP Matrix & Vector // Lua function definitions (shared) #include "luadefs/CLuaBitDefs.h" @@ -34,4 +34,11 @@ class CLuaShared // Shared scripting is the only place where we need the async task scheduler // so just go with a hack here static SharedUtil::CAsyncTaskScheduler* GetAsyncTaskScheduler(); + +// Only enable train tracks for custom builds, as this is work in progress and the API may change +#if MTASA_VERSION_TYPE == VERSION_TYPE_CUSTOM + const static bool CustomTrainTracks = true; +#else + const static bool CustomTrainTracks = false; +#endif }; diff --git a/Shared/mods/deathmatch/logic/lua/CLuaStackChecker.h b/Shared/mods/deathmatch/logic/lua/CLuaStackChecker.h index dceb65e7365..2663665b4b4 100644 --- a/Shared/mods/deathmatch/logic/lua/CLuaStackChecker.h +++ b/Shared/mods/deathmatch/logic/lua/CLuaStackChecker.h @@ -47,10 +47,10 @@ namespace lua } } }; -} // namespace lua +} // namespace lua #ifdef MTA_DEBUG -#define LUA_STACK_EXPECT(i) lua::CLuaStackChecker invalidHiddenName(L, i) + #define LUA_STACK_EXPECT(i) lua::CLuaStackChecker invalidHiddenName(L, i) #else -#define LUA_STACK_EXPECT(i) + #define LUA_STACK_EXPECT(i) #endif diff --git a/Shared/mods/deathmatch/logic/lua/CLuaTimer.cpp b/Shared/mods/deathmatch/logic/lua/CLuaTimer.cpp index 5de04e728b8..c3fd609ca99 100644 --- a/Shared/mods/deathmatch/logic/lua/CLuaTimer.cpp +++ b/Shared/mods/deathmatch/logic/lua/CLuaTimer.cpp @@ -46,7 +46,7 @@ void CLuaTimer::ExecuteTimer(CLuaMain* pLuaMain) { lua_State* pState = pLuaMain->GetVM(); - LUA_CHECKSTACK(pState, 1); // Ensure some room + LUA_CHECKSTACK(pState, 1); // Ensure some room // Store the current values of the globals lua_getglobal(pState, "sourceTimer"); diff --git a/Shared/mods/deathmatch/logic/lua/LuaBasic.cpp b/Shared/mods/deathmatch/logic/lua/LuaBasic.cpp index c7b369e4459..109867efcfc 100644 --- a/Shared/mods/deathmatch/logic/lua/LuaBasic.cpp +++ b/Shared/mods/deathmatch/logic/lua/LuaBasic.cpp @@ -42,11 +42,11 @@ namespace lua return lua_touserdata(L, index++); } - template<> + template <> lua_Number PopPrimitive(lua_State* L, int& index) { return lua_tonumber(L, index++); } // Int types aren't Poppable directly, because they need to be checked for under/overflow, NaN, inf -} // namespace lua +} // namespace lua diff --git a/Shared/mods/deathmatch/logic/lua/LuaBasic.h b/Shared/mods/deathmatch/logic/lua/LuaBasic.h index 14e85d1c7e7..d2a8856fc73 100644 --- a/Shared/mods/deathmatch/logic/lua/LuaBasic.h +++ b/Shared/mods/deathmatch/logic/lua/LuaBasic.h @@ -31,24 +31,51 @@ namespace lua // PopTrival should read a simple value of type T from the stack without extra type checks // If whatever is at that point in the stack is not convertible to T, the behavior is undefined template - inline T PopPrimitive(lua_State* L, int& index); + T PopPrimitive(lua_State* L, int& index); // Push should push a value of type T to the Lua Stack // This will always increase the stack size by 1 - inline void Push(lua_State* L, int value) { lua_pushnumber(L, value); } - inline void Push(lua_State* L, unsigned int value) { lua_pushnumber(L, value); } - inline void Push(lua_State* L, float value) { lua_pushnumber(L, value); } - inline void Push(lua_State* L, double value) { lua_pushnumber(L, value); } + inline void Push(lua_State* L, int value) + { + lua_pushnumber(L, value); + } + inline void Push(lua_State* L, unsigned int value) + { + lua_pushnumber(L, value); + } + inline void Push(lua_State* L, float value) + { + lua_pushnumber(L, value); + } + inline void Push(lua_State* L, double value) + { + lua_pushnumber(L, value); + } - inline void Push(lua_State* L, bool value) { lua_pushboolean(L, value); } + inline void Push(lua_State* L, bool value) + { + lua_pushboolean(L, value); + } - inline void Push(lua_State* L, std::nullptr_t) { lua_pushnil(L); } + inline void Push(lua_State* L, std::nullptr_t) + { + lua_pushnil(L); + } - inline void Push(lua_State* L, const char* value) { lua_pushstring(L, value); } + inline void Push(lua_State* L, const char* value) + { + lua_pushstring(L, value); + } - inline void Push(lua_State* L, const std::string& value) { lua_pushlstring(L, value.data(), value.length()); } + inline void Push(lua_State* L, const std::string& value) + { + lua_pushlstring(L, value.data(), value.length()); + } - inline void Push(lua_State* L, const std::string_view& value) { lua_pushlstring(L, value.data(), value.length()); } + inline void Push(lua_State* L, const std::string_view& value) + { + lua_pushlstring(L, value.data(), value.length()); + } inline void Push(lua_State* L, const CLuaArgument& arg) { @@ -61,36 +88,99 @@ namespace lua arg.Push(L); } - inline void Push(lua_State* L, const CLuaArguments& args) { args.PushAsTable(L); } + inline void Push(lua_State* L, const CLuaArguments& args) + { + args.PushAsTable(L); + } - inline void Push(lua_State* L, const CVector2D& value) { lua_pushvector(L, value); } + inline void Push(lua_State* L, const CVector2D& value) + { + lua_pushvector(L, value); + } - inline void Push(lua_State* L, const CVector& value) { lua_pushvector(L, value); } + inline void Push(lua_State* L, const CVector& value) + { + lua_pushvector(L, value); + } - inline void Push(lua_State* L, const CVector4D& value) { lua_pushvector(L, value); } + inline void Push(lua_State* L, const CVector4D& value) + { + lua_pushvector(L, value); + } - inline void Push(lua_State* L, const CMatrix& value) { lua_pushmatrix(L, value); } + inline void Push(lua_State* L, const CMatrix& value) + { + lua_pushmatrix(L, value); + } - // Script entities - #ifdef MTA_CLIENT - inline void Push(lua_State* L, const CClientEntity* value) { lua_pushelement(L, const_cast(value)); } - #else - inline void Push(lua_State* L, const CElement* value) { lua_pushelement(L, const_cast(value)); } - inline void Push(lua_State* L, const CAccount* value) { lua_pushaccount(L, const_cast(value)); } - inline void Push(lua_State* L, const CAccessControlList* value) { lua_pushacl(L, const_cast(value)); } - inline void Push(lua_State* L, const CAccessControlListGroup* value) { lua_pushaclgroup(L, const_cast(value)); } - inline void Push(lua_State* L, const CBan* value) { lua_pushban(L, const_cast(value)); } - inline void Push(lua_State* L, const CTextDisplay* value) { lua_pushtextdisplay(L, const_cast(value)); } - inline void Push(lua_State* L, const CTextItem* value) { lua_pushtextitem(L, const_cast(value)); } - inline void Push(lua_State* L, const CDbJobData* value) { lua_pushquery(L, const_cast(value)); } - #endif - inline void Push(lua_State* L, const CResource* value) { lua_pushresource(L, const_cast(value)); } - inline void Push(lua_State* L, const CXMLNode* value) { lua_pushxmlnode(L, const_cast(value)); } - inline void Push(lua_State* L, const CLuaTimer* value) { lua_pushtimer(L, const_cast(value)); } - inline void Push(lua_State* L, const CLuaVector2D* value) { lua_pushvector(L, *value); } - inline void Push(lua_State* L, const CLuaVector3D* value) { lua_pushvector(L, *value); } - inline void Push(lua_State* L, const CLuaVector4D* value) { lua_pushvector(L, *value); } - inline void Push(lua_State* L, const CLuaMatrix* value) { lua_pushmatrix(L, *value); } +// Script entities +#ifdef MTA_CLIENT + inline void Push(lua_State* L, const CClientEntity* value) + { + lua_pushelement(L, const_cast(value)); + } +#else + inline void Push(lua_State* L, const CElement* value) + { + lua_pushelement(L, const_cast(value)); + } + inline void Push(lua_State* L, const CAccount* value) + { + lua_pushaccount(L, const_cast(value)); + } + inline void Push(lua_State* L, const CAccessControlList* value) + { + lua_pushacl(L, const_cast(value)); + } + inline void Push(lua_State* L, const CAccessControlListGroup* value) + { + lua_pushaclgroup(L, const_cast(value)); + } + inline void Push(lua_State* L, const CBan* value) + { + lua_pushban(L, const_cast(value)); + } + inline void Push(lua_State* L, const CTextDisplay* value) + { + lua_pushtextdisplay(L, const_cast(value)); + } + inline void Push(lua_State* L, const CTextItem* value) + { + lua_pushtextitem(L, const_cast(value)); + } + inline void Push(lua_State* L, const CDbJobData* value) + { + lua_pushquery(L, const_cast(value)); + } +#endif + inline void Push(lua_State* L, const CResource* value) + { + lua_pushresource(L, const_cast(value)); + } + inline void Push(lua_State* L, const CXMLNode* value) + { + lua_pushxmlnode(L, const_cast(value)); + } + inline void Push(lua_State* L, const CLuaTimer* value) + { + lua_pushtimer(L, const_cast(value)); + } + inline void Push(lua_State* L, const CLuaVector2D* value) + { + lua_pushvector(L, *value); + } + inline void Push(lua_State* L, const CLuaVector3D* value) + { + lua_pushvector(L, *value); + } + inline void Push(lua_State* L, const CLuaVector4D* value) + { + lua_pushvector(L, *value); + } + inline void Push(lua_State* L, const CLuaMatrix* value) + { + lua_pushmatrix(L, *value); + } // Overload for enum types only template @@ -198,9 +288,11 @@ namespace lua // Call Push on each element of the tuple lua_createtable(L, sizeof...(Ts), 0); std::apply( - [L](const auto&... values) { + [L](const auto&... values) + { int key = 1; - auto PushTable = [](lua_State* L, int& key, const auto& value) { + auto PushTable = [](lua_State* L, int& key, const auto& value) + { Push(L, value); lua_rawseti(L, -2, key++); }; @@ -209,4 +301,4 @@ namespace lua }, tuple); } -} // namespace lua +} // namespace lua diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaBitDefs.cpp b/Shared/mods/deathmatch/logic/luadefs/CLuaBitDefs.cpp index a1944039d27..af2ff1ec37d 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaBitDefs.cpp +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaBitDefs.cpp @@ -68,7 +68,8 @@ int CLuaBitDefs::bitNot(lua_State* luaVM) if (!argStream.HasErrors()) { - lua_pushnumber(luaVM, ~uiVar); + const uint uiResult = ~uiVar; + lua_pushnumber(luaVM, static_cast(uiResult)); return 1; } else @@ -184,7 +185,7 @@ int CLuaBitDefs::bitLRotate(lua_State* luaVM) if (!argStream.HasErrors()) { - iDisp &= (32 - 1); // iDisp %= 32 + iDisp &= (32 - 1); // iDisp %= 32 uint uiResult = (uiVar << iDisp) | (uiVar >> (32 - iDisp)); lua_pushnumber(luaVM, uiResult); @@ -209,7 +210,7 @@ int CLuaBitDefs::bitRRotate(lua_State* luaVM) if (!argStream.HasErrors()) { - iDisp &= (32 - 1); // iDisp %= 32 + iDisp &= (32 - 1); // iDisp %= 32 uint uiResult = (uiVar >> iDisp) | (uiVar << (32 - iDisp)); lua_pushnumber(luaVM, uiResult); diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaCryptDefs.cpp b/Shared/mods/deathmatch/logic/luadefs/CLuaCryptDefs.cpp index c0d11305fee..a559e982dfc 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaCryptDefs.cpp +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaCryptDefs.cpp @@ -19,20 +19,18 @@ void CLuaCryptDefs::LoadFunctions() { - constexpr static const std::pair functions[]{ - {"md5", ArgumentParserWarn}, - {"sha256", ArgumentParserWarn}, - {"hash", ArgumentParserWarn}, - {"teaEncode", ArgumentParserWarn}, - {"teaDecode", ArgumentParserWarn}, - {"base64Encode", ArgumentParserWarn}, - {"base64Decode", ArgumentParserWarn}, - {"passwordHash", ArgumentParserWarn}, - {"generateKeyPair", ArgumentParser}, - {"passwordVerify", PasswordVerify}, - {"encodeString", EncodeString}, - {"decodeString", DecodeString} - }; + constexpr static const std::pair functions[]{{"md5", ArgumentParserWarn}, + {"sha256", ArgumentParserWarn}, + {"hash", ArgumentParserWarn}, + {"teaEncode", ArgumentParserWarn}, + {"teaDecode", ArgumentParserWarn}, + {"base64Encode", ArgumentParserWarn}, + {"base64Decode", ArgumentParserWarn}, + {"passwordHash", ArgumentParserWarn}, + {"generateKeyPair", ArgumentParser}, + {"passwordVerify", PasswordVerify}, + {"encodeString", EncodeString}, + {"decodeString", DecodeString}}; // Add functions for (const auto& [name, func] : functions) @@ -62,7 +60,7 @@ std::variant CLuaCryptDefs::Hash(lua_State* const luaVM, Hash switch (hashFunction) { case HashFunctionType::MD5: - return SharedUtil::Hash(strSourceData).ToLower(); + return SharedUtil::Hash(strSourceData).ToLower(); case HashFunctionType::SHA1: return SharedUtil::Hash(strSourceData).ToLower(); @@ -106,7 +104,7 @@ std::variant CLuaCryptDefs::Hash(lua_State* const luaVM, Hash switch (hmacAlgorithm) { case HmacAlgorithm::MD5: - return SharedUtil::Hmac(strSourceData, key).ToLower(); + return SharedUtil::Hmac(strSourceData, key).ToLower(); case HmacAlgorithm::SHA1: return SharedUtil::Hmac(strSourceData, key).ToLower(); @@ -191,11 +189,13 @@ std::variant CLuaCryptDefs::PasswordHash(lua_State* luaVM, st if (pLuaMain) { CLuaShared::GetAsyncTaskScheduler()->PushTask( - [password, salt = options["salt"], cost] { + [password, salt = options["salt"], cost] + { // Execute time-consuming task return SharedUtil::BcryptHash(password, salt, cost); }, - [luaFunctionRef = callback.value()](const SString& hash) { + [luaFunctionRef = callback.value()](const SString& hash) + { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaFunctionRef.GetLuaVM()); if (pLuaMain) { @@ -276,17 +276,19 @@ int CLuaCryptDefs::PasswordVerify(lua_State* luaVM) { lua_pushboolean(luaVM, SharedUtil::BcryptVerify(password, hash)); } - else // Async + else // Async { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); if (pLuaMain) { CLuaShared::GetAsyncTaskScheduler()->PushTask( - [password, hash] { + [password, hash] + { // Execute time-consuming task return SharedUtil::BcryptVerify(password, hash); }, - [luaFunctionRef](const bool& correct) { + [luaFunctionRef](const bool& correct) + { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaFunctionRef.GetLuaVM()); if (pLuaMain) { @@ -336,7 +338,8 @@ std::variant> CLuaCryptDefs::GenerateKey if (pLuaMain) { CLuaShared::GetAsyncTaskScheduler()->PushTask( - [size]() -> std::variant { + [size]() -> std::variant + { // Execute time-consuming task try { @@ -347,7 +350,8 @@ std::variant> CLuaCryptDefs::GenerateKey return {ex.GetWhat()}; } }, - [luaFunctionRef = callback.value()](const auto& result) { + [luaFunctionRef = callback.value()](const auto& result) + { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaFunctionRef.GetLuaVM()); if (pLuaMain) { @@ -434,13 +438,15 @@ int CLuaCryptDefs::EncodeString(lua_State* luaVM) if (pLuaMain) { CLuaShared::GetAsyncTaskScheduler()->PushTask( - [data, key] { + [data, key] + { // Execute time-consuming task SString result; SharedUtil::TeaEncode(data, key, &result); return result; }, - [luaFunctionRef](const SString& result) { + [luaFunctionRef](const SString& result) + { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaFunctionRef.GetLuaVM()); if (pLuaMain) { @@ -453,7 +459,7 @@ int CLuaCryptDefs::EncodeString(lua_State* luaVM) lua_pushboolean(luaVM, true); } } - else // Sync + else // Sync { SString result; SharedUtil::TeaEncode(data, key, &result); @@ -479,7 +485,8 @@ int CLuaCryptDefs::EncodeString(lua_State* luaVM) if (pLuaMain) { CLuaShared::GetAsyncTaskScheduler()->PushTask( - [data, key] { + [data, key] + { std::pair result; try { @@ -490,7 +497,8 @@ int CLuaCryptDefs::EncodeString(lua_State* luaVM) } return result; }, - [luaFunctionRef](const std::pair result) { + [luaFunctionRef](const std::pair result) + { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaFunctionRef.GetLuaVM()); if (pLuaMain) { @@ -512,7 +520,7 @@ int CLuaCryptDefs::EncodeString(lua_State* luaVM) lua_pushboolean(luaVM, true); } } - else // Sync + else // Sync { std::pair result; try @@ -547,7 +555,8 @@ int CLuaCryptDefs::EncodeString(lua_State* luaVM) if (pLuaMain) { CLuaShared::GetAsyncTaskScheduler()->PushTask( - [data, key] { + [data, key] + { try { return std::make_pair(SharedUtil::RsaEncode(data, key), true); @@ -557,7 +566,8 @@ int CLuaCryptDefs::EncodeString(lua_State* luaVM) return std::make_pair(SString(ex.GetWhat()), false); } }, - [luaFunctionRef](const std::pair& result) { + [luaFunctionRef](const std::pair& result) + { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaFunctionRef.GetLuaVM()); if (pLuaMain) { @@ -579,7 +589,7 @@ int CLuaCryptDefs::EncodeString(lua_State* luaVM) lua::Push(luaVM, true); } } - else // Sync + else // Sync { try { @@ -646,7 +656,7 @@ int CLuaCryptDefs::EncodeString(lua_State* luaVM) lua::Push(luaVM, true); } } - else // Sync + else // Sync { try { @@ -713,7 +723,7 @@ int CLuaCryptDefs::EncodeString(lua_State* luaVM) lua::Push(luaVM, true); } } - else // Sync + else // Sync { try { @@ -730,8 +740,8 @@ int CLuaCryptDefs::EncodeString(lua_State* luaVM) } case StringEncodeFunction::ZLIB: { - int compression = 9; - int format = (int)ZLibFormat::GZIP; + int compression = 9; + int format = (int)ZLibFormat::GZIP; ZLibStrategy strategy = ZLibStrategy::DEFAULT; if (!options["format"].empty() && !StringToEnum(options["format"], (ZLibFormat&)format) && !StringToZLibFormat(options["format"], format)) { @@ -796,7 +806,7 @@ int CLuaCryptDefs::EncodeString(lua_State* luaVM) lua_pushboolean(luaVM, true); } } - else // Sync + else // Sync { SString output; int result = SharedUtil::ZLibCompress(data, output, format, compression, strategy); @@ -867,13 +877,15 @@ int CLuaCryptDefs::DecodeString(lua_State* luaVM) if (pLuaMain) { CLuaShared::GetAsyncTaskScheduler()->PushTask( - [data, key] { + [data, key] + { // Execute time-consuming task SString result; SharedUtil::TeaDecode(data, key, &result); return result; }, - [luaFunctionRef](const SString& result) { + [luaFunctionRef](const SString& result) + { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaFunctionRef.GetLuaVM()); if (pLuaMain) { @@ -886,7 +898,7 @@ int CLuaCryptDefs::DecodeString(lua_State* luaVM) lua_pushboolean(luaVM, true); } } - else // Sync + else // Sync { SString result; SharedUtil::TeaDecode(data, key, &result); @@ -920,7 +932,8 @@ int CLuaCryptDefs::DecodeString(lua_State* luaVM) if (pLuaMain) { CLuaShared::GetAsyncTaskScheduler()->PushTask( - [data, key, iv] { + [data, key, iv] + { // Execute time-consuming task SString result; try @@ -932,7 +945,8 @@ int CLuaCryptDefs::DecodeString(lua_State* luaVM) } return result; }, - [luaFunctionRef](const SString& result) { + [luaFunctionRef](const SString& result) + { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaFunctionRef.GetLuaVM()); if (pLuaMain) { @@ -953,7 +967,7 @@ int CLuaCryptDefs::DecodeString(lua_State* luaVM) lua_pushboolean(luaVM, true); } } - else // Sync + else // Sync { SString result; try @@ -987,7 +1001,8 @@ int CLuaCryptDefs::DecodeString(lua_State* luaVM) if (pLuaMain) { CLuaShared::GetAsyncTaskScheduler()->PushTask( - [data, key] { + [data, key] + { try { return std::make_pair(SharedUtil::RsaDecode(data, key), true); @@ -997,7 +1012,8 @@ int CLuaCryptDefs::DecodeString(lua_State* luaVM) return std::make_pair(SString(ex.GetWhat()), false); } }, - [luaFunctionRef](const std::pair& result) { + [luaFunctionRef](const std::pair& result) + { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaFunctionRef.GetLuaVM()); if (pLuaMain) { @@ -1019,7 +1035,7 @@ int CLuaCryptDefs::DecodeString(lua_State* luaVM) lua::Push(luaVM, true); } } - else // Sync + else // Sync { try { @@ -1086,7 +1102,7 @@ int CLuaCryptDefs::DecodeString(lua_State* luaVM) lua::Push(luaVM, true); } } - else // Sync + else // Sync { try { @@ -1153,7 +1169,7 @@ int CLuaCryptDefs::DecodeString(lua_State* luaVM) lua::Push(luaVM, true); } } - else // Sync + else // Sync { try { @@ -1218,7 +1234,7 @@ int CLuaCryptDefs::DecodeString(lua_State* luaVM) lua_pushboolean(luaVM, true); } } - else // Sync + else // Sync { SString output; int result = SharedUtil::ZLibUncompress(data, output, format); diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaElementDefsShared.cpp b/Shared/mods/deathmatch/logic/luadefs/CLuaElementDefsShared.cpp index 32d221f66d9..823845118a0 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaElementDefsShared.cpp +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaElementDefsShared.cpp @@ -18,9 +18,9 @@ int CLuaElementDefs::GetElementData(lua_State* luaVM) { // var getElementData ( element theElement, string key [, inherit = true] ) - CElement* pElement; + CElement* pElement; CStringName key; - bool bInherit; + bool bInherit; CScriptArgReader argStream(luaVM); argStream.ReadUserData(pElement); @@ -42,9 +42,9 @@ int CLuaElementDefs::GetElementData(lua_State* luaVM) } #ifdef MTA_CLIENT - CLuaArgument* pVariable = pElement->GetCustomData(key.ToCString(), bInherit); + CLuaArgument* pVariable = pElement->GetCustomData(key, bInherit); #else - CLuaArgument* pVariable = CStaticFunctionDefinitions::GetElementData(pElement, key.ToCString(), bInherit); + CLuaArgument* pVariable = CStaticFunctionDefinitions::GetElementData(pElement, key, bInherit); #endif if (pVariable) { @@ -72,9 +72,9 @@ int CLuaElementDefs::HasElementData(lua_State* luaVM) { // bool hasElementData ( element theElement, string key [, bool inherit = true ] ) - CElement* pElement; + CElement* pElement; CStringName key; - bool bInherit; + bool bInherit; CScriptArgReader argStream(luaVM); argStream.ReadUserData(pElement); diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaFileDefs.cpp b/Shared/mods/deathmatch/logic/luadefs/CLuaFileDefs.cpp index 826a621ddd3..3c268b557f9 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaFileDefs.cpp +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaFileDefs.cpp @@ -227,7 +227,7 @@ int CLuaFileDefs::fileOpen(lua_State* luaVM) CheckCanAccessOtherResourceFile(argStream, pThisResource, pResource, strAbsPath, &bReadOnly); if (!argStream.HasErrors()) { -#ifndef MTA_CLIENT // IF SERVER +#ifndef MTA_CLIENT // IF SERVER // Create the file to create CScriptFile* pFile = new CScriptFile(pThisResource->GetScriptID(), strMetaPath, DEFAULT_MAX_FILESIZE); #else @@ -313,7 +313,7 @@ int CLuaFileDefs::fileCreate(lua_State* luaVM) lua_pushboolean(luaVM, false); return 1; } -#endif // MTA_CLIENT +#endif // MTA_CLIENT SString strAbsPath; SString strMetaPath; @@ -765,7 +765,7 @@ int CLuaFileDefs::fileWrite(lua_State* luaVM) if (!argStream.HasErrors()) { - long lBytesWritten = 0; // Total bytes written + long lBytesWritten = 0; // Total bytes written // While we're not out of string arguments // (we will always have at least one string because we validated it above) @@ -816,7 +816,7 @@ std::optional CLuaFileDefs::fileGetContents(lua_State* L, CScriptFi // string fileGetContents ( file target [, bool verifyContents = true ] ) std::string buffer; - const long bytesRead = scriptFile->GetContents(buffer); + const long bytesRead = scriptFile->GetContents(buffer); if (bytesRead == -2) { @@ -918,7 +918,7 @@ std::optional CLuaFileDefs::fileGetHash(lua_State* const luaVM, CSc switch (hashFunction) { case HashFunctionType::MD5: - result = ComputeScriptFileHash(scriptFile); + result = ComputeScriptFileHash(scriptFile); break; case HashFunctionType::SHA1: result = ComputeScriptFileHash(scriptFile); @@ -951,11 +951,11 @@ std::optional CLuaFileDefs::fileGetHash(lua_State* const luaVM, CSc if (algorithm.empty() || !StringToEnum(algorithm, hmacAlgorithm)) throw std::invalid_argument("Invalid value for field 'algorithm'"); - + switch (hmacAlgorithm) { case HmacAlgorithm::MD5: - result = ComputeScriptFileHash>(scriptFile, key); + result = ComputeScriptFileHash>(scriptFile, key); break; case HmacAlgorithm::SHA1: result = ComputeScriptFileHash>(scriptFile, key); diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaMatrixDefs.h b/Shared/mods/deathmatch/logic/luadefs/CLuaMatrixDefs.h index 4c987e719ce..8967885734c 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaMatrixDefs.h +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaMatrixDefs.h @@ -13,9 +13,9 @@ extern "C" { - #include "lua.h" - #include "lualib.h" - #include "lauxlib.h" +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" } #include "luadefs/CLuaDefs.h" diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaPathDefs.cpp b/Shared/mods/deathmatch/logic/luadefs/CLuaPathDefs.cpp index a36ed162157..80a8368dfb9 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaPathDefs.cpp +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaPathDefs.cpp @@ -44,10 +44,8 @@ void CLuaPathDefs::AddClass(lua_State* luaVM) lua_registerclass(luaVM, "path"); } -std::optional> CLuaPathDefs::pathListDir( - lua_State* luaVM, - std::string path -) { +std::optional> CLuaPathDefs::pathListDir(lua_State* luaVM, std::string path) +{ CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); if (!pLuaMain) return std::nullopt; @@ -57,15 +55,13 @@ std::optional> CLuaPathDefs::pathListDir( CResource* pResource = pLuaMain->GetResource(); if (!CResourceManager::ParseResourcePathInput(path, pResource, &strAbsPath)) { - m_pScriptDebugging->LogWarning(luaVM, "Cannot parse provided path: \"%s\"", - path.c_str()); + m_pScriptDebugging->LogWarning(luaVM, "Cannot parse provided path: \"%s\"", path.c_str()); return std::nullopt; } if (!DirectoryExists(strAbsPath)) { - m_pScriptDebugging->LogWarning(luaVM, "Directory \"%s\" doesn't exist!", - path.c_str()); + m_pScriptDebugging->LogWarning(luaVM, "Directory \"%s\" doesn't exist!", path.c_str()); return std::nullopt; } @@ -83,8 +79,7 @@ bool CLuaPathDefs::pathIsFile(lua_State* luaVM, std::string path) CResource* pResource = pLuaMain->GetResource(); if (!CResourceManager::ParseResourcePathInput(path, pResource, &strAbsPath)) { - m_pScriptDebugging->LogWarning(luaVM, "Cannot parse provided path: \"%s\"", - path.c_str()); + m_pScriptDebugging->LogWarning(luaVM, "Cannot parse provided path: \"%s\"", path.c_str()); return false; } @@ -102,8 +97,7 @@ bool CLuaPathDefs::pathIsDirectory(lua_State* luaVM, std::string path) CResource* pResource = pLuaMain->GetResource(); if (!CResourceManager::ParseResourcePathInput(path, pResource, &strAbsPath)) { - m_pScriptDebugging->LogWarning(luaVM, "Cannot parse provided path: \"%s\"", - path.c_str()); + m_pScriptDebugging->LogWarning(luaVM, "Cannot parse provided path: \"%s\"", path.c_str()); return false; } diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaPathDefs.h b/Shared/mods/deathmatch/logic/luadefs/CLuaPathDefs.h index 6a8e950f551..d3e1d6eb089 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaPathDefs.h +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaPathDefs.h @@ -19,7 +19,7 @@ class CLuaPathDefs : public CLuaDefs private: static std::optional> pathListDir(lua_State* luaVM, std::string path); - + static bool pathIsFile(lua_State* luaVM, std::string path); static bool pathIsDirectory(lua_State* luaVM, std::string path); }; diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaTrainTrackDefs.cpp b/Shared/mods/deathmatch/logic/luadefs/CLuaTrainTrackDefs.cpp index 9706863ba25..866508db360 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaTrainTrackDefs.cpp +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaTrainTrackDefs.cpp @@ -18,19 +18,19 @@ void CLuaTrainTrackDefs::LoadFunctions() { - // CLuaCFunctions::AddFunction("getDefaultTrack", ArgumentParser); + CLuaCFunctions::AddFunction("getDefaultTrack", ArgumentParser); } void CLuaTrainTrackDefs::AddClass(lua_State* luaVM) { - // lua_newclass(luaVM); + lua_newclass(luaVM); - // lua_classfunction(luaVM, "getDefault", "getDefaultTrack"); + lua_classfunction(luaVM, "getDefault", "getDefaultTrack"); - // lua_registerclass(luaVM, "TrainTrack", "Element"); + lua_registerclass(luaVM, "TrainTrack", "Element"); } -auto CLuaTrainTrackDefs::GetDefaultTrack(uchar trackID) -> CLuaTrainTrackDefs::TrainTrack +CLuaTrainTrackDefs::TrainTrack CLuaTrainTrackDefs::GetDefaultTrack(uchar trackID) { if (trackID > 3) throw std::invalid_argument("Bad default track ID (0-3)"); @@ -38,6 +38,6 @@ auto CLuaTrainTrackDefs::GetDefaultTrack(uchar trackID) -> CLuaTrainTrackDefs::T #ifdef MTA_CLIENT return trackID; #else - return g_pGame->GetTrainTrackManager()->GetTrainTrackByIndex(trackID); + return g_pGame->GetTrainTrackManager()->GetDefaultTrackByIndex(trackID); #endif } diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaUtilDefs.cpp b/Shared/mods/deathmatch/logic/luadefs/CLuaUtilDefs.cpp index cd44d9e2ba0..b4c655ac4f8 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaUtilDefs.cpp +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaUtilDefs.cpp @@ -204,7 +204,7 @@ int CLuaUtilDefs::Split(lua_State* luaVM) wchar_t wUNICODE[2] = {static_cast(uiDelimiter), '\0'}; strDelimiter = UTF16ToMbUTF8(wUNICODE); } - else // It's already a string + else // It's already a string argStream.ReadString(strDelimiter); if (!argStream.HasErrors()) @@ -227,7 +227,7 @@ int CLuaUtilDefs::Split(lua_State* luaVM) lua_pushstring(luaVM, szToken); lua_settable(luaVM, -3); - szToken = strtok(NULL, strDelimiter); + szToken = strtok(nullptr, strDelimiter.c_str()); } // Delete the text @@ -263,7 +263,7 @@ int CLuaUtilDefs::GetUserdataType(lua_State* luaVM) else if (iArgument == LUA_TUSERDATA) strType = GetUserDataClassName(*((void**)lua_touserdata(luaVM, 1)), luaVM, false); - strType = strType.empty() ? "userdata" : strType; + strType = strType.empty() ? SStringX("userdata") : strType; lua_pushstring(luaVM, strType.c_str()); return 1; @@ -664,7 +664,7 @@ int CLuaUtilDefs::GetTok(lua_State* luaVM) wchar_t wUNICODE[2] = {static_cast(uiDelimiter), '\0'}; strDelimiter = UTF16ToMbUTF8(wUNICODE); } - else // It's already a string + else // It's already a string argStream.ReadString(strDelimiter); if (!argStream.HasErrors()) @@ -728,7 +728,12 @@ int CLuaUtilDefs::tocolor(lua_State* luaVM) if (!argStream.HasErrors()) { // Make it into an unsigned long - unsigned long ulColor = COLOR_RGBA(iRed, iGreen, iBlue, iAlpha); + const unsigned char ucRed = static_cast(Clamp(0, iRed, 255)); + const unsigned char ucGreen = static_cast(Clamp(0, iGreen, 255)); + const unsigned char ucBlue = static_cast(Clamp(0, iBlue, 255)); + const unsigned char ucAlpha = static_cast(Clamp(0, iAlpha, 255)); + + unsigned long ulColor = COLOR_RGBA(ucRed, ucGreen, ucBlue, ucAlpha); lua_pushinteger(luaVM, static_cast(ulColor)); return 1; } diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaUtilDefs.h b/Shared/mods/deathmatch/logic/luadefs/CLuaUtilDefs.h index e690c7cf3ca..02993d72d81 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaUtilDefs.h +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaUtilDefs.h @@ -23,7 +23,7 @@ class CLuaUtilDefs : public CLuaDefs // Some of these are based on standard mIRC script funcs as a lot of people will be used to them LUA_DECLARE(Dereference); LUA_DECLARE(Reference); - LUA_DECLARE(GetTickCount_); // Trailing underscore to prevent macro issues + LUA_DECLARE(GetTickCount_); // Trailing underscore to prevent macro issues LUA_DECLARE(GetCTime); LUA_DECLARE(Split); LUA_DECLARE(IsOOPEnabled); diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaVector2Defs.h b/Shared/mods/deathmatch/logic/luadefs/CLuaVector2Defs.h index deb38f6b851..035827e9d3f 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaVector2Defs.h +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaVector2Defs.h @@ -13,9 +13,9 @@ extern "C" { - #include "lua.h" - #include "lualib.h" - #include "lauxlib.h" +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" } #include "luadefs/CLuaDefs.h" diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaVector3Defs.h b/Shared/mods/deathmatch/logic/luadefs/CLuaVector3Defs.h index 24b786ab7a8..da73aa7a247 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaVector3Defs.h +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaVector3Defs.h @@ -13,9 +13,9 @@ extern "C" { - #include "lua.h" - #include "lualib.h" - #include "lauxlib.h" +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" } #include "luadefs/CLuaDefs.h" diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaVector4Defs.h b/Shared/mods/deathmatch/logic/luadefs/CLuaVector4Defs.h index ee6d76d0355..4edf07f44d9 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaVector4Defs.h +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaVector4Defs.h @@ -13,9 +13,9 @@ extern "C" { - #include "lua.h" - #include "lualib.h" - #include "lauxlib.h" +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" } #include "luadefs/CLuaDefs.h" diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaXMLDefs.cpp b/Shared/mods/deathmatch/logic/luadefs/CLuaXMLDefs.cpp index 90c3773ee9c..17e617b5b56 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaXMLDefs.cpp +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaXMLDefs.cpp @@ -55,7 +55,7 @@ void CLuaXMLDefs::AddClass(lua_State* luaVM) #ifndef MTA_CLIENT lua_classfunction(luaVM, "loadMapData", "loadMapData"); lua_classfunction(luaVM, "saveMapData", "saveMapData"); -#endif // !MTA_CLIENT +#endif // !MTA_CLIENT lua_classfunction(luaVM, "getValue", "xmlNodeGetValue"); lua_classfunction(luaVM, "setAttribute", "xmlNodeSetAttribute"); @@ -85,7 +85,7 @@ int CLuaXMLDefs::xmlCreateFile(lua_State* luaVM) #ifndef MTA_CLIENT if (lua_type(luaVM, 3) == LUA_TLIGHTUSERDATA) m_pScriptDebugging->LogCustom(luaVM, "xmlCreateFile may be using an outdated syntax. Please check and update."); -#endif // !MTA_CLIENT +#endif // !MTA_CLIENT // Grab our resource CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); @@ -101,7 +101,7 @@ int CLuaXMLDefs::xmlCreateFile(lua_State* luaVM) { SString strPath; CResource* pThisResource = pLuaMain->GetResource(); - CResource* pOtherResource = pThisResource; // clientside, this variable will always be pThisResource + CResource* pOtherResource = pThisResource; // clientside, this variable will always be pThisResource // Resolve other resource from name if (CResourceManager::ParseResourcePathInput(strInputPath, pOtherResource, &strPath, nullptr)) @@ -144,7 +144,7 @@ int CLuaXMLDefs::xmlLoadFile(lua_State* luaVM) #ifndef MTA_CLIENT if (lua_type(luaVM, 2) == LUA_TLIGHTUSERDATA) m_pScriptDebugging->LogCustom(luaVM, "xmlLoadFile may be using an outdated syntax. Please check and update."); -#endif // !MTA_CLIENT +#endif // !MTA_CLIENT // Grab our resource CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); @@ -250,7 +250,7 @@ int CLuaXMLDefs::xmlCopyFile(lua_State* luaVM) #ifndef MTA_CLIENT if (lua_type(luaVM, 3) == LUA_TLIGHTUSERDATA) m_pScriptDebugging->LogCustom(luaVM, "xmlCopyFile may be using an outdated syntax. Please check and update."); -#endif // !MTA_CLIENT +#endif // !MTA_CLIENT // Grab our resource CLuaMain* pLUA = m_pLuaManager->GetVirtualMachine(luaVM); diff --git a/Shared/mods/deathmatch/logic/luascripts/coroutine_debug.lua.h b/Shared/mods/deathmatch/logic/luascripts/coroutine_debug.lua.h index 1c361b07876..3c1c1769655 100644 --- a/Shared/mods/deathmatch/logic/luascripts/coroutine_debug.lua.h +++ b/Shared/mods/deathmatch/logic/luascripts/coroutine_debug.lua.h @@ -1,3 +1,4 @@ +#pragma once namespace EmbeddedLuaCode { const char* const coroutine_debug = R"~LUA~( @@ -23,4 +24,4 @@ function coroutine.resume(...) end )~LUA~"; -} \ No newline at end of file +} diff --git a/Shared/mods/deathmatch/logic/luascripts/exports.lua.h b/Shared/mods/deathmatch/logic/luascripts/exports.lua.h index aa7f5c36c98..a048a8b12e8 100644 --- a/Shared/mods/deathmatch/logic/luascripts/exports.lua.h +++ b/Shared/mods/deathmatch/logic/luascripts/exports.lua.h @@ -1,3 +1,4 @@ +#pragma once namespace EmbeddedLuaCode { const char* const exports = R"~LUA~( diff --git a/Shared/mods/deathmatch/logic/luascripts/inspect.lua.h b/Shared/mods/deathmatch/logic/luascripts/inspect.lua.h index 16eb1078b81..8a5888db442 100644 --- a/Shared/mods/deathmatch/logic/luascripts/inspect.lua.h +++ b/Shared/mods/deathmatch/logic/luascripts/inspect.lua.h @@ -1,3 +1,4 @@ +#pragma once namespace EmbeddedLuaCode { const char* const inspect = R"~LUA~( @@ -443,4 +444,4 @@ setmetatable(inspect, { __call = function(_, ...) return inspect.inspect(...) en )~LUA~"; -} \ No newline at end of file +} diff --git a/Shared/premake5.lua b/Shared/premake5.lua index 76c3c52c84a..813ecfb431f 100644 --- a/Shared/premake5.lua +++ b/Shared/premake5.lua @@ -7,6 +7,7 @@ project "Shared" language "C++" kind "None" targetname "shared" + clangtidy "On" vpaths { ["Headers/*"] = { "**.h", "**.hpp" }, diff --git a/Shared/publicsdk/CThread.cpp b/Shared/publicsdk/CThread.cpp index 4bbeab012c4..29354858e54 100644 --- a/Shared/publicsdk/CThread.cpp +++ b/Shared/publicsdk/CThread.cpp @@ -22,7 +22,7 @@ CThread::CThread() { m_pThreadData = NULL; m_pArg = NULL; -#ifdef WIN32 // Win32 threads +#ifdef WIN32 // Win32 threads m_hThread = NULL; #endif } @@ -34,22 +34,22 @@ CThread::~CThread() bool CThread::Start(CThreadData* pData) { - if (pData == NULL) // pData HAS to be valid + if (pData == NULL) // pData HAS to be valid return false; Stop(); Arg(pData); - #ifdef WIN32 // Win32 threads +#ifdef WIN32 // Win32 threads m_hThread = CreateThread(NULL, 0, &CThread::EntryPoint, this, 0, NULL); return m_hThread != NULL; - #else // POSIX threads +#else // POSIX threads if (pthread_create(&m_hThread, NULL, CThread::EntryPoint, this)) { // something bad happened return false; } - #endif +#endif return true; } @@ -65,32 +65,32 @@ void CThread::Stop() bool CThread::TryLock(ThreadMutex* Mutex) { - #ifdef WIN32 +#ifdef WIN32 if (TryEnterCriticalSection(Mutex) != 0) return true; - #else +#else if (pthread_mutex_trylock(Mutex) == 0) return true; - #endif +#endif return false; } void CThread::Lock(ThreadMutex* Mutex) { - #ifdef WIN32 // Win32 threads +#ifdef WIN32 // Win32 threads EnterCriticalSection(Mutex); - #else // POSIX threads +#else // POSIX threads pthread_mutex_lock(Mutex); - #endif +#endif } void CThread::Unlock(ThreadMutex* Mutex) { - #ifdef WIN32 // Win32 threads +#ifdef WIN32 // Win32 threads LeaveCriticalSection(Mutex); - #else // POSIX threads +#else // POSIX threads pthread_mutex_unlock(Mutex); - #endif +#endif } int CThread::Run(CThreadData* arg) @@ -98,13 +98,13 @@ int CThread::Run(CThreadData* arg) return Execute(arg); } -#ifdef WIN32 // Win32 threads +#ifdef WIN32 // Win32 threads DWORD CThread::EntryPoint(void* pThis) { CThread* pt = (CThread*)pThis; return pt->Run(pt->Arg()); } -#else // POSIX threads +#else // POSIX threads void* CThread::EntryPoint(void* pThis) { CThread* pt = (CThread*)pThis; diff --git a/Shared/publicsdk/CThread.h b/Shared/publicsdk/CThread.h index f4a23bd9d95..bf74e4d64dc 100644 --- a/Shared/publicsdk/CThread.h +++ b/Shared/publicsdk/CThread.h @@ -20,14 +20,14 @@ #pragma once -#ifdef WIN32 // Win32 threads +#ifdef WIN32 // Win32 threads #define _WIN32_WINNT 0x400 #define WIN32_LEAN_AND_MEAN #include typedef HANDLE ThreadHandle; typedef CRITICAL_SECTION ThreadMutex; -#else // POSIX threads +#else // POSIX threads #include #include @@ -59,9 +59,9 @@ class CThread CThreadData* Arg() const; void Arg(CThreadData* pData); -#ifdef WIN32 // Win32 threads +#ifdef WIN32 // Win32 threads static DWORD WINAPI EntryPoint(void*); -#else // POSIX threads +#else // POSIX threads static void* EntryPoint(void*); #endif diff --git a/Shared/publicsdk/CThreadData.cpp b/Shared/publicsdk/CThreadData.cpp index 383410128e6..f773d7dbbdc 100644 --- a/Shared/publicsdk/CThreadData.cpp +++ b/Shared/publicsdk/CThreadData.cpp @@ -22,21 +22,21 @@ CThreadData::CThreadData() { bAbortThread = false; - // Initialize the mutexes - #ifdef WIN32 // Win32 threads +// Initialize the mutexes +#ifdef WIN32 // Win32 threads InitializeCriticalSection(&MutexPrimary); InitializeCriticalSection(&MutexLogical); - #else // POSIX threads +#else // POSIX threads pthread_mutex_init(&MutexPrimary, NULL); pthread_mutex_init(&MutexLogical, NULL); - #endif +#endif } CThreadData::~CThreadData() { - #ifdef WIN32 +#ifdef WIN32 DeleteCriticalSection(&MutexPrimary); DeleteCriticalSection(&MutexLogical); - #else - #endif +#else +#endif } diff --git a/Shared/publicsdk/CThreadData.h b/Shared/publicsdk/CThreadData.h index c5c7e04c708..75564e13a49 100644 --- a/Shared/publicsdk/CThreadData.h +++ b/Shared/publicsdk/CThreadData.h @@ -29,6 +29,6 @@ class CThreadData ~CThreadData(); bool bAbortThread; - ThreadMutex MutexPrimary; // primary mutex for suspend/resume operations - ThreadMutex MutexLogical; // logical mutex for proper CThreadData sync + ThreadMutex MutexPrimary; // primary mutex for suspend/resume operations + ThreadMutex MutexLogical; // logical mutex for proper CThreadData sync }; diff --git a/Shared/publicsdk/Common.h b/Shared/publicsdk/Common.h index 036890ba0b6..a0c5f93495e 100644 --- a/Shared/publicsdk/Common.h +++ b/Shared/publicsdk/Common.h @@ -18,28 +18,29 @@ extern "C" { - #include - #include - #include +#include +#include +#include } #ifdef WIN32 #define MTAEXPORT extern "C" __declspec(dllexport) #else - #define MTAEXPORT extern "C" __attribute__ ((visibility ("default"))) + #define MTAEXPORT extern "C" __attribute__((visibility("default"))) #endif #include #include // Obviously i can't get us this so other includes will most likely be needed later on -using namespace std; +using std::list; +using std::vector; #ifndef __COMMON_H -#define __COMMON_H + #define __COMMON_H -// used in the function argument vector -#define MAX_ARGUMENTS 10 + // used in the function argument vector + #define MAX_ARGUMENTS 10 struct FunctionArguments { lua_State* luaVM; diff --git a/Shared/publicsdk/extra/CLuaArgument.h b/Shared/publicsdk/extra/CLuaArgument.h index faaef1ebfcf..e5c61438056 100644 --- a/Shared/publicsdk/extra/CLuaArgument.h +++ b/Shared/publicsdk/extra/CLuaArgument.h @@ -20,7 +20,7 @@ extern "C" { - #include +#include } class CLuaArgument diff --git a/Shared/publicsdk/extra/CLuaArguments.cpp b/Shared/publicsdk/extra/CLuaArguments.cpp index d56b8aa39d0..88afc0573cf 100644 --- a/Shared/publicsdk/extra/CLuaArguments.cpp +++ b/Shared/publicsdk/extra/CLuaArguments.cpp @@ -98,7 +98,7 @@ bool CLuaArguments::Call(lua_State* luaVM, const char* szFunction) const if (iret == LUA_ERRRUN || iret == LUA_ERRMEM) { const char* szRes = lua_tostring(luaVM, -1); - return false; // the function call failed + return false; // the function call failed } return true; diff --git a/Shared/publicsdk/extra/CLuaArguments.h b/Shared/publicsdk/extra/CLuaArguments.h index 9758d041f19..8d0a3534466 100644 --- a/Shared/publicsdk/extra/CLuaArguments.h +++ b/Shared/publicsdk/extra/CLuaArguments.h @@ -20,18 +20,18 @@ extern "C" { - #include +#include } #include "CLuaArgument.h" #include -using namespace std; +using std::vector; class CLuaArguments { public: - CLuaArguments(){}; + CLuaArguments() {}; CLuaArguments(const CLuaArguments& Arguments); ~CLuaArguments() { DeleteArguments(); }; diff --git a/Shared/publicsdk/include/ILuaModuleManager.h b/Shared/publicsdk/include/ILuaModuleManager.h index 2c8a6e22039..03848c3e24c 100644 --- a/Shared/publicsdk/include/ILuaModuleManager.h +++ b/Shared/publicsdk/include/ILuaModuleManager.h @@ -17,14 +17,14 @@ extern "C" { - #include - #include - #include +#include +#include +#include } #include #ifndef __CChecksum_H -#define __CChecksum_H + #define __CChecksum_H class CChecksum { public: @@ -41,9 +41,9 @@ class ILuaModuleManager virtual void DebugPrintf(lua_State* luaVM, const char* szFormat, ...) = 0; virtual void Printf(const char* szFormat, ...) = 0; - virtual bool RegisterFunction(lua_State* luaVM, const char* szFunctionName, lua_CFunction Func) = 0; - virtual bool GetResourceName( - lua_State* luaVM, std::string& strName) = 0; // This function might not work if module and MTA were compiled with different compiler versions + virtual bool RegisterFunction(lua_State* luaVM, const char* szFunctionName, lua_CFunction Func) = 0; + virtual bool GetResourceName(lua_State* luaVM, + std::string& strName) = 0; // This function might not work if module and MTA were compiled with different compiler versions virtual CChecksum GetResourceMetaChecksum(lua_State* luaVM) = 0; virtual CChecksum GetResourceFileChecksum(lua_State* luaVM, const char* szFile) = 0; }; diff --git a/Shared/publicsdk/ml_base.h b/Shared/publicsdk/ml_base.h index ac09276c2de..c70f55760b8 100644 --- a/Shared/publicsdk/ml_base.h +++ b/Shared/publicsdk/ml_base.h @@ -17,9 +17,9 @@ *********************************************************/ /** MODULE SPECIFIC INFORMATION **/ -#define MODULE_NAME "Base Module" -#define MODULE_AUTHOR "anon" -#define MODULE_VERSION 1.0 +#define MODULE_NAME "Base Module" +#define MODULE_AUTHOR "anon" +#define MODULE_VERSION 1.0 #include #include "Common.h" diff --git a/Shared/sdk/CChecksum.h b/Shared/sdk/CChecksum.h index 7714cee68f6..0e10b614bfa 100644 --- a/Shared/sdk/CChecksum.h +++ b/Shared/sdk/CChecksum.h @@ -13,45 +13,165 @@ #define __CChecksum_H #include +#include +#include #include "SharedUtil.Hash.h" +#include "SharedUtil.File.h" #include "SString.h" #include +#if defined(_WIN32) && defined(MTA_CLIENT) + #include + #include +#endif + // Depends on CMD5Hasher and CRCGenerator class CChecksum { public: - // Initialize to zeros - CChecksum() - { - ulCRC = 0; - memset(md5.data, 0, sizeof(md5.data)); - } + CChecksum() : ulCRC(0), md5{} {} // Comparison operators bool operator==(const CChecksum& other) const { return ulCRC == other.ulCRC && memcmp(md5.data, other.md5.data, sizeof(md5.data)) == 0; } bool operator!=(const CChecksum& other) const { return !operator==(other); } - // GenerateChecksumFromFile returns either a CChecksum or an error message. - static std::variant GenerateChecksumFromFile(const SString& strFilename) +#if defined(_WIN32) && defined(MTA_CLIENT) +private: + struct CacheEntry { - // Reset error number before using it to report an error - errno = 0; - - CChecksum result; - result.ulCRC = CRCGenerator::GetCRCFromFile(strFilename); - - if (!result.ulCRC && errno) - return SString("CRC could not open file: %s", std::strerror(errno)); + std::uint64_t size, mtime; + unsigned long crc; + MD5 md5; + }; + static std::unordered_map& Cache() + { + static std::unordered_map c; + return c; + } + static std::mutex& CacheMtx() + { + static std::mutex m; + return m; + } - bool success = CMD5Hasher().Calculate(strFilename, result.md5); +public: + static void ClearChecksumCache() + { + std::lock_guard l(CacheMtx()); + Cache().clear(); + } - if (!success) - return SString("MD5 could not open file: %s", std::strerror(errno)); + static std::variant GenerateChecksumFromFile(const SString& strFilename) + { + std::string key = strFilename; + for (char& c : key) + { + if (c >= 'A' && c <= 'Z') + c += 32; + if (c == '\\') + c = '/'; + } + + WIN32_FILE_ATTRIBUTE_DATA attr; + WString wide; + try + { + wide = SharedUtil::FromUTF8(strFilename); + } + catch (...) + { + } + bool hasMeta = !wide.empty() && SharedUtil::GetFileAttributesExWithTimeout(wide.c_str(), attr, 500); + std::uint64_t sz = 0, mt = 0; + if (hasMeta) + { + sz = (std::uint64_t(attr.nFileSizeHigh) << 32) | attr.nFileSizeLow; + mt = (std::uint64_t(attr.ftLastWriteTime.dwHighDateTime) << 32) | attr.ftLastWriteTime.dwLowDateTime; + std::lock_guard l(CacheMtx()); + auto it = Cache().find(key); + if (it != Cache().end() && it->second.size == sz && it->second.mtime == mt) + { + CChecksum cached; + cached.ulCRC = it->second.crc; + cached.md5 = it->second.md5; + return cached; + } + } + + SString buf; + if (!SharedUtil::FileLoadWithTimeout(strFilename, buf, 2000)) + { + if (!hasMeta) + return SString("File not found or inaccessible: %s", strFilename.c_str()); + return SString("Could not read: %s", strFilename.c_str()); + } + + CChecksum r; + r.ulCRC = CRCGenerator::GetCRCFromBuffer(buf.data(), buf.size()); + CMD5Hasher().Calculate(buf.data(), buf.size(), r.md5); + + if (hasMeta && SharedUtil::GetFileAttributesExWithTimeout(wide.c_str(), attr, 500) && + sz == ((std::uint64_t(attr.nFileSizeHigh) << 32) | attr.nFileSizeLow) && + mt == ((std::uint64_t(attr.ftLastWriteTime.dwHighDateTime) << 32) | attr.ftLastWriteTime.dwLowDateTime)) + { + std::lock_guard l(CacheMtx()); + Cache()[key] = {sz, mt, r.ulCRC, r.md5}; + } + return r; + } +#else + static void ClearChecksumCache() {} - return result; + // Server and non-Windows builds use the original implementation + static std::variant GenerateChecksumFromFile(const SString& strFilename) + { + constexpr int maxRetries = 3; + constexpr int retryDelayMs = 50; + int lastErrno = 0; + int attemptsMade = 0; + + for (int attempt = 0; attempt < maxRetries; ++attempt) + { + ++attemptsMade; + + if (attempt > 0) + std::this_thread::sleep_for(std::chrono::milliseconds(retryDelayMs * attempt)); + + errno = 0; + + CChecksum result; + result.ulCRC = CRCGenerator::GetCRCFromFile(strFilename); + + if (errno) + { + lastErrno = errno; + if (errno == ENOENT) + break; + continue; + } + + errno = 0; + bool success = CMD5Hasher().Calculate(strFilename, result.md5); + + if (!success) + { + lastErrno = errno ? errno : EIO; + if (errno == ENOENT) + break; + continue; + } + + return result; + } + + if (lastErrno == ENOENT) + return SString("File not found: %s", strFilename.c_str()); + + return SString("Could not checksum '%s' after %d attempt%s: %s", strFilename.c_str(), attemptsMade, attemptsMade == 1 ? "" : "s", + lastErrno ? std::strerror(lastErrno) : "Unknown error"); } +#endif // GenerateChecksumFromFileUnsafe should never ever be used unless you are a bad person. Or unless you really know what you're doing. // If it's the latter, please leave a code comment somewhere explaining why. Otherwise we'll think it's just code that hasn't been migrated yet. diff --git a/Shared/sdk/CDuplicateLineFilter.h b/Shared/sdk/CDuplicateLineFilter.h index 67d67576246..f7312022eed 100644 --- a/Shared/sdk/CDuplicateLineFilter.h +++ b/Shared/sdk/CDuplicateLineFilter.h @@ -50,7 +50,7 @@ class CDuplicateLineFilter m_uiMatchCurLine = i; m_uiDupCount = 0; if (m_uiMatchCurLine == 0) - m_uiDupCount++; // Completed matching set (will only occur here for single line match) + m_uiDupCount++; // Completed matching set (will only occur here for single line match) return; } } @@ -65,7 +65,7 @@ class CDuplicateLineFilter // Still matching m_uiMatchCurLine = uiNextLine; if (m_uiMatchCurLine == 0) - m_uiDupCount++; // Completed matching set + m_uiDupCount++; // Completed matching set return; } else @@ -153,11 +153,11 @@ class CDuplicateLineFilter protected: std::deque m_History; std::list m_PendingOutput; - bool m_bIsMatching = false; // true if matching a duplicate set - uint m_uiMatchSize = 0; // Number of lines in active match - uint m_uiMatchCurLine = 0; // Current line in active match - uint m_uiDupCount = 0; // Number of duplicates found for active match + bool m_bIsMatching = false; // true if matching a duplicate set + uint m_uiMatchSize = 0; // Number of lines in active match + uint m_uiMatchCurLine = 0; // Current line in active match + uint m_uiDupCount = 0; // Number of duplicates found for active match time_t m_tLastOutputTime = 0; - uint m_uiMaxNumOfLinesInMatch; // Max number lines in a matching set - uint m_uiMaxDelaySeconds; // Max seconds to delay outputting duplicated lines + uint m_uiMaxNumOfLinesInMatch; // Max number lines in a matching set + uint m_uiMaxDelaySeconds; // Max seconds to delay outputting duplicated lines }; diff --git a/Shared/sdk/CFastList.h b/Shared/sdk/CFastList.h index a8020362ea9..773b0999fed 100644 --- a/Shared/sdk/CFastList.h +++ b/Shared/sdk/CFastList.h @@ -52,21 +52,21 @@ class CFastList T item; }; - uint uiRevision; // Incremented every time the ordered map changes - uint uiNextFrontIndex; // Next (decrementing) index to use as a map key for items added to the front - uint uiNextBackIndex; // Next (incrementing) index to use as a map key for items added to the back - MapType orderedMap; // Ordered map of items - InfoType infoMap; // info for each item + uint uiRevision; // Incremented every time the ordered map changes + uint uiNextFrontIndex; // Next (decrementing) index to use as a map key for items added to the front + uint uiNextBackIndex; // Next (incrementing) index to use as a map key for items added to the back + MapType orderedMap; // Ordered map of items + InfoType infoMap; // info for each item bool m_bSuspendingModifyOperations; std::vector m_SuspendedOperationList; CFastList() : uiRevision(1), uiNextFrontIndex(UINT_MAX / 2 - 1), uiNextBackIndex(UINT_MAX / 2), m_bSuspendingModifyOperations(false) { - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG // T must be a pointer void* ptr = (T)NULL; ptr = NULL; - #endif +#endif } const T& front() const { return orderedMap.begin()->second; } diff --git a/Shared/sdk/CIntrusiveDoubleLinkedList.h b/Shared/sdk/CIntrusiveDoubleLinkedList.h index bfda4c9f88e..66e9f3b532e 100644 --- a/Shared/sdk/CIntrusiveDoubleLinkedList.h +++ b/Shared/sdk/CIntrusiveDoubleLinkedList.h @@ -23,21 +23,19 @@ struct CIntrusiveDoubleLinkedListNode }; // Double-linked list template class. Elements must inherit from CIntrusiveDoubleLinkedListNode. -template class CIntrusiveDoubleLinkedList +template +class CIntrusiveDoubleLinkedList { public: struct SIterator { using iterator_category = std::bidirectional_iterator_tag; - using difference_type = std::ptrdiff_t; - using value_type = T; - using pointer = T*; - using reference = T&; + using difference_type = std::ptrdiff_t; + using value_type = T; + using pointer = T*; + using reference = T&; - SIterator(T* ptr) : - m_ptr(ptr) - { - } + SIterator(T* ptr) : m_ptr(ptr) {} // Point to the node value. reference operator*() const { return *m_ptr; } @@ -78,10 +76,10 @@ template class CIntrusiveDoubleLinkedList } // Test for equality with another iterator. - friend bool operator== (const SIterator& a, const SIterator& b) { return a.m_ptr == b.m_ptr; }; + friend bool operator==(const SIterator& a, const SIterator& b) { return a.m_ptr == b.m_ptr; }; // Test for inequality with another iterator. - friend bool operator!= (const SIterator& a, const SIterator& b) { return a.m_ptr != b.m_ptr; }; + friend bool operator!=(const SIterator& a, const SIterator& b) { return a.m_ptr != b.m_ptr; }; private: T* m_ptr; @@ -90,15 +88,12 @@ template class CIntrusiveDoubleLinkedList struct SConstIterator { using iterator_category = std::bidirectional_iterator_tag; - using difference_type = std::ptrdiff_t; - using value_type = T; - using pointer = T*; - using reference = T&; + using difference_type = std::ptrdiff_t; + using value_type = T; + using pointer = T*; + using reference = T&; - SConstIterator(T* ptr) : - m_ptr(ptr) - { - } + SConstIterator(T* ptr) : m_ptr(ptr) {} // Point to the node value. const reference operator*() const { return *m_ptr; } @@ -139,20 +134,17 @@ template class CIntrusiveDoubleLinkedList } // Test for equality with another iterator. - friend bool operator== (const SConstIterator& a, const SConstIterator& b) { return a.m_ptr == b.m_ptr; }; + friend bool operator==(const SConstIterator& a, const SConstIterator& b) { return a.m_ptr == b.m_ptr; }; // Test for inequality with another iterator. - friend bool operator!= (const SConstIterator& a, const SConstIterator& b) { return a.m_ptr != b.m_ptr; }; + friend bool operator!=(const SConstIterator& a, const SConstIterator& b) { return a.m_ptr != b.m_ptr; }; private: T* m_ptr; }; // Construct empty. - CIntrusiveDoubleLinkedList() : - m_head(nullptr) - { - } + CIntrusiveDoubleLinkedList() : m_head(nullptr) {} // Non-copyable. CIntrusiveDoubleLinkedList(const CIntrusiveDoubleLinkedList& list) = delete; @@ -165,13 +157,10 @@ template class CIntrusiveDoubleLinkedList } // Non-assignable. - CIntrusiveDoubleLinkedList& operator =(const CIntrusiveDoubleLinkedList& list) = delete; + CIntrusiveDoubleLinkedList& operator=(const CIntrusiveDoubleLinkedList& list) = delete; // Destruct. - ~CIntrusiveDoubleLinkedList() - { - Clear(); - } + ~CIntrusiveDoubleLinkedList() { Clear(); } // Remove all elements. void Clear() @@ -223,7 +212,7 @@ template class CIntrusiveDoubleLinkedList void Detach(T* element) { assert(element); - + T* previous = Previous(element); T* next = Next(element); @@ -239,7 +228,7 @@ template class CIntrusiveDoubleLinkedList // Invalidate element's references element->m_previous = nullptr; element->m_next = nullptr; - } + } // Return first element, or null if empty. T* First() const { return m_head; } @@ -260,7 +249,7 @@ template class CIntrusiveDoubleLinkedList T* Previous(T* element) const { return element ? static_cast(element->m_previous) : nullptr; } // Return next element, or null if no more elements. - T* Next(T* element) const { return element ? static_cast(element->m_next) : nullptr; } + T* Next(T* element) const { return element ? static_cast(element->m_next) : nullptr; } // Return whether is empty. bool Empty() const { return m_head == nullptr; } diff --git a/Shared/sdk/CMatrix.h b/Shared/sdk/CMatrix.h index a12000d9cda..c2847f39f66 100644 --- a/Shared/sdk/CMatrix.h +++ b/Shared/sdk/CMatrix.h @@ -173,6 +173,11 @@ class CMatrix return CVector(vec.fX * vRight.fX + vec.fY * vFront.fX + vec.fZ * vUp.fX + vPos.fX, vec.fX * vRight.fY + vec.fY * vFront.fY + vec.fZ * vUp.fY + vPos.fY, vec.fX * vRight.fZ + vec.fY * vFront.fZ + vec.fZ * vUp.fZ + vPos.fZ); } + CVector TransformVectorByRotation(const CVector& vec) const + { + return CVector(vec.fX * vRight.fX + vec.fY * vFront.fX + vec.fZ * vUp.fX, vec.fX * vRight.fY + vec.fY * vFront.fY + vec.fZ * vUp.fY, + vec.fX * vRight.fZ + vec.fY * vFront.fZ + vec.fZ * vUp.fZ); + } // // Ensure matrix component axes are normalized and orthogonal to each other. diff --git a/Shared/sdk/CMatrix_Pad.h b/Shared/sdk/CMatrix_Pad.h index aded0d67f1b..61d565668d7 100644 --- a/Shared/sdk/CMatrix_Pad.h +++ b/Shared/sdk/CMatrix_Pad.h @@ -20,14 +20,14 @@ class CMatrix_Padded { public: - CVector vRight; // 0 RIGHT - DWORD dwPadRoll; // 12 - CVector vFront; // 16 FOREWARDS - DWORD dwPadDirection; // 28 - CVector vUp; // 32 UP - DWORD dwPadWas; // 44 - CVector vPos; // 48 TRANSLATE - DWORD dwPadPos; // 60 + CVector vRight; // 0 RIGHT + DWORD dwPadRoll; // 12 + CVector vFront; // 16 FOREWARDS + DWORD dwPadDirection; // 28 + CVector vUp; // 32 UP + DWORD dwPadWas; // 44 + CVector vPos; // 48 TRANSLATE + DWORD dwPadPos; // 60 CMatrix_Padded() { memset(this, 0, sizeof(CMatrix_Padded)); } diff --git a/Shared/sdk/CMtaVersion.h b/Shared/sdk/CMtaVersion.h index c5b1ac4ef2e..2cef9e3a5a8 100644 --- a/Shared/sdk/CMtaVersion.h +++ b/Shared/sdk/CMtaVersion.h @@ -26,7 +26,7 @@ namespace SharedUtil CMtaVersion(const std::string& strString) : std::string(strString) {} // Assignment like SString - operator const char*() const { return c_str(); } // Auto assign to const char* without using c_str() + operator const char*() const { return c_str(); } // Auto assign to const char* without using c_str() const char* operator*() const { return c_str(); } // Compare disregarding build type @@ -55,4 +55,4 @@ namespace SharedUtil SString GetGeneration() const { return SStringX(*this).SubStr(0, 3); } }; -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/CRect.h b/Shared/sdk/CRect.h index 39f49f04e3f..e6e13baf5ae 100644 --- a/Shared/sdk/CRect.h +++ b/Shared/sdk/CRect.h @@ -19,10 +19,10 @@ class CRect { public: - float left; // x1 - float bottom; // y1 - float right; // x2 - float top; // y2 + float left; // x1 + float bottom; // y1 + float right; // x2 + float top; // y2 CRect() { diff --git a/Shared/sdk/CScriptArgReader.h b/Shared/sdk/CScriptArgReader.h index 70af7f9872d..9cd034f7dff 100644 --- a/Shared/sdk/CScriptArgReader.h +++ b/Shared/sdk/CScriptArgReader.h @@ -166,7 +166,7 @@ class CScriptArgReader return; } outValue = CVector2D(); - return; // Error set in ReadUserData + return; // Error set in ReadUserData } else if (NextIsUserDataOfType()) { @@ -179,7 +179,7 @@ class CScriptArgReader return; } outValue = CVector2D(); - return; // Error set in ReadUserData + return; // Error set in ReadUserData } else if (NextIsUserDataOfType()) { @@ -192,7 +192,7 @@ class CScriptArgReader return; } outValue = CVector2D(); - return; // Error set in ReadUserData + return; // Error set in ReadUserData } } @@ -227,7 +227,7 @@ class CScriptArgReader return; } outValue = CVector2D(); - return; // Error set in ReadUserData + return; // Error set in ReadUserData } else if (NextIsUserDataOfType()) { @@ -240,7 +240,7 @@ class CScriptArgReader return; } outValue = CVector2D(); - return; // Error set in ReadUserData + return; // Error set in ReadUserData } else if (NextIsUserDataOfType()) { @@ -253,7 +253,7 @@ class CScriptArgReader return; } outValue = CVector2D(); - return; // Error set in ReadUserData + return; // Error set in ReadUserData } } else if (iArgument == LUA_TNIL || iArgument == LUA_TNONE) @@ -292,7 +292,7 @@ class CScriptArgReader return; } outValue = CVector(); - return; // Error set in ReadUserData + return; // Error set in ReadUserData } else if (NextIsUserDataOfType()) { @@ -305,7 +305,7 @@ class CScriptArgReader return; } outValue = CVector4D(); - return; // Error set in ReadUserData + return; // Error set in ReadUserData } } @@ -341,7 +341,7 @@ class CScriptArgReader return; } outValue = CVector(); - return; // Error set in ReadUserData + return; // Error set in ReadUserData } else if (NextIsUserDataOfType()) { @@ -354,7 +354,7 @@ class CScriptArgReader return; } outValue = CVector4D(); - return; // Error set in ReadUserData + return; // Error set in ReadUserData } } else if (iArgument == LUA_TNIL || iArgument == LUA_TNONE) @@ -394,7 +394,7 @@ class CScriptArgReader return; } outValue = CVector4D(); - return; // Error set in ReadUserData + return; // Error set in ReadUserData } } @@ -431,7 +431,7 @@ class CScriptArgReader return; } outValue = CVector4D(); - return; // Error set in ReadUserData + return; // Error set in ReadUserData } } else if (iArgument == LUA_TNIL || iArgument == LUA_TNONE) @@ -477,7 +477,7 @@ class CScriptArgReader return; } outValue = CMatrix(); - return; // Error set in ReadUserData + return; // Error set in ReadUserData } outValue = CMatrix(); @@ -537,7 +537,7 @@ class CScriptArgReader { return lua_toboolean(m_luaVM, m_iIndex++) ? true : false; } - + m_iIndex++; return false; } @@ -619,9 +619,9 @@ class CScriptArgReader const int iArgument = lua_type(m_luaVM, m_iIndex); if (iArgument == LUA_TSTRING) { - size_t length; + size_t length; const char* str = lua_tolstring(m_luaVM, m_iIndex, &length); - unsigned hash = lua_tostringhash(m_luaVM, m_iIndex++); + unsigned hash = lua_tostringhash(m_luaVM, m_iIndex++); try { @@ -633,7 +633,7 @@ class CScriptArgReader } return; - } + } outValue.Clear(); SetTypeError("string"); @@ -651,7 +651,7 @@ class CScriptArgReader m_iIndex = -1; ReadAnyAsString(outValue); - lua_pop(m_luaVM, 1); // Clean up stack + lua_pop(m_luaVM, 1); // Clean up stack m_iIndex = oldIndex + 1; return; } @@ -821,7 +821,7 @@ class CScriptArgReader // If will be coercing a string to an enum, make sure string contains only digits size_t uiPos = strValue.find_first_not_of("0123456789"); if (uiPos != SString::npos || strValue.empty()) - iArgument = LUA_TNONE; // Force error + iArgument = LUA_TNONE; // Force error } if (iArgument == LUA_TSTRING || iArgument == LUA_TNUMBER) @@ -1389,7 +1389,7 @@ class CScriptArgReader if (NextIsNumber()) ReadNumber(outValue, defaultValue); else - outValue = defaultValue; + outValue = static_cast(defaultValue); } void ReadIfNextIsString(SString& outValue, const char* defaultValue) @@ -1455,11 +1455,11 @@ class CScriptArgReader // Output warning here (there's no better way to integrate it without huge code changes if (!m_bError && !m_strCustomWarning.empty()) { - #ifdef MTA_CLIENT +#ifdef MTA_CLIENT CLuaFunctionDefs::m_pScriptDebugging->LogWarning(m_luaVM, m_strCustomWarning); - #else +#else g_pGame->GetScriptDebugging()->LogWarning(m_luaVM, m_strCustomWarning); - #endif +#endif m_strCustomWarning.clear(); } diff --git a/Shared/sdk/CVector.h b/Shared/sdk/CVector.h index ad9805077e7..fb55ede23b3 100644 --- a/Shared/sdk/CVector.h +++ b/Shared/sdk/CVector.h @@ -30,11 +30,13 @@ class CVector float fY; float fZ; - struct NoInit {}; + struct NoInit + { + }; CVector(NoInit) noexcept {} constexpr CVector() noexcept : fX(0.0f), fY(0.0f), fZ(0.0f) {} - + constexpr explicit CVector(float x, float y = 0.0f, float z = 0.0f) noexcept : fX(x), fY(y), fZ(z) {} constexpr CVector(const CVector4D& vec) noexcept : fX(vec.fX), fY(vec.fY), fZ(vec.fZ) {} @@ -142,8 +144,8 @@ class CVector } // https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm - bool IntersectsSegmentTriangle(const CVector& dir, const CVector& vecVert1, const CVector& vecVert2, const CVector& vecVert3, - CVector* outVec, CVector* outHitBary = nullptr) const noexcept + bool IntersectsSegmentTriangle(const CVector& dir, const CVector& vecVert1, const CVector& vecVert2, const CVector& vecVert3, CVector* outVec, + CVector* outHitBary = nullptr) const noexcept { constexpr float fEpsilon = 1e-6f; @@ -185,8 +187,9 @@ class CVector if (t > fEpsilon && t <= dir.Length()) { *outVec = *this + vecRay * t; - if (outHitBary) { // Calculate all barycentric coords if necessary - *outHitBary = CVector( 1.f - u - v, u, v ); // For vertices A, B, C [I assume?] + if (outHitBary) + { // Calculate all barycentric coords if necessary + *outHitBary = CVector(1.f - u - v, u, v); // For vertices A, B, C [I assume?] } return true; } diff --git a/Shared/sdk/Common.h b/Shared/sdk/Common.h index 09e6636e57f..13517bf29a1 100644 --- a/Shared/sdk/Common.h +++ b/Shared/sdk/Common.h @@ -11,19 +11,22 @@ #pragma once +#include +#include + // Min and max number of characters in player serial #define MIN_SERIAL_LENGTH 1 #define MAX_SERIAL_LENGTH 32 // Network disconnection reason (message) size -#define NET_DISCONNECT_REASON_SIZE 256 +#define NET_DISCONNECT_REASON_SIZE 256 // Element IDs #define RESERVED_ELEMENT_ID 0xFFFFFFFE -#define INVALID_ELEMENT_ID 0xFFFFFFFF +#define INVALID_ELEMENT_ID 0xFFFFFFFF // Element name characteristics -#define MAX_TYPENAME_LENGTH 32 +#define MAX_TYPENAME_LENGTH 32 #define MAX_ELEMENT_NAME_LENGTH 64 // Allow 2^17 server elements and 2^17 client elements @@ -83,18 +86,50 @@ struct ElementID #define MAX_EVENT_NAME_LENGTH 512 // LAN packet broadcasting port -#define SERVER_LIST_BROADCAST_PORT 34219 +#define SERVER_LIST_BROADCAST_PORT 34219 // Server game to query port offset (gameport + offset = queryport) -#define SERVER_LIST_QUERY_PORT_OFFSET 123 +#define SERVER_LIST_QUERY_PORT_OFFSET 123 // LAN packet broadcasting string -#define SERVER_LIST_CLIENT_BROADCAST_STR "MTA-CLIENT" -#define SERVER_LIST_SERVER_BROADCAST_STR "MTA-SERVER" +#define SERVER_LIST_CLIENT_BROADCAST_STR "MTA-CLIENT" +#define SERVER_LIST_SERVER_BROADCAST_STR "MTA-SERVER" // Defines the min/max size for the player nick for use in the core module -#define MIN_PLAYER_NICK_LENGTH 1 -#define MAX_PLAYER_NICK_LENGTH 22 +#define MIN_PLAYER_NICK_LENGTH 1 +#define MAX_PLAYER_NICK_LENGTH 22 // Maximum number of players that can be packed in a single lightweight puresync packet -#define LIGHTSYNC_MAX_PLAYERS 32 +#define LIGHTSYNC_MAX_PLAYERS 32 + +// Frame rate limits +namespace FPSLimits +{ + constexpr std::uint16_t FPS_MAX = std::numeric_limits::max(); // Maximum allowed frame rate limit + constexpr std::uint16_t FPS_MIN = 25; // Minimum allowed frame rate limit + constexpr std::uint16_t FPS_UNLIMITED = 0; // Unlimited frame rate (no limit) + + // Takes a FPS value and + // 1. Returns if `fpsToValidate` was valid + // 2. Writes clamped value to `outValidFps` reference + inline bool IsValidAndSetValid(std::uint16_t fpsToValidate, std::uint16_t& outValidFps) noexcept + { + if (fpsToValidate == FPS_UNLIMITED) + { + outValidFps = FPS_UNLIMITED; + return true; + } + if (fpsToValidate < FPS_MIN) + { + outValidFps = FPS_MIN; + return false; + } + if (fpsToValidate > FPS_MAX) + { + outValidFps = FPS_MAX; + return false; + } + outValidFps = fpsToValidate; + return true; + } +} // namespace FPSLimits diff --git a/Shared/sdk/CrashTelemetry.h b/Shared/sdk/CrashTelemetry.h new file mode 100644 index 00000000000..b9cde5d3c73 --- /dev/null +++ b/Shared/sdk/CrashTelemetry.h @@ -0,0 +1,377 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include + +#if defined(_WIN32) && defined(__cplusplus) +extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(void); +#endif + +#ifdef __cplusplus +namespace CrashTelemetry +{ + struct Context + { + std::size_t requestedSize{0}; + const void* resourcePointer{nullptr}; + std::array resourceTag{}; + std::array detail{}; + std::chrono::system_clock::time_point timestamp{}; + std::uint32_t threadId{0}; + bool hasData{false}; + }; + + #if defined(MTA_CLIENT) + #include + #include + #include + #include + #include + + namespace detail + { + constexpr std::size_t kHistoryCapacity = 6; + + template + inline void CopyInto(std::array& destination, const char* source) noexcept + { + if (destination.empty()) + return; + + const std::size_t maxCopy = N - 1; + const std::size_t copyLength = (source != nullptr) ? std::min(std::strlen(source), maxCopy) : 0; + + if (copyLength != 0) + { + std::memcpy(destination.data(), source, copyLength); + destination[copyLength] = '\0'; + } + else + { + destination[0] = '\0'; + } + + if (copyLength + 1 < N) + { + std::fill(destination.begin() + static_cast(copyLength + 1), destination.end(), '\0'); + } + } + + inline std::uint32_t GetThreadIdentifier() noexcept + { + #if defined(_WIN32) + return static_cast(::GetCurrentThreadId()); + #else + const auto hashed = std::hash{}(std::this_thread::get_id()); + return static_cast(hashed & 0xFFFFFFFFu); + #endif + } + + struct ThreadState + { + Context current{}; + std::array history{}; + std::size_t nextSlot = 0; + std::size_t size = 0; + std::size_t lastFailureSize = 0; + Context lastManualScope{}; + bool lastManualScopeValid = false; + + void PushSnapshot() noexcept + { + history[nextSlot] = current; + history[nextSlot].hasData = true; + nextSlot = (nextSlot + 1) % kHistoryCapacity; + if (size < kHistoryCapacity) + ++size; + } + + template + void VisitNewestFirst(Callback&& callback) const noexcept + { + for (std::size_t i = 0; i < size; ++i) + { + const auto slotIndex = (nextSlot + kHistoryCapacity - 1 - i) % kHistoryCapacity; + const Context& entry = history[slotIndex]; + if (!entry.hasData) + continue; + + callback(entry); + } + } + }; + + inline ThreadState& GetThreadState() noexcept + { + thread_local ThreadState state{}; + return state; + } + + inline bool ContextEquals(const Context& lhs, const Context& rhs) noexcept + { + if (!lhs.hasData || !rhs.hasData) + return false; + + if (lhs.requestedSize != rhs.requestedSize || lhs.resourcePointer != rhs.resourcePointer || lhs.threadId != rhs.threadId || + lhs.timestamp != rhs.timestamp) + return false; + + if (std::memcmp(lhs.resourceTag.data(), rhs.resourceTag.data(), lhs.resourceTag.size()) != 0) + return false; + + if (std::memcmp(lhs.detail.data(), rhs.detail.data(), lhs.detail.size()) != 0) + return false; + + return true; + } + + inline void RecordManualScopeSnapshot() noexcept + { + ThreadState& state = GetThreadState(); + state.lastManualScope = state.current; + state.lastManualScope.hasData = true; + state.lastManualScopeValid = true; + } + } // namespace detail + + inline void SetAllocationContext(std::size_t sizeBytes, const void* resourcePtr, const char* resourceTag, const char* detail) noexcept + { + Context& current = detail::GetThreadState().current; + current.requestedSize = sizeBytes; + current.resourcePointer = resourcePtr; + current.timestamp = std::chrono::system_clock::now(); + current.threadId = detail::GetThreadIdentifier(); + detail::CopyInto(current.resourceTag, resourceTag); + detail::CopyInto(current.detail, detail); + current.hasData = true; + + detail::GetThreadState().PushSnapshot(); + } + + inline void ClearAllocationContext() noexcept + { + detail::GetThreadState().current = Context{}; + } + + inline Context CaptureContext() noexcept + { + return detail::GetThreadState().current; + } + + inline void RestoreContext(const Context& context) noexcept + { + detail::GetThreadState().current = context; + } + + inline void RecordAllocationFailureSize(std::size_t sizeBytes) noexcept + { + detail::GetThreadState().lastFailureSize = sizeBytes; + } + + inline std::size_t GetRecordedAllocationSize() noexcept + { + const auto& state = detail::GetThreadState(); + if (state.lastFailureSize != 0) + return state.lastFailureSize; + + return state.current.requestedSize; + } + + inline std::string BuildAllocationTelemetryNote() noexcept + { + std::array snapshot{}; + std::size_t snapshotCount = 0; + const auto now = std::chrono::system_clock::now(); + + const auto& threadState = detail::GetThreadState(); + threadState.VisitNewestFirst( + [&](const Context& entry) + { + if (snapshotCount < snapshot.size()) + snapshot[snapshotCount++] = entry; + }); + + const std::size_t recordedSize = GetRecordedAllocationSize(); + + std::string note; + note.reserve(640); + + auto appendEntryLine = [&](const Context& entry, std::size_t index, bool includeIndexLabel) + { + std::size_t sizeToReport = entry.requestedSize; + if (includeIndexLabel && index == 0 && recordedSize != 0) + { + sizeToReport = recordedSize; + } + + const char* resourceTag = (entry.resourceTag[0] != '\0') ? entry.resourceTag.data() : ""; + const char* detailText = (entry.detail[0] != '\0') ? entry.detail.data() : ""; + const auto threadId = entry.threadId != 0 ? entry.threadId : detail::GetThreadIdentifier(); + + long long ageMs = -1; + if (entry.timestamp.time_since_epoch().count() != 0) + { + ageMs = std::chrono::duration_cast(now - entry.timestamp).count(); + if (ageMs < 0) + ageMs = 0; + } + + char line[256]{}; + if (ageMs >= 0) + { + if (includeIndexLabel) + { + _snprintf_s(line, sizeof(line), _TRUNCATE, " #%zu requested=%zu bytes, tag=%s, detail=%s, object=0x%p, thread=%lu, age=%llims\n", index, + sizeToReport, resourceTag, detailText, entry.resourcePointer, static_cast(threadId), ageMs); + } + else + { + _snprintf_s(line, sizeof(line), _TRUNCATE, " requested=%zu bytes, tag=%s, detail=%s, object=0x%p, thread=%lu, age=%llims\n", sizeToReport, + resourceTag, detailText, entry.resourcePointer, static_cast(threadId), ageMs); + } + } + else + { + if (includeIndexLabel) + { + _snprintf_s(line, sizeof(line), _TRUNCATE, " #%zu requested=%zu bytes, tag=%s, detail=%s, object=0x%p, thread=%lu\n", index, sizeToReport, + resourceTag, detailText, entry.resourcePointer, static_cast(threadId)); + } + else + { + _snprintf_s(line, sizeof(line), _TRUNCATE, " requested=%zu bytes, tag=%s, detail=%s, object=0x%p, thread=%lu\n", sizeToReport, resourceTag, + detailText, entry.resourcePointer, static_cast(threadId)); + } + } + + note += line; + }; + + if (snapshotCount == 0) + { + char buffer[160]{}; + _snprintf_s(buffer, sizeof(buffer), _TRUNCATE, "Allocation telemetry: requested=%zu bytes (no tagged context available)\n", recordedSize); + note += buffer; + } + else + { + note += "Allocation telemetry (most recent first):\n"; + for (std::size_t i = 0; i < snapshotCount; ++i) + { + appendEntryLine(snapshot[i], i, true); + } + } + + const bool hasManualScope = threadState.lastManualScopeValid && threadState.lastManualScope.hasData; + bool manualScopeCapturedInRing = false; + if (hasManualScope) + { + for (std::size_t i = 0; i < snapshotCount; ++i) + { + if (detail::ContextEquals(snapshot[i], threadState.lastManualScope)) + { + manualScopeCapturedInRing = true; + break; + } + } + } + + if (!hasManualScope) + { + note += "CrashTelemetry::Scope annotations: none executed on this thread before crash; instrument entry points to capture context.\n"; + } + else if (!manualScopeCapturedInRing) + { + // Helps to see the last annotated scope even if the allocator ring threw it out; use this to decide + // which additional paths (such as todos: CMapEventManager dispatch, CClientEntity::CallEvent, resource download callbacks, etc.) + // should receive CrashTelemetry::Scope guards next. + note += "Last CrashTelemetry::Scope (not present in allocation ring):\n"; + appendEntryLine(threadState.lastManualScope, 0, false); + } + + return note; + } + + class Scope + { + public: + Scope(std::size_t sizeBytes, const void* resourcePtr, const char* resourceTag, const char* detail) noexcept + : m_previous(CaptureContext()), m_restore(true) + { + SetAllocationContext(sizeBytes, resourcePtr, resourceTag, detail); + // Every CrashTelemetry::Scope marks a meaningful execution point. Add these to crash-prone hot paths + // (Lua event dispatch, CMapEventManager, CClientEntity::CallEvent, resource downloads, etc.) so any crash, + // including nullptr dereferences, retains the last context in telemetry dumps. + detail::RecordManualScopeSnapshot(); + } + ~Scope() + { + if (m_restore) + { + RestoreContext(m_previous); + } + } + + Scope(const Scope&) = delete; + Scope& operator=(const Scope&) = delete; + Scope(Scope&&) = delete; + Scope& operator=(Scope&&) = delete; + + private: + Context m_previous{}; + bool m_restore{false}; + }; + #else + inline void RecordAllocationFailureSize(std::size_t) noexcept + { + } + inline std::size_t GetRecordedAllocationSize() noexcept + { + return 0; + } + inline void SetAllocationContext(std::size_t, const void*, const char*, const char*) noexcept + { + } + + inline void ClearAllocationContext() noexcept + { + } + + inline Context CaptureContext() noexcept + { + return Context{}; + } + inline void RestoreContext(const Context&) noexcept + { + } + inline std::string BuildAllocationTelemetryNote() noexcept + { + return {}; + } + + class Scope + { + public: + Scope(std::size_t, const void*, const char*, const char*) noexcept {} + ~Scope() = default; + + Scope(const Scope&) = delete; + Scope& operator=(const Scope&) = delete; + Scope(Scope&&) = delete; + Scope& operator=(Scope&&) = delete; + }; + #endif +} // namespace CrashTelemetry +#endif diff --git a/Shared/sdk/RTree.h b/Shared/sdk/RTree.h index 922c5183271..3f662e4b1b8 100644 --- a/Shared/sdk/RTree.h +++ b/Shared/sdk/RTree.h @@ -55,23 +55,23 @@ o Minor updates for MSVC 2005/08 compilers #include #ifndef _WIN32 -#define __cdecl + #define __cdecl #endif -#define ASSERT assert // RTree uses ASSERT( condition ) +#define ASSERT assert // RTree uses ASSERT( condition ) // // RTree.h // -#define RTREE_TEMPLATE template -#define RTREE_QUAL RTree +#define RTREE_TEMPLATE template +#define RTREE_QUAL RTree -#define RTREE_DONT_USE_MEMPOOLS // This version does not contain a fixed memory allocator, fill in lines with EXAMPLE to implement one. -#define RTREE_USE_SPHERICAL_VOLUME // Better split classification, may be slower on some systems +#define RTREE_DONT_USE_MEMPOOLS // This version does not contain a fixed memory allocator, fill in lines with EXAMPLE to implement one. +#define RTREE_USE_SPHERICAL_VOLUME // Better split classification, may be slower on some systems // Fwd decl -class RTFileStream; // File I/O helper class, look below for implementation and notes. +class RTFileStream; // File I/O helper class, look below for implementation and notes. /// \class RTree /// Implementation of RTree, a multidimensional bounding rectangle tree. @@ -93,15 +93,15 @@ template IsLeaf()) { @@ -268,10 +268,10 @@ class RTree return m_stack[m_tos]; } - StackElement m_stack[MAX_STACK]; ///< Stack as we are doing iteration instead of recursion - int m_tos; ///< Top Of Stack index + StackElement m_stack[MAX_STACK]; ///< Stack as we are doing iteration instead of recursion + int m_tos; ///< Top Of Stack index - friend class RTree; // Allow hiding of non-public functions while allowing manipulation by logical owner + friend class RTree; // Allow hiding of non-public functions while allowing manipulation by logical owner }; /// Get 'first' for iteration @@ -283,7 +283,7 @@ class RTree { if (first->IsInternalNode() && first->m_count > 1) { - a_it.Push(first, 1); // Descend sibling branch later + a_it.Push(first, 1); // Descend sibling branch later } else if (first->IsLeaf()) { @@ -310,8 +310,8 @@ class RTree /// Minimal bounding rectangle (n-dimensional) struct Rect { - ELEMTYPE m_min[NUMDIMS]; ///< Min dimensions of bounding box - ELEMTYPE m_max[NUMDIMS]; ///< Max dimensions of bounding box + ELEMTYPE m_min[NUMDIMS]; ///< Min dimensions of bounding box + ELEMTYPE m_max[NUMDIMS]; ///< Max dimensions of bounding box }; /// May be data or may be another subtree @@ -319,30 +319,30 @@ class RTree /// If the parents level is 0, then this is data struct Branch { - Rect m_rect; ///< Bounds + Rect m_rect; ///< Bounds union { - Node* m_child; ///< Child node - DATATYPE m_data; ///< Data Id or Ptr + Node* m_child; ///< Child node + DATATYPE m_data; ///< Data Id or Ptr }; }; /// Node for each branch level struct Node { - bool IsInternalNode() { return (m_level > 0); } // Not a leaf, but a internal node - bool IsLeaf() { return (m_level == 0); } // A leaf, contains data + bool IsInternalNode() { return (m_level > 0); } // Not a leaf, but a internal node + bool IsLeaf() { return (m_level == 0); } // A leaf, contains data - int m_count; ///< Count - int m_level; ///< Leaf is zero, others positive - Branch m_branch[MAXNODES]; ///< Branch + int m_count; ///< Count + int m_level; ///< Leaf is zero, others positive + Branch m_branch[MAXNODES]; ///< Branch }; /// A link list of nodes for reinsertion after a delete operation struct ListNode { - ListNode* m_next; ///< Next in list - Node* m_node; ///< Node + ListNode* m_next; ///< Next in list + Node* m_node; ///< Node }; /// Variables for finding a split partition @@ -397,8 +397,8 @@ class RTree bool SaveRec(Node* a_node, RTFileStream& a_stream); bool LoadRec(Node* a_node, RTFileStream& a_stream); - Node* m_root; ///< Root of tree - ELEMTYPEREAL m_unitSphereVolume; ///< Unit sphere constant for required number of dimensions + Node* m_root; ///< Root of tree + ELEMTYPEREAL m_unitSphereVolume; ///< Unit sphere constant for required number of dimensions }; // Because there is not stream support, this is a quick and dirty file I/O helper. @@ -482,13 +482,13 @@ RTREE_QUAL::RTree() // Precomputed volumes of the unit spheres for the first few dimensions const float UNIT_SPHERE_VOLUMES[] = { - 0.000000f, 2.000000f, 3.141593f, // Dimension 0,1,2 - 4.188790f, 4.934802f, 5.263789f, // Dimension 3,4,5 - 5.167713f, 4.724766f, 4.058712f, // Dimension 6,7,8 - 3.298509f, 2.550164f, 1.884104f, // Dimension 9,10,11 - 1.335263f, 0.910629f, 0.599265f, // Dimension 12,13,14 - 0.381443f, 0.235331f, 0.140981f, // Dimension 15,16,17 - 0.082146f, 0.046622f, 0.025807f, // Dimension 18,19,20 + 0.000000f, 2.000000f, 3.141593f, // Dimension 0,1,2 + 4.188790f, 4.934802f, 5.263789f, // Dimension 3,4,5 + 5.167713f, 4.724766f, 4.058712f, // Dimension 6,7,8 + 3.298509f, 2.550164f, 1.884104f, // Dimension 9,10,11 + 1.335263f, 0.910629f, 0.599265f, // Dimension 12,13,14 + 0.381443f, 0.235331f, 0.140981f, // Dimension 15,16,17 + 0.082146f, 0.046622f, 0.025807f, // Dimension 18,19,20 }; m_root = AllocNode(); @@ -499,7 +499,7 @@ RTREE_QUAL::RTree() RTREE_TEMPLATE RTREE_QUAL::~RTree() { - Reset(); // Free, or reset node memory + Reset(); // Free, or reset node memory } RTREE_TEMPLATE @@ -510,7 +510,7 @@ void RTREE_QUAL::Insert(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMD { ASSERT(a_min[index] <= a_max[index]); } -#endif //_DEBUG +#endif //_DEBUG Rect rect; @@ -531,7 +531,7 @@ void RTREE_QUAL::Remove(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMD { ASSERT(a_min[index] <= a_max[index]); } -#endif //_DEBUG +#endif //_DEBUG Rect rect; @@ -552,7 +552,7 @@ void RTREE_QUAL::Search(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMD { ASSERT(a_min[index] <= a_max[index]); } -#endif //_DEBUG +#endif //_DEBUG Rect rect; @@ -579,14 +579,14 @@ int RTREE_QUAL::Count() RTREE_TEMPLATE void RTREE_QUAL::CountRec(Node* a_node, int& a_count) { - if (a_node->IsInternalNode()) // not a leaf node + if (a_node->IsInternalNode()) // not a leaf node { for (int index = 0; index < a_node->m_count; ++index) { CountRec(a_node->m_branch[index].m_child, a_count); } } - else // A leaf node + else // A leaf node { a_count += a_node->m_count; } @@ -595,7 +595,7 @@ void RTREE_QUAL::CountRec(Node* a_node, int& a_count) RTREE_TEMPLATE bool RTREE_QUAL::Load(const char* a_fileName) { - RemoveAll(); // Clear existing tree + RemoveAll(); // Clear existing tree RTFileStream stream; if (!stream.OpenRead(a_fileName)) @@ -657,7 +657,7 @@ bool RTREE_QUAL::LoadRec(Node* a_node, RTFileStream& a_stream) a_stream.Read(a_node->m_level); a_stream.Read(a_node->m_count); - if (a_node->IsInternalNode()) // not a leaf node + if (a_node->IsInternalNode()) // not a leaf node { for (int index = 0; index < a_node->m_count; ++index) { @@ -670,7 +670,7 @@ bool RTREE_QUAL::LoadRec(Node* a_node, RTFileStream& a_stream) LoadRec(curBranch->m_child, a_stream); } } - else // A leaf node + else // A leaf node { for (int index = 0; index < a_node->m_count; ++index) { @@ -683,7 +683,7 @@ bool RTREE_QUAL::LoadRec(Node* a_node, RTFileStream& a_stream) } } - return true; // Should do more error checking on I/O operations + return true; // Should do more error checking on I/O operations } RTREE_TEMPLATE @@ -734,7 +734,7 @@ bool RTREE_QUAL::SaveRec(Node* a_node, RTFileStream& a_stream) a_stream.Write(a_node->m_level); a_stream.Write(a_node->m_count); - if (a_node->IsInternalNode()) // not a leaf node + if (a_node->IsInternalNode()) // not a leaf node { for (int index = 0; index < a_node->m_count; ++index) { @@ -746,7 +746,7 @@ bool RTREE_QUAL::SaveRec(Node* a_node, RTFileStream& a_stream) SaveRec(curBranch->m_child, a_stream); } } - else // A leaf node + else // A leaf node { for (int index = 0; index < a_node->m_count; ++index) { @@ -759,7 +759,7 @@ bool RTREE_QUAL::SaveRec(Node* a_node, RTFileStream& a_stream) } } - return true; // Should do more error checking on I/O operations + return true; // Should do more error checking on I/O operations } RTREE_TEMPLATE @@ -778,10 +778,10 @@ void RTREE_QUAL::Reset() #ifdef RTREE_DONT_USE_MEMPOOLS // Delete all existing nodes RemoveAllRec(m_root); -#else // RTREE_DONT_USE_MEMPOOLS +#else // RTREE_DONT_USE_MEMPOOLS // Just reset memory pools. We are not using complex types // EXAMPLE -#endif // RTREE_DONT_USE_MEMPOOLS +#endif // RTREE_DONT_USE_MEMPOOLS } RTREE_TEMPLATE @@ -790,7 +790,7 @@ void RTREE_QUAL::RemoveAllRec(Node* a_node) ASSERT(a_node); ASSERT(a_node->m_level >= 0); - if (a_node->IsInternalNode()) // This is an internal node in the tree + if (a_node->IsInternalNode()) // This is an internal node in the tree { for (int index = 0; index < a_node->m_count; ++index) { @@ -806,9 +806,9 @@ typename RTREE_QUAL::Node* RTREE_QUAL::AllocNode() Node* newNode; #ifdef RTREE_DONT_USE_MEMPOOLS newNode = new Node; -#else // RTREE_DONT_USE_MEMPOOLS +#else // RTREE_DONT_USE_MEMPOOLS // EXAMPLE -#endif // RTREE_DONT_USE_MEMPOOLS +#endif // RTREE_DONT_USE_MEMPOOLS InitNode(newNode); return newNode; } @@ -820,9 +820,9 @@ void RTREE_QUAL::FreeNode(Node* a_node) #ifdef RTREE_DONT_USE_MEMPOOLS delete a_node; -#else // RTREE_DONT_USE_MEMPOOLS +#else // RTREE_DONT_USE_MEMPOOLS // EXAMPLE -#endif // RTREE_DONT_USE_MEMPOOLS +#endif // RTREE_DONT_USE_MEMPOOLS } // Allocate space for a node in the list used in DeletRect to @@ -832,9 +832,9 @@ typename RTREE_QUAL::ListNode* RTREE_QUAL::AllocListNode() { #ifdef RTREE_DONT_USE_MEMPOOLS return new ListNode; -#else // RTREE_DONT_USE_MEMPOOLS +#else // RTREE_DONT_USE_MEMPOOLS // EXAMPLE -#endif // RTREE_DONT_USE_MEMPOOLS +#endif // RTREE_DONT_USE_MEMPOOLS } RTREE_TEMPLATE @@ -842,9 +842,9 @@ void RTREE_QUAL::FreeListNode(ListNode* a_listNode) { #ifdef RTREE_DONT_USE_MEMPOOLS delete a_listNode; -#else // RTREE_DONT_USE_MEMPOOLS +#else // RTREE_DONT_USE_MEMPOOLS // EXAMPLE -#endif // RTREE_DONT_USE_MEMPOOLS +#endif // RTREE_DONT_USE_MEMPOOLS } RTREE_TEMPLATE @@ -891,7 +891,7 @@ bool RTREE_QUAL::InsertRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, a_node->m_branch[index].m_rect = CombineRect(a_rect, &(a_node->m_branch[index].m_rect)); return false; } - else // Child was split + else // Child was split { a_node->m_branch[index].m_rect = NodeCover(a_node->m_branch[index].m_child); branch.m_child = otherNode; @@ -899,7 +899,7 @@ bool RTREE_QUAL::InsertRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, return AddBranch(&branch, a_node, a_newNode); } } - else if (a_node->m_level == a_level) // Have reached level for insertion. Add rect, split if necessary + else if (a_node->m_level == a_level) // Have reached level for insertion. Add rect, split if necessary { branch.m_rect = *a_rect; branch.m_child = (Node*)a_id; @@ -931,15 +931,15 @@ bool RTREE_QUAL::InsertRect(Rect* a_rect, const DATATYPE& a_id, Node** a_root, i { ASSERT(a_rect->m_min[index] <= a_rect->m_max[index]); } -#endif //_DEBUG +#endif //_DEBUG Node* newRoot; Node* newNode; Branch branch; - if (InsertRectRec(a_rect, a_id, *a_root, &newNode, a_level)) // Root split + if (InsertRectRec(a_rect, a_id, *a_root, &newNode, a_level)) // Root split { - newRoot = AllocNode(); // Grow tree taller and new root + newRoot = AllocNode(); // Grow tree taller and new root newRoot->m_level = (*a_root)->m_level + 1; branch.m_rect = NodeCover(*a_root); branch.m_child = *a_root; @@ -990,7 +990,7 @@ bool RTREE_QUAL::AddBranch(Branch* a_branch, Node* a_node, Node** a_newNode) ASSERT(a_branch); ASSERT(a_node); - if (a_node->m_count < MAXNODES) // Split won't be necessary + if (a_node->m_count < MAXNODES) // Split won't be necessary { a_node->m_branch[a_node->m_count] = *a_branch; ++a_node->m_count; @@ -1163,10 +1163,10 @@ RTREE_TEMPLATE ELEMTYPEREAL RTREE_QUAL::CalcRectVolume(Rect* a_rect) { #ifdef RTREE_USE_SPHERICAL_VOLUME - return RectSphericalVolume(a_rect); // Slower but helps certain merge cases -#else // RTREE_USE_SPHERICAL_VOLUME - return RectVolume(a_rect); // Faster but can cause poor merges -#endif // RTREE_USE_SPHERICAL_VOLUME + return RectSphericalVolume(a_rect); // Slower but helps certain merge cases +#else // RTREE_USE_SPHERICAL_VOLUME + return RectVolume(a_rect); // Faster but can cause poor merges +#endif // RTREE_USE_SPHERICAL_VOLUME } // Load branch buffer with branches from full node plus the extra branch. @@ -1438,7 +1438,7 @@ bool RTREE_QUAL::RemoveRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, ASSERT(a_rect && a_node && a_listNode); ASSERT(a_node->m_level >= 0); - if (a_node->IsInternalNode()) // not a leaf node + if (a_node->IsInternalNode()) // not a leaf node { for (int index = 0; index < a_node->m_count; ++index) { @@ -1455,7 +1455,7 @@ bool RTREE_QUAL::RemoveRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, { // child removed, not enough entries in node, eliminate node ReInsert(a_node->m_branch[index].m_child, a_listNode); - DisconnectBranch(a_node, index); // Must return after this call as count has changed + DisconnectBranch(a_node, index); // Must return after this call as count has changed } return false; } @@ -1463,13 +1463,13 @@ bool RTREE_QUAL::RemoveRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, } return true; } - else // A leaf node + else // A leaf node { for (int index = 0; index < a_node->m_count; ++index) { if (a_node->m_branch[index].m_child == (Node*)a_id) { - DisconnectBranch(a_node, index); // Must return after this call as count has changed + DisconnectBranch(a_node, index); // Must return after this call as count has changed return false; } } @@ -1514,7 +1514,7 @@ bool RTREE_QUAL::Search(Node* a_node, Rect* a_rect, std::vector& resul ASSERT(a_node->m_level >= 0); ASSERT(a_rect); - if (a_node->IsInternalNode()) // This is an internal node in the tree + if (a_node->IsInternalNode()) // This is an internal node in the tree { for (int index = 0; index < a_node->m_count; ++index) { @@ -1522,12 +1522,12 @@ bool RTREE_QUAL::Search(Node* a_node, Rect* a_rect, std::vector& resul { if (!Search(a_node->m_branch[index].m_child, a_rect, resultList)) { - return false; // Don't continue searching + return false; // Don't continue searching } } } } - else // This is a leaf node + else // This is a leaf node { for (int index = 0; index < a_node->m_count; ++index) { @@ -1541,10 +1541,10 @@ bool RTREE_QUAL::Search(Node* a_node, Rect* a_rect, std::vector& resul } } - return true; // Continue searching + return true; // Continue searching } #undef RTREE_TEMPLATE #undef RTREE_QUAL -#endif //RTREE_H +#endif // RTREE_H diff --git a/Shared/sdk/SString.h b/Shared/sdk/SString.h index 54595788386..08ba333a781 100644 --- a/Shared/sdk/SString.h +++ b/Shared/sdk/SString.h @@ -17,9 +17,9 @@ #include "SharedUtil.IntTypes.h" #ifdef WIN32 -#ifndef va_copy - #define va_copy(dest, orig) (dest) = (orig) -#endif + #ifndef va_copy + #define va_copy(dest, orig) (dest) = (orig) + #endif #endif class SString : public std::string @@ -68,7 +68,7 @@ class SString : public std::string SString operator+(const SString& other) const { return std::string(*this) + other; } // Assignment - operator const char*() const { return c_str(); } // Auto assign to const char* without using c_str() + operator const char*() const { return c_str(); } // Auto assign to const char* without using c_str() const char* operator*() const { return c_str(); } // Functions @@ -98,6 +98,10 @@ class SString : public std::string void AssignLeft(const char* szOther, uint uiMaxLength); }; +// When to use SStringX over SString: +// - (Potential) macro conversions +// - Trouble with implicit conversions +// - Situations where a length parameter is needed class SStringX : public SString { public: diff --git a/Shared/sdk/SharedUtil.AllocTracking.h b/Shared/sdk/SharedUtil.AllocTracking.h index e23f6032ef3..7945c9e9b65 100644 --- a/Shared/sdk/SharedUtil.AllocTracking.h +++ b/Shared/sdk/SharedUtil.AllocTracking.h @@ -105,10 +105,10 @@ inline void _free_(void* Original) return myFree(Original); } - #define malloc _malloc_ - #define calloc _calloc_ + #define malloc _malloc_ + #define calloc _calloc_ #define realloc _realloc_ - #define free _free_ + #define free _free_ #endif #include @@ -181,7 +181,7 @@ namespace std inline bool operator==(Allocator const&) { return true; } inline bool operator!=(Allocator const& a) { return !operator==(a); } - }; // end of class Allocator + }; // end of class Allocator template class CArray : public std::vector<_Ty, Allocator<_Ty> > @@ -226,22 +226,22 @@ namespace std { public: }; -} // namespace std +} // namespace std // Replace std classes // Not safe - do not enable this in distributed builds - #define vector CArray - #define list CList - #define map CMap - #define set CSet - #define deque CDeque + #define vector CArray + #define list CList + #define map CMap + #define set CSet + #define deque CDeque #else - #define myMalloc(a,tag) malloc(a) - #define myCalloc(a,tag) calloc(a) - #define myRealloc(a,b,tag) realloc(a,b) - #define myFree free + #define myMalloc(a, tag) malloc(a) + #define myCalloc(a, tag) calloc(a) + #define myRealloc(a, b, tag) realloc(a, b) + #define myFree free #endif // WITH_ALLOC_TRACKING diff --git a/Shared/sdk/SharedUtil.AllocTracking.hpp b/Shared/sdk/SharedUtil.AllocTracking.hpp index 0dcc9a77a43..aa364b4073c 100644 --- a/Shared/sdk/SharedUtil.AllocTracking.hpp +++ b/Shared/sdk/SharedUtil.AllocTracking.hpp @@ -18,23 +18,22 @@ // #if WITH_ALLOC_TRACKING -#undef map -#ifdef WIN32 - #undef malloc - #undef realloc - #undef calloc - #undef free - #define thread_id uint -#else - #define GetCurrentThreadId pthread_self - #define thread_id pthread_t -#endif - -using namespace std; + #undef map + #ifdef WIN32 + #undef malloc + #undef realloc + #undef calloc + #undef free + #define thread_id uint + #else + #define GetCurrentThreadId pthread_self + #define thread_id pthread_t + #endif + namespace { // #define maptype hash_map - #define maptype map + #define maptype std::map // Update or add a value for a key template void xMapSet(maptype& collection, const T2& key, const V& value) @@ -77,7 +76,7 @@ namespace return NULL; return &it->second; } -} // namespace +} // namespace struct CAllocInfo { @@ -89,18 +88,18 @@ struct CAllocInfo }; static int stats_ready = 1; -#ifdef ALLOC_STATS_MODULE_NAME - #ifndef ALLOC_STATS_PRE_COUNT - #define ALLOC_STATS_PRE_COUNT 0 // Increase if crash at startup - #endif + #ifdef ALLOC_STATS_MODULE_NAME + #ifndef ALLOC_STATS_PRE_COUNT + #define ALLOC_STATS_PRE_COUNT 0 // Increase if crash at startup + #endif static int pre_count = ALLOC_STATS_PRE_COUNT; -#else - #define ALLOC_STATS_MODULE_NAME "none" + #else + #define ALLOC_STATS_MODULE_NAME "none" static int pre_count = -1; -#endif + #endif -static int no_stuff = 0; // No tracking when tracker is allocating -#define INVALID_THREAD_ID (-2) +static int no_stuff = 0; // No tracking when tracker is allocating + #define INVALID_THREAD_ID (-2) typedef unsigned char BYTE; @@ -310,7 +309,7 @@ class CAllocStats { thread_id dwThreadWanting = GetCurrentThreadId(); if (dwThreadWanting == dwThreadUsing) - return false; // No tracking when tracker is allocating + return false; // No tracking when tracker is allocating cs.Lock(); dwThreadUsing = dwThreadWanting; return true; @@ -464,12 +463,12 @@ MTAEXPORT unsigned long GetAllocStats(uint uiType, void* pOutData, unsigned long return 0; } -#define map CMap -#ifdef WIN32 - #define malloc _malloc_ - #define realloc _realloc_ - #define calloc _calloc_ - #define free _free_ -#endif + #define map CMap + #ifdef WIN32 + #define malloc _malloc_ + #define realloc _realloc_ + #define calloc _calloc_ + #define free _free_ + #endif #endif // WITH_ALLOC_TRACKING diff --git a/Shared/sdk/SharedUtil.AsyncTaskScheduler.h b/Shared/sdk/SharedUtil.AsyncTaskScheduler.h index b509070d3bd..e2d3bc071ba 100644 --- a/Shared/sdk/SharedUtil.AsyncTaskScheduler.h +++ b/Shared/sdk/SharedUtil.AsyncTaskScheduler.h @@ -4,14 +4,14 @@ // Workaround MultiplayerSA including this header for whatever reason.. #ifdef __cpp_lib_is_invocable -#define HAS_ASYNC_TASK_SCHED + #define HAS_ASYNC_TASK_SCHED -#include -#include -#include -#include -#include -#include + #include + #include + #include + #include + #include + #include namespace SharedUtil { @@ -96,5 +96,5 @@ namespace SharedUtil std::vector> m_TaskResults; std::mutex m_TaskResultsMutex; }; -} // namespace SharedUtil +} // namespace SharedUtil #endif diff --git a/Shared/sdk/SharedUtil.AsyncTaskScheduler.hpp b/Shared/sdk/SharedUtil.AsyncTaskScheduler.hpp index d547786eb19..5b26b41d5d3 100644 --- a/Shared/sdk/SharedUtil.AsyncTaskScheduler.hpp +++ b/Shared/sdk/SharedUtil.AsyncTaskScheduler.hpp @@ -67,5 +67,5 @@ namespace SharedUtil } } } -} // namespace SharedUtil +} // namespace SharedUtil #endif diff --git a/Shared/sdk/SharedUtil.Buffer.h b/Shared/sdk/SharedUtil.Buffer.h index be104c771e6..a70120141b1 100644 --- a/Shared/sdk/SharedUtil.Buffer.h +++ b/Shared/sdk/SharedUtil.Buffer.h @@ -35,8 +35,8 @@ namespace SharedUtil operator T*() { return buffer.empty() ? nullptr : reinterpret_cast(&buffer.at(0)); } }; - // Assuming compiled on little endian machine - #define CBUFFER_LITTLE_ENDIAN +// Assuming compiled on little endian machine +#define CBUFFER_LITTLE_ENDIAN // #define CBUFFER_BIG_ENDIAN ////////////////////////////////////////////////////// @@ -210,15 +210,15 @@ namespace SharedUtil Seek(Tell()); if (!pBuffer->GetBytes(pData, iLength, Tell(), bToFromNetwork)) - return false; // Not enough bytes left to fill request + return false; // Not enough bytes left to fill request // Adjust pos Seek(Tell() + iLength); return true; } - void Read(SString&); // Not defined as it won't work - void Read(CBuffer&); // Not defined as it won't work + void Read(SString&); // Not defined as it won't work + void Read(CBuffer&); // Not defined as it won't work bool ReadString(SString& result, bool bByteLength = false, bool bDoesLengthIncludeLengthOfLength = false) { result = ""; @@ -343,8 +343,8 @@ namespace SharedUtil Seek(Tell() + iLength); } - void Write(const SString&); // Not defined as it won't work - void Write(const CBuffer&); // Not defined as it won't work + void Write(const SString&); // Not defined as it won't work + void Write(const CBuffer&); // Not defined as it won't work void WriteString(const SString& str, bool bByteLength = false, bool bDoesLengthIncludeLengthOfLength = false) { ushort usLength = (ushort)str.length(); @@ -395,4 +395,4 @@ namespace SharedUtil #endif }; -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.ClassIdent.h b/Shared/sdk/SharedUtil.ClassIdent.h index 79d6f8a4157..7bfc4ae0ba9 100644 --- a/Shared/sdk/SharedUtil.ClassIdent.h +++ b/Shared/sdk/SharedUtil.ClassIdent.h @@ -20,58 +20,80 @@ namespace SharedUtil typedef uint64 ClassBits; typedef uchar ClassId; - #define DECLARE_BASE_CLASS(cls) \ - public: \ - static ClassId GetClassId ( void ) \ - { \ - return CLASS_##cls; \ - } \ - bool IsA( ClassId classId ) const \ - { \ - return ( ClassHierarchyBits & ( 1ULL << classId ) ) ? true : false; \ - } \ - const char* GetClassName ( void ) \ - { \ - return ClassName; \ - } \ - protected: \ - static const char* StaticGetClassName ( void ) \ - { \ - return #cls; \ - } \ - static ClassBits CalcClassHierarchyBits ( void ) \ - { \ - return ( 1ULL << GetClassId () ); \ - } \ - const char* ClassName; \ - ClassBits ClassHierarchyBits; \ - friend CAutoClassInit < cls >; \ - CAutoClassInit < cls > ClassInit; \ - public: \ - void* operator new ( size_t size ) { void* ptr = ::operator new(size); memset(ptr,0,size); return ptr; } \ - void* operator new ( size_t size, void* where ) { memset(where,0,size); return where; } +#define DECLARE_BASE_CLASS(cls) \ +public: \ + static ClassId GetClassId(void) \ + { \ + return CLASS_##cls; \ + } \ + bool IsA(ClassId classId) const \ + { \ + return (ClassHierarchyBits & (1ULL << classId)) ? true : false; \ + } \ + const char* GetClassName(void) \ + { \ + return ClassName; \ + } \ +\ +protected: \ + static const char* StaticGetClassName(void) \ + { \ + return #cls; \ + } \ + static ClassBits CalcClassHierarchyBits(void) \ + { \ + return (1ULL << GetClassId()); \ + } \ + const char* ClassName; \ + ClassBits ClassHierarchyBits; \ + friend CAutoClassInit; \ + CAutoClassInit ClassInit; \ +\ +public: \ + void* operator new(size_t size) \ + { \ + void* ptr = ::operator new(size); \ + memset(ptr, 0, size); \ + return ptr; \ + } \ + void* operator new(size_t size, void* where) \ + { \ + memset(where, 0, size); \ + return where; \ + } - #define DECLARE_CLASS(cls,super) \ - public: \ - static ClassId GetClassId ( void ) \ - { \ - return CLASS_##cls; \ - } \ - protected: \ - static const char* StaticGetClassName ( void ) \ - { \ - return #cls; \ - } \ - static ClassBits CalcClassHierarchyBits ( void ) \ - { \ - return ( 1ULL << GetClassId () ) | super::CalcClassHierarchyBits (); \ - } \ - friend CAutoClassInit < cls >; \ - CAutoClassInit < cls > ClassInit; \ - public: \ - typedef super Super; \ - void* operator new ( size_t size ) { void* ptr = ::operator new(size); memset(ptr,0,size); return ptr; } \ - void* operator new ( size_t size, void* where ) { memset(where,0,size); return where; } +#define DECLARE_CLASS(cls, super) \ +public: \ + static ClassId GetClassId(void) \ + { \ + return CLASS_##cls; \ + } \ +\ +protected: \ + static const char* StaticGetClassName(void) \ + { \ + return #cls; \ + } \ + static ClassBits CalcClassHierarchyBits(void) \ + { \ + return (1ULL << GetClassId()) | super::CalcClassHierarchyBits(); \ + } \ + friend CAutoClassInit; \ + CAutoClassInit ClassInit; \ +\ +public: \ + typedef super Super; \ + void* operator new(size_t size) \ + { \ + void* ptr = ::operator new(size); \ + memset(ptr, 0, size); \ + return ptr; \ + } \ + void* operator new(size_t size, void* where) \ + { \ + memset(where, 0, size); \ + return where; \ + } // // Auto init the class bit flags @@ -99,7 +121,7 @@ namespace SharedUtil return NULL; } - #ifdef WIN32 - #pragma warning( disable : 4355 ) // warning C4355: 'this' : used in base member initializer list - #endif -} // namespace SharedUtil +#ifdef WIN32 + #pragma warning(disable : 4355) // warning C4355: 'this' : used in base member initializer list +#endif +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.Crypto.h b/Shared/sdk/SharedUtil.Crypto.h index 29df819f530..21dd2b90dbb 100644 --- a/Shared/sdk/SharedUtil.Crypto.h +++ b/Shared/sdk/SharedUtil.Crypto.h @@ -8,6 +8,8 @@ * *****************************************************************************/ #pragma once + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 #include #include #include @@ -18,6 +20,8 @@ #include #include #include +#include +#include #include "SString.h" namespace SharedUtil @@ -174,19 +178,42 @@ namespace SharedUtil using namespace CryptoPP; using CryptoPP::byte; - AutoSeededRandomPool rnd; + // Use malloc to probe if allocation would succeed, bypassing MTA's custom OOM handler + // (which uses non-continuable SEH exceptions). Unlike new, malloc does not invoke _set_new_handler. + // Probe with 3x input size to cover: output buffer + Crypto++ internal buffers + StringSink allocations. + constexpr size_t kMaxProbeSize = SIZE_MAX / 3 - 256; + if (sData.size() > kMaxProbeSize) + return {SString(), SString()}; - SString result; - SString sIv; + void* probe = std::malloc(sData.size() * 3 + 256); + if (!probe) + return {SString(), SString()}; + std::free(probe); + + try + { + AutoSeededRandomPool rnd; + + SString result; + SString sIv; - sIv.resize(AES::BLOCKSIZE); - rnd.GenerateBlock((byte*)sIv.data(), sIv.size()); + // Pre-reserve output buffer - AES-CTR output size equals input size + // This avoids StringSink's doubling behavior on large inputs + result.reserve(sData.size()); - CTR_Mode::Encryption aesEncryption; - aesEncryption.SetKeyWithIV((byte*)sKey.data(), sKey.size(), (byte*)sIv.data()); - StringSource ss(sData, true, new StreamTransformationFilter(aesEncryption, new StringSink(result))); + sIv.resize(AES::BLOCKSIZE); + rnd.GenerateBlock((byte*)sIv.data(), sIv.size()); - return {result, sIv}; + CTR_Mode::Encryption aesEncryption; + aesEncryption.SetKeyWithIV((byte*)sKey.data(), sKey.size(), (byte*)sIv.data()); + StringSource ss(sData, true, new StreamTransformationFilter(aesEncryption, new StringSink(result))); + + return {result, sIv}; + } + catch (const std::exception&) + { + return {SString(), SString()}; + } } inline SString Aes128decode(const SString& sData, const SString& sKey, SString sIv) @@ -194,20 +221,43 @@ namespace SharedUtil using namespace CryptoPP; using CryptoPP::byte; - sIv.resize(AES::BLOCKSIZE); - SString result; + // Use malloc to probe if allocation would succeed, bypassing MTA's custom OOM handler + // (which uses non-continuable SEH exceptions). Unlike new, malloc does not invoke _set_new_handler. + // Probe with 3x input size to cover: output buffer + Crypto++ internal buffers + StringSink allocations. + constexpr size_t kMaxProbeSize = SIZE_MAX / 3 - 256; + if (sData.size() > kMaxProbeSize) + return SString(); - CTR_Mode::Decryption aesDecryption; - aesDecryption.SetKeyWithIV((byte*)sKey.data(), sKey.size(), (byte*)sIv.data()); - StringSource ss(sData, true, new StreamTransformationFilter(aesDecryption, new StringSink(result))); + void* probe = std::malloc(sData.size() * 3 + 256); + if (!probe) + return SString(); + std::free(probe); - return result; + try + { + sIv.resize(AES::BLOCKSIZE); + SString result; + + // Pre-reserve output buffer - AES-CTR output size equals input size + // This avoids StringSink's doubling behavior on large inputs + result.reserve(sData.size()); + + CTR_Mode::Decryption aesDecryption; + aesDecryption.SetKeyWithIV((byte*)sKey.data(), sKey.size(), (byte*)sIv.data()); + StringSource ss(sData, true, new StreamTransformationFilter(aesDecryption, new StringSink(result))); + + return result; + } + catch (const std::exception&) + { + return SString(); + } } inline bool StringToZLibFormat(const std::string& format, int& outResult) { int value = atoi(format.c_str()); - if ((value >= 9 && value <= 31) || (value >= -15 && value <= -9)) // allowed values: 9..31, -9..-15 + if ((value >= 9 && value <= 31) || (value >= -15 && value <= -9)) // allowed values: 9..31, -9..-15 { outResult = value; return true; @@ -224,7 +274,7 @@ namespace SharedUtil if (result != Z_OK) return result; - output.resize(deflateBound(&stream, input.size())); // resize to the upper bound of what the compressed size might be + output.resize(deflateBound(&stream, input.size())); // resize to the upper bound of what the compressed size might be stream.next_out = (Bytef*)output.data(); stream.avail_out = output.size(); @@ -236,14 +286,14 @@ namespace SharedUtil result |= deflateEnd(&stream); if (result == Z_STREAM_END) - output.resize(stream.total_out); // resize to the actual size + output.resize(stream.total_out); // resize to the actual size return result; } inline int ZLibUncompress(const std::string& input, std::string& output, int windowBits = 0) { - if (windowBits == 0 && input.size() >= 2) // try to determine format automatically + if (windowBits == 0 && input.size() >= 2) // try to determine format automatically { if (input[0] == '\x1F' && input[1] == '\x8B') windowBits = (int)ZLibFormat::GZIP; @@ -263,7 +313,7 @@ namespace SharedUtil // Uncompress in chunks std::string buffer; - buffer.resize(std::min(stream.avail_in, 128000U)); // use input length for chunk size (capped to 128k bytes which should be efficient enough) + buffer.resize(std::min(stream.avail_in, 128000U)); // use input length for chunk size (capped to 128k bytes which should be efficient enough) while (true) { stream.next_out = (Bytef*)buffer.data(); @@ -273,7 +323,7 @@ namespace SharedUtil if (result != Z_OK && result != Z_STREAM_END) break; - output.append(buffer, 0, stream.total_out - output.size()); // append only what was written to buffer + output.append(buffer, 0, stream.total_out - output.size()); // append only what was written to buffer if (result == Z_STREAM_END) break; @@ -282,4 +332,4 @@ namespace SharedUtil return result; } -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.Defines.h b/Shared/sdk/SharedUtil.Defines.h index ee7d13ca83f..f17c9347326 100644 --- a/Shared/sdk/SharedUtil.Defines.h +++ b/Shared/sdk/SharedUtil.Defines.h @@ -17,16 +17,16 @@ // Enable WITH_ALLOC_TRACKING to monitor server module memory usage. *Has a negative performance impact* #ifndef WITH_ALLOC_TRACKING #ifndef MTA_CLIENT - #define WITH_ALLOC_TRACKING 0 // Alloc track server - (Can also be defined in individual modules, just above #include "SharedUtil.h") + #define WITH_ALLOC_TRACKING 0 // Alloc track server - (Can also be defined in individual modules, just above #include "SharedUtil.h") #else - #define WITH_ALLOC_TRACKING 0 // Alloc track client - (Can also be defined in individual modules, just above #include "SharedUtil.h") + #define WITH_ALLOC_TRACKING 0 // Alloc track client - (Can also be defined in individual modules, just above #include "SharedUtil.h") #endif #endif // // Architecture // -#if defined( _M_X64 ) || defined( __x86_64__ ) || defined( _M_AMD64 ) || defined( __amd64__ ) +#if defined(_M_X64) || defined(__x86_64__) || defined(_M_AMD64) || defined(__amd64__) #define ANY_x64 #ifdef _WIN64 #define WIN_x64 @@ -81,39 +81,39 @@ // Location of server crash dumps // #ifdef WIN32 - #define SERVER_DUMP_PATH "dumps" + #define SERVER_DUMP_PATH "dumps" #else - #define SERVER_DUMP_PATH "mods/deathmatch/dumps" + #define SERVER_DUMP_PATH "mods/deathmatch/dumps" #endif // // vsnprintf with buffer full check // -#define VSNPRINTF( buffer, count, format, argptr ) \ +#define VSNPRINTF(buffer, count, format, argptr) \ { \ - int iResult = vsnprintf ( buffer, count, format, argptr ); \ - if( iResult == -1 || iResult == (count) ) \ - (buffer)[(count)-1] = 0; \ + int iResult = vsnprintf(buffer, count, format, argptr); \ + if (iResult == -1 || iResult == (count)) \ + (buffer)[(count) - 1] = 0; \ } // // strncpy with null termination // #ifndef STRNCPY - #define STRNCPY( dest, source, count ) \ + #define STRNCPY(dest, source, count) \ { \ - strncpy( dest, source, (count)-1 ); \ - (dest)[(count)-1] = 0; \ + strncpy(dest, source, (count) - 1); \ + (dest)[(count) - 1] = 0; \ } #endif // // Copy null terminated string to a temporary buffer on the stack // -#define COPY_CSTR_TO_TEMP_BUFFER( tempname, src, maxsize ) \ - char tempname [maxsize] = ""; \ - if ( src ) \ - STRNCPY( tempname, src, maxsize ); +#define COPY_CSTR_TO_TEMP_BUFFER(tempname, src, maxsize) \ + char tempname[maxsize] = ""; \ + if (src) \ + STRNCPY(tempname, src, maxsize); #ifndef _MSC_VER #define wcsicmp wcscasecmp @@ -122,15 +122,15 @@ // // Macro for counting the number of elements in a static array // -#ifndef NUMELMS // from DShow.h - #define NUMELMS(aa) (sizeof(aa)/sizeof((aa)[0])) +#ifndef NUMELMS // from DShow.h + #define NUMELMS(aa) (sizeof(aa) / sizeof((aa)[0])) #endif // // Stringize the result of expansion of a macro argument // #define MTA_STR_EXPAND(token) #token -#define MTA_STR(token) MTA_STR_EXPAND(token) +#define MTA_STR(token) MTA_STR_EXPAND(token) #ifdef WIN32 #define PATH_SEPERATOR "\\" @@ -140,31 +140,53 @@ // Auto clear a class when new'ed. (Won't work for inline creation.) #define ZERO_ON_NEW \ - void* operator new ( size_t size ) { void* ptr = ::operator new(size); memset(ptr == (void*)-1 ? 0 : ptr,0,size); return ptr; } \ - void* operator new ( size_t size, void* where ) { memset(where,0,size); return where; } + void* operator new(size_t size) \ + { \ + void* ptr = ::operator new(size); \ + memset(ptr == (void*)-1 ? 0 : ptr, 0, size); \ + return ptr; \ + } \ + void* operator new(size_t size, void* where) \ + { \ + memset(where, 0, size); \ + return where; \ + } // As NDEBUG is not defined across most MTA projects, assert() will always be enabled // Use dassert for debug build only assertations #if defined(MTA_DEBUG) || defined(DEBUG) || defined(_DEBUG) #define dassert assert #else - #define dassert(_Expression) ((void)0) + #define dassert(_Expression) ((void)0) #ifdef WIN32 // This, along with RedirectedSetUnhandledExceptionFilter means we can get reports from all crashes with the correct crash address in the file name #undef assert - #define assert(_Expression) (void)( (!!(_Expression)) || ( *((int*)NULL) = 0) ) + #define assert(_Expression) (void)((!!(_Expression)) || (*((int*)NULL) = 0)) #endif #endif -#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } -#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } +#define SAFE_DELETE(p) \ + { \ + if (p) \ + { \ + delete (p); \ + (p) = NULL; \ + } \ + } +#define SAFE_RELEASE(p) \ + { \ + if (p) \ + { \ + (p)->Release(); \ + (p) = NULL; \ + } \ + } #define PI (3.14159265358979323846f) // Clear all member variables to zero for a struct. // Note: Struct should have simple member variables and no virtual functions. -#define ZERO_POD_STRUCT(ptr) \ - memset ( ptr, 0, sizeof(*(ptr)) ) +#define ZERO_POD_STRUCT(ptr) memset(ptr, 0, sizeof(*(ptr))) #define BYTE_MASK(n) ((1 << (n)) - 1) @@ -181,40 +203,42 @@ // s char char wchar_t char // S wchar_t char char ???? // -#define PRSinS "%s" // i.e. SString ( "name:" PRSinS, "dave" ); -#define PRWinS "%ls" // i.e. SString ( "name:" PRWinS, L"dave" ); -#define PRWinW L"%ls" // i.e. WString ( L"name:" PRWinW, L"dave" ); +#define PRSinS "%s" // i.e. SString ( "name:" PRSinS, "dave" ); +#define PRWinS "%ls" // i.e. SString ( "name:" PRWinS, L"dave" ); +#define PRWinW L"%ls" // i.e. WString ( L"name:" PRWinW, L"dave" ); #ifdef _MSC_VER - #define PRSinW L"%S" // i.e. WString ( L"name:" PRSinW, "dave" ); + #define PRSinW L"%S" // i.e. WString ( L"name:" PRSinW, "dave" ); #else - #define PRSinW L"%s" // i.e. WString ( L"name:" PRSinW, "dave" ); + #define PRSinW L"%s" // i.e. WString ( L"name:" PRSinW, "dave" ); #endif // Generic way of showing a uchar index is not set #define UCHAR_INVALID_INDEX 0xFF // Tick count conversions -#define TICKS_FROM_SECONDS(m) ((m)*1000) -#define TICKS_FROM_MINUTES(m) (TICKS_FROM_SECONDS(m)*60) -#define TICKS_FROM_HOURS(m) (TICKS_FROM_MINUTES(m)*60) -#define TICKS_FROM_DAYS(m) (TICKS_FROM_HOURS(m)*24) +#define TICKS_FROM_SECONDS(m) ((m) * 1000) +#define TICKS_FROM_MINUTES(m) (TICKS_FROM_SECONDS(m) * 60) +#define TICKS_FROM_HOURS(m) (TICKS_FROM_MINUTES(m) * 60) +#define TICKS_FROM_DAYS(m) (TICKS_FROM_HOURS(m) * 24) // Export function #if defined _WIN32 #define MTAEXPORT extern "C" __declspec(dllexport) #else - #define MTAEXPORT extern "C" __attribute__ ((visibility ("default"))) + #define MTAEXPORT extern "C" __attribute__((visibility("default"))) #endif -#define BUILD_YEAR ((((__DATE__ [7]-'0')*10+(__DATE__ [8]-'0'))*10+(__DATE__ [9]-'0'))*10+(__DATE__ [10]-'0')) -#define BUILD_MONTH (__DATE__ [2] == 'n' ? (__DATE__ [1] == 'a' ? 0 : 5) \ - : __DATE__ [2] == 'b' ? 1 \ - : __DATE__ [2] == 'r' ? (__DATE__ [0] == 'M'? 2 : 3) \ - : __DATE__ [2] == 'y' ? 4 \ - : __DATE__ [2] == 'l' ? 6 \ - : __DATE__ [2] == 'g' ? 7 \ - : __DATE__ [2] == 'p' ? 8 \ - : __DATE__ [2] == 't' ? 9 \ - : __DATE__ [2] == 'v' ? 10 : 11) -#define BUILD_DAY ((__DATE__ [4]==' ' ? 0 : __DATE__[4]-'0')*10+(__DATE__[5]-'0')) +#define BUILD_YEAR ((((__DATE__[7] - '0') * 10 + (__DATE__[8] - '0')) * 10 + (__DATE__[9] - '0')) * 10 + (__DATE__[10] - '0')) +#define BUILD_MONTH \ + (__DATE__[2] == 'n' ? (__DATE__[1] == 'a' ? 0 : 5) \ + : __DATE__[2] == 'b' ? 1 \ + : __DATE__[2] == 'r' ? (__DATE__[0] == 'M' ? 2 : 3) \ + : __DATE__[2] == 'y' ? 4 \ + : __DATE__[2] == 'l' ? 6 \ + : __DATE__[2] == 'g' ? 7 \ + : __DATE__[2] == 'p' ? 8 \ + : __DATE__[2] == 't' ? 9 \ + : __DATE__[2] == 'v' ? 10 \ + : 11) +#define BUILD_DAY ((__DATE__[4] == ' ' ? 0 : __DATE__[4] - '0') * 10 + (__DATE__[5] - '0')) static constexpr float FLOAT_EPSILON = 0.0001f; diff --git a/Shared/sdk/SharedUtil.Detours.h b/Shared/sdk/SharedUtil.Detours.h index 9c40c748e2f..9041766dbfc 100644 --- a/Shared/sdk/SharedUtil.Detours.h +++ b/Shared/sdk/SharedUtil.Detours.h @@ -10,7 +10,7 @@ #pragma once #if defined(WIN32) -#include + #include namespace SharedUtil { @@ -44,6 +44,6 @@ namespace SharedUtil DetourDetach(&reinterpret_cast(target), replacement); return DetourTransactionCommit() == NO_ERROR; } -} // namespace SharedUtil +} // namespace SharedUtil #endif diff --git a/Shared/sdk/SharedUtil.FastHashMap.h b/Shared/sdk/SharedUtil.FastHashMap.h index e00b2577e77..a379c818569 100644 --- a/Shared/sdk/SharedUtil.FastHashMap.h +++ b/Shared/sdk/SharedUtil.FastHashMap.h @@ -16,16 +16,16 @@ #define CFastHashMap std::CMap #else -#ifdef WIN32 - #pragma push_macro("assert") -#endif + #ifdef WIN32 + #pragma push_macro("assert") + #endif -#include -#undef BASE_TEMPLATE_UTIL_H_ // HACK: Sparsehash and CEF share the same include guard name (NEVER USE MACROS AS INCLUDE GUARDS) + #include + #undef BASE_TEMPLATE_UTIL_H_ // HACK: Sparsehash and CEF share the same include guard name (NEVER USE MACROS AS INCLUDE GUARDS) -#ifdef WIN32 - #pragma pop_macro("assert") -#endif + #ifdef WIN32 + #pragma pop_macro("assert") + #endif // // Default keys for pointers @@ -136,7 +136,7 @@ namespace SharedUtil } return it->second; } -} // namespace SharedUtil +} // namespace SharedUtil inline SString GetEmptyMapKey(SString*) { diff --git a/Shared/sdk/SharedUtil.FastHashSet.h b/Shared/sdk/SharedUtil.FastHashSet.h index ba292f33e88..2d968e7f5bd 100644 --- a/Shared/sdk/SharedUtil.FastHashSet.h +++ b/Shared/sdk/SharedUtil.FastHashSet.h @@ -16,15 +16,15 @@ #define CFastHashSet std::CSet #else -#ifdef WIN32 - #pragma push_macro("assert") -#endif + #ifdef WIN32 + #pragma push_macro("assert") + #endif -#include + #include -#ifdef WIN32 - #pragma pop_macro("assert") -#endif + #ifdef WIN32 + #pragma pop_macro("assert") + #endif namespace SharedUtil { @@ -67,6 +67,6 @@ namespace SharedUtil return true; } -} // namespace SharedUtil +} // namespace SharedUtil #endif // WITH_ALLOC_TRACKING diff --git a/Shared/sdk/SharedUtil.File.h b/Shared/sdk/SharedUtil.File.h index bd462f9bbf0..6e3f20a0dfb 100644 --- a/Shared/sdk/SharedUtil.File.h +++ b/Shared/sdk/SharedUtil.File.h @@ -15,6 +15,13 @@ #include "SString.h" #include "WString.h" +#if defined(_WIN32) && defined(MTA_CLIENT) +// Workaround to prevent pulling in the fat windows.h header +// Callers that need WIN32_FILE_ATTRIBUTE_DATA as a value type must include after all. +struct _WIN32_FILE_ATTRIBUTE_DATA; +typedef struct _WIN32_FILE_ATTRIBUTE_DATA WIN32_FILE_ATTRIBUTE_DATA; +#endif + namespace SharedUtil { // @@ -30,6 +37,11 @@ namespace SharedUtil bool FileLoad(const SString& strFilename, SString& strBuffer, int iMaxSize = INT_MAX, int iOffset = 0); bool FileLoad(std::nothrow_t, const SString& filePath, SString& outBuffer, size_t maxSize = INT_MAX, size_t offset = 0) noexcept; +#if defined(_WIN32) && defined(MTA_CLIENT) + bool GetFileAttributesExWithTimeout(const wchar_t* path, WIN32_FILE_ATTRIBUTE_DATA& attr, unsigned long timeoutMs) noexcept; + bool FileLoadWithTimeout(const SString& filePath, SString& outBuffer, unsigned long timeoutMs) noexcept; +#endif + // // Save to a file // @@ -107,10 +119,15 @@ namespace SharedUtil namespace File { FILE* Fopen(const char* szFilename, const char* szMode); - int Mkdir(const char* szPath, int iMode = 0775); - int Chdir(const char* szPath); - int Rmdir(const char* szPath); - int Delete(const char* szFilename); - int Rename(const char* szOldFilename, const char* szNewFilename); - } // namespace File -} // namespace SharedUtil + FILE* FopenExclusive(const char* szFilename, const char* szMode); +#if defined(_WIN32) && defined(MTA_CLIENT) + FILE* TryFopen(const char* szFilename, const char* szMode); + FILE* TryFopenExclusive(const char* szFilename, const char* szMode); +#endif + int Mkdir(const char* szPath, int iMode = 0775); + int Chdir(const char* szPath); + int Rmdir(const char* szPath); + int Delete(const char* szFilename); + int Rename(const char* szOldFilename, const char* szNewFilename); + } // namespace File +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.File.hpp b/Shared/sdk/SharedUtil.File.hpp index 827358f7614..45c9936037d 100644 --- a/Shared/sdk/SharedUtil.File.hpp +++ b/Shared/sdk/SharedUtil.File.hpp @@ -8,22 +8,37 @@ * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ + +#ifndef _WIN32 + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif +#endif + #include "SharedUtil.File.h" #include "SharedUtil.Defines.h" #include "SharedUtil.IntTypes.h" #include "SharedUtil.Misc.h" #include "SharedUtil.Buffer.h" #include -#include +#include +#include +#include + +#if __cplusplus >= 201703L // C++17 + #include +#endif #ifdef _WIN32 #ifndef NOMINMAX - #define NOMINMAX + #define NOMINMAX #endif #include "Windows.h" #include "shellapi.h" #include "shlobj.h" #include + #include + #include #pragma comment(lib, "Shlwapi.lib") #else #include @@ -32,6 +47,14 @@ #include #endif +namespace SharedUtil +{ + namespace File + { + inline bool IsPathSafe(const char* filename) noexcept; + } +} + // // Returns true if the file exists // @@ -43,15 +66,29 @@ bool SharedUtil::FileExists(const std::string& strFilename) noexcept return fs::is_regular_file(strFilename.c_str(), errorCode); #else #ifdef _WIN32 - DWORD dwAtr = GetFileAttributes(strFilename.c_str()); - if (dwAtr == INVALID_FILE_ATTRIBUTES) + if (strFilename.empty()) return false; - return !(dwAtr & FILE_ATTRIBUTE_DIRECTORY); + + WString widePath; + try + { + widePath = FromUTF8(strFilename); + } + catch (...) + { + return false; + } + if (widePath.empty()) + return false; + DWORD attrs = GetFileAttributesW(widePath.c_str()); + if (attrs == INVALID_FILE_ATTRIBUTES) + return false; + return (attrs & FILE_ATTRIBUTE_DIRECTORY) == 0; #else struct stat s; - if (!stat(strFilename.c_str(), &s)) + if (stat(strFilename.c_str(), &s) != 0) return false; - return s.st_mode & S_IFREG; + return (s.st_mode & S_IFREG) != 0; #endif #endif } @@ -67,15 +104,29 @@ bool SharedUtil::DirectoryExists(const std::string& strPath) noexcept return fs::is_directory(strPath.c_str(), errorCode); #else #ifdef _WIN32 - DWORD dwAtr = GetFileAttributes(strPath.c_str()); - if (dwAtr == INVALID_FILE_ATTRIBUTES) + if (strPath.empty()) + return false; + + WString widePath; + try + { + widePath = FromUTF8(strPath); + } + catch (...) + { + return false; + } + if (widePath.empty()) + return false; + DWORD attrs = GetFileAttributesW(widePath.c_str()); + if (attrs == INVALID_FILE_ATTRIBUTES) return false; - return (dwAtr & FILE_ATTRIBUTE_DIRECTORY) != 0; + return (attrs & FILE_ATTRIBUTE_DIRECTORY) != 0; #else struct stat s; - if (!stat(strPath.c_str(), &s)) + if (stat(strPath.c_str(), &s) != 0) return false; - return s.st_mode & S_IFDIR; + return (s.st_mode & S_IFDIR) != 0; #endif #endif } @@ -96,6 +147,9 @@ bool SharedUtil::FileLoad(std::nothrow_t, const SString& filePath, SString& outB { outBuffer.clear(); + if (!File::IsPathSafe(filePath.c_str())) + return false; + constexpr unsigned int GIBIBYTE = 1 * 1024 * 1024 * 1024; if (offset > GIBIBYTE) @@ -108,7 +162,7 @@ bool SharedUtil::FileLoad(std::nothrow_t, const SString& filePath, SString& outB { wideFilePath = FromUTF8(filePath); } - catch (const std::bad_alloc&) + catch (...) { return false; } @@ -126,23 +180,57 @@ bool SharedUtil::FileLoad(std::nothrow_t, const SString& filePath, SString& outB if (fileSize == 0 || fileSize <= static_cast(offset)) return true; - HANDLE handle = CreateFileW(wideFilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + constexpr int MAX_RETRY_ATTEMPTS = 20; + constexpr int RETRY_DELAY_MS = 10; + + HANDLE handle = INVALID_HANDLE_VALUE; + for (int attempt = 0; attempt < MAX_RETRY_ATTEMPTS; ++attempt) + { + handle = CreateFileW(wideFilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (handle != INVALID_HANDLE_VALUE) + break; + + DWORD errorCode = GetLastError(); + if (errorCode != ERROR_SHARING_VIOLATION && errorCode != ERROR_LOCK_VIOLATION) + break; + + if (attempt + 1 < MAX_RETRY_ATTEMPTS) + Sleep(RETRY_DELAY_MS); + } if (handle == INVALID_HANDLE_VALUE) return false; + if (offset > 0) + { + LARGE_INTEGER seek{}; + seek.QuadPart = static_cast(offset); + if (!SetFilePointerEx(handle, seek, nullptr, FILE_BEGIN)) + { + CloseHandle(handle); + return false; + } + } + DWORD numBytesToRead = fileSize - static_cast(offset); if (static_cast(numBytesToRead) > maxSize) numBytesToRead = static_cast(maxSize); + if (numBytesToRead == 0) + { + CloseHandle(handle); + return true; + } + try { outBuffer.resize(static_cast(numBytesToRead)); } - catch (const std::bad_alloc&) + catch (...) { CloseHandle(handle); + outBuffer.clear(); return false; } @@ -151,23 +239,24 @@ bool SharedUtil::FileLoad(std::nothrow_t, const SString& filePath, SString& outB if (!ReadFile(handle, &outBuffer[0], numBytesToRead, &numBytesFromRead, nullptr) || numBytesFromRead != numBytesToRead) { CloseHandle(handle); + outBuffer.clear(); return false; } CloseHandle(handle); return true; #else -#ifdef __APPLE__ + #ifdef __APPLE__ struct stat info; if (stat(filePath, &info) != 0) return false; -#else + #else struct stat64 info; if (stat64(filePath, &info) != 0) return false; -#endif + #endif size_t fileSize = static_cast(info.st_size); @@ -182,24 +271,43 @@ bool SharedUtil::FileLoad(std::nothrow_t, const SString& filePath, SString& outB if (numBytesToRead > maxSize) numBytesToRead = maxSize; + FILE* handle = fopen(filePath, "rb"); + + if (!handle) + return false; + try { outBuffer.resize(numBytesToRead); } - catch (const std::bad_alloc&) + catch (...) { + fclose(handle); + outBuffer.clear(); return false; } - FILE* handle = fopen(filePath, "rb"); - - if (!handle) + #ifdef __APPLE__ + if (fseeko(handle, static_cast(offset), SEEK_SET) != 0) + #else + if (fseeko64(handle, static_cast(offset), SEEK_SET) != 0) + #endif + { + fclose(handle); + outBuffer.clear(); return false; + } - fseek(handle, static_cast(offset), SEEK_SET); size_t numBytesFromRead = fread(&outBuffer[0], 1, numBytesToRead, handle); fclose(handle); - return numBytesToRead == numBytesFromRead; + + if (numBytesFromRead != numBytesToRead) + { + outBuffer.clear(); + return false; + } + + return true; #endif } @@ -217,7 +325,7 @@ bool SharedUtil::FileDelete(const SString& strFilename, bool bForce) { #ifdef _WIN32 if (bForce) - SetFileAttributes(strFilename, FILE_ATTRIBUTE_NORMAL); + SetFileAttributesW(FromUTF8(strFilename), FILE_ATTRIBUTE_NORMAL); #endif return File::Delete(strFilename) == 0; } @@ -230,11 +338,12 @@ bool SharedUtil::FileRename(const SString& strFilenameOld, const SString& strFil int errorCode = GetLastError(); if (errorCode == ERROR_ACCESS_DENIED) { - // Try alternate rename strategy if (!FileExists(strFilenameNew) && FileCopy(strFilenameOld, strFilenameNew)) { FileDelete(strFilenameOld); - return true; + if (!FileExists(strFilenameOld)) + return true; + FileDelete(strFilenameNew); } } if (pOutErrorCode) @@ -259,29 +368,39 @@ bool SharedUtil::FileRename(const SString& strFilenameOld, const SString& strFil bool SharedUtil::FileLoad(const SString& strFilename, std::vector& buffer, int iMaxSize, int iOffset) { buffer.clear(); - // Open FILE* fh = File::Fopen(strFilename, "rb"); if (!fh) return false; - // Get size + fseek(fh, 0, SEEK_END); - int size = ftell(fh); +#ifdef _WIN32 + int64 rawSize = _ftelli64(fh); +#elif defined(__APPLE__) + int64 rawSize = ftello(fh); +#else + int64 rawSize = ftello64(fh); +#endif + int size = static_cast(std::min(INT_MAX, rawSize)); - // Set offset iOffset = std::min(iOffset, size); fseek(fh, iOffset, SEEK_SET); size -= iOffset; int bytesRead = 0; - if (size > 0 && size < 1e9) // 1GB limit + if (size > 0 && size < 1e9) { size = std::min(size, iMaxSize); - // Allocate space - buffer.assign(size, 0); - // Read into buffer + try + { + buffer.assign(size, 0); + } + catch (...) + { + fclose(fh); + return false; + } bytesRead = fread(&buffer.at(0), 1, size, fh); } - // Close fclose(fh); return bytesRead == size; } @@ -293,7 +412,7 @@ bool SharedUtil::FileSave(const SString& strFilename, const void* pBuffer, unsig { #ifdef _WIN32 if (bForce) - SetFileAttributes(strFilename, FILE_ATTRIBUTE_NORMAL); + SetFileAttributesW(FromUTF8(strFilename), FILE_ATTRIBUTE_NORMAL); #endif if (bForce) @@ -317,7 +436,7 @@ bool SharedUtil::FileAppend(const SString& strFilename, const void* pBuffer, uns { #ifdef _WIN32 if (bForce) - SetFileAttributes(strFilename, FILE_ATTRIBUTE_NORMAL); + SetFileAttributesW(FromUTF8(strFilename), FILE_ATTRIBUTE_NORMAL); #endif FILE* fh = File::Fopen(strFilename, "ab"); @@ -382,7 +501,7 @@ void SharedUtil::MakeSureDirExists(const SString& strPath) } #else std::filesystem::path filePath = static_cast(PathConform(strPath)); - std::error_code ec{}; + std::error_code ec{}; std::filesystem::create_directories(filePath.parent_path(), ec); #endif } @@ -398,7 +517,7 @@ SString SharedUtil::PathConform(const SString& strPath) // Remove slash duplicates size_t iFirstDoubleSlash = strTemp.find(PATH_SEPERATOR PATH_SEPERATOR); if (iFirstDoubleSlash == std::string::npos) - return strTemp; // No duplicates present + return strTemp; // No duplicates present // If first double slash is not at the start, then treat as a normal duplicate if: // 1. It is not preceeded by a colon, or @@ -464,7 +583,7 @@ SString SharedUtil::GetSystemCurrentDirectory() } #ifdef _WIN32 -#ifdef MTA_CLIENT + #ifdef MTA_CLIENT SString SharedUtil::GetSystemDllDirectory() { @@ -547,18 +666,93 @@ SString SharedUtil::GetMTATempPath() // C:\Program Files\gta_sa.exe SString SharedUtil::GetLaunchPathFilename() { - static SString strLaunchPathFilename; - if (strLaunchPathFilename.empty()) + struct LaunchPathFilenameHolder { - wchar_t szBuffer[2048]; - GetModuleFileNameW(NULL, szBuffer, NUMELMS(szBuffer) - 1); + SString strValue; - wchar_t fullPath[MAX_PATH]; - GetFullPathNameW(szBuffer, MAX_PATH, fullPath, nullptr); + LaunchPathFilenameHolder() + { + try + { + std::wstring wstrModulePath(512, L'\0'); + constexpr size_t MAX_PATH_LENGTH = 32768; - strLaunchPathFilename = ToUTF8(fullPath); - } - return strLaunchPathFilename; + for (;;) + { + DWORD dwBufferSize = static_cast(wstrModulePath.size()); + DWORD dwLength = GetModuleFileNameW(NULL, &wstrModulePath[0], dwBufferSize); + + if (dwLength == 0) + { + wstrModulePath.clear(); + break; + } + + if (dwLength < dwBufferSize) + { + wstrModulePath.resize(dwLength); + break; + } + + // dwLength == dwBufferSize means truncation or error + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + wstrModulePath.resize(dwLength); + break; + } + + // Buffer too small - grow it + if (wstrModulePath.size() >= MAX_PATH_LENGTH) + { + wstrModulePath.resize(dwLength); + break; + } + + size_t uiNextSize = wstrModulePath.size() * 2; + if (uiNextSize > MAX_PATH_LENGTH) + uiNextSize = MAX_PATH_LENGTH; + + wstrModulePath.resize(uiNextSize); + } + + // Convert to full path + if (!wstrModulePath.empty()) + { + DWORD dwNeeded = GetFullPathNameW(wstrModulePath.c_str(), 0, nullptr, nullptr); + if (dwNeeded > 0) + { + std::wstring wstrFullPath(dwNeeded, L'\0'); + DWORD dwWritten = GetFullPathNameW(wstrModulePath.c_str(), dwNeeded, &wstrFullPath[0], nullptr); + + if (dwWritten > 0) + { + wstrFullPath.resize(dwWritten); + strValue = ToUTF8(wstrFullPath); + } + else + { + strValue = ToUTF8(wstrModulePath); + } + } + else + { + strValue = ToUTF8(wstrModulePath); + } + } + else + { + strValue.clear(); + } + } + catch (...) + { + strValue.clear(); + } + } + }; + + static LaunchPathFilenameHolder holder; + return holder.strValue; } // C:\Program Files @@ -615,12 +809,12 @@ SString SharedUtil::GetDriveNameWithNotEnoughSpace(uint uiResourcesPathMinMB, ui return ""; } -#endif // #ifdef MTA_CLIENT -#endif // #ifdef _WIN32 + #endif // #ifdef MTA_CLIENT +#endif // #ifdef _WIN32 WString SharedUtil::FromUTF8(const SString& strPath) { -#ifdef WIN32_TESTING // This might be faster - Needs testing +#ifdef WIN32_TESTING // This might be faster - Needs testing const char* szSrc = strPath; uint cCharacters = strlen(szSrc) + 1; uint cbUnicode = cCharacters * 4; @@ -641,7 +835,7 @@ WString SharedUtil::FromUTF8(const SString& strPath) SString SharedUtil::ToUTF8(const WString& strPath) { -#ifdef WIN32_TESTING // This might be faster - Needs testing +#ifdef WIN32_TESTING // This might be faster - Needs testing const wchar_t* pszW = strPath; uint cCharacters = wcslen(pszW) + 1; uint cbAnsi = cCharacters * 6; @@ -684,7 +878,7 @@ bool SharedUtil::DelTree(const SString& strPath, const SString& strInsideHere) sfos.hwnd = NULL; sfos.wFunc = FO_DELETE; - sfos.pFrom = szBuffer; // Double NULL terminated + sfos.pFrom = szBuffer; // Double NULL terminated sfos.pTo = NULL; sfos.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT; @@ -722,7 +916,7 @@ bool SharedUtil::FileCopy(const SString& strSrc, const SString& strDest, bool bF #ifdef _WIN32 if (bForce) - SetFileAttributes(strDest, FILE_ATTRIBUTE_NORMAL); + SetFileAttributesW(FromUTF8(strDest), FILE_ATTRIBUTE_NORMAL); #endif FILE* fhSrc = File::Fopen(strSrc, "rb"); @@ -739,17 +933,26 @@ bool SharedUtil::FileCopy(const SString& strSrc, const SString& strDest, bool bF } char cBuffer[65536]; + bool ok = true; while (true) { size_t dataLength = fread(cBuffer, 1, 65536, fhSrc); if (dataLength == 0) + { + if (ferror(fhSrc)) + ok = false; + break; + } + if (fwrite(cBuffer, 1, dataLength, fhDst) != dataLength) + { + ok = false; break; - fwrite(cBuffer, 1, dataLength, fhDst); + } } fclose(fhSrc); fclose(fhDst); - return true; + return ok; } #ifdef _WIN32 @@ -771,20 +974,28 @@ std::vector SharedUtil::FindFiles(const SString& strInMatch, bool bFile strMatch += "*"; _WIN32_FIND_DATAW findData; - HANDLE hFind = FindFirstFileW(FromUTF8(strMatch), &findData); + HANDLE hFind = FindFirstFileW(FromUTF8(strMatch), &findData); if (hFind != INVALID_HANDLE_VALUE) { - do + try { - if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? bDirectories : bFiles) - if (wcscmp(findData.cFileName, L".") && wcscmp(findData.cFileName, L"..")) - { - if (bSortByDate) - MapInsert(sortMap, (uint64&)findData.ftLastWriteTime, ToUTF8(findData.cFileName)); - else - strResult.push_back(ToUTF8(findData.cFileName)); - } - } while (FindNextFileW(hFind, &findData)); + do + { + if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? bDirectories : bFiles) + if (wcscmp(findData.cFileName, L".") && wcscmp(findData.cFileName, L"..")) + { + if (bSortByDate) + MapInsert(sortMap, (uint64&)findData.ftLastWriteTime, ToUTF8(findData.cFileName)); + else + strResult.push_back(ToUTF8(findData.cFileName)); + } + } while (FindNextFileW(hFind, &findData)); + } + catch (...) + { + FindClose(hFind); + throw; + } FindClose(hFind); } @@ -927,7 +1138,7 @@ SString SharedUtil::MakeUniquePath(const SString& strInPathFilename) SString strTest = strPathFilename; int iCount = 1; #ifdef _WIN32 - while (GetFileAttributes(strTest) != INVALID_FILE_ATTRIBUTES) + while (GetFileAttributesW(FromUTF8(strTest)) != INVALID_FILE_ATTRIBUTES) #else while (DirectoryExists(strTest) || FileExists(strTest)) #endif @@ -975,12 +1186,14 @@ SString SharedUtil::MakeGenericPath(const SString& uniqueFilePath) SString SharedUtil::ConformPathForSorting(const SString& strPathFilename) { SString strResult = strPathFilename; - std::transform(strResult.begin(), strResult.end(), strResult.begin(), [](int c) { - // Ignores locale and always does this: - if (c >= 'A' && c <= 'Z') - c = c - 'A' + 'a'; - return c; - }); + std::transform(strResult.begin(), strResult.end(), strResult.begin(), + [](int c) + { + // Ignores locale and always does this: + if (c >= 'A' && c <= 'Z') + c = c - 'A' + 'a'; + return c; + }); return strResult; } @@ -1026,16 +1239,402 @@ SString SharedUtil::GetSystemLongPathName(const SString& strPath) return strPath; return ToUTF8(szBuffer); } -#endif // _WIN32 +#endif // _WIN32 -FILE* SharedUtil::File::Fopen(const char* szFilename, const char* szMode) +namespace SharedUtil { + namespace File + { #ifdef _WIN32 - return _wfsopen(FromUTF8(szFilename), FromUTF8(szMode), _SH_DENYNO); + inline bool IsReservedName(const char* path) noexcept + { + const char* name = path; + for (const char* p = path; *p; ++p) + { + if (*p == '\\' || *p == '/') + name = p + 1; + } + + std::size_t len = 0; + while (name[len] && name[len] != '.' && name[len] != ':') + ++len; + + while (len > 0 && (name[len - 1] == ' ' || name[len - 1] == '.')) + --len; + + auto up = [](char c) noexcept -> char { return (c >= 'a' && c <= 'z') ? static_cast(c - 'a' + 'A') : c; }; + + if (len == 3) + { + char a = up(name[0]), b = up(name[1]), c = up(name[2]); + return (a == 'C' && b == 'O' && c == 'N') || (a == 'P' && b == 'R' && c == 'N') || (a == 'A' && b == 'U' && c == 'X') || + (a == 'N' && b == 'U' && c == 'L'); + } + if (len == 4 && name[3] >= '1' && name[3] <= '9') + { + char a = up(name[0]), b = up(name[1]), c = up(name[2]); + return (a == 'C' && b == 'O' && c == 'M') || (a == 'L' && b == 'P' && c == 'T'); + } + if (len == 6 && name[5] == '$') + { + char a = up(name[0]), b = up(name[1]), c = up(name[2]); + char d = up(name[3]), e = up(name[4]); + return a == 'C' && b == 'O' && c == 'N' && d == 'I' && e == 'N'; + } + if (len == 7 && name[6] == '$') + { + char a = up(name[0]), b = up(name[1]), c = up(name[2]); + char d = up(name[3]), e = up(name[4]), f = up(name[5]); + return a == 'C' && b == 'O' && c == 'N' && d == 'O' && e == 'U' && f == 'T'; + } + return false; + } +#endif + + inline bool IsPathSafe(const char* filename) noexcept + { + if (!filename || !*filename) + return false; + + constexpr std::size_t maxPathLen = 4'096; + if (std::strlen(filename) > maxPathLen) + return false; + + const auto isSeparator = [](char c) noexcept { return c == '\\' || c == '/'; }; + for (const char* p = filename; *p; ++p) + { + if (p[0] == '.' && p[1] == '.' && (p == filename || isSeparator(p[-1])) && (p[2] == '\0' || isSeparator(p[2]))) + return false; + } + +#ifdef _WIN32 + const auto* colonPos = std::strchr(filename, ':'); + if (colonPos) + { + const bool isDriveLetter = (colonPos == filename + 1) && std::isalpha(static_cast(filename[0])); + if (!isDriveLetter || std::strchr(colonPos + 1, ':')) + return false; + } + + if (isSeparator(filename[0]) && isSeparator(filename[1]) && (filename[2] == '.' || filename[2] == '?') && isSeparator(filename[3])) + return false; + + if (filename[0] == '\\' && filename[1] == '?' && filename[2] == '?' && filename[3] == '\\') + return false; + + if (IsReservedName(filename)) + return false; +#endif + return true; + } + } +} + +#if defined(_WIN32) && defined(MTA_CLIENT) +FILE* SharedUtil::File::TryFopen(const char* filename, const char* mode) +{ + if (!filename || !mode || !*filename || !*mode) + return errno = EINVAL, nullptr; + + if (!IsPathSafe(filename)) + return errno = EINVAL, nullptr; + + constexpr std::size_t maxModeLen = 3; + if (std::strlen(mode) > maxModeLen) + return errno = EINVAL, nullptr; + + const auto baseMode = mode[0]; + if (baseMode != 'r' && baseMode != 'w' && baseMode != 'a') + return errno = EINVAL, nullptr; + + auto hasPlus = false; + auto hasBT = false; + auto isBinary = false; + for (std::size_t i = 1; mode[i] != '\0'; ++i) + { + switch (mode[i]) + { + case '+': + if (hasPlus) + return errno = EINVAL, nullptr; + hasPlus = true; + break; + case 'b': + if (hasBT) + return errno = EINVAL, nullptr; + hasBT = true; + isBinary = true; + break; + case 't': + if (hasBT) + return errno = EINVAL, nullptr; + hasBT = true; + break; + default: + return errno = EINVAL, nullptr; + } + } + + char normalizedMode[4]; + std::size_t modePos = 0; + normalizedMode[modePos++] = baseMode; + if (hasPlus) + normalizedMode[modePos++] = '+'; + if (isBinary) + normalizedMode[modePos++] = 'b'; + normalizedMode[modePos] = '\0'; + + DWORD accessFlags{}, creationMode{}; + int osFlags{}; + switch (baseMode) + { + case 'r': + accessFlags = hasPlus ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_READ; + creationMode = OPEN_EXISTING; + osFlags = hasPlus ? _O_RDWR : _O_RDONLY; + break; + case 'w': + accessFlags = hasPlus ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_WRITE; + creationMode = CREATE_ALWAYS; + osFlags = (hasPlus ? _O_RDWR : _O_WRONLY) | _O_CREAT | _O_TRUNC; + break; + case 'a': + accessFlags = hasPlus ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_WRITE; + creationMode = OPEN_ALWAYS; + osFlags = (hasPlus ? _O_RDWR : _O_WRONLY) | _O_CREAT | _O_APPEND; + break; + } + osFlags |= isBinary ? _O_BINARY : _O_TEXT; + + WString wideFilename; + try + { + wideFilename = FromUTF8(filename); + } + catch (...) + { + return errno = EINVAL, nullptr; + } + if (wideFilename.empty()) + return errno = EINVAL, nullptr; + + const auto fileHandle = CreateFileW(wideFilename.c_str(), accessFlags, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, creationMode, + FILE_ATTRIBUTE_NORMAL, nullptr); + if (fileHandle == INVALID_HANDLE_VALUE) + { + const auto errorCode = GetLastError(); + switch (errorCode) + { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + errno = ENOENT; + break; + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + case ERROR_LOCK_VIOLATION: + errno = EACCES; + break; + case ERROR_INVALID_NAME: + case ERROR_BAD_PATHNAME: + errno = EINVAL; + break; + case ERROR_FILE_EXISTS: + case ERROR_ALREADY_EXISTS: + errno = EEXIST; + break; + case ERROR_DISK_FULL: + case ERROR_HANDLE_DISK_FULL: + errno = ENOSPC; + break; + case ERROR_TOO_MANY_OPEN_FILES: + errno = EMFILE; + break; + case ERROR_WRITE_PROTECT: + errno = EROFS; + break; + case ERROR_NOT_READY: + errno = ENXIO; + break; + case ERROR_INVALID_DRIVE: + errno = ENODEV; + break; + default: + errno = EIO; + break; + } + return nullptr; + } + + if (GetFileType(fileHandle) != FILE_TYPE_DISK) + { + CloseHandle(fileHandle); + return errno = EACCES, nullptr; + } + + { + wchar_t finalPath[1024]; + DWORD pathLen = GetFinalPathNameByHandleW(fileHandle, finalPath, 1024, FILE_NAME_NORMALIZED); + if (pathLen > 0 && pathLen < 1024 && pathLen >= 8 && finalPath[0] == L'\\' && finalPath[1] == L'\\' && finalPath[2] == L'?' && finalPath[3] == L'\\' && + (finalPath[4] == L'U' || finalPath[4] == L'u') && (finalPath[5] == L'N' || finalPath[5] == L'n') && + (finalPath[6] == L'C' || finalPath[6] == L'c') && finalPath[7] == L'\\') + { + CloseHandle(fileHandle); + return errno = EACCES, nullptr; + } + } + + const auto fileDescriptor = _open_osfhandle(reinterpret_cast(fileHandle), osFlags); + if (fileDescriptor == -1) + { + const auto savedErrno = errno; + CloseHandle(fileHandle); + return errno = savedErrno, nullptr; + } + + auto* fileStream = _fdopen(fileDescriptor, normalizedMode); + if (!fileStream) + { + const auto savedErrno = errno; + _close(fileDescriptor); + return errno = savedErrno, nullptr; + } + return fileStream; +} + +FILE* SharedUtil::File::TryFopenExclusive(const char* filename, const char* mode) +{ + if (!filename || !mode || !*filename || !*mode) + return errno = EINVAL, nullptr; + + if (!IsPathSafe(filename)) + return errno = EINVAL, nullptr; + + if (mode[0] != 'r' || (mode[1] != 'b' && mode[1] != '\0') || (mode[1] == 'b' && mode[2] != '\0')) + return errno = EINVAL, nullptr; + + WString wideFilename; + try + { + wideFilename = FromUTF8(filename); + } + catch (...) + { + return errno = EINVAL, nullptr; + } + if (wideFilename.empty()) + return errno = EINVAL, nullptr; + + const auto fileHandle = CreateFileW(wideFilename.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + if (fileHandle == INVALID_HANDLE_VALUE) + { + const auto errorCode = GetLastError(); + switch (errorCode) + { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + errno = ENOENT; + break; + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + case ERROR_LOCK_VIOLATION: + errno = EACCES; + break; + case ERROR_INVALID_NAME: + case ERROR_BAD_PATHNAME: + errno = EINVAL; + break; + case ERROR_TOO_MANY_OPEN_FILES: + errno = EMFILE; + break; + default: + errno = EIO; + break; + } + return nullptr; + } + + if (GetFileType(fileHandle) != FILE_TYPE_DISK) + { + CloseHandle(fileHandle); + return errno = EACCES, nullptr; + } + + { + wchar_t finalPath[1024]; + DWORD pathLen = GetFinalPathNameByHandleW(fileHandle, finalPath, 1024, FILE_NAME_NORMALIZED); + if (pathLen > 0 && pathLen < 1024 && pathLen >= 8 && finalPath[0] == L'\\' && finalPath[1] == L'\\' && finalPath[2] == L'?' && finalPath[3] == L'\\' && + (finalPath[4] == L'U' || finalPath[4] == L'u') && (finalPath[5] == L'N' || finalPath[5] == L'n') && + (finalPath[6] == L'C' || finalPath[6] == L'c') && finalPath[7] == L'\\') + { + CloseHandle(fileHandle); + return errno = EACCES, nullptr; + } + } + + const int osFlags = (mode[1] == 'b') ? (_O_RDONLY | _O_BINARY) : _O_RDONLY; + const auto fileDescriptor = _open_osfhandle(reinterpret_cast(fileHandle), osFlags); + if (fileDescriptor == -1) + { + const auto savedErrno = errno; + CloseHandle(fileHandle); + return errno = savedErrno, nullptr; + } + + auto* fileStream = _fdopen(fileDescriptor, mode); + if (!fileStream) + { + const auto savedErrno = errno; + _close(fileDescriptor); + return errno = savedErrno, nullptr; + } + return fileStream; +} + +FILE* SharedUtil::File::Fopen(const char* szFilename, const char* szMode) +{ + return TryFopen(szFilename, szMode); +} + +FILE* SharedUtil::File::FopenExclusive(const char* szFilename, const char* szMode) +{ + return TryFopenExclusive(szFilename, szMode); +} + #else +FILE* SharedUtil::File::Fopen(const char* szFilename, const char* szMode) +{ + #ifdef _WIN32 + try + { + return _wfsopen(FromUTF8(szFilename), FromUTF8(szMode), _SH_DENYNO); + } + catch (...) + { + errno = EINVAL; + return nullptr; + } + #else return fopen(szFilename, szMode); -#endif + #endif +} + +FILE* SharedUtil::File::FopenExclusive(const char* szFilename, const char* szMode) +{ + #ifdef _WIN32 + try + { + return _wfsopen(FromUTF8(szFilename), FromUTF8(szMode), _SH_DENYWR); + } + catch (...) + { + errno = EINVAL; + return nullptr; + } + #else + return fopen(szFilename, szMode); + #endif } +#endif int SharedUtil::File::Mkdir(const char* szPath, int iMode) { @@ -1098,26 +1697,49 @@ std::vector SharedUtil::ListDir(const char* szPath) noexcept entries.push_back(entry.path().filename().string()); } } - catch (...) {} // catch all possible errors and ignore them + catch (...) + { + } // catch all possible errors and ignore them #else #ifdef _WIN32 std::string search_path = szPath; if (search_path.empty()) return {}; - if (search_path.back() != '/') + char lastChar = search_path.back(); + if (lastChar == '/' || lastChar == '\\') + search_path += '*'; + else search_path += "/*"; - WIN32_FIND_DATA fd; - HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd); - if (hFind == INVALID_HANDLE_VALUE) - return {}; + try + { + WString wideSearchPath = FromUTF8(search_path); + WIN32_FIND_DATAW fd; + HANDLE hFind = ::FindFirstFileW(wideSearchPath.c_str(), &fd); - do + if (hFind != INVALID_HANDLE_VALUE) + { + try + { + do + { + entries.push_back(ToUTF8(fd.cFileName)); + } while (::FindNextFileW(hFind, &fd)); + } + catch (...) + { + ::FindClose(hFind); + throw; + } + ::FindClose(hFind); + } + return entries; + } + catch (...) { - entries.push_back(fd.cFileName); - } while (::FindNextFile(hFind, &fd)); - ::FindClose(hFind); + return {}; + } #else DIR* dir; @@ -1125,9 +1747,17 @@ std::vector SharedUtil::ListDir(const char* szPath) noexcept if (!(dir = opendir(szPath))) return {}; - while ((ent = readdir(dir))) + try { - entries.push_back(ent->d_name); + while ((ent = readdir(dir))) + { + entries.push_back(ent->d_name); + } + } + catch (...) + { + closedir(dir); + return {}; } closedir(dir); #endif @@ -1135,3 +1765,148 @@ std::vector SharedUtil::ListDir(const char* szPath) noexcept return entries; } +#if defined(_WIN32) && defined(MTA_CLIENT) +namespace +{ + // Helper to call GetFileAttributesExW with timeout to prevent indefinite hangs due to env issues + struct GetAttributesParams + { + wchar_t* pathCopy; + WIN32_FILE_ATTRIBUTE_DATA attrLocal; + BOOL result; + std::atomic abandoned; + }; + + DWORD WINAPI GetAttributesThread(LPVOID param) + { + auto* p = static_cast(param); + p->result = GetFileAttributesExW(p->pathCopy, GetFileExInfoStandard, &p->attrLocal); + if (p->abandoned.load(std::memory_order_acquire)) + { + delete[] p->pathCopy; + delete p; + } + return 0; + } +} + +bool SharedUtil::GetFileAttributesExWithTimeout(const wchar_t* path, WIN32_FILE_ATTRIBUTE_DATA& attr, DWORD timeoutMs) noexcept +{ + size_t pathLen = wcslen(path) + 1; + wchar_t* pathCopy = new (std::nothrow) wchar_t[pathLen]; + if (!pathCopy) + return false; + + #ifdef _MSC_VER + wcscpy_s(pathCopy, pathLen, path); + #else + wcscpy(pathCopy, path); + #endif + + auto* params = new (std::nothrow) GetAttributesParams{pathCopy, {}, FALSE, {false}}; + if (!params) + { + delete[] pathCopy; + return false; + } + + DWORD threadId; + HANDLE thread = CreateThread(nullptr, 0, GetAttributesThread, params, 0, &threadId); + if (!thread) + { + delete[] params->pathCopy; + delete params; + return false; + } + + DWORD waitResult = WaitForSingleObject(thread, timeoutMs); + + if (waitResult == WAIT_OBJECT_0) + { + CloseHandle(thread); + attr = params->attrLocal; + bool success = params->result != FALSE; + delete[] params->pathCopy; + delete params; + return success; + } + + // Timeout - let the worker thread clean up when it finishes + params->abandoned.store(true, std::memory_order_release); + CloseHandle(thread); + return false; +} + +bool SharedUtil::FileLoadWithTimeout(const SString& filePath, SString& outBuffer, DWORD timeoutMs) noexcept +{ + outBuffer.clear(); + + if (!File::IsPathSafe(filePath.c_str())) + return false; + + WString wideFilePath; + try + { + wideFilePath = FromUTF8(filePath); + } + catch (...) + { + return false; + } + + if (wideFilePath.empty()) + return false; + + WIN32_FILE_ATTRIBUTE_DATA attr; + if (!GetFileAttributesExWithTimeout(wideFilePath.c_str(), attr, timeoutMs) || attr.nFileSizeHigh > 0) + return false; + + DWORD fileSize = attr.nFileSizeLow; + if (fileSize == 0) + return true; + + HANDLE fh = CreateFileW(wideFilePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr); + if (fh == INVALID_HANDLE_VALUE) + return false; + + HANDLE ev = CreateEventW(nullptr, TRUE, FALSE, nullptr); + if (!ev) + { + CloseHandle(fh); + return false; + } + + bool ok = false; + try + { + outBuffer.resize(fileSize); + } + catch (...) + { + goto done; + } + + { + OVERLAPPED ov{}; + ov.hEvent = ev; + DWORD n = 0; + if (!ReadFile(fh, &outBuffer[0], fileSize, &n, &ov) && GetLastError() == ERROR_IO_PENDING) + { + if (WaitForSingleObject(ev, timeoutMs) != WAIT_OBJECT_0) + { + CancelIo(fh); + GetOverlappedResult(fh, &ov, &n, TRUE); + goto done; + } + } + ok = GetOverlappedResult(fh, &ov, &n, FALSE) && n == fileSize; + } +done: + CloseHandle(ev); + CloseHandle(fh); + if (!ok) + outBuffer.clear(); + return ok; +} +#endif diff --git a/Shared/sdk/SharedUtil.Game.h b/Shared/sdk/SharedUtil.Game.h index 95e5cf17b36..a2632459a5e 100644 --- a/Shared/sdk/SharedUtil.Game.h +++ b/Shared/sdk/SharedUtil.Game.h @@ -29,7 +29,7 @@ namespace SharedUtil AUTO, DISABLED, }; - } // namespace TrafficLight + } // namespace TrafficLight unsigned char GetTrafficLightStateFromColors(TrafficLight::EColor eColorNS, TrafficLight::EColor eColorEW); @@ -79,14 +79,14 @@ namespace SharedUtil { } - uchar ucIntensity; // 0 to 255 - uchar ucRandomShift; // 0 to 255 - ushort usSpeedMin; // 0 to 1000 - ushort usSpeedMax; // 0 to 1000 - short sScanSizeX; // -1000 to 1000 - short sScanSizeY; // -1000 to 1000 - ushort usRenderSizeX; // 0 to 1000 - ushort usRenderSizeY; // 0 to 1000 + uchar ucIntensity; // 0 to 255 + uchar ucRandomShift; // 0 to 255 + ushort usSpeedMin; // 0 to 1000 + ushort usSpeedMax; // 0 to 1000 + short sScanSizeX; // -1000 to 1000 + short sScanSizeY; // -1000 to 1000 + ushort usRenderSizeX; // 0 to 1000 + ushort usRenderSizeY; // 0 to 1000 bool bInsideBuilding; }; @@ -109,27 +109,27 @@ namespace SharedUtil using EDiagnosticDebug::EDiagnosticDebugType; - // Common strings for SetApplicationSetting - #define DIAG_PRELOAD_UPGRADES_SLOW "diagnostics", "preloading-upgrades-slow" - #define DIAG_PRELOAD_UPGRADE_ATTEMPT_ID "diagnostics", "preloading-upgrade-attempt-id" - #define DIAG_PRELOAD_UPGRADES_LOWEST_UNSAFE "diagnostics", "preloading-upgrades-lowest-unsafe" - #define DIAG_PRELOAD_UPGRADES_HISCORE "diagnostics", "preloading-upgrades-hiscore" - #define DIAG_CRASH_EXTRA_MSG "diagnostics", "last-crash-reason" - #define DIAG_MINIDUMP_DETECTED_COUNT "diagnostics", "num-minidump-detected" - #define DIAG_MINIDUMP_CONFIRMED_COUNT "diagnostics", "num-minidump-confirmed" - #define DIAG_BSOD_DETECT_SKIP "diagnostics", "bsod-detect-skip" - #define GENERAL_PROGRESS_ANIMATION_DISABLE "progress-animation-disable" - - // Common strings for watchdog detections - #define WD_SECTION_PRELOAD_UPGRADES "preload-upgrades" - #define WD_SECTION_NOT_CLEAN_GTA_EXIT "L0" // Opened in loader, closed if GTA exits with no error - #define WD_SECTION_NOT_STARTED_ONLINE_GAME "L1" // Opened in loader, closed when online game has started - #define WD_SECTION_NOT_SHOWN_LOADING_SCREEN "L2" // Opened in loader, closed when loading screen is shown - #define WD_SECTION_STARTUP_FREEZE "L3" // Opened in loader, closed when loading screen is shown, or a startup problem is handled elsewhere - #define WD_SECTION_NOT_USED_MAIN_MENU "L4" // Opened in loader, closed when main menu is used - #define WD_SECTION_POST_INSTALL "L5" // Opened in when installer runs, closed when main menu is used - #define WD_SECTION_IS_QUITTING "Q0" // Open during quit - #define WD_COUNTER_CRASH_CHAIN_BEFORE_ONLINE_GAME "CR1" // Counts consecutive crashes before the online game starts - #define WD_COUNTER_CRASH_CHAIN_BEFORE_LOADING_SCREEN "CR2" // Counts consecutive crashes before the loading screen is shown - #define WD_COUNTER_CRASH_CHAIN_BEFORE_USED_MAIN_MENU "CR3" // Counts consecutive crashes before the main menu is used -} // namespace SharedUtil +// Common strings for SetApplicationSetting +#define DIAG_PRELOAD_UPGRADES_SLOW "diagnostics", "preloading-upgrades-slow" +#define DIAG_PRELOAD_UPGRADE_ATTEMPT_ID "diagnostics", "preloading-upgrade-attempt-id" +#define DIAG_PRELOAD_UPGRADES_LOWEST_UNSAFE "diagnostics", "preloading-upgrades-lowest-unsafe" +#define DIAG_PRELOAD_UPGRADES_HISCORE "diagnostics", "preloading-upgrades-hiscore" +#define DIAG_CRASH_EXTRA_MSG "diagnostics", "last-crash-reason" +#define DIAG_MINIDUMP_DETECTED_COUNT "diagnostics", "num-minidump-detected" +#define DIAG_MINIDUMP_CONFIRMED_COUNT "diagnostics", "num-minidump-confirmed" +#define DIAG_BSOD_DETECT_SKIP "diagnostics", "bsod-detect-skip" +#define GENERAL_PROGRESS_ANIMATION_DISABLE "progress-animation-disable" + +// Common strings for watchdog detections +#define WD_SECTION_PRELOAD_UPGRADES "preload-upgrades" +#define WD_SECTION_NOT_CLEAN_GTA_EXIT "L0" // Opened in loader, closed if GTA exits with no error +#define WD_SECTION_NOT_STARTED_ONLINE_GAME "L1" // Opened in loader, closed when online game has started +#define WD_SECTION_NOT_SHOWN_LOADING_SCREEN "L2" // Opened in loader, closed when loading screen is shown +#define WD_SECTION_STARTUP_FREEZE "L3" // Opened in loader, closed when loading screen is shown, or a startup problem is handled elsewhere +#define WD_SECTION_NOT_USED_MAIN_MENU "L4" // Opened in loader, closed when main menu is used +#define WD_SECTION_POST_INSTALL "L5" // Opened in when installer runs, closed when main menu is used +#define WD_SECTION_IS_QUITTING "Q0" // Open during quit +#define WD_COUNTER_CRASH_CHAIN_BEFORE_ONLINE_GAME "CR1" // Counts consecutive crashes before the online game starts +#define WD_COUNTER_CRASH_CHAIN_BEFORE_LOADING_SCREEN "CR2" // Counts consecutive crashes before the loading screen is shown +#define WD_COUNTER_CRASH_CHAIN_BEFORE_USED_MAIN_MENU "CR3" // Counts consecutive crashes before the main menu is used +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.Game.hpp b/Shared/sdk/SharedUtil.Game.hpp index 42c361a787a..ce1149da491 100644 --- a/Shared/sdk/SharedUtil.Game.hpp +++ b/Shared/sdk/SharedUtil.Game.hpp @@ -76,7 +76,7 @@ namespace SharedUtil CVehicleColor::CVehicleColor() { // Init - m_ucPaletteColors[0] = 0; // Palette color 0 is black + m_ucPaletteColors[0] = 0; // Palette color 0 is black m_ucPaletteColors[1] = 0; m_ucPaletteColors[2] = 0; m_ucPaletteColors[3] = 0; @@ -238,7 +238,7 @@ namespace SharedUtil if (ulDist < ulBestDist) { ulBestDist = ulDist; - ucBestMatch = i; + ucBestMatch = static_cast(i); } } return ucBestMatch; @@ -246,11 +246,11 @@ namespace SharedUtil SColor CVehicleColor::GetRGBFromPaletteIndex(uchar ucColor) { - ucColor = std::min(ucColor, static_cast(NUMELMS(paletteColorTable8) / 4)); + ucColor = std::min(ucColor, static_cast(NUMELMS(paletteColorTable8) / 4)); uchar r = paletteColorTable8[ucColor * 4]; uchar g = paletteColorTable8[ucColor * 4 + 1]; uchar b = paletteColorTable8[ucColor * 4 + 2]; return SColorRGBA(r, g, b, 0); } -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.Hash.h b/Shared/sdk/SharedUtil.Hash.h index b1d65ad5410..79fc0d9bdfc 100644 --- a/Shared/sdk/SharedUtil.Hash.h +++ b/Shared/sdk/SharedUtil.Hash.h @@ -154,4 +154,4 @@ namespace SharedUtil SString GenerateHashHexString(EHashFunctionType hashFunction, const void* pData, uint uiLength); SString GenerateHashHexString(EHashFunctionType hashFunction, const SString& strData); SString GenerateHashHexStringFromFile(EHashFunctionType hashFunction, const SString& strFilename, int iMaxSize = INT_MAX, int iOffset = 0); -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.Hash.hpp b/Shared/sdk/SharedUtil.Hash.hpp index b38cf11037f..f5632208d7c 100644 --- a/Shared/sdk/SharedUtil.Hash.hpp +++ b/Shared/sdk/SharedUtil.Hash.hpp @@ -13,6 +13,10 @@ #include "sha2.hpp" #include #include +#include +#include +#include +#include #include "SharedUtil.Hash.h" #include "SharedUtil.File.h" @@ -20,64 +24,71 @@ namespace bcrypt { extern "C" { - #include +#include } -} // namespace bcrypt +} // namespace bcrypt namespace SharedUtil { - #define S11 7 - #define S12 12 - #define S13 17 - #define S14 22 - #define S21 5 - #define S22 9 - #define S23 14 - #define S24 20 - #define S31 4 - #define S32 11 - #define S33 16 - #define S34 23 - #define S41 6 - #define S42 10 - #define S43 15 - #define S44 21 - - CMD5Hasher::CMD5Hasher() {} - - CMD5Hasher::~CMD5Hasher() {} +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + + CMD5Hasher::CMD5Hasher() + { + } + + CMD5Hasher::~CMD5Hasher() + { + } bool CMD5Hasher::Calculate(const char* szFilename, MD5& md5Result) { - // CRYPT_START - // Try to load the file - FILE* pFile = File::Fopen(szFilename, "rb"); + FILE* pFile = File::FopenExclusive(szFilename, "rb"); if (pFile) { - // Init Init(); - // Hash it - unsigned char Buffer[65536]; - while (unsigned int uiRead = static_cast(fread(Buffer, 1, 65536, pFile))) + constexpr size_t bufferSize = 65536; + unsigned char Buffer[bufferSize]; + while (true) { - Update(Buffer, uiRead); + size_t bytesRead = fread(Buffer, 1, bufferSize, pFile); + if (bytesRead == 0) + { + if (ferror(pFile)) + { + fclose(pFile); + errno = EIO; + return false; + } + break; + } + Update(Buffer, static_cast(bytesRead)); } - // Finalize Finalize(); - // Close it fclose(pFile); - // Success memcpy(md5Result.data, m_digest, 16); return true; } - // Failed return false; - // CRYPT_END } bool CMD5Hasher::Calculate(const void* pBuffer, size_t sizeLength, MD5& md5Result) @@ -147,7 +158,7 @@ namespace SharedUtil { // CRYPT_START unsigned int input_index, buffer_index; - unsigned int buffer_space; // how much space is left in buffer + unsigned int buffer_space; // how much space is left in buffer // Compute number of bytes mod 64 buffer_index = (unsigned int)((m_count[0] >> 3) & 0x3F); @@ -160,10 +171,10 @@ namespace SharedUtil m_count[1] += ((unsigned int)input_length >> 29); - buffer_space = 64 - buffer_index; // how much space is left in buffer + buffer_space = 64 - buffer_index; // how much space is left in buffer // Transform as many times as possible. - if (input_length >= buffer_space) // ie. we have enough to fill the buffer + if (input_length >= buffer_space) // ie. we have enough to fill the buffer { // fill the rest of the buffer and transform memcpy(m_buffer + buffer_index, input, buffer_space); @@ -175,11 +186,11 @@ namespace SharedUtil Transform(input + input_index); } - buffer_index = 0; // so we can buffer remaining + buffer_index = 0; // so we can buffer remaining } else { - input_index = 0; // so we can buffer the whole input + input_index = 0; // so we can buffer the whole input } // and here we do the buffering: @@ -212,7 +223,10 @@ namespace SharedUtil memset(m_buffer, 0, sizeof(m_buffer)); } - const unsigned char* CMD5Hasher::GetResult() const { return m_digest; } + const unsigned char* CMD5Hasher::GetResult() const + { + return m_digest; + } void CMD5Hasher::Transform(unsigned char block[64]) { @@ -323,15 +337,30 @@ namespace SharedUtil ((unsigned int)input[j]) | (((unsigned int)input[j + 1]) << 8) | (((unsigned int)input[j + 2]) << 16) | (((unsigned int)input[j + 3]) << 24); } - inline unsigned int CMD5Hasher::RotateLeft(unsigned int x, unsigned int n) { return (x << n) | (x >> (32 - n)); } + inline unsigned int CMD5Hasher::RotateLeft(unsigned int x, unsigned int n) + { + return (x << n) | (x >> (32 - n)); + } - inline unsigned int CMD5Hasher::F(unsigned int x, unsigned int y, unsigned int z) { return (x & y) | (~x & z); } + inline unsigned int CMD5Hasher::F(unsigned int x, unsigned int y, unsigned int z) + { + return (x & y) | (~x & z); + } - inline unsigned int CMD5Hasher::G(unsigned int x, unsigned int y, unsigned int z) { return (x & z) | (y & ~z); } + inline unsigned int CMD5Hasher::G(unsigned int x, unsigned int y, unsigned int z) + { + return (x & z) | (y & ~z); + } - inline unsigned int CMD5Hasher::H(unsigned int x, unsigned int y, unsigned int z) { return x ^ y ^ z; } + inline unsigned int CMD5Hasher::H(unsigned int x, unsigned int y, unsigned int z) + { + return x ^ y ^ z; + } - inline unsigned int CMD5Hasher::I(unsigned int x, unsigned int y, unsigned int z) { return y ^ (x | ~z); } + inline unsigned int CMD5Hasher::I(unsigned int x, unsigned int y, unsigned int z) + { + return y ^ (x | ~z); + } inline void CMD5Hasher::FF(unsigned int& a, unsigned int b, unsigned int c, unsigned int d, unsigned int x, unsigned int s, unsigned int ac) { @@ -361,18 +390,21 @@ namespace SharedUtil // Implementation of Bob Jenkin's awesome hash function // Ref: https://burtleburtle.net/bob/hash/doobs.html // - unsigned int HashString(const char* szString) { return HashString(szString, (unsigned int)strlen(szString)); } + unsigned int HashString(const char* szString) + { + return HashString(szString, (unsigned int)strlen(szString)); + } unsigned int HashString(const char* szString, unsigned int length) { - const char* k; //< pointer to the string data to be hashed - unsigned int a, b, c; //< temporary variables - unsigned int len; //< length of the string left + const char* k; //< pointer to the string data to be hashed + unsigned int a, b, c; //< temporary variables + unsigned int len; //< length of the string left k = szString; len = length; a = b = 0x9e3779b9; - c = 0xabcdef89; // initval, arbitrarily set + c = 0xabcdef89; // initval, arbitrarily set while (len >= 12) { @@ -416,7 +448,7 @@ namespace SharedUtil // Handle the last 11 remaining bytes // Note: All cases fall through - c += length; // Lower byte of c gets used for length + c += length; // Lower byte of c gets used for length switch (len) { @@ -545,20 +577,32 @@ namespace SharedUtil if (c < 16) { if ((i & 1) == 0) - pOutput[i / 2] = (c << 4); // First nibble + pOutput[i / 2] = (c << 4); // First nibble else - pOutput[i / 2] |= c; // Second nibble + pOutput[i / 2] |= c; // Second nibble } } } - void GenerateSha256(const void* pData, uint uiLength, uchar output[32]) { sha256((const uchar*)pData, uiLength, output); } + void GenerateSha256(const void* pData, uint uiLength, uchar output[32]) + { + sha256((const uchar*)pData, uiLength, output); + } - SString GenerateSha256HexString(const void* pData, uint uiLength) { return GenerateHashHexString(EHashFunction::SHA256, pData, uiLength); } + SString GenerateSha256HexString(const void* pData, uint uiLength) + { + return GenerateHashHexString(EHashFunction::SHA256, pData, uiLength); + } - SString GenerateSha256HexString(const SString& strData) { return GenerateHashHexString(EHashFunction::SHA256, strData); } + SString GenerateSha256HexString(const SString& strData) + { + return GenerateHashHexString(EHashFunction::SHA256, strData); + } - SString GenerateSha256HexStringFromFile(const SString& strFilename) { return GenerateHashHexStringFromFile(EHashFunction::SHA256, strFilename); } + SString GenerateSha256HexStringFromFile(const SString& strFilename) + { + return GenerateHashHexStringFromFile(EHashFunction::SHA256, strFilename); + } SString GenerateHashHexString(EHashFunctionType hashFunction, const void* pData, uint uiLength) { @@ -749,20 +793,38 @@ namespace SharedUtil k[i] = keybuffer[i]; // Copy the input string to a buffer of size multiple of 4 - int strbuflen = str.length(); - if (strbuflen == 0) + if (str.length() == 0 || str.length() > static_cast(INT_MAX - 4)) return; + int strbuflen = static_cast(str.length()); if ((strbuflen % 4) > 0) strbuflen += 4 - (strbuflen % 4); - unsigned char* strbuf = new unsigned char[strbuflen]; - memset(strbuf, 0, strbuflen); - memcpy(strbuf, str.c_str(), str.length()); + + // Use malloc to probe if allocation would succeed, bypassing MTA's custom OOM handler + // (which uses non-continuable SEH exceptions). Unlike new, malloc does not invoke _set_new_handler. + // Probe for working buffer (strbuflen) + output string with capacity headroom (2 * (strbuflen + 4)) + // to account for std::string's capacity doubling behavior during repeated appends. + constexpr size_t kMaxProbeSize = SIZE_MAX / 3 - 8; + if (static_cast(strbuflen) > kMaxProbeSize) + return; + + size_t totalProbeSize = static_cast(strbuflen) * 3 + 8; + void* probe = std::malloc(totalProbeSize); + if (!probe) + return; + std::free(probe); + + std::unique_ptr strbuf(static_cast(std::malloc(strbuflen)), &std::free); + if (!strbuf) + return; + + memset(strbuf.get(), 0, strbuflen); + memcpy(strbuf.get(), str.c_str(), str.length()); // Encode it! v[1] = 0; for (int i = 0; i < strbuflen; i += 4) { - v[0] = *(unsigned int*)&strbuf[i]; + v[0] = *(unsigned int*)&strbuf.get()[i]; encodeXtea(&v[0], &w[0], &k[0]); out->append((char*)&w[0], 4); @@ -770,8 +832,6 @@ namespace SharedUtil v[1] = w[1]; } out->append((char*)&v[1], 4); - - delete[] strbuf; } void TeaDecode(const SString& str, const SString& key, SString* out) @@ -789,7 +849,9 @@ namespace SharedUtil out->clear(); // Count the number of passes that we need - int numBlocks = str.length() / 4; + if (str.length() > static_cast(INT_MAX)) + return; + int numBlocks = static_cast(str.length() / 4); int numPasses = numBlocks - 1; if (numPasses <= 0) @@ -803,9 +865,25 @@ namespace SharedUtil for (int i = 0; i < 4; ++i) k[i] = keybuffer[i]; - // Create a temporary buffer to store the result - unsigned char* buffer = new unsigned char[numPasses * 4 + 4]; - memset(buffer, 0, numPasses * 4 + 4); + // Use malloc to probe if allocation would succeed, bypassing MTA's custom OOM handler + // (which uses non-continuable SEH exceptions). Unlike new, malloc does not invoke _set_new_handler. + // Probe for working buffer (numPasses * 4 + 4) + output string (numPasses * 4) to cover out->assign() allocation. + constexpr size_t kMaxNumPasses = (SIZE_MAX - 4) / 8; + if (static_cast(numPasses) > kMaxNumPasses) + return; + + size_t workingSize = static_cast(numPasses) * 4 + 4; + size_t outputSize = static_cast(numPasses) * 4; + void* probe = std::malloc(workingSize + outputSize); + if (!probe) + return; + std::free(probe); + + std::unique_ptr buffer(static_cast(std::malloc(workingSize)), &std::free); + if (!buffer) + return; + + memset(buffer.get(), 0, workingSize); // Decode it! const char* p = str.c_str(); @@ -814,11 +892,10 @@ namespace SharedUtil { v[0] = *(unsigned int*)&p[(numPasses - i - 1) * 4]; decodeXtea(&v[0], &w[0], &k[0]); - *(unsigned int*)&buffer[(numPasses - i - 1) * 4] = w[0]; + *(unsigned int*)&buffer.get()[(numPasses - i - 1) * 4] = w[0]; v[1] = w[1]; } - out->assign((char*)buffer, numPasses * 4); - delete[] buffer; + out->assign((char*)buffer.get(), numPasses * 4); } -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.HashMap.h b/Shared/sdk/SharedUtil.HashMap.h index 869d1947913..ea0e0e36cb3 100644 --- a/Shared/sdk/SharedUtil.HashMap.h +++ b/Shared/sdk/SharedUtil.HashMap.h @@ -14,9 +14,9 @@ #define CHashMap CMap #else -#include -#include -#include "SString.h" + #include + #include + #include "SString.h" namespace SharedUtil { @@ -95,7 +95,7 @@ namespace SharedUtil } return it->second; } -} // namespace SharedUtil +} // namespace SharedUtil // Calculate a hash value for SString namespace std @@ -105,6 +105,6 @@ namespace std { size_t operator()(const SString& str) const { return std::hash()(str); } }; -} // namespace std +} // namespace std #endif // WITH_ALLOC_TRACKING diff --git a/Shared/sdk/SharedUtil.IntTypes.h b/Shared/sdk/SharedUtil.IntTypes.h index e3b391b3543..6f8171852f9 100644 --- a/Shared/sdk/SharedUtil.IntTypes.h +++ b/Shared/sdk/SharedUtil.IntTypes.h @@ -12,27 +12,27 @@ *************************************************************************/ // VS GCC // Actual sizes: 32bit 64bit 64bit -typedef unsigned long ulong; // 32 32 64 -typedef unsigned int uint; // 32 -typedef unsigned short ushort; // 16 -typedef unsigned char uchar; // 8 +typedef unsigned long ulong; // 32 32 64 +typedef unsigned int uint; // 32 +typedef unsigned short ushort; // 16 +typedef unsigned char uchar; // 8 -typedef unsigned long long uint64; // 64 -typedef unsigned int uint32; // 32 -typedef unsigned short uint16; // 16 -typedef unsigned char uint8; // 8 +typedef unsigned long long uint64; // 64 +typedef unsigned int uint32; // 32 +typedef unsigned short uint16; // 16 +typedef unsigned char uint8; // 8 // signed types -typedef signed long long int64; // 64 -typedef signed int int32; // 32 -typedef signed short int16; // 16 -typedef signed char int8; // 8 +typedef signed long long int64; // 64 +typedef signed int int32; // 32 +typedef signed short int16; // 16 +typedef signed char int8; // 8 // Windowsesq types -typedef unsigned char BYTE; // 8 -typedef unsigned short WORD; // 16 -typedef unsigned long DWORD; // 32 32 64 -typedef float FLOAT; // 32 +typedef unsigned char BYTE; // 8 +typedef unsigned short WORD; // 16 +typedef unsigned long DWORD; // 32 32 64 +typedef float FLOAT; // 32 // Type: considerations: // a) long (and therefore DWORD) is 64 bits when compiled using 64 bit GCC diff --git a/Shared/sdk/SharedUtil.IntervalCounter.h b/Shared/sdk/SharedUtil.IntervalCounter.h index aa3e4a7fb21..39afe4c7532 100644 --- a/Shared/sdk/SharedUtil.IntervalCounter.h +++ b/Shared/sdk/SharedUtil.IntervalCounter.h @@ -51,4 +51,4 @@ namespace SharedUtil } shared; }; -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.IntervalCounter.hpp b/Shared/sdk/SharedUtil.IntervalCounter.hpp index a8b2d6d3bc3..8f3cd790110 100644 --- a/Shared/sdk/SharedUtil.IntervalCounter.hpp +++ b/Shared/sdk/SharedUtil.IntervalCounter.hpp @@ -119,4 +119,4 @@ namespace SharedUtil pTimer->Reset(); } -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.Legacy.h b/Shared/sdk/SharedUtil.Legacy.h index d8fd1e0189c..eba6ee78a1b 100644 --- a/Shared/sdk/SharedUtil.Legacy.h +++ b/Shared/sdk/SharedUtil.Legacy.h @@ -26,30 +26,34 @@ namespace SharedUtil { return a > b ? a : b; } -} // namespace SharedUtil +} // namespace SharedUtil -#define PRId64 "lld" -#define PRIx64 "llx" +#ifndef PRId64 + #define PRId64 "lld" +#endif +#ifndef PRIx64 + #define PRIx64 "llx" +#endif // Crazy thing -#define LOCAL_FUNCTION_START struct local { -#define LOCAL_FUNCTION_END }; -#define LOCAL_FUNCTION local +#define LOCAL_FUNCTION_START \ + struct local \ + { +#define LOCAL_FUNCTION_END \ + } \ + ; +#define LOCAL_FUNCTION local // Inline callback definition for std::sort -#define sort_inline(a,b,c) \ - { \ - LOCAL_FUNCTION_START \ - static bool SortPredicate c \ - LOCAL_FUNCTION_END \ - std::sort ( a, b, LOCAL_FUNCTION::SortPredicate ); \ - } +#define sort_inline(a, b, c) \ + { \ + LOCAL_FUNCTION_START \ + static bool SortPredicate c LOCAL_FUNCTION_END std::sort(a, b, LOCAL_FUNCTION::SortPredicate); \ + } // Inline callback definition for std::list::sort -#define sort_list_inline(a,c) \ - { \ - LOCAL_FUNCTION_START \ - static bool SortPredicate c \ - LOCAL_FUNCTION_END \ - a.sort ( LOCAL_FUNCTION::SortPredicate ); \ - } +#define sort_list_inline(a, c) \ + { \ + LOCAL_FUNCTION_START \ + static bool SortPredicate c LOCAL_FUNCTION_END a.sort(LOCAL_FUNCTION::SortPredicate); \ + } diff --git a/Shared/sdk/SharedUtil.Logging.h b/Shared/sdk/SharedUtil.Logging.h index 05422e15fc5..408e3806344 100644 --- a/Shared/sdk/SharedUtil.Logging.h +++ b/Shared/sdk/SharedUtil.Logging.h @@ -13,37 +13,44 @@ namespace SharedUtil { - // - // Output timestamped line into the debugger - // - #ifdef MTA_DEBUG +// +// Output timestamped line into the debugger +// +#ifdef MTA_DEBUG void OutputDebugLine(const char* szMessage); void SetDebugTagHidden(const SString& strTag, bool bHidden = true); bool IsDebugTagHidden(const SString& strTag); - #else - inline void OutputDebugLineDummy() {} - inline void SetDebugTagHiddenDummy() {} - inline bool IsDebugTagHiddenDummy() { return false; } - #define OutputDebugLine(x) OutputDebugLineDummy () - #define SetDebugTagHidden(x) SetDebugTagHiddenDummy () - #define IsDebugTagHidden(x) IsDebugTagHiddenDummy () - #endif +#else + inline void OutputDebugLineDummy() + { + } + inline void SetDebugTagHiddenDummy() + { + } + inline bool IsDebugTagHiddenDummy() + { + return false; + } + #define OutputDebugLine(x) OutputDebugLineDummy() + #define SetDebugTagHidden(x) SetDebugTagHiddenDummy() + #define IsDebugTagHidden(x) IsDebugTagHiddenDummy() +#endif void OutputReleaseLine(const char* szMessage); - // Instance counter - #ifdef MTA_DEBUG +// Instance counter +#ifdef MTA_DEBUG void DebugCreateCount(const SString& strName); void DebugDestroyCount(const SString& strName); - #define DEBUG_CREATE_COUNT(cls) DebugCreateCount(cls) - #define DEBUG_DESTROY_COUNT(cls) DebugDestroyCount(cls) - #else - #define DEBUG_CREATE_COUNT(cls) - #define DEBUG_DESTROY_COUNT(cls) - #endif + #define DEBUG_CREATE_COUNT(cls) DebugCreateCount(cls) + #define DEBUG_DESTROY_COUNT(cls) DebugDestroyCount(cls) +#else + #define DEBUG_CREATE_COUNT(cls) + #define DEBUG_DESTROY_COUNT(cls) +#endif // Cycle (log) files when they reach a certain size. void CycleFile(const SString& strPathFilename, uint uiCycleThreshKB = 1, uint uiNumBackups = 1); -}; // namespace SharedUtil +}; // namespace SharedUtil using namespace SharedUtil; diff --git a/Shared/sdk/SharedUtil.Logging.hpp b/Shared/sdk/SharedUtil.Logging.hpp index 3de31f50ebd..f295bc0175a 100644 --- a/Shared/sdk/SharedUtil.Logging.hpp +++ b/Shared/sdk/SharedUtil.Logging.hpp @@ -47,13 +47,13 @@ namespace SharedUtil SetDebugTagHidden("LogEvent"); SetDebugTagHidden("Mem"); - #ifdef Has_InitDebugTagsLocal + #ifdef Has_InitDebugTagsLocal InitDebugTagsLocal(); - #endif + #endif } static std::set ms_debugTagInvisibleMap; -}; // namespace SharedUtil +}; // namespace SharedUtil // // Set hiddeness of a debug tag @@ -96,11 +96,11 @@ void SharedUtil::OutputDebugLine(const char* szMessage) SString strMessage = GetLocalTimeString(false, true) + " - " + szMessage; if (strMessage.length() > 0 && strMessage[strMessage.length() - 1] != '\n') strMessage += "\n"; -#ifdef _WIN32 - OutputDebugString(strMessage); -#else - // Other platforms here -#endif + #ifdef _WIN32 + OutputDebugStringW(FromUTF8(strMessage)); + #else + // Other platforms here + #endif } namespace SharedUtil @@ -131,7 +131,7 @@ namespace SharedUtil if (info.iCount < 0) OutputDebugLine(SString("[InstanceCount] Count is negative (%d) for %s", info.iCount, *strName)); } -} // namespace SharedUtil +} // namespace SharedUtil #endif // MTA_DEBUG @@ -144,9 +144,9 @@ void SharedUtil::OutputReleaseLine(const char* szMessage) if (strMessage.length() > 0 && strMessage[strMessage.length() - 1] != '\n') strMessage += "\n"; #ifdef _WIN32 - OutputDebugString(strMessage); + OutputDebugStringW(FromUTF8(strMessage)); #else - // Other platforms here + // Other platforms here #endif } @@ -167,8 +167,8 @@ void SharedUtil::CycleFile(const SString& strPathFilename, uint uiCycleThreshKB, // Rename older files .1 .2 etc uint uiNew = uiNumBackups - 1 - i; uint uiOld = uiNumBackups - i; - SString strFilenameNewer = strPathFilename + (uiNew ? SString(".%d", uiNew) : ""); - SString strFilenameOlder = strPathFilename + (uiOld ? SString(".%d", uiOld) : ""); + SString strFilenameNewer = strPathFilename + (uiNew ? SString(".%d", uiNew) : SStringX("")); + SString strFilenameOlder = strPathFilename + (uiOld ? SString(".%d", uiOld) : SStringX("")); FileDelete(strFilenameOlder); FileRename(strFilenameNewer, strFilenameOlder); diff --git a/Shared/sdk/SharedUtil.Map.h b/Shared/sdk/SharedUtil.Map.h index 8907932bf62..860a6ab149d 100644 --- a/Shared/sdk/SharedUtil.Map.h +++ b/Shared/sdk/SharedUtil.Map.h @@ -216,4 +216,4 @@ namespace SharedUtil return std::get(collection.insert(item)); } -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.Math.h b/Shared/sdk/SharedUtil.Math.h index bd53f711106..3dc5cebddac 100644 --- a/Shared/sdk/SharedUtil.Math.h +++ b/Shared/sdk/SharedUtil.Math.h @@ -104,10 +104,13 @@ namespace SharedUtil } } - inline float DegreesToRadians(float fValue) { return fValue * 0.017453292f; } + inline float DegreesToRadians(float fValue) + { + return fValue * 0.017453292f; + } static std::random_device randomDevice; - static std::mt19937 randomEngine(randomDevice()); + static std::mt19937 randomEngine(randomDevice()); inline float GetRandomNumberInRange(float minRange, float maxRange) { @@ -116,6 +119,27 @@ namespace SharedUtil inline bool IsNearlyEqual(float a, float b, float epsilon = std::numeric_limits().epsilon()) noexcept { - return std::fabs(a - b) <= epsilon; + return std::fabs(a - b) <= epsilon; + } + + inline bool ApproximatelyEqual(float a, float b, float epsilon = std::numeric_limits().epsilon()) noexcept + { + return std::fabs(a - b) <= std::max(std::fabs(a), std::fabs(b)) * epsilon; + } + + inline bool EssentiallyEqual(float a, float b, float epsilon = std::numeric_limits().epsilon()) noexcept + { + return std::fabs(a - b) <= std::min(std::fabs(a), std::fabs(b)) * epsilon; } -} // namespace SharedUtil + + inline bool DefinitelyGreaterThan(float a, float b, float epsilon = std::numeric_limits().epsilon()) noexcept + { + return (a - b) > std::max(std::fabs(a), std::fabs(b)) * epsilon; + } + + inline bool DefinitelyLessThan(float a, float b, float epsilon = std::numeric_limits().epsilon()) noexcept + { + return (b - a) > std::max(std::fabs(a), std::fabs(b)) * epsilon; + } + +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.MemAccess.h b/Shared/sdk/SharedUtil.MemAccess.h index 6f236275c4d..78625284741 100644 --- a/Shared/sdk/SharedUtil.MemAccess.h +++ b/Shared/sdk/SharedUtil.MemAccess.h @@ -11,6 +11,16 @@ #include +#ifdef _WIN32 + #ifdef MTASA_EXPORT_SHARED_UTIL + #define SHARED_UTIL_API __declspec(dllexport) + #else + #define SHARED_UTIL_API __declspec(dllimport) + #endif +#else + #define SHARED_UTIL_API +#endif + namespace SharedUtil { struct SMemWrite @@ -20,12 +30,20 @@ namespace SharedUtil DWORD oldProt; }; - void SetInitialVirtualProtect(); - bool IsSlowMem(const void* pAddr, uint uiAmount); - SMemWrite OpenMemWrite(const void* pAddr, uint uiAmount); - void CloseMemWrite(SMemWrite& hMem); - bool ismemset(const void* pAddr, int cValue, uint uiAmount); + SHARED_UTIL_API void SetInitialVirtualProtect(); + SHARED_UTIL_API bool IsSlowMem(const void* pAddr, uint uiAmount); + SHARED_UTIL_API SMemWrite OpenMemWrite(const void* pAddr, uint uiAmount); + SHARED_UTIL_API void CloseMemWrite(SMemWrite& hMem); + SHARED_UTIL_API bool ismemset(const void* pAddr, int cValue, uint uiAmount); + + bool IsProtectedSlowMem(const void* pAddr); - #define DEBUG_CHECK_IS_FAST_MEM(addr,size) { dassert( !IsSlowMem( (const void*)(addr), size ) ); } - #define DEBUG_CHECK_IS_SLOW_MEM(addr,size) { dassert( IsSlowMem( (const void*)(addr), size ) ); } -} // namespace SharedUtil +#define DEBUG_CHECK_IS_FAST_MEM(addr, size) \ + { \ + dassert(!IsSlowMem((const void*)(addr), size)); \ + } +#define DEBUG_CHECK_IS_SLOW_MEM(addr, size) \ + { \ + dassert(IsSlowMem((const void*)(addr), size)); \ + } +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.MemAccess.hpp b/Shared/sdk/SharedUtil.MemAccess.hpp index 79355d00eba..e4a487e0f69 100644 --- a/Shared/sdk/SharedUtil.MemAccess.hpp +++ b/Shared/sdk/SharedUtil.MemAccess.hpp @@ -8,15 +8,22 @@ * *****************************************************************************/ +#pragma once +#include +#include +#include "SharedUtil.MemAccess.h" +#include "SharedUtil.Logging.h" +#include "SString.h" + namespace SharedUtil { // Returns true if matching memset would have no affect bool ismemset(const void* pInAddr, int cValue, uint uiAmount) { const uchar* pAddr = (const uchar*)pInAddr; - uchar ucValue = cValue; + const int iValue = (cValue & 0xFF); for (uint i = 0; i < uiAmount; i++) - if (pAddr[i] != ucValue) + if (pAddr[i] != iValue) return false; return true; } @@ -74,13 +81,12 @@ namespace SharedUtil // Temporarily unprotect slow mem area SMemWrite OpenMemWrite(const void* pAddr, uint uiAmount) { - SMemWrite hMem; + SMemWrite hMem{}; // Check for incorrect use of function if (!IsSlowMem(pAddr, uiAmount)) { dassert(0 && "Should use Mem*Fast function"); - hMem.dwFirstPage = 0; return hMem; } @@ -91,26 +97,45 @@ namespace SharedUtil hMem.dwFirstPage = ((DWORD)pAddr) & ~0xFFF; DWORD dwLastPage = (((DWORD)pAddr) + uiAmount - 1) & ~0xFFF; hMem.dwSize = dwLastPage - hMem.dwFirstPage + 0x1000; - VirtualProtect((LPVOID)hMem.dwFirstPage, 0x1000, PAGE_EXECUTE_READWRITE, &hMem.oldProt); + + if (!VirtualProtect((LPVOID)hMem.dwFirstPage, 0x1000, PAGE_EXECUTE_READWRITE, &hMem.oldProt)) + { + DWORD error = GetLastError(); + OutputDebugLine(SString("MemAccess::OpenMemWrite: VirtualProtect failed at %08x, error: %d", hMem.dwFirstPage, error)); + hMem = {}; + assert(!"Failed to unprotect memory"); + return hMem; + } // Make sure not using this slow function too much - OutputDebugLine(SString("[Mem] OpenMemWrite at %08x for %d bytes (oldProt:%04x)", pAddr, uiAmount, hMem.oldProt)); + OutputDebugLine(SString("[MemAccess] OpenMemWrite at %08x for %d bytes (oldProt:%04x)", pAddr, uiAmount, hMem.oldProt)); #ifdef MTA_DEBUG -#if 0 // Annoying - // Checks + #if 0 // Annoying + // Checks if ( IsProtectedSlowMem( (const void*)hMem.dwFirstPage ) ) assert( hMem.oldProt == PAGE_EXECUTE_READ || hMem.oldProt == PAGE_READONLY ); else assert( hMem.oldProt == PAGE_EXECUTE_READWRITE || hMem.oldProt == PAGE_EXECUTE_WRITECOPY ); -#endif + #endif #endif // Extra if more than one page for (uint i = 0x1000; i < hMem.dwSize; i += 0x1000) { DWORD oldProtCheck; - VirtualProtect((LPVOID)(hMem.dwFirstPage + i), 0x1000, PAGE_EXECUTE_READWRITE, &oldProtCheck); + if (!VirtualProtect((LPVOID)(hMem.dwFirstPage + i), 0x1000, PAGE_EXECUTE_READWRITE, &oldProtCheck)) + { + // Try to rollback + DWORD temp; + VirtualProtect((LPVOID)hMem.dwFirstPage, i, hMem.oldProt, &temp); + + DWORD error = GetLastError(); + OutputDebugLine(SString("[MemAccess] OpenMemWrite VirtualProtect failed at %08x, error: %d", hMem.dwFirstPage + i, error)); + hMem = {}; + assert(!"Failed to unprotect multi-page memory region"); + return hMem; + } dassert(hMem.oldProt == oldProtCheck); } @@ -122,9 +147,22 @@ namespace SharedUtil { if (hMem.dwFirstPage == 0) return; + DWORD oldProt; - VirtualProtect((LPVOID)hMem.dwFirstPage, hMem.dwSize, hMem.oldProt, &oldProt); - dassert(oldProt == PAGE_EXECUTE_READWRITE); + BOOL result = VirtualProtect((LPVOID)hMem.dwFirstPage, hMem.dwSize, hMem.oldProt, &oldProt); + + if (!result) + { + DWORD error = GetLastError(); + OutputDebugLine(SString("MemAccess::CloseMemWrite: VirtualProtect failed at %08x, size %08x, error: %d", hMem.dwFirstPage, hMem.dwSize, error)); + assert(!"Failed to restore memory protection - critical"); + } + else + { + dassert(oldProt == PAGE_EXECUTE_READWRITE); + } + + hMem.dwFirstPage = 0; // Invalidate handle } -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.Memory.h b/Shared/sdk/SharedUtil.Memory.h index 5cbd40a7b0f..563f5bfdb6b 100644 --- a/Shared/sdk/SharedUtil.Memory.h +++ b/Shared/sdk/SharedUtil.Memory.h @@ -12,7 +12,7 @@ #include -#define CUSTOM_EXCEPTION_CODE_OOM 0xE03B10C0 // -533000000 +#define CUSTOM_EXCEPTION_CODE_OOM 0xE03B10C0 // -533000000 namespace SharedUtil { @@ -27,4 +27,4 @@ namespace SharedUtil bool TryGetProcessMemoryStats(ProcessMemoryStats& out); void SetMemoryAllocationFailureHandler(); -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.Memory.hpp b/Shared/sdk/SharedUtil.Memory.hpp index eff4ab688b5..2834249d67a 100644 --- a/Shared/sdk/SharedUtil.Memory.hpp +++ b/Shared/sdk/SharedUtil.Memory.hpp @@ -102,7 +102,7 @@ namespace SharedUtil if (!success && GetLastError() == ERROR_BAD_LENGTH) { - workingSetInfo->NumberOfEntries += 64; // Insurance in case the number of entries changes. + workingSetInfo->NumberOfEntries += 64; // Insurance in case the number of entries changes. workingSetBuffer.resize(workingSetInfo->NumberOfEntries * sizeof(PSAPI_WORKING_SET_BLOCK) + sizeof(PSAPI_WORKING_SET_INFORMATION)); workingSetInfo = reinterpret_cast(workingSetBuffer.data()); success = QueryWorkingSet(process, workingSetBuffer.data(), workingSetBuffer.size()); @@ -187,9 +187,9 @@ namespace SharedUtil { #if defined(_WIN32) _set_new_handler(&HandleMemoryAllocationFailure); - _set_new_mode(1 /* call _set_new_handler for malloc failure */); + // _set_new_mode(1 /* call _set_new_handler for malloc failure */); #else std::set_new_handler(&HandleMemoryAllocationFailure); #endif } -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.Misc.h b/Shared/sdk/SharedUtil.Misc.h index 56b6b8508a7..7a40e18f4d2 100644 --- a/Shared/sdk/SharedUtil.Misc.h +++ b/Shared/sdk/SharedUtil.Misc.h @@ -16,34 +16,115 @@ #include #include #include +#include +#include +#include +#include #include "SString.h" #include "WString.h" #include "SharedUtil.Defines.h" #include "SharedUtil.Map.h" +#include "SharedUtil.Logging.h" + +#if __cplusplus >= 201703L // C++17 + #ifndef __GLIBCXX__ +namespace std +{ + namespace filesystem + { + class path; + } +} + #else +namespace std +{ + namespace filesystem + { + inline namespace __cxx11 __attribute__((__abi_tag__("cxx11"))) { + } + inline _GLIBCXX_BEGIN_NAMESPACE_CXX11 + + class path; + + _GLIBCXX_END_NAMESPACE_CXX11 + } +} + #endif +#endif + +#ifdef WIN32 + // Forward declare basic windows types to avoid including windows.h here + #ifdef STRICT +struct HGLOBAL__; +using WinHGlobalHandle = struct HGLOBAL__*; + #else +using WinHGlobalHandle = void*; + #endif + +struct HWND__; + #ifndef _WINDOWS_ +typedef HWND__* HWND; +typedef unsigned int UINT; + #ifndef HINSTANCE__ +struct HINSTANCE__; + #endif +typedef HINSTANCE__* HINSTANCE; +typedef HINSTANCE HMODULE; + #ifndef BOOL +typedef int BOOL; + #endif + #ifndef WINAPI + #define WINAPI __stdcall + #endif + #ifndef NO_ERROR + #define NO_ERROR 0L + #endif +extern "C" __declspec(dllimport) void WINAPI SetLastError(DWORD dwErrCode); +extern "C" __declspec(dllimport) DWORD WINAPI GetLastError(void); +extern "C" __declspec(dllimport) BOOL WINAPI GlobalUnlock(WinHGlobalHandle hMem); + #endif +#endif namespace SharedUtil { class CArgMap; #ifdef WIN32 + namespace Details + { + inline void* GetProcAddressRaw(HMODULE hModule, const char* functionName) noexcept + { + #ifdef _WINDOWS_ + if (hModule != nullptr) + { + return reinterpret_cast(::GetProcAddress(hModule, functionName)); + } + #else + (void)hModule; + (void)functionName; + #endif + return nullptr; + } + } + SString GetMajorVersionString(); // Get a system registry value - SString GetSystemRegistryValue(uint hKey, const SString& strPath, const SString& strName); + SString GetSystemRegistryValue(uint hKey, const SString& strPath, const SString& strName, int* iResult = nullptr); // Get/set registry values for the current version void SetRegistryValue(const SString& strPath, const SString& strName, const SString& strValue, bool bFlush = false); - SString GetRegistryValue(const SString& strPath, const SString& strName); + SString GetRegistryValue(const SString& strPath, const SString& strName, int* iResult = nullptr); bool RemoveRegistryKey(const SString& strPath); // Get/set registry values for a particular version void SetVersionRegistryValue(const SString& strVersion, const SString& strPath, const SString& strName, const SString& strValue); - SString GetVersionRegistryValue(const SString& strVersion, const SString& strPath, const SString& strName); + SString GetVersionRegistryValue(const SString& strVersion, const SString& strPath, const SString& strName, int* iResult = nullptr); // Get/set registry values for all versions (Common) void SetCommonRegistryValue(const SString& strPath, const SString& strName, const SString& strValue); - SString GetCommonRegistryValue(const SString& strPath, const SString& strName); + SString GetCommonRegistryValue(const SString& strPath, const SString& strName, int* iResult = nullptr); bool ShellExecuteBlocking(const SString& strAction, const SString& strFile, const SString& strParameters = "", const SString& strDirectory = "", int nShowCmd = 1); @@ -54,15 +135,18 @@ namespace SharedUtil // Output a UTF8 encoded messagebox // Used in the Win32 Client only // - #ifdef _WINDOWS_ int MessageBoxUTF8(HWND hWnd, SString lpText, SString lpCaption, UINT uType); - #endif // // Return full path and filename of parent exe // SString GetParentProcessPathFilename(int pid); + // + // Set the MTASA base dir manually + // + void SetMTASABaseDirOverride(const SString& strPath); + // // Get startup directory as saved in the registry by the launcher // Used in the Win32 Client only @@ -78,6 +162,165 @@ namespace SharedUtil // Returns true if current process is GTA (i.e not MTA process) bool IsGTAProcess(); + // Returns true if the pointer points to committed, readable memory + bool IsReadablePointer(const void* ptr, size_t size); + + // GTA:SA executable memory bounds for validating vtable/function pointers. + // .text (code): 0x401000 - 0x857000 (VA 0x1000, size 0x456000) + // .rdata (vtables): 0x858000 - 0x8A4000 (VA 0x458000, size 0x4C000) + constexpr std::uint32_t GTA_SA_VALID_PTR_START = 0x401000; + constexpr std::uint32_t GTA_SA_VALID_PTR_END = 0x8A4000; + + // Fast address range check for GTA:SA code/rdata pointers (vtables, functions). + // Used to validate pointers before dereferencing, avoiding expensive SEH volatile reads. + inline bool IsValidGtaSaPtr(std::uint32_t addr) noexcept + { + return addr >= GTA_SA_VALID_PTR_START && addr < GTA_SA_VALID_PTR_END; + } + + [[nodiscard]] const SString& GetMTAProcessBaseDir(); + + template + [[nodiscard]] inline bool TryGetProcAddress(HMODULE hModule, const char* functionName, TFunction& outExport) noexcept + { + static_assert(std::is_pointer_v, "TryGetProcAddress expects a pointer type"); + + void* address = nullptr; + + #if defined(_WIN32) + address = Details::GetProcAddressRaw(hModule, functionName); + #else + (void)hModule; + (void)functionName; + #endif + + if (address != nullptr) + { + outExport = reinterpret_cast(address); + return true; + } + + outExport = nullptr; + return false; + } + + class GlobalUnlockGuard + { + public: + using MutexGuard = std::scoped_lock; + + GlobalUnlockGuard() noexcept = default; + explicit GlobalUnlockGuard(WinHGlobalHandle handle) noexcept : m_handle(handle) {} + ~GlobalUnlockGuard() { UnlockAndLog("during destruction"); } + + GlobalUnlockGuard(const GlobalUnlockGuard&) = delete; + GlobalUnlockGuard& operator=(const GlobalUnlockGuard&) = delete; + + GlobalUnlockGuard(GlobalUnlockGuard&& other) noexcept : m_handle(other.release()) {} + + GlobalUnlockGuard& operator=(GlobalUnlockGuard&& other) noexcept + { + if (this != &other) + { + WithLock( + [&]() noexcept + { + DWORD errorCode = NO_ERROR; + UnlockLocked("during move assignment", &errorCode); + m_handle = other.release(); + }); + } + return *this; + } + + [[nodiscard]] bool UnlockChecked(DWORD* failureCode = nullptr) noexcept + { + return WithLock([&]() noexcept { return UnlockInternal(failureCode); }); + } + + void reset(WinHGlobalHandle handle = nullptr) noexcept + { + WithLock( + [&]() noexcept + { + DWORD errorCode = NO_ERROR; + UnlockLocked("during reset", &errorCode); + m_handle = handle; + }); + } + + [[nodiscard]] WinHGlobalHandle release() noexcept + { + return WithLock([&]() noexcept { return std::exchange(m_handle, nullptr); }); + } + + [[nodiscard]] WinHGlobalHandle get() const noexcept + { + return WithLock([&]() noexcept { return m_handle; }); + } + + [[nodiscard]] explicit operator bool() const noexcept { return get() != nullptr; } + + private: + void UnlockAndLog(const char* context) noexcept + { + WithLock( + [&]() noexcept + { + DWORD errorCode = NO_ERROR; + UnlockLocked(context, &errorCode); + }); + } + + template + decltype(auto) WithLock(Fn&& fn) const noexcept(noexcept(std::invoke(std::forward(fn)))) + { + MutexGuard lock(m_mutex); + return std::invoke(std::forward(fn)); + } + + template + decltype(auto) WithLock(Fn&& fn) noexcept(noexcept(static_cast(this)->WithLock(std::forward(fn)))) + { + return static_cast(this)->WithLock(std::forward(fn)); + } + + bool UnlockLocked(const char* context, DWORD* failureCode) noexcept + { + const bool ok = UnlockInternal(failureCode); + if (!ok && context && failureCode && *failureCode != NO_ERROR) + OutputDebugLine(SString("[GlobalUnlockGuard] GlobalUnlock %s failed (error %lu)", context, static_cast(*failureCode))); + return ok; + } + + bool UnlockInternal(DWORD* failureCode) noexcept + { + if (!m_handle) + { + if (failureCode) + *failureCode = NO_ERROR; + return true; + } + + SetLastError(NO_ERROR); + const BOOL unlocked = GlobalUnlock(m_handle); + const DWORD lastError = GetLastError(); + const bool failed = (unlocked == 0 && lastError != NO_ERROR); + if (failureCode) + *failureCode = failed ? lastError : NO_ERROR; + m_handle = nullptr; + return !failed; + } + + WinHGlobalHandle m_handle = nullptr; + mutable std::mutex m_mutex; + }; + + [[nodiscard]] inline GlobalUnlockGuard MakeGlobalUnlockGuard(WinHGlobalHandle handle) noexcept + { + return GlobalUnlockGuard(handle); + } + // // Run ShellExecute with these parameters after exit // @@ -146,18 +389,18 @@ namespace SharedUtil // BrowseToSolution flags enum { - EXIT_GAME_FIRST = 1, // Exit from game before showing message - Useful only if game has started and has control of the screen - ASK_GO_ONLINE = 2, // Ask user if he wants to go online (otherwise, always go online) - TERMINATE_IF_YES = 4, // What to do at the end. Only relevant if EXIT_GAME_FIRST is not used - TERMINATE_IF_NO = 8, // '' + EXIT_GAME_FIRST = 1, // Exit from game before showing message - Useful only if game has started and has control of the screen + ASK_GO_ONLINE = 2, // Ask user if he wants to go online (otherwise, always go online) + TERMINATE_IF_YES = 4, // What to do at the end. Only relevant if EXIT_GAME_FIRST is not used + TERMINATE_IF_NO = 8, // '' TERMINATE_IF_YES_OR_NO = TERMINATE_IF_YES | TERMINATE_IF_NO, TERMINATE_PROCESS = TERMINATE_IF_YES_OR_NO, - ICON_ERROR = 0x10, // MB_ICONERROR - ICON_QUESTION = 0x20, // MB_ICONQUESTION - ICON_WARNING = 0x30, // MB_ICONWARNING - ICON_INFO = 0x40, // MB_ICONINFORMATION + ICON_ERROR = 0x10, // MB_ICONERROR + ICON_QUESTION = 0x20, // MB_ICONQUESTION + ICON_WARNING = 0x30, // MB_ICONWARNING + ICON_INFO = 0x40, // MB_ICONINFORMATION ICON_MASK_VALUE = ICON_ERROR | ICON_QUESTION | ICON_WARNING | ICON_INFO, - SHOW_MESSAGE_ONLY = 0x80, // Just show message without going online + SHOW_MESSAGE_ONLY = 0x80, // Just show message without going online }; void BrowseToSolution(const SString& strType, int uiFlags = 0, const SString& strMessageBoxMessage = "", const SString& strErrorCode = ""); bool ProcessPendingBrowseToSolution(); @@ -215,8 +458,6 @@ namespace SharedUtil SString UnescapeString(const SString& strText, char cSpecialChar = '#'); SString EscapeURLArgument(const SString& strText); - SString ExpandEnvString(const SString& strInput); - // Version string things bool IsValidVersionString(const SString& strVersion); SString ExtractVersionStringBuildNumber(const SString& strVersion); @@ -230,6 +471,10 @@ namespace SharedUtil // string stuff // +#if __cplusplus >= 201703L // C++17 + std::string UTF8FilePath(const std::filesystem::path& input); +#endif + std::wstring MbUTF8ToUTF16(const SString& s); std::string UTF16ToMbUTF8(const std::wstring& ws); @@ -285,7 +530,10 @@ namespace SharedUtil } // Unlerp avoiding extrapolation - inline const float UnlerpClamped(const double dFrom, const double dPos, const double dTo) { return Clamp(0.0f, Unlerp(dFrom, dPos, dTo), 1.0f); } + inline const float UnlerpClamped(const double dFrom, const double dPos, const double dTo) + { + return Clamp(0.0f, Unlerp(dFrom, dPos, dTo), 1.0f); + } template int Round(T value) @@ -415,6 +663,24 @@ namespace SharedUtil } } + // Remove all occurrences of item from unordered itemList (swap-and-pop) + // Only use when element order within the vector does not matter. + template + void ListRemoveUnordered(std::vector& itemList, const T& item) + { + for (std::size_t i = 0; i < itemList.size();) + { + if (item == itemList[i]) + { + if (i != itemList.size() - 1) + itemList[i] = std::move(itemList.back()); + itemList.pop_back(); + } + else + ++i; + } + } + // Remove item at index from itemList template void ListRemoveIndex(std::vector& itemList, uint index) @@ -539,15 +805,39 @@ namespace SharedUtil // typedef SColor RGBA; - inline unsigned char COLOR_RGBA_R(SColor color) { return color.R; } - inline unsigned char COLOR_RGBA_G(SColor color) { return color.G; } - inline unsigned char COLOR_RGBA_B(SColor color) { return color.B; } - inline unsigned char COLOR_RGBA_A(SColor color) { return color.A; } - inline unsigned char COLOR_ARGB_A(SColor color) { return color.A; } + inline unsigned char COLOR_RGBA_R(SColor color) + { + return color.R; + } + inline unsigned char COLOR_RGBA_G(SColor color) + { + return color.G; + } + inline unsigned char COLOR_RGBA_B(SColor color) + { + return color.B; + } + inline unsigned char COLOR_RGBA_A(SColor color) + { + return color.A; + } + inline unsigned char COLOR_ARGB_A(SColor color) + { + return color.A; + } - inline SColor COLOR_RGBA(unsigned char R, unsigned char G, unsigned char B, unsigned char A) { return SColorRGBA(R, G, B, A); } - inline SColor COLOR_ARGB(unsigned char A, unsigned char R, unsigned char G, unsigned char B) { return SColorRGBA(R, G, B, A); } - inline SColor COLOR_ABGR(unsigned char A, unsigned char B, unsigned char G, unsigned char R) { return SColorRGBA(R, G, B, A); } + inline SColor COLOR_RGBA(unsigned char R, unsigned char G, unsigned char B, unsigned char A) + { + return SColorRGBA(R, G, B, A); + } + inline SColor COLOR_ARGB(unsigned char A, unsigned char R, unsigned char G, unsigned char B) + { + return SColorRGBA(R, G, B, A); + } + inline SColor COLOR_ABGR(unsigned char A, unsigned char B, unsigned char G, unsigned char R) + { + return SColorRGBA(R, G, B, A); + } // // Convert tocolor value to SColor @@ -595,9 +885,8 @@ namespace SharedUtil CCriticalSection& m_CS; }; - // Macro for instantiating automatic critical section locking procedure - #define LOCK_SCOPE( cs ) \ - volatile CAutoCSLock _lock ( cs ) +// Macro for instantiating automatic critical section locking procedure +#define LOCK_SCOPE(cs) volatile CAutoCSLock _lock(cs) // // Expiry stuff @@ -749,16 +1038,16 @@ namespace SharedUtil void RemoveMultiValues(); SString Escape(const SString& strIn) const; SString Unescape(const SString& strIn) const; - void Set(const SString& strInCmd, const SString& strInValue); // Set a unique key string value - void Set(const SString& strInCmd, int iValue); // Set a unique key int value - void Insert(const SString& strInCmd, int iValue); // Insert a key int value - void Insert(const SString& strInCmd, const SString& strInValue); // Insert a key string value - bool Contains(const SString& strInCmd) const; // Test if key exists - bool Get(const SString& strInCmd, SString& strOut, const char* szDefault = "") const; // First result as string - SString Get(const SString& strInCmd) const; // First result as string - bool Get(const SString& strInCmd, std::vector& outList) const; // All results as strings - bool Get(const SString& strInCmd, int& iValue, int iDefault = 0) const; // First result as int - void GetKeys(std::vector& outList) const; // All keys + void Set(const SString& strInCmd, const SString& strInValue); // Set a unique key string value + void Set(const SString& strInCmd, int iValue); // Set a unique key int value + void Insert(const SString& strInCmd, int iValue); // Insert a key int value + void Insert(const SString& strInCmd, const SString& strInValue); // Insert a key string value + bool Contains(const SString& strInCmd) const; // Test if key exists + bool Get(const SString& strInCmd, SString& strOut, const char* szDefault = "") const; // First result as string + SString Get(const SString& strInCmd) const; // First result as string + bool Get(const SString& strInCmd, std::vector& outList) const; // All results as strings + bool Get(const SString& strInCmd, int& iValue, int iDefault = 0) const; // First result as int + void GetKeys(std::vector& outList) const; // All keys }; // Some templated accessors for CArgMap derived classes @@ -929,16 +1218,16 @@ namespace SharedUtil }; template - class CMappedList : public CMappedContainer > + class CMappedList : public CMappedContainer> { }; template - class CMappedArray : public CMappedContainer > + class CMappedArray : public CMappedContainer> { public: - const T& operator[](int idx) const { return CMappedContainer >::m_List[idx]; } - T& operator[](int idx) { return CMappedContainer >::m_List[idx]; } + const T& operator[](int idx) const { return CMappedContainer>::m_List[idx]; } + T& operator[](int idx) { return CMappedContainer>::m_List[idx]; } }; // Returns true if the item is in the itemList @@ -984,7 +1273,7 @@ namespace SharedUtil CIntrusiveListNode(T* pOuterItem) : m_pOuterItem(pOuterItem), m_pPrev(NULL), m_pNext(NULL) {} - T* m_pOuterItem; // Item this node is inside + T* m_pOuterItem; // Item this node is inside Node* m_pPrev; Node* m_pNext; }; @@ -999,7 +1288,7 @@ namespace SharedUtil template class CIntrusiveList { - void operator=(const CIntrusiveList& other); // Copy will probably not work as expected + void operator=(const CIntrusiveList& other); // Copy will probably not work as expected // CIntrusiveList ( const CIntrusiveList& other ); // Default copy constructor is required by dense_hash for some reason public: @@ -1011,8 +1300,8 @@ namespace SharedUtil size_t m_Size; Node* m_pFirst; Node* m_pLast; - Node T::* m_pNodePtr; // Pointer to the CIntrusiveListNode member variable in T - std::vector m_ActiveIterators; // Keep track of iterators + Node T::* m_pNodePtr; // Pointer to the CIntrusiveListNode member variable in T + std::vector m_ActiveIterators; // Keep track of iterators public: // @@ -1070,9 +1359,9 @@ namespace SharedUtil // // Constructor // - CIntrusiveList(Node T::*pNodePtr) : m_pNodePtr(pNodePtr) + CIntrusiveList(Node T::* pNodePtr) : m_pNodePtr(pNodePtr) { - assert(m_pNodePtr); // This must be set upon construction + assert(m_pNodePtr); // This must be set upon construction m_Size = 0; m_pFirst = NULL; m_pLast = NULL; @@ -1101,7 +1390,7 @@ namespace SharedUtil Node* pNode = &(pItem->*m_pNodePtr); if (!pNode->m_pPrev && !pNode->m_pNext && m_pFirst != pNode) - return; // Not in list + return; // Not in list // Keep active iterators valid for (int i = m_ActiveIterators.size() - 1; i >= 0; i--) @@ -1198,9 +1487,9 @@ namespace SharedUtil // Allow use of std iterator names typedef Iterator iterator; - typedef Iterator const_iterator; // TODO + typedef Iterator const_iterator; // TODO typedef ReverseIterator reverse_iterator; - typedef ReverseIterator const_reverse_iterator; // TODO + typedef ReverseIterator const_reverse_iterator; // TODO }; /////////////////////////////////////////////////////////////// @@ -1210,7 +1499,7 @@ namespace SharedUtil // Uses the member variable pointer declared in the template // /////////////////////////////////////////////////////////////// - template T::*member_ptr> + template T::* member_ptr> class CIntrusiveListExt : public CIntrusiveList { public: @@ -1310,42 +1599,54 @@ namespace SharedUtil const SString& GetTypeName() const { return m_strTypeName; } - SString m_strTypeName; - SString m_strDefaultName; - T m_DefaultValue; - std::map m_ValueMap; - std::map m_NameMap; + SString m_strTypeName; + SString m_strDefaultName; + T m_DefaultValue; + std::map m_ValueMap; + std::map m_NameMap; }; - #define DECLARE_ENUM(T) \ - CEnumInfo* GetEnumInfo ( const T* ); \ - inline const SString& EnumToString ( const T& value ) { return GetEnumInfo ( (T*)0 )->FindName ( value ); }\ - inline bool StringToEnum ( const SString& strName, T& outResult ) { return GetEnumInfo ( (T*)0 )->FindValue ( strName, outResult ); }\ - inline const SString& GetEnumTypeName ( const T& ) { return GetEnumInfo ( (T*)0 )->GetTypeName (); }\ - inline bool EnumValueValid ( const T& value ) { return GetEnumInfo ( (T*)0 )->ValueValid ( value ); }\ - - #define IMPLEMENT_ENUM_BEGIN(T) \ - CEnumInfo* GetEnumInfo( const T* ) \ - { \ - using CEnumInfo = CEnumInfo; \ - static const CEnumInfo::SEnumItem items[] = { - - #define IMPLEMENT_ENUM_END(name) \ - IMPLEMENT_ENUM_END_DEFAULTS(name, static_cast().iValue)>>(0), "") +#define DECLARE_ENUM(T) \ + CEnumInfo* GetEnumInfo(const T*); \ + inline const SString& EnumToString(const T& value) \ + { \ + return GetEnumInfo((T*)0)->FindName(value); \ + } \ + inline bool StringToEnum(const SString& strName, T& outResult) \ + { \ + return GetEnumInfo((T*)0)->FindValue(strName, outResult); \ + } \ + inline const SString& GetEnumTypeName(const T&) \ + { \ + return GetEnumInfo((T*)0)->GetTypeName(); \ + } \ + inline bool EnumValueValid(const T& value) \ + { \ + return GetEnumInfo((T*)0)->ValueValid(value); \ + } - #define IMPLEMENT_ENUM_END_DEFAULTS(name,defvalue,defname) \ - }; \ - static CEnumInfo info(name, items, NUMELMS(items), defvalue, defname); \ - return &info; \ - } +#define IMPLEMENT_ENUM_BEGIN(T) \ + CEnumInfo* GetEnumInfo(const T*) \ + { \ + using CEnumInfo = CEnumInfo; \ + static const CEnumInfo::SEnumItem items[] = { +#define IMPLEMENT_ENUM_END(name) \ + IMPLEMENT_ENUM_END_DEFAULTS(name, static_cast().iValue)>>(0), "") + +#define IMPLEMENT_ENUM_END_DEFAULTS(name, defvalue, defname) \ + } \ + ; \ + static CEnumInfo info(name, items, NUMELMS(items), defvalue, defname); \ + return &info; \ + } - #define ADD_ENUM(value,name) {value, name}, - #define ADD_ENUM1(value) {value, #value}, +#define ADD_ENUM(value, name) {value, name}, +#define ADD_ENUM1(value) {value, #value}, - // enum class - #define DECLARE_ENUM_CLASS(T) DECLARE_ENUM(T) - #define IMPLEMENT_ENUM_CLASS_BEGIN(T) IMPLEMENT_ENUM_BEGIN(T) - #define IMPLEMENT_ENUM_CLASS_END(name) IMPLEMENT_ENUM_END(name) +// enum class +#define DECLARE_ENUM_CLASS(T) DECLARE_ENUM(T) +#define IMPLEMENT_ENUM_CLASS_BEGIN(T) IMPLEMENT_ENUM_BEGIN(T) +#define IMPLEMENT_ENUM_CLASS_END(name) IMPLEMENT_ENUM_END(name) // // Fast wildcard matching @@ -1470,7 +1771,10 @@ namespace SharedUtil } } - inline void ReadCommaSeparatedList(const SString& strInput, std::vector& outList) { return ReadTokenSeparatedList(",", strInput, outList); } + inline void ReadCommaSeparatedList(const SString& strInput, std::vector& outList) + { + return ReadTokenSeparatedList(",", strInput, outList); + } /////////////////////////////////////////////////////////////// // @@ -1560,7 +1864,7 @@ namespace SharedUtil class CRefCountable { int m_iRefCount; - CCriticalSection* m_pCS; // Use a pointer incase the static variable exists more than once + CCriticalSection* m_pCS; // Use a pointer incase the static variable exists more than once static CCriticalSection ms_CS; protected: @@ -1627,9 +1931,8 @@ namespace SharedUtil } }; - // Use this macro if the size of the initializer list is unknown - #define IMPLEMENT_FIXED_ARRAY( vartype, varname ) \ - SFixedArrayInit < vartype, NUMELMS( _##varname ) > varname ( _##varname, NUMELMS( _##varname ) ) +// Use this macro if the size of the initializer list is unknown +#define IMPLEMENT_FIXED_ARRAY(vartype, varname) SFixedArrayInit varname(_##varname, NUMELMS(_##varname)) // // Ranges of numbers. i.e. 100-4000, 5000-6999, 7000-7010 @@ -1639,7 +1942,7 @@ namespace SharedUtil public: void SetRange(uint uiStart, uint uiLength); void UnsetRange(uint uiStart, uint uiLength); - bool IsRangeSet(uint uiStart, uint uiLength); // Returns true if any part of the range already exists in the map + bool IsRangeSet(uint uiStart, uint uiLength); // Returns true if any part of the range already exists in the map protected: typedef std::map::iterator IterType; @@ -1657,11 +1960,11 @@ namespace SharedUtil class CRefedPointer : public CRefCountable { private: - T* pData; // Target + T* pData; // Target virtual ~CRefedPointer() { SAFE_DELETE(pData); } CRefedPointer(const CRefedPointer& other); - CRefedPointer& operator=(const CRefedPointer& other); + CRefedPointer& operator*(const CRefedPointer& other); public: CRefedPointer() { pData = new T(); } @@ -1692,7 +1995,7 @@ namespace SharedUtil CAutoRefedPointer& operator=(const CAutoRefedPointer& other) { // Assignment operator - if (this != &other) // Avoid self assignment + if (this != &other) // Avoid self assignment { CRefedPointer* pOldPointer = pPointer; @@ -1711,7 +2014,7 @@ namespace SharedUtil const T* operator->() const { return pPointer->GetData(); } }; -}; // namespace SharedUtil +}; // namespace SharedUtil using namespace SharedUtil; diff --git a/Shared/sdk/SharedUtil.Misc.hpp b/Shared/sdk/SharedUtil.Misc.hpp index 4478d223d93..0c9c8d5a724 100644 --- a/Shared/sdk/SharedUtil.Misc.hpp +++ b/Shared/sdk/SharedUtil.Misc.hpp @@ -11,31 +11,283 @@ #include "SharedUtil.Misc.h" #include "SharedUtil.Time.h" +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) || defined(WIN32) + #define SHAREDUTIL_PLATFORM_WINDOWS 1 +#endif + +#if defined(__linux__) || defined(LINUX_x86) || defined(LINUX_x64) || defined(LINUX_arm) || defined(LINUX_arm64) + #include + #include + #include + #include + #include +#endif + +#if defined(__APPLE__) || defined(APPLE_x64) || defined(APPLE_arm64) + #include + #include +#endif + #include "UTF8.h" #include "UTF8Detect.hpp" #include "CDuplicateLineFilter.h" #include "version.h" -#ifdef WIN32 - #include + +namespace SharedUtil::Details +{ + constexpr size_t kMaxClipboardBytes = 100u * 1024u * 1024u; + constexpr size_t kMaxClipboardChars = kMaxClipboardBytes / sizeof(wchar_t); + + inline std::mutex& ClipboardMutex() noexcept + { + static std::mutex mutex; + return mutex; + } +} + +#if defined(SHAREDUTIL_PLATFORM_WINDOWS) + #ifndef NOMINMAX + #define NOMINMAX + #endif #include + #include #include #include #include #include + #ifdef GetModuleBaseName + #undef GetModuleBaseName + #endif + #ifdef GetModuleBaseNameA + #undef GetModuleBaseNameA + #endif + #ifdef GetModuleBaseNameW + #undef GetModuleBaseNameW + #endif + + #if defined(_MSVC_LANG) && _MSVC_LANG >= 201703L + #include + #endif + +struct HKeyDeleter +{ + void operator()(HKEY hk) const noexcept { RegCloseKey(hk); } +}; +using UniqueHKey = std::unique_ptr, HKeyDeleter>; + +namespace SharedUtil::Details +{ + class UniqueHGlobal + { + public: + UniqueHGlobal() noexcept = default; + explicit UniqueHGlobal(HGLOBAL value) noexcept : m_handle(value) {} + ~UniqueHGlobal() { reset(); } + + UniqueHGlobal(const UniqueHGlobal&) = delete; + UniqueHGlobal& operator=(const UniqueHGlobal&) = delete; + + UniqueHGlobal(UniqueHGlobal&& other) noexcept : m_handle(other.release()) {} + + UniqueHGlobal& operator=(UniqueHGlobal&& other) noexcept + { + if (this != &other) + reset(other.release()); + return *this; + } + + void reset(HGLOBAL value = nullptr) noexcept + { + if (m_handle) + GlobalFree(m_handle); + m_handle = value; + } + + [[nodiscard]] HGLOBAL get() const noexcept { return m_handle; } + + [[nodiscard]] HGLOBAL release() noexcept { return std::exchange(m_handle, nullptr); } + + [[nodiscard]] explicit operator bool() const noexcept { return m_handle != nullptr; } + + private: + HGLOBAL m_handle = nullptr; + }; +} // namespace SharedUtil::Details + +static void InitializeProcessBaseDir(SString& strProcessBaseDir) +{ + try + { + constexpr auto bufferSize = MAX_PATH * 2; + constexpr auto MAX_UNICODE_PATH = 32767; + auto coreFileName = std::array{}; + + // Get core.dll module handle to determine base directory + // Try debug build first (core_d.dll), then release build (core.dll) + constexpr auto coreDllDebug = std::wstring_view{L"core_d.dll"}; + constexpr auto coreDllRelease = std::wstring_view{L"core.dll"}; + + auto hCoreModule = HMODULE{}; + auto bCoreModuleFound = bool{false}; + #ifdef MTA_DEBUG + if (bCoreModuleFound = GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, coreDllDebug.data(), &hCoreModule); !bCoreModuleFound) + #endif + bCoreModuleFound = GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, coreDllRelease.data(), &hCoreModule); + + // Fallback: Use current module if core.dll isn't loaded yet + if (!hCoreModule) + { + GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + reinterpret_cast(&InitializeProcessBaseDir), &hCoreModule); + } + + if (hCoreModule) + { + if (DWORD lengthCore = GetModuleFileNameW(hCoreModule, coreFileName.data(), static_cast(coreFileName.size())); lengthCore > 0) + { + // Use std::wstring for flexible buffer management + auto corePathBuffer = std::wstring{coreFileName.data(), static_cast(lengthCore)}; + + // If buffer too small, resize for long path support + if (const auto bufferTooSmall = (static_cast(lengthCore) == coreFileName.size()); bufferTooSmall) + { + corePathBuffer.resize(MAX_UNICODE_PATH); + + if (lengthCore = GetModuleFileNameW(hCoreModule, corePathBuffer.data(), static_cast(corePathBuffer.size())); + lengthCore > 0 && static_cast(lengthCore) < corePathBuffer.size()) + { + corePathBuffer.resize(lengthCore); + } + else + { + return; // Long path retrieval failed + } + } + + auto fullPath = std::array{}; + + if (DWORD lengthFull = GetFullPathNameW(corePathBuffer.c_str(), static_cast(fullPath.size()), fullPath.data(), nullptr); lengthFull > 0) + { + // Process path and extract base directory + // The directory above /MTA/ is always the base directory + const auto processPath = [&strProcessBaseDir](const std::wstring_view fullPathStr) + { + if (const auto lastSeparator = fullPathStr.find_last_of(L"\\/"); lastSeparator != std::wstring_view::npos) + { + const auto moduleDir = fullPathStr.substr(0, lastSeparator); + auto currentPath = std::filesystem::path(moduleDir); + + // Walk up to find MTA/ folder + // Stop at first MTA folder found - it's guaranteed to be the correct one + // Check current directory and up to 2 parent levels + for (auto level = 0; level < 3; ++level) + { + auto folderName = currentPath.filename().wstring(); + + // Convert to lowercase for case-insensitive comparison + std::transform(folderName.begin(), folderName.end(), folderName.begin(), ::towlower); + + if (folderName == L"mta") + { + const SString strCurrentPath = ToUTF8(currentPath.wstring()); + const bool bHasKnownModule = + FileExists(PathJoin(strCurrentPath, "core.dll")) || FileExists(PathJoin(strCurrentPath, "core_d.dll")) || + FileExists(PathJoin(strCurrentPath, "loader.dll")) || FileExists(PathJoin(strCurrentPath, "loader_d.dll")); + + if (!bHasKnownModule) + { + if (currentPath.has_parent_path()) + currentPath = currentPath.parent_path(); + else + break; + continue; + } + + // Found MTA folder - base directory is its parent + // Stop searching immediately to avoid finding outer "MTA" folders (e.g user with custom intall dir) + if (currentPath.has_parent_path()) + { + strProcessBaseDir = ToUTF8(currentPath.parent_path().wstring()); + } + return; // Always stop at first MTA folder found + } + + // Move up one level + if (currentPath.has_parent_path()) + currentPath = currentPath.parent_path(); + else + break; // Reached root, can't go further + } + } + }; + + // If buffer too small, resize for long path support + if (auto fullPathBuffer = std::wstring{}; static_cast(lengthFull) > fullPath.size()) + { + if (static_cast(lengthFull) > MAX_UNICODE_PATH) + return; // Path too long, validation failed + + fullPathBuffer.resize(static_cast(lengthFull)); + if (lengthFull = GetFullPathNameW(corePathBuffer.c_str(), static_cast(fullPathBuffer.size()), fullPathBuffer.data(), nullptr); + lengthFull > 0 && static_cast(lengthFull) < fullPathBuffer.size()) + { + processPath(std::wstring_view(fullPathBuffer.data(), static_cast(lengthFull))); + } + } + else + { + processPath(std::wstring_view(fullPath.data(), static_cast(lengthFull))); + } + } + } + } + } + catch (...) + { + } +} + +[[nodiscard]] const SString& SharedUtil::GetMTAProcessBaseDir() +{ + static auto strProcessBaseDir = SString{}; + static auto initFlag = std::once_flag{}; + + std::call_once(initFlag, InitializeProcessBaseDir, std::ref(strProcessBaseDir)); + + return strProcessBaseDir; +} + #else #include #ifndef _GNU_SOURCE - # define _GNU_SOURCE /* See feature_test_macros(7) */ + #define _GNU_SOURCE /* See feature_test_macros(7) */ #endif #include #include #include #ifndef RUSAGE_THREAD - #define RUSAGE_THREAD 1 /* only the calling thread */ + #define RUSAGE_THREAD 1 /* only the calling thread */ #endif #endif +#if __cplusplus >= 201703L // C++17 + #include +#endif + #if defined(__APPLE__) && !defined(__aarch64__) #include #endif @@ -57,15 +309,15 @@ CDuplicateLineFilter ms_ReportLineFilter; #ifdef MTA_CLIENT -#define PRODUCT_REGISTRY_PATH "Software\\Multi Theft Auto: San Andreas All" // HKLM -#define PRODUCT_COMMON_DATA_DIR "MTA San Andreas All" // C:\ProgramData -#define TROUBLE_URL1 "https://help.multitheftauto.com/sa/trouble/?v=_VERSION_&id=_ID_&tr=_TROUBLE_" + #define PRODUCT_REGISTRY_PATH "Software\\Multi Theft Auto: San Andreas All" // HKLM + #define PRODUCT_COMMON_DATA_DIR "MTA San Andreas All" // C:\ProgramData + #define TROUBLE_URL1 "https://help.multitheftauto.com/sa/trouble/?v=_VERSION_&id=_ID_&tr=_TROUBLE_" -// -// Output a UTF8 encoded messagebox -// Used in the Win32 Client only -// -#ifdef _WINDOWS_ //Only for modules that use windows.h + // + // Output a UTF8 encoded messagebox + // Used in the Win32 Client only + // + #ifdef _WINDOWS_ // Only for modules that use windows.h int SharedUtil::MessageBoxUTF8(HWND hWnd, SString lpText, SString lpCaption, UINT uType) { // Default to warning icon @@ -78,7 +330,7 @@ int SharedUtil::MessageBoxUTF8(HWND hWnd, SString lpText, SString lpCaption, UIN WString strCaption = MbUTF8ToUTF16(lpCaption); return MessageBoxW(hWnd, strText.c_str(), strCaption.c_str(), uType); } -#endif + #endif // // Return full path and filename of parent exe @@ -97,15 +349,21 @@ SString SharedUtil::GetParentProcessPathFilename(int pid) if (hProcess) { WCHAR szModuleName[MAX_PATH * 2] = {0}; - GetModuleFileNameExW(hProcess, nullptr, szModuleName, NUMELMS(szModuleName)); + DWORD dwSize = GetModuleFileNameExW(hProcess, nullptr, szModuleName, NUMELMS(szModuleName) - 1); CloseHandle(hProcess); - SString strModuleName = ToUTF8(szModuleName); - if (FileExists(strModuleName)) + + if (dwSize > 0) { - CloseHandle(hSnapshot); - if (IsShortPathName(strModuleName)) - return GetSystemLongPathName(strModuleName); - return strModuleName; + // Ensure null termination + szModuleName[std::min(dwSize, (DWORD)(NUMELMS(szModuleName) - 1))] = L'\0'; + SString strModuleName = ToUTF8(szModuleName); + if (FileExists(strModuleName)) + { + CloseHandle(hSnapshot); + if (IsShortPathName(strModuleName)) + return GetSystemLongPathName(strModuleName); + return strModuleName; + } } } } @@ -115,30 +373,135 @@ SString SharedUtil::GetParentProcessPathFilename(int pid) return ""; } +// +// Set the MTASA base dir manually +// +static SString strInstallRootOverride; + +void SharedUtil::SetMTASABaseDirOverride(const SString& strPath) +{ + strInstallRootOverride = strPath; +} + +static bool IsUsableMtasaInstallRoot(const SString& strPath) +{ + if (strPath.empty()) + return false; + + return FileExists(PathJoin(strPath, "Multi Theft Auto.exe")) || FileExists(PathJoin(strPath, "Multi Theft Auto_d.exe")) || + FileExists(PathJoin(strPath, "mta", "core.dll")) || FileExists(PathJoin(strPath, "MTA", "core.dll")) || + FileExists(PathJoin(strPath, "mta", "core_d.dll")) || FileExists(PathJoin(strPath, "MTA", "core_d.dll")); +} + +static SString ReadInstallRootRegistryValue64() +{ + #if defined(KEY_WOW64_64KEY) + const WString wstrSubKey = FromUTF8(PathJoin(GetProductRegistryPath(), GetMajorVersionString()).TrimEnd("\\")); + const WString wstrValue = FromUTF8("Last Run Location"); + + HKEY hkTemp = NULL; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, wstrSubKey, 0, KEY_READ | KEY_WOW64_64KEY, &hkTemp) != ERROR_SUCCESS || !hkTemp) + return ""; + + DWORD dwType = REG_SZ; + DWORD dwSize = 0; + LONG result = RegQueryValueExW(hkTemp, wstrValue, NULL, &dwType, NULL, &dwSize); + if (result != ERROR_SUCCESS || (dwType != REG_SZ && dwType != REG_EXPAND_SZ) || dwSize == 0) + { + RegCloseKey(hkTemp); + return ""; + } + + std::vector buffer((dwSize / sizeof(wchar_t)) + 1u, L'\0'); + result = RegQueryValueExW(hkTemp, wstrValue, NULL, &dwType, reinterpret_cast(buffer.data()), &dwSize); + RegCloseKey(hkTemp); + + if (result != ERROR_SUCCESS || (dwType != REG_SZ && dwType != REG_EXPAND_SZ)) + return ""; + + if (dwSize >= sizeof(wchar_t)) + buffer[(dwSize / sizeof(wchar_t)) - 1u] = L'\0'; + else + buffer[0] = L'\0'; + + return ToUTF8(buffer.data()); + #else + return ""; + #endif +} + // // Get startup directory as saved in the registry by the launcher // Used in the Win32 Client only // SString SharedUtil::GetMTASABaseDir() { + if (!strInstallRootOverride.empty()) + return strInstallRootOverride; + static SString strInstallRoot; + static SString strInstallRootSource; if (strInstallRoot.empty()) { if (IsGTAProcess()) { // Try to get base dir from parent process - strInstallRoot = ExtractPath(GetParentProcessPathFilename(GetCurrentProcessId())); + SString strParentDir = ExtractPath(GetParentProcessPathFilename(GetCurrentProcessId())); + if (FileExists(PathJoin(strParentDir, "mta", "core.dll")) || FileExists(PathJoin(strParentDir, "MTA", "core.dll"))) + { + strInstallRoot = strParentDir; + strInstallRootSource = "parent process"; + } + } + if (strInstallRoot.empty()) + { + HMODULE hCoreModule = nullptr; + #ifdef MTA_DEBUG + if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L"core_d.dll", &hCoreModule)) + #endif + GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L"core.dll", &hCoreModule); + + if (hCoreModule) + { + strInstallRoot = GetMTAProcessBaseDir(); + if (!strInstallRoot.empty()) + strInstallRootSource = "loaded core module"; + } } if (strInstallRoot.empty()) { strInstallRoot = GetRegistryValue("", "Last Run Location"); + if (!IsUsableMtasaInstallRoot(strInstallRoot)) + { + const SString strRegistry32InstallRoot = strInstallRoot; + const SString strRegistry64InstallRoot = ReadInstallRootRegistryValue64(); + if (IsUsableMtasaInstallRoot(strRegistry64InstallRoot)) + { + strInstallRoot = strRegistry64InstallRoot; + strInstallRootSource = "registry64"; + } + else + { + if (!strRegistry32InstallRoot.empty()) + { + AddReportLog(1042, SString("GetMTASABaseDir: ignoring unusable registry path '%s'", strRegistry32InstallRoot.c_str()), 1); + } + strInstallRoot.clear(); + } + } if (strInstallRoot.empty()) { + AddReportLog(1042, "GetMTASABaseDir: unable to resolve install root", 1); MessageBoxUTF8(0, _("Multi Theft Auto has not been installed properly, please reinstall."), _("Error") + _E("U01"), MB_OK | MB_ICONERROR | MB_TOPMOST); TerminateProcess(GetCurrentProcess(), 9); } + if (strInstallRootSource.empty()) + strInstallRootSource = "registry"; } + + if (!strInstallRoot.empty()) + AddReportLog(1042, SString("GetMTASABaseDir: resolved '%s' via %s", strInstallRoot.c_str(), strInstallRootSource.c_str()), 1); } return strInstallRoot; } @@ -157,8 +520,162 @@ SString SharedUtil::CalcMTASAPath(const SString& strPath) // bool SharedUtil::IsGTAProcess() { + static int iResult = -1; + if (iResult != -1) + return iResult != 0; + SString strLaunchPathFilename = GetLaunchPathFilename(); - return strLaunchPathFilename.EndsWithI("gta_sa.exe"); + SString strExecutable = ExtractFilename(strLaunchPathFilename); + + if (strExecutable.EndsWithI("gta_sa.exe")) + { + iResult = 1; + return true; + } + + if (strExecutable.EndsWithI("Multi Theft Auto.exe")) + { + iResult = 0; + return false; + } + + SString strBaseDir = ExtractPath(strLaunchPathFilename); + if (FileExists(PathJoin(strBaseDir, "models", "gta3.img")) || FileExists(PathJoin(strBaseDir, "data", "gta3.dat"))) + { + iResult = 1; + return true; + } + + iResult = 0; + return false; +} + +bool SharedUtil::IsReadablePointer(const void* ptr, size_t size) +{ + // Guard against null or overflow before touching platform APIs + if (!ptr || size == 0) + return false; + + const uintptr_t start = reinterpret_cast(ptr); + constexpr uintptr_t maxAddress = std::numeric_limits::max(); + if (size > maxAddress - start) + return false; + + const uintptr_t end = start + size; + + #ifdef SHAREDUTIL_PLATFORM_WINDOWS + constexpr DWORD readableMask = PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY; + for (uintptr_t current = start; current < end;) + { + MEMORY_BASIC_INFORMATION mbi{}; + if (VirtualQuery(reinterpret_cast(current), &mbi, sizeof(mbi)) == 0) + return false; + + const uintptr_t regionStart = reinterpret_cast(mbi.BaseAddress); + const uintptr_t regionSize = static_cast(mbi.RegionSize); + const uintptr_t regionEnd = regionStart + regionSize; + const DWORD protection = mbi.Protect; + if (regionSize == 0 || current < regionStart || regionStart > maxAddress - regionSize || regionEnd <= current || mbi.State != MEM_COMMIT || + (protection & PAGE_GUARD) || (protection & readableMask) == 0) + return false; + + current = regionEnd; + } + + return true; + #elif defined(LINUX_x86) || defined(LINUX_x64) || defined(LINUX_arm) || defined(LINUX_arm64) + static_assert(sizeof(uintptr_t) <= sizeof(unsigned long long), "Unexpected uintptr_t size"); + + std::ifstream maps("/proc/self/maps"); + if (!maps.is_open()) + return false; + + const auto parseAddress = [maxAddress](const std::string& token, uintptr_t& out) -> bool + { + errno = 0; + char* endPtr = nullptr; + unsigned long long value = std::strtoull(token.c_str(), &endPtr, 16); + if (errno != 0 || endPtr == token.c_str() || *endPtr != '\0' || value > maxAddress) + return false; + out = static_cast(value); + return true; + }; + + uintptr_t coverage = start; + bool coveringRange = false; + for (std::string line; std::getline(maps, line);) + { + if (line.empty()) + continue; + std::istringstream iss(line); + std::string range, perms; + if (!(iss >> range >> perms)) + continue; + const size_t dashPos = range.find('-'); + if (dashPos == std::string::npos) + continue; + uintptr_t regionStart = 0; + uintptr_t regionEnd = 0; + if (!parseAddress(range.substr(0, dashPos), regionStart) || !parseAddress(range.substr(dashPos + 1), regionEnd)) + continue; + if (regionEnd <= regionStart || regionEnd <= coverage) + continue; + if (coveringRange) + { + if (regionStart > coverage) + return false; + } + else if (regionStart > coverage || coverage >= regionEnd) + { + continue; + } + else + coveringRange = true; + + if (perms.empty() || perms[0] != 'r') + return false; + coverage = regionEnd; + if (coverage >= end) + return true; + } + + return false; + #elif defined(APPLE_x64) || defined(APPLE_arm64) + mach_vm_address_t queryAddress = static_cast(start); + const mach_vm_address_t targetEnd = static_cast(end); + constexpr mach_vm_address_t maxAddressMac = std::numeric_limits::max(); + vm_region_basic_info_data_64_t info; + mach_msg_type_number_t infoCount = VM_REGION_BASIC_INFO_COUNT_64; + mach_port_t objectName = MACH_PORT_NULL; + + while (queryAddress < targetEnd) + { + mach_vm_size_t regionSize = 0; + infoCount = VM_REGION_BASIC_INFO_COUNT_64; + mach_vm_address_t regionAddress = queryAddress; + kern_return_t kr = mach_vm_region(mach_task_self(), ®ionAddress, ®ionSize, VM_REGION_BASIC_INFO_64, reinterpret_cast(&info), + &infoCount, &objectName); + if (objectName != MACH_PORT_NULL) + { + mach_port_deallocate(mach_task_self(), objectName); + objectName = MACH_PORT_NULL; + } + + if (kr != KERN_SUCCESS || regionSize == 0 || queryAddress < regionAddress || (info.protection & VM_PROT_READ) == 0 || + regionAddress > maxAddressMac - static_cast(regionSize)) + return false; + + const mach_vm_address_t regionEnd = regionAddress + static_cast(regionSize); + if (regionEnd <= queryAddress) + return false; + + queryAddress = regionEnd; + } + + return true; + #else + return false; + #endif } // @@ -186,32 +703,328 @@ static void WriteRegistryStringValue(HKEY hkRoot, const char* szSubKey, const ch // // Read a registry string value // -static SString ReadRegistryStringValue(HKEY hkRoot, const char* szSubKey, const char* szValue, int* iResult) +namespace { - // Clear output - SString strOutResult = ""; + constexpr DWORD kMaxRegistryValueBytes = 1024 * 1024; // Cap to avoid runaway allocations + constexpr DWORD kMinStringAlloc = sizeof(wchar_t); + constexpr DWORD kMinBinaryAlloc = static_cast(sizeof(unsigned long long)); - bool bResult = false; - HKEY hkTemp = NULL; - WString wstrSubKey = FromUTF8(szSubKey); - WString wstrValue = FromUTF8(szValue); - if (RegOpenKeyExW(hkRoot, wstrSubKey, 0, KEY_READ, &hkTemp) == ERROR_SUCCESS) + bool ComputeNextAllocation(DWORD current, DWORD requested, DWORD minimum, DWORD& outNext) { - DWORD dwBufferSize; - if (RegQueryValueExW(hkTemp, wstrValue, NULL, NULL, NULL, &dwBufferSize) == ERROR_SUCCESS) + const ULONGLONG requestedSize = requested != 0 ? static_cast(requested) : static_cast(current) * 2ULL; + const ULONGLONG adjusted = std::max(requestedSize, static_cast(minimum)); + if (adjusted > kMaxRegistryValueBytes) + return false; + outNext = static_cast(adjusted); + return true; + } + + size_t ComputeWideBufferCapacity(DWORD bytes) + { + const size_t rounded = static_cast(bytes) + (sizeof(wchar_t) - 1u); + return (rounded / sizeof(wchar_t)) + 1u; // +1 for null terminator + } + + WString CollapseMultiSz(const wchar_t* data, size_t wcharCount) + { + const wchar_t* current = data; + const wchar_t* end = current + wcharCount; + WString combined; + while (current < end && *current != L'\0') { - CScopeAlloc szBuffer(dwBufferSize + sizeof(wchar_t)); - if (RegQueryValueExW(hkTemp, wstrValue, NULL, NULL, (LPBYTE)(wchar_t*)szBuffer, &dwBufferSize) == ERROR_SUCCESS) + if (!combined.empty()) + combined.push_back(L'\n'); + const wchar_t* segmentEnd = current; + while (segmentEnd < end && *segmentEnd != L'\0') + ++segmentEnd; + combined.append(current, static_cast(segmentEnd - current)); + current = segmentEnd; + if (current >= end) + break; + ++current; + } + return combined; + } + + SString ExpandEnvironmentToUtf8(const wchar_t* raw) + { + const DWORD expandedChars = ExpandEnvironmentStringsW(raw, NULL, 0); + const DWORD maxExpandChars = kMaxRegistryValueBytes / sizeof(wchar_t); + if (expandedChars > 0 && expandedChars <= maxExpandChars) + { + std::vector expanded(expandedChars, L'\0'); + if (ExpandEnvironmentStringsW(raw, expanded.data(), expandedChars)) { - szBuffer[dwBufferSize / sizeof(wchar_t)] = 0; - strOutResult = ToUTF8((wchar_t*)szBuffer); - bResult = true; + WString expandedString; + expandedString.assign(expanded.data()); + return ToUTF8(expandedString); } } - RegCloseKey(hkTemp); + + WString fallback; + fallback.assign(raw); + return ToUTF8(fallback); + } + + SString BinaryBufferToHex(const unsigned char* data, DWORD size) + { + if (size == 0) + return SString(); + + static const char hexDigits[] = "0123456789ABCDEF"; + std::string hex; + hex.reserve(static_cast(size) * 2u); + for (DWORD i = 0; i < size; ++i) + { + const unsigned char byte = data[i]; + hex.push_back(hexDigits[(byte >> 4) & 0x0F]); + hex.push_back(hexDigits[byte & 0x0F]); + } + SString result; + result = hex.c_str(); + return result; } + + bool TryReadStringValue(HKEY key, const wchar_t* valueName, DWORD& dwType, DWORD initialSize, SString& outValue, int& status) + { + DWORD allocSize = std::max(initialSize, kMinStringAlloc); + std::vector buffer(ComputeWideBufferCapacity(allocSize), L'\0'); + + while (true) + { + DWORD dwTempSize = allocSize; + LONG readResult = RegQueryValueExW(key, valueName, NULL, &dwType, reinterpret_cast(buffer.data()), &dwTempSize); + + if (readResult == ERROR_MORE_DATA) + { + if (dwTempSize > kMaxRegistryValueBytes) + { + status = -static_cast(ERROR_MORE_DATA); + return false; + } + + DWORD newSize = 0; + if (!ComputeNextAllocation(allocSize, dwTempSize, kMinStringAlloc, newSize)) + { + status = -static_cast(ERROR_MORE_DATA); + return false; + } + + allocSize = newSize; + buffer.assign(ComputeWideBufferCapacity(allocSize), L'\0'); + continue; + } + + if (readResult != ERROR_SUCCESS) + { + status = -static_cast(readResult); + return false; + } + + size_t wcharCount = static_cast(dwTempSize) / sizeof(wchar_t); + if (wcharCount >= buffer.size()) + wcharCount = buffer.size() - 1u; + buffer[wcharCount] = L'\0'; + + if (dwType == REG_MULTI_SZ) + { + outValue = ToUTF8(CollapseMultiSz(buffer.data(), wcharCount)); + } + else if (dwType == REG_EXPAND_SZ) + { + outValue = ExpandEnvironmentToUtf8(buffer.data()); + } + else + { + WString direct; + direct.assign(buffer.data()); + outValue = ToUTF8(direct); + } + + status = 1; + return true; + } + } + + bool TryReadBinaryValue(HKEY key, const wchar_t* valueName, DWORD& dwType, DWORD initialSize, SString& outValue, int& status) + { + DWORD allocSize = std::max(initialSize, kMinBinaryAlloc); + std::vector buffer(static_cast(allocSize), 0u); + + while (true) + { + DWORD dwTempSize = allocSize; + LONG readResult = RegQueryValueExW(key, valueName, NULL, &dwType, buffer.data(), &dwTempSize); + + if (readResult == ERROR_MORE_DATA) + { + if (dwTempSize > kMaxRegistryValueBytes) + { + status = -static_cast(ERROR_MORE_DATA); + return false; + } + + DWORD newSize = 0; + if (!ComputeNextAllocation(allocSize, dwTempSize, kMinBinaryAlloc, newSize)) + { + status = -static_cast(ERROR_MORE_DATA); + return false; + } + + allocSize = newSize; + buffer.assign(static_cast(allocSize), 0u); + continue; + } + + if (readResult != ERROR_SUCCESS) + { + status = -static_cast(readResult); + return false; + } + + switch (dwType) + { + case REG_DWORD: + { + DWORD value = 0; + const DWORD copyBytes = std::min(dwTempSize, sizeof(DWORD)); + for (DWORD i = 0; i < copyBytes; ++i) + value |= static_cast(buffer[i]) << (8u * i); + outValue.Format("%lu", static_cast(value)); + break; + } + case REG_DWORD_BIG_ENDIAN: + { + DWORD value = 0; + const DWORD copyBytes = std::min(dwTempSize, sizeof(DWORD)); + for (DWORD i = 0; i < copyBytes; ++i) + { + value <<= 8; + value |= buffer[i]; + } + outValue.Format("%lu", static_cast(value)); + break; + } + case REG_QWORD: + { + unsigned long long value = 0ull; + const DWORD copyBytes = std::min(dwTempSize, static_cast(sizeof(value))); + for (DWORD i = 0; i < copyBytes; ++i) + value |= static_cast(buffer[i]) << (8ull * i); + outValue.Format("%llu", static_cast(value)); + break; + } + case REG_BINARY: + case REG_LINK: + case REG_RESOURCE_LIST: + case REG_FULL_RESOURCE_DESCRIPTOR: + case REG_RESOURCE_REQUIREMENTS_LIST: + case REG_NONE: + default: + { + outValue = BinaryBufferToHex(buffer.data(), dwTempSize); + break; + } + } + + status = 1; + return true; + } + } + + bool PopulateValueFromKey(HKEY key, const wchar_t* valueName, int& status, SString& outValue) + { + DWORD dwType = REG_NONE; + DWORD dwBufferSize = 0; + LONG queryResult = RegQueryValueExW(key, valueName, NULL, &dwType, NULL, &dwBufferSize); + + if (queryResult != ERROR_SUCCESS && queryResult != ERROR_MORE_DATA) + { + status = -static_cast(queryResult); + return false; + } + + if (dwBufferSize > kMaxRegistryValueBytes) + { + status = -static_cast(ERROR_MORE_DATA); + return false; + } + + int localStatus = 0; + const bool isStringType = (dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_MULTI_SZ); + const bool success = isStringType ? TryReadStringValue(key, valueName, dwType, dwBufferSize, outValue, localStatus) + : TryReadBinaryValue(key, valueName, dwType, dwBufferSize, outValue, localStatus); + + if (localStatus != 0) + status = localStatus; + + return success; + } + +} + +static SString ReadRegistryStringValue(HKEY hkRoot, const char* szSubKey, const char* szValue, int* iResult) +{ + SString strOutResult; + int status = 0; + bool success = false; + + const char* szSafeSubKey = szSubKey ? szSubKey : ""; + const char* szSafeValue = szValue ? szValue : ""; + + WString wstrSubKey; + const wchar_t* pSubKey = L""; + if (szSafeSubKey[0] != '\0') + { + wstrSubKey = FromUTF8(szSafeSubKey); + pSubKey = wstrSubKey.c_str(); + } + + static constexpr wchar_t kDefaultValueName[] = L""; + WString wstrValue; + const wchar_t* pValueName = kDefaultValueName; + if (szSafeValue[0] != '\0') + { + wstrValue = FromUTF8(szSafeValue); + pValueName = wstrValue.c_str(); + } + + constexpr size_t kAccessMaskSlots = 3u; + std::array accessMasks{}; + size_t maskCount = 0; + #ifdef KEY_WOW64_64KEY + accessMasks[maskCount++] = KEY_READ | KEY_WOW64_64KEY; + #endif + #ifdef KEY_WOW64_32KEY + accessMasks[maskCount++] = KEY_READ | KEY_WOW64_32KEY; + #endif + accessMasks[maskCount++] = KEY_READ; + + for (size_t maskIndex = 0; maskIndex < maskCount && !success; ++maskIndex) + { + HKEY hkTemp = nullptr; + const LONG openResult = RegOpenKeyExW(hkRoot, pSubKey, 0, accessMasks[maskIndex], &hkTemp); + if (openResult != ERROR_SUCCESS) + { + status = -static_cast(openResult); + continue; + } + + UniqueHKey keyGuard(hkTemp); + + if (PopulateValueFromKey(hkTemp, pValueName, status, strOutResult)) + { + success = true; + break; + } + } + if (iResult) - *iResult = bResult; + *iResult = status; + + if (!success) + strOutResult.clear(); + return strOutResult; } @@ -234,9 +1047,9 @@ SString SharedUtil::GetMajorVersionString() // // GetSystemRegistryValue // -SString SharedUtil::GetSystemRegistryValue(uint hKey, const SString& strPath, const SString& strName) +SString SharedUtil::GetSystemRegistryValue(uint hKey, const SString& strPath, const SString& strName, int* iResult /*= nullptr*/) { - return ReadRegistryStringValue((HKEY)hKey, strPath, strName, NULL); + return ReadRegistryStringValue((HKEY)hKey, strPath, strName, iResult); } // @@ -260,9 +1073,9 @@ void SharedUtil::SetRegistryValue(const SString& strPath, const SString& strName WriteRegistryStringValue(HKEY_LOCAL_MACHINE, MakeVersionRegistryPath(GetMajorVersionString(), strPath), strName, strValue, bFlush); } -SString SharedUtil::GetRegistryValue(const SString& strPath, const SString& strName) +SString SharedUtil::GetRegistryValue(const SString& strPath, const SString& strName, int* iResult /*= nullptr*/) { - return ReadRegistryStringValue(HKEY_LOCAL_MACHINE, MakeVersionRegistryPath(GetMajorVersionString(), strPath), strName, NULL); + return ReadRegistryStringValue(HKEY_LOCAL_MACHINE, MakeVersionRegistryPath(GetMajorVersionString(), strPath), strName, iResult); } bool SharedUtil::RemoveRegistryKey(const SString& strPath) @@ -276,9 +1089,9 @@ void SharedUtil::SetVersionRegistryValue(const SString& strVersion, const SStrin WriteRegistryStringValue(HKEY_LOCAL_MACHINE, MakeVersionRegistryPath(strVersion, strPath), strName, strValue); } -SString SharedUtil::GetVersionRegistryValue(const SString& strVersion, const SString& strPath, const SString& strName) +SString SharedUtil::GetVersionRegistryValue(const SString& strVersion, const SString& strPath, const SString& strName, int* iResult /*= nullptr*/) { - return ReadRegistryStringValue(HKEY_LOCAL_MACHINE, MakeVersionRegistryPath(strVersion, strPath), strName, NULL); + return ReadRegistryStringValue(HKEY_LOCAL_MACHINE, MakeVersionRegistryPath(strVersion, strPath), strName, iResult); } // Get/set registry values for all versions (common) @@ -287,9 +1100,9 @@ void SharedUtil::SetCommonRegistryValue(const SString& strPath, const SString& s WriteRegistryStringValue(HKEY_LOCAL_MACHINE, MakeVersionRegistryPath("Common", strPath), strName, strValue); } -SString SharedUtil::GetCommonRegistryValue(const SString& strPath, const SString& strName) +SString SharedUtil::GetCommonRegistryValue(const SString& strPath, const SString& strName, int* iResult /*= nullptr*/) { - return ReadRegistryStringValue(HKEY_LOCAL_MACHINE, MakeVersionRegistryPath("Common", strPath), strName, NULL); + return ReadRegistryStringValue(HKEY_LOCAL_MACHINE, MakeVersionRegistryPath("Common", strPath), strName, iResult); } // @@ -309,6 +1122,12 @@ void SharedUtil::SetOnQuitCommand(const SString& strOperation, const SString& st void SharedUtil::SetOnRestartCommand(const SString& strOperation, const SString& strFile, const SString& strParameters, const SString& strDirectory, const SString& strShowCmd) { + if (strOperation.empty() && strFile.empty() && strParameters.empty() && strDirectory.empty() && strShowCmd.empty()) + { + SetRegistryValue("", "OnRestartCommand", ""); + return; + } + // Encode into a string and set a registry key SString strVersion("%d.%d.%d-%d.%05d", MTASA_VERSION_MAJOR, MTASA_VERSION_MINOR, MTASA_VERSION_MAINTENANCE, MTASA_VERSION_TYPE, MTASA_VERSION_BUILD); SString strValue("%s\t%s\t%s\t%s\t%s\t%s", strOperation.c_str(), strFile.c_str(), strParameters.c_str(), strDirectory.c_str(), strShowCmd.c_str(), @@ -322,7 +1141,6 @@ void SharedUtil::SetOnRestartCommand(const SString& strOperation, const SString& bool SharedUtil::GetOnRestartCommand(SString& strOperation, SString& strFile, SString& strParameters, SString& strDirectory, SString& strShowCmd) { SString strOnRestartCommand = GetRegistryValue("", "OnRestartCommand"); - SetOnRestartCommand(""); std::vector vecParts; strOnRestartCommand.Split("\t", vecParts); @@ -339,6 +1157,14 @@ bool SharedUtil::GetOnRestartCommand(SString& strOperation, SString& strFile, SS return true; } AddReportLog(4000, SString("OnRestartCommand disregarded due to version change %s -> %s", vecParts[5].c_str(), strVersion.c_str())); + SetOnRestartCommand(""); + return false; + } + + if (!strOnRestartCommand.empty()) + { + AddReportLog(4001, SString("OnRestartCommand disregarded due to invalid format '%s'", strOnRestartCommand.c_str())); + SetOnRestartCommand(""); } return false; } @@ -365,7 +1191,20 @@ SString SharedUtil::GetPostUpdateConnect() CArgMap argMap; argMap.SetFromString(strPostUpdateConnect); SString strHost = argMap.Get("host"); - time_t timeThen = (time_t)std::atoll(argMap.Get("time")); + SString strTimeString = argMap.Get("time"); + + time_t timeThen = 0; + if (!strTimeString.empty()) + { + char* endptr; + long long result = strtoll(strTimeString.c_str(), &endptr, 10); + + // Check for valid conversion + if (endptr != strTimeString.c_str() && *endptr == '\0' && result >= 0 && result <= LLONG_MAX) + { + timeThen = static_cast(result); + } + } // Expire after 5 mins double seconds = difftime(time(NULL), timeThen); @@ -408,7 +1247,21 @@ void SharedUtil::SetApplicationSettingInt(const SString& strPath, const SString& int SharedUtil::GetApplicationSettingInt(const SString& strPath, const SString& strName) { - return atoi(GetApplicationSetting(strPath, strName)); + SString strValue = GetApplicationSetting(strPath, strName); + if (strValue.empty()) + return 0; + + char* endptr; + long result = strtol(strValue.c_str(), &endptr, 10); + + // Check for conversion errors + if (endptr == strValue.c_str() || *endptr != '\0') + return 0; // Invalid conversion + + if (result > INT_MAX || result < INT_MIN) + return 0; + + return static_cast(result); } int SharedUtil::IncApplicationSettingInt(const SString& strPath, const SString& strName) @@ -586,47 +1439,138 @@ const SString& SharedUtil::GetProductVersion() void SharedUtil::SetClipboardText(const SString& strText) { - // If we got something to copy - if (!strText.empty()) + if (strText.empty()) + return; + + std::lock_guard clipboardGuard(Details::ClipboardMutex()); + + WString wideText; + try { - // Convert it to Unicode - WString strUTF = MbUTF8ToUTF16(strText); + wideText = MbUTF8ToUTF16(strText); + } + catch (const std::exception&) + { + return; + } + catch (...) + { + return; + } + + if (!OpenClipboard(nullptr)) + return; - // Open and empty the clipboard - OpenClipboard(NULL); - EmptyClipboard(); + struct ClipboardCloser + { + ~ClipboardCloser() { CloseClipboard(); } + } clipboardCloser; + + if (!EmptyClipboard()) + return; + + const size_t length = wideText.length(); + if (length > (std::numeric_limits::max() / sizeof(wchar_t)) - 1) + return; + + const size_t charCount = length + 1u; + if (charCount > Details::kMaxClipboardChars) + return; - // Allocate the clipboard buffer and copy the data - HGLOBAL hBuf = GlobalAlloc(GMEM_DDESHARE, strUTF.length() * sizeof(wchar_t) + sizeof(wchar_t)); - wchar_t* buf = reinterpret_cast(GlobalLock(hBuf)); - wcscpy(buf, strUTF); - GlobalUnlock(hBuf); + const size_t totalBytes = charCount * sizeof(wchar_t); - // Copy the data into the clipboard - SetClipboardData(CF_UNICODETEXT, hBuf); + Details::UniqueHGlobal clipboardMemory(GlobalAlloc(GMEM_MOVEABLE, totalBytes)); + if (!clipboardMemory) + return; - // Close the clipboard - CloseClipboard(); + void* rawBuffer = GlobalLock(clipboardMemory.get()); + if (!rawBuffer) + return; + + auto lockGuard = SharedUtil::MakeGlobalUnlockGuard(static_cast(clipboardMemory.get())); + + auto* buffer = static_cast(rawBuffer); + std::copy_n(wideText.c_str(), charCount, buffer); + + if (!lockGuard.UnlockChecked()) + return; + + if (const HANDLE placedHandle = SetClipboardData(CF_UNICODETEXT, clipboardMemory.get())) + { + static_cast(clipboardMemory.release()); } } SString SharedUtil::GetClipboardText() { - SString data; + SString result; + + std::lock_guard clipboardGuard(Details::ClipboardMutex()); - if (OpenClipboard(NULL)) + if (!OpenClipboard(nullptr)) + return result; + + struct ClipboardCloser + { + ~ClipboardCloser() { CloseClipboard(); } + } clipboardCloser; + + if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) + return result; + + if (const HANDLE clipboardData = GetClipboardData(CF_UNICODETEXT); clipboardData) { - // Get the clipboard's data - HANDLE clipboardData = GetClipboardData(CF_UNICODETEXT); - void* lockedData = GlobalLock(clipboardData); - if (lockedData) - data = UTF16ToMbUTF8(static_cast(lockedData)); + void* rawData = GlobalLock(clipboardData); + if (!rawData) + return result; - GlobalUnlock(clipboardData); - CloseClipboard(); + auto lockGuard = SharedUtil::MakeGlobalUnlockGuard(static_cast(clipboardData)); + + const SIZE_T rawSizeBytes = GlobalSize(static_cast(clipboardData)); + if (rawSizeBytes == 0) + return result; + + if (rawSizeBytes > Details::kMaxClipboardBytes) + { + return result; + } + + if ((rawSizeBytes % sizeof(wchar_t)) != 0) + { + return result; + } + + const size_t wcharCount = static_cast(rawSizeBytes / sizeof(wchar_t)); + if (wcharCount == 0) + return result; + + const auto* lockedData = static_cast(rawData); + const auto* terminator = std::find(lockedData, lockedData + wcharCount, L'\0'); + if (terminator == lockedData + wcharCount) + { + return result; + } + + try + { + result = UTF16ToMbUTF8(lockedData); + } + catch (const std::exception&) + { + result.clear(); + } + catch (...) + { + result.clear(); + } + + if (!lockGuard.UnlockChecked()) + { + // Unlock failure is non-fatal; retain gathered data + } } - return data; + return result; } // @@ -679,7 +1623,8 @@ bool SharedUtil::ProcessPendingBrowseToSolution() ClearPendingBrowseToSolution(); - SString strTitle("MTA: San Andreas %s (CTRL+C to copy)", *strErrorCode); + SString strTitle; + strTitle.Format("MTA: San Andreas %s (CTRL+C to copy)", strErrorCode.c_str()); // Show message if set, ask question if required, and then launch URL if (iFlags & ASK_GO_ONLINE) { @@ -769,8 +1714,10 @@ void SharedUtil::AddReportLog(uint uiId, const SString& strText, uint uiAmountLi SString strPathFilename = PathJoin(GetMTADataPath(), "report.log"); MakeSureDirExists(strPathFilename); - SString strMessage("%u: %s %s [%s] - %s\n", uiId, GetTimeString(true, false).c_str(), GetReportLogHeaderText().c_str(), - GetReportLogProcessTag().c_str(), strText.c_str()); + SString strMessage; + strMessage.Format("%u: %s %s [%s] - ", uiId, GetTimeString(true, false).c_str(), GetReportLogHeaderText().c_str(), GetReportLogProcessTag().c_str()); + strMessage += strText; + strMessage += "\n"; FileAppend(strPathFilename, &strMessage.at(0), strMessage.length()); OutputDebugLine(SStringX("[ReportLog] ") + strMessage); } @@ -785,13 +1732,16 @@ void SharedUtil::AddExceptionReportLog(uint uiId, const char* szExceptionName, c constexpr size_t BOILERPLATE_SIZE = 46; constexpr size_t MAX_EXCEPTION_NAME_SIZE = 64; constexpr size_t MAX_EXCEPTION_TEXT_SIZE = 256; - static char szOutput[BOILERPLATE_SIZE + MAX_EXCEPTION_NAME_SIZE + MAX_EXCEPTION_TEXT_SIZE] = {0}; + constexpr size_t TOTAL_BUFFER_SIZE = BOILERPLATE_SIZE + MAX_EXCEPTION_NAME_SIZE + MAX_EXCEPTION_TEXT_SIZE; + static char szOutput[TOTAL_BUFFER_SIZE] = {0}; SYSTEMTIME s = {0}; GetSystemTime(&s); - sprintf_s(szOutput, "%u: %04hu-%02hu-%02hu %02hu:%02hu:%02hu - Caught %.*s exception: %.*s\n", uiId, s.wYear, s.wMonth, s.wDay, s.wHour, s.wMinute, - s.wSecond, MAX_EXCEPTION_NAME_SIZE, szExceptionName, MAX_EXCEPTION_TEXT_SIZE, szExceptionText); + // Use _snprintf_s to prevent buffer overflow and ensure null termination + int result = _snprintf_s(szOutput, TOTAL_BUFFER_SIZE, _TRUNCATE, "%u: %04hu-%02hu-%02hu %02hu:%02hu:%02hu - Caught %.*s exception: %.*s\n", uiId, s.wYear, + s.wMonth, s.wDay, s.wHour, s.wMinute, s.wSecond, (int)MAX_EXCEPTION_NAME_SIZE, szExceptionName ? szExceptionName : "Unknown", + (int)MAX_EXCEPTION_TEXT_SIZE, szExceptionText ? szExceptionText : ""); OutputDebugString("[ReportLog] "); OutputDebugString(&szOutput[0]); @@ -878,9 +1828,9 @@ void WriteEvent(const char* szType, const SString& strText) SString strPathFilename = CalcMTASAPath(PathJoin("mta", "logs", "logfile.txt")); SString strMessage("%s - %s %s", *GetLocalTimeString(), szType, *strText); FileAppend(strPathFilename, strMessage + "\n"); -#ifdef MTA_DEBUG + #ifdef MTA_DEBUG OutputDebugLine(strMessage); -#endif + #endif } void SharedUtil::WriteDebugEvent(const SString& strText) @@ -936,28 +1886,11 @@ SString SharedUtil::GetSystemErrorMessage(uint uiError, bool bRemoveNewlines, bo strResult = strResult.Replace("\n", "").Replace("\r", ""); if (bPrependCode) - strResult = SString("Error %u: %s", uiError, *strResult); + strResult.Format("Error %u: %s", uiError, strResult.c_str()); return strResult; } -#ifdef ExpandEnvironmentStringsForUser -// -// eg "%HOMEDRIVE%" -> "C:" -// -SString SharedUtil::ExpandEnvString(const SString& strInput) -{ - HANDLE hProcessToken; - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE, &hProcessToken)) - return strInput; - - const static int iBufferSize = 32000; - char envBuf[iBufferSize + 2]; - ExpandEnvironmentStringsForUser(hProcessToken, strInput, envBuf, iBufferSize); - return envBuf; -} -#endif - /////////////////////////////////////////////////////////////// // // MyShellExecute @@ -1002,8 +1935,8 @@ static bool MyShellExecute(bool bBlocking, const SString& strAction, const SStri } else { - int iResult = (int)ShellExecute(NULL, strAction, strFile, strParameters, strDirectory, nShowCmd); - return iResult > 32; + const auto result = reinterpret_cast(ShellExecute(NULL, strAction, strFile, strParameters, strDirectory, nShowCmd)); + return result > 32; } } @@ -1034,8 +1967,8 @@ bool SharedUtil::ShellExecuteNonBlocking(const SString& strAction, const SString #endif // MTA_CLIENT -#ifdef WIN32 -#define _WIN32_WINNT_WIN8 0x0602 +#ifdef SHAREDUTIL_PLATFORM_WINDOWS + #define _WIN32_WINNT_WIN8 0x0602 /////////////////////////////////////////////////////////////////////////// // // SharedUtil::IsWindowsVersionOrGreater @@ -1077,7 +2010,7 @@ bool SharedUtil::IsWindows8OrGreater() { return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0); } -#endif // WIN32 +#endif // SHAREDUTIL_PLATFORM_WINDOWS static uchar ToHexChar(uchar c) { @@ -1138,7 +2071,7 @@ SString SharedUtil::EscapeURLArgument(const SString& strArg) // // Cross platform critical section // -#ifdef WIN32 +#ifdef SHAREDUTIL_PLATFORM_WINDOWS SharedUtil::CCriticalSection::CCriticalSection() { @@ -1199,7 +2132,7 @@ void SharedUtil::RandomizeRandomSeed() srand(rand() + GetTickCount32()); } -#ifdef WIN32 +#ifdef SHAREDUTIL_PLATFORM_WINDOWS static LONG SafeNtQueryInformationThread(HANDLE ThreadHandle, INT ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength, PULONG ReturnLength) { @@ -1208,6 +2141,7 @@ static LONG SafeNtQueryInformationThread(HANDLE ThreadHandle, INT ThreadInformat struct FunctionLookup { FunctionPointer function; + HMODULE module; bool once; }; @@ -1217,18 +2151,18 @@ static LONG SafeNtQueryInformationThread(HANDLE ThreadHandle, INT ThreadInformat { lookup.once = true; - HMODULE ntdll = LoadLibraryA("ntdll.dll"); + lookup.module = LoadLibraryA("ntdll.dll"); - if (ntdll) - lookup.function = static_cast(static_cast(GetProcAddress(ntdll, "NtQueryInformationThread"))); + if (lookup.module) + lookup.function = static_cast(static_cast(GetProcAddress(lookup.module, "NtQueryInformationThread"))); else - return 0xC0000135L; // STATUS_DLL_NOT_FOUND + return 0xC0000135L; // STATUS_DLL_NOT_FOUND } if (lookup.function) return lookup.function(ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength, ReturnLength); else - return 0xC00000BBL; // STATUS_NOT_SUPPORTED + return 0xC00000BBL; // STATUS_NOT_SUPPORTED } bool SharedUtil::QueryThreadEntryPointAddress(void* thread, DWORD* entryPointAddress) @@ -1248,7 +2182,7 @@ DWORD SharedUtil::GetMainThreadId() if (GetModuleInformation(GetCurrentProcess(), GetModuleHandle(nullptr), &moduleInfo, sizeof(MODULEINFO)) != 0) { - processEntryPointAddress = reinterpret_cast(moduleInfo.EntryPoint); + processEntryPointAddress = static_cast(reinterpret_cast(moduleInfo.EntryPoint)); } // Find oldest thread in the current process ( https://www.codeproject.com/Questions/78801/How-to-get-the-main-thread-ID-of-a-process-known-b ) @@ -1324,7 +2258,7 @@ DWORD SharedUtil::GetMainThreadId() // bool SharedUtil::IsMainThread() { -#ifdef WIN32 +#ifdef SHAREDUTIL_PLATFORM_WINDOWS DWORD mainThreadID = GetMainThreadId(); DWORD currentThreadID = GetCurrentThreadId(); return mainThreadID == currentThreadID; @@ -1337,7 +2271,7 @@ bool SharedUtil::IsMainThread() // // Expiry stuff // -#ifdef WIN32 +#ifdef SHAREDUTIL_PLATFORM_WINDOWS #include int SharedUtil::GetBuildAge() @@ -1350,7 +2284,7 @@ int SharedUtil::GetBuildAge() return (int)(time(NULL) - mktime(&when)) / (60 * 60 * 24); } -#if defined(MTA_DM_EXPIRE_DAYS) + #if defined(MTA_DM_EXPIRE_DAYS) int SharedUtil::GetDaysUntilExpire() { tm when; @@ -1361,7 +2295,7 @@ int SharedUtil::GetDaysUntilExpire() return (int)(mktime(&when) - time(NULL)) / (60 * 60 * 24); } -#endif + #endif #endif // @@ -1483,6 +2417,18 @@ char* SharedUtil::Trim(char* szText) return static_cast(memmove(szOriginal, szText, uiLen + 1)); } +#if __cplusplus >= 201703L // C++17 +std::string SharedUtil::UTF8FilePath(const std::filesystem::path& input) +{ + #ifdef __cpp_lib_char8_t + std::u8string raw = input.u8string(); + return std::string{std::begin(raw), std::end(raw)}; + #else + return input.u8string(); + #endif +} +#endif + // Convert a standard multibyte UTF-8 std::string into a UTF-16 std::wstring std::wstring SharedUtil::MbUTF8ToUTF16(const SString& input) { @@ -1516,15 +2462,20 @@ int SharedUtil::GetUTF8Confidence(const unsigned char* input, int len) // Translate a true ANSI string to the UTF-16 equivalent (reencode+convert) std::wstring SharedUtil::ANSIToUTF16(const SString& input) { + if (input.empty()) + return L""; + size_t len = mbstowcs(NULL, input.c_str(), input.length()); if (len == (size_t)-1) return L"?"; - wchar_t* wcsOutput = new wchar_t[len + 1]; - mbstowcs(wcsOutput, input.c_str(), input.length()); - wcsOutput[len] = 0; // Null terminate the string - std::wstring strOutput(wcsOutput); - delete[] wcsOutput; - return strOutput; + + std::vector wcsOutput(len + 1); // Use vector for automatic cleanup + size_t result = mbstowcs(wcsOutput.data(), input.c_str(), len); + if (result == (size_t)-1 || result != len) + return L"?"; + + wcsOutput[len] = 0; // Null terminate the string + return std::wstring(wcsOutput.data()); } // Check for BOM bytes @@ -1543,14 +2494,14 @@ bool SharedUtil::IsLuaCompiledScript(const void* pData, uint uiLength) pCharData += 3; uiLength -= 3; } - return (uiLength > 0 && pCharData[0] == 0x1B); // Do the same check as what the Lua parser does + return (uiLength > 0 && pCharData[0] == 0x1B); // Do the same check as what the Lua parser does } // Check for obfuscated script bool SharedUtil::IsLuaObfuscatedScript(const void* pData, uint uiLength) { const uchar* pCharData = (const uchar*)pData; - return (uiLength > 0 && pCharData[0] == 0x1C); // Look for our special marker + return (uiLength > 0 && pCharData[0] == 0x1C); // Look for our special marker } // @@ -1598,7 +2549,7 @@ SString SharedUtil::ConformResourcePath(const char* szRes, bool bConvertToUnixPa char cPathSep; // Handle which path sep char -#ifdef WIN32 +#ifdef SHAREDUTIL_PLATFORM_WINDOWS if (!bConvertToUnixPathSep) { cPathSep = '\\'; @@ -1643,9 +2594,15 @@ namespace SharedUtil m_cEscapeCharacter = '#'; } - void CArgMap::SetEscapeCharacter(char cEscapeCharacter) { m_cEscapeCharacter = cEscapeCharacter; } + void CArgMap::SetEscapeCharacter(char cEscapeCharacter) + { + m_cEscapeCharacter = cEscapeCharacter; + } - void CArgMap::Merge(const CArgMap& other, bool bAllowMultiValues) { MergeFromString(other.ToString(), bAllowMultiValues); } + void CArgMap::Merge(const CArgMap& other, bool bAllowMultiValues) + { + MergeFromString(other.ToString(), bAllowMultiValues); + } void CArgMap::SetFromString(const SString& strLine, bool bAllowMultiValues) { @@ -1663,7 +2620,7 @@ namespace SharedUtil parts[i].Split(m_strArgSep, &strCmd, &strArg); if (!bAllowMultiValues) m_Map.erase(strCmd); - if (strCmd.length()) // Key can not be empty + if (strCmd.length()) // Key can not be empty MapInsert(m_Map, strCmd, strArg); } } @@ -1698,9 +2655,15 @@ namespace SharedUtil SetFromString(ToString(), false); } - SString CArgMap::Escape(const SString& strIn) const { return EscapeString(strIn, m_strDisallowedChars, m_cEscapeCharacter); } + SString CArgMap::Escape(const SString& strIn) const + { + return EscapeString(strIn, m_strDisallowedChars, m_cEscapeCharacter); + } - SString CArgMap::Unescape(const SString& strIn) const { return UnescapeString(strIn, m_cEscapeCharacter); } + SString CArgMap::Unescape(const SString& strIn) const + { + return UnescapeString(strIn, m_cEscapeCharacter); + } // Set a unique key string value void CArgMap::Set(const SString& strCmd, const SString& strValue) @@ -1717,17 +2680,23 @@ namespace SharedUtil } // Insert a key int value - void CArgMap::Insert(const SString& strCmd, int iValue) { Insert(strCmd, SString("%d", iValue)); } + void CArgMap::Insert(const SString& strCmd, int iValue) + { + Insert(strCmd, SString("%d", iValue)); + } // Insert a key string value void CArgMap::Insert(const SString& strCmd, const SString& strValue) { - if (strCmd.length()) // Key can not be empty + if (strCmd.length()) // Key can not be empty MapInsert(m_Map, Escape(strCmd), Escape(strValue)); } // Test if key exists - bool CArgMap::Contains(const SString& strCmd) const { return MapFind(m_Map, Escape(strCmd)) != NULL; } + bool CArgMap::Contains(const SString& strCmd) const + { + return MapFind(m_Map, Escape(strCmd)) != NULL; + } // First result as string bool CArgMap::Get(const SString& strCmd, SString& strOut, const char* szDefault) const @@ -1781,7 +2750,7 @@ namespace SharedUtil outList.push_back(iter->first); } -#ifdef WIN32 +#ifdef SHAREDUTIL_PLATFORM_WINDOWS /////////////////////////////////////////////////////////////////////////// // // GetCurrentProcessorNumberXP for the current thread, especially for Windows XP @@ -1817,21 +2786,30 @@ namespace SharedUtil /////////////////////////////////////////////////////////////////////////// DWORD _GetCurrentProcessorNumber() { -#ifdef WIN32 +#ifdef SHAREDUTIL_PLATFORM_WINDOWS // Dynamically load GetCurrentProcessorNumber, as it does not exist on XP using GetCurrentProcessorNumber_t = DWORD(WINAPI*)(); - static auto FnGetCurrentProcessorNumber = ([]() -> GetCurrentProcessorNumber_t { - HMODULE kernel32 = LoadLibraryA("kernel32"); + struct ProcessorNumberLookup + { + GetCurrentProcessorNumber_t function; + HMODULE module; + bool once; + }; - if (kernel32) - return static_cast(static_cast(GetProcAddress(kernel32, "GetCurrentProcessorNumber"))); + static ProcessorNumberLookup lookup = {}; - return nullptr; - })(); + if (!lookup.once) + { + lookup.once = true; + lookup.module = LoadLibraryA("kernel32"); - if (FnGetCurrentProcessorNumber) - return FnGetCurrentProcessorNumber(); + if (lookup.module) + lookup.function = static_cast(static_cast(GetProcAddress(lookup.module, "GetCurrentProcessorNumber"))); + } + + if (lookup.function) + return lookup.function(); return _GetCurrentProcessorNumberXP(); #elif defined(__APPLE__) && defined(__aarch64__) @@ -1870,7 +2848,7 @@ namespace SharedUtil { outUserTime = 0; outKernelTime = 0; -#ifdef WIN32 +#ifdef SHAREDUTIL_PLATFORM_WINDOWS FILETIME CreationTime, ExitTime, KernelTime, UserTime; if (GetThreadTimes(GetCurrentThread(), &CreationTime, &ExitTime, &KernelTime, &UserTime)) { @@ -1950,6 +2928,11 @@ namespace SharedUtil { if (uiLength < 1) return; + + // Check for arithmetic overflow + if (uiStart + uiLength < uiStart || uiStart + uiLength - 1 < uiStart) + return; + uint uiLast = uiStart + uiLength - 1; // Make a hole @@ -1965,34 +2948,68 @@ namespace SharedUtil { if (uiLength < 1) return; + + // Check for arithmetic overflow + if (uiStart + uiLength < uiStart || uiStart + uiLength - 1 < uiStart) + return; + uint uiLast = uiStart + uiLength - 1; RemoveObscuredRanges(uiStart, uiLast); - IterType iterOverlap; if (GetRangeOverlappingPoint(uiStart, iterOverlap)) { uint uiOverlapPrevLast = iterOverlap->second; - // Modify overlapping range last point - uint uiNewLast = uiStart - 1; - iterOverlap->second = uiNewLast; + // Modify overlapping range last point with underflow check + if (uiStart > 0) + { + uint uiNewLast = uiStart - 1; + iterOverlap->second = uiNewLast; - if (uiOverlapPrevLast > uiLast) + if (uiOverlapPrevLast > uiLast) + { + // Need to add range after hole + // Check for overflow when calculating uiLast + 1 + if (uiLast < UINT_MAX) + { + uint uiNewStart = uiLast + 1; + m_StartLastMap[uiNewStart] = uiOverlapPrevLast; + } + } + } + else { - // Need to add range after hole - uint uiNewStart = uiLast + 1; - m_StartLastMap[uiNewStart] = uiOverlapPrevLast; + // Special case: uiStart is 0, remove the range entirely + m_StartLastMap.erase(iterOverlap); + if (uiOverlapPrevLast > uiLast) + { + // Check for overflow when calculating uiLast + 1 + if (uiLast < UINT_MAX) + { + uint uiNewStart = uiLast + 1; + m_StartLastMap[uiNewStart] = uiOverlapPrevLast; + } + } } } if (GetRangeOverlappingPoint(uiLast, iterOverlap)) { // Modify overlapping range start point - uint uiNewStart = uiLast + 1; - uint uiOldLast = iterOverlap->second; - m_StartLastMap.erase(iterOverlap); - m_StartLastMap[uiNewStart] = uiOldLast; + // Check for overflow when calculating uiLast + 1 + if (uiLast < UINT_MAX) + { + uint uiNewStart = uiLast + 1; + uint uiOldLast = iterOverlap->second; + m_StartLastMap.erase(iterOverlap); + m_StartLastMap[uiNewStart] = uiOldLast; + } + else + { + // If uiLast == UINT_MAX, we can't create a range after it, just remove the overlapping range + m_StartLastMap.erase(iterOverlap); + } } } @@ -2001,6 +3018,11 @@ namespace SharedUtil { if (uiLength < 1) return false; + + // Check for arithmetic overflow + if (uiStart + uiLength < uiStart || uiStart + uiLength - 1 < uiStart) + return false; + uint uiLast = uiStart + uiLength - 1; IterType iter = m_StartLastMap.lower_bound(uiStart); @@ -2036,7 +3058,7 @@ namespace SharedUtil if (iter == m_StartLastMap.end()) return; - // If last of found range is after query last, then range is not obscured + // If last of found range is after or at query last, then range is not obscured if (iter->second > uiLast) return; @@ -2050,6 +3072,15 @@ namespace SharedUtil IterType iter = m_StartLastMap.lower_bound(uiPoint); // iter is on or after point - So it can't overlap the point + if (iter != m_StartLastMap.end()) + { + // If last of found range is after or at query point, then range is overlapping + if (iter->first <= uiPoint && iter->second >= uiPoint) + { + result = iter; + return true; + } + } if (iter != m_StartLastMap.begin()) { iter--; @@ -2065,7 +3096,7 @@ namespace SharedUtil return false; } -} // namespace SharedUtil +} // namespace SharedUtil // // For checking MTA library module versions diff --git a/Shared/sdk/SharedUtil.Profiling.h b/Shared/sdk/SharedUtil.Profiling.h index 8b1ad9af4b9..fac23671392 100644 --- a/Shared/sdk/SharedUtil.Profiling.h +++ b/Shared/sdk/SharedUtil.Profiling.h @@ -74,25 +74,24 @@ namespace SharedUtil // Global CStatEvents instance extern class CStatEvents g_StatEvents; - // Macros for clocking areas - #define CLOCK(section,name) g_StatEvents.Add( section, name, STATS_CLOCK ) - #define UNCLOCK(section,name) g_StatEvents.Add( section, name, STATS_UNCLOCK ) - - // Macro for clocking enclosed code - #define CLOCK_CALL(section,code) \ - { \ - CLOCK( section, #code ); \ - code; \ - UNCLOCK( section, #code ); \ - } +// Macros for clocking areas +#define CLOCK(section, name) g_StatEvents.Add(section, name, STATS_CLOCK) +#define UNCLOCK(section, name) g_StatEvents.Add(section, name, STATS_UNCLOCK) + +// Macro for clocking enclosed code +#define CLOCK_CALL(section, code) \ + { \ + CLOCK(section, #code); \ + code; \ + UNCLOCK(section, #code); \ + } - // Macros using a common section name - #define CLOCK_SET_SECTION(tag) \ - const char* szClockSectionTag = tag +// Macros using a common section name +#define CLOCK_SET_SECTION(tag) const char* szClockSectionTag = tag - #define CLOCK1(name) CLOCK( szClockSectionTag, name ) - #define UNCLOCK1(name) UNCLOCK( szClockSectionTag, name) - #define CLOCK_CALL1(code) CLOCK_CALL( szClockSectionTag, code ) +#define CLOCK1(name) CLOCK(szClockSectionTag, name) +#define UNCLOCK1(name) UNCLOCK(szClockSectionTag, name) +#define CLOCK_CALL1(code) CLOCK_CALL(szClockSectionTag, code) // // Performance stat resulting @@ -145,4 +144,4 @@ namespace SharedUtil float m_fNextMaxClearTime; }; -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.Profiling.hpp b/Shared/sdk/SharedUtil.Profiling.hpp index 9d2bf66b689..a0586fa5510 100644 --- a/Shared/sdk/SharedUtil.Profiling.hpp +++ b/Shared/sdk/SharedUtil.Profiling.hpp @@ -63,14 +63,14 @@ namespace SharedUtil public: }; - /////////////////////////////////////////////////////////////// - // - // GetNextUnclockIndex - // - // Search forward from supplied index looking for an (unpaired) unclock marker - // - /////////////////////////////////////////////////////////////// - #define INVALID_INDEX -1 +/////////////////////////////////////////////////////////////// +// +// GetNextUnclockIndex +// +// Search forward from supplied index looking for an (unpaired) unclock marker +// +/////////////////////////////////////////////////////////////// +#define INVALID_INDEX -1 int GetNextUnclockIndex(std::vector& eventList, int i) { if (i < 0 || i >= (int)eventList.size()) @@ -105,7 +105,7 @@ namespace SharedUtil { // check has even number of events if (eventList.size() & 1) - return; // Error + return; // Error // remove recursive Clock/Unclocks for (int i = 0; i < (int)eventList.size() - 1; i += 2) @@ -114,16 +114,16 @@ namespace SharedUtil SFrameEvent& endEvent = eventList[i + 1]; if (startEvent.type == STATS_CLOCK && endEvent.type == STATS_UNCLOCK) - continue; // Fast simple case of unclock following a clock + continue; // Fast simple case of unclock following a clock if (startEvent.type != STATS_CLOCK) - return; // Error + return; // Error int iClockIdx = i; int iUnclockIdx = GetNextUnclockIndex(eventList, iClockIdx + 1); if (iUnclockIdx == INVALID_INDEX) - return; // Error + return; // Error assert(iUnclockIdx != iClockIdx + 1); { @@ -176,7 +176,10 @@ namespace SharedUtil // // //////////////////////////////////////////////// - CStatEvents::CStatEvents() : m_bEnabled(false), m_ItemBuffer(0), m_BufferPos(0), m_BufferPosMax(0), m_BufferPosMaxUsing(0) { ClearBuffer(true); } + CStatEvents::CStatEvents() : m_bEnabled(false), m_ItemBuffer(0), m_BufferPos(0), m_BufferPosMax(0), m_BufferPosMaxUsing(0) + { + ClearBuffer(true); + } /////////////////////////////////////////////////////////////// // @@ -311,7 +314,7 @@ namespace SharedUtil continue; } - float StartMs = (StartEvent.timeStamp - baseTimeStamp) * (1 / 1000.0f); // TIMEUS to ms + float StartMs = (StartEvent.timeStamp - baseTimeStamp) * (1 / 1000.0f); // TIMEUS to ms float EndMs = (EndEvent.timeStamp - baseTimeStamp) * (1 / 1000.0f); float LengthMs = EndMs - StartMs; fTotalMs += LengthMs; @@ -347,7 +350,10 @@ namespace SharedUtil // // /////////////////////////////////////////////////////////////// - CStatResults::CStatResults() { m_fNextMaxClearTime = 0; } + CStatResults::CStatResults() + { + m_fNextMaxClearTime = 0; + } /////////////////////////////////////////////////////////////// // @@ -443,4 +449,4 @@ namespace SharedUtil UNCLOCK("Profiling", "Compile stats"); } -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.SysInfo.h b/Shared/sdk/SharedUtil.SysInfo.h index 76e6fa2ab0c..d6580b555bb 100644 --- a/Shared/sdk/SharedUtil.SysInfo.h +++ b/Shared/sdk/SharedUtil.SysInfo.h @@ -11,10 +11,10 @@ #pragma once #ifdef WIN32 -#include -#include "SString.h" -#include -#include "WinVer.h" + #include + #include "SString.h" + #include + #include "WinVer.h" namespace SharedUtil { @@ -45,6 +45,6 @@ namespace SharedUtil bool IsHotFixInstalled(const SString& strHotFixId); bool GetLibVersionInfo(const SString& strLibName, SLibVersionInfo* pOutLibVersionInfo); bool Is64BitOS(); -} // namespace SharedUtil +} // namespace SharedUtil #endif diff --git a/Shared/sdk/SharedUtil.SysInfo.hpp b/Shared/sdk/SharedUtil.SysInfo.hpp index e79751ca4f1..b32f40920f6 100644 --- a/Shared/sdk/SharedUtil.SysInfo.hpp +++ b/Shared/sdk/SharedUtil.SysInfo.hpp @@ -11,12 +11,12 @@ #ifdef MTA_CLIENT -#define _WIN32_DCOM -#include -#include + #define _WIN32_DCOM + #include + #include -# pragma comment(lib, "wbemuuid.lib") -#pragma comment(lib, "Version.lib") + #pragma comment(lib, "wbemuuid.lib") + #pragma comment(lib, "Version.lib") namespace { @@ -45,7 +45,7 @@ namespace /* [in] */ long lTimeout, /* [in] */ ULONG uCount, /* [length_is][size_is][out] */ __RPC__out_ecount_part(uCount, *puReturned) IWbemClassObject** apObjects, - /* [out] */ __RPC__out ULONG* puReturned) + /* [out] */ __RPC__out ULONG* puReturned) { __try { @@ -57,7 +57,7 @@ namespace return STATUS_ACCESS_VIOLATION; } } -} // namespace +} // namespace ///////////////////////////////////////////////////////////////////// // @@ -92,14 +92,14 @@ bool SharedUtil::QueryWMI(SQueryWMIResult& outResult, const SString& strQuery, c // parameter of CoInitializeSecurity ------------------------ hres = CoInitializeSecurity(NULL, - -1, // COM authentication - NULL, // Authentication services - NULL, // Reserved - RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication - RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation - NULL, // Authentication info - EOAC_NONE, // Additional capabilities - NULL // Reserved + -1, // COM authentication + NULL, // Authentication services + NULL, // Reserved + RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication + RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation + NULL, // Authentication info + EOAC_NONE, // Additional capabilities + NULL // Reserved ); // Error here can be non fatal @@ -131,14 +131,14 @@ bool SharedUtil::QueryWMI(SQueryWMIResult& outResult, const SString& strQuery, c // the current user and obtain pointer pSvc // to make IWbemServices calls. hres = CallConnectServer(pLoc, - _bstr_t(SStringX("ROOT\\") + strNamespace), // Object path of WMI namespace - NULL, // User name. NULL = current user - NULL, // User password. NULL = current - 0, // Locale. NULL indicates current - NULL, // Security flags. - 0, // Authority (e.g. Kerberos) - 0, // Context object - &pSvc // pointer to IWbemServices proxy + _bstr_t(SStringX("ROOT\\") + strNamespace), // Object path of WMI namespace + NULL, // User name. NULL = current user + NULL, // User password. NULL = current + 0, // Locale. NULL indicates current + NULL, // Security flags. + 0, // Authority (e.g. Kerberos) + 0, // Context object + &pSvc // pointer to IWbemServices proxy ); if (FAILED(hres)) @@ -151,14 +151,14 @@ bool SharedUtil::QueryWMI(SQueryWMIResult& outResult, const SString& strQuery, c // Step 5: -------------------------------------------------- // Set security levels on the proxy ------------------------- - hres = CoSetProxyBlanket(pSvc, // Indicates the proxy to set - RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx - RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx - NULL, // Server principal name - RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx - RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx - NULL, // client identity - EOAC_NONE // proxy capabilities + hres = CoSetProxyBlanket(pSvc, // Indicates the proxy to set + RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx + RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx + NULL, // Server principal name + RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx + RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx + NULL, // client identity + EOAC_NONE // proxy capabilities ); if (FAILED(hres)) @@ -314,7 +314,7 @@ long long SharedUtil::GetWMITotalPhysicalMemory() if (llResult == 0) { - llResult = 2LL * 1024 * 1024 * 1024; // 2GB + llResult = 2LL * 1024 * 1024 * 1024; // 2GB } return llResult; } @@ -350,7 +350,7 @@ unsigned int SharedUtil::GetWMIVideoAdapterMemorySize(const unsigned long ulVen, if ((iAvailability == 8 || iAvailability == 3) && PNPDeviceID.Contains(DevVen)) { uiResult = uiAdapterRAM; - break; // Found match + break; // Found match } } diff --git a/Shared/sdk/SharedUtil.Template.h b/Shared/sdk/SharedUtil.Template.h index 86627eab8f4..9a84a5bd176 100644 --- a/Shared/sdk/SharedUtil.Template.h +++ b/Shared/sdk/SharedUtil.Template.h @@ -1,5 +1,9 @@ #pragma once +#ifdef __INTELLISENSE__ + #pragma diag_suppress 842 +#endif + #include #include @@ -246,3 +250,38 @@ struct pad_func_with_func std::max(sizeof...(Args), sizeof...(ArgsB)) - sizeof...(Args) == 0>::type> { }; + +// Removes noexcept(true) from a function type +template +struct remove_noexcept +{ + using type = T; +}; + +template +struct remove_noexcept +{ + using type = R(Args...); +}; + +template +using remove_noexcept_t = typename remove_noexcept::type; + +// Removes noexcept(true) from a function +template +struct remove_noexcept_fn; + +template +struct remove_noexcept_fn +{ + using type = R (*)(Args...); +}; + +template +struct remove_noexcept_fn +{ + using type = R (*)(Args...); +}; + +template +constexpr auto remove_noexcept_fn_v = static_cast::type>(Func); diff --git a/Shared/sdk/SharedUtil.Tests.hpp b/Shared/sdk/SharedUtil.Tests.hpp index bce0db9a41f..7f727b34ef4 100644 --- a/Shared/sdk/SharedUtil.Tests.hpp +++ b/Shared/sdk/SharedUtil.Tests.hpp @@ -47,20 +47,21 @@ void SharedUtil_Tests() // /////////////////////////////////////////////////////////////// #define TEST_FUNCTION \ - struct testStruct { \ - void Test(int testIndex) \ - { \ - testStruct dataCopy = *this; // Info when debugging + struct testStruct \ + { \ + void Test(int testIndex) \ + { \ + testStruct dataCopy = *this; // Info when debugging -#define TEST_VARS \ - } +#define TEST_VARS } #define TEST_DATA \ - } testData[] + } \ + testData[] #define TEST_END \ - for (uint i = 0 ; i < NUMELMS(testData) ; i++) \ - testData[i].Test(i); + for (uint i = 0; i < NUMELMS(testData); i++) \ + testData[i].Test(i); /////////////////////////////////////////////////////////////// // @@ -789,7 +790,7 @@ void SharedUtil_Hash_Tests() switch (algorithm) { case HmacAlgorithm::MD5: - hmacResult = SharedUtil::Hmac(data, key); + hmacResult = SharedUtil::Hmac(data, key); break; case HmacAlgorithm::SHA1: hmacResult = SharedUtil::Hmac(data, key); @@ -946,7 +947,11 @@ void SharedUtil_Hash_Tests() TEST_END } - #define szTempFilename "hash_""\xD0""\x98""_test" +#define szTempFilename \ + "hash_" \ + "\xD0" \ + "\x98" \ + "_test" // MD5 { diff --git a/Shared/sdk/SharedUtil.Thread.h b/Shared/sdk/SharedUtil.Thread.h index 2df1742422f..916a9a87bfc 100644 --- a/Shared/sdk/SharedUtil.Thread.h +++ b/Shared/sdk/SharedUtil.Thread.h @@ -15,13 +15,13 @@ #include #ifdef WIN32 -#ifndef _WINSOCKAPI_ + #ifndef _WINSOCKAPI_ struct timeval { long tv_sec; /* seconds */ long tv_usec; /* and microseconds */ }; -#endif + #endif #else #include #endif @@ -53,7 +53,7 @@ namespace SharedUtil { pthread_mutex_t mutex; pthread_cond_t cond; - bool m_bInCondWait; // Hacky flag to avoid deadlock on dll exit + bool m_bInCondWait; // Hacky flag to avoid deadlock on dll exit public: CComboMutex() { @@ -90,14 +90,14 @@ namespace SharedUtil { // Get time now struct timeval tv; - #ifdef WIN32 +#ifdef WIN32 _timeb timeb; _ftime(&timeb); tv.tv_sec = static_cast(timeb.time); tv.tv_usec = timeb.millitm * 1000; - #else +#else gettimeofday(&tv, NULL); - #endif +#endif // Add the timeout length tv.tv_sec += uiTimeout / 1000; tv.tv_usec += (uiTimeout % 1000) * 1000; @@ -119,4 +119,4 @@ namespace SharedUtil void Signal() { pthread_cond_signal(&cond); } }; -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.ThreadPool.h b/Shared/sdk/SharedUtil.ThreadPool.h index 9fd5880f0f2..d28d5a08483 100644 --- a/Shared/sdk/SharedUtil.ThreadPool.h +++ b/Shared/sdk/SharedUtil.ThreadPool.h @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include "SharedUtil.Misc.h" namespace SharedUtil @@ -26,71 +28,116 @@ namespace SharedUtil m_vecThreads.reserve(threads); for (std::size_t i = 0; i < threads; ++i) { - m_vecThreads.emplace_back([this] { - while (true) + m_vecThreads.emplace_back( + [this] { - std::packaged_task task; + while (true) { - // Wait until either exit is signalled or a new task arrives - std::unique_lock lock(m_mutex); - m_cv.wait(lock, [this] { return m_exit || !m_tasks.empty(); }); - if (m_exit && m_tasks.empty()) - return; - task = std::move(m_tasks.front()); - m_tasks.pop(); + std::packaged_task task; + { + // Wait until either exit is signalled or a new task arrives + std::unique_lock lock(m_mutex); + m_cv.wait(lock, [this] { return m_exit || !m_tasks.empty(); }); + if (m_exit && m_tasks.empty()) + return; + task = std::move(m_tasks.front()); + m_tasks.pop(); + } + // Run the task (catch exceptions to prevent thread death) + try + { + task(false); + } + catch (...) + { + // Exception is automatically captured by std::packaged_task + // and will be re-thrown when future.get() is called. + // We must catch here to prevent the worker thread from terminating. + } } - // Run the task - task(false); - } - }); + }); } }; template auto enqueue(Func&& f, Args&&... args) { +#if __cplusplus < 201703L // C++17 + using ReturnT = typename std::result_of::type; +#else using ReturnT = std::invoke_result_t; - auto ff = std::bind(std::forward(f), std::forward(args)...); - auto* task = new std::packaged_task(ff); - - // Package the task in a wrapper with a common void result - // plus a skip flag for destruction without running the task - std::packaged_task resultTask([task](bool skip) { - if (!skip) - (*task)(); - delete task; - }); - - // Add task to queue and return future +#endif + + auto ff = std::bind(std::forward(f), std::forward(args)...); + auto task = std::make_shared>(ff); std::future res = task->get_future(); + { std::unique_lock lock(m_mutex); + if (m_exit) + { + // Return failed future instead of throwing (avoids crash if caller ignores result) + lock.unlock(); + std::promise failedPromise; + failedPromise.set_exception(std::make_exception_ptr(std::runtime_error("Cannot enqueue task: thread pool is shutting down"))); + return failedPromise.get_future(); + } + + // Wrap task with skip flag for shutdown cleanup + std::packaged_task resultTask( + [task](bool skip) + { + if (!skip) + (*task)(); + }); + m_tasks.emplace(std::move(resultTask)); } m_cv.notify_one(); return res; } - ~CThreadPool() + void shutdown() { + { + std::unique_lock lock(m_mutex); + + // Already shutting down or shut down + if (m_exit) + return; + + m_exit = true; + + // Clear all remaining tasks (they will be destroyed automatically) + while (!m_tasks.empty()) + { + m_tasks.pop(); + } + } + // Notify all threads to exit - m_exit = true; m_cv.notify_all(); + // Wait for threads to end for (std::thread& worker : m_vecThreads) { - worker.join(); + if (worker.joinable()) + worker.join(); } - // Cleanup - do + } + + ~CThreadPool() noexcept + { + try + { + shutdown(); + } + catch (...) { - if (m_tasks.empty()) - break; - // Run each task but skip execution of the actual - // function (-> just delete the task) - auto task = std::move(m_tasks.front()); - task(true); - } while (true); + // Must suppress exceptions to prevent std::terminate(). + // This should only happen if mutex operations fail (system error). + dassert(false && "Exception during thread pool destruction"); + } } static CThreadPool& getDefaultThreadPool() @@ -112,4 +159,4 @@ namespace SharedUtil { return CThreadPool::getDefaultThreadPool().enqueue(std::forward(args)...); } -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.Time.h b/Shared/sdk/SharedUtil.Time.h index 244a60f5807..c91eaa2f00e 100644 --- a/Shared/sdk/SharedUtil.Time.h +++ b/Shared/sdk/SharedUtil.Time.h @@ -23,9 +23,9 @@ namespace SharedUtil // uint GetTickCount32(); - // Forbid use of GetTickCount - #define GetTickCount GetTickCount_has_been_replaced_with_GetTickCount32 - #define GetTickCount64 GetTickCount64_wont_work_on_XP_you_IDIOT +// Forbid use of GetTickCount +#define GetTickCount GetTickCount_has_been_replaced_with_GetTickCount32 +#define GetTickCount64 GetTickCount64_wont_work_on_XP_you_IDIOT // // Retrieves the number of milliseconds that have elapsed since some arbitrary point in time. @@ -41,6 +41,8 @@ namespace SharedUtil // double GetSecondCount(); + std::int64_t GetTimestamp(); + // // Get the time as a sortable string. // Set bDate to include the date, bMs to include milliseconds @@ -166,9 +168,9 @@ namespace SharedUtil m_ppIntervalCounter = NULL; m_ucUpdateCount = 0; m_uiElapsedTime = 0; - #ifndef SHARED_UTIL_MANUAL_TIMER_INITIALIZATION +#ifndef SHARED_UTIL_MANUAL_TIMER_INITIALIZATION StaticInitialize(this); - #endif +#endif } ~CElapsedTimeApprox() @@ -278,4 +280,4 @@ namespace SharedUtil std::vector itemList; }; -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.Time.hpp b/Shared/sdk/SharedUtil.Time.hpp index f84ae8e1fe6..ae2aedbc780 100644 --- a/Shared/sdk/SharedUtil.Time.hpp +++ b/Shared/sdk/SharedUtil.Time.hpp @@ -14,7 +14,7 @@ #include "sys/time.h" #else #ifndef NOMINMAX - #define NOMINMAX + #define NOMINMAX #endif #include #endif @@ -86,6 +86,15 @@ double SharedUtil::GetSecondCount() return GetTickCount64_() * (1 / 1000.0); } +// +// Returns a timestamp in ms +// +std::int64_t SharedUtil::GetTimestamp() +{ + auto now = std::chrono::system_clock::now(); + return std::chrono::duration_cast(now.time_since_epoch()).count(); +} + // // Get the time as a sortable string. // Set bDate to include the date, bMs to include milliseconds @@ -192,41 +201,41 @@ namespace SharedUtil public: CPerModuleTickCount() { - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG m_TimeSinceUpdated.SetMaxIncrement(500); - #endif +#endif m_ResultValue.Initialize(GetTickCount64_()); } long long Get() { - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG if (m_TimeSinceUpdated.Get() > 10000) { m_TimeSinceUpdated.Reset(); OutputDebugLine("WARNING: UpdateModuleTickCount64 might not be called for the current module"); } - #endif +#endif return m_ResultValue.GetValue(); } void Update() { - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG m_TimeSinceUpdated.Reset(); - #endif +#endif m_ResultValue.SetValue(GetTickCount64_()); } protected: CThreadResultValue m_ResultValue; - #ifdef MTA_DEBUG +#ifdef MTA_DEBUG CElapsedTime m_TimeSinceUpdated; - #endif +#endif }; CPerModuleTickCount ms_PerModuleTickCount; -} // namespace SharedUtil +} // namespace SharedUtil long long SharedUtil::GetModuleTickCount64() { @@ -248,8 +257,8 @@ void SharedUtil::UpdateModuleTickCount64() // #if defined(__APPLE__) -// Apple / Darwin platforms with Mach monotonic clock support -#include + // Apple / Darwin platforms with Mach monotonic clock support + #include unsigned long GetTickCountInternal() { mach_timebase_info_data_t info; @@ -271,7 +280,7 @@ unsigned long GetTickCountInternal() unsigned long GetTickCountInternal() { #if !defined(CLOCK_MONOTONIC) - #error "This platform does not have monotonic clock support." + #error "This platform does not have monotonic clock support." #endif /* @@ -306,9 +315,9 @@ unsigned long GetTickCountInternal() #else -// Win32 platforms -#include -#pragma comment(lib, "Winmm.lib") + // Win32 platforms + #include + #pragma comment(lib, "Winmm.lib") unsigned long GetTickCountInternal() { // Uses timeGetTime() as Win32 GetTickCount() has a resolution of 16ms. @@ -340,8 +349,7 @@ TIMEUS SharedUtil::GetTimeUs() return llDuration & 0xffffffff; } #else -#include // for gettimeofday() -using namespace std; + #include // for gettimeofday() typedef long long LONGLONG; TIMEUS SharedUtil::GetTimeUs() @@ -361,8 +369,8 @@ TIMEUS SharedUtil::GetTimeUs() // compute elapsed time in us LONGLONG llDuration; - llDuration = (t2.tv_sec - t1.tv_sec) * 1000000LL; // sec to us - llDuration += (t2.tv_usec - t1.tv_usec); // us to us + llDuration = (t2.tv_sec - t1.tv_sec) * 1000000LL; // sec to us + llDuration += (t2.tv_usec - t1.tv_usec); // us to us return llDuration & 0xffffffff; } diff --git a/Shared/sdk/SharedUtil.Win32Utf8FileHooks.hpp b/Shared/sdk/SharedUtil.Win32Utf8FileHooks.hpp index d28365660f2..0cd75bcb9ec 100644 --- a/Shared/sdk/SharedUtil.Win32Utf8FileHooks.hpp +++ b/Shared/sdk/SharedUtil.Win32Utf8FileHooks.hpp @@ -11,6 +11,8 @@ #include #include +#include +#include /* The hooks in this file modify the following functions to work correctly with utf8 strings: @@ -70,14 +72,14 @@ auto ToACP(const std::filesystem::path& path) -> std::string namespace SharedUtil { - ///////////////////////////////////////////////////////////// - // - // Hook variables - // - ///////////////////////////////////////////////////////////// - #define HOOKVAR(name) \ - using FUNC_##name = decltype(&name); \ - FUNC_##name pfn##name; +///////////////////////////////////////////////////////////// +// +// Hook variables +// +///////////////////////////////////////////////////////////// +#define HOOKVAR(name) \ + using FUNC_##name = decltype(&name); \ + FUNC_##name pfn##name; HOOKVAR(CreateFileA) HOOKVAR(LoadLibraryA) @@ -98,91 +100,607 @@ namespace SharedUtil HOOKVAR(GetModuleHandleA) #ifdef MTA_CLIENT - ///////////////////////////////////////////////////////////// - // - // Ensure codepage type characters have been utf8ified - // - ///////////////////////////////////////////////////////////// + // Converts codepage paths to UTF8 SString MakeSurePathIsUTF8(const SString& strOriginal) { #ifdef UTF8_FILE_HOOKS_PERSONALITY_Core static SString gtaDirCP = ToACP(g_gtaDirectory); - static SString gtaDirUTF8 = g_gtaDirectory.u8string(); - if (strOriginal.BeginsWithI(gtaDirCP)) + static SString gtaDirUTF8 = UTF8FilePath(g_gtaDirectory); + if (!gtaDirCP.empty() && strOriginal.BeginsWithI(gtaDirCP)) { SString tail = strOriginal.SubStr(gtaDirCP.length()); return PathJoin(gtaDirUTF8, tail); } #endif - static SString strLaunchPathCP, strLaunchPathUTF8; - if (strLaunchPathCP.empty()) + struct LaunchPathInfo + { + SString cp; + SString utf8; + LaunchPathInfo() + { + char szLaunchPath[2048] = {}; + GetModuleFileNameA(NULL, szLaunchPath, NUMELMS(szLaunchPath) - 1); + cp = ExtractPath(szLaunchPath); + utf8 = GetLaunchPath(); + } + }; + static LaunchPathInfo launchPath; + + if (!launchPath.cp.empty() && strOriginal.BeginsWithI(launchPath.cp)) { - char szLaunchPath[2048]; - GetModuleFileNameA(NULL, szLaunchPath, NUMELMS(szLaunchPath) - 1); - strLaunchPathCP = ExtractPath(szLaunchPath); - strLaunchPathUTF8 = GetLaunchPath(); + SString strPathTail = strOriginal.SubStr(launchPath.cp.length()); + return PathJoin(launchPath.utf8, strPathTail); } - if (strOriginal.BeginsWithI(strLaunchPathCP)) + + struct ProfilePathInfo + { + SString cp; + SString utf8; + ProfilePathInfo() + { + char szProfilePath[MAX_PATH] = ""; + wchar_t wszProfilePath[MAX_PATH] = L""; + if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, szProfilePath)) && + SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, wszProfilePath))) + { + cp = szProfilePath; + utf8 = ToUTF8(wszProfilePath); + } + } + }; + static ProfilePathInfo profilePath; + + if (!profilePath.cp.empty() && strOriginal.BeginsWithI(profilePath.cp)) { - // Fix gta install path - SString strPathTail = strOriginal.SubStr(strLaunchPathCP.length()); - SString strNewPathName = PathJoin(strLaunchPathUTF8, strPathTail); - return strNewPathName; + SString strPathTail = strOriginal.SubStr(profilePath.cp.length()); + return PathJoin(profilePath.utf8, strPathTail); } - static SString strProfilePathCP, strProfilePathUTF8; - if (strProfilePathCP.empty()) + return strOriginal; + } +#endif + +#ifdef MTA_CLIENT + + // Reusable event handle pool for async CreateFile operations + namespace EventPool + { + constexpr size_t POOL_SIZE = 32; + static std::atomic ms_Slots[POOL_SIZE] = {}; + + static HANDLE Acquire() { - char szProfilePath[MAX_PATH] = ""; - wchar_t wszProfilePath[MAX_PATH] = L""; - SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, szProfilePath); - SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, wszProfilePath); - strProfilePathCP = szProfilePath; - strProfilePathUTF8 = ToUTF8(wszProfilePath); + for (size_t i = 0; i < POOL_SIZE; ++i) + { + HANDLE hEvent = ms_Slots[i].exchange(nullptr); + if (hEvent) + { + ResetEvent(hEvent); + return hEvent; + } + } + return CreateEventW(nullptr, TRUE, FALSE, nullptr); } - if (strOriginal.BeginsWithI(strProfilePathCP)) + + static void Release(HANDLE hEvent) { - // Fix username path - SString strPathTail = strOriginal.SubStr(strProfilePathCP.length()); - SString strNewPathName = PathJoin(strProfilePathUTF8, strPathTail); - return strNewPathName; + if (!hEvent) + return; + + for (size_t i = 0; i < POOL_SIZE; ++i) + { + HANDLE hExpected = nullptr; + if (ms_Slots[i].compare_exchange_strong(hExpected, hEvent)) + return; + } + CloseHandle(hEvent); + } + } + + // Async CreateFile with timeout to prevent NtCreateFile hangs + namespace AsyncCreateFile + { + enum class EState : int + { + Running = 0, + Completed = 1, + Abandoned = 2 + }; + + constexpr DWORD TIMEOUT_MS = 5000; + + struct SCreateFileParams + { + std::wstring wstrFileName; + DWORD dwAccess = 0; + DWORD dwShareMode = 0; + LPSECURITY_ATTRIBUTES pSecurity = nullptr; + DWORD dwDisposition = 0; + DWORD dwFlags = 0; + HANDLE hTemplateFile = nullptr; + HANDLE hResult = INVALID_HANDLE_VALUE; + DWORD dwError = ERROR_SUCCESS; + HANDLE hEvent = nullptr; + std::atomic state{0}; + }; + + constexpr size_t POOL_SIZE = 32; + static std::atomic ms_ParamsPool[POOL_SIZE] = {}; + + static SCreateFileParams* AcquireParams() + { + for (size_t i = 0; i < POOL_SIZE; ++i) + { + SCreateFileParams* pParams = ms_ParamsPool[i].exchange(nullptr); + if (pParams) + { + pParams->state = 0; + pParams->hResult = INVALID_HANDLE_VALUE; + pParams->dwError = ERROR_SUCCESS; + pParams->hEvent = nullptr; + pParams->wstrFileName.clear(); + return pParams; + } + } + return new (std::nothrow) SCreateFileParams(); + } + + static void ReleaseParams(SCreateFileParams* pParams) + { + if (!pParams) + return; + + pParams->wstrFileName.clear(); + + for (size_t i = 0; i < POOL_SIZE; ++i) + { + SCreateFileParams* pExpected = nullptr; + if (ms_ParamsPool[i].compare_exchange_strong(pExpected, pParams)) + return; + } + delete pParams; + } + + static DWORD WINAPI WorkerCallback(LPVOID pArg) + { + SCreateFileParams* pParams = static_cast(pArg); + + pParams->hResult = CreateFileW(pParams->wstrFileName.c_str(), pParams->dwAccess, pParams->dwShareMode, pParams->pSecurity, pParams->dwDisposition, + pParams->dwFlags, pParams->hTemplateFile); + pParams->dwError = GetLastError(); + + int iExpected = static_cast(EState::Running); + if (pParams->state.compare_exchange_strong(iExpected, static_cast(EState::Completed))) + { + SetEvent(pParams->hEvent); + } + else + { + EventPool::Release(pParams->hEvent); + if (pParams->hResult != INVALID_HANDLE_VALUE) + CloseHandle(pParams->hResult); + ReleaseParams(pParams); + } + return 0; + } + + static HANDLE DirectCreateFile(LPCWSTR wszFileName, DWORD dwAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES pSecurity, DWORD dwDisposition, + DWORD dwFlags, HANDLE hTemplate) + { + return CreateFileW(wszFileName, dwAccess, dwShareMode, pSecurity, dwDisposition, dwFlags, hTemplate); + } + } + + static HANDLE CreateFileWithTimeout(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) + { + using namespace AsyncCreateFile; + + if (!IsGTAProcess()) + return DirectCreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); + + // Skip async if caller provided security attributes or template (lifetime issue) + if (lpSecurityAttributes || hTemplateFile) + return DirectCreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); + + SCreateFileParams* pParams = AcquireParams(); + if (!pParams) + { + AddReportLog(6214, "CreateFile timeout: alloc failed"); + return DirectCreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); + } + + try + { + pParams->wstrFileName = lpFileName; + } + catch (...) + { + AddReportLog(6220, "CreateFile timeout: string copy failed"); + ReleaseParams(pParams); + return DirectCreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); + } + + HANDLE hEvent = EventPool::Acquire(); + if (!hEvent) + { + AddReportLog(6215, "CreateFile timeout: event failed"); + ReleaseParams(pParams); + return DirectCreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); + } + + pParams->dwAccess = dwDesiredAccess; + pParams->dwShareMode = dwShareMode; + pParams->pSecurity = lpSecurityAttributes; + pParams->dwDisposition = dwCreationDisposition; + pParams->dwFlags = dwFlagsAndAttributes; + pParams->hTemplateFile = hTemplateFile; + pParams->hEvent = hEvent; + + if (!QueueUserWorkItem(WorkerCallback, pParams, WT_EXECUTELONGFUNCTION)) + { + AddReportLog(6218, "CreateFile timeout: queue failed"); + EventPool::Release(hEvent); + ReleaseParams(pParams); + return DirectCreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); + } + + if (WaitForSingleObject(hEvent, TIMEOUT_MS) == WAIT_OBJECT_0) + { + EventPool::Release(hEvent); + HANDLE hResult = pParams->hResult; + DWORD dwError = pParams->dwError; + ReleaseParams(pParams); + SetLastError(dwError); + return hResult; + } + + // Timeout occurred + AddReportLog(6212, SString("CreateFile timed out after %ums: %s", TIMEOUT_MS, ToUTF8(lpFileName).c_str())); + + int iExpected = static_cast(EState::Running); + if (pParams->state.compare_exchange_strong(iExpected, static_cast(EState::Abandoned))) + { + SetLastError(ERROR_TIMEOUT); + } + else + { + EventPool::Release(hEvent); + DWORD dwActualError = (pParams->hResult == INVALID_HANDLE_VALUE) ? pParams->dwError : ERROR_TIMEOUT; + if (pParams->hResult != INVALID_HANDLE_VALUE) + CloseHandle(pParams->hResult); + ReleaseParams(pParams); + SetLastError(dwActualError); + } + return INVALID_HANDLE_VALUE; + } + + // Caches UTF8-to-wide path conversions + namespace PathCache + { + struct CacheEntry + { + SString strKey; + std::wstring wstrValue; + }; + + constexpr size_t CACHE_SIZE = 64; + static std::atomic ms_CacheSlots[CACHE_SIZE] = {}; + + static uint32_t ComputeHash(const char* szPath) + { + uint32_t uiHash = 5381; + while (*szPath) + { + uiHash = ((uiHash << 5) + uiHash) + static_cast(*szPath); + ++szPath; + } + return uiHash; + } + + static const std::wstring* Lookup(const char* szPath) + { + uint32_t uiIndex = ComputeHash(szPath) % CACHE_SIZE; + CacheEntry* pEntry = ms_CacheSlots[uiIndex].load(std::memory_order_acquire); + + if (pEntry && pEntry->strKey == szPath) + return &pEntry->wstrValue; + + return nullptr; + } + + static void Store(const char* szPath, const std::wstring& wstrWide) + { + uint32_t uiIndex = ComputeHash(szPath) % CACHE_SIZE; + + if (ms_CacheSlots[uiIndex].load(std::memory_order_relaxed)) + return; + + CacheEntry* pEntry = new (std::nothrow) CacheEntry(); + if (!pEntry) + return; + + try + { + pEntry->strKey = szPath; + pEntry->wstrValue = wstrWide; + } + catch (...) + { + delete pEntry; + return; + } + + CacheEntry* pExpected = nullptr; + if (!ms_CacheSlots[uiIndex].compare_exchange_strong(pExpected, pEntry, std::memory_order_release)) + delete pEntry; + } + + static const std::wstring& GetExePath() + { + static const std::wstring wstrExePath = FromUTF8(GetLaunchPathFilename()); + return wstrExePath; + } + + static const std::wstring& GetExeName() + { + static const std::wstring wstrExeName = FromUTF8(GetLaunchFilename()); + return wstrExeName; + } + + // Strips \\?\ and \\?\UNC\ prefixes + static std::wstring StripExtendedPrefix(const std::wstring& wstrPath) + { + if (wstrPath.size() < 4) + return wstrPath; + + if (wstrPath[0] != L'\\' || wstrPath[1] != L'\\' || wstrPath[2] != L'?' || wstrPath[3] != L'\\') + return wstrPath; + + if (wstrPath.size() >= 8) + { + bool bIsUNC = (wstrPath[4] == L'U' || wstrPath[4] == L'u') && (wstrPath[5] == L'N' || wstrPath[5] == L'n') && + (wstrPath[6] == L'C' || wstrPath[6] == L'c') && wstrPath[7] == L'\\'; + + if (bIsUNC) + return L"\\" + wstrPath.substr(8); + } + + return wstrPath.substr(4); + } + + static std::wstring GetFullPath(const std::wstring& wstrPath) + { + if (wstrPath.empty()) + return std::wstring(); + + DWORD dwNeeded = GetFullPathNameW(wstrPath.c_str(), 0, nullptr, nullptr); + if (dwNeeded == 0) + return wstrPath; + + std::wstring wstrResult(dwNeeded, L'\0'); + DWORD dwWritten = GetFullPathNameW(wstrPath.c_str(), dwNeeded, &wstrResult[0], nullptr); + + if (dwWritten > 0) + wstrResult.resize(dwWritten); + else + wstrResult = wstrPath; + + return wstrResult; + } + + static std::wstring ExtractDirectory(const std::wstring& wstrPath) + { + std::wstring wstrStripped = StripExtendedPrefix(wstrPath); + size_t uiPos = wstrStripped.find_last_of(L"\\/"); + + if (uiPos == std::wstring::npos) + return std::wstring(); + + return wstrStripped.substr(0, uiPos + 1); + } + + static const std::wstring& GetExeDir() + { + static const std::wstring wstrExeDir = ExtractDirectory(GetExePath()); + return wstrExeDir; + } + + static const std::wstring& GetExeDirShort() + { + struct Holder + { + std::wstring wstrValue; + Holder() + { + std::wstring wstrDir = GetExeDir(); + if (wstrDir.empty()) + return; + + if (wstrDir.back() == L'\\' || wstrDir.back() == L'/') + wstrDir.pop_back(); + + if (wstrDir.empty()) + { + wstrValue = GetExeDir(); + return; + } + + DWORD dwNeeded = GetShortPathNameW(wstrDir.c_str(), nullptr, 0); + if (dwNeeded == 0) + { + wstrValue = GetExeDir(); + return; + } + + std::wstring wstrBuffer(dwNeeded, L'\0'); + DWORD dwWritten = GetShortPathNameW(wstrDir.c_str(), &wstrBuffer[0], dwNeeded); + if (dwWritten == 0) + { + wstrValue = GetExeDir(); + return; + } + + wstrBuffer.resize(dwWritten); + wstrValue = wstrBuffer + L"\\"; + } + }; + static Holder holder; + return holder.wstrValue; + } + + static const std::wstring& GetExeShort() + { + struct Holder + { + std::wstring wstrValue; + Holder() + { + wstrValue = GetExeName(); + + const std::wstring& wstrFullPath = GetExePath(); + if (wstrFullPath.empty()) + return; + + DWORD dwNeeded = GetShortPathNameW(wstrFullPath.c_str(), nullptr, 0); + if (dwNeeded == 0) + return; + + std::wstring wstrBuffer(dwNeeded, L'\0'); + DWORD dwWritten = GetShortPathNameW(wstrFullPath.c_str(), &wstrBuffer[0], dwNeeded); + if (dwWritten == 0) + return; + + wstrBuffer.resize(dwWritten); + size_t uiPos = wstrBuffer.find_last_of(L"\\/"); + + if (uiPos == std::wstring::npos) + wstrValue = wstrBuffer; + else + wstrValue = wstrBuffer.substr(uiPos + 1); + } + }; + static Holder holder; + return holder.wstrValue; + } + + // Checks if path refers to the GTA executable (handles 8.3 names and trailing junk) + static bool IsExe(const std::wstring& wstrPath) + { + if (wstrPath.empty()) + return false; + + const std::wstring& wstrExePath = GetExePath(); + if (wstrExePath.empty()) + return false; + + if (_wcsicmp(wstrPath.c_str(), wstrExePath.c_str()) == 0) + return true; + + size_t uiPos = wstrPath.find_last_of(L"\\/"); + const wchar_t* wszName = (uiPos == std::wstring::npos) ? wstrPath.c_str() : wstrPath.c_str() + uiPos + 1; + + size_t uiLen = wcslen(wszName); + while (uiLen > 0 && (wszName[uiLen - 1] == L' ' || wszName[uiLen - 1] == L'.')) + --uiLen; + + if (uiLen == 0) + return false; + + const std::wstring& wstrExeName = GetExeName(); + if (wstrExeName.size() == uiLen && _wcsnicmp(wszName, wstrExeName.c_str(), uiLen) == 0) + return true; + + const std::wstring& wstrExeShort = GetExeShort(); + if (wstrExeShort.size() == uiLen && _wcsnicmp(wszName, wstrExeShort.c_str(), uiLen) == 0) + return true; + + return false; } - return strOriginal; } #endif - ///////////////////////////////////////////////////////////// - // - // Hook implementations - // - ///////////////////////////////////////////////////////////// HANDLE WINAPI MyCreateFileA(__in LPCSTR lpFileName, __in DWORD dwDesiredAccess, __in DWORD dwShareMode, __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes, __in DWORD dwCreationDisposition, __in DWORD dwFlagsAndAttributes, __in_opt HANDLE hTemplateFile) { - SString strFileName = lpFileName; + if (!lpFileName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return INVALID_HANDLE_VALUE; + } + #ifdef MTA_CLIENT if (IsGTAProcess()) - strFileName = MakeSurePathIsUTF8(strFileName); + { + const std::wstring* pCached = PathCache::Lookup(lpFileName); + if (pCached) + { + if (PathCache::IsExe(*pCached)) + return CreateFileWithTimeout(pCached->c_str(), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, + dwFlagsAndAttributes, hTemplateFile); + + return CreateFileW(pCached->c_str(), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, + hTemplateFile); + } + + SString strFileName = MakeSurePathIsUTF8(lpFileName); + std::wstring wstrWidePath = FromUTF8(strFileName); + PathCache::Store(lpFileName, wstrWidePath); + + if (PathCache::IsExe(wstrWidePath)) + return CreateFileWithTimeout(wstrWidePath.c_str(), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, + dwFlagsAndAttributes, hTemplateFile); + + return CreateFileW(wstrWidePath.c_str(), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, + hTemplateFile); + } #endif + SString strFileName = lpFileName; return CreateFileW(FromUTF8(strFileName), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); } HMODULE WINAPI - MyLoadLibraryA(__in LPCSTR lpLibFileName) { return LoadLibraryW(FromUTF8(lpLibFileName)); } + MyLoadLibraryA(__in LPCSTR lpLibFileName) + { + if (!lpLibFileName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + return LoadLibraryW(FromUTF8(lpLibFileName)); + } HMODULE WINAPI - MyLoadLibraryExA(__in LPCSTR lpLibFileName, __reserved HANDLE hFile, __in DWORD dwFlags) { return LoadLibraryExW(FromUTF8(lpLibFileName), hFile, dwFlags); } + MyLoadLibraryExA(__in LPCSTR lpLibFileName, __reserved HANDLE hFile, __in DWORD dwFlags) + { + if (!lpLibFileName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + return LoadLibraryExW(FromUTF8(lpLibFileName), hFile, dwFlags); + } - BOOL WINAPI MySetDllDirectoryA(__in_opt LPCSTR lpPathName) { return SetDllDirectoryW(FromUTF8(lpPathName)); } + BOOL WINAPI MySetDllDirectoryA(__in_opt LPCSTR lpPathName) + { + if (!lpPathName) + return SetDllDirectoryW(NULL); + return SetDllDirectoryW(FromUTF8(lpPathName)); + } BOOL WINAPI MySetCurrentDirectoryA(__in LPCSTR lpPathName) { + if (!lpPathName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } SString strPathName = lpPathName; #ifdef MTA_CLIENT if (IsGTAProcess()) @@ -191,12 +709,33 @@ namespace SharedUtil return SetCurrentDirectoryW(FromUTF8(strPathName)); } - int WINAPI MyAddFontResourceExA(__in LPCSTR name, __in DWORD fl, __reserved PVOID res) { return AddFontResourceExW(FromUTF8(name), fl, res); } + int WINAPI MyAddFontResourceExA(__in LPCSTR name, __in DWORD fl, __reserved PVOID res) + { + if (!name) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + return AddFontResourceExW(FromUTF8(name), fl, res); + } - BOOL WINAPI MyRemoveFontResourceExA(__in LPCSTR name, __in DWORD fl, __reserved PVOID pdv) { return RemoveFontResourceExW(FromUTF8(name), fl, pdv); } + BOOL WINAPI MyRemoveFontResourceExA(__in LPCSTR name, __in DWORD fl, __reserved PVOID pdv) + { + if (!name) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + return RemoveFontResourceExW(FromUTF8(name), fl, pdv); + } BOOL WINAPI MyRemoveDirectoryA(__in LPCSTR lpPathName) { + if (!lpPathName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } SString strPathName = lpPathName; #ifdef MTA_CLIENT if (IsGTAProcess()) @@ -208,6 +747,8 @@ namespace SharedUtil BOOL WINAPI MyGetDiskFreeSpaceExA(__in_opt LPCSTR lpDirectoryName, __out_opt PULARGE_INTEGER lpFreeBytesAvailableToCaller, __out_opt PULARGE_INTEGER lpTotalNumberOfBytes, __out_opt PULARGE_INTEGER lpTotalNumberOfFreeBytes) { + if (!lpDirectoryName) + return GetDiskFreeSpaceExW(NULL, lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes); return GetDiskFreeSpaceExW(FromUTF8(lpDirectoryName), lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes); } @@ -215,6 +756,11 @@ namespace SharedUtil WINAPI MyGetFileAttributesA(__in LPCSTR lpFileName) { + if (!lpFileName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return INVALID_FILE_ATTRIBUTES; + } SString strFileName = lpFileName; #ifdef MTA_CLIENT if (IsGTAProcess()) @@ -225,6 +771,11 @@ namespace SharedUtil BOOL WINAPI MySetFileAttributesA(__in LPCSTR lpFileName, __in DWORD dwFileAttributes) { + if (!lpFileName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } SString strFileName = lpFileName; #ifdef MTA_CLIENT if (IsGTAProcess()) @@ -235,11 +786,22 @@ namespace SharedUtil HINSTANCE STDAPICALLTYPE MyShellExecuteA(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd) { - return ShellExecuteW(hwnd, FromUTF8(lpOperation), FromUTF8(lpFile), FromUTF8(lpParameters), FromUTF8(lpDirectory), nShowCmd); + if (!lpFile) + { + SetLastError(ERROR_INVALID_PARAMETER); + return reinterpret_cast(SE_ERR_FNF); + } + return ShellExecuteW(hwnd, lpOperation ? FromUTF8(lpOperation).c_str() : NULL, FromUTF8(lpFile), lpParameters ? FromUTF8(lpParameters).c_str() : NULL, + lpDirectory ? FromUTF8(lpDirectory).c_str() : NULL, nShowCmd); } BOOL WINAPI MyCreateDirectoryA(__in LPCSTR lpPathName, __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes) { + if (!lpPathName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } SString strPathName = lpPathName; #ifdef MTA_CLIENT if (IsGTAProcess()) @@ -250,16 +812,31 @@ namespace SharedUtil BOOL WINAPI MyCopyFileA(__in LPCSTR lpExistingFileName, __in LPCSTR lpNewFileName, __in BOOL bFailIfExists) { + if (!lpExistingFileName || !lpNewFileName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } return CopyFileW(FromUTF8(lpExistingFileName), FromUTF8(lpNewFileName), bFailIfExists); } BOOL WINAPI MyMoveFileA(__in LPCSTR lpExistingFileName, __in LPCSTR lpNewFileName) { + if (!lpExistingFileName || !lpNewFileName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } return MoveFileW(FromUTF8(lpExistingFileName), FromUTF8(lpNewFileName)); } BOOL WINAPI MyDeleteFileA(__in LPCSTR lpFileName) { + if (!lpFileName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } SString strFileName = lpFileName; #ifdef MTA_CLIENT if (IsGTAProcess()) @@ -284,11 +861,11 @@ namespace SharedUtil ///////////////////////////////////////////////////////////// void AddUtf8FileHooks() { - #define ADDHOOK(module,name) \ - static_assert(std::is_same_v, "invalid type of " MTA_STR(pfn##name)); \ - pfn##name = reinterpret_cast(DetourFindFunction(module, #name)); \ - DetourAttach(&reinterpret_cast(pfn##name), My##name); \ - assert(pfn##name); +#define ADDHOOK(module, name) \ + static_assert(std::is_same_v, "invalid type of " MTA_STR(pfn##name)); \ + pfn##name = reinterpret_cast(DetourFindFunction(module, #name)); \ + DetourAttach(&reinterpret_cast(pfn##name), My##name); \ + assert(pfn##name); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); @@ -321,12 +898,12 @@ namespace SharedUtil ///////////////////////////////////////////////////////////// void RemoveUtf8FileHooks() { - #define DELHOOK(name) \ - if (pfn##name != nullptr) \ - { \ - DetourDetach(&reinterpret_cast(pfn##name), My##name); \ - pfn##name = nullptr; \ - } +#define DELHOOK(name) \ + if (pfn##name != nullptr) \ + { \ + DetourDetach(&reinterpret_cast(pfn##name), My##name); \ + pfn##name = nullptr; \ + } DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); @@ -351,4 +928,4 @@ namespace SharedUtil DetourTransactionCommit(); } -} // namespace SharedUtil +} // namespace SharedUtil diff --git a/Shared/sdk/SharedUtil.h b/Shared/sdk/SharedUtil.h index 3d4ff256dc6..837e4e49644 100644 --- a/Shared/sdk/SharedUtil.h +++ b/Shared/sdk/SharedUtil.h @@ -29,13 +29,13 @@ // Vendor #ifndef _ -#define _ //Use a dummy localisation define for modules that don't need it + #define _ // Use a dummy localisation define for modules that don't need it #endif #include "SString.h" #include "WString.h" -#define _E(code) SString(" [%s]",code) +#define _E(code) SString(" [%s]", code) #include "SharedUtil.Legacy.h" #include "SharedUtil.Map.h" @@ -67,21 +67,21 @@ #include "CDuplicateLineFilter.h" #ifdef _MSC_VER -#define snprintf _snprintf + #define snprintf _snprintf #endif #ifndef stricmp -#ifdef _MSC_VER -#define stricmp _stricmp -#else -#define stricmp strcasecmp -#endif + #ifdef _MSC_VER + #define stricmp _stricmp + #else + #define stricmp strcasecmp + #endif #endif #ifndef strnicmp -#ifdef _MSC_VER -#define strnicmp _strnicmp -#else -#define strnicmp strncasecmp -#endif + #ifdef _MSC_VER + #define strnicmp _strnicmp + #else + #define strnicmp strncasecmp + #endif #endif diff --git a/Shared/sdk/UTF8.hpp b/Shared/sdk/UTF8.hpp index 50091956bd2..3f845b2413c 100644 --- a/Shared/sdk/UTF8.hpp +++ b/Shared/sdk/UTF8.hpp @@ -26,14 +26,14 @@ #include "UTF8.h" /* Return code if invalid. (xxx_mbtowc, xxx_wctomb) */ -#define RET_ILSEQ 0 +#define RET_ILSEQ 0 /* Return code if only a shift sequence of n bytes was read. (xxx_mbtowc) */ -#define RET_TOOFEW(n) (-1-(n)) +#define RET_TOOFEW(n) (-1 - (n)) /* Return code if output buffer is too small. (xxx_wctomb, xxx_reset) */ -#define RET_TOOSMALL -1 +#define RET_TOOSMALL -1 /* Replacement character for invalid multibyte sequence or wide character. */ -#define BAD_WCHAR ((wchar_t) 0xfffd) -#define BAD_CHAR '?' +#define BAD_WCHAR ((wchar_t)0xfffd) +#define BAD_CHAR '?' int utf8_mbtowc(wchar_t* pwc, const unsigned char* src, int src_len) { diff --git a/Shared/sdk/UTF8Detect.hpp b/Shared/sdk/UTF8Detect.hpp index 902e9c36ad5..a5be5e5492a 100644 --- a/Shared/sdk/UTF8Detect.hpp +++ b/Shared/sdk/UTF8Detect.hpp @@ -60,7 +60,7 @@ int icu_getUTF8Confidence(const unsigned char* input, int len) if ((b & 0x80) == 0) { - continue; // ASCII + continue; // ASCII } // Hi bit on char found. Figure out how long the sequence should be diff --git a/Shared/sdk/WString.h b/Shared/sdk/WString.h index ac3ca48abec..7bcd2852db8 100644 --- a/Shared/sdk/WString.h +++ b/Shared/sdk/WString.h @@ -16,9 +16,9 @@ #include "SString.h" #ifdef WIN32 -#ifndef va_copy - #define va_copy(dest, orig) (dest) = (orig) -#endif + #ifndef va_copy + #define va_copy(dest, orig) (dest) = (orig) + #endif #endif // @@ -36,7 +36,7 @@ class WString : public std::wstring WString(const char* szText); - WString(const char16_t* szText) : std::wstring(szText ? (const wchar_t*)szText : L""){}; + WString(const char16_t* szText) : std::wstring(szText ? (const wchar_t*)szText : L"") {}; explicit WString(const wchar_t* szFormat, ...) : std::wstring() { @@ -74,7 +74,7 @@ class WString : public std::wstring WString operator+(const WString& other) const { return std::wstring(*this) + other; } // Assignment - operator const wchar_t*() const { return c_str(); } // Auto assign to const wchar_t* without using c_str() + operator const wchar_t*() const { return c_str(); } // Auto assign to const wchar_t* without using c_str() const wchar_t* operator*() const { return c_str(); } // Functions diff --git a/Shared/sdk/enums/MarkerDisplay.h b/Shared/sdk/enums/MarkerDisplay.h index b41f46344ea..ed81618251c 100644 --- a/Shared/sdk/enums/MarkerDisplay.h +++ b/Shared/sdk/enums/MarkerDisplay.h @@ -14,8 +14,8 @@ enum class MarkerDisplay : std::uint8_t { - MARKER_DISPLAY_NEITHER = 0, // BLIPDISPLAY_NEITHER - MARKER_DISPLAY_MARKERONLY, // BLIPDISPLAY_MARKERONLY - MARKER_DISPLAY_BLIPONLY, // MARKER_DISPLAY_BLIPONLY - MARKER_DISPLAY_BOTH // BLIPDISPLAY_BOTH + MARKER_DISPLAY_NEITHER = 0, // BLIPDISPLAY_NEITHER + MARKER_DISPLAY_MARKERONLY, // BLIPDISPLAY_MARKERONLY + MARKER_DISPLAY_BLIPONLY, // MARKER_DISPLAY_BLIPONLY + MARKER_DISPLAY_BOTH // BLIPDISPLAY_BOTH }; diff --git a/Shared/sdk/enums/ObjectGroupPhysicalProperties.h b/Shared/sdk/enums/ObjectGroupPhysicalProperties.h index 774fd84b3c4..6532a1e95e1 100644 --- a/Shared/sdk/enums/ObjectGroupPhysicalProperties.h +++ b/Shared/sdk/enums/ObjectGroupPhysicalProperties.h @@ -74,4 +74,4 @@ namespace ObjectGroupPhysicalProperties BY_GUN, SMASHABLE, }; -} // namespace ObjectGroupPhysicalProperties +} // namespace ObjectGroupPhysicalProperties diff --git a/Shared/sdk/enums/PedMoveState.h b/Shared/sdk/enums/PedMoveState.h new file mode 100644 index 00000000000..0e8c1f9a87d --- /dev/null +++ b/Shared/sdk/enums/PedMoveState.h @@ -0,0 +1,27 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: sdk/PedMoveState.h + * PURPOSE: Header for common definitions + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +namespace PedMoveState +{ + enum Enum + { + PEDMOVE_NONE = 0, + PEDMOVE_STILL, + PEDMOVE_TURN_L, + PEDMOVE_TURN_R, + PEDMOVE_WALK, + PEDMOVE_JOG, + PEDMOVE_RUN, + PEDMOVE_SPRINT, + }; +} diff --git a/Shared/sdk/enums/PedState.h b/Shared/sdk/enums/PedState.h index 25d9c815fca..429c7199747 100644 --- a/Shared/sdk/enums/PedState.h +++ b/Shared/sdk/enums/PedState.h @@ -30,14 +30,14 @@ enum class PedState PED_DUMMY, PED_PAUSE, PED_ATTACK, - PED_FIGHT, // new close combat fist fight mode + PED_FIGHT, // new close combat fist fight mode PED_FACE_PHONE, PED_MAKE_PHONECALL, PED_CHAT, PED_MUG, PED_AIMGUN, PED_AI_CONTROL, - PED_SEEK_CAR, // 24 + PED_SEEK_CAR, // 24 PED_SEEK_BOAT_POSITION, PED_FOLLOW_ROUTE, PED_CPR, @@ -51,7 +51,7 @@ enum class PedState PED_JOG, PED_ANSWER_MOBILE, PED_HANG_OUT, - PED_STATES_NO_AI, // only put states after here that do not require AI, put other ones before this + PED_STATES_NO_AI, // only put states after here that do not require AI, put other ones before this PED_ABSEIL_FROM_HELI, PED_SIT, PED_JUMP, @@ -59,11 +59,11 @@ enum class PedState PED_GETUP, PED_STAGGER, PED_EVADE_DIVE, - PED_STATES_CAN_SHOOT, // only put states before here than ped can be shot during + PED_STATES_CAN_SHOOT, // only put states before here than ped can be shot during PED_ENTER_TRAIN, PED_EXIT_TRAIN, PED_ARREST_PLAYER, - PED_DRIVING, // 50 + PED_DRIVING, // 50 PED_PASSENGER, PED_TAXI_PASSENGER, PED_OPEN_DOOR, diff --git a/Shared/sdk/enums/PostFXType.h b/Shared/sdk/enums/PostFXType.h new file mode 100644 index 00000000000..9186518abb3 --- /dev/null +++ b/Shared/sdk/enums/PostFXType.h @@ -0,0 +1,18 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: sdk/PostFXType.h + * PURPOSE: Header for common definitions + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +enum class PostFXType +{ + GAMMA, + BRIGHTNESS, + CONTRAST, + SATURATION +}; diff --git a/Shared/sdk/enums/SoundEffectParams.h b/Shared/sdk/enums/SoundEffectParams.h index b7b5b93ed4f..a246246d4bb 100644 --- a/Shared/sdk/enums/SoundEffectParams.h +++ b/Shared/sdk/enums/SoundEffectParams.h @@ -99,4 +99,4 @@ namespace eSoundEffectParams REVERB_TIME, HIGH_FREQ_RT_RATIO, }; -} // namespace eSoundEffectParams +} // namespace eSoundEffectParams diff --git a/Shared/sdk/enums/SurfaceType.h b/Shared/sdk/enums/SurfaceType.h new file mode 100644 index 00000000000..fa7bf54ef89 --- /dev/null +++ b/Shared/sdk/enums/SurfaceType.h @@ -0,0 +1,198 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: sdk/SurfaceType.h + * PURPOSE: Header for common definitions + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +namespace SurfaceTypes +{ + enum Enum : std::uint8_t + { + SURFACE_DEFAULT = 0, + SURFACE_TARMAC, + SURFACE_TARMAC_FUCKED, + SURFACE_TARMAC_REALLYFUCKED, + SURFACE_PAVEMENT, + SURFACE_PAVEMENT_FUCKED, + SURFACE_GRAVEL, + SURFACE_FUCKED_CONCRETE, + SURFACE_PAINTED_GROUND, + SURFACE_GRASS_SHORT_LUSH, + SURFACE_GRASS_MEDIUM_LUSH, + SURFACE_GRASS_LONG_LUSH, + SURFACE_GRASS_SHORT_DRY, + SURFACE_GRASS_MEDIUM_DRY, + SURFACE_GRASS_LONG_DRY, + SURFACE_GOLFGRASS_ROUGH, + SURFACE_GOLFGRASS_SMOOTH, + SURFACE_STEEP_SLIDYGRASS, + SURFACE_STEEP_CLIFF, + SURFACE_FLOWERBED, + SURFACE_MEADOW, + SURFACE_WASTEGROUND, + SURFACE_WOODLANDGROUND, + SURFACE_VEGETATION, + SURFACE_MUD_WET, + SURFACE_MUD_DRY, + SURFACE_DIRT, + SURFACE_DIRTTRACK, + SURFACE_SAND_DEEP, + SURFACE_SAND_MEDIUM, + SURFACE_SAND_COMPACT, + SURFACE_SAND_ARID, + SURFACE_SAND_MORE, + SURFACE_SAND_BEACH, + SURFACE_CONCRETE_BEACH, + SURFACE_ROCK_DRY, + SURFACE_ROCK_WET, + SURFACE_ROCK_CLIFF, + SURFACE_WATER_RIVERBED, + SURFACE_WATER_SHALLOW, + SURFACE_CORNFIELD, + SURFACE_HEDGE, + SURFACE_WOOD_CRATES, + SURFACE_WOOD_SOLID, + SURFACE_WOOD_THIN, + SURFACE_GLASS, + SURFACE_GLASS_WINDOWS_LARGE, + SURFACE_GLASS_WINDOWS_SMALL, + SURFACE_EMPTY1, + SURFACE_EMPTY2, + SURFACE_GARAGE_DOOR, + SURFACE_THICK_METAL_PLATE, + SURFACE_SCAFFOLD_POLE, + SURFACE_LAMP_POST, + SURFACE_METAL_GATE, + SURFACE_METAL_CHAIN_FENCE, + SURFACE_GIRDER, + SURFACE_FIRE_HYDRANT, + SURFACE_CONTAINER, + SURFACE_NEWS_VENDOR, + SURFACE_WHEELBASE, + SURFACE_CARDBOARDBOX, + SURFACE_PED, + SURFACE_CAR, + SURFACE_CAR_PANEL, + SURFACE_CAR_MOVINGCOMPONENT, + SURFACE_TRANSPARENT_CLOTH, + SURFACE_RUBBER, + SURFACE_PLASTIC, + SURFACE_TRANSPARENT_STONE, + SURFACE_WOOD_BENCH, + SURFACE_CARPET, + SURFACE_FLOORBOARD, + SURFACE_STAIRSWOOD, + SURFACE_P_SAND, + SURFACE_P_SAND_DENSE, + SURFACE_P_SAND_ARID, + SURFACE_P_SAND_COMPACT, + SURFACE_P_SAND_ROCKY, + SURFACE_P_SANDBEACH, + SURFACE_P_GRASS_SHORT, + SURFACE_P_GRASS_MEADOW, + SURFACE_P_GRASS_DRY, + SURFACE_P_WOODLAND, + SURFACE_P_WOODDENSE, + SURFACE_P_ROADSIDE, + SURFACE_P_ROADSIDEDES, + SURFACE_P_FLOWERBED, + SURFACE_P_WASTEGROUND, + SURFACE_P_CONCRETE, + SURFACE_P_OFFICEDESK, + SURFACE_P_711SHELF1, + SURFACE_P_711SHELF2, + SURFACE_P_711SHELF3, + SURFACE_P_RESTUARANTTABLE, + SURFACE_P_BARTABLE, + SURFACE_P_UNDERWATERLUSH, + SURFACE_P_UNDERWATERBARREN, + SURFACE_P_UNDERWATERCORAL, + SURFACE_P_UNDERWATERDEEP, + SURFACE_P_RIVERBED, + SURFACE_P_RUBBLE, + SURFACE_P_BEDROOMFLOOR, + SURFACE_P_KIRCHENFLOOR, + SURFACE_P_LIVINGRMFLOOR, + SURFACE_P_CORRIDORFLOOR, + SURFACE_P_711FLOOR, + SURFACE_P_FASTFOODFLOOR, + SURFACE_P_SKANKYFLOOR, + SURFACE_P_MOUNTAIN, + SURFACE_P_MARSH, + SURFACE_P_BUSHY, + SURFACE_P_BUSHYMIX, + SURFACE_P_BUSHYDRY, + SURFACE_P_BUSHYMID, + SURFACE_P_GRASSWEEFLOWERS, + SURFACE_P_GRASSDRYTALL, + SURFACE_P_GRASSLUSHTALL, + SURFACE_P_GRASSGRNMIX, + SURFACE_P_GRASSBRNMIX, + SURFACE_P_GRASSLOW, + SURFACE_P_GRASSROCKY, + SURFACE_P_GRASSSMALLTREES, + SURFACE_P_DIRTROCKY, + SURFACE_P_DIRTWEEDS, + SURFACE_P_GRASSWEEDS, + SURFACE_P_RIVEREDGE, + SURFACE_P_POOLSIDE, + SURFACE_P_FORESTSTUMPS, + SURFACE_P_FORESTSTICKS, + SURFACE_P_FORRESTLEAVES, + SURFACE_P_DESERTROCKS, + SURFACE_P_FORRESTDRY, + SURFACE_P_SPARSEFLOWERS, + SURFACE_P_BUILDINGSITE, + SURFACE_P_DOCKLANDS, + SURFACE_P_INDUSTRIAL, + SURFACE_P_INDUSTJETTY, + SURFACE_P_CONCRETELITTER, + SURFACE_P_ALLEYRUBISH, + SURFACE_P_JUNKYARDPILES, + SURFACE_P_JUNKYARDGRND, + SURFACE_P_DUMP, + SURFACE_P_CACTUSDENSE, + SURFACE_P_AIRPORTGRND, + SURFACE_P_CORNFIELD, + SURFACE_P_GRASSLIGHT, + SURFACE_P_GRASSLIGHTER, + SURFACE_P_GRASSLIGHTER2, + SURFACE_P_GRASSMID1, + SURFACE_P_GRASSMID2, + SURFACE_P_GRASSDARK, + SURFACE_P_GRASSDARK2, + SURFACE_P_GRASSDIRTMIX, + SURFACE_P_RIVERBEDSTONE, + SURFACE_P_RIVERBEDSHALLOW, + SURFACE_P_RIVERBEDWEEDS, + SURFACE_P_SEAWEED, + SURFACE_DOOR, + SURFACE_PLASTICBARRIER, + SURFACE_PARKGRASS, + SURFACE_STAIRSSTONE, + SURFACE_STAIRSMETAL, + SURFACE_STAIRSCARPET, + SURFACE_FLOORMETAL, + SURFACE_FLOORCONCRETE, + SURFACE_BIN_BAG, + SURFACE_THIN_METAL_SHEET, + SURFACE_METAL_BARREL, + SURFACE_PLASTIC_CONE, + SURFACE_PLASTIC_DUMPSTER, + SURFACE_METAL_DUMPSTER, + SURFACE_WOOD_PICKET_FENCE, + SURFACE_WOOD_SLATTED_FENCE, + SURFACE_WOOD_RANCH_FENCE, + SURFACE_UNBREAKABLE_GLASS, + SURFACE_HAY_BALE, + SURFACE_GORE, + SURFACE_RAILTRACK, + }; +} diff --git a/Shared/sdk/enums/WeaponProperty.h b/Shared/sdk/enums/WeaponProperty.h index 79fc9dbee93..d6851a5f1f4 100644 --- a/Shared/sdk/enums/WeaponProperty.h +++ b/Shared/sdk/enums/WeaponProperty.h @@ -56,27 +56,27 @@ enum class WeaponProperty WEAPON_DEFAULT_COMBO, WEAPON_COMBOS_AVAILABLE, - WEAPON_FLAG_AIM_NO_AUTO, // 0x000001 - cant auto target to aim (disable automatic up/down adjustment when firing without aiming) + WEAPON_FLAG_AIM_NO_AUTO, // 0x000001 - cant auto target to aim (disable automatic up/down adjustment when firing without aiming) WEAPON_FLAG_FIRST = WEAPON_FLAG_AIM_NO_AUTO, - WEAPON_FLAG_AIM_ARM, // 0x000002 - only needs arm to aim (ie pistol/shotgun/tec9/uzi) - WEAPON_FLAG_AIM_1ST_PERSON, // 0x000004 - uses 1st person aim (ie sniper/rpg-hs - WEAPON_FLAG_AIM_FREE, // 0x000008 - can only use free aiming (ie country sniper/flame thrower/minigun/fire extinguisher) - WEAPON_FLAG_MOVE_AND_AIM, // 0x000010 - can move and aim at same time - WEAPON_FLAG_MOVE_AND_SHOOT, // 0x000020 - can move and fire at same time + WEAPON_FLAG_AIM_ARM, // 0x000002 - only needs arm to aim (ie pistol/shotgun/tec9/uzi) + WEAPON_FLAG_AIM_1ST_PERSON, // 0x000004 - uses 1st person aim (ie sniper/rpg-hs + WEAPON_FLAG_AIM_FREE, // 0x000008 - can only use free aiming (ie country sniper/flame thrower/minigun/fire extinguisher) + WEAPON_FLAG_MOVE_AND_AIM, // 0x000010 - can move and aim at same time + WEAPON_FLAG_MOVE_AND_SHOOT, // 0x000020 - can move and fire at same time WEAPON_FLAG_UNKNOWN_0040, WEAPON_FLAG_UNKNOWN_0080, - WEAPON_FLAG_TYPE_THROW, // 0x000100 - is a throwing weapon (ie satchel) - WEAPON_FLAG_TYPE_HEAVY, // 0x000200 - heavy weapon - can't jump (ie flame thrower/rpgs/minigun) - WEAPON_FLAG_TYPE_CONSTANT, // 0x000400 - fires every frame within loop (ie paint spray) - WEAPON_FLAG_TYPE_DUAL, // 0x000800 - can use 2x guns at same time (ie pistol/shotgun/tec9/uzi) - WEAPON_FLAG_ANIM_RELOAD, // 0x001000 - weapon has reload anims (ie everything except shotgun/snipers/flame thrower/rpgs/minigun/satchel) - WEAPON_FLAG_ANIM_CROUCH, // 0x002000 - weapon has crouching anims (ie everything except flame thrower/rpgs/minigun/satchel) - WEAPON_FLAG_ANIM_RELOAD_LOOP, // 0x004000 - loop from end of reload to fire loop start - WEAPON_FLAG_ANIM_RELOAD_LONG, // 0x008000 - force a longer reload time! (ie rpgs/snipers) - WEAPON_FLAG_SHOT_SLOWS, // 0x010000 - slows down (ie flame thrower) - WEAPON_FLAG_SHOT_RAND_SPEED, // 0x020000 - random speed (ie flame thrower) - WEAPON_FLAG_SHOT_ANIM_ABRUPT, // 0x040000 - force the anim to finish player after aim/fire rather than blending out (ie rpgs) - WEAPON_FLAG_SHOT_EXPANDS, // 0x080000 - expands + WEAPON_FLAG_TYPE_THROW, // 0x000100 - is a throwing weapon (ie satchel) + WEAPON_FLAG_TYPE_HEAVY, // 0x000200 - heavy weapon - can't jump (ie flame thrower/rpgs/minigun) + WEAPON_FLAG_TYPE_CONSTANT, // 0x000400 - fires every frame within loop (ie paint spray) + WEAPON_FLAG_TYPE_DUAL, // 0x000800 - can use 2x guns at same time (ie pistol/shotgun/tec9/uzi) + WEAPON_FLAG_ANIM_RELOAD, // 0x001000 - weapon has reload anims (ie everything except shotgun/snipers/flame thrower/rpgs/minigun/satchel) + WEAPON_FLAG_ANIM_CROUCH, // 0x002000 - weapon has crouching anims (ie everything except flame thrower/rpgs/minigun/satchel) + WEAPON_FLAG_ANIM_RELOAD_LOOP, // 0x004000 - loop from end of reload to fire loop start + WEAPON_FLAG_ANIM_RELOAD_LONG, // 0x008000 - force a longer reload time! (ie rpgs/snipers) + WEAPON_FLAG_SHOT_SLOWS, // 0x010000 - slows down (ie flame thrower) + WEAPON_FLAG_SHOT_RAND_SPEED, // 0x020000 - random speed (ie flame thrower) + WEAPON_FLAG_SHOT_ANIM_ABRUPT, // 0x040000 - force the anim to finish player after aim/fire rather than blending out (ie rpgs) + WEAPON_FLAG_SHOT_EXPANDS, // 0x080000 - expands WEAPON_FLAG_LAST = WEAPON_FLAG_SHOT_EXPANDS, WEAPON_FIRE_ROTATION, diff --git a/Shared/sdk/net/CNetHTTPDownloadManagerInterface.h b/Shared/sdk/net/CNetHTTPDownloadManagerInterface.h index 2bd5a647bf7..741cebf9659 100644 --- a/Shared/sdk/net/CNetHTTPDownloadManagerInterface.h +++ b/Shared/sdk/net/CNetHTTPDownloadManagerInterface.h @@ -20,14 +20,14 @@ struct SHttpRequestOptions { SHttpRequestOptions() {} SHttpRequestOptions(const struct SHttpRequestOptionsTx& in); - bool bIsLegacy = false; // true = sets CURLOPT_FAILONERROR - bool bIsLocal = false; // false = download aborts if < 10 bytes/s for uiConnectTimeoutMs - bool bCheckContents = false; // true = check for naughty things before saving file - bool bResumeFile = false; // true = attempt to resume previously interrupted download + bool bIsLegacy = false; // true = sets CURLOPT_FAILONERROR + bool bIsLocal = false; // false = download aborts if < 10 bytes/s for uiConnectTimeoutMs + bool bCheckContents = false; // true = check for naughty things before saving file + bool bResumeFile = false; // true = attempt to resume previously interrupted download SString strPostData; - bool bPostBinary = false; // false = truncate strPostData to first null character and send as text/plain - // (true = send as application/octet-stream) - std::map formFields; // If set, send items as multipart/formdata (and ignore strPostData) + bool bPostBinary = false; // false = truncate strPostData to first null character and send as text/plain + // (true = send as application/octet-stream) + std::map formFields; // If set, send items as multipart/formdata (and ignore strPostData) uint uiConnectionAttempts = 10; uint uiConnectTimeoutMs = 10000; SString strRequestMethod; @@ -152,9 +152,9 @@ inline SHttpRequestOptionsTx::SHttpRequestOptionsTx(const SHttpRequestOptions& i struct SDownloadStatus { - uint uiAttemptNumber = 0; // 0=Queued 1+=Downloading - uint uiContentLength = 0; // Item total size. Will be 0 if http header 'Content-Length' is missing - uint uiBytesReceived = 0; // Download progress + uint uiAttemptNumber = 0; // 0=Queued 1+=Downloading + uint uiContentLength = 0; // Item total size. Will be 0 if http header 'Content-Length' is missing + uint uiBytesReceived = 0; // Download progress }; // PFN_DOWNLOAD_FINISHED_CALLBACK is called once at the end of the download. diff --git a/Shared/sdk/net/SyncStructures.h b/Shared/sdk/net/SyncStructures.h index 87109e3202f..8c3276be531 100644 --- a/Shared/sdk/net/SyncStructures.h +++ b/Shared/sdk/net/SyncStructures.h @@ -57,9 +57,9 @@ struct SFloatSync : public ISyncStructure double dValue = data.fValue; #ifdef WIN32 -#ifdef MTA_DEBUG + #ifdef MTA_DEBUG assert(!std::isnan(dValue)); -#endif + #endif #endif dValue = Clamp(limitsMin, dValue, limitsMax); @@ -544,33 +544,12 @@ struct SPlayerPuresyncFlags : public ISyncStructure { enum { - BITCOUNT = 12 - }; - - enum - { - BITCOUNT2 = 1 + BITCOUNT = 15 }; - bool Read(NetBitStreamInterface& stream) - { - bool ok = stream.ReadBits((char*)&data, BITCOUNT); - - if (stream.Can(eBitStreamVersion::IsPedReloadingWeapon)) - ok &= stream.ReadBits((char*)&data2, BITCOUNT2); - else - data2.isReloadingWeapon = 0; - - return ok; - } + bool Read(NetBitStreamInterface& stream) { return stream.ReadBits((char*)&data, BITCOUNT); } - void Write(NetBitStreamInterface& stream) const - { - stream.WriteBits((const char*)&data, BITCOUNT); - - if (stream.Can(eBitStreamVersion::IsPedReloadingWeapon)) - stream.WriteBits((const char*)&data2, BITCOUNT2); - } + void Write(NetBitStreamInterface& stream) const { stream.WriteBits((const char*)&data, BITCOUNT); } struct { @@ -586,12 +565,10 @@ struct SPlayerPuresyncFlags : public ISyncStructure bool bHasAWeapon : 1; bool bSyncingVelocity : 1; bool bStealthAiming : 1; - } data; - - struct - { bool isReloadingWeapon : 1; - } data2; + bool animInterrupted : 1; + bool hangingDuringClimb : 1; + } data; }; struct SPedRotationSync : public ISyncStructure @@ -907,26 +884,23 @@ struct SFullKeysyncSync : public ISyncStructure bitStream.ReadBits((char*)&data, 8); - if (bitStream.Can(eBitStreamVersion::AnalogControlSync_AccelBrakeReverse)) + if (bitStream.ReadBit()) { - if (bitStream.ReadBit()) - { - unsigned char ucButtonSquare; - bitStream.Read(ucButtonSquare); - data.ucButtonSquare = ucButtonSquare; - } - else - data.ucButtonSquare = 0; + unsigned char ucButtonSquare; + bitStream.Read(ucButtonSquare); + data.ucButtonSquare = ucButtonSquare; + } + else + data.ucButtonSquare = 0; - if (bitStream.ReadBit()) - { - unsigned char ucButtonCross; - bitStream.Read(ucButtonCross); - data.ucButtonCross = ucButtonCross; - } - else - data.ucButtonCross = 0; + if (bitStream.ReadBit()) + { + unsigned char ucButtonCross; + bitStream.Read(ucButtonCross); + data.ucButtonCross = ucButtonCross; } + else + data.ucButtonCross = 0; bitStream.Read(cLeftStickX); if (bitStream.Read(cLeftStickY)) @@ -941,24 +915,21 @@ struct SFullKeysyncSync : public ISyncStructure { bitStream.WriteBits((const char*)&data, 8); - if (bitStream.Can(eBitStreamVersion::AnalogControlSync_AccelBrakeReverse)) + if (data.ucButtonSquare >= 1 && data.ucButtonSquare <= 254) { - if (data.ucButtonSquare >= 1 && data.ucButtonSquare <= 254) - { - bitStream.WriteBit(true); - bitStream.Write(data.ucButtonSquare); - } - else - bitStream.WriteBit(false); + bitStream.WriteBit(true); + bitStream.Write(data.ucButtonSquare); + } + else + bitStream.WriteBit(false); - if (data.ucButtonCross >= 1 && data.ucButtonCross <= 254) - { - bitStream.WriteBit(true); - bitStream.Write(data.ucButtonCross); - } - else - bitStream.WriteBit(false); + if (data.ucButtonCross >= 1 && data.ucButtonCross <= 254) + { + bitStream.WriteBit(true); + bitStream.Write(data.ucButtonCross); } + else + bitStream.WriteBit(false); char cLeftStickX = static_cast((float)data.sLeftStickX * 127.0f / 128.0f); bitStream.Write(cLeftStickX); @@ -996,26 +967,23 @@ struct SSmallKeysyncSync : public ISyncStructure bitStream.ReadBits((char*)&data, 8); - if (bitStream.Can(eBitStreamVersion::AnalogControlSync_AccelBrakeReverse)) + if (bitStream.ReadBit()) { - if (bitStream.ReadBit()) - { - unsigned char ucButtonSquare; - bitStream.Read(ucButtonSquare); - data.ucButtonSquare = ucButtonSquare; - } - else - data.ucButtonSquare = 0; + unsigned char ucButtonSquare; + bitStream.Read(ucButtonSquare); + data.ucButtonSquare = ucButtonSquare; + } + else + data.ucButtonSquare = 0; - if (bitStream.ReadBit()) - { - unsigned char ucButtonCross; - bitStream.Read(ucButtonCross); - data.ucButtonCross = ucButtonCross; - } - else - data.ucButtonCross = 0; + if (bitStream.ReadBit()) + { + unsigned char ucButtonCross; + bitStream.Read(ucButtonCross); + data.ucButtonCross = ucButtonCross; } + else + data.ucButtonCross = 0; bitStream.Read(cLeftStickX); if (bitStream.Read(cLeftStickY)) @@ -1030,24 +998,21 @@ struct SSmallKeysyncSync : public ISyncStructure { bitStream.WriteBits((const char*)&data, 8); - if (bitStream.Can(eBitStreamVersion::AnalogControlSync_AccelBrakeReverse)) + if (data.ucButtonSquare >= 1 && data.ucButtonSquare <= 254) { - if (data.ucButtonSquare >= 1 && data.ucButtonSquare <= 254) - { - bitStream.WriteBit(true); - bitStream.Write(data.ucButtonSquare); - } - else - bitStream.WriteBit(false); + bitStream.WriteBit(true); + bitStream.Write(data.ucButtonSquare); + } + else + bitStream.WriteBit(false); - if (data.ucButtonCross >= 1 && data.ucButtonCross <= 254) - { - bitStream.WriteBit(true); - bitStream.Write(data.ucButtonCross); - } - else - bitStream.WriteBit(false); + if (data.ucButtonCross >= 1 && data.ucButtonCross <= 254) + { + bitStream.WriteBit(true); + bitStream.Write(data.ucButtonCross); } + else + bitStream.WriteBit(false); char cLeftStickX = static_cast((float)data.sLeftStickX * 127.0f / 128.0f); bitStream.Write(cLeftStickX); @@ -1723,49 +1688,49 @@ struct SVehicleHandlingSync : public ISyncStructure struct { - float fMass; // +4 + float fMass; // +4 - float fTurnMass; // +12 - float fDragCoeff; // +16 - CVector vecCenterOfMass; // +20 - unsigned char ucPercentSubmerged; // +32 (unsigned int - sync changes) + float fTurnMass; // +12 + float fDragCoeff; // +16 + CVector vecCenterOfMass; // +20 + unsigned char ucPercentSubmerged; // +32 (unsigned int - sync changes) - float fTractionMultiplier; // +40 + float fTractionMultiplier; // +40 - unsigned char ucDriveType; // +112 - unsigned char ucEngineType; // +113 - unsigned char ucNumberOfGears; // +114 + unsigned char ucDriveType; // +112 + unsigned char ucEngineType; // +113 + unsigned char ucNumberOfGears; // +114 - float fEngineAcceleration; // +120 (value in handling.cfg * 0x86A950) - float fEngineInertia; // +124 - float fMaxVelocity; // +128 + float fEngineAcceleration; // +120 (value in handling.cfg * 0x86A950) + float fEngineInertia; // +124 + float fMaxVelocity; // +128 - float fBrakeDeceleration; // +148 - float fBrakeBias; // +152 - bool bABS; // +156 + float fBrakeDeceleration; // +148 + float fBrakeBias; // +152 + bool bABS; // +156 - float fSteeringLock; // +160 - float fTractionLoss; // +164 - float fTractionBias; // +168 + float fSteeringLock; // +160 + float fTractionLoss; // +164 + float fTractionBias; // +168 - float fSuspensionForceLevel; // +172 - float fSuspensionDamping; // +176 - float fSuspensionHighSpdDamping; // +180 - float fSuspensionUpperLimit; // +184 - float fSuspensionLowerLimit; // +188 - float fSuspensionFrontRearBias; // +192 - float fSuspensionAntiDiveMultiplier; // +196 + float fSuspensionForceLevel; // +172 + float fSuspensionDamping; // +176 + float fSuspensionHighSpdDamping; // +180 + float fSuspensionUpperLimit; // +184 + float fSuspensionLowerLimit; // +188 + float fSuspensionFrontRearBias; // +192 + float fSuspensionAntiDiveMultiplier; // +196 - float fCollisionDamageMultiplier; // +200 + float fCollisionDamageMultiplier; // +200 - unsigned int uiModelFlags; // +204 - unsigned int uiHandlingFlags; // +208 - float fSeatOffsetDistance; // +212 + unsigned int uiModelFlags; // +204 + unsigned int uiHandlingFlags; // +208 + float fSeatOffsetDistance; // +212 // unsigned int uiMonetary; // +216 // unsigned char ucHeadLight; // +220 // unsigned char ucTailLight; // +221 - unsigned char ucAnimGroup; // +222 + unsigned char ucAnimGroup; // +222 } data; }; @@ -1946,77 +1911,28 @@ struct SFunBugsStateSync : public ISyncStructure { enum { - BITCOUNT = 5 - }; - enum - { - BITCOUNT2 = 1 - }; - enum - { - BITCOUNT3 = 1 - }; - enum - { - BITCOUNT4 = 1 - }; - enum - { - BITCOUNT5 = 1 - }; - enum - { - BITCOUNT6 = 1 + BITCOUNT = 10 }; bool Read(NetBitStreamInterface& bitStream) { bool bOk = bitStream.ReadBits(reinterpret_cast(&data), BITCOUNT); - if (bitStream.Version() >= 0x046) - bOk &= bitStream.ReadBits(reinterpret_cast(&data2), BITCOUNT2); - else - data2.bHitAnim = 0; - if (bitStream.Version() >= 0x058) - bOk &= bitStream.ReadBits(reinterpret_cast(&data3), BITCOUNT3); - else - data3.bFastSprint = 0; - if (bitStream.Version() >= 0x059) - bOk &= bitStream.ReadBits(reinterpret_cast(&data4), BITCOUNT4); - else - data4.bBadDrivebyHitboxes = 0; - if (bitStream.Can(eBitStreamVersion::QuickStandGlitch)) - bOk &= bitStream.ReadBits(reinterpret_cast(&data5), BITCOUNT5); - else - data5.bQuickStand = 0; - if (bitStream.Can(eBitStreamVersion::Glitch_VehicleRapidStop)) - bOk &= bitStream.ReadBits(reinterpret_cast(&data6), BITCOUNT6); - else - data6.vehicleRapidStop = 0; //// Example for adding item: - // if ( bitStream.Version() >= 0x999 ) + // if (bitStream.Can(eBitStreamVersion::PLACEHOLDER)) // bOk &= bitStream.ReadBits ( reinterpret_cast < char* > ( &data9 ), BITCOUNT9 ); // else // data9.bItemName = 0; return bOk; } + void Write(NetBitStreamInterface& bitStream) const { bitStream.WriteBits(reinterpret_cast(&data), BITCOUNT); - if (bitStream.Version() >= 0x046) - bitStream.WriteBits(reinterpret_cast(&data2), BITCOUNT2); - if (bitStream.Version() >= 0x058) - bitStream.WriteBits(reinterpret_cast(&data3), BITCOUNT3); - if (bitStream.Version() >= 0x059) - bitStream.WriteBits(reinterpret_cast(&data4), BITCOUNT4); - if (bitStream.Can(eBitStreamVersion::QuickStandGlitch)) - bitStream.WriteBits(reinterpret_cast(&data5), BITCOUNT5); - if (bitStream.Can(eBitStreamVersion::Glitch_VehicleRapidStop)) - bitStream.WriteBits(reinterpret_cast(&data6), BITCOUNT6); //// Example for adding item: - // if (bitStream.Can(eBitStreamVersion::YourGlitch)) + // if (bitStream.Can(eBitStreamVersion::PLACEHOLDER)) // bitStream.WriteBits(reinterpret_cast(&data9), BITCOUNT9); } @@ -2027,37 +1943,14 @@ struct SFunBugsStateSync : public ISyncStructure bool bFastFire : 1; bool bFastMove : 1; bool bCrouchBug : 1; - } data; - - // Add new ones in separate structs - struct - { bool bHitAnim : 1; - } data2; - - // Add new ones in separate structs - struct - { bool bFastSprint : 1; - } data3; - - // Add new ones in separate structs - struct - { bool bBadDrivebyHitboxes : 1; - } data4; - - // Add new ones in separate structs - struct - { bool bQuickStand : 1; - } data5; + bool vehicleRapidStop : 1; + } data; // Add new ones in separate structs - struct - { - bool vehicleRapidStop : 1; - } data6; }; ////////////////////////////////////////// @@ -2069,84 +1962,13 @@ struct SWorldSpecialPropertiesStateSync : public ISyncStructure { enum { - BITCOUNT = 12 - }; - enum - { - BITCOUNT2 = 1 - }; - enum - { - BITCOUNT3 = 1 - }; - enum - { - BITCOUNT4 = 1 - }; - enum - { - BITCOUNT5 = 1 - }; - enum - { - BITCOUNT6 = 1 - }; - enum - { - BITCOUNT7 = 1 - }; - enum - { - BITCOUNT8 = 1 - }; - enum - { - BITCOUNT9 = 1 + BITCOUNT = 20 }; bool Read(NetBitStreamInterface& bitStream) { bool isOK = bitStream.ReadBits(reinterpret_cast(&data), BITCOUNT); - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_FireballDestruct)) - isOK &= bitStream.ReadBits(reinterpret_cast(&data2), BITCOUNT2); - else - data2.fireballdestruct = true; - - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_RoadSignsText)) - isOK &= bitStream.ReadBits(reinterpret_cast(&data3), BITCOUNT3); - else - data3.roadsignstext = true; - - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_ExtendedWaterCannons)) - isOK &= bitStream.ReadBits(reinterpret_cast(&data4), BITCOUNT4); - else - data4.extendedwatercannons = true; - - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_TunnelWeatherBlend)) - isOK &= bitStream.ReadBits(reinterpret_cast(&data5), BITCOUNT5); - else - data5.tunnelweatherblend = true; - - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_IgnoreFireState)) - isOK &= bitStream.ReadBits(reinterpret_cast(&data6), BITCOUNT6); - else - data6.ignoreFireState = false; - - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_FlyingComponents)) - isOK &= bitStream.ReadBits(reinterpret_cast(&data7), BITCOUNT7); - else - data7.flyingcomponents = true; - - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_VehicleBurnExplosions)) - isOK &= bitStream.ReadBits(reinterpret_cast(&data8), BITCOUNT8); - else - data8.vehicleburnexplosions = true; - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_VehicleEngineAutoStart)) - isOK &= bitStream.ReadBits(reinterpret_cast(&data9), BITCOUNT9); - else - data9.vehicleEngineAutoStart = true; - //// Example for adding item: // if (bitStream.Can(eBitStreamVersion::YourProperty)) // isOK &= bitStream.ReadBits(reinterpret_cast(&data9), BITCOUNT9); @@ -2155,32 +1977,10 @@ struct SWorldSpecialPropertiesStateSync : public ISyncStructure return isOK; } + void Write(NetBitStreamInterface& bitStream) const { bitStream.WriteBits(reinterpret_cast(&data), BITCOUNT); - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_FireballDestruct)) - bitStream.WriteBits(reinterpret_cast(&data2), BITCOUNT2); - - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_RoadSignsText)) - bitStream.WriteBits(reinterpret_cast(&data3), BITCOUNT3); - - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_ExtendedWaterCannons)) - bitStream.WriteBits(reinterpret_cast(&data4), BITCOUNT4); - - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_TunnelWeatherBlend)) - bitStream.WriteBits(reinterpret_cast(&data5), BITCOUNT5); - - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_IgnoreFireState)) - bitStream.WriteBits(reinterpret_cast(&data6), BITCOUNT6); - - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_FlyingComponents)) - bitStream.WriteBits(reinterpret_cast(&data7), BITCOUNT7); - - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_VehicleBurnExplosions)) - bitStream.WriteBits(reinterpret_cast(&data8), BITCOUNT8); - - if (bitStream.Can(eBitStreamVersion::WorldSpecialProperty_VehicleEngineAutoStart)) - bitStream.WriteBits(reinterpret_cast(&data9), BITCOUNT9); //// Example for adding item: // if (bitStream.Can(eBitStreamVersion::YourProperty)) @@ -2201,49 +2001,18 @@ struct SWorldSpecialPropertiesStateSync : public ISyncStructure bool coronaztest : 1; bool watercreatures : 1; bool burnflippedcars : 1; - } data; - - // Add new ones in separate structs - struct - { bool fireballdestruct : 1; - } data2; - - struct - { bool roadsignstext : 1; - } data3; - - struct - { bool extendedwatercannons : 1; - } data4; - - struct - { bool tunnelweatherblend : 1; - } data5; - - struct - { bool ignoreFireState : 1; - } data6; - - struct - { bool flyingcomponents : 1; - } data7; - - struct - { bool vehicleburnexplosions : 1; - } data8; - - struct - { bool vehicleEngineAutoStart : 1; - } data9; - + } data; + + // Add new ones in separate structs + SWorldSpecialPropertiesStateSync() { // Set default states @@ -2259,14 +2028,14 @@ struct SWorldSpecialPropertiesStateSync : public ISyncStructure data.coronaztest = true; data.watercreatures = true; data.burnflippedcars = true; - data2.fireballdestruct = true; - data3.roadsignstext = true; - data4.extendedwatercannons = true; - data5.tunnelweatherblend = true; - data6.ignoreFireState = false; - data7.flyingcomponents = true; - data8.vehicleburnexplosions = true; - data9.vehicleEngineAutoStart = true; + data.fireballdestruct = true; + data.roadsignstext = true; + data.extendedwatercannons = true; + data.tunnelweatherblend = true; + data.ignoreFireState = false; + data.flyingcomponents = true; + data.vehicleburnexplosions = true; + data.vehicleEngineAutoStart = true; } }; @@ -2632,26 +2401,26 @@ struct sWeaponPropertySync : public ISyncStructure struct { int weaponType; - FLOAT fTargetRange; // max targeting range - FLOAT fWeaponRange; // absolute gun range / default melee attack range + FLOAT fTargetRange; // max targeting range + FLOAT fWeaponRange; // absolute gun range / default melee attack range - int nFlags; // flags defining characteristics + int nFlags; // flags defining characteristics - short nAmmo; // ammo in one clip - short nDamage; // damage inflicted per hit + short nAmmo; // ammo in one clip + short nDamage; // damage inflicted per hit - FLOAT fAccuracy; // modify accuracy of weapon - FLOAT fMoveSpeed; // how fast can move with weapon + FLOAT fAccuracy; // modify accuracy of weapon + FLOAT fMoveSpeed; // how fast can move with weapon - FLOAT anim_loop_start; // start of animation loop - FLOAT anim_loop_stop; // end of animation loop - FLOAT anim_loop_bullet_fire; // time in animation when weapon should be fired + FLOAT anim_loop_start; // start of animation loop + FLOAT anim_loop_stop; // end of animation loop + FLOAT anim_loop_bullet_fire; // time in animation when weapon should be fired - FLOAT anim2_loop_start; // start of animation2 loop - FLOAT anim2_loop_stop; // end of animation2 loop - FLOAT anim2_loop_bullet_fire; // time in animation2 when weapon should be fired + FLOAT anim2_loop_start; // start of animation2 loop + FLOAT anim2_loop_stop; // end of animation2 loop + FLOAT anim2_loop_bullet_fire; // time in animation2 when weapon should be fired - FLOAT anim_breakout_time; // time after which player can break out of attack and run off + FLOAT anim_breakout_time; // time after which player can break out of attack and run off } data; }; diff --git a/Shared/sdk/net/bitstream.h b/Shared/sdk/net/bitstream.h index 3c45f47ad64..6b04aa6a305 100644 --- a/Shared/sdk/net/bitstream.h +++ b/Shared/sdk/net/bitstream.h @@ -24,17 +24,31 @@ #endif #ifdef __cpp_lib_string_view -#include + #include #endif struct ISyncStructure; -class NetBitStreamInterface; -class NetBitStreamInterfaceNoVersion : public CRefCountable +// eBitStreamVersion allows us to track what BitStream version is being used without placing magic numbers everywhere. +// It also helps us know what code branches can be removed when we increment a major version of MTA. +// Make sure you only add new items to the end of the list, above the "Latest" entry. +enum class eBitStreamVersion : unsigned short { -public: - virtual operator NetBitStreamInterface&() = 0; + Unk = 0x030, + + // DESCRIPTION + // YYYY-MM-DD + // Name, + + // This allows us to automatically increment the BitStreamVersion when things are added to this enum. + // Make sure you only add things above this comment. + Next, + Latest = Next - 1, +}; +class NetBitStreamInterface : public CRefCountable +{ +public: virtual int GetReadOffsetAsBits() = 0; virtual void SetReadOffsetAsBits(int iOffset) = 0; @@ -53,7 +67,7 @@ class NetBitStreamInterfaceNoVersion : public CRefCountable virtual void Write(const char* input, int numberOfBytes) = 0; virtual void Write(const ISyncStructure* syncStruct) = 0; -public: // Use char functions only when they will be 0 most times +public: // Use char functions only when they will be 0 most times virtual void WriteCompressed(const unsigned char& input) = 0; virtual void WriteCompressed(const char& input) = 0; @@ -63,7 +77,7 @@ class NetBitStreamInterfaceNoVersion : public CRefCountable virtual void WriteCompressed(const unsigned int& input) = 0; virtual void WriteCompressed(const int& input) = 0; -private: // Float functions not used because they only cover -1 to +1 and are lossy +private: // Float functions not used because they only cover -1 to +1 and are lossy virtual void WriteCompressed(const float& input) = 0; virtual void WriteCompressed(const double& input) = 0; @@ -95,7 +109,7 @@ class NetBitStreamInterfaceNoVersion : public CRefCountable virtual bool Read(char* output, int numberOfBytes) = 0; virtual bool Read(ISyncStructure* syncStruct) = 0; -public: // Use char functions only when they will be 0 most times +public: // Use char functions only when they will be 0 most times virtual bool ReadCompressed(unsigned char& output) = 0; virtual bool ReadCompressed(char& output) = 0; @@ -105,7 +119,7 @@ class NetBitStreamInterfaceNoVersion : public CRefCountable virtual bool ReadCompressed(unsigned int& output) = 0; virtual bool ReadCompressed(int& output) = 0; -private: // Float functions not used because they only cover -1 to +1 and are lossy +private: // Float functions not used because they only cover -1 to +1 and are lossy virtual bool ReadCompressed(float& output) = 0; virtual bool ReadCompressed(double& output) = 0; @@ -128,6 +142,10 @@ class NetBitStreamInterfaceNoVersion : public CRefCountable virtual unsigned char* GetData() const = 0; + virtual unsigned short Version() const = 0; + + bool Can(eBitStreamVersion query) { return static_cast(Version()) >= query; } + // Force long types to use 4 bytes bool Read(unsigned long& e) { @@ -302,15 +320,15 @@ class NetBitStreamInterfaceNoVersion : public CRefCountable // Write variable size length void WriteLength(uint uiLength) { - if (uiLength <= 0x7F) // One byte for length up to 127 + if (uiLength <= 0x7F) // One byte for length up to 127 Write((uchar)uiLength); else if (uiLength <= 0x7EFF) - { // Two bytes for length from 128 to 32511 + { // Two bytes for length from 128 to 32511 Write((uchar)((uiLength >> 8) + 128)); Write((uchar)(uiLength & 0xFF)); } else - { // Five bytes for length 32512 and up + { // Five bytes for length 32512 and up Write((uchar)255); Write(uiLength); } @@ -326,18 +344,18 @@ class NetBitStreamInterfaceNoVersion : public CRefCountable return false; if (ucValue <= 0x7F) - { // One byte for length up to 127 + { // One byte for length up to 127 uiOutLength = ucValue; } else if (ucValue != 255) - { // Two bytes for length from 128 to 32511 + { // Two bytes for length from 128 to 32511 uchar ucValue2 = 0; if (!Read(ucValue2)) return false; uiOutLength = ((ucValue - 128) << 8) + ucValue2; } else - { // Five bytes for length 32512 and up + { // Five bytes for length 32512 and up if (!Read(uiOutLength)) return false; } @@ -354,18 +372,18 @@ class NetBitStreamInterfaceNoVersion : public CRefCountable return ReadStringCharacters(result, uiLength); } - #ifdef MTA_CLIENT - #define MAX_ELEMENTS MAX_CLIENT_ELEMENTS - #else - #define MAX_ELEMENTS MAX_SERVER_ELEMENTS - #endif +#ifdef MTA_CLIENT + #define MAX_ELEMENTS MAX_CLIENT_ELEMENTS +#else + #define MAX_ELEMENTS MAX_SERVER_ELEMENTS +#endif // Write an element ID void Write(const ElementID& ID) { static const unsigned int bitcount = NumberOfSignificantBits<(MAX_ELEMENTS - 1)>::COUNT; const unsigned int& IDref = ID.Value(); - #ifdef MTA_CLIENT +#ifdef MTA_CLIENT if (IDref != INVALID_ELEMENT_ID && IDref >= MAX_SERVER_ELEMENTS) { dassert("Sending client side element id to server" && 0); @@ -373,7 +391,7 @@ class NetBitStreamInterfaceNoVersion : public CRefCountable WriteBits(reinterpret_cast(&uiInvalidId), bitcount); return; } - #endif +#endif WriteBits(reinterpret_cast(&IDref), bitcount); } @@ -394,262 +412,6 @@ class NetBitStreamInterfaceNoVersion : public CRefCountable } }; -// eBitStreamVersion allows us to track what BitStream version is being used without placing magic numbers everywhere. -// It also helps us know what code branches can be removed when we increment a major version of MTA. -// Make sure you only add new items to the end of the list, above the "Latest" entry. -enum class eBitStreamVersion : unsigned short -{ - Unk = 0x062, - - // - // 1.5.0 UNSTABLE - 2015-01-17 - // - - // Add "quickstand" to setGlitchEnabled - // 2015-07-13 0x063 209837dcdc30d267519abc12e1361a1d18cd1553 - QuickStandGlitch, - - // - // 1.5.0 RC RELEASED - 2015-07-15 - // - - // - // 1.5.1 RELEASED - 2015-11-05 - // - - // Update fix #9038 (bugged shotgun with bullet sync) to only work if all connected clients support it - // 2015-10-17 0x064 edbc6d37a734914b7349c693edf9a087a5a78a3d - ShotgunDamageFix, - - // - // 1.5.2 RELEASED - 2016-01-24 - // - - // Add blend parameter to setPedAnimation (#62) - // 2016-09-05 0x065 f51983c3e3385b4de8d754e11efe329acaee9301 - SetPedAnimation_Blend, - - // Update net module version - // 2016-09-24 0x066 3de7e5bd2d425747617a24350f2974e02cddc6dc - NetUpdate_0x09E, - - // - // 1.5.3 RELEASED - 2016-10-20 - // - - // Fix player nametag unicode characters missing on player join - // 2016-12-09 0x067 2e582453b476c1183bd9fae5363a7cffdb531834 - UnicodeNametags, - - // Add -1 parameter to setElementDimension (only to objects) (#111) - // 2017-02-22 0x068 2e319aa823929360da9e1f48c7eb233f1d6f29e5 - DimensionOmnipresence, - - // Add support for more special detections - // 2017-02-26 0x069 9b6187b3c2eaa655624254f8d83acb35b31243e7 - MoreSpecialDetections_Nice69, - - // Add option to enable fakelag command for testing sync issues - // 2017-03-08 0x06A a99fa0afa3b55e84f15aed335ab542520f39126d - FakeLagCommand, - - // - // 1.5.4 RELEASED - 2017-04-17 - // - - // Add player element for onClientChatMessage (#138) - // 2017-07-04 0x06B 8c7095599c6d54784692bf93a1e6c7f56392c323 - OnClientChatMessage_PlayerSource, - - // - // 1.5.5 RELEASED - 2017-08-07 - // - - // Add bShallow argument for server-side water as well (#240) - // 2018-08-05 0x06C 1321b538559efe6d70deb5b784c2d392d52658f5 - Water_bShallow_ServerSide, - - // - // 1.5.6 RELEASED - 2018-09-07 - // 1.5.7 RELEASED - 2019-08-31 - // - - // Add option to disable spawning components by setVehicleDoorState - // 2019-10-11 0x06D e79d97195439f70ac66ece1859152b4c4896af31 - SetVehicleDoorState_SpawnFlyingComponent, - - // Increment BitStream version for Discord update (#1330) - // 2020-03-27 0x06E a0ce68f284487ba636e839b06c103bc2442d95e0 - Discord_InitialImplementation, - - // Add analog control sync for accelerate and brake_reverse (#1164) - // 2020-04-02 0x06F 41e36cc67520dded2a5203727a726c4261c65e31 - AnalogControlSync_AccelBrakeReverse, - - // - // 1.5.8 RELEASED - 2020-10-11 - // - - // setWaterLevel: add bIncludeWorldSeaLevel and bIncludeOutsideWorldLevel - // 2020-11-03 0x70 - SetWaterLevel_ChangeOutsideWorldLevel, - - // Implement entering/exiting/jacking for peds #1748 - // 2020-11-10 0x71 - PedEnterExit, - - // Add height for colpolygon (#1908) - // 2021-01-16 0x72 - SetColPolygonHeight, - - // Support for vehicle blow without explosion and blow state synchronisation - // 2021-02-26 0x73 - VehicleBlowStateSupport, - - // Implement messageType parameter to onClientChatMessage (#1020) - // 2021-05-15 0x74 - OnClientChatMessage_MessageType, - - // Add serverside event "onPlayerResourceStart" (#2150) - // 2021-08-30 0x75 - OnPlayerResourceStart, - - // - // 1.5.9 RELEASED - 2021-10-01 - // - - // Remove "old" Discord implementation (#2499) - // 2022-01-16 0x76 - Discord_Cleanup, - - // - // 1.6.0 RELEASED - 2023-04-07 - // - - CEntityAddPacket_ObjectBreakable, - - // Add serverside setWorldSpecialPropertyEnabled - // 2023-08-17 - WorldSpecialProperties, - - // Add "fireballdestruct" to setWorldSpecialPropertyEnabled - // 2023-09-09 - WorldSpecialProperty_FireballDestruct, - - // Send server name to player in CPlayerJoinCompletePacket - // 2023-10-12 - CPlayerJoinCompletePacket_ServerName, - - // Add "roadsignstext" to setWorldSpecialPropertyEnabled - // 2024-05-17 - WorldSpecialProperty_RoadSignsText, - - // Add "extendedwatercannons" to setWorldSpecialPropertyEnabled - // 2024-05-23 - WorldSpecialProperty_ExtendedWaterCannons, - - // Add breakObject to serverside as well - // 2024-05-31 - BreakObject_Serverside, - - // Ped syncronization revision - // 2024-06-16 - PedSync_Revision, - - // Add "tunnelweatherblend" to setWorldSpecialPropertyEnabled - // 2024-06-30 - WorldSpecialProperty_TunnelWeatherBlend, - - // Checkpoint & arrow alpha fix - // 2024-07-03 - Marker_IgnoreAlphaLimits, - - // Add "setMarkerTargetArrowProperties" - // 2024-07-05 - SetMarkerTargetArrowProperties, - - // Add respawnObject and toggleObjectRespawn to serverside - // 2024-09-04 - RespawnObject_Serverside, - - // Add check_duplicate_serials - // 2024-09-04 - CheckDuplicateSerials, - - // Add ignorefirestate special world property - // 2024-11-07 - WorldSpecialProperty_IgnoreFireState, - - // Fix iPedSyncerDistance and iUnoccupiedVehicleSyncerDistance sync - // 2024-11-22 - FixSyncerDistance, - - // Add onPlayerChangesWorldSpecialProperty - // 2024-11-26 - WorldSpecialPropertyEvent, - - // Add setElementOnFire function - // 2024-12-30 - SetElementOnFire, - - // Add "spawnFlyingComponent" to setVehiclePanelState - // 2024-12-31 - SetVehiclePanelState_SpawnFlyingComponent, - - // Ped animations synchronization - // 2025-01-01 - AnimationsSync, - - // Add server side isPedReloadingWeapon - // 2025-01-09 - IsPedReloadingWeapon, - - // Add "flyingcomponents" to setWorldSpecialPropertyEnabled - // 2025-01-10 - WorldSpecialProperty_FlyingComponents, - - // Ped's camera synchronization - // 2025-01-29 - PedSync_CameraRotation, - - // Add "vehicleburnexplosions" to setWorldSpecialPropertyEnabled - // 2025-02-20 - WorldSpecialProperty_VehicleBurnExplosions, - - // Add serverside building support - // 2025-05-26 - ServersideBuildingElement, - - // Add "vehenginemanualmode" to setWorldSpecialPropertyEnabled - // 2025-06-02 - WorldSpecialProperty_VehicleEngineAutoStart, - - // Add "vehicle_rapid_stop" to setGlitchEnabled - // 2025-06-05 - Glitch_VehicleRapidStop, - - // This allows us to automatically increment the BitStreamVersion when things are added to this enum. - // Make sure you only add things above this comment. - Next, - Latest = Next - 1, -}; - -class NetBitStreamInterface : public NetBitStreamInterfaceNoVersion -{ - NetBitStreamInterface(const NetBitStreamInterface&); - const NetBitStreamInterface& operator=(const NetBitStreamInterface&); - -protected: - NetBitStreamInterface() { DEBUG_CREATE_COUNT("NetBitStreamInterface"); } - virtual ~NetBitStreamInterface() { DEBUG_DESTROY_COUNT("NetBitStreamInterface"); } - -public: - virtual operator NetBitStreamInterface&() { return *this; } - virtual unsigned short Version() const = 0; - - bool Can(eBitStreamVersion query) { return static_cast(Version()) >= query; } -}; - // Interface for all sync structures struct ISyncStructure { diff --git a/Shared/sdk/net/rpc_enums.h b/Shared/sdk/net/rpc_enums.h index 84c7518bc45..81ec05b0444 100644 --- a/Shared/sdk/net/rpc_enums.h +++ b/Shared/sdk/net/rpc_enums.h @@ -290,8 +290,8 @@ enum eElementRPCFunctions SPAWN_VEHICLE_FLYING_COMPONENT, SET_VEHICLE_NITRO_ACTIVATED, - + SET_ELEMENT_ON_FIRE, - NUM_RPC_FUNCS // Add above this line + NUM_RPC_FUNCS // Add above this line }; diff --git a/Shared/sdk/profiler/SharedUtil.Profiler.h b/Shared/sdk/profiler/SharedUtil.Profiler.h index 0c85c2df0d2..094c9c814dc 100644 --- a/Shared/sdk/profiler/SharedUtil.Profiler.h +++ b/Shared/sdk/profiler/SharedUtil.Profiler.h @@ -20,8 +20,7 @@ // #if MTASA_VERSION_TYPE >= VERSION_TYPE_UNSTABLE && defined(_DECLARE_PROFILER_SECTION) - #define DECLARE_PROFILER_SECTION(tag) \ - _DECLARE_PROFILER_SECTION(__FILE__, tag) + #define DECLARE_PROFILER_SECTION(tag) _DECLARE_PROFILER_SECTION(__FILE__, tag) #else #define DECLARE_PROFILER_SECTION(tag) #endif diff --git a/Shared/sdk/sha1.h b/Shared/sdk/sha1.h index 4d7dcab0c7a..4170fa2ae45 100644 --- a/Shared/sdk/sha1.h +++ b/Shared/sdk/sha1.h @@ -30,22 +30,22 @@ #include #if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) -#include + #include typedef UINT32 uint32_t; #else -#include + #include #endif -#define POLARSSL_ERR_SHA1_FILE_IO_ERROR -0x0076 /**< Read/write error in file. */ +#define POLARSSL_ERR_SHA1_FILE_IO_ERROR -0x0076 /**< Read/write error in file. */ #if !defined(POLARSSL_SHA1_ALT) // Regular implementation // -#ifdef __cplusplus + #ifdef __cplusplus extern "C" { -#endif + #endif /** * \brief SHA-1 context structure @@ -101,12 +101,12 @@ extern "C" /* Internal use */ void sha1_process(sha1_context* ctx, const unsigned char data[64]); -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#else /* POLARSSL_SHA1_ALT */ -#include "sha1_alt.h" +#else /* POLARSSL_SHA1_ALT */ + #include "sha1_alt.h" #endif /* POLARSSL_SHA1_ALT */ #ifdef __cplusplus diff --git a/Shared/sdk/sha1.hpp b/Shared/sdk/sha1.hpp index a160d1870ac..d73b9128dee 100644 --- a/Shared/sdk/sha1.hpp +++ b/Shared/sdk/sha1.hpp @@ -31,13 +31,13 @@ #include "sha1.h" #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) -#include + #include #endif #if defined(POLARSSL_PLATFORM_C) -#include "polarssl/platform.h" + #include "polarssl/platform.h" #else -#define polarssl_printf printf + #define polarssl_printf printf #endif /* Implementation that should never be optimized out by the compiler */ @@ -50,28 +50,25 @@ static void polarssl_zeroize(void* v, size_t n) #if !defined(POLARSSL_SHA1_ALT) -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif + /* + * 32-bit integer manipulation macros (big endian) + */ + #ifndef GET_UINT32_BE + #define GET_UINT32_BE(n, b, i) \ + { \ + (n) = ((uint32_t)(b)[(i)] << 24) | ((uint32_t)(b)[(i) + 1] << 16) | ((uint32_t)(b)[(i) + 2] << 8) | ((uint32_t)(b)[(i) + 3]); \ + } + #endif + + #ifndef PUT_UINT32_BE + #define PUT_UINT32_BE(n, b, i) \ + { \ + (b)[(i)] = (unsigned char)((n) >> 24); \ + (b)[(i) + 1] = (unsigned char)((n) >> 16); \ + (b)[(i) + 2] = (unsigned char)((n) >> 8); \ + (b)[(i) + 3] = (unsigned char)((n)); \ + } + #endif void sha1_init(sha1_context* ctx) { @@ -122,19 +119,15 @@ void sha1_process(sha1_context* ctx, const unsigned char data[64]) GET_UINT32_BE(W[14], data, 56); GET_UINT32_BE(W[15], data, 60); -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + #define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) -#define R(t) \ -( \ - temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \ - W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \ - ( W[t & 0x0F] = S(temp,1) ) \ -) + #define R(t) (temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ W[(t - 14) & 0x0F] ^ W[t & 0x0F], (W[t & 0x0F] = S(temp, 1))) -#define P(a,b,c,d,e,x) \ -{ \ - e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ -} + #define P(a, b, c, d, e, x) \ + { \ + e += S(a, 5) + F(b, c, d) + K + x; \ + b = S(b, 30); \ + } A = ctx->state[0]; B = ctx->state[1]; @@ -142,8 +135,8 @@ void sha1_process(sha1_context* ctx, const unsigned char data[64]) D = ctx->state[3]; E = ctx->state[4]; -#define F(x,y,z) (z ^ (x & (y ^ z))) -#define K 0x5A827999 + #define F(x, y, z) (z ^ (x & (y ^ z))) + #define K 0x5A827999 P(A, B, C, D, E, W[0]); P(E, A, B, C, D, W[1]); @@ -166,11 +159,11 @@ void sha1_process(sha1_context* ctx, const unsigned char data[64]) P(C, D, E, A, B, R(18)); P(B, C, D, E, A, R(19)); -#undef K -#undef F + #undef K + #undef F -#define F(x,y,z) (x ^ y ^ z) -#define K 0x6ED9EBA1 + #define F(x, y, z) (x ^ y ^ z) + #define K 0x6ED9EBA1 P(A, B, C, D, E, R(20)); P(E, A, B, C, D, R(21)); @@ -193,11 +186,11 @@ void sha1_process(sha1_context* ctx, const unsigned char data[64]) P(C, D, E, A, B, R(38)); P(B, C, D, E, A, R(39)); -#undef K -#undef F + #undef K + #undef F -#define F(x,y,z) ((x & y) | (z & (x | y))) -#define K 0x8F1BBCDC + #define F(x, y, z) ((x & y) | (z & (x | y))) + #define K 0x8F1BBCDC P(A, B, C, D, E, R(40)); P(E, A, B, C, D, R(41)); @@ -220,11 +213,11 @@ void sha1_process(sha1_context* ctx, const unsigned char data[64]) P(C, D, E, A, B, R(58)); P(B, C, D, E, A, R(59)); -#undef K -#undef F + #undef K + #undef F -#define F(x,y,z) (x ^ y ^ z) -#define K 0xCA62C1D6 + #define F(x, y, z) (x ^ y ^ z) + #define K 0xCA62C1D6 P(A, B, C, D, E, R(60)); P(E, A, B, C, D, R(61)); @@ -247,11 +240,11 @@ void sha1_process(sha1_context* ctx, const unsigned char data[64]) P(C, D, E, A, B, R(78)); P(B, C, D, E, A, R(79)); -#undef K -#undef F -#undef S -#undef R -#undef P + #undef K + #undef F + #undef S + #undef R + #undef P ctx->state[0] += A; ctx->state[1] += B; diff --git a/Shared/sdk/sha2.h b/Shared/sdk/sha2.h index 2c0e59b20e5..dacedb92866 100644 --- a/Shared/sdk/sha2.h +++ b/Shared/sdk/sha2.h @@ -34,18 +34,18 @@ #ifndef SHA2_H #define SHA2_H -#define SHA224_DIGEST_SIZE ( 224 / 8) -#define SHA256_DIGEST_SIZE ( 256 / 8) -#define SHA384_DIGEST_SIZE ( 384 / 8) -#define SHA512_DIGEST_SIZE ( 512 / 8) +#define SHA224_DIGEST_SIZE (224 / 8) +#define SHA256_DIGEST_SIZE (256 / 8) +#define SHA384_DIGEST_SIZE (384 / 8) +#define SHA512_DIGEST_SIZE (512 / 8) -#define SHA256_BLOCK_SIZE ( 512 / 8) -#define SHA512_BLOCK_SIZE (1024 / 8) -#define SHA384_BLOCK_SIZE SHA512_BLOCK_SIZE -#define SHA224_BLOCK_SIZE SHA256_BLOCK_SIZE +#define SHA256_BLOCK_SIZE (512 / 8) +#define SHA512_BLOCK_SIZE (1024 / 8) +#define SHA384_BLOCK_SIZE SHA512_BLOCK_SIZE +#define SHA224_BLOCK_SIZE SHA256_BLOCK_SIZE #ifndef SHA2_TYPES -#define SHA2_TYPES + #define SHA2_TYPES typedef unsigned char uint8; typedef unsigned int uint32; typedef unsigned long long uint64; diff --git a/Shared/sdk/sha2.hpp b/Shared/sdk/sha2.hpp index bf633d1dbd4..d08b1c19c72 100644 --- a/Shared/sdk/sha2.hpp +++ b/Shared/sdk/sha2.hpp @@ -32,100 +32,87 @@ */ #if 0 -#define UNROLL_LOOPS /* Enable loops unrolling */ + #define UNROLL_LOOPS /* Enable loops unrolling */ #endif #include #include "sha2.h" -#define SHFR(x, n) (x >> n) +#define SHFR(x, n) (x >> n) #define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n))) #define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n))) #define CH(x, y, z) ((x & y) ^ (~x & z)) #define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) -#define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) -#define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) -#define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3)) +#define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3)) #define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10)) #define SHA512_F1(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39)) #define SHA512_F2(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41)) -#define SHA512_F3(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHFR(x, 7)) -#define SHA512_F4(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHFR(x, 6)) - -#define UNPACK32(x, str) \ -{ \ - *((str) + 3) = (uint8) ((x) ); \ - *((str) + 2) = (uint8) ((x) >> 8); \ - *((str) + 1) = (uint8) ((x) >> 16); \ - *((str) + 0) = (uint8) ((x) >> 24); \ -} +#define SHA512_F3(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHFR(x, 7)) +#define SHA512_F4(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHFR(x, 6)) + +#define UNPACK32(x, str) \ + { \ + *((str) + 3) = (uint8)((x)); \ + *((str) + 2) = (uint8)((x) >> 8); \ + *((str) + 1) = (uint8)((x) >> 16); \ + *((str) + 0) = (uint8)((x) >> 24); \ + } -#define PACK32(str, x) \ -{ \ - *(x) = ((uint32) *((str) + 3) ) \ - | ((uint32) *((str) + 2) << 8) \ - | ((uint32) *((str) + 1) << 16) \ - | ((uint32) *((str) + 0) << 24); \ -} +#define PACK32(str, x) \ + { \ + *(x) = ((uint32) * ((str) + 3)) | ((uint32) * ((str) + 2) << 8) | ((uint32) * ((str) + 1) << 16) | ((uint32) * ((str) + 0) << 24); \ + } -#define UNPACK64(x, str) \ -{ \ - *((str) + 7) = (uint8) ((x) ); \ - *((str) + 6) = (uint8) ((x) >> 8); \ - *((str) + 5) = (uint8) ((x) >> 16); \ - *((str) + 4) = (uint8) ((x) >> 24); \ - *((str) + 3) = (uint8) ((x) >> 32); \ - *((str) + 2) = (uint8) ((x) >> 40); \ - *((str) + 1) = (uint8) ((x) >> 48); \ - *((str) + 0) = (uint8) ((x) >> 56); \ -} +#define UNPACK64(x, str) \ + { \ + *((str) + 7) = (uint8)((x)); \ + *((str) + 6) = (uint8)((x) >> 8); \ + *((str) + 5) = (uint8)((x) >> 16); \ + *((str) + 4) = (uint8)((x) >> 24); \ + *((str) + 3) = (uint8)((x) >> 32); \ + *((str) + 2) = (uint8)((x) >> 40); \ + *((str) + 1) = (uint8)((x) >> 48); \ + *((str) + 0) = (uint8)((x) >> 56); \ + } -#define PACK64(str, x) \ -{ \ - *(x) = ((uint64) *((str) + 7) ) \ - | ((uint64) *((str) + 6) << 8) \ - | ((uint64) *((str) + 5) << 16) \ - | ((uint64) *((str) + 4) << 24) \ - | ((uint64) *((str) + 3) << 32) \ - | ((uint64) *((str) + 2) << 40) \ - | ((uint64) *((str) + 1) << 48) \ - | ((uint64) *((str) + 0) << 56); \ -} +#define PACK64(str, x) \ + { \ + *(x) = ((uint64) * ((str) + 7)) | ((uint64) * ((str) + 6) << 8) | ((uint64) * ((str) + 5) << 16) | ((uint64) * ((str) + 4) << 24) | \ + ((uint64) * ((str) + 3) << 32) | ((uint64) * ((str) + 2) << 40) | ((uint64) * ((str) + 1) << 48) | ((uint64) * ((str) + 0) << 56); \ + } /* Macros used for loops unrolling */ -#define SHA256_SCR(i) \ -{ \ - w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \ - + SHA256_F3(w[i - 15]) + w[i - 16]; \ -} +#define SHA256_SCR(i) \ + { \ + w[i] = SHA256_F4(w[i - 2]) + w[i - 7] + SHA256_F3(w[i - 15]) + w[i - 16]; \ + } -#define SHA512_SCR(i) \ -{ \ - w[i] = SHA512_F4(w[i - 2]) + w[i - 7] \ - + SHA512_F3(w[i - 15]) + w[i - 16]; \ -} +#define SHA512_SCR(i) \ + { \ + w[i] = SHA512_F4(w[i - 2]) + w[i - 7] + SHA512_F3(w[i - 15]) + w[i - 16]; \ + } -#define SHA256_EXP(a, b, c, d, e, f, g, h, j) \ -{ \ - t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \ - + sha256_k[j] + w[j]; \ - t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \ - wv[d] += t1; \ - wv[h] = t1 + t2; \ -} +#define SHA256_EXP(a, b, c, d, e, f, g, h, j) \ + { \ + t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) + sha256_k[j] + w[j]; \ + t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \ + wv[d] += t1; \ + wv[h] = t1 + t2; \ + } -#define SHA512_EXP(a, b, c, d, e, f, g ,h, j) \ -{ \ - t1 = wv[h] + SHA512_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \ - + sha512_k[j] + w[j]; \ - t2 = SHA512_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \ - wv[d] += t1; \ - wv[h] = t1 + t2; \ -} +#define SHA512_EXP(a, b, c, d, e, f, g, h, j) \ + { \ + t1 = wv[h] + SHA512_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) + sha512_k[j] + w[j]; \ + t2 = SHA512_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \ + wv[d] += t1; \ + wv[h] = t1 + t2; \ + } uint32 sha224_h0[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}; @@ -955,8 +942,8 @@ void sha224_final(sha224_ctx* ctx, unsigned char* digest) /* FIPS 180-2 Validation tests */ -#include -#include + #include + #include void test(const char* vector, unsigned char* digest, unsigned int digest_size) { diff --git a/Shared/sdk/version.h b/Shared/sdk/version.h index c02d3f8c403..b11c799a852 100644 --- a/Shared/sdk/version.h +++ b/Shared/sdk/version.h @@ -42,99 +42,102 @@ *******************************************************************************/ // New version info -#define MTASA_VERSION_MAJOR 1 -#define MTASA_VERSION_MINOR 6 -#define MTASA_VERSION_MAINTENANCE 0 -#define MTASA_VERSION_TYPE VERSION_TYPE_CUSTOM -#define MTASA_VERSION_BUILD 0 +#define MTASA_VERSION_MAJOR 1 +#define MTASA_VERSION_MINOR 7 +#define MTASA_VERSION_MAINTENANCE 0 +#define MTASA_VERSION_TYPE VERSION_TYPE_CUSTOM +#define MTASA_VERSION_BUILD 0 #include "../build_overrides.h" // Old version info -#define MTA_DM_VERSION ( ( ( MTASA_VERSION_MAJOR ) << 8 ) | ( ( MTASA_VERSION_MINOR ) << 4 ) | ( ( MTASA_VERSION_MAINTENANCE ) << 0 ) ) +#define MTA_DM_VERSION (((MTASA_VERSION_MAJOR) << 8) | ((MTASA_VERSION_MINOR) << 4) | ((MTASA_VERSION_MAINTENANCE) << 0)) #if MTASA_VERSION_MAINTENANCE == 0 - #define MTA_DM_VERSIONSTRING QUOTE_DEFINE ( MTASA_VERSION_MAJOR ) "." QUOTE_DEFINE ( MTASA_VERSION_MINOR ) + #define MTA_DM_VERSIONSTRING QUOTE_DEFINE(MTASA_VERSION_MAJOR) "." QUOTE_DEFINE(MTASA_VERSION_MINOR) #else - #define MTA_DM_VERSIONSTRING QUOTE_DEFINE ( MTASA_VERSION_MAJOR ) "." QUOTE_DEFINE ( MTASA_VERSION_MINOR ) "." QUOTE_DEFINE ( MTASA_VERSION_MAINTENANCE ) + #define MTA_DM_VERSIONSTRING QUOTE_DEFINE(MTASA_VERSION_MAJOR) "." QUOTE_DEFINE(MTASA_VERSION_MINOR) "." QUOTE_DEFINE(MTASA_VERSION_MAINTENANCE) #endif #ifdef MTA_CLIENT -#define MTA_DM_FULL_STRING "MTA:SA Client" + #define MTA_DM_FULL_STRING "MTA:SA Client" #else -#define MTA_DM_FULL_STRING "MTA:SA Server" + #define MTA_DM_FULL_STRING "MTA:SA Server" #endif +// MTA_MAETRO is defined in premake5.lua + // Compile types -#define VERSION_TYPE_CUSTOM 0x01 -#define VERSION_TYPE_EXPERIMENTAL 0x03 -#define VERSION_TYPE_UNSTABLE 0x05 -#define VERSION_TYPE_UNTESTED 0x07 -#define VERSION_TYPE_RELEASE 0x09 +#define VERSION_TYPE_CUSTOM 0x01 +#define VERSION_TYPE_EXPERIMENTAL 0x03 +#define VERSION_TYPE_UNSTABLE 0x05 +#define VERSION_TYPE_UNTESTED 0x07 +#define VERSION_TYPE_RELEASE 0x09 #define QUOTE_DEFINE2(c) #c -#define QUOTE_DEFINE(x) QUOTE_DEFINE2(x) +#define QUOTE_DEFINE(x) QUOTE_DEFINE2(x) // Implement compile types #if MTASA_VERSION_TYPE == VERSION_TYPE_CUSTOM - #define MTA_DM_BUILDTYPE "custom" - #define MTA_DM_BUILDTAG_SHORT MTA_DM_VERSIONSTRING "-" MTA_DM_BUILDTYPE - #define MTA_DM_BUILDTAG_LONG MTA_DM_VERSIONSTRING "-" MTA_DM_BUILDTYPE + #define MTA_DM_BUILDTYPE "custom" + #define MTA_DM_BUILDTAG_SHORT MTA_DM_VERSIONSTRING "-" MTA_DM_BUILDTYPE + #define MTA_DM_BUILDTAG_LONG MTA_DM_VERSIONSTRING "-" MTA_DM_BUILDTYPE #elif MTASA_VERSION_TYPE == VERSION_TYPE_UNSTABLE - #define MTA_DM_BUILDTYPE "unstable" - #define MTA_DM_BUILDTAG_SHORT MTA_DM_VERSIONSTRING "-" MTA_DM_BUILDTYPE "-" QUOTE_DEFINE ( MTASA_VERSION_BUILD ) - #define MTA_DM_BUILDTAG_LONG MTA_DM_VERSIONSTRING "-" MTA_DM_BUILDTYPE "-" QUOTE_DEFINE ( MTASA_VERSION_BUILD ) + #define MTA_DM_BUILDTYPE "unstable" + #define MTA_DM_BUILDTAG_SHORT MTA_DM_VERSIONSTRING "-" MTA_DM_BUILDTYPE "-" QUOTE_DEFINE(MTASA_VERSION_BUILD) + #define MTA_DM_BUILDTAG_LONG MTA_DM_VERSIONSTRING "-" MTA_DM_BUILDTYPE "-" QUOTE_DEFINE(MTASA_VERSION_BUILD) #elif MTASA_VERSION_TYPE == VERSION_TYPE_UNTESTED - #define MTA_DM_BUILDTYPE "untested" - #define MTA_DM_BUILDTAG_SHORT MTA_DM_VERSIONSTRING "-" MTA_DM_BUILDTYPE "-" QUOTE_DEFINE ( MTASA_VERSION_BUILD ) - #define MTA_DM_BUILDTAG_LONG MTA_DM_VERSIONSTRING "-" MTA_DM_BUILDTYPE "-" QUOTE_DEFINE ( MTASA_VERSION_BUILD ) + #define MTA_DM_BUILDTYPE "untested" + #define MTA_DM_BUILDTAG_SHORT MTA_DM_VERSIONSTRING "-" MTA_DM_BUILDTYPE "-" QUOTE_DEFINE(MTASA_VERSION_BUILD) + #define MTA_DM_BUILDTAG_LONG MTA_DM_VERSIONSTRING "-" MTA_DM_BUILDTYPE "-" QUOTE_DEFINE(MTASA_VERSION_BUILD) #define MTA_DM_PUBLIC_CONNECTIONS - #define MTA_DM_EXPIRE_DAYS 60 + #define MTA_DM_EXPIRE_DAYS 60 #elif MTASA_VERSION_TYPE == VERSION_TYPE_RELEASE - #define MTA_DM_BUILDTYPE "release" - #define MTA_DM_BUILDTAG_SHORT MTA_DM_VERSIONSTRING - #define MTA_DM_BUILDTAG_LONG MTA_DM_VERSIONSTRING "-" MTA_DM_BUILDTYPE "-" QUOTE_DEFINE ( MTASA_VERSION_BUILD ) + #define MTA_DM_BUILDTYPE "release" + #define MTA_DM_BUILDTAG_SHORT MTA_DM_VERSIONSTRING + #define MTA_DM_BUILDTAG_LONG MTA_DM_VERSIONSTRING "-" MTA_DM_BUILDTYPE "-" QUOTE_DEFINE(MTASA_VERSION_BUILD) #define MTA_DM_PUBLIC_CONNECTIONS #else #error "Incorrect MTASA_VERSION_TYPE" #endif -#define _ASE_VERSION QUOTE_DEFINE(MTASA_VERSION_MAJOR) "." QUOTE_DEFINE(MTASA_VERSION_MINOR) -#define _NETCODE_VERSION_BRANCH_ID 0x4 // Use 0x1 - 0xF to indicate an incompatible branch is being used (0x0 is reserved, 0x4 is trunk) -#define _CLIENT_NET_MODULE_VERSION 0x0B2 // (0x000 - 0xfff) Lvl9 wizards only -#define _SERVER_NET_MODULE_VERSION 0x0AB // (0x000 - 0xfff) Lvl9 wizards only -#define _NETCODE_VERSION 0x1DA // (0x000 - 0xfff) Increment when net messages change (pre-release) +#define _ASE_VERSION QUOTE_DEFINE(MTASA_VERSION_MAJOR) "." QUOTE_DEFINE(MTASA_VERSION_MINOR) +#define _NETCODE_VERSION_BRANCH_ID 0x4 // Use 0x1 - 0xF to indicate an incompatible branch is being used (0x0 is reserved, 0x4 is trunk) +#define _CLIENT_NET_MODULE_VERSION 0x0B5 // (0x000 - 0xfff) Lvl9 wizards only +#define _SERVER_NET_MODULE_VERSION 0x0AD // (0x000 - 0xfff) Lvl9 wizards only +#define _NETCODE_VERSION 0x1DE // (0x000 - 0xfff) Increment when net messages change (pre-release) // (0x000 - 0xfff) Update bitstream.h when net messages change (post-release). (Changing will also require additional backward compatibility code). #define MTA_DM_BITSTREAM_VERSION eBitStreamVersion::Latest // To avoid user confusion, make sure the ASE version matches only if communication is possible #if defined(MTA_DM_PUBLIC_CONNECTIONS) - #define MTA_DM_ASE_VERSION _ASE_VERSION - #define MTA_DM_NETCODE_VERSION _NETCODE_VERSION - #define MTA_DM_CLIENT_NET_MODULE_VERSION _CLIENT_NET_MODULE_VERSION - #define MTA_DM_SERVER_NET_MODULE_VERSION _SERVER_NET_MODULE_VERSION + #define MTA_DM_ASE_VERSION _ASE_VERSION + #define MTA_DM_NETCODE_VERSION _NETCODE_VERSION + #define MTA_DM_CLIENT_NET_MODULE_VERSION _CLIENT_NET_MODULE_VERSION + #define MTA_DM_SERVER_NET_MODULE_VERSION _SERVER_NET_MODULE_VERSION #else #if _NETCODE_VERSION_BRANCH_ID < 1 || _NETCODE_VERSION_BRANCH_ID > 15 #error "_NETCODE_VERSION_BRANCH_ID wrong" #endif - #define MTA_DM_ASE_VERSION _ASE_VERSION "n" - #define MTA_DM_NETCODE_VERSION ( _NETCODE_VERSION + ( _NETCODE_VERSION_BRANCH_ID << 12 ) ) - #define MTA_DM_CLIENT_NET_MODULE_VERSION ( _CLIENT_NET_MODULE_VERSION + ( 4 << 12 ) ) - #define MTA_DM_SERVER_NET_MODULE_VERSION _SERVER_NET_MODULE_VERSION + #define MTA_DM_ASE_VERSION _ASE_VERSION "n" + #define MTA_DM_NETCODE_VERSION (_NETCODE_VERSION + (_NETCODE_VERSION_BRANCH_ID << 12)) + #define MTA_DM_CLIENT_NET_MODULE_VERSION (_CLIENT_NET_MODULE_VERSION + (4 << 12)) + #define MTA_DM_SERVER_NET_MODULE_VERSION _SERVER_NET_MODULE_VERSION #endif // Handy self compile message #ifndef MTA_DM_PUBLIC_CONNECTIONS #if defined(SHOW_SELF_COMPILE_WARNING) && !defined(CI_BUILD) && !defined(MTA_CLIENT) - #pragma message("\n\ + #pragma message( \ + "\n\ ----------------------------------------------------------------------\n\ MTASA_VERSION_TYPE is not set to VERSION_TYPE_RELEASE\n\ Server will not work with release clients\n\ diff --git a/Shared/sdk/xml/CXML.h b/Shared/sdk/xml/CXML.h index 139ea350d66..db005aa84ee 100644 --- a/Shared/sdk/xml/CXML.h +++ b/Shared/sdk/xml/CXML.h @@ -19,7 +19,7 @@ class CXMLAttribute; typedef struct SXMLString { CXMLNode* node; - virtual ~SXMLString(){}; + virtual ~SXMLString() {}; } SXMLString; class CXML diff --git a/Shared/sdk/xml/CXMLAttribute.h b/Shared/sdk/xml/CXMLAttribute.h index ae7772f9ff7..9e1ca230df6 100644 --- a/Shared/sdk/xml/CXMLAttribute.h +++ b/Shared/sdk/xml/CXMLAttribute.h @@ -17,7 +17,7 @@ class CXMLAttribute : public CXMLCommon { public: - virtual ~CXMLAttribute(){}; + virtual ~CXMLAttribute() {}; virtual const std::string GetName() const = 0; virtual const std::string& GetValue() const = 0; diff --git a/Shared/sdk/xml/CXMLCommon.h b/Shared/sdk/xml/CXMLCommon.h index 96de694c5f7..fbff75e244c 100644 --- a/Shared/sdk/xml/CXMLCommon.h +++ b/Shared/sdk/xml/CXMLCommon.h @@ -23,7 +23,7 @@ enum eXMLClass class CXMLCommon { public: - virtual ~CXMLCommon(){}; + virtual ~CXMLCommon() {}; virtual eXMLClass GetClassType() = 0; virtual unsigned long GetID() = 0; diff --git a/Shared/sdk/xml/CXMLFile.h b/Shared/sdk/xml/CXMLFile.h index ab8f794cac7..ed57a77c371 100644 --- a/Shared/sdk/xml/CXMLFile.h +++ b/Shared/sdk/xml/CXMLFile.h @@ -22,7 +22,7 @@ class CXMLNode; class CXMLFile : public CXMLCommon { public: - virtual ~CXMLFile(){}; + virtual ~CXMLFile() {}; virtual const char* GetFilename() = 0; virtual void SetFilename(const char* szFilename) = 0; diff --git a/Shared/sdk/xml/CXMLNode.h b/Shared/sdk/xml/CXMLNode.h index 133687b36eb..d3974c7af6b 100644 --- a/Shared/sdk/xml/CXMLNode.h +++ b/Shared/sdk/xml/CXMLNode.h @@ -19,7 +19,7 @@ class CXMLNode : public CXMLCommon { public: - virtual ~CXMLNode(){}; + virtual ~CXMLNode() {}; virtual CXMLNode* CreateSubNode(const char* szTagName, CXMLNode* pInsertAfter = nullptr) = 0; virtual void DeleteSubNode(CXMLNode* pNode) = 0; diff --git a/Tests/client/CDuplicateLineFilter_Tests.cpp b/Tests/client/CDuplicateLineFilter_Tests.cpp new file mode 100644 index 00000000000..48c96df0dd2 --- /dev/null +++ b/Tests/client/CDuplicateLineFilter_Tests.cpp @@ -0,0 +1,158 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Tests/client/CDuplicateLineFilter_Tests.cpp + * PURPOSE: Google Test suite for CDuplicateLineFilter + * + *****************************************************************************/ + +#include +#include +#include + +/////////////////////////////////////////////////////////////// +// +// Basic pass-through: unique lines appear immediately +// +/////////////////////////////////////////////////////////////// + +// Verify a single unique line passes through immediately +TEST(CDuplicateLineFilter, UniqueLinePassesThrough) +{ + CDuplicateLineFilter filter; + filter.AddLine("hello"); + SString output; + EXPECT_TRUE(filter.PopOutputLine(output)); + EXPECT_STREQ(output.c_str(), "hello"); +} + +// Verify multiple distinct lines all pass through in order +TEST(CDuplicateLineFilter, MultipleUniqueLinesPassThrough) +{ + CDuplicateLineFilter filter; + filter.AddLine("line1"); + filter.AddLine("line2"); + filter.AddLine("line3"); + + SString output; + EXPECT_TRUE(filter.PopOutputLine(output)); + EXPECT_STREQ(output.c_str(), "line1"); + EXPECT_TRUE(filter.PopOutputLine(output)); + EXPECT_STREQ(output.c_str(), "line2"); + EXPECT_TRUE(filter.PopOutputLine(output)); + EXPECT_STREQ(output.c_str(), "line3"); + EXPECT_FALSE(filter.PopOutputLine(output)); +} + +/////////////////////////////////////////////////////////////// +// +// Single-line duplicate detection +// +/////////////////////////////////////////////////////////////// + +// Verify consecutive duplicates are absorbed until a different line breaks the sequence +TEST(CDuplicateLineFilter, SingleLineDuplicateDetected) +{ + CDuplicateLineFilter filter; + // First occurrence goes to output + filter.AddLine("repeated"); + SString output; + EXPECT_TRUE(filter.PopOutputLine(output)); + EXPECT_STREQ(output.c_str(), "repeated"); + + // Second and third occurrences are absorbed as duplicates + filter.AddLine("repeated"); + filter.AddLine("repeated"); + filter.AddLine("repeated"); + // The duplicates are held until a non-matching line or flush + EXPECT_FALSE(filter.PopOutputLine(output)); + + // A different line breaks the match + filter.AddLine("different"); + // Now the duplicate line(s) plus the new line should be available + EXPECT_TRUE(filter.PopOutputLine(output)); + // The output should contain the repeated line with a DUP marker + EXPECT_NE(output.find("repeated"), SString::npos); +} + +/////////////////////////////////////////////////////////////// +// +// Flush releases held duplicates +// +/////////////////////////////////////////////////////////////// + +// Verify Flush() releases held duplicate lines without requiring a different line +TEST(CDuplicateLineFilter, FlushReleasesHeldLines) +{ + CDuplicateLineFilter filter; + filter.AddLine("alpha"); + // Consume the first output + SString output; + EXPECT_TRUE(filter.PopOutputLine(output)); + + // Start duplicate matching + filter.AddLine("alpha"); + filter.AddLine("alpha"); + // Without flush, nothing should be available + EXPECT_FALSE(filter.PopOutputLine(output)); + + filter.Flush(); + // After flush, the held lines should be released + EXPECT_TRUE(filter.PopOutputLine(output)); + EXPECT_NE(output.find("alpha"), SString::npos); +} + +/////////////////////////////////////////////////////////////// +// +// Multi-line pattern detection +// +/////////////////////////////////////////////////////////////// + +// Verify multi-line repeating patterns are detected and collapsed +TEST(CDuplicateLineFilter, MultiLinePatternDetection) +{ + CDuplicateLineFilter filter(4); + // Produce a 2-line pattern: "A", "B" + filter.AddLine("A"); + filter.AddLine("B"); + + // Consume initial output + SString output; + while (filter.PopOutputLine(output)) + { + } + + // Repeat the pattern + filter.AddLine("A"); + filter.AddLine("B"); + filter.AddLine("A"); + filter.AddLine("B"); + + // Duplicates should be held + // Flush to release + filter.Flush(); + + // Should have output with dup count + bool foundOutput = false; + while (filter.PopOutputLine(output)) + foundOutput = true; + EXPECT_TRUE(foundOutput); +} + +/////////////////////////////////////////////////////////////// +// +// Empty output when nothing added +// +/////////////////////////////////////////////////////////////// + +// Verify an empty filter produces no output even after Flush() +TEST(CDuplicateLineFilter, EmptyOutputWhenNothingAdded) +{ + CDuplicateLineFilter filter; + SString output; + // PopOutputLine with no delay should return false (we can't test time-based + // behavior reliably, so just test the immediate case) + filter.Flush(); + EXPECT_FALSE(filter.PopOutputLine(output)); +} diff --git a/Tests/client/CFastList_Tests.cpp b/Tests/client/CFastList_Tests.cpp new file mode 100644 index 00000000000..d14e5f61b48 --- /dev/null +++ b/Tests/client/CFastList_Tests.cpp @@ -0,0 +1,298 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Tests/client/CFastList_Tests.cpp + * PURPOSE: Google Test suite for CFastList (pointer-only ordered map list) + * + *****************************************************************************/ + +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////// +// +// Helpers — CFastList only works with pointers +// +/////////////////////////////////////////////////////////////// + +struct Dummy +{ + int value; +}; + +/////////////////////////////////////////////////////////////// +// +// Basic operations +// +/////////////////////////////////////////////////////////////// + +// Verify a newly constructed list is empty with size 0 +TEST(CFastList, EmptyOnConstruction) +{ + CFastList list; + EXPECT_TRUE(list.empty()); + EXPECT_EQ(list.size(), 0u); +} + +// Verify push_back appends elements and increments size +TEST(CFastList, PushBack) +{ + Dummy a{1}, b{2}, c{3}; + CFastList list; + list.push_back(&a); + list.push_back(&b); + list.push_back(&c); + EXPECT_EQ(list.size(), 3u); + EXPECT_FALSE(list.empty()); +} + +// Verify push_front inserts at the beginning of the list +TEST(CFastList, PushFront) +{ + Dummy a{1}, b{2}; + CFastList list; + list.push_back(&a); + list.push_front(&b); + // front() should be the item pushed to front + EXPECT_EQ(list.front(), &b); +} + +// Verify front() returns the first element and its value +TEST(CFastList, Front) +{ + Dummy a{10}; + CFastList list; + list.push_back(&a); + EXPECT_EQ(list.front(), &a); + EXPECT_EQ(list.front()->value, 10); +} + +// Verify pop_front removes the first element and shifts front +TEST(CFastList, PopFront) +{ + Dummy a{1}, b{2}; + CFastList list; + list.push_back(&a); + list.push_back(&b); + list.pop_front(); + EXPECT_EQ(list.size(), 1u); + EXPECT_EQ(list.front(), &b); +} + +// Verify contains() detects present elements and rejects absent ones +TEST(CFastList, Contains) +{ + Dummy a{1}, b{2}, c{3}; + CFastList list; + list.push_back(&a); + list.push_back(&b); + EXPECT_TRUE(list.contains(&a)); + EXPECT_TRUE(list.contains(&b)); + EXPECT_FALSE(list.contains(&c)); +} + +// Verify remove() deletes a specific element while keeping others +TEST(CFastList, Remove) +{ + Dummy a{1}, b{2}, c{3}; + CFastList list; + list.push_back(&a); + list.push_back(&b); + list.push_back(&c); + list.remove(&b); + EXPECT_EQ(list.size(), 2u); + EXPECT_FALSE(list.contains(&b)); + EXPECT_TRUE(list.contains(&a)); + EXPECT_TRUE(list.contains(&c)); +} + +// Verify clear() empties the list and invalidates containment +TEST(CFastList, Clear) +{ + Dummy a{1}, b{2}; + CFastList list; + list.push_back(&a); + list.push_back(&b); + list.clear(); + EXPECT_TRUE(list.empty()); + EXPECT_EQ(list.size(), 0u); + EXPECT_FALSE(list.contains(&a)); +} + +/////////////////////////////////////////////////////////////// +// +// Iteration order +// +/////////////////////////////////////////////////////////////// + +// Verify forward iteration follows push_back insertion order +TEST(CFastList, IterationOrderPushBack) +{ + Dummy a{1}, b{2}, c{3}; + CFastList list; + list.push_back(&a); + list.push_back(&b); + list.push_back(&c); + + std::vector result; + for (auto it = list.begin(); it != list.end(); ++it) + result.push_back(*it); + + ASSERT_EQ(result.size(), 3u); + EXPECT_EQ(result[0], &a); + EXPECT_EQ(result[1], &b); + EXPECT_EQ(result[2], &c); +} + +// Verify mixed push_front/push_back produces expected iteration order +TEST(CFastList, IterationOrderPushFrontThenBack) +{ + Dummy a{1}, b{2}, c{3}; + CFastList list; + list.push_back(&b); + list.push_front(&a); + list.push_back(&c); + + std::vector result; + for (auto it = list.begin(); it != list.end(); ++it) + result.push_back(*it); + + ASSERT_EQ(result.size(), 3u); + EXPECT_EQ(result[0], &a); + EXPECT_EQ(result[1], &b); + EXPECT_EQ(result[2], &c); +} + +// Verify reverse iteration visits elements in back-to-front order +TEST(CFastList, ReverseIteration) +{ + Dummy a{1}, b{2}, c{3}; + CFastList list; + list.push_back(&a); + list.push_back(&b); + list.push_back(&c); + + std::vector result; + for (auto it = list.rbegin(); it != list.rend(); ++it) + result.push_back(*it); + + ASSERT_EQ(result.size(), 3u); + EXPECT_EQ(result[0], &c); + EXPECT_EQ(result[1], &b); + EXPECT_EQ(result[2], &a); +} + +/////////////////////////////////////////////////////////////// +// +// Erase via iterator +// +/////////////////////////////////////////////////////////////// + +// Verify erase via iterator removes the element and returns the next iterator +TEST(CFastList, IteratorErase) +{ + Dummy a{1}, b{2}, c{3}; + CFastList list; + list.push_back(&a); + list.push_back(&b); + list.push_back(&c); + + // Erase middle element + auto it = list.begin(); + ++it; // points to &b + it = list.erase(it); + EXPECT_EQ(list.size(), 2u); + EXPECT_FALSE(list.contains(&b)); + // Iterator should advance to next element (&c) + EXPECT_EQ(*it, &c); +} + +/////////////////////////////////////////////////////////////// +// +// Suspend / Resume operations +// +/////////////////////////////////////////////////////////////// + +// Verify push_back during suspended operations is deferred until resume +TEST(CFastList, SuspendedPushBackIsDeferred) +{ + Dummy a{1}, b{2}; + CFastList list; + list.push_back(&a); + list.SuspendModifyOperations(); + list.push_back(&b); + // b should not be in the list yet + EXPECT_FALSE(list.contains(&b)); + EXPECT_EQ(list.size(), 1u); + list.ResumeModifyOperations(); + // Now b should be present + EXPECT_TRUE(list.contains(&b)); + EXPECT_EQ(list.size(), 2u); +} + +// Verify remove during suspended operations is deferred until resume +TEST(CFastList, SuspendedRemoveIsDeferred) +{ + Dummy a{1}, b{2}; + CFastList list; + list.push_back(&a); + list.push_back(&b); + list.SuspendModifyOperations(); + list.remove(&a); + // a should still be in the list + EXPECT_TRUE(list.contains(&a)); + list.ResumeModifyOperations(); + EXPECT_FALSE(list.contains(&a)); + EXPECT_EQ(list.size(), 1u); +} + +/////////////////////////////////////////////////////////////// +// +// Revision tracking +// +/////////////////////////////////////////////////////////////// + +// Verify the revision counter increments on each push_back and remove +TEST(CFastList, RevisionIncrementsOnModify) +{ + Dummy a{1}; + CFastList list; + uint rev0 = list.GetRevision(); + list.push_back(&a); + uint rev1 = list.GetRevision(); + EXPECT_GT(rev1, rev0); + list.remove(&a); + uint rev2 = list.GetRevision(); + EXPECT_GT(rev2, rev1); +} + +/////////////////////////////////////////////////////////////// +// +// ListContains / ListRemove free functions +// +/////////////////////////////////////////////////////////////// + +// Verify the ListContains free function works like the member contains() +TEST(CFastList, ListContainsFreeFunction) +{ + Dummy a{1}, b{2}; + CFastList list; + list.push_back(&a); + EXPECT_TRUE(ListContains(list, &a)); + EXPECT_FALSE(ListContains(list, &b)); +} + +// Verify the ListRemove free function works like the member remove() +TEST(CFastList, ListRemoveFreeFunction) +{ + Dummy a{1}, b{2}; + CFastList list; + list.push_back(&a); + list.push_back(&b); + ListRemove(list, &a); + EXPECT_FALSE(list.contains(&a)); + EXPECT_EQ(list.size(), 1u); +} diff --git a/Tests/client/CMatrix4_Tests.cpp b/Tests/client/CMatrix4_Tests.cpp new file mode 100644 index 00000000000..9149a13de97 --- /dev/null +++ b/Tests/client/CMatrix4_Tests.cpp @@ -0,0 +1,191 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Tests/client/CMatrix4_Tests.cpp + * PURPOSE: Google Test suite for CMatrix4 (4x4 matrix math) + * + *****************************************************************************/ + +#include +#include +#include + +static constexpr float kEpsilon = 0.001f; +static constexpr float kPi = 3.14159265f; + +/////////////////////////////////////////////////////////////// +// +// Construction & Identity +// +/////////////////////////////////////////////////////////////// + +// Verify default constructor produces an identity matrix (1s on diagonal, 0s elsewhere) +TEST(CMatrix4, DefaultConstructorIsIdentity) +{ + CMatrix4 m; + EXPECT_FLOAT_EQ(m[0], 1.0f); + EXPECT_FLOAT_EQ(m[5], 1.0f); + EXPECT_FLOAT_EQ(m[10], 1.0f); + EXPECT_FLOAT_EQ(m[15], 1.0f); + // Off-diagonals should be zero + EXPECT_FLOAT_EQ(m[1], 0.0f); + EXPECT_FLOAT_EQ(m[4], 0.0f); + EXPECT_FLOAT_EQ(m[12], 0.0f); +} + +// Verify Identity() resets a modified matrix back to the identity matrix +TEST(CMatrix4, IdentityResetsMatrix) +{ + CMatrix4 m; + m[1] = 99.0f; + m.Identity(); + EXPECT_FLOAT_EQ(m[1], 0.0f); + EXPECT_FLOAT_EQ(m[0], 1.0f); +} + +/////////////////////////////////////////////////////////////// +// +// Rotation builders +// +/////////////////////////////////////////////////////////////// + +// Verify 90-degree X rotation maps (0,1,0) to (0,0,1) +TEST(CMatrix4, RotXHalfPi) +{ + CMatrix4 m; + m.rotX(kPi / 2.0f); + // After 90-degree X rotation, (0,1,0) -> (0,0,1) + CVector v(0.0f, 1.0f, 0.0f); + CVector result = m.Multiply(v); + EXPECT_NEAR(result.fX, 0.0f, kEpsilon); + EXPECT_NEAR(result.fY, 0.0f, kEpsilon); + EXPECT_NEAR(result.fZ, 1.0f, kEpsilon); +} + +// Verify 90-degree Y rotation maps (0,0,1) to (1,0,0) +TEST(CMatrix4, RotYHalfPi) +{ + CMatrix4 m; + m.rotY(kPi / 2.0f); + // After 90-degree Y rotation, (0,0,1) -> (1,0,0) + CVector v(0.0f, 0.0f, 1.0f); + CVector result = m.Multiply(v); + EXPECT_NEAR(result.fX, 1.0f, kEpsilon); + EXPECT_NEAR(result.fY, 0.0f, kEpsilon); + EXPECT_NEAR(result.fZ, 0.0f, kEpsilon); +} + +// Verify 90-degree Z rotation maps (1,0,0) to (0,1,0) +TEST(CMatrix4, RotZHalfPi) +{ + CMatrix4 m; + m.rotZ(kPi / 2.0f); + // After 90-degree Z rotation, (1,0,0) -> (0,1,0) + CVector v(1.0f, 0.0f, 0.0f); + CVector result = m.Multiply(v); + EXPECT_NEAR(result.fX, 0.0f, kEpsilon); + EXPECT_NEAR(result.fY, 1.0f, kEpsilon); + EXPECT_NEAR(result.fZ, 0.0f, kEpsilon); +} + +/////////////////////////////////////////////////////////////// +// +// Translate +// +/////////////////////////////////////////////////////////////// + +// Verify Translate() transforms the origin to the given offset +TEST(CMatrix4, TranslateAddsOffset) +{ + CMatrix4 m; + CVector offset(10.0f, 20.0f, 30.0f); + m.Translate(offset); + // Identity + translation should transform origin to offset + CVector origin(0.0f, 0.0f, 0.0f); + CVector result = m.Multiply(origin); + EXPECT_NEAR(result.fX, 10.0f, kEpsilon); + EXPECT_NEAR(result.fY, 20.0f, kEpsilon); + EXPECT_NEAR(result.fZ, 30.0f, kEpsilon); +} + +// Verify two successive Translate() calls accumulate the offsets +TEST(CMatrix4, TranslateAccumulates) +{ + CMatrix4 m; + CVector a(1.0f, 2.0f, 3.0f); + CVector b(4.0f, 5.0f, 6.0f); + m.Translate(a); + m.Translate(b); + CVector result = m.Multiply(CVector(0.0f, 0.0f, 0.0f)); + EXPECT_NEAR(result.fX, 5.0f, kEpsilon); + EXPECT_NEAR(result.fY, 7.0f, kEpsilon); + EXPECT_NEAR(result.fZ, 9.0f, kEpsilon); +} + +/////////////////////////////////////////////////////////////// +// +// Multiply +// +/////////////////////////////////////////////////////////////// + +// Verify identity matrix leaves a vector unchanged after Multiply +TEST(CMatrix4, MultiplyIdentityPreservesVector) +{ + CMatrix4 m; + CVector v(5.0f, 10.0f, 15.0f); + CVector result = m.Multiply(v); + EXPECT_NEAR(result.fX, 5.0f, kEpsilon); + EXPECT_NEAR(result.fY, 10.0f, kEpsilon); + EXPECT_NEAR(result.fZ, 15.0f, kEpsilon); +} + +/////////////////////////////////////////////////////////////// +// +// Matrix multiplication (operator*) +// +/////////////////////////////////////////////////////////////// + +// Verify multiplying two identity matrices yields identity +TEST(CMatrix4, MultiplyTwoIdentitiesIsIdentity) +{ + CMatrix4 a; + CMatrix4 b; + CMatrix4 c = a * b; + EXPECT_FLOAT_EQ(c[0], 1.0f); + EXPECT_FLOAT_EQ(c[5], 1.0f); + EXPECT_FLOAT_EQ(c[10], 1.0f); + EXPECT_FLOAT_EQ(c[15], 1.0f); + EXPECT_FLOAT_EQ(c[1], 0.0f); +} + +// Verify operator* correctly chains a rotation then a translation +TEST(CMatrix4, MultiplyRotXThenTranslate) +{ + // Rotate 90 degrees around X, then translate by (0, 0, 5). + // The combined matrix should rotate first, then translate. + CMatrix4 rot; + rot.rotX(kPi / 2.0f); + + CMatrix4 trans; + CVector offset(0.0f, 0.0f, 5.0f); + trans.Translate(offset); + + // trans * rot means: first apply rot, then trans + CMatrix4 combined = trans * rot; + + CVector v(0.0f, 1.0f, 0.0f); + CVector result = combined.Multiply(v); + // rotX(90) turns (0,1,0)->(0,0,1), then translate adds (0,0,5) -> (0,0,6) + EXPECT_NEAR(result.fX, 0.0f, kEpsilon); + EXPECT_NEAR(result.fY, 0.0f, kEpsilon); + EXPECT_NEAR(result.fZ, 6.0f, kEpsilon); +} + +// Verify subscript operator allows reading and writing individual elements +TEST(CMatrix4, SubscriptOperator) +{ + CMatrix4 m; + m[3] = 42.0f; + EXPECT_FLOAT_EQ(m[3], 42.0f); +} diff --git a/Tests/client/CMatrix_Tests.cpp b/Tests/client/CMatrix_Tests.cpp new file mode 100644 index 00000000000..5455f049cb3 --- /dev/null +++ b/Tests/client/CMatrix_Tests.cpp @@ -0,0 +1,458 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Tests/client/CMatrix_Tests.cpp + * PURPOSE: Google Test suite for CMatrix (4x3 GTA matrix) + * + *****************************************************************************/ + +#include +#include +#include + +static constexpr float kEpsilon = 0.001f; + +/////////////////////////////////////////////////////////////// +// +// Construction +// +/////////////////////////////////////////////////////////////// + +// Verify default constructor produces the identity matrix (diagonal 1s, rest 0s) +TEST(CMatrix, DefaultConstructorIsIdentity) +{ + CMatrix m; + EXPECT_FLOAT_EQ(m.vRight.fX, 1.0f); + EXPECT_FLOAT_EQ(m.vRight.fY, 0.0f); + EXPECT_FLOAT_EQ(m.vRight.fZ, 0.0f); + EXPECT_FLOAT_EQ(m.vFront.fX, 0.0f); + EXPECT_FLOAT_EQ(m.vFront.fY, 1.0f); + EXPECT_FLOAT_EQ(m.vFront.fZ, 0.0f); + EXPECT_FLOAT_EQ(m.vUp.fX, 0.0f); + EXPECT_FLOAT_EQ(m.vUp.fY, 0.0f); + EXPECT_FLOAT_EQ(m.vUp.fZ, 1.0f); + EXPECT_FLOAT_EQ(m.vPos.fX, 0.0f); + EXPECT_FLOAT_EQ(m.vPos.fY, 0.0f); + EXPECT_FLOAT_EQ(m.vPos.fZ, 0.0f); +} + +// Verify position-only constructor sets vPos and leaves rotation as identity +TEST(CMatrix, ConstructWithPosition) +{ + CVector pos(10.0f, 20.0f, 30.0f); + CMatrix m(pos); + EXPECT_FLOAT_EQ(m.vPos.fX, 10.0f); + EXPECT_FLOAT_EQ(m.vPos.fY, 20.0f); + EXPECT_FLOAT_EQ(m.vPos.fZ, 30.0f); + // Rotation part should still be identity + EXPECT_FLOAT_EQ(m.vRight.fX, 1.0f); + EXPECT_FLOAT_EQ(m.vFront.fY, 1.0f); + EXPECT_FLOAT_EQ(m.vUp.fZ, 1.0f); +} + +// Verify position+rotation constructor applies zero rotation without breaking identity +TEST(CMatrix, ConstructWithPositionAndRotation) +{ + CVector pos(5.0f, 0.0f, 0.0f); + CVector rot(0.0f, 0.0f, 0.0f); + CMatrix m(pos, rot); + // Zero rotation should preserve identity rotation + EXPECT_NEAR(m.vRight.fX, 1.0f, kEpsilon); + EXPECT_NEAR(m.vFront.fY, 1.0f, kEpsilon); + EXPECT_NEAR(m.vUp.fZ, 1.0f, kEpsilon); + EXPECT_FLOAT_EQ(m.vPos.fX, 5.0f); +} + +// Verify position+rotation+scale constructor sets the correct scale on each axis +TEST(CMatrix, ConstructWithPositionRotationScale) +{ + CVector pos(0.0f, 0.0f, 0.0f); + CVector rot(0.0f, 0.0f, 0.0f); + CVector scale(2.0f, 3.0f, 4.0f); + CMatrix m(pos, rot, scale); + CVector s = m.GetScale(); + EXPECT_NEAR(s.fX, 2.0f, kEpsilon); + EXPECT_NEAR(s.fY, 3.0f, kEpsilon); + EXPECT_NEAR(s.fZ, 4.0f, kEpsilon); +} + +/////////////////////////////////////////////////////////////// +// +// Arithmetic operators +// +/////////////////////////////////////////////////////////////// + +// Verify operator+ adds all four row vectors component-wise +TEST(CMatrix, Addition) +{ + CMatrix a(CVector(1.0f, 2.0f, 3.0f)); + CMatrix b(CVector(4.0f, 5.0f, 6.0f)); + CMatrix c = a + b; + EXPECT_FLOAT_EQ(c.vPos.fX, 5.0f); + EXPECT_FLOAT_EQ(c.vPos.fY, 7.0f); + EXPECT_FLOAT_EQ(c.vPos.fZ, 9.0f); + // vRight should be (1,0,0) + (1,0,0) = (2,0,0) + EXPECT_FLOAT_EQ(c.vRight.fX, 2.0f); +} + +// Verify operator- subtracts all four row vectors component-wise +TEST(CMatrix, Subtraction) +{ + CMatrix a(CVector(10.0f, 20.0f, 30.0f)); + CMatrix b(CVector(3.0f, 5.0f, 7.0f)); + CMatrix c = a - b; + EXPECT_FLOAT_EQ(c.vPos.fX, 7.0f); + EXPECT_FLOAT_EQ(c.vPos.fY, 15.0f); + EXPECT_FLOAT_EQ(c.vPos.fZ, 23.0f); +} + +// Verify multiplying a matrix by identity preserves position and rotation +TEST(CMatrix, MultiplyIdentity) +{ + // Multiplying by identity should return the original matrix + CMatrix a(CVector(1.0f, 2.0f, 3.0f)); + CMatrix identity; + CMatrix c = a * identity; + EXPECT_NEAR(c.vPos.fX, 1.0f, kEpsilon); + EXPECT_NEAR(c.vPos.fY, 2.0f, kEpsilon); + EXPECT_NEAR(c.vPos.fZ, 3.0f, kEpsilon); + EXPECT_NEAR(c.vRight.fX, 1.0f, kEpsilon); + EXPECT_NEAR(c.vFront.fY, 1.0f, kEpsilon); + EXPECT_NEAR(c.vUp.fZ, 1.0f, kEpsilon); +} + +// Verify matrix*vector applies rotation only (no translation) as per operator* semantics +TEST(CMatrix, MultiplyVector) +{ + // Identity * vector = same direction (no translation applied) + CMatrix identity; + CVector v(1.0f, 2.0f, 3.0f); + CVector result = identity * v; + EXPECT_NEAR(result.fX, 1.0f, kEpsilon); + EXPECT_NEAR(result.fY, 2.0f, kEpsilon); + EXPECT_NEAR(result.fZ, 3.0f, kEpsilon); +} + +// Verify operator/ by identity preserves the original matrix (uses Invert, not Inverse) +TEST(CMatrix, DivideByIdentityPreservesMatrix) +{ + // operator/ uses Invert() (transpose + negate position), which is only + // a valid inverse for orthonormal matrices. Dividing by identity + // should preserve the original matrix. + CVector pos(1.0f, 2.0f, 3.0f); + CVector rot(0.3f, 0.5f, 0.7f); + CMatrix a(pos, rot); + CMatrix identity; + CMatrix result = a / identity; + + EXPECT_NEAR(result.vPos.fX, a.vPos.fX, kEpsilon); + EXPECT_NEAR(result.vPos.fY, a.vPos.fY, kEpsilon); + EXPECT_NEAR(result.vPos.fZ, a.vPos.fZ, kEpsilon); + EXPECT_NEAR(result.vRight.fX, a.vRight.fX, kEpsilon); + EXPECT_NEAR(result.vFront.fY, a.vFront.fY, kEpsilon); +} + +/////////////////////////////////////////////////////////////// +// +// Inverse +// +/////////////////////////////////////////////////////////////// + +// Verify Inverse() of identity is still identity +TEST(CMatrix, InverseOfIdentityIsIdentity) +{ + CMatrix identity; + CMatrix inv = identity.Inverse(); + EXPECT_NEAR(inv.vRight.fX, 1.0f, kEpsilon); + EXPECT_NEAR(inv.vFront.fY, 1.0f, kEpsilon); + EXPECT_NEAR(inv.vUp.fZ, 1.0f, kEpsilon); + EXPECT_NEAR(inv.vPos.fX, 0.0f, kEpsilon); + EXPECT_NEAR(inv.vPos.fY, 0.0f, kEpsilon); + EXPECT_NEAR(inv.vPos.fZ, 0.0f, kEpsilon); +} + +// Verify M * M^-1 produces the identity matrix (inverse roundtrip) +TEST(CMatrix, InverseRoundtrip) +{ + // M * M^-1 should produce identity + CVector pos(5.0f, 10.0f, 15.0f); + CVector rot(0.3f, 0.5f, 0.7f); + CMatrix m(pos, rot); + CMatrix inv = m.Inverse(); + CMatrix result = m * inv; + EXPECT_NEAR(result.vRight.fX, 1.0f, kEpsilon); + EXPECT_NEAR(result.vRight.fY, 0.0f, kEpsilon); + EXPECT_NEAR(result.vRight.fZ, 0.0f, kEpsilon); + EXPECT_NEAR(result.vFront.fX, 0.0f, kEpsilon); + EXPECT_NEAR(result.vFront.fY, 1.0f, kEpsilon); + EXPECT_NEAR(result.vFront.fZ, 0.0f, kEpsilon); + EXPECT_NEAR(result.vUp.fX, 0.0f, kEpsilon); + EXPECT_NEAR(result.vUp.fY, 0.0f, kEpsilon); + EXPECT_NEAR(result.vUp.fZ, 1.0f, kEpsilon); + EXPECT_NEAR(result.vPos.fX, 0.0f, kEpsilon); + EXPECT_NEAR(result.vPos.fY, 0.0f, kEpsilon); + EXPECT_NEAR(result.vPos.fZ, 0.0f, kEpsilon); +} + +/////////////////////////////////////////////////////////////// +// +// Rotation get/set roundtrip +// +/////////////////////////////////////////////////////////////// + +// Verify SetRotation then GetRotation returns the same Euler angles +TEST(CMatrix, SetRotationGetRotationRoundtrip) +{ + // A key property: SetRotation followed by GetRotation should return the same angles + CVector rot(0.4f, 0.6f, -0.8f); + CMatrix m; + m.SetRotation(rot); + CVector result = m.GetRotation(); + EXPECT_NEAR(result.fX, rot.fX, kEpsilon); + EXPECT_NEAR(result.fY, rot.fY, kEpsilon); + EXPECT_NEAR(result.fZ, rot.fZ, kEpsilon); +} + +// Verify SetRotation does not alter the matrix scale +TEST(CMatrix, SetRotationPreservesScale) +{ + CVector scale(2.0f, 3.0f, 4.0f); + CMatrix m(CVector(), CVector(), scale); + CVector scaleBeforeRot = m.GetScale(); + m.SetRotation(CVector(0.5f, 0.5f, 0.5f)); + CVector scaleAfterRot = m.GetScale(); + EXPECT_NEAR(scaleBeforeRot.fX, scaleAfterRot.fX, kEpsilon); + EXPECT_NEAR(scaleBeforeRot.fY, scaleAfterRot.fY, kEpsilon); + EXPECT_NEAR(scaleBeforeRot.fZ, scaleAfterRot.fZ, kEpsilon); +} + +// Verify SetRotation(0,0,0) restores the identity rotation part +TEST(CMatrix, ZeroRotationProducesIdentityRotation) +{ + CMatrix m; + m.SetRotation(CVector(0.0f, 0.0f, 0.0f)); + EXPECT_NEAR(m.vRight.fX, 1.0f, kEpsilon); + EXPECT_NEAR(m.vFront.fY, 1.0f, kEpsilon); + EXPECT_NEAR(m.vUp.fZ, 1.0f, kEpsilon); +} + +/////////////////////////////////////////////////////////////// +// +// Position get/set +// +/////////////////////////////////////////////////////////////// + +// Verify SetPosition/GetPosition roundtrip stores and retrieves the position +TEST(CMatrix, SetPositionGetPosition) +{ + CMatrix m; + CVector pos(100.0f, 200.0f, 300.0f); + m.SetPosition(pos); + const CVector& result = m.GetPosition(); + EXPECT_FLOAT_EQ(result.fX, 100.0f); + EXPECT_FLOAT_EQ(result.fY, 200.0f); + EXPECT_FLOAT_EQ(result.fZ, 300.0f); +} + +/////////////////////////////////////////////////////////////// +// +// Scale get/set +// +/////////////////////////////////////////////////////////////// + +// Verify default identity matrix has unit scale on all axes +TEST(CMatrix, DefaultScaleIsOne) +{ + CMatrix m; + CVector s = m.GetScale(); + EXPECT_NEAR(s.fX, 1.0f, kEpsilon); + EXPECT_NEAR(s.fY, 1.0f, kEpsilon); + EXPECT_NEAR(s.fZ, 1.0f, kEpsilon); +} + +// Verify SetScale/GetScale roundtrip stores and retrieves the scale +TEST(CMatrix, SetScaleGetScale) +{ + CMatrix m; + m.SetScale(CVector(5.0f, 6.0f, 7.0f)); + CVector s = m.GetScale(); + EXPECT_NEAR(s.fX, 5.0f, kEpsilon); + EXPECT_NEAR(s.fY, 6.0f, kEpsilon); + EXPECT_NEAR(s.fZ, 7.0f, kEpsilon); +} + +// Verify SetScale does not alter the rotation angles +TEST(CMatrix, SetScalePreservesRotation) +{ + CVector rot(0.3f, 0.5f, 0.7f); + CMatrix m(CVector(), rot); + CVector rotBefore = m.GetRotation(); + m.SetScale(CVector(2.0f, 2.0f, 2.0f)); + CVector rotAfter = m.GetRotation(); + EXPECT_NEAR(rotBefore.fX, rotAfter.fX, kEpsilon); + EXPECT_NEAR(rotBefore.fY, rotAfter.fY, kEpsilon); + EXPECT_NEAR(rotBefore.fZ, rotAfter.fZ, kEpsilon); +} + +/////////////////////////////////////////////////////////////// +// +// TransformVector / TransformVectorByRotation +// +/////////////////////////////////////////////////////////////// + +// Verify TransformVector applies both rotation and translation to the input vector +TEST(CMatrix, TransformVectorIncludesPosition) +{ + CMatrix m(CVector(10.0f, 20.0f, 30.0f)); + CVector v(1.0f, 0.0f, 0.0f); + CVector result = m.TransformVector(v); + // Identity rotation + position offset + EXPECT_NEAR(result.fX, 11.0f, kEpsilon); + EXPECT_NEAR(result.fY, 20.0f, kEpsilon); + EXPECT_NEAR(result.fZ, 30.0f, kEpsilon); +} + +// Verify TransformVectorByRotation applies rotation but ignores translation +TEST(CMatrix, TransformVectorByRotationExcludesPosition) +{ + CMatrix m(CVector(10.0f, 20.0f, 30.0f)); + CVector v(1.0f, 0.0f, 0.0f); + CVector result = m.TransformVectorByRotation(v); + // Identity rotation, no position applied + EXPECT_NEAR(result.fX, 1.0f, kEpsilon); + EXPECT_NEAR(result.fY, 0.0f, kEpsilon); + EXPECT_NEAR(result.fZ, 0.0f, kEpsilon); +} + +// Verify TransformVectorByRotation correctly rotates (1,0,0) by 90 degrees around Z +TEST(CMatrix, TransformVectorByRotationAppliesRotation) +{ + // Rotate 90 degrees around Z axis + float halfPi = 1.5707963f; + CMatrix m(CVector(), CVector(0.0f, 0.0f, halfPi)); + CVector v(1.0f, 0.0f, 0.0f); + CVector result = m.TransformVectorByRotation(v); + // (1,0,0) rotated 90 degrees around Z should give roughly (0,1,0) + EXPECT_NEAR(result.fX, 0.0f, kEpsilon); + EXPECT_NEAR(result.fY, 1.0f, kEpsilon); + EXPECT_NEAR(result.fZ, 0.0f, kEpsilon); +} + +/////////////////////////////////////////////////////////////// +// +// OrthoNormalize +// +/////////////////////////////////////////////////////////////// + +// Verify OrthoNormalize produces unit-length axes from scaled-up axes +TEST(CMatrix, OrthoNormalizeProducesUnitAxes) +{ + CMatrix m; + // Scale up the axes to make them non-unit + m.vRight = CVector(3.0f, 0.0f, 0.0f); + m.vFront = CVector(0.0f, 5.0f, 0.0f); + m.vUp = CVector(0.0f, 0.0f, 7.0f); + m.OrthoNormalize(CMatrix::AXIS_RIGHT, CMatrix::AXIS_FRONT); + EXPECT_NEAR(m.vRight.Length(), 1.0f, kEpsilon); + EXPECT_NEAR(m.vFront.Length(), 1.0f, kEpsilon); + EXPECT_NEAR(m.vUp.Length(), 1.0f, kEpsilon); +} + +// Verify OrthoNormalize keeps the primary axis direction unchanged +TEST(CMatrix, OrthoNormalizePreservesPrimaryAxisDirection) +{ + CMatrix m; + m.vRight = CVector(2.0f, 0.0f, 0.0f); + m.vFront = CVector(0.1f, 3.0f, 0.0f); // slightly off perpendicular + m.OrthoNormalize(CMatrix::AXIS_RIGHT, CMatrix::AXIS_FRONT); + // Right should still point along +X + EXPECT_NEAR(m.vRight.fX, 1.0f, kEpsilon); + EXPECT_NEAR(m.vRight.fY, 0.0f, kEpsilon); + EXPECT_NEAR(m.vRight.fZ, 0.0f, kEpsilon); +} + +/////////////////////////////////////////////////////////////// +// +// Clone / Invert / GetBuffer / To4x4Array +// +/////////////////////////////////////////////////////////////// + +// Verify Clone() produces an independent copy with identical values +TEST(CMatrix, CloneProducesCopy) +{ + CMatrix m(CVector(1.0f, 2.0f, 3.0f), CVector(0.5f, 0.5f, 0.5f)); + CMatrix c = m.Clone(); + EXPECT_FLOAT_EQ(m.vPos.fX, c.vPos.fX); + EXPECT_FLOAT_EQ(m.vPos.fY, c.vPos.fY); + EXPECT_FLOAT_EQ(m.vPos.fZ, c.vPos.fZ); + EXPECT_FLOAT_EQ(m.vRight.fX, c.vRight.fX); + EXPECT_FLOAT_EQ(m.vFront.fY, c.vFront.fY); + EXPECT_FLOAT_EQ(m.vUp.fZ, c.vUp.fZ); +} + +// Verify Invert() transposes the 3x3 rotation and negates position +TEST(CMatrix, InvertTransposesRotationAndNegatesPosition) +{ + CMatrix m; + m.vPos = CVector(5.0f, 10.0f, 15.0f); + m.Invert(); + EXPECT_FLOAT_EQ(m.vPos.fX, -5.0f); + EXPECT_FLOAT_EQ(m.vPos.fY, -10.0f); + EXPECT_FLOAT_EQ(m.vPos.fZ, -15.0f); + // Identity rotation transposed is still identity + EXPECT_FLOAT_EQ(m.vRight.fX, 1.0f); + EXPECT_FLOAT_EQ(m.vFront.fY, 1.0f); + EXPECT_FLOAT_EQ(m.vUp.fZ, 1.0f); +} + +// Verify GetBuffer() writes position to elements [12..14] and 1.0 to [15] +TEST(CMatrix, GetBufferLayout) +{ + CMatrix m(CVector(10.0f, 20.0f, 30.0f)); + float buf[16]; + m.GetBuffer(buf); + // Position should be in elements 12-14 + EXPECT_FLOAT_EQ(buf[12], 10.0f); + EXPECT_FLOAT_EQ(buf[13], 20.0f); + EXPECT_FLOAT_EQ(buf[14], 30.0f); + EXPECT_FLOAT_EQ(buf[15], 1.0f); +} + +// Verify To4x4Array() places position in row 3 with w=1.0 +TEST(CMatrix, To4x4ArrayLayout) +{ + CMatrix m(CVector(10.0f, 20.0f, 30.0f)); + auto arr = m.To4x4Array(); + // Position should be row 3 (index [3]) + EXPECT_FLOAT_EQ(arr[3][0], 10.0f); + EXPECT_FLOAT_EQ(arr[3][1], 20.0f); + EXPECT_FLOAT_EQ(arr[3][2], 30.0f); + EXPECT_FLOAT_EQ(arr[3][3], 1.0f); +} + +// Verify GetAxis() returns the correct axis vector by enum index +TEST(CMatrix, GetAxis) +{ + CMatrix m; + EXPECT_FLOAT_EQ(m.GetAxis(CMatrix::AXIS_RIGHT).fX, 1.0f); + EXPECT_FLOAT_EQ(m.GetAxis(CMatrix::AXIS_FRONT).fY, 1.0f); + EXPECT_FLOAT_EQ(m.GetAxis(CMatrix::AXIS_UP).fZ, 1.0f); +} + +// Verify GetRotationMatrix() strips scale to unit and zeros out position +TEST(CMatrix, GetRotationMatrix) +{ + CVector scale(2.0f, 3.0f, 4.0f); + CMatrix m(CVector(5.0f, 6.0f, 7.0f), CVector(0.3f, 0.5f, 0.7f), scale); + CMatrix rotMat = m.GetRotationMatrix(); + // Rotation matrix should have unit scale + CVector s = rotMat.GetScale(); + EXPECT_NEAR(s.fX, 1.0f, kEpsilon); + EXPECT_NEAR(s.fY, 1.0f, kEpsilon); + EXPECT_NEAR(s.fZ, 1.0f, kEpsilon); + // Position should be zeroed out + EXPECT_FLOAT_EQ(rotMat.vPos.fX, 0.0f); + EXPECT_FLOAT_EQ(rotMat.vPos.fY, 0.0f); + EXPECT_FLOAT_EQ(rotMat.vPos.fZ, 0.0f); +} diff --git a/Tests/client/CRect_Tests.cpp b/Tests/client/CRect_Tests.cpp new file mode 100644 index 00000000000..e3b32816d18 --- /dev/null +++ b/Tests/client/CRect_Tests.cpp @@ -0,0 +1,194 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Tests/client/CRect_Tests.cpp + * PURPOSE: Google Test suite for CRect (GTA SA bounding rect) + * + *****************************************************************************/ + +#include +#include +#include + +/////////////////////////////////////////////////////////////// +// +// Construction +// +/////////////////////////////////////////////////////////////// + +// Verify default constructor uses large sentinel values for StretchToPoint compatibility +TEST(CRect, DefaultConstructorHasSentinelValues) +{ + // CRect uses large sentinel values so StretchToPoint can shrink them + CRect r; + EXPECT_FLOAT_EQ(r.left, 1000000.0f); + EXPECT_FLOAT_EQ(r.top, 1000000.0f); + EXPECT_FLOAT_EQ(r.right, -1000000.0f); + EXPECT_FLOAT_EQ(r.bottom, -1000000.0f); +} + +// Verify four-argument constructor assigns left, top, right, bottom +TEST(CRect, ExplicitConstructor) +{ + CRect r(10.0f, 20.0f, 30.0f, 40.0f); + EXPECT_FLOAT_EQ(r.left, 10.0f); + EXPECT_FLOAT_EQ(r.top, 20.0f); + EXPECT_FLOAT_EQ(r.right, 30.0f); + EXPECT_FLOAT_EQ(r.bottom, 40.0f); +} + +/////////////////////////////////////////////////////////////// +// +// StretchToPoint +// +/////////////////////////////////////////////////////////////// + +// Verify first StretchToPoint collapses sentinel to a zero-size rect at the point +TEST(CRect, StretchToPointFromDefault) +{ + // First point sets both left/right and top/bottom + CRect r; + r.StretchToPoint(5.0f, 10.0f); + EXPECT_FLOAT_EQ(r.left, 5.0f); + EXPECT_FLOAT_EQ(r.right, 5.0f); + EXPECT_FLOAT_EQ(r.top, 10.0f); + EXPECT_FLOAT_EQ(r.bottom, 10.0f); +} + +// Verify second StretchToPoint expands to encompass both points +TEST(CRect, StretchToPointExpandsBounds) +{ + CRect r; + r.StretchToPoint(0.0f, 0.0f); + r.StretchToPoint(10.0f, 20.0f); + EXPECT_FLOAT_EQ(r.left, 0.0f); + EXPECT_FLOAT_EQ(r.right, 10.0f); + EXPECT_FLOAT_EQ(r.top, 0.0f); + EXPECT_FLOAT_EQ(r.bottom, 20.0f); +} + +// Verify StretchToPoint handles negative coordinates correctly +TEST(CRect, StretchToPointNegativeCoords) +{ + CRect r; + r.StretchToPoint(-5.0f, -10.0f); + r.StretchToPoint(5.0f, 10.0f); + EXPECT_FLOAT_EQ(r.left, -5.0f); + EXPECT_FLOAT_EQ(r.right, 5.0f); + EXPECT_FLOAT_EQ(r.top, -10.0f); + EXPECT_FLOAT_EQ(r.bottom, 10.0f); +} + +/////////////////////////////////////////////////////////////// +// +// Restrict +// +/////////////////////////////////////////////////////////////// + +// Verify Restrict() widens the rect to fully contain a larger rect +TEST(CRect, RestrictExpandsToContainOther) +{ + CRect a(5.0f, 5.0f, 15.0f, 15.0f); + CRect b(0.0f, 0.0f, 20.0f, 20.0f); + a.Restrict(&b); + EXPECT_FLOAT_EQ(a.left, 0.0f); + EXPECT_FLOAT_EQ(a.top, 0.0f); + EXPECT_FLOAT_EQ(a.right, 20.0f); + EXPECT_FLOAT_EQ(a.bottom, 20.0f); +} + +// Verify Restrict() is a no-op when the rect already contains the other +TEST(CRect, RestrictDoesNotShrink) +{ + CRect a(0.0f, 0.0f, 20.0f, 20.0f); + CRect b(5.0f, 5.0f, 15.0f, 15.0f); + a.Restrict(&b); + // a already contains b, so no change + EXPECT_FLOAT_EQ(a.left, 0.0f); + EXPECT_FLOAT_EQ(a.top, 0.0f); + EXPECT_FLOAT_EQ(a.right, 20.0f); + EXPECT_FLOAT_EQ(a.bottom, 20.0f); +} + +/////////////////////////////////////////////////////////////// +// +// IsCircleInside +// +/////////////////////////////////////////////////////////////// + +// Verify IsCircleInside returns true for a circle fully within the rect +TEST(CRect, IsCircleInsideCentered) +{ + CRect r(0.0f, 0.0f, 10.0f, 10.0f); + CVector2D center(5.0f, 5.0f); + EXPECT_TRUE(r.IsCircleInside(¢er, 1.0f)); +} + +// Verify IsCircleInside returns true when the circle overlaps the rect edge +TEST(CRect, IsCircleInsidePartiallyOverlapping) +{ + CRect r(0.0f, 0.0f, 10.0f, 10.0f); + CVector2D center(11.0f, 5.0f); + // Circle center is outside right edge, but radius 2 reaches inside + EXPECT_TRUE(r.IsCircleInside(¢er, 2.0f)); +} + +// Verify IsCircleInside returns false for a circle entirely outside the rect +TEST(CRect, IsCircleInsideCompletelyOutside) +{ + CRect r(0.0f, 0.0f, 10.0f, 10.0f); + CVector2D center(20.0f, 20.0f); + EXPECT_FALSE(r.IsCircleInside(¢er, 1.0f)); +} + +/////////////////////////////////////////////////////////////// +// +// Reset +// +/////////////////////////////////////////////////////////////// + +// Verify Reset() zeroes all four fields +TEST(CRect, ResetZeroesAllFields) +{ + CRect r(10.0f, 20.0f, 30.0f, 40.0f); + r.Reset(); + EXPECT_FLOAT_EQ(r.left, 0.0f); + EXPECT_FLOAT_EQ(r.top, 0.0f); + EXPECT_FLOAT_EQ(r.right, 0.0f); + EXPECT_FLOAT_EQ(r.bottom, 0.0f); +} + +/////////////////////////////////////////////////////////////// +// +// FixIncorrectTopLeft +// +/////////////////////////////////////////////////////////////// + +// Verify FixIncorrectTopLeft swaps left/right and top/bottom when inverted +TEST(CRect, FixIncorrectTopLeftCorrectsBadValues) +{ + // Simulate corrupted bounding box where left > right + CRect r; + r.left = 20.0f; + r.right = 10.0f; + r.top = 30.0f; + r.bottom = 5.0f; + r.FixIncorrectTopLeft(); + EXPECT_LT(r.left, r.right); + EXPECT_LT(r.top, r.bottom); + EXPECT_FLOAT_EQ(r.left, 9.0f); // right - 1.0 + EXPECT_FLOAT_EQ(r.top, 4.0f); // bottom - 1.0 +} + +// Verify FixIncorrectTopLeft is a no-op when the rect is already correct +TEST(CRect, FixIncorrectTopLeftNoOpWhenCorrect) +{ + CRect r(0.0f, 0.0f, 10.0f, 10.0f); + r.FixIncorrectTopLeft(); + // Already correct, values should not change + EXPECT_FLOAT_EQ(r.left, 0.0f); + EXPECT_FLOAT_EQ(r.top, 0.0f); + EXPECT_FLOAT_EQ(r.right, 10.0f); + EXPECT_FLOAT_EQ(r.bottom, 10.0f); +} diff --git a/Tests/client/CVector2D_Tests.cpp b/Tests/client/CVector2D_Tests.cpp new file mode 100644 index 00000000000..cf469abe76a --- /dev/null +++ b/Tests/client/CVector2D_Tests.cpp @@ -0,0 +1,239 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Tests/client/CVector2D_Tests.cpp + * PURPOSE: Google Test suite for CVector2D (2D vector math) + * + *****************************************************************************/ + +#include +#include +#include + +static constexpr float kEpsilon = 0.001f; + +/////////////////////////////////////////////////////////////// +// +// Construction +// +/////////////////////////////////////////////////////////////// + +// Verify default constructor zero-initializes both components +TEST(CVector2D, DefaultConstructor) +{ + CVector2D v; + EXPECT_FLOAT_EQ(v.fX, 0.0f); + EXPECT_FLOAT_EQ(v.fY, 0.0f); +} + +// Verify two-argument constructor sets fX and fY +TEST(CVector2D, ExplicitConstructor) +{ + CVector2D v(3.0f, 4.0f); + EXPECT_FLOAT_EQ(v.fX, 3.0f); + EXPECT_FLOAT_EQ(v.fY, 4.0f); +} + +// Verify construction from CVector copies fX and fY, discarding fZ +TEST(CVector2D, ConstructFromCVector) +{ + CVector v3(1.0f, 2.0f, 3.0f); + CVector2D v2(v3); + EXPECT_FLOAT_EQ(v2.fX, 1.0f); + EXPECT_FLOAT_EQ(v2.fY, 2.0f); +} + +// Verify construction from CVector4D copies fX and fY, discarding fZ and fW +TEST(CVector2D, ConstructFromCVector4D) +{ + CVector4D v4(5.0f, 6.0f, 7.0f, 8.0f); + CVector2D v2(v4); + EXPECT_FLOAT_EQ(v2.fX, 5.0f); + EXPECT_FLOAT_EQ(v2.fY, 6.0f); +} + +/////////////////////////////////////////////////////////////// +// +// Math operations +// +/////////////////////////////////////////////////////////////// + +// Verify Length() returns the Euclidean magnitude (3-4-5 triangle) +TEST(CVector2D, Length) +{ + CVector2D v(3.0f, 4.0f); + EXPECT_NEAR(v.Length(), 5.0f, kEpsilon); +} + +// Verify LengthSquared() returns length without the sqrt +TEST(CVector2D, LengthSquared) +{ + CVector2D v(3.0f, 4.0f); + EXPECT_FLOAT_EQ(v.LengthSquared(), 25.0f); +} + +// Verify DotProduct returns 0 for perpendicular vectors and correct value otherwise +TEST(CVector2D, DotProduct) +{ + CVector2D a(1.0f, 0.0f); + CVector2D b(0.0f, 1.0f); + EXPECT_FLOAT_EQ(a.DotProduct(b), 0.0f); + + CVector2D c(2.0f, 3.0f); + CVector2D d(4.0f, 5.0f); + EXPECT_FLOAT_EQ(c.DotProduct(d), 23.0f); +} + +// Verify Normalize() produces a unit vector with correct direction +TEST(CVector2D, Normalize) +{ + CVector2D v(3.0f, 4.0f); + v.Normalize(); + EXPECT_NEAR(v.Length(), 1.0f, kEpsilon); + EXPECT_NEAR(v.fX, 0.6f, kEpsilon); + EXPECT_NEAR(v.fY, 0.8f, kEpsilon); +} + +// Verify Normalize() on a zero vector is a safe no-op +TEST(CVector2D, NormalizeZeroVector) +{ + CVector2D v(0.0f, 0.0f); + v.Normalize(); + EXPECT_FLOAT_EQ(v.fX, 0.0f); + EXPECT_FLOAT_EQ(v.fY, 0.0f); +} + +/////////////////////////////////////////////////////////////// +// +// Operators +// +/////////////////////////////////////////////////////////////// + +// Verify scalar multiplication scales both components +TEST(CVector2D, ScalarMultiply) +{ + CVector2D v(2.0f, 3.0f); + CVector2D result = v * 4.0f; + EXPECT_FLOAT_EQ(result.fX, 8.0f); + EXPECT_FLOAT_EQ(result.fY, 12.0f); +} + +// Verify scalar division divides both components +TEST(CVector2D, ScalarDivide) +{ + CVector2D v(10.0f, 20.0f); + CVector2D result = v / 2.0f; + EXPECT_FLOAT_EQ(result.fX, 5.0f); + EXPECT_FLOAT_EQ(result.fY, 10.0f); +} + +// Verify operator+ adds components pairwise +TEST(CVector2D, VectorAddition) +{ + CVector2D a(1.0f, 2.0f); + CVector2D b(3.0f, 4.0f); + CVector2D result = a + b; + EXPECT_FLOAT_EQ(result.fX, 4.0f); + EXPECT_FLOAT_EQ(result.fY, 6.0f); +} + +// Verify operator- subtracts components pairwise +TEST(CVector2D, VectorSubtraction) +{ + CVector2D a(5.0f, 7.0f); + CVector2D b(2.0f, 3.0f); + CVector2D result = a - b; + EXPECT_FLOAT_EQ(result.fX, 3.0f); + EXPECT_FLOAT_EQ(result.fY, 4.0f); +} + +// Verify component-wise vector multiplication +TEST(CVector2D, VectorMultiply) +{ + CVector2D a(2.0f, 3.0f); + CVector2D b(4.0f, 5.0f); + CVector2D result = a * b; + EXPECT_FLOAT_EQ(result.fX, 8.0f); + EXPECT_FLOAT_EQ(result.fY, 15.0f); +} + +// Verify component-wise vector division +TEST(CVector2D, VectorDivide) +{ + CVector2D a(10.0f, 20.0f); + CVector2D b(2.0f, 5.0f); + CVector2D result = a / b; + EXPECT_FLOAT_EQ(result.fX, 5.0f); + EXPECT_FLOAT_EQ(result.fY, 4.0f); +} + +// Verify operator+= with a scalar adds to both components +TEST(CVector2D, CompoundAddScalar) +{ + CVector2D v(1.0f, 2.0f); + v += 5.0f; + EXPECT_FLOAT_EQ(v.fX, 6.0f); + EXPECT_FLOAT_EQ(v.fY, 7.0f); +} + +// Verify operator-= with a vector subtracts components in-place +TEST(CVector2D, CompoundSubVector) +{ + CVector2D v(10.0f, 20.0f); + v -= CVector2D(3.0f, 5.0f); + EXPECT_FLOAT_EQ(v.fX, 7.0f); + EXPECT_FLOAT_EQ(v.fY, 15.0f); +} + +// Verify operator*= with a scalar scales in-place +TEST(CVector2D, CompoundMulScalar) +{ + CVector2D v(2.0f, 3.0f); + v *= 4.0f; + EXPECT_FLOAT_EQ(v.fX, 8.0f); + EXPECT_FLOAT_EQ(v.fY, 12.0f); +} + +// Verify operator/= with a scalar divides in-place +TEST(CVector2D, CompoundDivScalar) +{ + CVector2D v(10.0f, 20.0f); + v /= 5.0f; + EXPECT_FLOAT_EQ(v.fX, 2.0f); + EXPECT_FLOAT_EQ(v.fY, 4.0f); +} + +/////////////////////////////////////////////////////////////// +// +// Equality +// +/////////////////////////////////////////////////////////////// + +// Verify operator== uses FLOAT_EPSILON tolerance for both components +TEST(CVector2D, Equality) +{ + CVector2D a(1.0f, 2.0f); + CVector2D b(1.0f, 2.0f); + EXPECT_TRUE(a == b); + EXPECT_FALSE(a != b); +} + +// Verify operator!= detects differing components +TEST(CVector2D, Inequality) +{ + CVector2D a(1.0f, 2.0f); + CVector2D b(1.0f, 3.0f); + EXPECT_TRUE(a != b); + EXPECT_FALSE(a == b); +} + +// Verify assignment from CVector copies fX and fY +TEST(CVector2D, AssignFromCVector) +{ + CVector v3(7.0f, 8.0f, 9.0f); + CVector2D v2; + v2 = v3; + EXPECT_FLOAT_EQ(v2.fX, 7.0f); + EXPECT_FLOAT_EQ(v2.fY, 8.0f); +} diff --git a/Tests/client/CVector4D_Tests.cpp b/Tests/client/CVector4D_Tests.cpp new file mode 100644 index 00000000000..a8904cf777f --- /dev/null +++ b/Tests/client/CVector4D_Tests.cpp @@ -0,0 +1,257 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Tests/client/CVector4D_Tests.cpp + * PURPOSE: Google Test suite for CVector4D (4D vector math) + * + *****************************************************************************/ + +#include +#include +#include + +static constexpr float kEpsilon = 0.001f; + +/////////////////////////////////////////////////////////////// +// +// Construction +// +/////////////////////////////////////////////////////////////// + +// Verify default constructor zero-initializes all four components +TEST(CVector4D, DefaultConstructor) +{ + CVector4D v; + EXPECT_FLOAT_EQ(v.fX, 0.0f); + EXPECT_FLOAT_EQ(v.fY, 0.0f); + EXPECT_FLOAT_EQ(v.fZ, 0.0f); + EXPECT_FLOAT_EQ(v.fW, 0.0f); +} + +// Verify four-argument constructor sets fX, fY, fZ, and fW +TEST(CVector4D, ExplicitConstructor) +{ + CVector4D v(1.0f, 2.0f, 3.0f, 4.0f); + EXPECT_FLOAT_EQ(v.fX, 1.0f); + EXPECT_FLOAT_EQ(v.fY, 2.0f); + EXPECT_FLOAT_EQ(v.fZ, 3.0f); + EXPECT_FLOAT_EQ(v.fW, 4.0f); +} + +// Verify copy constructor duplicates all four components +TEST(CVector4D, CopyConstructor) +{ + CVector4D a(1.0f, 2.0f, 3.0f, 4.0f); + CVector4D b(a); + EXPECT_FLOAT_EQ(b.fX, 1.0f); + EXPECT_FLOAT_EQ(b.fY, 2.0f); + EXPECT_FLOAT_EQ(b.fZ, 3.0f); + EXPECT_FLOAT_EQ(b.fW, 4.0f); +} + +/////////////////////////////////////////////////////////////// +// +// Math operations +// +/////////////////////////////////////////////////////////////// + +// Verify Length() returns the 4D Euclidean magnitude +TEST(CVector4D, Length) +{ + CVector4D v(1.0f, 2.0f, 2.0f, 0.0f); + // sqrt(1 + 4 + 4 + 0) = 3 + EXPECT_NEAR(v.Length(), 3.0f, kEpsilon); +} + +// Verify LengthSquared() returns the sum of squared components without sqrt +TEST(CVector4D, LengthSquared) +{ + CVector4D v(1.0f, 2.0f, 3.0f, 4.0f); + // 1 + 4 + 9 + 16 = 30 + EXPECT_FLOAT_EQ(v.LengthSquared(), 30.0f); +} + +// Verify DotProduct intentionally excludes fW (only uses fX, fY, fZ) +TEST(CVector4D, DotProduct) +{ + // Note: CVector4D::DotProduct intentionally excludes fW (see source comment) + CVector4D a(1.0f, 2.0f, 3.0f, 100.0f); + CVector4D b(4.0f, 5.0f, 6.0f, 200.0f); + // 1*4 + 2*5 + 3*6 = 32 (fW is not included) + EXPECT_FLOAT_EQ(a.DotProduct(b), 32.0f); +} + +// Verify Normalize() produces a unit-length vector along the same direction +TEST(CVector4D, Normalize) +{ + CVector4D v(2.0f, 0.0f, 0.0f, 0.0f); + v.Normalize(); + EXPECT_NEAR(v.fX, 1.0f, kEpsilon); + EXPECT_NEAR(v.Length(), 1.0f, kEpsilon); +} + +// Verify Normalize() divides all four components by the 4D length +TEST(CVector4D, NormalizeFourComponents) +{ + CVector4D v(1.0f, 1.0f, 1.0f, 1.0f); + v.Normalize(); + // Each component should be 1/2 since sqrt(4) = 2 + EXPECT_NEAR(v.fX, 0.5f, kEpsilon); + EXPECT_NEAR(v.fW, 0.5f, kEpsilon); + EXPECT_NEAR(v.Length(), 1.0f, kEpsilon); +} + +// Verify Normalize() on a zero vector is a safe no-op +TEST(CVector4D, NormalizeZeroVector) +{ + CVector4D v(0.0f, 0.0f, 0.0f, 0.0f); + v.Normalize(); + EXPECT_FLOAT_EQ(v.fX, 0.0f); + EXPECT_FLOAT_EQ(v.fW, 0.0f); +} + +/////////////////////////////////////////////////////////////// +// +// Operators +// +/////////////////////////////////////////////////////////////// + +// Verify operator+ adds all four components pairwise +TEST(CVector4D, Addition) +{ + CVector4D a(1.0f, 2.0f, 3.0f, 4.0f); + CVector4D b(5.0f, 6.0f, 7.0f, 8.0f); + CVector4D c = a + b; + EXPECT_FLOAT_EQ(c.fX, 6.0f); + EXPECT_FLOAT_EQ(c.fY, 8.0f); + EXPECT_FLOAT_EQ(c.fZ, 10.0f); + EXPECT_FLOAT_EQ(c.fW, 12.0f); +} + +// Verify operator- subtracts all four components pairwise +TEST(CVector4D, Subtraction) +{ + CVector4D a(5.0f, 6.0f, 7.0f, 8.0f); + CVector4D b(1.0f, 2.0f, 3.0f, 4.0f); + CVector4D c = a - b; + EXPECT_FLOAT_EQ(c.fX, 4.0f); + EXPECT_FLOAT_EQ(c.fY, 4.0f); + EXPECT_FLOAT_EQ(c.fZ, 4.0f); + EXPECT_FLOAT_EQ(c.fW, 4.0f); +} + +// Verify component-wise vector multiplication across all four components +TEST(CVector4D, VectorMultiply) +{ + CVector4D a(2.0f, 3.0f, 4.0f, 5.0f); + CVector4D b(6.0f, 7.0f, 8.0f, 9.0f); + CVector4D c = a * b; + EXPECT_FLOAT_EQ(c.fX, 12.0f); + EXPECT_FLOAT_EQ(c.fY, 21.0f); + EXPECT_FLOAT_EQ(c.fZ, 32.0f); + EXPECT_FLOAT_EQ(c.fW, 45.0f); +} + +// Verify scalar multiplication scales all four components +TEST(CVector4D, ScalarMultiply) +{ + CVector4D v(1.0f, 2.0f, 3.0f, 4.0f); + CVector4D result = v * 3.0f; + EXPECT_FLOAT_EQ(result.fX, 3.0f); + EXPECT_FLOAT_EQ(result.fY, 6.0f); + EXPECT_FLOAT_EQ(result.fZ, 9.0f); + EXPECT_FLOAT_EQ(result.fW, 12.0f); +} + +// Verify scalar division divides all four components +TEST(CVector4D, ScalarDivide) +{ + CVector4D v(10.0f, 20.0f, 30.0f, 40.0f); + CVector4D result = v / 10.0f; + EXPECT_FLOAT_EQ(result.fX, 1.0f); + EXPECT_FLOAT_EQ(result.fY, 2.0f); + EXPECT_FLOAT_EQ(result.fZ, 3.0f); + EXPECT_FLOAT_EQ(result.fW, 4.0f); +} + +// Verify component-wise vector division across all four components +TEST(CVector4D, VectorDivide) +{ + CVector4D a(10.0f, 20.0f, 30.0f, 40.0f); + CVector4D b(2.0f, 4.0f, 5.0f, 8.0f); + CVector4D c = a / b; + EXPECT_FLOAT_EQ(c.fX, 5.0f); + EXPECT_FLOAT_EQ(c.fY, 5.0f); + EXPECT_FLOAT_EQ(c.fZ, 6.0f); + EXPECT_FLOAT_EQ(c.fW, 5.0f); +} + +// Verify operator+= with a scalar adds to all four components +TEST(CVector4D, CompoundAddScalar) +{ + CVector4D v(1.0f, 2.0f, 3.0f, 4.0f); + v += 10.0f; + EXPECT_FLOAT_EQ(v.fX, 11.0f); + EXPECT_FLOAT_EQ(v.fW, 14.0f); +} + +// Verify operator-= subtracts a vector from all four components in-place +TEST(CVector4D, CompoundSubVector) +{ + CVector4D v(10.0f, 20.0f, 30.0f, 40.0f); + v -= CVector4D(1.0f, 2.0f, 3.0f, 4.0f); + EXPECT_FLOAT_EQ(v.fX, 9.0f); + EXPECT_FLOAT_EQ(v.fW, 36.0f); +} + +// Verify operator*= scales all four components in-place +TEST(CVector4D, CompoundMulScalar) +{ + CVector4D v(2.0f, 3.0f, 4.0f, 5.0f); + v *= 3.0f; + EXPECT_FLOAT_EQ(v.fX, 6.0f); + EXPECT_FLOAT_EQ(v.fW, 15.0f); +} + +// Verify operator/= divides all four components in-place +TEST(CVector4D, CompoundDivScalar) +{ + CVector4D v(10.0f, 20.0f, 30.0f, 40.0f); + v /= 10.0f; + EXPECT_FLOAT_EQ(v.fX, 1.0f); + EXPECT_FLOAT_EQ(v.fW, 4.0f); +} + +/////////////////////////////////////////////////////////////// +// +// Equality +// +/////////////////////////////////////////////////////////////// + +// Verify operator== returns true when all four components match +TEST(CVector4D, Equality) +{ + CVector4D a(1.0f, 2.0f, 3.0f, 4.0f); + CVector4D b(1.0f, 2.0f, 3.0f, 4.0f); + EXPECT_TRUE(a == b); + EXPECT_FALSE(a != b); +} + +// Verify operator!= detects a differing fW component +TEST(CVector4D, Inequality) +{ + CVector4D a(1.0f, 2.0f, 3.0f, 4.0f); + CVector4D b(1.0f, 2.0f, 3.0f, 5.0f); + EXPECT_TRUE(a != b); + EXPECT_FALSE(a == b); +} + +// Verify copy assignment produces an equal vector +TEST(CVector4D, CopyAssignment) +{ + CVector4D a(1.0f, 2.0f, 3.0f, 4.0f); + CVector4D b; + b = a; + EXPECT_TRUE(a == b); +} diff --git a/Tests/client/CVector_Tests.cpp b/Tests/client/CVector_Tests.cpp new file mode 100644 index 00000000000..882684e5da0 --- /dev/null +++ b/Tests/client/CVector_Tests.cpp @@ -0,0 +1,260 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Tests/client/CVector_Tests.cpp + * PURPOSE: Google Test suite for CVector (3D vector math) + * + *****************************************************************************/ + +#include +#include +#include +#include + +static constexpr float kEpsilon = 0.001f; + +/////////////////////////////////////////////////////////////// +// +// Construction +// +/////////////////////////////////////////////////////////////// + +// Verify default constructor zero-initializes all components +TEST(CVector, DefaultConstructor) +{ + CVector v; + EXPECT_FLOAT_EQ(v.fX, 0.0f); + EXPECT_FLOAT_EQ(v.fY, 0.0f); + EXPECT_FLOAT_EQ(v.fZ, 0.0f); +} + +// Verify three-argument constructor sets all components correctly +TEST(CVector, ExplicitConstructor) +{ + CVector v(1.0f, 2.0f, 3.0f); + EXPECT_FLOAT_EQ(v.fX, 1.0f); + EXPECT_FLOAT_EQ(v.fY, 2.0f); + EXPECT_FLOAT_EQ(v.fZ, 3.0f); +} + +// Verify single-argument constructor sets fX and zero-initializes fY, fZ +TEST(CVector, PartialConstructor) +{ + CVector v(5.0f); + EXPECT_FLOAT_EQ(v.fX, 5.0f); + EXPECT_FLOAT_EQ(v.fY, 0.0f); + EXPECT_FLOAT_EQ(v.fZ, 0.0f); +} + +// Verify construction from CVector4D copies XYZ and discards W +TEST(CVector, FromCVector4D) +{ + CVector4D v4(1.0f, 2.0f, 3.0f, 4.0f); + CVector v(v4); + EXPECT_FLOAT_EQ(v.fX, 1.0f); + EXPECT_FLOAT_EQ(v.fY, 2.0f); + EXPECT_FLOAT_EQ(v.fZ, 3.0f); +} + +/////////////////////////////////////////////////////////////// +// +// Length / Normalize +// +/////////////////////////////////////////////////////////////// + +// Verify Length() returns the Euclidean magnitude (3-4-5 triangle) +TEST(CVector, Length) +{ + CVector v(3.0f, 4.0f, 0.0f); + EXPECT_NEAR(v.Length(), 5.0f, kEpsilon); +} + +// Verify LengthSquared() returns length without the sqrt +TEST(CVector, LengthSquared) +{ + CVector v(3.0f, 4.0f, 0.0f); + EXPECT_NEAR(v.LengthSquared(), 25.0f, kEpsilon); +} + +// Verify Normalize() produces a unit vector and returns the original length +TEST(CVector, Normalize) +{ + CVector v(0.0f, 3.0f, 4.0f); + float origLen = v.Normalize(); + EXPECT_NEAR(origLen, 5.0f, kEpsilon); + EXPECT_NEAR(v.Length(), 1.0f, kEpsilon); +} + +// Verify Normalize() on a zero vector returns 0 without crashing +TEST(CVector, NormalizeZeroVector) +{ + CVector v(0.0f, 0.0f, 0.0f); + float len = v.Normalize(); + EXPECT_FLOAT_EQ(len, 0.0f); +} + +/////////////////////////////////////////////////////////////// +// +// Dot / Cross product +// +/////////////////////////////////////////////////////////////// + +// Verify DotProduct returns the sum of component-wise products +TEST(CVector, DotProduct) +{ + CVector a(1.0f, 2.0f, 3.0f); + CVector b(4.0f, 5.0f, 6.0f); + EXPECT_NEAR(a.DotProduct(&b), 32.0f, kEpsilon); +} + +// Verify DotProduct of perpendicular unit vectors is zero +TEST(CVector, DotProductPerpendicular) +{ + CVector a(1.0f, 0.0f, 0.0f); + CVector b(0.0f, 1.0f, 0.0f); + EXPECT_NEAR(a.DotProduct(&b), 0.0f, kEpsilon); +} + +// Verify CrossProduct of X and Y axes produces the Z axis +TEST(CVector, CrossProduct) +{ + CVector a(1.0f, 0.0f, 0.0f); + CVector b(0.0f, 1.0f, 0.0f); + a.CrossProduct(&b); + EXPECT_NEAR(a.fX, 0.0f, kEpsilon); + EXPECT_NEAR(a.fY, 0.0f, kEpsilon); + EXPECT_NEAR(a.fZ, 1.0f, kEpsilon); +} + +/////////////////////////////////////////////////////////////// +// +// Arithmetic operators +// +/////////////////////////////////////////////////////////////// + +// Verify operator+ adds components pairwise +TEST(CVector, Addition) +{ + CVector a(1.0f, 2.0f, 3.0f); + CVector b(4.0f, 5.0f, 6.0f); + CVector c = a + b; + EXPECT_FLOAT_EQ(c.fX, 5.0f); + EXPECT_FLOAT_EQ(c.fY, 7.0f); + EXPECT_FLOAT_EQ(c.fZ, 9.0f); +} + +// Verify operator- subtracts components pairwise +TEST(CVector, Subtraction) +{ + CVector a(4.0f, 5.0f, 6.0f); + CVector b(1.0f, 2.0f, 3.0f); + CVector c = a - b; + EXPECT_FLOAT_EQ(c.fX, 3.0f); + EXPECT_FLOAT_EQ(c.fY, 3.0f); + EXPECT_FLOAT_EQ(c.fZ, 3.0f); +} + +// Verify unary operator- negates all components +TEST(CVector, Negation) +{ + CVector a(1.0f, -2.0f, 3.0f); + CVector b = -a; + EXPECT_FLOAT_EQ(b.fX, -1.0f); + EXPECT_FLOAT_EQ(b.fY, 2.0f); + EXPECT_FLOAT_EQ(b.fZ, -3.0f); +} + +// Verify scalar multiplication scales all components +TEST(CVector, ScalarMultiply) +{ + CVector a(1.0f, 2.0f, 3.0f); + CVector b = a * 2.0f; + EXPECT_FLOAT_EQ(b.fX, 2.0f); + EXPECT_FLOAT_EQ(b.fY, 4.0f); + EXPECT_FLOAT_EQ(b.fZ, 6.0f); +} + +// Verify scalar division divides all components +TEST(CVector, ScalarDivide) +{ + CVector a(4.0f, 6.0f, 8.0f); + CVector b = a / 2.0f; + EXPECT_FLOAT_EQ(b.fX, 2.0f); + EXPECT_FLOAT_EQ(b.fY, 3.0f); + EXPECT_FLOAT_EQ(b.fZ, 4.0f); +} + +// Verify operator+= modifies the vector in place +TEST(CVector, CompoundAdd) +{ + CVector a(1.0f, 2.0f, 3.0f); + a += CVector(10.0f, 20.0f, 30.0f); + EXPECT_FLOAT_EQ(a.fX, 11.0f); + EXPECT_FLOAT_EQ(a.fY, 22.0f); + EXPECT_FLOAT_EQ(a.fZ, 33.0f); +} + +// Verify operator-= modifies the vector in place +TEST(CVector, CompoundSubtract) +{ + CVector a(10.0f, 20.0f, 30.0f); + a -= CVector(1.0f, 2.0f, 3.0f); + EXPECT_FLOAT_EQ(a.fX, 9.0f); + EXPECT_FLOAT_EQ(a.fY, 18.0f); + EXPECT_FLOAT_EQ(a.fZ, 27.0f); +} + +/////////////////////////////////////////////////////////////// +// +// Comparison / Validity +// +/////////////////////////////////////////////////////////////// + +// Verify operator== uses FLOAT_EPSILON tolerance and operator!= is its inverse +TEST(CVector, Equality) +{ + CVector a(1.0f, 2.0f, 3.0f); + CVector b(1.0f, 2.0f, 3.0f); + CVector c(1.0f, 2.0f, 3.1f); + EXPECT_TRUE(a == b); + EXPECT_TRUE(a != c); +} + +// Verify IsValid() rejects NaN and infinity +TEST(CVector, IsValid) +{ + CVector valid(1.0f, 2.0f, 3.0f); + EXPECT_TRUE(valid.IsValid()); + + CVector nan(std::numeric_limits::quiet_NaN(), 0.0f, 0.0f); + EXPECT_FALSE(nan.IsValid()); + + CVector inf(0.0f, std::numeric_limits::infinity(), 0.0f); + EXPECT_FALSE(inf.IsValid()); +} + +// Verify operator[] accesses components by index (0=X, 1=Y, 2=Z) +TEST(CVector, IndexOperator) +{ + CVector v(10.0f, 20.0f, 30.0f); + EXPECT_FLOAT_EQ(v[0], 10.0f); + EXPECT_FLOAT_EQ(v[1], 20.0f); + EXPECT_FLOAT_EQ(v[2], 30.0f); +} + +/////////////////////////////////////////////////////////////// +// +// Geometry helpers +// +/////////////////////////////////////////////////////////////// + +// Verify GetOtherAxis() returns a perpendicular unit vector +TEST(CVector, GetOtherAxis) +{ + CVector v(1.0f, 0.0f, 0.0f); + CVector perp = v.GetOtherAxis(); + // Must be perpendicular (dot ~ 0) and unit length + EXPECT_NEAR(v.DotProduct(&perp), 0.0f, kEpsilon); + EXPECT_NEAR(perp.Length(), 1.0f, kEpsilon); +} diff --git a/Tests/client/SharedUtilHash_Tests.cpp b/Tests/client/SharedUtilHash_Tests.cpp new file mode 100644 index 00000000000..cfe0be93026 --- /dev/null +++ b/Tests/client/SharedUtilHash_Tests.cpp @@ -0,0 +1,529 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Tests/client/SharedUtilHash_Tests.cpp + * PURPOSE: Google Test suite for SharedUtil hash and crypto functions + * + * Ported from Shared/sdk/SharedUtil.Tests.hpp - SharedUtil_Hash_Tests(). + * Covers hex conversion, TEA, HMAC, RSA, AES-128, MD5, and SHA family. + * + *****************************************************************************/ + +#include +#include + +using namespace SharedUtil; + +// Temp file used by hash-from-file tests. +// The original tests use a UTF-8-containing filename to exercise non-ASCII path handling. +static const SStringX kTempFilename("hash_\xD0\x98_test"); + +// Helper: construct an SString from raw bytes with a specified length (avoids +// SString(const char*, ...) printf-style constructor ambiguity). +static SString MakeRawString(const char* data, size_t len) +{ + return SString(std::string(data, len)); +} + +/////////////////////////////////////////////////////////////// +// +// Hex conversion +// +/////////////////////////////////////////////////////////////// + +// Verify round-trip hex conversion preserves uppercase canonical form +TEST(SharedUtilHash, ConvertHexRoundTrip) +{ + struct TestData + { + const char* input; + const char* expected; + }; + + TestData tests[] = { + {"66B9139D8C424BE2BCF224706B48FEB8", "66B9139D8C424BE2BCF224706B48FEB8"}, + {"E7C7253C74275F2DC2DC8C6828816C18301636949369F3bad87666C81E71B309", "E7C7253C74275F2DC2DC8C6828816C18301636949369F3BAD87666C81E71B309"}, + {"61", "61"}, + }; + + for (const auto& t : tests) + { + char buffer[256]; + SStringX input(t.input); + uint length = input.length() / 2; + ConvertHexStringToData(input, buffer, length); + SString result = ConvertDataToHexString(buffer, length); + EXPECT_EQ(result, t.expected) << "Input: " << t.input; + } +} + +/////////////////////////////////////////////////////////////// +// +// TEA encode / decode +// +/////////////////////////////////////////////////////////////// + +// Verify TeaEncode/TeaDecode round-trips data correctly including embedded nulls +TEST(SharedUtilHash, TeaEncodeDecodeRoundTrip) +{ + // Simple case with known ciphertext + { + SStringX data("1234"); + SStringX key("AB12\xC2\xA3$_ "); + SString encoded; + TeaEncode(data, key, &encoded); + EXPECT_EQ(encoded, MakeRawString("\x08\x56\x3B\x4F\x31\x2D\xE4\x4A", 8)); + SString decoded; + TeaDecode(encoded, key, &decoded); + EXPECT_EQ(data, *decoded); + } + + // Round-trip with long key (original test data contains \0 in the literal, + // but SString construction from const char* truncates at the null terminator) + { + SStringX data("Hello thereHello there"); + SStringX key("78111E998C42243285635E39AFDD614B"); + SString encoded; + TeaEncode(data, key, &encoded); + SString decoded; + TeaDecode(encoded, key, &decoded); + EXPECT_EQ(data, *decoded); + } + + // Round-trip with long data (original test data contains \0 in the literal, + // but SString construction from const char* truncates at the null terminator) + { + SStringX data("78111E998C42243285635E39AFD"); + SStringX key("Hello thereHello there"); + SString encoded; + TeaEncode(data, key, &encoded); + SString decoded; + TeaDecode(encoded, key, &decoded); + EXPECT_EQ(data, *decoded); + } +} + +/////////////////////////////////////////////////////////////// +// +// HMAC (requires CryptoPP) +// +/////////////////////////////////////////////////////////////// + +// Verify HMAC-MD5 produces the expected digest +TEST(SharedUtilHash, HmacMD5) +{ + SString result = Hmac("Hello world", "hecker was there"); + EXPECT_EQ(result, "657C7088ADEA11E6482EE794D3E5489C"); +} + +// Verify HMAC-SHA1 with an empty key +TEST(SharedUtilHash, HmacSHA1) +{ + SString result = Hmac("cstddef", ""); + EXPECT_EQ(result, "0339B2CA65A63209C656047C5B11ADA73B63A367"); +} + +// Verify HMAC-SHA224 with special characters in key +TEST(SharedUtilHash, HmacSHA224) +{ + SString result = Hmac("Hello thereHello there", "!@#$%^&*()_+|:<>"); + EXPECT_EQ(result, "A7A00E964617DFB59324502786BB28AEEF22898C00B226A7B4A1D607"); +} + +// Verify HMAC-SHA256 with special characters in data +TEST(SharedUtilHash, HmacSHA256) +{ + SString result = Hmac("!@#$%^&*()_+|:<>", "cppsymbol"); + EXPECT_EQ(result, "46105B670A55EA8808B16FFC8B88507EAEA3E9D1F5A55891CD04136FB2AADA15"); +} + +// Verify HMAC-SHA384 +TEST(SharedUtilHash, HmacSHA384) +{ + SString result = Hmac("value", "sha384"); + EXPECT_EQ(result, "CEC945A598261608218BA685EEC02D773F57AFD6410AF67D2A2D1B0D22DAE8624D0F369E55C8C7E774805204A2B5A75A"); +} + +// Verify HMAC-SHA512 with empty data +TEST(SharedUtilHash, HmacSHA512) +{ + SString result = Hmac("", "gHtySkGerYnhDxAs"); + EXPECT_EQ(result, "4E6E87CE637808642B902A07F43CA6A1CFE4346054C0C8C542A67C4BF206708CF5AFE3F1BB6D53DCE3469CDEA1CE11A0892EE2F95322C45D2CB809F165AD3BB3"); +} + +/////////////////////////////////////////////////////////////// +// +// RSA key generation + encrypt/decrypt round-trip +// +/////////////////////////////////////////////////////////////// + +// Verify RSA keygen + encrypt/decrypt round-trip at 1024-bit key size +TEST(SharedUtilHash, RsaRoundTrip1024) +{ + auto keyPair = GenerateRsaKeyPair(1024); + ASSERT_FALSE(keyPair.privateKey.empty()); + ASSERT_FALSE(keyPair.publicKey.empty()); + SString encrypted = RsaEncode("Hello world", keyPair.publicKey); + ASSERT_FALSE(encrypted.empty()); + SString decrypted = RsaDecode(encrypted, keyPair.privateKey); + EXPECT_EQ(decrypted, "Hello world"); +} + +// Verify RSA keygen + encrypt/decrypt round-trip at 2048-bit key size +TEST(SharedUtilHash, RsaRoundTrip2048) +{ + auto keyPair = GenerateRsaKeyPair(2048); + ASSERT_FALSE(keyPair.privateKey.empty()); + ASSERT_FALSE(keyPair.publicKey.empty()); + SString encrypted = RsaEncode("!@#$%^&*()_+|:<>", keyPair.publicKey); + ASSERT_FALSE(encrypted.empty()); + SString decrypted = RsaDecode(encrypted, keyPair.privateKey); + EXPECT_EQ(decrypted, "!@#$%^&*()_+|:<>"); +} + +/////////////////////////////////////////////////////////////// +// +// RSA decryption of known ciphertexts +// +/////////////////////////////////////////////////////////////// + +// Verify RSA decryption of a pre-encoded 1024-bit ciphertext +TEST(SharedUtilHash, RsaDecryptKnown1024) +{ + SString rawEncoded = Base64decode( + "ei2zOjHZLpp5/xhc5GyUoFIdmpj8BZFOtLOHafunis3KVYcEoZmm/JxMMnGMiAemqWCmGhkNin76Jy84G5O9pHCFR499cEvAq92Or1cX8tiM3nqJrgbeNj6SM3QWHGhnx" + "NDaxHXbXAvh9M2dyR12+X5bQVhex5O0R2XGv1XaaRw="); + SString rawKey = Base64decode( + "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJOYjQmpsmZb8KafeeUtaEydwjM2rRNrdR3BvKdNa4MMx5+YxweWrbsyDycW4AIfU5jcHN61QHaRx53zS" + "F59cV79ARKoIY+Csi3yD9mgmN81O043/SuU+HqpIsjapTqvT3w4o0dFbJAcoxTvcJf0ZjVhkzK1V6Jucf+4k8OwqeAFAgMBAAECgYBF+HMcWpudlQaQJ1hlQlKIx91R5CD" + "G7RF3iuoBsl0+omdcjNQGD/PKo9+1G04VE37RH8B8ABdQXqnwgm4ThYqh0XOcL2QcpqzTxCLJI9XsjA5T8EUpETZYl4CNTyVqaEHNywPPVgo7M+dJjfHaKZAiKlpzxJ34M" + "aG/fmfH7p+U3QJBANQhOLugLnz2zPN7ek9uPRlJlp1KGLA7n773fQ9lccBwxmQcec7wshlyOiH6QzYfyry+gH8WmWcs23NvXh+x/p8CQQCyHrcR3r4y7l7ziKc2NsAvL1v" + "PD+hyluNae87XTEN14mSc2qFyjIBRRDS+2Y+nZBLWXOwpTaj7MO24yu1SFjLbAkA3D6R9Nxe6AgmyzYMy6OddD/fTPe9olyFg3TaN74P2Mo+cXrPTXjCsYDTsqtwVSW1DT" + "qNl2YTZ/g+8R9UDnxz7AkEAma+83/NkAwf/73tyY2m8Szo+qhucwfqFMtZusv+/mWB81YYjFXY7ZWNHa4DG3XSQeFt2/XBfpFUkWHTnbhNvTwJBAJq5Gl/CM6Zozhr9yTC" + "S1i3n3ZuX2V0F8X8QlTC90P5GJLAaGadY0DEJICNhmbaRVZ6W4GSmi3nxnibmz936/1k="); + ASSERT_FALSE(rawEncoded.empty()); + ASSERT_FALSE(rawKey.empty()); + SString decrypted = RsaDecode(rawEncoded, rawKey); + EXPECT_EQ(decrypted, "Hello world"); +} + +// Verify RSA decryption of a pre-encoded 2048-bit ciphertext +TEST(SharedUtilHash, RsaDecryptKnown2048) +{ + SString rawEncoded = Base64decode( + "Juwvq3z+ykIIdThZIUgMo3VjX4QqnT16CcJLf6ueCLHAK6E9tneLSSHmMjWr1NexPEVHr9BD3lRnmV78d2p/9yIPIF9tcDcMAqNnNQNcQ+LSgg8urDIWhT+ORCatZsM20" + "7A/W+sQCBqyEsSMflgdc9+K7bmxksucclGyAbjpOvUK7IEH65LJDWFIG4q2uUnzHZkl8UTh26SPbZWecBWME1/+CMR62zJdM43Wm31bFzOPCQCU/5ecJX9brpOX1lGPI6e" + "Eg895ZwSdLH+JaG6wA9BGc2Z/6Fg+EOxNRy8ZzPD7zq6+Z1If3m3ieVVaV0uraVGXUz4ygKgDDTmSwL5vLQ=="); + SString rawKey = Base64decode( + "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCddRAukUoE4EfHv5RO1rHU1s8PLwzAE1eUf4uOcrfNNA677L15RD3ZC4RfdpA4Ya41mMQAy4BimIXHJ" + "Ko0JcygV2Jo9W0268afsJpDgz69uZiXp4OFG1CfKrDNG7oyM310OBkrsQdBPoBNveeBqjWf88oq95nHf5h8MMPL+x2WRf4LELnx1VlaGaw0DfVPHnNtpnv0cMFEc/saCBu" + "UtethD/1HataFucwNotr77tQy1kK8K9nHrFhC69kvPti2unL0IQ3OYMjgZoHpv1Ecz5l7zm2DyRa9RIeeZXnADOwaS/9e6hvriirvs7aqlioVIK1wi82hrZLuOh0rHt5WL" + "+i3AgMBAAECggEAD/DpGX3WG5ZFTiDEOBMeX+j7f5MI3G1Y4YzkKSDOIPVTRI1cRWm2RUIYPb34Le0dwQldVqNDtTex246HuM3W4KjYKr4mN3g5XLN5erpP4M9odnocI56" + "3U9XznmBfQnPaEKkZS0YZ8O4N+VDvnj4IPdBluGHm7L6rRm99cypSPYNgxCyYX0JGEfOYXmvnVqlIlnohVy4IoQ8toPE8WIChN+kXfkcluj++YDvF+7ir7vh8EVgOsgtoz" + "80CS+sn6lUAh+TUFmbHqJvzMn9LovhkMxhq+U55bxpVlzsWQWKKPQsU2F7g3akCux2zapI0C8rIGOqmoO8cY3hkXvAG/LpWuQKBgQD98dJ66cMfGH5uS3XeOadS9JSqyql" + "jejWg7LhFWqpK2UAqE8hxmAhJIRexEH7jxYhCGSro2sLsbiZw00t94cNIjUdfm2urLTNBk+LNExlGMwJmVzNCSIx4085JFLRMIf9XAAOF62gZGW3yRKSl+lfG2aEMN/oQR" + "rm2IVqpLnEsiwKBgQCeu1FJB7zUgOVZEg+DwEm+SalhERwQY200UnkIW0Q9T+SHVS1VGBQHa3oQIICotufLPn1LIRKEl+6mP+ITbxvdFbwCueNnaukGSfVvdno0vwfoFjC" + "PD5nlwWuSf4/kAiA2zX21Hc7yO3+VPSzy9FzLcEQrpg41CnnjVzntl71eBQKBgHuuPpQsrCLF/DXdvM96BvuJMaspP2y6xcnV4T2uFciUnQKhVfu1TzvGyVIstZBb0axXs" + "6VrfopGb6R91IO/5Cu+22c+PCdHwXIMA+dbiPC+wUl06Ps8eGYUyqCfW9zEpicKU6zy5WVsFDdtpT9NeVjY/+4CiWFKAQMqpYxGmUpXAoGAOIq/NMWF1SipCeZuEl9/pUH" + "2DPacSZYxQ08RgBGKqFB6Nl74C/TMxavaSj5Ztj+ZKAP1e7qnLwYz45KkBIoyoblpRItU3vTtVuknfXH1rC5UMa8d0wgaqQYSPJgl+HFtajgezFJ28kCRfObSySSUnX87O" + "VUogGpf6sSahPDlasUCgYBz2t0Qh7aILYiqIu9VaqmSAUQV21tk8rnfD5DmwZchFmVsb1TqogRLWHRz78ciV/RlWt1+QI1scUKHvYUdxrsmR2zq2AO7qWE4csDtYNgnuwZ" + "vTpg9Nn0v9257IPf6O2ihBStJhh18tyR5VIjY5ftAWMZpF67TDdlNuKxBtkUmdg=="); + ASSERT_FALSE(rawEncoded.empty()); + ASSERT_FALSE(rawKey.empty()); + SString decrypted = RsaDecode(rawEncoded, rawKey); + EXPECT_EQ(decrypted, "!@#$%^&*()_+|:<>"); +} + +// Verify RSA decryption of a pre-encoded 4096-bit ciphertext +TEST(SharedUtilHash, RsaDecryptKnown4096) +{ + SString rawEncoded = Base64decode( + "Yxt6G+BHWxutrtZ0ecuOFEZT1NexrLqzOCB1I4p09xlIzepI6j69jqwVdGLJQdlZq2K4O8PoFXgc2o5g9mGpB8zq8KDULkbLwcaNjK0WcRkOPrdveesDUzCCJc7Qm2/BE" + "ItQeTe6kS1joV/VSy8xbyauViJUSA1EcyaIm0WI7JrP/f8phjPlFeSujlAYezyUArBIdvokO6lFJuhTPgMxJ0NOczOrbELszzUaa3ikHm6nkoK7zZQG+o4wlDeshZg1xux" + "qKu0IfvnwQBnP0BttV0aiglGqUonZdy9CvJ14t8jyOo7rLnDkftdyV8ITG5WEoOnSmzcUR8O7xakem2aJhPFZEFcCFu1n3L0kM+L2lPu3QtgMacbtP7Qsk+UNubpSP/t/4" + "1hBnIeQ9CYhvb08PN322OA1ZeAaXVVlyOyM6uTqhD7h4tzUi30/mKqurnrXhzEE2Thn0OZ9rIYcKHHxsE0/dBiOpgngw7I0qCqG7+N0z2NP4Cqj1e/KTEd/7kJQ4/wA7oF" + "PzzNpq70+f/YlQQUyvpmq8kKt3MTwTuWiBDxOiEMHeoJoLEQAIB3obqymE76vfzuOc26fXNmVBsaNkm3wzVbpE9TtktHFCrFwAdvlk5/treUCIjIwoD2PHxJwOs6eFNuOP" + "SZ+WGQ77oZYDHDoDwWi/fNzkPbBT2Cr0Vs="); + SString rawKey = Base64decode( + "MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCdiuUO/W+rDH4qvCNpEKV+5xU/tb0evRPTjuuyTEAC+7QTAtmb0bXRn/rjhHcLqzzQwLzPFt/K18EI2" + "0hsXx/xI8rOzWvuyr8/Anx6fDV/QmEwe92GWoEhTbVkk0myQh0AX5XxIvwLKNfWAyKbncu0BlzF5FUwMJT/r+ttlvauRIv+HLPkKeyx5q40XAkyuK8sw4Bo7lujVgStS1B" + "b4eh3nwoUo3OnfsKfuH4GZaj+O3MfQb2cGw1oLQkS1TYzp5lPDkoRhVtz9CjzEvHkaTE+26cc77KYqOdfm8GHcvoD6MBebcrHcYZ8OFwfFZzENLKzewMSwSdZNjqWPzNll" + "J5PULD0H7g/54sagfp+kx6MKVGcrPHGVGR5RXESfs/ZuukRNcEqGi8+HaBnW5ii+5qvLZtA5F2f/eCvcE9eAo9d/fZWqgfdOV0BN2H2b4ElQLWoBzzfLLyC0dJGHHKxLVx" + "jcxGVIKOq22u57nj0hzfKHWzbjh9s1pcM7HAZfzHJzUf2zutJ2sjnJIcFJCXvArZkSFyIuYJl5BZKb1esjjJwZCCFGt6gj4t3aBUnoyP9Gz9gqcGZm1Qe4aXfyBxWTVw87" + "Y47hP38sy7XyLdD7hlaB8qZJERJRNyFBmILqjX4FZ6AQlNhDeojltyvbdavsIY1h0ooitGdGDxFqIegli+iDwIDAQABAoICAE9YN9sf21DrntOJI9BzmNZcLgCDWLeVhNn" + "FHoITEx4thNkaU1y99vOXvjU+bvKKkLuWhsFKBPZVSZxbTJOAKUc6vpb/ML/4ju9+IhFSY2MvnGFd0QkspeKPD6+S2sgTsiWQ/qSO+R/ptyLLO2/ivkhx9+GXCSyXG0PXZ" + "xwvrxe/4D3gWN2uG87RnqUyQVOxXlCOOise+To/RWW+C7/q/Dja+anBVKtkFUN6GMbCBqXcbTOt2YA4w7zXCb3Zck37uCPvz3AZmSDCNKmPvhJKxImi+PyC4JEwaC9n88V" + "zK+YyIEiuxTVDwPbpL8RcDzNmUyY/6yFT9KxiuokXVZxwiHYhXiWUYfXWu8rAloD4asS0Z+lIGrzVjKuuqp4UgVQLXtMop5L4ddxQrs1c46aRqq9MicFyyR7b2IuZcj9J5" + "bi6DZwYJvItA7Mn9fXahBWWIsaKMo498zIJPFWHQZmzmXOt47wZXDwo9Cu73H3e61NjyR1JJ5WJ3+ykRxAN8wc9t8w9UZnvzjoOwz8sNcu5PT5/GUPArqpqQK8YKjxHDo1" + "KdnsmFUSVkz+fLY0YmID3FzlqKYUtQ5MXvaFTruzdjIdDjupVl1UVJNGYSUUK2oT5qiHYifEcDMsX6qprnm0GAXet2YQoPt8MOsIzFG6QNdeT8XMP7tfIGGpB4uLKVvVxA" + "oIBAQDTjzIEI0cmISBMJ70R6tNJSrn0Q0zmHldb9za79VfKaV0Jk+KHVrLyALsGuJGt+GEnaoJmT79mPQgHoPrGGztasvpCQf1IGxoSfGbopzegPqh7ovoLkp24t+cWChO" + "Jt6aJzaCXDNdNgS25LLVGwKQ5AEaxUoGOp231KHtToqL/8QLlCDNozAGBEB2SHvwtvESkjoe8LLmQ5PY//a700vb/Kfm8is4Q42YcHJUGv39fQ9Yw/Rvzs0JgARYDfqN6u" + "ivLeNgWH4wcSU0HgxmVv7z7YI0VqhevPjSFVOfP5TSOCXv33hYNBZ4p5wEa+bfDNo7Wp0h8Fr+mz3nGXaG/fGQZAoIBAQC+ouUXNBFASdFJeYzzfNoVq33+uaavM+ODUAR" + "kvWsnpP96m17DehQBCvHxg5EaX4LPL1cj8vuFbNrWq1N7lD9t9Dneu6xVspxbN+YoJON1A2gGkhjPpzchEr+6qcoIWmMuIIyrVyNuZL6rA/6yLm0PUXtR9G4et6htNgJia" + "o6/wjuvpCltuoXYWYyDItDuNRQWr/lbsKg++OLhNzmgtCCiqctzi19vziHUP8Ufx/bgmMvV8qLQrLen0g8ahsiDL58yphlyAUA+N1KT4w0koQ/7cYUVSCV8Oeur55tCyf/" + "gCtzhaQvbRrOEscBNnYEj0w3CnUCLzYUuWaTwR1qqybxnAoIBAQCtpTtIaixb/5Si7Xsi2bvSzKMU+qiDuSO7OI6UeCw214Sl99xXebInMLJSMexg/x2/XIzrrUlMgYu1t" + "0wejvuI1p7TA5cBOD2OLs3I6Hef784arQrPtOgAVfI3BM5Em5j2QvEtCj0uQHlnJGsmR7iDkNZ1dWMh1AtMzo1reHKR4SCfHLwVqF0TskaTSRtz7rPo3ZRLv+oQI957Z53" + "TFdXmWm3Bc6zv77ZAHLW1dDj32JZWX2ox/VDdvAZ1l9xXP7fyqp2yivJVxVSUdebqIxbavcUPoy0NieFSDv62hUs9yksWiBNRXOsVOaaOnalXcdCMH4I/V+y23lT1nKTGp" + "zMBAoIBADnGeJO9rfTD6m/QLM2maxniLX9DmKbEnREw8QPu/Ei5ksv/xoqLtwBR5t2BODq785MDD+/PNjdLtE8XAWgUl9ylBdzhF+upBAYJPPGxrFXMQHytTmOwk96sJft" + "WdepuKlzSdI+BCzXrxnVh8pDhzR+1XCCMactZcewXUEWvca/gF+K1Z/DfdK0LBrC/nn5zC7GMh5AoS/U5zNjgudBghvuFZimQdc4WtN30rbNiEQokhLJEpN+FWOu9l+I8M" + "wy/JApfmJqaknPIpHg5ecQ+I+/aibDXerTZgPlKah2lxqyJ3kNaaMN9++4dSOC8+WR4FFWE/wjfsptHg9tmZK4aEcUCggEBAL8qBnKkQgf3mk4EwDJsdoTUk14MLSj65xZ" + "Dyjfm3oTVDhi8xfr6FpUXZHHxZE8pM8GIxcTx/TYAlR0kolxhkPztxxz5ZMTC+0Rr0ugKSklfCa79idE7rJs47LaIUN1pb6LpLYN4ya/U27i6R/4B9BCMpDbb5AARwofXb" + "+qPFtLZmdukLs4WtmLF+LRFqwjTkNPEhK39o5GL86ecm3JGRlDv7NyJJvuzdOQuJbKeif4+WyXRHZFv6wFOlVJLbFP6lzXSYMJtQrABYk7vlOvtG2DMcmp6Wl0IqAZgdrJ" + "W+TP9gfFUerC6nzsIRCQxcW4ygGiAprMTkrgfKZwQ7U6a26U="); + ASSERT_FALSE(rawEncoded.empty()); + ASSERT_FALSE(rawKey.empty()); + SString decrypted = RsaDecode(rawEncoded, rawKey); + EXPECT_EQ(decrypted, "Hecker there"); +} + +/////////////////////////////////////////////////////////////// +// +// AES-128 encrypt/decrypt round-trip +// +/////////////////////////////////////////////////////////////// + +// Verify AES-128-CTR encrypt/decrypt round-trip with simple data +TEST(SharedUtilHash, Aes128RoundTripSimple) +{ + auto res = Aes128encode("AB12\xC2\xA3$_ ", "5347123412340000"); + ASSERT_FALSE(res.first.empty()); + ASSERT_FALSE(res.second.empty()); + SString decoded = Aes128decode(res.first, "5347123412340000", res.second); + EXPECT_EQ(decoded, "AB12\xC2\xA3$_ "); +} + +// Verify AES-128-CTR round-trip with data containing embedded null +TEST(SharedUtilHash, Aes128RoundTripEmbeddedNull) +{ + SString data = MakeRawString("78111E998C42243285635E39AFDD614B\0 AB12\xC2\xA3$_ ", 46); + auto res = Aes128encode(data, "gHtySkGerYnhDxAs"); + ASSERT_FALSE(res.first.empty()); + ASSERT_FALSE(res.second.empty()); + SString decoded = Aes128decode(res.first, "gHtySkGerYnhDxAs", res.second); + EXPECT_EQ(decoded, data); +} + +// Verify AES-128-CTR round-trip with special characters in data +TEST(SharedUtilHash, Aes128RoundTripSpecialChars) +{ + auto res = Aes128encode("Hello thereHello there", "!@#$%^&*()_+|:<>"); + ASSERT_FALSE(res.first.empty()); + ASSERT_FALSE(res.second.empty()); + SString decoded = Aes128decode(res.first, "!@#$%^&*()_+|:<>", res.second); + EXPECT_EQ(decoded, "Hello thereHello there"); +} + +/////////////////////////////////////////////////////////////// +// +// MD5 +// +/////////////////////////////////////////////////////////////// + +// Verify MD5 hash via CMD5Hasher, GenerateHashHexString, and file-based hashing +TEST(SharedUtilHash, MD5) +{ + struct TestData + { + const char* input; + size_t length; + const char* expected; + }; + + TestData tests[] = { + {"", 0, "D41D8CD98F00B204E9800998ECF8427E"}, + {"Hello there", 11, "E8EA7A8D1E93E8764A84A0F3DF4644DE"}, + {"AB12\xC2\xA3$_", 8, "135C3423B76DEECA446666DE48912C3B"}, + }; + + for (const auto& t : tests) + { + SString input = MakeRawString(t.input, t.length); + SString result = CMD5Hasher::CalculateHexString(input.c_str(), input.length()); + EXPECT_EQ(result, t.expected) << "MD5 hasher failed for length " << t.length; + + result = GenerateHashHexString(EHashFunction::MD5, input); + EXPECT_EQ(result, t.expected) << "MD5 GenerateHashHexString failed for length " << t.length; + + FileSave(kTempFilename, input); + result = GenerateHashHexStringFromFile(EHashFunction::MD5, kTempFilename); + EXPECT_EQ(result, t.expected) << "MD5 from file failed for length " << t.length; + } + FileDelete(kTempFilename); +} + +/////////////////////////////////////////////////////////////// +// +// SHA-256 +// +/////////////////////////////////////////////////////////////// + +// Verify SHA-256 hash via GenerateSha256HexString and file-based hashing +TEST(SharedUtilHash, SHA256) +{ + struct TestData + { + const char* input; + size_t length; + const char* expected; + }; + + TestData tests[] = { + {"", 0, "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"}, + {"Hello there", 11, "4E47826698BB4630FB4451010062FADBF85D61427CBDFAED7AD0F23F239BED89"}, + {"AB12\xC2\xA3$_", 8, "46CD8EB20A879864D5B7968679B6D60615BC64592D376FA10A90C064D9BA269F"}, + }; + + for (const auto& t : tests) + { + SString input = MakeRawString(t.input, t.length); + SString result = GenerateSha256HexString(input); + EXPECT_EQ(result, t.expected) << "SHA256 failed for length " << t.length; + + FileSave(kTempFilename, input); + result = GenerateHashHexStringFromFile(EHashFunction::SHA256, kTempFilename); + EXPECT_EQ(result, t.expected) << "SHA256 from file failed for length " << t.length; + } + FileDelete(kTempFilename); +} + +/////////////////////////////////////////////////////////////// +// +// SHA-1 +// +/////////////////////////////////////////////////////////////// + +// Verify SHA-1 hash via GenerateHashHexString and file-based hashing +TEST(SharedUtilHash, SHA1) +{ + struct TestData + { + const char* input; + size_t length; + const char* expected; + }; + + TestData tests[] = { + {"", 0, "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"}, + {"Hello there", 11, "726C76553E1A3FDEA29134F36E6AF2EA05EC5CCE"}, + {"AB12\xC2\xA3$_", 8, "EDD865E6301DC1F3B578E12ACAB9A6363F1F0598"}, + }; + + for (const auto& t : tests) + { + SString input = MakeRawString(t.input, t.length); + SString result = GenerateHashHexString(EHashFunction::SHA1, input); + EXPECT_EQ(result, t.expected) << "SHA1 failed for length " << t.length; + + FileSave(kTempFilename, input); + result = GenerateHashHexStringFromFile(EHashFunction::SHA1, kTempFilename); + EXPECT_EQ(result, t.expected) << "SHA1 from file failed for length " << t.length; + } + FileDelete(kTempFilename); +} + +/////////////////////////////////////////////////////////////// +// +// SHA-224 +// +/////////////////////////////////////////////////////////////// + +// Verify SHA-224 hash via GenerateHashHexString and file-based hashing +TEST(SharedUtilHash, SHA224) +{ + struct TestData + { + const char* input; + size_t length; + const char* expected; + }; + + TestData tests[] = { + {"", 0, "D14A028C2A3A2BC9476102BB288234C415A2B01F828EA62AC5B3E42F"}, + {"Hello there", 11, "40AACC4967ECA7730A1A069539D78AE7782480802E481F1ECC26927D"}, + {"AB12\xC2\xA3$_", 8, "5CD74BB63D1F75CF4E4EB3967D101EC05DBF2E9E101BE932ABD18D27"}, + }; + + for (const auto& t : tests) + { + SString input = MakeRawString(t.input, t.length); + SString result = GenerateHashHexString(EHashFunction::SHA224, input); + EXPECT_EQ(result, t.expected) << "SHA224 failed for length " << t.length; + + FileSave(kTempFilename, input); + result = GenerateHashHexStringFromFile(EHashFunction::SHA224, kTempFilename); + EXPECT_EQ(result, t.expected) << "SHA224 from file failed for length " << t.length; + } + FileDelete(kTempFilename); +} + +/////////////////////////////////////////////////////////////// +// +// SHA-384 +// +/////////////////////////////////////////////////////////////// + +// Verify SHA-384 hash via GenerateHashHexString and file-based hashing +TEST(SharedUtilHash, SHA384) +{ + struct TestData + { + const char* input; + size_t length; + const char* expected; + }; + + TestData tests[] = { + {"", 0, "38B060A751AC96384CD9327EB1B1E36A21FDB71114BE07434C0CC7BF63F6E1DA274EDEBFE76F65FBD51AD2F14898B95B"}, + {"Hello there", 11, "7438E0294C534D6CA6CC2EFB04A60DB488C86B66C4CBD3C00D11D58C8020274AB0A2A720C88986968D894F26B16C461F"}, + {"AB12\xC2\xA3$_", 8, "D097C56CEB17C6553E216C42DA60EF85917738EAB9D5A7A62674945CF51F5945C3A573A1A7E9B40A9B427789110A2C14"}, + }; + + for (const auto& t : tests) + { + SString input = MakeRawString(t.input, t.length); + SString result = GenerateHashHexString(EHashFunction::SHA384, input); + EXPECT_EQ(result, t.expected) << "SHA384 failed for length " << t.length; + + FileSave(kTempFilename, input); + result = GenerateHashHexStringFromFile(EHashFunction::SHA384, kTempFilename); + EXPECT_EQ(result, t.expected) << "SHA384 from file failed for length " << t.length; + } + FileDelete(kTempFilename); +} + +/////////////////////////////////////////////////////////////// +// +// SHA-512 +// +/////////////////////////////////////////////////////////////// + +// Verify SHA-512 hash via GenerateHashHexString and file-based hashing +TEST(SharedUtilHash, SHA512) +{ + struct TestData + { + const char* input; + size_t length; + const char* expected; + }; + + TestData tests[] = { + {"", 0, "CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E"}, + {"Hello there", 11, "567683DDBA1F5A576B68EC26F41FFBCC7E718D646839AC6C2EF746FE952CEF4CBE6DEA635BC2F098B92B65CAACF482333BB9D1D9A3089BC4F01CB86F7A2FBC18"}, + {"AB12\xC2\xA3$_", 8, + "6838166F7AE21CF8344B2F3A83AF2EAF34309AE3A84369BF2E59C7F0FA2971A5975CBC24CF079074FB579BF75920B2E83B0E01AFEDFDB5522240979D3EAA0B6C"}, + }; + + for (const auto& t : tests) + { + SString input = MakeRawString(t.input, t.length); + SString result = GenerateHashHexString(EHashFunction::SHA512, input); + EXPECT_EQ(result, t.expected) << "SHA512 failed for length " << t.length; + + FileSave(kTempFilename, input); + result = GenerateHashHexStringFromFile(EHashFunction::SHA512, kTempFilename); + EXPECT_EQ(result, t.expected) << "SHA512 from file failed for length " << t.length; + } + FileDelete(kTempFilename); +} diff --git a/Tests/client/SharedUtilMath_Tests.cpp b/Tests/client/SharedUtilMath_Tests.cpp new file mode 100644 index 00000000000..4f5bd6f38d6 --- /dev/null +++ b/Tests/client/SharedUtilMath_Tests.cpp @@ -0,0 +1,252 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Tests/client/SharedUtilMath_Tests.cpp + * PURPOSE: Google Test suite for SharedUtil.Math.h utilities + * + *****************************************************************************/ + +#include +#include + +static constexpr float kPi = 3.14159265f; + +/////////////////////////////////////////////////////////////// +// +// Square +// +/////////////////////////////////////////////////////////////// + +// Verify Square() works for positive, negative, and zero integers +TEST(SharedUtilMath, SquareInt) +{ + EXPECT_EQ(SharedUtil::Square(5), 25); + EXPECT_EQ(SharedUtil::Square(-3), 9); + EXPECT_EQ(SharedUtil::Square(0), 0); +} + +// Verify Square() works for floating-point values +TEST(SharedUtilMath, SquareFloat) +{ + EXPECT_FLOAT_EQ(SharedUtil::Square(2.5f), 6.25f); +} + +/////////////////////////////////////////////////////////////// +// +// DegreesToRadians +// +/////////////////////////////////////////////////////////////// + +// Verify 0 degrees converts to 0 radians +TEST(SharedUtilMath, DegreesToRadiansZero) +{ + EXPECT_FLOAT_EQ(SharedUtil::DegreesToRadians(0.0f), 0.0f); +} + +// Verify 180 degrees converts to pi radians +TEST(SharedUtilMath, DegreesToRadians180) +{ + EXPECT_NEAR(SharedUtil::DegreesToRadians(180.0f), kPi, 0.001f); +} + +// Verify 90 degrees converts to pi/2 radians +TEST(SharedUtilMath, DegreesToRadians90) +{ + EXPECT_NEAR(SharedUtil::DegreesToRadians(90.0f), kPi / 2.0f, 0.001f); +} + +// Verify 360 degrees converts to 2*pi radians +TEST(SharedUtilMath, DegreesToRadians360) +{ + EXPECT_NEAR(SharedUtil::DegreesToRadians(360.0f), 2.0f * kPi, 0.01f); +} + +/////////////////////////////////////////////////////////////// +// +// ShouldUseInt +// +/////////////////////////////////////////////////////////////// + +// Verify an exact integer double is recognized and output correctly +TEST(SharedUtilMath, ShouldUseIntExactInteger) +{ + int number = 0; + EXPECT_TRUE(SharedUtil::ShouldUseInt(42.0, &number)); + EXPECT_EQ(number, 42); +} + +// Verify a fractional double is rejected +TEST(SharedUtilMath, ShouldUseIntFractionalValue) +{ + int number = 0; + EXPECT_FALSE(SharedUtil::ShouldUseInt(42.5, &number)); +} + +// Verify 0.0 is recognized as an integer +TEST(SharedUtilMath, ShouldUseIntZero) +{ + int number = -1; + EXPECT_TRUE(SharedUtil::ShouldUseInt(0.0, &number)); + EXPECT_EQ(number, 0); +} + +// Verify large-but-representable integer values are accepted via rounding +TEST(SharedUtilMath, ShouldUseIntLargeValue) +{ + // Values in the large-int range (>= 0x1000000) should return true via rounding + int number = 0; + double large = 20000000.0; + EXPECT_TRUE(SharedUtil::ShouldUseInt(large, &number)); + EXPECT_EQ(number, 20000000); +} + +// Verify values exceeding int range are rejected +TEST(SharedUtilMath, ShouldUseIntTooLargeForInt) +{ + int number = 0; + double huge = 3e10; + EXPECT_FALSE(SharedUtil::ShouldUseInt(huge, &number)); +} + +// Verify negative exact integers are accepted +TEST(SharedUtilMath, ShouldUseIntNegative) +{ + int number = 0; + EXPECT_TRUE(SharedUtil::ShouldUseInt(-100.0, &number)); + EXPECT_EQ(number, -100); +} + +/////////////////////////////////////////////////////////////// +// +// IsNearlyEqual +// +/////////////////////////////////////////////////////////////// + +// Verify identical values are nearly equal +TEST(SharedUtilMath, IsNearlyEqualSameValue) +{ + EXPECT_TRUE(SharedUtil::IsNearlyEqual(1.0f, 1.0f)); +} + +// Verify values within the epsilon threshold are considered nearly equal +TEST(SharedUtilMath, IsNearlyEqualWithinEpsilon) +{ + float eps = 0.01f; + EXPECT_TRUE(SharedUtil::IsNearlyEqual(1.0f, 1.005f, eps)); +} + +// Verify values outside the epsilon threshold are not nearly equal +TEST(SharedUtilMath, IsNearlyEqualOutsideEpsilon) +{ + float eps = 0.001f; + EXPECT_FALSE(SharedUtil::IsNearlyEqual(1.0f, 1.01f, eps)); +} + +/////////////////////////////////////////////////////////////// +// +// ApproximatelyEqual (relative comparison using max) +// +/////////////////////////////////////////////////////////////// + +// Verify identical values pass the max-relative-error approximation check +TEST(SharedUtilMath, ApproximatelyEqualSameValue) +{ + EXPECT_TRUE(SharedUtil::ApproximatelyEqual(100.0f, 100.0f)); +} + +// Verify values within the relative epsilon (based on max) are approximately equal +TEST(SharedUtilMath, ApproximatelyEqualLargeEpsilon) +{ + // With epsilon=0.1, 100 and 105 differ by 5, max(100,105)=105, 105*0.1=10.5 > 5 + EXPECT_TRUE(SharedUtil::ApproximatelyEqual(100.0f, 105.0f, 0.1f)); +} + +// Verify values outside the relative epsilon fail the approximation check +TEST(SharedUtilMath, ApproximatelyEqualFailsSmallEpsilon) +{ + EXPECT_FALSE(SharedUtil::ApproximatelyEqual(100.0f, 110.0f, 0.01f)); +} + +/////////////////////////////////////////////////////////////// +// +// EssentiallyEqual (relative comparison using min) +// +/////////////////////////////////////////////////////////////// + +// Verify identical values pass the min-relative-error essential equality check +TEST(SharedUtilMath, EssentiallyEqualSameValue) +{ + EXPECT_TRUE(SharedUtil::EssentiallyEqual(100.0f, 100.0f)); +} + +// Verify EssentiallyEqual uses min() for a stricter relative comparison than ApproximatelyEqual +TEST(SharedUtilMath, EssentiallyEqualIsStricterThanApproximately) +{ + // With epsilon=0.1, 100 and 105: min(100,105)=100, 100*0.1=10 > 5 => true + EXPECT_TRUE(SharedUtil::EssentiallyEqual(100.0f, 105.0f, 0.1f)); + // But with a smaller epsilon, EssentiallyEqual should be stricter + // min(100,110)=100, 100*0.01=1 < 10 => false + EXPECT_FALSE(SharedUtil::EssentiallyEqual(100.0f, 110.0f, 0.01f)); +} + +/////////////////////////////////////////////////////////////// +// +// DefinitelyGreaterThan / DefinitelyLessThan +// +/////////////////////////////////////////////////////////////// + +// Verify a clearly larger value is detected as definitely greater +TEST(SharedUtilMath, DefinitelyGreaterThanClearlyGreater) +{ + EXPECT_TRUE(SharedUtil::DefinitelyGreaterThan(200.0f, 100.0f, 0.1f)); +} + +// Verify equal values are not definitely greater than each other +TEST(SharedUtilMath, DefinitelyGreaterThanNearlyEqual) +{ + // 100.0 vs 100.0 — not definitely greater + EXPECT_FALSE(SharedUtil::DefinitelyGreaterThan(100.0f, 100.0f, 0.1f)); +} + +// Verify a clearly smaller value is detected as definitely less +TEST(SharedUtilMath, DefinitelyLessThanClearlyLess) +{ + EXPECT_TRUE(SharedUtil::DefinitelyLessThan(100.0f, 200.0f, 0.1f)); +} + +// Verify equal values are not definitely less than each other +TEST(SharedUtilMath, DefinitelyLessThanNearlyEqual) +{ + EXPECT_FALSE(SharedUtil::DefinitelyLessThan(100.0f, 100.0f, 0.1f)); +} + +/////////////////////////////////////////////////////////////// +// +// NumberOfSignificantBits +// +/////////////////////////////////////////////////////////////// + +// Verify compile-time bit count for 0 is 0 +TEST(SharedUtilMath, NumberOfSignificantBitsZero) +{ + EXPECT_EQ(SharedUtil::NumberOfSignificantBits<0>::COUNT, 0); +} + +// Verify compile-time bit count for 1 is 1 +TEST(SharedUtilMath, NumberOfSignificantBitsOne) +{ + EXPECT_EQ(SharedUtil::NumberOfSignificantBits<1>::COUNT, 1); +} + +// Verify 255 (0xFF) requires 8 significant bits +TEST(SharedUtilMath, NumberOfSignificantBits255) +{ + EXPECT_EQ(SharedUtil::NumberOfSignificantBits<255>::COUNT, 8); +} + +// Verify 256 (0x100) requires 9 significant bits +TEST(SharedUtilMath, NumberOfSignificantBits256) +{ + EXPECT_EQ(SharedUtil::NumberOfSignificantBits<256>::COUNT, 9); +} diff --git a/Tests/client/SharedUtil_Impl.cpp b/Tests/client/SharedUtil_Impl.cpp new file mode 100644 index 00000000000..90aa843ff5d --- /dev/null +++ b/Tests/client/SharedUtil_Impl.cpp @@ -0,0 +1,32 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Tests/client/SharedUtil_impl.cpp + * PURPOSE: Provide SharedUtil implementations for the test project + * + *****************************************************************************/ + +#include + +// Core string/formatting implementations +#include "../../Shared/sdk/SString.hpp" +#include "../../Shared/sdk/WString.hpp" + +// Allocation tracking (mostly macros, lightweight) +#include "../../Shared/sdk/SharedUtil.AllocTracking.hpp" + +// Pure utility implementations used by our tests +#include "../../Shared/sdk/SharedUtil.Misc.hpp" +#include "../../Shared/sdk/SharedUtil.File.hpp" +#include "../../Shared/sdk/SharedUtil.Time.hpp" +#include "../../Shared/sdk/SharedUtil.Game.hpp" + +// Hash implementations (MD5, SHA family, TEA, hex conversion - requires bcrypt vendor) +#include "../../Shared/sdk/SharedUtil.Hash.hpp" + +#include "../../Shared/sdk/SharedUtil.Profiling.hpp" +#include "../../Shared/sdk/SharedUtil.Logging.hpp" +#include "../../Shared/sdk/SharedUtil.AsyncTaskScheduler.hpp" +#include "../../Shared/sdk/SharedUtil.Memory.hpp" +#include "../../Shared/sdk/UTF8.hpp" diff --git a/Tests/client/SharedUtil_Tests.cpp b/Tests/client/SharedUtil_Tests.cpp new file mode 100644 index 00000000000..735efd97161 --- /dev/null +++ b/Tests/client/SharedUtil_Tests.cpp @@ -0,0 +1,687 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Tests/client/SharedUtil_Tests.cpp + * PURPOSE: Google Test port of Shared/sdk/SharedUtil.Tests.hpp + * + * Tests ported from the original assert()-based tests in SharedUtil.Tests.hpp. + * Only tests that require no heavy external dependencies (CryptoPP, bcrypt) + * are included here. Hash/crypto tests are deferred to a future iteration + * once those vendor libraries are linked into the test project. + * + *****************************************************************************/ + +#include +#include + +using namespace SharedUtil; + +/////////////////////////////////////////////////////////////// +// +// SString Tests +// +/////////////////////////////////////////////////////////////// + +// Verify SString printf-style construction with mixed format specifiers +TEST(SString, vFormat) +{ + EXPECT_EQ(SString("XX%sAA%dBB", "la", 0), "XXlaAA0BB"); + EXPECT_EQ(SString("XX%sAA%dBB", "laQWE", 2000), "XXlaQWEAA2000BB"); +} + +// Verify Split() separates a string at the Nth delimiter occurrence +TEST(SString, Split) +{ + struct TestData + { + SString source; + const char* delim; + int index; + bool result; + const char* resultLeft; + const char* resultRight; + }; + + TestData tests[] = { + {"a.b.c.d.e", ".", 1, true, "a", "b.c.d.e"}, + {"a.b.c.d.e", ".", 2, true, "a.b", "c.d.e"}, + {"a.b.c.d.e", ".", -2, true, "a.b.c", "d.e"}, + }; + + for (const auto& t : tests) + { + SString strLeft, strRight; + EXPECT_EQ(t.source.Split(t.delim, &strLeft, &strRight, t.index), t.result); + EXPECT_EQ(strLeft, t.resultLeft); + EXPECT_EQ(strRight, t.resultRight); + } +} + +// Verify Split() with a vector output produces all delimited parts +TEST(SString, SplitMultiple) +{ + struct TestData + { + SString source; + const char* delim; + uint maxAmount; + uint minAmount; + const char* resultFirst; + const char* resultLast; + uint resultCount; + }; + + TestData tests[] = { + {"hello", ".", 0, 0, "hello", "hello", 1}, + {"a.#b.#c.#d.#e", ".#", 0, 0, "a", "e", 5}, + }; + + for (const auto& t : tests) + { + std::vector parts; + t.source.Split(t.delim, parts, t.maxAmount, t.minAmount); + EXPECT_EQ(parts.front(), t.resultFirst); + EXPECT_EQ(parts.back(), t.resultLast); + EXPECT_EQ(parts.size(), t.resultCount); + } +} + +// Verify case-sensitive Replace() with various needle/replacement patterns +TEST(SString, Replace) +{ + struct TestData + { + SString source; + const char* needle; + const char* replacement; + const char* result; + }; + + TestData tests[] = { + {"blah1234blah", "la", "QwE", "bQwEh1234bQwEh"}, + {"blah1234blah", "blah", "", "1234"}, + {"blahblah1234", "blah", "", "1234"}, + {"1234blahblah", "blah", "", "1234"}, + {"1234blAhblaH", "BLah", "", "1234blAhblaH"}, + {"blah1234blah", "LA", "QwE", "blah1234blah"}, + {"blah1234blah", "blAh", "", "blah1234blah"}, + {"blah////blah", "//", "/", "blah//blah"}, + }; + + for (const auto& t : tests) + { + EXPECT_EQ(t.source.Replace(t.needle, t.replacement), t.result); + } +} + +// Verify Replace() bSearchJustReplaced flag controls re-scanning of replaced text +TEST(SString, ReplaceSearchJustReplaced) +{ + SString source = "blah////blah"; + // With bSearchJustReplaced = false (default) + EXPECT_EQ(source.Replace("//", "/", false), "blah//blah"); + // With bSearchJustReplaced = true + EXPECT_EQ(source.Replace("//", "/", true), "blah/blah"); +} + +// Verify case-insensitive ReplaceI() matches regardless of letter casing +TEST(SString, ReplaceI) +{ + struct TestData + { + SString source; + const char* needle; + const char* replacement; + const char* result; + }; + + TestData tests[] = { + {"blah1234blah", "la", "QwE", "bQwEh1234bQwEh"}, + {"blah1234blah", "blah", "", "1234"}, + {"blahblah1234", "blAh", "", "1234"}, + {"1234blAhblaH", "BLah", "", "1234"}, + {"blah1234blah", "LA", "QwE", "bQwEh1234bQwEh"}, + {"blah1234blah", "blAh", "", "1234"}, + }; + + for (const auto& t : tests) + { + EXPECT_EQ(t.source.ReplaceI(t.needle, t.replacement), t.result); + } +} + +// Verify SString::Join() reassembles split parts with a delimiter and offset/count +TEST(SString, Join) +{ + struct TestData + { + SString source; + SString delim; + int first; + int count; + SString result; + }; + + TestData tests[] = { + {"", "/", 0, 999, ""}, + {"A", "/", 0, 999, "A"}, + {"A,B", "/", 0, 999, "A/B"}, + {"A,B,C,D,E", "/", 0, 999, "A/B/C/D/E"}, + {"A,B,C,D,E", "/", -5, 7, "A/B"}, + {"", "/", 0, 0, ""}, + {"A", "/", 0, 0, ""}, + {"A,B", "/", 0, 0, ""}, + {"A,B,C,D,E", "/", 0, 0, ""}, + {"", "/", 0, 1, ""}, + {"A", "/", 0, 1, "A"}, + {"A,B", "/", 0, 1, "A"}, + {"A,B,C,D,E", "/", 0, 1, "A"}, + {"", "/", 0, 2, ""}, + {"A", "/", 0, 2, "A"}, + {"A,B", "/", 0, 2, "A/B"}, + {"A,B,C,D,E", "/", 0, 2, "A/B"}, + {"", "/", 1, 2, ""}, + {"A", "/", 1, 2, ""}, + {"A,B", "/", 1, 2, "B"}, + {"A,B,C,D,E", "/", 1, 2, "B/C"}, + {"A,B,C,D,E", "/", 1, 4, "B/C/D/E"}, + {"A,B,C,D,E", "/", 1, 5, "B/C/D/E"}, + }; + + for (const auto& t : tests) + { + std::vector parts; + t.source.Split(",", parts); + EXPECT_EQ(SString::Join(t.delim, parts, t.first, t.count), t.result); + } +} + +/////////////////////////////////////////////////////////////// +// +// SharedUtil File Tests (PathJoin) +// +/////////////////////////////////////////////////////////////// + +#ifdef WIN32 + +// Verify PathJoin normalizes slashes and joins two path segments +TEST(SharedUtilFile, PathJoin2Parts) +{ + struct TestData + { + const char* a; + const char* b; + const char* result; + }; + + TestData tests[] = { + {"///\\\\\\/\\/\\/\\/blah/\\/\\/\\", "////\\\\/////\\/fleeb///\\\\///\\/\\", "\\\\blah\\fleeb\\"}, + {"blah/\\/\\/\\", "////\\\\/////\\/fleeb", "blah\\fleeb"}, + {"blah", "fleeb", "blah\\fleeb"}, + }; + + for (const auto& t : tests) + { + EXPECT_EQ(PathJoin(t.a, t.b), t.result); + } +} + +// Verify PathJoin normalizes and joins three path segments +TEST(SharedUtilFile, PathJoin3Parts) +{ + struct TestData + { + const char* a; + const char* b; + const char* c; + const char* result; + }; + + TestData tests[] = { + {"/blah/", "/\\fl\\eeb/", "//fleeeb/", "\\blah\\fl\\eeb\\fleeeb\\"}, + {"blah/", "/fl//eeb", "\\fleeeb", "blah\\fl\\eeb\\fleeeb"}, + {"blah", "fleeb", "fleeb", "blah\\fleeb\\fleeb"}, + }; + + for (const auto& t : tests) + { + EXPECT_EQ(PathJoin(t.a, t.b, t.c), t.result); + } +} + +// Verify PathJoin preserves UNC, file://, and drive-letter prefixes +TEST(SharedUtilFile, PathJoinUNC) +{ + struct TestData + { + const char* a; + const char* b; + const char* result; + }; + + TestData tests[] = { + {"//blah/", "//fleeeb/", "\\\\blah\\fleeeb\\"}, + {"//?/blah/", "//fleeeb/", "\\\\?\\blah\\fleeeb\\"}, + {"//?/C:\blah/", "//fleeeb/", "\\\\?\\C:\blah\\fleeeb\\"}, + {"///?/C:\blah/", "//fleeeb/", "\\\\?\\C:\blah\\fleeeb\\"}, + {"file://blah/", "//fleeeb/", "file:\\\\blah\\fleeeb\\"}, + {"file:///blah\\/", "//fleeeb/", "file:\\\\blah\\fleeeb\\"}, + {"fil:e///blah\\/", "//fleeeb/", "fil:e\\blah\\fleeeb\\"}, + {"fi/le:///blah\\/", "//fleeeb/", "fi\\le:\\blah\\fleeeb\\"}, + {"c:///blah\\/", "//fleeeb/", "c:\\blah\\fleeeb\\"}, + }; + + for (const auto& t : tests) + { + EXPECT_EQ(PathJoin(t.a, t.b), t.result); + } +} + +#endif // WIN32 + +/////////////////////////////////////////////////////////////// +// +// ClassIdent Tests +// +/////////////////////////////////////////////////////////////// + +#ifdef WIN32 + +// Verify MTA's custom DynamicCast works correctly across a class hierarchy +TEST(SharedUtilClassIdent, DynamicCast) +{ + enum eTestClassTypes + { + CLASS_SPlant, + CLASS_STree, + CLASS_SFlower, + CLASS_SBlueBell, + CLASS_SDaffodil, + }; + + struct SPlant + { + DECLARE_BASE_CLASS(SPlant) + SPlant() : ClassInit(this) {} + }; + + struct STree : SPlant + { + DECLARE_CLASS(STree, SPlant) + STree() : ClassInit(this) {} + }; + + struct SFlower : SPlant + { + DECLARE_CLASS(SFlower, SPlant) + SFlower() : ClassInit(this) {} + }; + + struct SBlueBell : SFlower + { + DECLARE_CLASS(SBlueBell, SFlower) + SBlueBell() : ClassInit(this) {} + }; + + struct SDaffodil : SFlower + { + DECLARE_CLASS(SDaffodil, SFlower) + SDaffodil() : ClassInit(this) {} + }; + + // Create test data + SPlant* pPlant = new SPlant(); + STree* pTree = new STree(); + SFlower* pFlower = new SFlower(); + SBlueBell* pBlueBell = new SBlueBell(); + SDaffodil* pDaffodil = new SDaffodil(); + + // Direct pointer tests + EXPECT_TRUE(DynamicCast(pPlant)); + EXPECT_TRUE(DynamicCast(pTree)); + EXPECT_TRUE(DynamicCast(pFlower)); + EXPECT_TRUE(DynamicCast(pBlueBell)); + EXPECT_TRUE(DynamicCast(pDaffodil)); + + EXPECT_FALSE(DynamicCast(pPlant)); + EXPECT_TRUE(DynamicCast(pTree)); + + EXPECT_FALSE(DynamicCast(pPlant)); + EXPECT_TRUE(DynamicCast(pFlower)); + EXPECT_TRUE(DynamicCast(pBlueBell)); + EXPECT_TRUE(DynamicCast(pDaffodil)); + + EXPECT_FALSE(DynamicCast(pPlant)); + EXPECT_FALSE(DynamicCast(pFlower)); + EXPECT_TRUE(DynamicCast(pBlueBell)); + + EXPECT_FALSE(DynamicCast(pPlant)); + EXPECT_FALSE(DynamicCast(pFlower)); + EXPECT_TRUE(DynamicCast(pDaffodil)); + + // Upcast pointer tests (cast to base, then check derived) + SPlant* pPlantTree = pTree; + SPlant* pPlantFlower = pFlower; + SPlant* pPlantBlueBell = pBlueBell; + SPlant* pPlantDaffodil = pDaffodil; + SFlower* pFlowerBlueBell = pBlueBell; + SFlower* pFlowerDaffodil = pDaffodil; + + EXPECT_TRUE(DynamicCast(pPlantTree)); + EXPECT_TRUE(DynamicCast(pPlantFlower)); + EXPECT_TRUE(DynamicCast(pPlantBlueBell)); + EXPECT_TRUE(DynamicCast(pPlantDaffodil)); + EXPECT_TRUE(DynamicCast(pFlowerBlueBell)); + EXPECT_TRUE(DynamicCast(pFlowerDaffodil)); + + EXPECT_TRUE(DynamicCast(pPlantTree)); + EXPECT_FALSE(DynamicCast(pPlantFlower)); + EXPECT_FALSE(DynamicCast(pPlantBlueBell)); + EXPECT_FALSE(DynamicCast(pPlantDaffodil)); + + EXPECT_FALSE(DynamicCast(pPlantTree)); + EXPECT_TRUE(DynamicCast(pPlantFlower)); + EXPECT_TRUE(DynamicCast(pPlantBlueBell)); + EXPECT_TRUE(DynamicCast(pPlantDaffodil)); + EXPECT_TRUE(DynamicCast(pFlowerBlueBell)); + EXPECT_TRUE(DynamicCast(pFlowerDaffodil)); + + EXPECT_FALSE(DynamicCast(pPlantTree)); + EXPECT_FALSE(DynamicCast(pPlantFlower)); + EXPECT_TRUE(DynamicCast(pPlantBlueBell)); + EXPECT_FALSE(DynamicCast(pPlantDaffodil)); + EXPECT_TRUE(DynamicCast(pFlowerBlueBell)); + EXPECT_FALSE(DynamicCast(pFlowerDaffodil)); + + EXPECT_FALSE(DynamicCast(pPlantTree)); + EXPECT_FALSE(DynamicCast(pPlantFlower)); + EXPECT_FALSE(DynamicCast(pPlantBlueBell)); + EXPECT_TRUE(DynamicCast(pPlantDaffodil)); + EXPECT_FALSE(DynamicCast(pFlowerBlueBell)); + EXPECT_TRUE(DynamicCast(pFlowerDaffodil)); + + // ClassBits must be at least 64 bits + EXPECT_GE(sizeof(ClassBits) * 8, 64u); + + delete pPlant; + delete pTree; + delete pFlower; + delete pBlueBell; + delete pDaffodil; +} + +#endif // WIN32 + +/////////////////////////////////////////////////////////////// +// +// WildcardMatch Tests +// +/////////////////////////////////////////////////////////////// + +// Verify WildcardMatch handles *, ?, and various edge cases +TEST(SharedUtilWildcard, WildcardMatch) +{ + struct TestData + { + const char* pattern; + const char* str; + bool result; + }; + + TestData tests[] = { + {"*bd*", "abcbde", true}, + {"*bd?f*", "abcbdef_bdgh", true}, + {"*bd?h*", "abcbdef_bdgh", true}, + {"*bd?g*", "abcbdef_bdgh", false}, + {"scr*w?d", "screeeewywxd", true}, + {"A*B", "A_B_B", true}, + {"", "", true}, + {"*", "", true}, + {"*", "A", true}, + {"", "A", false}, + {"A*", "", false}, + {"A*", "AAB", true}, + {"A*", "BAA", false}, + {"A*", "A", true}, + {"A*B", "", false}, + {"A*B", "AAB", true}, + {"A*B", "AB", true}, + {"A*B", "AABA", false}, + {"A*B", "ABAB", true}, + {"A*B", "ABBBB", true}, + {"A*B*C", "", false}, + {"A*B*C", "ABC", true}, + {"A*B*C", "ABCC", true}, + {"A*B*C", "ABBBC", true}, + {"A*B*C", "ABBBBCCCC", true}, + {"A*B*C", "ABCBBBCBCCCBCBCCCC", true}, + {"A*B*", "AB", true}, + {"A*B*", "AABA", true}, + {"A*B*", "ABAB", true}, + {"A*B*", "ABBBB", true}, + {"A*B*C*", "", false}, + {"A*B*C*", "ABC", true}, + {"A*B*C*", "ABCC", true}, + {"A*B*C*", "ABBBC", true}, + {"A*B*C*", "ABBBBCCCC", true}, + {"A*B*C*", "ABCBBBCBCCCBCBCCCC", true}, + {"A?", "AAB", false}, + {"A?B", "AAB", true}, + {"A?*", "A", false}, + {"A?*", "ABBCC", true}, + {"A?*", "BAA", false}, + }; + + for (const auto& t : tests) + { + EXPECT_EQ(WildcardMatch(t.pattern, t.str), t.result) << "Pattern: \"" << t.pattern << "\", String: \"" << t.str << "\""; + } +} + +/////////////////////////////////////////////////////////////// +// +// Collection Tests (iterator behaviour) +// +/////////////////////////////////////////////////////////////// + +// Verify post-increment erase idiom works correctly with std::map iterators +TEST(SharedUtilCollection, MapEraseIterator) +{ + std::map testMap; + MapSet(testMap, 10, "10"); + MapSet(testMap, 20, "20"); + MapSet(testMap, 30, "30"); + MapSet(testMap, 40, "40"); + + auto iter = testMap.begin(); + EXPECT_EQ(iter->first, 10u); + iter++; + EXPECT_EQ(iter->first, 20u); + iter++; + testMap.erase(iter++); + EXPECT_EQ(iter->first, 40u); + iter++; + EXPECT_EQ(iter, testMap.end()); +} + +// Verify post-increment erase idiom works correctly with std::set iterators +TEST(SharedUtilCollection, SetEraseIterator) +{ + std::set testSet; + MapInsert(testSet, 10); + MapInsert(testSet, 20); + MapInsert(testSet, 30); + MapInsert(testSet, 40); + + auto iter = testSet.begin(); + EXPECT_EQ(*iter, 10u); + iter++; + EXPECT_EQ(*iter, 20u); + iter++; + testSet.erase(iter++); + EXPECT_EQ(*iter, 40u); + iter++; + EXPECT_EQ(iter, testSet.end()); +} + +// Verify erase returns the next valid iterator for std::list +TEST(SharedUtilCollection, ListEraseIterator) +{ + std::list testList; + testList.push_back(10); + testList.push_back(20); + testList.push_back(30); + testList.push_back(40); + + auto iter = testList.begin(); + EXPECT_EQ(*iter, 10u); + iter++; + EXPECT_EQ(*iter, 20u); + iter++; + iter = testList.erase(iter); + EXPECT_EQ(*iter, 40u); + iter++; + EXPECT_EQ(iter, testList.end()); +} + +// Verify erase returns the next valid iterator for std::vector +TEST(SharedUtilCollection, VectorEraseIterator) +{ + std::vector testList; + testList.push_back(10); + testList.push_back(20); + testList.push_back(30); + testList.push_back(40); + + auto iter = testList.begin(); + EXPECT_EQ(*iter, 10u); + iter++; + EXPECT_EQ(*iter, 20u); + iter++; + iter = testList.erase(iter); + EXPECT_EQ(*iter, 40u); + iter++; + EXPECT_EQ(iter, testList.end()); +} + +/////////////////////////////////////////////////////////////// +// +// String formatting and utility tests +// +/////////////////////////////////////////////////////////////// + +// Verify PRSinS/PRWinS/PRSinW/PRWinW cross-string-type format specifiers +TEST(SharedUtilString, SStringFormatting) +{ + SString strTemp1("name:" PRSinS, "dave"); + SString strTemp2("name:" PRWinS, L"dave"); + WString wstrTemp3(L"name:" PRSinW, "dave"); + WString wstrTemp4(L"name:" PRWinW, L"dave"); + + EXPECT_EQ(strTemp1, "name:dave"); + EXPECT_EQ(strTemp2, "name:dave"); + EXPECT_TRUE(wstrTemp3 == L"name:dave"); + EXPECT_TRUE(wstrTemp4 == L"name:dave"); +} + +// Verify WString::ToAnsi() round-trips ASCII text correctly +TEST(SharedUtilString, WStringToAnsi) +{ + SString strTemp1 = "abcABC 123"; + WString wstrTemp2 = "defDEF 456"; + WString wstrTemp3 = L"ghiGHI 789"; + + EXPECT_TRUE(wstrTemp2 == L"defDEF 456"); + + SString strTemp2 = wstrTemp2.ToAnsi(); + SString strTemp3 = wstrTemp3.ToAnsi(); + + EXPECT_EQ(strTemp2, "defDEF 456"); + EXPECT_EQ(strTemp3, "ghiGHI 789"); +} + +// Verify EscapeURLArgument percent-encodes reserved chars and UnescapeString reverses it +TEST(SharedUtilString, EscapeURLArgument) +{ + struct TestData + { + const char* input; + const char* result; + }; + + TestData tests[] = { + {"!*'();:@", "%21%2A%27%28%29%3B%3A%40"}, + {"&=+$,/?#", "%26%3D%2B%24%2C%2F%3F%23"}, + {"[] \"%<>\\", "%5B%5D%20%22%25%3C%3E%5C"}, + {"^`{|}", "%5E%60%7B%7C%7D"}, + {"AZaz09-_.~", "AZaz09-_.~"}, + }; + + for (const auto& t : tests) + { + SStringX strInput(t.input); + SString strEscaped = SharedUtil::EscapeURLArgument(strInput); + SString strUnescaped = SharedUtil::UnescapeString(strEscaped, '%'); + EXPECT_EQ(strEscaped, t.result); + EXPECT_EQ(strInput, strUnescaped); + } +} + +// Verify RemoveColorCodes strips valid #RRGGBB color codes from narrow strings +TEST(SharedUtilString, RemoveColorCodes) +{ + struct TestData + { + const char* input; + const char* result; + }; + + TestData tests[] = { + {"aa #0f0F34 bb", "aa bb"}, + {"aa #0f0F34#AABBBB bb", "aa bb"}, + {"aa #0f0F3G#AABBBB bb", "aa #0f0F3G bb"}, + {"aa #0f0F34#AABBB bb", "aa #AABBB bb"}, + {"#0f0F34#AABBB1", ""}, + {"#0f0F34 x #AABBB1", " x "}, + {"#0f0F34#0f0F34 x #AABBB1#AABBB1", " x "}, + {"#123456#12345G#123456#12345G", "#12345G#12345G"}, + {"#123456#12345#123456#125G", "#12345#125G"}, + {"##123456#125G##123456#12345", "##125G##12345"}, + }; + + for (const auto& t : tests) + { + EXPECT_EQ(SharedUtil::RemoveColorCodes(t.input), t.result) << "Input: \"" << t.input << "\""; + } +} + +// Verify RemoveColorCodesInPlaceW strips color codes from wide strings in-place +TEST(SharedUtilString, RemoveColorCodesInPlaceW) +{ + struct TestData + { + const wchar_t* input; + const wchar_t* result; + }; + + TestData tests[] = { + {L"aa #0f0F34 bb", L"aa bb"}, + {L"aa #0f0F34#AABBBB bb", L"aa bb"}, + {L"aa #0f0F3G#AABBBB bb", L"aa #0f0F3G bb"}, + {L"aa #0f0F34#AABBB bb", L"aa #AABBB bb"}, + {L"#0f0F34#AABBB1", L""}, + {L"#0f0F34 x #AABBB1", L" x "}, + {L"#0f0F34#0f0F34 x #AABBB1#AABBB1", L" x "}, + {L"#123456#12345G#123456#12345G", L"#12345G#12345G"}, + {L"#123456#12345#123456#125G", L"#12345#125G"}, + {L"##123456#125G##123456#12345", L"##125G##12345"}, + }; + + for (const auto& t : tests) + { + WString wstr = t.input; + SharedUtil::RemoveColorCodesInPlaceW(wstr); + EXPECT_TRUE(wstr == t.result); + } +} diff --git a/Tests/client/main.cpp b/Tests/client/main.cpp new file mode 100644 index 00000000000..3cd26586c5a --- /dev/null +++ b/Tests/client/main.cpp @@ -0,0 +1,18 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: Tests/client/main.cpp + * PURPOSE: Google Test entry point for client unit tests + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/Tests/client/premake5.lua b/Tests/client/premake5.lua new file mode 100644 index 00000000000..bb16c092712 --- /dev/null +++ b/Tests/client/premake5.lua @@ -0,0 +1,46 @@ +project "Tests_Client" + language "C++" + kind "ConsoleApp" + targetname "Tests_Client" + targetdir(buildpath("tests")) + + vpaths { + ["Headers/*"] = "**.h", + ["Sources/*"] = "**.cpp", + ["*"] = "premake5.lua" + } + + includedirs { + "../../Shared/sdk", + "../../Client/sdk", + "../../vendor/googletest/include", + -- Needed so SharedUtil.h -> SharedUtil.Crypto.h can find and + "../../vendor", + } + + links { "gtest", "cryptopp", "blowfish_bcrypt", "zlib" } + + files { + "premake5.lua", + "**.h", + "**.cpp" + } + + defines { + "GTEST_HAS_PTHREAD=0", + "MTA_CLIENT", + "SHARED_UTIL_WITH_HASH_MAP", + } + + filter "system:windows" + includedirs { "../../vendor/sparsehash/src/windows" } + links { "ws2_32", "shlwapi", "shell32" } + + filter {} + includedirs { "../../vendor/sparsehash/src/" } + + filter "architecture:not x86" + flags { "ExcludeFromBuild" } + + filter "system:not windows" + flags { "ExcludeFromBuild" } diff --git a/crowdin.yml b/crowdin.yml index 1e88cfcea9d..8355b173868 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -2,8 +2,8 @@ commit_message: '[ci skip]' files: - source: /Shared/data/MTA San Andreas/MTA/locale/en_US/* ignore: - - 'latest_news.png' - - 'menu_*.png' + - latest_news.png + - menu_*.png translation: /Shared/data/MTA San Andreas/MTA/locale/%locale_with_underscore%/%original_file_name% - source: /Shared/installer/locale/en_US.pot translation: /Shared/installer/locale/%locale_with_underscore%.%file_extension% diff --git a/linux-build.sh b/linux-build.sh index a4a72a711bc..fa6c2fde2a1 100755 --- a/linux-build.sh +++ b/linux-build.sh @@ -1,27 +1,27 @@ #!/bin/bash -e # Set variable defaults -: ${BUILD_OS:=linux} -: ${BUILD_ARCHITECTURE:=x64} : ${BUILD_CONFIG:=release} : ${PREMAKE_FILE:=premake5.lua} -# Find premake binary location if [ "$(uname)" == "Darwin" ]; then - PREMAKE5=utils/premake5-macos + cores=$(sysctl -n hw.ncpu) + : ${NUM_CORES:=$cores} + : ${PREMAKE5:=utils/premake5-macos} + : ${BUILD_OS:=macosx} + : ${BUILD_ARCHITECTURE:=arm64} + : ${AR:=ar} + : ${CC:=clang} + : ${CXX:=clang++} else - PREMAKE5=utils/premake5 -fi - -# Number of cores -if [ "$(uname)" == "Darwin" ]; then - NUM_CORES=$(sysctl -n hw.ncpu) - : ${GCC_PREFIX:=} + cores=$(grep -c ^processor /proc/cpuinfo) + : ${NUM_CORES:=$cores} + : ${PREMAKE5:=utils/premake5} + : ${BUILD_OS:=linux} + : ${BUILD_ARCHITECTURE:=x64} : ${AR:=ar} : ${CC:=gcc} : ${CXX:=g++} -else - NUM_CORES=$(grep -c ^processor /proc/cpuinfo) fi # Read script arguments @@ -55,31 +55,15 @@ esac case $BUILD_ARCHITECTURE in 32|x86) CONFIG=${BUILD_CONFIG}_x86 - : ${GCC_PREFIX:=i386-linux-gnu-} - : ${AR:=x86_64-linux-gnu-gcc-ar-10} - : ${CC:=x86_64-linux-gnu-gcc-10} - : ${CXX:=x86_64-linux-gnu-g++-10} ;; 64|x64) CONFIG=${BUILD_CONFIG}_x64 - : ${GCC_PREFIX:=x86_64-linux-gnu-} - : ${AR:=x86_64-linux-gnu-gcc-ar-10} - : ${CC:=x86_64-linux-gnu-gcc-10} - : ${CXX:=x86_64-linux-gnu-g++-10} ;; arm) CONFIG=${BUILD_CONFIG}_${BUILD_ARCHITECTURE} - : ${GCC_PREFIX:=arm-linux-gnueabihf-} - : ${AR:=arm-linux-gnueabihf-ar} - : ${CC:=arm-linux-gnueabihf-gcc-10} - : ${CXX:=arm-linux-gnueabihf-g++-10} ;; arm64) CONFIG=${BUILD_CONFIG}_${BUILD_ARCHITECTURE} - : ${GCC_PREFIX:=aarch64-linux-gnu-} - : ${AR:=aarch64-linux-gnu-gcc-ar-10} - : ${CC:=aarch64-linux-gnu-gcc-10} - : ${CXX:=aarch64-linux-gnu-g++-10} ;; *) echo "Error: Invalid build architecture" >&2 diff --git a/premake5.lua b/premake5.lua index f87c8585979..6da46bf9baf 100644 --- a/premake5.lua +++ b/premake5.lua @@ -14,7 +14,13 @@ if ci and ci:lower() == "true" then else CI_BUILD = false end + GLIBC_COMPAT = os.getenv("GLIBC_COMPAT") == "true" +MTA_MAETRO = os.getenv("MTA_MAETRO") == "true" + +if MTA_MAETRO then + require "maetro" +end newoption { trigger = "gccprefix", @@ -26,7 +32,7 @@ workspace "MTASA" configurations {"Debug", "Release", "Nightly"} if os.host() == "macosx" then - platforms { "x64", "arm64" } + platforms { "arm64" } elseif os.host() == "windows" then platforms { "x86", "x64", "arm64" } else @@ -42,7 +48,7 @@ workspace "MTASA" location "Build" startproject "Client Launcher" - cppdialect "C++17" + cppdialect "C++23" characterset "MBCS" pic "On" symbols "On" @@ -61,6 +67,10 @@ workspace "MTASA" "_TIMESPEC_DEFINED" } + if MTA_MAETRO then + defines { "MTA_MAETRO" } + end + -- Helper function for output path buildpath = function(p) return "%{wks.location}/../Bin/"..p.."/" end copy = function(p) return "{COPY} %{cfg.buildtarget.abspath} \"%{wks.location}../Bin/"..p.."/\"" end @@ -89,6 +99,12 @@ workspace "MTASA" defines { "MTA_DEBUG" } targetsuffix "_d" + filter "configurations:Release" + defines { "MTA_RELEASE" } + + filter "configurations:Nightly" + defines { "MTA_NIGHTLY" } + filter "configurations:Release or configurations:Nightly" optimize "Speed" -- "On"=MS:/Ox GCC:/O2 "Speed"=MS:/O2 GCC:/O3 "Full"=MS:/Ox GCC:/O3 @@ -111,11 +127,11 @@ workspace "MTASA" symbolspath "$(SolutionDir)Symbols\\$(Configuration)_$(Platform)\\$(ProjectName).pdb" filter "system:windows" - toolset "v143" + toolset "v145" preferredtoolarchitecture "x86_64" staticruntime "On" defines { "WIN32", "_WIN32", "_WIN32_WINNT=0x601", "_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion)" } - buildoptions { "/Zc:__cplusplus" } + buildoptions { "/Zc:__cplusplus", "/permissive-" } includedirs { path.join(dxdir, "Include") } @@ -123,10 +139,18 @@ workspace "MTASA" path.join(dxdir, "Lib/x86") } + if MTA_MAETRO then + flags { "NoImplicitLink" } + end + filter {"system:windows", "configurations:Debug"} runtime "Release" -- Always use Release runtime defines { "DEBUG" } -- Using DEBUG as _DEBUG is not available with /MT + -- Disable Edit and Continue on x86 Debug to avoid conflict with /SAFESEH + filter {"system:windows", "configurations:Debug", "platforms:x86"} + editandcontinue "Off" + filter { "system:linux or macosx", "configurations:not Debug" } buildoptions { "-fvisibility=hidden" } @@ -170,6 +194,14 @@ workspace "MTASA" include "vendor/libspeex" include "vendor/detours" include "vendor/lunasvg" + include "vendor/googletest" + + if MTA_MAETRO then + include "vendor/maetro32" + end + + group "Tests" + include "Tests/client" end filter {} diff --git a/utils/buildactions/compose_files.lua b/utils/buildactions/compose_files.lua index 0adaf2cfc1a..a9fa9679567 100644 --- a/utils/buildactions/compose_files.lua +++ b/utils/buildactions/compose_files.lua @@ -11,10 +11,10 @@ local WINDOWS = os.host() == "windows" newaction { trigger = "compose_files", description = "Composes files that are required for building the installer", - + execute = function() os.mkdir(OUTPUT_DIR) - + -- Copy data files if WINDOWS then os.copydir(DATA_DIR.."/MTA", OUTPUT_DIR.."/MTA") @@ -25,9 +25,9 @@ newaction { -- Copy configs os.copydir("Server/mods/deathmatch", OUTPUT_DIR.."/server/mods/deathmatch", "*.conf") - os.copydir("Server/mods/deathmatch", OUTPUT_DIR.."/server/mods/deathmatch", "mtaserver.conf.template") + makeconfigtemplate(OUTPUT_DIR.."/server/mods/deathmatch/mtaserver.conf", OUTPUT_DIR.."/server/mods/deathmatch/mtaserver.conf.template") os.copydir("Server/mods/deathmatch", OUTPUT_DIR.."/server/mods/deathmatch", "*.xml") - + -- Copy compiled binaries if WINDOWS then os.copydir(BIN_DIR, OUTPUT_DIR, "**.exe") diff --git a/utils/buildactions/install_cef.lua b/utils/buildactions/install_cef.lua index 221a8918551..f60f914e217 100644 --- a/utils/buildactions/install_cef.lua +++ b/utils/buildactions/install_cef.lua @@ -9,8 +9,15 @@ local CEF_URL_PREFIX = "https://cef-builds.spotifycdn.com/cef_binary_" local CEF_URL_SUFFIX = "_windows32_minimal.tar.bz2" -- Change here to update CEF version -local CEF_VERSION = "138.0.33+g276ed6d+chromium-138.0.7204.169" -local CEF_HASH = "59ddad41e92bba21b133a20fe48165db02b77b063553051f8f021643bd9fcaef" +local CEF_VERSION = "144.0.13+g9f739aa+chromium-144.0.7559.133" +local CEF_HASH = "f39f2c31a2ac08f4e134b147072708468dc0861ca35ddcd333f4a8494beb3433" + +-- Stuck in the past for maetro +if os.getenv("MTA_MAETRO") == "true" then + CEF_URL_PREFIX = "https://mirror-cdn.multitheftauto.com/vendor/cef/cef_binary_" + CEF_VERSION = "109.1.18+gf1c41e4+chromium-109.0.5414.120" + CEF_HASH = "ac78ea1e9f9d386130de16ca951acef1ba5a37ad9aef9d66f3d5f3529672c21c" +end function make_cef_download_url() return CEF_URL_PREFIX..CEF_VERSION..CEF_URL_SUFFIX diff --git a/utils/buildactions/install_data.lua b/utils/buildactions/install_data.lua index 930ecf35197..08bbc821c8e 100644 --- a/utils/buildactions/install_data.lua +++ b/utils/buildactions/install_data.lua @@ -5,18 +5,19 @@ premake.modules.install_data = {} -- Config variables local BIN_DIR = "Bin" local DATA_DIR = "Shared/data/MTA San Andreas" +local BASE_URL = "https://mirror-cdn.multitheftauto.com/bdata/" -local NET_PATH_X86_WIN = "https://mirror-cdn.multitheftauto.com/bdata/net.dll" -local NET_PATH_X64_WIN = "https://mirror-cdn.multitheftauto.com/bdata/net_64.dll" -local NET_PATH_ARM64_WIN = "https://mirror-cdn.multitheftauto.com/bdata/net_arm64.dll" -local NETC_PATH_WIN = "https://mirror-cdn.multitheftauto.com/bdata/netc.dll" +local NET_PATH_X86_WIN = BASE_URL .. "net.dll" +local NET_PATH_X64_WIN = BASE_URL .. "net_64.dll" +local NET_PATH_ARM64_WIN = BASE_URL .. "net_arm64.dll" +local NETC_PATH_WIN = BASE_URL .. "netc.dll" -local NET_PATH_X86_LINUX = "https://mirror-cdn.multitheftauto.com/bdata/net.so" -local NET_PATH_X64_LINUX = "https://mirror-cdn.multitheftauto.com/bdata/net_64.so" -local NET_PATH_ARM_LINUX = "https://mirror-cdn.multitheftauto.com/bdata/net_arm.so" -local NET_PATH_ARM64_LINUX = "https://mirror-cdn.multitheftauto.com/bdata/net_arm64.so" +local NET_PATH_X86_LINUX = BASE_URL .. "net.so" +local NET_PATH_X64_LINUX = BASE_URL .. "net_64.so" +local NET_PATH_ARM_LINUX = BASE_URL .. "net_arm.so" +local NET_PATH_ARM64_LINUX = BASE_URL .. "net_arm64.so" -local NET_PATH_X64_MACOS = "https://mirror-cdn.multitheftauto.com/bdata/net.dylib" +local NET_PATH_X64_MACOS = BASE_URL .. "net.dylib" newaction { trigger = "install_data", @@ -49,9 +50,8 @@ newaction { return end - local success, message = os.copydir("Server/mods/deathmatch", BIN_DIR.."/server/mods/deathmatch", "mtaserver.conf.template", false, true) - if not success then - errormsg("ERROR: Couldn't copy server config files", "\n"..message) + if not makeconfigtemplate(BIN_DIR.."/server/mods/deathmatch/mtaserver.conf", BIN_DIR.."/server/mods/deathmatch/mtaserver.conf.template") then + errormsg("ERROR: Could not copy mtaserver.conf to mtaserver.conf.template") os.exit(1) return end @@ -76,7 +76,7 @@ newaction { success = success and http.download_print_errors(NET_PATH_X64_WIN, BIN_DIR.."/server/x64/net.dll") success = success and http.download_print_errors(NET_PATH_ARM64_WIN, BIN_DIR.."/server/arm64/net.dll") success = success and http.download_print_errors(NETC_PATH_WIN, BIN_DIR.."/MTA/netc.dll") - + -- A download failed if not success then os.exit(1) @@ -111,13 +111,13 @@ newaction { print(string.format("Listen, I ain't leaving here till you tell me where the macOS net builds are.\n " .. " So come on bub, for old times' sake, huh?\n\t%s[45m%s[37mDid you just call me... BLOB?%s[0m\n", c,c,c,c)) - if not http.download_print_errors(NET_PATH_X64_MACOS, BIN_DIR.."/server/x64/net.dylib") then + if not http.download_print_errors(NET_PATH_X64_MACOS, BIN_DIR.."/server/arm64/net.dylib") then os.exit(1) return end - if not os.copyfile(BIN_DIR.."/server/x64/net.dylib", BIN_DIR.."/server/x64/net_d.dylib") then - errormsg("ERROR: Could not copy server/x64/net.dylib") + if not os.copyfile(BIN_DIR.."/server/arm64/net.dylib", BIN_DIR.."/server/arm64/net_d.dylib") then + errormsg("ERROR: Could not copy server/arm64/net.dylib") os.exit(1) return end diff --git a/utils/buildactions/install_discord.lua b/utils/buildactions/install_discord.lua index 912ae100b34..ca7dd3944f1 100644 --- a/utils/buildactions/install_discord.lua +++ b/utils/buildactions/install_discord.lua @@ -145,6 +145,7 @@ end local function check_rapid(should_upgrade) local has_rapid_dir = os.isdir(RAPID_PATH) + local is_installed = has_rapid_dir and os.isfile(RAPID_PATH .. "include/rapidjson/document.h") -- Check file hash local archive_path = RAPID_TEMP @@ -152,7 +153,7 @@ local function check_rapid(should_upgrade) if hash_passed then print("rapidjson consistency checks succeeded") - if has_rapid_dir then + if is_installed then return end else @@ -190,7 +191,7 @@ local function check_rapid(should_upgrade) end -- Delete old rapidjson files - if has_discord_dir then + if has_rapid_dir then if not os.rmdir(RAPID_PATH) then errormsg("ERROR: Could not delete rapidjson folder") os.exit(1) diff --git a/utils/buildactions/maetro.lua b/utils/buildactions/maetro.lua new file mode 100644 index 00000000000..77cc56eff57 --- /dev/null +++ b/utils/buildactions/maetro.lua @@ -0,0 +1,15 @@ +local use64 = false +function maetro64() + use64 = true +end + +local _project = project +function project(name) + _project(name) + + if name ~= "maetro32" and name ~= "maetro64" then + links { use64 and "maetro64" or "maetro32", "kernel32.lib"} + linkoptions { "/NODEFAULTLIB:kernel32" } + use64 = false + end +end diff --git a/utils/buildactions/utils.lua b/utils/buildactions/utils.lua index 6f573f6a481..dd21e77b236 100644 --- a/utils/buildactions/utils.lua +++ b/utils/buildactions/utils.lua @@ -96,7 +96,7 @@ function os.sha256_file(path) local windows = os.host() == "windows" local s, errc if windows then - s, errc = os.outputof(string.format("CertUtil -hashfile \"%s\" SHA256", path)) + s, errc = os.outputof(string.format("call \"utils\\7z\\7za.exe\" h -scrcSHA256 \"%s\"", path)) else s, errc = os.outputof(string.format("sha256sum \"%s\" | awk '{ print $1 }'", path)) end @@ -109,7 +109,7 @@ function os.sha256_file(path) -- Clean windows output if windows then - s = (s:match("\n(.*)\n(.*)") or ""):gsub(" ", "") + s = (s:match("SHA256 for data: +([^\n]*)") or "") end return s:lower() @@ -171,3 +171,25 @@ function errormsg(title, message) end term.popColor() end + +-- Does a normal file copy and adds hardcoded text to the beginning of the resulting file +-- Used in compose_files.lua and install_data.lua +function makeconfigtemplate(file_path, result_path) + if not os.copyfile(file_path, result_path) then + return false + end + local result_file = io.open(result_path, "r") + if not result_file then + return false + end + local file_content = result_file:read("*all") + result_file:close() + result_file = io.open(result_path, "w") + if not result_file then + return false, "Failed to open result file for writing." + end + result_file:write("\n") + result_file:write(file_content) + result_file:close() + return true +end diff --git a/utils/clang-format.ps1 b/utils/clang-format.ps1 new file mode 100755 index 00000000000..8a182a95c6e --- /dev/null +++ b/utils/clang-format.ps1 @@ -0,0 +1,141 @@ +#!/usr/bin/env pwsh + +# Check PowerShell version +if ($PSVersionTable.PSVersion.Major -lt 7) { + $currentVersion = $PSVersionTable.PSVersion + Write-Error @" +This script requires PowerShell 7 or later. +Current version: $currentVersion + +Install PowerShell 7+: + - Or run: winget install Microsoft.PowerShell (Windows) + - Windows/macOS/Linux: https://github.com/PowerShell/PowerShell#get-powershell +"@ + exit 1 +} + +$ToolConfig = @{ + "clang-format" = @{ + "linux-amd64" = @{ + "url" = "https://github.com/multitheftauto/clang-tools-static-binaries/releases/download/v21.1.7/clang-format-21_linux-amd64" + "filename" = "clang-format" + "hash" = "3d75779cdc69b06f7e39946b0e50d6ce3dccda1d766e355bf4cf507b1ae13303" + } + "windows-amd64" = @{ + "url" = "https://github.com/multitheftauto/clang-tools-static-binaries/releases/download/v21.1.7/clang-format-21_windows-amd64.exe" + "filename" = "clang-format.exe" + "hash" = "11defe615493876745f36fb77e9783e7eed03a7f800044ff58619d9293e79409" + } + } + # "clang-tidy" = @{ + # "linux-amd64" = @{ + # "url" = "https://github.com/multitheftauto/clang-tools-static-binaries/releases/download/v21.1.7/clang-tidy-21_linux-amd64" + # "filename" = "clang-tidy" + # "hash" = "7b35986c04b7c4fc7040c254ac2b5eb0b01ece87c91cccb32e3a4d6ecfa9695f" + # } + # "windows-amd64" = @{ + # "url" = "https://github.com/multitheftauto/clang-tools-static-binaries/releases/download/v21.1.7/clang-tidy-21_windows-amd64.exe" + # "filename" = "clang-tidy.exe" + # "hash" = "e6afe42eb50ec9dcdf945d88b220b6b36971573cec7c5b6db22d3535c6cc61c4" + # } + # } +} + +function Get-ClangTool { + param( + [Parameter(Mandatory)] [string]$RepoRoot, + [Parameter(Mandatory)] [string]$ToolName + ) + + $platform = if ($isLinux) { "linux-amd64" } else { "windows-amd64" } + $toolConfig = $ToolConfig[$ToolName][$platform] + if (-not $toolConfig) { + Write-Error "No configuration found for tool '$ToolName' on platform '$platform'" + exit 1 + } + + $binDir = Join-Path $RepoRoot "Build" "tmp" + if (-not (Test-Path $binDir)) { + New-Item -ItemType Directory -Path $binDir | Out-Null + } + + # Check existing file + $toolPath = Join-Path $binDir $toolConfig.filename + if (Test-Path $toolPath) { + $currentHash = (Get-FileHash -Path $toolPath -Algorithm SHA256).Hash + if ($currentHash -eq $toolConfig.hash) { + return $toolPath + } + Write-Warning "$ToolName hash mismatch, re-downloading..." + } + + # Download process + Write-Host "Downloading $ToolName..." -ForegroundColor Cyan + Invoke-WebRequest -Uri $toolConfig.url -OutFile $toolPath + if ($isLinux) { + chmod +x $toolPath + } + Write-Verbose "Downloaded $ToolName to $toolPath" + + # Verify hash + $downloadedHash = (Get-FileHash -Path $toolPath -Algorithm SHA256).Hash + if ($downloadedHash -ne $toolConfig.hash) { + Remove-Item $toolPath -ErrorAction SilentlyContinue + Write-Error "SHA256 hash mismatch! The download may be corrupted. Expected: $($toolConfig.hash) Got: $downloadedHash" + exit 1 + } + + Write-Verbose "$ToolName verified successfully." + return $toolPath +} + +function Invoke-ClangFormat { + [CmdletBinding()] + param() + + $arguments = @('-i') + if ($VerbosePreference -eq 'Continue') { + $arguments += '--verbose' + } + + $repoRoot = Split-Path -Parent $PSScriptRoot + Push-Location $repoRoot + Write-Verbose "Changed directory to repository root: $repoRoot" + + try { + $clangFormatPath = Get-ClangTool -RepoRoot $repoRoot -ToolName "clang-format" + # $clangTidyPath = Get-ClangTool -RepoRoot $repoRoot -ToolName "clang-tidy" + + Write-Verbose "Searching for source files to format..." + $searchFolders = "Client", "Server", "Shared", "Tests" + $files = Get-ChildItem -Path $searchFolders -Include *.c, *.cc, *.cpp, *.h, *.hh, *.hpp -Recurse -ErrorAction SilentlyContinue + + $tmp = [System.IO.Path]::GetTempFileName() + $files.FullName | ForEach-Object { '"{0}"' -f $_ } | Set-Content $tmp -Encoding utf8 + Write-Verbose "List of files to format written to temporary file: $tmp" + + & "$clangFormatPath" @arguments "@$tmp" + + Remove-Item $tmp + Write-Verbose "Successfully formatted $($files.Count) files." + + # Check git diff only on Linux (CI's checkout starts off clean) + if ($isLinux) { + $diffOutput = git diff --name-only + if ($diffOutput.Count -eq 0) { + Write-Host "No formatting changes detected." -ForegroundColor Green + exit 0 + } else { + Write-Host "::group::Files with formatting issues ($($diffOutput.Count) files)" + $diffOutput | ForEach-Object { Write-Host $_ } + Write-Host "::endgroup::" + Write-Error "Code formatting issues detected. Run utils/clang-format.ps1 locally and commit the changes." + exit 1 + } + } + } finally { + Pop-Location + } +} + +Invoke-ClangFormat @args diff --git a/utils/docker/Dockerfile b/utils/docker/Dockerfile index 943137f5d9c..a7174179eca 100644 --- a/utils/docker/Dockerfile +++ b/utils/docker/Dockerfile @@ -1,65 +1,62 @@ -FROM ubuntu:focal +FROM ghcr.io/multitheftauto/mtasa-blue-gcc:15-noble -ENV LC_ALL=C.UTF-8 \ - LANG=C.UTF-8 \ - LANGUAGE=C.UTF-8 \ - GLIBC_COMPAT=true +ARG GLIBC_COMPAT=true -# Trust the signing key for "PPA for Ubuntu Toolchain Uploads". -# Source: https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2c277a0a352154e5 -COPY ubuntu-toolchain-r-ubuntu-test.asc /etc/apt/trusted.gpg.d/ - -# Use a combined APT sources list for amd64, i386, armhf, arm64, and PPA for Ubuntu Toolchain Uploads. -COPY sources.list /etc/apt/sources.list +# Use a combined APT sources list for amd64, i386, armhf and arm64. +COPY ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources # 1. Add the supported architectures. # 2. Install all compilers and build-time dependencies (libncurses, libmysqlclient) for every architecture. # 3. Manually download, modify, and install libmysqlclient-dev, because it can't be installed in parallel. # 4. Remove cache and temporary files. -RUN dpkg --add-architecture i386 \ - && dpkg --add-architecture armhf \ - && dpkg --add-architecture arm64 \ - && apt-get update \ - && apt-get install -y --no-install-recommends make \ - libncurses-dev:arm64 libmysqlclient21:arm64 zlib1g-dev:arm64 libssl-dev:arm64 g++-10-arm-linux-gnueabihf \ - libncurses-dev:armhf libmysqlclient21:armhf zlib1g-dev:armhf libssl-dev:armhf g++-10-aarch64-linux-gnu \ - libncurses-dev:i386 libmysqlclient21:i386 zlib1g-dev:i386 libssl-dev:i386 g++-10-multilib \ - libncurses-dev libmysqlclient21 zlib1g-dev libssl-dev \ - && apt-get upgrade -y \ - && cd /tmp \ - && apt-get download \ +RUN set -ex ;\ + dpkg --add-architecture i386 ;\ + dpkg --add-architecture armhf ;\ + dpkg --add-architecture arm64 ;\ + apt-get update ;\ + DEBIAN_FRONTEND=noninteractive apt-get install -y make binutils \ + libncurses-dev:arm64 libmysqlclient21:arm64 zlib1g-dev:arm64 libzstd-dev:arm64 libssl-dev:arm64 \ + libncurses-dev:armhf libmysqlclient21:armhf zlib1g-dev:armhf libzstd-dev:armhf libssl-dev:armhf \ + libncurses-dev:i386 libmysqlclient21:i386 zlib1g-dev:i386 libzstd-dev:i386 libssl-dev:i386 \ + libncurses-dev libmysqlclient21 zlib1g-dev libzstd-dev libssl-dev \ + ;\ + apt-get upgrade -y ;\ + cd /tmp ;\ + apt-get download \ libmysqlclient-dev:armhf \ libmysqlclient-dev:arm64 \ libmysqlclient-dev:i386 \ libmysqlclient-dev \ - && dpkg-deb -R libmysqlclient-dev_*_armhf.deb libmysqlclient-dev-armhf \ - && dpkg-deb -R libmysqlclient-dev_*_arm64.deb libmysqlclient-dev-arm64 \ - && dpkg-deb -R libmysqlclient-dev_*_i386.deb libmysqlclient-dev-i386 \ - && dpkg-deb -R libmysqlclient-dev_*_amd64.deb libmysqlclient-dev-amd64 \ - && echo 'Multi-Arch: same' | tee -a \ + ;\ + dpkg-deb -R libmysqlclient-dev_*_armhf.deb libmysqlclient-dev-armhf ;\ + dpkg-deb -R libmysqlclient-dev_*_arm64.deb libmysqlclient-dev-arm64 ;\ + dpkg-deb -R libmysqlclient-dev_*_i386.deb libmysqlclient-dev-i386 ;\ + dpkg-deb -R libmysqlclient-dev_*_amd64.deb libmysqlclient-dev-amd64 ;\ + echo 'Multi-Arch: same' | tee -a \ libmysqlclient-dev-amd64/DEBIAN/control \ libmysqlclient-dev-i386/DEBIAN/control \ libmysqlclient-dev-armhf/DEBIAN/control \ libmysqlclient-dev-arm64/DEBIAN/control \ - && dpkg-deb -b libmysqlclient-dev-amd64 libmysqlclient-dev-amd64.deb \ - && dpkg-deb -b libmysqlclient-dev-i386 libmysqlclient-dev-i386.deb \ - && dpkg-deb -b libmysqlclient-dev-armhf libmysqlclient-dev-armhf.deb \ - && dpkg-deb -b libmysqlclient-dev-arm64 libmysqlclient-dev-arm64.deb \ - && dpkg -i --force-overwrite \ + ;\ + dpkg-deb -b libmysqlclient-dev-amd64 libmysqlclient-dev-amd64.deb ;\ + dpkg-deb -b libmysqlclient-dev-i386 libmysqlclient-dev-i386.deb ;\ + dpkg-deb -b libmysqlclient-dev-armhf libmysqlclient-dev-armhf.deb ;\ + dpkg-deb -b libmysqlclient-dev-arm64 libmysqlclient-dev-arm64.deb ;\ + dpkg -i --force-overwrite \ libmysqlclient-dev-armhf.deb \ libmysqlclient-dev-arm64.deb \ libmysqlclient-dev-i386.deb \ libmysqlclient-dev-amd64.deb \ - && rm -rf /tmp/* /var/lib/apt/lists/* + ;\ + rm -rf /tmp/* /var/lib/apt/lists/* # Downgrade glibc symbols for backwards compatibility. COPY compat /compat -RUN mkdir -p /compat/x64 /compat/x86 \ - && objcopy --redefine-syms=/compat/glibc_version_x64.redef "$(gcc-10 --print-file-name=libstdc++.a)" /compat/x64/libstdc++.a \ - && objcopy --redefine-syms=/compat/glibc_version_x64.redef /usr/lib/x86_64-linux-gnu/libmysqlclient.a /compat/x64/libmysqlclient.a \ - && objcopy --redefine-syms=/compat/glibc_version_x86.redef "$(gcc-10 -m32 --print-file-name=libstdc++.a)" /compat/x86/libstdc++.a \ - && objcopy --redefine-syms=/compat/glibc_version_x86.redef /usr/lib/i386-linux-gnu/libmysqlclient.a /compat/x86/libmysqlclient.a +RUN set -ex ;\ + mkdir -p /compat/x64 /compat/x86 ;\ + objcopy --redefine-syms=/compat/glibc_version_x64.redef "$(gcc --print-file-name=libstdc++.a)" /compat/x64/libstdc++.a ;\ + objcopy --redefine-syms=/compat/glibc_version_x86.redef "$(gcc -m32 --print-file-name=libstdc++.a)" /compat/x86/libstdc++.a VOLUME /build WORKDIR /build diff --git a/utils/docker/compat/glibc_version.h b/utils/docker/compat/glibc_version.h index a48fdf350a0..ad30ff74676 100644 --- a/utils/docker/compat/glibc_version.h +++ b/utils/docker/compat/glibc_version.h @@ -3,45 +3,14 @@ #ifdef __x86_64__ #ifndef __ASSEMBLER__ - __asm__(".symver memcmp,memcmp@GLIBC_2.2.5"); - __asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); - __asm__(".symver powf,powf@GLIBC_2.2.5"); - __asm__(".symver log,log@GLIBC_2.2.5"); - __asm__(".symver log2,log2@GLIBC_2.2.5"); - __asm__(".symver pow,pow@GLIBC_2.2.5"); - __asm__(".symver exp,exp@GLIBC_2.2.5"); - __asm__(".symver fcntl64,fcntl@GLIBC_2.2.5"); + // __asm__(".symver memcmp,memcmp@GLIBC_2.2.5"); #else - .symver memcmp,memcmp@GLIBC_2.2.5 - .symver memcpy,memcpy@GLIBC_2.2.5 - .symver powf,powf@GLIBC_2.2.5 - .symver log,log@GLIBC_2.2.5 - .symver log2,log2@GLIBC_2.2.5 - .symver pow,pow@GLIBC_2.2.5 - .symver exp,exp@GLIBC_2.2.5 - .symver fcntl64,fcntl@GLIBC_2.2.5 + // .symver memcmp,memcmp@GLIBC_2.2.5 #endif #else #ifndef __ASSEMBLER__ - __asm__(".symver memcmp,memcmp@GLIBC_2.0"); - __asm__(".symver memcpy,memcpy@GLIBC_2.0"); - __asm__(".symver powf,powf@GLIBC_2.0"); - __asm__(".symver log,log@GLIBC_2.0"); - __asm__(".symver log2,log2@GLIBC_2.1"); - __asm__(".symver pow,pow@GLIBC_2.0"); - __asm__(".symver exp,exp@GLIBC_2.0"); - __asm__(".symver fcntl64,fcntl@GLIBC_2.0"); - __asm__(".symver fcntl,fcntl@GLIBC_2.0"); + // __asm__(".symver memcmp,memcmp@GLIBC_2.0"); #else - .symver memcmp,memcmp@GLIBC_2.0 - .symver memcpy,memcpy@GLIBC_2.0 - .symver powf,powf@GLIBC_2.0 - .symver log,log@GLIBC_2.0 - .symver log2,log2@GLIBC_2.1 - .symver pow,pow@GLIBC_2.0 - .symver exp,exp@GLIBC_2.0 - .symver fcntl64,fcntl@GLIBC_2.0 - .symver fcntl,fcntl@GLIBC_2.0 + // .symver memcmp,memcmp@GLIBC_2.0 #endif - #endif diff --git a/utils/docker/compat/glibc_version_x64.redef b/utils/docker/compat/glibc_version_x64.redef index 90521e83876..822b1d8f322 100644 --- a/utils/docker/compat/glibc_version_x64.redef +++ b/utils/docker/compat/glibc_version_x64.redef @@ -4,11 +4,4 @@ # If you change this, remember to also change glibc_version.h # See also: create_static_libraries.sh # -memcmp memcmp@GLIBC_2.2.5 -memcpy memcpy@GLIBC_2.2.5 -powf powf@GLIBC_2.2.5 -log log@GLIBC_2.2.5 -log2 log2@GLIBC_2.2.5 -pow pow@GLIBC_2.2.5 -exp exp@GLIBC_2.2.5 -fcntl64 fcntl@GLIBC_2.2.5 +# memcmp memcmp@GLIBC_2.2.5 diff --git a/utils/docker/compat/glibc_version_x86.redef b/utils/docker/compat/glibc_version_x86.redef index 12c4fedfa7d..3a380d9789d 100644 --- a/utils/docker/compat/glibc_version_x86.redef +++ b/utils/docker/compat/glibc_version_x86.redef @@ -4,11 +4,4 @@ # If you change this, remember to also change glibc_version.h # See also: create_static_libraries.sh # -memcmp memcmp@GLIBC_2.0 -memcpy memcpy@GLIBC_2.0 -powf powf@GLIBC_2.0 -log log@GLIBC_2.0 -log2 log2@GLIBC_2.1 -pow pow@GLIBC_2.0 -exp exp@GLIBC_2.0 -fcntl fcntl@GLIBC_2.0 +# memcmp memcmp@GLIBC_2.0 diff --git a/utils/docker/docker-entrypoint.sh b/utils/docker/docker-entrypoint.sh index 6c54b1a58c4..b65860f031f 100644 --- a/utils/docker/docker-entrypoint.sh +++ b/utils/docker/docker-entrypoint.sh @@ -1,5 +1,45 @@ #!/bin/bash +: ${arch_value:=x64} + +for arg in "$@"; do + case $arg in + --arch=*) + arch_value="${arg#--arch=}" + break + ;; + esac +done + +case $arch_value in + 32|x86) + prefix=i386-linux-gnu- + triplet=x86_64-linux-gnu- + ;; + 64|x64) + prefix=x86_64-linux-gnu- + triplet=$prefix + ;; + arm) + prefix=arm-linux-gnueabihf- + triplet=$prefix + ;; + arm64) + prefix=aarch64-linux-gnu- + triplet=$prefix + ;; + *) + echo "Error: Invalid build architecture" >&2 + exit 1 +esac + +: ${GCC_PREFIX:=$prefix} +: ${AR:=${triplet}gcc-ar-15} +: ${CC:=${triplet}gcc-15} +: ${CXX:=${triplet}g++-15} + +export GCC_PREFIX AR CC CXX + if [ -f ./linux-build.sh ]; then chmod +x ./linux-build.sh ./linux-build.sh "$@" diff --git a/utils/docker/sources.list b/utils/docker/sources.list deleted file mode 100644 index e91852f757b..00000000000 --- a/utils/docker/sources.list +++ /dev/null @@ -1,20 +0,0 @@ -deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu/ focal main restricted -deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu/ focal-updates main restricted -deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu/ focal universe -deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu/ focal-updates universe -deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu/ focal multiverse -deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu/ focal-updates multiverse -deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse -deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu/ focal-security main restricted -deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu/ focal-security universe -deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu/ focal-security multiverse - -deb [arch=armhf,arm64] http://ports.ubuntu.com/ focal main restricted -deb [arch=armhf,arm64] http://ports.ubuntu.com/ focal-updates main restricted -deb [arch=armhf,arm64] http://ports.ubuntu.com/ focal universe -deb [arch=armhf,arm64] http://ports.ubuntu.com/ focal-updates universe -deb [arch=armhf,arm64] http://ports.ubuntu.com/ focal multiverse -deb [arch=armhf,arm64] http://ports.ubuntu.com/ focal-updates multiverse -deb [arch=armhf,arm64] http://ports.ubuntu.com/ focal-backports main restricted universe multiverse - -deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu focal main diff --git a/utils/docker/ubuntu-toolchain-r-ubuntu-test.asc b/utils/docker/ubuntu-toolchain-r-ubuntu-test.asc deleted file mode 100644 index 83f21190117..00000000000 --- a/utils/docker/ubuntu-toolchain-r-ubuntu-test.asc +++ /dev/null @@ -1,31 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Comment: Hostname: -Version: Hockeypuck 2.2 - -xsFNBGYzeoEBEADEVzm0fPTo1KfunTjKV5ZP0Mb86Z6izCXSYbeYt/iAaIfK7a8x -c13I/uAOxzjcuZHD4sQh7/22I74ignCSexoJD3PnytpZtAxNjyj3jkJpIrdFOVd4 -Cmua5tnEI1Av+B21YLlYYftK2wR+Z6hpsz3NyQ8URR1SCX04BOV9AGxcWb7izkV9 -RHu6xR4x8kAjuTObhhqw/ZR73+U9mig785qmrtapQkF/IanYj2OofqUJwosDo8YA -shi01735JP9s5do4nnsb6w6xcYQ0HlGn3AxR1k4WA2CK/90QybOmVbLz7IOF3Ou3 -cPfoDzSxAiQemge2msJWPaQLSy/HPUivPB2uNPxkcNIHUVwbjgIig0yaN0EOsveg -o1m6QvS8sm1MEA2ySl+9+q8wdqTnXbSgA3hq/5OoG4rvHD9GUAd6oRxbz/wdOU3J -7BlAhEMAHgeQ9DyIzRP9lGeU3QnWNA+WFiiDrLljf+6xewe5iyqLxPqvCkFUDPCF -emp2oIqeWf6l04IMtM4SJz2AnU1EvytprEEvntMvHMXlBBinw1Q5r3ES/QlPfWr4 -o5CUpu2P3GpZtflDe7jvccyJUMDtlqOVv7wBZPMZykjTAPQ16clGdtIqWdQSk3/b -UA96RSdpM4gMGXFBGLBoAd7CptafRvPjpRnbMxs2jIxicnASfwJALEFgbQARAQAB -zT9MYXVuY2hwYWQgUFBBIGZvciBQUEEgZm9yIFVidW50dSBUb29sY2hhaW4gVXBs -b2FkcyAocmVzdHJpY3RlZCnCwY4EEwEKADgWIQTI7JUuKg4fvcUJD2osJ3oKNSFU -5QUCZjN6gQIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRAsJ3oKNSFU5TkT -EACpFJ+q0xqfAmRF1886cgtVw+ruJTqfsxdj7ms1os3/I5VXLhPMbUg56mtK9Okj -0Nf9rY5bnDagJobjtS2JgzMbYWXocPJuwK6ZvmMD5tFSsTov19R3SyIT2x3JAy7S -/LNWqVeZS41RtM8uSu56PhghE7aAP9PigFTI3CUargpx1DQh6xiHKRR57ZMrLcd4 -l6tj8yb4Hl+OeFRQMcoim696lPMSqzVtJ0epP7yNsz2LFaRmkRP/hf+S4JlSs8uC -wzAl9eJR2h1v1WoBr0pAW2gjjd8VyKWhaKjneicJPqo5GDvhDl+lbrpqSwSHENlH -DVyC+XvAjvTf4JhTQE/M1L/sGrqqa65n+WF4ZqauiDvn1bUw0vnL0oaiK/hyH1YG -XW7khJ7JDlw/6LFNZ6Ih0UuVRTzVBBBz3Sipw5hgM9ztKEYLMI5zlwWGlhEjMnxD -X5WauIUWjPv3dKQp1qTthN7Fgv3/2J6j+2/tMAfWeWB1tL8H4lVPUCfcpQpkTP/E -HTnB3oaRiYy6GDuGKsNkhEUvlV2AnVAxO17IN5QQ2lMQ261zaPj9y9v1oCQlzGfm -UKRJWFGbsooapdm7DTrqrfO+zyRXWPe6GRnYlmeXTRWi8CEIXpCkhhf8rma8KNnW -S96jsTSU97Lo0hnIbL+4o3qf2BiYcfIwfoIXzUaj5ajGEA== -=CwJW ------END PGP PUBLIC KEY BLOCK----- diff --git a/utils/docker/ubuntu.sources b/utils/docker/ubuntu.sources new file mode 100644 index 00000000000..6ad16497cbb --- /dev/null +++ b/utils/docker/ubuntu.sources @@ -0,0 +1,20 @@ +Types: deb +URIs: http://archive.ubuntu.com/ubuntu/ +Suites: noble noble-updates noble-backports +Components: main universe restricted multiverse +Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg +Architectures: amd64 i386 + +Types: deb +URIs: http://security.ubuntu.com/ubuntu/ +Suites: noble-security +Components: main universe restricted multiverse +Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg +Architectures: amd64 i386 + +Types: deb +URIs: http://ports.ubuntu.com/ubuntu-ports +Suites: noble noble-updates noble-backports +Components: main universe restricted multiverse +Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg +Architectures: arm64 armhf diff --git a/utils/hookcheck.exe b/utils/hookcheck.exe new file mode 100644 index 00000000000..c4b3e2425fd Binary files /dev/null and b/utils/hookcheck.exe differ diff --git a/utils/localization/build_locale_nsi.py b/utils/localization/build_locale_nsi.py index d00a4310413..84a386bce38 100644 --- a/utils/localization/build_locale_nsi.py +++ b/utils/localization/build_locale_nsi.py @@ -95,7 +95,7 @@ "yo" : "Yoruba", } -rtl_locales = [ "ar", "he" ] +rtl_locales = [ "ar", "he", "fa"] def escape_nsis(msgstr: str) -> str: diff --git a/utils/localization/generate-images/package-lock.json b/utils/localization/generate-images/package-lock.json index 09dab4c0924..e8a67785cf0 100644 --- a/utils/localization/generate-images/package-lock.json +++ b/utils/localization/generate-images/package-lock.json @@ -116,13 +116,13 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", - "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.1.tgz", + "integrity": "sha512-Kn4kbSXpkFHCGE6rBFNwIv0GQs4AvDT80jlveJDKFxjbTYMUeB4QtsdPCv6H8Cm19Je7IU6VFtRl2zWZI0rudQ==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, @@ -1078,9 +1078,9 @@ } }, "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -1343,9 +1343,9 @@ "license": "MIT" }, "node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.4.tgz", + "integrity": "sha512-UdiSoX6ypifLmrfQ/XfiawN6hkjSBpCjhKxxZcWlUUmoXLaCKQU0bx4HF/tdDK2uzRuchf1txGvrWBzYREssoQ==", "license": "MIT", "engines": { "node": ">=14.14" diff --git a/utils/localization/generate-translators/crowdin-translators.json b/utils/localization/generate-translators/crowdin-translators.json index 33226e715e9..36c43f8f944 100644 --- a/utils/localization/generate-translators/crowdin-translators.json +++ b/utils/localization/generate-translators/crowdin-translators.json @@ -12,7 +12,9 @@ "Avenger", "Bydlo", "ccw", + "chbaya7 chbaya7 (chbaya701)", "Conolel", + "Crown (x-Crown)", "DABL", "devmedoo", "Elizeu Monteiro (elizeuszernek)", @@ -49,6 +51,7 @@ "UAEpro", "xXHaMoDeXx \"Dante~#(xXHaMoDeXx)\" Dante", "XyZ", + "Youssef Maged (iManGaaX)", "Zed159" ], "az": [ @@ -58,7 +61,8 @@ "Ertogrul Khazarli (Khazarli)", "Mahammadali \"Reynmen\" Bagirov", "Seid Musayev (Maestro-17)", - "turret001" + "turret001", + "Youssef Maged (iManGaaX)" ], "bg_BG": [ "Arenata", @@ -311,7 +315,7 @@ "Gabrielius \"Drakath\" LaurinaviÄius", "Karolis \"Blantas\" Vaikutis", "Kristupas \"Buffalo\" Skabeikis", - "Lukas Bistrickas (morpp)", + "morpp", "qaisjp", "Rytis \"-TmS\" Jankauskas", "Tadas \"Grafu\" LapÄ—" diff --git a/utils/localization/generate-translators/package-lock.json b/utils/localization/generate-translators/package-lock.json index 0af8736b0d1..79bde4006fc 100644 --- a/utils/localization/generate-translators/package-lock.json +++ b/utils/localization/generate-translators/package-lock.json @@ -88,13 +88,13 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", - "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.1.tgz", + "integrity": "sha512-Kn4kbSXpkFHCGE6rBFNwIv0GQs4AvDT80jlveJDKFxjbTYMUeB4QtsdPCv6H8Cm19Je7IU6VFtRl2zWZI0rudQ==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, diff --git a/utils/msdia140.dll b/utils/msdia140.dll new file mode 100644 index 00000000000..7c81dfd4b6d Binary files /dev/null and b/utils/msdia140.dll differ diff --git a/utils/premake5 b/utils/premake5 index bcb51ced668..1b601b0ae3b 100755 Binary files a/utils/premake5 and b/utils/premake5 differ diff --git a/utils/premake5-macos b/utils/premake5-macos index e207e75b0b9..88c75dac6c6 100755 Binary files a/utils/premake5-macos and b/utils/premake5-macos differ diff --git a/utils/premake5.exe b/utils/premake5.exe index 52ae09d3b71..e01ba865812 100644 Binary files a/utils/premake5.exe and b/utils/premake5.exe differ diff --git a/utils/settings.VisualStudio.json b/utils/settings.VisualStudio.json new file mode 100644 index 00000000000..9e54da03ecf --- /dev/null +++ b/utils/settings.VisualStudio.json @@ -0,0 +1,5 @@ +/* Visual Studio Settings File */ +{ + "textEditor.codeCleanup.profile": "profile1", + "projectsAndSolutions.buildAndRun.onRunOnlyBuildStartupProjects": false +} diff --git a/utils/src/gen_language_list/build-solution.bat b/utils/src/gen_language_list/build-solution.bat index f1e992734b3..68e389e61dc 100644 --- a/utils/src/gen_language_list/build-solution.bat +++ b/utils/src/gen_language_list/build-solution.bat @@ -8,7 +8,7 @@ pause exit /b 1 :FindVisualStudio -for /f "usebackq tokens=*" %%i in (`call "%VSWHERE%" -latest -requires Microsoft.Component.MSBuild -find "**\VsDevCmd.bat"`) do ( +for /f "usebackq tokens=*" %%i in (`call "%VSWHERE%" -products * -latest -requires Microsoft.Component.MSBuild -find "**\VsDevCmd.bat"`) do ( set VSDEVCMD=%%i ) @@ -21,7 +21,7 @@ exit /b 1 :SetupEnv echo Found Visual Studio environment setup batch file: echo ^>^> %VSDEVCMD% -call "%VSDEVCMD%" -arch=arm64 -host_arch=amd64 >NUL +call "%VSDEVCMD%" -arch=amd64 -host_arch=amd64 >NUL where MSBuild.exe >NUL 2>&1 if %ERRORLEVEL% == 0 goto :Build diff --git a/utils/src/gen_language_list/create-solution.bat b/utils/src/gen_language_list/create-solution.bat index 7d3243124e2..7cef29280c7 100644 --- a/utils/src/gen_language_list/create-solution.bat +++ b/utils/src/gen_language_list/create-solution.bat @@ -1,3 +1,3 @@ @echo off -..\..\premake5.exe vs2022 +..\..\premake5.exe vs2026 if %0 == "%~0" pause diff --git a/utils/src/gen_language_list/premake5.lua b/utils/src/gen_language_list/premake5.lua index 6a189e06e50..fc1ab9371b5 100644 --- a/utils/src/gen_language_list/premake5.lua +++ b/utils/src/gen_language_list/premake5.lua @@ -3,7 +3,7 @@ workspace "utility" architecture "x86_64" preferredtoolarchitecture "x86_64" staticruntime "on" - cppdialect "C++20" + cppdialect "C++23" characterset "Unicode" flags "MultiProcessorCompile" warnings "Off" diff --git a/utils/src/hookcheck/build-solution.bat b/utils/src/hookcheck/build-solution.bat new file mode 100644 index 00000000000..cbcc180e8be --- /dev/null +++ b/utils/src/hookcheck/build-solution.bat @@ -0,0 +1,45 @@ +@echo off +set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" +if exist "%VSWHERE%" goto :FindVisualStudio + +echo Unable to locate Visual Studio: vswhere not found +echo ^>^> %VSWHERE% +pause +exit /b 1 + +:FindVisualStudio +for /f "usebackq tokens=*" %%i in (`call "%VSWHERE%" -products * -latest -requires Microsoft.Component.MSBuild -find "**\VsDevCmd.bat"`) do ( + set VSDEVCMD=%%i +) + +if defined VSDEVCMD goto :SetupEnv +echo Visual Studio not found +echo Make sure you've installed the 'Desktop development with C++' workload +pause +exit /b 1 + +:SetupEnv +echo Found Visual Studio environment setup batch file: +echo ^>^> %VSDEVCMD% +call "%VSDEVCMD%" -arch=amd64 -host_arch=amd64 >NUL + +where MSBuild.exe >NUL 2>&1 +if %ERRORLEVEL% == 0 goto :Build +echo MSBuild not found +echo Make sure you've installed the 'Desktop development with C++' workload +pause +exit /b 1 + +:Build +call create-solution.bat < NUL + +MSBuild.exe build\utility.sln ^ + -target:hookcheck ^ + -property:Configuration=Release ^ + -property:Platform=x64 ^ + -maxCpuCount + +copy build\bin\Release\*.dll ..\..\ >NUL +copy build\bin\Release\hookcheck.exe ..\..\ >NUL + +if %0 == "%~0" pause diff --git a/utils/src/hookcheck/create-solution.bat b/utils/src/hookcheck/create-solution.bat new file mode 100644 index 00000000000..7cef29280c7 --- /dev/null +++ b/utils/src/hookcheck/create-solution.bat @@ -0,0 +1,3 @@ +@echo off +..\..\premake5.exe vs2026 +if %0 == "%~0" pause diff --git a/utils/src/hookcheck/dll-analyzer.cpp b/utils/src/hookcheck/dll-analyzer.cpp new file mode 100644 index 00000000000..24cadabe985 --- /dev/null +++ b/utils/src/hookcheck/dll-analyzer.cpp @@ -0,0 +1,197 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: utils/src/hookcheck/dll-analyzer.cpp + * PURPOSE: Implementation for a class that can extract both the PDB file + * path and the value of the __LOCAL_SIZE assignment from our + * special macro. + * + * Multi Theft Auto is available from https://multitheftauto.com/ + * + *****************************************************************************/ + +#include "dll-analyzer.h" + +#include +#include + +#define NOMINMAX +#define WIN32_LEAN_AND_MEAN +#include + +static const std::string EmptyString; + +struct CV_INFO_PDB70 +{ + DWORD CvSignature; + GUID Guid; + DWORD Age; + char PdbFileName[1]; +}; + +DllAnalyzer::DllAnalyzer() = default; + +DllAnalyzer::~DllAnalyzer() +{ + Unload(); +} + +auto DllAnalyzer::LoadDll(const std::wstring& dll) -> std::pair +{ + using enum LoadError; + + HANDLE fileHandle = CreateFileW(dll.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); + + if (fileHandle == INVALID_HANDLE_VALUE) + { + const auto hr = HRESULT_FROM_WIN32(GetLastError()); + return std::make_pair(OpenDll, hr); + } + + HANDLE mapping = CreateFileMappingW(fileHandle, nullptr, PAGE_READONLY, 0, 0, nullptr); + if (!mapping) + { + const auto hr = HRESULT_FROM_WIN32(GetLastError()); + CloseHandle(fileHandle); + return std::make_pair(CreateMapping, hr); + } + + LPVOID fileView = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); + if (!fileView) + { + const auto hr = HRESULT_FROM_WIN32(GetLastError()); + CloseHandle(mapping); + CloseHandle(fileHandle); + return std::make_pair(CreateView, hr); + } + + const auto base = reinterpret_cast(fileView); + const auto dos = reinterpret_cast(fileView); + + if (dos->e_magic != IMAGE_DOS_SIGNATURE) + { + UnmapViewOfFile(fileView); + CloseHandle(mapping); + CloseHandle(fileHandle); + return std::make_pair(DosSignature, E_UNEXPECTED); + } + + const auto nt = reinterpret_cast(base + dos->e_lfanew); + + if (nt->Signature != IMAGE_NT_SIGNATURE) + { + UnmapViewOfFile(fileView); + CloseHandle(mapping); + CloseHandle(fileHandle); + return std::make_pair(NtSignature, E_UNEXPECTED); + } + + if (nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 || nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) + { + UnmapViewOfFile(fileView); + CloseHandle(mapping); + CloseHandle(fileHandle); + return std::make_pair(ImageArch, E_UNEXPECTED); + } + + m_file = fileHandle; + m_mapping = mapping; + m_view = fileView; + m_nt = nt; + return std::make_pair(None, S_OK); +} + +void DllAnalyzer::Unload() +{ + if (m_view) + { + UnmapViewOfFile(m_view); + m_view = {}; + m_nt = {}; + } + + if (m_mapping) + { + CloseHandle(m_mapping); + m_mapping = {}; + } + + if (m_file) + { + CloseHandle(m_file); + m_file = {}; + } +} + +auto DllAnalyzer::ExtractPdbPath() const -> std::pair +{ + using enum ExtractError; + + if (!m_nt) + return std::make_pair(NotLoaded, EmptyString); + + const auto base = reinterpret_cast(m_view); + const auto opt32 = reinterpret_cast(&m_nt->OptionalHeader); + const auto ddir = &opt32->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]; + + if (!ddir->Size) + return std::make_pair(NoDebugDirectory, EmptyString); + + const auto rva = ddir->VirtualAddress; + auto section = IMAGE_FIRST_SECTION(m_nt); + + for (WORD i = 0; i < m_nt->FileHeader.NumberOfSections; ++i, ++section) + { + const auto rvaBegin = section->VirtualAddress; + const auto rvaEnd = rvaBegin + section->SizeOfRawData; + + if (rva < rvaBegin || rva >= rvaEnd) + continue; + + auto entry = reinterpret_cast(base + section->PointerToRawData + (rva - rvaBegin)); + const DWORD numEntries = ddir->Size / sizeof(IMAGE_DEBUG_DIRECTORY); + + for (DWORD j = 0; j < numEntries; ++j, ++entry) + { + if (entry->Type == IMAGE_DEBUG_TYPE_CODEVIEW) + { + const auto info = reinterpret_cast(base + entry->PointerToRawData); + + if (info->CvSignature == 'SDSR') + { + return std::make_pair(None, std::string{ info->PdbFileName }); + } + } + } + + break; + } + + return std::make_pair(NotFound, EmptyString); +} + +auto DllAnalyzer::GetLocalSize(DWORD virtualAddress) -> std::optional +{ + if (!m_nt) + return std::nullopt; + + const auto base = reinterpret_cast(m_view); + auto section = IMAGE_FIRST_SECTION(m_nt); + + for (WORD i = 0; i < m_nt->FileHeader.NumberOfSections; ++i, ++section) + { + const auto rvaBegin = section->VirtualAddress; + const auto rvaEnd = rvaBegin + section->SizeOfRawData; + + if (virtualAddress < rvaBegin || virtualAddress >= rvaEnd) + continue; + + // B8 00 00 00 00 | mov eax, __LOCAL_SIZE + // We must skip a singular byte (0xB8 for mov) to retrieve the value of __LOCAL_SIZE. + auto value = reinterpret_cast(base + section->PointerToRawData + (virtualAddress - rvaBegin) + 1); + return *value; + } + + return std::nullopt; +} diff --git a/utils/src/hookcheck/dll-analyzer.h b/utils/src/hookcheck/dll-analyzer.h new file mode 100644 index 00000000000..5617a5b9838 --- /dev/null +++ b/utils/src/hookcheck/dll-analyzer.h @@ -0,0 +1,97 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: utils/src/hookcheck/dll-analyzer.h + * PURPOSE: Header for a class that can extract both the PDB file path + * and the value of the __LOCAL_SIZE assignment from our special + * macro. + * + * Multi Theft Auto is available from https://multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include +#include +#include + +using HRESULT = long; +using HANDLE = void*; +using LPVOID = void*; +using DWORD = unsigned long; +using ULONGLONG = unsigned long long; + +struct _IMAGE_NT_HEADERS; + +class DllAnalyzer final +{ +public: + enum class LoadError + { + None, + OpenDll, + CreateMapping, + CreateView, + DosSignature, + NtSignature, + ImageArch, + }; + + enum class ExtractError + { + None, + NotLoaded, + NoDebugDirectory, + NotFound, + }; + +public: + DllAnalyzer(); + ~DllAnalyzer(); + + DllAnalyzer(const DllAnalyzer&) = delete; + DllAnalyzer& operator=(const DllAnalyzer&) = delete; + + DllAnalyzer(DllAnalyzer&&) noexcept = default; + DllAnalyzer& operator=(DllAnalyzer&&) noexcept = default; + +public: + /** + * @brief Loads a DLL (Dynamic-Link Library) file. + * @param dll The path to the DLL file to load. + * @return A pair consisting of a LoadError value indicating the generic error of the load operation, + * and an HRESULT code providing additional status information. + */ + [[nodiscard]] + auto LoadDll(const std::wstring& dll) -> std::pair; + + /** + * @brief Releases or unloads resources. + */ + void Unload(); + + /** + * @brief Extracts the path to the PDB (Program Database) file. + * @return A pair consisting of a ExtractError value indicating an error and an empty string on failure, + * or a pair consisting of ExtractError::None and the path to the PDB file on success. + */ + [[nodiscard]] + auto ExtractPdbPath() const -> std::pair; + + /** + * @brief Retrieves the value of __LOCAL_SIZE using the virtual address of the label before it. + * @param virtualAddress The virtual address of the label before the assignment. + * @return The value of __LOCAL_SIZE on success, otherwise an empty value on failure. + */ + [[nodiscard]] + auto GetLocalSize(DWORD virtualAddress) -> std::optional; + +private: + HANDLE m_file{}; + HANDLE m_mapping{}; + LPVOID m_view{}; + + const _IMAGE_NT_HEADERS* m_nt{}; +}; diff --git a/utils/src/hookcheck/hookcheck.cpp b/utils/src/hookcheck/hookcheck.cpp new file mode 100644 index 00000000000..ae675a0b514 --- /dev/null +++ b/utils/src/hookcheck/hookcheck.cpp @@ -0,0 +1,365 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: utils/src/hookcheck/hookcheck.cpp + * PURPOSE: A tool to inspect the value of __LOCAL_SIZE inside + * __declspec(naked) hook functions, to verify that its value is + * equal to zero. It uses the PDB file to identify these functions + * and then provides a list of problems, if any were identified. + * + * Multi Theft Auto is available from https://multitheftauto.com/ + * + *****************************************************************************/ + +#define TOOL_NAME "hookcheck" +#define TOOL_VERSION "1.0.0" +#define DEFAULT_LABEL "_localSize" + +#include "dll-analyzer.h" +#include "pdb-analyzer.h" +#include "utility.h" + +#include +#include +#include +#include +#include +#include +#include + +#define NOMINMAX +#define WIN32_LEAN_AND_MEAN +#include + +namespace fs = std::filesystem; + +int wmain(int argc, wchar_t* argv[]) +try +{ + SetConsoleOutputCP(CP_UTF8); + + struct Arguments + { + std::optional dll; + std::optional label; + std::vector ignore; + } arguments; + + for (int i = 1; i < argc; ++i) + { + std::wstring_view arg = argv[i]; + + if (arg.length() < 2 || !arg.starts_with(L'-')) + continue; + + std::wstring key; + std::wstring value; + + if (const size_t pos = arg.find_first_of(L':', 1); pos != std::wstring_view::npos && pos > 1) + { + key = arg.substr(1, pos - 1); + value = arg.substr(pos + 1); + } + else + { + key = arg.substr(1); + } + + Trim(key); + Trim(value); + + if (key.empty()) + continue; + + if (!_wcsnicmp(key.c_str(), L"dll", key.size())) + { + if (!value.empty() && !arguments.dll.has_value()) + arguments.dll = value; + + continue; + } + + if (!_wcsnicmp(key.c_str(), L"label", key.size())) + { + if (!value.empty() && !arguments.label.has_value()) + arguments.label = value; + + continue; + } + + if (!_wcsnicmp(key.c_str(), L"ignore", key.size())) + { + if (!value.empty()) + arguments.ignore.emplace_back(value); + + continue; + } + } + + if (!arguments.dll.has_value()) + { + PrintLn(L"Usage: " TOOL_NAME L" -dll: [-label:" DEFAULT_LABEL L"] [-ignore:]"); + return 1; + } + + std::error_code ec{}; + + const fs::path dllFilePath = fs::absolute(arguments.dll.value(), ec); + std::wstring labelName = arguments.label.value_or(L"" DEFAULT_LABEL); + + if (!fs::exists(dllFilePath, ec) || !fs::is_regular_file(dllFilePath, ec)) + { + PrintErrorLn(L"DLL file '{}' does not exist or is not readable", dllFilePath.wstring()); + return 1; + } + + DllAnalyzer dll; + + if (auto [errorCode, hr] = dll.LoadDll(dllFilePath.wstring()); errorCode != DllAnalyzer::LoadError::None) + { + std::wstring message = L"An unknown error has occurred in DllAnalyzer::LoadDll"; + + switch (errorCode) + { + using enum DllAnalyzer::LoadError; + + case OpenDll: + message = L"CreateFileW has failed for the DLL"; + break; + case CreateMapping: + message = L"CreateFileMappingW has failed for the DLL"; + break; + case CreateView: + message = L"MapViewOfFile has failed for the DLL"; + break; + case DosSignature: + message = L"Unexpected signature in IMAGE_DOS_HEADER"; + break; + case NtSignature: + message = L"Unexpected signature in IMAGE_NT_HEADERS"; + break; + case ImageArch: + message = L"This tool supports only 32-Bit DLLs"; + break; + default: + break; + } + + PrintErrorLn(hr, L"{}", message); + return 1; + } + + fs::path pdbFilePath; + + if (auto [errorCode, filePath] = dll.ExtractPdbPath(); errorCode != DllAnalyzer::ExtractError::None) + { + std::wstring message = L"An unknown error has occurred in DllAnalyzer::ExtractPdbPath"; + + switch (errorCode) + { + using enum DllAnalyzer::ExtractError; + + case NotLoaded: + message = L"You must load a DLL before trying to extract a PDB path"; + break; + case NoDebugDirectory: + message = L"IMAGE_DIRECTORY_ENTRY_DEBUG not found in data directory"; + break; + case NotFound: + message = L"CodeView entry with PDB information not found in IMAGE_DIRECTORY_ENTRY_DEBUG"; + break; + default: + break; + } + + PrintErrorLn(L"{}", message); + return 1; + } + else + { + pdbFilePath = fs::absolute(filePath, ec); + } + +#ifdef MTA_DEBUG + PrintLn(L"[~] " TOOL_NAME L" " TOOL_VERSION); + PrintLn(L"[~] Label: '{}'", labelName); + PrintLn(L"[~] DLL: '{}'", dllFilePath.wstring()); + PrintLn(L"[~] PDB: '{}'", pdbFilePath.wstring()); + + for (const std::wstring& ignore : arguments.ignore) + PrintLn(L"[~] Ignore: '{}'", ignore); +#endif + + if (!fs::exists(pdbFilePath, ec) || !fs::is_regular_file(pdbFilePath, ec)) + { + PrintErrorLn(L"{} is not a regular file", pdbFilePath.wstring()); + return 1; + } + + if (HRESULT hr = CoInitialize(nullptr); FAILED(hr)) + { + PrintErrorLn(hr, L"CoInitialize has failed"); + return 1; + } + + PdbAnalyzer pdb; + + if (auto [errorCode, hr] = pdb.LoadPdb(pdbFilePath.wstring()); errorCode != PdbAnalyzer::LoadError::None) + { + std::wstring message = L"An unknown error has occurred in PdbAnalyzer::LoadPdb"; + + switch (errorCode) + { + using enum PdbAnalyzer::LoadError; + + case DiaSdkNotFound: + message = L"Failed to create DIA data source"; + break; + case PdbNotLoadable: + message = L"Failed to load the PDB file"; + break; + case NoSession: + message = L"Failed to open a DIA session"; + break; + case NoGlobalSymbol: + message = L"Failed to retrieve the global symbol"; + break; + default: + break; + } + + PrintErrorLn(hr, L"{}", message); + return 1; + } + + if (auto hr = pdb.Analyze(); FAILED(hr)) + { + PrintErrorLn(hr, L"Analysis of PDB has failed"); + return 1; + } + + std::vector& functions = pdb.GetFunctions(); + + if (functions.empty()) + return 0; + + const auto ContainsIgnore = [&ignored = arguments.ignore](const PdbAnalyzer::Function& f) + { + for (const std::wstring& ignore : ignored) + { + if (StrStrIW(f.SourceFile.c_str(), ignore.c_str()) != nullptr) + return true; + } + + return false; + }; + + functions.erase(std::remove_if(std::begin(functions), std::end(functions), ContainsIgnore), std::end(functions)); + + const auto SortBySource = [](const PdbAnalyzer::Function& lhs, const PdbAnalyzer::Function& rhs) + { + const auto compare = + std::lexicographical_compare_three_way(std::begin(lhs.SourceFile), std::end(lhs.SourceFile), std::begin(rhs.SourceFile), std::end(rhs.SourceFile), + [](wchar_t a, wchar_t b) { return std::tolower(a) <=> std::tolower(b); }); + + if (std::is_lt(compare)) + return true; + if (std::is_gt(compare)) + return false; + + return lhs.SourceLine < rhs.SourceLine; + }; + + std::sort(std::begin(functions), std::end(functions), SortBySource); + + int exitCode = 0; + + const auto isOurLabel = [&labelName](const PdbAnalyzer::Label& l) { return l.Name == labelName; }; + + for (const PdbAnalyzer::Function& function : functions) + { + const auto label = std::find_if(std::begin(function.Labels), std::end(function.Labels), isOurLabel); + const bool hasLabel = label != std::end(function.Labels); + + std::vector problems; + + if (!hasLabel && !fs::is_regular_file(function.SourceFile, ec)) + continue; + + if (function.Name.starts_with(L"std::") || function.Name.starts_with(L'_')) + { + if (!hasLabel) + continue; + + problems.emplace_back(L"warning: rename this naked hook function, to not start with an underscore, and neither with 'std::'"); + } + + if (!hasLabel) + { + problems.emplace_back(L"error: a naked hook function must use MTA_VERIFY_HOOK_LOCAL_SIZE"); + exitCode = 1; + } + + if (!function.HasInlineAssembly) + { + problems.emplace_back(L"warning: a naked hook function should contain inline assembly"); + } + + if (!function.IsStatic) + { + problems.emplace_back(L"warning: a naked hook function should be static"); + } + + if (hasLabel) + { + std::optional localSize = dll.GetLocalSize(static_cast(label->VirtualAddress)); + + if (localSize.has_value()) + { + if (localSize.value() > 0) + { + problems.emplace_back(std::format(L"error: naked hook function is using local space (__LOCAL_SIZE is {} bytes)", localSize.value())); + exitCode = 1; + } + } + else + { + problems.emplace_back(L"error: failed to extract the value of __LOCAL_SIZE"); + exitCode = 1; + } + } + + if (problems.empty()) + continue; + + for (const std::wstring& problem : problems) + PrintLn(L"{}({}): {}", function.SourceFile, function.SourceLine, problem); + } + + return exitCode; +} +catch (const fs::filesystem_error& ex) +{ + HRESULT hr = S_OK; + + if (ex.code()) + { + if (ex.code().category() == std::system_category()) + { + hr = HRESULT_FROM_WIN32(ex.code().value()); + } + else + { + hr = E_FAIL; + } + } + + PrintErrorLn(hr, L"A filesystem exception was thrown: {}", ToWideString(ex.what())); + return -1; +} +catch (const std::exception& ex) +{ + PrintErrorLn(L"An exception was thrown: {}", ToWideString(ex.what())); + return -1; +} diff --git a/utils/src/hookcheck/locate-dia-sdk.bat b/utils/src/hookcheck/locate-dia-sdk.bat new file mode 100644 index 00000000000..902949ef25d --- /dev/null +++ b/utils/src/hookcheck/locate-dia-sdk.bat @@ -0,0 +1,21 @@ +@echo off + +set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" +if exist "%VSWHERE%" goto :FindVisualStudio +exit /b 1 + +:FindVisualStudio +for /f "usebackq tokens=*" %%i in (`call "%VSWHERE%" -products * -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do ( + set VSDIR=%%i +) + +if defined VSDIR goto :CheckPath +exit /b 2 + +:CheckPath +if exist "%VSDIR%\DIA SDK\" goto :PrintPath +exit /b 3 + +:PrintPath +echo %VSDIR%\DIA SDK\ +exit /b 0 diff --git a/utils/src/hookcheck/pdb-analyzer.cpp b/utils/src/hookcheck/pdb-analyzer.cpp new file mode 100644 index 00000000000..5fba6fa49c1 --- /dev/null +++ b/utils/src/hookcheck/pdb-analyzer.cpp @@ -0,0 +1,347 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: utils/src/hookcheck/pdb-analyzer.cpp + * PURPOSE: Implementation for a class for extracting information from a PDB + * file using the DIA SDK provided by Microsoft. Its main focus is + * to identify __declspec(naked) functions, and provide information + * surrounding each one. + * + * Multi Theft Auto is available from https://multitheftauto.com/ + * + *****************************************************************************/ + +#include "pdb-analyzer.h" +#include "utility.h" + +#include +#include +#include + +#include +#include + +#pragma comment(lib, "diaguids.lib") + +#if 0 +static constexpr auto kTags = std::to_array({ + SymTagExe, + SymTagCompiland, + SymTagCompilandDetails, + SymTagCompilandEnv, + SymTagFunction, + SymTagBlock, + SymTagData, + SymTagAnnotation, + SymTagLabel, + SymTagPublicSymbol, + SymTagUDT, + SymTagEnum, + SymTagFunctionType, + SymTagPointerType, + SymTagArrayType, + SymTagBaseType, + SymTagTypedef, + SymTagBaseClass, + SymTagFriend, + SymTagFunctionArgType, + SymTagFuncDebugStart, + SymTagFuncDebugEnd, + SymTagUsingNamespace, + SymTagVTableShape, + SymTagVTable, + SymTagCustom, + SymTagThunk, + SymTagCustomType, + SymTagManagedType, + SymTagDimension, + SymTagCallSite, + SymTagInlineSite, + SymTagBaseInterface, + SymTagVectorType, + SymTagMatrixType, + SymTagHLSLType, + SymTagCaller, + SymTagCallee, + SymTagExport, + SymTagHeapAllocationSite, + SymTagCoffGroup, + SymTagInlinee, + SymTagTaggedUnionCase, +}); + +static constexpr auto kTagNames = std::to_array({ + L"SymTagExe", + L"SymTagCompiland", + L"SymTagCompilandDetails", + L"SymTagCompilandEnv", + L"SymTagFunction", + L"SymTagBlock", + L"SymTagData", + L"SymTagAnnotation", + L"SymTagLabel", + L"SymTagPublicSymbol", + L"SymTagUDT", + L"SymTagEnum", + L"SymTagFunctionType", + L"SymTagPointerType", + L"SymTagArrayType", + L"SymTagBaseType", + L"SymTagTypedef", + L"SymTagBaseClass", + L"SymTagFriend", + L"SymTagFunctionArgType", + L"SymTagFuncDebugStart", + L"SymTagFuncDebugEnd", + L"SymTagUsingNamespace", + L"SymTagVTableShape", + L"SymTagVTable", + L"SymTagCustom", + L"SymTagThunk", + L"SymTagCustomType", + L"SymTagManagedType", + L"SymTagDimension", + L"SymTagCallSite", + L"SymTagInlineSite", + L"SymTagBaseInterface", + L"SymTagVectorType", + L"SymTagMatrixType", + L"SymTagHLSLType", + L"SymTagCaller", + L"SymTagCallee", + L"SymTagExport", + L"SymTagHeapAllocationSite", + L"SymTagCoffGroup", + L"SymTagInlinee", + L"SymTagTaggedUnionCase", +}); + +static_assert(kTags.size() == kTagNames.size()); + +[[maybe_unused]] +static void Dump(IDiaSymbol* symbol) +{ + for (size_t i = {}; i < kTags.size(); ++i) + { + CComPtr iterator{}; + + if (HRESULT hr = symbol->findChildren(kTags[i], nullptr, nsNone, &iterator); FAILED(hr)) + { + PrintErrorLn(hr, L"Could not find children for {}", kTagNames[i]); + continue; + } + + LONG numSymbols{}; + if (HRESULT hr = iterator->get_Count(&numSymbols); FAILED(hr)) + { + PrintErrorLn(hr, L"Could not get children count for {}", kTagNames[i]); + continue; + } + + PrintLn(L"Found {} symbols for {}", numSymbols, kTagNames[i]); + } +} +#endif + +PdbAnalyzer::PdbAnalyzer() = default; + +PdbAnalyzer::~PdbAnalyzer() = default; + +auto PdbAnalyzer::LoadPdb(const std::wstring& pdb) -> std::pair +{ + using enum LoadError; + + HRESULT hr = NoRegCoCreate(L"" MSDIA_DLL, CLSID_DiaSource, IID_IDiaDataSource, (void**)&m_dataSource); + + if (FAILED(hr)) + return std::make_pair(DiaSdkNotFound, hr); + + if (hr = m_dataSource->loadDataFromPdb(pdb.c_str()); FAILED(hr)) + return std::make_pair(PdbNotLoadable, hr); + + if (hr = m_dataSource->openSession(&m_session); FAILED(hr)) + return std::make_pair(NoSession, hr); + + if (hr = m_session->get_globalScope(&m_globalSymbol); FAILED(hr)) + return std::make_pair(NoGlobalSymbol, hr); + + return std::make_pair(None, S_OK); +} + +auto PdbAnalyzer::Analyze() -> HRESULT +{ + CComPtr iterator{}; + + if (HRESULT hr = m_globalSymbol->findChildren(SymTagFunction, nullptr, nsNone, &iterator); FAILED(hr)) + { + PrintErrorLn(hr, L"IDiaEnumSymbols::findChildren has failed for SymTagFunction"); + return hr; + } + + CComPtr function{}; + ULONG counter{}; + + while (SUCCEEDED(iterator->Next(1, &function, &counter)) && counter == 1) + { + AnalyzeFunction(function); + function.Release(); + } + + return S_OK; +} + +void PdbAnalyzer::AnalyzeFunction(IDiaSymbol* functionSymbol) +{ + BSTR name{}; + + // There is nothing we can really do without a function name, skip this one. + if (FAILED(functionSymbol->get_name(&name)) || !name) + return; + + // We are going to immediately discard any non-naked functions from the selection. + BOOL isNaked{}; + + if (HRESULT hr = functionSymbol->get_isNaked(&isNaked); FAILED(hr) || !isNaked) + { + if (FAILED(hr)) + PrintWarningLn(hr, L"IDiaSymbol::get_isNaked has failed for function {}", name); + + SysFreeString(name); + return; + } + + ULONGLONG virtualAddress{}; + + if (HRESULT hr = functionSymbol->get_virtualAddress(&virtualAddress); FAILED(hr) || !virtualAddress) + { + PrintWarningLn(hr, L"IDiaSymbol::get_virtualAddress has failed for function {}", name); + SysFreeString(name); + return; + } + + BOOL hasInlineAssembly{}; + + if (HRESULT hr = functionSymbol->get_hasInlAsm(&hasInlineAssembly); FAILED(hr)) + { + PrintWarningLn(hr, L"IDiaSymbol::get_hasInlAsm has failed for function {}", name); + SysFreeString(name); + return; + } + + BOOL isStatic{}; + + if (HRESULT hr = functionSymbol->get_isStatic(&isStatic); FAILED(hr)) + { + PrintWarningLn(hr, L"IDiaSymbol::get_isStatic has failed for function {}", name); + SysFreeString(name); + return; + } + + Function& newFunction = m_functions.emplace_back(); + newFunction.Name = name; + newFunction.VirtualAddress = virtualAddress; + newFunction.IsStatic = isStatic; + newFunction.HasInlineAssembly = hasInlineAssembly; + SysFreeString(name); + + AttachLocation(functionSymbol, newFunction); + NormalizePath(newFunction.SourceFile); + + if (newFunction.SourceFile.empty()) + { + m_functions.pop_back(); + return; + } + + AttachLabels(functionSymbol, newFunction); +} + +void PdbAnalyzer::AttachLocation(IDiaSymbol* functionSymbol, Function& attachTo) +{ + ULONGLONG length{}; + + if (HRESULT hr = functionSymbol->get_length(&length); FAILED(hr)) + { + PrintWarningLn(hr, L"IDiaSymbol::get_length has failed for function {}", attachTo.Name); + return; + } + + CComPtr iterator; + + if (HRESULT hr = m_session->findLinesByVA(attachTo.VirtualAddress, static_cast(length), &iterator); FAILED(hr)) + { + PrintWarningLn(hr, L"IDiaSymbol::findChildren has failed for SymTagLabel for function {}", attachTo.Name); + return; + } + + CComPtr line{}; + ULONG counter{}; + + // In practice there can be multiple lines associated with a virtual address, but we are only going to pick the first one. + if (HRESULT hr = iterator->Next(1, &line, &counter); FAILED(hr) || counter != 1) + { + PrintWarningLn(hr, L"IDiaEnumLineNumbers::Next has failed for function {}", attachTo.Name); + return; + } + + CComPtr sourceFile; + + if (HRESULT hr = line->get_sourceFile(&sourceFile); FAILED(hr)) + { + PrintWarningLn(hr, L"IDiaLineNumber::get_sourceFile has failed for function {}", attachTo.Name); + return; + } + + BSTR fileName{}; + + if (HRESULT hr = sourceFile->get_fileName(&fileName); FAILED(hr)) + { + PrintWarningLn(hr, L"IDiaSourceFile::get_fileName has failed for function {}", attachTo.Name); + return; + } + + attachTo.SourceFile = fileName; + + // Not a problem if this fails, only the name of the source file is better than nothing. + (void)line->get_lineNumber(&attachTo.SourceLine); + + SysFreeString(fileName); +} + +void PdbAnalyzer::AttachLabels(IDiaSymbol* functionSymbol, Function& attachTo) +{ + CComPtr iterator; + + if (HRESULT hr = functionSymbol->findChildren(SymTagLabel, nullptr, nsNone, &iterator); FAILED(hr)) + { + PrintErrorLn(hr, L"IDiaSymbol::findChildren has failed for SymTagLabel for function {}", attachTo.Name); + return; + } + + CComPtr item{}; + ULONG counter{}; + + while (SUCCEEDED(iterator->Next(1, &item, &counter)) && counter == 1) + { + CComPtr label = item.Detach(); + BSTR name{}; + + // There is nothing we can really do without a function name, skip this one. + if (FAILED(label->get_name(&name)) || !name) + continue; + + ULONGLONG virtualAddress{}; + + if (HRESULT hr = label->get_virtualAddress(&virtualAddress); FAILED(hr) || !virtualAddress) + { + PrintErrorLn(hr, L"IDiaSymbol::get_virtualAddress has failed for label {} in function {}", name, attachTo.Name); + SysFreeString(name); + continue; + } + + Label& newLabel = attachTo.Labels.emplace_back(); + newLabel.Name = name; + newLabel.VirtualAddress = virtualAddress; + } +} diff --git a/utils/src/hookcheck/pdb-analyzer.h b/utils/src/hookcheck/pdb-analyzer.h new file mode 100644 index 00000000000..2163411661e --- /dev/null +++ b/utils/src/hookcheck/pdb-analyzer.h @@ -0,0 +1,128 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: utils/src/hookcheck/pdb-analyzer.h + * PURPOSE: Header for a class for extracting information from a PDB file + * using the DIA SDK provided by Microsoft. Its main focus is to + * identify __declspec(naked) functions, and provide information + * surrounding each one. + * + * Multi Theft Auto is available from https://multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include +#include +#include + +#include + +struct IDiaDataSource; +struct IDiaSession; +struct IDiaSymbol; + +using HRESULT = long; +using ULONGLONG = unsigned long long; + +class PdbAnalyzer final +{ +public: + /** + * @brief Enumerates possible errors that can occur during a load operation. + */ + enum class LoadError + { + None, + DiaSdkNotFound, + PdbNotLoadable, + NoSession, + NoGlobalSymbol, + }; + + /** + * @brief Represents a label with a name and a virtual address. + */ + struct Label + { + std::wstring Name; + ULONGLONG VirtualAddress{}; + }; + + /** + * @brief Represents information about a function, including its name, source location, attributes, and associated labels. + */ + struct Function + { + std::wstring Name; + std::wstring SourceFile; + DWORD SourceLine{}; + ULONGLONG VirtualAddress{}; + BOOL IsStatic{}; + BOOL HasInlineAssembly{}; + + std::vector